From 1e1a6ac3613d6fb7661fbceb0e3c62cb3c8090e0 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 4 Feb 2013 17:26:27 +0000 Subject: [PATCH 001/467] Convert singleton calculation engine to multiton --- Classes/PHPExcel.php | 43 ++++++++++++++++++-- Classes/PHPExcel/Calculation.php | 70 ++++++++++++++++++++++++-------- Classes/PHPExcel/Cell.php | 8 ++-- 3 files changed, 96 insertions(+), 25 deletions(-) diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index ec98ad036..901cb16df 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -42,6 +42,13 @@ */ 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 @@ public function __construct() } + /** + * 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 @@ public function disconnectWorksheets() { $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 @@ public function garbageCollect() 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 254a4e9ca..a2f537211 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 @@ private static function _loadLocales() { * @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 @@ public static function getInstance() { 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 @@ public static function getInstance() { * @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 @@ public static function getArrayReturnType() { * @return boolean */ public function getCalculationCacheEnabled() { - return self::$_calculationCacheEnabled; + return $this->_calculationCacheEnabled; } // function getCalculationCacheEnabled() @@ -1803,7 +1837,7 @@ public function getCalculationCacheEnabled() { * @param boolean $pValue */ public function setCalculationCacheEnabled($pValue = true) { - self::$_calculationCacheEnabled = $pValue; + $this->_calculationCacheEnabled = $pValue; $this->clearCalculationCache(); } // function setCalculationCacheEnabled() @@ -1828,7 +1862,7 @@ public function disableCalculationCache() { * Clear calculation cache */ public function clearCalculationCache() { - self::$_calculationCache = array(); + $this->_calculationCache = array(); } // function clearCalculationCache() @@ -2206,7 +2240,7 @@ public function calculateFormula($formula, $cellID=null, PHPExcel_Cell $pCell = // 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 @@ public function calculateFormula($formula, $cellID=null, PHPExcel_Cell $pCell = } // Reset calculation cacheing to its previous state - self::$_calculationCacheEnabled = $resetCache; + $this->_calculationCacheEnabled = $resetCache; return $result; } // function calculateFormula() @@ -2250,15 +2284,15 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC } // 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 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC // 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 2e9cd3272..ea37c7ecc 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -288,7 +288,7 @@ public function getCalculatedValue($resetLog = TRUE) 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 @@ public static function extractAllCellReferencesInRange($pRange = 'A1') { */ 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; From 6f4cfcc8c6331e80dc3b9e2ea23ea1a25518cb43 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 4 Feb 2013 23:16:39 +0000 Subject: [PATCH 002/467] Ensure that writers access the workbook rather than the global calculation engine --- Classes/PHPExcel/Writer/CSV.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007.php | 6 +++--- Classes/PHPExcel/Writer/Excel5.php | 8 ++++---- Classes/PHPExcel/Writer/HTML.php | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php index 2ff5b410e..3979d6094 100644 --- a/Classes/PHPExcel/Writer/CSV.php +++ b/Classes/PHPExcel/Writer/CSV.php @@ -102,8 +102,8 @@ public function save($pFilename = null) { // Fetch sheet $sheet = $this->_phpExcel->getSheet($this->_sheetIndex); - $saveDebugLog = PHPExcel_Calculation::getInstance()->writeDebugLog; - PHPExcel_Calculation::getInstance()->writeDebugLog = false; + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog; + PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = FALSE; $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); @@ -139,7 +139,7 @@ public function save($pFilename = null) { fclose($fileHandle); PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); - PHPExcel_Calculation::getInstance()->writeDebugLog = $saveDebugLog; + PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = $saveDebugLog; } /** diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index a74350ca5..951b33973 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -179,8 +179,8 @@ public function save($pFilename = null) } } - $saveDebugLog = PHPExcel_Calculation::getInstance()->writeDebugLog; - PHPExcel_Calculation::getInstance()->writeDebugLog = false; + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->writeDebugLog; + PHPExcel_Calculation::getInstance($this->_spreadSheet)->writeDebugLog = false; $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); @@ -341,7 +341,7 @@ public function save($pFilename = null) } PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); - PHPExcel_Calculation::getInstance()->writeDebugLog = $saveDebugLog; + PHPExcel_Calculation::getInstance($this->_spreadSheet)->writeDebugLog = $saveDebugLog; // Close file if ($objZip->close() === false) { diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index 459653c63..daa1d0fe2 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -120,13 +120,13 @@ public function save($pFilename = null) { // garbage collect $this->_phpExcel->garbageCollect(); - $saveDebugLog = PHPExcel_Calculation::getInstance()->writeDebugLog; - PHPExcel_Calculation::getInstance()->writeDebugLog = false; + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog; + PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = false; $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // initialize colors array - $this->_colors = array(); + $this->_colors = array(); // Initialise workbook writer $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel, @@ -226,7 +226,7 @@ public function save($pFilename = null) { $res = $root->save($pFilename); PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); - PHPExcel_Calculation::getInstance()->writeDebugLog = $saveDebugLog; + PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = $saveDebugLog; } /** diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index d07dbd2d1..5aca92e9c 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -152,8 +152,8 @@ public function save($pFilename = null) { // garbage collect $this->_phpExcel->garbageCollect(); - $saveDebugLog = PHPExcel_Calculation::getInstance()->writeDebugLog; - PHPExcel_Calculation::getInstance()->writeDebugLog = false; + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog; + PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = false; $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); @@ -184,7 +184,7 @@ public function save($pFilename = null) { fclose($fileHandle); PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); - PHPExcel_Calculation::getInstance()->writeDebugLog = $saveDebugLog; + PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = $saveDebugLog; } /** From abb076a8175d4c39113210098ec8e4d39b334974 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 5 Feb 2013 09:52:28 +0000 Subject: [PATCH 003/467] Use direct reference to workbook in Calc Engine rather than cell's parent's parent --- Classes/PHPExcel/Calculation.php | 36 +++++++++++++------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index a2f537211..0e4f066cd 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -1829,7 +1829,6 @@ public function getCalculationCacheEnabled() { return $this->_calculationCacheEnabled; } // function getCalculationCacheEnabled() - /** * Enable/disable calculation cache * @@ -2265,7 +2264,7 @@ public function calculateFormula($formula, $cellID=null, PHPExcel_Cell $pCell = * @throws PHPExcel_Calculation_Exception */ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) { -// echo ''.$cellID.'
'; +//echo $cellID,PHP_EOL; $cellValue = ''; // Basic validation that this is indeed a formula @@ -2275,25 +2274,20 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC $formula = ltrim(substr($formula,1)); if (!isset($formula{0})) return self::_wrapResult($formula); - $wsTitle = "\x00Wrk"; - if ($pCell !== NULL) { - $pCellParent = $pCell->getParent(); - if ($pCellParent !== NULL) { - $wsTitle = $pCellParent->getTitle(); - } - } + $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL; + $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; // Is calculation cacheing enabled? if ($cellID !== NULL) { if ($this->_calculationCacheEnabled) { // Is the value present in calculation cache? $this->_writeDebug('Testing cache value for cell ', $cellID); -// echo 'Testing cache value
'; +//echo 'Testing cache value',PHP_EOL; if (isset($this->_calculationCache[$wsTitle][$cellID])) { -// echo 'Value is in cache
'; +//echo 'Value is in cache',PHP_EOL; $this->_writeDebug('Retrieving value for ', $cellID, ' from cache'); // Return the cached result $returnValue = $this->_calculationCache[$wsTitle][$cellID]; -// echo 'Retrieving data value of '.$returnValue.' for '.$cellID.' from cache
'; +//echo 'Retrieving data value of '.$returnValue.' for '.$cellID.' from cache',PHP_EOL; if (is_array($returnValue)) { $returnValue = PHPExcel_Calculation_Functions::flattenArray($returnValue); return array_shift($returnValue); @@ -2670,9 +2664,9 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { // The guts of the lexical parser // Loop through the formula extracting each operator and operand in turn while(true) { -// echo 'Assessing Expression '.substr($formula, $index).'
'; +//echo 'Assessing Expression '.substr($formula, $index),PHP_EOL; $opCharacter = $formula{$index}; // Get the first character of the value at the current index position -// echo 'Initial character of expression block is '.$opCharacter.'
'; +//echo 'Initial character of expression block is '.$opCharacter,PHP_EOL; if ((isset($comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset($comparisonOperators[$formula{$index+1}]))) { $opCharacter .= $formula{++$index}; // echo 'Initial character of expression block is comparison operator '.$opCharacter.'
'; @@ -3004,7 +2998,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), // so we store the parent worksheet so that we can re-attach it when necessary - $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null; + $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL; $stack = new PHPExcel_Calculation_Token_Stack; // Loop through each token in turn @@ -3083,7 +3077,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $pCellParent->getParent()->getSheetByName($sheet1), false); + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), false); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } @@ -3203,7 +3197,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
'; $this->_writeDebug('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $pCellParent->getParent()->getSheetByName($matches[2]), false); + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), false); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } @@ -3236,8 +3230,8 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
'; $this->_writeDebug('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== NULL) { - if ($pCellParent->getParent()->getSheetByName($matches[2])->cellExists($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $pCellParent->getParent()->getSheetByName($matches[2]), false); + if ($this->_workbook->getSheetByName($matches[2])->cellExists($cellRef)) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), false); $pCell->attach($pCellParent); } else { $cellValue = null; @@ -3618,7 +3612,7 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = n if (strpos ($pRange, '!') !== false) { // echo '$pRange reference includes sheet reference
'; $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, true); - $pSheet = $pSheet->getParent()->getSheetByName($worksheetReference[0]); + $pSheet = $this->_workbook->getSheetByName($worksheetReference[0]); // echo 'New sheet name is '.$pSheet->getTitle().'
'; $pRange = $worksheetReference[1]; // echo 'Adjusted Range reference is '.$pRange.'
'; @@ -3674,7 +3668,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = if (strpos ($pRange, '!') !== false) { // echo '$pRange reference includes sheet reference
'; $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, true); - $pSheet = $pSheet->getParent()->getSheetByName($worksheetReference[0]); + $pSheet = $this->_workbook->getSheetByName($worksheetReference[0]); // echo 'New sheet name is '.$pSheet->getTitle().'
'; $pRange = $worksheetReference[1]; // echo 'Adjusted Range reference is '.$pRange.'
'; From f05f66fa82802ef457a4862a9ae87bd5615be646 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 11 Feb 2013 14:11:36 +0000 Subject: [PATCH 004/467] Eliminate some code duplication --- Classes/PHPExcel/Calculation.php | 432 ++++++++++---------- Classes/PHPExcel/Cell.php | 5 +- Classes/PHPExcel/Chart/DataSeriesValues.php | 2 +- 3 files changed, 223 insertions(+), 216 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 0e4f066cd..e04fd6958 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -127,7 +127,7 @@ class PHPExcel_Calculation { * @access private * @var boolean */ - private $_calculationCacheEnabled = true; + private $_calculationCacheEnabled = TRUE; /** @@ -137,10 +137,10 @@ class PHPExcel_Calculation { * @access private * @var array */ - private static $_operators = array('+' => true, '-' => true, '*' => true, '/' => true, - '^' => true, '&' => true, '%' => false, '~' => false, - '>' => true, '<' => true, '=' => true, '>=' => true, - '<=' => true, '<>' => true, '|' => true, ':' => true + private static $_operators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, + '^' => TRUE, '&' => TRUE, '%' => FALSE, '~' => FALSE, + '>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, + '<=' => TRUE, '<>' => TRUE, '|' => TRUE, ':' => TRUE ); @@ -150,10 +150,10 @@ class PHPExcel_Calculation { * @access private * @var array */ - private static $_binaryOperators = array('+' => true, '-' => true, '*' => true, '/' => true, - '^' => true, '&' => true, '>' => true, '<' => true, - '=' => true, '>=' => true, '<=' => true, '<>' => true, - '|' => true, ':' => true + private static $_binaryOperators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, + '^' => TRUE, '&' => TRUE, '>' => TRUE, '<' => TRUE, + '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE, + '|' => TRUE, ':' => TRUE ); /** @@ -165,7 +165,7 @@ class PHPExcel_Calculation { * @var boolean * */ - public $suppressFormulaErrors = false; + public $suppressFormulaErrors = FALSE; /** * Error message for any error that was raised/thrown by the calculation engine @@ -174,7 +174,7 @@ class PHPExcel_Calculation { * @var string * */ - public $formulaError = null; + public $formulaError = NULL; /** * Flag to determine whether a debug log should be generated by the calculation engine @@ -185,7 +185,7 @@ class PHPExcel_Calculation { * @var boolean * */ - public $writeDebugLog = false; + public $writeDebugLog = FALSE; /** * Flag to determine whether a debug log should be echoed by the calculation engine @@ -197,7 +197,7 @@ class PHPExcel_Calculation { * @var boolean * */ - public $echoDebugLog = false; + public $echoDebugLog = FALSE; /** @@ -237,9 +237,9 @@ class PHPExcel_Calculation { // Constant conversion from text name/value to actual (datatyped) value - private static $_ExcelConstants = array('TRUE' => true, - 'FALSE' => false, - 'NULL' => null + private static $_ExcelConstants = array('TRUE' => TRUE, + 'FALSE' => FALSE, + 'NULL' => NULL ); // PHPExcel functions @@ -411,7 +411,7 @@ class PHPExcel_Calculation { 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', 'argumentCount' => '-1', - 'passByReference' => array(true) + 'passByReference' => array(TRUE) ), 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', @@ -820,7 +820,7 @@ class PHPExcel_Calculation { 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', 'argumentCount' => '1,2', - 'passCellReference'=> true + 'passCellReference'=> TRUE ), 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', @@ -909,7 +909,7 @@ class PHPExcel_Calculation { 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', 'argumentCount' => '1,2', - 'passCellReference'=> true + 'passCellReference'=> TRUE ), 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', @@ -1226,8 +1226,8 @@ class PHPExcel_Calculation { 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', 'argumentCount' => '3,5', - 'passCellReference'=> true, - 'passByReference' => array(true) + 'passCellReference'=> TRUE, + 'passByReference' => array(TRUE) ), 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', @@ -1372,7 +1372,7 @@ class PHPExcel_Calculation { 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', 'argumentCount' => '-1', - 'passByReference' => array(true) + 'passByReference' => array(TRUE) ), 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', @@ -1766,7 +1766,7 @@ public function flushInstance() { * @throws PHPExcel_Calculation_Exception */ public final function __clone() { - throw new PHPExcel_Calculation_Exception ('Cloning a Singleton is not allowed!'); + throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!'); } // function __clone() @@ -1802,10 +1802,10 @@ public static function setArrayReturnType($returnType) { ($returnType == self::RETURN_ARRAY_AS_ERROR) || ($returnType == self::RETURN_ARRAY_AS_ARRAY)) { self::$returnArrayAsType = $returnType; - return true; + return TRUE; } - return false; - } // function setExcelCalendar() + return FALSE; + } // function setArrayReturnType() /** @@ -1816,7 +1816,7 @@ public static function setArrayReturnType($returnType) { */ public static function getArrayReturnType() { return self::$returnArrayAsType; - } // function getExcelCalendar() + } // function getArrayReturnType() /** @@ -1835,7 +1835,7 @@ public function getCalculationCacheEnabled() { * @access public * @param boolean $pValue */ - public function setCalculationCacheEnabled($pValue = true) { + public function setCalculationCacheEnabled($pValue = TRUE) { $this->_calculationCacheEnabled = $pValue; $this->clearCalculationCache(); } // function setCalculationCacheEnabled() @@ -1845,7 +1845,7 @@ public function setCalculationCacheEnabled($pValue = true) { * Enable calculation cache */ public function enableCalculationCache() { - $this->setCalculationCacheEnabled(true); + $this->setCalculationCacheEnabled(TRUE); } // function enableCalculationCache() @@ -1853,7 +1853,7 @@ public function enableCalculationCache() { * Disable calculation cache */ public function disableCalculationCache() { - $this->setCalculationCacheEnabled(false); + $this->setCalculationCacheEnabled(FALSE); } // function disableCalculationCache() @@ -1883,7 +1883,7 @@ public function getLocale() { public function setLocale($locale='en_us') { // Identify our locale and language $language = $locale = strtolower($locale); - if (strpos($locale,'_') !== false) { + if (strpos($locale,'_') !== FALSE) { list($language) = explode('_',$locale); } @@ -1904,14 +1904,14 @@ public function setLocale($locale='en_us') { // If there isn't a locale specific function file, look for a language specific function file $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions'; if (!file_exists($functionNamesFile)) { - return false; + return FALSE; } } // Retrieve the list of locale or language specific function names $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($localeFunctions as $localeFunction) { list($localeFunction) = explode('##',$localeFunction); // Strip out comments - if (strpos($localeFunction,'=') !== false) { + if (strpos($localeFunction,'=') !== FALSE) { list($fName,$lfName) = explode('=',$localeFunction); $fName = trim($fName); $lfName = trim($lfName); @@ -1932,7 +1932,7 @@ public function setLocale($locale='en_us') { $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($localeSettings as $localeSetting) { list($localeSetting) = explode('##',$localeSetting); // Strip out comments - if (strpos($localeSetting,'=') !== false) { + if (strpos($localeSetting,'=') !== FALSE) { list($settingName,$settingValue) = explode('=',$localeSetting); $settingName = strtoupper(trim($settingName)); switch ($settingName) { @@ -1946,11 +1946,11 @@ public function setLocale($locale='en_us') { } self::$functionReplaceFromExcel = self::$functionReplaceToExcel = - self::$functionReplaceFromLocale = self::$functionReplaceToLocale = null; + self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL; self::$_localeLanguage = $locale; - return true; + return TRUE; } - return false; + return FALSE; } // function setLocale() @@ -1960,9 +1960,9 @@ public static function _translateSeparator($fromSeparator,$toSeparator,$formula, for ($i = 0; $i < $strlen; ++$i) { $chr = mb_substr($formula,$i,1); switch ($chr) { - case '{' : $inBraces = true; + case '{' : $inBraces = TRUE; break; - case '}' : $inBraces = false; + case '}' : $inBraces = FALSE; break; case $fromSeparator : if (!$inBraces) { @@ -1976,13 +1976,13 @@ public static function _translateSeparator($fromSeparator,$toSeparator,$formula, private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) { // Convert any Excel function names to the required language if (self::$_localeLanguage !== 'en_us') { - $inBraces = false; + $inBraces = FALSE; // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators - if (strpos($formula,'"') !== false) { + if (strpos($formula,'"') !== FALSE) { // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded // the formula $temp = explode('"',$formula); - $i = false; + $i = FALSE; foreach($temp as &$value) { // Only count/replace in alternating array entries if ($i = !$i) { @@ -2003,8 +2003,8 @@ private static function _translateFormula($from,$to,$formula,$fromSeparator,$toS return $formula; } - private static $functionReplaceFromExcel = null; - private static $functionReplaceToLocale = null; + private static $functionReplaceFromExcel = NULL; + private static $functionReplaceToLocale = NULL; public function _translateFormulaToLocale($formula) { if (self::$functionReplaceFromExcel === NULL) { @@ -2032,8 +2032,8 @@ public function _translateFormulaToLocale($formula) { } // function _translateFormulaToLocale() - private static $functionReplaceFromLocale = null; - private static $functionReplaceToExcel = null; + private static $functionReplaceFromLocale = NULL; + private static $functionReplaceToExcel = NULL; public function _translateFormulaToEnglish($formula) { if (self::$functionReplaceFromLocale === NULL) { @@ -2129,7 +2129,7 @@ public static function _unwrapResult($value) { * @return mixed * @throws PHPExcel_Calculation_Exception */ - public function calculate(PHPExcel_Cell $pCell = null) { + public function calculate(PHPExcel_Cell $pCell = NULL) { try { return $this->calculateCellValue($pCell); } catch (PHPExcel_Exception $e) { @@ -2147,24 +2147,22 @@ public function calculate(PHPExcel_Cell $pCell = null) { * @return mixed * @throws PHPExcel_Calculation_Exception */ - public function calculateCellValue(PHPExcel_Cell $pCell = null, $resetLog = true) { + public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) { + if ($pCell === NULL) { + return NULL; + } + + $returnArrayAsType = self::$returnArrayAsType; if ($resetLog) { // Initialise the logging settings if requested - $this->formulaError = null; + $this->formulaError = NULL; $this->debugLog = $this->debugLogStack = array(); $this->_cyclicFormulaCount = 1; - $returnArrayAsType = self::$returnArrayAsType; self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; } - // Read the formula from the cell - if ($pCell === NULL) { - return NULL; - } - if ($resetLog) { - self::$returnArrayAsType = $returnArrayAsType; } // Execute the calculation for the cell formula try { @@ -2174,6 +2172,7 @@ public function calculateCellValue(PHPExcel_Cell $pCell = null, $resetLog = true } if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { + self::$returnArrayAsType = $returnArrayAsType; $testResult = PHPExcel_Calculation_Functions::flattenArray($result); if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) { return PHPExcel_Calculation_Functions::VALUE(); @@ -2194,6 +2193,8 @@ public function calculateCellValue(PHPExcel_Cell $pCell = null, $resetLog = true } $result = array_shift($testResult); } + self::$returnArrayAsType = $returnArrayAsType; + if ($result === NULL) { return 0; @@ -2231,7 +2232,7 @@ public function parseFormula($formula) { * @return mixed * @throws PHPExcel_Calculation_Exception */ - public function calculateFormula($formula, $cellID=null, PHPExcel_Cell $pCell = null) { + public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) { // Initialise the logging settings $this->formulaError = null; $this->debugLog = $this->debugLogStack = array(); @@ -2254,6 +2255,25 @@ public function calculateFormula($formula, $cellID=null, PHPExcel_Cell $pCell = } // function calculateFormula() + public function getValueFromCache($worksheetName, $cellID, &$cellValue) { + // Is calculation cacheing enabled? + // Is the value present in calculation cache? + $this->_writeDebug('Testing cache value for cell ', $worksheetName, '!', $cellID); + if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$worksheetName][$cellID]))) { + $this->_writeDebug('Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache'); + // Return the cached result + $cellValue = $this->_calculationCache[$worksheetName][$cellID]; + return TRUE; + } + return FALSE; + } + + public function saveValueToCache($worksheetName, $cellID, $cellValue) { + if ($this->_calculationCacheEnabled) { + $this->_calculationCache[$worksheetName][$cellID] = $cellValue; + } + } + /** * Parse a cell formula and calculate its value * @@ -2264,11 +2284,10 @@ public function calculateFormula($formula, $cellID=null, PHPExcel_Cell $pCell = * @throws PHPExcel_Calculation_Exception */ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) { -//echo $cellID,PHP_EOL; $cellValue = ''; // Basic validation that this is indeed a formula - // We simply return the "cell value" (formula) if not + // We simply return the cell value if not $formula = trim($formula); if ($formula{0} != '=') return self::_wrapResult($formula); $formula = ltrim(substr($formula,1)); @@ -2276,28 +2295,12 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL; $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; - // Is calculation cacheing enabled? - if ($cellID !== NULL) { - if ($this->_calculationCacheEnabled) { - // Is the value present in calculation cache? - $this->_writeDebug('Testing cache value for cell ', $cellID); -//echo 'Testing cache value',PHP_EOL; - if (isset($this->_calculationCache[$wsTitle][$cellID])) { -//echo 'Value is in cache',PHP_EOL; - $this->_writeDebug('Retrieving value for ', $cellID, ' from cache'); - // Return the cached result - $returnValue = $this->_calculationCache[$wsTitle][$cellID]; -//echo 'Retrieving data value of '.$returnValue.' for '.$cellID.' from cache',PHP_EOL; - if (is_array($returnValue)) { - $returnValue = PHPExcel_Calculation_Functions::flattenArray($returnValue); - return array_shift($returnValue); - } - return $returnValue; - } - } + + if (($cellID !== NULL) && ($this->getValueFromCache($wsTitle, $cellID, $cellValue))) { + return $cellValue; } - if ((in_array($wsTitle.'!'.$cellID,$this->debugLogStack)) && ($wsTitle != "\x00Wrk")) { + if (($wsTitle{0} !== "\x00") && (in_array($wsTitle.'!'.$cellID,$this->debugLogStack))) { if ($this->cyclicFormulaCount <= 0) { return $this->_raiseFormulaError('Cyclic Reference in Formula'); } elseif (($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) && @@ -2322,9 +2325,7 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC // Save to calculation cache if ($cellID !== NULL) { - if ($this->_calculationCacheEnabled) { - $this->_calculationCache[$wsTitle][$cellID] = $cellValue; - } + $this->saveValueToCache($wsTitle, $cellID, $cellValue); } // Return the calculated value @@ -2555,15 +2556,15 @@ private static function _convertMatrixReferences($formula) { static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))'); // Convert any Excel matrix references to the MKMATRIX() function - if (strpos($formula,'{') !== false) { + if (strpos($formula,'{') !== FALSE) { // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators - if (strpos($formula,'"') !== false) { + if (strpos($formula,'"') !== FALSE) { // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded // the formula $temp = explode('"',$formula); // Open and Closed counts used for trapping mismatched braces in the formula $openCount = $closeCount = 0; - $i = false; + $i = FALSE; foreach($temp as &$value) { // Only count/replace in alternating array entries if ($i = !$i) { @@ -2606,9 +2607,40 @@ private static function _mkMatrix() { } // function _mkMatrix() + // Binary Operators + // These operators always work on two values + // Array key is the operator, the value indicates whether this is a left or right associative operator + private static $_operatorAssociativity = array( + '^' => 0, // Exponentiation + '*' => 0, '/' => 0, // Multiplication and Division + '+' => 0, '-' => 0, // Addition and Subtraction + '&' => 0, // Concatenation + '|' => 0, ':' => 0, // Intersect and Range + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison + ); + + // Comparison (Boolean) Operators + // These operators work on two values, but always return a boolean result + private static $_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE); + + // Operator Precedence + // This list includes all valid operators, whether binary (including boolean) or unary (such as %) + // Array key is the operator, the value is its precedence + private static $_operatorPrecedence = array( + ':' => 8, // Range + '|' => 7, // Intersect + '~' => 6, // Negation + '%' => 5, // Percentage + '^' => 4, // Exponentiation + '*' => 3, '/' => 3, // Multiplication and Division + '+' => 2, '-' => 2, // Addition and Subtraction + '&' => 1, // Concatenation + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison + ); + // Convert infix to postfix notation - private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { - if (($formula = self::_convertMatrixReferences(trim($formula))) === false) { + private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { + if (($formula = self::_convertMatrixReferences(trim($formula))) === FALSE) { return FALSE; } @@ -2616,34 +2648,6 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { // so we store the parent worksheet so that we can re-attach it when necessary $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL; - // Binary Operators - // These operators always work on two values - // Array key is the operator, the value indicates whether this is a left or right associative operator - $operatorAssociativity = array('^' => 0, // Exponentiation - '*' => 0, '/' => 0, // Multiplication and Division - '+' => 0, '-' => 0, // Addition and Subtraction - '&' => 0, // Concatenation - '|' => 0, ':' => 0, // Intersect and Range - '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison - ); - // Comparison (Boolean) Operators - // These operators work on two values, but always return a boolean result - $comparisonOperators = array('>' => true, '<' => true, '=' => true, '>=' => true, '<=' => true, '<>' => true); - - // Operator Precedence - // This list includes all valid operators, whether binary (including boolean) or unary (such as %) - // Array key is the operator, the value is its precedence - $operatorPrecedence = array(':' => 8, // Range - '|' => 7, // Intersect - '~' => 6, // Negation - '%' => 5, // Percentage - '^' => 4, // Exponentiation - '*' => 3, '/' => 3, // Multiplication and Division - '+' => 2, '-' => 2, // Addition and Subtraction - '&' => 1, // Concatenation - '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison - ); - $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION. '|'.self::CALCULATION_REGEXP_NUMBER. '|'.self::CALCULATION_REGEXP_STRING. @@ -2657,55 +2661,55 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { $index = 0; $stack = new PHPExcel_Calculation_Token_Stack; $output = array(); - $expectingOperator = false; // We use this test in syntax-checking the expression to determine when a + $expectingOperator = FALSE; // We use this test in syntax-checking the expression to determine when a // - is a negation or + is a positive operator rather than an operation - $expectingOperand = false; // We use this test in syntax-checking the expression to determine whether an operand + $expectingOperand = FALSE; // We use this test in syntax-checking the expression to determine whether an operand // should be null in a function call // The guts of the lexical parser // Loop through the formula extracting each operator and operand in turn - while(true) { + while(TRUE) { //echo 'Assessing Expression '.substr($formula, $index),PHP_EOL; $opCharacter = $formula{$index}; // Get the first character of the value at the current index position //echo 'Initial character of expression block is '.$opCharacter,PHP_EOL; - if ((isset($comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset($comparisonOperators[$formula{$index+1}]))) { + if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) { $opCharacter .= $formula{++$index}; -// echo 'Initial character of expression block is comparison operator '.$opCharacter.'
'; +//echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL; } // Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match); -// echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').'
'; -// var_dump($match); +//echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').PHP_EOL; +//var_dump($match); if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus? -// echo 'Element is a Negation operator
'; +//echo 'Element is a Negation operator',PHP_EOL; $stack->push('Unary Operator','~'); // Put a negation on the stack ++$index; // and drop the negation symbol } elseif ($opCharacter == '%' && $expectingOperator) { -// echo 'Element is a Percentage operator
'; +//echo 'Element is a Percentage operator',PHP_EOL; $stack->push('Unary Operator','%'); // Put a percentage on the stack ++$index; } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded? -// echo 'Element is a Positive number, not Plus operator
'; +//echo 'Element is a Positive number, not Plus operator',PHP_EOL; ++$index; // Drop the redundant plus symbol } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? -// echo 'Element with value '.$opCharacter.' is an Operator
'; +//echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL; while($stack->count() > 0 && ($o2 = $stack->last()) && isset(self::$_operators[$o2['value']]) && - @($operatorAssociativity[$opCharacter] ? $operatorPrecedence[$opCharacter] < $operatorPrecedence[$o2['value']] : $operatorPrecedence[$opCharacter] <= $operatorPrecedence[$o2['value']])) { + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack ++$index; - $expectingOperator = false; + $expectingOperator = FALSE; } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis? -// echo 'Element is a Closing bracket
'; - $expectingOperand = false; +//echo 'Element is a Closing bracket',PHP_EOL; + $expectingOperand = FALSE; while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"'); else $output[] = $o2; @@ -2713,65 +2717,65 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { $d = $stack->last(2); if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function? $functionName = $matches[1]; // Get the function name -// echo 'Closed Function is '.$functionName.'
'; +//echo 'Closed Function is '.$functionName,PHP_EOL; $d = $stack->pop(); $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack) -// if ($argumentCount == 0) { -// echo 'With no arguments
'; -// } elseif ($argumentCount == 1) { -// echo 'With 1 argument
'; -// } else { -// echo 'With '.$argumentCount.' arguments
'; -// } +//if ($argumentCount == 0) { +// echo 'With no arguments',PHP_EOL; +//} elseif ($argumentCount == 1) { +// echo 'With 1 argument',PHP_EOL; +//} else { +// echo 'With '.$argumentCount.' arguments',PHP_EOL; +//} $output[] = $d; // Dump the argument count on the output $output[] = $stack->pop(); // Pop the function and push onto the output if (isset(self::$_controlFunctions[$functionName])) { -// echo 'Built-in function '.$functionName.'
'; +//echo 'Built-in function '.$functionName,PHP_EOL; $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount']; $functionCall = self::$_controlFunctions[$functionName]['functionCall']; } elseif (isset(self::$_PHPExcelFunctions[$functionName])) { -// echo 'PHPExcel function '.$functionName.'
'; +//echo 'PHPExcel function '.$functionName,PHP_EOL; $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount']; $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; } else { // did we somehow push a non-function on the stack? this should never happen return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack"); } // Check the argument count - $argumentCountError = false; + $argumentCountError = FALSE; if (is_numeric($expectedArgumentCount)) { if ($expectedArgumentCount < 0) { -// echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount).'
'; +//echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount),PHP_EOL; if ($argumentCount > abs($expectedArgumentCount)) { - $argumentCountError = true; + $argumentCountError = TRUE; $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount); } } else { -// echo '$expectedArgumentCount is numeric '.$expectedArgumentCount.'
'; +//echo '$expectedArgumentCount is numeric '.$expectedArgumentCount,PHP_EOL; if ($argumentCount != $expectedArgumentCount) { - $argumentCountError = true; + $argumentCountError = TRUE; $expectedArgumentCountString = $expectedArgumentCount; } } } elseif ($expectedArgumentCount != '*') { $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch); -// print_r($argMatch); -// echo '
'; +//print_r($argMatch); +//echo PHP_EOL; switch ($argMatch[2]) { case '+' : if ($argumentCount < $argMatch[1]) { - $argumentCountError = true; + $argumentCountError = TRUE; $expectedArgumentCountString = $argMatch[1].' or more '; } break; case '-' : if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) { - $argumentCountError = true; + $argumentCountError = TRUE; $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3]; } break; case ',' : if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) { - $argumentCountError = true; + $argumentCountError = TRUE; $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3]; } break; @@ -2784,7 +2788,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { ++$index; } elseif ($opCharacter == ',') { // Is this the separator for function arguments? -// echo 'Element is a Function argument separator
'; +//echo 'Element is a Function argument separator',PHP_EOL; while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,"); else $output[] = $o2; // pop the argument expression stuff and push onto the output @@ -2792,7 +2796,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { // If we've a comma when we're expecting an operand, then what we actually have is a null operand; // so push a null onto the stack if (($expectingOperand) || (!$expectingOperator)) { - $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => null); + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); } // make sure there was a function $d = $stack->last(2); @@ -2801,8 +2805,8 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { $d = $stack->pop(); $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again - $expectingOperator = false; - $expectingOperand = true; + $expectingOperator = FALSE; + $expectingOperand = TRUE; ++$index; } elseif ($opCharacter == '(' && !$expectingOperator) { @@ -2811,8 +2815,8 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { ++$index; } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number? - $expectingOperator = true; - $expectingOperand = false; + $expectingOperator = TRUE; + $expectingOperand = FALSE; $val = $match[1]; $length = strlen($val); // echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function
'; @@ -2825,14 +2829,14 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { $ax = preg_match('/^\s*(\s*\))/i', substr($formula, $index+$length), $amatch); if ($ax) { $stack->push('Operand Count for Function '.strtoupper($val).')', 0); - $expectingOperator = true; + $expectingOperator = TRUE; } else { $stack->push('Operand Count for Function '.strtoupper($val).')', 1); - $expectingOperator = false; + $expectingOperator = FALSE; } $stack->push('Brace', '('); } else { // it's a var w/ implicit multiplication - $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => null); + $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL); } } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) { // echo 'Element '.$val.' is a Cell reference
'; @@ -2857,7 +2861,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { } $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val); -// $expectingOperator = false; +// $expectingOperator = FALSE; } else { // it's a variable, constant, string, number or boolean // echo 'Element is a Variable, Constant, String, Number or Boolean
'; // If the last entry on the stack was a : operator, then we may have a row or column range reference @@ -2865,12 +2869,12 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { if ($testPrevOp['value'] == ':') { $startRowColRef = $output[count($output)-1]['value']; $rangeWS1 = ''; - if (strpos('!',$startRowColRef) !== false) { + if (strpos('!',$startRowColRef) !== FALSE) { list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef); } if ($rangeWS1 != '') $rangeWS1 .= '!'; $rangeWS2 = $rangeWS1; - if (strpos('!',$val) !== false) { + if (strpos('!',$val) !== FALSE) { list($rangeWS2,$val) = explode('!',$val); } if ($rangeWS2 != '') $rangeWS2 .= '!'; @@ -2889,14 +2893,14 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { } } - $localeConstant = false; + $localeConstant = FALSE; if ($opCharacter == '"') { // echo 'Element is a String
'; // UnEscape any quotes within the string $val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val))); } elseif (is_numeric($val)) { // echo 'Element is a Number
'; - if ((strpos($val,'.') !== false) || (stripos($val,'e') !== false) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { + if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { // echo 'Casting '.$val.' to float
'; $val = (float) $val; } else { @@ -2907,11 +2911,11 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { $excelConstant = trim(strtoupper($val)); // echo 'Element '.$excelConstant.' is an Excel Constant
'; $val = self::$_ExcelConstants[$excelConstant]; - } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== false) { + } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) { // echo 'Element '.$localeConstant.' is an Excel Constant
'; $val = self::$_ExcelConstants[$localeConstant]; } - $details = array('type' => 'Value', 'value' => $val, 'reference' => null); + $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL); if ($localeConstant) { $details['localeValue'] = $localeConstant; } $output[] = $details; } @@ -2921,9 +2925,9 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { ++$index; } elseif ($opCharacter == ')') { // miscellaneous error checking if ($expectingOperand) { - $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => null); - $expectingOperand = false; - $expectingOperator = true; + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); + $expectingOperand = FALSE; + $expectingOperator = TRUE; } else { return $this->_raiseFormulaError("Formula Error: Unexpected ')'"); } @@ -2959,11 +2963,11 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { while($stack->count() > 0 && ($o2 = $stack->last()) && isset(self::$_operators[$o2['value']]) && - @($operatorAssociativity[$opCharacter] ? $operatorPrecedence[$opCharacter] < $operatorPrecedence[$o2['value']] : $operatorPrecedence[$opCharacter] <= $operatorPrecedence[$o2['value']])) { + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } $stack->push('Binary Operator','|'); // Put an Intersect Operator on the stack - $expectingOperator = false; + $expectingOperator = FALSE; } } } @@ -2993,8 +2997,8 @@ private static function _dataTestReference(&$operandData) } // evaluate postfix notation - private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCell = null) { - if ($tokens == false) return false; + private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) { + if ($tokens == FALSE) return FALSE; // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), // so we store the parent worksheet so that we can re-attach it when necessary @@ -3038,12 +3042,12 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // Binary Operators case ':' : // Range $sheet1 = $sheet2 = ''; - if (strpos($operand1Data['reference'],'!') !== false) { + if (strpos($operand1Data['reference'],'!') !== FALSE) { list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']); } else { $sheet1 = ($pCellParent !== NULL) ? $pCellParent->getTitle() : ''; } - if (strpos($operand2Data['reference'],'!') !== false) { + if (strpos($operand2Data['reference'],'!') !== FALSE) { list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']); } else { $sheet2 = $sheet1; @@ -3077,13 +3081,13 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), false); + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } $stack->push('Cell Reference',$cellValue,$cellRef); } else { - $stack->push('Error',PHPExcel_Calculation_Functions::REF(),null); + $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL); } break; @@ -3178,7 +3182,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { - $cellRef = null; + $cellRef = NULL; // echo 'Element '.$token.' is a Cell reference
'; if (isset($matches[8])) { // echo 'Reference is a Range of cells
'; @@ -3189,7 +3193,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10]; if ($matches[2] > '') { $matches[2] = trim($matches[2],"\"'"); - if ((strpos($matches[2],'[') !== false) || (strpos($matches[2],']') !== false)) { + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { // It's a Reference to an external workbook (not currently supported) return $this->_raiseFormulaError('Unable to access External Workbook'); } @@ -3197,7 +3201,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
'; $this->_writeDebug('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), false); + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } @@ -3207,7 +3211,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // echo '$cellRef='.$cellRef.' in current worksheet
'; $this->_writeDebug('Evaluating Cell Range ', $cellRef, ' in current worksheet'); if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $pCellParent, false); + $cellValue = $this->extractCellRange($cellRef, $pCellParent, FALSE); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } @@ -3223,7 +3227,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $cellRef = $matches[6].$matches[7]; if ($matches[2] > '') { $matches[2] = trim($matches[2],"\"'"); - if ((strpos($matches[2],'[') !== false) || (strpos($matches[2],']') !== false)) { + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { // It's a Reference to an external workbook (not currently supported) return $this->_raiseFormulaError('Unable to access External Workbook'); } @@ -3231,10 +3235,10 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $this->_writeDebug('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== NULL) { if ($this->_workbook->getSheetByName($matches[2])->cellExists($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), false); + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); $pCell->attach($pCellParent); } else { - $cellValue = null; + $cellValue = NULL; } } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); @@ -3245,10 +3249,10 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // echo '$cellRef='.$cellRef.' in current worksheet
'; $this->_writeDebug('Evaluating Cell ', $cellRef, ' in current worksheet'); if ($pCellParent->cellExists($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $pCellParent, false); + $cellValue = $this->extractCellRange($cellRef, $pCellParent, FALSE); $pCell->attach($pCellParent); } else { - $cellValue = null; + $cellValue = NULL; } $this->_writeDebug('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); } @@ -3338,7 +3342,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel if ($passCellReference) { $args[] = $pCell; } - if (strpos($functionCall,'::') !== false) { + if (strpos($functionCall,'::') !== FALSE) { $result = call_user_func_array(explode('::',$functionCall),$args); } else { foreach($args as &$arg) { @@ -3370,7 +3374,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $namedRange = $matches[6]; // echo 'Named Range is '.$namedRange.'
'; $this->_writeDebug('Evaluating Named Range ', $namedRange); - $cellValue = $this->extractNamedRange($namedRange, ((null !== $pCell) ? $pCellParent : null), false); + $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellParent : NULL), FALSE); $pCell->attach($pCellParent); $this->_writeDebug('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); $stack->push('Named Range',$cellValue,$namedRange); @@ -3391,7 +3395,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } // function _processTokenStack() - private function _validateBinaryOperand($cellID,&$operand,&$stack) { + private function _validateBinaryOperand($cellID, &$operand, &$stack) { // Numbers, matrices and booleans can pass straight through, as they're already valid if (is_string($operand)) { // We only need special validations for the operand if it is a string @@ -3403,22 +3407,22 @@ private function _validateBinaryOperand($cellID,&$operand,&$stack) { if ($operand > '' && $operand{0} == '#') { $stack->push('Value', $operand); $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($operand)); - return false; + return FALSE; } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations $stack->push('Value', '#VALUE!'); $this->_writeDebug('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); - return false; + return FALSE; } } } // return a true if the value of the operand is one that we can use in normal binary operations - return true; + return TRUE; } // function _validateBinaryOperand() - private function _executeBinaryComparisonOperation($cellID,$operand1,$operand2,$operation,&$stack,$recursingArrays=false) { + private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) { // If we're dealing with matrix operations, we want a matrix result if ((is_array($operand1)) || (is_array($operand2))) { $result = array(); @@ -3440,7 +3444,7 @@ private function _executeBinaryComparisonOperation($cellID,$operand1,$operand2,$ if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } foreach($operand1 as $x => $operandData) { $this->_writeDebug('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); - $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,true); + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); $r = $stack->pop(); $result[$x] = $r['value']; } @@ -3449,7 +3453,7 @@ private function _executeBinaryComparisonOperation($cellID,$operand1,$operand2,$ $this->_writeDebug('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack $stack->push('Array',$result); - return true; + return TRUE; } // Simple validate the two operands if they are string values @@ -3488,28 +3492,28 @@ private function _executeBinaryComparisonOperation($cellID,$operand1,$operand2,$ $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack $stack->push('Value',$result); - return true; + return TRUE; } // function _executeBinaryComparisonOperation() private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { // Validate the two operands - if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return false; - if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return false; + if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; + if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; - $executeMatrixOperation = false; + $executeMatrixOperation = FALSE; // If either of the operands is a matrix, we need to treat them both as matrices // (converting the other operand to a matrix if need be); then perform the required // matrix operation if ((is_array($operand1)) || (is_array($operand2))) { // Ensure that both operands are arrays/matrices - $executeMatrixOperation = true; + $executeMatrixOperation = TRUE; $mSize = array(); list($mSize[],$mSize[],$mSize[],$mSize[]) = self::_checkMatrixOperands($operand1,$operand2,2); // But if they're both single cell matrices, then we can treat them as simple values if (array_sum($mSize) == 4) { - $executeMatrixOperation = false; + $executeMatrixOperation = FALSE; $operand1 = $operand1[0][0]; $operand2 = $operand2[0][0]; } @@ -3551,7 +3555,7 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope // Trap for Divide by Zero error $stack->push('Value','#DIV/0!'); $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); - return false; + return FALSE; } else { $result = $operand1/$operand2; } @@ -3568,7 +3572,7 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack $stack->push('Value',$result); - return true; + return TRUE; } // function _executeNumericBinaryOperation() @@ -3601,7 +3605,7 @@ protected function _raiseFormulaError($errorMessage) { * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. * @throws PHPExcel_Calculation_Exception */ - public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = null, $resetLog=true) { + public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog=TRUE) { // Return value $returnValue = array (); @@ -3609,9 +3613,9 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = n if ($pSheet !== NULL) { // echo 'Passed sheet name is '.$pSheet->getTitle().'
'; // echo 'Range reference is '.$pRange.'
'; - if (strpos ($pRange, '!') !== false) { + if (strpos ($pRange, '!') !== FALSE) { // echo '$pRange reference includes sheet reference
'; - $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, true); + $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, TRUE); $pSheet = $this->_workbook->getSheetByName($worksheetReference[0]); // echo 'New sheet name is '.$pSheet->getTitle().'
'; $pRange = $worksheetReference[1]; @@ -3627,7 +3631,7 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = n if ($pSheet->cellExists($aReferences[0])) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); } else { - $returnValue[$currentRow][$currentCol] = null; + $returnValue[$currentRow][$currentCol] = NULL; } } else { // Extract cell data for all cells in the range @@ -3638,7 +3642,7 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = n if ($pSheet->cellExists($reference)) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); } else { - $returnValue[$currentRow][$currentCol] = null; + $returnValue[$currentRow][$currentCol] = NULL; } } } @@ -3657,7 +3661,7 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = n * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. * @throws PHPExcel_Calculation_Exception */ - public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = null, $resetLog=true) { + public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog=TRUE) { // Return value $returnValue = array (); @@ -3665,9 +3669,9 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = if ($pSheet !== NULL) { // echo 'Current sheet name is '.$pSheet->getTitle().'
'; // echo 'Range reference is '.$pRange.'
'; - if (strpos ($pRange, '!') !== false) { + if (strpos ($pRange, '!') !== FALSE) { // echo '$pRange reference includes sheet reference
'; - $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, true); + $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, TRUE); $pSheet = $this->_workbook->getSheetByName($worksheetReference[0]); // echo 'New sheet name is '.$pSheet->getTitle().'
'; $pRange = $worksheetReference[1]; @@ -3709,7 +3713,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = if ($pSheet->cellExists($aReferences[0])) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); } else { - $returnValue[$currentRow][$currentCol] = null; + $returnValue[$currentRow][$currentCol] = NULL; } } else { // Extract cell data for all cells in the range @@ -3720,7 +3724,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = if ($pSheet->cellExists($reference)) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); } else { - $returnValue[$currentRow][$currentCol] = null; + $returnValue[$currentRow][$currentCol] = NULL; } } } @@ -3744,7 +3748,7 @@ public function isImplemented($pFunction = '') { if (isset(self::$_PHPExcelFunctions[$pFunction])) { return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); } else { - return false; + return FALSE; } } // function isImplemented() diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index ea37c7ecc..ab8b472cb 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -288,7 +288,10 @@ public function getCalculatedValue($resetLog = TRUE) if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { try { // echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value
'; - $result = $this->getParent()->getParent()->getCalculationEngine()->calculateCellValue($this,$resetLog); + $result = PHPExcel_Calculation::getInstance( + $this->getParent()->getParent() + )->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)) { diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index 4a2064820..034ac9e21 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -279,7 +279,7 @@ private function _stripNulls($var) { public function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) { if ($this->_dataSource !== NULL) { - $calcEngine = PHPExcel_Calculation::getInstance(); + $calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent()); $newDataValues = PHPExcel_Calculation::_unwrapResult( $calcEngine->_calculateFormulaValue( '='.$this->_dataSource, From b589fab56bbe12e9378a901dbf6a06cdbff14020 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 12 Feb 2013 12:44:31 +0000 Subject: [PATCH 005/467] Selective calculation cache clearance and adjustment for unsetting or renaming worksheets --- Classes/PHPExcel.php | 41 +++++++++++++++++++--------- Classes/PHPExcel/Calculation.php | 19 +++++++++++++ Classes/PHPExcel/Worksheet.php | 46 +++++++++++++++++++++++--------- 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index 901cb16df..ff6a10d72 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -143,8 +143,7 @@ public function __construct() $this->addCellStyleXf(new PHPExcel_Style); } - - /** + /** * Destroy this workbook */ public function __destruct() { @@ -157,7 +156,9 @@ public function __destruct() { * typically so that the PHPExcel object can be unset * */ - public function disconnectWorksheets() { + public function disconnectWorksheets() + { + $worksheet = NULL; foreach($this->_workSheetCollection as $k => &$worksheet) { $worksheet->disconnectCells(); $this->_workSheetCollection[$k] = null; @@ -171,8 +172,8 @@ public function disconnectWorksheets() { * * @return PHPExcel_Calculation */ - public function getCalculationEngine() { - + public function getCalculationEngine() + { return $this->_calculationEngine; } // function getCellCacheController() @@ -262,7 +263,9 @@ public function sheetNameExists($pSheetName) public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = NULL) { if ($this->sheetNameExists($pSheet->getTitle())) { - throw new PHPExcel_Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first."); + throw new PHPExcel_Exception( + "Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first." + ); } if($iSheetIndex === NULL) { @@ -295,8 +298,13 @@ public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = NULL) */ public function removeSheetByIndex($pIndex = 0) { - if ($pIndex > count($this->_workSheetCollection) - 1) { - throw new PHPExcel_Exception("Sheet index is out of bounds."); + + $numSheets = count($this->_workSheetCollection); + + if ($pIndex > $numSheets - 1) { + throw new PHPExcel_Exception( + "You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}." + ); } else { array_splice($this->_workSheetCollection, $pIndex, 1); } @@ -317,8 +325,13 @@ public function removeSheetByIndex($pIndex = 0) */ public function getSheet($pIndex = 0) { - if ($pIndex > count($this->_workSheetCollection) - 1) { - throw new PHPExcel_Exception("Sheet index is out of bounds."); + + $numSheets = count($this->_workSheetCollection); + + if ($pIndex > $numSheets - 1) { + throw new PHPExcel_Exception( + "Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}." + ); } else { return $this->_workSheetCollection[$pIndex]; } @@ -424,8 +437,12 @@ public function getActiveSheetIndex() */ public function setActiveSheetIndex($pIndex = 0) { - if ($pIndex > count($this->_workSheetCollection) - 1) { - throw new PHPExcel_Exception("Active sheet index is out of bounds."); + $numSheets = count($this->_workSheetCollection); + + if ($pIndex > $numSheets - 1) { + throw new PHPExcel_Exception( + "You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}." + ); } else { $this->_activeSheetIndex = $pIndex; } diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index e04fd6958..a1e51bc41 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -1864,6 +1864,25 @@ public function clearCalculationCache() { $this->_calculationCache = array(); } // function clearCalculationCache() + /** + * Clear calculation cache for a specified worksheet + */ + public function clearCalculationCacheForWorksheet($worksheetName) { + if (isset($this->_calculationCache[$worksheetName])) { + unset($this->_calculationCache[$worksheetName]); + } + } // function clearCalculationCache() + + /** + * Rename calculation cache for a specified worksheet + */ + public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) { + if (isset($this->_calculationCache[$fromWorksheetName])) { + $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName]; + unset($this->_calculationCache[$fromWorksheetName]); + } + } // function clearCalculationCache() + /** * Get the currently defined locale code diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index ec201ab59..5a0ea5444 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -378,13 +378,25 @@ public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') */ public function disconnectCells() { $this->_cellCollection->unsetWorksheetCells(); - $this->_cellCollection = null; + $this->_cellCollection = NULL; // detach ourself from the workbook, so that it can then delete this worksheet successfully $this->_parent = null; } /** + * Code to execute when this worksheet is unset() + * + */ + function __destruct() { + if ($this->_cellCollection !== NULL) { + $this->disconnectCells(); + } + PHPExcel_Calculation::getInstance($this->_parent) + ->clearCalculationCacheForWorksheet($this->_title); + } + + /** * Return the cache controller for the cell collection * * @return PHPExcel_CachedObjectStorage_xxx @@ -703,14 +715,20 @@ public function calculateColumnWidths($calculateMergeCells = false) $cellValue = $cell->getCalculatedValue(); // To formatted string - $cellValue = PHPExcel_Style_NumberFormat::toFormattedString($cellValue, $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode()); + $cellValue = PHPExcel_Style_NumberFormat::toFormattedString( + $cellValue, + $this->_parent->getCellXfByIndex($cell->getXfIndex()) + ->getNumberFormat()->getFormatCode() + ); $autoSizes[$cell->getColumn()] = max( (float)$autoSizes[$cell->getColumn()], (float)PHPExcel_Shared_Font::calculateColumnWidth( - $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(), + $this->_parent->getCellXfByIndex($cell->getXfIndex()) + ->getFont(), $cellValue, - $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(), + $this->_parent->getCellXfByIndex($cell->getXfIndex()) + ->getAlignment()->getTextRotation(), $this->getDefaultStyle()->getFont() ) ); @@ -791,16 +809,16 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t // Old title $oldTitle = $this->getTitle(); - if ($this->getParent()) { + if ($this->_parent) { // Is there already such sheet name? - if ($this->getParent()->sheetNameExists($pValue)) { + if ($this->_parent->sheetNameExists($pValue)) { // Use name, but append with lowest possible integer if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); } $i = 1; - while ($this->getParent()->sheetNameExists($pValue . ' ' . $i)) { + while ($this->_parent->sheetNameExists($pValue . ' ' . $i)) { ++$i; if ($i == 10) { if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { @@ -822,11 +840,13 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t $this->_title = $pValue; $this->_dirty = true; - if ($this->getParent()) { + if ($this->_parent) { // New title $newTitle = $this->getTitle(); + PHPExcel_Calculation::getInstance($this->_parent) + ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); if ($updateFormulaCellReferences) - PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->getParent(), $oldTitle, $newTitle); + PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_parent, $oldTitle, $newTitle); } return $this; @@ -1092,7 +1112,7 @@ public function getCell($pCoordinate = 'A1') // Worksheet reference? if (strpos($pCoordinate, '!') !== false) { $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); - return $this->getParent()->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]); + return $this->_parent->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]); } // Named range? @@ -1184,7 +1204,7 @@ public function cellExists($pCoordinate = 'A1') // Worksheet reference? if (strpos($pCoordinate, '!') !== false) { $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); - return $this->getParent()->getSheetByName($worksheetReference[0])->cellExists($worksheetReference[1]); + return $this->_parent->getSheetByName($worksheetReference[0])->cellExists($worksheetReference[1]); } // Named range? @@ -2416,7 +2436,9 @@ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormul if ($formatData) { $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); - $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString($returnValue[$rRef][$cRef], $style->getNumberFormat()->getFormatCode()); + $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString( + $returnValue[$rRef][$cRef], $style->getNumberFormat()->getFormatCode() + ); } } else { // Cell holds a NULL From 6fd6b4d0443aca9d8f29d4de2f168b12e1512e21 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 13 Feb 2013 13:17:16 +0000 Subject: [PATCH 006/467] Fix PHPExcel object destructor --- Classes/PHPExcel.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index 4116b6c4d..99435ca7a 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -143,8 +143,9 @@ public function __construct() $this->addCellStyleXf(new PHPExcel_Style); } - /** - * Destroy this workbook + /** + * Code to execute when this worksheet is unset() + * */ public function __destruct() { PHPExcel_Calculation::unsetInstance($this); @@ -177,14 +178,6 @@ public function getCalculationEngine() return $this->_calculationEngine; } // function getCellCacheController() - /** - * Code to execute when this worksheet is unset() - * - */ - function __destruct() { - $this->disconnectWorksheets(); - } - /** * Get properties * From 3886c47ebe1700009c89df9c25f2df94ea59236f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 15 Feb 2013 15:42:06 +0000 Subject: [PATCH 007/467] Refactoring of calculation engine using the multiton pattern to eliminate caching issues when working with multiple workbooks Refactoring of calculation engine for improved performance and memory usage Refactoring of cell object to eliminate data duplication and reduce memory --- Classes/PHPExcel.php | 4 +- .../CachedObjectStorage/CacheBase.php | 22 + .../PHPExcel/CachedObjectStorage/Memory.php | 10 +- Classes/PHPExcel/CalcEngine/Logger.php | 109 + Classes/PHPExcel/Calculation.php | 238 +- Classes/PHPExcel/Calculation/Token/Stack.php | 4 +- Classes/PHPExcel/Cell.php | 63 +- Classes/PHPExcel/Worksheet.php | 5083 ++++++++--------- Classes/PHPExcel/Writer/CSV.php | 6 +- Classes/PHPExcel/Writer/Excel2007.php | 6 +- .../PHPExcel/Writer/Excel2007/Worksheet.php | 11 +- Classes/PHPExcel/Writer/Excel5.php | 8 +- Classes/PHPExcel/Writer/HTML.php | 6 +- 13 files changed, 2838 insertions(+), 2732 deletions(-) create mode 100644 Classes/PHPExcel/CalcEngine/Logger.php diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index 99435ca7a..19213c246 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -70,7 +70,7 @@ class PHPExcel */ private $_workSheetCollection = array(); - /** + /** * Calculation Engine * * @var PHPExcel_Calculation @@ -878,7 +878,7 @@ public function garbageCollect() $columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] ); } - // also do garbage collection for all the sheets + // also do garbage collection for all the sheets $sheet->garbageCollect(); } } diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index 924b4b441..0651b4a3a 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -86,6 +86,11 @@ public function __construct(PHPExcel_Worksheet $parent) { } // function __construct() + public function getParent() + { + return $this->_parent; + } + /** * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? * @@ -188,6 +193,23 @@ public function getHighestRowAndColumn() } + public function getCurrentAddress() + { + return $this->_currentObjectID; + } + + public function getCurrentColumn() + { + list($column,$row) = sscanf($this->_currentObjectID, '%[A-Z]%d'); + return $column; + } + + public function getCurrentRow() + { + list($column,$row) = sscanf($this->_currentObjectID, '%[A-Z]%d'); + return $row; + } + /** * Get highest worksheet column * diff --git a/Classes/PHPExcel/CachedObjectStorage/Memory.php b/Classes/PHPExcel/CachedObjectStorage/Memory.php index 416b1e477..1e05b062f 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memory.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memory.php @@ -48,11 +48,15 @@ protected function _storeData() { * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { $this->_cellCache[$pCoord] = $cell; + + // Set current entry to the new/updated entry + $this->_currentObjectID = $pCoord; + return $cell; } // function addCacheData() @@ -67,10 +71,14 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) { public function getCacheData($pCoord) { // Check if the entry that has been requested actually exists if (!isset($this->_cellCache[$pCoord])) { + $this->_currentObjectID = NULL; // Return null if requested entry doesn't exist in cache return null; } + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + // Return requested entry return $this->_cellCache[$pCoord]; } // function getCacheData() diff --git a/Classes/PHPExcel/CalcEngine/Logger.php b/Classes/PHPExcel/CalcEngine/Logger.php new file mode 100644 index 000000000..2cb893efa --- /dev/null +++ b/Classes/PHPExcel/CalcEngine/Logger.php @@ -0,0 +1,109 @@ +_writeDebugLog = $pValue; + } + + public function getWriteDebugLog() { + return $this->_writeDebugLog; + } + + public function setEchoDebugLog($pValue = FALSE) { + $this->_echoDebugLog = $pValue; + } + + public function getEchoDebugLog() { + return $this->_echoDebugLog; + } + + public function writeDebugLog(array $cellReferencePath) { + // Only write the debug log if logging is enabled + if ($this->_writeDebugLog) { + $message = func_get_args(); + array_shift($message); + $cellReference = implode(' -> ', $cellReferencePath); + $message = implode($message); + if ($this->_echoDebugLog) { + echo $cellReference, (count($cellReferencePath) > 0 ? ' => ' : ''), $message,PHP_EOL; + } + $this->_debugLog[] = $cellReference . (count($cellReferencePath) > 0 ? ' => ' : '') . $message; + } + } // function _writeDebug() + + + public function clearLog() { + $this->_debugLog = array(); + } // function flushLogger() + + public function getLog() { + return $this->_debugLog; + } // function flushLogger() + + +} // class PHPExcel_Calculation_Logger + diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index a1e51bc41..e109865c1 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -156,6 +156,15 @@ class PHPExcel_Calculation { '|' => TRUE, ':' => TRUE ); + /** + * The debug log generated by the calculation engine + * + * @access private + * @var PHPExcel_CalcEngine_Logger + * + */ + private $debugLog; + /** * Flag to determine how formula errors should be handled * If true, then a user error will be triggered @@ -176,30 +185,6 @@ class PHPExcel_Calculation { */ public $formulaError = NULL; - /** - * Flag to determine whether a debug log should be generated by the calculation engine - * If true, then a debug log will be generated - * If false, then a debug log will not be generated - * - * @access public - * @var boolean - * - */ - public $writeDebugLog = FALSE; - - /** - * Flag to determine whether a debug log should be echoed by the calculation engine - * If true, then a debug log will be echoed - * If false, then a debug log will not be echoed - * A debug log can only be echoed if it is generated - * - * @access public - * @var boolean - * - */ - public $echoDebugLog = FALSE; - - /** * An array of the nested cell references accessed by the calculation engine, used for the debug log * @@ -207,22 +192,14 @@ class PHPExcel_Calculation { * @var array of string * */ - private $debugLogStack = array(); + private $cyclicReferenceStack = array(); - /** - * The debug log generated by the calculation engine - * - * @access public - * @var array of string - * - */ - public $debugLog = array(); private $_cyclicFormulaCount = 0; private $_cyclicFormulaCell = ''; public $cyclicFormulaCount = 0; - private $_savedPrecision = 12; + private $_savedPrecision = 14; private static $_localeLanguage = 'en_us'; // US English (default locale) @@ -1688,7 +1665,7 @@ class PHPExcel_Calculation { private function __construct(PHPExcel $workbook = NULL) { - $setPrecision = (PHP_INT_SIZE == 4) ? 12 : 16; + $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; $this->_savedPrecision = ini_get('precision'); if ($this->_savedPrecision < $setPrecision) { ini_set('precision',$setPrecision); @@ -1699,6 +1676,7 @@ private function __construct(PHPExcel $workbook = NULL) { } $this->_workbook = $workbook; + $this->_debugLog = new PHPExcel_CalcEngine_Logger(); } // function __construct() @@ -1759,6 +1737,10 @@ public function flushInstance() { } // function flushInstance() + public function getDebugLog() { + return $this->_debugLog; + } + /** * __clone implementation. Cloning should not be allowed in a Singleton! * @@ -1871,7 +1853,7 @@ public function clearCalculationCacheForWorksheet($worksheetName) { if (isset($this->_calculationCache[$worksheetName])) { unset($this->_calculationCache[$worksheetName]); } - } // function clearCalculationCache() + } // function clearCalculationCacheForWorksheet() /** * Rename calculation cache for a specified worksheet @@ -1881,7 +1863,7 @@ public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksh $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName]; unset($this->_calculationCache[$fromWorksheetName]); } - } // function clearCalculationCache() + } // function renameCalculationCacheForWorksheet() /** @@ -2174,15 +2156,14 @@ public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE $returnArrayAsType = self::$returnArrayAsType; if ($resetLog) { // Initialise the logging settings if requested - $this->formulaError = NULL; - $this->debugLog = $this->debugLogStack = array(); + $this->formulaError = null; + $this->_debugLog->clearLog(); + $this->cyclicReferenceStack = array(); $this->_cyclicFormulaCount = 1; self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; } - if ($resetLog) { - } // Execute the calculation for the cell formula try { $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); @@ -2254,7 +2235,8 @@ public function parseFormula($formula) { public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) { // Initialise the logging settings $this->formulaError = null; - $this->debugLog = $this->debugLogStack = array(); + $this->_debugLog->clearLog(); + $this->cyclicReferenceStack = array(); // Disable calculation cacheing because it only applies to cell calculations, not straight formulae // But don't actually flush any cache @@ -2277,9 +2259,11 @@ public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = public function getValueFromCache($worksheetName, $cellID, &$cellValue) { // Is calculation cacheing enabled? // Is the value present in calculation cache? - $this->_writeDebug('Testing cache value for cell ', $worksheetName, '!', $cellID); +//echo 'Test cache for ',$worksheetName,'!',$cellID,PHP_EOL; + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Testing cache value for cell ', $worksheetName, '!', $cellID); if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$worksheetName][$cellID]))) { - $this->_writeDebug('Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache'); +//echo 'Retrieve from cache',PHP_EOL; + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache'); // Return the cached result $cellValue = $this->_calculationCache[$worksheetName][$cellID]; return TRUE; @@ -2312,14 +2296,14 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC $formula = ltrim(substr($formula,1)); if (!isset($formula{0})) return self::_wrapResult($formula); - $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL; + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; if (($cellID !== NULL) && ($this->getValueFromCache($wsTitle, $cellID, $cellValue))) { return $cellValue; } - if (($wsTitle{0} !== "\x00") && (in_array($wsTitle.'!'.$cellID,$this->debugLogStack))) { + if (($wsTitle{0} !== "\x00") && (in_array($wsTitle.'!'.$cellID,$this->cyclicReferenceStack))) { if ($this->cyclicFormulaCount <= 0) { return $this->_raiseFormulaError('Cyclic Reference in Formula'); } elseif (($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) && @@ -2337,10 +2321,10 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC } } } - $this->debugLogStack[] = $wsTitle.'!'.$cellID; + $this->cyclicReferenceStack[] = $wsTitle.'!'.$cellID; // Parse the formula onto the token stack and calculate the value $cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell); - array_pop($this->debugLogStack); + array_pop($this->cyclicReferenceStack); // Save to calculation cache if ($cellID !== NULL) { @@ -2505,7 +2489,7 @@ private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$ * @return mixed */ private function _showValue($value) { - if ($this->writeDebugLog) { + if ($this->_debugLog->getWriteDebugLog()) { $testArray = PHPExcel_Calculation_Functions::flattenArray($value); if (count($testArray) == 1) { $value = array_pop($testArray); @@ -2540,7 +2524,7 @@ private function _showValue($value) { * @return mixed */ private function _showTypeDetails($value) { - if ($this->writeDebugLog) { + if ($this->_debugLog->getWriteDebugLog()) { $testArray = PHPExcel_Calculation_Functions::flattenArray($value); if (count($testArray) == 1) { $value = array_pop($testArray); @@ -2665,7 +2649,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), // so we store the parent worksheet so that we can re-attach it when necessary - $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL; + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION. '|'.self::CALCULATION_REGEXP_NUMBER. @@ -3019,9 +3003,10 @@ private static function _dataTestReference(&$operandData) private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) { if ($tokens == FALSE) return FALSE; - // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), - // so we store the parent worksheet so that we can re-attach it when necessary - $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL; + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection), + // so we store the parent cell collection so that we can re-attach it when necessary + $pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null; $stack = new PHPExcel_Calculation_Token_Stack; // Loop through each token in turn @@ -3042,9 +3027,9 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // Log what we're doing if ($token == ':') { - $this->_writeDebug('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); } else { - $this->_writeDebug('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); } // Process the operation in the appropriate manner @@ -3064,7 +3049,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel if (strpos($operand1Data['reference'],'!') !== FALSE) { list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']); } else { - $sheet1 = ($pCellParent !== NULL) ? $pCellParent->getTitle() : ''; + $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : ''; } if (strpos($operand2Data['reference'],'!') !== FALSE) { list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']); @@ -3145,13 +3130,13 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $matrixResult = $matrix->concat($operand2); $result = $matrixResult->getArray(); } catch (PHPExcel_Exception $ex) { - $this->_writeDebug('JAMA Matrix Exception: ', $ex->getMessage()); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage()); $result = '#VALUE!'; } } else { $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"'; } - $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result)); $stack->push('Value',$result); break; case '|' : // Intersect @@ -3165,7 +3150,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } } $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); - $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); $stack->push('Value',$cellIntersect,$cellRef); break; } @@ -3177,11 +3162,11 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $arg = $arg['value']; if ($token === '~') { // echo 'Token is a negation operator
'; - $this->_writeDebug('Evaluating Negation of ', $this->_showValue($arg)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Negation of ', $this->_showValue($arg)); $multiplier = -1; } else { // echo 'Token is a percentile operator
'; - $this->_writeDebug('Evaluating Percentile of ', $this->_showValue($arg)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Percentile of ', $this->_showValue($arg)); $multiplier = 0.01; } if (is_array($arg)) { @@ -3191,10 +3176,10 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $matrixResult = $matrix1->arrayTimesEquals($multiplier); $result = $matrixResult->getArray(); } catch (PHPExcel_Exception $ex) { - $this->_writeDebug('JAMA Matrix Exception: ', $ex->getMessage()); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage()); $result = '#VALUE!'; } - $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result)); $stack->push('Value',$result); } else { $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack); @@ -3218,23 +3203,23 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } $matches[2] = trim($matches[2],"\"'"); // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
'; - $this->_writeDebug('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== NULL) { $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } - $this->_writeDebug('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); // $cellRef = $matches[2].'!'.$cellRef; } else { // echo '$cellRef='.$cellRef.' in current worksheet
'; - $this->_writeDebug('Evaluating Cell Range ', $cellRef, ' in current worksheet'); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell Range ', $cellRef, ' in current worksheet'); if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $pCellParent, FALSE); + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } - $this->_writeDebug('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); } } } else { @@ -3251,7 +3236,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel return $this->_raiseFormulaError('Unable to access External Workbook'); } // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
'; - $this->_writeDebug('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== NULL) { if ($this->_workbook->getSheetByName($matches[2])->cellExists($cellRef)) { $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); @@ -3262,18 +3247,18 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } - $this->_writeDebug('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); // $cellRef = $matches[2].'!'.$cellRef; } else { // echo '$cellRef='.$cellRef.' in current worksheet
'; - $this->_writeDebug('Evaluating Cell ', $cellRef, ' in current worksheet'); - if ($pCellParent->cellExists($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $pCellParent, FALSE); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell ', $cellRef, ' in current worksheet'); + if ($pCellParent->isDataSet($cellRef)) { + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); $pCell->attach($pCellParent); } else { $cellValue = NULL; } - $this->_writeDebug('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); } } } @@ -3286,7 +3271,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $argCount = $stack->pop(); $argCount = $argCount['value']; if ($functionName != 'MKMATRIX') { - $this->_writeDebug('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); } if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function if (isset(self::$_PHPExcelFunctions[$functionName])) { @@ -3329,30 +3314,30 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // print_r($args); // echo '
'; if ($functionName != 'MKMATRIX') { - if ($this->writeDebugLog) { + if ($this->_debugLog->getWriteDebugLog()) { krsort($argArrayVals); - $this->_writeDebug('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); } } // Process each argument in turn, building the return value as an array // if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) { // $operand1 = $args[1]; -// $this->_writeDebug('Argument is a matrix: ', $this->_showValue($operand1)); +// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Argument is a matrix: ', $this->_showValue($operand1)); // $result = array(); // $row = 0; // foreach($operand1 as $args) { // if (is_array($args)) { // foreach($args as $arg) { -// $this->_writeDebug('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); +// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); // $r = call_user_func_array($functionCall,$arg); -// $this->_writeDebug('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); // $result[$row][] = $r; // } // ++$row; // } else { -// $this->_writeDebug('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); +// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); // $r = call_user_func_array($functionCall,$args); -// $this->_writeDebug('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); // $result[] = $r; // } // } @@ -3372,7 +3357,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } // } if ($functionName != 'MKMATRIX') { - $this->_writeDebug('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); } $stack->push('Value',self::_wrapResult($result)); } @@ -3383,7 +3368,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $excelConstant = strtoupper($token); // echo 'Token is a PHPExcel constant: '.$excelConstant.'
'; $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]); - $this->_writeDebug('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { // echo 'Token is a number, boolean, string, null or an Excel error
'; $stack->push('Value',$token); @@ -3392,10 +3377,10 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // echo 'Token is a named range
'; $namedRange = $matches[6]; // echo 'Named Range is '.$namedRange.'
'; - $this->_writeDebug('Evaluating Named Range ', $namedRange); - $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellParent : NULL), FALSE); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Named Range ', $namedRange); + $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE); $pCell->attach($pCellParent); - $this->_writeDebug('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); $stack->push('Named Range',$cellValue,$namedRange); } else { return $this->_raiseFormulaError("undefined variable '$token'"); @@ -3425,12 +3410,12 @@ private function _validateBinaryOperand($cellID, &$operand, &$stack) { // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations if ($operand > '' && $operand{0} == '#') { $stack->push('Value', $operand); - $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($operand)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($operand)); return FALSE; } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations $stack->push('Value', '#VALUE!'); - $this->_writeDebug('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); return FALSE; } } @@ -3447,14 +3432,14 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 $result = array(); if ((is_array($operand1)) && (!is_array($operand2))) { foreach($operand1 as $x => $operandData) { - $this->_writeDebug('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack); $r = $stack->pop(); $result[$x] = $r['value']; } } elseif ((!is_array($operand1)) && (is_array($operand2))) { foreach($operand2 as $x => $operandData) { - $this->_writeDebug('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack); $r = $stack->pop(); $result[$x] = $r['value']; @@ -3462,14 +3447,14 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 } else { if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } foreach($operand1 as $x => $operandData) { - $this->_writeDebug('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); $r = $stack->pop(); $result[$x] = $r['value']; } } // Log the result details - $this->_writeDebug('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Comparison Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack $stack->push('Array',$result); return TRUE; @@ -3508,7 +3493,7 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 } // Log the result details - $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack $stack->push('Value',$result); return TRUE; @@ -3546,7 +3531,7 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope $matrixResult = $matrix->$matrixFunction($operand2); $result = $matrixResult->getArray(); } catch (PHPExcel_Exception $ex) { - $this->_writeDebug('JAMA Matrix Exception: ', $ex->getMessage()); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage()); $result = '#VALUE!'; } } else { @@ -3573,7 +3558,7 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope if ($operand2 == 0) { // Trap for Divide by Zero error $stack->push('Value','#DIV/0!'); - $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); return FALSE; } else { $result = $operand1/$operand2; @@ -3588,29 +3573,17 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope } // Log the result details - $this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack $stack->push('Value',$result); return TRUE; } // function _executeNumericBinaryOperation() - private function _writeDebug() { - // Only write the debug log if logging is enabled - if ($this->writeDebugLog) { - $message = implode('',func_get_args()); - if ($this->echoDebugLog) { - echo implode(' -> ',$this->debugLogStack).' -> '.$message,'
'; - } - $this->debugLog[] = implode(' -> ',$this->debugLogStack).' -> '.$message; - } - } // function _writeDebug() - - // trigger an error, but nicely, if need be protected function _raiseFormulaError($errorMessage) { $this->formulaError = $errorMessage; - $this->debugLogStack = array(); + $this->cyclicReferenceStack = array(); if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); trigger_error($errorMessage, E_USER_ERROR); } // function _raiseFormulaError() @@ -3628,25 +3601,26 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = N // Return value $returnValue = array (); -// echo 'extractCellRange('.$pRange.')
'; +// echo 'extractCellRange('.$pRange.')',PHP_EOL; if ($pSheet !== NULL) { -// echo 'Passed sheet name is '.$pSheet->getTitle().'
'; -// echo 'Range reference is '.$pRange.'
'; - if (strpos ($pRange, '!') !== FALSE) { -// echo '$pRange reference includes sheet reference
'; - $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, TRUE); - $pSheet = $this->_workbook->getSheetByName($worksheetReference[0]); -// echo 'New sheet name is '.$pSheet->getTitle().'
'; - $pRange = $worksheetReference[1]; -// echo 'Adjusted Range reference is '.$pRange.'
'; + $pSheetName = $pSheet->getTitle(); +// echo 'Passed sheet name is '.$pSheetName.PHP_EOL; +// echo 'Range reference is '.$pRange.PHP_EOL; + if (strpos ($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference',PHP_EOL; + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName,PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + $pSheet = $this->_workbook->getSheetByName($pSheetName); } // Extract range $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); - $pRange = $pSheet->getTitle().'!'.$pRange; + $pRange = $pSheetName.'!'.$pRange; if (!isset($aReferences[1])) { // Single cell in range list($currentCol,$currentRow) = sscanf($aReferences[0],'%[A-Z]%d'); + $cellValue = NULL; if ($pSheet->cellExists($aReferences[0])) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); } else { @@ -3657,7 +3631,7 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = N foreach ($aReferences as $reference) { // Extract range list($currentCol,$currentRow) = sscanf($reference,'%[A-Z]%d'); - + $cellValue = NULL; if ($pSheet->cellExists($reference)) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); } else { @@ -3686,15 +3660,15 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = // echo 'extractNamedRange('.$pRange.')
'; if ($pSheet !== NULL) { -// echo 'Current sheet name is '.$pSheet->getTitle().'
'; + $pSheetName = $pSheet->getTitle(); +// echo 'Current sheet name is '.$pSheetName.'
'; // echo 'Range reference is '.$pRange.'
'; - if (strpos ($pRange, '!') !== FALSE) { -// echo '$pRange reference includes sheet reference
'; - $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, TRUE); - $pSheet = $this->_workbook->getSheetByName($worksheetReference[0]); -// echo 'New sheet name is '.$pSheet->getTitle().'
'; - $pRange = $worksheetReference[1]; -// echo 'Adjusted Range reference is '.$pRange.'
'; + if (strpos ($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference',PHP_EOL; + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName,PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + $pSheet = $this->_workbook->getSheetByName($pSheetName); } // Named range? @@ -3729,6 +3703,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = if (!isset($aReferences[1])) { // Single cell (or single column or row) in range list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); + $cellValue = NULL; if ($pSheet->cellExists($aReferences[0])) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); } else { @@ -3740,6 +3715,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = // Extract range list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference); // echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'
'; + $cellValue = NULL; if ($pSheet->cellExists($reference)) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); } else { diff --git a/Classes/PHPExcel/Calculation/Token/Stack.php b/Classes/PHPExcel/Calculation/Token/Stack.php index 081a38dca..bdf9d555e 100644 --- a/Classes/PHPExcel/Calculation/Token/Stack.php +++ b/Classes/PHPExcel/Calculation/Token/Stack.php @@ -67,7 +67,9 @@ public function last($n=1) { } // function last() - function __construct() { + function clear() { + $this->_stack = array(); + $this->_count = 0; } } // class PHPExcel_Calculation_Token_Stack diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index ab8b472cb..e21674aae 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -50,13 +50,6 @@ class PHPExcel_Cell */ private static $_valueBinder = NULL; - /** - * Cell Address (e.g. A1) - * - * @var string - */ - private $_coordinate; - /** * Value of the cell * @@ -86,7 +79,7 @@ class PHPExcel_Cell /** * Parent worksheet * - * @var PHPExcel_Worksheet + * @var PHPExcel_CachedObjectStorage_CacheBase */ private $_parent; @@ -110,7 +103,7 @@ class PHPExcel_Cell * @return void **/ public function notifyCacheController() { - $this->_parent->getCellCacheController()->updateCacheData($this); + $this->_parent->updateCacheData($this); return $this; } @@ -118,7 +111,9 @@ public function detach() { $this->_parent = NULL; } - public function attach($parent) { + public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) { + + $this->_parent = $parent; } @@ -126,23 +121,18 @@ public function attach($parent) { /** * Create a new Cell * - * @param string $pColumn - * @param int $pRow * @param mixed $pValue * @param string $pDataType * @param PHPExcel_Worksheet $pSheet * @throws PHPExcel_Exception */ - public function __construct($pCoordinate = 'A1', $pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL) + public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL) { - // Initialise cell coordinate - $this->_coordinate = strtoupper($pCoordinate); - // Initialise cell value $this->_value = $pValue; - // Set worksheet - $this->_parent = $pSheet; + // Set worksheet cache + $this->_parent = $pSheet->getCellCacheController(); // Set datatype? if ($pDataType !== NULL) { @@ -166,8 +156,7 @@ public function __construct($pCoordinate = 'A1', $pValue = NULL, $pDataType = NU */ public function getColumn() { - list($column) = sscanf($this->_coordinate, '%[A-Z]%d'); - return $column; + return $this->_parent->getCurrentColumn(); } /** @@ -177,8 +166,7 @@ public function getColumn() */ public function getRow() { - list(,$row) = sscanf($this->_coordinate, '%[A-Z]%d'); - return $row; + return $this->_parent->getCurrentRow(); } /** @@ -188,7 +176,7 @@ public function getRow() */ public function getCoordinate() { - return $this->_coordinate; + return $this->_parent->getCurrentAddress(); } /** @@ -210,7 +198,7 @@ public function getFormattedValue() { return (string) PHPExcel_Style_NumberFormat::toFormattedString( $this->getCalculatedValue(), - $this->_parent->getParent()->getCellXfByIndex($this->getXfIndex()) + $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex()) ->getNumberFormat()->getFormatCode() ); } @@ -289,7 +277,7 @@ public function getCalculatedValue($resetLog = TRUE) try { // echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value
'; $result = PHPExcel_Calculation::getInstance( - $this->getParent()->getParent() + $this->getWorksheet()->getParent() )->calculateCellValue($this,$resetLog); // $result = $this->getParent()->getParent()->getCalculationEngine()->calculateCellValue($this,$resetLog); // echo $this->getCoordinate().' calculation result is '.$result.'
'; @@ -302,7 +290,7 @@ public function getCalculatedValue($resetLog = TRUE) $result = '#N/A'; throw( new PHPExcel_Calculation_Exception( - $this->getParent()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage() + $this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage() ) ); } @@ -391,7 +379,7 @@ public function hasDataValidation() throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet'); } - return $this->_parent->dataValidationExists($this->getCoordinate()); + return $this->getWorksheet()->dataValidationExists($this->getCoordinate()); } /** @@ -406,7 +394,7 @@ public function getDataValidation() throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet'); } - return $this->_parent->getDataValidation($this->getCoordinate()); + return $this->getWorksheet()->getDataValidation($this->getCoordinate()); } /** @@ -422,7 +410,7 @@ public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet'); } - $this->_parent->setDataValidation($this->getCoordinate(), $pDataValidation); + $this->getWorksheet()->setDataValidation($this->getCoordinate(), $pDataValidation); return $this->notifyCacheController(); } @@ -439,7 +427,7 @@ public function hasHyperlink() throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); } - return $this->_parent->hyperlinkExists($this->getCoordinate()); + return $this->getWorksheet()->hyperlinkExists($this->getCoordinate()); } /** @@ -454,7 +442,7 @@ public function getHyperlink() throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); } - return $this->_parent->getHyperlink($this->getCoordinate()); + return $this->getWorksheet()->getHyperlink($this->getCoordinate()); } /** @@ -470,7 +458,7 @@ public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL) throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); } - $this->_parent->setHyperlink($this->getCoordinate(), $pHyperlink); + $this->getWorksheet()->setHyperlink($this->getCoordinate(), $pHyperlink); return $this->notifyCacheController(); } @@ -484,6 +472,15 @@ public function getParent() { return $this->_parent; } + /** + * Get parent worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() { + return $this->_parent->getParent(); + } + /** * Re-bind parent * @@ -491,7 +488,7 @@ public function getParent() { * @return PHPExcel_Cell */ public function rebindParent(PHPExcel_Worksheet $parent) { - $this->_parent = $parent; + $this->_parent = $parent->getCellCacheController(); return $this->notifyCacheController(); } diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 64ad11182..fad7c50c6 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -19,10 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category PHPExcel - * @package PHPExcel_Worksheet + * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ @@ -30,2785 +30,2780 @@ * PHPExcel_Worksheet * * @category PHPExcel - * @package PHPExcel_Worksheet + * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet implements PHPExcel_IComparable { - /* Break types */ - const BREAK_NONE = 0; - const BREAK_ROW = 1; - const BREAK_COLUMN = 2; - - /* Sheet state */ - const SHEETSTATE_VISIBLE = 'visible'; - const SHEETSTATE_HIDDEN = 'hidden'; - const SHEETSTATE_VERYHIDDEN = 'veryHidden'; - - /** - * Invalid characters in sheet title - * - * @var array - */ - private static $_invalidCharacters = array('*', ':', '/', '\\', '?', '[', ']'); - - /** - * Parent spreadsheet - * - * @var PHPExcel - */ - private $_parent; - - /** - * Cacheable collection of cells - * - * @var PHPExcel_CachedObjectStorage_xxx - */ - private $_cellCollection = null; - - /** - * Collection of row dimensions - * - * @var PHPExcel_Worksheet_RowDimension[] - */ - private $_rowDimensions = array(); - - /** - * Default row dimension - * - * @var PHPExcel_Worksheet_RowDimension - */ - private $_defaultRowDimension = null; - - /** - * Collection of column dimensions - * - * @var PHPExcel_Worksheet_ColumnDimension[] - */ - private $_columnDimensions = array(); - - /** - * Default column dimension - * - * @var PHPExcel_Worksheet_ColumnDimension - */ - private $_defaultColumnDimension = null; - - /** - * Collection of drawings - * - * @var PHPExcel_Worksheet_BaseDrawing[] - */ - private $_drawingCollection = null; - - /** - * Collection of Chart objects - * - * @var PHPExcel_Chart[] - */ - private $_chartCollection = array(); - - /** - * Worksheet title - * - * @var string - */ - private $_title; - - /** - * Sheet state - * - * @var string - */ - private $_sheetState; - - /** - * Page setup - * - * @var PHPExcel_Worksheet_PageSetup - */ - private $_pageSetup; - - /** - * Page margins - * - * @var PHPExcel_Worksheet_PageMargins - */ - private $_pageMargins; - - /** - * Page header/footer - * - * @var PHPExcel_Worksheet_HeaderFooter - */ - private $_headerFooter; - - /** - * Sheet view - * - * @var PHPExcel_Worksheet_SheetView - */ - private $_sheetView; - - /** - * Protection - * - * @var PHPExcel_Worksheet_Protection - */ - private $_protection; - - /** - * Collection of styles - * - * @var PHPExcel_Style[] - */ - private $_styles = array(); - - /** - * Conditional styles. Indexed by cell coordinate, e.g. 'A1' - * - * @var array - */ - private $_conditionalStylesCollection = array(); - - /** - * Is the current cell collection sorted already? - * - * @var boolean - */ - private $_cellCollectionIsSorted = false; - - /** - * Collection of breaks - * - * @var array - */ - private $_breaks = array(); - - /** - * Collection of merged cell ranges - * - * @var array - */ - private $_mergeCells = array(); - - /** - * Collection of protected cell ranges - * - * @var array - */ - private $_protectedCells = array(); - - /** - * Autofilter Range and selection - * - * @var PHPExcel_Worksheet_AutoFilter - */ - private $_autoFilter = NULL; - - /** - * Freeze pane - * - * @var string - */ - private $_freezePane = ''; - - /** - * Show gridlines? - * - * @var boolean - */ - private $_showGridlines = true; - - /** - * Print gridlines? - * - * @var boolean - */ - private $_printGridlines = false; - - /** - * Show row and column headers? - * - * @var boolean - */ - private $_showRowColHeaders = true; - - /** - * Show summary below? (Row/Column outline) - * - * @var boolean - */ - private $_showSummaryBelow = true; - - /** - * Show summary right? (Row/Column outline) - * - * @var boolean - */ - private $_showSummaryRight = true; - - /** - * Collection of comments - * - * @var PHPExcel_Comment[] - */ - private $_comments = array(); - - /** - * Active cell. (Only one!) - * - * @var string - */ - private $_activeCell = 'A1'; - - /** - * Selected cells - * - * @var string - */ - private $_selectedCells = 'A1'; - - /** - * Cached highest column - * - * @var string - */ - private $_cachedHighestColumn = 'A'; - - /** - * Cached highest row - * - * @var int - */ - private $_cachedHighestRow = 1; - - /** - * Right-to-left? - * - * @var boolean - */ - private $_rightToLeft = false; - - /** - * Hyperlinks. Indexed by cell coordinate, e.g. 'A1' - * - * @var array - */ - private $_hyperlinkCollection = array(); - - /** - * Data validation objects. Indexed by cell coordinate, e.g. 'A1' - * - * @var array - */ - private $_dataValidationCollection = array(); - - /** - * Tab color - * - * @var PHPExcel_Style_Color - */ - private $_tabColor; - - /** - * Dirty flag - * - * @var boolean - */ - private $_dirty = true; - - /** - * Hash - * - * @var string - */ - private $_hash = null; - - /** - * Create a new worksheet - * - * @param PHPExcel $pParent - * @param string $pTitle - */ - public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') - { - // Set parent and title - $this->_parent = $pParent; - $this->setTitle($pTitle, FALSE); - $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE); - - $this->_cellCollection = PHPExcel_CachedObjectStorageFactory::getInstance($this); - - // Set page setup - $this->_pageSetup = new PHPExcel_Worksheet_PageSetup(); - - // Set page margins - $this->_pageMargins = new PHPExcel_Worksheet_PageMargins(); - - // Set page header/footer - $this->_headerFooter = new PHPExcel_Worksheet_HeaderFooter(); - - // Set sheet view - $this->_sheetView = new PHPExcel_Worksheet_SheetView(); - - // Drawing collection - $this->_drawingCollection = new ArrayObject(); - - // Chart collection - $this->_chartCollection = new ArrayObject(); - - // Protection - $this->_protection = new PHPExcel_Worksheet_Protection(); - - // Default row dimension - $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(NULL); - - // Default column dimension - $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(NULL); - - $this->_autoFilter = new PHPExcel_Worksheet_AutoFilter(NULL, $this); - } + /* Break types */ + const BREAK_NONE = 0; + const BREAK_ROW = 1; + const BREAK_COLUMN = 2; + /* Sheet state */ + const SHEETSTATE_VISIBLE = 'visible'; + const SHEETSTATE_HIDDEN = 'hidden'; + const SHEETSTATE_VERYHIDDEN = 'veryHidden'; - /** - * Disconnect all cells from this PHPExcel_Worksheet object, - * typically so that the worksheet object can be unset - * - */ - public function disconnectCells() { - $this->_cellCollection->unsetWorksheetCells(); - $this->_cellCollection = NULL; + /** + * Invalid characters in sheet title + * + * @var array + */ + private static $_invalidCharacters = array('*', ':', '/', '\\', '?', '[', ']'); - // detach ourself from the workbook, so that it can then delete this worksheet successfully - $this->_parent = null; - } + /** + * Parent spreadsheet + * + * @var PHPExcel + */ + private $_parent; - /** - * Code to execute when this worksheet is unset() + /** + * Cacheable collection of cells * + * @var PHPExcel_CachedObjectStorage_xxx */ - function __destruct() { - if ($this->_cellCollection !== NULL) { - $this->disconnectCells(); - } - PHPExcel_Calculation::getInstance($this->_parent) - ->clearCalculationCacheForWorksheet($this->_title); - } + private $_cellCollection = null; - /** - * Return the cache controller for the cell collection - * - * @return PHPExcel_CachedObjectStorage_xxx - */ - public function getCellCacheController() { - return $this->_cellCollection; - } // function getCellCacheController() - - - /** - * Get array of invalid characters for sheet title - * - * @return array - */ - public static function getInvalidCharacters() - { - return self::$_invalidCharacters; - } + /** + * Collection of row dimensions + * + * @var PHPExcel_Worksheet_RowDimension[] + */ + private $_rowDimensions = array(); - /** - * Check sheet title for valid Excel syntax - * - * @param string $pValue The string to check - * @return string The valid string - * @throws PHPExcel_Exception - */ - private static function _checkSheetTitle($pValue) - { - // Some of the printable ASCII characters are invalid: * : / \ ? [ ] - if (str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) { - throw new PHPExcel_Exception('Invalid character found in sheet title'); - } + /** + * Default row dimension + * + * @var PHPExcel_Worksheet_RowDimension + */ + private $_defaultRowDimension = null; - // Maximum 31 characters allowed for sheet title - if (PHPExcel_Shared_String::CountCharacters($pValue) > 31) { - throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet title.'); - } + /** + * Collection of column dimensions + * + * @var PHPExcel_Worksheet_ColumnDimension[] + */ + private $_columnDimensions = array(); - return $pValue; - } + /** + * Default column dimension + * + * @var PHPExcel_Worksheet_ColumnDimension + */ + private $_defaultColumnDimension = null; - /** - * Get collection of cells - * - * @param boolean $pSorted Also sort the cell collection? - * @return PHPExcel_Cell[] - */ - public function getCellCollection($pSorted = true) - { - if ($pSorted) { - // Re-order cell collection - return $this->sortCellCollection(); - } - if ($this->_cellCollection !== NULL) { - return $this->_cellCollection->getCellList(); - } - return array(); - } + /** + * Collection of drawings + * + * @var PHPExcel_Worksheet_BaseDrawing[] + */ + private $_drawingCollection = null; - /** - * Sort collection of cells - * - * @return PHPExcel_Worksheet - */ - public function sortCellCollection() - { - if ($this->_cellCollection !== NULL) { - return $this->_cellCollection->getSortedCellList(); - } - return array(); - } + /** + * Collection of Chart objects + * + * @var PHPExcel_Chart[] + */ + private $_chartCollection = array(); - /** - * Get collection of row dimensions - * - * @return PHPExcel_Worksheet_RowDimension[] - */ - public function getRowDimensions() - { - return $this->_rowDimensions; - } + /** + * Worksheet title + * + * @var string + */ + private $_title; - /** - * Get default row dimension - * - * @return PHPExcel_Worksheet_RowDimension - */ - public function getDefaultRowDimension() - { - return $this->_defaultRowDimension; - } + /** + * Sheet state + * + * @var string + */ + private $_sheetState; - /** - * Get collection of column dimensions - * - * @return PHPExcel_Worksheet_ColumnDimension[] - */ - public function getColumnDimensions() - { - return $this->_columnDimensions; - } + /** + * Page setup + * + * @var PHPExcel_Worksheet_PageSetup + */ + private $_pageSetup; - /** - * Get default column dimension - * - * @return PHPExcel_Worksheet_ColumnDimension - */ - public function getDefaultColumnDimension() - { - return $this->_defaultColumnDimension; - } + /** + * Page margins + * + * @var PHPExcel_Worksheet_PageMargins + */ + private $_pageMargins; - /** - * Get collection of drawings - * - * @return PHPExcel_Worksheet_BaseDrawing[] - */ - public function getDrawingCollection() - { - return $this->_drawingCollection; - } + /** + * Page header/footer + * + * @var PHPExcel_Worksheet_HeaderFooter + */ + private $_headerFooter; - /** - * Get collection of charts - * - * @return PHPExcel_Chart[] - */ - public function getChartCollection() - { - return $this->_chartCollection; - } + /** + * Sheet view + * + * @var PHPExcel_Worksheet_SheetView + */ + private $_sheetView; - /** - * Add chart - * - * @param PHPExcel_Chart $pChart - * @param int|null $iChartIndex Index where chart should go (0,1,..., or null for last) - * @return PHPExcel_Chart - */ - public function addChart(PHPExcel_Chart $pChart = null, $iChartIndex = null) - { - $pChart->setWorksheet($this); - if (is_null($iChartIndex)) { - $this->_chartCollection[] = $pChart; - } else { - // Insert the chart at the requested index - array_splice($this->_chartCollection, $iChartIndex, 0, array($pChart)); - } + /** + * Protection + * + * @var PHPExcel_Worksheet_Protection + */ + private $_protection; - return $pChart; - } + /** + * Collection of styles + * + * @var PHPExcel_Style[] + */ + private $_styles = array(); - /** - * Return the count of charts on this worksheet - * - * @return int The number of charts - */ - public function getChartCount() - { - return count($this->_chartCollection); - } + /** + * Conditional styles. Indexed by cell coordinate, e.g. 'A1' + * + * @var array + */ + private $_conditionalStylesCollection = array(); - /** - * Get a chart by its index position - * - * @param string $index Chart index position - * @return false|PHPExcel_Chart - * @throws PHPExcel_Exception - */ - public function getChartByIndex($index = null) - { - $chartCount = count($this->_chartCollection); - if ($chartCount == 0) { - return false; - } - if (is_null($index)) { - $index = --$chartCount; - } - if (!isset($this->_chartCollection[$index])) { - return false; - } + /** + * Is the current cell collection sorted already? + * + * @var boolean + */ + private $_cellCollectionIsSorted = false; - return $this->_chartCollection[$index]; - } + /** + * Collection of breaks + * + * @var array + */ + private $_breaks = array(); - /** - * Return an array of the names of charts on this worksheet - * - * @return string[] The names of charts - * @throws PHPExcel_Exception - */ - public function getChartNames() - { - $chartNames = array(); - foreach($this->_chartCollection as $chart) { - $chartNames[] = $chart->getName(); - } - return $chartNames; - } + /** + * Collection of merged cell ranges + * + * @var array + */ + private $_mergeCells = array(); - /** - * Get a chart by name - * - * @param string $chartName Chart name - * @return false|PHPExcel_Chart - * @throws PHPExcel_Exception - */ - public function getChartByName($chartName = '') - { - $chartCount = count($this->_chartCollection); - if ($chartCount == 0) { - return false; - } - foreach($this->_chartCollection as $index => $chart) { - if ($chart->getName() == $chartName) { - return $this->_chartCollection[$index]; - } - } - return false; - } + /** + * Collection of protected cell ranges + * + * @var array + */ + private $_protectedCells = array(); - /** - * Refresh column dimensions - * - * @return PHPExcel_Worksheet - */ - public function refreshColumnDimensions() - { - $currentColumnDimensions = $this->getColumnDimensions(); - $newColumnDimensions = array(); - - foreach ($currentColumnDimensions as $objColumnDimension) { - $newColumnDimensions[$objColumnDimension->getColumnIndex()] = $objColumnDimension; - } + /** + * Autofilter Range and selection + * + * @var PHPExcel_Worksheet_AutoFilter + */ + private $_autoFilter = NULL; - $this->_columnDimensions = $newColumnDimensions; + /** + * Freeze pane + * + * @var string + */ + private $_freezePane = ''; - return $this; - } + /** + * Show gridlines? + * + * @var boolean + */ + private $_showGridlines = true; - /** - * Refresh row dimensions - * - * @return PHPExcel_Worksheet - */ - public function refreshRowDimensions() - { - $currentRowDimensions = $this->getRowDimensions(); - $newRowDimensions = array(); - - foreach ($currentRowDimensions as $objRowDimension) { - $newRowDimensions[$objRowDimension->getRowIndex()] = $objRowDimension; - } + /** + * Print gridlines? + * + * @var boolean + */ + private $_printGridlines = false; - $this->_rowDimensions = $newRowDimensions; + /** + * Show row and column headers? + * + * @var boolean + */ + private $_showRowColHeaders = true; - return $this; - } + /** + * Show summary below? (Row/Column outline) + * + * @var boolean + */ + private $_showSummaryBelow = true; - /** - * Calculate worksheet dimension - * - * @return string String containing the dimension of this worksheet - */ - public function calculateWorksheetDimension() - { - // Return - return 'A1' . ':' . $this->getHighestColumn() . $this->getHighestRow(); - } + /** + * Show summary right? (Row/Column outline) + * + * @var boolean + */ + private $_showSummaryRight = true; - /** - * Calculate worksheet data dimension - * - * @return string String containing the dimension of this worksheet that actually contain data - */ - public function calculateWorksheetDataDimension() - { - // Return - return 'A1' . ':' . $this->getHighestDataColumn() . $this->getHighestDataRow(); - } + /** + * Collection of comments + * + * @var PHPExcel_Comment[] + */ + private $_comments = array(); - /** - * Calculate widths for auto-size columns - * - * @param boolean $calculateMergeCells Calculate merge cell width - * @return PHPExcel_Worksheet; - */ - public function calculateColumnWidths($calculateMergeCells = false) - { - // initialize $autoSizes array - $autoSizes = array(); - foreach ($this->getColumnDimensions() as $colDimension) { - if ($colDimension->getAutoSize()) { - $autoSizes[$colDimension->getColumnIndex()] = -1; - } - } + /** + * Active cell. (Only one!) + * + * @var string + */ + private $_activeCell = 'A1'; - // There is only something to do if there are some auto-size columns - if (!empty($autoSizes)) { - - // build list of cells references that participate in a merge - $isMergeCell = array(); - foreach ($this->getMergeCells() as $cells) { - foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cells) as $cellReference) { - $isMergeCell[$cellReference] = true; - } - } - - // loop through all cells in the worksheet - foreach ($this->getCellCollection(false) as $cellID) { - $cell = $this->getCell($cellID); - if (isset($autoSizes[$cell->getColumn()])) { - // Determine width if cell does not participate in a merge - if (!isset($isMergeCell[$cell->getCoordinate()])) { - // Calculated value - $cellValue = $cell->getCalculatedValue(); - - // To formatted string - $cellValue = PHPExcel_Style_NumberFormat::toFormattedString( - $cellValue, - $this->_parent->getCellXfByIndex($cell->getXfIndex()) - ->getNumberFormat()->getFormatCode() - ); + /** + * Selected cells + * + * @var string + */ + private $_selectedCells = 'A1'; - $autoSizes[$cell->getColumn()] = max( - (float)$autoSizes[$cell->getColumn()], - (float)PHPExcel_Shared_Font::calculateColumnWidth( - $this->_parent->getCellXfByIndex($cell->getXfIndex()) - ->getFont(), - $cellValue, - $this->_parent->getCellXfByIndex($cell->getXfIndex()) - ->getAlignment()->getTextRotation(), - $this->getDefaultStyle()->getFont() - ) - ); - } - } - } - - // adjust column widths - foreach ($autoSizes as $columnIndex => $width) { - if ($width == -1) $width = $this->getDefaultColumnDimension()->getWidth(); - $this->getColumnDimension($columnIndex)->setWidth($width); - } - } + /** + * Cached highest column + * + * @var string + */ + private $_cachedHighestColumn = 'A'; - return $this; - } + /** + * Cached highest row + * + * @var int + */ + private $_cachedHighestRow = 1; - /** - * Get parent - * - * @return PHPExcel - */ - public function getParent() { - return $this->_parent; - } + /** + * Right-to-left? + * + * @var boolean + */ + private $_rightToLeft = false; - /** - * Re-bind parent - * - * @param PHPExcel $parent - * @return PHPExcel_Worksheet - */ - public function rebindParent(PHPExcel $parent) { - $namedRanges = $this->_parent->getNamedRanges(); - foreach ($namedRanges as $namedRange) { - $parent->addNamedRange($namedRange); - } + /** + * Hyperlinks. Indexed by cell coordinate, e.g. 'A1' + * + * @var array + */ + private $_hyperlinkCollection = array(); - $this->_parent->removeSheetByIndex( - $this->_parent->getIndex($this) - ); - $this->_parent = $parent; + /** + * Data validation objects. Indexed by cell coordinate, e.g. 'A1' + * + * @var array + */ + private $_dataValidationCollection = array(); - return $this; - } + /** + * Tab color + * + * @var PHPExcel_Style_Color + */ + private $_tabColor; - /** - * Get title - * - * @return string - */ - public function getTitle() - { - return $this->_title; - } + /** + * Dirty flag + * + * @var boolean + */ + private $_dirty = true; - /** - * Set title - * - * @param string $pValue String containing the dimension of this worksheet - * @param string $updateFormulaCellReferences boolean Flag indicating whether cell references in formulae should - * be updated to reflect the new sheet name. - * This should be left as the default true, unless you are - * certain that no formula cells on any worksheet contain - * references to this worksheet - * @return PHPExcel_Worksheet - */ - public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = true) - { - // Is this a 'rename' or not? - if ($this->getTitle() == $pValue) { - return $this; - } + /** + * Hash + * + * @var string + */ + private $_hash = null; - // Syntax check - self::_checkSheetTitle($pValue); + /** + * Create a new worksheet + * + * @param PHPExcel $pParent + * @param string $pTitle + */ + public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') + { + // Set parent and title + $this->_parent = $pParent; + $this->setTitle($pTitle, FALSE); + $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE); - // Old title - $oldTitle = $this->getTitle(); + $this->_cellCollection = PHPExcel_CachedObjectStorageFactory::getInstance($this); - if ($this->_parent) { - // Is there already such sheet name? - if ($this->_parent->sheetNameExists($pValue)) { - // Use name, but append with lowest possible integer + // Set page setup + $this->_pageSetup = new PHPExcel_Worksheet_PageSetup(); - if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); - } - $i = 1; - while ($this->_parent->sheetNameExists($pValue . ' ' . $i)) { - ++$i; - if ($i == 10) { - if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); - } - } elseif ($i == 100) { - if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); - } - } - } - - $altTitle = $pValue . ' ' . $i; - return $this->setTitle($altTitle,$updateFormulaCellReferences); - } - } + // Set page margins + $this->_pageMargins = new PHPExcel_Worksheet_PageMargins(); - // Set title - $this->_title = $pValue; - $this->_dirty = true; + // Set page header/footer + $this->_headerFooter = new PHPExcel_Worksheet_HeaderFooter(); - if ($this->_parent) { - // New title - $newTitle = $this->getTitle(); - PHPExcel_Calculation::getInstance($this->_parent) - ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); - if ($updateFormulaCellReferences) - PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_parent, $oldTitle, $newTitle); - } + // Set sheet view + $this->_sheetView = new PHPExcel_Worksheet_SheetView(); - return $this; - } + // Drawing collection + $this->_drawingCollection = new ArrayObject(); - /** - * Get sheet state - * - * @return string Sheet state (visible, hidden, veryHidden) - */ - public function getSheetState() { - return $this->_sheetState; - } + // Chart collection + $this->_chartCollection = new ArrayObject(); - /** - * Set sheet state - * - * @param string $value Sheet state (visible, hidden, veryHidden) - * @return PHPExcel_Worksheet - */ - public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) { - $this->_sheetState = $value; - return $this; - } + // Protection + $this->_protection = new PHPExcel_Worksheet_Protection(); - /** - * Get page setup - * - * @return PHPExcel_Worksheet_PageSetup - */ - public function getPageSetup() - { - return $this->_pageSetup; - } + // Default row dimension + $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(NULL); - /** - * Set page setup - * - * @param PHPExcel_Worksheet_PageSetup $pValue - * @return PHPExcel_Worksheet - */ - public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue) - { - $this->_pageSetup = $pValue; - return $this; - } + // Default column dimension + $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(NULL); - /** - * Get page margins - * - * @return PHPExcel_Worksheet_PageMargins - */ - public function getPageMargins() - { - return $this->_pageMargins; - } + $this->_autoFilter = new PHPExcel_Worksheet_AutoFilter(NULL, $this); + } - /** - * Set page margins - * - * @param PHPExcel_Worksheet_PageMargins $pValue - * @return PHPExcel_Worksheet - */ - public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue) - { - $this->_pageMargins = $pValue; - return $this; - } - /** - * Get page header/footer - * - * @return PHPExcel_Worksheet_HeaderFooter - */ - public function getHeaderFooter() - { - return $this->_headerFooter; - } + /** + * Disconnect all cells from this PHPExcel_Worksheet object, + * typically so that the worksheet object can be unset + * + */ + public function disconnectCells() { + $this->_cellCollection->unsetWorksheetCells(); + $this->_cellCollection = NULL; - /** - * Set page header/footer - * - * @param PHPExcel_Worksheet_HeaderFooter $pValue - * @return PHPExcel_Worksheet - */ - public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue) - { - $this->_headerFooter = $pValue; - return $this; - } + // detach ourself from the workbook, so that it can then delete this worksheet successfully + $this->_parent = null; + } - /** - * Get sheet view - * - * @return PHPExcel_Worksheet_SheetView - */ - public function getSheetView() - { - return $this->_sheetView; + /** + * Code to execute when this worksheet is unset() + * + */ + function __destruct() { + if ($this->_cellCollection !== NULL) { + $this->disconnectCells(); + } + PHPExcel_Calculation::getInstance($this->_parent) + ->clearCalculationCacheForWorksheet($this->_title); } - /** - * Set sheet view - * - * @param PHPExcel_Worksheet_SheetView $pValue - * @return PHPExcel_Worksheet - */ - public function setSheetView(PHPExcel_Worksheet_SheetView $pValue) - { - $this->_sheetView = $pValue; - return $this; - } + /** + * Return the cache controller for the cell collection + * + * @return PHPExcel_CachedObjectStorage_xxx + */ + public function getCellCacheController() { + return $this->_cellCollection; + } // function getCellCacheController() - /** - * Get Protection - * - * @return PHPExcel_Worksheet_Protection - */ - public function getProtection() - { - return $this->_protection; - } - /** - * Set Protection - * - * @param PHPExcel_Worksheet_Protection $pValue - * @return PHPExcel_Worksheet - */ - public function setProtection(PHPExcel_Worksheet_Protection $pValue) - { - $this->_protection = $pValue; - $this->_dirty = true; - - return $this; - } + /** + * Get array of invalid characters for sheet title + * + * @return array + */ + public static function getInvalidCharacters() + { + return self::$_invalidCharacters; + } - /** - * Get highest worksheet column - * - * @return string Highest column name - */ - public function getHighestColumn() - { - return $this->_cachedHighestColumn; - } + /** + * Check sheet title for valid Excel syntax + * + * @param string $pValue The string to check + * @return string The valid string + * @throws PHPExcel_Exception + */ + private static function _checkSheetTitle($pValue) + { + // Some of the printable ASCII characters are invalid: * : / \ ? [ ] + if (str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) { + throw new PHPExcel_Exception('Invalid character found in sheet title'); + } - /** - * Get highest worksheet column that contains data - * - * @return string Highest column name that contains data - */ - public function getHighestDataColumn() - { - return $this->_cellCollection->getHighestColumn(); - } + // Maximum 31 characters allowed for sheet title + if (PHPExcel_Shared_String::CountCharacters($pValue) > 31) { + throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet title.'); + } - /** - * Get highest worksheet row - * - * @return int Highest row number - */ - public function getHighestRow() - { - return $this->_cachedHighestRow; - } + return $pValue; + } - /** - * Get highest worksheet row that contains data - * - * @return string Highest row number that contains data - */ - public function getHighestDataRow() - { - return $this->_cellCollection->getHighestRow(); - } + /** + * Get collection of cells + * + * @param boolean $pSorted Also sort the cell collection? + * @return PHPExcel_Cell[] + */ + public function getCellCollection($pSorted = true) + { + if ($pSorted) { + // Re-order cell collection + return $this->sortCellCollection(); + } + if ($this->_cellCollection !== NULL) { + return $this->_cellCollection->getCellList(); + } + return array(); + } - /** - * Get highest worksheet column and highest row that have cell records - * - * @return array Highest column name and highest row number - */ - public function getHighestRowAndColumn() - { - return $this->_cellCollection->getHighestRowAndColumn(); - } + /** + * Sort collection of cells + * + * @return PHPExcel_Worksheet + */ + public function sortCellCollection() + { + if ($this->_cellCollection !== NULL) { + return $this->_cellCollection->getSortedCellList(); + } + return array(); + } - /** - * Set a cell value - * - * @param string $pCoordinate Coordinate of the cell - * @param mixed $pValue Value of the cell - * @param bool $returnCell Return the worksheet (false, default) or the cell (true) - * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified - */ - public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = false) - { - $cell = $this->getCell($pCoordinate)->setValue($pValue); - return ($returnCell) ? $cell : $this; - } + /** + * Get collection of row dimensions + * + * @return PHPExcel_Worksheet_RowDimension[] + */ + public function getRowDimensions() + { + return $this->_rowDimensions; + } - /** - * Set a cell value by using numeric cell coordinates - * - * @param string $pColumn Numeric column coordinate of the cell (A = 0) - * @param string $pRow Numeric row coordinate of the cell - * @param mixed $pValue Value of the cell - * @param bool $returnCell Return the worksheet (false, default) or the cell (true) - * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified - */ - public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $returnCell = false) - { - $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValue($pValue); - return ($returnCell) ? $cell : $this; - } + /** + * Get default row dimension + * + * @return PHPExcel_Worksheet_RowDimension + */ + public function getDefaultRowDimension() + { + return $this->_defaultRowDimension; + } - /** - * Set a cell value - * - * @param string $pCoordinate Coordinate of the cell - * @param mixed $pValue Value of the cell - * @param string $pDataType Explicit data type - * @param bool $returnCell Return the worksheet (false, default) or the cell (true) - * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified - */ - public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) - { - // Set value - $cell = $this->getCell($pCoordinate)->setValueExplicit($pValue, $pDataType); - return ($returnCell) ? $cell : $this; - } + /** + * Get collection of column dimensions + * + * @return PHPExcel_Worksheet_ColumnDimension[] + */ + public function getColumnDimensions() + { + return $this->_columnDimensions; + } - /** - * Set a cell value by using numeric cell coordinates - * - * @param string $pColumn Numeric column coordinate of the cell - * @param string $pRow Numeric row coordinate of the cell - * @param mixed $pValue Value of the cell - * @param string $pDataType Explicit data type - * @param bool $returnCell Return the worksheet (false, default) or the cell (true) - * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified - */ - public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) - { - $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValueExplicit($pValue, $pDataType); - return ($returnCell) ? $cell : $this; - } + /** + * Get default column dimension + * + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function getDefaultColumnDimension() + { + return $this->_defaultColumnDimension; + } - /** - * Get cell at a specific coordinate - * - * @param string $pCoordinate Coordinate of the cell - * @throws PHPExcel_Exception - * @return PHPExcel_Cell Cell that was found - */ - public function getCell($pCoordinate = 'A1') - { - // Check cell collection - if ($this->_cellCollection->isDataSet($pCoordinate)) { - return $this->_cellCollection->getCacheData($pCoordinate); - } + /** + * Get collection of drawings + * + * @return PHPExcel_Worksheet_BaseDrawing[] + */ + public function getDrawingCollection() + { + return $this->_drawingCollection; + } - // Worksheet reference? - if (strpos($pCoordinate, '!') !== false) { - $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); - return $this->_parent->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]); - } + /** + * Get collection of charts + * + * @return PHPExcel_Chart[] + */ + public function getChartCollection() + { + return $this->_chartCollection; + } - // Named range? - if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) && - (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) { - $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); - if ($namedRange !== NULL) { - $pCoordinate = $namedRange->getRange(); - return $namedRange->getWorksheet()->getCell($pCoordinate); - } - } + /** + * Add chart + * + * @param PHPExcel_Chart $pChart + * @param int|null $iChartIndex Index where chart should go (0,1,..., or null for last) + * @return PHPExcel_Chart + */ + public function addChart(PHPExcel_Chart $pChart = null, $iChartIndex = null) + { + $pChart->setWorksheet($this); + if (is_null($iChartIndex)) { + $this->_chartCollection[] = $pChart; + } else { + // Insert the chart at the requested index + array_splice($this->_chartCollection, $iChartIndex, 0, array($pChart)); + } + + return $pChart; + } + + /** + * Return the count of charts on this worksheet + * + * @return int The number of charts + */ + public function getChartCount() + { + return count($this->_chartCollection); + } + + /** + * Get a chart by its index position + * + * @param string $index Chart index position + * @return false|PHPExcel_Chart + * @throws PHPExcel_Exception + */ + public function getChartByIndex($index = null) + { + $chartCount = count($this->_chartCollection); + if ($chartCount == 0) { + return false; + } + if (is_null($index)) { + $index = --$chartCount; + } + if (!isset($this->_chartCollection[$index])) { + return false; + } + + return $this->_chartCollection[$index]; + } - // Uppercase coordinate - $pCoordinate = strtoupper($pCoordinate); + /** + * Return an array of the names of charts on this worksheet + * + * @return string[] The names of charts + * @throws PHPExcel_Exception + */ + public function getChartNames() + { + $chartNames = array(); + foreach($this->_chartCollection as $chart) { + $chartNames[] = $chart->getName(); + } + return $chartNames; + } - if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { - throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.'); - } elseif (strpos($pCoordinate,'$') !== false) { - throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); - } else { - // Create new cell object + /** + * Get a chart by name + * + * @param string $chartName Chart name + * @return false|PHPExcel_Chart + * @throws PHPExcel_Exception + */ + public function getChartByName($chartName = '') + { + $chartCount = count($this->_chartCollection); + if ($chartCount == 0) { + return false; + } + foreach($this->_chartCollection as $index => $chart) { + if ($chart->getName() == $chartName) { + return $this->_chartCollection[$index]; + } + } + return false; + } - // Coordinates - $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); + /** + * Refresh column dimensions + * + * @return PHPExcel_Worksheet + */ + public function refreshColumnDimensions() + { + $currentColumnDimensions = $this->getColumnDimensions(); + $newColumnDimensions = array(); - $cell = $this->_cellCollection->addCacheData($pCoordinate,new PHPExcel_Cell($pCoordinate, NULL, PHPExcel_Cell_DataType::TYPE_NULL, $this)); - $this->_cellCollectionIsSorted = false; + foreach ($currentColumnDimensions as $objColumnDimension) { + $newColumnDimensions[$objColumnDimension->getColumnIndex()] = $objColumnDimension; + } - if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) - $this->_cachedHighestColumn = $aCoordinates[0]; + $this->_columnDimensions = $newColumnDimensions; - $this->_cachedHighestRow = max($this->_cachedHighestRow,$aCoordinates[1]); + return $this; + } - // Cell needs appropriate xfIndex - $rowDimensions = $this->getRowDimensions(); - $columnDimensions = $this->getColumnDimensions(); + /** + * Refresh row dimensions + * + * @return PHPExcel_Worksheet + */ + public function refreshRowDimensions() + { + $currentRowDimensions = $this->getRowDimensions(); + $newRowDimensions = array(); - if ( isset($rowDimensions[$aCoordinates[1]]) && $rowDimensions[$aCoordinates[1]]->getXfIndex() !== null ) { - // then there is a row dimension with explicit style, assign it to the cell - $cell->setXfIndex($rowDimensions[$aCoordinates[1]]->getXfIndex()); - } else if ( isset($columnDimensions[$aCoordinates[0]]) ) { - // then there is a column dimension, assign it to the cell - $cell->setXfIndex($columnDimensions[$aCoordinates[0]]->getXfIndex()); - } else { - // set to default index - $cell->setXfIndex(0); - } + foreach ($currentRowDimensions as $objRowDimension) { + $newRowDimensions[$objRowDimension->getRowIndex()] = $objRowDimension; + } - return $cell; - } - } + $this->_rowDimensions = $newRowDimensions; - /** - * Get cell at a specific coordinate by using numeric cell coordinates - * - * @param string $pColumn Numeric column coordinate of the cell - * @param string $pRow Numeric row coordinate of the cell - * @return PHPExcel_Cell Cell that was found - */ - public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) - { - $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn); - $coordinate = $columnLetter . $pRow; + return $this; + } - if (!$this->_cellCollection->isDataSet($coordinate)) { - $cell = $this->_cellCollection->addCacheData($coordinate, new PHPExcel_Cell($coordinate, NULL, PHPExcel_Cell_DataType::TYPE_NULL, $this)); - $this->_cellCollectionIsSorted = false; + /** + * Calculate worksheet dimension + * + * @return string String containing the dimension of this worksheet + */ + public function calculateWorksheetDimension() + { + // Return + return 'A1' . ':' . $this->getHighestColumn() . $this->getHighestRow(); + } - if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < $pColumn) - $this->_cachedHighestColumn = $columnLetter; + /** + * Calculate worksheet data dimension + * + * @return string String containing the dimension of this worksheet that actually contain data + */ + public function calculateWorksheetDataDimension() + { + // Return + return 'A1' . ':' . $this->getHighestDataColumn() . $this->getHighestDataRow(); + } - $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow); + /** + * Calculate widths for auto-size columns + * + * @param boolean $calculateMergeCells Calculate merge cell width + * @return PHPExcel_Worksheet; + */ + public function calculateColumnWidths($calculateMergeCells = false) + { + // initialize $autoSizes array + $autoSizes = array(); + foreach ($this->getColumnDimensions() as $colDimension) { + if ($colDimension->getAutoSize()) { + $autoSizes[$colDimension->getColumnIndex()] = -1; + } + } + + // There is only something to do if there are some auto-size columns + if (!empty($autoSizes)) { + + // build list of cells references that participate in a merge + $isMergeCell = array(); + foreach ($this->getMergeCells() as $cells) { + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cells) as $cellReference) { + $isMergeCell[$cellReference] = true; + } + } + + // loop through all cells in the worksheet + foreach ($this->getCellCollection(false) as $cellID) { + $cell = $this->getCell($cellID); + if (isset($autoSizes[$this->_cellCollection->getCurrentColumn()])) { + // Determine width if cell does not participate in a merge + if (!isset($isMergeCell[$this->_cellCollection->getCurrentAddress()])) { + // Calculated value + // To formatted string + $cellValue = PHPExcel_Style_NumberFormat::toFormattedString( + $cell->getCalculatedValue(), + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode() + ); - return $cell; - } + $autoSizes[$this->_cellCollection->getCurrentColumn()] = max( + (float) $autoSizes[$this->_cellCollection->getCurrentColumn()], + (float)PHPExcel_Shared_Font::calculateColumnWidth( + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(), + $cellValue, + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(), + $this->getDefaultStyle()->getFont() + ) + ); + } + } + } + + // adjust column widths + foreach ($autoSizes as $columnIndex => $width) { + if ($width == -1) $width = $this->getDefaultColumnDimension()->getWidth(); + $this->getColumnDimension($columnIndex)->setWidth($width); + } + } + + return $this; + } - return $this->_cellCollection->getCacheData($coordinate); - } + /** + * Get parent + * + * @return PHPExcel + */ + public function getParent() { + return $this->_parent; + } + + /** + * Re-bind parent + * + * @param PHPExcel $parent + * @return PHPExcel_Worksheet + */ + public function rebindParent(PHPExcel $parent) { + $namedRanges = $this->_parent->getNamedRanges(); + foreach ($namedRanges as $namedRange) { + $parent->addNamedRange($namedRange); + } + + $this->_parent->removeSheetByIndex( + $this->_parent->getIndex($this) + ); + $this->_parent = $parent; + + return $this; + } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return $this->_title; + } + + /** + * Set title + * + * @param string $pValue String containing the dimension of this worksheet + * @param string $updateFormulaCellReferences boolean Flag indicating whether cell references in formulae should + * be updated to reflect the new sheet name. + * This should be left as the default true, unless you are + * certain that no formula cells on any worksheet contain + * references to this worksheet + * @return PHPExcel_Worksheet + */ + public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = true) + { + // Is this a 'rename' or not? + if ($this->getTitle() == $pValue) { + return $this; + } + + // Syntax check + self::_checkSheetTitle($pValue); + + // Old title + $oldTitle = $this->getTitle(); + + if ($this->_parent) { + // Is there already such sheet name? + if ($this->_parent->sheetNameExists($pValue)) { + // Use name, but append with lowest possible integer + + if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); + } + $i = 1; + while ($this->_parent->sheetNameExists($pValue . ' ' . $i)) { + ++$i; + if ($i == 10) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); + } + } elseif ($i == 100) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); + } + } + } + + $altTitle = $pValue . ' ' . $i; + return $this->setTitle($altTitle,$updateFormulaCellReferences); + } + } + + // Set title + $this->_title = $pValue; + $this->_dirty = true; + + if ($this->_parent) { + // New title + $newTitle = $this->getTitle(); + PHPExcel_Calculation::getInstance($this->_parent) + ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); + if ($updateFormulaCellReferences) + PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_parent, $oldTitle, $newTitle); + } + + return $this; + } + + /** + * Get sheet state + * + * @return string Sheet state (visible, hidden, veryHidden) + */ + public function getSheetState() { + return $this->_sheetState; + } + + /** + * Set sheet state + * + * @param string $value Sheet state (visible, hidden, veryHidden) + * @return PHPExcel_Worksheet + */ + public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) { + $this->_sheetState = $value; + return $this; + } + + /** + * Get page setup + * + * @return PHPExcel_Worksheet_PageSetup + */ + public function getPageSetup() + { + return $this->_pageSetup; + } + + /** + * Set page setup + * + * @param PHPExcel_Worksheet_PageSetup $pValue + * @return PHPExcel_Worksheet + */ + public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue) + { + $this->_pageSetup = $pValue; + return $this; + } + + /** + * Get page margins + * + * @return PHPExcel_Worksheet_PageMargins + */ + public function getPageMargins() + { + return $this->_pageMargins; + } + + /** + * Set page margins + * + * @param PHPExcel_Worksheet_PageMargins $pValue + * @return PHPExcel_Worksheet + */ + public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue) + { + $this->_pageMargins = $pValue; + return $this; + } + + /** + * Get page header/footer + * + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function getHeaderFooter() + { + return $this->_headerFooter; + } + + /** + * Set page header/footer + * + * @param PHPExcel_Worksheet_HeaderFooter $pValue + * @return PHPExcel_Worksheet + */ + public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue) + { + $this->_headerFooter = $pValue; + return $this; + } + + /** + * Get sheet view + * + * @return PHPExcel_Worksheet_SheetView + */ + public function getSheetView() + { + return $this->_sheetView; + } + + /** + * Set sheet view + * + * @param PHPExcel_Worksheet_SheetView $pValue + * @return PHPExcel_Worksheet + */ + public function setSheetView(PHPExcel_Worksheet_SheetView $pValue) + { + $this->_sheetView = $pValue; + return $this; + } + + /** + * Get Protection + * + * @return PHPExcel_Worksheet_Protection + */ + public function getProtection() + { + return $this->_protection; + } + + /** + * Set Protection + * + * @param PHPExcel_Worksheet_Protection $pValue + * @return PHPExcel_Worksheet + */ + public function setProtection(PHPExcel_Worksheet_Protection $pValue) + { + $this->_protection = $pValue; + $this->_dirty = true; + + return $this; + } + + /** + * Get highest worksheet column + * + * @return string Highest column name + */ + public function getHighestColumn() + { + return $this->_cachedHighestColumn; + } + + /** + * Get highest worksheet column that contains data + * + * @return string Highest column name that contains data + */ + public function getHighestDataColumn() + { + return $this->_cellCollection->getHighestColumn(); + } + + /** + * Get highest worksheet row + * + * @return int Highest row number + */ + public function getHighestRow() + { + return $this->_cachedHighestRow; + } + + /** + * Get highest worksheet row that contains data + * + * @return string Highest row number that contains data + */ + public function getHighestDataRow() + { + return $this->_cellCollection->getHighestRow(); + } + + /** + * Get highest worksheet column and highest row that have cell records + * + * @return array Highest column name and highest row number + */ + public function getHighestRowAndColumn() + { + return $this->_cellCollection->getHighestRowAndColumn(); + } + + /** + * Set a cell value + * + * @param string $pCoordinate Coordinate of the cell + * @param mixed $pValue Value of the cell + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = false) + { + $cell = $this->getCell($pCoordinate)->setValue($pValue); + return ($returnCell) ? $cell : $this; + } + + /** + * Set a cell value by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell (A = 0) + * @param string $pRow Numeric row coordinate of the cell + * @param mixed $pValue Value of the cell + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $returnCell = false) + { + $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValue($pValue); + return ($returnCell) ? $cell : $this; + } + + /** + * Set a cell value + * + * @param string $pCoordinate Coordinate of the cell + * @param mixed $pValue Value of the cell + * @param string $pDataType Explicit data type + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) + { + // Set value + $cell = $this->getCell($pCoordinate)->setValueExplicit($pValue, $pDataType); + return ($returnCell) ? $cell : $this; + } + + /** + * Set a cell value by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell + * @param string $pRow Numeric row coordinate of the cell + * @param mixed $pValue Value of the cell + * @param string $pDataType Explicit data type + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) + { + $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValueExplicit($pValue, $pDataType); + return ($returnCell) ? $cell : $this; + } + + /** + * Get cell at a specific coordinate + * + * @param string $pCoordinate Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found + */ + public function getCell($pCoordinate = 'A1') + { + // Check cell collection + if ($this->_cellCollection->isDataSet($pCoordinate)) { + return $this->_cellCollection->getCacheData($pCoordinate); + } + + // Worksheet reference? + if (strpos($pCoordinate, '!') !== false) { + $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); + return $this->_parent->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]); + } + + // Named range? + if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) && + (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) { + $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); + if ($namedRange !== NULL) { + $pCoordinate = $namedRange->getRange(); + return $namedRange->getWorksheet()->getCell($pCoordinate); + } + } + + // Uppercase coordinate + $pCoordinate = strtoupper($pCoordinate); + + if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { + throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.'); + } elseif (strpos($pCoordinate,'$') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); + } else { + // Create new cell object + + // Coordinates + $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); + + $cell = $this->_cellCollection->addCacheData($pCoordinate,new PHPExcel_Cell(NULL, PHPExcel_Cell_DataType::TYPE_NULL, $this)); + $this->_cellCollectionIsSorted = false; + + if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) + $this->_cachedHighestColumn = $aCoordinates[0]; + + $this->_cachedHighestRow = max($this->_cachedHighestRow,$aCoordinates[1]); + + // Cell needs appropriate xfIndex + $rowDimensions = $this->getRowDimensions(); + $columnDimensions = $this->getColumnDimensions(); + + if ( isset($rowDimensions[$aCoordinates[1]]) && $rowDimensions[$aCoordinates[1]]->getXfIndex() !== null ) { + // then there is a row dimension with explicit style, assign it to the cell + $cell->setXfIndex($rowDimensions[$aCoordinates[1]]->getXfIndex()); + } else if ( isset($columnDimensions[$aCoordinates[0]]) ) { + // then there is a column dimension, assign it to the cell + $cell->setXfIndex($columnDimensions[$aCoordinates[0]]->getXfIndex()); + } else { + // set to default index + $cell->setXfIndex(0); + } + + return $cell; + } + } + + /** + * Get cell at a specific coordinate by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell + * @param string $pRow Numeric row coordinate of the cell + * @return PHPExcel_Cell Cell that was found + */ + public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) + { + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn); + $coordinate = $columnLetter . $pRow; + + if (!$this->_cellCollection->isDataSet($coordinate)) { + $cell = $this->_cellCollection->addCacheData($coordinate, new PHPExcel_Cell(NULL, PHPExcel_Cell_DataType::TYPE_NULL, $this)); + $this->_cellCollectionIsSorted = false; + + if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < $pColumn) + $this->_cachedHighestColumn = $columnLetter; + + $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow); + + return $cell; + } + + return $this->_cellCollection->getCacheData($coordinate); + } - /** - * Cell at a specific coordinate exists? - * - * @param string $pCoordinate Coordinate of the cell - * @throws PHPExcel_Exception - * @return boolean - */ - public function cellExists($pCoordinate = 'A1') - { - // Worksheet reference? - if (strpos($pCoordinate, '!') !== false) { - $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); + /** + * Cell at a specific coordinate exists? + * + * @param string $pCoordinate Coordinate of the cell + * @throws PHPExcel_Exception + * @return boolean + */ + public function cellExists($pCoordinate = 'A1') + { + // Worksheet reference? + if (strpos($pCoordinate, '!') !== false) { + $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); return $this->_parent->getSheetByName($worksheetReference[0])->cellExists($worksheetReference[1]); - } + } + + // Named range? + if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) && + (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) { + $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); + if ($namedRange !== NULL) { + $pCoordinate = $namedRange->getRange(); + if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) { + if (!$namedRange->getLocalOnly()) { + return $namedRange->getWorksheet()->cellExists($pCoordinate); + } else { + throw new PHPExcel_Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle()); + } + } + } + else { return false; } + } + + // Uppercase coordinate + $pCoordinate = strtoupper($pCoordinate); + + if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { + throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.'); + } elseif (strpos($pCoordinate,'$') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); + } else { + // Coordinates + $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); + + // Cell exists? + return $this->_cellCollection->isDataSet($pCoordinate); + } + } - // Named range? - if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) && - (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) { - $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); - if ($namedRange !== NULL) { - $pCoordinate = $namedRange->getRange(); - if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) { - if (!$namedRange->getLocalOnly()) { - return $namedRange->getWorksheet()->cellExists($pCoordinate); - } else { - throw new PHPExcel_Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle()); - } - } - } - else { return false; } - } + /** + * Cell at a specific coordinate by using numeric cell coordinates exists? + * + * @param string $pColumn Numeric column coordinate of the cell + * @param string $pRow Numeric row coordinate of the cell + * @return boolean + */ + public function cellExistsByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->cellExists(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } - // Uppercase coordinate - $pCoordinate = strtoupper($pCoordinate); + /** + * Get row dimension at a specific row + * + * @param int $pRow Numeric index of the row + * @return PHPExcel_Worksheet_RowDimension + */ + public function getRowDimension($pRow = 1) + { + // Found + $found = null; - if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { - throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.'); - } elseif (strpos($pCoordinate,'$') !== false) { - throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); - } else { - // Coordinates - $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); + // Get row dimension + if (!isset($this->_rowDimensions[$pRow])) { + $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow); - // Cell exists? - return $this->_cellCollection->isDataSet($pCoordinate); - } - } + $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow); + } + return $this->_rowDimensions[$pRow]; + } - /** - * Cell at a specific coordinate by using numeric cell coordinates exists? - * - * @param string $pColumn Numeric column coordinate of the cell - * @param string $pRow Numeric row coordinate of the cell - * @return boolean - */ - public function cellExistsByColumnAndRow($pColumn = 0, $pRow = 1) - { - return $this->cellExists(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); - } + /** + * Get column dimension at a specific column + * + * @param string $pColumn String index of the column + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function getColumnDimension($pColumn = 'A') + { + // Uppercase coordinate + $pColumn = strtoupper($pColumn); - /** - * Get row dimension at a specific row - * - * @param int $pRow Numeric index of the row - * @return PHPExcel_Worksheet_RowDimension - */ - public function getRowDimension($pRow = 1) - { - // Found - $found = null; - - // Get row dimension - if (!isset($this->_rowDimensions[$pRow])) { - $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow); - - $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow); - } - return $this->_rowDimensions[$pRow]; - } + // Fetch dimensions + if (!isset($this->_columnDimensions[$pColumn])) { + $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn); - /** - * Get column dimension at a specific column - * - * @param string $pColumn String index of the column - * @return PHPExcel_Worksheet_ColumnDimension - */ - public function getColumnDimension($pColumn = 'A') - { - // Uppercase coordinate - $pColumn = strtoupper($pColumn); - - // Fetch dimensions - if (!isset($this->_columnDimensions[$pColumn])) { - $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn); - - if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) - $this->_cachedHighestColumn = $pColumn; - } - return $this->_columnDimensions[$pColumn]; - } + if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) + $this->_cachedHighestColumn = $pColumn; + } + return $this->_columnDimensions[$pColumn]; + } - /** - * Get column dimension at a specific column by using numeric cell coordinates - * - * @param string $pColumn Numeric column coordinate of the cell - * @return PHPExcel_Worksheet_ColumnDimension - */ - public function getColumnDimensionByColumn($pColumn = 0) - { - return $this->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($pColumn)); - } + /** + * Get column dimension at a specific column by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function getColumnDimensionByColumn($pColumn = 0) + { + return $this->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($pColumn)); + } - /** - * Get styles - * - * @return PHPExcel_Style[] - */ - public function getStyles() - { - return $this->_styles; - } + /** + * Get styles + * + * @return PHPExcel_Style[] + */ + public function getStyles() + { + return $this->_styles; + } - /** - * Get default style of workbook. - * - * @deprecated - * @return PHPExcel_Style - * @throws PHPExcel_Exception - */ - public function getDefaultStyle() - { - return $this->_parent->getDefaultStyle(); - } + /** + * Get default style of workbook. + * + * @deprecated + * @return PHPExcel_Style + * @throws PHPExcel_Exception + */ + public function getDefaultStyle() + { + return $this->_parent->getDefaultStyle(); + } - /** - * Set default style - should only be used by PHPExcel_IReader implementations! - * - * @deprecated - * @param PHPExcel_Style $pValue - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function setDefaultStyle(PHPExcel_Style $pValue) - { - $this->_parent->getDefaultStyle()->applyFromArray(array( - 'font' => array( - 'name' => $pValue->getFont()->getName(), - 'size' => $pValue->getFont()->getSize(), - ), - )); - return $this; - } + /** + * Set default style - should only be used by PHPExcel_IReader implementations! + * + * @deprecated + * @param PHPExcel_Style $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setDefaultStyle(PHPExcel_Style $pValue) + { + $this->_parent->getDefaultStyle()->applyFromArray(array( + 'font' => array( + 'name' => $pValue->getFont()->getName(), + 'size' => $pValue->getFont()->getSize(), + ), + )); + return $this; + } - /** - * Get style for cell - * - * @param string $pCellCoordinate Cell coordinate to get style for - * @return PHPExcel_Style - * @throws PHPExcel_Exception - */ - public function getStyle($pCellCoordinate = 'A1') - { - // set this sheet as active - $this->_parent->setActiveSheetIndex($this->_parent->getIndex($this)); - - // set cell coordinate as active - $this->setSelectedCells($pCellCoordinate); - - return $this->_parent->getCellXfSupervisor(); - } + /** + * Get style for cell + * + * @param string $pCellCoordinate Cell coordinate to get style for + * @return PHPExcel_Style + * @throws PHPExcel_Exception + */ + public function getStyle($pCellCoordinate = 'A1') + { + // set this sheet as active + $this->_parent->setActiveSheetIndex($this->_parent->getIndex($this)); - /** - * Get conditional styles for a cell - * - * @param string $pCoordinate - * @return PHPExcel_Style_Conditional[] - */ - public function getConditionalStyles($pCoordinate = 'A1') - { - if (!isset($this->_conditionalStylesCollection[$pCoordinate])) { - $this->_conditionalStylesCollection[$pCoordinate] = array(); - } - return $this->_conditionalStylesCollection[$pCoordinate]; - } + // set cell coordinate as active + $this->setSelectedCells($pCellCoordinate); - /** - * Do conditional styles exist for this cell? - * - * @param string $pCoordinate - * @return boolean - */ - public function conditionalStylesExists($pCoordinate = 'A1') - { - if (isset($this->_conditionalStylesCollection[$pCoordinate])) { - return true; - } - return false; - } + return $this->_parent->getCellXfSupervisor(); + } - /** - * Removes conditional styles for a cell - * - * @param string $pCoordinate - * @return PHPExcel_Worksheet - */ - public function removeConditionalStyles($pCoordinate = 'A1') - { - unset($this->_conditionalStylesCollection[$pCoordinate]); - return $this; - } + /** + * Get conditional styles for a cell + * + * @param string $pCoordinate + * @return PHPExcel_Style_Conditional[] + */ + public function getConditionalStyles($pCoordinate = 'A1') + { + if (!isset($this->_conditionalStylesCollection[$pCoordinate])) { + $this->_conditionalStylesCollection[$pCoordinate] = array(); + } + return $this->_conditionalStylesCollection[$pCoordinate]; + } - /** - * Get collection of conditional styles - * - * @return array - */ - public function getConditionalStylesCollection() - { - return $this->_conditionalStylesCollection; - } + /** + * Do conditional styles exist for this cell? + * + * @param string $pCoordinate + * @return boolean + */ + public function conditionalStylesExists($pCoordinate = 'A1') + { + if (isset($this->_conditionalStylesCollection[$pCoordinate])) { + return true; + } + return false; + } - /** - * Set conditional styles - * - * @param $pCoordinate string E.g. 'A1' - * @param $pValue PHPExcel_Style_Conditional[] - * @return PHPExcel_Worksheet - */ - public function setConditionalStyles($pCoordinate = 'A1', $pValue) - { - $this->_conditionalStylesCollection[$pCoordinate] = $pValue; - return $this; - } + /** + * Removes conditional styles for a cell + * + * @param string $pCoordinate + * @return PHPExcel_Worksheet + */ + public function removeConditionalStyles($pCoordinate = 'A1') + { + unset($this->_conditionalStylesCollection[$pCoordinate]); + return $this; + } - /** - * Get style for cell by using numeric cell coordinates - * - * @param int $pColumn Numeric column coordinate of the cell - * @param int $pRow Numeric row coordinate of the cell - * @return PHPExcel_Style - */ - public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1) - { - return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); - } + /** + * Get collection of conditional styles + * + * @return array + */ + public function getConditionalStylesCollection() + { + return $this->_conditionalStylesCollection; + } + + /** + * Set conditional styles + * + * @param $pCoordinate string E.g. 'A1' + * @param $pValue PHPExcel_Style_Conditional[] + * @return PHPExcel_Worksheet + */ + public function setConditionalStyles($pCoordinate = 'A1', $pValue) + { + $this->_conditionalStylesCollection[$pCoordinate] = $pValue; + return $this; + } + + /** + * Get style for cell by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @return PHPExcel_Style + */ + public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } - /** - * Set shared cell style to a range of cells - * - * Please note that this will overwrite existing cell styles for cells in range! - * - * @deprecated - * @param PHPExcel_Style $pSharedCellStyle Cell style to share - * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function setSharedStyle(PHPExcel_Style $pSharedCellStyle = null, $pRange = '') - { - $this->duplicateStyle($pSharedCellStyle, $pRange); - return $this; - } + /** + * Set shared cell style to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range! + * + * @deprecated + * @param PHPExcel_Style $pSharedCellStyle Cell style to share + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setSharedStyle(PHPExcel_Style $pSharedCellStyle = null, $pRange = '') + { + $this->duplicateStyle($pSharedCellStyle, $pRange); + return $this; + } - /** - * Duplicate cell style to a range of cells - * - * Please note that this will overwrite existing cell styles for cells in range! - * - * @param PHPExcel_Style $pCellStyle Cell style to duplicate - * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') - { - // make sure we have a real style and not supervisor - $style = $pCellStyle->getIsSupervisor() ? $pCellStyle->getSharedComponent() : $pCellStyle; - - // Add the style to the workbook if necessary - $workbook = $this->_parent; - if ($this->_parent->cellXfExists($pCellStyle)) { - // there is already this cell Xf in our collection - $xfIndex = $pCellStyle->getIndex(); - } else { - // we don't have such a cell Xf, need to add - $workbook->addCellXf($pCellStyle); - $xfIndex = $pCellStyle->getIndex(); - } + /** + * Duplicate cell style to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range! + * + * @param PHPExcel_Style $pCellStyle Cell style to duplicate + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') + { + // make sure we have a real style and not supervisor + $style = $pCellStyle->getIsSupervisor() ? $pCellStyle->getSharedComponent() : $pCellStyle; + + // Add the style to the workbook if necessary + $workbook = $this->_parent; + if ($this->_parent->cellXfExists($pCellStyle)) { + // there is already this cell Xf in our collection + $xfIndex = $pCellStyle->getIndex(); + } else { + // we don't have such a cell Xf, need to add + $workbook->addCellXf($pCellStyle); + $xfIndex = $pCellStyle->getIndex(); + } + + // Uppercase coordinate + $pRange = strtoupper($pRange); + + // Is it a cell range or a single cell? + $rangeA = ''; + $rangeB = ''; + if (strpos($pRange, ':') === false) { + $rangeA = $pRange; + $rangeB = $pRange; + } else { + list($rangeA, $rangeB) = explode(':', $pRange); + } + + // Calculate range outer borders + $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA); + $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB); + + // Translate column into index + $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1; + $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1; + + // Make sure we can loop upwards on rows and columns + if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { + $tmp = $rangeStart; + $rangeStart = $rangeEnd; + $rangeEnd = $tmp; + } + + // Loop through cells and apply styles + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col) . $row)->setXfIndex($xfIndex); + } + } + + return $this; + } - // Uppercase coordinate - $pRange = strtoupper($pRange); - - // Is it a cell range or a single cell? - $rangeA = ''; - $rangeB = ''; - if (strpos($pRange, ':') === false) { - $rangeA = $pRange; - $rangeB = $pRange; - } else { - list($rangeA, $rangeB) = explode(':', $pRange); - } + /** + * Duplicate conditional style to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range! + * + * @param array of PHPExcel_Style_Conditional $pCellStyle Cell style to duplicate + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function duplicateConditionalStyle(array $pCellStyle = null, $pRange = '') + { + foreach($pCellStyle as $cellStyle) { + if (!($cellStyle instanceof PHPExcel_Style_Conditional)) { + throw new PHPExcel_Exception('Style is not a conditional style'); + } + } + + // Uppercase coordinate + $pRange = strtoupper($pRange); + + // Is it a cell range or a single cell? + $rangeA = ''; + $rangeB = ''; + if (strpos($pRange, ':') === false) { + $rangeA = $pRange; + $rangeB = $pRange; + } else { + list($rangeA, $rangeB) = explode(':', $pRange); + } + + // Calculate range outer borders + $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA); + $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB); + + // Translate column into index + $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1; + $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1; + + // Make sure we can loop upwards on rows and columns + if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { + $tmp = $rangeStart; + $rangeStart = $rangeEnd; + $rangeEnd = $tmp; + } + + // Loop through cells and apply styles + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $this->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($col) . $row, $pCellStyle); + } + } + + return $this; + } - // Calculate range outer borders - $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA); - $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB); + /** + * Duplicate cell style array to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range, + * if they are in the styles array. For example, if you decide to set a range of + * cells to font bold, only include font bold in the styles array. + * + * @deprecated + * @param array $pStyles Array containing style information + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @param boolean $pAdvanced Advanced mode for setting borders. + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function duplicateStyleArray($pStyles = null, $pRange = '', $pAdvanced = true) + { + $this->getStyle($pRange)->applyFromArray($pStyles, $pAdvanced); + return $this; + } - // Translate column into index - $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1; - $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1; + /** + * Set break on a cell + * + * @param string $pCell Cell coordinate (e.g. A1) + * @param int $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE) + { + // Uppercase coordinate + $pCell = strtoupper($pCell); - // Make sure we can loop upwards on rows and columns - if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { - $tmp = $rangeStart; - $rangeStart = $rangeEnd; - $rangeEnd = $tmp; - } + if ($pCell != '') { + $this->_breaks[$pCell] = $pBreak; + } else { + throw new PHPExcel_Exception('No cell coordinate specified.'); + } - // Loop through cells and apply styles - for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { - for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { - $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col) . $row)->setXfIndex($xfIndex); - } - } + return $this; + } - return $this; - } + /** + * Set break on a cell by using numeric cell coordinates + * + * @param integer $pColumn Numeric column coordinate of the cell + * @param integer $pRow Numeric row coordinate of the cell + * @param integer $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*) + * @return PHPExcel_Worksheet + */ + public function setBreakByColumnAndRow($pColumn = 0, $pRow = 1, $pBreak = PHPExcel_Worksheet::BREAK_NONE) + { + return $this->setBreak(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow, $pBreak); + } - /** - * Duplicate conditional style to a range of cells - * - * Please note that this will overwrite existing cell styles for cells in range! - * - * @param array of PHPExcel_Style_Conditional $pCellStyle Cell style to duplicate - * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function duplicateConditionalStyle(array $pCellStyle = null, $pRange = '') - { - foreach($pCellStyle as $cellStyle) { - if (!($cellStyle instanceof PHPExcel_Style_Conditional)) { - throw new PHPExcel_Exception('Style is not a conditional style'); - } - } + /** + * Get breaks + * + * @return array[] + */ + public function getBreaks() + { + return $this->_breaks; + } - // Uppercase coordinate - $pRange = strtoupper($pRange); - - // Is it a cell range or a single cell? - $rangeA = ''; - $rangeB = ''; - if (strpos($pRange, ':') === false) { - $rangeA = $pRange; - $rangeB = $pRange; - } else { - list($rangeA, $rangeB) = explode(':', $pRange); - } + /** + * Set merge on a cell range + * + * @param string $pRange Cell range (e.g. A1:E1) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function mergeCells($pRange = 'A1:A1') + { + // Uppercase coordinate + $pRange = strtoupper($pRange); - // Calculate range outer borders - $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA); - $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB); + if (strpos($pRange,':') !== false) { + $this->_mergeCells[$pRange] = $pRange; - // Translate column into index - $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1; - $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1; + // make sure cells are created - // Make sure we can loop upwards on rows and columns - if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { - $tmp = $rangeStart; - $rangeStart = $rangeEnd; - $rangeEnd = $tmp; - } + // get the cells in the range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); - // Loop through cells and apply styles - for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { - for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { - $this->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($col) . $row, $pCellStyle); - } - } + // create upper left cell if it does not already exist + $upperLeft = $aReferences[0]; + if (!$this->cellExists($upperLeft)) { + $this->getCell($upperLeft)->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); + } - return $this; - } + // create or blank out the rest of the cells in the range + $count = count($aReferences); + for ($i = 1; $i < $count; $i++) { + $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); + } - /** - * Duplicate cell style array to a range of cells - * - * Please note that this will overwrite existing cell styles for cells in range, - * if they are in the styles array. For example, if you decide to set a range of - * cells to font bold, only include font bold in the styles array. - * - * @deprecated - * @param array $pStyles Array containing style information - * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") - * @param boolean $pAdvanced Advanced mode for setting borders. - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function duplicateStyleArray($pStyles = null, $pRange = '', $pAdvanced = true) - { - $this->getStyle($pRange)->applyFromArray($pStyles, $pAdvanced); - return $this; - } + } else { + throw new PHPExcel_Exception('Merge must be set on a range of cells.'); + } - /** - * Set break on a cell - * - * @param string $pCell Cell coordinate (e.g. A1) - * @param int $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*) - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE) - { - // Uppercase coordinate - $pCell = strtoupper($pCell); - - if ($pCell != '') { - $this->_breaks[$pCell] = $pBreak; - } else { - throw new PHPExcel_Exception('No cell coordinate specified.'); - } + return $this; + } - return $this; - } + /** + * Set merge on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function mergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->mergeCells($cellRange); + } - /** - * Set break on a cell by using numeric cell coordinates - * - * @param integer $pColumn Numeric column coordinate of the cell - * @param integer $pRow Numeric row coordinate of the cell - * @param integer $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*) - * @return PHPExcel_Worksheet - */ - public function setBreakByColumnAndRow($pColumn = 0, $pRow = 1, $pBreak = PHPExcel_Worksheet::BREAK_NONE) - { - return $this->setBreak(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow, $pBreak); - } + /** + * Remove merge on a cell range + * + * @param string $pRange Cell range (e.g. A1:E1) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unmergeCells($pRange = 'A1:A1') + { + // Uppercase coordinate + $pRange = strtoupper($pRange); + + if (strpos($pRange,':') !== false) { + if (isset($this->_mergeCells[$pRange])) { + unset($this->_mergeCells[$pRange]); + } else { + throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as merged.'); + } + } else { + throw new PHPExcel_Exception('Merge can only be removed from a range of cells.'); + } + + return $this; + } - /** - * Get breaks - * - * @return array[] - */ - public function getBreaks() - { - return $this->_breaks; - } + /** + * Remove merge on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unmergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->unmergeCells($cellRange); + } - /** - * Set merge on a cell range - * - * @param string $pRange Cell range (e.g. A1:E1) - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function mergeCells($pRange = 'A1:A1') - { - // Uppercase coordinate - $pRange = strtoupper($pRange); - - if (strpos($pRange,':') !== false) { - $this->_mergeCells[$pRange] = $pRange; - - // make sure cells are created - - // get the cells in the range - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); - - // create upper left cell if it does not already exist - $upperLeft = $aReferences[0]; - if (!$this->cellExists($upperLeft)) { - $this->getCell($upperLeft)->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); - } - - // create or blank out the rest of the cells in the range - $count = count($aReferences); - for ($i = 1; $i < $count; $i++) { - $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); - } - - } else { - throw new PHPExcel_Exception('Merge must be set on a range of cells.'); - } + /** + * Get merge cells array. + * + * @return array[] + */ + public function getMergeCells() + { + return $this->_mergeCells; + } - return $this; - } + /** + * Set merge cells array for the entire sheet. Use instead mergeCells() to merge + * a single cell range. + * + * @param array + */ + public function setMergeCells($pValue = array()) + { + $this->_mergeCells = $pValue; - /** - * Set merge on a cell range by using numeric cell coordinates - * - * @param int $pColumn1 Numeric column coordinate of the first cell - * @param int $pRow1 Numeric row coordinate of the first cell - * @param int $pColumn2 Numeric column coordinate of the last cell - * @param int $pRow2 Numeric row coordinate of the last cell - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function mergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) - { - $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; - return $this->mergeCells($cellRange); - } + return $this; + } - /** - * Remove merge on a cell range - * - * @param string $pRange Cell range (e.g. A1:E1) - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function unmergeCells($pRange = 'A1:A1') - { - // Uppercase coordinate - $pRange = strtoupper($pRange); - - if (strpos($pRange,':') !== false) { - if (isset($this->_mergeCells[$pRange])) { - unset($this->_mergeCells[$pRange]); - } else { - throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as merged.'); - } - } else { - throw new PHPExcel_Exception('Merge can only be removed from a range of cells.'); - } + /** + * Set protection on a cell range + * + * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1) + * @param string $pPassword Password to unlock the protection + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function protectCells($pRange = 'A1', $pPassword = '', $pAlreadyHashed = false) + { + // Uppercase coordinate + $pRange = strtoupper($pRange); - return $this; - } + if (!$pAlreadyHashed) { + $pPassword = PHPExcel_Shared_PasswordHasher::hashPassword($pPassword); + } + $this->_protectedCells[$pRange] = $pPassword; - /** - * Remove merge on a cell range by using numeric cell coordinates - * - * @param int $pColumn1 Numeric column coordinate of the first cell - * @param int $pRow1 Numeric row coordinate of the first cell - * @param int $pColumn2 Numeric column coordinate of the last cell - * @param int $pRow2 Numeric row coordinate of the last cell - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function unmergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) - { - $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; - return $this->unmergeCells($cellRange); - } + return $this; + } - /** - * Get merge cells array. - * - * @return array[] - */ - public function getMergeCells() - { - return $this->_mergeCells; - } + /** + * Set protection on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @param string $pPassword Password to unlock the protection + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function protectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->protectCells($cellRange, $pPassword, $pAlreadyHashed); + } - /** - * Set merge cells array for the entire sheet. Use instead mergeCells() to merge - * a single cell range. - * - * @param array - */ - public function setMergeCells($pValue = array()) - { - $this->_mergeCells = $pValue; - - return $this; - } + /** + * Remove protection on a cell range + * + * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unprotectCells($pRange = 'A1') + { + // Uppercase coordinate + $pRange = strtoupper($pRange); + + if (isset($this->_protectedCells[$pRange])) { + unset($this->_protectedCells[$pRange]); + } else { + throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as protected.'); + } + return $this; + } - /** - * Set protection on a cell range - * - * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1) - * @param string $pPassword Password to unlock the protection - * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function protectCells($pRange = 'A1', $pPassword = '', $pAlreadyHashed = false) - { - // Uppercase coordinate - $pRange = strtoupper($pRange); - - if (!$pAlreadyHashed) { - $pPassword = PHPExcel_Shared_PasswordHasher::hashPassword($pPassword); - } - $this->_protectedCells[$pRange] = $pPassword; + /** + * Remove protection on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @param string $pPassword Password to unlock the protection + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unprotectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->unprotectCells($cellRange, $pPassword, $pAlreadyHashed); + } - return $this; - } + /** + * Get protected cells + * + * @return array[] + */ + public function getProtectedCells() + { + return $this->_protectedCells; + } - /** - * Set protection on a cell range by using numeric cell coordinates - * - * @param int $pColumn1 Numeric column coordinate of the first cell - * @param int $pRow1 Numeric row coordinate of the first cell - * @param int $pColumn2 Numeric column coordinate of the last cell - * @param int $pRow2 Numeric row coordinate of the last cell - * @param string $pPassword Password to unlock the protection - * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function protectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false) - { - $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; - return $this->protectCells($cellRange, $pPassword, $pAlreadyHashed); - } + /** + * Get Autofilter + * + * @return PHPExcel_Worksheet_AutoFilter + */ + public function getAutoFilter() + { + return $this->_autoFilter; + } - /** - * Remove protection on a cell range - * - * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1) - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function unprotectCells($pRange = 'A1') - { - // Uppercase coordinate - $pRange = strtoupper($pRange); - - if (isset($this->_protectedCells[$pRange])) { - unset($this->_protectedCells[$pRange]); - } else { - throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as protected.'); - } - return $this; - } + /** + * Set AutoFilter + * + * @param PHPExcel_Worksheet_AutoFilter|string $pValue + * A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setAutoFilter($pValue) + { + if (is_string($pValue)) { + $this->_autoFilter->setRange($pValue); + } elseif(is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) { + $this->_autoFilter = $pValue; + } + return $this; + } - /** - * Remove protection on a cell range by using numeric cell coordinates - * - * @param int $pColumn1 Numeric column coordinate of the first cell - * @param int $pRow1 Numeric row coordinate of the first cell - * @param int $pColumn2 Numeric column coordinate of the last cell - * @param int $pRow2 Numeric row coordinate of the last cell - * @param string $pPassword Password to unlock the protection - * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function unprotectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false) - { - $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; - return $this->unprotectCells($cellRange, $pPassword, $pAlreadyHashed); - } + /** + * Set Autofilter Range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the second cell + * @param int $pRow2 Numeric row coordinate of the second cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) + { + return $this->setAutoFilter( + PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 + . ':' . + PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2 + ); + } - /** - * Get protected cells - * - * @return array[] - */ - public function getProtectedCells() - { - return $this->_protectedCells; - } + /** + * Remove autofilter + * + * @return PHPExcel_Worksheet + */ + public function removeAutoFilter() + { + $this->_autoFilter->setRange(NULL); + return $this; + } - /** - * Get Autofilter - * - * @return PHPExcel_Worksheet_AutoFilter - */ - public function getAutoFilter() - { - return $this->_autoFilter; - } + /** + * Get Freeze Pane + * + * @return string + */ + public function getFreezePane() + { + return $this->_freezePane; + } - /** - * Set AutoFilter - * - * @param PHPExcel_Worksheet_AutoFilter|string $pValue - * A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function setAutoFilter($pValue) - { - if (is_string($pValue)) { - $this->_autoFilter->setRange($pValue); - } elseif(is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) { - $this->_autoFilter = $pValue; - } - return $this; - } + /** + * Freeze Pane + * + * @param string $pCell Cell (i.e. A2) + * Examples: + * A2 will freeze the rows above cell A2 (i.e row 1) + * B1 will freeze the columns to the left of cell B1 (i.e column A) + * B2 will freeze the rows above and to the left of cell A2 + * (i.e row 1 and column A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function freezePane($pCell = '') + { + // Uppercase coordinate + $pCell = strtoupper($pCell); + + if (strpos($pCell,':') === false && strpos($pCell,',') === false) { + $this->_freezePane = $pCell; + } else { + throw new PHPExcel_Exception('Freeze pane can not be set on a range of cells.'); + } + return $this; + } - /** - * Set Autofilter Range by using numeric cell coordinates - * - * @param int $pColumn1 Numeric column coordinate of the first cell - * @param int $pRow1 Numeric row coordinate of the first cell - * @param int $pColumn2 Numeric column coordinate of the second cell - * @param int $pRow2 Numeric row coordinate of the second cell - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) - { - return $this->setAutoFilter( - PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 - . ':' . - PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2 - ); - } + /** + * Freeze Pane by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function freezePaneByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->freezePane(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } /** - * Remove autofilter + * Unfreeze Pane * * @return PHPExcel_Worksheet */ - public function removeAutoFilter() + public function unfreezePane() { - $this->_autoFilter->setRange(NULL); - return $this; + return $this->freezePane(''); } - /** - * Get Freeze Pane - * - * @return string - */ - public function getFreezePane() - { - return $this->_freezePane; - } + /** + * Insert a new row, updating all possible related data + * + * @param int $pBefore Insert before this one + * @param int $pNumRows Number of rows to insert + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function insertNewRowBefore($pBefore = 1, $pNumRows = 1) { + if ($pBefore >= 1) { + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore('A' . $pBefore, 0, $pNumRows, $this); + } else { + throw new PHPExcel_Exception("Rows can only be inserted before at least row 1."); + } + return $this; + } - /** - * Freeze Pane - * - * @param string $pCell Cell (i.e. A2) - * Examples: - * A2 will freeze the rows above cell A2 (i.e row 1) - * B1 will freeze the columns to the left of cell B1 (i.e column A) - * B2 will freeze the rows above and to the left of cell A2 - * (i.e row 1 and column A) - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function freezePane($pCell = '') - { - // Uppercase coordinate - $pCell = strtoupper($pCell); - - if (strpos($pCell,':') === false && strpos($pCell,',') === false) { - $this->_freezePane = $pCell; - } else { - throw new PHPExcel_Exception('Freeze pane can not be set on a range of cells.'); - } - return $this; - } + /** + * Insert a new column, updating all possible related data + * + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to insert + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1) { + if (!is_numeric($pBefore)) { + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore($pBefore . '1', $pNumCols, 0, $this); + } else { + throw new PHPExcel_Exception("Column references should not be numeric."); + } + return $this; + } - /** - * Freeze Pane by using numeric cell coordinates - * - * @param int $pColumn Numeric column coordinate of the cell - * @param int $pRow Numeric row coordinate of the cell - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function freezePaneByColumnAndRow($pColumn = 0, $pRow = 1) - { - return $this->freezePane(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); - } + /** + * Insert a new column, updating all possible related data + * + * @param int $pBefore Insert before this one (numeric column coordinate of the cell) + * @param int $pNumCols Number of columns to insert + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) { + if ($pBefore >= 0) { + return $this->insertNewColumnBefore(PHPExcel_Cell::stringFromColumnIndex($pBefore), $pNumCols); + } else { + throw new PHPExcel_Exception("Columns can only be inserted before at least column A (0)."); + } + } - /** - * Unfreeze Pane - * - * @return PHPExcel_Worksheet - */ - public function unfreezePane() - { - return $this->freezePane(''); - } + /** + * Delete a row, updating all possible related data + * + * @param int $pRow Remove starting with this one + * @param int $pNumRows Number of rows to remove + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function removeRow($pRow = 1, $pNumRows = 1) { + if ($pRow >= 1) { + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this); + } else { + throw new PHPExcel_Exception("Rows to be deleted should at least start from row 1."); + } + return $this; + } - /** - * Insert a new row, updating all possible related data - * - * @param int $pBefore Insert before this one - * @param int $pNumRows Number of rows to insert - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function insertNewRowBefore($pBefore = 1, $pNumRows = 1) { - if ($pBefore >= 1) { - $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); - $objReferenceHelper->insertNewBefore('A' . $pBefore, 0, $pNumRows, $this); - } else { - throw new PHPExcel_Exception("Rows can only be inserted before at least row 1."); - } - return $this; - } + /** + * Remove a column, updating all possible related data + * + * @param int $pColumn Remove starting with this one + * @param int $pNumCols Number of columns to remove + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function removeColumn($pColumn = 'A', $pNumCols = 1) { + if (!is_numeric($pColumn)) { + $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols); + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this); + } else { + throw new PHPExcel_Exception("Column references should not be numeric."); + } + return $this; + } - /** - * Insert a new column, updating all possible related data - * - * @param int $pBefore Insert before this one - * @param int $pNumCols Number of columns to insert - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1) { - if (!is_numeric($pBefore)) { - $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); - $objReferenceHelper->insertNewBefore($pBefore . '1', $pNumCols, 0, $this); - } else { - throw new PHPExcel_Exception("Column references should not be numeric."); - } - return $this; - } + /** + * Remove a column, updating all possible related data + * + * @param int $pColumn Remove starting with this one (numeric column coordinate of the cell) + * @param int $pNumCols Number of columns to remove + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) { + if ($pColumn >= 0) { + return $this->removeColumn(PHPExcel_Cell::stringFromColumnIndex($pColumn), $pNumCols); + } else { + throw new PHPExcel_Exception("Columns to be deleted should at least start from column 0"); + } + } - /** - * Insert a new column, updating all possible related data - * - * @param int $pBefore Insert before this one (numeric column coordinate of the cell) - * @param int $pNumCols Number of columns to insert - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) { - if ($pBefore >= 0) { - return $this->insertNewColumnBefore(PHPExcel_Cell::stringFromColumnIndex($pBefore), $pNumCols); - } else { - throw new PHPExcel_Exception("Columns can only be inserted before at least column A (0)."); - } - } + /** + * Show gridlines? + * + * @return boolean + */ + public function getShowGridlines() { + return $this->_showGridlines; + } - /** - * Delete a row, updating all possible related data - * - * @param int $pRow Remove starting with this one - * @param int $pNumRows Number of rows to remove - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function removeRow($pRow = 1, $pNumRows = 1) { - if ($pRow >= 1) { - $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); - $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this); - } else { - throw new PHPExcel_Exception("Rows to be deleted should at least start from row 1."); - } - return $this; - } + /** + * Set show gridlines + * + * @param boolean $pValue Show gridlines (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowGridlines($pValue = false) { + $this->_showGridlines = $pValue; + return $this; + } - /** - * Remove a column, updating all possible related data - * - * @param int $pColumn Remove starting with this one - * @param int $pNumCols Number of columns to remove - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function removeColumn($pColumn = 'A', $pNumCols = 1) { - if (!is_numeric($pColumn)) { - $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols); - $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); - $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this); - } else { - throw new PHPExcel_Exception("Column references should not be numeric."); - } - return $this; - } + /** + * Print gridlines? + * + * @return boolean + */ + public function getPrintGridlines() { + return $this->_printGridlines; + } - /** - * Remove a column, updating all possible related data - * - * @param int $pColumn Remove starting with this one (numeric column coordinate of the cell) - * @param int $pNumCols Number of columns to remove - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) { - if ($pColumn >= 0) { - return $this->removeColumn(PHPExcel_Cell::stringFromColumnIndex($pColumn), $pNumCols); - } else { - throw new PHPExcel_Exception("Columns to be deleted should at least start from column 0"); - } - } + /** + * Set print gridlines + * + * @param boolean $pValue Print gridlines (true/false) + * @return PHPExcel_Worksheet + */ + public function setPrintGridlines($pValue = false) { + $this->_printGridlines = $pValue; + return $this; + } - /** - * Show gridlines? - * - * @return boolean - */ - public function getShowGridlines() { - return $this->_showGridlines; - } + /** + * Show row and column headers? + * + * @return boolean + */ + public function getShowRowColHeaders() { + return $this->_showRowColHeaders; + } - /** - * Set show gridlines - * - * @param boolean $pValue Show gridlines (true/false) - * @return PHPExcel_Worksheet - */ - public function setShowGridlines($pValue = false) { - $this->_showGridlines = $pValue; - return $this; - } + /** + * Set show row and column headers + * + * @param boolean $pValue Show row and column headers (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowRowColHeaders($pValue = false) { + $this->_showRowColHeaders = $pValue; + return $this; + } + + /** + * Show summary below? (Row/Column outlining) + * + * @return boolean + */ + public function getShowSummaryBelow() { + return $this->_showSummaryBelow; + } - /** - * Print gridlines? - * - * @return boolean - */ - public function getPrintGridlines() { - return $this->_printGridlines; - } + /** + * Set show summary below + * + * @param boolean $pValue Show summary below (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowSummaryBelow($pValue = true) { + $this->_showSummaryBelow = $pValue; + return $this; + } - /** - * Set print gridlines - * - * @param boolean $pValue Print gridlines (true/false) - * @return PHPExcel_Worksheet - */ - public function setPrintGridlines($pValue = false) { - $this->_printGridlines = $pValue; - return $this; - } + /** + * Show summary right? (Row/Column outlining) + * + * @return boolean + */ + public function getShowSummaryRight() { + return $this->_showSummaryRight; + } - /** - * Show row and column headers? - * - * @return boolean - */ - public function getShowRowColHeaders() { - return $this->_showRowColHeaders; - } + /** + * Set show summary right + * + * @param boolean $pValue Show summary right (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowSummaryRight($pValue = true) { + $this->_showSummaryRight = $pValue; + return $this; + } - /** - * Set show row and column headers - * - * @param boolean $pValue Show row and column headers (true/false) - * @return PHPExcel_Worksheet - */ - public function setShowRowColHeaders($pValue = false) { - $this->_showRowColHeaders = $pValue; - return $this; - } + /** + * Get comments + * + * @return PHPExcel_Comment[] + */ + public function getComments() + { + return $this->_comments; + } - /** - * Show summary below? (Row/Column outlining) - * - * @return boolean - */ - public function getShowSummaryBelow() { - return $this->_showSummaryBelow; - } + /** + * Set comments array for the entire sheet. + * + * @param array of PHPExcel_Comment + * @return PHPExcel_Worksheet + */ + public function setComments($pValue = array()) + { + $this->_comments = $pValue; - /** - * Set show summary below - * - * @param boolean $pValue Show summary below (true/false) - * @return PHPExcel_Worksheet - */ - public function setShowSummaryBelow($pValue = true) { - $this->_showSummaryBelow = $pValue; - return $this; - } + return $this; + } - /** - * Show summary right? (Row/Column outlining) - * - * @return boolean - */ - public function getShowSummaryRight() { - return $this->_showSummaryRight; - } + /** + * Get comment for cell + * + * @param string $pCellCoordinate Cell coordinate to get comment for + * @return PHPExcel_Comment + * @throws PHPExcel_Exception + */ + public function getComment($pCellCoordinate = 'A1') + { + // Uppercase coordinate + $pCellCoordinate = strtoupper($pCellCoordinate); + + if (strpos($pCellCoordinate,':') !== false || strpos($pCellCoordinate,',') !== false) { + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells.'); + } else if (strpos($pCellCoordinate,'$') !== false) { + throw new PHPExcel_Exception('Cell coordinate string must not be absolute.'); + } else if ($pCellCoordinate == '') { + throw new PHPExcel_Exception('Cell coordinate can not be zero-length string.'); + } else { + // Check if we already have a comment for this cell. + // If not, create a new comment. + if (isset($this->_comments[$pCellCoordinate])) { + return $this->_comments[$pCellCoordinate]; + } else { + $newComment = new PHPExcel_Comment(); + $this->_comments[$pCellCoordinate] = $newComment; + return $newComment; + } + } + } - /** - * Set show summary right - * - * @param boolean $pValue Show summary right (true/false) - * @return PHPExcel_Worksheet - */ - public function setShowSummaryRight($pValue = true) { - $this->_showSummaryRight = $pValue; - return $this; - } + /** + * Get comment for cell by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @return PHPExcel_Comment + */ + public function getCommentByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->getComment(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } - /** - * Get comments - * - * @return PHPExcel_Comment[] - */ - public function getComments() - { - return $this->_comments; - } + /** + * Get selected cell + * + * @deprecated + * @return string + */ + public function getSelectedCell() + { + return $this->getSelectedCells(); + } - /** - * Set comments array for the entire sheet. - * - * @param array of PHPExcel_Comment - * @return PHPExcel_Worksheet - */ - public function setComments($pValue = array()) - { - $this->_comments = $pValue; + /** + * Get active cell + * + * @return string Example: 'A1' + */ + public function getActiveCell() + { + return $this->_activeCell; + } - return $this; - } + /** + * Get selected cells + * + * @return string + */ + public function getSelectedCells() + { + return $this->_selectedCells; + } - /** - * Get comment for cell - * - * @param string $pCellCoordinate Cell coordinate to get comment for - * @return PHPExcel_Comment - * @throws PHPExcel_Exception - */ - public function getComment($pCellCoordinate = 'A1') - { - // Uppercase coordinate - $pCellCoordinate = strtoupper($pCellCoordinate); - - if (strpos($pCellCoordinate,':') !== false || strpos($pCellCoordinate,',') !== false) { - throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells.'); - } else if (strpos($pCellCoordinate,'$') !== false) { - throw new PHPExcel_Exception('Cell coordinate string must not be absolute.'); - } else if ($pCellCoordinate == '') { - throw new PHPExcel_Exception('Cell coordinate can not be zero-length string.'); - } else { - // Check if we already have a comment for this cell. - // If not, create a new comment. - if (isset($this->_comments[$pCellCoordinate])) { - return $this->_comments[$pCellCoordinate]; - } else { - $newComment = new PHPExcel_Comment(); - $this->_comments[$pCellCoordinate] = $newComment; - return $newComment; - } - } - } + /** + * Selected cell + * + * @param string $pCoordinate Cell (i.e. A1) + * @return PHPExcel_Worksheet + */ + public function setSelectedCell($pCoordinate = 'A1') + { + return $this->setSelectedCells($pCoordinate); + } - /** - * Get comment for cell by using numeric cell coordinates - * - * @param int $pColumn Numeric column coordinate of the cell - * @param int $pRow Numeric row coordinate of the cell - * @return PHPExcel_Comment - */ - public function getCommentByColumnAndRow($pColumn = 0, $pRow = 1) - { - return $this->getComment(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); - } + /** + * Select a range of cells. + * + * @param string $pCoordinate Cell range, examples: 'A1', 'B2:G5', 'A:C', '3:6' + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setSelectedCells($pCoordinate = 'A1') + { + // Uppercase coordinate + $pCoordinate = strtoupper($pCoordinate); - /** - * Get selected cell - * - * @deprecated - * @return string - */ - public function getSelectedCell() - { - return $this->getSelectedCells(); - } + // Convert 'A' to 'A:A' + $pCoordinate = preg_replace('/^([A-Z]+)$/', '${1}:${1}', $pCoordinate); - /** - * Get active cell - * - * @return string Example: 'A1' - */ - public function getActiveCell() - { - return $this->_activeCell; - } + // Convert '1' to '1:1' + $pCoordinate = preg_replace('/^([0-9]+)$/', '${1}:${1}', $pCoordinate); - /** - * Get selected cells - * - * @return string - */ - public function getSelectedCells() - { - return $this->_selectedCells; - } + // Convert 'A:C' to 'A1:C1048576' + $pCoordinate = preg_replace('/^([A-Z]+):([A-Z]+)$/', '${1}1:${2}1048576', $pCoordinate); - /** - * Selected cell - * - * @param string $pCoordinate Cell (i.e. A1) - * @return PHPExcel_Worksheet - */ - public function setSelectedCell($pCoordinate = 'A1') - { - return $this->setSelectedCells($pCoordinate); - } + // Convert '1:3' to 'A1:XFD3' + $pCoordinate = preg_replace('/^([0-9]+):([0-9]+)$/', 'A${1}:XFD${2}', $pCoordinate); - /** - * Select a range of cells. - * - * @param string $pCoordinate Cell range, examples: 'A1', 'B2:G5', 'A:C', '3:6' - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function setSelectedCells($pCoordinate = 'A1') - { - // Uppercase coordinate - $pCoordinate = strtoupper($pCoordinate); - - // Convert 'A' to 'A:A' - $pCoordinate = preg_replace('/^([A-Z]+)$/', '${1}:${1}', $pCoordinate); - - // Convert '1' to '1:1' - $pCoordinate = preg_replace('/^([0-9]+)$/', '${1}:${1}', $pCoordinate); - - // Convert 'A:C' to 'A1:C1048576' - $pCoordinate = preg_replace('/^([A-Z]+):([A-Z]+)$/', '${1}1:${2}1048576', $pCoordinate); - - // Convert '1:3' to 'A1:XFD3' - $pCoordinate = preg_replace('/^([0-9]+):([0-9]+)$/', 'A${1}:XFD${2}', $pCoordinate); - - if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { - list($first, ) = PHPExcel_Cell::splitRange($pCoordinate); - $this->_activeCell = $first[0]; - } else { - $this->_activeCell = $pCoordinate; - } - $this->_selectedCells = $pCoordinate; - return $this; - } + if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { + list($first, ) = PHPExcel_Cell::splitRange($pCoordinate); + $this->_activeCell = $first[0]; + } else { + $this->_activeCell = $pCoordinate; + } + $this->_selectedCells = $pCoordinate; + return $this; + } - /** - * Selected cell by using numeric cell coordinates - * - * @param int $pColumn Numeric column coordinate of the cell - * @param int $pRow Numeric row coordinate of the cell - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function setSelectedCellByColumnAndRow($pColumn = 0, $pRow = 1) - { - return $this->setSelectedCells(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); - } + /** + * Selected cell by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setSelectedCellByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->setSelectedCells(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } - /** - * Get right-to-left - * - * @return boolean - */ - public function getRightToLeft() { - return $this->_rightToLeft; - } + /** + * Get right-to-left + * + * @return boolean + */ + public function getRightToLeft() { + return $this->_rightToLeft; + } - /** - * Set right-to-left - * - * @param boolean $value Right-to-left true/false - * @return PHPExcel_Worksheet - */ - public function setRightToLeft($value = false) { - $this->_rightToLeft = $value; - return $this; - } + /** + * Set right-to-left + * + * @param boolean $value Right-to-left true/false + * @return PHPExcel_Worksheet + */ + public function setRightToLeft($value = false) { + $this->_rightToLeft = $value; + return $this; + } - /** - * Fill worksheet from values in array - * - * @param array $source Source array - * @param mixed $nullValue Value in source array that stands for blank cell - * @param string $startCell Insert array starting from this cell address as the top left coordinate - * @param boolean $strictNullComparison Apply strict comparison when testing for null values in the array - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet - */ - public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false) { - if (is_array($source)) { - // Convert a 1-D array to 2-D (for ease of looping) - if (!is_array(end($source))) { - $source = array($source); - } - - // start coordinate - list ($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($startCell); - - // Loop through $source - foreach ($source as $rowData) { - $currentColumn = $startColumn; - foreach($rowData as $cellValue) { - if ($strictNullComparison) { - if ($cellValue !== $nullValue) { - // Set cell value - $this->getCell($currentColumn . $startRow)->setValue($cellValue); - } - } else { - if ($cellValue != $nullValue) { - // Set cell value - $this->getCell($currentColumn . $startRow)->setValue($cellValue); - } - } - ++$currentColumn; - } - ++$startRow; - } - } else { - throw new PHPExcel_Exception("Parameter \$source should be an array."); - } - return $this; - } + /** + * Fill worksheet from values in array + * + * @param array $source Source array + * @param mixed $nullValue Value in source array that stands for blank cell + * @param string $startCell Insert array starting from this cell address as the top left coordinate + * @param boolean $strictNullComparison Apply strict comparison when testing for null values in the array + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false) { + if (is_array($source)) { + // Convert a 1-D array to 2-D (for ease of looping) + if (!is_array(end($source))) { + $source = array($source); + } + + // start coordinate + list ($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($startCell); + + // Loop through $source + foreach ($source as $rowData) { + $currentColumn = $startColumn; + foreach($rowData as $cellValue) { + if ($strictNullComparison) { + if ($cellValue !== $nullValue) { + // Set cell value + $this->getCell($currentColumn . $startRow)->setValue($cellValue); + } + } else { + if ($cellValue != $nullValue) { + // Set cell value + $this->getCell($currentColumn . $startRow)->setValue($cellValue); + } + } + ++$currentColumn; + } + ++$startRow; + } + } else { + throw new PHPExcel_Exception("Parameter \$source should be an array."); + } + return $this; + } - /** - * Create array from a range of cells - * - * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") - * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist - * @param boolean $calculateFormulas Should formulas be calculated? - * @param boolean $formatData Should formatting be applied to cell values? - * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero - * True - Return rows and columns indexed by their actual row and column IDs - * @return array - */ + /** + * Create array from a range of cells + * + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist + * @param boolean $calculateFormulas Should formulas be calculated? + * @param boolean $formatData Should formatting be applied to cell values? + * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero + * True - Return rows and columns indexed by their actual row and column IDs + * @return array + */ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { - // Returnvalue - $returnValue = array(); - // Identify the range that we need to extract from the worksheet - list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange); - $minCol = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] -1); - $minRow = $rangeStart[1]; - $maxCol = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] -1); - $maxRow = $rangeEnd[1]; - - $maxCol++; - // Loop through rows - $r = -1; - for ($row = $minRow; $row <= $maxRow; ++$row) { - $rRef = ($returnCellRef) ? $row : ++$r; - $c = -1; - // Loop through columns in the current row - for ($col = $minCol; $col != $maxCol; ++$col) { - $cRef = ($returnCellRef) ? $col : ++$c; - // Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen - // so we test and retrieve directly against _cellCollection - if ($this->_cellCollection->isDataSet($col.$row)) { - // Cell exists - $cell = $this->_cellCollection->getCacheData($col.$row); - if ($cell->getValue() !== null) { - if ($cell->getValue() instanceof PHPExcel_RichText) { - $returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText(); - } else { - if ($calculateFormulas) { - $returnValue[$rRef][$cRef] = $cell->getCalculatedValue(); - } else { - $returnValue[$rRef][$cRef] = $cell->getValue(); - } - } - - if ($formatData) { - $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); + // Returnvalue + $returnValue = array(); + // Identify the range that we need to extract from the worksheet + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange); + $minCol = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] -1); + $minRow = $rangeStart[1]; + $maxCol = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] -1); + $maxRow = $rangeEnd[1]; + + $maxCol++; + // Loop through rows + $r = -1; + for ($row = $minRow; $row <= $maxRow; ++$row) { + $rRef = ($returnCellRef) ? $row : ++$r; + $c = -1; + // Loop through columns in the current row + for ($col = $minCol; $col != $maxCol; ++$col) { + $cRef = ($returnCellRef) ? $col : ++$c; + // Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen + // so we test and retrieve directly against _cellCollection + if ($this->_cellCollection->isDataSet($col.$row)) { + // Cell exists + $cell = $this->_cellCollection->getCacheData($col.$row); + if ($cell->getValue() !== null) { + if ($cell->getValue() instanceof PHPExcel_RichText) { + $returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText(); + } else { + if ($calculateFormulas) { + $returnValue[$rRef][$cRef] = $cell->getCalculatedValue(); + } else { + $returnValue[$rRef][$cRef] = $cell->getValue(); + } + } + + if ($formatData) { + $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString( $returnValue[$rRef][$cRef], $style->getNumberFormat()->getFormatCode() ); - } - } else { - // Cell holds a NULL - $returnValue[$rRef][$cRef] = $nullValue; - } - } else { - // Cell doesn't exist - $returnValue[$rRef][$cRef] = $nullValue; - } - } - } - - // Return - return $returnValue; - } + } + } else { + // Cell holds a NULL + $returnValue[$rRef][$cRef] = $nullValue; + } + } else { + // Cell doesn't exist + $returnValue[$rRef][$cRef] = $nullValue; + } + } + } + + // Return + return $returnValue; + } - /** - * Create array from a range of cells - * - * @param string $pNamedRange Name of the Named Range - * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist - * @param boolean $calculateFormulas Should formulas be calculated? - * @param boolean $formatData Should formatting be applied to cell values? - * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero - * True - Return rows and columns indexed by their actual row and column IDs - * @return array - * @throws PHPExcel_Exception - */ + /** + * Create array from a range of cells + * + * @param string $pNamedRange Name of the Named Range + * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist + * @param boolean $calculateFormulas Should formulas be calculated? + * @param boolean $formatData Should formatting be applied to cell values? + * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero + * True - Return rows and columns indexed by their actual row and column IDs + * @return array + * @throws PHPExcel_Exception + */ public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { - $namedRange = PHPExcel_NamedRange::resolveRange($pNamedRange, $this); - if ($namedRange !== NULL) { - $pWorkSheet = $namedRange->getWorksheet(); - $pCellRange = $namedRange->getRange(); + $namedRange = PHPExcel_NamedRange::resolveRange($pNamedRange, $this); + if ($namedRange !== NULL) { + $pWorkSheet = $namedRange->getWorksheet(); + $pCellRange = $namedRange->getRange(); return $pWorkSheet->rangeToArray( $pCellRange, $nullValue, $calculateFormulas, $formatData, $returnCellRef); - } + } - throw new PHPExcel_Exception('Named Range '.$pNamedRange.' does not exist.'); - } + throw new PHPExcel_Exception('Named Range '.$pNamedRange.' does not exist.'); + } - /** - * Create array from worksheet - * - * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist - * @param boolean $calculateFormulas Should formulas be calculated? - * @param boolean $formatData Should formatting be applied to cell values? - * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero - * True - Return rows and columns indexed by their actual row and column IDs - * @return array - */ + /** + * Create array from worksheet + * + * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist + * @param boolean $calculateFormulas Should formulas be calculated? + * @param boolean $formatData Should formatting be applied to cell values? + * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero + * True - Return rows and columns indexed by their actual row and column IDs + * @return array + */ public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { - // Garbage collect... - $this->garbageCollect(); + // Garbage collect... + $this->garbageCollect(); - // Identify the range that we need to extract from the worksheet - $maxCol = $this->getHighestColumn(); - $maxRow = $this->getHighestRow(); - // Return + // Identify the range that we need to extract from the worksheet + $maxCol = $this->getHighestColumn(); + $maxRow = $this->getHighestRow(); + // Return return $this->rangeToArray( 'A1:'.$maxCol.$maxRow, $nullValue, $calculateFormulas, $formatData, $returnCellRef); - } + } - /** - * Get row iterator - * + /** + * Get row iterator + * * @param integer $startRow The row number at which to start iterating - * @return PHPExcel_Worksheet_RowIterator - */ + * @return PHPExcel_Worksheet_RowIterator + */ public function getRowIterator($startRow = 1) { - return new PHPExcel_Worksheet_RowIterator($this,$startRow); - } + return new PHPExcel_Worksheet_RowIterator($this,$startRow); + } - /** - * Run PHPExcel garabage collector. - * - * @return PHPExcel_Worksheet - */ + /** + * Run PHPExcel garabage collector. + * + * @return PHPExcel_Worksheet + */ public function garbageCollect() { - // Flush cache - $this->_cellCollection->getCacheData('A1'); - // Build a reference table from images -// $imageCoordinates = array(); -// $iterator = $this->getDrawingCollection()->getIterator(); -// while ($iterator->valid()) { -// $imageCoordinates[$iterator->current()->getCoordinates()] = true; + // Flush cache + $this->_cellCollection->getCacheData('A1'); + // Build a reference table from images +// $imageCoordinates = array(); +// $iterator = $this->getDrawingCollection()->getIterator(); +// while ($iterator->valid()) { +// $imageCoordinates[$iterator->current()->getCoordinates()] = true; // -// $iterator->next(); -// } +// $iterator->next(); +// } // - // Lookup highest column and highest row if cells are cleaned - $colRow = $this->_cellCollection->getHighestRowAndColumn(); - $highestRow = $colRow['row']; - $highestColumn = PHPExcel_Cell::columnIndexFromString($colRow['column']); - - // Loop through column dimensions - foreach ($this->_columnDimensions as $dimension) { - $highestColumn = max($highestColumn,PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex())); - } - - // Loop through row dimensions - foreach ($this->_rowDimensions as $dimension) { - $highestRow = max($highestRow,$dimension->getRowIndex()); - } - - // Cache values - if ($highestColumn < 0) { - $this->_cachedHighestColumn = 'A'; - } else { - $this->_cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn); - } - $this->_cachedHighestRow = $highestRow; - - // Return - return $this; - } + // Lookup highest column and highest row if cells are cleaned + $colRow = $this->_cellCollection->getHighestRowAndColumn(); + $highestRow = $colRow['row']; + $highestColumn = PHPExcel_Cell::columnIndexFromString($colRow['column']); + + // Loop through column dimensions + foreach ($this->_columnDimensions as $dimension) { + $highestColumn = max($highestColumn,PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex())); + } + + // Loop through row dimensions + foreach ($this->_rowDimensions as $dimension) { + $highestRow = max($highestRow,$dimension->getRowIndex()); + } + + // Cache values + if ($highestColumn < 0) { + $this->_cachedHighestColumn = 'A'; + } else { + $this->_cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn); + } + $this->_cachedHighestRow = $highestRow; + + // Return + return $this; + } - /** - * Get hash code - * - * @return string Hash code - */ + /** + * Get hash code + * + * @return string Hash code + */ public function getHashCode() { - if ($this->_dirty) { - $this->_hash = md5( $this->_title . - $this->_autoFilter . - ($this->_protection->isProtectionEnabled() ? 't' : 'f') . - __CLASS__ - ); - $this->_dirty = false; - } - return $this->_hash; - } + if ($this->_dirty) { + $this->_hash = md5( $this->_title . + $this->_autoFilter . + ($this->_protection->isProtectionEnabled() ? 't' : 'f') . + __CLASS__ + ); + $this->_dirty = false; + } + return $this->_hash; + } - /** - * Extract worksheet title from range. - * - * Example: extractSheetTitle("testSheet!A1") ==> 'A1' - * Example: extractSheetTitle("'testSheet 1'!A1", true) ==> array('testSheet 1', 'A1'); - * - * @param string $pRange Range to extract title from - * @param bool $returnRange Return range? (see example) - * @return mixed - */ + /** + * Extract worksheet title from range. + * + * Example: extractSheetTitle("testSheet!A1") ==> 'A1' + * Example: extractSheetTitle("'testSheet 1'!A1", true) ==> array('testSheet 1', 'A1'); + * + * @param string $pRange Range to extract title from + * @param bool $returnRange Return range? (see example) + * @return mixed + */ public static function extractSheetTitle($pRange, $returnRange = false) { - // Sheet title included? - if (($sep = strpos($pRange, '!')) === false) { - return ''; - } - - if ($returnRange) { - return array( trim(substr($pRange, 0, $sep),"'"), - substr($pRange, $sep + 1) - ); - } - - return substr($pRange, $sep + 1); - } - - /** - * Get hyperlink - * - * @param string $pCellCoordinate Cell coordinate to get hyperlink for - */ - public function getHyperlink($pCellCoordinate = 'A1') - { - // return hyperlink if we already have one - if (isset($this->_hyperlinkCollection[$pCellCoordinate])) { - return $this->_hyperlinkCollection[$pCellCoordinate]; - } - - // else create hyperlink - $this->_hyperlinkCollection[$pCellCoordinate] = new PHPExcel_Cell_Hyperlink(); - return $this->_hyperlinkCollection[$pCellCoordinate]; - } + // Sheet title included? + if (($sep = strpos($pRange, '!')) === false) { + return ''; + } + + if ($returnRange) { + return array( trim(substr($pRange, 0, $sep),"'"), + substr($pRange, $sep + 1) + ); + } + + return substr($pRange, $sep + 1); + } - /** - * Set hyperlnk - * - * @param string $pCellCoordinate Cell coordinate to insert hyperlink - * @param PHPExcel_Cell_Hyperlink $pHyperlink - * @return PHPExcel_Worksheet - */ - public function setHyperlink($pCellCoordinate = 'A1', PHPExcel_Cell_Hyperlink $pHyperlink = null) - { - if ($pHyperlink === null) { - unset($this->_hyperlinkCollection[$pCellCoordinate]); - } else { - $this->_hyperlinkCollection[$pCellCoordinate] = $pHyperlink; - } - return $this; - } + /** + * Get hyperlink + * + * @param string $pCellCoordinate Cell coordinate to get hyperlink for + */ + public function getHyperlink($pCellCoordinate = 'A1') + { + // return hyperlink if we already have one + if (isset($this->_hyperlinkCollection[$pCellCoordinate])) { + return $this->_hyperlinkCollection[$pCellCoordinate]; + } + + // else create hyperlink + $this->_hyperlinkCollection[$pCellCoordinate] = new PHPExcel_Cell_Hyperlink(); + return $this->_hyperlinkCollection[$pCellCoordinate]; + } - /** - * Hyperlink at a specific coordinate exists? - * - * @param string $pCoordinate - * @return boolean - */ - public function hyperlinkExists($pCoordinate = 'A1') - { - return isset($this->_hyperlinkCollection[$pCoordinate]); - } + /** + * Set hyperlnk + * + * @param string $pCellCoordinate Cell coordinate to insert hyperlink + * @param PHPExcel_Cell_Hyperlink $pHyperlink + * @return PHPExcel_Worksheet + */ + public function setHyperlink($pCellCoordinate = 'A1', PHPExcel_Cell_Hyperlink $pHyperlink = null) + { + if ($pHyperlink === null) { + unset($this->_hyperlinkCollection[$pCellCoordinate]); + } else { + $this->_hyperlinkCollection[$pCellCoordinate] = $pHyperlink; + } + return $this; + } - /** - * Get collection of hyperlinks - * - * @return PHPExcel_Cell_Hyperlink[] - */ - public function getHyperlinkCollection() - { - return $this->_hyperlinkCollection; - } + /** + * Hyperlink at a specific coordinate exists? + * + * @param string $pCoordinate + * @return boolean + */ + public function hyperlinkExists($pCoordinate = 'A1') + { + return isset($this->_hyperlinkCollection[$pCoordinate]); + } - /** - * Get data validation - * - * @param string $pCellCoordinate Cell coordinate to get data validation for - */ - public function getDataValidation($pCellCoordinate = 'A1') - { - // return data validation if we already have one - if (isset($this->_dataValidationCollection[$pCellCoordinate])) { - return $this->_dataValidationCollection[$pCellCoordinate]; - } + /** + * Get collection of hyperlinks + * + * @return PHPExcel_Cell_Hyperlink[] + */ + public function getHyperlinkCollection() + { + return $this->_hyperlinkCollection; + } - // else create data validation - $this->_dataValidationCollection[$pCellCoordinate] = new PHPExcel_Cell_DataValidation(); - return $this->_dataValidationCollection[$pCellCoordinate]; - } + /** + * Get data validation + * + * @param string $pCellCoordinate Cell coordinate to get data validation for + */ + public function getDataValidation($pCellCoordinate = 'A1') + { + // return data validation if we already have one + if (isset($this->_dataValidationCollection[$pCellCoordinate])) { + return $this->_dataValidationCollection[$pCellCoordinate]; + } + + // else create data validation + $this->_dataValidationCollection[$pCellCoordinate] = new PHPExcel_Cell_DataValidation(); + return $this->_dataValidationCollection[$pCellCoordinate]; + } - /** - * Set data validation - * - * @param string $pCellCoordinate Cell coordinate to insert data validation - * @param PHPExcel_Cell_DataValidation $pDataValidation - * @return PHPExcel_Worksheet - */ - public function setDataValidation($pCellCoordinate = 'A1', PHPExcel_Cell_DataValidation $pDataValidation = null) - { - if ($pDataValidation === null) { - unset($this->_dataValidationCollection[$pCellCoordinate]); - } else { - $this->_dataValidationCollection[$pCellCoordinate] = $pDataValidation; - } - return $this; - } + /** + * Set data validation + * + * @param string $pCellCoordinate Cell coordinate to insert data validation + * @param PHPExcel_Cell_DataValidation $pDataValidation + * @return PHPExcel_Worksheet + */ + public function setDataValidation($pCellCoordinate = 'A1', PHPExcel_Cell_DataValidation $pDataValidation = null) + { + if ($pDataValidation === null) { + unset($this->_dataValidationCollection[$pCellCoordinate]); + } else { + $this->_dataValidationCollection[$pCellCoordinate] = $pDataValidation; + } + return $this; + } - /** - * Data validation at a specific coordinate exists? - * - * @param string $pCoordinate - * @return boolean - */ - public function dataValidationExists($pCoordinate = 'A1') - { - return isset($this->_dataValidationCollection[$pCoordinate]); - } + /** + * Data validation at a specific coordinate exists? + * + * @param string $pCoordinate + * @return boolean + */ + public function dataValidationExists($pCoordinate = 'A1') + { + return isset($this->_dataValidationCollection[$pCoordinate]); + } - /** - * Get collection of data validations - * - * @return PHPExcel_Cell_DataValidation[] - */ - public function getDataValidationCollection() - { - return $this->_dataValidationCollection; - } + /** + * Get collection of data validations + * + * @return PHPExcel_Cell_DataValidation[] + */ + public function getDataValidationCollection() + { + return $this->_dataValidationCollection; + } - /** - * Accepts a range, returning it as a range that falls within the current highest row and column of the worksheet - * - * @param string $range - * @return string Adjusted range value - */ + /** + * Accepts a range, returning it as a range that falls within the current highest row and column of the worksheet + * + * @param string $range + * @return string Adjusted range value + */ public function shrinkRangeToFit($range) { - $maxCol = $this->getHighestColumn(); - $maxRow = $this->getHighestRow(); - $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol); - - $rangeBlocks = explode(' ',$range); - foreach ($rangeBlocks as &$rangeSet) { - $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($rangeSet); - - if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) { $rangeBoundaries[0][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); } - if ($rangeBoundaries[0][1] > $maxRow) { $rangeBoundaries[0][1] = $maxRow; } - if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) { $rangeBoundaries[1][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); } - if ($rangeBoundaries[1][1] > $maxRow) { $rangeBoundaries[1][1] = $maxRow; } - $rangeSet = $rangeBoundaries[0][0].$rangeBoundaries[0][1].':'.$rangeBoundaries[1][0].$rangeBoundaries[1][1]; - } - unset($rangeSet); - $stRange = implode(' ',$rangeBlocks); + $maxCol = $this->getHighestColumn(); + $maxRow = $this->getHighestRow(); + $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol); + + $rangeBlocks = explode(' ',$range); + foreach ($rangeBlocks as &$rangeSet) { + $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($rangeSet); + + if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) { $rangeBoundaries[0][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); } + if ($rangeBoundaries[0][1] > $maxRow) { $rangeBoundaries[0][1] = $maxRow; } + if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) { $rangeBoundaries[1][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); } + if ($rangeBoundaries[1][1] > $maxRow) { $rangeBoundaries[1][1] = $maxRow; } + $rangeSet = $rangeBoundaries[0][0].$rangeBoundaries[0][1].':'.$rangeBoundaries[1][0].$rangeBoundaries[1][1]; + } + unset($rangeSet); + $stRange = implode(' ',$rangeBlocks); + + return $stRange; + } - return $stRange; - } + /** + * Get tab color + * + * @return PHPExcel_Style_Color + */ + public function getTabColor() + { + if ($this->_tabColor === NULL) + $this->_tabColor = new PHPExcel_Style_Color(); - /** - * Get tab color - * - * @return PHPExcel_Style_Color - */ - public function getTabColor() - { - if ($this->_tabColor === NULL) - $this->_tabColor = new PHPExcel_Style_Color(); - - return $this->_tabColor; - } + return $this->_tabColor; + } - /** - * Reset tab color - * - * @return PHPExcel_Worksheet - */ - public function resetTabColor() - { - $this->_tabColor = null; - unset($this->_tabColor); - - return $this; - } + /** + * Reset tab color + * + * @return PHPExcel_Worksheet + */ + public function resetTabColor() + { + $this->_tabColor = null; + unset($this->_tabColor); - /** - * Tab color set? - * - * @return boolean - */ - public function isTabColorSet() - { - return ($this->_tabColor !== NULL); - } + return $this; + } + + /** + * Tab color set? + * + * @return boolean + */ + public function isTabColorSet() + { + return ($this->_tabColor !== NULL); + } - /** - * Copy worksheet (!= clone!) - * - * @return PHPExcel_Worksheet - */ + /** + * Copy worksheet (!= clone!) + * + * @return PHPExcel_Worksheet + */ public function copy() { - $copied = clone $this; + $copied = clone $this; - return $copied; - } + return $copied; + } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ public function __clone() { - foreach ($this as $key => $val) { - if ($key == '_parent') { - continue; - } - - if (is_object($val) || (is_array($val))) { - if ($key == '_cellCollection') { - $newCollection = clone $this->_cellCollection; - $newCollection->copyCellCollection($this); - $this->_cellCollection = $newCollection; - } elseif ($key == '_drawingCollection') { - $newCollection = clone $this->_drawingCollection; - $this->_drawingCollection = $newCollection; - } elseif (($key == '_autoFilter') && ($this->_autoFilter instanceof PHPExcel_Worksheet_AutoFilter)) { - $newAutoFilter = clone $this->_autoFilter; - $this->_autoFilter = $newAutoFilter; - $this->_autoFilter->setParent($this); - } else { - $this->{$key} = unserialize(serialize($val)); - } - } - } - } + foreach ($this as $key => $val) { + if ($key == '_parent') { + continue; + } + + if (is_object($val) || (is_array($val))) { + if ($key == '_cellCollection') { + $newCollection = clone $this->_cellCollection; + $newCollection->copyCellCollection($this); + $this->_cellCollection = $newCollection; + } elseif ($key == '_drawingCollection') { + $newCollection = clone $this->_drawingCollection; + $this->_drawingCollection = $newCollection; + } elseif (($key == '_autoFilter') && ($this->_autoFilter instanceof PHPExcel_Worksheet_AutoFilter)) { + $newAutoFilter = clone $this->_autoFilter; + $this->_autoFilter = $newAutoFilter; + $this->_autoFilter->setParent($this); + } else { + $this->{$key} = unserialize(serialize($val)); + } + } + } + } } diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php index 3979d6094..3563cb23c 100644 --- a/Classes/PHPExcel/Writer/CSV.php +++ b/Classes/PHPExcel/Writer/CSV.php @@ -102,8 +102,8 @@ public function save($pFilename = null) { // Fetch sheet $sheet = $this->_phpExcel->getSheet($this->_sheetIndex); - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog; - PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = FALSE; + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); @@ -139,7 +139,7 @@ public function save($pFilename = null) { fclose($fileHandle); PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); - PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = $saveDebugLog; + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); } /** diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index 951b33973..f09bb2715 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -179,8 +179,8 @@ public function save($pFilename = null) } } - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->writeDebugLog; - PHPExcel_Calculation::getInstance($this->_spreadSheet)->writeDebugLog = false; + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(FALSE); $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); @@ -341,7 +341,7 @@ public function save($pFilename = null) } PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); - PHPExcel_Calculation::getInstance($this->_spreadSheet)->writeDebugLog = $saveDebugLog; + PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); // Close file if ($objZip->close() === false) { diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index 977f172de..cb1437d32 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -1074,12 +1074,9 @@ private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce $objWriter->writeAttribute('t', $mappedType); break; case 'f': // Formula - $calculatedValue = null; - if ($this->getParentWriter()->getPreCalculateFormulas()) { - $calculatedValue = $pCell->getCalculatedValue(); - } else { - $calculatedValue = $cellValue; - } + $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ? + $pCell->getCalculatedValue() : + $cellValue; if (is_string($calculatedValue)) { $objWriter->writeAttribute('t', 'str'); } @@ -1125,7 +1122,7 @@ private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce } if ($this->getParentWriter()->getOffice2003Compatibility() === false) { if ($this->getParentWriter()->getPreCalculateFormulas()) { - $calculatedValue = $pCell->getCalculatedValue(); +// $calculatedValue = $pCell->getCalculatedValue(); if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') { $objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue)); } else { diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index daa1d0fe2..a63c1d1c3 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -120,13 +120,13 @@ public function save($pFilename = null) { // garbage collect $this->_phpExcel->garbageCollect(); - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog; - PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = false; + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // initialize colors array - $this->_colors = array(); + $this->_colors = array(); // Initialise workbook writer $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel, @@ -226,7 +226,7 @@ public function save($pFilename = null) { $res = $root->save($pFilename); PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); - PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = $saveDebugLog; + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); } /** diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 5aca92e9c..49c7b6c31 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -152,8 +152,8 @@ public function save($pFilename = null) { // garbage collect $this->_phpExcel->garbageCollect(); - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog; - PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = false; + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); @@ -184,7 +184,7 @@ public function save($pFilename = null) { fclose($fileHandle); PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); - PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = $saveDebugLog; + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); } /** From 6b6f00c2af0b90baef450e920f9999a16625b5d2 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 15 Feb 2013 16:14:15 +0000 Subject: [PATCH 008/467] Changelog entry for refactored calculation engine --- changelog.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 552cb9e43..193640481 100644 --- a/changelog.txt +++ b/changelog.txt @@ -23,7 +23,7 @@ ************************************************************************************** -Fixed in develop branch: +Fixed in develop branch for release v1.7.9: - Feature: (MBaker) Include charts option for HTML Writer - Feature: (MBaker) Added composer file - Bugfix: (Asker) Work item 18777 - Error in PHPEXCEL/Calculation.php script on line 2976 (stack pop check) @@ -41,6 +41,8 @@ Fixed in develop branch: - General: (cfhay) Work item 18958 - Memory and Speed improvements in PHPExcel_Reader_Excel5 - General: (MBaker) Work item GH-78 - Modify listWorksheetNames() and listWorksheetInfo to use XMLReader with streamed XML rather than SimpleXML - General: (dbonsch) Restructuring of PHPExcel Exceptions +- General: (MBaker) Work items 16926 and 15145 - Refactor Calculation Engine from singleton to a Multiton + Ensures that calculation cache is maintained independently for different workbooks - Bugfix: (techhead) Work item GH-70 - Fixed formula/formatting bug when removing rows - Bugfix: (alexgann) Work item GH-63 - Fix to cellExists for non-existent namedRanges - Bugfix: (MBaker) Work item 18844 - cache_in_memory_gzip "eats" last worksheet line, cache_in_memory doesn't From be5551d29eecda8652d3827e24510a246b2d9e7b Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 16 Feb 2013 10:59:19 +0000 Subject: [PATCH 009/467] Refactor the cyclic reference stack as an object so that we can inject it into the logger constructor rather than having to pass it at every call --- .../CalcEngine/CyclicReferenceStack.php | 58 +++++++++++ Classes/PHPExcel/CalcEngine/Logger.php | 34 ++++--- Classes/PHPExcel/Calculation.php | 98 ++++++++++--------- 3 files changed, 131 insertions(+), 59 deletions(-) create mode 100644 Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php diff --git a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php new file mode 100644 index 000000000..e64b46867 --- /dev/null +++ b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php @@ -0,0 +1,58 @@ +_stack); + } + + public function push($value) { + $this->_stack[] = $value; + } // function push() + + public function pop() { + return array_pop($this->_stack); + } // function pop() + + public function onStack($value) { + return in_array($value,$this->_stack); + } + + public function clear() { + $this->_stack = array(); + } // function push() + + public function showStack() { + return $this->_stack; + } + +} // class PHPExcel_CalcEngine_CyclicReferenceStack diff --git a/Classes/PHPExcel/CalcEngine/Logger.php b/Classes/PHPExcel/CalcEngine/Logger.php index 2cb893efa..250f841d9 100644 --- a/Classes/PHPExcel/CalcEngine/Logger.php +++ b/Classes/PHPExcel/CalcEngine/Logger.php @@ -55,7 +55,6 @@ class PHPExcel_CalcEngine_Logger { */ private $_echoDebugLog = FALSE; - /** * The debug log generated by the calculation engine * @@ -64,6 +63,18 @@ class PHPExcel_CalcEngine_Logger { */ private $_debugLog = array(); + /** + * The calculation engine cell reference stack + * + * @var PHPExcel_CalcEngine_CyclicReferenceStack + * + */ + private $_cellStack; + + + public function __construct(PHPExcel_CalcEngine_CyclicReferenceStack $stack) { + $this->_cellStack = $stack; + } public function setWriteDebugLog($pValue = FALSE) { $this->_writeDebugLog = $pValue; @@ -81,21 +92,23 @@ public function getEchoDebugLog() { return $this->_echoDebugLog; } - public function writeDebugLog(array $cellReferencePath) { + public function writeDebugLog() { // Only write the debug log if logging is enabled if ($this->_writeDebugLog) { - $message = func_get_args(); - array_shift($message); - $cellReference = implode(' -> ', $cellReferencePath); - $message = implode($message); + $message = implode(func_get_args()); + $cellReference = implode(' -> ', $this->_cellStack->showStack()); if ($this->_echoDebugLog) { - echo $cellReference, (count($cellReferencePath) > 0 ? ' => ' : ''), $message,PHP_EOL; + echo $cellReference, + ($this->_cellStack->count() > 0 ? ' => ' : ''), + $message, + PHP_EOL; } - $this->_debugLog[] = $cellReference . (count($cellReferencePath) > 0 ? ' => ' : '') . $message; + $this->_debugLog[] = $cellReference . + ($this->_cellStack->count() > 0 ? ' => ' : '') . + $message; } } // function _writeDebug() - public function clearLog() { $this->_debugLog = array(); } // function flushLogger() @@ -104,6 +117,5 @@ public function getLog() { return $this->_debugLog; } // function flushLogger() - -} // class PHPExcel_Calculation_Logger +} // class PHPExcel_CalcEngine_Logger diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index e109865c1..c98e50cb7 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -192,7 +192,7 @@ class PHPExcel_Calculation { * @var array of string * */ - private $cyclicReferenceStack = array(); + private $_cyclicReferenceStack; private $_cyclicFormulaCount = 0; private $_cyclicFormulaCell = ''; @@ -1676,7 +1676,8 @@ private function __construct(PHPExcel $workbook = NULL) { } $this->_workbook = $workbook; - $this->_debugLog = new PHPExcel_CalcEngine_Logger(); + $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); + $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack); } // function __construct() @@ -2158,7 +2159,7 @@ public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE // Initialise the logging settings if requested $this->formulaError = null; $this->_debugLog->clearLog(); - $this->cyclicReferenceStack = array(); + $this->_cyclicReferenceStack->clear(); $this->_cyclicFormulaCount = 1; self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; @@ -2236,7 +2237,7 @@ public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = // Initialise the logging settings $this->formulaError = null; $this->_debugLog->clearLog(); - $this->cyclicReferenceStack = array(); + $this->_cyclicReferenceStack->clear(); // Disable calculation cacheing because it only applies to cell calculations, not straight formulae // But don't actually flush any cache @@ -2260,10 +2261,10 @@ public function getValueFromCache($worksheetName, $cellID, &$cellValue) { // Is calculation cacheing enabled? // Is the value present in calculation cache? //echo 'Test cache for ',$worksheetName,'!',$cellID,PHP_EOL; - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Testing cache value for cell ', $worksheetName, '!', $cellID); + $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($this->cyclicReferenceStack, 'Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache'); + $this->_debugLog->writeDebugLog('Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache'); // Return the cached result $cellValue = $this->_calculationCache[$worksheetName][$cellID]; return TRUE; @@ -2303,7 +2304,7 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC return $cellValue; } - if (($wsTitle{0} !== "\x00") && (in_array($wsTitle.'!'.$cellID,$this->cyclicReferenceStack))) { + if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsTitle.'!'.$cellID))) { if ($this->cyclicFormulaCount <= 0) { return $this->_raiseFormulaError('Cyclic Reference in Formula'); } elseif (($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) && @@ -2321,10 +2322,11 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC } } } - $this->cyclicReferenceStack[] = $wsTitle.'!'.$cellID; + // Parse the formula onto the token stack and calculate the value + $this->_cyclicReferenceStack->push($wsTitle.'!'.$cellID); $cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell); - array_pop($this->cyclicReferenceStack); + $this->_cyclicReferenceStack->pop(); // Save to calculation cache if ($cellID !== NULL) { @@ -3027,9 +3029,9 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // Log what we're doing if ($token == ':') { - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); + $this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); } else { - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); + $this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); } // Process the operation in the appropriate manner @@ -3130,13 +3132,13 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $matrixResult = $matrix->concat($operand2); $result = $matrixResult->getArray(); } catch (PHPExcel_Exception $ex) { - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage()); + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); $result = '#VALUE!'; } } else { $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"'; } - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); $stack->push('Value',$result); break; case '|' : // Intersect @@ -3150,7 +3152,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } } $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); $stack->push('Value',$cellIntersect,$cellRef); break; } @@ -3162,11 +3164,11 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $arg = $arg['value']; if ($token === '~') { // echo 'Token is a negation operator
'; - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Negation of ', $this->_showValue($arg)); + $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg)); $multiplier = -1; } else { // echo 'Token is a percentile operator
'; - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Percentile of ', $this->_showValue($arg)); + $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg)); $multiplier = 0.01; } if (is_array($arg)) { @@ -3176,10 +3178,10 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $matrixResult = $matrix1->arrayTimesEquals($multiplier); $result = $matrixResult->getArray(); } catch (PHPExcel_Exception $ex) { - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage()); + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); $result = '#VALUE!'; } - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); $stack->push('Value',$result); } else { $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack); @@ -3203,23 +3205,23 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } $matches[2] = trim($matches[2],"\"'"); // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
'; - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== NULL) { $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); // $cellRef = $matches[2].'!'.$cellRef; } else { // echo '$cellRef='.$cellRef.' in current worksheet
'; - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell Range ', $cellRef, ' in current worksheet'); + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet'); if ($pCellParent !== NULL) { $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); } } } else { @@ -3236,7 +3238,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel return $this->_raiseFormulaError('Unable to access External Workbook'); } // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
'; - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== NULL) { if ($this->_workbook->getSheetByName($matches[2])->cellExists($cellRef)) { $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); @@ -3247,18 +3249,18 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); // $cellRef = $matches[2].'!'.$cellRef; } else { // echo '$cellRef='.$cellRef.' in current worksheet
'; - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell ', $cellRef, ' in current worksheet'); + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet'); if ($pCellParent->isDataSet($cellRef)) { $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); $pCell->attach($pCellParent); } else { $cellValue = NULL; } - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); } } } @@ -3271,7 +3273,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $argCount = $stack->pop(); $argCount = $argCount['value']; if ($functionName != 'MKMATRIX') { - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); + $this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); } if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function if (isset(self::$_PHPExcelFunctions[$functionName])) { @@ -3316,28 +3318,28 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel if ($functionName != 'MKMATRIX') { if ($this->_debugLog->getWriteDebugLog()) { krsort($argArrayVals); - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); + $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); } } // Process each argument in turn, building the return value as an array // if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) { // $operand1 = $args[1]; -// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Argument is a matrix: ', $this->_showValue($operand1)); +// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1)); // $result = array(); // $row = 0; // foreach($operand1 as $args) { // if (is_array($args)) { // foreach($args as $arg) { -// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); // $r = call_user_func_array($functionCall,$arg); -// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); // $result[$row][] = $r; // } // ++$row; // } else { -// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); // $r = call_user_func_array($functionCall,$args); -// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); // $result[] = $r; // } // } @@ -3357,7 +3359,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } // } if ($functionName != 'MKMATRIX') { - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); } $stack->push('Value',self::_wrapResult($result)); } @@ -3368,7 +3370,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $excelConstant = strtoupper($token); // echo 'Token is a PHPExcel constant: '.$excelConstant.'
'; $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]); - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); + $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { // echo 'Token is a number, boolean, string, null or an Excel error
'; $stack->push('Value',$token); @@ -3377,10 +3379,10 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // echo 'Token is a named range
'; $namedRange = $matches[6]; // echo 'Named Range is '.$namedRange.'
'; - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Named Range ', $namedRange); + $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange); $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE); $pCell->attach($pCellParent); - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); $stack->push('Named Range',$cellValue,$namedRange); } else { return $this->_raiseFormulaError("undefined variable '$token'"); @@ -3410,12 +3412,12 @@ private function _validateBinaryOperand($cellID, &$operand, &$stack) { // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations if ($operand > '' && $operand{0} == '#') { $stack->push('Value', $operand); - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($operand)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand)); return FALSE; } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations $stack->push('Value', '#VALUE!'); - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); + $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); return FALSE; } } @@ -3432,14 +3434,14 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 $result = array(); if ((is_array($operand1)) && (!is_array($operand2))) { foreach($operand1 as $x => $operandData) { - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack); $r = $stack->pop(); $result[$x] = $r['value']; } } elseif ((!is_array($operand1)) && (is_array($operand2))) { foreach($operand2 as $x => $operandData) { - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack); $r = $stack->pop(); $result[$x] = $r['value']; @@ -3447,14 +3449,14 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 } else { if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } foreach($operand1 as $x => $operandData) { - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); $r = $stack->pop(); $result[$x] = $r['value']; } } // Log the result details - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Comparison Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack $stack->push('Array',$result); return TRUE; @@ -3493,7 +3495,7 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 } // Log the result details - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack $stack->push('Value',$result); return TRUE; @@ -3531,7 +3533,7 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope $matrixResult = $matrix->$matrixFunction($operand2); $result = $matrixResult->getArray(); } catch (PHPExcel_Exception $ex) { - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage()); + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); $result = '#VALUE!'; } } else { @@ -3558,7 +3560,7 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope if ($operand2 == 0) { // Trap for Divide by Zero error $stack->push('Value','#DIV/0!'); - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); return FALSE; } else { $result = $operand1/$operand2; @@ -3573,7 +3575,7 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope } // Log the result details - $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack $stack->push('Value',$result); return TRUE; @@ -3583,7 +3585,7 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope // trigger an error, but nicely, if need be protected function _raiseFormulaError($errorMessage) { $this->formulaError = $errorMessage; - $this->cyclicReferenceStack = array(); + $this->_cyclicReferenceStack->clear(); if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); trigger_error($errorMessage, E_USER_ERROR); } // function _raiseFormulaError() From db75c5981aaf78c0a6193e2019e86df778a272d8 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 21 Feb 2013 11:29:32 +0000 Subject: [PATCH 010/467] Fixes to Advanced Value Binder for cell restructuring --- Classes/PHPExcel/Cell.php | 3 ++- Classes/PHPExcel/Cell/AdvancedValueBinder.php | 18 +++++++++--------- .../PHPExcel/Cell/AdvancedValueBinderTest.php | 16 ++++++++++++++-- .../PHPExcel/Worksheet/AutoFilterTest.php | 6 ++++++ .../Calculation/DateTime/DATEVALUE.data | 8 ++++---- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index e21674aae..1b944bbc1 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -104,6 +104,7 @@ class PHPExcel_Cell **/ public function notifyCacheController() { $this->_parent->updateCacheData($this); + return $this; } @@ -133,7 +134,7 @@ public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Workshee // Set worksheet cache $this->_parent = $pSheet->getCellCacheController(); - + // Set datatype? if ($pDataType !== NULL) { if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) diff --git a/Classes/PHPExcel/Cell/AdvancedValueBinder.php b/Classes/PHPExcel/Cell/AdvancedValueBinder.php index 0b5efec05..9c96a1b90 100644 --- a/Classes/PHPExcel/Cell/AdvancedValueBinder.php +++ b/Classes/PHPExcel/Cell/AdvancedValueBinder.php @@ -86,7 +86,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) if ($matches[1] == '-') $value = 0 - $value; $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getParent()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode( '??/??' ); return true; } elseif (preg_match('/^([+-]?)([0-9]*) +([0-9]*)\s?\/\s*([0-9]*)$/', $value, $matches)) { @@ -95,7 +95,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) if ($matches[1] == '-') $value = 0 - $value; $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getParent()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode( '# ??/??' ); return true; } @@ -106,7 +106,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) $value = (float) str_replace('%', '', $value) / 100; $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getParent()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00 ); return true; } @@ -120,7 +120,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) $value = (float) trim(str_replace(array($currencyCode, $thousandsSeparator, $decimalSeparator), array('', '', '.'), $value)); $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getParent()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode( str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE ) ); @@ -130,7 +130,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) $value = (float) trim(str_replace(array('$',','), '', $value)); $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getParent()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE ); return true; } @@ -142,7 +142,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) $days = $h / 24 + $m / 1440; $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getParent()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3 ); return true; } @@ -155,7 +155,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) // Convert value to number $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getParent()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4 ); return true; } @@ -170,7 +170,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) } else { $formatCode = 'yyyy-mm-dd'; } - $cell->getParent()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode($formatCode); return true; } @@ -180,7 +180,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) $value = PHPExcel_Shared_String::SanitizeUTF8($value); $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); // Set style - $cell->getParent()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getAlignment()->setWrapText(TRUE); return true; } diff --git a/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php b/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php index a76a2b25a..0a6ca54da 100644 --- a/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php +++ b/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php @@ -35,7 +35,16 @@ public function provider() */ public function testCurrency($value, $valueBinded, $format, $thousandsSeparator, $decimalSeparator, $currencyCode) { - $sheet = $this->getMock('PHPExcel_Worksheet', array('getStyle', 'getNumberFormat', 'setFormatCode')); + $sheet = $this->getMock( + 'PHPExcel_Worksheet', + array('getStyle', 'getNumberFormat', 'setFormatCode','getCellCacheController') + ); + $cache = $this->getMockBuilder('PHPExcel_CachedObjectStorage_Memory') + ->disableOriginalConstructor() + ->getMock(); + $cache->expects($this->any()) + ->method('getParent') + ->will($this->returnValue($sheet)); $sheet->expects($this->once()) ->method('getStyle') @@ -47,12 +56,15 @@ public function testCurrency($value, $valueBinded, $format, $thousandsSeparator, ->method('setFormatCode') ->with($format) ->will($this->returnSelf()); + $sheet->expects($this->any()) + ->method('getCellCacheController') + ->will($this->returnValue($cache)); PHPExcel_Shared_String::setCurrencyCode($currencyCode); PHPExcel_Shared_String::setDecimalSeparator($decimalSeparator); PHPExcel_Shared_String::setThousandsSeparator($thousandsSeparator); - $cell = new PHPExcel_Cell('A', 1, null, PHPExcel_Cell_DataType::TYPE_STRING, $sheet); + $cell = new PHPExcel_Cell(NULL, PHPExcel_Cell_DataType::TYPE_STRING, $sheet); $binder = new PHPExcel_Cell_AdvancedValueBinder(); $binder->bindValue($cell, $value); diff --git a/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php b/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php index 6a6d5ae8d..9907eabc5 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php @@ -18,6 +18,12 @@ public function setUp() $this->_mockWorksheetObject = $this->getMockBuilder('PHPExcel_Worksheet') ->disableOriginalConstructor() ->getMock(); + $this->_mockCacheController = $this->getMockBuilder('PHPExcel_CachedObjectStorage_Memory') + ->disableOriginalConstructor() + ->getMock(); + $this->_mockWorksheetObject->expects($this->any()) + ->method('getCellCacheController') + ->will($this->returnValue($this->_mockCacheController)); $this->_testAutoFilterObject = new PHPExcel_Worksheet_AutoFilter( $this->_testInitialRange, diff --git a/unitTests/rawTestData/Calculation/DateTime/DATEVALUE.data b/unitTests/rawTestData/Calculation/DateTime/DATEVALUE.data index 281c707f1..43970c28d 100644 --- a/unitTests/rawTestData/Calculation/DateTime/DATEVALUE.data +++ b/unitTests/rawTestData/Calculation/DateTime/DATEVALUE.data @@ -35,11 +35,11 @@ "22 August 98", 36029 "1st March 2007", 39142 // MS Excel will fail with a #VALUE return, but PHPExcel can parse this date "The 1st day of March 2007", "#VALUE!" -"1 Jan", 40909 -"31/12", 41274 +"1 Jan", 41275 +"31/12", 41639 "12/31", 11658 // Excel reads as 1st December 1931, not 31st December in current year -"5-JUL", 41095 -"5 Jul", 41095 +"5-JUL", 41460 +"5 Jul", 41460 "12/2008", 39783 "10/32", 11963 11, "#VALUE!" From d42361e8bf31acc5fc1b74f1dcbb5c7b20e42a94 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 21 Feb 2013 11:44:33 +0000 Subject: [PATCH 011/467] Correct attachment of cells to cache collection as parent rather than worksheet --- Classes/PHPExcel/CachedObjectStorage/APC.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/CacheBase.php | 2 +- Classes/PHPExcel/CachedObjectStorage/DiscISAM.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/Igbinary.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/Memcache.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/PHPTemp.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/SQLite.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/SQLite3.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/Wincache.php | 4 ++-- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/APC.php b/Classes/PHPExcel/CachedObjectStorage/APC.php index 8f1e931ec..2e61f03b0 100644 --- a/Classes/PHPExcel/CachedObjectStorage/APC.php +++ b/Classes/PHPExcel/CachedObjectStorage/APC.php @@ -154,8 +154,8 @@ public function getCacheData($pCoord) { // Set current entry to the requested entry $this->_currentObjectID = $pCoord; $this->_currentObject = unserialize($obj); - // Re-attach the parent worksheet - $this->_currentObject->attach($this->_parent); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); // Return requested entry return $this->_currentObject; diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index 0651b4a3a..2176c0ca4 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -259,7 +259,7 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) { $this->_parent = $parent; if (($this->_currentObject !== NULL) && (is_object($this->_currentObject))) { - $this->_currentObject->attach($parent); + $this->_currentObject->attach($this); } } // function copyCellCollection() diff --git a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php index 3fde38512..956fd56e8 100644 --- a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php +++ b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php @@ -124,8 +124,8 @@ public function getCacheData($pCoord) { $this->_currentObjectID = $pCoord; fseek($this->_fileHandle,$this->_cellCache[$pCoord]['ptr']); $this->_currentObject = unserialize(fread($this->_fileHandle,$this->_cellCache[$pCoord]['sz'])); - // Re-attach the parent worksheet - $this->_currentObject->attach($this->_parent); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); // Return requested entry return $this->_currentObject; diff --git a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php index 6e33468a9..7e7d1dfcc 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php +++ b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php @@ -96,8 +96,8 @@ public function getCacheData($pCoord) { // Set current entry to the requested entry $this->_currentObjectID = $pCoord; $this->_currentObject = igbinary_unserialize($this->_cellCache[$pCoord]); - // Re-attach the parent worksheet - $this->_currentObject->attach($this->_parent); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); // Return requested entry return $this->_currentObject; diff --git a/Classes/PHPExcel/CachedObjectStorage/Memcache.php b/Classes/PHPExcel/CachedObjectStorage/Memcache.php index 76ff90964..a54405995 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memcache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memcache.php @@ -158,8 +158,8 @@ public function getCacheData($pCoord) { // Set current entry to the requested entry $this->_currentObjectID = $pCoord; $this->_currentObject = unserialize($obj); - // Re-attach the parent worksheet - $this->_currentObject->attach($this->_parent); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); // Return requested entry return $this->_currentObject; diff --git a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php index ecb29b8c6..43ed104f8 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php @@ -96,8 +96,8 @@ public function getCacheData($pCoord) { // Set current entry to the requested entry $this->_currentObjectID = $pCoord; $this->_currentObject = unserialize(gzinflate($this->_cellCache[$pCoord])); - // Re-attach the parent worksheet - $this->_currentObject->attach($this->_parent); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); // Return requested entry return $this->_currentObject; diff --git a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php index 3feb5faf7..5e1f8381a 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php @@ -96,8 +96,8 @@ public function getCacheData($pCoord) { // Set current entry to the requested entry $this->_currentObjectID = $pCoord; $this->_currentObject = unserialize($this->_cellCache[$pCoord]); - // Re-attach the parent worksheet - $this->_currentObject->attach($this->_parent); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); // Return requested entry return $this->_currentObject; diff --git a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php index e6eafb7f6..5b13e6681 100644 --- a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php +++ b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php @@ -116,8 +116,8 @@ public function getCacheData($pCoord) { $this->_currentObjectID = $pCoord; fseek($this->_fileHandle,$this->_cellCache[$pCoord]['ptr']); $this->_currentObject = unserialize(fread($this->_fileHandle,$this->_cellCache[$pCoord]['sz'])); - // Re-attach the parent worksheet - $this->_currentObject->attach($this->_parent); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); // Return requested entry return $this->_currentObject; diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php index 915d21d0d..0bafbb726 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php @@ -116,8 +116,8 @@ public function getCacheData($pCoord) { $cellResult = $cellResultSet->fetchSingle(); $this->_currentObject = unserialize($cellResult); - // Re-attach the parent worksheet - $this->_currentObject->attach($this->_parent); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); // Return requested entry return $this->_currentObject; diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index f9ca246e0..37615d0a4 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -119,8 +119,8 @@ public function getCacheData($pCoord) { $this->_currentObjectID = $pCoord; $this->_currentObject = unserialize($cellResult); - // Re-attach the parent worksheet - $this->_currentObject->attach($this->_parent); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); // Return requested entry return $this->_currentObject; diff --git a/Classes/PHPExcel/CachedObjectStorage/Wincache.php b/Classes/PHPExcel/CachedObjectStorage/Wincache.php index 38d611663..97b163979 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Wincache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Wincache.php @@ -158,8 +158,8 @@ public function getCacheData($pCoord) { // Set current entry to the requested entry $this->_currentObjectID = $pCoord; $this->_currentObject = unserialize($obj); - // Re-attach the parent worksheet - $this->_currentObject->attach($this->_parent); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); // Return requested entry return $this->_currentObject; From e47b543c895ce7f45ce4a8d424835bec6157bce9 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 27 Feb 2013 12:18:34 +0000 Subject: [PATCH 012/467] Bugfix: Work item GH-80 - "Sheet index is out of bounds." Exception --- Classes/PHPExcel/Reader/Excel2007.php | 19 ++++++++++--------- changelog.txt | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index bd91592df..e2a677dec 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1608,15 +1608,16 @@ public function load($pFilename) break; default: - $range = explode('!', (string)$definedName); - if (count($range) == 2) { - $range[0] = str_replace("''", "'", $range[0]); - $range[0] = str_replace("'", "", $range[0]); - if ($worksheet = $docSheet->getParent()->getSheetByName($range[0])) { - $extractedRange = str_replace('$', '', $range[1]); - $scope = $docSheet->getParent()->getSheet((string)$definedName['localSheetId']); - - $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $worksheet, $extractedRange, true, $scope) ); + if ($mapSheetId[(integer) $definedName['localSheetId']] !== null) { + $range = explode('!', (string)$definedName); + if (count($range) == 2) { + $range[0] = str_replace("''", "'", $range[0]); + $range[0] = str_replace("'", "", $range[0]); + if ($worksheet = $docSheet->getParent()->getSheetByName($range[0])) { + $extractedRange = str_replace('$', '', $range[1]); + $scope = $docSheet->getParent()->getSheet($mapSheetId[(integer) $definedName['localSheetId']]); + $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $worksheet, $extractedRange, true, $scope) ); + } } } break; diff --git a/changelog.txt b/changelog.txt index 552cb9e43..e02c3a4a7 100644 --- a/changelog.txt +++ b/changelog.txt @@ -50,7 +50,7 @@ Fixed in develop branch: - Bugfix: (MBaker) Work item GH-104 - echo statements in HTML.php - Feature: (Progi1984) Work item GH-8/CP11704 : Conditional formatting in Excel 5 Writer - Bugfix: (MBaker) Work item GH-113 - canRead() Error for GoogleDocs ODS files: in ODS files from Google Docs there is no mimetype file - +- Bugfix: (MBaker) Work item GH-80 - "Sheet index is out of bounds." Exception -------------------------------------------------------------------------------- BREAKING CHANGE! As part of the planned changes for handling array formulae in From a49b3c48341f30bd5630cd79a8f38ee71875fadc Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 27 Feb 2013 12:52:57 +0000 Subject: [PATCH 013/467] Example of cell-level protection in a worksheet --- Examples/12cellProtection.php | 107 ++++++++++++++++++++++++++++++++++ Examples/runall.php | 1 + 2 files changed, 108 insertions(+) create mode 100644 Examples/12cellProtection.php diff --git a/Examples/12cellProtection.php b/Examples/12cellProtection.php new file mode 100644 index 000000000..caa38767b --- /dev/null +++ b/Examples/12cellProtection.php @@ -0,0 +1,107 @@ +'); + +date_default_timezone_set('Europe/London'); + +/** Include PHPExcel */ +require_once '../Classes/PHPExcel.php'; + + +// Create new PHPExcel object +echo date('H:i:s') , " Create new PHPExcel object" , EOL; +$objPHPExcel = new PHPExcel(); + +// Set document properties +echo date('H:i:s') , " Set document properties" , EOL; +$objPHPExcel->getProperties()->setCreator("Mark Baker") + ->setLastModifiedBy("Mark Baker") + ->setTitle("Office 2007 XLSX Test Document") + ->setSubject("Office 2007 XLSX Test Document") + ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") + ->setKeywords("office 2007 openxml php") + ->setCategory("Test result file"); + + +// Add some data +echo date('H:i:s') , " Add some data" , EOL; +$objPHPExcel->setActiveSheetIndex(0); +$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Crouching'); +$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Tiger'); +$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Hidden'); +$objPHPExcel->getActiveSheet()->setCellValue('B2', 'Dragon'); + +// Rename worksheet +echo date('H:i:s') , " Rename worksheet" , EOL; +$objPHPExcel->getActiveSheet()->setTitle('Simple'); + + +// Set document security +echo date('H:i:s') , " Set cell protection" , EOL; + + +// Set sheet security +echo date('H:i:s') , " Set sheet security" , EOL; +$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); +$objPHPExcel->getActiveSheet() + ->getStyle('A2:B2') + ->getProtection()->setLocked( + PHPExcel_Style_Protection::PROTECTION_UNPROTECTED + ); + + +// Set active sheet index to the first sheet, so Excel opens this as the first sheet +$objPHPExcel->setActiveSheetIndex(0); + + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Examples/runall.php b/Examples/runall.php index ad37f3397..7e97ee825 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -52,6 +52,7 @@ , '10autofilter-selection-2.php' , '11documentsecurity.php' , '11documentsecurity-xls.php' + , '12cellProtection.php' , '13calculation.php' , '14excel5.php' , '15datavalidation.php' From 429ad592843d3aa415608cb17d1a7f5116152852 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 27 Feb 2013 17:54:45 +0000 Subject: [PATCH 014/467] Method for moving cells in the cell cache without needing to access the cell itself TODO Sqlite cell cache needs equivalent method for updating cache database rather than simply the indexed cache array --- .../CachedObjectStorage/CacheBase.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index 0651b4a3a..b6cf4be07 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -106,6 +106,26 @@ public function isDataSet($pCoord) { } // function isDataSet() + /** + * Move a cell object from one address to another + * + * @param string $fromAddress Current address of the cell to move + * @param string $toAddress Destination address of the cell to move + * @return boolean + */ + public function moveCell($fromAddress, $toAddress) { + if ($fromAddress === $this->_currentObjectID) { + $this->_currentObjectID = $toAddress; + } + if (isset($this->_cellCache[$fromAddress])) { + $this->_cellCache[$toAddress] = &$this->_cellCache[$fromAddress]; + unset($this->_cellCache[$fromAddress]); + } + + return TRUE; + } // function isDataSet() + + /** * Add or Update a cell in cache * From ae9d9fd75864028e9a89599def7dc9338639271e Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 27 Feb 2013 23:13:49 +0000 Subject: [PATCH 015/467] Add move cell method for SQLite. TODO - modify SQLite3 to use parameterised statements consistently throughout --- .../CachedObjectStorage/CacheBase.php | 3 ++- .../PHPExcel/CachedObjectStorage/SQLite.php | 26 +++++++++++++++++++ .../PHPExcel/CachedObjectStorage/SQLite3.php | 26 +++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index e5fc678c5..6dd6c1a5a 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -117,13 +117,14 @@ public function moveCell($fromAddress, $toAddress) { if ($fromAddress === $this->_currentObjectID) { $this->_currentObjectID = $toAddress; } + $this->_currentCellIsDirty = true; if (isset($this->_cellCache[$fromAddress])) { $this->_cellCache[$toAddress] = &$this->_cellCache[$fromAddress]; unset($this->_cellCache[$fromAddress]); } return TRUE; - } // function isDataSet() + } // function moveCell() /** diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php index 0bafbb726..d717c4993 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php @@ -169,6 +169,32 @@ public function deleteCacheData($pCoord) { } // function deleteCacheData() + /** + * Move a cell object from one address to another + * + * @param string $fromAddress Current address of the cell to move + * @param string $toAddress Destination address of the cell to move + * @return boolean + */ + public function moveCell($fromAddress, $toAddress) { + if ($fromAddress === $this->_currentObjectID) { + $this->_currentObjectID = $toAddress; + } + + $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$toAddress."'"; + $result = $this->_DBHandle->exec($query); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + $query = "UPDATE kvp_".$this->_TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'"; + $result = $this->_DBHandle->exec($query); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + return TRUE; + } // function moveCell() + + /** * Get a list of all cell addresses currently held in cache * diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index 37615d0a4..5886c3c35 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -173,6 +173,32 @@ public function deleteCacheData($pCoord) { } // function deleteCacheData() + /** + * Move a cell object from one address to another + * + * @param string $fromAddress Current address of the cell to move + * @param string $toAddress Destination address of the cell to move + * @return boolean + */ + public function moveCell($fromAddress, $toAddress) { + if ($fromAddress === $this->_currentObjectID) { + $this->_currentObjectID = $toAddress; + } + + $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$toAddress."'"; + $result = $this->_DBHandle->exec($query); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + $query = "UPDATE kvp_".$this->_TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'"; + $result = $this->_DBHandle->exec($query); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + return TRUE; + } // function moveCell() + + /** * Get a list of all cell addresses currently held in cache * From e5613be860f590e8fd1ff17e060cd99d05fe1a27 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 28 Feb 2013 12:22:10 +0000 Subject: [PATCH 016/467] Ensure that values returned get getCalculatedValue aren't array values, irrespective of the returnArrayAsType setting --- Classes/PHPExcel/Cell.php | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 1b944bbc1..cbaddc153 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -134,7 +134,7 @@ public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Workshee // Set worksheet cache $this->_parent = $pSheet->getCellCacheController(); - + // Set datatype? if ($pDataType !== NULL) { if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) @@ -273,21 +273,26 @@ public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_Data */ public function getCalculatedValue($resetLog = TRUE) { -// echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().'
'; +//echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().PHP_EOL; if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { try { -// echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value
'; +//echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value'.PHP_EOL; $result = PHPExcel_Calculation::getInstance( $this->getWorksheet()->getParent() )->calculateCellValue($this,$resetLog); -// $result = $this->getParent()->getParent()->getCalculationEngine()->calculateCellValue($this,$resetLog); -// echo $this->getCoordinate().' calculation result is '.$result.'
'; +//echo $this->getCoordinate().' calculation result is '.$result.PHP_EOL; + // We don't yet handle array returns + if (is_array($result)) { + while (is_array($result)) { + $result = array_pop($result); + } + } } catch ( PHPExcel_Exception $ex ) { if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) { -// echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().'
'; +//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; return $this->_calculatedValue; // Fallback for calculations referencing external files. } -// echo 'Calculation Exception: '.$ex->getMessage().'
'; +//echo 'Calculation Exception: '.$ex->getMessage().PHP_EOL; $result = '#N/A'; throw( new PHPExcel_Calculation_Exception( @@ -297,10 +302,10 @@ public function getCalculatedValue($resetLog = TRUE) } if ($result === '#Not Yet Implemented') { -// echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().'
'; +//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; return $this->_calculatedValue; // Fallback if calculation engine does not support the formula. } -// echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().'
'; +//echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL; return $result; } From 5144932a8b956901fc5c4c4fe7b12d08d1b24ffa Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 1 Mar 2013 13:50:06 +0000 Subject: [PATCH 017/467] Make consistent use of prepared statements --- .../PHPExcel/CachedObjectStorage/SQLite3.php | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index 5886c3c35..c3a1deb5b 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -106,19 +106,22 @@ public function getCacheData($pCoord) { } $this->_storeData(); - $query = "SELECT value FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; - $cellResult = $this->_DBHandle->querySingle($query); - if ($cellResult === false) { + $query = $this->_DBHandle->prepare("SELECT value FROM kvp_".$this->_TableName." WHERE id = :id"); + $query->bindValue('id',$pCoord,SQLITE3_TEXT); + $cellResult = $query->execute(); + if ($cellResult === FALSE) { throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); - } elseif (is_null($cellResult)) { + } + $cellData = $cellResult->fetchArray(SQLITE3_ASSOC); + if ($cellData === FALSE) { // Return null if requested entry doesn't exist in cache - return null; + return NULL; } // Set current entry to the requested entry $this->_currentObjectID = $pCoord; - $this->_currentObject = unserialize($cellResult); + $this->_currentObject = unserialize($cellData['value']); // Re-attach this as the cell's parent $this->_currentObject->attach($this); @@ -135,19 +138,19 @@ public function getCacheData($pCoord) { */ public function isDataSet($pCoord) { if ($pCoord === $this->_currentObjectID) { - return true; + return TRUE; } // Check if the requested entry exists in the cache - $query = "SELECT id FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; - $cellResult = $this->_DBHandle->querySingle($query); - if ($cellResult === false) { + $query = $this->_DBHandle->prepare("SELECT value FROM kvp_".$this->_TableName." WHERE id = :id"); + $query->bindValue('id',$pCoord,SQLITE3_TEXT); + $cellResult = $query->execute(); + if ($cellResult === FALSE) { throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); - } elseif (is_null($cellResult)) { - // Return null if requested entry doesn't exist in cache - return false; } - return true; + $cellData = $cellResult->fetchArray(SQLITE3_ASSOC); + + return ($cellData === FALSE) ? FALSE : TRUE; } // function isDataSet() @@ -160,16 +163,17 @@ public function isDataSet($pCoord) { public function deleteCacheData($pCoord) { if ($pCoord === $this->_currentObjectID) { $this->_currentObject->detach(); - $this->_currentObjectID = $this->_currentObject = null; + $this->_currentObjectID = $this->_currentObject = NULL; } // Check if the requested entry exists in the cache - $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; - $result = $this->_DBHandle->exec($query); - if ($result === false) + $query = $this->_DBHandle->prepare("DELETE FROM kvp_".$this->_TableName." WHERE id = :id"); + $query->bindValue('id',$pCoord,SQLITE3_TEXT); + $result = $query->execute(); + if ($result === FALSE) throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); - $this->_currentCellIsDirty = false; + $this->_currentCellIsDirty = FALSE; } // function deleteCacheData() From 6145cf326b7492c2297430f5acdf71c5712027d1 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 1 Mar 2013 21:38:13 +0000 Subject: [PATCH 018/467] Bugfix: (ccorliss) Work item GH-105 - Fixed number format fatal error --- Classes/PHPExcel/Style/NumberFormat.php | 2 +- Classes/PHPExcel/Worksheet.php | 5 ++++- changelog.txt | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index ed6ace90c..dde1ad991 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -439,7 +439,7 @@ public function getHashCode() * @param array $callBack Callback function for additional formatting of string * @return string Formatted string */ - public static function toFormattedString($value = '', $format = '', $callBack = null) + public static function toFormattedString($value = PHPExcel_Style_NumberFormat::FORMAT_GENERAL, $format = '', $callBack = null) { // For now we do not treat strings although section 4 of a format code affects strings if (!is_numeric($value)) return $value; diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 738d1674d..5357a9380 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -2438,7 +2438,10 @@ public function rangeToArray( if ($formatData) { $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString( - $returnValue[$rRef][$cRef], $style->getNumberFormat()->getFormatCode() + $returnValue[$rRef][$cRef], + ($style->getNumberFormat()) ? + $style->getNumberFormat()->getFormatCode() : + PHPExcel_Style_NumberFormat::FORMAT_GENERAL ); } } else { diff --git a/changelog.txt b/changelog.txt index e02c3a4a7..600a33fdc 100644 --- a/changelog.txt +++ b/changelog.txt @@ -51,6 +51,7 @@ Fixed in develop branch: - Feature: (Progi1984) Work item GH-8/CP11704 : Conditional formatting in Excel 5 Writer - Bugfix: (MBaker) Work item GH-113 - canRead() Error for GoogleDocs ODS files: in ODS files from Google Docs there is no mimetype file - Bugfix: (MBaker) Work item GH-80 - "Sheet index is out of bounds." Exception +- Bugfix: (ccorliss) Work item GH-105 - Fixed number format fatal error -------------------------------------------------------------------------------- BREAKING CHANGE! As part of the planned changes for handling array formulae in From 8a97503f175d1d68b443ce96847cecbcea22ae65 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 6 Mar 2013 17:19:22 +0000 Subject: [PATCH 019/467] Bugfix: Add DROP TABLE in destructor for SQLite and SQLite3 cache controllers --- .../PHPExcel/CachedObjectStorage/SQLite.php | 4 + .../PHPExcel/CachedObjectStorage/SQLite3.php | 1 + .../06largescale-with-cellcaching-sqlite.php | 126 ++++++++++++++++++ .../06largescale-with-cellcaching-sqlite3.php | 126 ++++++++++++++++++ changelog.txt | 1 + 5 files changed, 258 insertions(+) create mode 100644 Examples/06largescale-with-cellcaching-sqlite.php create mode 100644 Examples/06largescale-with-cellcaching-sqlite3.php diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php index d717c4993..5e82c089c 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php @@ -282,6 +282,10 @@ public function __construct(PHPExcel_Worksheet $parent) { * Destroy this cell collection */ public function __destruct() { + if (!is_null($this->_DBHandle)) { + $this->_DBHandle->queryExec('DROP TABLE kvp_'.$this->_TableName); + $this->_DBHandle->close(); + } $this->_DBHandle = null; } // function __destruct() diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index c3a1deb5b..35fd73eed 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -291,6 +291,7 @@ public function __construct(PHPExcel_Worksheet $parent) { */ public function __destruct() { if (!is_null($this->_DBHandle)) { + $this->_DBHandle->exec('DROP TABLE kvp_'.$this->_TableName); $this->_DBHandle->close(); } $this->_DBHandle = null; diff --git a/Examples/06largescale-with-cellcaching-sqlite.php b/Examples/06largescale-with-cellcaching-sqlite.php new file mode 100644 index 000000000..fff369594 --- /dev/null +++ b/Examples/06largescale-with-cellcaching-sqlite.php @@ -0,0 +1,126 @@ +'); + +date_default_timezone_set('Europe/London'); + +/** Include PHPExcel */ +require_once '../Classes/PHPExcel.php'; + +$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite; +PHPExcel_Settings::setCacheStorageMethod($cacheMethod); +echo date('H:i:s') , " Enable Cell Caching using " , $cacheMethod , " method" , EOL; + + +// Create new PHPExcel object +echo date('H:i:s') , " Create new PHPExcel object" , EOL; +$objPHPExcel = new PHPExcel(); + +// Set document properties +echo date('H:i:s') , " Set properties" , EOL; +$objPHPExcel->getProperties()->setCreator("Maarten Balliauw") + ->setLastModifiedBy("Maarten Balliauw") + ->setTitle("Office 2007 XLSX Test Document") + ->setSubject("Office 2007 XLSX Test Document") + ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") + ->setKeywords("office 2007 openxml php") + ->setCategory("Test result file"); + + +// Create a first sheet +echo date('H:i:s') , " Add data" , EOL; +$objPHPExcel->setActiveSheetIndex(0); +$objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname"); +$objPHPExcel->getActiveSheet()->setCellValue('B1', "Lastname"); +$objPHPExcel->getActiveSheet()->setCellValue('C1', "Phone"); +$objPHPExcel->getActiveSheet()->setCellValue('D1', "Fax"); +$objPHPExcel->getActiveSheet()->setCellValue('E1', "Is Client ?"); + + +// Hide "Phone" and "fax" column +echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , EOL; +$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false); +$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false); + + +// Set outline levels +echo date('H:i:s') , " Set outline levels" , EOL; +$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1) + ->setVisible(false) + ->setCollapsed(true); + +// Freeze panes +echo date('H:i:s') , " Freeze panes" , EOL; +$objPHPExcel->getActiveSheet()->freezePane('A2'); + + +// Rows to repeat at top +echo date('H:i:s') , " Rows to repeat at top" , EOL; +$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1); + + +// Add data +for ($i = 2; $i <= 5000; $i++) { + $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i") + ->setCellValue('B' . $i, "LName $i") + ->setCellValue('C' . $i, "PhoneNo $i") + ->setCellValue('D' . $i, "FaxNo $i") + ->setCellValue('E' . $i, true); +} + + +// Set active sheet index to the first sheet, so Excel opens this as the first sheet +$objPHPExcel->setActiveSheetIndex(0); + + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Examples/06largescale-with-cellcaching-sqlite3.php b/Examples/06largescale-with-cellcaching-sqlite3.php new file mode 100644 index 000000000..a4c537a59 --- /dev/null +++ b/Examples/06largescale-with-cellcaching-sqlite3.php @@ -0,0 +1,126 @@ +'); + +date_default_timezone_set('Europe/London'); + +/** Include PHPExcel */ +require_once '../Classes/PHPExcel.php'; + +$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3; +PHPExcel_Settings::setCacheStorageMethod($cacheMethod); +echo date('H:i:s') , " Enable Cell Caching using " , $cacheMethod , " method" , EOL; + + +// Create new PHPExcel object +echo date('H:i:s') , " Create new PHPExcel object" , EOL; +$objPHPExcel = new PHPExcel(); + +// Set document properties +echo date('H:i:s') , " Set properties" , EOL; +$objPHPExcel->getProperties()->setCreator("Maarten Balliauw") + ->setLastModifiedBy("Maarten Balliauw") + ->setTitle("Office 2007 XLSX Test Document") + ->setSubject("Office 2007 XLSX Test Document") + ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") + ->setKeywords("office 2007 openxml php") + ->setCategory("Test result file"); + + +// Create a first sheet +echo date('H:i:s') , " Add data" , EOL; +$objPHPExcel->setActiveSheetIndex(0); +$objPHPExcel->getActiveSheet()->setCellValue('A1', "Firstname"); +$objPHPExcel->getActiveSheet()->setCellValue('B1', "Lastname"); +$objPHPExcel->getActiveSheet()->setCellValue('C1', "Phone"); +$objPHPExcel->getActiveSheet()->setCellValue('D1', "Fax"); +$objPHPExcel->getActiveSheet()->setCellValue('E1', "Is Client ?"); + + +// Hide "Phone" and "fax" column +echo date('H:i:s') , " Hide 'Phone' and 'fax' columns" , EOL; +$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false); +$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false); + + +// Set outline levels +echo date('H:i:s') , " Set outline levels" , EOL; +$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1) + ->setVisible(false) + ->setCollapsed(true); + +// Freeze panes +echo date('H:i:s') , " Freeze panes" , EOL; +$objPHPExcel->getActiveSheet()->freezePane('A2'); + + +// Rows to repeat at top +echo date('H:i:s') , " Rows to repeat at top" , EOL; +$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1); + + +// Add data +for ($i = 2; $i <= 5000; $i++) { + $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i") + ->setCellValue('B' . $i, "LName $i") + ->setCellValue('C' . $i, "PhoneNo $i") + ->setCellValue('D' . $i, "FaxNo $i") + ->setCellValue('E' . $i, true); +} + + +// Set active sheet index to the first sheet, so Excel opens this as the first sheet +$objPHPExcel->setActiveSheetIndex(0); + + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/changelog.txt b/changelog.txt index b626123bb..27410f85e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -54,6 +54,7 @@ Fixed in develop branch for release v1.7.9: - Bugfix: (MBaker) Work item GH-113 - canRead() Error for GoogleDocs ODS files: in ODS files from Google Docs there is no mimetype file - Bugfix: (MBaker) Work item GH-80 - "Sheet index is out of bounds." Exception - Bugfix: (ccorliss) Work item GH-105 - Fixed number format fatal error +- Bugfix: (MBaker) - Add DROP TABLE in destructor for SQLite and SQLite3 cache controllers -------------------------------------------------------------------------------- BREAKING CHANGE! As part of the planned changes for handling array formulae in From 5940e40362eeacf7ac66ef9238826973db531c84 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 6 Mar 2013 17:43:12 +0000 Subject: [PATCH 020/467] Make prepared statements re-usable --- .../PHPExcel/CachedObjectStorage/SQLite3.php | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index 35fd73eed..ecd802945 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -49,6 +49,11 @@ class PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_ */ private $_DBHandle = null; + private $_selectQuery; + private $_insertQuery; + private $_updateQuery; + private $_deleteQuery; + /** * Store cell data in cache for the current cell object if it's "dirty", * and the 'nullify' the current cell object @@ -60,10 +65,9 @@ protected function _storeData() { if ($this->_currentCellIsDirty) { $this->_currentObject->detach(); - $query = $this->_DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES(:id,:data)"); - $query->bindValue('id',$this->_currentObjectID,SQLITE3_TEXT); - $query->bindValue('data',serialize($this->_currentObject),SQLITE3_BLOB); - $result = $query->execute(); + $this->_insertQuery->bindValue('id',$this->_currentObjectID,SQLITE3_TEXT); + $this->_insertQuery->bindValue('data',serialize($this->_currentObject),SQLITE3_BLOB); + $result = $this->_insertQuery->execute(); if ($result === false) throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); $this->_currentCellIsDirty = false; @@ -106,9 +110,8 @@ public function getCacheData($pCoord) { } $this->_storeData(); - $query = $this->_DBHandle->prepare("SELECT value FROM kvp_".$this->_TableName." WHERE id = :id"); - $query->bindValue('id',$pCoord,SQLITE3_TEXT); - $cellResult = $query->execute(); + $this->_selectQuery->bindValue('id',$pCoord,SQLITE3_TEXT); + $cellResult = $this->_selectQuery->execute(); if ($cellResult === FALSE) { throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); } @@ -142,9 +145,8 @@ public function isDataSet($pCoord) { } // Check if the requested entry exists in the cache - $query = $this->_DBHandle->prepare("SELECT value FROM kvp_".$this->_TableName." WHERE id = :id"); - $query->bindValue('id',$pCoord,SQLITE3_TEXT); - $cellResult = $query->execute(); + $this->_selectQuery->bindValue('id',$pCoord,SQLITE3_TEXT); + $cellResult = $this->_selectQuery->execute(); if ($cellResult === FALSE) { throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); } @@ -167,9 +169,8 @@ public function deleteCacheData($pCoord) { } // Check if the requested entry exists in the cache - $query = $this->_DBHandle->prepare("DELETE FROM kvp_".$this->_TableName." WHERE id = :id"); - $query->bindValue('id',$pCoord,SQLITE3_TEXT); - $result = $query->execute(); + $this->_deleteQuery->bindValue('id',$pCoord,SQLITE3_TEXT); + $result = $this->_deleteQuery->execute(); if ($result === FALSE) throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); @@ -189,13 +190,14 @@ public function moveCell($fromAddress, $toAddress) { $this->_currentObjectID = $toAddress; } - $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$toAddress."'"; - $result = $this->_DBHandle->exec($query); + $this->_deleteQuery->bindValue('id',$toAddress,SQLITE3_TEXT); + $result = $this->_deleteQuery->execute(); if ($result === false) throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); - $query = "UPDATE kvp_".$this->_TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'"; - $result = $this->_DBHandle->exec($query); + $this->_updateQuery->bindValue('toid',$toAddress,SQLITE3_TEXT); + $this->_updateQuery->bindValue('fromid',$fromAddress,SQLITE3_TEXT); + $result = $this->_updateQuery->execute(); if ($result === false) throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); @@ -283,6 +285,11 @@ public function __construct(PHPExcel_Worksheet $parent) { if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); } + + $this->_selectQuery = $this->_DBHandle->prepare("SELECT value FROM kvp_".$this->_TableName." WHERE id = :id"); + $this->_insertQuery = $this->_DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES(:id,:data)"); + $this->_updateQuery = $this->_DBHandle->prepare("UPDATE kvp_".$this->_TableName." SET id=:toId WHERE id=:fromId"); + $this->_deleteQuery = $this->_DBHandle->prepare("DELETE FROM kvp_".$this->_TableName." WHERE id = :id"); } // function __construct() From fb16712e13f4240403859771c87647f8ce1f8ba3 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 6 Mar 2013 21:38:42 +0000 Subject: [PATCH 021/467] Some work on page margins for HTML Writer, and initial elements for DomPDF PDF Writer --- Classes/PHPExcel/Writer/HTML.php | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index d07dbd2d1..fb467f361 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -1016,7 +1016,8 @@ private function _generateTableHeader($pSheet) { // Construct HTML $html = ''; - + $html .= $this->_setMargins($pSheet); + if (!$this->_useInlineCss) { $gridlines = $pSheet->getShowGridLines() ? ' gridlines' : ''; $html .= ' ' . PHP_EOL; @@ -1495,4 +1496,27 @@ private function _calculateSpans() $this->_spansAreCalculated = true; } + private function _setMargins(PHPExcel_Worksheet $pSheet) { + $htmlPage = '@page { '; + $htmlBody = 'body { '; + + $left = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()) . 'in; '; + $htmlPage .= 'left-margin: ' . $left; + $htmlBody .= 'left-margin: ' . $left; + $right = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()) . 'in; '; + $htmlPage .= 'right-margin: ' . $right; + $htmlBody .= 'right-margin: ' . $right; + $top = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()) . 'in; '; + $htmlPage .= 'top-margin: ' . $top; + $htmlBody .= 'top-margin: ' . $top; + $bottom = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()) . 'in; '; + $htmlPage .= 'bottom-margin: ' . $bottom; + $htmlBody .= 'bottom-margin: ' . $bottom; + + $htmlPage .= "}\n"; + $htmlBody .= "}\n"; + + return "\n"; + } + } From 316f86e03c02b9112bd7c54de83b5738defd869f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 10 Mar 2013 23:15:57 +0000 Subject: [PATCH 022/467] Docblock comments --- Classes/PHPExcel/Calculation/Engineering.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Calculation/Engineering.php b/Classes/PHPExcel/Calculation/Engineering.php index 84dcd388f..c0005e744 100644 --- a/Classes/PHPExcel/Calculation/Engineering.php +++ b/Classes/PHPExcel/Calculation/Engineering.php @@ -1932,7 +1932,7 @@ public static function IMLOG10($complexNumber) { /** * IMLOG2 * - * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format. + * Returns the base-2 logarithm of a complex number in x + yi or x + yj text format. * * Excel Function: * IMLOG2(complexNumber) From 80e3c46f3a5d28625a610c93a16ceb8239727da4 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 16 Mar 2013 00:18:38 +0000 Subject: [PATCH 023/467] iconv() is more efficient than mb_convert_encoding() --- Classes/PHPExcel/Shared/String.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 3e495e822..31e2ef347 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -482,7 +482,7 @@ public static function UTF8toBIFF8UnicodeLong($value) } /** - * Convert string from one encoding to another. First try iconv, then mbstring, or no convertion + * Convert string from one encoding to another. First try mbstring, then iconv, finally strlen * * @param string $value * @param string $to Encoding to convert to, e.g. 'UTF-8' @@ -491,14 +491,14 @@ public static function UTF8toBIFF8UnicodeLong($value) */ public static function ConvertEncoding($value, $to, $from) { - if (self::getIsIconvEnabled()) { - return iconv($from, $to, $value); - } - if (self::getIsMbstringEnabled()) { return mb_convert_encoding($value, $to, $from); } + if (self::getIsIconvEnabled()) { + return iconv($from, $to, $value); + } + if($from == 'UTF-16LE'){ return self::utf16_decode($value, false); }else if($from == 'UTF-16BE'){ @@ -548,20 +548,20 @@ public static function utf16_decode( $str, $bom_be=true ) { */ public static function CountCharacters($value, $enc = 'UTF-8') { - if (self::getIsIconvEnabled()) { - return iconv_strlen($value, $enc); - } - if (self::getIsMbstringEnabled()) { return mb_strlen($value, $enc); } + if (self::getIsIconvEnabled()) { + return iconv_strlen($value, $enc); + } + // else strlen return strlen($value); } /** - * Get a substring of a UTF-8 encoded string + * Get a substring of a UTF-8 encoded string. First try mbstring, then iconv, finally strlen * * @param string $pValue UTF-8 encoded string * @param int $start Start offset @@ -570,14 +570,14 @@ public static function CountCharacters($value, $enc = 'UTF-8') */ public static function Substring($pValue = '', $pStart = 0, $pLength = 0) { - if (self::getIsIconvEnabled()) { - return iconv_substr($pValue, $pStart, $pLength, 'UTF-8'); - } - if (self::getIsMbstringEnabled()) { return mb_substr($pValue, $pStart, $pLength, 'UTF-8'); } + if (self::getIsIconvEnabled()) { + return iconv_substr($pValue, $pStart, $pLength, 'UTF-8'); + } + // else substr return substr($pValue, $pStart, $pLength); } From b42d4a353cc98709a9ef463ec7a3dee0aa0ffa34 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 20 Mar 2013 13:48:25 +0000 Subject: [PATCH 024/467] Fix reference to worksheet/cell collection from cell in isDateTime() --- Classes/PHPExcel/Shared/Date.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index d74e96740..68076ce12 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -253,7 +253,7 @@ public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minut */ public static function isDateTime(PHPExcel_Cell $pCell) { return self::isDateTimeFormat( - $pCell->getParent()->getStyle( + $pCell->getWorksheet()->getStyle( $pCell->getCoordinate() )->getNumberFormat() ); From 477902570160a5c1a070bf157ce146a373076f2d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 22 Mar 2013 14:09:22 +0000 Subject: [PATCH 025/467] General: Work item GH-98 - Split repository in order to improve distribution of the library via composer Added .gitattributes file to identify files/folders that should be excluded from a composer distribution unless invoked as composer install --prefer-source --- .gitattributes | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..1bc28be4b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +/Build export-ignore +/Documentation export-ignore +/Tests export-ignore +README.md export-ignore From d79bdc5b19ba10326ad92876b0eb65ead5b5d6da Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 24 Mar 2013 21:56:06 +0000 Subject: [PATCH 026/467] iconv rather than mbstring for convert encoding --- Classes/PHPExcel/Shared/String.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 31e2ef347..38974336d 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -491,14 +491,14 @@ public static function UTF8toBIFF8UnicodeLong($value) */ public static function ConvertEncoding($value, $to, $from) { - if (self::getIsMbstringEnabled()) { - return mb_convert_encoding($value, $to, $from); - } - if (self::getIsIconvEnabled()) { return iconv($from, $to, $value); } + if (self::getIsMbstringEnabled()) { + return mb_convert_encoding($value, $to, $from); + } + if($from == 'UTF-16LE'){ return self::utf16_decode($value, false); }else if($from == 'UTF-16BE'){ From 0c15e8abb71a358d8622ae2eedcdbbb2da1346bf Mon Sep 17 00:00:00 2001 From: Phill Sparks Date: Wed, 27 Mar 2013 16:12:35 +0000 Subject: [PATCH 027/467] Fix Excel5 category Update Excel5.php to remove hard-coded "Test result file" category --- Classes/PHPExcel/Writer/Excel5.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index a63c1d1c3..37f5b85c3 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -596,7 +596,6 @@ private function _writeDocumentSummaryInformation(){ // GKPIDDSI_CATEGORY : Category if($this->_phpExcel->getProperties()->getCategory()){ $dataProp = $this->_phpExcel->getProperties()->getCategory(); - $dataProp = 'Test result file'; $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), @@ -933,4 +932,4 @@ private function _writeSummaryInformation(){ return $data; } -} \ No newline at end of file +} From 663b8a190342a86a67501caa37067350372b4021 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 29 Mar 2013 11:15:36 +0000 Subject: [PATCH 028/467] General: Modify cell's getCalculatedValue() method to return the content of RichText objects rather than the RichText object itself --- Classes/PHPExcel/Cell.php | 8 +++----- changelog.txt | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index cbaddc153..dbd7a822f 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -307,12 +307,10 @@ public function getCalculatedValue($resetLog = TRUE) } //echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL; return $result; + } elseif($this->_value instanceof PHPExcel_RichText) { +// echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->_value.'
'; + return $this->_value->getPlainText(); } - -// if ($this->_value === NULL) { -// echo 'Cell '.$this->getCoordinate().' has no value, formula or otherwise
'; -// return NULL; -// } // echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'
'; return $this->_value; } diff --git a/changelog.txt b/changelog.txt index 27410f85e..afdadb0d0 100644 --- a/changelog.txt +++ b/changelog.txt @@ -43,6 +43,7 @@ Fixed in develop branch for release v1.7.9: - General: (dbonsch) Restructuring of PHPExcel Exceptions - General: (MBaker) Work items 16926 and 15145 - Refactor Calculation Engine from singleton to a Multiton Ensures that calculation cache is maintained independently for different workbooks +- General: (MBaker) Modify cell's getCalculatedValue() method to return the content of RichText objects rather than the RichText object itself - Bugfix: (techhead) Work item GH-70 - Fixed formula/formatting bug when removing rows - Bugfix: (alexgann) Work item GH-63 - Fix to cellExists for non-existent namedRanges - Bugfix: (MBaker) Work item 18844 - cache_in_memory_gzip "eats" last worksheet line, cache_in_memory doesn't From db7b99ac8ee04e52c4e4bf35df4714dcb3f50321 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 1 Apr 2013 17:26:26 +0100 Subject: [PATCH 029/467] Bugfix: (alexgann) Work item GH-154 - Fix merged-cell borders on HTML/PDF output --- Classes/PHPExcel/Writer/HTML.php | 10 +++++++++- changelog.txt | 8 +++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index a30033f1d..f50412e5a 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -966,7 +966,10 @@ private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) { */ private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) { // Create CSS - $css = $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); +// $css = $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); + // Create CSS - add !important to non-none border styles for merged cells + $borderStyle = $this->_mapBorderStyle($pStyle->getBorderStyle()); + $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); // Return return $css; @@ -1229,6 +1232,11 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow $spans = $this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]; $rowSpan = $spans['rowspan']; $colSpan = $spans['colspan']; + + // Also apply style from last cell in merge to fix borders - + // relies on !important for non-none border declarations in _createCSSStyleBorder + $endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan); + $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex(); } // Write diff --git a/changelog.txt b/changelog.txt index afdadb0d0..16a7ac10d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -56,13 +56,15 @@ Fixed in develop branch for release v1.7.9: - Bugfix: (MBaker) Work item GH-80 - "Sheet index is out of bounds." Exception - Bugfix: (ccorliss) Work item GH-105 - Fixed number format fatal error - Bugfix: (MBaker) - Add DROP TABLE in destructor for SQLite and SQLite3 cache controllers +- Bugfix: (alexgann) Work item GH-154 - Fix merged-cell borders on HTML/PDF output + -------------------------------------------------------------------------------- BREAKING CHANGE! As part of the planned changes for handling array formulae in workbooks, there are some changes that will affect the PHPExcel_Cell object methods. -The following methods are now deprecated, and will be removed in version 1.7.9: +The following methods are now deprecated, and will be removed in or after version 1.8.0: getCalculatedValue() The getValue() method will return calculated values for cells containing formulae instead. setCalculatedValue() The cell value will always contain the result of a @@ -72,7 +74,7 @@ The following methods are now deprecated, and will be removed in version 1.7.9: getFormulaAttributes() This will be replaced by the getArrayFormulaRange() method. -The following methods will be added in version 1.7.9 +The following methods will be added in version 1.8.0 getFormula() Use to retrieve a cell formula, will return the cell value if the cell doesn't contain a formula, or is not part of an array formula range. @@ -87,7 +89,7 @@ The following methods will be added in version 1.7.9 or is part of an array formula range or not. getArrayFormulaRange() Use to retrieve an array formula range. -The following methods will be changed in version 1.7.9 +The following methods will be changed in version 1.8.0 setValue() The logic behind this will be modified to store formula values in the new cell property structure, but it will still perform the same function. From af01842f786ccfd5e6d96a42166dca6fc2bb6b9a Mon Sep 17 00:00:00 2001 From: jgilliland Date: Tue, 16 Apr 2013 17:27:20 -0500 Subject: [PATCH 030/467] Remove empty row from empty charts and images --- Classes/PHPExcel/Writer/HTML.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index f50412e5a..6c44ca40f 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -520,9 +520,9 @@ private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) $chartCol = PHPExcel_Cell::columnIndexFromString($chartTL[0]); if ($chartTL[1] > $rowMax) { $rowMax = $chartTL[1]; - } - if ($chartCol > PHPExcel_Cell::columnIndexFromString($colMax)) { - $colMax = $chartTL[0]; + if ($chartCol > PHPExcel_Cell::columnIndexFromString($colMax)) { + $colMax = $chartTL[0]; + } } } } @@ -534,15 +534,15 @@ private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) $imageCol = PHPExcel_Cell::columnIndexFromString($imageTL[0]); if ($imageTL[1] > $rowMax) { $rowMax = $imageTL[1]; - } - if ($imageCol > PHPExcel_Cell::columnIndexFromString($colMax)) { - $colMax = $imageTL[0]; + if ($imageCol > PHPExcel_Cell::columnIndexFromString($colMax)) { + $colMax = $imageTL[0]; + } } } } $html = ''; $colMax++; - while ($row <= $rowMax) { + while ($row < $rowMax) { $html .= '
'; for ($col = 'A'; $col != $colMax; ++$col) { $html .= ', $tbodyStart = $rowMin; - $tbodyEnd = $rowMax; $theadStart = $theadEnd = 0; // default: no no if ($sheet->getPageSetup()->isRowsToRepeatAtTopSet()) { $rowsToRepeatAtTop = $sheet->getPageSetup()->getRowsToRepeatAtTop(); @@ -441,14 +440,12 @@ public function generateSheetData() { if ($row == $theadEnd) { $html .= ' ' . PHP_EOL; } - - // ? - if ($row == $tbodyEnd) { - $html .= ' ' . PHP_EOL; - } } $html .= $this->_extendRowsForChartsAndImages($sheet, $row); + // Close table body. + $html .= ' ' . PHP_EOL; + // Write table footer $html .= $this->_generateTableFooter(); From e76673bcc084d48f2d7434362653be571d9cd76e Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 20 Apr 2013 11:46:20 +0100 Subject: [PATCH 032/467] Bugfix: (Shanto) Work item GH-161 - Fix: Hyperlinks break when removing rows --- Classes/PHPExcel/ReferenceHelper.php | 4 +++- changelog.txt | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index ef990bdaa..6fc96ecba 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -274,7 +274,9 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P $pSheet->setComments($aNewComments); // replace the comments array // Update worksheet: hyperlinks - $aHyperlinkCollection = array_reverse($pSheet->getHyperlinkCollection(), true); + $aHyperlinkCollection = $pNumCols > 0 || $pNumRows > 0 ? + array_reverse($pSheet->getHyperlinkCollection(), true) : + $pSheet->getHyperlinkCollection(); foreach ($aHyperlinkCollection as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { diff --git a/changelog.txt b/changelog.txt index 16a7ac10d..bcdccbae2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -57,6 +57,7 @@ Fixed in develop branch for release v1.7.9: - Bugfix: (ccorliss) Work item GH-105 - Fixed number format fatal error - Bugfix: (MBaker) - Add DROP TABLE in destructor for SQLite and SQLite3 cache controllers - Bugfix: (alexgann) Work item GH-154 - Fix merged-cell borders on HTML/PDF output +- Bugfix: (Shanto) Work item GH-161 - Fix: Hyperlinks break when removing rows -------------------------------------------------------------------------------- From ab01a6c6dc85842953d335821f66d3ce6525e353 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 20 Apr 2013 23:53:25 +0100 Subject: [PATCH 033/467] Additional work on bugfix GH-161: Hyperlinks break when removing rows --- Classes/PHPExcel/ReferenceHelper.php | 27 ++++++++++++++++++++++++--- changelog.txt | 1 + 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 6fc96ecba..32b32784d 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -68,6 +68,26 @@ public static function getInstance() { protected function __construct() { } + private function cellSort($a, $b) { + list($ac,$ar) = sscanf($a,'%[A-Z]%d'); + list($bc,$br) = sscanf($b,'%[A-Z]%d'); + + if ($ar == $br) { + return strcasecmp(sprintf('%03s',$ac), sprintf('%03s',$bc)); + } + return ($ar < $br) ? -1 : 1; + } + + private function cellReverseSort($a, $b) { + list($ac,$ar) = sscanf($a,'%[A-Z]%d'); + list($bc,$br) = sscanf($b,'%[A-Z]%d'); + + if ($ar == $br) { + return 1 - strcasecmp(sprintf('%03s',$ac), sprintf('%03s',$bc)); + } + return ($ar < $br) ? 1 : -1; + } + /** * Insert a new column, updating all possible related data * @@ -274,9 +294,10 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P $pSheet->setComments($aNewComments); // replace the comments array // Update worksheet: hyperlinks - $aHyperlinkCollection = $pNumCols > 0 || $pNumRows > 0 ? - array_reverse($pSheet->getHyperlinkCollection(), true) : - $pSheet->getHyperlinkCollection(); + $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); foreach ($aHyperlinkCollection as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { diff --git a/changelog.txt b/changelog.txt index bcdccbae2..cfe17493a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -58,6 +58,7 @@ Fixed in develop branch for release v1.7.9: - Bugfix: (MBaker) - Add DROP TABLE in destructor for SQLite and SQLite3 cache controllers - Bugfix: (alexgann) Work item GH-154 - Fix merged-cell borders on HTML/PDF output - Bugfix: (Shanto) Work item GH-161 - Fix: Hyperlinks break when removing rows +- Bugfix: (neclimdul) Work item GH-166 - Fix Extra Table Row From Images and Charts -------------------------------------------------------------------------------- From 097ae1706eb3d82c9dab4f78c38cc54cd7921d77 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 21 Apr 2013 16:03:25 +0100 Subject: [PATCH 034/467] Additional work on GH-161 - Fix: Hyperlinks break when removing rows --- Classes/PHPExcel/ReferenceHelper.php | 33 ++++++++++++---------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 32b32784d..8b986c08e 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -73,7 +73,7 @@ private function cellSort($a, $b) { list($bc,$br) = sscanf($b,'%[A-Z]%d'); if ($ar == $br) { - return strcasecmp(sprintf('%03s',$ac), sprintf('%03s',$bc)); + return strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); } return ($ar < $br) ? -1 : 1; } @@ -83,7 +83,7 @@ private function cellReverseSort($a, $b) { list($bc,$br) = sscanf($b,'%[A-Z]%d'); if ($ar == $br) { - return 1 - strcasecmp(sprintf('%03s',$ac), sprintf('%03s',$bc)); + return 1 - strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); } return ($ar < $br) ? 1 : -1; } @@ -106,7 +106,6 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString( $pBefore ); $beforeColumnIndex = PHPExcel_Cell::columnIndexFromString($beforeColumn); - // Clear cells if we are removing columns or rows $highestColumn = $pSheet->getHighestColumn(); $highestRow = $pSheet->getHighestRow(); @@ -139,7 +138,6 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } } - // Loop through cells, bottom-up, and change cell coordinates while (($cellID = $remove ? array_shift($aCellCollection) : array_pop($aCellCollection))) { $cell = $pSheet->getCell($cellID); @@ -184,7 +182,6 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } } - // Duplicate styles for the newly inserted cells $highestColumn = $pSheet->getHighestColumn(); $highestRow = $pSheet->getHighestRow(); @@ -236,7 +233,6 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } } - // Update worksheet: column dimensions $aColumnDimensions = array_reverse($pSheet->getColumnDimensions(), true); if (!empty($aColumnDimensions)) { @@ -250,7 +246,6 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P $pSheet->refreshColumnDimensions(); } - // Update worksheet: row dimensions $aRowDimensions = array_reverse($pSheet->getRowDimensions(), true); if (!empty($aRowDimensions)) { @@ -273,9 +268,11 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } } - // Update worksheet: breaks - $aBreaks = array_reverse($pSheet->getBreaks(), true); + $aBreaks = $pSheet->getBreaks(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellSort')); foreach ($aBreaks as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { @@ -306,9 +303,11 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } } - // Update worksheet: data validations - $aDataValidationCollection = array_reverse($pSheet->getDataValidationCollection(), true); + $aDataValidationCollection = $pSheet->getDataValidationCollection(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); foreach ($aDataValidationCollection as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { @@ -317,7 +316,6 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } } - // Update worksheet: merge cells $aMergeCells = $pSheet->getMergeCells(); $aNewMergeCells = array(); // the new array of all merge cells @@ -327,9 +325,11 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } $pSheet->setMergeCells($aNewMergeCells); // replace the merge cells array - // Update worksheet: protected cells - $aProtectedCells = array_reverse($pSheet->getProtectedCells(), true); + $aProtectedCells = $pSheet->getProtectedCells(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellSort')); foreach ($aProtectedCells as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { @@ -338,7 +338,6 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } } - // Update worksheet: autofilter $autoFilter = $pSheet->getAutoFilter(); $autoFilterRange = $autoFilter->getRange(); @@ -397,19 +396,16 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P $pSheet->setAutoFilter( $this->updateCellReference($autoFilterRange, $pBefore, $pNumCols, $pNumRows) ); } - // Update worksheet: freeze pane if ($pSheet->getFreezePane() != '') { $pSheet->freezePane( $this->updateCellReference($pSheet->getFreezePane(), $pBefore, $pNumCols, $pNumRows) ); } - // Page setup if ($pSheet->getPageSetup()->isPrintAreaSet()) { $pSheet->getPageSetup()->setPrintArea( $this->updateCellReference($pSheet->getPageSetup()->getPrintArea(), $pBefore, $pNumCols, $pNumRows) ); } - // Update worksheet: drawings $aDrawings = $pSheet->getDrawingCollection(); foreach ($aDrawings as $objDrawing) { @@ -419,7 +415,6 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } } - // Update workbook: named ranges if (count($pSheet->getParent()->getNamedRanges()) > 0) { foreach ($pSheet->getParent()->getNamedRanges() as $namedRange) { From 15bfe6b8d544008a27d592606ba308bf6427636d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 21 Apr 2013 16:27:35 +0100 Subject: [PATCH 035/467] Update examples --- Examples/33chartcreate-area.php | 6 ++---- Examples/33chartcreate-bar-stacked.php | 6 ++---- Examples/33chartcreate-bar.php | 6 ++---- Examples/33chartcreate-column-2.php | 6 ++---- Examples/33chartcreate-column.php | 6 ++---- Examples/33chartcreate-composite-chart.php | 6 ++---- Examples/33chartcreate-line.php | 6 ++---- Examples/33chartcreate-multiple-charts.php | 6 ++---- Examples/33chartcreate-pie.php | 6 ++---- Examples/33chartcreate-radar.php | 6 ++---- 10 files changed, 20 insertions(+), 40 deletions(-) diff --git a/Examples/33chartcreate-area.php b/Examples/33chartcreate-area.php index 1e53b6041..925ea0adf 100644 --- a/Examples/33chartcreate-area.php +++ b/Examples/33chartcreate-area.php @@ -36,11 +36,9 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +require_once '../Classes/PHPExcel.php'; + $objPHPExcel = new PHPExcel(); $objWorksheet = $objPHPExcel->getActiveSheet(); diff --git a/Examples/33chartcreate-bar-stacked.php b/Examples/33chartcreate-bar-stacked.php index f6465ee76..0c604bb35 100644 --- a/Examples/33chartcreate-bar-stacked.php +++ b/Examples/33chartcreate-bar-stacked.php @@ -36,11 +36,9 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +require_once '../Classes/PHPExcel.php'; + $objPHPExcel = new PHPExcel(); $objWorksheet = $objPHPExcel->getActiveSheet(); diff --git a/Examples/33chartcreate-bar.php b/Examples/33chartcreate-bar.php index 764942f09..daefd6642 100644 --- a/Examples/33chartcreate-bar.php +++ b/Examples/33chartcreate-bar.php @@ -36,11 +36,9 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +require_once '../Classes/PHPExcel.php'; + $objPHPExcel = new PHPExcel(); $objWorksheet = $objPHPExcel->getActiveSheet(); diff --git a/Examples/33chartcreate-column-2.php b/Examples/33chartcreate-column-2.php index 921049922..959712b52 100644 --- a/Examples/33chartcreate-column-2.php +++ b/Examples/33chartcreate-column-2.php @@ -36,11 +36,9 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +require_once '../Classes/PHPExcel.php'; + $objPHPExcel = new PHPExcel(); $objWorksheet = $objPHPExcel->getActiveSheet(); diff --git a/Examples/33chartcreate-column.php b/Examples/33chartcreate-column.php index 6feacf9ad..4c2dae64b 100644 --- a/Examples/33chartcreate-column.php +++ b/Examples/33chartcreate-column.php @@ -36,11 +36,9 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +require_once '../Classes/PHPExcel.php'; + $objPHPExcel = new PHPExcel(); $objWorksheet = $objPHPExcel->getActiveSheet(); diff --git a/Examples/33chartcreate-composite-chart.php b/Examples/33chartcreate-composite-chart.php index 14496f1c9..a9785ff13 100644 --- a/Examples/33chartcreate-composite-chart.php +++ b/Examples/33chartcreate-composite-chart.php @@ -36,11 +36,9 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +require_once '../Classes/PHPExcel.php'; + $objPHPExcel = new PHPExcel(); $objWorksheet = $objPHPExcel->getActiveSheet(); diff --git a/Examples/33chartcreate-line.php b/Examples/33chartcreate-line.php index 8fc9714e7..4745982db 100644 --- a/Examples/33chartcreate-line.php +++ b/Examples/33chartcreate-line.php @@ -36,11 +36,9 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +require_once '../Classes/PHPExcel.php'; + $objPHPExcel = new PHPExcel(); $objWorksheet = $objPHPExcel->getActiveSheet(); diff --git a/Examples/33chartcreate-multiple-charts.php b/Examples/33chartcreate-multiple-charts.php index a8943eec1..041e03ae1 100644 --- a/Examples/33chartcreate-multiple-charts.php +++ b/Examples/33chartcreate-multiple-charts.php @@ -36,11 +36,9 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +require_once '../Classes/PHPExcel.php'; + $objPHPExcel = new PHPExcel(); $objWorksheet = $objPHPExcel->getActiveSheet(); diff --git a/Examples/33chartcreate-pie.php b/Examples/33chartcreate-pie.php index fe68ba2c3..ce9825cb1 100644 --- a/Examples/33chartcreate-pie.php +++ b/Examples/33chartcreate-pie.php @@ -36,11 +36,9 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +require_once '../Classes/PHPExcel.php'; + $objPHPExcel = new PHPExcel(); $objWorksheet = $objPHPExcel->getActiveSheet(); diff --git a/Examples/33chartcreate-radar.php b/Examples/33chartcreate-radar.php index a1bb413ac..b3c226aa6 100644 --- a/Examples/33chartcreate-radar.php +++ b/Examples/33chartcreate-radar.php @@ -36,11 +36,9 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +require_once '../Classes/PHPExcel.php'; + $objPHPExcel = new PHPExcel(); $objWorksheet = $objPHPExcel->getActiveSheet(); From db1fcd5cd6f7a85f0129c0daa0af53bc408fbe7c Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 23 Apr 2013 17:42:40 +0100 Subject: [PATCH 036/467] Additional work on GH-161 for Breaks --- Classes/PHPExcel/ReferenceHelper.php | 40 +++++++++++++++++----------- Classes/PHPExcel/Worksheet.php | 14 +++++++--- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 8b986c08e..5b17054d5 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -68,7 +68,15 @@ public static function getInstance() { protected function __construct() { } - private function cellSort($a, $b) { + public static function columnSort($a, $b) { + return strcasecmp(strlen($a) . $a, strlen($b) . $b); + } + + public static function columnReverseSort($a, $b) { + return 1 - strcasecmp(strlen($a) . $a, strlen($b) . $b); + } + + public static function cellSort($a, $b) { list($ac,$ar) = sscanf($a,'%[A-Z]%d'); list($bc,$br) = sscanf($b,'%[A-Z]%d'); @@ -78,7 +86,7 @@ private function cellSort($a, $b) { return ($ar < $br) ? -1 : 1; } - private function cellReverseSort($a, $b) { + public static function cellReverseSort($a, $b) { list($ac,$ar) = sscanf($a,'%[A-Z]%d'); list($bc,$br) = sscanf($b,'%[A-Z]%d'); @@ -270,14 +278,14 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P // Update worksheet: breaks $aBreaks = $pSheet->getBreaks(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellSort')); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellSort')); foreach ($aBreaks as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { - $pSheet->setBreak( $newReference, $value ); - $pSheet->setBreak( $key, PHPExcel_Worksheet::BREAK_NONE ); + $pSheet->setBreak($newReference, $value) + ->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); } } @@ -292,9 +300,9 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P // Update worksheet: hyperlinks $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); foreach ($aHyperlinkCollection as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { @@ -305,9 +313,9 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P // Update worksheet: data validations $aDataValidationCollection = $pSheet->getDataValidationCollection(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); foreach ($aDataValidationCollection as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { @@ -327,9 +335,9 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P // Update worksheet: protected cells $aProtectedCells = $pSheet->getProtectedCells(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellSort')); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellSort')); foreach ($aProtectedCells as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 9791ead2b..51cb4e797 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1604,7 +1604,13 @@ public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE $pCell = strtoupper($pCell); if ($pCell != '') { - $this->_breaks[$pCell] = $pBreak; + if ($pBreak == PHPExcel_Worksheet::BREAK_NONE) { + if (isset($this->_breaks[$pCell])) { + unset($this->_breaks[$pCell]); + } + } else { + $this->_breaks[$pCell] = $pBreak; + } } else { throw new PHPExcel_Exception('No cell coordinate specified.'); } @@ -2432,9 +2438,9 @@ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormul if ($formatData) { $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString( - $returnValue[$rRef][$cRef], - ($style->getNumberFormat()) ? - $style->getNumberFormat()->getFormatCode() : + $returnValue[$rRef][$cRef], + ($style->getNumberFormat()) ? + $style->getNumberFormat()->getFormatCode() : PHPExcel_Style_NumberFormat::FORMAT_GENERAL ); } From 7f7b5206522c21567fcb81bff77320b5c6613209 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 25 Apr 2013 17:53:29 +0100 Subject: [PATCH 037/467] Some refactoring of insert/delete row/column reference methods --- Classes/PHPExcel/Comment.php | 13 +- Classes/PHPExcel/ReferenceHelper.php | 261 +++++++++++------- .../Classes/PHPExcel/ReferenceHelperTest.php | 58 ++++ 3 files changed, 234 insertions(+), 98 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/ReferenceHelperTest.php diff --git a/Classes/PHPExcel/Comment.php b/Classes/PHPExcel/Comment.php index 47db7ecd8..e9f257814 100644 --- a/Classes/PHPExcel/Comment.php +++ b/Classes/PHPExcel/Comment.php @@ -106,10 +106,10 @@ class PHPExcel_Comment implements PHPExcel_IComparable public function __construct() { // Initialise variables - $this->_author = 'Author'; - $this->_text = new PHPExcel_RichText(); - $this->_fillColor = new PHPExcel_Style_Color('FFFFFFE1'); - $this->_alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + $this->_author = 'Author'; + $this->_text = new PHPExcel_RichText(); + $this->_fillColor = new PHPExcel_Style_Color('FFFFFFE1'); + $this->_alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; } /** @@ -314,4 +314,9 @@ public function __clone() { } } } + + public function __toString() { + return $this->_text->getPlainText(); + } + } diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 5b17054d5..f301c5595 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -96,22 +96,176 @@ public static function cellReverseSort($a, $b) { return ($ar < $br) ? 1 : -1; } + private static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols) { + list($cellColumn, $cellRow) = PHPExcel_Cell::coordinateFromString($cellAddress); + $cellColumnIndex = PHPExcel_Cell::columnIndexFromString($cellColumn); + // Is cell within the range of rows/columns if we're deleting + if ($pNumRows < 0 && + ($cellRow >= ($beforeRow + $pNumRows)) && + ($cellRow < $beforeRow)) { + return TRUE; + } elseif ($pNumCols < 0 && + ($cellColumnIndex >= ($beforeColumnIndex + $pNumCols)) && + ($cellColumnIndex < $beforeColumnIndex)) { + return TRUE; + } + return FALSE; + } + + protected function _adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aBreaks = $pSheet->getBreaks(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellSort')); + + foreach ($aBreaks as $key => $value) { + if (self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { + // If we're deleting, then clear any defined breaks that are within the range + // of rows/columns that we're deleting + $pSheet->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); + } else { + // Otherwise update any affected breaks by inserting a new break at the appropriate point + // and removing the old affected break + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setBreak($newReference, $value) + ->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); + } + } + } + } + + protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aComments = $pSheet->getComments(); + $aNewComments = array(); // the new array of all comments + + foreach ($aComments as $key => &$value) { + // Any comments inside a deleted range will be ignored + if (!self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { + // Otherwise build a new array of comments indexed by the adjusted cell reference + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + $aNewComments[$newReference] = $value; + } + } + // Replace the comments array with the new set of comments + $pSheet->setComments($aNewComments); + } + + protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); + + foreach ($aHyperlinkCollection as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setHyperlink( $newReference, $value ); + $pSheet->setHyperlink( $key, null ); + } + } + } + + protected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aDataValidationCollection = $pSheet->getDataValidationCollection(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); + foreach ($aDataValidationCollection as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setDataValidation( $newReference, $value ); + $pSheet->setDataValidation( $key, null ); + } + } + } + + protected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aMergeCells = $pSheet->getMergeCells(); + $aNewMergeCells = array(); // the new array of all merge cells + foreach ($aMergeCells as $key => &$value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + $aNewMergeCells[$newReference] = $newReference; + } + $pSheet->setMergeCells($aNewMergeCells); // replace the merge cells array + } + + protected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aProtectedCells = $pSheet->getProtectedCells(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellSort')); + foreach ($aProtectedCells as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->protectCells( $newReference, $value, true ); + $pSheet->unprotectCells( $key ); + } + } + } + + protected function _adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aColumnDimensions = array_reverse($pSheet->getColumnDimensions(), true); + if (!empty($aColumnDimensions)) { + foreach ($aColumnDimensions as $objColumnDimension) { + $newReference = $this->updateCellReference($objColumnDimension->getColumnIndex() . '1', $pBefore, $pNumCols, $pNumRows); + list($newReference) = PHPExcel_Cell::coordinateFromString($newReference); + if ($objColumnDimension->getColumnIndex() != $newReference) { + $objColumnDimension->setColumnIndex($newReference); + } + } + $pSheet->refreshColumnDimensions(); + } + } + + protected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aRowDimensions = array_reverse($pSheet->getRowDimensions(), true); + if (!empty($aRowDimensions)) { + foreach ($aRowDimensions as $objRowDimension) { + $newReference = $this->updateCellReference('A' . $objRowDimension->getRowIndex(), $pBefore, $pNumCols, $pNumRows); + list(, $newReference) = PHPExcel_Cell::coordinateFromString($newReference); + if ($objRowDimension->getRowIndex() != $newReference) { + $objRowDimension->setRowIndex($newReference); + } + } + $pSheet->refreshRowDimensions(); + + $copyDimension = $pSheet->getRowDimension($beforeRow - 1); + for ($i = $beforeRow; $i <= $beforeRow - 1 + $pNumRows; ++$i) { + $newDimension = $pSheet->getRowDimension($i); + $newDimension->setRowHeight($copyDimension->getRowHeight()); + $newDimension->setVisible($copyDimension->getVisible()); + $newDimension->setOutlineLevel($copyDimension->getOutlineLevel()); + $newDimension->setCollapsed($copyDimension->getCollapsed()); + } + } + } + /** - * Insert a new column, updating all possible related data + * Insert a new column or row, updating all possible related data * * @param int $pBefore Insert before this one * @param int $pNumCols Number of columns to insert * @param int $pNumRows Number of rows to insert * @throws PHPExcel_Exception */ - public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, PHPExcel_Worksheet $pSheet = null) { + public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, PHPExcel_Worksheet $pSheet = NULL) + { $remove = ($pNumCols < 0 || $pNumRows < 0); $aCellCollection = $pSheet->getCellCollection(); // Get coordinates of $pBefore $beforeColumn = 'A'; $beforeRow = 1; - list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString( $pBefore ); + list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString($pBefore); $beforeColumnIndex = PHPExcel_Cell::columnIndexFromString($beforeColumn); // Clear cells if we are removing columns or rows @@ -242,109 +396,28 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } // Update worksheet: column dimensions - $aColumnDimensions = array_reverse($pSheet->getColumnDimensions(), true); - if (!empty($aColumnDimensions)) { - foreach ($aColumnDimensions as $objColumnDimension) { - $newReference = $this->updateCellReference($objColumnDimension->getColumnIndex() . '1', $pBefore, $pNumCols, $pNumRows); - list($newReference) = PHPExcel_Cell::coordinateFromString($newReference); - if ($objColumnDimension->getColumnIndex() != $newReference) { - $objColumnDimension->setColumnIndex($newReference); - } - } - $pSheet->refreshColumnDimensions(); - } + $this->_adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: row dimensions - $aRowDimensions = array_reverse($pSheet->getRowDimensions(), true); - if (!empty($aRowDimensions)) { - foreach ($aRowDimensions as $objRowDimension) { - $newReference = $this->updateCellReference('A' . $objRowDimension->getRowIndex(), $pBefore, $pNumCols, $pNumRows); - list(, $newReference) = PHPExcel_Cell::coordinateFromString($newReference); - if ($objRowDimension->getRowIndex() != $newReference) { - $objRowDimension->setRowIndex($newReference); - } - } - $pSheet->refreshRowDimensions(); - - $copyDimension = $pSheet->getRowDimension($beforeRow - 1); - for ($i = $beforeRow; $i <= $beforeRow - 1 + $pNumRows; ++$i) { - $newDimension = $pSheet->getRowDimension($i); - $newDimension->setRowHeight($copyDimension->getRowHeight()); - $newDimension->setVisible($copyDimension->getVisible()); - $newDimension->setOutlineLevel($copyDimension->getOutlineLevel()); - $newDimension->setCollapsed($copyDimension->getCollapsed()); - } - } + $this->_adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); - // Update worksheet: breaks - $aBreaks = $pSheet->getBreaks(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellSort')); - foreach ($aBreaks as $key => $value) { - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - if ($key != $newReference) { - $pSheet->setBreak($newReference, $value) - ->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); - } - } + // Update worksheet: page breaks + $this->_adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); - // Update worksheet: comments - $aComments = $pSheet->getComments(); - $aNewComments = array(); // the new array of all comments - foreach ($aComments as $key => &$value) { - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - $aNewComments[$newReference] = $value; - } - $pSheet->setComments($aNewComments); // replace the comments array + // Update worksheet: comments + $this->_adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: hyperlinks - $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); - foreach ($aHyperlinkCollection as $key => $value) { - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - if ($key != $newReference) { - $pSheet->setHyperlink( $newReference, $value ); - $pSheet->setHyperlink( $key, null ); - } - } + $this->_adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: data validations - $aDataValidationCollection = $pSheet->getDataValidationCollection(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); - foreach ($aDataValidationCollection as $key => $value) { - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - if ($key != $newReference) { - $pSheet->setDataValidation( $newReference, $value ); - $pSheet->setDataValidation( $key, null ); - } - } + $this->_adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: merge cells - $aMergeCells = $pSheet->getMergeCells(); - $aNewMergeCells = array(); // the new array of all merge cells - foreach ($aMergeCells as $key => &$value) { - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - $aNewMergeCells[$newReference] = $newReference; - } - $pSheet->setMergeCells($aNewMergeCells); // replace the merge cells array + $this->_adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: protected cells - $aProtectedCells = $pSheet->getProtectedCells(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellSort')); - foreach ($aProtectedCells as $key => $value) { - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - if ($key != $newReference) { - $pSheet->protectCells( $newReference, $value, true ); - $pSheet->unprotectCells( $key ); - } - } + $this->_adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: autofilter $autoFilter = $pSheet->getAutoFilter(); diff --git a/unitTests/Classes/PHPExcel/ReferenceHelperTest.php b/unitTests/Classes/PHPExcel/ReferenceHelperTest.php new file mode 100644 index 000000000..f37db692e --- /dev/null +++ b/unitTests/Classes/PHPExcel/ReferenceHelperTest.php @@ -0,0 +1,58 @@ + $value) { + $this->assertEquals($columnExpectedResult[$key], $value); + } + } + + public function testColumnReverseSort() + { + $columnBase = $columnExpectedResult = array( + 'A','B','Z', + 'AA','AB','AZ', + 'BA','BB','BZ', + 'ZA','ZB','ZZ', + 'AAA','AAB','AAZ', + 'ABA','ABB','ABZ', + 'AZA','AZB','AZZ', + 'BAA','BAB','BAZ', + 'BBA','BBB','BBZ', + 'BZA','BZB','BZZ' + ); + shuffle($columnBase); + $columnExpectedResult = array_reverse($columnExpectedResult); + usort($columnBase, array('PHPExcel_ReferenceHelper','columnReverseSort')); + foreach($columnBase as $key => $value) { + $this->assertEquals($columnExpectedResult[$key], $value); + } + } + +} From d96364fda65ef361f01090d49e1a47a984518b62 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 25 Apr 2013 23:44:15 +0100 Subject: [PATCH 038/467] PHPDoc blocks --- Classes/PHPExcel/ReferenceHelper.php | 99 ++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index f301c5595..f6deb0423 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -96,6 +96,16 @@ public static function cellReverseSort($a, $b) { return ($ar < $br) ? 1 : -1; } + /** + * Test whether a cell address falls within a defined range of cells + * + * @param string $cellAddress Address of the cell we're testing + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @return boolean + */ private static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols) { list($cellColumn, $cellRow) = PHPExcel_Cell::coordinateFromString($cellAddress); $cellColumnIndex = PHPExcel_Cell::columnIndexFromString($cellColumn); @@ -112,6 +122,16 @@ private static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNum return FALSE; } + /** + * Update page breaks when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ protected function _adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aBreaks = $pSheet->getBreaks(); @@ -136,6 +156,16 @@ protected function _adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $befo } } + /** + * Update cell comments when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aComments = $pSheet->getComments(); @@ -153,6 +183,16 @@ protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumC $pSheet->setComments($aNewComments); } + /** + * Update hyperlinks when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); @@ -169,6 +209,16 @@ protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNu } } + /** + * Update data validations when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ protected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aDataValidationCollection = $pSheet->getDataValidationCollection(); @@ -184,6 +234,16 @@ protected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, } } + /** + * Update merged cells when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ protected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aMergeCells = $pSheet->getMergeCells(); @@ -195,6 +255,16 @@ protected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNu $pSheet->setMergeCells($aNewMergeCells); // replace the merge cells array } + /** + * Update protected cells when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ protected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aProtectedCells = $pSheet->getProtectedCells(); @@ -210,6 +280,16 @@ protected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, } } + /** + * Update column dimensions when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ protected function _adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aColumnDimensions = array_reverse($pSheet->getColumnDimensions(), true); @@ -225,6 +305,16 @@ protected function _adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex } } + /** + * Update row dimensions when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ protected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aRowDimensions = array_reverse($pSheet->getRowDimensions(), true); @@ -252,10 +342,11 @@ protected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $ /** * Insert a new column or row, updating all possible related data * - * @param int $pBefore Insert before this one - * @param int $pNumCols Number of columns to insert - * @param int $pNumRows Number of rows to insert - * @throws PHPExcel_Exception + * @param string $pBefore Insert before this cell address (e.g. 'A1') + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @throws PHPExcel_Exception */ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, PHPExcel_Worksheet $pSheet = NULL) { From 8a05ee88964a659fd66d2f730deba519a6c6a0c9 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 26 Apr 2013 07:46:50 +0100 Subject: [PATCH 039/467] Added Docblocks for cell address and column sort callback functions --- Classes/PHPExcel/ReferenceHelper.php | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index f6deb0423..6f8c1d433 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -68,14 +68,38 @@ public static function getInstance() { protected function __construct() { } + /** + * Compare two column addresses + * Intended for use as a Callback function for sorting column addresses by column + * + * @param string $a First column to test (e.g. 'AA') + * @param string $b Second column to test (e.g. 'Z') + * @return integer + */ public static function columnSort($a, $b) { return strcasecmp(strlen($a) . $a, strlen($b) . $b); } + /** + * Compare two column addresses + * Intended for use as a Callback function for reverse sorting column addresses by column + * + * @param string $a First column to test (e.g. 'AA') + * @param string $b Second column to test (e.g. 'Z') + * @return integer + */ public static function columnReverseSort($a, $b) { return 1 - strcasecmp(strlen($a) . $a, strlen($b) . $b); } + /** + * Compare two cell addresses + * Intended for use as a Callback function for sorting cell addresses by column and row + * + * @param string $a First cell to test (e.g. 'AA1') + * @param string $b Second cell to test (e.g. 'Z1') + * @return integer + */ public static function cellSort($a, $b) { list($ac,$ar) = sscanf($a,'%[A-Z]%d'); list($bc,$br) = sscanf($b,'%[A-Z]%d'); @@ -86,6 +110,14 @@ public static function cellSort($a, $b) { return ($ar < $br) ? -1 : 1; } + /** + * Compare two cell addresses + * Intended for use as a Callback function for sorting cell addresses by column and row + * + * @param string $a First cell to test (e.g. 'AA1') + * @param string $b Second cell to test (e.g. 'Z1') + * @return integer + */ public static function cellReverseSort($a, $b) { list($ac,$ar) = sscanf($a,'%[A-Z]%d'); list($bc,$br) = sscanf($b,'%[A-Z]%d'); From 8debf76a8a58131da6f3f82fe792359123dcb1bc Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 26 Apr 2013 12:44:47 +0100 Subject: [PATCH 040/467] Minor performance tweaks --- Classes/PHPExcel/CachedObjectStorage/CacheBase.php | 8 ++++---- Classes/PHPExcel/Calculation.php | 4 ++-- Classes/PHPExcel/Cell.php | 6 +++--- Classes/PHPExcel/ReferenceHelper.php | 10 +++++----- Classes/PHPExcel/Worksheet/AutoFilter.php | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index 6dd6c1a5a..c4b578179 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -177,7 +177,7 @@ public function getCellList() { public function getSortedCellList() { $sortKeys = array(); foreach ($this->getCellList() as $coord) { - list($column,$row) = sscanf($coord,'%[A-Z]%d'); + sscanf($coord,'%[A-Z]%d', $column, $row); $sortKeys[sprintf('%09d%3s',$row,$column)] = $coord; } ksort($sortKeys); @@ -198,7 +198,7 @@ public function getHighestRowAndColumn() $col = array('A' => '1A'); $row = array(1); foreach ($this->getCellList() as $coord) { - list($c,$r) = sscanf($coord,'%[A-Z]%d'); + sscanf($coord,'%[A-Z]%d', $c, $r); $row[$r] = $r; $col[$c] = strlen($c).$c; } @@ -221,13 +221,13 @@ public function getCurrentAddress() public function getCurrentColumn() { - list($column,$row) = sscanf($this->_currentObjectID, '%[A-Z]%d'); + sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); return $column; } public function getCurrentRow() { - list($column,$row) = sscanf($this->_currentObjectID, '%[A-Z]%d'); + sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); return $row; } diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index c98e50cb7..93f77d74d 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -3621,7 +3621,7 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = N $pRange = $pSheetName.'!'.$pRange; if (!isset($aReferences[1])) { // Single cell in range - list($currentCol,$currentRow) = sscanf($aReferences[0],'%[A-Z]%d'); + sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow); $cellValue = NULL; if ($pSheet->cellExists($aReferences[0])) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); @@ -3632,7 +3632,7 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = N // Extract cell data for all cells in the range foreach ($aReferences as $reference) { // Extract range - list($currentCol,$currentRow) = sscanf($reference,'%[A-Z]%d'); + sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow); $cellValue = NULL; if ($pSheet->cellExists($reference)) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index dbd7a822f..27fb91479 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -822,8 +822,8 @@ public static function extractAllCellReferencesInRange($pRange = 'A1') { // Range... list($rangeStart, $rangeEnd) = $range; - list($startCol, $startRow) = sscanf($rangeStart,'%[A-Z]%d'); - list($endCol, $endRow) = sscanf($rangeEnd,'%[A-Z]%d'); + sscanf($rangeStart,'%[A-Z]%d', $startCol, $startRow); + sscanf($rangeEnd,'%[A-Z]%d', $endCol, $endRow); $endCol++; // Current data @@ -845,7 +845,7 @@ public static function extractAllCellReferencesInRange($pRange = 'A1') { // Sort the result by column and row $sortKeys = array(); foreach (array_unique($returnValue) as $coord) { - list($column,$row) = sscanf($coord,'%[A-Z]%d'); + sscanf($coord,'%[A-Z]%d', $column, $row); $sortKeys[sprintf('%3s%09d',$column,$row)] = $coord; } ksort($sortKeys); diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 6f8c1d433..94f21b326 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -101,8 +101,8 @@ public static function columnReverseSort($a, $b) { * @return integer */ public static function cellSort($a, $b) { - list($ac,$ar) = sscanf($a,'%[A-Z]%d'); - list($bc,$br) = sscanf($b,'%[A-Z]%d'); + sscanf($a,'%[A-Z]%d', $ac, $ar); + sscanf($b,'%[A-Z]%d', $bc, $br); if ($ar == $br) { return strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); @@ -119,8 +119,8 @@ public static function cellSort($a, $b) { * @return integer */ public static function cellReverseSort($a, $b) { - list($ac,$ar) = sscanf($a,'%[A-Z]%d'); - list($bc,$br) = sscanf($b,'%[A-Z]%d'); + sscanf($a,'%[A-Z]%d', $ac, $ar); + sscanf($b,'%[A-Z]%d', $bc, $br); if ($ar == $br) { return 1 - strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); @@ -549,7 +549,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P if ($pNumCols != 0) { $autoFilterColumns = array_keys($autoFilter->getColumns()); if (count($autoFilterColumns) > 0) { - list($column,$row) = sscanf($pBefore,'%[A-Z]%d'); + sscanf($pBefore,'%[A-Z]%d', $column, $row); $columnIndex = PHPExcel_Cell::columnIndexFromString($column); list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($autoFilterRange); if ($columnIndex <= $rangeEnd[0]) { diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index c39bfbf8a..ae05875e8 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -725,7 +725,7 @@ public function showHideRows() // Date based if ($dynamicRuleType{0} == 'M' || $dynamicRuleType{0} == 'Q') { // Month or Quarter - list($periodType,$period) = sscanf($dynamicRuleType,'%[A-Z]%d'); + sscanf($dynamicRuleType,'%[A-Z]%d', $periodType, $period); if ($periodType == 'M') { $ruleValues = array($period); } else { From 4d9258c9e17d082f418a7c8cbf331531abf14dbf Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 27 Apr 2013 13:42:14 +0100 Subject: [PATCH 041/467] Modified some of the examples to show rich text and additional download headers that might be needed --- Examples/01simple-download-xls.php | 8 ++++++++ Examples/02types-xls.php | 11 +++++++++++ Examples/02types.php | 13 +++++++++++++ 3 files changed, 32 insertions(+) diff --git a/Examples/01simple-download-xls.php b/Examples/01simple-download-xls.php index c1d670dc3..986e3ae66 100644 --- a/Examples/01simple-download-xls.php +++ b/Examples/01simple-download-xls.php @@ -75,6 +75,14 @@ header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="01simple.xls"'); header('Cache-Control: max-age=0'); +// If you're serving to IE 9, then the following may be needed +header('Cache-Control: max-age=1'); + +// If you're serving to IE over SSL, then the following may be needed +header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past +header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified +header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1 +header ('Pragma: public'); // HTTP/1.0 $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save('php://output'); diff --git a/Examples/02types-xls.php b/Examples/02types-xls.php index 905dc9d11..53d6cc528 100644 --- a/Examples/02types-xls.php +++ b/Examples/02types-xls.php @@ -109,6 +109,17 @@ $objPHPExcel->getActiveSheet()->setCellValue('A12', 'NULL') ->setCellValue('C12', NULL); +$objRichText = new PHPExcel_RichText(); +$objRichText->createText('你好 '); +$objPayable = $objRichText->createTextRun('你 好 吗?'); +$objPayable->getFont()->setBold(true); +$objPayable->getFont()->setItalic(true); +$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) ); + +$objRichText->createText(', unless specified otherwise on the invoice.'); + +$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Rich Text') + ->setCellValue('C13', $objRichText); $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true); diff --git a/Examples/02types.php b/Examples/02types.php index a66af9053..6a5ea9d4a 100644 --- a/Examples/02types.php +++ b/Examples/02types.php @@ -109,7 +109,20 @@ $objPHPExcel->getActiveSheet()->setCellValue('A12', 'NULL') ->setCellValue('C12', NULL); +$objRichText = new PHPExcel_RichText(); +$objRichText->createText('你好 '); +$objPayable = $objRichText->createTextRun('你 好 吗?'); +$objPayable->getFont()->setBold(true); +$objPayable->getFont()->setItalic(true); +$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) ); + +$objRichText->createText(', unless specified otherwise on the invoice.'); + +$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Rich Text') + ->setCellValue('C13', $objRichText); + + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true); From cfdd19e47ce59f96a854a5e178b8e01acc340d89 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 27 Apr 2013 14:49:08 +0100 Subject: [PATCH 042/467] Docblock modifications --- Classes/PHPExcel.php | 7 +++++- .../CachedObjectStorage/CacheBase.php | 20 ++++++++++++++++ .../PHPExcel/CachedObjectStorage/SQLite3.php | 23 +++++++++++++++++++ .../PHPExcel/CachedObjectStorageFactory.php | 4 ++++ Classes/PHPExcel/Writer/PDF.php | 19 +++++++++------ Classes/PHPExcel/Writer/PDF/Core.php | 2 +- Classes/PHPExcel/Writer/PDF/DomPDF.php | 2 +- Classes/PHPExcel/Writer/PDF/mPDF.php | 4 ++-- Classes/PHPExcel/Writer/PDF/tcPDF.php | 2 +- 9 files changed, 70 insertions(+), 13 deletions(-) diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index 19213c246..6090edf59 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -664,7 +664,7 @@ public function getCellXfByHashCode($pValue = '') /** * Check if style exists in style collection * - * @param PHPExcel_Style $style + * @param PHPExcel_Style $pCellStyle * @return boolean */ public function cellXfExists($pCellStyle = null) @@ -883,6 +883,11 @@ public function garbageCollect() } } + /** + * Return the unique ID value assigned to this spreadsheet workbook + * + * @return string + */ public function getID() { return $this->_uniqueID; } diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index c4b578179..249abaf54 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -86,6 +86,11 @@ public function __construct(PHPExcel_Worksheet $parent) { } // function __construct() + /** + * Return the parent worksheet for this cell collection + * + * @return PHPExcel_Worksheet + */ public function getParent() { return $this->_parent; @@ -214,17 +219,32 @@ public function getHighestRowAndColumn() } + /** + * Return the cell address of the currently active cell object + * + * @return string + */ public function getCurrentAddress() { return $this->_currentObjectID; } + /** + * Return the column address of the currently active cell object + * + * @return string + */ public function getCurrentColumn() { sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); return $column; } + /** + * Return the row address of the currently active cell object + * + * @return string + */ public function getCurrentRow() { sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index ecd802945..f573b0390 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -49,9 +49,32 @@ class PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_ */ private $_DBHandle = null; + /** + * Prepared statement for a SQLite3 select query + * + * @var SQLite3Stmt + */ private $_selectQuery; + + /** + * Prepared statement for a SQLite3 insert query + * + * @var SQLite3Stmt + */ private $_insertQuery; + + /** + * Prepared statement for a SQLite3 update query + * + * @var SQLite3Stmt + */ private $_updateQuery; + + /** + * Prepared statement for a SQLite3 delete query + * + * @var SQLite3Stmt + */ private $_deleteQuery; /** diff --git a/Classes/PHPExcel/CachedObjectStorageFactory.php b/Classes/PHPExcel/CachedObjectStorageFactory.php index f68431e39..0e7648d88 100644 --- a/Classes/PHPExcel/CachedObjectStorageFactory.php +++ b/Classes/PHPExcel/CachedObjectStorageFactory.php @@ -237,6 +237,10 @@ public static function getInstance(PHPExcel_Worksheet $parent) } // function getInstance() + /** + * Clear the cache storage + * + **/ public static function finalize() { self::$_cacheStorageMethod = NULL; diff --git a/Classes/PHPExcel/Writer/PDF.php b/Classes/PHPExcel/Writer/PDF.php index cacd9c730..d346f8afe 100644 --- a/Classes/PHPExcel/Writer/PDF.php +++ b/Classes/PHPExcel/Writer/PDF.php @@ -36,13 +36,18 @@ class PHPExcel_Writer_PDF { + /** + * The wrapper for the requested PDF rendering engine + * + * @var PHPExcel_Writer_PDF_Core + */ private $_renderer = NULL; /** * Instantiate a new renderer of the configured type within this container class * - * @param PHPExcel $phpExcel PHPExcel object - * @throws PHPExcel_Writer_Exception when PDF library is not configured + * @param PHPExcel $phpExcel PHPExcel object + * @throws PHPExcel_Writer_Exception when PDF library is not configured */ public function __construct(PHPExcel $phpExcel) { @@ -67,16 +72,16 @@ public function __construct(PHPExcel $phpExcel) /** - * Magic method to handle direct calls to the configured PDF renderer wrapper class + * Magic method to handle direct calls to the configured PDF renderer wrapper class. * - * @param string $name Renderer library method name - * @param mixed[] $arguments Array of arguments to pass to the renderer method - * @return mixed Returned data from the PDF renderer wrapper method + * @param string $name Renderer library method name + * @param mixed[] $arguments Array of arguments to pass to the renderer method + * @return mixed Returned data from the PDF renderer wrapper method */ public function __call($name, $arguments) { if ($this->_renderer === NULL) { - throw new PHPExcel_Writer_Exception("PDF Renderer has not been defined."); + throw new PHPExcel_Writer_Exception("PDF Rendering library has not been defined."); } return call_user_func_array(array($this->_renderer, $name), $arguments); diff --git a/Classes/PHPExcel/Writer/PDF/Core.php b/Classes/PHPExcel/Writer/PDF/Core.php index 8669333ee..6c270f983 100644 --- a/Classes/PHPExcel/Writer/PDF/Core.php +++ b/Classes/PHPExcel/Writer/PDF/Core.php @@ -322,7 +322,7 @@ public function setTempDir($pValue = '') /** * Save PHPExcel to PDF file, pre-save * - * @param string $pFileName + * @param string $pFileName Name of the file to save as * @throws PHPExcel_Writer_Exception */ protected function prepareForSave($pFilename = NULL) diff --git a/Classes/PHPExcel/Writer/PDF/DomPDF.php b/Classes/PHPExcel/Writer/PDF/DomPDF.php index 5abd0a3cf..d06bc4dfe 100644 --- a/Classes/PHPExcel/Writer/PDF/DomPDF.php +++ b/Classes/PHPExcel/Writer/PDF/DomPDF.php @@ -56,7 +56,7 @@ public function __construct(PHPExcel $phpExcel) /** * Save PHPExcel to file * - * @param string $pFileName + * @param string $pFileName Name of the file to save as * @throws PHPExcel_Writer_Exception */ public function save($pFilename = NULL) diff --git a/Classes/PHPExcel/Writer/PDF/mPDF.php b/Classes/PHPExcel/Writer/PDF/mPDF.php index a9b6b0fcb..e9b8a6e3b 100644 --- a/Classes/PHPExcel/Writer/PDF/mPDF.php +++ b/Classes/PHPExcel/Writer/PDF/mPDF.php @@ -46,7 +46,7 @@ class PHPExcel_Writer_PDF_mPDF extends PHPExcel_Writer_PDF_Core implements PHPEx /** * Create a new PHPExcel_Writer_PDF * - * @param PHPExcel $phpExcel PHPExcel object + * @param PHPExcel $phpExcel PHPExcel object */ public function __construct(PHPExcel $phpExcel) { @@ -56,7 +56,7 @@ public function __construct(PHPExcel $phpExcel) /** * Save PHPExcel to file * - * @param string $pFileName + * @param string $pFileName Name of the file to save as * @throws PHPExcel_Writer_Exception */ public function save($pFilename = NULL) diff --git a/Classes/PHPExcel/Writer/PDF/tcPDF.php b/Classes/PHPExcel/Writer/PDF/tcPDF.php index 23a6e3156..289610a25 100644 --- a/Classes/PHPExcel/Writer/PDF/tcPDF.php +++ b/Classes/PHPExcel/Writer/PDF/tcPDF.php @@ -57,7 +57,7 @@ public function __construct(PHPExcel $phpExcel) /** * Save PHPExcel to file * - * @param string $pFileName + * @param string $pFileName Name of the file to save as * @throws PHPExcel_Writer_Exception */ public function save($pFilename = NULL) From 28f266bbba10f08899d40cd23058ccae4ab940a5 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 27 Apr 2013 16:02:07 +0100 Subject: [PATCH 043/467] Docblock comments --- .../CalcEngine/CyclicReferenceStack.php | 42 ++++++++++++- Classes/PHPExcel/CalcEngine/Logger.php | 40 +++++++++++-- Classes/PHPExcel/Calculation/Token/Stack.php | 60 +++++++++++++++---- Classes/PHPExcel/Cell.php | 3 +- Classes/PHPExcel/Comment.php | 5 ++ Classes/PHPExcel/RichText.php | 2 +- 6 files changed, 135 insertions(+), 17 deletions(-) diff --git a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php index e64b46867..c35a1191c 100644 --- a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php +++ b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php @@ -26,31 +26,71 @@ */ +/** + * PHPExcel_CalcEngine_CyclicReferenceStack + * + * @category PHPExcel_CalcEngine_CyclicReferenceStack + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + */ class PHPExcel_CalcEngine_CyclicReferenceStack { + /** + * The call stack for calculated cells + * + * @var mixed[] + */ private $_stack = array(); + /** + * Return the number of entries on the stack + * + * @return integer + */ public function count() { return count($this->_stack); } + /** + * Push a new entry onto the stack + * + * @param mixed $value + */ public function push($value) { $this->_stack[] = $value; } // function push() + /** + * Pop the last entry from the stack + * + * @return mixed + */ public function pop() { return array_pop($this->_stack); } // function pop() + /** + * Test to see if a specified entry exists on the stack + * + * @param mixed $value The value to test + */ public function onStack($value) { - return in_array($value,$this->_stack); + return in_array($value, $this->_stack); } + /** + * Clear the stack + */ public function clear() { $this->_stack = array(); } // function push() + /** + * Return an array of all entries on the stack + * + * @return mixed[] + */ public function showStack() { return $this->_stack; } diff --git a/Classes/PHPExcel/CalcEngine/Logger.php b/Classes/PHPExcel/CalcEngine/Logger.php index 250f841d9..a34a56892 100644 --- a/Classes/PHPExcel/CalcEngine/Logger.php +++ b/Classes/PHPExcel/CalcEngine/Logger.php @@ -40,7 +40,6 @@ class PHPExcel_CalcEngine_Logger { * If false, then a debug log will not be generated * * @var boolean - * */ private $_writeDebugLog = FALSE; @@ -51,7 +50,6 @@ class PHPExcel_CalcEngine_Logger { * A debug log can only be echoed if it is generated * * @var boolean - * */ private $_echoDebugLog = FALSE; @@ -59,7 +57,6 @@ class PHPExcel_CalcEngine_Logger { * The debug log generated by the calculation engine * * @var string[] - * */ private $_debugLog = array(); @@ -67,31 +64,58 @@ class PHPExcel_CalcEngine_Logger { * The calculation engine cell reference stack * * @var PHPExcel_CalcEngine_CyclicReferenceStack - * */ private $_cellStack; + /** + * Instantiate a Calculation engine logger + * + * @param PHPExcel_CalcEngine_CyclicReferenceStack $stack + */ public function __construct(PHPExcel_CalcEngine_CyclicReferenceStack $stack) { $this->_cellStack = $stack; } + /** + * Enable/Disable Calculation engine logging + * + * @param boolean $pValue + */ public function setWriteDebugLog($pValue = FALSE) { $this->_writeDebugLog = $pValue; } + /** + * Return whether calculation engine logging is enabled or disabled + * + * @return boolean + */ public function getWriteDebugLog() { return $this->_writeDebugLog; } + /** + * Enable/Disable echoing of debug log information + * + * @param boolean $pValue + */ public function setEchoDebugLog($pValue = FALSE) { $this->_echoDebugLog = $pValue; } + /** + * Return whether echoing of debug log information is enabled or disabled + * + * @return boolean + */ public function getEchoDebugLog() { return $this->_echoDebugLog; } + /** + * Write an entry to the calculation engine debug log + */ public function writeDebugLog() { // Only write the debug log if logging is enabled if ($this->_writeDebugLog) { @@ -109,10 +133,18 @@ public function writeDebugLog() { } } // function _writeDebug() + /** + * Clear the calculation engine debug log + */ public function clearLog() { $this->_debugLog = array(); } // function flushLogger() + /** + * Return the calculation engine debug log + * + * @return string[] + */ public function getLog() { return $this->_debugLog; } // function flushLogger() diff --git a/Classes/PHPExcel/Calculation/Token/Stack.php b/Classes/PHPExcel/Calculation/Token/Stack.php index bdf9d555e..3a94fa29f 100644 --- a/Classes/PHPExcel/Calculation/Token/Stack.php +++ b/Classes/PHPExcel/Calculation/Token/Stack.php @@ -26,18 +26,47 @@ */ +/** + * PHPExcel_Calculation_Token_Stack + * + * @category PHPExcel_Calculation_Token_Stack + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + */ class PHPExcel_Calculation_Token_Stack { + /** + * The parser stack for formulae + * + * @var mixed[] + */ private $_stack = array(); + + /** + * Count of entries in the parser stack + * + * @var integer + */ private $_count = 0; + /** + * Return the number of entries on the stack + * + * @return integer + */ public function count() { return $this->_count; } // function count() - - public function push($type,$value,$reference=null) { + /** + * Push a new entry onto the stack + * + * @param mixed $type + * @param mixed $value + * @param mixed $reference + */ + public function push($type, $value, $reference = NULL) { $this->_stack[$this->_count++] = array('type' => $type, 'value' => $value, 'reference' => $reference @@ -50,23 +79,34 @@ public function push($type,$value,$reference=null) { } } // function push() - + /** + * Pop the last entry from the stack + * + * @return mixed + */ public function pop() { if ($this->_count > 0) { return $this->_stack[--$this->_count]; } - return null; + return NULL; } // function pop() - - public function last($n=1) { - if ($this->_count-$n < 0) { - return null; + /** + * Return an entry from the stack without removing it + * + * @param integer $n number indicating how far back in the stack we want to look + * @return mixed + */ + public function last($n = 1) { + if ($this->_count - $n < 0) { + return NULL; } - return $this->_stack[$this->_count-$n]; + return $this->_stack[$this->_count - $n]; } // function last() - + /** + * Clear the stack + */ function clear() { $this->_stack = array(); $this->_count = 0; diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 27fb91479..310680c1b 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -268,6 +268,7 @@ public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_Data * * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling * + * @param boolean $resetLog Whether the calculation engine logger should be reset or not * @return mixed * @throws PHPExcel_Exception */ @@ -858,7 +859,7 @@ public static function extractAllCellReferencesInRange($pRange = 'A1') { * Compare 2 cells * * @param PHPExcel_Cell $a Cell a - * @param PHPExcel_Cell $a Cell b + * @param PHPExcel_Cell $b Cell b * @return int Result of comparison (always -1 or 1, never zero!) */ public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b) diff --git a/Classes/PHPExcel/Comment.php b/Classes/PHPExcel/Comment.php index e9f257814..af40420ac 100644 --- a/Classes/PHPExcel/Comment.php +++ b/Classes/PHPExcel/Comment.php @@ -315,6 +315,11 @@ public function __clone() { } } + /** + * Convert to string + * + * @return string + */ public function __toString() { return $this->_text->getPlainText(); } diff --git a/Classes/PHPExcel/RichText.php b/Classes/PHPExcel/RichText.php index 090049010..848098f29 100644 --- a/Classes/PHPExcel/RichText.php +++ b/Classes/PHPExcel/RichText.php @@ -45,7 +45,7 @@ class PHPExcel_RichText implements PHPExcel_IComparable /** * Create a new PHPExcel_RichText instance * - * @param PHPExcel_Cell $pParent + * @param PHPExcel_Cell $pCell * @throws PHPExcel_Exception */ public function __construct(PHPExcel_Cell $pCell = null) From c66049244648456a53ffd1da091fb109292a5b37 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 27 Apr 2013 18:07:12 +0100 Subject: [PATCH 044/467] Docblocks --- Classes/PHPExcel/IOFactory.php | 6 +++--- Classes/PHPExcel/Reader/CSV.php | 10 +++++----- Classes/PHPExcel/Reader/Excel2003XML.php | 2 +- Classes/PHPExcel/Reader/Excel2007.php | 2 +- Classes/PHPExcel/Reader/Excel5.php | 2 +- Classes/PHPExcel/Reader/Gnumeric.php | 2 +- Classes/PHPExcel/Reader/HTML.php | 2 +- Classes/PHPExcel/Reader/IReader.php | 4 ++-- Classes/PHPExcel/Reader/OOCalc.php | 2 +- Classes/PHPExcel/Reader/SYLK.php | 2 +- Classes/PHPExcel/ReferenceHelper.php | 1 + Classes/PHPExcel/Shared/Font.php | 10 +++++----- Classes/PHPExcel/Shared/String.php | 9 +++++---- 13 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Classes/PHPExcel/IOFactory.php b/Classes/PHPExcel/IOFactory.php index a467ecb3c..637054630 100644 --- a/Classes/PHPExcel/IOFactory.php +++ b/Classes/PHPExcel/IOFactory.php @@ -183,7 +183,7 @@ public static function createReader($readerType = '') { * * @static * @access public - * @param string $pFileName The name of the spreadsheet file + * @param string $pFilename The name of the spreadsheet file * @return PHPExcel * @throws PHPExcel_Reader_Exception */ @@ -197,7 +197,7 @@ public static function load($pFilename) { * * @static * @access public - * @param string $pFileName The name of the spreadsheet file to identify + * @param string $pFilename The name of the spreadsheet file to identify * @return string * @throws PHPExcel_Reader_Exception */ @@ -214,7 +214,7 @@ public static function identify($pFilename) { * * @static * @access public - * @param string $pFileName The name of the spreadsheet file + * @param string $pFilename The name of the spreadsheet file * @return PHPExcel_Reader_IReader * @throws PHPExcel_Reader_Exception */ diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index 13d0e2779..4678f7dc5 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -113,7 +113,7 @@ public function __construct() { * Can the current PHPExcel_Reader_IReader read the file? * * @access public - * @param string $pFileName + * @param string $pFilename * @return boolean * @throws PHPExcel_Reader_Exception */ @@ -434,7 +434,7 @@ public function getSheetIndex() { * Set sheet index * * @access public - * @param int $pValue Sheet index + * @param integer $pValue Sheet index * @return PHPExcel_Reader_CSV */ public function setSheetIndex($pValue = 0) { @@ -447,11 +447,11 @@ public function setSheetIndex($pValue = 0) { * Set Contiguous * * @access public - * @param string $pValue Input encoding + * @param boolean $contiguous */ - public function setContiguous($contiguous = false) + public function setContiguous($contiguous = FALSE) { - $this->_contiguous = (bool)$contiguous; + $this->_contiguous = (bool) $contiguous; if (!$contiguous) { $this->_contiguousRow = -1; } diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index 76500ec52..584968559 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -70,7 +70,7 @@ public function __construct() { /** * Can the current PHPExcel_Reader_IReader read the file? * - * @param string $pFileName + * @param string $pFilename * @return boolean * @throws PHPExcel_Reader_Exception */ diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index e2a677dec..4830934cf 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -71,7 +71,7 @@ public function __construct() { /** * Can the current PHPExcel_Reader_IReader read the file? * - * @param string $pFileName + * @param string $pFilename * @return boolean * @throws PHPExcel_Reader_Exception */ diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 5efee8d51..91569d283 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -391,7 +391,7 @@ public function __construct() { /** * Can the current PHPExcel_Reader_IReader read the file? * - * @param string $pFileName + * @param string $pFilename * @return boolean * @throws PHPExcel_Reader_Exception */ diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index 821d1acd4..c0ad7725a 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -73,7 +73,7 @@ public function __construct() { /** * Can the current PHPExcel_Reader_IReader read the file? * - * @param string $pFileName + * @param string $pFilename * @return boolean * @throws PHPExcel_Reader_Exception */ diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 4e8b8e99f..d8c5821ba 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -111,7 +111,7 @@ public function __construct() { /** * Can the current PHPExcel_Reader_IReader read the file? * - * @param string $pFileName + * @param string $pFilename * @return boolean * @throws PHPExcel_Reader_Exception */ diff --git a/Classes/PHPExcel/Reader/IReader.php b/Classes/PHPExcel/Reader/IReader.php index c26f1d40c..db97bb853 100644 --- a/Classes/PHPExcel/Reader/IReader.php +++ b/Classes/PHPExcel/Reader/IReader.php @@ -38,7 +38,7 @@ interface PHPExcel_Reader_IReader /** * Can the current PHPExcel_Reader_IReader read the file? * - * @param string $pFileName + * @param string $pFilename * @return boolean */ public function canRead($pFilename); @@ -46,7 +46,7 @@ public function canRead($pFilename); /** * Loads PHPExcel from file * - * @param string $pFileName + * @param string $pFilename * @throws PHPExcel_Reader_Exception */ public function load($pFilename); diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index a25ceb090..460e675b1 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -63,7 +63,7 @@ public function __construct() { /** * Can the current PHPExcel_Reader_IReader read the file? * - * @param string $pFileName + * @param string $pFilename * @return boolean * @throws PHPExcel_Reader_Exception */ diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index 0be71f3ce..d3a993573 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -83,7 +83,7 @@ public function __construct() { /** * Can the current PHPExcel_Reader_IReader read the file? * - * @param string $pFileName + * @param string $pFilename * @return boolean * @throws PHPExcel_Reader_Exception */ diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 94f21b326..0e191c62d 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -641,6 +641,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P * @param int $pBefore Insert before this one * @param int $pNumCols Number of columns to insert * @param int $pNumRows Number of rows to insert + * @param string $sheetName Worksheet name/title * @return string Updated formula * @throws PHPExcel_Exception */ diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php index 6879e602d..1a4f8ae40 100644 --- a/Classes/PHPExcel/Shared/Font.php +++ b/Classes/PHPExcel/Shared/Font.php @@ -244,11 +244,11 @@ public static function getTrueTypeFontPath() /** * Calculate an (approximate) OpenXML column width, based on font size and text contained * - * @param int $fontSize Font size (in pixels or points) - * @param bool $fontSizeInPixels Is the font size specified in pixels (true) or in points (false) ? - * @param string $cellText Text to calculate width - * @param int $rotation Rotation angle - * @return int Column width + * @param PHPExcel_Style_Font $font Font object + * @param PHPExcel_RichText|string $cellText Text to calculate width + * @param integer $rotation Rotation angle + * @param PHPExcel_Style_Font|NULL $defaultFont Font object + * @return integer Column width */ public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText = '', $rotation = 0, PHPExcel_Style_Font $defaultFont = null) { diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 38974336d..d9470b1b5 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -427,7 +427,8 @@ public static function FormatNumber($value) { * although this will give wrong results for non-ASCII strings * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 * - * @param string $value UTF-8 encoded string + * @param string $value UTF-8 encoded string + * @param mixed[] $arrcRuns Details of rich text runs in $value * @return string */ public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = array()) @@ -523,7 +524,7 @@ public static function ConvertEncoding($value, $to, $from) * @author Rasmus Andersson {@link http://rasmusandersson.se/} * @author vadik56 */ - public static function utf16_decode( $str, $bom_be=true ) { + public static function utf16_decode($str, $bom_be = TRUE) { if( strlen($str) < 2 ) return $str; $c0 = ord($str{0}); $c1 = ord($str{1}); @@ -564,8 +565,8 @@ public static function CountCharacters($value, $enc = 'UTF-8') * Get a substring of a UTF-8 encoded string. First try mbstring, then iconv, finally strlen * * @param string $pValue UTF-8 encoded string - * @param int $start Start offset - * @param int $length Maximum number of characters in substring + * @param int $pStart Start offset + * @param int $pLength Maximum number of characters in substring * @return string */ public static function Substring($pValue = '', $pStart = 0, $pLength = 0) From e9a09c8903b92f6ffcbcdf1c61ad5c6cde7394b5 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 27 Apr 2013 21:57:30 +0100 Subject: [PATCH 045/467] Document blocks --- Classes/PHPExcel/Worksheet.php | 10 +++++----- Classes/PHPExcel/Worksheet/AutoFilter.php | 17 ++++++++++------- .../PHPExcel/Worksheet/AutoFilter/Column.php | 13 +++++++++++++ .../Worksheet/AutoFilter/Column/Rule.php | 2 ++ Classes/PHPExcel/Writer/Excel5/Workbook.php | 8 ++++---- Classes/PHPExcel/Writer/IWriter.php | 4 ++-- Classes/PHPExcel/Writer/PDF/Core.php | 6 +++--- Classes/PHPExcel/Writer/PDF/DomPDF.php | 6 +++--- Classes/PHPExcel/Writer/PDF/mPDF.php | 4 ++-- Classes/PHPExcel/Writer/PDF/tcPDF.php | 4 ++-- 10 files changed, 46 insertions(+), 28 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 51cb4e797..37df75025 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1861,7 +1861,7 @@ public function getAutoFilter() /** * Set AutoFilter * - * @param PHPExcel_Worksheet_AutoFilter|string $pValue + * @param PHPExcel_Worksheet_AutoFilter|string $pValue * A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility * @throws PHPExcel_Exception * @return PHPExcel_Worksheet @@ -1879,10 +1879,10 @@ public function setAutoFilter($pValue) /** * Set Autofilter Range by using numeric cell coordinates * - * @param int $pColumn1 Numeric column coordinate of the first cell - * @param int $pRow1 Numeric row coordinate of the first cell - * @param int $pColumn2 Numeric column coordinate of the second cell - * @param int $pRow2 Numeric row coordinate of the second cell + * @param integer $pColumn1 Numeric column coordinate of the first cell + * @param integer $pRow1 Numeric row coordinate of the first cell + * @param integer $pColumn2 Numeric column coordinate of the second cell + * @param integer $pRow2 Numeric row coordinate of the second cell * @throws PHPExcel_Exception * @return PHPExcel_Worksheet */ diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index ae05875e8..75a06a446 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -61,6 +61,9 @@ class PHPExcel_Worksheet_AutoFilter /** * Create a new PHPExcel_Worksheet_AutoFilter + * + * @param string $pRange Cell range (i.e. A1:E10) + * @param PHPExcel_Worksheet $pSheet */ public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = NULL) { @@ -80,7 +83,7 @@ public function getParent() { /** * Set AutoFilter Parent Worksheet * - * @param PHPExcel_Worksheet + * @param PHPExcel_Worksheet $pSheet * @return PHPExcel_Worksheet_AutoFilter */ public function setParent(PHPExcel_Worksheet $pSheet = NULL) { @@ -243,7 +246,7 @@ public function setColumn($pColumn) /** * Clear a specified AutoFilter Column * - * @param string $pColumn Column name (e.g. A) + * @param string $pColumn Column name (e.g. A) * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter */ @@ -347,10 +350,10 @@ private static function _filterTestInDateGroupSet($cellValue,$dataSet) * Test if cell value is within a set of values defined by a ruleset * * @param mixed $cellValue - * @param mixed[] $dataSet + * @param mixed[] $ruleSet * @return boolean */ - private static function _filterTestInCustomDataSet($cellValue,$ruleSet) + private static function _filterTestInCustomDataSet($cellValue, $ruleSet) { $dataSet = $ruleSet['filterRules']; $join = $ruleSet['join']; @@ -424,10 +427,10 @@ private static function _filterTestInCustomDataSet($cellValue,$ruleSet) * Test if cell date value is matches a set of values defined by a set of months * * @param mixed $cellValue - * @param mixed[] $dataSet + * @param mixed[] $monthSet * @return boolean */ - private static function _filterTestInPeriodDateSet($cellValue,$monthSet) + private static function _filterTestInPeriodDateSet($cellValue, $monthSet) { // Blank cells are always ignored, so return a FALSE if (($cellValue == '') || ($cellValue === NULL)) { @@ -457,7 +460,7 @@ private static function _filterTestInPeriodDateSet($cellValue,$monthSet) * Convert a dynamic rule daterange to a custom filter range expression for ease of calculation * * @param string $dynamicRuleType - * @param PHPExcel_Worksheet_AutoFilter_Column $filterColumn + * @param PHPExcel_Worksheet_AutoFilter_Column &$filterColumn * @return mixed[] */ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php index 9a743520c..95f70847f 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php @@ -44,6 +44,11 @@ class PHPExcel_Worksheet_AutoFilter_Column // e.g. filtered by date = TODAY const AUTOFILTER_FILTERTYPE_TOPTENFILTER = 'top10'; + /** + * Types of autofilter rules + * + * @var string[] + */ private static $_filterTypes = array( // Currently we're not handling // colorFilter @@ -59,6 +64,11 @@ class PHPExcel_Worksheet_AutoFilter_Column const AUTOFILTER_COLUMN_JOIN_AND = 'and'; const AUTOFILTER_COLUMN_JOIN_OR = 'or'; + /** + * Join options for autofilter rules + * + * @var string[] + */ private static $_ruleJoins = array( self::AUTOFILTER_COLUMN_JOIN_AND, self::AUTOFILTER_COLUMN_JOIN_OR, @@ -114,6 +124,9 @@ class PHPExcel_Worksheet_AutoFilter_Column /** * Create a new PHPExcel_Worksheet_AutoFilter_Column + * + * @param string $pColumn Column (e.g. A) + * @param PHPExcel_Worksheet_AutoFilter $pParent Autofilter for this column */ public function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = NULL) { diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php index 771358bc2..a1cbc6fe0 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -269,6 +269,8 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule /** * Create a new PHPExcel_Worksheet_AutoFilter_Column_Rule + * + * @param PHPExcel_Worksheet_AutoFilter_Column $pParent */ public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) { diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index b50fa0ff1..2a2eb4725 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -836,10 +836,10 @@ private function _writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $i /** * Write a short NAME record * - * @param string $name - * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global - * @param int[][] $range rangeboundaries - * @param bool $isHidden + * @param string $name + * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global + * @param integer[][] $rangeBounds range boundaries + * @param boolean $isHidden * @return string Complete binary record data * */ private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){ diff --git a/Classes/PHPExcel/Writer/IWriter.php b/Classes/PHPExcel/Writer/IWriter.php index 908e45f69..d69687e30 100644 --- a/Classes/PHPExcel/Writer/IWriter.php +++ b/Classes/PHPExcel/Writer/IWriter.php @@ -38,8 +38,8 @@ interface PHPExcel_Writer_IWriter /** * Save PHPExcel to file * - * @param string $pFilename - * @throws PHPExcel_Writer_Exception + * @param string $pFilename NAme of the file to save + * @throws PHPExcel_Writer_Exception */ public function save($pFilename = NULL); diff --git a/Classes/PHPExcel/Writer/PDF/Core.php b/Classes/PHPExcel/Writer/PDF/Core.php index 6c270f983..0925ca3a3 100644 --- a/Classes/PHPExcel/Writer/PDF/Core.php +++ b/Classes/PHPExcel/Writer/PDF/Core.php @@ -261,7 +261,7 @@ public function getPaperSize() /** * Set Paper Size * - * @param int $pValue + * @param string $pValue Paper size * @return PHPExcel_Writer_PDF */ public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) @@ -283,7 +283,7 @@ public function getOrientation() /** * Set Orientation * - * @param string $pValue + * @param string $pValue Page orientation * @return PHPExcel_Writer_PDF */ public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) @@ -322,7 +322,7 @@ public function setTempDir($pValue = '') /** * Save PHPExcel to PDF file, pre-save * - * @param string $pFileName Name of the file to save as + * @param string $pFilename Name of the file to save as * @throws PHPExcel_Writer_Exception */ protected function prepareForSave($pFilename = NULL) diff --git a/Classes/PHPExcel/Writer/PDF/DomPDF.php b/Classes/PHPExcel/Writer/PDF/DomPDF.php index d06bc4dfe..db3045d46 100644 --- a/Classes/PHPExcel/Writer/PDF/DomPDF.php +++ b/Classes/PHPExcel/Writer/PDF/DomPDF.php @@ -46,7 +46,7 @@ class PHPExcel_Writer_PDF_DomPDF extends PHPExcel_Writer_PDF_Core implements PHP /** * Create a new PHPExcel_Writer_PDF * - * @param PHPExcel $phpExcel PHPExcel object + * @param PHPExcel $phpExcel PHPExcel object */ public function __construct(PHPExcel $phpExcel) { @@ -56,8 +56,8 @@ public function __construct(PHPExcel $phpExcel) /** * Save PHPExcel to file * - * @param string $pFileName Name of the file to save as - * @throws PHPExcel_Writer_Exception + * @param string $pFilename Name of the file to save as + * @throws PHPExcel_Writer_Exception */ public function save($pFilename = NULL) { diff --git a/Classes/PHPExcel/Writer/PDF/mPDF.php b/Classes/PHPExcel/Writer/PDF/mPDF.php index e9b8a6e3b..ef050d7bd 100644 --- a/Classes/PHPExcel/Writer/PDF/mPDF.php +++ b/Classes/PHPExcel/Writer/PDF/mPDF.php @@ -46,7 +46,7 @@ class PHPExcel_Writer_PDF_mPDF extends PHPExcel_Writer_PDF_Core implements PHPEx /** * Create a new PHPExcel_Writer_PDF * - * @param PHPExcel $phpExcel PHPExcel object + * @param PHPExcel $phpExcel PHPExcel object */ public function __construct(PHPExcel $phpExcel) { @@ -56,7 +56,7 @@ public function __construct(PHPExcel $phpExcel) /** * Save PHPExcel to file * - * @param string $pFileName Name of the file to save as + * @param string $pFilename Name of the file to save as * @throws PHPExcel_Writer_Exception */ public function save($pFilename = NULL) diff --git a/Classes/PHPExcel/Writer/PDF/tcPDF.php b/Classes/PHPExcel/Writer/PDF/tcPDF.php index 289610a25..25bfb50c6 100644 --- a/Classes/PHPExcel/Writer/PDF/tcPDF.php +++ b/Classes/PHPExcel/Writer/PDF/tcPDF.php @@ -47,7 +47,7 @@ class PHPExcel_Writer_PDF_tcPDF extends PHPExcel_Writer_PDF_Core implements PHPE /** * Create a new PHPExcel_Writer_PDF * - * @param PHPExcel $phpExcel PHPExcel object + * @param PHPExcel $phpExcel PHPExcel object */ public function __construct(PHPExcel $phpExcel) { @@ -57,7 +57,7 @@ public function __construct(PHPExcel $phpExcel) /** * Save PHPExcel to file * - * @param string $pFileName Name of the file to save as + * @param string $pFilename Name of the file to save as * @throws PHPExcel_Writer_Exception */ public function save($pFilename = NULL) From 212b7acc7965fbea9ef7147acd28422870789bf8 Mon Sep 17 00:00:00 2001 From: Gabriel Machado Date: Sat, 27 Apr 2013 18:17:14 -0300 Subject: [PATCH 046/467] Update IWriter.php Fixing a typo --- Classes/PHPExcel/Writer/IWriter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/IWriter.php b/Classes/PHPExcel/Writer/IWriter.php index d69687e30..af50b55d3 100644 --- a/Classes/PHPExcel/Writer/IWriter.php +++ b/Classes/PHPExcel/Writer/IWriter.php @@ -38,7 +38,7 @@ interface PHPExcel_Writer_IWriter /** * Save PHPExcel to file * - * @param string $pFilename NAme of the file to save + * @param string $pFilename Name of the file to save * @throws PHPExcel_Writer_Exception */ public function save($pFilename = NULL); From d41c8aacf7d1a53028eaf8d25aca1898f26cb400 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 27 Apr 2013 22:47:25 +0100 Subject: [PATCH 047/467] Modify build to use PHPDocumentor 2 rather than PHPDocumentor 1 --- Build/build.xml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Build/build.xml b/Build/build.xml index 568ff89ed..c29b8d18e 100644 --- a/Build/build.xml +++ b/Build/build.xml @@ -95,17 +95,13 @@ - + - + From d4e7026c95631fe232f609830b3c44344d1a5652 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 27 Apr 2013 23:36:39 +0100 Subject: [PATCH 048/467] docblocks --- Classes/PHPExcel/CalcEngine/Logger.php | 2 +- Classes/PHPExcel/Calculation.php | 46 ++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Classes/PHPExcel/CalcEngine/Logger.php b/Classes/PHPExcel/CalcEngine/Logger.php index a34a56892..627788f6c 100644 --- a/Classes/PHPExcel/CalcEngine/Logger.php +++ b/Classes/PHPExcel/CalcEngine/Logger.php @@ -26,7 +26,7 @@ */ /** - * PHPExcel_Calculation_Logger + * PHPExcel_CalcEngine_Logger * * @category PHPExcel * @package PHPExcel_Calculation diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 93f77d74d..ab474a3ba 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -1701,6 +1701,8 @@ private static function _loadLocales() { * Get an instance of this class * * @access public + * @param PHPExcel $workbook Injected workbook for working with a PHPExcel object, + * or NULL to create a standalone claculation engine * @return PHPExcel_Calculation */ public static function getInstance(PHPExcel $workbook = NULL) { @@ -1718,6 +1720,12 @@ public static function getInstance(PHPExcel $workbook = NULL) { return self::$_instance; } // function getInstance() + /** + * Unset an instance of this class + * + * @access public + * @param PHPExcel $workbook Injected workbook identifying the instance to unset + */ public static function unsetInstance(PHPExcel $workbook = NULL) { if ($workbook !== NULL) { if (isset(self::$_workbookSets[$workbook->getID()])) { @@ -1738,6 +1746,12 @@ public function flushInstance() { } // function flushInstance() + /** + * Get the debuglog for this claculation engine instance + * + * @access public + * @return PHPExcel_CalcEngine_Logger + */ public function getDebugLog() { return $this->_debugLog; } @@ -1849,6 +1863,8 @@ public function clearCalculationCache() { /** * Clear calculation cache for a specified worksheet + * + * @param string $worksheetName */ public function clearCalculationCacheForWorksheet($worksheetName) { if (isset($this->_calculationCache[$worksheetName])) { @@ -1858,6 +1874,9 @@ public function clearCalculationCacheForWorksheet($worksheetName) { /** * Rename calculation cache for a specified worksheet + * + * @param string $fromWorksheetName + * @param string $toWorksheetName */ public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) { if (isset($this->_calculationCache[$fromWorksheetName])) { @@ -1880,9 +1899,10 @@ public function getLocale() { /** * Set the locale code * + * @param string $locale The locale to use for formula translation * @return boolean */ - public function setLocale($locale='en_us') { + public function setLocale($locale = 'en_us') { // Identify our locale and language $language = $locale = strtolower($locale); if (strpos($locale,'_') !== FALSE) { @@ -2229,7 +2249,9 @@ public function parseFormula($formula) { /** * Calculate the value of a formula * - * @param string $formula Formula to parse + * @param string $formula Formula to parse + * @param string $cellID Address of the cell to calculate + * @param PHPExcel_Cell $pCell Cell to calculate * @return mixed * @throws PHPExcel_Calculation_Exception */ @@ -2405,8 +2427,12 @@ public static function _getMatrixDimensions(&$matrix) { /** * Ensure that paired matrix operands are both matrices of the same size * - * @param mixed &$matrix1 First matrix operand - * @param mixed &$matrix2 Second matrix operand + * @param mixed &$matrix1 First matrix operand + * @param mixed &$matrix2 Second matrix operand + * @param integer $matrix1Rows Row size of first matrix operand + * @param integer $matrix1Columns Column size of first matrix operand + * @param integer $matrix2Rows Row size of second matrix operand + * @param integer $matrix2Columns Column size of second matrix operand */ private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { @@ -2446,6 +2472,10 @@ private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$ * * @param mixed &$matrix1 First matrix operand * @param mixed &$matrix2 Second matrix operand + * @param integer $matrix1Rows Row size of first matrix operand + * @param integer $matrix1Columns Column size of first matrix operand + * @param integer $matrix2Rows Row size of second matrix operand + * @param integer $matrix2Columns Column size of second matrix operand */ private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { @@ -3594,12 +3624,13 @@ protected function _raiseFormulaError($errorMessage) { /** * Extract range values * - * @param string &$pRange String based range representation + * @param string &$pRange String based range representation * @param PHPExcel_Worksheet $pSheet Worksheet + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. * @throws PHPExcel_Calculation_Exception */ - public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog=TRUE) { + public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { // Return value $returnValue = array (); @@ -3654,9 +3685,10 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = N * @param string &$pRange String based range representation * @param PHPExcel_Worksheet $pSheet Worksheet * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not * @throws PHPExcel_Calculation_Exception */ - public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog=TRUE) { + public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { // Return value $returnValue = array (); From 91eb758a6dbbe27844ffcbb322a82bf79197a91a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 28 Apr 2013 16:02:46 +0100 Subject: [PATCH 049/467] Yet more docblock fixes --- Classes/PHPExcel/Calculation/Engineering.php | 2 +- Classes/PHPExcel/Calculation/Financial.php | 84 +++++++++++++++----- 2 files changed, 67 insertions(+), 19 deletions(-) diff --git a/Classes/PHPExcel/Calculation/Engineering.php b/Classes/PHPExcel/Calculation/Engineering.php index c0005e744..50c49026d 100644 --- a/Classes/PHPExcel/Calculation/Engineering.php +++ b/Classes/PHPExcel/Calculation/Engineering.php @@ -2356,7 +2356,6 @@ public static function getConversionGroups() { * Returns an array of units of measure, for a specified conversion group, or for all groups * * @param string $group The group whose units of measure you want to retrieve - * * @return array */ public static function getConversionGroupUnits($group = NULL) { @@ -2373,6 +2372,7 @@ public static function getConversionGroupUnits($group = NULL) { /** * getConversionGroupUnitDetails * + * @param string $group The group whose units of measure you want to retrieve * @return array */ public static function getConversionGroupUnitDetails($group = NULL) { diff --git a/Classes/PHPExcel/Calculation/Financial.php b/Classes/PHPExcel/Calculation/Financial.php index e507f05f5..d8e5195af 100644 --- a/Classes/PHPExcel/Calculation/Financial.php +++ b/Classes/PHPExcel/Calculation/Financial.php @@ -1206,13 +1206,22 @@ public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) { /** * FVSCHEDULE * + * Returns the future value of an initial principal after applying a series of compound interest rates. + * Use FVSCHEDULE to calculate the future value of an investment with a variable or adjustable rate. + * + * Excel Function: + * FVSCHEDULE(principal,schedule) + * + * @param float $principal The present value. + * @param float[] $schedule An array of interest rates to apply. + * @return float */ public static function FVSCHEDULE($principal, $schedule) { $principal = PHPExcel_Calculation_Functions::flattenSingleValue($principal); $schedule = PHPExcel_Calculation_Functions::flattenArray($schedule); - foreach($schedule as $n) { - $principal *= 1 + $n; + foreach($schedule as $rate) { + $principal *= 1 + $rate; } return $principal; @@ -1227,13 +1236,13 @@ public static function FVSCHEDULE($principal, $schedule) { * Excel Function: * INTRATE(settlement,maturity,investment,redemption[,basis]) * - * @param mixed settlement The security's settlement date. + * @param mixed $settlement The security's settlement date. * The security settlement date is the date after the issue date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. + * @param mixed $maturity The security's maturity date. * The maturity date is the date when the security expires. - * @param integer investment The amount invested in the security. - * @param integer redemption The amount to be received at maturity. - * @param integer basis The type of day count to use. + * @param integer $investment The amount invested in the security. + * @param integer $redemption The amount to be received at maturity. + * @param integer $basis The type of day count to use. * 0 or omitted US (NASD) 30/360 * 1 Actual/actual * 2 Actual/360 @@ -1273,6 +1282,9 @@ public static function INTRATE($settlement, $maturity, $investment, $redemption, * * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate. * + * Excel Function: + * IPMT(rate,per,nper,pv[,fv][,type]) + * * @param float $rate Interest rate per period * @param int $per Period for which we want to find the interest * @param int $nper Number of periods @@ -1302,7 +1314,25 @@ public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { return $interestAndPrincipal[0]; } // function IPMT() - + /** + * IRR + * + * Returns the internal rate of return for a series of cash flows represented by the numbers in values. + * These cash flows do not have to be even, as they would be for an annuity. However, the cash flows must occur + * at regular intervals, such as monthly or annually. The internal rate of return is the interest rate received + * for an investment consisting of payments (negative values) and income (positive values) that occur at regular + * periods. + * + * Excel Function: + * IRR(values[,guess]) + * + * @param float[] $values An array or a reference to cells that contain numbers for which you want + * to calculate the internal rate of return. + * Values must contain at least one positive value and one negative value to + * calculate the internal rate of return. + * @param float $guess A number that you guess is close to the result of IRR + * @return float + */ public static function IRR($values, $guess = 0.1) { if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); $values = PHPExcel_Calculation_Functions::flattenArray($values); @@ -1336,28 +1366,30 @@ public static function IRR($values, $guess = 0.1) { $dx *= 0.5; $x_mid = $rtb + $dx; $f_mid = self::NPV($x_mid, $values); - if ($f_mid <= 0.0) $rtb = $x_mid; - if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) return $x_mid; + if ($f_mid <= 0.0) + $rtb = $x_mid; + if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) + return $x_mid; } return PHPExcel_Calculation_Functions::VALUE(); } // function IRR() /** - * ISPMT + * ISPMT * - * Returns the interest payment for an investment based on an interest rate and a constant payment schedule. + * Returns the interest payment for an investment based on an interest rate and a constant payment schedule. * - * Excel Function: - * =ISPMT(interest_rate, period, number_payments, PV) + * Excel Function: + * =ISPMT(interest_rate, period, number_payments, PV) * - * interest_rate is the interest rate for the investment + * interest_rate is the interest rate for the investment * - * period is the period to calculate the interest rate. It must be betweeen 1 and number_payments. + * period is the period to calculate the interest rate. It must be betweeen 1 and number_payments. * - * number_payments is the number of payments for the annuity + * number_payments is the number of payments for the annuity * - * PV is the loan amount or present value of the payments + * PV is the loan amount or present value of the payments */ public static function ISPMT() { // Return value @@ -1384,6 +1416,22 @@ public static function ISPMT() { } // function ISPMT() + /** + * MIRR + * + * Returns the modified internal rate of return for a series of periodic cash flows. MIRR considers both + * the cost of the investment and the interest received on reinvestment of cash. + * + * Excel Function: + * MIRR(values,finance_rate, reinvestment_rate) + * + * @param float[] $values An array or a reference to cells that contain a series of payments and + * income occurring at regular intervals. + * Payments are negative value, income is positive values. + * @param float $finance_rate The interest rate you pay on the money used in the cash flows + * @param float $reinvestment_rate The interest rate you receive on the cash flows as you reinvest them + * @return float + */ public static function MIRR($values, $finance_rate, $reinvestment_rate) { if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); $values = PHPExcel_Calculation_Functions::flattenArray($values); From 6f83afd512bbd1688b3a3b96ac7a58d66f1f043c Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 28 Apr 2013 16:21:03 +0100 Subject: [PATCH 050/467] Include Examples directory for release builds in phing build --- Build/build.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Build/build.xml b/Build/build.xml index c29b8d18e..47884c75d 100644 --- a/Build/build.xml +++ b/Build/build.xml @@ -42,6 +42,12 @@ + + + + + + @@ -87,7 +93,7 @@ - + From 2cf5e0f5aa3551a3a2c15179186e1dcdd3da0dbf Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 28 Apr 2013 17:08:30 +0100 Subject: [PATCH 051/467] Fix to version/date/docformat prompts in build script --- Build/build.xml | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/Build/build.xml b/Build/build.xml index 47884c75d..280b459cc 100644 --- a/Build/build.xml +++ b/Build/build.xml @@ -4,27 +4,36 @@ - - - - + + + + + + + - - - - + + + + + + + - - - - + + + + + + + From 8b7e5021295698dd30f583c9a62acad1797fadef Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 28 Apr 2013 18:06:20 +0100 Subject: [PATCH 052/467] Documentation updates --- .../Examples/Reader/exampleReader18.php | 50 +++++++++++++++++ .../Examples/Reader/exampleReader19.php | 53 ++++++++++++++++++ ...umentation - Reading Spreadsheet Files.doc | Bin 168960 -> 174592 bytes 3 files changed, 103 insertions(+) create mode 100644 Documentation/Examples/Reader/exampleReader18.php create mode 100644 Documentation/Examples/Reader/exampleReader19.php diff --git a/Documentation/Examples/Reader/exampleReader18.php b/Documentation/Examples/Reader/exampleReader18.php new file mode 100644 index 000000000..438d88691 --- /dev/null +++ b/Documentation/Examples/Reader/exampleReader18.php @@ -0,0 +1,50 @@ + + + + + +PHPExcel Reader Example #18 + + + + +

PHPExcel Reader Example #18

+

Reading list of WorkSheets without loading entire file

+'; + +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +$worksheetNames = $objReader->listWorksheetNames($inputFileName); + +echo '

Worksheet Names

'; +echo '
    '; +foreach ($worksheetNames as $worksheetName) { + echo '
  1. ', $worksheetName, '
  2. '; +} +echo '
'; + +?> + + \ No newline at end of file diff --git a/Documentation/Examples/Reader/exampleReader19.php b/Documentation/Examples/Reader/exampleReader19.php new file mode 100644 index 000000000..2f3eaaf28 --- /dev/null +++ b/Documentation/Examples/Reader/exampleReader19.php @@ -0,0 +1,53 @@ + + + + + +PHPExcel Reader Example #19 + + + + +

PHPExcel Reader Example #19

+

Reading WorkSheet information without loading entire file

+'; + +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +$worksheetData = $objReader->listWorksheetInfo($inputFileName); + +echo '

Worksheet Information

'; +echo '
    '; +foreach ($worksheetData as $worksheet) { + echo '
  1. ', $worksheet['worksheetName'], '
    '; + echo 'Rows: ', $worksheet['totalRows'], ' Columns: ', $worksheet['totalColumns'], '
    '; + echo 'Cell Range: A1:', $worksheet['lastColumnLetter'], $worksheet['totalRows']; + echo '
  2. '; +} +echo '
'; + +?> + + \ No newline at end of file diff --git a/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc b/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc index 810937e7414f650a31672804149a01f710271d44..ed9573ea787369ffa9e1b1d3fb6c32497a777580 100644 GIT binary patch delta 28370 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 delta 24175 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 From cbe9e35e6fac5771aafaa3e0bbed3c4f5529d90e Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 28 Apr 2013 22:29:32 +0100 Subject: [PATCH 053/467] Fix for specifying version/date/format in documentation builds --- Build/build.xml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Build/build.xml b/Build/build.xml index 280b459cc..761e6487e 100644 --- a/Build/build.xml +++ b/Build/build.xml @@ -72,12 +72,6 @@
- - - - - - @@ -193,7 +187,7 @@
- + From 9ecce7f009f7f1bde71b6735434280362897a8c1 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 29 Apr 2013 00:06:06 +0100 Subject: [PATCH 054/467] Minor performance tweak --- Classes/PHPExcel/Calculation.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index ab474a3ba..2b3099aae 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2436,6 +2436,11 @@ public static function _getMatrixDimensions(&$matrix) { */ private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { + if ($matrix2Rows < $matrix1Rows) { + for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { + unset($matrix1[$i]); + } + } if ($matrix2Columns < $matrix1Columns) { for ($i = 0; $i < $matrix1Rows; ++$i) { for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { @@ -2443,14 +2448,14 @@ private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$ } } } - if ($matrix2Rows < $matrix1Rows) { - for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { - unset($matrix1[$i]); - } - } } if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { + if ($matrix1Rows < $matrix2Rows) { + for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) { + unset($matrix2[$i]); + } + } if ($matrix1Columns < $matrix2Columns) { for ($i = 0; $i < $matrix2Rows; ++$i) { for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { @@ -2458,11 +2463,6 @@ private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$ } } } - if ($matrix1Rows < $matrix2Rows) { - for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) { - unset($matrix2[$i]); - } - } } } // function _resizeMatricesShrink() From 12baf4e097f59ee5b0a79bd4d77d673bec4a5362 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 29 Apr 2013 09:14:32 +0100 Subject: [PATCH 055/467] Documentation updates --- ...lter Reference developer documentation.doc | Bin 628736 -> 629760 bytes ...tion Reference developer documentation.doc | Bin 617984 -> 628736 bytes ...umentation - Reading Spreadsheet Files.doc | Bin 174592 -> 174592 bytes .../PHPExcel developer documentation.doc | Bin 816640 -> 817152 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Documentation/PHPExcel AutoFilter Reference developer documentation.doc b/Documentation/PHPExcel AutoFilter Reference developer documentation.doc index 2024f77c2e98b53e7067efffbb95acf61fa58873..85f7e420976fa4643a4ba680616006e0b2338210 100644 GIT binary patch delta 3173 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 HSL6K$tk3s_ diff --git a/Documentation/PHPExcel Function Reference developer documentation.doc b/Documentation/PHPExcel Function Reference developer documentation.doc index 1ab93b253ecdea5ac8d8e4f715918fbeba1242fc..8d6e14f266f702a5a49567ff7b13aabd26f46eda 100644 GIT binary patch delta 9374 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

wfV3EV}6G*_A1PK_MAOYhx2pH;pNWSO}$rm#q z`C=O+S6FkHNPq}|1cfO$i7eFY${An>j^W2{jtt=J|HpRcdjUJ5IU`6O7zxP(%OQE- z6eJJ4f#d;yNFIm*Il!tGQjq?BHl$x)8xt@IXK@L!y$Krl71CvQcGt)C;Xa3S+kc02 z+kGM3_AZca`!q)UVy)L8!tv=+Z7=E{s zcQQ|OaV#Hww>19H0++qbb6qjuDG zEY@-}EzUCB5;LpT+y6as+&(VO;-VQY4z*1jWO=Dgu#FpRv6_r3>Rw|)9YOn33EwLgPmKhBFUhT6-f=p#T+L z1tOrJsG#UX^oi*DcxgoRtqlMICodA{kN}$MYh`#4S#Y6uQNw@p5Y8dr{gVlJ`VcBZenZjz3#A*SIAAe)Fm4p?^Ut`?V!V3_ z;C8HT`vGJ?0)k0;mSFNKMi`MIS`1?+3UPiYzGt*i_Z!mK3BwMZn{)gV^S|MJ-Vi+B z3Fd+y0X~mK)$!awDMl{?&C~jk>L*DC?*XIw@urQe-C>>))!)4-mGV?dTCYk|61P0M zK@bwc#2?*|cNLF*0Y9@0ga?s@$V1FUtUwg8mMq0(-4Un`?Dm!V^v1(a){&(ouy1b> zOH_ny`Q+z6gEu@HeFp(7C0iM9iho&R3$vBiEL&e+1}{-!wk=1Eoy}H~$;4w`WwxXw zCL|{$v(-6@V@TrExU7=mvbZF7ViMnzqbw%OubJZ;@{}Q#Or&B^E9JxUluqI(Lf=}% zI>dU!21GeR+!}v&wO#+|0>`&tEMb8FUBLVvMXTfquRP(XvjIT4z`Yv3FJ1QbU^f+s zMs+W;HzusM<=7b30eKYy`;|*50dpy?TZZV*<%`};+v3Pq5N7VkSF3YL25W9oM=BXt z2t=?;O=_yL7en{+$bITRvLf26;E@N^ZnGjvSMXr7>Y6|@xa+EVINH7rWASx|k3BRp3KBeQ5FF>w?oiGSs# zb<$uNR2Zd$<>peWMMXmiL**-S>1C67-bJLcgu55gjb?ij7B?0&7Qo`16w*#2su$AP zCPl&$694*5nrN{{b48!@*B4?>#8zWI&D@>Si`N5&@7s$mc~E!~z6 zhy<{D&p2hD>JoZ7@pDTLT}Ma^d+&F;(F&gV!mkB_ktEc>ZR~=@-KE2r`!1Dv%3Ycu z9lJ-12zi#Ryic8D78lYEteYm%8mz^0&YdM8J+N;KUevt#K0O?n{1m=uc*BQA96kk+ z6a?PDp-f>5eF$PvUgn%d9&ct&_KUpPr1h-j-X59|`T}!~m1|YeviSA0>TTL6T|2l< zbIYZIXPfZ(P;1z(?Ph`P+C=gt8(pLQQtQue@N30dplxaB_tC;j{F;eKZ_i}wYqf`D TDJ!YdDwUO(x|#o7r>V-nzC`H% diff --git a/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc b/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc index ed9573ea787369ffa9e1b1d3fb6c32497a777580..d1dde477f2e885b7112c2c09bb9506f7bb9992ba 100644 GIT binary patch delta 5260 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 delta 2740 zcmbtW4^Wgv6o32O-aqz}15Qp)5f2nl8D-YP?>0b~q5!-o6V!TodwXSPilM&1C7kQjYO+(I$(uejQ-E7BAKaUO zf(f9`O(7DNRV=G$k8Y0+j!}k0fB!6ignFL9CA4Y_*3&`3)ynHt9d-hX6@Zda0GDC_ zTs{CdT0D+iQh%Q12WT7saDEoR6&=94g#f=}kdf#I-9Qv_N&kh91h9cWj=)`yEPK=EF6pGG|g^%KZPOSdBurKzO;TyD4|w_VyL8_JFWOfce>Cua6H)pRW-t;~Pp z!J)=hmlnG=>)*NDh^*+p+12<=wLTL;C4Uau+ zv^t9XCAm5NdASb9qHIUv3dc+&$0npi$3Ums;Sa0~tl!{pr8!;VeGkngJnf{CaXf?W zh#c^9I)$ryoS2Fx;wkNyM93SRp*(`Q|+hP4z=xRYwv7+ zS=Ktp_cSVIp0tog70J*c)>ghe?ij4e2f7xqKHp3OCK4G=c@1i^2L@^B%0gheIAFp7 z(|x;;3Vho_>a$9RvRax`bjY*v=%6v70!G{~=TNK&Xj#rdS z1+f*;C*4~6A}Z{Q^j9mD@0rk@*5CA@P3cLW%qXzNCNneg%nY4iGM#eKArKHB^~+JZjX!aiClY7uu=m|F_Kd8UsI z(oe!5T6nRK&DPHjiHCeFg~v=_dHk%8O*X0c!e)0r3Vi7V*2GUWvvQ@Aa@|C>UpX<6 zTe6rqxRsKo8Bx+B48VMPtV${OL^ z$XqeQ^-v>A7sDM;hJSBj%oomYL*uWKe~^3`3L*hsQ=rT zczrXA(}w~V$D7&LR3DB83$aoWY(KkE9Bad~fLD$DU4ftEsX&V5)?2tQi*K>Fh3!vv zg^Hd#Y^M^h!=IpUKEvM=gd}oTm(RvGpY3{6eTX!_b5SiMh97#5K(<-96!idMuLjHq zQXJnt9#3wHD>^lf%B%LRP=ilg+;NjyL5PPxVOEoMb!secFsliM(%(PFw^qDwR_iU^ z9Ul2ChRK0UE|`Ik=QtZ7bt&T^g0eZ&a?0{&Oq(^mNVM41g`Qvo9eKP^Z5m8^_`V7? zogb}GY3z9XrSl-WGr$5YMbpHxuQOmv^sK zEAp0n*%316|4)DcKrR%(cQ6z3QTh%(h4aWS!fEise7FGT@cRVLU^^Gi^23#Crlp@V yaidaQt{>@~k})N7sxvLs?{QB}b?4@wG$qZM>dEmsr+CsQPj Date: Mon, 29 Apr 2013 17:26:05 +0100 Subject: [PATCH 056/467] Updated documentation with Autofilter execution, and provided an example script --- ...lter Reference developer documentation.doc | Bin 629760 -> 635904 bytes Examples/10autofilter-selection-display.php | 198 ++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 Examples/10autofilter-selection-display.php diff --git a/Documentation/PHPExcel AutoFilter Reference developer documentation.doc b/Documentation/PHPExcel AutoFilter Reference developer documentation.doc index 85f7e420976fa4643a4ba680616006e0b2338210..2a4a1d94048d8802beb8a5b17e6f2b8b9a37ba18 100644 GIT binary patch delta 17155 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 UL1bh|gYd}E;LNeFS*M%-3s+u<6#xJL delta 12404 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 diff --git a/Examples/10autofilter-selection-display.php b/Examples/10autofilter-selection-display.php new file mode 100644 index 000000000..1b26cbb50 --- /dev/null +++ b/Examples/10autofilter-selection-display.php @@ -0,0 +1,198 @@ +'); + +/** Include PHPExcel */ +require_once '../Classes/PHPExcel.php'; + + +// Create new PHPExcel object +echo date('H:i:s').' Create new PHPExcel object'.EOL; +$objPHPExcel = new PHPExcel(); + +// Set document properties +echo date('H:i:s').' Set document properties'.EOL; +$objPHPExcel->getProperties()->setCreator('Maarten Balliauw') + ->setLastModifiedBy('Maarten Balliauw') + ->setTitle('PHPExcel Test Document') + ->setSubject('PHPExcel Test Document') + ->setDescription('Test document for PHPExcel, generated using PHP classes.') + ->setKeywords('office PHPExcel php') + ->setCategory('Test result file'); + +// Create the worksheet +echo date('H:i:s').' Add data'.EOL; +$objPHPExcel->setActiveSheetIndex(0); +$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Financial Year') + ->setCellValue('B1', 'Financial Period') + ->setCellValue('C1', 'Country') + ->setCellValue('D1', 'Date') + ->setCellValue('E1', 'Sales Value') + ->setCellValue('F1', 'Expenditure') + ; +$startYear = $endYear = $currentYear = date('Y'); +$startYear--; +$endYear++; + +$years = range($startYear,$endYear); +$periods = range(1,12); +$countries = array( 'United States', 'UK', 'France', 'Germany', + 'Italy', 'Spain', 'Portugal', 'Japan' + ); + +$row = 2; +foreach($years as $year) { + foreach($periods as $period) { + foreach($countries as $country) { + $endDays = date('t',mktime(0,0,0,$period,1,$year)); + for($i = 1; $i <= $endDays; ++$i) { + $eDate = PHPExcel_Shared_Date::FormattedPHPToExcel( + $year, + $period, + $i + ); + $value = rand(500,1000) * (1 + rand(-0.25,+0.25)); + $salesValue = $invoiceValue = NULL; + $incomeOrExpenditure = rand(-1,1); + if ($incomeOrExpenditure == -1) { + $expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25)); + $income = NULL; + } elseif ($incomeOrExpenditure == 1) { + $expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25)); + $income = rand(500,1000) * (1 + rand(-0.25,+0.25));; + } else { + $expenditure = NULL; + $income = rand(500,1000) * (1 + rand(-0.25,+0.25));; + } + $dataArray = array( $year, + $period, + $country, + $eDate, + $income, + $expenditure, + ); + $objPHPExcel->getActiveSheet()->fromArray($dataArray, NULL, 'A'.$row++); + } + } + } +} +$row--; + + +// Set styling +echo date('H:i:s').' Set styling'.EOL; +$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getFont()->setBold(true); +$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getAlignment()->setWrapText(TRUE); +$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12.5); +$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(10.5); +$objPHPExcel->getActiveSheet()->getStyle('D2:D'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2); +$objPHPExcel->getActiveSheet()->getStyle('E2:F'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE); +$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(14); +$objPHPExcel->getActiveSheet()->freezePane('A2'); + + + +// Set autofilter range +echo date('H:i:s').' Set autofilter range'.EOL; +// Always include the complete filter range! +// Excel does support setting only the caption +// row, but that's not a best practise... +$objPHPExcel->getActiveSheet()->setAutoFilter($objPHPExcel->getActiveSheet()->calculateWorksheetDimension()); + +// Set active filters +$autoFilter = $objPHPExcel->getActiveSheet()->getAutoFilter(); +echo date('H:i:s').' Set active filters'.EOL; +// Filter the Country column on a filter value of countries beginning with the letter U (or Japan) +// We use * as a wildcard, so specify as U* and using a wildcard requires customFilter +$autoFilter->getColumn('C') + ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER) + ->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + 'u*' + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); +$autoFilter->getColumn('C') + ->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + 'japan' + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); +// Filter the Date column on a filter value of the first day of every period of the current year +// We us a dateGroup ruletype for this, although it is still a standard filter +foreach($periods as $period) { + $endDate = date('t',mktime(0,0,0,$period,1,$currentYear)); + + $autoFilter->getColumn('D') + ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) + ->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + array( + 'year' => $currentYear, + 'month' => $period, + 'day' => $endDate + ) + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); +} +// Display only sales values that are blank +// Standard filter, operator equals, and value of NULL +$autoFilter->getColumn('E') + ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) + ->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + '' + ); + +// Execute filtering +echo date('H:i:s').' Execute filtering'.EOL; +$autoFilter->showHideRows(); + +// Set active sheet index to the first sheet, so Excel opens this as the first sheet +$objPHPExcel->setActiveSheetIndex(0); + + +// Display Results of filtering +echo date('H:i:s').' Display filtered rows'.EOL; +foreach ($objPHPExcel->getActiveSheet()->getRowIterator() as $row) { + if ($objPHPExcel->getActiveSheet()->getRowDimension($row->getRowIndex())->getVisible()) { + echo ' Row number - ' , $row->getRowIndex() , ' '; + echo $objPHPExcel->getActiveSheet()->getCell('C'.$row->getRowIndex())->getValue(), ' '; + echo $objPHPExcel->getActiveSheet()->getCell('D'.$row->getRowIndex())->getFormattedValue(), ' '; + echo EOL; + } +} From b8c462f1c225c2a5abb7362bdf5311fc5571fba3 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 29 Apr 2013 17:39:03 +0100 Subject: [PATCH 057/467] ADded new autofilter example to runall --- Examples/runall.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Examples/runall.php b/Examples/runall.php index 7e97ee825..b3ad069c0 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -50,6 +50,7 @@ , '10autofilter.php' , '10autofilter-selection-1.php' , '10autofilter-selection-2.php' + , '10autofilter-selection-display.php' , '11documentsecurity.php' , '11documentsecurity-xls.php' , '12cellProtection.php' From 73d2757728af7ed226857004efa97774e1f5ec4c Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 29 Apr 2013 22:47:36 +0100 Subject: [PATCH 058/467] Fix for quoted worksheet names in INDIRECT and OFFSET methods; and Docblock fixes --- Classes/PHPExcel/Calculation/DateTime.php | 12 +++++++++ Classes/PHPExcel/Calculation/Engineering.php | 17 +++++++----- Classes/PHPExcel/Calculation/Financial.php | 4 --- Classes/PHPExcel/Calculation/LookupRef.php | 28 +++++++++++--------- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/Classes/PHPExcel/Calculation/DateTime.php b/Classes/PHPExcel/Calculation/DateTime.php index 854f8f842..3902924d5 100644 --- a/Classes/PHPExcel/Calculation/DateTime.php +++ b/Classes/PHPExcel/Calculation/DateTime.php @@ -56,6 +56,18 @@ public static function _isLeapYear($year) { } // function _isLeapYear() + /** + * Return the number of days between two dates based on a 360 day calendar + * + * @param integer $startDay Day of month of the start date + * @param integer $startMonth Month of the start date + * @param integer $startYear Year of the start date + * @param integer $endDay Day of month of the start date + * @param integer $endMonth Month of the start date + * @param integer $endYear Year of the start date + * @param boolean $methodUS Whether to use the US method or the European method of calculation + * @return integer Number of days between the start date and the end date + */ private static function _dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, $methodUS) { if ($startDay == 31) { --$startDay; diff --git a/Classes/PHPExcel/Calculation/Engineering.php b/Classes/PHPExcel/Calculation/Engineering.php index 50c49026d..b96f16d3c 100644 --- a/Classes/PHPExcel/Calculation/Engineering.php +++ b/Classes/PHPExcel/Calculation/Engineering.php @@ -741,8 +741,6 @@ public static function _parseComplex($complexNumber) { /** - * _cleanComplex - * * Cleans the leading characters in a complex number string * * @param string $complexNumber The complex number to clean @@ -756,20 +754,25 @@ private static function _cleanComplex($complexNumber) { return $complexNumber; } - - private static function _nbrConversionFormat($xVal,$places) { + /** + * Formats a number base string value with leading zeroes + * + * @param string $xVal The "number" to pad + * @param integer $places The length that we want to pad this value + * @return string The padded "number" + */ + private static function _nbrConversionFormat($xVal, $places) { if (!is_null($places)) { if (strlen($xVal) <= $places) { - return substr(str_pad($xVal,$places,'0',STR_PAD_LEFT),-10); + return substr(str_pad($xVal, $places, '0', STR_PAD_LEFT), -10); } else { return PHPExcel_Calculation_Functions::NaN(); } } - return substr($xVal,-10); + return substr($xVal, -10); } // function _nbrConversionFormat() - /** * BESSELI * diff --git a/Classes/PHPExcel/Calculation/Financial.php b/Classes/PHPExcel/Calculation/Financial.php index d8e5195af..4c42277cc 100644 --- a/Classes/PHPExcel/Calculation/Financial.php +++ b/Classes/PHPExcel/Calculation/Financial.php @@ -1523,14 +1523,11 @@ public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) { } } // function NPER() - /** * NPV * * Returns the Net Present Value of a cash flow series given a discount rate. * - * @param float Discount interest rate - * @param array Cash flow series * @return float */ public static function NPV() { @@ -1553,7 +1550,6 @@ public static function NPV() { return $returnValue; } // function NPV() - /** * PMT * diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index ba89a1147..a22faff38 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -251,8 +251,9 @@ public static function ROWS($cellAddress=Null) { * * @access public * @category Logical Functions - * @param string $linkURL Value to check, is also the value returned when no error - * @param string $displayName Value to return when testValue is an error condition + * @param string $linkURL Value to check, is also the value returned when no error + * @param string $displayName Value to return when testValue is an error condition + * @param PHPExcel_Cell $pCell The cell to set the hyperlink in * @return mixed The value of $displayName (or $linkURL if $displayName was blank) */ public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Cell $pCell = null) { @@ -287,13 +288,14 @@ public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Ce * * NOTE - INDIRECT() does not yet support the optional a1 parameter introduced in Excel 2010 * - * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of rows + * @param cellAddress $cellAddress The cell address of the current cell (containing this formula) + * @param PHPExcel_Cell $pCell The current cell (containing this formula) * @return mixed The cells referenced by cellAddress * * @todo Support for the optional a1 parameter introduced in Excel 2010 * */ - public static function INDIRECT($cellAddress=Null, PHPExcel_Cell $pCell = null) { + public static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL) { $cellAddress = PHPExcel_Calculation_Functions::flattenSingleValue($cellAddress); if (is_null($cellAddress) || $cellAddress === '') { return PHPExcel_Calculation_Functions::REF(); @@ -307,29 +309,30 @@ public static function INDIRECT($cellAddress=Null, PHPExcel_Cell $pCell = null) if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress1, $matches)) || ((!is_null($cellAddress2)) && (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress2, $matches)))) { - if (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $cellAddress1, $matches)) { return PHPExcel_Calculation_Functions::REF(); } - if (strpos($cellAddress,'!') !== false) { - list($sheetName,$cellAddress) = explode('!',$cellAddress); + if (strpos($cellAddress,'!') !== FALSE) { + list($sheetName, $cellAddress) = explode('!',$cellAddress); + $sheetName = trim($sheetName, "'"); $pSheet = $pCell->getParent()->getParent()->getSheetByName($sheetName); } else { $pSheet = $pCell->getParent(); } - return PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, False); + return PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, FALSE); } - if (strpos($cellAddress,'!') !== false) { + if (strpos($cellAddress,'!') !== FALSE) { list($sheetName,$cellAddress) = explode('!',$cellAddress); + $sheetName = trim($sheetName, "'"); $pSheet = $pCell->getParent()->getParent()->getSheetByName($sheetName); } else { $pSheet = $pCell->getParent(); } - return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, False); + return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, FALSE); } // function INDIRECT() @@ -373,9 +376,10 @@ public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null, return PHPExcel_Calculation_Functions::REF(); } - $sheetName = null; + $sheetName = NULL; if (strpos($cellAddress,"!")) { list($sheetName,$cellAddress) = explode("!",$cellAddress); + $sheetName = trim($sheetName, "'"); } if (strpos($cellAddress,":")) { list($startCell,$endCell) = explode(":",$cellAddress); @@ -416,7 +420,7 @@ public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null, $cellAddress .= ':'.$endCellColumn.$endCellRow; } - if ($sheetName !== null) { + if ($sheetName !== NULL) { $pSheet = $pCell->getParent()->getParent()->getSheetByName($sheetName); } else { $pSheet = $pCell->getParent(); From c2bbafb4d9e1c2c64445800156c53b4a1322bceb Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 29 Apr 2013 23:09:39 +0100 Subject: [PATCH 059/467] Docblock fixes --- Classes/PHPExcel/Calculation/MathTrig.php | 13 ++++++----- Classes/PHPExcel/Calculation/Statistical.php | 23 +++++++++++++------- Classes/PHPExcel/Calculation/TextData.php | 21 ++++++++++-------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index 2da748afd..134fff7d9 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -495,13 +495,13 @@ public static function LCM() { * * @access public * @category Mathematical and Trigonometric Functions - * @param float $value The positive real number for which you want the logarithm + * @param float $number The positive real number for which you want the logarithm * @param float $base The base of the logarithm. If base is omitted, it is assumed to be 10. * @return float */ public static function LOG_BASE($number = NULL, $base = 10) { $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - $base = (is_null($base)) ? 10 : (float) PHPExcel_Calculation_Functions::flattenSingleValue($base); + $base = (is_null($base)) ? 10 : (float) PHPExcel_Calculation_Functions::flattenSingleValue($base); if ((!is_numeric($base)) || (!is_numeric($number))) return PHPExcel_Calculation_Functions::VALUE(); @@ -1252,7 +1252,8 @@ public static function SUMSQ() { /** * SUMX2MY2 * - * @param mixed $value Value to check + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 * @return float */ public static function SUMX2MY2($matrixData1,$matrixData2) { @@ -1281,7 +1282,8 @@ public static function SUMX2MY2($matrixData1,$matrixData2) { /** * SUMX2PY2 * - * @param mixed $value Value to check + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 * @return float */ public static function SUMX2PY2($matrixData1,$matrixData2) { @@ -1310,7 +1312,8 @@ public static function SUMX2PY2($matrixData1,$matrixData2) { /** * SUMXMY2 * - * @param mixed $value Value to check + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 * @return float */ public static function SUMXMY2($matrixData1,$matrixData2) { diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php index 05dae7be4..348b459cf 100644 --- a/Classes/PHPExcel/Calculation/Statistical.php +++ b/Classes/PHPExcel/Calculation/Statistical.php @@ -834,6 +834,7 @@ public static function AVERAGEA() { * @category Mathematical and Trigonometric Functions * @param mixed $arg,... Data values * @param string $condition The criteria that defines which cells will be checked. + * @param mixed[] $averageArgs Data values * @return float */ public static function AVERAGEIF($aArgs,$condition,$averageArgs = array()) { @@ -912,6 +913,8 @@ public static function BETADIST($value,$alpha,$beta,$rMin=0,$rMax=1) { * @param float $probability Probability at which you want to evaluate the distribution * @param float $alpha Parameter to the distribution * @param float $beta Parameter to the distribution + * @param float $rMin Minimum value + * @param float $rMax Maximum value * @param boolean $cumulative * @return float * @@ -1954,9 +1957,9 @@ public static function LARGE() { * @param boolean A logical value specifying whether to return additional regression statistics. * @return array */ - public static function LINEST($yValues,$xValues=null,$const=True,$stats=False) { - $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); - $stats = (is_null($stats)) ? False : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); + public static function LINEST($yValues, $xValues = NULL, $const = TRUE, $stats = FALSE) { + $const = (is_null($const)) ? TRUE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $stats = (is_null($stats)) ? FALSE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); if (!self::_checkTrendArrays($yValues,$xValues)) { @@ -2059,7 +2062,9 @@ public static function LOGEST($yValues,$xValues=null,$const=True,$stats=False) { * * Returns the inverse of the normal cumulative distribution * - * @param float $value + * @param float $probability + * @param float $mean + * @param float $stdDev * @return float * * @todo Try implementing P J Acklam's refinement algorithm for greater @@ -2088,6 +2093,8 @@ public static function LOGINV($probability, $mean, $stdDev) { * with parameters mean and standard_dev. * * @param float $value + * @param float $mean + * @param float $stdDev * @return float */ public static function LOGNORMDIST($value, $mean, $stdDev) { @@ -3621,14 +3628,14 @@ public static function WEIBULL($value, $alpha, $beta, $cumulative) { * Returns the Weibull distribution. Use this distribution in reliability * analysis, such as calculating a device's mean time to failure. * - * @param float $value - * @param float $alpha Alpha Parameter - * @param float $beta Beta Parameter + * @param float $dataSet + * @param float $m0 Alpha Parameter + * @param float $sigma Beta Parameter * @param boolean $cumulative * @return float * */ - public static function ZTEST($dataSet, $m0, $sigma=null) { + public static function ZTEST($dataSet, $m0, $sigma = NULL) { $dataSet = PHPExcel_Calculation_Functions::flattenArrayIndexed($dataSet); $m0 = PHPExcel_Calculation_Functions::flattenSingleValue($m0); $sigma = PHPExcel_Calculation_Functions::flattenSingleValue($sigma); diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php index d08829cbb..46decb3df 100644 --- a/Classes/PHPExcel/Calculation/TextData.php +++ b/Classes/PHPExcel/Calculation/TextData.php @@ -89,7 +89,7 @@ public static function CHARACTER($character) { /** * TRIMNONPRINTABLE * - * @param mixed $value Value to check + * @param mixed $stringValue Value to check * @return string */ public static function TRIMNONPRINTABLE($stringValue = '') { @@ -113,7 +113,7 @@ public static function TRIMNONPRINTABLE($stringValue = '') { /** * TRIMSPACES * - * @param mixed $value Value to check + * @param mixed $stringValue Value to check * @return string */ public static function TRIMSPACES($stringValue = '') { @@ -133,7 +133,7 @@ public static function TRIMSPACES($stringValue = '') { /** * ASCIICODE * - * @param string $character Value + * @param string $characters Value * @return int */ public static function ASCIICODE($characters) { @@ -296,7 +296,9 @@ public static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) { /** * FIXEDFORMAT * - * @param mixed $value Value to check + * @param mixed $value Value to check + * @param integer $decimals + * @param boolean $no_commas * @return boolean */ public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = FALSE) { @@ -407,7 +409,6 @@ public static function RIGHT($value = '', $chars = 1) { * STRINGLENGTH * * @param string $value Value - * @param int $chars Number of characters * @return string */ public static function STRINGLENGTH($value = '') { @@ -485,9 +486,10 @@ public static function PROPERCASE($mixedCaseString) { /** * REPLACE * - * @param string $value Value - * @param int $start Start character - * @param int $chars Number of characters + * @param string $oldText String to modify + * @param int $start Start character + * @param int $chars Number of characters + * @param string $newText String to replace in defined position * @return string */ public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) { @@ -553,7 +555,7 @@ public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $ins /** * RETURNSTRING * - * @param mixed $value Value to check + * @param mixed $testValue Value to check * @return boolean */ public static function RETURNSTRING($testValue = '') { @@ -570,6 +572,7 @@ public static function RETURNSTRING($testValue = '') { * TEXTFORMAT * * @param mixed $value Value to check + * @param string $format Format mask to use * @return boolean */ public static function TEXTFORMAT($value,$format) { From 216ef82a1413dee31b7a395b4b0214499f3a8866 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 30 Apr 2013 12:45:13 +0100 Subject: [PATCH 060/467] Yet more docblock fixes --- Classes/PHPExcel/Calculation.php | 62 +++++++++++++++++++++++++++++--- Classes/PHPExcel/Chart.php | 24 +++++++++++++ 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 2b3099aae..9e51ea32a 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -53,7 +53,7 @@ /** - * PHPExcel_Calculation (Singleton) + * PHPExcel_Calculation (Multiton) * * @category PHPExcel * @package PHPExcel_Calculation @@ -105,7 +105,7 @@ class PHPExcel_Calculation { private $_workbook; /** - * List of instances of the calculation engine that we've instantiated + * List of instances of the calculation engine that we've instantiated for individual workbooks * * @access private * @var PHPExcel_Calculation[] @@ -194,26 +194,80 @@ class PHPExcel_Calculation { */ private $_cyclicReferenceStack; + /** + * Current iteration counter for cyclic formulae + * If the value is 0 (or less) then cyclic formulae will throw an exception, + * otherwise they will iterate to the limit defined here before returning a result + * + * @var integer + * + */ private $_cyclicFormulaCount = 0; + private $_cyclicFormulaCell = ''; - public $cyclicFormulaCount = 0; + /** + * Number of iterations for cyclic formulae + * + * @var integer + * + */ + public $cyclicFormulaCount = 0; + /** + * Precision used for calculations + * + * @var integer + * + */ private $_savedPrecision = 14; + /** + * The current locale setting + * + * @var string + * + */ private static $_localeLanguage = 'en_us'; // US English (default locale) + + /** + * List of available locale settings + * Note that this is read for the locale subdirectory only when requested + * + * @var string[] + * + */ private static $_validLocaleLanguages = array( 'en' // English (default language) ); + /** + * Locale-specific argument separator for function arguments + * + * @var string + * + */ private static $_localeArgumentSeparator = ','; private static $_localeFunctions = array(); + + /** + * Locale-specific translations for Excel constants (True, False and Null) + * + * @var string[] + * + */ public static $_localeBoolean = array( 'TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL' ); - // Constant conversion from text name/value to actual (datatyped) value + /** + * Excel constant string translations to their PHP equivalents + * Constant conversion from text name/value to actual (datatyped) value + * + * @var string[] + * + */ private static $_ExcelConstants = array('TRUE' => TRUE, 'FALSE' => FALSE, 'NULL' => NULL diff --git a/Classes/PHPExcel/Chart.php b/Classes/PHPExcel/Chart.php index 3e9572dc7..4c6d5e322 100644 --- a/Classes/PHPExcel/Chart.php +++ b/Classes/PHPExcel/Chart.php @@ -378,6 +378,13 @@ public function setTopLeftCell($cell) { return $this; } + /** + * Set the offset position within the Top Left cell for the chart + * + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ public function setTopLeftOffset($xOffset=null,$yOffset=null) { if (!is_null($xOffset)) $this->setTopLeftXOffset($xOffset); @@ -387,6 +394,11 @@ public function setTopLeftOffset($xOffset=null,$yOffset=null) { return $this; } + /** + * Get the offset position within the Top Left cell for the chart + * + * @return integer[] + */ public function getTopLeftOffset() { return array( 'X' => $this->_topLeftXOffset, 'Y' => $this->_topLeftYOffset @@ -458,6 +470,13 @@ public function getBottomRightCell() { return $this->_bottomRightCellRef; } + /** + * Set the offset position within the Bottom Right cell for the chart + * + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ public function setBottomRightOffset($xOffset=null,$yOffset=null) { if (!is_null($xOffset)) $this->setBottomRightXOffset($xOffset); @@ -467,6 +486,11 @@ public function setBottomRightOffset($xOffset=null,$yOffset=null) { return $this; } + /** + * Get the offset position within the Bottom Right cell for the chart + * + * @return integer[] + */ public function getBottomRightOffset() { return array( 'X' => $this->_bottomRightXOffset, 'Y' => $this->_bottomRightYOffset From fd2a3773d8dc326654696f6ad83af58aa81dd2e9 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 6 May 2013 23:39:49 +0100 Subject: [PATCH 061/467] Refactoring of canRead function in Readers, and minor fixes to Examples and documentation updates --- Classes/PHPExcel/Reader/Abstract.php | 51 ++++- Classes/PHPExcel/Reader/CSV.php | 190 ++++++------------ Classes/PHPExcel/Reader/Excel2003XML.php | 14 +- Classes/PHPExcel/Reader/HTML.php | 38 ++-- Classes/PHPExcel/Reader/SYLK.php | 68 +++---- .../PHPExcel developer documentation.doc | Bin 817152 -> 819200 bytes ...-chart.php => 33chartcreate-composite.php} | 0 Examples/33chartcreate-scatter.php | 138 +++++++++++++ Examples/34chartupdate.php | 5 +- 9 files changed, 292 insertions(+), 212 deletions(-) rename Examples/{33chartcreate-composite-chart.php => 33chartcreate-composite.php} (100%) create mode 100644 Examples/33chartcreate-scatter.php diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php index 224136a5b..1c61197dd 100644 --- a/Classes/PHPExcel/Reader/Abstract.php +++ b/Classes/PHPExcel/Reader/Abstract.php @@ -67,6 +67,8 @@ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader */ protected $_readFilter = NULL; + protected $_fileHandle = NULL; + /** * Read data only? @@ -79,7 +81,6 @@ public function getReadDataOnly() { return $this->_readDataOnly; } - /** * Set read data only * Set to true, to advise the Reader only to read data values for cells, and to ignore any formatting information. @@ -94,7 +95,6 @@ public function setReadDataOnly($pValue = FALSE) { return $this; } - /** * Read charts in workbook? * If this is true, then the Reader will include any charts that exist in the workbook. @@ -107,7 +107,6 @@ public function getIncludeCharts() { return $this->_includeCharts; } - /** * Set read charts in workbook * Set to true, to advise the Reader to include any charts that exist in the workbook. @@ -123,7 +122,6 @@ public function setIncludeCharts($pValue = FALSE) { return $this; } - /** * Get which sheets to load * Returns either an array of worksheet names (the list of worksheets that should be loaded), or a null @@ -136,7 +134,6 @@ public function getLoadSheetsOnly() return $this->_loadSheetsOnly; } - /** * Set which sheets to load * @@ -153,7 +150,6 @@ public function setLoadSheetsOnly($value = NULL) return $this; } - /** * Set all sheets to load * Tells the Reader to load all worksheets from the workbook. @@ -166,7 +162,6 @@ public function setLoadAllSheets() return $this; } - /** * Read filter * @@ -176,7 +171,6 @@ public function getReadFilter() { return $this->_readFilter; } - /** * Set read filter * @@ -188,5 +182,46 @@ public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) { return $this; } + /** + * Open file for reading + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + * @return resource + */ + protected function _openFile($pFilename) + { + // Check if file exists + if (!file_exists($pFilename) || !is_readable($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Open file + $this->_fileHandle = fopen($pFilename, 'r'); + if ($this->_fileHandle === FALSE) { + throw new PHPExcel_Reader_Exception("Could not open file " . $pFilename . " for reading."); + } + } + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + try { + $this->_openFile($pFilename); + } catch (Exception $e) { + return FALSE; + } + + $readable = $this->_isValidFormat(); + fclose ($this->_fileHandle); + return $readable; + } } diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index 4678f7dc5..a0fac3832 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -92,112 +92,104 @@ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_R */ private $_contiguous = false; - /** * Row counter for loading rows contiguously * - * @access private * @var int */ private $_contiguousRow = -1; + /** * Create a new PHPExcel_Reader_CSV */ public function __construct() { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - } // function __construct() - + } /** - * Can the current PHPExcel_Reader_IReader read the file? + * Validate that the current file is a CSV file * - * @access public - * @param string $pFilename * @return boolean - * @throws PHPExcel_Reader_Exception */ - public function canRead($pFilename) + protected function _isValidFormat() { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - return true; - } // function canRead() - + return TRUE; + } /** * Set input encoding * - * @access public * @param string $pValue Input encoding */ public function setInputEncoding($pValue = 'UTF-8') { $this->_inputEncoding = $pValue; return $this; - } // function setInputEncoding() - + } /** * Get input encoding * - * @access public * @return string */ public function getInputEncoding() { return $this->_inputEncoding; - } // function getInputEncoding() - + } /** - * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * Move filepointer past any BOM marker * - * @access public - * @param string $pFilename - * @throws PHPExcel_Reader_Exception */ - public function listWorksheetInfo($pFilename) + protected function _skipBOM() { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - // Open file - $fileHandle = fopen($pFilename, 'r'); - if ($fileHandle === false) { - throw new PHPExcel_Reader_Exception("Could not open file " . $pFilename . " for reading."); - } + rewind($fileHandle); - // Skip BOM, if any switch ($this->_inputEncoding) { case 'UTF-8': - fgets($fileHandle, 4) == "\xEF\xBB\xBF" ? - fseek($fileHandle, 3) : fseek($fileHandle, 0); + fgets($this->_fileHandle, 4) == "\xEF\xBB\xBF" ? + fseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0); break; case 'UTF-16LE': - fgets($fileHandle, 3) == "\xFF\xFE" ? - fseek($fileHandle, 2) : fseek($fileHandle, 0); + fgets($this->_fileHandle, 3) == "\xFF\xFE" ? + fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); break; case 'UTF-16BE': - fgets($fileHandle, 3) == "\xFE\xFF" ? - fseek($fileHandle, 2) : fseek($fileHandle, 0); + fgets($this->_fileHandle, 3) == "\xFE\xFF" ? + fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); break; case 'UTF-32LE': - fgets($fileHandle, 5) == "\xFF\xFE\x00\x00" ? - fseek($fileHandle, 4) : fseek($fileHandle, 0); + fgets($this->_fileHandle, 5) == "\xFF\xFE\x00\x00" ? + fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); break; case 'UTF-32BE': - fgets($fileHandle, 5) == "\x00\x00\xFE\xFF" ? - fseek($fileHandle, 4) : fseek($fileHandle, 0); + fgets($this->_fileHandle, 5) == "\x00\x00\xFE\xFF" ? + fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); break; default: break; } + } + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + + // Skip BOM, if any + $this->_skipBOM(); $escapeEnclosures = array( "\\" . $this->_enclosure, $this->_enclosure . $this->_enclosure ); @@ -223,11 +215,9 @@ public function listWorksheetInfo($pFilename) return $worksheetInfo; } - /** * Loads PHPExcel from file * - * @access public * @param string $pFilename * @return PHPExcel * @throws PHPExcel_Reader_Exception @@ -239,13 +229,11 @@ public function load($pFilename) // Load into this instance return $this->loadIntoExisting($pFilename, $objPHPExcel); - } // function load() - + } /** * Loads PHPExcel from file into PHPExcel instance * - * @access public * @param string $pFilename * @param PHPExcel $objPHPExcel * @return PHPExcel @@ -253,51 +241,25 @@ public function load($pFilename) */ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - // Create new PHPExcel - while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { - $objPHPExcel->createSheet(); - } - $sheet = $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex ); - $lineEnding = ini_get('auto_detect_line_endings'); ini_set('auto_detect_line_endings', true); // Open file - $fileHandle = fopen($pFilename, 'r'); - if ($fileHandle === false) { - throw new PHPExcel_Reader_Exception("Could not open file $pFilename for reading."); + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } + $fileHandle = $this->_fileHandle; // Skip BOM, if any - switch ($this->_inputEncoding) { - case 'UTF-8': - fgets($fileHandle, 4) == "\xEF\xBB\xBF" ? - fseek($fileHandle, 3) : fseek($fileHandle, 0); - break; - case 'UTF-16LE': - fgets($fileHandle, 3) == "\xFF\xFE" ? - fseek($fileHandle, 2) : fseek($fileHandle, 0); - break; - case 'UTF-16BE': - fgets($fileHandle, 3) == "\xFE\xFF" ? - fseek($fileHandle, 2) : fseek($fileHandle, 0); - break; - case 'UTF-32LE': - fgets($fileHandle, 5) == "\xFF\xFE\x00\x00" ? - fseek($fileHandle, 4) : fseek($fileHandle, 0); - break; - case 'UTF-32BE': - fgets($fileHandle, 5) == "\x00\x00\xFE\xFF" ? - fseek($fileHandle, 4) : fseek($fileHandle, 0); - break; - default: - break; + $this->_skipBOM(); + + // Create new PHPExcel object + while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + $objPHPExcel->createSheet(); } + $sheet = $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); $escapeEnclosures = array( "\\" . $this->_enclosure, $this->_enclosure . $this->_enclosure @@ -341,48 +303,40 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Return return $objPHPExcel; - } // function loadIntoExisting() - + } /** * Get delimiter * - * @access public * @return string */ public function getDelimiter() { return $this->_delimiter; - } // function getDelimiter() - + } /** * Set delimiter * - * @access public * @param string $pValue Delimiter, defaults to , * @return PHPExcel_Reader_CSV */ public function setDelimiter($pValue = ',') { $this->_delimiter = $pValue; return $this; - } // function setDelimiter() - + } /** * Get enclosure * - * @access public * @return string */ public function getEnclosure() { return $this->_enclosure; - } // function getEnclosure() - + } /** * Set enclosure * - * @access public * @param string $pValue Enclosure, defaults to " * @return PHPExcel_Reader_CSV */ @@ -392,82 +346,70 @@ public function setEnclosure($pValue = '"') { } $this->_enclosure = $pValue; return $this; - } // function setEnclosure() - + } /** * Get line ending * - * @access public * @return string */ public function getLineEnding() { return $this->_lineEnding; - } // function getLineEnding() - + } /** * Set line ending * - * @access public * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) * @return PHPExcel_Reader_CSV */ public function setLineEnding($pValue = PHP_EOL) { $this->_lineEnding = $pValue; return $this; - } // function setLineEnding() - + } /** * Get sheet index * - * @access public - * @return int + * @return integer */ public function getSheetIndex() { return $this->_sheetIndex; - } // function getSheetIndex() - + } /** * Set sheet index * - * @access public * @param integer $pValue Sheet index * @return PHPExcel_Reader_CSV */ public function setSheetIndex($pValue = 0) { $this->_sheetIndex = $pValue; return $this; - } // function setSheetIndex() - + } /** * Set Contiguous * - * @access public * @param boolean $contiguous */ public function setContiguous($contiguous = FALSE) { $this->_contiguous = (bool) $contiguous; if (!$contiguous) { - $this->_contiguousRow = -1; + $this->_contiguousRow = -1; } return $this; - } // function setInputEncoding() - + } /** * Get Contiguous * - * @access public * @return boolean */ public function getContiguous() { return $this->_contiguous; - } // function getSheetIndex() + } } diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index 584968559..ec910f780 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -92,15 +92,13 @@ public function canRead($pFilename) '' ); - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - + // Open file + $this->_openFile($pFilename); + $fileHandle = $this->_fileHandle; + // Read sample data (first 2 KB will do) - $fh = fopen($pFilename, 'r'); - $data = fread($fh, 2048); - fclose($fh); + $data = fread($fileHandle, 2048); + fclose($fileHandle); $valid = true; foreach($signature as $match) { diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index d8c5821ba..3ff0a172e 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -109,24 +109,14 @@ public function __construct() { } /** - * Can the current PHPExcel_Reader_IReader read the file? + * Validate that the current file is an HTML file * - * @param string $pFilename - * @return boolean - * @throws PHPExcel_Reader_Exception + * @return boolean */ - public function canRead($pFilename) + protected function _isValidFormat() { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - // Read sample data (first 2 KB will do) - $fh = fopen($pFilename, 'r'); - $data = fread($fh, 2048); - fclose($fh); - + // Reading 2048 bytes should be enough to validate that the format is HTML + $data = fread($this->_fileHandle, 2048); if ((strpos('<',$data) !== FALSE) && (strlen($data) !== strlen(strip_tags($data)))) { return TRUE; @@ -416,14 +406,14 @@ private function _processDomElement(DOMNode $element, $sheet, &$row, &$column, & */ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - if (!is_file($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! The given file is not a regular file."); + // Open file to validate + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid HTML file."); } + // Close after validating + fclose ($this->_fileHandle); // Create new PHPExcel while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { @@ -433,9 +423,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Create a new DOM object $dom = new domDocument; - // Load the HTML file into the DOM object + // Reload the HTML file into the DOM object $loaded = $dom->loadHTMLFile($pFilename); - if ($loaded === false) { + if ($loaded === FALSE) { throw new PHPExcel_Reader_Exception('Failed to load ',$pFilename,' as a DOM Document'); } diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index d3a993573..a6e22e6dd 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -79,42 +79,31 @@ public function __construct() { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); } - /** - * Can the current PHPExcel_Reader_IReader read the file? + * Validate that the current file is a SYLK file * - * @param string $pFilename - * @return boolean - * @throws PHPExcel_Reader_Exception + * @return boolean */ - public function canRead($pFilename) + protected function _isValidFormat() { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - // Read sample data (first 2 KB will do) - $fh = fopen($pFilename, 'r'); - $data = fread($fh, 2048); - fclose($fh); + $data = fread($this->_fileHandle, 2048); // Count delimiters in file $delimiterCount = substr_count($data, ';'); if ($delimiterCount < 1) { - return false; + return FALSE; } // Analyze first line looking for ID; signature $lines = explode("\n", $data); if (substr($lines[0],0,4) != 'ID;P') { - return false; + return FALSE; } - return true; + return TRUE; } - /** * Set input encoding * @@ -126,7 +115,6 @@ public function setInputEncoding($pValue = 'ANSI') return $this; } - /** * Get input encoding * @@ -137,7 +125,6 @@ public function getInputEncoding() return $this->_inputEncoding; } - /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) * @@ -146,16 +133,13 @@ public function getInputEncoding() */ public function listWorksheetInfo($pFilename) { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - // Open file - $fileHandle = fopen($pFilename, 'r'); - if ($fileHandle === false) { - throw new PHPExcel_Reader_Exception("Could not open file " . $pFilename . " for reading."); + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } + $fileHandle = $this->_fileHandle; $worksheetInfo = array(); $worksheetInfo[0]['worksheetName'] = 'Worksheet'; @@ -177,7 +161,7 @@ public function listWorksheetInfo($pFilename) // explode each row at semicolons while taking into account that literal semicolon (;) // is escaped like this (;;) - $rowData = explode("\t",str_replace('?',';',str_replace(';',"\t",str_replace(';;','?',rtrim($rowData))))); + $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); $dataType = array_shift($rowData); if ($dataType == 'C') { @@ -209,7 +193,6 @@ public function listWorksheetInfo($pFilename) return $worksheetInfo; } - /** * Loads PHPExcel from file * @@ -226,7 +209,6 @@ public function load($pFilename) return $this->loadIntoExisting($pFilename, $objPHPExcel); } - /** * Loads PHPExcel from file into PHPExcel instance * @@ -237,11 +219,15 @@ public function load($pFilename) */ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } - + $fileHandle = $this->_fileHandle; + rewind($fileHandle); + // Create new PHPExcel while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { $objPHPExcel->createSheet(); @@ -251,12 +237,6 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $fromFormats = array('\-', '\ '); $toFormats = array('-', ' '); - // Open file - $fileHandle = fopen($pFilename, 'r'); - if ($fileHandle === false) { - throw new PHPExcel_Reader_Exception("Could not open file $pFilename for reading."); - } - // Loop through file $rowData = array(); $column = $row = ''; @@ -404,7 +384,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } if (($formatStyle > '') && ($column > '') && ($row > '')) { $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); - $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($this->_formats[$formatStyle]); + if (isset($this->_formats[$formatStyle])) { + $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($this->_formats[$formatStyle]); + } } if ((!empty($styleData)) && ($column > '') && ($row > '')) { $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); @@ -444,7 +426,6 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) return $objPHPExcel; } - /** * Get sheet index * @@ -454,7 +435,6 @@ public function getSheetIndex() { return $this->_sheetIndex; } - /** * Set sheet index * diff --git a/Documentation/PHPExcel developer documentation.doc b/Documentation/PHPExcel developer documentation.doc index 30600f63257b1de167940293d8a205b0db6f7780..6eb230c93b96f8c59553e0922607e6f79ea36134 100644 GIT binary patch delta 32396 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 N@2s0JNi#$Be*piUI!yoo diff --git a/Examples/33chartcreate-composite-chart.php b/Examples/33chartcreate-composite.php similarity index 100% rename from Examples/33chartcreate-composite-chart.php rename to Examples/33chartcreate-composite.php diff --git a/Examples/33chartcreate-scatter.php b/Examples/33chartcreate-scatter.php new file mode 100644 index 000000000..9d62e9166 --- /dev/null +++ b/Examples/33chartcreate-scatter.php @@ -0,0 +1,138 @@ +'); + +date_default_timezone_set('Europe/London'); + +/** + * PHPExcel + * + * Copyright (C) 2006 - 2012 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## + */ + +/** PHPExcel */ +require_once '../Classes/PHPExcel.php'; + + +$objPHPExcel = new PHPExcel(); +$objWorksheet = $objPHPExcel->getActiveSheet(); +$objWorksheet->fromArray( + array( + array('', 2010, 2011, 2012), + array('Q1', 12, 15, 21), + array('Q2', 56, 73, 86), + array('Q3', 52, 61, 69), + array('Q4', 30, 32, 0), + ) +); + +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker +$dataseriesLabels = array( + new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010 + new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 + new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012 +); +// Set the X-Axis Labels +$xAxisTickValues = array( + new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4 +); +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker +$dataSeriesValues = array( + new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4), + new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4), + new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4), +); + +// Build the dataseries +$series = new PHPExcel_Chart_DataSeries( + PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART, // plotType + NULL, // plotGrouping (Scatter charts don't have any grouping) + range(0, count($dataSeriesValues)-1), // plotOrder + $dataseriesLabels, // plotLabel + $xAxisTickValues, // plotCategory + $dataSeriesValues, // plotValues + NULL, // smooth line + PHPExcel_Chart_DataSeries::STYLE_LINEMARKER // plotStyle +); + +// Set the series in the plot area +$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series)); +// Set the chart legend +$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false); + +$title = new PHPExcel_Chart_Title('Test Scatter Chart'); +$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)'); + + +// Create the chart +$chart = new PHPExcel_Chart( + 'chart1', // name + $title, // title + $legend, // legend + $plotarea, // plotArea + true, // plotVisibleOnly + 0, // displayBlanksAs + NULL, // xAxisLabel + $yAxisLabel // yAxisLabel +); + +// Set the position where the chart should appear in the worksheet +$chart->setTopLeftPosition('A7'); +$chart->setBottomRightPosition('H20'); + +// Add the chart to the worksheet +$objWorksheet->addChart($chart); + + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->setIncludeCharts(TRUE); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Examples/34chartupdate.php b/Examples/34chartupdate.php index c60217235..569e3169e 100644 --- a/Examples/34chartupdate.php +++ b/Examples/34chartupdate.php @@ -36,11 +36,8 @@ * @version ##VERSION##, ##DATE## */ -/** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); - /** PHPExcel */ -include 'PHPExcel.php'; +include '../Classes/PHPExcel.php'; if (!file_exists("33chartcreate-bar.xlsx")) { exit("Please run 33chartcreate-bar.php first." . EOL); From b1c61d1be0266c8572de39f1e6d0bf10b2cf2cc7 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 7 May 2013 12:50:42 +0100 Subject: [PATCH 062/467] Fix file rewind in SYLK reader --- Classes/PHPExcel/Reader/SYLK.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index a6e22e6dd..cacfc87b5 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -140,6 +140,7 @@ public function listWorksheetInfo($pFilename) throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } $fileHandle = $this->_fileHandle; + rewind($fileHandle); $worksheetInfo = array(); $worksheetInfo[0]['worksheetName'] = 'Worksheet'; @@ -227,7 +228,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } $fileHandle = $this->_fileHandle; rewind($fileHandle); - + // Create new PHPExcel while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { $objPHPExcel->createSheet(); From 69dc096fe747a87b37093d2a2829ed5e79e9de28 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 9 May 2013 22:28:23 +0100 Subject: [PATCH 063/467] Added getStyle() method to Cell object --- Classes/PHPExcel/Cell.php | 10 ++++++++++ changelog.txt | 1 + 2 files changed, 11 insertions(+) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 310680c1b..9b20b91cc 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -486,6 +486,16 @@ public function getWorksheet() { return $this->_parent->getParent(); } + /** + * Get cell style + * + * @return PHPExcel_Style + */ + public function getStyle() + { + return $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex()); + } + /** * Re-bind parent * diff --git a/changelog.txt b/changelog.txt index cfe17493a..ead60ad61 100644 --- a/changelog.txt +++ b/changelog.txt @@ -26,6 +26,7 @@ Fixed in develop branch for release v1.7.9: - Feature: (MBaker) Include charts option for HTML Writer - Feature: (MBaker) Added composer file +- Feature: (MBaker) Added getStyle() method to Cell object - Bugfix: (Asker) Work item 18777 - Error in PHPEXCEL/Calculation.php script on line 2976 (stack pop check) - Bugfix: (MBaker) Work item 18794 - CSV files without a file extension being identified as HTML - Bugfix: (AndreKR) Work item GH-66 - Wrong check for maximum number of rows in Excel5 Writer From 04c1608f3fc81cba01a02f4a6dd16462daaebb9f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 10 May 2013 14:21:23 +0100 Subject: [PATCH 064/467] Feature: Added getStyle() method to Cell object --- Classes/PHPExcel/Cell.php | 11 +++++++++++ Classes/PHPExcel/Worksheet.php | 8 ++++---- changelog.txt | 11 ++++++----- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 310680c1b..9a52fc019 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -902,6 +902,17 @@ public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) self::$_valueBinder = $binder; } + /** + * Get style for cell + * + * @return PHPExcel_Style + * @throws PHPExcel_Exception + */ + public function getStyle() + { + return $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex()); + } + /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 37df75025..81717b6df 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -36,13 +36,13 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable { /* Break types */ - const BREAK_NONE = 0; - const BREAK_ROW = 1; - const BREAK_COLUMN = 2; + const BREAK_NONE = 0; + const BREAK_ROW = 1; + const BREAK_COLUMN = 2; /* Sheet state */ const SHEETSTATE_VISIBLE = 'visible'; - const SHEETSTATE_HIDDEN = 'hidden'; + const SHEETSTATE_HIDDEN = 'hidden'; const SHEETSTATE_VERYHIDDEN = 'veryHidden'; /** diff --git a/changelog.txt b/changelog.txt index cfe17493a..0e0c5502a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -26,6 +26,7 @@ Fixed in develop branch for release v1.7.9: - Feature: (MBaker) Include charts option for HTML Writer - Feature: (MBaker) Added composer file +- Feature: (MBaker) Added getStyle() method to Cell object - Bugfix: (Asker) Work item 18777 - Error in PHPEXCEL/Calculation.php script on line 2976 (stack pop check) - Bugfix: (MBaker) Work item 18794 - CSV files without a file extension being identified as HTML - Bugfix: (AndreKR) Work item GH-66 - Wrong check for maximum number of rows in Excel5 Writer @@ -63,7 +64,7 @@ Fixed in develop branch for release v1.7.9: -------------------------------------------------------------------------------- BREAKING CHANGE! As part of the planned changes for handling array formulae in -workbooks, there are some changes that will affect the PHPExcel_Cell object +workbooks, there are some changes that will affect the PHPExcel_Cell object methods. The following methods are now deprecated, and will be removed in or after version 1.8.0: @@ -81,13 +82,13 @@ The following methods will be added in version 1.8.0 value if the cell doesn't contain a formula, or is not part of an array formula range. setFormula() Use to set a cell formula. It will still be possible - to set formulae using the setValue() and + to set formulae using the setValue() and setValueExplicit() methods. calculate() Use to execute a formula calculation to update the cell value. isFormula() Use to determine if a cell contains a formula, or is part of an array formula range or not. - isArrayFormula() Use to determine if a cell contains an array formula, + isArrayFormula() Use to determine if a cell contains an array formula, or is part of an array formula range or not. getArrayFormulaRange() Use to retrieve an array formula range. @@ -98,7 +99,7 @@ The following methods will be changed in version 1.8.0 setValueExplicit() The logic behind this will be modified to store formula values in the new cell property structure, but it will still perform the same function. - getValue() Will no longer return a formula if the cell contains + getValue() Will no longer return a formula if the cell contains a formula, but will return the calculated value instead. For cells that don't contain a formula, it will still return the stored value. @@ -178,7 +179,7 @@ The following methods will be changed in version 1.8.0 - General: (MBaker) Reduce cell caching overhead using dirty flag to ensure that cells are only rewritten to the cache if they have actually been changed - General: (MBaker) Improved memory usage in CSV Writer - General: (MBaker) Improved speed and memory usage in Excel5 Writer -- General: (MBaker) Experimental - +- General: (MBaker) Experimental - Added getHighestDataColumn(), getHighestDataRow(), getHighestRowAndColumn() and calculateWorksheetDataDimension() methods for the worksheet that return the highest row and column that have cell records - General: (MBaker) Change iterators to implement Iterator rather than extend CachingIterator, as a fix for PHP 5.4. changes in SPL - Bugfix: (MBaker) Work item 15459 - Invalid cell coordinate in Autofilter for Excel2007 Writer From 9a06b8a6fcd6ec766f4a9257952f634f63bd8b7c Mon Sep 17 00:00:00 2001 From: Andreas Heiberg Date: Sat, 11 May 2013 00:14:19 +0200 Subject: [PATCH 065/467] Removed duplicate declaration of getStyle() --- Classes/PHPExcel/Cell.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index e6e180ebd..9b20b91cc 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -912,17 +912,6 @@ public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) self::$_valueBinder = $binder; } - /** - * Get style for cell - * - * @return PHPExcel_Style - * @throws PHPExcel_Exception - */ - public function getStyle() - { - return $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex()); - } - /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ From 80c78e1ab9cca26b92aacf455b9de8e54551cef4 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 13 May 2013 13:59:53 +0100 Subject: [PATCH 066/467] Initial work on converting documentation to markdown --- .../Features/Autofilters/01-Autofilters.md | 19 + .../Autofilters/02-Setting-an-Autofilter.md | 24 + .../Autofilters/03-Autofilter-Expressions.md | 26 + .../04-01-Autofilter-Expressions-Simple.md | 52 + .../04-02-Autofilter-Expressions-Dategroup.md | 48 + .../04-03-Autofilter-Expressions-Custom.md | 84 + .../04-04-Autofilter-Expressions-Dynamic.md | 88 + .../04-05-Autofilter-Expressions-Topten.md | 69 + .../Autofilters/05-Executing-Autofilters.md | 42 + .../Autofilters/06-Autofilter-Sorting.md | 7 + .../Autofilters/images/01-01-autofilter.png | Bin 0 -> 45173 bytes .../Autofilters/images/01-02-autofilter.png | Bin 0 -> 14496 bytes .../images/01-03-filter-icon-1.png | Bin 0 -> 453 bytes .../images/01-03-filter-icon-2.png | Bin 0 -> 640 bytes .../Autofilters/images/01-04-autofilter.png | Bin 0 -> 17489 bytes .../images/04-01-simple-autofilter.png | Bin 0 -> 67694 bytes .../images/04-02-dategroup-autofilter.png | Bin 0 -> 49268 bytes .../images/04-03-custom-autofilter-1.png | Bin 0 -> 51786 bytes .../images/04-03-custom-autofilter-2.png | Bin 0 -> 53489 bytes .../images/04-04-dynamic-autofilter.png | Bin 0 -> 111531 bytes .../images/04-05-topten-autofilter-1.png | Bin 0 -> 53737 bytes .../images/04-05-topten-autofilter-2.png | Bin 0 -> 22842 bytes .../Functions/FunctionListByCategory.md | 410 +++ .../markdown/Functions/FunctionListByName.md | 381 ++ .../markdown/Overview/01-getting-started.md | 174 + .../markdown/Overview/02-architecture.md | 67 + Documentation/markdown/Overview/developer.md | 3050 +++++++++++++++++ .../markdown/Overview/images/01-schematic.png | Bin 0 -> 14519 bytes .../Overview/images/02-readers-writers.png | Bin 0 -> 55819 bytes 29 files changed, 4541 insertions(+) create mode 100644 Documentation/markdown/Features/Autofilters/01-Autofilters.md create mode 100644 Documentation/markdown/Features/Autofilters/02-Setting-an-Autofilter.md create mode 100644 Documentation/markdown/Features/Autofilters/03-Autofilter-Expressions.md create mode 100644 Documentation/markdown/Features/Autofilters/04-01-Autofilter-Expressions-Simple.md create mode 100644 Documentation/markdown/Features/Autofilters/04-02-Autofilter-Expressions-Dategroup.md create mode 100644 Documentation/markdown/Features/Autofilters/04-03-Autofilter-Expressions-Custom.md create mode 100644 Documentation/markdown/Features/Autofilters/04-04-Autofilter-Expressions-Dynamic.md create mode 100644 Documentation/markdown/Features/Autofilters/04-05-Autofilter-Expressions-Topten.md create mode 100644 Documentation/markdown/Features/Autofilters/05-Executing-Autofilters.md create mode 100644 Documentation/markdown/Features/Autofilters/06-Autofilter-Sorting.md create mode 100644 Documentation/markdown/Features/Autofilters/images/01-01-autofilter.png create mode 100644 Documentation/markdown/Features/Autofilters/images/01-02-autofilter.png create mode 100644 Documentation/markdown/Features/Autofilters/images/01-03-filter-icon-1.png create mode 100644 Documentation/markdown/Features/Autofilters/images/01-03-filter-icon-2.png create mode 100644 Documentation/markdown/Features/Autofilters/images/01-04-autofilter.png create mode 100644 Documentation/markdown/Features/Autofilters/images/04-01-simple-autofilter.png create mode 100644 Documentation/markdown/Features/Autofilters/images/04-02-dategroup-autofilter.png create mode 100644 Documentation/markdown/Features/Autofilters/images/04-03-custom-autofilter-1.png create mode 100644 Documentation/markdown/Features/Autofilters/images/04-03-custom-autofilter-2.png create mode 100644 Documentation/markdown/Features/Autofilters/images/04-04-dynamic-autofilter.png create mode 100644 Documentation/markdown/Features/Autofilters/images/04-05-topten-autofilter-1.png create mode 100644 Documentation/markdown/Features/Autofilters/images/04-05-topten-autofilter-2.png create mode 100644 Documentation/markdown/Functions/FunctionListByCategory.md create mode 100644 Documentation/markdown/Functions/FunctionListByName.md create mode 100644 Documentation/markdown/Overview/01-getting-started.md create mode 100644 Documentation/markdown/Overview/02-architecture.md create mode 100644 Documentation/markdown/Overview/developer.md create mode 100644 Documentation/markdown/Overview/images/01-schematic.png create mode 100644 Documentation/markdown/Overview/images/02-readers-writers.png diff --git a/Documentation/markdown/Features/Autofilters/01-Autofilters.md b/Documentation/markdown/Features/Autofilters/01-Autofilters.md new file mode 100644 index 000000000..0f11d53cc --- /dev/null +++ b/Documentation/markdown/Features/Autofilters/01-Autofilters.md @@ -0,0 +1,19 @@ +# PHPExcel AutoFilter Reference + + +## AutoFilters + +Each worksheet in an Excel Workbook can contain a single autoFilter range. Filtered data displays only the rows that meet criteria that you specify and hides rows that you do not want displayed. You can filter by more than one column: filters are additive, which means that each additional filter is based on the current filter and further reduces the subset of data. + +![01-01-autofilter.png](./images/01-01-autofilter.png "") + +When an AutoFilter is applied to a range of cells, the first row in an autofilter range will be the heading row, which displays the autoFilter dropdown icons. It is not part of the actual autoFiltered data. All subsequent rows are the autoFiltered data. So an AutoFilter range should always contain the heading row and one or more data rows (one data row is pretty meaningless), but PHPExcel won't actually stop you specifying a meaningless range: it's up to you as the developer to avoid such errors. + +To determine if a filter is applied, note the icon in the column heading. A drop-down arrow (![01-03-filter-icon-1.png](./images/01-03-filter-icon-1.png "")) means that filtering is enabled but not applied. In MS Excel, when you hover over the heading of a column with filtering enabled but not applied, a screen tip displays the cell text for the first row in that column, and the message "(Showing All)". + +![01-02-autofilter.png](./images/01-02-autofilter.png "") + + +A Filter button (![01-03-filter-icon-2.png](./images/01-03-filter-icon-2.png "")) means that a filter is applied. When you hover over the heading of a filtered column, a screen tip displays the filter applied to that column, such as "Equals a red cell color" or "Larger than 150". + +![01-04-autofilter.png](./images/01-04-autofilter.png "") diff --git a/Documentation/markdown/Features/Autofilters/02-Setting-an-Autofilter.md b/Documentation/markdown/Features/Autofilters/02-Setting-an-Autofilter.md new file mode 100644 index 000000000..49c8fa4c1 --- /dev/null +++ b/Documentation/markdown/Features/Autofilters/02-Setting-an-Autofilter.md @@ -0,0 +1,24 @@ +# PHPExcel AutoFilter Reference + + +## Setting an AutoFilter area on a worksheet + +To set an autoFilter on a range of cells. + +```php +$objPHPExcel->getActiveSheet()->setAutoFilter('A1:E20'); +``` + +The first row in an autofilter range will be the heading row, which displays the autoFilter dropdown icons. It is not part of the actual autoFiltered data. All subsequent rows are the autoFiltered data. So an AutoFilter range should always contain the heading row and one or more data rows (one data row is pretty meaningless, but PHPExcel won't actually stop you specifying a meaningless range: it's up to you as the developer to avoid such errors. + +If you want to set the whole worksheet as an autofilter region + +```php +$objPHPExcel->getActiveSheet()->setAutoFilter( + $objPHPExcel->getActiveSheet() + ->calculateWorksheetDimension() +); +``` + +This enables filtering, but does not actually apply any filters. + diff --git a/Documentation/markdown/Features/Autofilters/03-Autofilter-Expressions.md b/Documentation/markdown/Features/Autofilters/03-Autofilter-Expressions.md new file mode 100644 index 000000000..dae24b4f6 --- /dev/null +++ b/Documentation/markdown/Features/Autofilters/03-Autofilter-Expressions.md @@ -0,0 +1,26 @@ +# PHPExcel AutoFilter Reference + + +## Autofilter Expressions + +PHPEXcel 1.7.8 introduced the ability to actually create, read and write filter expressions; initially only for Excel2007 files, but later releases will extend this to other formats. + +To apply a filter expression to an autoFilter range, you first need to identify which column you're going to be applying this filter to. + +```php +$autoFilter = $objPHPExcel->getActiveSheet()->getAutoFilter(); +$columnFilter = $autoFilter->getColumn('C'); +``` + +This returns an autoFilter column object, and you can then apply filters to that column. + +There are a number of different types of autofilter expressions. The most commonly used are: + + - Simple Filters + - DateGroup Filters + - Custom filters + - Dynamic Filters + - Top Ten Filters + +These different types are mutually exclusive within any single column. You should not mix the different types of filter in the same column. PHPExcel will not actively prevent you from doing this, but the results are unpredictable. + diff --git a/Documentation/markdown/Features/Autofilters/04-01-Autofilter-Expressions-Simple.md b/Documentation/markdown/Features/Autofilters/04-01-Autofilter-Expressions-Simple.md new file mode 100644 index 000000000..ca229b892 --- /dev/null +++ b/Documentation/markdown/Features/Autofilters/04-01-Autofilter-Expressions-Simple.md @@ -0,0 +1,52 @@ +# PHPExcel AutoFilter Reference + + +## Autofilter Expressions + +### Simple filters + +In MS Excel, Simple Filters are a dropdown list of all values used in that column, and the user can select which ones they want to display and which ones they want to hide by ticking and unticking the checkboxes alongside each option. When the filter is applied, rows containing the checked entries will be displayed, rows that don't contain those values will be hidden. + +![04-01-simple-autofilter.png](./images/04-01-simple-autofilter.png "") + +To create a filter expression, we need to start by identifying the filter type. In this case, we're just going to specify that this filter is a standard filter. + +```php +$columnFilter->setFilterType( + PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER +); +``` + +Now we've identified the filter type, we can create a filter rule and set the filter values: + +When creating a simple filter in PHPExcel, you only need to specify the values for "checked" columns: you do this by creating a filter rule for each value. + +```php +$columnFilter->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + 'France' + ); + +$columnFilter->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + 'Germany' + ); +``` + +This creates two filter rules: the column will be filtered by values that match “France” OR “Germany”. For Simple Filters, you can create as many rules as you want + +Simple filters are always a comparison match of EQUALS, and multiple standard filters are always treated as being joined by an OR condition. + +#### Matching Blanks + +If you want to create a filter to select blank cells, you would use: + +```php +$columnFilter->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + '' + ); +``` diff --git a/Documentation/markdown/Features/Autofilters/04-02-Autofilter-Expressions-Dategroup.md b/Documentation/markdown/Features/Autofilters/04-02-Autofilter-Expressions-Dategroup.md new file mode 100644 index 000000000..2b9015ff4 --- /dev/null +++ b/Documentation/markdown/Features/Autofilters/04-02-Autofilter-Expressions-Dategroup.md @@ -0,0 +1,48 @@ +# PHPExcel AutoFilter Reference + + +## Autofilter Expressions + +### DateGroup Filters + +In MS Excel, DateGroup filters provide a series of dropdown filter selectors for date values, so you can specify entire years, or months within a year, or individual days within each month. + +![04-02-dategroup-autofilter.png](./images/04-02-dategroup-autofilter.png "") + +DateGroup filters are still applied as a Standard Filter type. + +```php +$columnFilter->setFilterType( + PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER +); +``` + +Creating a dateGroup filter in PHPExcel, you specify the values for "checked" columns as an associative array of year. month, day, hour minute and second. To select a year and month, you need to create a DateGroup rule identifying the selected year and month: + +```php +$columnFilter->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + array( + 'year' => 2012, + 'month' => 1 + ) + ) + ->setRuleType( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP + ); +``` + +The key values for the associative array are: + + - year + - month + - day + - hour + - minute + - second + +Like Standard filters, DateGroup filters are always a match of EQUALS, and multiple standard filters are always treated as being joined by an OR condition. + +Note that we alse specify a ruleType: to differentiate this from a standard filter, we explicitly set the Rule's Type to AUTOFILTER_RULETYPE_DATEGROUP. As with standard filters, we can create any number of DateGroup Filters. + diff --git a/Documentation/markdown/Features/Autofilters/04-03-Autofilter-Expressions-Custom.md b/Documentation/markdown/Features/Autofilters/04-03-Autofilter-Expressions-Custom.md new file mode 100644 index 000000000..9ca3bd49d --- /dev/null +++ b/Documentation/markdown/Features/Autofilters/04-03-Autofilter-Expressions-Custom.md @@ -0,0 +1,84 @@ +# PHPExcel AutoFilter Reference + + +## Autofilter Expressions + +### Custom filters + +In MS Excel, Custom filters allow us to select more complex conditions using an operator as well as a value. Typical examples might be values that fall within a range (e.g. between -20 and +20), or text values with wildcards (e.g. beginning with the letter U). To handle this, they + +![04-03-custom-autofilter-1.png](./images/04-03-custom-autofilter-1.png "") + +![04-03-custom-autofilter-2.png](./images/04-03-custom-autofilter-2.png "") + +Custom filters are limited to 2 rules, and these can be joined using either an AND or an OR. + +We start by specifying a Filter type, this time a CUSTOMFILTER. + +```php +$columnFilter->setFilterType( + PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER +); +``` + +And then define our rules. + +The following shows a simple wildcard filter to show all column entries beginning with the letter 'U'. + +```php +$columnFilter->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + 'U*' + ) + ->setRuleType( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER + ); +``` + +MS Excel uses \* as a wildcard to match any number of characters, and ? as a wildcard to match a single character. 'U\*' equates to "begins with a 'U'"; '\*U' equates to "ends with a 'U'"; and '\*U\*' equates to "contains a 'U'" + +If you want to match explicitly against a \* or a ? character, you can escape it with a tilde (~), so ?~\*\* would explicitly match for a \* character as the second character in the cell value, followed by any number of other characters. The only other character that needs escaping is the ~ itself. + +To create a "between" condition, we need to define two rules: + +```php +$columnFilter->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, + -20 + ) + ->setRuleType( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER + ); +$columnFilter->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL, + 20 + ) + ->setRuleType( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER + ); +``` + +We also set the rule type to CUSTOMFILTER. + +This defined two rules, filtering numbers that are >= -20 OR <= 20, so we also need to modify the join condition to reflect AND rather than OR. + +```php +$columnFilter->setAndOr( + PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_ANDOR_AND +); +``` + +The valid set of operators for Custom Filters are defined in the PHPExcel_Worksheet_AutoFilter_Column_Rule class, and comprise: + + Operator Constant | Value | + ------------------------------------------|----------------------| + AUTOFILTER_COLUMN_RULE_EQUAL | 'equal' | + AUTOFILTER_COLUMN_RULE_NOTEQUAL | 'notEqual' | + AUTOFILTER_COLUMN_RULE_GREATERTHAN | 'greaterThan' | + AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL | 'greaterThanOrEqual' | + AUTOFILTER_COLUMN_RULE_LESSTHAN | 'lessThan' | + AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL | 'lessThanOrEqual' | + diff --git a/Documentation/markdown/Features/Autofilters/04-04-Autofilter-Expressions-Dynamic.md b/Documentation/markdown/Features/Autofilters/04-04-Autofilter-Expressions-Dynamic.md new file mode 100644 index 000000000..f285e573e --- /dev/null +++ b/Documentation/markdown/Features/Autofilters/04-04-Autofilter-Expressions-Dynamic.md @@ -0,0 +1,88 @@ +# PHPExcel AutoFilter Reference + + +## Autofilter Expressions + +### Dynamic Filters + +Dynamic Filters are based on a dynamic comparison condition, where the value we're comparing against the cell values is variable, such as 'today'; or when we're testing against an aggregate of the cell data (e.g. 'aboveAverage'). Only a single dynamic filter can be applied to a column at a time. + +![04-04-dynamic-autofilter.png](./images/04-04-dynamic-autofilter.png "") + +Again, we start by specifying a Filter type, this time a DYNAMICFILTER. + +```php +$columnFilter->setFilterType( + PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER +); +``` + +When defining the rule for a dynamic filter, we don't define a value (we can simply set that to NULL) but we do specify the dynamic filter category. + +```php +$columnFilter->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, + NULL, + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE + ) + ->setRuleType( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER + ); +``` + +We also set the rule type to DYNAMICFILTER. + +The valid set of dynamic filter categories is defined in the PHPExcel_Worksheet_AutoFilter_Column_Rule class, and comprises: + + Operator Constant | Value | + -----------------------------------------|----------------| + AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY | 'yesterday' | + AUTOFILTER_RULETYPE_DYNAMIC_TODAY | 'today' | + AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW | 'tomorrow' | + AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE | 'yearToDate' | + AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR | 'thisYear' | + AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER | 'thisQuarter' | + AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH | 'thisMonth' | + AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK | 'thisWeek' | + AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR | 'lastYear' | + AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER | 'lastQuarter' | + AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH | 'lastMonth' | + AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK | 'lastWeek' | + AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR | 'nextYear' | + AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER | 'nextQuarter' | + AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH | 'nextMonth' | + AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK | 'nextWeek' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1 | 'M1' | + AUTOFILTER_RULETYPE_DYNAMIC_JANUARY | 'M1' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2 | 'M2' | + AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY | 'M2' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3 | 'M3' | + AUTOFILTER_RULETYPE_DYNAMIC_MARCH | 'M3' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4 | 'M4' | + AUTOFILTER_RULETYPE_DYNAMIC_APRIL | 'M4' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5 | 'M5' | + AUTOFILTER_RULETYPE_DYNAMIC_MAY | 'M5' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6 | 'M6' | + AUTOFILTER_RULETYPE_DYNAMIC_JUNE | 'M6' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7 | 'M7' | + AUTOFILTER_RULETYPE_DYNAMIC_JULY | 'M7' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8 | 'M8' | + AUTOFILTER_RULETYPE_DYNAMIC_AUGUST | 'M8' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9 | 'M9' | + AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER | 'M9' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10 | 'M10' | + AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER | 'M10' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11 | 'M11' | + AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER | 'M11' | + AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12 | 'M12' | + AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER | 'M12' | + AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1 | 'Q1' | + AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2 | 'Q2' | + AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3 | 'Q3' | + AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4 | 'Q4' | + AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE | 'aboveAverage' | + AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE | 'belowAverage' | + +We can only apply a single Dynamic Filter rule to a column at a time. + diff --git a/Documentation/markdown/Features/Autofilters/04-05-Autofilter-Expressions-Topten.md b/Documentation/markdown/Features/Autofilters/04-05-Autofilter-Expressions-Topten.md new file mode 100644 index 000000000..ff36b0a8a --- /dev/null +++ b/Documentation/markdown/Features/Autofilters/04-05-Autofilter-Expressions-Topten.md @@ -0,0 +1,69 @@ +# PHPExcel AutoFilter Reference + + +## Autofilter Expressions + +### Top Ten Filters + +Top Ten Filters are similar to Dynamic Filters in that they are based on a summarisation of the actual data values in the cells. However, unlike Dynamic Filters where you can only select a single option, Top Ten Filters allow you to select based on a number of criteria: + +![04-05-custom-topten-1.png](./images/04-05-topten-autofilter-1.png "") + +![04-05-custom-topten-2.png](./images/04-05-topten-autofilter-2.png "") + +You can identify whether you want the top (highest) or bottom (lowest) values.You can identify how many values you wish to select in the filterYou can identify whether this should be a percentage or a number of items. + +Like Dynamic Filters, only a single Top Ten filter can be applied to a column at a time. + +We start by specifying a Filter type, this time a DYNAMICFILTER. + +```php +$columnFilter->setFilterType( + PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER +); +``` + +Then we create the rule: + +```php +$columnFilter->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, + 5, + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP + ) + ->setRuleType( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER + ); +``` + +This will filter the Top 5 percent of values in the column. + +To specify the lowest (bottom 2 values), we would specify a rule of: + +```php +$columnFilter->createRule() + ->setRule( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, + 5, + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM + ) + ->setRuleType( + PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER + ); +``` + +The option values for TopTen Filters top/bottom value/percent are all defined in the PHPExcel_Worksheet_AutoFilter_Column_Rule class, and comprise: + + Operator Constant | Value | + ---------------------------------------|-------------| + AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE | 'byValue' | + AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT | 'byPercent' | + +and + + Operator Constant | Value | + -------------------------------------|----------| + AUTOFILTER_COLUMN_RULE_TOPTEN_TOP | 'top' | + AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM | 'bottom' | + diff --git a/Documentation/markdown/Features/Autofilters/05-Executing-Autofilters.md b/Documentation/markdown/Features/Autofilters/05-Executing-Autofilters.md new file mode 100644 index 000000000..852e1f41f --- /dev/null +++ b/Documentation/markdown/Features/Autofilters/05-Executing-Autofilters.md @@ -0,0 +1,42 @@ +# PHPExcel AutoFilter Reference + + +## Executing an AutoFilter + +When an autofilter is applied in MS Excel, it sets the row hidden/visible flags for each row of the autofilter area based on the selected criteria, so that only those rows that match the filter criteria are displayed. + +PHPExcel will not execute the equivalent function automatically when you set or change a filter expression, but only when the file is saved. + +### Applying the Filter + +If you wish to execute your filter from within a script, you need to do this manually. You can do this using the autofilters showHideRows() method. + +```php +$autoFilter = $objPHPExcel->getActiveSheet()->getAutoFilter(); +$autoFilter->showHideRows(); +``` + +This will set all rows that match the filter criteria to visible, while hiding all other rows within the autofilter area. + +### Displaying Filtered Rows + +Simply looping through the rows in an autofilter area will still access ever row, whether it matches the filter criteria or not. To selectively access only the filtered rows, you need to test each row’s visibility settings. + +```php +foreach ($objPHPExcel->getActiveSheet()->getRowIterator() as $row) { + if ($objPHPExcel->getActiveSheet() + ->getRowDimension($row->getRowIndex())->getVisible()) { + echo ' Row number - ' , $row->getRowIndex() , ' '; + echo $objPHPExcel->getActiveSheet() + ->getCell( + 'C'.$row->getRowIndex() + ) + ->getValue(), ' '; + echo $objPHPExcel->getActiveSheet() + ->getCell( + 'D'.$row->getRowIndex() + )->getFormattedValue(), ' '; + echo EOL; + } +} +``` diff --git a/Documentation/markdown/Features/Autofilters/06-Autofilter-Sorting.md b/Documentation/markdown/Features/Autofilters/06-Autofilter-Sorting.md new file mode 100644 index 000000000..23133b8f4 --- /dev/null +++ b/Documentation/markdown/Features/Autofilters/06-Autofilter-Sorting.md @@ -0,0 +1,7 @@ +# PHPExcel AutoFilter Reference + + +## AutoFilter Sorting + +In MS Excel, Autofiltering also allows the rows to be sorted. This feature is ***not*** supported by PHPExcel. + diff --git a/Documentation/markdown/Features/Autofilters/images/01-01-autofilter.png b/Documentation/markdown/Features/Autofilters/images/01-01-autofilter.png new file mode 100644 index 0000000000000000000000000000000000000000..8b5c4fad634025f4061da572ec954cdf267e8b76 GIT binary patch literal 45173 zcmaHS2{@GB`~J)@_MJlZvQ)yL>>(=q5|y$J60(ye%#2;KM)p00B1`sd#;&rKEE&uo zyRn2Z%-}!ze80cn_xIoCy0~UJ?|aU9p8L6<`#I;lF~){kjC2?10001^j`nR6004vl z0D$E*ROJ6?`W-Lw4?rIiEe$}$5brAa1Eu3FgIfSVbs{~<7EJz3>#6SpmmCUDS9x{Ic8A<_Kt~ZQ(491~^Iv@!NfyTYc zLbrt*eCP?nUq}J-=4vT95$f76qx$dNyDqHZ%~B+sg#H>CB1jWj>J`SeVuSlQW!3W0 z&(~~!ada$yR%%iaV}$rvR)(M5-&|WSIXrc5syjZm*y7-E9{jXC+%SyT=h3pqEqDyc zxgVRjY&I?oIn9;u2V6F%@|*9zvGHeQ^JyC2w<%7z^k+`^me}Ot^wInA>HWEuHZZpJ z4MhVK*8rD5H}30wYC2#(eR&Mh=PEwzj#PV^OYQe-Fx`CrwB9+ZU2^pFV$&j1&sX|l ziDrZJndy&-vENCDB`0CN{237a-S%)qj}mivqQJ>^^wehSvb`Uzk$Y3pkNv7(CJ_fs zPb*7Q6QK!3zG;-^&O8376ZL?_AdH6*a`97hc>D!fPQxr21y`??AKs8!$(i6x>ja0m z+>LLSs%D2zrlnT))h`a*2r9)E+G9RRxo*x$2{j zD_`hz9Qvl>NjLM0Ybe4ti^nMU`%st=Ni;QAkC%RdCCi1zAN^3%*@@gQZ)c-?V$?RH zeBP#vc5VuXyB&lI$uGbjao+2o07Yjv3_)X)Az?fs3unfH>2%yLB~$W ze0xlQ=49?r*4Cqp&)qEiqX}$O2c5~Gqe;#Kx2IVi20_0VR;f}aaCgpm=8|o5b1ON> z_IA|vz;*c?HfqB{ALwZ74^@P9rl0kU z`|C@uW1f?pTE*Sl2^sv<`v*rK`t6Y{`)sTm6W(BMaN zta3b1bA(x1$j4%)LffT_6`Ah$Rf^4AIu5XW^*hbtf=`ZXLXj;IsyCtt*&k;r%>R4c z9&k(g%ZuGR|AdCC;bHP;-bVN3_E=7}3B^JEcexaEypl{5N*o2@6Egw5LA!SzG4Y?! z_XD?Y=G>Ok#3l3N=VHVkB_g>gqMkfb1AlA7t-0vGP}qNWHNv}!afW*AJmojiTIFf+ ziCKfl<>h*c64V>s4-O-$D*24-p}tJ|ZFNP=E6|~ADewMBrOX!oFbAJ+J`M(u-F9DP z>f+fcp}kSXBxK#CzEJz&jf;WIZqaYlT=m=J*Q-IN9k;sdzr7Dt+S!m!8$(xV2Gd-l z(9B6-DKGPZuDxeRi*@PUWB`}?U}c9@gWfS&rVWM8SSat^m^)Ff36a*!V9L~Focr)x z^U<*$X5t*<+)o!Hydj>&u&qvWrB880RV>U%EVOMkc$TGDQ#M_5GqTHUF@B1k+M!4& zC(y*1823_AD2S%yY>@1VBP#EooLv|8YeJ8ewtq0ESooT zeOsfwxvkg8BNW*B8sV_Y8?d(bICTmVJR^?vNsR2L%C!A3`gpE-`~C_`@h@J+IUe={ z?XBDmp`2zdbMpMRqfBuw6}8OVd5Aj#)CY>517zF-u1QA>Vn+Qg2%WI_-PU|0lcW{3 z-5J2N5#)30{KcWV}6hXXbC_x$c&l2>4ru)p|rR z=fOP>C&yq!{cP`aNlk)3jbp%vXp+#i3kt7>Lbn@T{I9Ner0;(y{~Nk*-Wxi8_XEzb zxG5nQg}4&2M3`Km8X1`hhk#* zrnAuQsG^$)t=Vj&Z?kvitUGQ*=Nez#osA{=*G%>tth-fV2A?cBTyj7=V$RbAD71_1>PTq#fBgEvXnh&k4Kddj}#KAg1*qGQE zKtXz9RebBz4JZXX{c~c}0JVJkUZ15HD}r?t2y8swaAdFisL#9l{MG$Zm2JtAEz}Xk zFqFICTw>FJrhgsHWq}bhfmSVKEld-OH_UDNaE$Y}T6U8fJ7IHD8v$%kb4RMOF80j0Q+`=VqF|IMc$d$$%!4`S;{@Rg;$R#)X}i$}-_trT?QY@nXt$f)s2*DQEmF-$SAx^{{IvL- zQy1dim8X|Vhuz01Qe`RA!$JC){aP^Lk(ru@yu?gNE%lj3C6=N`Plh#57>`FLimM}h zJ7-y7+701|(GyTofVR(SrsI@edR|PjzF5JrvsCarl?3Os!Ga`{=hkEni}QID5>gQ; zAKLOt@TRj}7M9q;uB|&o?QTXf;_}H6U@qN4lYGI z&;@+4f~3MjcyRYuFE^65TcAG15ekUIewRxdVjHXKi+dFrwLGVrGvF>gHB+gRpQx%2 zr*a-9clsBTTCfo4J5-jre+S3j#QFA6IvCKzi*K6T(o_i8Waaj+ZgWEjOV$CcKxPGK zyU%IZ;*SP;rgJVb4+Ox(mix_mZ@;Y^#$IFozAm0x+|pWcl9~{9Yq7J)pVZ>d$*}dS zLtcP5Jl;4Xse+^Pom;j%^6T(X>c%=6a-r(T9XIRIv47e%G6I3z(~B=SrVN$Oldw~+ zYipI&47{atk_ywkSV^wgH{f2}Gt;{w_w`+0`O?ySJC6(d`Wix_*M0Ohgn9-nK0Udt z6_nZn{hYJQ8EvgrP0uu;Cy}r5NNh8#3qFsjMFE8Q=S2i3>nh#q<{bTnH{dyf>0O&) z$CSdyV?Ueei(5qZ(hCv7jr;nF?r4{dur5ExjWEn7w(Xf&Nxv`uvOm&Vg_V(lDo&Z( zEp4KKesk^D$UTUNZP!!L7Gu9-L&@lAaP&SHRH}1DQc{g1+2}aIJ9dxRR&7Rda*O%Qj(5R7b?{T^Eh)pI zKm)c;W@kT48Nx^Lx1<6C*J|b6EqKROG}zSh#bo-0j!<3y4yp+wb-xa~2iYYd=8N|) zdaRm5*v2_&3Pj&GHU{IYAR=|GRGn}`CAwl-ZU2rrO&uQ_dMXoI>GS3oKfeyI-XQcx z4&Kt|oCAy(et}~jxFJCwDXB&$U}LDpxD$)FA$ zm)wVrK&&>;9r&<}E21SQby2L^lG_oD&@`tV``Mk zmZC`42T@<00sELz|LyE(0&fi5uP`ginP$Bi^&AtJ;HUYae($ivgOm42=m<{LsU(IA z69Vpt3GAmPP!GDx)hi{2S;62-5nf|0HdS~w@VQBt8ikq39Br)M!5119z>BE0r+ zVRJT9k=sN?n)Mv={b*OV!e%7pNjd#O{vCzkT{pA;L0GZpiLPz(NNN$hrv_NTKU&o; zlG1+W3R{Md0jupyCwa8vKSAWr;(ahCwrAwknTTJv(fN!jq*rs$McmL~DF(zu2hf%x zWX(i!4ew^ViWxRyNIfX9Egc**Tgql^csusfliBx;NGr(kzR#@;kTCy`Y43G6+&X4E z1-FF>T#mwp56DzYJn~sT+*JY&=PHYd`gyvzDe8 zv|3VXNTMq1X@PD2_fa`hoa|PM-T0A$MKc^S*~^3JJC*bKHsuJH>o3@3KgFHeq3GS7 zfreJgmJ*nQJt07$L)Cr2Y1vvdL|fhc(9&-Vn9R&zYs-dty0!5Klb_bSIGRmBsIi;#@Am4==|r? zhmfFpyah_G=1MNb6UDS<(lQ{tgzK8-^baWn#b@mc65niqU z+!^ONVlkHL!082uGs}>*2^Aq~RyP$_Lis=h+b2cZDW#-rXWdhU5IEgcex4>fh}upM zrdxtQK4bo_BgpX3eC+J4Jup09?*T2LB%f6Cm6k@GDI_ynbxbBefhv{mq>i~?J+qLK zviPTeTnO_BCsqs+|A%7sOV-&H%lSw2nG~CGAKA90woYq>u|uU-fdT>Bl}u?NYNR>l zOWB>%`;67U@n_2%_hzbGuiEB9qxIF@iEox_@?oV4K(8MbO8ZAAWoj=ORz!aaDJ&OF zHVGtsWQMM1)3`5?i`@nfM4yL0x`^7)KJ-b~(f3ZucPB%+2T{IZwjhn{SUc_Ixy*LF zVSd{O*o3cqJ<4}%>`3Ow9l#Pbms_5g zbqC7nrQy>~i)Pf7!R6DX*Y{eWP8@uUN>xf;(+mDWr++F>&vUCM&U-%bPrU1=6JX-c z6wb&nM(rEwGZUEpT-h00#T(42Bt^M~*c~QW*0xCk3r`gSTAQOopA_w%S>n&CFjE3a zT6!gfo_3v*-oIneq1f8BrEK^*fBHH+Im5rd{I_TIa=nrB34ROdS*3{8J0$r3I(BGWrMXak2RRN1Phu6>m^Hpq6-1tUw{e4>|QDgJIMm* zV(}g7NO24^?y9R1qJBRL9;vzle;pouh4$sw+Y2vtMH&p!bH3O8ak-D#vP&vgF%TX`oT0=RY+fml(AKEWs!c<=<{ zvC^J*fplZ@&-!r6SePD>XHspP3f&;r<1!-D#iUb;{qH4;L9ONQug& z$AC6j$QE0%(J!H;X>lht5YZ>zqK{}{TDNwGfHNXj8He;*aZFncjebiYbf@H};5;$azKZ-geCK~i3kBJ8dRcHJKAnq`(+N3N?IP|S87#$0*<94fzmo0!l(>bqB^+`ckZ ztQH*(QafNiUrtX!f7~73x{YNzDj?SVtb=-U=zmou=lGW;Htmp|3fL#aeM``c6ZsDE zc?;sobog`a<*p|@Vp)&bq?kKGx(Y^c9jesv6evx^s(N-ay&)gi)J9otAw;R%A!b|DE%{`>clZ@85N|1;j_vLd2=T*Y>YC;@Ut^$JeY$a?ZWxmyrlb| zz1De;E^`q_>mv8kFHM0l9*l-vSeeQ5Csv@Dl^P~{ZHg6t~NolLagV(9=FxSL*1XR7GZIg^s{~-(Cj_WBxtqAAZJ|v z^?M+u%qm#12=r=d?{^VF|L%V7>(=_NlI-AVAu{fu%o^J^M}F5-xULAnIE1x2vdE*k zDxlGSt8%&?hMLD5eMu!a>Vk&g9Ki`X>JSC4LXW-+DIpw+boGeK-b`{A5v-PP%fhei zmdwhjH_)ozY__3pJ|EX#lNja5Nw^^jT)n$^dGfVxI~(GA2obio9uZi8 zdR|~K0}j&a08Y9uQ;%Nhb-0j8;m)Futk&0SzkfAeGa;gOl`9;KuV zFM>h>wXVbD8YwaNkoM;tE@^dqSX56prgi0PMvnMip;n`-$N9k_L%P2OgbSvb8*e}k zdu1emrXQ{|5uwez;Mh<0_%YtMAweKAzOMp@?@$YES7uUo@^(sy8>r_jMELL}?F9U~ zj(;u@aMhH}bLDbIpkj&I;D=GiOv>Q8wmZjVr{g8|O9)AY8_xWCxQVcqkJWC?$$JF_ z`vZe-D7&A`Cx)%oIiul~DCxoYlA+sL9oteluR0v6BuFik&EE-^6>uc!pTQDbo?3NJ z9d>On)V0>G3vBu`-~&Fey`9qEK$V{kn9^$(Vy_>rrPP1_Lm_M3?LR?$#A8UNTZXd) zHSwBqV<`~NIzX&MJP?Rjap}Uhu>H`wqM5<9ZkKL|*_NmooxKFwAT7=ag){JxS} zjqqoM^4&EuTk>5?qAVv~o;=n|A1(SSl93#ep+9{O5^_ACO6Nzboy=r2>USJ#4t6$4 zQMR^`dkXFb4j*CP8^o~jY@>5+96PcK#miMBC1#i;f1%`REL*Bek3~M{m z293ix^eOK4PXw}reeLE0j}{%oXmv>LY`d>W(`w5%lkP!2c*stKt^O$p{#|*P(M-Ro zOxN4}9KKEDx#-i*_m9I9$mPQ&>!E@jJ3F7uX~vqr!}052MwTz}EtPVfMn;6AXe6ky^|mLG{Q#1MKvQze`Ws4Ka?Jbvz;5)}|l09=BUmkT9DJjk64T05uktYz$p`UmGcuhc(xsdvntxUwO z7OD%H_iGNInh5iHu}uBLhDi#z^T74U!eZz)6;qGKqLfC5iyTw)S1W7DJ zP+Op@I22RJz~^M@-vQI=;Bs81MxlhfIa+W1H@dS!Diag@OsV2I*|YnbDS!V=khLYM zV_gcH=HBS3Pr8jF=I-8a6f>48J2J1DqRP#99nR9X4R_Ja{vYgjRe&umTv2ey<%7UB z@#7hBSQ86$WFQKRMMgc7;Ym}K;1aeG{gJQ!uO1|ZopWzeyX?)Z;bdkTbX4P3vP=#B zSwwuWe$O*KMDF{xilFHH!wPUvLgmqA1u39C;_x}J0fB9{1wBM?=%0i1MeKL{=IQ?j z;^Z+W1Sp30#>NafTm{bkSCCqR=BJrYa1~&qMxh&IUL?~F;`PrzEas9M=d3tSRe#@u zxET>{M(eas9BOqK^Pfa=a=0xfIBh{gg`qQA9UtRkzG)!tS-y>)hzoa_rz_PuSO;iz z)ZWY$fSiwkD}l*Ot277M5fv8vn`8KS6zP~!3o$mT_4L+ny>)$7ilDBEyWy)G3o`Ko zKzSNb%%lI4!%b-~F9Q##D3Rw|DOJ4YZy!kAILfVpeKcr4ux>Rv)x&j<9enuR@|Jkb zHD8H+d)DQ7n3eCA{8US&+_PxE)CX!1TjKq)5JhqjHM1FSzC3U7eSq&fUROKepH!>_ zJWVlB5A4=6kTRvdlpNA`tBy8<48~JBbje3bQn-b?%im?}^+Pmz0yQVLuMxl=mXVP$ zS#9A{b`C{e(bl9FoFTr7iP^Ux_Tdl-xfLjFB{dUc%#;uYpq&95p25x4+-v#YB z>wjmWLVhZxBwJ?DtdTY3*xmlF{SK+;pur;;bLn2DVmWMc*|CmumdK8y82F>;Y5-LE zyWJK2`5j=^Ynj@jih265PzR(P=^+ig9}`FMW;WL}HWEbO{xfsF{BC~24I@D6cQoyC zExybnbIdv*pH2PgA+IQiOUgr)yfJ28D-HTWD{#RK{wi0&*4<1WW{rl9_@)oz9`t|W z#!(y`Ka9iMe|_vm9JD#R{1mY<1)G0$`Ynyy)C0aErEI`J=y|6nsw9BWB+K;v4f?=O`=n*DCjaxUn~t&f44dj@%Fg1 z?md{rnkrK2oznFg^w+@BHkd}+2qCg^`R;f^^;xq%#GjH+^=c<6;WPy=e2a(%TG}*^ z5)>&gnY_|lN@K;CQh%LOH>8qtnpN{-iAx^Cqxpk8>)21v8&!X%i-$BC#^c!6`nqe? zdK(!A7fnvH1xqf1xJHBj46BX3m6o&|2T-)k*fB5z_8`p7(&P6LJR<0D|kJb*x zHWh&JY1KmO0s0yP{ntpY1^>%|gcmxu0rpuaLO;>sx+3+zXR~UgHZtph%b?sI3Q|pT zb7`-;rrsbO|5#4q?}XyRwdH~ z13MUUC~sqQ*?r>$>T8lu*q03a+zZjJ$gj%`&WPoxbqsp;Bmr-RIF@g7s737YUdxfv zTl|uYqw4LZ8rt2VI!0e~uitN66z2sBUQhy6PF~n5m2uHf=2$X{d$#zeiczjiem!3H=cHP$GJ3 z^-dvM6{2Kl`X_R|nFnnXxL#RnM%v3p=N};?jqr(d&}A)fE#t}3RDA#UC8)kDU|Q8p zYtoNHU6TJ1lSF!z)fFB#^){>Ql3G}XS*_dC<4|RRR)@{`{LmIB?cOwgQ+JEWG?opX z-@nka@c0uV%Ic)pUD2Fu>=(a1ENV&I1+a(r9uHYOzC1UZ{VKuwnet{uMFM9#BJeOM z{BDYZD^D0sHq?RA_>|iQ93dPwtgGAHt0@9;rH~KH-osK>}|PU@4iSy-xt~ z_6|FcBVsXRRM_QnF<^Y^VCkz^{WFzB%xH7x<>-DaZT=#V4sgAz_}a5QmZH z4JeIS5;$4gGnT5Q;MK4VY5R+Rn_LO;R6vR909AaKEL}ESQ2~XL@3S&XLz2Qq{TK_1IeX(+wcUk-fc@Pze~LPXBsFcqDhBIO+%txgtjk zq*N2U{A338C|y@Z#fyOo9?K?uyOKRWc+1du;pjG?(6E88hRMA$;%oH-HyJl$TnXsY z(d{nGm_fgV6A#N&+NXcq(k`oUy$TTxm4+95SN$)CNEW_*Wxkk){ z7mv4{sq*>&z^Z)YV1}vI^lC~p^dK%A{!$4wkgu(L_ZCI763oVq9 zfle@kra+Ka>SBoWnau^U5SYO@N4q(3lb*b;0St~;8Yn&uyHN@IMU?-HeYHcjw^yqm z0Q-VM!I35ZvRP7@;SHe9kD%0}FiS8$Cz^0|uAow4GHUvd%1)r?&^M3w;whuOlVS^% z5t4e-@VzSqy9wRb@cofa$7F2g0C$w_$rRE!>4gg?9E#LQPYPxr3MsyQ7w?=qx9}d| zXj?G~)a4ssOt!rDC_3*}8jJciMVQ9;aV+eCPLx$~voj8o{5d z_4eZ(xKxN@{YQgh#*fGM3m)X>1jST3zW`nH+3OZ%FO_;88Jqg+;gH;=d|~2>LIwa& z_;FqO;A+*Ha!R@nzD+S`^Cm8{W{Zh3=~XW4tw!7(M6pMBHD=+Q?dGc;8IZ!Ju8`8N z3?Dm*_SycrVI%&Cv|C4%EXc0UGtE{eA1F=pZMV2ZFSt|ez8Vj|xa?*I>+PnW=ox-- zjordkE%!>}pX$mT zd%J9~3DC=nU-&@7wqb(h!{(qz6yYG6e+!eiGxyObyt7KV0j?THGSdlKALD}7WmVZ3 zmTA4X+l)U82bl0m(E#>>Y5m_?-nsOm0_s-KmUPW^UGmEVtXK77B^&;T94YOH(Cy$= z$WA1Kf@A8GyAA3!q2*E=-9Wd`(AiyG=}+#wF6wVzk?jyn_E7Q=h`%%pmI5o#!!*xg zMPA$c&fEwzIh{_B0PN`ab>^U$h`$aB4>zw|pri)o+ugiyF~qn8o$#2t!L0N5fDmT_(%N7hdP_%&rhThIrq0hN9sjAKP;{2qv zqpKdwiZ`3FDgn@|+SLdW-LmA~mL;7__v$``EMBc*Q+JEuh7xk5Ea%?OpGR?DkWBkh z)85pL6X#UlvWqZC+qBszW25>@IO}>c@z#B`Odz-3!0Z19;k3sxP#`5GP`CcE)T5^w z7i_>$s8y6Dx9~UWWJFSp<;y6raVC2^LDA-D+>xVx`)ZX6z2)6W)ybeH2lxo9In^q= zdaDxE^L0PF5~|uGhM-|%fEN#0lkjsWdbF&`idr{H!iVfLC!-dlgRRWr^yRV?&yn4a z%^N60bQk9xgZonpy?T^b2aMeD%p7#sR#BSHqce^dBnxO|ElS8;GRHGf^4_idngx2~ zg30#LCA4b*d69G*a4PnE_9#RXhT57<I>?E&dD;E&vCEJcHYad}cs;us!6;z<#4P!E1gSsdEe$^@T z5^W|KGTTEVPUi1Pv(zU6^IQz1^CEUHt^0%p_PJ}h*T4UdZ2Pe8Yi$Q(p0$naqR*5u zoh!x1h)}xhD1>wCsvPTOb~@-!{$_R)uLYA8DCi4;jodK^A7n=5&8@oduL02l2U_Sh zDvq+`Q6n<_NXEMrpm3poCsxCaH-OS%NTUX@+YM^{Jy38J>+#?AEs82@f8ll+IN__Y zRBtzA17LaG)-3%!8?qZ(>Eg@+S7idG!ja%Caf*83fUxUG z8OqZ%t1BwkdvGm+W}$t(e$QSg^j$~B?nFui+Nr6W>Y_#=ZgDVgOS4cS>82wl1@tnC z{C1Wm9#Qh`8d!n$AA?J-22t;ZUU_Dt0q9_+VJhCVDc2L>&QqYGKm%K(Hr}n~Z)rotXR_WKHocqyF^@)w*;s3U~WFbE2Tw`r3I}BmG9OgTx z|Gq3S?%}oY*haY@_4EETy)+H1pNAMAC0pe9AHt9YODKkdO1TWd`Dh48*IE5J4KS{r z2$+2b9w9-R&p227j1N|2zNCt4O?c!<^Y2(W?TAxr2U5?Y+M)0BEpgNP@ZiYK^2?kbK|V-lYOtHbOx}N{G>bf zJbC`{ySAMVuxAHtK{Vt3=eXRx=HR>ONLHl>Pp`B;&RBmQVnXc`PMO2OoNRviFLChY z%%D~{|3P}QnnLNmlA$Myf7n!o5hcsobF}n27O$JZYcVD|N;L+*I`YwIsI7aVwl%W; z7VI;I=uqF?L7B880_cxZj;;i0@(Nww_E6w|8?4~KXGP1wE-I03OMAAIRK z4n<#{%l+m9?G*B-;KI>}SjaYC8g3ldZAcq(#1O_xC;0!&gV4iCvS?BIzI=D$?juL4 z6}w1eBFy;@%fOsn$otam$TQ8dM<@CKoK}}T4!GePUFv66{C7DA#=Qxxm&@41uyv@_L3xVF%n~A+Qr>wBdiBvh~rnCKy zuqPgQ?)5VaxQR|hvi_zSt!)3O+xwy6@gXG;m(9;2&d<+hUvsrLsYqSW5B@6_xxgd& zKqarB6O#DRw~EJxl*SS${H+#JN4gHT{hnMFS*sL!tN`9KEm6@bTroTf)P7~40ceY5 zefXsrQ7xIOeMUUZ0)L5zmgz@sckg}-KqJ>(`6=JDHEoK0+0>J%f+-`g`F>17U&UtV zA7iPLmN9xEYIgNCJE0Jk7 zO_Wx4{sK9~b)W;_%+CEnBfy;UHS{NR%nZB|#C)i9%?RBSS7}f+#4yrB2m6InSAPGh z66CY<&WjEeyRc|_?H~52A%i`HjPVU#)^@J5+(+v|C&>GwLZ=!KwY;OW4(FVd2#QzY zh(;`k_w=Sw8olZ>i^AG8(d8(mbIs>dOcNhq8{rj<7WRBVUjK6$N2+`Nys_a{V7ZH& zbb_^gFx4DDSPjH~^OT-zGB{@rK{p|F^conwD#6{y)(B zT;=nk#EIZV<&TjKAfNGK)JN;Nk4(&}{>B%#RfX%^s zIs99;+`J;?FcOr00$VE-{%$x)Gr_%WjvTHbWVv^{c2 zT?KM|dD1btm+U3-Mja(<`EooFCUc^@@;R=BZlH&ktV2Tq$XRxoqk6|@ONtnhc#j@% zsME59Tuf&02xH#`B$YGQ(tCqX7*p=1u$(CeKK=h70E|4%jX=JX;Gd}fpAlE=htDWr zT#YMRAIejFWhd1*1dnF1DF9u}hrk#VGXOG3%A+HuCWic-tDaYv+H+t=Lx8S^n?A#b zOO{utvhy7(I4X>S7sVsiHS+{Dtz($zX=ID;!Hv%W`dAQge%Cw zu+5Ff?qWaU$M2&wS-rvq`Y(D3z{WFyOM5eCD%i6AHij&j1UDk;D66Psz$0pudHs~P z9toTkjZvm&3{3N1rAq~vWstTYD2H)q{RN5?Wft%?)w)%K!C~<+HnvF z?L%ePA4{G;F%6nV8!ng>zple;gtE$bub|&oA;wb&5rF39pdFhA(%7a);~gp_Vl=gq z<@FoKP`$sB;(vqcLD6l7@9PR3w+aRyB}V-pWr+Ls-cevd@JGh??Q;4JD|eV{3|@)_ z<1w!WmNoyUpt!sml#g28Aj{8t)7u{_i40U1OCyHhy}m0CpfAn`WFYa8U&B3NE9~k7 zrhdP_axMKoc$Pwk8WDtkkT1Q{>AT~@-``zdsj|FYrD7#VWy$H^I%D{b=acC9T6jhL z^X=$G>AN3tiAu8VUNGuT2fe+USN=Qx$=J?gC6g+jAc)HzJaSegUZW;+z(4Yhoy?Np zCB*K*9he9g0%TeNO20Rar1w4-;Og49q+vrgtJIT``gcd&skhFw+5@cS{tRdPL=(55 zYxs$t0sZU?|HbqZswzvcWVnlsi7Oju#VW4qtg!R_Al${?2OT-S%&NJkAqO083Ra+b^xhEcym^!%L`)!g7@CBs5@`&Mw#4qNbEmgb1I3?Z-g* z4ahuRO74>DYzxGQ6315faHFLC(tP%b<9r5xzu{-8#c14UHb(Ru%Jk9YRD#oHl8 zgQJ1w&*rzwKq z<wgmR>3J~Jm-6M7yS#0t~|Gc6o>(v+EzHc3z-(807Pkq%=r zzl_HoJW#B8D~sB8&Zrihmmgvhh15lhuO_JP|hI?E|0P)M-U_eCyDzud1Hn-1f744|KTSBY@7Tv z0Mx!GkzEx+f>-=zVis9es?9MYEvbElYwu8W;rqdfwq$3WZOZ(IA;(@}to&zY;M(M_ zQ)30h0-YW$jf6M+dfN+Xu^Y+0b{xfhPA99>j{hqb0!HjyQ;wGSnnI=5NVoki!( zDxG(TLmsZZjj9{JvRby98o)tot9nYTJ>A`Z7`i?5{sQLjt`5}5rn&p$!u|00pZd5h zMP>X!6&YGVaIIPCk!fNy;%Asu^B#k^wW&e3#|1KiF3vZ&WvMl96-i9WUQNmgFu1{r za(+n|i+zcycUC>BPOLkC?b+jGhb1N8=~KndN-k0}4+T-$Zafo#NvgGY2*cMftB%h4#fGkdyvenZ^m+)f$m zzrQ=qhZlf}Yi6f;VKG8+YvF@e7ME!^fsLG)j-*#9w z99$13PE91}k>K0m0#ARL(+<={)_i&;@Za6As#UlZ@|6+1V2ot%=fhSC@#Hh7+A)}k z$2)eoS(nd<4XPeycW?(WbMHMYsQ-&e@adSq6K(@&>oMS3^yYXfumD-bHF18Z6Bvan zJFcghiXL_Jc;=ztTm1K|=@tQpaYn3vEXzE}w0Jc#9#P*mT!mB0*HPaa9I}KTO#irk zo@>$)tx*J0_o#d9&8u;obkMZ$?oHL!*=85H2wTNBV0^8Jcz=={+Fy5fq>Iy{suFQ5 z@Mwo_ki?dDYOeuXdJ5l!D?b00OhThjSq_B+=Z%}@J{|k%F7%GJ#BJ5jDY6W26^UGI z_yycVYt3;yruidmy^@sGpu(ZHEB5lXl2)3lygGWqu>!Z`%tT40+~Q%bO=_%Yw(5sC*rv@f)*W*Z^u08YT%~zyB zXJjk)J}{)|s#o4wu)AI%1*vk*u4viOC)Sr$I-flbJ^M$SwBe^8?3V3I6vW>`3QuX- z1F1Y;c=XbK814P;ivCHzxH9>wPDpe^nQM>eh}h(8blg#}rPT1)9D3nWy`yh~dwWP-lzhcF7Jb*QWS6)Cfbp_YlmBE3*Pf=9YFc(5!bZ zX^e?f?N>kk9h;9DsO<-=H*?cU`eV|=anYKu$=1AZe1K>n8O(Us3hi{ko$1ko-HuG1 za>a2=3H;?Bf!iJjZ?q=ysyjTtIJqWmTPgxZQ@?-KCWSE;OlG8wKALQ`o9d(GN|U752v*~fgo#-Wxd`Is+<(1FU>Hm2_WDIpuf;TQTBLlE0NGMC+!B|Z;w zQ{T$0Q_JiqUP)V}^grIfuhdU-H6lHGU*+RC2@IzWe`nF?=Y7}SKG=yARh=+3^wNg2 z=rt@fbg)i>Jk@Y~PDK66qNHOBc>?KdD9DyqPQ*N?dn}IyYy^oqbc7GBOVzz2-2C$e zQxC-o*fut{})$HXVH*P-tC!)VOxqhiA&cg<`@dI%Gqw!46Qp4!*AYa28>bHBVdCkRR}=T?d$x>Q_l7H< zJkDs34kO#Otk#Ix`~`0^OLP`GKJl!<)f1OOJeQe7az%+5@&94a7U$_6JkfkLMR1Vww-Z$lO zWoH4t?!y!=%*w7TN30e&em%%Nk=SOw+am@4049z%AP0x0i>J(GQI_qrH%$LIZNL}g znvlDsm#8)y1|y;`!f#xhHHegj#(KN ziUz@L%yzp31N=oRV<8DyV`6tY%xR(fNQ}JcS%$GbzT4F!(iFaK_hq}D^@8R#OaC@tBo2}$JGrn&fGJ8#c}pX^3-qcKc~m%ZtcYi zaGh&iMja(jjg;ZCfBJa{IcQkiC;cq=d8k8O;+@m~OChui`coLLZbLMgj}B7N50kWg zX#=@eYt-Bkseu*adb3X%|C7SkF}<8t;RU>P*q9T{iz?cJ&4O9>6M)*aCYv+XhY zsB6mp_XS!X)8e9W`C{;QZLU1r`R|SzmAGMMh!wnM#Y*L*Od2~Z2&5&TtL%S~rzU1?CEyNZ3M26p@VLN{|VD0w8~56_NitN)F5rRJCEA>T?K zC4MT14gWam*2TMYTjN5~pVOa{c02`?Gpc;NAO27w;cF#7roSVrl=-<x4{`+p`l-TiwDQxh1^6(gUvaasXsZY=OLYM$Y zT0$cnu`Da;zoHJFm$Up6{G~w}uk$hS#_KiZc>fGBuhZrApxrpSv**{*@Pn4)dFuV5 z%q~lXjraL4EHp@-mCykN4k}1+ae|jaoaVG+gV{$NlK20j?aSk#Y~S`PMY2}09z ziX=v>yEMv)%eaVtBGeq{KB1@J@n-*D8))>2Fr)+~^$Ueqc#%yMOH+p({zTckr zegFCS^p|e;dL8F^9LITH*EJN0?)6UJ585LiJC6x?U`8%pKA^yG5wa49ck9TEi z1eijmhAY<;%e*mrjJ;|O+$zfv(5}~lE(x%;b|c>a;9k+9o15;Ma2NU5@)1hYGMI(T zjg>Id1VzgHY7`So56ZzGD-h_xMK8nse5(B$-1%eTA234AectVZy=vuD5WV6+aR#O; z^xxA8#!DQvcE-oIDf$`vhj(sVvA8o8Fk6<5JvS4dZQoE3Hk>)ECks>R(qf!Tmw2R4 z@8q-yCp53ylBZk^`x*6)sO>V|&x0{-)12#F?7rla_@*;XU1K^%^qVm#(ylay_~!JR z6$HD{4@-4v>dswmr>Qd{a(dLlQ_`np92*qVWQSzZY)Z7vL`Rr(%#FJ)Xql8o5Ytl{ zPkIxg-QVH|t)B*zgt&{nu#-GwqP-eyVDD@{AB~7VkjKEg7+e-S6YD8@ma5$x130!f zO0b_edK?r>+FilYh<+|)elHK>1$Smv%$bQSDOgFOY)~fg^c9;kw~<^RzaI=X!dBsA zzTlX(fqfMxUY{IMn}e66lAomL)%mYCp7-*q{&v?UprTMW92c4G%J^*f)C*$h(l|-G zLN53PwhP0Q;L~7gTVK+^u}k<^zbk^z?9pxwj2;IYYlqY2d*ZTcFGTtor!7*0^E)0~ zz2ZYd94*-!VAeo-f+-DERK(mkU#1#8@dMP)sv`i`&*ZQS_T}dUty2~FJ7{(5>)k3j zvI^p`vS}qpp?xjPh&T3@0u!9;gV@J&`Zg8ozN&GBP@jO}_WQu+XItm_F zdAcI3f$RA^%W2B?)ajldI2U)9)X-8}71HS>yMqaIH zb%sweOGO-o^6SP8iis`=tQM3Y&4rBN!oTC=Lb^{xi|+l-&8ROSEiHXL={BCBQdSjt z8atn?Jiv*^*Nfz1)B9Mha{t9Z0MX|q^Kw4LNiF*@^i=Sii5MFAX zc+c1hei^#~0=pfy&C($ba+U7f3rd}2?~4?#@BC;)HLyR8%=OZ)U2|nXJ%+x!=v5rd z-&;-|1+74q93=gT1veR=F@dfm(9h4yKJVPA2&5|`74|sK;BdGpvg)E|*?WDej$54| zs5uJERIX8;XhPMwaOxiz7~xBU@s>Szt@m;xkCpIfS6*yoE%mMzgr-WnfbfT>gyYR; zQf2v^79hUlIBt+b9x)5v*oH|a`W0(@V)gKUrHb^@s&KoEHx0Wo4HC}$TJB-6#1OtH z?!pav>KOt=U`m*NSF`}0MLLEMZK$OFB^V#}A^YjWpr;;ecvbmWzcV1418%+I+1Nd0 zRUmg!Vdu|qmJwC# zuvg8$p(hR@Db99*1b1;OVl%ntfnaB!bG<1NTB7OwL=47@jkR$MtB%Ay)vREh?dNS& z{BdbPbML8O#7ahE2W2y3W@=D8u2Y|~lLh2q5&cz@JHi!%*#i&b8T2$TZwhNg#U40M zK6ku?nckCf=yU?HTbChh#r%f$?#763e@IgtOgBI-f@kwy#fa)K9SLE`B&3sLJna{N zm*9GDzA};Srie}?kvn2UJC@^W7mS%RH{u+0cDJhpccjAE1DWylT9L{VCKq5t1L29U zA-Xf8jqRMkhZ)iqY6ip|w-uHBkum&wb)AFGw5G~ZWssMDu67r;PDRX; z4_U7k9=?>C$(Yp7W#rRX3R{KiFf@hGGT1cr~oTS=37a*5qKqL6Bc%4smdOR)E_( zWm~4|i%6M;_+AGPCI;#7WVBe#M6&|aMd(wh=MjrVus-TX0A&98RuhkTVEo28+Ht~P z=8n%ok%oUBu}Y5~!SowG?_!$U|CpO3U=px*5*V4h`&)2b(5KFPZ>!n@DIW;Maz51? ziAHIyo%RT_K2IHX-+3VbvdeGzK2{6$j&j;VIS0Ffv%QEmja*Oov8$Aw_yg}B{-dC$ zk%mw#NiH-JTm2;I!4LpBr@v?eEjtNgRJ}z&)j|34!7Ky$k1Vc{F&a0}6erkZ`sh-C zX686!m1S#jVIrr+;mx-5Q2Xf5jTwX2e_w;TgK zc7Kyarc46B6>n(o=<7cB8eaPwRU~R~_k<+VbDMZkJEUd^YhyOShOLr!v^c$qqgshK zvo(kKYHiq|pkdEFD^}l{4~z%vQ$#2|!po7W>Sj~Q_Gl)Bz^7$g4~sqhLXqP_;Ppog zM`9-Bl`cgiaLM1q?}2p0y6@qyBoes*|Mhnep4g%3)%7sQQZUogYPtNR?iKwO5rk!0qOPIym7SsRQoiiPF5^H>e3*dfHzr>B z;_0=Tx|NW{^f3nxheYMVBfsf=+}1bC~4%SVfbU~?I?4#W1{FmsYb5AT`{(ePOC5&xw~^JkeK6hLMj-T8pdJ zex@=mP>%K~JVVaSIx+oC@83lQ_>eMy{ff=_nnDTK#NZQEp#2BXX=ee$?ku$={%1DC zG6YGL@~+x?%EDGt2bW+~OX_#aognopHmy z4ludfXPaTRHR$W2ZtP2cjPnbT*A}`|gI2q&E)KIjsE<>{RS~veN^;}*3r{iAjp0p& zvGQ$%7Ej({2RQ@nF6t#M{RZ1c#kIf;?hiT(Pd(N(cy&3ANF$?`Um4A=P~C*Ld7KXS zK~tC{Z0;-5wrY9{6ej;tO}{~5?BXh=;^QeXOfwIqXDW1L_THD;b)uVMFjIb?LtbaS zif|+k2=*#6vSGBiilC~6W-3W0hT03^uMPkc>RA)S5b9DeYa4xT8(}CWQdKE(#rz^w zsoYsBpDiD&K(fpdfAeCJ3cBG2jeufJc?E6Lykw$iFYxRuhY~JlavUqw6C#i?e01r8 zbbRP#?-d00F&Zl`?jcHS|HKh#HK0w+PH25WJnU=^B#f|z9>g^ZFM+O4*bCX%_O;`W zEUX(m`QwDsPGhfr?hJ`V;N2}5=W5F$NISxTD#xjXESD`2GsHt2U>ZoF$Y4_SsyYcV z#6je*u_yDpUXfM>{Rn^ZzY(?cO`>Lwe{LN30w5RlDyx@I5aZxso3=vFiJp;covdJ6 zBB}El6SzxT?6ajYDzemyzi0hht-Ksn{gl^y2w24PxEbw;)dHPlH~(i*^=as=I5ib)pnGZ^LRFYy5E;OTQVC(*nMiry2dN;N5qv;*ACK zcY4gd>*~j_UylGag+Gq+y=#g2wiJ^yr7QMk2o>v5_CBLlB9g2ZD4&T{t}SiQ8f;$2d+nQgS?U@j~fzr zL>MEdFEpk!bh60l@5*~_Or6OIttH7x!K^Tw;oTDTdw3_aQl32OjZiLs4t+@-Jbs_m z1D?U|oQwNjrgf~k+wBAQ8Qa8-L?kLBMnee<3?_!1VPrA_>({xAu~h_QXbLB2*q2|G z{r+TR=Qrhi))V22R>Q2e^7vR36U-M|9}NIDFNsEU2bgepWV>>t6hxQdTx9ltY*S3G+*&x(x||{m2DDdocV3ThNZ|qnxH9yN zbo>n^fL5054XZ>SK2)ukC%UcVCI3?LYiVX8sNE6ClkE8!)mD;=0boH5MEHFFu9A0? z*AGw)QpJ7OfSfp9Tt&nArO9aKLzm7OQ|nZ0Vmqh`!u`cn7vBEvy8Q!7Dte?DF4c2@ z;ikUg4~>NyBXu!q9RbgAJ(H_hgaXK}2z;q+bu~u^we3UdP`~9H$Gbs;@2oU7c3+Tz z1*e~DG-kV)g}CE&WV#~r2T%5*cpo=N*L>4x`=QKSvGW}DUi7olXlBPh;m8Rw@aiA} zyT_+hS3~KD0RScPn0q84j9^^bKJ;8oMLS1%Y&Z0{3VAUafn}NomZXI`H6}i}``M5g zwWj#QVa}vqcpnp{IobRQwZcf1UAcjoBP^9%tcITl+Ae;<=s!gNP~0!kZvc|`C0p_v zR+o3IUAw*L3?2~XSlDj^8OQaU5jZ(^TTs(+e~45RRO4F!IXnTG6zAjHRDBc=2}mRY zuY6JfEakSS*YbvlcSzYnQ}#YV>TX882$E$Ik?qqqo)~yuUgEzJA##vEv-8<*T@$wp z|D8i#J=U9Pb2C^B*St4V$XVigPGSU@TyU&9C*<21BXm7A+No}3ZKQ)bij5Wpf)5PB zB3EqJ50(A_eCbP3qKg`F0+DB))i}-Z-(VD~1JTPGF%mGpZ7-bURm%20 zo*P+wk=k(>PqCCS8!oOIQGqCmQazYbb^3 zf9Q+<***xZtUA-6$g%3s^8Scf#Hh!8FA`@yLf3b0b&waR(a;C215{OqTlL^?uh3H> zX$gwOn*zljf&HUD(`)#1y@mASM2B2w5&aN|a;z60jn3 z^M1-B?RJd+msNCvMk6jl(704A^ z9t8p=iSxR@ptC&N`Sk_>onSq7@qbhLBDI}1<43#&huu;oFzT#L9V7*U)Rg#0dO3d@ z@r;%l^|JO3+bj)dJOhMiODha`D<1@id>7*}dr=#UMMM->8X zFhDN+!)`m?KjQV42jnrO_FaeS!kB5I`Wu3{@H}{n16&|m`H#fVXyW&69Q~*tN%^SO zzIL6eP3fx7cJ?#A``|`Tz0=L}aO0G5rwTU#d&|?8PSH>W7zsiJ*)+4W4N;=cl$r2y0z4&jhh8Fi92Q zuWrOX-t|lFG~dswrFV1k%pLn?VRcsqpJ5^c?)BErj&OCbaem5Mu2LTf`w=CY(tK#9 zAr8>%H~Zmv9DRE0J5Bm{j$PsS_Ff$J%Av?86Ka>?5?sPJ=E!1scSetx_a+L=cm$T6 zc$?MTO$)!`|H9x@`j)jk`d&fSjF#82p>+u6y!u{g6B4t}cJ7+jVEUd?Bc@;l-fxa^ zqC`Dwjut(%XBD+o$N7Uce@=6PyeWwM+8e~h1rnLNbap!QfXcwbnsp5%ily~b3NMIL zW541NAKl0*=Q|rO8#)6no;sign1R_m?+%CBDn+!v#BSDS#PohqvaEpze^T5h%1(eK zFW>!6&zIw};X;SD$%nch`f)jGeP6i4h@|n zZ$s{sf=pz<51b&rAr?&3z>mlq(Y#f8@Pw3xJw?_W<4I-W)FlCHr&46Bb0O;sDTgc4^toQ*k@sGuSTizjlhbAiV+7b>kWmMMnmc%4lV5 zAwab6j&HNFv>NT^=P&ZD&ZVg}6m3>4@`x|9v25_S+;Q6Np@`Y_*cimYA)hsSXrXomN60@cV9Wv!>gsfHRq$PgH=u4t zE+lI*?z4bEe9qcC8JODj2kNnO56_F#CC}F^^eOFnxrfzX#vT9`Q-$+ZR6j25^%koC zx4SfV{1x>)_1j~P5WhQIbKs@JefCFZFi(ML6-tpB4<9hTpn{H<3^2-`E)`{G&;NY7 z!BehC(OqOfm~F3MFp`WT_+a#$d{+lYmo)8ZZc8SZY0di}IXrioPG|J@w3;`BpD}#3 zt7a@Xg&XPdH0e*Hc--LLQO~DqEAE{5qmskS_i#{lYGqX>G4wPPm<;oIY^Q4VRRN__ zPG#Z5@$C9EZ&_BGEuXfmikaWf(U3W_S3BR}Php$6GU%$x9PS%ag_Rj&I8bLChQ4IpanOD#u6hhK)hTQa z#Xt0t@HCt+i}Yr<@^&4hbj_{6^(bK{|1WC8AddgXNT1LJ>PeP#p#Bl% zF@+`bQnF!@XYn?{-0MZ`K4c?%M}Gxxy3op6)eY)Q??Dp~zc%2HQE}T&tNu@?l`-n3 znh&n(7-vH@I>InobP=z#B^oe~zO0G+wuj(U6Tr8*&RVeBS=R zt<@18&0mqXhF%;_w-r@;Q!sFck&jfeTR&R4preXM&3_Z`ZK6V4h`zE(jhxqew^ zQ!9{Ra5&kpPXi3d4=c7-rgj2dG3o0U@#4{=6}lzR zC4u(#@_QE%_Acxjf-A%FgtsmgCP+-by^!=e@jy?100Yg#6PUvg3^k5H&~+!Np39gI zODjEmr?%t#uhRRHsv*Ip!FZhfV;BEF;`~2}&bP6C^c#*lm4&Q(0mHSBP283~6(_$3 zsRyJQ%MFbp{ZK$9$l9)H=TZzS84&MTBoF|_IsRZ%CRC`hP)g5kTFVBd=Q>I4I)<3$ z%i9evk3UxRO3&a{6Ut$yQH4sRC8u-9uaZt%Qz zmKy#^Nl}dx|Bm-}lt6sz4^!;Ibf{x*mH9^tnzc$}9hOuTo+DBLt!;W}+qTMCc7lWv zc8>oD8q%hh#I0)i4Oe+UYu+;eoiM_-q<43U=+m+9^&$$i?g5i0F8b&dyvtklk6%)) z`xI$`WGu9jf;!oIq`$+RrzT&?P&=08X;cDgWwictdD6l1WIqgrmV!K@U zq?2$Euqt)G$_zco(sY4(UOz*zohR%LAtt#?_KH-nmok{eD?^>g{lJJd$A_tx)QrEU z-B+Vr=Ti!tY_DqAv71|sb;>a^az9XE*LU(}*xl#LesUka*zf6#H-<@n=Z4xpl8CeF zuO#w%deB-ISpaF38QOBHu4mfj?m*2`us3aDF?^H{g}9cqqmB!jM`4B9w0PB1oZ3Ov zorAIOsLmQEzCL^+y~41Yd*4Q>)ONGV{0t8$$l1nA`%*MGHE^@s-tYf=xm~-ynvnB@ zq!!nb<)z12x)b4fe91iyr8_Z?J2Wqj#Jx#l0Aka0A>Wa@dh3&|s>J{c+emL?y)AIc z()uq_^cz@&832(BrqosxP9Gok zuE}OG;AERqVWCh;ZRaY*p#gUSffaTU9rd^MTGzY}fZ~^#tG8|D)}KP5z}f|DKyTRE z{ZiLJ;}^T#Z?&405ysS97*N-I-hCC{EU8vq7C?-S!CKh9)|!f~M#iy|!XuaO`Pl?d zNKz|5IYAy?rT8=!=(4@akt4B8{XCaV$79h;eZ|hA2O86Q0z>FZBi;R= za2c(MsQCO`S;;OSty;zrhA*x%0hz5IYYtNkNUZ5jN1xs_qOg*id8LvnZggi;FMj|$ z-7-Qb!b-`vfuq%)`;Ogt>i?KoHqEFYCl&_xFCD_4U}eHfm#CGsFhP>azE@hu7_08V zoa?H4`G;VE0PpvXsxHQ)29@x!0(C5>aMzzz^YQQkL#mEtMYZgQhR(jwKZ=8#->Ma> zlD`Ufo7IYw3ZUVL&GxPt|5N!{?8x|FfjzwfV5Ip zQu$k2SrZ@}m&#?c_tB$VBo(9lFLot4glwC+Z@2*+F+95iSk3SkU}yo5+Sf!|ftwz` zisg=fld!3q7{1cP#f{;(LvDcoM0xP5u`8Hd?82hJP*L(w_e;LWvbVBswU*21-IrBN$r~8yuf{_YXB@=t1)y-}sISDguOh9yVtUUX zvrqnxtX-1`-qFt{%VZQ{2+T(~rWi3VIqahcLc3<`$2yYvt!c28 z(kQgVPl($#a&(S|)|P9P4uf`AQ(R7}CfAQj0U2_$S*O=`z*XVa(6{id zx0Xwdk9L1xlnI{3Dfw4^XhsBnc-tasMDD7?z2n6}3c3~dRqlh$s0Qj8$zOj?Uv*VW zM$bSZ+7e${kHZv@+?stY473ySp9u}}@UzH{aGDLa&;1g9qG`|P&}&HVwdHlDf@g0~ ztCP4vy7{LnuNAln4Q55zv0~L;(%ga&5fl_;@U;N$yAX(`zKd>LI^Ll4Ui;#voj|W*i`ON=re&(|^y%DC;I)AWh>wYsy@4l0z;Tfk^ z)<1#Y4p|e?N+gKx)|-%aq7iNbrvldhtGwwVdX+F~YAk$bIaPC3m!-eJ=<^y^;N0>H zjdxdiH{iz?sl+TxXf*?>XHp!!u=_!aecG)rTJU*(O@)%+PBe&G@D_WYz79G9r{CH> z`_GXfO74pM9-cU0C8|9zS#YN(lDE${QxjdEPV{^dO)qihM*0~T(`fh`jl6|gMzn@~ zGH}sqN;WSxp9B3K`zAL#9}}8r$%D@Zh8{2iQ6>7+K4mQu1mFMnSS_by1G5!GtC?g% zMQ638gR#)NX1B^KO(uIic}A( zC}6|(sCIst^wf(oG0+9z1YA@M24=@&wGT%_R`f(S%mjykuHvIfNO_;xDZ+6n50t!?qzU)G7WEf+r)vZ+iTL?2GH`N>+Q(@m^+#4ViRG;H;UjT( zpV_9Y_1#Cb>~5AkY!mnLtYXp$TOg)UW!#vf(I+QKBf^unwfI#NG~bWK&&9$03k{fD z&iDjveYr`*#$CaoRB+&FX?P8Ar&UpTX!8^1%pg@Y%I^<86F~4$xEURxG?CW7PYJS= zmL?W-@T2&l+;x5Z;S3OE1?j8{8NXlP7Q8HzEOthj?Y{<5E)AoI>Z)Eo0K`^iu9(|V z^pbcWh&JF_#j8hTq`W<8n|nRwK!3agKW;%MaOR{%5Is>BsC}oY)j}B5)_|ZHgE$Ro z)kl($R^orWhG<|R8}=PA@lA#FE?E;tO51Q1d0MT-eE%P(`rtpD!9<@^b$5o-KNYl0 z7F-dl0TIVJoQkXdaAapNAxG`w=3zI*Y6_~!VS@|K;rH$yV2uP$`T`R`9Jt^@~ft@a4u+CLO{^GK6QCuvP^(9_e!@|ADwUbYP8?r$YNyA zhpA!?tzqrmghFK^^-}>HI@N-f#6lE7-PtE>v2&C(l?nMLR6m@XL|FD`QI~f(k6mIl zblS!Zr{b%1FVL|s-4b@Hmn!iY&`yBjKCOoM;*Q3-Z)9EOL&vj4jqaZnc3;g`M_w86JtD zMy=dL)ownJ3v$^NAa`r<4HrrZIOr%v>!2tyJNo=IUux;b!R~3#`Ui~PYiyg?%G3!Q zHS(h0rY_j~G(Q|S@is@5Ug!t+7+W^SF}zhgZLL~8yDs|v=*w#fr>oZOM%1T#e8q~; zJ!rNy`NZln(~MURx1V%wtWBf3XybzD0oo+T%st087Bx*$%^_ClL&;Ykg-9`e&(sN_ zcdpZ_`gQnWczNV7EfGPvOMtk9ov9TdsJ2Ej)6dRV_}qz{XEX6o+bLc1$=}z zSyq7=p7{OgffHZKx(&X3>cTyQt2TFsPWZ^8UmeR@yFWMW(9JJKKI5a=^G=Tb!{u>n z(D$^JL)Puzu-b~xi1*drqbya)IC4u%JcEl*O-0f|w)KTS?(l;M#-nA1( zqEk_Bz?aHF%W7yFkYt3;T3O}PRGyw`J|xS>W}RJ6R1_ByFNb#U<_-H4eo0n4lyv>+-(v^6mm9vqIXbm&C1t^6oI!;=V4x0U-Q8K6s zCp0EoVFo%c=egf&)Ues}T3sWebwOYDtH3NsSQY$0$k9Zv?s1!oXdaB00n;E}0i&;TF@}4icAb4f6KoHj@ zv@)0AZmI%5zzj}P8!CEY+Vs38QA7Dif@CM`81z-yQM(NmJBv)gl#3Iir=YV}D675I zP^a-0gfgV0b10+3*J0T$BMC`-UAOxQ*Vn6d;VmsHmX4q^$`KD~y+v{e>g6-aF%8k} ze5L{4EDPK|L&bPOj2W?F7rIMKNrJV+J5$xkCMk4B$niLf#B)OrBz&z#q&-j(4tJWH znA%&NP#zxU)0LSj$p+vZ+qXqK26Y+cLW-c#FUxJ;99wLEd8zYb4iwlU$jW1ReXJGh z`t26(ct3JR5k!xfqn7E9^-05nWGuL6uG-mP)*PF>(l?mTF-vZw#--njUU5r83Kd;Q zZh1nzyh_m5azj9N_XgCIRdcqL0R`fHPG8#LrXZf)$4&2>CEPDOEb>SbWR2{~s#Z;m zQc!)cKC7|^))sx)Tj(w!f40%P6qd*?p}HKX1V0iF@tqYoK5j~gyV;TkfFq!`1&pCp z6SZrCQC}xJ58Z-GoYPFZdc|dGFnYmCmMnk+`G2sP5a`Qo^=XZI9gZ-)SG!L%>Vg@t zG7!ViW9}lGjSj^-&l*dbMf8*IkCZsq7C}Rivls8%F|+=Fzn@UMMN@mhZ&n&mnPBdx z=c$^x+FU+uPkH$DZo5hPN5yA>vOacKdG)eKoXKw9rSrSJ)ru|%8!VR>JuXx4JoQdG z7+COupyAqCg3fYS4mg2Y(1JfM6wEQ(yUpL~Rbc9xlb3ymB<?S0z)Y~X8i{zdNJt{aB{8nU>3$CZ7M|yfc3sV5x#6Vt<~LGv1-*g zXqhSL?fWz(kv|>=p^?;%X{?kg{z-e>y@(tj-FEe@o+NnzLj3lh)Q9hMR4pd z$V>Q?p){OwI^6DHBwmz$GgPCy;NZ^~!-S{!EPOA0YAaQ6UPBFd)XbB<`R6L}tLE-N zi%psaNfo#JT+vYtH!lb?Uje2%y#3m}P99v}Rj0Y5b{}lcT@Zl8AtL|ws~OtZB}2K_{6)BOtDw6CEd{@Pdb;*aL zE7eK5tq7`e3V9EQog-%51%eG5Ue^V&@Sz+#srMDVKO&x+p$^6Q)-1{fCE1t7MR_r5 zDGuM-$hA)ak$Rs!v%9qwP@-55h)7GQ(bY_vF(wKUw{=^~Fl(-RHK!;5iw!r=zASM?1sHDu%F55dcN%=e|a zMby9sBbUpnKHv$Va<;|gd++Uc*L;lRGBD~GPUZf(jCL!C@SeXs%os9zNljy(kjgb; zp0Gjcn>zR;)z@FnyR||&$yAz=qYttsTFG$LtSqgY9<%jTW+Ok|?BIYBH#8F!z*+x_m+)R@!M;&8I=)vh-W{-YV!7 z4%D>BmpOnag3N5KZAu7Oj?`m@28l$!GTcY|Vwas273F1M zl=mQ+J|O%w-ie>XD#hY_xC}LuoAo+T=WJa?U8_J>esb5I`GC9U&Lz4hYDvhjRJwQH zv#0C=mIB+?$j$$iezV#Af|20G<&%e;MjnyR1*F)kSAW+KG5T!RjxVx5`qJ;GpL6*xdGRIE4Tp9<;aL6P})`Z#&G-}kgBOks+4u2`QP8$xJ@;Fizuy= z#(*Y_`iGFa!X1!KWtP~_qY+2+jtwgXTIP-3*FDG2lt>=s^H5BHNul#?saNe zt_-|@Lk2#z0ntTHxTZWrFMLw;e}!A`bs)p`9P+hrMx{|36Q5({LfZ+Esq59fe@ zQC=#(@==`aqm+jQe=(Ij-6z~D0&fd7eirbCO=zrP%?uPYAHQO66t@gy`s`y`nu{Of z`UDrXAR7)R3_eq_k>B{&@3n~9kH=>4AjfR2cVnf)>ytoDLDt+=07V$TB!r!o?Nei( z5Gvf2oFt^B7&n|`lB~L5-v>YGc=)tZ*hy}YPi&Gq<~$2+WL~xoIGleSykh6-`%2X@ za{7BtiQ#9+*x98&?Sa%FDU4Q14P@Op0H1$6=nQ_K&%e04@W}Q(VNfAj)@ZE@@UbtWJ82 z8G!GU4_J&M-@iBfEfloGO_uDX@WgOOK-oP=|21jld5J<0S&ec_5doBo<6 z{*yVJ{l3K<4D!R)3@_UGtf0SjHr#m$uq_?Ih$6p2nn*sKvm(jYv57cDs3j{uVT~vs zy*$>O$$y~vp%d;&Hcx<+qYmzo!y{6S$?f5_Ne*}C<MUiaUE|B{N?en3@`HWX zrQw0egQ-dnXL1`ZB=Kfvx{E{jVqi_Uh5_NScqcQ2LaV%F9S_Winek|_n1rp>tz36) zrZv-hYnsR|VGv3La@L5~AN6ccGhq+y)zJenQcB76PYI|81qB@t;OdfF|iVV-gaX@@F3?z;Ss!n}C^ao8*wbW}$3*>QAadlQhxs;X5EY zG9vyz1QR|(+SvWp)hY;;C9NDx;#XU-MvlpheNNTRh5xYs7akDu*+A=@ zr2c`_hK8s$1dQq6y0ubG!<`Qo;sbN7L^qN^j?2u|If&ekP5@2rLeSTMuk=~XOl5gU zroi1%poNkhu(RX6W_QVfF`f!{t5>B+-zH6Ir>Y`9Q$TABdW(K(9ai!7=rY3tf#fzI zF>u%l=A3lmOZcmJbyfU|%)_ANX~Wfp7t3E$D^#2_v{v}48@gc$cJ4_^9Xl&kTl5pW zEW)(_y6mWQP`L{(<9{%Zey1(?v`^Y;Vdlh`=Y!IFV?NkGD&njh&o-+omZ&+Mv>#gh zV`M?73d#PY3(mS8)*Rd=^4;JHt*@Ue?4c*SQfWfQN*bdnnQKjb!iA!Soly`YYu+gj zy(8Ai7bmPwkm}L1=UCtg@2A&c=?ITrf7<50OP54Sv|ZnTDFaiJor?yyd**ah^|)Gg zw~jC9!mZ0KqEf?`&uJ=b5sHg}4ii`gbItRAi;+p}U(qFE z;;C8SaL}!ioI?ea@u4Pc6jtSxd+SVsJKvBFx~-#15k3`FDz*8dnHG$DDVXe})bjG! z)~+Dwhzl>h5rLiH6Gf^?pJv*?cOtrOx?r4I_0|r3^>km(-BY$jGR`ji6} zs%&)|xW|vRq{z}?<~z4hS9scVXMla|)=Iyx%5|Ln}Mv|Rsb=X00eyzOULM7OPacVth6&>!78v^?Raf(Q`YIpMTTP~k6RG>7o=;# zFL=3KS*pt%jh=L48LTv!?2_4am|mpGA!zLXtXWsy}lTcZbT|$KI=C@w@dTwY7?WXz|Jx1wQmR2 zAe~^Th4Zq!XSNFsg>mS1BTe|dpv(nDz#Y)hA9h%l`O@Jju^oaoiG7skrc(|48lW9# z|Fb-S`yV2Sf)i~wS4{MO+0`AdTde=h)5!0n0^|q{Txvpz)_PZ~_Sot>M&3N+^+WXj zO*%Vo%fS0YS0RBM2R2T<)KXo48BU{i3SM%JL#1VAwjWNi8zrxwJgu=Cvix2^vbwJ> zFbO8`Yle+CyID@VenK|i`NbRIzEpL~h&4olIc?H7HfAV-YsZ?pnG#p8!-9(B znd-YmpEP>SP58$C7&m?~l2_?61-)`7Ji^Tf5J>Q1@x1y^bJ@o=}9bvVQPhCBEejStjSqCtvHJYw)Py;$^3!`>uS=3@Ce z*tx*kth59N(qtlc%;iHyZq;cO&!>Vm!$T2KdBAe_>6ntNujsu^xtlNT163XM&USd~ zX4*{YFh8fe03X)8-t}48-uIzJN|#VxvoZQn(B8l9hC>?Oba4^T8uk?Fz;PU%yETpY z!%}T@Xwn#W>(Z{Qi>wBpv)e9s#1?|NLQ{#VI_8xi&|Z{k$H(TBgO~Qg z4o`kfU05C{Q6|NTo>RxI;ZqxN$0tV3Z^`T`JVj>zg5v!E%HdxYePG%INMWR>!WvAL zr?*AoI3~*<3OJB?pqce0kt5{07a@*|mzXz52=$ac{!(QPjSSNWdm|A4)V9(%4Z#Gw z=~fx1j4YFxTQMs2q>Kp!x9F>Zq*sYCl|Pk6Q`4)avQBMMY#hlQT_&R0Z7&lDMGK&Q zLvuKQX7SE#H0#R-`}~A+y5a?P)z^~amr+W)p3)dur0q6|K={{fBET}Y>+{KPCAT+} zH_jaUmJRGx(m7c@Fx-TLoN2t0Nq-!NI<_*oCdRX&RIoTeJG9czIUN`w>SOm{PE)EG zbYI(`Xp08a1#FuL0)iPACl(E9UD~O42LpyYDMQ83z8>VHcU}^xQuU?&I|f51TFOj#Mfo~YQi|NS4dj(ZY8L z{NFIXo$UdP%h~H0{4yao@9kuxB@CEm8<^VTMtR0?Unx=ELAj8&&{`!#-#^XW2|GT* z`O|CYII60q_P9w4zO0V&r1-3_uNg`tIxRbKKVnuA=N8J?Pfd^i7%~my^a7K%;v@r7 z;>g{BzhG|kH_XrZU!C$b0ZDDbd}Q!nGx{dXBipc%oA#qjX5jtuW<(=PbDb9`C)>v2 zB#sI@Uu`l;%#}+G^nX5U?#)qDj_5hb26ntk-G98v3OOg`x_qO^osf;ZI1q0l7rw3U zZ3U1SS^l+|1ld8b(WT+gM`aKkY135rRfPCooq_dHFfl~``*j2U#6Jmu&dN>S;Qts& zGK#0ag)44$1+i?`Co~FV(js8rYwoS}$4t^s%FPCR`SIw+Eg?Zj`|W55Y&a1a}_aA8-vxC-)+t`N&-B0_=U(j7w z)*uyYKS$U9!z8p;$W!*P@5@K`rQY44T)LQ6O|)mna3e3pC+mMkC=$5hv4NneNquXD zwPG1VgzBQX!+9aGe*X1z8MtE|??#Yb&lN>4g?CQHPPDqz6GNL72ks^fo5m9|8bQ|l z_B7$_xli?bL&$=1oB~HqZMq3Vj)0qRzHk%il>6_&Q4vEtP~*Au zVLm}YsZ6I~%u_9glWMn$4Ng<% z^553WB0+9mM7h((TuI*~5Is-EX%yBpCKI+CRyu^-DKSzL(@jRvI&v;oqbE9Su- zz`ZorCOr>7!^6yxq4;X?^(E`UK#ERE;o#rN8~0c87EB1U8~4t5l|ruFGi4JI+o@7v zPYIt|YcKhKm7RS&)9e4oJKt`klvw9PXeCC6+?IRRaT^VlbHZ^BvY6Z+q$#!)x>0V* zI&No6iOxyoE;qSZ&nMYo zuu3>SbqXQ0KM_l%;QRjQYa^vwM+N)%%zPL?o89sAZ6ILK8#UY}1P137lN0kyP@|)C z)*u+pvDbGr7EOaqIbT`uy-w4lLDKp4?a`AMFK@rP$ z80GT#MWJObma{eYz837#bE({bae9VQb22lZjDTL5OTf!j6;t z8)u=oIoJ-{M9yBPc_y| zLK?(gjX--JaS`Hs^_Cy=oAUHql>l(qCZag0eU~Jf*~5yyvSY=(V4uP(Va(=<4Bz0~ z;pk~};p*ss#+vD;p6Z#9m$w6IV+QUL4%2An_DT#;!K1DQueX7zlM6)Am_hoecEGf7 z%CZx%)0lo_YxJS_gO5f4A}st&sxVL;>IdL!s#oM6T+1a~@o znLU1w(qq|06W-J~SDxmf0E;vOq5sznL2@(7$D{nM%wZ+)R=H*9109BQ`;WUE&c6+9 z3-15lWSt;+52KLu#)_c;PWXw<50ns{w|}k`_LNaf4R==P~5I133Q^#(soUm6~OhzCC;kQ+(UpN!TsK84brrgg{jGtd_K+}L^|HtL{LQy&rxQhX^|)ga z)KgUZXx}gO`Qc+KRJ21)TPkL4Q_29Z;@=?$Dt>%?Vv&UBiE6D{5TN(RgDd2{-#pJ* z8&7`T*E4OBi+Yz?1s^e0oRt;!I5XuHFi|6^`WD0jEQ-_tr@l72vqbw*h=@op_M(91 zr&M5T(!ro5rGd+FWLA;8|Ie+bf5z<=BQ3=Ys-6=5&U5Di{p%9)BS5at4e^{5xv!;s z$p3Xu%bP8W7X_BhY8A9BNR>^5({4JJ1uunW6 zAxTFVhqJ||RY%Ats9O;PRPx-wWs_To7Fx`$FIs=+>L2X}!zr=J^XXVvx)j-1&lVAGF29zcOU=aK@SuG&c22HGq?{OW~wWC=01;-schLD8bz6urHd1j}Y?pJwYdTVM^i(x>%ql!Q-I-682GWSguXb zXEj3(xJ}fgxZZ0zF##Uc{;jwMj)+sD^1$?5PD!KE=r<7D)4U9Fb3d8z8iFt)dpMWR zdYVk&cm2fqnJtb&6f?+6Ns6Y=N`C)i6o$Qmj(8Q{feENWxU zUe94P7T;NkGYTC>m+YPIG6MAIpkwA1fGRj%z3hxFi#^0!1DG6+N`rJ8nZT`=;)B?%f?~2uI#GMGTP`B2ZqpONRu)9*XP2QxKa96D00oJH7531 zPhaw)0G*G(F?Vw68-KwC8P+40l#r%1uOMEqqslug9Akdn9!D^GS9S$lBNl8#g?}8b zREnwm?zvwlL&&UQhAOU$tnmdA5X-hS3lIrg&G(8S`Rz62B4I<0X*EIaCg+{OkOr{Mx>m_B7x;tMM7jBcjZlcs+r5x1!)Ff-DSIOO=U6e5mMQ zU1%(q?U_M`r+B-5>LCVh-1IoAE26bwLu}Iq72BB4v@$bFPPeH)PNY{5p0OtEM}x~a zyKNMak9Ebsj(YWc{prgD#nF6|jnQKp=PYesoFOX5Jvq#Mt>a_l-+nmu^{%H=9d-iR zCt9weqj?uA(K9S56rj)|3DxBu{XL_%mKN3MPLKz{(kgM6MW3Sv>)uO#G4Tb7OR{OF1~kRR-J zU{L2C_j|MGI}DA(kubJ3d43PJAhCQAB0P?vP@w9paOUBrMw@nZ@GE`WIDeK;gwtP= znz?##F=If4t;_ank9zK<9p{M!Fc!9~LM@?ZwLrag|E&|FY4Q=l<+Mgb^#rctb^DXX z{F5Vl@mTwP?O! z#0a>Sz8u2|0fqM$;pMc>y z?en(-6{vYR(Hs;ZJWI%MnT7$-P2LOx&p(d>&g;=eLQ(aqI{`tuSVMb+dr_Eppv1c$yt>CD4e^2av?M4%3_M`8 zWS5-jnWC4#JHQYNhyDgB*7kmoVxeGIZn#$v?|%T-^!@T%9EgbiO@?pAvR;(A@!X+y z5k3(7w}YPzv>tzFz$^DSo*_7DXp;uDH zDJQr;i!xM@4^S_Ds!rb3?WYcqvsQf2^zC=*!1boKwt|d+Na-25Z61eedWd=N2D{v= z91;#O9v|xZOME-C*|!=b{kgg}NqIWYBhRIYu7;56h1gPFMh?GsPVe4&r&Y}U(53_5 z+}dyF^J9NTbaMINEr$7WxAr3vUeL_!`nPu;at=6h01_m7!%5!7MXr<**FLFR7*a2f z=Yt%M?IgHbiHGvF&Lq!kh8AeBnswV^4`hh0#;Yr+t6c9-p#XHV zO5&2cVQT-DnoCnoYHk}~4Y`(FzHa0RR47jQbdlMw7=g%_YNyGlm#^ zqSxQDJ7ZHm!pAYg92}ZlqqkNK;@W>+q_9tv?2#=~xO~JnQ3xoCHhor%g=z0yug|Fw1NsNyM6#uU&LU1n}$ zAjxwS_2S7a#tFHzooX*Gz7McavFi<+xfFQ4ETQoi&JAad67w#+b=uA;c8RFCv={hG zqIN>Z(uqC!Q8e(bd75(FN!?;dGUpGFzYx@nc*#LzvGB)?5HqnFy1&(p&bk-g zwZ6*mBZ!M*6t|rew(5)~a0c=!r9kxzqWd}89aQn=f>Vq+Ju8iRNMJH)73ILkQ@%e$jK^WXjM;$8FtzRqxbj)J; zE&)CD))z8C!kI}Ox1cUi0{~#quYjZSfx&e(YVg*8+Q=znG|nOZe~$}-B2 z2^iv8Ib3IB&J==rE8b8JD^*z{q{E$xCU|>IQ=Mi+&Dh#k9$8js31qGs;8pxp#PABa z8r)M?kWeJBLTO(pNz&;HO49AA;|-^(5ySr*7X&6%KE8lW;N^(1ta}IZoj?rz$b$Znbar7(P$VOvO#8H75SEc zUI$ItOi|P|2Zr0q_YhGdaI4Q}Lyn-04>x%>G2y{JpJv)irxzEm@sdTtmj)q-hao6*ZVB#vsEvZQ0BvMT+ zg5Jo>x7xpz=^I(Z1}Tc)U;~Emh_trLqIaZ+1O>#ir3FOF5bKk<%wM)rp9rYiE2+|y zzd|L4h%sYkKM(CUa@`P;3f65QLll-|g2(IwlSL#RGm=~1J!vagEOO<-!q|e2Vm~^! zdB^??ed$lRA*dcs3~7E-?R!k1O<_3Q=`kJ?=e8UltWMtO~5@nCQ_D zAGMahI2XT7AslE#aEBT0p323||2W2ouKqPO0BW&Ycgb{Ov+%{Dz?!@oXuxwKs1NcY zy-D%RGk)72$iZshvVg(KSweqA4{{Q3*E)M?h%vzoaUjSffG*(Z6S- zNf0XwKd!BsPcs$&It=mQDe#5Z1get}p&wIbfwMgpvm7iuB5A`v04%T_ufdyZIQCll zzsTT=FdzE@oymeU(c7AgQFPWO?|&km5yPcrkZ(K^c>VQ)hM4-?xZ>#`*z?1&{5`)> z0?jnWQ?oIXb!lDuXf?o})aLGKkR@_Xo^|TT~T2@5?!iFzC9@Xn_I8~_h`K{+fQ`0z_I%9m-aI#;!YABi*T??5Zl-HAuLj{06Y>2LUU!N|GpMC|y1jbCA4WuL+ z0?+DJ$1zs?c&IvVj)P%f&ea};n0TyqMU*n`I6o)>a{qG4=x!x;3#gO+|9a-v%(fdm z?IP*@+H~M|gF?-5xqfc&?EbcmD|K{$)y~V{$z97$Ew7Lfxlf><^-Papbv6$RjIac? zSN^gt&3HRCUM$$P@)sh&`vjP*-?xm#N`$j?X};{U;C^!Fn{+xB%FO4?{~$Eh`JN>_ Rrnn0HnVVP{KQMF-{V!{iXSVjgC4j@D8Gz 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

=zRIBM;1AayTPQ_VZBzzE0wk1U4P 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 literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Features/Autofilters/images/01-03-filter-icon-1.png b/Documentation/markdown/Features/Autofilters/images/01-03-filter-icon-1.png new file mode 100644 index 0000000000000000000000000000000000000000..e5a7e7dc09c53595d3d47a6e3aea9ef6d1253643 GIT binary patch literal 453 zcmeAS@N?(olHy`uVBq!ia0vp^f*{Pn%)r1{y`?=4$YCrFa(7}_cTVOdki(Mh=0^i@ie*gaU^Oi+> zTjm{m{`xr(1ZD0G%G?^1y7l?v=g%MCbMmdW^sT=4_};zy_cRTh?%lq2@AkcGx3Bdq z+I#K#wQHBJwanYQcH6mYm(QKMd~WHsV?b-|%G#d+DYcRyzhI#4gaO0ys>VG)9h?Oo zk;M!Qe1}1p@p%4<6rkWLPZ!4!iE!V(My_T99vA)4^kWGg!AtlSp850N{#{V&ZEfG% z6>)q53Ts!+S2Ac;=~%UCSGc2)rBW)}Ztf$LG`d3ATAv-j=3 zFtw;D^8Ld3yQ3SN*4z-j%5~Oq&i}FxUAHP0`UbpIUdiwGxMX%+Px`%jiz!!^Wyi|? z()T`BdGe|Bw47)awJUR`^QD)cy}0M-x^p7drulYC0U`O#H4L}C1ho`4@SXy?n!(f6 K&t;ucLK6T=xaoBO literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Features/Autofilters/images/01-03-filter-icon-2.png b/Documentation/markdown/Features/Autofilters/images/01-03-filter-icon-2.png new file mode 100644 index 0000000000000000000000000000000000000000..1567245f34484f6caf50ca4c0ed4873d311a4abb GIT binary patch literal 640 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 X;)9YI`!@lP0b%fT^>bP0l+XkK&`adE literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Features/Autofilters/images/04-01-simple-autofilter.png b/Documentation/markdown/Features/Autofilters/images/04-01-simple-autofilter.png new file mode 100644 index 0000000000000000000000000000000000000000..5dcc6a47cee34a4bf7bec206542d336d0e2b2dbd GIT binary patch literal 67694 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 literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Features/Autofilters/images/04-02-dategroup-autofilter.png b/Documentation/markdown/Features/Autofilters/images/04-02-dategroup-autofilter.png new file mode 100644 index 0000000000000000000000000000000000000000..da1f089be02b1e0f142e770548c72e917fe18323 GIT binary patch literal 49268 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 literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Features/Autofilters/images/04-03-custom-autofilter-1.png b/Documentation/markdown/Features/Autofilters/images/04-03-custom-autofilter-1.png new file mode 100644 index 0000000000000000000000000000000000000000..0098d98a4999ed0671f357c568e6828dd8ba24b5 GIT binary patch literal 51786 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 literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Features/Autofilters/images/04-03-custom-autofilter-2.png b/Documentation/markdown/Features/Autofilters/images/04-03-custom-autofilter-2.png new file mode 100644 index 0000000000000000000000000000000000000000..96ff2cf0fc856013ef1c7d2d7ddb1a57fe6f508f GIT binary patch literal 53489 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 y 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 P_^0wf<9_ZvBj5iIv^nmF literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Features/Autofilters/images/04-04-dynamic-autofilter.png b/Documentation/markdown/Features/Autofilters/images/04-04-dynamic-autofilter.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb905d97fc573a4a4b53833f1cd5757b96a6bc3 GIT binary patch literal 111531 zcmY(rbyyWqyFN@evT3BdQ^`%Y(nxoQNOx|!OGLUsKnP z_ROq!>R$JHo;8FkDM+KE5TZaqL7{*AAn^$b3MLQ=3RV*d0SXHG_s*;c@BrHBle8FA z*(mWI@B_|5R9+McsxlV!(Fh*+jcorx%Lxh!%lY*WdfA-J9SZ6t|D%Mcs=NMSE3zMM zZ{zjKOEYA}t^H(qF>P_P&j%kG6M-Q4ZKBZ%k5;IQCh?5F(TWklwU5YzrSauHb*iPR zF|njs944+C4mxJ5gS|WszJxsG>GMJ9K3H$5aFlOp$2n_qXZT?<^th~S*=iZ0;NqrM zU%8R!Wq3msyKvcmBQz@0c|cS4Lx&sp?KIC*J&Vyvr-jYrrwhEzFO%zF-r@g=Gaq($AkZnu)LCRS5e{T3Seq8BPDMT;Xec4*7p^z)p<#ZiUffTR1( zlW+Kv_7++8^HG&YyRXZlB3l(01 zWplR~487PebVulBUA(>g=akc9)(k2WyK}IadoYBA27-SdnNSRxVKPfRcuu(XfR!7V zZbKsuiQ;t;DU%Y0iV4_S&uKdrHjV~AZFbUqTOlZK?~GVr7HE6ML8&azr&sZQ7%{j5 z zI(Q4=M%AzI?p!;oe}N|G zH0Bd6Ars3p?v%<0b*fOT|6*3$xljEB`8${+A-FVuH*BVOfpO(5Wh&~)mw`H0UI+I= zV3kv(Uu>*8TpWRut6E2i%CSUnfma@hlNsj*rbEG`lFDrR0}K1)qTggC>lmzQU=lO; zi;;0%{OY>`{{G&uqPXk*x=U-)B;VU8NhTgi6lF%8fw{dF=Y*?+bf#d-C-AK2vx@?P ziS}LBhqX0V#~e_GT3m zm&-{dMim0wgky+i#p$^=8&>e`Gi|}V{mq53`}N(&L&tJ_GG8kPOq}Rc)9sIW%Q|+) zpYJ*FO4~R-g}FsV7=*=r5O|Wib#|<8ECfH6#r@?-EFH)gYLhc+hV~~-wF!3LpJFJJ zGiKIH*(_y`=Z}S2#p3-=+*rLxj2hFN^$azd!H4MkxIwlSuPDT!!UgwekH%p>rbo&k z@ymLBcOp+WrH4Skl$Whx%VV{&O8!F>ZbBLrCc(*UN?3HIZTIL03K^P6Pc74Sk)mKL zA2VV5h}(?_zhd4mvyq;ZnWMhmC#Ii*HMO(`rj^%d3XcyzA)I;_pSUG_S0 z7%;GC@ehX&7r!z$r|m3^T}0JVD-83Xis)uVl=ZPHFk&vQvK9GGu;R%mA!b;jC0*b3 zsW6m)RYLU$O6@_K>xzzE4HIL3vO%`0;#xla^2&Sj&PXn;qM+cTr zzU&e#)a%TS`nE(eE(~-i>@2q7A}F!3-VM*>-?DL!_H(vd#q=fGtjB#WQ?Hx!uk;L@ z&Wk|d;EQUMWpru+okhT(%&hL|s0Cr1C+L?88AUOtb)&M9B-nV+3BEj7X@57pTjRZ34?N;6x_*^A0^}-4&EqBH# zK0o&Cj+<1lpae4a==SdNS$;1Td%P&j3f7K2^qN_myfnEa(H}%D+bolamFwN$pI@d` zcY~t~zhH=k=Nc<=aF`DiBCXWEE`-g~5uT`dLpIuYCec_ufRkGqi^Rk(WP?XM=H|_R z!kV*w7>gC@F8Q17ZuoiLeSmHyH$Z<+I%8s&_jl3y2h3&mzZjW)sBaW^ZtJ@aF_Yz} z_mz$5e@)IWq+r5H?e#FUte!f%Vuu?EW|(;7YPVvFx42P}YTvosS$rSU0x<~i1b>h) zkxSuA!Y9rgJ$Fqe^@5|t4)^?yB(vr`N`2@|ItFxZ!Bg7RIfD&Vf6n{58fc^xIjKoRX`@6gc=rgN^*2a}CgAY-WpWoTxS??V*-$s;lwuNpd{ zFR5Ck7*4F5q#3_HMaYA5jIw-G*H|J3*2avE`guV2Bp-wVrK+?l<4sfolZ6Dzm^=m6 z1c6GS;wF63QTu4+`gqe}v589$PD|p;u?e5rK0n` z?5J|kCPjK0*R7yLhFbbku|7!T7i3098hqxHgEx8P#0-C&otG@GsK^{;b)y4C9nUs< zDM|M9?M}HNu{BtiTU%h|$;K|XtlsVs*Ms0+yFOA>R!(>l#f>@V@MQ&7Ao&~UxGpD^ zFbPhna!4+yy0t2LMPmR*$|ySnL8 zO-_gJT2`x`ony{MemNUPrL=#?*PVF*Tl~S69>$9M$v9hayonTh`Qn@@l=f|V>ogX#)LgRw1Dxc!sC6E@#nEcp5Df|2d{HSJ0G zSu1gK4~v+J!)AI(U6*Q$gnk*~T$7?0_+FGU(L_24+GXAHg7T@bTo$3k(v@v*jJiDha?V~T zn`nEnKSIlBIiH}*Itz&ZQ#z@b54+?VZA%ls+7s$Kirfox5VjkB?&SW5Yzri6=j`mmLVMr~e<~$n5PpvtCpT%(vEIx1UP%DiX=|)S8Osxx% zO~dctvH^=u=9Z0@=xMN*9SFj(S|BHFyZH^xovzRH+J8QXv2Gz?9Xk2l&t}@xfLjEs zJ5@!c+Y_==Z#sAYwZmnHA#61P4f!1+Y(0Sq8Gf@Z&HNO~yyC$;7CYy-Q(beR?Gk{h z{eCNQ&4c;Ko4D#IW9*OpV*qzXN)N9L^H85ol}pvx#kr=oYyqBilZSL7ZGYri=m

|gk4Ft{irS)R%4JabzZ*&$$ z@W!_I12S(qs!jiBaPA+Eao0s_dV+S4c1#-Li1dhmV*Uk1Z1hfLi${KBc5g$l{ZjJX zxFz%C?%lZYFpQ;;E2(08$d=vUl=~D+gEs-uoBqAvamy(IOHK&1ZuiVY(68Q};IBLm zm^GwhoDRsGSv8t+in?f}GWZvliOdF_L6X*KsN}wXDCyIy((~C?_x4spz85 z4n5AE=caszUurO^kLK%2$eNd%bBi)ELv6I9lhb+YSA`J~VoGpqiZ#bo~>8-X( zNi-`$8xiwA3p=2K++>ak@X%roP}ud`oGEUgZwBgwp^YEUmTvM;zS_s0**yCKTsf6<5@q=%`c|>Ey#`eMn zqzyF7W7kP}yY+<8FW9EJP#x17(x*2;v7Ait5liF$EosW0NN}^E2J@(vgPL8?fBrK7(Lq*EiUi)l79LIbx&T@`R zIxXYJ47}Mo;j8SLpTn2%L07dG`{Uk%Ipx1$Bu+0? zI$>%K`*vU+A1~NUJPo=1;lqMAq#(w`0@SSeSX?A+clTH;JjZnV48x&=7=E58UZPJE z5myJ+hrauK`j&IwDDLlF(%jFk`6N~PZZs?aJ(^eNMKY(m!j|kB^&1*?xHoD zh_G+)lHuVJo4~1`mixTEAMrI))JokqI8T&Wp?l5O;Z`SB$by{?=u%WBeiubbw7$dS z#eOUuH9f|GY}4pl&Oe)91AUGWLlW=_rMy{j$muc)PbsRQ)Xb>f@&~IhbzpBR*@wyJ z#y}WMvxv}!m}W0>JW)&}3GMo1zVQX0RjJwZ5?_2$$n5eh8H%=w>hYjif5u77cTJBS z*fPdj&FK!$Lgine%X*qr6fbm6?7Wt5+r3!{($?hSp*)FHk-0;guHX`pW#qeaXSN_K*& z7D@hsv(v`kkNT#Vs1jAl-SE=P%+V6{bagT`p0PvD@pza|s3(Bm^U~6s>NHN8R1M`M zvV>lQ1nA9TT4k<8&VmZK>>kr$QO*C9TNmZ~ldRL|ZF5PNkrMvJw>eV!AInym{hdxXL=+XsT`K?cKl_aWg7E!RT2hpDiw^Z+o_5< zZYfGttvK(IR27VPPBfJqq{x@0J{?2lC!k3gI`hERug+q3i){;>@}0@`#KH`Jf1v>8 z^5l~1fXO(oqWO$sQFWzW0@E`(n;Tf`&SSLsR5EA*Ud(0b=)WP0z%k_ZZRB?vsS4^i(H@eXGy|*kK2FJ@LxcYuPs$a6^3I(5>zjTR2`d13%QGmG)a`pNH1Scla1og0d92{$X2t}6Oot=P?jW}il2VDR1N%X+EQ)YZ`mm@ zle&s8&(HFhdN+O$Q#8&8(Mv?MiXG)kGKHw2XYxt`5ZeN%1S4WWE4Ma4Ti7|W4(i0q zv|P=vpehas>-PH$cMBKBY|Md#d5&d{;)Ir*o!!ZRd6mSRA(sT9z}yHZzsL^ zf^SHEu)f#=`pfiLH-BwZKw=~q>>ywQe|w94Tprx*iL%kq24&)Qb?$jj37B{tdFvCa zD0D~)U^J?BY#wZOsH!U*DIf^h+JCk*(szyoRb+NG>;r=m*=?Si$R8Mi$qH`O^9kVT zA5g`+X0)79zM!1e&XyE9hNrp){ZHF5p?cv@exK$)^r6_VK$J0hpgySj

6A1@$qC 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

6)CDi&Dfdf9a)nwad!2Jv#*zCtV4wBYA}5 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/~{*2lbph8k;GB56C58{MBKFH077i`8cF#G1;P45* zzyC^E*(}5-ZHE|(oBHZQz#9>siRFCesSdv(ry$Asyug`0;;fY4AO(GHE5>X)l30?{ zl9XL1vs>3@o6N9`({w#KSD^Wu@`~kDS8lx;NV?YvD6sn7ie6{^(}FIETU%*m#0PX@ zEIHP!Snkw&fdwOLy z|1H9p@%x{@i|^kL(ZEy1dJ+yDN*!!MB^`QURFLSLlXcxC{FzJ_F46u-#`(0#7E`U^ z#hpl0XO2z%!I5#1VXy6BPOm-?fFOON1CUR^Yp{_@>Vb?0eiew%$Cp(NKFUtnBZ58_ zp1xiL8+=iD9+c=D**?5Ag`wuQ%XaqroBV!gRzj9};ZYJih=REC>mNRAN<{K4PyHF) zByu3GQz-Dk6}rJz*V_}l-Mkg5@bl$sE(isV8K_&Q0!4mc zf<4?`%{BNRJ_PVok{b=zD9x}a1P>2{jMT(SRAA50);Fax3-X(lirPggde0vxMekG_ zQsAA_$O+QVI6^V!s`sVx_exGA74V)CX4lmPP^1~x=CFx6q~|(VI@)vmQE7ad6)Y>B z#u4p0M<^6UP;N>`97%964oWUl56eJ}ptHFLS20M>MGaGX;@fVkiJ)9=L%bI;&UdV~ zO+`>x%cD-d@{OgbhwRyHpbx8FsBLgM7jCKX+4aE-v0emkb7zZ;ID}_dViMLCfyz)I7+6ty2vf{#sZ_Pp_`9CYJdJ1U8rifFCp>G-V zC>0dZ8~F-ICt!1+v1Vrb4k@4*z6P~Ql6q%oup!DC=#)#F*1jm1c{#D0^fG;>r36nV zX7y&2)4!iMkTZCu-PHQ@LTDGqVh zOYCSIDkPaQ^5RRn2narm}el{+@&`?4jBZIY{qG5m%v zK?qh1>1zgB)PP)}wU>s>o4+jT@4*3UlyCg*i{Dt+~|km#V5K*@#qz zipWtFyyd1Sr@n05w~Tnn;2Ci!ch(=+6+|{(0_kZ~(5k%LY*VkES{_sx>4a%J_mo_) zIT1Diy<~dnh9-o1V%_d@iPZod} zuVxTD95Il!B8yFzWy~Z*nTdAh=Y29$$ngX()$&z^Vq|Z$uqBqDtiihkUiX~m0Yuqz zP+?`_(CJXOaN@o+;t|mlLlZx*q3lB_I+8YycLxtnFZXj)GAto!owqh#!@zwB(EB1w zP9K4M`VMPt7;4UEKr5s}4@zz>8%@D6{7y(4Z9o;Lyf&;$1D}%pPDnr+v+vG;N(!%A z1Dk{nAhcNQKn@OQ3UrS%C8*ZxW!H}RtJgn7&V((nIAFonQ1#RzzBE#uho>?g!XE%l zDsA8%Dp6Rg5xv6ZqxIk=Hs_Ikjn%4W@H{Rm-Cwi!%v_PY6?2?iKzouz7ZE2sm^GDU z=iAnY(XKCK*q@}uJ{w>P@!#*q={HZUC!ov})L^S!_s8YoZjLEUC|4!ye6qnD9!m^Z zsZo5Azi{f( z67G(UkWZ%|26c)T<_TOIYK|+0Daq%Nj8V#_F6!>BSliw5+NPJhjNJY*ZdDf34Oc^D zWCVH13ch*Ge!Js$a3ex5Sgb}pc~zbqCG9u_b^#1a{Do0!4oGTOHq7-VIawCxJd%Zc z)KzI|2r3?XM=f%z<~)91m2|8BAtb2x!jUmOdEn!MYodoug4pSh<5~qjUg&$VvQ{Ni-rbMRh$?bz=^{}{syQ8$1b95IL8Bq{@W=7=qV-djH{8H zQKA~X2kzJu21y4j|L zjzL!yF#-w-Gc;B#$* zepaYTuqstUR!n7j9yh6$TVSR&(?F&cKwCCoSA;y>Fr?p+OSmPt#dpkMdhf(bTs4c{ zn{t3lBn6pda=t}|B=Uxn9ElVmtDxMoUKc2yIR!}DIAa_)y01S6#cfq?rJZh`I+Y<) zYAbHJn~ktedhP#kT*$21r7i21;Q-d6`rBl48WS`IToau|RA{bs({826^Od1!slP|+ zl_rpkjiC0p7JX$SId^gA6!{5@UGVTK#TLg<08fD9!q;%2!#Q+=YZ?-x-z{8u)s~~Y zN1eKF!DTpQQfNRo#&d17PaQ#b*3O#2TZR`}UZ99FCe%5!p5EotFsiKW^Zg-47-Had%UE zN*C%IzMVKxZ}T* zm><)lbF5@pckb8)q7#z0ps<|0Se|IY*~hP(!18m&tCfG1ib28YJpT4}1br{2NMk+v z39CTg0;h>hHP5koO$AIYXcOKgu+Vs{YVZbhi@aoLTlKB5dN9Y$Bqz=(Ux1O@qE2CDZD?y%P8@~Pa)Mjcc`6H;&}=)PKK6E0e#W=H zclmOQP-P>%i5w!~n1r3nAm<|HqPCmVAE90DHL6Qk!0di z4msbtvgASG5@-jQyyrwgs;1W$3xW8wUfh;_#8_}-&i3)$XKZd1?epXdnM%9}f{M-( z7hBN^hn!-Q6{oz0!NAb%&yn^A?MWUMhJ0MwM{lSNaf`IJ$Wscw6?oM64n=*mTM9}I z>$ia4iG!b0sCl)Pte|1)tBat%vH~l))PnJY2)A_~^Jsba5Xn$wG(2earYoo*Wr`2$ zJ+Udv3A61Hc|?J3*N17i{CKnc`2F_$mkZ)goUtsPOhr^8C&Q;Cm7oz!Jp=jkJfZC- zSBA@fjuX)P{OYEPmPxdaM_wDNW{<3ZL;Oec1{jbbdf`)Flg5kCs>p%v&F~quyL75Rn(%msI4r`Cw4GS7g?`wO!#j&6W$;$ntoazus0=PgzK#SH{5uEYU(LL zaeTVu{s>gKjy;mP&5mes4u7#B9E zYZW#q_h}<>qtq+6@bxdNquqmJ>aWzY@%|`e!G9BVXSc6;49@nmczVT_b>IuTjM9_z z=xXbSr4xgMI-81SA*@u8pw}K$(*$QwrPNCrAu^%HWHXyZBw$cM>!glYU_jCO;9XD~ znV|L?R+?R@?yGm}Fl1`nq@Un2C_Jdx&0qO8piHyvzS!f?<>_dKF}N2(IB7W-jcK%d z9%B+hhyI*187#48FZIHiCb^GJLB_!WODBN_iSrh2QRv%r{E*xKOT+xZ6AWQ z;8bRLZ-*1#-fdzWVVL)vzE$SByx|x*Ss{dq;p=c|PH#Ql{2G>xZUCA{8?%w9xy*t+ zlC7KGd$!Vbkn46;WU&!zZce+ClRU=J)xMr>4K_kmL2MV0=M!zuYVMd|(3Nc>bu~J$ z3GtqGUdhdXQ$H6v8Ic?Rs2MRSt06taqPu#KzEaqhf$3Q1f*Z4wk%#DFQA=Z(4jn#w zrgP90v@WiJV2LU>YunGnOi2AO*jZza|&UDeT!UMF7%;*ZVDYxTy!tqAVC!9Kx zKP^x!#GmCP?JJily>^;_x44=7EH|8tdj(ftPpzDQut)K=aF}V%CYD2h11jt-eg8P9 z`DTCJwf=fZ-KXJTqP*1gdS(z`j_b1SLcah0*sK(C<0-$kaBIAj`06g<(64b}xc>e9 z0tl=achV>~Q`ml&U)890eRQtOwd=>7H}c1!cLze6TW;k9Dll{;{atqEy*8mSIzMc2$gDkN7GBtc#OTViEDCV|!8YZ5W3b z?-g8Y^m-<7u>r+bGq0CdJUWii*(|!3v@amswtw6PRhb-Gbgx6z%U;_WUX&fT!>jT- zIwOqoG;E+QmmW+?so%8arIQ2)sat=R_Ff`Zbw(+PQf;}kZy3%57DdQGSgT@-;Co_v z)&qhZZF4Aj`+2RM2Tn2ZYWwWxTP8n!f7wpun|RWLfmgp_9oo&+$NYS3_S4rbOA8qS zj?Wm_aiwo;c}{qiJVTxcaxmkSykPhacZi@t`nY?Ox+~#6?=l%i=UXDH5fJ5a8q}vS z_dTjrVpeGpr@?@M4CVtn0Qx-eDMP&PpP3}A#FejXnY|c|-xt!$JR0q*- zGI69)4~pkyv2z8l3h-mBf<JmoO%8gQlE+WZgulC>f7?=i zb_{|~6GVqJ{DF>3pey0cjPgxdo`RME=o&b`<-I|XP%o#EsY`UhTH1N~9V4xk^L-Xv zhcBW1QSJa^mm;BSC+w>E*(gDrO3}vSQw`LNs3sqW<6QVNC39S;)o1M;*wH-jYl-V7 z33bh}n0;k!9!D;Vx_vn-#_hG-v&XmG5xs-#UX#+i(bdRocpNV!j<=VBr7h-EexMR& z#OZIn4)_>!nEm98!SN<#L)$m?BjdL<+N_%L^Ep;Sjt!rh7VW+#E?1WsZ!f36dEOn$ zE|`jKw&tfAbuQ%2j7&67tZZAXdw+F_HhV7`#F`jic=e>410_b_aHDx<#aRy`Kc$ILX_uPv~6aUYeGl_Yj?t1Qjtk_}90)@1k@% zpIxVN>d5Z7ojG+B5{&Z|3=c7J=9Mr7jcWw;YbMs)R89X7J26Xf;$s{bSUB@Odb<)I(DmXsx^RA{h0D~!4uPkdrA{64L01$)MiSirmdEAx#Jyt#jC?L z4C*T7if?5f-b5C*pCpETmU+|pK_kAK)JQh#vrLiJ>hQ91DpwZ|S!RsO5 z6cZa+9AzypkS4DldLo->y@L1yLx42P>yZT>ZsVSbtW|I)1?n);oKnrBxDRNPkF1Yx~$bj1b?8@VC!5(Tkl-|$H`y_s#ow&f6PEIz63pyh@V zaQ19(Y0NPQmXE$yq%4*RN`!Fau{<6yRluvCpmpW#?`FtNSLbp{3j}*U%F?B}*^1bg zJYMe6%;lWy~A{D_*|u$haxlR z>$u;G*Ix~*&OY9b)QOLsE9=`~oGd<}IP;f|swip=a)D^Xf5LAiMGh!kK*dN}$C5VQ zx{1^UqGfh$ix?KDVP2F~243&>Yc-~t;pG;)vdHN-QXkDU9z@^3E-zq=O)K+D-fq4t zVG6WoEIcuDF}>YRoN4O77_YtaInAG~P=l6QjyOh|DV{IE+)!@UfJayhk0tBC8u=5* zdAdKmY$#IHYjhLXNz(UW=APV5i)}Y$G}%$VSib_DI6BYUHYA8t=I?GH8KbS8Q`((= zh2Io2t`!Ze#)+)83_GOUa9drgw-9&C+L** z9Iai}6KHoe+8}e#Qa518FK6`D2AX-A)wa1S9)2hOoPqhx&vnXg?lJZzAxEkHl*sk? z*9JF>#^6f)SjbE{;+^4Ax~`RB5Q5p@mp&fHI}+`U9Zrl581K7+5n}Fm zgpVD}1qkSk@2XdbK2yi0t-Y>i(J1tjx$E}Z_*$9?dCbsOm8S~s2u-J2u>RhUr|_LU z8H?(NNa#Yz#txF7>e0!w3uehXdWPpEeslz(#OtO?;TD+JUG1<4Nhm7ypyW$suD7(? zo4n9Bw{YDA$>)z;ybmx|2-=u@#g@j6`gsyl{@zUi|9~_#2OKqF;?%kIx~YN&30F{#l$8Ur zvi&IqHggaX7@NG|g2w!Iar0efNQ*Zl}$i=zzd$1~*V(X2(2h?1#ICUp;|A z35t8ZEqzl}!PI=AaS_T*0P@npp)T%xem83!ZJFHyoZH61nJUh7wXu7x#&sZ)30U(M zC-G3>#=rAzP)9)Rcqv??P3Pepd7|RraOQZWmuVRM>RRT2DW?BX6Ru^DXi>iR+WL6u zhg%HBueVJfUZ1qs6@pFi$P<+?4jm`Ds=@HeEB@DVMf~HnH!$q7C91W*6U0rkE%}}HG zms|7)#Jz1`EwC|)>V5HJRTs5t&tg&)O-kB&l6p1bfJi#e=pRjyYV@rz>WPA|7~GK} za?WQxne1QLU3}eDzFTFHR%MM`7{+G=zPq9c3VBa2K>6}UOP;g!Oj~5Yb;+%Y%;?2% zihLF<_PRyz*Pv9C)?RT(LK2ok)KThBn`A;aua8q8TZOJ}3#8~$61{ds&5@U(YV`Fd zo?*R=PDpAN;ZBDL7^FVp-wS7pH@5H)=sGPfKcF0EF&hTg@$OwpZ2EP=9JMW}`n@0* z5bfseiMGHqZ_ZIV-=NJ+4561Q;l`!+b*qMyO6oVCG}eE z=G;kDe)vR%1M3_j2US|Fl8z%0iUq5WS`&M$s!LnzrfPVycyD;cV8;0wUT+S^#+V zYRG$>C>OujM`i7rJ2As{vm8#z_%s8YLViwB;ka;$#b0>w?1;FKFjF4hXuQrt;TU@A zgsxU?20oH`xzN~Er_!pf;K+S@lF2g0O103r-ta^hwyeT83~ExM;!b5k{mkKNXgN_H1AESX<0!7t3&y;)rM;$&&rW?9}?=w&FF# zHnb~tb)!_bKXrJu$f`J)!EDxjzO>_}$_B}`W4N~hPfdH(P_-Vujy)$CB+Y>89-qIB zl4p4A#*n973qu^Z0_xgk+GA53xpFa9aav5en^p}v#|5>jS&St*g3=o+#J1D~#p4|} zyUFT}pw0}%RMo^=!~%h(r|S1Ju7m2X_xrBY1nxk)oCUPYXVP)wV8;<`k|;`gTC;|E z1i3Mrj^vc%a9JBj`PSaC+?>Ne&UDDS_%|{dL$rRHbl4WpH44VV zL&O_96y?KG-!?c>Yj}gr-lp(Ng!osBv4!!huxm5(st=` zWE=v`*0;DML;ocBU4!HxQH2}(sY+SR zckC)r?CPgDRVt+uA=H*IRC88$SX85MRK4#mzqCcL_ot_K3dHs@)Hg*7x_4;eBPM%Z zv%lRt+*mA8cW8PtNZi|wGyG(LIDt4)hm1;v-Xu&qFK7wp1kt@T1Oxuh!TD|N<>-&Zx;aqh0ZoYb0Z_d#6% z?{qvHm)Gu2RcR5I$1LPXfe1z_I6TEyc0Mgm?@CZ`S+ghA$5r$y;5ysE@}9s~_JF(- z;TbdYWe?2MA5-ljkDX3JcMPxB$!Q(yR!R3ER6k7oo1)Y zLk^HQ^f(|#0qn(?wwgRF*n^_xBQsFXdpCKB3{)t;qVC6kD7SztQpry}zA#faI@87@#iF8~D6lj;Wo%7%yYA!B8fkex(&y=yf z6t@*1&eGZODE1AA0$X{-kr+LQqa1y$I>zF9Tzh-g!AP}sFwfg8!wG(BfT$P5rQ66= zhCa|%aoagwe%n?U7`}FG zav(rvKi-c3x-FF(V$()rrzLkfxnSQX9E>`Cl)u4Z ztjqpcJ*Mh5J;3#3l*Ej~0;Smk-;4BJ?P*_!DOc&?OxL2stg{iSH|hrJ#Vy!xSmvk@Qrl7K0DyBFrQ1jzpWnZ2GnF0D3hXbTjw zGH4R+E_4J&t|dhNpc%|(`V^-dZV2UtwDpTbPUHbFavmpD7mNx2HM2DW#1j^AVbUAY|42{{=+^y8C9iFf&}jX+3O^2}v&ZD6zxX6%e}4L!l6p%QZ?(LKr0T z503g}Vxdo~Ue%zOdgKvPe45@xg^cnO&*jx+tVabsxEk=u;IFalT&?owf#m8VpP&bh zpo>1W^_7K?1<8@%GLIvRyT=sv%(ddBS)UBN<}S_UnA-W$(p;zw+h18T{-UX^XZWK> zp4s`z(!0p8^WzenGY=`%02&xKf_n0b zmrW}Ep>oo{#)qhJ4; zhofRKKg_GXGog*SXu`L7Q+mEVeDr;|`9z-CV6E^=5i_<*?zQJU(x35N>)T*{SD4Qw zZ1`rA*ZC%w$ca3&hz}1@?G^dP`PTJ)W;e9n-%=;F5?kx%)}C>SvDQW3P(A%=9`v}) zQm<;1td&QX)}(9axpgz=9n5|AjjtTKI9EINzqU5Ve+>`4^^N28i0i)bwc`c(cCwD0 zH@>lUd^!)lMgOg*=V92h=f#(gV&+&QJtjL2o;$tbdBBG6r-yU6lk>1pmv}uMyFkzW zmo`8xqr{p%_=}yp`B(70oxA;mojdr>&fNUYPDy_2&&a<8-`RO^_SW}y61&NR?``@9 z_6I-MnH%5P^zL75dhdJghwp3{jP3p4Fd`nD5Z(TZjqQBr$+o|lqeW24B2**~IV z*b2j|&ux^wqgb+YI{0zy6k`H9wvG-sJNEE6IfmJz!|cl;_NO3zL}T{xD0^&d{VN+r zKFGcm9pH`|Vc(Czk76^-SX3B-AI5G3UUtLW8N=Km1KeN3{Kus9o{fhg?zWz5cdcdq zj-@VrV)2=eEW)EObpEDA&);%#_@B|vo|bx;g+Q?-b8j_k@Gh!cy8Z9 zGY9zHaO2RK8y3J$dLepd-x7?4ID875BtDKOc655j!qb};JGpJ~=?#lat@H3)w*Ljz WFH2+MFc!=J0000}oe(WbFc@7VdX3(D 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 literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Features/Autofilters/images/04-05-topten-autofilter-2.png b/Documentation/markdown/Features/Autofilters/images/04-05-topten-autofilter-2.png new file mode 100644 index 0000000000000000000000000000000000000000..4db5125210ea59f29cb75ea60560e96286da0f72 GIT binary patch literal 22842 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 SU%${l{s*e0saOuN2>u_Pw-LPn literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Functions/FunctionListByCategory.md b/Documentation/markdown/Functions/FunctionListByCategory.md new file mode 100644 index 000000000..cdd39f095 --- /dev/null +++ b/Documentation/markdown/Functions/FunctionListByCategory.md @@ -0,0 +1,410 @@ +## CATEGORY_CUBE + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + CUBEKPIMEMBER | *** Not yet Implemented + CUBEMEMBER | *** Not yet Implemented + CUBEMEMBERPROPERTY | *** Not yet Implemented + CUBERANKEDMEMBER | *** Not yet Implemented + CUBESET | *** Not yet Implemented + CUBESETCOUNT | *** Not yet Implemented + CUBEVALUE | *** Not yet Implemented + +## CATEGORY_DATABASE + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + DAVERAGE | PHPExcel_Calculation_Database::DAVERAGE + DCOUNT | PHPExcel_Calculation_Database::DCOUNT + DCOUNTA | PHPExcel_Calculation_Database::DCOUNTA + DGET | PHPExcel_Calculation_Database::DGET + DMAX | PHPExcel_Calculation_Database::DMAX + DMIN | PHPExcel_Calculation_Database::DMIN + DPRODUCT | PHPExcel_Calculation_Database::DPRODUCT + DSTDEV | PHPExcel_Calculation_Database::DSTDEV + DSTDEVP | PHPExcel_Calculation_Database::DSTDEVP + DSUM | PHPExcel_Calculation_Database::DSUM + DVAR | PHPExcel_Calculation_Database::DVAR + DVARP | PHPExcel_Calculation_Database::DVARP + +## CATEGORY_DATE_AND_TIME + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + DATE | PHPExcel_Calculation_DateTime::DATE + DATEDIF | PHPExcel_Calculation_DateTime::DATEDIF + DATEVALUE | PHPExcel_Calculation_DateTime::DATEVALUE + DAY | PHPExcel_Calculation_DateTime::DAYOFMONTH + DAYS360 | PHPExcel_Calculation_DateTime::DAYS360 + EDATE | PHPExcel_Calculation_DateTime::EDATE + EOMONTH | PHPExcel_Calculation_DateTime::EOMONTH + HOUR | PHPExcel_Calculation_DateTime::HOUROFDAY + MINUTE | PHPExcel_Calculation_DateTime::MINUTEOFHOUR + MONTH | PHPExcel_Calculation_DateTime::MONTHOFYEAR + NETWORKDAYS | PHPExcel_Calculation_DateTime::NETWORKDAYS + NOW | PHPExcel_Calculation_DateTime::DATETIMENOW + SECOND | PHPExcel_Calculation_DateTime::SECONDOFMINUTE + TIME | PHPExcel_Calculation_DateTime::TIME + TIMEVALUE | PHPExcel_Calculation_DateTime::TIMEVALUE + TODAY | PHPExcel_Calculation_DateTime::DATENOW + WEEKDAY | PHPExcel_Calculation_DateTime::DAYOFWEEK + WEEKNUM | PHPExcel_Calculation_DateTime::WEEKOFYEAR + WORKDAY | PHPExcel_Calculation_DateTime::WORKDAY + YEAR | PHPExcel_Calculation_DateTime::YEAR + YEARFRAC | PHPExcel_Calculation_DateTime::YEARFRAC + +## CATEGORY_ENGINEERING + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + BESSELI | PHPExcel_Calculation_Engineering::BESSELI + BESSELJ | PHPExcel_Calculation_Engineering::BESSELJ + BESSELK | PHPExcel_Calculation_Engineering::BESSELK + BESSELY | PHPExcel_Calculation_Engineering::BESSELY + BIN2DEC | PHPExcel_Calculation_Engineering::BINTODEC + BIN2HEX | PHPExcel_Calculation_Engineering::BINTOHEX + BIN2OCT | PHPExcel_Calculation_Engineering::BINTOOCT + COMPLEX | PHPExcel_Calculation_Engineering::COMPLEX + CONVERT | PHPExcel_Calculation_Engineering::CONVERTUOM + DEC2BIN | PHPExcel_Calculation_Engineering::DECTOBIN + DEC2HEX | PHPExcel_Calculation_Engineering::DECTOHEX + DEC2OCT | PHPExcel_Calculation_Engineering::DECTOOCT + DELTA | PHPExcel_Calculation_Engineering::DELTA + ERF | PHPExcel_Calculation_Engineering::ERF + ERFC | PHPExcel_Calculation_Engineering::ERFC + GESTEP | PHPExcel_Calculation_Engineering::GESTEP + HEX2BIN | PHPExcel_Calculation_Engineering::HEXTOBIN + HEX2DEC | PHPExcel_Calculation_Engineering::HEXTODEC + HEX2OCT | PHPExcel_Calculation_Engineering::HEXTOOCT + IMABS | PHPExcel_Calculation_Engineering::IMABS + IMAGINARY | PHPExcel_Calculation_Engineering::IMAGINARY + IMARGUMENT | PHPExcel_Calculation_Engineering::IMARGUMENT + IMCONJUGATE | PHPExcel_Calculation_Engineering::IMCONJUGATE + IMCOS | PHPExcel_Calculation_Engineering::IMCOS + IMDIV | PHPExcel_Calculation_Engineering::IMDIV + IMEXP | PHPExcel_Calculation_Engineering::IMEXP + IMLN | PHPExcel_Calculation_Engineering::IMLN + IMLOG10 | PHPExcel_Calculation_Engineering::IMLOG10 + IMLOG2 | PHPExcel_Calculation_Engineering::IMLOG2 + IMPOWER | PHPExcel_Calculation_Engineering::IMPOWER + IMPRODUCT | PHPExcel_Calculation_Engineering::IMPRODUCT + IMREAL | PHPExcel_Calculation_Engineering::IMREAL + IMSIN | PHPExcel_Calculation_Engineering::IMSIN + IMSQRT | PHPExcel_Calculation_Engineering::IMSQRT + IMSUB | PHPExcel_Calculation_Engineering::IMSUB + IMSUM | PHPExcel_Calculation_Engineering::IMSUM + OCT2BIN | PHPExcel_Calculation_Engineering::OCTTOBIN + OCT2DEC | PHPExcel_Calculation_Engineering::OCTTODEC + OCT2HEX | PHPExcel_Calculation_Engineering::OCTTOHEX + +## CATEGORY_FINANCIAL + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + ACCRINT | PHPExcel_Calculation_Financial::ACCRINT + ACCRINTM | PHPExcel_Calculation_Financial::ACCRINTM + AMORDEGRC | PHPExcel_Calculation_Financial::AMORDEGRC + AMORLINC | PHPExcel_Calculation_Financial::AMORLINC + COUPDAYBS | PHPExcel_Calculation_Financial::COUPDAYBS + COUPDAYS | PHPExcel_Calculation_Financial::COUPDAYS + COUPDAYSNC | PHPExcel_Calculation_Financial::COUPDAYSNC + COUPNCD | PHPExcel_Calculation_Financial::COUPNCD + COUPNUM | PHPExcel_Calculation_Financial::COUPNUM + COUPPCD | PHPExcel_Calculation_Financial::COUPPCD + CUMIPMT | PHPExcel_Calculation_Financial::CUMIPMT + CUMPRINC | PHPExcel_Calculation_Financial::CUMPRINC + DB | PHPExcel_Calculation_Financial::DB + DDB | PHPExcel_Calculation_Financial::DDB + DISC | PHPExcel_Calculation_Financial::DISC + DOLLARDE | PHPExcel_Calculation_Financial::DOLLARDE + DOLLARFR | PHPExcel_Calculation_Financial::DOLLARFR + DURATION | *** Not yet Implemented + EFFECT | PHPExcel_Calculation_Financial::EFFECT + FV | PHPExcel_Calculation_Financial::FV + FVSCHEDULE | PHPExcel_Calculation_Financial::FVSCHEDULE + INTRATE | PHPExcel_Calculation_Financial::INTRATE + IPMT | PHPExcel_Calculation_Financial::IPMT + IRR | PHPExcel_Calculation_Financial::IRR + ISPMT | PHPExcel_Calculation_Financial::ISPMT + MDURATION | *** Not yet Implemented + MIRR | PHPExcel_Calculation_Financial::MIRR + NOMINAL | PHPExcel_Calculation_Financial::NOMINAL + NPER | PHPExcel_Calculation_Financial::NPER + NPV | PHPExcel_Calculation_Financial::NPV + ODDFPRICE | *** Not yet Implemented + ODDFYIELD | *** Not yet Implemented + ODDLPRICE | *** Not yet Implemented + ODDLYIELD | *** Not yet Implemented + PMT | PHPExcel_Calculation_Financial::PMT + PPMT | PHPExcel_Calculation_Financial::PPMT + PRICE | PHPExcel_Calculation_Financial::PRICE + PRICEDISC | PHPExcel_Calculation_Financial::PRICEDISC + PRICEMAT | PHPExcel_Calculation_Financial::PRICEMAT + PV | PHPExcel_Calculation_Financial::PV + RATE | PHPExcel_Calculation_Financial::RATE + RECEIVED | PHPExcel_Calculation_Financial::RECEIVED + SLN | PHPExcel_Calculation_Financial::SLN + SYD | PHPExcel_Calculation_Financial::SYD + TBILLEQ | PHPExcel_Calculation_Financial::TBILLEQ + TBILLPRICE | PHPExcel_Calculation_Financial::TBILLPRICE + TBILLYIELD | PHPExcel_Calculation_Financial::TBILLYIELD + USDOLLAR | *** Not yet Implemented + VDB | *** Not yet Implemented + XIRR | PHPExcel_Calculation_Financial::XIRR + XNPV | PHPExcel_Calculation_Financial::XNPV + YIELD | *** Not yet Implemented + YIELDDISC | PHPExcel_Calculation_Financial::YIELDDISC + YIELDMAT | PHPExcel_Calculation_Financial::YIELDMAT + +## CATEGORY_INFORMATION + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + CELL *** Not yet Implemented + ERROR.TYPE PHPExcel_Calculation_Functions::ERROR_TYPE + INFO *** Not yet Implemented + ISBLANK PHPExcel_Calculation_Functions::IS_BLANK + ISERR PHPExcel_Calculation_Functions::IS_ERR + ISERROR PHPExcel_Calculation_Functions::IS_ERROR + ISEVEN PHPExcel_Calculation_Functions::IS_EVEN + ISLOGICAL PHPExcel_Calculation_Functions::IS_LOGICAL + ISNA PHPExcel_Calculation_Functions::IS_NA + ISNONTEXT PHPExcel_Calculation_Functions::IS_NONTEXT + ISNUMBER PHPExcel_Calculation_Functions::IS_NUMBER + ISODD PHPExcel_Calculation_Functions::IS_ODD + ISREF *** Not yet Implemented + ISTEXT PHPExcel_Calculation_Functions::IS_TEXT + N PHPExcel_Calculation_Functions::N + NA PHPExcel_Calculation_Functions::NA + TYPE PHPExcel_Calculation_Functions::TYPE + VERSION PHPExcel_Calculation_Functions::VERSION + +## CATEGORY_LOGICAL + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + AND PHPExcel_Calculation_Logical::LOGICAL_AND + FALSE PHPExcel_Calculation_Logical::FALSE + IF PHPExcel_Calculation_Logical::STATEMENT_IF + IFERROR PHPExcel_Calculation_Logical::IFERROR + NOT PHPExcel_Calculation_Logical::NOT + OR PHPExcel_Calculation_Logical::LOGICAL_OR + TRUE PHPExcel_Calculation_Logical::TRUE + +## CATEGORY_LOOKUP_AND_REFERENCE + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + ADDRESS PHPExcel_Calculation_LookupRef::CELL_ADDRESS + AREAS *** Not yet Implemented + CHOOSE PHPExcel_Calculation_LookupRef::CHOOSE + COLUMN PHPExcel_Calculation_LookupRef::COLUMN + COLUMNS PHPExcel_Calculation_LookupRef::COLUMNS + GETPIVOTDATA *** Not yet Implemented + HLOOKUP *** Not yet Implemented + HYPERLINK PHPExcel_Calculation_LookupRef::HYPERLINK + INDEX PHPExcel_Calculation_LookupRef::INDEX + INDIRECT PHPExcel_Calculation_LookupRef::INDIRECT + LOOKUP PHPExcel_Calculation_LookupRef::LOOKUP + MATCH PHPExcel_Calculation_LookupRef::MATCH + OFFSET PHPExcel_Calculation_LookupRef::OFFSET + ROW PHPExcel_Calculation_LookupRef::ROW + ROWS PHPExcel_Calculation_LookupRef::ROWS + RTD *** Not yet Implemented + TRANSPOSE PHPExcel_Calculation_LookupRef::TRANSPOSE + VLOOKUP PHPExcel_Calculation_LookupRef::VLOOKUP + +## CATEGORY_MATH_AND_TRIG + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + ABS abs + ACOS acos + ACOSH acosh + ASIN asin + ASINH asinh + ATAN atan + ATAN2 PHPExcel_Calculation_MathTrig::REVERSE_ATAN2 + ATANH atanh + CEILING PHPExcel_Calculation_MathTrig::CEILING + COMBIN PHPExcel_Calculation_MathTrig::COMBIN + COS cos + COSH cosh + DEGREES rad2deg + EVEN PHPExcel_Calculation_MathTrig::EVEN + EXP exp + FACT PHPExcel_Calculation_MathTrig::FACT + FACTDOUBLE PHPExcel_Calculation_MathTrig::FACTDOUBLE + FLOOR PHPExcel_Calculation_MathTrig::FLOOR + GCD PHPExcel_Calculation_MathTrig::GCD + INT PHPExcel_Calculation_MathTrig::INT + LCM PHPExcel_Calculation_MathTrig::LCM + LN log + LOG PHPExcel_Calculation_MathTrig::LOG_BASE + LOG10 log10 + MDETERM PHPExcel_Calculation_MathTrig::MDETERM + MINVERSE PHPExcel_Calculation_MathTrig::MINVERSE + MMULT PHPExcel_Calculation_MathTrig::MMULT + MOD PHPExcel_Calculation_MathTrig::MOD + MROUND PHPExcel_Calculation_MathTrig::MROUND + MULTINOMIAL PHPExcel_Calculation_MathTrig::MULTINOMIAL + ODD PHPExcel_Calculation_MathTrig::ODD + PI pi + POWER PHPExcel_Calculation_MathTrig::POWER + PRODUCT PHPExcel_Calculation_MathTrig::PRODUCT + QUOTIENT PHPExcel_Calculation_MathTrig::QUOTIENT + RADIANS deg2rad + RAND PHPExcel_Calculation_MathTrig::RAND + RANDBETWEEN PHPExcel_Calculation_MathTrig::RAND + ROMAN PHPExcel_Calculation_MathTrig::ROMAN + ROUND round + ROUNDDOWN PHPExcel_Calculation_MathTrig::ROUNDDOWN + ROUNDUP PHPExcel_Calculation_MathTrig::ROUNDUP + SERIESSUM PHPExcel_Calculation_MathTrig::SERIESSUM + SIGN PHPExcel_Calculation_MathTrig::SIGN + SIN sin + SINH sinh + SQRT sqrt + SQRTPI PHPExcel_Calculation_MathTrig::SQRTPI + SUBTOTAL PHPExcel_Calculation_MathTrig::SUBTOTAL + SUM PHPExcel_Calculation_MathTrig::SUM + SUMIF PHPExcel_Calculation_MathTrig::SUMIF + SUMIFS *** Not yet Implemented + SUMPRODUCT PHPExcel_Calculation_MathTrig::SUMPRODUCT + SUMSQ PHPExcel_Calculation_MathTrig::SUMSQ + SUMX2MY2 PHPExcel_Calculation_MathTrig::SUMX2MY2 + SUMX2PY2 PHPExcel_Calculation_MathTrig::SUMX2PY2 + SUMXMY2 PHPExcel_Calculation_MathTrig::SUMXMY2 + TAN tan + TANH tanh + TRUNC PHPExcel_Calculation_MathTrig::TRUNC + +## CATEGORY_STATISTICAL + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + AVEDEV PHPExcel_Calculation_Statistical::AVEDEV + AVERAGE PHPExcel_Calculation_Statistical::AVERAGE + AVERAGEA PHPExcel_Calculation_Statistical::AVERAGEA + AVERAGEIF PHPExcel_Calculation_Statistical::AVERAGEIF + AVERAGEIFS *** Not yet Implemented + BETADIST PHPExcel_Calculation_Statistical::BETADIST + BETAINV PHPExcel_Calculation_Statistical::BETAINV + BINOMDIST PHPExcel_Calculation_Statistical::BINOMDIST + CHIDIST PHPExcel_Calculation_Statistical::CHIDIST + CHIINV PHPExcel_Calculation_Statistical::CHIINV + CHITEST *** Not yet Implemented + CONFIDENCE PHPExcel_Calculation_Statistical::CONFIDENCE + CORREL PHPExcel_Calculation_Statistical::CORREL + COUNT PHPExcel_Calculation_Statistical::COUNT + COUNTA PHPExcel_Calculation_Statistical::COUNTA + COUNTBLANK PHPExcel_Calculation_Statistical::COUNTBLANK + COUNTIF PHPExcel_Calculation_Statistical::COUNTIF + COUNTIFS *** Not yet Implemented + COVAR PHPExcel_Calculation_Statistical::COVAR + CRITBINOM PHPExcel_Calculation_Statistical::CRITBINOM + DEVSQ PHPExcel_Calculation_Statistical::DEVSQ + EXPONDIST PHPExcel_Calculation_Statistical::EXPONDIST + FDIST *** Not yet Implemented + FINV *** Not yet Implemented + FISHER PHPExcel_Calculation_Statistical::FISHER + FISHERINV PHPExcel_Calculation_Statistical::FISHERINV + FORECAST PHPExcel_Calculation_Statistical::FORECAST + FREQUENCY *** Not yet Implemented + FTEST *** Not yet Implemented + GAMMADIST PHPExcel_Calculation_Statistical::GAMMADIST + GAMMAINV PHPExcel_Calculation_Statistical::GAMMAINV + GAMMALN PHPExcel_Calculation_Statistical::GAMMALN + GEOMEAN PHPExcel_Calculation_Statistical::GEOMEAN + GROWTH PHPExcel_Calculation_Statistical::GROWTH + HARMEAN PHPExcel_Calculation_Statistical::HARMEAN + HYPGEOMDIST PHPExcel_Calculation_Statistical::HYPGEOMDIST + INTERCEPT PHPExcel_Calculation_Statistical::INTERCEPT + KURT PHPExcel_Calculation_Statistical::KURT + LARGE PHPExcel_Calculation_Statistical::LARGE + LINEST PHPExcel_Calculation_Statistical::LINEST + LOGEST PHPExcel_Calculation_Statistical::LOGEST + LOGINV PHPExcel_Calculation_Statistical::LOGINV + LOGNORMDIST PHPExcel_Calculation_Statistical::LOGNORMDIST + MAX PHPExcel_Calculation_Statistical::MAX + MAXA PHPExcel_Calculation_Statistical::MAXA + MAXIF PHPExcel_Calculation_Statistical::MAXIF + MEDIAN PHPExcel_Calculation_Statistical::MEDIAN + MEDIANIF *** Not yet Implemented + MIN PHPExcel_Calculation_Statistical::MIN + MINA PHPExcel_Calculation_Statistical::MINA + MINIF PHPExcel_Calculation_Statistical::MINIF + MODE PHPExcel_Calculation_Statistical::MODE + NEGBINOMDIST PHPExcel_Calculation_Statistical::NEGBINOMDIST + NORMDIST PHPExcel_Calculation_Statistical::NORMDIST + NORMINV PHPExcel_Calculation_Statistical::NORMINV + NORMSDIST PHPExcel_Calculation_Statistical::NORMSDIST + NORMSINV PHPExcel_Calculation_Statistical::NORMSINV + PEARSON PHPExcel_Calculation_Statistical::CORREL + PERCENTILE PHPExcel_Calculation_Statistical::PERCENTILE + PERCENTRANK PHPExcel_Calculation_Statistical::PERCENTRANK + PERMUT PHPExcel_Calculation_Statistical::PERMUT + POISSON PHPExcel_Calculation_Statistical::POISSON + PROB *** Not yet Implemented + QUARTILE PHPExcel_Calculation_Statistical::QUARTILE + RANK PHPExcel_Calculation_Statistical::RANK + RSQ PHPExcel_Calculation_Statistical::RSQ + SKEW PHPExcel_Calculation_Statistical::SKEW + SLOPE PHPExcel_Calculation_Statistical::SLOPE + SMALL PHPExcel_Calculation_Statistical::SMALL + STANDARDIZE PHPExcel_Calculation_Statistical::STANDARDIZE + STDEV PHPExcel_Calculation_Statistical::STDEV + STDEVA PHPExcel_Calculation_Statistical::STDEVA + STDEVP PHPExcel_Calculation_Statistical::STDEVP + STDEVPA PHPExcel_Calculation_Statistical::STDEVPA + STEYX PHPExcel_Calculation_Statistical::STEYX + TDIST PHPExcel_Calculation_Statistical::TDIST + TINV PHPExcel_Calculation_Statistical::TINV + TREND PHPExcel_Calculation_Statistical::TREND + TRIMMEAN PHPExcel_Calculation_Statistical::TRIMMEAN + TTEST *** Not yet Implemented + VAR PHPExcel_Calculation_Statistical::VARFunc + VARA PHPExcel_Calculation_Statistical::VARA + VARP PHPExcel_Calculation_Statistical::VARP + VARPA PHPExcel_Calculation_Statistical::VARPA + WEIBULL PHPExcel_Calculation_Statistical::WEIBULL + ZTEST PHPExcel_Calculation_Statistical::ZTEST + +## CATEGORY_TEXT_AND_DATA + + Excel Function | PHPExcel Function + ------------------------|------------------------------------------- + ASC *** Not yet Implemented + BAHTTEXT *** Not yet Implemented + CHAR PHPExcel_Calculation_TextData::CHARACTER + CLEAN PHPExcel_Calculation_TextData::TRIMNONPRINTABLE + CODE PHPExcel_Calculation_TextData::ASCIICODE + CONCATENATE PHPExcel_Calculation_TextData::CONCATENATE + DOLLAR PHPExcel_Calculation_TextData::DOLLAR + EXACT *** Not yet Implemented + FIND PHPExcel_Calculation_TextData::SEARCHSENSITIVE + FINDB PHPExcel_Calculation_TextData::SEARCHSENSITIVE + FIXED PHPExcel_Calculation_TextData::FIXEDFORMAT + JIS *** Not yet Implemented + LEFT PHPExcel_Calculation_TextData::LEFT + LEFTB PHPExcel_Calculation_TextData::LEFT + LEN PHPExcel_Calculation_TextData::STRINGLENGTH + LENB PHPExcel_Calculation_TextData::STRINGLENGTH + LOWER PHPExcel_Calculation_TextData::LOWERCASE + MID PHPExcel_Calculation_TextData::MID + MIDB PHPExcel_Calculation_TextData::MID + PHONETIC *** Not yet Implemented + PROPER PHPExcel_Calculation_TextData::PROPERCASE + REPLACE PHPExcel_Calculation_TextData::REPLACE + REPLACEB PHPExcel_Calculation_TextData::REPLACE + REPT str_repeat + RIGHT PHPExcel_Calculation_TextData::RIGHT + RIGHTB PHPExcel_Calculation_TextData::RIGHT + SEARCH PHPExcel_Calculation_TextData::SEARCHINSENSITIVE + SEARCHB PHPExcel_Calculation_TextData::SEARCHINSENSITIVE + SUBSTITUTE PHPExcel_Calculation_TextData::SUBSTITUTE + T PHPExcel_Calculation_TextData::RETURNSTRING + TEXT PHPExcel_Calculation_TextData::TEXTFORMAT + TRIM PHPExcel_Calculation_TextData::TRIMSPACES + UPPER PHPExcel_Calculation_TextData::UPPERCASE + VALUE *** Not yet Implemented diff --git a/Documentation/markdown/Functions/FunctionListByName.md b/Documentation/markdown/Functions/FunctionListByName.md new file mode 100644 index 000000000..082c83af0 --- /dev/null +++ b/Documentation/markdown/Functions/FunctionListByName.md @@ -0,0 +1,381 @@ +ABS CATEGORY_MATH_AND_TRIG abs +ACCRINT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::ACCRINT +ACCRINTM CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::ACCRINTM +ACOS CATEGORY_MATH_AND_TRIG acos +ACOSH CATEGORY_MATH_AND_TRIG acosh +ADDRESS CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::CELL_ADDRESS +AMORDEGRC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::AMORDEGRC +AMORLINC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::AMORLINC +AND CATEGORY_LOGICAL PHPExcel_Calculation_Logical::LOGICAL_AND +AREAS CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented +ASC CATEGORY_TEXT_AND_DATA *** Not yet Implemented +ASIN CATEGORY_MATH_AND_TRIG asin +ASINH CATEGORY_MATH_AND_TRIG asinh +ATAN CATEGORY_MATH_AND_TRIG atan +ATAN2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::REVERSE_ATAN2 +ATANH CATEGORY_MATH_AND_TRIG atanh +AVEDEV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVEDEV +AVERAGE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVERAGE +AVERAGEA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVERAGEA +AVERAGEIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVERAGEIF +AVERAGEIFS CATEGORY_STATISTICAL *** Not yet Implemented + +BAHTTEXT CATEGORY_TEXT_AND_DATA *** Not yet Implemented +BESSELI CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELI +BESSELJ CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELJ +BESSELK CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELK +BESSELY CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELY +BETADIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::BETADIST +BETAINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::BETAINV +BIN2DEC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BINTODEC +BIN2HEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BINTOHEX +BIN2OCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BINTOOCT +BINOMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::BINOMDIST + +CEILING CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::CEILING +CELL CATEGORY_INFORMATION *** Not yet Implemented +CHAR CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::CHARACTER +CHIDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CHIDIST +CHIINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CHIINV +CHITEST CATEGORY_STATISTICAL *** Not yet Implemented +CHOOSE CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::CHOOSE +CLEAN CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::TRIMNONPRINTABLE +CODE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::ASCIICODE +COLUMN CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::COLUMN +COLUMNS CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::COLUMNS +COMBIN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::COMBIN +COMPLEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::COMPLEX +CONCATENATE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::CONCATENATE +CONFIDENCE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CONFIDENCE +CONVERT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::CONVERTUOM +CORREL CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CORREL +COS CATEGORY_MATH_AND_TRIG cos +COSH CATEGORY_MATH_AND_TRIG cosh +COUNT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNT +COUNTA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNTA +COUNTBLANK CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNTBLANK +COUNTIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNTIF +COUNTIFS CATEGORY_STATISTICAL *** Not yet Implemented +COUPDAYBS CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPDAYBS +COUPDAYS CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPDAYS +COUPDAYSNC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPDAYSNC +COUPNCD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPNCD +COUPNUM CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPNUM +COUPPCD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPPCD +COVAR CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COVAR +CRITBINOM CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CRITBINOM +CUBEKPIMEMBER CATEGORY_CUBE *** Not yet Implemented +CUBEMEMBER CATEGORY_CUBE *** Not yet Implemented +CUBEMEMBERPROPERTY CATEGORY_CUBE *** Not yet Implemented +CUBERANKEDMEMBER CATEGORY_CUBE *** Not yet Implemented +CUBESET CATEGORY_CUBE *** Not yet Implemented +CUBESETCOUNT CATEGORY_CUBE *** Not yet Implemented +CUBEVALUE CATEGORY_CUBE *** Not yet Implemented +CUMIPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::CUMIPMT +CUMPRINC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::CUMPRINC + +DATE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATE +DATEDIF CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATEDIF +DATEVALUE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATEVALUE +DAVERAGE CATEGORY_DATABASE PHPExcel_Calculation_Database::DAVERAGE +DAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DAYOFMONTH +DAYS360 CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DAYS360 +DB CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DB +DCOUNT CATEGORY_DATABASE PHPExcel_Calculation_Database::DCOUNT +DCOUNTA CATEGORY_DATABASE PHPExcel_Calculation_Database::DCOUNTA +DDB CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DDB +DEC2BIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DECTOBIN +DEC2HEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DECTOHEX +DEC2OCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DECTOOCT +DEGREES CATEGORY_MATH_AND_TRIG rad2deg +DELTA CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DELTA +DEVSQ CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::DEVSQ +DGET CATEGORY_DATABASE PHPExcel_Calculation_Database::DGET +DISC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DISC +DMAX CATEGORY_DATABASE PHPExcel_Calculation_Database::DMAX +DMIN CATEGORY_DATABASE PHPExcel_Calculation_Database::DMIN +DOLLAR CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::DOLLAR +DOLLARDE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DOLLARDE +DOLLARFR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DOLLARFR +DPRODUCT CATEGORY_DATABASE PHPExcel_Calculation_Database::DPRODUCT +DSTDEV CATEGORY_DATABASE PHPExcel_Calculation_Database::DSTDEV +DSTDEVP CATEGORY_DATABASE PHPExcel_Calculation_Database::DSTDEVP +DSUM CATEGORY_DATABASE PHPExcel_Calculation_Database::DSUM +DURATION CATEGORY_FINANCIAL *** Not yet Implemented +DVAR CATEGORY_DATABASE PHPExcel_Calculation_Database::DVAR +DVARP CATEGORY_DATABASE PHPExcel_Calculation_Database::DVARP + +EDATE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::EDATE +EFFECT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::EFFECT +EOMONTH CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::EOMONTH +ERF CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::ERF +ERFC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::ERFC +ERROR.TYPE CATEGORY_INFORMATION PHPExcel_Calculation_Functions::ERROR_TYPE +EVEN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::EVEN +EXACT CATEGORY_TEXT_AND_DATA *** Not yet Implemented +EXP CATEGORY_MATH_AND_TRIG exp +EXPONDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::EXPONDIST + +FACT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::FACT +FACTDOUBLE CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::FACTDOUBLE +FALSE CATEGORY_LOGICAL PHPExcel_Calculation_Logical::FALSE +FDIST CATEGORY_STATISTICAL *** Not yet Implemented +FIND CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHSENSITIVE +FINDB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHSENSITIVE +FINV CATEGORY_STATISTICAL *** Not yet Implemented +FISHER CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::FISHER +FISHERINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::FISHERINV +FIXED CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::FIXEDFORMAT +FLOOR CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::FLOOR +FORECAST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::FORECAST +FREQUENCY CATEGORY_STATISTICAL *** Not yet Implemented +FTEST CATEGORY_STATISTICAL *** Not yet Implemented +FV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::FV +FVSCHEDULE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::FVSCHEDULE + +GAMMADIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GAMMADIST +GAMMAINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GAMMAINV +GAMMALN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GAMMALN +GCD CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::GCD +GEOMEAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GEOMEAN +GESTEP CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::GESTEP +GETPIVOTDATA CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented +GROWTH CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GROWTH + +HARMEAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::HARMEAN +HEX2BIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTOBIN +HEX2DEC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTODEC +HEX2OCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTOOCT +HLOOKUP CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented +HOUR CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::HOUROFDAY +HYPERLINK CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::HYPERLINK +HYPGEOMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::HYPGEOMDIST + +IF CATEGORY_LOGICAL PHPExcel_Calculation_Logical::STATEMENT_IF +IFERROR CATEGORY_LOGICAL PHPExcel_Calculation_Logical::IFERROR +IMABS CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMABS +IMAGINARY CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMAGINARY +IMARGUMENT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMARGUMENT +IMCONJUGATE CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMCONJUGATE +IMCOS CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMCOS +IMDIV CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMDIV +IMEXP CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMEXP +IMLN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMLN +IMLOG10 CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMLOG10 +IMLOG2 CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMLOG2 +IMPOWER CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMPOWER +IMPRODUCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMPRODUCT +IMREAL CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMREAL +IMSIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSIN +IMSQRT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSQRT +IMSUB CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSUB +IMSUM CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSUM +INDEX CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::INDEX +INDIRECT CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::INDIRECT +INFO CATEGORY_INFORMATION *** Not yet Implemented +INT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::INT +INTERCEPT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::INTERCEPT +INTRATE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::INTRATE +IPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::IPMT +IRR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::IRR +ISBLANK CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_BLANK +ISERR CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_ERR +ISERROR CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_ERROR +ISEVEN CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_EVEN +ISLOGICAL CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_LOGICAL +ISNA CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_NA +ISNONTEXT CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_NONTEXT +ISNUMBER CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_NUMBER +ISODD CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_ODD +ISPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::ISPMT +ISREF CATEGORY_INFORMATION *** Not yet Implemented +ISTEXT CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_TEXT + +JIS CATEGORY_TEXT_AND_DATA *** Not yet Implemented + +KURT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::KURT + +LARGE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LARGE +LCM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::LCM +LEFT CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::LEFT +LEFTB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::LEFT +LEN CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::STRINGLENGTH +LENB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::STRINGLENGTH +LINEST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LINEST +LN CATEGORY_MATH_AND_TRIG log +LOG CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::LOG_BASE +LOG10 CATEGORY_MATH_AND_TRIG log10 +LOGEST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LOGEST +LOGINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LOGINV +LOGNORMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LOGNORMDIST +LOOKUP CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::LOOKUP +LOWER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::LOWERCASE + +MATCH CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::MATCH +MAX CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MAX +MAXA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MAXA +MAXIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MAXIF +MDETERM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MDETERM +MDURATION CATEGORY_FINANCIAL *** Not yet Implemented +MEDIAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MEDIAN +MEDIANIF CATEGORY_STATISTICAL *** Not yet Implemented +MID CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::MID +MIDB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::MID +MIN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MIN +MINA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MINA +MINIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MINIF +MINUTE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::MINUTEOFHOUR +MINVERSE CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MINVERSE +MIRR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::MIRR +MMULT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MMULT +MOD CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MOD +MODE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MODE +MONTH CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::MONTHOFYEAR +MROUND CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MROUND +MULTINOMIAL CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MULTINOMIAL + +N CATEGORY_INFORMATION PHPExcel_Calculation_Functions::N +NA CATEGORY_INFORMATION PHPExcel_Calculation_Functions::NA +NEGBINOMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NEGBINOMDIST +NETWORKDAYS CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::NETWORKDAYS +NOMINAL CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::NOMINAL +NORMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMDIST +NORMINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMINV +NORMSDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMSDIST +NORMSINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMSINV +NOT CATEGORY_LOGICAL PHPExcel_Calculation_Logical::NOT +NOW CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATETIMENOW +NPER CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::NPER +NPV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::NPV + +OCT2BIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::OCTTOBIN +OCT2DEC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::OCTTODEC +OCT2HEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::OCTTOHEX +ODD CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ODD +ODDFPRICE CATEGORY_FINANCIAL *** Not yet Implemented +ODDFYIELD CATEGORY_FINANCIAL *** Not yet Implemented +ODDLPRICE CATEGORY_FINANCIAL *** Not yet Implemented +ODDLYIELD CATEGORY_FINANCIAL *** Not yet Implemented +OFFSET CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::OFFSET +OR CATEGORY_LOGICAL PHPExcel_Calculation_Logical::LOGICAL_OR + +PEARSON CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CORREL +PERCENTILE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::PERCENTILE +PERCENTRANK CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::PERCENTRANK +PERMUT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::PERMUT +PHONETIC CATEGORY_TEXT_AND_DATA *** Not yet Implemented +PI CATEGORY_MATH_AND_TRIG pi +PMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PMT +POISSON CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::POISSON +POWER CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::POWER +PPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PPMT +PRICE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PRICE +PRICEDISC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PRICEDISC +PRICEMAT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PRICEMAT +PROB CATEGORY_STATISTICAL *** Not yet Implemented +PRODUCT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::PRODUCT +PROPER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::PROPERCASE +PV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PV + +QUARTILE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::QUARTILE +QUOTIENT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::QUOTIENT + +RADIANS CATEGORY_MATH_AND_TRIG deg2rad +RAND CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::RAND +RANDBETWEEN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::RAND +RANK CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::RANK +RATE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::RATE +RECEIVED CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::RECEIVED +REPLACE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::REPLACE +REPLACEB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::REPLACE +REPT CATEGORY_TEXT_AND_DATA str_repeat +RIGHT CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::RIGHT +RIGHTB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::RIGHT +ROMAN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ROMAN +ROUND CATEGORY_MATH_AND_TRIG round +ROUNDDOWN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ROUNDDOWN +ROUNDUP CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ROUNDUP +ROW CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::ROW +ROWS CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::ROWS +RSQ CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::RSQ +RTD CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented + +SEARCH CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHINSENSITIVE +SEARCHB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHINSENSITIVE +SECOND CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::SECONDOFMINUTE +SERIESSUM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SERIESSUM +SIGN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SIGN +SIN CATEGORY_MATH_AND_TRIG sin +SINH CATEGORY_MATH_AND_TRIG sinh +SKEW CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::SKEW +SLN CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::SLN +SLOPE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::SLOPE +SMALL CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::SMALL +SQRT CATEGORY_MATH_AND_TRIG sqrt +SQRTPI CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SQRTPI +STANDARDIZE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STANDARDIZE +STDEV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEV +STDEVA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEVA +STDEVP CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEVP +STDEVPA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEVPA +STEYX CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STEYX +SUBSTITUTE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SUBSTITUTE +SUBTOTAL CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUBTOTAL +SUM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUM +SUMIF CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMIF +SUMIFS CATEGORY_MATH_AND_TRIG *** Not yet Implemented +SUMPRODUCT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMPRODUCT +SUMSQ CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMSQ +SUMX2MY2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMX2MY2 +SUMX2PY2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMX2PY2 +SUMXMY2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMXMY2 +SYD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::SYD + +T CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::RETURNSTRING +TAN CATEGORY_MATH_AND_TRIG tan +TANH CATEGORY_MATH_AND_TRIG tanh +TBILLEQ CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::TBILLEQ +TBILLPRICE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::TBILLPRICE +TBILLYIELD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::TBILLYIELD +TDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TDIST +TEXT CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::TEXTFORMAT +TIME CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::TIME +TIMEVALUE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::TIMEVALUE +TINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TINV +TODAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATENOW +TRANSPOSE CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::TRANSPOSE +TREND CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TREND +TRIM CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::TRIMSPACES +TRIMMEAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TRIMMEAN +TRUE CATEGORY_LOGICAL PHPExcel_Calculation_Logical::TRUE +TRUNC CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::TRUNC +TTEST CATEGORY_STATISTICAL *** Not yet Implemented +TYPE CATEGORY_INFORMATION PHPExcel_Calculation_Functions::TYPE + +UPPER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::UPPERCASE +USDOLLAR CATEGORY_FINANCIAL *** Not yet Implemented + +VALUE CATEGORY_TEXT_AND_DATA *** Not yet Implemented +VAR CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARFunc +VARA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARA +VARP CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARP +VARPA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARPA +VDB CATEGORY_FINANCIAL *** Not yet Implemented +VERSION CATEGORY_INFORMATION PHPExcel_Calculation_Functions::VERSION +VLOOKUP CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::VLOOKUP + +WEEKDAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DAYOFWEEK +WEEKNUM CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::WEEKOFYEAR +WEIBULL CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::WEIBULL +WORKDAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::WORKDAY + +XIRR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::XIRR +XNPV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::XNPV + +YEAR CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::YEAR +YEARFRAC CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::YEARFRAC +YIELD CATEGORY_FINANCIAL *** Not yet Implemented +YIELDDISC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::YIELDDISC +YIELDMAT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::YIELDMAT + +ZTEST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::ZTEST diff --git a/Documentation/markdown/Overview/01-getting-started.md b/Documentation/markdown/Overview/01-getting-started.md new file mode 100644 index 000000000..7be472228 --- /dev/null +++ b/Documentation/markdown/Overview/01-getting-started.md @@ -0,0 +1,174 @@ +# PHPExcel Developer Documentation + + +## 1. Prerequisites, Installation, FAQ and Links + +### 1.1 Software requirements + +The following software is required to develop using PHPExcel: + + - PHP version 5.2.0 or newer + - PHP extension php_zip enabled [^phpzip_footnote] + - PHP extension php_xml enabled + - PHP extension php_gd2 enabled (if not compiled in) + + [^phpzip_footnote]: __php_zip__ is only needed by __PHPExcel_Reader_Excel2007__, __PHPExcel_Writer_Excel2007__ and __PHPExcel_Reader_OOCalc__. In other words, if you need PHPExcel to handle .xlsx or .ods files you will need the zip extension, but otherwise not. You can remove this dependency for writing Excel2007 files (though not yet for reading) by using the PCLZip library that is bundled with PHPExcel. See the FAQ section of this document for details about this. PCLZip does have a dependency on PHP's zlib extension being enabled. + +### 1.2 Installation instructions + +Installation is quite easy: copy the contents of the Classes folder to any location within your application source directories. + +*Example:* + +If your web root folder is /var/www/ you may want to create a subfolder called /var/www/Classes/ and copy the files into that folder so you end up with files: + +/var/www/Classes/PHPExcel.php +/var/www/Classes/PHPExcel/Calculation.php +/var/www/Classes/PHPExcel/Cell.php +... + +### 1.3 Getting started + +A good way to get started is to run some of the tests included in the download. +Copy the "Examples" folder next to your "Classes" folder from above so you end up with: + +/var/www/Examples/01simple.php +/var/www/Examples/02types.php +... + +Start running the tests by pointing your browser to the test scripts: + +http://example.com/Tests/01simple.php +http://example.com/Tests/02types.php +... + +Note: It may be necessary to modify the include/require statements at the beginning of each of the test scripts if your "Classes" folder from above is named differently. + +### 1.4 Useful links and tools + +There are some links and tools which are very useful when developing using PHPExcel. Please refer to the [PHPExcel CodePlex pages][2] for an update version of the list below. + +#### 1.4.1 OpenXML / SpreadsheetML + + - __File format documentation__ +[http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm][3] + - __OpenXML Explained e-book__ +[http://openxmldeveloper.org/articles/1970.aspx][4] + - __Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint 2007 File Formats__ +[http://www.microsoft.com/downloads/details.aspx?familyid=941b3470-3ae9-4aee-8f43-c6bb74cd1466&displaylang=en][5] + - __OpenXML Package Explorer__ +[http://www.codeplex.com/PackageExplorer/][6] + +#### 1.4.2 Frequently asked questions + +The up-to-date F.A.Q. page for PHPExcel can be found on [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=FAQ&referringTitle=Requirements][7]. + +##### There seems to be a problem with character encoding... + +It is necessary to use UTF-8 encoding for all texts in PHPExcel. If the script uses different encoding then you can convert those texts with PHP's iconv() or mb_convert_encoding() functions. + +##### PHP complains about ZipArchive not being found + +Make sure you meet all requirements, especially php_zip extension should be enabled. + +The ZipArchive class is only required when reading or writing formats that use Zip compression (Excel2007 and OOCalc). Since version 1.7.6 the PCLZip library has been bundled with PHPExcel as an alternative to the ZipArchive class. + +This can be enabled by calling: +```php +PHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP); +``` +*before* calling the save method of the Excel2007 Writer. + +You can revert to using ZipArchive by calling: +```php +PHPExcel_Settings::setZipClass(PHPExcel_Settings::ZIPARCHIVE); +``` +At present, this only allows you to write Excel2007 files without the need for ZipArchive (not to read Excel2007 or OOCalc) + +##### Excel 2007 cannot open the file generated by PHPExcel_Writer_2007 on Windows + +*"Excel found unreadable content in '*.xlsx'. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes."�* + +Some older versions of the 5.2.x php_zip extension on Windows contain an error when creating ZIP files. The version that can be found on [http://snaps.php.net/win32/php5.2-win32-latest.zip][8] should work at all times. + +Alternatively, upgrading to at least PHP 5.2.9 should solve the problem. + +If you can't locate a clean copy of ZipArchive, then you can use the PCLZip library as an alternative when writing Excel2007 files, as described above. + +##### Fatal error: Allowed memory size of xxx bytes exhausted (tried to allocate yyy bytes) in zzz on line aaa + +PHPExcel holds an "in memory" representation of a spreadsheet, so it is susceptible to PHP's memory limitations. The memory made available to PHP can be increased by editing the value of the memory_limit directive in your php.ini file, or by using ini_set('memory_limit', '128M') within your code (ISP permitting). + +Some Readers and Writers are faster than others, and they also use differing amounts of memory. You can find some indication of the relative performance and memory usage for the different Readers and Writers, over the different versions of PHPExcel, on the [discussion board][9]. + +If you've already increased memory to a maximum, or can't change your memory limit, then [this discussion][10] on the board describes some of the methods that can be applied to reduce the memory usage of your scripts using PHPExcel. + +##### Protection on my worksheet is not working? + +When you make use of any of the worksheet protection features (e.g. cell range protection, prohibiting deleting rows, ...), make sure you enable worksheet security. This can for example be done like this: +```php +$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); +``` + +##### Feature X is not working with PHPExcel_Reader_Y / PHPExcel_Writer_Z + +Not all features of PHPExcel are implemented in all of the Reader / Writer classes. This is mostly due to underlying libraries not supporting a specific feature or not having implemented a specific feature. + +For example autofilter is not implemented in PEAR Spreadsheet_Excel_writer, which is the base of our Excel5 writer. + +We are slowly building up a list of features, together with the different readers and writers that support them, in the "Functionality Cross-Reference.xls" file in the /Documentation folder. + +##### Formulas don't seem to be calculated in Excel2003 using compatibility pack? + +This is normal behaviour of the compatibility pack, Excel2007 displays this correctly. Use PHPExcel_Writer_Excel5 if you really need calculated values, or force recalculation in Excel2003. + +##### Setting column width is not 100% accurate + +Trying to set column width, I experience one problem. When I open the file in Excel, the actual width is 0.71 less than it should be. + +The short answer is that PHPExcel uses a measure where padding is included. See section: "Setting a column's width" for more details. + +##### How do I use PHPExcel with my framework + + - There are some instructions for using PHPExcel with Joomla on the [Joomla message board][11] + - A page of advice on using [PHPExcel in the Yii framework][12] + - [The Bakery][13] has some helper classes for reading and writing with PHPExcel within CakePHP + - Integrating [PHPExcel into Kohana 3][14] and [?????????? PHPExcel ? Kohana Framework][15] + - Using [PHPExcel with Typo3][16] + +##### Joomla Autoloader interferes with PHPExcel Autoloader + +Thanks to peterrlynch for the following advice on resolving issues between the [PHPExcel autoloader and Joomla Autoloader][17] + +#### 1.4.3 Tutorials + + - __English PHPExcel tutorial__ + [http://openxmldeveloper.org][18] + - __French PHPExcel tutorial__ + [http://g-ernaelsten.developpez.com/tutoriels/excel2007/][19] + - __Russian PHPExcel Blog Postings__ + [http://www.web-junior.net/sozdanie-excel-fajjlov-s-pomoshhyu-phpexcel/][20] + - __A Japanese-language introduction to PHPExcel__ + [http://journal.mycom.co.jp/articles/2009/03/06/phpexcel/index.html][21] + + + [2]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Documents&referringTitle=Home + [3]: http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm + [4]: http://openxmldeveloper.org/articles/1970.aspx + [5]: http://www.microsoft.com/downloads/details.aspx?familyid=941b3470-3ae9-4aee-8f43-c6bb74cd1466&displaylang=en + [6]: http://www.codeplex.com/PackageExplorer/ + [7]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=FAQ&referringTitle=Requirements + [8]: http://snaps.php.net/win32/php5.2-win32-latest.zip + [9]: http://phpexcel.codeplex.com/Thread/View.aspx?ThreadId=234150 + [10]: http://phpexcel.codeplex.com/Thread/View.aspx?ThreadId=242712 + [11]: http://http:/forum.joomla.org/viewtopic.php?f=304&t=433060 + [12]: http://www.yiiframework.com/wiki/101/how-to-use-phpexcel-external-library-with-yii/ + [13]: http://bakery.cakephp.org/articles/melgior/2010/01/26/simple-excel-spreadsheet-helper + [14]: http://www.flynsarmy.com/2010/07/phpexcel-module-for-kohana-3/ + [15]: http://szpargalki.blogspot.com/2011/02/phpexcel-kohana-framework.html + [16]: http://typo3.org/documentation/document-library/extension-manuals/phpexcel_library/1.1.1/view/toc/0/ + [17]: http://phpexcel.codeplex.com/discussions/211925 + [18]: http://openxmldeveloper.org + [19]: http://g-ernaelsten.developpez.com/tutoriels/excel2007/ + [20]: http://www.web-junior.net/sozdanie-excel-fajjlov-s-pomoshhyu-phpexcel/ + [21]: http://journal.mycom.co.jp/articles/2009/03/06/phpexcel/index.html diff --git a/Documentation/markdown/Overview/02-architecture.md b/Documentation/markdown/Overview/02-architecture.md new file mode 100644 index 000000000..6ce1330c7 --- /dev/null +++ b/Documentation/markdown/Overview/02-architecture.md @@ -0,0 +1,67 @@ +# PHPExcel Developer Documentation + + +## Architecture + +### Schematical + + + +### Lazy Loader + +PHPExcel implements an autoloader or "lazy loader"�, which means that it is not necessary to include every file within PHPExcel. It is only necessary to include the initial PHPExcel class file, then the autoloader will include other class files as and when required, so only those files that are actually required by your script will be loaded into PHP memory. The main benefit of this is that it reduces the memory footprint of PHPExcel itself, so that it uses less PHP memory. + +If your own scripts already define an autoload function, then this may be overwritten by the PHPExcel autoload function. For example, if you have: +```php +function __autoload($class) { + ... +} +``` +Do this instead: +```php +function myAutoload($class) { + ... +} + +spl_autoload_register('myAutoload'); +``` +Your autoloader will then co-exist with the autoloader of PHPExcel. + +### Spreadsheet in memory + +PHPExcel's architecture is built in a way that it can serve as an in-memory spreadsheet. This means that, if one would want to create a web based view of a spreadsheet which communicates with PHPExcel's object model, he would only have to write the front-end code. + +Just like desktop spreadsheet software, PHPExcel represents a spreadsheet containing one or more worksheets, which contain cells with data, formulas, images, ... + +### Readers and writers + +On its own, PHPExcel does not provide the functionality to read from or write to a persisted spreadsheet (on disk or in a database). To provide that functionality, readers and writers can be used. + +By default, the PHPExcel package provides some readers and writers, including one for the Open XML spreadsheet format (a.k.a. Excel 2007 file format). You are not limited to the default readers and writers, as you are free to implement the PHPExcel_Writer_IReader and PHPExcel_Writer_IWriter interface in a custom class. + +### Fluent interfaces + +PHPExcel supports fluent interfaces in most locations. This means that you can easily "chain"" calls to specific methods without requiring a new PHP statement. For example, take the following code: +```php +$objPHPExcel->getProperties()->setCreator("Maarten Balliauw"); +$objPHPExcel->getProperties()->setLastModifiedBy("Maarten Balliauw"); +$objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document"); +$objPHPExcel->getProperties()->setSubject("Office 2007 XLSX Test Document"); +$objPHPExcel->getProperties()->setDescription("Test document for Office 2007 XLSX, generated using PHP classes."); +$objPHPExcel->getProperties()->setKeywords("office 2007 openxml php"); +$objPHPExcel->getProperties()->setCategory("Test result file"); +``` +This can be rewritten as: +```php +$objPHPExcel->getProperties() + ->setCreator("Maarten Balliauw") + ->setLastModifiedBy("Maarten Balliauw") + ->setTitle("Office 2007 XLSX Test Document") + ->setSubject("Office 2007 XLSX Test Document") + ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") + ->setKeywords("office 2007 openxml php") + ->setCategory("Test result file"); +``` + +__Using fluent interfaces is not required__ +Fluent interfaces have been implemented to provide a convenient programming API. Use of them is not required, but can make your code easier to read and maintain. It can also improve performance, as you are reducing the overall number of calls to PHPExcel methods. diff --git a/Documentation/markdown/Overview/developer.md b/Documentation/markdown/Overview/developer.md new file mode 100644 index 000000000..7030eaae0 --- /dev/null +++ b/Documentation/markdown/Overview/developer.md @@ -0,0 +1,3050 @@ +# PHPExcel Developer Documentation + + +## 1. Prerequisites + +### 1.1 Software requirements + +The following software is required to develop using PHPExcel: + + - PHP version 5.2.0 or newer + - PHP extension php_zip enabled [^phpzip_footnote] + - PHP extension php_xml enabled + - PHP extension php_gd2 enabled (if not compiled in) + +[^phpzip_footnote]: ____php_zip__ is only needed by __PHPExcel_Reader_Excel2007__, __PHPExcel_Writer_Excel2007__ and __PHPExcel_Reader_OOCalc__. In other words, if you need PHPExcel to handle .xlsx or .ods files you will need the zip extension, but otherwise not.You can remove this dependency for writing Excel2007 files (though not yet for reading) by using the PCLZip library that is bundled with PHPExcel. See the FAQ section of this document for details about this. PCLZip does have a dependency on PHP's zlib extension being enabled. + +### 1.2 Installation instructions + +Installation is quite easy: copy the contents of the Classes folder to any location within your application source directories. + +*Example:* + +If your web root folder is /var/www/ you may want to create a subfolder called /var/www/Classes/ and copy the files into that folder so you end up with files: + +/var/www/Classes/PHPExcel.php +/var/www/Classes/PHPExcel/Calculation.php +/var/www/Classes/PHPExcel/Cell.php +... + +### 1.3 Getting started + +A good way to get started is to run some of the tests included in the download. + +Copy the "Examples" folder next to your "Classes" folder from above so you end up with: + +/var/www/Examples/01simple.php +/var/www/Examples/02types.php +... + +Start running the tests by pointing your browser to the test scripts: + +http://example.com/Tests/01simple.php +http://example.com/Tests/02types.php +... + +Note: It may be necessary to modify the include/require statements at the beginning of each of the test scripts if your "Classes" folder from above is named differently. + +### 1.4 Useful links and tools + +There are some links and tools which are very useful when developing using PHPExcel. Please refer to the [PHPExcel CodePlex pages][2] for an update version of the list below. + +#### 1.4.1 OpenXML / SpreadsheetML + + - __File format documentation__ +[http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm][3] + - __OpenXML Explained e-book__ +[http://openxmldeveloper.org/articles/1970.aspx][4] + - __Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint 2007 File Formats__ +[http://www.microsoft.com/downloads/details.aspx?familyid=941b3470-3ae9-4aee-8f43-c6bb74cd1466&displaylang=en][5] + - __OpenXML Package Explorer__ +[http://www.codeplex.com/PackageExplorer/][6] + +#### 1.4.2 Frequently asked questions + +The up-to-date F.A.Q. page for PHPExcel can be found on [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=FAQ&referringTitle=Requirements][7]. + +##### There seems to be a problem with character encoding... + +It is necessary to use UTF-8 encoding for all texts in PHPExcel. If the script uses different encoding then you can convert those texts with PHP's iconv() or mb_convert_encoding() functions. + +##### PHP complains about ZipArchive not being found + +Make sure you meet all requirements, especially php_zip extension should be enabled. + +The ZipArchive class is only required when reading or writing formats that use Zip compression (Excel2007 and OOCalc). Since version 1.7.6 the PCLZip library has been bundled with PHPExcel as an alternative to the ZipArchive class. + +This can be enabled by calling: +```php +PHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP); +``` +*before* calling the save method of the Excel2007 Writer. + +You can revert to using ZipArchive by calling: +```php +PHPExcel_Settings::setZipClass(PHPExcel_Settings::ZIPARCHIVE); +``` +At present, this only allows you to write Excel2007 files without the need for ZipArchive (not to read Excel2007 or OOCalc) + +##### Excel 2007 cannot open the file generated by PHPExcel_Writer_2007 on Windows + +*"Excel found unreadable content in '*.xlsx'. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes."�* + +Some older versions of the 5.2.x php_zip extension on Windows contain an error when creating ZIP files. The version that can be found on [http://snaps.php.net/win32/php5.2-win32-latest.zip][8] should work at all times. + +Alternatively, upgrading to at least PHP 5.2.9 should solve the problem. + +If you can't locate a clean copy of ZipArchive, then you can use the PCLZip library as an alternative when writing Excel2007 files, as described above. + +##### Fatal error: Allowed memory size of xxx bytes exhausted (tried to allocate yyy bytes) in zzz on line aaa + +PHPExcel holds an "in memory" representation of a spreadsheet, so it is susceptible to PHP's memory limitations. The memory made available to PHP can be increased by editing the value of the memory_limit directive in your php.ini file, or by using ini_set('memory_limit', '128M') within your code (ISP permitting). + +Some Readers and Writers are faster than others, and they also use differing amounts of memory. You can find some indication of the relative performance and memory usage for the different Readers and Writers, over the different versions of PHPExcel, on the [discussion board][9]. + +If you've already increased memory to a maximum, or can't change your memory limit, then [this discussion][10] on the board describes some of the methods that can be applied to reduce the memory usage of your scripts using PHPExcel. + +##### Protection on my worksheet is not working? + +When you make use of any of the worksheet protection features (e.g. cell range protection, prohibiting deleting rows, ...), make sure you enable worksheet security. This can for example be done like this: +```php +$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); +``` + +##### Feature X is not working with PHPExcel_Reader_Y / PHPExcel_Writer_Z + +Not all features of PHPExcel are implemented in all of the Reader / Writer classes. This is mostly due to underlying libraries not supporting a specific feature or not having implemented a specific feature. + +For example autofilter is not implemented in PEAR Spreadsheet_Excel_writer, which is the base of our Excel5 writer. + +We are slowly building up a list of features, together with the different readers and writers that support them, in the "Functionality Cross-Reference.xls" file in the /Documentation folder. + +##### Formulas don''t seem to be calculated in Excel2003 using compatibility pack? + +This is normal behaviour of the compatibility pack, Excel2007 displays this correctly. Use PHPExcel_Writer_Excel5 if you really need calculated values, or force recalculation in Excel2003. + +##### Setting column width is not 100% accurate + +Trying to set column width, I experience one problem. When I open the file in Excel, the actual width is 0.71 less than it should be. + +The short answer is that PHPExcel uses a measure where padding is included. See section: "Setting a column's width"" for more details. + +##### How do I use PHPExcel with my framework + + - There are some instructions for using PHPExcel with Joomla on the [Joomla message board][11] + - A page of advice on using [PHPExcel in the Yii framework][12] + - [The Bakery][13] has some helper classes for reading and writing with PHPExcel within CakePHP + - Integrating [PHPExcel into Kohana][14] http://www.flynsarmy.com/2010/07/phpexcel-module-for-kohana-3/ and [?????????? PHPExcel ? Kohana Framework][15] + - Using [PHPExcel with Typo3][16] + +##### Joomla Autoloader interferes with PHPExcel Autoloader + +Thanks to peterrlynch for the following advice on resolving issues between the [PHPExcel autoloader and Joomla Autoloader][17] + +#### 1.4.3 Tutorials + + - __English PHPExcel tutorial__ + http://openxmldeveloper.org + - __French PHPExcel tutorial__ +[http://g-ernaelsten.developpez.com/tutoriels/excel2007/][18] + - __Russian PHPExcel Blog Postings__ + http://www.web-junior.net/sozdanie-excel-fajjlov-s-pomoshhyu-phpexcel/ + - __A Japanese-language introduction to PHPExcel__ + [http://journal.mycom.co.jp/articles/2009/03/06/phpexcel/index.html][19] + + +# Architecture + +## Schematical + + + +## Lazy Loader + +PHPExcel implements an autoloader or "lazy loader"�, which means that it is not necessary to include every file within PHPExcel. It is only necessary to include the initial PHPExcel class file, then the autoloader will include other class files as and when required, so only those files that are actually required by your script will be loaded into PHP memory. The main benefit of this is that it reduces the memory footprint of PHPExcel itself, so that it uses less PHP memory. + +If your own scripts already define an autoload function, then this may be overwritten by the PHPExcel autoload function. For example, if you have: + +function __autoload($class) { + +... + +} + +Do this instead: + +function myAutoload($class) { + +... + +} + +spl_autoload_register('myAutoload'); + +Your autoloader will then co-exist with the autoloader of PHPExcel. + +## Spreadsheet in memory + +PHPExcel’s architecture is built in a way that it can serve as an in-memory spreadsheet. This means that, if one would want to create a web based view of a spreadsheet which communicates with PHPExcel’s object model, he would only have to write the front-end code. + +Just like desktop spreadsheet software, PHPExcel represents a spreadsheet containing one or more worksheets, which contain cells with data, formulas, images, … + +## Readers and writers + +On its own, PHPExcel does not provide the functionality to read from or write to a persisted spreadsheet (on disk or in a database). To provide that functionality, readers and writers can be used. + +By default, the PHPExcel package provides some readers and writers, including one for the Open XML spreadsheet format (a.k.a. Excel 2007 file format). You are not limited to the default readers and writers, as you are free to implement the PHPExcel_Writer_IReader and PHPExcel_Writer_IWriter interface in a custom class. + + + +## Fluent interfaces + +PHPExcel supports fluent interfaces in most locations. This means that you can easily “chain” calls to specific methods without requiring a new PHP statement. For example, take the following code: + +$objPHPExcel->getProperties()->setCreator("Maarten Balliauw"); + +$objPHPExcel->getProperties()->setLastModifiedBy("Maarten Balliauw"); + +$objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document"); + +$objPHPExcel->getProperties()->setSubject("Office 2007 XLSX Test Document"); + +$objPHPExcel->getProperties()->setDescription("Test document for Office 2007 XLSX, generated using PHP classes."); + +$objPHPExcel->getProperties()->setKeywords("office 2007 openxml php"); + +$objPHPExcel->getProperties()->setCategory("Test result file"); + +This can be rewritten as: + +$objPHPExcel->getProperties() + ->setCreator("Maarten Balliauw") + +->setLastModifiedBy("Maarten Balliauw") + +->setTitle("Office 2007 XLSX Test Document") + +->setSubject("Office 2007 XLSX Test Document") + +->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") + +->setKeywords("office 2007 openxml php") + +->setCategory("Test result file"); + +__Using fluent interfaces is not required__ +Fluent interfaces have been implemented to provide a convenient programming API. Use of them is not required, but can make your code easier to read and maintain. It can also improve performance, as you are reducing the overall number of calls to PHPExcel methods. + +# Creating a spreadsheet + +## The PHPExcel class + +The PHPExcel class is the core of PHPExcel. It contains references to the contained worksheets, document security settings and document meta data. + +To simplify the PHPExcel concept: the PHPExcel class represents your workbook. + +Typically, you will create a workbook in one of two ways, either by loading it from a spreadsheet file, or creating it manually. A third option, though less commonly used, is cloning an existing workbook that has been created using one of the previous two methods. + +### Loading a Workbook from a file + +Details of the different spreadsheet formats supported, and the options available to read them into a PHPExcel object are described fully in the “PHPExcel User Documentation - Reading Spreadsheet Files” document. + + +$inputFileName� =� './sampleData/example1.xls'; + +/**� Load� $inputFileName� to� a� PHPExcel� Object� � **/ +$objPHPExcel� =� PHPExcel_IOFactory::load($inputFileName); + + +### Creating a new workbook + +If you want to create a new workbook, rather than load one from file, then you simply need to instantiate it as a new PHPExcel object. + + +/**� Create a� new PHPExcel� Object� � **/ +$objPHPExcel� =� new PHPExcel(); + + +A new workbook will always be created with a single worksheet. + +## Configuration Settings + +Once you have included the PHPExcel files in your script, but before instantiating a PHPExcel object or loading a workbook file, there are a number of configuration options that can be set which will affect the subsequent behaviour of the script. + +### Cell Caching + +PHPExcel uses an average of about 1k/cell in your worksheets, so large workbooks can quickly use up available memory. Cell caching provides a mechanism that allows PHPExcel to maintain the cell objects in a smaller size of memory, on disk, or in APC, memcache or Wincache, rather than in PHP memory. This allows you to reduce the memory usage for large workbooks, although at a cost of speed to access cell data. + +By default, PHPExcel still holds all cell objects in memory, but you can specify alternatives. To enable cell caching, you must call the PHPExcel_Settings::setCacheStorageMethod() method, passing in the caching method that you wish to use. + +$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory; + +PHPExcel_Settings::setCacheStorageMethod($cacheMethod); + +setCacheStorageMethod() will return a boolean true on success, false on failure (for example if trying to cache to APC when APC is not enabled). + +A separate cache is maintained for each individual worksheet, and is automatically created when the worksheet is instantiated based on the caching method and settings that you have configured. You cannot change the configuration settings once you have started to read a workbook, or have created your first worksheet. + +Currently, the following caching methods are available. + +PHPExcel_CachedObjectStorageFactory::cache_in_memory; + +The default. If you don’t initialise any caching method, then this is the method that PHPExcel will use. Cell objects are maintained in PHP memory as at present. + +PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized; + +Using this caching method, cells are held in PHP memory as an array of serialized objects, which reduces the memory footprint with minimal performance overhead. + +PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip; + +Like cache_in_memory_serialized, this method holds cells in PHP memory as an array of serialized objects, but gzipped to reduce the memory usage still further, although access to read or write a cell is slightly slower. + +PHPExcel_CachedObjectStorageFactory::cache_igbinary; + +Uses PHP’s igbinary extension (if it’s available) to serialize cell objects in memory. This is normally faster and uses less memory than standard PHP serialization, but isn’t available in most hosting environments. + +PHPExcel_CachedObjectStorageFactory::cache_to_discISAM; + +When using cache_to_discISAM all cells are held in a temporary disk file, with only an index to their location in that file maintained in PHP memory. This is slower than any of the cache_in_memory methods, but significantly reduces the memory footprint. By default, PHPExcel will use PHP’s temp directory for the cache file, but you can specify a different directory when initialising cache_to_discISAM. + +$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_discISAM; + +$cacheSettings = array( 'dir' => '/usr/local/tmp' + +); + +PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); + +The temporary disk file is automatically deleted when your script terminates. + +PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp; + +Like cache_to_discISAM, when using cache_to_phpTemp all cells are held in the php://temp I/O stream, with only an index to their location maintained in PHP memory. In PHP, the php://memory wrapper stores data in the memory: php://temp behaves similarly, but uses a temporary file for storing the data when a certain memory limit is reached. The default is 1 MB, but you can change this when initialising cache_to_phpTemp. + +$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp; + +$cacheSettings = array( 'memoryCacheSize' => '8MB' + +); + +PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); + +The php://temp file is automatically deleted when your script terminates. + +PHPExcel_CachedObjectStorageFactory::cache_to_apc; + +When using cache_to_apc, cell objects are maintained in APC with only an index maintained in PHP memory to identify that the cell exists. By default, an APC cache timeout of 600 seconds is used, which should be enough for most applications: although it is possible to change this when initialising cache_to_APC. + +$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_APC; + +$cacheSettings = array( 'cacheTime' => 600 + +); + +PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); + +When your script terminates all entries will be cleared from APC, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism. + +PHPExcel_CachedObjectStorageFactory::cache_to_memcache + +When using cache_to_memcache, cell objects are maintained in memcache with only an index maintained in PHP memory to identify that the cell exists. + +By default, PHPExcel looks for a memcache server on localhost at port 11211. It also sets a memcache timeout limit of 600 seconds. If you are running memcache on a different server or port, then you can change these defaults when you initialise cache_to_memcache: + +$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_memcache; + +$cacheSettings = array( 'memcacheServer' => 'localhost', + +'memcachePort' => 11211, + +'cacheTime' => 600 + +); + +PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); + +When your script terminates all entries will be cleared from memcache, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism. + +PHPExcel_CachedObjectStorageFactory::cache_to_wincache; + +When using cache_to_wincache, cell objects are maintained in Wincache with only an index maintained in PHP memory to identify that the cell exists. By default, a Wincache cache timeout of 600 seconds is used, which should be enough for most applications: although it is possible to change this when initialising cache_to_wincache. + +$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_wincache; + +$cacheSettings = array( 'cacheTime' => 600 + +); + +PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); + +When your script terminates all entries will be cleared from Wincache, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism. + +PHPExcel_CachedObjectStorageFactory::cache_to_sqlite; + +Uses an SQLite 2 in-memory database for caching cell data. Unlike other caching methods, neither cells nor an index are held in PHP memory - an indexed database table makes it unnecessary to hold any index in PHP memory – making this the most memory-efficient of the cell caching methods. + +PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3; + +Uses an SQLite 3 in-memory database for caching cell data. Unlike other caching methods, neither cells nor an index are held in PHP memory - an indexed database table makes it unnecessary to hold any index in PHP memory – making this the most memory-efficient of the cell caching methods. + +### Language/Locale + +Some localisation elements have been included in PHPExcel. You can set a locale by changing the settings. To set the locale to Brazilian Portuguese you would use: + +$locale = 'pt_br'; + +$validLocale = PHPExcel_Settings::setLocale($locale); + +if (!$validLocale) { + +echo 'Unable to set locale to '.$locale." - reverting to en_us
\n"; + +} + +If Brazilian Portuguese language files aren’t available, then the Portuguese will be enabled instead: if Portuguese language files aren’t available, then the setLocale() method will return an error, and American English (en_us) settings will be used throughout. + +More details of the features available once a locale has been set, including a list of the languages and locales currently supported, can be found in section REF _Ref259954895 \r \h 4.5.5 REF _Ref259954904 \h Locale Settings for Formulae. + +## Clearing a Workbook from memory + +The PHPExcel object contains cyclic references (e.g. the workbook is linked to the worksheets, and the worksheets are linked to their parent workbook) which cause problems when PHP tries to clear the objects from memory when they are unset(), or at the end of a function when they are in local scope. The result of this is “memory leaks”, which can easily use a large amount of PHP’s limited memory. + +This can only be resolved manually: if you need to unset a workbook, then you also need to “break” these cyclic references before doing so. PHPExcel provides the disconnectWorksheets() method for this purpose. + +$objPHPExcel->disconnectWorksheets(); + +unset($objPHPExcel); + +## Worksheets + +A worksheet is a collection of cells, formula’s, images, graphs, … It holds all data necessary to represent as a spreadsheet worksheet. + +When you load a workbook from a spreadsheet file, it will be loaded with all its existing worksheets (unless you specified that only certain sheets should be loaded). When you load from non-spreadsheet files (such as a CSV or HTML file) or from spreadsheet formats that don’t identify worksheets by name (such as SYLK), then a single worksheet called “WorkSheet” will be created containing the data from that file. + +When you instantiate a new workbook, PHPExcel will create it with a single worksheet called “WorkSheet”. + +The getSheetCount() method will tell you the number of worksheets in the workbook; while the getSheetNames() method will return a list of all worksheets in the workbook, indexed by the order in which their “tabs” would appear when opened in MS Excel (or other appropriate Spreadsheet program). + +Individual worksheets can be accessed by name, or by their index position in the workbook. The index position represents the order that each worksheet “tab” is shown when the workbook is opened in MS Excel (or other appropriate Spreadsheet program). To access a sheet by its index, use the getSheet() method. + +// Get the second sheet in the workbook + +// Note that sheets are indexed from 0 + +$objPHPExcel->getSheet(1); + +If you don’t specify a sheet index, then the first worksheet will be returned. + +Methods also exist allowing you to reorder the worksheets in the workbook. + +To access a sheet by name, use the getSheetByName() method, specifying the name of the worksheet that you want to access. + +// Retrieve the worksheet called 'Worksheet 1' + +$objPHPExcel->getSheetByName('Worksheet 1'); + +Alternatively, one worksheet is always the currently active worksheet, and you can access that directly. The currently active worksheet is the one that will be active when the workbook is opened in MS Excel (or other appropriate Spreadsheet program). + +// Retrieve the current active worksheet + +$objPHPExcel->getActiveSheet(); + +You can change the currently active sheet by index or by name using the setActiveSheetIndex() and setActiveSheetIndexByName()methods. + +### Adding a new Worksheet + +You can add a new worksheet to the workbook using the createSheet() method of the PHPExcel object. By default, this will be created as a new “last” sheet; but you can also specify an index position as an argument, and the worksheet will be inserted at that position, shuffling all subsequent worksheets in the collection down a place. + +$objPHPExcel->createSheet(); + +A new worksheet created using this method will be called “Worksheet” or “Worksheet” where “” is the lowest number possible to guarantee that the title is unique. + +Alternatively, you can instantiate a new worksheet (setting the title to whatever you choose) and then insert it into your workbook using the addSheet() method. + +// Create a new worksheet called “My Data” + +$myWorkSheet = new PHPExcel_Worksheet($objPHPExcel, 'My Data'); + +// Attach the “My Data” worksheet as the first worksheet in the PHPExcel object + +$objPHPExcel->addSheet($myWorkSheet, 0); + +If you don’t specify an index position as the second argument, then the new worksheet will be added after the last existing worksheet. + +### Copying Worksheets + +Sheets within the same workbook can be copied by creating a clone of the worksheet you wish to copy, and then using the addSheet() method to insert the clone into the workbook. + +$objClonedWorksheet = clone $objPHPExcel->getSheetByName('Worksheet 1'); + +$objClonedWorksheet->setTitle('Copy of Worksheet 1') + +$objPHPExcel->addSheet($objClonedWorksheet); + +You can also copy worksheets from one workbook to another, though this is more complex as PHPExcel also has to replicate the styling between the two workbooks. The addExternalSheet() method is provided for this purpose. + +$objClonedWorksheet = clone $objPHPExcel1->getSheetByName('Worksheet 1'); + +$objPHPExcel->addExternalSheet($objClonedWorksheet); + +In both cases, it is the developer’s responsibility to ensure that worksheet names are not duplicated. PHPExcel will throw an exception if you attempt to copy worksheets that will result in a duplicate name. + +### Removing a Worksheet + +You can delete a worksheet from a workbook, identified by its index position, using the removeSheetByIndex() method + +$sheetIndex = $objPHPExcel->getIndex($objPHPExcel-> getSheetByName('Worksheet 1')); + +$objPHPExcel->removeSheetByIndex($sheetIndex); + +If the currently active worksheet is deleted, then the sheet at the previous index position will become the currently active sheet. + +## Accessing cells + +Accessing cells in a PHPExcel worksheet should be pretty straightforward. This topic lists some of the options to access a cell. + +### Setting a cell value by coordinate + +Setting a cell value by coordinate can be done using the worksheet’s setCellValue method. + +$objPHPExcel->getActiveSheet()->setCellValue('B8', 'Some value'); + +### Retrieving a cell by coordinate + +To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the getCell method. A cell’s value can be read again using the following line of code: + +$objPHPExcel->getActiveSheet()->getCell('B8')->getValue(); + +If you need the calculated value of a cell, use the following code. This is further explained in REF _Ref191885372 \w \h \* MERGEFORMAT 4.4.35. + +$objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue(); + +### Setting a cell value by column and row + +Setting a cell value by coordinate can be done using the worksheet’s setCellValueByColumnAndRow method. + +// Set cell B8 +$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(1, 8, 'Some value'); + +### Retrieving a cell by column and row + +To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the getCellByColumnAndRow method. A cell’s value can be read again using the following line of code: + +// Get cell B8 +$objPHPExcel->getActiveSheet()->getCellByColumnAndRow(1, 8)->getValue(); + +If you need the calculated value of a cell, use the following code. This is further explained in REF _Ref191885372 \w \h 4.4.35 + +// Get cell B8 +$objPHPExcel->getActiveSheet()->getCellByColumnAndRow(1, 8)->getCalculatedValue(); + +### Looping cells + +#### Looping cells using iterators + +The easiest way to loop cells is by using iterators. Using iterators, one can use foreach to loop worksheets, rows and cells. + +Below is an example where we read all the values in a worksheet and display them in a table. + +setReadDataOnly(true); + +$objPHPExcel = $objReader->load("test.xlsx"); + +$objWorksheet = $objPHPExcel->getActiveSheet(); + +echo '

'; From 0a09b235eeb0bf7bc66a4d49148cc168ad40f82c Mon Sep 17 00:00:00 2001 From: jgilliland Date: Tue, 16 Apr 2013 17:29:19 -0500 Subject: [PATCH 031/467] Close tbody after images and charts --- Classes/PHPExcel/Writer/HTML.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 6c44ca40f..874456986 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -394,7 +394,6 @@ public function generateSheetData() { // calculate start of
' . "\n"; + +foreach ($objWorksheet->getRowIterator() as $row) { + +echo '' . "\n"; + +$cellIterator = $row->getCellIterator(); + +$cellIterator->setIterateOnlyExistingCells(false); // This loops all cells, + // even if it is not set. + // By default, only cells + // that are set will be + // iterated. + +foreach ($cellIterator as $cell) { + +echo '' . "\n"; + +} + +echo '' . "\n"; + +} + +echo '
' . $cell->getValue() . '
' . "\n"; +?> + +Note that we have set the cell iterator’s setIterateOnlyExistingCells() to false. This makes the iterator loop all cells, even if they were not set before. + +__The cell iterator will return ____null____ as the cell if it is not set in the worksheet.__ +Setting the cell iterator’s setIterateOnlyExistingCells()to false will loop all cells in the worksheet that can be available at that moment. This will create new cells if required and increase memory usage! Only use it if it is intended to loop all cells that are possibly available. + +#### Looping cells using indexes + +One can use the possibility to access cell values by column and row index like (0,1) instead of 'A1' for reading and writing cell values in loops. + +Note: In PHPExcel column index is 0-based while row index is 1-based. That means 'A1' ~ (0,1) + +Below is an example where we read all the values in a worksheet and display them in a table. + +setReadDataOnly(true); + +$objPHPExcel = $objReader->load("test.xlsx"); + +$objWorksheet = $objPHPExcel->getActiveSheet(); + +$highestRow = $objWorksheet->getHighestRow(); // e.g. 10 + +$highestColumn = $objWorksheet->getHighestColumn(); // e.g 'F' + +$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn); // e.g. 5 + +echo '' . "\n"; + +for ($row = 1; $row <= $highestRow; ++$row) { + +echo '' . "\n"; + +for ($col = 0; $col <= $highestColumnIndex; ++$col) { + +echo '' . "\n"; + +} + +echo '' . "\n"; + +} + +echo '
' . $objWorksheet->getCellByColumnAndRow($col, $row)->getValue() . '
' . "\n"; + +?> + +### Using value binders to facilitate data entry + +Internally, PHPExcel uses a default PHPExcel_Cell_IValueBinder implementation (PHPExcel_Cell_DefaultValueBinder) to determine data types of entered data using a cell’s setValue() method. + +Optionally, the default behaviour of PHPExcel can be modified, allowing easier data entry. For example, a PHPExcel_Cell_AdvancedValueBinder class is present. It automatically converts percentages and dates entered as strings to the correct format, also setting the cell’s style information. The following example demonstrates how to set the value binder in PHPExcel: + +/** PHPExcel */ + +require_once 'PHPExcel.php'; + +/** PHPExcel_Cell_AdvancedValueBinder */ + +require_once 'PHPExcel/Cell/AdvancedValueBinder.php'; + +/** PHPExcel_IOFactory */ + +require_once 'PHPExcel/IOFactory.php'; + +// Set value binder + +PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); + +// Create new PHPExcel object + +$objPHPExcel = new PHPExcel(); + +// ... + +// Add some data, resembling some different data types + +$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Percentage value:'); + +$objPHPExcel->getActiveSheet()->setCellValue('B4', '10%'); + // Converts to 0.1 and sets percentage cell style + +$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Date/time value:'); + +$objPHPExcel->getActiveSheet()->setCellValue('B5', '21 December 1983'); + // Converts to date and sets date format cell style + +__Creating your own value binder is easy____.__ +When advanced value binding is required, you can implement the PHPExcel_Cell_IValueBinder interface or extend the PHPExcel_Cell_DefaultValueBinder or PHPExcel_Cell_AdvancedValueBinder classes. + +## PHPExcel recipes + +The following pages offer you some widely-used PHPExcel recipes. Please note that these do NOT offer complete documentation on specific PHPExcel API functions, but just a bump to get you started. If you need specific API functions, please refer to the API documentation. + +For example, REF _Ref191885321 \w \h 4.4.7 REF _Ref191885321 \h Setting a worksheet’s page orientation and size covers setting a page orientation to A4. Other paper formats, like US Letter, are not covered in this document, but in the PHPExcel API documentation. + +### Setting a spreadsheet’s metadata + +PHPExcel allows an easy way to set a spreadsheet’s metadata, using document property accessors. Spreadsheet metadata can be useful for finding a specific document in a file repository or a document management system. For example Microsoft Sharepoint uses document metadata to search for a specific document in its document lists. + +Setting spreadsheet metadata is done as follows: + +$objPHPExcel->getProperties()->setCreator("Maarten Balliauw"); + +$objPHPExcel->getProperties()->setLastModifiedBy("Maarten Balliauw"); + +$objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document"); + +$objPHPExcel->getProperties()->setSubject("Office 2007 XLSX Test Document"); + +$objPHPExcel->getProperties()->setDescription("Test document for Office 2007 XLSX, generated using PHP classes."); + +$objPHPExcel->getProperties()->setKeywords("office 2007 openxml php"); + +$objPHPExcel->getProperties()->setCategory("Test result file"); + +### Setting a spreadsheet’s active sheet + +The following line of code sets the active sheet index to the first sheet: + +$objPHPExcel->setActiveSheetIndex(0); + +### Write a date or time into a cell + +In Excel, dates and Times are stored as numeric values counting the number of days elapsed since 1900-01-01. For example, the date '2008-12-31' is represented as 39813. You can verify this in Microsoft Office Excel by entering that date in a cell and afterwards changing the number format to 'General' so the true numeric value is revealed. Likewise, '3:15 AM' is represented as 0.135417. + +PHPExcel works with UST (Universal Standard Time) date and Time values, but does no internal conversions; so it is up to the developer to ensure that values passed to the date/time conversion functions are UST. + +Writing a date value in a cell consists of 2 lines of code. Select the method that suits you the best. Here are some examples: + +/* PHPExcel_Cell_AdvanceValueBinder required for this sample */ + +require_once 'PHPExcel/Cell/AdvancedValueBinder.php'; + +// MySQL-like timestamp '2008-12-31' or date string + +PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); + +$objPHPExcel->getActiveSheet() + +->setCellValue('D1', '2008-12-31'); + +$objPHPExcel->getActiveSheet() + +->getStyle('D1') + +->getNumberFormat() + +->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH) + +// PHP-time (Unix time) + +$time = gmmktime(0,0,0,12,31,2008); // int(1230681600) + +$objPHPExcel->getActiveSheet() + +->setCellValue('D1', PHPExcel_Shared_Date::PHPToExcel($time)); + +$objPHPExcel->getActiveSheet() + +->getStyle('D1') + +->getNumberFormat() + +->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH) + +// Excel-date/time + +$objPHPExcel->getActiveSheet() + +->setCellValue('D1', 39813) + +$objPHPExcel->getActiveSheet() + +->getStyle('D1') + +->getNumberFormat() + +->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH) + +The above methods for entering a date all yield the same result. PHPExcel_Style_NumberFormat provides a lot of pre-defined date formats. + +The PHPExcel_Shared_Date::PHPToExcel() method will also work with a PHP DateTime object. + +Similarly, times (or date and time values) can be entered in the same fashion: just remember to use an appropriate format code. + +__Notes:__ + +See section "Using value binders to facilitate data entry" to learn more about the AdvancedValueBinder used in the first example. +In previous versions of PHPExcel up to and including 1.6.6, when a cell had a date-like number format code, it was possible to enter a date directly using an integer PHP-time without converting to Excel date format. Starting with PHPExcel 1.6.7 this is no longer supported. +Excel can also operate in a 1904-based calendar (default for workbooks saved on Mac). Normally, you do not have to worry about this when using PHPExcel.### Write a formula into a cell + +Inside the Excel file, formulas are always stored as they would appear in an English version of Microsoft Office Excel, and PHPExcel handles all formulae internally in this format. This means that the following rules hold: + +Decimal separator is '.' (period)Function argument separator is ',' (comma)Matrix row separator is ';' (semicolon)English function names must be usedThis is regardless of which language version of Microsoft Office Excel may have been used to create the Excel file. + +When the final workbook is opened by the user, Microsoft Office Excel will take care of displaying the formula according the applications language. Translation is taken care of by the application! + +The following line of code writes the formula “=IF(C4>500,"profit","loss")” into the cell B8. Note that the formula must start with “=” to make PHPExcel recognise this as a formula. + +$objPHPExcel->getActiveSheet()->setCellValue('B8','=IF(C4>500,"profit","loss")'); + +If you want to write a string beginning with an “=” to a cell, then you should use the setCellValueExplicit() method. + +$objPHPExcel->getActiveSheet() + +->setCellValueExplicit('B8', + +'=IF(C4>500,"profit","loss")', + +PHPExcel_Cell_DataType::TYPE_STRING + +); + +A cell’s formula can be read again using the following line of code: + +$formula = $objPHPExcel->getActiveSheet()->getCell('B8')->getValue(); + +If you need the calculated value of a cell, use the following code. This is further explained in REF _Ref191885372 \w \h \* MERGEFORMAT 4.4.35. + +$value = $objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue(); + +### Locale Settings for Formulae + +Some localisation elements have been included in PHPExcel. You can set a locale by changing the settings. To set the locale to Russian you would use: + +$locale = 'ru'; + +$validLocale = PHPExcel_Settings::setLocale($locale); + +if (!$validLocale) { + +echo 'Unable to set locale to '.$locale." - reverting to en_us
\n"; + +} + +If Russian language files aren’t available, the setLocale() method will return an error, and English settings will be used throughout. + +Once you have set a locale, you can translate a formula from its internal English coding. + +$formula = $objPHPExcel->getActiveSheet()->getCell('B8')->getValue(); + +$translatedFormula = + +PHPExcel_Calculation::getInstance()->_translateFormulaToLocale($formula); + +You can also create a formula using the function names and argument separators appropriate to the defined locale; then translate it to English before setting the cell value: + +$formula = '=ДНЕЙ360(ДАТА(2010;2;5);ДАТА(2010;12;31);ИСТИНА)'; + +$internalFormula = + +PHPExcel_Calculation::getInstance()->translateFormulaToEnglish($formula); + +$objPHPExcel->getActiveSheet()->setCellValue('B8',$internalFormula); + +Currently, formula translation only translates the function names, the constants TRUE and FALSE, and the function argument separators. + +At present, the following locale settings are supported: + +__Language__ + +__Locale Code__ + +Czech + +Čeština + +cs + +Danish + +Dansk + +da + +German + +Deutsch + +de + +Spanish + +Español + +es + +Finnish + +Suomi + +fi + +French + +Français + +fr + +Hungarian + +Magyar + +hu + +Italian + +Italiano + +it + +Dutch + +Nederlands + +nl + +Norwegian + +Norsk + +no + +Polish + +Język polski + +pl + +Portuguese + +Português + +pt + +Brazilian Portuguese + +Português Brasileiro + +pt_br + +Russian + +русский язык + +ru + +Swedish + +Svenska + +sv + +Turkish + +Türkçe + +tr + +### Write a newline character "\n" in a cell (ALT+"Enter") + +In Microsoft Office Excel you get a line break in a cell by hitting ALT+"Enter". When you do that, it automatically turns on "wrap text" for the cell. + +Here is how to achieve this in PHPExcel: + +$objPHPExcel->getActiveSheet()->getCell('A1')->setValue("hello\nworld"); + +$objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setWrapText(true); + +__Tip__ + +Read more about formatting cells using getStyle() elsewhere.__Tip__ + +AdvancedValuebinder.php automatically turns on "wrap text" for the cell when it sees a newline character in a string that you are inserting in a cell. Just like Microsoft Office Excel. Try this:require_once 'PHPExcel/Cell/AdvancedValueBinder.php';PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() );$objPHPExcel->getActiveSheet()->getCell('A1')->setValue("hello\nworld");Read more about AdvancedValueBinder.php elsewhere.### Explicitly set a cell’s datatype + +You can set a cell’s datatype explicitly by using the cell’s setValueExplicit method, or the setCellValueExplicit method of a worksheet. Here’s an example: + +$objPHPExcel->getActiveSheet()->getCell('A1')->setValueExplicit('25', PHPExcel_Cell_DataType::TYPE_NUMERIC); + +### Change a cell into a clickable URL + +You can make a cell a clickable URL by setting its hyperlink property: + +$objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net'); + +$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl('http://www.phpexcel.net/'); + +If you want to make a hyperlink to another worksheet/cell, use the following code: + +$objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net'); + +$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl(“sheet://'Sheetname'!A1”); + +### Setting a worksheet’s page orientation and size + +Setting a worksheet’s page orientation and size can be done using the following lines of code: + +$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); + +$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4); + +Note that there are additional page settings available. Please refer to the API documentation for all possible options. + +### Page Setup: Scaling options + +The page setup scaling options in PHPExcel relate directly to the scaling options in the "Page Setup" dialog as shown in the illustration. + +Default values in PHPExcel correspond to default values in MS Office Excel as shown in illustration + + + +method + +initial value + +calling method will trigger + +Note + +setFitToPage(...) + +false + +- + +setScale(...) + +100 + +setFitToPage(false) + +setFitToWidth(...) + +1 + +setFitToPage(true) + +value 0 means do-not-fit-to-width + +setFitToHeight(...) + +1 + +setFitToPage(true) + +value 0 means do-not-fit-to-height + +#### Example + +Here is how to __f____it to 1 page wide by infinite pages tall__: + +$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToWidth(1); + +$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToHeight(0); + +As you can see, it is not necessary to call setFitToPage(true) since setFitToWidth(…) and setFitToHeight(…) triggers this. + +If you use setFitToWidth() you should in general also specify setFitToHeight() explicitly like in the example. Be careful relying on the initial values. This is especially true if you are upgrading from PHPExcel 1.7.0 to 1.7.1 where the default values for fit-to-height and fit-to-width changed from 0 to 1. + +### Page margins + +To set page margins for a worksheet, use this code: + +$objPHPExcel->getActiveSheet()->getPageMargins()->setTop(1); +$objPHPExcel->getActiveSheet()->getPageMargins()->setRight(0.75); +$objPHPExcel->getActiveSheet()->getPageMargins()->setLeft(0.75); + +$objPHPExcel->getActiveSheet()->getPageMargins()->setBottom(1); + +Note that the margin values are specified in inches. + + + +### Center a page horizontally/vertically + +To center a page horizontally/vertically, you can use the following code: + +$objPHPExcel->getActiveSheet()->getPageSetup()->setHorizontalCentered(true); +$objPHPExcel->getActiveSheet()->getPageSetup()->setVerticalCentered(false); + +### Setting the print header and footer of a worksheet + +Setting a worksheet’s print header and footer can be done using the following lines of code: + +$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader('&C&HPlease treat this document as confidential!'); + +$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N'); + +Substitution and formatting codes (starting with &) can be used inside headers and footers. There is no required order in which these codes must appear. + +The first occurrence of the following codes turns the formatting ON, the second occurrence turns it OFF again: + +StrikethroughSuperscriptSubscriptSuperscript and subscript cannot both be ON at same time. Whichever comes first wins and the other is ignored, while the first is ON. + +The following codes are supported by Excel2007: + +&L + +Code for "left section" (there are three header / footer locations, "left", "center", and "right"). When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the left section. + +&P + +Code for "current page #" + +&N + +Code for "total pages" + +&font size + +Code for "text font size", where font size is a font size in points. + +&K + +Code for "text font color" + +RGB Color is specified as RRGGBBTheme Color is specifed as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade value, NN is the tint/shade value.&S + +Code for "text strikethrough" on / off + +&X + +Code for "text super script" on / off + +&Y + +Code for "text subscript" on / off + +&C + +Code for "center section". When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the center section. + +&D + +Code for "date" + +&T + +Code for "time" + +&G + +Code for "picture as background" + +Please make sure to add the image to the header/footer: + +$objDrawing = new PHPExcel_Worksheet_HeaderFooterDrawing(); + +$objDrawing->setName('PHPExcel logo'); + +$objDrawing->setPath('./images/phpexcel_logo.gif'); + +$objDrawing->setHeight(36); + +$objPHPExcel->getActiveSheet()->getHeaderFooter()->addImage($objDrawing, PHPExcel_Worksheet_HeaderFooter::IMAGE_HEADER_LEFT); + +&U + +Code for "text single underline" + +&E + +Code for "double underline" + +&R + +Code for "right section". When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the right section. + +&Z + +Code for "this workbook's file path" + +&F + +Code for "this workbook's file name" + +&A + +Code for "sheet tab name" + +&+ + +Code for add to page # + +&- + +Code for subtract from page # + +&"font name,font type" + +Code for "text font name" and "text font type", where font name and font type are strings specifying the name and type of the font, separated by a comma. When a hyphen appears in font name, it means "none specified". Both of font name and font type can be localized values. + +&"-,Bold" + +Code for "bold font style" + +&B + +Code for "bold font style" + +&"-,Regular" + +Code for "regular font style" + +&"-,Italic" + +Code for "italic font style" + +&I + +Code for "italic font style" + +&"-,Bold Italic" + +Code for "bold italic font style" + +&O + +Code for "outline style" + +&H + +Code for "shadow style" + +__Tip__ + +The above table of codes may seem overwhelming first time you are trying to figure out how to write some header or footer. Luckily, there is an easier way. Let Microsoft Office Excel do the work for you.For example, create in Microsoft Office Excel an xlsx file where you insert the header and footer as desired using the programs own interface. Save file as test.xlsx. Now, take that file and read off the values using PHPExcel as follows:$objPHPexcel = PHPExcel_IOFactory::load('test.xlsx');$objWorksheet = $objPHPexcel->getActiveSheet();var_dump($objWorksheet->getHeaderFooter()->getOddFooter());var_dump($objWorksheet->getHeaderFooter()->getEvenFooter());var_dump($objWorksheet->getHeaderFooter()->getOddHeader());var_dump($objWorksheet->getHeaderFooter()->getEvenHeader());That reveals the codes for the even/odd header and footer. Experienced users may find it easier to rename test.xlsx to test.zip, unzip it, and inspect directly the contents of the relevant xl/worksheets/sheetX.xml to find the codes for header/footer.### Setting printing breaks on a row or column + +To set a print break, use the following code, which sets a row break on row 10. + +$objPHPExcel->getActiveSheet()->setBreak( 'A10' , PHPExcel_Worksheet::BREAK_ROW ); + +The following line of code sets a print break on column D: + +$objPHPExcel->getActiveSheet()->setBreak( 'D10' , PHPExcel_Worksheet::BREAK_COLUMN ); + +### Show/hide gridlines when printing + +To show/hide gridlines when printing, use the following code: + +$objPHPExcel->getActiveSheet()->setShowGridlines(true); + +### Setting rows/columns to repeat at top/left + +PHPExcel can repeat specific rows/cells at top/left of a page. The following code is an example of how to repeat row 1 to 5 on each printed page of a specific worksheet: + +$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 5); + +### Specify printing area + +To specify a worksheet’s printing area, use the following code: + +$objPHPExcel->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5'); + +There can also be multiple printing areas in a single worksheet: + +$objPHPExcel->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5,G4:M20'); + +### Formatting cells + +A cell can be formatted with font, border, fill, … style information. For example, one can set the foreground colour of a cell to red, aligned to the right, and the border to black and thick border style. Let’s do that on cell B2: + +$objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED); + +$objPHPExcel->getActiveSheet()->getStyle('B2')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); + +$objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); + +$objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getBottom()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); + +$objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getLeft()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); + +$objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); + +$objPHPExcel->getActiveSheet()->getStyle('B2')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID); + +$objPHPExcel->getActiveSheet()->getStyle('B2')->getFill()->getStartColor()->setARGB('FFFF0000'); + +Starting with PHPExcel 1.7.0 getStyle() also accepts a cell range as a parameter. For example, you can set a red background color on a range of cells: + +$objPHPExcel->getActiveSheet()->getStyle('B3:B7')->getFill() + +->setFillType(PHPExcel_Style_Fill::FILL_SOLID) + +->getStartColor()->setARGB('FFFF0000'); + +__Tip__ +It is recommended to style many cells at once, using e.g. getStyle('A1:M500'), rather than styling the cells individually in a loop. This is much faster compared to looping through cells and styling them individually. + +There is also an alternative manner to set styles. The following code sets a cell’s style to font bold, alignment right, top border thin and a gradient fill: + +$styleArray = array( + +'font' => array( + +'bold' => true, + +), + +'alignment' => array( + +'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, + +), + +'borders' => array( + +'top' => array( + +'style' => PHPExcel_Style_Border::BORDER_THIN, + +), + +), + +'fill' => array( + +'type' => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR, + +'rotation' => 90, + +'startcolor' => array( + +'argb' => 'FFA0A0A0', + +), + +'endcolor' => array( + +'argb' => 'FFFFFFFF', + +), + +), + +); + +$objPHPExcel->getActiveSheet()->getStyle('A3')->applyFromArray($styleArray); + +Or with a range of cells: + +$objPHPExcel->getActiveSheet()->getStyle('B3:B7')->applyFromArray($styleArray); + +This alternative method using arrays should be faster in terms of execution whenever you are setting more than one style property. But the difference may barely be measurable unless you have many different styles in your workbook. + +Prior to PHPExcel 1.7.0 duplicateStyleArray() was the recommended method for styling a cell range, but this method has now been deprecated since getStyle() has started to accept a cell range. + +### Number formats + +You often want to format numbers in Excel. For example you may want a thousands separator plus a fixed number of decimals after the decimal separator. Or perhaps you want some numbers to be zero-padded. + +In Microsoft Office Excel you may be familiar with selecting a number format from the "Format Cells" dialog. Here there are some predefined number formats available including some for dates. The dialog is designed in a way so you don't have to interact with the underlying raw number format code unless you need a custom number format. + +In PHPExcel, you can also apply various predefined number formats. Example: + +$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() + +->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1); + +This will format a number e.g. 1587.2 so it shows up as 1,587.20 when you open the workbook in MS Office Excel. (Depending on settings for decimal and thousands separators in Microsoft Office Excel it may show up as 1.587,20) + +You can achieve exactly the same as the above by using this: + +$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() + +->setFormatCode('#,##0.00'); + +In Microsoft Office Excel, as well as in PHPExcel, you will have to interact with raw number format codes whenever you need some special custom number format. Example: + +$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() + +->setFormatCode('[Blue][>=3000]$#,##0;[Red][<0]$#,##0;$#,##0'); + +Another example is when you want numbers zero-padded with leading zeros to a fixed length: + +$objPHPExcel->getActiveSheet()->getCell('A1')->setValue(19); + +$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() + +->setFormatCode('0000'); // will show as 0019 in Excel + +__Tip__ +The rules for composing a number format code in Excel can be rather complicated. Sometimes you know how to create some number format in Microsoft Office Excel, but don't know what the underlying number format code looks like. How do you find it? + +The readers shipped with PHPExcel come to the rescue. Load your template workbook using e.g. Excel2007 reader to reveal the number format code. Example how read a number format code for cell A1: + +$objReader = PHPExcel_IOFactory::createReader('Excel2007'); +$objPHPExcel = $objReader->load('template.xlsx'); +var_dump($objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat()->getFormatCode()); +Advanced users may find it faster to inspect the number format code directly by renaming template.xlsx to template.zip, unzipping, and looking for the relevant piece of XML code holding the number format code in *xl/styles.xml*.### Alignment and wrap text + +Let’s set vertical alignment to the top for cells A1:D4 + +$objPHPExcel->getActiveSheet()->getStyle('A1:D4') + +->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP); + +Here is how to achieve wrap text: + +$objPHPExcel->getActiveSheet()->getStyle('A1:D4') + +->getAlignment()->setWrapText(true); + +### Setting the default style of a workbook + +It is possible to set the default style of a workbook. Let’s set the default font to Arial size 8: + +$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial'); +$objPHPExcel->getDefaultStyle()->getFont()->setSize(8); + +### Styling cell borders + +In PHPExcel it is easy to apply various borders on a rectangular selection. Here is how to apply a thick red border outline around cells B2:G8. + +$styleArray = array( + +'borders' => array( + +'outline' => array( + +'style' => PHPExcel_Style_Border::BORDER_THICK, + +'color' => array('argb' => 'FFFF0000'), + +), + +), + +); + +$objWorksheet->getStyle('B2:G8')->applyFromArray($styleArray); + +In Microsoft Office Excel, the above operation would correspond to selecting the cells B2:G8, launching the style dialog, choosing a thick red border, and clicking on the "Outline" border component. + +Note that the border outline is applied to the rectangular selection B2:G8 as a whole, not on each cell individually. + +You can achieve any border effect by using just the 5 basic borders and operating on a single cell at a time: + +__Array key__ + +__Maps to property__ + +left + +right + +top + +bottom + +diagonal + +getLeft() +getRight() +getTop() +getBottom() +getDiagonal() + +Additional shortcut borders come in handy like in the example above. These are the shortcut borders available: + +__Array key__ + +__Maps to property__ + +allborders +outline + +inside +vertical + +horizontal + +getAllBorders() + +getOutline() + +getInside() + +getVertical() + +getHorizontal() + +An overview of all border shortcuts can be seen in the following image: + + + +If you simultaneously set e.g. allborders and vertical, then we have "overlapping" borders, and one of the components has to win over the other where there is border overlap. In PHPExcel, from weakest to strongest borders, the list is as follows: allborders, outline/inside, vertical/horizontal, left/right/top/bottom/diagonal. + +This border hierarchy can be utilized to achieve various effects in an easy manner. + +### Conditional formatting a cell + +A cell can be formatted conditionally, based on a specific rule. For example, one can set the foreground colour of a cell to red if its value is below zero, and to green if its value is zero or more. + +One can set a conditional style ruleset to a cell using the following code: + +$objConditional1 = new PHPExcel_Style_Conditional(); + +$objConditional1->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS); + +$objConditional1->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_LESSTHAN); + +$objConditional1->addCondition('0'); + +$objConditional1->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED); + +$objConditional1->getStyle()->getFont()->setBold(true); + +$objConditional2 = new PHPExcel_Style_Conditional(); + +$objConditional2->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS); + +$objConditional2->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL); + +$objConditional2->addCondition('0'); + +$objConditional2->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN); + +$objConditional2->getStyle()->getFont()->setBold(true); + +$conditionalStyles = $objPHPExcel->getActiveSheet()->getStyle('B2')->getConditionalStyles(); + +array_push($conditionalStyles, $objConditional1); + +array_push($conditionalStyles, $objConditional2); + +$objPHPExcel->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditionalStyles); + +If you want to copy the ruleset to other cells, you can duplicate the style object: + +$objPHPExcel->getActiveSheet()->duplicateStyle( $objPHPExcel->getActiveSheet()->getStyle('B2'), 'B3:B7' ); + +### Add a comment to a cell + +To add a comment to a cell, use the following code. The example below adds a comment to cell E11: + +$objPHPExcel->getActiveSheet()->getComment('E11')->setAuthor('PHPExcel'); + +$objCommentRichText = $objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun('PHPExcel:'); + + +$objCommentRichText->getFont()->setBold(true); + + +$objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun("\r\n"); + + +$objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun('Total amount on the current invoice, excluding VAT.'); + + + +### Apply autofilter to a range of cells + +To apply an autofilter to a range of cells, use the following code: + +$objPHPExcel->getActiveSheet()->setAutoFilter('A1:C9'); + +__Make sure that you always include the complete filter range!__ +Excel does support setting only the captionrow, but that's __not__ a best practice... + +### Setting security on a spreadsheet + +Excel offers 3 levels of “protection”: document security, sheet security and cell security. + +Document security allows you to set a password on a complete spreadsheet, allowing changes to be made only when that password is entered.Worksheet security offers other security options: you can disallow inserting rows on a specific sheet, disallow sorting, …Cell security offers the option to lock/unlock a cell as well as show/hide the internal formulaAn example on setting document security: + +$objPHPExcel->getSecurity()->setLockWindows(true); + +$objPHPExcel->getSecurity()->setLockStructure(true); + +$objPHPExcel->getSecurity()->setWorkbookPassword("PHPExcel"); + +An example on setting worksheet security: + +$objPHPExcel->getActiveSheet()->getProtection()->setPassword('PHPExcel'); + +$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); + +$objPHPExcel->getActiveSheet()->getProtection()->setSort(true); + +$objPHPExcel->getActiveSheet()->getProtection()->setInsertRows(true); + +$objPHPExcel->getActiveSheet()->getProtection()->setFormatCells(true); + +An example on setting cell security: + +$objPHPExcel->getActiveSheet()->getStyle('B1')->getProtection()->setLocked( + +PHPExcel_Style_Protection::PROTECTION_UNPROTECTED + +); + +__Make sure you enable worksheet protection if you need any of the worksheet protection features!__ This can be done using the following code: $objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); + +### Setting data validation on a cell + +Data validation is a powerful feature of Excel2007. It allows to specify an input filter on the data that can be inserted in a specific cell. This filter can be a range (i.e. value must be between 0 and 10), a list (i.e. value must be picked from a list), … + +The following piece of code only allows numbers between 10 and 20 to be entered in cell B3: + +$objValidation = $objPHPExcel->getActiveSheet()->getCell('B3') + +->getDataValidation(); + +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_WHOLE ); + +$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP ); + +$objValidation->setAllowBlank(true); + +$objValidation->setShowInputMessage(true); + +$objValidation->setShowErrorMessage(true); + +$objValidation->setErrorTitle('Input error'); + +$objValidation->setError('Number is not allowed!'); + +$objValidation->setPromptTitle('Allowed input'); + +$objValidation->setPrompt('Only numbers between 10 and 20 are allowed.'); + +$objValidation->setFormula1(10); + +$objValidation->setFormula2(20); + +The following piece of code only allows an item picked from a list of data to be entered in cell B3: + +$objValidation = $objPHPExcel->getActiveSheet()->getCell('B5') + +->getDataValidation(); + +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST ); + +$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION ); + +$objValidation->setAllowBlank(false); + +$objValidation->setShowInputMessage(true); + +$objValidation->setShowErrorMessage(true); + +$objValidation->setShowDropDown(true); + +$objValidation->setErrorTitle('Input error'); + +$objValidation->setError('Value is not in list.'); + +$objValidation->setPromptTitle('Pick from list'); + +$objValidation->setPrompt('Please pick a value from the drop-down list.'); + +$objValidation->setFormula1('"Item A,Item B,Item C"'); + +When using a data validation list like above, make sure you put the list between " and " and that you split the items with a comma (,). + +It is important to remember that any string participating in an Excel formula is allowed to be maximum 255 characters (not bytes). This sets a limit on how many items you can have in the string "Item A,Item B,Item C". Therefore it is normally a better idea to type the item values directly in some cell range, say A1:A3, and instead use, say, $objValidation->setFormula1('Sheet!$A$1:$A$3');. Another benefit is that the item values themselves can contain the comma ‘,’ character itself. + +If you need data validation on multiple cells, one can clone the ruleset: + +$objPHPExcel->getActiveSheet()->getCell('B8')->setDataValidation(clone $objValidation); + +### Setting a column’s width + +A column’s width can be set using the following code: + +$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(12); + +If you want PHPExcel to perform an automatic width calculation, use the following code. PHPExcel will approximate the column with to the width of the widest column value. + +$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); + +The measure for column width in PHPExcel does __not__ correspond exactly to the measure you may be used to in Microsoft Office Excel. Column widths are difficult to deal with in Excel, and there are several measures for the column width.1) __Inner width in character units__ (e.g. 8.43 this is probably what you are familiar with in Excel)2) __Full width in pixels__ (e.g. 64 pixels)3) __Full width in character units__ (e.g. 9.140625, value -1 indicates unset width)__PHPExcel always operates with 3) "Full width in character units"__ which is in fact the only value that is stored in any Excel file, hence the most reliable measure. Unfortunately, __Microsoft ____Office ____Excel does not present you with this ____measure__. Instead measures 1) and 2) are computed by the application when the file is opened and these values are presented in various dialogues and tool tips.The character width unit is the width of a '0' (zero) glyph in the workbooks default font. Therefore column widths measured in character units in two different workbooks can only be compared if they have the same default workbook font.If you have some Excel file and need to know the column widths in measure 3), you can read the Excel file with PHPExcel and echo the retrieved values.### Show/hide a column + +To set a worksheet’s column visibility, you can use the following code. The first line explicitly shows the column C, the second line hides column D. + +$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(true); + +$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false); + +### Group/outline a column + +To group/outline a column, you can use the following code: + +$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1); + +You can also collapse the column. Note that you should also set the column invisible, otherwise the collapse will not be visible in Excel 2007. + +$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setCollapsed(true); + +$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setVisible(false); + +Please refer to the part “group/outline a row” for a complete example on collapsing. + +You can instruct PHPExcel to add a summary to the right (default), or to the left. The following code adds the summary to the left: + +$objPHPExcel->getActiveSheet()->setShowSummaryRight(false); + +### Setting a row’s height + +A row’s height can be set using the following code: + +$objPHPExcel->getActiveSheet()->getRowDimension('10')->setRowHeight(100); + +### Show/hide a row + +To set a worksheet’s row visibility, you can use the following code. The following example hides row number 10. + +$objPHPExcel->getActiveSheet()->getRowDimension('10')->setVisible(false); + +Note that if you apply active filters using an AutoFilter, then this will override any rows that you hide or unhide manually within that AutoFilter range if you save the file. + +### Group/outline a row + +To group/outline a row, you can use the following code: + +$objPHPExcel->getActiveSheet()->getRowDimension('5')->setOutlineLevel(1); + +You can also collapse the row. Note that you should also set the row invisible, otherwise the collapse will not be visible in Excel 2007. + +$objPHPExcel->getActiveSheet()->getRowDimension('5')->setCollapsed(true); + +$objPHPExcel->getActiveSheet()->getRowDimension('5')->setVisible(false); + +Here’s an example which collapses rows 50 to 80: + +for ($i = 51; $i <= 80; $i++) { + +$objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i"); + +$objPHPExcel->getActiveSheet()->setCellValue('B' . $i, "LName $i"); + +$objPHPExcel->getActiveSheet()->setCellValue('C' . $i, "PhoneNo $i"); + +$objPHPExcel->getActiveSheet()->setCellValue('D' . $i, "FaxNo $i"); + +$objPHPExcel->getActiveSheet()->setCellValue('E' . $i, true); + +$objPHPExcel->getActiveSheet()->getRowDimension($i)->setOutlineLevel(1); + +$objPHPExcel->getActiveSheet()->getRowDimension($i)->setVisible(false); + +} + +$objPHPExcel->getActiveSheet()->getRowDimension(81)->setCollapsed(true); + +You can instruct PHPExcel to add a summary below the collapsible rows (default), or above. The following code adds the summary above: + +$objPHPExcel->getActiveSheet()->setShowSummaryBelow(false); + +### Merge/unmerge cells + +If you have a big piece of data you want to display in a worksheet, you can merge two or more cells together, to become one cell. This can be done using the following code: + +$objPHPExcel->getActiveSheet()->mergeCells('A18:E22'); + +Removing a merge can be done using the unmergeCells method: + +$objPHPExcel->getActiveSheet()->unmergeCells('A18:E22'); + +### Inserting rows/columns + +You can insert/remove rows/columns at a specific position. The following code inserts 2 new rows, right before row 7: + +$objPHPExcel->getActiveSheet()->insertNewRowBefore(7, 2); + +### Add a drawing to a worksheet + +A drawing is always represented as a separate object, which can be added to a worksheet. Therefore, you must first instantiate a new PHPExcel_Worksheet_Drawing, and assign its properties a meaningful value: + +$objDrawing = new PHPExcel_Worksheet_Drawing(); + +$objDrawing->setName('Logo'); + +$objDrawing->setDescription('Logo'); + +$objDrawing->setPath('./images/officelogo.jpg'); + +$objDrawing->setHeight(36); + +To add the above drawing to the worksheet, use the following snippet of code. PHPExcel creates the link between the drawing and the worksheet: + +$objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); + +You can set numerous properties on a drawing, here are some examples: + +$objDrawing->setName('Paid'); + +$objDrawing->setDescription('Paid'); + +$objDrawing->setPath('./images/paid.png'); + +$objDrawing->setCoordinates('B15'); + +$objDrawing->setOffsetX(110); + +$objDrawing->setRotation(25); + +$objDrawing->getShadow()->setVisible(true); + +$objDrawing->getShadow()->setDirection(45); + +You can also add images created using GD functions without needing to save them to disk first as In-Memory drawings. + +// Use GD to create an in-memory image + +$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream'); + +$textColor = imagecolorallocate($gdImage, 255, 255, 255); + +imagestring($gdImage, 1, 5, 5, 'Created with PHPExcel', $textColor); + +// Add the In-Memory image to a worksheet + +$objDrawing = new PHPExcel_Worksheet_MemoryDrawing(); + +$objDrawing->setName('In-Memory image 1'); + +$objDrawing->setDescription('In-Memory image 1'); + +$objDrawing->setCoordinates('A1'); + +$objDrawing->setImageResource($gdImage); + +$objDrawing->setRenderingFunction( + +PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG + +); + +$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT); + +$objDrawing->setHeight(36); + +$objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); + +### Reading Images from a worksheet + +A commonly asked question is how to retrieve the images from a workbook that has been loaded, and save them as individual image files to disk. + +The following code extracts images from the current active worksheet, and writes each as a separate file. + +$i = 0; + +foreach ($objPHPExcel->getActiveSheet()->getDrawingCollection() as $drawing) { + +if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { + +ob_start(); + +call_user_func( + +$drawing->getRenderingFunction(), + +$drawing->getImageResource() + +); + +$imageContents = ob_get_contents(); + +ob_end_clean(); + +switch ($drawing->getMimeType()) { + +case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG : + +$extension = 'png'; break; + +case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_GIF: + +$extension = 'gif'; break; + +case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG : + +$extension = 'jpg'; break; + +} + +} else { + +$zipReader = fopen($drawing->getPath(),'r'); + +$imageContents = ''; + +while (!feof($zipReader)) { + +$imageContents .= fread($zipReader,1024); + +} + +fclose($zipReader); + +$extension = $drawing->getExtension(); + +} + +$myFileName = '00_Image_'.++$i.'.'.$extension; + +file_put_contents($myFileName,$imageContents); + +} + +### Add rich text to a cell + +Adding rich text to a cell can be done using PHPExcel_RichText instances. Here’s an example, which creates the following rich text string: + +This invoice is *__payable within thirty days after the end of the month__* unless specified otherwise on the invoice. + +$objRichText = new PHPExcel_RichText(); + +$objRichText->createText('This invoice is '); + +$objPayable = $objRichText->createTextRun('payable within thirty days after the end of the month'); + +$objPayable->getFont()->setBold(true); + +$objPayable->getFont()->setItalic(true); + +$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) ); + +$objRichText->createText(', unless specified otherwise on the invoice.'); + +$objPHPExcel->getActiveSheet()->getCell('A18')->setValue($objRichText); + +### Define a named range + +PHPExcel supports the definition of named ranges. These can be defined using the following code: + +// Add some data + +$objPHPExcel->setActiveSheetIndex(0); + +$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:'); + +$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Lastname:'); + +$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Maarten'); + +$objPHPExcel->getActiveSheet()->setCellValue('B2', 'Balliauw'); + +// Define named ranges + +$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonFN', $objPHPExcel->getActiveSheet(), 'B1') ); + +$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonLN', $objPHPExcel->getActiveSheet(), 'B2') ); + +Optionally, a fourth parameter can be passed defining the named range local (i.e. only usable on the current worksheet). Named ranges are global by default. + +### Redirect output to a client’s web browser + +Sometimes, one really wants to output a file to a client’s browser, especially when creating spreadsheets on-the-fly. There are some easy steps that can be followed to do this: + +Create your PHPExcel spreadsheetOutput HTTP headers for the type of document you wish to outputUse the PHPExcel_Writer_* of your choice, and save to “php://output”PHPExcel_Writer_Excel2007 uses temporary storage when writing to php://output. By default, temporary files are stored in the script’s working directory. When there is no access, it falls back to the operating system’s temporary files location. + +__This may not be safe for unauthorized viewing!__ +Depending on the configuration of your operating system, temporary storage can be read by anyone using the same temporary storage folder. When confidentiality of your document is needed, it is recommended not to use php://output. + +#### HTTP headers + +Example of a script redirecting an Excel 2007 file to the client's browser: + +save('php://output'); + +?> + +Example of a script redirecting an Excel5 file to the client's browser: + +save('php://output'); + +?> + +Caution: + +Make sure not to include any echo statements or output any other contents than the Excel file. There should be no whitespace before the opening tag (which can also be omitted to avoid problems).Make sure that your script is saved without a BOM (Byte-order mark). (Because this counts as echoing output)Same things apply to all included filesFailing to follow the above guidelines may result in corrupt Excel files arriving at the client browser, and/or that headers cannot be set by PHP (resulting in warning messages). + +### Setting the default column width + +Default column width can be set using the following code: + +$objPHPExcel->getActiveSheet()->getDefaultColumnDimension()->setWidth(12); + +### Setting the default row height + +Default row height can be set using the following code: + +$objPHPExcel->getActiveSheet()->getDefaultRowDimension()->setRowHeight(15); + +### Add a GD drawing to a worksheet + +There might be a situation where you want to generate an in-memory image using GD and add it to a PHPExcel worksheet without first having to save this file to a temporary location. + +Here’s an example which generates an image in memory and adds it to the active worksheet: + +// Generate an image + +$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream'); + +$textColor = imagecolorallocate($gdImage, 255, 255, 255); + +imagestring($gdImage, 1, 5, 5, 'Created with PHPExcel', $textColor); + +// Add a drawing to the worksheet + +$objDrawing = new PHPExcel_Worksheet_MemoryDrawing(); + +$objDrawing->setName('Sample image'); + +$objDrawing->setDescription('Sample image'); + +$objDrawing->setImageResource($gdImage); + +$objDrawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); + +$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT); + +$objDrawing->setHeight(36); + +$objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); + +### Setting worksheet zoom level + +To set a worksheet’s zoom level, the following code can be used: + +$objPHPExcel->getActiveSheet()->getSheetView()->setZoomScale(75); + +Note that zoom level should be in range 10 – 400. + +### Sheet tab color + +Sometimes you want to set a color for sheet tab. For example you can have a red sheet tab: + +$objWorksheet->getTabColor()->setRGB('FF0000'); + +### Creating worksheets in a workbook + +If you need to create more worksheets in the workbook, here is how: + +$objWorksheet1 = $objPHPExcel->createSheet(); + +$objWorksheet1->setTitle('Another sheet'); + +Think of createSheet() as the "Insert sheet" button in Excel. When you hit that button a new sheet is appended to the existing collection of worksheets in the workbook.### Hidden worksheets (Sheet states) + +Set a worksheet to be __hidden__ using this code: + +$objPHPExcel->getActiveSheet() + +->setSheetState(PHPExcel_Worksheet::SHEETSTATE_HIDDEN); + +Sometimes you may even want the worksheet to be __“very hidden”__. The available sheet states are : + +PHPExcel_Worksheet::SHEETSTATE_VISIBLE + +PHPExcel_Worksheet::SHEETSTATE_HIDDEN + +PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN + +In Excel the sheet state “very hidden” can only be set programmatically, e.g. with Visual Basic Macro. It is not possible to make such a sheet visible via the user interface.### Right-to-left worksheet + +Worksheets can be set individually whether column ‘A’ should start at left or right side. Default is left. Here is how to set columns from right-to-left. + +// right-to-left worksheet + +$objPHPExcel->getActiveSheet() + +->setRightToLeft(true); + +# Performing formula calculations + +## Using the PHPExcel calculation engine + +As PHPExcel represents an in-memory spreadsheet, it also offers formula calculation capabilities. A cell can be of a value type (containing a number or text), or a formula type (containing a formula which can be evaluated). For example, the formula "=SUM(A1:A10)" evaluates to the sum of values in A1, A2, ..., A10. + +To calculate a formula, you can call the cell containing the formula’s method getCalculatedValue(), for example: + +$objPHPExcel->getActiveSheet()->getCell('E11')->getCalculatedValue(); + +If you write the following line of code in the invoice demo included with PHPExcel, it evaluates to the value "64": + + + +Another nice feature of PHPExcel's formula parser, is that it can automatically adjust a formula when inserting/removing rows/columns. Here's an example: + + + +You see that the formula contained in cell E11 is "SUM(E4:E9)". Now, when I write the following line of code, two new product lines are added: + +$objPHPExcel->getActiveSheet()->insertNewRowBefore(7, 2); + + + +Did you notice? The formula in the former cell E11 (now E13, as I inserted 2 new rows), changed to "SUM(E4:E11)". Also, the inserted cells duplicate style information of the previous cell, just like Excel's behaviour. Note that you can both insert rows and columns. + +## Known limitations + +There are some known limitations to the PHPExcel calculation engine. Most of them are due to the fact that an Excel formula is converted into PHP code before being executed. This means that Excel formula calculation is subject to PHP’s language characteristics. + +### Operator precedence + +In Excel '+' wins over '&', just like '*' wins over '+' in ordinary algebra. The former rule is not what one finds using the calculation engine shipped with PHPExcel. + +Reference for operator precedence in Excel: + +Reference for operator precedence in PHP: + +### Formulas involving numbers and text + +Formulas involving numbers and text may produce unexpected results or even unreadable file contents. For example, the formula '=3+"Hello "' is expected to produce an error in Excel (#VALUE!). Due to the fact that PHP converts “Hello” to a numeric value (zero), the result of this formula is evaluated as 3 instead of evaluating as an error. This also causes the Excel document being generated as containing unreadable content. + +Reference for this behaviour in PHP: + +[http://be.php.net/manual/en/language.types.string.php#language.types.string.conversion][20] + +# Reading and writing to file + +As you already know from part REF _Ref191885438 \w \h 3.3 REF _Ref191885438 \h Readers and writers, reading and writing to a persisted storage is not possible using the base PHPExcel classes. For this purpose, PHPExcel provides readers and writers, which are implementations of PHPExcel_Writer_IReader and PHPExcel_Writer_IWriter. + +## PHPExcel_IOFactory + +The PHPExcel API offers multiple methods to create a PHPExcel_Writer_IReader or PHPExcel_Writer_IWriter instance: + +Direct creationVia PHPExcel_IOFactoryAll examples underneath demonstrate the direct creation method. Note that you can also use the PHPExcel_IOFactory class to do this. + +### Creating PHPExcel_Reader_IReader using PHPExcel_IOFactory + +There are 2 methods for reading in a file into PHPExcel: using automatic file type resolving or explicitly. + +Automatic file type resolving checks the different PHPExcel_Reader_IReader distributed with PHPExcel. If one of them can load the specified file name, the file is loaded using that PHPExcel_Reader_IReader. Explicit mode requires you to specify which PHPExcel_Reader_IReader should be used. + +You can create a PHPExcel_Reader_IReader instance using PHPExcel_IOFactory in automatic file type resolving mode using the following code sample: + +$objPHPExcel = PHPExcel_IOFactory::load("05featuredemo.xlsx"); + +A typical use of this feature is when you need to read files uploaded by your users, and you don’t know whether they are uploading xls or xlsx files. + +If you need to set some properties on the reader, (e.g. to only read data, see more about this later), then you may instead want to use this variant: + +$objReader = PHPExcel_IOFactory::createReaderForFile("05featuredemo.xlsx"); + +$objReader->setReadDataOnly(true); + +$objReader->load("05featuredemo.xlsx"); + +You can create a PHPExcel_Reader_IReader instance using PHPExcel_IOFactory in explicit mode using the following code sample: + +$objReader = PHPExcel_IOFactory::createReader("Excel2007"); +$objPHPExcel = $objReader->load("05featuredemo.xlsx"); + +Note that automatic type resolving mode is slightly slower than explicit mode. + +### Creating PHPExcel_Writer_IWriter using PHPExcel_IOFactory + +You can create a PHPExcel_Writer_Iwriter instance using PHPExcel_IOFactory: + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007"); +$objWriter->save("05featuredemo.xlsx"); + +## Excel 2007 (SpreadsheetML) file format + +Excel2007 file format is the main file format of PHPExcel. It allows outputting the in-memory spreadsheet to a .xlsx file. + +### PHPExcel_Reader_Excel2007 + +#### Reading a spreadsheet + +You can read an .xlsx file using the following code: + +$objReader = new PHPExcel_Reader_Excel2007(); + +$objPHPExcel = $objReader->load("05featuredemo.xlsx"); + +#### Read data only + +You can set the option setReadDataOnly on the reader, to instruct the reader to ignore styling, data validation, … and just read cell data: + +$objReader = new PHPExcel_Reader_Excel2007(); + +$objReader->setReadDataOnly(true); + +$objPHPExcel = $objReader->load("05featuredemo.xlsx"); + +#### Read specific sheets only + +You can set the option setLoadSheetsOnly on the reader, to instruct the reader to only load the sheets with a given name: + +$objReader = new PHPExcel_Reader_Excel2007(); + +$objReader->setLoadSheetsOnly( array("Sheet 1", "My special sheet") ); + +$objPHPExcel = $objReader->load("05featuredemo.xlsx"); + +#### Read specific cells only + +You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. + +The following code will only read row 1 and rows 20 – 30 of any sheet in the Excel file: + +class MyReadFilter implements PHPExcel_Reader_IReadFilter + +{ + +public function readCell($column, $row, $worksheetName = '') { + +// Read title row and rows 20 - 30 + +if ($row == 1 || ($row >= 20 && $row <= 30)) { + +return true; + +} + +return false; + +} + +} + +$objReader = new PHPExcel_Reader_Excel2007(); + +$objReader->setReadFilter( new MyReadFilter() ); +$objPHPExcel = $objReader->load("06largescale.xlsx"); + +### PHPExcel_Writer_Excel2007 + +#### Writing a spreadsheet + +You can write an .xlsx file using the following code: + +$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); + +$objWriter->save("05featuredemo.xlsx"); + +#### Formula pre-calculation + +By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation: + +$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); +$objWriter->setPreCalculateFormulas(false); + +$objWriter->save("05featuredemo.xlsx"); + +#### Office 2003 compatibility pack + +Because of a bug in the Office2003 compatibility pack, there can be some small issues when opening Excel2007 spreadsheets (mostly related to formula calculation). You can enable Office2003 compatibility with the following code: + +$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); +$objWriter->setOffice2003Compatibility(true); + +$objWriter->save("05featuredemo.xlsx"); + +__Office2003 compatibility should only be used when needed__ +Office2003 compatibility option should only be used when needed. This option disables several Office2007 file format options, resulting in a lower-featured Office2007 spreadsheet when this option is used. + +## Excel 5 (BIFF) file format + +Excel5 file format is the old Excel file format, implemented in PHPExcel to provide a uniform manner to create both .xlsx and .xls files. It is basically a modified version of [PEAR Spreadsheet_Excel_Writer][21], although it has been extended and has fewer limitations and more features than the old PEAR library. This can read all BIFF versions that use OLE2: BIFF5 (introduced with office 95) through BIFF8, but cannot read earlier versions. + +Excel5 file format will not be developed any further, it just provides an additional file format for PHPExcel. + +__Excel5 (BIFF) limitations__ +Please note that BIFF file format has some limits regarding to styling cells and handling large spreadsheets via PHP. + +### PHPExcel_Reader_Excel5 + +#### Reading a spreadsheet + +You can read an .xls file using the following code: + +$objReader = new PHPExcel_Reader_Excel5(); + +$objPHPExcel = $objReader->load("05featuredemo.xls"); + +#### Read data only + +You can set the option setReadDataOnly on the reader, to instruct the reader to ignore styling, data validation, … and just read cell data: + +$objReader = new PHPExcel_Reader_Excel5(); + +$objReader->setReadDataOnly(true); + +$objPHPExcel = $objReader->load("05featuredemo.xls"); + +#### Read specific sheets only + +You can set the option setLoadSheetsOnly on the reader, to instruct the reader to only load the sheets with a given name: + +$objReader = new PHPExcel_Reader_Excel5(); + +$objReader->setLoadSheetsOnly( array("Sheet 1", "My special sheet") ); + +$objPHPExcel = $objReader->load("05featuredemo.xls"); + +#### Read specific cells only + +You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. + +The following code will only read row 1 and rows 20 – 30 of any sheet in the Excel file: + +class MyReadFilter implements PHPExcel_Reader_IReadFilter + +{ + +public function readCell($column, $row, $worksheetName = '') { + +// Read title row and rows 20 - 30 + +if ($row == 1 || ($row >= 20 && $row <= 30)) { + +return true; + +} + +return false; + +} + +} + +$objReader = new PHPExcel_Reader_Excel5(); + +$objReader->setReadFilter( new MyReadFilter() ); +$objPHPExcel = $objReader->load("06largescale.xls"); + +### PHPExcel_Writer_Excel5 + +#### Writing a spreadsheet + +You can write an .xls file using the following code: + +$objWriter = new PHPExcel_Writer_Excel5($objPHPExcel); + +$objWriter->save("05featuredemo.xls"); + +## Excel 2003 XML file format + +Excel 2003 XML file format is a file format which can be used in older versions of Microsoft Excel. + +__Excel 2003 XML limitations__ +Please note that Excel 2003 XML format has some limits regarding to styling cells and handling large spreadsheets via PHP. + +### PHPExcel_Reader_Excel2003XML + +#### Reading a spreadsheet + +You can read an .xml file using the following code: + +$objReader = new PHPExcel_Reader_Excel2003XML(); + +$objPHPExcel = $objReader->load("05featuredemo.xml"); + +#### Read specific cells only + +You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. + +The following code will only read row 1 and rows 20 – 30 of any sheet in the Excel file: + +class MyReadFilter implements PHPExcel_Reader_IReadFilter + +{ + +public function readCell($column, $row, $worksheetName = '') { + +// Read title row and rows 20 - 30 + +if ($row == 1 || ($row >= 20 && $row <= 30)) { + +return true; + +} + +return false; + +} + +} + +$objReader = new PHPExcel_Reader_Excel2003XML(); + +$objReader->setReadFilter( new MyReadFilter() ); +$objPHPExcel = $objReader->load("06largescale.xml"); + +## Symbolic LinK (SYLK) + +Symbolic Link (SYLK) is a Microsoft file format typically used to exchange data between applications, specifically spreadsheets. SYLK files conventionally have a .slk suffix. Composed of only displayable ANSI characters, it can be easily created and processed by other applications, such as databases. + +__SYLK limitations__ +Please note that SYLK file format has some limits regarding to styling cells and handling large spreadsheets via PHP. + +### PHPExcel_Reader_SYLK + +#### Reading a spreadsheet + +You can read an .slk file using the following code: + +$objReader = new PHPExcel_Reader_SYLK(); + +$objPHPExcel = $objReader->load("05featuredemo.slk"); + +#### Read specific cells only + +You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. + +The following code will only read row 1 and rows 20 – 30 of any sheet in the SYLK file: + +class MyReadFilter implements PHPExcel_Reader_IReadFilter + +{ + +public function readCell($column, $row, $worksheetName = '') { + +// Read title row and rows 20 - 30 + +if ($row == 1 || ($row >= 20 && $row <= 30)) { + +return true; + +} + +return false; + +} + +} + +$objReader = new PHPExcel_Reader_SYLK(); + +$objReader->setReadFilter( new MyReadFilter() ); +$objPHPExcel = $objReader->load("06largescale.slk"); + +## Open/Libre Office (.ods) + +Open Office or Libre Office .ods files are the standard file format fopr Open Office or Libre Office Calc files. + +### PHPExcel_Reader_OOCalc + +#### Reading a spreadsheet + +You can read an .ods file using the following code: + +$objReader = new PHPExcel_Reader_OOCalc(); + +$objPHPExcel = $objReader->load("05featuredemo.ods"); + +#### Read specific cells only + +You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. + +The following code will only read row 1 and rows 20 – 30 of any sheet in the Calc file: + +class MyReadFilter implements PHPExcel_Reader_IReadFilter + +{ + +public function readCell($column, $row, $worksheetName = '') { + +// Read title row and rows 20 - 30 + +if ($row == 1 || ($row >= 20 && $row <= 30)) { + +return true; + +} + +return false; + +} + +} + +$objReader = new PHPExcel_Reader_OOcalc(); + +$objReader->setReadFilter( new MyReadFilter() ); +$objPHPExcel = $objReader->load("06largescale.ods"); + +## CSV (Comma Separated Values) + +CSV (Comma Separated Values) are often used as an import/export file format with other systems. PHPExcel allows reading and writing to CSV files. + +__CSV limitations__ +Please note that CSV file format has some limits regarding to styling cells, number formatting, … + +### PHPExcel_Reader_CSV + +#### Reading a CSV file + +You can read a .csv file using the following code: + +$objReader = new PHPExcel_Reader_CSV(); + +$objPHPExcel = $objReader->load("sample.csv"); + +#### Setting CSV options + +Often, CSV files are not really “comma separated”, or use semicolon (;) as a separator. You can instruct PHPExcel_Reader_CSV some options before reading a CSV file. + +Note that PHPExcel_Reader_CSV by default assumes that the loaded CSV file is UTF-8 encoded. If you are reading CSV files that were created in Microsoft Office Excel the correct input encoding may rather be Windows-1252 (CP1252). Always make sure that the input encoding is set appropriately. + +$objReader = new PHPExcel_Reader_CSV(); +$objReader->setInputEncoding('CP1252'); + +$objReader->setDelimiter(';'); + +$objReader->setEnclosure(''); + +$objReader->setLineEnding("\r\n"); +$objReader->setSheetIndex(0); + +$objPHPExcel = $objReader->load("sample.csv"); + +#### Read a specific worksheet + +CSV files can only contain one worksheet. Therefore, you can specify which sheet to read from CSV: + +$objReader->setSheetIndex(0); + +#### Read into existing spreadsheet + +When working with CSV files, it might occur that you want to import CSV data into an existing PHPExcel object. The following code loads a CSV file into an existing $objPHPExcel containing some sheets, and imports onto the 6th sheet: + +$objReader = new PHPExcel_Reader_CSV(); +$objReader->setDelimiter(';'); + +$objReader->setEnclosure(''); + +$objReader->setLineEnding("\r\n"); +$objReader->setSheetIndex(5); +$objReader->loadIntoExisting("05featuredemo.csv", $objPHPExcel); + +### PHPExcel_Writer_CSV + +#### Writing a CSV file + +You can write a .csv file using the following code: + +$objWriter = new PHPExcel_Writer_CSV($objPHPExcel); + +$objWriter->save("05featuredemo.csv"); + +#### Setting CSV options + +Often, CSV files are not really “comma separated”, or use semicolon (;) as a separator. You can instruct PHPExcel_Writer_CSV some options before writing a CSV file: + +$objWriter = new PHPExcel_Writer_CSV($objPHPExcel); +$objWriter->setDelimiter(';'); + +$objWriter->setEnclosure(''); + +$objWriter->setLineEnding("\r\n"); +$objWriter->setSheetIndex(0); + +$objWriter->save("05featuredemo.csv"); + +#### Write a specific worksheet + +CSV files can only contain one worksheet. Therefore, you can specify which sheet to write to CSV: + +$objWriter->setSheetIndex(0); + +#### Formula pre-calculation + +By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation: + +$objWriter = new PHPExcel_Writer_CSV($objPHPExcel); +$objWriter->setPreCalculateFormulas(false); + +$objWriter->save("05featuredemo.csv"); + +#### Writing UTF-8 CSV files + +A CSV file can be marked as UTF-8 by writing a BOM file header. This can be enabled by using the following code: + +$objWriter = new PHPExcel_Writer_CSV($objPHPExcel); +$objWriter->setUseBOM(true); + +$objWriter->save("05featuredemo.csv"); + +#### Decimal and thousands separators + +If the worksheet you are exporting contains numbers with decimal or thousands separators then you should think about what characters you want to use for those before doing the export. + +By default PHPExcel looks up in the server’s locale settings to decide what characters to use. But to avoid problems it is recommended to set the characters explicitly as shown below. + +English users will want to use this before doing the export: + +require_once 'PHPExcel/Shared/String.php' + +PHPExcel_Shared_String::setDecimalSeparator('.'); + +PHPExcel_Shared_String::setThousandsSeparator(','); + +German users will want to use the opposite values. + +require_once 'PHPExcel/Shared/String.php' + +PHPExcel_Shared_String::setDecimalSeparator(','); + +PHPExcel_Shared_String::setThousandsSeparator('.'); + +Note that the above code sets decimal and thousand separators as global options. This also affects how HTML and PDF is exported. + +## HTML + +PHPExcel allows you to read or write a spreadsheet as HTML format, for quick representation of the data in it to anyone who does not have a spreadsheet application on their PC, or loading files saved by other scripts that simply create HTML markup and give it a .xls file extension. + +__HTML limitations__ +Please note that HTML file format has some limits regarding to styling cells, number formatting, … + +### PHPExcel_Reader_HTML + +#### Reading a spreadsheet + +You can read an .html or .htm file using the following code: + +$objReader = new PHPExcel_Reader_HTML(); + +$objPHPExcel = $objReader->load("05featuredemo.html"); + +__HTML limitations__ +Please note that HTML reader is still experimental and does not yet support merged cells or nested tables cleanly + +### PHPExcel_Writer_HTML + +Please note that PHPExcel_Writer_HTML only outputs the first worksheet by default. + +#### Writing a spreadsheet + +You can write a .htm file using the following code: + +$objWriter = new PHPExcel_Writer_HTML($objPHPExcel); + +$objWriter->save("05featuredemo.htm"); + +#### Write all worksheets + +HTML files can contain one or more worksheets. If you want to write all sheets into a single HTML file, use the following code: + +$objWriter->writeAllSheets(); + +#### Write a specific worksheet + +HTML files can contain one or more worksheets. Therefore, you can specify which sheet to write to HTML: + +$objWriter->setSheetIndex(0); + +#### Setting the images root of the HTML file + +There might be situations where you want to explicitly set the included images root. For example, one might want to see instead of . + +You can use the following code to achieve this result: + +$objWriter->setImagesRoot('http://www.example.com/'); + +#### Formula pre-calculation + +By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation: + +$objWriter = new PHPExcel_Writer_HTML($objPHPExcel); +$objWriter->setPreCalculateFormulas(false); + +$objWriter->save("05featuredemo.htm"); + +#### Embedding generated HTML in a web page + +There might be a situation where you want to embed the generated HTML in an existing website. PHPExcel_Writer_HTML provides support to generate only specific parts of the HTML code, which allows you to use these parts in your website. + +Supported methods: + +generateHTMLHeader()generateStyles()generateSheetData()generateHTMLFooter()Here’s an example which retrieves all parts independently and merges them into a resulting HTML page: + +generateHTMLHeader(); +?> + + +?> + +--> + + + +generateSheetData(); +echo $objWriter->generateHTMLFooter(); +?> + +#### Writing UTF-8 HTML files + +A HTML file can be marked as UTF-8 by writing a BOM file header. This can be enabled by using the following code: + +$objWriter = new PHPExcel_Writer_HTML($objPHPExcel); +$objWriter->setUseBOM(true); + +$objWriter->save("05featuredemo.htm"); + +#### Decimal and thousands separators + +See section PHPExcel_Writer_CSV how to control the appearance of these. + +## PDF + +PHPExcel allows you to write a spreadsheet into PDF format, for fast distribution of represented data. + +__PDF limitations__ +Please note that PDF file format has some limits regarding to styling cells, number formatting, … + +### PHPExcel_Writer_PDF + +PHPExcel’s PDF Writer is a wrapper for a 3rd-Party PDF Rendering library such as tcPDF, mPDF or DomPDF. Prior to version 1.7.8 of PHPExcel, the tcPDF library was bundled with PHPExcel; but from version 1.7.8 this was removed. Instead, you must now install a PDF Rendering library yourself; but PHPExcel will work with a number of different libraries. + +Currently, the following libraries are supported: + +__Library__ + +__Version used for testing__ + +__Downloadable from__ + +__PHPExcel Internal Constant__ + +tcPDF + +5.9 + +http://www.tcpdf.org/ + +PDF_RENDERER_TCPDF + +mPDF + +5.4 + +http://www.mpdf1.com/mpdf/ + +PDF_RENDERER_MPDF + +domPDF + +0.6.0 beta 3 + +http://code.google.com/p/dompdf/ + +PDF_RENDERER_DOMPDF + +The different libraries have different strengths and weaknesses. Some generate better formatted output than others, some are faster or use less memory than others, while some generate smaller .pdf files. It is the developers choice which one they wish to use, appropriate to their own circumstances. + +Before instantiating a Writer to generate PDF output, you will need to indicate which Rendering library you are using, and where it is located. + +$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF; + +$rendererLibrary = 'mPDF5.4'; + +$rendererLibraryPath = dirname(__FILE__).'/../../../libraries/PDF/' . $rendererLibrary; + +if (!PHPExcel_Settings::setPdfRenderer( + +$rendererName, + +$rendererLibraryPath + +)) { + +die( + +'Please set the $rendererName and $rendererLibraryPath values' . + +PHP_EOL . + +' as appropriate for your directory structure' + +); + +} + +#### Writing a spreadsheet + +Once you have identified the Renderer that you wish to use for PDF generation, you can write a .pdf file using the following code: + +$objWriter = new PHPExcel_Writer_PDF($objPHPExcel); + +$objWriter->save("05featuredemo.pdf"); + +Please note that PHPExcel_Writer_PDF only outputs the first worksheet by default. + +#### Write all worksheets + +PDF files can contain one or more worksheets. If you want to write all sheets into a single PDF file, use the following code: + +$objWriter->writeAllSheets(); + +#### Write a specific worksheet + +PDF files can contain one or more worksheets. Therefore, you can specify which sheet to write to PDF: + +$objWriter->setSheetIndex(0); + +#### Formula pre-calculation + +By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation: + +$objWriter = new PHPExcel_Writer_PDF($objPHPExcel); +$objWriter->setPreCalculateFormulas(false); + +$objWriter->save("05featuredemo.pdf"); + +#### Decimal and thousands separators + +See section PHPExcel_Writer_CSV how to control the appearance of these. + +## Generating Excel files from templates (read, modify, write) + +Readers and writers are the tools that allow you to generate Excel files from templates. This requires less coding effort than generating the Excel file from scratch, especially if your template has many styles, page setup properties, headers etc. + +Here is an example how to open a template file, fill in a couple of fields and save it again: + +$objPHPexcel = PHPExcel_IOFactory::load('template.xlsx'); + +$objWorksheet = $objPHPexcel->getActiveSheet(); + +$objWorksheet->getCell('A1')->setValue('John'); + +$objWorksheet->getCell('A2')->setValue('Smith'); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPexcel, 'Excel5'); + +$objWriter->save('write.xls'); + +Notice that it is ok to load an xlsx file and generate an xls file. + +# Credits + +Please refer to the internet page [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home][22] for up-to-date credits. + +# Valid array keys for style applyFromArray() + +The following table lists the valid array keys for PHPExcel_Style applyFromArray() classes. If the “Maps to property” column maps a key to a setter, the value provided for that key will be applied directly. If the “Maps to property” column maps a key to a getter, the value provided for that key will be applied as another style array. + +__PHPExcel_Style__ + +Array key: + +Maps to property: + +fill + +font + +borders + +alignment + +numberformat + +protection + + +getFill() +getFont() +getBorders() +getAlignment() +getNumberFormat() +getProtection() + +__PHPExcel_Style_Fill__ + +Array key: + +Maps to property: + +type +rotation +startcolor +endcolor +color + + +setFillType() +setRotation() +getStartColor() +getEndColor() +getStartColor() + +__PHPExcel_Style_Font__ + +Array key: + +Maps to property: + +name +bold +italic +underline +strike +color +size +superScript +subScript + + +setName() +setBold() +setItalic() +setUnderline() +setStrikethrough() +getColor() +setSize() +setSuperScript() +setSubScript() + +__PHPExcel_Style_Borders__ + +Array key: + +Maps to property: + +allborders +left +right +top +bottom +diagonal +vertical +horizontal +diagonaldirection +outline + + +getLeft(); getRight(); getTop(); getBottom() +getLeft() +getRight() +getTop() +getBottom() + +getDiagonal() +getVertical() +getHorizontal() +setDiagonalDirection() +setOutline() + +__PHPExcel_Style_Border__ + +Array key: + +Maps to property: + +style +color + + +setBorderStyle() +getColor() + +__PHPExcel_Style_Alignment__ + +Array key: + +Maps to property: + +horizontal +vertical +rotation +wrap +shrinkToFit +indent + + +setHorizontal() +setVertical() +setTextRotation() +setWrapText() +setShrinkToFit() +setIndent() + +__PHPExcel_Style_NumberFormat__ + +Array key: + +Maps to property: + +code + + +setFormatCode() + +__PHPExcel_Style_Protection__ + +Array key: + +Maps to property: + +locked +hidden + + +setLocked() +setHidden() + + + [2]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Documents&referringTitle=Home + [3]: http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm + [4]: http://openxmldeveloper.org/articles/1970.aspx + [5]: http://www.microsoft.com/downloads/details.aspx?familyid=941b3470-3ae9-4aee-8f43-c6bb74cd1466&displaylang=en + [6]: http://www.codeplex.com/PackageExplorer/ + [7]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=FAQ&referringTitle=Requirements + [8]: http://snaps.php.net/win32/php5.2-win32-latest.zip + [9]: http://phpexcel.codeplex.com/Thread/View.aspx?ThreadId=234150 + [10]: http://phpexcel.codeplex.com/Thread/View.aspx?ThreadId=242712 + [11]: http://http:/forum.joomla.org/viewtopic.php?f=304&t=433060 + [12]: http://www.yiiframework.com/wiki/101/how-to-use-phpexcel-external-library-with-yii/ + [13]: http://bakery.cakephp.org/articles/melgior/2010/01/26/simple-excel-spreadsheet-helper + [14]: http://www.flynsarmy.com/2010/07/phpexcel-module-for-kohana-3/ + [15]: http://szpargalki.blogspot.com/2011/02/phpexcel-kohana-framework.html + [16]: http://typo3.org/documentation/document-library/extension-manuals/phpexcel_library/1.1.1/view/toc/0/ + [17]: http://phpexcel.codeplex.com/discussions/211925 + [18]: http://g-ernaelsten.developpez.com/tutoriels/excel2007/ + [19]: http://journal.mycom.co.jp/articles/2009/03/06/phpexcel/index.html + [20]: http://be.php.net/manual/en/language.types.string.php#language.types.string.conversion + [21]: http://pear.php.net/package/Spreadsheet_Excel_Writer + [22]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home diff --git a/Documentation/markdown/Overview/images/01-schematic.png b/Documentation/markdown/Overview/images/01-schematic.png new file mode 100644 index 0000000000000000000000000000000000000000..8b6779204c7416b176c6a45fd22e8874779da120 GIT binary patch literal 14519 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
C@R3Al}NuGZG*}hoF=XAuf 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

M&E2g}Bvvd* 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 MJXU#BAOnT}H$4rR*8l(j literal 0 HcmV?d00001 From 9879a71952d9673650b50d867228d005d010e18e Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 13 May 2013 14:45:30 +0100 Subject: [PATCH 067/467] Documentation markdown --- .../Functions/FunctionListByCategory.md | 447 +++++++++--------- .../markdown/Functions/FunctionListByName.md | 152 +++--- 2 files changed, 303 insertions(+), 296 deletions(-) diff --git a/Documentation/markdown/Functions/FunctionListByCategory.md b/Documentation/markdown/Functions/FunctionListByCategory.md index cdd39f095..ff765dc7f 100644 --- a/Documentation/markdown/Functions/FunctionListByCategory.md +++ b/Documentation/markdown/Functions/FunctionListByCategory.md @@ -160,251 +160,252 @@ Excel Function | PHPExcel Function ------------------------|------------------------------------------- - CELL *** Not yet Implemented - ERROR.TYPE PHPExcel_Calculation_Functions::ERROR_TYPE - INFO *** Not yet Implemented - ISBLANK PHPExcel_Calculation_Functions::IS_BLANK - ISERR PHPExcel_Calculation_Functions::IS_ERR - ISERROR PHPExcel_Calculation_Functions::IS_ERROR - ISEVEN PHPExcel_Calculation_Functions::IS_EVEN - ISLOGICAL PHPExcel_Calculation_Functions::IS_LOGICAL - ISNA PHPExcel_Calculation_Functions::IS_NA - ISNONTEXT PHPExcel_Calculation_Functions::IS_NONTEXT - ISNUMBER PHPExcel_Calculation_Functions::IS_NUMBER - ISODD PHPExcel_Calculation_Functions::IS_ODD - ISREF *** Not yet Implemented - ISTEXT PHPExcel_Calculation_Functions::IS_TEXT - N PHPExcel_Calculation_Functions::N - NA PHPExcel_Calculation_Functions::NA - TYPE PHPExcel_Calculation_Functions::TYPE - VERSION PHPExcel_Calculation_Functions::VERSION + CELL | *** Not yet Implemented + ERROR.TYPE | PHPExcel_Calculation_Functions::ERROR_TYPE + INFO | *** Not yet Implemented + ISBLANK | PHPExcel_Calculation_Functions::IS_BLANK + ISERR | PHPExcel_Calculation_Functions::IS_ERR + ISERROR | PHPExcel_Calculation_Functions::IS_ERROR + ISEVEN | PHPExcel_Calculation_Functions::IS_EVEN + ISLOGICAL | PHPExcel_Calculation_Functions::IS_LOGICAL + ISNA | PHPExcel_Calculation_Functions::IS_NA + ISNONTEXT | PHPExcel_Calculation_Functions::IS_NONTEXT + ISNUMBER | PHPExcel_Calculation_Functions::IS_NUMBER + ISODD | PHPExcel_Calculation_Functions::IS_ODD + ISREF | *** Not yet Implemented + ISTEXT | PHPExcel_Calculation_Functions::IS_TEXT + N | PHPExcel_Calculation_Functions::N + NA | PHPExcel_Calculation_Functions::NA + TYPE | PHPExcel_Calculation_Functions::TYPE + VERSION | PHPExcel_Calculation_Functions::VERSION ## CATEGORY_LOGICAL Excel Function | PHPExcel Function ------------------------|------------------------------------------- - AND PHPExcel_Calculation_Logical::LOGICAL_AND - FALSE PHPExcel_Calculation_Logical::FALSE - IF PHPExcel_Calculation_Logical::STATEMENT_IF - IFERROR PHPExcel_Calculation_Logical::IFERROR - NOT PHPExcel_Calculation_Logical::NOT - OR PHPExcel_Calculation_Logical::LOGICAL_OR - TRUE PHPExcel_Calculation_Logical::TRUE + AND | PHPExcel_Calculation_Logical::LOGICAL_AND + FALSE | PHPExcel_Calculation_Logical::FALSE + IF | PHPExcel_Calculation_Logical::STATEMENT_IF + IFERROR | PHPExcel_Calculation_Logical::IFERROR + NOT | PHPExcel_Calculation_Logical::NOT + OR | PHPExcel_Calculation_Logical::LOGICAL_OR + TRUE | PHPExcel_Calculation_Logical::TRUE ## CATEGORY_LOOKUP_AND_REFERENCE Excel Function | PHPExcel Function ------------------------|------------------------------------------- - ADDRESS PHPExcel_Calculation_LookupRef::CELL_ADDRESS - AREAS *** Not yet Implemented - CHOOSE PHPExcel_Calculation_LookupRef::CHOOSE - COLUMN PHPExcel_Calculation_LookupRef::COLUMN - COLUMNS PHPExcel_Calculation_LookupRef::COLUMNS - GETPIVOTDATA *** Not yet Implemented - HLOOKUP *** Not yet Implemented - HYPERLINK PHPExcel_Calculation_LookupRef::HYPERLINK - INDEX PHPExcel_Calculation_LookupRef::INDEX - INDIRECT PHPExcel_Calculation_LookupRef::INDIRECT - LOOKUP PHPExcel_Calculation_LookupRef::LOOKUP - MATCH PHPExcel_Calculation_LookupRef::MATCH - OFFSET PHPExcel_Calculation_LookupRef::OFFSET - ROW PHPExcel_Calculation_LookupRef::ROW - ROWS PHPExcel_Calculation_LookupRef::ROWS - RTD *** Not yet Implemented - TRANSPOSE PHPExcel_Calculation_LookupRef::TRANSPOSE - VLOOKUP PHPExcel_Calculation_LookupRef::VLOOKUP + ADDRESS | PHPExcel_Calculation_LookupRef::CELL_ADDRESS + AREAS | *** Not yet Implemented + CHOOSE | PHPExcel_Calculation_LookupRef::CHOOSE + COLUMN | PHPExcel_Calculation_LookupRef::COLUMN + COLUMNS | PHPExcel_Calculation_LookupRef::COLUMNS + GETPIVOTDATA | *** Not yet Implemented + HLOOKUP | *** Not yet Implemented + HYPERLINK | PHPExcel_Calculation_LookupRef::HYPERLINK + INDEX | PHPExcel_Calculation_LookupRef::INDEX + INDIRECT | PHPExcel_Calculation_LookupRef::INDIRECT + LOOKUP | PHPExcel_Calculation_LookupRef::LOOKUP + MATCH | PHPExcel_Calculation_LookupRef::MATCH + OFFSET | PHPExcel_Calculation_LookupRef::OFFSET + ROW | PHPExcel_Calculation_LookupRef::ROW + ROWS | PHPExcel_Calculation_LookupRef::ROWS + RTD | *** Not yet Implemented + TRANSPOSE | PHPExcel_Calculation_LookupRef::TRANSPOSE + VLOOKUP | PHPExcel_Calculation_LookupRef::VLOOKUP ## CATEGORY_MATH_AND_TRIG Excel Function | PHPExcel Function ------------------------|------------------------------------------- - ABS abs - ACOS acos - ACOSH acosh - ASIN asin - ASINH asinh - ATAN atan - ATAN2 PHPExcel_Calculation_MathTrig::REVERSE_ATAN2 - ATANH atanh - CEILING PHPExcel_Calculation_MathTrig::CEILING - COMBIN PHPExcel_Calculation_MathTrig::COMBIN - COS cos - COSH cosh - DEGREES rad2deg - EVEN PHPExcel_Calculation_MathTrig::EVEN - EXP exp - FACT PHPExcel_Calculation_MathTrig::FACT - FACTDOUBLE PHPExcel_Calculation_MathTrig::FACTDOUBLE - FLOOR PHPExcel_Calculation_MathTrig::FLOOR - GCD PHPExcel_Calculation_MathTrig::GCD - INT PHPExcel_Calculation_MathTrig::INT - LCM PHPExcel_Calculation_MathTrig::LCM - LN log - LOG PHPExcel_Calculation_MathTrig::LOG_BASE - LOG10 log10 - MDETERM PHPExcel_Calculation_MathTrig::MDETERM - MINVERSE PHPExcel_Calculation_MathTrig::MINVERSE - MMULT PHPExcel_Calculation_MathTrig::MMULT - MOD PHPExcel_Calculation_MathTrig::MOD - MROUND PHPExcel_Calculation_MathTrig::MROUND - MULTINOMIAL PHPExcel_Calculation_MathTrig::MULTINOMIAL - ODD PHPExcel_Calculation_MathTrig::ODD - PI pi - POWER PHPExcel_Calculation_MathTrig::POWER - PRODUCT PHPExcel_Calculation_MathTrig::PRODUCT - QUOTIENT PHPExcel_Calculation_MathTrig::QUOTIENT - RADIANS deg2rad - RAND PHPExcel_Calculation_MathTrig::RAND - RANDBETWEEN PHPExcel_Calculation_MathTrig::RAND - ROMAN PHPExcel_Calculation_MathTrig::ROMAN - ROUND round - ROUNDDOWN PHPExcel_Calculation_MathTrig::ROUNDDOWN - ROUNDUP PHPExcel_Calculation_MathTrig::ROUNDUP - SERIESSUM PHPExcel_Calculation_MathTrig::SERIESSUM - SIGN PHPExcel_Calculation_MathTrig::SIGN - SIN sin - SINH sinh - SQRT sqrt - SQRTPI PHPExcel_Calculation_MathTrig::SQRTPI - SUBTOTAL PHPExcel_Calculation_MathTrig::SUBTOTAL - SUM PHPExcel_Calculation_MathTrig::SUM - SUMIF PHPExcel_Calculation_MathTrig::SUMIF - SUMIFS *** Not yet Implemented - SUMPRODUCT PHPExcel_Calculation_MathTrig::SUMPRODUCT - SUMSQ PHPExcel_Calculation_MathTrig::SUMSQ - SUMX2MY2 PHPExcel_Calculation_MathTrig::SUMX2MY2 - SUMX2PY2 PHPExcel_Calculation_MathTrig::SUMX2PY2 - SUMXMY2 PHPExcel_Calculation_MathTrig::SUMXMY2 - TAN tan - TANH tanh - TRUNC PHPExcel_Calculation_MathTrig::TRUNC + ABS | abs + ACOS | acos + ACOSH | acosh + ASIN | asin + ASINH | asinh + ATAN | atan + ATAN2 | PHPExcel_Calculation_MathTrig::REVERSE_ATAN2 + ATANH | atanh + CEILING | PHPExcel_Calculation_MathTrig::CEILING + COMBIN | PHPExcel_Calculation_MathTrig::COMBIN + COS | cos + COSH | cosh + DEGREES | rad2deg + EVEN | PHPExcel_Calculation_MathTrig::EVEN + EXP | exp + FACT | PHPExcel_Calculation_MathTrig::FACT + FACTDOUBLE | PHPExcel_Calculation_MathTrig::FACTDOUBLE + FLOOR | PHPExcel_Calculation_MathTrig::FLOOR + GCD | PHPExcel_Calculation_MathTrig::GCD + INT | PHPExcel_Calculation_MathTrig::INT + LCM | PHPExcel_Calculation_MathTrig::LCM + LN | log + LOG | PHPExcel_Calculation_MathTrig::LOG_BASE + LOG10 | log10 + MDETERM | PHPExcel_Calculation_MathTrig::MDETERM + MINVERSE | PHPExcel_Calculation_MathTrig::MINVERSE + MMULT | PHPExcel_Calculation_MathTrig::MMULT + MOD | PHPExcel_Calculation_MathTrig::MOD + MROUND | PHPExcel_Calculation_MathTrig::MROUND + MULTINOMIAL | PHPExcel_Calculation_MathTrig::MULTINOMIAL + ODD | PHPExcel_Calculation_MathTrig::ODD + PI | pi + POWER | PHPExcel_Calculation_MathTrig::POWER + PRODUCT | PHPExcel_Calculation_MathTrig::PRODUCT + QUOTIENT | PHPExcel_Calculation_MathTrig::QUOTIENT + RADIANS | deg2rad + RAND | PHPExcel_Calculation_MathTrig::RAND + RANDBETWEEN | PHPExcel_Calculation_MathTrig::RAND + ROMAN | PHPExcel_Calculation_MathTrig::ROMAN + ROUND | round + ROUNDDOWN | PHPExcel_Calculation_MathTrig::ROUNDDOWN + ROUNDUP | PHPExcel_Calculation_MathTrig::ROUNDUP + SERIESSUM | PHPExcel_Calculation_MathTrig::SERIESSUM + SIGN | PHPExcel_Calculation_MathTrig::SIGN + SIN | sin + SINH | sinh + SQRT | sqrt + SQRTPI | PHPExcel_Calculation_MathTrig::SQRTPI + SUBTOTAL | PHPExcel_Calculation_MathTrig::SUBTOTAL + SUM | PHPExcel_Calculation_MathTrig::SUM + SUMIF | PHPExcel_Calculation_MathTrig::SUMIF + SUMIFS | *** Not yet Implemented + SUMPRODUCT | PHPExcel_Calculation_MathTrig::SUMPRODUCT + SUMSQ | PHPExcel_Calculation_MathTrig::SUMSQ + SUMX2MY2 | PHPExcel_Calculation_MathTrig::SUMX2MY2 + SUMX2PY2 | PHPExcel_Calculation_MathTrig::SUMX2PY2 + SUMXMY2 | PHPExcel_Calculation_MathTrig::SUMXMY2 + TAN | tan + TANH | tanh + TRUNC | PHPExcel_Calculation_MathTrig::TRUNC ## CATEGORY_STATISTICAL Excel Function | PHPExcel Function ------------------------|------------------------------------------- - AVEDEV PHPExcel_Calculation_Statistical::AVEDEV - AVERAGE PHPExcel_Calculation_Statistical::AVERAGE - AVERAGEA PHPExcel_Calculation_Statistical::AVERAGEA - AVERAGEIF PHPExcel_Calculation_Statistical::AVERAGEIF - AVERAGEIFS *** Not yet Implemented - BETADIST PHPExcel_Calculation_Statistical::BETADIST - BETAINV PHPExcel_Calculation_Statistical::BETAINV - BINOMDIST PHPExcel_Calculation_Statistical::BINOMDIST - CHIDIST PHPExcel_Calculation_Statistical::CHIDIST - CHIINV PHPExcel_Calculation_Statistical::CHIINV - CHITEST *** Not yet Implemented - CONFIDENCE PHPExcel_Calculation_Statistical::CONFIDENCE - CORREL PHPExcel_Calculation_Statistical::CORREL - COUNT PHPExcel_Calculation_Statistical::COUNT - COUNTA PHPExcel_Calculation_Statistical::COUNTA - COUNTBLANK PHPExcel_Calculation_Statistical::COUNTBLANK - COUNTIF PHPExcel_Calculation_Statistical::COUNTIF - COUNTIFS *** Not yet Implemented - COVAR PHPExcel_Calculation_Statistical::COVAR - CRITBINOM PHPExcel_Calculation_Statistical::CRITBINOM - DEVSQ PHPExcel_Calculation_Statistical::DEVSQ - EXPONDIST PHPExcel_Calculation_Statistical::EXPONDIST - FDIST *** Not yet Implemented - FINV *** Not yet Implemented - FISHER PHPExcel_Calculation_Statistical::FISHER - FISHERINV PHPExcel_Calculation_Statistical::FISHERINV - FORECAST PHPExcel_Calculation_Statistical::FORECAST - FREQUENCY *** Not yet Implemented - FTEST *** Not yet Implemented - GAMMADIST PHPExcel_Calculation_Statistical::GAMMADIST - GAMMAINV PHPExcel_Calculation_Statistical::GAMMAINV - GAMMALN PHPExcel_Calculation_Statistical::GAMMALN - GEOMEAN PHPExcel_Calculation_Statistical::GEOMEAN - GROWTH PHPExcel_Calculation_Statistical::GROWTH - HARMEAN PHPExcel_Calculation_Statistical::HARMEAN - HYPGEOMDIST PHPExcel_Calculation_Statistical::HYPGEOMDIST - INTERCEPT PHPExcel_Calculation_Statistical::INTERCEPT - KURT PHPExcel_Calculation_Statistical::KURT - LARGE PHPExcel_Calculation_Statistical::LARGE - LINEST PHPExcel_Calculation_Statistical::LINEST - LOGEST PHPExcel_Calculation_Statistical::LOGEST - LOGINV PHPExcel_Calculation_Statistical::LOGINV - LOGNORMDIST PHPExcel_Calculation_Statistical::LOGNORMDIST - MAX PHPExcel_Calculation_Statistical::MAX - MAXA PHPExcel_Calculation_Statistical::MAXA - MAXIF PHPExcel_Calculation_Statistical::MAXIF - MEDIAN PHPExcel_Calculation_Statistical::MEDIAN - MEDIANIF *** Not yet Implemented - MIN PHPExcel_Calculation_Statistical::MIN - MINA PHPExcel_Calculation_Statistical::MINA - MINIF PHPExcel_Calculation_Statistical::MINIF - MODE PHPExcel_Calculation_Statistical::MODE - NEGBINOMDIST PHPExcel_Calculation_Statistical::NEGBINOMDIST - NORMDIST PHPExcel_Calculation_Statistical::NORMDIST - NORMINV PHPExcel_Calculation_Statistical::NORMINV - NORMSDIST PHPExcel_Calculation_Statistical::NORMSDIST - NORMSINV PHPExcel_Calculation_Statistical::NORMSINV - PEARSON PHPExcel_Calculation_Statistical::CORREL - PERCENTILE PHPExcel_Calculation_Statistical::PERCENTILE - PERCENTRANK PHPExcel_Calculation_Statistical::PERCENTRANK - PERMUT PHPExcel_Calculation_Statistical::PERMUT - POISSON PHPExcel_Calculation_Statistical::POISSON - PROB *** Not yet Implemented - QUARTILE PHPExcel_Calculation_Statistical::QUARTILE - RANK PHPExcel_Calculation_Statistical::RANK - RSQ PHPExcel_Calculation_Statistical::RSQ - SKEW PHPExcel_Calculation_Statistical::SKEW - SLOPE PHPExcel_Calculation_Statistical::SLOPE - SMALL PHPExcel_Calculation_Statistical::SMALL - STANDARDIZE PHPExcel_Calculation_Statistical::STANDARDIZE - STDEV PHPExcel_Calculation_Statistical::STDEV - STDEVA PHPExcel_Calculation_Statistical::STDEVA - STDEVP PHPExcel_Calculation_Statistical::STDEVP - STDEVPA PHPExcel_Calculation_Statistical::STDEVPA - STEYX PHPExcel_Calculation_Statistical::STEYX - TDIST PHPExcel_Calculation_Statistical::TDIST - TINV PHPExcel_Calculation_Statistical::TINV - TREND PHPExcel_Calculation_Statistical::TREND - TRIMMEAN PHPExcel_Calculation_Statistical::TRIMMEAN - TTEST *** Not yet Implemented - VAR PHPExcel_Calculation_Statistical::VARFunc - VARA PHPExcel_Calculation_Statistical::VARA - VARP PHPExcel_Calculation_Statistical::VARP - VARPA PHPExcel_Calculation_Statistical::VARPA - WEIBULL PHPExcel_Calculation_Statistical::WEIBULL - ZTEST PHPExcel_Calculation_Statistical::ZTEST + AVEDEV | PHPExcel_Calculation_Statistical::AVEDEV + AVERAGE | PHPExcel_Calculation_Statistical::AVERAGE + AVERAGEA | PHPExcel_Calculation_Statistical::AVERAGEA + AVERAGEIF | PHPExcel_Calculation_Statistical::AVERAGEIF + AVERAGEIFS | *** Not yet Implemented + BETADIST | PHPExcel_Calculation_Statistical::BETADIST + BETAINV | PHPExcel_Calculation_Statistical::BETAINV + BINOMDIST | PHPExcel_Calculation_Statistical::BINOMDIST + CHIDIST | PHPExcel_Calculation_Statistical::CHIDIST + CHIINV | PHPExcel_Calculation_Statistical::CHIINV + CHITEST | *** Not yet Implemented + CONFIDENCE | PHPExcel_Calculation_Statistical::CONFIDENCE + CORREL | PHPExcel_Calculation_Statistical::CORREL + COUNT | PHPExcel_Calculation_Statistical::COUNT + COUNTA | PHPExcel_Calculation_Statistical::COUNTA + COUNTBLANK | PHPExcel_Calculation_Statistical::COUNTBLANK + COUNTIF | PHPExcel_Calculation_Statistical::COUNTIF + COUNTIFS | *** Not yet Implemented + COVAR | PHPExcel_Calculation_Statistical::COVAR + CRITBINOM | PHPExcel_Calculation_Statistical::CRITBINOM + DEVSQ | PHPExcel_Calculation_Statistical::DEVSQ + EXPONDIST | PHPExcel_Calculation_Statistical::EXPONDIST + FDIST | *** Not yet Implemented + FINV | *** Not yet Implemented + FISHER | PHPExcel_Calculation_Statistical::FISHER + FISHERINV | PHPExcel_Calculation_Statistical::FISHERINV + FORECAST | PHPExcel_Calculation_Statistical::FORECAST + FREQUENCY | *** Not yet Implemented + FTEST | *** Not yet Implemented + GAMMADIST | PHPExcel_Calculation_Statistical::GAMMADIST + GAMMAINV | PHPExcel_Calculation_Statistical::GAMMAINV + GAMMALN | PHPExcel_Calculation_Statistical::GAMMALN + GEOMEAN | PHPExcel_Calculation_Statistical::GEOMEAN + GROWTH | PHPExcel_Calculation_Statistical::GROWTH + HARMEAN | PHPExcel_Calculation_Statistical::HARMEAN + HYPGEOMDIST | PHPExcel_Calculation_Statistical::HYPGEOMDIST + INTERCEPT | PHPExcel_Calculation_Statistical::INTERCEPT + KURT | PHPExcel_Calculation_Statistical::KURT + LARGE | PHPExcel_Calculation_Statistical::LARGE + LINEST | PHPExcel_Calculation_Statistical::LINEST + LOGEST | PHPExcel_Calculation_Statistical::LOGEST + LOGINV | PHPExcel_Calculation_Statistical::LOGINV + LOGNORMDIST | PHPExcel_Calculation_Statistical::LOGNORMDIST + MAX | PHPExcel_Calculation_Statistical::MAX + MAXA | PHPExcel_Calculation_Statistical::MAXA + MAXIF | PHPExcel_Calculation_Statistical::MAXIF + MEDIAN | PHPExcel_Calculation_Statistical::MEDIAN + MEDIANIF | *** Not yet Implemented + MIN | PHPExcel_Calculation_Statistical::MIN + MINA | PHPExcel_Calculation_Statistical::MINA + MINIF | PHPExcel_Calculation_Statistical::MINIF + MODE | PHPExcel_Calculation_Statistical::MODE + NEGBINOMDIST | PHPExcel_Calculation_Statistical::NEGBINOMDIST + NORMDIST | PHPExcel_Calculation_Statistical::NORMDIST + NORMINV | PHPExcel_Calculation_Statistical::NORMINV + NORMSDIST | PHPExcel_Calculation_Statistical::NORMSDIST + NORMSINV | PHPExcel_Calculation_Statistical::NORMSINV + PEARSON | PHPExcel_Calculation_Statistical::CORREL + PERCENTILE | PHPExcel_Calculation_Statistical::PERCENTILE + PERCENTRANK | PHPExcel_Calculation_Statistical::PERCENTRANK + PERMUT | PHPExcel_Calculation_Statistical::PERMUT + POISSON | PHPExcel_Calculation_Statistical::POISSON + PROB | *** Not yet Implemented + QUARTILE | PHPExcel_Calculation_Statistical::QUARTILE + RANK | PHPExcel_Calculation_Statistical::RANK + RSQ | PHPExcel_Calculation_Statistical::RSQ + SKEW | PHPExcel_Calculation_Statistical::SKEW + SLOPE | PHPExcel_Calculation_Statistical::SLOPE + SMALL | PHPExcel_Calculation_Statistical::SMALL + STANDARDIZE | PHPExcel_Calculation_Statistical::STANDARDIZE + STDEV | PHPExcel_Calculation_Statistical::STDEV + STDEVA | PHPExcel_Calculation_Statistical::STDEVA + STDEVP | PHPExcel_Calculation_Statistical::STDEVP + STDEVPA | PHPExcel_Calculation_Statistical::STDEVPA + STEYX | PHPExcel_Calculation_Statistical::STEYX + TDIST | PHPExcel_Calculation_Statistical::TDIST + TINV | PHPExcel_Calculation_Statistical::TINV + TREND | PHPExcel_Calculation_Statistical::TREND + TRIMMEAN | PHPExcel_Calculation_Statistical::TRIMMEAN + TTEST | *** Not yet Implemented + VAR | PHPExcel_Calculation_Statistical::VARFunc + VARA | PHPExcel_Calculation_Statistical::VARA + VARP | PHPExcel_Calculation_Statistical::VARP + VARPA | PHPExcel_Calculation_Statistical::VARPA + WEIBULL | PHPExcel_Calculation_Statistical::WEIBULL + ZTEST | PHPExcel_Calculation_Statistical::ZTEST ## CATEGORY_TEXT_AND_DATA Excel Function | PHPExcel Function ------------------------|------------------------------------------- - ASC *** Not yet Implemented - BAHTTEXT *** Not yet Implemented - CHAR PHPExcel_Calculation_TextData::CHARACTER - CLEAN PHPExcel_Calculation_TextData::TRIMNONPRINTABLE - CODE PHPExcel_Calculation_TextData::ASCIICODE - CONCATENATE PHPExcel_Calculation_TextData::CONCATENATE - DOLLAR PHPExcel_Calculation_TextData::DOLLAR - EXACT *** Not yet Implemented - FIND PHPExcel_Calculation_TextData::SEARCHSENSITIVE - FINDB PHPExcel_Calculation_TextData::SEARCHSENSITIVE - FIXED PHPExcel_Calculation_TextData::FIXEDFORMAT - JIS *** Not yet Implemented - LEFT PHPExcel_Calculation_TextData::LEFT - LEFTB PHPExcel_Calculation_TextData::LEFT - LEN PHPExcel_Calculation_TextData::STRINGLENGTH - LENB PHPExcel_Calculation_TextData::STRINGLENGTH - LOWER PHPExcel_Calculation_TextData::LOWERCASE - MID PHPExcel_Calculation_TextData::MID - MIDB PHPExcel_Calculation_TextData::MID - PHONETIC *** Not yet Implemented - PROPER PHPExcel_Calculation_TextData::PROPERCASE - REPLACE PHPExcel_Calculation_TextData::REPLACE - REPLACEB PHPExcel_Calculation_TextData::REPLACE - REPT str_repeat - RIGHT PHPExcel_Calculation_TextData::RIGHT - RIGHTB PHPExcel_Calculation_TextData::RIGHT - SEARCH PHPExcel_Calculation_TextData::SEARCHINSENSITIVE - SEARCHB PHPExcel_Calculation_TextData::SEARCHINSENSITIVE - SUBSTITUTE PHPExcel_Calculation_TextData::SUBSTITUTE - T PHPExcel_Calculation_TextData::RETURNSTRING - TEXT PHPExcel_Calculation_TextData::TEXTFORMAT - TRIM PHPExcel_Calculation_TextData::TRIMSPACES - UPPER PHPExcel_Calculation_TextData::UPPERCASE - VALUE *** Not yet Implemented + ASC | *** Not yet Implemented + BAHTTEXT | *** Not yet Implemented + CHAR | PHPExcel_Calculation_TextData::CHARACTER + CLEAN | PHPExcel_Calculation_TextData::TRIMNONPRINTABLE + CODE | PHPExcel_Calculation_TextData::ASCIICODE + CONCATENATE | PHPExcel_Calculation_TextData::CONCATENATE + DOLLAR | PHPExcel_Calculation_TextData::DOLLAR + EXACT | *** Not yet Implemented + FIND | PHPExcel_Calculation_TextData::SEARCHSENSITIVE + FINDB | PHPExcel_Calculation_TextData::SEARCHSENSITIVE + FIXED | PHPExcel_Calculation_TextData::FIXEDFORMAT + JIS | *** Not yet Implemented + LEFT | PHPExcel_Calculation_TextData::LEFT + LEFTB | PHPExcel_Calculation_TextData::LEFT + LEN | PHPExcel_Calculation_TextData::STRINGLENGTH + LENB | PHPExcel_Calculation_TextData::STRINGLENGTH + LOWER | PHPExcel_Calculation_TextData::LOWERCASE + MID | PHPExcel_Calculation_TextData::MID + MIDB | PHPExcel_Calculation_TextData::MID + PHONETIC | *** Not yet Implemented + PROPER | PHPExcel_Calculation_TextData::PROPERCASE + REPLACE | PHPExcel_Calculation_TextData::REPLACE + REPLACEB | PHPExcel_Calculation_TextData::REPLACE + REPT | str_repeat + RIGHT | PHPExcel_Calculation_TextData::RIGHT + RIGHTB | PHPExcel_Calculation_TextData::RIGHT + SEARCH | PHPExcel_Calculation_TextData::SEARCHINSENSITIVE + SEARCHB | PHPExcel_Calculation_TextData::SEARCHINSENSITIVE + SUBSTITUTE | PHPExcel_Calculation_TextData::SUBSTITUTE + T | PHPExcel_Calculation_TextData::RETURNSTRING + TEXT | PHPExcel_Calculation_TextData::TEXTFORMAT + TRIM | PHPExcel_Calculation_TextData::TRIMSPACES + UPPER | PHPExcel_Calculation_TextData::UPPERCASE + VALUE | *** Not yet Implemented + diff --git a/Documentation/markdown/Functions/FunctionListByName.md b/Documentation/markdown/Functions/FunctionListByName.md index 082c83af0..e16114b50 100644 --- a/Documentation/markdown/Functions/FunctionListByName.md +++ b/Documentation/markdown/Functions/FunctionListByName.md @@ -1,78 +1,84 @@ -ABS CATEGORY_MATH_AND_TRIG abs -ACCRINT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::ACCRINT -ACCRINTM CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::ACCRINTM -ACOS CATEGORY_MATH_AND_TRIG acos -ACOSH CATEGORY_MATH_AND_TRIG acosh -ADDRESS CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::CELL_ADDRESS -AMORDEGRC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::AMORDEGRC -AMORLINC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::AMORLINC -AND CATEGORY_LOGICAL PHPExcel_Calculation_Logical::LOGICAL_AND -AREAS CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented -ASC CATEGORY_TEXT_AND_DATA *** Not yet Implemented -ASIN CATEGORY_MATH_AND_TRIG asin -ASINH CATEGORY_MATH_AND_TRIG asinh -ATAN CATEGORY_MATH_AND_TRIG atan -ATAN2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::REVERSE_ATAN2 -ATANH CATEGORY_MATH_AND_TRIG atanh -AVEDEV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVEDEV -AVERAGE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVERAGE -AVERAGEA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVERAGEA -AVERAGEIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::AVERAGEIF -AVERAGEIFS CATEGORY_STATISTICAL *** Not yet Implemented + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + ABS | CATEGORY_MATH_AND_TRIG | abs + ACCRINT | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::ACCRINT + ACCRINTM | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::ACCRINTM + ACOS | CATEGORY_MATH_AND_TRIG | acos + ACOSH | CATEGORY_MATH_AND_TRIG | acosh + ADDRESS | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::CELL_ADDRESS + AMORDEGRC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::AMORDEGRC + AMORLINC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::AMORLINC + AND | CATEGORY_LOGICAL | PHPExcel_Calculation_Logical::LOGICAL_AND + AREAS | CATEGORY_LOOKUP_AND_REFERENCE | *** Not yet Implemented + ASC | CATEGORY_TEXT_AND_DATA | *** Not yet Implemented + ASIN | CATEGORY_MATH_AND_TRIG | asin + ASINH | CATEGORY_MATH_AND_TRIG | asinh + ATAN | CATEGORY_MATH_AND_TRIG | atan + ATAN2 | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::REVERSE_ATAN2 + ATANH | CATEGORY_MATH_AND_TRIG | atanh + AVEDEV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::AVEDEV + AVERAGE | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::AVERAGE + AVERAGEA | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::AVERAGEA + AVERAGEIF | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::AVERAGEIF + AVERAGEIFS | CATEGORY_STATISTICAL | *** Not yet Implemented -BAHTTEXT CATEGORY_TEXT_AND_DATA *** Not yet Implemented -BESSELI CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELI -BESSELJ CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELJ -BESSELK CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELK -BESSELY CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BESSELY -BETADIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::BETADIST -BETAINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::BETAINV -BIN2DEC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BINTODEC -BIN2HEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BINTOHEX -BIN2OCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::BINTOOCT -BINOMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::BINOMDIST + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + BAHTTEXT | CATEGORY_TEXT_AND_DATA | *** Not yet Implemented + BESSELI | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BESSELI + BESSELJ | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BESSELJ + BESSELK | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BESSELK + BESSELY | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BESSELY + BETADIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::BETADIST + BETAINV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::BETAINV + BIN2DEC | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BINTODEC + BIN2HEX | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BINTOHEX + BIN2OCT | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BINTOOCT + BINOMDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::BINOMDIST -CEILING CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::CEILING -CELL CATEGORY_INFORMATION *** Not yet Implemented -CHAR CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::CHARACTER -CHIDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CHIDIST -CHIINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CHIINV -CHITEST CATEGORY_STATISTICAL *** Not yet Implemented -CHOOSE CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::CHOOSE -CLEAN CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::TRIMNONPRINTABLE -CODE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::ASCIICODE -COLUMN CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::COLUMN -COLUMNS CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::COLUMNS -COMBIN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::COMBIN -COMPLEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::COMPLEX -CONCATENATE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::CONCATENATE -CONFIDENCE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CONFIDENCE -CONVERT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::CONVERTUOM -CORREL CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CORREL -COS CATEGORY_MATH_AND_TRIG cos -COSH CATEGORY_MATH_AND_TRIG cosh -COUNT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNT -COUNTA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNTA -COUNTBLANK CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNTBLANK -COUNTIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COUNTIF -COUNTIFS CATEGORY_STATISTICAL *** Not yet Implemented -COUPDAYBS CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPDAYBS -COUPDAYS CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPDAYS -COUPDAYSNC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPDAYSNC -COUPNCD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPNCD -COUPNUM CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPNUM -COUPPCD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::COUPPCD -COVAR CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::COVAR -CRITBINOM CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CRITBINOM -CUBEKPIMEMBER CATEGORY_CUBE *** Not yet Implemented -CUBEMEMBER CATEGORY_CUBE *** Not yet Implemented -CUBEMEMBERPROPERTY CATEGORY_CUBE *** Not yet Implemented -CUBERANKEDMEMBER CATEGORY_CUBE *** Not yet Implemented -CUBESET CATEGORY_CUBE *** Not yet Implemented -CUBESETCOUNT CATEGORY_CUBE *** Not yet Implemented -CUBEVALUE CATEGORY_CUBE *** Not yet Implemented -CUMIPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::CUMIPMT -CUMPRINC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::CUMPRINC + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + CEILING | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::CEILING + CELL | CATEGORY_INFORMATION | *** Not yet Implemented + CHAR | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::CHARACTER + CHIDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::CHIDIST + CHIINV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::CHIINV + CHITEST | CATEGORY_STATISTICAL | *** Not yet Implemented + CHOOSE | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::CHOOSE + CLEAN | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::TRIMNONPRINTABLE + CODE | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::ASCIICODE + COLUMN | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::COLUMN + COLUMNS | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::COLUMNS + COMBIN | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::COMBIN + COMPLEX | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::COMPLEX + CONCATENATE | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::CONCATENATE + CONFIDENCE | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::CONFIDENCE + CONVERT | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::CONVERTUOM + CORREL | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::CORREL + COS | CATEGORY_MATH_AND_TRIG | cos + COSH | CATEGORY_MATH_AND_TRIG | cosh + COUNT | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::COUNT + COUNTA | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::COUNTA + COUNTBLANK | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::COUNTBLANK + COUNTIF | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::COUNTIF + COUNTIFS | CATEGORY_STATISTICAL | *** Not yet Implemented + COUPDAYBS | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::COUPDAYBS + COUPDAYS | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::COUPDAYS + COUPDAYSNC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::COUPDAYSNC + COUPNCD | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::COUPNCD + COUPNUM | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::COUPNUM + COUPPCD | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::COUPPCD + COVAR | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::COVAR + CRITBINOM | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::CRITBINOM + CUBEKPIMEMBER | CATEGORY_CUBE | *** Not yet Implemented + CUBEMEMBER | CATEGORY_CUBE | *** Not yet Implemented + CUBEMEMBERPROPERTY | CATEGORY_CUBE | *** Not yet Implemented + CUBERANKEDMEMBER | CATEGORY_CUBE | *** Not yet Implemented + CUBESET | CATEGORY_CUBE | *** Not yet Implemented + CUBESETCOUNT | CATEGORY_CUBE | *** Not yet Implemented + CUBEVALUE | CATEGORY_CUBE | *** Not yet Implemented + CUMIPMT | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::CUMIPMT + CUMPRINC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::CUMPRINC DATE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATE DATEDIF CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATEDIF From 76534a7bfcb74f88fd0fc7ef226c37887aa24bbc Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 13 May 2013 17:10:06 +0100 Subject: [PATCH 068/467] documentation markdown --- .../Features/Autofilters/01-Autofilters.md | 2 +- .../Autofilters/03-Autofilter-Expressions.md | 3 +- .../Functions/FunctionListByCategory.md | 756 +++++++++--------- .../markdown/Functions/FunctionListByName.md | 738 +++++++++-------- 4 files changed, 799 insertions(+), 700 deletions(-) diff --git a/Documentation/markdown/Features/Autofilters/01-Autofilters.md b/Documentation/markdown/Features/Autofilters/01-Autofilters.md index 0f11d53cc..c2fbd2fa8 100644 --- a/Documentation/markdown/Features/Autofilters/01-Autofilters.md +++ b/Documentation/markdown/Features/Autofilters/01-Autofilters.md @@ -14,6 +14,6 @@ To determine if a filter is applied, note the icon in the column heading. A drop ![01-02-autofilter.png](./images/01-02-autofilter.png "") -A Filter button (![01-03-filter-icon-2.png](./images/01-03-filter-icon-2.png "")) means that a filter is applied. When you hover over the heading of a filtered column, a screen tip displays the filter applied to that column, such as "Equals a red cell color" or "Larger than 150". +A Filter button (![01-03-filter-icon-2.png](./images/01-03-filter-icon-2.png "")) means that a filter is applied. When you hover over the heading of a filtered column, a screen tip displays the filter that has been applied to that column, such as "Equals a red cell color" or "Larger than 150". ![01-04-autofilter.png](./images/01-04-autofilter.png "") diff --git a/Documentation/markdown/Features/Autofilters/03-Autofilter-Expressions.md b/Documentation/markdown/Features/Autofilters/03-Autofilter-Expressions.md index dae24b4f6..fd6590175 100644 --- a/Documentation/markdown/Features/Autofilters/03-Autofilter-Expressions.md +++ b/Documentation/markdown/Features/Autofilters/03-Autofilter-Expressions.md @@ -12,7 +12,7 @@ $autoFilter = $objPHPExcel->getActiveSheet()->getAutoFilter(); $columnFilter = $autoFilter->getColumn('C'); ``` -This returns an autoFilter column object, and you can then apply filters to that column. +This returns an autoFilter column object, and you can then apply filter expressions to that column. There are a number of different types of autofilter expressions. The most commonly used are: @@ -24,3 +24,4 @@ There are a number of different types of autofilter expressions. The most common These different types are mutually exclusive within any single column. You should not mix the different types of filter in the same column. PHPExcel will not actively prevent you from doing this, but the results are unpredictable. +Other filter expression types (such as cell colour filters) are not yet supported. diff --git a/Documentation/markdown/Functions/FunctionListByCategory.md b/Documentation/markdown/Functions/FunctionListByCategory.md index ff765dc7f..4ceb1e476 100644 --- a/Documentation/markdown/Functions/FunctionListByCategory.md +++ b/Documentation/markdown/Functions/FunctionListByCategory.md @@ -1,411 +1,411 @@ ## CATEGORY_CUBE - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - CUBEKPIMEMBER | *** Not yet Implemented - CUBEMEMBER | *** Not yet Implemented - CUBEMEMBERPROPERTY | *** Not yet Implemented - CUBERANKEDMEMBER | *** Not yet Implemented - CUBESET | *** Not yet Implemented - CUBESETCOUNT | *** Not yet Implemented - CUBEVALUE | *** Not yet Implemented + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + CUBEKPIMEMBER | **\*\*\* Not yet Implemented** + CUBEMEMBER | **\*\*\* Not yet Implemented** + CUBEMEMBERPROPERTY | **\*\*\* Not yet Implemented** + CUBERANKEDMEMBER | **\*\*\* Not yet Implemented** + CUBESET | **\*\*\* Not yet Implemented** + CUBESETCOUNT | **\*\*\* Not yet Implemented** + CUBEVALUE | **\*\*\* Not yet Implemented** ## CATEGORY_DATABASE - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - DAVERAGE | PHPExcel_Calculation_Database::DAVERAGE - DCOUNT | PHPExcel_Calculation_Database::DCOUNT - DCOUNTA | PHPExcel_Calculation_Database::DCOUNTA - DGET | PHPExcel_Calculation_Database::DGET - DMAX | PHPExcel_Calculation_Database::DMAX - DMIN | PHPExcel_Calculation_Database::DMIN - DPRODUCT | PHPExcel_Calculation_Database::DPRODUCT - DSTDEV | PHPExcel_Calculation_Database::DSTDEV - DSTDEVP | PHPExcel_Calculation_Database::DSTDEVP - DSUM | PHPExcel_Calculation_Database::DSUM - DVAR | PHPExcel_Calculation_Database::DVAR - DVARP | PHPExcel_Calculation_Database::DVARP + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + DAVERAGE | PHPExcel_Calculation_Database::DAVERAGE + DCOUNT | PHPExcel_Calculation_Database::DCOUNT + DCOUNTA | PHPExcel_Calculation_Database::DCOUNTA + DGET | PHPExcel_Calculation_Database::DGET + DMAX | PHPExcel_Calculation_Database::DMAX + DMIN | PHPExcel_Calculation_Database::DMIN + DPRODUCT | PHPExcel_Calculation_Database::DPRODUCT + DSTDEV | PHPExcel_Calculation_Database::DSTDEV + DSTDEVP | PHPExcel_Calculation_Database::DSTDEVP + DSUM | PHPExcel_Calculation_Database::DSUM + DVAR | PHPExcel_Calculation_Database::DVAR + DVARP | PHPExcel_Calculation_Database::DVARP ## CATEGORY_DATE_AND_TIME - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - DATE | PHPExcel_Calculation_DateTime::DATE - DATEDIF | PHPExcel_Calculation_DateTime::DATEDIF - DATEVALUE | PHPExcel_Calculation_DateTime::DATEVALUE - DAY | PHPExcel_Calculation_DateTime::DAYOFMONTH - DAYS360 | PHPExcel_Calculation_DateTime::DAYS360 - EDATE | PHPExcel_Calculation_DateTime::EDATE - EOMONTH | PHPExcel_Calculation_DateTime::EOMONTH - HOUR | PHPExcel_Calculation_DateTime::HOUROFDAY - MINUTE | PHPExcel_Calculation_DateTime::MINUTEOFHOUR - MONTH | PHPExcel_Calculation_DateTime::MONTHOFYEAR - NETWORKDAYS | PHPExcel_Calculation_DateTime::NETWORKDAYS - NOW | PHPExcel_Calculation_DateTime::DATETIMENOW - SECOND | PHPExcel_Calculation_DateTime::SECONDOFMINUTE - TIME | PHPExcel_Calculation_DateTime::TIME - TIMEVALUE | PHPExcel_Calculation_DateTime::TIMEVALUE - TODAY | PHPExcel_Calculation_DateTime::DATENOW - WEEKDAY | PHPExcel_Calculation_DateTime::DAYOFWEEK - WEEKNUM | PHPExcel_Calculation_DateTime::WEEKOFYEAR - WORKDAY | PHPExcel_Calculation_DateTime::WORKDAY - YEAR | PHPExcel_Calculation_DateTime::YEAR - YEARFRAC | PHPExcel_Calculation_DateTime::YEARFRAC + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + DATE | PHPExcel_Calculation_DateTime::DATE + DATEDIF | PHPExcel_Calculation_DateTime::DATEDIF + DATEVALUE | PHPExcel_Calculation_DateTime::DATEVALUE + DAY | PHPExcel_Calculation_DateTime::DAYOFMONTH + DAYS360 | PHPExcel_Calculation_DateTime::DAYS360 + EDATE | PHPExcel_Calculation_DateTime::EDATE + EOMONTH | PHPExcel_Calculation_DateTime::EOMONTH + HOUR | PHPExcel_Calculation_DateTime::HOUROFDAY + MINUTE | PHPExcel_Calculation_DateTime::MINUTEOFHOUR + MONTH | PHPExcel_Calculation_DateTime::MONTHOFYEAR + NETWORKDAYS | PHPExcel_Calculation_DateTime::NETWORKDAYS + NOW | PHPExcel_Calculation_DateTime::DATETIMENOW + SECOND | PHPExcel_Calculation_DateTime::SECONDOFMINUTE + TIME | PHPExcel_Calculation_DateTime::TIME + TIMEVALUE | PHPExcel_Calculation_DateTime::TIMEVALUE + TODAY | PHPExcel_Calculation_DateTime::DATENOW + WEEKDAY | PHPExcel_Calculation_DateTime::DAYOFWEEK + WEEKNUM | PHPExcel_Calculation_DateTime::WEEKOFYEAR + WORKDAY | PHPExcel_Calculation_DateTime::WORKDAY + YEAR | PHPExcel_Calculation_DateTime::YEAR + YEARFRAC | PHPExcel_Calculation_DateTime::YEARFRAC ## CATEGORY_ENGINEERING - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - BESSELI | PHPExcel_Calculation_Engineering::BESSELI - BESSELJ | PHPExcel_Calculation_Engineering::BESSELJ - BESSELK | PHPExcel_Calculation_Engineering::BESSELK - BESSELY | PHPExcel_Calculation_Engineering::BESSELY - BIN2DEC | PHPExcel_Calculation_Engineering::BINTODEC - BIN2HEX | PHPExcel_Calculation_Engineering::BINTOHEX - BIN2OCT | PHPExcel_Calculation_Engineering::BINTOOCT - COMPLEX | PHPExcel_Calculation_Engineering::COMPLEX - CONVERT | PHPExcel_Calculation_Engineering::CONVERTUOM - DEC2BIN | PHPExcel_Calculation_Engineering::DECTOBIN - DEC2HEX | PHPExcel_Calculation_Engineering::DECTOHEX - DEC2OCT | PHPExcel_Calculation_Engineering::DECTOOCT - DELTA | PHPExcel_Calculation_Engineering::DELTA - ERF | PHPExcel_Calculation_Engineering::ERF - ERFC | PHPExcel_Calculation_Engineering::ERFC - GESTEP | PHPExcel_Calculation_Engineering::GESTEP - HEX2BIN | PHPExcel_Calculation_Engineering::HEXTOBIN - HEX2DEC | PHPExcel_Calculation_Engineering::HEXTODEC - HEX2OCT | PHPExcel_Calculation_Engineering::HEXTOOCT - IMABS | PHPExcel_Calculation_Engineering::IMABS - IMAGINARY | PHPExcel_Calculation_Engineering::IMAGINARY - IMARGUMENT | PHPExcel_Calculation_Engineering::IMARGUMENT - IMCONJUGATE | PHPExcel_Calculation_Engineering::IMCONJUGATE - IMCOS | PHPExcel_Calculation_Engineering::IMCOS - IMDIV | PHPExcel_Calculation_Engineering::IMDIV - IMEXP | PHPExcel_Calculation_Engineering::IMEXP - IMLN | PHPExcel_Calculation_Engineering::IMLN - IMLOG10 | PHPExcel_Calculation_Engineering::IMLOG10 - IMLOG2 | PHPExcel_Calculation_Engineering::IMLOG2 - IMPOWER | PHPExcel_Calculation_Engineering::IMPOWER - IMPRODUCT | PHPExcel_Calculation_Engineering::IMPRODUCT - IMREAL | PHPExcel_Calculation_Engineering::IMREAL - IMSIN | PHPExcel_Calculation_Engineering::IMSIN - IMSQRT | PHPExcel_Calculation_Engineering::IMSQRT - IMSUB | PHPExcel_Calculation_Engineering::IMSUB - IMSUM | PHPExcel_Calculation_Engineering::IMSUM - OCT2BIN | PHPExcel_Calculation_Engineering::OCTTOBIN - OCT2DEC | PHPExcel_Calculation_Engineering::OCTTODEC - OCT2HEX | PHPExcel_Calculation_Engineering::OCTTOHEX + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + BESSELI | PHPExcel_Calculation_Engineering::BESSELI + BESSELJ | PHPExcel_Calculation_Engineering::BESSELJ + BESSELK | PHPExcel_Calculation_Engineering::BESSELK + BESSELY | PHPExcel_Calculation_Engineering::BESSELY + BIN2DEC | PHPExcel_Calculation_Engineering::BINTODEC + BIN2HEX | PHPExcel_Calculation_Engineering::BINTOHEX + BIN2OCT | PHPExcel_Calculation_Engineering::BINTOOCT + COMPLEX | PHPExcel_Calculation_Engineering::COMPLEX + CONVERT | PHPExcel_Calculation_Engineering::CONVERTUOM + DEC2BIN | PHPExcel_Calculation_Engineering::DECTOBIN + DEC2HEX | PHPExcel_Calculation_Engineering::DECTOHEX + DEC2OCT | PHPExcel_Calculation_Engineering::DECTOOCT + DELTA | PHPExcel_Calculation_Engineering::DELTA + ERF | PHPExcel_Calculation_Engineering::ERF + ERFC | PHPExcel_Calculation_Engineering::ERFC + GESTEP | PHPExcel_Calculation_Engineering::GESTEP + HEX2BIN | PHPExcel_Calculation_Engineering::HEXTOBIN + HEX2DEC | PHPExcel_Calculation_Engineering::HEXTODEC + HEX2OCT | PHPExcel_Calculation_Engineering::HEXTOOCT + IMABS | PHPExcel_Calculation_Engineering::IMABS + IMAGINARY | PHPExcel_Calculation_Engineering::IMAGINARY + IMARGUMENT | PHPExcel_Calculation_Engineering::IMARGUMENT + IMCONJUGATE | PHPExcel_Calculation_Engineering::IMCONJUGATE + IMCOS | PHPExcel_Calculation_Engineering::IMCOS + IMDIV | PHPExcel_Calculation_Engineering::IMDIV + IMEXP | PHPExcel_Calculation_Engineering::IMEXP + IMLN | PHPExcel_Calculation_Engineering::IMLN + IMLOG10 | PHPExcel_Calculation_Engineering::IMLOG10 + IMLOG2 | PHPExcel_Calculation_Engineering::IMLOG2 + IMPOWER | PHPExcel_Calculation_Engineering::IMPOWER + IMPRODUCT | PHPExcel_Calculation_Engineering::IMPRODUCT + IMREAL | PHPExcel_Calculation_Engineering::IMREAL + IMSIN | PHPExcel_Calculation_Engineering::IMSIN + IMSQRT | PHPExcel_Calculation_Engineering::IMSQRT + IMSUB | PHPExcel_Calculation_Engineering::IMSUB + IMSUM | PHPExcel_Calculation_Engineering::IMSUM + OCT2BIN | PHPExcel_Calculation_Engineering::OCTTOBIN + OCT2DEC | PHPExcel_Calculation_Engineering::OCTTODEC + OCT2HEX | PHPExcel_Calculation_Engineering::OCTTOHEX ## CATEGORY_FINANCIAL - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - ACCRINT | PHPExcel_Calculation_Financial::ACCRINT - ACCRINTM | PHPExcel_Calculation_Financial::ACCRINTM - AMORDEGRC | PHPExcel_Calculation_Financial::AMORDEGRC - AMORLINC | PHPExcel_Calculation_Financial::AMORLINC - COUPDAYBS | PHPExcel_Calculation_Financial::COUPDAYBS - COUPDAYS | PHPExcel_Calculation_Financial::COUPDAYS - COUPDAYSNC | PHPExcel_Calculation_Financial::COUPDAYSNC - COUPNCD | PHPExcel_Calculation_Financial::COUPNCD - COUPNUM | PHPExcel_Calculation_Financial::COUPNUM - COUPPCD | PHPExcel_Calculation_Financial::COUPPCD - CUMIPMT | PHPExcel_Calculation_Financial::CUMIPMT - CUMPRINC | PHPExcel_Calculation_Financial::CUMPRINC - DB | PHPExcel_Calculation_Financial::DB - DDB | PHPExcel_Calculation_Financial::DDB - DISC | PHPExcel_Calculation_Financial::DISC - DOLLARDE | PHPExcel_Calculation_Financial::DOLLARDE - DOLLARFR | PHPExcel_Calculation_Financial::DOLLARFR - DURATION | *** Not yet Implemented - EFFECT | PHPExcel_Calculation_Financial::EFFECT - FV | PHPExcel_Calculation_Financial::FV - FVSCHEDULE | PHPExcel_Calculation_Financial::FVSCHEDULE - INTRATE | PHPExcel_Calculation_Financial::INTRATE - IPMT | PHPExcel_Calculation_Financial::IPMT - IRR | PHPExcel_Calculation_Financial::IRR - ISPMT | PHPExcel_Calculation_Financial::ISPMT - MDURATION | *** Not yet Implemented - MIRR | PHPExcel_Calculation_Financial::MIRR - NOMINAL | PHPExcel_Calculation_Financial::NOMINAL - NPER | PHPExcel_Calculation_Financial::NPER - NPV | PHPExcel_Calculation_Financial::NPV - ODDFPRICE | *** Not yet Implemented - ODDFYIELD | *** Not yet Implemented - ODDLPRICE | *** Not yet Implemented - ODDLYIELD | *** Not yet Implemented - PMT | PHPExcel_Calculation_Financial::PMT - PPMT | PHPExcel_Calculation_Financial::PPMT - PRICE | PHPExcel_Calculation_Financial::PRICE - PRICEDISC | PHPExcel_Calculation_Financial::PRICEDISC - PRICEMAT | PHPExcel_Calculation_Financial::PRICEMAT - PV | PHPExcel_Calculation_Financial::PV - RATE | PHPExcel_Calculation_Financial::RATE - RECEIVED | PHPExcel_Calculation_Financial::RECEIVED - SLN | PHPExcel_Calculation_Financial::SLN - SYD | PHPExcel_Calculation_Financial::SYD - TBILLEQ | PHPExcel_Calculation_Financial::TBILLEQ - TBILLPRICE | PHPExcel_Calculation_Financial::TBILLPRICE - TBILLYIELD | PHPExcel_Calculation_Financial::TBILLYIELD - USDOLLAR | *** Not yet Implemented - VDB | *** Not yet Implemented - XIRR | PHPExcel_Calculation_Financial::XIRR - XNPV | PHPExcel_Calculation_Financial::XNPV - YIELD | *** Not yet Implemented - YIELDDISC | PHPExcel_Calculation_Financial::YIELDDISC - YIELDMAT | PHPExcel_Calculation_Financial::YIELDMAT + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + ACCRINT | PHPExcel_Calculation_Financial::ACCRINT + ACCRINTM | PHPExcel_Calculation_Financial::ACCRINTM + AMORDEGRC | PHPExcel_Calculation_Financial::AMORDEGRC + AMORLINC | PHPExcel_Calculation_Financial::AMORLINC + COUPDAYBS | PHPExcel_Calculation_Financial::COUPDAYBS + COUPDAYS | PHPExcel_Calculation_Financial::COUPDAYS + COUPDAYSNC | PHPExcel_Calculation_Financial::COUPDAYSNC + COUPNCD | PHPExcel_Calculation_Financial::COUPNCD + COUPNUM | PHPExcel_Calculation_Financial::COUPNUM + COUPPCD | PHPExcel_Calculation_Financial::COUPPCD + CUMIPMT | PHPExcel_Calculation_Financial::CUMIPMT + CUMPRINC | PHPExcel_Calculation_Financial::CUMPRINC + DB | PHPExcel_Calculation_Financial::DB + DDB | PHPExcel_Calculation_Financial::DDB + DISC | PHPExcel_Calculation_Financial::DISC + DOLLARDE | PHPExcel_Calculation_Financial::DOLLARDE + DOLLARFR | PHPExcel_Calculation_Financial::DOLLARFR + DURATION | **\*\*\* Not yet Implemented** + EFFECT | PHPExcel_Calculation_Financial::EFFECT + FV | PHPExcel_Calculation_Financial::FV + FVSCHEDULE | PHPExcel_Calculation_Financial::FVSCHEDULE + INTRATE | PHPExcel_Calculation_Financial::INTRATE + IPMT | PHPExcel_Calculation_Financial::IPMT + IRR | PHPExcel_Calculation_Financial::IRR + ISPMT | PHPExcel_Calculation_Financial::ISPMT + MDURATION | **\*\*\* Not yet Implemented** + MIRR | PHPExcel_Calculation_Financial::MIRR + NOMINAL | PHPExcel_Calculation_Financial::NOMINAL + NPER | PHPExcel_Calculation_Financial::NPER + NPV | PHPExcel_Calculation_Financial::NPV + ODDFPRICE | **\*\*\* Not yet Implemented** + ODDFYIELD | **\*\*\* Not yet Implemented** + ODDLPRICE | **\*\*\* Not yet Implemented** + ODDLYIELD | **\*\*\* Not yet Implemented** + PMT | PHPExcel_Calculation_Financial::PMT + PPMT | PHPExcel_Calculation_Financial::PPMT + PRICE | PHPExcel_Calculation_Financial::PRICE + PRICEDISC | PHPExcel_Calculation_Financial::PRICEDISC + PRICEMAT | PHPExcel_Calculation_Financial::PRICEMAT + PV | PHPExcel_Calculation_Financial::PV + RATE | PHPExcel_Calculation_Financial::RATE + RECEIVED | PHPExcel_Calculation_Financial::RECEIVED + SLN | PHPExcel_Calculation_Financial::SLN + SYD | PHPExcel_Calculation_Financial::SYD + TBILLEQ | PHPExcel_Calculation_Financial::TBILLEQ + TBILLPRICE | PHPExcel_Calculation_Financial::TBILLPRICE + TBILLYIELD | PHPExcel_Calculation_Financial::TBILLYIELD + USDOLLAR | **\*\*\* Not yet Implemented** + VDB | **\*\*\* Not yet Implemented** + XIRR | PHPExcel_Calculation_Financial::XIRR + XNPV | PHPExcel_Calculation_Financial::XNPV + YIELD | **\*\*\* Not yet Implemented** + YIELDDISC | PHPExcel_Calculation_Financial::YIELDDISC + YIELDMAT | PHPExcel_Calculation_Financial::YIELDMAT ## CATEGORY_INFORMATION - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - CELL | *** Not yet Implemented - ERROR.TYPE | PHPExcel_Calculation_Functions::ERROR_TYPE - INFO | *** Not yet Implemented - ISBLANK | PHPExcel_Calculation_Functions::IS_BLANK - ISERR | PHPExcel_Calculation_Functions::IS_ERR - ISERROR | PHPExcel_Calculation_Functions::IS_ERROR - ISEVEN | PHPExcel_Calculation_Functions::IS_EVEN - ISLOGICAL | PHPExcel_Calculation_Functions::IS_LOGICAL - ISNA | PHPExcel_Calculation_Functions::IS_NA - ISNONTEXT | PHPExcel_Calculation_Functions::IS_NONTEXT - ISNUMBER | PHPExcel_Calculation_Functions::IS_NUMBER - ISODD | PHPExcel_Calculation_Functions::IS_ODD - ISREF | *** Not yet Implemented - ISTEXT | PHPExcel_Calculation_Functions::IS_TEXT - N | PHPExcel_Calculation_Functions::N - NA | PHPExcel_Calculation_Functions::NA - TYPE | PHPExcel_Calculation_Functions::TYPE - VERSION | PHPExcel_Calculation_Functions::VERSION + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + CELL | **\*\*\* Not yet Implemented** + ERROR.TYPE | PHPExcel_Calculation_Functions::ERROR_TYPE + INFO | **\*\*\* Not yet Implemented** + ISBLANK | PHPExcel_Calculation_Functions::IS_BLANK + ISERR | PHPExcel_Calculation_Functions::IS_ERR + ISERROR | PHPExcel_Calculation_Functions::IS_ERROR + ISEVEN | PHPExcel_Calculation_Functions::IS_EVEN + ISLOGICAL | PHPExcel_Calculation_Functions::IS_LOGICAL + ISNA | PHPExcel_Calculation_Functions::IS_NA + ISNONTEXT | PHPExcel_Calculation_Functions::IS_NONTEXT + ISNUMBER | PHPExcel_Calculation_Functions::IS_NUMBER + ISODD | PHPExcel_Calculation_Functions::IS_ODD + ISREF | **\*\*\* Not yet Implemented** + ISTEXT | PHPExcel_Calculation_Functions::IS_TEXT + N | PHPExcel_Calculation_Functions::N + NA | PHPExcel_Calculation_Functions::NA + TYPE | PHPExcel_Calculation_Functions::TYPE + VERSION | PHPExcel_Calculation_Functions::VERSION ## CATEGORY_LOGICAL - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - AND | PHPExcel_Calculation_Logical::LOGICAL_AND - FALSE | PHPExcel_Calculation_Logical::FALSE - IF | PHPExcel_Calculation_Logical::STATEMENT_IF - IFERROR | PHPExcel_Calculation_Logical::IFERROR - NOT | PHPExcel_Calculation_Logical::NOT - OR | PHPExcel_Calculation_Logical::LOGICAL_OR - TRUE | PHPExcel_Calculation_Logical::TRUE + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + AND | PHPExcel_Calculation_Logical::LOGICAL_AND + FALSE | PHPExcel_Calculation_Logical::FALSE + IF | PHPExcel_Calculation_Logical::STATEMENT_IF + IFERROR | PHPExcel_Calculation_Logical::IFERROR + NOT | PHPExcel_Calculation_Logical::NOT + OR | PHPExcel_Calculation_Logical::LOGICAL_OR + TRUE | PHPExcel_Calculation_Logical::TRUE ## CATEGORY_LOOKUP_AND_REFERENCE - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - ADDRESS | PHPExcel_Calculation_LookupRef::CELL_ADDRESS - AREAS | *** Not yet Implemented - CHOOSE | PHPExcel_Calculation_LookupRef::CHOOSE - COLUMN | PHPExcel_Calculation_LookupRef::COLUMN - COLUMNS | PHPExcel_Calculation_LookupRef::COLUMNS - GETPIVOTDATA | *** Not yet Implemented - HLOOKUP | *** Not yet Implemented - HYPERLINK | PHPExcel_Calculation_LookupRef::HYPERLINK - INDEX | PHPExcel_Calculation_LookupRef::INDEX - INDIRECT | PHPExcel_Calculation_LookupRef::INDIRECT - LOOKUP | PHPExcel_Calculation_LookupRef::LOOKUP - MATCH | PHPExcel_Calculation_LookupRef::MATCH - OFFSET | PHPExcel_Calculation_LookupRef::OFFSET - ROW | PHPExcel_Calculation_LookupRef::ROW - ROWS | PHPExcel_Calculation_LookupRef::ROWS - RTD | *** Not yet Implemented - TRANSPOSE | PHPExcel_Calculation_LookupRef::TRANSPOSE - VLOOKUP | PHPExcel_Calculation_LookupRef::VLOOKUP + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + ADDRESS | PHPExcel_Calculation_LookupRef::CELL_ADDRESS + AREAS | **\*\*\* Not yet Implemented** + CHOOSE | PHPExcel_Calculation_LookupRef::CHOOSE + COLUMN | PHPExcel_Calculation_LookupRef::COLUMN + COLUMNS | PHPExcel_Calculation_LookupRef::COLUMNS + GETPIVOTDATA | **\*\*\* Not yet Implemented** + HLOOKUP | **\*\*\* Not yet Implemented** + HYPERLINK | PHPExcel_Calculation_LookupRef::HYPERLINK + INDEX | PHPExcel_Calculation_LookupRef::INDEX + INDIRECT | PHPExcel_Calculation_LookupRef::INDIRECT + LOOKUP | PHPExcel_Calculation_LookupRef::LOOKUP + MATCH | PHPExcel_Calculation_LookupRef::MATCH + OFFSET | PHPExcel_Calculation_LookupRef::OFFSET + ROW | PHPExcel_Calculation_LookupRef::ROW + ROWS | PHPExcel_Calculation_LookupRef::ROWS + RTD | **\*\*\* Not yet Implemented** + TRANSPOSE | PHPExcel_Calculation_LookupRef::TRANSPOSE + VLOOKUP | PHPExcel_Calculation_LookupRef::VLOOKUP ## CATEGORY_MATH_AND_TRIG - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - ABS | abs - ACOS | acos - ACOSH | acosh - ASIN | asin - ASINH | asinh - ATAN | atan - ATAN2 | PHPExcel_Calculation_MathTrig::REVERSE_ATAN2 - ATANH | atanh - CEILING | PHPExcel_Calculation_MathTrig::CEILING - COMBIN | PHPExcel_Calculation_MathTrig::COMBIN - COS | cos - COSH | cosh - DEGREES | rad2deg - EVEN | PHPExcel_Calculation_MathTrig::EVEN - EXP | exp - FACT | PHPExcel_Calculation_MathTrig::FACT - FACTDOUBLE | PHPExcel_Calculation_MathTrig::FACTDOUBLE - FLOOR | PHPExcel_Calculation_MathTrig::FLOOR - GCD | PHPExcel_Calculation_MathTrig::GCD - INT | PHPExcel_Calculation_MathTrig::INT - LCM | PHPExcel_Calculation_MathTrig::LCM - LN | log - LOG | PHPExcel_Calculation_MathTrig::LOG_BASE - LOG10 | log10 - MDETERM | PHPExcel_Calculation_MathTrig::MDETERM - MINVERSE | PHPExcel_Calculation_MathTrig::MINVERSE - MMULT | PHPExcel_Calculation_MathTrig::MMULT - MOD | PHPExcel_Calculation_MathTrig::MOD - MROUND | PHPExcel_Calculation_MathTrig::MROUND - MULTINOMIAL | PHPExcel_Calculation_MathTrig::MULTINOMIAL - ODD | PHPExcel_Calculation_MathTrig::ODD - PI | pi - POWER | PHPExcel_Calculation_MathTrig::POWER - PRODUCT | PHPExcel_Calculation_MathTrig::PRODUCT - QUOTIENT | PHPExcel_Calculation_MathTrig::QUOTIENT - RADIANS | deg2rad - RAND | PHPExcel_Calculation_MathTrig::RAND - RANDBETWEEN | PHPExcel_Calculation_MathTrig::RAND - ROMAN | PHPExcel_Calculation_MathTrig::ROMAN - ROUND | round - ROUNDDOWN | PHPExcel_Calculation_MathTrig::ROUNDDOWN - ROUNDUP | PHPExcel_Calculation_MathTrig::ROUNDUP - SERIESSUM | PHPExcel_Calculation_MathTrig::SERIESSUM - SIGN | PHPExcel_Calculation_MathTrig::SIGN - SIN | sin - SINH | sinh - SQRT | sqrt - SQRTPI | PHPExcel_Calculation_MathTrig::SQRTPI - SUBTOTAL | PHPExcel_Calculation_MathTrig::SUBTOTAL - SUM | PHPExcel_Calculation_MathTrig::SUM - SUMIF | PHPExcel_Calculation_MathTrig::SUMIF - SUMIFS | *** Not yet Implemented - SUMPRODUCT | PHPExcel_Calculation_MathTrig::SUMPRODUCT - SUMSQ | PHPExcel_Calculation_MathTrig::SUMSQ - SUMX2MY2 | PHPExcel_Calculation_MathTrig::SUMX2MY2 - SUMX2PY2 | PHPExcel_Calculation_MathTrig::SUMX2PY2 - SUMXMY2 | PHPExcel_Calculation_MathTrig::SUMXMY2 - TAN | tan - TANH | tanh - TRUNC | PHPExcel_Calculation_MathTrig::TRUNC + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + ABS | abs + ACOS | acos + ACOSH | acosh + ASIN | asin + ASINH | asinh + ATAN | atan + ATAN2 | PHPExcel_Calculation_MathTrig::REVERSE_ATAN2 + ATANH | atanh + CEILING | PHPExcel_Calculation_MathTrig::CEILING + COMBIN | PHPExcel_Calculation_MathTrig::COMBIN + COS | cos + COSH | cosh + DEGREES | rad2deg + EVEN | PHPExcel_Calculation_MathTrig::EVEN + EXP | exp + FACT | PHPExcel_Calculation_MathTrig::FACT + FACTDOUBLE | PHPExcel_Calculation_MathTrig::FACTDOUBLE + FLOOR | PHPExcel_Calculation_MathTrig::FLOOR + GCD | PHPExcel_Calculation_MathTrig::GCD + INT | PHPExcel_Calculation_MathTrig::INT + LCM | PHPExcel_Calculation_MathTrig::LCM + LN | log + LOG | PHPExcel_Calculation_MathTrig::LOG_BASE + LOG10 | log10 + MDETERM | PHPExcel_Calculation_MathTrig::MDETERM + MINVERSE | PHPExcel_Calculation_MathTrig::MINVERSE + MMULT | PHPExcel_Calculation_MathTrig::MMULT + MOD | PHPExcel_Calculation_MathTrig::MOD + MROUND | PHPExcel_Calculation_MathTrig::MROUND + MULTINOMIAL | PHPExcel_Calculation_MathTrig::MULTINOMIAL + ODD | PHPExcel_Calculation_MathTrig::ODD + PI | pi + POWER | PHPExcel_Calculation_MathTrig::POWER + PRODUCT | PHPExcel_Calculation_MathTrig::PRODUCT + QUOTIENT | PHPExcel_Calculation_MathTrig::QUOTIENT + RADIANS | deg2rad + RAND | PHPExcel_Calculation_MathTrig::RAND + RANDBETWEEN | PHPExcel_Calculation_MathTrig::RAND + ROMAN | PHPExcel_Calculation_MathTrig::ROMAN + ROUND | round + ROUNDDOWN | PHPExcel_Calculation_MathTrig::ROUNDDOWN + ROUNDUP | PHPExcel_Calculation_MathTrig::ROUNDUP + SERIESSUM | PHPExcel_Calculation_MathTrig::SERIESSUM + SIGN | PHPExcel_Calculation_MathTrig::SIGN + SIN | sin + SINH | sinh + SQRT | sqrt + SQRTPI | PHPExcel_Calculation_MathTrig::SQRTPI + SUBTOTAL | PHPExcel_Calculation_MathTrig::SUBTOTAL + SUM | PHPExcel_Calculation_MathTrig::SUM + SUMIF | PHPExcel_Calculation_MathTrig::SUMIF + SUMIFS | **\*\*\* Not yet Implemented** + SUMPRODUCT | PHPExcel_Calculation_MathTrig::SUMPRODUCT + SUMSQ | PHPExcel_Calculation_MathTrig::SUMSQ + SUMX2MY2 | PHPExcel_Calculation_MathTrig::SUMX2MY2 + SUMX2PY2 | PHPExcel_Calculation_MathTrig::SUMX2PY2 + SUMXMY2 | PHPExcel_Calculation_MathTrig::SUMXMY2 + TAN | tan + TANH | tanh + TRUNC | PHPExcel_Calculation_MathTrig::TRUNC ## CATEGORY_STATISTICAL - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - AVEDEV | PHPExcel_Calculation_Statistical::AVEDEV - AVERAGE | PHPExcel_Calculation_Statistical::AVERAGE - AVERAGEA | PHPExcel_Calculation_Statistical::AVERAGEA - AVERAGEIF | PHPExcel_Calculation_Statistical::AVERAGEIF - AVERAGEIFS | *** Not yet Implemented - BETADIST | PHPExcel_Calculation_Statistical::BETADIST - BETAINV | PHPExcel_Calculation_Statistical::BETAINV - BINOMDIST | PHPExcel_Calculation_Statistical::BINOMDIST - CHIDIST | PHPExcel_Calculation_Statistical::CHIDIST - CHIINV | PHPExcel_Calculation_Statistical::CHIINV - CHITEST | *** Not yet Implemented - CONFIDENCE | PHPExcel_Calculation_Statistical::CONFIDENCE - CORREL | PHPExcel_Calculation_Statistical::CORREL - COUNT | PHPExcel_Calculation_Statistical::COUNT - COUNTA | PHPExcel_Calculation_Statistical::COUNTA - COUNTBLANK | PHPExcel_Calculation_Statistical::COUNTBLANK - COUNTIF | PHPExcel_Calculation_Statistical::COUNTIF - COUNTIFS | *** Not yet Implemented - COVAR | PHPExcel_Calculation_Statistical::COVAR - CRITBINOM | PHPExcel_Calculation_Statistical::CRITBINOM - DEVSQ | PHPExcel_Calculation_Statistical::DEVSQ - EXPONDIST | PHPExcel_Calculation_Statistical::EXPONDIST - FDIST | *** Not yet Implemented - FINV | *** Not yet Implemented - FISHER | PHPExcel_Calculation_Statistical::FISHER - FISHERINV | PHPExcel_Calculation_Statistical::FISHERINV - FORECAST | PHPExcel_Calculation_Statistical::FORECAST - FREQUENCY | *** Not yet Implemented - FTEST | *** Not yet Implemented - GAMMADIST | PHPExcel_Calculation_Statistical::GAMMADIST - GAMMAINV | PHPExcel_Calculation_Statistical::GAMMAINV - GAMMALN | PHPExcel_Calculation_Statistical::GAMMALN - GEOMEAN | PHPExcel_Calculation_Statistical::GEOMEAN - GROWTH | PHPExcel_Calculation_Statistical::GROWTH - HARMEAN | PHPExcel_Calculation_Statistical::HARMEAN - HYPGEOMDIST | PHPExcel_Calculation_Statistical::HYPGEOMDIST - INTERCEPT | PHPExcel_Calculation_Statistical::INTERCEPT - KURT | PHPExcel_Calculation_Statistical::KURT - LARGE | PHPExcel_Calculation_Statistical::LARGE - LINEST | PHPExcel_Calculation_Statistical::LINEST - LOGEST | PHPExcel_Calculation_Statistical::LOGEST - LOGINV | PHPExcel_Calculation_Statistical::LOGINV - LOGNORMDIST | PHPExcel_Calculation_Statistical::LOGNORMDIST - MAX | PHPExcel_Calculation_Statistical::MAX - MAXA | PHPExcel_Calculation_Statistical::MAXA - MAXIF | PHPExcel_Calculation_Statistical::MAXIF - MEDIAN | PHPExcel_Calculation_Statistical::MEDIAN - MEDIANIF | *** Not yet Implemented - MIN | PHPExcel_Calculation_Statistical::MIN - MINA | PHPExcel_Calculation_Statistical::MINA - MINIF | PHPExcel_Calculation_Statistical::MINIF - MODE | PHPExcel_Calculation_Statistical::MODE - NEGBINOMDIST | PHPExcel_Calculation_Statistical::NEGBINOMDIST - NORMDIST | PHPExcel_Calculation_Statistical::NORMDIST - NORMINV | PHPExcel_Calculation_Statistical::NORMINV - NORMSDIST | PHPExcel_Calculation_Statistical::NORMSDIST - NORMSINV | PHPExcel_Calculation_Statistical::NORMSINV - PEARSON | PHPExcel_Calculation_Statistical::CORREL - PERCENTILE | PHPExcel_Calculation_Statistical::PERCENTILE - PERCENTRANK | PHPExcel_Calculation_Statistical::PERCENTRANK - PERMUT | PHPExcel_Calculation_Statistical::PERMUT - POISSON | PHPExcel_Calculation_Statistical::POISSON - PROB | *** Not yet Implemented - QUARTILE | PHPExcel_Calculation_Statistical::QUARTILE - RANK | PHPExcel_Calculation_Statistical::RANK - RSQ | PHPExcel_Calculation_Statistical::RSQ - SKEW | PHPExcel_Calculation_Statistical::SKEW - SLOPE | PHPExcel_Calculation_Statistical::SLOPE - SMALL | PHPExcel_Calculation_Statistical::SMALL - STANDARDIZE | PHPExcel_Calculation_Statistical::STANDARDIZE - STDEV | PHPExcel_Calculation_Statistical::STDEV - STDEVA | PHPExcel_Calculation_Statistical::STDEVA - STDEVP | PHPExcel_Calculation_Statistical::STDEVP - STDEVPA | PHPExcel_Calculation_Statistical::STDEVPA - STEYX | PHPExcel_Calculation_Statistical::STEYX - TDIST | PHPExcel_Calculation_Statistical::TDIST - TINV | PHPExcel_Calculation_Statistical::TINV - TREND | PHPExcel_Calculation_Statistical::TREND - TRIMMEAN | PHPExcel_Calculation_Statistical::TRIMMEAN - TTEST | *** Not yet Implemented - VAR | PHPExcel_Calculation_Statistical::VARFunc - VARA | PHPExcel_Calculation_Statistical::VARA - VARP | PHPExcel_Calculation_Statistical::VARP - VARPA | PHPExcel_Calculation_Statistical::VARPA - WEIBULL | PHPExcel_Calculation_Statistical::WEIBULL - ZTEST | PHPExcel_Calculation_Statistical::ZTEST + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + AVEDEV | PHPExcel_Calculation_Statistical::AVEDEV + AVERAGE | PHPExcel_Calculation_Statistical::AVERAGE + AVERAGEA | PHPExcel_Calculation_Statistical::AVERAGEA + AVERAGEIF | PHPExcel_Calculation_Statistical::AVERAGEIF + AVERAGEIFS | **\*\*\* Not yet Implemented** + BETADIST | PHPExcel_Calculation_Statistical::BETADIST + BETAINV | PHPExcel_Calculation_Statistical::BETAINV + BINOMDIST | PHPExcel_Calculation_Statistical::BINOMDIST + CHIDIST | PHPExcel_Calculation_Statistical::CHIDIST + CHIINV | PHPExcel_Calculation_Statistical::CHIINV + CHITEST | **\*\*\* Not yet Implemented** + CONFIDENCE | PHPExcel_Calculation_Statistical::CONFIDENCE + CORREL | PHPExcel_Calculation_Statistical::CORREL + COUNT | PHPExcel_Calculation_Statistical::COUNT + COUNTA | PHPExcel_Calculation_Statistical::COUNTA + COUNTBLANK | PHPExcel_Calculation_Statistical::COUNTBLANK + COUNTIF | PHPExcel_Calculation_Statistical::COUNTIF + COUNTIFS | **\*\*\* Not yet Implemented** + COVAR | PHPExcel_Calculation_Statistical::COVAR + CRITBINOM | PHPExcel_Calculation_Statistical::CRITBINOM + DEVSQ | PHPExcel_Calculation_Statistical::DEVSQ + EXPONDIST | PHPExcel_Calculation_Statistical::EXPONDIST + FDIST | **\*\*\* Not yet Implemented** + FINV | **\*\*\* Not yet Implemented** + FISHER | PHPExcel_Calculation_Statistical::FISHER + FISHERINV | PHPExcel_Calculation_Statistical::FISHERINV + FORECAST | PHPExcel_Calculation_Statistical::FORECAST + FREQUENCY | **\*\*\* Not yet Implemented** + FTEST | **\*\*\* Not yet Implemented** + GAMMADIST | PHPExcel_Calculation_Statistical::GAMMADIST + GAMMAINV | PHPExcel_Calculation_Statistical::GAMMAINV + GAMMALN | PHPExcel_Calculation_Statistical::GAMMALN + GEOMEAN | PHPExcel_Calculation_Statistical::GEOMEAN + GROWTH | PHPExcel_Calculation_Statistical::GROWTH + HARMEAN | PHPExcel_Calculation_Statistical::HARMEAN + HYPGEOMDIST | PHPExcel_Calculation_Statistical::HYPGEOMDIST + INTERCEPT | PHPExcel_Calculation_Statistical::INTERCEPT + KURT | PHPExcel_Calculation_Statistical::KURT + LARGE | PHPExcel_Calculation_Statistical::LARGE + LINEST | PHPExcel_Calculation_Statistical::LINEST + LOGEST | PHPExcel_Calculation_Statistical::LOGEST + LOGINV | PHPExcel_Calculation_Statistical::LOGINV + LOGNORMDIST | PHPExcel_Calculation_Statistical::LOGNORMDIST + MAX | PHPExcel_Calculation_Statistical::MAX + MAXA | PHPExcel_Calculation_Statistical::MAXA + MAXIF | PHPExcel_Calculation_Statistical::MAXIF + MEDIAN | PHPExcel_Calculation_Statistical::MEDIAN + MEDIANIF | **\*\*\* Not yet Implemented** + MIN | PHPExcel_Calculation_Statistical::MIN + MINA | PHPExcel_Calculation_Statistical::MINA + MINIF | PHPExcel_Calculation_Statistical::MINIF + MODE | PHPExcel_Calculation_Statistical::MODE + NEGBINOMDIST | PHPExcel_Calculation_Statistical::NEGBINOMDIST + NORMDIST | PHPExcel_Calculation_Statistical::NORMDIST + NORMINV | PHPExcel_Calculation_Statistical::NORMINV + NORMSDIST | PHPExcel_Calculation_Statistical::NORMSDIST + NORMSINV | PHPExcel_Calculation_Statistical::NORMSINV + PEARSON | PHPExcel_Calculation_Statistical::CORREL + PERCENTILE | PHPExcel_Calculation_Statistical::PERCENTILE + PERCENTRANK | PHPExcel_Calculation_Statistical::PERCENTRANK + PERMUT | PHPExcel_Calculation_Statistical::PERMUT + POISSON | PHPExcel_Calculation_Statistical::POISSON + PROB | **\*\*\* Not yet Implemented** + QUARTILE | PHPExcel_Calculation_Statistical::QUARTILE + RANK | PHPExcel_Calculation_Statistical::RANK + RSQ | PHPExcel_Calculation_Statistical::RSQ + SKEW | PHPExcel_Calculation_Statistical::SKEW + SLOPE | PHPExcel_Calculation_Statistical::SLOPE + SMALL | PHPExcel_Calculation_Statistical::SMALL + STANDARDIZE | PHPExcel_Calculation_Statistical::STANDARDIZE + STDEV | PHPExcel_Calculation_Statistical::STDEV + STDEVA | PHPExcel_Calculation_Statistical::STDEVA + STDEVP | PHPExcel_Calculation_Statistical::STDEVP + STDEVPA | PHPExcel_Calculation_Statistical::STDEVPA + STEYX | PHPExcel_Calculation_Statistical::STEYX + TDIST | PHPExcel_Calculation_Statistical::TDIST + TINV | PHPExcel_Calculation_Statistical::TINV + TREND | PHPExcel_Calculation_Statistical::TREND + TRIMMEAN | PHPExcel_Calculation_Statistical::TRIMMEAN + TTEST | **\*\*\* Not yet Implemented** + VAR | PHPExcel_Calculation_Statistical::VARFunc + VARA | PHPExcel_Calculation_Statistical::VARA + VARP | PHPExcel_Calculation_Statistical::VARP + VARPA | PHPExcel_Calculation_Statistical::VARPA + WEIBULL | PHPExcel_Calculation_Statistical::WEIBULL + ZTEST | PHPExcel_Calculation_Statistical::ZTEST ## CATEGORY_TEXT_AND_DATA - Excel Function | PHPExcel Function - ------------------------|------------------------------------------- - ASC | *** Not yet Implemented - BAHTTEXT | *** Not yet Implemented - CHAR | PHPExcel_Calculation_TextData::CHARACTER - CLEAN | PHPExcel_Calculation_TextData::TRIMNONPRINTABLE - CODE | PHPExcel_Calculation_TextData::ASCIICODE - CONCATENATE | PHPExcel_Calculation_TextData::CONCATENATE - DOLLAR | PHPExcel_Calculation_TextData::DOLLAR - EXACT | *** Not yet Implemented - FIND | PHPExcel_Calculation_TextData::SEARCHSENSITIVE - FINDB | PHPExcel_Calculation_TextData::SEARCHSENSITIVE - FIXED | PHPExcel_Calculation_TextData::FIXEDFORMAT - JIS | *** Not yet Implemented - LEFT | PHPExcel_Calculation_TextData::LEFT - LEFTB | PHPExcel_Calculation_TextData::LEFT - LEN | PHPExcel_Calculation_TextData::STRINGLENGTH - LENB | PHPExcel_Calculation_TextData::STRINGLENGTH - LOWER | PHPExcel_Calculation_TextData::LOWERCASE - MID | PHPExcel_Calculation_TextData::MID - MIDB | PHPExcel_Calculation_TextData::MID - PHONETIC | *** Not yet Implemented - PROPER | PHPExcel_Calculation_TextData::PROPERCASE - REPLACE | PHPExcel_Calculation_TextData::REPLACE - REPLACEB | PHPExcel_Calculation_TextData::REPLACE - REPT | str_repeat - RIGHT | PHPExcel_Calculation_TextData::RIGHT - RIGHTB | PHPExcel_Calculation_TextData::RIGHT - SEARCH | PHPExcel_Calculation_TextData::SEARCHINSENSITIVE - SEARCHB | PHPExcel_Calculation_TextData::SEARCHINSENSITIVE - SUBSTITUTE | PHPExcel_Calculation_TextData::SUBSTITUTE - T | PHPExcel_Calculation_TextData::RETURNSTRING - TEXT | PHPExcel_Calculation_TextData::TEXTFORMAT - TRIM | PHPExcel_Calculation_TextData::TRIMSPACES - UPPER | PHPExcel_Calculation_TextData::UPPERCASE - VALUE | *** Not yet Implemented + Excel Function | PHPExcel Function + --------------------|------------------------------------------- + ASC | **\*\*\* Not yet Implemented** + BAHTTEXT | **\*\*\* Not yet Implemented** + CHAR | PHPExcel_Calculation_TextData::CHARACTER + CLEAN | PHPExcel_Calculation_TextData::TRIMNONPRINTABLE + CODE | PHPExcel_Calculation_TextData::ASCIICODE + CONCATENATE | PHPExcel_Calculation_TextData::CONCATENATE + DOLLAR | PHPExcel_Calculation_TextData::DOLLAR + EXACT | **\*\*\* Not yet Implemented** + FIND | PHPExcel_Calculation_TextData::SEARCHSENSITIVE + FINDB | PHPExcel_Calculation_TextData::SEARCHSENSITIVE + FIXED | PHPExcel_Calculation_TextData::FIXEDFORMAT + JIS | **\*\*\* Not yet Implemented** + LEFT | PHPExcel_Calculation_TextData::LEFT + LEFTB | PHPExcel_Calculation_TextData::LEFT + LEN | PHPExcel_Calculation_TextData::STRINGLENGTH + LENB | PHPExcel_Calculation_TextData::STRINGLENGTH + LOWER | PHPExcel_Calculation_TextData::LOWERCASE + MID | PHPExcel_Calculation_TextData::MID + MIDB | PHPExcel_Calculation_TextData::MID + PHONETIC | **\*\*\* Not yet Implemented** + PROPER | PHPExcel_Calculation_TextData::PROPERCASE + REPLACE | PHPExcel_Calculation_TextData::REPLACE + REPLACEB | PHPExcel_Calculation_TextData::REPLACE + REPT | str_repeat + RIGHT | PHPExcel_Calculation_TextData::RIGHT + RIGHTB | PHPExcel_Calculation_TextData::RIGHT + SEARCH | PHPExcel_Calculation_TextData::SEARCHINSENSITIVE + SEARCHB | PHPExcel_Calculation_TextData::SEARCHINSENSITIVE + SUBSTITUTE | PHPExcel_Calculation_TextData::SUBSTITUTE + T | PHPExcel_Calculation_TextData::RETURNSTRING + TEXT | PHPExcel_Calculation_TextData::TEXTFORMAT + TRIM | PHPExcel_Calculation_TextData::TRIMSPACES + UPPER | PHPExcel_Calculation_TextData::UPPERCASE + VALUE | **\*\*\* Not yet Implemented** diff --git a/Documentation/markdown/Functions/FunctionListByName.md b/Documentation/markdown/Functions/FunctionListByName.md index e16114b50..b69e45469 100644 --- a/Documentation/markdown/Functions/FunctionListByName.md +++ b/Documentation/markdown/Functions/FunctionListByName.md @@ -1,3 +1,5 @@ +#A + Excel Function | Category | PHPExcel Function --------------------|--------------------------------|------------------------------------------- ABS | CATEGORY_MATH_AND_TRIG | abs @@ -9,8 +11,8 @@ AMORDEGRC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::AMORDEGRC AMORLINC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::AMORLINC AND | CATEGORY_LOGICAL | PHPExcel_Calculation_Logical::LOGICAL_AND - AREAS | CATEGORY_LOOKUP_AND_REFERENCE | *** Not yet Implemented - ASC | CATEGORY_TEXT_AND_DATA | *** Not yet Implemented + AREAS | CATEGORY_LOOKUP_AND_REFERENCE | **\*\*\* Not yet Implemented** + ASC | CATEGORY_TEXT_AND_DATA | **\*\*\* Not yet Implemented** ASIN | CATEGORY_MATH_AND_TRIG | asin ASINH | CATEGORY_MATH_AND_TRIG | asinh ATAN | CATEGORY_MATH_AND_TRIG | atan @@ -20,11 +22,13 @@ AVERAGE | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::AVERAGE AVERAGEA | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::AVERAGEA AVERAGEIF | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::AVERAGEIF - AVERAGEIFS | CATEGORY_STATISTICAL | *** Not yet Implemented - + AVERAGEIFS | CATEGORY_STATISTICAL | **\*\*\* Not yet Implemented** + +#B + Excel Function | Category | PHPExcel Function --------------------|--------------------------------|------------------------------------------- - BAHTTEXT | CATEGORY_TEXT_AND_DATA | *** Not yet Implemented + BAHTTEXT | CATEGORY_TEXT_AND_DATA | **\*\*\* Not yet Implemented** BESSELI | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BESSELI BESSELJ | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BESSELJ BESSELK | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BESSELK @@ -36,14 +40,16 @@ BIN2OCT | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::BINTOOCT BINOMDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::BINOMDIST +#C + Excel Function | Category | PHPExcel Function --------------------|--------------------------------|------------------------------------------- CEILING | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::CEILING - CELL | CATEGORY_INFORMATION | *** Not yet Implemented + CELL | CATEGORY_INFORMATION | **\*\*\* Not yet Implemented** CHAR | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::CHARACTER CHIDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::CHIDIST CHIINV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::CHIINV - CHITEST | CATEGORY_STATISTICAL | *** Not yet Implemented + CHITEST | CATEGORY_STATISTICAL | **\*\*\* Not yet Implemented** CHOOSE | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::CHOOSE CLEAN | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::TRIMNONPRINTABLE CODE | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::ASCIICODE @@ -61,7 +67,7 @@ COUNTA | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::COUNTA COUNTBLANK | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::COUNTBLANK COUNTIF | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::COUNTIF - COUNTIFS | CATEGORY_STATISTICAL | *** Not yet Implemented + COUNTIFS | CATEGORY_STATISTICAL | **\*\*\* Not yet Implemented** COUPDAYBS | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::COUPDAYBS COUPDAYS | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::COUPDAYS COUPDAYSNC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::COUPDAYSNC @@ -70,318 +76,410 @@ COUPPCD | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::COUPPCD COVAR | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::COVAR CRITBINOM | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::CRITBINOM - CUBEKPIMEMBER | CATEGORY_CUBE | *** Not yet Implemented - CUBEMEMBER | CATEGORY_CUBE | *** Not yet Implemented - CUBEMEMBERPROPERTY | CATEGORY_CUBE | *** Not yet Implemented - CUBERANKEDMEMBER | CATEGORY_CUBE | *** Not yet Implemented - CUBESET | CATEGORY_CUBE | *** Not yet Implemented - CUBESETCOUNT | CATEGORY_CUBE | *** Not yet Implemented - CUBEVALUE | CATEGORY_CUBE | *** Not yet Implemented + CUBEKPIMEMBER | CATEGORY_CUBE | **\*\*\* Not yet Implemented** + CUBEMEMBER | CATEGORY_CUBE | **\*\*\* Not yet Implemented** + CUBEMEMBERPROPERTY | CATEGORY_CUBE | **\*\*\* Not yet Implemented** + CUBERANKEDMEMBER | CATEGORY_CUBE | **\*\*\* Not yet Implemented** + CUBESET | CATEGORY_CUBE | **\*\*\* Not yet Implemented** + CUBESETCOUNT | CATEGORY_CUBE | **\*\*\* Not yet Implemented** + CUBEVALUE | CATEGORY_CUBE | **\*\*\* Not yet Implemented** CUMIPMT | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::CUMIPMT CUMPRINC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::CUMPRINC -DATE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATE -DATEDIF CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATEDIF -DATEVALUE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATEVALUE -DAVERAGE CATEGORY_DATABASE PHPExcel_Calculation_Database::DAVERAGE -DAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DAYOFMONTH -DAYS360 CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DAYS360 -DB CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DB -DCOUNT CATEGORY_DATABASE PHPExcel_Calculation_Database::DCOUNT -DCOUNTA CATEGORY_DATABASE PHPExcel_Calculation_Database::DCOUNTA -DDB CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DDB -DEC2BIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DECTOBIN -DEC2HEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DECTOHEX -DEC2OCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DECTOOCT -DEGREES CATEGORY_MATH_AND_TRIG rad2deg -DELTA CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::DELTA -DEVSQ CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::DEVSQ -DGET CATEGORY_DATABASE PHPExcel_Calculation_Database::DGET -DISC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DISC -DMAX CATEGORY_DATABASE PHPExcel_Calculation_Database::DMAX -DMIN CATEGORY_DATABASE PHPExcel_Calculation_Database::DMIN -DOLLAR CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::DOLLAR -DOLLARDE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DOLLARDE -DOLLARFR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::DOLLARFR -DPRODUCT CATEGORY_DATABASE PHPExcel_Calculation_Database::DPRODUCT -DSTDEV CATEGORY_DATABASE PHPExcel_Calculation_Database::DSTDEV -DSTDEVP CATEGORY_DATABASE PHPExcel_Calculation_Database::DSTDEVP -DSUM CATEGORY_DATABASE PHPExcel_Calculation_Database::DSUM -DURATION CATEGORY_FINANCIAL *** Not yet Implemented -DVAR CATEGORY_DATABASE PHPExcel_Calculation_Database::DVAR -DVARP CATEGORY_DATABASE PHPExcel_Calculation_Database::DVARP - -EDATE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::EDATE -EFFECT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::EFFECT -EOMONTH CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::EOMONTH -ERF CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::ERF -ERFC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::ERFC -ERROR.TYPE CATEGORY_INFORMATION PHPExcel_Calculation_Functions::ERROR_TYPE -EVEN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::EVEN -EXACT CATEGORY_TEXT_AND_DATA *** Not yet Implemented -EXP CATEGORY_MATH_AND_TRIG exp -EXPONDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::EXPONDIST - -FACT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::FACT -FACTDOUBLE CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::FACTDOUBLE -FALSE CATEGORY_LOGICAL PHPExcel_Calculation_Logical::FALSE -FDIST CATEGORY_STATISTICAL *** Not yet Implemented -FIND CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHSENSITIVE -FINDB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHSENSITIVE -FINV CATEGORY_STATISTICAL *** Not yet Implemented -FISHER CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::FISHER -FISHERINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::FISHERINV -FIXED CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::FIXEDFORMAT -FLOOR CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::FLOOR -FORECAST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::FORECAST -FREQUENCY CATEGORY_STATISTICAL *** Not yet Implemented -FTEST CATEGORY_STATISTICAL *** Not yet Implemented -FV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::FV -FVSCHEDULE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::FVSCHEDULE - -GAMMADIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GAMMADIST -GAMMAINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GAMMAINV -GAMMALN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GAMMALN -GCD CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::GCD -GEOMEAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GEOMEAN -GESTEP CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::GESTEP -GETPIVOTDATA CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented -GROWTH CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::GROWTH - -HARMEAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::HARMEAN -HEX2BIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTOBIN -HEX2DEC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTODEC -HEX2OCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTOOCT -HLOOKUP CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented -HOUR CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::HOUROFDAY -HYPERLINK CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::HYPERLINK -HYPGEOMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::HYPGEOMDIST - -IF CATEGORY_LOGICAL PHPExcel_Calculation_Logical::STATEMENT_IF -IFERROR CATEGORY_LOGICAL PHPExcel_Calculation_Logical::IFERROR -IMABS CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMABS -IMAGINARY CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMAGINARY -IMARGUMENT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMARGUMENT -IMCONJUGATE CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMCONJUGATE -IMCOS CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMCOS -IMDIV CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMDIV -IMEXP CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMEXP -IMLN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMLN -IMLOG10 CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMLOG10 -IMLOG2 CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMLOG2 -IMPOWER CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMPOWER -IMPRODUCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMPRODUCT -IMREAL CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMREAL -IMSIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSIN -IMSQRT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSQRT -IMSUB CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSUB -IMSUM CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::IMSUM -INDEX CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::INDEX -INDIRECT CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::INDIRECT -INFO CATEGORY_INFORMATION *** Not yet Implemented -INT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::INT -INTERCEPT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::INTERCEPT -INTRATE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::INTRATE -IPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::IPMT -IRR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::IRR -ISBLANK CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_BLANK -ISERR CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_ERR -ISERROR CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_ERROR -ISEVEN CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_EVEN -ISLOGICAL CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_LOGICAL -ISNA CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_NA -ISNONTEXT CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_NONTEXT -ISNUMBER CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_NUMBER -ISODD CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_ODD -ISPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::ISPMT -ISREF CATEGORY_INFORMATION *** Not yet Implemented -ISTEXT CATEGORY_INFORMATION PHPExcel_Calculation_Functions::IS_TEXT - -JIS CATEGORY_TEXT_AND_DATA *** Not yet Implemented - -KURT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::KURT - -LARGE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LARGE -LCM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::LCM -LEFT CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::LEFT -LEFTB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::LEFT -LEN CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::STRINGLENGTH -LENB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::STRINGLENGTH -LINEST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LINEST -LN CATEGORY_MATH_AND_TRIG log -LOG CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::LOG_BASE -LOG10 CATEGORY_MATH_AND_TRIG log10 -LOGEST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LOGEST -LOGINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LOGINV -LOGNORMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::LOGNORMDIST -LOOKUP CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::LOOKUP -LOWER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::LOWERCASE - -MATCH CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::MATCH -MAX CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MAX -MAXA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MAXA -MAXIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MAXIF -MDETERM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MDETERM -MDURATION CATEGORY_FINANCIAL *** Not yet Implemented -MEDIAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MEDIAN -MEDIANIF CATEGORY_STATISTICAL *** Not yet Implemented -MID CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::MID -MIDB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::MID -MIN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MIN -MINA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MINA -MINIF CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MINIF -MINUTE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::MINUTEOFHOUR -MINVERSE CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MINVERSE -MIRR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::MIRR -MMULT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MMULT -MOD CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MOD -MODE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::MODE -MONTH CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::MONTHOFYEAR -MROUND CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MROUND -MULTINOMIAL CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::MULTINOMIAL - -N CATEGORY_INFORMATION PHPExcel_Calculation_Functions::N -NA CATEGORY_INFORMATION PHPExcel_Calculation_Functions::NA -NEGBINOMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NEGBINOMDIST -NETWORKDAYS CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::NETWORKDAYS -NOMINAL CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::NOMINAL -NORMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMDIST -NORMINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMINV -NORMSDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMSDIST -NORMSINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::NORMSINV -NOT CATEGORY_LOGICAL PHPExcel_Calculation_Logical::NOT -NOW CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATETIMENOW -NPER CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::NPER -NPV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::NPV - -OCT2BIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::OCTTOBIN -OCT2DEC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::OCTTODEC -OCT2HEX CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::OCTTOHEX -ODD CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ODD -ODDFPRICE CATEGORY_FINANCIAL *** Not yet Implemented -ODDFYIELD CATEGORY_FINANCIAL *** Not yet Implemented -ODDLPRICE CATEGORY_FINANCIAL *** Not yet Implemented -ODDLYIELD CATEGORY_FINANCIAL *** Not yet Implemented -OFFSET CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::OFFSET -OR CATEGORY_LOGICAL PHPExcel_Calculation_Logical::LOGICAL_OR - -PEARSON CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::CORREL -PERCENTILE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::PERCENTILE -PERCENTRANK CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::PERCENTRANK -PERMUT CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::PERMUT -PHONETIC CATEGORY_TEXT_AND_DATA *** Not yet Implemented -PI CATEGORY_MATH_AND_TRIG pi -PMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PMT -POISSON CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::POISSON -POWER CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::POWER -PPMT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PPMT -PRICE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PRICE -PRICEDISC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PRICEDISC -PRICEMAT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PRICEMAT -PROB CATEGORY_STATISTICAL *** Not yet Implemented -PRODUCT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::PRODUCT -PROPER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::PROPERCASE -PV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::PV - -QUARTILE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::QUARTILE -QUOTIENT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::QUOTIENT - -RADIANS CATEGORY_MATH_AND_TRIG deg2rad -RAND CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::RAND -RANDBETWEEN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::RAND -RANK CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::RANK -RATE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::RATE -RECEIVED CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::RECEIVED -REPLACE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::REPLACE -REPLACEB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::REPLACE -REPT CATEGORY_TEXT_AND_DATA str_repeat -RIGHT CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::RIGHT -RIGHTB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::RIGHT -ROMAN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ROMAN -ROUND CATEGORY_MATH_AND_TRIG round -ROUNDDOWN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ROUNDDOWN -ROUNDUP CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::ROUNDUP -ROW CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::ROW -ROWS CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::ROWS -RSQ CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::RSQ -RTD CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented - -SEARCH CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHINSENSITIVE -SEARCHB CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SEARCHINSENSITIVE -SECOND CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::SECONDOFMINUTE -SERIESSUM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SERIESSUM -SIGN CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SIGN -SIN CATEGORY_MATH_AND_TRIG sin -SINH CATEGORY_MATH_AND_TRIG sinh -SKEW CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::SKEW -SLN CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::SLN -SLOPE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::SLOPE -SMALL CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::SMALL -SQRT CATEGORY_MATH_AND_TRIG sqrt -SQRTPI CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SQRTPI -STANDARDIZE CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STANDARDIZE -STDEV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEV -STDEVA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEVA -STDEVP CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEVP -STDEVPA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STDEVPA -STEYX CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::STEYX -SUBSTITUTE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::SUBSTITUTE -SUBTOTAL CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUBTOTAL -SUM CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUM -SUMIF CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMIF -SUMIFS CATEGORY_MATH_AND_TRIG *** Not yet Implemented -SUMPRODUCT CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMPRODUCT -SUMSQ CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMSQ -SUMX2MY2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMX2MY2 -SUMX2PY2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMX2PY2 -SUMXMY2 CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::SUMXMY2 -SYD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::SYD - -T CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::RETURNSTRING -TAN CATEGORY_MATH_AND_TRIG tan -TANH CATEGORY_MATH_AND_TRIG tanh -TBILLEQ CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::TBILLEQ -TBILLPRICE CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::TBILLPRICE -TBILLYIELD CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::TBILLYIELD -TDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TDIST -TEXT CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::TEXTFORMAT -TIME CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::TIME -TIMEVALUE CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::TIMEVALUE -TINV CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TINV -TODAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DATENOW -TRANSPOSE CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::TRANSPOSE -TREND CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TREND -TRIM CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::TRIMSPACES -TRIMMEAN CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::TRIMMEAN -TRUE CATEGORY_LOGICAL PHPExcel_Calculation_Logical::TRUE -TRUNC CATEGORY_MATH_AND_TRIG PHPExcel_Calculation_MathTrig::TRUNC -TTEST CATEGORY_STATISTICAL *** Not yet Implemented -TYPE CATEGORY_INFORMATION PHPExcel_Calculation_Functions::TYPE - -UPPER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::UPPERCASE -USDOLLAR CATEGORY_FINANCIAL *** Not yet Implemented - -VALUE CATEGORY_TEXT_AND_DATA *** Not yet Implemented -VAR CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARFunc -VARA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARA -VARP CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARP -VARPA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARPA -VDB CATEGORY_FINANCIAL *** Not yet Implemented -VERSION CATEGORY_INFORMATION PHPExcel_Calculation_Functions::VERSION -VLOOKUP CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::VLOOKUP - -WEEKDAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::DAYOFWEEK -WEEKNUM CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::WEEKOFYEAR -WEIBULL CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::WEIBULL -WORKDAY CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::WORKDAY - -XIRR CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::XIRR -XNPV CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::XNPV - -YEAR CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::YEAR -YEARFRAC CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::YEARFRAC -YIELD CATEGORY_FINANCIAL *** Not yet Implemented -YIELDDISC CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::YIELDDISC -YIELDMAT CATEGORY_FINANCIAL PHPExcel_Calculation_Financial::YIELDMAT - -ZTEST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::ZTEST +#D + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + DATE | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::DATE + DATEDIF | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::DATEDIF + DATEVALUE | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::DATEVALUE + DAVERAGE | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DAVERAGE + DAY | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::DAYOFMONTH + DAYS360 | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::DAYS360 + DB | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::DB + DCOUNT | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DCOUNT + DCOUNTA | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DCOUNTA + DDB | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::DDB + DEC2BIN | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::DECTOBIN + DEC2HEX | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::DECTOHEX + DEC2OCT | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::DECTOOCT + DEGREES | CATEGORY_MATH_AND_TRIG | rad2deg + DELTA | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::DELTA + DEVSQ | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::DEVSQ + DGET | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DGET + DISC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::DISC + DMAX | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DMAX + DMIN | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DMIN + DOLLAR | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::DOLLAR + DOLLARDE | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::DOLLARDE + DOLLARFR | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::DOLLARFR + DPRODUCT | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DPRODUCT + DSTDEV | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DSTDEV + DSTDEVP | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DSTDEVP + DSUM | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DSUM + DURATION | CATEGORY_FINANCIAL | **\*\*\* Not yet Implemented** + DVAR | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DVAR + DVARP | CATEGORY_DATABASE | PHPExcel_Calculation_Database::DVARP + +#E + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + EDATE | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::EDATE + EFFECT | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::EFFECT + EOMONTH | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::EOMONTH + ERF | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::ERF + ERFC | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::ERFC + ERROR.TYPE | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::ERROR_TYPE + EVEN | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::EVEN + EXACT | CATEGORY_TEXT_AND_DATA | **\*\*\* Not yet Implemented** + EXP | CATEGORY_MATH_AND_TRIG | exp + EXPONDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::EXPONDIST + +#F + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + FACT | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::FACT + FACTDOUBLE | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::FACTDOUBLE + FALSE | CATEGORY_LOGICAL | PHPExcel_Calculation_Logical::FALSE + FDIST | CATEGORY_STATISTICAL | **\*\*\* Not yet Implemented** + FIND | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::SEARCHSENSITIVE + FINDB | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::SEARCHSENSITIVE + FINV | CATEGORY_STATISTICAL | **\*\*\* Not yet Implemented** + FISHER | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::FISHER + FISHERINV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::FISHERINV + FIXED | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::FIXEDFORMAT + FLOOR | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::FLOOR + FORECAST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::FORECAST + FREQUENCY | CATEGORY_STATISTICAL | **\*\*\* Not yet Implemented** + FTEST | CATEGORY_STATISTICAL | **\*\*\* Not yet Implemented** + FV | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::FV + FVSCHEDULE | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::FVSCHEDULE + +#G + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + GAMMADIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::GAMMADIST + GAMMAINV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::GAMMAINV + GAMMALN | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::GAMMALN + GCD | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::GCD + GEOMEAN | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::GEOMEAN + GESTEP | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::GESTEP + GETPIVOTDATA | CATEGORY_LOOKUP_AND_REFERENCE | **\*\*\* Not yet Implemented** + GROWTH | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::GROWTH + +#H + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + HARMEAN | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::HARMEAN + HEX2BIN | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::HEXTOBIN + HEX2DEC | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::HEXTODEC + HEX2OCT | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::HEXTOOCT + HLOOKUP | CATEGORY_LOOKUP_AND_REFERENCE | **\*\*\* Not yet Implemented** + HOUR | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::HOUROFDAY + HYPERLINK | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::HYPERLINK + HYPGEOMDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::HYPGEOMDIST + +#I + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + IF | CATEGORY_LOGICAL | PHPExcel_Calculation_Logical::STATEMENT_IF + IFERROR | CATEGORY_LOGICAL | PHPExcel_Calculation_Logical::IFERROR + IMABS | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMABS + IMAGINARY | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMAGINARY + IMARGUMENT | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMARGUMENT + IMCONJUGATE | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMCONJUGATE + IMCOS | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMCOS + IMDIV | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMDIV + IMEXP | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMEXP + IMLN | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMLN + IMLOG10 | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMLOG10 + IMLOG2 | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMLOG2 + IMPOWER | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMPOWER + IMPRODUCT | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMPRODUCT + IMREAL | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMREAL + IMSIN | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMSIN + IMSQRT | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMSQRT + IMSUB | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMSUB + IMSUM | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::IMSUM + INDEX | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::INDEX + INDIRECT | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::INDIRECT + INFO | CATEGORY_INFORMATION | **\*\*\* Not yet Implemented** + INT | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::INT + INTERCEPT | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::INTERCEPT + INTRATE | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::INTRATE + IPMT | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::IPMT + IRR | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::IRR + ISBLANK | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::IS_BLANK + ISERR | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::IS_ERR + ISERROR | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::IS_ERROR + ISEVEN | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::IS_EVEN + ISLOGICAL | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::IS_LOGICAL + ISNA | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::IS_NA + ISNONTEXT | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::IS_NONTEXT + ISNUMBER | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::IS_NUMBER + ISODD | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::IS_ODD + ISPMT | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::ISPMT + ISREF | CATEGORY_INFORMATION | **\*\*\* Not yet Implemented** + ISTEXT | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::IS_TEXT + +#J + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + JIS | CATEGORY_TEXT_AND_DATA | **\*\*\* Not yet Implemented** + +#K + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + KURT | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::KURT + +#L + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + LARGE | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::LARGE + LCM | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::LCM + LEFT | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::LEFT + LEFTB | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::LEFT + LEN | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::STRINGLENGTH + LENB | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::STRINGLENGTH + LINEST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::LINEST + LN | CATEGORY_MATH_AND_TRIG | log + LOG | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::LOG_BASE + LOG10 | CATEGORY_MATH_AND_TRIG | log10 + LOGEST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::LOGEST + LOGINV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::LOGINV + LOGNORMDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::LOGNORMDIST + LOOKUP | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::LOOKUP + LOWER | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::LOWERCASE + +#M + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + MATCH | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::MATCH + MAX | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::MAX + MAXA | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::MAXA + MAXIF | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::MAXIF + MDETERM | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::MDETERM + MDURATION | CATEGORY_FINANCIAL | **\*\*\* Not yet Implemented** + MEDIAN | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::MEDIAN + MEDIANIF | CATEGORY_STATISTICAL | **\*\*\* Not yet Implemented** + MID | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::MID + MIDB | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::MID + MIN | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::MIN + MINA | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::MINA + MINIF | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::MINIF + MINUTE | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::MINUTEOFHOUR + MINVERSE | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::MINVERSE + MIRR | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::MIRR + MMULT | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::MMULT + MOD | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::MOD + MODE | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::MODE + MONTH | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::MONTHOFYEAR + MROUND | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::MROUND + MULTINOMIAL | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::MULTINOMIAL + +#N + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + N | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::N + NA | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::NA + NEGBINOMDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::NEGBINOMDIST + NETWORKDAYS | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::NETWORKDAYS + NOMINAL | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::NOMINAL + NORMDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::NORMDIST + NORMINV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::NORMINV + NORMSDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::NORMSDIST + NORMSINV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::NORMSINV + NOT | CATEGORY_LOGICAL | PHPExcel_Calculation_Logical::NOT + NOW | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::DATETIMENOW + NPER | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::NPER + NPV | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::NPV + +#O + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + OCT2BIN | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::OCTTOBIN + OCT2DEC | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::OCTTODEC + OCT2HEX | CATEGORY_ENGINEERING | PHPExcel_Calculation_Engineering::OCTTOHEX + ODD | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::ODD + ODDFPRICE | CATEGORY_FINANCIAL | **\*\*\* Not yet Implemented** + ODDFYIELD | CATEGORY_FINANCIAL | **\*\*\* Not yet Implemented** + ODDLPRICE | CATEGORY_FINANCIAL | **\*\*\* Not yet Implemented** + ODDLYIELD | CATEGORY_FINANCIAL | **\*\*\* Not yet Implemented** + OFFSET | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::OFFSET + OR | CATEGORY_LOGICAL | PHPExcel_Calculation_Logical::LOGICAL_OR + +#P + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + PEARSON | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::CORREL + PERCENTILE | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::PERCENTILE + PERCENTRANK | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::PERCENTRANK + PERMUT | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::PERMUT + PHONETIC | CATEGORY_TEXT_AND_DATA | **\*\*\* Not yet Implemented** + PI | CATEGORY_MATH_AND_TRIG | pi + PMT | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::PMT + POISSON | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::POISSON + POWER | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::POWER + PPMT | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::PPMT + PRICE | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::PRICE + PRICEDISC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::PRICEDISC + PRICEMAT | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::PRICEMAT + PROB | CATEGORY_STATISTICAL | **\*\*\* Not yet Implemented** + PRODUCT | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::PRODUCT + PROPER | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::PROPERCASE + PV | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::PV + +#Q + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + QUARTILE | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::QUARTILE + QUOTIENT | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::QUOTIENT + +#R + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + RADIANS | CATEGORY_MATH_AND_TRIG | deg2rad + RAND | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::RAND + RANDBETWEEN | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::RAND + RANK | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::RANK + RATE | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::RATE + RECEIVED | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::RECEIVED + REPLACE | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::REPLACE + REPLACEB | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::REPLACE + REPT | CATEGORY_TEXT_AND_DATA | str_repeat + RIGHT | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::RIGHT + RIGHTB | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::RIGHT + ROMAN | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::ROMAN + ROUND | CATEGORY_MATH_AND_TRIG | round + ROUNDDOWN | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::ROUNDDOWN + ROUNDUP | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::ROUNDUP + ROW | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::ROW + ROWS | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::ROWS + RSQ | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::RSQ + RTD | CATEGORY_LOOKUP_AND_REFERENCE | **\*\*\* Not yet Implemented** + +#S + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + SEARCH | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::SEARCHINSENSITIVE + SEARCHB | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::SEARCHINSENSITIVE + SECOND | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::SECONDOFMINUTE + SERIESSUM | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SERIESSUM + SIGN | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SIGN + SIN | CATEGORY_MATH_AND_TRIG | sin + SINH | CATEGORY_MATH_AND_TRIG | sinh + SKEW | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::SKEW + SLN | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::SLN + SLOPE | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::SLOPE + SMALL | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::SMALL + SQRT | CATEGORY_MATH_AND_TRIG | sqrt + SQRTPI | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SQRTPI + STANDARDIZE | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::STANDARDIZE + STDEV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::STDEV + STDEVA | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::STDEVA + STDEVP | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::STDEVP + STDEVPA | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::STDEVPA + STEYX | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::STEYX + SUBSTITUTE | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::SUBSTITUTE + SUBTOTAL | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SUBTOTAL + SUM | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SUM + SUMIF | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SUMIF + SUMIFS | CATEGORY_MATH_AND_TRIG | **\*\*\* Not yet Implemented** + SUMPRODUCT | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SUMPRODUCT + SUMSQ | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SUMSQ + SUMX2MY2 | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SUMX2MY2 + SUMX2PY2 | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SUMX2PY2 + SUMXMY2 | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::SUMXMY2 + SYD | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::SYD + +#T + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + T | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::RETURNSTRING + TAN | CATEGORY_MATH_AND_TRIG | tan + TANH | CATEGORY_MATH_AND_TRIG | tanh + TBILLEQ | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::TBILLEQ + TBILLPRICE | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::TBILLPRICE + TBILLYIELD | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::TBILLYIELD + TDIST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::TDIST + TEXT | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::TEXTFORMAT + TIME | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::TIME + TIMEVALUE | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::TIMEVALUE + TINV | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::TINV + TODAY | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::DATENOW + TRANSPOSE | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::TRANSPOSE + TREND | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::TREND + TRIM | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::TRIMSPACES + TRIMMEAN | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::TRIMMEAN + TRUE | CATEGORY_LOGICAL | PHPExcel_Calculation_Logical::TRUE + TRUNC | CATEGORY_MATH_AND_TRIG | PHPExcel_Calculation_MathTrig::TRUNC + TTEST | CATEGORY_STATISTICAL | **\*\*\* Not yet Implemented** + TYPE | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::TYPE + +#U + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + UPPER | CATEGORY_TEXT_AND_DATA | PHPExcel_Calculation_TextData::UPPERCASE + USDOLLAR | CATEGORY_FINANCIAL | **\*\*\* Not yet Implemented** + +#V + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + VALUE | CATEGORY_TEXT_AND_DATA | **\*\*\* Not yet Implemented** + VAR | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::VARFunc + VARA | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::VARA + VARP | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::VARP + VARPA | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::VARPA + VDB | CATEGORY_FINANCIAL | **\*\*\* Not yet Implemented** + VERSION | CATEGORY_INFORMATION | PHPExcel_Calculation_Functions::VERSION + VLOOKUP | CATEGORY_LOOKUP_AND_REFERENCE | PHPExcel_Calculation_LookupRef::VLOOKUP + +#W + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + WEEKDAY | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::DAYOFWEEK + WEEKNUM | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::WEEKOFYEAR + WEIBULL | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::WEIBULL + WORKDAY | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::WORKDAY + +#X + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + XIRR | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::XIRR + XNPV | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::XNPV + +#Y + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + YEAR | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::YEAR + YEARFRAC | CATEGORY_DATE_AND_TIME | PHPExcel_Calculation_DateTime::YEARFRAC + YIELD | CATEGORY_FINANCIAL | **\*\*\* Not yet Implemented** + YIELDDISC | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::YIELDDISC + YIELDMAT | CATEGORY_FINANCIAL | PHPExcel_Calculation_Financial::YIELDMAT + +#Z + + Excel Function | Category | PHPExcel Function + --------------------|--------------------------------|------------------------------------------- + ZTEST | CATEGORY_STATISTICAL | PHPExcel_Calculation_Statistical::ZTEST From 6a4be7da3c7ac7fb5f00dba5ab18e77a19fc97d8 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 14 May 2013 12:20:28 +0100 Subject: [PATCH 069/467] Update to copyright year in file headers, and minor documentation updates --- Classes/PHPExcel.php | 6 +++--- Classes/PHPExcel/Autoloader.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/APC.php | 6 +++--- .../CachedObjectStorage/CacheBase.php | 6 +++--- .../PHPExcel/CachedObjectStorage/DiscISAM.php | 6 +++--- .../PHPExcel/CachedObjectStorage/ICache.php | 6 +++--- .../PHPExcel/CachedObjectStorage/Igbinary.php | 6 +++--- .../PHPExcel/CachedObjectStorage/Memcache.php | 6 +++--- .../PHPExcel/CachedObjectStorage/Memory.php | 6 +++--- .../CachedObjectStorage/MemoryGZip.php | 6 +++--- .../CachedObjectStorage/MemorySerialized.php | 6 +++--- .../PHPExcel/CachedObjectStorage/PHPTemp.php | 6 +++--- .../PHPExcel/CachedObjectStorage/SQLite.php | 6 +++--- .../PHPExcel/CachedObjectStorage/SQLite3.php | 6 +++--- .../PHPExcel/CachedObjectStorage/Wincache.php | 6 +++--- .../PHPExcel/CachedObjectStorageFactory.php | 6 +++--- .../CalcEngine/CyclicReferenceStack.php | 6 +++--- Classes/PHPExcel/CalcEngine/Logger.php | 6 +++--- Classes/PHPExcel/Calculation.php | 6 +++--- Classes/PHPExcel/Calculation/Database.php | 6 +++--- Classes/PHPExcel/Calculation/DateTime.php | 6 +++--- Classes/PHPExcel/Calculation/Engineering.php | 6 +++--- Classes/PHPExcel/Calculation/Exception.php | 6 +++--- .../PHPExcel/Calculation/ExceptionHandler.php | 6 +++--- Classes/PHPExcel/Calculation/Financial.php | 6 +++--- .../PHPExcel/Calculation/FormulaParser.php | 6 +++--- Classes/PHPExcel/Calculation/FormulaToken.php | 6 +++--- Classes/PHPExcel/Calculation/Function.php | 6 +++--- Classes/PHPExcel/Calculation/Functions.php | 6 +++--- Classes/PHPExcel/Calculation/Logical.php | 6 +++--- Classes/PHPExcel/Calculation/LookupRef.php | 6 +++--- Classes/PHPExcel/Calculation/MathTrig.php | 6 +++--- Classes/PHPExcel/Calculation/Statistical.php | 6 +++--- Classes/PHPExcel/Calculation/TextData.php | 6 +++--- Classes/PHPExcel/Calculation/Token/Stack.php | 6 +++--- Classes/PHPExcel/Cell.php | 6 +++--- Classes/PHPExcel/Cell/AdvancedValueBinder.php | 6 +++--- Classes/PHPExcel/Cell/DataType.php | 6 +++--- Classes/PHPExcel/Cell/DataValidation.php | 6 +++--- Classes/PHPExcel/Cell/DefaultValueBinder.php | 6 +++--- Classes/PHPExcel/Cell/Hyperlink.php | 6 +++--- Classes/PHPExcel/Cell/IValueBinder.php | 6 +++--- Classes/PHPExcel/Chart.php | 6 +++--- Classes/PHPExcel/Chart/DataSeries.php | 6 +++--- Classes/PHPExcel/Chart/DataSeriesValues.php | 6 +++--- Classes/PHPExcel/Chart/Exception.php | 6 +++--- Classes/PHPExcel/Chart/Layout.php | 6 +++--- Classes/PHPExcel/Chart/Legend.php | 6 +++--- Classes/PHPExcel/Chart/PlotArea.php | 6 +++--- Classes/PHPExcel/Chart/Renderer/jpgraph.php | 6 +++--- Classes/PHPExcel/Chart/Title.php | 6 +++--- Classes/PHPExcel/Comment.php | 6 +++--- Classes/PHPExcel/DocumentProperties.php | 6 +++--- Classes/PHPExcel/DocumentSecurity.php | 6 +++--- Classes/PHPExcel/Exception.php | 6 +++--- Classes/PHPExcel/HashTable.php | 6 +++--- Classes/PHPExcel/IComparable.php | 4 ++-- Classes/PHPExcel/IOFactory.php | 6 +++--- Classes/PHPExcel/NamedRange.php | 6 +++--- Classes/PHPExcel/Reader/Abstract.php | 6 +++--- Classes/PHPExcel/Reader/CSV.php | 6 +++--- Classes/PHPExcel/Reader/DefaultReadFilter.php | 6 +++--- Classes/PHPExcel/Reader/Excel2003XML.php | 6 +++--- Classes/PHPExcel/Reader/Excel2007.php | 6 +++--- Classes/PHPExcel/Reader/Excel2007/Chart.php | 6 +++--- Classes/PHPExcel/Reader/Excel2007/Theme.php | 6 +++--- Classes/PHPExcel/Reader/Excel5.php | 6 +++--- Classes/PHPExcel/Reader/Excel5/Escher.php | 6 +++--- Classes/PHPExcel/Reader/Exception.php | 6 +++--- Classes/PHPExcel/Reader/Gnumeric.php | 6 +++--- Classes/PHPExcel/Reader/HTML.php | 6 +++--- Classes/PHPExcel/Reader/IReadFilter.php | 6 +++--- Classes/PHPExcel/Reader/IReader.php | 6 +++--- Classes/PHPExcel/Reader/OOCalc.php | 6 +++--- Classes/PHPExcel/Reader/SYLK.php | 6 +++--- Classes/PHPExcel/ReferenceHelper.php | 6 +++--- Classes/PHPExcel/RichText.php | 6 +++--- Classes/PHPExcel/RichText/ITextElement.php | 4 ++-- Classes/PHPExcel/RichText/Run.php | 4 ++-- Classes/PHPExcel/RichText/TextElement.php | 4 ++-- Classes/PHPExcel/Settings.php | 4 ++-- Classes/PHPExcel/Shared/CodePage.php | 6 +++--- Classes/PHPExcel/Shared/Date.php | 6 +++--- Classes/PHPExcel/Shared/Drawing.php | 6 +++--- Classes/PHPExcel/Shared/Escher.php | 6 +++--- .../PHPExcel/Shared/Escher/DgContainer.php | 6 +++--- .../Escher/DgContainer/SpgrContainer.php | 6 +++--- .../DgContainer/SpgrContainer/SpContainer.php | 6 +++--- .../PHPExcel/Shared/Escher/DggContainer.php | 6 +++--- .../Escher/DggContainer/BstoreContainer.php | 6 +++--- .../DggContainer/BstoreContainer/BSE.php | 6 +++--- .../DggContainer/BstoreContainer/BSE/Blip.php | 6 +++--- Classes/PHPExcel/Shared/Excel5.php | 6 +++--- Classes/PHPExcel/Shared/File.php | 6 +++--- Classes/PHPExcel/Shared/Font.php | 6 +++--- .../Shared/OLE/ChainedBlockStream.php | 2 +- Classes/PHPExcel/Shared/OLERead.php | 4 ++-- Classes/PHPExcel/Shared/PasswordHasher.php | 6 +++--- Classes/PHPExcel/Shared/String.php | 6 +++--- Classes/PHPExcel/Shared/TimeZone.php | 6 +++--- Classes/PHPExcel/Shared/XMLWriter.php | 6 +++--- Classes/PHPExcel/Shared/ZipArchive.php | 6 +++--- Classes/PHPExcel/Shared/ZipStreamWrapper.php | 6 +++--- .../PHPExcel/Shared/trend/bestFitClass.php | 6 +++--- .../Shared/trend/exponentialBestFitClass.php | 6 +++--- .../Shared/trend/linearBestFitClass.php | 6 +++--- .../Shared/trend/logarithmicBestFitClass.php | 6 +++--- .../Shared/trend/polynomialBestFitClass.php | 6 +++--- .../Shared/trend/powerBestFitClass.php | 6 +++--- Classes/PHPExcel/Shared/trend/trendClass.php | 6 +++--- Classes/PHPExcel/Style.php | 6 +++--- Classes/PHPExcel/Style/Alignment.php | 6 +++--- Classes/PHPExcel/Style/Border.php | 6 +++--- Classes/PHPExcel/Style/Borders.php | 6 +++--- Classes/PHPExcel/Style/Color.php | 6 +++--- Classes/PHPExcel/Style/Conditional.php | 6 +++--- Classes/PHPExcel/Style/Fill.php | 6 +++--- Classes/PHPExcel/Style/Font.php | 6 +++--- Classes/PHPExcel/Style/NumberFormat.php | 6 +++--- Classes/PHPExcel/Style/Protection.php | 6 +++--- Classes/PHPExcel/Style/Supervisor.php | 6 +++--- Classes/PHPExcel/Worksheet.php | 6 +++--- Classes/PHPExcel/Worksheet/AutoFilter.php | 6 +++--- .../PHPExcel/Worksheet/AutoFilter/Column.php | 6 +++--- .../Worksheet/AutoFilter/Column/Rule.php | 6 +++--- Classes/PHPExcel/Worksheet/BaseDrawing.php | 6 +++--- Classes/PHPExcel/Worksheet/CellIterator.php | 6 +++--- .../PHPExcel/Worksheet/ColumnDimension.php | 6 +++--- Classes/PHPExcel/Worksheet/Drawing.php | 6 +++--- Classes/PHPExcel/Worksheet/Drawing/Shadow.php | 6 +++--- Classes/PHPExcel/Worksheet/HeaderFooter.php | 6 +++--- .../Worksheet/HeaderFooterDrawing.php | 6 +++--- Classes/PHPExcel/Worksheet/MemoryDrawing.php | 6 +++--- Classes/PHPExcel/Worksheet/PageMargins.php | 6 +++--- Classes/PHPExcel/Worksheet/PageSetup.php | 6 +++--- Classes/PHPExcel/Worksheet/Protection.php | 6 +++--- Classes/PHPExcel/Worksheet/Row.php | 6 +++--- Classes/PHPExcel/Worksheet/RowDimension.php | 6 +++--- Classes/PHPExcel/Worksheet/RowIterator.php | 6 +++--- Classes/PHPExcel/Worksheet/SheetView.php | 6 +++--- Classes/PHPExcel/WorksheetIterator.php | 6 +++--- Classes/PHPExcel/Writer/Abstract.php | 6 +++--- Classes/PHPExcel/Writer/CSV.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Chart.php | 6 +++--- .../PHPExcel/Writer/Excel2007/Comments.php | 6 +++--- .../Writer/Excel2007/ContentTypes.php | 6 +++--- .../PHPExcel/Writer/Excel2007/DocProps.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Drawing.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Rels.php | 6 +++--- .../PHPExcel/Writer/Excel2007/StringTable.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Style.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Theme.php | 6 +++--- .../PHPExcel/Writer/Excel2007/Workbook.php | 6 +++--- .../PHPExcel/Writer/Excel2007/Worksheet.php | 6 +++--- .../PHPExcel/Writer/Excel2007/WriterPart.php | 6 +++--- Classes/PHPExcel/Writer/Excel5.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/BIFFwriter.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Escher.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Font.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Parser.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Workbook.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Xf.php | 6 +++--- Classes/PHPExcel/Writer/Exception.php | 6 +++--- Classes/PHPExcel/Writer/HTML.php | 6 +++--- Classes/PHPExcel/Writer/IWriter.php | 6 +++--- Classes/PHPExcel/Writer/PDF.php | 6 +++--- Classes/PHPExcel/Writer/PDF/Core.php | 6 +++--- Classes/PHPExcel/Writer/PDF/DomPDF.php | 6 +++--- Classes/PHPExcel/Writer/PDF/mPDF.php | 6 +++--- Classes/PHPExcel/Writer/PDF/tcPDF.php | 6 +++--- Classes/PHPExcel/locale/cs/config | 4 ++-- Classes/PHPExcel/locale/cs/functions | 4 ++-- Classes/PHPExcel/locale/da/config | 4 ++-- Classes/PHPExcel/locale/da/functions | 4 ++-- Classes/PHPExcel/locale/de/config | 4 ++-- Classes/PHPExcel/locale/de/functions | 4 ++-- Classes/PHPExcel/locale/en/uk/config | 4 ++-- Classes/PHPExcel/locale/es/config | 4 ++-- Classes/PHPExcel/locale/es/functions | 4 ++-- Classes/PHPExcel/locale/fi/config | 4 ++-- Classes/PHPExcel/locale/fi/functions | 4 ++-- Classes/PHPExcel/locale/fr/config | 4 ++-- Classes/PHPExcel/locale/fr/functions | 4 ++-- Classes/PHPExcel/locale/hu/config | 4 ++-- Classes/PHPExcel/locale/hu/functions | 4 ++-- Classes/PHPExcel/locale/it/config | 4 ++-- Classes/PHPExcel/locale/it/functions | 4 ++-- Classes/PHPExcel/locale/nl/config | 4 ++-- Classes/PHPExcel/locale/nl/functions | 4 ++-- Classes/PHPExcel/locale/no/config | 4 ++-- Classes/PHPExcel/locale/no/functions | 4 ++-- Classes/PHPExcel/locale/pl/config | 4 ++-- Classes/PHPExcel/locale/pl/functions | 4 ++-- Classes/PHPExcel/locale/pt/br/config | 4 ++-- Classes/PHPExcel/locale/pt/config | 4 ++-- Classes/PHPExcel/locale/ru/config | 4 ++-- Classes/PHPExcel/locale/ru/functions | 4 ++-- Classes/PHPExcel/locale/sv/config | 4 ++-- Classes/PHPExcel/locale/tr/config | 4 ++-- Classes/PHPExcel/locale/tr/functions | 4 ++-- .../Functionality Cross-Reference.xls | Bin 38912 -> 38912 bytes Examples/01pharSimple.php | 4 ++-- Examples/01simple-download-pdf.php | 4 ++-- Examples/01simple-download-xls.php | 4 ++-- Examples/01simple-download-xlsx.php | 4 ++-- Examples/01simple.php | 4 ++-- Examples/02types-xls.php | 4 ++-- Examples/02types.php | 4 ++-- Examples/03formulas.php | 4 ++-- Examples/04printing.php | 4 ++-- Examples/05featuredemo.inc.php | 4 ++-- Examples/05featuredemo.php | 4 ++-- .../06largescale-with-cellcaching-sqlite.php | 4 ++-- .../06largescale-with-cellcaching-sqlite3.php | 4 ++-- Examples/06largescale-with-cellcaching.php | 4 ++-- Examples/06largescale-xls.php | 4 ++-- Examples/06largescale.php | 4 ++-- Examples/07reader.php | 4 ++-- Examples/08conditionalformatting.php | 4 ++-- Examples/08conditionalformatting2.php | 4 ++-- Examples/09pagebreaks.php | 4 ++-- Examples/10autofilter-selection-1.php | 4 ++-- Examples/10autofilter-selection-2.php | 4 ++-- Examples/10autofilter-selection-display.php | 4 ++-- Examples/10autofilter.php | 4 ++-- Examples/11documentsecurity-xls.php | 4 ++-- Examples/11documentsecurity.php | 4 ++-- Examples/12cellProtection.php | 4 ++-- Examples/13calculation.php | 4 ++-- Examples/14excel5.php | 4 ++-- Examples/15datavalidation-xls.php | 4 ++-- Examples/15datavalidation.php | 4 ++-- Examples/16csv.php | 4 ++-- Examples/17html.php | 4 ++-- Examples/18extendedcalculation.php | 4 ++-- Examples/19namedrange.php | 4 ++-- Examples/20readexcel5.php | 4 ++-- Examples/21pdf.php | 4 ++-- Examples/22heavilyformatted.php | 4 ++-- Examples/23sharedstyles.php | 4 ++-- Examples/24readfilter.php | 4 ++-- Examples/25inmemoryimage.php | 4 ++-- Examples/26utf8.php | 4 ++-- Examples/27imagesexcel5.php | 4 ++-- Examples/28iterator.php | 4 ++-- Examples/29advancedvaluebinder.php | 4 ++-- Examples/30template.php | 4 ++-- Examples/31docproperties_write-xls.php | 4 ++-- Examples/31docproperties_write.php | 4 ++-- Examples/32chartreadwrite.php | 4 ++-- Examples/33chartcreate-area.php | 4 ++-- Examples/33chartcreate-bar-stacked.php | 4 ++-- Examples/33chartcreate-bar.php | 4 ++-- Examples/33chartcreate-column-2.php | 4 ++-- Examples/33chartcreate-column.php | 4 ++-- Examples/33chartcreate-composite.php | 4 ++-- Examples/33chartcreate-line.php | 4 ++-- Examples/33chartcreate-multiple-charts.php | 4 ++-- Examples/33chartcreate-pie.php | 4 ++-- Examples/33chartcreate-radar.php | 4 ++-- Examples/33chartcreate-scatter.php | 4 ++-- Examples/34chartupdate.php | 4 ++-- Examples/35chartrender.php | 4 ++-- Examples/36chartreadwriteHTML.php | 4 ++-- Examples/36chartreadwritePDF.php | 4 ++-- Examples/37page_layout_view.php | 4 ++-- Examples/Excel2003XMLReader.php | 4 ++-- Examples/GnumericReader.php | 4 ++-- Examples/OOCalcReader.php | 4 ++-- Examples/SylkReader.php | 4 ++-- Examples/XMLReader.php | 4 ++-- Examples/runall.php | 4 ++-- changelog.txt | 4 ++-- install.txt | 6 +++--- unitTests/bootstrap.php | 2 +- 277 files changed, 716 insertions(+), 716 deletions(-) diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index 6090edf59..7bd024346 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -38,7 +38,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel { diff --git a/Classes/PHPExcel/Autoloader.php b/Classes/PHPExcel/Autoloader.php index dc8527013..3878a0919 100644 --- a/Classes/PHPExcel/Autoloader.php +++ b/Classes/PHPExcel/Autoloader.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Autoloader { diff --git a/Classes/PHPExcel/CachedObjectStorage/APC.php b/Classes/PHPExcel/CachedObjectStorage/APC.php index 2e61f03b0..55454fa03 100644 --- a/Classes/PHPExcel/CachedObjectStorage/APC.php +++ b/Classes/PHPExcel/CachedObjectStorage/APC.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index 249abaf54..b04f44a48 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_CachedObjectStorage_CacheBase { diff --git a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php index 956fd56e8..1a319d0f7 100644 --- a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php +++ b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/ICache.php b/Classes/PHPExcel/CachedObjectStorage/ICache.php index 8b82f103c..15d96d863 100644 --- a/Classes/PHPExcel/CachedObjectStorage/ICache.php +++ b/Classes/PHPExcel/CachedObjectStorage/ICache.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php index 7e7d1dfcc..6af87b3e7 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php +++ b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_Igbinary extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/Memcache.php b/Classes/PHPExcel/CachedObjectStorage/Memcache.php index a54405995..2c33050ce 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memcache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memcache.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/Memory.php b/Classes/PHPExcel/CachedObjectStorage/Memory.php index 1e05b062f..bbe3d9ba4 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memory.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memory.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php index 43ed104f8..f8a779161 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_MemoryGZip extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php index 5e1f8381a..9825cabf9 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_MemorySerialized extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php index 5b13e6681..61fb41603 100644 --- a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php +++ b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_PHPTemp extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php index 5e82c089c..bab179adb 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_SQLite extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index f573b0390..7e6924770 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/Wincache.php b/Classes/PHPExcel/CachedObjectStorage/Wincache.php index 97b163979..af31eb7d4 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Wincache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Wincache.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_Wincache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorageFactory.php b/Classes/PHPExcel/CachedObjectStorageFactory.php index 0e7648d88..b5c4f7e14 100644 --- a/Classes/PHPExcel/CachedObjectStorageFactory.php +++ b/Classes/PHPExcel/CachedObjectStorageFactory.php @@ -3,7 +3,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -32,7 +32,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorageFactory { diff --git a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php index c35a1191c..3759517f8 100644 --- a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php +++ b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel_CalcEngine_CyclicReferenceStack * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CalcEngine_CyclicReferenceStack { diff --git a/Classes/PHPExcel/CalcEngine/Logger.php b/Classes/PHPExcel/CalcEngine/Logger.php index 627788f6c..77c42aa51 100644 --- a/Classes/PHPExcel/CalcEngine/Logger.php +++ b/Classes/PHPExcel/CalcEngine/Logger.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CalcEngine_Logger { diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 9e51ea32a..7b935e641 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -57,7 +57,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation { diff --git a/Classes/PHPExcel/Calculation/Database.php b/Classes/PHPExcel/Calculation/Database.php index 02f27006e..0d4fabf3d 100644 --- a/Classes/PHPExcel/Calculation/Database.php +++ b/Classes/PHPExcel/Calculation/Database.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Database { diff --git a/Classes/PHPExcel/Calculation/DateTime.php b/Classes/PHPExcel/Calculation/DateTime.php index 3902924d5..364cc9f68 100644 --- a/Classes/PHPExcel/Calculation/DateTime.php +++ b/Classes/PHPExcel/Calculation/DateTime.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_DateTime { diff --git a/Classes/PHPExcel/Calculation/Engineering.php b/Classes/PHPExcel/Calculation/Engineering.php index b96f16d3c..85a65ca0e 100644 --- a/Classes/PHPExcel/Calculation/Engineering.php +++ b/Classes/PHPExcel/Calculation/Engineering.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -45,7 +45,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Engineering { diff --git a/Classes/PHPExcel/Calculation/Exception.php b/Classes/PHPExcel/Calculation/Exception.php index 9be7e1b65..7666f2f86 100644 --- a/Classes/PHPExcel/Calculation/Exception.php +++ b/Classes/PHPExcel/Calculation/Exception.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Exception extends PHPExcel_Exception { /** diff --git a/Classes/PHPExcel/Calculation/ExceptionHandler.php b/Classes/PHPExcel/Calculation/ExceptionHandler.php index 68c122410..c1148756a 100644 --- a/Classes/PHPExcel/Calculation/ExceptionHandler.php +++ b/Classes/PHPExcel/Calculation/ExceptionHandler.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_ExceptionHandler { /** diff --git a/Classes/PHPExcel/Calculation/Financial.php b/Classes/PHPExcel/Calculation/Financial.php index 4c42277cc..8d359d8c1 100644 --- a/Classes/PHPExcel/Calculation/Financial.php +++ b/Classes/PHPExcel/Calculation/Financial.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -48,7 +48,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Financial { diff --git a/Classes/PHPExcel/Calculation/FormulaParser.php b/Classes/PHPExcel/Calculation/FormulaParser.php index 72b7c6e02..69b1463fd 100644 --- a/Classes/PHPExcel/Calculation/FormulaParser.php +++ b/Classes/PHPExcel/Calculation/FormulaParser.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -54,7 +54,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_FormulaParser { /* Character constants */ diff --git a/Classes/PHPExcel/Calculation/FormulaToken.php b/Classes/PHPExcel/Calculation/FormulaToken.php index a5acbd1bd..6eaa3ee09 100644 --- a/Classes/PHPExcel/Calculation/FormulaToken.php +++ b/Classes/PHPExcel/Calculation/FormulaToken.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -55,7 +55,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_FormulaToken { /* Token types */ diff --git a/Classes/PHPExcel/Calculation/Function.php b/Classes/PHPExcel/Calculation/Function.php index 3ca09904d..b98220086 100644 --- a/Classes/PHPExcel/Calculation/Function.php +++ b/Classes/PHPExcel/Calculation/Function.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Function { /* Function categories */ diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index f06dd6ef2..3e6a56db0 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -54,7 +54,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Functions { diff --git a/Classes/PHPExcel/Calculation/Logical.php b/Classes/PHPExcel/Calculation/Logical.php index 5d6a31c8d..77ae4732b 100644 --- a/Classes/PHPExcel/Calculation/Logical.php +++ b/Classes/PHPExcel/Calculation/Logical.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Logical { diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index a22faff38..96f60206b 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_LookupRef { diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index 134fff7d9..69f296f72 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_MathTrig { diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php index 348b459cf..76760f2d4 100644 --- a/Classes/PHPExcel/Calculation/Statistical.php +++ b/Classes/PHPExcel/Calculation/Statistical.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -57,7 +57,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Statistical { diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php index 46decb3df..d8a98db26 100644 --- a/Classes/PHPExcel/Calculation/TextData.php +++ b/Classes/PHPExcel/Calculation/TextData.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_TextData { diff --git a/Classes/PHPExcel/Calculation/Token/Stack.php b/Classes/PHPExcel/Calculation/Token/Stack.php index 3a94fa29f..05825d157 100644 --- a/Classes/PHPExcel/Calculation/Token/Stack.php +++ b/Classes/PHPExcel/Calculation/Token/Stack.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel_Calculation_Token_Stack * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Token_Stack { diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 9b20b91cc..c34c7c53d 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell { diff --git a/Classes/PHPExcel/Cell/AdvancedValueBinder.php b/Classes/PHPExcel/Cell/AdvancedValueBinder.php index 9c96a1b90..d6c043306 100644 --- a/Classes/PHPExcel/Cell/AdvancedValueBinder.php +++ b/Classes/PHPExcel/Cell/AdvancedValueBinder.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell_AdvancedValueBinder extends PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder { diff --git a/Classes/PHPExcel/Cell/DataType.php b/Classes/PHPExcel/Cell/DataType.php index 762b67f20..6ec30ce8b 100644 --- a/Classes/PHPExcel/Cell/DataType.php +++ b/Classes/PHPExcel/Cell/DataType.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell_DataType { diff --git a/Classes/PHPExcel/Cell/DataValidation.php b/Classes/PHPExcel/Cell/DataValidation.php index 2d43a64c3..80bf91f48 100644 --- a/Classes/PHPExcel/Cell/DataValidation.php +++ b/Classes/PHPExcel/Cell/DataValidation.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell_DataValidation { diff --git a/Classes/PHPExcel/Cell/DefaultValueBinder.php b/Classes/PHPExcel/Cell/DefaultValueBinder.php index b2656c777..6d71a03a1 100644 --- a/Classes/PHPExcel/Cell/DefaultValueBinder.php +++ b/Classes/PHPExcel/Cell/DefaultValueBinder.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder { diff --git a/Classes/PHPExcel/Cell/Hyperlink.php b/Classes/PHPExcel/Cell/Hyperlink.php index 395b656c4..910a04864 100644 --- a/Classes/PHPExcel/Cell/Hyperlink.php +++ b/Classes/PHPExcel/Cell/Hyperlink.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell_Hyperlink { diff --git a/Classes/PHPExcel/Cell/IValueBinder.php b/Classes/PHPExcel/Cell/IValueBinder.php index 937f1eddd..b07df74c5 100644 --- a/Classes/PHPExcel/Cell/IValueBinder.php +++ b/Classes/PHPExcel/Cell/IValueBinder.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_Cell_IValueBinder { diff --git a/Classes/PHPExcel/Chart.php b/Classes/PHPExcel/Chart.php index 4c6d5e322..0e9b487ef 100644 --- a/Classes/PHPExcel/Chart.php +++ b/Classes/PHPExcel/Chart.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart { diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index 68073fa61..68382e789 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_DataSeries { diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index 034ac9e21..f7d068180 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_DataSeriesValues { diff --git a/Classes/PHPExcel/Chart/Exception.php b/Classes/PHPExcel/Chart/Exception.php index f7f2825b2..e7448ce2f 100644 --- a/Classes/PHPExcel/Chart/Exception.php +++ b/Classes/PHPExcel/Chart/Exception.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Exception extends PHPExcel_Exception { /** diff --git a/Classes/PHPExcel/Chart/Layout.php b/Classes/PHPExcel/Chart/Layout.php index f12cae60a..4b2c6af09 100644 --- a/Classes/PHPExcel/Chart/Layout.php +++ b/Classes/PHPExcel/Chart/Layout.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Layout { diff --git a/Classes/PHPExcel/Chart/Legend.php b/Classes/PHPExcel/Chart/Legend.php index 80b54ff8c..0422e9668 100644 --- a/Classes/PHPExcel/Chart/Legend.php +++ b/Classes/PHPExcel/Chart/Legend.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Legend { diff --git a/Classes/PHPExcel/Chart/PlotArea.php b/Classes/PHPExcel/Chart/PlotArea.php index 2a092ce7d..2975c0936 100644 --- a/Classes/PHPExcel/Chart/PlotArea.php +++ b/Classes/PHPExcel/Chart/PlotArea.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_PlotArea { diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index d3d98bf52..9da620dc8 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -3,7 +3,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ * * @category PHPExcel * @package PHPExcel_Chart_Renderer - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,7 +35,7 @@ * * @category PHPExcel * @package PHPExcel_Chart_Renderer - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Renderer_jpgraph { diff --git a/Classes/PHPExcel/Chart/Title.php b/Classes/PHPExcel/Chart/Title.php index 9382346f3..cacfae34d 100644 --- a/Classes/PHPExcel/Chart/Title.php +++ b/Classes/PHPExcel/Chart/Title.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Title { diff --git a/Classes/PHPExcel/Comment.php b/Classes/PHPExcel/Comment.php index af40420ac..a8f599d10 100644 --- a/Classes/PHPExcel/Comment.php +++ b/Classes/PHPExcel/Comment.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Comment implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/DocumentProperties.php b/Classes/PHPExcel/DocumentProperties.php index 952fa7df5..c8099dc1a 100644 --- a/Classes/PHPExcel/DocumentProperties.php +++ b/Classes/PHPExcel/DocumentProperties.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_DocumentProperties { diff --git a/Classes/PHPExcel/DocumentSecurity.php b/Classes/PHPExcel/DocumentSecurity.php index 7f47cbaec..bbbe4b77b 100644 --- a/Classes/PHPExcel/DocumentSecurity.php +++ b/Classes/PHPExcel/DocumentSecurity.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_DocumentSecurity { diff --git a/Classes/PHPExcel/Exception.php b/Classes/PHPExcel/Exception.php index 8ac538654..e25803640 100644 --- a/Classes/PHPExcel/Exception.php +++ b/Classes/PHPExcel/Exception.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Exception extends Exception { /** diff --git a/Classes/PHPExcel/HashTable.php b/Classes/PHPExcel/HashTable.php index 6458291cc..a94e19e81 100644 --- a/Classes/PHPExcel/HashTable.php +++ b/Classes/PHPExcel/HashTable.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_HashTable { diff --git a/Classes/PHPExcel/IComparable.php b/Classes/PHPExcel/IComparable.php index b9d31b1bf..f1c8e9ac5 100644 --- a/Classes/PHPExcel/IComparable.php +++ b/Classes/PHPExcel/IComparable.php @@ -18,7 +18,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -29,7 +29,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_IComparable { diff --git a/Classes/PHPExcel/IOFactory.php b/Classes/PHPExcel/IOFactory.php index 637054630..49580126a 100644 --- a/Classes/PHPExcel/IOFactory.php +++ b/Classes/PHPExcel/IOFactory.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_IOFactory { diff --git a/Classes/PHPExcel/NamedRange.php b/Classes/PHPExcel/NamedRange.php index 4b58df4e1..2ab04aa13 100644 --- a/Classes/PHPExcel/NamedRange.php +++ b/Classes/PHPExcel/NamedRange.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_NamedRange { diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php index 1c61197dd..1a5978d1d 100644 --- a/Classes/PHPExcel/Reader/Abstract.php +++ b/Classes/PHPExcel/Reader/Abstract.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index a0fac3832..d43b374bf 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/DefaultReadFilter.php b/Classes/PHPExcel/Reader/DefaultReadFilter.php index e6863679d..6111c8011 100644 --- a/Classes/PHPExcel/Reader/DefaultReadFilter.php +++ b/Classes/PHPExcel/Reader/DefaultReadFilter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_DefaultReadFilter implements PHPExcel_Reader_IReadFilter { diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index ec910f780..1d16855d6 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 4830934cf..23a58b708 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index c8c35701d..0c33ef287 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Chart.php +++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel2007_Chart { diff --git a/Classes/PHPExcel/Reader/Excel2007/Theme.php b/Classes/PHPExcel/Reader/Excel2007/Theme.php index eb3004321..89176a287 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Theme.php +++ b/Classes/PHPExcel/Reader/Excel2007/Theme.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel2007_Theme { diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 91569d283..495536979 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -73,7 +73,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/Excel5/Escher.php b/Classes/PHPExcel/Reader/Excel5/Escher.php index 8c54aac7b..0970d1baf 100644 --- a/Classes/PHPExcel/Reader/Excel5/Escher.php +++ b/Classes/PHPExcel/Reader/Excel5/Escher.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel5_Escher { diff --git a/Classes/PHPExcel/Reader/Exception.php b/Classes/PHPExcel/Reader/Exception.php index 5a2b2461a..498071149 100644 --- a/Classes/PHPExcel/Reader/Exception.php +++ b/Classes/PHPExcel/Reader/Exception.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Exception extends PHPExcel_Exception { /** diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index c0ad7725a..50e7a8a11 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 3ff0a172e..4780a9557 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_HTML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/IReadFilter.php b/Classes/PHPExcel/Reader/IReadFilter.php index 5f29cd502..584b928dd 100644 --- a/Classes/PHPExcel/Reader/IReadFilter.php +++ b/Classes/PHPExcel/Reader/IReadFilter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_Reader_IReadFilter { diff --git a/Classes/PHPExcel/Reader/IReader.php b/Classes/PHPExcel/Reader/IReader.php index db97bb853..97cc50393 100644 --- a/Classes/PHPExcel/Reader/IReader.php +++ b/Classes/PHPExcel/Reader/IReader.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 460e675b1..aa296098f 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index cacfc87b5..3d3b59cf4 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 0e191c62d..f6fb72fb1 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_ReferenceHelper { diff --git a/Classes/PHPExcel/RichText.php b/Classes/PHPExcel/RichText.php index 848098f29..97c388a20 100644 --- a/Classes/PHPExcel/RichText.php +++ b/Classes/PHPExcel/RichText.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_RichText implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/RichText/ITextElement.php b/Classes/PHPExcel/RichText/ITextElement.php index 27ca6246c..da119dcf0 100644 --- a/Classes/PHPExcel/RichText/ITextElement.php +++ b/Classes/PHPExcel/RichText/ITextElement.php @@ -18,7 +18,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -29,7 +29,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_RichText_ITextElement { diff --git a/Classes/PHPExcel/RichText/Run.php b/Classes/PHPExcel/RichText/Run.php index 24c5fb1c6..7b82a71f3 100644 --- a/Classes/PHPExcel/RichText/Run.php +++ b/Classes/PHPExcel/RichText/Run.php @@ -18,7 +18,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -29,7 +29,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_RichText_Run extends PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement { diff --git a/Classes/PHPExcel/RichText/TextElement.php b/Classes/PHPExcel/RichText/TextElement.php index ce37c066d..71a15d692 100644 --- a/Classes/PHPExcel/RichText/TextElement.php +++ b/Classes/PHPExcel/RichText/TextElement.php @@ -18,7 +18,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -29,7 +29,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement { diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php index eed460c39..8cd1da383 100644 --- a/Classes/PHPExcel/Settings.php +++ b/Classes/PHPExcel/Settings.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Settings - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index 7bc28ae2d..c91ecb363 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_CodePage { diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index 68076ce12..fe8fc6a1c 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -3,7 +3,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -32,7 +32,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Date { diff --git a/Classes/PHPExcel/Shared/Drawing.php b/Classes/PHPExcel/Shared/Drawing.php index d1c33aa99..7f7842b20 100644 --- a/Classes/PHPExcel/Shared/Drawing.php +++ b/Classes/PHPExcel/Shared/Drawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Drawing { diff --git a/Classes/PHPExcel/Shared/Escher.php b/Classes/PHPExcel/Shared/Escher.php index bb695ec72..e3f1d55c6 100644 --- a/Classes/PHPExcel/Shared/Escher.php +++ b/Classes/PHPExcel/Shared/Escher.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher { diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer.php index f0f9ba646..bea1e4494 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DgContainer { diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php index 9c13d3013..827ac3d91 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer { diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php index 0b362dca7..f3a8bab57 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer { diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer.php index 54af54b78..5cb2ceb9b 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DggContainer { diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php index 2f8a8f4fc..fceb57ba6 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer { diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php index 639493598..e278f21fb 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE { diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php index 8c3b11963..b30ef877b 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip { diff --git a/Classes/PHPExcel/Shared/Excel5.php b/Classes/PHPExcel/Shared/Excel5.php index 990407602..b80d61c96 100644 --- a/Classes/PHPExcel/Shared/Excel5.php +++ b/Classes/PHPExcel/Shared/Excel5.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Excel5 { diff --git a/Classes/PHPExcel/Shared/File.php b/Classes/PHPExcel/Shared/File.php index 145f99c5e..e325bb31b 100644 --- a/Classes/PHPExcel/Shared/File.php +++ b/Classes/PHPExcel/Shared/File.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_File { diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php index 1a4f8ae40..32d29df6e 100644 --- a/Classes/PHPExcel/Shared/Font.php +++ b/Classes/PHPExcel/Shared/Font.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Font { diff --git a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php index 77b8ff8a2..64cecec8c 100644 --- a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php +++ b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2012 PHPExcel + * Copyright (C) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/Classes/PHPExcel/Shared/OLERead.php b/Classes/PHPExcel/Shared/OLERead.php index 5319370db..55ed7e0af 100644 --- a/Classes/PHPExcel/Shared/OLERead.php +++ b/Classes/PHPExcel/Shared/OLERead.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Classes/PHPExcel/Shared/PasswordHasher.php b/Classes/PHPExcel/Shared/PasswordHasher.php index 349857525..270e54d7c 100644 --- a/Classes/PHPExcel/Shared/PasswordHasher.php +++ b/Classes/PHPExcel/Shared/PasswordHasher.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_PasswordHasher { diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index d9470b1b5..f72ccc55d 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_String { diff --git a/Classes/PHPExcel/Shared/TimeZone.php b/Classes/PHPExcel/Shared/TimeZone.php index be18f633e..9f1ba4af6 100644 --- a/Classes/PHPExcel/Shared/TimeZone.php +++ b/Classes/PHPExcel/Shared/TimeZone.php @@ -3,7 +3,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -32,7 +32,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_TimeZone { diff --git a/Classes/PHPExcel/Shared/XMLWriter.php b/Classes/PHPExcel/Shared/XMLWriter.php index 2abf451a2..dfbcef89f 100644 --- a/Classes/PHPExcel/Shared/XMLWriter.php +++ b/Classes/PHPExcel/Shared/XMLWriter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -39,7 +39,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_XMLWriter extends XMLWriter { /** Temporary storage method */ diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index f66bbf767..50e2240f5 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_ZipArchive - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -36,7 +36,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_ZipArchive - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_ZipArchive { diff --git a/Classes/PHPExcel/Shared/ZipStreamWrapper.php b/Classes/PHPExcel/Shared/ZipStreamWrapper.php index 1be11f7d0..cc401ce07 100644 --- a/Classes/PHPExcel/Shared/ZipStreamWrapper.php +++ b/Classes/PHPExcel/Shared/ZipStreamWrapper.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_ZipStreamWrapper { /** diff --git a/Classes/PHPExcel/Shared/trend/bestFitClass.php b/Classes/PHPExcel/Shared/trend/bestFitClass.php index fa7ecbed8..f6cbaf981 100644 --- a/Classes/PHPExcel/Shared/trend/bestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/bestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php index 37f3c339c..12166bc2f 100644 --- a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,7 +34,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php index f9d990397..973bcdaef 100644 --- a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,7 +34,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php index 4121cfb97..498fe55b9 100644 --- a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,7 +34,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php index 21c5d582b..f39459e04 100644 --- a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,7 +35,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php index d9525a230..a3f806353 100644 --- a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,7 +34,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/trendClass.php b/Classes/PHPExcel/Shared/trend/trendClass.php index 6c68beaf4..eec10ce4e 100644 --- a/Classes/PHPExcel/Shared/trend/trendClass.php +++ b/Classes/PHPExcel/Shared/trend/trendClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -38,7 +38,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class trendClass { diff --git a/Classes/PHPExcel/Style.php b/Classes/PHPExcel/Style.php index 03777d91b..7669b695c 100644 --- a/Classes/PHPExcel/Style.php +++ b/Classes/PHPExcel/Style.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Alignment.php b/Classes/PHPExcel/Style/Alignment.php index 1e0d2612a..5bf2fa684 100644 --- a/Classes/PHPExcel/Style/Alignment.php +++ b/Classes/PHPExcel/Style/Alignment.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Alignment extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Border.php b/Classes/PHPExcel/Style/Border.php index b0e5a9e7b..b75f82c4d 100644 --- a/Classes/PHPExcel/Style/Border.php +++ b/Classes/PHPExcel/Style/Border.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Border extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Borders.php b/Classes/PHPExcel/Style/Borders.php index 9c79ed8d7..ccb1be813 100644 --- a/Classes/PHPExcel/Style/Borders.php +++ b/Classes/PHPExcel/Style/Borders.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Borders extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Color.php b/Classes/PHPExcel/Style/Color.php index d1aaeb0b7..6248862c7 100644 --- a/Classes/PHPExcel/Style/Color.php +++ b/Classes/PHPExcel/Style/Color.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Color extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Conditional.php b/Classes/PHPExcel/Style/Conditional.php index 9573f5b78..1d3f950c6 100644 --- a/Classes/PHPExcel/Style/Conditional.php +++ b/Classes/PHPExcel/Style/Conditional.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Conditional implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Fill.php b/Classes/PHPExcel/Style/Fill.php index f76b0e9e8..8f4eaf3d8 100644 --- a/Classes/PHPExcel/Style/Fill.php +++ b/Classes/PHPExcel/Style/Fill.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Fill extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Font.php b/Classes/PHPExcel/Style/Font.php index a9f01fbc6..6a00a155f 100644 --- a/Classes/PHPExcel/Style/Font.php +++ b/Classes/PHPExcel/Style/Font.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Font extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index dde1ad991..04d51a8a4 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_NumberFormat extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Protection.php b/Classes/PHPExcel/Style/Protection.php index 67e0bdd2f..a8f65ce37 100644 --- a/Classes/PHPExcel/Style/Protection.php +++ b/Classes/PHPExcel/Style/Protection.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version 1.4.5, 2007-08-23 */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Protection extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Supervisor.php b/Classes/PHPExcel/Style/Supervisor.php index e91f22521..d0fa06b29 100644 --- a/Classes/PHPExcel/Style/Supervisor.php +++ b/Classes/PHPExcel/Style/Supervisor.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Style_Supervisor { diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 81717b6df..3094fb3c5 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index 75a06a446..3872d0e36 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_AutoFilter { diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php index 95f70847f..e43a33362 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_AutoFilter_Column { diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php index a1cbc6fe0..1b8c03eb5 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_AutoFilter_Column_Rule { diff --git a/Classes/PHPExcel/Worksheet/BaseDrawing.php b/Classes/PHPExcel/Worksheet/BaseDrawing.php index 40b94502a..392c4d52a 100644 --- a/Classes/PHPExcel/Worksheet/BaseDrawing.php +++ b/Classes/PHPExcel/Worksheet/BaseDrawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/CellIterator.php b/Classes/PHPExcel/Worksheet/CellIterator.php index 2378340d8..f349d2aa5 100644 --- a/Classes/PHPExcel/Worksheet/CellIterator.php +++ b/Classes/PHPExcel/Worksheet/CellIterator.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -33,7 +33,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_CellIterator implements Iterator { diff --git a/Classes/PHPExcel/Worksheet/ColumnDimension.php b/Classes/PHPExcel/Worksheet/ColumnDimension.php index 3f7cad184..dddb28765 100644 --- a/Classes/PHPExcel/Worksheet/ColumnDimension.php +++ b/Classes/PHPExcel/Worksheet/ColumnDimension.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_ColumnDimension { diff --git a/Classes/PHPExcel/Worksheet/Drawing.php b/Classes/PHPExcel/Worksheet/Drawing.php index 922bbb439..d3efa6a5c 100644 --- a/Classes/PHPExcel/Worksheet/Drawing.php +++ b/Classes/PHPExcel/Worksheet/Drawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet_Drawing - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet_Drawing - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php index 01474cbb0..646b0646b 100644 --- a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php +++ b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet_Drawing - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet_Drawing - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/HeaderFooter.php b/Classes/PHPExcel/Worksheet/HeaderFooter.php index 162482393..88c35daa7 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooter.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -91,7 +91,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_HeaderFooter { diff --git a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php index 2e178f109..7dd03a0fb 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/MemoryDrawing.php b/Classes/PHPExcel/Worksheet/MemoryDrawing.php index c3a5b3bc7..753a135a1 100644 --- a/Classes/PHPExcel/Worksheet/MemoryDrawing.php +++ b/Classes/PHPExcel/Worksheet/MemoryDrawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/PageMargins.php b/Classes/PHPExcel/Worksheet/PageMargins.php index 4221efd44..8fc4cbeca 100644 --- a/Classes/PHPExcel/Worksheet/PageMargins.php +++ b/Classes/PHPExcel/Worksheet/PageMargins.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_PageMargins { diff --git a/Classes/PHPExcel/Worksheet/PageSetup.php b/Classes/PHPExcel/Worksheet/PageSetup.php index c94a02776..e82275457 100644 --- a/Classes/PHPExcel/Worksheet/PageSetup.php +++ b/Classes/PHPExcel/Worksheet/PageSetup.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -102,7 +102,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_PageSetup { diff --git a/Classes/PHPExcel/Worksheet/Protection.php b/Classes/PHPExcel/Worksheet/Protection.php index f4222fc71..e968c1199 100644 --- a/Classes/PHPExcel/Worksheet/Protection.php +++ b/Classes/PHPExcel/Worksheet/Protection.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_Protection { diff --git a/Classes/PHPExcel/Worksheet/Row.php b/Classes/PHPExcel/Worksheet/Row.php index 0a4d1db01..07025e8e0 100644 --- a/Classes/PHPExcel/Worksheet/Row.php +++ b/Classes/PHPExcel/Worksheet/Row.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -33,7 +33,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_Row { diff --git a/Classes/PHPExcel/Worksheet/RowDimension.php b/Classes/PHPExcel/Worksheet/RowDimension.php index 6e8944d6a..1c6abaa42 100644 --- a/Classes/PHPExcel/Worksheet/RowDimension.php +++ b/Classes/PHPExcel/Worksheet/RowDimension.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_RowDimension { diff --git a/Classes/PHPExcel/Worksheet/RowIterator.php b/Classes/PHPExcel/Worksheet/RowIterator.php index c03038c40..840f7f94a 100644 --- a/Classes/PHPExcel/Worksheet/RowIterator.php +++ b/Classes/PHPExcel/Worksheet/RowIterator.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -33,7 +33,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_RowIterator implements Iterator { diff --git a/Classes/PHPExcel/Worksheet/SheetView.php b/Classes/PHPExcel/Worksheet/SheetView.php index 30dbc2be3..f37ba81d2 100644 --- a/Classes/PHPExcel/Worksheet/SheetView.php +++ b/Classes/PHPExcel/Worksheet/SheetView.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_SheetView { diff --git a/Classes/PHPExcel/WorksheetIterator.php b/Classes/PHPExcel/WorksheetIterator.php index cceec417c..27cc1d208 100644 --- a/Classes/PHPExcel/WorksheetIterator.php +++ b/Classes/PHPExcel/WorksheetIterator.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -33,7 +33,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_WorksheetIterator implements Iterator { diff --git a/Classes/PHPExcel/Writer/Abstract.php b/Classes/PHPExcel/Writer/Abstract.php index 7aa50ccaa..8b9fe500e 100644 --- a/Classes/PHPExcel/Writer/Abstract.php +++ b/Classes/PHPExcel/Writer/Abstract.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php index 3563cb23c..2ca7c2581 100644 --- a/Classes/PHPExcel/Writer/CSV.php +++ b/Classes/PHPExcel/Writer/CSV.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_CSV - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_CSV - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { /** diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index f09bb2715..9c78dff48 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 9ef40f5d6..763f8af02 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Comments.php b/Classes/PHPExcel/Writer/Excel2007/Comments.php index 5859896be..cfaffef5a 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Comments.php +++ b/Classes/PHPExcel/Writer/Excel2007/Comments.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Comments extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php index a9b1dd92c..9fdc9dd5e 100644 --- a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php +++ b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_ContentTypes extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/DocProps.php b/Classes/PHPExcel/Writer/Excel2007/DocProps.php index 67ad72df2..3d1497a40 100644 --- a/Classes/PHPExcel/Writer/Excel2007/DocProps.php +++ b/Classes/PHPExcel/Writer/Excel2007/DocProps.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_DocProps extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Drawing.php b/Classes/PHPExcel/Writer/Excel2007/Drawing.php index fbb355665..2bc4b39e3 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Drawing.php +++ b/Classes/PHPExcel/Writer/Excel2007/Drawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Drawing extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Rels.php b/Classes/PHPExcel/Writer/Excel2007/Rels.php index 606e8c79e..fa225eec7 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Rels.php +++ b/Classes/PHPExcel/Writer/Excel2007/Rels.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Rels extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Classes/PHPExcel/Writer/Excel2007/StringTable.php index e43d0f0fd..d6a702768 100644 --- a/Classes/PHPExcel/Writer/Excel2007/StringTable.php +++ b/Classes/PHPExcel/Writer/Excel2007/StringTable.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_StringTable extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Style.php b/Classes/PHPExcel/Writer/Excel2007/Style.php index 90b5e9545..887b5ab9d 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Style.php +++ b/Classes/PHPExcel/Writer/Excel2007/Style.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Style extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Theme.php b/Classes/PHPExcel/Writer/Excel2007/Theme.php index ce3a8c2c8..ba8563921 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Theme.php +++ b/Classes/PHPExcel/Writer/Excel2007/Theme.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Workbook.php b/Classes/PHPExcel/Writer/Excel2007/Workbook.php index 6f3e44a25..db88e74e8 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel2007/Workbook.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index cb1437d32..f70d4fe74 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php index e1242c84c..0667ed4d4 100644 --- a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php +++ b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index 37f5b85c3..5ba73f082 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php index 20c125d0c..d75c33b2d 100644 --- a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php +++ b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -65,7 +65,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_BIFFwriter { diff --git a/Classes/PHPExcel/Writer/Excel5/Escher.php b/Classes/PHPExcel/Writer/Excel5/Escher.php index 91fc27b05..8286bc12b 100644 --- a/Classes/PHPExcel/Writer/Excel5/Escher.php +++ b/Classes/PHPExcel/Writer/Excel5/Escher.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Escher { diff --git a/Classes/PHPExcel/Writer/Excel5/Font.php b/Classes/PHPExcel/Writer/Excel5/Font.php index f59cce66e..a0936eb87 100644 --- a/Classes/PHPExcel/Writer/Excel5/Font.php +++ b/Classes/PHPExcel/Writer/Excel5/Font.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Font { diff --git a/Classes/PHPExcel/Writer/Excel5/Parser.php b/Classes/PHPExcel/Writer/Excel5/Parser.php index 579fecfac..2018c5ba1 100644 --- a/Classes/PHPExcel/Writer/Excel5/Parser.php +++ b/Classes/PHPExcel/Writer/Excel5/Parser.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -55,7 +55,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Parser { diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index 2a2eb4725..915096fa2 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -66,7 +66,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter { diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index ff675b4cc..cc39513fe 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -66,7 +66,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter { diff --git a/Classes/PHPExcel/Writer/Excel5/Xf.php b/Classes/PHPExcel/Writer/Excel5/Xf.php index 1653c7fc4..241b5f894 100644 --- a/Classes/PHPExcel/Writer/Excel5/Xf.php +++ b/Classes/PHPExcel/Writer/Excel5/Xf.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -66,7 +66,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Xf { diff --git a/Classes/PHPExcel/Writer/Exception.php b/Classes/PHPExcel/Writer/Exception.php index 70c8418ac..b5d437d4e 100644 --- a/Classes/PHPExcel/Writer/Exception.php +++ b/Classes/PHPExcel/Writer/Exception.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Exception extends PHPExcel_Exception { /** diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 874456986..318fd988a 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_HTML - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_HTML - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { /** diff --git a/Classes/PHPExcel/Writer/IWriter.php b/Classes/PHPExcel/Writer/IWriter.php index af50b55d3..6bb8a3954 100644 --- a/Classes/PHPExcel/Writer/IWriter.php +++ b/Classes/PHPExcel/Writer/IWriter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/PDF.php b/Classes/PHPExcel/Writer/PDF.php index d346f8afe..a2524d4db 100644 --- a/Classes/PHPExcel/Writer/PDF.php +++ b/Classes/PHPExcel/Writer/PDF.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_PDF { diff --git a/Classes/PHPExcel/Writer/PDF/Core.php b/Classes/PHPExcel/Writer/PDF/Core.php index 0925ca3a3..24d104ce9 100644 --- a/Classes/PHPExcel/Writer/PDF/Core.php +++ b/Classes/PHPExcel/Writer/PDF/Core.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Writer_PDF_Core extends PHPExcel_Writer_HTML { diff --git a/Classes/PHPExcel/Writer/PDF/DomPDF.php b/Classes/PHPExcel/Writer/PDF/DomPDF.php index db3045d46..4563a9546 100644 --- a/Classes/PHPExcel/Writer/PDF/DomPDF.php +++ b/Classes/PHPExcel/Writer/PDF/DomPDF.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -39,7 +39,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_PDF_DomPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/PDF/mPDF.php b/Classes/PHPExcel/Writer/PDF/mPDF.php index ef050d7bd..1e20e6feb 100644 --- a/Classes/PHPExcel/Writer/PDF/mPDF.php +++ b/Classes/PHPExcel/Writer/PDF/mPDF.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -39,7 +39,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_PDF_mPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/PDF/tcPDF.php b/Classes/PHPExcel/Writer/PDF/tcPDF.php index 25bfb50c6..2895512e4 100644 --- a/Classes/PHPExcel/Writer/PDF/tcPDF.php +++ b/Classes/PHPExcel/Writer/PDF/tcPDF.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2012 PHPExcel + * Copyright (c) 2006 - 2013 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_PDF_tcPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/locale/cs/config b/Classes/PHPExcel/locale/cs/config index a4af0566e..42cdf3267 100644 --- a/Classes/PHPExcel/locale/cs/config +++ b/Classes/PHPExcel/locale/cs/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/cs/functions b/Classes/PHPExcel/locale/cs/functions index b895196a3..c0a3cbbf9 100644 --- a/Classes/PHPExcel/locale/cs/functions +++ b/Classes/PHPExcel/locale/cs/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/da/config b/Classes/PHPExcel/locale/da/config index 4093fc660..ae5900311 100644 --- a/Classes/PHPExcel/locale/da/config +++ b/Classes/PHPExcel/locale/da/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/da/functions b/Classes/PHPExcel/locale/da/functions index 86adec51d..26e0310c1 100644 --- a/Classes/PHPExcel/locale/da/functions +++ b/Classes/PHPExcel/locale/da/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/de/config b/Classes/PHPExcel/locale/de/config index e4bff5946..aa0228e7f 100644 --- a/Classes/PHPExcel/locale/de/config +++ b/Classes/PHPExcel/locale/de/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/de/functions b/Classes/PHPExcel/locale/de/functions index 3a9d426aa..3147f9c8b 100644 --- a/Classes/PHPExcel/locale/de/functions +++ b/Classes/PHPExcel/locale/de/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/en/uk/config b/Classes/PHPExcel/locale/en/uk/config index 255cf3723..532080b57 100644 --- a/Classes/PHPExcel/locale/en/uk/config +++ b/Classes/PHPExcel/locale/en/uk/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/es/config b/Classes/PHPExcel/locale/es/config index a387b64b1..96cfa69db 100644 --- a/Classes/PHPExcel/locale/es/config +++ b/Classes/PHPExcel/locale/es/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/es/functions b/Classes/PHPExcel/locale/es/functions index c57b9341f..48762695b 100644 --- a/Classes/PHPExcel/locale/es/functions +++ b/Classes/PHPExcel/locale/es/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/fi/config b/Classes/PHPExcel/locale/fi/config index f080c8790..498cf4ceb 100644 --- a/Classes/PHPExcel/locale/fi/config +++ b/Classes/PHPExcel/locale/fi/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/fi/functions b/Classes/PHPExcel/locale/fi/functions index d38d724e7..6a7c2b36f 100644 --- a/Classes/PHPExcel/locale/fi/functions +++ b/Classes/PHPExcel/locale/fi/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/fr/config b/Classes/PHPExcel/locale/fr/config index cab84aacf..1f5db88c4 100644 --- a/Classes/PHPExcel/locale/fr/config +++ b/Classes/PHPExcel/locale/fr/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/fr/functions b/Classes/PHPExcel/locale/fr/functions index 915fa87ec..03b80e5a4 100644 --- a/Classes/PHPExcel/locale/fr/functions +++ b/Classes/PHPExcel/locale/fr/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/hu/config b/Classes/PHPExcel/locale/hu/config index 80278165b..080b2018f 100644 --- a/Classes/PHPExcel/locale/hu/config +++ b/Classes/PHPExcel/locale/hu/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/hu/functions b/Classes/PHPExcel/locale/hu/functions index 5bed391ad..200d3f71f 100644 --- a/Classes/PHPExcel/locale/hu/functions +++ b/Classes/PHPExcel/locale/hu/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/it/config b/Classes/PHPExcel/locale/it/config index 1d9b8847d..c3afa754b 100644 --- a/Classes/PHPExcel/locale/it/config +++ b/Classes/PHPExcel/locale/it/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/it/functions b/Classes/PHPExcel/locale/it/functions index c262d3bb3..d371f3d72 100644 --- a/Classes/PHPExcel/locale/it/functions +++ b/Classes/PHPExcel/locale/it/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/nl/config b/Classes/PHPExcel/locale/nl/config index 5818fcc8e..48dcc15b5 100644 --- a/Classes/PHPExcel/locale/nl/config +++ b/Classes/PHPExcel/locale/nl/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/nl/functions b/Classes/PHPExcel/locale/nl/functions index a1af0427a..573600aca 100644 --- a/Classes/PHPExcel/locale/nl/functions +++ b/Classes/PHPExcel/locale/nl/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/no/config b/Classes/PHPExcel/locale/no/config index 0d4d4b70e..bf2d34a7f 100644 --- a/Classes/PHPExcel/locale/no/config +++ b/Classes/PHPExcel/locale/no/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/no/functions b/Classes/PHPExcel/locale/no/functions index 9675504e4..10d0a2076 100644 --- a/Classes/PHPExcel/locale/no/functions +++ b/Classes/PHPExcel/locale/no/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/pl/config b/Classes/PHPExcel/locale/pl/config index 48be512e3..4dd75bee6 100644 --- a/Classes/PHPExcel/locale/pl/config +++ b/Classes/PHPExcel/locale/pl/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/pl/functions b/Classes/PHPExcel/locale/pl/functions index 1d7d4d06f..1881a71e5 100644 --- a/Classes/PHPExcel/locale/pl/functions +++ b/Classes/PHPExcel/locale/pl/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/pt/br/config b/Classes/PHPExcel/locale/pt/br/config index a5e83b9d4..45b6fbd92 100644 --- a/Classes/PHPExcel/locale/pt/br/config +++ b/Classes/PHPExcel/locale/pt/br/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/pt/config b/Classes/PHPExcel/locale/pt/config index e7e08cbf6..8bb8d8b8e 100644 --- a/Classes/PHPExcel/locale/pt/config +++ b/Classes/PHPExcel/locale/pt/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/ru/config b/Classes/PHPExcel/locale/ru/config index 7fb640647..56e45bfda 100644 --- a/Classes/PHPExcel/locale/ru/config +++ b/Classes/PHPExcel/locale/ru/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/ru/functions b/Classes/PHPExcel/locale/ru/functions index 8df03251d..5ff6d4fbf 100644 --- a/Classes/PHPExcel/locale/ru/functions +++ b/Classes/PHPExcel/locale/ru/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/sv/config b/Classes/PHPExcel/locale/sv/config index 0e29095eb..726f77164 100644 --- a/Classes/PHPExcel/locale/sv/config +++ b/Classes/PHPExcel/locale/sv/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/tr/config b/Classes/PHPExcel/locale/tr/config index 64771bbb3..b69d4257a 100644 --- a/Classes/PHPExcel/locale/tr/config +++ b/Classes/PHPExcel/locale/tr/config @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Settings -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Classes/PHPExcel/locale/tr/functions b/Classes/PHPExcel/locale/tr/functions index 62960d632..45d7df1fe 100644 --- a/Classes/PHPExcel/locale/tr/functions +++ b/Classes/PHPExcel/locale/tr/functions @@ -1,7 +1,7 @@ ## ## PHPExcel ## -## Copyright (c) 2006 - 2011 PHPExcel +## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ ## ## @category PHPExcel ## @package PHPExcel_Calculation -## @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) ## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL ## @version ##VERSION##, ##DATE## ## diff --git a/Documentation/Functionality Cross-Reference.xls b/Documentation/Functionality Cross-Reference.xls index 905f944306e493352f14bd1fbd5efe34ae9534cf..227fd612f0a99ae0c2b318f36d8ad63b4513ed93 100644 GIT binary patch delta 380 zcmZqJz|^pTX~P47$p`q^CjS%Qn|wz=LZXI4grSCm0SSaK95y`nX0wW*CjaCMvI2}j zlOM_|OkN-s>tF^QpvXQ35g^IL5R3%v88{gJ zGH?OKIf0_OU{!oTk_)D0vxbMaBG8JGOjjVe3q(%Ja&-@4CFNfb*Cb zT#$I2C~{m#a^XN7L6dv3K*nCma=NOqcUo6q* MpDf_Wv8Y7^07HXOb^rhX delta 376 zcmZqJz|^pTX~P47$v*@{Cf^Z|kf`AhVW{C?Kms8Q>a2{fH>(J0@=snMDZm&sxj{;W zhk=0ws3w|0g@Zw4@RM1hk4r0&&%I#wi0g_A%K}gV^frH^M0~b)7 z6DX<+R>cP-xnOEGYj}7o0?jJPbOn;TK;)z>SNC9sGN3Au&M*c>26qMnIFAX1$BDw@ zLgIx3bp%iD$pRUBDa+L|n4uDCMkI=fkw6zC%#Q@R6PX7zadJTRCZ=!gn^|(A89{Vn z?q)_t*U9G!Bqr Date: Wed, 15 May 2013 18:02:24 +0100 Subject: [PATCH 070/467] Manual PR merge to remove redundant brackets after throw in 2 files, courtesy of kachkaev --- Classes/PHPExcel/Calculation.php | 6 +++--- Classes/PHPExcel/Cell.php | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 7b935e641..0e6e2306e 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2209,7 +2209,7 @@ public function calculate(PHPExcel_Cell $pCell = NULL) { try { return $this->calculateCellValue($pCell); } catch (PHPExcel_Exception $e) { - throw(new PHPExcel_Calculation_Exception($e->getMessage())); + throw new PHPExcel_Calculation_Exception($e->getMessage()); } } // function calculate() @@ -2243,7 +2243,7 @@ public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE try { $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); } catch (PHPExcel_Exception $e) { - throw(new PHPExcel_Calculation_Exception($e->getMessage())); + throw new PHPExcel_Calculation_Exception($e->getMessage()); } if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { @@ -2323,7 +2323,7 @@ public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = try { $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); } catch (PHPExcel_Exception $e) { - throw(new PHPExcel_Calculation_Exception($e->getMessage())); + throw new PHPExcel_Calculation_Exception($e->getMessage()); } // Reset calculation cacheing to its previous state diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index c34c7c53d..6664e6450 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -295,10 +295,8 @@ public function getCalculatedValue($resetLog = TRUE) } //echo 'Calculation Exception: '.$ex->getMessage().PHP_EOL; $result = '#N/A'; - throw( - new PHPExcel_Calculation_Exception( - $this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage() - ) + throw new PHPExcel_Calculation_Exception( + $this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage() ); } From b075996eee08d113a2d64b0102f09492b1ef26fd Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 16 May 2013 17:34:11 +0100 Subject: [PATCH 071/467] Markdown documentation --- .../FunctionReference/01-Introduction.md | 11 + .../02-01-Date-and-Time-Handling.md | 123 ++ .../02-General-Introduction.md | 36 + .../FunctionReference/03-01-Cube-Functions.md | 34 + .../03-02-Database-Functions.md | 618 ++++++++++ .../03-03-Date-and-Time-Functions.md | 1000 +++++++++++++++++ 6 files changed, 1822 insertions(+) create mode 100644 Documentation/markdown/CalculationEngine/FunctionReference/01-Introduction.md create mode 100644 Documentation/markdown/CalculationEngine/FunctionReference/02-01-Date-and-Time-Handling.md create mode 100644 Documentation/markdown/CalculationEngine/FunctionReference/02-General-Introduction.md create mode 100644 Documentation/markdown/CalculationEngine/FunctionReference/03-01-Cube-Functions.md create mode 100644 Documentation/markdown/CalculationEngine/FunctionReference/03-02-Database-Functions.md create mode 100644 Documentation/markdown/CalculationEngine/FunctionReference/03-03-Date-and-Time-Functions.md diff --git a/Documentation/markdown/CalculationEngine/FunctionReference/01-Introduction.md b/Documentation/markdown/CalculationEngine/FunctionReference/01-Introduction.md new file mode 100644 index 000000000..2ea3a5057 --- /dev/null +++ b/Documentation/markdown/CalculationEngine/FunctionReference/01-Introduction.md @@ -0,0 +1,11 @@ +# Calculation Engine - Formula Function Reference + +## Frequently asked questions + +The up-to-date F.A.Q. page for PHPExcel can be found on [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=FAQ&referringTitle=Requirements][1]. + +### Formulas don’t seem to be calculated in Excel2003 using compatibility pack? + +This is normal behaviour of the compatibility pack, Excel2007 displays this correctly. Use PHPExcel_Writer_Excel5 if you really need calculated values, or force recalculation in Excel2003. + + [1]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=FAQ&referringTitle=Requirements diff --git a/Documentation/markdown/CalculationEngine/FunctionReference/02-01-Date-and-Time-Handling.md b/Documentation/markdown/CalculationEngine/FunctionReference/02-01-Date-and-Time-Handling.md new file mode 100644 index 000000000..82993bbcc --- /dev/null +++ b/Documentation/markdown/CalculationEngine/FunctionReference/02-01-Date-and-Time-Handling.md @@ -0,0 +1,123 @@ +# Calculation Engine - Formula Function Reference + +## Function Reference + +### Handling Date and Time Values + +#### Excel functions that return a Date and Time value + +Any of the Date and Time functions that return a date value in Excel can return either an Excel timestamp or a PHP timestamp or date object. + +It is possible for scripts to change the data type used for returning date values by calling the PHPExcel_Calculation_Functions::setReturnDateType() method: + +```php +PHPExcel_Calculation_Functions::setReturnDateType($returnDateType); +``` + +where the following constants can be used for $returnDateType + + - PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC + - PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT + - PHPExcel_Calculation_Functions::RETURNDATE_EXCEL + +The method will return a Boolean True on success, False on failure (e.g. if an invalid value is passed in for the return date type). + +The PHPExcel_Calculation_Functions::getReturnDateType() method can be used to determine the current value of this setting: + +```php +$returnDateType = PHPExcel_Calculation_Functions::getReturnDateType(); +``` + +The default is RETURNDATE_PHP_NUMERIC. + +##### PHP Timestamps + +If RETURNDATE_PHP_NUMERIC is set for the Return Date Type, then any date value returned to the calling script by any access to the Date and Time functions in Excel will be an integer value that represents the number of seconds from the PHP/Unix base date. The PHP/Unix base date (0) is 00:00 UST on 1st January 1970. This value can be positive or negative: so a value of -3600 would be 23:00 hrs on 31st December 1969; while a value of +3600 would be 01:00 hrs on 1st January 1970. This gives PHP a date range of between 14th December 1901 and 19th January 2038. + +##### PHP DateTime Objects + +If the Return Date Type is set for RETURNDATE_PHP_NUMERIC, then any date value returned to the calling script by any access to the Date and Time functions in Excel will be a PHP date/time object. + +##### Excel Timestamps + +If RETURNDATE_EXCEL is set for the Return Date Type, then the returned date value by any access to the Date and Time functions in Excel will be a floating point value that represents a number of days from the Excel base date. The Excel base date is determined by which calendar Excel uses: the Windows 1900 or the Mac 1904 calendar. 1st January 1900 is the base date for the Windows 1900 calendar while 1st January 1904 is the base date for the Mac 1904 calendar. + +It is possible for scripts to change the calendar used for calculating Excel date values by calling the PHPExcel_Shared_Date::setExcelCalendar() method: + +```php +PHPExcel_Shared_Date::setExcelCalendar($baseDate); +``` + +where the following constants can be used for $baseDate + + - PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 + - PHPExcel_Shared_Date::CALENDAR_MAC_1904 + +The method will return a Boolean True on success, False on failure (e.g. if an invalid value is passed in). + +The PHPExcel_Shared_Date::getExcelCalendar() method can be used to determine the current value of this setting: + +```php +$baseDate = PHPExcel_Shared_Date::getExcelCalendar(); +``` +The default is CALENDAR_WINDOWS_1900. + +##### Functions that return a Date/Time Value + + - DATE + - DATEVALUE + - EDATE + - EOMONTH + - NOW + - TIME + - TIMEVALUE + - TODAY + +#### Excel functions that accept Date and Time values as parameters + +Date values passed in as parameters to a function can be an Excel timestamp or a PHP timestamp; or date object; or a string containing a date value (e.g. '1-Jan-2009'). PHPExcel will attempt to identify their type based on the PHP datatype: + +An integer numeric value will be treated as a PHP/Unix timestamp. A real (floating point) numeric value will be treated as an Excel date/timestamp. Any PHP DateTime object will be treated as a DateTime object. Any string value (even one containing straight numeric data) will be converted to a date/time object for validation as a date value based on the server locale settings, so passing through an ambiguous value of '07/08/2008' will be treated as 7th August 2008 if your server settings are UK, but as 8th July 2008 if your server settings are US. However, if you pass through a value such as '31/12/2008' that would be considered an error by a US-based server, but which is not ambiguous, then PHPExcel will attempt to correct this to 31st December 2008. If the content of the string doesn’t match any of the formats recognised by the php date/time object implementation of strtotime() (which can handle a wider range of formats than the normal strtotime() function), then the function will return a '#VALUE' error. However, Excel recommends that you should always use date/timestamps for your date functions, and the recommendation for PHPExcel is the same: avoid strings because the result is not predictable. + +The same principle applies when data is being written to Excel. Cells containing date actual values (rather than Excel functions that return a date value) are always written as Excel dates, converting where necessary. If a cell formatted as a date contains an integer or date/time object value, then it is converted to an Excel value for writing: if a cell formatted as a date contains a real value, then no conversion is required. Note that string values are written as strings rather than converted to Excel date timestamp values. + +##### Functions that expect a Date/Time Value + + - DATEDIF + - DAY + - DAYS360 + - EDATE + - EOMONTH + - HOUR + - MINUTE + - MONTH + - NETWORKDAYS + - SECOND + - WEEKDAY + - WEEKNUM + - WORKDAY + - YEAR + - YEARFRAC + +#### Helper Methods + +In addition to the setExcelCalendar() and getExcelCalendar() methods, a number of other methods are available in the PHPExcel_Shared_Date class that can help when working with dates: + +##### PHPExcel_Shared_Date::ExcelToPHP($excelDate) + +Converts a date/time from an Excel date timestamp to return a PHP serialized date/timestamp. + +Note that this method does not trap for Excel dates that fall outside of the valid range for a PHP date timestamp. + +##### PHPExcel_Shared_Date::ExcelToPHPObject($excelDate) + +Converts a date from an Excel date/timestamp to return a PHP DateTime object. + +##### PHPExcel_Shared_Date::PHPToExcel($PHPDate) + +Converts a PHP serialized date/timestamp or a PHP DateTime object to return an Excel date timestamp. + +##### PHPExcel_Shared_Date::FormattedPHPToExcel($year, $month, $day, $hours=0, $minutes=0, $seconds=0) + +Takes year, month and day values (and optional hour, minute and second values) and returns an Excel date timestamp value. + diff --git a/Documentation/markdown/CalculationEngine/FunctionReference/02-General-Introduction.md b/Documentation/markdown/CalculationEngine/FunctionReference/02-General-Introduction.md new file mode 100644 index 000000000..b714d5118 --- /dev/null +++ b/Documentation/markdown/CalculationEngine/FunctionReference/02-General-Introduction.md @@ -0,0 +1,36 @@ +# Calculation Engine - Formula Function Reference + +## General Introduction + +### Function that are not Supported in Excel5 + +Not all functions are supported by the Excel 5 Writer. Use of these functions within your workbooks will result in an error when trying to write to Excel5. + +The following is the list of those functions that are implemented within PHPExcel, but that cannot currently be written to Excel 5. + +#### Cube Functions + + Excel Function | Notes + --------------------|--------- + CUBEKPIMEMBER | Not yet Implemented + CUBEMEMBER | Not yet Implemented + CUBEMEMBERPROPERTY | Not yet Implemented + CUBERANKEDMEMBER | Not yet Implemented + CUBESET | Not yet Implemented + CUBESETCOUNT | Not yet Implemented + CUBEVALUE | Not yet Implemented + + +#### Database Functions + + Excel Function | Notes + ---------------|--------- + + +#### Date and Time Functions + + Excel Function | Notes + ---------------|--------- + EDATE | Not a standard function within Excel 5, but an add-in from the Analysis ToolPak. + EOMONTH | Not a standard function within Excel 5, but an add-in from the Analysis ToolPak. + diff --git a/Documentation/markdown/CalculationEngine/FunctionReference/03-01-Cube-Functions.md b/Documentation/markdown/CalculationEngine/FunctionReference/03-01-Cube-Functions.md new file mode 100644 index 000000000..8c946321d --- /dev/null +++ b/Documentation/markdown/CalculationEngine/FunctionReference/03-01-Cube-Functions.md @@ -0,0 +1,34 @@ +# Calculation Engine - Formula Function Reference + +## Function Reference + +### Cube Functions + +#### CUBEKPIMEMBER + +Not yet implemented. + +#### CUBEMEMBER + +Not yet implemented. + +#### CUBEMEMBERPROPERTY + +Not yet implemented. + +#### CUBERANKEDMEMBER + +Not yet implemented. + +#### CUBESET + +Not yet implemented. + +#### CUBESETCOUNT + +Not yet implemented. + +#### CUBEVALUE + +Not yet implemented. + diff --git a/Documentation/markdown/CalculationEngine/FunctionReference/03-02-Database-Functions.md b/Documentation/markdown/CalculationEngine/FunctionReference/03-02-Database-Functions.md new file mode 100644 index 000000000..a50e1c853 --- /dev/null +++ b/Documentation/markdown/CalculationEngine/FunctionReference/03-02-Database-Functions.md @@ -0,0 +1,618 @@ +# Calculation Engine - Formula Function Reference + +## Function Reference + +### Database Functions + +#### DAVERAGE + +The DAVERAGE function returns the average value of the cells in a column of a list or database that match conditions you specify. + +##### Syntax + +``` +DAVERAGE (database, field, criteria) +``` + +##### Parameters + +**database** The range of cells that makes up the list or database. + +A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column. + +**field** Indicates which column of the database is used in the function. + +Enter the column label as a string (enclosed between double quotation marks), such as "Age" or "Yield," or as a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on. + +**criteria** The range of cells that contains the conditions you specify. + +You can use any range for the criteria argument, as long as it includes at least one column label and at least one cell below the column label in which you specify a condition for the column. + +##### Return Value + +**float** The average value of the matching cells. + +This is the statistical mean. + +##### Examples + +```php +$database = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ), + array( 'Apple', 18, 20, 14, 105.00 ), + array( 'Pear', 12, 12, 10, 96.00 ), + array( 'Cherry', 13, 14, 9, 105.00 ), + array( 'Apple', 14, 15, 10, 75.00 ), + array( 'Pear', 9, 8, 8, 76.80 ), + array( 'Apple', 8, 9, 6, 45.00 ), +); + +$criteria = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ), + array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ), + array( '="=Pear"', NULL, NULL, NULL, NULL, NULL ), +); + +$worksheet->fromArray( $criteria, NULL, 'A1' ) + ->fromArray( $database, NULL, 'A4' ); + +$worksheet->setCellValue('A12', '=DAVERAGE(A4:E10,"Yield",A1:B2)'); + +$retVal = $worksheet->getCell('A12')->getCalculatedValue(); +// $retVal = 12 +``` + +##### Notes + +There are no additional notes on this function + +#### DCOUNT + +The DCOUNT function returns the count of cells that contain a number in a column of a list or database matching conditions that you specify. + +##### Syntax + +``` +DCOUNT(database, [field], criteria) +``` + +##### Parameters + +**database** The range of cells that makes up the list or database. + +A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column. + +**field** Indicates which column of the database is used in the function. + +Enter the column label as a string (enclosed between double quotation marks), such as "Age" or "Yield," or as a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on. + +**criteria** The range of cells that contains the conditions you specify. + +You can use any range for the criteria argument, as long as it includes at least one column label and at least one cell below the column label in which you specify a condition for the column. + +##### Return Value + +**float** The count of the matching cells. + +##### Examples + +```php +$database = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ), + array( 'Apple', 18, 20, 14, 105.00 ), + array( 'Pear', 12, 12, 10, 96.00 ), + array( 'Cherry', 13, 14, 9, 105.00 ), + array( 'Apple', 14, 15, 10, 75.00 ), + array( 'Pear', 9, 8, 8, 76.80 ), + array( 'Apple', 8, 9, 6, 45.00 ), +); + +$criteria = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ), + array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ), + array( '="=Pear"', NULL, NULL, NULL, NULL, NULL ), +); + +$worksheet->fromArray( $criteria, NULL, 'A1' ) + ->fromArray( $database, NULL, 'A4' ); + +$worksheet->setCellValue('A12', '=DCOUNT(A4:E10,"Height",A1:B3)'); + +$retVal = $worksheet->getCell('A12')->getCalculatedValue(); + +// $retVal = 3 +``` + +##### Notes + +In MS Excel, The field argument is optional. If field is omitted, DCOUNT counts all records in the database that match the criteria. This logic has not yet been implemented in PHPExcel. + +#### DCOUNTA + +The DCOUNT function returns the count of cells that aren’t blank in a column of a list or database and that match conditions that you specify. + +##### Syntax + +``` +DCOUNTA(database, [field], criteria) +``` + +##### Parameters + +**database** The range of cells that makes up the list or database. + +A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column. + +**field** Indicates which column of the database is used in the function. + +Enter the column label as a string (enclosed between double quotation marks), such as "Age" or "Yield," or as a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on. + +**criteria** The range of cells that contains the conditions you specify. + +You can use any range for the criteria argument, as long as it includes at least one column label and at least one cell below the column label in which you specify a condition for the column. + +##### Return Value + +**float** The count of the matching cells. + +##### Examples + +```php +$database = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ), + array( 'Apple', 18, 20, 14, 105.00 ), + array( 'Pear', 12, 12, 10, 96.00 ), + array( 'Cherry', 13, 14, 9, 105.00 ), + array( 'Apple', 14, 15, 10, 75.00 ), + array( 'Pear', 9, 8, 8, 76.80 ), + array( 'Apple', 8, 9, 6, 45.00 ), +); + +$criteria = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ), + array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ), + array( '="=Pear"', NULL, NULL, NULL, NULL, NULL ), +); + +$worksheet->fromArray( $criteria, NULL, 'A1' ) + ->fromArray( $database, NULL, 'A4' ); + +$worksheet->setCellValue('A12', '=DCOUNTA(A4:E10,"Yield",A1:A3)'); + +$retVal = $worksheet->getCell('A12')->getCalculatedValue(); + +// $retVal = 5 +``` + +##### Notes + +In MS Excel, The field argument is optional. If field is omitted, DCOUNTA counts all records in the database that match the criteria. This logic has not yet been implemented in PHPExcel. + +#### DGET + +The DGET function extracts a single value from a column of a list or database that matches conditions that you specify. + +##### Syntax + +``` +DGET(database, field, criteria) +``` + +##### Parameters + +**database** The range of cells that makes up the list or database. + +A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column. + +**field** Indicates which column of the database is used in the function. + +Enter the column label as a string (enclosed between double quotation marks), such as "Age" or "Yield," or as a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on. + +**criteria** The range of cells that contains the conditions you specify. + +You can use any range for the criteria argument, as long as it includes at least one column label and at least one cell below the column label in which you specify a condition for the column. + +##### Return Value + +**mixed** The value from the selected column of the matching row. + +#### Examples + +```php +$database = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ), + array( 'Apple', 18, 20, 14, 105.00 ), + array( 'Pear', 12, 12, 10, 96.00 ), + array( 'Cherry', 13, 14, 9, 105.00 ), + array( 'Apple', 14, 15, 10, 75.00 ), + array( 'Pear', 9, 8, 8, 76.80 ), + array( 'Apple', 8, 9, 6, 45.00 ), +); + +$criteria = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ), + array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ), + array( '="=Pear"', NULL, NULL, NULL, NULL, NULL ), +); + +$worksheet->fromArray( $criteria, NULL, 'A1' ) + ->fromArray( $database, NULL, 'A4' ); + +$worksheet->setCellValue('A12', '=GET(A4:E10,"Age",A1:F2)'); + +$retVal = $worksheet->getCell('A12')->getCalculatedValue(); +// $retVal = 14 +``` + +##### Notes + +There are no additional notes on this function + +#### DMAX + +The DMAX function returns the largest number in a column of a list or database that matches conditions you specify. + +##### Syntax + +``` +DMAX(database, field, criteria) +``` + +##### Parameters + +**database** The range of cells that makes up the list or database. + +A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column. + +**field** Indicates which column of the database is used in the function. + +Enter the column label as a string (enclosed between double quotation marks), such as "Age" or "Yield," or as a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on. + +**criteria** The range of cells that contains the conditions you specify. + +You can use any range for the criteria argument, as long as it includes at least one column label and at least one cell below the column label in which you specify a condition for the column. + +##### Return Value + +**float** The maximum value of the matching cells. + +##### Examples + +```php +$database = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ), + array( 'Apple', 18, 20, 14, 105.00 ), + array( 'Pear', 12, 12, 10, 96.00 ), + array( 'Cherry', 13, 14, 9, 105.00 ), + array( 'Apple', 14, 15, 10, 75.00 ), + array( 'Pear', 9, 8, 8, 76.80 ), + array( 'Apple', 8, 9, 6, 45.00 ), +); + +$criteria = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ), + array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ), + array( '="=Pear"', NULL, NULL, NULL, NULL, NULL ), +); + +$worksheet->fromArray( $criteria, NULL, 'A1' ) + ->fromArray( $database, NULL, 'A4' ); + +$worksheet->setCellValue('A12', '=DMAX(A4:E10,"Profit",A1:B2)'); + +$retVal = $worksheet->getCell('A12')->getCalculatedValue(); +// $retVal = 105 +``` + +##### Notes + +There are no additional notes on this function + +#### DMIN + +The DMIN function returns the smallest number in a column of a list or database that matches conditions you specify. + +##### Syntax + +``` +DMIN(database, field, criteria) +``` + +##### Parameters + +**database** The range of cells that makes up the list or database. + +A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column. + +**field** Indicates which column of the database is used in the function. + +Enter the column label as a string (enclosed between double quotation marks), such as "Age" or "Yield," or as a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on. + +**criteria** The range of cells that contains the conditions you specify. + +You can use any range for the criteria argument, as long as it includes at least one column label and at least one cell below the column label in which you specify a condition for the column. + +##### Return Value + +**float** The minimum value of the matching cells. + +##### Examples + +```php +$database = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ), + array( 'Apple', 18, 20, 14, 105.00 ), + array( 'Pear', 12, 12, 10, 96.00 ), + array( 'Cherry', 13, 14, 9, 105.00 ), + array( 'Apple', 14, 15, 10, 75.00 ), + array( 'Pear', 9, 8, 8, 76.80 ), + array( 'Apple', 8, 9, 6, 45.00 ), +); + +$criteria = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ), + array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ), + array( '="=Pear"', NULL, NULL, NULL, NULL, NULL ), +); + +$worksheet->fromArray( $criteria, NULL, 'A1' ) + ->fromArray( $database, NULL, 'A4' ); + +$worksheet->setCellValue('A12', '=DMIN(A4:E10,"Yield",A1:A3)'); + +$retVal = $worksheet->getCell('A12')->getCalculatedValue(); +// $retVal = 6 +``` + +##### Notes + +There are no additional notes on this function + +#### DPRODUCT + +The DPRODUCT function multiplies the values in a column of a list or database that match conditions that you specify. + +##### Syntax + +``` +DPRODUCT(database, field, criteria) +``` + +##### Parameters + +**database** The range of cells that makes up the list or database. + +A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column. + +**field** Indicates which column of the database is used in the function. + +Enter the column label as a string (enclosed between double quotation marks), such as "Age" or "Yield," or as a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on. + +**criteria** The range of cells that contains the conditions you specify. + +You can use any range for the criteria argument, as long as it includes at least one column label and at least one cell below the column label in which you specify a condition for the column. + +##### Return Value + +**float** The product of the matching cells. + +##### Examples + +```php +$database = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ), + array( 'Apple', 18, 20, 14, 105.00 ), + array( 'Pear', 12, 12, 10, 96.00 ), + array( 'Cherry', 13, 14, 9, 105.00 ), + array( 'Apple', 14, 15, 10, 75.00 ), + array( 'Pear', 9, 8, 8, 76.80 ), + array( 'Apple', 8, 9, 6, 45.00 ), +); + +$criteria = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ), + array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ), + array( '="=Pear"', NULL, NULL, NULL, NULL, NULL ), +); + +$worksheet->fromArray( $criteria, NULL, 'A1' ) + ->fromArray( $database, NULL, 'A4' ); + +$worksheet->setCellValue('A12', '=DPRODUCT(A4:E10,"Yield",A1:B2)'); + +$retVal = $worksheet->getCell('A12')->getCalculatedValue(); +// $retVal = 140 +``` + +##### Notes + +There are no additional notes on this function + +#### DSTDEV + +The DSTDEV function estimates the standard deviation of a population based on a sample by using the numbers in a column of a list or database that match conditions that you specify. + +##### Syntax + +``` +DSTDEV(database, field, criteria) +``` + +##### Parameters + +**database** The range of cells that makes up the list or database. + +A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column. + +**field** Indicates which column of the database is used in the function. + +Enter the column label as a string (enclosed between double quotation marks), such as "Age" or "Yield," or as a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on. + +**criteria** The range of cells that contains the conditions you specify. + +You can use any range for the criteria argument, as long as it includes at least one column label and at least one cell below the column label in which you specify a condition for the column. + +##### Return Value + +**float** The estimated standard deviation of the matching cells. + +##### Examples + +```php +$database = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ), + array( 'Apple', 18, 20, 14, 105.00 ), + array( 'Pear', 12, 12, 10, 96.00 ), + array( 'Cherry', 13, 14, 9, 105.00 ), + array( 'Apple', 14, 15, 10, 75.00 ), + array( 'Pear', 9, 8, 8, 76.80 ), + array( 'Apple', 8, 9, 6, 45.00 ), +); + +$criteria = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ), + array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ), + array( '="=Pear"', NULL, NULL, NULL, NULL, NULL ), +); + +$worksheet->fromArray( $criteria, NULL, 'A1' ) + ->fromArray( $database, NULL, 'A4' ); + +$worksheet->setCellValue('A12', '=DSTDEV(A4:E10,"Yield",A1:A3)'); + +$retVal = $worksheet->getCell('A12')->getCalculatedValue(); +// $retVal = 2.97 +``` + +##### Notes + +There are no additional notes on this function + +#### DSTDEVP + +The DSTDEVP function calculates the standard deviation of a population based on the entire population by using the numbers in a column of a list or database that match conditions that you specify. + +##### Syntax + +``` +DSTDEVP(database, field, criteria) +``` + +##### Parameters + +**database** The range of cells that makes up the list or database. + +A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column. + +**field** Indicates which column of the database is used in the function. + +Enter the column label as a string (enclosed between double quotation marks), such as "Age" or "Yield," or as a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on. + +**criteria** The range of cells that contains the conditions you specify. + +You can use any range for the criteria argument, as long as it includes at least one column label and at least one cell below the column label in which you specify a condition for the column. + +##### Return Value + +**float** The estimated standard deviation of the matching cells. + +##### Examples + +```php +$database = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ), + array( 'Apple', 18, 20, 14, 105.00 ), + array( 'Pear', 12, 12, 10, 96.00 ), + array( 'Cherry', 13, 14, 9, 105.00 ), + array( 'Apple', 14, 15, 10, 75.00 ), + array( 'Pear', 9, 8, 8, 76.80 ), + array( 'Apple', 8, 9, 6, 45.00 ), +); + +$criteria = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ), + array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ), + array( '="=Pear"', NULL, NULL, NULL, NULL, NULL ), +); + +$worksheet->fromArray( $criteria, NULL, 'A1' ) + ->fromArray( $database, NULL, 'A4' ); + +$worksheet->setCellValue('A12', '=DSTDEVP(A4:E10,"Yield",A1:A3)'); + +$retVal = $worksheet->getCell('A12')->getCalculatedValue(); +// $retVal = 2.65 +``` + +##### Notes + +There are no additional notes on this function + +#### DSUM + +The DSUM function adds the numbers in a column of a list or database that matches conditions you specify. + +##### Syntax + +``` +DSUM(database, field, criteria) +``` + +##### Parameters + +**database** The range of cells that makes up the list or database. + +A database is a list of related data in which rows of related information are records, and columns of data are fields. The first row of the list contains labels for each column. + +**field** Indicates which column of the database is used in the function. + +Enter the column label as a string (enclosed between double quotation marks), such as "Age" or "Yield," or as a number (without quotation marks) that represents the position of the column within the list: 1 for the first column, 2 for the second column, and so on. + +**criteria** The range of cells that contains the conditions you specify. + +You can use any range for the criteria argument, as long as it includes at least one column label and at least one cell below the column label in which you specify a condition for the column. + +##### Return Value + +**float** The total value of the matching cells. + +##### Examples + +```php +$database = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit' ), + array( 'Apple', 18, 20, 14, 105.00 ), + array( 'Pear', 12, 12, 10, 96.00 ), + array( 'Cherry', 13, 14, 9, 105.00 ), + array( 'Apple', 14, 15, 10, 75.00 ), + array( 'Pear', 9, 8, 8, 76.80 ), + array( 'Apple', 8, 9, 6, 45.00 ), +); + +$criteria = array( + array( 'Tree', 'Height', 'Age', 'Yield', 'Profit', 'Height' ), + array( '="=Apple"', '>10', NULL, NULL, NULL, '<16' ), + array( '="=Pear"', NULL, NULL, NULL, NULL, NULL ), +); + +$worksheet->fromArray( $criteria, NULL, 'A1' ) + ->fromArray( $database, NULL, 'A4' ); + +$worksheet->setCellValue('A12', '=DMIN(A4:E10,"Profit",A1:A2)'); + +$retVal = $worksheet->getCell('A12')->getCalculatedValue(); +// $retVal = 225 +``` + +##### Notes + +There are no additional notes on this function + +#### DVAR + +Not yet documented. + +#### DVARP + +Not yet documented. + diff --git a/Documentation/markdown/CalculationEngine/FunctionReference/03-03-Date-and-Time-Functions.md b/Documentation/markdown/CalculationEngine/FunctionReference/03-03-Date-and-Time-Functions.md new file mode 100644 index 000000000..d0cc56817 --- /dev/null +++ b/Documentation/markdown/CalculationEngine/FunctionReference/03-03-Date-and-Time-Functions.md @@ -0,0 +1,1000 @@ +# Calculation Engine - Formula Function Reference + +## Function Reference + +### Date and Time Functions + +Excel provides a number of functions for the manipulation of dates and times, and calculations based on date/time values. it is worth spending some time reading the section titled "Date and Time Values" on passing date parameters and returning date values to understand how PHPExcel reconciles the differences between dates and times in Excel and in PHP. + +#### DATE + +The DATE function returns an Excel timestamp or a PHP timestamp or date object representing the date that is referenced by the parameters. + +##### Syntax + +``` +DATE(year, month, day) +``` + +##### Parameters + +**year** The year number. + +If this value is between 0 (zero) and 1899 inclusive (for the Windows 1900 calendar), or between 4 and 1903 inclusive (for the Mac 1904), then PHPExcel adds it to the Calendar base year, so a value of 108 will interpret the year as 2008 when using the Windows 1900 calendar, or 2012 when using the Mac 1904 calendar. + +**month** The month number. + +If this value is greater than 12, the DATE function adds that number of months to the first month in the year specified. For example, DATE(2008,14,2) returns a value representing February 2, 2009. + +If the value of __month__ is less than 1, then that value will be adjusted by -1, and that will then be subtracted from the first month of the year specified. For example, DATE(2008,0,2) returns a value representing December 2, 2007; while DATE(2008,-1,2) returns a value representing November 2, 2007. + +**day** The day number. + +If this value is greater than the number of days in the month (and year) specified, the DATE function adds that number of days to the first day in the month. For example, DATE(2008,1,35) returns a value representing February 4, 2008. + +If the value of __day__ is less than 1, then that value will be adjusted by -1, and that will then be subtracted from the first month of the year specified. For example, DATE(2008,3,0) returns a value representing February 29, 2008; while DATE(2008,3,-2) returns a value representing February 27, 2008. + +##### Return Value + +**mixed** A date/time stamp that corresponds to the given date. + +This could be a PHP timestamp value (integer), a PHP date/time object, or an Excel timestamp value (real), depending on the value of PHPExcel_Calculation_Functions::getReturnDateType(). + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Year') + ->setCellValue('A2', 'Month') + ->setCellValue('A3', 'Day'); + +$worksheet->setCellValue('B1', 2008) + ->setCellValue('B2', 12) + ->setCellValue('B3', 31); + +$worksheet->setCellValue('D1', '=DATE(B1,B2,B3)'); + +$retVal = $worksheet->getCell('D1')->getCalculatedValue(); +// $retVal = 1230681600 +``` + +```php +// We're going to be calling the same cell calculation multiple times, +// and expecting different return values, so disable calculation cacheing +PHPExcel_Calculation::getInstance()->setCalculationCacheEnabled(FALSE); + +$saveFormat = PHPExcel_Calculation_Functions::getReturnDateType(); + +PHPExcel_Calculation_Functions::setReturnDateType( + PHPExcel_Calculation_Functions::RETURNDATE_EXCEL +); + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DATE'), + array(2008, 12, 31) +); +// $retVal = 39813.0 + +PHPExcel_Calculation_Functions::setReturnDateType( + PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC +); + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DATE'), + array(2008, 12, 31) +); +// $retVal = 1230681600 + +PHPExcel_Calculation_Functions::setReturnDateType($saveFormat); +``` + +##### Notes + +There are no additional notes on this function + +#### DATEDIF + +The DATEDIF function computes the difference between two dates in a variety of different intervals, such number of years, months, or days. + +##### Syntax + +``` +DATEDIF(date1, date2 [, unit]) +``` + +##### Parameters + +**date1** First Date. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +**date2** Second Date. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +**unit** The interval type to use for the calculation + +This is a string, comprising one of the values listed below: + +Unit | Meaning | Description +-----|---------------------------------|-------------------------------- +m | Months | Complete calendar months between the dates. +d | Days | Number of days between the dates. +y | Years | Complete calendar years between the dates. +ym | Months Excluding Years | Complete calendar months between the dates as if they were of the same year. +yd | Days Excluding Years | Complete calendar days between the dates as if they were of the same year. +md | Days Excluding Years And Months | Complete calendar days between the dates as if they were of the same month and same year. + +The unit value is not case sensitive, and defaults to "d". + +##### Return Value + +**integer** An integer value that reflects the difference between the two dates. + +This could be the number of full days, months or years between the two dates, depending on the interval unit value passed into the function as the third parameter. + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Year') + ->setCellValue('A2', 'Month') + ->setCellValue('A3', 'Day'); + +$worksheet->setCellValue('B1', 2001) + ->setCellValue('C1', 2009) + ->setCellValue('B2', 7) + ->setCellValue('C2', 12) + ->setCellValue('B3', 1) + ->setCellValue('C3', 31); + +$worksheet->setCellValue('D1', '=DATEDIF(DATE(B1,B2,B3),DATE(C1,C2,C3),"d")') + ->setCellValue('D2', '=DATEDIF(DATE(B1,B2,B3),DATE(C1,C2,C3),"m")') + ->setCellValue('D3', '=DATEDIF(DATE(B1,B2,B3),DATE(C1,C2,C3),"y")') + ->setCellValue('D4', '=DATEDIF(DATE(B1,B2,B3),DATE(C1,C2,C3),"ym")') + ->setCellValue('D5', '=DATEDIF(DATE(B1,B2,B3),DATE(C1,C2,C3),"yd")') + ->setCellValue('D6', '=DATEDIF(DATE(B1,B2,B3),DATE(C1,C2,C3),"md")'); + +$retVal = $worksheet->getCell('D1')->getCalculatedValue(); +// $retVal = 3105 + +$retVal = $worksheet->getCell('D2')->getCalculatedValue(); +// $retVal = 101 + +$retVal = $worksheet->getCell('D3')->getCalculatedValue(); +// $retVal = 8 + +$retVal = $worksheet->getCell('D4')->getCalculatedValue(); +// $retVal = 5 + +$retVal = $worksheet->getCell('D5')->getCalculatedValue(); +// $retVal = 183 + +$retVal = $worksheet->getCell('D6')->getCalculatedValue(); +// $retVal = 30 +``` + +```php +$date1 = 1193317015; // PHP timestamp for 25-Oct-2007 +$date2 = 1449579415; // PHP timestamp for 8-Dec-2015 + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DATEDIF'), + array($date1, $date2, 'd') +); +// $retVal = 2966 + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DATEDIF'), + array($date1, $date2, 'm') +); +// $retVal = 97 + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DATEDIF'), + array($date1, $date2, 'y') +); +// $retVal = 8 + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DATEDIF'), + array($date1, $date2, 'ym') +); +// $retVal = 1 + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DATEDIF'), + array($date1, $date2, 'yd') +); +// $retVal = 44 + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DATEDIF'), + array($date1, $date2, 'md') +); +// $retVal = 13 +``` + +##### Notes + +If Date1 is later than Date2, DATEDIF will return a #NUM! error. + +#### DATEVALUE + +The DATEVALUE function returns the date represented by a date formatted as a text string. Use DATEVALUE to convert a date represented by text to a serial number. + +##### Syntax + +``` +DATEVALUE(dateString) +``` + +##### Parameters + +**date** Date String. + +A string, representing a date value. + +##### Return Value + +**mixed** A date/time stamp that corresponds to the given date. + +This could be a PHP timestamp value (integer), a PHP date/time object, or an Excel timestamp value (real), depending on the value of PHPExcel_Calculation_Functions::getReturnDateType(). + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Date String'); + ->setCellValue('A2', '31-Dec-2008') + ->setCellValue('A3', '31/12/2008') + ->setCellValue('A4', '12-31-2008'); + +$worksheet->setCellValue('B2', '=DATEVALUE(A2)') + ->setCellValue('B3', '=DATEVALUE(A3)') + ->setCellValue('B4', '=DATEVALUE(A4)'); + +PHPExcel_Calculation_Functions::setReturnDateType( + PHPExcel_Calculation_Functions::RETURNDATE_EXCEL +); + +$retVal = $worksheet->getCell('B2')->getCalculatedValue(); + +$retVal = $worksheet->getCell('B3')->getCalculatedValue(); + +$retVal = $worksheet->getCell('B4')->getCalculatedValue(); +// $retVal = 39813.0 for all cases +``` + +```php +// We're going to be calling the same cell calculation multiple times, +// and expecting different return values, so disable calculation cacheing +PHPExcel_Calculation::getInstance()->setCalculationCacheEnabled(FALSE); + +$saveFormat = PHPExcel_Calculation_Functions::getReturnDateType(); + +PHPExcel_Calculation_Functions::setReturnDateType( + PHPExcel_Calculation_Functions::RETURNDATE_EXCEL +); + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DATEVALUE'), + array('31-Dec-2008') +); +// $retVal = 39813.0 + +PHPExcel_Calculation_Functions::setReturnDateType( + PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC +); + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DATEVALUE'), + array('31-Dec-2008') +); +// $retVal = 1230681600 + +PHPExcel_Calculation_Functions::setReturnDateType($saveFormat); +``` + +##### Notes + +DATEVALUE uses the php date/time object implementation of strtotime() (which can handle a wider range of formats than the normal strtotime() function), and it is also called for any date parameter passed to other date functions (such as DATEDIF) when the parameter value is a string. + +__WARNING:-__ PHPExcel accepts a wider range of date formats than MS Excel, so it is entirely possible that Excel will return a #VALUE! error when passed a date string that it can’t interpret, while PHPExcel is able to translate that same string into a correct date value. + +Care should be taken in workbooks that use string formatted dates in calculations when writing to Excel5 or Excel2007. + +#### DAY + +The DAY function returns the day of a date. The day is given as an integer ranging from 1 to 31. + +##### Syntax + +``` +DAY(datetime) +``` + +##### Parameters + +**datetime** Date. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +##### Return Value + +**integer** An integer value that reflects the day of the month. + +This is an integer ranging from 1 to 31. + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Date String') + ->setCellValue('A2', '31-Dec-2008') + ->setCellValue('A3', '14-Feb-2008'); + +$worksheet->setCellValue('B2', '=DAY(A2)') + ->setCellValue('B3', '=DAY(A3)'); + +$retVal = $worksheet->getCell('B2')->getCalculatedValue(); +// $retVal = 31 + +$retVal = $worksheet->getCell('B3')->getCalculatedValue(); +// $retVal = 14 +``` + +```php +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DAYOFMONTH'), + array('25-Dec-2008') +); +// $retVal = 25 +``` + +##### Notes + +Note that the PHPExcel function is PHPExcel_Calculation_Functions::DAYOFMONTH() when the method is called statically. + +#### DAYS360 + +The DAYS360 function computes the difference between two dates based on a 360 day year (12 equal periods of 30 days each) used by some accounting systems. + +##### Syntax + +``` +DAYS360(date1, date2 [, method]) +``` + +#### Parameters + +**date1** First Date. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +**date2** Second Date. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +**method** A boolean flag (TRUE or FALSE) + +This is a flag that determines which method to use in the calculation, based on the values listed below: + + method | Description + -------|------------ + FALSE | U.S. (NASD) method. If the starting date is the last day of a month, it becomes equal to the 30th of the same month. If the ending date is the last day of a month and the starting date is earlier than the 30th of a month, the ending date becomes equal to the 1st of the next month; otherwise the ending date becomes equal to the 30th of the same month. + TRUE | European method. Starting dates and ending dates that occur on the 31st of a month become equal to the 30th of the same month. + +The method value defaults to FALSE. + +##### Return Value + +**integer** An integer value that reflects the difference between the two dates. + +This is the number of full days between the two dates, based on a 360 day year. + +##### Examples + +```php +$worksheet->setCellValue('B1', 'Start Date') + ->setCellValue('C1', 'End Date') + ->setCellValue('A2', 'Year') + ->setCellValue('A3', 'Month') + ->setCellValue('A4', 'Day'); + +$worksheet->setCellValue('B2', 2003) + ->setCellValue('B3', 2) + ->setCellValue('B4', 3); + +$worksheet->setCellValue('C2', 2007) + ->setCellValue('C3', 5) + ->setCellValue('C4', 31); + +$worksheet->setCellValue('E2', '=DAYS360(DATE(B2,B3,B4),DATE(C2,C3,C4))') + ->setCellValue('E4', '=DAYS360(DATE(B2,B3,B4),DATE(C2,C3,C4),FALSE)'); + +$retVal = $worksheet->getCell('E2')->getCalculatedValue(); +// $retVal = 1558 + +$retVal = $worksheet->getCell('E4')->getCalculatedValue(); +// $retVal = 1557 +``` + +```php +$date1 = 37655.0; // Excel timestamp for 25-Oct-2007 +$date2 = 39233.0; // Excel timestamp for 8-Dec-2015 + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DAYS360'), + array($date1, $date2) +); +// $retVal = 1558 + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DAYS360'), + array($date1, $date2, TRUE) +); +// $retVal = 1557 +``` + +##### Notes + +__WARNING:-__ This function does not currently work with the Excel5 Writer when a PHP Boolean is used for the third (optional) parameter (as shown in the example above), and the writer will generate and error. It will work if a numeric 0 or 1 is used for the method parameter; or if the Excel TRUE() and FALSE() functions are used instead. + +#### EDATE + +The EDATE function returns an Excel timestamp or a PHP timestamp or date object representing the date that is the indicated number of months before or after a specified date (the start_date). Use EDATE to calculate maturity dates or due dates that fall on the same day of the month as the date of issue. + +##### Syntax + +``` +EDATE(baseDate, months) +``` + +##### Parameters + +**baseDate** Start Date. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +**months** Number of months to add. + +An integer value indicating the number of months before or after baseDate. A positive value for months yields a future date; a negative value yields a past date. + +##### Return Value + +**mixed** A date/time stamp that corresponds to the basedate + months. + +This could be a PHP timestamp value (integer), a PHP date/time object, or an Excel timestamp value (real), depending on the value of PHPExcel_Calculation_Functions::getReturnDateType(). + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Date String') + ->setCellValue('A2', '1-Jan-2008') + ->setCellValue('A3', '29-Feb-2008'); + +$worksheet->setCellValue('B2', '=EDATE(A2,5)') + ->setCellValue('B3', '=EDATE(A3,-12)'); + +PHPExcel_Calculation_Functions::setReturnDateType( + PHPExcel_Calculation_Functions::RETURNDATE_EXCEL +); + +$retVal = $worksheet->getCell('B2')->getCalculatedValue(); +// $retVal = 39600.0 (1-Jun-2008) + +$retVal = $worksheet->getCell('B3')->getCalculatedValue(); +// $retVal = 39141.0 (28-Feb-2007) +``` + +```php +PHPExcel_Calculation_Functions::setReturnDateType( + PHPExcel_Calculation_Functions::RETURNDATE_EXCEL +); + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'EDATE'), + array('31-Oct-2008',25) +); +// $retVal = 40512.0 (30-Nov-2010) +``` + +###### Notes + +__WARNING:-__ This function is currently not supported by the Excel5 Writer because it is not a standard function within Excel 5, but an add-in from the Analysis ToolPak. + +#### EOMONTH + +The EOMONTH function returns an Excel timestamp or a PHP timestamp or date object representing the date of the last day of the month that is the indicated number of months before or after a specified date (the start_date). Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month. + +##### Syntax + +``` +EOMONTH(baseDate, months) +``` + +##### Parameters + +**baseDate** Start Date. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +**months** Number of months to add. + +An integer value indicating the number of months before or after baseDate. A positive value for months yields a future date; a negative value yields a past date. + +##### Return Value + +**mixed** A date/time stamp that corresponds to the last day of basedate + months. + +This could be a PHP timestamp value (integer), a PHP date/time object, or an Excel timestamp value (real), depending on the value of PHPExcel_Calculation_Functions::getReturnDateType(). + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Date String') + ->setCellValue('A2', '1-Jan-2000') + ->setCellValue('A3', '14-Feb-2009'); + +$worksheet->setCellValue('B2', '=EOMONTH(A2,5)') + ->setCellValue('B3', '=EOMONTH(A3,-12)'); + +PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + +$retVal = $worksheet->getCell('B2')->getCalculatedValue(); +// $retVal = 39629.0 (30-Jun-2008) + +$retVal = $worksheet->getCell('B3')->getCalculatedValue(); +// $retVal = 39507.0 (29-Feb-2008) +``` + +```php +PHPExcel_Calculation_Functions::setReturnDateType( + PHPExcel_Calculation_Functions::RETURNDATE_EXCEL +); + +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'EOMONTH'), + array('31-Oct-2008',13) +); +// $retVal = 40147.0 (30-Nov-2010) +``` + +##### Notes + +__WARNING:-__ This function is currently not supported by the Excel5 Writer because it is not a standard function within Excel 5, but an add-in from the Analysis ToolPak. + +#### HOUR + +The HOUR function returns the hour of a time value. The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.). + +##### Syntax + +``` +HOUR(datetime) +``` + +##### Parameters + +**datetime** Time. + +An Excel date/time value, PHP date timestamp, PHP date object, or a date/time represented as a string. + +##### Return Value + +**integer** An integer value that reflects the hour of the day. + +This is an integer ranging from 0 to 23. + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Time String') + ->setCellValue('A2', '31-Dec-2008 17:30') + ->setCellValue('A3', '14-Feb-2008 4:20 AM') + ->setCellValue('A4', '14-Feb-2008 4:20 PM'); + +$worksheet->setCellValue('B2', '=HOUR(A2)') + ->setCellValue('B3', '=HOUR(A3)') + ->setCellValue('B4', '=HOUR(A4)'); + +$retVal = $worksheet->getCell('B2')->getCalculatedValue(); +// $retVal = 17 + +$retVal = $worksheet->getCell('B3')->getCalculatedValue(); +// $retVal = 4 + +$retVal = $worksheet->getCell('B4')->getCalculatedValue(); +// $retVal = 16 +``` + +```php +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'HOUROFDAY'), + array('09:30') +); +// $retVal = 9 +``` + +##### Notes + +Note that the PHPExcel function is PHPExcel_Calculation_Functions::HOUROFDAY() when the method is called statically. + +#### MINUTE + +The MINUTE function returns the minutes of a time value. The minute is given as an integer, ranging from 0 to 59. + +##### Syntax + +``` +MINUTE(datetime) +``` + +##### Parameters + +**datetime** Time. + +An Excel date/time value, PHP date timestamp, PHP date object, or a date/time represented as a string. + +##### Return Value + +**integer** An integer value that reflects the minutes within the hour. + +This is an integer ranging from 0 to 59. + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Time String') + ->setCellValue('A2', '31-Dec-2008 17:30') + ->setCellValue('A3', '14-Feb-2008 4:20 AM') + ->setCellValue('A4', '14-Feb-2008 4:45 PM'); + +$worksheet->setCellValue('B2', '=MINUTE(A2)') + ->setCellValue('B3', '=MINUTE(A3)') + ->setCellValue('B4', '=MINUTE(A4)'); + +$retVal = $worksheet->getCell('B2')->getCalculatedValue(); +// $retVal = 30 + +$retVal = $worksheet->getCell('B3')->getCalculatedValue(); +// $retVal = 20 + +$retVal = $worksheet->getCell('B4')->getCalculatedValue(); +// $retVal = 45 +``` + +```php +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'MINUTEOFHOUR'), + array('09:30') +); +// $retVal = 30 +``` + +##### Notes + +Note that the PHPExcel function is PHPExcel_Calculation_Functions::MINUTEOFHOUR() when the method is called statically. + +#### MONTH + +The MONTH function returns the month of a date. The month is given as an integer ranging from 1 to 12. + +##### Syntax + +``` +MONTH(datetime) +``` + +##### Parameters + +**datetime** Date. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +##### Return Value + +**integer** An integer value that reflects the month of the year. + +This is an integer ranging from 1 to 12. + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Date String'); +$worksheet->setCellValue('A2', '31-Dec-2008'); +$worksheet->setCellValue('A3', '14-Feb-2008'); + +$worksheet->setCellValue('B2', '=MONTH(A2)'); +$worksheet->setCellValue('B3', '=MONTH(A3)'); + +$retVal = $worksheet->getCell('B2')->getCalculatedValue(); +// $retVal = 12 + +$retVal = $worksheet->getCell('B3')->getCalculatedValue(); +// $retVal = 2 +``` + +```php +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'MONTHOFYEAR'), + array('14-July-2008') +); +// $retVal = 7 +``` + +#### Notes + +Note that the PHPExcel function is PHPExcel_Calculation_Functions::MONTHOFYEAR() when the method is called statically. + +#### NETWORKDAYS + +The NETWORKDAYS function returns the number of whole working days between a *start date* and an *end date*. Working days exclude weekends and any dates identified in *holidays*. Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days worked during a specific term. + +##### Syntax + +``` +NETWORKDAYS(startDate, endDate [, holidays]) +``` + +##### Parameters + +**startDate** Start Date of the period. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +**endDate** End Date of the period. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +**holidays** Optional array of Holiday dates. + +An optional range of one or more dates to exclude from the working calendar, such as state and federal holidays and floating holidays. + +The list can be either a range of cells that contains the dates or an array constant of Excel date values, PHP date timestamps, PHP date objects, or dates represented as strings. + +##### Return Value + +**integer** Number of working days. + +The number of working days between startDate and endDate. + +##### Examples + +```php +``` + +```php +``` + +##### Notes + +There are no additional notes on this function + +#### NOW + +The NOW function returns the current date and time. + +##### Syntax + +``` +NOW() +``` + +##### Parameters + +There are now parameters for the NOW() function. + +##### Return Value + +**mixed** A date/time stamp that corresponds to the current date and time. + +This could be a PHP timestamp value (integer), a PHP date/time object, or an Excel timestamp value (real), depending on the value of PHPExcel_Calculation_Functions::getReturnDateType(). + +##### Examples + +```php +``` + +```php +``` + +##### Notes + +Note that the PHPExcel function is PHPExcel_Calculation_Functions::DATETIMENOW() when the method is called statically. + +#### SECOND + +The SECOND function returns the seconds of a time value. The second is given as an integer, ranging from 0 to 59. + +##### Syntax + +``` +SECOND(datetime) +``` + +##### Parameters + +**datetime** Time. + +An Excel date/time value, PHP date timestamp, PHP date object, or a date/time represented as a string. + +##### Return Value + +**integer** An integer value that reflects the seconds within the minute. + +This is an integer ranging from 0 to 59. + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Time String') + ->setCellValue('A2', '31-Dec-2008 17:30:20') + ->setCellValue('A3', '14-Feb-2008 4:20 AM') + ->setCellValue('A4', '14-Feb-2008 4:45:59 PM'); + +$worksheet->setCellValue('B2', '=SECOND(A2)') + ->setCellValue('B3', '=SECOND(A3)'); + ->setCellValue('B4', '=SECOND(A4)'); + +$retVal = $worksheet->getCell('B2')->getCalculatedValue(); +// $retVal = 20 + +$retVal = $worksheet->getCell('B3')->getCalculatedValue(); +// $retVal = 0 + +$retVal = $worksheet->getCell('B4')->getCalculatedValue(); +// $retVal = 59 +``` + +```php +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'SECONDOFMINUTE'), + array('09:30:17') +); +// $retVal = 17 +``` + +##### Notes + +Note that the PHPExcel function is PHPExcel_Calculation_Functions::SECONDOFMINUTE() when the method is called statically. + +#### TIME + +Not yet documented. + +#### TIMEVALUE + +Not yet documented. + +#### TODAY + +Not yet documented. + +#### WEEKDAY + +The WEEKDAY function returns the day of the week for a given date. The day is given as an integer ranging from 1 to 7, although this can be modified to return a value between 0 and 6. + +##### Syntax + +``` +WEEKDAY(datetime [, method]) +``` + +##### Parameters + +**datetime** Date. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +**method** An integer flag (values 0, 1 or 2) + +This is a flag that determines which method to use in the calculation, based on the values listed below: + + method | Description + :-----:|------------------------------------------ + 0 | Returns 1 (Sunday) through 7 (Saturday). + 1 | Returns 1 (Monday) through 7 (Sunday). + 2 | Returns 0 (Monday) through 6 (Sunday). + +The method value defaults to 1. + +##### Return Value + +**integer** An integer value that reflects the day of the week. + +This is an integer ranging from 1 to 7, or 0 to 6, depending on the value of method. + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Date String') + ->setCellValue('A2', '31-Dec-2008') + ->setCellValue('A3', '14-Feb-2008'); + +$worksheet->setCellValue('B2', '=WEEKDAY(A2)') + ->setCellValue('B3', '=WEEKDAY(A3,0)') + ->setCellValue('B4', '=WEEKDAY(A3,2)'); + +$retVal = $worksheet->getCell('B2')->getCalculatedValue(); +// $retVal = 12 + +$retVal = $worksheet->getCell('B3')->getCalculatedValue(); +// $retVal = 2 + +$retVal = $worksheet->getCell('B4')->getCalculatedValue(); +// $retVal = 2 +``` + +```php +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'DAYOFWEEK'), + array('14-July-2008') +); +// $retVal = 7 +``` + +##### Notes + +Note that the PHPExcel function is PHPExcel_Calculation_Functions::DAYOFWEEK() when the method is called statically. + +#### WEEKNUM + +Not yet documented. + +#### WORKDAY + +Not yet documented. + +#### YEAR + +The YEAR function returns the year of a date. + +##### Syntax + +``` +YEAR(datetime) +``` + +##### Parameters + +**datetime** Date. + +An Excel date value, PHP date timestamp, PHP date object, or a date represented as a string. + +##### Return Value + +**integer** An integer value that reflects the month of the year. + +This is an integer year value. + +##### Examples + +```php +$worksheet->setCellValue('A1', 'Date String') + ->setCellValue('A2', '17-Jul-1982') + ->setCellValue('A3', '16-Apr-2009'); + +$worksheet->setCellValue('B2', '=YEAR(A2)') + ->setCellValue('B3', '=YEAR(A3)'); + +$retVal = $worksheet->getCell('B2')->getCalculatedValue(); +// $retVal = 1982 + +$retVal = $worksheet->getCell('B3')->getCalculatedValue(); +// $retVal = 2009 +``` + +```php +$retVal = call_user_func_array( + array('PHPExcel_Calculation_Functions', 'YEAR'), + array('14-July-2001') +); +// $retVal = 2001 +``` + +##### Notes + +There are no additional notes on this function + +### YEARFRAC + +Not yet documented. + From 8a25f345b8fe1fba48e2e41f35593b8848c6bc8c Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 16 May 2013 21:59:54 +0100 Subject: [PATCH 072/467] documentation markdown --- .../markdown/Overview/01-getting-started.md | 16 +- .../markdown/Overview/02-architecture.md | 7 +- .../Overview/03-Creating-a-Spreadsheet.md | 33 +++ .../Overview/04-Configuration-Settings.md | 139 +++++++++++ Documentation/markdown/Overview/developer.md | 235 ------------------ 5 files changed, 185 insertions(+), 245 deletions(-) create mode 100644 Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md create mode 100644 Documentation/markdown/Overview/04-Configuration-Settings.md diff --git a/Documentation/markdown/Overview/01-getting-started.md b/Documentation/markdown/Overview/01-getting-started.md index 7be472228..404640953 100644 --- a/Documentation/markdown/Overview/01-getting-started.md +++ b/Documentation/markdown/Overview/01-getting-started.md @@ -1,9 +1,9 @@ # PHPExcel Developer Documentation -## 1. Prerequisites, Installation, FAQ and Links +## Prerequisites, Installation, FAQ and Links -### 1.1 Software requirements +### Software requirements The following software is required to develop using PHPExcel: @@ -14,7 +14,7 @@ The following software is required to develop using PHPExcel: [^phpzip_footnote]: __php_zip__ is only needed by __PHPExcel_Reader_Excel2007__, __PHPExcel_Writer_Excel2007__ and __PHPExcel_Reader_OOCalc__. In other words, if you need PHPExcel to handle .xlsx or .ods files you will need the zip extension, but otherwise not. You can remove this dependency for writing Excel2007 files (though not yet for reading) by using the PCLZip library that is bundled with PHPExcel. See the FAQ section of this document for details about this. PCLZip does have a dependency on PHP's zlib extension being enabled. -### 1.2 Installation instructions +### Installation instructions Installation is quite easy: copy the contents of the Classes folder to any location within your application source directories. @@ -27,7 +27,7 @@ If your web root folder is /var/www/ you may want to create a subfolder called / /var/www/Classes/PHPExcel/Cell.php ... -### 1.3 Getting started +### Getting started A good way to get started is to run some of the tests included in the download. Copy the "Examples" folder next to your "Classes" folder from above so you end up with: @@ -44,11 +44,11 @@ http://example.com/Tests/02types.php Note: It may be necessary to modify the include/require statements at the beginning of each of the test scripts if your "Classes" folder from above is named differently. -### 1.4 Useful links and tools +### Useful links and tools There are some links and tools which are very useful when developing using PHPExcel. Please refer to the [PHPExcel CodePlex pages][2] for an update version of the list below. -#### 1.4.1 OpenXML / SpreadsheetML +#### OpenXML / SpreadsheetML - __File format documentation__ [http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm][3] @@ -59,7 +59,7 @@ There are some links and tools which are very useful when developing using PHPEx - __OpenXML Package Explorer__ [http://www.codeplex.com/PackageExplorer/][6] -#### 1.4.2 Frequently asked questions +#### Frequently asked questions The up-to-date F.A.Q. page for PHPExcel can be found on [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=FAQ&referringTitle=Requirements][7]. @@ -140,7 +140,7 @@ The short answer is that PHPExcel uses a measure where padding is included. See Thanks to peterrlynch for the following advice on resolving issues between the [PHPExcel autoloader and Joomla Autoloader][17] -#### 1.4.3 Tutorials +#### Tutorials - __English PHPExcel tutorial__ [http://openxmldeveloper.org][18] diff --git a/Documentation/markdown/Overview/02-architecture.md b/Documentation/markdown/Overview/02-architecture.md index 6ce1330c7..0baaef4e7 100644 --- a/Documentation/markdown/Overview/02-architecture.md +++ b/Documentation/markdown/Overview/02-architecture.md @@ -5,7 +5,7 @@ ### Schematical - +![01-schematic.png](./images/01-schematic.png "") ### Lazy Loader @@ -39,6 +39,9 @@ On its own, PHPExcel does not provide the functionality to read from or write to By default, the PHPExcel package provides some readers and writers, including one for the Open XML spreadsheet format (a.k.a. Excel 2007 file format). You are not limited to the default readers and writers, as you are free to implement the PHPExcel_Writer_IReader and PHPExcel_Writer_IWriter interface in a custom class. +![02-readers-writers.png](./images/02-readers-writers.png "") + + ### Fluent interfaces PHPExcel supports fluent interfaces in most locations. This means that you can easily "chain"" calls to specific methods without requiring a new PHP statement. For example, take the following code: @@ -63,5 +66,5 @@ $objPHPExcel->getProperties() ->setCategory("Test result file"); ``` -__Using fluent interfaces is not required__ +__Using fluent interfaces is not required__ Fluent interfaces have been implemented to provide a convenient programming API. Use of them is not required, but can make your code easier to read and maintain. It can also improve performance, as you are reducing the overall number of calls to PHPExcel methods. diff --git a/Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md b/Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md new file mode 100644 index 000000000..592d47580 --- /dev/null +++ b/Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md @@ -0,0 +1,33 @@ +# PHPExcel Developer Documentation + +## Creating a spreadsheet + +### The PHPExcel class + +The PHPExcel class is the core of PHPExcel. It contains references to the contained worksheets, document security settings and document meta data. + +To simplify the PHPExcel concept: the PHPExcel class represents your workbook. + +Typically, you will create a workbook in one of two ways, either by loading it from a spreadsheet file, or creating it manually. A third option, though less commonly used, is cloning an existing workbook that has been created using one of the previous two methods. + +#### Loading a Workbook from a file + +Details of the different spreadsheet formats supported, and the options available to read them into a PHPExcel object are described fully in the PHPExcel User Documentation - Reading Spreadsheet Files document. + +```php +$inputFileName = './sampleData/example1.xls'; + +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = PHPExcel_IOFactory::load($inputFileName); +``` + +#### Creating a new workbook + +If you want to create a new workbook, rather than load one from file, then you simply need to instantiate it as a new PHPExcel object. + +```php +/** Create a new PHPExcel Object **/ +$objPHPExcel = new PHPExcel(); +``` + +A new workbook will always be created with a single worksheet. diff --git a/Documentation/markdown/Overview/04-Configuration-Settings.md b/Documentation/markdown/Overview/04-Configuration-Settings.md new file mode 100644 index 000000000..c7752e527 --- /dev/null +++ b/Documentation/markdown/Overview/04-Configuration-Settings.md @@ -0,0 +1,139 @@ +# PHPExcel Developer Documentation + +## Configuration Settings + +Once you have included the PHPExcel files in your script, but before instantiating a PHPExcel object or loading a workbook file, there are a number of configuration options that can be set which will affect the subsequent behaviour of the script. + +### Cell Caching + +PHPExcel uses an average of about 1k/cell in your worksheets, so large workbooks can quickly use up available memory. Cell caching provides a mechanism that allows PHPExcel to maintain the cell objects in a smaller size of memory, on disk, or in APC, memcache or Wincache, rather than in PHP memory. This allows you to reduce the memory usage for large workbooks, although at a cost of speed to access cell data. + +By default, PHPExcel still holds all cell objects in memory, but you can specify alternatives. To enable cell caching, you must call the PHPExcel_Settings::setCacheStorageMethod() method, passing in the caching method that you wish to use. + +```php +$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory; + +PHPExcel_Settings::setCacheStorageMethod($cacheMethod); +``` + +setCacheStorageMethod() will return a boolean true on success, false on failure (for example if trying to cache to APC when APC is not enabled). + +A separate cache is maintained for each individual worksheet, and is automatically created when the worksheet is instantiated based on the caching method and settings that you have configured. You cannot change the configuration settings once you have started to read a workbook, or have created your first worksheet. + +Currently, the following caching methods are available. + +#### PHPExcel_CachedObjectStorageFactory::cache_in_memory + +The default. If you don't initialise any caching method, then this is the method that PHPExcel will use. Cell objects are maintained in PHP memory as at present. + +#### PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized + +Using this caching method, cells are held in PHP memory as an array of serialized objects, which reduces the memory footprint with minimal performance overhead. + +#### PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip + +Like cache_in_memory_serialized, this method holds cells in PHP memory as an array of serialized objects, but gzipped to reduce the memory usage still further, although access to read or write a cell is slightly slower. + +#### PHPExcel_CachedObjectStorageFactory::cache_igbinary + +Uses PHPs igbinary extension (if its available) to serialize cell objects in memory. This is normally faster and uses less memory than standard PHP serialization, but isnt available in most hosting environments. + +#### PHPExcel_CachedObjectStorageFactory::cache_to_discISAM + +When using cache_to_discISAM all cells are held in a temporary disk file, with only an index to their location in that file maintained in PHP memory. This is slower than any of the cache_in_memory methods, but significantly reduces the memory footprint. By default, PHPExcel will use PHP's temp directory for the cache file, but you can specify a different directory when initialising cache_to_discISAM. + +```php +$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_discISAM; +$cacheSettings = array( + 'dir' => '/usr/local/tmp' +); +PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); +``` + +The temporary disk file is automatically deleted when your script terminates. + +#### PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp + +Like cache_to_discISAM, when using cache_to_phpTemp all cells are held in the php://temp I/O stream, with only an index to their location maintained in PHP memory. In PHP, the php://memory wrapper stores data in the memory: php://temp behaves similarly, but uses a temporary file for storing the data when a certain memory limit is reached. The default is 1 MB, but you can change this when initialising cache_to_phpTemp. + +```php +$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp; +$cacheSettings = array( + 'memoryCacheSize' => '8MB' +); +PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); +``` + +The php://temp file is automatically deleted when your script terminates. + +#### PHPExcel_CachedObjectStorageFactory::cache_to_apc + +When using cache_to_apc, cell objects are maintained in APC with only an index maintained in PHP memory to identify that the cell exists. By default, an APC cache timeout of 600 seconds is used, which should be enough for most applications: although it is possible to change this when initialising cache_to_APC. + +```php +$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_APC; +$cacheSettings = array( + 'cacheTime' => 600 +); +PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); +``` + +When your script terminates all entries will be cleared from APC, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism. + +#### PHPExcel_CachedObjectStorageFactory::cache_to_memcache + +When using cache_to_memcache, cell objects are maintained in memcache with only an index maintained in PHP memory to identify that the cell exists. + +By default, PHPExcel looks for a memcache server on localhost at port 11211. It also sets a memcache timeout limit of 600 seconds. If you are running memcache on a different server or port, then you can change these defaults when you initialise cache_to_memcache: + +```php +$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_memcache; +$cacheSettings = array( + 'memcacheServer' => 'localhost', + 'memcachePort' => 11211, + 'cacheTime' => 600 +); +PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); +``` + +When your script terminates all entries will be cleared from memcache, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism. + +#### PHPExcel_CachedObjectStorageFactory::cache_to_wincache + +When using cache_to_wincache, cell objects are maintained in Wincache with only an index maintained in PHP memory to identify that the cell exists. By default, a Wincache cache timeout of 600 seconds is used, which should be enough for most applications: although it is possible to change this when initialising cache_to_wincache. + +```php +$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_wincache; +$cacheSettings = array( + 'cacheTime' => 600 +); +PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); +``` + +When your script terminates all entries will be cleared from Wincache, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism. + +#### PHPExcel_CachedObjectStorageFactory::cache_to_sqlite + +Uses an SQLite 2 "in-memory"" database for caching cell data. Unlike other caching methods, neither cells nor an index are held in PHP memory - an indexed database table makes it unnecessary to hold any index in PHP memory, which makes this the most memory-efficient of the cell caching methods. + +#### PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3; + +Uses an SQLite 3 "in-memory" database for caching cell data. Unlike other caching methods, neither cells nor an index are held in PHP memory - an indexed database table makes it unnecessary to hold any index in PHP memory, which makes this the most memory-efficient of the cell caching methods. + + +### Language/Locale + +Some localisation elements have been included in PHPExcel. You can set a locale by changing the settings. To set the locale to Brazilian Portuguese you would use: + +```php +$locale = 'pt_br'; +$validLocale = PHPExcel_Settings::setLocale($locale); +if (!$validLocale) { + echo 'Unable to set locale to '.$locale." - reverting to en_us
\n"; +} +``` + +If Brazilian Portuguese language files aren't available, then the Portuguese will be enabled instead: if Portuguese language files aren't available, then the setLocale() method will return an error, and American English (en_us) settings will be used throughout. + +More details of the features available once a locale has been set, including a list of the languages and locales currently supported, can be found in the section of this document entitled "Locale Settings for Formulae". + diff --git a/Documentation/markdown/Overview/developer.md b/Documentation/markdown/Overview/developer.md index 7030eaae0..5063d741b 100644 --- a/Documentation/markdown/Overview/developer.md +++ b/Documentation/markdown/Overview/developer.md @@ -1,240 +1,5 @@ # PHPExcel Developer Documentation - -## 1. Prerequisites - -### 1.1 Software requirements - -The following software is required to develop using PHPExcel: - - - PHP version 5.2.0 or newer - - PHP extension php_zip enabled [^phpzip_footnote] - - PHP extension php_xml enabled - - PHP extension php_gd2 enabled (if not compiled in) - -[^phpzip_footnote]: ____php_zip__ is only needed by __PHPExcel_Reader_Excel2007__, __PHPExcel_Writer_Excel2007__ and __PHPExcel_Reader_OOCalc__. In other words, if you need PHPExcel to handle .xlsx or .ods files you will need the zip extension, but otherwise not.You can remove this dependency for writing Excel2007 files (though not yet for reading) by using the PCLZip library that is bundled with PHPExcel. See the FAQ section of this document for details about this. PCLZip does have a dependency on PHP's zlib extension being enabled. - -### 1.2 Installation instructions - -Installation is quite easy: copy the contents of the Classes folder to any location within your application source directories. - -*Example:* - -If your web root folder is /var/www/ you may want to create a subfolder called /var/www/Classes/ and copy the files into that folder so you end up with files: - -/var/www/Classes/PHPExcel.php -/var/www/Classes/PHPExcel/Calculation.php -/var/www/Classes/PHPExcel/Cell.php -... - -### 1.3 Getting started - -A good way to get started is to run some of the tests included in the download. - -Copy the "Examples" folder next to your "Classes" folder from above so you end up with: - -/var/www/Examples/01simple.php -/var/www/Examples/02types.php -... - -Start running the tests by pointing your browser to the test scripts: - -http://example.com/Tests/01simple.php -http://example.com/Tests/02types.php -... - -Note: It may be necessary to modify the include/require statements at the beginning of each of the test scripts if your "Classes" folder from above is named differently. - -### 1.4 Useful links and tools - -There are some links and tools which are very useful when developing using PHPExcel. Please refer to the [PHPExcel CodePlex pages][2] for an update version of the list below. - -#### 1.4.1 OpenXML / SpreadsheetML - - - __File format documentation__ -[http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm][3] - - __OpenXML Explained e-book__ -[http://openxmldeveloper.org/articles/1970.aspx][4] - - __Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint 2007 File Formats__ -[http://www.microsoft.com/downloads/details.aspx?familyid=941b3470-3ae9-4aee-8f43-c6bb74cd1466&displaylang=en][5] - - __OpenXML Package Explorer__ -[http://www.codeplex.com/PackageExplorer/][6] - -#### 1.4.2 Frequently asked questions - -The up-to-date F.A.Q. page for PHPExcel can be found on [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=FAQ&referringTitle=Requirements][7]. - -##### There seems to be a problem with character encoding... - -It is necessary to use UTF-8 encoding for all texts in PHPExcel. If the script uses different encoding then you can convert those texts with PHP's iconv() or mb_convert_encoding() functions. - -##### PHP complains about ZipArchive not being found - -Make sure you meet all requirements, especially php_zip extension should be enabled. - -The ZipArchive class is only required when reading or writing formats that use Zip compression (Excel2007 and OOCalc). Since version 1.7.6 the PCLZip library has been bundled with PHPExcel as an alternative to the ZipArchive class. - -This can be enabled by calling: -```php -PHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP); -``` -*before* calling the save method of the Excel2007 Writer. - -You can revert to using ZipArchive by calling: -```php -PHPExcel_Settings::setZipClass(PHPExcel_Settings::ZIPARCHIVE); -``` -At present, this only allows you to write Excel2007 files without the need for ZipArchive (not to read Excel2007 or OOCalc) - -##### Excel 2007 cannot open the file generated by PHPExcel_Writer_2007 on Windows - -*"Excel found unreadable content in '*.xlsx'. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes."�* - -Some older versions of the 5.2.x php_zip extension on Windows contain an error when creating ZIP files. The version that can be found on [http://snaps.php.net/win32/php5.2-win32-latest.zip][8] should work at all times. - -Alternatively, upgrading to at least PHP 5.2.9 should solve the problem. - -If you can't locate a clean copy of ZipArchive, then you can use the PCLZip library as an alternative when writing Excel2007 files, as described above. - -##### Fatal error: Allowed memory size of xxx bytes exhausted (tried to allocate yyy bytes) in zzz on line aaa - -PHPExcel holds an "in memory" representation of a spreadsheet, so it is susceptible to PHP's memory limitations. The memory made available to PHP can be increased by editing the value of the memory_limit directive in your php.ini file, or by using ini_set('memory_limit', '128M') within your code (ISP permitting). - -Some Readers and Writers are faster than others, and they also use differing amounts of memory. You can find some indication of the relative performance and memory usage for the different Readers and Writers, over the different versions of PHPExcel, on the [discussion board][9]. - -If you've already increased memory to a maximum, or can't change your memory limit, then [this discussion][10] on the board describes some of the methods that can be applied to reduce the memory usage of your scripts using PHPExcel. - -##### Protection on my worksheet is not working? - -When you make use of any of the worksheet protection features (e.g. cell range protection, prohibiting deleting rows, ...), make sure you enable worksheet security. This can for example be done like this: -```php -$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); -``` - -##### Feature X is not working with PHPExcel_Reader_Y / PHPExcel_Writer_Z - -Not all features of PHPExcel are implemented in all of the Reader / Writer classes. This is mostly due to underlying libraries not supporting a specific feature or not having implemented a specific feature. - -For example autofilter is not implemented in PEAR Spreadsheet_Excel_writer, which is the base of our Excel5 writer. - -We are slowly building up a list of features, together with the different readers and writers that support them, in the "Functionality Cross-Reference.xls" file in the /Documentation folder. - -##### Formulas don''t seem to be calculated in Excel2003 using compatibility pack? - -This is normal behaviour of the compatibility pack, Excel2007 displays this correctly. Use PHPExcel_Writer_Excel5 if you really need calculated values, or force recalculation in Excel2003. - -##### Setting column width is not 100% accurate - -Trying to set column width, I experience one problem. When I open the file in Excel, the actual width is 0.71 less than it should be. - -The short answer is that PHPExcel uses a measure where padding is included. See section: "Setting a column's width"" for more details. - -##### How do I use PHPExcel with my framework - - - There are some instructions for using PHPExcel with Joomla on the [Joomla message board][11] - - A page of advice on using [PHPExcel in the Yii framework][12] - - [The Bakery][13] has some helper classes for reading and writing with PHPExcel within CakePHP - - Integrating [PHPExcel into Kohana][14] http://www.flynsarmy.com/2010/07/phpexcel-module-for-kohana-3/ and [?????????? PHPExcel ? Kohana Framework][15] - - Using [PHPExcel with Typo3][16] - -##### Joomla Autoloader interferes with PHPExcel Autoloader - -Thanks to peterrlynch for the following advice on resolving issues between the [PHPExcel autoloader and Joomla Autoloader][17] - -#### 1.4.3 Tutorials - - - __English PHPExcel tutorial__ - http://openxmldeveloper.org - - __French PHPExcel tutorial__ -[http://g-ernaelsten.developpez.com/tutoriels/excel2007/][18] - - __Russian PHPExcel Blog Postings__ - http://www.web-junior.net/sozdanie-excel-fajjlov-s-pomoshhyu-phpexcel/ - - __A Japanese-language introduction to PHPExcel__ - [http://journal.mycom.co.jp/articles/2009/03/06/phpexcel/index.html][19] - - -# Architecture - -## Schematical - - - -## Lazy Loader - -PHPExcel implements an autoloader or "lazy loader"�, which means that it is not necessary to include every file within PHPExcel. It is only necessary to include the initial PHPExcel class file, then the autoloader will include other class files as and when required, so only those files that are actually required by your script will be loaded into PHP memory. The main benefit of this is that it reduces the memory footprint of PHPExcel itself, so that it uses less PHP memory. - -If your own scripts already define an autoload function, then this may be overwritten by the PHPExcel autoload function. For example, if you have: - -function __autoload($class) { - -... - -} - -Do this instead: - -function myAutoload($class) { - -... - -} - -spl_autoload_register('myAutoload'); - -Your autoloader will then co-exist with the autoloader of PHPExcel. - -## Spreadsheet in memory - -PHPExcel’s architecture is built in a way that it can serve as an in-memory spreadsheet. This means that, if one would want to create a web based view of a spreadsheet which communicates with PHPExcel’s object model, he would only have to write the front-end code. - -Just like desktop spreadsheet software, PHPExcel represents a spreadsheet containing one or more worksheets, which contain cells with data, formulas, images, … - -## Readers and writers - -On its own, PHPExcel does not provide the functionality to read from or write to a persisted spreadsheet (on disk or in a database). To provide that functionality, readers and writers can be used. - -By default, the PHPExcel package provides some readers and writers, including one for the Open XML spreadsheet format (a.k.a. Excel 2007 file format). You are not limited to the default readers and writers, as you are free to implement the PHPExcel_Writer_IReader and PHPExcel_Writer_IWriter interface in a custom class. - - - -## Fluent interfaces - -PHPExcel supports fluent interfaces in most locations. This means that you can easily “chain” calls to specific methods without requiring a new PHP statement. For example, take the following code: - -$objPHPExcel->getProperties()->setCreator("Maarten Balliauw"); - -$objPHPExcel->getProperties()->setLastModifiedBy("Maarten Balliauw"); - -$objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document"); - -$objPHPExcel->getProperties()->setSubject("Office 2007 XLSX Test Document"); - -$objPHPExcel->getProperties()->setDescription("Test document for Office 2007 XLSX, generated using PHP classes."); - -$objPHPExcel->getProperties()->setKeywords("office 2007 openxml php"); - -$objPHPExcel->getProperties()->setCategory("Test result file"); - -This can be rewritten as: - -$objPHPExcel->getProperties() - ->setCreator("Maarten Balliauw") - -->setLastModifiedBy("Maarten Balliauw") - -->setTitle("Office 2007 XLSX Test Document") - -->setSubject("Office 2007 XLSX Test Document") - -->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") - -->setKeywords("office 2007 openxml php") - -->setCategory("Test result file"); - -__Using fluent interfaces is not required__ -Fluent interfaces have been implemented to provide a convenient programming API. Use of them is not required, but can make your code easier to read and maintain. It can also improve performance, as you are reducing the overall number of calls to PHPExcel methods. - # Creating a spreadsheet ## The PHPExcel class From 43c77557d7c49e183b338152a9642d2111ac8187 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 16 May 2013 22:52:37 +0100 Subject: [PATCH 073/467] case-sensitivity in file names --- .../Overview/{01-getting-started.md => 01-Getting-Startedx.md} | 0 .../markdown/Overview/{02-architecture.md => 02-Architecturex.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Documentation/markdown/Overview/{01-getting-started.md => 01-Getting-Startedx.md} (100%) rename Documentation/markdown/Overview/{02-architecture.md => 02-Architecturex.md} (100%) diff --git a/Documentation/markdown/Overview/01-getting-started.md b/Documentation/markdown/Overview/01-Getting-Startedx.md similarity index 100% rename from Documentation/markdown/Overview/01-getting-started.md rename to Documentation/markdown/Overview/01-Getting-Startedx.md diff --git a/Documentation/markdown/Overview/02-architecture.md b/Documentation/markdown/Overview/02-Architecturex.md similarity index 100% rename from Documentation/markdown/Overview/02-architecture.md rename to Documentation/markdown/Overview/02-Architecturex.md From 934b07cc76ad2669695dbaa87b0cff30fa55a263 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 16 May 2013 22:53:16 +0100 Subject: [PATCH 074/467] case-sensitivity in filenames --- .../Overview/{01-Getting-Startedx.md => 01-Getting-Started.md} | 0 .../markdown/Overview/{02-Architecturex.md => 02-Architecture.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Documentation/markdown/Overview/{01-Getting-Startedx.md => 01-Getting-Started.md} (100%) rename Documentation/markdown/Overview/{02-Architecturex.md => 02-Architecture.md} (100%) diff --git a/Documentation/markdown/Overview/01-Getting-Startedx.md b/Documentation/markdown/Overview/01-Getting-Started.md similarity index 100% rename from Documentation/markdown/Overview/01-Getting-Startedx.md rename to Documentation/markdown/Overview/01-Getting-Started.md diff --git a/Documentation/markdown/Overview/02-Architecturex.md b/Documentation/markdown/Overview/02-Architecture.md similarity index 100% rename from Documentation/markdown/Overview/02-Architecturex.md rename to Documentation/markdown/Overview/02-Architecture.md From e74b1e08f8a93ab72c146c82d269a18a1474aa33 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 17 May 2013 00:09:14 +0100 Subject: [PATCH 075/467] markdown documentation --- .../Overview/05-Deleting-a-Workbook.md | 13 +++ .../markdown/Overview/06-Worksheets.md | 94 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 Documentation/markdown/Overview/05-Deleting-a-Workbook.md create mode 100644 Documentation/markdown/Overview/06-Worksheets.md diff --git a/Documentation/markdown/Overview/05-Deleting-a-Workbook.md b/Documentation/markdown/Overview/05-Deleting-a-Workbook.md new file mode 100644 index 000000000..0ea91712f --- /dev/null +++ b/Documentation/markdown/Overview/05-Deleting-a-Workbook.md @@ -0,0 +1,13 @@ +# PHPExcel Developer Documentation + +## Clearing a Workbook from memory + +The PHPExcel object contains cyclic references (e.g. the workbook is linked to the worksheets, and the worksheets are linked to their parent workbook) which cause problems when PHP tries to clear the objects from memory when they are unset(), or at the end of a function when they are in local scope. The result of this is "memory leaks", which can easily use a large amount of PHP's limited memory. + +This can only be resolved manually: if you need to unset a workbook, then you also need to "break" these cyclic references before doing so. PHPExcel provides the disconnectWorksheets() method for this purpose. + +```php +$objPHPExcel->disconnectWorksheets(); + +unset($objPHPExcel); +``` diff --git a/Documentation/markdown/Overview/06-Worksheets.md b/Documentation/markdown/Overview/06-Worksheets.md new file mode 100644 index 000000000..1c2a9ea5c --- /dev/null +++ b/Documentation/markdown/Overview/06-Worksheets.md @@ -0,0 +1,94 @@ +# PHPExcel Developer Documentation + +## Worksheets + +A worksheet is a collection of cells, formulae, images, graphs, etc. It holds all data necessary to represent a spreadsheet worksheet. + +When you load a workbook from a spreadsheet file, it will be loaded with all its existing worksheets (unless you specified that only certain sheets should be loaded). When you load from non-spreadsheet files (such as a CSV or HTML file) or from spreadsheet formats that don't identify worksheets by name (such as SYLK), then a single worksheet called "WorkSheet1" will be created containing the data from that file. + +When you instantiate a new workbook, PHPExcel will create it with a single worksheet called "WorkSheet1"�. + +The `getSheetCount()` method will tell you the number of worksheets in the workbook; while the `getSheetNames()` method will return a list of all worksheets in the workbook, indexed by the order in which their "tabs" would appear when opened in MS Excel (or other appropriate Spreadsheet program). + +Individual worksheets can be accessed by name, or by their index position in the workbook. The index position represents the order that each worksheet "tab" is shown when the workbook is opened in MS Excel (or other appropriate Spreadsheet program). To access a sheet by its index, use the `getSheet()` method. + +```php +// Get the second sheet in the workbook +// Note that sheets are indexed from 0 +$objPHPExcel->getSheet(1); +``` + +If you don't specify a sheet index, then the first worksheet will be returned. + +Methods also exist allowing you to reorder the worksheets in the workbook. + +To access a sheet by name, use the `getSheetByName()` method, specifying the name of the worksheet that you want to access. + +```php +// Retrieve the worksheet called 'Worksheet 1' +$objPHPExcel->getSheetByName('Worksheet 1'); +``` + +Alternatively, one worksheet is always the currently active worksheet, and you can access that directly. The currently active worksheet is the one that will be active when the workbook is opened in MS Excel (or other appropriate Spreadsheet program). + +```php +// Retrieve the current active worksheet +$objPHPExcel->getActiveSheet(); +``` + +You can change the currently active sheet by index or by name using the `setActiveSheetIndex()` and `setActiveSheetIndexByName()` methods. + +### Adding a new Worksheet + +You can add a new worksheet to the workbook using the `createSheet()` method of the PHPExcel object. By default, this will be created as a new "last�" sheet; but you can also specify an index position as an argument, and the worksheet will be inserted at that position, shuffling all subsequent worksheets in the collection down a place. + +```php +$objPHPExcel->createSheet(); +``` + +A new worksheet created using this method will be called "Worksheet"� where ""� is the lowest number possible to guarantee that the title is unique. + +Alternatively, you can instantiate a new worksheet (setting the title to whatever you choose) and then insert it into your workbook using the addSheet() method. + +```php +// Create a new worksheet called "My Data" +$myWorkSheet = new PHPExcel_Worksheet($objPHPExcel, 'My Data'); + +// Attach the "My Data" worksheet as the first worksheet in the PHPExcel object +$objPHPExcel->addSheet($myWorkSheet, 0); +``` + +If you don't specify an index position as the second argument, then the new worksheet will be added after the last existing worksheet. + +### Copying Worksheets + +Sheets within the same workbook can be copied by creating a clone of the worksheet you wish to copy, and then using the addSheet() method to insert the clone into the workbook. + +```php +$objClonedWorksheet = clone $objPHPExcel->getSheetByName('Worksheet 1'); +$objClonedWorksheet->setTitle('Copy of Worksheet 1') +$objPHPExcel->addSheet($objClonedWorksheet); +``` + +You can also copy worksheets from one workbook to another, though this is more complex as PHPExcel also has to replicate the styling between the two workbooks. The addExternalSheet() method is provided for this purpose. + +``` +$objClonedWorksheet = clone $objPHPExcel1->getSheetByName('Worksheet 1'); +$objPHPExcel->addExternalSheet($objClonedWorksheet); +``` + +In both cases, it is the developer's responsibility to ensure that worksheet names are not duplicated. PHPExcel will throw an exception if you attempt to copy worksheets that will result in a duplicate name. + +### Removing a Worksheet + +You can delete a worksheet from a workbook, identified by its index position, using the removeSheetByIndex() method + +```php +$sheetIndex = $objPHPExcel->getIndex( + $objPHPExcel->getSheetByName('Worksheet 1') +); +$objPHPExcel->removeSheetByIndex($sheetIndex); +``` + +If the currently active worksheet is deleted, then the sheet at the previous index position will become the currently active sheet. + From 1c98aaa76a2b4600e42f899a63eed493a1f31df0 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 17 May 2013 17:49:12 +0100 Subject: [PATCH 076/467] documentation markdown --- .../markdown/Overview/07-Accessing-Cells.md | 357 ++++++++++++++++++ Documentation/markdown/Overview/developer.md | 331 ++-------------- .../Overview/images/07-simple-example-1.png | Bin 0 -> 12239 bytes .../Overview/images/07-simple-example-2.png | Bin 0 -> 9620 bytes .../Overview/images/07-simple-example-3.png | Bin 0 -> 7157 bytes .../Overview/images/07-simple-example-4.png | Bin 0 -> 8018 bytes 6 files changed, 391 insertions(+), 297 deletions(-) create mode 100644 Documentation/markdown/Overview/07-Accessing-Cells.md create mode 100644 Documentation/markdown/Overview/images/07-simple-example-1.png create mode 100644 Documentation/markdown/Overview/images/07-simple-example-2.png create mode 100644 Documentation/markdown/Overview/images/07-simple-example-3.png create mode 100644 Documentation/markdown/Overview/images/07-simple-example-4.png diff --git a/Documentation/markdown/Overview/07-Accessing-Cells.md b/Documentation/markdown/Overview/07-Accessing-Cells.md new file mode 100644 index 000000000..cc446d889 --- /dev/null +++ b/Documentation/markdown/Overview/07-Accessing-Cells.md @@ -0,0 +1,357 @@ +# PHPExcel Developer Documentation + +## Accessing cells + +Accessing cells in a PHPExcel worksheet should be pretty straightforward. This topic lists some of the options to access a cell. + +### Setting a cell value by coordinate + +Setting a cell value by coordinate can be done using the worksheet's `setCellValue()` method. + +```php +// Set cell A1 with a string value +$objPHPExcel->getActiveSheet()->setCellValue('A1', 'PHPExcel'); + +// Set cell A2 with a numeric value +$objPHPExcel->getActiveSheet()->setCellValue('A2', 12345.6789); + +// Set cell A3 with a boolean value +$objPHPExcel->getActiveSheet()->setCellValue('A3', TRUE); + +// Set cell A4 with a formula +$objPHPExcel->getActiveSheet()->setCellValue( + 'A4', + '=IF(A3, CONCATENATE(A1, " ", A2), CONCATENATE(A2, " ", A1))' +); +``` + +#### Setting a date and/or time in a cell + +Date or time values are held as timestamp in Excel (a simple floating point value), and a number format mask is used to show how that value should be formatted; so if we want to store a date in a cell, we need to calculate the correct Excel timestamp, and set a number format mask. + +```php +// Get the current date/time and convert to an Excel date/time +$dateTimeNow = time(); +$excelDateValue = PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ); +// Set cell A6 with the Excel date/time value +$objPHPExcel->getActiveSheet()->setCellValue( + 'A6', + $excelDateValue +); +// Set the number format mask so that the excel timestamp will be displayed as a human-readable date/time +$objPHPExcel->getActiveSheet()->getStyle('A6') + ->getNumberFormat() + ->setFormatCode( + PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME + ); +``` + +#### Setting a number with leading zeroes + +By default, PHPExcel will automatically detect the value type and set it to the appropriate Excel datatype. This type conversion is handled by a value binder, as described in the section of this document entitled "Using value binders to facilitate data entry". + +Numbers don't have leading zeroes, so if you try to set a numeric value that does have leading zeroes (such as a telephone number) then these will be normally be lost as the value is cast to a number, so "01513789642" will be displayed as 1513789642. + +There are two ways you can force PHPExcel to override this behaviour. + +Firstly, you can set the datatype explicitly as a string so that it is not converted to a number. + +```php +// Set cell A8 with a numeric value, but tell PHPExcel it should be treated as a string +$objPHPExcel->getActiveSheet()->setCellValueExplicit( + 'A8', + "01513789642", + PHPExcel_Cell_DataType::TYPE_STRING +); +``` + +Alternatively, you can use a number format mask to display the value with leading zeroes. + +```php +// Set cell A9 with a numeric value +$objPHPExcel->getActiveSheet()->setCellValue('A9', 1513789642); +// Set a number format mask to display the value as 11 digits with leading zeroes +$objPHPExcel->getActiveSheet()->getStyle('A9') + ->getNumberFormat() + ->setFormatCode( + '00000000000' + ); +``` + +With number format masking, you can even break up the digits into groups to make the value more easily readable. + +```php +// Set cell A10 with a numeric value +$objPHPExcel->getActiveSheet()->setCellValue('A10', 1513789642); +// Set a number format mask to display the value as 11 digits with leading zeroes +$objPHPExcel->getActiveSheet()->getStyle('A10') + ->getNumberFormat() + ->setFormatCode( + '0000-000-0000' + ); +``` + +![07-simple-example-1.png](./images/07-simple-example-1.png "") + + +**Note** that not all complex format masks such as this one will work when retrieving a formatted value to display "on screen", or for certain writers such as HTML or PDF, but it will work with the true spreadsheet writers (Excel2007 and Excel5). + +### Setting a range of cells from an array + +It is also possible to set a range of cell values in a single call by passing an array of values to the `fromArray()` method. + +```php +$arrayData = array( + array(NULL, 2010, 2011, 2012), + array('Q1', 12, 15, 21), + array('Q2', 56, 73, 86), + array('Q3', 52, 61, 69), + array('Q4', 30, 32, 0), +); +$objPHPExcel->getActiveSheet() + ->fromArray( + $arrayData, // The data to set + NULL, // Array values with this value will not be set + 'C3' // Top left coordinate of the worksheet range where + // we want to set these values (default is A1) + ); +``` + +![07-simple-example-2.png](./images/07-simple-example-2.png "") + +If you pass a 2-d array, then this will be treated as a series of rows and columns. A 1-d array will be treated as a single row, which is particularly useful if you're fetching an array of data from a database. + +```php +$rowArray = array('Value1', 'Value2', 'Value3', 'Value4'); +$objPHPExcel->getActiveSheet() + ->fromArray( + $rowArray, // The data to set + NULL, // Array values with this value will not be set + 'C3' // Top left coordinate of the worksheet range where + // we want to set these values (default is A1) + ); +``` + +![07-simple-example-3.png](./images/07-simple-example-3.png "") + +If you have a simple 1-d array, and want to write it as a column, then the following will convert it into an appropriately structured 2-d array that can be fed to the `fromArray()` method: + +```php +$rowArray = array('Value1', 'Value2', 'Value3', 'Value4'); +$columnArray = array_chunk($rowArray, 1); +$objPHPExcel->getActiveSheet() + ->fromArray( + $columnArray, // The data to set + NULL, // Array values with this value will not be set + 'C3' // Top left coordinate of the worksheet range where + // we want to set these values (default is A1) + ); +``` + +![07-simple-example-4.png](./images/07-simple-example-4.png "") + +### Retrieving a cell value by coordinate + +To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the `getCell()` method. A cell's value can be read using the `getValue()` method. + +```php +// Get the value fom cell A1 +$cellValue = $objPHPExcel->getActiveSheet()->getCell('A1') + ->getValue(); +``` + +This will retrieve the raw, unformatted value contained in the cell. + +If a cell contains a formula, and you need to retrieve the calculated value rather than the formula itself, then use the cell's `getCalculatedValue()` method. This is further explained in . + +```php +// Get the value fom cell A4 +$cellValue = $objPHPExcel->getActiveSheet()->getCell('A4') + ->getCalculatedValue(); +``` + +Alternatively, if you want to see the value with any cell formatting applied (e.g. for a human-readable date or time value), then you can use the cell's `getFormattedValue()` method. + +```php +// Get the value fom cell A6 +$cellValue = $objPHPExcel->getActiveSheet()->getCell('A6') + ->getFormattedValue(); +``` + + +### Setting a cell value by column and row + +Setting a cell value by coordinate can be done using the worksheet's `setCellValueByColumnAndRow()` method. + +```php +// Set cell B5 with a string value +$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(1, 5, 'PHPExcel'); +``` + +**Note** that column references start with '0' for column 'A', rather than from '1'. + +### Retrieving a cell value by column and row + +To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the getCellByColumnAndRow method. A cell’s value can be read again using the following line of code: + +```php +// Get the value fom cell B5 +$cellValue = $objPHPExcel->getActiveSheet()->getCellByColumnAndRow(1, 5) + ->getValue(); +``` +If you need the calculated value of a cell, use the following code. This is further explained in . + +```php +// Get the value fom cell A4 +$cellValue = $objPHPExcel->getActiveSheet()->getCellByColumnAndRow(0, 4) + ->getCalculatedValue(); +``` + +### Retrieving a range of cell values to an array + +It is also possible to retrieve a range of cell values to an array in a single call using the `toArray()`, `rangeToArray()` or `namedRangeToArray()` methods. + +```php +$dataArray = $objPHPExcel->getActiveSheet() + ->rangeToArray( + 'C3:E5', // The worksheet range that we want to retrieve + NULL, // Value that should be returned for empty cells + TRUE, // Should formulas be calculated (the equivalent of getCalculatedValue() for each cell) + TRUE, // Should values be formatted (the equivalent of getFormattedValue() for each cell) + TRUE // Should the array be indexed by cell row and cell column + ); +``` + +These methods will all return a 2-d array of rows and columns. The `toArray()` method will return the whole worksheet; `rangeToArray()` will return a specified range or cells; while `namedRangeToArray()` will return the cells within a defined `named range`. + +### Looping through cells + +#### Looping through cells using iterators + +The easiest way to loop cells is by using iterators. Using iterators, one can use foreach to loop worksheets, rows within a worksheet, and cells within a row. + +Below is an example where we read all the values in a worksheet and display them in a table. + +```php +$objReader = PHPExcel_IOFactory::createReader('Excel2007'); +$objReader->setReadDataOnly(TRUE); +$objPHPExcel = $objReader->load("test.xlsx"); + +$objWorksheet = $objPHPExcel->getActiveSheet(); + +echo '' . PHP_EOL; +foreach ($objWorksheet->getRowIterator() as $row) { + echo '' . PHP_EOL; + $cellIterator = $row->getCellIterator(); + $cellIterator->setIterateOnlyExistingCells(FALSE); // This loops through all cells, + // even if a cell value is not set. + // By default, only cells that have a value + // set will be iterated. + foreach ($cellIterator as $cell) { + echo '' . PHP_EOL; + } + echo '' . PHP_EOL; +} +echo '
' . + $cell->getValue() . + '
' . PHP_EOL; +``` + +Note that we have set the cell iterator's `setIterateOnlyExistingCells()` to FALSE. This makes the iterator loop all cells within the worksheet range, even if they have not been set. + +The cell iterator will return a __NULL__ as the cell value if it is not set in the worksheet. +Setting the cell iterator's setIterateOnlyExistingCells() to FALSE will loop all cells in the worksheet that can be available at that moment. This will create new cells if required and increase memory usage! Only use it if it is intended to loop all cells that are possibly available. + +#### Looping through cells using indexes + +One can use the possibility to access cell values by column and row index like (0,1) instead of 'A1' for reading and writing cell values in loops. + +Note: In PHPExcel column index is 0-based while row index is 1-based. That means 'A1' ~ (0,1) + +Below is an example where we read all the values in a worksheet and display them in a table. + +```php +$objReader = PHPExcel_IOFactory::createReader('Excel2007'); +$objReader->setReadDataOnly(TRUE); +$objPHPExcel = $objReader->load("test.xlsx"); + +$objWorksheet = $objPHPExcel->getActiveSheet(); +// Get the highest row and column numbers referenced in the worksheet +$highestRow = $objWorksheet->getHighestRow(); // e.g. 10 +$highestColumn = $objWorksheet->getHighestColumn(); // e.g 'F' +$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn); // e.g. 5 + +echo '' . "\n"; +for ($row = 1; $row <= $highestRow; ++$row) { + echo '' . PHP_EOL; + for ($col = 0; $col <= $highestColumnIndex; ++$col) { + echo '' . PHP_EOL; + } + echo '' . PHP_EOL; +} +echo '
' . + $objWorksheet->getCellByColumnAndRow($col, $row) + ->getValue() . + '
' . PHP_EOL; +``` + +Alternatively, you can take advantage of PHP's "Perl-style" character incrementors to loop through the cells by coordinate: + +```php +$objReader = PHPExcel_IOFactory::createReader('Excel2007'); +$objReader->setReadDataOnly(TRUE); +$objPHPExcel = $objReader->load("test.xlsx"); + +$objWorksheet = $objPHPExcel->getActiveSheet(); +// Get the highest row number and column letter referenced in the worksheet +$highestRow = $objWorksheet->getHighestRow(); // e.g. 10 +$highestColumn = $objWorksheet->getHighestColumn(); // e.g 'F' +// Increment the highest column letter +$highestColumn++; + +echo '' . "\n"; +for ($row = 1; $row <= $highestRow; ++$row) { + echo '' . PHP_EOL; + for ($col = 'A'; $col != $highestColumn; ++$col) { + echo '' . PHP_EOL; + } + echo '' . PHP_EOL; +} +echo '
' . + $objWorksheet->getCell($col . $row) + ->getValue() . + '
' . PHP_EOL; +``` + +Note that we can't use a <= comparison here, because 'AA' would match as <= 'B', so we increment the highest column letter and then loop while $col != the incremented highest column. + +### Using value binders to facilitate data entry + +Internally, PHPExcel uses a default PHPExcel_Cell_IValueBinder implementation (PHPExcel_Cell_DefaultValueBinder) to determine data types of entered data using a cell's `setValue()` method (the `setValueExplicit()` method bypasses this check). + +Optionally, the default behaviour of PHPExcel can be modified, allowing easier data entry. For example, a PHPExcel_Cell_AdvancedValueBinder class is available. It automatically converts percentages, number in scientific format, and dates entered as strings to the correct format, also setting the cell's style information. The following example demonstrates how to set the value binder in PHPExcel: + +```php +/** PHPExcel */ +require_once 'PHPExcel.php'; + +// Set value binder +PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); + +// Create new PHPExcel object +$objPHPExcel = new PHPExcel(); + +// ... +// Add some data, resembling some different data types +$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Percentage value:'); +// Converts the string value to 0.1 and sets percentage cell style +$objPHPExcel->getActiveSheet()->setCellValue('B4', '10%'); + +$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Date/time value:'); +// Converts the string value to an Excel datestamp and sets the date format cell style +$objPHPExcel->getActiveSheet()->setCellValue('B5', '21 December 1983'); +``` + +__Creating your own value binder is easy.__ +When advanced value binding is required, you can implement the PHPExcel_Cell_IValueBinder interface or extend the PHPExcel_Cell_DefaultValueBinder or PHPExcel_Cell_AdvancedValueBinder classes. + diff --git a/Documentation/markdown/Overview/developer.md b/Documentation/markdown/Overview/developer.md index 5063d741b..1e993044f 100644 --- a/Documentation/markdown/Overview/developer.md +++ b/Documentation/markdown/Overview/developer.md @@ -1,307 +1,59 @@ # PHPExcel Developer Documentation -# Creating a spreadsheet - -## The PHPExcel class - -The PHPExcel class is the core of PHPExcel. It contains references to the contained worksheets, document security settings and document meta data. - -To simplify the PHPExcel concept: the PHPExcel class represents your workbook. - -Typically, you will create a workbook in one of two ways, either by loading it from a spreadsheet file, or creating it manually. A third option, though less commonly used, is cloning an existing workbook that has been created using one of the previous two methods. - -### Loading a Workbook from a file - -Details of the different spreadsheet formats supported, and the options available to read them into a PHPExcel object are described fully in the “PHPExcel User Documentation - Reading Spreadsheet Files” document. - - -$inputFileName� =� './sampleData/example1.xls'; - -/**� Load� $inputFileName� to� a� PHPExcel� Object� � **/ -$objPHPExcel� =� PHPExcel_IOFactory::load($inputFileName); - - -### Creating a new workbook - -If you want to create a new workbook, rather than load one from file, then you simply need to instantiate it as a new PHPExcel object. - - -/**� Create a� new PHPExcel� Object� � **/ -$objPHPExcel� =� new PHPExcel(); - - -A new workbook will always be created with a single worksheet. - -## Configuration Settings - -Once you have included the PHPExcel files in your script, but before instantiating a PHPExcel object or loading a workbook file, there are a number of configuration options that can be set which will affect the subsequent behaviour of the script. - -### Cell Caching - -PHPExcel uses an average of about 1k/cell in your worksheets, so large workbooks can quickly use up available memory. Cell caching provides a mechanism that allows PHPExcel to maintain the cell objects in a smaller size of memory, on disk, or in APC, memcache or Wincache, rather than in PHP memory. This allows you to reduce the memory usage for large workbooks, although at a cost of speed to access cell data. - -By default, PHPExcel still holds all cell objects in memory, but you can specify alternatives. To enable cell caching, you must call the PHPExcel_Settings::setCacheStorageMethod() method, passing in the caching method that you wish to use. - -$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory; - -PHPExcel_Settings::setCacheStorageMethod($cacheMethod); - -setCacheStorageMethod() will return a boolean true on success, false on failure (for example if trying to cache to APC when APC is not enabled). - -A separate cache is maintained for each individual worksheet, and is automatically created when the worksheet is instantiated based on the caching method and settings that you have configured. You cannot change the configuration settings once you have started to read a workbook, or have created your first worksheet. - -Currently, the following caching methods are available. - -PHPExcel_CachedObjectStorageFactory::cache_in_memory; - -The default. If you don’t initialise any caching method, then this is the method that PHPExcel will use. Cell objects are maintained in PHP memory as at present. - -PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized; - -Using this caching method, cells are held in PHP memory as an array of serialized objects, which reduces the memory footprint with minimal performance overhead. - -PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip; - -Like cache_in_memory_serialized, this method holds cells in PHP memory as an array of serialized objects, but gzipped to reduce the memory usage still further, although access to read or write a cell is slightly slower. - -PHPExcel_CachedObjectStorageFactory::cache_igbinary; - -Uses PHP’s igbinary extension (if it’s available) to serialize cell objects in memory. This is normally faster and uses less memory than standard PHP serialization, but isn’t available in most hosting environments. - -PHPExcel_CachedObjectStorageFactory::cache_to_discISAM; - -When using cache_to_discISAM all cells are held in a temporary disk file, with only an index to their location in that file maintained in PHP memory. This is slower than any of the cache_in_memory methods, but significantly reduces the memory footprint. By default, PHPExcel will use PHP’s temp directory for the cache file, but you can specify a different directory when initialising cache_to_discISAM. - -$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_discISAM; - -$cacheSettings = array( 'dir' => '/usr/local/tmp' - -); - -PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); - -The temporary disk file is automatically deleted when your script terminates. - -PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp; - -Like cache_to_discISAM, when using cache_to_phpTemp all cells are held in the php://temp I/O stream, with only an index to their location maintained in PHP memory. In PHP, the php://memory wrapper stores data in the memory: php://temp behaves similarly, but uses a temporary file for storing the data when a certain memory limit is reached. The default is 1 MB, but you can change this when initialising cache_to_phpTemp. - -$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp; - -$cacheSettings = array( 'memoryCacheSize' => '8MB' - -); - -PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); - -The php://temp file is automatically deleted when your script terminates. - -PHPExcel_CachedObjectStorageFactory::cache_to_apc; - -When using cache_to_apc, cell objects are maintained in APC with only an index maintained in PHP memory to identify that the cell exists. By default, an APC cache timeout of 600 seconds is used, which should be enough for most applications: although it is possible to change this when initialising cache_to_APC. - -$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_APC; - -$cacheSettings = array( 'cacheTime' => 600 - -); - -PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); - -When your script terminates all entries will be cleared from APC, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism. - -PHPExcel_CachedObjectStorageFactory::cache_to_memcache - -When using cache_to_memcache, cell objects are maintained in memcache with only an index maintained in PHP memory to identify that the cell exists. - -By default, PHPExcel looks for a memcache server on localhost at port 11211. It also sets a memcache timeout limit of 600 seconds. If you are running memcache on a different server or port, then you can change these defaults when you initialise cache_to_memcache: - -$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_memcache; - -$cacheSettings = array( 'memcacheServer' => 'localhost', - -'memcachePort' => 11211, - -'cacheTime' => 600 - -); - -PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); - -When your script terminates all entries will be cleared from memcache, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism. - -PHPExcel_CachedObjectStorageFactory::cache_to_wincache; - -When using cache_to_wincache, cell objects are maintained in Wincache with only an index maintained in PHP memory to identify that the cell exists. By default, a Wincache cache timeout of 600 seconds is used, which should be enough for most applications: although it is possible to change this when initialising cache_to_wincache. - -$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_wincache; - -$cacheSettings = array( 'cacheTime' => 600 - -); - -PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); - -When your script terminates all entries will be cleared from Wincache, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism. - -PHPExcel_CachedObjectStorageFactory::cache_to_sqlite; - -Uses an SQLite 2 in-memory database for caching cell data. Unlike other caching methods, neither cells nor an index are held in PHP memory - an indexed database table makes it unnecessary to hold any index in PHP memory – making this the most memory-efficient of the cell caching methods. - -PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3; - -Uses an SQLite 3 in-memory database for caching cell data. Unlike other caching methods, neither cells nor an index are held in PHP memory - an indexed database table makes it unnecessary to hold any index in PHP memory – making this the most memory-efficient of the cell caching methods. - -### Language/Locale - -Some localisation elements have been included in PHPExcel. You can set a locale by changing the settings. To set the locale to Brazilian Portuguese you would use: - -$locale = 'pt_br'; - -$validLocale = PHPExcel_Settings::setLocale($locale); - -if (!$validLocale) { - -echo 'Unable to set locale to '.$locale." - reverting to en_us
\n"; - -} - -If Brazilian Portuguese language files aren’t available, then the Portuguese will be enabled instead: if Portuguese language files aren’t available, then the setLocale() method will return an error, and American English (en_us) settings will be used throughout. - -More details of the features available once a locale has been set, including a list of the languages and locales currently supported, can be found in section REF _Ref259954895 \r \h 4.5.5 REF _Ref259954904 \h Locale Settings for Formulae. - -## Clearing a Workbook from memory - -The PHPExcel object contains cyclic references (e.g. the workbook is linked to the worksheets, and the worksheets are linked to their parent workbook) which cause problems when PHP tries to clear the objects from memory when they are unset(), or at the end of a function when they are in local scope. The result of this is “memory leaks”, which can easily use a large amount of PHP’s limited memory. - -This can only be resolved manually: if you need to unset a workbook, then you also need to “break” these cyclic references before doing so. PHPExcel provides the disconnectWorksheets() method for this purpose. - -$objPHPExcel->disconnectWorksheets(); - -unset($objPHPExcel); - -## Worksheets - -A worksheet is a collection of cells, formula’s, images, graphs, … It holds all data necessary to represent as a spreadsheet worksheet. - -When you load a workbook from a spreadsheet file, it will be loaded with all its existing worksheets (unless you specified that only certain sheets should be loaded). When you load from non-spreadsheet files (such as a CSV or HTML file) or from spreadsheet formats that don’t identify worksheets by name (such as SYLK), then a single worksheet called “WorkSheet” will be created containing the data from that file. - -When you instantiate a new workbook, PHPExcel will create it with a single worksheet called “WorkSheet”. - -The getSheetCount() method will tell you the number of worksheets in the workbook; while the getSheetNames() method will return a list of all worksheets in the workbook, indexed by the order in which their “tabs” would appear when opened in MS Excel (or other appropriate Spreadsheet program). - -Individual worksheets can be accessed by name, or by their index position in the workbook. The index position represents the order that each worksheet “tab” is shown when the workbook is opened in MS Excel (or other appropriate Spreadsheet program). To access a sheet by its index, use the getSheet() method. - -// Get the second sheet in the workbook - -// Note that sheets are indexed from 0 - -$objPHPExcel->getSheet(1); - -If you don’t specify a sheet index, then the first worksheet will be returned. - -Methods also exist allowing you to reorder the worksheets in the workbook. - -To access a sheet by name, use the getSheetByName() method, specifying the name of the worksheet that you want to access. - -// Retrieve the worksheet called 'Worksheet 1' - -$objPHPExcel->getSheetByName('Worksheet 1'); - -Alternatively, one worksheet is always the currently active worksheet, and you can access that directly. The currently active worksheet is the one that will be active when the workbook is opened in MS Excel (or other appropriate Spreadsheet program). - -// Retrieve the current active worksheet - -$objPHPExcel->getActiveSheet(); - -You can change the currently active sheet by index or by name using the setActiveSheetIndex() and setActiveSheetIndexByName()methods. - -### Adding a new Worksheet - -You can add a new worksheet to the workbook using the createSheet() method of the PHPExcel object. By default, this will be created as a new “last” sheet; but you can also specify an index position as an argument, and the worksheet will be inserted at that position, shuffling all subsequent worksheets in the collection down a place. - -$objPHPExcel->createSheet(); - -A new worksheet created using this method will be called “Worksheet” or “Worksheet” where “” is the lowest number possible to guarantee that the title is unique. - -Alternatively, you can instantiate a new worksheet (setting the title to whatever you choose) and then insert it into your workbook using the addSheet() method. - -// Create a new worksheet called “My Data” - -$myWorkSheet = new PHPExcel_Worksheet($objPHPExcel, 'My Data'); - -// Attach the “My Data” worksheet as the first worksheet in the PHPExcel object - -$objPHPExcel->addSheet($myWorkSheet, 0); - -If you don’t specify an index position as the second argument, then the new worksheet will be added after the last existing worksheet. - -### Copying Worksheets - -Sheets within the same workbook can be copied by creating a clone of the worksheet you wish to copy, and then using the addSheet() method to insert the clone into the workbook. - -$objClonedWorksheet = clone $objPHPExcel->getSheetByName('Worksheet 1'); - -$objClonedWorksheet->setTitle('Copy of Worksheet 1') - -$objPHPExcel->addSheet($objClonedWorksheet); - -You can also copy worksheets from one workbook to another, though this is more complex as PHPExcel also has to replicate the styling between the two workbooks. The addExternalSheet() method is provided for this purpose. - -$objClonedWorksheet = clone $objPHPExcel1->getSheetByName('Worksheet 1'); - -$objPHPExcel->addExternalSheet($objClonedWorksheet); - -In both cases, it is the developer’s responsibility to ensure that worksheet names are not duplicated. PHPExcel will throw an exception if you attempt to copy worksheets that will result in a duplicate name. - -### Removing a Worksheet - -You can delete a worksheet from a workbook, identified by its index position, using the removeSheetByIndex() method - -$sheetIndex = $objPHPExcel->getIndex($objPHPExcel-> getSheetByName('Worksheet 1')); - -$objPHPExcel->removeSheetByIndex($sheetIndex); - -If the currently active worksheet is deleted, then the sheet at the previous index position will become the currently active sheet. - ## Accessing cells Accessing cells in a PHPExcel worksheet should be pretty straightforward. This topic lists some of the options to access a cell. ### Setting a cell value by coordinate -Setting a cell value by coordinate can be done using the worksheet’s setCellValue method. +Setting a cell value by coordinate can be done using the worksheet's `setCellValue()` method. +```php +// Set cell B8 $objPHPExcel->getActiveSheet()->setCellValue('B8', 'Some value'); +``` + +Will set cell B8 in the currently active worksheet to a string value of "Some Value" ### Retrieving a cell by coordinate -To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the getCell method. A cell’s value can be read again using the following line of code: +To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the `getCell()` method. A cell's value can be read again using the following line of code: +```php +// Get cell B8 $objPHPExcel->getActiveSheet()->getCell('B8')->getValue(); +``` -If you need the calculated value of a cell, use the following code. This is further explained in REF _Ref191885372 \w \h \* MERGEFORMAT 4.4.35. +If a cell contains a formula, and you need to retrieve the calculated value rather than the formula itself, then use the following code. This is further explained in . +```php +// Get cell B8 $objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue(); +``` ### Setting a cell value by column and row Setting a cell value by coordinate can be done using the worksheet’s setCellValueByColumnAndRow method. +```php // Set cell B8 $objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(1, 8, 'Some value'); +``` ### Retrieving a cell by column and row To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the getCellByColumnAndRow method. A cell’s value can be read again using the following line of code: +```php // Get cell B8 $objPHPExcel->getActiveSheet()->getCellByColumnAndRow(1, 8)->getValue(); +``` +If you need the calculated value of a cell, use the following code. This is further explained in . -If you need the calculated value of a cell, use the following code. This is further explained in REF _Ref191885372 \w \h 4.4.35 - +```php // Get cell B8 $objPHPExcel->getActiveSheet()->getCellByColumnAndRow(1, 8)->getCalculatedValue(); +``` ### Looping cells @@ -311,47 +63,32 @@ The easiest way to loop cells is by using iterators. Using iterators, one can us Below is an example where we read all the values in a worksheet and display them in a table. -setReadDataOnly(true); - $objPHPExcel = $objReader->load("test.xlsx"); $objWorksheet = $objPHPExcel->getActiveSheet(); echo '' . "\n"; - foreach ($objWorksheet->getRowIterator() as $row) { - -echo '' . "\n"; - -$cellIterator = $row->getCellIterator(); - -$cellIterator->setIterateOnlyExistingCells(false); // This loops all cells, - // even if it is not set. - // By default, only cells - // that are set will be - // iterated. - -foreach ($cellIterator as $cell) { - -echo '' . "\n"; - -} - -echo '' . "\n"; - + echo '' . "\n"; + $cellIterator = $row->getCellIterator(); + $cellIterator->setIterateOnlyExistingCells(FALSE); // This loops all cells,even if a cell is not set. + // By default, only cells that are set will be iterated. + foreach ($cellIterator as $cell) { + echo '' . "\n"; + } + echo '' . "\n"; } echo '
' . $cell->getValue() . '
' . $cell->getValue() . '
' . "\n"; -?> +``` -Note that we have set the cell iterator’s setIterateOnlyExistingCells() to false. This makes the iterator loop all cells, even if they were not set before. +Note that we have set the cell iterator's `setIterateOnlyExistingCells()` to FALSE. This makes the iterator loop all cells, even if they were not set before. -__The cell iterator will return ____null____ as the cell if it is not set in the worksheet.__ -Setting the cell iterator’s setIterateOnlyExistingCells()to false will loop all cells in the worksheet that can be available at that moment. This will create new cells if required and increase memory usage! Only use it if it is intended to loop all cells that are possibly available. +__The cell iterator will return ____NULL____ as the cell if it is not set in the worksheet.__ +Setting the cell iterator's setIterateOnlyExistingCells() to FALSE will loop all cells in the worksheet that can be available at that moment. This will create new cells if required and increase memory usage! Only use it if it is intended to loop all cells that are possibly available. #### Looping cells using indexes diff --git a/Documentation/markdown/Overview/images/07-simple-example-1.png b/Documentation/markdown/Overview/images/07-simple-example-1.png new file mode 100644 index 0000000000000000000000000000000000000000..30d193683aa96b6839237baf5808043bc6000c08 GIT binary patch literal 12239 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%0Du42g>vFf1>WzBRf|-?z3rz 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 literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Overview/images/07-simple-example-2.png b/Documentation/markdown/Overview/images/07-simple-example-2.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b68506ceb7cd25d4bc3e13f7d8de422472fcc0 GIT binary patch literal 9620 zcmdUVc{G&m|G$<=iByz|;z`sbTV)-Zc*wqu7}-XTvX-%=AsJ62DKSEpvP_I!){?B# zB!ukC*oPQG48}Ga-<$fhe9!m!o#*_1=X}rk{oy$GeP7r0-rw)n_2QASp%xF<5iSl6 z4jvtC4HyTKu8^LX*J5c1JY>H4cu#@ZGGdAmDkI zyY>|?4vzh|Hh#7YISBi3aEO6*G}JEp*v=$QM+uR9hgOg}4P=^g156|4z?F2^b#PWl z>EBKbMb~_zE^A0UvO6R^eEhU#Ly?exT91hH-m;7P^F?ATo^WVuKhb!yw_r!9r&Ead zE@K(}`m)xF`beAX{kxU?%Q7;U6&Zea9#mF#7_Fn1_D?{^J4B_Ul1h&$s4@D!L;hc$bzCAGw$j zTctBsTz`9cz2M88)gDnp;)||S|2P|`mlbp3*_oN@^G{D_3x9K=I@}yNe_;B!WBV@J z*`!V{P2@{UPz`ZD@|lpag;o^KYALtR+E@=+vDET7MK7G35O;nQsp_TmS*gs#`(398 zGcX+;^`*L|>rWtJlgn^wfQaz=``D^TB!n`9SA5vu8Fc~8@CDq}oF>{9avD3)Pb50+ zFsZc?A%!4)S!vfGVb!+=y1k5h+U6O=>}?A;$kNAyueHH(KJn5Ze8!nW(&&l$tI}dE zh=m;jZ1HGB`Ec1fQPhxLEq#|R!AWrcIQfn!JsxP7=b^IDqu?Z5Toh$%cA!QSALt}+ zQajk_T@z2ri@Ryn;$~lEX6$`&C{04!29&&cpI?wvC^B8~UZL_Odb<>rtKGKVg!C&m_37?;;R;;c@T+}-V`o^dOzzFxT@-#rT!Hb0m2(Fi7k?lo{%_M!ESj%SQL z7rI@iR9?cV?7l)QUz>V&6g5OyjAc?!&w3i+!V^_ya2iHCOs>r9gqvNS|5*Pf0824n z?U)oup=%sQiNL!Q@@=HBC%WRFy4kkW91mZv{c`%@p1v77gPQOgC^gB-O85HUv=-n%MvoWznFIg zDT6f**EozXEnW;1CSV_&Sy`lK2JAojO|p}lB)fMAvQK?y@>Q3~{^=Hx`+L=^JKMda zt<`t_asNS9T4O$I?;rQ~9!Zbcb9d7A{?Mb@wRV3)qKNv=C3PJxTTomOZoQFk!FLvu zlYp-yERWH{!WOuFWhF-KaM2`U*q^oZp-2x*j|U> z0R+^mB~T0JH}9vmqLpP~z)=~SL?0a54*OvLbTPKKG38q#`3lzsusf4 z$ikRrn^kN_y=g|EhlDxbMXCtssxovvHh}$EH5f-&T~X^0#=NB{Hyle99(PSn75Q7G9UM0{(4f0uwAcHJviK8BhtK@y#yZ1GL;IQW z6Sgb{ANfMj?f3OJ-v$%6Y`sJEBQuG->(7SI%?l`qlt%ZF$EoSM+eivvN9%}Ip4-?sI?xrqX=vQ~|@Cj>B% zSm?5MN#WY3buVRa#-m#mr(k`$y!s*-6;``CwJk@wg2lUGL%FmH zbATMg$m>M#iGj8}_}hu=!4`oqqFTla(cSO*cHRN~lv zd6molgtck6(ULsGZ3ZvkI2>zoo&5?*m{ACz1sW=#$M7|QrkgG}2lB7Fg83kLhf6vA z(u>hCQdMcyymjkr{@wLD=vqCrlF=tvI`F5$A)#*5w16|UHapRaDCqdH3*NKN8S9ny z8G<@qg}NI7d7@9Ws1Sn(5)XlU9#U19gM0|4dFyPVEqx>>ziO@93d$^v>UZZ2+{Vah zxx4ITNYt{oK3*1KG_;ttNaCc;r)aDFJ(L`WiFoJLV*)GKhpeD?C;JI=^;N#H9#*pP znkjZ;1`4x`86jV6PyuUY(--EFRw^dSc<;W;^0_Ou;mw`tb}HLZtGNa&eL!;-anTvcRQ$x$JHPLH`EHvHnOo#@r25WfvU$|UzMt~x6Gb9lWpxg}a@2S15faKC zSmh1< zI5=dqW4f`pz8i`30YW*WMEDpsfjo>4?DI4g3U%5|=zE|4<|X+AC@{G@I(67ffm&{qmL9>u6XN|m zdz4-rqt(BRlMB9?RF*%Hn@EwgAW&)`M`o0TgbJP&q5JiTDu961g}Ub7*&F88z7#yO9v^Aq~3|p!GGr!6}9+zAY)ZC`=H!{!qz| zuXrc8=eqW-e!0lTD#;s%4HHpeGW%JtCTBfU`sreza`Rv``}1I_LoFnFsb8H7sQJ^! zo}>;(lc|?^>3SCl{^PuZ=O%b=A2G~X?x#LD z11MyZ10f_5Lia^4F%3;+j@&b>v5(|u1xN2$f&>qo!$JpQRIMxB&X+B>(m!vB&&ky$ z?mtSpQeq>jL(H|&2JF&OUwB?{o9kfP`fF0R>%Vn+-G~>$E ztp#iu2D~~?K&6F?Ne8dB1?vTBL5B_3lJG$hP5j`uSqrnPp{H>B2G4kZC4mc79`c8l zq}!$scW!tQmpaV5uBBy3yH|2Blw433w${c&AvU#}XV{VQ58ob=V^Qpsb`GjfojIgT zJrYzu!=kulU?*bvzgi43iXWFu!%;8E&rAz+wksbXoX{Z(2NVe=>Y!u4LX(_TstyC` zcBW&d-(e8Nlku*2syHHXU{)FfNg`{j>Sa`QJb|?~t~XHc=O&SRVFgz=&N!_@#0{Jm z0;<6(Ptrou>h$+&bkrt}@B4C@^&TiScHpn2=7m;v5Elcl_GLT}g&6~t3RLHH_U&j) z{(8%=>ul171=n2_kApU97bxj&YNTs#rgte{*j{y~`Qlqk?RD~2QU_ule8^|@2aK*& zDj%{fTl9P*$32(BgDx&am+KL~a%TU@)ewldIhPZ*q{sD!8+?ivT};fE@0JGloK1b9 zvf8zS&}TtNwQGEWSr~>3vRv%hkr>H;*hCElufAhOLAR_;uJ6Z^Lijr$n56=;h)5cL z#YpSYn$)2^u!18n<6|rrK9ib$h8XLbTeQnS0A0!P2@wS=HgSIW1G z`x=gT&|}?Fjn0pGTz`6#XWMtTU|}*$=c&{YEv^kWeUHs=vM*eYmj4kOrm@+k@|&@l z`P0n#f7%3uz`8$TQ1|%NI+ubH!_*hw_79g_<#PKvD6dmh4RPG94l@Qqys;fZl1Q0m z#%kdy{(>VuL4Zp(vxW#b`xn_>X~R=ew)=ALWw-ywWGw%pa8&P`^&5(|;Gd^?aWTSc zZ;;E6VM)Ne`L>qT9E0)Fc)o?^@D^DK+yMNVd?d`wsG;kBO69*9ooe^59R9nfe%mB(L~Oq)=1^9%f5Y~2 z%7=#b`_X*8P7O8vL(wzt+nGX>vCroj`R%lL<4V0|0(5-(@JM3RSo{)}w&9?e zC#gK+VP~A~RB2XCzj-_~tlZR{MmU$=fbT@FvRyE&UInEWiGg@mKrj zg=3R*kXKlR3k8ZXuoW|~C3^aH+C#de3FE=xmt?wW0sV2xhOEJ}AqGwI7uP>Q_iw35 z-hmLKpwuZ+CWNHV3PRP4L{X5!vYTMon;EDe77i5s4uaLCLSFHH%GyEaM-G`pxDGwh zxKyt*KVy}r4lpF+1ur4gCb+uNdn2sWgCka!Lx(1&BYCQHf#%s@lY%}~uIO?N_VdkUBqpZU`)Y^8X7=7TO2zl?aAKyb z{t(=b923M|Wmg6A-(Yo%Y`7d!i#p#w{XYHB^urFTELHVJq#;F0m2iM86S&kb10vn# z&u5vV=0lu#fI739CaskEXwjP722Qd)YSJek-Kx(*h>fH4DN?coxeXWhFIvj@OUnck zj+$;WOKXZ@7~r}&^`Bq$Kox4H=N5cQl{NP_3yC8$Oh;N5AQVAm3j(e3xN`hIl+|y^ z5{dbzlBPyJ&fGJGmH~j{Yp2ha1^xrhO>Z7-*=$g&|2FUcWw8K5QKr09V>EuZas;MN zgS{hQtZGr~t5-V#h4AW#4N9$}2|`EG`uFto?xndRi}qT~W{|;A7P3pb7IO}py8Ev$ zI5Dw_{W`=WI}m2hTMr(zRyNjsudZ8bK7PETg`TTCQtxwN@6BjSbYNDjN{jb*$uLPaxqBiQIO^+%o2BbcJ@IlUuTEQd7m`XTWFA(`*jXFpQx=ccYR7H zZ#hEjydiO{xb^EnTB@CDbzXLZ_$VTCm-)!+^ol2ozUYj^xt`iKL<^tjIw=pfXnB#-kS_;wH_3vIphG^5O)?Bn!C1d4^k|fY*XbRD`6^8? zcW*eu(uo0#I>%Ns3d!<1*8@oU`K+4M7Md06eNJCSHksclrqY&R7NyNKZb1lx$&~I5 zEd*>=JbM~u9AAVWaEm^cEZeC=#Ad0CbPbwzAhEfmHAe0;4VX+FBXOidw)E}6myW|` z2f~S~r@%e3^L(=>GdzzivJTF1YFqE_Hrmu2$f|Rz*=MHG9h8yFT%hT5|hFVC7~I#OjMWKpLZiUpLZ(=7A8b{zRx!N&Lk za=eCQ-K3jPq%DB0x?LY)YOVk96gz*y^Ai7~E?Zvq122oaDu2@xd8UDphPw(k>q>dN z6#sNe^|6ldM2Rve>J=hjfoa>~y>uX_d#wf87QM!54q1XsFfolxdCWE!U|O0kTlFF( za8KY+Q-nUFPi!~8_{SDfLx^j<{rlc&U)4H{lxR{odojMb;9Qj3*aON0%3%YtS#|?Jpm(y`u6e`5VXr@tV(;26r6e8US6_cJtMvGpLy`%r=gFTXcCnpIb zu|!WiI*m%=zx8|)1l!!s;6D$+$o1{sK3*at;9$vm%HMwt$2O0}pKQ8s7a+_&SS>kt z%qV%8)f~9Q+yireJza1(92ha_UrA?*xC!!&qid~G2a7XzenMW2)Q>&S*JV#It5Hlo zBz%}nn>M(tk+{fe21X!a1LV{e+lg(<&-R&+#iQRHBW+_q2{n1n%9+mb>?J|zn*H(@ z?|dOK5;PJQSk1vp{bxX=6={L9(*B4ihZ#Mkn^A0?q)nD>@q;?Hqhj9;ai%9TNy6@ zQQQvWmSww`OpdV9iLs`$7~-tEBVt;qovLcutchUnaLvA^=ZT)EWhB!4iO+ywb+jVO z_(gAKA!WWn%S|Mcy&reqpI3eSKe+s#2F36BttXYD{Desac!t)LN3O(Wj|{o~BRe+H z~>Zt{I4a!1Dm`XFCBpxw%);t5g?oi-kEX8Uv6$#5y$AY{rT$f^4 zwRqRI`xiEJ(5!??O5BnWaz@17*_T%Q;LNaj*V$tcd!AAQVyMe{uN6wnJQqFCQBgwB zy83~q6URdzpu1n?m%20_zGoI5hk$0-;|go!SJ7RHAa)+6SWp(8?46O&p?CM@FV4A5{1JGLbh$MBOIH6MP%Ld`0m<|Jg({(~L zyZdF`Qwy@q4Td6NZOkZBgd>xnzgNd+lp^XUmXVt0?gtqnGjN z5?u&u#JK1KE1B2)TGWuDoQbkX!b}As{;F6Kj`KgVB5n zV&@{Jq6~>sT`^z5EwoM5aab_>xrV1?&tk6Hro&ZsjN-xQ`dY}`@%D8(kI`FPLU!*Y z9${)CF7AR+??mc)UMsK%26dYZC@}USyZ=6``z|Oj|8&RY>MbjZ1A;b1k9F3^NySy~ z=}VGcXSWdl)RUg>73k`@JV`u6g*aGs=2u(EO8^)l+n39Ma8@zhWBWIF!U&3s@<&S| z;+!X%9xbKRqy^Kgys8@cqD`irs^(5aPGCldt$lPsnUs2TF`JrZ#mpYv#{!euuRVj(PEVA~URJc& zxYBz8jj8<1jPi|I{Eu0+MbNwcEn#v$_-*~$T3kyo@4foND^XFS z>+BGFc5^Id;Cc!69^9-n2m2_L!Cf))*D~%#0p}tbt>+c7U2T4mnV4qXx?m;##&via zer%)bFA8A#SMq{KHyQz$S!{D&?5hIZqyAEbrsSzg9QiYU@8nr{APl{YB?XfKI#M@P z2>iAXCAjiD-@eD}fUVWo(=yj&S+V$3JJeG_LZVdEVPLWT800}EdZ`fYXhiI?X@Uww zZH$MplClYYLBk>&ZVi}w$2?z@i4(I3Y%x-DUs}i1FVL2-?Hwag4#W-`e#3UGp5I8C zr>yP_yE1&-y;Qr2RQi)d&tCon;{_{`qB05 ze-Il-J}VOdAennc#7hc+oxZ%Vs@Xy zUwgg;@H~*|4Eu3_7&iEmV2TS|0sT5Y%sxjIP}M$u;~{=;<^SCOQJXXe^bqjZFw65E zl06q@UprV;b8HSOfTH|&Q|aH{dAPw}s9;%#nEs|H%s18}a08Q6<+k@>uV9}1-~{CL ziD8xfmjG-|{|Mlfc(UuyZ_S>PilwW&|17lqNj1=!m^HK3w&lv{$y#oO#FIY=hjVw8 z9fa=hf|v)|Y~EMD(GUPgBetfiMX1^x_%JOB|K>3@9{OSX7B=~nsU zN{oC3bc_Iq`AJcL1DLR-{o>_jcS#FYW4N4QD?#!X3#gV=}UKdS%CbJZ%&Sc_M0l%lt*8@~JYWRS+kLN|5 zpWo}581W7K9DWI6PTN)lH_#IW{YYPODNLrmf<-Zwj(_~~?e9+b&2u;B{fVAZ2Y+VL zgs$2JQOn&w=veAq@G2g-ibp+$1~^-A*IfLmi4;gL;HbF0CvhTB1~0yK0}_3sGLccP pL=dpMM9*QcV|h+Uy5l1e){A4-M^p#!mLVhEuOIkh7U89PE@NOBm5kwkJ#;}C<{ zC^-xhGGoY080Yg0V;shOkKV-ou6JMW^?rYSf6O)4b6@wp?zMhvt>14wGfzyf8VdX( z_6rvmm%ycq7tFZ0w&`mP24lcXOPmw3db3p&^QY^TyD;tqAe8%8`YouV>an$Mm`bssRh zoqFx#r2GMKyZBeZMtf!7X`eg}xy%w1ZE4tcdiPs5p(7dk*cW_!?{pkuiNPOhw@F_= zQZyvq@aLmqn?mKR)EYMv!Wf!7-Hw{pCafYBo_}Gqp;}bDC=8=Td|OEyj^PnkvN|g# zPRd7?xN7H|rW7;F!cAU(nm3z^-JTbmayQdZ@KBWM%4jW_%wAz?DQjst-V(sx?XO#_ zkZHwTKb&<7J%8(}$5#+G_26ea3LeE9;c_E!*w^g_#!(64(xy7?Ya$j8tF3E?DqJOK zJpi2&d2mS9??VdXRpC*QZN8O_GJPo;o#&O16YXOat>u%Ig9*+tN6oyl|G))woLg+e z3bc1>s(U2cltqlx1%Lz3Vg7jF(b??rwR0?1W8wU8^I&3kIbQDg!XS2Fpa^q8oLs0EP{&u!4sIagajTfTDU+Qio--xMh? zlCPG#DDt{QO(7ELT85Vk-Jam&VNITf%=GL*b1}~E=xyoL92lr@9Ii!rR8L&aZ{h8o zTXzW^_@VKXQx|lXGAu(F@Fr72<&+w{(&@RRSN21|kBp%)x&A1%{&wi@IG3*|f)=sC z*5;{vVTlp!d~VFS^4^JDfAwn~u4gES)48;^9B(ah8E@uZ;N~Nk z{hsj2_?w!)l;xn)2*eL<1&azyv8P|BbEVzYP7s0vG%V3W$>rl?uG9Ph$Nh|BPeUp! zIvDQ+NZYZCV#j4>)}|MIzE*cS_eKXidl?JeCZRDOC=y)LtUXrkr0;*r~m}^fA{?o z*IUJveZYNWXl$BG zlMizsCnu>PzQu^-U3dWMg(Ypol*4MYY;D3Q-mDwcm}|=V#N_RTiaR+DCQlLc>!UqP z$^yFTr{YJ)znH^)PJvh{D>uoc&Xo+e=hM|QI>5DM*y#$d6&r){pnw1~RsWglMJK_- z>YVJz9Bbxt#pd+iZKUI-QX?~i9mFgO3N4llnmi2J9!wXj7xwTh^^Un(x93{iZlRGi z1v)w$(_)Ht2X*N44;3tjfF04fIqzMDi}3}=#`&>qOXdy168Dv8 zOXn7iB8TypfTU^PuNJq*)<^>?%hJseR z3>#JM#ZzvMpI~TcHF=R5zREYsIh7ZnnbnSMq2qiHA%>08Kzjpe+1gwc|iY8pd)?HBO%>J-%>QxZ;#X?A-YXLoI<+6E~!TkEGF<|J77t- zCa-i#6DuTU*^BeS#X>IZ${6pek{v@i4I3{EC2{0iqaRiGWrZ@Z#^b710aZPv0%gJXiD)BGr--@e-Cp@n~JsGH%; zehQfGWps3y6buFISJnQbFYDJt8zzbnNI6H^yRj|KL=x=H$|?1U30CJUCiq|j9p*k6 zkfM>)`OuUC?u15_KmC7g!(=rrmh-#r`S2Qh_HFhe{B!MO>J)2wdnWu0jq|8nhT>;1!-8G42uz<61b1g7rb;C7q=MtCaQ>3lH3p zSkyktrssh%BGaO_50*mXz{LwMzm%VS2IHb+B*A>H4e|C|96?D%zpJr#>edWUT!F@r z5`zA4S{g|Rc34y_x=$WT44T!GR2G-S`rt=B!K~V%2U9^cbFJ23daP@d2kQfJtTy(0 zcJLU*H}5RTYU6MxOEoV3^KueiEe?+$3*;Svg;#+pfyHj_?{rn7>_HD;rA5kqIIO! z=3j%S(zKkJ9R>_6GjgLR9he<^z-mF%=|D2>qMiZm;Q8vOFwp?6Sru#j%)6SfK$m+6s4j0%jfP8zn6AiZ5uuU-%nxw*Jj zU#nq)JaW#_7jQMRgA)dZ4MhvZXWUV*yK|lSa6NTJq&v{pX|j!&I8sb>ql$aKg*9uz zDxOA;l$1Oi3j;Qk%}$h_YQiLX9QgY)Sn1qRLP@Bddq2swf`Ac4+&dSj+=wwxKeV~; z&(4{0K6&01bo`5mLM~r70fnOY*n@(8J zZc&@}^ktOwiZd;@%j>q$Pw&R0f&vy)Ag+t?Q_T1jT(?KioFfyecl|J&h!P4QrY!yL z@(Mx~%=pBt9DDWdtcGphUQ;+at5VBq*DI25@4ca18A5L0)y~{*&usYNUf(#_*t)|c zZR_Ibe3ck-si;rT`@Xf=SbT*Zq#7|Bd4=cuGx7&Mw&nD! zr7LMt>OG#UhIC;MJi&m&FkY}KJWF_{XJ}KHGP?#XQdGGt z$VZ=?1Vdhj2EEVdqkz(`HH7Fzo1gLF<%cdzr|ZXMHzx*kjT~HoO{NQ&EYQfiX3}}W zpWh*1wAbA@NFyt(RVd4GW`^tstZ&>urgHCMt_I-)Ns|H|WMldxK;p@CyC`Bhj9rgE zsdcsyW4Cq%vh02L?c5d8ec?qLcZr796|;DIU}LVX?}M6H!kIl+Xyn=FSkdgz7#6QWOM-z`Q|>El&@;z2=LC1YRhluL=6LS4y{*T)2JZK^pw}Qtd5i zx?8tc8mPt9_LJd_<{@Y-5T@O+MhwX_*T66sXS|G+4xOks1z<8R^;CdRIR*)?UF`VD zIBRya3$TjxMu;QL(4oI@9+iZc&m5=c-vqLzAWS2B5~HJm;_iW5L3f>8y~BsI&2vTz z3#w$!^Mrr`2Kh3j=|r^=R%f0%f_p{a1Ll+`kS# z0|l&54Gn3ive`VjRsVtnXi%&*>NkK6avVzKQ`hEAZxa`ZC+94JmPCiCeA4x@ukDcK z2HRKfgxD3mIY}6>HV+5I?ZowbBe^!JBtC`FzgdW{`U}8^_tK3dzVDJE+|Wfgh1j{z zPN>mPR~l8|vv~rD>M)SkZukj7L}_gi2`I0fMf^2;mLfUMq?HIzXV@Bv7uOTzgtoyk zdSk3U65=d3WJl#bz&0qS7dv3Cg(_D|v~KcTqIIK6takwt`KDdw9; zgq#evY)gjS24|-Oybsg`ut^CQN_Rutad@k!0wiTUqIJJwK@-dOo(e}u_#N9^tRRH& zANc{2`-jzM{~iN9v_=@>^Sbf%LjLqw@VhJi#x1ngx3?vf0XcNeap2&UhLtwT|G%~c zG{u2soh`}YZ+NIyKs;V9|M7J)A7bZrTQhND8@pn=@o+~V4;_er`Pq(w#1gCZ zdDj11J|{%hiapGmeF-6*r=)i;in_eo@Th!bvgh;%VxBG>NR&){^V(%Kc(!pO^=@sk zX0_>x<{0Pw-1e}N9<@f#yDCiuk9=>P%uZpfCcBO@HJ|g;Tw-V(dtY&dn6Jd)uP^NJ zhphPx))9++0^IJj7cL3`rpl?QJTEL)G)FnJVR*>?s#l|0srhw3lm zR;p&7_l+<=_H}@8QpCQyhSF?iuI39Jg!u?hN*8M(H5e|^V2KaYVpgyL>WiD}?aByT zc?-N4uL-J~k9ZdeDE;ej*o&SOABBh$O9Bc9I@Ow`TIW)@_Bo*FF`A&4MH9=TI+Y#YRa&0*AszvRMMW_vPcN z?JXV`SPW6Yk&9gs(^)`W(^$sKr0KfZsH;*3MNO+X<|8yS=g)tswt6bQpD;MwSv7Lz z=pn1SZU@B%&OEU4x=5|s2P9O7kw0tg40Hh;F{o}_>ixK{x_TM>wQY)1_r-Lh>Ynp&{M=kYhkwXDv2lpSfFAEVv%SJ$6{y;m>^` zI*UGPRrl}R_V$~*_DP)H_KPCSml{@@fA+NoB2)Zua(hw(OU?SXqW+I&gQ@LRONWH` zTk`Bc04f=5%%~P-M~&pG?*{!@$R71lF8yPCAyWReDJ0I=AK6Z7Ud!kFiH^#?-(I>z zQAb7O%tXB|IHubznz&!|TFow&9}p^Dxbx>AatKJyI!)#wlkB$8(Lc1}*7k8hRUItD z>xBVqDFB&F*JuD`&k>#f{6E=}+Co}1)KA{bzJdN|S7OKdM2Ol#h$jdlWznTF#DerA zgyo;q_K|U#1syMb^YNxA5;P&OLAU!`F|!vPXJxx+(4Y-E&bCDJ7>W(1XPqD{|D(b-!Z zM3np+!Tc1V&8WQ5@xp*ut;>PB1EOh@>9)fAPmp{UD#3%gyQEaF6$cF;U?eqIXLA3a zZ2f~QCF{Zy*p~?RJDEwgTZp|MB+C$20$zSL;!XVbs+O!n0gIsa3wx4bQvw0X3tKSt{S#!JdI-kJm-#7_N7mDy)gkN8iNd{} z=GjQfelnQPxAEM5t&RgvHtz_j3c7xIQ^K~2w5jag!Vt%+N$+io9i+S%2Gkg=BF38O&#BaLIjVwhwDd){0%{tIC==dJiP_h zNE-C5m%4gs(i_pen_DAkWPBwc9qh1TR)I?W2U@UN_UkPTq)IUJM2F5~32U!j{Mr4~ zx)m6}x1HifFA7qw^3Jc1Q$MO|XEP?Wz>x+O{MkT2rB`a_OHQT>2l8#ns6HKk?ymzi zX$@5K#XmP%C}Ie@D&s7>e~-%gw6;Db0je$1ig~F2^X~tL%yS+cild-HsSJGRMj*UE zg#~Fk)uWBHEH+E(@DTz_i-7n!tc-#9eA~XyQVN@`QtpP9yBf_{`NDqjWA;ma23N1n zV9Dql-LmT%I#d%jXgxCJ58kqBgpQ|bY#p(lfO;{M5773QF`2*hCm$!*e|=skI`KE4 zYkk_b(&sqiNXV8M?!PPDPGz`?8!DV1_-#Tgw;Svg1veTjXy^Jd5B_(ywzk36ajzZ3 zhqDU`RR;fV{If!+x^N=fQAuT@`GVMHVFHD|KBZJ6PQ1aJ81LuEscs3J0-l(BN}eOy zZRSdjwFdQzD%Mh}5OROc%DA&-HyhM=`4vxoN?F^u%$DV5%&Y+BY{N_U=rhdVjY0rK z;m2%NY>uLsK2X@w0zCB7DYo`?v9OAt6%jj#WJ;#q=VNFk7FD#2eN>yaqiQRu+NP*7wzi6*V&4*k+7fG(GHRFvLe&~7DLSEuEn;8pi(%$|e)qThaX=o|3mnA1)Dn@mjaF z$LUi1H_{v0#w`Y{YGC~WffBBt+j#O~#WxBwECkdsr^p4|raQrfooKV3f~0O}|ZSvo5DT2>XU|4EmCliBc=@Q_z(@PSIUd1jQ>$V)C{0?=fhmDch2&*){_cM)!Nd9tGCS89)DRL_!ZKGh;SI73Pp$!;L9TTQ8ovu!G4n>8c` zSq<8HIpK3F(2@GXWxh6rQ^8Hkc#9Ar6k)ak^x)1bd>DR2Cb6P$h?hOBmE$(UpMcPwu4EA9Mh@xz*=JTxhhV5uI-BGSB%u zS(tMukB~rgn;$hxxWTt7jEGMi%gWg^DCmVuW9V;=5oNz!g6`cZ=X2EsOonF}{x#Efu*NWw`d61lTN>GCepuDD-C zju(`(O2~2g1oH`bm+=S6x_<7(_tM&2Eb(FCpGxqCsm8vr`Ki3fdtILloQ4>YJpr)i zm@?Ozg$=M}NK-6`G8||Zm|_N+8LC!$c*UDVN0ubzZ*sfE$+xVjZXh;2({&_ai4P52 zCStL;j)4zI-!;s|>wGJ*=oh&7N-NJ)kd?Z%HJuAX*-@$&t7xqSH$NE;Ny1`z?q&Dp z#|mca6O?9Th&M_nxCpw?bpKLMySIu9?J)QYo6hRFT9|qNrpv)u;zAS!x6Z;(ML9Hf zdc3zj*w+Om2Rn^(gr8Q&<;cjqpNYygxyWa;u@?&Dcq0eOsKrnujBKEnN?dE>0KfrB-v9gPl0W* zRSv%*M+m7dm$Z?CHVPKJ z5#XC#0zA4YpCmpes%@=Fm6L0?*3eewFZmnu6ld-{DIGXD2fCzg*VcTj z=79LoT? zQ=Z#1r15y=<>t6N6_8`o=MvEIuQ+M8*Yn~+Oib5ly7att0&(CKf!an9GGhi5YaM{}&q z0230X^GE1PUrr3FRn5Kr4~cd6|NQr0u)0#}BjqH;hfL5qv4Urlx$U?ZSiWU8L~ z`u!E98LIqJZ=uaxlbYgteXv*?vbypX!7D%{xc6R6TOOrmc}OtVu#SF_ zr`X2boM#Gy4WSQ%`mqBsPl+GSnnL>45%2(I5dzz-(<-|55%wJ4?h-710aI?&(Bc9l zTbx_9`@g1nb;%Fwrd)*yyH$905VN!GoHB!!CkIhFfx${ZKt5JXzKmY-zhHrTzwp+M z>v)BrlHZ(e$Sc$9D83(aJiA*}wXi=KZqKg^I+B#wt$x_9XYH(_bq1&|CeZb2mt*1R z1l&g5@BbuA`w~vKvOz9bG!2Dad%D?FOKXCW)07g(A(isGW)w9IWIaH zj(Aay`ps7CyuX<76^dHe%^ywbg;$i%XaTYCC2ec+w0mldGCLDfUysaOn-P4MSxysl zkBimvpjW1un7%~Ug*A=Q>DRw6bRF~EyRbiAT-1quq;-7N;wpn zS>ug(f-Kdj8S0ju^UC}_!x}=ngY_)|5bDsxL&z7N>WfQ8TCIMaKSqZ}`j?J3;rJ}Q z@18ZJ6Qm59;Ve{@?Yz+w)V@;;Xlo==3OBDlVQ5!Uy;DEB3h2ovCHkkpK$PFw;vepr zuX9G&=^3jfD-VlkV_Z!U)ddUf<0M?9Lcz(YnRn3fy8#9{W+*>uH&NoH|4|dy)Uu2B zc{3TWArG-hWn*g${S@V*NA#@TlBuyK91wc1)oX4vN7PDA*LtT)w3ZgH+v?(n4=HNy zbH86_vmyHoPq@2t7V6I$*KQL9`>z){7OBYAc;={GK!V{DEwS6R337LpecQ-@T|7KI zg&CkiK)>2e#V*Bnc$~bHs#n)oLP87cy#NVfV`@2rdf)OW3;JP7Z{ggPS4jO{D@vC1 z-0CX#MMFCma1*X>6GwT7v$3~ts_Di%3_VgyV*UCL$?Gq3|kkC}PUBU&v=h=RB0!T8wj?iM;SRhgFBoXbpAVMuL1T59aj z(o)bXyKTb4Dx_dZM&I$|^(9X4q)2ZQJ5p2R;XeG{bl>hmoj^xxGG#NroUlDtIck-} zo6UMpPNMw?#&k2i%@YzwH^GD|!2JNp7lA@dt6OV#dZNK$RdZgZ!i!Kc6_Nfv;m0tf zg#H8JOt&w^9L6n?$kugPxFPVs1n|H}T|oQ&OQg%N%}*STOZh1v*8FyL%)m-rt4f_* zwgdcLtt0=Wz80GcWG?cBo-~$zE!8fEXrT%CqWTy$h;dR)@pNE+G4i*0#96cBbkIV; z_r2A~um{HZh2Ql^74EcbtE0eCpDEX39gEYDY|w%8!Pt6SUEL$Z7zxLg!7MX(B*MQ` z&VwphXqmVw4788SEq@~2=?h`l?+Cp%xbM%b$aWxuYp*Fc;P#SB2EIml$4IEh!M9rv z(xw#`9RvDh7-brFT78ilwL*yMx-TrAjh9~F4B7FccFAcpMPGzGD~mWf)rZ%piIs_` z#%34^6C^kp&@d$I1T_grz6M z0W=3f$d~D0R%9v-=aj}O18tTleLK;i4bp&9sozsnl~8TJup#+(sW#-Ombv1;i-|{4 zU}myXqZ3F;USVzh4)y~BgzU&G50c-WLzxPa(L;BzUIMx@SlIqeeDpY5$jZk&U>k5p zFiMuAKprb5U>vz;x)7F{ba6E_!W!ZRc*&3|Z@zR|Tzn11cSS}0xR^-{k`l1kD`D&e zU8(ICxP$qEEjm5^xnFB~4vf^hc*~;cI|g(-3laiEuBSn zLxETWMn1!U(b*W&n3%VN*WBVK04Cnw7trOc>ngI(vL+Yqo2^Pvs-4_QzQE@2Ncgs3 z)la#*2Un%xUfrx$ba}N`^UIPjoTTx}Lv6IY79xQN>#a_g8Vkk`jave>0D#q-0YyAc z6o{-!kn_M_*Actp&68(d6p4ahtcN-fskR+2kcuTP#vw!Uhl244FG7*M0k@SkCVSF` zm5|TD0CeeeiHVQ5*pJ^-Uxa^p&x0cS#=p5oh+uJI&!w?^bOY^AtcWJm~)_=6vud zwf~%cm75Ob!Gc>es2Itm>4nin;|1%w%o2yr5e{yt~PKWjj|1D9F2Aq`*Eq>7zXwaK(T=f*OE zd&p3U7n|$-)!&UXf`|GJFHUzHxp4K5RSo+O0`#hIz&Dx5TyWvn-{(fYUp6T1#q|D0 zBHeX>nsU)WD^JUT+1t;L4fF{gjciSMkW4VV^!XQ`VOq@y5J8rH~@D+2*VS7kK2W(T5v=5eS(!;s@&ER zGM-ARii4fk;I<|rsDTTBBgUxd<~&xT28H9!8hn%YH7?aHg+8vwoai$LPdG;U#aH$} zFO{gDF;Hct`mh1FH>Z~SxR!HJY^IN-3w+{sY!7j}AZQ*vc7=|gK)?T@rH5T;{U99g zA!QA*atlPIz&K66OaC1}7eHibGPy@4@9*X}!NT;PE%sC2h#eTsc=~Zk*1<*H{T@H< z<(V}6!U28!2{=^wzg}!5DBE>@X`Id{K28PSaN!@Y>2N|R$+u>V>NNYO%M+d=!&;q< zx{>E(5&(x;EI)K;Fpe}WFsnXE_qBPWB!54%0H;2dUWW|Jby3spXfXc3$KwL@A{Vea zTo0eww!HpkO^Qa+4?xsO!Ra(Q6^u!E#8Dm2GA6E2z(rjG-}!cS*u<$tMr*P1-b9*}E3rElIlGczb%n*R$jabs}{x&^N| z3S8TQdx}-T1<^iy7|QEcpwc=&`av6G8)82vIoUeO&{;4iGVukU#g^P>>78tPuVOjr z3T&z1imwh6CsC+!C2y!+n#)3j()h2k@F}ubnXSaqRV?;~D#5~oD0l@?daUs7&>4oC`F}BpG3VyR%_&zG4m(7{6Zrt(<6q_RDDAG z4}&ARM0z-IYA>=Hlf92$UC@xh8^cD@Fv4UNs<}pgAycu^`+Ren03ryels-=lI9yK1 zJChgOvHMvTC zk3au$fsn;^zl=oL9v2Hoy`vT!qbJ7h6>fmgfQBa20ARL#4gQk_E&eON7YiSNW|j`z zx5Vu7!ZwrhC{qlgMsbJi=2*#kZ~Chg!AkB#XY*YoRm*i3`2=Rj0a)TcPcP%G z6n-Y+Z4m*6?(|6m#<$d<^Oe%Y9pe1Y+4dO?>Z!;C>IuJ>}(0o_yudhY;G! z{0p7NCbO=S3qWYN87%91ie=9cBWN(9s@McO`)I2i846TB8}it|tK(e}kl7L(4LJFN z;rON;g|I|}m)xg*tv%JCImG@eGK?9XCsETHhAe$QrJpyz3%_o23a0$Xq2F>$AXZKD z9+nnh3o+emYy6_G0V(P#|PxtNXD9Wh8I$YD!^ zW9N!QW#hkOrR#zLy26CYVto)|$}=6{%a49D;>a@U(e3=7s^4uk!t}{Ks@4+ymY)62 zS08}ABBLyv-=gBbVa*Kip;iV&X3xZ&+NS;x;2_Y8GHyi5QSTqwD}`am>68CtG2VvL ziWaeb22?*=V4&qD7%B`2oB}H5l+P)E$!-`6PW7?S`_KNz3&-aK!30ID*#w8nhgvpQw!g^z zg&n&Nc~E=k#?4LKG9#jit&UH{6ae0zmS30ie@CTVdDLOKDtyqC|7@9fPPtLK2s+-~ zuN4(-bZ9OK##x>wcxP&{=|F0aGp_<1VGZVXhhefgkOy;wg*OpXJ2n5cYD~iFpf+9( zOas$MA6rmho;`Q~p~tK<0m)u(w>MM)@D9KMu8j{@(JgCHE2kX)-Ge~mL^ z?>#$SkaR3LF5!-Y23~!L*vGmJ`Bt|6?hjTzk{%1c$KJLRU;FDJ=IChjO79XrX`zX2 zRG)x3y5Fd_;_QGCFtOs)aB8U|v7rslzyseA{akfBQY zlOz5rQHQNB(524DDAL&u@O4cK!*j?O+^7NbOcO3UvNoeBbgfNmZ!8AJx(3|8Z<_wG zjbe{MHg#CN?lR)V)281&q5^IkKK042PVCT01T&PoGN}yr&^~1e?)Rz4nvKV;jZYgwV z_7V)DI{a~;1|6RhH` u4BtSRJ9O>87$*L=ivN$;6#{yP^ Date: Sat, 18 May 2013 15:56:43 +0100 Subject: [PATCH 077/467] documentation markdown --- Documentation/markdown/Overview/08-Recipes.md | 1187 ++++++++++ Documentation/markdown/Overview/developer.md | 2102 ++--------------- .../Overview/images/08-cell-comment.png | Bin 0 -> 31473 bytes .../Overview/images/08-column-width.png | Bin 0 -> 14985 bytes .../Overview/images/08-page-setup-margins.png | Bin 0 -> 125173 bytes .../images/08-page-setup-scaling-options.png | Bin 0 -> 24136 bytes .../images/08-styling-border-options.png | Bin 0 -> 18878 bytes .../images/09-command-line-calculation.png | Bin 0 -> 44332 bytes .../Overview/images/09-formula-in-cell-1.png | Bin 0 -> 26053 bytes .../Overview/images/09-formula-in-cell-2.png | Bin 0 -> 34014 bytes 10 files changed, 1403 insertions(+), 1886 deletions(-) create mode 100644 Documentation/markdown/Overview/08-Recipes.md create mode 100644 Documentation/markdown/Overview/images/08-cell-comment.png create mode 100644 Documentation/markdown/Overview/images/08-column-width.png create mode 100644 Documentation/markdown/Overview/images/08-page-setup-margins.png create mode 100644 Documentation/markdown/Overview/images/08-page-setup-scaling-options.png create mode 100644 Documentation/markdown/Overview/images/08-styling-border-options.png create mode 100644 Documentation/markdown/Overview/images/09-command-line-calculation.png create mode 100644 Documentation/markdown/Overview/images/09-formula-in-cell-1.png create mode 100644 Documentation/markdown/Overview/images/09-formula-in-cell-2.png diff --git a/Documentation/markdown/Overview/08-Recipes.md b/Documentation/markdown/Overview/08-Recipes.md new file mode 100644 index 000000000..d7a3db388 --- /dev/null +++ b/Documentation/markdown/Overview/08-Recipes.md @@ -0,0 +1,1187 @@ +# PHPExcel Developer Documentation + +## PHPExcel recipes + +The following pages offer you some widely-used PHPExcel recipes. Please note that these do NOT offer complete documentation on specific PHPExcel API functions, but just a bump to get you started. If you need specific API functions, please refer to the API documentation. + +For example, REF _Ref191885321 \w \h 4.4.7 REF _Ref191885321 \h Setting a worksheet's page orientation and size covers setting a page orientation to A4. Other paper formats, like US Letter, are not covered in this document, but in the PHPExcel API documentation. + +### Setting a spreadsheet's metadata + +PHPExcel allows an easy way to set a spreadsheet's metadata, using document property accessors. Spreadsheet metadata can be useful for finding a specific document in a file repository or a document management system. For example Microsoft Sharepoint uses document metadata to search for a specific document in its document lists. + +Setting spreadsheet metadata is done as follows: + +```php +$objPHPExcel->getProperties() + ->setCreator("Maarten Balliauw") + ->setLastModifiedBy("Maarten Balliauw"); + ->setTitle("Office 2007 XLSX Test Document") + ->setSubject("Office 2007 XLSX Test Document") + ->setDescription( + "Test document for Office 2007 XLSX, generated using PHP classes." + ) + ->setKeywords("office 2007 openxml php") + ->setCategory("Test result file"); +``` + +### Setting a spreadsheet's active sheet + +The following line of code sets the active sheet index to the first sheet: + +```php +$objPHPExcel->setActiveSheetIndex(0); +``` + +You can also set the active sheet by its name/title + +```php +$objPHPExcel->setActiveSheetIndexByName('DataSheet') +``` + +will change the currently active sheet to the worksheet called "DataSheet". + +### Write a date or time into a cell + +In Excel, dates and Times are stored as numeric values counting the number of days elapsed since 1900-01-01. For example, the date '2008-12-31' is represented as 39813. You can verify this in Microsoft Office Excel by entering that date in a cell and afterwards changing the number format to 'General' so the true numeric value is revealed. Likewise, '3:15 AM' is represented as 0.135417. + +PHPExcel works with UST (Universal Standard Time) date and Time values, but does no internal conversions; so it is up to the developer to ensure that values passed to the date/time conversion functions are UST. + +Writing a date value in a cell consists of 2 lines of code. Select the method that suits you the best. Here are some examples: + +```php +/* PHPExcel_Cell_AdvanceValueBinder required for this sample */ +require_once 'PHPExcel/Cell/AdvancedValueBinder.php'; + +// MySQL-like timestamp '2008-12-31' or date string +PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); + +$objPHPExcel->getActiveSheet() + ->setCellValue('D1', '2008-12-31'); + +$objPHPExcel->getActiveSheet()->getStyle('D1') + ->getNumberFormat() + ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH); + +// PHP-time (Unix time) +$time = gmmktime(0,0,0,12,31,2008); // int(1230681600) +$objPHPExcel->getActiveSheet() + ->setCellValue('D1', PHPExcel_Shared_Date::PHPToExcel($time)); +$objPHPExcel->getActiveSheet()->getStyle('D1') + ->getNumberFormat() + ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH); + +// Excel-date/time +$objPHPExcel->getActiveSheet()->setCellValue('D1', 39813) +$objPHPExcel->getActiveSheet()->getStyle('D1') + ->getNumberFormat() + ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH); +``` + +The above methods for entering a date all yield the same result. PHPExcel_Style_NumberFormat provides a lot of pre-defined date formats. + +The PHPExcel_Shared_Date::PHPToExcel() method will also work with a PHP DateTime object. + +Similarly, times (or date and time values) can be entered in the same fashion: just remember to use an appropriate format code. + +__Notes:__ + +See section "Using value binders to facilitate data entry" to learn more about the AdvancedValueBinder used in the first example. +In previous versions of PHPExcel up to and including 1.6.6, when a cell had a date-like number format code, it was possible to enter a date directly using an integer PHP-time without converting to Excel date format. Starting with PHPExcel 1.6.7 this is no longer supported. +Excel can also operate in a 1904-based calendar (default for workbooks saved on Mac). Normally, you do not have to worry about this when using PHPExcel.### Write a formula into a cell + +Inside the Excel file, formulas are always stored as they would appear in an English version of Microsoft Office Excel, and PHPExcel handles all formulae internally in this format. This means that the following rules hold: + + - Decimal separator is '.' (period) + - Function argument separator is ',' (comma) + - Matrix row separator is ';' (semicolon) + - English function names must be used + +This is regardless of which language version of Microsoft Office Excel may have been used to create the Excel file. + +When the final workbook is opened by the user, Microsoft Office Excel will take care of displaying the formula according the applications language. Translation is taken care of by the application! + +The following line of code writes the formula '=IF(C4>500,"profit","loss")'� into the cell B8. Note that the formula must start with "=" to make PHPExcel recognise this as a formula. + +```php +$objPHPExcel->getActiveSheet()->setCellValue('B8','=IF(C4>500,"profit","loss")'); +``` + +If you want to write a string beginning with an "="� character to a cell, then you should use the setCellValueExplicit() method. + +```php +$objPHPExcel->getActiveSheet() + ->setCellValueExplicit( + 'B8', + '=IF(C4>500,"profit","loss")', + PHPExcel_Cell_DataType::TYPE_STRING + ); +``` + +A cell's formula can be read again using the following line of code: + +```php +$formula = $objPHPExcel->getActiveSheet()->getCell('B8')->getValue(); +``` + +If you need the calculated value of a cell, use the following code. This is further explained in REF _Ref191885372 \w \h \* MERGEFORMAT 4.4.35. + +```php +$value = $objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue(); +``` + +### Locale Settings for Formulae + +Some localisation elements have been included in PHPExcel. You can set a locale by changing the settings. To set the locale to Russian you would use: + +```php +$locale = 'ru'; +$validLocale = PHPExcel_Settings::setLocale($locale); +if (!$validLocale) { + echo 'Unable to set locale to '.$locale." - reverting to en_us
\n"; +} +``` + +If Russian language files aren't available, the `setLocale()` method will return an error, and English settings will be used throughout. + +Once you have set a locale, you can translate a formula from its internal English coding. + +```php +$formula = $objPHPExcel->getActiveSheet()->getCell('B8')->getValue(); +$translatedFormula = PHPExcel_Calculation::getInstance()->_translateFormulaToLocale($formula); +``` + +You can also create a formula using the function names and argument separators appropriate to the defined locale; then translate it to English before setting the cell value: + +```php +$formula = '=????360(????(2010;2;5);????(2010;12;31);??????)'; +$internalFormula = PHPExcel_Calculation::getInstance()->translateFormulaToEnglish($formula); +$objPHPExcel->getActiveSheet()->setCellValue('B8',$internalFormula); +``` + +Currently, formula translation only translates the function names, the constants TRUE and FALSE, and the function argument separators. + +At present, the following locale settings are supported: + + Language | | Locale Code + ---------------------|----------------------|------------- + Czech | Ce�tina | cs + Danish | Dansk | da + German | Deutsch | de + Spanish | Espa�ol | es + Finnish | Suomi | fi + French | Fran�ais | fr + Hungarian | Magyar | hu + Italian | Italiano | it + Dutch | Nederlands | nl + Norwegian | Norsk | no + Polish | Jezyk polski | pl + Portuguese | Portugu�s | pt + Brazilian Portuguese | Portugu�s Brasileiro | pt_br + Russian | ??????? ???? | ru + Swedish | Svenska | sv + Turkish | T�rk�e | tr + +### Write a newline character "\n" in a cell (ALT+"Enter") + +In Microsoft Office Excel you get a line break in a cell by hitting ALT+"Enter". When you do that, it automatically turns on "wrap text" for the cell. + +Here is how to achieve this in PHPExcel: + +```php +$objPHPExcel->getActiveSheet()->getCell('A1')->setValue("hello\nworld"); +$objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setWrapText(true); +``` + +__Tip__ + +Read more about formatting cells using getStyle() elsewhere.__Tip__ + +AdvancedValuebinder.php automatically turns on "wrap text" for the cell when it sees a newline character in a string that you are inserting in a cell. Just like Microsoft Office Excel. Try this: + +```php +require_once 'PHPExcel/Cell/AdvancedValueBinder.php'; +PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); + +$objPHPExcel->getActiveSheet()->getCell('A1')->setValue("hello\nworld"); +``` + +Read more about AdvancedValueBinder.php elsewhere. + +### Explicitly set a cell's datatype + +You can set a cell's datatype explicitly by using the cell's setValueExplicit method, or the setCellValueExplicit method of a worksheet. Here's an example: + +```php +$objPHPExcel->getActiveSheet()->getCell('A1') + ->setValueExplicit( + '25', + PHPExcel_Cell_DataType::TYPE_NUMERIC + ); +``` + +### Change a cell into a clickable URL + +You can make a cell a clickable URL by setting its hyperlink property: + +```php +$objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net'); +$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl('http://www.phpexcel.net/'); +``` + +If you want to make a hyperlink to another worksheet/cell, use the following code: + +```php +$objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net'); +$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl("sheet://'Sheetname'!A1"); +``` + +### Setting Printer Options for Excel files + +#### Setting a worksheet's page orientation and size + +Setting a worksheet's page orientation and size can be done using the following lines of code: + +```php +$objPHPExcel->getActiveSheet()->getPageSetup() + ->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); +$objPHPExcel->getActiveSheet()->getPageSetup() + ->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4); +``` + +Note that there are additional page settings available. Please refer to the API documentation for all possible options. + +#### Page Setup: Scaling options + +The page setup scaling options in PHPExcel relate directly to the scaling options in the "Page Setup" dialog as shown in the illustration. + +Default values in PHPExcel correspond to default values in MS Office Excel as shown in illustration + +![08-page-setup-scaling-options.png](./images/08-page-setup-scaling-options.png "") + + method | initial value | calling method will trigger | Note + --------------------|:-------------:|-----------------------------|------ + setFitToPage(...) | FALSE | - | + setScale(...) | 100 | setFitToPage(FALSE) | + setFitToWidth(...) | 1 | setFitToPage(TRUE) | value 0 means do-not-fit-to-width + setFitToHeight(...) | 1 | setFitToPage(TRUE) | value 0 means do-not-fit-to-height + +##### Example + +Here is how to fit to 1 page wide by infinite pages tall: + +```php +$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToWidth(1); +$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToHeight(0); +``` + +As you can see, it is not necessary to call setFitToPage(TRUE) since setFitToWidth(...) and setFitToHeight(...) triggers this. + +If you use setFitToWidth() you should in general also specify setFitToHeight() explicitly like in the example. Be careful relying on the initial values. This is especially true if you are upgrading from PHPExcel 1.7.0 to 1.7.1 where the default values for fit-to-height and fit-to-width changed from 0 to 1. + +#### Page margins + +To set page margins for a worksheet, use this code: + +```php +$objPHPExcel->getActiveSheet()->getPageMargins()->setTop(1); +$objPHPExcel->getActiveSheet()->getPageMargins()->setRight(0.75); +$objPHPExcel->getActiveSheet()->getPageMargins()->setLeft(0.75); +$objPHPExcel->getActiveSheet()->getPageMargins()->setBottom(1); +``` + +Note that the margin values are specified in inches. + +![08-page-setup-margins.png](./images/08-page-setup-margins.png "") + +#### Center a page horizontally/vertically + +To center a page horizontally/vertically, you can use the following code: + +```php +$objPHPExcel->getActiveSheet()->getPageSetup()->setHorizontalCentered(true); +$objPHPExcel->getActiveSheet()->getPageSetup()->setVerticalCentered(false); +``` + +#### Setting the print header and footer of a worksheet + +Setting a worksheet's print header and footer can be done using the following lines of code: + +```php +$objPHPExcel->getActiveSheet()->getHeaderFooter() + ->setOddHeader('&C&HPlease treat this document as confidential!'); +$objPHPExcel->getActiveSheet()->getHeaderFooter() + ->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N'); +``` + +Substitution and formatting codes (starting with &) can be used inside headers and footers. There is no required order in which these codes must appear. + +The first occurrence of the following codes turns the formatting ON, the second occurrence turns it OFF again: + + - Strikethrough + - Superscript + - Subscript + +Superscript and subscript cannot both be ON at same time. Whichever comes first wins and the other is ignored, while the first is ON. + +The following codes are supported by Excel2007: + +Code | Meaning +-----------------------|----------- +&L | Code for "left section" (there are three header / footer locations, "left", "center", and "right"). When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the left section. +&P | Code for "current page #" +&N | Code for "total pages" +&font size | Code for "text font size", where font size is a font size in points. +&K | Code for "text font color" - RGB Color is specified as RRGGBB Theme Color is specifed as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade value, NN is the tint/shade value. +&S | Code for "text strikethrough" on / off +&X | Code for "text super script" on / off +&Y | Code for "text subscript" on / off +&C | Code for "center section". When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the center section. +&D | Code for "date" +&T | Code for "time" +&G | Code for "picture as background" - Please make sure to add the image to the header/footer[^print-footer-image-footnote] +&U | Code for "text single underline" +&E | Code for "double underline" +&R | Code for "right section". When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the right section. +&Z | Code for "this workbook's file path" +&F | Code for "this workbook's file name" +&A | Code for "sheet tab name" +&+ | Code for add to page # +&- | Code for subtract from page # +&"font name,font type" | Code for "text font name" and "text font type", where font name and font type are strings specifying the name and type of the font, separated by a comma. When a hyphen appears in font name, it means "none specified". Both of font name and font type can be localized values. +&"-,Bold" | Code for "bold font style" +&B | Code for "bold font style" +&"-,Regular" | Code for "regular font style" +&"-,Italic" | Code for "italic font style" +&I | Code for "italic font style" +&"-,Bold Italic" | Code for "bold italic font style" +&O | Code for "outline style" +&H | Code for "shadow style" + + [^print-footer-image-footnote]: z +```php +$objDrawing = new PHPExcel_Worksheet_HeaderFooterDrawing(); +$objDrawing->setName('PHPExcel logo'); +$objDrawing->setPath('./images/phpexcel_logo.gif'); +$objDrawing->setHeight(36); +$objPHPExcel->getActiveSheet()->getHeaderFooter()->addImage($objDrawing, PHPExcel_Worksheet_HeaderFooter::IMAGE_HEADER_LEFT); +``` + +__Tip__ + +The above table of codes may seem overwhelming first time you are trying to figure out how to write some header or footer. Luckily, there is an easier way. Let Microsoft Office Excel do the work for you.For example, create in Microsoft Office Excel an xlsx file where you insert the header and footer as desired using the programs own interface. Save file as test.xlsx. Now, take that file and read off the values using PHPExcel as follows: + +```php +$objPHPexcel = PHPExcel_IOFactory::load('test.xlsx'); +$objWorksheet = $objPHPexcel->getActiveSheet(); + +var_dump($objWorksheet->getHeaderFooter()->getOddFooter()); +var_dump($objWorksheet->getHeaderFooter()->getEvenFooter()); +var_dump($objWorksheet->getHeaderFooter()->getOddHeader()); +var_dump($objWorksheet->getHeaderFooter()->getEvenHeader()); +``` + +That reveals the codes for the even/odd header and footer. Experienced users may find it easier to rename test.xlsx to test.zip, unzip it, and inspect directly the contents of the relevant xl/worksheets/sheetX.xml to find the codes for header/footer. + +#### Setting printing breaks on a row or column + +To set a print break, use the following code, which sets a row break on row 10. + +```php +$objPHPExcel->getActiveSheet()->setBreak( 'A10' , PHPExcel_Worksheet::BREAK_ROW ); +``` + +The following line of code sets a print break on column D: + +```php +$objPHPExcel->getActiveSheet()->setBreak( 'D10' , PHPExcel_Worksheet::BREAK_COLUMN ); +``` + +#### Show/hide gridlines when printing + +To show/hide gridlines when printing, use the following code: + +$objPHPExcel->getActiveSheet()->setShowGridlines(true); + +#### Setting rows/columns to repeat at top/left + +PHPExcel can repeat specific rows/cells at top/left of a page. The following code is an example of how to repeat row 1 to 5 on each printed page of a specific worksheet: + +```php +$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 5); +``` + +#### Specify printing area + +To specify a worksheet's printing area, use the following code: + +```php +$objPHPExcel->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5'); +``` + +There can also be multiple printing areas in a single worksheet: + +```php +$objPHPExcel->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5,G4:M20'); +``` + +### Styles + +#### Formatting cells + +A cell can be formatted with font, border, fill, ... style information. For example, one can set the foreground colour of a cell to red, aligned to the right, and the border to black and thick border style. Let's do that on cell B2: + +```php +$objPHPExcel->getActiveSheet()->getStyle('B2') + ->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED); +$objPHPExcel->getActiveSheet()->getStyle('B2') + ->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); +$objPHPExcel->getActiveSheet()->getStyle('B2') + ->getBorders()->getTop()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); +$objPHPExcel->getActiveSheet()->getStyle('B2') + ->getBorders()->getBottom()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); +$objPHPExcel->getActiveSheet()->getStyle('B2') + ->getBorders()->getLeft()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); +$objPHPExcel->getActiveSheet()->getStyle('B2') + ->getBorders()->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); +$objPHPExcel->getActiveSheet()->getStyle('B2') + ->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID); +$objPHPExcel->getActiveSheet()->getStyle('B2') + ->getFill()->getStartColor()->setARGB('FFFF0000'); +``` + +Starting with PHPExcel 1.7.0 getStyle() also accepts a cell range as a parameter. For example, you can set a red background color on a range of cells: + +```php +$objPHPExcel->getActiveSheet()->getStyle('B3:B7')->getFill() + ->setFillType(PHPExcel_Style_Fill::FILL_SOLID) + ->getStartColor()->setARGB('FFFF0000'); +``` + +__Tip__ +It is recommended to style many cells at once, using e.g. getStyle('A1:M500'), rather than styling the cells individually in a loop. This is much faster compared to looping through cells and styling them individually. + +There is also an alternative manner to set styles. The following code sets a cell's style to font bold, alignment right, top border thin and a gradient fill: + +```php +$styleArray = array( + 'font' => array( + 'bold' => true, + ), + 'alignment' => array( + 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, + ), + 'borders' => array( + 'top' => array( + 'style' => PHPExcel_Style_Border::BORDER_THIN, + ), + ), + 'fill' => array( + 'type' => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR, + 'rotation' => 90, + 'startcolor' => array( + 'argb' => 'FFA0A0A0', + ), + 'endcolor' => array( + 'argb' => 'FFFFFFFF', + ), + ), +); + +$objPHPExcel->getActiveSheet()->getStyle('A3')->applyFromArray($styleArray); +``` + +Or with a range of cells: + +```php +$objPHPExcel->getActiveSheet()->getStyle('B3:B7')->applyFromArray($styleArray); +``` + +This alternative method using arrays should be faster in terms of execution whenever you are setting more than one style property. But the difference may barely be measurable unless you have many different styles in your workbook. + +Prior to PHPExcel 1.7.0 duplicateStyleArray() was the recommended method for styling a cell range, but this method has now been deprecated since getStyle() has started to accept a cell range. + +#### Number formats + +You often want to format numbers in Excel. For example you may want a thousands separator plus a fixed number of decimals after the decimal separator. Or perhaps you want some numbers to be zero-padded. + +In Microsoft Office Excel you may be familiar with selecting a number format from the "Format Cells" dialog. Here there are some predefined number formats available including some for dates. The dialog is designed in a way so you don't have to interact with the underlying raw number format code unless you need a custom number format. + +In PHPExcel, you can also apply various predefined number formats. Example: + +```php +$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() + ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1); +``` + +This will format a number e.g. 1587.2 so it shows up as 1,587.20 when you open the workbook in MS Office Excel. (Depending on settings for decimal and thousands separators in Microsoft Office Excel it may show up as 1.587,20) + +You can achieve exactly the same as the above by using this: + +```php +$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() + ->setFormatCode('#,##0.00'); +``` + +In Microsoft Office Excel, as well as in PHPExcel, you will have to interact with raw number format codes whenever you need some special custom number format. Example: + +```php +$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() + ->setFormatCode('[Blue][>=3000]$#,##0;[Red][<0]$#,##0;$#,##0'); +``` + +Another example is when you want numbers zero-padded with leading zeros to a fixed length: + +```php +$objPHPExcel->getActiveSheet()->getCell('A1')->setValue(19); +$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() + ->setFormatCode('0000'); // will show as 0019 in Excel +``` + +__Tip__ +The rules for composing a number format code in Excel can be rather complicated. Sometimes you know how to create some number format in Microsoft Office Excel, but don't know what the underlying number format code looks like. How do you find it? + +The readers shipped with PHPExcel come to the rescue. Load your template workbook using e.g. Excel2007 reader to reveal the number format code. Example how read a number format code for cell A1: + +```php +$objReader = PHPExcel_IOFactory::createReader('Excel2007'); +$objPHPExcel = $objReader->load('template.xlsx'); +var_dump($objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat()->getFormatCode()); +``` + +Advanced users may find it faster to inspect the number format code directly by renaming template.xlsx to template.zip, unzipping, and looking for the relevant piece of XML code holding the number format code in *xl/styles.xml*. + +#### Alignment and wrap text + +Let's set vertical alignment to the top for cells A1:D4 + +```php +$objPHPExcel->getActiveSheet()->getStyle('A1:D4') + ->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP); +``` + +Here is how to achieve wrap text: + +```php +$objPHPExcel->getActiveSheet()->getStyle('A1:D4') + ->getAlignment()->setWrapText(true); +``` + +#### Setting the default style of a workbook + +It is possible to set the default style of a workbook. Let's set the default font to Arial size 8: + +```php +$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial'); +$objPHPExcel->getDefaultStyle()->getFont()->setSize(8); +``` + +#### Styling cell borders + +In PHPExcel it is easy to apply various borders on a rectangular selection. Here is how to apply a thick red border outline around cells B2:G8. + +```php +$styleArray = array( + 'borders' => array( + 'outline' => array( + 'style' => PHPExcel_Style_Border::BORDER_THICK, + 'color' => array('argb' => 'FFFF0000'), + ), + ), +); + +$objWorksheet->getStyle('B2:G8')->applyFromArray($styleArray); +``` + +In Microsoft Office Excel, the above operation would correspond to selecting the cells B2:G8, launching the style dialog, choosing a thick red border, and clicking on the "Outline" border component. + +Note that the border outline is applied to the rectangular selection B2:G8 as a whole, not on each cell individually. + +You can achieve any border effect by using just the 5 basic borders and operating on a single cell at a time: + + Array key | Maps to property + ----------|------------------ + left | getLeft() + right | getRight() + top | getTop() + bottom | getBottom() + diagonal | getDiagonal() + +Additional shortcut borders come in handy like in the example above. These are the shortcut borders available: + + Array key | Maps to property + -----------|------------------ + allborders | getAllBorders() + outline | getOutline() + inside | getInside() + vertical | getVertical() + horizontal | getHorizontal() + + + +An overview of all border shortcuts can be seen in the following image: + +![08-styling-border-options.png](./images/08-styling-border-options.png "") + +If you simultaneously set e.g. allborders and vertical, then we have "overlapping" borders, and one of the components has to win over the other where there is border overlap. In PHPExcel, from weakest to strongest borders, the list is as follows: allborders, outline/inside, vertical/horizontal, left/right/top/bottom/diagonal. + +This border hierarchy can be utilized to achieve various effects in an easy manner. + +### Conditional formatting a cell + +A cell can be formatted conditionally, based on a specific rule. For example, one can set the foreground colour of a cell to red if its value is below zero, and to green if its value is zero or more. + +One can set a conditional style ruleset to a cell using the following code: + +```php +$objConditional1 = new PHPExcel_Style_Conditional(); +$objConditional1->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS); +$objConditional1->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_LESSTHAN); +$objConditional1->addCondition('0'); +$objConditional1->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED); +$objConditional1->getStyle()->getFont()->setBold(true); + +$objConditional2 = new PHPExcel_Style_Conditional(); +$objConditional2->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS); +$objConditional2->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL); +$objConditional2->addCondition('0'); +$objConditional2->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN); +$objConditional2->getStyle()->getFont()->setBold(true); + +$conditionalStyles = $objPHPExcel->getActiveSheet()->getStyle('B2')->getConditionalStyles(); +array_push($conditionalStyles, $objConditional1); +array_push($conditionalStyles, $objConditional2); + +$objPHPExcel->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditionalStyles); +``` + +If you want to copy the ruleset to other cells, you can duplicate the style object: + +```php +$objPHPExcel->getActiveSheet() + ->duplicateStyle( + $objPHPExcel->getActiveSheet()->getStyle('B2'), + 'B3:B7' + ); +``` + +### Add a comment to a cell + +To add a comment to a cell, use the following code. The example below adds a comment to cell E11: + +```php +$objPHPExcel->getActiveSheet() + ->getComment('E11') + ->setAuthor('Mark Baker'); +$objCommentRichText = $objPHPExcel->getActiveSheet() + ->getComment('E11') + ->getText()->createTextRun('PHPExcel:'); +$objCommentRichText->getFont()->setBold(true); +$objPHPExcel->getActiveSheet() + ->getComment('E11') + ->getText()->createTextRun("\r\n"); +$objPHPExcel->getActiveSheet() + ->getComment('E11') + ->getText()->createTextRun('Total amount on the current invoice, excluding VAT.'); +``` + +![08-cell-comment.png](./images/08-cell-comment.png "") + +### Apply autofilter to a range of cells + +To apply an autofilter to a range of cells, use the following code: + +```php +$objPHPExcel->getActiveSheet()->setAutoFilter('A1:C9'); +``` + +__Make sure that you always include the complete filter range!__ +Excel does support setting only the captionrow, but that's __not__ a best practice... + +### Setting security on a spreadsheet + +Excel offers 3 levels of "protection": document security, sheet security and cell security. + +Document security allows you to set a password on a complete spreadsheet, allowing changes to be made only when that password is entered.Worksheet security offers other security options: you can disallow inserting rows on a specific sheet, disallow sorting, ... Cell security offers the option to lock/unlock a cell as well as show/hide the internal formulaAn example on setting document security: + +```php +$objPHPExcel->getSecurity()->setLockWindows(true); +$objPHPExcel->getSecurity()->setLockStructure(true); +$objPHPExcel->getSecurity()->setWorkbookPassword("PHPExcel"); +``` + +An example on setting worksheet security: + +```php +$objPHPExcel->getActiveSheet() + ->getProtection()->setPassword('PHPExcel'); +$objPHPExcel->getActiveSheet() + ->getProtection()->setSheet(true); +$objPHPExcel->getActiveSheet() + ->getProtection()->setSort(true); +$objPHPExcel->getActiveSheet() + ->getProtection()->setInsertRows(true); +$objPHPExcel->getActiveSheet() + ->getProtection()->setFormatCells(true); +``` + +An example on setting cell security: + +```php +$objPHPExcel->getActiveSheet()->getStyle('B1') + ->getProtection() + ->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + +__Make sure you enable worksheet protection if you need any of the worksheet protection features!__ This can be done using the following code: $objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); + +### Setting data validation on a cell + +Data validation is a powerful feature of Excel2007. It allows to specify an input filter on the data that can be inserted in a specific cell. This filter can be a range (i.e. value must be between 0 and 10), a list (i.e. value must be picked from a list), ... + +The following piece of code only allows numbers between 10 and 20 to be entered in cell B3: + +```php +$objValidation = $objPHPExcel->getActiveSheet()->getCell('B3') + ->getDataValidation(); +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_WHOLE ); +$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP ); +$objValidation->setAllowBlank(true); +$objValidation->setShowInputMessage(true); +$objValidation->setShowErrorMessage(true); +$objValidation->setErrorTitle('Input error'); +$objValidation->setError('Number is not allowed!'); +$objValidation->setPromptTitle('Allowed input'); +$objValidation->setPrompt('Only numbers between 10 and 20 are allowed.'); +$objValidation->setFormula1(10); +$objValidation->setFormula2(20); +``` + +The following piece of code only allows an item picked from a list of data to be entered in cell B3: + +```php +$objValidation = $objPHPExcel->getActiveSheet()->getCell('B5') + ->getDataValidation(); +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST ); +$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION ); +$objValidation->setAllowBlank(false); +$objValidation->setShowInputMessage(true); +$objValidation->setShowErrorMessage(true); +$objValidation->setShowDropDown(true); +$objValidation->setErrorTitle('Input error'); +$objValidation->setError('Value is not in list.'); +$objValidation->setPromptTitle('Pick from list'); +$objValidation->setPrompt('Please pick a value from the drop-down list.'); +$objValidation->setFormula1('"Item A,Item B,Item C"'); +``` + +When using a data validation list like above, make sure you put the list between " and " and that you split the items with a comma (,). + +It is important to remember that any string participating in an Excel formula is allowed to be maximum 255 characters (not bytes). This sets a limit on how many items you can have in the string "Item A,Item B,Item C". Therefore it is normally a better idea to type the item values directly in some cell range, say A1:A3, and instead use, say, $objValidation->setFormula1('Sheet!$A$1:$A$3');. Another benefit is that the item values themselves can contain the comma "," character itself. + +If you need data validation on multiple cells, one can clone the ruleset: + +```php +$objPHPExcel->getActiveSheet()->getCell('B8')->setDataValidation(clone $objValidation); +``` + +### Setting a column's width + +A column's width can be set using the following code: + +```php +$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(12); +``` + +If you want PHPExcel to perform an automatic width calculation, use the following code. PHPExcel will approximate the column with to the width of the widest column value. + +```php +$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); +``` + +![08-column-width.png](./images/08-column-width.png "") + +The measure for column width in PHPExcel does __not__ correspond exactly to the measure you may be used to in Microsoft Office Excel. Column widths are difficult to deal with in Excel, and there are several measures for the column width.1) __Inner width in character units__ (e.g. 8.43 this is probably what you are familiar with in Excel)2) __Full width in pixels__ (e.g. 64 pixels)3) __Full width in character units__ (e.g. 9.140625, value -1 indicates unset width)__PHPExcel always operates with 3) "Full width in character units"__ which is in fact the only value that is stored in any Excel file, hence the most reliable measure. Unfortunately, __Microsoft ____Office ____Excel does not present you with this ____measure__. Instead measures 1) and 2) are computed by the application when the file is opened and these values are presented in various dialogues and tool tips.The character width unit is the width of a '0' (zero) glyph in the workbooks default font. Therefore column widths measured in character units in two different workbooks can only be compared if they have the same default workbook font.If you have some Excel file and need to know the column widths in measure 3), you can read the Excel file with PHPExcel and echo the retrieved values. + +### Show/hide a column + +To set a worksheet's column visibility, you can use the following code. The first line explicitly shows the column C, the second line hides column D. + +```php +$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(true); +$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false); +``` + +### Group/outline a column + +To group/outline a column, you can use the following code: + +```php +$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1); +``` + +You can also collapse the column. Note that you should also set the column invisible, otherwise the collapse will not be visible in Excel 2007. + +```php +$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setCollapsed(true); +$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setVisible(false); +``` + +Please refer to the section "group/outline a row" for a complete example on collapsing. + +You can instruct PHPExcel to add a summary to the right (default), or to the left. The following code adds the summary to the left: + +```php +$objPHPExcel->getActiveSheet()->setShowSummaryRight(false); +``` + +### Setting a row''s height + +A row's height can be set using the following code: + +```php +$objPHPExcel->getActiveSheet()->getRowDimension('10')->setRowHeight(100); +``` + +### Show/hide a row + +To set a worksheet''s row visibility, you can use the following code. The following example hides row number 10. + +```php +$objPHPExcel->getActiveSheet()->getRowDimension('10')->setVisible(false); +``` + +Note that if you apply active filters using an AutoFilter, then this will override any rows that you hide or unhide manually within that AutoFilter range if you save the file. + +### Group/outline a row + +To group/outline a row, you can use the following code: + +```php +$objPHPExcel->getActiveSheet()->getRowDimension('5')->setOutlineLevel(1); +``` + +You can also collapse the row. Note that you should also set the row invisible, otherwise the collapse will not be visible in Excel 2007. + +```php +$objPHPExcel->getActiveSheet()->getRowDimension('5')->setCollapsed(true); +$objPHPExcel->getActiveSheet()->getRowDimension('5')->setVisible(false); +``` + +Here's an example which collapses rows 50 to 80: + +```php +for ($i = 51; $i <= 80; $i++) { + $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i"); + $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, "LName $i"); + $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, "PhoneNo $i"); + $objPHPExcel->getActiveSheet()->setCellValue('D' . $i, "FaxNo $i"); + $objPHPExcel->getActiveSheet()->setCellValue('E' . $i, true); + $objPHPExcel->getActiveSheet()->getRowDimension($i)->setOutlineLevel(1); + $objPHPExcel->getActiveSheet()->getRowDimension($i)->setVisible(false); +} + +$objPHPExcel->getActiveSheet()->getRowDimension(81)->setCollapsed(true); +``` + +You can instruct PHPExcel to add a summary below the collapsible rows (default), or above. The following code adds the summary above: + +```php +$objPHPExcel->getActiveSheet()->setShowSummaryBelow(false); +``` + +### Merge/unmerge cells + +If you have a big piece of data you want to display in a worksheet, you can merge two or more cells together, to become one cell. This can be done using the following code: + +```php +$objPHPExcel->getActiveSheet()->mergeCells('A18:E22'); +``` + +Removing a merge can be done using the unmergeCells method: + +```php +$objPHPExcel->getActiveSheet()->unmergeCells('A18:E22'); +``` + +### Inserting rows/columns + +You can insert/remove rows/columns at a specific position. The following code inserts 2 new rows, right before row 7: + +```php +$objPHPExcel->getActiveSheet()->insertNewRowBefore(7, 2); +``` + +### Add a drawing to a worksheet + +A drawing is always represented as a separate object, which can be added to a worksheet. Therefore, you must first instantiate a new PHPExcel_Worksheet_Drawing, and assign its properties a meaningful value: + +```php +$objDrawing = new PHPExcel_Worksheet_Drawing(); +$objDrawing->setName('Logo'); +$objDrawing->setDescription('Logo'); +$objDrawing->setPath('./images/officelogo.jpg'); +$objDrawing->setHeight(36); +``` + +To add the above drawing to the worksheet, use the following snippet of code. PHPExcel creates the link between the drawing and the worksheet: + +```php +$objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); +``` + +You can set numerous properties on a drawing, here are some examples: + +```php +$objDrawing->setName('Paid'); +$objDrawing->setDescription('Paid'); +$objDrawing->setPath('./images/paid.png'); +$objDrawing->setCoordinates('B15'); +$objDrawing->setOffsetX(110); +$objDrawing->setRotation(25); +$objDrawing->getShadow()->setVisible(true); +$objDrawing->getShadow()->setDirection(45); +``` + +You can also add images created using GD functions without needing to save them to disk first as In-Memory drawings. + +```php +// Use GD to create an in-memory image +$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream'); +$textColor = imagecolorallocate($gdImage, 255, 255, 255); +imagestring($gdImage, 1, 5, 5, 'Created with PHPExcel', $textColor); + +// Add the In-Memory image to a worksheet +$objDrawing = new PHPExcel_Worksheet_MemoryDrawing(); +$objDrawing->setName('In-Memory image 1'); +$objDrawing->setDescription('In-Memory image 1'); +$objDrawing->setCoordinates('A1'); +$objDrawing->setImageResource($gdImage); +$objDrawing->setRenderingFunction( + PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG +); +$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT); +$objDrawing->setHeight(36); +$objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); +``` + +### Reading Images from a worksheet + +A commonly asked question is how to retrieve the images from a workbook that has been loaded, and save them as individual image files to disk. + +The following code extracts images from the current active worksheet, and writes each as a separate file. + +```php +$i = 0; +foreach ($objPHPExcel->getActiveSheet()->getDrawingCollection() as $drawing) { + if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { + ob_start(); + call_user_func( + $drawing->getRenderingFunction(), + $drawing->getImageResource() + ); + $imageContents = ob_get_contents(); + ob_end_clean(); + switch ($drawing->getMimeType()) { + case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG : + $extension = 'png'; + break; + case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_GIF: + $extension = 'gif'; + break; + case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG : + $extension = 'jpg'; + break; + } + } else { + $zipReader = fopen($drawing->getPath(),'r'); + $imageContents = ''; + while (!feof($zipReader)) { + $imageContents .= fread($zipReader,1024); + } + fclose($zipReader); + $extension = $drawing->getExtension(); + } + $myFileName = '00_Image_'.++$i.'.'.$extension; + file_put_contents($myFileName,$imageContents); +} +``` + +### Add rich text to a cell + +Adding rich text to a cell can be done using PHPExcel_RichText instances. Here''s an example, which creates the following rich text string: + + > This invoice is *__payable within thirty days after the end of the month__* unless specified otherwise on the invoice. + +```php +$objRichText = new PHPExcel_RichText(); +$objRichText->createText('This invoice is '); +$objPayable = $objRichText->createTextRun('payable within thirty days after the end of the month'); +$objPayable->getFont()->setBold(true); +$objPayable->getFont()->setItalic(true); +$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) ); +$objRichText->createText(', unless specified otherwise on the invoice.'); +$objPHPExcel->getActiveSheet()->getCell('A18')->setValue($objRichText); +``` + +### Define a named range + +PHPExcel supports the definition of named ranges. These can be defined using the following code: + +```php +// Add some data +$objPHPExcel->setActiveSheetIndex(0); +$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:'); +$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Lastname:'); +$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Maarten'); +$objPHPExcel->getActiveSheet()->setCellValue('B2', 'Balliauw'); + +// Define named ranges +$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonFN', $objPHPExcel->getActiveSheet(), 'B1') ); +$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonLN', $objPHPExcel->getActiveSheet(), 'B2') ); +``` + +Optionally, a fourth parameter can be passed defining the named range local (i.e. only usable on the current worksheet). Named ranges are global by default. + +### Redirect output to a client's web browser + +Sometimes, one really wants to output a file to a client''s browser, especially when creating spreadsheets on-the-fly. There are some easy steps that can be followed to do this: + + 1. Create your PHPExcel spreadsheet + 2. Output HTTP headers for the type of document you wish to output + 3. Use the PHPExcel_Writer_* of your choice, and save to "php://output" + +�PHPExcel_Writer_Excel2007 uses temporary storage when writing to php://output. By default, temporary files are stored in the script's working directory. When there is no access, it falls back to the operating system's temporary files location. + +__This may not be safe for unauthorized viewing!__ +Depending on the configuration of your operating system, temporary storage can be read by anyone using the same temporary storage folder. When confidentiality of your document is needed, it is recommended not to use php://output. + +#### HTTP headers + +Example of a script redirecting an Excel 2007 file to the client's browser: + +```php +/* Here there will be some code where you create $objPHPExcel */ + +// redirect output to client browser +header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); +header('Content-Disposition: attachment;filename="myfile.xlsx"'); +header('Cache-Control: max-age=0'); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save('php://output'); +``` + +Example of a script redirecting an Excel5 file to the client's browser: + +```php +/* Here there will be some code where you create $objPHPExcel */ + +// redirect output to client browser +header('Content-Type: application/vnd.ms-excel'); +header('Content-Disposition: attachment;filename="myfile.xls"'); +header('Cache-Control: max-age=0'); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); +$objWriter->save('php://output'); +``` + +**Caution:** + +Make sure not to include any echo statements or output any other contents than the Excel file. There should be no whitespace before the opening tag (which can also be omitted to avoid problems). Make sure that your script is saved without a BOM (Byte-order mark) because this counts as echoing output. The same things apply to all included files. +Failing to follow the above guidelines may result in corrupt Excel files arriving at the client browser, and/or that headers cannot be set by PHP (resulting in warning messages). + +### Setting the default column width + +Default column width can be set using the following code: + +```php +$objPHPExcel->getActiveSheet()->getDefaultColumnDimension()->setWidth(12); +``` + +### Setting the default row height + +Default row height can be set using the following code: + +```php +$objPHPExcel->getActiveSheet()->getDefaultRowDimension()->setRowHeight(15); +``` + +### Add a GD drawing to a worksheet + +There might be a situation where you want to generate an in-memory image using GD and add it to a PHPExcel worksheet without first having to save this file to a temporary location. + +Here''s an example which generates an image in memory and adds it to the active worksheet: + +```php +// Generate an image +$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream'); +$textColor = imagecolorallocate($gdImage, 255, 255, 255); +imagestring($gdImage, 1, 5, 5, 'Created with PHPExcel', $textColor); + +// Add a drawing to the worksheet +$objDrawing = new PHPExcel_Worksheet_MemoryDrawing(); +$objDrawing->setName('Sample image'); +$objDrawing->setDescription('Sample image'); +$objDrawing->setImageResource($gdImage); +$objDrawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); +$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT); +$objDrawing->setHeight(36); +$objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); +``` + +### Setting worksheet zoom level + +To set a worksheet's zoom level, the following code can be used: + +```php +$objPHPExcel->getActiveSheet()->getSheetView()->setZoomScale(75); +``` + +Note that zoom level should be in range 10 – 400. + +### Sheet tab color + +Sometimes you want to set a color for sheet tab. For example you can have a red sheet tab: + +```php +$objWorksheet->getTabColor()->setRGB('FF0000'); +``` + +### Creating worksheets in a workbook + +If you need to create more worksheets in the workbook, here is how: + +```php +$objWorksheet1 = $objPHPExcel->createSheet(); +$objWorksheet1->setTitle('Another sheet'); +``` + +Think of createSheet() as the "Insert sheet" button in Excel. When you hit that button a new sheet is appended to the existing collection of worksheets in the workbook. + +### Hidden worksheets (Sheet states) + +Set a worksheet to be __hidden__ using this code: + +```php +$objPHPExcel->getActiveSheet() + ->setSheetState(PHPExcel_Worksheet::SHEETSTATE_HIDDEN); +``` + +Sometimes you may even want the worksheet to be __"very hidden"__. The available sheet states are : + + - PHPExcel_Worksheet::SHEETSTATE_VISIBLE + - PHPExcel_Worksheet::SHEETSTATE_HIDDEN + - PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN + +In Excel the sheet state "very hidden" can only be set programmatically, e.g. with Visual Basic Macro. It is not possible to make such a sheet visible via the user interface. + +### Right-to-left worksheet + +Worksheets can be set individually whether column "A" should start at left or right side. Default is left. Here is how to set columns from right-to-left. + +```php +// right-to-left worksheet +$objPHPExcel->getActiveSheet() + ->setRightToLeft(true); +``` + diff --git a/Documentation/markdown/Overview/developer.md b/Documentation/markdown/Overview/developer.md index 1e993044f..ac15747dc 100644 --- a/Documentation/markdown/Overview/developer.md +++ b/Documentation/markdown/Overview/developer.md @@ -1,1592 +1,9 @@ # PHPExcel Developer Documentation -## Accessing cells - -Accessing cells in a PHPExcel worksheet should be pretty straightforward. This topic lists some of the options to access a cell. - -### Setting a cell value by coordinate - -Setting a cell value by coordinate can be done using the worksheet's `setCellValue()` method. - -```php -// Set cell B8 -$objPHPExcel->getActiveSheet()->setCellValue('B8', 'Some value'); -``` - -Will set cell B8 in the currently active worksheet to a string value of "Some Value" - -### Retrieving a cell by coordinate - -To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the `getCell()` method. A cell's value can be read again using the following line of code: - -```php -// Get cell B8 -$objPHPExcel->getActiveSheet()->getCell('B8')->getValue(); -``` - -If a cell contains a formula, and you need to retrieve the calculated value rather than the formula itself, then use the following code. This is further explained in . - -```php -// Get cell B8 -$objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue(); -``` - -### Setting a cell value by column and row - -Setting a cell value by coordinate can be done using the worksheet’s setCellValueByColumnAndRow method. - -```php -// Set cell B8 -$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(1, 8, 'Some value'); -``` - -### Retrieving a cell by column and row - -To retrieve the value of a cell, the cell should first be retrieved from the worksheet using the getCellByColumnAndRow method. A cell’s value can be read again using the following line of code: - -```php -// Get cell B8 -$objPHPExcel->getActiveSheet()->getCellByColumnAndRow(1, 8)->getValue(); -``` -If you need the calculated value of a cell, use the following code. This is further explained in . - -```php -// Get cell B8 -$objPHPExcel->getActiveSheet()->getCellByColumnAndRow(1, 8)->getCalculatedValue(); -``` - -### Looping cells - -#### Looping cells using iterators - -The easiest way to loop cells is by using iterators. Using iterators, one can use foreach to loop worksheets, rows and cells. - -Below is an example where we read all the values in a worksheet and display them in a table. - -```php -$objReader = PHPExcel_IOFactory::createReader('Excel2007'); -$objReader->setReadDataOnly(true); -$objPHPExcel = $objReader->load("test.xlsx"); - -$objWorksheet = $objPHPExcel->getActiveSheet(); - -echo '' . "\n"; -foreach ($objWorksheet->getRowIterator() as $row) { - echo '' . "\n"; - $cellIterator = $row->getCellIterator(); - $cellIterator->setIterateOnlyExistingCells(FALSE); // This loops all cells,even if a cell is not set. - // By default, only cells that are set will be iterated. - foreach ($cellIterator as $cell) { - echo '' . "\n"; - } - echo '' . "\n"; -} - -echo '
' . $cell->getValue() . '
' . "\n"; -``` - -Note that we have set the cell iterator's `setIterateOnlyExistingCells()` to FALSE. This makes the iterator loop all cells, even if they were not set before. - -__The cell iterator will return ____NULL____ as the cell if it is not set in the worksheet.__ -Setting the cell iterator's setIterateOnlyExistingCells() to FALSE will loop all cells in the worksheet that can be available at that moment. This will create new cells if required and increase memory usage! Only use it if it is intended to loop all cells that are possibly available. - -#### Looping cells using indexes - -One can use the possibility to access cell values by column and row index like (0,1) instead of 'A1' for reading and writing cell values in loops. - -Note: In PHPExcel column index is 0-based while row index is 1-based. That means 'A1' ~ (0,1) - -Below is an example where we read all the values in a worksheet and display them in a table. - -setReadDataOnly(true); - -$objPHPExcel = $objReader->load("test.xlsx"); - -$objWorksheet = $objPHPExcel->getActiveSheet(); - -$highestRow = $objWorksheet->getHighestRow(); // e.g. 10 - -$highestColumn = $objWorksheet->getHighestColumn(); // e.g 'F' - -$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn); // e.g. 5 - -echo '' . "\n"; - -for ($row = 1; $row <= $highestRow; ++$row) { - -echo '' . "\n"; - -for ($col = 0; $col <= $highestColumnIndex; ++$col) { - -echo '' . "\n"; - -} - -echo '' . "\n"; - -} - -echo '
' . $objWorksheet->getCellByColumnAndRow($col, $row)->getValue() . '
' . "\n"; - -?> - -### Using value binders to facilitate data entry - -Internally, PHPExcel uses a default PHPExcel_Cell_IValueBinder implementation (PHPExcel_Cell_DefaultValueBinder) to determine data types of entered data using a cell’s setValue() method. - -Optionally, the default behaviour of PHPExcel can be modified, allowing easier data entry. For example, a PHPExcel_Cell_AdvancedValueBinder class is present. It automatically converts percentages and dates entered as strings to the correct format, also setting the cell’s style information. The following example demonstrates how to set the value binder in PHPExcel: - -/** PHPExcel */ - -require_once 'PHPExcel.php'; - -/** PHPExcel_Cell_AdvancedValueBinder */ - -require_once 'PHPExcel/Cell/AdvancedValueBinder.php'; - -/** PHPExcel_IOFactory */ - -require_once 'PHPExcel/IOFactory.php'; - -// Set value binder - -PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); - -// Create new PHPExcel object - -$objPHPExcel = new PHPExcel(); - -// ... - -// Add some data, resembling some different data types - -$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Percentage value:'); - -$objPHPExcel->getActiveSheet()->setCellValue('B4', '10%'); - // Converts to 0.1 and sets percentage cell style - -$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Date/time value:'); - -$objPHPExcel->getActiveSheet()->setCellValue('B5', '21 December 1983'); - // Converts to date and sets date format cell style - -__Creating your own value binder is easy____.__ -When advanced value binding is required, you can implement the PHPExcel_Cell_IValueBinder interface or extend the PHPExcel_Cell_DefaultValueBinder or PHPExcel_Cell_AdvancedValueBinder classes. - -## PHPExcel recipes - -The following pages offer you some widely-used PHPExcel recipes. Please note that these do NOT offer complete documentation on specific PHPExcel API functions, but just a bump to get you started. If you need specific API functions, please refer to the API documentation. - -For example, REF _Ref191885321 \w \h 4.4.7 REF _Ref191885321 \h Setting a worksheet’s page orientation and size covers setting a page orientation to A4. Other paper formats, like US Letter, are not covered in this document, but in the PHPExcel API documentation. - -### Setting a spreadsheet’s metadata - -PHPExcel allows an easy way to set a spreadsheet’s metadata, using document property accessors. Spreadsheet metadata can be useful for finding a specific document in a file repository or a document management system. For example Microsoft Sharepoint uses document metadata to search for a specific document in its document lists. - -Setting spreadsheet metadata is done as follows: - -$objPHPExcel->getProperties()->setCreator("Maarten Balliauw"); - -$objPHPExcel->getProperties()->setLastModifiedBy("Maarten Balliauw"); - -$objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document"); - -$objPHPExcel->getProperties()->setSubject("Office 2007 XLSX Test Document"); - -$objPHPExcel->getProperties()->setDescription("Test document for Office 2007 XLSX, generated using PHP classes."); - -$objPHPExcel->getProperties()->setKeywords("office 2007 openxml php"); - -$objPHPExcel->getProperties()->setCategory("Test result file"); - -### Setting a spreadsheet’s active sheet - -The following line of code sets the active sheet index to the first sheet: - -$objPHPExcel->setActiveSheetIndex(0); - -### Write a date or time into a cell - -In Excel, dates and Times are stored as numeric values counting the number of days elapsed since 1900-01-01. For example, the date '2008-12-31' is represented as 39813. You can verify this in Microsoft Office Excel by entering that date in a cell and afterwards changing the number format to 'General' so the true numeric value is revealed. Likewise, '3:15 AM' is represented as 0.135417. - -PHPExcel works with UST (Universal Standard Time) date and Time values, but does no internal conversions; so it is up to the developer to ensure that values passed to the date/time conversion functions are UST. - -Writing a date value in a cell consists of 2 lines of code. Select the method that suits you the best. Here are some examples: - -/* PHPExcel_Cell_AdvanceValueBinder required for this sample */ - -require_once 'PHPExcel/Cell/AdvancedValueBinder.php'; - -// MySQL-like timestamp '2008-12-31' or date string - -PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); - -$objPHPExcel->getActiveSheet() - -->setCellValue('D1', '2008-12-31'); - -$objPHPExcel->getActiveSheet() - -->getStyle('D1') - -->getNumberFormat() - -->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH) - -// PHP-time (Unix time) - -$time = gmmktime(0,0,0,12,31,2008); // int(1230681600) - -$objPHPExcel->getActiveSheet() - -->setCellValue('D1', PHPExcel_Shared_Date::PHPToExcel($time)); - -$objPHPExcel->getActiveSheet() - -->getStyle('D1') - -->getNumberFormat() - -->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH) - -// Excel-date/time - -$objPHPExcel->getActiveSheet() - -->setCellValue('D1', 39813) - -$objPHPExcel->getActiveSheet() - -->getStyle('D1') - -->getNumberFormat() - -->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH) - -The above methods for entering a date all yield the same result. PHPExcel_Style_NumberFormat provides a lot of pre-defined date formats. - -The PHPExcel_Shared_Date::PHPToExcel() method will also work with a PHP DateTime object. - -Similarly, times (or date and time values) can be entered in the same fashion: just remember to use an appropriate format code. - -__Notes:__ - -See section "Using value binders to facilitate data entry" to learn more about the AdvancedValueBinder used in the first example. -In previous versions of PHPExcel up to and including 1.6.6, when a cell had a date-like number format code, it was possible to enter a date directly using an integer PHP-time without converting to Excel date format. Starting with PHPExcel 1.6.7 this is no longer supported. -Excel can also operate in a 1904-based calendar (default for workbooks saved on Mac). Normally, you do not have to worry about this when using PHPExcel.### Write a formula into a cell - -Inside the Excel file, formulas are always stored as they would appear in an English version of Microsoft Office Excel, and PHPExcel handles all formulae internally in this format. This means that the following rules hold: - -Decimal separator is '.' (period)Function argument separator is ',' (comma)Matrix row separator is ';' (semicolon)English function names must be usedThis is regardless of which language version of Microsoft Office Excel may have been used to create the Excel file. - -When the final workbook is opened by the user, Microsoft Office Excel will take care of displaying the formula according the applications language. Translation is taken care of by the application! - -The following line of code writes the formula “=IF(C4>500,"profit","loss")” into the cell B8. Note that the formula must start with “=” to make PHPExcel recognise this as a formula. - -$objPHPExcel->getActiveSheet()->setCellValue('B8','=IF(C4>500,"profit","loss")'); - -If you want to write a string beginning with an “=” to a cell, then you should use the setCellValueExplicit() method. - -$objPHPExcel->getActiveSheet() - -->setCellValueExplicit('B8', - -'=IF(C4>500,"profit","loss")', - -PHPExcel_Cell_DataType::TYPE_STRING - -); - -A cell’s formula can be read again using the following line of code: - -$formula = $objPHPExcel->getActiveSheet()->getCell('B8')->getValue(); - -If you need the calculated value of a cell, use the following code. This is further explained in REF _Ref191885372 \w \h \* MERGEFORMAT 4.4.35. - -$value = $objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue(); - -### Locale Settings for Formulae - -Some localisation elements have been included in PHPExcel. You can set a locale by changing the settings. To set the locale to Russian you would use: - -$locale = 'ru'; - -$validLocale = PHPExcel_Settings::setLocale($locale); - -if (!$validLocale) { - -echo 'Unable to set locale to '.$locale." - reverting to en_us
\n"; - -} - -If Russian language files aren’t available, the setLocale() method will return an error, and English settings will be used throughout. - -Once you have set a locale, you can translate a formula from its internal English coding. - -$formula = $objPHPExcel->getActiveSheet()->getCell('B8')->getValue(); - -$translatedFormula = - -PHPExcel_Calculation::getInstance()->_translateFormulaToLocale($formula); - -You can also create a formula using the function names and argument separators appropriate to the defined locale; then translate it to English before setting the cell value: - -$formula = '=ДНЕЙ360(ДАТА(2010;2;5);ДАТА(2010;12;31);ИСТИНА)'; - -$internalFormula = - -PHPExcel_Calculation::getInstance()->translateFormulaToEnglish($formula); - -$objPHPExcel->getActiveSheet()->setCellValue('B8',$internalFormula); - -Currently, formula translation only translates the function names, the constants TRUE and FALSE, and the function argument separators. - -At present, the following locale settings are supported: - -__Language__ - -__Locale Code__ - -Czech - -Čeština - -cs - -Danish - -Dansk - -da - -German - -Deutsch - -de - -Spanish - -Español - -es - -Finnish - -Suomi - -fi - -French - -Français - -fr - -Hungarian - -Magyar - -hu - -Italian - -Italiano - -it - -Dutch - -Nederlands - -nl - -Norwegian - -Norsk - -no - -Polish - -Język polski - -pl - -Portuguese - -Português - -pt - -Brazilian Portuguese - -Português Brasileiro - -pt_br - -Russian - -русский язык - -ru - -Swedish - -Svenska - -sv - -Turkish - -Türkçe - -tr - -### Write a newline character "\n" in a cell (ALT+"Enter") - -In Microsoft Office Excel you get a line break in a cell by hitting ALT+"Enter". When you do that, it automatically turns on "wrap text" for the cell. - -Here is how to achieve this in PHPExcel: - -$objPHPExcel->getActiveSheet()->getCell('A1')->setValue("hello\nworld"); - -$objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setWrapText(true); - -__Tip__ - -Read more about formatting cells using getStyle() elsewhere.__Tip__ - -AdvancedValuebinder.php automatically turns on "wrap text" for the cell when it sees a newline character in a string that you are inserting in a cell. Just like Microsoft Office Excel. Try this:require_once 'PHPExcel/Cell/AdvancedValueBinder.php';PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() );$objPHPExcel->getActiveSheet()->getCell('A1')->setValue("hello\nworld");Read more about AdvancedValueBinder.php elsewhere.### Explicitly set a cell’s datatype - -You can set a cell’s datatype explicitly by using the cell’s setValueExplicit method, or the setCellValueExplicit method of a worksheet. Here’s an example: - -$objPHPExcel->getActiveSheet()->getCell('A1')->setValueExplicit('25', PHPExcel_Cell_DataType::TYPE_NUMERIC); - -### Change a cell into a clickable URL - -You can make a cell a clickable URL by setting its hyperlink property: - -$objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net'); - -$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl('http://www.phpexcel.net/'); - -If you want to make a hyperlink to another worksheet/cell, use the following code: - -$objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net'); - -$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl(“sheet://'Sheetname'!A1”); - -### Setting a worksheet’s page orientation and size - -Setting a worksheet’s page orientation and size can be done using the following lines of code: - -$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); - -$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4); - -Note that there are additional page settings available. Please refer to the API documentation for all possible options. - -### Page Setup: Scaling options - -The page setup scaling options in PHPExcel relate directly to the scaling options in the "Page Setup" dialog as shown in the illustration. - -Default values in PHPExcel correspond to default values in MS Office Excel as shown in illustration - - - -method - -initial value - -calling method will trigger - -Note - -setFitToPage(...) - -false - -- - -setScale(...) - -100 - -setFitToPage(false) - -setFitToWidth(...) - -1 - -setFitToPage(true) - -value 0 means do-not-fit-to-width - -setFitToHeight(...) - -1 - -setFitToPage(true) - -value 0 means do-not-fit-to-height - -#### Example - -Here is how to __f____it to 1 page wide by infinite pages tall__: - -$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToWidth(1); - -$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToHeight(0); - -As you can see, it is not necessary to call setFitToPage(true) since setFitToWidth(…) and setFitToHeight(…) triggers this. - -If you use setFitToWidth() you should in general also specify setFitToHeight() explicitly like in the example. Be careful relying on the initial values. This is especially true if you are upgrading from PHPExcel 1.7.0 to 1.7.1 where the default values for fit-to-height and fit-to-width changed from 0 to 1. - -### Page margins - -To set page margins for a worksheet, use this code: - -$objPHPExcel->getActiveSheet()->getPageMargins()->setTop(1); -$objPHPExcel->getActiveSheet()->getPageMargins()->setRight(0.75); -$objPHPExcel->getActiveSheet()->getPageMargins()->setLeft(0.75); - -$objPHPExcel->getActiveSheet()->getPageMargins()->setBottom(1); - -Note that the margin values are specified in inches. - - - -### Center a page horizontally/vertically - -To center a page horizontally/vertically, you can use the following code: - -$objPHPExcel->getActiveSheet()->getPageSetup()->setHorizontalCentered(true); -$objPHPExcel->getActiveSheet()->getPageSetup()->setVerticalCentered(false); - -### Setting the print header and footer of a worksheet - -Setting a worksheet’s print header and footer can be done using the following lines of code: - -$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader('&C&HPlease treat this document as confidential!'); - -$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N'); - -Substitution and formatting codes (starting with &) can be used inside headers and footers. There is no required order in which these codes must appear. - -The first occurrence of the following codes turns the formatting ON, the second occurrence turns it OFF again: - -StrikethroughSuperscriptSubscriptSuperscript and subscript cannot both be ON at same time. Whichever comes first wins and the other is ignored, while the first is ON. - -The following codes are supported by Excel2007: - -&L - -Code for "left section" (there are three header / footer locations, "left", "center", and "right"). When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the left section. - -&P - -Code for "current page #" - -&N - -Code for "total pages" - -&font size - -Code for "text font size", where font size is a font size in points. - -&K - -Code for "text font color" - -RGB Color is specified as RRGGBBTheme Color is specifed as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade value, NN is the tint/shade value.&S - -Code for "text strikethrough" on / off - -&X - -Code for "text super script" on / off - -&Y - -Code for "text subscript" on / off - -&C - -Code for "center section". When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the center section. - -&D - -Code for "date" - -&T - -Code for "time" - -&G - -Code for "picture as background" - -Please make sure to add the image to the header/footer: - -$objDrawing = new PHPExcel_Worksheet_HeaderFooterDrawing(); - -$objDrawing->setName('PHPExcel logo'); - -$objDrawing->setPath('./images/phpexcel_logo.gif'); - -$objDrawing->setHeight(36); - -$objPHPExcel->getActiveSheet()->getHeaderFooter()->addImage($objDrawing, PHPExcel_Worksheet_HeaderFooter::IMAGE_HEADER_LEFT); - -&U - -Code for "text single underline" - -&E - -Code for "double underline" - -&R - -Code for "right section". When two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the order of appearance, and placed into the right section. - -&Z - -Code for "this workbook's file path" - -&F - -Code for "this workbook's file name" - -&A - -Code for "sheet tab name" - -&+ - -Code for add to page # - -&- - -Code for subtract from page # - -&"font name,font type" - -Code for "text font name" and "text font type", where font name and font type are strings specifying the name and type of the font, separated by a comma. When a hyphen appears in font name, it means "none specified". Both of font name and font type can be localized values. - -&"-,Bold" - -Code for "bold font style" - -&B - -Code for "bold font style" - -&"-,Regular" - -Code for "regular font style" - -&"-,Italic" - -Code for "italic font style" - -&I - -Code for "italic font style" - -&"-,Bold Italic" - -Code for "bold italic font style" - -&O - -Code for "outline style" - -&H - -Code for "shadow style" - -__Tip__ - -The above table of codes may seem overwhelming first time you are trying to figure out how to write some header or footer. Luckily, there is an easier way. Let Microsoft Office Excel do the work for you.For example, create in Microsoft Office Excel an xlsx file where you insert the header and footer as desired using the programs own interface. Save file as test.xlsx. Now, take that file and read off the values using PHPExcel as follows:$objPHPexcel = PHPExcel_IOFactory::load('test.xlsx');$objWorksheet = $objPHPexcel->getActiveSheet();var_dump($objWorksheet->getHeaderFooter()->getOddFooter());var_dump($objWorksheet->getHeaderFooter()->getEvenFooter());var_dump($objWorksheet->getHeaderFooter()->getOddHeader());var_dump($objWorksheet->getHeaderFooter()->getEvenHeader());That reveals the codes for the even/odd header and footer. Experienced users may find it easier to rename test.xlsx to test.zip, unzip it, and inspect directly the contents of the relevant xl/worksheets/sheetX.xml to find the codes for header/footer.### Setting printing breaks on a row or column - -To set a print break, use the following code, which sets a row break on row 10. - -$objPHPExcel->getActiveSheet()->setBreak( 'A10' , PHPExcel_Worksheet::BREAK_ROW ); - -The following line of code sets a print break on column D: - -$objPHPExcel->getActiveSheet()->setBreak( 'D10' , PHPExcel_Worksheet::BREAK_COLUMN ); - -### Show/hide gridlines when printing - -To show/hide gridlines when printing, use the following code: - -$objPHPExcel->getActiveSheet()->setShowGridlines(true); - -### Setting rows/columns to repeat at top/left - -PHPExcel can repeat specific rows/cells at top/left of a page. The following code is an example of how to repeat row 1 to 5 on each printed page of a specific worksheet: - -$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 5); - -### Specify printing area - -To specify a worksheet’s printing area, use the following code: - -$objPHPExcel->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5'); - -There can also be multiple printing areas in a single worksheet: - -$objPHPExcel->getActiveSheet()->getPageSetup()->setPrintArea('A1:E5,G4:M20'); - -### Formatting cells - -A cell can be formatted with font, border, fill, … style information. For example, one can set the foreground colour of a cell to red, aligned to the right, and the border to black and thick border style. Let’s do that on cell B2: - -$objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED); - -$objPHPExcel->getActiveSheet()->getStyle('B2')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); - -$objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); - -$objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getBottom()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); - -$objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getLeft()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); - -$objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK); - -$objPHPExcel->getActiveSheet()->getStyle('B2')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID); - -$objPHPExcel->getActiveSheet()->getStyle('B2')->getFill()->getStartColor()->setARGB('FFFF0000'); - -Starting with PHPExcel 1.7.0 getStyle() also accepts a cell range as a parameter. For example, you can set a red background color on a range of cells: - -$objPHPExcel->getActiveSheet()->getStyle('B3:B7')->getFill() - -->setFillType(PHPExcel_Style_Fill::FILL_SOLID) - -->getStartColor()->setARGB('FFFF0000'); - -__Tip__ -It is recommended to style many cells at once, using e.g. getStyle('A1:M500'), rather than styling the cells individually in a loop. This is much faster compared to looping through cells and styling them individually. - -There is also an alternative manner to set styles. The following code sets a cell’s style to font bold, alignment right, top border thin and a gradient fill: - -$styleArray = array( - -'font' => array( - -'bold' => true, - -), - -'alignment' => array( - -'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, - -), - -'borders' => array( - -'top' => array( - -'style' => PHPExcel_Style_Border::BORDER_THIN, - -), - -), - -'fill' => array( - -'type' => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR, - -'rotation' => 90, - -'startcolor' => array( - -'argb' => 'FFA0A0A0', - -), - -'endcolor' => array( - -'argb' => 'FFFFFFFF', - -), - -), - -); - -$objPHPExcel->getActiveSheet()->getStyle('A3')->applyFromArray($styleArray); - -Or with a range of cells: - -$objPHPExcel->getActiveSheet()->getStyle('B3:B7')->applyFromArray($styleArray); - -This alternative method using arrays should be faster in terms of execution whenever you are setting more than one style property. But the difference may barely be measurable unless you have many different styles in your workbook. - -Prior to PHPExcel 1.7.0 duplicateStyleArray() was the recommended method for styling a cell range, but this method has now been deprecated since getStyle() has started to accept a cell range. - -### Number formats - -You often want to format numbers in Excel. For example you may want a thousands separator plus a fixed number of decimals after the decimal separator. Or perhaps you want some numbers to be zero-padded. - -In Microsoft Office Excel you may be familiar with selecting a number format from the "Format Cells" dialog. Here there are some predefined number formats available including some for dates. The dialog is designed in a way so you don't have to interact with the underlying raw number format code unless you need a custom number format. - -In PHPExcel, you can also apply various predefined number formats. Example: - -$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() - -->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1); - -This will format a number e.g. 1587.2 so it shows up as 1,587.20 when you open the workbook in MS Office Excel. (Depending on settings for decimal and thousands separators in Microsoft Office Excel it may show up as 1.587,20) - -You can achieve exactly the same as the above by using this: - -$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() - -->setFormatCode('#,##0.00'); - -In Microsoft Office Excel, as well as in PHPExcel, you will have to interact with raw number format codes whenever you need some special custom number format. Example: - -$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() - -->setFormatCode('[Blue][>=3000]$#,##0;[Red][<0]$#,##0;$#,##0'); - -Another example is when you want numbers zero-padded with leading zeros to a fixed length: - -$objPHPExcel->getActiveSheet()->getCell('A1')->setValue(19); - -$objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat() - -->setFormatCode('0000'); // will show as 0019 in Excel - -__Tip__ -The rules for composing a number format code in Excel can be rather complicated. Sometimes you know how to create some number format in Microsoft Office Excel, but don't know what the underlying number format code looks like. How do you find it? - -The readers shipped with PHPExcel come to the rescue. Load your template workbook using e.g. Excel2007 reader to reveal the number format code. Example how read a number format code for cell A1: - -$objReader = PHPExcel_IOFactory::createReader('Excel2007'); -$objPHPExcel = $objReader->load('template.xlsx'); -var_dump($objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat()->getFormatCode()); -Advanced users may find it faster to inspect the number format code directly by renaming template.xlsx to template.zip, unzipping, and looking for the relevant piece of XML code holding the number format code in *xl/styles.xml*.### Alignment and wrap text - -Let’s set vertical alignment to the top for cells A1:D4 - -$objPHPExcel->getActiveSheet()->getStyle('A1:D4') - -->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP); - -Here is how to achieve wrap text: - -$objPHPExcel->getActiveSheet()->getStyle('A1:D4') - -->getAlignment()->setWrapText(true); - -### Setting the default style of a workbook - -It is possible to set the default style of a workbook. Let’s set the default font to Arial size 8: - -$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial'); -$objPHPExcel->getDefaultStyle()->getFont()->setSize(8); - -### Styling cell borders - -In PHPExcel it is easy to apply various borders on a rectangular selection. Here is how to apply a thick red border outline around cells B2:G8. - -$styleArray = array( - -'borders' => array( - -'outline' => array( - -'style' => PHPExcel_Style_Border::BORDER_THICK, - -'color' => array('argb' => 'FFFF0000'), - -), - -), - -); - -$objWorksheet->getStyle('B2:G8')->applyFromArray($styleArray); - -In Microsoft Office Excel, the above operation would correspond to selecting the cells B2:G8, launching the style dialog, choosing a thick red border, and clicking on the "Outline" border component. - -Note that the border outline is applied to the rectangular selection B2:G8 as a whole, not on each cell individually. - -You can achieve any border effect by using just the 5 basic borders and operating on a single cell at a time: - -__Array key__ - -__Maps to property__ - -left - -right - -top - -bottom - -diagonal - -getLeft() -getRight() -getTop() -getBottom() -getDiagonal() - -Additional shortcut borders come in handy like in the example above. These are the shortcut borders available: - -__Array key__ - -__Maps to property__ - -allborders -outline - -inside -vertical - -horizontal - -getAllBorders() - -getOutline() - -getInside() - -getVertical() - -getHorizontal() - -An overview of all border shortcuts can be seen in the following image: - - - -If you simultaneously set e.g. allborders and vertical, then we have "overlapping" borders, and one of the components has to win over the other where there is border overlap. In PHPExcel, from weakest to strongest borders, the list is as follows: allborders, outline/inside, vertical/horizontal, left/right/top/bottom/diagonal. - -This border hierarchy can be utilized to achieve various effects in an easy manner. - -### Conditional formatting a cell - -A cell can be formatted conditionally, based on a specific rule. For example, one can set the foreground colour of a cell to red if its value is below zero, and to green if its value is zero or more. - -One can set a conditional style ruleset to a cell using the following code: - -$objConditional1 = new PHPExcel_Style_Conditional(); - -$objConditional1->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS); - -$objConditional1->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_LESSTHAN); - -$objConditional1->addCondition('0'); - -$objConditional1->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED); - -$objConditional1->getStyle()->getFont()->setBold(true); - -$objConditional2 = new PHPExcel_Style_Conditional(); - -$objConditional2->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS); - -$objConditional2->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL); - -$objConditional2->addCondition('0'); - -$objConditional2->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN); - -$objConditional2->getStyle()->getFont()->setBold(true); - -$conditionalStyles = $objPHPExcel->getActiveSheet()->getStyle('B2')->getConditionalStyles(); - -array_push($conditionalStyles, $objConditional1); - -array_push($conditionalStyles, $objConditional2); - -$objPHPExcel->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditionalStyles); - -If you want to copy the ruleset to other cells, you can duplicate the style object: - -$objPHPExcel->getActiveSheet()->duplicateStyle( $objPHPExcel->getActiveSheet()->getStyle('B2'), 'B3:B7' ); - -### Add a comment to a cell - -To add a comment to a cell, use the following code. The example below adds a comment to cell E11: - -$objPHPExcel->getActiveSheet()->getComment('E11')->setAuthor('PHPExcel'); - -$objCommentRichText = $objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun('PHPExcel:'); - - -$objCommentRichText->getFont()->setBold(true); - - -$objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun("\r\n"); - - -$objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun('Total amount on the current invoice, excluding VAT.'); - - - -### Apply autofilter to a range of cells - -To apply an autofilter to a range of cells, use the following code: - -$objPHPExcel->getActiveSheet()->setAutoFilter('A1:C9'); - -__Make sure that you always include the complete filter range!__ -Excel does support setting only the captionrow, but that's __not__ a best practice... - -### Setting security on a spreadsheet - -Excel offers 3 levels of “protection”: document security, sheet security and cell security. - -Document security allows you to set a password on a complete spreadsheet, allowing changes to be made only when that password is entered.Worksheet security offers other security options: you can disallow inserting rows on a specific sheet, disallow sorting, …Cell security offers the option to lock/unlock a cell as well as show/hide the internal formulaAn example on setting document security: - -$objPHPExcel->getSecurity()->setLockWindows(true); - -$objPHPExcel->getSecurity()->setLockStructure(true); - -$objPHPExcel->getSecurity()->setWorkbookPassword("PHPExcel"); - -An example on setting worksheet security: - -$objPHPExcel->getActiveSheet()->getProtection()->setPassword('PHPExcel'); - -$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); - -$objPHPExcel->getActiveSheet()->getProtection()->setSort(true); - -$objPHPExcel->getActiveSheet()->getProtection()->setInsertRows(true); - -$objPHPExcel->getActiveSheet()->getProtection()->setFormatCells(true); - -An example on setting cell security: - -$objPHPExcel->getActiveSheet()->getStyle('B1')->getProtection()->setLocked( - -PHPExcel_Style_Protection::PROTECTION_UNPROTECTED - -); - -__Make sure you enable worksheet protection if you need any of the worksheet protection features!__ This can be done using the following code: $objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); - -### Setting data validation on a cell - -Data validation is a powerful feature of Excel2007. It allows to specify an input filter on the data that can be inserted in a specific cell. This filter can be a range (i.e. value must be between 0 and 10), a list (i.e. value must be picked from a list), … - -The following piece of code only allows numbers between 10 and 20 to be entered in cell B3: - -$objValidation = $objPHPExcel->getActiveSheet()->getCell('B3') - -->getDataValidation(); - -$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_WHOLE ); - -$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP ); - -$objValidation->setAllowBlank(true); - -$objValidation->setShowInputMessage(true); - -$objValidation->setShowErrorMessage(true); - -$objValidation->setErrorTitle('Input error'); - -$objValidation->setError('Number is not allowed!'); - -$objValidation->setPromptTitle('Allowed input'); - -$objValidation->setPrompt('Only numbers between 10 and 20 are allowed.'); - -$objValidation->setFormula1(10); - -$objValidation->setFormula2(20); - -The following piece of code only allows an item picked from a list of data to be entered in cell B3: - -$objValidation = $objPHPExcel->getActiveSheet()->getCell('B5') - -->getDataValidation(); - -$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST ); - -$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION ); - -$objValidation->setAllowBlank(false); - -$objValidation->setShowInputMessage(true); - -$objValidation->setShowErrorMessage(true); - -$objValidation->setShowDropDown(true); - -$objValidation->setErrorTitle('Input error'); - -$objValidation->setError('Value is not in list.'); - -$objValidation->setPromptTitle('Pick from list'); - -$objValidation->setPrompt('Please pick a value from the drop-down list.'); - -$objValidation->setFormula1('"Item A,Item B,Item C"'); - -When using a data validation list like above, make sure you put the list between " and " and that you split the items with a comma (,). - -It is important to remember that any string participating in an Excel formula is allowed to be maximum 255 characters (not bytes). This sets a limit on how many items you can have in the string "Item A,Item B,Item C". Therefore it is normally a better idea to type the item values directly in some cell range, say A1:A3, and instead use, say, $objValidation->setFormula1('Sheet!$A$1:$A$3');. Another benefit is that the item values themselves can contain the comma ‘,’ character itself. - -If you need data validation on multiple cells, one can clone the ruleset: - -$objPHPExcel->getActiveSheet()->getCell('B8')->setDataValidation(clone $objValidation); - -### Setting a column’s width - -A column’s width can be set using the following code: - -$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(12); - -If you want PHPExcel to perform an automatic width calculation, use the following code. PHPExcel will approximate the column with to the width of the widest column value. - -$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); - -The measure for column width in PHPExcel does __not__ correspond exactly to the measure you may be used to in Microsoft Office Excel. Column widths are difficult to deal with in Excel, and there are several measures for the column width.1) __Inner width in character units__ (e.g. 8.43 this is probably what you are familiar with in Excel)2) __Full width in pixels__ (e.g. 64 pixels)3) __Full width in character units__ (e.g. 9.140625, value -1 indicates unset width)__PHPExcel always operates with 3) "Full width in character units"__ which is in fact the only value that is stored in any Excel file, hence the most reliable measure. Unfortunately, __Microsoft ____Office ____Excel does not present you with this ____measure__. Instead measures 1) and 2) are computed by the application when the file is opened and these values are presented in various dialogues and tool tips.The character width unit is the width of a '0' (zero) glyph in the workbooks default font. Therefore column widths measured in character units in two different workbooks can only be compared if they have the same default workbook font.If you have some Excel file and need to know the column widths in measure 3), you can read the Excel file with PHPExcel and echo the retrieved values.### Show/hide a column - -To set a worksheet’s column visibility, you can use the following code. The first line explicitly shows the column C, the second line hides column D. - -$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(true); - -$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false); - -### Group/outline a column - -To group/outline a column, you can use the following code: - -$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1); - -You can also collapse the column. Note that you should also set the column invisible, otherwise the collapse will not be visible in Excel 2007. - -$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setCollapsed(true); - -$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setVisible(false); - -Please refer to the part “group/outline a row” for a complete example on collapsing. - -You can instruct PHPExcel to add a summary to the right (default), or to the left. The following code adds the summary to the left: - -$objPHPExcel->getActiveSheet()->setShowSummaryRight(false); - -### Setting a row’s height - -A row’s height can be set using the following code: - -$objPHPExcel->getActiveSheet()->getRowDimension('10')->setRowHeight(100); - -### Show/hide a row - -To set a worksheet’s row visibility, you can use the following code. The following example hides row number 10. - -$objPHPExcel->getActiveSheet()->getRowDimension('10')->setVisible(false); - -Note that if you apply active filters using an AutoFilter, then this will override any rows that you hide or unhide manually within that AutoFilter range if you save the file. - -### Group/outline a row - -To group/outline a row, you can use the following code: - -$objPHPExcel->getActiveSheet()->getRowDimension('5')->setOutlineLevel(1); - -You can also collapse the row. Note that you should also set the row invisible, otherwise the collapse will not be visible in Excel 2007. - -$objPHPExcel->getActiveSheet()->getRowDimension('5')->setCollapsed(true); - -$objPHPExcel->getActiveSheet()->getRowDimension('5')->setVisible(false); - -Here’s an example which collapses rows 50 to 80: - -for ($i = 51; $i <= 80; $i++) { - -$objPHPExcel->getActiveSheet()->setCellValue('A' . $i, "FName $i"); - -$objPHPExcel->getActiveSheet()->setCellValue('B' . $i, "LName $i"); - -$objPHPExcel->getActiveSheet()->setCellValue('C' . $i, "PhoneNo $i"); - -$objPHPExcel->getActiveSheet()->setCellValue('D' . $i, "FaxNo $i"); - -$objPHPExcel->getActiveSheet()->setCellValue('E' . $i, true); - -$objPHPExcel->getActiveSheet()->getRowDimension($i)->setOutlineLevel(1); - -$objPHPExcel->getActiveSheet()->getRowDimension($i)->setVisible(false); - -} - -$objPHPExcel->getActiveSheet()->getRowDimension(81)->setCollapsed(true); - -You can instruct PHPExcel to add a summary below the collapsible rows (default), or above. The following code adds the summary above: - -$objPHPExcel->getActiveSheet()->setShowSummaryBelow(false); - -### Merge/unmerge cells - -If you have a big piece of data you want to display in a worksheet, you can merge two or more cells together, to become one cell. This can be done using the following code: - -$objPHPExcel->getActiveSheet()->mergeCells('A18:E22'); - -Removing a merge can be done using the unmergeCells method: - -$objPHPExcel->getActiveSheet()->unmergeCells('A18:E22'); - -### Inserting rows/columns - -You can insert/remove rows/columns at a specific position. The following code inserts 2 new rows, right before row 7: - -$objPHPExcel->getActiveSheet()->insertNewRowBefore(7, 2); - -### Add a drawing to a worksheet - -A drawing is always represented as a separate object, which can be added to a worksheet. Therefore, you must first instantiate a new PHPExcel_Worksheet_Drawing, and assign its properties a meaningful value: - -$objDrawing = new PHPExcel_Worksheet_Drawing(); - -$objDrawing->setName('Logo'); - -$objDrawing->setDescription('Logo'); - -$objDrawing->setPath('./images/officelogo.jpg'); - -$objDrawing->setHeight(36); - -To add the above drawing to the worksheet, use the following snippet of code. PHPExcel creates the link between the drawing and the worksheet: - -$objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); - -You can set numerous properties on a drawing, here are some examples: - -$objDrawing->setName('Paid'); - -$objDrawing->setDescription('Paid'); - -$objDrawing->setPath('./images/paid.png'); - -$objDrawing->setCoordinates('B15'); - -$objDrawing->setOffsetX(110); - -$objDrawing->setRotation(25); - -$objDrawing->getShadow()->setVisible(true); - -$objDrawing->getShadow()->setDirection(45); - -You can also add images created using GD functions without needing to save them to disk first as In-Memory drawings. - -// Use GD to create an in-memory image - -$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream'); - -$textColor = imagecolorallocate($gdImage, 255, 255, 255); - -imagestring($gdImage, 1, 5, 5, 'Created with PHPExcel', $textColor); - -// Add the In-Memory image to a worksheet - -$objDrawing = new PHPExcel_Worksheet_MemoryDrawing(); - -$objDrawing->setName('In-Memory image 1'); - -$objDrawing->setDescription('In-Memory image 1'); - -$objDrawing->setCoordinates('A1'); - -$objDrawing->setImageResource($gdImage); - -$objDrawing->setRenderingFunction( - -PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG - -); - -$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT); - -$objDrawing->setHeight(36); - -$objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); - -### Reading Images from a worksheet - -A commonly asked question is how to retrieve the images from a workbook that has been loaded, and save them as individual image files to disk. - -The following code extracts images from the current active worksheet, and writes each as a separate file. - -$i = 0; - -foreach ($objPHPExcel->getActiveSheet()->getDrawingCollection() as $drawing) { - -if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { - -ob_start(); - -call_user_func( - -$drawing->getRenderingFunction(), - -$drawing->getImageResource() - -); - -$imageContents = ob_get_contents(); - -ob_end_clean(); - -switch ($drawing->getMimeType()) { - -case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG : - -$extension = 'png'; break; - -case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_GIF: - -$extension = 'gif'; break; - -case PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG : - -$extension = 'jpg'; break; - -} - -} else { - -$zipReader = fopen($drawing->getPath(),'r'); - -$imageContents = ''; - -while (!feof($zipReader)) { - -$imageContents .= fread($zipReader,1024); - -} - -fclose($zipReader); - -$extension = $drawing->getExtension(); - -} - -$myFileName = '00_Image_'.++$i.'.'.$extension; - -file_put_contents($myFileName,$imageContents); - -} - -### Add rich text to a cell - -Adding rich text to a cell can be done using PHPExcel_RichText instances. Here’s an example, which creates the following rich text string: - -This invoice is *__payable within thirty days after the end of the month__* unless specified otherwise on the invoice. - -$objRichText = new PHPExcel_RichText(); - -$objRichText->createText('This invoice is '); - -$objPayable = $objRichText->createTextRun('payable within thirty days after the end of the month'); - -$objPayable->getFont()->setBold(true); - -$objPayable->getFont()->setItalic(true); - -$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) ); - -$objRichText->createText(', unless specified otherwise on the invoice.'); - -$objPHPExcel->getActiveSheet()->getCell('A18')->setValue($objRichText); - -### Define a named range - -PHPExcel supports the definition of named ranges. These can be defined using the following code: - -// Add some data - -$objPHPExcel->setActiveSheetIndex(0); - -$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:'); - -$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Lastname:'); - -$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Maarten'); - -$objPHPExcel->getActiveSheet()->setCellValue('B2', 'Balliauw'); - -// Define named ranges - -$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonFN', $objPHPExcel->getActiveSheet(), 'B1') ); - -$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonLN', $objPHPExcel->getActiveSheet(), 'B2') ); - -Optionally, a fourth parameter can be passed defining the named range local (i.e. only usable on the current worksheet). Named ranges are global by default. - -### Redirect output to a client’s web browser - -Sometimes, one really wants to output a file to a client’s browser, especially when creating spreadsheets on-the-fly. There are some easy steps that can be followed to do this: - -Create your PHPExcel spreadsheetOutput HTTP headers for the type of document you wish to outputUse the PHPExcel_Writer_* of your choice, and save to “php://output”PHPExcel_Writer_Excel2007 uses temporary storage when writing to php://output. By default, temporary files are stored in the script’s working directory. When there is no access, it falls back to the operating system’s temporary files location. - -__This may not be safe for unauthorized viewing!__ -Depending on the configuration of your operating system, temporary storage can be read by anyone using the same temporary storage folder. When confidentiality of your document is needed, it is recommended not to use php://output. - -#### HTTP headers - -Example of a script redirecting an Excel 2007 file to the client's browser: - -save('php://output'); - -?> - -Example of a script redirecting an Excel5 file to the client's browser: - -save('php://output'); - -?> - -Caution: - -Make sure not to include any echo statements or output any other contents than the Excel file. There should be no whitespace before the opening tag (which can also be omitted to avoid problems).Make sure that your script is saved without a BOM (Byte-order mark). (Because this counts as echoing output)Same things apply to all included filesFailing to follow the above guidelines may result in corrupt Excel files arriving at the client browser, and/or that headers cannot be set by PHP (resulting in warning messages). - -### Setting the default column width - -Default column width can be set using the following code: - -$objPHPExcel->getActiveSheet()->getDefaultColumnDimension()->setWidth(12); - -### Setting the default row height - -Default row height can be set using the following code: - -$objPHPExcel->getActiveSheet()->getDefaultRowDimension()->setRowHeight(15); - -### Add a GD drawing to a worksheet - -There might be a situation where you want to generate an in-memory image using GD and add it to a PHPExcel worksheet without first having to save this file to a temporary location. - -Here’s an example which generates an image in memory and adds it to the active worksheet: - -// Generate an image - -$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream'); - -$textColor = imagecolorallocate($gdImage, 255, 255, 255); - -imagestring($gdImage, 1, 5, 5, 'Created with PHPExcel', $textColor); - -// Add a drawing to the worksheet - -$objDrawing = new PHPExcel_Worksheet_MemoryDrawing(); - -$objDrawing->setName('Sample image'); - -$objDrawing->setDescription('Sample image'); - -$objDrawing->setImageResource($gdImage); - -$objDrawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); - -$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT); - -$objDrawing->setHeight(36); - -$objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); - -### Setting worksheet zoom level - -To set a worksheet’s zoom level, the following code can be used: - -$objPHPExcel->getActiveSheet()->getSheetView()->setZoomScale(75); - -Note that zoom level should be in range 10 – 400. - -### Sheet tab color - -Sometimes you want to set a color for sheet tab. For example you can have a red sheet tab: - -$objWorksheet->getTabColor()->setRGB('FF0000'); - -### Creating worksheets in a workbook - -If you need to create more worksheets in the workbook, here is how: - -$objWorksheet1 = $objPHPExcel->createSheet(); - -$objWorksheet1->setTitle('Another sheet'); - -Think of createSheet() as the "Insert sheet" button in Excel. When you hit that button a new sheet is appended to the existing collection of worksheets in the workbook.### Hidden worksheets (Sheet states) - -Set a worksheet to be __hidden__ using this code: - -$objPHPExcel->getActiveSheet() - -->setSheetState(PHPExcel_Worksheet::SHEETSTATE_HIDDEN); - -Sometimes you may even want the worksheet to be __“very hidden”__. The available sheet states are : - -PHPExcel_Worksheet::SHEETSTATE_VISIBLE - -PHPExcel_Worksheet::SHEETSTATE_HIDDEN - -PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN - -In Excel the sheet state “very hidden” can only be set programmatically, e.g. with Visual Basic Macro. It is not possible to make such a sheet visible via the user interface.### Right-to-left worksheet - -Worksheets can be set individually whether column ‘A’ should start at left or right side. Default is left. Here is how to set columns from right-to-left. - -// right-to-left worksheet - -$objPHPExcel->getActiveSheet() - -->setRightToLeft(true); - -# Performing formula calculations - ## Using the PHPExcel calculation engine +### Performing formula calculations + As PHPExcel represents an in-memory spreadsheet, it also offers formula calculation capabilities. A cell can be of a value type (containing a number or text), or a formula type (containing a formula which can be evaluated). For example, the formula "=SUM(A1:A10)" evaluates to the sum of values in A1, A2, ..., A10. To calculate a formula, you can call the cell containing the formula’s method getCalculatedValue(), for example: @@ -1611,7 +28,7 @@ Did you notice? The formula in the former cell E11 (now E13, as I inserted 2 new ## Known limitations -There are some known limitations to the PHPExcel calculation engine. Most of them are due to the fact that an Excel formula is converted into PHP code before being executed. This means that Excel formula calculation is subject to PHP’s language characteristics. +There are some known limitations to the PHPExcel calculation engine. Most of them are due to the fact that an Excel formula is converted into PHP code before being executed. This means that Excel formula calculation is subject to PHP's language characteristics. ### Operator precedence @@ -1629,17 +46,17 @@ Reference for this behaviour in PHP: [http://be.php.net/manual/en/language.types.string.php#language.types.string.conversion][20] -# Reading and writing to file +## Reading and writing to file As you already know from part REF _Ref191885438 \w \h 3.3 REF _Ref191885438 \h Readers and writers, reading and writing to a persisted storage is not possible using the base PHPExcel classes. For this purpose, PHPExcel provides readers and writers, which are implementations of PHPExcel_Writer_IReader and PHPExcel_Writer_IWriter. -## PHPExcel_IOFactory +### PHPExcel_IOFactory The PHPExcel API offers multiple methods to create a PHPExcel_Writer_IReader or PHPExcel_Writer_IWriter instance: Direct creationVia PHPExcel_IOFactoryAll examples underneath demonstrate the direct creation method. Note that you can also use the PHPExcel_IOFactory class to do this. -### Creating PHPExcel_Reader_IReader using PHPExcel_IOFactory +#### Creating PHPExcel_Reader_IReader using PHPExcel_IOFactory There are 2 methods for reading in a file into PHPExcel: using automatic file type resolving or explicitly. @@ -1666,20 +83,20 @@ $objPHPExcel = $objReader->load("05featuredemo.xlsx"); Note that automatic type resolving mode is slightly slower than explicit mode. -### Creating PHPExcel_Writer_IWriter using PHPExcel_IOFactory +#### Creating PHPExcel_Writer_IWriter using PHPExcel_IOFactory You can create a PHPExcel_Writer_Iwriter instance using PHPExcel_IOFactory: $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007"); $objWriter->save("05featuredemo.xlsx"); -## Excel 2007 (SpreadsheetML) file format +### Excel 2007 (SpreadsheetML) file format Excel2007 file format is the main file format of PHPExcel. It allows outputting the in-memory spreadsheet to a .xlsx file. -### PHPExcel_Reader_Excel2007 +#### PHPExcel_Reader_Excel2007 -#### Reading a spreadsheet +##### Reading a spreadsheet You can read an .xlsx file using the following code: @@ -1687,7 +104,7 @@ $objReader = new PHPExcel_Reader_Excel2007(); $objPHPExcel = $objReader->load("05featuredemo.xlsx"); -#### Read data only +##### Read data only You can set the option setReadDataOnly on the reader, to instruct the reader to ignore styling, data validation, … and just read cell data: @@ -1697,7 +114,7 @@ $objReader->setReadDataOnly(true); $objPHPExcel = $objReader->load("05featuredemo.xlsx"); -#### Read specific sheets only +##### Read specific sheets only You can set the option setLoadSheetsOnly on the reader, to instruct the reader to only load the sheets with a given name: @@ -1707,7 +124,7 @@ $objReader->setLoadSheetsOnly( array("Sheet 1", "My special sheet") ); $objPHPExcel = $objReader->load("05featuredemo.xlsx"); -#### Read specific cells only +##### Read specific cells only You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. @@ -1738,9 +155,9 @@ $objReader = new PHPExcel_Reader_Excel2007(); $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.xlsx"); -### PHPExcel_Writer_Excel2007 +#### PHPExcel_Writer_Excel2007 -#### Writing a spreadsheet +##### Writing a spreadsheet You can write an .xlsx file using the following code: @@ -1748,7 +165,7 @@ $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); $objWriter->save("05featuredemo.xlsx"); -#### Formula pre-calculation +##### Formula pre-calculation By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation: @@ -1757,7 +174,7 @@ $objWriter->setPreCalculateFormulas(false); $objWriter->save("05featuredemo.xlsx"); -#### Office 2003 compatibility pack +##### Office 2003 compatibility pack Because of a bug in the Office2003 compatibility pack, there can be some small issues when opening Excel2007 spreadsheets (mostly related to formula calculation). You can enable Office2003 compatibility with the following code: @@ -1769,7 +186,7 @@ $objWriter->save("05featuredemo.xlsx"); __Office2003 compatibility should only be used when needed__ Office2003 compatibility option should only be used when needed. This option disables several Office2007 file format options, resulting in a lower-featured Office2007 spreadsheet when this option is used. -## Excel 5 (BIFF) file format +### Excel 5 (BIFF) file format Excel5 file format is the old Excel file format, implemented in PHPExcel to provide a uniform manner to create both .xlsx and .xls files. It is basically a modified version of [PEAR Spreadsheet_Excel_Writer][21], although it has been extended and has fewer limitations and more features than the old PEAR library. This can read all BIFF versions that use OLE2: BIFF5 (introduced with office 95) through BIFF8, but cannot read earlier versions. @@ -1778,9 +195,9 @@ Excel5 file format will not be developed any further, it just provides an additi __Excel5 (BIFF) limitations__ Please note that BIFF file format has some limits regarding to styling cells and handling large spreadsheets via PHP. -### PHPExcel_Reader_Excel5 +#### PHPExcel_Reader_Excel5 -#### Reading a spreadsheet +##### Reading a spreadsheet You can read an .xls file using the following code: @@ -1788,7 +205,7 @@ $objReader = new PHPExcel_Reader_Excel5(); $objPHPExcel = $objReader->load("05featuredemo.xls"); -#### Read data only +##### Read data only You can set the option setReadDataOnly on the reader, to instruct the reader to ignore styling, data validation, … and just read cell data: @@ -1798,7 +215,7 @@ $objReader->setReadDataOnly(true); $objPHPExcel = $objReader->load("05featuredemo.xls"); -#### Read specific sheets only +##### Read specific sheets only You can set the option setLoadSheetsOnly on the reader, to instruct the reader to only load the sheets with a given name: @@ -1808,7 +225,7 @@ $objReader->setLoadSheetsOnly( array("Sheet 1", "My special sheet") ); $objPHPExcel = $objReader->load("05featuredemo.xls"); -#### Read specific cells only +##### Read specific cells only You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. @@ -1839,9 +256,9 @@ $objReader = new PHPExcel_Reader_Excel5(); $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.xls"); -### PHPExcel_Writer_Excel5 +#### PHPExcel_Writer_Excel5 -#### Writing a spreadsheet +##### Writing a spreadsheet You can write an .xls file using the following code: @@ -1849,16 +266,16 @@ $objWriter = new PHPExcel_Writer_Excel5($objPHPExcel); $objWriter->save("05featuredemo.xls"); -## Excel 2003 XML file format +### Excel 2003 XML file format Excel 2003 XML file format is a file format which can be used in older versions of Microsoft Excel. __Excel 2003 XML limitations__ Please note that Excel 2003 XML format has some limits regarding to styling cells and handling large spreadsheets via PHP. -### PHPExcel_Reader_Excel2003XML +#### PHPExcel_Reader_Excel2003XML -#### Reading a spreadsheet +##### Reading a spreadsheet You can read an .xml file using the following code: @@ -1866,7 +283,7 @@ $objReader = new PHPExcel_Reader_Excel2003XML(); $objPHPExcel = $objReader->load("05featuredemo.xml"); -#### Read specific cells only +##### Read specific cells only You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. @@ -1897,16 +314,16 @@ $objReader = new PHPExcel_Reader_Excel2003XML(); $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.xml"); -## Symbolic LinK (SYLK) +### Symbolic LinK (SYLK) Symbolic Link (SYLK) is a Microsoft file format typically used to exchange data between applications, specifically spreadsheets. SYLK files conventionally have a .slk suffix. Composed of only displayable ANSI characters, it can be easily created and processed by other applications, such as databases. __SYLK limitations__ Please note that SYLK file format has some limits regarding to styling cells and handling large spreadsheets via PHP. -### PHPExcel_Reader_SYLK +#### PHPExcel_Reader_SYLK -#### Reading a spreadsheet +##### Reading a spreadsheet You can read an .slk file using the following code: @@ -1914,7 +331,7 @@ $objReader = new PHPExcel_Reader_SYLK(); $objPHPExcel = $objReader->load("05featuredemo.slk"); -#### Read specific cells only +##### Read specific cells only You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. @@ -1945,13 +362,13 @@ $objReader = new PHPExcel_Reader_SYLK(); $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.slk"); -## Open/Libre Office (.ods) +### Open/Libre Office (.ods) Open Office or Libre Office .ods files are the standard file format fopr Open Office or Libre Office Calc files. -### PHPExcel_Reader_OOCalc +#### PHPExcel_Reader_OOCalc -#### Reading a spreadsheet +##### Reading a spreadsheet You can read an .ods file using the following code: @@ -1959,7 +376,7 @@ $objReader = new PHPExcel_Reader_OOCalc(); $objPHPExcel = $objReader->load("05featuredemo.ods"); -#### Read specific cells only +##### Read specific cells only You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. @@ -1990,218 +407,247 @@ $objReader = new PHPExcel_Reader_OOcalc(); $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.ods"); -## CSV (Comma Separated Values) +### CSV (Comma Separated Values) CSV (Comma Separated Values) are often used as an import/export file format with other systems. PHPExcel allows reading and writing to CSV files. __CSV limitations__ Please note that CSV file format has some limits regarding to styling cells, number formatting, … -### PHPExcel_Reader_CSV +#### PHPExcel_Reader_CSV -#### Reading a CSV file +##### Reading a CSV file You can read a .csv file using the following code: +```php $objReader = new PHPExcel_Reader_CSV(); $objPHPExcel = $objReader->load("sample.csv"); +``` -#### Setting CSV options +##### Setting CSV options Often, CSV files are not really “comma separated”, or use semicolon (;) as a separator. You can instruct PHPExcel_Reader_CSV some options before reading a CSV file. Note that PHPExcel_Reader_CSV by default assumes that the loaded CSV file is UTF-8 encoded. If you are reading CSV files that were created in Microsoft Office Excel the correct input encoding may rather be Windows-1252 (CP1252). Always make sure that the input encoding is set appropriately. +```php $objReader = new PHPExcel_Reader_CSV(); $objReader->setInputEncoding('CP1252'); - $objReader->setDelimiter(';'); - $objReader->setEnclosure(''); - $objReader->setLineEnding("\r\n"); $objReader->setSheetIndex(0); $objPHPExcel = $objReader->load("sample.csv"); +``` -#### Read a specific worksheet +##### Read a specific worksheet CSV files can only contain one worksheet. Therefore, you can specify which sheet to read from CSV: +```php $objReader->setSheetIndex(0); +``` -#### Read into existing spreadsheet +##### Read into existing spreadsheet When working with CSV files, it might occur that you want to import CSV data into an existing PHPExcel object. The following code loads a CSV file into an existing $objPHPExcel containing some sheets, and imports onto the 6th sheet: +```php $objReader = new PHPExcel_Reader_CSV(); $objReader->setDelimiter(';'); - $objReader->setEnclosure(''); - $objReader->setLineEnding("\r\n"); $objReader->setSheetIndex(5); + $objReader->loadIntoExisting("05featuredemo.csv", $objPHPExcel); +``` -### PHPExcel_Writer_CSV +#### PHPExcel_Writer_CSV -#### Writing a CSV file +##### Writing a CSV file You can write a .csv file using the following code: +```php $objWriter = new PHPExcel_Writer_CSV($objPHPExcel); $objWriter->save("05featuredemo.csv"); +``` -#### Setting CSV options +##### Setting CSV options Often, CSV files are not really “comma separated”, or use semicolon (;) as a separator. You can instruct PHPExcel_Writer_CSV some options before writing a CSV file: +```php $objWriter = new PHPExcel_Writer_CSV($objPHPExcel); $objWriter->setDelimiter(';'); - $objWriter->setEnclosure(''); - $objWriter->setLineEnding("\r\n"); $objWriter->setSheetIndex(0); $objWriter->save("05featuredemo.csv"); +``` -#### Write a specific worksheet +##### Write a specific worksheet CSV files can only contain one worksheet. Therefore, you can specify which sheet to write to CSV: +```php $objWriter->setSheetIndex(0); +``` -#### Formula pre-calculation +##### Formula pre-calculation By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation: +```php $objWriter = new PHPExcel_Writer_CSV($objPHPExcel); $objWriter->setPreCalculateFormulas(false); - $objWriter->save("05featuredemo.csv"); +``` -#### Writing UTF-8 CSV files +##### Writing UTF-8 CSV files A CSV file can be marked as UTF-8 by writing a BOM file header. This can be enabled by using the following code: +```php $objWriter = new PHPExcel_Writer_CSV($objPHPExcel); $objWriter->setUseBOM(true); - $objWriter->save("05featuredemo.csv"); +``` -#### Decimal and thousands separators +##### Decimal and thousands separators If the worksheet you are exporting contains numbers with decimal or thousands separators then you should think about what characters you want to use for those before doing the export. -By default PHPExcel looks up in the server’s locale settings to decide what characters to use. But to avoid problems it is recommended to set the characters explicitly as shown below. +By default PHPExcel looks up in the server's locale settings to decide what characters to use. But to avoid problems it is recommended to set the characters explicitly as shown below. English users will want to use this before doing the export: -require_once 'PHPExcel/Shared/String.php' - +```php PHPExcel_Shared_String::setDecimalSeparator('.'); - PHPExcel_Shared_String::setThousandsSeparator(','); +``` German users will want to use the opposite values. -require_once 'PHPExcel/Shared/String.php' - +```php PHPExcel_Shared_String::setDecimalSeparator(','); - PHPExcel_Shared_String::setThousandsSeparator('.'); +``` Note that the above code sets decimal and thousand separators as global options. This also affects how HTML and PDF is exported. -## HTML +### HTML PHPExcel allows you to read or write a spreadsheet as HTML format, for quick representation of the data in it to anyone who does not have a spreadsheet application on their PC, or loading files saved by other scripts that simply create HTML markup and give it a .xls file extension. __HTML limitations__ -Please note that HTML file format has some limits regarding to styling cells, number formatting, … +Please note that HTML file format has some limits regarding to styling cells, number formatting, ... -### PHPExcel_Reader_HTML +#### PHPExcel_Reader_HTML -#### Reading a spreadsheet +##### Reading a spreadsheet You can read an .html or .htm file using the following code: +```php $objReader = new PHPExcel_Reader_HTML(); $objPHPExcel = $objReader->load("05featuredemo.html"); +``` __HTML limitations__ Please note that HTML reader is still experimental and does not yet support merged cells or nested tables cleanly -### PHPExcel_Writer_HTML +#### PHPExcel_Writer_HTML Please note that PHPExcel_Writer_HTML only outputs the first worksheet by default. -#### Writing a spreadsheet +##### Writing a spreadsheet You can write a .htm file using the following code: +```php $objWriter = new PHPExcel_Writer_HTML($objPHPExcel); $objWriter->save("05featuredemo.htm"); +``` -#### Write all worksheets +##### Write all worksheets HTML files can contain one or more worksheets. If you want to write all sheets into a single HTML file, use the following code: +```php $objWriter->writeAllSheets(); +``` -#### Write a specific worksheet +##### Write a specific worksheet HTML files can contain one or more worksheets. Therefore, you can specify which sheet to write to HTML: +```php $objWriter->setSheetIndex(0); +``` -#### Setting the images root of the HTML file +##### Setting the images root of the HTML file -There might be situations where you want to explicitly set the included images root. For example, one might want to see instead of . +There might be situations where you want to explicitly set the included images root. For example, one might want to see +```html + +``` + +instead of + +```html +. +``` You can use the following code to achieve this result: +```php $objWriter->setImagesRoot('http://www.example.com/'); +``` -#### Formula pre-calculation +##### Formula pre-calculation By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation: +```php $objWriter = new PHPExcel_Writer_HTML($objPHPExcel); $objWriter->setPreCalculateFormulas(false); $objWriter->save("05featuredemo.htm"); +``` -#### Embedding generated HTML in a web page +##### Embedding generated HTML in a web page There might be a situation where you want to embed the generated HTML in an existing website. PHPExcel_Writer_HTML provides support to generate only specific parts of the HTML code, which allows you to use these parts in your website. Supported methods: -generateHTMLHeader()generateStyles()generateSheetData()generateHTMLFooter()Here’s an example which retrieves all parts independently and merges them into a resulting HTML page: + - generateHTMLHeader() + - generateStyles() + - generateSheetData() + - generateHTMLFooter() +Here's an example which retrieves all parts independently and merges them into a resulting HTML page: + +```php generateHTMLHeader(); ?> ?> --> - generateSheetData(); echo $objWriter->generateHTMLFooter(); ?> +``` -#### Writing UTF-8 HTML files +##### Writing UTF-8 HTML files A HTML file can be marked as UTF-8 by writing a BOM file header. This can be enabled by using the following code: +```php $objWriter = new PHPExcel_Writer_HTML($objPHPExcel); $objWriter->setUseBOM(true); $objWriter->save("05featuredemo.htm"); +``` -#### Decimal and thousands separators +##### Decimal and thousands separators See section PHPExcel_Writer_CSV how to control the appearance of these. -## PDF +### PDF PHPExcel allows you to write a spreadsheet into PDF format, for fast distribution of represented data. __PDF limitations__ -Please note that PDF file format has some limits regarding to styling cells, number formatting, … +Please note that PDF file format has some limits regarding to styling cells, number formatting, ... -### PHPExcel_Writer_PDF +#### PHPExcel_Writer_PDF PHPExcel’s PDF Writer is a wrapper for a 3rd-Party PDF Rendering library such as tcPDF, mPDF or DomPDF. Prior to version 1.7.8 of PHPExcel, the tcPDF library was bundled with PHPExcel; but from version 1.7.8 this was removed. Instead, you must now install a PDF Rendering library yourself; but PHPExcel will work with a number of different libraries. Currently, the following libraries are supported: -__Library__ - -__Version used for testing__ - -__Downloadable from__ - -__PHPExcel Internal Constant__ - -tcPDF - -5.9 - -http://www.tcpdf.org/ - -PDF_RENDERER_TCPDF - -mPDF - -5.4 - -http://www.mpdf1.com/mpdf/ - -PDF_RENDERER_MPDF - -domPDF - -0.6.0 beta 3 - -http://code.google.com/p/dompdf/ - -PDF_RENDERER_DOMPDF +Library | Version used for testing | Downloadable from | PHPExcel Internal Constant +--------|--------------------------|----------------------------------|---------------------------- +tcPDF | 5.9 | http://www.tcpdf.org/ | PDF_RENDERER_TCPDF +mPDF | 5.4 | http://www.mpdf1.com/mpdf/ | PDF_RENDERER_MPDF +domPDF | 0.6.0 beta 3 | http://code.google.com/p/dompdf/ | PDF_RENDERER_DOMPDF The different libraries have different strengths and weaknesses. Some generate better formatted output than others, some are faster or use less memory than others, while some generate smaller .pdf files. It is the developers choice which one they wish to use, appropriate to their own circumstances. Before instantiating a Writer to generate PDF output, you will need to indicate which Rendering library you are using, and where it is located. +```php $rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF; - $rendererLibrary = 'mPDF5.4'; - $rendererLibraryPath = dirname(__FILE__).'/../../../libraries/PDF/' . $rendererLibrary; if (!PHPExcel_Settings::setPdfRenderer( - -$rendererName, - -$rendererLibraryPath - -)) { - -die( - -'Please set the $rendererName and $rendererLibraryPath values' . - -PHP_EOL . - -' as appropriate for your directory structure' - -); - + $rendererName, + $rendererLibraryPath + )) { + die( + 'Please set the $rendererName and $rendererLibraryPath values' . + PHP_EOL . + ' as appropriate for your directory structure' + ); } +``` -#### Writing a spreadsheet +##### Writing a spreadsheet Once you have identified the Renderer that you wish to use for PDF generation, you can write a .pdf file using the following code: +```php $objWriter = new PHPExcel_Writer_PDF($objPHPExcel); - $objWriter->save("05featuredemo.pdf"); +``` Please note that PHPExcel_Writer_PDF only outputs the first worksheet by default. -#### Write all worksheets +##### Write all worksheets PDF files can contain one or more worksheets. If you want to write all sheets into a single PDF file, use the following code: +```php $objWriter->writeAllSheets(); +``` -#### Write a specific worksheet +##### Write a specific worksheet PDF files can contain one or more worksheets. Therefore, you can specify which sheet to write to PDF: +```php $objWriter->setSheetIndex(0); +``` -#### Formula pre-calculation +##### Formula pre-calculation By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation: +```php $objWriter = new PHPExcel_Writer_PDF($objPHPExcel); $objWriter->setPreCalculateFormulas(false); $objWriter->save("05featuredemo.pdf"); +``` -#### Decimal and thousands separators +##### Decimal and thousands separators See section PHPExcel_Writer_CSV how to control the appearance of these. -## Generating Excel files from templates (read, modify, write) +### Generating Excel files from templates (read, modify, write) Readers and writers are the tools that allow you to generate Excel files from templates. This requires less coding effort than generating the Excel file from scratch, especially if your template has many styles, page setup properties, headers etc. Here is an example how to open a template file, fill in a couple of fields and save it again: +```php $objPHPexcel = PHPExcel_IOFactory::load('template.xlsx'); $objWorksheet = $objPHPexcel->getActiveSheet(); $objWorksheet->getCell('A1')->setValue('John'); - $objWorksheet->getCell('A2')->setValue('Smith'); $objWriter = PHPExcel_IOFactory::createWriter($objPHPexcel, 'Excel5'); - $objWriter->save('write.xls'); +``` Notice that it is ok to load an xlsx file and generate an xls file. -# Credits +## Credits Please refer to the internet page [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home][22] for up-to-date credits. -# Valid array keys for style applyFromArray() +## Valid array keys for style applyFromArray() -The following table lists the valid array keys for PHPExcel_Style applyFromArray() classes. If the “Maps to property” column maps a key to a setter, the value provided for that key will be applied directly. If the “Maps to property” column maps a key to a getter, the value provided for that key will be applied as another style array. +The following table lists the valid array keys for PHPExcel_Style applyFromArray() classes. If the "Maps to property"� column maps a key to a setter, the value provided for that key will be applied directly. If the "Maps to property" column maps a key to a getter, the value provided for that key will be applied as another style array. __PHPExcel_Style__ -Array key: - -Maps to property: - -fill - -font - -borders - -alignment - -numberformat - -protection + Array key | Maps to property + -------------|------------------- + fill | getFill() + font | getFont() + borders | getBorders() + alignment | getAlignment() + numberformat | getNumberFormat() + protection | getProtection() -getFill() -getFont() -getBorders() -getAlignment() -getNumberFormat() -getProtection() - __PHPExcel_Style_Fill__ -Array key: - -Maps to property: - -type -rotation -startcolor -endcolor -color - + Array key | Maps to property + -----------|------------------- + type | setFillType() + rotation | setRotation() + startcolor | getStartColor() + endcolor | getEndColor() + color | getStartColor() -setFillType() -setRotation() -getStartColor() -getEndColor() -getStartColor() __PHPExcel_Style_Font__ -Array key: + Array key | Maps to property + ------------|------------------- + name | setName() + bold | setBold() + italic | setItalic() + underline | setUnderline() + strike | setStrikethrough() + color | getColor() + size | setSize() + superScript | setSuperScript() + subScript | setSubScript() -Maps to property: - -name -bold -italic -underline -strike -color -size -superScript -subScript - - -setName() -setBold() -setItalic() -setUnderline() -setStrikethrough() -getColor() -setSize() -setSuperScript() -setSubScript() __PHPExcel_Style_Borders__ -Array key: - -Maps to property: + Array key | Maps to property + ------------------|------------------- + allborders | getLeft(); getRight(); getTop(); getBottom() + left | getLeft() + right | getRight() + top | getTop() + bottom | getBottom() + diagonal | getDiagonal() + vertical | getVertical() + horizontal | getHorizontal() + diagonaldirection | setDiagonalDirection() + outline | setOutline() -allborders -left -right -top -bottom -diagonal -vertical -horizontal -diagonaldirection -outline - - -getLeft(); getRight(); getTop(); getBottom() -getLeft() -getRight() -getTop() -getBottom() - -getDiagonal() -getVertical() -getHorizontal() -setDiagonalDirection() -setOutline() __PHPExcel_Style_Border__ -Array key: - -Maps to property: + Array key | Maps to property + ----------|------------------- + style | setBorderStyle() + color | getColor() -style -color - - -setBorderStyle() -getColor() __PHPExcel_Style_Alignment__ -Array key: - -Maps to property: - -horizontal -vertical -rotation -wrap -shrinkToFit -indent + Array key | Maps to property + ------------|------------------- + horizontal | setHorizontal() + vertical | setVertical() + rotation | setTextRotation() + wrap | setWrapText() + shrinkToFit | setShrinkToFit() + indent | setIndent() -setHorizontal() -setVertical() -setTextRotation() -setWrapText() -setShrinkToFit() -setIndent() - __PHPExcel_Style_NumberFormat__ -Array key: - -Maps to property: - -code - + Array key | Maps to property + ----------|------------------- + code | setFormatCode() -setFormatCode() __PHPExcel_Style_Protection__ -Array key: - -Maps to property: - -locked -hidden - - -setLocked() -setHidden() + Array key | Maps to property + ----------|------------------- + locked | setLocked() + hidden | setHidden() - [2]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Documents&referringTitle=Home - [3]: http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm - [4]: http://openxmldeveloper.org/articles/1970.aspx - [5]: http://www.microsoft.com/downloads/details.aspx?familyid=941b3470-3ae9-4aee-8f43-c6bb74cd1466&displaylang=en - [6]: http://www.codeplex.com/PackageExplorer/ - [7]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=FAQ&referringTitle=Requirements - [8]: http://snaps.php.net/win32/php5.2-win32-latest.zip - [9]: http://phpexcel.codeplex.com/Thread/View.aspx?ThreadId=234150 - [10]: http://phpexcel.codeplex.com/Thread/View.aspx?ThreadId=242712 - [11]: http://http:/forum.joomla.org/viewtopic.php?f=304&t=433060 - [12]: http://www.yiiframework.com/wiki/101/how-to-use-phpexcel-external-library-with-yii/ - [13]: http://bakery.cakephp.org/articles/melgior/2010/01/26/simple-excel-spreadsheet-helper - [14]: http://www.flynsarmy.com/2010/07/phpexcel-module-for-kohana-3/ - [15]: http://szpargalki.blogspot.com/2011/02/phpexcel-kohana-framework.html - [16]: http://typo3.org/documentation/document-library/extension-manuals/phpexcel_library/1.1.1/view/toc/0/ - [17]: http://phpexcel.codeplex.com/discussions/211925 - [18]: http://g-ernaelsten.developpez.com/tutoriels/excel2007/ - [19]: http://journal.mycom.co.jp/articles/2009/03/06/phpexcel/index.html [20]: http://be.php.net/manual/en/language.types.string.php#language.types.string.conversion [21]: http://pear.php.net/package/Spreadsheet_Excel_Writer [22]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home diff --git a/Documentation/markdown/Overview/images/08-cell-comment.png b/Documentation/markdown/Overview/images/08-cell-comment.png new file mode 100644 index 0000000000000000000000000000000000000000..bd8f8e66eef6344d0db52f385801c91d8c4c1c39 GIT binary patch literal 31473 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

RPVEMRpmyUY_2B3R3ou;~q7N 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 G|NjAX=Qhg# literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Overview/images/08-column-width.png b/Documentation/markdown/Overview/images/08-column-width.png new file mode 100644 index 0000000000000000000000000000000000000000..1419943413d6f871c495de1fda642ebd7a9f05c2 GIT binary patch literal 14985 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 F{{RpA=L-M; literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Overview/images/08-page-setup-margins.png b/Documentation/markdown/Overview/images/08-page-setup-margins.png new file mode 100644 index 0000000000000000000000000000000000000000..36e07a9b69aba676926a0dac959a91b399ea5617 GIT binary patch literal 125173 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

NE6V3$KNym{v~)U$gt7Z19s>1cj@gN(q8v(I( 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 LNkvXXu0mjfu6ewA literal 0 HcmV?d00001 diff --git a/Documentation/markdown/Overview/images/08-page-setup-scaling-options.png b/Documentation/markdown/Overview/images/08-page-setup-scaling-options.png new file mode 100644 index 0000000000000000000000000000000000000000..80fb5f00c391d985a94515feb07d92c8a7bfdbad GIT binary patch literal 24136 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⁢+M*--LFW2^S986nA3(;Lx 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 Date: Sat, 18 May 2013 23:22:27 +0100 Subject: [PATCH 078/467] documentation markdown --- .../Overview/09-Calculation-Engine.md | 52 +++ ...developer.md => 10-Reading-and-Writing.md} | 354 +++++------------- .../markdown/Overview/11-Appendices.md | 100 +++++ 3 files changed, 245 insertions(+), 261 deletions(-) create mode 100644 Documentation/markdown/Overview/09-Calculation-Engine.md rename Documentation/markdown/Overview/{developer.md => 10-Reading-and-Writing.md} (76%) create mode 100644 Documentation/markdown/Overview/11-Appendices.md diff --git a/Documentation/markdown/Overview/09-Calculation-Engine.md b/Documentation/markdown/Overview/09-Calculation-Engine.md new file mode 100644 index 000000000..c13a18c6c --- /dev/null +++ b/Documentation/markdown/Overview/09-Calculation-Engine.md @@ -0,0 +1,52 @@ +# PHPExcel Developer Documentation + +## Using the PHPExcel calculation engine + +### Performing formula calculations + +As PHPExcel represents an in-memory spreadsheet, it also offers formula calculation capabilities. A cell can be of a value type (containing a number or text), or a formula type (containing a formula which can be evaluated). For example, the formula "=SUM(A1:A10)" evaluates to the sum of values in A1, A2, ..., A10. + +To calculate a formula, you can call the cell containing the formula’s method getCalculatedValue(), for example: + +```php +$objPHPExcel->getActiveSheet()->getCell('E11')->getCalculatedValue(); +``` +If you write the following line of code in the invoice demo included with PHPExcel, it evaluates to the value "64": + +![09-command-line-calculation.png](./images/09-command-line-calculation.png "") + +Another nice feature of PHPExcel's formula parser, is that it can automatically adjust a formula when inserting/removing rows/columns. Here's an example: + +![09-formula-in-cell-1.png](./images/09-formula-in-cell-1.png "") + +You see that the formula contained in cell E11 is "SUM(E4:E9)". Now, when I write the following line of code, two new product lines are added: + +```php +$objPHPExcel->getActiveSheet()->insertNewRowBefore(7, 2); +``` + +![09-formula-in-cell-2.png](./images/09-formula-in-cell-2.png "") + +Did you notice? The formula in the former cell E11 (now E13, as I inserted 2 new rows), changed to "SUM(E4:E11)". Also, the inserted cells duplicate style information of the previous cell, just like Excel's behaviour. Note that you can both insert rows and columns. + +### Known limitations + +There are some known limitations to the PHPExcel calculation engine. Most of them are due to the fact that an Excel formula is converted into PHP code before being executed. This means that Excel formula calculation is subject to PHP's language characteristics. + +#### Operator precedence + +In Excel '+' wins over '&', just like '*' wins over '+' in ordinary algebra. The former rule is not what one finds using the calculation engine shipped with PHPExcel. + +Reference for operator precedence in Excel: [http://support.microsoft.com/kb/25189][18] + +Reference for operator precedence in PHP: [http://www.php.net/operators][19] + +#### Formulas involving numbers and text + +Formulas involving numbers and text may produce unexpected results or even unreadable file contents. For example, the formula '=3+"Hello "' is expected to produce an error in Excel (#VALUE!). Due to the fact that PHP converts “Hello” to a numeric value (zero), the result of this formula is evaluated as 3 instead of evaluating as an error. This also causes the Excel document being generated as containing unreadable content. + +Reference for this behaviour in PHP: [http://be.php.net/manual/en/language.types.string.php#language.types.string.conversion][20] + + [18]: http://support.microsoft.com/kb/25189 + [19]: http://www.php.net/operators + [20]: http://be.php.net/manual/en/language.types.string.php#language.types.string.conversion diff --git a/Documentation/markdown/Overview/developer.md b/Documentation/markdown/Overview/10-Reading-and-Writing.md similarity index 76% rename from Documentation/markdown/Overview/developer.md rename to Documentation/markdown/Overview/10-Reading-and-Writing.md index ac15747dc..e582352ac 100644 --- a/Documentation/markdown/Overview/developer.md +++ b/Documentation/markdown/Overview/10-Reading-and-Writing.md @@ -1,51 +1,5 @@ # PHPExcel Developer Documentation -## Using the PHPExcel calculation engine - -### Performing formula calculations - -As PHPExcel represents an in-memory spreadsheet, it also offers formula calculation capabilities. A cell can be of a value type (containing a number or text), or a formula type (containing a formula which can be evaluated). For example, the formula "=SUM(A1:A10)" evaluates to the sum of values in A1, A2, ..., A10. - -To calculate a formula, you can call the cell containing the formula’s method getCalculatedValue(), for example: - -$objPHPExcel->getActiveSheet()->getCell('E11')->getCalculatedValue(); - -If you write the following line of code in the invoice demo included with PHPExcel, it evaluates to the value "64": - - - -Another nice feature of PHPExcel's formula parser, is that it can automatically adjust a formula when inserting/removing rows/columns. Here's an example: - - - -You see that the formula contained in cell E11 is "SUM(E4:E9)". Now, when I write the following line of code, two new product lines are added: - -$objPHPExcel->getActiveSheet()->insertNewRowBefore(7, 2); - - - -Did you notice? The formula in the former cell E11 (now E13, as I inserted 2 new rows), changed to "SUM(E4:E11)". Also, the inserted cells duplicate style information of the previous cell, just like Excel's behaviour. Note that you can both insert rows and columns. - -## Known limitations - -There are some known limitations to the PHPExcel calculation engine. Most of them are due to the fact that an Excel formula is converted into PHP code before being executed. This means that Excel formula calculation is subject to PHP's language characteristics. - -### Operator precedence - -In Excel '+' wins over '&', just like '*' wins over '+' in ordinary algebra. The former rule is not what one finds using the calculation engine shipped with PHPExcel. - -Reference for operator precedence in Excel: - -Reference for operator precedence in PHP: - -### Formulas involving numbers and text - -Formulas involving numbers and text may produce unexpected results or even unreadable file contents. For example, the formula '=3+"Hello "' is expected to produce an error in Excel (#VALUE!). Due to the fact that PHP converts “Hello” to a numeric value (zero), the result of this formula is evaluated as 3 instead of evaluating as an error. This also causes the Excel document being generated as containing unreadable content. - -Reference for this behaviour in PHP: - -[http://be.php.net/manual/en/language.types.string.php#language.types.string.conversion][20] - ## Reading and writing to file As you already know from part REF _Ref191885438 \w \h 3.3 REF _Ref191885438 \h Readers and writers, reading and writing to a persisted storage is not possible using the base PHPExcel classes. For this purpose, PHPExcel provides readers and writers, which are implementations of PHPExcel_Writer_IReader and PHPExcel_Writer_IWriter. @@ -64,22 +18,26 @@ Automatic file type resolving checks the different PHPExcel_Reader_IReader distr You can create a PHPExcel_Reader_IReader instance using PHPExcel_IOFactory in automatic file type resolving mode using the following code sample: +```php $objPHPExcel = PHPExcel_IOFactory::load("05featuredemo.xlsx"); +``` A typical use of this feature is when you need to read files uploaded by your users, and you don’t know whether they are uploading xls or xlsx files. If you need to set some properties on the reader, (e.g. to only read data, see more about this later), then you may instead want to use this variant: +```php $objReader = PHPExcel_IOFactory::createReaderForFile("05featuredemo.xlsx"); - $objReader->setReadDataOnly(true); - $objReader->load("05featuredemo.xlsx"); +``` You can create a PHPExcel_Reader_IReader instance using PHPExcel_IOFactory in explicit mode using the following code sample: +```php $objReader = PHPExcel_IOFactory::createReader("Excel2007"); $objPHPExcel = $objReader->load("05featuredemo.xlsx"); +``` Note that automatic type resolving mode is slightly slower than explicit mode. @@ -87,8 +45,10 @@ Note that automatic type resolving mode is slightly slower than explicit mode. You can create a PHPExcel_Writer_Iwriter instance using PHPExcel_IOFactory: +```php $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007"); $objWriter->save("05featuredemo.xlsx"); +``` ### Excel 2007 (SpreadsheetML) file format @@ -100,29 +60,30 @@ Excel2007 file format is the main file format of PHPExcel. It allows outputting You can read an .xlsx file using the following code: +```php $objReader = new PHPExcel_Reader_Excel2007(); - $objPHPExcel = $objReader->load("05featuredemo.xlsx"); +``` ##### Read data only You can set the option setReadDataOnly on the reader, to instruct the reader to ignore styling, data validation, … and just read cell data: +```php $objReader = new PHPExcel_Reader_Excel2007(); - $objReader->setReadDataOnly(true); - $objPHPExcel = $objReader->load("05featuredemo.xlsx"); +``` ##### Read specific sheets only You can set the option setLoadSheetsOnly on the reader, to instruct the reader to only load the sheets with a given name: +```php $objReader = new PHPExcel_Reader_Excel2007(); - $objReader->setLoadSheetsOnly( array("Sheet 1", "My special sheet") ); - $objPHPExcel = $objReader->load("05featuredemo.xlsx"); +``` ##### Read specific cells only @@ -130,30 +91,22 @@ You can set the option setReadFilter on the reader, to instruct the reader to on The following code will only read row 1 and rows 20 – 30 of any sheet in the Excel file: -class MyReadFilter implements PHPExcel_Reader_IReadFilter - -{ - -public function readCell($column, $row, $worksheetName = '') { - -// Read title row and rows 20 - 30 - -if ($row == 1 || ($row >= 20 && $row <= 30)) { - -return true; - -} - -return false; - -} - +```php +class MyReadFilter implements PHPExcel_Reader_IReadFilter { + + public function readCell($column, $row, $worksheetName = '') { + // Read title row and rows 20 - 30 + if ($row == 1 || ($row >= 20 && $row <= 30)) { + return true; + } + return false; + } } $objReader = new PHPExcel_Reader_Excel2007(); - $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.xlsx"); +``` #### PHPExcel_Writer_Excel2007 @@ -161,27 +114,30 @@ $objPHPExcel = $objReader->load("06largescale.xlsx"); You can write an .xlsx file using the following code: +```php $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); - $objWriter->save("05featuredemo.xlsx"); +``` ##### Formula pre-calculation By default, this writer pre-calculates all formulas in the spreadsheet. This can be slow on large spreadsheets, and maybe even unwanted. You can however disable formula pre-calculation: +```php $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); $objWriter->setPreCalculateFormulas(false); - $objWriter->save("05featuredemo.xlsx"); +``` ##### Office 2003 compatibility pack Because of a bug in the Office2003 compatibility pack, there can be some small issues when opening Excel2007 spreadsheets (mostly related to formula calculation). You can enable Office2003 compatibility with the following code: +``` $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); $objWriter->setOffice2003Compatibility(true); - $objWriter->save("05featuredemo.xlsx"); +``` __Office2003 compatibility should only be used when needed__ Office2003 compatibility option should only be used when needed. This option disables several Office2007 file format options, resulting in a lower-featured Office2007 spreadsheet when this option is used. @@ -201,60 +157,53 @@ Please note that BIFF file format has some limits regarding to styling cells and You can read an .xls file using the following code: +```php $objReader = new PHPExcel_Reader_Excel5(); - $objPHPExcel = $objReader->load("05featuredemo.xls"); +``` ##### Read data only You can set the option setReadDataOnly on the reader, to instruct the reader to ignore styling, data validation, … and just read cell data: +```php $objReader = new PHPExcel_Reader_Excel5(); - $objReader->setReadDataOnly(true); - $objPHPExcel = $objReader->load("05featuredemo.xls"); +``` ##### Read specific sheets only You can set the option setLoadSheetsOnly on the reader, to instruct the reader to only load the sheets with a given name: +```php $objReader = new PHPExcel_Reader_Excel5(); - $objReader->setLoadSheetsOnly( array("Sheet 1", "My special sheet") ); - $objPHPExcel = $objReader->load("05featuredemo.xls"); +``` ##### Read specific cells only You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. -The following code will only read row 1 and rows 20 – 30 of any sheet in the Excel file: - -class MyReadFilter implements PHPExcel_Reader_IReadFilter - -{ - -public function readCell($column, $row, $worksheetName = '') { - -// Read title row and rows 20 - 30 - -if ($row == 1 || ($row >= 20 && $row <= 30)) { - -return true; - -} - -return false; - -} +The following code will only read row 1 and rows 20 to 30 of any sheet in the Excel file: +```php +class MyReadFilter implements PHPExcel_Reader_IReadFilter { + + public function readCell($column, $row, $worksheetName = '') { + // Read title row and rows 20 - 30 + if ($row == 1 || ($row >= 20 && $row <= 30)) { + return true; + } + return false; + } } $objReader = new PHPExcel_Reader_Excel5(); - $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.xls"); +``` #### PHPExcel_Writer_Excel5 @@ -262,9 +211,10 @@ $objPHPExcel = $objReader->load("06largescale.xls"); You can write an .xls file using the following code: +```php $objWriter = new PHPExcel_Writer_Excel5($objPHPExcel); - $objWriter->save("05featuredemo.xls"); +``` ### Excel 2003 XML file format @@ -277,42 +227,36 @@ Please note that Excel 2003 XML format has some limits regarding to styling cell ##### Reading a spreadsheet -You can read an .xml file using the following code: +You can read an Excel 2003 .xml file using the following code: +```php $objReader = new PHPExcel_Reader_Excel2003XML(); - $objPHPExcel = $objReader->load("05featuredemo.xml"); +``` ##### Read specific cells only You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. -The following code will only read row 1 and rows 20 – 30 of any sheet in the Excel file: - -class MyReadFilter implements PHPExcel_Reader_IReadFilter - -{ - -public function readCell($column, $row, $worksheetName = '') { - -// Read title row and rows 20 - 30 - -if ($row == 1 || ($row >= 20 && $row <= 30)) { - -return true; - -} +The following code will only read row 1 and rows 20 to 30 of any sheet in the Excel file: -return false; +```php +class MyReadFilter implements PHPExcel_Reader_IReadFilter { -} + public function readCell($column, $row, $worksheetName = '') { + // Read title row and rows 20 - 30 + if ($row == 1 || ($row >= 20 && $row <= 30)) { + return true; + } + return false; + } } $objReader = new PHPExcel_Reader_Excel2003XML(); - $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.xml"); +``` ### Symbolic LinK (SYLK) @@ -327,44 +271,38 @@ Please note that SYLK file format has some limits regarding to styling cells and You can read an .slk file using the following code: +```php $objReader = new PHPExcel_Reader_SYLK(); - $objPHPExcel = $objReader->load("05featuredemo.slk"); +``` ##### Read specific cells only You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. -The following code will only read row 1 and rows 20 – 30 of any sheet in the SYLK file: - -class MyReadFilter implements PHPExcel_Reader_IReadFilter - -{ - -public function readCell($column, $row, $worksheetName = '') { +The following code will only read row 1 and rows 20 to 30 of any sheet in the SYLK file: -// Read title row and rows 20 - 30 - -if ($row == 1 || ($row >= 20 && $row <= 30)) { - -return true; - -} +```php +class MyReadFilter implements PHPExcel_Reader_IReadFilter { -return false; - -} + public function readCell($column, $row, $worksheetName = '') { + // Read title row and rows 20 - 30 + if ($row == 1 || ($row >= 20 && $row <= 30)) { + return true; + } + return false; + } } $objReader = new PHPExcel_Reader_SYLK(); - $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.slk"); +``` ### Open/Libre Office (.ods) -Open Office or Libre Office .ods files are the standard file format fopr Open Office or Libre Office Calc files. +Open Office or Libre Office .ods files are the standard file format for Open Office or Libre Office Calc files. #### PHPExcel_Reader_OOCalc @@ -372,47 +310,41 @@ Open Office or Libre Office .ods files are the standard file format fopr Open Of You can read an .ods file using the following code: +```php $objReader = new PHPExcel_Reader_OOCalc(); - $objPHPExcel = $objReader->load("05featuredemo.ods"); +``` ##### Read specific cells only You can set the option setReadFilter on the reader, to instruct the reader to only load the cells which match a given rule. A read filter can be any class which implements PHPExcel_Reader_IReadFilter. By default, all cells are read using the PHPExcel_Reader_DefaultReadFilter. -The following code will only read row 1 and rows 20 – 30 of any sheet in the Calc file: - -class MyReadFilter implements PHPExcel_Reader_IReadFilter - -{ - -public function readCell($column, $row, $worksheetName = '') { - -// Read title row and rows 20 - 30 - -if ($row == 1 || ($row >= 20 && $row <= 30)) { +The following code will only read row 1 and rows 20 to 30 of any sheet in the Calc file: -return true; - -} - -return false; +```php +class MyReadFilter implements PHPExcel_Reader_IReadFilter { -} + public function readCell($column, $row, $worksheetName = '') { + // Read title row and rows 20 - 30 + if ($row == 1 || ($row >= 20 && $row <= 30)) { + return true; + } + return false; + } } $objReader = new PHPExcel_Reader_OOcalc(); - $objReader->setReadFilter( new MyReadFilter() ); $objPHPExcel = $objReader->load("06largescale.ods"); +``` ### CSV (Comma Separated Values) CSV (Comma Separated Values) are often used as an import/export file format with other systems. PHPExcel allows reading and writing to CSV files. __CSV limitations__ -Please note that CSV file format has some limits regarding to styling cells, number formatting, … +Please note that CSV file format has some limits regarding to styling cells, number formatting, ... #### PHPExcel_Reader_CSV @@ -422,7 +354,6 @@ You can read a .csv file using the following code: ```php $objReader = new PHPExcel_Reader_CSV(); - $objPHPExcel = $objReader->load("sample.csv"); ``` @@ -473,7 +404,6 @@ You can write a .csv file using the following code: ```php $objWriter = new PHPExcel_Writer_CSV($objPHPExcel); - $objWriter->save("05featuredemo.csv"); ``` @@ -780,103 +710,5 @@ $objWriter->save('write.xls'); Notice that it is ok to load an xlsx file and generate an xls file. -## Credits - -Please refer to the internet page [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home][22] for up-to-date credits. - -## Valid array keys for style applyFromArray() - -The following table lists the valid array keys for PHPExcel_Style applyFromArray() classes. If the "Maps to property"� column maps a key to a setter, the value provided for that key will be applied directly. If the "Maps to property" column maps a key to a getter, the value provided for that key will be applied as another style array. - -__PHPExcel_Style__ - - Array key | Maps to property - -------------|------------------- - fill | getFill() - font | getFont() - borders | getBorders() - alignment | getAlignment() - numberformat | getNumberFormat() - protection | getProtection() - - -__PHPExcel_Style_Fill__ - - Array key | Maps to property - -----------|------------------- - type | setFillType() - rotation | setRotation() - startcolor | getStartColor() - endcolor | getEndColor() - color | getStartColor() - - -__PHPExcel_Style_Font__ - - Array key | Maps to property - ------------|------------------- - name | setName() - bold | setBold() - italic | setItalic() - underline | setUnderline() - strike | setStrikethrough() - color | getColor() - size | setSize() - superScript | setSuperScript() - subScript | setSubScript() - - -__PHPExcel_Style_Borders__ - - Array key | Maps to property - ------------------|------------------- - allborders | getLeft(); getRight(); getTop(); getBottom() - left | getLeft() - right | getRight() - top | getTop() - bottom | getBottom() - diagonal | getDiagonal() - vertical | getVertical() - horizontal | getHorizontal() - diagonaldirection | setDiagonalDirection() - outline | setOutline() - - -__PHPExcel_Style_Border__ - - Array key | Maps to property - ----------|------------------- - style | setBorderStyle() - color | getColor() - - -__PHPExcel_Style_Alignment__ - - Array key | Maps to property - ------------|------------------- - horizontal | setHorizontal() - vertical | setVertical() - rotation | setTextRotation() - wrap | setWrapText() - shrinkToFit | setShrinkToFit() - indent | setIndent() - - -__PHPExcel_Style_NumberFormat__ - - Array key | Maps to property - ----------|------------------- - code | setFormatCode() - - -__PHPExcel_Style_Protection__ - - Array key | Maps to property - ----------|------------------- - locked | setLocked() - hidden | setHidden() - - - [20]: http://be.php.net/manual/en/language.types.string.php#language.types.string.conversion [21]: http://pear.php.net/package/Spreadsheet_Excel_Writer [22]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home diff --git a/Documentation/markdown/Overview/11-Appendices.md b/Documentation/markdown/Overview/11-Appendices.md new file mode 100644 index 000000000..1302feb3f --- /dev/null +++ b/Documentation/markdown/Overview/11-Appendices.md @@ -0,0 +1,100 @@ +# PHPExcel Developer Documentation + +## Credits + +Please refer to the internet page [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home][22] for up-to-date credits. + +## Valid array keys for style applyFromArray() + +The following table lists the valid array keys for PHPExcel_Style applyFromArray() classes. If the "Maps to property"� column maps a key to a setter, the value provided for that key will be applied directly. If the "Maps to property" column maps a key to a getter, the value provided for that key will be applied as another style array. + +__PHPExcel_Style__ + + Array key | Maps to property + -------------|------------------- + fill | getFill() + font | getFont() + borders | getBorders() + alignment | getAlignment() + numberformat | getNumberFormat() + protection | getProtection() + + +__PHPExcel_Style_Fill__ + + Array key | Maps to property + -----------|------------------- + type | setFillType() + rotation | setRotation() + startcolor | getStartColor() + endcolor | getEndColor() + color | getStartColor() + + +__PHPExcel_Style_Font__ + + Array key | Maps to property + ------------|------------------- + name | setName() + bold | setBold() + italic | setItalic() + underline | setUnderline() + strike | setStrikethrough() + color | getColor() + size | setSize() + superScript | setSuperScript() + subScript | setSubScript() + + +__PHPExcel_Style_Borders__ + + Array key | Maps to property + ------------------|------------------- + allborders | getLeft(); getRight(); getTop(); getBottom() + left | getLeft() + right | getRight() + top | getTop() + bottom | getBottom() + diagonal | getDiagonal() + vertical | getVertical() + horizontal | getHorizontal() + diagonaldirection | setDiagonalDirection() + outline | setOutline() + + +__PHPExcel_Style_Border__ + + Array key | Maps to property + ----------|------------------- + style | setBorderStyle() + color | getColor() + + +__PHPExcel_Style_Alignment__ + + Array key | Maps to property + ------------|------------------- + horizontal | setHorizontal() + vertical | setVertical() + rotation | setTextRotation() + wrap | setWrapText() + shrinkToFit | setShrinkToFit() + indent | setIndent() + + +__PHPExcel_Style_NumberFormat__ + + Array key | Maps to property + ----------|------------------- + code | setFormatCode() + + +__PHPExcel_Style_Protection__ + + Array key | Maps to property + ----------|------------------- + locked | setLocked() + hidden | setHidden() + + + [22]: http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Credits&referringTitle=Home From d6ec415676989782fd3b49b9e25509b9e852418e Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 19 May 2013 22:14:52 +0100 Subject: [PATCH 079/467] documentation markdown --- .../PHPExcel developer documentation.doc | Bin 819200 -> 818688 bytes .../markdown/Overview/01-Getting-Started.md | 13 ++++++++++--- .../markdown/Overview/02-Architecture.md | 9 ++++++--- .../Overview/03-Creating-a-Spreadsheet.md | 1 + .../Overview/04-Configuration-Settings.md | 7 ++++--- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Documentation/PHPExcel developer documentation.doc b/Documentation/PHPExcel developer documentation.doc index 6eb230c93b96f8c59553e0922607e6f79ea36134..b6c1f4d273daa2cd68cf43f86403caa3d741c6ca 100644 GIT binary patch delta 25234 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 aH>%sEOPBV|Y?`-k-l=1AgZq3!{eJ+f{IOgB delta 25334 zcmciLcU(^IANcX>oVzscvSmhyY_j*t9$6nd8A*286*}2umT^KzM##$O&fY{ek?kX7 zMVTS`y)Mc3^ZoqhU%&3h^W4|DyYKs4*Y!T7WfT#@`XIhw7+K9{{o;2P5A|Zzu9R>C_ z@jQj+L%mr1<9Setr5T3eT6TuBewkH}`V=^x@3rH_mB+Jw^Y3T*b-wk5$lhx9_xyWZ z7WAJ#+28Z~HNDDdwS1NAy#4RqEI*XfOo+|76!AjUOP*HSX(0uE*WB-#C#ae7OCP6} zne?X3izqz+3VTm$*$x7>3L~Ui*V=Ph0OlY z|NU7Oy>XuZ>3w?}Sau&|<}%iEpdNiv$+vgUaMw{w!_AD-6JrvUDOc^53>9J@4&Wd< z4ijR{Fg<9CTGH~;uuH?-DV!c{Zg9{?ELLqzFSe)!6~!@To7zjw8~KmVxMqD$F&c*J zO%+2CeaTsat)AOx=qp!k^{eTstv>1%iKoO!K!&4zu{E3nJT;n zpRfFrHbK!J?NA-GB5U~4O~cvE&~pU43RYn?!VrZWh{JirBLhERJyHl86o&&GQ3f?o z3$;-PosfWAxQ#^oz|WDcLKsI0VT+@lJ!X4EXvFnJ0ox<89@j^td+=)3 z3)g?`6Mq&t?S`Hym|-n;ciV>{HpL@k@(MRYr@nb`sIzPlYVa_;rP$u z(?)(V`G~=&$L&`u>+N@`fm*(QW?%ssSb~*Uhh(HeX2```hyfUjahQU+C_qO4nb{e? zGAqPvp7W38_b7x!bRS2Uu^3D6_c)r8R1#nC6TQb%{i)CH{(4-wd*w8bX9sphhVNV+ zv|Jmn9oRX{okw=X>orX3MSbN1O0;>8+NCu?5Tn{yS&oAsD9dui|5-0Riwwz375tr{ z9&GQQnK{e)ISd=G2WP0A^~Kw$ygRoHwu+a2>6W1|dvi(Ck64wR_erc;R6np^HEM!g zy6}+x?2R((UPwYRKEQl}5bfa#FB+l{til?Mo5XvOg1Ww(pWuQhH1iXpIRY^k8?YHW za0tcy*-`MWFN+WO0n5okG(t19K|9Vt?cp?4h%xvZpI&`>^y%iS^RG_uhZDu``(0h*O;)Gn`gp2q0(O|J&az&72kD)V)fI#zxb>%sbn95Pn5ll8dRDQL z6*dYRO;#7>CpVJb1X)KRIEzPr>g)F>FUwEL+8c{aCabIRlbc9y#-jisO0o-d!$|By z-@xCWyv`>zS?5n+#yc%h4G$qdne}cVmIVrN2Y2B-opbyQ+Oe5J^n*J#U?aB8;_Nh= z@0i2;;0AZ}hbM+20&kNNlP)ElO-wqp&Ee37L!mQ5$A*pwoiU)-fX)Lt6W4$K=(X;s zkv293hTbgWFYJa6bU35OUQpfjZF5!YU$HjiXi!(TiB~HbMX|ntY!pjPRyV1J@=Hm} z%$J|`JL6=251ykSg{THu7)Mk2Tk37a%8^3+DwxUYE}ys0E}$$}8cI{RhWJ%Tll^@) zNwLZ#8_)yF1{E?{;Grk_hx`|Gcc8LUbr6Im%INXr5znXI0&UODMs1rGgP*zG(&!51{6fU?jnOqHLj zHx&04q}x$A7xL_Z4~sZ&E#|1e8z@UCIBc;TD^M#$h_yJql=tG>GRnVPh_)CEPwd0~ z<+{&vLv7t>rJ?4EJO-x~2Y7x-7ou94!Brn+Zk9)160Dl(;jh&Jnyj>DkQoVJ!>4~| z;@rP7F^CL|#4^YX7q;YA#I_mtU1#4?Riu#{dk32V~vIdQn!epP)MYF&SZ4gDu#KZHUEL#Nh@Ka2ri^ zc5vK428x9WVXv|1gwE&-PxwN<9*PKTzyTaYD!#*N6-O<;etP@$?Web&oK`Cl(y+?|gQ_EpDbiU;l4x9qNp0n1f?5Ao3#go+|t3+0T zEN&wHtEl8!mPD39=DsYPa0OQ}b~ROr2dEq-L=W`DLwsWs!ZhryswDi@&NQv3Ab5G>X@R&W}dt$W&QDGe|EVg1B{KM(*!LXj%$85}jF@jz|mT>Yy&#A-mM?Nvo7rmcA9bt|PA9NqE2$ zJ{W^>kkvCC3$YZNA*-t`)zlIGNXA#FRF$l{jP#83w2W728EF|w>Gu=U6YsN{#%ovO zj>H|={vrv-85MX33!WlNX2J-!9Vk(vRwnR^Ca^V zx1Do7a_^uq!%WPD2{)03kN7IrcQQD%i`@Xd(QG&0wO5o8-S^6K=#A94)FUy^qQZHs z44)f5W%v}9bHk&aMLmn@&(KK`eeEjM%21~EPknl(+Dd30)h+r&36m~!s z`8+%+k}R?;Rw`ytq?vevq+Rl2Fjf!G;BuNPLMPqlhq`2R62EFnsb$GqV+J-O5(zMm zrm;j51VBRqZXpFl_t2D}I))=2S8x@{cnO8dq*jIVUfp?zT3gR;FvQ5AmZ4cgEmstS zvnDIt8-WPN9VDUWJ`PIs+s}o3EWg89oWpCpfyDtjJ*ba9aEFF@ScRB_R3Tz<4cBo4 ziMWHi2So*Ok3<^YJ5EsXg>2-~XvL*5k|#CG^snY9XzpGlh7A6u40cS&&f(!hGz*E4+qz4CiB1 zMl;OE0&K&1T);J4hn0yI43|)VO31DpS?F&xm{~uj0M#&E8IoNSTPff+96Cf(hO$T4 z>Cg*09-!P&u1oO(RgV!BEW;z1ALlcOI>EItw39>(nGmPsxDI{e9~{zjkejVoZm6m6 z*eTn992_aXQvEFq>or-;@9_bp$VF*5VhrYE0T$vQWKKUFrbG5SmohimImt^-il8iN zqbdB!)hx`$LM+01Y=O*mz)4~)vn@^$lZQ7R#vR$iBQh*5Yi&WKq5Y&z&V;> z495q2qj*u%e?OA`q~3o0l`fk7i+fk^C7n5NX6J^`g;@{w`n0^9F7;f7diwKR zhC=#+PX;UfPA($pYGtq^>icEX2U{6R_pc+XHaoYj|H^Hj^A!66Z6!IBIhVOs$(bWM zVG?A{b6w)hgaq8eg3EN{@#wN_o@@Uat23>)G4xk7S+MN4%eUs>Z4PilKgf?BM?9|K zCK7Q650Le>biA+7QNuJWhK@Bjfrl_$rGJB>a6(&jxGK7fjwC{`28p-Y(Exuz zj>FyLap~+a9+zTwZ&|-4>#<_ZiZ$!EJX(Bd<|Du1e%X7ZUO&muNWWxdu(kbj#Z{(4 ztk9q3G=yaxSl{y+?7X*`mB{YaTb6r7X}XhBS&|7@i^q_;C8vKfnw?2+GIj)a;d7ni z3^9mDfg4;Mq7c?09N%taotQW$ImvTU5!rt!q96aL+HTHcP&8T4?(oDAjKnC&?f4>l zTlYxkXB*`)8s3oGw__V}n`3vaCSnr& zpdk=DuoH)H7{_oNCvZ}q*T-z9QI<~>up8R3u$A7tuh|Sk&mQ^oxV~m}3zHv_y&+%H z*-#{+7;W#sEcwLSz%MoQcpehGZ<-n;N2$dsHa*RV>0Lm*3+1-~tQrRJ- zYK_0T3$l6rcEi-%)|f-Jk~^K;r%vi!avAF=J@t9Hj1~0-{cLRXuzog$nt4+gAB@3R zOu!`gV+y81Lm;MOCT3$Uf-qmN>~2$0cXPKXWWJ8|_4>fv#)5j7yG;lEjk`^yJaN2u z0r9wmE4q@$m`_U}c?*fSgS)tohj@g)@dQbDhUZAeOT5Bsq~I;m@E-DRiqH6hulR=V z_<^4g1WJKH6?(1#HigY?Sh3Y>4X|l#%E)8PZKJ)I!EcFy6^tm2rntD8Z^cjCWJKj1 zKEo7E?;VM_i}xtChf``CXBUh_ajLj0e6a~vk%DJbc{{3nJs#rgSjAcVAd!iJ?DZAV zi+T>jLF{19%}EswfIW4W&o+Oi>9~V&q(LstRK1d;@u_`T$~gw1Acum3Pb44-ul34h zjFUOu^=)O073A}+tY?#2))-(`r+<~KZ&uAXta5WwPv9RfC1!K*e+LHck5}OAyI^#hWTC@ z?~}uaj8i_M)k>xFoyM2H=kWW$4*HR6BB6->){2NQDq^#ZB3kBC#QegFxKxzdFQ$m7 zQi`}xNfC8wC}L7gMf9wrh&PC-s|e4=in!545v!Ui!mN!VE_P7F%T9_Y)s34(+&EPB zxhbMgKSlh&n}LcrHi&f(MVuL|hz~=EvzHPe`)2vs#gwUSWXBUDQXRT)B6icsAlRM|EWs!D{a7oqYe zRM136LUo@|c@wHxgvystT_IFHglZn4iY8RG3DrbGb)HZiBvgY4RRp0*BUBFdR6n75 zLa5pjs)dAV6k+-f|9Tv8gz6=siXl{`2~`rI`a!7L6RMjsRKA3$n7bk@3DIRtCQQ!= zlQkhKM2Muus7k2X5~{qkl*b5_6QR-wl>=eQL6}zKDWQraREG#vDxum(s4fwzXhJoa zP<10r_i%_%-6T{g8lgH#sJsZ(UP9HLP}L(;dk9q!q1q%v#bKVA$|6r%#k9t%!NF z-o^FOO^h!2mh#dal;h=<^5t8K{=KJ7Nzg2bY#MdzD5w_%^<6=1-sE>G^Z|1Kqyur3I|5Bk6j?);msQmi{q&3 zL#qxKxS|WjV-n_KK0>hpo3Rtoh{Yk?LNZ?BCuDnTL{1dNC@ew97>!;KiETK9I3%Lp zI4;Z30rF0dKA4I?$lFhrA{$fyBIpcJa2K3p&oQ=wrQR$x6gA{v&H_&nU8VH!fP4!dy;vIAMmms>udwPVp0 z{V)Wxun@;^4#oY*0IH)An!*E~moGIVi&-HgI>UkrmkRzr4wl_^v+bZkKsVsHTW@euFu9+|MF7nctW(Gi_6 zcq;K9LPB=)#$y^z;5;7SIh+GHx1t9;5yWS9pzJgzcCZm!u>-L4^S zp>H|}Ay|zF?80|w@>HLS@32|IUJL7BE|5?VrQjYyEkVxMZ^dq$#A#fC{Zhh(DyWAB za6wCS#;|47Fg9R6#CTNAW=#HN7#1sTzF;-(E_O2)X2T7bo9FkCT1675_Xa^toVlBe) z0Xa8vG~gW;Zf3WEOC%dc8+5^67=ob~kC|AA#aN3i*c+*Fi9q5wZs7@@BMl#*Y@t0z z9uz=Hltwi)MMrc&KlFz;Cc+Pa2*GkhU?UFT5aJ-`^m1t|98ne>;Et)7hxrJ{PQ>6Y z?xWE*Vvp|dMj*m*2Y(}P6gwn(!WUh)(*|H5hG7)^Fd5n$7K^bP`*0j5aRFD6jCW9W zkYnUQJ`_bUlt(kTqBGnv7_+bn5r{$zj^GTecT$@uxRdyoAyFQ+&<*YwfYBI>09?i$ z+`~(x;4AEQ5fYS!Gisq3EOzrc>Z1?bp+R1+1mirep;R>SuMo|dYY!JiID_lBkEf6` zX*nS;;p?LzS|c6_sJf5W(Hny?1miFX(=Z>h0~U%6*n~ZZ!8u&hSjgVlL%hUmq$2}n z`>7e!L~XdBHM(FTreOw_U>PFt5+Csyh8SuBdEo#jltV>SLj!1yShRyHdczO1@ffd> z0%2l0B9{FFhJ#c$nxX?-(F1N6hbYK-zk`UwWxT^@D2Mnw@<7f*RXIfbTaxIEt{4D0 zDdmSnSc3wGX`)dRb(G>$Q22(K;p;(2D*oA{Qj0?DjB&5UQ2$@B|5#k?6ViDFM z3I}lp=a7KscniZ(suEE+i*(o=WB))QG(-zjIL;x8vG7OJ6EsT5fZ0j5gGdZvGH0~L zqV`!rfSwqH!H}~~GoZt8j07q~d7jYBD^BkI(jH#H01z3!5L?8->aSrAe zh`%)pBW%$IT_ERF@*p2dq6{jbCK{p{x?=G~GKJiiIhIifMbHMF&>3AJCr}1r6eeII zd@=tr@n1+n$2x4oKJ14Hrw|7@(;{bC?&2~2MiNr-72lA7d{=0cU=JshLuJ%KV>E#a zTA&p=U(u*`61~s|gE1T@Ci1i7)j-5D+%++2Jq};}MUmc!3Z21j9Gl zapXb~ltfuLqdHomI|gA0M&S@nA>%tWoxvfQLHzwloW(ul`N1)XZs>yh;68wLlG`$sj=vWo^Zzyj7BWZz+kBe zBX%Jchj0m3a1XEX8Q);A;?D~)5xcEQ3g$5D5!{Bn1^62M;O8piD;aJZ6Rh4P#6_7 z7ERC=?cs)}c#V>bqEVI(FX5Yw>`!Ptn+*opEE zgb}qJh<^(bZO|RPF%ZKs0h2Hb^RNP|upV1WQk57{ioG4an2jLlSd9&+?8v@?#%PQ7 z=#73Dj8Tr7A_7Rvz!HRDC04_PI3(aUp5i&wGVEkFpKkuM=~;DQ;vBo6h#?SM@_UwXY@mVjKyTkMG#gZ0=p26qqvF(c!Xpa$}1u_ z^1`7!@vlXqIa;720%AvmHEDx(_epdRX@DcYkW`l3HZ zU>wF{5~d&k8fMAoB`iV^j*ZxjSRBBaeqdcm@8THWvgD?UUG!}C(7poA39Wdbl&LU4oPBciuTYN$eS2h4U6hbM~M+>w; zH+07!ti={=Lp1i|FwQ``!r~edaUaj{7U}o~h3Qyx*diaCP#%rY0|ViKQTT}*ofR<# zQxJe)=!n2Z>_H4p;zDQQe}lvwJjHW-L^{m6a7ZFQil7XfPz&|Y61_1PLogn`n27~g zhG-ndQN-gKp5i&);(Zt5|ARy(Y`b#CLs^tVEi`~DI-?id;DuqBgst7EPFVd#n2;Ct z7=j5{j!+nTa+IJMI^ZpoUKB)Q(Ht$&6TRUHFO0fD6lZW7Pw*74VLpJGLmm`C zGqgunjKw5O!wdvr4I;4>rUAtN0*RZrh39yIcUUoyh6oXe!X6yPQCz@9+{PUwT7*6wxQ@Di05ghAyh7b4xtC8%0 zqqwyQ$)l+u_>SYui7;%$V|+md@{Ok;kT*h9LQV9;c=%#5c0xPOqT~e5Na%zi7zKIv z#4ecNFp;W6TXaDL4j>snQF0PJV6;IWY`{)L;}kr7X>KtRKFIAyt)ZA7@vlOn8eHH8 zPk3P>G|WXTuHX^UP{yC$F`VIomgs_k7zrQvAr%&rIrJcJ1*wj<=#3E=J(>7VBH@n( zScFvwLnLBx0&nmYb*FI7h9`V536rrI(Kv;3c!4z7O{I2F230T?)9?amu+suKL!l(9 zp&nYG4Z0v4(J&*Uwy2H=AS^^E z!mvqWaRMEVa*=@%mo7IKoa6qcMKM_7m5IEw^4#TR^oa+)edJv2oZbi+Ul!B|W}5Vj!(hj9f?XQ){$ z#R}-?aZ?#7v-@doeFY7SE_koR`%M)G`S zN6>QtnS$d&{&^$B;vB3OGp7Vk_(9$Rk^ym~d?k{lWS>8|J19{)TLEPFx{O^)TK`QLGGU|<*sDsfM3whtbdYr&% zT*ocEL<;0IeSa**a>!}{+4?Rdzk+fbasS;#5dgP0vhl_TOj z8$=9ZaS>M`XJETR&b-RM#TyAq=x5ptfe5VpXC zSNIA!U)URResDkJG~QdJJrXn?9OoF1oj45px0Doea;qN(V;I7*2@miDh2IfkjfI?a zdJZ|cGyzN^iHa!yfs!K;$r$*N!v_!W6nQ=g;ef4(MbXbp(?Z8)o2jomj zH%ux{KOb_&q%7nNNpHv*kwtie?_dT*w1k}Km<(jA09E|litwluwEIfKy$ zqo6@fSgeAapm+v3AyEx-BBC$k1jKB}iH9h}<0j-hL(a0i7xm$f*;tK8$oYh(kn;$h zkn;zDP8$6=5*Hxn2Z}+?3$%fp4;TkI53mYy{Qnr_xc>{t@&1yK!~CvTjMcEJz<0r_ zBF~7#UIbR+J#eZ_Eulyi#+@`4Z);FJs8^E><2IgSe=UaOpw?zbfgH}Si`_T||GLB- zC+e{?VMTqq-*}97=-7aMB;;`Ze8^$?tB|Ab1t3S&H8&P=w0u2o;0f#-afuBtOoSXI zZv{Cj?t(2afzfU;6;aJ7Axv0-4 zkladRpoxSW>n(#3m;^b-dkS)F_X)Cxa3{89$AJk)a1qxahiE@S4$<17HkzP4x}XQ# zFa?1~z#UZ9+Ouau4#h^|E*?P+xmtI~8fvY^vm9dezzod725iUAj$947W{sGZ=2?!A zdO(hh?tvT#y#qP$ss0|=9L@6}#v?tU$q~&E$dSywkOP*VAO|LELk>hvKo}w*2Ocj% zjwjZ}i@&%;!^R$r8NjM1F~>wq#Wf@%UoZA}$l<^tScIj$i2r*Ma{RA(9}Fj_`mS<~ss8yqAQM1GspFC&obz-_0MOWsTd# zvLc7;l97r018D&<01?;@IZPLiUW3@7Acx^vLJqsVfgE+S9Go@kR*mOUo?Pxhj<(5> zwl!FfvxtWrRePkdki%+es6ULo8FCoy0lvd}IKwd`h!f=K*+=+}WJki8NxTX$ z7}F#KVKL+wQdh_!pw$>Zg;2tBDvcMaL94~$I4;35fL}lk-8iEgdcl!esscGg(+Nuv ziaOJ{XvKK=<1X&QW;)-4QYeQSs0ld&6M(KWI2tfX{=*VeNX(wesS~$x9|dQV2@Hof zss>SwaGFm>&;ea=4=+%90hjTR0~l>F0zPQ4kU>hwfeH^qVmsO`rXZNJm{Kexk%D(9 zv4ouswa@^q&>DeQgnq#c&qKpZ)LY7XFc`yNv7FMQ1=?X7w&OmY;62h|SV3C>7mY<1 zr0E<5SQpApf@Hjb^-AW4v3(UMAiTsobXv{lFb#8{V-2=oD<0!5TCd^cgpnA7oa;Cg z(H>o(MYGt8B)r5|WWqX}F@Cf_S2T>^^a*!(VC+VYaqPfBT*Mu`LOSYiq6NflJVU-n z!itvY3J;8lB>p|Oa9+nmOvZ?<#2i}@gL6oL_TeznVSbUSMpeAH#OELf!2TZxx*UFua7|8NPsUuxKlGD-)t5cO^>Cqa zoaxd+V}`9J|5{J}MP3NxU*oO8xY1m51TegV{anqNa1GaSB{+*5>N$#2xCXZ?30}xHJxW*j)}L~imV_B+Sp0u4!oR{$ z>3=)mD2tJu{ohq@y1daiU(p|IG+OGtHybldy(5hUdnl#!F+Ys?l#=?aAI8k1aho2&1L* z3R&jNUTf%MGt#`GT+^d{Y^v(VeQYfA)MvfH?{~=0G&ZIA*cg=+V{JxR{{Ei?8kr`H zwJ}qavbz5`n{SGRK4H9#rsUE;jkob`o&DbpWIvOgKR?|>2XTh_yDmNRRLt6QUX9h3iLo7w9B02kZBfdBvi diff --git a/Documentation/markdown/Overview/01-Getting-Started.md b/Documentation/markdown/Overview/01-Getting-Started.md index 404640953..d3fb06b5a 100644 --- a/Documentation/markdown/Overview/01-Getting-Started.md +++ b/Documentation/markdown/Overview/01-Getting-Started.md @@ -12,7 +12,6 @@ The following software is required to develop using PHPExcel: - PHP extension php_xml enabled - PHP extension php_gd2 enabled (if not compiled in) - [^phpzip_footnote]: __php_zip__ is only needed by __PHPExcel_Reader_Excel2007__, __PHPExcel_Writer_Excel2007__ and __PHPExcel_Reader_OOCalc__. In other words, if you need PHPExcel to handle .xlsx or .ods files you will need the zip extension, but otherwise not. You can remove this dependency for writing Excel2007 files (though not yet for reading) by using the PCLZip library that is bundled with PHPExcel. See the FAQ section of this document for details about this. PCLZip does have a dependency on PHP's zlib extension being enabled. ### Installation instructions @@ -27,6 +26,7 @@ If your web root folder is /var/www/ you may want to create a subfolder called / /var/www/Classes/PHPExcel/Cell.php ... + ### Getting started A good way to get started is to run some of the tests included in the download. @@ -42,7 +42,8 @@ http://example.com/Tests/01simple.php http://example.com/Tests/02types.php ... -Note: It may be necessary to modify the include/require statements at the beginning of each of the test scripts if your "Classes" folder from above is named differently. +**Note:** It may be necessary to modify the include/require statements at the beginning of each of the test scripts if your "Classes" folder from above is named differently. + ### Useful links and tools @@ -59,7 +60,8 @@ There are some links and tools which are very useful when developing using PHPEx - __OpenXML Package Explorer__ [http://www.codeplex.com/PackageExplorer/][6] -#### Frequently asked questions + +### Frequently asked questions The up-to-date F.A.Q. page for PHPExcel can be found on [http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=FAQ&referringTitle=Requirements][7]. @@ -140,6 +142,7 @@ The short answer is that PHPExcel uses a measure where padding is included. See Thanks to peterrlynch for the following advice on resolving issues between the [PHPExcel autoloader and Joomla Autoloader][17] + #### Tutorials - __English PHPExcel tutorial__ @@ -172,3 +175,7 @@ Thanks to peterrlynch for the following advice on resolving issues between the [ [19]: http://g-ernaelsten.developpez.com/tutoriels/excel2007/ [20]: http://www.web-junior.net/sozdanie-excel-fajjlov-s-pomoshhyu-phpexcel/ [21]: http://journal.mycom.co.jp/articles/2009/03/06/phpexcel/index.html + + +[^phpzip_footnote]: __php_zip__ is only needed by __PHPExcel_Reader_Excel2007__, __PHPExcel_Writer_Excel2007__ and __PHPExcel_Reader_OOCalc__. In other words, if you need PHPExcel to handle .xlsx or .ods files you will need the zip extension, but otherwise not.
You can remove this dependency for writing Excel2007 files (though not yet for reading) by using the PCLZip library that is bundled with PHPExcel. See the FAQ section of this document for details about this. PCLZip does have a dependency on PHP's zlib extension being enabled. + diff --git a/Documentation/markdown/Overview/02-Architecture.md b/Documentation/markdown/Overview/02-Architecture.md index 0baaef4e7..d5af2ce6f 100644 --- a/Documentation/markdown/Overview/02-Architecture.md +++ b/Documentation/markdown/Overview/02-Architecture.md @@ -7,6 +7,7 @@ ![01-schematic.png](./images/01-schematic.png "") + ### Lazy Loader PHPExcel implements an autoloader or "lazy loader"�, which means that it is not necessary to include every file within PHPExcel. It is only necessary to include the initial PHPExcel class file, then the autoloader will include other class files as and when required, so only those files that are actually required by your script will be loaded into PHP memory. The main benefit of this is that it reduces the memory footprint of PHPExcel itself, so that it uses less PHP memory. @@ -27,12 +28,14 @@ spl_autoload_register('myAutoload'); ``` Your autoloader will then co-exist with the autoloader of PHPExcel. + ### Spreadsheet in memory PHPExcel's architecture is built in a way that it can serve as an in-memory spreadsheet. This means that, if one would want to create a web based view of a spreadsheet which communicates with PHPExcel's object model, he would only have to write the front-end code. Just like desktop spreadsheet software, PHPExcel represents a spreadsheet containing one or more worksheets, which contain cells with data, formulas, images, ... + ### Readers and writers On its own, PHPExcel does not provide the functionality to read from or write to a persisted spreadsheet (on disk or in a database). To provide that functionality, readers and writers can be used. @@ -41,7 +44,6 @@ By default, the PHPExcel package provides some readers and writers, including on ![02-readers-writers.png](./images/02-readers-writers.png "") - ### Fluent interfaces PHPExcel supports fluent interfaces in most locations. This means that you can easily "chain"" calls to specific methods without requiring a new PHP statement. For example, take the following code: @@ -66,5 +68,6 @@ $objPHPExcel->getProperties() ->setCategory("Test result file"); ``` -__Using fluent interfaces is not required__ -Fluent interfaces have been implemented to provide a convenient programming API. Use of them is not required, but can make your code easier to read and maintain. It can also improve performance, as you are reducing the overall number of calls to PHPExcel methods. + > __Using fluent interfaces is not required__ + > Fluent interfaces have been implemented to provide a convenient programming API. Use of them is not required, but can make your code easier to read and maintain. + > It can also improve performance, as you are reducing the overall number of calls to PHPExcel methods: in the above example, the `getProperties()` method is being called only once rather than 7 times in the non-fluent version. diff --git a/Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md b/Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md index 592d47580..b65000bf5 100644 --- a/Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md +++ b/Documentation/markdown/Overview/03-Creating-a-Spreadsheet.md @@ -1,5 +1,6 @@ # PHPExcel Developer Documentation + ## Creating a spreadsheet ### The PHPExcel class diff --git a/Documentation/markdown/Overview/04-Configuration-Settings.md b/Documentation/markdown/Overview/04-Configuration-Settings.md index c7752e527..2024e801e 100644 --- a/Documentation/markdown/Overview/04-Configuration-Settings.md +++ b/Documentation/markdown/Overview/04-Configuration-Settings.md @@ -1,5 +1,6 @@ # PHPExcel Developer Documentation + ## Configuration Settings Once you have included the PHPExcel files in your script, but before instantiating a PHPExcel object or loading a workbook file, there are a number of configuration options that can be set which will affect the subsequent behaviour of the script. @@ -114,7 +115,7 @@ When your script terminates all entries will be cleared from Wincache, regardles #### PHPExcel_CachedObjectStorageFactory::cache_to_sqlite -Uses an SQLite 2 "in-memory"" database for caching cell data. Unlike other caching methods, neither cells nor an index are held in PHP memory - an indexed database table makes it unnecessary to hold any index in PHP memory, which makes this the most memory-efficient of the cell caching methods. +Uses an SQLite 2 "in-memory" database for caching cell data. Unlike other caching methods, neither cells nor an index are held in PHP memory - an indexed database table makes it unnecessary to hold any index in PHP memory, which makes this the most memory-efficient of the cell caching methods. #### PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3; @@ -129,11 +130,11 @@ Some localisation elements have been included in PHPExcel. You can set a locale $locale = 'pt_br'; $validLocale = PHPExcel_Settings::setLocale($locale); if (!$validLocale) { - echo 'Unable to set locale to '.$locale." - reverting to en_us
\n"; + echo 'Unable to set locale to ' . $locale . " - reverting to en_us" . PHP_EOL; } ``` -If Brazilian Portuguese language files aren't available, then the Portuguese will be enabled instead: if Portuguese language files aren't available, then the setLocale() method will return an error, and American English (en_us) settings will be used throughout. +If Brazilian Portuguese language files aren't available, then Portuguese will be enabled instead: if Portuguese language files aren't available, then the setLocale() method will return an error, and American English (en_us) settings will be used throughout. More details of the features available once a locale has been set, including a list of the languages and locales currently supported, can be found in the section of this document entitled "Locale Settings for Formulae". From c758748b3988633c6a52ff82630d3790c4ae9f0c Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 20 May 2013 07:44:14 +0100 Subject: [PATCH 080/467] Reader markdown --- .../01-file-formats.md | 50 ++ .../ReadingSpreadsheetFiles/Reader.md | 521 ++++++++++++++++++ 2 files changed, 571 insertions(+) create mode 100644 Documentation/markdown/ReadingSpreadsheetFiles/01-file-formats.md create mode 100644 Documentation/markdown/ReadingSpreadsheetFiles/Reader.md diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/01-file-formats.md b/Documentation/markdown/ReadingSpreadsheetFiles/01-file-formats.md new file mode 100644 index 000000000..ad8181d73 --- /dev/null +++ b/Documentation/markdown/ReadingSpreadsheetFiles/01-file-formats.md @@ -0,0 +1,50 @@ +# PHPExcel User Documentation – Reading Spreadsheet Files + + +## Spreadsheet File Formats + +PHPExcel can read a number of different spreadsheet and file formats, although not all features are supported by all of the readers. Check the Functionality Cross-Reference document (Functionality Cross-Reference.xls) for a list that identifies which features are supported by which readers. + +Currently, PHPExcel supports the following File Types for Reading: + +### Excel5 + +The Microsoft Excel™ Binary file format (BIFF5 and BIFF8) is a binary file format that was used by Microsoft Excel™ between versions 95 and 2003. The format is supported (to various extents) by most spreadsheet programs. BIFF files normally have an extension of .xls. Documentation describing the format can be found online at [http://msdn.microsoft.com/en-us/library/cc313154(v=office.12).aspx][2] or from [http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/[MS-XLS].pdf][3] (as a downloadable PDF). + +### Excel2003XML + +Microsoft Excel™ 2003 included options for a file format called SpreadsheetML. This file is a zipped XML document. It is not very common, but its core features are supported. Documentation for the format can be found at [http://msdn.microsoft.com/en-us/library/aa140066%28office.10%29.aspx][4] though it’s sadly rather sparse in its detail. + +### Excel2007 + +Microsoft Excel™ 2007 shipped with a new file format, namely Microsoft Office Open XML SpreadsheetML, and Excel 2010 extended this still further with its new features such as sparklines. These files typically have an extension of .xlsx. This format is based around a zipped collection of eXtensible Markup Language (XML) files. Microsoft Office Open XML SpreadsheetML is mostly standardized in ECMA 376 ([http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm][5]) and ISO 29500. + +### OOCalc + +aka Open Document Format (ODF) or OASIS, this is the OpenOffice.org XML File Format for spreadsheets. It comprises a zip archive including several components all of which are text files, most of these with markup in the eXtensible Markup Language (XML). It is the standard file format for OpenOffice.org Calc and StarCalc, and files typically have an extension of .ods. The published specification for the file format is available from the OASIS Open Office XML Format Technical Committee web page ([http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office#technical][6]). Other information is available from the OpenOffice.org XML File Format web page ([http://xml.openoffice.org/general.html][7]), part of the OpenOffice.org project. + +### SYLK + +This is the Microsoft Multiplan Symbolic Link Interchange (SYLK) file format. Multiplan was a predecessor to Microsoft Excel™. Files normally have an extension of .slk. While not common, there are still a few applications that generate SYLK files as a cross-platform option, because (despite being limited to a single worksheet) it is a simple format to implement, and supports some basic data and cell formatting options (unlike CSV files). + +### Gnumeric + +The Gnumeric file format is used by the Gnome Gnumeric spreadsheet application, and typically files have an extension of .gnumeric. The file contents are stored using eXtensible Markup Language (XML) markup, and the file is then compressed using the GNU project's gzip compression library. [http://projects.gnome.org/gnumeric/doc/file-format-gnumeric.shtml][8] + +### CSV + +Comma Separated Value (CSV) file format is a common structuring strategy for text format files. In CSV flies, each line in the file represents a row of data and (within each line of the file) the different data fields (or columns) are separated from one another using a comma (","). If a data field contains a comma, then it should be enclosed (typically in quotation marks ("). Sometimes tabs "\t" or the pipe symbol ("|") are used as separators instead of a comma. Because CSV is a text-only format, it doesn't support any data formatting options. + +### HTML + + + + + + [2]: http://msdn.microsoft.com/en-us/library/cc313154(v=office.12).aspx + [3]: http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/%5bMS-XLS%5d.pdf + [4]: http://msdn.microsoft.com/en-us/library/aa140066%28office.10%29.aspx + [5]: http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm + [6]: http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office + [7]: http://xml.openoffice.org/general.html + [8]: http://projects.gnome.org/gnumeric/doc/file-format-gnumeric.shtml diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/Reader.md b/Documentation/markdown/ReadingSpreadsheetFiles/Reader.md new file mode 100644 index 000000000..9c9c5b797 --- /dev/null +++ b/Documentation/markdown/ReadingSpreadsheetFiles/Reader.md @@ -0,0 +1,521 @@ +# PHPExcel User Documentation – Reading Spreadsheet Files + +## Loading a Spreadsheet File + +The simplest way to load a workbook file is to let PHPExcel's IO Factory identify the file type and load it, calling the static load() method of the PHPExcel_IOFactory class. + +```php +$inputFileName = './sampleData/example1.xls'; + +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = PHPExcel_IOFactory::load($inputFileName); +``` + > See Examples/Reader/exampleReader01.php for a working example of this code. + +The load() method will attempt to identify the file type, and instantiate a loader for that file type; using it to load the file and store the data and any formatting in a PHPExcel object. + +The method makes an initial guess at the loader to instantiate based on the file extension; but will test the file before actually executing the load: so if (for example) the file is actually a CSV file or conatins HTML markup, but that has been given a .xls extension (quite a common practise), it will reject the Excel5 loader that it would normally use for a .xls file; and test the file using the other loaders until it finds the appropriate loader, and then use that to read the file. + +While easy to implement in your code, and you don't need to worry about the file type; this isn't the most efficient method to load a file; and it lacks the flexibility to configure the loader in any way before actually reading the file into a PHPExcel object. + +## Creating a Reader and Loading a Spreadsheet File + +If you know the file type of the spreadsheet file that you need to load, you can instantiate a new reader object for that file type, then use the reader's load() method to read the file to a PHPExcel object. It is possible to instantiate the reader objects for each of the different supported filetype by name. However, you may get unpredictable results if the file isn't of the right type (e.g. it is a CSV with an extension of .xls), although this type of exception should normally be trapped. + +```php +$inputFileName = './sampleData/example1.xls'; + +/** Create a new Excel5 Reader **/ +$objReader = new PHPExcel_Reader_Excel5(); +// $objReader = new PHPExcel_Reader_Excel2007(); +// $objReader = new PHPExcel_Reader_Excel2003XML(); +// $objReader = new PHPExcel_Reader_OOCalc(); +// $objReader = new PHPExcel_Reader_SYLK(); +// $objReader = new PHPExcel_Reader_Gnumeric(); +// $objReader = new PHPExcel_Reader_CSV(); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader02.php for a working example of this code. + +Alternatively, you can use the IO Factory's createReader() method to instantiate the reader object for you, simply telling it the file type of the reader that you want instantiating. + +```php +$inputFileType = 'Excel5'; +// $inputFileType = 'Excel2007'; +// $inputFileType = 'Excel2003XML'; +// $inputFileType = 'OOCalc'; +// $inputFileType = 'SYLK'; +// $inputFileType = 'Gnumeric'; +// $inputFileType = 'CSV'; +$inputFileName = './sampleData/example1.xls'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader03.php for a working example of this code. + +If you're uncertain of the filetype, you can use the IO Factory's identify() method to identify the reader that you need, before using the createReader() method to instantiate the reader object. + +```php +$inputFileName = './sampleData/example1.xls'; + +/** Identify the type of $inputFileName **/ +$inputFileType = PHPExcel_IOFactory::identify($inputFileName); +/** Create a new Reader of the type that has been identified **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader04.php for a working example of this code. + +## Spreadsheet Reader Options + +Once you have created a reader object for the workbook that you want to load, you have the opportunity to set additional options before executing the load() method. + +### Reading Only Data from a Spreadsheet File + +If you're only interested in the cell values in a workbook, but don't need any of the cell formatting information, then you can set the reader to read only the data values and any formulae from each cell using the setReadDataOnly() method. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example1.xls'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Advise the Reader that we only want to load cell data **/ +$objReader->setReadDataOnly(true); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader05.php for a working example of this code. + +It is important to note that Workbooks (and PHPExcel) store dates and times as simple numeric values: they can only be distinguished from other numeric values by the format mask that is applied to that cell. When setting read data only to true, PHPExcel doesn't read the cell format masks, so it is not possible to differentiate between dates/times and numbers. + +The Gnumeric loader has been written to read the format masks for date values even when read data only has been set to true, so it can differentiate between dates/times and numbers; but this change hasn't yet been implemented for the other readers. + +Reading Only Data from a Spreadsheet File applies to Readers: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | YES | Excel5 | YES | Excel2003XML | YES | +OOCalc | YES | SYLK | NO | Gnumeric | YES | +CSV | NO | + +### Reading Only Named WorkSheets from a File + +If your workbook contains a number of worksheets, but you are only interested in reading some of those, then you can use the setLoadSheetsOnly() method to identify those sheets you are interested in reading. + +To read a single sheet, you can pass that sheet name as a parameter to the setLoadSheetsOnly() method. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example1.xls'; +$sheetname = 'Data Sheet #2'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Advise the Reader of which WorkSheets we want to load **/ +$objReader->setLoadSheetsOnly($sheetname); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader07.php for a working example of this code. + +If you want to read more than just a single sheet, you can pass a list of sheet names as an array parameter to the setLoadSheetsOnly() method. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example1.xls'; +$sheetnames = array('Data Sheet #1','Data Sheet #3'); + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Advise the Reader of which WorkSheets we want to load **/ +$objReader->setLoadSheetsOnly($sheetnames); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader08.php for a working example of this code. + +To reset this option to the default, you can call the setLoadAllSheets() method. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example1.xls'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Advise the Reader to load all Worksheets **/ +$objReader->setLoadAllSheets(); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader06.php for a working example of this code. + +Reading Only Named WorkSheets from a File applies to Readers: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | YES | Excel5 | YES | Excel2003XML | YES | +OOCalc | YES | SYLK | NO | Gnumeric | YES | +CSV | NO | + +### Reading Only Specific Columns and Rows from a File (Read Filters) + +If you are only interested in reading part of a worksheet, then you can write a filter class that identifies whether or not individual cells should be read by the loader. A read filter must implement the PHPExcel_Reader_IReadFilter interface, and contain a readCell() method that accepts arguments of $column, $row and $worksheetName, and return a boolean true or false that indicates whether a workbook cell identified by those arguments should be read or not. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example1.xls'; +$sheetname = 'Data Sheet #3'; + + +/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */ +class MyReadFilter implements PHPExcel_Reader_IReadFilter +{ + public function readCell($column, $row, $worksheetName = '') { + // Read rows 1 to 7 and columns A to E only + if ($row >= 1 && $row <= 7) { + if (in_array($column,range('A','E'))) { + return true; + } + } + return false; + } +} + +/** Create an Instance of our Read Filter **/ +$filterSubset = new MyReadFilter(); + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Tell the Reader that we want to use the Read Filter **/ +$objReader->setReadFilter($filterSubset); +/** Load only the rows and columns that match our filter to PHPExcel **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader09.php for a working example of this code. + +This example is not particularly useful, because it can only be used in a very specific circumstance (when you only want cells in the range A1:E7 from your worksheet. A generic Read Filter would probably be more useful: + +```php +/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */ +class MyReadFilter implements PHPExcel_Reader_IReadFilter +{ + private $_startRow = 0; + private $_endRow = 0; + private $_columns = array(); + + /** Get the list of rows and columns to read */ + public function __construct($startRow, $endRow, $columns) { + $this->_startRow = $startRow; + $this->_endRow = $endRow; + $this->_columns = $columns; + } + + public function readCell($column, $row, $worksheetName = '') { + // Only read the rows and columns that were configured + if ($row >= $this->_startRow && $row <= $this->_endRow) { + if (in_array($column,$this->_columns)) { + return true; + } + } + return false; + } +} + +/** Create an Instance of our Read Filter, passing in the cell range **/ +$filterSubset = new MyReadFilter(9,15,range('G','K')); +``` + > See Examples/Reader/exampleReader10.php for a working example of this code. + +This can be particularly useful for conserving memory, by allowing you to read and process a large workbook in “chunks”: an example of this usage might be when transferring data from an Excel worksheet to a database. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example2.xls'; + + +/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */ +class chunkReadFilter implements PHPExcel_Reader_IReadFilter +{ + private $_startRow = 0; + private $_endRow = 0; + + /** Set the list of rows that we want to read */ + public function setRows($startRow, $chunkSize) { + $this->_startRow = $startRow; + $this->_endRow = $startRow + $chunkSize; + } + + public function readCell($column, $row, $worksheetName = '') { + // Only read the heading row, and the configured rows + if (($row == 1) || ($row >= $this->_startRow && $row < $this->_endRow)) { + return true; + } + return false; + } +} + + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); + + +/** Define how many rows we want to read for each "chunk" **/ +$chunkSize = 2048; +/** Create a new Instance of our Read Filter **/ +$chunkFilter = new chunkReadFilter(); + +/** Tell the Reader that we want to use the Read Filter **/ +$objReader->setReadFilter($chunkFilter); + +/** Loop to read our worksheet in "chunk size" blocks **/ +for ($startRow = 2; $startRow <= 65536; $startRow += $chunkSize) { + /** Tell the Read Filter which rows we want this iteration **/ + $chunkFilter->setRows($startRow,$chunkSize); + /** Load only the rows that match our filter **/ + $objPHPExcel = $objReader->load($inputFileName); + // Do some processing here +} +``` + > See Examples/Reader/exampleReader12.php for a working example of this code. + +Using Read Filters applies to: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | YES | Excel5 | YES | Excel2003XML | YES | +OOCalc | YES | SYLK | NO | Gnumeric | YES | +CSV | YES | + +### Combining Multiple Files into a Single PHPExcel Object + +While you can limit the number of worksheets that are read from a workbook file using the setLoadSheetsOnly() method, certain readers also allow you to combine several individual "sheets" from different files into a single PHPExcel object, where each individual file is a single worksheet within that workbook. For each file that you read, you need to indicate which worksheet index it should be loaded into using the setSheetIndex() method of the $objReader, then use the loadIntoExisting() method rather than the load() method to actually read the file into that worksheet. + +```php +$inputFileType = 'CSV'; +$inputFileNames = array('./sampleData/example1.csv', + './sampleData/example2.csv' + './sampleData/example3.csv' +); + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); + + +/** Extract the first named file from the array list **/ +$inputFileName = array_shift($inputFileNames); +/** Load the initial file to the first worksheet in a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +/** Set the worksheet title (to the filename that we've loaded) **/ +$objPHPExcel->getActiveSheet() + ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME)); + + +/** Loop through all the remaining files in the list **/ +foreach($inputFileNames as $sheet => $inputFileName) { + /** Increment the worksheet index pointer for the Reader **/ + $objReader->setSheetIndex($sheet+1); + /** Load the current file into a new worksheet in PHPExcel **/ + $objReader->loadIntoExisting($inputFileName,$objPHPExcel); + /** Set the worksheet title (to the filename that we've loaded) **/ + $objPHPExcel->getActiveSheet() + ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME)); +} +``` + > See Examples/Reader/exampleReader13.php for a working example of this code. + +Note that using the same sheet index for multiple sheets won't append files into the same sheet, but overwrite the results of the previous load. You cannot load multiple CSV files into the same worksheet. + +Combining Multiple Files into a Single PHPExcel Object applies to: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | +OOCalc | NO | SYLK | YES | Gnumeric | NO | +CSV | YES | + +### Combining Read Filters with the setSheetIndex() method to split a large CSV file across multiple Worksheets + +An Excel5 BIFF .xls file is limited to 65536 rows in a worksheet, while the Excel2007 Microsoft Office Open XML SpreadsheetML .xlsx file is limited to 1,048,576 rows in a worksheet; but a CSV file is not limited other than by available disk space. This means that we wouldn’t ordinarily be able to read all the rows from a very large CSV file that exceeded those limits, and save it as an Excel5 or Excel2007 file. However, by using Read Filters to read the CSV file in “chunks” (using the chunkReadFilter Class that we defined in section REF _Ref275604563 \r \p 5.3 above), and the setSheetIndex() method of the $objReader, we can split the CSV file across several individual worksheets. + +```php +$inputFileType = 'CSV'; +$inputFileName = './sampleData/example2.csv'; + + +echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'
'; +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); + + +/** Define how many rows we want to read for each "chunk" **/ +$chunkSize = 65530; +/** Create a new Instance of our Read Filter **/ +$chunkFilter = new chunkReadFilter(); + +/** Tell the Reader that we want to use the Read Filter **/ +/** and that we want to store it in contiguous rows/columns **/ + +$objReader->setReadFilter($chunkFilter) + ->setContiguous(true); + +/** Instantiate a new PHPExcel object manually **/ +$objPHPExcel = new PHPExcel(); + +/** Set a sheet index **/ +$sheet = 0; +/** Loop to read our worksheet in "chunk size" blocks **/ +/** $startRow is set to 2 initially because we always read the headings in row #1 **/ +for ($startRow = 2; $startRow <= 1000000; $startRow += $chunkSize) { + /** Tell the Read Filter which rows we want to read this loop **/ + $chunkFilter->setRows($startRow,$chunkSize); + + /** Increment the worksheet index pointer for the Reader **/ + $objReader->setSheetIndex($sheet); + /** Load only the rows that match our filter into a new worksheet **/ + $objReader->loadIntoExisting($inputFileName,$objPHPExcel); + /** Set the worksheet title for the sheet that we've justloaded) **/ + /** and increment the sheet index as well **/ + $objPHPExcel->getActiveSheet()->setTitle('Country Data #'.(++$sheet)); +} +``` + > See Examples/Reader/exampleReader14.php for a working example of this code. + +This code will read 65,530 rows at a time from the CSV file that we’re loading, and store each "chunk" in a new worksheet. + +The setContiguous() method for the Reader is important here. It is applicable only when working with a Read Filter, and identifies whether or not the cells should be stored by their position within the CSV file, or their position relative to the filter. + +For example, if the filter returned true for cells in the range B2:C3, then with setContiguous set to false (the default) these would be loaded as B2:C3 in the PHPExcel object; but with setContiguous set to true, they would be loaded as A1:B2. + +Splitting a single loaded file across multiple worksheets applies to: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | +OOCalc | NO | SYLK | NO | Gnumeric | NO | +CSV | YES | + +### Pipe or Tab Separated Value Files + +The CSV loader defaults to loading a file where comma is used as the separator, but you can modify this to load tab- or pipe-separated value files using the setDelimiter() method. + +```php +$inputFileType = 'CSV'; +$inputFileName = './sampleData/example1.tsv'; + +/** Create a new Reader of the type defined in $inputFileType **/ $objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Set the delimiter to a TAB character **/ +$objReader->setDelimiter("\t"); +// $objReader->setDelimiter('|'); + +/** Load the file to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader15.php for a working example of this code. + +In addition to the delimiter, you can also use the following methods to set other attributes for the data load: + +setEnclosure() | default is " +setLineEnding() | default is PHP_EOL +setInputEncoding() | default is UTF-8 + +Setting CSV delimiter applies to: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | +OOCalc | NO | SYLK | NO | Gnumeric | NO | +CSV | YES | + +### A Brief Word about the Advanced Value Binder + +When loading data from a file that contains no formatting information, such as a CSV file, then data is read either as strings or numbers (float or integer). This means that PHPExcel does not automatically recognise dates/times (such as "16-Apr-2009" or "13:30"), booleans ("TRUE" or "FALSE"), percentages ("75%"), hyperlinks ("http://www.phpexcel.net/"), etc as anything other than simple strings. However, you can apply additional processing that is executed against these values during the load process within a Value Binder. + +A Value Binder is a class that implement the PHPExcel_Cell_IValueBinder interface. It must contain a bindValue() method that accepts a PHPExcel_Cell and a value as arguments, and return a boolean true or false that indicates whether the workbook cell has been populated with the value or not. The Advanced Value Binder implements such a class: amongst other tests, it identifies a string comprising "TRUE" or "FALSE" (based on locale settings) and sets it to a boolean; or a number in scientific format (e.g. "1.234e-5") and converts it to a float; or dates and times, converting them to their Excel timestamp value – before storing the value in the cell object. It also sets formatting for strings that are identified as dates, times or percentages. It could easily be extended to provide additional handling (including text or cell formatting) when it encountered a hyperlink, or HTML markup within a CSV file. + +So using a Value Binder allows a great deal more flexibility in the loader logic when reading unformatted text files. + +```php +/** Tell PHPExcel that we want to use the Advanced Value Binder **/ +PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); + +$inputFileType = 'CSV'; +$inputFileName = './sampleData/example1.tsv'; + +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +$objReader->setDelimiter("\t"); +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader15.php for a working example of this code. + +Loading using a Value Binder applies to: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | +OOCalc | NO | SYLK | NO | Gnumeric | NO | +CSV | YES | + +## Error Handling + +Of course, you should always apply some error handling to your scripts as well. PHPExcel throws exceptions, so you can wrap all your code that accesses the library methods within Try/Catch blocks to trap for any problems that are encountered, and deal with them in an appropriate manner. + +The PHPExcel Readers throw a PHPExcel_Reader_Exception. + +```php +$inputFileName = './sampleData/example-1.xls'; + +try { + /** Load $inputFileName to a PHPExcel Object **/ + $objPHPExcel = PHPExcel_IOFactory::load($inputFileName); +} catch(PHPExcel_Reader_Exception $e) { + die('Error loading file: '.$e->getMessage()); +} +``` + > See Examples/Reader/exampleReader16.php for a working example of this code. + +## Helper Methods + +You can retrieve a list of worksheet names contained in a file without loading the whole file by using the Reader’s listWorksheetNames() method; similarly, a listWorksheetInfo() method will retrieve the dimensions of worksheet in a file without needing to load and parse the whole file. + +The listWorksheetNames() method returns a simple array listing each worksheet name within the workbook: + +```php +$objReader = PHPExcel_IOFactory::createReader($inputFileType); + +$worksheetNames = $objReader->listWorksheetNames($inputFileName); + +echo '

Worksheet Names

'; +echo '
    '; +foreach ($worksheetNames as $worksheetName) { + echo '
  1. ', $worksheetName, '
  2. '; +} +echo '
'; +``` + > See Examples/Reader/exampleReader18.php for a working example of this code. + +The listWorksheetInfo() method returns a nested array, with each entry listing the name and dimensions for a worksheet: + +```php +$objReader = PHPExcel_IOFactory::createReader($inputFileType); + +$worksheetData = $objReader->listWorksheetInfo($inputFileName); + +echo '

Worksheet Information

'; +echo '
    '; +foreach ($worksheetData as $worksheet) { + echo '
  1. ', $worksheet['worksheetName'], '
    '; + echo 'Rows: ', $worksheet['totalRows'], + ' Columns: ', $worksheet['totalColumns'], '
    '; + echo 'Cell Range: A1:', + $worksheet['lastColumnLetter'], $worksheet['totalRows']; + echo '
  2. '; +} +echo '
'; +``` + > See Examples/Reader/exampleReader19.php for a working example of this code. From 9e5ffa20da56bd7932d6fced83a56024ed6dee14 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 20 May 2013 12:21:56 +0100 Subject: [PATCH 081/467] Reader documentation markdown --- ...{01-file-formats.md => 01-File-Formats.md} | 38 +- .../02-Loading-a-Spreadsheet.md | 21 + .../03-Loading-with-a-Reader.md | 56 +++ .../04-Reader-Options.md | 392 ++++++++++++++++++ .../05-Error-Handling.md | 20 + .../06-Helper-Methods.md | 47 +++ .../ReadingSpreadsheetFiles/Reader.md | 71 ---- 7 files changed, 560 insertions(+), 85 deletions(-) rename Documentation/markdown/ReadingSpreadsheetFiles/{01-file-formats.md => 01-File-Formats.md} (54%) create mode 100644 Documentation/markdown/ReadingSpreadsheetFiles/02-Loading-a-Spreadsheet.md create mode 100644 Documentation/markdown/ReadingSpreadsheetFiles/03-Loading-with-a-Reader.md create mode 100644 Documentation/markdown/ReadingSpreadsheetFiles/04-Reader-Options.md create mode 100644 Documentation/markdown/ReadingSpreadsheetFiles/05-Error-Handling.md create mode 100644 Documentation/markdown/ReadingSpreadsheetFiles/06-Helper-Methods.md diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/01-file-formats.md b/Documentation/markdown/ReadingSpreadsheetFiles/01-File-Formats.md similarity index 54% rename from Documentation/markdown/ReadingSpreadsheetFiles/01-file-formats.md rename to Documentation/markdown/ReadingSpreadsheetFiles/01-File-Formats.md index ad8181d73..d89166437 100644 --- a/Documentation/markdown/ReadingSpreadsheetFiles/01-file-formats.md +++ b/Documentation/markdown/ReadingSpreadsheetFiles/01-File-Formats.md @@ -9,19 +9,19 @@ Currently, PHPExcel supports the following File Types for Reading: ### Excel5 -The Microsoft Excel™ Binary file format (BIFF5 and BIFF8) is a binary file format that was used by Microsoft Excel™ between versions 95 and 2003. The format is supported (to various extents) by most spreadsheet programs. BIFF files normally have an extension of .xls. Documentation describing the format can be found online at [http://msdn.microsoft.com/en-us/library/cc313154(v=office.12).aspx][2] or from [http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/[MS-XLS].pdf][3] (as a downloadable PDF). +The Microsoft Excel™ Binary file format (BIFF5 and BIFF8) is a binary file format that was used by Microsoft Excel™ between versions 95 and 2003. The format is supported (to various extents) by most spreadsheet programs. BIFF files normally have an extension of .xls. Documentation describing the format can be found online at [http://msdn.microsoft.com/en-us/library/cc313154(v=office.12).aspx][1] or from [http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/[MS-XLS].pdf][2] (as a downloadable PDF). ### Excel2003XML -Microsoft Excel™ 2003 included options for a file format called SpreadsheetML. This file is a zipped XML document. It is not very common, but its core features are supported. Documentation for the format can be found at [http://msdn.microsoft.com/en-us/library/aa140066%28office.10%29.aspx][4] though it’s sadly rather sparse in its detail. +Microsoft Excel™ 2003 included options for a file format called SpreadsheetML. This file is a zipped XML document. It is not very common, but its core features are supported. Documentation for the format can be found at [http://msdn.microsoft.com/en-us/library/aa140066%28office.10%29.aspx][3] though it’s sadly rather sparse in its detail. ### Excel2007 -Microsoft Excel™ 2007 shipped with a new file format, namely Microsoft Office Open XML SpreadsheetML, and Excel 2010 extended this still further with its new features such as sparklines. These files typically have an extension of .xlsx. This format is based around a zipped collection of eXtensible Markup Language (XML) files. Microsoft Office Open XML SpreadsheetML is mostly standardized in ECMA 376 ([http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm][5]) and ISO 29500. +Microsoft Excel™ 2007 shipped with a new file format, namely Microsoft Office Open XML SpreadsheetML, and Excel 2010 extended this still further with its new features such as sparklines. These files typically have an extension of .xlsx. This format is based around a zipped collection of eXtensible Markup Language (XML) files. Microsoft Office Open XML SpreadsheetML is mostly standardized in ECMA 376 ([http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm][4]) and ISO 29500. ### OOCalc -aka Open Document Format (ODF) or OASIS, this is the OpenOffice.org XML File Format for spreadsheets. It comprises a zip archive including several components all of which are text files, most of these with markup in the eXtensible Markup Language (XML). It is the standard file format for OpenOffice.org Calc and StarCalc, and files typically have an extension of .ods. The published specification for the file format is available from the OASIS Open Office XML Format Technical Committee web page ([http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office#technical][6]). Other information is available from the OpenOffice.org XML File Format web page ([http://xml.openoffice.org/general.html][7]), part of the OpenOffice.org project. +aka Open Document Format (ODF) or OASIS, this is the OpenOffice.org XML File Format for spreadsheets. It comprises a zip archive including several components all of which are text files, most of these with markup in the eXtensible Markup Language (XML). It is the standard file format for OpenOffice.org Calc and StarCalc, and files typically have an extension of .ods. The published specification for the file format is available from the OASIS Open Office XML Format Technical Committee web page ([http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office#technical][5]). Other information is available from the OpenOffice.org XML File Format web page ([http://xml.openoffice.org/general.html][6]), part of the OpenOffice.org project. ### SYLK @@ -29,22 +29,32 @@ This is the Microsoft Multiplan Symbolic Link Interchange (SYLK) file format. Mu ### Gnumeric -The Gnumeric file format is used by the Gnome Gnumeric spreadsheet application, and typically files have an extension of .gnumeric. The file contents are stored using eXtensible Markup Language (XML) markup, and the file is then compressed using the GNU project's gzip compression library. [http://projects.gnome.org/gnumeric/doc/file-format-gnumeric.shtml][8] +The Gnumeric file format is used by the Gnome Gnumeric spreadsheet application, and typically files have an extension of .gnumeric. The file contents are stored using eXtensible Markup Language (XML) markup, and the file is then compressed using the GNU project's gzip compression library. [http://projects.gnome.org/gnumeric/doc/file-format-gnumeric.shtml][7] ### CSV -Comma Separated Value (CSV) file format is a common structuring strategy for text format files. In CSV flies, each line in the file represents a row of data and (within each line of the file) the different data fields (or columns) are separated from one another using a comma (","). If a data field contains a comma, then it should be enclosed (typically in quotation marks ("). Sometimes tabs "\t" or the pipe symbol ("|") are used as separators instead of a comma. Because CSV is a text-only format, it doesn't support any data formatting options. +Comma Separated Value (CSV) file format is a common structuring strategy for text format files. In CSV flies, each line in the file represents a row of data and (within each line of the file) the different data fields (or columns) are separated from one another using a comma (","). If a data field contains a comma, then it should be enclosed (typically in quotation marks ("). Sometimes tabs "\t", or the pipe symbol ("|"), or a semi-colon (";") are used as separators instead of a comma, although other symbols can be used. Because CSV is a text-only format, it doesn't support any data formatting options. -### HTML +"CSV" is not a single, well-defined format (although see RFC 4180 for one definition that is commonly used). Rather, in practice the term "CSV" refers to any file that: + - is plain text using a character set such as ASCII, Unicode, EBCDIC, or Shift JIS, + - consists of records (typically one record per line), + - with the records divided into fields separated by delimiters (typically a single reserved character such as comma, semicolon, or tab, + - where every record has the same sequence of fields. + +Within these general constraints, many variations are in use. Therefore "CSV" files are not entirely portable. Nevertheless, the variations are fairly small, and many implementations allow users to glance at the file (which is feasible because it is plain text), and then specify the delimiter character(s), quoting rules, etc. +**Warning:** Microsoft Excel™ will open .csv files, but depending on the system's regional settings, it may expect a semicolon as a separator instead of a comma, since in some languages the comma is used as the decimal separator. Also, many regional versions of Excel will not be able to deal with Unicode characters in a CSV file. + +### HTML +HyperText Markup Language (HTML) is the main markup language for creating web pages and other information that can be displayed in a web browser. Files typically have an extension of .html or .htm. HTML markup provides a means to create structured documents by denoting structural semantics for text such as headings, paragraphs, lists, links, quotes and other items. Since 1996, the HTML specifications have been maintained, with input from commercial software vendors, by the World Wide Web Consortium (W3C). However, in 2000, HTML also became an international standard (ISO/IEC 15445:2000). HTML 4.01 was published in late 1999, with further errata published through 2001. In 2004 development began on HTML5 in the Web Hypertext Application Technology Working Group (WHATWG), which became a joint deliverable with the W3C in 2008. - [2]: http://msdn.microsoft.com/en-us/library/cc313154(v=office.12).aspx - [3]: http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/%5bMS-XLS%5d.pdf - [4]: http://msdn.microsoft.com/en-us/library/aa140066%28office.10%29.aspx - [5]: http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm - [6]: http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office - [7]: http://xml.openoffice.org/general.html - [8]: http://projects.gnome.org/gnumeric/doc/file-format-gnumeric.shtml + [1]: http://msdn.microsoft.com/en-us/library/cc313154(v=office.12).aspx + [2]: http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/%5bMS-XLS%5d.pdf + [3]: http://msdn.microsoft.com/en-us/library/aa140066%28office.10%29.aspx + [4]: http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm + [5]: http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office + [6]: http://xml.openoffice.org/general.html + [7]: http://projects.gnome.org/gnumeric/doc/file-format-gnumeric.shtml diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/02-Loading-a-Spreadsheet.md b/Documentation/markdown/ReadingSpreadsheetFiles/02-Loading-a-Spreadsheet.md new file mode 100644 index 000000000..986360f7c --- /dev/null +++ b/Documentation/markdown/ReadingSpreadsheetFiles/02-Loading-a-Spreadsheet.md @@ -0,0 +1,21 @@ +# PHPExcel User Documentation – Reading Spreadsheet Files + + +## Loading a Spreadsheet File + +The simplest way to load a workbook file is to let PHPExcel's IO Factory identify the file type and load it, calling the static load() method of the PHPExcel_IOFactory class. + +```php +$inputFileName = './sampleData/example1.xls'; + +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = PHPExcel_IOFactory::load($inputFileName); +``` + > See Examples/Reader/exampleReader01.php for a working example of this code. + +The load() method will attempt to identify the file type, and instantiate a loader for that file type; using it to load the file and store the data and any formatting in a PHPExcel object. + +The method makes an initial guess at the loader to instantiate based on the file extension; but will test the file before actually executing the load: so if (for example) the file is actually a CSV file or conatins HTML markup, but that has been given a .xls extension (quite a common practise), it will reject the Excel5 loader that it would normally use for a .xls file; and test the file using the other loaders until it finds the appropriate loader, and then use that to read the file. + +While easy to implement in your code, and you don't need to worry about the file type; this isn't the most efficient method to load a file; and it lacks the flexibility to configure the loader in any way before actually reading the file into a PHPExcel object. + diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/03-Loading-with-a-Reader.md b/Documentation/markdown/ReadingSpreadsheetFiles/03-Loading-with-a-Reader.md new file mode 100644 index 000000000..94d07aaa3 --- /dev/null +++ b/Documentation/markdown/ReadingSpreadsheetFiles/03-Loading-with-a-Reader.md @@ -0,0 +1,56 @@ +# PHPExcel User Documentation – Reading Spreadsheet Files + + +## Creating a Reader and Loading a Spreadsheet File + +If you know the file type of the spreadsheet file that you need to load, you can instantiate a new reader object for that file type, then use the reader's load() method to read the file to a PHPExcel object. It is possible to instantiate the reader objects for each of the different supported filetype by name. However, you may get unpredictable results if the file isn't of the right type (e.g. it is a CSV with an extension of .xls), although this type of exception should normally be trapped. + +```php +$inputFileName = './sampleData/example1.xls'; + +/** Create a new Excel5 Reader **/ +$objReader = new PHPExcel_Reader_Excel5(); +// $objReader = new PHPExcel_Reader_Excel2007(); +// $objReader = new PHPExcel_Reader_Excel2003XML(); +// $objReader = new PHPExcel_Reader_OOCalc(); +// $objReader = new PHPExcel_Reader_SYLK(); +// $objReader = new PHPExcel_Reader_Gnumeric(); +// $objReader = new PHPExcel_Reader_CSV(); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader02.php for a working example of this code. + +Alternatively, you can use the IO Factory's createReader() method to instantiate the reader object for you, simply telling it the file type of the reader that you want instantiating. + +```php +$inputFileType = 'Excel5'; +// $inputFileType = 'Excel2007'; +// $inputFileType = 'Excel2003XML'; +// $inputFileType = 'OOCalc'; +// $inputFileType = 'SYLK'; +// $inputFileType = 'Gnumeric'; +// $inputFileType = 'CSV'; +$inputFileName = './sampleData/example1.xls'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader03.php for a working example of this code. + +If you're uncertain of the filetype, you can use the IO Factory's identify() method to identify the reader that you need, before using the createReader() method to instantiate the reader object. + +```php +$inputFileName = './sampleData/example1.xls'; + +/** Identify the type of $inputFileName **/ +$inputFileType = PHPExcel_IOFactory::identify($inputFileName); +/** Create a new Reader of the type that has been identified **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader04.php for a working example of this code. + diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/04-Reader-Options.md b/Documentation/markdown/ReadingSpreadsheetFiles/04-Reader-Options.md new file mode 100644 index 000000000..137fd1e8f --- /dev/null +++ b/Documentation/markdown/ReadingSpreadsheetFiles/04-Reader-Options.md @@ -0,0 +1,392 @@ +# PHPExcel User Documentation – Reading Spreadsheet Files + +## Spreadsheet Reader Options + +Once you have created a reader object for the workbook that you want to load, you have the opportunity to set additional options before executing the load() method. + +### Reading Only Data from a Spreadsheet File + +If you're only interested in the cell values in a workbook, but don't need any of the cell formatting information, then you can set the reader to read only the data values and any formulae from each cell using the setReadDataOnly() method. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example1.xls'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Advise the Reader that we only want to load cell data **/ +$objReader->setReadDataOnly(true); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader05.php for a working example of this code. + +It is important to note that Workbooks (and PHPExcel) store dates and times as simple numeric values: they can only be distinguished from other numeric values by the format mask that is applied to that cell. When setting read data only to true, PHPExcel doesn't read the cell format masks, so it is not possible to differentiate between dates/times and numbers. + +The Gnumeric loader has been written to read the format masks for date values even when read data only has been set to true, so it can differentiate between dates/times and numbers; but this change hasn't yet been implemented for the other readers. + +Reading Only Data from a Spreadsheet File applies to Readers: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | YES | Excel5 | YES | Excel2003XML | YES | +OOCalc | YES | SYLK | NO | Gnumeric | YES | +CSV | NO | HTML | NO + +### Reading Only Named WorkSheets from a File + +If your workbook contains a number of worksheets, but you are only interested in reading some of those, then you can use the setLoadSheetsOnly() method to identify those sheets you are interested in reading. + +To read a single sheet, you can pass that sheet name as a parameter to the setLoadSheetsOnly() method. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example1.xls'; +$sheetname = 'Data Sheet #2'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Advise the Reader of which WorkSheets we want to load **/ +$objReader->setLoadSheetsOnly($sheetname); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader07.php for a working example of this code. + +If you want to read more than just a single sheet, you can pass a list of sheet names as an array parameter to the setLoadSheetsOnly() method. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example1.xls'; +$sheetnames = array('Data Sheet #1','Data Sheet #3'); + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Advise the Reader of which WorkSheets we want to load **/ +$objReader->setLoadSheetsOnly($sheetnames); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader08.php for a working example of this code. + +To reset this option to the default, you can call the setLoadAllSheets() method. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example1.xls'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Advise the Reader to load all Worksheets **/ +$objReader->setLoadAllSheets(); +/** Load $inputFileName to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader06.php for a working example of this code. + +Reading Only Named WorkSheets from a File applies to Readers: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | YES | Excel5 | YES | Excel2003XML | YES | +OOCalc | YES | SYLK | NO | Gnumeric | YES | +CSV | NO | HTML | NO + +### Reading Only Specific Columns and Rows from a File (Read Filters) + +If you are only interested in reading part of a worksheet, then you can write a filter class that identifies whether or not individual cells should be read by the loader. A read filter must implement the PHPExcel_Reader_IReadFilter interface, and contain a readCell() method that accepts arguments of $column, $row and $worksheetName, and return a boolean true or false that indicates whether a workbook cell identified by those arguments should be read or not. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example1.xls'; +$sheetname = 'Data Sheet #3'; + + +/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */ +class MyReadFilter implements PHPExcel_Reader_IReadFilter +{ + public function readCell($column, $row, $worksheetName = '') { + // Read rows 1 to 7 and columns A to E only + if ($row >= 1 && $row <= 7) { + if (in_array($column,range('A','E'))) { + return true; + } + } + return false; + } +} + +/** Create an Instance of our Read Filter **/ +$filterSubset = new MyReadFilter(); + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Tell the Reader that we want to use the Read Filter **/ +$objReader->setReadFilter($filterSubset); +/** Load only the rows and columns that match our filter to PHPExcel **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader09.php for a working example of this code. + +This example is not particularly useful, because it can only be used in a very specific circumstance (when you only want cells in the range A1:E7 from your worksheet. A generic Read Filter would probably be more useful: + +```php +/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */ +class MyReadFilter implements PHPExcel_Reader_IReadFilter +{ + private $_startRow = 0; + private $_endRow = 0; + private $_columns = array(); + + /** Get the list of rows and columns to read */ + public function __construct($startRow, $endRow, $columns) { + $this->_startRow = $startRow; + $this->_endRow = $endRow; + $this->_columns = $columns; + } + + public function readCell($column, $row, $worksheetName = '') { + // Only read the rows and columns that were configured + if ($row >= $this->_startRow && $row <= $this->_endRow) { + if (in_array($column,$this->_columns)) { + return true; + } + } + return false; + } +} + +/** Create an Instance of our Read Filter, passing in the cell range **/ +$filterSubset = new MyReadFilter(9,15,range('G','K')); +``` + > See Examples/Reader/exampleReader10.php for a working example of this code. + +This can be particularly useful for conserving memory, by allowing you to read and process a large workbook in “chunks”: an example of this usage might be when transferring data from an Excel worksheet to a database. + +```php +$inputFileType = 'Excel5'; +$inputFileName = './sampleData/example2.xls'; + + +/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */ +class chunkReadFilter implements PHPExcel_Reader_IReadFilter +{ + private $_startRow = 0; + private $_endRow = 0; + + /** Set the list of rows that we want to read */ + public function setRows($startRow, $chunkSize) { + $this->_startRow = $startRow; + $this->_endRow = $startRow + $chunkSize; + } + + public function readCell($column, $row, $worksheetName = '') { + // Only read the heading row, and the configured rows + if (($row == 1) || ($row >= $this->_startRow && $row < $this->_endRow)) { + return true; + } + return false; + } +} + + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); + + +/** Define how many rows we want to read for each "chunk" **/ +$chunkSize = 2048; +/** Create a new Instance of our Read Filter **/ +$chunkFilter = new chunkReadFilter(); + +/** Tell the Reader that we want to use the Read Filter **/ +$objReader->setReadFilter($chunkFilter); + +/** Loop to read our worksheet in "chunk size" blocks **/ +for ($startRow = 2; $startRow <= 65536; $startRow += $chunkSize) { + /** Tell the Read Filter which rows we want this iteration **/ + $chunkFilter->setRows($startRow,$chunkSize); + /** Load only the rows that match our filter **/ + $objPHPExcel = $objReader->load($inputFileName); + // Do some processing here +} +``` + > See Examples/Reader/exampleReader12.php for a working example of this code. + +Using Read Filters applies to: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | YES | Excel5 | YES | Excel2003XML | YES | +OOCalc | YES | SYLK | NO | Gnumeric | YES | +CSV | YES | HTML | NO + +### Combining Multiple Files into a Single PHPExcel Object + +While you can limit the number of worksheets that are read from a workbook file using the setLoadSheetsOnly() method, certain readers also allow you to combine several individual "sheets" from different files into a single PHPExcel object, where each individual file is a single worksheet within that workbook. For each file that you read, you need to indicate which worksheet index it should be loaded into using the setSheetIndex() method of the $objReader, then use the loadIntoExisting() method rather than the load() method to actually read the file into that worksheet. + +```php +$inputFileType = 'CSV'; +$inputFileNames = array('./sampleData/example1.csv', + './sampleData/example2.csv' + './sampleData/example3.csv' +); + +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); + + +/** Extract the first named file from the array list **/ +$inputFileName = array_shift($inputFileNames); +/** Load the initial file to the first worksheet in a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +/** Set the worksheet title (to the filename that we've loaded) **/ +$objPHPExcel->getActiveSheet() + ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME)); + + +/** Loop through all the remaining files in the list **/ +foreach($inputFileNames as $sheet => $inputFileName) { + /** Increment the worksheet index pointer for the Reader **/ + $objReader->setSheetIndex($sheet+1); + /** Load the current file into a new worksheet in PHPExcel **/ + $objReader->loadIntoExisting($inputFileName,$objPHPExcel); + /** Set the worksheet title (to the filename that we've loaded) **/ + $objPHPExcel->getActiveSheet() + ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME)); +} +``` + > See Examples/Reader/exampleReader13.php for a working example of this code. + +Note that using the same sheet index for multiple sheets won't append files into the same sheet, but overwrite the results of the previous load. You cannot load multiple CSV files into the same worksheet. + +Combining Multiple Files into a Single PHPExcel Object applies to: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | +OOCalc | NO | SYLK | YES | Gnumeric | NO | +CSV | YES | HTML | NO + +### Combining Read Filters with the setSheetIndex() method to split a large CSV file across multiple Worksheets + +An Excel5 BIFF .xls file is limited to 65536 rows in a worksheet, while the Excel2007 Microsoft Office Open XML SpreadsheetML .xlsx file is limited to 1,048,576 rows in a worksheet; but a CSV file is not limited other than by available disk space. This means that we wouldn’t ordinarily be able to read all the rows from a very large CSV file that exceeded those limits, and save it as an Excel5 or Excel2007 file. However, by using Read Filters to read the CSV file in “chunks” (using the chunkReadFilter Class that we defined in section REF _Ref275604563 \r \p 5.3 above), and the setSheetIndex() method of the $objReader, we can split the CSV file across several individual worksheets. + +```php +$inputFileType = 'CSV'; +$inputFileName = './sampleData/example2.csv'; + + +echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'
'; +/** Create a new Reader of the type defined in $inputFileType **/ +$objReader = PHPExcel_IOFactory::createReader($inputFileType); + + +/** Define how many rows we want to read for each "chunk" **/ +$chunkSize = 65530; +/** Create a new Instance of our Read Filter **/ +$chunkFilter = new chunkReadFilter(); + +/** Tell the Reader that we want to use the Read Filter **/ +/** and that we want to store it in contiguous rows/columns **/ + +$objReader->setReadFilter($chunkFilter) + ->setContiguous(true); + +/** Instantiate a new PHPExcel object manually **/ +$objPHPExcel = new PHPExcel(); + +/** Set a sheet index **/ +$sheet = 0; +/** Loop to read our worksheet in "chunk size" blocks **/ +/** $startRow is set to 2 initially because we always read the headings in row #1 **/ +for ($startRow = 2; $startRow <= 1000000; $startRow += $chunkSize) { + /** Tell the Read Filter which rows we want to read this loop **/ + $chunkFilter->setRows($startRow,$chunkSize); + + /** Increment the worksheet index pointer for the Reader **/ + $objReader->setSheetIndex($sheet); + /** Load only the rows that match our filter into a new worksheet **/ + $objReader->loadIntoExisting($inputFileName,$objPHPExcel); + /** Set the worksheet title for the sheet that we've justloaded) **/ + /** and increment the sheet index as well **/ + $objPHPExcel->getActiveSheet()->setTitle('Country Data #'.(++$sheet)); +} +``` + > See Examples/Reader/exampleReader14.php for a working example of this code. + +This code will read 65,530 rows at a time from the CSV file that we’re loading, and store each "chunk" in a new worksheet. + +The setContiguous() method for the Reader is important here. It is applicable only when working with a Read Filter, and identifies whether or not the cells should be stored by their position within the CSV file, or their position relative to the filter. + +For example, if the filter returned true for cells in the range B2:C3, then with setContiguous set to false (the default) these would be loaded as B2:C3 in the PHPExcel object; but with setContiguous set to true, they would be loaded as A1:B2. + +Splitting a single loaded file across multiple worksheets applies to: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | +OOCalc | NO | SYLK | NO | Gnumeric | NO | +CSV | YES | HTML | NO + +### Pipe or Tab Separated Value Files + +The CSV loader defaults to loading a file where comma is used as the separator, but you can modify this to load tab- or pipe-separated value files using the setDelimiter() method. + +```php +$inputFileType = 'CSV'; +$inputFileName = './sampleData/example1.tsv'; + +/** Create a new Reader of the type defined in $inputFileType **/ $objReader = PHPExcel_IOFactory::createReader($inputFileType); +/** Set the delimiter to a TAB character **/ +$objReader->setDelimiter("\t"); +// $objReader->setDelimiter('|'); + +/** Load the file to a PHPExcel Object **/ +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader15.php for a working example of this code. + +In addition to the delimiter, you can also use the following methods to set other attributes for the data load: + +setEnclosure() | default is " +setLineEnding() | default is PHP_EOL +setInputEncoding() | default is UTF-8 + +Setting CSV delimiter applies to: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | +OOCalc | NO | SYLK | NO | Gnumeric | NO | +CSV | YES | HTML | NO + +### A Brief Word about the Advanced Value Binder + +When loading data from a file that contains no formatting information, such as a CSV file, then data is read either as strings or numbers (float or integer). This means that PHPExcel does not automatically recognise dates/times (such as "16-Apr-2009" or "13:30"), booleans ("TRUE" or "FALSE"), percentages ("75%"), hyperlinks ("http://www.phpexcel.net/"), etc as anything other than simple strings. However, you can apply additional processing that is executed against these values during the load process within a Value Binder. + +A Value Binder is a class that implement the PHPExcel_Cell_IValueBinder interface. It must contain a bindValue() method that accepts a PHPExcel_Cell and a value as arguments, and return a boolean true or false that indicates whether the workbook cell has been populated with the value or not. The Advanced Value Binder implements such a class: amongst other tests, it identifies a string comprising "TRUE" or "FALSE" (based on locale settings) and sets it to a boolean; or a number in scientific format (e.g. "1.234e-5") and converts it to a float; or dates and times, converting them to their Excel timestamp value – before storing the value in the cell object. It also sets formatting for strings that are identified as dates, times or percentages. It could easily be extended to provide additional handling (including text or cell formatting) when it encountered a hyperlink, or HTML markup within a CSV file. + +So using a Value Binder allows a great deal more flexibility in the loader logic when reading unformatted text files. + +```php +/** Tell PHPExcel that we want to use the Advanced Value Binder **/ +PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); + +$inputFileType = 'CSV'; +$inputFileName = './sampleData/example1.tsv'; + +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +$objReader->setDelimiter("\t"); +$objPHPExcel = $objReader->load($inputFileName); +``` + > See Examples/Reader/exampleReader15.php for a working example of this code. + +Loading using a Value Binder applies to: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | +OOCalc | NO | SYLK | NO | Gnumeric | NO | +CSV | YES | HTML | YES + diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/05-Error-Handling.md b/Documentation/markdown/ReadingSpreadsheetFiles/05-Error-Handling.md new file mode 100644 index 000000000..d3e064f9b --- /dev/null +++ b/Documentation/markdown/ReadingSpreadsheetFiles/05-Error-Handling.md @@ -0,0 +1,20 @@ +# PHPExcel User Documentation – Reading Spreadsheet Files + +## Error Handling + +Of course, you should always apply some error handling to your scripts as well. PHPExcel throws exceptions, so you can wrap all your code that accesses the library methods within Try/Catch blocks to trap for any problems that are encountered, and deal with them in an appropriate manner. + +The PHPExcel Readers throw a PHPExcel_Reader_Exception. + +```php +$inputFileName = './sampleData/example-1.xls'; + +try { + /** Load $inputFileName to a PHPExcel Object **/ + $objPHPExcel = PHPExcel_IOFactory::load($inputFileName); +} catch(PHPExcel_Reader_Exception $e) { + die('Error loading file: '.$e->getMessage()); +} +``` + > See Examples/Reader/exampleReader16.php for a working example of this code. + diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/06-Helper-Methods.md b/Documentation/markdown/ReadingSpreadsheetFiles/06-Helper-Methods.md new file mode 100644 index 000000000..57dbec7a7 --- /dev/null +++ b/Documentation/markdown/ReadingSpreadsheetFiles/06-Helper-Methods.md @@ -0,0 +1,47 @@ +# PHPExcel User Documentation – Reading Spreadsheet Files + + +## Helper Methods + +You can retrieve a list of worksheet names contained in a file without loading the whole file by using the Reader’s `listWorksheetNames()` method; similarly, a `listWorksheetInfo()` method will retrieve the dimensions of worksheet in a file without needing to load and parse the whole file. + +### listWorksheetNames + +The `listWorksheetNames()` method returns a simple array listing each worksheet name within the workbook: + +```php +$objReader = PHPExcel_IOFactory::createReader($inputFileType); + +$worksheetNames = $objReader->listWorksheetNames($inputFileName); + +echo '

Worksheet Names

'; +echo '
    '; +foreach ($worksheetNames as $worksheetName) { + echo '
  1. ', $worksheetName, '
  2. '; +} +echo '
'; +``` + > See Examples/Reader/exampleReader18.php for a working example of this code. + +### listWorksheetInfo + +The `listWorksheetInfo()` method returns a nested array, with each entry listing the name and dimensions for a worksheet: + +```php +$objReader = PHPExcel_IOFactory::createReader($inputFileType); + +$worksheetData = $objReader->listWorksheetInfo($inputFileName); + +echo '

Worksheet Information

'; +echo '
    '; +foreach ($worksheetData as $worksheet) { + echo '
  1. ', $worksheet['worksheetName'], '
    '; + echo 'Rows: ', $worksheet['totalRows'], + ' Columns: ', $worksheet['totalColumns'], '
    '; + echo 'Cell Range: A1:', + $worksheet['lastColumnLetter'], $worksheet['totalRows']; + echo '
  2. '; +} +echo '
'; +``` + > See Examples/Reader/exampleReader19.php for a working example of this code. diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/Reader.md b/Documentation/markdown/ReadingSpreadsheetFiles/Reader.md index 9c9c5b797..1da31a911 100644 --- a/Documentation/markdown/ReadingSpreadsheetFiles/Reader.md +++ b/Documentation/markdown/ReadingSpreadsheetFiles/Reader.md @@ -1,76 +1,5 @@ # PHPExcel User Documentation – Reading Spreadsheet Files -## Loading a Spreadsheet File - -The simplest way to load a workbook file is to let PHPExcel's IO Factory identify the file type and load it, calling the static load() method of the PHPExcel_IOFactory class. - -```php -$inputFileName = './sampleData/example1.xls'; - -/** Load $inputFileName to a PHPExcel Object **/ -$objPHPExcel = PHPExcel_IOFactory::load($inputFileName); -``` - > See Examples/Reader/exampleReader01.php for a working example of this code. - -The load() method will attempt to identify the file type, and instantiate a loader for that file type; using it to load the file and store the data and any formatting in a PHPExcel object. - -The method makes an initial guess at the loader to instantiate based on the file extension; but will test the file before actually executing the load: so if (for example) the file is actually a CSV file or conatins HTML markup, but that has been given a .xls extension (quite a common practise), it will reject the Excel5 loader that it would normally use for a .xls file; and test the file using the other loaders until it finds the appropriate loader, and then use that to read the file. - -While easy to implement in your code, and you don't need to worry about the file type; this isn't the most efficient method to load a file; and it lacks the flexibility to configure the loader in any way before actually reading the file into a PHPExcel object. - -## Creating a Reader and Loading a Spreadsheet File - -If you know the file type of the spreadsheet file that you need to load, you can instantiate a new reader object for that file type, then use the reader's load() method to read the file to a PHPExcel object. It is possible to instantiate the reader objects for each of the different supported filetype by name. However, you may get unpredictable results if the file isn't of the right type (e.g. it is a CSV with an extension of .xls), although this type of exception should normally be trapped. - -```php -$inputFileName = './sampleData/example1.xls'; - -/** Create a new Excel5 Reader **/ -$objReader = new PHPExcel_Reader_Excel5(); -// $objReader = new PHPExcel_Reader_Excel2007(); -// $objReader = new PHPExcel_Reader_Excel2003XML(); -// $objReader = new PHPExcel_Reader_OOCalc(); -// $objReader = new PHPExcel_Reader_SYLK(); -// $objReader = new PHPExcel_Reader_Gnumeric(); -// $objReader = new PHPExcel_Reader_CSV(); -/** Load $inputFileName to a PHPExcel Object **/ -$objPHPExcel = $objReader->load($inputFileName); -``` - > See Examples/Reader/exampleReader02.php for a working example of this code. - -Alternatively, you can use the IO Factory's createReader() method to instantiate the reader object for you, simply telling it the file type of the reader that you want instantiating. - -```php -$inputFileType = 'Excel5'; -// $inputFileType = 'Excel2007'; -// $inputFileType = 'Excel2003XML'; -// $inputFileType = 'OOCalc'; -// $inputFileType = 'SYLK'; -// $inputFileType = 'Gnumeric'; -// $inputFileType = 'CSV'; -$inputFileName = './sampleData/example1.xls'; - -/** Create a new Reader of the type defined in $inputFileType **/ -$objReader = PHPExcel_IOFactory::createReader($inputFileType); -/** Load $inputFileName to a PHPExcel Object **/ -$objPHPExcel = $objReader->load($inputFileName); -``` - > See Examples/Reader/exampleReader03.php for a working example of this code. - -If you're uncertain of the filetype, you can use the IO Factory's identify() method to identify the reader that you need, before using the createReader() method to instantiate the reader object. - -```php -$inputFileName = './sampleData/example1.xls'; - -/** Identify the type of $inputFileName **/ -$inputFileType = PHPExcel_IOFactory::identify($inputFileName); -/** Create a new Reader of the type that has been identified **/ -$objReader = PHPExcel_IOFactory::createReader($inputFileType); -/** Load $inputFileName to a PHPExcel Object **/ -$objPHPExcel = $objReader->load($inputFileName); -``` - > See Examples/Reader/exampleReader04.php for a working example of this code. - ## Spreadsheet Reader Options Once you have created a reader object for the workbook that you want to load, you have the opportunity to set additional options before executing the load() method. From 46982cf09801d70729fb219a2ba25caf144fbd42 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 20 May 2013 12:23:07 +0100 Subject: [PATCH 082/467] Reader documentation markdown --- .../ReadingSpreadsheetFiles/Reader.md | 450 ------------------ 1 file changed, 450 deletions(-) delete mode 100644 Documentation/markdown/ReadingSpreadsheetFiles/Reader.md diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/Reader.md b/Documentation/markdown/ReadingSpreadsheetFiles/Reader.md deleted file mode 100644 index 1da31a911..000000000 --- a/Documentation/markdown/ReadingSpreadsheetFiles/Reader.md +++ /dev/null @@ -1,450 +0,0 @@ -# PHPExcel User Documentation – Reading Spreadsheet Files - -## Spreadsheet Reader Options - -Once you have created a reader object for the workbook that you want to load, you have the opportunity to set additional options before executing the load() method. - -### Reading Only Data from a Spreadsheet File - -If you're only interested in the cell values in a workbook, but don't need any of the cell formatting information, then you can set the reader to read only the data values and any formulae from each cell using the setReadDataOnly() method. - -```php -$inputFileType = 'Excel5'; -$inputFileName = './sampleData/example1.xls'; - -/** Create a new Reader of the type defined in $inputFileType **/ -$objReader = PHPExcel_IOFactory::createReader($inputFileType); -/** Advise the Reader that we only want to load cell data **/ -$objReader->setReadDataOnly(true); -/** Load $inputFileName to a PHPExcel Object **/ -$objPHPExcel = $objReader->load($inputFileName); -``` - > See Examples/Reader/exampleReader05.php for a working example of this code. - -It is important to note that Workbooks (and PHPExcel) store dates and times as simple numeric values: they can only be distinguished from other numeric values by the format mask that is applied to that cell. When setting read data only to true, PHPExcel doesn't read the cell format masks, so it is not possible to differentiate between dates/times and numbers. - -The Gnumeric loader has been written to read the format masks for date values even when read data only has been set to true, so it can differentiate between dates/times and numbers; but this change hasn't yet been implemented for the other readers. - -Reading Only Data from a Spreadsheet File applies to Readers: - -Reader | Y/N |Reader | Y/N |Reader | Y/N | -----------|:---:|--------|:---:|--------------|:---:| -Excel2007 | YES | Excel5 | YES | Excel2003XML | YES | -OOCalc | YES | SYLK | NO | Gnumeric | YES | -CSV | NO | - -### Reading Only Named WorkSheets from a File - -If your workbook contains a number of worksheets, but you are only interested in reading some of those, then you can use the setLoadSheetsOnly() method to identify those sheets you are interested in reading. - -To read a single sheet, you can pass that sheet name as a parameter to the setLoadSheetsOnly() method. - -```php -$inputFileType = 'Excel5'; -$inputFileName = './sampleData/example1.xls'; -$sheetname = 'Data Sheet #2'; - -/** Create a new Reader of the type defined in $inputFileType **/ -$objReader = PHPExcel_IOFactory::createReader($inputFileType); -/** Advise the Reader of which WorkSheets we want to load **/ -$objReader->setLoadSheetsOnly($sheetname); -/** Load $inputFileName to a PHPExcel Object **/ -$objPHPExcel = $objReader->load($inputFileName); -``` - > See Examples/Reader/exampleReader07.php for a working example of this code. - -If you want to read more than just a single sheet, you can pass a list of sheet names as an array parameter to the setLoadSheetsOnly() method. - -```php -$inputFileType = 'Excel5'; -$inputFileName = './sampleData/example1.xls'; -$sheetnames = array('Data Sheet #1','Data Sheet #3'); - -/** Create a new Reader of the type defined in $inputFileType **/ -$objReader = PHPExcel_IOFactory::createReader($inputFileType); -/** Advise the Reader of which WorkSheets we want to load **/ -$objReader->setLoadSheetsOnly($sheetnames); -/** Load $inputFileName to a PHPExcel Object **/ -$objPHPExcel = $objReader->load($inputFileName); -``` - > See Examples/Reader/exampleReader08.php for a working example of this code. - -To reset this option to the default, you can call the setLoadAllSheets() method. - -```php -$inputFileType = 'Excel5'; -$inputFileName = './sampleData/example1.xls'; - -/** Create a new Reader of the type defined in $inputFileType **/ -$objReader = PHPExcel_IOFactory::createReader($inputFileType); -/** Advise the Reader to load all Worksheets **/ -$objReader->setLoadAllSheets(); -/** Load $inputFileName to a PHPExcel Object **/ -$objPHPExcel = $objReader->load($inputFileName); -``` - > See Examples/Reader/exampleReader06.php for a working example of this code. - -Reading Only Named WorkSheets from a File applies to Readers: - -Reader | Y/N |Reader | Y/N |Reader | Y/N | -----------|:---:|--------|:---:|--------------|:---:| -Excel2007 | YES | Excel5 | YES | Excel2003XML | YES | -OOCalc | YES | SYLK | NO | Gnumeric | YES | -CSV | NO | - -### Reading Only Specific Columns and Rows from a File (Read Filters) - -If you are only interested in reading part of a worksheet, then you can write a filter class that identifies whether or not individual cells should be read by the loader. A read filter must implement the PHPExcel_Reader_IReadFilter interface, and contain a readCell() method that accepts arguments of $column, $row and $worksheetName, and return a boolean true or false that indicates whether a workbook cell identified by those arguments should be read or not. - -```php -$inputFileType = 'Excel5'; -$inputFileName = './sampleData/example1.xls'; -$sheetname = 'Data Sheet #3'; - - -/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */ -class MyReadFilter implements PHPExcel_Reader_IReadFilter -{ - public function readCell($column, $row, $worksheetName = '') { - // Read rows 1 to 7 and columns A to E only - if ($row >= 1 && $row <= 7) { - if (in_array($column,range('A','E'))) { - return true; - } - } - return false; - } -} - -/** Create an Instance of our Read Filter **/ -$filterSubset = new MyReadFilter(); - -/** Create a new Reader of the type defined in $inputFileType **/ -$objReader = PHPExcel_IOFactory::createReader($inputFileType); -/** Tell the Reader that we want to use the Read Filter **/ -$objReader->setReadFilter($filterSubset); -/** Load only the rows and columns that match our filter to PHPExcel **/ -$objPHPExcel = $objReader->load($inputFileName); -``` - > See Examples/Reader/exampleReader09.php for a working example of this code. - -This example is not particularly useful, because it can only be used in a very specific circumstance (when you only want cells in the range A1:E7 from your worksheet. A generic Read Filter would probably be more useful: - -```php -/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */ -class MyReadFilter implements PHPExcel_Reader_IReadFilter -{ - private $_startRow = 0; - private $_endRow = 0; - private $_columns = array(); - - /** Get the list of rows and columns to read */ - public function __construct($startRow, $endRow, $columns) { - $this->_startRow = $startRow; - $this->_endRow = $endRow; - $this->_columns = $columns; - } - - public function readCell($column, $row, $worksheetName = '') { - // Only read the rows and columns that were configured - if ($row >= $this->_startRow && $row <= $this->_endRow) { - if (in_array($column,$this->_columns)) { - return true; - } - } - return false; - } -} - -/** Create an Instance of our Read Filter, passing in the cell range **/ -$filterSubset = new MyReadFilter(9,15,range('G','K')); -``` - > See Examples/Reader/exampleReader10.php for a working example of this code. - -This can be particularly useful for conserving memory, by allowing you to read and process a large workbook in “chunks”: an example of this usage might be when transferring data from an Excel worksheet to a database. - -```php -$inputFileType = 'Excel5'; -$inputFileName = './sampleData/example2.xls'; - - -/** Define a Read Filter class implementing PHPExcel_Reader_IReadFilter */ -class chunkReadFilter implements PHPExcel_Reader_IReadFilter -{ - private $_startRow = 0; - private $_endRow = 0; - - /** Set the list of rows that we want to read */ - public function setRows($startRow, $chunkSize) { - $this->_startRow = $startRow; - $this->_endRow = $startRow + $chunkSize; - } - - public function readCell($column, $row, $worksheetName = '') { - // Only read the heading row, and the configured rows - if (($row == 1) || ($row >= $this->_startRow && $row < $this->_endRow)) { - return true; - } - return false; - } -} - - -/** Create a new Reader of the type defined in $inputFileType **/ -$objReader = PHPExcel_IOFactory::createReader($inputFileType); - - -/** Define how many rows we want to read for each "chunk" **/ -$chunkSize = 2048; -/** Create a new Instance of our Read Filter **/ -$chunkFilter = new chunkReadFilter(); - -/** Tell the Reader that we want to use the Read Filter **/ -$objReader->setReadFilter($chunkFilter); - -/** Loop to read our worksheet in "chunk size" blocks **/ -for ($startRow = 2; $startRow <= 65536; $startRow += $chunkSize) { - /** Tell the Read Filter which rows we want this iteration **/ - $chunkFilter->setRows($startRow,$chunkSize); - /** Load only the rows that match our filter **/ - $objPHPExcel = $objReader->load($inputFileName); - // Do some processing here -} -``` - > See Examples/Reader/exampleReader12.php for a working example of this code. - -Using Read Filters applies to: - -Reader | Y/N |Reader | Y/N |Reader | Y/N | -----------|:---:|--------|:---:|--------------|:---:| -Excel2007 | YES | Excel5 | YES | Excel2003XML | YES | -OOCalc | YES | SYLK | NO | Gnumeric | YES | -CSV | YES | - -### Combining Multiple Files into a Single PHPExcel Object - -While you can limit the number of worksheets that are read from a workbook file using the setLoadSheetsOnly() method, certain readers also allow you to combine several individual "sheets" from different files into a single PHPExcel object, where each individual file is a single worksheet within that workbook. For each file that you read, you need to indicate which worksheet index it should be loaded into using the setSheetIndex() method of the $objReader, then use the loadIntoExisting() method rather than the load() method to actually read the file into that worksheet. - -```php -$inputFileType = 'CSV'; -$inputFileNames = array('./sampleData/example1.csv', - './sampleData/example2.csv' - './sampleData/example3.csv' -); - -/** Create a new Reader of the type defined in $inputFileType **/ -$objReader = PHPExcel_IOFactory::createReader($inputFileType); - - -/** Extract the first named file from the array list **/ -$inputFileName = array_shift($inputFileNames); -/** Load the initial file to the first worksheet in a PHPExcel Object **/ -$objPHPExcel = $objReader->load($inputFileName); -/** Set the worksheet title (to the filename that we've loaded) **/ -$objPHPExcel->getActiveSheet() - ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME)); - - -/** Loop through all the remaining files in the list **/ -foreach($inputFileNames as $sheet => $inputFileName) { - /** Increment the worksheet index pointer for the Reader **/ - $objReader->setSheetIndex($sheet+1); - /** Load the current file into a new worksheet in PHPExcel **/ - $objReader->loadIntoExisting($inputFileName,$objPHPExcel); - /** Set the worksheet title (to the filename that we've loaded) **/ - $objPHPExcel->getActiveSheet() - ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME)); -} -``` - > See Examples/Reader/exampleReader13.php for a working example of this code. - -Note that using the same sheet index for multiple sheets won't append files into the same sheet, but overwrite the results of the previous load. You cannot load multiple CSV files into the same worksheet. - -Combining Multiple Files into a Single PHPExcel Object applies to: - -Reader | Y/N |Reader | Y/N |Reader | Y/N | -----------|:---:|--------|:---:|--------------|:---:| -Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | -OOCalc | NO | SYLK | YES | Gnumeric | NO | -CSV | YES | - -### Combining Read Filters with the setSheetIndex() method to split a large CSV file across multiple Worksheets - -An Excel5 BIFF .xls file is limited to 65536 rows in a worksheet, while the Excel2007 Microsoft Office Open XML SpreadsheetML .xlsx file is limited to 1,048,576 rows in a worksheet; but a CSV file is not limited other than by available disk space. This means that we wouldn’t ordinarily be able to read all the rows from a very large CSV file that exceeded those limits, and save it as an Excel5 or Excel2007 file. However, by using Read Filters to read the CSV file in “chunks” (using the chunkReadFilter Class that we defined in section REF _Ref275604563 \r \p 5.3 above), and the setSheetIndex() method of the $objReader, we can split the CSV file across several individual worksheets. - -```php -$inputFileType = 'CSV'; -$inputFileName = './sampleData/example2.csv'; - - -echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'
'; -/** Create a new Reader of the type defined in $inputFileType **/ -$objReader = PHPExcel_IOFactory::createReader($inputFileType); - - -/** Define how many rows we want to read for each "chunk" **/ -$chunkSize = 65530; -/** Create a new Instance of our Read Filter **/ -$chunkFilter = new chunkReadFilter(); - -/** Tell the Reader that we want to use the Read Filter **/ -/** and that we want to store it in contiguous rows/columns **/ - -$objReader->setReadFilter($chunkFilter) - ->setContiguous(true); - -/** Instantiate a new PHPExcel object manually **/ -$objPHPExcel = new PHPExcel(); - -/** Set a sheet index **/ -$sheet = 0; -/** Loop to read our worksheet in "chunk size" blocks **/ -/** $startRow is set to 2 initially because we always read the headings in row #1 **/ -for ($startRow = 2; $startRow <= 1000000; $startRow += $chunkSize) { - /** Tell the Read Filter which rows we want to read this loop **/ - $chunkFilter->setRows($startRow,$chunkSize); - - /** Increment the worksheet index pointer for the Reader **/ - $objReader->setSheetIndex($sheet); - /** Load only the rows that match our filter into a new worksheet **/ - $objReader->loadIntoExisting($inputFileName,$objPHPExcel); - /** Set the worksheet title for the sheet that we've justloaded) **/ - /** and increment the sheet index as well **/ - $objPHPExcel->getActiveSheet()->setTitle('Country Data #'.(++$sheet)); -} -``` - > See Examples/Reader/exampleReader14.php for a working example of this code. - -This code will read 65,530 rows at a time from the CSV file that we’re loading, and store each "chunk" in a new worksheet. - -The setContiguous() method for the Reader is important here. It is applicable only when working with a Read Filter, and identifies whether or not the cells should be stored by their position within the CSV file, or their position relative to the filter. - -For example, if the filter returned true for cells in the range B2:C3, then with setContiguous set to false (the default) these would be loaded as B2:C3 in the PHPExcel object; but with setContiguous set to true, they would be loaded as A1:B2. - -Splitting a single loaded file across multiple worksheets applies to: - -Reader | Y/N |Reader | Y/N |Reader | Y/N | -----------|:---:|--------|:---:|--------------|:---:| -Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | -OOCalc | NO | SYLK | NO | Gnumeric | NO | -CSV | YES | - -### Pipe or Tab Separated Value Files - -The CSV loader defaults to loading a file where comma is used as the separator, but you can modify this to load tab- or pipe-separated value files using the setDelimiter() method. - -```php -$inputFileType = 'CSV'; -$inputFileName = './sampleData/example1.tsv'; - -/** Create a new Reader of the type defined in $inputFileType **/ $objReader = PHPExcel_IOFactory::createReader($inputFileType); -/** Set the delimiter to a TAB character **/ -$objReader->setDelimiter("\t"); -// $objReader->setDelimiter('|'); - -/** Load the file to a PHPExcel Object **/ -$objPHPExcel = $objReader->load($inputFileName); -``` - > See Examples/Reader/exampleReader15.php for a working example of this code. - -In addition to the delimiter, you can also use the following methods to set other attributes for the data load: - -setEnclosure() | default is " -setLineEnding() | default is PHP_EOL -setInputEncoding() | default is UTF-8 - -Setting CSV delimiter applies to: - -Reader | Y/N |Reader | Y/N |Reader | Y/N | -----------|:---:|--------|:---:|--------------|:---:| -Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | -OOCalc | NO | SYLK | NO | Gnumeric | NO | -CSV | YES | - -### A Brief Word about the Advanced Value Binder - -When loading data from a file that contains no formatting information, such as a CSV file, then data is read either as strings or numbers (float or integer). This means that PHPExcel does not automatically recognise dates/times (such as "16-Apr-2009" or "13:30"), booleans ("TRUE" or "FALSE"), percentages ("75%"), hyperlinks ("http://www.phpexcel.net/"), etc as anything other than simple strings. However, you can apply additional processing that is executed against these values during the load process within a Value Binder. - -A Value Binder is a class that implement the PHPExcel_Cell_IValueBinder interface. It must contain a bindValue() method that accepts a PHPExcel_Cell and a value as arguments, and return a boolean true or false that indicates whether the workbook cell has been populated with the value or not. The Advanced Value Binder implements such a class: amongst other tests, it identifies a string comprising "TRUE" or "FALSE" (based on locale settings) and sets it to a boolean; or a number in scientific format (e.g. "1.234e-5") and converts it to a float; or dates and times, converting them to their Excel timestamp value – before storing the value in the cell object. It also sets formatting for strings that are identified as dates, times or percentages. It could easily be extended to provide additional handling (including text or cell formatting) when it encountered a hyperlink, or HTML markup within a CSV file. - -So using a Value Binder allows a great deal more flexibility in the loader logic when reading unformatted text files. - -```php -/** Tell PHPExcel that we want to use the Advanced Value Binder **/ -PHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() ); - -$inputFileType = 'CSV'; -$inputFileName = './sampleData/example1.tsv'; - -$objReader = PHPExcel_IOFactory::createReader($inputFileType); -$objReader->setDelimiter("\t"); -$objPHPExcel = $objReader->load($inputFileName); -``` - > See Examples/Reader/exampleReader15.php for a working example of this code. - -Loading using a Value Binder applies to: - -Reader | Y/N |Reader | Y/N |Reader | Y/N | -----------|:---:|--------|:---:|--------------|:---:| -Excel2007 | NO | Excel5 | NO | Excel2003XML | NO | -OOCalc | NO | SYLK | NO | Gnumeric | NO | -CSV | YES | - -## Error Handling - -Of course, you should always apply some error handling to your scripts as well. PHPExcel throws exceptions, so you can wrap all your code that accesses the library methods within Try/Catch blocks to trap for any problems that are encountered, and deal with them in an appropriate manner. - -The PHPExcel Readers throw a PHPExcel_Reader_Exception. - -```php -$inputFileName = './sampleData/example-1.xls'; - -try { - /** Load $inputFileName to a PHPExcel Object **/ - $objPHPExcel = PHPExcel_IOFactory::load($inputFileName); -} catch(PHPExcel_Reader_Exception $e) { - die('Error loading file: '.$e->getMessage()); -} -``` - > See Examples/Reader/exampleReader16.php for a working example of this code. - -## Helper Methods - -You can retrieve a list of worksheet names contained in a file without loading the whole file by using the Reader’s listWorksheetNames() method; similarly, a listWorksheetInfo() method will retrieve the dimensions of worksheet in a file without needing to load and parse the whole file. - -The listWorksheetNames() method returns a simple array listing each worksheet name within the workbook: - -```php -$objReader = PHPExcel_IOFactory::createReader($inputFileType); - -$worksheetNames = $objReader->listWorksheetNames($inputFileName); - -echo '

Worksheet Names

'; -echo '
    '; -foreach ($worksheetNames as $worksheetName) { - echo '
  1. ', $worksheetName, '
  2. '; -} -echo '
'; -``` - > See Examples/Reader/exampleReader18.php for a working example of this code. - -The listWorksheetInfo() method returns a nested array, with each entry listing the name and dimensions for a worksheet: - -```php -$objReader = PHPExcel_IOFactory::createReader($inputFileType); - -$worksheetData = $objReader->listWorksheetInfo($inputFileName); - -echo '

Worksheet Information

'; -echo '
    '; -foreach ($worksheetData as $worksheet) { - echo '
  1. ', $worksheet['worksheetName'], '
    '; - echo 'Rows: ', $worksheet['totalRows'], - ' Columns: ', $worksheet['totalColumns'], '
    '; - echo 'Cell Range: A1:', - $worksheet['lastColumnLetter'], $worksheet['totalRows']; - echo '
  2. '; -} -echo '
'; -``` - > See Examples/Reader/exampleReader19.php for a working example of this code. From c17a4a62a34285feee59b2d530326c1676c44fc6 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 21 May 2013 18:00:57 +0100 Subject: [PATCH 083/467] Improvements to formatting numbers with more complex masks --- Classes/PHPExcel/Shared/String.php | 5 + Classes/PHPExcel/Style/NumberFormat.php | 177 ++++++++++++------ .../PHPExcel/Style/NumberFormatTest.php | 33 ++++ unitTests/rawTestData/Style/NumberFormat.data | 34 ++++ 4 files changed, 187 insertions(+), 62 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/Style/NumberFormatTest.php create mode 100644 unitTests/rawTestData/Style/NumberFormat.data diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index f72ccc55d..3ba1be262 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -687,6 +687,11 @@ public static function getThousandsSeparator() $localeconv = localeconv(); self::$_thousandsSeparator = ($localeconv['thousands_sep'] != '') ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep']; + + if (self::$_thousandsSeparator == '') { + // Default to . + self::$_thousandsSeparator = ','; + } } return self::$_thousandsSeparator; } diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index 04d51a8a4..3d5b20e13 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -431,6 +431,108 @@ public function getHashCode() 'h' => 'g' ); + private static function _formatAsDate(&$value, &$format) + { + // dvc: convert Excel formats to PHP date formats + + // strip off first part containing e.g. [$-F800] or [$USD-409] + // general syntax: [$-] + // language info is in hexadecimal + $format = preg_replace('/^(\[\$[A-Z]*-[0-9A-F]*\])/i', '', $format); + + // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case + $format = strtolower($format); + + $format = strtr($format,self::$_dateFormatReplacements); + if (!strpos($format,'A')) { // 24-hour time format + $format = strtr($format,self::$_dateFormatReplacements24); + } else { // 12-hour time format + $format = strtr($format,self::$_dateFormatReplacements12); + } + + $dateObj = PHPExcel_Shared_Date::ExcelToPHPObject($value); + $value = $dateObj->format($format); + } + + private static function _formatAsPercentage(&$value, &$format) + { + if ($format === self::FORMAT_PERCENTAGE) { + $value = round( (100 * $value), 0) . '%'; + } else { + if (preg_match('/\.[#0]+/i', $format, $m)) { + $s = substr($m[0], 0, 1) . (strlen($m[0]) - 1); + $format = str_replace($m[0], $s, $format); + } + if (preg_match('/^[#0]+/', $format, $m)) { + $format = str_replace($m[0], strlen($m[0]), $format); + } + $format = '%' . str_replace('%', 'f%%', $format); + + $value = sprintf($format, 100 * $value); + } + } + + private static function _formatAsFraction(&$value, &$format) + { + $sign = ($value < 0) ? '-' : ''; + + $integerPart = floor(abs($value)); + $decimalPart = trim(fmod(abs($value),1),'0.'); + $decimalLength = strlen($decimalPart); + $decimalDivisor = pow(10,$decimalLength); + + $GCD = PHPExcel_Calculation_MathTrig::GCD($decimalPart,$decimalDivisor); + + $adjustedDecimalPart = $decimalPart/$GCD; + $adjustedDecimalDivisor = $decimalDivisor/$GCD; + + if ((strpos($format,'0') !== false) || (strpos($format,'#') !== false) || (substr($format,0,3) == '? ?')) { + if ($integerPart == 0) { + $integerPart = ''; + } + $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor"; + } else { + $adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor; + $value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor"; + } + } + + private static function _complexNumberFormatMask($number, $mask) { + if (strpos($mask,'.') !== false) { + $numbers = explode('.', $number . '.0'); + $masks = explode('.', $mask . '.0'); + $result1 = self::_complexNumberFormatMask($numbers[0], $masks[0]); + $result2 = strrev(self::_complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]))); + return $result1 . '.' . $result2; + } + + $r = preg_match_all('/0+/', $mask, $result, PREG_OFFSET_CAPTURE); + if ($r > 1) { + $result = array_reverse($result[0]); + + foreach($result as $block) { + $divisor = 1 . $block[0]; + $size = strlen($block[0]); + $offset = $block[1]; + + $blockValue = sprintf( + '%0' . $size . 'd', + fmod($number, $divisor) + ); + $number = floor($number / $divisor); + $mask = substr_replace($mask,$blockValue, $offset, $size); + } + if ($number > 0) { + $mask = substr_replace($mask, $number, $offset, 0); + } + $result = $mask; + } else { + $result = $number; + } + + return $result; + } + /** * Convert a value in a pre-defined format to a PHP string * @@ -439,7 +541,7 @@ public function getHashCode() * @param array $callBack Callback function for additional formatting of string * @return string Formatted string */ - public static function toFormattedString($value = PHPExcel_Style_NumberFormat::FORMAT_GENERAL, $format = '', $callBack = null) + public static function toFormattedString($value = '0', $format = PHPExcel_Style_NumberFormat::FORMAT_GENERAL, $callBack = null) { // For now we do not treat strings although section 4 of a format code affects strings if (!is_numeric($value)) return $value; @@ -499,46 +601,12 @@ public static function toFormattedString($value = PHPExcel_Style_NumberFormat::F // Let's begin inspecting the format and converting the value to a formatted string if (preg_match('/^(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy]/i', $format)) { // datetime format - // dvc: convert Excel formats to PHP date formats - - // strip off first part containing e.g. [$-F800] or [$USD-409] - // general syntax: [$-] - // language info is in hexadecimal - $format = preg_replace('/^(\[\$[A-Z]*-[0-9A-F]*\])/i', '', $format); - - // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case - $format = strtolower($format); - - $format = strtr($format,self::$_dateFormatReplacements); - if (!strpos($format,'A')) { // 24-hour time format - $format = strtr($format,self::$_dateFormatReplacements24); - } else { // 12-hour time format - $format = strtr($format,self::$_dateFormatReplacements12); - } - - $dateObj = PHPExcel_Shared_Date::ExcelToPHPObject($value); - $value = $dateObj->format($format); - + self::_formatAsDate($value, $format); } else if (preg_match('/%$/', $format)) { // % number format - if ($format === self::FORMAT_PERCENTAGE) { - $value = round( (100 * $value), 0) . '%'; - } else { - if (preg_match('/\.[#0]+/i', $format, $m)) { - $s = substr($m[0], 0, 1) . (strlen($m[0]) - 1); - $format = str_replace($m[0], $s, $format); - } - if (preg_match('/^[#0]+/', $format, $m)) { - $format = str_replace($m[0], strlen($m[0]), $format); - } - $format = '%' . str_replace('%', 'f%%', $format); - - $value = sprintf($format, 100 * $value); - } - + self::_formatAsPercentage($value, $format); } else { if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) { $value = 'EUR ' . sprintf('%1.2f', $value); - } else { // In Excel formats, "_" is used to add spacing, which we can't do in HTML $format = preg_replace('/_./', '', $format); @@ -574,25 +642,7 @@ public static function toFormattedString($value = PHPExcel_Style_NumberFormat::F if (preg_match('/#?.*\?\/\?/', $format, $m)) { //echo 'Format mask is fractional '.$format.'
'; if ($value != (int)$value) { - $sign = ($value < 0) ? '-' : ''; - - $integerPart = floor(abs($value)); - $decimalPart = trim(fmod(abs($value),1),'0.'); - $decimalLength = strlen($decimalPart); - $decimalDivisor = pow(10,$decimalLength); - - $GCD = PHPExcel_Calculation_MathTrig::GCD($decimalPart,$decimalDivisor); - - $adjustedDecimalPart = $decimalPart/$GCD; - $adjustedDecimalDivisor = $decimalDivisor/$GCD; - - if ((strpos($format,'0') !== false) || (strpos($format,'#') !== false) || (substr($format,0,3) == '? ?')) { - if ($integerPart == 0) { $integerPart = ''; } - $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor"; - } else { - $adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor; - $value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor"; - } + self::_formatAsFraction($value, $format); } } else { @@ -602,7 +652,7 @@ public static function toFormattedString($value = PHPExcel_Style_NumberFormat::F $value = $value / $scale; // Strip # - $format = preg_replace('/\\#/', '', $format); + $format = preg_replace('/\\#/', '0', $format); $n = "/\[[^\]]+\]/"; $m = preg_replace($n, '', $format); @@ -614,7 +664,6 @@ public static function toFormattedString($value = PHPExcel_Style_NumberFormat::F // minimun width of formatted number (including dot) $minWidth = strlen($left) + strlen($dec) + strlen($right); - if ($useThousands) { $value = number_format( $value @@ -622,12 +671,16 @@ public static function toFormattedString($value = PHPExcel_Style_NumberFormat::F , PHPExcel_Shared_String::getDecimalSeparator() , PHPExcel_Shared_String::getThousandsSeparator() ); + $value = preg_replace($number_regex, $value, $format); } else { - $sprintf_pattern = "%0$minWidth." . strlen($right) . "f"; - $value = sprintf($sprintf_pattern, $value); + if (preg_match('/0([^\d\.]+)0/', $format, $matches)) { + $value = self::_complexNumberFormatMask($value, $format); + } else { + $sprintf_pattern = "%0$minWidth." . strlen($right) . "f"; + $value = sprintf($sprintf_pattern, $value); + $value = preg_replace($number_regex, $value, $format); + } } - - $value = preg_replace($number_regex, $value, $format); } } if (preg_match('/\[\$(.*)\]/u', $format, $m)) { diff --git a/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php b/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php new file mode 100644 index 000000000..10b442773 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php @@ -0,0 +1,33 @@ +assertEquals($expectedResult, $result); + } + + public function providerNumberFormat() + { + return new testDataFileIterator('rawTestData/Style/NumberFormat.data'); + } + +} diff --git a/unitTests/rawTestData/Style/NumberFormat.data b/unitTests/rawTestData/Style/NumberFormat.data new file mode 100644 index 000000000..3f5901a59 --- /dev/null +++ b/unitTests/rawTestData/Style/NumberFormat.data @@ -0,0 +1,34 @@ +# value format result +0.0, "0.0", "0.0" +0.0, "0", "0" +0, "0.0", "0.0" +0, "0", "0" +0, "##0", "000" +12, "#.0#", "12.0" +0.1, "0.0", "0.1" +0.1, "0", "0" +5.5555, "0.###", "5.556" +5.5555, "0.0##", "5.556" +5.5555, "0.00#", "5.556" +5.5555, "0.000", "5.556" +5.5555, "0.0000", "5.5555" +12345.6789, '"#,##0.00"', '"12,345.68"' +12345.6789, '"#,##0.000"', '"12,345.679"' +12345.6789, '"£ #,##0.00"', '"£ 12,345.68"' +12345.6789, '"$ #,##0.000"', '"$ 12,345.679"' +5.6789, '"#,##0.00"', '"5.68"' +12000, '"#,###"', '"12,000"' +12000, '"#,"', '12' +12200000, '"0.0,,"', '12.2' // Scaling test +0.08, "0%", "8%" +0.8, "0%", "80%" +2.8, "0%", "280%" +125.74, '$0.00" Surplus";$-0.00" Shortage"', "$125.74 Surplus" +-125.74, '$0.00" Surplus";$-0.00" Shortage"', "$-125.74 Shortage" +-125.74, '$0.00" Surplus";$0.00" Shortage"', "$125.74 Shortage" +5.25, '# ???/???', "5 1/4" // Fraction +5.3, '# ???/???', "5 3/10" // Vulgar Fraction +5.25, '???/???', "21/4" +123456789, '(000) 0-0000-000', "(001) 2-3456-789" +123456789, '0 (+00) 0000 00 00 00', "0 (+00) 0123 45 67 89" +123456789, '0000:00:00', "12345:67:89" From 4ac95ac24ca44693dc72f91a5bc90eb28a8d95e5 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 23 May 2013 12:37:02 +0100 Subject: [PATCH 084/467] GH-186 - sqlite OOP doesn't have a close method, need to use a procedural close --- Classes/PHPExcel/CachedObjectStorage/SQLite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php index bab179adb..5a72f6f40 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php @@ -284,7 +284,7 @@ public function __construct(PHPExcel_Worksheet $parent) { public function __destruct() { if (!is_null($this->_DBHandle)) { $this->_DBHandle->queryExec('DROP TABLE kvp_'.$this->_TableName); - $this->_DBHandle->close(); + sqlite_close($this->_DBHandle); } $this->_DBHandle = null; } // function __destruct() From 9331422a8adf9f584f62241107647855068fcb80 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 23 May 2013 22:34:08 +0100 Subject: [PATCH 085/467] SQLite caching - fix error message --- Classes/PHPExcel/CachedObjectStorage/SQLite.php | 1 - Examples/06largescale-with-cellcaching.php | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php index 5a72f6f40..1b0221ee1 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php @@ -284,7 +284,6 @@ public function __construct(PHPExcel_Worksheet $parent) { public function __destruct() { if (!is_null($this->_DBHandle)) { $this->_DBHandle->queryExec('DROP TABLE kvp_'.$this->_TableName); - sqlite_close($this->_DBHandle); } $this->_DBHandle = null; } // function __destruct() diff --git a/Examples/06largescale-with-cellcaching.php b/Examples/06largescale-with-cellcaching.php index e645d0b4b..ff6e7b2dd 100644 --- a/Examples/06largescale-with-cellcaching.php +++ b/Examples/06largescale-with-cellcaching.php @@ -38,7 +38,9 @@ require_once '../Classes/PHPExcel.php'; $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip; -PHPExcel_Settings::setCacheStorageMethod($cacheMethod); +if (!PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) { + die($cacheMethod . " caching method is not available" . EOL); +} echo date('H:i:s') , " Enable Cell Caching using " , $cacheMethod , " method" , EOL; From de2248d1d432535f49fd728e45477879eb96c55a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 24 May 2013 09:19:13 +0100 Subject: [PATCH 086/467] Fix for SUMIF(), COUNTIF() and related functions if condition references a blank cell, courtesy of watermark86 --- Classes/PHPExcel/Calculation/Functions.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index 3e6a56db0..5de66c41a 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -308,6 +308,8 @@ public static function isCellValue($idx) { public static function _ifCondition($condition) { $condition = PHPExcel_Calculation_Functions::flattenSingleValue($condition); + if (!isset($condition{0})) + $condition = '=""'; if (!in_array($condition{0},array('>', '<', '='))) { if (!is_numeric($condition)) { $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); } return '='.$condition; From b880b5ff9d9825fb3758b2797a43b62ff0644c04 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 24 May 2013 09:29:43 +0100 Subject: [PATCH 087/467] Excel2007 reader wasn't always reading the print_titles properly, fix courtesy of watermark86 --- Classes/PHPExcel/Reader/Excel2007.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 23a58b708..410025b7a 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1542,13 +1542,14 @@ public function load($pFilename) // Set print titles foreach ($extractedRange as $range) { $matches = array(); + $range = str_replace('$', '', $range); // check for repeating columns, e g. 'A:A' or 'A:D' - if (preg_match('/^([A-Z]+)\:([A-Z]+)$/', $range, $matches)) { + if (preg_match('/!?([A-Z]+)\:([A-Z]+)$/', $range, $matches)) { $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($matches[1], $matches[2])); } // check for repeating rows, e.g. '1:1' or '1:5' - elseif (preg_match('/^(\d+)\:(\d+)$/', $range, $matches)) { + elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) { $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($matches[1], $matches[2])); } } From 7a7634fba664249a04fc771df677a9b9f755d7ec Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 24 May 2013 12:57:42 +0100 Subject: [PATCH 088/467] Only read first 8 bytes of a file when validating, rather than load the entire file into memory at that point --- Classes/PHPExcel/Shared/OLERead.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Shared/OLERead.php b/Classes/PHPExcel/Shared/OLERead.php index 55ed7e0af..30e12a41a 100644 --- a/Classes/PHPExcel/Shared/OLERead.php +++ b/Classes/PHPExcel/Shared/OLERead.php @@ -80,14 +80,18 @@ public function read($sFileName) throw new PHPExcel_Reader_Exception("Could not open " . $sFileName . " for reading! File does not exist, or it is not readable."); } - // Get the file data - $this->data = file_get_contents($sFileName); + // Get the file identifier + // Don't bother reading the whole file until we know it's a valid OLE file + $this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8); // Check OLE identifier - if (substr($this->data, 0, 8) != self::IDENTIFIER_OLE) { + if ($this->data != self::IDENTIFIER_OLE) { throw new PHPExcel_Reader_Exception('The filename ' . $sFileName . ' is not recognised as an OLE file'); } + // Get the file data + $this->data = file_get_contents($sFileName); + // Total number of sectors used for the SAT $this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); From dd8c1414ca7fdc61ad5312a4fdd7287f17568eb1 Mon Sep 17 00:00:00 2001 From: zordsdavini Date: Mon, 3 Jun 2013 12:51:53 +0300 Subject: [PATCH 089/467] fixed undifind variable in _skipBOM --- Classes/PHPExcel/Reader/CSV.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index d43b374bf..e7c5fcc91 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -144,7 +144,7 @@ public function getInputEncoding() */ protected function _skipBOM() { - rewind($fileHandle); + rewind($this->_fileHandle); switch ($this->_inputEncoding) { case 'UTF-8': From f44b41242023265192efa5d4dd1dbf1dcb0d7cd1 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 3 Jun 2013 13:39:58 +0100 Subject: [PATCH 090/467] Fix to rewind filepointer when testing BOM marker --- Classes/PHPExcel/Reader/CSV.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index d43b374bf..d45a0c6b3 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -144,28 +144,28 @@ public function getInputEncoding() */ protected function _skipBOM() { - rewind($fileHandle); + rewind($this->_fileHandle); switch ($this->_inputEncoding) { case 'UTF-8': fgets($this->_fileHandle, 4) == "\xEF\xBB\xBF" ? - fseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0); + fseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0); break; case 'UTF-16LE': fgets($this->_fileHandle, 3) == "\xFF\xFE" ? - fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); + fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); break; case 'UTF-16BE': fgets($this->_fileHandle, 3) == "\xFE\xFF" ? - fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); + fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); break; case 'UTF-32LE': fgets($this->_fileHandle, 5) == "\xFF\xFE\x00\x00" ? - fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); + fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); break; case 'UTF-32BE': fgets($this->_fileHandle, 5) == "\x00\x00\xFE\xFF" ? - fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); + fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); break; default: break; @@ -187,7 +187,7 @@ public function listWorksheetInfo($pFilename) throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } $fileHandle = $this->_fileHandle; - + // Skip BOM, if any $this->_skipBOM(); From aeec8ef23cb0ad1bb8492ba8ca61fabf2e6dd96d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 3 Jun 2013 22:28:32 +0100 Subject: [PATCH 091/467] Fix to clone worksheet --- .../PHPExcel/CachedObjectStorage/Memory.php | 2 +- Examples/38cloneWorksheet.php | 118 ++++++++++++++++++ Examples/runall.php | 1 + 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 Examples/38cloneWorksheet.php diff --git a/Classes/PHPExcel/CachedObjectStorage/Memory.php b/Classes/PHPExcel/CachedObjectStorage/Memory.php index bbe3d9ba4..dd01bc3b7 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memory.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memory.php @@ -96,7 +96,7 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) { $newCollection = array(); foreach($this->_cellCache as $k => &$cell) { $newCollection[$k] = clone $cell; - $newCollection[$k]->attach($parent); + $newCollection[$k]->attach($this); } $this->_cellCache = $newCollection; diff --git a/Examples/38cloneWorksheet.php b/Examples/38cloneWorksheet.php new file mode 100644 index 000000000..d8e141c1f --- /dev/null +++ b/Examples/38cloneWorksheet.php @@ -0,0 +1,118 @@ +'); + +/** Include PHPExcel */ +require_once '../Classes/PHPExcel.php'; + + +// Create new PHPExcel object +echo date('H:i:s') , " Create new PHPExcel object" , EOL; +$objPHPExcel = new PHPExcel(); + +// Set document properties +echo date('H:i:s') , " Set document properties" , EOL; +$objPHPExcel->getProperties()->setCreator("Maarten Balliauw") + ->setLastModifiedBy("Maarten Balliauw") + ->setTitle("PHPExcel Test Document") + ->setSubject("PHPExcel Test Document") + ->setDescription("Test document for PHPExcel, generated using PHP classes.") + ->setKeywords("office PHPExcel php") + ->setCategory("Test result file"); + + +// Add some data +echo date('H:i:s') , " Add some data" , EOL; +$objPHPExcel->setActiveSheetIndex(0) + ->setCellValue('A1', 'Hello') + ->setCellValue('B2', 'world!') + ->setCellValue('C1', 'Hello') + ->setCellValue('D2', 'world!'); + +// Miscellaneous glyphs, UTF-8 +$objPHPExcel->setActiveSheetIndex(0) + ->setCellValue('A4', 'Miscellaneous glyphs') + ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç'); + + +$objPHPExcel->getActiveSheet()->setCellValue('A8',"Hello\nWorld"); +$objPHPExcel->getActiveSheet()->getRowDimension(8)->setRowHeight(-1); +$objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true); + + +// Rename worksheet +echo date('H:i:s') , " Rename worksheet" , EOL; +$objPHPExcel->getActiveSheet()->setTitle('Simple'); + + +// Clone worksheet +echo date('H:i:s') , " Clone worksheet" , EOL; +$clonedSheet = clone $objPHPExcel->getActiveSheet(); +$clonedSheet + ->setCellValue('A1', 'Goodbye') + ->setCellValue('A2', 'cruel') + ->setCellValue('C1', 'Goodbye') + ->setCellValue('C2', 'cruel'); + +// Rename cloned worksheet +echo date('H:i:s') , " Rename cloned worksheet" , EOL; +$clonedSheet->setTitle('Simple Clone'); +$objPHPExcel->addSheet($clonedSheet); + + +// Set active sheet index to the first sheet, so Excel opens this as the first sheet +$objPHPExcel->setActiveSheetIndex(0); + + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing files" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Examples/runall.php b/Examples/runall.php index 00f43eaed..e19835f82 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -90,6 +90,7 @@ , '35chartrender.php' , '36chartreadwriteHTML.php' , '37page_layout_view.php' + , '38cloneWorksheet.php' , '40duplicateStyle.php' , 'OOCalcReader.php' , 'SylkReader.php' From 9a36ddb1a2f7a38a6d17bdf4aef5634eadd84b1d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 10 Jun 2013 23:20:58 +0100 Subject: [PATCH 092/467] Quick bugfix to PDF merge cell styling --- Classes/PHPExcel/Writer/HTML.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 318fd988a..3affa7eac 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -1233,7 +1233,9 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow // Also apply style from last cell in merge to fix borders - // relies on !important for non-none border declarations in _createCSSStyleBorder $endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan); - $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex(); + if (!$this->_useInlineCss) { + $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex(); + } } // Write From 78c034880f7ddaf2204452cf21d30d71dc95843b Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 11 Jun 2013 22:52:06 +0100 Subject: [PATCH 093/467] Update changelog --- changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelog.txt b/changelog.txt index 4847b0878..ff2749468 100644 --- a/changelog.txt +++ b/changelog.txt @@ -23,6 +23,12 @@ ************************************************************************************** +Fixed in develop branch for release v1.7.9a: +- Bugfix: (MBaker) Work item 19830 - Undefined variable: fileHandle in CSV Reader +- Bugfix: (MBaker) - Style error with merged cells in PDF Writer +- Bugfix: (MBaker) - Problem with cloning worksheets + + Fixed in develop branch for release v1.7.9: - Feature: (MBaker) Include charts option for HTML Writer - Feature: (MBaker) Added composer file From dfc74f8b95e6a3d7ec29794911c846d90d4d0ad4 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 14 Jun 2013 23:57:50 +0100 Subject: [PATCH 094/467] Feature: (amerov) - Implementation of the Excel HLOOKUP() function --- Classes/PHPExcel/Calculation.php | 2 +- Classes/PHPExcel/Calculation/LookupRef.php | 66 ++++++++++++++++++- changelog.txt | 2 +- .../PHPExcel/Calculation/LookupRefTest.php | 34 ++++++++++ .../Calculation/LookupRef/HLOOKUP.data | 9 +++ 5 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php create mode 100644 unitTests/rawTestData/Calculation/LookupRef/HLOOKUP.data diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 0e6e2306e..a3f7be2c0 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -841,7 +841,7 @@ class PHPExcel_Calculation { 'argumentCount' => '1,2' ), 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', 'argumentCount' => '3,4' ), 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index 96f60206b..c3a3f074c 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -721,7 +721,8 @@ public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not $rowNumber = $rowValue = False; foreach($lookup_array as $rowKey => $rowData) { - if (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)) { + if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) || + (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) { break; } $rowNumber = $rowKey; @@ -742,6 +743,69 @@ public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not } // function VLOOKUP() +/** + * HLOOKUP + * The HLOOKUP function searches for value in the top-most row of lookup_array and returns the value in the same column based on the index_number. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param index_number The row number in table_array from which the matching value must be returned. The first row is 1. + * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. + * @return mixed The value of the found cell + */ + public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) { + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + $index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); + $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); + + // index_number must be greater than or equal to 1 + if ($index_number < 1) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // index_number must be less than or equal to the number of columns in lookup_array + if ((!is_array($lookup_array)) || (empty($lookup_array))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $f = array_keys($lookup_array); + $firstRow = array_pop($f); + if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $columnKeys = array_keys($lookup_array[$firstRow]); + $firstkey = $f[0] - 1; + $returnColumn = $firstkey + $index_number; + $firstColumn = array_shift($f); + } + } + + if (!$not_exact_match) { + $firstRowH = asort($lookup_array[$firstColumn]); + } + + $rowNumber = $rowValue = False; + foreach($lookup_array[$firstColumn] as $rowKey => $rowData) { + if ((is_numeric($lookup_value) && is_numeric($rowData) && ($rowData > $lookup_value)) || + (!is_numeric($lookup_value) && !is_numeric($rowData) && (strtolower($rowData) > strtolower($lookup_value)))) { + break; + } + $rowNumber = $rowKey; + $rowValue = $rowData; + } + + if ($rowNumber !== false) { + if ((!$not_exact_match) && ($rowValue != $lookup_value)) { + // if an exact match is required, we have what we need to return an appropriate response + return PHPExcel_Calculation_Functions::NA(); + } else { + // otherwise return the appropriate value + return $lookup_array[$returnColumn][$rowNumber]; + } + } + + return PHPExcel_Calculation_Functions::NA(); + } // function HLOOKUP() + + /** * LOOKUP * The LOOKUP function searches for value either from a one-row or one-column range or from an array. diff --git a/changelog.txt b/changelog.txt index ff2749468..3c27a1b29 100644 --- a/changelog.txt +++ b/changelog.txt @@ -27,7 +27,7 @@ Fixed in develop branch for release v1.7.9a: - Bugfix: (MBaker) Work item 19830 - Undefined variable: fileHandle in CSV Reader - Bugfix: (MBaker) - Style error with merged cells in PDF Writer - Bugfix: (MBaker) - Problem with cloning worksheets - +- Feature: (amerov) - Implementation of the Excel HLOOKUP() function Fixed in develop branch for release v1.7.9: - Feature: (MBaker) Include charts option for HTML Writer diff --git a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php new file mode 100644 index 000000000..bc6343173 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php @@ -0,0 +1,34 @@ +assertEquals($expectedResult, $result); + } + + public function providerHLOOKUP() + { + return new testDataFileIterator('rawTestData/Calculation/LookupRef/HLOOKUP.data'); + } + +} diff --git a/unitTests/rawTestData/Calculation/LookupRef/HLOOKUP.data b/unitTests/rawTestData/Calculation/LookupRef/HLOOKUP.data new file mode 100644 index 000000000..c29fdc95d --- /dev/null +++ b/unitTests/rawTestData/Calculation/LookupRef/HLOOKUP.data @@ -0,0 +1,9 @@ +10251, {"Order ID"|10247|10249|10250|10251|10252|10253;"Unit Price"|14.00|18.60|7.70|16.80|16.80|64.80;"Quantity"|12|9|10|6|20|40}, 2, FALSE, 16.8 +10251, {"Order ID"|10247|10249|10250|10251|10252|10253;"Unit Price"|14.00|18.60|7.70|16.80|16.80|64.80;"Quantity"|12|9|10|6|20|40}, 3, FALSE, 6.0 +10248, {"Order ID"|10247|10249|10250|10251|10252|10253;"Unit Price"|14.00|18.60|7.70|16.80|16.80|64.80;"Quantity"|12|9|10|6|20|40}, 2, FALSE, "#N/A" +10248, {"Order ID"|10247|10249|10250|10251|10252|10253;"Unit Price"|14.00|18.60|7.70|16.80|16.80|64.80;"Quantity"|12|9|10|6|20|40}, 2, TRUE, 14.0 +"Axles", {"Axles"|"Bearings"|"Bolts";4|4|9;5|7|10;6|8|11}, 2, TRUE, 4 +"Bearings", {"Axles"|"Bearings"|"Bolts";4|4|9;5|7|10;6|8|11}, 3, FALSE, 7 +"B", {"Axles"|"Bearings"|"Bolts";4|4|9;5|7|10;6|8|11}, 3, TRUE, 5 +"Bolts", {"Axles"|"Bearings"|"Bolts";4|4|9;5|7|10;6|8|11}, 4, 11 +3, {1|2|3;"a"|"b"|"c";"d"|"e"|"f"}, 2, TRUE, "c" From 83bd690633a12d5b7211100e0e51f40bf867c91d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 15 Jun 2013 00:03:48 +0100 Subject: [PATCH 095/467] HLOOKUP --- Documentation/FunctionListByCategory.txt | 2 +- Documentation/FunctionListByName.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/FunctionListByCategory.txt b/Documentation/FunctionListByCategory.txt index a5423eb66..1c3ec5c27 100644 --- a/Documentation/FunctionListByCategory.txt +++ b/Documentation/FunctionListByCategory.txt @@ -177,7 +177,7 @@ CATEGORY_LOOKUP_AND_REFERENCE COLUMN PHPExcel_Calculation_LookupRef::COLUMN COLUMNS PHPExcel_Calculation_LookupRef::COLUMNS GETPIVOTDATA *** Not yet Implemented - HLOOKUP *** Not yet Implemented + HLOOKUP PHPExcel_Calculation_LookupRef::HLOOKUP HYPERLINK PHPExcel_Calculation_LookupRef::HYPERLINK INDEX PHPExcel_Calculation_LookupRef::INDEX INDIRECT PHPExcel_Calculation_LookupRef::INDIRECT diff --git a/Documentation/FunctionListByName.txt b/Documentation/FunctionListByName.txt index 082c83af0..02e2f0632 100644 --- a/Documentation/FunctionListByName.txt +++ b/Documentation/FunctionListByName.txt @@ -146,7 +146,7 @@ HARMEAN CATEGORY_STATISTICAL PHPExcel_Calculation_Sta HEX2BIN CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTOBIN HEX2DEC CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTODEC HEX2OCT CATEGORY_ENGINEERING PHPExcel_Calculation_Engineering::HEXTOOCT -HLOOKUP CATEGORY_LOOKUP_AND_REFERENCE *** Not yet Implemented +HLOOKUP CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::HLOOKUP HOUR CATEGORY_DATE_AND_TIME PHPExcel_Calculation_DateTime::HOUROFDAY HYPERLINK CATEGORY_LOOKUP_AND_REFERENCE PHPExcel_Calculation_LookupRef::HYPERLINK HYPGEOMDIST CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::HYPGEOMDIST From 4d92e77d001ae36357bb992090d0a757415698d8 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 15 Jun 2013 12:15:03 +0100 Subject: [PATCH 096/467] Eliminate need for use of money_format() function; various fixes to HLOOKUP, VLOOKUP and DOLLAR functions + unit tests --- Classes/PHPExcel/Calculation/Functions.php | 94 ------------------- Classes/PHPExcel/Calculation/LookupRef.php | 9 +- Classes/PHPExcel/Calculation/TextData.php | 11 ++- .../PHPExcel/Calculation/LookupRefTest.php | 16 ++++ .../PHPExcel/Style/NumberFormatTest.php | 3 + .../Calculation/LookupRef/VLOOKUP.data | 5 + 6 files changed, 37 insertions(+), 101 deletions(-) create mode 100644 unitTests/rawTestData/Calculation/LookupRef/VLOOKUP.data diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index 5de66c41a..3004eec93 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -689,100 +689,6 @@ function atanh($x) { } // function atanh() } -if (!function_exists('money_format')) { - function money_format($format, $number) { - $regex = array( '/%((?:[\^!\-]|\+|\(|\=.)*)([0-9]+)?(?:#([0-9]+))?', - '(?:\.([0-9]+))?([in%])/' - ); - $regex = implode('', $regex); - if (setlocale(LC_MONETARY, null) == '') { - setlocale(LC_MONETARY, ''); - } - $locale = localeconv(); - $number = floatval($number); - if (!preg_match($regex, $format, $fmatch)) { - trigger_error("No format specified or invalid format", E_USER_WARNING); - return $number; - } - $flags = array( 'fillchar' => preg_match('/\=(.)/', $fmatch[1], $match) ? $match[1] : ' ', - 'nogroup' => preg_match('/\^/', $fmatch[1]) > 0, - 'usesignal' => preg_match('/\+|\(/', $fmatch[1], $match) ? $match[0] : '+', - 'nosimbol' => preg_match('/\!/', $fmatch[1]) > 0, - 'isleft' => preg_match('/\-/', $fmatch[1]) > 0 - ); - $width = trim($fmatch[2]) ? (int)$fmatch[2] : 0; - $left = trim($fmatch[3]) ? (int)$fmatch[3] : 0; - $right = trim($fmatch[4]) ? (int)$fmatch[4] : $locale['int_frac_digits']; - $conversion = $fmatch[5]; - $positive = true; - if ($number < 0) { - $positive = false; - $number *= -1; - } - $letter = $positive ? 'p' : 'n'; - $prefix = $suffix = $cprefix = $csuffix = $signal = ''; - if (!$positive) { - $signal = $locale['negative_sign']; - switch (true) { - case $locale['n_sign_posn'] == 0 || $flags['usesignal'] == '(': - $prefix = '('; - $suffix = ')'; - break; - case $locale['n_sign_posn'] == 1: - $prefix = $signal; - break; - case $locale['n_sign_posn'] == 2: - $suffix = $signal; - break; - case $locale['n_sign_posn'] == 3: - $cprefix = $signal; - break; - case $locale['n_sign_posn'] == 4: - $csuffix = $signal; - break; - } - } - if (!$flags['nosimbol']) { - $currency = $cprefix; - $currency .= ($conversion == 'i' ? $locale['int_curr_symbol'] : $locale['currency_symbol']); - $currency .= $csuffix; - $currency = iconv('ISO-8859-1','UTF-8',$currency); - } else { - $currency = ''; - } - $space = $locale["{$letter}_sep_by_space"] ? ' ' : ''; - - if (!isset($locale['mon_decimal_point']) || empty($locale['mon_decimal_point'])) { - $locale['mon_decimal_point'] = (!isset($locale['decimal_point']) || empty($locale['decimal_point'])) ? - $locale['decimal_point'] : - '.'; - } - - $number = number_format($number, $right, $locale['mon_decimal_point'], $flags['nogroup'] ? '' : $locale['mon_thousands_sep'] ); - $number = explode($locale['mon_decimal_point'], $number); - - $n = strlen($prefix) + strlen($currency); - if ($left > 0 && $left > $n) { - if ($flags['isleft']) { - $number[0] .= str_repeat($flags['fillchar'], $left - $n); - } else { - $number[0] = str_repeat($flags['fillchar'], $left - $n) . $number[0]; - } - } - $number = implode($locale['mon_decimal_point'], $number); - if ($locale["{$letter}_cs_precedes"]) { - $number = $prefix . $currency . $space . $number . $suffix; - } else { - $number = $prefix . $number . $space . $currency . $suffix; - } - if ($width > 0) { - $number = str_pad($number, $width, $flags['fillchar'], $flags['isleft'] ? STR_PAD_RIGHT : STR_PAD_LEFT); - } - $format = str_replace($fmatch[0], $number, $format); - return $format; - } // function money_format() -} - // // Strangely, PHP doesn't have a mb_str_replace multibyte function diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index c3a3f074c..c3363f15d 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -735,7 +735,11 @@ public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not return PHPExcel_Calculation_Functions::NA(); } else { // otherwise return the appropriate value - return $lookup_array[$rowNumber][$returnColumn]; + $result = $lookup_array[$rowNumber][$returnColumn]; + if ((is_numeric($lookup_value) && is_numeric($result)) || + (!is_numeric($lookup_value) && !is_numeric($result))) { + return $result; + } } } @@ -798,7 +802,8 @@ public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not return PHPExcel_Calculation_Functions::NA(); } else { // otherwise return the appropriate value - return $lookup_array[$returnColumn][$rowNumber]; + $result = $lookup_array[$returnColumn][$rowNumber]; + return $result; } } diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php index d8a98db26..90447c0bc 100644 --- a/Classes/PHPExcel/Calculation/TextData.php +++ b/Classes/PHPExcel/Calculation/TextData.php @@ -208,16 +208,17 @@ public static function DOLLAR($value = 0, $decimals = 2) { } $decimals = floor($decimals); + $mask = '$#,##0'; if ($decimals > 0) { - return money_format('%.'.$decimals.'n',$value); + $mask .= '.' . str_repeat('0',$decimals); } else { $round = pow(10,abs($decimals)); if ($value < 0) { $round = 0-$round; } - $value = PHPExcel_Calculation_MathTrig::MROUND($value,$round); - // The implementation of money_format used if the standard PHP function is not available can't handle decimal places of 0, - // so we display to 1 dp and chop off that character and the decimal separator using substr - return substr(money_format('%.1n',$value),0,-2); + $value = PHPExcel_Calculation_MathTrig::MROUND($value, $round); } + + return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask); + } // function DOLLAR() diff --git a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php index bc6343173..454422a15 100644 --- a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php @@ -31,4 +31,20 @@ public function providerHLOOKUP() return new testDataFileIterator('rawTestData/Calculation/LookupRef/HLOOKUP.data'); } + /** + * @dataProvider providerVLOOKUP + */ + public function testVLOOKUP() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','VLOOKUP'),$args); + $this->assertEquals($expectedResult, $result); + } + + public function providerVLOOKUP() + { + return new testDataFileIterator('rawTestData/Calculation/LookupRef/VLOOKUP.data'); + } + } diff --git a/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php b/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php index 10b442773..13fc3ede3 100644 --- a/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php +++ b/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php @@ -12,6 +12,9 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Shared_String::setDecimalSeparator('.'); + PHPExcel_Shared_String::setThousandsSeparator(','); } /** diff --git a/unitTests/rawTestData/Calculation/LookupRef/VLOOKUP.data b/unitTests/rawTestData/Calculation/LookupRef/VLOOKUP.data new file mode 100644 index 000000000..8fefc6cc0 --- /dev/null +++ b/unitTests/rawTestData/Calculation/LookupRef/VLOOKUP.data @@ -0,0 +1,5 @@ +1, {"Density"|"Viscosity"|"Temperature";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0}, 2, FALSE, 2.17 +1, {"Density"|"Viscosity"|"Temperature";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0}, 3, TRUE, 100 +.7, {"Density"|"Viscosity"|"Temperature";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0}, 3, FALSE, "#N/A" +0.1, {"Density"|"Viscosity"|"Temperature";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0}, 2, TRUE, "#N/A" +2, {"Density"|"Viscosity"|"Temperature";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0}, 2, TRUE, 1.71 From 8f7db244de93ddc2fc8afbf377cf2b6de84f83ba Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 16 Jun 2013 10:26:16 +0100 Subject: [PATCH 097/467] Eliminate unnecessary version checks --- .../PHPExcel/Shared/OLE/ChainedBlockStream.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php index 64cecec8c..025c6cbcb 100644 --- a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php +++ b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php @@ -161,14 +161,15 @@ public function stream_read($count) */ public function stream_eof() { - $eof = $this->pos >= strlen($this->data); - // Workaround for bug in PHP 5.0.x: http://bugs.php.net/27508 - if (version_compare(PHP_VERSION, '5.0', '>=') && - version_compare(PHP_VERSION, '5.1', '<')) { - - $eof = !$eof; - } - return $eof; +// As we don't support below 5.2 anymore, this is simply redundancy and overhead +// $eof = $this->pos >= strlen($this->data); +// // Workaround for bug in PHP 5.0.x: http://bugs.php.net/27508 +// if (version_compare(PHP_VERSION, '5.0', '>=') && +// version_compare(PHP_VERSION, '5.1', '<')) { +// $eof = !$eof; +// } +// return $eof; + return $this->pos >= strlen($this->data); } /** From a0859fd7d0a445fc2c67a5755ef7d0cdbbdb6b04 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 16 Jun 2013 15:13:05 +0100 Subject: [PATCH 098/467] Fix to number format masking for scientific notation --- Classes/PHPExcel/Style/NumberFormat.php | 5 ++++- .../Calculation/TextData/TEXT.data | 19 +++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index 3d5b20e13..80347bf93 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -673,7 +673,10 @@ public static function toFormattedString($value = '0', $format = PHPExcel_Style_ ); $value = preg_replace($number_regex, $value, $format); } else { - if (preg_match('/0([^\d\.]+)0/', $format, $matches)) { + if (preg_match('/0E[+-]0/i', $format)) { + // Scientific format + $value = sprintf('%5.2E', $value); + } elseif (preg_match('/0([^\d\.]+)0/', $format)) { $value = self::_complexNumberFormatMask($value, $format); } else { $sprintf_pattern = "%0$minWidth." . strlen($right) . "f"; diff --git a/unitTests/rawTestData/Calculation/TextData/TEXT.data b/unitTests/rawTestData/Calculation/TextData/TEXT.data index 3087dfaad..da18defa3 100644 --- a/unitTests/rawTestData/Calculation/TextData/TEXT.data +++ b/unitTests/rawTestData/Calculation/TextData/TEXT.data @@ -1,10 +1,13 @@ -123.456, '"$#,##0.00"', "$123.46" -123.456, '"#,##0.00"', "123.46" -123.456, '"#,##0"', "123" -123.456, "00000", "00123" -123456.789, '"$#,##0.00"', '"$123,456.79"' -123456.789, '"#,##0.00"', '"123,456.79"' -123456.789, "0.00E+00", "1.23E05" +123.456, '"$#,##0.00"', "$123.46" +-123.456, '"$#,##0.00"', "$-123.46" +123.456, '"#,##0.00"', "123.46" +123.456, '"#,##0"', "123" +123.456, "00000", "00123" +123456.789, '"$#,##0.00"', '"$123,456.79"' +123456.789, '"#,##0.00"', '"123,456.79"' +123456.789, "0.00E+00", "1.23E05" +-123456.789, "0.00E+00", "-1.23E05" +0.000012345, "0.00E+00", "1.23E-05" "19-Dec-1960", "yyyy-mm-dd", "1960-12-19" "1-Jan-2012", "yyyy-mm-dd", "2012-01-01" -1.75, "# ?/?", "1 3/4" +1.75, "# ?/?", "1 3/4" From 333c811c5e523544a60e0d004f4bd3cb6734dfcb Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 16 Jun 2013 16:24:34 +0100 Subject: [PATCH 099/467] Minor performance tweaks to calculation engine --- Classes/PHPExcel/Calculation.php | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index a3f7be2c0..01cfb7cfa 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -3486,6 +3486,13 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel private function _validateBinaryOperand($cellID, &$operand, &$stack) { + if (is_array($operand)) { + if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { + do { + $operand = array_pop($operand); + } while (is_array($operand)); + } + } // Numbers, matrices and booleans can pass straight through, as they're already valid if (is_string($operand)) { // We only need special validations for the operand if it is a string @@ -3591,25 +3598,13 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; - $executeMatrixOperation = FALSE; // If either of the operands is a matrix, we need to treat them both as matrices // (converting the other operand to a matrix if need be); then perform the required // matrix operation if ((is_array($operand1)) || (is_array($operand2))) { - // Ensure that both operands are arrays/matrices - $executeMatrixOperation = TRUE; - $mSize = array(); - list($mSize[],$mSize[],$mSize[],$mSize[]) = self::_checkMatrixOperands($operand1,$operand2,2); - - // But if they're both single cell matrices, then we can treat them as simple values - if (array_sum($mSize) == 4) { - $executeMatrixOperation = FALSE; - $operand1 = $operand1[0][0]; - $operand2 = $operand2[0][0]; - } - } + // Ensure that both operands are arrays/matrices of the same size + self::_checkMatrixOperands($operand1, $operand2, 2); - if ($executeMatrixOperation) { try { // Convert operand 1 from a PHP array to a matrix $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); From 90eff17853bfbfce0502bae903a6fc9814ffa097 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 16 Jun 2013 21:34:17 +0100 Subject: [PATCH 100/467] Performance tweaks --- Classes/PHPExcel/Worksheet.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 3094fb3c5..257fc7a2e 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1054,7 +1054,7 @@ public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = */ public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $returnCell = false) { - $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValue($pValue); + $cell = $this->getCellByColumnAndRow($pColumn, $pRow)->setValue($pValue); return ($returnCell) ? $cell : $this; } @@ -1086,7 +1086,7 @@ public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pData */ public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) { - $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValueExplicit($pValue, $pDataType); + $cell = $this->getCellByColumnAndRow($pColumn, $pRow)->setValueExplicit($pValue, $pDataType); return ($returnCell) ? $cell : $this; } From 6216d2855cac16c6adcd8f8f39bb81fd163c9cea Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 16 Jun 2013 21:35:35 +0100 Subject: [PATCH 101/467] Performance tweaks --- Classes/PHPExcel/Worksheet.php | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 3094fb3c5..19d89538d 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1142,18 +1142,15 @@ public function getCell($pCoordinate = 'A1') $this->_cachedHighestRow = max($this->_cachedHighestRow,$aCoordinates[1]); // Cell needs appropriate xfIndex - $rowDimensions = $this->getRowDimensions(); - $columnDimensions = $this->getColumnDimensions(); + $rowDimension = $this->getRowDimension($aCoordinates[1], FALSE); + $columnDimension = $this->getColumnDimension($aCoordinates[0], FALSE); - if ( isset($rowDimensions[$aCoordinates[1]]) && $rowDimensions[$aCoordinates[1]]->getXfIndex() !== null ) { + if ($rowDimension !== NULL && $rowDimension->getXfIndex() > 0) { // then there is a row dimension with explicit style, assign it to the cell - $cell->setXfIndex($rowDimensions[$aCoordinates[1]]->getXfIndex()); - } else if ( isset($columnDimensions[$aCoordinates[0]]) ) { + $cell->setXfIndex($rowDimension->getXfIndex()); + } elseif ($columnDimension !== NULL && $columnDimension->getXfIndex() > 0) { // then there is a column dimension, assign it to the cell - $cell->setXfIndex($columnDimensions[$aCoordinates[0]]->getXfIndex()); - } else { - // set to default index - $cell->setXfIndex(0); + $cell->setXfIndex($columnDimension->getXfIndex()); } return $cell; @@ -1253,13 +1250,15 @@ public function cellExistsByColumnAndRow($pColumn = 0, $pRow = 1) * @param int $pRow Numeric index of the row * @return PHPExcel_Worksheet_RowDimension */ - public function getRowDimension($pRow = 1) + public function getRowDimension($pRow = 1, $create = TRUE) { // Found $found = null; // Get row dimension if (!isset($this->_rowDimensions[$pRow])) { + if (!$create) + return NULL; $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow); $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow); @@ -1273,13 +1272,15 @@ public function getRowDimension($pRow = 1) * @param string $pColumn String index of the column * @return PHPExcel_Worksheet_ColumnDimension */ - public function getColumnDimension($pColumn = 'A') + public function getColumnDimension($pColumn = 'A', $create = TRUE) { // Uppercase coordinate $pColumn = strtoupper($pColumn); // Fetch dimensions if (!isset($this->_columnDimensions[$pColumn])) { + if (!$create) + return NULL; $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn); if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) From 98e5ac2b240471d08586ed6798589c8ee903af30 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 17 Jun 2013 11:37:29 +0100 Subject: [PATCH 102/467] Performance improvements --- Classes/PHPExcel/Worksheet.php | 87 ++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 338dcca35..bd5dc1780 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1123,38 +1123,14 @@ public function getCell($pCoordinate = 'A1') // Uppercase coordinate $pCoordinate = strtoupper($pCoordinate); - if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { + if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) { throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.'); - } elseif (strpos($pCoordinate,'$') !== false) { + } elseif (strpos($pCoordinate, '$') !== false) { throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); - } else { - // Create new cell object - - // Coordinates - $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); - - $cell = $this->_cellCollection->addCacheData($pCoordinate,new PHPExcel_Cell(NULL, PHPExcel_Cell_DataType::TYPE_NULL, $this)); - $this->_cellCollectionIsSorted = false; - - if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) - $this->_cachedHighestColumn = $aCoordinates[0]; - - $this->_cachedHighestRow = max($this->_cachedHighestRow,$aCoordinates[1]); - - // Cell needs appropriate xfIndex - $rowDimension = $this->getRowDimension($aCoordinates[1], FALSE); - $columnDimension = $this->getColumnDimension($aCoordinates[0], FALSE); - - if ($rowDimension !== NULL && $rowDimension->getXfIndex() > 0) { - // then there is a row dimension with explicit style, assign it to the cell - $cell->setXfIndex($rowDimension->getXfIndex()); - } elseif ($columnDimension !== NULL && $columnDimension->getXfIndex() > 0) { - // then there is a column dimension, assign it to the cell - $cell->setXfIndex($columnDimension->getXfIndex()); - } - - return $cell; } + + // Create new cell object + return $this->_createNewCell($pCoordinate); } /** @@ -1169,21 +1145,52 @@ public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn); $coordinate = $columnLetter . $pRow; - if (!$this->_cellCollection->isDataSet($coordinate)) { - $cell = $this->_cellCollection->addCacheData($coordinate, new PHPExcel_Cell(NULL, PHPExcel_Cell_DataType::TYPE_NULL, $this)); - $this->_cellCollectionIsSorted = false; - - if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < $pColumn) - $this->_cachedHighestColumn = $columnLetter; - - $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow); - - return $cell; + if ($this->_cellCollection->isDataSet($coordinate)) { + return $this->_cellCollection->getCacheData($coordinate); } - return $this->_cellCollection->getCacheData($coordinate); + return $this->_createNewCell($coordinate); } + /** + * Create a new cell at the specified coordinate + * + * @param string $pCoordinate Coordinate of the cell + * @return PHPExcel_Cell Cell that was created + */ + private function _createNewCell($pCoordinate) + { + $cell = $this->_cellCollection->addCacheData( + $pCoordinate, + new PHPExcel_Cell( + NULL, + PHPExcel_Cell_DataType::TYPE_NULL, + $this + ) + ); + $this->_cellCollectionIsSorted = false; + + // Coordinates + $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); + if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) + $this->_cachedHighestColumn = $aCoordinates[0]; + $this->_cachedHighestRow = max($this->_cachedHighestRow, $aCoordinates[1]); + + // Cell needs appropriate xfIndex + $rowDimension = $this->getRowDimension($aCoordinates[1], FALSE); + $columnDimension = $this->getColumnDimension($aCoordinates[0], FALSE); + + if ($rowDimension !== NULL && $rowDimension->getXfIndex() > 0) { + // then there is a row dimension with explicit style, assign it to the cell + $cell->setXfIndex($rowDimension->getXfIndex()); + } elseif ($columnDimension !== NULL && $columnDimension->getXfIndex() > 0) { + // then there is a column dimension, assign it to the cell + $cell->setXfIndex($columnDimension->getXfIndex()); + } + + return $cell; + } + /** * Cell at a specific coordinate exists? * From da7cd71be894aabb8d5b70e820e3c9ffec38ea70 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 17 Jun 2013 12:01:51 +0100 Subject: [PATCH 103/467] Minor performance tweaks --- Classes/PHPExcel/Worksheet.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index bd5dc1780..4c7b239b3 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1176,7 +1176,8 @@ private function _createNewCell($pCoordinate) $this->_cachedHighestColumn = $aCoordinates[0]; $this->_cachedHighestRow = max($this->_cachedHighestRow, $aCoordinates[1]); - // Cell needs appropriate xfIndex + // Cell needs appropriate xfIndex from dimensions records + // but don't create dimension records if they don't already exist $rowDimension = $this->getRowDimension($aCoordinates[1], FALSE); $columnDimension = $this->getColumnDimension($aCoordinates[0], FALSE); @@ -1192,7 +1193,7 @@ private function _createNewCell($pCoordinate) } /** - * Cell at a specific coordinate exists? + * Does the cell at a specific coordinate exist? * * @param string $pCoordinate Coordinate of the cell * @throws PHPExcel_Exception From 6cea3bbf7b6cf17659214ed9d1e0ec97cafc49c8 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 21 Jun 2013 22:52:29 +0100 Subject: [PATCH 104/467] Minor fix to HTML Reader canRead method (even developers have brainfarts occasionally) --- Classes/PHPExcel/Reader/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 4780a9557..8ebdc9f47 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -117,7 +117,7 @@ protected function _isValidFormat() { // Reading 2048 bytes should be enough to validate that the format is HTML $data = fread($this->_fileHandle, 2048); - if ((strpos('<',$data) !== FALSE) && + if ((strpos($data, '<') !== FALSE) && (strlen($data) !== strlen(strip_tags($data)))) { return TRUE; } From 39953ff49fc8781a33d126e81c733aefc5f7bba1 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 25 Jun 2013 23:13:13 +0100 Subject: [PATCH 105/467] Feature: Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) --- Classes/PHPExcel/Reader/Excel2007.php | 11 ++++ Classes/PHPExcel/Style.php | 57 +++++++++++++++++- Classes/PHPExcel/Writer/Excel2007.php | 20 +++++- Classes/PHPExcel/Writer/Excel2007/Style.php | 3 + .../PHPExcel developer documentation.doc | Bin 818688 -> 819200 bytes changelog.txt | 1 + 6 files changed, 90 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 410025b7a..678d837cf 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -496,6 +496,10 @@ public function load($pFilename) $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); } } + $quotePrefix = false; + if (isset($xf["quotePrefix"])) { + $quotePrefix = (boolean) $xf["quotePrefix"]; + } //$numFmt = str_replace('mm', 'i', $numFmt); //$numFmt = str_replace('h', 'H', $numFmt); @@ -506,6 +510,7 @@ public function load($pFilename) "border" => $xmlStyles->borders->border[intval($xf["borderId"])], "alignment" => $xf->alignment, "protection" => $xf->protection, + "quotePrefix" => $quotePrefix, ); $styles[] = $style; @@ -533,6 +538,7 @@ public function load($pFilename) "border" => $xmlStyles->borders->border[intval($xf["borderId"])], "alignment" => $xf->alignment, "protection" => $xf->protection, + "quotePrefix" => $quotePrefix, ); $cellStyles[] = $cellStyle; @@ -1856,6 +1862,11 @@ private static function _readStyle($docStyle, $style) { } } } + + // top-level style settings + if (isset($style->quotePrefix)) { + $docStyle->setQuotePrefix($style->quotePrefix); + } } diff --git a/Classes/PHPExcel/Style.php b/Classes/PHPExcel/Style.php index 7669b695c..646182619 100644 --- a/Classes/PHPExcel/Style.php +++ b/Classes/PHPExcel/Style.php @@ -91,6 +91,13 @@ class PHPExcel_Style extends PHPExcel_Style_Supervisor implements PHPExcel_IComp */ protected $_index; + /** + * Use Quote Prefix when displaying in cell editor. Only used for real style. + * + * @var boolean + */ + protected $_quotePrefix = false; + /** * Create a new PHPExcel_Style * @@ -156,6 +163,17 @@ public function getParent() return $this->_parent; } + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('quotePrefix' => $array); + } + /** * Apply styles from array * @@ -185,7 +203,8 @@ public function getParent() * 'rgb' => '808080' * ) * ) - * ) + * ), + * 'quotePrefix' => true * ) * ); * @@ -463,6 +482,9 @@ public function applyFromArray($pStyles = null, $pAdvanced = true) if (array_key_exists('protection', $pStyles)) { $this->getProtection()->applyFromArray($pStyles['protection']); } + if (array_key_exists('quotePrefix', $pStyles)) { + $this->_quotePrefix = $pStyles['quotePrefix']; + } } } else { throw new PHPExcel_Exception("Invalid style array passed."); @@ -566,6 +588,38 @@ public function getProtection() return $this->_protection; } + /** + * Get quote prefix + * + * @return boolean + */ + public function getQuotePrefix() + { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getQuotePrefix(); + } + return $this->_quotePrefix; + } + + /** + * Set quote prefix + * + * @param boolean $pValue + */ + public function setQuotePrefix($pValue) + { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = array('quotePrefix' => $pValue); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_quotePrefix = (boolean) $pValue; + } + return $this; + } + /** * Get hash code * @@ -586,6 +640,7 @@ public function getHashCode() . $this->_numberFormat->getHashCode() . $hashConditionals . $this->_protection->getHashCode() + . ($this->_quotePrefix ? 't' : 'f') . __CLASS__ ); } diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index 9c78dff48..3d67b3db8 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -70,6 +70,13 @@ class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPE */ private $_stylesConditionalHashTable; + /** + * Private unique PHPExcel_Style HashTable + * + * @var PHPExcel_HashTable + */ + private $_styleHashTable; + /** * Private unique PHPExcel_Style_Fill HashTable * @@ -135,7 +142,8 @@ public function __construct(PHPExcel $pPHPExcel = null) } $hashTablesArray = array( '_stylesConditionalHashTable', '_fillHashTable', '_fontHashTable', - '_bordersHashTable', '_numFmtHashTable', '_drawingHashTable' + '_bordersHashTable', '_numFmtHashTable', '_drawingHashTable', + '_styleHashTable' ); // Set HashTable variables @@ -191,6 +199,7 @@ public function save($pFilename = null) } // Create styles dictionaries + $this->_styleHashTable->addFromSource( $this->getWriterPart('Style')->allStyles($this->_spreadSheet) ); $this->_stylesConditionalHashTable->addFromSource( $this->getWriterPart('Style')->allConditionalStyles($this->_spreadSheet) ); $this->_fillHashTable->addFromSource( $this->getWriterPart('Style')->allFills($this->_spreadSheet) ); $this->_fontHashTable->addFromSource( $this->getWriterPart('Style')->allFonts($this->_spreadSheet) ); @@ -395,6 +404,15 @@ public function getStringTable() { return $this->_stringTable; } + /** + * Get PHPExcel_Style HashTable + * + * @return PHPExcel_HashTable + */ + public function getStyleHashTable() { + return $this->_styleHashTable; + } + /** * Get PHPExcel_Style_Conditional HashTable * diff --git a/Classes/PHPExcel/Writer/Excel2007/Style.php b/Classes/PHPExcel/Writer/Excel2007/Style.php index 887b5ab9d..bd246fcd0 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Style.php +++ b/Classes/PHPExcel/Writer/Excel2007/Style.php @@ -397,6 +397,9 @@ private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, $objWriter->startElement('xf'); $objWriter->writeAttribute('xfId', 0); $objWriter->writeAttribute('fontId', (int)$this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode())); + if ($pStyle->getQuotePrefix()) { + $objWriter->writeAttribute('quotePrefix', 1); + } if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) { $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164) ); diff --git a/Documentation/PHPExcel developer documentation.doc b/Documentation/PHPExcel developer documentation.doc index b6c1f4d273daa2cd68cf43f86403caa3d741c6ca..a3542c9a04c2d407ad1f24302959d7d6c6d86214 100644 GIT binary patch delta 4183 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 Date: Tue, 2 Jul 2013 13:13:07 +0100 Subject: [PATCH 106/467] Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer --- Classes/PHPExcel/Reader/Excel5.php | 9 ++++++++- Classes/PHPExcel/Style/Alignment.php | 3 +++ Classes/PHPExcel/Writer/Excel5/Xf.php | 3 ++- changelog.txt | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 495536979..8dc8d6c77 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -1569,11 +1569,15 @@ private function _readBof() private function _readFilepass() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); -// $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = substr($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 16-bit hash value of password + $password = strtoupper(dechex(self::_GetInt2d($recordData, 0))); // the hashed password + } throw new PHPExcel_Reader_Exception('Cannot read encrypted file'); } @@ -1836,6 +1840,9 @@ private function _readXf() case 3: $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); break; + case 4: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_FILL); + break; case 5: $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY); break; diff --git a/Classes/PHPExcel/Style/Alignment.php b/Classes/PHPExcel/Style/Alignment.php index 5bf2fa684..f7be8f60f 100644 --- a/Classes/PHPExcel/Style/Alignment.php +++ b/Classes/PHPExcel/Style/Alignment.php @@ -42,12 +42,15 @@ class PHPExcel_Style_Alignment extends PHPExcel_Style_Supervisor implements PHPE const HORIZONTAL_CENTER = 'center'; const HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous'; const HORIZONTAL_JUSTIFY = 'justify'; + const HORIZONTAL_FILL = 'fill'; + const HORIZONTAL_DISTRIBUTED = 'distributed'; // Excel2007 only /* Vertical alignment styles */ const VERTICAL_BOTTOM = 'bottom'; const VERTICAL_TOP = 'top'; const VERTICAL_CENTER = 'center'; const VERTICAL_JUSTIFY = 'justify'; + const VERTICAL_DISTRIBUTED = 'distributed'; // Excel2007 only /** * Horizontal diff --git a/Classes/PHPExcel/Writer/Excel5/Xf.php b/Classes/PHPExcel/Writer/Excel5/Xf.php index 241b5f894..da25c2bc5 100644 --- a/Classes/PHPExcel/Writer/Excel5/Xf.php +++ b/Classes/PHPExcel/Writer/Excel5/Xf.php @@ -179,7 +179,7 @@ function writeXf() // Flags to indicate if attributes have been set. $atr_num = ($this->_numberFormatIndex != 0)?1:0; $atr_fnt = ($this->_fontIndex != 0)?1:0; - $atr_alc = ((int) $this->_style->getAlignment()->getWrapText())?1:0; + $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0; $atr_bdr = (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) || self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) || self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) || @@ -457,6 +457,7 @@ private static function _mapFillType($fillType) { PHPExcel_Style_Alignment::HORIZONTAL_LEFT => 1, PHPExcel_Style_Alignment::HORIZONTAL_CENTER => 2, PHPExcel_Style_Alignment::HORIZONTAL_RIGHT => 3, + PHPExcel_Style_Alignment::HORIZONTAL_FILL => 4, PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY => 5, PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6, ); diff --git a/changelog.txt b/changelog.txt index f7b7767f1..7ff71fb06 100644 --- a/changelog.txt +++ b/changelog.txt @@ -29,6 +29,7 @@ Fixed in develop branch for release v1.7.9a: - Bugfix: (MBaker) - Problem with cloning worksheets - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) +- Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer Fixed in develop branch for release v1.7.9: - Feature: (MBaker) Include charts option for HTML Writer From 5818a79e67b205b76f4681c2832a8c8c35d43680 Mon Sep 17 00:00:00 2001 From: Maarten Balliauw Date: Wed, 10 Jul 2013 11:18:43 +0200 Subject: [PATCH 107/467] Update bootstrap.php --- unitTests/bootstrap.php | 1 + 1 file changed, 1 insertion(+) diff --git a/unitTests/bootstrap.php b/unitTests/bootstrap.php index d963cc7b1..19b31a883 100644 --- a/unitTests/bootstrap.php +++ b/unitTests/bootstrap.php @@ -30,6 +30,7 @@ set_include_path(implode(PATH_SEPARATOR, array( realpath(APPLICATION_PATH . '/../Classes'), './', + dirname(__FILE__), get_include_path(), ))); From 8057604241836132c7bef5e5d0371f07a184ff8a Mon Sep 17 00:00:00 2001 From: Maarten Balliauw Date: Wed, 10 Jul 2013 13:33:04 +0200 Subject: [PATCH 108/467] Updated include paths for examples --- Examples/01simple-download-pdf.php | 2 +- Examples/01simple-download-xls.php | 2 +- Examples/01simple-download-xlsx.php | 2 +- Examples/01simple.php | 2 +- Examples/02types-xls.php | 2 +- Examples/02types.php | 2 +- Examples/03formulas.php | 2 +- Examples/04printing.php | 2 +- Examples/05featuredemo.php | 2 +- Examples/06largescale-with-cellcaching-sqlite.php | 2 +- Examples/06largescale-with-cellcaching-sqlite3.php | 2 +- Examples/06largescale-with-cellcaching.php | 2 +- Examples/06largescale-xls.php | 2 +- Examples/06largescale.php | 2 +- Examples/07reader.php | 2 +- Examples/08conditionalformatting.php | 2 +- Examples/08conditionalformatting2.php | 2 +- Examples/09pagebreaks.php | 2 +- Examples/10autofilter-selection-1.php | 2 +- Examples/10autofilter-selection-2.php | 2 +- Examples/10autofilter-selection-display.php | 2 +- Examples/10autofilter.php | 2 +- Examples/11documentsecurity-xls.php | 2 +- Examples/11documentsecurity.php | 2 +- Examples/12cellProtection.php | 2 +- Examples/13calculation.php | 2 +- Examples/14excel5.php | 2 +- Examples/15datavalidation-xls.php | 2 +- Examples/15datavalidation.php | 2 +- Examples/16csv.php | 2 +- Examples/17html.php | 2 +- Examples/18extendedcalculation.php | 2 +- Examples/19namedrange.php | 2 +- Examples/20readexcel5.php | 2 +- Examples/21pdf.php | 2 +- Examples/22heavilyformatted.php | 2 +- Examples/23sharedstyles.php | 2 +- Examples/24readfilter.php | 2 +- Examples/25inmemoryimage.php | 2 +- Examples/26utf8.php | 2 +- Examples/27imagesexcel5.php | 2 +- Examples/28iterator.php | 2 +- Examples/29advancedvaluebinder.php | 2 +- Examples/30template.php | 2 +- Examples/31docproperties_write-xls.php | 2 +- Examples/31docproperties_write.php | 2 +- Examples/32chartreadwrite.php | 2 +- Examples/33chartcreate-area.php | 2 +- Examples/33chartcreate-bar-stacked.php | 2 +- Examples/33chartcreate-bar.php | 2 +- Examples/33chartcreate-column-2.php | 2 +- Examples/33chartcreate-column.php | 2 +- Examples/33chartcreate-composite.php | 2 +- Examples/33chartcreate-line.php | 2 +- Examples/33chartcreate-multiple-charts.php | 2 +- Examples/33chartcreate-pie.php | 2 +- Examples/33chartcreate-radar.php | 2 +- Examples/33chartcreate-scatter.php | 2 +- Examples/35chartrender.php | 2 +- Examples/36chartreadwriteHTML.php | 2 +- Examples/36chartreadwritePDF.php | 2 +- Examples/37page_layout_view.php | 2 +- Examples/38cloneWorksheet.php | 2 +- Examples/40duplicateStyle.php | 2 +- Examples/Excel2003XMLReader.php | 2 +- Examples/GnumericReader.php | 2 +- Examples/OOCalcReader.php | 2 +- Examples/Quadratic.php | 2 +- Examples/Quadratic2.php | 2 +- Examples/SylkReader.php | 2 +- Examples/XMLReader.php | 2 +- 71 files changed, 71 insertions(+), 71 deletions(-) diff --git a/Examples/01simple-download-pdf.php b/Examples/01simple-download-pdf.php index d3dcdfc47..4de034711 100644 --- a/Examples/01simple-download-pdf.php +++ b/Examples/01simple-download-pdf.php @@ -35,7 +35,7 @@ die('This example should only be run from a Web Browser'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Change these values to select the Rendering library that you wish to use diff --git a/Examples/01simple-download-xls.php b/Examples/01simple-download-xls.php index f7f7aed96..ddbfc44a2 100644 --- a/Examples/01simple-download-xls.php +++ b/Examples/01simple-download-xls.php @@ -35,7 +35,7 @@ die('This example should only be run from a Web Browser'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/01simple-download-xlsx.php b/Examples/01simple-download-xlsx.php index 7e040b374..a2b927b82 100644 --- a/Examples/01simple-download-xlsx.php +++ b/Examples/01simple-download-xlsx.php @@ -35,7 +35,7 @@ die('This example should only be run from a Web Browser'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/01simple.php b/Examples/01simple.php index 5dbf743c3..baeb4cc9b 100644 --- a/Examples/01simple.php +++ b/Examples/01simple.php @@ -34,7 +34,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/02types-xls.php b/Examples/02types-xls.php index 005d2ff2a..1e9025d60 100644 --- a/Examples/02types-xls.php +++ b/Examples/02types-xls.php @@ -34,7 +34,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/02types.php b/Examples/02types.php index 914c82d9a..4fc4114a6 100644 --- a/Examples/02types.php +++ b/Examples/02types.php @@ -34,7 +34,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/03formulas.php b/Examples/03formulas.php index 4f464d442..04e56d240 100644 --- a/Examples/03formulas.php +++ b/Examples/03formulas.php @@ -34,7 +34,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/04printing.php b/Examples/04printing.php index de6aa49ec..6a90eede3 100644 --- a/Examples/04printing.php +++ b/Examples/04printing.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/05featuredemo.php b/Examples/05featuredemo.php index 83e36c56d..3bfb9984a 100644 --- a/Examples/05featuredemo.php +++ b/Examples/05featuredemo.php @@ -37,7 +37,7 @@ include "05featuredemo.inc.php"; /** Include PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; // Save Excel 2007 file diff --git a/Examples/06largescale-with-cellcaching-sqlite.php b/Examples/06largescale-with-cellcaching-sqlite.php index b3bdcac99..80a9e436a 100644 --- a/Examples/06largescale-with-cellcaching-sqlite.php +++ b/Examples/06largescale-with-cellcaching-sqlite.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite; PHPExcel_Settings::setCacheStorageMethod($cacheMethod); diff --git a/Examples/06largescale-with-cellcaching-sqlite3.php b/Examples/06largescale-with-cellcaching-sqlite3.php index 768f7d160..678e2ecd0 100644 --- a/Examples/06largescale-with-cellcaching-sqlite3.php +++ b/Examples/06largescale-with-cellcaching-sqlite3.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3; PHPExcel_Settings::setCacheStorageMethod($cacheMethod); diff --git a/Examples/06largescale-with-cellcaching.php b/Examples/06largescale-with-cellcaching.php index ff6e7b2dd..adb93c4bc 100644 --- a/Examples/06largescale-with-cellcaching.php +++ b/Examples/06largescale-with-cellcaching.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip; if (!PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) { diff --git a/Examples/06largescale-xls.php b/Examples/06largescale-xls.php index b5b80695a..d1fde8916 100644 --- a/Examples/06largescale-xls.php +++ b/Examples/06largescale-xls.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; /* diff --git a/Examples/06largescale.php b/Examples/06largescale.php index 3eb431234..2e597d3f5 100644 --- a/Examples/06largescale.php +++ b/Examples/06largescale.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; /* diff --git a/Examples/07reader.php b/Examples/07reader.php index 93456ceb3..482a375d5 100644 --- a/Examples/07reader.php +++ b/Examples/07reader.php @@ -34,7 +34,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; if (!file_exists("05featuredemo.xlsx")) { diff --git a/Examples/08conditionalformatting.php b/Examples/08conditionalformatting.php index 89a77a787..6f384d262 100644 --- a/Examples/08conditionalformatting.php +++ b/Examples/08conditionalformatting.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/08conditionalformatting2.php b/Examples/08conditionalformatting2.php index b59c66d20..630eb6b63 100644 --- a/Examples/08conditionalformatting2.php +++ b/Examples/08conditionalformatting2.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/09pagebreaks.php b/Examples/09pagebreaks.php index f37f763f0..5b2da248a 100644 --- a/Examples/09pagebreaks.php +++ b/Examples/09pagebreaks.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/10autofilter-selection-1.php b/Examples/10autofilter-selection-1.php index 98f46babc..ef41cf165 100644 --- a/Examples/10autofilter-selection-1.php +++ b/Examples/10autofilter-selection-1.php @@ -34,7 +34,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/10autofilter-selection-2.php b/Examples/10autofilter-selection-2.php index 82bd8b53f..c6628114b 100644 --- a/Examples/10autofilter-selection-2.php +++ b/Examples/10autofilter-selection-2.php @@ -34,7 +34,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/10autofilter-selection-display.php b/Examples/10autofilter-selection-display.php index 26eefecee..0e60e3713 100644 --- a/Examples/10autofilter-selection-display.php +++ b/Examples/10autofilter-selection-display.php @@ -34,7 +34,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/10autofilter.php b/Examples/10autofilter.php index d9cb54050..3f7975c6c 100644 --- a/Examples/10autofilter.php +++ b/Examples/10autofilter.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object echo date('H:i:s').' Create new PHPExcel object'.EOL; diff --git a/Examples/11documentsecurity-xls.php b/Examples/11documentsecurity-xls.php index 6ad13005b..071b4aea5 100644 --- a/Examples/11documentsecurity-xls.php +++ b/Examples/11documentsecurity-xls.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/11documentsecurity.php b/Examples/11documentsecurity.php index 7a5135c5d..94378a9de 100644 --- a/Examples/11documentsecurity.php +++ b/Examples/11documentsecurity.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/12cellProtection.php b/Examples/12cellProtection.php index 77ad5c2e1..f6507b1f7 100644 --- a/Examples/12cellProtection.php +++ b/Examples/12cellProtection.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/13calculation.php b/Examples/13calculation.php index bfbd51d2e..c1c0de8da 100644 --- a/Examples/13calculation.php +++ b/Examples/13calculation.php @@ -36,7 +36,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // List functions diff --git a/Examples/14excel5.php b/Examples/14excel5.php index f56c5d454..62a9fe465 100644 --- a/Examples/14excel5.php +++ b/Examples/14excel5.php @@ -37,7 +37,7 @@ include "05featuredemo.inc.php"; /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; // Save Excel 95 file diff --git a/Examples/15datavalidation-xls.php b/Examples/15datavalidation-xls.php index df99bdc7b..9652546db 100644 --- a/Examples/15datavalidation-xls.php +++ b/Examples/15datavalidation-xls.php @@ -36,7 +36,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/15datavalidation.php b/Examples/15datavalidation.php index faabddef1..af49c6a06 100644 --- a/Examples/15datavalidation.php +++ b/Examples/15datavalidation.php @@ -36,7 +36,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/16csv.php b/Examples/16csv.php index b456c9c35..9f9405182 100644 --- a/Examples/16csv.php +++ b/Examples/16csv.php @@ -38,7 +38,7 @@ include "05featuredemo.inc.php"; /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; echo date('H:i:s') , " Write to CSV format" , EOL; diff --git a/Examples/17html.php b/Examples/17html.php index c08e902ab..3ad968d1e 100644 --- a/Examples/17html.php +++ b/Examples/17html.php @@ -38,7 +38,7 @@ include "05featuredemo.inc.php"; /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; echo date('H:i:s') , " Write to HTML format" , EOL; diff --git a/Examples/18extendedcalculation.php b/Examples/18extendedcalculation.php index fb80dc02b..b037106a7 100644 --- a/Examples/18extendedcalculation.php +++ b/Examples/18extendedcalculation.php @@ -36,7 +36,7 @@ date_default_timezone_set('Europe/London'); /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // List functions diff --git a/Examples/19namedrange.php b/Examples/19namedrange.php index 8a86bf747..444ca07c7 100644 --- a/Examples/19namedrange.php +++ b/Examples/19namedrange.php @@ -36,7 +36,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/20readexcel5.php b/Examples/20readexcel5.php index 2aeefb259..d09c05209 100644 --- a/Examples/20readexcel5.php +++ b/Examples/20readexcel5.php @@ -36,7 +36,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; if (!file_exists("14excel5.xls")) { diff --git a/Examples/21pdf.php b/Examples/21pdf.php index cae16a01a..70aa792b7 100644 --- a/Examples/21pdf.php +++ b/Examples/21pdf.php @@ -38,7 +38,7 @@ include "05featuredemo.inc.php"; /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; // Change these values to select the Rendering library that you wish to use diff --git a/Examples/22heavilyformatted.php b/Examples/22heavilyformatted.php index e4025c12e..188857d27 100644 --- a/Examples/22heavilyformatted.php +++ b/Examples/22heavilyformatted.php @@ -36,7 +36,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/23sharedstyles.php b/Examples/23sharedstyles.php index 744ccd2f8..1a07cd47b 100644 --- a/Examples/23sharedstyles.php +++ b/Examples/23sharedstyles.php @@ -36,7 +36,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/24readfilter.php b/Examples/24readfilter.php index d5de002a1..b51cc5969 100644 --- a/Examples/24readfilter.php +++ b/Examples/24readfilter.php @@ -34,7 +34,7 @@ date_default_timezone_set('Europe/London'); /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; // Check prerequisites diff --git a/Examples/25inmemoryimage.php b/Examples/25inmemoryimage.php index 5c363807e..8d99e1867 100644 --- a/Examples/25inmemoryimage.php +++ b/Examples/25inmemoryimage.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/26utf8.php b/Examples/26utf8.php index 67651ff20..08fd85115 100644 --- a/Examples/26utf8.php +++ b/Examples/26utf8.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Change these values to select the PDF Rendering library that you wish to use diff --git a/Examples/27imagesexcel5.php b/Examples/27imagesexcel5.php index a2f554747..e83996188 100644 --- a/Examples/27imagesexcel5.php +++ b/Examples/27imagesexcel5.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Read from Excel5 (.xls) template diff --git a/Examples/28iterator.php b/Examples/28iterator.php index f6783afac..d86e0207d 100644 --- a/Examples/28iterator.php +++ b/Examples/28iterator.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; if (!file_exists("05featuredemo.xlsx")) { diff --git a/Examples/29advancedvaluebinder.php b/Examples/29advancedvaluebinder.php index 60831c065..5c3bd2c90 100644 --- a/Examples/29advancedvaluebinder.php +++ b/Examples/29advancedvaluebinder.php @@ -33,7 +33,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Set timezone diff --git a/Examples/30template.php b/Examples/30template.php index 9480735bd..62802ba4b 100644 --- a/Examples/30template.php +++ b/Examples/30template.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; diff --git a/Examples/31docproperties_write-xls.php b/Examples/31docproperties_write-xls.php index 1cdfbf598..f68dff5bf 100644 --- a/Examples/31docproperties_write-xls.php +++ b/Examples/31docproperties_write-xls.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $inputFileType = 'Excel5'; diff --git a/Examples/31docproperties_write.php b/Examples/31docproperties_write.php index 1e3d87d12..6ca7631f9 100644 --- a/Examples/31docproperties_write.php +++ b/Examples/31docproperties_write.php @@ -35,7 +35,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $inputFileType = 'Excel2007'; diff --git a/Examples/32chartreadwrite.php b/Examples/32chartreadwrite.php index 3a4ee03f9..0ecab8e0a 100644 --- a/Examples/32chartreadwrite.php +++ b/Examples/32chartreadwrite.php @@ -37,7 +37,7 @@ */ /** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); +set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/'); /** PHPExcel_IOFactory */ include 'PHPExcel/IOFactory.php'; diff --git a/Examples/33chartcreate-area.php b/Examples/33chartcreate-area.php index cb57240a9..9a1e9c7fa 100644 --- a/Examples/33chartcreate-area.php +++ b/Examples/33chartcreate-area.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/33chartcreate-bar-stacked.php b/Examples/33chartcreate-bar-stacked.php index f4ad142a6..cca6f6849 100644 --- a/Examples/33chartcreate-bar-stacked.php +++ b/Examples/33chartcreate-bar-stacked.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/33chartcreate-bar.php b/Examples/33chartcreate-bar.php index 3b86def91..d7344eecb 100644 --- a/Examples/33chartcreate-bar.php +++ b/Examples/33chartcreate-bar.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/33chartcreate-column-2.php b/Examples/33chartcreate-column-2.php index 424a8f611..18f90bf2d 100644 --- a/Examples/33chartcreate-column-2.php +++ b/Examples/33chartcreate-column-2.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/33chartcreate-column.php b/Examples/33chartcreate-column.php index 4d6c88569..caa5b8129 100644 --- a/Examples/33chartcreate-column.php +++ b/Examples/33chartcreate-column.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/33chartcreate-composite.php b/Examples/33chartcreate-composite.php index 70d3f3043..497e2b9ac 100644 --- a/Examples/33chartcreate-composite.php +++ b/Examples/33chartcreate-composite.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/33chartcreate-line.php b/Examples/33chartcreate-line.php index 5a41afc27..3e9ec7675 100644 --- a/Examples/33chartcreate-line.php +++ b/Examples/33chartcreate-line.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/33chartcreate-multiple-charts.php b/Examples/33chartcreate-multiple-charts.php index 545d47923..ee45f0a23 100644 --- a/Examples/33chartcreate-multiple-charts.php +++ b/Examples/33chartcreate-multiple-charts.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/33chartcreate-pie.php b/Examples/33chartcreate-pie.php index 6b62249a9..62360c4f2 100644 --- a/Examples/33chartcreate-pie.php +++ b/Examples/33chartcreate-pie.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/33chartcreate-radar.php b/Examples/33chartcreate-radar.php index 1e044e953..179dec0e7 100644 --- a/Examples/33chartcreate-radar.php +++ b/Examples/33chartcreate-radar.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/33chartcreate-scatter.php b/Examples/33chartcreate-scatter.php index eab9b4c6d..467d60155 100644 --- a/Examples/33chartcreate-scatter.php +++ b/Examples/33chartcreate-scatter.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $objPHPExcel = new PHPExcel(); diff --git a/Examples/35chartrender.php b/Examples/35chartrender.php index 7660da8fa..7d6e3cafc 100644 --- a/Examples/35chartrender.php +++ b/Examples/35chartrender.php @@ -37,7 +37,7 @@ */ /** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); +set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/'); /** PHPExcel_IOFactory */ include 'PHPExcel/IOFactory.php'; diff --git a/Examples/36chartreadwriteHTML.php b/Examples/36chartreadwriteHTML.php index afb00d017..6811c274a 100644 --- a/Examples/36chartreadwriteHTML.php +++ b/Examples/36chartreadwriteHTML.php @@ -37,7 +37,7 @@ */ /** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); +set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/'); /** PHPExcel_IOFactory */ include 'PHPExcel/IOFactory.php'; diff --git a/Examples/36chartreadwritePDF.php b/Examples/36chartreadwritePDF.php index 554c5b13e..a3517f39d 100644 --- a/Examples/36chartreadwritePDF.php +++ b/Examples/36chartreadwritePDF.php @@ -37,7 +37,7 @@ */ /** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); +set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/'); /** PHPExcel_IOFactory */ include 'PHPExcel/IOFactory.php'; diff --git a/Examples/37page_layout_view.php b/Examples/37page_layout_view.php index 4db30a0fc..042e8e851 100644 --- a/Examples/37page_layout_view.php +++ b/Examples/37page_layout_view.php @@ -34,7 +34,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/38cloneWorksheet.php b/Examples/38cloneWorksheet.php index d8e141c1f..d2f9a6d45 100644 --- a/Examples/38cloneWorksheet.php +++ b/Examples/38cloneWorksheet.php @@ -34,7 +34,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; // Create new PHPExcel object diff --git a/Examples/40duplicateStyle.php b/Examples/40duplicateStyle.php index 52891ad4c..be31951a4 100644 --- a/Examples/40duplicateStyle.php +++ b/Examples/40duplicateStyle.php @@ -10,7 +10,7 @@ date_default_timezone_set('Europe/London'); /** Include PHPExcel */ -require_once '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); diff --git a/Examples/Excel2003XMLReader.php b/Examples/Excel2003XMLReader.php index 0955c6fbb..96ee5a3f6 100644 --- a/Examples/Excel2003XMLReader.php +++ b/Examples/Excel2003XMLReader.php @@ -31,7 +31,7 @@ date_default_timezone_set('Europe/London'); /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; echo date('H:i:s') , " Load from Excel2003XML file" , PHP_EOL; diff --git a/Examples/GnumericReader.php b/Examples/GnumericReader.php index c79f18996..4304ccccb 100644 --- a/Examples/GnumericReader.php +++ b/Examples/GnumericReader.php @@ -31,7 +31,7 @@ date_default_timezone_set('Europe/London'); /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; echo date('H:i:s') , " Load from Gnumeric file" , PHP_EOL; $callStartTime = microtime(true); diff --git a/Examples/OOCalcReader.php b/Examples/OOCalcReader.php index a5e6d3508..237d12462 100644 --- a/Examples/OOCalcReader.php +++ b/Examples/OOCalcReader.php @@ -31,7 +31,7 @@ date_default_timezone_set('Europe/London'); /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; echo date('H:i:s') , " Load from OOCalc file" , PHP_EOL; $callStartTime = microtime(true); diff --git a/Examples/Quadratic.php b/Examples/Quadratic.php index ce4191a26..11a712e5d 100644 --- a/Examples/Quadratic.php +++ b/Examples/Quadratic.php @@ -9,7 +9,7 @@ error_reporting(E_ALL); /** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); +set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/'); ?>

Quadratic Equation Solver

diff --git a/Examples/Quadratic2.php b/Examples/Quadratic2.php index 93f285996..5f6013eab 100644 --- a/Examples/Quadratic2.php +++ b/Examples/Quadratic2.php @@ -9,7 +9,7 @@ error_reporting(E_ALL); /** Include path **/ -set_include_path(get_include_path() . PATH_SEPARATOR . '../Classes/'); +set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/'); ?>

Quadratic Equation Solver

diff --git a/Examples/SylkReader.php b/Examples/SylkReader.php index 7389bd6b6..9c7a5bee0 100644 --- a/Examples/SylkReader.php +++ b/Examples/SylkReader.php @@ -31,7 +31,7 @@ date_default_timezone_set('Europe/London'); /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; echo date('H:i:s') , " Load from SYLK file" , PHP_EOL; diff --git a/Examples/XMLReader.php b/Examples/XMLReader.php index b40370732..ca5e4bcf2 100644 --- a/Examples/XMLReader.php +++ b/Examples/XMLReader.php @@ -31,7 +31,7 @@ date_default_timezone_set('Europe/London'); /** PHPExcel_IOFactory */ -require_once '../Classes/PHPExcel/IOFactory.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; echo date('H:i:s') , " Load from XML file" , PHP_EOL; From a4e6355ef553741f134f01682bcf82bd7fe10dfe Mon Sep 17 00:00:00 2001 From: Maarten Balliauw Date: Wed, 10 Jul 2013 14:41:23 +0200 Subject: [PATCH 109/467] Update build.xml --- Build/build.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Build/build.xml b/Build/build.xml index 761e6487e..241cfc29b 100644 --- a/Build/build.xml +++ b/Build/build.xml @@ -1,7 +1,5 @@ - - @@ -152,6 +150,8 @@ + + @@ -213,4 +213,4 @@ - \ No newline at end of file + From d62615fbeb80d0021c849645826162f911ead77a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 11 Jul 2013 08:28:42 +0100 Subject: [PATCH 110/467] INDIRECT and OFFSET call to get worksheet rather than cell collection --- Classes/PHPExcel/Calculation/LookupRef.php | 12 ++++++------ Classes/PHPExcel/Cell.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index c3363f15d..96c7da20a 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -316,9 +316,9 @@ public static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL if (strpos($cellAddress,'!') !== FALSE) { list($sheetName, $cellAddress) = explode('!',$cellAddress); $sheetName = trim($sheetName, "'"); - $pSheet = $pCell->getParent()->getParent()->getSheetByName($sheetName); + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); } else { - $pSheet = $pCell->getParent(); + $pSheet = $pCell->getWorksheet(); } return PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, FALSE); @@ -327,9 +327,9 @@ public static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL if (strpos($cellAddress,'!') !== FALSE) { list($sheetName,$cellAddress) = explode('!',$cellAddress); $sheetName = trim($sheetName, "'"); - $pSheet = $pCell->getParent()->getParent()->getSheetByName($sheetName); + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); } else { - $pSheet = $pCell->getParent(); + $pSheet = $pCell->getWorksheet(); } return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, FALSE); @@ -421,9 +421,9 @@ public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null, } if ($sheetName !== NULL) { - $pSheet = $pCell->getParent()->getParent()->getSheetByName($sheetName); + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); } else { - $pSheet = $pCell->getParent(); + $pSheet = $pCell->getWorksheet(); } return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, False); diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 6664e6450..2cafff3ea 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -469,7 +469,7 @@ public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL) /** * Get parent worksheet * - * @return PHPExcel_Worksheet + * @return PHPExcel_CachedObjectStorage_CacheBase */ public function getParent() { return $this->_parent; From d4277abd853a4045cddc7a24afdfca91d324a156 Mon Sep 17 00:00:00 2001 From: Nikolay Ninkov Date: Mon, 15 Jul 2013 09:28:47 +0300 Subject: [PATCH 111/467] Bulgarian localisation Start translation to Bulgarian language. --- Classes/PHPExcel/locale/bg/config | 49 +++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Classes/PHPExcel/locale/bg/config diff --git a/Classes/PHPExcel/locale/bg/config b/Classes/PHPExcel/locale/bg/config new file mode 100644 index 000000000..4cecddb3c --- /dev/null +++ b/Classes/PHPExcel/locale/bg/config @@ -0,0 +1,49 @@ +## +## PHPExcel +## + +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version ##VERSION##, ##DATE## +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = лв + + +## +## Excel Error Codes (For future use) + +## +NULL = #ПРАЗНО! +DIV0 = #ДЕЛ/0! +VALUE = #СТОЙНОСТ! +REF = #РЕФ! +NAME = #ИМЕ? +NUM = #ЧИСЛО! +NA = #Н/Д From 963931a7e31e37d323824dd94f09934826c85bb2 Mon Sep 17 00:00:00 2001 From: Jack Stone Date: Thu, 18 Jul 2013 10:34:27 -0400 Subject: [PATCH 112/467] Update 02-Loading-a-Spreadsheet.md --- .../ReadingSpreadsheetFiles/02-Loading-a-Spreadsheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/02-Loading-a-Spreadsheet.md b/Documentation/markdown/ReadingSpreadsheetFiles/02-Loading-a-Spreadsheet.md index 986360f7c..afa674d1b 100644 --- a/Documentation/markdown/ReadingSpreadsheetFiles/02-Loading-a-Spreadsheet.md +++ b/Documentation/markdown/ReadingSpreadsheetFiles/02-Loading-a-Spreadsheet.md @@ -15,7 +15,7 @@ $objPHPExcel = PHPExcel_IOFactory::load($inputFileName); The load() method will attempt to identify the file type, and instantiate a loader for that file type; using it to load the file and store the data and any formatting in a PHPExcel object. -The method makes an initial guess at the loader to instantiate based on the file extension; but will test the file before actually executing the load: so if (for example) the file is actually a CSV file or conatins HTML markup, but that has been given a .xls extension (quite a common practise), it will reject the Excel5 loader that it would normally use for a .xls file; and test the file using the other loaders until it finds the appropriate loader, and then use that to read the file. +The method makes an initial guess at the loader to instantiate based on the file extension; but will test the file before actually executing the load: so if (for example) the file is actually a CSV file or contains HTML markup, but that has been given a .xls extension (quite a common practise), it will reject the Excel5 loader that it would normally use for a .xls file; and test the file using the other loaders until it finds the appropriate loader, and then use that to read the file. While easy to implement in your code, and you don't need to worry about the file type; this isn't the most efficient method to load a file; and it lacks the flexibility to configure the loader in any way before actually reading the file into a PHPExcel object. From 67ed42d0cdf2501a4e0d9f8bd97d2892152d9a21 Mon Sep 17 00:00:00 2001 From: Jack Stone Date: Thu, 18 Jul 2013 10:42:58 -0400 Subject: [PATCH 113/467] Update 10-Reading-and-Writing.md --- Documentation/markdown/Overview/10-Reading-and-Writing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/markdown/Overview/10-Reading-and-Writing.md b/Documentation/markdown/Overview/10-Reading-and-Writing.md index e582352ac..1468abc7e 100644 --- a/Documentation/markdown/Overview/10-Reading-and-Writing.md +++ b/Documentation/markdown/Overview/10-Reading-and-Writing.md @@ -8,7 +8,7 @@ As you already know from part REF _Ref191885438 \w \h 3.3 REF _Ref191885438 \h The PHPExcel API offers multiple methods to create a PHPExcel_Writer_IReader or PHPExcel_Writer_IWriter instance: -Direct creationVia PHPExcel_IOFactoryAll examples underneath demonstrate the direct creation method. Note that you can also use the PHPExcel_IOFactory class to do this. +Direct creation via PHPExcel_IOFactory. All examples underneath demonstrate the direct creation method. Note that you can also use the PHPExcel_IOFactory class to do this. #### Creating PHPExcel_Reader_IReader using PHPExcel_IOFactory From 2d39be32cb4321bd43b7aa790949df6a9a7d248b Mon Sep 17 00:00:00 2001 From: Andreas Scheibleger Date: Tue, 23 Jul 2013 14:16:40 +0200 Subject: [PATCH 114/467] Check whether margin-left is set in excel file when reading --- Classes/PHPExcel/Reader/Excel2007.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 678d837cf..412cc719d 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1371,7 +1371,9 @@ public function load($pFilename) $hfImages[ (string)$shape['id'] ]->setResizeProportional(false); $hfImages[ (string)$shape['id'] ]->setWidth($style['width']); $hfImages[ (string)$shape['id'] ]->setHeight($style['height']); - $hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']); + if (isset($style['margin-left'])) { + $hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']); + } $hfImages[ (string)$shape['id'] ]->setOffsetY($style['margin-top']); $hfImages[ (string)$shape['id'] ]->setResizeProportional(true); } From f1a1f525eafc26371451f85536d151d0c6dea9db Mon Sep 17 00:00:00 2001 From: Adrien Crivelli Date: Thu, 8 Aug 2013 12:17:00 +0900 Subject: [PATCH 115/467] Double quote support for SUMIF() SUMIF() should handle double quotes properly in both criteria and cells values. This is especially useful when we need to compare string containing themselve double quote(s). --- Classes/PHPExcel/Calculation/MathTrig.php | 6 +- .../PHPExcel/Calculation/MathTrigTest.php | 62 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index 69f296f72..929bccdc0 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -1164,7 +1164,11 @@ public static function SUMIF($aArgs,$condition,$sumArgs = array()) { $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); // Loop through arguments foreach ($aArgs as $key => $arg) { - if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + if (!is_numeric($arg)) { + $arg = str_replace('"', '""', $arg); + $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + } + $testCondition = '='.$arg.$condition; if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { // Is it a value within our criteria diff --git a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php index ce448d6ab..d6eaba022 100644 --- a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php @@ -479,6 +479,68 @@ public function testSQRTPI() public function providerSQRTPI() { return new testDataFileIterator('rawTestData/Calculation/MathTrig/SQRTPI.data'); + } + + /** + * @dataProvider providerSUMIF + */ + public function testSUMIF() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig', 'SUMIF'), $args); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); + } + + public function providerSUMIF() + { + return array( + array( + array( + array(1), + array(5), + array(10), + ), + '>=5', + 15, + ), + array( + array( + array('text'), + array(2), + ), + '=text', + array( + array(10), + array(100), + ), + 10, + ), + array( + array( + array('"text with quotes"'), + array(2), + ), + '=""text with quotes""', + array( + array(10), + array(100), + ), + 10, + ), + array( + array( + array('"text with quotes"'), + array(''), + ), + '>""', // Compare to the single characater " (double quote) + array( + array(10), + array(100), + ), + 10 + ), + ); } } From 60c9bf391cede3b95db94384960ec9572a2f413a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 15 Aug 2013 18:10:29 +0100 Subject: [PATCH 116/467] Excel compatibility mode for CSV Writer --- Classes/PHPExcel/Reader/Excel2003XML.php | 2 +- Classes/PHPExcel/Writer/CSV.php | 21 +++++++++------------ Examples/02types-xls.php | 11 +++++++++++ Examples/02types.php | 12 +++++++++++- Examples/16csv.php | 16 +++++++++++++++- 5 files changed, 47 insertions(+), 15 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index 1d16855d6..acde1cca6 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -22,7 +22,7 @@ * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @version 1.7.9, 2013-06-02 */ diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php index 2ca7c2581..6d624eebe 100644 --- a/Classes/PHPExcel/Writer/CSV.php +++ b/Classes/PHPExcel/Writer/CSV.php @@ -114,18 +114,19 @@ public function save($pFilename = null) { } if ($this->_excelCompatibility) { - // Write the UTF-16LE BOM code - fwrite($fileHandle, "\xFF\xFE"); // Excel uses UTF-16LE encoding - $this->setEnclosure(); // Default enclosure is " - $this->setDelimiter("\t"); // Excel delimiter is a TAB + fwrite($fileHandle, "\xEF\xBB\xBF"); // Enforce UTF-8 BOM Header + $this->setEnclosure('"'); // Set enclosure to " + $this->setDelimiter(";"); // Set delimiter to a semi-colon + $this->setLineEnding("\r\n"); + fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->_lineEnding); } elseif ($this->_useBOM) { - // Write the UTF-8 BOM code + // Write the UTF-8 BOM code if required fwrite($fileHandle, "\xEF\xBB\xBF"); } // Identify the range that we need to extract from the worksheet - $maxCol = $sheet->getHighestColumn(); - $maxRow = $sheet->getHighestRow(); + $maxCol = $sheet->getHighestDataColumn(); + $maxRow = $sheet->getHighestDataRow(); // Write rows to file for($row = 1; $row <= $maxRow; ++$row) { @@ -300,11 +301,7 @@ private function _writeLine($pFileHandle = null, $pValues = null) { $line .= $this->_lineEnding; // Write to file - if ($this->_excelCompatibility) { - fwrite($pFileHandle, mb_convert_encoding($line,"UTF-16LE","UTF-8")); - } else { - fwrite($pFileHandle, $line); - } + fwrite($pFileHandle, $line); } else { throw new PHPExcel_Writer_Exception("Invalid data row passed to CSV writer."); } diff --git a/Examples/02types-xls.php b/Examples/02types-xls.php index 1e9025d60..81d41914c 100644 --- a/Examples/02types-xls.php +++ b/Examples/02types-xls.php @@ -121,6 +121,17 @@ $objPHPExcel->getActiveSheet()->setCellValue('A13', 'Rich Text') ->setCellValue('C13', $objRichText); + +$objRichText2 = new PHPExcel_RichText(); +$objRichText2->createText("black text\n"); + +$objRed = $objRichText2->createTextRun("red text"); +$objRed->getFont()->setColor( new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_RED ) ); + +$objPHPExcel->getActiveSheet()->getCell("C14")->setValue($objRichText2); +$objPHPExcel->getActiveSheet()->getStyle("C14")->getAlignment()->setWrapText(true); + + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true); diff --git a/Examples/02types.php b/Examples/02types.php index 4fc4114a6..386e4f5b9 100644 --- a/Examples/02types.php +++ b/Examples/02types.php @@ -122,7 +122,17 @@ $objPHPExcel->getActiveSheet()->setCellValue('A13', 'Rich Text') ->setCellValue('C13', $objRichText); - + +$objRichText2 = new PHPExcel_RichText(); +$objRichText2->createText("black text\n"); + +$objRed = $objRichText2->createTextRun("red text"); +$objRed->getFont()->setColor( new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_RED ) ); + +$objPHPExcel->getActiveSheet()->getCell("C14")->setValue($objRichText2); +$objPHPExcel->getActiveSheet()->getStyle("C14")->getAlignment()->setWrapText(true); + + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true); diff --git a/Examples/16csv.php b/Examples/16csv.php index 9f9405182..8a1971786 100644 --- a/Examples/16csv.php +++ b/Examples/16csv.php @@ -38,7 +38,7 @@ include "05featuredemo.inc.php"; /** PHPExcel_IOFactory */ -require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; +require_once '../Classes/PHPExcel/IOFactory.php'; echo date('H:i:s') , " Write to CSV format" , EOL; @@ -85,6 +85,20 @@ echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; +echo date('H:i:s') , " Write to CSV format" , EOL; +$callStartTime = microtime(true); + +$objWriterCSV = PHPExcel_IOFactory::createWriter($objPHPExcelFromCSV, 'CSV'); +$objWriterCSV->setExcelCompatibility(true); +$objWriterCSV->save(str_replace('.php', '_excel.csv', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; +echo date('H:i:s') , " File written to " , str_replace('.php', '_excel.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + // Echo memory peak usage echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; From 44f953b69d78dbd79a0d1ea37e898056b710d88f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 15 Aug 2013 23:28:51 +0100 Subject: [PATCH 117/467] Fixes to style duplication --- Classes/PHPExcel/Style.php | 28 ++++++++++++++-------------- Classes/PHPExcel/Worksheet.php | 6 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Classes/PHPExcel/Style.php b/Classes/PHPExcel/Style.php index 646182619..a188f7195 100644 --- a/Classes/PHPExcel/Style.php +++ b/Classes/PHPExcel/Style.php @@ -422,7 +422,7 @@ public function applyFromArray($pStyles = null, $pAdvanced = true) $newStyle = clone $style; $newStyle->applyFromArray($pStyles); - if ($workbook->cellXfExists($newStyle)) { + if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) { // there is already such cell Xf in our collection $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex(); } else { @@ -595,9 +595,9 @@ public function getProtection() */ public function getQuotePrefix() { - if ($this->_isSupervisor) { - return $this->getSharedComponent()->getQuotePrefix(); - } + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getQuotePrefix(); + } return $this->_quotePrefix; } @@ -608,16 +608,16 @@ public function getQuotePrefix() */ public function setQuotePrefix($pValue) { - if ($pValue == '') { - $pValue = false; - } - if ($this->_isSupervisor) { - $styleArray = array('quotePrefix' => $pValue); - $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); - } else { - $this->_quotePrefix = (boolean) $pValue; - } - return $this; + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = array('quotePrefix' => $pValue); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_quotePrefix = (boolean) $pValue; + } + return $this; } /** diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 4c7b239b3..41b321294 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1476,9 +1476,9 @@ public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') // Add the style to the workbook if necessary $workbook = $this->_parent; - if ($this->_parent->cellXfExists($pCellStyle)) { - // there is already this cell Xf in our collection - $xfIndex = $pCellStyle->getIndex(); + if ($existingStyle = $this->_parent->getCellXfByHashCode($pCellStyle->getHashCode())) { + // there is already such cell Xf in our collection + $xfIndex = $existingStyle->getIndex(); } else { // we don't have such a cell Xf, need to add $workbook->addCellXf($pCellStyle); From 29746bb995c85b4fadd1c9346bfdff150e03390d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 18 Aug 2013 12:32:40 +0100 Subject: [PATCH 118/467] General: (cdhutch) Work item 20055 - remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed --- Classes/PHPExcel/ReferenceHelper.php | 6 +++++- changelog.txt | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index f6fb72fb1..f7d137094 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -424,7 +424,11 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } // Loop through cells, bottom-up, and change cell coordinates - while (($cellID = $remove ? array_shift($aCellCollection) : array_pop($aCellCollection))) { + if($remove) { + // It's faster to reverse and pop than to use unshift, especially with large cell collections + $aCellCollection = array_reverse($aCellCollection); + } + while ($cellID = array_pop($aCellCollection)) { $cell = $pSheet->getCell($cellID); $cellIndex = PHPExcel_Cell::columnIndexFromString($cell->getColumn()); if ($cellIndex-1 + $pNumCols < 0) { diff --git a/changelog.txt b/changelog.txt index 7ff71fb06..ab962b4a9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -23,13 +23,16 @@ ************************************************************************************** -Fixed in develop branch for release v1.7.9a: +Fixed in develop branch for release v1.8.0: - Bugfix: (MBaker) Work item 19830 - Undefined variable: fileHandle in CSV Reader +- Bugfix: (MBaker) Work item 19968 - Out of memory in style/supervisor.php - Bugfix: (MBaker) - Style error with merged cells in PDF Writer - Bugfix: (MBaker) - Problem with cloning worksheets - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer +- General: (cdhutch) Work item 20055 - remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed + Fixed in develop branch for release v1.7.9: - Feature: (MBaker) Include charts option for HTML Writer From a11a8da4170d89c4557582832556c7e035facefd Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 23 Aug 2013 09:06:15 +0100 Subject: [PATCH 119/467] Issue 19827 - Unknown codepage: 10008 --- Classes/PHPExcel/Shared/CodePage.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index c91ecb363..6bc4f4819 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -85,6 +85,7 @@ public static function NumberToName($codePage = 1252) case 10000: return 'MAC'; break; // Apple Roman case 10006: return 'MACGREEK'; break; // Macintosh Greek case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic + case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe case 10079: return 'MACICELAND'; break; // Macintosh Icelandic case 10081: return 'MACTURKISH'; break; // Macintosh Turkish From 4b0c98eb588ce312bdfb14450fedf4d54b1e12e6 Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Fri, 6 Sep 2013 10:53:46 +0200 Subject: [PATCH 120/467] Travis: test also against PHP 5.5 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 532f05164..8b53bf22e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ php: - 5.3.3 - 5.3 - 5.4 + - 5.5 script: - phpunit -c ./unitTests/ From cb5fc9532f17c7d378903fee10e545dc9e24cafb Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 14 Sep 2013 23:13:17 +0100 Subject: [PATCH 121/467] Fixes to stock charts --- Classes/PHPExcel/Chart/Renderer/jpgraph.php | 29 +++- Classes/PHPExcel/Writer/Excel2007/Chart.php | 21 ++- Examples/33chartcreate-stock.php | 151 ++++++++++++++++++++ Examples/runall.php | 1 + 4 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 Examples/33chartcreate-stock.php diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index 9da620dc8..f2e6e24cc 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -517,19 +517,36 @@ private function _renderPlotContour($groupID) { private function _renderPlotStock($groupID) { $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); $plotOrder = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); + $seriesPlots = array(); + //var_dump($seriesCount); $dataValues = array(); + // Loop through each data series in turn for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + foreach($dataValuesX as $j => $dataValueX) { + $dataValues[$plotOrder[$i]][$j] = $dataValueX; + } + } - foreach($dataValuesX as $j => $dataValueX) - $dataValues[$j][$plotOrder[$i]] = $dataValueX; + if(empty($dataValues)) { + return; } - $seriesPlot = new StockPlot($dataValues); + $dataValuesPlot = array(); + + for($j = 0; $j < count($dataValues[0]); $j++) { + for($i = 0; $i < $seriesCount; $i++) { + $dataValuesPlot[] = $dataValues[$i][$j]; + } + } + + $xAxisLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + + $seriesPlot = new StockPlot($dataValuesPlot, $xAxisLabel); + $seriesPlot->SetWidth(20); $this->_graph->Add($seriesPlot); } // function _renderPlotStock() @@ -681,9 +698,9 @@ private function _renderRadarChart($groupCount) { private function _renderStockChart($groupCount) { require_once('jpgraph_stock.php'); - $this->_renderCartesianPlotArea(); + $this->_renderCartesianPlotArea('intint'); - for($groupID = 0; $groupID < $groupCount; ++$i) { + for($groupID = 0; $groupID < $groupCount; ++$groupID) { $this->_renderPlotStock($groupID); } } // function _renderStockChart() diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 763f8af02..8ea5851cd 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -299,6 +299,20 @@ private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, $objWriter->startElement('c:hiLowLines'); $objWriter->endElement(); + + $objWriter->startElement( 'c:upDownBars' ); + + $objWriter->startElement( 'c:gapWidth' ); + $objWriter->writeAttribute('val', 300); + $objWriter->endElement(); + + $objWriter->startElement( 'c:upBars' ); + $objWriter->endElement(); + + $objWriter->startElement( 'c:downBars' ); + $objWriter->endElement(); + + $objWriter->endElement(); } // Generate 2 unique numbers to use for axId values @@ -779,10 +793,15 @@ private function _writePlotGroup( $plotGroup, } // Formatting for the points - if ($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) { + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { $objWriter->startElement('c:spPr'); $objWriter->startElement('a:ln'); $objWriter->writeAttribute('w', 12700); + if ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { + $objWriter->startElement('a:noFill'); + $objWriter->endElement(); + } $objWriter->endElement(); $objWriter->endElement(); } diff --git a/Examples/33chartcreate-stock.php b/Examples/33chartcreate-stock.php new file mode 100644 index 000000000..080662769 --- /dev/null +++ b/Examples/33chartcreate-stock.php @@ -0,0 +1,151 @@ +'); + +date_default_timezone_set('Europe/London'); + +/** + * PHPExcel + * + * Copyright (C) 2006 - 2013 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## + */ + +/** PHPExcel */ +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; + + +$objPHPExcel = new PHPExcel(); +$objWorksheet = $objPHPExcel->getActiveSheet(); +$objWorksheet->fromArray( + array( + array('Counts', 'Max', 'Min', 'Min Threshold', 'Max Threshold' ), + array(10, 10, 5, 0, 50 ), + array(30, 20, 10, 0, 50 ), + array(20, 30, 15, 0, 50 ), + array(40, 10, 0, 0, 50 ), + array(100, 40, 5, 0, 50 ), + ), null, 'A1', true +); +$objWorksheet->getStyle('B2:E6')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_00); + + +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker +$dataseriesLabels = array( + new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), //Max / Open + new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), //Min / Close + new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), //Min Threshold / Min + new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$E$1', NULL, 1), //Max Threshold / Max +); +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker +$xAxisTickValues = array( + new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$6', NULL, 5), // Counts +); +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker +$dataSeriesValues = array( + new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$6', NULL, 5), + new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$6', NULL, 5), + new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$6', NULL, 5), + new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$E$2:$E$6', NULL, 5), +); + +// Build the dataseries +$series = new PHPExcel_Chart_DataSeries( + PHPExcel_Chart_DataSeries::TYPE_STOCKCHART, // plotType + null, // plotGrouping - if we set this to not null, then xlsx throws error + range(0, count($dataSeriesValues)-1), // plotOrder + $dataseriesLabels, // plotLabel + $xAxisTickValues, // plotCategory + $dataSeriesValues // plotValues +); + +// Set the series in the plot area +$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series)); +// Set the chart legend +$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false); + +$title = new PHPExcel_Chart_Title('Test Stock Chart'); +$xAxisLabel = new PHPExcel_Chart_Title('Counts'); +$yAxisLabel = new PHPExcel_Chart_Title('Values'); + +// Create the chart +$chart = new PHPExcel_Chart( + 'stock-chart', // name + $title, // title + $legend, // legend + $plotarea, // plotArea + true, // plotVisibleOnly + 0, // displayBlanksAs + $xAxisLabel, // xAxisLabel + $yAxisLabel // yAxisLabel +); + +// Set the position where the chart should appear in the worksheet +$chart->setTopLeftPosition('A7'); +$chart->setBottomRightPosition('H20'); + +// Add the chart to the worksheet +$objWorksheet->addChart($chart); + + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->setIncludeCharts(TRUE); +$filename = str_replace('.php', '.xlsx', __FILE__); +if(file_exists($filename)) { + unlink($filename); +} +$objWriter->save($filename); +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Examples/runall.php b/Examples/runall.php index e19835f82..766f8eb3c 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -84,6 +84,7 @@ , '33chartcreate-line.php' , '33chartcreate-pie.php' , '33chartcreate-radar.php' + , '33chartcreate-stock.php' , '33chartcreate-multiple-charts.php' , '33chartcreate-composite.php' , '34chartupdate.php' From 47f38886647c6cb9322c2aead8339f807265c69c Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 15 Sep 2013 12:44:39 +0100 Subject: [PATCH 122/467] Fixed rendering of stock charts with jpgraph --- Classes/PHPExcel/Chart/Renderer/jpgraph.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index f2e6e24cc..9a822e8f5 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -524,8 +524,8 @@ private function _renderPlotStock($groupID) { $dataValues = array(); // Loop through each data series in turn - for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + foreach($plotOrder as $i => $v) { + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); foreach($dataValuesX as $j => $dataValueX) { $dataValues[$plotOrder[$i]][$j] = $dataValueX; } @@ -543,11 +543,16 @@ private function _renderPlotStock($groupID) { } } - $xAxisLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - - $seriesPlot = new StockPlot($dataValuesPlot, $xAxisLabel); + $seriesPlot = new StockPlot($dataValuesPlot); $seriesPlot->SetWidth(20); + $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->_graph->xaxis->SetTickLabels($datasetLabels); + } + $this->_graph->Add($seriesPlot); } // function _renderPlotStock() From 555a4ab828d84ec720ae2cf9dd3862010c5653f3 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 15 Sep 2013 18:11:48 +0100 Subject: [PATCH 123/467] In code comments for stock chart improvements --- Classes/PHPExcel/Chart/DataSeries.php | 1 + Classes/PHPExcel/Chart/Renderer/jpgraph.php | 16 ++++++---------- changelog.txt | 3 ++- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index 68382e789..0822de3fd 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -52,6 +52,7 @@ class PHPExcel_Chart_DataSeries const TYPE_RADARCHART = 'radarChart'; const TYPE_BUBBLECHART = 'bubbleChart'; const TYPE_STOCKCHART = 'stockChart'; + const TYPE_CANDLECHART = self::TYPE_STOCKCHART; // Synonym const GROUPING_CLUSTERED = 'clustered'; const GROUPING_STACKED = 'stacked'; diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index 9a822e8f5..fa0bf1088 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -518,34 +518,27 @@ private function _renderPlotStock($groupID) { $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); $plotOrder = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); - $seriesPlots = array(); - //var_dump($seriesCount); - $dataValues = array(); - - // Loop through each data series in turn + // Loop through each data series in turn and build the plot arrays foreach($plotOrder as $i => $v) { $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); foreach($dataValuesX as $j => $dataValueX) { $dataValues[$plotOrder[$i]][$j] = $dataValueX; } } - if(empty($dataValues)) { return; } $dataValuesPlot = array(); - + // Flatten the plot arrays to a single dimensional array to work with jpgraph for($j = 0; $j < count($dataValues[0]); $j++) { for($i = 0; $i < $seriesCount; $i++) { $dataValuesPlot[] = $dataValues[$i][$j]; } } - $seriesPlot = new StockPlot($dataValuesPlot); - $seriesPlot->SetWidth(20); - + // Set the x-axis labels $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); if ($labelCount > 0) { $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); @@ -553,6 +546,9 @@ private function _renderPlotStock($groupID) { $this->_graph->xaxis->SetTickLabels($datasetLabels); } + $seriesPlot = new StockPlot($dataValuesPlot); + $seriesPlot->SetWidth(20); + $this->_graph->Add($seriesPlot); } // function _renderPlotStock() diff --git a/changelog.txt b/changelog.txt index ab962b4a9..cbbc50ff7 100644 --- a/changelog.txt +++ b/changelog.txt @@ -31,7 +31,8 @@ Fixed in develop branch for release v1.8.0: - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer -- General: (cdhutch) Work item 20055 - remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed +- General: (cdhutch) Work item 20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed +- General: (MBaker) - Improve stock chart handling and rendering, with help from Swashata Ghosh Fixed in develop branch for release v1.7.9: From 68a0918ceb0cf0e46377713a6eba553969b04a7a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 4 Oct 2013 20:48:15 +0100 Subject: [PATCH 124/467] General: Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load if it's actually required General: Modified Excel2007 Writer to default preCalculateFormulas to false Note that autosize columns will still recalculate affected formulae internally --- Classes/PHPExcel/Writer/Excel2007.php | 11 +++++++++++ Classes/PHPExcel/Writer/Excel2007/Workbook.php | 8 ++++++-- Examples/03formulas.php | 9 +++++++++ Examples/13calculation.php | 9 +++++++++ changelog.txt | 4 ++++ 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index 3d67b3db8..4e93201a5 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -35,6 +35,17 @@ */ class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { + /** + * Pre-calculate formulas + * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are + * immediately available to MS Excel or other office spreadsheet viewer when opening the file + * + * Overrides the default TRUE for this specific writer for performance reasons + * + * @var boolean + */ + protected $_preCalculateFormulas = FALSE; + /** * Office2003 compatibility * diff --git a/Classes/PHPExcel/Writer/Excel2007/Workbook.php b/Classes/PHPExcel/Writer/Excel2007/Workbook.php index db88e74e8..2abf9ebd3 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel2007/Workbook.php @@ -194,10 +194,14 @@ private function _writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $reca { $objWriter->startElement('calcPr'); - $objWriter->writeAttribute('calcId', '124519'); + // Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc + // If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit + // because the file has changed + $objWriter->writeAttribute('calcId', '999999'); $objWriter->writeAttribute('calcMode', 'auto'); // fullCalcOnLoad isn't needed if we've recalculating for the save - $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? '0' : '1'); + $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0); + $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1); $objWriter->endElement(); } diff --git a/Examples/03formulas.php b/Examples/03formulas.php index 04e56d240..b493aa5ff 100644 --- a/Examples/03formulas.php +++ b/Examples/03formulas.php @@ -107,6 +107,15 @@ $callStartTime = microtime(true); $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); + +// +// If we set Pre Calculated Formulas to true then PHPExcel will calculate all formulae in the +// workbook before saving. This adds time and memory overhead, and can cause some problems with formulae +// using functions or features (such as array formulae) that aren't yet supported by the calculation engine +// If the value is false (the default) for the Excel2007 Writer, then MS Excel (or the application used to +// open the file) will need to recalculate values itself to guarantee that the correct results are available. +// +//$objWriter->setPreCalculateFormulas(true); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); $callEndTime = microtime(true); $callTime = $callEndTime - $callStartTime; diff --git a/Examples/13calculation.php b/Examples/13calculation.php index c1c0de8da..a8f17b0d7 100644 --- a/Examples/13calculation.php +++ b/Examples/13calculation.php @@ -207,6 +207,15 @@ $callStartTime = microtime(true); $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); + +// +// If we set Pre Calculated Formulas to true then PHPExcel will calculate all formulae in the +// workbook before saving. This adds time and memory overhead, and can cause some problems with formulae +// using functions or features (such as array formulae) that aren't yet supported by the calculation engine +// If the value is false (the default) for the Excel2007 Writer, then MS Excel (or the application used to +// open the file) will need to recalculate values itself to guarantee that the correct results are available. +// +//$objWriter->setPreCalculateFormulas(true); $objWriter->save(str_replace('.php', '.xlsx', __FILE__)); $callEndTime = microtime(true); $callTime = $callEndTime - $callStartTime; diff --git a/changelog.txt b/changelog.txt index cbbc50ff7..3eca4dc13 100644 --- a/changelog.txt +++ b/changelog.txt @@ -33,6 +33,10 @@ Fixed in develop branch for release v1.8.0: - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer - General: (cdhutch) Work item 20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed - General: (MBaker) - Improve stock chart handling and rendering, with help from Swashata Ghosh +- General: (MBaker) - Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load + if it's actually required +- General: (MBaker) - Modified Excel2007 Writer to default preCalculateFormulas to false + Note that autosize columns will still recalculate affected formulae internally Fixed in develop branch for release v1.7.9: From 4f82ad416093a4706aa333a91f8b2d8fdf8e047b Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 9 Oct 2013 12:48:41 +0100 Subject: [PATCH 125/467] Case-sensitivity fix --- Classes/PHPExcel/Writer/HTML.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 3affa7eac..ca45a6f4d 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -1019,13 +1019,13 @@ private function _generateTableHeader($pSheet) { $html .= $this->_setMargins($pSheet); if (!$this->_useInlineCss) { - $gridlines = $pSheet->getShowGridLines() ? ' gridlines' : ''; + $gridlines = $pSheet->getShowGridlines() ? ' gridlines' : ''; $html .= ' ' . PHP_EOL; } else { $style = isset($this->_cssStyles['table']) ? $this->_assembleCSS($this->_cssStyles['table']) : ''; - if ($this->_isPdf && $pSheet->getShowGridLines()) { + if ($this->_isPdf && $pSheet->getShowGridlines()) { $html .= '
' . PHP_EOL; } else { $html .= '
' . PHP_EOL; From bdd1f6fa31afd21ffec8029e588ded9482552014 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 13 Oct 2013 11:31:01 +0100 Subject: [PATCH 126/467] Added page header and footer examples to print options demo script --- Examples/09pagebreaks.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Examples/09pagebreaks.php b/Examples/09pagebreaks.php index 5b2da248a..4d038af2d 100644 --- a/Examples/09pagebreaks.php +++ b/Examples/09pagebreaks.php @@ -22,7 +22,7 @@ * @package PHPExcel * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @version 1.7.9, 2013-06-02 */ /** Error reporting */ @@ -78,9 +78,22 @@ } } - // Set active sheet index to the first sheet, so Excel opens this as the first sheet $objPHPExcel->setActiveSheetIndex(0); +$objPHPExcel->getActiveSheet()->setTitle('Printing Options'); + +// Set print headers +$objPHPExcel->getActiveSheet() + ->getHeaderFooter()->setOddHeader('&C&24&K0000FF&B&U&A'); +$objPHPExcel->getActiveSheet() + ->getHeaderFooter()->setEvenHeader('&C&24&K0000FF&B&U&A'); + +// Set print footers +$objPHPExcel->getActiveSheet() + ->getHeaderFooter()->setOddFooter('&R&D &T&C&F&LPage &P / &N'); +$objPHPExcel->getActiveSheet() + ->getHeaderFooter()->setEvenFooter('&L&D &T&C&F&RPage &P / &N'); + // Save Excel 2007 file From ea18123aea60456f280b442cf099ca329121fa9a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 13 Oct 2013 11:37:00 +0100 Subject: [PATCH 127/467] Added an isFormula() method to the cell object --- Classes/PHPExcel/Cell.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 2cafff3ea..73495d58e 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -370,6 +370,16 @@ public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING) return $this->notifyCacheController(); } + /** + * Identify if the cell contains a formula + * + * @return boolean + */ + public function isFormula() + { + return $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA + } + /** * Does this cell contain Data validation rules? * From b6e09de1956f320f3a0729f6dfd173d8e93dc055 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 13 Oct 2013 11:54:24 +0100 Subject: [PATCH 128/467] Fixed silly missing ; typo --- Classes/PHPExcel/Cell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 73495d58e..cbd8a8f7f 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -377,7 +377,7 @@ public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING) */ public function isFormula() { - return $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA + return $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA; } /** From 9d224456733e1ff89c03c4dc97ff9edc1a7c5577 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 13 Oct 2013 17:09:09 +0100 Subject: [PATCH 129/467] Eliminate some code duplication --- Classes/PHPExcel/Worksheet.php | 40 ++-------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 41b321294..a701f3ab6 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1485,26 +1485,8 @@ public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') $xfIndex = $pCellStyle->getIndex(); } - // Uppercase coordinate - $pRange = strtoupper($pRange); - - // Is it a cell range or a single cell? - $rangeA = ''; - $rangeB = ''; - if (strpos($pRange, ':') === false) { - $rangeA = $pRange; - $rangeB = $pRange; - } else { - list($rangeA, $rangeB) = explode(':', $pRange); - } - // Calculate range outer borders - $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA); - $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB); - - // Translate column into index - $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1; - $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1; + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange . ':' . $pRange); // Make sure we can loop upwards on rows and columns if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { @@ -1541,26 +1523,8 @@ public function duplicateConditionalStyle(array $pCellStyle = null, $pRange = '' } } - // Uppercase coordinate - $pRange = strtoupper($pRange); - - // Is it a cell range or a single cell? - $rangeA = ''; - $rangeB = ''; - if (strpos($pRange, ':') === false) { - $rangeA = $pRange; - $rangeB = $pRange; - } else { - list($rangeA, $rangeB) = explode(':', $pRange); - } - // Calculate range outer borders - $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA); - $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB); - - // Translate column into index - $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1; - $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1; + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange . ':' . $pRange); // Make sure we can loop upwards on rows and columns if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { From a90b711edde37e14e6b23676ca1e88b666eb4830 Mon Sep 17 00:00:00 2001 From: Marco Marche Date: Thu, 17 Oct 2013 10:50:14 +0200 Subject: [PATCH 130/467] Fixed problem in Excel 2007 reader with headers and footers containing multiple images. All images were substituted with the first one. --- Classes/PHPExcel/Reader/Excel2007.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 412cc719d..d197efff9 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1354,10 +1354,10 @@ public function load($pFilename) $hfImages = array(); $shapes = $vmlDrawing->xpath('//v:shape'); - foreach ($shapes as $shape) { + foreach ($shapes as $idx => $shape) { $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); $imageData = $shape->xpath('//v:imagedata'); - $imageData = $imageData[0]; + $imageData = $imageData[$idx]; $imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office'); $style = self::toCSSArray( (string)$shape['style'] ); From 6d21efc173b54e61fadeaaee971bfa219bf806c0 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 17 Oct 2013 11:19:20 +0100 Subject: [PATCH 131/467] Updated data validation example to show a list derived from data in the worksheet rather than from a comma-separated string --- Examples/15datavalidation.php | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/Examples/15datavalidation.php b/Examples/15datavalidation.php index af49c6a06..2b4745ff7 100644 --- a/Examples/15datavalidation.php +++ b/Examples/15datavalidation.php @@ -62,7 +62,15 @@ ->setCellValue('A3', "Number:") ->setCellValue('B3', "10") ->setCellValue('A5', "List:") - ->setCellValue('B5', "Item A"); + ->setCellValue('B5', "Item A") + ->setCellValue('A7', "List #2:") + ->setCellValue('B7', "Item #2") + ->setCellValue('D2', "Item #1") + ->setCellValue('D3', "Item #2") + ->setCellValue('D4', "Item #3") + ->setCellValue('D5', "Item #4") + ->setCellValue('D6', "Item #5") + ; // Set data validation @@ -91,7 +99,21 @@ $objValidation->setError('Value is not in list.'); $objValidation->setPromptTitle('Pick from list'); $objValidation->setPrompt('Please pick a value from the drop-down list.'); -$objValidation->setFormula1('"Item A,Item B,Item C"'); // Make sure to put the list items between " and " !!! +$objValidation->setFormula1('"Item A,Item B,Item C"'); // Make sure to put the list items between " and " if your list is simply a comma-separated list of values !!! + + +$objValidation = $objPHPExcel->getActiveSheet()->getCell('B7')->getDataValidation(); +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST ); +$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION ); +$objValidation->setAllowBlank(false); +$objValidation->setShowInputMessage(true); +$objValidation->setShowErrorMessage(true); +$objValidation->setShowDropDown(true); +$objValidation->setErrorTitle('Input error'); +$objValidation->setError('Value is not in list.'); +$objValidation->setPromptTitle('Pick from list'); +$objValidation->setPrompt('Please pick a value from the drop-down list.'); +$objValidation->setFormula1('$D$2:$D$6'); // Make sure NOT to put a range of cells or a formula between " and " !!! // Set active sheet index to the first sheet, so Excel opens this as the first sheet From bff907a1b8d00a69f480e9923176c7f744965b08 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 28 Oct 2013 19:05:26 +0000 Subject: [PATCH 132/467] Number format mask test for dates: test for "General" format should be case-insensitive, and scientific format mask shouldn't return a positive for date --- Classes/PHPExcel/Shared/Date.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index fe8fc6a1c..4bae5f2fb 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -280,11 +280,14 @@ public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) { * @return boolean */ public static function isDateTimeFormatCode($pFormatCode = '') { + if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) + // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) + return FALSE; + if (preg_match('/0E[+-]0/i', $pFormatCode)) { + // Scientific format + return FALSE; // Switch on formatcode switch ($pFormatCode) { - // General contains an epoch letter 'e', so we trap for it explicitly here - case PHPExcel_Style_NumberFormat::FORMAT_GENERAL: - return FALSE; // Explicitly defined date formats case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD: case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2: From f86458630f49fcbe8f1022e6ec352d7c292eb198 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 28 Oct 2013 19:13:59 +0000 Subject: [PATCH 133/467] Trap for scientific format masks with "0" or "#" before the "E" --- Classes/PHPExcel/Shared/Date.php | 2 +- Classes/PHPExcel/Style/NumberFormat.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index 4bae5f2fb..0c7bb913f 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -283,7 +283,7 @@ public static function isDateTimeFormatCode($pFormatCode = '') { if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) return FALSE; - if (preg_match('/0E[+-]0/i', $pFormatCode)) { + if (preg_match('/[0#]E[+-]0/i', $pFormatCode)) // Scientific format return FALSE; // Switch on formatcode diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index 80347bf93..a0688f494 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -673,7 +673,7 @@ public static function toFormattedString($value = '0', $format = PHPExcel_Style_ ); $value = preg_replace($number_regex, $value, $format); } else { - if (preg_match('/0E[+-]0/i', $format)) { + if (preg_match('/[0#]E[+-]0/i', $format)) { // Scientific format $value = sprintf('%5.2E', $value); } elseif (preg_match('/0([^\d\.]+)0/', $format)) { From 233021529cf0ff1ae2961b05159fb9f28c9ce019 Mon Sep 17 00:00:00 2001 From: Trevor North Date: Tue, 29 Oct 2013 11:25:36 +0000 Subject: [PATCH 134/467] Implement Excel 5 RC4 stream decryption The decryption functions and objects implemented here are are based on the source of Spreadsheet-ParseExcel: http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/ --- Classes/PHPExcel/Reader/Excel5.php | 380 ++++++++++++++++++++----- Classes/PHPExcel/Reader/Excel5/MD5.php | 229 +++++++++++++++ Classes/PHPExcel/Reader/Excel5/RC4.php | 88 ++++++ 3 files changed, 623 insertions(+), 74 deletions(-) create mode 100644 Classes/PHPExcel/Reader/Excel5/MD5.php create mode 100644 Classes/PHPExcel/Reader/Excel5/RC4.php diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 8dc8d6c77..601c492d3 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -159,6 +159,13 @@ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExce const XLS_Type_PAGELAYOUTVIEW = 0x088b; const XLS_Type_UNKNOWN = 0xffff; + // Encryption type + const MS_BIFF_CRYPTO_NONE = 0; + const MS_BIFF_CRYPTO_XOR = 1; + const MS_BIFF_CRYPTO_RC4 = 2; + + // Size of stream blocks when using RC4 encryption + const REKEY_BLOCK = 0x400; /** * Summary Information stream data. @@ -379,6 +386,40 @@ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExce */ private $_sharedFormulaParts; + /** + * The type of encryption in use + * + * @var int + */ + private $_encryption = 0; + + /** + * The position in the stream after which contents are encrypted + * + * @var int + */ + private $_encryptionStartPos = false; + + /** + * The current RC4 decryption object + * + * @var PHPExcel_Reader_Excel5_RC4 + */ + private $_rc4Key = null; + + /** + * The position in the stream that the RC4 decryption object was left at + * + * @var int + */ + private $_rc4Pos = 0; + + /** + * The current MD5 context state + * + * @var string + */ + private $_md5Ctxt = null; /** * Create a new PHPExcel_Reader_Excel5 instance @@ -531,7 +572,7 @@ public function listWorksheetInfo($pFilename) case self::XLS_Type_BOOLERR: case self::XLS_Type_LABEL: $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -1051,7 +1092,63 @@ public function load($pFilename) return $this->_phpExcel; } - + + /** + * Read record data from stream, decrypting as required + * + * @param string $data Data stream to read from + * @param int $pos Position to start reading from + * @param int $length Record data length + * + * @return string Record data + */ + private function _readRecordData($data, $pos, $len) + { + $data = substr($data, $pos, $len); + + // File not encrypted, or record before encryption start point + if ($this->_encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->_encryptionStartPos) { + return $data; + } + + $recordData = ''; + if ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) { + + $oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK); + $block = floor($pos / self::REKEY_BLOCK); + $endBlock = floor(($pos + $len) / self::REKEY_BLOCK); + + // Spin an RC4 decryptor to the right spot. If we have a decryptor sitting + // at a point earlier in the current block, re-use it as we can save some time. + if ($block != $oldBlock || $pos < $this->_rc4Pos || !$this->_rc4Key) { + $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + $step = $pos % self::REKEY_BLOCK; + } else { + $step = $pos - $this->_rc4Pos; + } + $this->_rc4Key->RC4(str_repeat("\0", $step)); + + // Decrypt record data (re-keying at the end of every block) + while ($block != $endBlock) { + $step = self::REKEY_BLOCK - ($pos % self::REKEY_BLOCK); + $recordData .= $this->_rc4Key->RC4(substr($data, 0, $step)); + $data = substr($data, $step); + $pos += $step; + $len -= $step; + $block++; + $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + } + $recordData .= $this->_rc4Key->RC4(substr($data, 0, $len)); + + // Keep track of the position of this decryptor. + // We'll try and re-use it later if we can to speed things up + $this->_rc4Pos = $pos + $len; + + } elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) { + throw new PHPExcel_Reader_Exception('XOr encryption not supported'); + } + return $recordData; + } /** * Use OLE reader to extract the relevant data streams from the OLE file @@ -1404,7 +1501,7 @@ private function _readDocumentSummaryInformation() private function _readDefault() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); -// $recordData = substr($this->_data, $this->_pos + 4, $length); +// $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -1419,7 +1516,7 @@ private function _readNote() { // echo 'Read Cell Annotation
'; $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -1481,7 +1578,7 @@ private function _readNote() private function _readTextObject() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -1565,22 +1662,156 @@ private function _readBof() * * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" + * + * The decryption functions and objects used from here on in + * are based on the source of Spreadsheet-ParseExcel: + * http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/ */ private function _readFilepass() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + if ($length != 54) { + throw new PHPExcel_Reader_Exception('Unexpected file pass record length'); + } + + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + // move stream pointer to next record $this->_pos += 4 + $length; + + if (!$this->_verifyPassword( + 'VelvetSweatshop', + substr($recordData, 6, 16), + substr($recordData, 22, 16), + substr($recordData, 38, 16), + $this->_md5Ctxt + )) { + throw new \Exception('Decryption password incorrect'); + } + + $this->_encryption = self::MS_BIFF_CRYPTO_RC4; - if (!$this->_readDataOnly) { - // offset: 0; size: 2; 16-bit hash value of password - $password = strtoupper(dechex(self::_GetInt2d($recordData, 0))); // the hashed password - } - throw new PHPExcel_Reader_Exception('Cannot read encrypted file'); + // Decryption required from the record after next onwards + $this->_encryptionStartPos = $this->_pos + self::_GetInt2d($this->_data, $this->_pos + 2); + } + + /** + * Make an RC4 decryptor for the given block + * + * @var int $block Block for which to create decrypto + * @var string $valContext MD5 context state + * + * @return PHPExcel_Reader_Excel5_RC4 + */ + private function _makeKey($block, $valContext) + { + $pwarray = str_repeat("\0", 64); + + for ($i = 0; $i < 5; $i++) { + $pwarray[$i] = $valContext[$i]; + } + + $pwarray[5] = chr($block & 0xff); + $pwarray[6] = chr(($block >> 8) & 0xff); + $pwarray[7] = chr(($block >> 16) & 0xff); + $pwarray[8] = chr(($block >> 24) & 0xff); + + $pwarray[9] = "\x80"; + $pwarray[56] = "\x48"; + + $md5 = new PHPExcel_Reader_Excel5_MD5(); + $md5->add($pwarray); + + $s = $md5->getContext(); + return new PHPExcel_Reader_Excel5_RC4($s); } + /** + * Verify RC4 file password + * + * @var string $password Password to check + * @var string $docid Document id + * @var string $salt_data Salt data + * @var string $hashedsalt_data Hashed salt data + * @var string &$valContext Set to the MD5 context of the value + * + * @return bool Success + */ + private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext) + { + $pwarray = str_repeat("\0", 64); + + for ($i = 0; $i < strlen($password); $i++) { + $o = ord(substr($password, $i, 1)); + $pwarray[2 * $i] = chr($o & 0xff); + $pwarray[2 * $i + 1] = chr(($o >> 8) & 0xff); + } + $pwarray[2 * $i] = chr(0x80); + $pwarray[56] = chr(($i << 4) & 0xff); + + $md5 = new PHPExcel_Reader_Excel5_MD5(); + $md5->add($pwarray); + + $mdContext1 = $md5->getContext(); + + $offset = 0; + $keyoffset = 0; + $tocopy = 5; + + $md5->reset(); + + while ($offset != 16) { + if ((64 - $offset) < 5) { + $tocopy = 64 - $offset; + } + + for ($i = 0; $i <= $tocopy; $i++) { + $pwarray[$offset + $i] = $mdContext1[$keyoffset + $i]; + } + + $offset += $tocopy; + + if ($offset == 64) { + $md5->add($pwarray); + $keyoffset = $tocopy; + $tocopy = 5 - $tocopy; + $offset = 0; + continue; + } + + $keyoffset = 0; + $tocopy = 5; + for ($i = 0; $i < 16; $i++) { + $pwarray[$offset + $i] = $docid[$i]; + } + $offset += 16; + } + + $pwarray[16] = "\x80"; + for ($i = 0; $i < 47; $i++) { + $pwarray[17 + $i] = "\0"; + } + $pwarray[56] = "\x80"; + $pwarray[57] = "\x0a"; + + $md5->add($pwarray); + $valContext = $md5->getContext(); + + $key = $this->_makeKey(0, $valContext); + + $salt = $key->RC4($salt_data); + $hashedsalt = $key->RC4($hashedsalt_data); + + $salt .= "\x80" . str_repeat("\0", 47); + $salt[56] = "\x80"; + + $md5->reset(); + $md5->add($salt); + $mdContext2 = $md5->getContext(); + + return $mdContext2 == $hashedsalt; + } /** * CODEPAGE @@ -1594,7 +1825,7 @@ private function _readFilepass() private function _readCodepage() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -1621,7 +1852,7 @@ private function _readCodepage() private function _readDateMode() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -1640,7 +1871,7 @@ private function _readDateMode() private function _readFont() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -1738,7 +1969,7 @@ private function _readFont() private function _readFormat() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -1776,7 +2007,7 @@ private function _readFormat() private function _readXf() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2062,7 +2293,7 @@ private function _readXf() private function _readXfExt() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2239,7 +2470,7 @@ private function _readXfExt() private function _readStyle() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2280,7 +2511,7 @@ private function _readStyle() private function _readPalette() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2313,14 +2544,15 @@ private function _readPalette() private function _readSheet() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // offset: 0; size: 4; absolute stream position of the BOF record of the sheet + // NOTE: not encrypted + $rec_offset = self::_GetInt4d($this->_data, $this->_pos + 4); // move stream pointer to next record $this->_pos += 4 + $length; - // offset: 0; size: 4; absolute stream position of the BOF record of the sheet - $rec_offset = self::_GetInt4d($recordData, 0); - // offset: 4; size: 1; sheet state switch (ord($recordData{4})) { case 0x00: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; @@ -2356,7 +2588,7 @@ private function _readSheet() private function _readExternalBook() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2420,7 +2652,7 @@ private function _readExternalBook() private function _readExternName() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2455,7 +2687,7 @@ private function _readExternName() private function _readExternSheet() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2492,7 +2724,7 @@ private function _readExternSheet() private function _readDefinedName() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2754,7 +2986,7 @@ private function _readSst() private function _readPrintGridlines() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2773,7 +3005,7 @@ private function _readPrintGridlines() private function _readDefaultRowHeight() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2791,7 +3023,7 @@ private function _readDefaultRowHeight() private function _readSheetPr() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2818,7 +3050,7 @@ private function _readSheetPr() private function _readHorizontalPageBreaks() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2847,7 +3079,7 @@ private function _readHorizontalPageBreaks() private function _readVerticalPageBreaks() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2875,7 +3107,7 @@ private function _readVerticalPageBreaks() private function _readHeader() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2903,7 +3135,7 @@ private function _readHeader() private function _readFooter() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2930,7 +3162,7 @@ private function _readFooter() private function _readHcenter() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2950,7 +3182,7 @@ private function _readHcenter() private function _readVcenter() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2970,7 +3202,7 @@ private function _readVcenter() private function _readLeftMargin() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -2988,7 +3220,7 @@ private function _readLeftMargin() private function _readRightMargin() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3006,7 +3238,7 @@ private function _readRightMargin() private function _readTopMargin() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3024,7 +3256,7 @@ private function _readTopMargin() private function _readBottomMargin() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3042,7 +3274,7 @@ private function _readBottomMargin() private function _readPageSetup() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3100,7 +3332,7 @@ private function _readPageSetup() private function _readProtect() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3123,7 +3355,7 @@ private function _readProtect() private function _readScenProtect() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3147,7 +3379,7 @@ private function _readScenProtect() private function _readObjectProtect() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3171,7 +3403,7 @@ private function _readObjectProtect() private function _readPassword() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3190,7 +3422,7 @@ private function _readPassword() private function _readDefColWidth() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3209,7 +3441,7 @@ private function _readDefColWidth() private function _readColInfo() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3268,7 +3500,7 @@ private function _readColInfo() private function _readRow() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3338,7 +3570,7 @@ private function _readRow() private function _readRk() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3383,7 +3615,7 @@ private function _readRk() private function _readLabelSst() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3461,7 +3693,7 @@ private function _readLabelSst() private function _readMulRk() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3516,7 +3748,7 @@ private function _readMulRk() private function _readNumber() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3558,7 +3790,7 @@ private function _readNumber() private function _readFormula() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3699,7 +3931,7 @@ private function _readFormula() private function _readSharedFmla() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3732,7 +3964,7 @@ private function _readSharedFmla() private function _readString() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3760,7 +3992,7 @@ private function _readString() private function _readBoolErr() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3819,7 +4051,7 @@ private function _readBoolErr() private function _readMulBlank() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3861,7 +4093,7 @@ private function _readMulBlank() private function _readLabel() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3904,7 +4136,7 @@ private function _readLabel() private function _readBlank() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3951,7 +4183,7 @@ private function _readMsoDrawing() private function _readObj() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -3996,7 +4228,7 @@ private function _readObj() private function _readWindow2() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -4063,7 +4295,7 @@ private function _readWindow2() */ private function _readPageLayoutView(){ $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -4102,7 +4334,7 @@ private function _readPageLayoutView(){ private function _readScl() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -4124,7 +4356,7 @@ private function _readScl() private function _readPane() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -4152,7 +4384,7 @@ private function _readPane() private function _readSelection() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -4229,7 +4461,7 @@ private function _includeCellRangeFiltered($cellRangeAddress) private function _readMergedCells() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -4252,7 +4484,7 @@ private function _readMergedCells() private function _readHyperLink() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer forward to next record $this->_pos += 4 + $length; @@ -4428,7 +4660,7 @@ private function _readHyperLink() private function _readDataValidations() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer forward to next record $this->_pos += 4 + $length; @@ -4441,7 +4673,7 @@ private function _readDataValidations() private function _readDataValidation() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer forward to next record $this->_pos += 4 + $length; @@ -4601,7 +4833,7 @@ private function _readDataValidation() private function _readSheetLayout() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -4641,7 +4873,7 @@ private function _readSheetLayout() private function _readSheetProtection() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -4742,7 +4974,7 @@ private function _readSheetProtection() private function _readRangeProtection() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // move stream pointer to next record $this->_pos += 4 + $length; @@ -4886,7 +5118,7 @@ private function _readImData() private function _readContinue() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); // check if we are reading drawing data // this is in case a free CONTINUE record occurs in other circumstances we are unaware of @@ -4951,7 +5183,7 @@ private function _getSplicedRecordData() $identifier = self::_GetInt2d($this->_data, $this->_pos); // offset: 2; size: 2; length $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $data .= substr($this->_data, $this->_pos + 4, $length); + $data .= $this->_readRecordData($this->_data, $this->_pos + 4, $length); $spliceOffsets[$i] = $spliceOffsets[$i - 1] + $length; diff --git a/Classes/PHPExcel/Reader/Excel5/MD5.php b/Classes/PHPExcel/Reader/Excel5/MD5.php new file mode 100644 index 000000000..62e05156b --- /dev/null +++ b/Classes/PHPExcel/Reader/Excel5/MD5.php @@ -0,0 +1,229 @@ +reset(); + } + + /** + * Reset the MD5 stream context + */ + public function reset() + { + $this->a = 0x67452301; + $this->b = 0xEFCDAB89; + $this->c = 0x98BADCFE; + $this->d = 0x10325476; + } + + /** + * Get MD5 stream context + * + * @return string + */ + public function getContext() + { + $s = ''; + foreach (array('a', 'b', 'c', 'd') as $i) { + $v = $this->{$i}; + $s .= chr($v & 0xff); + $s .= chr(($v >> 8) & 0xff); + $s .= chr(($v >> 16) & 0xff); + $s .= chr(($v >> 24) & 0xff); + } + + return $s; + } + + /** + * Add data to context + * + * @param string $data Data to add + */ + public function add($data) + { + $words = array_values(unpack('V16', $data)); + + $A = $this->a; + $B = $this->b; + $C = $this->c; + $D = $this->d; + + /* ROUND 1 */ + self::FF($A, $B, $C, $D, $words[0], 7, 0xd76aa478); + self::FF($D, $A, $B, $C, $words[1], 12, 0xe8c7b756); + self::FF($C, $D, $A, $B, $words[2], 17, 0x242070db); + self::FF($B, $C, $D, $A, $words[3], 22, 0xc1bdceee); + self::FF($A, $B, $C, $D, $words[4], 7, 0xf57c0faf); + self::FF($D, $A, $B, $C, $words[5], 12, 0x4787c62a); + self::FF($C, $D, $A, $B, $words[6], 17, 0xa8304613); + self::FF($B, $C, $D, $A, $words[7], 22, 0xfd469501); + self::FF($A, $B, $C, $D, $words[8], 7, 0x698098d8); + self::FF($D, $A, $B, $C, $words[9], 12, 0x8b44f7af); + self::FF($C, $D, $A, $B, $words[10], 17, 0xffff5bb1); + self::FF($B, $C, $D, $A, $words[11], 22, 0x895cd7be); + self::FF($A, $B, $C, $D, $words[12], 7, 0x6b901122); + self::FF($D, $A, $B, $C, $words[13], 12, 0xfd987193); + self::FF($C, $D, $A, $B, $words[14], 17, 0xa679438e); + self::FF($B, $C, $D, $A, $words[15], 22, 0x49b40821); + + /* ROUND 2 */ + self::GG($A, $B, $C, $D, $words[1], 5, 0xf61e2562); + self::GG($D, $A, $B, $C, $words[6], 9, 0xc040b340); + self::GG($C, $D, $A, $B, $words[11], 14, 0x265e5a51); + self::GG($B, $C, $D, $A, $words[0], 20, 0xe9b6c7aa); + self::GG($A, $B, $C, $D, $words[5], 5, 0xd62f105d); + self::GG($D, $A, $B, $C, $words[10], 9, 0x02441453); + self::GG($C, $D, $A, $B, $words[15], 14, 0xd8a1e681); + self::GG($B, $C, $D, $A, $words[4], 20, 0xe7d3fbc8); + self::GG($A, $B, $C, $D, $words[9], 5, 0x21e1cde6); + self::GG($D, $A, $B, $C, $words[14], 9, 0xc33707d6); + self::GG($C, $D, $A, $B, $words[3], 14, 0xf4d50d87); + self::GG($B, $C, $D, $A, $words[8], 20, 0x455a14ed); + self::GG($A, $B, $C, $D, $words[13], 5, 0xa9e3e905); + self::GG($D, $A, $B, $C, $words[2], 9, 0xfcefa3f8); + self::GG($C, $D, $A, $B, $words[7], 14, 0x676f02d9); + self::GG($B, $C, $D, $A, $words[12], 20, 0x8d2a4c8a); + + /* ROUND 3 */ + self::HH($A, $B, $C, $D, $words[5], 4, 0xfffa3942); + self::HH($D, $A, $B, $C, $words[8], 11, 0x8771f681); + self::HH($C, $D, $A, $B, $words[11], 16, 0x6d9d6122); + self::HH($B, $C, $D, $A, $words[14], 23, 0xfde5380c); + self::HH($A, $B, $C, $D, $words[1], 4, 0xa4beea44); + self::HH($D, $A, $B, $C, $words[4], 11, 0x4bdecfa9); + self::HH($C, $D, $A, $B, $words[7], 16, 0xf6bb4b60); + self::HH($B, $C, $D, $A, $words[10], 23, 0xbebfbc70); + self::HH($A, $B, $C, $D, $words[13], 4, 0x289b7ec6); + self::HH($D, $A, $B, $C, $words[0], 11, 0xeaa127fa); + self::HH($C, $D, $A, $B, $words[3], 16, 0xd4ef3085); + self::HH($B, $C, $D, $A, $words[6], 23, 0x04881d05); + self::HH($A, $B, $C, $D, $words[9], 4, 0xd9d4d039); + self::HH($D, $A, $B, $C, $words[12], 11, 0xe6db99e5); + self::HH($C, $D, $A, $B, $words[15], 16, 0x1fa27cf8); + self::HH($B, $C, $D, $A, $words[2], 23, 0xc4ac5665); + + /* ROUND 4 */ + self::II($A, $B, $C, $D, $words[0], 6, 0xf4292244); + self::II($D, $A, $B, $C, $words[7], 10, 0x432aff97); + self::II($C, $D, $A, $B, $words[14], 15, 0xab9423a7); + self::II($B, $C, $D, $A, $words[5], 21, 0xfc93a039); + self::II($A, $B, $C, $D, $words[12], 6, 0x655b59c3); + self::II($D, $A, $B, $C, $words[3], 10, 0x8f0ccc92); + self::II($C, $D, $A, $B, $words[10], 15, 0xffeff47d); + self::II($B, $C, $D, $A, $words[1], 21, 0x85845dd1); + self::II($A, $B, $C, $D, $words[8], 6, 0x6fa87e4f); + self::II($D, $A, $B, $C, $words[15], 10, 0xfe2ce6e0); + self::II($C, $D, $A, $B, $words[6], 15, 0xa3014314); + self::II($B, $C, $D, $A, $words[13], 21, 0x4e0811a1); + self::II($A, $B, $C, $D, $words[4], 6, 0xf7537e82); + self::II($D, $A, $B, $C, $words[11], 10, 0xbd3af235); + self::II($C, $D, $A, $B, $words[2], 15, 0x2ad7d2bb); + self::II($B, $C, $D, $A, $words[9], 21, 0xeb86d391); + + $this->a = ($this->a + $A) & 0xffffffff; + $this->b = ($this->b + $B) & 0xffffffff; + $this->c = ($this->c + $C) & 0xffffffff; + $this->d = ($this->d + $D) & 0xffffffff; + } + + private static function F($X, $Y, $Z) + { + $calc = (($X & $Y) | ((~ $X) & $Z)); // X AND Y OR NOT X AND Z + return $calc; + } + + private static function G($X, $Y, $Z) + { + $calc = (($X & $Z) | ($Y & (~ $Z))); // X AND Z OR Y AND NOT Z + return $calc; + } + + private static function H($X, $Y, $Z) + { + $calc = ($X ^ $Y ^ $Z); // X XOR Y XOR Z + return $calc; + } + + private static function I($X, $Y, $Z) + { + $calc = ($Y ^ ($X | (~ $Z))) ; // Y XOR (X OR NOT Z) + return $calc; + } + + private static function FF(&$A, $B, $C, $D, $M, $s, $t) + { + $A = ($A + self::F($B, $C, $D) + $M + $t) & 0xffffffff; + $A = self::rotate($A, $s); + $A = ($B + $A) & 0xffffffff; + } + + private static function GG(&$A, $B, $C, $D, $M, $s, $t) + { + $A = ($A + self::G($B, $C, $D) + $M + $t) & 0xffffffff; + $A = self::rotate($A, $s); + $A = ($B + $A) & 0xffffffff; + } + + private static function HH(&$A, $B, $C, $D, $M, $s, $t) + { + $A = ($A + self::H($B, $C, $D) + $M + $t) & 0xffffffff; + $A = self::rotate($A, $s); + $A = ($B + $A) & 0xffffffff; + } + + private static function II(&$A, $B, $C, $D, $M, $s, $t) + { + $A = ($A + self::I($B, $C, $D) + $M + $t) & 0xffffffff; + $A = self::rotate($A, $s); + $A = ($B + $A) & 0xffffffff; + } + + private static function rotate ($decimal, $bits) + { + return (($decimal << $bits) | ($decimal >> (32 - $bits))) & 0xffffffff; + } +} diff --git a/Classes/PHPExcel/Reader/Excel5/RC4.php b/Classes/PHPExcel/Reader/Excel5/RC4.php new file mode 100644 index 000000000..492e1b47b --- /dev/null +++ b/Classes/PHPExcel/Reader/Excel5/RC4.php @@ -0,0 +1,88 @@ +i = 0; $this->i < 256; $this->i++) { + $this->s[$this->i] = $this->i; + } + + $this->j = 0; + for ($this->i = 0; $this->i < 256; $this->i++) { + $this->j = ($this->j + $this->s[$this->i] + ord($key[$this->i % $len])) % 256; + $t = $this->s[$this->i]; + $this->s[$this->i] = $this->s[$this->j]; + $this->s[$this->j] = $t; + } + $this->i = $this->j = 0; + } + + /** + * Symmetric decryption/encryption function + * + * @param string $data Data to encrypt/decrypt + * + * @return string + */ + public function RC4($data) + { + $len = strlen($data); + for ($c = 0; $c < $len; $c++) { + $this->i = ($this->i + 1) % 256; + $this->j = ($this->j + $this->s[$this->i]) % 256; + $t = $this->s[$this->i]; + $this->s[$this->i] = $this->s[$this->j]; + $this->s[$this->j] = $t; + + $t = ($this->s[$this->i] + $this->s[$this->j]) % 256; + + $data[$c] = chr(ord($data[$c]) ^ $this->s[$t]); + } + return $data; + } +} From 6fd27196f03613e2d10c0ff74fb5155c03b4f051 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 30 Oct 2013 13:50:40 +0000 Subject: [PATCH 135/467] Bugfix: (tavoarcila) Work Item GH-259 - Bug fix reading Open Office files --- Classes/PHPExcel/Reader/OOCalc.php | 2 +- changelog.txt | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index aa296098f..8343e3772 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -572,7 +572,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; $dataValue = (float) $cellDataOfficeAttributes['value']; if (floor($dataValue) == $dataValue) { - if ($dataValue = (integer) $dataValue) + if ($dataValue == (integer) $dataValue) $dataValue = (integer) $dataValue; else $dataValue = (float) $dataValue; diff --git a/changelog.txt b/changelog.txt index 3eca4dc13..ca6a42e08 100644 --- a/changelog.txt +++ b/changelog.txt @@ -24,19 +24,19 @@ Fixed in develop branch for release v1.8.0: -- Bugfix: (MBaker) Work item 19830 - Undefined variable: fileHandle in CSV Reader -- Bugfix: (MBaker) Work item 19968 - Out of memory in style/supervisor.php -- Bugfix: (MBaker) - Style error with merged cells in PDF Writer -- Bugfix: (MBaker) - Problem with cloning worksheets -- Feature: (amerov) - Implementation of the Excel HLOOKUP() function -- Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) -- Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer -- General: (cdhutch) Work item 20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed -- General: (MBaker) - Improve stock chart handling and rendering, with help from Swashata Ghosh -- General: (MBaker) - Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load - if it's actually required -- General: (MBaker) - Modified Excel2007 Writer to default preCalculateFormulas to false - Note that autosize columns will still recalculate affected formulae internally +- Bugfix: (MBaker) Work item 19830 - Undefined variable: fileHandle in CSV Reader +- Bugfix: (MBaker) Work item 19968 - Out of memory in style/supervisor.php +- Bugfix: (MBaker) - Style error with merged cells in PDF Writer +- Bugfix: (MBaker) - Problem with cloning worksheets +- Bugfix: (tavoarcila) Work Item GH-259 - Bug fix reading Open Office files +- Feature: (amerov) - Implementation of the Excel HLOOKUP() function +- Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) +- Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer +- General: (cdhutch) Work item 20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed +- General: (MBaker) - Improve stock chart handling and rendering, with help from Swashata Ghosh +- General: (MBaker) - Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load if it's actually required +- General: (MBaker) - Modified Excel2007 Writer to default preCalculateFormulas to false + Note that autosize columns will still recalculate affected formulae internally Fixed in develop branch for release v1.7.9: From f9f37f566ac7f1948aff42a60613dac6fe475b51 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 3 Nov 2013 22:46:11 +0000 Subject: [PATCH 136/467] Feature: (trvrnrth) - Add support for reading protected (RC4 encrypted) .xls files (64-bit Linux only) --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index ca6a42e08..17242b7fb 100644 --- a/changelog.txt +++ b/changelog.txt @@ -32,6 +32,7 @@ Fixed in develop branch for release v1.8.0: - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer +- Feature: (trvrnrth) - Add support for reading protected (RC4 encrypted) .xls files (64-bit Linux only) - General: (cdhutch) Work item 20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed - General: (MBaker) - Improve stock chart handling and rendering, with help from Swashata Ghosh - General: (MBaker) - Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load if it's actually required From ded0f6dc13128deebb1caabaa87a5e3cee14ac16 Mon Sep 17 00:00:00 2001 From: Roman Syroeshko Date: Sun, 3 Nov 2013 21:24:10 -0800 Subject: [PATCH 137/467] https://github.com/PHPOffice/PHPExcel/issues/258 CHOOSE() returns "#VALUE!" if the 1st entry is chosen --- Classes/PHPExcel/Calculation/LookupRef.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index 96c7da20a..fc9fdbab9 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -462,7 +462,7 @@ public static function CHOOSE() { return PHPExcel_Calculation_Functions::VALUE(); } $chosenEntry = floor($chosenEntry); - if (($chosenEntry <= 0) || ($chosenEntry > $entryCount)) { + if (($chosenEntry < 0) || ($chosenEntry > $entryCount)) { return PHPExcel_Calculation_Functions::VALUE(); } From 94a1a693730eceefeab147c112e56a4bf8ef1828 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 7 Nov 2013 23:14:39 +0000 Subject: [PATCH 138/467] Bugfix: Work item 20397 - Serious bug in absolute cell reference used in shared formula Would also have affected insert/delete column/row --- Classes/PHPExcel/Reader/Excel2007.php | 28 +++++++++++++-------------- Classes/PHPExcel/ReferenceHelper.php | 9 ++++----- changelog.txt | 2 ++ 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index d197efff9..7ae0a992a 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -262,36 +262,34 @@ private static function _castToString($c) { private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) { -// echo 'Formula
'; -// echo '$c->f is '.$c->f.'
'; +// echo 'Formula',PHP_EOL; +// echo '$c->f is '.$c->f.PHP_EOL; $cellDataType = 'f'; $value = "={$c->f}"; $calculatedValue = self::$castBaseType($c); // Shared formula? if (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') { -// echo 'SHARED FORMULA
'; +// echo 'SHARED FORMULA'.PHP_EOL; $instance = (string)$c->f['si']; -// echo 'Instance ID = '.$instance.'
'; +// echo 'Instance ID = '.$instance.PHP_EOL; // -// echo 'Shared Formula Array:
';
+//			echo 'Shared Formula Array:'.PHP_EOL;
 //			print_r($sharedFormulas);
-//			echo '
'; if (!isset($sharedFormulas[(string)$c->f['si']])) { -// echo 'SETTING NEW SHARED FORMULA
'; -// echo 'Master is '.$r.'
'; -// echo 'Formula is '.$value.'
'; +// echo 'SETTING NEW SHARED FORMULA'.PHP_EOL; +// echo 'Master is '.$r.PHP_EOL; +// echo 'Formula is '.$value.PHP_EOL; $sharedFormulas[$instance] = array( 'master' => $r, 'formula' => $value ); -// echo 'New Shared Formula Array:
';
+//				echo 'New Shared Formula Array:'.PHP_EOL;
 //				print_r($sharedFormulas);
-//				echo '
'; } else { -// echo 'GETTING SHARED FORMULA
'; -// echo 'Master is '.$sharedFormulas[$instance]['master'].'
'; -// echo 'Formula is '.$sharedFormulas[$instance]['formula'].'
'; +// echo 'GETTING SHARED FORMULA'.PHP_EOL; +// echo 'Master is '.$sharedFormulas[$instance]['master'].PHP_EOL; +// echo 'Formula is '.$sharedFormulas[$instance]['formula'].PHP_EOL; $master = PHPExcel_Cell::coordinateFromString($sharedFormulas[$instance]['master']); $current = PHPExcel_Cell::coordinateFromString($r); @@ -304,7 +302,7 @@ private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,& $difference[0], $difference[1] ); -// echo 'Adjusted Formula is '.$value.'
'; +// echo 'Adjusted Formula is '.$value.PHP_EOL; } } } diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index f7d137094..ff3ed2c4e 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -702,7 +702,7 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo $cellIndex = $column.$row; $newCellTokens[$cellIndex] = preg_quote($toString); - $cellTokens[$cellIndex] = '/(? '') ? $match[2].'!' : ''; $fromString .= $match[3]; - $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); + $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); if ($match[3] !== $modified3) { if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { $toString = ($match[2] > '') ? $match[2].'!' : ''; @@ -753,7 +753,7 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo $cellIndex = $column.$row; $newCellTokens[$cellIndex] = preg_quote($toString); - $cellTokens[$cellIndex] = '/(?= PHPExcel_Cell::columnIndexFromString($beforeColumn)); - $updateRow = (($newRow{0} != '$') && ($beforeRow{0} != '$') && $newRow >= $beforeRow); diff --git a/changelog.txt b/changelog.txt index 17242b7fb..858749538 100644 --- a/changelog.txt +++ b/changelog.txt @@ -29,6 +29,8 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (MBaker) - Style error with merged cells in PDF Writer - Bugfix: (MBaker) - Problem with cloning worksheets - Bugfix: (tavoarcila) Work Item GH-259 - Bug fix reading Open Office files +- Bugfix: (MBaker) Work item 20397 - Serious bug in absolute cell reference used in shared formula + Would also have affected insert/delete column/row - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From 2bd1c10b2154773d295e75add034bddce5afb2b3 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 7 Nov 2013 23:24:04 +0000 Subject: [PATCH 139/467] Further fix to regexp for preventing update of absolute rows when adjusting row references --- Classes/PHPExcel/ReferenceHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index ff3ed2c4e..550b7f3f0 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -677,7 +677,7 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo $cellIndex = $column.$row; $newCellTokens[$cellIndex] = preg_quote($toString); - $cellTokens[$cellIndex] = '/(? Date: Fri, 8 Nov 2013 19:47:13 +0000 Subject: [PATCH 140/467] Bugfix: (RomanSyroeshko) Work Item GH-267 - CHOOSE() returns "#VALUE!" if the 1st entry is chosen --- changelog.txt | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/changelog.txt b/changelog.txt index 858749538..471a8cda6 100644 --- a/changelog.txt +++ b/changelog.txt @@ -24,22 +24,23 @@ Fixed in develop branch for release v1.8.0: -- Bugfix: (MBaker) Work item 19830 - Undefined variable: fileHandle in CSV Reader -- Bugfix: (MBaker) Work item 19968 - Out of memory in style/supervisor.php -- Bugfix: (MBaker) - Style error with merged cells in PDF Writer -- Bugfix: (MBaker) - Problem with cloning worksheets -- Bugfix: (tavoarcila) Work Item GH-259 - Bug fix reading Open Office files -- Bugfix: (MBaker) Work item 20397 - Serious bug in absolute cell reference used in shared formula - Would also have affected insert/delete column/row -- Feature: (amerov) - Implementation of the Excel HLOOKUP() function -- Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) -- Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer -- Feature: (trvrnrth) - Add support for reading protected (RC4 encrypted) .xls files (64-bit Linux only) -- General: (cdhutch) Work item 20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed -- General: (MBaker) - Improve stock chart handling and rendering, with help from Swashata Ghosh -- General: (MBaker) - Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load if it's actually required -- General: (MBaker) - Modified Excel2007 Writer to default preCalculateFormulas to false - Note that autosize columns will still recalculate affected formulae internally +- Bugfix: (MBaker) Work item 19830 - Undefined variable: fileHandle in CSV Reader +- Bugfix: (MBaker) Work item 19968 - Out of memory in style/supervisor.php +- Bugfix: (MBaker) - Style error with merged cells in PDF Writer +- Bugfix: (MBaker) - Problem with cloning worksheets +- Bugfix: (tavoarcila) Work Item GH-259 - Bug fix reading Open Office files +- Bugfix: (MBaker) Work item 20397 - Serious bug in absolute cell reference used in shared formula + Would also have affected insert/delete column/row +- Bugfix: (RomanSyroeshko) Work Item GH-267 - CHOOSE() returns "#VALUE!" if the 1st entry is chosen +- Feature: (amerov) - Implementation of the Excel HLOOKUP() function +- Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) +- Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer +- Feature: (trvrnrth) - Add support for reading protected (RC4 encrypted) .xls files (64-bit Linux only) +- General: (cdhutch) Work item 20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed +- General: (MBaker) - Improve stock chart handling and rendering, with help from Swashata Ghosh +- General: (MBaker) - Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load if it's actually required +- General: (MBaker) - Modified Excel2007 Writer to default preCalculateFormulas to false + Note that autosize columns will still recalculate affected formulae internally Fixed in develop branch for release v1.7.9: From 13a98ef631b3d2d4c1a251477c56885f58e3ab9b Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 9 Nov 2013 00:40:59 +0000 Subject: [PATCH 141/467] General: (dresenhista) Work Item GH-242 - Functionality to getHighestRow() for a specified column, and getHighestColumn() for a specified row --- .../CachedObjectStorage/CacheBase.php | 47 +++++++++++++++---- changelog.txt | 1 + 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index b04f44a48..81afb7acd 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -254,23 +254,52 @@ public function getCurrentRow() /** * Get highest worksheet column * - * @return string Highest column name + * @param string $row Return the highest column for the specified row, + * or the highest column of any row if no row number is passed + * @return string Highest column name */ - public function getHighestColumn() + public function getHighestColumn($row = null) { - $colRow = $this->getHighestRowAndColumn(); - return $colRow['column']; - } + if ($row == null) { + $colRow = $this->getHighestRowAndColumn(); + return $colRow['column']; + } + + $columnList = array(1); + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $c, $r); + if ($r != $row) { + continue; + } + $columnList[] = PHPExcel_Cell::columnIndexFromString($c); + } + return PHPExcel_Cell::stringFromColumnIndex(max($columnList) - 1); + } /** * Get highest worksheet row * - * @return int Highest row number + * @param string $column Return the highest row for the specified column, + * or the highest row of any column if no column letter is passed + * @return int Highest row number */ - public function getHighestRow() + public function getHighestRow($column = null) { - $colRow = $this->getHighestRowAndColumn(); - return $colRow['row']; + if ($column == null) { + $colRow = $this->getHighestRowAndColumn(); + return $colRow['row']; + } + + $rowList = array(0); + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $c, $r); + if ($c != $column) { + continue; + } + $rowList[] = $r; + } + + return max($rowList); } diff --git a/changelog.txt b/changelog.txt index 471a8cda6..7c322733e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -41,6 +41,7 @@ Fixed in develop branch for release v1.8.0: - General: (MBaker) - Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load if it's actually required - General: (MBaker) - Modified Excel2007 Writer to default preCalculateFormulas to false Note that autosize columns will still recalculate affected formulae internally +- General: (dresenhista) Work Item GH-242 - Functionality to getHighestRow() for a specified column, and getHighestColumn() for a specified row Fixed in develop branch for release v1.7.9: From 74f8efc1f8a51943abeab9272c8cbbdd077c5646 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 9 Nov 2013 10:21:54 +0000 Subject: [PATCH 142/467] Modified getHighest calls for row/column at Worksheet level to accept optional column/row arguments --- Classes/PHPExcel/Worksheet.php | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index a701f3ab6..c3d53647a 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -982,41 +982,55 @@ public function setProtection(PHPExcel_Worksheet_Protection $pValue) /** * Get highest worksheet column * + * @param string $row Return the data highest column for the specified row, + * or the highest column of any row if no row number is passed * @return string Highest column name */ - public function getHighestColumn() + public function getHighestColumn($row = null) { - return $this->_cachedHighestColumn; + if ($row == null) { + return $this->_cachedHighestColumn; + } + return $this->getHighestDataColumn($row); } /** * Get highest worksheet column that contains data * + * @param string $row Return the highest data column for the specified row, + * or the highest data column of any row if no row number is passed * @return string Highest column name that contains data */ - public function getHighestDataColumn() + public function getHighestDataColumn($row = null) { - return $this->_cellCollection->getHighestColumn(); + return $this->_cellCollection->getHighestColumn($row); } /** * Get highest worksheet row * + * @param string $column Return the highest data row for the specified column, + * or the highest row of any column if no column letter is passed * @return int Highest row number */ - public function getHighestRow() + public function getHighestRow($column = null) { - return $this->_cachedHighestRow; + if ($column == null) { + return $this->_cachedHighestRow; + } + return $this->getHighestDataRow($column); } /** * Get highest worksheet row that contains data * + * @param string $column Return the highest data row for the specified column, + * or the highest data row of any column if no column letter is passed * @return string Highest row number that contains data */ - public function getHighestDataRow() + public function getHighestDataRow($column = null) { - return $this->_cellCollection->getHighestRow(); + return $this->_cellCollection->getHighestRow($column); } /** From df592cc7c46249e3cda8ee92a3bea33c67535222 Mon Sep 17 00:00:00 2001 From: Gemorroj Date: Fri, 15 Nov 2013 12:29:21 +0300 Subject: [PATCH 143/467] When duplicating styles, styles shifted by one column to the right. PHPExcel_Cell::rangeBoundaries -> PHPExcel_Cell::columnIndexFromString (Column index (base 1 !!!)) PHPExcel_Cell::stringFromColumnIndex Column index (base 0 !!!) --- Classes/PHPExcel/Worksheet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index c3d53647a..493b462ba 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1512,7 +1512,7 @@ public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') // Loop through cells and apply styles for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { - $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col) . $row)->setXfIndex($xfIndex); + $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col - 1) . $row)->setXfIndex($xfIndex); } } From 1a85271db61325175d8cfc81f5170d8ed3a6787f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 15 Nov 2013 19:11:08 +0000 Subject: [PATCH 144/467] Bugfix: (Gemorroj) Work Item GH-268 - When duplicating styles, styles shifted by one column to the right --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 7c322733e..1e943d028 100644 --- a/changelog.txt +++ b/changelog.txt @@ -32,6 +32,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (MBaker) Work item 20397 - Serious bug in absolute cell reference used in shared formula Would also have affected insert/delete column/row - Bugfix: (RomanSyroeshko) Work Item GH-267 - CHOOSE() returns "#VALUE!" if the 1st entry is chosen +- Bugfix: (Gemorroj) Work Item GH-268 - When duplicating styles, styles shifted by one column to the right - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From 968bfef0a26b0b83cebd742eeaaea514d2be4b60 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 15 Nov 2013 19:24:51 +0000 Subject: [PATCH 145/467] Bugfix: When duplicating conditional styles, styles shifted by one column to the right --- Classes/PHPExcel/Worksheet.php | 2 +- changelog.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 493b462ba..24b5e3e8f 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1550,7 +1550,7 @@ public function duplicateConditionalStyle(array $pCellStyle = null, $pRange = '' // Loop through cells and apply styles for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { - $this->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($col) . $row, $pCellStyle); + $this->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($col - 1) . $row, $pCellStyle); } } diff --git a/changelog.txt b/changelog.txt index 1e943d028..2f5bb06ba 100644 --- a/changelog.txt +++ b/changelog.txt @@ -33,6 +33,7 @@ Fixed in develop branch for release v1.8.0: Would also have affected insert/delete column/row - Bugfix: (RomanSyroeshko) Work Item GH-267 - CHOOSE() returns "#VALUE!" if the 1st entry is chosen - Bugfix: (Gemorroj) Work Item GH-268 - When duplicating styles, styles shifted by one column to the right + Fix also applied to duplicating conditional styles - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From fe840150778f76a9d8b37f0843942de49bf0a17e Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 16 Nov 2013 10:38:30 +0000 Subject: [PATCH 146/467] On the chance that a cell doesn't have a defined style but it's still trying to be formatted --- Classes/PHPExcel/Worksheet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 24b5e3e8f..9d7a50071 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -2426,7 +2426,7 @@ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormul $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString( $returnValue[$rRef][$cRef], - ($style->getNumberFormat()) ? + ($style && $style->getNumberFormat()) ? $style->getNumberFormat()->getFormatCode() : PHPExcel_Style_NumberFormat::FORMAT_GENERAL ); From 732cb11e0cd987574e597d9b04def0ff02c3bf03 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 17 Nov 2013 00:11:45 +0000 Subject: [PATCH 147/467] Feature: (LWol) Work Item GH-252 - Adding support for macros, Ribbon in Excel 2007 --- Classes/PHPExcel.php | 253 +++++++++++++++++- Classes/PHPExcel/Reader/Excel2007.php | 71 ++++- Classes/PHPExcel/Worksheet.php | 102 +++++++ Classes/PHPExcel/Writer/Excel2007.php | 31 +++ .../Writer/Excel2007/ContentTypes.php | 34 ++- Classes/PHPExcel/Writer/Excel2007/Rels.php | 20 ++ .../PHPExcel/Writer/Excel2007/RelsRibbon.php | 77 ++++++ Classes/PHPExcel/Writer/Excel2007/RelsVBA.php | 72 +++++ .../PHPExcel/Writer/Excel2007/Worksheet.php | 6 + changelog.txt | 1 + 10 files changed, 652 insertions(+), 15 deletions(-) create mode 100644 Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php create mode 100644 Classes/PHPExcel/Writer/Excel2007/RelsVBA.php diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index 7bd024346..c71ee5f60 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -112,18 +112,257 @@ class PHPExcel */ private $_cellStyleXfCollection = array(); - /** - * Create a new PHPExcel with one Worksheet + /** + * _hasMacros : this workbook have macros ? + * + * @var bool + */ + private $_hasMacros = FALSE; + + /** + * _macrosCode : all macros code (the vbaProject.bin file, this include form, code, etc.), NULL if no macro + * + * @var binary + */ + private $_macrosCode=NULL; + /** + * _macrosCertificate : if macros are signed, contains vbaProjectSignature.bin file, NULL if not signed + * + * @var binary + */ + private $_macrosCertificate=NULL; + + /** + * _ribbonXMLData : NULL if workbook is'nt Excel 2007 or not contain a customized UI + * + * @var NULL|string + */ + private $_ribbonXMLData=NULL; + + /** + * _ribbonBinObjects : NULL if workbook is'nt Excel 2007 or not contain embedded objects (picture(s)) for Ribbon Elements + * ignored if $_ribbonXMLData is null + * + * @var NULL|array + */ + private $_ribbonBinObjects=NULL; + + /** + * The workbook has macros ? + * + * @return true if workbook has macros, false if not + */ + public function hasMacros(){ + return $this->_hasMacros; + } + + /** + * Define if a workbook has macros + * + * @param true|false + */ + public function setHasMacros($hasMacros=false){ + $this->_hasMacros=(bool)$hasMacros; + } + + /** + * Set the macros code + * + * @param binary string|null + */ + public function setMacrosCode($MacrosCode){ + $this->_macrosCode=$MacrosCode; + $this->setHasMacros(!is_null($MacrosCode)); + } + + /** + * Return the macros code + * + * @return binary|null + */ + public function getMacrosCode(){ + return $this->_macrosCode; + } + + /** + * Set the macros certificate + * + * @param binary|null + */ + public function setMacrosCertificate($Certificate=NULL){ + $this->_macrosCertificate=$Certificate; + } + + /** + * Is the project signed ? + * + * @return true|false + */ + public function hasMacrosCertificate(){ + return !is_null($this->_macrosCertificate); + } + + /** + * Return the macros certificate + * + * @return binary|null + */ + public function getMacrosCertificate(){ + return $this->_macrosCertificate; + } + + /** + * Remove all macros, certificate from spreadsheet + * + * @param none + * @return void + */ + public function discardMacros(){ + $this->_hasMacros=false; + $this->_macrosCode=NULL; + $this->_macrosCertificate=NULL; + } + + /** + * set ribbon XML data + * + */ + public function setRibbonXMLData($Target=NULL, $XMLData=NULL){ + if(!is_null($Target) && !is_null($XMLData)){ + $this->_ribbonXMLData=array('target'=>$Target, 'data'=>$XMLData); + }else{ + $this->_ribbonXMLData=NULL; + } + } + + /** + * retrieve ribbon XML Data + * + * return string|null|array + */ + public function getRibbonXMLData($What='all'){//we need some constants here... + $ReturnData=NULL; + $What=strtolower($What); + switch($What){ + case 'all': + $ReturnData=$this->_ribbonXMLData; + break; + case 'target': + case 'data': + if(is_array($this->_ribbonXMLData) && array_key_exists($What,$this->_ribbonXMLData)){ + $ReturnData=$this->_ribbonXMLData[$What]; + }//else $ReturnData stay at null + break; + }//default: $ReturnData at null + return $ReturnData; + } + + /** + * store binaries ribbon objects (pictures) + * + */ + public function setRibbonBinObjects($BinObjectsNames=NULL, $BinObjectsData=NULL){ + if(!is_null($BinObjectsNames) && !is_null($BinObjectsData)){ + $this->_ribbonBinObjects=array('names'=>$BinObjectsNames, 'data'=>$BinObjectsData); + }else{ + $this->_ribbonBinObjects=NULL; + } + } + /** + * return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function) + * + */ + private function _getExtensionOnly($ThePath){ + return pathinfo($ThePath, PATHINFO_EXTENSION); + } + + /** + * retrieve Binaries Ribbon Objects + * + */ + public function getRibbonBinObjects($What='all'){ + $ReturnData=NULL; + $What=strtolower($What); + switch($What){ + case 'all': + return $this->_ribbonBinObjects; + break; + case 'names': + case 'data': + if(is_array($this->_ribbonBinObjects) && array_key_exists($What, $this->_ribbonBinObjects)){ + $ReturnData=$this->_ribbonBinObjects[$What]; + } + break; + case 'types': + if(is_array($this->_ribbonBinObjects) && array_key_exists('data', $this->_ribbonBinObjects) && is_array($this->_ribbonBinObjects['data'])){ + $tmpTypes=array_keys($this->_ribbonBinObjects['data']); + $ReturnData=array_unique(array_map(array($this,'_getExtensionOnly'), $tmpTypes)); + }else + $ReturnData=array();//the caller want an array... not null if empty + break; + } + return $ReturnData; + } + + /** + * This workbook have a custom UI ? + * + * @return true|false + */ + public function hasRibbon(){ + return !is_null($this->_ribbonXMLData); + } + + /** + * This workbook have additionnal object for the ribbon ? + * + * @return true|false + */ + public function hasRibbonBinObjects(){ + return !is_null($this->_ribbonBinObjects); + } + + /** + * Check if a sheet with a specified code name already exists + * + * @param string $pSheetCodeName Name of the worksheet to check + * @return boolean */ - public function __construct() + public function sheetCodeNameExists($pSheetCodeName) { + return ($this->getSheetByCodeName($pSheetCodeName) !== NULL); + } + + /** + * Get sheet by code name. Warning : sheet don't have always a code name ! + * + * @param string $pName Sheet name + * @return PHPExcel_Worksheet + */ + public function getSheetByCodeName($pName = '') + { + $worksheetCount = count($this->_workSheetCollection); + for ($i = 0; $i < $worksheetCount; ++$i) { + if ($this->_workSheetCollection[$i]->getCodeName() == $pName) { + return $this->_workSheetCollection[$i]; + } + } + + return null; + } + + /** + * Create a new PHPExcel with one Worksheet + */ + 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); - $this->_activeSheetIndex = 0; + // Initialise worksheet collection and add one worksheet + $this->_workSheetCollection = array(); + $this->_workSheetCollection[] = new PHPExcel_Worksheet($this); + $this->_activeSheetIndex = 0; // Create document properties $this->_properties = new PHPExcel_DocumentProperties(); diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 7ae0a992a..8f58279b0 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -440,7 +440,13 @@ public function load($pFilename) } } break; - + //Ribbon + case "http://schemas.microsoft.com/office/2006/relationships/ui/extensibility": + $customUI = $rel['Target']; + if(!is_null($customUI)){ + $this->_readRibbon($excel, $customUI, $zip); + } + break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": $dir = dirname($rel["Target"]); $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships"); @@ -460,12 +466,30 @@ public function load($pFilename) } $worksheets = array(); + $macros = $customUI = NULL; foreach ($relsWorkbook->Relationship as $ele) { - if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet") { + switch($ele['Type']){ + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": $worksheets[(string) $ele["Id"]] = $ele["Target"]; + break; + // a vbaProject ? (: some macros) + case "http://schemas.microsoft.com/office/2006/relationships/vbaProject": + $macros = $ele["Target"]; + break; } } + if(!is_null($macros)){ + $macrosCode = $this->_getFromZipArchive($zip, 'xl/vbaProject.bin');//vbaProject.bin always in 'xl' dir and always named vbaProject.bin + if($macrosCode !== false){ + $excel->setMacrosCode($macrosCode); + $excel->setHasMacros(true); + //short-circuit : not reading vbaProject.bin.rel to get Signature =>allways vbaProjectSignature.bin in 'xl' dir + $Certificate = $this->_getFromZipArchive($zip, 'xl/vbaProjectSignature.bin'); + if($Certificate !== false) + $excel->setMacrosCertificate($Certificate); + } + } $styles = array(); $cellStyles = array(); $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); @@ -684,7 +708,9 @@ public function load($pFilename) $docSheet->getTabColor()->setARGB( (string)$xmlSheet->sheetPr->tabColor['rgb'] ); } } - + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr['codeName'])) { + $docSheet->setCodeName((string) $xmlSheet->sheetPr['codeName']); + } if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->outlinePr)) { if (isset($xmlSheet->sheetPr->outlinePr['summaryRight']) && !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryRight'])) { @@ -1942,7 +1968,44 @@ private function _parseRichText($is = null) { return $value; } - + private function _readRibbon($excel, $customUITarget, $zip) + { + $baseDir = dirname($customUITarget); + $nameCustomUI = basename($customUITarget); + // get the xml file (ribbon) + $localRibbon = $this->_getFromZipArchive($zip, $customUITarget); + $customUIImagesNames = array(); + $customUIImagesBinaries = array(); + // something like customUI/_rels/customUI.xml.rels + $pathRels = $baseDir . '/_rels/' . $nameCustomUI . '.rels'; + $dataRels = $this->_getFromZipArchive($zip, $pathRels); + if ($dataRels) { + // exists and not empty if the ribbon have some pictures (other than internal MSO) + $UIRels = simplexml_load_string($dataRels); + if ($UIRels) { + // we need to save id and target to avoid parsing customUI.xml and "guess" if it's a pseudo callback who load the image + foreach ($UIRels->Relationship as $ele) { + if ($ele["Type"] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') { + // an image ? + $customUIImagesNames[(string) $ele['Id']] = (string)$ele['Target']; + $customUIImagesBinaries[(string)$ele['Target']] = $this->_getFromZipArchive($zip, $baseDir . '/' . (string) $ele['Target']); + } + } + } + } + if ($localRibbon) { + $excel->setRibbonXMLData($customUITarget, $localRibbon); + if (count($customUIImagesNames) > 0 && count($customUIImagesBinaries) > 0) { + $excel->setRibbonBinObjects($customUIImagesNames, $customUIImagesBinaries); + } else { + $excel->setRibbonBinObjects(NULL); + } + } else { + $excel->setRibbonXMLData(NULL); + $excel->setRibbonBinObjects(NULL); + } + } + private static function array_item($array, $key = 0) { return (isset($array[$key]) ? $array[$key] : null); } diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 9d7a50071..3fecc164d 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -326,6 +326,13 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable private $_hash = null; /** + * CodeName + * + * @var string + */ + private $_codeName = null; + + /** * Create a new worksheet * * @param PHPExcel $pParent @@ -336,6 +343,8 @@ public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') // Set parent and title $this->_parent = $pParent; $this->setTitle($pTitle, FALSE); + // setTitle can change $pTitle + $this->setCodeName($this->getTitle()); $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE); $this->_cellCollection = PHPExcel_CachedObjectStorageFactory::getInstance($this); @@ -417,6 +426,34 @@ public static function getInvalidCharacters() } /** + * Check sheet code name for valid Excel syntax + * + * @param string $pValue The string to check + * @return string The valid string + * @throws Exception + */ + private static function _checkSheetCodeName($pValue) + { + $CharCount = PHPExcel_Shared_String::CountCharacters($pValue); + if ($CharCount == 0) { + throw new PHPExcel_Exception('Sheet code name cannot be empty.'); + } + // Some of the printable ASCII characters are invalid: * : / \ ? [ ] and first and last characters cannot be a "'" + if ((str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) || + (PHPExcel_Shared_String::Substring($pValue,-1,1)=='\'') || + (PHPExcel_Shared_String::Substring($pValue,0,1)=='\'')) { + throw new PHPExcel_Exception('Invalid character found in sheet code name'); + } + + // Maximum 31 characters allowed for sheet title + if ($CharCount > 31) { + throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet code name.'); + } + + return $pValue; + } + + /** * Check sheet title for valid Excel syntax * * @param string $pValue The string to check @@ -2802,4 +2839,69 @@ public function __clone() { } } } +/** + * Define the code name of the sheet + * + * @param null|string Same rule as Title minus space not allowed (but, like Excel, change silently space to underscore) + * @return objWorksheet + * @throws PHPExcel_Exception + */ + public function setCodeName($pValue=null){ + // Is this a 'rename' or not? + if ($this->getCodeName() == $pValue) { + return $this; + } + $pValue = str_replace(' ', '_', $pValue);//Excel does this automatically without flinching, we are doing the same + // Syntax check + // throw an exception if not valid + self::_checkSheetCodeName($pValue); + + // We use the same code that setTitle to find a valid codeName else not using a space (Excel don't like) but a '_' + + if ($this->getParent()) { + // Is there already such sheet name? + if ($this->getParent()->sheetCodeNameExists($pValue)) { + // Use name, but append with lowest possible integer + + if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); + } + $i = 1; + while ($this->getParent()->sheetCodeNameExists($pValue . '_' . $i)) { + ++$i; + if ($i == 10) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); + } + } elseif ($i == 100) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); + } + } + } + + $pValue = $pValue . '_' . $i;// ok, we have a valid name + //codeName is'nt used in formula : no need to call for an update + //return $this->setTitle($altTitle,$updateFormulaCellReferences); + } + } + + $this->_codeName=$pValue; + return $this; + } + /** + * Return the code name of the sheet + * + * @return null|string + */ + public function getCodeName(){ + return $this->_codeName; + } + /** + * Sheet has a code name ? + * @return boolean + */ + public function hasCodeName(){ + return !(is_null($this->_codeName)); + } } diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index 4e93201a5..5ff98f2fd 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -144,6 +144,8 @@ public function __construct(PHPExcel $pPHPExcel = null) 'drawing' => 'PHPExcel_Writer_Excel2007_Drawing', 'comments' => 'PHPExcel_Writer_Excel2007_Comments', 'chart' => 'PHPExcel_Writer_Excel2007_Chart', + 'relsvba' => 'PHPExcel_Writer_Excel2007_RelsVBA', + 'relsribbonobjects' => 'PHPExcel_Writer_Excel2007_RelsRibbon' ); // Initialise writer parts @@ -243,6 +245,35 @@ public function save($pFilename = null) // Add [Content_Types].xml to ZIP file $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->_includeCharts)); + //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) + if($this->_spreadSheet->hasMacros()){ + $macrosCode=$this->_spreadSheet->getMacrosCode(); + if(!is_null($macrosCode)){// we have the code ? + $objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin + if($this->_spreadSheet->hasMacrosCertificate()){//signed macros ? + // Yes : add the certificate file and the related rels file + $objZip->addFromString('xl/vbaProjectSignature.bin', $this->_spreadSheet->getMacrosCertificate()); + $objZip->addFromString('xl/_rels/vbaProject.bin.rels', + $this->getWriterPart('RelsVBA')->writeVBARelationships($this->_spreadSheet)); + } + } + } + //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) + if($this->_spreadSheet->hasRibbon()){ + $tmpRibbonTarget=$this->_spreadSheet->getRibbonXMLData('target'); + $objZip->addFromString($tmpRibbonTarget, $this->_spreadSheet->getRibbonXMLData('data')); + if($this->_spreadSheet->hasRibbonBinObjects()){ + $tmpRootPath=dirname($tmpRibbonTarget).'/'; + $ribbonBinObjects=$this->_spreadSheet->getRibbonBinObjects('data');//the files to write + foreach($ribbonBinObjects as $aPath=>$aContent){ + $objZip->addFromString($tmpRootPath.$aPath, $aContent); + } + //the rels for files + $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', + $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->_spreadSheet)); + } + } + // Add relationships to ZIP file $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->_spreadSheet)); $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->_spreadSheet)); diff --git a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php index 9fdc9dd5e..b19b4cd93 100644 --- a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php +++ b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -86,9 +86,26 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = F ); // Workbook - $this->_writeOverrideContentType( - $objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml' - ); + if($pPHPExcel->hasMacros()){ //Macros in workbook ? + // Yes : not standard content but "macroEnabled" + $this->_writeOverrideContentType( + $objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml' + ); + //... and define a new type for the VBA project + $this->_writeDefaultContentType( + $objWriter, 'bin', 'application/vnd.ms-office.vbaProject' + ); + if($pPHPExcel->hasMacrosCertificate()){// signed macros ? + // Yes : add needed information + $this->_writeOverrideContentType( + $objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature' + ); + } + }else{// no macros in workbook, so standard type + $this->_writeOverrideContentType( + $objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml' + ); + } // DocProps $this->_writeOverrideContentType( @@ -178,7 +195,16 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = F ); } } - + if($pPHPExcel->hasRibbonBinObjects()){//Some additional objects in the ribbon ? + //we need to write "Extension" but not already write for media content + $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); + foreach($tabRibbonTypes as $aRibbonType){ + $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor + $this->_writeDefaultContentType( + $objWriter, $aRibbonType, $mimeType + ); + } + } $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) { diff --git a/Classes/PHPExcel/Writer/Excel2007/Rels.php b/Classes/PHPExcel/Writer/Excel2007/Rels.php index fa225eec7..87403b629 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Rels.php +++ b/Classes/PHPExcel/Writer/Excel2007/Rels.php @@ -94,6 +94,15 @@ public function writeRelationships(PHPExcel $pPHPExcel = null) 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', 'xl/workbook.xml' ); + // a custom UI in workbook ? + if($pPHPExcel->hasRibbon()){ + $this->_writeRelationShip( + $objWriter, + 5, + 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', + $pPHPExcel->getRibbonXMLData('target') + ); + } $objWriter->endElement(); @@ -159,6 +168,17 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) 'worksheets/sheet' . ($i + 1) . '.xml' ); } + // Relationships for vbaProject if needed + // id : just after the last sheet + if($pPHPExcel->hasMacros()){ + $this->_writeRelationShip( + $objWriter, + ($i + 1 + 3), + 'http://schemas.microsoft.com/office/2006/relationships/vbaProject', + 'vbaProject.bin' + ); + ++$i;//increment i if needed for an another relation + } $objWriter->endElement(); diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php new file mode 100644 index 000000000..47b75a317 --- /dev/null +++ b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php @@ -0,0 +1,77 @@ +getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + $localRels=$pPHPExcel->getRibbonBinObjects('names'); + if(is_array($localRels)){ + foreach($localRels as $aId=>$aTarget){ + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', $aId); + $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); + $objWriter->writeAttribute('Target', $aTarget); + $objWriter->endElement();//Relationship + } + } + $objWriter->endElement();//Relationships + + // Return + return $objWriter->getData(); + + } + +} diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php new file mode 100644 index 000000000..60833e10e --- /dev/null +++ b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php @@ -0,0 +1,72 @@ +getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', 'rId1'); + $objWriter->writeAttribute('Type', 'http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature'); + $objWriter->writeAttribute('Target', 'vbaProjectSignature.bin'); + $objWriter->endElement();//Relationship + $objWriter->endElement();//Relationships + + // Return + return $objWriter->getData(); + + } + +} diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index f70d4fe74..8ca33aa4f 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -148,6 +148,12 @@ private function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPE // sheetPr $objWriter->startElement('sheetPr'); //$objWriter->writeAttribute('codeName', $pSheet->getTitle()); + if($pSheet->getParent()->hasMacros()){//if the workbook have macros, we need to have codeName for the sheet + if($pSheet->hasCodeName()==false){ + $pSheet->setCodeName($pSheet->getTitle()); + } + $objWriter->writeAttribute('codeName', $pSheet->getCodeName()); + } $autoFilterRange = $pSheet->getAutoFilter()->getRange(); if (!empty($autoFilterRange)) { $objWriter->writeAttribute('filterMode', 1); diff --git a/changelog.txt b/changelog.txt index 2f5bb06ba..deeb03b3e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -38,6 +38,7 @@ Fixed in develop branch for release v1.8.0: - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer - Feature: (trvrnrth) - Add support for reading protected (RC4 encrypted) .xls files (64-bit Linux only) +- Feature: (LWol) Work Item GH-252 - Adding support for macros, Ribbon in Excel 2007 - General: (cdhutch) Work item 20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed - General: (MBaker) - Improve stock chart handling and rendering, with help from Swashata Ghosh - General: (MBaker) - Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load if it's actually required From 51a1661c7988ad93dd5f4197205a31a5d0396a6a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 17 Nov 2013 13:09:11 +0000 Subject: [PATCH 148/467] Feature: (adamriyadi) GH-247 - Add locateName() and getFromName() to PHPExcel_Shared_ZipArchive --- Classes/PHPExcel/Shared/ZipArchive.php | 62 ++++++++++++++++++++++++++ Examples/runall.php | 1 + 2 files changed, 63 insertions(+) diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index 50e2240f5..195cd6ba8 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -111,4 +111,66 @@ public function addFromString($localname, $contents) unlink($this->_tempDir.'/'.$filenameParts["basename"]); } + /** + * Find if given fileName exist in archive (Emulate ZipArchive locateName()) + * author Adam (adam.riyadi@gmail.com) + * + * @param string $fileName Filename for the file in zip archive + * @return boolean + */ + public function locateName($name) + { + $list = $this->_zip->listContent(); + $listCount = count($list); + $list_index = -1; + for ($i = 0; $i < $listCount; $i++) { + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || + strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { + $list_index = $i; + break; + } + } + return ($list_index > -1); + } + + /** + * Extract file from archive by given fileName (Emulate ZipArchive getFromName()) + * author Adam (adam.riyadi@gmail.com) + * + * @param string $fileName Filename for the file in zip archive + * @return string $contents File string contents + */ + public function getFromName($fileName) + { + $list = $this->_zip->listContent(); + $listCount = count($list); + $list_index = -1; + for ($i = 0; $i < $listCount; $i++) { + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || + strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { + $list_index = $i; + break; + } + } + + $extracted = ""; + if ($list_index != -1) { + $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); + } else { + $filename = substr($fileName, 1); + $list_index = -1; + for ($i = 0; $i < $listCount; $i++) { + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { + $list_index = $i; + break; + } + } + $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); + } + if ((is_array($extracted)) && ($extracted != 0)) { + $contents = $extracted[0]["content"]; + } + + return $contents; + } } diff --git a/Examples/runall.php b/Examples/runall.php index 766f8eb3c..5512b0249 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -35,6 +35,7 @@ // List of tests $aTests = array( '01simple.php' + , '01simplePCLZip.php' , '02types.php' , '02types-xls.php' , '03formulas.php' From 7fb98dbcd5fbe30f5ef27253f267d6e7eacdd6c6 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 17 Nov 2013 14:15:22 +0000 Subject: [PATCH 149/467] Fix to new PCLZip wrapper locateName() method --- Classes/PHPExcel/Shared/ZipArchive.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index 195cd6ba8..e70ad28a6 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -118,7 +118,7 @@ public function addFromString($localname, $contents) * @param string $fileName Filename for the file in zip archive * @return boolean */ - public function locateName($name) + public function locateName($fileName) { $list = $this->_zip->listContent(); $listCount = count($list); From 0d8a5d1f0b73b4a45eee4c455898ff6836104ae7 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 17 Nov 2013 17:33:56 +0000 Subject: [PATCH 150/467] General: (adamriyadi) Work Item GH-247 - Modify PHPExcel_Reader_Excel2007 to use zipClass from PHPExcel_Settings::getZipClass() This allows the use of PCLZip when reading for people that don't have access to ZipArchive --- Classes/PHPExcel/Reader/Excel2007.php | 27 +++++++++++++++++--------- Classes/PHPExcel/Shared/ZipArchive.php | 13 ++++++------- changelog.txt | 2 ++ 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 8f58279b0..74322a18d 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -82,14 +82,16 @@ public function canRead($pFilename) throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); } + $zipClass = PHPExcel_Settings::getZipClass(); + // Check if zip class exists - if (!class_exists('ZipArchive',FALSE)) { - throw new PHPExcel_Reader_Exception("ZipArchive library is not enabled"); - } +// if (!class_exists($zipClass, FALSE)) { +// throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); +// } $xl = false; // Load file - $zip = new ZipArchive; + $zip = new $zipClass; if ($zip->open($pFilename) === true) { // check if it is an OOXML archive $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels")); @@ -127,7 +129,9 @@ public function listWorksheetNames($pFilename) $worksheetNames = array(); - $zip = new ZipArchive; + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; $zip->open($pFilename); // The files we're looking at here are small enough that simpleXML is more efficient than XMLReader @@ -171,7 +175,9 @@ public function listWorksheetInfo($pFilename) $worksheetInfo = array(); - $zip = new ZipArchive; + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; $zip->open($pFilename); $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships"); @@ -308,7 +314,7 @@ private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,& } - public function _getFromZipArchive(ZipArchive $archive, $fileName = '') + public function _getFromZipArchive($archive, $fileName = '') { // Root-relative paths if (strpos($fileName, '//') !== false) @@ -348,7 +354,10 @@ public function load($pFilename) $excel->removeCellStyleXfByIndex(0); // remove the default style $excel->removeCellXfByIndex(0); // remove the default style } - $zip = new ZipArchive; + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; $zip->open($pFilename); // Read the theme first, because we need the colour scheme when reading the styles @@ -1409,7 +1418,7 @@ public function load($pFilename) } -// TODO: Autoshapes from twoCellAnchors! + // TODO: Autoshapes from twoCellAnchors! if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $drawings = array(); diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index e70ad28a6..a0a954c8a 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -113,7 +113,6 @@ public function addFromString($localname, $contents) /** * Find if given fileName exist in archive (Emulate ZipArchive locateName()) - * author Adam (adam.riyadi@gmail.com) * * @param string $fileName Filename for the file in zip archive * @return boolean @@ -123,7 +122,7 @@ public function locateName($fileName) $list = $this->_zip->listContent(); $listCount = count($list); $list_index = -1; - for ($i = 0; $i < $listCount; $i++) { + for ($i = 0; $i < $listCount; ++$i) { if (strtolower($list[$i]["filename"]) == strtolower($fileName) || strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { $list_index = $i; @@ -135,7 +134,6 @@ public function locateName($fileName) /** * Extract file from archive by given fileName (Emulate ZipArchive getFromName()) - * author Adam (adam.riyadi@gmail.com) * * @param string $fileName Filename for the file in zip archive * @return string $contents File string contents @@ -145,22 +143,23 @@ public function getFromName($fileName) $list = $this->_zip->listContent(); $listCount = count($list); $list_index = -1; - for ($i = 0; $i < $listCount; $i++) { + for ($i = 0; $i < $listCount; ++$i) { if (strtolower($list[$i]["filename"]) == strtolower($fileName) || strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { $list_index = $i; break; } } - + $extracted = ""; if ($list_index != -1) { $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); } else { $filename = substr($fileName, 1); $list_index = -1; - for ($i = 0; $i < $listCount; $i++) { - if (strtolower($list[$i]["filename"]) == strtolower($fileName) || strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { + for ($i = 0; $i < $listCount; ++$i) { + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || + strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { $list_index = $i; break; } diff --git a/changelog.txt b/changelog.txt index deeb03b3e..6340623ec 100644 --- a/changelog.txt +++ b/changelog.txt @@ -45,6 +45,8 @@ Fixed in develop branch for release v1.8.0: - General: (MBaker) - Modified Excel2007 Writer to default preCalculateFormulas to false Note that autosize columns will still recalculate affected formulae internally - General: (dresenhista) Work Item GH-242 - Functionality to getHighestRow() for a specified column, and getHighestColumn() for a specified row +- General: (adamriyadi) Work Item GH-247 - Modify PHPExcel_Reader_Excel2007 to use zipClass from PHPExcel_Settings::getZipClass() + This allows the use of PCLZip when reading for people that don't have access to ZipArchive Fixed in develop branch for release v1.7.9: From 4eefabf7a0b86894533c0bcc4983da1de0ae6a04 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 17 Nov 2013 17:45:21 +0000 Subject: [PATCH 151/467] Modify OOCalc reader to work with PCLZip rather than ZipArchive if configured to do so --- Classes/PHPExcel/Reader/OOCalc.php | 22 ++++-- Examples/01simplePCLZip.php | 106 +++++++++++++++++++++++++++++ Examples/07readerPCLZip.php | 79 +++++++++++++++++++++ Examples/OOCalcReaderPCLZip.php | 64 +++++++++++++++++ Examples/runall.php | 2 + 5 files changed, 266 insertions(+), 7 deletions(-) create mode 100644 Examples/01simplePCLZip.php create mode 100644 Examples/07readerPCLZip.php create mode 100644 Examples/OOCalcReaderPCLZip.php diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 8343e3772..106421730 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -74,14 +74,16 @@ public function canRead($pFilename) throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); } + $zipClass = PHPExcel_Settings::getZipClass(); + // Check if zip class exists - if (!class_exists('ZipArchive',FALSE)) { - throw new PHPExcel_Reader_Exception("ZipArchive library is not enabled"); - } +// if (!class_exists($zipClass, FALSE)) { +// throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); +// } $mimeType = 'UNKNOWN'; // Load file - $zip = new ZipArchive; + $zip = new $zipClass; if ($zip->open($pFilename) === true) { // check if it is an OOXML archive $stat = $zip->statName('mimetype'); @@ -124,7 +126,9 @@ public function listWorksheetNames($pFilename) throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); } - $zip = new ZipArchive; + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; if (!$zip->open($pFilename)) { throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); } @@ -176,7 +180,9 @@ public function listWorksheetInfo($pFilename) $worksheetInfo = array(); - $zip = new ZipArchive; + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; if (!$zip->open($pFilename)) { throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); } @@ -331,7 +337,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $timezoneObj = new DateTimeZone('Europe/London'); $GMT = new DateTimeZone('UTC'); - $zip = new ZipArchive; + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; if (!$zip->open($pFilename)) { throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); } diff --git a/Examples/01simplePCLZip.php b/Examples/01simplePCLZip.php new file mode 100644 index 000000000..ab82497cf --- /dev/null +++ b/Examples/01simplePCLZip.php @@ -0,0 +1,106 @@ +'); + +/** Include PHPExcel */ +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; + + +// Create new PHPExcel object +echo date('H:i:s') , " Create new PHPExcel object" , EOL; +$objPHPExcel = new PHPExcel(); + +// Set document properties +echo date('H:i:s') , " Set document properties" , EOL; +$objPHPExcel->getProperties()->setCreator("Maarten Balliauw") + ->setLastModifiedBy("Maarten Balliauw") + ->setTitle("PHPExcel Test Document") + ->setSubject("PHPExcel Test Document") + ->setDescription("Test document for PHPExcel, generated using PHP classes.") + ->setKeywords("office PHPExcel php") + ->setCategory("Test result file"); + + +// Add some data +echo date('H:i:s') , " Add some data" , EOL; +$objPHPExcel->setActiveSheetIndex(0) + ->setCellValue('A1', 'Hello') + ->setCellValue('B2', 'world!') + ->setCellValue('C1', 'Hello') + ->setCellValue('D2', 'world!'); + +// Miscellaneous glyphs, UTF-8 +$objPHPExcel->setActiveSheetIndex(0) + ->setCellValue('A4', 'Miscellaneous glyphs') + ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç'); + + +$objPHPExcel->getActiveSheet()->setCellValue('A8',"Hello\nWorld"); +$objPHPExcel->getActiveSheet()->getRowDimension(8)->setRowHeight(-1); +$objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true); + + +// Rename worksheet +echo date('H:i:s') , " Rename worksheet" , EOL; +$objPHPExcel->getActiveSheet()->setTitle('Simple'); + + +// Set active sheet index to the first sheet, so Excel opens this as the first sheet +$objPHPExcel->setActiveSheetIndex(0); + + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$callStartTime = microtime(true); + +// Use PCLZip rather than ZipArchive to create the Excel2007 OfficeOpenXML file +PHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Examples/07readerPCLZip.php b/Examples/07readerPCLZip.php new file mode 100644 index 000000000..dc1885a58 --- /dev/null +++ b/Examples/07readerPCLZip.php @@ -0,0 +1,79 @@ +'); + +date_default_timezone_set('Europe/London'); + +/** Include PHPExcel_IOFactory */ +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; + + +if (!file_exists("05featuredemo.xlsx")) { + exit("Please run 05featuredemo.php first." . EOL); +} + +// Use PCLZip rather than ZipArchive to read the Excel2007 OfficeOpenXML file +PHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP); + +echo date('H:i:s') , " Load from Excel2007 file" , EOL; +$callStartTime = microtime(true); + +$objPHPExcel = PHPExcel_IOFactory::load("05featuredemo.xlsx"); + +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; +echo 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); + +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Examples/OOCalcReaderPCLZip.php b/Examples/OOCalcReaderPCLZip.php new file mode 100644 index 000000000..2f3f922fa --- /dev/null +++ b/Examples/OOCalcReaderPCLZip.php @@ -0,0 +1,64 @@ +load("OOCalcTest.ods"); + + +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; +echo 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , PHP_EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; + + +echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , PHP_EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , PHP_EOL; + diff --git a/Examples/runall.php b/Examples/runall.php index 5512b0249..4d2e207f2 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -45,6 +45,7 @@ , '06largescale-with-cellcaching.php' , '06largescale-xls.php' , '07reader.php' + , '07readerPCLZip.php' , '08conditionalformatting.php' , '08conditionalformatting2.php' , '09pagebreaks.php' @@ -95,6 +96,7 @@ , '38cloneWorksheet.php' , '40duplicateStyle.php' , 'OOCalcReader.php' + , 'OOCalcReaderPCLZip.php' , 'SylkReader.php' , 'Excel2003XMLReader.php' , 'XMLReader.php' From f3755a09655299fc3e0fef7b5b3144833df47701 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 17 Nov 2013 19:43:47 +0000 Subject: [PATCH 152/467] Documentation fix: (PowerKiKi) GH-224 - Minor fix in DocBlock --- Classes/PHPExcel/Calculation/Functions.php | 2 +- Classes/PHPExcel/Writer/HTML.php | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index 3004eec93..2d6bf9474 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -270,7 +270,7 @@ public static function REF() { * * @access public * @category Error Returns - * @return string #REF! + * @return string #NULL! */ public static function NULL() { return self::$_errorCodes['null']; diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index ca45a6f4d..e0a2d784f 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -608,7 +608,10 @@ private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { } $html .= '
'; - $html .= '' . PHP_EOL; + $html .= ''; $html .= '
'; } } From aa660150aee4dc28208e573a6e35a096a2249f20 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 17 Nov 2013 19:52:35 +0000 Subject: [PATCH 153/467] Documentation (jamescostian) GH-234 - Fixed some malformed Markdown --- Documentation/markdown/Overview/08-Recipes.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/markdown/Overview/08-Recipes.md b/Documentation/markdown/Overview/08-Recipes.md index d7a3db388..616c145d2 100644 --- a/Documentation/markdown/Overview/08-Recipes.md +++ b/Documentation/markdown/Overview/08-Recipes.md @@ -731,8 +731,13 @@ An example on setting cell security: $objPHPExcel->getActiveSheet()->getStyle('B1') ->getProtection() ->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); +``` + +__Make sure you enable worksheet protection if you need any of the worksheet protection features!__ This can be done using the following code: -__Make sure you enable worksheet protection if you need any of the worksheet protection features!__ This can be done using the following code: $objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); +```php +$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); +``` ### Setting data validation on a cell From dc416f83a574b5613e1732214eb9914406fa8c49 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 17 Nov 2013 21:36:43 +0000 Subject: [PATCH 154/467] Fix UTF-8 in markdown --- Documentation/markdown/Overview/08-Recipes.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Documentation/markdown/Overview/08-Recipes.md b/Documentation/markdown/Overview/08-Recipes.md index 616c145d2..eed732b9a 100644 --- a/Documentation/markdown/Overview/08-Recipes.md +++ b/Documentation/markdown/Overview/08-Recipes.md @@ -165,22 +165,22 @@ At present, the following locale settings are supported: Language | | Locale Code ---------------------|----------------------|------------- - Czech | Ce�tina | cs + Czech | Čeština | cs Danish | Dansk | da German | Deutsch | de - Spanish | Espa�ol | es + Spanish | Español | es Finnish | Suomi | fi - French | Fran�ais | fr + French | Français | fr Hungarian | Magyar | hu Italian | Italiano | it Dutch | Nederlands | nl Norwegian | Norsk | no Polish | Jezyk polski | pl - Portuguese | Portugu�s | pt - Brazilian Portuguese | Portugu�s Brasileiro | pt_br - Russian | ??????? ???? | ru + Portuguese | Português | pt + Brazilian Portuguese | Português Brasileiro | pt_br + Russian | русский язык | ru Swedish | Svenska | sv - Turkish | T�rk�e | tr + Turkish | Türkçe | tr ### Write a newline character "\n" in a cell (ALT+"Enter") @@ -195,7 +195,9 @@ $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setWrapText(true __Tip__ -Read more about formatting cells using getStyle() elsewhere.__Tip__ +Read more about formatting cells using getStyle() elsewhere. + +__Tip__ AdvancedValuebinder.php automatically turns on "wrap text" for the cell when it sees a newline character in a string that you are inserting in a cell. Just like Microsoft Office Excel. Try this: From 7f0a8044a49f0739d77c26ed7e298d6d3e310435 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 17 Nov 2013 21:45:30 +0000 Subject: [PATCH 155/467] Markdown charset, second attempt --- Documentation/markdown/Overview/08-Recipes.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/markdown/Overview/08-Recipes.md b/Documentation/markdown/Overview/08-Recipes.md index eed732b9a..165bb5473 100644 --- a/Documentation/markdown/Overview/08-Recipes.md +++ b/Documentation/markdown/Overview/08-Recipes.md @@ -165,22 +165,22 @@ At present, the following locale settings are supported: Language | | Locale Code ---------------------|----------------------|------------- - Czech | Čeština | cs + Czech | Ce�tina | cs Danish | Dansk | da German | Deutsch | de - Spanish | Español | es + Spanish | Espa�ol | es Finnish | Suomi | fi - French | Français | fr + French | Fran�ais | fr Hungarian | Magyar | hu Italian | Italiano | it Dutch | Nederlands | nl Norwegian | Norsk | no Polish | Jezyk polski | pl - Portuguese | Português | pt - Brazilian Portuguese | Português Brasileiro | pt_br - Russian | русский язык | ru + Portuguese | Portugu�s | pt + Brazilian Portuguese | Portugu�s Brasileiro | pt_br + Russian | ??????? ???? | ru Swedish | Svenska | sv - Turkish | Türkçe | tr + Turkish | T�rk�e | tr ### Write a newline character "\n" in a cell (ALT+"Enter") From 30459d260d69f516bf986ea649abb93a96d719d6 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 18 Nov 2013 08:00:49 +0000 Subject: [PATCH 156/467] General: (RomanSyroeshko) GB-265 - PHPExcel_Shared_String.IsUTF8 returns FALSE for Cyrillic UTF-8 input --- Classes/PHPExcel/Shared/String.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 3ba1be262..6fe9eb96e 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -403,7 +403,7 @@ public static function SanitizeUTF8($value) * @return boolean */ public static function IsUTF8($value = '') { - return utf8_encode(utf8_decode($value)) === $value; + return $string === '' || preg_match('/^./su', $string) === 1; } /** From 9c6287a323d9899ffbbd37dfe357d1d1212c998a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 18 Nov 2013 14:20:37 +0000 Subject: [PATCH 157/467] Bugfix: (IndrekHaav) Work Item GH-212 - Fix for formulae that reference a sheet whose name begins with a digit: these were erroneously identified as numeric values, causing the parser to throw an undefined variable error. --- Classes/PHPExcel/Calculation.php | 2 +- changelog.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 01cfb7cfa..152c98e1d 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2738,10 +2738,10 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION. + '|'.self::CALCULATION_REGEXP_CELLREF. '|'.self::CALCULATION_REGEXP_NUMBER. '|'.self::CALCULATION_REGEXP_STRING. '|'.self::CALCULATION_REGEXP_OPENBRACE. - '|'.self::CALCULATION_REGEXP_CELLREF. '|'.self::CALCULATION_REGEXP_NAMEDRANGE. '|'.self::CALCULATION_REGEXP_ERROR. ')/si'; diff --git a/changelog.txt b/changelog.txt index 6340623ec..13b7964e4 100644 --- a/changelog.txt +++ b/changelog.txt @@ -34,6 +34,8 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (RomanSyroeshko) Work Item GH-267 - CHOOSE() returns "#VALUE!" if the 1st entry is chosen - Bugfix: (Gemorroj) Work Item GH-268 - When duplicating styles, styles shifted by one column to the right Fix also applied to duplicating conditional styles +- Bugfix: (IndrekHaav) Work Item GH-212 - Fix for formulae that reference a sheet whose name begins with a digit: + these were erroneously identified as numeric values, causing the parser to throw an undefined variable error. - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From f5bd6dc0f2bb7e76502494912805b51d96ef2de8 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 18 Nov 2013 14:28:22 +0000 Subject: [PATCH 158/467] Bugfix: (IndrekHaav) Work Item CP16208 - Fixed undefined variable error due to $styleArray being used before it's initialised --- Classes/PHPExcel/Reader/Gnumeric.php | 2 +- changelog.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index 50e7a8a11..9e2b241f6 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -511,7 +511,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // We still set the number format mask for date/time values, even if _readDataOnly is true if ((!$this->_readDataOnly) || - (PHPExcel_Shared_Date::isDateTimeFormatCode($styleArray['numberformat']['code']))) { + (PHPExcel_Shared_Date::isDateTimeFormatCode((string) $styleAttributes['Format']))) { $styleArray = array(); $styleArray['numberformat']['code'] = (string) $styleAttributes['Format']; // If _readDataOnly is false, we set all formatting information diff --git a/changelog.txt b/changelog.txt index 13b7964e4..17b828179 100644 --- a/changelog.txt +++ b/changelog.txt @@ -36,6 +36,7 @@ Fixed in develop branch for release v1.8.0: Fix also applied to duplicating conditional styles - Bugfix: (IndrekHaav) Work Item GH-212 - Fix for formulae that reference a sheet whose name begins with a digit: these were erroneously identified as numeric values, causing the parser to throw an undefined variable error. +- Bugfix: (IndrekHaav) Work Item CP16208 - Fixed undefined variable error due to $styleArray being used before it's initialised - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From f505648ec5471204cf2fc95650b72463c7577bce Mon Sep 17 00:00:00 2001 From: bolovincev Date: Tue, 19 Nov 2013 22:51:11 +0300 Subject: [PATCH 159/467] Update Worksheet.php getStyleByColumnAndRow() http://phpexcel.codeplex.com/discussions/263626 $objPHPExcel->getActiveSheet()->getStyleByColumnAndRow(1, 2, 5, 2)->applyFromArray($styleArray); It is very convenient in cycles --- Classes/PHPExcel/Worksheet.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 3fecc164d..35a0bdb19 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1486,11 +1486,20 @@ public function setConditionalStyles($pCoordinate = 'A1', $pValue) * * @param int $pColumn Numeric column coordinate of the cell * @param int $pRow Numeric row coordinate of the cell + * @param int pColumn2 Numeric column coordinate of the range cell + * @param int pRow2 Numeric row coordinate of the range cell * @return PHPExcel_Style */ - public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1) + public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1, $pColumn2=null, $pRow2=null) { - return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + + if(!is_null($pColumn2) && !is_null($pRow2)) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->getStyle($cellRange); + } + + return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); } /** From f2e24ecdd49c57ba8f7ae382099eeaf6225bd56e Mon Sep 17 00:00:00 2001 From: Adrien Crivelli Date: Wed, 20 Nov 2013 18:55:05 +0900 Subject: [PATCH 160/467] Comparison operators on strings are usually case insensitive Excel, Gnumeric and Google Spreadsheet are case insensitive, so the default behavior of PHPExcel is modified accordingly. However OpenOffice is case sensitive and is also supported via the compatibility mode of PHPExcel. Fixes #31 --- Classes/PHPExcel/Calculation.php | 53 +++++++++++++++++-- .../Classes/PHPExcel/CalculationTest.php | 35 ++++++++++++ .../CalculationBinaryComparisonOperation.data | 53 +++++++++++++++++++ 3 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/CalculationTest.php create mode 100644 unitTests/rawTestData/CalculationBinaryComparisonOperation.data diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 152c98e1d..19e8edd92 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -3557,15 +3557,37 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); } if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); } + // Use case insensitive comparaison if not OpenOffice mode + if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) + { + if (is_string($operand1)) { + $operand1 = strtoupper($operand1); + } + + if (is_string($operand2)) { + $operand2 = strtoupper($operand2); + } + } + + $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE; + // execute the necessary operation switch ($operation) { // Greater than case '>': - $result = ($operand1 > $operand2); + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0; + } else { + $result = ($operand1 > $operand2); + } break; // Less than case '<': - $result = ($operand1 < $operand2); + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0; + } else { + $result = ($operand1 < $operand2); + } break; // Equality case '=': @@ -3573,11 +3595,19 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 break; // Greater than or equal case '>=': - $result = ($operand1 >= $operand2); + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0; + } else { + $result = ($operand1 >= $operand2); + } break; // Less than or equal case '<=': - $result = ($operand1 <= $operand2); + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0; + } else { + $result = ($operand1 <= $operand2); + } break; // Inequality case '<>': @@ -3592,6 +3622,21 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 return TRUE; } // function _executeBinaryComparisonOperation() + /** + * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters + * @param string $str1 + * @param string $str2 + * @return integer + */ + private function strcmpLowercaseFirst($str1, $str2) + { + $from = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + $to = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $inversedStr1 = strtr($str1, $from, $to); + $inversedStr2 = strtr($str2, $from, $to); + + return strcmp($inversedStr1, $inversedStr2); + } private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { // Validate the two operands diff --git a/unitTests/Classes/PHPExcel/CalculationTest.php b/unitTests/Classes/PHPExcel/CalculationTest.php new file mode 100644 index 000000000..8f8ce7e0a --- /dev/null +++ b/unitTests/Classes/PHPExcel/CalculationTest.php @@ -0,0 +1,35 @@ +_calculateFormulaValue($formula); + $this->assertEquals($expectedResultExcel, $resultExcel, 'should be Excel compatible'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE); + $resultOpenOffice = \PHPExcel_Calculation::getInstance()->_calculateFormulaValue($formula); + $this->assertEquals($expectedResultOpenOffice, $resultOpenOffice, 'should be OpenOffice compatible'); + } + + public function providerBinaryComparisonOperation() + { + return new testDataFileIterator('rawTestData/CalculationBinaryComparisonOperation.data'); + } + +} diff --git a/unitTests/rawTestData/CalculationBinaryComparisonOperation.data b/unitTests/rawTestData/CalculationBinaryComparisonOperation.data new file mode 100644 index 000000000..de04cbf79 --- /dev/null +++ b/unitTests/rawTestData/CalculationBinaryComparisonOperation.data @@ -0,0 +1,53 @@ +# formula, expectedResultExcel, expectedResultOpenOffice +'=TRUE', TRUE, TRUE +'=1 + 2.5', 3.5, 3.5 +'=2.5 + 1', 3.5, 3.5 +'=1 - 2.5', -1.5, -1.5 +'=2.5 - 1', 1.5, 1.5 +'=3 > 1', TRUE, TRUE +'=3 > 3', FALSE, FALSE +'=1 > 3', FALSE, FALSE +'=3 < 1', FALSE, FALSE +'=3 < 3', FALSE, FALSE +'=1 < 3', TRUE, TRUE +'=3 = 1', FALSE, FALSE +'=3 = 3', TRUE, TRUE +'=1 = 1.0', TRUE, TRUE +'=3 >= 1', TRUE, TRUE +'=3 >= 3', TRUE, TRUE +'=1 >= 3', FALSE, FALSE +'=3 <= 1', FALSE, FALSE +'=3 <= 3', TRUE, TRUE +'=1 <= 3', TRUE, TRUE +'=3 <> 1', TRUE, TRUE +'=3 <> 3', FALSE, FALSE +'=1 <> 1.0', FALSE, FALSE +'="a" > "a"', FALSE, FALSE +'="A" > "A"', FALSE, FALSE +'="A" > "a"', FALSE, TRUE +'="a" > "A"', FALSE, FALSE +'="a" < "a"', FALSE, FALSE +'="A" < "A"', FALSE, FALSE +'="A" < "a"', FALSE, FALSE +'="a" < "A"', FALSE, TRUE +'="a" = "a"', TRUE, TRUE +'="A" = "A"', TRUE, TRUE +'="A" = "a"', TRUE, FALSE +'="a" = "A"', TRUE, FALSE +'="a" <= "a"', TRUE, TRUE +'="A" <= "A"', TRUE, TRUE +'="A" <= "a"', TRUE, FALSE +'="a" <= "A"', TRUE, TRUE +'="a" >= "a"', TRUE, TRUE +'="A" >= "A"', TRUE, TRUE +'="A" >= "a"', TRUE, TRUE +'="a" >= "A"', TRUE, FALSE +'="a" <> "a"', FALSE, FALSE +'="A" <> "A"', FALSE, FALSE +'="A" <> "a"', FALSE, TRUE +'="a" <> "A"', FALSE, TRUE +'="A" > "b"', FALSE, TRUE +'="a" > "b"', FALSE, FALSE +'="b" > "a"', TRUE, TRUE +'="b" > "A"', TRUE, FALSE +'="a2" > "a10"', TRUE, TRUE // Test natural sorting is not used From 5d6687b6ceaee4e8868d88829543c824c2e2160e Mon Sep 17 00:00:00 2001 From: Adrien Crivelli Date: Fri, 22 Nov 2013 19:33:56 +0900 Subject: [PATCH 161/467] ISTEXT() return wrong result if referencing an empty but formatted cell ISTEXT should always return FALSE for empty cells, however PHPExcel returns TRUE if the cell is formatted. This can be reproduced in Excel by choosing formatting category "Text" for cell A1, and then in cell B1 input the formula '=ISTEXT(A1)'. B1 will display FALSE, but PHPExcel will return TRUE. This patch fix the NULL value being incorrectly cast to an empty string, and thus eliminating ISTEXT() issue (and probably several others). --- Classes/PHPExcel/Cell.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index cbd8a8f7f..f2f331e57 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -233,10 +233,12 @@ public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_Data { // set the value according to data type switch ($pDataType) { + case PHPExcel_Cell_DataType::TYPE_NULL: + $this->_value = $pValue; + break; case PHPExcel_Cell_DataType::TYPE_STRING2: $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; case PHPExcel_Cell_DataType::TYPE_STRING: - case PHPExcel_Cell_DataType::TYPE_NULL: case PHPExcel_Cell_DataType::TYPE_INLINE: $this->_value = PHPExcel_Cell_DataType::checkString($pValue); break; @@ -379,7 +381,7 @@ public function isFormula() { return $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA; } - + /** * Does this cell contain Data validation rules? * From f2f097733b8a9b2dd39d6d71555725f03fcc3ab8 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 23 Nov 2013 21:22:06 +0000 Subject: [PATCH 162/467] Bugfix: (PowerKiKi) Work Item GH-273 - ISTEXT() return wrong result if referencing an empty but formatted cell --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 17b828179..50554ab4b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -37,6 +37,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (IndrekHaav) Work Item GH-212 - Fix for formulae that reference a sheet whose name begins with a digit: these were erroneously identified as numeric values, causing the parser to throw an undefined variable error. - Bugfix: (IndrekHaav) Work Item CP16208 - Fixed undefined variable error due to $styleArray being used before it's initialised +- Bugfix: (PowerKiKi) Work Item GH-273 - ISTEXT() return wrong result if referencing an empty but formatted cell - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From 4570c52d2a6e15c0b02353999df11bf1efc3112d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 23 Nov 2013 21:38:09 +0000 Subject: [PATCH 163/467] Bugfix: (PowerKiKi) Work Item GH-270/GH-31 - Binary comparison of strings are case insensitive --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 50554ab4b..f9c6ab87e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -38,6 +38,7 @@ Fixed in develop branch for release v1.8.0: these were erroneously identified as numeric values, causing the parser to throw an undefined variable error. - Bugfix: (IndrekHaav) Work Item CP16208 - Fixed undefined variable error due to $styleArray being used before it's initialised - Bugfix: (PowerKiKi) Work Item GH-273 - ISTEXT() return wrong result if referencing an empty but formatted cell +- Bugfix: (PowerKiKi) Work Item GH-270/GH-31 - Binary comparison of strings are case insensitive - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From b671d8376faf2bfdbd117ab5180b31a504c624c2 Mon Sep 17 00:00:00 2001 From: infojunkie Date: Mon, 25 Nov 2013 16:18:46 -0800 Subject: [PATCH 164/467] Convert properties to string in OOCalc reader --- Classes/PHPExcel/Reader/OOCalc.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 106421730..2d9af18d3 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -359,6 +359,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); } foreach($officePropertyDC as $propertyName => $propertyValue) { + $propertyValue = (string) $propertyValue; switch ($propertyName) { case 'title' : $docProps->setTitle($propertyValue); @@ -386,6 +387,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } foreach($officePropertyMeta as $propertyName => $propertyValue) { $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']); + $propertyValue = (string) $propertyValue; switch ($propertyName) { case 'initial-creator' : $docProps->setCreator($propertyValue); From c7a6431e099067becda33986ee664fe52ea10e33 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Thu, 28 Nov 2013 23:43:57 +0000 Subject: [PATCH 165/467] Feature: (trvrnrth) Work Item GH-261 - Add support for reading protected (RC4 encrypted) .xls files (tweaked for PHP 5.2 compatibility) --- Classes/PHPExcel/Reader/Excel5.php | 2 +- Classes/PHPExcel/Reader/Excel5/MD5.php | 384 ++++++++++++------------- changelog.txt | 2 +- 3 files changed, 190 insertions(+), 198 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 601c492d3..b9932e636 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -1687,7 +1687,7 @@ private function _readFilepass() substr($recordData, 38, 16), $this->_md5Ctxt )) { - throw new \Exception('Decryption password incorrect'); + throw new PHPExcel_Reader_Exception('Decryption password incorrect'); } $this->_encryption = self::MS_BIFF_CRYPTO_RC4; diff --git a/Classes/PHPExcel/Reader/Excel5/MD5.php b/Classes/PHPExcel/Reader/Excel5/MD5.php index 62e05156b..3663236bc 100644 --- a/Classes/PHPExcel/Reader/Excel5/MD5.php +++ b/Classes/PHPExcel/Reader/Excel5/MD5.php @@ -21,209 +21,201 @@ * @category PHPExcel * @package PHPExcel_Reader_Excel5 * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ + /** * PHPExcel_Reader_Excel5_MD5 * - * @category PHPExcel - * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel5_MD5 { - // Context - private $a; - private $b; - private $c; - private $d; - - /** - * MD5 stream constructor - */ - public function __construct() - { - $this->reset(); - } - - /** - * Reset the MD5 stream context - */ - public function reset() - { - $this->a = 0x67452301; - $this->b = 0xEFCDAB89; - $this->c = 0x98BADCFE; - $this->d = 0x10325476; - } - - /** - * Get MD5 stream context - * - * @return string - */ - public function getContext() - { - $s = ''; - foreach (array('a', 'b', 'c', 'd') as $i) { - $v = $this->{$i}; - $s .= chr($v & 0xff); - $s .= chr(($v >> 8) & 0xff); - $s .= chr(($v >> 16) & 0xff); - $s .= chr(($v >> 24) & 0xff); - } - - return $s; - } - - /** - * Add data to context - * - * @param string $data Data to add - */ - public function add($data) - { - $words = array_values(unpack('V16', $data)); - - $A = $this->a; - $B = $this->b; - $C = $this->c; - $D = $this->d; - - /* ROUND 1 */ - self::FF($A, $B, $C, $D, $words[0], 7, 0xd76aa478); - self::FF($D, $A, $B, $C, $words[1], 12, 0xe8c7b756); - self::FF($C, $D, $A, $B, $words[2], 17, 0x242070db); - self::FF($B, $C, $D, $A, $words[3], 22, 0xc1bdceee); - self::FF($A, $B, $C, $D, $words[4], 7, 0xf57c0faf); - self::FF($D, $A, $B, $C, $words[5], 12, 0x4787c62a); - self::FF($C, $D, $A, $B, $words[6], 17, 0xa8304613); - self::FF($B, $C, $D, $A, $words[7], 22, 0xfd469501); - self::FF($A, $B, $C, $D, $words[8], 7, 0x698098d8); - self::FF($D, $A, $B, $C, $words[9], 12, 0x8b44f7af); - self::FF($C, $D, $A, $B, $words[10], 17, 0xffff5bb1); - self::FF($B, $C, $D, $A, $words[11], 22, 0x895cd7be); - self::FF($A, $B, $C, $D, $words[12], 7, 0x6b901122); - self::FF($D, $A, $B, $C, $words[13], 12, 0xfd987193); - self::FF($C, $D, $A, $B, $words[14], 17, 0xa679438e); - self::FF($B, $C, $D, $A, $words[15], 22, 0x49b40821); - - /* ROUND 2 */ - self::GG($A, $B, $C, $D, $words[1], 5, 0xf61e2562); - self::GG($D, $A, $B, $C, $words[6], 9, 0xc040b340); - self::GG($C, $D, $A, $B, $words[11], 14, 0x265e5a51); - self::GG($B, $C, $D, $A, $words[0], 20, 0xe9b6c7aa); - self::GG($A, $B, $C, $D, $words[5], 5, 0xd62f105d); - self::GG($D, $A, $B, $C, $words[10], 9, 0x02441453); - self::GG($C, $D, $A, $B, $words[15], 14, 0xd8a1e681); - self::GG($B, $C, $D, $A, $words[4], 20, 0xe7d3fbc8); - self::GG($A, $B, $C, $D, $words[9], 5, 0x21e1cde6); - self::GG($D, $A, $B, $C, $words[14], 9, 0xc33707d6); - self::GG($C, $D, $A, $B, $words[3], 14, 0xf4d50d87); - self::GG($B, $C, $D, $A, $words[8], 20, 0x455a14ed); - self::GG($A, $B, $C, $D, $words[13], 5, 0xa9e3e905); - self::GG($D, $A, $B, $C, $words[2], 9, 0xfcefa3f8); - self::GG($C, $D, $A, $B, $words[7], 14, 0x676f02d9); - self::GG($B, $C, $D, $A, $words[12], 20, 0x8d2a4c8a); - - /* ROUND 3 */ - self::HH($A, $B, $C, $D, $words[5], 4, 0xfffa3942); - self::HH($D, $A, $B, $C, $words[8], 11, 0x8771f681); - self::HH($C, $D, $A, $B, $words[11], 16, 0x6d9d6122); - self::HH($B, $C, $D, $A, $words[14], 23, 0xfde5380c); - self::HH($A, $B, $C, $D, $words[1], 4, 0xa4beea44); - self::HH($D, $A, $B, $C, $words[4], 11, 0x4bdecfa9); - self::HH($C, $D, $A, $B, $words[7], 16, 0xf6bb4b60); - self::HH($B, $C, $D, $A, $words[10], 23, 0xbebfbc70); - self::HH($A, $B, $C, $D, $words[13], 4, 0x289b7ec6); - self::HH($D, $A, $B, $C, $words[0], 11, 0xeaa127fa); - self::HH($C, $D, $A, $B, $words[3], 16, 0xd4ef3085); - self::HH($B, $C, $D, $A, $words[6], 23, 0x04881d05); - self::HH($A, $B, $C, $D, $words[9], 4, 0xd9d4d039); - self::HH($D, $A, $B, $C, $words[12], 11, 0xe6db99e5); - self::HH($C, $D, $A, $B, $words[15], 16, 0x1fa27cf8); - self::HH($B, $C, $D, $A, $words[2], 23, 0xc4ac5665); - - /* ROUND 4 */ - self::II($A, $B, $C, $D, $words[0], 6, 0xf4292244); - self::II($D, $A, $B, $C, $words[7], 10, 0x432aff97); - self::II($C, $D, $A, $B, $words[14], 15, 0xab9423a7); - self::II($B, $C, $D, $A, $words[5], 21, 0xfc93a039); - self::II($A, $B, $C, $D, $words[12], 6, 0x655b59c3); - self::II($D, $A, $B, $C, $words[3], 10, 0x8f0ccc92); - self::II($C, $D, $A, $B, $words[10], 15, 0xffeff47d); - self::II($B, $C, $D, $A, $words[1], 21, 0x85845dd1); - self::II($A, $B, $C, $D, $words[8], 6, 0x6fa87e4f); - self::II($D, $A, $B, $C, $words[15], 10, 0xfe2ce6e0); - self::II($C, $D, $A, $B, $words[6], 15, 0xa3014314); - self::II($B, $C, $D, $A, $words[13], 21, 0x4e0811a1); - self::II($A, $B, $C, $D, $words[4], 6, 0xf7537e82); - self::II($D, $A, $B, $C, $words[11], 10, 0xbd3af235); - self::II($C, $D, $A, $B, $words[2], 15, 0x2ad7d2bb); - self::II($B, $C, $D, $A, $words[9], 21, 0xeb86d391); - - $this->a = ($this->a + $A) & 0xffffffff; - $this->b = ($this->b + $B) & 0xffffffff; - $this->c = ($this->c + $C) & 0xffffffff; - $this->d = ($this->d + $D) & 0xffffffff; - } - - private static function F($X, $Y, $Z) - { - $calc = (($X & $Y) | ((~ $X) & $Z)); // X AND Y OR NOT X AND Z - return $calc; - } - - private static function G($X, $Y, $Z) - { - $calc = (($X & $Z) | ($Y & (~ $Z))); // X AND Z OR Y AND NOT Z - return $calc; - } - - private static function H($X, $Y, $Z) - { - $calc = ($X ^ $Y ^ $Z); // X XOR Y XOR Z - return $calc; - } - - private static function I($X, $Y, $Z) - { - $calc = ($Y ^ ($X | (~ $Z))) ; // Y XOR (X OR NOT Z) - return $calc; - } - - private static function FF(&$A, $B, $C, $D, $M, $s, $t) - { - $A = ($A + self::F($B, $C, $D) + $M + $t) & 0xffffffff; - $A = self::rotate($A, $s); - $A = ($B + $A) & 0xffffffff; - } - - private static function GG(&$A, $B, $C, $D, $M, $s, $t) - { - $A = ($A + self::G($B, $C, $D) + $M + $t) & 0xffffffff; - $A = self::rotate($A, $s); - $A = ($B + $A) & 0xffffffff; - } - - private static function HH(&$A, $B, $C, $D, $M, $s, $t) - { - $A = ($A + self::H($B, $C, $D) + $M + $t) & 0xffffffff; - $A = self::rotate($A, $s); - $A = ($B + $A) & 0xffffffff; - } - - private static function II(&$A, $B, $C, $D, $M, $s, $t) - { - $A = ($A + self::I($B, $C, $D) + $M + $t) & 0xffffffff; - $A = self::rotate($A, $s); - $A = ($B + $A) & 0xffffffff; - } - - private static function rotate ($decimal, $bits) - { - return (($decimal << $bits) | ($decimal >> (32 - $bits))) & 0xffffffff; - } + // Context + private $a; + private $b; + private $c; + private $d; + + + /** + * MD5 stream constructor + */ + public function __construct() + { + $this->reset(); + } + + + /** + * Reset the MD5 stream context + */ + public function reset() + { + $this->a = 0x67452301; + $this->b = 0xEFCDAB89; + $this->c = 0x98BADCFE; + $this->d = 0x10325476; + } + + + /** + * Get MD5 stream context + * + * @return string + */ + public function getContext() + { + $s = ''; + foreach (array('a', 'b', 'c', 'd') as $i) { + $v = $this->{$i}; + $s .= chr($v & 0xff); + $s .= chr(($v >> 8) & 0xff); + $s .= chr(($v >> 16) & 0xff); + $s .= chr(($v >> 24) & 0xff); + } + + return $s; + } + + + /** + * Add data to context + * + * @param string $data Data to add + */ + public function add($data) + { + $words = array_values(unpack('V16', $data)); + + $A = $this->a; + $B = $this->b; + $C = $this->c; + $D = $this->d; + + $F = array('PHPExcel_Reader_Excel5_MD5','F'); + $G = array('PHPExcel_Reader_Excel5_MD5','G'); + $H = array('PHPExcel_Reader_Excel5_MD5','H'); + $I = array('PHPExcel_Reader_Excel5_MD5','I'); + + /* ROUND 1 */ + self::step($F, $A, $B, $C, $D, $words[0], 7, 0xd76aa478); + self::step($F, $D, $A, $B, $C, $words[1], 12, 0xe8c7b756); + self::step($F, $C, $D, $A, $B, $words[2], 17, 0x242070db); + self::step($F, $B, $C, $D, $A, $words[3], 22, 0xc1bdceee); + self::step($F, $A, $B, $C, $D, $words[4], 7, 0xf57c0faf); + self::step($F, $D, $A, $B, $C, $words[5], 12, 0x4787c62a); + self::step($F, $C, $D, $A, $B, $words[6], 17, 0xa8304613); + self::step($F, $B, $C, $D, $A, $words[7], 22, 0xfd469501); + self::step($F, $A, $B, $C, $D, $words[8], 7, 0x698098d8); + self::step($F, $D, $A, $B, $C, $words[9], 12, 0x8b44f7af); + self::step($F, $C, $D, $A, $B, $words[10], 17, 0xffff5bb1); + self::step($F, $B, $C, $D, $A, $words[11], 22, 0x895cd7be); + self::step($F, $A, $B, $C, $D, $words[12], 7, 0x6b901122); + self::step($F, $D, $A, $B, $C, $words[13], 12, 0xfd987193); + self::step($F, $C, $D, $A, $B, $words[14], 17, 0xa679438e); + self::step($F, $B, $C, $D, $A, $words[15], 22, 0x49b40821); + + /* ROUND 2 */ + self::step($G, $A, $B, $C, $D, $words[1], 5, 0xf61e2562); + self::step($G, $D, $A, $B, $C, $words[6], 9, 0xc040b340); + self::step($G, $C, $D, $A, $B, $words[11], 14, 0x265e5a51); + self::step($G, $B, $C, $D, $A, $words[0], 20, 0xe9b6c7aa); + self::step($G, $A, $B, $C, $D, $words[5], 5, 0xd62f105d); + self::step($G, $D, $A, $B, $C, $words[10], 9, 0x02441453); + self::step($G, $C, $D, $A, $B, $words[15], 14, 0xd8a1e681); + self::step($G, $B, $C, $D, $A, $words[4], 20, 0xe7d3fbc8); + self::step($G, $A, $B, $C, $D, $words[9], 5, 0x21e1cde6); + self::step($G, $D, $A, $B, $C, $words[14], 9, 0xc33707d6); + self::step($G, $C, $D, $A, $B, $words[3], 14, 0xf4d50d87); + self::step($G, $B, $C, $D, $A, $words[8], 20, 0x455a14ed); + self::step($G, $A, $B, $C, $D, $words[13], 5, 0xa9e3e905); + self::step($G, $D, $A, $B, $C, $words[2], 9, 0xfcefa3f8); + self::step($G, $C, $D, $A, $B, $words[7], 14, 0x676f02d9); + self::step($G, $B, $C, $D, $A, $words[12], 20, 0x8d2a4c8a); + + /* ROUND 3 */ + self::step($H, $A, $B, $C, $D, $words[5], 4, 0xfffa3942); + self::step($H, $D, $A, $B, $C, $words[8], 11, 0x8771f681); + self::step($H, $C, $D, $A, $B, $words[11], 16, 0x6d9d6122); + self::step($H, $B, $C, $D, $A, $words[14], 23, 0xfde5380c); + self::step($H, $A, $B, $C, $D, $words[1], 4, 0xa4beea44); + self::step($H, $D, $A, $B, $C, $words[4], 11, 0x4bdecfa9); + self::step($H, $C, $D, $A, $B, $words[7], 16, 0xf6bb4b60); + self::step($H, $B, $C, $D, $A, $words[10], 23, 0xbebfbc70); + self::step($H, $A, $B, $C, $D, $words[13], 4, 0x289b7ec6); + self::step($H, $D, $A, $B, $C, $words[0], 11, 0xeaa127fa); + self::step($H, $C, $D, $A, $B, $words[3], 16, 0xd4ef3085); + self::step($H, $B, $C, $D, $A, $words[6], 23, 0x04881d05); + self::step($H, $A, $B, $C, $D, $words[9], 4, 0xd9d4d039); + self::step($H, $D, $A, $B, $C, $words[12], 11, 0xe6db99e5); + self::step($H, $C, $D, $A, $B, $words[15], 16, 0x1fa27cf8); + self::step($H, $B, $C, $D, $A, $words[2], 23, 0xc4ac5665); + + /* ROUND 4 */ + self::step($I, $A, $B, $C, $D, $words[0], 6, 0xf4292244); + self::step($I, $D, $A, $B, $C, $words[7], 10, 0x432aff97); + self::step($I, $C, $D, $A, $B, $words[14], 15, 0xab9423a7); + self::step($I, $B, $C, $D, $A, $words[5], 21, 0xfc93a039); + self::step($I, $A, $B, $C, $D, $words[12], 6, 0x655b59c3); + self::step($I, $D, $A, $B, $C, $words[3], 10, 0x8f0ccc92); + self::step($I, $C, $D, $A, $B, $words[10], 15, 0xffeff47d); + self::step($I, $B, $C, $D, $A, $words[1], 21, 0x85845dd1); + self::step($I, $A, $B, $C, $D, $words[8], 6, 0x6fa87e4f); + self::step($I, $D, $A, $B, $C, $words[15], 10, 0xfe2ce6e0); + self::step($I, $C, $D, $A, $B, $words[6], 15, 0xa3014314); + self::step($I, $B, $C, $D, $A, $words[13], 21, 0x4e0811a1); + self::step($I, $A, $B, $C, $D, $words[4], 6, 0xf7537e82); + self::step($I, $D, $A, $B, $C, $words[11], 10, 0xbd3af235); + self::step($I, $C, $D, $A, $B, $words[2], 15, 0x2ad7d2bb); + self::step($I, $B, $C, $D, $A, $words[9], 21, 0xeb86d391); + + $this->a = ($this->a + $A); + $this->b = ($this->b + $B); + $this->c = ($this->c + $C); + $this->d = ($this->d + $D); + } + + + private static function F($X, $Y, $Z) + { + return (($X & $Y) | ((~ $X) & $Z)); // X AND Y OR NOT X AND Z + } + + + private static function G($X, $Y, $Z) + { + return (($X & $Z) | ($Y & (~ $Z))); // X AND Z OR Y AND NOT Z + } + + + private static function H($X, $Y, $Z) + { + return ($X ^ $Y ^ $Z); // X XOR Y XOR Z + } + + + private static function I($X, $Y, $Z) + { + return ($Y ^ ($X | (~ $Z))) ; // Y XOR (X OR NOT Z) + } + + + private static function step($func, &$A, $B, $C, $D, $M, $s, $t) + { + $A = ($A + call_user_func($func, $B, $C, $D) + $M + $t); + $A = self::rotate($A, $s); + $A = ($B + $A); + } + + + private static function rotate($decimal, $bits) + { + $binary = str_pad(decbin($decimal), 32, "0", STR_PAD_LEFT); + return bindec(substr($binary, $bits).substr($binary, 0, $bits)); + } } diff --git a/changelog.txt b/changelog.txt index f9c6ab87e..e1497e593 100644 --- a/changelog.txt +++ b/changelog.txt @@ -42,7 +42,7 @@ Fixed in develop branch for release v1.8.0: - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer -- Feature: (trvrnrth) - Add support for reading protected (RC4 encrypted) .xls files (64-bit Linux only) +- Feature: (trvrnrth) Work Item GH-261 - Add support for reading protected (RC4 encrypted) .xls files - Feature: (LWol) Work Item GH-252 - Adding support for macros, Ribbon in Excel 2007 - General: (cdhutch) Work item 20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed - General: (MBaker) - Improve stock chart handling and rendering, with help from Swashata Ghosh From ee03569d72277eaa518b3d6757977fc9cf747f1e Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 1 Dec 2013 11:37:10 +0000 Subject: [PATCH 166/467] General: (infojunkie) Work Item GH-276 - Convert properties to string in OOCalc reader --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index e1497e593..052258f4f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -52,6 +52,7 @@ Fixed in develop branch for release v1.8.0: - General: (dresenhista) Work Item GH-242 - Functionality to getHighestRow() for a specified column, and getHighestColumn() for a specified row - General: (adamriyadi) Work Item GH-247 - Modify PHPExcel_Reader_Excel2007 to use zipClass from PHPExcel_Settings::getZipClass() This allows the use of PCLZip when reading for people that don't have access to ZipArchive +- General: (infojunkie) Work Item GH-276 - Convert properties to string in OOCalc reader Fixed in develop branch for release v1.7.9: From 7a90c5b88802eb10d00f3b9df76c94092bc684a3 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 3 Dec 2013 13:51:40 +0000 Subject: [PATCH 167/467] Mods to handle encrypted files on both 32-bit and 64-bit versions of PHP - currently only tested on 32-bit Windows --- Classes/PHPExcel/Reader/Excel5/MD5.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel5/MD5.php b/Classes/PHPExcel/Reader/Excel5/MD5.php index 3663236bc..6f6e6af6d 100644 --- a/Classes/PHPExcel/Reader/Excel5/MD5.php +++ b/Classes/PHPExcel/Reader/Excel5/MD5.php @@ -174,10 +174,10 @@ public function add($data) self::step($I, $C, $D, $A, $B, $words[2], 15, 0x2ad7d2bb); self::step($I, $B, $C, $D, $A, $words[9], 21, 0xeb86d391); - $this->a = ($this->a + $A); - $this->b = ($this->b + $B); - $this->c = ($this->c + $C); - $this->d = ($this->d + $D); + $this->a = ($this->a + $A) & 0xffffffff; + $this->b = ($this->b + $B) & 0xffffffff; + $this->c = ($this->c + $C) & 0xffffffff; + $this->d = ($this->d + $D) & 0xffffffff; } @@ -207,9 +207,9 @@ private static function I($X, $Y, $Z) private static function step($func, &$A, $B, $C, $D, $M, $s, $t) { - $A = ($A + call_user_func($func, $B, $C, $D) + $M + $t); + $A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & 0xffffffff; $A = self::rotate($A, $s); - $A = ($B + $A); + $A = ($B + $A) & 0xffffffff; } @@ -218,4 +218,4 @@ private static function rotate($decimal, $bits) $binary = str_pad(decbin($decimal), 32, "0", STR_PAD_LEFT); return bindec(substr($binary, $bits).substr($binary, 0, $bits)); } -} +} \ No newline at end of file From b9907446a3146014cdc17761559441b5d2ede1cc Mon Sep 17 00:00:00 2001 From: Eliu Florez Date: Wed, 4 Dec 2013 22:46:55 -0430 Subject: [PATCH 168/467] Update Calculation.php PHPExcel Fatal error: Call to a member function cellExists() line: 3327 --- Classes/PHPExcel/Calculation.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 19e8edd92..4e70972a6 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -3324,7 +3324,8 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
'; $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== NULL) { - if ($this->_workbook->getSheetByName($matches[2])->cellExists($cellRef)) { + $cellSheet = $this->_workbook->getSheetByName($matches[2]); + if ($cellSheet && $cellSheet->cellExists($cellRef)) { $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); $pCell->attach($pCellParent); } else { From e79181cb4d5e7065d645c2a94161c088e7d8d7a3 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 9 Dec 2013 22:33:45 +0000 Subject: [PATCH 169/467] Bugfix: Work Item GH-275 - Insert New Row/Column Before is not correctly updating formula references --- Classes/PHPExcel/ReferenceHelper.php | 13 +++++-------- changelog.txt | 1 + 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 550b7f3f0..e4aa9d8b0 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -431,6 +431,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P while ($cellID = array_pop($aCellCollection)) { $cell = $pSheet->getCell($cellID); $cellIndex = PHPExcel_Cell::columnIndexFromString($cell->getColumn()); + if ($cellIndex-1 + $pNumCols < 0) { continue; } @@ -736,6 +737,7 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo } // Search for cell references (e.g. 'Sheet1'!A3 or C5) with or without $ absolutes (e.g. $A1 or C$5) $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLREF.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + if ($matchCount > 0) { foreach($matches as $match) { $fromString = ($match[2] > '') ? $match[2].'!' : ''; @@ -750,7 +752,7 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; $row = trim($row,'$') + 10000000; - $cellIndex = $column.$row; + $cellIndex = $row . $column; $newCellTokens[$cellIndex] = preg_quote($toString); $cellTokens[$cellIndex] = '/(? 0) { - if ($pNumCols > 0) { - krsort($cellTokens); - krsort($newCellTokens); - } else { - ksort($cellTokens); - ksort($newCellTokens); - } + krsort($cellTokens); + krsort($newCellTokens); // Update cell references in the formula $formulaBlock = str_replace('\\','',preg_replace($cellTokens,$newCellTokens,$formulaBlock)); } diff --git a/changelog.txt b/changelog.txt index 052258f4f..d213be5ed 100644 --- a/changelog.txt +++ b/changelog.txt @@ -39,6 +39,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (IndrekHaav) Work Item CP16208 - Fixed undefined variable error due to $styleArray being used before it's initialised - Bugfix: (PowerKiKi) Work Item GH-273 - ISTEXT() return wrong result if referencing an empty but formatted cell - Bugfix: (PowerKiKi) Work Item GH-270/GH-31 - Binary comparison of strings are case insensitive +- Bugfix: (MBaker) Work Item GH-275 - Insert New Row/Column Before is not correctly updating formula references - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From fcb794e2e210fd3d86cced37ad0105fe8da030ec Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 9 Dec 2013 23:45:45 +0000 Subject: [PATCH 170/467] Bugfix: Work Item GH-275 - Insert New Row/Column Before is not correctly updating formula references --- Classes/PHPExcel/ReferenceHelper.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index e4aa9d8b0..90277c257 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -762,9 +762,13 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo } } if ($adjustCount > 0) { - krsort($cellTokens); - krsort($newCellTokens); - // Update cell references in the formula + if ($pNumCols > 0 || $pNumRows > 0) { + krsort($cellTokens); + krsort($newCellTokens); + } else { + ksort($cellTokens); + ksort($newCellTokens); + } // Update cell references in the formula $formulaBlock = str_replace('\\','',preg_replace($cellTokens,$newCellTokens,$formulaBlock)); } } From 56eae54a4b8ca18f8bc42288cb6ac1a790988e8d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 23 Dec 2013 08:13:12 +0000 Subject: [PATCH 171/467] Minor fix to chart layout --- Classes/PHPExcel/Chart/Layout.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Chart/Layout.php b/Classes/PHPExcel/Chart/Layout.php index 4b2c6af09..8401245c2 100644 --- a/Classes/PHPExcel/Chart/Layout.php +++ b/Classes/PHPExcel/Chart/Layout.php @@ -196,7 +196,7 @@ public function setXMode($value) { * @return string */ public function getYMode() { - return $this->_xMode; + return $this->_yMode; } /** @@ -205,7 +205,7 @@ public function getYMode() { * @param Y-Mode $value */ public function setYMode($value) { - $this->_xMode = $value; + $this->_yMode = $value; } /** From 30070f35c2b8bc10926e234c70fec3c4a5ec158b Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 28 Dec 2013 13:40:24 +0000 Subject: [PATCH 172/467] Bugfix: Work Item GH-257 - Passing an array of cells to _generateRow() in the HTML/PDF Writer causes caching problems with last cell in the range --- Classes/PHPExcel/Writer/HTML.php | 6 +++--- changelog.txt | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index e0a2d784f..a003b6d2f 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -428,7 +428,7 @@ public function generateSheetData() { while($column++ < $dimension[1][0]) { // Cell exists? if ($sheet->cellExistsByColumnAndRow($column, $row)) { - $rowData[$column] = $sheet->getCellByColumnAndRow($column, $row); + $rowData[$column] = PHPExcel_Cell::stringFromColumnIndex($column) . $row; } else { $rowData[$column] = ''; } @@ -1114,9 +1114,9 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow // Write cells $colNum = 0; - foreach ($pValues as $cell) { + foreach ($pValues as $cellAddress) { + $cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : ''; $coordinate = PHPExcel_Cell::stringFromColumnIndex($colNum) . ($pRow + 1); - if (!$this->_useInlineCss) { $cssClass = ''; $cssClass = 'column' . $colNum; diff --git a/changelog.txt b/changelog.txt index d213be5ed..db0bc146d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -40,6 +40,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (PowerKiKi) Work Item GH-273 - ISTEXT() return wrong result if referencing an empty but formatted cell - Bugfix: (PowerKiKi) Work Item GH-270/GH-31 - Binary comparison of strings are case insensitive - Bugfix: (MBaker) Work Item GH-275 - Insert New Row/Column Before is not correctly updating formula references +- Bugfix: (MBaker) Work Item GH-257 - Passing an array of cells to _generateRow() in the HTML/PDF Writer causes caching problems with last cell in the range - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From 2bcaa01eccebb306a8b7f13b06242398740785dd Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 29 Dec 2013 23:48:42 +0000 Subject: [PATCH 173/467] Bugfix: Work Item GH-193 - Fix to empty worksheet garbage collection when using cell caching --- Classes/PHPExcel/CachedObjectStorage/APC.php | 2 +- Classes/PHPExcel/CachedObjectStorage/DiscISAM.php | 2 +- Classes/PHPExcel/CachedObjectStorage/Igbinary.php | 2 +- Classes/PHPExcel/CachedObjectStorage/Memcache.php | 2 +- Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php | 2 +- Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php | 2 +- Classes/PHPExcel/CachedObjectStorage/PHPTemp.php | 2 +- Classes/PHPExcel/CachedObjectStorage/SQLite.php | 2 +- Classes/PHPExcel/CachedObjectStorage/SQLite3.php | 2 +- Classes/PHPExcel/CachedObjectStorage/Wincache.php | 2 +- changelog.txt | 1 + 11 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/APC.php b/Classes/PHPExcel/CachedObjectStorage/APC.php index 55454fa03..3a6b53d06 100644 --- a/Classes/PHPExcel/CachedObjectStorage/APC.php +++ b/Classes/PHPExcel/CachedObjectStorage/APC.php @@ -61,7 +61,7 @@ class PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_Cach * @throws PHPExcel_Exception */ protected function _storeData() { - if ($this->_currentCellIsDirty) { + if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { $this->_currentObject->detach(); if (!apc_store($this->_cachePrefix.$this->_currentObjectID.'.cache',serialize($this->_currentObject),$this->_cacheTime)) { diff --git a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php index 1a319d0f7..5afc26b50 100644 --- a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php +++ b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php @@ -65,7 +65,7 @@ class PHPExcel_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage * @throws PHPExcel_Exception */ protected function _storeData() { - if ($this->_currentCellIsDirty) { + if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { $this->_currentObject->detach(); fseek($this->_fileHandle,0,SEEK_END); diff --git a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php index 6af87b3e7..aaee0217b 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php +++ b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php @@ -43,7 +43,7 @@ class PHPExcel_CachedObjectStorage_Igbinary extends PHPExcel_CachedObjectStorage * @throws PHPExcel_Exception */ protected function _storeData() { - if ($this->_currentCellIsDirty) { + if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { $this->_currentObject->detach(); $this->_cellCache[$this->_currentObjectID] = igbinary_serialize($this->_currentObject); diff --git a/Classes/PHPExcel/CachedObjectStorage/Memcache.php b/Classes/PHPExcel/CachedObjectStorage/Memcache.php index 2c33050ce..27ffc195e 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memcache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memcache.php @@ -65,7 +65,7 @@ class PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage * @throws PHPExcel_Exception */ protected function _storeData() { - if ($this->_currentCellIsDirty) { + if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { $this->_currentObject->detach(); $obj = serialize($this->_currentObject); diff --git a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php index f8a779161..7327dc14b 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php @@ -43,7 +43,7 @@ class PHPExcel_CachedObjectStorage_MemoryGZip extends PHPExcel_CachedObjectStora * @throws PHPExcel_Exception */ protected function _storeData() { - if ($this->_currentCellIsDirty) { + if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { $this->_currentObject->detach(); $this->_cellCache[$this->_currentObjectID] = gzdeflate(serialize($this->_currentObject)); diff --git a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php index 9825cabf9..12c9b589d 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php @@ -43,7 +43,7 @@ class PHPExcel_CachedObjectStorage_MemorySerialized extends PHPExcel_CachedObjec * @throws PHPExcel_Exception */ protected function _storeData() { - if ($this->_currentCellIsDirty) { + if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { $this->_currentObject->detach(); $this->_cellCache[$this->_currentObjectID] = serialize($this->_currentObject); diff --git a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php index 61fb41603..9078b3757 100644 --- a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php +++ b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php @@ -57,7 +57,7 @@ class PHPExcel_CachedObjectStorage_PHPTemp extends PHPExcel_CachedObjectStorage_ * @throws PHPExcel_Exception */ protected function _storeData() { - if ($this->_currentCellIsDirty) { + if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { $this->_currentObject->detach(); fseek($this->_fileHandle,0,SEEK_END); diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php index 1b0221ee1..3585f7599 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php @@ -57,7 +57,7 @@ class PHPExcel_CachedObjectStorage_SQLite extends PHPExcel_CachedObjectStorage_C * @throws PHPExcel_Exception */ protected function _storeData() { - if ($this->_currentCellIsDirty) { + if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { $this->_currentObject->detach(); if (!$this->_DBHandle->queryExec("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES('".$this->_currentObjectID."','".sqlite_escape_string(serialize($this->_currentObject))."')")) diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index 7e6924770..187b83f70 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -85,7 +85,7 @@ class PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_ * @throws PHPExcel_Exception */ protected function _storeData() { - if ($this->_currentCellIsDirty) { + if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { $this->_currentObject->detach(); $this->_insertQuery->bindValue('id',$this->_currentObjectID,SQLITE3_TEXT); diff --git a/Classes/PHPExcel/CachedObjectStorage/Wincache.php b/Classes/PHPExcel/CachedObjectStorage/Wincache.php index af31eb7d4..c4fbd371c 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Wincache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Wincache.php @@ -58,7 +58,7 @@ class PHPExcel_CachedObjectStorage_Wincache extends PHPExcel_CachedObjectStorage * @throws PHPExcel_Exception */ protected function _storeData() { - if ($this->_currentCellIsDirty) { + if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { $this->_currentObject->detach(); $obj = serialize($this->_currentObject); diff --git a/changelog.txt b/changelog.txt index db0bc146d..9c8841422 100644 --- a/changelog.txt +++ b/changelog.txt @@ -41,6 +41,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (PowerKiKi) Work Item GH-270/GH-31 - Binary comparison of strings are case insensitive - Bugfix: (MBaker) Work Item GH-275 - Insert New Row/Column Before is not correctly updating formula references - Bugfix: (MBaker) Work Item GH-257 - Passing an array of cells to _generateRow() in the HTML/PDF Writer causes caching problems with last cell in the range +- Bugfix: (MBaker) Work Item GH-193 - Fix to empty worksheet garbage collection when using cell caching - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From 8cd6f56fdd8fcf50c6351399ab5f32bb5e97bb2f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 30 Dec 2013 22:19:05 +0000 Subject: [PATCH 174/467] Bugfix: (Jazzo) Work Item GH-248 - Excel2007 does not correctly mark rows as hidden --- Classes/PHPExcel/Reader/Excel2007.php | 6 +++--- changelog.txt | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 74322a18d..893a097c5 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -762,7 +762,7 @@ public function load($pFilename) if (isset($xmlSheet->cols) && !$this->_readDataOnly) { foreach ($xmlSheet->cols->col as $col) { - for ($i = intval($col["min"]) - 1; $i < intval($col["max"]); ++$i) { + for ($i = intval($col["min"]) - 1; $i < intval($col["max"]); ++$i) { if ($col["style"] && !$this->_readDataOnly) { $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setXfIndex(intval($col["style"])); } @@ -2057,9 +2057,9 @@ private static function toCSSArray($style) { private static function boolean($value = NULL) { - if (is_numeric($value)) { + if (is_numeric($value) || is_object($value)) { return (bool) $value; - } + } return ($value === 'true' || $value === 'TRUE') ? TRUE : FALSE; } } diff --git a/changelog.txt b/changelog.txt index 9c8841422..4a1d922f2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -42,6 +42,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (MBaker) Work Item GH-275 - Insert New Row/Column Before is not correctly updating formula references - Bugfix: (MBaker) Work Item GH-257 - Passing an array of cells to _generateRow() in the HTML/PDF Writer causes caching problems with last cell in the range - Bugfix: (MBaker) Work Item GH-193 - Fix to empty worksheet garbage collection when using cell caching +- Bugfix: (Jazzo) Work Item GH-248 - Excel2007 does not correctly mark rows as hidden - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From 19fc61114d970f8e39f0663ad71474f49d5ba30d Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 30 Dec 2013 22:27:40 +0000 Subject: [PATCH 175/467] Bugfix: (Roy Shahbazian) Work Item GH-299 - Fixed typo in Chart/Layout set/getYMode() --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 4a1d922f2..ea8c98e03 100644 --- a/changelog.txt +++ b/changelog.txt @@ -43,6 +43,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (MBaker) Work Item GH-257 - Passing an array of cells to _generateRow() in the HTML/PDF Writer causes caching problems with last cell in the range - Bugfix: (MBaker) Work Item GH-193 - Fix to empty worksheet garbage collection when using cell caching - Bugfix: (Jazzo) Work Item GH-248 - Excel2007 does not correctly mark rows as hidden +- Bugfix: (Roy Shahbazian) Work Item GH-299 - Fixed typo in Chart/Layout set/getYMode() - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From dc97d2f46b04be5e87a90eff770750fff8de02bc Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 30 Dec 2013 23:44:42 +0000 Subject: [PATCH 176/467] Improve fluent interface in charting methods --- Classes/PHPExcel/Chart/DataSeries.php | 10 +++++++++ Classes/PHPExcel/Chart/Layout.php | 30 ++++++++++++++++++++++++++- Classes/PHPExcel/Chart/PlotArea.php | 3 +++ Classes/PHPExcel/Chart/Title.php | 3 +++ Examples/runall.php | 1 + 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index 0822de3fd..92588c7f9 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -170,9 +170,11 @@ public function getPlotType() { * Set Plot Type * * @param string $plotType + * @return PHPExcel_Chart_DataSeries */ public function setPlotType($plotType = '') { $this->_plotType = $plotType; + return $this; } /** @@ -188,9 +190,11 @@ public function getPlotGrouping() { * Set Plot Grouping Type * * @param string $groupingType + * @return PHPExcel_Chart_DataSeries */ public function setPlotGrouping($groupingType = null) { $this->_plotGrouping = $groupingType; + return $this; } /** @@ -206,9 +210,11 @@ public function getPlotDirection() { * Set Plot Direction * * @param string $plotDirection + * @return PHPExcel_Chart_DataSeries */ public function setPlotDirection($plotDirection = null) { $this->_plotDirection = $plotDirection; + return $this; } /** @@ -281,9 +287,11 @@ public function getPlotStyle() { * Set Plot Style * * @param string $plotStyle + * @return PHPExcel_Chart_DataSeries */ public function setPlotStyle($plotStyle = null) { $this->_plotStyle = $plotStyle; + return $this; } /** @@ -332,9 +340,11 @@ public function getSmoothLine() { * Set Smooth Line * * @param boolean $smoothLine + * @return PHPExcel_Chart_DataSeries */ public function setSmoothLine($smoothLine = TRUE) { $this->_smoothLine = $smoothLine; + return $this; } public function refresh(PHPExcel_Worksheet $worksheet) { diff --git a/Classes/PHPExcel/Chart/Layout.php b/Classes/PHPExcel/Chart/Layout.php index 8401245c2..7c37ef926 100644 --- a/Classes/PHPExcel/Chart/Layout.php +++ b/Classes/PHPExcel/Chart/Layout.php @@ -167,9 +167,11 @@ public function getLayoutTarget() { * Set Layout Target * * @param Layout Target $value + * @return PHPExcel_Chart_Layout */ public function setLayoutTarget($value) { $this->_layoutTarget = $value; + return $this; } /** @@ -185,9 +187,11 @@ public function getXMode() { * Set X-Mode * * @param X-Mode $value + * @return PHPExcel_Chart_Layout */ public function setXMode($value) { $this->_xMode = $value; + return $this; } /** @@ -203,9 +207,11 @@ public function getYMode() { * Set Y-Mode * * @param Y-Mode $value + * @return PHPExcel_Chart_Layout */ public function setYMode($value) { $this->_yMode = $value; + return $this; } /** @@ -221,9 +227,11 @@ public function getXPosition() { * Set X-Position * * @param X-Position $value + * @return PHPExcel_Chart_Layout */ public function setXPosition($value) { $this->_xPos = $value; + return $this; } /** @@ -239,9 +247,11 @@ public function getYPosition() { * Set Y-Position * * @param Y-Position $value + * @return PHPExcel_Chart_Layout */ public function setYPosition($value) { $this->_yPos = $value; + return $this; } /** @@ -257,9 +267,11 @@ public function getWidth() { * Set Width * * @param Width $value + * @return PHPExcel_Chart_Layout */ public function setWidth($value) { $this->_width = $value; + return $this; } /** @@ -275,9 +287,11 @@ public function getHeight() { * Set Height * * @param Height $value + * @return PHPExcel_Chart_Layout */ public function setHeight($value) { $this->_height = $value; + return $this; } @@ -295,9 +309,11 @@ public function getShowLegendKey() { * Specifies that legend keys should be shown in data labels. * * @param boolean $value Show legend key + * @return PHPExcel_Chart_Layout */ public function setShowLegendKey($value) { $this->_showLegendKey = $value; + return $this; } /** @@ -314,9 +330,11 @@ public function getShowVal() { * Specifies that the value should be shown in data labels. * * @param boolean $value Show val + * @return PHPExcel_Chart_Layout */ public function setShowVal($value) { $this->_showVal = $value; + return $this; } /** @@ -333,9 +351,11 @@ public function getShowCatName() { * Specifies that the category name should be shown in data labels. * * @param boolean $value Show cat name + * @return PHPExcel_Chart_Layout */ public function setShowCatName($value) { $this->_showCatName = $value; + return $this; } /** @@ -351,10 +371,12 @@ public function getShowSerName() { * Set show ser name * Specifies that the series name should be shown in data labels. * - * @param boolean $value Show ser name + * @param boolean $value Show series name + * @return PHPExcel_Chart_Layout */ public function setShowSerName($value) { $this->_showSerName = $value; + return $this; } /** @@ -371,9 +393,11 @@ public function getShowPercent() { * Specifies that the percentage should be shown in data labels. * * @param boolean $value Show percentage + * @return PHPExcel_Chart_Layout */ public function setShowPercent($value) { $this->_showPercent = $value; + return $this; } /** @@ -390,9 +414,11 @@ public function getShowBubbleSize() { * Specifies that the bubble size should be shown in data labels. * * @param boolean $value Show bubble size + * @return PHPExcel_Chart_Layout */ public function setShowBubbleSize($value) { $this->_showBubbleSize = $value; + return $this; } /** @@ -409,9 +435,11 @@ public function getShowLeaderLines() { * Specifies that leader lines should be shown in data labels. * * @param boolean $value Show leader lines + * @return PHPExcel_Chart_Layout */ public function setShowLeaderLines($value) { $this->_showLeaderLines = $value; + return $this; } } diff --git a/Classes/PHPExcel/Chart/PlotArea.php b/Classes/PHPExcel/Chart/PlotArea.php index 2975c0936..cc512cdef 100644 --- a/Classes/PHPExcel/Chart/PlotArea.php +++ b/Classes/PHPExcel/Chart/PlotArea.php @@ -111,9 +111,12 @@ public function getPlotGroupByIndex($index) { * Set Plot Series * * @param [PHPExcel_Chart_DataSeries] + * @return PHPExcel_Chart_PlotArea */ public function setPlotSeries($plotSeries = array()) { $this->_plotSeries = $plotSeries; + + return $this; } public function refresh(PHPExcel_Worksheet $worksheet) { diff --git a/Classes/PHPExcel/Chart/Title.php b/Classes/PHPExcel/Chart/Title.php index cacfae34d..0883a2197 100644 --- a/Classes/PHPExcel/Chart/Title.php +++ b/Classes/PHPExcel/Chart/Title.php @@ -72,9 +72,12 @@ public function getCaption() { * Set caption * * @param string $caption + * @return PHPExcel_Chart_Title */ public function setCaption($caption = null) { $this->_caption = $caption; + + return $this; } /** diff --git a/Examples/runall.php b/Examples/runall.php index 4d2e207f2..d41249399 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -92,6 +92,7 @@ , '34chartupdate.php' , '35chartrender.php' , '36chartreadwriteHTML.php' + , '36chartreadwritePDF.php' , '37page_layout_view.php' , '38cloneWorksheet.php' , '40duplicateStyle.php' From 70892b93c80a687c51847d0f05a73f066f0b422b Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 31 Dec 2013 00:06:56 +0000 Subject: [PATCH 177/467] Bugfix: (EliuFlorez) Work item GH-279 - Fatal error: Call to a member function cellExists() line: 3327 in calculation.php if referenced worksheet doesn't exist --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index ea8c98e03..658fd1c85 100644 --- a/changelog.txt +++ b/changelog.txt @@ -44,6 +44,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (MBaker) Work Item GH-193 - Fix to empty worksheet garbage collection when using cell caching - Bugfix: (Jazzo) Work Item GH-248 - Excel2007 does not correctly mark rows as hidden - Bugfix: (Roy Shahbazian) Work Item GH-299 - Fixed typo in Chart/Layout set/getYMode() +- Bugfix: (EliuFlorez) Work item GH-279 - Fatal error: Call to a member function cellExists() line: 3327 in calculation.php if referenced worksheet doesn't exist - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From 93b3b8eed2114a96dcfe67b5100060f43eb511b0 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 31 Dec 2013 01:13:06 +0000 Subject: [PATCH 178/467] Bugfix: Work Item GH-290 - AdvancedValueBinder "Division by zero"-error --- Classes/PHPExcel/Cell/AdvancedValueBinder.php | 2 +- changelog.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Cell/AdvancedValueBinder.php b/Classes/PHPExcel/Cell/AdvancedValueBinder.php index d6c043306..bb3c88220 100644 --- a/Classes/PHPExcel/Cell/AdvancedValueBinder.php +++ b/Classes/PHPExcel/Cell/AdvancedValueBinder.php @@ -80,7 +80,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) } // Check for fraction - if (preg_match('/^([+-]?) *([0-9]*)\s?\/\s*([0-9]*)$/', $value, $matches)) { + if (preg_match('/^([+-]?)\s*([0-9]+)\s?\/\s*([0-9]+)$/', $value, $matches)) { // Convert value to number $value = $matches[2] / $matches[3]; if ($matches[1] == '-') $value = 0 - $value; diff --git a/changelog.txt b/changelog.txt index 658fd1c85..96f97c6de 100644 --- a/changelog.txt +++ b/changelog.txt @@ -45,6 +45,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (Jazzo) Work Item GH-248 - Excel2007 does not correctly mark rows as hidden - Bugfix: (Roy Shahbazian) Work Item GH-299 - Fixed typo in Chart/Layout set/getYMode() - Bugfix: (EliuFlorez) Work item GH-279 - Fatal error: Call to a member function cellExists() line: 3327 in calculation.php if referenced worksheet doesn't exist +- Bugfix: (MBaker) Work Item GH-290 - AdvancedValueBinder "Division by zero"-error - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From 992aee683ac0e9f8acfa12a52a4f3cc19a9e3808 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 31 Dec 2013 18:36:33 +0000 Subject: [PATCH 179/467] Update to copyright year in file headers --- Classes/PHPExcel.php | 6 +++--- Classes/PHPExcel/Autoloader.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/APC.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/CacheBase.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/DiscISAM.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/ICache.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/Igbinary.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/Memcache.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/Memory.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/PHPTemp.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/SQLite.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/SQLite3.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/Wincache.php | 6 +++--- Classes/PHPExcel/CachedObjectStorageFactory.php | 6 +++--- Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php | 6 +++--- Classes/PHPExcel/CalcEngine/Logger.php | 6 +++--- Classes/PHPExcel/Calculation.php | 6 +++--- Classes/PHPExcel/Calculation/Database.php | 6 +++--- Classes/PHPExcel/Calculation/DateTime.php | 6 +++--- Classes/PHPExcel/Calculation/Engineering.php | 6 +++--- Classes/PHPExcel/Calculation/Exception.php | 6 +++--- Classes/PHPExcel/Calculation/ExceptionHandler.php | 6 +++--- Classes/PHPExcel/Calculation/Financial.php | 6 +++--- Classes/PHPExcel/Calculation/FormulaParser.php | 6 +++--- Classes/PHPExcel/Calculation/FormulaToken.php | 6 +++--- Classes/PHPExcel/Calculation/Function.php | 6 +++--- Classes/PHPExcel/Calculation/Functions.php | 6 +++--- Classes/PHPExcel/Calculation/Logical.php | 6 +++--- Classes/PHPExcel/Calculation/LookupRef.php | 6 +++--- Classes/PHPExcel/Calculation/MathTrig.php | 6 +++--- Classes/PHPExcel/Calculation/Statistical.php | 6 +++--- Classes/PHPExcel/Calculation/TextData.php | 6 +++--- Classes/PHPExcel/Calculation/Token/Stack.php | 6 +++--- Classes/PHPExcel/Cell.php | 6 +++--- Classes/PHPExcel/Cell/AdvancedValueBinder.php | 6 +++--- Classes/PHPExcel/Cell/DataType.php | 6 +++--- Classes/PHPExcel/Cell/DataValidation.php | 6 +++--- Classes/PHPExcel/Cell/DefaultValueBinder.php | 6 +++--- Classes/PHPExcel/Cell/Hyperlink.php | 6 +++--- Classes/PHPExcel/Cell/IValueBinder.php | 6 +++--- Classes/PHPExcel/Chart.php | 6 +++--- Classes/PHPExcel/Chart/DataSeries.php | 6 +++--- Classes/PHPExcel/Chart/DataSeriesValues.php | 6 +++--- Classes/PHPExcel/Chart/Exception.php | 6 +++--- Classes/PHPExcel/Chart/Layout.php | 6 +++--- Classes/PHPExcel/Chart/Legend.php | 6 +++--- Classes/PHPExcel/Chart/PlotArea.php | 6 +++--- Classes/PHPExcel/Chart/Renderer/jpgraph.php | 6 +++--- Classes/PHPExcel/Chart/Title.php | 6 +++--- Classes/PHPExcel/Comment.php | 6 +++--- Classes/PHPExcel/DocumentProperties.php | 6 +++--- Classes/PHPExcel/DocumentSecurity.php | 6 +++--- Classes/PHPExcel/Exception.php | 6 +++--- Classes/PHPExcel/HashTable.php | 6 +++--- Classes/PHPExcel/IComparable.php | 4 ++-- Classes/PHPExcel/IOFactory.php | 6 +++--- Classes/PHPExcel/NamedRange.php | 6 +++--- Classes/PHPExcel/Reader/Abstract.php | 6 +++--- Classes/PHPExcel/Reader/CSV.php | 6 +++--- Classes/PHPExcel/Reader/DefaultReadFilter.php | 6 +++--- Classes/PHPExcel/Reader/Excel2003XML.php | 8 ++++---- Classes/PHPExcel/Reader/Excel2007.php | 6 +++--- Classes/PHPExcel/Reader/Excel2007/Chart.php | 6 +++--- Classes/PHPExcel/Reader/Excel2007/Theme.php | 6 +++--- Classes/PHPExcel/Reader/Excel5.php | 6 +++--- Classes/PHPExcel/Reader/Excel5/Escher.php | 6 +++--- Classes/PHPExcel/Reader/Excel5/MD5.php | 6 +++--- Classes/PHPExcel/Reader/Excel5/RC4.php | 6 +++--- Classes/PHPExcel/Reader/Exception.php | 6 +++--- Classes/PHPExcel/Reader/Gnumeric.php | 6 +++--- Classes/PHPExcel/Reader/HTML.php | 6 +++--- Classes/PHPExcel/Reader/IReadFilter.php | 6 +++--- Classes/PHPExcel/Reader/IReader.php | 6 +++--- Classes/PHPExcel/Reader/OOCalc.php | 6 +++--- Classes/PHPExcel/Reader/SYLK.php | 6 +++--- Classes/PHPExcel/ReferenceHelper.php | 6 +++--- Classes/PHPExcel/RichText.php | 6 +++--- Classes/PHPExcel/RichText/ITextElement.php | 4 ++-- Classes/PHPExcel/RichText/Run.php | 4 ++-- Classes/PHPExcel/RichText/TextElement.php | 4 ++-- Classes/PHPExcel/Settings.php | 4 ++-- Classes/PHPExcel/Shared/CodePage.php | 6 +++--- Classes/PHPExcel/Shared/Date.php | 6 +++--- Classes/PHPExcel/Shared/Drawing.php | 6 +++--- Classes/PHPExcel/Shared/Escher.php | 6 +++--- Classes/PHPExcel/Shared/Escher/DgContainer.php | 6 +++--- .../PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php | 6 +++--- .../Escher/DgContainer/SpgrContainer/SpContainer.php | 6 +++--- Classes/PHPExcel/Shared/Escher/DggContainer.php | 6 +++--- .../Shared/Escher/DggContainer/BstoreContainer.php | 6 +++--- .../Shared/Escher/DggContainer/BstoreContainer/BSE.php | 6 +++--- .../Escher/DggContainer/BstoreContainer/BSE/Blip.php | 6 +++--- Classes/PHPExcel/Shared/Excel5.php | 6 +++--- Classes/PHPExcel/Shared/File.php | 6 +++--- Classes/PHPExcel/Shared/Font.php | 6 +++--- Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php | 2 +- Classes/PHPExcel/Shared/OLERead.php | 4 ++-- Classes/PHPExcel/Shared/PasswordHasher.php | 6 +++--- Classes/PHPExcel/Shared/String.php | 6 +++--- Classes/PHPExcel/Shared/TimeZone.php | 6 +++--- Classes/PHPExcel/Shared/XMLWriter.php | 6 +++--- Classes/PHPExcel/Shared/ZipArchive.php | 6 +++--- Classes/PHPExcel/Shared/ZipStreamWrapper.php | 6 +++--- Classes/PHPExcel/Shared/trend/bestFitClass.php | 6 +++--- Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php | 6 +++--- Classes/PHPExcel/Shared/trend/linearBestFitClass.php | 6 +++--- Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php | 6 +++--- Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php | 6 +++--- Classes/PHPExcel/Shared/trend/powerBestFitClass.php | 6 +++--- Classes/PHPExcel/Shared/trend/trendClass.php | 6 +++--- Classes/PHPExcel/Style.php | 6 +++--- Classes/PHPExcel/Style/Alignment.php | 6 +++--- Classes/PHPExcel/Style/Border.php | 6 +++--- Classes/PHPExcel/Style/Borders.php | 6 +++--- Classes/PHPExcel/Style/Color.php | 6 +++--- Classes/PHPExcel/Style/Conditional.php | 6 +++--- Classes/PHPExcel/Style/Fill.php | 6 +++--- Classes/PHPExcel/Style/Font.php | 6 +++--- Classes/PHPExcel/Style/NumberFormat.php | 6 +++--- Classes/PHPExcel/Style/Protection.php | 6 +++--- Classes/PHPExcel/Style/Supervisor.php | 6 +++--- Classes/PHPExcel/Worksheet.php | 6 +++--- Classes/PHPExcel/Worksheet/AutoFilter.php | 6 +++--- Classes/PHPExcel/Worksheet/AutoFilter/Column.php | 6 +++--- Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php | 6 +++--- Classes/PHPExcel/Worksheet/BaseDrawing.php | 6 +++--- Classes/PHPExcel/Worksheet/CellIterator.php | 6 +++--- Classes/PHPExcel/Worksheet/ColumnDimension.php | 6 +++--- Classes/PHPExcel/Worksheet/Drawing.php | 6 +++--- Classes/PHPExcel/Worksheet/Drawing/Shadow.php | 6 +++--- Classes/PHPExcel/Worksheet/HeaderFooter.php | 6 +++--- Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php | 6 +++--- Classes/PHPExcel/Worksheet/MemoryDrawing.php | 6 +++--- Classes/PHPExcel/Worksheet/PageMargins.php | 6 +++--- Classes/PHPExcel/Worksheet/PageSetup.php | 6 +++--- Classes/PHPExcel/Worksheet/Protection.php | 6 +++--- Classes/PHPExcel/Worksheet/Row.php | 6 +++--- Classes/PHPExcel/Worksheet/RowDimension.php | 6 +++--- Classes/PHPExcel/Worksheet/RowIterator.php | 6 +++--- Classes/PHPExcel/Worksheet/SheetView.php | 6 +++--- Classes/PHPExcel/WorksheetIterator.php | 6 +++--- Classes/PHPExcel/Writer/Abstract.php | 6 +++--- Classes/PHPExcel/Writer/CSV.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Chart.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Comments.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/ContentTypes.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/DocProps.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Drawing.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Rels.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/RelsVBA.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/StringTable.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Style.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Theme.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Workbook.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/Worksheet.php | 6 +++--- Classes/PHPExcel/Writer/Excel2007/WriterPart.php | 6 +++--- Classes/PHPExcel/Writer/Excel5.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/BIFFwriter.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Escher.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Font.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Parser.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Workbook.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 6 +++--- Classes/PHPExcel/Writer/Excel5/Xf.php | 6 +++--- Classes/PHPExcel/Writer/Exception.php | 6 +++--- Classes/PHPExcel/Writer/HTML.php | 6 +++--- Classes/PHPExcel/Writer/IWriter.php | 6 +++--- Classes/PHPExcel/Writer/PDF.php | 6 +++--- Classes/PHPExcel/Writer/PDF/Core.php | 6 +++--- Classes/PHPExcel/Writer/PDF/DomPDF.php | 6 +++--- Classes/PHPExcel/Writer/PDF/mPDF.php | 6 +++--- Classes/PHPExcel/Writer/PDF/tcPDF.php | 6 +++--- Examples/01pharSimple.php | 4 ++-- Examples/01simple-download-pdf.php | 4 ++-- Examples/01simple-download-xls.php | 4 ++-- Examples/01simple-download-xlsx.php | 4 ++-- Examples/01simple.php | 4 ++-- Examples/01simplePCLZip.php | 4 ++-- Examples/02types-xls.php | 4 ++-- Examples/02types.php | 4 ++-- Examples/03formulas.php | 4 ++-- Examples/04printing.php | 4 ++-- Examples/05featuredemo.inc.php | 4 ++-- Examples/05featuredemo.php | 4 ++-- Examples/06largescale-with-cellcaching-sqlite.php | 4 ++-- Examples/06largescale-with-cellcaching-sqlite3.php | 4 ++-- Examples/06largescale-with-cellcaching.php | 4 ++-- Examples/06largescale-xls.php | 4 ++-- Examples/06largescale.php | 4 ++-- Examples/07reader.php | 4 ++-- Examples/07readerPCLZip.php | 4 ++-- Examples/08conditionalformatting.php | 4 ++-- Examples/08conditionalformatting2.php | 4 ++-- Examples/09pagebreaks.php | 6 +++--- Examples/10autofilter-selection-1.php | 4 ++-- Examples/10autofilter-selection-2.php | 4 ++-- Examples/10autofilter-selection-display.php | 4 ++-- Examples/10autofilter.php | 4 ++-- Examples/11documentsecurity-xls.php | 4 ++-- Examples/11documentsecurity.php | 4 ++-- Examples/12cellProtection.php | 4 ++-- Examples/13calculation.php | 4 ++-- Examples/14excel5.php | 4 ++-- Examples/15datavalidation-xls.php | 4 ++-- Examples/15datavalidation.php | 4 ++-- Examples/16csv.php | 4 ++-- Examples/17html.php | 4 ++-- Examples/18extendedcalculation.php | 4 ++-- Examples/19namedrange.php | 4 ++-- Examples/20readexcel5.php | 4 ++-- Examples/21pdf.php | 4 ++-- Examples/22heavilyformatted.php | 4 ++-- Examples/23sharedstyles.php | 4 ++-- Examples/24readfilter.php | 4 ++-- Examples/25inmemoryimage.php | 4 ++-- Examples/26utf8.php | 4 ++-- Examples/27imagesexcel5.php | 4 ++-- Examples/28iterator.php | 4 ++-- Examples/29advancedvaluebinder.php | 4 ++-- Examples/30template.php | 4 ++-- Examples/31docproperties_write-xls.php | 4 ++-- Examples/31docproperties_write.php | 4 ++-- Examples/32chartreadwrite.php | 4 ++-- Examples/33chartcreate-area.php | 4 ++-- Examples/33chartcreate-bar-stacked.php | 4 ++-- Examples/33chartcreate-bar.php | 4 ++-- Examples/33chartcreate-column-2.php | 4 ++-- Examples/33chartcreate-column.php | 4 ++-- Examples/33chartcreate-composite.php | 4 ++-- Examples/33chartcreate-line.php | 4 ++-- Examples/33chartcreate-multiple-charts.php | 4 ++-- Examples/33chartcreate-pie.php | 4 ++-- Examples/33chartcreate-radar.php | 4 ++-- Examples/33chartcreate-scatter.php | 4 ++-- Examples/33chartcreate-stock.php | 4 ++-- Examples/34chartupdate.php | 4 ++-- Examples/35chartrender.php | 4 ++-- Examples/36chartreadwriteHTML.php | 4 ++-- Examples/36chartreadwritePDF.php | 4 ++-- Examples/37page_layout_view.php | 4 ++-- Examples/38cloneWorksheet.php | 4 ++-- Examples/Excel2003XMLReader.php | 4 ++-- Examples/GnumericReader.php | 4 ++-- Examples/OOCalcReader.php | 4 ++-- Examples/OOCalcReaderPCLZip.php | 4 ++-- Examples/SylkReader.php | 4 ++-- Examples/XMLReader.php | 4 ++-- Examples/runall.php | 4 ++-- unitTests/bootstrap.php | 2 +- 253 files changed, 675 insertions(+), 675 deletions(-) diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index c71ee5f60..29d0aa0f4 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -38,7 +38,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel { diff --git a/Classes/PHPExcel/Autoloader.php b/Classes/PHPExcel/Autoloader.php index 3878a0919..221666f99 100644 --- a/Classes/PHPExcel/Autoloader.php +++ b/Classes/PHPExcel/Autoloader.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Autoloader { diff --git a/Classes/PHPExcel/CachedObjectStorage/APC.php b/Classes/PHPExcel/CachedObjectStorage/APC.php index 3a6b53d06..c256919da 100644 --- a/Classes/PHPExcel/CachedObjectStorage/APC.php +++ b/Classes/PHPExcel/CachedObjectStorage/APC.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index 81afb7acd..5e1b17976 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_CachedObjectStorage_CacheBase { diff --git a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php index 5afc26b50..0ae2151a7 100644 --- a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php +++ b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/ICache.php b/Classes/PHPExcel/CachedObjectStorage/ICache.php index 15d96d863..7686f3c4b 100644 --- a/Classes/PHPExcel/CachedObjectStorage/ICache.php +++ b/Classes/PHPExcel/CachedObjectStorage/ICache.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php index aaee0217b..e20d9a828 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php +++ b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_Igbinary extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/Memcache.php b/Classes/PHPExcel/CachedObjectStorage/Memcache.php index 27ffc195e..35f3d5968 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memcache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memcache.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/Memory.php b/Classes/PHPExcel/CachedObjectStorage/Memory.php index dd01bc3b7..1319a18de 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memory.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memory.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php index 7327dc14b..f98f0372d 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_MemoryGZip extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php index 12c9b589d..ef597b789 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_MemorySerialized extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php index 9078b3757..fb0c85ed2 100644 --- a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php +++ b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_PHPTemp extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php index 3585f7599..bcaf011b7 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_SQLite extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index 187b83f70..4446c5604 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorage/Wincache.php b/Classes/PHPExcel/CachedObjectStorage/Wincache.php index c4fbd371c..a6968566c 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Wincache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Wincache.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorage_Wincache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { diff --git a/Classes/PHPExcel/CachedObjectStorageFactory.php b/Classes/PHPExcel/CachedObjectStorageFactory.php index b5c4f7e14..2da92346e 100644 --- a/Classes/PHPExcel/CachedObjectStorageFactory.php +++ b/Classes/PHPExcel/CachedObjectStorageFactory.php @@ -3,7 +3,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -32,7 +32,7 @@ * * @category PHPExcel * @package PHPExcel_CachedObjectStorage - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CachedObjectStorageFactory { diff --git a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php index 3759517f8..a633c2c3a 100644 --- a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php +++ b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel_CalcEngine_CyclicReferenceStack * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CalcEngine_CyclicReferenceStack { diff --git a/Classes/PHPExcel/CalcEngine/Logger.php b/Classes/PHPExcel/CalcEngine/Logger.php index 77c42aa51..fe43ae4f6 100644 --- a/Classes/PHPExcel/CalcEngine/Logger.php +++ b/Classes/PHPExcel/CalcEngine/Logger.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_CalcEngine_Logger { diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 4e70972a6..c8ddbbd64 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -57,7 +57,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation { diff --git a/Classes/PHPExcel/Calculation/Database.php b/Classes/PHPExcel/Calculation/Database.php index 0d4fabf3d..908decfc4 100644 --- a/Classes/PHPExcel/Calculation/Database.php +++ b/Classes/PHPExcel/Calculation/Database.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Database { diff --git a/Classes/PHPExcel/Calculation/DateTime.php b/Classes/PHPExcel/Calculation/DateTime.php index 364cc9f68..6eb96fd2c 100644 --- a/Classes/PHPExcel/Calculation/DateTime.php +++ b/Classes/PHPExcel/Calculation/DateTime.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_DateTime { diff --git a/Classes/PHPExcel/Calculation/Engineering.php b/Classes/PHPExcel/Calculation/Engineering.php index 85a65ca0e..b60163e56 100644 --- a/Classes/PHPExcel/Calculation/Engineering.php +++ b/Classes/PHPExcel/Calculation/Engineering.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -45,7 +45,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Engineering { diff --git a/Classes/PHPExcel/Calculation/Exception.php b/Classes/PHPExcel/Calculation/Exception.php index 7666f2f86..2ddf666df 100644 --- a/Classes/PHPExcel/Calculation/Exception.php +++ b/Classes/PHPExcel/Calculation/Exception.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Exception extends PHPExcel_Exception { /** diff --git a/Classes/PHPExcel/Calculation/ExceptionHandler.php b/Classes/PHPExcel/Calculation/ExceptionHandler.php index c1148756a..41c42d7ac 100644 --- a/Classes/PHPExcel/Calculation/ExceptionHandler.php +++ b/Classes/PHPExcel/Calculation/ExceptionHandler.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_ExceptionHandler { /** diff --git a/Classes/PHPExcel/Calculation/Financial.php b/Classes/PHPExcel/Calculation/Financial.php index 8d359d8c1..912a26961 100644 --- a/Classes/PHPExcel/Calculation/Financial.php +++ b/Classes/PHPExcel/Calculation/Financial.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -48,7 +48,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Financial { diff --git a/Classes/PHPExcel/Calculation/FormulaParser.php b/Classes/PHPExcel/Calculation/FormulaParser.php index 69b1463fd..3884fd20a 100644 --- a/Classes/PHPExcel/Calculation/FormulaParser.php +++ b/Classes/PHPExcel/Calculation/FormulaParser.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -54,7 +54,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_FormulaParser { /* Character constants */ diff --git a/Classes/PHPExcel/Calculation/FormulaToken.php b/Classes/PHPExcel/Calculation/FormulaToken.php index 6eaa3ee09..ad10c00a2 100644 --- a/Classes/PHPExcel/Calculation/FormulaToken.php +++ b/Classes/PHPExcel/Calculation/FormulaToken.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -55,7 +55,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_FormulaToken { /* Token types */ diff --git a/Classes/PHPExcel/Calculation/Function.php b/Classes/PHPExcel/Calculation/Function.php index b98220086..1301cd096 100644 --- a/Classes/PHPExcel/Calculation/Function.php +++ b/Classes/PHPExcel/Calculation/Function.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Function { /* Function categories */ diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index 2d6bf9474..c9ac97bb4 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -54,7 +54,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Functions { diff --git a/Classes/PHPExcel/Calculation/Logical.php b/Classes/PHPExcel/Calculation/Logical.php index 77ae4732b..48fdb17f4 100644 --- a/Classes/PHPExcel/Calculation/Logical.php +++ b/Classes/PHPExcel/Calculation/Logical.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Logical { diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index fc9fdbab9..94f42e5f2 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_LookupRef { diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index 929bccdc0..b2bb19d48 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_MathTrig { diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php index 76760f2d4..2037f3349 100644 --- a/Classes/PHPExcel/Calculation/Statistical.php +++ b/Classes/PHPExcel/Calculation/Statistical.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -57,7 +57,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Statistical { diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php index 90447c0bc..73a0d0cd7 100644 --- a/Classes/PHPExcel/Calculation/TextData.php +++ b/Classes/PHPExcel/Calculation/TextData.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_TextData { diff --git a/Classes/PHPExcel/Calculation/Token/Stack.php b/Classes/PHPExcel/Calculation/Token/Stack.php index 05825d157..57963e738 100644 --- a/Classes/PHPExcel/Calculation/Token/Stack.php +++ b/Classes/PHPExcel/Calculation/Token/Stack.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel_Calculation_Token_Stack * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Token_Stack { diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index f2f331e57..0462686d1 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell { diff --git a/Classes/PHPExcel/Cell/AdvancedValueBinder.php b/Classes/PHPExcel/Cell/AdvancedValueBinder.php index bb3c88220..f4280ac49 100644 --- a/Classes/PHPExcel/Cell/AdvancedValueBinder.php +++ b/Classes/PHPExcel/Cell/AdvancedValueBinder.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell_AdvancedValueBinder extends PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder { diff --git a/Classes/PHPExcel/Cell/DataType.php b/Classes/PHPExcel/Cell/DataType.php index 6ec30ce8b..07e148a50 100644 --- a/Classes/PHPExcel/Cell/DataType.php +++ b/Classes/PHPExcel/Cell/DataType.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell_DataType { diff --git a/Classes/PHPExcel/Cell/DataValidation.php b/Classes/PHPExcel/Cell/DataValidation.php index 80bf91f48..538ecd1fb 100644 --- a/Classes/PHPExcel/Cell/DataValidation.php +++ b/Classes/PHPExcel/Cell/DataValidation.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell_DataValidation { diff --git a/Classes/PHPExcel/Cell/DefaultValueBinder.php b/Classes/PHPExcel/Cell/DefaultValueBinder.php index 6d71a03a1..67a4b5f68 100644 --- a/Classes/PHPExcel/Cell/DefaultValueBinder.php +++ b/Classes/PHPExcel/Cell/DefaultValueBinder.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -41,7 +41,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder { diff --git a/Classes/PHPExcel/Cell/Hyperlink.php b/Classes/PHPExcel/Cell/Hyperlink.php index 910a04864..178ba7ee2 100644 --- a/Classes/PHPExcel/Cell/Hyperlink.php +++ b/Classes/PHPExcel/Cell/Hyperlink.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Cell_Hyperlink { diff --git a/Classes/PHPExcel/Cell/IValueBinder.php b/Classes/PHPExcel/Cell/IValueBinder.php index b07df74c5..551815523 100644 --- a/Classes/PHPExcel/Cell/IValueBinder.php +++ b/Classes/PHPExcel/Cell/IValueBinder.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Cell - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_Cell_IValueBinder { diff --git a/Classes/PHPExcel/Chart.php b/Classes/PHPExcel/Chart.php index 0e9b487ef..2f3f19d22 100644 --- a/Classes/PHPExcel/Chart.php +++ b/Classes/PHPExcel/Chart.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart { diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index 92588c7f9..86e61eb17 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_DataSeries { diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index f7d068180..731d2c922 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_DataSeriesValues { diff --git a/Classes/PHPExcel/Chart/Exception.php b/Classes/PHPExcel/Chart/Exception.php index e7448ce2f..58b5b5822 100644 --- a/Classes/PHPExcel/Chart/Exception.php +++ b/Classes/PHPExcel/Chart/Exception.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Exception extends PHPExcel_Exception { /** diff --git a/Classes/PHPExcel/Chart/Layout.php b/Classes/PHPExcel/Chart/Layout.php index 7c37ef926..eefa157a9 100644 --- a/Classes/PHPExcel/Chart/Layout.php +++ b/Classes/PHPExcel/Chart/Layout.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Layout { diff --git a/Classes/PHPExcel/Chart/Legend.php b/Classes/PHPExcel/Chart/Legend.php index 0422e9668..783b3d429 100644 --- a/Classes/PHPExcel/Chart/Legend.php +++ b/Classes/PHPExcel/Chart/Legend.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Legend { diff --git a/Classes/PHPExcel/Chart/PlotArea.php b/Classes/PHPExcel/Chart/PlotArea.php index cc512cdef..c917ce305 100644 --- a/Classes/PHPExcel/Chart/PlotArea.php +++ b/Classes/PHPExcel/Chart/PlotArea.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_PlotArea { diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index fa0bf1088..41066efac 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -3,7 +3,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ * * @category PHPExcel * @package PHPExcel_Chart_Renderer - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,7 +35,7 @@ * * @category PHPExcel * @package PHPExcel_Chart_Renderer - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Renderer_jpgraph { diff --git a/Classes/PHPExcel/Chart/Title.php b/Classes/PHPExcel/Chart/Title.php index 0883a2197..5d226c4b2 100644 --- a/Classes/PHPExcel/Chart/Title.php +++ b/Classes/PHPExcel/Chart/Title.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Title { diff --git a/Classes/PHPExcel/Comment.php b/Classes/PHPExcel/Comment.php index a8f599d10..8b8cfdcc4 100644 --- a/Classes/PHPExcel/Comment.php +++ b/Classes/PHPExcel/Comment.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Comment implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/DocumentProperties.php b/Classes/PHPExcel/DocumentProperties.php index c8099dc1a..7b4a0e435 100644 --- a/Classes/PHPExcel/DocumentProperties.php +++ b/Classes/PHPExcel/DocumentProperties.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_DocumentProperties { diff --git a/Classes/PHPExcel/DocumentSecurity.php b/Classes/PHPExcel/DocumentSecurity.php index bbbe4b77b..cf7ffb57c 100644 --- a/Classes/PHPExcel/DocumentSecurity.php +++ b/Classes/PHPExcel/DocumentSecurity.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_DocumentSecurity { diff --git a/Classes/PHPExcel/Exception.php b/Classes/PHPExcel/Exception.php index e25803640..578b9eeee 100644 --- a/Classes/PHPExcel/Exception.php +++ b/Classes/PHPExcel/Exception.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Exception extends Exception { /** diff --git a/Classes/PHPExcel/HashTable.php b/Classes/PHPExcel/HashTable.php index a94e19e81..77106e1e0 100644 --- a/Classes/PHPExcel/HashTable.php +++ b/Classes/PHPExcel/HashTable.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_HashTable { diff --git a/Classes/PHPExcel/IComparable.php b/Classes/PHPExcel/IComparable.php index f1c8e9ac5..adb9a016d 100644 --- a/Classes/PHPExcel/IComparable.php +++ b/Classes/PHPExcel/IComparable.php @@ -18,7 +18,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -29,7 +29,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_IComparable { diff --git a/Classes/PHPExcel/IOFactory.php b/Classes/PHPExcel/IOFactory.php index 49580126a..1daa06a53 100644 --- a/Classes/PHPExcel/IOFactory.php +++ b/Classes/PHPExcel/IOFactory.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_IOFactory { diff --git a/Classes/PHPExcel/NamedRange.php b/Classes/PHPExcel/NamedRange.php index 2ab04aa13..fe245e3ee 100644 --- a/Classes/PHPExcel/NamedRange.php +++ b/Classes/PHPExcel/NamedRange.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_NamedRange { diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php index 1a5978d1d..e0f4c0dc3 100644 --- a/Classes/PHPExcel/Reader/Abstract.php +++ b/Classes/PHPExcel/Reader/Abstract.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index d45a0c6b3..043aeecf5 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/DefaultReadFilter.php b/Classes/PHPExcel/Reader/DefaultReadFilter.php index 6111c8011..dc55fc6bd 100644 --- a/Classes/PHPExcel/Reader/DefaultReadFilter.php +++ b/Classes/PHPExcel/Reader/DefaultReadFilter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_DefaultReadFilter implements PHPExcel_Reader_IReadFilter { diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index acde1cca6..b08ec8647 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,9 +20,9 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version 1.7.9, 2013-06-02 + * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 893a097c5..ed0376e73 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index 0c33ef287..1424276c6 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Chart.php +++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel2007_Chart { diff --git a/Classes/PHPExcel/Reader/Excel2007/Theme.php b/Classes/PHPExcel/Reader/Excel2007/Theme.php index 89176a287..a371c6208 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Theme.php +++ b/Classes/PHPExcel/Reader/Excel2007/Theme.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel2007_Theme { diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index b9932e636..3e9b091ba 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -73,7 +73,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/Excel5/Escher.php b/Classes/PHPExcel/Reader/Excel5/Escher.php index 0970d1baf..8dc5e902e 100644 --- a/Classes/PHPExcel/Reader/Excel5/Escher.php +++ b/Classes/PHPExcel/Reader/Excel5/Escher.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel5_Escher { diff --git a/Classes/PHPExcel/Reader/Excel5/MD5.php b/Classes/PHPExcel/Reader/Excel5/MD5.php index 6f6e6af6d..097e9753f 100644 --- a/Classes/PHPExcel/Reader/Excel5/MD5.php +++ b/Classes/PHPExcel/Reader/Excel5/MD5.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel5_MD5 { diff --git a/Classes/PHPExcel/Reader/Excel5/RC4.php b/Classes/PHPExcel/Reader/Excel5/RC4.php index 492e1b47b..199ee1921 100644 --- a/Classes/PHPExcel/Reader/Excel5/RC4.php +++ b/Classes/PHPExcel/Reader/Excel5/RC4.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel5_RC4 { diff --git a/Classes/PHPExcel/Reader/Exception.php b/Classes/PHPExcel/Reader/Exception.php index 498071149..d0e2f5707 100644 --- a/Classes/PHPExcel/Reader/Exception.php +++ b/Classes/PHPExcel/Reader/Exception.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Exception extends PHPExcel_Exception { /** diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index 9e2b241f6..790192b2f 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 8ebdc9f47..3a832c114 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_HTML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/IReadFilter.php b/Classes/PHPExcel/Reader/IReadFilter.php index 584b928dd..f27cff8b9 100644 --- a/Classes/PHPExcel/Reader/IReadFilter.php +++ b/Classes/PHPExcel/Reader/IReadFilter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_Reader_IReadFilter { diff --git a/Classes/PHPExcel/Reader/IReader.php b/Classes/PHPExcel/Reader/IReader.php index 97cc50393..a24ab4e97 100644 --- a/Classes/PHPExcel/Reader/IReader.php +++ b/Classes/PHPExcel/Reader/IReader.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 2d9af18d3..df7f23077 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index 3d3b59cf4..b61118a3b 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 90277c257..9eadab4d5 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_ReferenceHelper { diff --git a/Classes/PHPExcel/RichText.php b/Classes/PHPExcel/RichText.php index 97c388a20..19326315b 100644 --- a/Classes/PHPExcel/RichText.php +++ b/Classes/PHPExcel/RichText.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_RichText implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/RichText/ITextElement.php b/Classes/PHPExcel/RichText/ITextElement.php index da119dcf0..9f1c6240a 100644 --- a/Classes/PHPExcel/RichText/ITextElement.php +++ b/Classes/PHPExcel/RichText/ITextElement.php @@ -18,7 +18,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -29,7 +29,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_RichText_ITextElement { diff --git a/Classes/PHPExcel/RichText/Run.php b/Classes/PHPExcel/RichText/Run.php index 7b82a71f3..4a8c592e3 100644 --- a/Classes/PHPExcel/RichText/Run.php +++ b/Classes/PHPExcel/RichText/Run.php @@ -18,7 +18,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -29,7 +29,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_RichText_Run extends PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement { diff --git a/Classes/PHPExcel/RichText/TextElement.php b/Classes/PHPExcel/RichText/TextElement.php index 71a15d692..ec7c2644e 100644 --- a/Classes/PHPExcel/RichText/TextElement.php +++ b/Classes/PHPExcel/RichText/TextElement.php @@ -18,7 +18,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -29,7 +29,7 @@ * * @category PHPExcel * @package PHPExcel_RichText - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement { diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php index 8cd1da383..5cf8ed652 100644 --- a/Classes/PHPExcel/Settings.php +++ b/Classes/PHPExcel/Settings.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Settings - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index 6bc4f4819..d1c4e1a59 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_CodePage { diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index 0c7bb913f..f253786d6 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -3,7 +3,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -32,7 +32,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Date { diff --git a/Classes/PHPExcel/Shared/Drawing.php b/Classes/PHPExcel/Shared/Drawing.php index 7f7842b20..dbff74abc 100644 --- a/Classes/PHPExcel/Shared/Drawing.php +++ b/Classes/PHPExcel/Shared/Drawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Drawing { diff --git a/Classes/PHPExcel/Shared/Escher.php b/Classes/PHPExcel/Shared/Escher.php index e3f1d55c6..ddf68c65b 100644 --- a/Classes/PHPExcel/Shared/Escher.php +++ b/Classes/PHPExcel/Shared/Escher.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher { diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer.php index bea1e4494..cb826db10 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DgContainer { diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php index 827ac3d91..b8ad8eafd 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer { diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php index f3a8bab57..682314801 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer { diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer.php index 5cb2ceb9b..26696ec9d 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DggContainer { diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php index fceb57ba6..fba2e73fa 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer { diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php index e278f21fb..418896a34 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE { diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php index b30ef877b..d9cc2f5c0 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip { diff --git a/Classes/PHPExcel/Shared/Excel5.php b/Classes/PHPExcel/Shared/Excel5.php index b80d61c96..3caf675dd 100644 --- a/Classes/PHPExcel/Shared/Excel5.php +++ b/Classes/PHPExcel/Shared/Excel5.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -30,7 +30,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Excel5 { diff --git a/Classes/PHPExcel/Shared/File.php b/Classes/PHPExcel/Shared/File.php index e325bb31b..52c9b9796 100644 --- a/Classes/PHPExcel/Shared/File.php +++ b/Classes/PHPExcel/Shared/File.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_File { diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php index 32d29df6e..9effd91ec 100644 --- a/Classes/PHPExcel/Shared/Font.php +++ b/Classes/PHPExcel/Shared/Font.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Font { diff --git a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php index 025c6cbcb..5145206e7 100644 --- a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php +++ b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/Classes/PHPExcel/Shared/OLERead.php b/Classes/PHPExcel/Shared/OLERead.php index 30e12a41a..261bdde58 100644 --- a/Classes/PHPExcel/Shared/OLERead.php +++ b/Classes/PHPExcel/Shared/OLERead.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Classes/PHPExcel/Shared/PasswordHasher.php b/Classes/PHPExcel/Shared/PasswordHasher.php index 270e54d7c..891b6bc15 100644 --- a/Classes/PHPExcel/Shared/PasswordHasher.php +++ b/Classes/PHPExcel/Shared/PasswordHasher.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_PasswordHasher { diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 6fe9eb96e..fc86d537d 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_String { diff --git a/Classes/PHPExcel/Shared/TimeZone.php b/Classes/PHPExcel/Shared/TimeZone.php index 9f1ba4af6..1792a2953 100644 --- a/Classes/PHPExcel/Shared/TimeZone.php +++ b/Classes/PHPExcel/Shared/TimeZone.php @@ -3,7 +3,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -32,7 +32,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_TimeZone { diff --git a/Classes/PHPExcel/Shared/XMLWriter.php b/Classes/PHPExcel/Shared/XMLWriter.php index dfbcef89f..beca51fc5 100644 --- a/Classes/PHPExcel/Shared/XMLWriter.php +++ b/Classes/PHPExcel/Shared/XMLWriter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -39,7 +39,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_XMLWriter extends XMLWriter { /** Temporary storage method */ diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index a0a954c8a..5507210af 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_ZipArchive - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -36,7 +36,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_ZipArchive - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_ZipArchive { diff --git a/Classes/PHPExcel/Shared/ZipStreamWrapper.php b/Classes/PHPExcel/Shared/ZipStreamWrapper.php index cc401ce07..6e63d3ce3 100644 --- a/Classes/PHPExcel/Shared/ZipStreamWrapper.php +++ b/Classes/PHPExcel/Shared/ZipStreamWrapper.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_ZipStreamWrapper { /** diff --git a/Classes/PHPExcel/Shared/trend/bestFitClass.php b/Classes/PHPExcel/Shared/trend/bestFitClass.php index f6cbaf981..9ae8b006d 100644 --- a/Classes/PHPExcel/Shared/trend/bestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/bestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php index 12166bc2f..b524b5fe4 100644 --- a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,7 +34,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php index 973bcdaef..7d811aa5b 100644 --- a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,7 +34,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php index 498fe55b9..b43cd5edf 100644 --- a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,7 +34,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php index f39459e04..3d329eb7d 100644 --- a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,7 +35,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php index a3f806353..832669c9f 100644 --- a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,7 +34,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit { diff --git a/Classes/PHPExcel/Shared/trend/trendClass.php b/Classes/PHPExcel/Shared/trend/trendClass.php index eec10ce4e..25d7eb1d8 100644 --- a/Classes/PHPExcel/Shared/trend/trendClass.php +++ b/Classes/PHPExcel/Shared/trend/trendClass.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -38,7 +38,7 @@ * * @category PHPExcel * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class trendClass { diff --git a/Classes/PHPExcel/Style.php b/Classes/PHPExcel/Style.php index a188f7195..9c29320ea 100644 --- a/Classes/PHPExcel/Style.php +++ b/Classes/PHPExcel/Style.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Alignment.php b/Classes/PHPExcel/Style/Alignment.php index f7be8f60f..7577da537 100644 --- a/Classes/PHPExcel/Style/Alignment.php +++ b/Classes/PHPExcel/Style/Alignment.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Alignment extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Border.php b/Classes/PHPExcel/Style/Border.php index b75f82c4d..ec737bf0f 100644 --- a/Classes/PHPExcel/Style/Border.php +++ b/Classes/PHPExcel/Style/Border.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Border extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Borders.php b/Classes/PHPExcel/Style/Borders.php index ccb1be813..21dcfeeef 100644 --- a/Classes/PHPExcel/Style/Borders.php +++ b/Classes/PHPExcel/Style/Borders.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Borders extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Color.php b/Classes/PHPExcel/Style/Color.php index 6248862c7..a56c9a633 100644 --- a/Classes/PHPExcel/Style/Color.php +++ b/Classes/PHPExcel/Style/Color.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Color extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Conditional.php b/Classes/PHPExcel/Style/Conditional.php index 1d3f950c6..aebf1e313 100644 --- a/Classes/PHPExcel/Style/Conditional.php +++ b/Classes/PHPExcel/Style/Conditional.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Conditional implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Fill.php b/Classes/PHPExcel/Style/Fill.php index 8f4eaf3d8..6412ba634 100644 --- a/Classes/PHPExcel/Style/Fill.php +++ b/Classes/PHPExcel/Style/Fill.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Fill extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Font.php b/Classes/PHPExcel/Style/Font.php index 6a00a155f..296e34855 100644 --- a/Classes/PHPExcel/Style/Font.php +++ b/Classes/PHPExcel/Style/Font.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Font extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index a0688f494..0d7d93de2 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_NumberFormat extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Protection.php b/Classes/PHPExcel/Style/Protection.php index a8f65ce37..8dc1f31ad 100644 --- a/Classes/PHPExcel/Style/Protection.php +++ b/Classes/PHPExcel/Style/Protection.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version 1.4.5, 2007-08-23 */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Style_Protection extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Style/Supervisor.php b/Classes/PHPExcel/Style/Supervisor.php index d0fa06b29..2d21f5293 100644 --- a/Classes/PHPExcel/Style/Supervisor.php +++ b/Classes/PHPExcel/Style/Supervisor.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Style - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Style_Supervisor { diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 3fecc164d..753e9c2aa 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index 3872d0e36..d0fa8b6df 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_AutoFilter { diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php index e43a33362..1a6fb4eb8 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_AutoFilter_Column { diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php index 1b8c03eb5..4a14d7d7d 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_AutoFilter_Column_Rule { diff --git a/Classes/PHPExcel/Worksheet/BaseDrawing.php b/Classes/PHPExcel/Worksheet/BaseDrawing.php index 392c4d52a..0250035cc 100644 --- a/Classes/PHPExcel/Worksheet/BaseDrawing.php +++ b/Classes/PHPExcel/Worksheet/BaseDrawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/CellIterator.php b/Classes/PHPExcel/Worksheet/CellIterator.php index f349d2aa5..27cdc94c3 100644 --- a/Classes/PHPExcel/Worksheet/CellIterator.php +++ b/Classes/PHPExcel/Worksheet/CellIterator.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -33,7 +33,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_CellIterator implements Iterator { diff --git a/Classes/PHPExcel/Worksheet/ColumnDimension.php b/Classes/PHPExcel/Worksheet/ColumnDimension.php index dddb28765..bc6a042eb 100644 --- a/Classes/PHPExcel/Worksheet/ColumnDimension.php +++ b/Classes/PHPExcel/Worksheet/ColumnDimension.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_ColumnDimension { diff --git a/Classes/PHPExcel/Worksheet/Drawing.php b/Classes/PHPExcel/Worksheet/Drawing.php index d3efa6a5c..e8d87f1d0 100644 --- a/Classes/PHPExcel/Worksheet/Drawing.php +++ b/Classes/PHPExcel/Worksheet/Drawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet_Drawing - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet_Drawing - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php index 646b0646b..98b95b1a7 100644 --- a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php +++ b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet_Drawing - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet_Drawing - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/HeaderFooter.php b/Classes/PHPExcel/Worksheet/HeaderFooter.php index 88c35daa7..803741638 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooter.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -91,7 +91,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_HeaderFooter { diff --git a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php index 7dd03a0fb..966664f93 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/MemoryDrawing.php b/Classes/PHPExcel/Worksheet/MemoryDrawing.php index 753a135a1..80fc6d1f0 100644 --- a/Classes/PHPExcel/Worksheet/MemoryDrawing.php +++ b/Classes/PHPExcel/Worksheet/MemoryDrawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { diff --git a/Classes/PHPExcel/Worksheet/PageMargins.php b/Classes/PHPExcel/Worksheet/PageMargins.php index 8fc4cbeca..b05a291ff 100644 --- a/Classes/PHPExcel/Worksheet/PageMargins.php +++ b/Classes/PHPExcel/Worksheet/PageMargins.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_PageMargins { diff --git a/Classes/PHPExcel/Worksheet/PageSetup.php b/Classes/PHPExcel/Worksheet/PageSetup.php index e82275457..ba2792fac 100644 --- a/Classes/PHPExcel/Worksheet/PageSetup.php +++ b/Classes/PHPExcel/Worksheet/PageSetup.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -102,7 +102,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_PageSetup { diff --git a/Classes/PHPExcel/Worksheet/Protection.php b/Classes/PHPExcel/Worksheet/Protection.php index e968c1199..da66bf763 100644 --- a/Classes/PHPExcel/Worksheet/Protection.php +++ b/Classes/PHPExcel/Worksheet/Protection.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_Protection { diff --git a/Classes/PHPExcel/Worksheet/Row.php b/Classes/PHPExcel/Worksheet/Row.php index 07025e8e0..df16d33c2 100644 --- a/Classes/PHPExcel/Worksheet/Row.php +++ b/Classes/PHPExcel/Worksheet/Row.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -33,7 +33,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_Row { diff --git a/Classes/PHPExcel/Worksheet/RowDimension.php b/Classes/PHPExcel/Worksheet/RowDimension.php index 1c6abaa42..93535f55e 100644 --- a/Classes/PHPExcel/Worksheet/RowDimension.php +++ b/Classes/PHPExcel/Worksheet/RowDimension.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_RowDimension { diff --git a/Classes/PHPExcel/Worksheet/RowIterator.php b/Classes/PHPExcel/Worksheet/RowIterator.php index 840f7f94a..642ec763d 100644 --- a/Classes/PHPExcel/Worksheet/RowIterator.php +++ b/Classes/PHPExcel/Worksheet/RowIterator.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -33,7 +33,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_RowIterator implements Iterator { diff --git a/Classes/PHPExcel/Worksheet/SheetView.php b/Classes/PHPExcel/Worksheet/SheetView.php index f37ba81d2..8ced835dd 100644 --- a/Classes/PHPExcel/Worksheet/SheetView.php +++ b/Classes/PHPExcel/Worksheet/SheetView.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_SheetView { diff --git a/Classes/PHPExcel/WorksheetIterator.php b/Classes/PHPExcel/WorksheetIterator.php index 27cc1d208..ad17fd903 100644 --- a/Classes/PHPExcel/WorksheetIterator.php +++ b/Classes/PHPExcel/WorksheetIterator.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -33,7 +33,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_WorksheetIterator implements Iterator { diff --git a/Classes/PHPExcel/Writer/Abstract.php b/Classes/PHPExcel/Writer/Abstract.php index 8b9fe500e..fca6a60cc 100644 --- a/Classes/PHPExcel/Writer/Abstract.php +++ b/Classes/PHPExcel/Writer/Abstract.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php index 6d624eebe..97961ccca 100644 --- a/Classes/PHPExcel/Writer/CSV.php +++ b/Classes/PHPExcel/Writer/CSV.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_CSV - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_CSV - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { /** diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index 5ff98f2fd..4cf14ac1c 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 8ea5851cd..0b686b912 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Comments.php b/Classes/PHPExcel/Writer/Excel2007/Comments.php index cfaffef5a..dc809fa8e 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Comments.php +++ b/Classes/PHPExcel/Writer/Excel2007/Comments.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Comments extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php index b19b4cd93..557853654 100644 --- a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php +++ b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_ContentTypes extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/DocProps.php b/Classes/PHPExcel/Writer/Excel2007/DocProps.php index 3d1497a40..f8821379c 100644 --- a/Classes/PHPExcel/Writer/Excel2007/DocProps.php +++ b/Classes/PHPExcel/Writer/Excel2007/DocProps.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_DocProps extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Drawing.php b/Classes/PHPExcel/Writer/Excel2007/Drawing.php index 2bc4b39e3..1cf971ed4 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Drawing.php +++ b/Classes/PHPExcel/Writer/Excel2007/Drawing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Drawing extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Rels.php b/Classes/PHPExcel/Writer/Excel2007/Rels.php index 87403b629..a7d36c0a9 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Rels.php +++ b/Classes/PHPExcel/Writer/Excel2007/Rels.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Rels extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php index 47b75a317..615f2cbd9 100644 --- a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php +++ b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_RelsRibbon extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php index 60833e10e..3f87d81f2 100644 --- a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php +++ b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_RelsVBA extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Classes/PHPExcel/Writer/Excel2007/StringTable.php index d6a702768..e8ca1c5a5 100644 --- a/Classes/PHPExcel/Writer/Excel2007/StringTable.php +++ b/Classes/PHPExcel/Writer/Excel2007/StringTable.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_StringTable extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Style.php b/Classes/PHPExcel/Writer/Excel2007/Style.php index bd246fcd0..9857043b8 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Style.php +++ b/Classes/PHPExcel/Writer/Excel2007/Style.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Style extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Theme.php b/Classes/PHPExcel/Writer/Excel2007/Theme.php index ba8563921..c67b94816 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Theme.php +++ b/Classes/PHPExcel/Writer/Excel2007/Theme.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Workbook.php b/Classes/PHPExcel/Writer/Excel2007/Workbook.php index 2abf9ebd3..f30929476 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel2007/Workbook.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index 8ca33aa4f..760581647 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php index 0667ed4d4..68b1124fd 100644 --- a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php +++ b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Writer_Excel2007_WriterPart { diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index 5ba73f082..1a990d045 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php index d75c33b2d..86201134d 100644 --- a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php +++ b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -65,7 +65,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_BIFFwriter { diff --git a/Classes/PHPExcel/Writer/Excel5/Escher.php b/Classes/PHPExcel/Writer/Excel5/Escher.php index 8286bc12b..92e6a8d88 100644 --- a/Classes/PHPExcel/Writer/Excel5/Escher.php +++ b/Classes/PHPExcel/Writer/Excel5/Escher.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Escher { diff --git a/Classes/PHPExcel/Writer/Excel5/Font.php b/Classes/PHPExcel/Writer/Excel5/Font.php index a0936eb87..0df194382 100644 --- a/Classes/PHPExcel/Writer/Excel5/Font.php +++ b/Classes/PHPExcel/Writer/Excel5/Font.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Font { diff --git a/Classes/PHPExcel/Writer/Excel5/Parser.php b/Classes/PHPExcel/Writer/Excel5/Parser.php index 2018c5ba1..7bdc1c0bc 100644 --- a/Classes/PHPExcel/Writer/Excel5/Parser.php +++ b/Classes/PHPExcel/Writer/Excel5/Parser.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -55,7 +55,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Parser { diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index 915096fa2..ecfac5dc0 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -66,7 +66,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter { diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index cc39513fe..722ac15bf 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -66,7 +66,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter { diff --git a/Classes/PHPExcel/Writer/Excel5/Xf.php b/Classes/PHPExcel/Writer/Excel5/Xf.php index da25c2bc5..99f1b2a0c 100644 --- a/Classes/PHPExcel/Writer/Excel5/Xf.php +++ b/Classes/PHPExcel/Writer/Excel5/Xf.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -66,7 +66,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel5_Xf { diff --git a/Classes/PHPExcel/Writer/Exception.php b/Classes/PHPExcel/Writer/Exception.php index b5d437d4e..1715587a2 100644 --- a/Classes/PHPExcel/Writer/Exception.php +++ b/Classes/PHPExcel/Writer/Exception.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Exception extends PHPExcel_Exception { /** diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index a003b6d2f..72fd81856 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_HTML - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_HTML - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { /** diff --git a/Classes/PHPExcel/Writer/IWriter.php b/Classes/PHPExcel/Writer/IWriter.php index 6bb8a3954..f0b94b9e9 100644 --- a/Classes/PHPExcel/Writer/IWriter.php +++ b/Classes/PHPExcel/Writer/IWriter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ interface PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/PDF.php b/Classes/PHPExcel/Writer/PDF.php index a2524d4db..4111f8bd9 100644 --- a/Classes/PHPExcel/Writer/PDF.php +++ b/Classes/PHPExcel/Writer/PDF.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_PDF { diff --git a/Classes/PHPExcel/Writer/PDF/Core.php b/Classes/PHPExcel/Writer/PDF/Core.php index 24d104ce9..3842334d9 100644 --- a/Classes/PHPExcel/Writer/PDF/Core.php +++ b/Classes/PHPExcel/Writer/PDF/Core.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Writer_PDF_Core extends PHPExcel_Writer_HTML { diff --git a/Classes/PHPExcel/Writer/PDF/DomPDF.php b/Classes/PHPExcel/Writer/PDF/DomPDF.php index 4563a9546..9ba97efcf 100644 --- a/Classes/PHPExcel/Writer/PDF/DomPDF.php +++ b/Classes/PHPExcel/Writer/PDF/DomPDF.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -39,7 +39,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_PDF_DomPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/PDF/mPDF.php b/Classes/PHPExcel/Writer/PDF/mPDF.php index 1e20e6feb..dddc097d3 100644 --- a/Classes/PHPExcel/Writer/PDF/mPDF.php +++ b/Classes/PHPExcel/Writer/PDF/mPDF.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -39,7 +39,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_PDF_mPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter { diff --git a/Classes/PHPExcel/Writer/PDF/tcPDF.php b/Classes/PHPExcel/Writer/PDF/tcPDF.php index 2895512e4..4e1937afc 100644 --- a/Classes/PHPExcel/Writer/PDF/tcPDF.php +++ b/Classes/PHPExcel/Writer/PDF/tcPDF.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2013 PHPExcel + * Copyright (c) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -40,7 +40,7 @@ * * @category PHPExcel * @package PHPExcel_Writer_PDF - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_PDF_tcPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter { diff --git a/Examples/01pharSimple.php b/Examples/01pharSimple.php index 9c4221fa4..a88047701 100644 --- a/Examples/01pharSimple.php +++ b/Examples/01pharSimple.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/01simple-download-pdf.php b/Examples/01simple-download-pdf.php index 4de034711..287b0e891 100644 --- a/Examples/01simple-download-pdf.php +++ b/Examples/01simple-download-pdf.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/01simple-download-xls.php b/Examples/01simple-download-xls.php index ddbfc44a2..60fc901bf 100644 --- a/Examples/01simple-download-xls.php +++ b/Examples/01simple-download-xls.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/01simple-download-xlsx.php b/Examples/01simple-download-xlsx.php index a2b927b82..c37be637a 100644 --- a/Examples/01simple-download-xlsx.php +++ b/Examples/01simple-download-xlsx.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/01simple.php b/Examples/01simple.php index baeb4cc9b..965fefafe 100644 --- a/Examples/01simple.php +++ b/Examples/01simple.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/01simplePCLZip.php b/Examples/01simplePCLZip.php index ab82497cf..0b7a46c17 100644 --- a/Examples/01simplePCLZip.php +++ b/Examples/01simplePCLZip.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/02types-xls.php b/Examples/02types-xls.php index 81d41914c..cc1dc3744 100644 --- a/Examples/02types-xls.php +++ b/Examples/02types-xls.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/02types.php b/Examples/02types.php index 386e4f5b9..ff5421e4b 100644 --- a/Examples/02types.php +++ b/Examples/02types.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/03formulas.php b/Examples/03formulas.php index b493aa5ff..1396717d7 100644 --- a/Examples/03formulas.php +++ b/Examples/03formulas.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/04printing.php b/Examples/04printing.php index 6a90eede3..14358b05e 100644 --- a/Examples/04printing.php +++ b/Examples/04printing.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/05featuredemo.inc.php b/Examples/05featuredemo.inc.php index 37de497c5..00a8b8729 100644 --- a/Examples/05featuredemo.inc.php +++ b/Examples/05featuredemo.inc.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/05featuredemo.php b/Examples/05featuredemo.php index 3bfb9984a..66d4980ec 100644 --- a/Examples/05featuredemo.php +++ b/Examples/05featuredemo.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/06largescale-with-cellcaching-sqlite.php b/Examples/06largescale-with-cellcaching-sqlite.php index 80a9e436a..6d36d24c4 100644 --- a/Examples/06largescale-with-cellcaching-sqlite.php +++ b/Examples/06largescale-with-cellcaching-sqlite.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/06largescale-with-cellcaching-sqlite3.php b/Examples/06largescale-with-cellcaching-sqlite3.php index 678e2ecd0..3642ce713 100644 --- a/Examples/06largescale-with-cellcaching-sqlite3.php +++ b/Examples/06largescale-with-cellcaching-sqlite3.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/06largescale-with-cellcaching.php b/Examples/06largescale-with-cellcaching.php index adb93c4bc..aa23b8cbb 100644 --- a/Examples/06largescale-with-cellcaching.php +++ b/Examples/06largescale-with-cellcaching.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/06largescale-xls.php b/Examples/06largescale-xls.php index d1fde8916..00137ad89 100644 --- a/Examples/06largescale-xls.php +++ b/Examples/06largescale-xls.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/06largescale.php b/Examples/06largescale.php index 2e597d3f5..b0fa44047 100644 --- a/Examples/06largescale.php +++ b/Examples/06largescale.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/07reader.php b/Examples/07reader.php index 482a375d5..616b6622f 100644 --- a/Examples/07reader.php +++ b/Examples/07reader.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/07readerPCLZip.php b/Examples/07readerPCLZip.php index dc1885a58..90e859050 100644 --- a/Examples/07readerPCLZip.php +++ b/Examples/07readerPCLZip.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/08conditionalformatting.php b/Examples/08conditionalformatting.php index 6f384d262..f65ec9efd 100644 --- a/Examples/08conditionalformatting.php +++ b/Examples/08conditionalformatting.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/08conditionalformatting2.php b/Examples/08conditionalformatting2.php index 630eb6b63..bbe084a26 100644 --- a/Examples/08conditionalformatting2.php +++ b/Examples/08conditionalformatting2.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/09pagebreaks.php b/Examples/09pagebreaks.php index 4d038af2d..6b8c185e3 100644 --- a/Examples/09pagebreaks.php +++ b/Examples/09pagebreaks.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,9 +20,9 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version 1.7.9, 2013-06-02 + * @version ##VERSION##, ##DATE## */ /** Error reporting */ diff --git a/Examples/10autofilter-selection-1.php b/Examples/10autofilter-selection-1.php index ef41cf165..7542a5295 100644 --- a/Examples/10autofilter-selection-1.php +++ b/Examples/10autofilter-selection-1.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/10autofilter-selection-2.php b/Examples/10autofilter-selection-2.php index c6628114b..c89173f5c 100644 --- a/Examples/10autofilter-selection-2.php +++ b/Examples/10autofilter-selection-2.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/10autofilter-selection-display.php b/Examples/10autofilter-selection-display.php index 0e60e3713..cf2b8acfd 100644 --- a/Examples/10autofilter-selection-display.php +++ b/Examples/10autofilter-selection-display.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/10autofilter.php b/Examples/10autofilter.php index 3f7975c6c..ea3f76343 100644 --- a/Examples/10autofilter.php +++ b/Examples/10autofilter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/11documentsecurity-xls.php b/Examples/11documentsecurity-xls.php index 071b4aea5..b104c7b8a 100644 --- a/Examples/11documentsecurity-xls.php +++ b/Examples/11documentsecurity-xls.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/11documentsecurity.php b/Examples/11documentsecurity.php index 94378a9de..96f5d9930 100644 --- a/Examples/11documentsecurity.php +++ b/Examples/11documentsecurity.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/12cellProtection.php b/Examples/12cellProtection.php index f6507b1f7..77bfee4ce 100644 --- a/Examples/12cellProtection.php +++ b/Examples/12cellProtection.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/13calculation.php b/Examples/13calculation.php index a8f17b0d7..db149489d 100644 --- a/Examples/13calculation.php +++ b/Examples/13calculation.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/14excel5.php b/Examples/14excel5.php index 62a9fe465..3fd3d69f3 100644 --- a/Examples/14excel5.php +++ b/Examples/14excel5.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/15datavalidation-xls.php b/Examples/15datavalidation-xls.php index 9652546db..22f7edcb4 100644 --- a/Examples/15datavalidation-xls.php +++ b/Examples/15datavalidation-xls.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/15datavalidation.php b/Examples/15datavalidation.php index 2b4745ff7..932bacc6f 100644 --- a/Examples/15datavalidation.php +++ b/Examples/15datavalidation.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/16csv.php b/Examples/16csv.php index 8a1971786..71ebfd00d 100644 --- a/Examples/16csv.php +++ b/Examples/16csv.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/17html.php b/Examples/17html.php index 3ad968d1e..0dc825b04 100644 --- a/Examples/17html.php +++ b/Examples/17html.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/18extendedcalculation.php b/Examples/18extendedcalculation.php index b037106a7..3c6fcb492 100644 --- a/Examples/18extendedcalculation.php +++ b/Examples/18extendedcalculation.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/19namedrange.php b/Examples/19namedrange.php index 444ca07c7..acea22b6d 100644 --- a/Examples/19namedrange.php +++ b/Examples/19namedrange.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/20readexcel5.php b/Examples/20readexcel5.php index d09c05209..d99b2306f 100644 --- a/Examples/20readexcel5.php +++ b/Examples/20readexcel5.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/21pdf.php b/Examples/21pdf.php index 70aa792b7..11c56b2ca 100644 --- a/Examples/21pdf.php +++ b/Examples/21pdf.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/22heavilyformatted.php b/Examples/22heavilyformatted.php index 188857d27..c17bc8683 100644 --- a/Examples/22heavilyformatted.php +++ b/Examples/22heavilyformatted.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/23sharedstyles.php b/Examples/23sharedstyles.php index 1a07cd47b..652b4ed2f 100644 --- a/Examples/23sharedstyles.php +++ b/Examples/23sharedstyles.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/24readfilter.php b/Examples/24readfilter.php index b51cc5969..afa6d0c41 100644 --- a/Examples/24readfilter.php +++ b/Examples/24readfilter.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/25inmemoryimage.php b/Examples/25inmemoryimage.php index 8d99e1867..7a3424e20 100644 --- a/Examples/25inmemoryimage.php +++ b/Examples/25inmemoryimage.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/26utf8.php b/Examples/26utf8.php index 08fd85115..ad0b40059 100644 --- a/Examples/26utf8.php +++ b/Examples/26utf8.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/27imagesexcel5.php b/Examples/27imagesexcel5.php index e83996188..17db771c3 100644 --- a/Examples/27imagesexcel5.php +++ b/Examples/27imagesexcel5.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/28iterator.php b/Examples/28iterator.php index d86e0207d..3e1e681de 100644 --- a/Examples/28iterator.php +++ b/Examples/28iterator.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/29advancedvaluebinder.php b/Examples/29advancedvaluebinder.php index 5c3bd2c90..bb387f9cd 100644 --- a/Examples/29advancedvaluebinder.php +++ b/Examples/29advancedvaluebinder.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/30template.php b/Examples/30template.php index 62802ba4b..33d553f78 100644 --- a/Examples/30template.php +++ b/Examples/30template.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/31docproperties_write-xls.php b/Examples/31docproperties_write-xls.php index f68dff5bf..cbb9aa352 100644 --- a/Examples/31docproperties_write-xls.php +++ b/Examples/31docproperties_write-xls.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/31docproperties_write.php b/Examples/31docproperties_write.php index 6ca7631f9..1b01f6fe0 100644 --- a/Examples/31docproperties_write.php +++ b/Examples/31docproperties_write.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/32chartreadwrite.php b/Examples/32chartreadwrite.php index 0ecab8e0a..e4c249d3f 100644 --- a/Examples/32chartreadwrite.php +++ b/Examples/32chartreadwrite.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-area.php b/Examples/33chartcreate-area.php index 9a1e9c7fa..52ee36b96 100644 --- a/Examples/33chartcreate-area.php +++ b/Examples/33chartcreate-area.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-bar-stacked.php b/Examples/33chartcreate-bar-stacked.php index cca6f6849..755fa78ee 100644 --- a/Examples/33chartcreate-bar-stacked.php +++ b/Examples/33chartcreate-bar-stacked.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-bar.php b/Examples/33chartcreate-bar.php index d7344eecb..84f8cf78c 100644 --- a/Examples/33chartcreate-bar.php +++ b/Examples/33chartcreate-bar.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-column-2.php b/Examples/33chartcreate-column-2.php index 18f90bf2d..1d8d689bc 100644 --- a/Examples/33chartcreate-column-2.php +++ b/Examples/33chartcreate-column-2.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-column.php b/Examples/33chartcreate-column.php index caa5b8129..eb3d7e211 100644 --- a/Examples/33chartcreate-column.php +++ b/Examples/33chartcreate-column.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-composite.php b/Examples/33chartcreate-composite.php index 497e2b9ac..0b512f09d 100644 --- a/Examples/33chartcreate-composite.php +++ b/Examples/33chartcreate-composite.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-line.php b/Examples/33chartcreate-line.php index 3e9ec7675..dce75e06b 100644 --- a/Examples/33chartcreate-line.php +++ b/Examples/33chartcreate-line.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-multiple-charts.php b/Examples/33chartcreate-multiple-charts.php index ee45f0a23..7da2fa289 100644 --- a/Examples/33chartcreate-multiple-charts.php +++ b/Examples/33chartcreate-multiple-charts.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-pie.php b/Examples/33chartcreate-pie.php index 62360c4f2..1a4f1df4a 100644 --- a/Examples/33chartcreate-pie.php +++ b/Examples/33chartcreate-pie.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-radar.php b/Examples/33chartcreate-radar.php index 179dec0e7..29fb2200f 100644 --- a/Examples/33chartcreate-radar.php +++ b/Examples/33chartcreate-radar.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-scatter.php b/Examples/33chartcreate-scatter.php index 467d60155..53851ad46 100644 --- a/Examples/33chartcreate-scatter.php +++ b/Examples/33chartcreate-scatter.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/33chartcreate-stock.php b/Examples/33chartcreate-stock.php index 080662769..dfc8d5cdd 100644 --- a/Examples/33chartcreate-stock.php +++ b/Examples/33chartcreate-stock.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/34chartupdate.php b/Examples/34chartupdate.php index e3e320e01..84f8a9221 100644 --- a/Examples/34chartupdate.php +++ b/Examples/34chartupdate.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/35chartrender.php b/Examples/35chartrender.php index 7d6e3cafc..710cddb49 100644 --- a/Examples/35chartrender.php +++ b/Examples/35chartrender.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/36chartreadwriteHTML.php b/Examples/36chartreadwriteHTML.php index 6811c274a..b4bae11cb 100644 --- a/Examples/36chartreadwriteHTML.php +++ b/Examples/36chartreadwriteHTML.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/36chartreadwritePDF.php b/Examples/36chartreadwritePDF.php index a3517f39d..10d62cd04 100644 --- a/Examples/36chartreadwritePDF.php +++ b/Examples/36chartreadwritePDF.php @@ -13,7 +13,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,7 +31,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/37page_layout_view.php b/Examples/37page_layout_view.php index 042e8e851..070f512a2 100644 --- a/Examples/37page_layout_view.php +++ b/Examples/37page_layout_view.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/38cloneWorksheet.php b/Examples/38cloneWorksheet.php index d2f9a6d45..901b887ee 100644 --- a/Examples/38cloneWorksheet.php +++ b/Examples/38cloneWorksheet.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/Excel2003XMLReader.php b/Examples/Excel2003XMLReader.php index 96ee5a3f6..00d96ddd8 100644 --- a/Examples/Excel2003XMLReader.php +++ b/Examples/Excel2003XMLReader.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/GnumericReader.php b/Examples/GnumericReader.php index 4304ccccb..7ddd74df0 100644 --- a/Examples/GnumericReader.php +++ b/Examples/GnumericReader.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/OOCalcReader.php b/Examples/OOCalcReader.php index 237d12462..b96dcbbc5 100644 --- a/Examples/OOCalcReader.php +++ b/Examples/OOCalcReader.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/OOCalcReaderPCLZip.php b/Examples/OOCalcReaderPCLZip.php index 2f3f922fa..45a5cdacb 100644 --- a/Examples/OOCalcReaderPCLZip.php +++ b/Examples/OOCalcReaderPCLZip.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/SylkReader.php b/Examples/SylkReader.php index 9c7a5bee0..ab144e0a4 100644 --- a/Examples/SylkReader.php +++ b/Examples/SylkReader.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/XMLReader.php b/Examples/XMLReader.php index ca5e4bcf2..33eda282a 100644 --- a/Examples/XMLReader.php +++ b/Examples/XMLReader.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Examples/runall.php b/Examples/runall.php index d41249399..c686d4d32 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (C) 2006 - 2013 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/unitTests/bootstrap.php b/unitTests/bootstrap.php index 19b31a883..8e8cdb39a 100644 --- a/unitTests/bootstrap.php +++ b/unitTests/bootstrap.php @@ -2,7 +2,7 @@ /** * $Id: bootstrap.php 2892 2011-08-14 15:11:50Z markbaker@phpexcel.net $ * - * @copyright Copyright (C) 2011-2013 PHPExcel. All rights reserved. + * @copyright Copyright (C) 2011-2014 PHPExcel. All rights reserved. * @package PHPExcel * @subpackage PHPExcel Unit Tests * @author Mark Baker From dde17c4e1dcf94fd0143fa81f2674bb1bda77b75 Mon Sep 17 00:00:00 2001 From: Navarr Barnier Date: Fri, 3 Jan 2014 16:59:32 -0500 Subject: [PATCH 180/467] Add ext-xmlwriter as a Composer requirement XMLWriter is surprisingly a different extension from xml; and so is not installed on some systems (such as Gentoo). This commit enforces it to be installed, since it's necessary for the functionality of PHPExcel. --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f0bd60e1c..ff18cb842 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ ], "require": { "php": ">=5.2.0", - "ext-xml": "*" + "ext-xml": "*", + "ext-xmlwriter": "*" }, "recommend": { "ext-zip": "*", From 496b76e70a3851d953bdede580e7d9a4390584fa Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Wed, 8 Jan 2014 10:15:07 +0000 Subject: [PATCH 181/467] Bugfix: Work Item CP20604 - Adding Sheet to Workbook Bug --- Classes/PHPExcel.php | 5 +++++ Classes/PHPExcel/Worksheet.php | 16 +++++++++------- changelog.txt | 1 + 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index 29d0aa0f4..e01581a24 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -527,6 +527,11 @@ public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = NULL) ++$this->_activeSheetIndex; } } + + if ($pSheet->getParent() === null) { + $pSheet->rebindParent($this); + } + return $pSheet; } diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 753e9c2aa..b61f76e6c 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -794,14 +794,16 @@ public function getParent() { * @return PHPExcel_Worksheet */ public function rebindParent(PHPExcel $parent) { - $namedRanges = $this->_parent->getNamedRanges(); - foreach ($namedRanges as $namedRange) { - $parent->addNamedRange($namedRange); - } + if ($this->_parent !== null) { + $namedRanges = $this->_parent->getNamedRanges(); + foreach ($namedRanges as $namedRange) { + $parent->addNamedRange($namedRange); + } - $this->_parent->removeSheetByIndex( - $this->_parent->getIndex($this) - ); + $this->_parent->removeSheetByIndex( + $this->_parent->getIndex($this) + ); + } $this->_parent = $parent; return $this; diff --git a/changelog.txt b/changelog.txt index 96f97c6de..1d1222b95 100644 --- a/changelog.txt +++ b/changelog.txt @@ -46,6 +46,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (Roy Shahbazian) Work Item GH-299 - Fixed typo in Chart/Layout set/getYMode() - Bugfix: (EliuFlorez) Work item GH-279 - Fatal error: Call to a member function cellExists() line: 3327 in calculation.php if referenced worksheet doesn't exist - Bugfix: (MBaker) Work Item GH-290 - AdvancedValueBinder "Division by zero"-error +- Bugfix: (MBaker) Work Item CP20604 - Adding Sheet to Workbook Bug - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From a0da3e32ec3db87fe2a41d9fee70a0099de676bb Mon Sep 17 00:00:00 2001 From: Adrien Crivelli Date: Fri, 17 Jan 2014 21:01:57 +0900 Subject: [PATCH 182/467] Double quote support for SUMIF() condition SUMIF() condition can have double quote, such as '=SUMIF(A2:A4,">""",B2:B4)'. This formula purpose is to compare the character double quote ("). In our previous patch (commit f1a1f525) we wrongly assumed that PHPExcel_Calculation_MathTrig::SUMIF() expected the condition to escaped ('>""'), but this is actually not the case in real use of PHPExcel, so the unit tests were modified accordingly to use non-escaped condition ('>"'). --- Classes/PHPExcel/Calculation/Functions.php | 7 ++++++- .../PHPExcel/Calculation/MathTrigTest.php | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index c9ac97bb4..df21ac4f4 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -316,7 +316,12 @@ public static function _ifCondition($condition) { } else { preg_match('/([<>=]+)(.*)/',$condition,$matches); list(,$operator,$operand) = $matches; - if (!is_numeric($operand)) { $operand = PHPExcel_Calculation::_wrapResult(strtoupper($operand)); } + + if (!is_numeric($operand)) { + $operand = str_replace('"', '""', $operand); + $operand = PHPExcel_Calculation::_wrapResult(strtoupper($operand)); + } + return $operator.$operand; } } // function _ifCondition() diff --git a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php index d6eaba022..e3d8c9d98 100644 --- a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php @@ -521,7 +521,7 @@ public function providerSUMIF() array('"text with quotes"'), array(2), ), - '=""text with quotes""', + '="text with quotes"', array( array(10), array(100), @@ -533,13 +533,25 @@ public function providerSUMIF() array('"text with quotes"'), array(''), ), - '>""', // Compare to the single characater " (double quote) + '>"', // Compare to the single characater " (double quote) array( array(10), array(100), ), 10 ), + array( + array( + array(''), + array('anything'), + ), + '>"', // Compare to the single characater " (double quote) + array( + array(10), + array(100), + ), + 100 + ), ); } From 353c46886ce89d656837d12289780a9cae955b03 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 9 Feb 2014 15:27:36 +0000 Subject: [PATCH 183/467] Extend headers to handle IE 9 problems and IE/SSL caching problems --- Examples/01simple-download-xlsx.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Examples/01simple-download-xlsx.php b/Examples/01simple-download-xlsx.php index c37be637a..538888ea7 100644 --- a/Examples/01simple-download-xlsx.php +++ b/Examples/01simple-download-xlsx.php @@ -75,6 +75,14 @@ header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment;filename="01simple.xlsx"'); header('Cache-Control: max-age=0'); +// If you're serving to IE 9, then the following may be needed +header('Cache-Control: max-age=1'); + +// If you're serving to IE over SSL, then the following may be needed +header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past +header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified +header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1 +header ('Pragma: public'); // HTTP/1.0 $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save('php://output'); From 220da7485ed450e0c12e53592bbbbeb83f888db6 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 9 Feb 2014 16:08:17 +0000 Subject: [PATCH 184/467] Bugfix: Work item CP20703 - Calculation engine incorrectly evaluates empty cells as #VALUE --- Classes/PHPExcel/Calculation.php | 13 +++++++------ changelog.txt | 9 +++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index c8ddbbd64..6159be9ba 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -3663,22 +3663,23 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope } } else { if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) && - ((is_string($operand1) && !is_numeric($operand1)) || (is_string($operand2) && !is_numeric($operand2)))) { + ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || + (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) { $result = PHPExcel_Calculation_Functions::VALUE(); } else { // If we're dealing with non-matrix operations, execute the necessary operation switch ($operation) { // Addition case '+': - $result = $operand1+$operand2; + $result = $operand1 + $operand2; break; // Subtraction case '-': - $result = $operand1-$operand2; + $result = $operand1 - $operand2; break; // Multiplication case '*': - $result = $operand1*$operand2; + $result = $operand1 * $operand2; break; // Division case '/': @@ -3688,12 +3689,12 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); return FALSE; } else { - $result = $operand1/$operand2; + $result = $operand1 / $operand2; } break; // Power case '^': - $result = pow($operand1,$operand2); + $result = pow($operand1, $operand2); break; } } diff --git a/changelog.txt b/changelog.txt index 1d1222b95..2029aee3d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -24,12 +24,12 @@ Fixed in develop branch for release v1.8.0: -- Bugfix: (MBaker) Work item 19830 - Undefined variable: fileHandle in CSV Reader -- Bugfix: (MBaker) Work item 19968 - Out of memory in style/supervisor.php +- Bugfix: (MBaker) Work item CP19830 - Undefined variable: fileHandle in CSV Reader +- Bugfix: (MBaker) Work item CP19968 - Out of memory in style/supervisor.php - Bugfix: (MBaker) - Style error with merged cells in PDF Writer - Bugfix: (MBaker) - Problem with cloning worksheets - Bugfix: (tavoarcila) Work Item GH-259 - Bug fix reading Open Office files -- Bugfix: (MBaker) Work item 20397 - Serious bug in absolute cell reference used in shared formula +- Bugfix: (MBaker) Work item CP20397 - Serious bug in absolute cell reference used in shared formula Would also have affected insert/delete column/row - Bugfix: (RomanSyroeshko) Work Item GH-267 - CHOOSE() returns "#VALUE!" if the 1st entry is chosen - Bugfix: (Gemorroj) Work Item GH-268 - When duplicating styles, styles shifted by one column to the right @@ -47,12 +47,13 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (EliuFlorez) Work item GH-279 - Fatal error: Call to a member function cellExists() line: 3327 in calculation.php if referenced worksheet doesn't exist - Bugfix: (MBaker) Work Item GH-290 - AdvancedValueBinder "Division by zero"-error - Bugfix: (MBaker) Work Item CP20604 - Adding Sheet to Workbook Bug +- Bugfix: (MBaker) Work item CP20703 - Calculation engine incorrectly evaluates empty cells as #VALUE - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer - Feature: (trvrnrth) Work Item GH-261 - Add support for reading protected (RC4 encrypted) .xls files - Feature: (LWol) Work Item GH-252 - Adding support for macros, Ribbon in Excel 2007 -- General: (cdhutch) Work item 20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed +- General: (cdhutch) Work item CP20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed - General: (MBaker) - Improve stock chart handling and rendering, with help from Swashata Ghosh - General: (MBaker) - Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load if it's actually required - General: (MBaker) - Modified Excel2007 Writer to default preCalculateFormulas to false From 1dad68114283623eb5d619fbce18cdb64636d926 Mon Sep 17 00:00:00 2001 From: Maarten Balliauw Date: Fri, 21 Feb 2014 09:23:55 +0100 Subject: [PATCH 185/467] Disabled libxml external entity loading by default. If you want to allow loading external entity references in XML, call PHPExcel_Settings::setLibXmlLoaderOptions(0). --- Classes/PHPExcel/Reader/Excel2003XML.php | 6 +- Classes/PHPExcel/Reader/Excel2007.php | 484 +++++++++++------------ Classes/PHPExcel/Reader/Gnumeric.php | 6 +- Classes/PHPExcel/Reader/OOCalc.php | 10 +- Classes/PHPExcel/Settings.php | 33 +- 5 files changed, 285 insertions(+), 254 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index b08ec8647..17472d040 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -137,7 +137,7 @@ public function listWorksheetNames($pFilename) $worksheetNames = array(); - $xml = simplexml_load_file($pFilename); + $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespaces = $xml->getNamespaces(true); $xml_ss = $xml->children($namespaces['ss']); @@ -165,7 +165,7 @@ public function listWorksheetInfo($pFilename) $worksheetInfo = array(); - $xml = simplexml_load_file($pFilename); + $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespaces = $xml->getNamespaces(true); $worksheetID = 1; @@ -330,7 +330,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } - $xml = simplexml_load_file($pFilename); + $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespaces = $xml->getNamespaces(true); $docProps = $objPHPExcel->getProperties(); diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index ed0376e73..05d053d17 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -59,15 +59,15 @@ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPE private static $_theme = NULL; - /** - * Create a new PHPExcel_Reader_Excel2007 instance - */ - public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); - } - - + /** + * Create a new PHPExcel_Reader_Excel2007 instance + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); + } + + /** * Can the current PHPExcel_Reader_IReader read the file? * @@ -94,7 +94,7 @@ public function canRead($pFilename) $zip = new $zipClass; if ($zip->open($pFilename) === true) { // check if it is an OOXML archive - $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels")); + $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if ($rels !== false) { foreach ($rels->Relationship as $rel) { switch ($rel["Type"]) { @@ -113,7 +113,7 @@ public function canRead($pFilename) return $xl; } - + /** * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object * @@ -136,13 +136,13 @@ public function listWorksheetNames($pFilename) // The files we're looking at here are small enough that simpleXML is more efficient than XMLReader $rels = simplexml_load_string( - $this->_getFromZipArchive($zip, "_rels/.rels") + $this->_getFromZipArchive($zip, "_rels/.rels", 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($rels->Relationship as $rel) { switch ($rel["Type"]) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": $xmlWorkbook = simplexml_load_string( - $this->_getFromZipArchive($zip, "{$rel['Target']}") + $this->_getFromZipArchive($zip, "{$rel['Target']}", 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) ); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); if ($xmlWorkbook->sheets) { @@ -160,56 +160,56 @@ public function listWorksheetNames($pFilename) } - /** - * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetInfo($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $worksheetInfo = array(); - + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + $zipClass = PHPExcel_Settings::getZipClass(); - $zip = new $zipClass; - $zip->open($pFilename); - - $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - foreach ($rels->Relationship as $rel) { - if ($rel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument") { - $dir = dirname($rel["Target"]); - $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); - - $worksheets = array(); - foreach ($relsWorkbook->Relationship as $ele) { - if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet") { - $worksheets[(string) $ele["Id"]] = $ele["Target"]; - } - } - - $xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - if ($xmlWorkbook->sheets) { - $dir = dirname($rel["Target"]); - foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { - $tmpInfo = array( - 'worksheetName' => (string) $eleSheet["name"], - 'lastColumnLetter' => 'A', - 'lastColumnIndex' => 0, - 'totalRows' => 0, - 'totalColumns' => 0, + $zip = new $zipClass; + $zip->open($pFilename); + + $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($rels->Relationship as $rel) { + if ($rel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument") { + $dir = dirname($rel["Target"]); + $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); + + $worksheets = array(); + foreach ($relsWorkbook->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet") { + $worksheets[(string) $ele["Id"]] = $ele["Target"]; + } + } + + $xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + if ($xmlWorkbook->sheets) { + $dir = dirname($rel["Target"]); + foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { + $tmpInfo = array( + 'worksheetName' => (string) $eleSheet["name"], + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, ); - - $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + + $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; $xml = new XMLReader(); - $res = $xml->open('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet"); + $res = $xml->open('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet", null, PHPExcel_Settings::getLibXmlLoaderOptions()); $xml->setParserProperty(2,true); $currCells = 0; @@ -229,18 +229,18 @@ public function listWorksheetInfo($pFilename) $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); - $worksheetInfo[] = $tmpInfo; - } - } - } - } - - $zip->close(); - - return $worksheetInfo; - } - - + $worksheetInfo[] = $tmpInfo; + } + } + } + } + + $zip->close(); + + return $worksheetInfo; + } + + private static function _castToBool($c) { // echo 'Initial Cast to Boolean
'; $value = isset($c->v) ? (string) $c->v : NULL; @@ -254,19 +254,19 @@ private static function _castToBool($c) { return $value; } // function _castToBool() - + private static function _castToError($c) { // echo 'Initial Cast to Error
'; return isset($c->v) ? (string) $c->v : NULL; } // function _castToError() - + private static function _castToString($c) { // echo 'Initial Cast to String
'; return isset($c->v) ? (string) $c->v : NULL; } // function _castToString() - + private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) { // echo 'Formula',PHP_EOL; // echo '$c->f is '.$c->f.PHP_EOL; @@ -313,7 +313,7 @@ private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,& } } - + public function _getFromZipArchive($archive, $fileName = '') { // Root-relative paths @@ -333,7 +333,7 @@ public function _getFromZipArchive($archive, $fileName = '') return $contents; } - + /** * Loads PHPExcel from file * @@ -361,19 +361,19 @@ public function load($pFilename) $zip->open($pFilename); // Read the theme first, because we need the colour scheme when reading the styles - $wbRels = simplexml_load_string($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $wbRels = simplexml_load_string($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($wbRels->Relationship as $rel) { switch ($rel["Type"]) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme": $themeOrderArray = array('lt1','dk1','lt2','dk2'); $themeOrderAdditional = count($themeOrderArray); - $xmlTheme = simplexml_load_string($this->_getFromZipArchive($zip, "xl/{$rel['Target']}")); + $xmlTheme = simplexml_load_string($this->_getFromZipArchive($zip, "xl/{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlTheme)) { $xmlThemeName = $xmlTheme->attributes(); $xmlTheme = $xmlTheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); $themeName = (string)$xmlThemeName['name']; - + $colourScheme = $xmlTheme->themeElements->clrScheme->attributes(); $colourSchemeName = (string)$colourScheme['name']; $colourScheme = $xmlTheme->themeElements->clrScheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); @@ -398,11 +398,11 @@ public function load($pFilename) } } - $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($rels->Relationship as $rel) { switch ($rel["Type"]) { case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties": - $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}")); + $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { $xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/"); $xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/"); @@ -421,7 +421,7 @@ public function load($pFilename) break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties": - $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}")); + $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { $docProps = $excel->getProperties(); if (isset($xmlCore->Company)) @@ -432,7 +432,7 @@ public function load($pFilename) break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties": - $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}")); + $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { $docProps = $excel->getProperties(); foreach ($xmlCore as $xmlProperty) { @@ -458,12 +458,12 @@ public function load($pFilename) break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": $dir = dirname($rel["Target"]); - $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); $sharedStrings = array(); $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']")); - $xmlStrings = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlStrings = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); if (isset($xmlStrings) && isset($xmlStrings->si)) { foreach ($xmlStrings->si as $val) { if (isset($val->t)) { @@ -502,7 +502,7 @@ public function load($pFilename) $styles = array(); $cellStyles = array(); $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); - $xmlStyles = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlStyles = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); $numFmts = null; if ($xmlStyles && $xmlStyles->numFmts[0]) { $numFmts = $xmlStyles->numFmts[0]; @@ -582,7 +582,7 @@ public function load($pFilename) $dxfs = array(); if (!$this->_readDataOnly && $xmlStyles) { - // Conditional Styles + // Conditional Styles if ($xmlStyles->dxfs) { foreach ($xmlStyles->dxfs->dxf as $dxf) { $style = new PHPExcel_Style(FALSE, TRUE); @@ -590,7 +590,7 @@ public function load($pFilename) $dxfs[] = $style; } } - // Cell Styles + // Cell Styles if ($xmlStyles->cellStyles) { foreach ($xmlStyles->cellStyles->cellStyle as $cellStyle) { if (intval($cellStyle['builtinId']) == 0) { @@ -606,7 +606,7 @@ public function load($pFilename) } } - $xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); // Set base date if ($xmlWorkbook->workbookPr) { @@ -643,13 +643,13 @@ public function load($pFilename) // Load sheet $docSheet = $excel->createSheet(); - // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet - // references in formula cells... during the load, all formulae should be correct, - // and we're simply bringing the worksheet name in line with the formula, not the - // reverse + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet + // references in formula cells... during the load, all formulae should be correct, + // and we're simply bringing the worksheet name in line with the formula, not the + // reverse $docSheet->setTitle((string) $eleSheet["name"],false); $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; - $xmlSheet = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$fileWorksheet")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlSheet = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$fileWorksheet"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); $sharedFormulas = array(); @@ -666,10 +666,10 @@ public function load($pFilename) $docSheet->getSheetView()->setZoomScaleNormal( intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal']) ); } - if (isset($xmlSheet->sheetViews->sheetView['view'])) { - $docSheet->getSheetView()->setView((string) $xmlSheet->sheetViews->sheetView['view']); - } - + if (isset($xmlSheet->sheetViews->sheetView['view'])) { + $docSheet->getSheetView()->setView((string) $xmlSheet->sheetViews->sheetView['view']); + } + if (isset($xmlSheet->sheetViews->sheetView['showGridLines'])) { $docSheet->setShowGridLines(self::boolean((string)$xmlSheet->sheetViews->sheetView['showGridLines'])); } @@ -754,9 +754,9 @@ public function load($pFilename) if (isset($xmlSheet->sheetFormatPr['defaultColWidth'])) { $docSheet->getDefaultColumnDimension()->setWidth( (float)$xmlSheet->sheetFormatPr['defaultColWidth'] ); } - if (isset($xmlSheet->sheetFormatPr['zeroHeight']) && - ((string)$xmlSheet->sheetFormatPr['zeroHeight'] == '1')) { - $docSheet->getDefaultRowDimension()->setzeroHeight(true); + if (isset($xmlSheet->sheetFormatPr['zeroHeight']) && + ((string)$xmlSheet->sheetFormatPr['zeroHeight'] == '1')) { + $docSheet->getDefaultRowDimension()->setzeroHeight(true); } } @@ -864,11 +864,11 @@ public function load($pFilename) } else { // Formula $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToBool'); - if (isset($c->f['t'])) { - $att = array(); - $att = $c->f; - $docSheet->getCell($r)->setFormulaAttributes($att); - } + if (isset($c->f['t'])) { + $att = array(); + $att = $c->f; + $docSheet->getCell($r)->setFormulaAttributes($att); + } // echo '$calculatedValue = '.$calculatedValue.'
'; } break; @@ -985,7 +985,7 @@ public function load($pFilename) } } } - + $aKeys = array("sheet", "objects", "scenarios", "formatCells", "formatColumns", "formatRows", "insertColumns", "insertRows", "insertHyperlinks", "deleteColumns", "deleteRows", "selectLockedCells", "sort", "autoFilter", "pivotTables", "selectUnlockedCells"); if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { foreach ($aKeys as $key) { @@ -1004,111 +1004,111 @@ public function load($pFilename) } if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { - $autoFilter = $docSheet->getAutoFilter(); + $autoFilter = $docSheet->getAutoFilter(); $autoFilter->setRange((string) $xmlSheet->autoFilter["ref"]); - foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { - $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); - // Check for standard filters - if ($filterColumn->filters) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER); - $filters = $filterColumn->filters; - if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - '' - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); - } - // Standard filters are always an OR join, so no join rule needs to be set - // Entries can be either filter elements - foreach ($filters->filter as $filterRule) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - (string) $filterRule["val"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); - } - // Or Date Group elements - foreach ($filters->dateGroupItem as $dateGroupItem) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - array( - 'year' => (string) $dateGroupItem["year"], - 'month' => (string) $dateGroupItem["month"], - 'day' => (string) $dateGroupItem["day"], - 'hour' => (string) $dateGroupItem["hour"], - 'minute' => (string) $dateGroupItem["minute"], - 'second' => (string) $dateGroupItem["second"], - ), - (string) $dateGroupItem["dateTimeGrouping"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); - } - } - // Check for custom filters - if ($filterColumn->customFilters) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER); - $customFilters = $filterColumn->customFilters; - // Custom filters can an AND or an OR join; - // and there should only ever be one or two entries - if ((isset($customFilters["and"])) && ($customFilters["and"] == 1)) { - $column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); - } - foreach ($customFilters->customFilter as $filterRule) { - $column->createRule()->setRule( - (string) $filterRule["operator"], - (string) $filterRule["val"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); - } - } - // Check for dynamic filters - if ($filterColumn->dynamicFilter) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); - // We should only ever have one dynamic filter - foreach ($filterColumn->dynamicFilter as $filterRule) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - (string) $filterRule["val"], - (string) $filterRule["type"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER); - if (isset($filterRule["val"])) { - $column->setAttribute('val',(string) $filterRule["val"]); - } - if (isset($filterRule["maxVal"])) { - $column->setAttribute('maxVal',(string) $filterRule["maxVal"]); - } - } - } - // Check for dynamic filters - if ($filterColumn->top10) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER); - // We should only ever have one top10 filter - foreach ($filterColumn->top10 as $filterRule) { - $column->createRule()->setRule( - (((isset($filterRule["percent"])) && ($filterRule["percent"] == 1)) - ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT - : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE - ), - (string) $filterRule["val"], - (((isset($filterRule["top"])) && ($filterRule["top"] == 1)) - ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP - : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM - ) - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER); - } - } - } + foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { + $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); + // Check for standard filters + if ($filterColumn->filters) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER); + $filters = $filterColumn->filters; + if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + '' + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + } + // Standard filters are always an OR join, so no join rule needs to be set + // Entries can be either filter elements + foreach ($filters->filter as $filterRule) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + (string) $filterRule["val"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + } + // Or Date Group elements + foreach ($filters->dateGroupItem as $dateGroupItem) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + array( + 'year' => (string) $dateGroupItem["year"], + 'month' => (string) $dateGroupItem["month"], + 'day' => (string) $dateGroupItem["day"], + 'hour' => (string) $dateGroupItem["hour"], + 'minute' => (string) $dateGroupItem["minute"], + 'second' => (string) $dateGroupItem["second"], + ), + (string) $dateGroupItem["dateTimeGrouping"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); + } + } + // Check for custom filters + if ($filterColumn->customFilters) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER); + $customFilters = $filterColumn->customFilters; + // Custom filters can an AND or an OR join; + // and there should only ever be one or two entries + if ((isset($customFilters["and"])) && ($customFilters["and"] == 1)) { + $column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); + } + foreach ($customFilters->customFilter as $filterRule) { + $column->createRule()->setRule( + (string) $filterRule["operator"], + (string) $filterRule["val"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); + } + } + // Check for dynamic filters + if ($filterColumn->dynamicFilter) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); + // We should only ever have one dynamic filter + foreach ($filterColumn->dynamicFilter as $filterRule) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + (string) $filterRule["val"], + (string) $filterRule["type"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER); + if (isset($filterRule["val"])) { + $column->setAttribute('val',(string) $filterRule["val"]); + } + if (isset($filterRule["maxVal"])) { + $column->setAttribute('maxVal',(string) $filterRule["maxVal"]); + } + } + } + // Check for dynamic filters + if ($filterColumn->top10) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER); + // We should only ever have one top10 filter + foreach ($filterColumn->top10 as $filterRule) { + $column->createRule()->setRule( + (((isset($filterRule["percent"])) && ($filterRule["percent"] == 1)) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE + ), + (string) $filterRule["val"], + (((isset($filterRule["top"])) && ($filterRule["top"] == 1)) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM + ) + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER); + } + } + } } if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) { foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) { - $mergeRef = (string) $mergeCell["ref"]; - if (strpos($mergeRef,':') !== FALSE) { + $mergeRef = (string) $mergeCell["ref"]; + if (strpos($mergeRef,':') !== FALSE) { $docSheet->mergeCells((string) $mergeCell["ref"]); - } + } } } @@ -1233,7 +1233,7 @@ public function load($pFilename) if (!$this->_readDataOnly) { // Locate hyperlink relations if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") { $hyperlinks[(string)$ele["Id"]] = (string)$ele["Target"]; @@ -1274,7 +1274,7 @@ public function load($pFilename) if (!$this->_readDataOnly) { // Locate comment relations if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") { $comments[(string)$ele["Id"]] = (string)$ele["Target"]; @@ -1289,7 +1289,7 @@ public function load($pFilename) foreach ($comments as $relName => $relPath) { // Load comments file $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); - $commentsFile = simplexml_load_string($this->_getFromZipArchive($zip, $relPath) ); + $commentsFile = simplexml_load_string($this->_getFromZipArchive($zip, $relPath) , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); // Utility variables $authors = array(); @@ -1310,7 +1310,7 @@ public function load($pFilename) foreach ($vmlComments as $relName => $relPath) { // Load VML comments file $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); - $vmlCommentsFile = simplexml_load_string( $this->_getFromZipArchive($zip, $relPath) ); + $vmlCommentsFile = simplexml_load_string( $this->_getFromZipArchive($zip, $relPath) , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); $shapes = $vmlCommentsFile->xpath('//v:shape'); @@ -1361,7 +1361,7 @@ public function load($pFilename) // Header/footer images if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) { if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $vmlRelationship = ''; foreach ($relsWorksheet->Relationship as $ele) { @@ -1372,7 +1372,7 @@ public function load($pFilename) if ($vmlRelationship != '') { // Fetch linked images - $relsVML = simplexml_load_string($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels' )); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsVML = simplexml_load_string($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels' ), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $drawings = array(); foreach ($relsVML->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { @@ -1381,7 +1381,7 @@ public function load($pFilename) } // Fetch VML document - $vmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $vmlRelationship)); + $vmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $vmlRelationship), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); $hfImages = array(); @@ -1420,7 +1420,7 @@ public function load($pFilename) // TODO: Autoshapes from twoCellAnchors! if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $drawings = array(); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing") { @@ -1430,7 +1430,7 @@ public function load($pFilename) if ($xmlSheet->drawing && !$this->_readDataOnly) { foreach ($xmlSheet->drawing as $drawing) { $fileDrawing = $drawings[(string) self::array_item($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; - $relsDrawing = simplexml_load_string($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsDrawing = simplexml_load_string($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $images = array(); if ($relsDrawing && $relsDrawing->Relationship) { @@ -1438,15 +1438,15 @@ public function load($pFilename) if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { $images[(string) $ele["Id"]] = self::dir_add($fileDrawing, $ele["Target"]); } elseif ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart") { - if ($this->_includeCharts) { + if ($this->_includeCharts) { $charts[self::dir_add($fileDrawing, $ele["Target"])] = array('id' => (string) $ele["Id"], 'sheet' => $docSheet->getTitle() ); } - } + } } } - $xmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $fileDrawing))->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"); + $xmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $fileDrawing), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"); if ($xmlDrawing->oneCellAnchor) { foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) { @@ -1479,7 +1479,7 @@ public function load($pFilename) } $objDrawing->setWorksheet($docSheet); } else { - // ? Can charts be positioned with a oneCellAnchor ? + // ? Can charts be positioned with a oneCellAnchor ? $coordinates = PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1); $offsetX = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff); $offsetY = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff); @@ -1520,7 +1520,7 @@ public function load($pFilename) $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); } $objDrawing->setWorksheet($docSheet); - } elseif(($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { + } elseif(($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { $fromCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1); $fromOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff); $fromOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff); @@ -1540,7 +1540,7 @@ public function load($pFilename) 'toOffsetY' => $toOffsetY, 'worksheetTitle' => $docSheet->getTitle() ); - } + } } } @@ -1570,10 +1570,10 @@ public function load($pFilename) // Switch on type switch ((string)$definedName['name']) { - case '_xlnm._FilterDatabase': - if ((string)$definedName['hidden'] !== '1') { + case '_xlnm._FilterDatabase': + if ((string)$definedName['hidden'] !== '1') { $docSheet->getAutoFilter()->setRange($extractedRange); - } + } break; case '_xlnm.Print_Titles': @@ -1710,13 +1710,13 @@ public function load($pFilename) if (!$this->_readDataOnly) { - $contentTypes = simplexml_load_string($this->_getFromZipArchive($zip, "[Content_Types].xml")); + $contentTypes = simplexml_load_string($this->_getFromZipArchive($zip, "[Content_Types].xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); foreach ($contentTypes->Override as $contentType) { switch ($contentType["ContentType"]) { case "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": - if ($this->_includeCharts) { + if ($this->_includeCharts) { $chartEntryRef = ltrim($contentType['PartName'],'/'); - $chartElements = simplexml_load_string($this->_getFromZipArchive($zip, $chartEntryRef)); + $chartElements = simplexml_load_string($this->_getFromZipArchive($zip, $chartEntryRef), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef,'.xml')); // echo 'Chart ',$chartEntryRef,'
'; @@ -1727,7 +1727,7 @@ public function load($pFilename) // echo 'Position Ref ',$chartPositionRef,'
'; if (isset($chartDetails[$chartPositionRef])) { // var_dump($chartDetails[$chartPositionRef]); - + $excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart); $objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet'])); $objChart->setTopLeftPosition( $chartDetails[$chartPositionRef]['fromCoordinate'], @@ -1739,7 +1739,7 @@ public function load($pFilename) $chartDetails[$chartPositionRef]['toOffsetY'] ); } - } + } } } } @@ -1749,7 +1749,7 @@ public function load($pFilename) return $excel; } - + private static function _readColor($color, $background=FALSE) { if (isset($color["rgb"])) { @@ -1773,16 +1773,16 @@ private static function _readColor($color, $background=FALSE) { return 'FF000000'; } - + private static function _readStyle($docStyle, $style) { // format code -// if (isset($style->numFmt)) { -// if (isset($style->numFmt['formatCode'])) { -// $docStyle->getNumberFormat()->setFormatCode((string) $style->numFmt['formatCode']); +// if (isset($style->numFmt)) { +// if (isset($style->numFmt['formatCode'])) { +// $docStyle->getNumberFormat()->setFormatCode((string) $style->numFmt['formatCode']); // } else { $docStyle->getNumberFormat()->setFormatCode($style->numFmt); -// } -// } +// } +// } // font if (isset($style->font)) { @@ -1820,7 +1820,7 @@ private static function _readStyle($docStyle, $style) { if (isset($style->fill)) { if ($style->fill->gradientFill) { $gradientFill = $style->fill->gradientFill[0]; - if(!empty($gradientFill["type"])) { + if(!empty($gradientFill["type"])) { $docStyle->getFill()->setFillType((string) $gradientFill["type"]); } $docStyle->getFill()->setRotation(floatval($gradientFill["degree"])); @@ -1903,7 +1903,7 @@ private static function _readStyle($docStyle, $style) { $docStyle->setQuotePrefix($style->quotePrefix); } } - + private static function _readBorder($docBorder, $eleBorder) { if (isset($eleBorder["style"])) { @@ -1914,7 +1914,7 @@ private static function _readBorder($docBorder, $eleBorder) { } } - + private function _parseRichText($is = null) { $value = new PHPExcel_RichText(); @@ -1990,7 +1990,7 @@ private function _readRibbon($excel, $customUITarget, $zip) $dataRels = $this->_getFromZipArchive($zip, $pathRels); if ($dataRels) { // exists and not empty if the ribbon have some pictures (other than internal MSO) - $UIRels = simplexml_load_string($dataRels); + $UIRels = simplexml_load_string($dataRels, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if ($UIRels) { // we need to save id and target to avoid parsing customUI.xml and "guess" if it's a pseudo callback who load the image foreach ($UIRels->Relationship as $ele) { @@ -1998,7 +1998,7 @@ private function _readRibbon($excel, $customUITarget, $zip) // an image ? $customUIImagesNames[(string) $ele['Id']] = (string)$ele['Target']; $customUIImagesBinaries[(string)$ele['Target']] = $this->_getFromZipArchive($zip, $baseDir . '/' . (string) $ele['Target']); - } + } } } } @@ -2019,12 +2019,12 @@ private static function array_item($array, $key = 0) { return (isset($array[$key]) ? $array[$key] : null); } - + private static function dir_add($base, $add) { return preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add"); } - + private static function toCSSArray($style) { $style = str_replace(array("\r","\n"), "", $style); diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index 790192b2f..d8121495d 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -117,7 +117,7 @@ public function listWorksheetNames($pFilename) $xml = new XMLReader(); $xml->open( - 'compress.zlib://'.realpath($pFilename) + 'compress.zlib://'.realpath($pFilename), null, PHPExcel_Settings::getLibXmlLoaderOptions() ); $xml->setParserProperty(2,true); @@ -151,7 +151,7 @@ public function listWorksheetInfo($pFilename) $xml = new XMLReader(); $xml->open( - 'compress.zlib://'.realpath($pFilename) + 'compress.zlib://'.realpath($pFilename), null, PHPExcel_Settings::getLibXmlLoaderOptions() ); $xml->setParserProperty(2,true); @@ -243,7 +243,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo htmlentities($gFileData,ENT_QUOTES,'UTF-8'); // echo '
'; // - $xml = simplexml_load_string($gFileData); + $xml = simplexml_load_string($gFileData, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespacesMeta = $xml->getNamespaces(true); // var_dump($namespacesMeta); diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index df7f23077..3eda756a2 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -90,7 +90,7 @@ public function canRead($pFilename) if ($stat && ($stat['size'] <= 255)) { $mimeType = $zip->getFromName($stat['name']); } elseif($stat = $zip->statName('META-INF/manifest.xml')) { - $xml = simplexml_load_string($zip->getFromName('META-INF/manifest.xml')); + $xml = simplexml_load_string($zip->getFromName('META-INF/manifest.xml'), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespacesContent = $xml->getNamespaces(true); if (isset($namespacesContent['manifest'])) { $manifest = $xml->children($namespacesContent['manifest']); @@ -136,7 +136,7 @@ public function listWorksheetNames($pFilename) $worksheetNames = array(); $xml = new XMLReader(); - $res = $xml->open('zip://'.realpath($pFilename).'#content.xml'); + $res = $xml->open('zip://'.realpath($pFilename).'#content.xml', null, PHPExcel_Settings::getLibXmlLoaderOptions()); $xml->setParserProperty(2,true); // Step into the first level of content of the XML @@ -188,7 +188,7 @@ public function listWorksheetInfo($pFilename) } $xml = new XMLReader(); - $res = $xml->open('zip://'.realpath($pFilename).'#content.xml'); + $res = $xml->open('zip://'.realpath($pFilename).'#content.xml', null, PHPExcel_Settings::getLibXmlLoaderOptions()); $xml->setParserProperty(2,true); // Step into the first level of content of the XML @@ -345,7 +345,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } // echo '

Meta Information

'; - $xml = simplexml_load_string($zip->getFromName("meta.xml")); + $xml = simplexml_load_string($zip->getFromName("meta.xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespacesMeta = $xml->getNamespaces(true); // echo '
';
 //		print_r($namespacesMeta);
@@ -431,7 +431,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
 
 
 //		echo '

Workbook Content

'; - $xml = simplexml_load_string($zip->getFromName("content.xml")); + $xml = simplexml_load_string($zip->getFromName("content.xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespacesContent = $xml->getNamespaces(true); // echo '
';
 //		print_r($namespacesContent);
diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php
index 5cf8ed652..03e1a2647 100644
--- a/Classes/PHPExcel/Settings.php
+++ b/Classes/PHPExcel/Settings.php
@@ -105,6 +105,12 @@ class PHPExcel_Settings
      */
     private static $_pdfRendererPath = NULL;
 
+    /**
+     * Default options for libxml loader
+     *
+     * @var int
+     */
+    private static $_libXmlLoaderOptions = null;
 
     /**
      * Set the Zip handler Class that PHPExcel should use for Zip file management (PCLZip or ZipArchive)
@@ -339,7 +345,6 @@ public static function getPdfRendererName()
         return self::$_pdfRendererName;
     } // function getPdfRendererName()
 
-
     /**
      * Return the directory path to the PDF Rendering Library that PHPExcel is currently configured to use
      *
@@ -351,4 +356,30 @@ public static function getPdfRendererPath()
         return self::$_pdfRendererPath;
     } // function getPdfRendererPath()
 
+    /**
+     * Set default options for libxml loader
+     *
+     * @param int $options Default options for libxml loader
+     */
+    public static function setLibXmlLoaderOptions($options = null)
+    {
+        if (is_null($options)) {
+            $options = LIBXML_DTDLOAD | LIBXML_DTDATTR;
+        }
+        self::$_libXmlLoaderOptions = $options;
+    } // function setLibXmlLoaderOptions
+
+    /**
+     * Get default options for libxml loader.
+     * Defaults to LIBXML_DTDLOAD | LIBXML_DTDATTR when not set explicitly.
+     *
+     * @return int Default options for libxml loader
+     */
+    public static function getLibXmlLoaderOptions()
+    {
+        if (is_null(self::$_libXmlLoaderOptions)) {
+            self::$_libXmlLoaderOptions = LIBXML_DTDLOAD | LIBXML_DTDATTR;
+        }
+        return self::$_libXmlLoaderOptions;
+    } // function getLibXmlLoaderOptions
 }
\ No newline at end of file

From c243bcb8ad2911cdbd0c272b284a516b444e606a Mon Sep 17 00:00:00 2001
From: Mark Baker 
Date: Fri, 21 Feb 2014 09:51:59 +0000
Subject: [PATCH 186/467] Updated documentation for XXE injection in readers

---
 ...umentation - Reading Spreadsheet Files.doc | Bin 174592 -> 178688 bytes
 .../ReadingSpreadsheetFiles/02-Security.md    |  22 ++++++++++++++++++
 ...adsheet.md => 03-Loading-a-Spreadsheet.md} |   0
 ...-Reader.md => 04-Loading-with-a-Reader.md} |   0
 ...Reader-Options.md => 07-Reader-Options.md} |   0
 changelog.txt                                 |   2 ++
 6 files changed, 24 insertions(+)
 create mode 100644 Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md
 rename Documentation/markdown/ReadingSpreadsheetFiles/{02-Loading-a-Spreadsheet.md => 03-Loading-a-Spreadsheet.md} (100%)
 rename Documentation/markdown/ReadingSpreadsheetFiles/{03-Loading-with-a-Reader.md => 04-Loading-with-a-Reader.md} (100%)
 rename Documentation/markdown/ReadingSpreadsheetFiles/{04-Reader-Options.md => 07-Reader-Options.md} (100%)

diff --git a/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc b/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc
index d1dde477f2e885b7112c2c09bb9506f7bb9992ba..c1dc2b55394d75f5779d83c48a5658ff3068ecda 100644
GIT binary patch
delta 25207
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

delta 22325
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
aUZYZtChm
Date: Fri, 21 Feb 2014 09:56:57 +0000
Subject: [PATCH 187/467] Warning in security docs

---
 Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md b/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md
index ee964643c..5c8cf9904 100644
--- a/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md
+++ b/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md
@@ -19,4 +19,6 @@ Should you ever need to change these settings, the following method is available
 PHPExcel_Settings::setLibXmlLoaderOptions();
 ```
 
-Allowing you to specify the XML loader settings that you want to use instead.
+Allowing you to specify the XML loader settings that those that you want to use instead.
+
+ > While PHPExcel protects you with its default settings, if you do change these settings yourself, then you're responsible for ensuring that your XML-based formats aren't open to XXE injection.

From 1abf061df3c95e939f88e631c1985693766ec179 Mon Sep 17 00:00:00 2001
From: Mark Baker 
Date: Fri, 21 Feb 2014 10:01:44 +0000
Subject: [PATCH 188/467] AS we're using simpleXML for xml reading still, we
 need to use libxml_disable_entity_loader(true); for XXE security patch

---
 Classes/PHPExcel/Settings.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php
index 03e1a2647..a550b55c5 100644
--- a/Classes/PHPExcel/Settings.php
+++ b/Classes/PHPExcel/Settings.php
@@ -377,6 +377,7 @@ public static function setLibXmlLoaderOptions($options = null)
      */
     public static function getLibXmlLoaderOptions()
     {
+        libxml_disable_entity_loader(true);
         if (is_null(self::$_libXmlLoaderOptions)) {
             self::$_libXmlLoaderOptions = LIBXML_DTDLOAD | LIBXML_DTDATTR;
         }

From fdc4532bc75426b7eb18643cae9aa92f09f37201 Mon Sep 17 00:00:00 2001
From: Maarten Balliauw 
Date: Fri, 21 Feb 2014 11:06:44 +0100
Subject: [PATCH 189/467] When libxmlloader options are teh default values,
 disable the entity loader as well. CVE-2014-2054 by MITRE

---
 Classes/PHPExcel/Settings.php | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php
index 03e1a2647..964146fb7 100644
--- a/Classes/PHPExcel/Settings.php
+++ b/Classes/PHPExcel/Settings.php
@@ -366,6 +366,7 @@ public static function setLibXmlLoaderOptions($options = null)
         if (is_null($options)) {
             $options = LIBXML_DTDLOAD | LIBXML_DTDATTR;
         }
+        @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); 
         self::$_libXmlLoaderOptions = $options;
     } // function setLibXmlLoaderOptions
 
@@ -378,8 +379,8 @@ public static function setLibXmlLoaderOptions($options = null)
     public static function getLibXmlLoaderOptions()
     {
         if (is_null(self::$_libXmlLoaderOptions)) {
-            self::$_libXmlLoaderOptions = LIBXML_DTDLOAD | LIBXML_DTDATTR;
+            self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR);
         }
         return self::$_libXmlLoaderOptions;
     } // function getLibXmlLoaderOptions
-}
\ No newline at end of file
+}

From 16c1a19d34525dfeea2f7d35baf34ab6f463503c Mon Sep 17 00:00:00 2001
From: Mark Baker 
Date: Fri, 21 Feb 2014 10:21:04 +0000
Subject: [PATCH 190/467] Update security section in Reader documentation

---
 ...umentation - Reading Spreadsheet Files.doc | Bin 178688 -> 178176 bytes
 .../ReadingSpreadsheetFiles/02-Security.md    |  13 +------------
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc b/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc
index c1dc2b55394d75f5779d83c48a5658ff3068ecda..a85a31689a5424f7b131d73e6b91bd67a4750db4 100644
GIT binary patch
delta 21075
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 delta 21486 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 LanvStviko3r1G)9 diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md b/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md index 5c8cf9904..12da958ff 100644 --- a/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md +++ b/Documentation/markdown/ReadingSpreadsheetFiles/02-Security.md @@ -10,15 +10,4 @@ XML-based formats such as OfficeOpen XML, Excel2003 XML, OASIS and Gnumeric are - Command Execution (depending on the installed PHP wrappers) -To prevent this, PHPExcel sets the LIBXML_DTDLOAD and LIBXML_DTDATTR settings for the XML Readers by default. - - -Should you ever need to change these settings, the following method is available through the PHPExcel_Settings: - -``` -PHPExcel_Settings::setLibXmlLoaderOptions(); -``` - -Allowing you to specify the XML loader settings that those that you want to use instead. - - > While PHPExcel protects you with its default settings, if you do change these settings yourself, then you're responsible for ensuring that your XML-based formats aren't open to XXE injection. +To prevent this, PHPExcel sets `libxml_disable_entity_loader` to `true` for the XML-based Readers by default. \ No newline at end of file From 6c8884b2eba9473e9859378cb640fd40cdc81911 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 21 Feb 2014 10:28:17 +0000 Subject: [PATCH 191/467] Hopefully final tweak for XXE to prevent displaying errors if SimpleXML isn't available --- Classes/PHPExcel/Settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php index cde7b6e7f..839231ba0 100644 --- a/Classes/PHPExcel/Settings.php +++ b/Classes/PHPExcel/Settings.php @@ -378,10 +378,10 @@ public static function setLibXmlLoaderOptions($options = null) */ public static function getLibXmlLoaderOptions() { - libxml_disable_entity_loader(true); if (is_null(self::$_libXmlLoaderOptions)) { self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR); } + @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); return self::$_libXmlLoaderOptions; } // function getLibXmlLoaderOptions } From 65178504caeb0605bd4ef7a7d7dee361a7c90978 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 21 Feb 2014 10:53:52 +0000 Subject: [PATCH 192/467] Added CVE reference to changelog --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 7ad3b0e2e..8d40e46aa 100644 --- a/changelog.txt +++ b/changelog.txt @@ -64,6 +64,7 @@ Fixed in develop branch for release v1.8.0: - General: (infojunkie) Work Item GH-276 - Convert properties to string in OOCalc reader - Security: (maartenba) Work Item GH-322 - Disable libxml external entity loading by default. This is to prevent XML External Entity Processing (XXE) injection attacks (see http://websec.io/2012/08/27/Preventing-XEE-in-PHP.html for an explanation of XXE injection). + Reference CVE-2014-2054 Fixed in develop branch for release v1.7.9: From 8f265a934297c8b8fe92f2cd03bcbd0f1316df70 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 21 Feb 2014 11:08:57 +0000 Subject: [PATCH 193/467] Added XXE protection to HTML Reader --- Classes/PHPExcel/Reader/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 3a832c114..5b32c9223 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -424,7 +424,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Create a new DOM object $dom = new domDocument; // Reload the HTML file into the DOM object - $loaded = $dom->loadHTMLFile($pFilename); + $loaded = $dom->loadHTMLFile($pFilename, PHPExcel_Settings::getLibXmlLoaderOptions()); if ($loaded === FALSE) { throw new PHPExcel_Reader_Exception('Failed to load ',$pFilename,' as a DOM Document'); } From 2caeb221227d1ef1e4ec2128343746ebc71ef6d4 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 22 Feb 2014 12:30:36 +0000 Subject: [PATCH 194/467] Bugfix: Work item CP20760 - Formula references to cell on another sheet in ODS files --- Classes/PHPExcel/Reader/OOCalc.php | 9 +++++---- changelog.txt | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 3eda756a2..01a34c15e 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -617,22 +617,23 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if ($hasCalculatedValue) { $type = PHPExcel_Cell_DataType::TYPE_FORMULA; -// echo 'Formula: '.$cellDataFormula.'
'; +// echo 'Formula: ', $cellDataFormula, PHP_EOL; $cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1); $temp = explode('"',$cellDataFormula); $tKey = false; foreach($temp as &$value) { // Only replace in alternate array entries (i.e. non-quoted blocks) if ($tKey = !$tKey) { - $value = preg_replace('/\[\.(.*):\.(.*)\]/Ui','$1:$2',$value); - $value = preg_replace('/\[\.(.*)\]/Ui','$1',$value); + $value = preg_replace('/\[(.+)\.(.*)\]/Ui','$1!$2',$value); // Cell reference in another sheet + $value = preg_replace('/\[\.(.*):\.(.*)\]/Ui','$1:$2',$value); // Cell range reference + $value = preg_replace('/\[\.(.*)\]/Ui','$1',$value); // Simple cell reference $value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces); } } unset($value); // Then rebuild the formula string $cellDataFormula = implode('"',$temp); -// echo 'Adjusted Formula: '.$cellDataFormula.'
'; +// echo 'Adjusted Formula: ', $cellDataFormula, PHP_EOL; } $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? diff --git a/changelog.txt b/changelog.txt index 8d40e46aa..8d9363076 100644 --- a/changelog.txt +++ b/changelog.txt @@ -48,6 +48,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (MBaker) Work Item GH-290 - AdvancedValueBinder "Division by zero"-error - Bugfix: (MBaker) Work Item CP20604 - Adding Sheet to Workbook Bug - Bugfix: (MBaker) Work item CP20703 - Calculation engine incorrectly evaluates empty cells as #VALUE +- Bugfix: (MBaker) Work item CP20760 - Formula references to cell on another sheet in ODS files - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From e892215970a3d6093afedd256800e4d373878c17 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 23 Feb 2014 15:35:05 +0000 Subject: [PATCH 195/467] Bugfix: Work item GH321, GH158, CP17824 - LibreOffice created XLSX files results in an empty file. Bugfix: Work item CP20760 - Formula references to cell on another sheet in ODS files --- Classes/PHPExcel/Reader/Excel2007.php | 68 ++++++++++--------- Classes/PHPExcel/Reader/OOCalc.php | 7 +- .../06largescale-with-cellcaching-sqlite.php | 7 +- .../06largescale-with-cellcaching-sqlite3.php | 7 +- Examples/runall.php | 2 + changelog.txt | 1 + 6 files changed, 53 insertions(+), 39 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 05d053d17..e1cef019c 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -242,7 +242,7 @@ public function listWorksheetInfo($pFilename) private static function _castToBool($c) { -// echo 'Initial Cast to Boolean
'; +// echo 'Initial Cast to Boolean', PHP_EOL; $value = isset($c->v) ? (string) $c->v : NULL; if ($value == '0') { return FALSE; @@ -256,46 +256,46 @@ private static function _castToBool($c) { private static function _castToError($c) { -// echo 'Initial Cast to Error
'; +// echo 'Initial Cast to Error', PHP_EOL; return isset($c->v) ? (string) $c->v : NULL; } // function _castToError() private static function _castToString($c) { -// echo 'Initial Cast to String
'; +// echo 'Initial Cast to String, PHP_EOL; return isset($c->v) ? (string) $c->v : NULL; } // function _castToString() private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) { -// echo 'Formula',PHP_EOL; -// echo '$c->f is '.$c->f.PHP_EOL; +// echo 'Formula', PHP_EOL; +// echo '$c->f is ', $c->f, PHP_EOL; $cellDataType = 'f'; $value = "={$c->f}"; $calculatedValue = self::$castBaseType($c); // Shared formula? if (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') { -// echo 'SHARED FORMULA'.PHP_EOL; +// echo 'SHARED FORMULA', PHP_EOL; $instance = (string)$c->f['si']; -// echo 'Instance ID = '.$instance.PHP_EOL; +// echo 'Instance ID = ', $instance, PHP_EOL; // -// echo 'Shared Formula Array:'.PHP_EOL; +// echo 'Shared Formula Array:', PHP_EOL; // print_r($sharedFormulas); if (!isset($sharedFormulas[(string)$c->f['si']])) { -// echo 'SETTING NEW SHARED FORMULA'.PHP_EOL; -// echo 'Master is '.$r.PHP_EOL; -// echo 'Formula is '.$value.PHP_EOL; +// echo 'SETTING NEW SHARED FORMULA', PHP_EOL; +// echo 'Master is ', $r, PHP_EOL; +// echo 'Formula is ', $value, PHP_EOL; $sharedFormulas[$instance] = array( 'master' => $r, 'formula' => $value ); -// echo 'New Shared Formula Array:'.PHP_EOL; +// echo 'New Shared Formula Array:', PHP_EOL; // print_r($sharedFormulas); } else { -// echo 'GETTING SHARED FORMULA'.PHP_EOL; -// echo 'Master is '.$sharedFormulas[$instance]['master'].PHP_EOL; -// echo 'Formula is '.$sharedFormulas[$instance]['formula'].PHP_EOL; +// echo 'GETTING SHARED FORMULA', PHP_EOL; +// echo 'Master is ', $sharedFormulas[$instance]['master'], PHP_EOL; +// echo 'Formula is ', $sharedFormulas[$instance]['formula'], PHP_EOL; $master = PHPExcel_Cell::coordinateFromString($sharedFormulas[$instance]['master']); $current = PHPExcel_Cell::coordinateFromString($r); @@ -308,7 +308,7 @@ private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,& $difference[0], $difference[1] ); -// echo 'Adjusted Formula is '.$value.PHP_EOL; +// echo 'Adjusted Formula is ', $value, PHP_EOL; } } } @@ -770,6 +770,7 @@ public function load($pFilename) //$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(TRUE); } if (self::boolean($col["hidden"])) { + echo PHPExcel_Cell::stringFromColumnIndex($i),': HIDDEN COLUMN',PHP_EOL; $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(FALSE); } if (self::boolean($col["collapsed"])) { @@ -837,15 +838,15 @@ public function load($pFilename) } } - // echo 'Reading cell '.$coordinates[0].$coordinates[1].'
'; + // echo 'Reading cell ', $coordinates[0], $coordinates[1], PHP_EOL; // print_r($c); - // echo '
'; - // echo 'Cell Data Type is '.$cellDataType.': '; + // echo PHP_EOL; + // echo 'Cell Data Type is ', $cellDataType, ': '; // // Read cell! switch ($cellDataType) { case "s": - // echo 'String
'; + // echo 'String', PHP_EOL; if ((string)$c->v != '') { $value = $sharedStrings[intval($c->v)]; @@ -858,7 +859,7 @@ public function load($pFilename) break; case "b": - // echo 'Boolean
'; + // echo 'Boolean', PHP_EOL; if (!isset($c->f)) { $value = self::_castToBool($c); } else { @@ -869,41 +870,41 @@ public function load($pFilename) $att = $c->f; $docSheet->getCell($r)->setFormulaAttributes($att); } - // echo '$calculatedValue = '.$calculatedValue.'
'; + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; } break; case "inlineStr": - // echo 'Inline String
'; + // echo 'Inline String', PHP_EOL; $value = $this->_parseRichText($c->is); break; case "e": - // echo 'Error
'; + // echo 'Error', PHP_EOL; if (!isset($c->f)) { $value = self::_castToError($c); } else { // Formula $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToError'); - // echo '$calculatedValue = '.$calculatedValue.'
'; + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; } break; default: - // echo 'Default
'; + // echo 'Default', PHP_EOL; if (!isset($c->f)) { - // echo 'Not a Formula
'; + // echo 'Not a Formula', PHP_EOL; $value = self::_castToString($c); } else { - // echo 'Treat as Formula
'; + // echo 'Treat as Formula', PHP_EOL; // Formula $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToString'); - // echo '$calculatedValue = '.$calculatedValue.'
'; + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; } break; } - // echo 'Value is '.$value.'
'; + // echo 'Value is ', $value, PHP_EOL; // Check for numeric values if (is_numeric($value) && $cellDataType != 's') { @@ -2057,9 +2058,12 @@ private static function toCSSArray($style) { private static function boolean($value = NULL) { - if (is_numeric($value) || is_object($value)) { + if (is_object($value)) { + $value = (string) $value; + } + if (is_numeric($value)) { return (bool) $value; } - return ($value === 'true' || $value === 'TRUE') ? TRUE : FALSE; + return ($value === 'true' || $value === 'TRUE'); } } diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 01a34c15e..ce30fc25d 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -624,9 +624,10 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach($temp as &$value) { // Only replace in alternate array entries (i.e. non-quoted blocks) if ($tKey = !$tKey) { - $value = preg_replace('/\[(.+)\.(.*)\]/Ui','$1!$2',$value); // Cell reference in another sheet - $value = preg_replace('/\[\.(.*):\.(.*)\]/Ui','$1:$2',$value); // Cell range reference - $value = preg_replace('/\[\.(.*)\]/Ui','$1',$value); // Simple cell reference + $value = preg_replace('/\[([^\.]+)\.([^\.]+):\.([^\.]+)\]/Ui','$1!$2:$3',$value); // Cell range reference in another sheet + $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/Ui','$1!$2',$value); // Cell reference in another sheet + $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/Ui','$1:$2',$value); // Cell range reference + $value = preg_replace('/\[\.([^\.]+)\]/Ui','$1',$value); // Simple cell reference $value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces); } } diff --git a/Examples/06largescale-with-cellcaching-sqlite.php b/Examples/06largescale-with-cellcaching-sqlite.php index 6d36d24c4..cbdb59b91 100644 --- a/Examples/06largescale-with-cellcaching-sqlite.php +++ b/Examples/06largescale-with-cellcaching-sqlite.php @@ -38,8 +38,11 @@ require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite; -PHPExcel_Settings::setCacheStorageMethod($cacheMethod); -echo date('H:i:s') , " Enable Cell Caching using " , $cacheMethod , " method" , EOL; +if (PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) { + echo date('H:i:s') , " Enable Cell Caching using " , $cacheMethod , " method" , EOL; +} else { + echo date('H:i:s') , " Unable to set Cell Caching using " , $cacheMethod , " method, reverting to memory" , EOL; +} // Create new PHPExcel object diff --git a/Examples/06largescale-with-cellcaching-sqlite3.php b/Examples/06largescale-with-cellcaching-sqlite3.php index 3642ce713..ca04f85e9 100644 --- a/Examples/06largescale-with-cellcaching-sqlite3.php +++ b/Examples/06largescale-with-cellcaching-sqlite3.php @@ -38,8 +38,11 @@ require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3; -PHPExcel_Settings::setCacheStorageMethod($cacheMethod); -echo date('H:i:s') , " Enable Cell Caching using " , $cacheMethod , " method" , EOL; +if (PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) { + echo date('H:i:s') , " Enable Cell Caching using " , $cacheMethod , " method" , EOL; +} else { + echo date('H:i:s') , " Unable to set Cell Caching using " , $cacheMethod , " method, reverting to memory" , EOL; +} // Create new PHPExcel object diff --git a/Examples/runall.php b/Examples/runall.php index c686d4d32..395e83e24 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -43,6 +43,8 @@ , '05featuredemo.php' , '06largescale.php' , '06largescale-with-cellcaching.php' + , '06largescale-with-cellcaching-sqlite.php' + , '06largescale-with-cellcaching-sqlite3.php' , '06largescale-xls.php' , '07reader.php' , '07readerPCLZip.php' diff --git a/changelog.txt b/changelog.txt index 8d9363076..dd04248ad 100644 --- a/changelog.txt +++ b/changelog.txt @@ -49,6 +49,7 @@ Fixed in develop branch for release v1.8.0: - Bugfix: (MBaker) Work Item CP20604 - Adding Sheet to Workbook Bug - Bugfix: (MBaker) Work item CP20703 - Calculation engine incorrectly evaluates empty cells as #VALUE - Bugfix: (MBaker) Work item CP20760 - Formula references to cell on another sheet in ODS files +- Bugfix: (MBaker) Work item GH321,GH158,CP17824 - LibreOffice created XLSX files results in an empty file. - Feature: (amerov) - Implementation of the Excel HLOOKUP() function - Feature: (MBaker) - Added "Quote Prefix" to style settings (Excel2007 Reader and Writer only) - Feature: (MBaker) - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer From 758f48baac8d19b8884cc19e81cb6f07a894bf78 Mon Sep 17 00:00:00 2001 From: Scott Arciszewski Date: Mon, 24 Feb 2014 11:34:08 -0500 Subject: [PATCH 196/467] Update Excel2007.php Fix output corruption --- Classes/PHPExcel/Reader/Excel2007.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index e1cef019c..105904c64 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -770,7 +770,7 @@ public function load($pFilename) //$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(TRUE); } if (self::boolean($col["hidden"])) { - echo PHPExcel_Cell::stringFromColumnIndex($i),': HIDDEN COLUMN',PHP_EOL; + // echo PHPExcel_Cell::stringFromColumnIndex($i),': HIDDEN COLUMN',PHP_EOL; $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(FALSE); } if (self::boolean($col["collapsed"])) { From be24d5d30fabd193a8ad4efa87424f41eee6b442 Mon Sep 17 00:00:00 2001 From: Scott Arciszewski Date: Tue, 25 Feb 2014 16:20:43 -0500 Subject: [PATCH 197/467] Update BaseDrawing.php Avoid division by zero --- Classes/PHPExcel/Worksheet/BaseDrawing.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Worksheet/BaseDrawing.php b/Classes/PHPExcel/Worksheet/BaseDrawing.php index 0250035cc..4820afb82 100644 --- a/Classes/PHPExcel/Worksheet/BaseDrawing.php +++ b/Classes/PHPExcel/Worksheet/BaseDrawing.php @@ -349,7 +349,7 @@ public function getHeight() { public function setHeight($pValue = 0) { // Resize proportional? if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_width / $this->_height; + $ratio = $this->_width / ($this->_height !== 0 ? $this->_height : 1); $this->_width = round($ratio * $pValue); } From 518f06ee20a400d337524b7be28731060df44056 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 2 Mar 2014 12:39:44 +0000 Subject: [PATCH 198/467] Documentation updates --- ...umentation - Reading Spreadsheet Files.doc | Bin 178176 -> 179200 bytes ...Reader-Options.md => 05-Reader-Options.md} | 0 ...Error-Handling.md => 06-Error-Handling.md} | 0 ...Helper-Methods.md => 07-Helper-Methods.md} | 0 Examples/15datavalidation-xls.php | 23 +++++++++++++++++- 5 files changed, 22 insertions(+), 1 deletion(-) rename Documentation/markdown/ReadingSpreadsheetFiles/{07-Reader-Options.md => 05-Reader-Options.md} (100%) rename Documentation/markdown/ReadingSpreadsheetFiles/{05-Error-Handling.md => 06-Error-Handling.md} (100%) rename Documentation/markdown/ReadingSpreadsheetFiles/{06-Helper-Methods.md => 07-Helper-Methods.md} (100%) diff --git a/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc b/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc index a85a31689a5424f7b131d73e6b91bd67a4750db4..06ee692a112115b0b583d395dee85babf95fa45c 100644 GIT binary patch delta 23467 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 M)i8PVPIa34Kl%H}yZ`_I delta 22675 zcmd_ycU%-#qww*WMF9(f0v3uQ*cAknVn>1WPo=*i&qXqGA_$e`l9X5KHd!zW3gL-u3g{IXio1=CnEI?9AYd*TrXK7hmdH zql+x*Ulx)SLRftKke8PyRtEE-6FMWwZLca`j#k;pF^avaO35TyYWK5wn9xmWuS!%; z6im%SbvG-z^an;3+tO!(|!HP(zmuGZDl`?>PXU5q6~DFBp;SH zc1jYPOSf2x*JqZsKKY^wYYrt!(q6V4y+@J`@Y#q2Su4wmSQfuuNw9Z%`E zm&8&Wd7+EpYyHwFL3wXfQEf=Lex*Jm^NL7PdG=eDm9}m5-xOYo-A%WYB*Re+`zicc zWVGPRu%G;O%5c+~E{3FiDX!SYk2Ez~D@hhcN`z^Edc!9D4h)B-esvXm{_v(Tk6q4* zn$x`u>x=nPTz

Q}rr5Kl6aq&h$9K1#>^C>n}ge2y32 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 E0EOcB^#A|> diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/07-Reader-Options.md b/Documentation/markdown/ReadingSpreadsheetFiles/05-Reader-Options.md similarity index 100% rename from Documentation/markdown/ReadingSpreadsheetFiles/07-Reader-Options.md rename to Documentation/markdown/ReadingSpreadsheetFiles/05-Reader-Options.md diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/05-Error-Handling.md b/Documentation/markdown/ReadingSpreadsheetFiles/06-Error-Handling.md similarity index 100% rename from Documentation/markdown/ReadingSpreadsheetFiles/05-Error-Handling.md rename to Documentation/markdown/ReadingSpreadsheetFiles/06-Error-Handling.md diff --git a/Documentation/markdown/ReadingSpreadsheetFiles/06-Helper-Methods.md b/Documentation/markdown/ReadingSpreadsheetFiles/07-Helper-Methods.md similarity index 100% rename from Documentation/markdown/ReadingSpreadsheetFiles/06-Helper-Methods.md rename to Documentation/markdown/ReadingSpreadsheetFiles/07-Helper-Methods.md diff --git a/Examples/15datavalidation-xls.php b/Examples/15datavalidation-xls.php index 22f7edcb4..2f8fa5ee9 100644 --- a/Examples/15datavalidation-xls.php +++ b/Examples/15datavalidation-xls.php @@ -62,7 +62,15 @@ ->setCellValue('A3', "Number:") ->setCellValue('B3', "10") ->setCellValue('A5', "List:") - ->setCellValue('B5', "Item A"); + ->setCellValue('B5', "Item A") + ->setCellValue('A7', "List #2:") + ->setCellValue('B7', "Item #2") + ->setCellValue('D2', "Item #1") + ->setCellValue('D3', "Item #2") + ->setCellValue('D4', "Item #3") + ->setCellValue('D5', "Item #4") + ->setCellValue('D6', "Item #5") + ; // Set data validation @@ -93,6 +101,19 @@ $objValidation->setPrompt('Please pick a value from the drop-down list.'); $objValidation->setFormula1('"Item A,Item B,Item C"'); // Make sure to put the list items between " and " !!! +$objValidation = $objPHPExcel->getActiveSheet()->getCell('B7')->getDataValidation(); +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST ); +$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION ); +$objValidation->setAllowBlank(false); +$objValidation->setShowInputMessage(true); +$objValidation->setShowErrorMessage(true); +$objValidation->setShowDropDown(true); +$objValidation->setErrorTitle('Input error'); +$objValidation->setError('Value is not in list.'); +$objValidation->setPromptTitle('Pick from list'); +$objValidation->setPrompt('Please pick a value from the drop-down list.'); +$objValidation->setFormula1('$D$2:$D$6'); // Make sure NOT to put a range of cells or a formula between " and " !!! + // Set active sheet index to the first sheet, so Excel opens this as the first sheet $objPHPExcel->setActiveSheetIndex(0); From 714b07881fb6bf7f65a91f6da535b6a8cc677f20 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 2 Mar 2014 13:27:41 +0000 Subject: [PATCH 199/467] Changelog --- changelog.txt | 50 +------------------------------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) diff --git a/changelog.txt b/changelog.txt index dd04248ad..083b8b126 100644 --- a/changelog.txt +++ b/changelog.txt @@ -69,7 +69,7 @@ Fixed in develop branch for release v1.8.0: Reference CVE-2014-2054 -Fixed in develop branch for release v1.7.9: +2013-06-02 (v1.7.9): - Feature: (MBaker) Include charts option for HTML Writer - Feature: (MBaker) Added composer file - Feature: (MBaker) Added getStyle() method to Cell object @@ -108,54 +108,6 @@ Fixed in develop branch for release v1.7.9: - Bugfix: (neclimdul) Work item GH-166 - Fix Extra Table Row From Images and Charts --------------------------------------------------------------------------------- -BREAKING CHANGE! As part of the planned changes for handling array formulae in -workbooks, there are some changes that will affect the PHPExcel_Cell object -methods. - -The following methods are now deprecated, and will be removed in or after version 1.8.0: - getCalculatedValue() The getValue() method will return calculated - values for cells containing formulae instead. - setCalculatedValue() The cell value will always contain the result of a - any formula calculation. - setFormulaAttributes() Will now be determined by the arguments to the - setFormula() method. - getFormulaAttributes() This will be replaced by the getArrayFormulaRange() - method. - -The following methods will be added in version 1.8.0 - getFormula() Use to retrieve a cell formula, will return the cell - value if the cell doesn't contain a formula, or - is not part of an array formula range. - setFormula() Use to set a cell formula. It will still be possible - to set formulae using the setValue() and - setValueExplicit() methods. - calculate() Use to execute a formula calculation to update the - cell value. - isFormula() Use to determine if a cell contains a formula, or is - part of an array formula range or not. - isArrayFormula() Use to determine if a cell contains an array formula, - or is part of an array formula range or not. - getArrayFormulaRange() Use to retrieve an array formula range. - -The following methods will be changed in version 1.8.0 - setValue() The logic behind this will be modified to store - formula values in the new cell property structure, - but it will still perform the same function. - setValueExplicit() The logic behind this will be modified to store - formula values in the new cell property structure, - but it will still perform the same function. - getValue() Will no longer return a formula if the cell contains - a formula, but will return the calculated value - instead. For cells that don't contain a formula, - it will still return the stored value. - getDataType() Will return the datatype of the calculated value for - cells that contain formulae. - setDataType() Error handling will be added to prevent setting a - cell datatype to an inappropriate value. --------------------------------------------------------------------------------- - - 2012-10-12 (v1.7.8): - Special: (kkamkou) Phar builder script to add phar file as a distribution option - Feature: (MBaker) Refactor PDF Writer to allow use with a choice of PDF Rendering library From 357a3b1fc2637c9b84fc57564d79000af4277c94 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 2 Mar 2014 13:40:35 +0000 Subject: [PATCH 200/467] Documentation --- ...lter Reference developer documentation.doc | Bin 635904 -> 635904 bytes ...tion Reference developer documentation.doc | Bin 628736 -> 624640 bytes ...umentation - Reading Spreadsheet Files.doc | Bin 179200 -> 179200 bytes .../PHPExcel developer documentation.doc | Bin 819200 -> 812544 bytes changelog.txt | 4 ++-- 5 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/PHPExcel AutoFilter Reference developer documentation.doc b/Documentation/PHPExcel AutoFilter Reference developer documentation.doc index 2a4a1d94048d8802beb8a5b17e6f2b8b9a37ba18..275d71e0b7d1b567d2e9b4761722ad3e41dbfb1a 100644 GIT binary patch delta 4534 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 diff --git a/Documentation/PHPExcel Function Reference developer documentation.doc b/Documentation/PHPExcel Function Reference developer documentation.doc index 8d6e14f266f702a5a49567ff7b13aabd26f46eda..88ae069a61e23a6ba96235516f369f8807144937 100644 GIT binary patch delta 4533 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 Wl}MjPd~p9HIvWWjJ}1%nX#W99slq$} delta 7186 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 diff --git a/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc b/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc index 06ee692a112115b0b583d395dee85babf95fa45c..09489fe1d40fa2f1c6683cb85b9547ca345ee380 100644 GIT binary patch delta 1570 zcma)+T}&KR6vxj!Gwd!Tq_hi!%2E*u2JFJR!EJ3-n~>=ZL)O-Q}2tjtsoJ1=}T_9vrx6 z&)M(rc(beO-hZQhVCKUN9{Bs<$iCIh#h(+c()K8c^m@$XH6dQr+kQSkbPN0nZi6|H z*g=#8@<2W)0EM6e7@!8!g4aPE*ahlA19%5Cf+o-m4uMY43;I9^90wy{v;&7>5`!u5 zJ(vbJLD(9$iE0g9S}wcD(zrUy^4rDR(Lu;AY6^Zqo3kL^cDxmJ+k2Fx+abngMA-Us zPV9UlD2N`!MZ{O~BooE)TL*pD{9a>TJZN+M$SF!xiR)mOCmS8jYtyEcjkgx0JyN+W+AM;+pUXS%b7YFtH+5Im0Wfxz6NZVB8k)MUQ zRx^+3j-gZBWYafXIqZ_}^|M{@p&{9NmVXjPf8u!bfArt~lDhK^dX~PUGJ1`w=o@+- zqn9a2lk^ge;-7K@xpDd$nMv#90B=dYM@r5O@a}|MUrD)VV}-HFU1F36+$CPm~SG#t>waGBZ(r1Pz;J zY(OMzA!cco7yr^otd#jjv7rwUU5vxUs3?CJNg&SIY1Cw58EV5o{N8rYfbfT>`Sjd- z&VAo|?tAy%{zOK9A|t$*MJ!On)x4Sm!)jh&8wW)=U{%&U_E4CJiO2~r?f>|t7`Gro z6vcz%Cx}j=zX8wZLfaZRrPT9=aNwF!^*}d*c}V(O@OKA4X(vhq+SSq=S;o!gZwY*C zsPzC`$=U9ay_}CYVZfm!qm&%j3oRbRJ0JjAKn2Up098Q<47Uui^9W(n~2_ms_Y+?nVBH!@I5T+IE%b7E;$%~ zKQBqOK6r;{a~jb#8&L^D_hG5|@L0LW+?pZZr!>6DVYSS>YAumVe!G&uinM%uyE*e1 z_eCS8EhVqq<#HDL{GGdA?AX;4`DuSXN5rciy`0^-={(UrO1D(Wdlo(YYayOg_x?6O zbO~Grv)~H2dmm9ICkS=YzI5QPH+eeg112sgupQ{ z4$kbue)tZJN$@?G0zZJ5_Mus9R8Xb1*dmIQc2|Msv52l@BWMwumj8}2OexGX*~#h~ofGDrDAZTGCWC}R5hE204> zNgw%BG>bW<(-bF8GzIPlu zOCm>0<7AxaBw`XHK3^7%4D#xcR`!fc@Jj8-BHnXijy;*RmwK=-AW;sQKnK_Ywu2oY z2tr^IOaUot!5OfSNy{qYTA^yKIef2vcmcnco-36)!65ke3B4_!hq*w`6bG}wm?5dC z|6Ry&k$qb{TEy0kxjA?dIJ|@<(T{SWuxzcohv)QVy}Vh~hx*v8*p+@kM{yHLqzU|t zw&6J|m7|zGHoy~{zSLT3Syp^ut5tvP0H0H%gS=a?)2+QU#LeoSt$$hdGedl?P^q@N z^{FB5QliKBd9(Tk?iqb&m@R_KbiMaD|0)`(-j=+4{(A|@886a$xluF`wn=Y#wYa${<| diff --git a/Documentation/PHPExcel developer documentation.doc b/Documentation/PHPExcel developer documentation.doc index a3542c9a04c2d407ad1f24302959d7d6c6d86214..1329207cfa3117fedf5de01c0d3452e473386762 100644 GIT binary patch delta 2099 zcma)7YfMx}6h3qB-Fxru49|5@WECtTN&%N$KztNfl(j(7TCk#kQCk6nsj?L`G$M#C zt*O>#tz%oTBqhc8ENZw(MdPC;R;{L~^20W!F`CjJjW&IlQVKn@D;BUndXn#c=gfR_ zX6D{IXBr!wjn`84I3^~l5U@~yndlRY28V`*0C=63r5h>rtdX3M!iiL_`Nqkf!naid z5{h;r3;RDj6?Lc01iEox4I^*><6}5}o$r0c>ia^@mX4{u0XaQxyhb1bJI{3D<3IRf z3BU^9G9@-#EMugd>Eu%`Na@K!A?)e?K)c8stN>j31E5b5WAe9k4+Q!=&jlE_kNZdK zI62dve&fkR!|juN0KdrqC;kL@F)+mc+=Ocyhh7ry!hu|lEKKSLIE7me2@1qv9AJ$e zh}!{V=pGOY@yrnm!F4?miowGAq62*7Z-C1<@ZFaI>aa;#22hNArqef1U1SljRM;_< z*Bqr*U%O&eU;hLkU&r_Sj4wf-AU@)NdR7VvYVOfmdNhKN5VFyuDe<#{7DqI}Qk|#~ zRp=QHGnE80k9uC|vO3dZ@@rpP8{>4OxNMphgeI2!Eq7dy7I)_>iNR5mJPKqYvJg3l z`G^8UnMdL0?~&=oh7#ox$&11!J3`2X)QuRHmZM*Rs6^~S>_+$ydlCB(t%x?n6~tA( zb%k<>iWP$`qH3G7pF2yHN?ACqrOK<3I4=w*`~dyo1c!NcnG$I@%arScw6>6yN+(%q z+9)u^f(+JgczskhryLzd}v+AzC-)>bOD_l5JxL=`iI;7_c#Y;o_ zJum;hNYiO7b~Ass#`C=9EYZEwYcAMp)gLGLSE2Jh)#6vo&@5+{TFp->%)GxWpqN{3 z`RR};A2Tm9X6Q6pGl>`2Y7~ahi#FRdY_CD=M~Kra&gU&27e||Metsy9CJ62gupv#O z2Ni#=0^@iBy>G498hyuO@z)Ii6&glG+eSr=qoSr!(e_bM^QdSCM!Y|hP9D@c8w;ywV>pjoM-z=l^>l}%)_x4oaFe@t)8vU;aHvQ(HjTU2cyl*( zkT@AMJn{n47>G6{&}V$qPM4VYJ8g7&m{{1SBQqKo+UQc<Bu*@o}*@ zz(a;zu6ak$m`lDk0wZ^_8$-K$TB8;Ot%a_b+ ztg%{r%y$)u-INUyQeq4-W+65U6vAroLN&xd4tmwF7Q9$&Y&<@g{jx8VImqWcC6pE9 zrQ!_Yug*rs;{>aaDe`(`@jGup4np369E`jNIRtq>GG0y4j%-Cf$S;Mm_oBp*!qwjD zn4HzsYrO!IF&6uGIUKw?j5#MKWVn7TyF#+D4Nk>==$v>t;1_pcMKbx zC1)f%o|LjLMLnzPUcv5-SHvyI`)Zhdg79R#8x@2Jp&~Q{w|kjg2@&2rFPldOd6$>D z_&G0AY)ROfj1Xf5QiR{tG?(n##MYY~k*EAOi^Hhh#AG5J590N;tY7Lk@wz(JKqUTq z9ow*QW C1KFGa delta 6514 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 OMlr$maeb|y82$qy=vvYM diff --git a/changelog.txt b/changelog.txt index 083b8b126..f3e8f51d5 100644 --- a/changelog.txt +++ b/changelog.txt @@ -17,13 +17,13 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * -* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## ************************************************************************************** -Fixed in develop branch for release v1.8.0: +2014-03-02 (v1.8.0): - Bugfix: (MBaker) Work item CP19830 - Undefined variable: fileHandle in CSV Reader - Bugfix: (MBaker) Work item CP19968 - Out of memory in style/supervisor.php - Bugfix: (MBaker) - Style error with merged cells in PDF Writer From 7d9e19e8cc23cd35c74eea759484a016e386ec45 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 2 Mar 2014 14:57:53 +0000 Subject: [PATCH 201/467] EMail address and changelog date --- Build/build.xml | 2 +- changelog.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Build/build.xml b/Build/build.xml index 241cfc29b..be49be3c5 100644 --- a/Build/build.xml +++ b/Build/build.xml @@ -139,7 +139,7 @@ - + diff --git a/changelog.txt b/changelog.txt index 083b8b126..9f7a4dc0a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -17,7 +17,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * -* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## ************************************************************************************** From e69a5e4d0ffa7fb6f171859e0a04346e580df30b Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 2 Mar 2014 15:22:49 +0000 Subject: [PATCH 202/467] Documentation updates --- ...lter Reference developer documentation.doc | Bin 635904 -> 636416 bytes ...tion Reference developer documentation.doc | Bin 624640 -> 628736 bytes ...umentation - Reading Spreadsheet Files.doc | Bin 179200 -> 173568 bytes .../PHPExcel developer documentation.doc | Bin 812544 -> 800256 bytes changelog.txt | 2 +- 5 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/PHPExcel AutoFilter Reference developer documentation.doc b/Documentation/PHPExcel AutoFilter Reference developer documentation.doc index 275d71e0b7d1b567d2e9b4761722ad3e41dbfb1a..208b20205029ca4cbed3690bbce9e3521d4cc5d1 100644 GIT binary patch delta 5412 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 Rsycru4_Lc)eW}&i{BIQ?QZoPm delta 1646 zcma)-YfM~46oAj%$KJVxEtq9_E-BLT2t~jeX>A*WSjv`{U0JITji%a!8lDjn(_l(M z)7BT>Wh-M$qsE4&sU}!sn8p-njRsnTsy`@bAJk?opvY2UL<+2D_I61_{NdSr_nf)+ zoO92aJ2TtzMQV$YYUITCDPT$@zy-7kj+O&~000|q)05R6yw`iC;T9o-UXK#vt(Hzo z&2Dd$ytA~goPdPx7f=iNKY9cD{k(@jHwGFN1kU2vhw&~t|S06j~+NMh@y`)IuV5 z5pZDd&PsE9atz?Q%^Vv53Sa@El7g+GlIJlZ z#H0#AjZ>RqIW!G$%7$jLH-pBCPq=95m7JBW=QMs!BWWWJO08Dg?k5Thl9KG!6*Fp+ z-3o9daE%}mBJ;pCrJ(v@-!BAiBNND<$PD5~?jUo>Kga@d7g*c(Oawk-!rRA@)$ z{qugG-*_2WC#h?Fpb0hY_M#|N6MvK*A`H`1Su|37A zJ32ysRkRpgRpW5MGn80@78@v5tL(qwD@A#tq*+9iwZuwG)Nk24-z!%3VyPOxVpVuQ zQIgr&Qnir8bd;$z^5(3^czu~_$c#R%K4_Vk8^1a_B)&_4Mb6SjW;j*-1)fz2HBOzr zhJg8Q5V|6#0bs4ESDxFWtFUhL2c;Il7^R7lm{12I20K`B*ABbY!){BrTdQ`FI#$!E zC7^nYah)9r(h&{ObpVTr?^V&&mUbc%Oa9soo z*d_cB3+tNJ;`p&?tudR_b3Ks`hFR;e3L%L|3ZG4qDzoHaJnEoq{bN#t)t#`msH6sqM$Gkx2_s#|F+Kh}y{CL-h*a_BSYHkAz< zl=6l5X+GhPGx~CoUB*q1M=9Wr1s@_rV%;|>=MBHodYSutbXiV>7IV5x2XP$VH}06C zNvbHcj;Bn~87b@)+j>oS7UD-=H%&)K_@-7D_#=T{4J?U$AIsxr=xs?X@9sOamXOV? zZjPop{`mbVA12Nd!OLSqC6@+B&>qjIaPTv8H0(n~{0Xr0@9Nu?7OcCYP5*)U+w@Fw xo+ZAg-|`qq9fn@5kDnL|o{Qh`CPSBrG+N0Hc=QEQ&zjoxgXDGoSGyjj{tFXP#kl|g diff --git a/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc b/Documentation/PHPExcel User Documentation - Reading Spreadsheet Files.doc index 09489fe1d40fa2f1c6683cb85b9547ca345ee380..ef3954d3b6dbb9c54e855d24782c0599f4c25fac 100644 GIT binary patch delta 2709 zcmbW(drXyO90%~<^SlQRAff{yQ7J_dCV_x}+~Xpkm>A1U*WASW$O~Gw1U4?3B`gIG z@Gh!_6%J%gfys-PfnX{jqORs2mZDIZF-<`mbI|GgI~M`7)_Tr9=efP-eSg2_y_`31 z&>^qWp*XRf=J?5uBf^Em)Z;4^?yp#h#yvePILnOaQxmCJ9jahP-10xg<(huot26~ zH=Yc|*E8yFem+L9$3&A*uSH}5s7oyowqiR{ zh*npkMyU%Xx{8|n)jZQ$j5v}aIF2sMII1V**B8vq{Ut=1c0@ydM4lLW9;r@7jm)EL zQyq9gxnLXh zm0O=j)BwjogC=N(7B~%Ua0b4G4!8iFa1pxT7q|^F9~pry=wSwULL@{%48%e_q`)Fr zn@`TP4vnpl3ELsN?22#+zILOty}7BmiNC&XZmMb@`E<5dqN7%|@1wCr^%CL}_u`xs zMB%nEBK|JX1SNyFG4<5TLd+2%^G=gdf_>T0(dEZhx=e%5o?y5(3l`K zKRa>$j_6SzJrD^Cop5|-@BrMM^cgG`&(@6b(IO?TT8kJpzhAW2^Eu>Yh*!tgN?-Mz z0r9>4HjHtEJzCmBksxv8vOk0|myhZWd}J@+XNwQS!AeMn94Ln>Xn_vk2g5KZf}eCm z5wHL_>h(|nd*C3P1djMDv_l8DqYDG2>}2!j}P#-ON`8B^4*K`|S(_IOYXDz3ad z6M&b7pB^#T)>e%i#zi}QSS*#YH%on7BjeR3qljJBn}uB)u?gAI)Xvys7t_B8_okue zZ0XhE3B`D8F48nEsR?7uI*vFoM^siQqsvldRFEV7m0b82C_G{QlQK2v04ip%C`DaL z>hC6z!umFRZtB#;3jbJ z3h7MrrdsbzdW1WgP92&gJ%mnkbCvFj-)+QXjb$N@$#EP8K5jbfg(v&hmQI#M!bgW4 z+E|#^;vZIE{}kzOT7joCw`RTFa>UV@-^UndZ_V`S%tkVl$Z75)A$rU9ia7e{I5V%ClC3YcG5#Gf78_s3xt1T!nH*|0~c4#XQ#}SvN%Vp%9b%U zrYBENo;>0|K2MMi*B;{{@Ugb7wZu!3sq|s`r5E7>jkbd7~_ zhY*44yG7DlxnEGORu;(_x*u(Pe6_Pha_Y=={BFg!ZX`rOG{nHm5DPpXk2(S7Ln0(W zGVtxr^TVU??VoBH=eaa)m!zL8KPorbU*7wh=|$yLZO2im2bb*tZ%^^bLBAmf_KqMpr1966pfHPD}78YNr(xLT%Jd-(j{3Z#8LZ zZG(((9KA2?L4#ap;}twNI3Oq_B-}47IB=d{@Z7lhe(|Akfqr505`&VG<^}{MhK6fd I$K@XR7YN*gHUIzs delta 7061 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 JX1>gp{{u(Gg!BLa diff --git a/Documentation/PHPExcel developer documentation.doc b/Documentation/PHPExcel developer documentation.doc index 1329207cfa3117fedf5de01c0d3452e473386762..5f1ac5f7533a68c0e47b8decf82404c35b26243a 100644 GIT binary patch delta 36821 zcmc(o2YeJo|Hfx8mwFcnBm@FU2!s+!lIwd%4;`d;qzgzj6cLo-Q7u>~`@#w@C|Hpf z6cIUnMHH~0BE^EfRzy@@2^|3u$p4w!o7n9agu z)ARmTUlKChL`c2HgnU~SWm^(52#Y~j(wBB=YX^NIA&>VW{e$Cnub&9gIY348mq=_R6+|)J4h;Eazfb zgH}_qL_y(3RED3`Sjv@J&@7ses|cKm#MQH;9PN_E^PnYcw=9l!o3>Q>VsS!gV&1!^ zMtQ7qC5dUFN@hZyc^^A8iFMvJb@eYhAcbH%Mkk^d3E7rZ^h0CMA=;SDu$L_Qu zmqQtnRC;GlEct|x!*PW47(mE)WbMSVE0$p=1`^T&+byvC7JZjpmn!K?yQG~>U(1d{ z)*$-&OhVSu0zR#fZL_v8e|1ZtR_s#_)+ZMcPBlpBebaE?cCS?V#FM;K|TT_qHNr%@ew_PluE2wzS3 zT@KAt87t!zPFNiBh9bu&bg<^I9G{|$!zQe==Eq9=aR?(USs|6fE?l#+VAzm@IUK@} zM0e#-5l7b0@u-|z__0O}R@5oHoyZ#Ea0;gqSq&X7p=zaUCUXhPD}{61!k9|oGHzv# zM+nF{9%T+MBvj60(RgK!R~T2hDa-LHb9}sD$G=;Q<>uuo~*+9!721i zs>62V7H(8&C~qk0;}QB*WleE~JS&mnk;}bU4;#rPQI97}8$72)X(sM#p^w^{-Iuv8kgBc{ffC=md z0*7!Uy$2J7W))Qg92FTILp%34g&#A+J9i21Ww54rT*@4`;K&S@!5k%*@d%qT**N!j zlsUW*Uz^Px9$uN_6~@+P2b{;t+HgLR^@GPJyj|PL+7Oyt90CNPiJZ4dL)eq&5VCTr zi$iL1$wKGGY!vf0;jS#!D&8)v%Cd#piw#ANL-;+*mn6+SJhMtUiSbThcpWEGI72m6 zDO|#yI&DH#lALQAI@|q${e5Ybi)p;j8Bo{vkBF6T7+`2VQZ9CRT?%vI~$3Z zmh0rC3eV)!WI8+5u?>fCI)_alK8G^LDGX}FTIq8NBO8ayxP*5au@j}wrOa^)wHmV{ z)#p~`c!Y-lctTOrqYdJO+#(qZFXTv)6lgA-B9E>grAy*&Mv&oq0Dg#y>mk&g10$^GkICk zanIX=mxZ3-8zKiYBr^vC}gzmP`{K4Bp#}v-&;c?2_?ZP&jT^h;Q zkdAG&!XZ?#hh|vb?hv-xnHzSeR5@2(yx4jJS5xSaADRJqyOZidjgT&;J$bHRBhJ~= zLshlAsEBR2g%*y`WeIP03)39o9FMTZ5ju2vyGNPB3s)WCs`1JkuQ1pd&haX9e8Rt- zp{rir9vVw7p-LvR7FW`>U3sCZJD6umfnAvA3QcyrgIT7yaOQDk{f#Rl)G&u*rJFh7 z2s!2rI?>LZ!Zc2WCN##p!nynuL7{O$;|w14yd!uC<;nBq#rJC8F+Mq~S3#!^eL8f^ z8qsgc=&&Z#nTq4Y;Sn63aN9!j7OvXZk;Xf4_3i1;YQ+nuJz067T?R)YpBLY5`q(iO zX53xEPI1M>vyOA%ii^LE1@kT1$p?1w+?mZ${J6#-AlYZjjPID=lRdfYwDa$?iuqjPbB(U@+ zE}k@RsG-Vn5_x>|EQidzuNfS-DZZ`UHGu6o_O=W-1DvUwkZuFwyw!x_wMc- z9|v2N`Qq{4IBn&cMfOe=65;gqntw{yAMxS76kk5Yr3D@R_!L(sxN`Osx222*9WCPO zhP$Po-h=S&!i`5wRYOPBjF2U$y zvRr%PPu3fMst<+hx+?wEx$*LKMd$oolg$lPwTf<(cCxuyag$B4^L{phBz$+;%t*BFE zWwqs%OKW*j#aUj3Sze{=qqwTV^1o|VPF7o*Tv|(0D$des%+hM=SvghJlv2&gspa5s zbyc;Bs+ZQ`8Wrbo8gn?U?1Q#uIapdtZE3C2TAE&QmS!+ZGs9#Ud35jU$QiCw!Z0r@}8nplW9&lc-lzqX`|A5+PLC8 zZNi3Wld=!frsZI1uG-Sv(ps8VahB#YOY_TasjVC=wW}?)m)258#aZfPmO9IBsjD0; zb*n9Pm)25G#aYTTOZl=}>MaLLeQHa6rM0wK#aY^%S=zkpmbNGdOIxZfZCP4NTUDH; zt(m2*%Wi3#a~2pi2e&7wtSOpw3*4Tp z3R$jh-^JX%tL$zUmV?_TE^J6%_$zx-s_^l~u&Ze_Is zMR%9_He_bSof>B`i)WSnYUEyprxkTIa-Y(3vFN^AFyLpaLYC`*pTl}%PT8lIxr*NS zyDn7bsjMlQcMIIUUlp=k-S#uL{bhH1emS_kKxIwQf?MGBLRH9eb$bzWdy#rFU#zRr zUry$W%fb95s%jN2DeY~}0~I%yKPWjIIQyU}mka+1%>R2XXsGz4u=bCl9#*>ZV9~>- zK+(fdS9T=QKSSyt$Hk=5KS&CkYh|tyFGh7X*Wg@YtWNpehI z{41L=DPqA0^G0#+U~@}<5{EKTfbJs(SV1D7`=k4+0;+==peCpV=>F-x+W@xj+ps)_}F(9k2(y4?X}NfvLPzZ(T(fOSi5%^S~Umv9VZbh&jzddy`a?{+!M+#9YsWKgjDm z#N0jy{Y(GAhE$H4NdHxfw1s|;PaR)xMlx~7EeMrbH^khxW)5q@e$-B?GVDQ(E{WW# zsI*!uX$=hCJs$d z#c}F=my%TNb7CCo#urP}#MAlj6m|YPjr?bcns_?@ok9Oqe%W5ow38-i;^=&L>V4n% zq9zVa(8SUC?$rA}wTmVWO;E*g>3x@yRPFllHccFwpoydN+ZFU%8E5s&>M+`E@lX%7 zK%X$}6^()>XlkN!*rj*4O>a#cnxKiJbJ(SK_?5nzI5a^O$E|l*N>Vx_9^R>mqf2;d zfJUK9D0m}!qIj%xbet-3I8{?C-FSBE$8*wP%|2;@CXUW+x8CgqLo{({f+mj6ZFkUZ zjp}R{&8+GcX_BhNQ-*8yMiW%?2tA+a<`I^t+M_2phz*iddptH$vqzesDWvn;qxZY_ zXiXfNpoydN+Y|I#(>{aqriVz0s+zaHQ?o~!pxL9&b5GE7m5SGoaw$o*w{7D!d($OM zy%A$DhK*C}OwvT737T5zT<7&?P2T9Lg(a%$U%61TN1C8=o)4L9n5e0nZp8EY`DOl8 z%^qojDvnq0yp*J>`T6OZI5a^MM>m6e^=C}4(HWB^YU1g<_v*d(8hOtWHSu&K->aW# zdflsOCr!}A(fRJx`@UzkCJs$d#qsHVmy%Rn?=zZdSfVDL&VQfYf1i>6EKw6r=f6)s z<7Ca(w38-i;^=($>3v_ZP!oqHXyWL6_vvSNpMGl5CGo_j^`0duyhoDWdpS{2H(FTZ zJxfv?L%ewIK~)>21Wg=`=QIvYQpFjyR1=3LXyRx*r*UYKrhU3u9=gy3q=~2Tp2jms z(#-T!rAxBwy_b?yZG2~$rj0Z~RVTaNb16v`$G%b%hbCy^=scHhR#jf%PF8!y=jrWj zFi{gv=e=F;yxe`Jki~m@}lO>R7%jq(T#P7 zcAi0K{X8QlYU1hq*WH=Yq6Yr6L`^)M|GGO)+q4Do!d zrD07gp3mU_RFhhu3+PVQ@sEu&xqu_i(!hj&QXRNG!E(l&Kp!K~=RZj3Q`vGyxKBco z>#Q;-*GVZ}H9xukC6TXhnPz&Hh@0zM8q?)bX&Epzuq-q?X$4I9m(7c?!(Ax93p;C` zKnVT;HeR%4__x@>R?+{3oC!sYc&f1_O+4J#(#tRyZSAfoC=)R>Daf{s@^RTjGo`NSqNYp-(u~UEr4=d^(A0l&A&* z9i!@k%5o(;kVW_(z3>Fs-nUX5wir|dPz!^V#?Ca85Be&2M!5LQsXIv4+ zj9YT1m*FJfjxcE45u8C|#L6~Hbuqza$s4OY_}meEaU1x;Y;i}h#Z7GykKBx@F7B{d zl2iw~JAy6l2)1}43>ZAND6!u?kq#wKgaPA;V2me%G4xjj>OrVDl<)vTlPM1-PXuQ? z5uBkHyy_jwG3fP#a)#!W zbU@KOIAeTLqnSqIh7KE=SJJSdc_j@Snx{XYLPsLaEa|jO^GZ5x)7hkCXY3K2u}jVv z9f>q(NrQ&wmFx^XM2wGMTF%Is;E_l(_0~w|HJVqlGxiA1lzi1or`gb$@$0VZX=cfT z2DhLkw$Ks5nUb!4{d7P%46Ts{nC{EOFqr%0$6*47RjH&|?0V9gfC6jHP27I}0R9Bsp2s%;fo?Bg$KY--AFKtN z!6)ETa1$hMA|wyA029HSO@7o6EAN3H!O!3-_!H#3NJvxA8ngxXfq7sx*a8lKL*P5` zBe(>vf+1TG9IOQ!zcn<6U1^7a%0bmO7gU12=lB1;R(f^CEG7eu(H3jSghd}fvr~sIM7+)g= zJ_KKZW_aGy4h;VkPJm4y0FHl#R)IG@M}Gs;7ia`{1MCN;qu2%)f$2+p!4;SVmiX~S zWh=o(uo-*^z62>>!$$Bb*b9CK=5GiY2*!Zz;2rSWcZB=_uKz%YN)wDV{^Xm|l%U zg0mp~cS4$g9bg}5aG4M{cpAI{YF|M&gQvhtAmb{IuB+((^;p>gV*bD<#lS2uACPMp z)xZu~f{~yQyblh6lO& zT|pmle_u zMu5k_IAg1g%p!a$BmOBO|dg z4QvN{L8a;(sRf*%1^5S8555PdL1qn(WP@IyKUfOZ0ACtMI)lub9LWXugU7%za1zAh zL2V5%0u+Lt=^PpE$J;_Y>wFZ{ugwuV7zD!4hl-yTKz(p#hFuxCH9wal{4waKarIN7{qF;5axB-f?r} z5J>d+F;F}Z^Bidh-UJ_kC0_J9IN-xz0vnrgWE(gIu7N?#IWh!12v&mw;2Th-1xK>L zATSQB2V21R;55i-$q^n*2Ma)3e=Cmk2CZ9jqz8Bv>;?C=;mAW^X8~FW4uYeg2>c1E zw1oqpE$9Z$fIq?1cIa>LI9Lx}1#g1y!D(P>k5+>$&=mMv;jJ^62xb7T14m+k6LbN~ z!8713@F9rq$Po+Z2krpV!ECS|YypSB_uvAE>VzW+*uYG%5WEWxf@9!xC-lF)3rD9@TK*~V$IamN50^fq4 zK;|HfcrXS`18cyO;07=aM%RLAU>$e{d>i zJ_1Jv7z7HzYhXV(4$gq4BRP@}rh@yy<6t$|0rr6(!3B^o3f~<8Mu16R>nQYp04pDY zqhRzM7*L@7Xv}or6u1Hs#^85XARjabxnnuf60`w5z$UN-905nc*W=LF;54`nI!wS| z248@aAZ8-Q0C-@MA5-HbOoyNtESijg1P;%F7&N~RlMt8=7J^k^E$B6yBg4R&IhdG$ ze=hnGB+tX-1)764;A8L=NWLHGpebkphJ(={-;WCTKxc3}coIAV+AiQoC*TK5z|Y`U zP<)Cip4l{g5%&;1Anuns3~wff{K8F zU?}(nTm*TKa>NbVgMMHpm;*XK#*yw|C@2KmK>+k$hK7KZ;0bUQTmy}lV;%r)Ku6FU z^jVJne*`OQ!1xs$nF5xAWuUzP5tssIfU2v|de9T}2d{wu_!XQ6H$c>C3}8?h^Z-M_ zbrDCw6CBwLwtx%Z3aGY*BQ@8+>cCo@fWRei4cz`u6a;QYfr@(&P4T%v(rx8sBb z5?)1@0PhZrG2jP_!BacX|IcD&$ZMFTz;%$Y6Q^46Z@|5df*|7!v=B@Hg<#a1Xc_n% zd8#DtKKS9BRuDL(B+;KMz7ka|q)dOS#cdmAHF&g&{3&d(^_W*6v)t!>HhHrCsZG8Q8wea;<;0 zJT%jcw#9*;0e$5L_WW%5HOj<~6QBRDrDGKRQ?670wLE36$IZuC6AB7_VRVGoXs%Y?0!e2r`%IS4lCxtQ zW_@#KE_X2S{dvnQj&q0uE?S0LoQrysb4eub+u|GSo6BRwuP$0n;hW6gy=19Vy(!7U z=SW78>0}bt+G1@I8B3-IPF%92bNHU~*wvRUHg1<_ziesZM;q{f5f5FkjK#7Bmeh`> zSjJ=72Ft2gcEd6O%gI<;u)G&bE0&9~OvDlsKB@EIl~8IOU3^fw^A`uUlMm#gb)C*tM&1;H@hb zzS7PZ>+8u;9+D}(nP%l{%fIxckAQuM9tDscT)rgkNweBDBCkfY$wOQL#4BH3|ClxZZA9hXEkj6|~IlBlYY zNOoKjS&c-piHNwuKkBq&OgXBGMp1?D(J;-qZVq(ifr*DS^*aay)&(xD>e zH4~jN5;3ot=%kT|dCf$}jYQ0ACi>P$#Jpyrqedd;H4_~+5;3ot=p!SM>~%`e>v#1c z`pbQ3bn`?K?KTq0j!UA~jYP8Jl4!e;NOoKjZ7~wbj!UBFjYP8Jl4ygGNOoKjtu+$K zj!U9{7>Q)ZCDG$XBH8g;LB}7`i|7YUnB$UYp^->-ToTPS63LEBqM1e_*>OoU)kq{e zE{P@@iDbtm(HJ9aYSZL79hXF1jYP8J zlBm6rNOoKjwK5XPj!Po1kw|u25;=@Svg4AdsgX!_ToN@f63LEBw?srl3gi*J<<<+^)d+mR2Fne6zT?SbS)pHCLfd~ukyd7>(m zcz&4mLGk)(Q(R#FaO)s5{e1E#_3V5Hr>~vUmFuzF+U2_3c5iM$dmo?cc6D^P RY`nwe_1OcnM_V5-{U2?&aku~g delta 47092 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 Date: Wed, 5 Mar 2014 18:39:07 -0300 Subject: [PATCH 203/467] Fixes html entities to prevent parsing error of generated documentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The html output contained "" which causes a parse error on stricter html validators. The solution was to swap < and > for the equivalent html entities < and > respectivelly. Signed-off-by: André Tannús --- Classes/PHPExcel/Writer/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 72fd81856..095f26e0f 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -670,7 +670,7 @@ private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) { /** * Generate CSS styles * - * @param boolean $generateSurroundingHTML Generate surrounding HTML tags? () + * @param boolean $generateSurroundingHTML Generate surrounding HTML tags? (<style> and </style>) * @return string * @throws PHPExcel_Writer_Exception */ From eb768751c6ce8c034bb251f9fd84879cf6b044c1 Mon Sep 17 00:00:00 2001 From: gondo Date: Fri, 28 Mar 2014 22:53:04 +0100 Subject: [PATCH 204/467] removed unnecessary break --- Classes/PHPExcel/Calculation/Functions.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index df21ac4f4..9a139ec79 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -578,7 +578,6 @@ public static function TYPE($value = NULL) { return 4; } elseif(is_array($value)) { return 64; - break; } elseif(is_string($value)) { // Errors if ((strlen($value) > 0) && ($value{0} == '#')) { From 0042e47c0b276ca0548d93468b312fca21265780 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 28 Mar 2014 23:59:38 +0000 Subject: [PATCH 205/467] GH-347 Using $this in static context in Calculation engine --- Classes/PHPExcel/Calculation.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 6159be9ba..c4f211292 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2640,7 +2640,7 @@ private function _showTypeDetails($value) { } // function _showTypeDetails() - private static function _convertMatrixReferences($formula) { + private function _convertMatrixReferences($formula) { static $matrixReplaceFrom = array('{',';','}'); static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))'); @@ -2729,7 +2729,7 @@ private static function _mkMatrix() { // Convert infix to postfix notation private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { - if (($formula = self::_convertMatrixReferences(trim($formula))) === FALSE) { + if (($formula = $this->_convertMatrixReferences(trim($formula))) === FALSE) { return FALSE; } From b4a4062a5d58de9fc1fc6b5090c0f970b6ae0de1 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 29 Mar 2014 00:06:50 +0000 Subject: [PATCH 206/467] GH-343 Error with PCLZip temporary directory --- Classes/PHPExcel/Shared/ZipArchive.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index 5507210af..9a801a841 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -26,7 +26,7 @@ */ if (!defined('PCLZIP_TEMPORARY_DIR')) { - define('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir()); + define('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir() . DIRECTORY_SEPARATOR); } require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/PCLZip/pclzip.lib.php'; From c2a277c447ca965bbe030cd83d6b92df95661541 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 3 Apr 2014 17:59:47 +0100 Subject: [PATCH 207/467] DocBlock updates --- Classes/PHPExcel/CachedObjectStorage/APC.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/CacheBase.php | 10 +++++----- Classes/PHPExcel/CachedObjectStorage/DiscISAM.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/ICache.php | 8 ++++---- Classes/PHPExcel/CachedObjectStorage/Igbinary.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/Memcache.php | 6 +++--- Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php | 4 ++-- .../PHPExcel/CachedObjectStorage/MemorySerialized.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/PHPTemp.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/SQLite.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/SQLite3.php | 4 ++-- Classes/PHPExcel/CachedObjectStorage/Wincache.php | 4 ++-- 12 files changed, 31 insertions(+), 31 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/APC.php b/Classes/PHPExcel/CachedObjectStorage/APC.php index c256919da..8bde7fe3e 100644 --- a/Classes/PHPExcel/CachedObjectStorage/APC.php +++ b/Classes/PHPExcel/CachedObjectStorage/APC.php @@ -80,7 +80,7 @@ protected function _storeData() { * @access public * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { @@ -102,7 +102,7 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) { * * @access public * @param string $pCoord Coordinate address of the cell to check - * @return void + * @throws PHPExcel_Exception * @return boolean */ public function isDataSet($pCoord) { @@ -165,7 +165,7 @@ public function getCacheData($pCoord) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { if ($this->_currentObjectID !== null) { diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index 5e1b17976..9f780b2a6 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -136,7 +136,7 @@ public function moveCell($fromAddress, $toAddress) { * Add or Update a cell in cache * * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function updateCacheData(PHPExcel_Cell $cell) { @@ -167,7 +167,7 @@ public function deleteCacheData($pCoord) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { return array_keys($this->_cellCache); @@ -177,7 +177,7 @@ public function getCellList() { /** * Sort the list of all cell addresses currently held in cache by row and column * - * @return void + * @return string[] */ public function getSortedCellList() { $sortKeys = array(); @@ -243,12 +243,12 @@ public function getCurrentColumn() /** * Return the row address of the currently active cell object * - * @return string + * @return integer */ public function getCurrentRow() { sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); - return $row; + return (integer) $row; } /** diff --git a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php index 0ae2151a7..96cb1e237 100644 --- a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php +++ b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php @@ -85,7 +85,7 @@ protected function _storeData() { * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { @@ -135,7 +135,7 @@ public function getCacheData($pCoord) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { if ($this->_currentObjectID !== null) { diff --git a/Classes/PHPExcel/CachedObjectStorage/ICache.php b/Classes/PHPExcel/CachedObjectStorage/ICache.php index 7686f3c4b..220905cd4 100644 --- a/Classes/PHPExcel/CachedObjectStorage/ICache.php +++ b/Classes/PHPExcel/CachedObjectStorage/ICache.php @@ -40,7 +40,7 @@ interface PHPExcel_CachedObjectStorage_ICache * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell); @@ -49,7 +49,7 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell); * Add or Update a cell in cache * * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function updateCacheData(PHPExcel_Cell $cell); @@ -82,14 +82,14 @@ public function isDataSet($pCoord); /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList(); /** * Get the list of all cell addresses currently held in cache sorted by column and row * - * @return void + * @return string[] */ public function getSortedCellList(); diff --git a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php index e20d9a828..8bd11f116 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php +++ b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php @@ -58,7 +58,7 @@ protected function _storeData() { * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { @@ -107,7 +107,7 @@ public function getCacheData($pCoord) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { if ($this->_currentObjectID !== null) { diff --git a/Classes/PHPExcel/CachedObjectStorage/Memcache.php b/Classes/PHPExcel/CachedObjectStorage/Memcache.php index 35f3d5968..6a096769e 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memcache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memcache.php @@ -86,7 +86,7 @@ protected function _storeData() { * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { @@ -107,7 +107,7 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) { * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? * * @param string $pCoord Coordinate address of the cell to check - * @return void + * @return boolean * @return boolean */ public function isDataSet($pCoord) { @@ -169,7 +169,7 @@ public function getCacheData($pCoord) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { if ($this->_currentObjectID !== null) { diff --git a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php index f98f0372d..e35563c4e 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php @@ -58,7 +58,7 @@ protected function _storeData() { * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { @@ -107,7 +107,7 @@ public function getCacheData($pCoord) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { if ($this->_currentObjectID !== null) { diff --git a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php index ef597b789..1082deae5 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php @@ -58,7 +58,7 @@ protected function _storeData() { * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { @@ -107,7 +107,7 @@ public function getCacheData($pCoord) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { if ($this->_currentObjectID !== null) { diff --git a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php index fb0c85ed2..1e36e1046 100644 --- a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php +++ b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php @@ -77,7 +77,7 @@ protected function _storeData() { * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { @@ -127,7 +127,7 @@ public function getCacheData($pCoord) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { if ($this->_currentObjectID !== null) { diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php index bcaf011b7..dd4f0e99d 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php @@ -73,7 +73,7 @@ protected function _storeData() { * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { @@ -198,7 +198,7 @@ public function moveCell($fromAddress, $toAddress) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { if ($this->_currentObjectID !== null) { diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index 4446c5604..bdc1d9793 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -104,7 +104,7 @@ protected function _storeData() { * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { @@ -231,7 +231,7 @@ public function moveCell($fromAddress, $toAddress) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { if ($this->_currentObjectID !== null) { diff --git a/Classes/PHPExcel/CachedObjectStorage/Wincache.php b/Classes/PHPExcel/CachedObjectStorage/Wincache.php index a6968566c..cdbef641b 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Wincache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Wincache.php @@ -85,7 +85,7 @@ protected function _storeData() { * * @param string $pCoord Coordinate address of the cell to update * @param PHPExcel_Cell $cell Cell to update - * @return void + * @return PHPExcel_Cell * @throws PHPExcel_Exception */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { @@ -169,7 +169,7 @@ public function getCacheData($pCoord) { /** * Get a list of all cell addresses currently held in cache * - * @return array of string + * @return string[] */ public function getCellList() { if ($this->_currentObjectID !== null) { From 83e024da994997dbb16a7ddab03ea961d8f9a572 Mon Sep 17 00:00:00 2001 From: Bobby Sciacchitano Date: Tue, 8 Apr 2014 11:43:53 +1000 Subject: [PATCH 208/467] Allow value of 0 to be passed into POISSON formula --- Classes/PHPExcel/Calculation/Statistical.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php index 2037f3349..67e1951c2 100644 --- a/Classes/PHPExcel/Calculation/Statistical.php +++ b/Classes/PHPExcel/Calculation/Statistical.php @@ -2737,7 +2737,7 @@ public static function POISSON($value, $mean, $cumulative) { $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); if ((is_numeric($value)) && (is_numeric($mean))) { - if (($value <= 0) || ($mean <= 0)) { + if (($value < 0) || ($mean <= 0)) { return PHPExcel_Calculation_Functions::NaN(); } if ((is_numeric($cumulative)) || (is_bool($cumulative))) { From 9a38a531daa273b7381451482f12d9f614f3976d Mon Sep 17 00:00:00 2001 From: Kevin Auvinet Date: Tue, 15 Apr 2014 15:07:06 +0200 Subject: [PATCH 209/467] Bug "Undefined variable: options" There is a bug for the var `$option`: Notice: Undefined variable: options in [...]/vendor/phpoffice/phpexcel/Classes/PHPExcel/Settings.php on line 384 This bug is fixed with `self::$_libXmlLoaderOptions == (LIBXML_DTDLOAD | LIBXML_DTDATTR)` instead of `$options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)` --- Classes/PHPExcel/Settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php index 839231ba0..d9d197a55 100644 --- a/Classes/PHPExcel/Settings.php +++ b/Classes/PHPExcel/Settings.php @@ -381,7 +381,7 @@ public static function getLibXmlLoaderOptions() if (is_null(self::$_libXmlLoaderOptions)) { self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR); } - @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + @libxml_disable_entity_loader(self::$_libXmlLoaderOptions == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); return self::$_libXmlLoaderOptions; } // function getLibXmlLoaderOptions } From 6d72423579b1af098bfa47351c87133676b1aeea Mon Sep 17 00:00:00 2001 From: januar Date: Sat, 10 May 2014 18:24:51 +0700 Subject: [PATCH 210/467] change sequential validation for orientation dompdf --- Classes/PHPExcel/Writer/PDF/DomPDF.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/PDF/DomPDF.php b/Classes/PHPExcel/Writer/PDF/DomPDF.php index 9ba97efcf..01e4e0122 100644 --- a/Classes/PHPExcel/Writer/PDF/DomPDF.php +++ b/Classes/PHPExcel/Writer/PDF/DomPDF.php @@ -83,6 +83,9 @@ public function save($pFilename = NULL) $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); } + + $orientation = ($orientation == 'L') ? 'landscape' : 'portrait'; + // Override Page Orientation if (!is_null($this->getOrientation())) { $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) @@ -98,7 +101,6 @@ public function save($pFilename = NULL) $paperSize = self::$_paperSizes[$printPaperSize]; } - $orientation = ($orientation == 'L') ? 'landscape' : 'portrait'; // Create PDF $pdf = new DOMPDF(); From 08c1f4b19a8c3e773c970f4cbba6f992fc330b98 Mon Sep 17 00:00:00 2001 From: Travis Paul Date: Wed, 14 May 2014 16:31:09 -0400 Subject: [PATCH 211/467] Prevent autoload clash when previous code has used spl_autoload_register --- Classes/PHPExcel/Autoloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Autoloader.php b/Classes/PHPExcel/Autoloader.php index 221666f99..db0dbef14 100644 --- a/Classes/PHPExcel/Autoloader.php +++ b/Classes/PHPExcel/Autoloader.php @@ -55,7 +55,7 @@ public static function Register() { spl_autoload_register('__autoload'); } // Register ourselves with SPL - return spl_autoload_register(array('PHPExcel_Autoloader', 'Load')); + return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'), true, true); } // function Register() From c7060d29bdf40f5d3e6189ac5f04f5230d1a9fc9 Mon Sep 17 00:00:00 2001 From: Diogo Oliveira de Melo Date: Thu, 29 May 2014 16:45:21 -0300 Subject: [PATCH 212/467] Change the names of variables $plotarea and $dataseriesLabel to $plotArea and $dataSeriesLabel, respectively, to make it camel case compliant --- Examples/33chartcreate-area.php | 8 ++++---- Examples/33chartcreate-bar-stacked.php | 8 ++++---- Examples/33chartcreate-bar.php | 8 ++++---- Examples/33chartcreate-column-2.php | 8 ++++---- Examples/33chartcreate-column.php | 8 ++++---- Examples/33chartcreate-composite.php | 16 ++++++++-------- Examples/33chartcreate-line.php | 8 ++++---- Examples/33chartcreate-multiple-charts.php | 16 ++++++++-------- Examples/33chartcreate-pie.php | 16 ++++++++-------- Examples/33chartcreate-radar.php | 8 ++++---- Examples/33chartcreate-scatter.php | 8 ++++---- Examples/33chartcreate-stock.php | 8 ++++---- 12 files changed, 60 insertions(+), 60 deletions(-) diff --git a/Examples/33chartcreate-area.php b/Examples/33chartcreate-area.php index 52ee36b96..53fe52398 100644 --- a/Examples/33chartcreate-area.php +++ b/Examples/33chartcreate-area.php @@ -59,7 +59,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels = array( +$dataSeriesLabels = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012 @@ -92,13 +92,13 @@ PHPExcel_Chart_DataSeries::TYPE_AREACHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping range(0, count($dataSeriesValues)-1), // plotOrder - $dataseriesLabels, // plotLabel + $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); // Set the series in the plot area -$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series)); +$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series)); // Set the chart legend $legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false); @@ -111,7 +111,7 @@ 'chart1', // name $title, // title $legend, // legend - $plotarea, // plotArea + $plotArea, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel diff --git a/Examples/33chartcreate-bar-stacked.php b/Examples/33chartcreate-bar-stacked.php index 755fa78ee..cac29f29f 100644 --- a/Examples/33chartcreate-bar-stacked.php +++ b/Examples/33chartcreate-bar-stacked.php @@ -59,7 +59,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels = array( +$dataSeriesLabels = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012 @@ -92,7 +92,7 @@ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_STACKED, // plotGrouping range(0, count($dataSeriesValues)-1), // plotOrder - $dataseriesLabels, // plotLabel + $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); @@ -101,7 +101,7 @@ $series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_BAR); // Set the series in the plot area -$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series)); +$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series)); // Set the chart legend $legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false); @@ -114,7 +114,7 @@ 'chart1', // name $title, // title $legend, // legend - $plotarea, // plotArea + $plotArea, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel diff --git a/Examples/33chartcreate-bar.php b/Examples/33chartcreate-bar.php index 84f8cf78c..14fd5d485 100644 --- a/Examples/33chartcreate-bar.php +++ b/Examples/33chartcreate-bar.php @@ -59,7 +59,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels = array( +$dataSeriesLabels = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012 @@ -92,7 +92,7 @@ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_CLUSTERED, // plotGrouping range(0, count($dataSeriesValues)-1), // plotOrder - $dataseriesLabels, // plotLabel + $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); @@ -101,7 +101,7 @@ $series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_BAR); // Set the series in the plot area -$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series)); +$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series)); // Set the chart legend $legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false); @@ -114,7 +114,7 @@ 'chart1', // name $title, // title $legend, // legend - $plotarea, // plotArea + $plotArea, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel diff --git a/Examples/33chartcreate-column-2.php b/Examples/33chartcreate-column-2.php index 1d8d689bc..00bf0d71b 100644 --- a/Examples/33chartcreate-column-2.php +++ b/Examples/33chartcreate-column-2.php @@ -67,7 +67,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels = array( +$dataSeriesLabels = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 'Budget' new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 'Forecast' new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$E$1', NULL, 1), // 'Actual' @@ -100,7 +100,7 @@ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_CLUSTERED, // plotGrouping range(0, count($dataSeriesValues)-1), // plotOrder - $dataseriesLabels, // plotLabel + $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); @@ -109,7 +109,7 @@ $series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL); // Set the series in the plot area -$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series)); +$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series)); // Set the chart legend $legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_BOTTOM, NULL, false); @@ -123,7 +123,7 @@ 'chart1', // name $title, // title $legend, // legend - $plotarea, // plotArea + $plotArea, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs $xAxisLabel, // xAxisLabel diff --git a/Examples/33chartcreate-column.php b/Examples/33chartcreate-column.php index eb3d7e211..ae9c6185e 100644 --- a/Examples/33chartcreate-column.php +++ b/Examples/33chartcreate-column.php @@ -59,7 +59,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels = array( +$dataSeriesLabels = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012 @@ -92,7 +92,7 @@ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping range(0, count($dataSeriesValues)-1), // plotOrder - $dataseriesLabels, // plotLabel + $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); @@ -101,7 +101,7 @@ $series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL); // Set the series in the plot area -$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series)); +$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series)); // Set the chart legend $legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false); @@ -114,7 +114,7 @@ 'chart1', // name $title, // title $legend, // legend - $plotarea, // plotArea + $plotArea, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel diff --git a/Examples/33chartcreate-composite.php b/Examples/33chartcreate-composite.php index 0b512f09d..8ea72126c 100644 --- a/Examples/33chartcreate-composite.php +++ b/Examples/33chartcreate-composite.php @@ -68,13 +68,13 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels1 = array( +$dataSeriesLabels1 = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // Temperature ); -$dataseriesLabels2 = array( +$dataSeriesLabels2 = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // Rainfall ); -$dataseriesLabels3 = array( +$dataSeriesLabels3 = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // Humidity ); @@ -106,7 +106,7 @@ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_CLUSTERED, // plotGrouping range(0, count($dataSeriesValues1)-1), // plotOrder - $dataseriesLabels1, // plotLabel + $dataSeriesLabels1, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues1 // plotValues ); @@ -131,7 +131,7 @@ PHPExcel_Chart_DataSeries::TYPE_LINECHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping range(0, count($dataSeriesValues2)-1), // plotOrder - $dataseriesLabels2, // plotLabel + $dataSeriesLabels2, // plotLabel NULL, // plotCategory $dataSeriesValues2 // plotValues ); @@ -153,14 +153,14 @@ PHPExcel_Chart_DataSeries::TYPE_AREACHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping range(0, count($dataSeriesValues2)-1), // plotOrder - $dataseriesLabels3, // plotLabel + $dataSeriesLabels3, // plotLabel NULL, // plotCategory $dataSeriesValues3 // plotValues ); // Set the series in the plot area -$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series1, $series2, $series3)); +$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series1, $series2, $series3)); // Set the chart legend $legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false); @@ -172,7 +172,7 @@ 'chart1', // name $title, // title $legend, // legend - $plotarea, // plotArea + $plotArea, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel diff --git a/Examples/33chartcreate-line.php b/Examples/33chartcreate-line.php index dce75e06b..145ae72e8 100644 --- a/Examples/33chartcreate-line.php +++ b/Examples/33chartcreate-line.php @@ -59,7 +59,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels = array( +$dataSeriesLabels = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012 @@ -92,13 +92,13 @@ PHPExcel_Chart_DataSeries::TYPE_LINECHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_STACKED, // plotGrouping range(0, count($dataSeriesValues)-1), // plotOrder - $dataseriesLabels, // plotLabel + $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); // Set the series in the plot area -$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series)); +$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series)); // Set the chart legend $legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false); @@ -111,7 +111,7 @@ 'chart1', // name $title, // title $legend, // legend - $plotarea, // plotArea + $plotArea, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel diff --git a/Examples/33chartcreate-multiple-charts.php b/Examples/33chartcreate-multiple-charts.php index 7da2fa289..a95c27633 100644 --- a/Examples/33chartcreate-multiple-charts.php +++ b/Examples/33chartcreate-multiple-charts.php @@ -60,7 +60,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels1 = array( +$dataSeriesLabels1 = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012 @@ -93,13 +93,13 @@ PHPExcel_Chart_DataSeries::TYPE_AREACHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping range(0, count($dataSeriesValues1)-1), // plotOrder - $dataseriesLabels1, // plotLabel + $dataSeriesLabels1, // plotLabel $xAxisTickValues1, // plotCategory $dataSeriesValues1 // plotValues ); // Set the series in the plot area -$plotarea1 = new PHPExcel_Chart_PlotArea(NULL, array($series1)); +$plotArea1 = new PHPExcel_Chart_PlotArea(NULL, array($series1)); // Set the chart legend $legend1 = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false); @@ -112,7 +112,7 @@ 'chart1', // name $title1, // title $legend1, // legend - $plotarea1, // plotArea + $plotArea1, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel @@ -134,7 +134,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels2 = array( +$dataSeriesLabels2 = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012 @@ -167,7 +167,7 @@ PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping range(0, count($dataSeriesValues2)-1), // plotOrder - $dataseriesLabels2, // plotLabel + $dataSeriesLabels2, // plotLabel $xAxisTickValues2, // plotCategory $dataSeriesValues2 // plotValues ); @@ -176,7 +176,7 @@ $series2->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL); // Set the series in the plot area -$plotarea2 = new PHPExcel_Chart_PlotArea(NULL, array($series2)); +$plotArea2 = new PHPExcel_Chart_PlotArea(NULL, array($series2)); // Set the chart legend $legend2 = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false); @@ -189,7 +189,7 @@ 'chart2', // name $title2, // title $legend2, // legend - $plotarea2, // plotArea + $plotArea2, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel diff --git a/Examples/33chartcreate-pie.php b/Examples/33chartcreate-pie.php index 1a4f1df4a..e1e388fdd 100644 --- a/Examples/33chartcreate-pie.php +++ b/Examples/33chartcreate-pie.php @@ -60,7 +60,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels1 = array( +$dataSeriesLabels1 = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 ); // Set the X-Axis Labels @@ -89,7 +89,7 @@ PHPExcel_Chart_DataSeries::TYPE_PIECHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping range(0, count($dataSeriesValues1)-1), // plotOrder - $dataseriesLabels1, // plotLabel + $dataSeriesLabels1, // plotLabel $xAxisTickValues1, // plotCategory $dataSeriesValues1 // plotValues ); @@ -100,7 +100,7 @@ $layout1->setShowPercent(TRUE); // Set the series in the plot area -$plotarea1 = new PHPExcel_Chart_PlotArea($layout1, array($series1)); +$plotArea1 = new PHPExcel_Chart_PlotArea($layout1, array($series1)); // Set the chart legend $legend1 = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false); @@ -112,7 +112,7 @@ 'chart1', // name $title1, // title $legend1, // legend - $plotarea1, // plotArea + $plotArea1, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel @@ -134,7 +134,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels2 = array( +$dataSeriesLabels2 = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 ); // Set the X-Axis Labels @@ -163,7 +163,7 @@ PHPExcel_Chart_DataSeries::TYPE_DONUTCHART, // plotType PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping range(0, count($dataSeriesValues2)-1), // plotOrder - $dataseriesLabels2, // plotLabel + $dataSeriesLabels2, // plotLabel $xAxisTickValues2, // plotCategory $dataSeriesValues2 // plotValues ); @@ -174,7 +174,7 @@ $layout2->setShowCatName(TRUE); // Set the series in the plot area -$plotarea2 = new PHPExcel_Chart_PlotArea($layout2, array($series2)); +$plotArea2 = new PHPExcel_Chart_PlotArea($layout2, array($series2)); $title2 = new PHPExcel_Chart_Title('Test Donut Chart'); @@ -184,7 +184,7 @@ 'chart2', // name $title2, // title NULL, // legend - $plotarea2, // plotArea + $plotArea2, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel diff --git a/Examples/33chartcreate-radar.php b/Examples/33chartcreate-radar.php index 29fb2200f..d0e2b9fa6 100644 --- a/Examples/33chartcreate-radar.php +++ b/Examples/33chartcreate-radar.php @@ -68,7 +68,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels = array( +$dataSeriesLabels = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012 ); @@ -100,7 +100,7 @@ PHPExcel_Chart_DataSeries::TYPE_RADARCHART, // plotType NULL, // plotGrouping range(0, count($dataSeriesValues)-1), // plotOrder - $dataseriesLabels, // plotLabel + $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues, // plotValues NULL, // smooth line @@ -111,7 +111,7 @@ $layout = new PHPExcel_Chart_Layout(); // Set the series in the plot area -$plotarea = new PHPExcel_Chart_PlotArea($layout, array($series)); +$plotArea = new PHPExcel_Chart_PlotArea($layout, array($series)); // Set the chart legend $legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false); @@ -123,7 +123,7 @@ 'chart1', // name $title, // title $legend, // legend - $plotarea, // plotArea + $plotArea, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel diff --git a/Examples/33chartcreate-scatter.php b/Examples/33chartcreate-scatter.php index 53851ad46..250c61d7e 100644 --- a/Examples/33chartcreate-scatter.php +++ b/Examples/33chartcreate-scatter.php @@ -59,7 +59,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels = array( +$dataSeriesLabels = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011 new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012 @@ -86,7 +86,7 @@ PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART, // plotType NULL, // plotGrouping (Scatter charts don't have any grouping) range(0, count($dataSeriesValues)-1), // plotOrder - $dataseriesLabels, // plotLabel + $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues, // plotValues NULL, // smooth line @@ -94,7 +94,7 @@ ); // Set the series in the plot area -$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series)); +$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series)); // Set the chart legend $legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false); @@ -107,7 +107,7 @@ 'chart1', // name $title, // title $legend, // legend - $plotarea, // plotArea + $plotArea, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs NULL, // xAxisLabel diff --git a/Examples/33chartcreate-stock.php b/Examples/33chartcreate-stock.php index dfc8d5cdd..b38fd5181 100644 --- a/Examples/33chartcreate-stock.php +++ b/Examples/33chartcreate-stock.php @@ -62,7 +62,7 @@ // Number of datapoints in series // Data values // Data Marker -$dataseriesLabels = array( +$dataSeriesLabels = array( new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), //Max / Open new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), //Min / Close new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), //Min Threshold / Min @@ -97,13 +97,13 @@ PHPExcel_Chart_DataSeries::TYPE_STOCKCHART, // plotType null, // plotGrouping - if we set this to not null, then xlsx throws error range(0, count($dataSeriesValues)-1), // plotOrder - $dataseriesLabels, // plotLabel + $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); // Set the series in the plot area -$plotarea = new PHPExcel_Chart_PlotArea(NULL, array($series)); +$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series)); // Set the chart legend $legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false); @@ -116,7 +116,7 @@ 'stock-chart', // name $title, // title $legend, // legend - $plotarea, // plotArea + $plotArea, // plotArea true, // plotVisibleOnly 0, // displayBlanksAs $xAxisLabel, // xAxisLabel From 2376bef3c24fd17c49164172d75d5aa4bc831da1 Mon Sep 17 00:00:00 2001 From: Alexander Pervakov Date: Thu, 29 May 2014 14:37:45 +0400 Subject: [PATCH 213/467] Implement empty ODF archive Work item CP1930, GH-157 --- Classes/PHPExcel/Writer/OpenDocument.php | 200 ++++++++++++++++++ .../PHPExcel/Writer/OpenDocument/Content.php | 118 +++++++++++ Classes/PHPExcel/Writer/OpenDocument/Meta.php | 98 +++++++++ .../PHPExcel/Writer/OpenDocument/MetaInf.php | 96 +++++++++ .../PHPExcel/Writer/OpenDocument/Mimetype.php | 50 +++++ .../PHPExcel/Writer/OpenDocument/Settings.php | 85 ++++++++ .../PHPExcel/Writer/OpenDocument/Styles.php | 101 +++++++++ .../Writer/OpenDocument/Thumbnails.php | 50 +++++ .../Writer/OpenDocument/WriterPart.php | 38 ++++ 9 files changed, 836 insertions(+) create mode 100644 Classes/PHPExcel/Writer/OpenDocument.php create mode 100644 Classes/PHPExcel/Writer/OpenDocument/Content.php create mode 100644 Classes/PHPExcel/Writer/OpenDocument/Meta.php create mode 100644 Classes/PHPExcel/Writer/OpenDocument/MetaInf.php create mode 100644 Classes/PHPExcel/Writer/OpenDocument/Mimetype.php create mode 100644 Classes/PHPExcel/Writer/OpenDocument/Settings.php create mode 100644 Classes/PHPExcel/Writer/OpenDocument/Styles.php create mode 100644 Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php create mode 100644 Classes/PHPExcel/Writer/OpenDocument/WriterPart.php diff --git a/Classes/PHPExcel/Writer/OpenDocument.php b/Classes/PHPExcel/Writer/OpenDocument.php new file mode 100644 index 000000000..2cbe6f904 --- /dev/null +++ b/Classes/PHPExcel/Writer/OpenDocument.php @@ -0,0 +1,200 @@ + + * @link http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os.html + */ +class PHPExcel_Writer_OpenDocument extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter +{ + /** + * Private writer parts + * + * @var PHPExcel_Writer_OpenDocument_WriterPart[] + */ + private $_writerParts = array(); + + /** + * Private PHPExcel + * + * @var PHPExcel + */ + private $_spreadSheet; + + /** + * Create a new PHPExcel_Writer_OpenDocument + * + * @param PHPExcel $pPHPExcel + */ + public function __construct(PHPExcel $pPHPExcel = null) + { + $this->setPHPExcel($pPHPExcel); + + $writerPartsArray = array( + 'content' => 'PHPExcel_Writer_OpenDocument_Content', + 'meta' => 'PHPExcel_Writer_OpenDocument_Meta', + 'meta_inf' => 'PHPExcel_Writer_OpenDocument_MetaInf', + 'mimetype' => 'PHPExcel_Writer_OpenDocument_Mimetype', + 'settings' => 'PHPExcel_Writer_OpenDocument_Settings', + 'styles' => 'PHPExcel_Writer_OpenDocument_Styles', + 'thumbnails' => 'PHPExcel_Writer_OpenDocument_Thumbnails' + ); + + foreach ($writerPartsArray as $writer => $class) { + $this->_writerParts[$writer] = new $class($this); + } + } + + /** + * Get writer part + * + * @param string $pPartName Writer part name + * @return PHPExcel_Writer_Excel2007_WriterPart + */ + public function getWriterPart($pPartName = '') + { + if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) { + return $this->_writerParts[strtolower($pPartName)]; + } else { + return null; + } + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = NULL) + { + if (!$this->_spreadSheet) { + throw new PHPExcel_Writer_Exception('PHPExcel object unassigned.'); + } + + // garbage collect + $this->_spreadSheet->garbageCollect(); + + // If $pFilename is php://output or php://stdout, make it a temporary file... + $originalFilename = $pFilename; + if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') { + $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp'); + if ($pFilename == '') { + $pFilename = $originalFilename; + } + } + + $objZip = $this->_createZip($pFilename); + + $objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest()); + $objZip->addFromString('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail()); + $objZip->addFromString('content.xml', $this->getWriterPart('content')->write()); + $objZip->addFromString('meta.xml', $this->getWriterPart('meta')->write()); + $objZip->addFromString('mimetype', $this->getWriterPart('mimetype')->write()); + $objZip->addFromString('settings.xml', $this->getWriterPart('settings')->write()); + $objZip->addFromString('styles.xml', $this->getWriterPart('styles')->write()); + + // Close file + if ($objZip->close() === false) { + throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename."); + } + + // If a temporary file was used, copy it to the correct file stream + if ($originalFilename != $pFilename) { + if (copy($pFilename, $originalFilename) === false) { + throw new PHPExcel_Writer_Exception("Could not copy temporary zip file $pFilename to $originalFilename."); + } + @unlink($pFilename); + } + } + + /** + * Create zip object + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + * @return ZipArchive + */ + private function _createZip($pFilename) + { + // Create new ZIP file and open it for writing + $zipClass = PHPExcel_Settings::getZipClass(); + $objZip = new $zipClass(); + + // Retrieve OVERWRITE and CREATE constants from the instantiated zip class + // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP + $ro = new ReflectionObject($objZip); + $zipOverWrite = $ro->getConstant('OVERWRITE'); + $zipCreate = $ro->getConstant('CREATE'); + + if (file_exists($pFilename)) { + unlink($pFilename); + } + // Try opening the ZIP file + if ($objZip->open($pFilename, $zipOverWrite) !== true) { + if ($objZip->open($pFilename, $zipCreate) !== true) { + throw new PHPExcel_Writer_Exception("Could not open $pFilename for writing."); + } + } + + return $objZip; + } + + /** + * Get PHPExcel object + * + * @return PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function getPHPExcel() + { + if ($this->_spreadSheet !== null) { + return $this->_spreadSheet; + } else { + throw new PHPExcel_Writer_Exception('No PHPExcel assigned.'); + } + } + + /** + * Set PHPExcel object + * + * @param PHPExcel $pPHPExcel PHPExcel object + * @throws PHPExcel_Writer_Exception + * @return PHPExcel_Writer_Excel2007 + */ + public function setPHPExcel(PHPExcel $pPHPExcel = null) + { + $this->_spreadSheet = $pPHPExcel; + return $this; + } +} diff --git a/Classes/PHPExcel/Writer/OpenDocument/Content.php b/Classes/PHPExcel/Writer/OpenDocument/Content.php new file mode 100644 index 000000000..d294b2e57 --- /dev/null +++ b/Classes/PHPExcel/Writer/OpenDocument/Content.php @@ -0,0 +1,118 @@ + + */ +class PHPExcel_Writer_OpenDocument_Content extends PHPExcel_Writer_OpenDocument_WriterPart +{ + /** + * Write content.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function write(PHPExcel $pPHPExcel = null) + { + if (!$pPHPExcel) { + $pPHPExcel = $this->getParentWriter()->getPHPExcel(); + } + + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0', 'UTF-8'); + + // Content + $objWriter->startElement('office:document-content'); + $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); + $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0'); + $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0'); + $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0'); + $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0'); + $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0'); + $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); + $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); + $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'); + $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0'); + $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0'); + $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0'); + $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0'); + $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0'); + $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML'); + $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0'); + $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0'); + $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); + $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer'); + $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc'); + $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events'); + $objWriter->writeAttribute('xmlns:xforms', 'http://www.w3.org/2002/xforms'); + $objWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema'); + $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report'); + $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2'); + $objWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml'); + $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#'); + $objWriter->writeAttribute('xmlns:tableooo', 'http://openoffice.org/2009/table'); + $objWriter->writeAttribute('xmlns:field', 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0'); + $objWriter->writeAttribute('xmlns:formx', 'urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0'); + $objWriter->writeAttribute('xmlns:css3t', 'http://www.w3.org/TR/css3-text/'); + $objWriter->writeAttribute('office:version', '1.2'); + + $objWriter->writeElement('office:scripts'); + $objWriter->writeElement('office:font-face-decls'); + $objWriter->writeElement('office:automatic-styles'); + + $objWriter->startElement('office:body'); + $objWriter->startElement('office:spreadsheet'); + $objWriter->writeElement('table:calculation-settings'); + $objWriter->startElement('table:table'); + $objWriter->writeAttribute('table:name', ''); + $objWriter->writeElement('office:forms'); + $objWriter->writeElement('table:table-column'); + $objWriter->writeElement('table:table-row'); + $objWriter->endElement(); + $objWriter->writeElement('table:named-expressions'); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + return $objWriter->getData(); + } +} diff --git a/Classes/PHPExcel/Writer/OpenDocument/Meta.php b/Classes/PHPExcel/Writer/OpenDocument/Meta.php new file mode 100644 index 000000000..7f39e5589 --- /dev/null +++ b/Classes/PHPExcel/Writer/OpenDocument/Meta.php @@ -0,0 +1,98 @@ + + */ +class PHPExcel_Writer_OpenDocument_Meta extends PHPExcel_Writer_OpenDocument_WriterPart +{ + /** + * Write meta.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function write(PHPExcel $pPHPExcel = null) + { + if (!$pPHPExcel) { + $pPHPExcel = $this->getParentWriter()->getPHPExcel(); + } + + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0', 'UTF-8'); + + // Meta + $objWriter->startElement('office:document-meta'); + $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); + $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); + $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); + $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'); + $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); + $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#'); + $objWriter->writeAttribute('office:version', '1.2'); + + $objWriter->startElement('office:meta'); + $objWriter->writeElement('meta:initial-creator', $pPHPExcel->getProperties()->getCreator()); + $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); + $objWriter->writeElement('meta:creation-date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); + $objWriter->writeElement('dc:date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); + $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); + $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); + $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); + $keywords = explode(' ', $pPHPExcel->getProperties()->getKeywords()); + foreach ($keywords as $keyword) { + $objWriter->writeElement('meta:keyword', $keyword); + } + // + $objWriter->startElement('meta:user-defined'); + $objWriter->writeAttribute('meta:name', 'Company'); + $objWriter->writeRaw($pPHPExcel->getProperties()->getCompany()); + $objWriter->endElement(); + $objWriter->startElement('meta:user-defined'); + $objWriter->writeAttribute('meta:name', 'category'); + $objWriter->writeRaw($pPHPExcel->getProperties()->getCategory()); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + return $objWriter->getData(); + } +} diff --git a/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php b/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php new file mode 100644 index 000000000..301d39db9 --- /dev/null +++ b/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php @@ -0,0 +1,96 @@ + + */ +class PHPExcel_Writer_OpenDocument_MetaInf extends PHPExcel_Writer_OpenDocument_WriterPart +{ + /** + * Write META-INF/manifest.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeManifest(PHPExcel $pPHPExcel = null) + { + if (!$pPHPExcel) { + $pPHPExcel = $this->getParentWriter()->getPHPExcel(); + } + + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0', 'UTF-8'); + + // Manifest + $objWriter->startElement('manifest:manifest'); + $objWriter->writeAttribute('xmlns:manifest', 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0'); + $objWriter->writeAttribute('manifest:version', '1.2'); + + $objWriter->startElement('manifest:file-entry'); + $objWriter->writeAttribute('manifest:full-path', '/'); + $objWriter->writeAttribute('manifest:version', '1.2'); + $objWriter->writeAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.spreadsheet'); + $objWriter->endElement(); + $objWriter->startElement('manifest:file-entry'); + $objWriter->writeAttribute('manifest:full-path', 'meta.xml'); + $objWriter->writeAttribute('manifest:media-type', 'text/xml'); + $objWriter->endElement(); + $objWriter->startElement('manifest:file-entry'); + $objWriter->writeAttribute('manifest:full-path', 'settings.xml'); + $objWriter->writeAttribute('manifest:media-type', 'text/xml'); + $objWriter->endElement(); + $objWriter->startElement('manifest:file-entry'); + $objWriter->writeAttribute('manifest:full-path', 'content.xml'); + $objWriter->writeAttribute('manifest:media-type', 'text/xml'); + $objWriter->endElement(); + $objWriter->startElement('manifest:file-entry'); + $objWriter->writeAttribute('manifest:full-path', 'Thumbnails/thumbnail.png'); + $objWriter->writeAttribute('manifest:media-type', 'image/png'); + $objWriter->endElement(); + $objWriter->startElement('manifest:file-entry'); + $objWriter->writeAttribute('manifest:full-path', 'styles.xml'); + $objWriter->writeAttribute('manifest:media-type', 'text/xml'); + $objWriter->endElement(); + $objWriter->endElement(); + + return $objWriter->getData(); + } +} diff --git a/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php b/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php new file mode 100644 index 000000000..99ff638a9 --- /dev/null +++ b/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php @@ -0,0 +1,50 @@ + + */ +class PHPExcel_Writer_OpenDocument_Mimetype extends PHPExcel_Writer_OpenDocument_WriterPart +{ + /** + * Write mimetype to plain text format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function write(PHPExcel $pPHPExcel = null) + { + return 'application/vnd.oasis.opendocument.spreadsheet'; + } +} diff --git a/Classes/PHPExcel/Writer/OpenDocument/Settings.php b/Classes/PHPExcel/Writer/OpenDocument/Settings.php new file mode 100644 index 000000000..557e748d4 --- /dev/null +++ b/Classes/PHPExcel/Writer/OpenDocument/Settings.php @@ -0,0 +1,85 @@ + + */ +class PHPExcel_Writer_OpenDocument_Settings extends PHPExcel_Writer_OpenDocument_WriterPart +{ + /** + * Write settings.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function write(PHPExcel $pPHPExcel = null) + { + if (!$pPHPExcel) { + $pPHPExcel = $this->getParentWriter()->getPHPExcel(); + } + + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0', 'UTF-8'); + + // Settings + $objWriter->startElement('office:document-settings'); + $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); + $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); + $objWriter->writeAttribute('xmlns:config', 'urn:oasis:names:tc:opendocument:xmlns:config:1.0'); + $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); + $objWriter->writeAttribute('office:version', '1.2'); + + $objWriter->startElement('office:settings'); + $objWriter->startElement('config:config-item-set'); + $objWriter->writeAttribute('config:name', 'ooo:view-settings'); + $objWriter->startElement('config:config-item-map-indexed'); + $objWriter->writeAttribute('config:name', 'Views'); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->startElement('config:config-item-set'); + $objWriter->writeAttribute('config:name', 'ooo:configuration-settings'); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + return $objWriter->getData(); + } +} diff --git a/Classes/PHPExcel/Writer/OpenDocument/Styles.php b/Classes/PHPExcel/Writer/OpenDocument/Styles.php new file mode 100644 index 000000000..d88673632 --- /dev/null +++ b/Classes/PHPExcel/Writer/OpenDocument/Styles.php @@ -0,0 +1,101 @@ + + */ +class PHPExcel_Writer_OpenDocument_Styles extends PHPExcel_Writer_OpenDocument_WriterPart +{ + /** + * Write styles.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function write(PHPExcel $pPHPExcel = null) + { + if (!$pPHPExcel) { + $pPHPExcel = $this->getParentWriter()->getPHPExcel(); + } + + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0', 'UTF-8'); + + // Content + $objWriter->startElement('office:document-styles'); + $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); + $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0'); + $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0'); + $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0'); + $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0'); + $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0'); + $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); + $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); + $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'); + $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0'); + $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0'); + $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0'); + $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0'); + $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0'); + $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML'); + $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0'); + $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0'); + $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); + $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer'); + $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc'); + $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events'); + $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report'); + $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2'); + $objWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml'); + $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#'); + $objWriter->writeAttribute('xmlns:tableooo', 'http://openoffice.org/2009/table'); + $objWriter->writeAttribute('xmlns:css3t', 'http://www.w3.org/TR/css3-text/'); + $objWriter->writeAttribute('office:version', '1.2'); + + $objWriter->writeElement('office:font-face-decls'); + $objWriter->writeElement('office:styles'); + $objWriter->writeElement('office:automatic-styles'); + $objWriter->writeElement('office:master-styles'); + $objWriter->endElement(); + + return $objWriter->getData(); + } +} diff --git a/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php b/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php new file mode 100644 index 000000000..a7e85c456 --- /dev/null +++ b/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php @@ -0,0 +1,50 @@ + + */ +class PHPExcel_Writer_OpenDocument_Thumbnails extends PHPExcel_Writer_OpenDocument_WriterPart +{ + /** + * Write Thumbnails/thumbnail.png to PNG format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeThumbnail(PHPExcel $pPHPExcel = null) + { + return ''; + } +} diff --git a/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php b/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php new file mode 100644 index 000000000..e6e713a1b --- /dev/null +++ b/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php @@ -0,0 +1,38 @@ + Date: Fri, 30 May 2014 10:44:22 +0400 Subject: [PATCH 214/467] Implements basic writing functionality --- .../PHPExcel/Writer/OpenDocument/Content.php | 163 +++++++++++++++++- 1 file changed, 156 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/Writer/OpenDocument/Content.php b/Classes/PHPExcel/Writer/OpenDocument/Content.php index d294b2e57..932f2cae2 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Content.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Content.php @@ -36,6 +36,9 @@ */ class PHPExcel_Writer_OpenDocument_Content extends PHPExcel_Writer_OpenDocument_WriterPart { + const NUMBER_COLS_REPEATED_MAX = 1024; + const NUMBER_ROWS_REPEATED_MAX = 1048576; + /** * Write content.xml to XML format * @@ -46,7 +49,7 @@ class PHPExcel_Writer_OpenDocument_Content extends PHPExcel_Writer_OpenDocument_ public function write(PHPExcel $pPHPExcel = null) { if (!$pPHPExcel) { - $pPHPExcel = $this->getParentWriter()->getPHPExcel(); + $pPHPExcel = $this->getParentWriter()->getPHPExcel(); /* @var $pPHPExcel PHPExcel */ } $objWriter = null; @@ -102,12 +105,7 @@ public function write(PHPExcel $pPHPExcel = null) $objWriter->startElement('office:body'); $objWriter->startElement('office:spreadsheet'); $objWriter->writeElement('table:calculation-settings'); - $objWriter->startElement('table:table'); - $objWriter->writeAttribute('table:name', ''); - $objWriter->writeElement('office:forms'); - $objWriter->writeElement('table:table-column'); - $objWriter->writeElement('table:table-row'); - $objWriter->endElement(); + $this->_writeSheets($objWriter); $objWriter->writeElement('table:named-expressions'); $objWriter->endElement(); $objWriter->endElement(); @@ -115,4 +113,155 @@ public function write(PHPExcel $pPHPExcel = null) return $objWriter->getData(); } + + /** + * Write sheets + * + * @param PHPExcel_Shared_XMLWriter $objWriter + */ + private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter) + { + $pPHPExcel = $this->getParentWriter()->getPHPExcel(); /* @var $pPHPExcel PHPExcel */ + + $sheet_count = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheet_count; $i++) { + //$this->getWriterPart('Worksheet')->writeWorksheet()); + $objWriter->startElement('table:table'); + $objWriter->writeAttribute('table:name', $pPHPExcel->getSheet($i)->getTitle()); + $objWriter->writeElement('office:forms'); + $objWriter->startElement('table:table-column'); + $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX); + $objWriter->endElement(); + $this->_writeRows($objWriter, $pPHPExcel->getSheet($i)); + $objWriter->endElement(); + } + } + + /** + * Write rows of the specified sheet + * + * @param PHPExcel_Shared_XMLWriter $objWriter + * @param PHPExcel_Worksheet $sheet + */ + private function _writeRows(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet $sheet) + { + $number_rows_repeated = self::NUMBER_ROWS_REPEATED_MAX; + $span_row = 0; + $rows = $sheet->getRowIterator(); + while ($rows->valid()) { + $number_rows_repeated--; + $row = $rows->current(); + if ($row->getCellIterator()->valid()) { + if ($span_row) { + $objWriter->startElement('table:table-row'); + if ($span_row > 1) { + $objWriter->writeAttribute('table:number-rows-repeated', $span_row); + } + $objWriter->startElement('table:table-cell'); + $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX); + $objWriter->endElement(); + $objWriter->endElement(); + $span_row = 0; + } + $objWriter->startElement('table:table-row'); + $this->_writeCells($objWriter, $row); + $objWriter->endElement(); + } else { + $span_row++; + } + $rows->next(); + } + } + + /** + * Write cells of the specified row + * + * @param PHPExcel_Shared_XMLWriter $objWriter + * @param PHPExcel_Worksheet_Row $row + * @throws PHPExcel_Writer_Exception + */ + private function _writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet_Row $row) + { + $number_cols_repeated = self::NUMBER_COLS_REPEATED_MAX; + $prev_column = -1; + $cells = $row->getCellIterator(); + while ($cells->valid()) { + $cell = $cells->current(); + $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1; + + $this->_writeCellSpan($objWriter, $column, $prev_column); + $objWriter->startElement('table:table-cell'); + + switch ($cell->getDataType()) { + case PHPExcel_Cell_DataType::TYPE_BOOL: + $objWriter->writeAttribute('office:value-type', 'boolean'); + $objWriter->writeAttribute('office:value', $cell->getValue()); + $objWriter->writeElement('text:p', $cell->getValue()); + break; + + case PHPExcel_Cell_DataType::TYPE_ERROR: + throw new PHPExcel_Writer_Exception('Writing of error not implemented yet.'); + break; + + case PHPExcel_Cell_DataType::TYPE_FORMULA: + try { + $formula_value = PHPExcel_Calculation::getInstance()->calculateCellValue($cell); + } catch (Exception $e) { + $formula_value = $cell->getValue(); + } + $objWriter->writeAttribute('table:formula', 'of:' . $cell->getValue()); + $objWriter->writeAttribute('office:value-type', 'float'); + $objWriter->writeAttribute('office:value', $formula_value); + $objWriter->writeElement('text:p', $formula_value); + break; + + case PHPExcel_Cell_DataType::TYPE_INLINE: + throw new PHPExcel_Writer_Exception('Writing of inline not implemented yet.'); + break; + + case PHPExcel_Cell_DataType::TYPE_NUMERIC: + $objWriter->writeAttribute('office:value-type', 'float'); + $objWriter->writeAttribute('office:value', $cell->getValue()); + $objWriter->writeElement('text:p', $cell->getValue()); + break; + + case PHPExcel_Cell_DataType::TYPE_STRING: + $objWriter->writeAttribute('office:value-type', 'string'); + $objWriter->writeElement('text:p', $cell->getValue()); + break; + } + $objWriter->endElement(); + $prev_column = $column; + $cells->next(); + } + $number_cols_repeated = $number_cols_repeated - $prev_column - 1; + if ($number_cols_repeated > 0) { + if ($number_cols_repeated > 1) { + $objWriter->startElement('table:table-cell'); + $objWriter->writeAttribute('table:number-columns-repeated', $number_cols_repeated); + $objWriter->endElement(); + } else { + $objWriter->writeElement('table:table-cell'); + } + } + } + + /** + * Write span + * + * @param PHPExcel_Shared_XMLWriter $objWriter + * @param integer $curColumn + * @param integer $prevColumn + */ + private function _writeCellSpan(PHPExcel_Shared_XMLWriter $objWriter, $curColumn, $prevColumn) + { + $diff = $curColumn - $prevColumn - 1; + if (1 === $diff) { + $objWriter->writeElement('table:table-cell'); + } elseif ($diff > 1) { + $objWriter->startElement('table:table-cell'); + $objWriter->writeAttribute('table:number-columns-repeated', $diff); + $objWriter->endElement(); + } + } } From de6a1ab35472762d2f67be00e6ae358289c3caaa Mon Sep 17 00:00:00 2001 From: Alexander Pervakov Date: Fri, 30 May 2014 11:13:34 +0400 Subject: [PATCH 215/467] Add example --- Examples/01simple-download-ods.php | 90 ++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 Examples/01simple-download-ods.php diff --git a/Examples/01simple-download-ods.php b/Examples/01simple-download-ods.php new file mode 100644 index 000000000..ddabd3ee4 --- /dev/null +++ b/Examples/01simple-download-ods.php @@ -0,0 +1,90 @@ +getProperties()->setCreator("Maarten Balliauw") + ->setLastModifiedBy("Maarten Balliauw") + ->setTitle("Office 2007 XLSX Test Document") + ->setSubject("Office 2007 XLSX Test Document") + ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") + ->setKeywords("office 2007 openxml php") + ->setCategory("Test result file"); + + +// Add some data +$objPHPExcel->setActiveSheetIndex(0) + ->setCellValue('A1', 'Hello') + ->setCellValue('B2', 'world!') + ->setCellValue('C1', 'Hello') + ->setCellValue('D2', 'world!'); + +// Miscellaneous glyphs, UTF-8 +$objPHPExcel->setActiveSheetIndex(0) + ->setCellValue('A4', 'Miscellaneous glyphs') + ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç'); + +// Rename worksheet +$objPHPExcel->getActiveSheet()->setTitle('Simple'); + + +// Set active sheet index to the first sheet, so Excel opens this as the first sheet +$objPHPExcel->setActiveSheetIndex(0); + + +// Redirect output to a client’s web browser (OpenDocument) +header('Content-Type: application/vnd.oasis.opendocument.spreadsheet'); +header('Content-Disposition: attachment;filename="01simple.ods"'); +header('Cache-Control: max-age=0'); +// If you're serving to IE 9, then the following may be needed +header('Cache-Control: max-age=1'); + +// If you're serving to IE over SSL, then the following may be needed +header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past +header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified +header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1 +header ('Pragma: public'); // HTTP/1.0 + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'OpenDocument'); +//$objWriter->save('php://output'); +$objWriter->save('a.ods'); +exit; From a6f00db9c68b96430177e962b82dad3e59255f9f Mon Sep 17 00:00:00 2001 From: Alexander Pervakov Date: Fri, 30 May 2014 14:37:11 +0400 Subject: [PATCH 216/467] Change the getter/setter for zeroHeight to camel case --- Classes/PHPExcel/Reader/Excel2007.php | 6 +++--- Classes/PHPExcel/Worksheet/RowDimension.php | 4 ++-- Classes/PHPExcel/Writer/Excel2007/Worksheet.php | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 105904c64..7647d58de 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -478,7 +478,7 @@ public function load($pFilename) $macros = $customUI = NULL; foreach ($relsWorkbook->Relationship as $ele) { switch($ele['Type']){ - case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": $worksheets[(string) $ele["Id"]] = $ele["Target"]; break; // a vbaProject ? (: some macros) @@ -756,7 +756,7 @@ public function load($pFilename) } if (isset($xmlSheet->sheetFormatPr['zeroHeight']) && ((string)$xmlSheet->sheetFormatPr['zeroHeight'] == '1')) { - $docSheet->getDefaultRowDimension()->setzeroHeight(true); + $docSheet->getDefaultRowDimension()->setZeroHeight(true); } } @@ -1984,7 +1984,7 @@ private function _readRibbon($excel, $customUITarget, $zip) $nameCustomUI = basename($customUITarget); // get the xml file (ribbon) $localRibbon = $this->_getFromZipArchive($zip, $customUITarget); - $customUIImagesNames = array(); + $customUIImagesNames = array(); $customUIImagesBinaries = array(); // something like customUI/_rels/customUI.xml.rels $pathRels = $baseDir . '/_rels/' . $nameCustomUI . '.rels'; diff --git a/Classes/PHPExcel/Worksheet/RowDimension.php b/Classes/PHPExcel/Worksheet/RowDimension.php index 93535f55e..bff89a080 100644 --- a/Classes/PHPExcel/Worksheet/RowDimension.php +++ b/Classes/PHPExcel/Worksheet/RowDimension.php @@ -145,7 +145,7 @@ public function setRowHeight($pValue = -1) { * * @return bool */ - public function getzeroHeight() { + public function getZeroHeight() { return $this->_zeroHeight; } @@ -155,7 +155,7 @@ public function getzeroHeight() { * @param bool $pValue * @return PHPExcel_Worksheet_RowDimension */ - public function setzeroHeight($pValue = false) { + public function setZeroHeight($pValue = false) { $this->_zeroHeight = $pValue; return $this; } diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index 760581647..5cb803e52 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -326,8 +326,8 @@ private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null } // Set Zero Height row - if ((string)$pSheet->getDefaultRowDimension()->getzeroHeight() == '1' || - strtolower((string)$pSheet->getDefaultRowDimension()->getzeroHeight()) == 'true' ) { + if ((string)$pSheet->getDefaultRowDimension()->getZeroHeight() == '1' || + strtolower((string)$pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true' ) { $objWriter->writeAttribute('zeroHeight', '1'); } From 5569c924498fa8ea42dcae3cdd88f745376117aa Mon Sep 17 00:00:00 2001 From: Shawn Welch Date: Fri, 30 May 2014 16:46:44 -0400 Subject: [PATCH 217/467] Invalid Index This happened when I tried to load an Excel doc that was exported by Google Docs. I'm guessing there is no author information or something? I dunno but this fixed worked. --- Classes/PHPExcel/Reader/Excel2007.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 105904c64..9ba62ec41 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1302,7 +1302,8 @@ public function load($pFilename) // Loop through contents foreach ($commentsFile->commentList->comment as $comment) { - $docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] ); + if(!empty($comment['authorId'])) + $docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] ); $docSheet->getComment( (string)$comment['ref'] )->setText( $this->_parseRichText($comment->text) ); } } From f5c0d0a3fdcf9aa8ad30a304f585bd7c9d91eec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20ANDR=C3=89?= Date: Fri, 6 Jun 2014 15:56:40 +0200 Subject: [PATCH 218/467] Fixed bug on jpgraph dependencies (It's suggested to use composer jpgraph/jpgraph instead of requiring these files) --- Classes/PHPExcel/Chart/Renderer/jpgraph.php | 34 ++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index 41066efac..99a0b97ad 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -554,7 +554,7 @@ private function _renderPlotStock($groupID) { private function _renderAreaChart($groupCount, $dimensions = '2d') { - require_once('jpgraph_line.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); $this->_renderCartesianPlotArea(); @@ -565,7 +565,7 @@ private function _renderAreaChart($groupCount, $dimensions = '2d') { private function _renderLineChart($groupCount, $dimensions = '2d') { - require_once('jpgraph_line.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); $this->_renderCartesianPlotArea(); @@ -576,7 +576,7 @@ private function _renderLineChart($groupCount, $dimensions = '2d') { private function _renderBarChart($groupCount, $dimensions = '2d') { - require_once('jpgraph_bar.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); $this->_renderCartesianPlotArea(); @@ -587,9 +587,9 @@ private function _renderBarChart($groupCount, $dimensions = '2d') { private function _renderScatterChart($groupCount) { - require_once('jpgraph_scatter.php'); - require_once('jpgraph_regstat.php'); - require_once('jpgraph_line.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); $this->_renderCartesianPlotArea('linlin'); @@ -600,7 +600,7 @@ private function _renderScatterChart($groupCount) { private function _renderBubbleChart($groupCount) { - require_once('jpgraph_scatter.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); $this->_renderCartesianPlotArea('linlin'); @@ -611,9 +611,9 @@ private function _renderBubbleChart($groupCount) { private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = False, $multiplePlots = False) { - require_once('jpgraph_pie.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie.php'); if ($dimensions == '3d') { - require_once('jpgraph_pie3d.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie3d.php'); } $this->_renderPiePlotArea($doughnut); @@ -686,7 +686,7 @@ private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = Fa private function _renderRadarChart($groupCount) { - require_once('jpgraph_radar.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_radar.php'); $this->_renderRadarPlotArea(); @@ -697,7 +697,7 @@ private function _renderRadarChart($groupCount) { private function _renderStockChart($groupCount) { - require_once('jpgraph_stock.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_stock.php'); $this->_renderCartesianPlotArea('intint'); @@ -708,7 +708,7 @@ private function _renderStockChart($groupCount) { private function _renderContourChart($groupCount,$dimensions) { - require_once('jpgraph_contour.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_contour.php'); $this->_renderCartesianPlotArea('intint'); @@ -719,11 +719,11 @@ private function _renderContourChart($groupCount,$dimensions) { private function _renderCombinationChart($groupCount,$dimensions,$outputDestination) { - require_once('jpgraph_line.php'); - require_once('jpgraph_bar.php'); - require_once('jpgraph_scatter.php'); - require_once('jpgraph_regstat.php'); - require_once('jpgraph_line.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); $this->_renderCartesianPlotArea(); From 5ab877958f3c224aeb83404593e5276df32e986c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 6 Jun 2014 23:56:57 +0100 Subject: [PATCH 219/467] Reduce memory usage after an xls load --- Classes/PHPExcel/Reader/Excel5.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 3e9b091ba..97c3df3c4 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -1089,6 +1089,7 @@ public function load($pFilename) } } } + $this->_data = null; return $this->_phpExcel; } From a6672451a533841332351f8248b5bc2f4b3763cb Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Thu, 12 Jun 2014 09:20:16 +0100 Subject: [PATCH 220/467] Minor Docblock update: return values on load function for PHPExcel_Reader_IReader and Excel2007 now listed as @return PHPExcel in order to utilize auto complete via IDE. --- Classes/PHPExcel/Reader/Excel2007.php | 1 + Classes/PHPExcel/Reader/IReader.php | 1 + 2 files changed, 2 insertions(+) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 9ba62ec41..19fd98269 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -338,6 +338,7 @@ public function _getFromZipArchive($archive, $fileName = '') * Loads PHPExcel from file * * @param string $pFilename + * @return PHPExcel * @throws PHPExcel_Reader_Exception */ public function load($pFilename) diff --git a/Classes/PHPExcel/Reader/IReader.php b/Classes/PHPExcel/Reader/IReader.php index a24ab4e97..b543df4a7 100644 --- a/Classes/PHPExcel/Reader/IReader.php +++ b/Classes/PHPExcel/Reader/IReader.php @@ -47,6 +47,7 @@ public function canRead($pFilename); * Loads PHPExcel from file * * @param string $pFilename + * @return PHPExcel * @throws PHPExcel_Reader_Exception */ public function load($pFilename); From 487888414a511ad24d2328b9d686f5ae56e3aeb7 Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Sun, 15 Jun 2014 18:05:51 +0100 Subject: [PATCH 221/467] Minor Docblock update: corrected the return value from PHPExcel_Shared_Date::ExcelToPHPObject updated to reflect the PHP DateTime object that is to be returned. --- Classes/PHPExcel/Shared/Date.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index f253786d6..75f367eac 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -155,7 +155,7 @@ public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $ti * Convert a date from Excel to a PHP Date/Time object * * @param integer $dateValue Excel date/time value - * @return integer PHP date/time object + * @return DateTime PHP date/time object */ public static function ExcelToPHPObject($dateValue = 0) { $dateTime = self::ExcelToPHP($dateValue); From 0ff99cb6ab9bd5c1683a54861a9fbfc203a31e7b Mon Sep 17 00:00:00 2001 From: CQD Date: Mon, 23 Jun 2014 14:10:09 +0800 Subject: [PATCH 222/467] Code formating --- Classes/PHPExcel/Shared/CodePage.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index d1c4e1a59..46c191ff1 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -84,11 +84,11 @@ public static function NumberToName($codePage = 1252) case 1361: return 'CP1361'; break; // ANSI Korean (Johab) case 10000: return 'MAC'; break; // Apple Roman case 10006: return 'MACGREEK'; break; // Macintosh Greek - case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic - case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) - case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe - case 10079: return 'MACICELAND'; break; // Macintosh Icelandic - case 10081: return 'MACTURKISH'; break; // Macintosh Turkish + case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic + case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) + case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe + case 10079: return 'MACICELAND'; break; // Macintosh Icelandic + case 10081: return 'MACTURKISH'; break; // Macintosh Turkish case 32768: return 'MAC'; break; // Apple Roman case 32769: throw new PHPExcel_Exception('Code page 32769 not supported.'); break; // ANSI Latin I (BIFF2-BIFF3) From 05dbc903920618c6c0a13d469a3407129462eed8 Mon Sep 17 00:00:00 2001 From: CQD Date: Mon, 23 Jun 2014 14:13:27 +0800 Subject: [PATCH 223/467] Code formating --- Classes/PHPExcel/Shared/CodePage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index 46c191ff1..3e3ab2950 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -85,7 +85,7 @@ public static function NumberToName($codePage = 1252) case 10000: return 'MAC'; break; // Apple Roman case 10006: return 'MACGREEK'; break; // Macintosh Greek case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic - case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) + case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe case 10079: return 'MACICELAND'; break; // Macintosh Icelandic case 10081: return 'MACTURKISH'; break; // Macintosh Turkish From ae2e4c9a01e28957a5604addca5405a6274dcb3e Mon Sep 17 00:00:00 2001 From: CQD Date: Mon, 23 Jun 2014 14:18:48 +0800 Subject: [PATCH 224/467] Add MAC CJK codepage Refering to http://msdn.microsoft.com/en-us/library/system.text.encodinginfo.codepage%28v=vs.110%29.aspx --- Classes/PHPExcel/Shared/CodePage.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index 3e3ab2950..01e0ea4f3 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -83,6 +83,9 @@ public static function NumberToName($codePage = 1252) case 1258: return 'CP1258'; break; // ANSI Vietnamese case 1361: return 'CP1361'; break; // ANSI Korean (Johab) case 10000: return 'MAC'; break; // Apple Roman + case 10001: return 'CP932'; break; // Macintosh Japanese + case 10002: return 'CP950'; break; // Macintosh Chinese Traditional + case 10003: return 'CP1361'; break; // Macintosh Korean case 10006: return 'MACGREEK'; break; // Macintosh Greek case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) From ddec5e9706d628bb788691fe5eb6e79a97b5df51 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 3 Jul 2014 00:43:29 +0100 Subject: [PATCH 225/467] Improve speed of calculation for autosize columns to reduce save time --- Classes/PHPExcel/Shared/Font.php | 60 +++++++++++++++++--------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php index 9effd91ec..2ded245dd 100644 --- a/Classes/PHPExcel/Shared/Font.php +++ b/Classes/PHPExcel/Shared/Font.php @@ -241,7 +241,9 @@ public static function getTrueTypeFontPath() return self::$trueTypeFontPath; } - /** + private static $columnWidthAdjust; + + /** * Calculate an (approximate) OpenXML column width, based on font size and text contained * * @param PHPExcel_Style_Font $font Font object @@ -251,7 +253,6 @@ public static function getTrueTypeFontPath() * @return integer Column width */ public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText = '', $rotation = 0, PHPExcel_Style_Font $defaultFont = null) { - // If it is rich text, use plain text if ($cellText instanceof PHPExcel_RichText) { $cellText = $cellText->getPlainText(); @@ -268,25 +269,27 @@ public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText } // Try to get the exact text width in pixels - try { - // If autosize method is set to 'approx', use approximation - if (self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX) { - throw new PHPExcel_Exception('AutoSize method is set to approx'); - } - - // Width of text in pixels excl. padding - $columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation); - - // Excel adds some padding, use 1.07 of the width of an 'n' glyph - $columnWidth += ceil(self::getTextWidthPixelsExact('0', $font, 0) * 1.07); // pixels incl. padding - - } catch (PHPExcel_Exception $e) { + $approximate = self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX; + if (!$approximate) { + if (is_null(self::$columnWidthAdjust)) { + self::$columnWidthAdjust = ceil(self::getTextWidthPixelsExact('0', $font, 0) * 1.07); + } + try { + // Width of text in pixels excl. padding + $columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation) + self::$columnWidthAdjust; + } catch (PHPExcel_Exception $e) { + $approximate == true; + } + } + + if ($approximate) { + if (is_null(self::$columnWidthAdjust)) { + self::$columnWidthAdjust = self::getTextWidthPixelsApprox('n', $font, 0); + } // Width of text in pixels excl. padding, approximation - $columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation); - - // Excel adds some padding, just use approx width of 'n' glyph - $columnWidth += self::getTextWidthPixelsApprox('n', $font, 0); - } + // and addition because Excel adds some padding, just use approx width of 'n' glyph + $columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation) + self::$columnWidthAdjust; + } // Convert from pixel width to column width $columnWidth = PHPExcel_Shared_Drawing::pixelsToCellDimension($columnWidth, $defaultFont); @@ -316,13 +319,13 @@ public static function getTextWidthPixelsExact($text, PHPExcel_Style_Font $font, // Get corners positions $lowerLeftCornerX = $textBox[0]; - $lowerLeftCornerY = $textBox[1]; +// $lowerLeftCornerY = $textBox[1]; $lowerRightCornerX = $textBox[2]; - $lowerRightCornerY = $textBox[3]; +// $lowerRightCornerY = $textBox[3]; $upperRightCornerX = $textBox[4]; - $upperRightCornerY = $textBox[5]; +// $upperRightCornerY = $textBox[5]; $upperLeftCornerX = $textBox[6]; - $upperLeftCornerY = $textBox[7]; +// $upperLeftCornerY = $textBox[7]; // Consider the rotation when calculating the width $textWidth = max($lowerRightCornerX - $upperLeftCornerX, $upperRightCornerX - $lowerLeftCornerX); @@ -353,9 +356,11 @@ public static function getTextWidthPixelsApprox($columnText, PHPExcel_Style_Font case 'Arial': // value 7 was found via interpolation by inspecting real Excel files with Arial 10 font. - $columnWidth = (int) (7 * PHPExcel_Shared_String::CountCharacters($columnText)); +// $columnWidth = (int) (7 * PHPExcel_Shared_String::CountCharacters($columnText)); + // value 8 was set because of experience in different exports at Arial 10 font. + $columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText)); $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size - break; + break; case 'Verdana': // value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font. @@ -383,8 +388,7 @@ public static function getTextWidthPixelsApprox($columnText, PHPExcel_Style_Font } // pixel width is an integer - $columnWidth = (int) $columnWidth; - return $columnWidth; + return (int) $columnWidth; } /** From 59ef7c3325f27a8fbf705ceaba46d94d26c15740 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 3 Jul 2014 01:01:39 +0100 Subject: [PATCH 226/467] Don't cache column width adjustment, because it should be based on the font size being used for a cell, and so should be dynamic --- Classes/PHPExcel/Shared/Font.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php index 2ded245dd..ee0702e44 100644 --- a/Classes/PHPExcel/Shared/Font.php +++ b/Classes/PHPExcel/Shared/Font.php @@ -199,7 +199,6 @@ public static function setAutoSizeMethod($pValue = self::AUTOSIZE_METHOD_APPROX) if (!in_array($pValue,self::$_autoSizeMethods)) { return FALSE; } - self::$autoSizeMethod = $pValue; return TRUE; @@ -241,8 +240,6 @@ public static function getTrueTypeFontPath() return self::$trueTypeFontPath; } - private static $columnWidthAdjust; - /** * Calculate an (approximate) OpenXML column width, based on font size and text contained * @@ -271,24 +268,21 @@ public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText // Try to get the exact text width in pixels $approximate = self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX; if (!$approximate) { - if (is_null(self::$columnWidthAdjust)) { - self::$columnWidthAdjust = ceil(self::getTextWidthPixelsExact('0', $font, 0) * 1.07); - } + $columnWidthAdjust = ceil(self::getTextWidthPixelsExact('n', $font, 0) * 1.07); try { // Width of text in pixels excl. padding - $columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation) + self::$columnWidthAdjust; + // and addition because Excel adds some padding, just use approx width of 'n' glyph + $columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation) + $columnWidthAdjust; } catch (PHPExcel_Exception $e) { $approximate == true; } } if ($approximate) { - if (is_null(self::$columnWidthAdjust)) { - self::$columnWidthAdjust = self::getTextWidthPixelsApprox('n', $font, 0); - } + $columnWidthAdjust = self::getTextWidthPixelsApprox('n', $font, 0); // Width of text in pixels excl. padding, approximation // and addition because Excel adds some padding, just use approx width of 'n' glyph - $columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation) + self::$columnWidthAdjust; + $columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation) + $columnWidthAdjust; } // Convert from pixel width to column width From d03ffd6776b1f0961ed5af7d8000b79e15df62e4 Mon Sep 17 00:00:00 2001 From: goncons Date: Sun, 6 Jul 2014 18:48:07 -0430 Subject: [PATCH 227/467] Open Document cell with not numeric formula Trying to write a Open Document with non numeric formula in a cell this exception was generated: "XMLWriter::writeAttribute() expects parameter 2 to be string, array given" The problem was that writer was using PHPExcel_Calculation::getInstance()->calculateCellValue($cell); instead of $cell->getCalculatedValue(); --- Classes/PHPExcel/Writer/OpenDocument/Content.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Writer/OpenDocument/Content.php b/Classes/PHPExcel/Writer/OpenDocument/Content.php index 932f2cae2..65ee5ed45 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Content.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Content.php @@ -205,12 +205,16 @@ private function _writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Work case PHPExcel_Cell_DataType::TYPE_FORMULA: try { - $formula_value = PHPExcel_Calculation::getInstance()->calculateCellValue($cell); + $formula_value = $cell->getCalculatedValue(); } catch (Exception $e) { $formula_value = $cell->getValue(); } $objWriter->writeAttribute('table:formula', 'of:' . $cell->getValue()); - $objWriter->writeAttribute('office:value-type', 'float'); + if (is_numeric($formula_value)) { + $objWriter->writeAttribute('office:value-type', 'float'); + } else { + $objWriter->writeAttribute('office:value-type', 'string'); + } $objWriter->writeAttribute('office:value', $formula_value); $objWriter->writeElement('text:p', $formula_value); break; From 1694960cd5f6300c99b0b8b93ae93e9789c3df86 Mon Sep 17 00:00:00 2001 From: yokota Date: Wed, 9 Jul 2014 10:53:03 +0900 Subject: [PATCH 228/467] Fixed failed include PHPExcel.php --- Examples/34chartupdate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/34chartupdate.php b/Examples/34chartupdate.php index 84f8a9221..cb586a318 100644 --- a/Examples/34chartupdate.php +++ b/Examples/34chartupdate.php @@ -37,7 +37,7 @@ */ /** PHPExcel */ -include '../Classes/PHPExcel.php'; +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; if (!file_exists("33chartcreate-bar.xlsx")) { exit("Please run 33chartcreate-bar.php first." . EOL); From 4f6256e621d9d267892a8c13f6b5e478a1662f56 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Wed, 9 Jul 2014 12:18:09 +0200 Subject: [PATCH 229/467] Added PHP 5.6 and HHVM to travis.yml --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8b53bf22e..c35625b13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,12 @@ php: - 5.3 - 5.4 - 5.5 + - 5.6 + - hhvm + +matrix: + allow_failures: + - php: hhvm script: - phpunit -c ./unitTests/ From 927d1513cfe01361e745901a2759339edce57fe4 Mon Sep 17 00:00:00 2001 From: Alexander Pervakov Date: Mon, 14 Jul 2014 12:07:07 +0400 Subject: [PATCH 230/467] Fix output in ODS example --- Examples/01simple-download-ods.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Examples/01simple-download-ods.php b/Examples/01simple-download-ods.php index ddabd3ee4..574fb0113 100644 --- a/Examples/01simple-download-ods.php +++ b/Examples/01simple-download-ods.php @@ -85,6 +85,5 @@ header ('Pragma: public'); // HTTP/1.0 $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'OpenDocument'); -//$objWriter->save('php://output'); -$objWriter->save('a.ods'); +$objWriter->save('php://output'); exit; From a81a7da6616d22e566db61aa9b5ae9a737f5b6f2 Mon Sep 17 00:00:00 2001 From: Alexander Pervakov Date: Mon, 14 Jul 2014 14:51:45 +0400 Subject: [PATCH 231/467] Add cell comment --- .../Writer/OpenDocument/Cell/Comment.php | 63 +++++++++++++++++++ .../PHPExcel/Writer/OpenDocument/Content.php | 1 + 2 files changed, 64 insertions(+) create mode 100644 Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php diff --git a/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php b/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php new file mode 100644 index 000000000..88406ed1a --- /dev/null +++ b/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php @@ -0,0 +1,63 @@ + + */ +class PHPExcel_Writer_OpenDocument_Cell_Comment +{ + public static function write(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Cell $cell) + { + $comments = $cell->getWorksheet()->getComments(); + if (!isset($comments[$cell->getCoordinate()])) { + return; + } + $comment = $comments[$cell->getCoordinate()]; + + $objWriter->startElement('office:annotation'); + //$objWriter->writeAttribute('draw:style-name', 'gr1'); + //$objWriter->writeAttribute('draw:text-style-name', 'P1'); + $objWriter->writeAttribute('svg:width', $comment->getWidth()); + $objWriter->writeAttribute('svg:height', $comment->getHeight()); + $objWriter->writeAttribute('svg:x', $comment->getMarginLeft()); + $objWriter->writeAttribute('svg:y', $comment->getMarginTop()); + //$objWriter->writeAttribute('draw:caption-point-x', $comment->getMarginLeft()); + //$objWriter->writeAttribute('draw:caption-point-y', $comment->getMarginTop()); + $objWriter->writeElement('dc:creator', $comment->getAuthor()); + // TODO: Not realized in PHPExcel_Comment yet. + //$objWriter->writeElement('dc:date', $comment->getDate()); + $objWriter->writeElement('text:p', $comment->getText()->getPlainText()); + //$objWriter->writeAttribute('draw:text-style-name', 'P1'); + $objWriter->endElement(); + } +} diff --git a/Classes/PHPExcel/Writer/OpenDocument/Content.php b/Classes/PHPExcel/Writer/OpenDocument/Content.php index 932f2cae2..8666f222e 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Content.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Content.php @@ -230,6 +230,7 @@ private function _writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Work $objWriter->writeElement('text:p', $cell->getValue()); break; } + PHPExcel_Writer_OpenDocument_Cell_Comment::write($objWriter, $cell); $objWriter->endElement(); $prev_column = $column; $cells->next(); From 524c0938957950ea05563a677bc43adc0d8644e3 Mon Sep 17 00:00:00 2001 From: Alexander Pervakov Date: Mon, 14 Jul 2014 14:55:57 +0400 Subject: [PATCH 232/467] Fix reader when comment within text:p element --- Classes/PHPExcel/Reader/OOCalc.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index ce30fc25d..4ffed2b3b 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -515,9 +515,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $annotationText = $cellDataOffice->annotation->children($namespacesContent['text']); $textArray = array(); foreach($annotationText as $t) { - foreach($t->span as $text) { - $textArray[] = (string)$text; - } + if (isset($t->span)) { + foreach($t->span as $text) { + $textArray[] = (string)$text; + } + } else { + $textArray[] = (string) $t; + } } $text = implode("\n",$textArray); // echo $text,'
'; From 568038c5bf54398466d25133e17f9d4b391805fd Mon Sep 17 00:00:00 2001 From: Wiktor Date: Mon, 14 Jul 2014 16:59:53 +0200 Subject: [PATCH 233/467] --Added 3 new classes: PHPExcel_Chart_Axis, PHPExcel_Chart_GridLines, PHPExcel_Chart_Properties.php --Modified Chart.php and Writer/Excel2007/Chart.php for using new classes --Now it is possible to set some (most of existing) options of Axis, Major Grid-lines and Minor Grid-lines --No need to use that feature --- Classes/PHPExcel/Chart.php | 86 +- Classes/PHPExcel/Chart/Axis.php | 584 ++++ Classes/PHPExcel/Chart/GridLines.php | 458 ++++ Classes/PHPExcel/Chart/Properties.php | 359 +++ Classes/PHPExcel/Writer/Excel2007/Chart.php | 2737 +++++++++++-------- 5 files changed, 3056 insertions(+), 1168 deletions(-) create mode 100644 Classes/PHPExcel/Chart/Axis.php create mode 100644 Classes/PHPExcel/Chart/GridLines.php create mode 100644 Classes/PHPExcel/Chart/Properties.php diff --git a/Classes/PHPExcel/Chart.php b/Classes/PHPExcel/Chart.php index 2f3f19d22..b9146b34b 100644 --- a/Classes/PHPExcel/Chart.php +++ b/Classes/PHPExcel/Chart.php @@ -98,6 +98,33 @@ class PHPExcel_Chart */ private $_displayBlanksAs = '0'; + /** + * Chart Asix Y as + * + * @var PHPExcel_Chart_Axis + */ + private $_yAxis = null; + + /** + * Chart Asix X as + * + * @var PHPExcel_Chart_Axis + */ + private $_xAxis = null; + + /** + * Chart Major Gridlines as + * + * @var PHPExcel_Chart_Gridlines + */ + private $_majorGridlines = null; + + /** + * Chart Minor Gridlines as + * + * @var PHPExcel_Chart_Gridlines + */ + private $_minorGridlines = null; /** * Top-Left Cell Position @@ -150,7 +177,7 @@ class PHPExcel_Chart /** * Create a new PHPExcel_Chart */ - public function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_Chart_Legend $legend = null, PHPExcel_Chart_PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = '0', PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null) + public function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_Chart_Legend $legend = null, PHPExcel_Chart_PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = '0', PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, PHPExcel_Chart_Axis $xAxis = null, PHPExcel_Chart_Axis $yAxis = null, PHPExcel_Chart_Gridlines $majorGridlines = null, PHPExcel_Chart_Gridlines $minorGridlines = null) { $this->_name = $name; $this->_title = $title; @@ -160,6 +187,10 @@ public function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_ $this->_plotArea = $plotArea; $this->_plotVisibleOnly = $plotVisibleOnly; $this->_displayBlanksAs = $displayBlanksAs; + $this->_xAxis = $xAxis; + $this->_yAxis = $yAxis; + $this->_majorGridlines = $majorGridlines; + $this->_minorGridlines = $minorGridlines; } /** @@ -327,6 +358,59 @@ public function setDisplayBlanksAs($displayBlanksAs = '0') { } + /** + * Get yAxis + * + * @return PHPExcel_Chart_Axis + */ + public function getChartAxisY() { + if($this->_yAxis !== NULL){ + return $this->_yAxis; + } + + return new PHPExcel_Chart_Axis(); + } + + /** + * Get xAxis + * + * @return PHPExcel_Chart_Axis + */ + public function getChartAxisX() { + if($this->_xAxis !== NULL){ + return $this->_xAxis; + } + + return new PHPExcel_Chart_Axis(); + } + + /** + * Get Major Gridlines + * + * @return PHPExcel_Chart_Gridlines + */ + public function getMajorGridlines() { + if($this->_majorGridlines !== NULL){ + return $this->_majorGridlines; + } + + return new PHPExcel_Chart_Gridlines(); + } + + /** + * Get Minor Gridlines + * + * @return PHPExcel_Chart_Gridlines + */ + public function getMinorGridlines() { + if($this->_minorGridlines !== NULL){ + return $this->_minorGridlines; + } + + return new PHPExcel_Chart_Gridlines(); + } + + /** * Set the Top Left position for the chart * diff --git a/Classes/PHPExcel/Chart/Axis.php b/Classes/PHPExcel/Chart/Axis.php new file mode 100644 index 000000000..efb39e9f4 --- /dev/null +++ b/Classes/PHPExcel/Chart/Axis.php @@ -0,0 +1,584 @@ + self::FORMAT_CODE_GENERAL, + 'source_linked' => 1 + ); + + /** + * Axis Options + * + * @var array of mixed + */ + + private $_axis_options = array( + 'minimum' => NULL, + 'maximum' => NULL, + 'major_unit' => NULL, + 'minor_unit' => NULL, + 'orientation' => self::ORIENTATION_NORMAL, + 'minor_tick_mark' => self::TICK_MARK_NONE, + 'major_tick_mark' => self::TICK_MARK_NONE, + 'axis_labels' => self::AXIS_LABELS_NEXT_TO, + 'horizontal_crosses' => self::HORIZONTAL_CROSSES_AUTOZERO, + 'horizontal_crosses_value' => NULL + ); + + /** + * Fill Properties + * + * @var array of mixed + */ + + private $_fill_properties = array( + 'type' => self::EXCEL_COLOR_TYPE_ARGB, + 'value' => NULL, + 'alpha' => 0 + ); + + /** + * Line Properties + * + * @var array of mixed + */ + + private $_line_properties = array( + 'type' => self::EXCEL_COLOR_TYPE_ARGB, + 'value' => NULL, + 'alpha' => 0 + ); + + /** + * Line Style Properties + * + * @var array of mixed + */ + + private $_line_style_properties = array( + 'width' => '9525', + 'compound' => self::LINE_STYLE_COMPOUND_SIMPLE, + 'dash' => self::LINE_STYLE_DASH_SOLID, + 'cap' => self::LINE_STYLE_CAP_FLAT, + 'join' => self::LINE_STYLE_JOIN_BEVEL, + 'arrow' => array( + 'head' => array( + 'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, + 'size' => self::LINE_STYLE_ARROW_SIZE_5 + ), + 'end' => array( + 'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, + 'size' => self::LINE_STYLE_ARROW_SIZE_8 + ), + ) + ); + + /** + * Shadow Properties + * + * @var array of mixed + */ + + private $_shadow_properties = array( + 'presets' => self::SHADOW_PRESETS_NOSHADOW, + 'effect' => NULL, + 'color' => array( + 'type' => self::EXCEL_COLOR_TYPE_STANDARD, + 'value' => 'black', + 'alpha' => 40, + ), + 'size' => array( + 'sx' => NULL, + 'sy' => NULL, + 'kx' => NULL + ), + 'blur' => NULL, + 'direction' => NULL, + 'distance' => NULL, + 'algn' => NULL, + 'rotWithShape' => NULL + ); + + /** + * Glow Properties + * + * @var array of mixed + */ + + private $_glow_properties = array( + 'size' => NULL, + 'color' => array( + 'type' => self::EXCEL_COLOR_TYPE_STANDARD, + 'value' => 'black', + 'alpha' => 40 + ) + ); + + /** + * Soft Edge Properties + * + * @var array of mixed + */ + + private $_soft_edges = array( + 'size' => NULL + ); + + /** + * Get Series Data Type + * + * @return string + */ + + public function setAxisNumberProperties($format_code) { + $this->_axis_number['format'] = (string) $format_code; + $this->_axis_number['source_linked'] = 0; + } + + /** + * Get Axis Number Format Data Type + * + * @return string + */ + + public function getAxisNumberFormat() { + return $this->_axis_number['format']; + } + + /** + * Get Axis Number Source Linked + * + * @return string + */ + + public function getAxisNumberSourceLinked() { + return (string) $this->_axis_number['source_linked']; + } + + /** + * Set Axis Options Properties + * + * @param string $axis_labels + * @param string $horizontal_crosses_value + * @param string $horizontal_crosses + * @param string $axis_orientation + * @param string $major_tmt + * @param string $minor_tmt + * @param string $minimum + * @param string $maximum + * @param string $major_unit + * @param string $minor_unit + * + */ + + public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = NULL, $horizontal_crosses = NULL, + $axis_orientation = NULL, $major_tmt = NULL, $minor_tmt = NULL, $minimum = NULL, $maximum = NULL, $major_unit = NULL, + $minor_unit = NULL) { + + $this->_axis_options['axis_labels'] = (string) $axis_labels; + ($horizontal_crosses_value !== NULL) + ? $this->_axis_options['horizontal_crosses_value'] = (string) $horizontal_crosses_value : NULL; + ($horizontal_crosses !== NULL) ? $this->_axis_options['horizontal_crosses'] = (string) $horizontal_crosses : NULL; + ($axis_orientation !== NULL) ? $this->_axis_options['orientation'] = (string) $axis_orientation : NULL; + ($major_tmt !== NULL) ? $this->_axis_options['major_tick_mark'] = (string) $major_tmt : NULL; + ($minor_tmt !== NULL) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : NULL; + ($minor_tmt !== NULL) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : NULL; + ($minimum !== NULL) ? $this->_axis_options['minimum'] = (string) $minimum : NULL; + ($maximum !== NULL) ? $this->_axis_options['maximum'] = (string) $maximum : NULL; + ($major_unit !== NULL) ? $this->_axis_options['major_unit'] = (string) $major_unit : NULL; + ($minor_unit !== NULL) ? $this->_axis_options['minor_unit'] = (string) $minor_unit : NULL; + } + + /** + * Get Axis Options Property + * + * @param string $property + * + * @return string + */ + + public function getAxisOptionsProperty($property) { + return $this->_axis_options[$property]; + } + + /** + * Set Axis Orientation Property + * + * @param string $orientation + * + */ + + public function setAxisOrientation($orientation) { + $this->orientation = (string) $orientation; + } + + /** + * Set Fill Property + * + * @param string $color + * @param int $alpha + * @param string $type + * + */ + + public function setFillParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) { + $this->_fill_properties = $this->setColorProperties($color, $alpha, $type); + } + + /** + * Set Line Property + * + * @param string $color + * @param int $alpha + * @param string $type + * + */ + + public function setLineParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) { + $this->_line_properties = $this->setColorProperties($color, $alpha, $type); + } + + /** + * Get Fill Property + * + * @param string $property + * + * @return string + */ + + public function getFillProperty($property) { + return $this->_fill_properties[$property]; + } + + /** + * Get Line Property + * + * @param string $property + * + * @return string + */ + + public function getLineProperty($property) { + return $this->_line_properties[$property]; + } + + /** + * Set Line Style Properties + * + * @param float $line_width + * @param string $compound_type + * @param string $dash_type + * @param string $cap_type + * @param string $join_type + * @param string $head_arrow_type + * @param string $head_arrow_size + * @param string $end_arrow_type + * @param string $end_arrow_size + * + */ + + public function setLineStyleProperties($line_width = NULL, $compound_type = NULL, + $dash_type = NULL, $cap_type = NULL, $join_type = NULL, $head_arrow_type = NULL, + $head_arrow_size = NULL, $end_arrow_type = NULL, $end_arrow_size = NULL) { + + (!is_null($line_width)) ? $this->_line_style_properties['width'] = $this->getExcelPointsWidth((float) $line_width) + : NULL; + (!is_null($compound_type)) ? $this->_line_style_properties['compound'] = (string) $compound_type : NULL; + (!is_null($dash_type)) ? $this->_line_style_properties['dash'] = (string) $dash_type : NULL; + (!is_null($cap_type)) ? $this->_line_style_properties['cap'] = (string) $cap_type : NULL; + (!is_null($join_type)) ? $this->_line_style_properties['join'] = (string) $join_type : NULL; + (!is_null($head_arrow_type)) ? $this->_line_style_properties['arrow']['head']['type'] = (string) $head_arrow_type + : NULL; + (!is_null($head_arrow_size)) ? $this->_line_style_properties['arrow']['head']['size'] = (string) $head_arrow_size + : NULL; + (!is_null($end_arrow_type)) ? $this->_line_style_properties['arrow']['end']['type'] = (string) $end_arrow_type + : NULL; + (!is_null($end_arrow_size)) ? $this->_line_style_properties['arrow']['end']['size'] = (string) $end_arrow_size + : NULL; + } + + /** + * Get Line Style Property + * + * @param array|string $elements + * + * @return string + */ + + public function getLineStyleProperty($elements) { + return $this->getArrayElementsValue($this->_line_style_properties, $elements); + } + + /** + * Get Line Style Arrow Excel Width + * + * @param string $arrow + * + * @return string + */ + + public function getLineStyleArrowWidth($arrow) { + return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'w'); + } + + /** + * Get Line Style Arrow Excel Length + * + * @param string $arrow + * + * @return string + */ + + public function getLineStyleArrowLength($arrow) { + return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'len'); + } + + /** + * Set Shadow Properties + * + * @param int $shadow_presets + * @param string $sh_color_value + * @param string $sh_color_type + * @param string $sh_color_alpha + * @param float $sh_blur + * @param int $sh_angle + * @param float $sh_distance + * + */ + + public function setShadowProperties($sh_presets, $sh_color_value = NULL, $sh_color_type = NULL, $sh_color_alpha = NULL, $sh_blur = NULL, $sh_angle = NULL, $sh_distance = NULL) { + $this + ->_setShadowPresetsProperties((int) $sh_presets) + ->_setShadowColor( + is_null($sh_color_value) ? $this->_shadow_properties['color']['value'] : $sh_color_value + , is_null($sh_color_alpha) ? (int) $this->_shadow_properties['color']['alpha'] : $sh_color_alpha + , is_null($sh_color_type) ? $this->_shadow_properties['color']['type'] : $sh_color_type) + ->_setShadowBlur($sh_blur) + ->_setShadowAngle($sh_angle) + ->_setShadowDistance($sh_distance); + } + + /** + * Set Shadow Color + * + * @param int $shadow_presets + * + * @return PHPExcel_Chart_Axis + */ + + private function _setShadowPresetsProperties($shadow_presets) { + $this->_shadow_properties['presets'] = $shadow_presets; + $this->_setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); + + return $this; + } + + /** + * Set Shadow Properties from Maped Values + * + * @param array $properties_map + * @param * $reference + * + * @return PHPExcel_Chart_Axis + */ + + private function _setShadowProperiesMapValues(array $properties_map, &$reference = NULL) { + $base_reference = $reference; + foreach ($properties_map as $property_key => $property_val) { + if (is_array($property_val)) { + if ($reference === NULL) { + $reference = & $this->_shadow_properties[$property_key]; + } else { + $reference = & $reference[$property_key]; + } + $this->_setShadowProperiesMapValues($property_val, $reference); + } else { + if ($base_reference === NULL) { + $this->_shadow_properties[$property_key] = $property_val; + } else { + $reference[$property_key] = $property_val; + } + } + } + + return $this; + } + + /** + * Set Shadow Color + * + * @param string $color + * @param int $alpha + * @param string $type + * + * @return PHPExcel_Chart_Axis + */ + + private function _setShadowColor($color, $alpha, $type) { + $this->_shadow_properties['color'] = $this->setColorProperties($color, $alpha, $type); + + return $this; + } + + /** + * Set Shadow Blur + * + * @param float $blur + * + * @return PHPExcel_Chart_Axis + */ + + private function _setShadowBlur($blur) { + if ($blur !== NULL) { + $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur); + } + + return $this; + } + + /** + * Set Shadow Angle + * + * @param int $angle + * + * @return PHPExcel_Chart_Axis + */ + + private function _setShadowAngle($angle) { + if ($angle !== NULL) { + $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle); + } + + return $this; + } + + /** + * Set Shadow Distance + * + * @param float $distance + * + * @return PHPExcel_Chart_Axis + */ + + private function _setShadowDistance($distance) { + if ($distance !== NULL) { + $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance); + } + + return $this; + } + + /** + * Get Glow Property + * + * @param float $size + * @param string $color_value + * @param int $color_alpha + * @param string $color_type + */ + + public function getShadowProperty($elements) { + return $this->getArrayElementsValue($this->_shadow_properties, $elements); + } + + /** + * Set Glow Properties + * + * @param float $size + * @param string $color_value + * @param int $color_alpha + * @param string $color_type + */ + + public function setGlowProperties($size, $color_value = NULL, $color_alpha = NULL, $color_type = NULL) { + $this + ->_setGlowSize($size) + ->_setGlowColor( + is_null($color_value) ? $this->_glow_properties['color']['value'] : $color_value + , is_null($color_alpha) ? (int) $this->_glow_properties['color']['alpha'] : $color_alpha + , is_null($color_type) ? $this->_glow_properties['color']['type'] : $color_type); + } + + /** + * Get Glow Property + * + * @param array|string $property + * + * @return string + */ + + public function getGlowProperty($property) { + return $this->getArrayElementsValue($this->_glow_properties, $property); + } + + /** + * Set Glow Color + * + * @param float $size + * + * @return PHPExcel_Chart_Axis + */ + + private function _setGlowSize($size) { + if (!is_null($size)) { + $this->_glow_properties['size'] = $this->getExcelPointsWidth($size); + } + + return $this; + } + + /** + * Set Glow Color + * + * @param string $color + * @param int $alpha + * @param string $type + * + * @return PHPExcel_Chart_Axis + */ + + private function _setGlowColor($color, $alpha, $type) { + $this->_glow_properties['color'] = $this->setColorProperties($color, $alpha, $type); + + return $this; + } + + /** + * Set Soft Edges Size + * + * @param float $size + */ + + public function setSoftEdges($size) { + if (!is_null($size)) { + $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size); + } + } + + /** + * Get Soft Edges Size + * + * @return string + */ + + public function getSoftEdgesSize() { + return $this->_soft_edges['size']; + } +} \ No newline at end of file diff --git a/Classes/PHPExcel/Chart/GridLines.php b/Classes/PHPExcel/Chart/GridLines.php new file mode 100644 index 000000000..7467ea7ea --- /dev/null +++ b/Classes/PHPExcel/Chart/GridLines.php @@ -0,0 +1,458 @@ + array( + 'type' => self::EXCEL_COLOR_TYPE_STANDARD, + 'value' => NULL, + 'alpha' => 0 + ), + 'style' => array( + 'width' => '9525', + 'compound' => self::LINE_STYLE_COMPOUND_SIMPLE, + 'dash' => self::LINE_STYLE_DASH_SOLID, + 'cap' => self::LINE_STYLE_CAP_FLAT, + 'join' => self::LINE_STYLE_JOIN_BEVEL, + 'arrow' => array( + 'head' => array( + 'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, + 'size' => self::LINE_STYLE_ARROW_SIZE_5 + ), + 'end' => array( + 'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, + 'size' => self::LINE_STYLE_ARROW_SIZE_8 + ), + ) + ) + ), + $_shadow_properties = array( + 'presets' => self::SHADOW_PRESETS_NOSHADOW, + 'effect' => NULL, + 'color' => array( + 'type' => self::EXCEL_COLOR_TYPE_STANDARD, + 'value' => 'black', + 'alpha' => 85, + ), + 'size' => array( + 'sx' => NULL, + 'sy' => NULL, + 'kx' => NULL + ), + 'blur' => NULL, + 'direction' => NULL, + 'distance' => NULL, + 'algn' => NULL, + 'rotWithShape' => NULL + ), + $_glow_properties = array( + 'size' => NULL, + 'color' => array( + 'type' => self::EXCEL_COLOR_TYPE_STANDARD, + 'value' => 'black', + 'alpha' => 40 + ) + ), + $_soft_edges = array( + 'size' => NULL + ); + + /** + * Get Object State + * + * @return bool + */ + + public function getObjectState() { + return $this->_object_state; + } + + /** + * Change Object State to True + * + * @return PHPExcel_Chart_Gridlines + */ + + private function _activateObject() { + $this->_object_state = TRUE; + + return $this; + } + + /** + * Set Line Color Properties + * + * @param string $value + * @param int $alpha + * @param string $type + */ + + public function setLineColorProperties($value, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_STANDARD) { + $this + ->_activateObject() + ->_line_properties['color'] = $this->setColorProperties( + $value, + $alpha, + $type); + } + + /** + * Set Line Color Properties + * + * @param float $line_width + * @param string $compound_type + * @param string $dash_type + * @param string $cap_type + * @param string $join_type + * @param string $head_arrow_type + * @param string $head_arrow_size + * @param string $end_arrow_type + * @param string $end_arrow_size + */ + + public function setLineStyleProperties($line_width = NULL, $compound_type = NULL, $dash_type = NULL, $cap_type = NULL, $join_type = NULL, $head_arrow_type = NULL, $head_arrow_size = NULL, $end_arrow_type = NULL, $end_arrow_size = NULL) { + $this->_activateObject(); + (!is_null($line_width)) + ? $this->_line_properties['style']['width'] = $this->getExcelPointsWidth((float) $line_width) + : NULL; + (!is_null($compound_type)) + ? $this->_line_properties['style']['compound'] = (string) $compound_type + : NULL; + (!is_null($dash_type)) + ? $this->_line_properties['style']['dash'] = (string) $dash_type + : NULL; + (!is_null($cap_type)) + ? $this->_line_properties['style']['cap'] = (string) $cap_type + : NULL; + (!is_null($join_type)) + ? $this->_line_properties['style']['join'] = (string) $join_type + : NULL; + (!is_null($head_arrow_type)) + ? $this->_line_properties['style']['arrow']['head']['type'] = (string) $head_arrow_type + : NULL; + (!is_null($head_arrow_size)) + ? $this->_line_properties['style']['arrow']['head']['size'] = (string) $head_arrow_size + : NULL; + (!is_null($end_arrow_type)) + ? $this->_line_properties['style']['arrow']['end']['type'] = (string) $end_arrow_type + : NULL; + (!is_null($end_arrow_size)) + ? $this->_line_properties['style']['arrow']['end']['size'] = (string) $end_arrow_size + : NULL; + } + + /** + * Get Line Color Property + * + * @param string $parameter + * + * @return string + */ + + public function getLineColorProperty($parameter) { + return $this->_line_properties['color'][$parameter]; + } + + /** + * Get Line Style Property + * + * @param array|string $elements + * + * @return string + */ + + public function getLineStyleProperty($elements) { + return $this->getArrayElementsValue($this->_line_properties['style'], $elements); + } + + /** + * Set Glow Properties + * + * @param float $size + * @param string $color_value + * @param int $color_alpha + * @param string $color_type + * + */ + + public function setGlowProperties($size, $color_value = NULL, $color_alpha = NULL, $color_type = NULL) { + $this + ->_activateObject() + ->_setGlowSize($size) + ->_setGlowColor($color_value, $color_alpha, $color_type); + } + + /** + * Get Glow Color Property + * + * @param string $property + * + * @return string + */ + + public function getGlowColor($property) { + return $this->_glow_properties['color'][$property]; + } + + /** + * Get Glow Size + * + * @return string + */ + + public function getGlowSize() { + return $this->_glow_properties['size']; + } + + /** + * Set Glow Size + * + * @param float $size + * + * @return PHPExcel_Chart_Gridlines + */ + + private function _setGlowSize($size) { + $this->_glow_properties['size'] = $this->getExcelPointsWidth((float) $size); + + return $this; + } + + /** + * Set Glow Color + * + * @param string $color + * @param int $alpha + * @param string $type + * + * @return PHPExcel_Chart_Gridlines + */ + + private function _setGlowColor($color, $alpha, $type) { + if (!is_null($color)) { + $this->_glow_properties['color']['value'] = (string) $color; + } + if (!is_null($alpha)) { + $this->_glow_properties['color']['alpha'] = $this->getTrueAlpha((int) $alpha); + } + if (!is_null($type)) { + $this->_glow_properties['color']['type'] = (string) $type; + } + + return $this; + } + + /** + * Get Line Style Arrow Parameters + * + * @param string $arrow_selector + * @param string $property_selector + * + * @return string + */ + + public function getLineStyleArrowParameters($arrow_selector, $property_selector) { + return $this->getLineStyleArrowSize($this->_line_properties['style']['arrow'][$arrow_selector]['size'], $property_selector); + } + + /** + * Set Shadow Properties + * + * @param int $sh_presets + * @param string $sh_color_value + * @param string $sh_color_type + * @param int $sh_color_alpha + * @param string $sh_blur + * @param int $sh_angle + * @param float $sh_distance + * + */ + + public function setShadowProperties($sh_presets, $sh_color_value = NULL, $sh_color_type = NULL, $sh_color_alpha = NULL, $sh_blur = NULL, $sh_angle = NULL, $sh_distance = NULL) { + $this + ->_activateObject() + ->_setShadowPresetsProperties((int) $sh_presets) + ->_setShadowColor( + is_null($sh_color_value) ? $this->_shadow_properties['color']['value'] : $sh_color_value + , is_null($sh_color_alpha) ? (int) $this->_shadow_properties['color']['alpha'] + : $this->getTrueAlpha($sh_color_alpha) + , is_null($sh_color_type) ? $this->_shadow_properties['color']['type'] : $sh_color_type) + ->_setShadowBlur($sh_blur) + ->_setShadowAngle($sh_angle) + ->_setShadowDistance($sh_distance); + } + + /** + * Set Shadow Presets Properties + * + * @param int $shadow_presets + * + * @return PHPExcel_Chart_Gridlines + */ + + private function _setShadowPresetsProperties($shadow_presets) { + $this->_shadow_properties['presets'] = $shadow_presets; + $this->_setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); + + return $this; + } + + /** + * Set Shadow Properties Values + * + * @param array $properties_map + * @param * $reference + * + * @return PHPExcel_Chart_Gridlines + */ + + private function _setShadowProperiesMapValues(array $properties_map, &$reference = NULL) { + $base_reference = $reference; + foreach ($properties_map as $property_key => $property_val) { + if (is_array($property_val)) { + if ($reference === NULL) { + $reference = & $this->_shadow_properties[$property_key]; + } else { + $reference = & $reference[$property_key]; + } + $this->_setShadowProperiesMapValues($property_val, $reference); + } else { + if ($base_reference === NULL) { + $this->_shadow_properties[$property_key] = $property_val; + } else { + $reference[$property_key] = $property_val; + } + } + } + + return $this; + } + + /** + * Set Shadow Color + * + * @param string $color + * @param int $alpha + * @param string $type + * + * @return PHPExcel_Chart_Gridlines + */ + + private function _setShadowColor($color, $alpha, $type) { + if (!is_null($color)) { + $this->_shadow_properties['color']['value'] = (string) $color; + } + if (!is_null($alpha)) { + $this->_shadow_properties['color']['alpha'] = $this->getTrueAlpha((int) $alpha); + } + if (!is_null($type)) { + $this->_shadow_properties['color']['type'] = (string) $type; + } + + return $this; + } + + /** + * Set Shadow Blur + * + * @param float $blur + * + * @return PHPExcel_Chart_Gridlines + */ + + private function _setShadowBlur($blur) { + if ($blur !== NULL) { + $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur); + } + + return $this; + } + + /** + * Set Shadow Angle + * + * @param int $angle + * + * @return PHPExcel_Chart_Gridlines + */ + + private function _setShadowAngle($angle) { + if ($angle !== NULL) { + $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle); + } + + return $this; + } + + /** + * Set Shadow Distance + * + * @param float $distance + * + * @return PHPExcel_Chart_Gridlines + */ + + private function _setShadowDistance($distance) { + if ($distance !== NULL) { + $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance); + } + + return $this; + } + + /** + * Get Shadow Property + * + * @param string $elements + * @param array $elements + * + * @return string + */ + + public function getShadowProperty($elements) { + return $this->getArrayElementsValue($this->_shadow_properties, $elements); + } + + /** + * Set Soft Edges Size + * + * @param float $size + */ + + public function setSoftEdgesSize($size) { + if (!is_null($size)) { + $this->_activateObject(); + $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size); + } + } + + /** + * Get Soft Edges Size + * + * @return string + */ + + public function getSoftEdgesSize() { + return $this->_soft_edges['size']; + } +} \ No newline at end of file diff --git a/Classes/PHPExcel/Chart/Properties.php b/Classes/PHPExcel/Chart/Properties.php new file mode 100644 index 000000000..7593983c0 --- /dev/null +++ b/Classes/PHPExcel/Chart/Properties.php @@ -0,0 +1,359 @@ + (string) $type, + 'value' => (string) $color, + 'alpha' => (string) $this->getTrueAlpha($alpha) + ); + } + + protected function getLineStyleArrowSize($array_selector, $array_kay_selector) { + $sizes = array( + 1 => array('w' => 'sm', 'len' => 'sm'), + 2 => array('w' => 'sm', 'len' => 'med'), + 3 => array('w' => 'sm', 'len' => 'lg'), + 4 => array('w' => 'med', 'len' => 'sm'), + 5 => array('w' => 'med', 'len' => 'med'), + 6 => array('w' => 'med', 'len' => 'lg'), + 7 => array('w' => 'lg', 'len' => 'sm'), + 8 => array('w' => 'lg', 'len' => 'med'), + 9 => array('w' => 'lg', 'len' => 'lg') + ); + + return $sizes[$array_selector][$array_kay_selector]; + } + + protected function getShadowPresetsMap($shadow_presets_option) { + $presets_options = array( + //OUTER + 1 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '2700000', + 'algn' => 'tl', + 'rotWithShape' => '0' + ), + 2 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '5400000', + 'algn' => 't', + 'rotWithShape' => '0' + ), + 3 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '8100000', + 'algn' => 'tr', + 'rotWithShape' => '0' + ), + 4 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'algn' => 'l', + 'rotWithShape' => '0' + ), + 5 => array( + 'effect' => 'outerShdw', + 'size' => array( + 'sx' => '102000', + 'sy' => '102000' + ) + , + 'blur' => '63500', + 'distance' => '38100', + 'algn' => 'ctr', + 'rotWithShape' => '0' + ), + 6 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '10800000', + 'algn' => 'r', + 'rotWithShape' => '0' + ), + 7 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '18900000', + 'algn' => 'bl', + 'rotWithShape' => '0' + ), + 8 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '16200000', + 'rotWithShape' => '0' + ), + 9 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '13500000', + 'algn' => 'br', + 'rotWithShape' => '0' + ), + //INNER + 10 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '2700000', + ), + 11 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '5400000', + ), + 12 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '8100000', + ), + 13 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + ), + 14 => array( + 'effect' => 'innerShdw', + 'blur' => '114300', + ), + 15 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '10800000', + ), + 16 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '18900000', + ), + 17 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '16200000', + ), + 18 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '13500000', + ), + //perspective + 19 => array( + 'effect' => 'outerShdw', + 'blur' => '152400', + 'distance' => '317500', + 'size' => array( + 'sx' => '90000', + 'sy' => '-19000', + ), + 'direction' => '5400000', + 'rotWithShape' => '0', + ), + 20 => array( + 'effect' => 'outerShdw', + 'blur' => '76200', + 'direction' => '18900000', + 'size' => array( + 'sy' => '23000', + 'kx' => '-1200000', + ), + 'algn' => 'bl', + 'rotWithShape' => '0', + ), + 21 => array( + 'effect' => 'outerShdw', + 'blur' => '76200', + 'direction' => '13500000', + 'size' => array( + 'sy' => '23000', + 'kx' => '1200000', + ), + 'algn' => 'br', + 'rotWithShape' => '0', + ), + 22 => array( + 'effect' => 'outerShdw', + 'blur' => '76200', + 'distance' => '12700', + 'direction' => '2700000', + 'size' => array( + 'sy' => '-23000', + 'kx' => '-800400', + ), + 'algn' => 'bl', + 'rotWithShape' => '0', + ), + 23 => array( + 'effect' => 'outerShdw', + 'blur' => '76200', + 'distance' => '12700', + 'direction' => '8100000', + 'size' => array( + 'sy' => '-23000', + 'kx' => '800400', + ), + 'algn' => 'br', + 'rotWithShape' => '0', + ), + ); + + return $presets_options[$shadow_presets_option]; + } + + protected function getArrayElementsValue($properties, $elements) { + $reference = & $properties; + if (!is_array($elements)) { + return $reference[$elements]; + } else { + foreach ($elements as $keys) { + $reference = & $reference[$keys]; + } + + return $reference; + } + + return $this; + } + +} \ No newline at end of file diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 0b686b912..d863734cf 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -25,7 +25,6 @@ * @version ##VERSION##, ##DATE## */ - /** * PHPExcel_Writer_Excel2007_Chart * @@ -33,1171 +32,1575 @@ * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ -class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPart -{ - /** - * Write charts to XML format - * - * @param PHPExcel_Chart $pChart - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeChart(PHPExcel_Chart $pChart = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - // Ensure that data series values are up-to-date before we save - $pChart->refresh(); - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // c:chartSpace - $objWriter->startElement('c:chartSpace'); - $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); - $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); - $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - - $objWriter->startElement('c:date1904'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - $objWriter->startElement('c:lang'); - $objWriter->writeAttribute('val', "en-GB"); - $objWriter->endElement(); - $objWriter->startElement('c:roundedCorners'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $this->_writeAlternateContent($objWriter); - - $objWriter->startElement('c:chart'); - - $this->_writeTitle($pChart->getTitle(), $objWriter); - - $objWriter->startElement('c:autoTitleDeleted'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $this->_writePlotArea($pChart->getPlotArea(), - $pChart->getXAxisLabel(), - $pChart->getYAxisLabel(), - $objWriter, - $pChart->getWorksheet() - ); - - $this->_writeLegend($pChart->getLegend(), $objWriter); - - - $objWriter->startElement('c:plotVisOnly'); - $objWriter->writeAttribute('val', 1); - $objWriter->endElement(); - - $objWriter->startElement('c:dispBlanksAs'); - $objWriter->writeAttribute('val', "gap"); - $objWriter->endElement(); - - $objWriter->startElement('c:showDLblsOverMax'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $objWriter->endElement(); - - $this->_writePrintSettings($objWriter); - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write Chart Title - * - * @param PHPExcel_Chart_Title $title - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @throws PHPExcel_Writer_Exception - */ - private function _writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) - { - if (is_null($title)) { - return; - } - - $objWriter->startElement('c:title'); - $objWriter->startElement('c:tx'); - $objWriter->startElement('c:rich'); - - $objWriter->startElement('a:bodyPr'); - $objWriter->endElement(); - - $objWriter->startElement('a:lstStyle'); - $objWriter->endElement(); - - $objWriter->startElement('a:p'); - - $caption = $title->getCaption(); - if ((is_array($caption)) && (count($caption) > 0)) - $caption = $caption[0]; - $this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a'); - - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - - $layout = $title->getLayout(); - $this->_writeLayout($layout, $objWriter); - - $objWriter->startElement('c:overlay'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write Chart Legend - * - * @param PHPExcel_Chart_Legend $legend - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @throws PHPExcel_Writer_Exception - */ - private function _writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) - { - if (is_null($legend)) { - return; - } - - $objWriter->startElement('c:legend'); - - $objWriter->startElement('c:legendPos'); - $objWriter->writeAttribute('val', $legend->getPosition()); - $objWriter->endElement(); - - $layout = $legend->getLayout(); - $this->_writeLayout($layout, $objWriter); - - $objWriter->startElement('c:overlay'); - $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0'); - $objWriter->endElement(); - - $objWriter->startElement('c:txPr'); - $objWriter->startElement('a:bodyPr'); - $objWriter->endElement(); - - $objWriter->startElement('a:lstStyle'); - $objWriter->endElement(); - - $objWriter->startElement('a:p'); - $objWriter->startElement('a:pPr'); - $objWriter->writeAttribute('rtl', 0); - - $objWriter->startElement('a:defRPr'); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('a:endParaRPr'); - $objWriter->writeAttribute('lang', "en-US"); - $objWriter->endElement(); - - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write Chart Plot Area - * - * @param PHPExcel_Chart_PlotArea $plotArea - * @param PHPExcel_Chart_Title $xAxisLabel - * @param PHPExcel_Chart_Title $yAxisLabel - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @throws PHPExcel_Writer_Exception - */ - private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, - PHPExcel_Chart_Title $xAxisLabel = NULL, - PHPExcel_Chart_Title $yAxisLabel = NULL, - $objWriter, - PHPExcel_Worksheet $pSheet) - { - if (is_null($plotArea)) { - return; - } - - $id1 = $id2 = 0; - $this->_seriesIndex = 0; - $objWriter->startElement('c:plotArea'); - - $layout = $plotArea->getLayout(); - - $this->_writeLayout($layout, $objWriter); - - $chartTypes = self::_getChartType($plotArea); - $catIsMultiLevelSeries = $valIsMultiLevelSeries = FALSE; - $plotGroupingType = ''; - foreach($chartTypes as $chartType) { - $objWriter->startElement('c:'.$chartType); - - $groupCount = $plotArea->getPlotGroupCount(); - for($i = 0; $i < $groupCount; ++$i) { - $plotGroup = $plotArea->getPlotGroupByIndex($i); - $groupType = $plotGroup->getPlotType(); - if ($groupType == $chartType) { - - $plotStyle = $plotGroup->getPlotStyle(); - if ($groupType === PHPExcel_Chart_DataSeries::TYPE_RADARCHART) { - $objWriter->startElement('c:radarStyle'); - $objWriter->writeAttribute('val', $plotStyle ); - $objWriter->endElement(); - } elseif ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) { - $objWriter->startElement('c:scatterStyle'); - $objWriter->writeAttribute('val', $plotStyle ); - $objWriter->endElement(); - } - - $this->_writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet); - } - } - - $this->_writeDataLbls($objWriter, $layout); - - if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) { - // Line only, Line3D can't be smoothed - - $objWriter->startElement('c:smooth'); - $objWriter->writeAttribute('val', (integer) $plotGroup->getSmoothLine() ); - $objWriter->endElement(); - } elseif (($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || - ($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) { - - $objWriter->startElement('c:gapWidth'); - $objWriter->writeAttribute('val', 150 ); - $objWriter->endElement(); - - if ($plotGroupingType == 'percentStacked' || - $plotGroupingType == 'stacked') { - - $objWriter->startElement('c:overlap'); - $objWriter->writeAttribute('val', 100 ); - $objWriter->endElement(); - } - } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - - $objWriter->startElement('c:bubbleScale'); - $objWriter->writeAttribute('val', 25 ); - $objWriter->endElement(); - - $objWriter->startElement('c:showNegBubbles'); - $objWriter->writeAttribute('val', 0 ); - $objWriter->endElement(); - } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { - - $objWriter->startElement('c:hiLowLines'); - $objWriter->endElement(); - - $objWriter->startElement( 'c:upDownBars' ); - - $objWriter->startElement( 'c:gapWidth' ); - $objWriter->writeAttribute('val', 300); - $objWriter->endElement(); - - $objWriter->startElement( 'c:upBars' ); - $objWriter->endElement(); - - $objWriter->startElement( 'c:downBars' ); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - // Generate 2 unique numbers to use for axId values -// $id1 = $id2 = rand(10000000,99999999); -// do { -// $id2 = rand(10000000,99999999); -// } while ($id1 == $id2); - $id1 = '75091328'; - $id2 = '75089408'; - - if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && - ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && - ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { - - $objWriter->startElement('c:axId'); - $objWriter->writeAttribute('val', $id1 ); - $objWriter->endElement(); - $objWriter->startElement('c:axId'); - $objWriter->writeAttribute('val', $id2 ); - $objWriter->endElement(); - } else { - $objWriter->startElement('c:firstSliceAng'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - if ($chartType === PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) { - - $objWriter->startElement('c:holeSize'); - $objWriter->writeAttribute('val', 50); - $objWriter->endElement(); - } - } - - $objWriter->endElement(); - } - - if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && - ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && - ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { - - if ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $this->_writeValAx($objWriter,$plotArea,$xAxisLabel,$chartType,$id1,$id2,$catIsMultiLevelSeries); - } else { - $this->_writeCatAx($objWriter,$plotArea,$xAxisLabel,$chartType,$id1,$id2,$catIsMultiLevelSeries); - } - - $this->_writeValAx($objWriter,$plotArea,$yAxisLabel,$chartType,$id1,$id2,$valIsMultiLevelSeries); - } - - $objWriter->endElement(); - } - - /** - * Write Data Labels - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Chart_Layout $chartLayout Chart layout - * @throws PHPExcel_Writer_Exception - */ - private function _writeDataLbls($objWriter, $chartLayout) - { - $objWriter->startElement('c:dLbls'); - - $objWriter->startElement('c:showLegendKey'); - $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey(); - $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1) ); - $objWriter->endElement(); - - - $objWriter->startElement('c:showVal'); - $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal(); - $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1) ); - $objWriter->endElement(); - - $objWriter->startElement('c:showCatName'); - $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName(); - $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1) ); - $objWriter->endElement(); - - $objWriter->startElement('c:showSerName'); - $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName(); - $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1) ); - $objWriter->endElement(); - - $objWriter->startElement('c:showPercent'); - $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent(); - $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1) ); - $objWriter->endElement(); - - $objWriter->startElement('c:showBubbleSize'); - $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize(); - $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1) ); - $objWriter->endElement(); - - $objWriter->startElement('c:showLeaderLines'); - $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines(); - $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1) ); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write Category Axis - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Chart_PlotArea $plotArea - * @param PHPExcel_Chart_Title $xAxisLabel - * @param string $groupType Chart type - * @param string $id1 - * @param string $id2 - * @param boolean $isMultiLevelSeries - * @throws PHPExcel_Writer_Exception - */ - private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries) - { - $objWriter->startElement('c:catAx'); - - if ($id1 > 0) { - $objWriter->startElement('c:axId'); - $objWriter->writeAttribute('val', $id1); - $objWriter->endElement(); - } - - $objWriter->startElement('c:scaling'); - $objWriter->startElement('c:orientation'); - $objWriter->writeAttribute('val', "minMax"); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('c:delete'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $objWriter->startElement('c:axPos'); - $objWriter->writeAttribute('val', "b"); - $objWriter->endElement(); - - if (!is_null($xAxisLabel)) { - $objWriter->startElement('c:title'); - $objWriter->startElement('c:tx'); - $objWriter->startElement('c:rich'); - - $objWriter->startElement('a:bodyPr'); - $objWriter->endElement(); - - $objWriter->startElement('a:lstStyle'); - $objWriter->endElement(); - - $objWriter->startElement('a:p'); - $objWriter->startElement('a:r'); - - $caption = $xAxisLabel->getCaption(); - if (is_array($caption)) - $caption = $caption[0]; - $objWriter->startElement('a:t'); -// $objWriter->writeAttribute('xml:space', 'preserve'); - $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $caption )); - $objWriter->endElement(); - - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - - $layout = $xAxisLabel->getLayout(); - $this->_writeLayout($layout, $objWriter); - - $objWriter->startElement('c:overlay'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $objWriter->endElement(); - - } - - $objWriter->startElement('c:numFmt'); - $objWriter->writeAttribute('formatCode', "General"); - $objWriter->writeAttribute('sourceLinked', 1); - $objWriter->endElement(); - - $objWriter->startElement('c:majorTickMark'); - $objWriter->writeAttribute('val', "out"); - $objWriter->endElement(); - - $objWriter->startElement('c:minorTickMark'); - $objWriter->writeAttribute('val', "none"); - $objWriter->endElement(); - - $objWriter->startElement('c:tickLblPos'); - $objWriter->writeAttribute('val', "nextTo"); - $objWriter->endElement(); - - if ($id2 > 0) { - $objWriter->startElement('c:crossAx'); - $objWriter->writeAttribute('val', $id2); - $objWriter->endElement(); - - $objWriter->startElement('c:crosses'); - $objWriter->writeAttribute('val', "autoZero"); - $objWriter->endElement(); - } - - $objWriter->startElement('c:auto'); - $objWriter->writeAttribute('val', 1); - $objWriter->endElement(); - - $objWriter->startElement('c:lblAlgn'); - $objWriter->writeAttribute('val', "ctr"); - $objWriter->endElement(); - - $objWriter->startElement('c:lblOffset'); - $objWriter->writeAttribute('val', 100); - $objWriter->endElement(); - - if ($isMultiLevelSeries) { - $objWriter->startElement('c:noMultiLvlLbl'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - } - $objWriter->endElement(); - - } - - - /** - * Write Value Axis - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Chart_PlotArea $plotArea - * @param PHPExcel_Chart_Title $yAxisLabel - * @param string $groupType Chart type - * @param string $id1 - * @param string $id2 - * @param boolean $isMultiLevelSeries - * @throws PHPExcel_Writer_Exception - */ - private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries) - { - $objWriter->startElement('c:valAx'); - - if ($id2 > 0) { - $objWriter->startElement('c:axId'); - $objWriter->writeAttribute('val', $id2); - $objWriter->endElement(); - } - - $objWriter->startElement('c:scaling'); - $objWriter->startElement('c:orientation'); - $objWriter->writeAttribute('val', "minMax"); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('c:delete'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $objWriter->startElement('c:axPos'); - $objWriter->writeAttribute('val', "l"); - $objWriter->endElement(); - - $objWriter->startElement('c:majorGridlines'); - $objWriter->endElement(); - - if (!is_null($yAxisLabel)) { - $objWriter->startElement('c:title'); - $objWriter->startElement('c:tx'); - $objWriter->startElement('c:rich'); - - $objWriter->startElement('a:bodyPr'); - $objWriter->endElement(); - - $objWriter->startElement('a:lstStyle'); - $objWriter->endElement(); - - $objWriter->startElement('a:p'); - $objWriter->startElement('a:r'); - - $caption = $yAxisLabel->getCaption(); - if (is_array($caption)) - $caption = $caption[0]; - $objWriter->startElement('a:t'); -// $objWriter->writeAttribute('xml:space', 'preserve'); - $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $caption )); - $objWriter->endElement(); - - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - - if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $layout = $yAxisLabel->getLayout(); - $this->_writeLayout($layout, $objWriter); - } - - $objWriter->startElement('c:overlay'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - $objWriter->startElement('c:numFmt'); - $objWriter->writeAttribute('formatCode', "General"); - $objWriter->writeAttribute('sourceLinked', 1); - $objWriter->endElement(); - - $objWriter->startElement('c:majorTickMark'); - $objWriter->writeAttribute('val', "out"); - $objWriter->endElement(); - - $objWriter->startElement('c:minorTickMark'); - $objWriter->writeAttribute('val', "none"); - $objWriter->endElement(); - - $objWriter->startElement('c:tickLblPos'); - $objWriter->writeAttribute('val', "nextTo"); - $objWriter->endElement(); - - if ($id1 > 0) { - $objWriter->startElement('c:crossAx'); - $objWriter->writeAttribute('val', $id2); - $objWriter->endElement(); - - $objWriter->startElement('c:crosses'); - $objWriter->writeAttribute('val', "autoZero"); - $objWriter->endElement(); - - $objWriter->startElement('c:crossBetween'); - $objWriter->writeAttribute('val', "midCat"); - $objWriter->endElement(); - } - - if ($isMultiLevelSeries) { - if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $objWriter->startElement('c:noMultiLvlLbl'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - } - } - $objWriter->endElement(); - - } - - - /** - * Get the data series type(s) for a chart plot series - * - * @param PHPExcel_Chart_PlotArea $plotArea - * @return string|array - * @throws PHPExcel_Writer_Exception - */ - private static function _getChartType($plotArea) - { - $groupCount = $plotArea->getPlotGroupCount(); - - if ($groupCount == 1) { - $chartType = array($plotArea->getPlotGroupByIndex(0)->getPlotType()); - } else { - $chartTypes = array(); - for($i = 0; $i < $groupCount; ++$i) { - $chartTypes[] = $plotArea->getPlotGroupByIndex($i)->getPlotType(); - } - $chartType = array_unique($chartTypes); - if (count($chartTypes) == 0) { - throw new PHPExcel_Writer_Exception('Chart is not yet implemented'); - } - } - - return $chartType; - } - - /** - * Write Plot Group (series of related plots) - * - * @param PHPExcel_Chart_DataSeries $plotGroup - * @param string $groupType Type of plot for dataseries - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param boolean &$catIsMultiLevelSeries Is category a multi-series category - * @param boolean &$valIsMultiLevelSeries Is value set a multi-series set - * @param string &$plotGroupingType Type of grouping for multi-series values - * @param PHPExcel_Worksheet $pSheet - * @throws PHPExcel_Writer_Exception - */ - private function _writePlotGroup( $plotGroup, - $groupType, - $objWriter, - &$catIsMultiLevelSeries, - &$valIsMultiLevelSeries, - &$plotGroupingType, - PHPExcel_Worksheet $pSheet - ) - { - if (is_null($plotGroup)) { - return; - } - - if (($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) { - $objWriter->startElement('c:barDir'); - $objWriter->writeAttribute('val', $plotGroup->getPlotDirection()); - $objWriter->endElement(); - } - - if (!is_null($plotGroup->getPlotGrouping())) { - $plotGroupingType = $plotGroup->getPlotGrouping(); - $objWriter->startElement('c:grouping'); - $objWriter->writeAttribute('val', $plotGroupingType); - $objWriter->endElement(); - } - - // Get these details before the loop, because we can use the count to check for varyColors - $plotSeriesOrder = $plotGroup->getPlotOrder(); - $plotSeriesCount = count($plotSeriesOrder); - - if (($groupType !== PHPExcel_Chart_DataSeries::TYPE_RADARCHART) && - ($groupType !== PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { - - if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_LINECHART) { - if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) || - ($plotSeriesCount > 1)) { - $objWriter->startElement('c:varyColors'); - $objWriter->writeAttribute('val', 1); - $objWriter->endElement(); - } else { - $objWriter->startElement('c:varyColors'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - } - } - } - - foreach($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) { - $objWriter->startElement('c:ser'); - - $objWriter->startElement('c:idx'); - $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesIdx); - $objWriter->endElement(); - - $objWriter->startElement('c:order'); - $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesRef); - $objWriter->endElement(); - - if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { - - $objWriter->startElement('c:dPt'); - $objWriter->startElement('c:idx'); - $objWriter->writeAttribute('val', 3); - $objWriter->endElement(); - - $objWriter->startElement('c:bubble3D'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $objWriter->startElement('c:spPr'); - $objWriter->startElement('a:solidFill'); - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', 'FF9900'); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - } - - // Labels - $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef); - if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) { - $objWriter->startElement('c:tx'); - $objWriter->startElement('c:strRef'); - $this->_writePlotSeriesLabel($plotSeriesLabel, $objWriter); - $objWriter->endElement(); - $objWriter->endElement(); - } - - // Formatting for the points - if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { - $objWriter->startElement('c:spPr'); - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', 12700); - if ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { - $objWriter->startElement('a:noFill'); - $objWriter->endElement(); - } - $objWriter->endElement(); - $objWriter->endElement(); - } - - $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef); - if ($plotSeriesValues) { - $plotSeriesMarker = $plotSeriesValues->getPointMarker(); - if ($plotSeriesMarker) { - $objWriter->startElement('c:marker'); - $objWriter->startElement('c:symbol'); - $objWriter->writeAttribute('val', $plotSeriesMarker); - $objWriter->endElement(); - - if ($plotSeriesMarker !== 'none') { - $objWriter->startElement('c:size'); - $objWriter->writeAttribute('val', 3); - $objWriter->endElement(); - } - $objWriter->endElement(); - } - } - - if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || - ($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) || - ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART)) { - - $objWriter->startElement('c:invertIfNegative'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - } - - // Category Labels - $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef); - if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) { - $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); - - if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { - - if (!is_null($plotGroup->getPlotStyle())) { - $plotStyle = $plotGroup->getPlotStyle(); - if ($plotStyle) { - $objWriter->startElement('c:explosion'); - $objWriter->writeAttribute('val', 25); - $objWriter->endElement(); - } - } - } - - if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || - ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) { - $objWriter->startElement('c:xVal'); - } else { - $objWriter->startElement('c:cat'); - } - - $this->_writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet); - $objWriter->endElement(); - } - - // Values - if ($plotSeriesValues) { - $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries(); - - if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || - ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) { - $objWriter->startElement('c:yVal'); - } else { - $objWriter->startElement('c:val'); - } - - $this->_writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet); - $objWriter->endElement(); - } - - if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $this->_writeBubbles($plotSeriesValues, $objWriter, $pSheet); - } - - $objWriter->endElement(); - - } - - $this->_seriesIndex += $plotSeriesIdx + 1; - } - - /** - * Write Plot Series Label - * - * @param PHPExcel_Chart_DataSeriesValues $plotSeriesLabel - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @throws PHPExcel_Writer_Exception - */ - private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) - { - if (is_null($plotSeriesLabel)) { - return; - } - - $objWriter->startElement('c:f'); - $objWriter->writeRawData($plotSeriesLabel->getDataSource()); - $objWriter->endElement(); - - $objWriter->startElement('c:strCache'); - $objWriter->startElement('c:ptCount'); - $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount() ); - $objWriter->endElement(); - - foreach($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) { - $objWriter->startElement('c:pt'); - $objWriter->writeAttribute('idx', $plotLabelKey ); - - $objWriter->startElement('c:v'); - $objWriter->writeRawData( $plotLabelValue ); - $objWriter->endElement(); - $objWriter->endElement(); - } - $objWriter->endElement(); - - } - - /** - * Write Plot Series Values - * - * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param string $groupType Type of plot for dataseries - * @param string $dataType Datatype of series values - * @param PHPExcel_Worksheet $pSheet - * @throws PHPExcel_Writer_Exception - */ - private function _writePlotSeriesValues( $plotSeriesValues, - $objWriter, - $groupType, - $dataType='str', - PHPExcel_Worksheet $pSheet - ) - { - if (is_null($plotSeriesValues)) { - return; - } - - if ($plotSeriesValues->isMultiLevelSeries()) { - $levelCount = $plotSeriesValues->multiLevelCount(); - - $objWriter->startElement('c:multiLvlStrRef'); - - $objWriter->startElement('c:f'); - $objWriter->writeRawData( $plotSeriesValues->getDataSource() ); - $objWriter->endElement(); - - $objWriter->startElement('c:multiLvlStrCache'); - - $objWriter->startElement('c:ptCount'); - $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount() ); - $objWriter->endElement(); - - for ($level = 0; $level < $levelCount; ++$level) { - $objWriter->startElement('c:lvl'); - - foreach($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) { - if (isset($plotSeriesValue[$level])) { - $objWriter->startElement('c:pt'); - $objWriter->writeAttribute('idx', $plotSeriesKey ); - - $objWriter->startElement('c:v'); - $objWriter->writeRawData( $plotSeriesValue[$level] ); - $objWriter->endElement(); - $objWriter->endElement(); - } - } - - $objWriter->endElement(); - } - - $objWriter->endElement(); - - $objWriter->endElement(); - } else { - $objWriter->startElement('c:'.$dataType.'Ref'); - - $objWriter->startElement('c:f'); - $objWriter->writeRawData( $plotSeriesValues->getDataSource() ); - $objWriter->endElement(); - - $objWriter->startElement('c:'.$dataType.'Cache'); - - if (($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART) && - ($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && - ($groupType != PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { - - if (($plotSeriesValues->getFormatCode() !== NULL) && - ($plotSeriesValues->getFormatCode() !== '')) { - $objWriter->startElement('c:formatCode'); - $objWriter->writeRawData( $plotSeriesValues->getFormatCode() ); - $objWriter->endElement(); - } - } - - $objWriter->startElement('c:ptCount'); - $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount() ); - $objWriter->endElement(); - - $dataValues = $plotSeriesValues->getDataValues(); - if (!empty($dataValues)) { - if (is_array($dataValues)) { - foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { - $objWriter->startElement('c:pt'); - $objWriter->writeAttribute('idx', $plotSeriesKey ); - - $objWriter->startElement('c:v'); - $objWriter->writeRawData( $plotSeriesValue ); - $objWriter->endElement(); - $objWriter->endElement(); - } - } - } - - $objWriter->endElement(); - - $objWriter->endElement(); - } - } - - /** - * Write Bubble Chart Details - * - * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @throws PHPExcel_Writer_Exception - */ - private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) - { - if (is_null($plotSeriesValues)) { - return; - } - - $objWriter->startElement('c:bubbleSize'); - $objWriter->startElement('c:numLit'); - - $objWriter->startElement('c:formatCode'); - $objWriter->writeRawData( 'General' ); - $objWriter->endElement(); - - $objWriter->startElement('c:ptCount'); - $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount() ); - $objWriter->endElement(); - - $dataValues = $plotSeriesValues->getDataValues(); - if (!empty($dataValues)) { - if (is_array($dataValues)) { - foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { - $objWriter->startElement('c:pt'); - $objWriter->writeAttribute('idx', $plotSeriesKey ); - $objWriter->startElement('c:v'); - $objWriter->writeRawData( 1 ); - $objWriter->endElement(); - $objWriter->endElement(); - } - } - } - - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('c:bubble3D'); - $objWriter->writeAttribute('val', 0 ); - $objWriter->endElement(); - } - - /** - * Write Layout - * - * @param PHPExcel_Chart_Layout $layout - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @throws PHPExcel_Writer_Exception - */ - private function _writeLayout(PHPExcel_Chart_Layout $layout = NULL, $objWriter) - { - $objWriter->startElement('c:layout'); - - if (!is_null($layout)) { - $objWriter->startElement('c:manualLayout'); - - $layoutTarget = $layout->getLayoutTarget(); - if (!is_null($layoutTarget)) { - $objWriter->startElement('c:layoutTarget'); - $objWriter->writeAttribute('val', $layoutTarget); - $objWriter->endElement(); - } - - $xMode = $layout->getXMode(); - if (!is_null($xMode)) { - $objWriter->startElement('c:xMode'); - $objWriter->writeAttribute('val', $xMode); - $objWriter->endElement(); - } - - $yMode = $layout->getYMode(); - if (!is_null($yMode)) { - $objWriter->startElement('c:yMode'); - $objWriter->writeAttribute('val', $yMode); - $objWriter->endElement(); - } - - $x = $layout->getXPosition(); - if (!is_null($x)) { - $objWriter->startElement('c:x'); - $objWriter->writeAttribute('val', $x); - $objWriter->endElement(); - } - - $y = $layout->getYPosition(); - if (!is_null($y)) { - $objWriter->startElement('c:y'); - $objWriter->writeAttribute('val', $y); - $objWriter->endElement(); - } - - $w = $layout->getWidth(); - if (!is_null($w)) { - $objWriter->startElement('c:w'); - $objWriter->writeAttribute('val', $w); - $objWriter->endElement(); - } - - $h = $layout->getHeight(); - if (!is_null($h)) { - $objWriter->startElement('c:h'); - $objWriter->writeAttribute('val', $h); - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - - /** - * Write Alternate Content block - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @throws PHPExcel_Writer_Exception - */ - private function _writeAlternateContent($objWriter) - { - $objWriter->startElement('mc:AlternateContent'); - $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); - - $objWriter->startElement('mc:Choice'); - $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart'); - $objWriter->writeAttribute('Requires', 'c14'); - - $objWriter->startElement('c14:style'); - $objWriter->writeAttribute('val', '102'); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('mc:Fallback'); - $objWriter->startElement('c:style'); - $objWriter->writeAttribute('val', '2'); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write Printer Settings - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @throws PHPExcel_Writer_Exception - */ - private function _writePrintSettings($objWriter) - { - $objWriter->startElement('c:printSettings'); - - $objWriter->startElement('c:headerFooter'); - $objWriter->endElement(); - - $objWriter->startElement('c:pageMargins'); - $objWriter->writeAttribute('footer', 0.3); - $objWriter->writeAttribute('header', 0.3); - $objWriter->writeAttribute('r', 0.7); - $objWriter->writeAttribute('l', 0.7); - $objWriter->writeAttribute('t', 0.75); - $objWriter->writeAttribute('b', 0.75); - $objWriter->endElement(); - - $objWriter->startElement('c:pageSetup'); - $objWriter->writeAttribute('orientation', "portrait"); - $objWriter->endElement(); - - $objWriter->endElement(); - } +class PHPExcel_Writer_Excel2007_Chart extends + PHPExcel_Writer_Excel2007_WriterPart { + + /** + * Write charts to XML format + * + * @param PHPExcel_Chart $pChart + * + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeChart(PHPExcel_Chart $pChart = NULL) { + // Create XML writer + $objWriter = NULL; + if ($this->getParentWriter() + ->getUseDiskCaching() + ) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter() + ->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + // Ensure that data series values are up-to-date before we save + $pChart->refresh(); + + // XML header + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); + + // c:chartSpace + $objWriter->startElement('c:chartSpace'); + $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + $objWriter->startElement('c:date1904'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + $objWriter->startElement('c:lang'); + $objWriter->writeAttribute('val', "en-GB"); + $objWriter->endElement(); + $objWriter->startElement('c:roundedCorners'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $this->_writeAlternateContent($objWriter); + + $objWriter->startElement('c:chart'); + + $this->_writeTitle($pChart->getTitle(), $objWriter); + + $objWriter->startElement('c:autoTitleDeleted'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $this->_writePlotArea( + $pChart->getPlotArea(), + $pChart->getXAxisLabel(), + $pChart->getYAxisLabel(), + $objWriter, + $pChart->getWorksheet(), + $pChart->getChartAxisX(), + $pChart->getChartAxisY(), + $pChart->getMajorGridlines(), + $pChart->getMinorGridlines() + ); + + $this->_writeLegend($pChart->getLegend(), $objWriter); + + $objWriter->startElement('c:plotVisOnly'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); + + $objWriter->startElement('c:dispBlanksAs'); + $objWriter->writeAttribute('val', "gap"); + $objWriter->endElement(); + + $objWriter->startElement('c:showDLblsOverMax'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + $this->_writePrintSettings($objWriter); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write Chart Title + * + * @param PHPExcel_Chart_Title $title + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeTitle(PHPExcel_Chart_Title $title = NULL, $objWriter) { + if (is_null($title)) { + return; + } + + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); + + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + + $caption = $title->getCaption(); + if ((is_array($caption)) && (count($caption) > 0)) { + $caption = $caption[0]; + } + $this->getParentWriter() + ->getWriterPart('stringtable') + ->writeRichTextForCharts($objWriter, $caption, 'a'); + + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $layout = $title->getLayout(); + $this->_writeLayout($layout, $objWriter); + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Chart Legend + * + * @param PHPExcel_Chart_Legend $legend + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeLegend(PHPExcel_Chart_Legend $legend = NULL, $objWriter) { + if (is_null($legend)) { + return; + } + + $objWriter->startElement('c:legend'); + + $objWriter->startElement('c:legendPos'); + $objWriter->writeAttribute('val', $legend->getPosition()); + $objWriter->endElement(); + + $layout = $legend->getLayout(); + $this->_writeLayout($layout, $objWriter); + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0'); + $objWriter->endElement(); + + $objWriter->startElement('c:txPr'); + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + $objWriter->startElement('a:pPr'); + $objWriter->writeAttribute('rtl', 0); + + $objWriter->startElement('a:defRPr'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('a:endParaRPr'); + $objWriter->writeAttribute('lang', "en-US"); + $objWriter->endElement(); + + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Chart Plot Area + * + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $xAxisLabel + * @param PHPExcel_Chart_Title $yAxisLabel + * @param PHPExcel_Chart_Axis $xAxis + * @param PHPExcel_Chart_Axis $yAxis + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, + PHPExcel_Chart_Title $xAxisLabel = NULL, + PHPExcel_Chart_Title $yAxisLabel = NULL, + $objWriter, + PHPExcel_Worksheet $pSheet, + PHPExcel_Chart_Axis $xAxis, + PHPExcel_Chart_Axis $yAxis, + PHPExcel_Chart_Gridlines $majorGridlines, + PHPExcel_Chart_Gridlines $minorGridlines + ) { + if (is_null($plotArea)) { + return; + } + + $id1 = $id2 = 0; + $this->_seriesIndex = 0; + $objWriter->startElement('c:plotArea'); + + $layout = $plotArea->getLayout(); + + $this->_writeLayout($layout, $objWriter); + + $chartTypes = self::_getChartType($plotArea); + $catIsMultiLevelSeries = $valIsMultiLevelSeries = FALSE; + $plotGroupingType = ''; + foreach ($chartTypes as $chartType) { + $objWriter->startElement('c:' . $chartType); + + $groupCount = $plotArea->getPlotGroupCount(); + for ($i = 0; $i < $groupCount; ++$i) { + $plotGroup = $plotArea->getPlotGroupByIndex($i); + $groupType = $plotGroup->getPlotType(); + if ($groupType == $chartType) { + + $plotStyle = $plotGroup->getPlotStyle(); + if ($groupType === PHPExcel_Chart_DataSeries::TYPE_RADARCHART) { + $objWriter->startElement('c:radarStyle'); + $objWriter->writeAttribute('val', $plotStyle); + $objWriter->endElement(); + } elseif ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) { + $objWriter->startElement('c:scatterStyle'); + $objWriter->writeAttribute('val', $plotStyle); + $objWriter->endElement(); + } + + $this->_writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet); + } + } + + $this->_writeDataLbls($objWriter, $layout); + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) { + // Line only, Line3D can't be smoothed + + $objWriter->startElement('c:smooth'); + $objWriter->writeAttribute('val', (integer) $plotGroup->getSmoothLine()); + $objWriter->endElement(); + } elseif (($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || + ($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) + ) { + + $objWriter->startElement('c:gapWidth'); + $objWriter->writeAttribute('val', 150); + $objWriter->endElement(); + + if ($plotGroupingType == 'percentStacked' || + $plotGroupingType == 'stacked' + ) { + + $objWriter->startElement('c:overlap'); + $objWriter->writeAttribute('val', 100); + $objWriter->endElement(); + } + } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + + $objWriter->startElement('c:bubbleScale'); + $objWriter->writeAttribute('val', 25); + $objWriter->endElement(); + + $objWriter->startElement('c:showNegBubbles'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { + + $objWriter->startElement('c:hiLowLines'); + $objWriter->endElement(); + + $objWriter->startElement('c:upDownBars'); + + $objWriter->startElement('c:gapWidth'); + $objWriter->writeAttribute('val', 300); + $objWriter->endElement(); + + $objWriter->startElement('c:upBars'); + $objWriter->endElement(); + + $objWriter->startElement('c:downBars'); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + // Generate 2 unique numbers to use for axId values + // $id1 = $id2 = rand(10000000,99999999); + // do { + // $id2 = rand(10000000,99999999); + // } while ($id1 == $id2); + $id1 = '75091328'; + $id2 = '75089408'; + + if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) + ) { + + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id1); + $objWriter->endElement(); + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + } else { + $objWriter->startElement('c:firstSliceAng'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) { + + $objWriter->startElement('c:holeSize'); + $objWriter->writeAttribute('val', 50); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } + + if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) + ) { + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $this->_writeValAx($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); + } else { + $this->_writeCatAx($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis); + } + + $this->_writeValAx($objWriter, $plotArea, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); + } + + $objWriter->endElement(); + } + + /** + * Write Data Labels + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_Layout $chartLayout Chart layout + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeDataLbls($objWriter, $chartLayout) { + $objWriter->startElement('c:dLbls'); + + $objWriter->startElement('c:showLegendKey'); + $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey(); + $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1)); + $objWriter->endElement(); + + $objWriter->startElement('c:showVal'); + $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal(); + $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1)); + $objWriter->endElement(); + + $objWriter->startElement('c:showCatName'); + $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName(); + $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1)); + $objWriter->endElement(); + + $objWriter->startElement('c:showSerName'); + $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName(); + $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1)); + $objWriter->endElement(); + + $objWriter->startElement('c:showPercent'); + $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent(); + $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1)); + $objWriter->endElement(); + + $objWriter->startElement('c:showBubbleSize'); + $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize(); + $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1)); + $objWriter->endElement(); + + $objWriter->startElement('c:showLeaderLines'); + $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines(); + $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1)); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Category Axis + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $xAxisLabel + * @param string $groupType Chart type + * @param string $id1 + * @param string $id2 + * @param boolean $isMultiLevelSeries + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis) { + $objWriter->startElement('c:catAx'); + + if ($id1 > 0) { + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id1); + $objWriter->endElement(); + } + + $objWriter->startElement('c:scaling'); + $objWriter->startElement('c:orientation'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('orientation')); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('c:delete'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->startElement('c:axPos'); + $objWriter->writeAttribute('val', "b"); + $objWriter->endElement(); + + if (!is_null($xAxisLabel)) { + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); + + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + $objWriter->startElement('a:r'); + + $caption = $xAxisLabel->getCaption(); + if (is_array($caption)) { + $caption = $caption[0]; + } + $objWriter->startElement('a:t'); + // $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption)); + $objWriter->endElement(); + + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $layout = $xAxisLabel->getLayout(); + $this->_writeLayout($layout, $objWriter); + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + } + + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', $yAxis->getAxisNumberFormat()); + $objWriter->writeAttribute('sourceLinked', $yAxis->getAxisNumberSourceLinked()); + $objWriter->endElement(); + + $objWriter->startElement('c:majorTickMark'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('major_tick_mark')); + $objWriter->endElement(); + + $objWriter->startElement('c:minorTickMark'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minor_tick_mark')); + $objWriter->endElement(); + + $objWriter->startElement('c:tickLblPos'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('axis_labels')); + $objWriter->endElement(); + + if ($id2 > 0) { + $objWriter->startElement('c:crossAx'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + + $objWriter->startElement('c:crosses'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('horizontal_crosses')); + $objWriter->endElement(); + } + + $objWriter->startElement('c:auto'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); + + $objWriter->startElement('c:lblAlgn'); + $objWriter->writeAttribute('val', "ctr"); + $objWriter->endElement(); + + $objWriter->startElement('c:lblOffset'); + $objWriter->writeAttribute('val', 100); + $objWriter->endElement(); + + if ($isMultiLevelSeries) { + $objWriter->startElement('c:noMultiLvlLbl'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + $objWriter->endElement(); + } + + /** + * Write Value Axis + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $yAxisLabel + * @param string $groupType Chart type + * @param string $id1 + * @param string $id2 + * @param boolean $isMultiLevelSeries + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines) { + $objWriter->startElement('c:valAx'); + + if ($id2 > 0) { + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + } + + $objWriter->startElement('c:scaling'); + $objWriter->startElement('c:orientation'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation')); + + if (!is_null($xAxis->getAxisOptionsProperty('maximum'))) { + $objWriter->startElement('c:max'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('maximum')); + $objWriter->endElement(); + } + + if (!is_null($xAxis->getAxisOptionsProperty('minimum'))) { + $objWriter->startElement('c:min'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minimum')); + $objWriter->endElement(); + } + + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('c:delete'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->startElement('c:axPos'); + $objWriter->writeAttribute('val', "l"); + $objWriter->endElement(); + + $objWriter->startElement('c:majorGridlines'); + $objWriter->startElement('c:spPr'); + + if (!is_null($majorGridlines->getLineColorProperty('value'))) { + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', $majorGridlines->getLineStyleProperty('width')); + $objWriter->startElement('a:solidFill'); + $objWriter->startElement("a:{$majorGridlines->getLineColorProperty('type')}"); + $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('alpha')); + $objWriter->endElement(); //end alpha + $objWriter->endElement(); //end srgbClr + $objWriter->endElement(); //end solidFill + + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', $majorGridlines->getLineStyleProperty('dash')); + $objWriter->endElement(); + + if ($majorGridlines->getLineStyleProperty('join') == 'miter') { + $objWriter->startElement('a:miter'); + $objWriter->writeAttribute('lim', '800000'); + $objWriter->endElement(); + } else { + $objWriter->startElement('a:bevel'); + $objWriter->endElement(); + } + + if (!is_null($majorGridlines->getLineStyleProperty(['arrow', 'head', 'type']))) { + $objWriter->startElement('a:headEnd'); + $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(['arrow', 'head', 'type'])); + $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('head', 'w')); + $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('head', 'len')); + $objWriter->endElement(); + } + + if (!is_null($majorGridlines->getLineStyleProperty(['arrow', 'end', 'type']))) { + $objWriter->startElement('a:tailEnd'); + $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(['arrow', 'end', 'type'])); + $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('end', 'w')); + $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('end', 'len')); + $objWriter->endElement(); + } + $objWriter->endElement(); //end ln + } + $objWriter->startElement('a:effectLst'); + + if (!is_null($majorGridlines->getGlowSize())) { + $objWriter->startElement('a:glow'); + $objWriter->writeAttribute('rad', $majorGridlines->getGlowSize()); + $objWriter->startElement("a:{$majorGridlines->getGlowColor('type')}"); + $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('alpha')); + $objWriter->endElement(); //end alpha + $objWriter->endElement(); //end schemeClr + $objWriter->endElement(); //end glow + } + + if (!is_null($majorGridlines->getShadowProperty('presets'))) { + $objWriter->startElement("a:{$majorGridlines->getShadowProperty('effect')}"); + if (!is_null($majorGridlines->getShadowProperty('blur'))) { + $objWriter->writeAttribute('blurRad', $majorGridlines->getShadowProperty('blur')); + } + if (!is_null($majorGridlines->getShadowProperty('distance'))) { + $objWriter->writeAttribute('dist', $majorGridlines->getShadowProperty('distance')); + } + if (!is_null($majorGridlines->getShadowProperty('direction'))) { + $objWriter->writeAttribute('dir', $majorGridlines->getShadowProperty('direction')); + } + if (!is_null($majorGridlines->getShadowProperty('algn'))) { + $objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn')); + } + if (!is_null($majorGridlines->getShadowProperty(['size', 'sx']))) { + $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(['size', 'sx'])); + } + if (!is_null($majorGridlines->getShadowProperty(['size', 'sy']))) { + $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(['size', 'sy'])); + } + if (!is_null($majorGridlines->getShadowProperty(['size', 'kx']))) { + $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(['size', 'kx'])); + } + if (!is_null($majorGridlines->getShadowProperty('rotWithShape'))) { + $objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape')); + } + $objWriter->startElement("a:{$majorGridlines->getShadowProperty(['color', 'type'])}"); + $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'value'])); + + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'alpha'])); + $objWriter->endElement(); //end alpha + + $objWriter->endElement(); //end color:type + $objWriter->endElement(); //end shadow + } + + if (!is_null($majorGridlines->getSoftEdgesSize())) { + $objWriter->startElement('a:softEdge'); + $objWriter->writeAttribute('rad', $majorGridlines->getSoftEdgesSize()); + $objWriter->endElement(); //end softEdge + } + + $objWriter->endElement(); //end effectLst + $objWriter->endElement(); //end spPr + $objWriter->endElement(); //end majorGridLines + + if ($minorGridlines->getObjectState()) { + $objWriter->startElement('c:minorGridlines'); + $objWriter->startElement('c:spPr'); + + if (!is_null($minorGridlines->getLineColorProperty('value'))) { + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', $minorGridlines->getLineStyleProperty('width')); + $objWriter->startElement('a:solidFill'); + $objWriter->startElement("a:{$minorGridlines->getLineColorProperty('type')}"); + $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('alpha')); + $objWriter->endElement(); //end alpha + $objWriter->endElement(); //end srgbClr + $objWriter->endElement(); //end solidFill + + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', $minorGridlines->getLineStyleProperty('dash')); + $objWriter->endElement(); + + if ($minorGridlines->getLineStyleProperty('join') == 'miter') { + $objWriter->startElement('a:miter'); + $objWriter->writeAttribute('lim', '800000'); + $objWriter->endElement(); + } else { + $objWriter->startElement('a:bevel'); + $objWriter->endElement(); + } + + if (!is_null($minorGridlines->getLineStyleProperty(['arrow', 'head', 'type']))) { + $objWriter->startElement('a:headEnd'); + $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(['arrow', 'head', 'type'])); + $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('head', 'w')); + $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('head', 'len')); + $objWriter->endElement(); + } + + if (!is_null($minorGridlines->getLineStyleProperty(['arrow', 'end', 'type']))) { + $objWriter->startElement('a:tailEnd'); + $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(['arrow', 'end', 'type'])); + $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('end', 'w')); + $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('end', 'len')); + $objWriter->endElement(); + } + $objWriter->endElement(); //end ln + } + + $objWriter->startElement('a:effectLst'); + + if (!is_null($minorGridlines->getGlowSize())) { + $objWriter->startElement('a:glow'); + $objWriter->writeAttribute('rad', $minorGridlines->getGlowSize()); + $objWriter->startElement("a:{$minorGridlines->getGlowColor('type')}"); + $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('alpha')); + $objWriter->endElement(); //end alpha + $objWriter->endElement(); //end schemeClr + $objWriter->endElement(); //end glow + } + + if (!is_null($minorGridlines->getShadowProperty('presets'))) { + $objWriter->startElement("a:{$minorGridlines->getShadowProperty('effect')}"); + if (!is_null($minorGridlines->getShadowProperty('blur'))) { + $objWriter->writeAttribute('blurRad', $minorGridlines->getShadowProperty('blur')); + } + if (!is_null($minorGridlines->getShadowProperty('distance'))) { + $objWriter->writeAttribute('dist', $minorGridlines->getShadowProperty('distance')); + } + if (!is_null($minorGridlines->getShadowProperty('direction'))) { + $objWriter->writeAttribute('dir', $minorGridlines->getShadowProperty('direction')); + } + if (!is_null($minorGridlines->getShadowProperty('algn'))) { + $objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn')); + } + if (!is_null($minorGridlines->getShadowProperty(['size', 'sx']))) { + $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(['size', 'sx'])); + } + if (!is_null($minorGridlines->getShadowProperty(['size', 'sy']))) { + $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(['size', 'sy'])); + } + if (!is_null($minorGridlines->getShadowProperty(['size', 'kx']))) { + $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(['size', 'kx'])); + } + if (!is_null($minorGridlines->getShadowProperty('rotWithShape'))) { + $objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape')); + } + $objWriter->startElement("a:{$minorGridlines->getShadowProperty(['color', 'type'])}"); + $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'value'])); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'alpha'])); + $objWriter->endElement(); //end alpha + $objWriter->endElement(); //end color:type + $objWriter->endElement(); //end shadow + } + + if (!is_null($minorGridlines->getSoftEdgesSize())) { + $objWriter->startElement('a:softEdge'); + $objWriter->writeAttribute('rad', $minorGridlines->getSoftEdgesSize()); + $objWriter->endElement(); //end softEdge + } + + $objWriter->endElement(); //end effectLst + $objWriter->endElement(); //end spPr + $objWriter->endElement(); //end minorGridLines + } + + if (!is_null($yAxisLabel)) { + + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); + + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + $objWriter->startElement('a:r'); + + $caption = $yAxisLabel->getCaption(); + if (is_array($caption)) { + $caption = $caption[0]; + } + + $objWriter->startElement('a:t'); + // $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption)); + $objWriter->endElement(); + + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $layout = $yAxisLabel->getLayout(); + $this->_writeLayout($layout, $objWriter); + } + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', $xAxis->getAxisNumberFormat()); + $objWriter->writeAttribute('sourceLinked', $xAxis->getAxisNumberSourceLinked()); + $objWriter->endElement(); + + $objWriter->startElement('c:majorTickMark'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_tick_mark')); + $objWriter->endElement(); + + $objWriter->startElement('c:minorTickMark'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_tick_mark')); + $objWriter->endElement(); + + $objWriter->startElement('c:tickLblPos'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('axis_labels')); + $objWriter->endElement(); + + $objWriter->startElement('c:spPr'); + + if (!is_null($xAxis->getFillProperty('value'))) { + $objWriter->startElement('a:solidFill'); + $objWriter->startElement("a:" . $xAxis->getFillProperty('type')); + $objWriter->writeAttribute('val', $xAxis->getFillProperty('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $xAxis->getFillProperty('alpha')); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + } + + $objWriter->startElement('a:ln'); + + $objWriter->writeAttribute('w', $xAxis->getLineStyleProperty('width')); + $objWriter->writeAttribute('cap', $xAxis->getLineStyleProperty('cap')); + $objWriter->writeAttribute('cmpd', $xAxis->getLineStyleProperty('compound')); + + if (!is_null($xAxis->getLineProperty('value'))) { + $objWriter->startElement('a:solidFill'); + $objWriter->startElement("a:" . $xAxis->getLineProperty('type')); + $objWriter->writeAttribute('val', $xAxis->getLineProperty('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $xAxis->getLineProperty('alpha')); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + } + + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', $xAxis->getLineStyleProperty('dash')); + $objWriter->endElement(); + + if ($xAxis->getLineStyleProperty('join') == 'miter') { + $objWriter->startElement('a:miter'); + $objWriter->writeAttribute('lim', '800000'); + $objWriter->endElement(); + } else { + $objWriter->startElement('a:bevel'); + $objWriter->endElement(); + } + + if (!is_null($xAxis->getLineStyleProperty(['arrow', 'head', 'type']))) { + $objWriter->startElement('a:headEnd'); + $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(['arrow', 'head', 'type'])); + $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('head')); + $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('head')); + $objWriter->endElement(); + } + + if (!is_null($xAxis->getLineStyleProperty(['arrow', 'end', 'type']))) { + $objWriter->startElement('a:tailEnd'); + $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(['arrow', 'end', 'type'])); + $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('end')); + $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('end')); + $objWriter->endElement(); + } + + $objWriter->endElement(); + + $objWriter->startElement('a:effectLst'); + + if (!is_null($xAxis->getGlowProperty('size'))) { + $objWriter->startElement('a:glow'); + $objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size')); + $objWriter->startElement("a:{$xAxis->getGlowProperty(['color','type'])}"); + $objWriter->writeAttribute('val', $xAxis->getGlowProperty(['color','value'])); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $xAxis->getGlowProperty(['color','alpha'])); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + } + + if (!is_null($xAxis->getShadowProperty('presets'))) { + $objWriter->startElement("a:{$xAxis->getShadowProperty('effect')}"); + + if (!is_null($xAxis->getShadowProperty('blur'))) { + $objWriter->writeAttribute('blurRad', $xAxis->getShadowProperty('blur')); + } + if (!is_null($xAxis->getShadowProperty('distance'))) { + $objWriter->writeAttribute('dist', $xAxis->getShadowProperty('distance')); + } + if (!is_null($xAxis->getShadowProperty('direction'))) { + $objWriter->writeAttribute('dir', $xAxis->getShadowProperty('direction')); + } + if (!is_null($xAxis->getShadowProperty('algn'))) { + $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn')); + } + if (!is_null($xAxis->getShadowProperty(['size','sx']))) { + $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(['size','sx'])); + } + if (!is_null($xAxis->getShadowProperty(['size','sy']))) { + $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(['size','sy'])); + } + if (!is_null($xAxis->getShadowProperty(['size','kx']))) { + $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(['size','kx'])); + } + if (!is_null($xAxis->getShadowProperty('rotWithShape'))) { + $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape')); + } + + $objWriter->startElement("a:{$xAxis->getShadowProperty(['color','type'])}"); + $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color','value'])); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color','alpha'])); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + if (!is_null($xAxis->getSoftEdgesSize())) { + $objWriter->startElement('a:softEdge'); + $objWriter->writeAttribute('rad', $xAxis->getSoftEdgesSize()); + $objWriter->endElement(); + } + + $objWriter->endElement(); //effectList + $objWriter->endElement(); //end spPr + + if ($id1 > 0) { + $objWriter->startElement('c:crossAx'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + + if (!is_null($xAxis->getAxisOptionsProperty('horizontal_crosses_value'))) { + $objWriter->startElement('c:crossesAt'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses_value')); + $objWriter->endElement(); + } else { + $objWriter->startElement('c:crosses'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses')); + $objWriter->endElement(); + } + + $objWriter->startElement('c:crossBetween'); + $objWriter->writeAttribute('val', "midCat"); + $objWriter->endElement(); + + if (!is_null($xAxis->getAxisOptionsProperty('major_unit'))) { + $objWriter->startElement('c:majorUnit'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_unit')); + $objWriter->endElement(); + } + + if (!is_null($xAxis->getAxisOptionsProperty('minor_unit'))) { + $objWriter->startElement('c:minorUnit'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_unit')); + $objWriter->endElement(); + } + + } + + if ($isMultiLevelSeries) { + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $objWriter->startElement('c:noMultiLvlLbl'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + + } + + /** + * Get the data series type(s) for a chart plot series + * + * @param PHPExcel_Chart_PlotArea $plotArea + * + * @return string|array + * @throws PHPExcel_Writer_Exception + */ + private + static function _getChartType($plotArea) { + $groupCount = $plotArea->getPlotGroupCount(); + + if ($groupCount == 1) { + $chartType = array( + $plotArea->getPlotGroupByIndex(0) + ->getPlotType() + ); + } else { + $chartTypes = array(); + for ($i = 0; $i < $groupCount; ++$i) { + $chartTypes[] = $plotArea->getPlotGroupByIndex($i) + ->getPlotType(); + } + $chartType = array_unique($chartTypes); + if (count($chartTypes) == 0) { + throw new PHPExcel_Writer_Exception('Chart is not yet implemented'); + } + } + + return $chartType; + } + + /** + * Write Plot Group (series of related plots) + * + * @param PHPExcel_Chart_DataSeries $plotGroup + * @param string $groupType Type of plot for dataseries + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param boolean &$catIsMultiLevelSeries Is category a multi-series category + * @param boolean &$valIsMultiLevelSeries Is value set a multi-series set + * @param string &$plotGroupingType Type of grouping for multi-series values + * @param PHPExcel_Worksheet $pSheet + * + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotGroup($plotGroup, + $groupType, + $objWriter, + &$catIsMultiLevelSeries, + &$valIsMultiLevelSeries, + &$plotGroupingType, + PHPExcel_Worksheet $pSheet + ) { + if (is_null($plotGroup)) { + return; + } + + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) + ) { + $objWriter->startElement('c:barDir'); + $objWriter->writeAttribute('val', $plotGroup->getPlotDirection()); + $objWriter->endElement(); + } + + if (!is_null($plotGroup->getPlotGrouping())) { + $plotGroupingType = $plotGroup->getPlotGrouping(); + $objWriter->startElement('c:grouping'); + $objWriter->writeAttribute('val', $plotGroupingType); + $objWriter->endElement(); + } + + // Get these details before the loop, because we can use the count to check for varyColors + $plotSeriesOrder = $plotGroup->getPlotOrder(); + $plotSeriesCount = count($plotSeriesOrder); + + if (($groupType !== PHPExcel_Chart_DataSeries::TYPE_RADARCHART) && + ($groupType !== PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) + ) { + + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_LINECHART) { + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) || + ($plotSeriesCount > 1) + ) { + $objWriter->startElement('c:varyColors'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); + } else { + $objWriter->startElement('c:varyColors'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + } + } + + foreach ($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) { + $objWriter->startElement('c:ser'); + + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesIdx); + $objWriter->endElement(); + + $objWriter->startElement('c:order'); + $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesRef); + $objWriter->endElement(); + + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) + ) { + + $objWriter->startElement('c:dPt'); + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', 3); + $objWriter->endElement(); + + $objWriter->startElement('c:bubble3D'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->startElement('c:spPr'); + $objWriter->startElement('a:solidFill'); + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FF9900'); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + } + + // Labels + $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef); + if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) { + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:strRef'); + $this->_writePlotSeriesLabel($plotSeriesLabel, $objWriter); + $objWriter->endElement(); + $objWriter->endElement(); + } + + // Formatting for the points + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) + ) { + $objWriter->startElement('c:spPr'); + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', 12700); + if ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { + $objWriter->startElement('a:noFill'); + $objWriter->endElement(); + } + $objWriter->endElement(); + $objWriter->endElement(); + } + + $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef); + if ($plotSeriesValues) { + $plotSeriesMarker = $plotSeriesValues->getPointMarker(); + if ($plotSeriesMarker) { + $objWriter->startElement('c:marker'); + $objWriter->startElement('c:symbol'); + $objWriter->writeAttribute('val', $plotSeriesMarker); + $objWriter->endElement(); + + if ($plotSeriesMarker !== 'none') { + $objWriter->startElement('c:size'); + $objWriter->writeAttribute('val', 3); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) + ) { + + $objWriter->startElement('c:invertIfNegative'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + + // Category Labels + $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef); + if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) { + $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); + + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) + ) { + + if (!is_null($plotGroup->getPlotStyle())) { + $plotStyle = $plotGroup->getPlotStyle(); + if ($plotStyle) { + $objWriter->startElement('c:explosion'); + $objWriter->writeAttribute('val', 25); + $objWriter->endElement(); + } + } + } + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) + ) { + $objWriter->startElement('c:xVal'); + } else { + $objWriter->startElement('c:cat'); + } + + $this->_writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet); + $objWriter->endElement(); + } + + // Values + if ($plotSeriesValues) { + $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries(); + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) + ) { + $objWriter->startElement('c:yVal'); + } else { + $objWriter->startElement('c:val'); + } + + $this->_writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet); + $objWriter->endElement(); + } + + if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $this->_writeBubbles($plotSeriesValues, $objWriter, $pSheet); + } + + $objWriter->endElement(); + + } + + $this->_seriesIndex += $plotSeriesIdx + 1; + } + + /** + * Write Plot Series Label + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesLabel + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) { + if (is_null($plotSeriesLabel)) { + return; + } + + $objWriter->startElement('c:f'); + $objWriter->writeRawData($plotSeriesLabel->getDataSource()); + $objWriter->endElement(); + + $objWriter->startElement('c:strCache'); + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount()); + $objWriter->endElement(); + + foreach ($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotLabelKey); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData($plotLabelValue); + $objWriter->endElement(); + $objWriter->endElement(); + } + $objWriter->endElement(); + + } + + /** + * Write Plot Series Values + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $groupType Type of plot for dataseries + * @param string $dataType Datatype of series values + * @param PHPExcel_Worksheet $pSheet + * + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotSeriesValues($plotSeriesValues, + $objWriter, + $groupType, + $dataType = 'str', + PHPExcel_Worksheet $pSheet + ) { + if (is_null($plotSeriesValues)) { + return; + } + + if ($plotSeriesValues->isMultiLevelSeries()) { + $levelCount = $plotSeriesValues->multiLevelCount(); + + $objWriter->startElement('c:multiLvlStrRef'); + + $objWriter->startElement('c:f'); + $objWriter->writeRawData($plotSeriesValues->getDataSource()); + $objWriter->endElement(); + + $objWriter->startElement('c:multiLvlStrCache'); + + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); + $objWriter->endElement(); + + for ($level = 0; $level < $levelCount; ++$level) { + $objWriter->startElement('c:lvl'); + + foreach ($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) { + if (isset($plotSeriesValue[$level])) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData($plotSeriesValue[$level]); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } else { + $objWriter->startElement('c:' . $dataType . 'Ref'); + + $objWriter->startElement('c:f'); + $objWriter->writeRawData($plotSeriesValues->getDataSource()); + $objWriter->endElement(); + + $objWriter->startElement('c:' . $dataType . 'Cache'); + + if (($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART) && + ($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && + ($groupType != PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) + ) { + + if (($plotSeriesValues->getFormatCode() !== NULL) && + ($plotSeriesValues->getFormatCode() !== '') + ) { + $objWriter->startElement('c:formatCode'); + $objWriter->writeRawData($plotSeriesValues->getFormatCode()); + $objWriter->endElement(); + } + } + + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); + $objWriter->endElement(); + + $dataValues = $plotSeriesValues->getDataValues(); + if (!empty($dataValues)) { + if (is_array($dataValues)) { + foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData($plotSeriesValue); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Write Bubble Chart Details + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) { + if (is_null($plotSeriesValues)) { + return; + } + + $objWriter->startElement('c:bubbleSize'); + $objWriter->startElement('c:numLit'); + + $objWriter->startElement('c:formatCode'); + $objWriter->writeRawData('General'); + $objWriter->endElement(); + + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); + $objWriter->endElement(); + + $dataValues = $plotSeriesValues->getDataValues(); + if (!empty($dataValues)) { + if (is_array($dataValues)) { + foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey); + $objWriter->startElement('c:v'); + $objWriter->writeRawData(1); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('c:bubble3D'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + + /** + * Write Layout + * + * @param PHPExcel_Chart_Layout $layout + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeLayout(PHPExcel_Chart_Layout $layout = NULL, $objWriter) { + $objWriter->startElement('c:layout'); + + if (!is_null($layout)) { + $objWriter->startElement('c:manualLayout'); + + $layoutTarget = $layout->getLayoutTarget(); + if (!is_null($layoutTarget)) { + $objWriter->startElement('c:layoutTarget'); + $objWriter->writeAttribute('val', $layoutTarget); + $objWriter->endElement(); + } + + $xMode = $layout->getXMode(); + if (!is_null($xMode)) { + $objWriter->startElement('c:xMode'); + $objWriter->writeAttribute('val', $xMode); + $objWriter->endElement(); + } + + $yMode = $layout->getYMode(); + if (!is_null($yMode)) { + $objWriter->startElement('c:yMode'); + $objWriter->writeAttribute('val', $yMode); + $objWriter->endElement(); + } + + $x = $layout->getXPosition(); + if (!is_null($x)) { + $objWriter->startElement('c:x'); + $objWriter->writeAttribute('val', $x); + $objWriter->endElement(); + } + + $y = $layout->getYPosition(); + if (!is_null($y)) { + $objWriter->startElement('c:y'); + $objWriter->writeAttribute('val', $y); + $objWriter->endElement(); + } + + $w = $layout->getWidth(); + if (!is_null($w)) { + $objWriter->startElement('c:w'); + $objWriter->writeAttribute('val', $w); + $objWriter->endElement(); + } + + $h = $layout->getHeight(); + if (!is_null($h)) { + $objWriter->startElement('c:h'); + $objWriter->writeAttribute('val', $h); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Alternate Content block + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeAlternateContent($objWriter) { + $objWriter->startElement('mc:AlternateContent'); + $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); + + $objWriter->startElement('mc:Choice'); + $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart'); + $objWriter->writeAttribute('Requires', 'c14'); + + $objWriter->startElement('c14:style'); + $objWriter->writeAttribute('val', '102'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('mc:Fallback'); + $objWriter->startElement('c:style'); + $objWriter->writeAttribute('val', '2'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Printer Settings + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writePrintSettings($objWriter) { + $objWriter->startElement('c:printSettings'); + + $objWriter->startElement('c:headerFooter'); + $objWriter->endElement(); + + $objWriter->startElement('c:pageMargins'); + $objWriter->writeAttribute('footer', 0.3); + $objWriter->writeAttribute('header', 0.3); + $objWriter->writeAttribute('r', 0.7); + $objWriter->writeAttribute('l', 0.7); + $objWriter->writeAttribute('t', 0.75); + $objWriter->writeAttribute('b', 0.75); + $objWriter->endElement(); + + $objWriter->startElement('c:pageSetup'); + $objWriter->writeAttribute('orientation', "portrait"); + $objWriter->endElement(); + + $objWriter->endElement(); + } } From 944a9ee32ea88537f22e553e5abf339dfce91d7a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 14 Jul 2014 23:07:00 +0100 Subject: [PATCH 234/467] PRs in changelog --- changelog.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/changelog.txt b/changelog.txt index 3177106f5..cab93b29b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -22,6 +22,11 @@ * @version ##VERSION##, ##DATE## ************************************************************************************** +Planned for v1.8.1 +- Bugfix: (goncons) Work Item GH-397 - Fix for Writing an Open Document cell with non-numeric formula +- Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines +- Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell + 2014-03-02 (v1.8.0): - Bugfix: (MBaker) Work item CP19830 - Undefined variable: fileHandle in CSV Reader From c6d0a4d3d03526e900ec71f033d95dffcd70b999 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 14 Jul 2014 23:45:46 +0100 Subject: [PATCH 235/467] Additional divide by zero handling --- Classes/PHPExcel/Worksheet/BaseDrawing.php | 12 ++++++++---- changelog.txt | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/Worksheet/BaseDrawing.php b/Classes/PHPExcel/Worksheet/BaseDrawing.php index 4820afb82..77b0b3987 100644 --- a/Classes/PHPExcel/Worksheet/BaseDrawing.php +++ b/Classes/PHPExcel/Worksheet/BaseDrawing.php @@ -321,7 +321,7 @@ public function getWidth() { public function setWidth($pValue = 0) { // Resize proportional? if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_height / $this->_width; + $ratio = $this->_height / ($this->_width !== 0 ? $this->_width : 1); $this->_height = round($ratio * $pValue); } @@ -373,8 +373,8 @@ public function setHeight($pValue = 0) { * @return PHPExcel_Worksheet_BaseDrawing */ public function setWidthAndHeight($width = 0, $height = 0) { - $xratio = $width / $this->_width; - $yratio = $height / $this->_height; + $xratio = $width / ($this->_width !== 0 ? $this->_width : 1); + $yratio = $height / ($this->_height !== 0 ? $this->_height : 1); if ($this->_resizeProportional && !($width == 0 || $height == 0)) { if (($xratio * $this->_height) < $height) { $this->_height = ceil($xratio * $this->_height); @@ -383,7 +383,11 @@ public function setWidthAndHeight($width = 0, $height = 0) { $this->_width = ceil($yratio * $this->_width); $this->_height = $height; } - } + } else { + $this->_width = $width; + $this->_height = $height; + } + return $this; } diff --git a/changelog.txt b/changelog.txt index cab93b29b..17e2bb0dd 100644 --- a/changelog.txt +++ b/changelog.txt @@ -24,8 +24,11 @@ Planned for v1.8.1 - Bugfix: (goncons) Work Item GH-397 - Fix for Writing an Open Document cell with non-numeric formula +- Bugfix: (sarciszewski) Work Item GH-329 - Avoid potential divide by zero in basedrawing +- General: (MBaker) - Small performance improvement for autosize columns - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines - Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell +- Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions 2014-03-02 (v1.8.0): From 87be8d3d8e1c503a6422fee585e5fc5193c66978 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 15 Jul 2014 23:33:06 +0100 Subject: [PATCH 236/467] Bugfix to ensure that current cell is maintained when executing formula calculations --- Classes/PHPExcel/Calculation.php | 10 ++++++++++ changelog.txt | 1 + 2 files changed, 11 insertions(+) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index c4f211292..c159012b3 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -194,6 +194,8 @@ class PHPExcel_Calculation { */ private $_cyclicReferenceStack; + private $_cellStack = array(); + /** * Current iteration counter for cyclic formulae * If the value is 0 (or less) then cyclic formulae will throw an exception, @@ -2240,9 +2242,17 @@ public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE } // Execute the calculation for the cell formula + $this->_cellStack[] = array( + 'sheet' => $pCell->getWorksheet()->getTitle(), + 'cell' => $pCell->getCoordinate(), + ); try { $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); + $cellAddress = array_pop($this->_cellStack); + $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); } catch (PHPExcel_Exception $e) { + $cellAddress = array_pop($this->_cellStack); + $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); throw new PHPExcel_Calculation_Exception($e->getMessage()); } diff --git a/changelog.txt b/changelog.txt index 17e2bb0dd..cb30111ec 100644 --- a/changelog.txt +++ b/changelog.txt @@ -25,6 +25,7 @@ Planned for v1.8.1 - Bugfix: (goncons) Work Item GH-397 - Fix for Writing an Open Document cell with non-numeric formula - Bugfix: (sarciszewski) Work Item GH-329 - Avoid potential divide by zero in basedrawing +- Bugfix: (MBaker) - Fix to ensure that current cell is maintained when executing formula calculations - General: (MBaker) - Small performance improvement for autosize columns - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines - Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell From 0787e56d41c1279faf2d0e4592d92d74a3f9502f Mon Sep 17 00:00:00 2001 From: Yves Maerschalck Date: Wed, 16 Jul 2014 09:28:33 +0200 Subject: [PATCH 237/467] XML External Entity (XXE) Processing https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing change simplexml_load_file to simplexml_load_string(file_get_contents()) because load_file doesn't work when http://php.net/manual/en/function.libxml-disable-entity-loader.php is true --- Classes/PHPExcel/Reader/Excel2003XML.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index 17472d040..6f3a4efd4 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -137,7 +137,7 @@ public function listWorksheetNames($pFilename) $worksheetNames = array(); - $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml = simplexml_load_string(file_get_contents($pFilename), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespaces = $xml->getNamespaces(true); $xml_ss = $xml->children($namespaces['ss']); @@ -165,7 +165,7 @@ public function listWorksheetInfo($pFilename) $worksheetInfo = array(); - $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml = simplexml_load_string(file_get_contents($pFilename), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespaces = $xml->getNamespaces(true); $worksheetID = 1; @@ -330,7 +330,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } - $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml = simplexml_load_string(file_get_contents($pFilename), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespaces = $xml->getNamespaces(true); $docProps = $objPHPExcel->getProperties(); From 38ff5a49f86f0b523e10f7499f7d3245590f48c6 Mon Sep 17 00:00:00 2001 From: matteofilippetto Date: Tue, 22 Jul 2014 17:40:31 +0200 Subject: [PATCH 238/467] again division by zero $this->_width and $this->_height are defined as float so !== will return TRUE also if the value is 0 ( as !== use OR ) --- Classes/PHPExcel/Worksheet/BaseDrawing.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/Worksheet/BaseDrawing.php b/Classes/PHPExcel/Worksheet/BaseDrawing.php index 77b0b3987..5a760fcad 100644 --- a/Classes/PHPExcel/Worksheet/BaseDrawing.php +++ b/Classes/PHPExcel/Worksheet/BaseDrawing.php @@ -321,7 +321,7 @@ public function getWidth() { public function setWidth($pValue = 0) { // Resize proportional? if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_height / ($this->_width !== 0 ? $this->_width : 1); + $ratio = $this->_height / ($this->_width != 0 ? $this->_width : 1); $this->_height = round($ratio * $pValue); } @@ -349,7 +349,7 @@ public function getHeight() { public function setHeight($pValue = 0) { // Resize proportional? if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_width / ($this->_height !== 0 ? $this->_height : 1); + $ratio = $this->_width / ($this->_height != 0 ? $this->_height : 1); $this->_width = round($ratio * $pValue); } @@ -373,8 +373,8 @@ public function setHeight($pValue = 0) { * @return PHPExcel_Worksheet_BaseDrawing */ public function setWidthAndHeight($width = 0, $height = 0) { - $xratio = $width / ($this->_width !== 0 ? $this->_width : 1); - $yratio = $height / ($this->_height !== 0 ? $this->_height : 1); + $xratio = $width / ($this->_width != 0 ? $this->_width : 1); + $yratio = $height / ($this->_height != 0 ? $this->_height : 1); if ($this->_resizeProportional && !($width == 0 || $height == 0)) { if (($xratio * $this->_height) < $height) { $this->_height = ceil($xratio * $this->_height); From 9065cab60c85293c0d9ec38c548482411a8dc504 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 22 Jul 2014 23:48:32 +0100 Subject: [PATCH 239/467] DOMDocument not domDocument --- Classes/PHPExcel/Reader/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 5b32c9223..ec074f5ac 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -422,7 +422,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex ); // Create a new DOM object - $dom = new domDocument; + $dom = new DOMDocument; // Reload the HTML file into the DOM object $loaded = $dom->loadHTMLFile($pFilename, PHPExcel_Settings::getLibXmlLoaderOptions()); if ($loaded === FALSE) { From 134bd0fda6949cf93424bb8be4264586e763254c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 24 Jul 2014 22:50:53 +0100 Subject: [PATCH 240/467] Feature - New methods added for testing cell status within merge groups --- Classes/PHPExcel/Cell.php | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 0462686d1..7f0dd1a5a 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -496,6 +496,45 @@ public function getWorksheet() { return $this->_parent->getParent(); } + /** + * Is this cell in a merge range + * + * @return boolean + */ + public function isInMergeRange() { + return (boolean) $this->getMergeRange(); + } + + /** + * Is this cell the master (top left cell) in a merge range (that holds the actual data value) + * + * @return boolean + */ + public function isMergeRangeValueCell() { + if ($mergeRange = $this->getMergeRange()) { + $mergeRange = PHPExcel_Cell::splitRange($mergeRange); + list($startCell) = $mergeRange[0]; + if ($this->getCoordinate() === $startCell) { + return true; + } + } + return false; + } + + /** + * If this cell is in a merge range, then return the range + * + * @return string + */ + public function getMergeRange() { + foreach($this->getWorksheet()->getMergeCells() as $mergeRange) { + if ($this->isInRange($mergeRange)) { + return $mergeRange; + } + } + return false; + } + /** * Get cell style * From 59cb459899174b36e65e59f73d42dc10fdc861c3 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 26 Jul 2014 15:45:44 +0100 Subject: [PATCH 241/467] Case-sensitivity error --- Classes/PHPExcel/Writer/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 72fd81856..bc220561e 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -1176,7 +1176,7 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow array($this, 'formatColor') ); } else { - $cellData = PHPExcel_Style_NumberFormat::ToFormattedString( + $cellData = PHPExcel_Style_NumberFormat::toFormattedString( $cell->getValue(), $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), array($this, 'formatColor') From fe6273f8e0648abe562377db30c47510c57419a2 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 26 Jul 2014 19:46:00 +0100 Subject: [PATCH 242/467] Fix for nested collapsed grouping when writing BIFF-format files, courtesy of ShadowEDX --- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index 722ac15bf..fb75499b1 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -1247,7 +1247,7 @@ private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) $grbit |= $level; if ($hidden) { - $grbit |= 0x0020; + $grbit |= 0x0030; } if ($height !== null) { $grbit |= 0x0040; // fUnsynced From 6a0d5b3c2a63b64a95e7780009818bef5e768357 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 27 Jul 2014 12:39:01 +0100 Subject: [PATCH 243/467] Update change log --- changelog.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelog.txt b/changelog.txt index cb30111ec..af74b4969 100644 --- a/changelog.txt +++ b/changelog.txt @@ -25,11 +25,14 @@ Planned for v1.8.1 - Bugfix: (goncons) Work Item GH-397 - Fix for Writing an Open Document cell with non-numeric formula - Bugfix: (sarciszewski) Work Item GH-329 - Avoid potential divide by zero in basedrawing +- Bugfix: (ymaerschalck) Work Item GH-405 - XML External Entity (XXE) Processing, different behaviour between simplexml_load_string() and simplexml_load_file(). - Bugfix: (MBaker) - Fix to ensure that current cell is maintained when executing formula calculations - General: (MBaker) - Small performance improvement for autosize columns +- General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines - Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions +- Feature: (MBaker) - New methods added for testing cell status within merge groups 2014-03-02 (v1.8.0): From 698a56eb922c598b6d972cef734b1efa75dd1e3f Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 27 Jul 2014 12:51:38 +0100 Subject: [PATCH 244/467] Bugfix: Work Item GH-350 - Keep/set the value on Reader _loadSheetsOnly as NULL, courtesy of Restless-ET --- Classes/PHPExcel/Reader/Abstract.php | 5 ++++- changelog.txt | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php index e0f4c0dc3..1a6b422ff 100644 --- a/Classes/PHPExcel/Reader/Abstract.php +++ b/Classes/PHPExcel/Reader/Abstract.php @@ -145,7 +145,10 @@ public function getLoadSheetsOnly() */ public function setLoadSheetsOnly($value = NULL) { - $this->_loadSheetsOnly = is_array($value) ? + if ($value === NULL) + return $this->setLoadAllSheets(); + + $this->_loadSheetsOnly = is_array($value) ? $value : array($value); return $this; } diff --git a/changelog.txt b/changelog.txt index af74b4969..4d6b41d15 100644 --- a/changelog.txt +++ b/changelog.txt @@ -27,6 +27,7 @@ Planned for v1.8.1 - Bugfix: (sarciszewski) Work Item GH-329 - Avoid potential divide by zero in basedrawing - Bugfix: (ymaerschalck) Work Item GH-405 - XML External Entity (XXE) Processing, different behaviour between simplexml_load_string() and simplexml_load_file(). - Bugfix: (MBaker) - Fix to ensure that current cell is maintained when executing formula calculations +- Bugfix: (MBaker) Work Item GH-350 - Keep/set the value on Reader _loadSheetsOnly as NULL, courtesy of Restless-ET - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines From ab693eafcd0349aef36e1a33dedcc44b00948477 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 27 Jul 2014 13:12:44 +0100 Subject: [PATCH 245/467] Feature: (bolovincev) Work Item GH-269 - Update Worksheet.php getStyleByColumnAndRow() to allow a range of cells rather than just a single cell --- Classes/PHPExcel/Worksheet.php | 17 ++++++++--------- changelog.txt | 1 + 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index e40c03f90..e53c22835 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1405,7 +1405,7 @@ public function setDefaultStyle(PHPExcel_Style $pValue) /** * Get style for cell * - * @param string $pCellCoordinate Cell coordinate to get style for + * @param string $pCellCoordinate Cell coordinate (or range) to get style for * @return PHPExcel_Style * @throws PHPExcel_Exception */ @@ -1492,16 +1492,15 @@ public function setConditionalStyles($pCoordinate = 'A1', $pValue) * @param int pRow2 Numeric row coordinate of the range cell * @return PHPExcel_Style */ - public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1, $pColumn2=null, $pRow2=null) + public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1, $pColumn2 = null, $pRow2 = null) { + if (!is_null($pColumn2) && !is_null($pRow2)) { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow . ':' . + PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->getStyle($cellRange); + } - if(!is_null($pColumn2) && !is_null($pRow2)) - { - $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; - return $this->getStyle($cellRange); - } - - return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); } /** diff --git a/changelog.txt b/changelog.txt index 4d6b41d15..51fc4a2cc 100644 --- a/changelog.txt +++ b/changelog.txt @@ -33,6 +33,7 @@ Planned for v1.8.1 - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines - Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions +- Feature: (bolovincev) Work Item GH-269 - Update Worksheet.php getStyleByColumnAndRow() to allow a range of cells rather than just a single cell - Feature: (MBaker) - New methods added for testing cell status within merge groups From d9fa784e1bffa1216c936d9102bdec1489ef7780 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 27 Jul 2014 15:18:00 +0100 Subject: [PATCH 246/467] Bugfix: Work Item CP18105 - Loading an Excel 2007 spreadsheet throws an "Autofilter must be set on a range of cells" exception Fix to jpgraph path for Chart Rendering tests --- Classes/PHPExcel/Reader/Excel2007.php | 17 +++++++++++++++-- Examples/35chartrender.php | 2 +- changelog.txt | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index a5da6e129..d5c947ee5 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1007,7 +1007,13 @@ public function load($pFilename) if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { $autoFilter = $docSheet->getAutoFilter(); - $autoFilter->setRange((string) $xmlSheet->autoFilter["ref"]); + + $autoFilterRange = (string) $xmlSheet->autoFilter["ref"]; + if (strpos($autoFilterRange, ':') === false) { + $autoFilterRange = "${autoFilterRange}:${autoFilterRange}"; + } + $autoFilter->setRange($autoFilterRange); + foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); // Check for standard filters @@ -1575,7 +1581,14 @@ public function load($pFilename) case '_xlnm._FilterDatabase': if ((string)$definedName['hidden'] !== '1') { - $docSheet->getAutoFilter()->setRange($extractedRange); + $extractedRange = explode(',', $extractedRange); + foreach ($extractedRange as $range) { + $autoFilterRange = $range; + if (strpos($autoFilterRange, ':') === false) { + $autoFilterRange = "${autoFilterRange}:${autoFilterRange}"; + } + $docSheet->getAutoFilter()->setRange($autoFilterRange); + } } break; diff --git a/Examples/35chartrender.php b/Examples/35chartrender.php index 710cddb49..f0e79636b 100644 --- a/Examples/35chartrender.php +++ b/Examples/35chartrender.php @@ -46,7 +46,7 @@ // Change these values to select the Rendering library that you wish to use // and its directory location on your server $rendererName = PHPExcel_Settings::CHART_RENDERER_JPGRAPH; -$rendererLibrary = 'jpgraph3.5.0b1/src'; +$rendererLibrary = 'jpgraph3.5.0b1/src/'; $rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary; diff --git a/changelog.txt b/changelog.txt index 51fc4a2cc..2754f3c15 100644 --- a/changelog.txt +++ b/changelog.txt @@ -28,6 +28,7 @@ Planned for v1.8.1 - Bugfix: (ymaerschalck) Work Item GH-405 - XML External Entity (XXE) Processing, different behaviour between simplexml_load_string() and simplexml_load_file(). - Bugfix: (MBaker) - Fix to ensure that current cell is maintained when executing formula calculations - Bugfix: (MBaker) Work Item GH-350 - Keep/set the value on Reader _loadSheetsOnly as NULL, courtesy of Restless-ET +- Bugfix: (MBaker) Work Item CP18105 - Loading an Excel 2007 spreadsheet throws an "Autofilter must be set on a range of cells" exception - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines From 5e703760187314e814d09af92a8dae144caaa134 Mon Sep 17 00:00:00 2001 From: z38 Date: Mon, 28 Jul 2014 16:27:52 +0200 Subject: [PATCH 247/467] Use normal array syntax to support PHP <5.4 --- Classes/PHPExcel/Writer/Excel2007/Chart.php | 84 ++++++++++----------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index d863734cf..ceb750ade 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -634,17 +634,17 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx $objWriter->endElement(); } - if (!is_null($majorGridlines->getLineStyleProperty(['arrow', 'head', 'type']))) { + if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) { $objWriter->startElement('a:headEnd'); - $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(['arrow', 'head', 'type'])); + $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type'))); $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('head', 'w')); $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('head', 'len')); $objWriter->endElement(); } - if (!is_null($majorGridlines->getLineStyleProperty(['arrow', 'end', 'type']))) { + if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) { $objWriter->startElement('a:tailEnd'); - $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(['arrow', 'end', 'type'])); + $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type'))); $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('end', 'w')); $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('end', 'len')); $objWriter->endElement(); @@ -679,23 +679,23 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx if (!is_null($majorGridlines->getShadowProperty('algn'))) { $objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn')); } - if (!is_null($majorGridlines->getShadowProperty(['size', 'sx']))) { - $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(['size', 'sx'])); + if (!is_null($majorGridlines->getShadowProperty(array('size', 'sx')))) { + $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(array('size', 'sx'))); } - if (!is_null($majorGridlines->getShadowProperty(['size', 'sy']))) { - $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(['size', 'sy'])); + if (!is_null($majorGridlines->getShadowProperty(array('size', 'sy')))) { + $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(array('size', 'sy'))); } - if (!is_null($majorGridlines->getShadowProperty(['size', 'kx']))) { - $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(['size', 'kx'])); + if (!is_null($majorGridlines->getShadowProperty(array('size', 'kx')))) { + $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(array('size', 'kx'))); } if (!is_null($majorGridlines->getShadowProperty('rotWithShape'))) { $objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape')); } - $objWriter->startElement("a:{$majorGridlines->getShadowProperty(['color', 'type'])}"); - $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'value'])); + $objWriter->startElement("a:{$majorGridlines->getShadowProperty(array('color', 'type'))}"); + $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'value'))); $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'alpha'])); + $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'alpha'))); $objWriter->endElement(); //end alpha $objWriter->endElement(); //end color:type @@ -741,17 +741,17 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx $objWriter->endElement(); } - if (!is_null($minorGridlines->getLineStyleProperty(['arrow', 'head', 'type']))) { + if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) { $objWriter->startElement('a:headEnd'); - $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(['arrow', 'head', 'type'])); + $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type'))); $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('head', 'w')); $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('head', 'len')); $objWriter->endElement(); } - if (!is_null($minorGridlines->getLineStyleProperty(['arrow', 'end', 'type']))) { + if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) { $objWriter->startElement('a:tailEnd'); - $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(['arrow', 'end', 'type'])); + $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type'))); $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('end', 'w')); $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('end', 'len')); $objWriter->endElement(); @@ -787,22 +787,22 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx if (!is_null($minorGridlines->getShadowProperty('algn'))) { $objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn')); } - if (!is_null($minorGridlines->getShadowProperty(['size', 'sx']))) { - $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(['size', 'sx'])); + if (!is_null($minorGridlines->getShadowProperty(array('size', 'sx')))) { + $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(array('size', 'sx'))); } - if (!is_null($minorGridlines->getShadowProperty(['size', 'sy']))) { - $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(['size', 'sy'])); + if (!is_null($minorGridlines->getShadowProperty(array('size', 'sy')))) { + $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(array('size', 'sy'))); } - if (!is_null($minorGridlines->getShadowProperty(['size', 'kx']))) { - $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(['size', 'kx'])); + if (!is_null($minorGridlines->getShadowProperty(array('size', 'kx')))) { + $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(array('size', 'kx'))); } if (!is_null($minorGridlines->getShadowProperty('rotWithShape'))) { $objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape')); } - $objWriter->startElement("a:{$minorGridlines->getShadowProperty(['color', 'type'])}"); - $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'value'])); + $objWriter->startElement("a:{$minorGridlines->getShadowProperty(array('color', 'type'))}"); + $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'value'))); $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'alpha'])); + $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'alpha'))); $objWriter->endElement(); //end alpha $objWriter->endElement(); //end color:type $objWriter->endElement(); //end shadow @@ -921,17 +921,17 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx $objWriter->endElement(); } - if (!is_null($xAxis->getLineStyleProperty(['arrow', 'head', 'type']))) { + if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'head', 'type')))) { $objWriter->startElement('a:headEnd'); - $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(['arrow', 'head', 'type'])); + $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'head', 'type'))); $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('head')); $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('head')); $objWriter->endElement(); } - if (!is_null($xAxis->getLineStyleProperty(['arrow', 'end', 'type']))) { + if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'end', 'type')))) { $objWriter->startElement('a:tailEnd'); - $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(['arrow', 'end', 'type'])); + $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'end', 'type'))); $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('end')); $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('end')); $objWriter->endElement(); @@ -944,10 +944,10 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx if (!is_null($xAxis->getGlowProperty('size'))) { $objWriter->startElement('a:glow'); $objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size')); - $objWriter->startElement("a:{$xAxis->getGlowProperty(['color','type'])}"); - $objWriter->writeAttribute('val', $xAxis->getGlowProperty(['color','value'])); + $objWriter->startElement("a:{$xAxis->getGlowProperty(array('color','type'))}"); + $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','value'))); $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $xAxis->getGlowProperty(['color','alpha'])); + $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','alpha'))); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); @@ -968,23 +968,23 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx if (!is_null($xAxis->getShadowProperty('algn'))) { $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn')); } - if (!is_null($xAxis->getShadowProperty(['size','sx']))) { - $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(['size','sx'])); + if (!is_null($xAxis->getShadowProperty(array('size','sx')))) { + $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(array('size','sx'))); } - if (!is_null($xAxis->getShadowProperty(['size','sy']))) { - $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(['size','sy'])); + if (!is_null($xAxis->getShadowProperty(array('size','sy')))) { + $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(array('size','sy'))); } - if (!is_null($xAxis->getShadowProperty(['size','kx']))) { - $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(['size','kx'])); + if (!is_null($xAxis->getShadowProperty(array('size','kx')))) { + $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(array('size','kx'))); } if (!is_null($xAxis->getShadowProperty('rotWithShape'))) { $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape')); } - $objWriter->startElement("a:{$xAxis->getShadowProperty(['color','type'])}"); - $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color','value'])); + $objWriter->startElement("a:{$xAxis->getShadowProperty(array('color','type'))}"); + $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','value'))); $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color','alpha'])); + $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','alpha'))); $objWriter->endElement(); $objWriter->endElement(); From 46e0758cbb8c9f76860c63828276a12b0cfdea22 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 2 Aug 2014 23:44:37 +0100 Subject: [PATCH 248/467] New example demonstrating linked drop-down validation lists --- Examples/39dropdown.php | 170 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 Examples/39dropdown.php diff --git a/Examples/39dropdown.php b/Examples/39dropdown.php new file mode 100644 index 000000000..c8e6b1b58 --- /dev/null +++ b/Examples/39dropdown.php @@ -0,0 +1,170 @@ +'); + +/** Include PHPExcel */ +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; + + +// Create new PHPExcel object +echo date('H:i:s') , " Create new PHPExcel object" , EOL; +$objPHPExcel = new PHPExcel(); + +// Set document properties +echo date('H:i:s') , " Set document properties" , EOL; +$objPHPExcel->getProperties() + ->setCreator("PHPOffice") + ->setLastModifiedBy("PHPOffice") + ->setTitle("PHPExcel Test Document") + ->setSubject("PHPExcel Test Document") + ->setDescription("Test document for PHPExcel, generated using PHP classes.") + ->setKeywords("Office PHPExcel php") + ->setCategory("Test result file"); + + +function transpose($value) { + return array($value); +} + +// Add some data +$continentColumn = 'D'; +$column = 'F'; + +foreach(glob('./data/continents/*') as $key => $filename) { + $continent = pathinfo($filename, PATHINFO_FILENAME); + echo "Loading $continent", EOL; + $continent = str_replace(' ','_',$continent); + $countries = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + $countryCount = count($countries); + + // Transpose $countries from a row to a column array + $countries = array_map('transpose', $countries); + $objPHPExcel->getActiveSheet() + ->fromArray($countries, null, $column . '1'); + $objPHPExcel->addNamedRange( + new PHPExcel_NamedRange( + $continent, + $objPHPExcel->getActiveSheet(), $column . '1:' . $column . $countryCount + ) + ); + $objPHPExcel->getActiveSheet() + ->getColumnDimension($column) + ->setVisible(false); + + $objPHPExcel->getActiveSheet() + ->setCellValue($continentColumn . ($key+1), $continent); + + ++$column; +} +$objPHPExcel->getActiveSheet() + ->getColumnDimension($continentColumn) + ->setVisible(false); + +$objPHPExcel->addNamedRange( + new PHPExcel_NamedRange( + 'Continents', + $objPHPExcel->getActiveSheet(), $continentColumn . '1:' . $continentColumn . ($key+1) + ) +); + + +$objPHPExcel->getActiveSheet() + ->setCellValue('A1', 'Continent:'); +$objPHPExcel->getActiveSheet() + ->setCellValue('B1', 'Select continent'); +$objPHPExcel->getActiveSheet() + ->setCellValue('B3', '=' . $column . 1); +$objPHPExcel->getActiveSheet() + ->setCellValue('B3', 'Select country'); +$objPHPExcel->getActiveSheet() + ->getStyle('A1:A3') + ->getFont()->setBold(true); + +$objValidation = $objPHPExcel->getActiveSheet() + ->getCell('B1') + ->getDataValidation(); +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST ) + ->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION ) + ->setAllowBlank(false) + ->setShowInputMessage(true) + ->setShowErrorMessage(true) + ->setShowDropDown(true) + ->setErrorTitle('Input error') + ->setError('Continent is not in the list.') + ->setPromptTitle('Pick from the list') + ->setPrompt('Please pick a continent from the drop-down list.') + ->setFormula1('=Continents'); + +$objPHPExcel->getActiveSheet() + ->setCellValue('A3', 'Country:'); +$objPHPExcel->getActiveSheet() + ->getStyle('A3') + ->getFont()->setBold(true); + +$objValidation = $objPHPExcel->getActiveSheet() + ->getCell('B3') + ->getDataValidation(); +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST ) + ->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION ) + ->setAllowBlank(false) + ->setShowInputMessage(true) + ->setShowErrorMessage(true) + ->setShowDropDown(true) + ->setErrorTitle('Input error') + ->setError('Country is not in the list.') + ->setPromptTitle('Pick from the list') + ->setPrompt('Please pick a country from the drop-down list.') + ->setFormula1('=INDIRECT($B$1)'); + + +$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(12); +$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(30); + + +// Set active sheet index to the first sheet, so Excel opens this as the first sheet +$objPHPExcel->setActiveSheetIndex(0); + +// Save Excel 2007 file +// This linked validation list method only seems to work for Excel2007, not for Excel5 +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; From 0d07a35fe5cc0315010d26f7845365b35f2824e5 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 2 Aug 2014 23:57:53 +0100 Subject: [PATCH 249/467] In-code comments and add data for linked validators example --- Examples/39dropdown.php | 5 ++ Examples/data/continents/Africa.txt | 54 ++++++++++++++++++++++ Examples/data/continents/Asia.txt | 44 ++++++++++++++++++ Examples/data/continents/Europe.txt | 47 +++++++++++++++++++ Examples/data/continents/North America.txt | 23 +++++++++ Examples/data/continents/Oceania.txt | 14 ++++++ Examples/data/continents/South America.txt | 12 +++++ 7 files changed, 199 insertions(+) create mode 100644 Examples/data/continents/Africa.txt create mode 100644 Examples/data/continents/Asia.txt create mode 100644 Examples/data/continents/Europe.txt create mode 100644 Examples/data/continents/North America.txt create mode 100644 Examples/data/continents/Oceania.txt create mode 100644 Examples/data/continents/South America.txt diff --git a/Examples/39dropdown.php b/Examples/39dropdown.php index c8e6b1b58..5dadc0992 100644 --- a/Examples/39dropdown.php +++ b/Examples/39dropdown.php @@ -61,6 +61,7 @@ function transpose($value) { $continentColumn = 'D'; $column = 'F'; +// Set data for dropdowns foreach(glob('./data/continents/*') as $key => $filename) { $continent = pathinfo($filename, PATHINFO_FILENAME); echo "Loading $continent", EOL; @@ -87,6 +88,8 @@ function transpose($value) { ++$column; } + +// Hide the dropdown data $objPHPExcel->getActiveSheet() ->getColumnDimension($continentColumn) ->setVisible(false); @@ -99,6 +102,7 @@ function transpose($value) { ); +// Set selection cells $objPHPExcel->getActiveSheet() ->setCellValue('A1', 'Continent:'); $objPHPExcel->getActiveSheet() @@ -111,6 +115,7 @@ function transpose($value) { ->getStyle('A1:A3') ->getFont()->setBold(true); +// Set linked validators $objValidation = $objPHPExcel->getActiveSheet() ->getCell('B1') ->getDataValidation(); diff --git a/Examples/data/continents/Africa.txt b/Examples/data/continents/Africa.txt new file mode 100644 index 000000000..407fa769a --- /dev/null +++ b/Examples/data/continents/Africa.txt @@ -0,0 +1,54 @@ +Algeria +Angola +Benin +Botswana +Burkina +Burundi +Cameroon +Cape Verde +Central African Republic +Chad +Comoros +Congo +Congo, Democratic Republic of +Djibouti +Egypt +Equatorial Guinea +Eritrea +Ethiopia +Gabon +Gambia +Ghana +Guinea +Guinea-Bissau +Ivory Coast +Kenya +Lesotho +Liberia +Libya +Madagascar +Malawi +Mali +Mauritania +Mauritius +Morocco +Mozambique +Namibia +Niger +Nigeria +Rwanda +Sao Tome and Principe +Senegal +Seychelles +Sierra Leone +Somalia +South Africa +South Sudan +Sudan +Swaziland +Tanzania +Togo +Tunisia +Uganda +Zambia +Zimbabwe diff --git a/Examples/data/continents/Asia.txt b/Examples/data/continents/Asia.txt new file mode 100644 index 000000000..9ce006c53 --- /dev/null +++ b/Examples/data/continents/Asia.txt @@ -0,0 +1,44 @@ +Afghanistan +Bahrain +Bangladesh +Bhutan +Brunei +Burma (Myanmar) +Cambodia +China +East Timor +India +Indonesia +Iran +Iraq +Israel +Japan +Jordan +Kazakhstan +Korea, North +Korea, South +Kuwait +Kyrgyzstan +Laos +Lebanon +Malaysia +Maldives +Mongolia +Nepal +Oman +Pakistan +Philippines +Qatar +Russian Federation +Saudi Arabia +Singapore +Sri Lanka +Syria +Tajikistan +Thailand +Turkey +Turkmenistan +United Arab Emirates +Uzbekistan +Vietnam +Yemen diff --git a/Examples/data/continents/Europe.txt b/Examples/data/continents/Europe.txt new file mode 100644 index 000000000..70c11607a --- /dev/null +++ b/Examples/data/continents/Europe.txt @@ -0,0 +1,47 @@ +Albania +Andorra +Armenia +Austria +Azerbaijan +Belarus +Belgium +Bosnia and Herzegovina +Bulgaria +Croatia +Cyprus +Czech Republic +Denmark +Estonia +Finland +France +Georgia +Germany +Greece +Hungary +Iceland +Ireland +Italy +Latvia +Liechtenstein +Lithuania +Luxembourg +Macedonia +Malta +Moldova +Monaco +Montenegro +Netherlands +Norway +Poland +Portugal +Romania +San Marino +Serbia +Slovakia +Slovenia +Spain +Sweden +Switzerland +Ukraine +United Kingdom +Vatican City diff --git a/Examples/data/continents/North America.txt b/Examples/data/continents/North America.txt new file mode 100644 index 000000000..5881ae132 --- /dev/null +++ b/Examples/data/continents/North America.txt @@ -0,0 +1,23 @@ +Antigua and Barbuda +Bahamas +Barbados +Belize +Canada +Costa Rica +Cuba +Dominica +Dominican Republic +El Salvador +Grenada +Guatemala +Haiti +Honduras +Jamaica +Mexico +Nicaragua +Panama +Saint Kitts and Nevis +Saint Lucia +Saint Vincent and the Grenadines +Trinidad and Tobago +United States diff --git a/Examples/data/continents/Oceania.txt b/Examples/data/continents/Oceania.txt new file mode 100644 index 000000000..cbdc896c1 --- /dev/null +++ b/Examples/data/continents/Oceania.txt @@ -0,0 +1,14 @@ +Australia +Fiji +Kiribati +Marshall Islands +Micronesia +Nauru +New Zealand +Palau +Papua New Guinea +Samoa +Solomon Islands +Tonga +Tuvalu +Vanuatu diff --git a/Examples/data/continents/South America.txt b/Examples/data/continents/South America.txt new file mode 100644 index 000000000..777ffbfb9 --- /dev/null +++ b/Examples/data/continents/South America.txt @@ -0,0 +1,12 @@ +Argentina +Bolivia +Brazil +Chile +Colombia +Ecuador +Guyana +Paraguay +Peru +Suriname +Uruguay +Venezuela From c2a04ab777b2659433cbf7f0c4de01a9ac9b1ba9 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 3 Aug 2014 00:22:49 +0100 Subject: [PATCH 250/467] Add new example to runall --- Examples/runall.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Examples/runall.php b/Examples/runall.php index 395e83e24..c65727eb1 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -97,6 +97,7 @@ , '36chartreadwritePDF.php' , '37page_layout_view.php' , '38cloneWorksheet.php' + , '39dropdown.php' , '40duplicateStyle.php' , 'OOCalcReader.php' , 'OOCalcReaderPCLZip.php' @@ -106,7 +107,7 @@ , 'GnumericReader.php' ); -// First, clear all results +// First, clear all previous run results foreach ($aTests as $sTest) { @unlink( str_replace('.php', '.xls', $sTest) ); @unlink( str_replace('.php', '.xlsx', $sTest) ); From 780cb7478209b82db236cb718f20f1e7850b3d5b Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 3 Aug 2014 22:02:46 +0100 Subject: [PATCH 251/467] URL Hyperlink data may not use the full length of the data field, but could instead be terminated by a null byte character --- Classes/PHPExcel/Reader/Excel5.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 97c3df3c4..f2893ece7 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -4562,6 +4562,9 @@ private function _readHyperLink() $offset += 4; // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); + $nullOffset = strpos($url, 0x00); + if ($nullOffset) + $url = substr($url,0,$nullOffset); $url .= $hasText ? '#' : ''; $offset += $us; break; From 14e5e806a7a366ff8352c503a808191c2887f2eb Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 5 Aug 2014 15:03:54 +0100 Subject: [PATCH 252/467] Bugfix: Fix to autoloader registration for backward compatibility with PHP 5.2.0 not accepting the prepend flag --- Classes/PHPExcel/Autoloader.php | 6 +++++- changelog.txt | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Autoloader.php b/Classes/PHPExcel/Autoloader.php index db0dbef14..f0b225163 100644 --- a/Classes/PHPExcel/Autoloader.php +++ b/Classes/PHPExcel/Autoloader.php @@ -55,7 +55,11 @@ public static function Register() { spl_autoload_register('__autoload'); } // Register ourselves with SPL - return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'), true, true); + if (version_compare(PHP_VERSION, '5.3.0') >= 0) { + return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'), true, true); + } else { + return spl_autoload_register(array('PHPExcel_Autoloader', 'Load')); + } } // function Register() diff --git a/changelog.txt b/changelog.txt index 2754f3c15..c20cf8799 100644 --- a/changelog.txt +++ b/changelog.txt @@ -29,6 +29,7 @@ Planned for v1.8.1 - Bugfix: (MBaker) - Fix to ensure that current cell is maintained when executing formula calculations - Bugfix: (MBaker) Work Item GH-350 - Keep/set the value on Reader _loadSheetsOnly as NULL, courtesy of Restless-ET - Bugfix: (MBaker) Work Item CP18105 - Loading an Excel 2007 spreadsheet throws an "Autofilter must be set on a range of cells" exception +- Bugfix: (MBaker) - Fix to autoloader registration for backward compatibility with PHP 5.2.0 not accepting the prepend flag - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines From bdb8b501563a4c35c78ede20130a47b7139bb796 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 6 Aug 2014 00:09:44 +0100 Subject: [PATCH 253/467] Use th rather than td for cells when in thead --- Classes/PHPExcel/Writer/HTML.php | 36 +++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index d8a18ee91..63c5d4787 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -412,11 +412,13 @@ public function generateSheetData() { //

? if ($row == $theadStart) { $html .= ' ' . PHP_EOL; + $cellType = 'th'; } // ? if ($row == $tbodyStart) { $html .= ' ' . PHP_EOL; + $cellType = 'td'; } // Write row if there are HTML table cells in it @@ -433,7 +435,7 @@ public function generateSheetData() { $rowData[$column] = ''; } } - $html .= $this->_generateRow($sheet, $rowData, $row - 1); + $html .= $this->_generateRow($sheet, $rowData, $row - 1, $cellType); } // ? @@ -751,6 +753,7 @@ public function buildCSS($generateSurroundingHTML = true) { // .gridlines td { } $css['.gridlines td']['border'] = '1px dotted black'; + $css['.gridlines th']['border'] = '1px dotted black'; // .b {} $css['.b']['text-align'] = 'center'; // BOOL @@ -773,6 +776,7 @@ public function buildCSS($generateSurroundingHTML = true) { // Calculate cell style hashes foreach ($this->_phpExcel->getCellXfCollection() as $index => $style) { $css['td.style' . $index] = $this->_createCSSStyle( $style ); + $css['th.style' . $index] = $this->_createCSSStyle( $style ); } // Fetch sheets @@ -1077,7 +1081,7 @@ private function _generateTableFooter() { * @return string * @throws PHPExcel_Writer_Exception */ - private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0) { + private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td') { if (is_array($pValues)) { // Construct HTML $html = ''; @@ -1122,9 +1126,15 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow $cssClass = 'column' . $colNum; } else { $cssClass = array(); - if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) { - $this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum]; - } + if ($cellType == 'th') { + if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum])) { + $this->_cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum]; + } + } else { + if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) { + $this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum]; + } + } } $colSpan = 1; $rowSpan = 1; @@ -1202,9 +1212,15 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow $cssClass .= ' style' . $cell->getXfIndex(); $cssClass .= ' ' . $cell->getDataType(); } else { - if (isset($this->_cssStyles['td.style' . $cell->getXfIndex()])) { - $cssClass = array_merge($cssClass, $this->_cssStyles['td.style' . $cell->getXfIndex()]); - } + if ($cellType == 'th') { + if (isset($this->_cssStyles['th.style' . $cell->getXfIndex()])) { + $cssClass = array_merge($cssClass, $this->_cssStyles['th.style' . $cell->getXfIndex()]); + } + } else { + if (isset($this->_cssStyles['td.style' . $cell->getXfIndex()])) { + $cssClass = array_merge($cssClass, $this->_cssStyles['td.style' . $cell->getXfIndex()]); + } + } // General horizontal alignment: Actual horizontal alignment depends on dataType $sharedStyle = $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() ); @@ -1244,7 +1260,7 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow // Write if ($writeCell) { // Column start - $html .= ' _useInlineCss) { $html .= ' class="' . $cssClass . '"'; } else { @@ -1291,7 +1307,7 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow $html .= $cellData; // Column end - $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; } // Next column From 125f39c745bab95ba5be7e4a3f030ef6ae3ce52e Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 16 Aug 2014 11:12:32 +0100 Subject: [PATCH 254/467] Minor performance tweak to PHPTemp and DiscISAM caching --- Classes/PHPExcel/CachedObjectStorage/DiscISAM.php | 10 +++++----- Classes/PHPExcel/CachedObjectStorage/PHPTemp.php | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php index 96cb1e237..c46cdd95b 100644 --- a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php +++ b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php @@ -69,11 +69,11 @@ protected function _storeData() { $this->_currentObject->detach(); fseek($this->_fileHandle,0,SEEK_END); - $offset = ftell($this->_fileHandle); - fwrite($this->_fileHandle, serialize($this->_currentObject)); - $this->_cellCache[$this->_currentObjectID] = array('ptr' => $offset, - 'sz' => ftell($this->_fileHandle) - $offset - ); + + $this->_cellCache[$this->_currentObjectID] = array( + 'ptr' => ftell($this->_fileHandle), + 'sz' => fwrite($this->_fileHandle, serialize($this->_currentObject)) + ); $this->_currentCellIsDirty = false; } $this->_currentObjectID = $this->_currentObject = null; diff --git a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php index 1e36e1046..e28429dec 100644 --- a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php +++ b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php @@ -61,11 +61,11 @@ protected function _storeData() { $this->_currentObject->detach(); fseek($this->_fileHandle,0,SEEK_END); - $offset = ftell($this->_fileHandle); - fwrite($this->_fileHandle, serialize($this->_currentObject)); - $this->_cellCache[$this->_currentObjectID] = array('ptr' => $offset, - 'sz' => ftell($this->_fileHandle) - $offset - ); + + $this->_cellCache[$this->_currentObjectID] = array( + 'ptr' => ftell($this->_fileHandle), + 'sz' => fwrite($this->_fileHandle, serialize($this->_currentObject)) + ); $this->_currentCellIsDirty = false; } $this->_currentObjectID = $this->_currentObject = null; From cdaabc57f19cba48e2c912b70dc2aa823ae26e06 Mon Sep 17 00:00:00 2001 From: Nicolas Vanheuverzwijn Date: Sat, 16 Aug 2014 14:55:11 -0400 Subject: [PATCH 255/467] Fix indentation in documentation --- Classes/PHPExcel/Worksheet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index e53c22835..6215be8b1 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -2545,7 +2545,7 @@ public function toArray($nullValue = null, $calculateFormulas = true, $formatDat /** * Get row iterator * - * @param integer $startRow The row number at which to start iterating + * @param integer $startRow The row number at which to start iterating * @return PHPExcel_Worksheet_RowIterator */ public function getRowIterator($startRow = 1) { From d777d0283d35af6eda09ae131ed08042e97d5688 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 17 Aug 2014 18:15:44 +0100 Subject: [PATCH 256/467] Support for cell readorder Context/LTR/RTL --- Classes/PHPExcel/Reader/Excel2007.php | 1 + Classes/PHPExcel/Style/Alignment.php | 91 ++++++++++++++++----- Classes/PHPExcel/Writer/Excel2007/Style.php | 3 + 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index d5c947ee5..afe3b5c8e 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1893,6 +1893,7 @@ private static function _readStyle($docStyle, $style) { $docStyle->getAlignment()->setWrapText(self::boolean((string) $style->alignment["wrapText"])); $docStyle->getAlignment()->setShrinkToFit(self::boolean((string) $style->alignment["shrinkToFit"])); $docStyle->getAlignment()->setIndent( intval((string)$style->alignment["indent"]) > 0 ? intval((string)$style->alignment["indent"]) : 0 ); + $docStyle->getAlignment()->setReadorder( intval((string)$style->alignment["readingOrder"]) > 0 ? intval((string)$style->alignment["readingOrder"]) : 0 ); } // protection diff --git a/Classes/PHPExcel/Style/Alignment.php b/Classes/PHPExcel/Style/Alignment.php index 7577da537..00825debf 100644 --- a/Classes/PHPExcel/Style/Alignment.php +++ b/Classes/PHPExcel/Style/Alignment.php @@ -36,49 +36,54 @@ class PHPExcel_Style_Alignment extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable { /* Horizontal alignment styles */ - const HORIZONTAL_GENERAL = 'general'; - const HORIZONTAL_LEFT = 'left'; - const HORIZONTAL_RIGHT = 'right'; - const HORIZONTAL_CENTER = 'center'; - const HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous'; - const HORIZONTAL_JUSTIFY = 'justify'; - const HORIZONTAL_FILL = 'fill'; - const HORIZONTAL_DISTRIBUTED = 'distributed'; // Excel2007 only + const HORIZONTAL_GENERAL = 'general'; + const HORIZONTAL_LEFT = 'left'; + const HORIZONTAL_RIGHT = 'right'; + const HORIZONTAL_CENTER = 'center'; + const HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous'; + const HORIZONTAL_JUSTIFY = 'justify'; + const HORIZONTAL_FILL = 'fill'; + const HORIZONTAL_DISTRIBUTED = 'distributed'; // Excel2007 only /* Vertical alignment styles */ - const VERTICAL_BOTTOM = 'bottom'; - const VERTICAL_TOP = 'top'; - const VERTICAL_CENTER = 'center'; - const VERTICAL_JUSTIFY = 'justify'; - const VERTICAL_DISTRIBUTED = 'distributed'; // Excel2007 only + const VERTICAL_BOTTOM = 'bottom'; + const VERTICAL_TOP = 'top'; + const VERTICAL_CENTER = 'center'; + const VERTICAL_JUSTIFY = 'justify'; + const VERTICAL_DISTRIBUTED = 'distributed'; // Excel2007 only + + /* Read order */ + const READORDER_CONTEXT = 0; + const READORDER_LTR = 1; + const READORDER_RTL = 2; /** - * Horizontal + * Horizontal alignment * * @var string */ - protected $_horizontal = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + protected $_horizontal = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; /** - * Vertical + * Vertical alignment * * @var string */ - protected $_vertical = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; + protected $_vertical = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; /** * Text rotation * - * @var int + * @var integer */ - protected $_textRotation = 0; + protected $_textRotation = 0; /** * Wrap text * * @var boolean */ - protected $_wrapText = FALSE; + protected $_wrapText = FALSE; /** * Shrink to fit @@ -90,9 +95,16 @@ class PHPExcel_Style_Alignment extends PHPExcel_Style_Supervisor implements PHPE /** * Indent - only possible with horizontal alignment left and right * - * @var int + * @var integer */ - protected $_indent = 0; + protected $_indent = 0; + + /** + * Read order + * + * @var integer + */ + protected $_readorder = 0; /** * Create a new PHPExcel_Style_Alignment @@ -180,6 +192,9 @@ public function applyFromArray($pStyles = NULL) { if (isset($pStyles['indent'])) { $this->setIndent($pStyles['indent']); } + if (isset($pStyles['readorder'])) { + $this->setReadorder($pStyles['readorder']); + } } } else { throw new PHPExcel_Exception("Invalid style array passed."); @@ -389,6 +404,37 @@ public function setIndent($pValue = 0) { return $this; } + /** + * Get read order + * + * @return integer + */ + public function getReadorder() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getReadorder(); + } + return $this->_readorder; + } + + /** + * Set read order + * + * @param int $pValue + * @return PHPExcel_Style_Alignment + */ + public function setReadorder($pValue = 0) { + if ($pValue < 0 || $pValue > 2) { + $pValue = 0; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('readorder' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_readorder = $pValue; + } + return $this; + } + /** * Get hash code * @@ -405,6 +451,7 @@ public function getHashCode() { . ($this->_wrapText ? 't' : 'f') . ($this->_shrinkToFit ? 't' : 'f') . $this->_indent + . $this->_readorder . __CLASS__ ); } diff --git a/Classes/PHPExcel/Writer/Excel2007/Style.php b/Classes/PHPExcel/Writer/Excel2007/Style.php index 9857043b8..d38c6eacc 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Style.php +++ b/Classes/PHPExcel/Writer/Excel2007/Style.php @@ -439,6 +439,9 @@ private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, if ($pStyle->getAlignment()->getIndent() > 0) { $objWriter->writeAttribute('indent', $pStyle->getAlignment()->getIndent()); } + if ($pStyle->getAlignment()->getReadorder() > 0) { + $objWriter->writeAttribute('readingOrder', $pStyle->getAlignment()->getReadorder()); + } $objWriter->endElement(); // protection From a7cf8c63e20822fe58e2af89047dc3af7b6615d6 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 23 Aug 2014 13:54:21 +0100 Subject: [PATCH 257/467] Bugfix: Work Item GH-384 - DOM loadHTMLFile() failing with options flags when using PHP < 5.4.0 --- Classes/PHPExcel/CachedObjectStorage/DiscISAM.php | 4 ++-- Classes/PHPExcel/Reader/HTML.php | 11 ++++++----- changelog.txt | 1 + 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php index c46cdd95b..cb38d0de4 100644 --- a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php +++ b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php @@ -122,8 +122,8 @@ public function getCacheData($pCoord) { // Set current entry to the requested entry $this->_currentObjectID = $pCoord; - fseek($this->_fileHandle,$this->_cellCache[$pCoord]['ptr']); - $this->_currentObject = unserialize(fread($this->_fileHandle,$this->_cellCache[$pCoord]['sz'])); + fseek($this->_fileHandle, $this->_cellCache[$pCoord]['ptr']); + $this->_currentObject = unserialize(fread($this->_fileHandle, $this->_cellCache[$pCoord]['sz'])); // Re-attach this as the cell's parent $this->_currentObject->attach($this); diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index ec074f5ac..3a59bb16b 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -424,9 +424,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Create a new DOM object $dom = new DOMDocument; // Reload the HTML file into the DOM object - $loaded = $dom->loadHTMLFile($pFilename, PHPExcel_Settings::getLibXmlLoaderOptions()); + if (version_compare(PHP_VERSION, '5.4.0') >= 0) { + $loaded = $dom->loadHTMLFile($pFilename, PHPExcel_Settings::getLibXmlLoaderOptions()); + } else { + $loaded = $dom->loadHTMLFile($pFilename); + } if ($loaded === FALSE) { - throw new PHPExcel_Reader_Exception('Failed to load ',$pFilename,' as a DOM Document'); + throw new PHPExcel_Reader_Exception('Failed to load '. $pFilename. ' as a DOM Document'); } // Discard white space @@ -438,9 +442,6 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $content = ''; $this->_processDomElement($dom,$objPHPExcel->getActiveSheet(),$row,$column,$content); -// echo '
'; -// var_dump($this->_dataArray); - // Return return $objPHPExcel; } diff --git a/changelog.txt b/changelog.txt index c20cf8799..13f434e49 100644 --- a/changelog.txt +++ b/changelog.txt @@ -30,6 +30,7 @@ Planned for v1.8.1 - Bugfix: (MBaker) Work Item GH-350 - Keep/set the value on Reader _loadSheetsOnly as NULL, courtesy of Restless-ET - Bugfix: (MBaker) Work Item CP18105 - Loading an Excel 2007 spreadsheet throws an "Autofilter must be set on a range of cells" exception - Bugfix: (MBaker) - Fix to autoloader registration for backward compatibility with PHP 5.2.0 not accepting the prepend flag +- Bugfix: (MBaker) Work Item GH-384 - DOM loadHTMLFile() failing with options flags when using PHP < 5.4.0 - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines From 99f4ebab0cb713a29b99d1ff5404ff989cb25d49 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 27 Aug 2014 22:07:24 +0100 Subject: [PATCH 258/467] Remove unused lineEnding methods from CSV Reader --- Classes/PHPExcel/Reader/CSV.php | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index 043aeecf5..22176fdc9 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -68,14 +68,6 @@ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_R */ private $_enclosure = '"'; - /** - * Line ending - * - * @access private - * @var string - */ - private $_lineEnding = PHP_EOL; - /** * Sheet index to read * @@ -348,26 +340,6 @@ public function setEnclosure($pValue = '"') { return $this; } - /** - * Get line ending - * - * @return string - */ - public function getLineEnding() { - return $this->_lineEnding; - } - - /** - * Set line ending - * - * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) - * @return PHPExcel_Reader_CSV - */ - public function setLineEnding($pValue = PHP_EOL) { - $this->_lineEnding = $pValue; - return $this; - } - /** * Get sheet index * From ba1e16d630468c332647714208f246192a026170 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 27 Aug 2014 23:27:11 +0100 Subject: [PATCH 259/467] Bugfix: - Fix for percentage operator in formulae for BIFF Writer --- Classes/PHPExcel/Writer/Excel5/Parser.php | 1 + changelog.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/Classes/PHPExcel/Writer/Excel5/Parser.php b/Classes/PHPExcel/Writer/Excel5/Parser.php index 7bdc1c0bc..bc6ddb132 100644 --- a/Classes/PHPExcel/Writer/Excel5/Parser.php +++ b/Classes/PHPExcel/Writer/Excel5/Parser.php @@ -1430,6 +1430,7 @@ function _fact() { if($this->_lookahead == '%'){ $result = $this->_createTree('ptgPercent', $this->_current_token, ''); + $this->_advance(); // Skip the percentage operator once we've pre-built that tree } else { $result = $this->_createTree($this->_current_token, '', ''); } diff --git a/changelog.txt b/changelog.txt index 13f434e49..8e4a5f6e5 100644 --- a/changelog.txt +++ b/changelog.txt @@ -31,6 +31,7 @@ Planned for v1.8.1 - Bugfix: (MBaker) Work Item CP18105 - Loading an Excel 2007 spreadsheet throws an "Autofilter must be set on a range of cells" exception - Bugfix: (MBaker) - Fix to autoloader registration for backward compatibility with PHP 5.2.0 not accepting the prepend flag - Bugfix: (MBaker) Work Item GH-384 - DOM loadHTMLFile() failing with options flags when using PHP < 5.4.0 +- Bugfix: (MBaker) - Fix for percentage operator in formulae for BIFF Writer - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines From 280620a753fc098567fdc6ed24675abb44f3f3de Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 30 Aug 2014 00:12:31 +0100 Subject: [PATCH 260/467] Implement Excel VALUE() function, locale-warts and all --- Classes/PHPExcel/Calculation.php | 2 +- Classes/PHPExcel/Calculation/TextData.php | 45 ++++++++++++++++++- Documentation/FunctionListByCategory.txt | 2 +- Documentation/FunctionListByName.txt | 2 +- .../PHPExcel/Calculation/TextDataTest.php | 20 +++++++++ .../Calculation/TextData/VALUE.data | 10 +++++ 6 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 unitTests/rawTestData/Calculation/TextData/VALUE.data diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index c159012b3..4de70eb27 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -1628,7 +1628,7 @@ class PHPExcel_Calculation { 'argumentCount' => '2' ), 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', 'argumentCount' => '1' ), 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php index 73a0d0cd7..7a52d2e7f 100644 --- a/Classes/PHPExcel/Calculation/TextData.php +++ b/Classes/PHPExcel/Calculation/TextData.php @@ -104,7 +104,7 @@ public static function TRIMNONPRINTABLE($stringValue = '') { } if (is_string($stringValue) || is_numeric($stringValue)) { - return str_replace(self::$_invalidChars,'',trim($stringValue,"\x00..\x1F")); + return str_replace(self::$_invalidChars, '', trim($stringValue, "\x00..\x1F")); } return NULL; } // function TRIMNONPRINTABLE() @@ -587,4 +587,45 @@ public static function TEXTFORMAT($value,$format) { return (string) PHPExcel_Style_NumberFormat::toFormattedString($value,$format); } // function TEXTFORMAT() -} // class PHPExcel_Calculation_TextData + /** + * VALUE + * + * @param mixed $value Value to check + * @return boolean + */ + public static function VALUE($value = '') { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (!is_numeric($value)) { + $numberValue = str_replace( + PHPExcel_Shared_String::getThousandsSeparator(), + '', + trim($value, " \t\n\r\0\x0B" . PHPExcel_Shared_String::getCurrencyCode()) + ); + if (is_numeric($numberValue)) { + return (float) $numberValue; + } + + $dateSetting = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + + if (strpos($value, ':') !== false) { + $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($value); + if ($timeValue !== PHPExcel_Calculation_Functions::VALUE()) { + PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); + return $timeValue; + } + } + $dateValue = PHPExcel_Calculation_DateTime::DATEVALUE($value); + if ($dateValue !== PHPExcel_Calculation_Functions::VALUE()) { + PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); + return $dateValue; + } + PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); + + return PHPExcel_Calculation_Functions::VALUE(); + } + return (float) $value; + } + +} diff --git a/Documentation/FunctionListByCategory.txt b/Documentation/FunctionListByCategory.txt index 1c3ec5c27..b23d9a11c 100644 --- a/Documentation/FunctionListByCategory.txt +++ b/Documentation/FunctionListByCategory.txt @@ -374,4 +374,4 @@ CATEGORY_TEXT_AND_DATA TEXT PHPExcel_Calculation_TextData::TEXTFORMAT TRIM PHPExcel_Calculation_TextData::TRIMSPACES UPPER PHPExcel_Calculation_TextData::UPPERCASE - VALUE *** Not yet Implemented + VALUE PHPExcel_Calculation_TextData::VALUE diff --git a/Documentation/FunctionListByName.txt b/Documentation/FunctionListByName.txt index 02e2f0632..45a9daf73 100644 --- a/Documentation/FunctionListByName.txt +++ b/Documentation/FunctionListByName.txt @@ -355,7 +355,7 @@ TYPE CATEGORY_INFORMATION PHPExcel_Calculation_Fun UPPER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::UPPERCASE USDOLLAR CATEGORY_FINANCIAL *** Not yet Implemented -VALUE CATEGORY_TEXT_AND_DATA *** Not yet Implemented +VALUE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::VALUE VAR CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARFunc VARA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARA VARP CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARP diff --git a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php index 717e8fefb..ea7882b6c 100644 --- a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php @@ -340,4 +340,24 @@ public function providerTEXT() return new testDataFileIterator('rawTestData/Calculation/TextData/TEXT.data'); } + /** + * @dataProvider providerVALUE + */ + public function testVALUE() + { + call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.'); + call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),' '); + call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$'); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','VALUE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerVALUE() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/VALUE.data'); + } + } diff --git a/unitTests/rawTestData/Calculation/TextData/VALUE.data b/unitTests/rawTestData/Calculation/TextData/VALUE.data new file mode 100644 index 000000000..505c2915b --- /dev/null +++ b/unitTests/rawTestData/Calculation/TextData/VALUE.data @@ -0,0 +1,10 @@ +"1000", "1000" +"1 000", "1000" +"$1 000", "1000" +"£1 000", "#VALUE!" +"1.1", "1.1" +"1 000.1", "1000.1" +"13 Monkeys", "#VALUE!" +"1-Jan-2014", "41640" +"12:34:56", "0.524259259259259" +"2:46 AM", "0.11527777777778" From 86a598f3ae11fed9ae63b7d11dbe8d3020746e5f Mon Sep 17 00:00:00 2001 From: William Crandell Date: Mon, 1 Sep 2014 03:09:52 -0500 Subject: [PATCH 261/467] Fix for substitute value is ZERO=0 --- Classes/PHPExcel/Calculation/Functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index 9a139ec79..7f6240141 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -710,7 +710,7 @@ function mb_str_replace($search, $replace, $subject) { } foreach((array) $search as $key => $s) { - if($s == '') { + if($s == '' && $s !== 0) { continue; } $r = !is_array($replace) ? $replace : (array_key_exists($key, $replace) ? $replace[$key] : ''); From 66b9ffa8ac5aa75cc1e39c3e45061e3fb82d74f0 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 3 Sep 2014 22:43:59 +0100 Subject: [PATCH 262/467] Minor tweaks to cell constructor --- Classes/PHPExcel/Cell.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 7f0dd1a5a..521b7bf82 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -88,7 +88,7 @@ class PHPExcel_Cell * * @var int */ - private $_xfIndex; + private $_xfIndex = 0; /** * Attributes of the formula @@ -113,8 +113,6 @@ public function detach() { } public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) { - - $this->_parent = $parent; } @@ -140,14 +138,9 @@ public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Workshee if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; $this->_dataType = $pDataType; - } else { - if (!self::getValueBinder()->bindValue($this, $pValue)) { - throw new PHPExcel_Exception("Value could not be bound to cell."); - } + } elseif (!self::getValueBinder()->bindValue($this, $pValue)) { + throw new PHPExcel_Exception("Value could not be bound to cell."); } - - // set default index to cellXf - $this->_xfIndex = 0; } /** From 57ce19d20a09a9066c66b250704a5b019aebb3e0 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 5 Sep 2014 10:17:39 +0100 Subject: [PATCH 263/467] Remove references to PHP versions < 5.2 --- Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php index 5145206e7..0736fc232 100644 --- a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php +++ b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php @@ -161,14 +161,6 @@ public function stream_read($count) */ public function stream_eof() { -// As we don't support below 5.2 anymore, this is simply redundancy and overhead -// $eof = $this->pos >= strlen($this->data); -// // Workaround for bug in PHP 5.0.x: http://bugs.php.net/27508 -// if (version_compare(PHP_VERSION, '5.0', '>=') && -// version_compare(PHP_VERSION, '5.1', '<')) { -// $eof = !$eof; -// } -// return $eof; return $this->pos >= strlen($this->data); } From f77d3d166814c8796181a1b838cfcb9767d3d03d Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 5 Sep 2014 10:20:12 +0100 Subject: [PATCH 264/467] Bugfix: Work Item GH-384 - DOM loadHTMLFile() failing with options flags when using PHP < 5.4.0 Additional check that libxml is running at an appropriate version by testing if libxml flag value constants are defined --- Classes/PHPExcel/Reader/HTML.php | 2 +- Classes/PHPExcel/Settings.php | 12 ++++++++---- changelog.txt | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 3a59bb16b..6adcc857a 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -424,7 +424,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Create a new DOM object $dom = new DOMDocument; // Reload the HTML file into the DOM object - if (version_compare(PHP_VERSION, '5.4.0') >= 0) { + if ((version_compare(PHP_VERSION, '5.4.0') >= 0) && defined(LIBXML_DTDLOAD)) { $loaded = $dom->loadHTMLFile($pFilename, PHPExcel_Settings::getLibXmlLoaderOptions()); } else { $loaded = $dom->loadHTMLFile($pFilename); diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php index d9d197a55..c78d9350d 100644 --- a/Classes/PHPExcel/Settings.php +++ b/Classes/PHPExcel/Settings.php @@ -363,10 +363,12 @@ public static function getPdfRendererPath() */ public static function setLibXmlLoaderOptions($options = null) { - if (is_null($options)) { + if (is_null($options) && defined(LIBXML_DTDLOAD)) { $options = LIBXML_DTDLOAD | LIBXML_DTDATTR; } - @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + if (version_compare(PHP_VERSION, '5.2.11') >= 0) { + @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + } self::$_libXmlLoaderOptions = $options; } // function setLibXmlLoaderOptions @@ -378,10 +380,12 @@ public static function setLibXmlLoaderOptions($options = null) */ public static function getLibXmlLoaderOptions() { - if (is_null(self::$_libXmlLoaderOptions)) { + if (is_null(self::$_libXmlLoaderOptions) && defined(LIBXML_DTDLOAD)) { self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR); } - @libxml_disable_entity_loader(self::$_libXmlLoaderOptions == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + if (version_compare(PHP_VERSION, '5.2.11') >= 0) { + @libxml_disable_entity_loader(self::$_libXmlLoaderOptions == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + } return self::$_libXmlLoaderOptions; } // function getLibXmlLoaderOptions } diff --git a/changelog.txt b/changelog.txt index 8e4a5f6e5..12794548c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -29,7 +29,7 @@ Planned for v1.8.1 - Bugfix: (MBaker) - Fix to ensure that current cell is maintained when executing formula calculations - Bugfix: (MBaker) Work Item GH-350 - Keep/set the value on Reader _loadSheetsOnly as NULL, courtesy of Restless-ET - Bugfix: (MBaker) Work Item CP18105 - Loading an Excel 2007 spreadsheet throws an "Autofilter must be set on a range of cells" exception -- Bugfix: (MBaker) - Fix to autoloader registration for backward compatibility with PHP 5.2.0 not accepting the prepend flag +- Bugfix: (MBaker) Work Item GH-388 - Fix to autoloader registration for backward compatibility with PHP 5.2.0 not accepting the prepend flag - Bugfix: (MBaker) Work Item GH-384 - DOM loadHTMLFile() failing with options flags when using PHP < 5.4.0 - Bugfix: (MBaker) - Fix for percentage operator in formulae for BIFF Writer - General: (MBaker) - Small performance improvement for autosize columns From fdfd36cc04d502a7afcae5f5f54cdfd987889c9e Mon Sep 17 00:00:00 2001 From: David de Boer Date: Mon, 8 Sep 2014 17:16:31 +0200 Subject: [PATCH 265/467] Improve sheet index error handling Fix 'Undefined offset: -1' warning, thrown when worksheets could not be parsed and _activeSheetIndex equals -1. --- Classes/PHPExcel.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index e01581a24..27aa77ae7 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -461,10 +461,12 @@ public function setSecurity(PHPExcel_DocumentSecurity $pValue) * Get active sheet * * @return PHPExcel_Worksheet + * + * @throws PHPExcel_Exception */ public function getActiveSheet() { - return $this->_workSheetCollection[$this->_activeSheetIndex]; + return $this->getSheet($this->_activeSheetIndex); } /** @@ -570,16 +572,14 @@ public function removeSheetByIndex($pIndex = 0) */ public function getSheet($pIndex = 0) { - - $numSheets = count($this->_workSheetCollection); - - if ($pIndex > $numSheets - 1) { + if (!isset($this->_workSheetCollection[$pIndex])) { + $numSheets = $this->getSheetCount(); throw new PHPExcel_Exception( - "Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}." - ); - } else { - return $this->_workSheetCollection[$pIndex]; + "Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}." + ); } + + return $this->_workSheetCollection[$pIndex]; } /** @@ -682,7 +682,7 @@ public function getActiveSheetIndex() */ public function setActiveSheetIndex($pIndex = 0) { - $numSheets = count($this->_workSheetCollection); + $numSheets = count($this->_workSheetCollection); if ($pIndex > $numSheets - 1) { throw new PHPExcel_Exception( From 31d60ad524e6d6351af44019518cef58aea48a6c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 9 Sep 2014 23:57:16 +0100 Subject: [PATCH 266/467] Fix to getStyle() call for cell object --- Classes/PHPExcel/Cell.php | 4 ++-- changelog.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 521b7bf82..2d5f9102d 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -192,7 +192,7 @@ public function getFormattedValue() { return (string) PHPExcel_Style_NumberFormat::toFormattedString( $this->getCalculatedValue(), - $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex()) + $this->getStyle() ->getNumberFormat()->getFormatCode() ); } @@ -535,7 +535,7 @@ public function getMergeRange() { */ public function getStyle() { - return $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex()); + return $this->getWorksheet()->getStyle($this->getCoordinate()); } /** diff --git a/changelog.txt b/changelog.txt index 12794548c..bf13da499 100644 --- a/changelog.txt +++ b/changelog.txt @@ -32,6 +32,7 @@ Planned for v1.8.1 - Bugfix: (MBaker) Work Item GH-388 - Fix to autoloader registration for backward compatibility with PHP 5.2.0 not accepting the prepend flag - Bugfix: (MBaker) Work Item GH-384 - DOM loadHTMLFile() failing with options flags when using PHP < 5.4.0 - Bugfix: (MBaker) - Fix for percentage operator in formulae for BIFF Writer +- Bugfix: (MBaker) - Fix to getStyle() call for cell object - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines From d4a641c5c70df1aac580a60fbb0dbee3bca1e3e1 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 9 Sep 2014 23:59:55 +0100 Subject: [PATCH 267/467] General: Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric --- Classes/PHPExcel/Cell/DefaultValueBinder.php | 16 +++++----------- changelog.txt | 1 + 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Classes/PHPExcel/Cell/DefaultValueBinder.php b/Classes/PHPExcel/Cell/DefaultValueBinder.php index 67a4b5f68..59a9c7137 100644 --- a/Classes/PHPExcel/Cell/DefaultValueBinder.php +++ b/Classes/PHPExcel/Cell/DefaultValueBinder.php @@ -76,31 +76,25 @@ public static function dataTypeForValue($pValue = null) { // Match the value against a few data types if (is_null($pValue)) { return PHPExcel_Cell_DataType::TYPE_NULL; - } elseif ($pValue === '') { return PHPExcel_Cell_DataType::TYPE_STRING; - } elseif ($pValue instanceof PHPExcel_RichText) { return PHPExcel_Cell_DataType::TYPE_INLINE; - } elseif ($pValue{0} === '=' && strlen($pValue) > 1) { return PHPExcel_Cell_DataType::TYPE_FORMULA; - } elseif (is_bool($pValue)) { return PHPExcel_Cell_DataType::TYPE_BOOL; - } elseif (is_float($pValue) || is_int($pValue)) { return PHPExcel_Cell_DataType::TYPE_NUMERIC; - } elseif (preg_match('/^\-?([0-9]+\\.?[0-9]*|[0-9]*\\.?[0-9]+)$/', $pValue)) { + if (is_string($pValue) && $pValue{0} === '0' && strlen($pValue) > 1 && $pValue{1} !== '.' ) { + return PHPExcel_Cell_DataType::TYPE_STRING; + } return PHPExcel_Cell_DataType::TYPE_NUMERIC; - } elseif (is_string($pValue) && array_key_exists($pValue, PHPExcel_Cell_DataType::getErrorCodes())) { return PHPExcel_Cell_DataType::TYPE_ERROR; - - } else { - return PHPExcel_Cell_DataType::TYPE_STRING; - } + + return PHPExcel_Cell_DataType::TYPE_STRING; } } diff --git a/changelog.txt b/changelog.txt index bf13da499..2e4c36e64 100644 --- a/changelog.txt +++ b/changelog.txt @@ -35,6 +35,7 @@ Planned for v1.8.1 - Bugfix: (MBaker) - Fix to getStyle() call for cell object - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case +- General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines - Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions From 548ff7c3e3dcacc594490601b3937d9e856f59ac Mon Sep 17 00:00:00 2001 From: masanaikeshima Date: Wed, 10 Sep 2014 15:49:54 +0100 Subject: [PATCH 268/467] Fixing Pie Chart example to display pie charts I have noticed that this example is currently throwing the following error when opening the produced Excel Spreadsheet - "We found a problem with some content in .xlsx. Do you want us to try to recover as much as we can? If you trust the source of this workbook click Yes". In order to fix this I have set the removed the PlotGrouping setting (currently PHPExcel_Chart_DataSeries::GROUPING_STANDARD) to NULL and it appears to work. --- Examples/33chartcreate-pie.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/33chartcreate-pie.php b/Examples/33chartcreate-pie.php index e1e388fdd..6fb88f4e4 100644 --- a/Examples/33chartcreate-pie.php +++ b/Examples/33chartcreate-pie.php @@ -87,7 +87,7 @@ // Build the dataseries $series1 = new PHPExcel_Chart_DataSeries( PHPExcel_Chart_DataSeries::TYPE_PIECHART, // plotType - PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping + NULL, // plotGrouping range(0, count($dataSeriesValues1)-1), // plotOrder $dataSeriesLabels1, // plotLabel $xAxisTickValues1, // plotCategory @@ -161,7 +161,7 @@ // Build the dataseries $series2 = new PHPExcel_Chart_DataSeries( PHPExcel_Chart_DataSeries::TYPE_DONUTCHART, // plotType - PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping + NULL, // plotGrouping range(0, count($dataSeriesValues2)-1), // plotOrder $dataSeriesLabels2, // plotLabel $xAxisTickValues2, // plotCategory From c32dbfccc278514d5537aa37ae6b4eb49f81496a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 10 Sep 2014 17:27:03 +0100 Subject: [PATCH 269/467] Fixing Pie Chart example to display pie charts --- Examples/33chartcreate-pie.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/33chartcreate-pie.php b/Examples/33chartcreate-pie.php index e1e388fdd..be861fbfd 100644 --- a/Examples/33chartcreate-pie.php +++ b/Examples/33chartcreate-pie.php @@ -87,7 +87,7 @@ // Build the dataseries $series1 = new PHPExcel_Chart_DataSeries( PHPExcel_Chart_DataSeries::TYPE_PIECHART, // plotType - PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping + NULL, // plotGrouping range(0, count($dataSeriesValues1)-1), // plotOrder $dataSeriesLabels1, // plotLabel $xAxisTickValues1, // plotCategory @@ -161,7 +161,7 @@ // Build the dataseries $series2 = new PHPExcel_Chart_DataSeries( PHPExcel_Chart_DataSeries::TYPE_DONUTCHART, // plotType - PHPExcel_Chart_DataSeries::GROUPING_STANDARD, // plotGrouping + NULL, // plotGrouping range(0, count($dataSeriesValues2)-1), // plotOrder $dataSeriesLabels2, // plotLabel $xAxisTickValues2, // plotCategory From 01d6f7f1d5a0580ae2b801d1642e3b8196ea874f Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 10 Sep 2014 17:45:17 +0100 Subject: [PATCH 270/467] Bugfix: (masanaikeshima) Work Item GH-426 - Pie chart won't work in Excel 2013 --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 2e4c36e64..3bb1ab5c6 100644 --- a/changelog.txt +++ b/changelog.txt @@ -33,6 +33,7 @@ Planned for v1.8.1 - Bugfix: (MBaker) Work Item GH-384 - DOM loadHTMLFile() failing with options flags when using PHP < 5.4.0 - Bugfix: (MBaker) - Fix for percentage operator in formulae for BIFF Writer - Bugfix: (MBaker) - Fix to getStyle() call for cell object +- Bugfix: (masanaikeshima) Work Item GH-426 - Pie chart won't work in Excel 2013 - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric From 37b4d18d456e3b533d838099f208e5d3f089a954 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 13 Sep 2014 16:12:45 +0100 Subject: [PATCH 271/467] Minor fixes to cyclic references in formulae --- Classes/PHPExcel/Calculation.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 4de70eb27..fa89671fe 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2374,13 +2374,13 @@ public function saveValueToCache($worksheetName, $cellID, $cellValue) { * @throws PHPExcel_Calculation_Exception */ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) { - $cellValue = ''; + $cellValue = null; // Basic validation that this is indeed a formula // We simply return the cell value if not $formula = trim($formula); if ($formula{0} != '=') return self::_wrapResult($formula); - $formula = ltrim(substr($formula,1)); + $formula = ltrim(substr($formula, 1)); if (!isset($formula{0})) return self::_wrapResult($formula); $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; @@ -2392,20 +2392,23 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsTitle.'!'.$cellID))) { 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) { ++$this->_cyclicFormulaCount; if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { + $this->_cyclicFormulaCell = ''; return $cellValue; } } elseif ($this->_cyclicFormulaCell == '') { - $this->_cyclicFormulaCell = $wsTitle.'!'.$cellID; if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { return $cellValue; } + $this->_cyclicFormulaCell = $wsTitle.'!'.$cellID; } } From 26aa0b27f7d1df55183c23c9f4a0411bbe389b53 Mon Sep 17 00:00:00 2001 From: Loren Klingman Date: Wed, 15 Oct 2014 11:32:27 -0500 Subject: [PATCH 272/467] "No Impact" conditional formatting fix for NumberFormat --- Classes/PHPExcel/Style/NumberFormat.php | 1 + changelog.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index 0d7d93de2..e098f6f20 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -120,6 +120,7 @@ public function __construct($isSupervisor = FALSE, $isConditional = FALSE) if ($isConditional) { $this->_formatCode = NULL; + $this->_builtInFormatCode = FALSE; } } diff --git a/changelog.txt b/changelog.txt index 3bb1ab5c6..59a26519d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -42,6 +42,7 @@ Planned for v1.8.1 - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions - Feature: (bolovincev) Work Item GH-269 - Update Worksheet.php getStyleByColumnAndRow() to allow a range of cells rather than just a single cell - Feature: (MBaker) - New methods added for testing cell status within merge groups +- Bugfix: (wiseloren) Work Item CP21454 - "No Impact" conditional formatting fix for NumberFormat 2014-03-02 (v1.8.0): From 832421bbcabf89310fa47714319be5f88b205d4f Mon Sep 17 00:00:00 2001 From: chamaeleon-nitr Date: Mon, 10 Nov 2014 17:43:16 +0300 Subject: [PATCH 273/467] Bug in String.php In function IsUTF8 --- Classes/PHPExcel/Shared/String.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index fc86d537d..4921dc958 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -403,7 +403,7 @@ public static function SanitizeUTF8($value) * @return boolean */ public static function IsUTF8($value = '') { - return $string === '' || preg_match('/^./su', $string) === 1; + return $value === '' || preg_match('/^./su', $value) === 1; } /** From fdefb8e392cb0a7c0f8b62dd1fb0164b8a7b4236 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 11 Nov 2014 23:18:13 +0000 Subject: [PATCH 274/467] Discard Autofilters in Excel2007 Reader when filter range isn't a valid range --- Classes/PHPExcel/Reader/Excel2007.php | 205 +++++++++++----------- Classes/PHPExcel/Worksheet/AutoFilter.php | 6 +- changelog.txt | 2 + 3 files changed, 108 insertions(+), 105 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index afe3b5c8e..3b0c1a747 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1006,108 +1006,106 @@ public function load($pFilename) } if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { - $autoFilter = $docSheet->getAutoFilter(); - $autoFilterRange = (string) $xmlSheet->autoFilter["ref"]; - if (strpos($autoFilterRange, ':') === false) { - $autoFilterRange = "${autoFilterRange}:${autoFilterRange}"; - } - $autoFilter->setRange($autoFilterRange); - - foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { - $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); - // Check for standard filters - if ($filterColumn->filters) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER); - $filters = $filterColumn->filters; - if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - '' - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); - } - // Standard filters are always an OR join, so no join rule needs to be set - // Entries can be either filter elements - foreach ($filters->filter as $filterRule) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - (string) $filterRule["val"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); - } - // Or Date Group elements - foreach ($filters->dateGroupItem as $dateGroupItem) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - array( - 'year' => (string) $dateGroupItem["year"], - 'month' => (string) $dateGroupItem["month"], - 'day' => (string) $dateGroupItem["day"], - 'hour' => (string) $dateGroupItem["hour"], - 'minute' => (string) $dateGroupItem["minute"], - 'second' => (string) $dateGroupItem["second"], - ), - (string) $dateGroupItem["dateTimeGrouping"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); - } - } - // Check for custom filters - if ($filterColumn->customFilters) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER); - $customFilters = $filterColumn->customFilters; - // Custom filters can an AND or an OR join; - // and there should only ever be one or two entries - if ((isset($customFilters["and"])) && ($customFilters["and"] == 1)) { - $column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); - } - foreach ($customFilters->customFilter as $filterRule) { - $column->createRule()->setRule( - (string) $filterRule["operator"], - (string) $filterRule["val"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); - } - } - // Check for dynamic filters - if ($filterColumn->dynamicFilter) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); - // We should only ever have one dynamic filter - foreach ($filterColumn->dynamicFilter as $filterRule) { - $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL - (string) $filterRule["val"], - (string) $filterRule["type"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER); - if (isset($filterRule["val"])) { - $column->setAttribute('val',(string) $filterRule["val"]); - } - if (isset($filterRule["maxVal"])) { - $column->setAttribute('maxVal',(string) $filterRule["maxVal"]); - } - } - } - // Check for dynamic filters - if ($filterColumn->top10) { - $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER); - // We should only ever have one top10 filter - foreach ($filterColumn->top10 as $filterRule) { - $column->createRule()->setRule( - (((isset($filterRule["percent"])) && ($filterRule["percent"] == 1)) - ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT - : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE - ), - (string) $filterRule["val"], - (((isset($filterRule["top"])) && ($filterRule["top"] == 1)) - ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP - : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM - ) - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER); - } - } + if (strpos($autoFilterRange, ':') !== false) { + $autoFilter = $docSheet->getAutoFilter(); + $autoFilter->setRange($autoFilterRange); + + foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { + $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); + // Check for standard filters + if ($filterColumn->filters) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER); + $filters = $filterColumn->filters; + if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + '' + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + } + // Standard filters are always an OR join, so no join rule needs to be set + // Entries can be either filter elements + foreach ($filters->filter as $filterRule) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + (string) $filterRule["val"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + } + // Or Date Group elements + foreach ($filters->dateGroupItem as $dateGroupItem) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + array( + 'year' => (string) $dateGroupItem["year"], + 'month' => (string) $dateGroupItem["month"], + 'day' => (string) $dateGroupItem["day"], + 'hour' => (string) $dateGroupItem["hour"], + 'minute' => (string) $dateGroupItem["minute"], + 'second' => (string) $dateGroupItem["second"], + ), + (string) $dateGroupItem["dateTimeGrouping"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); + } + } + // Check for custom filters + if ($filterColumn->customFilters) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER); + $customFilters = $filterColumn->customFilters; + // Custom filters can an AND or an OR join; + // and there should only ever be one or two entries + if ((isset($customFilters["and"])) && ($customFilters["and"] == 1)) { + $column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); + } + foreach ($customFilters->customFilter as $filterRule) { + $column->createRule()->setRule( + (string) $filterRule["operator"], + (string) $filterRule["val"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); + } + } + // Check for dynamic filters + if ($filterColumn->dynamicFilter) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); + // We should only ever have one dynamic filter + foreach ($filterColumn->dynamicFilter as $filterRule) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + (string) $filterRule["val"], + (string) $filterRule["type"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER); + if (isset($filterRule["val"])) { + $column->setAttribute('val',(string) $filterRule["val"]); + } + if (isset($filterRule["maxVal"])) { + $column->setAttribute('maxVal',(string) $filterRule["maxVal"]); + } + } + } + // Check for dynamic filters + if ($filterColumn->top10) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER); + // We should only ever have one top10 filter + foreach ($filterColumn->top10 as $filterRule) { + $column->createRule()->setRule( + (((isset($filterRule["percent"])) && ($filterRule["percent"] == 1)) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE + ), + (string) $filterRule["val"], + (((isset($filterRule["top"])) && ($filterRule["top"] == 1)) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM + ) + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER); + } + } + } } } @@ -1584,10 +1582,9 @@ public function load($pFilename) $extractedRange = explode(',', $extractedRange); foreach ($extractedRange as $range) { $autoFilterRange = $range; - if (strpos($autoFilterRange, ':') === false) { - $autoFilterRange = "${autoFilterRange}:${autoFilterRange}"; + if (strpos($autoFilterRange, ':') !== false) { + $docSheet->getAutoFilter()->setRange($autoFilterRange); } - $docSheet->getAutoFilter()->setRange($autoFilterRange); } } break; diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index d0fa8b6df..22c357489 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -633,7 +633,11 @@ public function showHideRows() ); } else { // Filter on date group values - $arguments = array(); + $arguments = array( + 'date' => array(), + 'time' => array(), + 'dateTime' => array(), + ); foreach($ruleDataSet as $ruleValue) { $date = $time = ''; if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) && diff --git a/changelog.txt b/changelog.txt index 3bb1ab5c6..d4e59470d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -33,10 +33,12 @@ Planned for v1.8.1 - Bugfix: (MBaker) Work Item GH-384 - DOM loadHTMLFile() failing with options flags when using PHP < 5.4.0 - Bugfix: (MBaker) - Fix for percentage operator in formulae for BIFF Writer - Bugfix: (MBaker) - Fix to getStyle() call for cell object +- Bugfix: (MBaker) - Discard Autofilters in Excel2007 Reader when filter range isn't a valid range - Bugfix: (masanaikeshima) Work Item GH-426 - Pie chart won't work in Excel 2013 - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric +- General: (MBaker) - Default precalculate formulas to false for writers - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines - Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions From 5bce69de6fda2eb2516c47f07cd5e2d90b07a60d Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 12 Nov 2014 22:21:47 +0000 Subject: [PATCH 275/467] Bugfix: (frozenstupidity) Work Item GH-423 - Fix invalid NA return in VLOOKUP Manual merge --- Classes/PHPExcel/Calculation/LookupRef.php | 9 ++------- changelog.txt | 3 ++- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index 94f42e5f2..75e7f69ce 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -735,11 +735,7 @@ public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not return PHPExcel_Calculation_Functions::NA(); } else { // otherwise return the appropriate value - $result = $lookup_array[$rowNumber][$returnColumn]; - if ((is_numeric($lookup_value) && is_numeric($result)) || - (!is_numeric($lookup_value) && !is_numeric($result))) { - return $result; - } + return $lookup_array[$rowNumber][$returnColumn]; } } @@ -802,8 +798,7 @@ public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not return PHPExcel_Calculation_Functions::NA(); } else { // otherwise return the appropriate value - $result = $lookup_array[$returnColumn][$rowNumber]; - return $result; + return $lookup_array[$returnColumn][$rowNumber]; } } diff --git a/changelog.txt b/changelog.txt index d4e59470d..0ae0d632b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -34,7 +34,8 @@ Planned for v1.8.1 - Bugfix: (MBaker) - Fix for percentage operator in formulae for BIFF Writer - Bugfix: (MBaker) - Fix to getStyle() call for cell object - Bugfix: (MBaker) - Discard Autofilters in Excel2007 Reader when filter range isn't a valid range -- Bugfix: (masanaikeshima) Work Item GH-426 - Pie chart won't work in Excel 2013 +- Bugfix: (MBaker) - Discard Autofilters in Excel2007 Reader when filter range isn't a valid range +- Bugfix: (frozenstupidity) Work Item GH-423 - Fix invalid NA return in VLOOKUP - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric From 27e64c14adfd456db0d23076d123646d8d840ea0 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 12 Nov 2014 22:22:20 +0000 Subject: [PATCH 276/467] Additional comments for hyperlinks in feature demo example --- Examples/05featuredemo.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Examples/05featuredemo.inc.php b/Examples/05featuredemo.inc.php index 00a8b8729..b543ca46b 100644 --- a/Examples/05featuredemo.inc.php +++ b/Examples/05featuredemo.inc.php @@ -267,12 +267,13 @@ $objPHPExcel->getActiveSheet()->getStyle('B1')->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); // Add a hyperlink to the sheet -echo date('H:i:s') , " Add a hyperlink to the sheet" , EOL; +echo date('H:i:s') , " Add a hyperlink to an external website" , EOL; $objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net'); $objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl('http://www.phpexcel.net/'); $objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setTooltip('Navigate to website'); $objPHPExcel->getActiveSheet()->getStyle('E26')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); +echo date('H:i:s') , " Add a hyperlink to another cell on a different worksheet within the workbook" , EOL; $objPHPExcel->getActiveSheet()->setCellValue('E27', 'Terms and conditions'); $objPHPExcel->getActiveSheet()->getCell('E27')->getHyperlink()->setUrl("sheet://'Terms and conditions'!A1"); $objPHPExcel->getActiveSheet()->getCell('E27')->getHyperlink()->setTooltip('Review terms and conditions'); From 2338c3caf2dc412fab3445e8c8a1dc23ed9aaf0c Mon Sep 17 00:00:00 2001 From: Artur Safin Date: Sat, 15 Nov 2014 13:00:08 +0200 Subject: [PATCH 277/467] Make PHPExcel_Writer_PDF implement IWriter --- Classes/PHPExcel/Writer/PDF.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/PDF.php b/Classes/PHPExcel/Writer/PDF.php index 4111f8bd9..3131ee0a1 100644 --- a/Classes/PHPExcel/Writer/PDF.php +++ b/Classes/PHPExcel/Writer/PDF.php @@ -33,7 +33,7 @@ * @package PHPExcel_Writer_PDF * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) */ -class PHPExcel_Writer_PDF +class PHPExcel_Writer_PDF implements PHPExcel_Writer_IWriter { /** @@ -87,4 +87,11 @@ public function __call($name, $arguments) return call_user_func_array(array($this->_renderer, $name), $arguments); } + /** + * {@inheritdoc} + */ + public function save($pFilename = null) + { + $this->_renderer->save($pFilename); + } } From 793fc2a08fcedc4e283f0f141687ab9095a2ee2f Mon Sep 17 00:00:00 2001 From: Mohd Farhan Firdaus Jamil Date: Sun, 16 Nov 2014 23:00:45 +0800 Subject: [PATCH 278/467] Check for is_object Without this , it give php-warning-invalid-argument-supplied-for-foreach error. --- Classes/PHPExcel/Reader/Excel2007.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 3b0c1a747..277d278d8 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1935,6 +1935,7 @@ private function _parseRichText($is = null) { if (isset($is->t)) { $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $is->t ) ); } else { + if(is_object($is->r)) { foreach ($is->r as $run) { if (!isset($run->rPr)) { $objText = $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); @@ -1986,6 +1987,7 @@ private function _parseRichText($is = null) { } } } + } } return $value; From 903f737a398e1eccaf0e325e1173cb3b9fa8f0de Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 26 Nov 2014 22:24:53 +0000 Subject: [PATCH 279/467] Bugfix: (bobwitlox) Work Item GH-467 - Bug in Excel2003XML reader, parsing merged cells --- Classes/PHPExcel/Reader/Excel2003XML.php | 6 ++++++ changelog.txt | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index 6f3a4efd4..dbb196d31 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -599,9 +599,11 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } + $additionalMergedCells = 0; if ((isset($cell_ss['MergeAcross'])) || (isset($cell_ss['MergeDown']))) { $columnTo = $columnID; if (isset($cell_ss['MergeAcross'])) { + $additionalMergedCells = (int)$cell_ss['MergeAcross']; $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cell_ss['MergeAcross'] -1); } $rowTo = $rowID; @@ -759,6 +761,10 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } ++$columnID; + while ($additionalMergedCells > 0) { + ++$columnID; + $additionalMergedCells--; + } } if ($rowHasData) { diff --git a/changelog.txt b/changelog.txt index 1af29b2b5..a60cea7dd 100644 --- a/changelog.txt +++ b/changelog.txt @@ -34,8 +34,9 @@ Planned for v1.8.1 - Bugfix: (MBaker) - Fix for percentage operator in formulae for BIFF Writer - Bugfix: (MBaker) - Fix to getStyle() call for cell object - Bugfix: (MBaker) - Discard Autofilters in Excel2007 Reader when filter range isn't a valid range -- Bugfix: (MBaker) - Discard Autofilters in Excel2007 Reader when filter range isn't a valid range -- Bugfix: (frozenstupidity) Work Item GH-423 - Fix invalid NA return in VLOOKUP +- Bugfix: (frozenstupidity) Work Item GH-423 - Fix invalid NA return in VLOOKUP +- Bugfix: (wiseloren) Work Item CP21454 - "No Impact" conditional formatting fix for NumberFormat +- Bugfix: (bobwitlox) Work Item GH-467 - Bug in Excel2003XML reader, parsing merged cells - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric @@ -45,7 +46,6 @@ Planned for v1.8.1 - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions - Feature: (bolovincev) Work Item GH-269 - Update Worksheet.php getStyleByColumnAndRow() to allow a range of cells rather than just a single cell - Feature: (MBaker) - New methods added for testing cell status within merge groups -- Bugfix: (wiseloren) Work Item CP21454 - "No Impact" conditional formatting fix for NumberFormat 2014-03-02 (v1.8.0): From 9940b262c475f21db2e0705f02111a25c505bafd Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 26 Nov 2014 22:40:49 +0000 Subject: [PATCH 280/467] Remove spurious worksheet created when instantiating the PHPExcel object, and only create sheets defined in the Excel2003XML file --- Classes/PHPExcel/Reader/Excel2003XML.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index dbb196d31..e8abeb4af 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -232,6 +232,7 @@ public function load($pFilename) { // Create new PHPExcel $objPHPExcel = new PHPExcel(); + $objPHPExcel->removeSheetByIndex(0); // Load into this instance return $this->loadIntoExisting($pFilename, $objPHPExcel); @@ -576,6 +577,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $rowID = 1; if (isset($worksheet->Table->Row)) { + $additionalMergedCells = 0; foreach($worksheet->Table->Row as $rowData) { $rowHasData = false; $row_ss = $rowData->attributes($namespaces['ss']); @@ -599,11 +601,10 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } - $additionalMergedCells = 0; if ((isset($cell_ss['MergeAcross'])) || (isset($cell_ss['MergeDown']))) { $columnTo = $columnID; if (isset($cell_ss['MergeAcross'])) { - $additionalMergedCells = (int)$cell_ss['MergeAcross']; + $additionalMergedCells += (int)$cell_ss['MergeAcross']; $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cell_ss['MergeAcross'] -1); } $rowTo = $rowID; From 2be1bb0c2e4157116710487003959009cff6b77f Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 26 Nov 2014 22:53:55 +0000 Subject: [PATCH 281/467] GH-455 Fix case-sensitivity issue with PHPExcel_Chart_GridLines --- Classes/PHPExcel/Chart.php | 14 +++++++------- Classes/PHPExcel/Chart/GridLines.php | 20 ++++++++++---------- Classes/PHPExcel/Writer/Excel2007/Chart.php | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Classes/PHPExcel/Chart.php b/Classes/PHPExcel/Chart.php index b9146b34b..9bf72dbbd 100644 --- a/Classes/PHPExcel/Chart.php +++ b/Classes/PHPExcel/Chart.php @@ -115,14 +115,14 @@ class PHPExcel_Chart /** * Chart Major Gridlines as * - * @var PHPExcel_Chart_Gridlines + * @var PHPExcel_Chart_GridLines */ private $_majorGridlines = null; /** * Chart Minor Gridlines as * - * @var PHPExcel_Chart_Gridlines + * @var PHPExcel_Chart_GridLines */ private $_minorGridlines = null; @@ -177,7 +177,7 @@ class PHPExcel_Chart /** * Create a new PHPExcel_Chart */ - public function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_Chart_Legend $legend = null, PHPExcel_Chart_PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = '0', PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, PHPExcel_Chart_Axis $xAxis = null, PHPExcel_Chart_Axis $yAxis = null, PHPExcel_Chart_Gridlines $majorGridlines = null, PHPExcel_Chart_Gridlines $minorGridlines = null) + public function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_Chart_Legend $legend = null, PHPExcel_Chart_PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = '0', PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, PHPExcel_Chart_Axis $xAxis = null, PHPExcel_Chart_Axis $yAxis = null, PHPExcel_Chart_GridLines $majorGridlines = null, PHPExcel_Chart_GridLines $minorGridlines = null) { $this->_name = $name; $this->_title = $title; @@ -387,27 +387,27 @@ public function getChartAxisX() { /** * Get Major Gridlines * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ public function getMajorGridlines() { if($this->_majorGridlines !== NULL){ return $this->_majorGridlines; } - return new PHPExcel_Chart_Gridlines(); + return new PHPExcel_Chart_GridLines(); } /** * Get Minor Gridlines * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ public function getMinorGridlines() { if($this->_minorGridlines !== NULL){ return $this->_minorGridlines; } - return new PHPExcel_Chart_Gridlines(); + return new PHPExcel_Chart_GridLines(); } diff --git a/Classes/PHPExcel/Chart/GridLines.php b/Classes/PHPExcel/Chart/GridLines.php index 7467ea7ea..269860ca1 100644 --- a/Classes/PHPExcel/Chart/GridLines.php +++ b/Classes/PHPExcel/Chart/GridLines.php @@ -7,7 +7,7 @@ * Time: 2:36 PM */ -class PHPExcel_Chart_Gridlines extends +class PHPExcel_Chart_GridLines extends PHPExcel_Properties { /** @@ -90,7 +90,7 @@ public function getObjectState() { /** * Change Object State to True * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ private function _activateObject() { @@ -229,7 +229,7 @@ public function getGlowSize() { * * @param float $size * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ private function _setGlowSize($size) { @@ -245,7 +245,7 @@ private function _setGlowSize($size) { * @param int $alpha * @param string $type * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ private function _setGlowColor($color, $alpha, $type) { @@ -307,7 +307,7 @@ public function setShadowProperties($sh_presets, $sh_color_value = NULL, $sh_col * * @param int $shadow_presets * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ private function _setShadowPresetsProperties($shadow_presets) { @@ -323,7 +323,7 @@ private function _setShadowPresetsProperties($shadow_presets) { * @param array $properties_map * @param * $reference * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ private function _setShadowProperiesMapValues(array $properties_map, &$reference = NULL) { @@ -355,7 +355,7 @@ private function _setShadowProperiesMapValues(array $properties_map, &$reference * @param int $alpha * @param string $type * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ private function _setShadowColor($color, $alpha, $type) { @@ -377,7 +377,7 @@ private function _setShadowColor($color, $alpha, $type) { * * @param float $blur * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ private function _setShadowBlur($blur) { @@ -393,7 +393,7 @@ private function _setShadowBlur($blur) { * * @param int $angle * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ private function _setShadowAngle($angle) { @@ -409,7 +409,7 @@ private function _setShadowAngle($angle) { * * @param float $distance * - * @return PHPExcel_Chart_Gridlines + * @return PHPExcel_Chart_GridLines */ private function _setShadowDistance($distance) { diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index ceb750ade..4846910fa 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -239,8 +239,8 @@ private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Worksheet $pSheet, PHPExcel_Chart_Axis $xAxis, PHPExcel_Chart_Axis $yAxis, - PHPExcel_Chart_Gridlines $majorGridlines, - PHPExcel_Chart_Gridlines $minorGridlines + PHPExcel_Chart_GridLines $majorGridlines, + PHPExcel_Chart_GridLines $minorGridlines ) { if (is_null($plotArea)) { return; From 2f76d1247b86a81b670abdbdb3a804fcb8d4e089 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 1 Dec 2014 22:35:23 +0000 Subject: [PATCH 282/467] Additional notes on building pie, donut and radar charts --- Examples/33chartcreate-pie.php | 4 ++-- Examples/33chartcreate-radar.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Examples/33chartcreate-pie.php b/Examples/33chartcreate-pie.php index 44910f9cb..5af02905b 100644 --- a/Examples/33chartcreate-pie.php +++ b/Examples/33chartcreate-pie.php @@ -87,7 +87,7 @@ // Build the dataseries $series1 = new PHPExcel_Chart_DataSeries( PHPExcel_Chart_DataSeries::TYPE_PIECHART, // plotType - NULL, // plotGrouping + NULL, // plotGrouping (Pie charts don't have any grouping) range(0, count($dataSeriesValues1)-1), // plotOrder $dataSeriesLabels1, // plotLabel $xAxisTickValues1, // plotCategory @@ -161,7 +161,7 @@ // Build the dataseries $series2 = new PHPExcel_Chart_DataSeries( PHPExcel_Chart_DataSeries::TYPE_DONUTCHART, // plotType - NULL, // plotGrouping + NULL, // plotGrouping (Donut charts don't have any grouping) range(0, count($dataSeriesValues2)-1), // plotOrder $dataSeriesLabels2, // plotLabel $xAxisTickValues2, // plotCategory diff --git a/Examples/33chartcreate-radar.php b/Examples/33chartcreate-radar.php index d0e2b9fa6..b8b427f3b 100644 --- a/Examples/33chartcreate-radar.php +++ b/Examples/33chartcreate-radar.php @@ -98,7 +98,7 @@ // Build the dataseries $series = new PHPExcel_Chart_DataSeries( PHPExcel_Chart_DataSeries::TYPE_RADARCHART, // plotType - NULL, // plotGrouping + NULL, // plotGrouping (Radar charts don't have any grouping) range(0, count($dataSeriesValues)-1), // plotOrder $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory From 2b389f97f1bf8cd399f27ea4ce0a2321419f1575 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 1 Dec 2014 22:35:42 +0000 Subject: [PATCH 283/467] ReadMe Notes on contributing --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 52b63b2e6..220a6681a 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,14 @@ Develop: [![Build Status](https://travis-ci.org/PHPOffice/PHPExcel.png?branch=de ## Want to contribute? -Fork us! + +If you would like to contribute, here are some notes and guidlines: + - All development happens on the develop branch, so it is always the most up-to-date + - The master branch only contains tagged releases + - If you are going to be submitting a pull request, please branch from develop, and submit your pull request back to the develop branch + - [Helpful article about forking](https://help.github.com/articles/fork-a-repo/ "") + - [Helpful article about pull requests](https://help.github.com/articles/using-pull-requests/ "") + ## License PHPExcel is licensed under [LGPL (GNU LESSER GENERAL PUBLIC LICENSE)](https://github.com/PHPOffice/PHPExcel/blob/master/license.md) From 0296daa75c9cd29880a13efa66037e050534550f Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 3 Dec 2014 08:05:25 +0000 Subject: [PATCH 284/467] General: Set default Cyclic Reference behaviour to 1 to eliminate exception when using a single cyclic iteration in formulae --- Classes/PHPExcel/Calculation.php | 4 ++-- changelog.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index fa89671fe..9a0bf0f07 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -214,7 +214,7 @@ class PHPExcel_Calculation { * @var integer * */ - public $cyclicFormulaCount = 0; + public $cyclicFormulaCount = 1; /** * Precision used for calculations @@ -2236,7 +2236,7 @@ public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE $this->formulaError = null; $this->_debugLog->clearLog(); $this->_cyclicReferenceStack->clear(); - $this->_cyclicFormulaCount = 1; + $this->_cyclicFormulaCount = 0; self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; } diff --git a/changelog.txt b/changelog.txt index a60cea7dd..ed9eaa641 100644 --- a/changelog.txt +++ b/changelog.txt @@ -41,6 +41,7 @@ Planned for v1.8.1 - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric - General: (MBaker) - Default precalculate formulas to false for writers +- General: (MBaker) - Set default Cyclic Reference behaviour to 1 to eliminate exception when using a single cyclic iteration in formulae - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines - Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions From 3f85430e6c112a980ec9fb021b83e11a3da897aa Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 5 Dec 2014 21:31:17 +0000 Subject: [PATCH 285/467] Some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE instead of using Codepage 1200 --- Classes/PHPExcel/Shared/CodePage.php | 1 + changelog.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index 01e0ea4f3..89e2d19cf 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -92,6 +92,7 @@ public static function NumberToName($codePage = 1252) case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe case 10079: return 'MACICELAND'; break; // Macintosh Icelandic case 10081: return 'MACTURKISH'; break; // Macintosh Turkish + case 21010: return 'UTF-16LE'; break; // UTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE case 32768: return 'MAC'; break; // Apple Roman case 32769: throw new PHPExcel_Exception('Code page 32769 not supported.'); break; // ANSI Latin I (BIFF2-BIFF3) diff --git a/changelog.txt b/changelog.txt index ed9eaa641..ac3cab2eb 100644 --- a/changelog.txt +++ b/changelog.txt @@ -42,6 +42,7 @@ Planned for v1.8.1 - General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric - General: (MBaker) - Default precalculate formulas to false for writers - General: (MBaker) - Set default Cyclic Reference behaviour to 1 to eliminate exception when using a single cyclic iteration in formulae +- General: (MBaker) - Some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines - Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions From 75464688d57f73310bd4c024e938e149823d14da Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 5 Dec 2014 21:32:53 +0000 Subject: [PATCH 286/467] Github issue log reference for codepage 21010 issue --- changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index ac3cab2eb..6a5bb81c0 100644 --- a/changelog.txt +++ b/changelog.txt @@ -42,7 +42,7 @@ Planned for v1.8.1 - General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric - General: (MBaker) - Default precalculate formulas to false for writers - General: (MBaker) - Set default Cyclic Reference behaviour to 1 to eliminate exception when using a single cyclic iteration in formulae -- General: (MBaker) - Some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE +- General: (MBaker) Work Item GH-396 - Some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE - Feature: (WiktrzGE) Work Item GH-404 - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines - Feature: (frost-nzcr4) Work Item GH-403 - ODS read/write comments in the cell - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions From 9daca467d61fc37130b6fe8485a12396e99b6c8a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 5 Dec 2014 23:59:41 +0000 Subject: [PATCH 287/467] 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 a633c2c3a..5cd0b909e 100644 --- a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php +++ b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php @@ -58,8 +58,8 @@ public function count() { * @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 @@ public function push($value) { */ 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 @@ public function pop() { * @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 @@ public function onStack($value) { */ public function clear() { $this->_stack = array(); - } // function push() + } /** * Return an array of all entries on the stack @@ -95,4 +95,4 @@ public function showStack() { return $this->_stack; } -} // class PHPExcel_CalcEngine_CyclicReferenceStack +} diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 9a0bf0f07..1f8c93238 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 @@ public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE $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 @@ public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = } // 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 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC $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 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC 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 From a4afd4d31383db6a070ec10c7559d14688989aba Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 6 Dec 2014 00:16:09 +0000 Subject: [PATCH 288/467] Modify RAND() and RANDBETWEEN() to use mt_rand() --- Classes/PHPExcel/Calculation/MathTrig.php | 4 ++-- Examples/13calculation.php | 1 + Examples/runall.php | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index b2bb19d48..9f0e7f4c7 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -880,9 +880,9 @@ public static function RAND($min = 0, $max = 0) { $max = PHPExcel_Calculation_Functions::flattenSingleValue($max); if ($min == 0 && $max == 0) { - return (rand(0,10000000)) / 10000000; + return (mt_rand(0,10000000)) / 10000000; } else { - return rand($min, $max); + return mt_rand($min, $max); } } // function RAND() diff --git a/Examples/13calculation.php b/Examples/13calculation.php index db149489d..01e63ea77 100644 --- a/Examples/13calculation.php +++ b/Examples/13calculation.php @@ -34,6 +34,7 @@ define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '
'); date_default_timezone_set('Europe/London'); +mt_srand(1234567890); /** Include PHPExcel */ require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; diff --git a/Examples/runall.php b/Examples/runall.php index c65727eb1..3818547a7 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -59,6 +59,7 @@ , '11documentsecurity-xls.php' , '12cellProtection.php' , '13calculation.php' + , '13calculationCyclicFormulae.php' , '14excel5.php' , '15datavalidation.php' , '15datavalidation-xls.php' From 741500da144b48d85d229e9dbaf3f590ed5f3f03 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 6 Dec 2014 00:16:41 +0000 Subject: [PATCH 289/467] Add example of cyclic reference calculation --- .../CalcEngine/CyclicReferenceStack.new.php | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 Classes/PHPExcel/CalcEngine/CyclicReferenceStack.new.php diff --git a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.new.php b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.new.php new file mode 100644 index 000000000..e57512de2 --- /dev/null +++ b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.new.php @@ -0,0 +1,122 @@ +_stack); + } + + /** + * Push a new entry onto the stack + * + * @param mixed $value + */ + public function push($value) { + $this->_stack[] = $value; + } // function push() + + /** + * Pop the last entry from the stack + * + * @return mixed + */ + public function pop() { + return array_pop($this->_stack); + } // function pop() + + /** + * Test to see if a specified entry exists on the stack + * + * @param mixed $value The value to test + */ + public function onStack($value) { + return in_array($value, $this->_stack); + } + + /** + * Clear the stack + */ + public function clear() { + $this->_stack = array(); + } // function push() + + /** + * Return an array of all entries on the stack + * + * @return mixed[] + */ + public function showStack() { + return $this->_stack; + } + + public function setValueByKey($key, $value) { + $this->_values[$key] = $value; + } + + public function getValueByKey($key, &$value) { + if (isset($this->_values[$key])) { + $value = $this->_values[$key]; + return true; + } + return false; + } + + public function removeValueByKey($key) { + if (isset($this->_values[$key])) { + unset($this->_values[$key]); + } + } + + public function showValues() { + return $this->_values; + } + +} // class PHPExcel_CalcEngine_CyclicReferenceStack From 4d67ff7de9e2109fb5dcf1dee9ad5348302558e3 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 6 Dec 2014 17:44:27 +0000 Subject: [PATCH 290/467] Bugfix: Work Item GH-302 - Fix for CEIL() and FLOOR() when number argument is zero --- Classes/PHPExcel/Calculation/MathTrig.php | 11 +++++------ changelog.txt | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index 9f0e7f4c7..f3ae111e4 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -145,8 +145,8 @@ public static function CEILING($number, $significance = NULL) { $significance = $number/abs($number); } - if ((is_numeric($number)) && (is_numeric($significance))) { - if ($significance == 0.0) { + if ((is_numeric($number)) && (is_numeric($significance))) { + if (($number == 0.0 ) || ($significance == 0.0)) { return 0.0; } elseif (self::SIGN($number) == self::SIGN($significance)) { return ceil($number / $significance) * $significance; @@ -316,10 +316,9 @@ public static function FLOOR($number, $significance = NULL) { } if ((is_numeric($number)) && (is_numeric($significance))) { - if ((float) $significance == 0.0) { - return PHPExcel_Calculation_Functions::DIV0(); - } - if (self::SIGN($number) == self::SIGN($significance)) { + if (($number == 0.0 ) || ($significance == 0.0)) { + return 0.0; + } elseif (self::SIGN($number) == self::SIGN($significance)) { return floor($number / $significance) * $significance; } else { return PHPExcel_Calculation_Functions::NaN(); diff --git a/changelog.txt b/changelog.txt index 6a5bb81c0..0b8845f1c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -37,6 +37,7 @@ Planned for v1.8.1 - Bugfix: (frozenstupidity) Work Item GH-423 - Fix invalid NA return in VLOOKUP - Bugfix: (wiseloren) Work Item CP21454 - "No Impact" conditional formatting fix for NumberFormat - Bugfix: (bobwitlox) Work Item GH-467 - Bug in Excel2003XML reader, parsing merged cells +- Bugfix: (MBaker) Work Item GH-302 - Fix for CEIL() and FLOOR() when number argument is zero - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric From b2e82a0e117be7d367ff4b84969b42b81eb05ad8 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 6 Dec 2014 20:50:57 +0000 Subject: [PATCH 291/467] Updates to dcumentation, particularly for setting/reading cell values, and with handling date/time values --- .../PHPExcel developer documentation.doc | Bin 800256 -> 865792 bytes .../markdown/Overview/07-Accessing-Cells.md | 37 +++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Documentation/PHPExcel developer documentation.doc b/Documentation/PHPExcel developer documentation.doc index 5f1ac5f7533a68c0e47b8decf82404c35b26243a..2c7c81a6e493f56d67a559654ec0d7380c2056e8 100644 GIT binary patch delta 151963 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≺ z_fP;u@BvETBh-T=meNRp2Izw;ct99LSMgNHS8Ox@U3%g~8aGl(H$6)TdynGx#qmiK zNswqp|IHLDedOm&u)+-1n_)r*KR69aBQWT|DRV5x0o?ye_#iz7&){N#t`2$d8T{v< zt3w9lf-FYKF3^+0P&ojGpcqYHCAdL2+=2$+FT|h&^B@);g2W=Mp@hY-8vGy_lHoDb zg19vng~D(+0s#;Y58=sTtX>65(-w>Pz#b=AK`_bzD?y0VD|i2T?^(1ANR2JKzBPbr^RSK*bTP#e;T7F=@eM zm<#Jca1`^yBWz^Aw`0ihaTF;y!!bAsx8Wgpp1@2A#qbrBuoi0oY{BGn5F#NC>Y)QB zB412I7a_2PuCPGZ?{eNPq{B2bE9K$oU>p^64neC16POIMUMfxI)+aQ`Oi zKOY;iG1vh-gAXuUgc~)$BoKaULZgL=U1ka16X543eP`ilG+1f&4wh zg-s8UA&7(+$b*ki58uHo1#K(^_3w#|Oe#v9T9?;0#=cWJrg67?g!I z^x?$?zP?pb?D>@CJb0R`|G29#h>g7cryTHzBkfK3_B1Hhvk;UN`XL%Yw&5xjvi7+8re32&hs z2329qhwjzLG#su*{hz`{NDUeZ(0A=V1NzQgQi~#o$?zIVpvPCtl&}rF;1zs;&fhR_ z!GP~LVDN`4@E$5*jx3KX08cm${%{&z%HsSm8yj8ZaH<6}U@ml&#~r(H3PQmWr{Q+6 zyc15np^E}8XCV+mpd5C8Y(2C2H)k*OS&MpiJPZasumbw@rR8iT>hx^>G#*b2l|GGbYO3Ipl@{02KGh=`UZysz~0|L-`DUB z*!vpj`x&f(y`O=;k0Bb^`xxl^7tDaYf8i9i6X14#RAL!6==&A4fxTaWzE9y8u=gp@ z_b1c>dw&9bUxF2|_a*pYTLkR=2=r|TY6DttL!fUz*aqzF2lQ~ZpU5Ptt z$`9k0_nBSc??=s>VH96eIMSIfDV%n$?fbtAkE7@sg;d&!3(MX4Qo@vN{OhfI)f8%P z;m5T7`_z?|zyE7eR<8W~=3OCGC84vBpZ3$=%5*8P>0|%e^zn2P{^8H>E_C1AQZ&f# zKOI?9OnsrbdrPFI-P!C$A>&15VbE^=FySG3t6?|4Tk~-s3|l8`>g>_{Q<})qAmKb8 zekY-~2VdpCSGSHQ|7+WV{+oiQ>#U_^bciz8!xtA54qK1b_undhkZ{sIzUF^FR5ty2 zQML#8^ZrGnq$ALctQv>84<)|$1iyc4vTDMM-gq(22Nlvmz}NYyP5f;eVN3mgkPEhg zo0=Eflm2@n`A@wKyZ=w&(I{MmQT}{IVbW>7`@d`+|1}Y|b~4)3`AGr93mx;DRzT=OtOcTQyDPC#^@0;J6D)f!yyNF5l5z1fZ>vmY{+L6o>>qI&$ zb|P9@!tvMn#bVtZg<4U3l@9ce-ti@elAw-5$)HZcX;J)lVzV@bS~vKAiS2X}X58Q# zirw2NTBoY}&jH~GVrswMs;R(<{?GbHzrA3X@8KV_Mb}bJg>5f4pd_xe??-)!z z4-F=}HU$&4fg$AX3?UW6pWD-Nb`zT+6ARQ9j*sP!5Z`X` zLAW!PKTzzLs_;rIKLkHki%-6R{*Qia9Ld{;uST#%qyOXKe|DRF7F))=htDRkF%2JW z6+;Ppgi>7LR516a7UAO zI*vb)$B#0P=bz^(j~O}`M<^yQE+!@>Auc9SCPq$e?uESxykHmp|~)#3fwrH2v@oPNzEV5&!wsJyC@TxK>tD(5DZj z^*^c4D5TFkx__Ao_a^fBvbr8KNO?!n?sa1W5529MFglTM&yzt2eqsAdh$#gc!cKSj zLh1ha-A8pIOUF()dP<_#^(4N4$I}zKCG#~T#xA`&S$IB~->au*g#3w4k9jyK93!qp zfj(yXnLcjejP_E!=^x?@|6hKIx z3fE@vjk#JJ_(Fg86d?Gx{mm3GQHMEKSFxgCBOK zi{cP>FoU0h?d1+e_fvW=?A~^A2h;m0m^*i{*79eL&6PV?Yb`Lr)^P`Gtp$aqV_eA< zOs7pPFv0A&gSFNI6KpYeu+~~&f-T?<)>;cpu-V+fT5Ev`HkCVAYb`LrCU6I9tpz67 zXzpOGwZH^3>eK_2UlKS_@3D9^AoN zYk>*YjXPLtEil0pxP!IU0uxM@J6LNiFu|m_gSFNI6O1$k`)SCcm$kDUP*Lbq`OA<+ zua{>6=;Bw5>7H68TwBT4`eDeTZ!BcTA~x73?qF>Bv%!kEgR$k$27AXHj4gjQ*lX@! zZ27an(z%1N<T_y?qF>Bv%&6g2V={h4Hm~8thE+Yn`+?(S1@|jEn8Vk zuyF2Rt+l`e3*rveS_@3D3*5n4Yk>)NiaS_qEil1+xr4RV0u$^Qcd*u4V1gas4%S)= zOt3$>gSFNI6Kn@}u-01mKW&^_Y!qb}hKHstT7RJ=wO~Oh*p{X3mUh|hZcz?fYO7GR zoDWvcASY{Wp~7+~pfo0}hMLrYkZ_|H4c>UgdSPN>j3GoxGzJM*M4=u+LbNx43H6!% ztY0DDCQoKM`}EJ|eRs3_Pv)P3ObbUWEk33N(YkC+TM(_?*0crD_Sl-XAli0Y(-uVA zXlvSnXzOfETM%u9t!WFQHQSoDAX=lXX$wzfT3BRh!Ijpdp9Rt8*_yT>TGZCG1<|T( zOhyX$zv|*_yUcm}wz9qdoNf60DBb777P? z-NV0#gXcAV8RqUlzkBrCC0JWG+ND^3o0f(z)@{?$?8O=~Esb8R8>Xeni*?AsQbr3Eph8=$Xt9>M;4<79Fx;g$#fKG#F@^=K>NuK1cbin_(Vj_Ri7!2u| zSD1bG{{4G{L3rhIiC8tHuQG17!+15Lny###S4p{ z_4aB=T$yw-FM~loZ^>dXcrkyHXAhq5@+^OBpXGAP4_jrk2E$u(I@{+cmWTNn43!)V zh5vPh8%efafXYs07VRjIy}|kS^j+Z98`)oQ2Ei-D4b?6G^=Sa z+^6DgP8$s5V`#^-{P`!(l*KUpoWZb;H`chAni&?1A%iyhI0yGsmb!Y^;iXsH_>u-g zHWIAixi8P&vY0l{@{P7XmbY7;Ej6*Ek*^EV6t8%n7Yir#G_CpYS#BpnF@##%-jdOW z8OtWH{h8ELWWB3K1X>FE*Y!yobfs_R?V*2F`JM`KV-A|uS+-^A-<4_ZU&$MBL`ItN z$FjUiUHUYm!SKUAgMps0{?wvOGEQ9S=OCVCf6Jc>q+3I?J6Ax|jNtP?c+a3nPRQZO2A11WCw$#PazJGnzGp3vwVyU9#ZGZnPYhLuD z<&?W;QD=i;NapxTj*6-eO%>o08WkKK8W9m3md#J`5CbMV_~}g?7`BFvc#a8Jr4Qs0_7z?vd5nG{iaM(1E_ zil}5#MC<*W{jDjY|C%BsNI&TuXh{(gluU|XJ;cSjm5|_MQiSNbOPHl*AtCxQ=gihu zq5AJG*==4ObxB$mrdM#yX5Ds}Ip^3QYa4`w>(gDcr!+UDp4HXQnp1@S$kp0@A(r;D zeQ%^*(#_g_A(r;DO%bKfa?5AkzNP(aQ$*{3xaF~KGg{B!X6@F{AQ=x~flhjsc3yht zG;Wsu4mCGous$w}wI-p#`pPtUtx3$SXrClRPn|Z(nk2;39QH{<^=@f{tw}t1aoWSYJiy zRot^#J8o0DtkyNr`W*Kln^)htTi+EHq^lnJt?%mTZhco+u-@1s(DE)`*}f}8-{RqK zT^C}vE>!pOENopDD%Yhm*DB1oLx%;12Zrc>dInkABh1=lXb>K+w>8Z^kL-fW0&62m^$gbEoF(cqz?~ts?@1dXZ?_ew{;8V*bSENu$Cyw z@{S07X8I!5Dn{uKJ(3zUT6gx&ZOzBL{|D=YxQBVm;pQ-o2n;5auU+ud$9h{sIouk` zHakUluzu9Ls3p^IYbe_$3DJxB6tpI>hO%vvP<@F{xTV^Z@9A63x(Rb9gxKzL;Su^P-=tEQ+uc4%q~1J3VQVhthPF=NmU_eBKTtqak6XR7RI?xhI5 zu($Qt7ZIwz%2e7?q6qU*AVjx0c|?Ti9Wz_&6=7~c`y}D|h0IC0SR2qbmk7Oj7VC}? zVQoO$B$4{+EcvWuu{NM>k|^EP&w3Dzh|&vXNNRy-J;pC2sg?yZSZf&>q#y7rX=xl@ zUCU^FTV$|aG;0Ctx?sC?A^Oa$QPy=K`q4~D?+evaW(%>d3$hgKLeJ!1(9*6^=0FP#wcX*PBJ~me z*1qG_m8?l+iqe1cx5h(Ml-;^$y<+aKt!0X~T^AjsZ_8cCvW{0-vRm_v4%YMMiMFl_ zwp$mXPs&r!x-P_SU8t_)wbnB_R3BxNXPDk5Z(i&B!tB$~z=<0d-XZe4^PoG+=I zoSbd)jMQi3v$jigq}{rx@%gRC*yt$zadzw3FFIPDKf>ivUp$_myxnidx?n zX}2y)4-5)5?}L#+=6x_so>Z(0jqMh}m|=UckG?v{J!yq$9A!*x$v!wpe;E{FNfK<{ z9m8yP>d4?=y>77OAj>ODF4wHr6OoL&ehIdWndGYyd96(p9I9ssv2=eVuWZ+a>HR}2 z=cUNtFuQf(`mK=s=3Oo_*nB7pGwyQM@)}1m5rMRAu!r6-)ZLogyoZ{STPqu>&j}5( zrZJxjKFHEIY>5b@OUN=)n5Q+lrLm1AFpqK~gUziSNtCWQq-4}bgt=Ka7p)h~pT$zv z5aT!|B9Q(h;~Qb=EXlaSu}u~%!(JxaZc1i-zqR2RWCfa{KQbi5lsYQVsa(y zNTiPmwDw0xsD6wwoF#)$yLDlDP(;$YFuQf(`k06e*7t?$hl7&xjL^BFWUMBfx*IfF)qMCn^1Gg&KWZs2g6AyQ-r1H`Bbo|e*@&nV%+o}MnA@g1X{ zxav*H&O=CiM7aZQ5iy-x_G;d;eL#m!ExNaF8PKXzmw*QC_xXP2un-hM9nuhNToeiD1m*Z)0 z;WkAl9vuwr4NX~B!qA;mop{xW*DVY!4P98;#?X2@6*a(-xia?v}Suuc+wi@)`2cArc|b>Ubl5kC+iY@RGVPq zyW%&rIT{c@QVdk$ou|}M;#*FQP~)dhZ>=bP@eVVCRekH6-0_WOH&NoZ&N-*VPnqYU zI{I~J*)671i$L+Dt&&4@YNMpqN=EtXMfT*@hwhBk6ZcdS;}s>3{`m1?%Z!s=VfPg4 z8})~~|B%V_%zLZqJ$DUrdP&b9NTrsY+9EPEk51ElXfoYUA6pi>pqGgD8+yaZXsT zDGp!BT(T#yaM*|I#njZwOXF%0=b@xY*yXIOR1>ug>&4^c+R zH|EhBzjsT>9jX*}Fs&^RrDRH28L13%N(e2XEOL;E{KVVR%I<_6Wt3pmSki>_<&}6< zysJouKdPuKHx;3BRV8i0@k&ZgMRcj8q!%t#6gQb^zJzjBl&@9QZ>ShmO=%>Kf1?yi z$W>igswOboB!#IQj~{;}n$=Z$2{w~+Qa$CcWyVct^_2_>zV(%%DUz0*Y@)19dbOpg zvc&F{qZrXz2@~(?Drp5P9ff~WC5=#~NJO$qPED2c|hWfqR(DfQ#=ieJJ`Hf-#wyyDR$Wtt( z$71EM-J%To<$Y;{?^5M}-Qx73=r2lJ(fKDOMS|xZrLQ7fm$Pdq2MJnhcBe#%)8xK& zh2oS@e5H~~NqQ}K?IyOpP%4X{g^FXsxmAjm-0Cz5x#E>y9W2|vV3~0hz8jQ#cCS(= zP^6biQW=bC+(gksN+q#nv(m=8^%MzJwkYcq%ezzPGec4)gltoG*u2@aFzZfbnIewt zQf?a)Z{AB2mEBK(yY5j&n^PySw4Tf?dqSc8%5LLQ7fq&52s)yS(Gs>DSK6s^jmr`)ol{b%V$ntATT$?$(jkF4H&dSH zt|&bfQT>|oM7({bM2o)Hl^B^><^=7Aaz{z{?WU5_xIWC-yb0ZIE6+8V-uOCA!m>og z*->sJt62U*NhhkVWX|=O@<3)c%UZ0g39PM}O7!}ZesY`SP zI8bZbk9+uEIVx!#2YSUswr(%7ELJl#Va8C)QRz_5;Ls7>9Tg8t0)x#$Ll)1N_`ZD& z#&;TmD!5x$b}i@R$h-0yHz7YJU=ucJ#Wp9^BXe5Q`)o4IV4G&3uXtdMAUS zEq+DrR0cyFE}VE9wS#;C=`0tYp0QVP{YxQx+U zM3Bbjk|sqiu`EkUmKi4p9X^uI_zvUR<>NI+F*}8tQEW@07LSv?CJVbC2XF^>aSw^O zj|X^xm-roNsZct&!vmi1f~>GNd=QQZL?Q|WQ3&Nw9u?5S$xzC0=j5Kvdwx18?ub$S zMz!lVs^3ZDl3L~^vh~eBrp|q?B-^=S^;c>-?K1_`AC%y~2`J|Ro-tc0^)N-S$gHS2 z;tW}62SZD=LTkjJ4P@}NLwk(C_ZW#EFa~3>01NRGwqpl&Vi$H}4`cxD#Xj7^Z9KSq z;_|jd+op~a{ZgqJDzxJ>S)0A`gPrm3c01ekVzQ%}{e#`8;QxQmv)hx|i~rI_qDe~C z>4Q9-tVam3BDLz1(tHRJZyeQ3aeqCY7&6LQ-@#qnmo0#=*d0^C5!sL(Igk^%;19X$ z=0RSRL0ObTc~nLfG(;mb#&@XoENHUC;m zYnxaPj5O!p9yR~c-p+O%I@LwZWZ(F{ad%DeVsrR3c495NW4JF(Vd#xM=!<^n4|yaU zfPt8SnV5yyn2!b6h)vjxGdPQLIFAe7OfKRQF5?Q`;H`*FrTWL!P|XJN-4L zPn)9VZ(^FN8fIW7W??qwK%UX(VLrBDJ9c0v_F+Fx;3Q7r5gy|Sp5mD|ljo4bf|vLm z?hFe&L~J^>Z0)l0aFsM}`ad3_O))D^^7b)n?42(es&CSKBvd`9swceQ4Iku0F8HGa zN}?3LMro9R96^;sd9*|;v_=ftqXT;3JM_i`XF}Cc%@J-L>3w`3-@CtR^dir?pt!D@NNDF-VBecgy!rqxSae*t+!5z7g z2YK-|N}~+Qq8!RYUMy5ZCB&c&+M*pgp)&?!2!>*oi+NP?GcW90<Rey5?rzs4xF$Z%o5Az|fy%ypp?8GkY#vbg)0bIl-T*fQB#vgctx1zkan%ea} zvj#5TG9r_!=#om!6_?%Z^N0IFwrAh5)*b%Khr9Pj!aWm(%#19^ifo8NGzy|7YN0mj zpf2h`UJo}wLwtwc=!3o(fPv640TZ#p^`9T*r}8~q`-c1UJtC7SFS|YBbBQ_t>aF{-a9-o|*d zM-7uN9KsLu9 z48|h zfKeEYF&GQESC5B|6JE4pDMe!wU!#7|g+ zC0L4|AuEh5QlIWCvggQa2NNWr6ca;&7c;XvHq)|zQbwIrWZeZP`5R0FS#DI z32Lfpa6k&Agd?0FPxz_fjNHhByvT=Ogh2j6NLiFaGc-pFv_fldCNYqshPG&j;TR!e zb90Ek;A__!|Hqg%-3)4E%EP9HU;GgLCa;>Q#9!~|88VKbs^4QIki zCTtN|^Q-Q8cQShgS8)y3aToU>&*;u@fxo+Gn_11Bt_HvM^j`(%sSI}A@jt&iU&mA) zo32gni0n^m1nRmT8?Y7Ia2t1U7b=4z4GwaUgp_cE zyd+44)bK}cj_i!*av&#)p*TvQ6uw4j$Sc;eD2EnkiB@Qh zc4!YdF6@W?nC$t_$HIa9y6%4!&8xE7_1|ZY<}lOtZ2CI6Xr?s`Q!o|NF#|Ip?*Yul z9BjrGY{fS0!LPW3ySN99s|E+8KuS1zGjW2vk&qhB$c;QAHi~Fokln5|J}H`WoAR)! z;g^r*h>t{b9;%ub`4Ef{)W)}{gD&WbZje`8J<$vDo=b1^fxu);!Bot~9Bju9?8GH6 z^MN;G&i^h{XYqUOUvh+-&9pt6j!Z68sjA^JuHYK3;|Am{s#~}Xm8%~O4oHF2aE3o} zBM(a9Ym`P=l=ERy9`Zg{MN~oz+N3uP67*bl&GAXG>SfBqrix!aRttV4R@+e5wrGb~ zbirth!B{N8Qv8hNSb>$0_XJlX9!GE#$8a2HaSm==yre-|T2fkkQYNc$A$_WWMDLx+8~BN~l*vniA?5akYf%7nh37riL@z z;Q>EnMK%;h5fnvnlt4+yB7cq2Xo_ZNjuvQ#_85op(6J1E{luiUh)bh}rn?=GY#)8n zH&@!2^7>+X(0x;k+8hd#+k<5FmtzH1VKw3*dwng|;W$p_H6+{QEuVYGAUx^F{Zdav#})s#Db(_y+Y*A44$=!!ZYQ zF%Ju{5I;fgWs9){d+;mvVjqs;7@p!8p2Ibx`CxxCDA~sNq)`3Vl-Cyv)$^uc_?u9r zss=ZtK{~j@1M;Bch4ctT7{U>OA}ER&v_V@8!B7mt2z>9uWF+K~Z4`dQVl2sM8benM z`S-DUI5^qv`J%B}=_9eagt{)p&xpqw?8AN>z%AUy9o$1AeuF#RwYY{7tM<>ZY({d*_RWYPFAq>UOHS z13R%F2XGxXa1-zF9tH*@Dl|Ai4pP2CN@Pb4cFP13R$`yKxYQ@B~ls3@%)VxWWx-kvSaaSy-YJ{~|`13$uJICCBB0#~@f z3+Yh+K?p`gR6=D`MKvEL)gdpWzd=oOMr>Bo@Kh`M?_+gXkz~8)i^gh$kHl&$b?t(# z=#4)35u-5%i?IYtu?)+x0`jJV{NQRe4&w-p;uy~293J5@o*;ELbFB6*mTY5uQmp=I z-#MTC7ViMl_WmYTsj9&lE^tE{q=mdk;|>o5As8VDML`rob=1H&=zxysgjjU(X3`b% zMo)M2z~bw-R=p^VvhSqiK6K9huw>DynLb zAC~4pKIBIL=ZG4NiXovO~hT#~2k@&%z$tcMCkfSjMOYyUaZAPeG zDP`9hpY&-&GgBTmHT?3S+TtUj`ZHBshUHj`bvTGaIE=fvheX`R13Uz`Yz>d`1TNgU zb%h(!AU(VhhHylnS`Krl)-L_uh3dJl?KZQ$3vVjz1M7d}F}06~>#RoC-dNtQ-#%%lDr(BZrZ2wyPSx=vJC&@oFESt- zvZEBfMrkxg6EsD0v_MP9NNJ5248c$g!*Gno7%anbtiZlp=A9~};(xbOt*v0!IiG!} ziZX4_rX!Qvsi>-9KMvp!4&w;qj&%&j@eq&j7*FsDui?!O=L27aAsi8iLbO~_5OVJ< zj3TIudj6&>z{Qp9n&XpVHNPnjn<{?!SncwWSgl80>!SghqXhMNW?&{}V-Ds* z9?9lo0k&fYc48L};2h$G6i!2)TF>GfUf?Bu$1A*tfm3dJ zc*6&wdCbA-TK&HZ&T-Z3I_I+or-x~KHXWHWC`3b!L<*rW>Yy&_p*|X- z5&EG&;xGkMF%2^?QD7a@JRvcXv)K;USB>ydw(QAw^G$@ z*pA)UgWqr;50H}aoFkl&8qRQm9Phay4e}!Zfhd4bgrPLbpe&l^B|zo>*!A|C|1Ln| zOnKSe>-}H;-x%s&>Xuvp(-ekgXpWX>h1QV6=Qe1IVHl1P_#R_07V|J43$PX2upK+G z%bUq=$T9e@*o&LEC1U#$%3W*y`%r#aGuhtzlDC2{^#4dG-=eCwaR(3Z5NWvtNe6cX zAP@x*j1YuEUao{A0yXdrYN8gtMICfSH+09CeCA_qV(nxb+f z@0)f;7j#88$jj~?=m{MYFcFh59W!tmXK)rz^P6M(Y~2rA#dxmzq?oR6%Ik~8^kq}j z{7p<#Rl_qp$4mT4wzt7ng z!!SI+^h@$p>wo^BK3?y`?)x7G^{|fw^>7+x1ir@@jKyLs!BXtT9{h@Z*pCA^h(kDx zMEr*Pcz|bk4i|1Kxxx*30?k3ar@@D<^65cc-jvrD3+jWWsQH_qrmBX#$cF#~q5$OG zwqS&y3aX+Ss-qTaqcdXB1*7mIMq@0-c{3RgdCP7BCSnyF1B>@?L87grn)9Fhw^MVQeb`i= z9_Tqud3~`!Ut|iUzX^01hgoQpzPNzGd>woS)DZ5nV+&G;GN8adc=8?Gu6Ttq;amV> zCywC`a`IKu;%F+Gj#l%U{tvUQqgDS&W7I*yq&Q{<9Ut~Zy zA`ppa6htA&;3$HksE7J!fQD#}7U+#W=!;3goG>zT<7I5iWER7}Hk$bD@lW?>^XVKcU12X^8LuHqWr;4S{ddlVi)${SM0?;?8gDz z!Cl-#A|B!qp5hsv!Cyxo}{hw;!c0aGv)r*Il)@FeUX z5A^GG{O`j1QU|+k{p{i0#I(KSy4WVXpU@yr@eD8U62C(ZG>b| zb*h%swG~>U3%X(^W??pd!A5KX|CixH)xD^^U<%_RDZ+fQREy^(@}dc=5s$<(`&R8+ zC>9PC3&ojLJ=!&?)uci(9t+QOV{maxm;>Sf?PgU5gy5-=nmzi4E$x;5j zG}B)eI?&m!`Ts>Uc3iCb+x(rNzy3Kj-?%EKjoI{*btIS+ir%uCaW++*%rDCw=eMrz zqdmXv)d4-=$?qw7Aq~X}*(g zXuk5ovx*oa7a1qUOVIiWY6+WVtZ)_Gm#R(U4BoO6)?qV_;vRm31EqC@6S80uPT~Tt z;0E$glf0;o8fb_1=zuQh3QLWPQPVQ`7Hwgyy+1QUsNSyLq$DQ-k6ReljoFbh61F z;}y!%Qsqz$tr3IHxPXhei4^iTn&684IDq50h9`J~iu{UBB`m{otiT@p3MYQ+Bbz^y z?09nf%z-nTZ2sL|wUCDx)mwBBtD3H&GMT;8TmBZ`cWu8mggXxGKqSj(7VDSuhxc~J ziu23W)w0T&#i$i(XnnuE6!R%EP?Rk2gQcj~nSWv~#u-Y`gkPYUTb$2S_=bNp3h-MB zt&p=6xA(9ZOECUx&MaSxao!F+g-aHB(?U*|^A&H)G1q^U+~>+`F3PW>XnD;i_pe-u zS%3aNFQ{TxaU?)XA&zfUJ;b6_>bG%TvTbr;5C&riPT~|~sUP7no*;l41fl^Nq7h`R z)?ytJ5L}!=Awn?=voROHU?Vo+DW2hZ@oF67X^KoJjK{Z5Jl^wogm%9-0wJXoVHRnPSlQ`f4c#QWvM*U7D_ zXR{nSTa_h|ThCRR@3}$##==BQLb@_sr{Wb}BV9R$oM?cCc!5Ucx$(f6V+!6>}Y{nV{y5OE2s89F}_7*6AH}awtoi!54!t7(1~G zFY!BMy>08ekUFnHHtL)mbx;>Nb)Sl9xQ%Cbvt7G;djIJir?;G5aeBqv6{q<_m0j8z zAC0S-J5wy&%%5SHyIy_hV(nMilj6}DHN7~vLG_L^WR|(z!Ckz21>f~B~K8+cSz-myG(dC$h5=ZyJz(9av^Z0y|e6$sxvD93A4|uRlT=7KjaieHmmu>sGX`)fw578tZ9<=>pFGw zCN1^0L^4Z7<_&5lv6dayJiJ)=o$-v*z~C!`DHp}F6#r-D`%u)rc#J1l$-(9=HdLo7 zXj_AQ5>Mds4M!%_t;qni7Nh#wbl|sKN7WJIN@@|J!%9xom#R4UiUN6LtY%;mRM){@ zRC%HKi!tvt7uR1+yPj#fgN8^i4s566rfpR7q;xQc-1d#CSDcq@L`$hwP$F5f1arxX zQkrV0gSwEVlqJke>9V0d8el#aU?G0NMx4eOL{W=q6vVf9k$5HX3jMXPIUwNSkL8d;=oST&Ddc=*{bf*=vg`V%MzDC z=3NJ})#_n0wqPsvVLx)vnmG}RE|6cw8jcY-h(jn&YnQ~=7>n_cJun+{F^rxVfst5= z)mZawUXDGS4<2)lkY^2^)|j5=@-%h)u<<>IwH?-&A~0$_xto|Y}U^4^FDN zGAuOhAExOXyBF*-KIY-cJ~cp;*shL@OJ{5h%Ju}MDPI|s#g7;bS>{dH3>V7j3O7_o z4Or?U>(UXjKGz$tOI$y(;rfZ|OQ!$OzwHkve(2x0X8DqlNynf|#S6(}khp(9b^prX zskIFsD*EkFOQ}VN$j0>$r}wBM)MbN2lV8=Lah@{AI<$vjD7!wo3Uc-#QRLH-ReU`_e z9fx)#@Hmw4^Ma{5kKt4MPVF|eebe@|w1=2^Of4oZRnT0LM!kmu8`;K_$aO%?;ch+W zbn1D4%Ob69;C4~|bF<=MNv(=FQiu`E(E!as+&-fE)HRk}c9tQ-B(jtpKN(Xn z4Xd#mb=nY-ScFw=Ily2+J5CuW*`ECw*Ki$qI&jh0K{jt5<6nGI9*GheR39;Q8#}ON z;wyrV@Y49FzU8HevOok=9=iqG98@2bGEFTRJfgK|l1zaOm*s%m-<>e>2m? zn+I1eoHT0Cs6hvNU+mPv_^8{WZWSJ#4C1FVs-L)YhSSw0CoP+}a$HR-Mjlmji$NzC zf2=;L))Bc+sAb9-GUsKJvN!|KlTFLb%T1(jYp)`dt%)2{RmreYe7brl1n z93tc%$6u*`MgVWC#KiKlgqXdL7^yG+o_xSv^*izWCI!2FPE8}KoKhp=ZsyI(H#==N zI@)HVS=gYTdBZn&Zt}s#@ALW%)NZsnTA&La;wj!CO?QU8sEaN=IA3D{7NLLPo+QRA zl#w-{!WXyL9Ixc9%W8;GQ3uKU7VZ^=sidw)~ z4{K>1q>2@%)mN#rAER8y(XE?EbzXg?c9=iu4d*fKoXQ_DRl8BL?pSADn{|O@t*0n+ zLH)&P9V-)1M>w5VU#q`b*B?r4Q0tiMGr_d7&qDh*r<%a}iHPlC+IH5TED83diBvh` zsIk;uw#H9A5>nk%Qz_~xQ<74*)Xk}WGB;0LPm$_2Men)D@^)GDINE9e*0WYtEZ<_w zT2s+8uV>{3RQ`@qU@xvAPjAAkw|rAZ(czW)jR?A{hKg;8+$=g~&ErsBsON_wfL3{Yi^LxQ9e+jpG(f zp#hBLa1*ysco5<6;MV2y#>bIe8+a_=HE-ASdAojKX27oRmhbA=kUfVV(c^_$Q0#f3 zrgtt`VMqD9~-%?8+bX-bV{eD>4&(v{OtZU63x002sAlo88ZP5rl zVQiNH$!=lj&$e4=MSHczOk?6#YVmSY9h4&_8Uj0}d8FTBh_dDVOMNUAR8 zhL|v7Vk+&G8o$!mJHd)}B-I4!J`o2;h*a;`savlyt&?v%$a2|655G69%dpz|zJP}x zwAVb@R!G1Ds5DO{$R?{Q0>08tsYlFjPpKV=ldX3TzN0w1ARj{U4A0^6BjY8w!2_P~ zLV5%s5Cu>Xl~4uWkKqCe$8a3ZW61~J=zyM>1;zt;84?^#+;Wu3(ZrwSWX_~HV@7n1 zX;`Zv{crmtrnqRW#3e_qs$vk;owQ8mn+}8HMWBoNGB^z4 zq`P%AXW2`8Ii#5GNDS1%j6>g`P7YP{84hVoms7J-Yfa*01IX=V9LMDc!>K$L2(%=Co`l%Zq!44w8E>$cOPGUeD&-h9*=i#-u-yP>J3X* zFWsH56ifmvh9Y)RBnhP1m|%9{ie|dxQnRi zjIYoP_okaJZj6@$vrE#uTpgIN1d12pB|Yw9y8VPf6e}7i449l?%JFyR^a0a(<2T$<~FYs~(=S`29>^#T> zf8<6UW)!@T0Gm+GOBy^V1!pT&3SIZ&-kPc*+sr&W(5yf5_m z)3~~C$y~&<OJS@w*` zjl2j!D2ky3N}?KSpdlL1X>Y1*XI>1#V2p;WysWqzmCXQI=~lRdhbTCo>j1oc@$l`# zw|C^^;gvI2j_f+JYukoxtEHtIm~tfBwqf4n;gbhQ+_CWzD<5l44#%qAGl<4M+7R)^ zORJ)t%-LHMO|N-%q+4Zg2U@l_%w}6X*q$@jFV)ctS5a&sU(`a*pV(8;AKD_mIf1Si z2e-vsO`!uiq8nD?#A10K$|LWJ^XW>E?4yp{kugo=GGnJ+a+Sw07dp>!a*}=QFP0VI zzRccmR;~=zJW|R#GE_=j3D>;hd}Pze;-0}-Ji$|_6j_54Qo&N4&CH*HrAoV~(zy?+ zb%m;3#cTY5H&Cda3fn5XEG|YMP(Mq(Wt~s_%sCv!58qx~*m5B;A#tI}G(L~}o+Z-~ z68m@M(Y`C)l)>0dX>&RfY}OH9g)HsF)nb~5*c+lbi(F2cr+6KrxrxJpnv*svuBgac zK+7*2eKc1wHk4aEQwlh^YyH+J;z5W;hJl*DCYvZ|tD2=<&J&dCB-AB@DMC>J{V@Ro zJ5YpDH^XF1$1JSFddOOxMCWB3xN&7U&4SS@7-r%D9!n6=zIS+q7SpJR?4OuOt+2SbOLg+0->l~ygP-Ln+{Rn{iFXLt$h8Lwpf4tE zG*mSRW+r1d_Q0^2Z-JmWdT-^j8fmsM9Dt0*bBA}X**SNOSi{p$`Exu-CSwYIMm%JxzNa*@ zRH-S^LaasRT?|@K8CB2$y)hC3OOSx~FzjYMdhd>7Av5c71~>5>${u1FS=oF%k&Vs;7kX0C2%SnF}Cplp?jSO){O&4Q}vh##;N zmR9hlvQ^O$8*mmc;7O${74OIVbnLeJ*+WqegRl_3 zhd3+YDy~5s=2{DhhsC(uS}8v0*mj-opd@|Yq;mkf5MSJL;fs4Nxld6+>(Bq^h1l-F zxVAw%PA9H%!kn8}QG_pBEh^9HWLIe|I4-^Hb6Iv--T-r%=kt6GHz3P<1rP8NZ(u3E zEPGnYoe!-M16h{?IE{x`9*PNM|in&;XgSZFRql{FM3n8e9 zZ&3#`@a*oT1VS{*UA00-QHTU9S7)0Z7$*BMVD=5vSfv~j5{i8Mjah4n{xdo70 z5b8qaY#`Sr7-inVS)Nmo`x2Wi{lb<^TVroO$NSL;i8s#jS@+pxlX(nY*0Fh=9d#<# zDPi4d<&4U{vb_c$jyZk9nKJwvZNFGtMdNQWdTk+7nNdl6jRt6RPK4FeB9wwOslVe| z?uoQ`xK2r!UR!IXh|9IKtl3h??Y2d448S0a#dOTYOEK1$uQPlnztmQ!mz>n$^U}(q z!&%LT=*l8G*X9&|u#T2Ny_Ue;)tq8Q&6Hn>eGRyo;a^ufBf2!v{KVMWngbt?ST@$4 zjC($#eT@z$(lVztSHb{zN3-0LG87{`VQHq6-DF5 z+8j@r>M1O3;6YI>+iAjf(*I(8SHiybT9hIactJLlY^1`lY^E8TQ8rrNV6z#SswiZ0 z%BE}u%Vt`znb}G2O4!##R!63YfoyQu)?;DWPAj%Ea#M2Kk*UT*_KNI{Utrlz4BN@G z+4?T?c4Uf8kbNfm>pCpkY0Gxpw^-j{Qy-b?CS=dbUQGwfcG|O@)k*I%Z%3x^fb4tO z?_a~RosMj0`qmG((_EVyN222BjLBG!qe#Rn{DHSnF7m-2oZyBuaEAxRU@8`2C7drY zkHuJqlemoE@CaXBri1YlqE|7AN53l^<*)$8ug(#*2NQQ~Sk5Pb^Ty8`K5xLhZal{@ z+mPq+2C=vc7cc=`wd47duK5Ex9I%eTa>xcK16jAJSO`lKcBTmnZL>Crxd~;8MUbs< z9A{x^!frHS&h6HB*mRXlbsn#!*eT`1TlWV4XQ)ByTi-qyqX#AQ5cM|3A z{AXCI`Wml3j0G#-b)p#FPwN%uDLY!`=|(7g37`^Hy5}u1(bz;hW->R4mThReH)fSKVtq*_}u1V>b7-6WxR=Cya8nV_{sdm z56i`!`HR~8c7i_*omq?@#vpM0K&?oemuv)?moMJnE!^+0+oCXvVHci2yURHQ-td7h zvLFxz5QIvok2s7$_j{a=q(n|E_ze&65Rc^ln&j~t*D-i>`O%5Jn^vA!eB#lGN0ZH% z|8dxleSU2JW7FD<6~+{!vE{f`OdF@AQAeZ}%f@L1e69D&uU5%LhL#&bE4thg-3D_9 z@Ae=*>`ffZWqkBt?Q8$6nWI@-5jgy8Ww8mog5bZ1V zx?{qkAzD$z$B;t4tq{tiGMb{S5G*);v~-CJ=CXsFogW5hHsw6 z5#`UgRfIqUqa;eB6=vb+bMAZMBwpe*yk4+};4-cu@AcUd{s-q3~j#J{r#3PBj z5;r9N%=Bj-vo@F?87(s#_{h|{)Huifuyl@AOq?I94HZ+0(ZrTL!`VM_F)b1g*+K}#9IVvfLN3*nL&Q9%U@KyPx}o9 ztzYx4jDF1Y$8xO17F@$E{D$Yq_y?a*pb~1K6J}vH7UDF{<2LTY?G0ykR76!gyZhJ2 zrDK=&T-um<<;F|$v62_Fn6A7ui+`gn57GOWR#{v+#wB})V?@~7^{SKjRnGOFqXmk@ zIh<&>j@5kAMA5v~HeB<&x!0SGwe1ZSTbuX1C5h8G+axTuw)|^Ll9hHzSZwW-oUhCq z`gXi+E-be8S5-@rcXmlwZ0*X|7T`5n`9?> z-+RBW^tYLvJv(#GdCvIE+1Lhfz?tM#yd;c{Z5ub7N#@OtGnGP&j@N9~6LDz?i-@E| z`4T*dV)+krDz}<*&ZW8$fFY-?p<3J1tk2h-W??TM<(wo7dlQl>Bd`;1@eZ#(vK#q{ zEhY}&AU>hNXLjAN8IO_f3tLSDDi-A{^u{*CC>FZNWrbsx{Uq0m{+RW;^NiD}EcF$5eJoFYI}CVH5W;EtxxQ z!mz%>y0vLqD|TPA@AulqB5Hv8vfWBWi@0RXqumbSbW-Fcs%G0IYmnx9jst@xvdplg z#945x;ngN+eORD6WTh?@=e(OR@3I~ir5rY56N0Q3r3lubkZMtWL4Hq*QUEjY3a=6A zWl^T!1l}RLw?)Z;oZc2~RDPNYk1_C6Mn>ysEnzWY@qlkh25PYpt49S!5nT)G; zfj+C*H_M=;8hhBIEjo9o8`@d>>5AOZBvsTnPFDYB_K)Lar4X|ZMmuzbWGfw6$$&W7 zQu6S=8+xE8`eF^%!;;LRgdh})u>@y*EXpmPjuxeGawd+hScT2lh8XO{0i3}(oJY-BRt#9~^Zw zy=EP#-M>aS3ti(BV76;iQs$nVkG^(M&g#nBbuX+wcIqbf{6b-BoT@X5;LQ3~-XFv7 zxPjLQp*Z2FfmWD~S(t;>xPv$FqXhXNrLKsUkkWSq>jTN`#Qfadsz0Z~-D%Ucv)R=y z+LBNLte;)yiIrsf{W@}}ZEurdf#bT)ntnAHlC$W2rLQA>NRPWJ*K+ltj53ohkg9f8 zaolRnMb##^S(Fs8;UrGsI#&7;9=!9jDDP3(-=a+L9K*9dqFMs7~hA9|Y}p{9#1r?s))x7yqr)|U4468^Y(3?Oe= zksBpZ8x7GD-@}eEn1EG?fwNpv2Fd=vDOpvdvM8T1GPOk+h3lA^h9E*iy|fmke%eYF zr2zve(osRkjyHnGVIDdEop^NO(caB#^?ys}EuFS`%;tXW`fb*OYee|;P3uUl^)1#Z z8*f=FXs`ZYbwYDYr}^+=4^5smw*BR%R+Sx)EEXqwlFi1Btd=8-akCppHd{cl{Uapn z&RnYLElOrI#CV*-X*`F~?i~61PYVvR<~6P^>K7JyCM?u=9EC_`)J|rlC7#VltbFB| zuxDxl_DG&rT#`vmt^NLiao6v0J>cve>sR&+QaK*XLS|nZ4Io*FJNs`ku;xH748{;F z!E&6(1ym1Y(ZUO?&S+77!ym|)*`j1ZX_Q4PjK?G_&rGyFGw=nWSxAIln1t$CS=&Cm zaq`BIoi~oGUvB(cxO`^h*vOfK^?zL)uiF0m*2~)QKdlkk%3G{P^53%h+QVI4SSWd= z4s()8DM)W5%ye5a{oIjxFEX78MbQD%F$;4rA5y4mSeD76{DeUAE`^L2qZgXrbPrpc zr~CD5tj;T|#(38w{Rw(V(YFw;PxT?a*A#td!Bg(jS#-}@G?^-Qviug_Tsw8onl*O@ z$;3oR&HjkxSb^2pfGwFV+MNv^ne>O;j3?ddYvsnX3s81EYg_%Q%sV zg&}l(e(Jfkpmq5+tM=b>Yq(bKg|$@dX7g+Ng1J`3dEQRKK(`-CW+_@Siggy}9L1|o z5trj%WTKcuunC*-5G5(H6nz&m=VpC@M%aY=NJmvjmGq5MEmiYcTw9-fvbt&!`@-r< zp7(TamNLpipRx%}Wi)Y0rrmmF&E7U66VdDUHGezivnaFi7|!~Zy4DiZx76!V@7QV5TvRJh)Lk=_Lb49GSSt-_KCUh#w?VYY;bMk|{EyjKQ@awsY_( z!h4LxJ@|cPp`UCT6Z)bb&IMZ(|DqNpCF&JpJBl~O?1Yhlmf;p<1SVk})?*8{;y$`X zSd^c!2Vuoo6XQ3W#3`gNK`n#r=o{z1t8cEpxpnT=kvBW#A6rx1(w+LhsHIVnQ9Gk{ zS~hb%#ON49>;1`ELc9No{kt=7S>ycqFHabxe#;uW&Rc8omLXE;rfB9U{3-tWQTW=J z1!ra4a8yWbDqI@iL4)+as3uMww4*Aq+bb~`FeEbdA<>b*_=YkLKj8#kBU=~;N9d20_#L?k5ftW@ocA5`zdx*^das!ah%20Ph}_e!t!O4 zJrevg zzpvTjL?mV+rWY@Jk-iK^hp3E(=!ou^iXU;ktVJ1Dj+JD2_G_>U`l;x9Ja4=C+)CHK z`77t2o59GV=f<5I@?Dp9v6ov$m$;zJexVl8yggapd{#LcYGL7~mY{u9<1C9Bto>n8 z^JsTITB~X0Jk>%i^Gc2zGxH{>NCqn58YDB%AQ?LA$W*a78QaZp%?cJ}F8;&=l&Z+8 z0Q>Q=qD5Qcq2|}td8pjZsP9o`Ay4dEW|Zp?+}_@rA$`G#_aa+=Z)4@ysEmhp%SX+w z{bE%c+tW#X>_H7?C9{^<$}AnTQ_@sopAADW0zV*CW%i+AtHRm>%dj7Xzv1W|`|%Rr zR3~^yUW08mvf@|#29KH+rC`k*5{x(8L35NlrI-Dp&6xORls;le?=HJqZP@k82K`d5 z^y#Dh?oUbOSXA})e5z<$Q>bw^y%HnsjLNwP;u9iaD5*{MR4dv`4_+U8py0Y@Cdr+> zcV(kiV~Z)pTN=}(=wIx^{*Rt_8FrLE)n6W+>D+oJ9-YrnQ8)2>TD6cfGG_N~*& zd^@8nHsd2cL&8xtPDmsi&QMqhM_GK2>F}(@d$dHM+JqZ}u}Ew8j*F^G^0SgoP%3W7 zkJCYsabKGhjmYH;Z?8|G|;f$7FM89S+_RgHOm+&!Wu3uMId)f-g`SaJ@zlbA}w%;c|j*Z#|` z=F-}Ds_E4EHQUhNc`=r-Q-xSdd`PaQaqS`|Z_b69vYu=rvZhc2TjpFuX3sz}{lp~W znd)+K4Basu(fAE-A%)6~xsJjeg_Ds;QJtwiS4z)U3l&9Q}zwOZSLkpu8 zMvfdjvRC^i?Q51V$&D<|+nMD_35Nm@_PQ>z)e(W!HNPi@gD!dS(Kj~#W}0h?au9l z#+}8q7HKj@yK(fhq<6OTKfl!B)?~j;u3&R}083GJ<2m8$fh<5{(yGHcq>(C2i&7Yl zz4(N$TT`8Agnf`|F6gN07yMn;mNo_})h<}HE~#< z42l+=N3E?sFMXGb8QIu{>yeF3(voayI#;q!ovzWHP&&0_hl13%lClfs#0vZjskb3< z>Mkqw=B&Si3=g6XzlYT2U#QT7eRUkfA^eFZ$MDg=r)Avty~B!m;ONL30hU zpBHM}Z<5$fdV)_`ulpKX+v_=4ypCm2IV{mndrK2=-ieZv-FCf6WFQOl7R06qB?)(9 zNE3(~{t!nK=pUyU<*H)B!}!l$Q?HNiE+JS9~q)x0otBiY6)#;4mDrn^fK|Qa5gJxO45Y( zI-1enj;6GMrc}K@ySwOwaaf2&*o*tfK9CDZ_)oJ;r++EEe^6H^p{_?Y98oA_7 za+WYhl?SjLB1dB|6IW4d5DO0K;1M3<35I>ob_y}rjzfbnl+%WIi+9K}jEyI%qXq^H zE6I9_ftmObvoLvtaim1=1_!quTzBxNbqD9HJGgG@x`U@ioEp&=`fDeO6=3WL1r<^& z7p0H39|JsN&vMBg1ZTMzJ8G|LGWKo(?YG?QwzK~x_6fHcSlL3lyxB` zl~Vo#XGx`$I~*mwL}{-LVO@nNN~%FhpN#@#hm=?fw|$s?sws?pA@-~}XRi<3$V?pd zBWC?HzN^bk_HDap(b5)o7U1w}NIo@7+d!tFbfA(tLMp48onh=8$+0-fjv_kfgwA-3 zJfm5lFcVwGaPkM=jAhe|3CJ>z$Y9Gj{e(%F)>AGnC%DYa0lVWe^UY!MsmV1W{ZPVn z6v2?uO@p>1NNr=+*8n+s&824($#^85;W?^MfNxM0&H{~Qcnrp3Ar@gVmfdknOC3xNhg787p{$5IC3F>dhsWwebe@}+RHwImgXz9 zqT`{FY7;z-Cl61K*9RO=kF@!Uh*T}cjt`fieXLb8Zqe=*WEIYXCq7onrTg%F$V{cGyPzAKRZdkaHO6!FixVh4fgL)eo=Ax?4r}2x$)e;%c{D*sbV4MiU>mmM z1-_u;WR77l1p!4OS)t-K>IU1yW_>!Dw_M=#s1MNf&|K5oP~?Yl1DwQD?u zvQG-*e8YU6n$d2AQN}GHJmyFl3u}98$;H?*guQVoDR(GuZxtj->td=O4+h8Gc71Ho zRne}=k;suEYUU1u>bSbL%^{^$C~YnzEdAGx8aQfF3;8ISvj(KpJ0T@jjFQS(zA)p+ zP+z<2y|c;cTt6Pv&)m{9Ga7v>d@UC;orkp%3DNT2vj|A+6NjPTY`M zr1GR9SK%_UOkuwcJu!MJZ4}p$ZW@=~(GYJ?fWA~{t#Vw(fEF~q9($$5Ost=@8&JtNEiL+Ev zqFSgH#Y!1Fuv3OLeZ{Qby+H@ZvU-lL!cLIBOVBfUoYkG9s}8-F4r5Q^75nfsr<8Kt zLhIdK_4G|vn;T>F4mc^FHm-!)$DUT|t~@HB4cg*cjKxGu#UlKKwb+QQ*ny*{N-ibW zlG}?$j+H?g>j{iUB-X$-hh1M3n#)l!>SN#BLTn4>vAUhlHcWc5mftoo{%u=xbn($y zlSWLMHK<3&9wT~mY_4rA!+~G5Fd{ZNjBVqS+%*+#YFV|S_Mj{$^re#k?e9>cb+{yP zJ70#YQuj+zSA}=btGpDQ4X^Vom+|o3(FvZ47hB^l^xUD)(@^|0N)BqD-!Ejh)lr7a zj&fvjl;u2s-#E%tSuYQpWd0VVNK&kkm`%~5=BG8vSYQDafbN*Fz!h3LYGkFL1&?9@ zbH!Kh)S6yc`e-atrM10ZtGU{y=WEIVoWmtt#X~$s;6lzqAPQ@72N@Qz=|yww!+tbg z%()~?!X7+D?j@{_myo5>)~?3>DA$=nHM8?_a>2>9F&)u>%0FIFjnLMYS3~USC6;kB zv5QRXc4S5}A{n>_nX$}t?NS=wPc)e2WE|aBaAFGeR&wyS%A(xH3%tTxyhoQ`IL^RG ztil@nh9|%D;9M&Mc~*165rwg84Ku-JTv*G+3zUwgR!|X@@CvU%XL3)kK0SAI=h4ml zGhWv$asHb-n}57B{!X^L_VvnER(opaE2}|qo)pp7A+%49=*y_VJ&I7fN_`6308;1& zc!>PVSoSdj(=ZdWu>z}b9a2F}9F=6Fa&jO7QdzSg6?PBrex?jR6UEr8OZtIuyqCC- z;Oaf7(>Y8&qjMO2KX30hYHqvq((6BBx#I}AVWk!f$rT)ZC?m7b;}c1Yrs5P{A{VhK zh6t2Ib=1OOIAbaC>qdx1L4(BYUr4Abqd8$};bp|jxN|LD?j2V`^>L0XXPls@!k(&r z_2x!Z`tEgHtyPWf(cWrm5&bGzf>H!ZgZKx}@D+`sA;w`g=3)WXVm)ra*;v}eX)vAE z(GoEg`|%Lz*Rz!4EY87km}i%6lJy;G$Kvj|Xv_6l>4j%+9o0+QSwpRC50sXuGNH7{ zfP^#gVWR$!85P8OoPo^n-wo_CZ)DFED{u&Z;xS&qwuvnf`eO*DVJ)IDWi#(L_a-h3 z*tgKMuoBl0zLga{o?-MhHsm;tyQmyvQQBh&xJBmS`D5qlHtE>;b?4Xdcclz3SUG#; zu?3SyOdcd3^8ZR1Cr^WD=W41ow8FL2wp!s9TvTJ9E}QmM6Lx-X)M9O(wX&L_t5QTN z@(pE^@=4h`Vhj#L%H>P`rCd@TDN7VZkYe1#N0Z|CQw%9mbw`mZP>iSPVLSPSW%J5DKggU#}rNC6g;BREvt+z5o8y{>9Hm)NZ`wGs}2hQi} zoqGvs+0eLF;rdXVODiSV#BSg;gBI05t*LEj#`We0b=1H(rAsG~mK;lNC8v_hVdQQW zwjc(QL&;e^+(G+2v?@%%d@Mrxy{ri^7PIjV$@bAq5sGqXi&1DXj+gD&jr}-)^LU7g z`&pBtIo9DYjD12bVeaGKmbLo7C0k~%<=?c){F^<3p)KEakw%!K1y>>T!-*D6)Jodc zCTjIK>+;zR+H;|zCrO^x<%lY0y|{aU4Q$`U?gi$T0%vs;dMJORA%(vSsempR<0!Bc z)|b5Jf)sKRoaJ(srG-%*Ek|YU7tl{=vKEo{M{6`XT-W=bbo53Tdu*Y1-liW4>xUK2 z&f8o&gWBju>hP9nomKUY*#sS69f+>@8{P-G9|V)J3g^(|Fb5Ktj>EW)s3UBdk@YBT z0l~-E1v=*1yP<39_da-eLo8#6!3A8zEi@vhlJjYB=Kh)^_gTobDto{E_BrZdDqC98px#2DDHoYmIu+ z^+>WNY*Awm8ghqkift}|)RR&P&Cm@a@FQm7KS++c9_MT*24FT;;vlkTPGM@UPn)AtNRC*1|!v3-Ig**A>{HpWLOy?PYZrRjNFWzax zG1U47YA)-QKBcuYt<=o+^ioGMr)IyAOWa2ClPtX`bBbLo^g&K0c@C}4$BbyJj;846wEPCsP6%&yQCR<&0-HT64}mXIG`qa5m^0XAVX zw!rfbPGuo0-aN`9_g*|Y#lL%x?r{&s2JRUf8QC|oP2c)`Bjqfd{-3t=J2sHhHhXxb zJ`)-52=Zyo-?h_wxuf;B9%?=9a8EAobBjh*t$$CoqBT5AY3+6kHCx-P)Ie;ZE-~yZ zNMA=`A{_;~z~4+1N($B#btzmuNFo2mBV?qo)iD&qaOkRQ#p}4s!rA#3M{{zN={ltA zE!TG&==Tab?m}47TWwp2N$7QWkH5}345qHKQAaf}{~FoHnrn_(u``}8W=S8F+xhig z)4Y^l{&vtli@b_8S`9US3WWP89vupaUca+q7{0g7kXn1PT*IhyTP?i6ht8m zKqRK%D30OYjRsu!yh(hK88h)CO5dUiQ6CM!8vZK(j@{e6W$n^?Yqu~m7=Ug z3{G6r{Q9f!ty89Y%EPopwBiHQ;{{Lf$*(wri@1&lcm-!2NcnqR*ZgMCvuE3Z9MbT@ zvnB)8EY_fDo-s@;#FE@qIhx-lZgb|*+qD{XpW1l-_Wm?|uKIn%Tm7U4$6`8`GG)ov z@ab{#<+qeimf<&~y&?17W6e5)nGKVfrKMJ-<_q$P$;>Xzh&wZ9Xu|nIRld+)eXe~T z$vNp>Kg6A5RX(nUsbGD;95ZVLN2^P%{xhAkRf(AqL(|zFof&tw66h?*kCIF;cD8MP zj5FKRCHc4%X5q06--@khy^g)46?f9_Kev7U-cR9qneH8wS!8Ll)I=$ojWnbBe9fdL zVrIq7lCzz)<_mrJLTr}m&W@8Mzdn527b7rF&(0p}i`kA!uuDT7hT)ixEqD#(HY%x# zH1BJG{pS ze8gvbfu#y*9=-Yf&FPZ|9=$nz;LU~=k5-6zGp39k>@c9G3{?=~tCta7lH3!NG zI=ar4A-OlLKfQJ8or8zR?k>6Y7EW^MJzPoSoQ%8+uAW;aC0F4(Xw}E5zShF|k7>=v zalJrac5krkre7ZVJa)1L=fzg6X-HQ^IYT;C-R4W$t=NzAaU)t@b4GN!dcu!SFTjVY z?odh9{AaMqD7b*OeOGgYHKt>fn!&>(BvczQNBz?~BzvuP{n~fYdd^jUlm^&21>bXq z(RjW)!2&*ajx$?>)vf*#?9rHt#WKhK>N8`Z3z_T8*i!YlKc6W}@H4gqf(xT4e2A;*6X|DOsnX=CF=QHIwz94;Ny*hSV56^eZvBQs zX?V`|_LgC3Z~sBs+o#G}k=5!h>(B+xjI2?&R{X>#(h3z?ptM32p74V|QX(_HMj4bx z1ysj$%&4Mj2R!(lp6=_^t=52ro?4r&>SFESdbNyQre}pr&kHvALZ&U#O@;KxfQ-ll znU~C`9Gvs1!Ehh+#Z*iK^Ht_z9`@q^j^Y?j;7k>@mU5PXPxy=!-;e?LBPCKHHC{fw zfAjuLdAY!!mrqY0J;=YOJEB)aFN~foe3Y96!q{?*rr9QIg)d1j^VrXWCO4OK6-Q@MXR-CA(|cm$!Vy zCpM`gOTpDs#b%2vB{x2ou?ZLWRE~9rzB0(@%!<6zvtpEtN#u9d_wg$Ju@$WNQh%?t zrJ+2(6S6^lXKn8c|H+MNXgc}S5Aka}Cfydbip9EVp=S&&CHdd}#gyVoQ6)?%riAma zsFv!mXD`!{DdMEm7Ju>V=QhIaYvp&FOiM=k#+jB9uJu{$*~es5ycwkQ@QOc28Ij;i zcb2+MM@Ge)&L}m(blgUKPMAVQB$(5gR=;!UTXEx~l$Mx0KVLPjK*)8e&mbCOZ<=2X@{!JK47 zf;uXuom=kKj*O8B=9qH5+Z<(-+w@G@criT?38pt{qucakl-u-7+Ica}bmX(eCMA)P z3Fh2;i`$%KRH}H(4a;l^?Zslx9*K-jkk3$U=~}nB8zU3U{q{DuxyvZG>6yeOR1a2y z>DAleHa!{THa(NLgz9lgP{2?n%&gqb(Fx{WcDLKyWt7|8O=1(OnU3tc#iSl(WP&+w z*y}cD8I@qpVP9+w35$Xeg59-X5T%-#R6+uUW8+cZsM z6Xpn+TV72TlQ4bRNig@3N8RQwqui!v5}Pp1BsMROyG>6ss>q{7W26>c6W=V-S%nk-4-W^1^*r`>8nM!8MTBue3CQ95weZF(}wZF(kA z3fH5Qpf!b?ui>1d6HGV4ELw?-Oe`i5TH>FWL@UBT9 zCCp-Dj7$)lq7U7sC!^e^XA+wdW^1_;=4(0UXt(K_#HfT>j7pft$T`|=x+XCyVYarL z@sC^iWt7|WOyX0*EIyX!Zqt)d@unA{1iQy4(UIosGD)8JCvMS_08JD<@mO564XTmKX_?U7jChV+{(xV^Evm{ZF(}wt!~|7CDW6UZlyQb z_mIoG6F|e^FLjErC2C{M5WCn_S` z$7pWn1|rNx_4Q6TDNRPX<;)}!Cg%qtG`I5u#wfSxnM5MQED~<#2_iHZL??xv6lXZ+85OO-TgoYXb-)T(x;T(UM6t5&{zvV7hrQ+P<~3BAiF zi|Jk7XY*8xs^vQ4lh6A$y~4<3>YeeKn>me_V=~1kOKN>GUfQR}KItuVn$5tTA#%EJ`j`-VU1Pha4J=n-@%eMoZwn2rJz zDK0+|fkn86n~?t`MHcA z27cfG!vm?=j6B_ndYSkkip>0!2+EV!1L&KTo*l6;8{H&lr_*!v&A~57<)lA$e%?l2J=O7G|B7{;S&;fgYr2A``8y`z_>w3Vnqy3Tu6 zhu_F)NQc=?8E!_m^DXHcxeEpB!Sw8Xn9=uqVKmjny#tG9(9`Q2I%l14{G_P-xT5?> zU*#RfZ<5K+5iLAx{IZPv#)$k>gY<Kauav(C;rAic#ao%jeqeTpTNSUSm6m9{E-!fAxlpdv|yM%0eRal8~Ql}6Ew+{sWaJqa&r;#k+ke?;*0{LZe`3Z6Pt#J8G@Tc}kR5J}rehXQC zAvX6<@?)TUu%1S@+4zM$`MELq-7fi+C;8PM`GFm2T=F9?^0O`SBP{Z}D)K8S^1CPU zD<<;0B=RdG^1C7OQyKE(7xGgU^5YcpQxoz-5ijnLap_QBdcv2E?xh=h>7-uznwMV4 zrK@o1>|1*CmX5il=WXd)Tl&tH&as0a-CIjn)Y8|qbS5pmMN4!_xWXXst>FXoX5g zbVe6+!(`B?6z;%P4&w-pL5k?jJac)lJmg^@FY==*T4M-?VK{iGLs^X7xQah;4L9%! zS*%1JrBE7W&>Ew#5R0({%Wx1E@fr!G#$e2bhB=sr zoj8eyc!bCJ2fpkp6+mTtgQ}>GZWxOtScadl0!Qq;+`xN$z(;&WRxe70Mrev=Xn~=a zg$>w@E!c+3_=G@jdRs>pWJ6iB!BC8V9iy-md*%HfyxhP|+=gs2(xNCr5rzmfL2pE2 z8m8k1Y{V73!oPTn_XzZ1D}pMhhU%z^9*D$Bto9-PYZ!>eDLjPA-kmp+Avp@-8?;9! zbVgT9!eZ>gUhKmG+<`3x?FofY7)4MU12Ge`5rsJ^WP8ZKU$EL(lfxT6D1b)ji~bmZ zLC_G56F7-eID==%?aS5#6;TOQ&Bd?GqDaEu?bsn5h>G< zQ+$PBgrGjgV;NT9XRN|;yn=rKD=DNwT7;o1#$h5RArfl>i2tt)Jiy<0geS12Wqp7O zsEjJ8iY^$51z3zFScZeRhcEC*M_Ym?@}M#LVE_i=d(6Q$oVW9G372sd?~pA$YcrHV zS(HaRjK(4?#WF0%VZ4N227aaisS$usv;jX*sEh!Qk}0FG6esZzk70kp%TxFTQoX2& zI;e~K=!a=ojcBaH2Asun*fLVxNQu-4L4EW>U-UzN%z_+Coxn+)!kLW3{}}_eOtfGW zLSYm^ZFI*3OhzQ8A{wXgH=f`hJcEB`;*5G|h(>6FL0E#_*oXZ%h`X?6A^zF2@N<;N zg*>Q?_ON3##$X&);3{6@E#BcjWaKEY6566YI-nEAV;z3QDV)YxJV#(QGK=DNUP_=8 zT3{69ka7u@;wK!!b-cp|e8gvD&CaS79nl3{(H)W4igUP#OSpo!$dH4!fd~|by(BNq zF#_|j5R0$``|$+HavI0AHvamd2&&*)bVMg~!9*;_ejLJK9K{2q&c*jo6d?#j!(7C_ zKLa!HBW58A+i(Vt@f6SS0;zIyV20l4hwm@|vvCEl@GsutJp%KPQGAPz=!7nqh}Afn z$4-l6;8&c)6Zqw2&4wTpK``o~FQ#G!e!!2|jPrPk7kG)+2*}5gJ?fx78lVvdAPSqX z72E8*Y{yl6LSTNj-^hY&D2wJ8h`|_wVOW42xP+_t9oO&y84K_$J1BvYD2@a#1|+9S%V=b%Ah$~p*7lKBo<&hc40U6;wJuvXCc}Pe2@Z#P!%1}8C}o~ zld-Z8@jt}CQ5?ew{Eb)eFHECB8l*)S>Y*q4pfA3|kGKpuU-Ab3;vF&su{lOLR753I zK_@K6F6<2={`(j>fO^5~ouD6Tgt6@6C~}3f4!}h`M^FUSiERie&cv__uaLO}8N+21 zF3I|%EK36Z#k`8_XW$(gRbmy6O?F;d)L`X;ow$q=HCc0^8TR4?a@Qhbn1GYWQJZQ- zT^z<$w5h|Qi{p5XjCE-Ts0R&a@Eld@(U7qlcE9>0z^gH|{IRrLq(c$Zz?J#5hXuqF zw-&L+gJm(R(2eXj;vW9QCj@O`?RlK=U=RxQ=9vhL!3JEzJ3Qxbv{65vIOu07p-8Vz zDrZ%aAvtm)9PKCa%ovVf`$-<&;n1@?XAyBf z>yTiE#p8aM;Ik5meip)ItHcTs!iAp}nQi&(@yiyXge38mVo7|Kc%6iB8)~B2$jaTR ziGHX=XkT*E0ygYU;l&QMc{oC-kHkMqympEuQ9H%BcQ(N^?Xfr07E7XziqTdQd@;`V z60f6TNz{?t!t1Np%}ZZQiPv!AwG9bv;+aXjW@Mt(n%$DxAC|zDR{7Q8Qsl)QsGuO&5Cgy)$WQ zZd=}t@t4T3BT!^GFa5lPfc zL=rU<;Z`$t*AoH}392T3P7`0pL?lr&+$5H00gFq`*b`Z$%ght2w&F>&nc_**OmUN% zu{)oS;I^(LW*EQG#I2d)Nwk^bNz_bnqh>T~9$Q*_L=q(`kwgP3kwh((NOGF-mMlB@ zbhU#LCe`GuC2p)rw3bRF(SAxKQA;Hh7Q)10T_Vv2BnwtziF5C-z}E! zC0;WjNz{yUx7cLIMkbngqX|i(W)j~SmT8ud8#0tiI26R86V3;7q&_Z$W2sP1bZ}6d zl>=Py8^@UqIect~-q^*#*U%=0xy?Aw(1wFtY;4EL)b^aC>cF94M~*{Ba)xg#2Tv0? z(4Njw|Bswx(>OMp%V`00n#W-&hn!^>a^{A^P5;$)P7iJ1hJ%|e$BIq9{|&b8MH#pp#Ul&%K3;`J8&N^ljk3_Tr{ zrQ51*d<)*$#9f(1~N;F7zme z0zK){uor!waDcp?W8&;wn5;K|9?H1G;PFtp2%0*K{v$`z8{-6yrn$8C=L}~01HD(w zq@$ZCGQ({KRTeN|tX@Jd`AbQ&lIyY?EK2K5jN8oZ5_`FxyN^O}k#ZUb)#Esz9(*}w zZ*hJGgiE8AlD1r02Y=s@_OA&(ryZ2D1pfgZ2UGnaTz4S;$v6p8oY;$t#J??Z?|~sW zOZ=x1f3dn5aVPeNafbLeBmQ>cKZf{!A^tsye|qA7nD~Dn{&R_c9%6rDt~53pz#tmH zw={r$i#b8Mngep;|6mg*If#ES@ed;Y_ldvL2I3z<{M!@%al~IVCH{XA{~^SG2Js(5 z{Qn^SLtj!L;=h~tmnZ(Ci2p_6f5b)~4r%N(1{%Oe8bBc$z!e(6KZWVJhxpGS{@)XO zui{i6@gGC{UlacW#J>pfe_E4R*QL8c;(v?yk0JK?h=#D6^TZ%ynU z;3)CGMf~3p|5L=jAMxKy{2LShO2mH;@t=K?cBIFjzHYyG6KpT#=CTr8Ym>{e`rBKM zx5m5M@!s8u_wH`IclYAGyC3J>g65og$Mu#h!mVg0TWCWlm`fTWCuaDMJ9@NhhMRux~P zGU}lbnxhpy!AeWdfdZI{AF&17!D>($agn=ta02J>>Y~N2d|)8x5}k{oIa;6;J!a#~IRbW*zE8hQCyyXj4#ar84!ImqkflcMAvNutb|K68mVZ+hV zWFJrQ8ePBUY&2e$;j}55m!}HQtO9>=qB8fuAgl^o0z7TVSxgjQ0WXTy=#0KB=tE#9 zPE)ZLC*_UWf)zCCpcNKiHT+w0b{mb+0h_QNpWsiBi=rgDVE|TO3%pu0J(R*XsMVJE zVdb|hz^qyBAwO%EJ)OzS1zx&$;c^Ooz)D#95nQxKN0jK##PIzHN`Uh;`iuB|6cfWg zcn0feu6p7hyhYP-lpagQa}FQ3@EULN3H2th_%vs|7CnjWAzntZe#5s@$P~Vs%Bgi6 z!g-{f&iP&R!B~8N_Y6+K|G;Tjbe+j65F;@jhjAK@@d8y?ch*7wSzKtwm06VH0Rt&! zb3PX(PywId7sU!2y)hMw@RAj;Cud6wq8R#M3_|8nwWvCu6Vk}IfcWDRYzvv@B1((w zizyU(E#Z_rX4`pLhTS-cXLyb5OG$`gh(LAJ!$^$9dhEjmJcG83tpdvaL@Ch;-7pkm zF%3UpDOO-RcEf&(m-G0HjLV4;KA`5$tQ=5tB{Rl%7>RjUjZ-*}&+uJE^`kVpVJOz) z2=3rdyu%0N|Aq7YD2oce5dXmp3`Z2!;v~-C2JYZB-l0V_6URI(!Ev0!ZQMi7bu1C+ zjv;t}Hz=~6wHQ8cBy^it47X5fY{1?v#Q$Fg)UCu1bubMJVA;lEhN@_ccd)T7weO@R za0D0Ow~HM-1fe8ap(lo69Ohy*cHkI%cXN3T*-^mGODpumFigTRT)_i8gLMy$6S+_n zk(iIwh{1W>#S8ogzrC!xQ3RzCxR0dk5}-x!X+~d!nohLO9D%=8YgfC0e?`7 z*o=dC^9S))ud&Rc12$nl9^GJjfRDFWH{519haEd`4Edi@QZz#s^hSTI!3I3UKgj)z z7~}493WB~bC_VDMnu(#!<7mnf#0zR@HKo;acFhWro(!F>qbjBjA zz!t>d7*0a@M2#X1(xW=+qcytVdkn*DEc`_LqZ!zU8+d{$pV`yEVq zfhsphq8kQd3D%*XC%dMo>qS>&n2H5Bgmd@|i#Io9`mjTRyS83@Y5y{@Q_P8g0KunOC78Mlx;FIA0FsEl#= z0Y76CO6Q{{(Hea)29Y?1O9;%*5eCYl0lMY4Q#}mK#tQ7luXu!4$WnmVp$?j19)3nZ zK_-TPLj1)h>_sGpKJyR~L@gmt5$^uQdk%+^g>poJ2DpnC*l!P`qd546(@+o^L07lf zgP=!}I}i<|fd`M;(YZ`k|s zB0n`+p$rGnC|j0aFTrLU#NcxD42f;!DIredGM?ZAQdOV^PyzCbnoscoeJT=fOv6HK z#xC5%Kk%qTp(_#p>Uwei(vgQC@VSOTLk1_yB*S8yGV@CE+WxkVi1Q5}uZ67A3# z6A+2pxR2sBXqZ@wP52X!;K|`{T01YHD1~;ApMso*8CZuH_|)d-S&$1w&=$S06?~ngir8jMra{FEVuwa;YKs!f1iO|&4~>fp*fPbVC{$e zt!SnA6~CiY8UAsjYfd+-B~r_Ilf>_4;m8A4k9s14Q3^Tei)6}n1{MUIDE$3p{$r-A4VvVW;iP^ zltMZDhO0<3g7GMf(y+JYr9Hl)CQ3kl38^_2L4NJ1!YF=62zHFapZE*uM>8P=p%}`b zEQVqdT8&|8z-Uas4`bPK;x7I|&hcboJnm*rJV(}*#1(bX3cWB4->zb_j!_to zfxi%PZ25)wA7J1-ZX?ZV_Dm3iBiOx$O(eY6(&scz;w+Lyv!+AXdKM>i#&Eoc?*>i; zqCC!TWETy8ZDNCk>VVO$RA8JP%V61fv+L zpehz(DWqrf`*@7!c!jsPdxRwhmZM|s!Z`MWYk=fS&)G%=~Xpa3;)%+sw5(jco-id13}Pwk`G0!kgI+$E0g+YiafL zR_ayv*3J#FE%r>tU^4B%Oj|)MxQ)$Ad-kJkTY{0hjrTDx+So#@j?b2Mw4HVg-Wd}+ z$k_B+n}s&|OP^y~o@7!cmNO>PRNLPk+WHlI;r1Y#V?Nr_?`;np-%ZsccJTjV+5>vq z?z?85UTfRe7AOS^)$06U8=c^jGjZSRc_%AbwHvc-nKl2PUCIB4O!1|X+E;^^QFJR? zac!gw6&_*B;5PNT-JJ=u4t6H&J=i><7u_?EYbF~n*UnrfU17wul(uPzE#v=NxHV^m zxBZ{1fnf5q-Y+)Km^veERu8T7cp`dptgX=hGIL$hX zHlPnV*x#21{k*rWYuq6GuNnh&*XaK-@6Kw|o3!4J7R8;t9=rd)+Q9#~lsPl=!kLBt zp%wp+6Li+LvDn^CaQOYB@0+ zhVmfq45elv%^qX>wcy|VSJ9F0FFeJ!T1h#4jZ*QewaU1TYn990)+(VXqm`FMqLpz2 zqdAkHjoEH%tlijd%b>mAPOaqFVax8ZF;uIu!!}R*dxx!@7PQk=TI(q<(L1TY-*?*9 z+GQIz3i6-4eko@e$w3f9LjGf8A3H4Lo~Sc&d34Y};-xm~a6N$2ubnvc+UYdT-~xx| zY~~(vaZxG9`9{uh%UAfj!SVjGywAdjtBw!;aQxkFDW@l#m`uyD+g8nzJf{0@ezZ($ zxYu^J*o8E?yz^zh)+xwx+Mm2s=Ca^44sjJug34AjWqoVHvGrq`>|-AwT}Y@*-}T=N zvN+>{w(+!24tmeXqW!numLf&5G4+(^DV1c`zkHHU0<{7MY@IDW+7Ab8fB7uo%U;N% zjXG%4w44t;nr=I68*H%zYeSCM@~I6=7Z1}`9I<83o_zQ2g5hT@bs`77DA z#`N81D`bhG50A|MpI)UGklj%iZHH4!xn=TF5Av6iUA|}==&?Oqt9{9q)3QqId&w5z zUp1VNIg)xPjkT|?u)lHfl5M{haFvF$_OflFC9SsS5?kk*S8T^Esg2=s*KDby0=$xG zRj%5~u&C(?7F@M;(Z>G4*E0WZTW)!+9r)dL$nrw|q}LYwVVh!kY7F!3rk2OX@P=!) zVU~x+aHZ?Ehn7Db!#8ZJEO(7z^`>os<(9VertOxd-eLM5AJ{T#4>Nhq)GFQP?G_o= z|F&(0*5R(q{SJ%&1>>tHW%#TyJnXJ*tmTwuxo5j&`Bl4f&o;qw%=l#FecL}4z!;nRfo;EKuQuwIt*G|=K#Im%kH2g+eZrNjdWCM$4*X^NDo5OVeT_SGjQVya zTW6lExFamiWUI`RMI=bJ%sd%E)br$=+5+=rVF{8&nJ06$Q0LTUm?tZiU}}@ilZ7Nm zHr6~@(FDmxm?sO4O_oJ3@%LuQxMZri`&^(zd3P!Tr=E+=9Fp_08Pv(k(kt~CGGFKFgWU0-QxuRes zvzaGzMZrksWuD9#g$O0B9tA~DmMQKUNp5X-MuBA7t{1kjc&jW);H-b=bXak}NU&y; zWX}3`CSzr8mdsiI&Sb3H&5}9m-kc`{cN zjATEXCv!!?NVdd0nJWrLvU%poTv0HR%`#8sih_}Bnt3u;6f)^im}r(v9%OJv!ALgR zJeeyBMzUe%$y`w|k_|LZ=8A%mtdDszR}_q7-OQ7@qF^NJV4lns1tVE&^JK0l7|EKN zCv!!?NLJrGnJWqz^(fRdOD1a(XB3QNRm_vQqF^K|XP(Rz1tVEW^JK0l7|BA-lewZ` zBr9T`%oPPAS$^|mt|%DEa+)V|MZrjx**uvm3P!SY=E+=92-KsH(kz)g2=Bj@q*&pV~T=kzpum6i?$>i}wXGx7@r_GbO>fcCq+&r19{*7b@ z&6ByJU?kgZp3D^mBiT0dWUeR}$u^iLb49^Ow%Rtv;Q81D%GEe4;LN+}L zbIg+Q6CJTpFp|wQPv(k(k!*^2GFKFgWaG_~xuRes8)=@*6$K;N5c6cNC>Y85nuz5096pUnf&6ByJU>wk8 zH%sO^UXI}TA~{=>(L9+e3P!R3^JK0l7|Hz1lewZ`Bui$V%oPPAnTMV%Ua#NsjB;p9 zc^f}|EkAWvcblK@#N_JdFJHcBQ!@CjQcrV|IHq`@?+jyP%*kB7+by}}^Lw5=xPU+L z0Ds{j{)YbjRe5~-XaV_si>FGjzGE`0ZfHXa`Pwa&wf_qF4)M6_sSPabJHqo3AF0~=!oJgetActiveSheet()->setCellValue( ); ``` -#### Setting a date and/or time in a cell +Alternatively, you can retrieve the cell object, and then call the cell’s setValue() method: + +```php +$objPHPExcel->getActiveSheet() + ->getCell('B8') + ->setValue('Some value'); +``` + +**Excel DataTypes** + +MS Excel supports 7 basic datatypes + - string + - number + - boolean + - null + - formula + - error + - Inline (or rich text) string + +By default, when you call the worksheet's `setCellValue()` method or the cell's `setValue()` method, PHPExcel will use the appropriate datatype for PHP nulls, booleans, floats or integers; or cast any string data value that you pass to the method into the most appropriate datatype, so numeric strings will be cast to numbers, while string values beginning with “=” will be converted to a formula. Strings that aren't numeric, or that don't begin with a leading "=" will be treated as genuine string values. + +This "conversion" is handled by a cell "value binder", and you can write custom "value binders" to change the behaviour of these "conversions". The standard PHPExcel package also provides an "advanced value binder" that handles a number of more complex conversions, such as converting strings with a fractional format like "3/4" to a number value (0.75 in this case) and setting an appropriate "fraction" number format mask. Similarly, strings like "5%" will be converted to a value of 0.05, and a percentage number format mask applied, and strings containing values that look like dates will be converted to Excel serialized datetimestamp values, and a corresponding mask applied. This is particularly useful when loading data from csv files, or setting cell values from a database. + +Formats handled by the advanced value binder include + - TRUE or FALSE (dependent on locale settings) are converted to booleans. + - Numeric strings identified as scientific (exponential) format are converted to numbers. + - Fractions and vulgar fractions are converted to numbers, and an appropriate number format mask applied. + - Percentages are converted to numbers, divided by 100, and an appropriate number format mask applied. + - Dates and times are converted to Excel timestamp values (numbers), and an appropriate number format mask applied. + - When strings contain a newline character ("\n"), then the cell styling is set to wrap. + +You can read more about value binders later in this section of the documentation. + +#### Setting a date and/or time value in a cell Date or time values are held as timestamp in Excel (a simple floating point value), and a number format mask is used to show how that value should be formatted; so if we want to store a date in a cell, we need to calculate the correct Excel timestamp, and set a number format mask. @@ -48,7 +81,7 @@ $objPHPExcel->getActiveSheet()->getStyle('A6') #### Setting a number with leading zeroes -By default, PHPExcel will automatically detect the value type and set it to the appropriate Excel datatype. This type conversion is handled by a value binder, as described in the section of this document entitled "Using value binders to facilitate data entry". +By default, PHPExcel will automatically detect the value type and set it to the appropriate Excel numeric datatype. This type conversion is handled by a value binder, as described in the section of this document entitled "Using value binders to facilitate data entry". Numbers don't have leading zeroes, so if you try to set a numeric value that does have leading zeroes (such as a telephone number) then these will be normally be lost as the value is cast to a number, so "01513789642" will be displayed as 1513789642. From d7ea3e2ab00edb1c33b44567a483cdd01f6bf3d0 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 7 Dec 2014 14:45:55 +0000 Subject: [PATCH 292/467] Feature: (cifren/MBaker) Work Item GH-205 - Handling merge cells in HTML Reader --- Classes/PHPExcel/Reader/HTML.php | 843 ++++++++++++++++--------------- changelog.txt | 1 + 2 files changed, 446 insertions(+), 398 deletions(-) diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 6adcc857a..df389e7ab 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -1,4 +1,5 @@ array( 'font' => array( 'bold' => true, - 'size' => 24, - ), - ), // Bold, 24pt - 'h2' => array( 'font' => array( 'bold' => true, - 'size' => 18, - ), - ), // Bold, 18pt - 'h3' => array( 'font' => array( 'bold' => true, - 'size' => 13.5, - ), - ), // Bold, 13.5pt - 'h4' => array( 'font' => array( 'bold' => true, - 'size' => 12, - ), - ), // Bold, 12pt - 'h5' => array( 'font' => array( 'bold' => true, - 'size' => 10, - ), - ), // Bold, 10pt - 'h6' => array( 'font' => array( 'bold' => true, - 'size' => 7.5, - ), - ), // Bold, 7.5pt - 'a' => array( 'font' => array( 'underline' => true, - 'color' => array( 'argb' => PHPExcel_Style_Color::COLOR_BLUE, - ), - ), - ), // Blue underlined - 'hr' => array( 'borders' => array( 'bottom' => array( 'style' => PHPExcel_Style_Border::BORDER_THIN, - 'color' => array( PHPExcel_Style_Color::COLOR_BLACK, - ), - ), - ), - ), // Bottom border - ); - - - /** - * Create a new PHPExcel_Reader_HTML - */ - public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - } - - /** - * Validate that the current file is an HTML file - * - * @return boolean - */ - protected function _isValidFormat() - { - // Reading 2048 bytes should be enough to validate that the format is HTML - $data = fread($this->_fileHandle, 2048); - if ((strpos($data, '<') !== FALSE) && - (strlen($data) !== strlen(strip_tags($data)))) { - return TRUE; - } - - return FALSE; - } - - /** - * Loads PHPExcel from file - * - * @param string $pFilename - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function load($pFilename) - { - // Create new PHPExcel - $objPHPExcel = new PHPExcel(); - - // Load into this instance - return $this->loadIntoExisting($pFilename, $objPHPExcel); - } - - /** - * Set input encoding - * - * @param string $pValue Input encoding - */ - public function setInputEncoding($pValue = 'ANSI') - { - $this->_inputEncoding = $pValue; - return $this; - } - - /** - * Get input encoding - * - * @return string - */ - public function getInputEncoding() - { - return $this->_inputEncoding; - } - - // Data Array used for testing only, should write to PHPExcel object on completion of tests - private $_dataArray = array(); - - private $_tableLevel = 0; - private $_nestedColumn = array('A'); - - private function _setTableStartColumn($column) { - if ($this->_tableLevel == 0) - $column = 'A'; - ++$this->_tableLevel; - $this->_nestedColumn[$this->_tableLevel] = $column; - - return $this->_nestedColumn[$this->_tableLevel]; - } - - private function _getTableStartColumn() { - return $this->_nestedColumn[$this->_tableLevel]; - } - - private function _releaseTableStartColumn() { - --$this->_tableLevel; - return array_pop($this->_nestedColumn); - } - - private function _flushCell($sheet,$column,$row,&$cellContent) { - if (is_string($cellContent)) { - // Simple String content - if (trim($cellContent) > '') { - // Only actually write it if there's content in the string + + /** + * Input encoding + * + * @var string + */ + protected $_inputEncoding = 'ANSI'; + + /** + * Sheet index to read + * + * @var int + */ + protected $_sheetIndex = 0; + + /** + * Formats + * + * @var array + */ + protected $_formats = array( + 'h1' => array('font' => array('bold' => true, + 'size' => 24, + ), + ), // Bold, 24pt + 'h2' => array('font' => array('bold' => true, + 'size' => 18, + ), + ), // Bold, 18pt + 'h3' => array('font' => array('bold' => true, + 'size' => 13.5, + ), + ), // Bold, 13.5pt + 'h4' => array('font' => array('bold' => true, + 'size' => 12, + ), + ), // Bold, 12pt + 'h5' => array('font' => array('bold' => true, + 'size' => 10, + ), + ), // Bold, 10pt + 'h6' => array('font' => array('bold' => true, + 'size' => 7.5, + ), + ), // Bold, 7.5pt + 'a' => array('font' => array('underline' => true, + 'color' => array('argb' => PHPExcel_Style_Color::COLOR_BLUE, + ), + ), + ), // Blue underlined + 'hr' => array('borders' => array('bottom' => array('style' => PHPExcel_Style_Border::BORDER_THIN, + 'color' => array(\PHPExcel_Style_Color::COLOR_BLACK, + ), + ), + ), + ), // Bottom border + ); + + protected $rowspan = array(); + + /** + * Create a new PHPExcel_Reader_HTML + */ + public function __construct() + { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + /** + * Validate that the current file is an HTML file + * + * @return boolean + */ + protected function _isValidFormat() + { + // Reading 2048 bytes should be enough to validate that the format is HTML + $data = fread($this->_fileHandle, 2048); + if ((strpos($data, '<') !== FALSE) && + (strlen($data) !== strlen(strip_tags($data)))) { + return TRUE; + } + + return FALSE; + } + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + /** + * Set input encoding + * + * @param string $pValue Input encoding + */ + public function setInputEncoding($pValue = 'ANSI') + { + $this->_inputEncoding = $pValue; + + return $this; + } + + /** + * Get input encoding + * + * @return string + */ + public function getInputEncoding() + { + return $this->_inputEncoding; + } + + // Data Array used for testing only, should write to PHPExcel object on completion of tests + protected $_dataArray = array(); + protected $_tableLevel = 0; + protected $_nestedColumn = array('A'); + + protected function _setTableStartColumn($column) + { + if ($this->_tableLevel == 0) + $column = 'A'; + ++$this->_tableLevel; + $this->_nestedColumn[$this->_tableLevel] = $column; + + return $this->_nestedColumn[$this->_tableLevel]; + } + + protected function _getTableStartColumn() + { + return $this->_nestedColumn[$this->_tableLevel]; + } + + protected function _releaseTableStartColumn() + { + --$this->_tableLevel; + + return array_pop($this->_nestedColumn); + } + + protected function _flushCell($sheet, $column, $row, &$cellContent) + { + if (is_string($cellContent)) { + // Simple String content + if (trim($cellContent) > '') { + // Only actually write it if there's content in the string // echo 'FLUSH CELL: ' , $column , $row , ' => ' , $cellContent , '
'; - // Write to worksheet to be done here... - // ... we return the cell so we can mess about with styles more easily - $cell = $sheet->setCellValue($column.$row,$cellContent,true); - $this->_dataArray[$row][$column] = $cellContent; - } - } else { - // We have a Rich Text run - // TODO - $this->_dataArray[$row][$column] = 'RICH TEXT: ' . $cellContent; - } - $cellContent = (string) ''; - } - - private function _processDomElement(DOMNode $element, $sheet, &$row, &$column, &$cellContent){ - foreach($element->childNodes as $child){ - if ($child instanceof DOMText) { - $domText = preg_replace('/\s+/',' ',trim($child->nodeValue)); - if (is_string($cellContent)) { - // simply append the text if the cell content is a plain text string - $cellContent .= $domText; - } else { - // but if we have a rich text run instead, we need to append it correctly - // TODO - } - } elseif($child instanceof DOMElement) { + // Write to worksheet to be done here... + // ... we return the cell so we can mess about with styles more easily + $sheet->setCellValue($column . $row, $cellContent, true); + $this->_dataArray[$row][$column] = $cellContent; + } + } else { + // We have a Rich Text run + // TODO + $this->_dataArray[$row][$column] = 'RICH TEXT: ' . $cellContent; + } + $cellContent = (string) ''; + } + + protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, &$cellContent, $format = null) + { + foreach ($element->childNodes as $child) { + if ($child instanceof DOMText) { + $domText = preg_replace('/\s+/', ' ', trim($child->nodeValue)); + if (is_string($cellContent)) { + // simply append the text if the cell content is a plain text string + $cellContent .= $domText; + } else { + // but if we have a rich text run instead, we need to append it correctly + // TODO + } + } elseif ($child instanceof DOMElement) { // echo 'DOM ELEMENT: ' , strtoupper($child->nodeName) , '
'; - $attributeArray = array(); - foreach($child->attributes as $attribute) { + $attributeArray = array(); + foreach ($child->attributes as $attribute) { // echo 'ATTRIBUTE: ' , $attribute->name , ' => ' , $attribute->value , '
'; - $attributeArray[$attribute->name] = $attribute->value; - } - - switch($child->nodeName) { - case 'meta' : - foreach($attributeArray as $attributeName => $attributeValue) { - switch($attributeName) { - case 'content': - // TODO - // Extract character set, so we can convert to UTF-8 if required - break; - } - } - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); - break; - case 'title' : - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); - $sheet->setTitle($cellContent); - $cellContent = ''; - break; - case 'span' : - case 'div' : - case 'font' : - case 'i' : - case 'em' : - case 'strong': - case 'b' : + $attributeArray[$attribute->name] = $attribute->value; + } + + switch ($child->nodeName) { + case 'meta' : + foreach ($attributeArray as $attributeName => $attributeValue) { + switch ($attributeName) { + case 'content': + // TODO + // Extract character set, so we can convert to UTF-8 if required + break; + } + } + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + break; + case 'title' : + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $sheet->setTitle($cellContent); + $cellContent = ''; + break; + case 'span' : + case 'div' : + case 'font' : + case 'i' : + case 'em' : + case 'strong': + case 'b' : // echo 'STYLING, SPAN OR DIV
'; - if ($cellContent > '') - $cellContent .= ' '; - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); - if ($cellContent > '') - $cellContent .= ' '; + if ($cellContent > '') + $cellContent .= ' '; + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + if ($cellContent > '') + $cellContent .= ' '; // echo 'END OF STYLING, SPAN OR DIV
'; - break; - case 'hr' : - $this->_flushCell($sheet,$column,$row,$cellContent); - ++$row; - if (isset($this->_formats[$child->nodeName])) { - $sheet->getStyle($column.$row)->applyFromArray($this->_formats[$child->nodeName]); - } else { - $cellContent = '----------'; - $this->_flushCell($sheet,$column,$row,$cellContent); - } - ++$row; - case 'br' : - if ($this->_tableLevel > 0) { - // If we're inside a table, replace with a \n - $cellContent .= "\n"; - } else { - // Otherwise flush our existing content and move the row cursor on - $this->_flushCell($sheet,$column,$row,$cellContent); - ++$row; - } + break; + case 'hr' : + $this->_flushCell($sheet, $column, $row, $cellContent); + ++$row; + if (isset($this->_formats[$child->nodeName])) { + $sheet->getStyle($column . $row)->applyFromArray($this->_formats[$child->nodeName]); + } else { + $cellContent = '----------'; + $this->_flushCell($sheet, $column, $row, $cellContent); + } + ++$row; + case 'br' : + if ($this->_tableLevel > 0) { + // If we're inside a table, replace with a \n + $cellContent .= "\n"; + } else { + // Otherwise flush our existing content and move the row cursor on + $this->_flushCell($sheet, $column, $row, $cellContent); + ++$row; + } // echo 'HARD LINE BREAK: ' , '
'; - break; - case 'a' : + break; + case 'a' : // echo 'START OF HYPERLINK: ' , '
'; - foreach($attributeArray as $attributeName => $attributeValue) { - switch($attributeName) { - case 'href': + foreach ($attributeArray as $attributeName => $attributeValue) { + switch ($attributeName) { + case 'href': // echo 'Link to ' , $attributeValue , '
'; - $sheet->getCell($column.$row)->getHyperlink()->setUrl($attributeValue); - if (isset($this->_formats[$child->nodeName])) { - $sheet->getStyle($column.$row)->applyFromArray($this->_formats[$child->nodeName]); - } - break; - } - } - $cellContent .= ' '; - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + $sheet->getCell($column . $row)->getHyperlink()->setUrl($attributeValue); + if (isset($this->_formats[$child->nodeName])) { + $sheet->getStyle($column . $row)->applyFromArray($this->_formats[$child->nodeName]); + } + break; + } + } + $cellContent .= ' '; + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF HYPERLINK:' , '
'; - break; - case 'h1' : - case 'h2' : - case 'h3' : - case 'h4' : - case 'h5' : - case 'h6' : - case 'ol' : - case 'ul' : - case 'p' : - if ($this->_tableLevel > 0) { - // If we're inside a table, replace with a \n - $cellContent .= "\n"; + break; + case 'h1' : + case 'h2' : + case 'h3' : + case 'h4' : + case 'h5' : + case 'h6' : + case 'ol' : + case 'ul' : + case 'p' : + if ($this->_tableLevel > 0) { + // If we're inside a table, replace with a \n + $cellContent .= "\n"; // echo 'LIST ENTRY: ' , '
'; - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF LIST ENTRY:' , '
'; - } else { - if ($cellContent > '') { - $this->_flushCell($sheet,$column,$row,$cellContent); - $row += 2; - } + } else { + if ($cellContent > '') { + $this->_flushCell($sheet, $column, $row, $cellContent); + $row++; + } // echo 'START OF PARAGRAPH: ' , '
'; - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF PARAGRAPH:' , '
'; - $this->_flushCell($sheet,$column,$row,$cellContent); - - if (isset($this->_formats[$child->nodeName])) { - $sheet->getStyle($column.$row)->applyFromArray($this->_formats[$child->nodeName]); - } - - $row += 2; - $column = 'A'; - } - break; - case 'li' : - if ($this->_tableLevel > 0) { - // If we're inside a table, replace with a \n - $cellContent .= "\n"; + $this->_flushCell($sheet, $column, $row, $cellContent); + + if (isset($this->_formats[$child->nodeName])) { + $sheet->getStyle($column . $row)->applyFromArray($this->_formats[$child->nodeName]); + } + + $row++; + $column = 'A'; + } + break; + case 'li' : + if ($this->_tableLevel > 0) { + // If we're inside a table, replace with a \n + $cellContent .= "\n"; // echo 'LIST ENTRY: ' , '
'; - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF LIST ENTRY:' , '
'; - } else { - if ($cellContent > '') { - $this->_flushCell($sheet,$column,$row,$cellContent); - } - ++$row; + } else { + if ($cellContent > '') { + $this->_flushCell($sheet, $column, $row, $cellContent); + } + ++$row; // echo 'LIST ENTRY: ' , '
'; - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF LIST ENTRY:' , '
'; - $this->_flushCell($sheet,$column,$row,$cellContent); - $column = 'A'; - } - break; - case 'table' : - $this->_flushCell($sheet,$column,$row,$cellContent); - $column = $this->_setTableStartColumn($column); + $this->_flushCell($sheet, $column, $row, $cellContent); + $column = 'A'; + } + break; + case 'table' : + $this->_flushCell($sheet, $column, $row, $cellContent); + $column = $this->_setTableStartColumn($column); // echo 'START OF TABLE LEVEL ' , $this->_tableLevel , '
'; - if ($this->_tableLevel > 1) - --$row; - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + if ($this->_tableLevel > 1) + --$row; + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF TABLE LEVEL ' , $this->_tableLevel , '
'; - $column = $this->_releaseTableStartColumn(); - if ($this->_tableLevel > 1) { - ++$column; - } else { - ++$row; - } - break; - case 'thead' : - case 'tbody' : - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); - break; - case 'tr' : - ++$row; - $column = $this->_getTableStartColumn(); - $cellContent = ''; + $column = $this->_releaseTableStartColumn(); + if ($this->_tableLevel > 1) { + ++$column; + } else { + ++$row; + } + break; + case 'thead' : + case 'tbody' : + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + break; + case 'tr' : + $column = $this->_getTableStartColumn(); + $cellContent = ''; // echo 'START OF TABLE ' , $this->_tableLevel , ' ROW
'; - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + ++$row; // echo 'END OF TABLE ' , $this->_tableLevel , ' ROW
'; - break; - case 'th' : - case 'td' : + break; + case 'th' : + case 'td' : // echo 'START OF TABLE ' , $this->_tableLevel , ' CELL
'; - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF TABLE ' , $this->_tableLevel , ' CELL
'; - $this->_flushCell($sheet,$column,$row,$cellContent); - ++$column; - break; - case 'body' : - $row = 1; - $column = 'A'; - $content = ''; - $this->_tableLevel = 0; - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); - break; - default: - $this->_processDomElement($child,$sheet,$row,$column,$cellContent); - } - } - } - } - - /** - * Loads PHPExcel from file into PHPExcel instance - * - * @param string $pFilename - * @param PHPExcel $objPHPExcel - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) - { - // Open file to validate - $this->_openFile($pFilename); - if (!$this->_isValidFormat()) { - fclose ($this->_fileHandle); - throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid HTML file."); - } - // Close after validating - fclose ($this->_fileHandle); - - // Create new PHPExcel - while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { - $objPHPExcel->createSheet(); - } - $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex ); - - // Create a new DOM object - $dom = new DOMDocument; - // Reload the HTML file into the DOM object - if ((version_compare(PHP_VERSION, '5.4.0') >= 0) && defined(LIBXML_DTDLOAD)) { - $loaded = $dom->loadHTMLFile($pFilename, PHPExcel_Settings::getLibXmlLoaderOptions()); - } else { - $loaded = $dom->loadHTMLFile($pFilename); + + while (isset($this->rowspan[$column . $row])) { + ++$column; + } + + $this->_flushCell($sheet, $column, $row, $cellContent); + + if (isset($attributeArray['style']) && !empty($attributeArray['style'])) { + $styleAry = $this->getPhpExcelStyleArray($attributeArray['style']); + + if (!empty($styleAry)) { + $sheet->getStyle($column . $row)->applyFromArray($styleAry); + } + } + + //create merging rowspan + if (isset($attributeArray['rowspan']) && isset($attributeArray['colspan'])) { + $columnTo = $column; + for ($i = 0; $i < $attributeArray['colspan'] - 1; $i++) { + ++$columnTo; + } + $range = $column . $row . ':' . $columnTo . ($row + $attributeArray['rowspan'] - 1); + foreach (\PHPExcel_Cell::extractAllCellReferencesInRange($range) as $value) { + $this->rowspan[$value] = true; + } + $sheet->mergeCells($range); + } elseif (isset($attributeArray['rowspan'])) { + $range = $column . $row . ':' . $column . ($row + $attributeArray['rowspan'] - 1); + foreach (\PHPExcel_Cell::extractAllCellReferencesInRange($range) as $value) { + $this->rowspan[$value] = true; + } + $sheet->mergeCells($range); + } elseif (isset($attributeArray['colspan'])) { + $columnTo = $column; + for ($i = 0; $i < $attributeArray['colspan'] - 1; $i++) { + ++$columnTo; + } + $sheet->mergeCells($column . $row . ':' . $columnTo . $row); + $column = $columnTo; + } + ++$column; + break; + case 'body' : + $row = 1; + $column = 'A'; + $content = ''; + $this->_tableLevel = 0; + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + break; + default: + $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + } + } + } + } + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Open file to validate + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid HTML file."); } - if ($loaded === FALSE) { - throw new PHPExcel_Reader_Exception('Failed to load '. $pFilename. ' as a DOM Document'); - } + // Close after validating + fclose($this->_fileHandle); - // Discard white space - $dom->preserveWhiteSpace = false; + // Create new PHPExcel + while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + $objPHPExcel->createSheet(); + } + $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); + + // Create a new DOM object + $dom = new domDocument; + // Reload the HTML file into the DOM object + $loaded = $dom->loadHTMLFile($pFilename); + if ($loaded === FALSE) { + throw new PHPExcel_Reader_Exception('Failed to load ', $pFilename, ' as a DOM Document'); + } + // Discard white space + $dom->preserveWhiteSpace = false; - $row = 0; - $column = 'A'; - $content = ''; - $this->_processDomElement($dom,$objPHPExcel->getActiveSheet(),$row,$column,$content); + $row = 0; + $column = 'A'; + $content = ''; + $this->_processDomElement($dom, $objPHPExcel->getActiveSheet(), $row, $column, $content); // Return - return $objPHPExcel; - } - - /** - * Get sheet index - * - * @return int - */ - public function getSheetIndex() { - return $this->_sheetIndex; - } - - /** - * Set sheet index - * - * @param int $pValue Sheet index - * @return PHPExcel_Reader_HTML - */ - public function setSheetIndex($pValue = 0) { - $this->_sheetIndex = $pValue; - return $this; - } + return $objPHPExcel; + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() + { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Reader_HTML + */ + public function setSheetIndex($pValue = 0) + { + $this->_sheetIndex = $pValue; + + return $this; + } } + diff --git a/changelog.txt b/changelog.txt index 0b8845f1c..587059b2c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -49,6 +49,7 @@ Planned for v1.8.1 - Feature: (CQD) Work Item GH-389 - Additional Mac CJK codepage definitions - Feature: (bolovincev) Work Item GH-269 - Update Worksheet.php getStyleByColumnAndRow() to allow a range of cells rather than just a single cell - Feature: (MBaker) - New methods added for testing cell status within merge groups +- Feature: (cifren/MBaker) Work Item GH-205 - Handling merge cells in HTML Reader 2014-03-02 (v1.8.0): From 180ad168cbb739b4fb6be7bca59c591b30e8742e Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 7 Dec 2014 23:45:15 +0000 Subject: [PATCH 293/467] Additional minor tweaks to HTML reader for merged cells --- Classes/PHPExcel/Reader/HTML.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index df389e7ab..103c2c643 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -403,8 +403,8 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, } } - //create merging rowspan if (isset($attributeArray['rowspan']) && isset($attributeArray['colspan'])) { + //create merging rowspan and colspan $columnTo = $column; for ($i = 0; $i < $attributeArray['colspan'] - 1; $i++) { ++$columnTo; @@ -414,13 +414,16 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, $this->rowspan[$value] = true; } $sheet->mergeCells($range); + $column = $columnTo; } elseif (isset($attributeArray['rowspan'])) { + //create merging rowspan $range = $column . $row . ':' . $column . ($row + $attributeArray['rowspan'] - 1); foreach (\PHPExcel_Cell::extractAllCellReferencesInRange($range) as $value) { $this->rowspan[$value] = true; } $sheet->mergeCells($range); } elseif (isset($attributeArray['colspan'])) { + //create merging colspan $columnTo = $column; for ($i = 0; $i < $attributeArray['colspan'] - 1; $i++) { ++$columnTo; From c40bb233bfa59fe8aadc6f3714cf500ec2c38e0f Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 18 Dec 2014 21:56:47 +0000 Subject: [PATCH 294/467] Remove spurious file --- .../CalcEngine/CyclicReferenceStack.new.php | 122 ------------------ 1 file changed, 122 deletions(-) delete mode 100644 Classes/PHPExcel/CalcEngine/CyclicReferenceStack.new.php diff --git a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.new.php b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.new.php deleted file mode 100644 index e57512de2..000000000 --- a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.new.php +++ /dev/null @@ -1,122 +0,0 @@ -_stack); - } - - /** - * Push a new entry onto the stack - * - * @param mixed $value - */ - public function push($value) { - $this->_stack[] = $value; - } // function push() - - /** - * Pop the last entry from the stack - * - * @return mixed - */ - public function pop() { - return array_pop($this->_stack); - } // function pop() - - /** - * Test to see if a specified entry exists on the stack - * - * @param mixed $value The value to test - */ - public function onStack($value) { - return in_array($value, $this->_stack); - } - - /** - * Clear the stack - */ - public function clear() { - $this->_stack = array(); - } // function push() - - /** - * Return an array of all entries on the stack - * - * @return mixed[] - */ - public function showStack() { - return $this->_stack; - } - - public function setValueByKey($key, $value) { - $this->_values[$key] = $value; - } - - public function getValueByKey($key, &$value) { - if (isset($this->_values[$key])) { - $value = $this->_values[$key]; - return true; - } - return false; - } - - public function removeValueByKey($key) { - if (isset($this->_values[$key])) { - unset($this->_values[$key]); - } - } - - public function showValues() { - return $this->_values; - } - -} // class PHPExcel_CalcEngine_CyclicReferenceStack From 0f146e4f315176e9ed3e48b90f0f5bb69e94f936 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 27 Dec 2014 23:48:24 +0000 Subject: [PATCH 295/467] Feature: Helper to convert basic HTML markup to a Rich Text object --- Classes/PHPExcel/Helper/HTML.php | 751 +++++++++++++++++++++++++++++++ Examples/42richText.php | 128 ++++++ changelog.txt | 1 + 3 files changed, 880 insertions(+) create mode 100644 Classes/PHPExcel/Helper/HTML.php create mode 100644 Examples/42richText.php diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php new file mode 100644 index 000000000..1cde91cdf --- /dev/null +++ b/Classes/PHPExcel/Helper/HTML.php @@ -0,0 +1,751 @@ + 'f0f8ff', + 'antiquewhite' => 'faebd7', + 'antiquewhite1' => 'ffefdb', + 'antiquewhite2' => 'eedfcc', + 'antiquewhite3' => 'cdc0b0', + 'antiquewhite4' => '8b8378', + 'aqua' => '00ffff', + 'aquamarine1' => '7fffd4', + 'aquamarine2' => '76eec6', + 'aquamarine4' => '458b74', + 'azure1' => 'f0ffff', + 'azure2' => 'e0eeee', + 'azure3' => 'c1cdcd', + 'azure4' => '838b8b', + 'beige' => 'f5f5dc', + 'bisque1' => 'ffe4c4', + 'bisque2' => 'eed5b7', + 'bisque3' => 'cdb79e', + 'bisque4' => '8b7d6b', + 'black' => '000000', + 'blanchedalmond' => 'ffebcd', + 'blue' => '0000ff', + 'blue1' => '0000ff', + 'blue2' => '0000ee', + 'blue4' => '00008b', + 'blueviolet' => '8a2be2', + 'brown' => 'a52a2a', + 'brown1' => 'ff4040', + 'brown2' => 'ee3b3b', + 'brown3' => 'cd3333', + 'brown4' => '8b2323', + 'burlywood' => 'deb887', + 'burlywood1' => 'ffd39b', + 'burlywood2' => 'eec591', + 'burlywood3' => 'cdaa7d', + 'burlywood4' => '8b7355', + 'cadetblue' => '5f9ea0', + 'cadetblue1' => '98f5ff', + 'cadetblue2' => '8ee5ee', + 'cadetblue3' => '7ac5cd', + 'cadetblue4' => '53868b', + 'chartreuse1' => '7fff00', + 'chartreuse2' => '76ee00', + 'chartreuse3' => '66cd00', + 'chartreuse4' => '458b00', + 'chocolate' => 'd2691e', + 'chocolate1' => 'ff7f24', + 'chocolate2' => 'ee7621', + 'chocolate3' => 'cd661d', + 'coral' => 'ff7f50', + 'coral1' => 'ff7256', + 'coral2' => 'ee6a50', + 'coral3' => 'cd5b45', + 'coral4' => '8b3e2f', + 'cornflowerblue' => '6495ed', + 'cornsilk1' => 'fff8dc', + 'cornsilk2' => 'eee8cd', + 'cornsilk3' => 'cdc8b1', + 'cornsilk4' => '8b8878', + 'cyan1' => '00ffff', + 'cyan2' => '00eeee', + 'cyan3' => '00cdcd', + 'cyan4' => '008b8b', + 'darkgoldenrod' => 'b8860b', + 'darkgoldenrod1' => 'ffb90f', + 'darkgoldenrod2' => 'eead0e', + 'darkgoldenrod3' => 'cd950c', + 'darkgoldenrod4' => '8b6508', + 'darkgreen' => '006400', + 'darkkhaki' => 'bdb76b', + 'darkolivegreen' => '556b2f', + 'darkolivegreen1' => 'caff70', + 'darkolivegreen2' => 'bcee68', + 'darkolivegreen3' => 'a2cd5a', + 'darkolivegreen4' => '6e8b3d', + 'darkorange' => 'ff8c00', + 'darkorange1' => 'ff7f00', + 'darkorange2' => 'ee7600', + 'darkorange3' => 'cd6600', + 'darkorange4' => '8b4500', + 'darkorchid' => '9932cc', + 'darkorchid1' => 'bf3eff', + 'darkorchid2' => 'b23aee', + 'darkorchid3' => '9a32cd', + 'darkorchid4' => '68228b', + 'darksalmon' => 'e9967a', + 'darkseagreen' => '8fbc8f', + 'darkseagreen1' => 'c1ffc1', + 'darkseagreen2' => 'b4eeb4', + 'darkseagreen3' => '9bcd9b', + 'darkseagreen4' => '698b69', + 'darkslateblue' => '483d8b', + 'darkslategray' => '2f4f4f', + 'darkslategray1' => '97ffff', + 'darkslategray2' => '8deeee', + 'darkslategray3' => '79cdcd', + 'darkslategray4' => '528b8b', + 'darkturquoise' => '00ced1', + 'darkviolet' => '9400d3', + 'deeppink1' => 'ff1493', + 'deeppink2' => 'ee1289', + 'deeppink3' => 'cd1076', + 'deeppink4' => '8b0a50', + 'deepskyblue1' => '00bfff', + 'deepskyblue2' => '00b2ee', + 'deepskyblue3' => '009acd', + 'deepskyblue4' => '00688b', + 'dimgray' => '696969', + 'dodgerblue1' => '1e90ff', + 'dodgerblue2' => '1c86ee', + 'dodgerblue3' => '1874cd', + 'dodgerblue4' => '104e8b', + 'firebrick' => 'b22222', + 'firebrick1' => 'ff3030', + 'firebrick2' => 'ee2c2c', + 'firebrick3' => 'cd2626', + 'firebrick4' => '8b1a1a', + 'floralwhite' => 'fffaf0', + 'forestgreen' => '228b22', + 'fuchsia' => 'ff00ff', + 'gainsboro' => 'dcdcdc', + 'ghostwhite' => 'f8f8ff', + 'gold1' => 'ffd700', + 'gold2' => 'eec900', + 'gold3' => 'cdad00', + 'gold4' => '8b7500', + 'goldenrod' => 'daa520', + 'goldenrod1' => 'ffc125', + 'goldenrod2' => 'eeb422', + 'goldenrod3' => 'cd9b1d', + 'goldenrod4' => '8b6914', + 'gray' => 'bebebe', + 'gray1' => '030303', + 'gray10' => '1a1a1a', + 'gray11' => '1c1c1c', + 'gray12' => '1f1f1f', + 'gray13' => '212121', + 'gray14' => '242424', + 'gray15' => '262626', + 'gray16' => '292929', + 'gray17' => '2b2b2b', + 'gray18' => '2e2e2e', + 'gray19' => '303030', + 'gray2' => '050505', + 'gray20' => '333333', + 'gray21' => '363636', + 'gray22' => '383838', + 'gray23' => '3b3b3b', + 'gray24' => '3d3d3d', + 'gray25' => '404040', + 'gray26' => '424242', + 'gray27' => '454545', + 'gray28' => '474747', + 'gray29' => '4a4a4a', + 'gray3' => '080808', + 'gray30' => '4d4d4d', + 'gray31' => '4f4f4f', + 'gray32' => '525252', + 'gray33' => '545454', + 'gray34' => '575757', + 'gray35' => '595959', + 'gray36' => '5c5c5c', + 'gray37' => '5e5e5e', + 'gray38' => '616161', + 'gray39' => '636363', + 'gray4' => '0a0a0a', + 'gray40' => '666666', + 'gray41' => '696969', + 'gray42' => '6b6b6b', + 'gray43' => '6e6e6e', + 'gray44' => '707070', + 'gray45' => '737373', + 'gray46' => '757575', + 'gray47' => '787878', + 'gray48' => '7a7a7a', + 'gray49' => '7d7d7d', + 'gray5' => '0d0d0d', + 'gray50' => '7f7f7f', + 'gray51' => '828282', + 'gray52' => '858585', + 'gray53' => '878787', + 'gray54' => '8a8a8a', + 'gray55' => '8c8c8c', + 'gray56' => '8f8f8f', + 'gray57' => '919191', + 'gray58' => '949494', + 'gray59' => '969696', + 'gray6' => '0f0f0f', + 'gray60' => '999999', + 'gray61' => '9c9c9c', + 'gray62' => '9e9e9e', + 'gray63' => 'a1a1a1', + 'gray64' => 'a3a3a3', + 'gray65' => 'a6a6a6', + 'gray66' => 'a8a8a8', + 'gray67' => 'ababab', + 'gray68' => 'adadad', + 'gray69' => 'b0b0b0', + 'gray7' => '121212', + 'gray70' => 'b3b3b3', + 'gray71' => 'b5b5b5', + 'gray72' => 'b8b8b8', + 'gray73' => 'bababa', + 'gray74' => 'bdbdbd', + 'gray75' => 'bfbfbf', + 'gray76' => 'c2c2c2', + 'gray77' => 'c4c4c4', + 'gray78' => 'c7c7c7', + 'gray79' => 'c9c9c9', + 'gray8' => '141414', + 'gray80' => 'cccccc', + 'gray81' => 'cfcfcf', + 'gray82' => 'd1d1d1', + 'gray83' => 'd4d4d4', + 'gray84' => 'd6d6d6', + 'gray85' => 'd9d9d9', + 'gray86' => 'dbdbdb', + 'gray87' => 'dedede', + 'gray88' => 'e0e0e0', + 'gray89' => 'e3e3e3', + 'gray9' => '171717', + 'gray90' => 'e5e5e5', + 'gray91' => 'e8e8e8', + 'gray92' => 'ebebeb', + 'gray93' => 'ededed', + 'gray94' => 'f0f0f0', + 'gray95' => 'f2f2f2', + 'gray97' => 'f7f7f7', + 'gray98' => 'fafafa', + 'gray99' => 'fcfcfc', + 'green' => '00ff00', + 'green1' => '00ff00', + 'green2' => '00ee00', + 'green3' => '00cd00', + 'green4' => '008b00', + 'greenyellow' => 'adff2f', + 'honeydew1' => 'f0fff0', + 'honeydew2' => 'e0eee0', + 'honeydew3' => 'c1cdc1', + 'honeydew4' => '838b83', + 'hotpink' => 'ff69b4', + 'hotpink1' => 'ff6eb4', + 'hotpink2' => 'ee6aa7', + 'hotpink3' => 'cd6090', + 'hotpink4' => '8b3a62', + 'indianred' => 'cd5c5c', + 'indianred1' => 'ff6a6a', + 'indianred2' => 'ee6363', + 'indianred3' => 'cd5555', + 'indianred4' => '8b3a3a', + 'ivory1' => 'fffff0', + 'ivory2' => 'eeeee0', + 'ivory3' => 'cdcdc1', + 'ivory4' => '8b8b83', + 'khaki' => 'f0e68c', + 'khaki1' => 'fff68f', + 'khaki2' => 'eee685', + 'khaki3' => 'cdc673', + 'khaki4' => '8b864e', + 'lavender' => 'e6e6fa', + 'lavenderblush1' => 'fff0f5', + 'lavenderblush2' => 'eee0e5', + 'lavenderblush3' => 'cdc1c5', + 'lavenderblush4' => '8b8386', + 'lawngreen' => '7cfc00', + 'lemonchiffon1' => 'fffacd', + 'lemonchiffon2' => 'eee9bf', + 'lemonchiffon3' => 'cdc9a5', + 'lemonchiffon4' => '8b8970', + 'light' => 'eedd82', + 'lightblue' => 'add8e6', + 'lightblue1' => 'bfefff', + 'lightblue2' => 'b2dfee', + 'lightblue3' => '9ac0cd', + 'lightblue4' => '68838b', + 'lightcoral' => 'f08080', + 'lightcyan1' => 'e0ffff', + 'lightcyan2' => 'd1eeee', + 'lightcyan3' => 'b4cdcd', + 'lightcyan4' => '7a8b8b', + 'lightgoldenrod1' => 'ffec8b', + 'lightgoldenrod2' => 'eedc82', + 'lightgoldenrod3' => 'cdbe70', + 'lightgoldenrod4' => '8b814c', + 'lightgoldenrodyellow' => 'fafad2', + 'lightgray' => 'd3d3d3', + 'lightpink' => 'ffb6c1', + 'lightpink1' => 'ffaeb9', + 'lightpink2' => 'eea2ad', + 'lightpink3' => 'cd8c95', + 'lightpink4' => '8b5f65', + 'lightsalmon1' => 'ffa07a', + 'lightsalmon2' => 'ee9572', + 'lightsalmon3' => 'cd8162', + 'lightsalmon4' => '8b5742', + 'lightseagreen' => '20b2aa', + 'lightskyblue' => '87cefa', + 'lightskyblue1' => 'b0e2ff', + 'lightskyblue2' => 'a4d3ee', + 'lightskyblue3' => '8db6cd', + 'lightskyblue4' => '607b8b', + 'lightslateblue' => '8470ff', + 'lightslategray' => '778899', + 'lightsteelblue' => 'b0c4de', + 'lightsteelblue1' => 'cae1ff', + 'lightsteelblue2' => 'bcd2ee', + 'lightsteelblue3' => 'a2b5cd', + 'lightsteelblue4' => '6e7b8b', + 'lightyellow1' => 'ffffe0', + 'lightyellow2' => 'eeeed1', + 'lightyellow3' => 'cdcdb4', + 'lightyellow4' => '8b8b7a', + 'lime' => '00ff00', + 'limegreen' => '32cd32', + 'linen' => 'faf0e6', + 'magenta' => 'ff00ff', + 'magenta2' => 'ee00ee', + 'magenta3' => 'cd00cd', + 'magenta4' => '8b008b', + 'maroon' => 'b03060', + 'maroon1' => 'ff34b3', + 'maroon2' => 'ee30a7', + 'maroon3' => 'cd2990', + 'maroon4' => '8b1c62', + 'medium' => '66cdaa', + 'mediumaquamarine' => '66cdaa', + 'mediumblue' => '0000cd', + 'mediumorchid' => 'ba55d3', + 'mediumorchid1' => 'e066ff', + 'mediumorchid2' => 'd15fee', + 'mediumorchid3' => 'b452cd', + 'mediumorchid4' => '7a378b', + 'mediumpurple' => '9370db', + 'mediumpurple1' => 'ab82ff', + 'mediumpurple2' => '9f79ee', + 'mediumpurple3' => '8968cd', + 'mediumpurple4' => '5d478b', + 'mediumseagreen' => '3cb371', + 'mediumslateblue' => '7b68ee', + 'mediumspringgreen' => '00fa9a', + 'mediumturquoise' => '48d1cc', + 'mediumvioletred' => 'c71585', + 'midnightblue' => '191970', + 'mintcream' => 'f5fffa', + 'mistyrose1' => 'ffe4e1', + 'mistyrose2' => 'eed5d2', + 'mistyrose3' => 'cdb7b5', + 'mistyrose4' => '8b7d7b', + 'moccasin' => 'ffe4b5', + 'navajowhite1' => 'ffdead', + 'navajowhite2' => 'eecfa1', + 'navajowhite3' => 'cdb38b', + 'navajowhite4' => '8b795e', + 'navy' => '000080', + 'navyblue' => '000080', + 'oldlace' => 'fdf5e6', + 'olive' => '808000', + 'olivedrab' => '6b8e23', + 'olivedrab1' => 'c0ff3e', + 'olivedrab2' => 'b3ee3a', + 'olivedrab4' => '698b22', + 'orange' => 'ffa500', + 'orange1' => 'ffa500', + 'orange2' => 'ee9a00', + 'orange3' => 'cd8500', + 'orange4' => '8b5a00', + 'orangered1' => 'ff4500', + 'orangered2' => 'ee4000', + 'orangered3' => 'cd3700', + 'orangered4' => '8b2500', + 'orchid' => 'da70d6', + 'orchid1' => 'ff83fa', + 'orchid2' => 'ee7ae9', + 'orchid3' => 'cd69c9', + 'orchid4' => '8b4789', + 'pale' => 'db7093', + 'palegoldenrod' => 'eee8aa', + 'palegreen' => '98fb98', + 'palegreen1' => '9aff9a', + 'palegreen2' => '90ee90', + 'palegreen3' => '7ccd7c', + 'palegreen4' => '548b54', + 'paleturquoise' => 'afeeee', + 'paleturquoise1' => 'bbffff', + 'paleturquoise2' => 'aeeeee', + 'paleturquoise3' => '96cdcd', + 'paleturquoise4' => '668b8b', + 'palevioletred' => 'db7093', + 'palevioletred1' => 'ff82ab', + 'palevioletred2' => 'ee799f', + 'palevioletred3' => 'cd6889', + 'palevioletred4' => '8b475d', + 'papayawhip' => 'ffefd5', + 'peachpuff1' => 'ffdab9', + 'peachpuff2' => 'eecbad', + 'peachpuff3' => 'cdaf95', + 'peachpuff4' => '8b7765', + 'pink' => 'ffc0cb', + 'pink1' => 'ffb5c5', + 'pink2' => 'eea9b8', + 'pink3' => 'cd919e', + 'pink4' => '8b636c', + 'plum' => 'dda0dd', + 'plum1' => 'ffbbff', + 'plum2' => 'eeaeee', + 'plum3' => 'cd96cd', + 'plum4' => '8b668b', + 'powderblue' => 'b0e0e6', + 'purple' => 'a020f0', + 'rebeccapurple' => '663399', + 'purple1' => '9b30ff', + 'purple2' => '912cee', + 'purple3' => '7d26cd', + 'purple4' => '551a8b', + 'red' => 'ff0000', + 'red1' => 'ff0000', + 'red2' => 'ee0000', + 'red3' => 'cd0000', + 'red4' => '8b0000', + 'rosybrown' => 'bc8f8f', + 'rosybrown1' => 'ffc1c1', + 'rosybrown2' => 'eeb4b4', + 'rosybrown3' => 'cd9b9b', + 'rosybrown4' => '8b6969', + 'royalblue' => '4169e1', + 'royalblue1' => '4876ff', + 'royalblue2' => '436eee', + 'royalblue3' => '3a5fcd', + 'royalblue4' => '27408b', + 'saddlebrown' => '8b4513', + 'salmon' => 'fa8072', + 'salmon1' => 'ff8c69', + 'salmon2' => 'ee8262', + 'salmon3' => 'cd7054', + 'salmon4' => '8b4c39', + 'sandybrown' => 'f4a460', + 'seagreen1' => '54ff9f', + 'seagreen2' => '4eee94', + 'seagreen3' => '43cd80', + 'seagreen4' => '2e8b57', + 'seashell1' => 'fff5ee', + 'seashell2' => 'eee5de', + 'seashell3' => 'cdc5bf', + 'seashell4' => '8b8682', + 'sienna' => 'a0522d', + 'sienna1' => 'ff8247', + 'sienna2' => 'ee7942', + 'sienna3' => 'cd6839', + 'sienna4' => '8b4726', + 'silver' => 'c0c0c0', + 'skyblue' => '87ceeb', + 'skyblue1' => '87ceff', + 'skyblue2' => '7ec0ee', + 'skyblue3' => '6ca6cd', + 'skyblue4' => '4a708b', + 'slateblue' => '6a5acd', + 'slateblue1' => '836fff', + 'slateblue2' => '7a67ee', + 'slateblue3' => '6959cd', + 'slateblue4' => '473c8b', + 'slategray' => '708090', + 'slategray1' => 'c6e2ff', + 'slategray2' => 'b9d3ee', + 'slategray3' => '9fb6cd', + 'slategray4' => '6c7b8b', + 'snow1' => 'fffafa', + 'snow2' => 'eee9e9', + 'snow3' => 'cdc9c9', + 'snow4' => '8b8989', + 'springgreen1' => '00ff7f', + 'springgreen2' => '00ee76', + 'springgreen3' => '00cd66', + 'springgreen4' => '008b45', + 'steelblue' => '4682b4', + 'steelblue1' => '63b8ff', + 'steelblue2' => '5cacee', + 'steelblue3' => '4f94cd', + 'steelblue4' => '36648b', + 'tan' => 'd2b48c', + 'tan1' => 'ffa54f', + 'tan2' => 'ee9a49', + 'tan3' => 'cd853f', + 'tan4' => '8b5a2b', + 'teal' => '008080', + 'thistle' => 'd8bfd8', + 'thistle1' => 'ffe1ff', + 'thistle2' => 'eed2ee', + 'thistle3' => 'cdb5cd', + 'thistle4' => '8b7b8b', + 'tomato1' => 'ff6347', + 'tomato2' => 'ee5c42', + 'tomato3' => 'cd4f39', + 'tomato4' => '8b3626', + 'turquoise' => '40e0d0', + 'turquoise1' => '00f5ff', + 'turquoise2' => '00e5ee', + 'turquoise3' => '00c5cd', + 'turquoise4' => '00868b', + 'violet' => 'ee82ee', + 'violetred' => 'd02090', + 'violetred1' => 'ff3e96', + 'violetred2' => 'ee3a8c', + 'violetred3' => 'cd3278', + 'violetred4' => '8b2252', + 'wheat' => 'f5deb3', + 'wheat1' => 'ffe7ba', + 'wheat2' => 'eed8ae', + 'wheat3' => 'cdba96', + 'wheat4' => '8b7e66', + 'white' => 'ffffff', + 'whitesmoke' => 'f5f5f5', + 'yellow' => 'ffff00', + 'yellow1' => 'ffff00', + 'yellow2' => 'eeee00', + 'yellow3' => 'cdcd00', + 'yellow4' => '8b8b00', + 'yellowgreen' => '9acd32', + ); + + protected $face; + protected $size; + protected $color; + + protected $bold = false; + protected $italic = false; + protected $underline = false; + protected $superscript = false; + protected $subscript = false; + protected $strikethrough = false; + + protected $startTagCallbacks = array( + 'font' => 'startFontTag', + 'b' => 'startBoldTag', + 'strong' => 'startBoldTag', + 'i' => 'startItalicTag', + 'em' => 'startItalicTag', + 'u' => 'startUnderlineTag', + 'ins' => 'startUnderlineTag', + 'del' => 'startStrikethruTag', + 'sup' => 'startSuperscriptTag', + 'sub' => 'startSubscriptTag', + ); + + protected $endTagCallbacks = array( + 'font' => 'endFontTag', + 'b' => 'endBoldTag', + 'strong' => 'endBoldTag', + 'i' => 'endItalicTag', + 'em' => 'endItalicTag', + 'u' => 'endUnderlineTag', + 'ins' => 'endUnderlineTag', + 'del' => 'endStrikethruTag', + 'sup' => 'endSuperscriptTag', + 'sub' => 'endSubscriptTag', + 'br' => 'breakTag', + 'p' => 'breakTag', + 'h1' => 'breakTag', + 'h2' => 'breakTag', + 'h3' => 'breakTag', + 'h4' => 'breakTag', + 'h5' => 'breakTag', + 'h6' => 'breakTag', + ); + + protected $stack = array(); + + protected $stringData = ''; + + protected $richTextObject; + + public function toRichTextObject($html) { + // Create a new DOM object + $dom = new domDocument; + // Load the HTML file into the DOM object + // Note the use of error suppression, because typically this will be an html fragment, so not fully valid markup + $loaded = @$dom->loadHTML($html); + + // Discard excess white space + $dom->preserveWhiteSpace = false; + + $this->richTextObject = new PHPExcel_RichText();; + $this->parseElements($dom); + return $this->richTextObject; + } + + protected function buildTextRun() { + $text = $this->stringData; + if (trim($text) === '') + return; + + $richtextRun = $this->richTextObject->createTextRun($this->stringData); + if ($this->face) { + $richtextRun->getFont()->setName($this->face); + } + if ($this->size) { + $richtextRun->getFont()->setSize($this->size); + } + if ($this->color) { + $richtextRun->getFont()->setColor( new PHPExcel_Style_Color( 'ff' . $this->color ) ); + } + if ($this->bold) { + $richtextRun->getFont()->setBold(true); + } + if ($this->italic) { + $richtextRun->getFont()->setItalic(true); + } + if ($this->underline) { + $richtextRun->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } + if ($this->superscript) { + $richtextRun->getFont()->setSuperScript(true); + } + if ($this->subscript) { + $richtextRun->getFont()->setSubScript(true); + } + if ($this->strikethrough) { + $richtextRun->getFont()->setStrikethrough(true); + } + $this->stringData = ''; + } + + protected function rgbToColour($rgb) { + preg_match_all('/\d+/', $rgb, $values); + foreach($values[0] as &$value) { + $value = str_pad(dechex($value), 2, '0', STR_PAD_LEFT); + } + return implode($values[0]); + } + + protected function colourNameLookup($rgb) { + return self::$colourMap[$rgb]; + } + + protected function startFontTag($tag) { + foreach ($tag->attributes as $attribute) { + $attributeName = strtolower($attribute->name); + $attributeValue = $attribute->value; + + if ($attributeName == 'color') { + if (preg_match('/rgb\s*\(/', $attributeValue)) { + $this->$attributeName = $this->rgbToColour($attributeValue); + } elseif(strpos(trim($attributeValue), '#') === 0) { + $this->$attributeName = ltrim($attributeValue, '#'); + } else { + $this->$attributeName = $this->colourNameLookup($attributeValue); + } + } else { + $this->$attributeName = $attributeValue; + } + } + } + + protected function endFontTag() { + $this->face = $this->size = $this->color = null; + } + + protected function startBoldTag() { + $this->bold = true; + } + + protected function endBoldTag() { + $this->bold = false; + } + + protected function startItalicTag() { + $this->italic = true; + } + + protected function endItalicTag() { + $this->italic = false; + } + + protected function startUnderlineTag() { + $this->underline = true; + } + + protected function endUnderlineTag() { + $this->underline = false; + } + + protected function startSubscriptTag() { + $this->subscript = true; + } + + protected function endSubscriptTag() { + $this->subscript = false; + } + + protected function startSuperscriptTag() { + $this->superscript = true; + } + + protected function endSupercriptTag() { + $this->superscript = false; + } + + protected function startStrikethruTag() { + $this->strikethrough = true; + } + + protected function endStrikethruTag() { + $this->strikethrough = false; + } + + protected function breakTag() { + $this->stringData .= PHP_EOL; + } + + protected function parseTextNode(DOMText $textNode) { + $domText = preg_replace('/\s+/', ' ', ltrim($textNode->nodeValue)); + $this->stringData .= $domText; + $this->buildTextRun(); + } + + protected function handleCallback($element, $callbackTag, $callbacks) { + if (isset($callbacks[$callbackTag])) { + $elementHandler = $callbacks[$callbackTag]; + if (method_exists($this, $elementHandler)) { + call_user_func(array($this, $elementHandler), $element); + } + } + } + + protected function parseElementNode(DOMElement $element) { + $callbackTag = strtolower($element->nodeName); + $this->stack[] = $callbackTag; + + $this->handleCallback($element, $callbackTag, $this->startTagCallbacks); + + $this->parseElements($element); + $this->stringData .= ' '; + array_pop($this->stack); + + $this->handleCallback($element, $callbackTag, $this->endTagCallbacks); + } + + protected function parseElements(DOMNode $element) { + foreach ($element->childNodes as $child) { + if ($child instanceof DOMText) { + $this->parseTextNode($child); + } elseif ($child instanceof DOMElement) { + $this->parseElementNode($child); + } + } + } +} diff --git a/Examples/42richText.php b/Examples/42richText.php new file mode 100644 index 000000000..cfaf09d92 --- /dev/null +++ b/Examples/42richText.php @@ -0,0 +1,128 @@ +'); + +/** Include PHPExcel */ +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; + + +// Create new PHPExcel object +echo date('H:i:s') , " Create new PHPExcel object" , EOL; +$objPHPExcel = new PHPExcel(); + +// Set document properties +echo date('H:i:s') , " Set document properties" , EOL; +$objPHPExcel->getProperties()->setCreator("Maarten Balliauw") + ->setLastModifiedBy("Maarten Balliauw") + ->setTitle("PHPExcel Test Document") + ->setSubject("PHPExcel Test Document") + ->setDescription("Test document for PHPExcel, generated using PHP classes.") + ->setKeywords("office PHPExcel php") + ->setCategory("Test result file"); + + +// Add some data +echo date('H:i:s') , " Add some data" , EOL; + +$html=' +

My very first example of rich text
generated from html markup

+

+ +This block contains an italicized word; +while this block uses an underline. + +

+

+I want to eat steakpizza. + +'; + +$wizard = new PHPExcel_Helper_HTML; +$richText = $wizard->toRichTextObject($html); + +$objPHPExcel->setActiveSheetIndex(0) + ->setCellValue('A1', $richText); + +$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(48); +$objPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(-1); +$objPHPExcel->getActiveSheet()->getStyle('A1') + ->getAlignment() + ->setWrapText(true); + + +// Rename worksheet +echo date('H:i:s') , " Rename worksheet" , EOL; +$objPHPExcel->getActiveSheet()->setTitle('Simple'); + + +// Set active sheet index to the first sheet, so Excel opens this as the first sheet +$objPHPExcel->setActiveSheetIndex(0); + + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Save Excel 95 file +echo date('H:i:s') , " Write to Excel5 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); +$objWriter->save(str_replace('.php', '.xls', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/changelog.txt b/changelog.txt index 587059b2c..f8f2170f2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -50,6 +50,7 @@ Planned for v1.8.1 - Feature: (bolovincev) Work Item GH-269 - Update Worksheet.php getStyleByColumnAndRow() to allow a range of cells rather than just a single cell - Feature: (MBaker) - New methods added for testing cell status within merge groups - Feature: (cifren/MBaker) Work Item GH-205 - Handling merge cells in HTML Reader +- Feature: (MBaker) - Helper to convert basic HTML markup to a Rich Text object 2014-03-02 (v1.8.0): From 7a4523967240760c8b15ac45e766be2f638e088e Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 27 Dec 2014 23:58:57 +0000 Subject: [PATCH 296/467] Added password-protected worksheet and richtext examples to runall --- Examples/41password.php | 84 +++++++++++++++++++++++++++++++++++++++++ Examples/runall.php | 2 + 2 files changed, 86 insertions(+) create mode 100644 Examples/41password.php diff --git a/Examples/41password.php b/Examples/41password.php new file mode 100644 index 000000000..7b03e4f9a --- /dev/null +++ b/Examples/41password.php @@ -0,0 +1,84 @@ +'); + +date_default_timezone_set('Europe/London'); + +include "05featuredemo.inc.php"; + +/** Include PHPExcel_IOFactory */ +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; + + +// Set password against the spreadsheet file +$objPHPExcel->getSecurity()->setLockWindows(true); +$objPHPExcel->getSecurity()->setLockStructure(true); +$objPHPExcel->getSecurity()->setWorkbookPassword('secret'); + + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Save Excel 95 file +echo date('H:i:s') , " Write to Excel5 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); +$objWriter->save(str_replace('.php', '.xls', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing files" , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/Examples/runall.php b/Examples/runall.php index 3818547a7..b2af1ccd0 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -100,6 +100,8 @@ , '38cloneWorksheet.php' , '39dropdown.php' , '40duplicateStyle.php' + , '41password.php' + , '42richText.php' , 'OOCalcReader.php' , 'OOCalcReaderPCLZip.php' , 'SylkReader.php' From ee309f6e930885c20014000f2e7dfa871314485c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 28 Dec 2014 19:08:33 +0000 Subject: [PATCH 297/467] Fix initialisation of html to Rich Text helper, and provide additional examples --- Classes/PHPExcel/Helper/HTML.php | 11 +++++++++++ Examples/42richText.php | 30 +++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index 1cde91cdf..a3e040518 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -573,7 +573,18 @@ class PHPExcel_Helper_HTML protected $richTextObject; + protected function initialise() { + $this->face = $this->size = $this->color = null; + $this->bold = $this->italic = $this->underline = $this->superscript = $this->subscript = $this->strikethrough = false; + + $this->stack = array(); + + $this->stringData = ''; + } + public function toRichTextObject($html) { + $this->initialise(); + // Create a new DOM object $dom = new domDocument; // Load the HTML file into the DOM object diff --git a/Examples/42richText.php b/Examples/42richText.php index cfaf09d92..001627237 100644 --- a/Examples/42richText.php +++ b/Examples/42richText.php @@ -55,21 +55,31 @@ // Add some data echo date('H:i:s') , " Add some data" , EOL; -$html=' +$html1='

My very first example of rich text
generated from html markup

- + This block contains an italicized word; while this block uses an underline.

-

-I want to eat steakpizza. +

+I want to eat healthy foodpizza. '; +$html2='

+ + 100°C is a hot temperature + +
+ + 10°F is cold + +

'; + $wizard = new PHPExcel_Helper_HTML; -$richText = $wizard->toRichTextObject($html); +$richText = $wizard->toRichTextObject($html1); $objPHPExcel->setActiveSheetIndex(0) ->setCellValue('A1', $richText); @@ -80,6 +90,16 @@ ->getAlignment() ->setWrapText(true); +$richText = $wizard->toRichTextObject($html2); + +$objPHPExcel->setActiveSheetIndex(0) + ->setCellValue('A2', $richText); + +$objPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(-1); +$objPHPExcel->getActiveSheet()->getStyle('A2') + ->getAlignment() + ->setWrapText(true); + // Rename worksheet echo date('H:i:s') , " Rename worksheet" , EOL; From 41d970f12580d3b3720241bcc1f02d2a90031ed2 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 7 Jan 2015 22:36:19 +0000 Subject: [PATCH 298/467] Force uppercase for cell address arguments --- Classes/PHPExcel/Worksheet.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 6215be8b1..88ffa315a 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1092,7 +1092,7 @@ public function getHighestRowAndColumn() */ public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = false) { - $cell = $this->getCell($pCoordinate)->setValue($pValue); + $cell = $this->getCell(strtoupper($pCoordinate))->setValue($pValue); return ($returnCell) ? $cell : $this; } @@ -1123,7 +1123,7 @@ public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = nu public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) { // Set value - $cell = $this->getCell($pCoordinate)->setValueExplicit($pValue, $pDataType); + $cell = $this->getCell(strtoupper($pCoordinate))->setValueExplicit($pValue, $pDataType); return ($returnCell) ? $cell : $this; } @@ -1152,6 +1152,7 @@ public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pVa */ public function getCell($pCoordinate = 'A1') { + $pCoordinate = strtoupper($pCoordinate); // Check cell collection if ($this->_cellCollection->isDataSet($pCoordinate)) { return $this->_cellCollection->getCacheData($pCoordinate); @@ -1254,10 +1255,10 @@ private function _createNewCell($pCoordinate) */ public function cellExists($pCoordinate = 'A1') { - // Worksheet reference? + // Worksheet reference? if (strpos($pCoordinate, '!') !== false) { $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); - return $this->_parent->getSheetByName($worksheetReference[0])->cellExists($worksheetReference[1]); + return $this->_parent->getSheetByName($worksheetReference[0])->cellExists(strtoupper($worksheetReference[1])); } // Named range? @@ -1415,7 +1416,7 @@ public function getStyle($pCellCoordinate = 'A1') $this->_parent->setActiveSheetIndex($this->_parent->getIndex($this)); // set cell coordinate as active - $this->setSelectedCells($pCellCoordinate); + $this->setSelectedCells(strtoupper($pCellCoordinate)); return $this->_parent->getCellXfSupervisor(); } @@ -1428,6 +1429,7 @@ public function getStyle($pCellCoordinate = 'A1') */ public function getConditionalStyles($pCoordinate = 'A1') { + $pCoordinate = strtoupper($pCoordinate); if (!isset($this->_conditionalStylesCollection[$pCoordinate])) { $this->_conditionalStylesCollection[$pCoordinate] = array(); } @@ -1442,7 +1444,7 @@ public function getConditionalStyles($pCoordinate = 'A1') */ public function conditionalStylesExists($pCoordinate = 'A1') { - if (isset($this->_conditionalStylesCollection[$pCoordinate])) { + if (isset($this->_conditionalStylesCollection[strtoupper($pCoordinate)])) { return true; } return false; @@ -1456,7 +1458,7 @@ public function conditionalStylesExists($pCoordinate = 'A1') */ public function removeConditionalStyles($pCoordinate = 'A1') { - unset($this->_conditionalStylesCollection[$pCoordinate]); + unset($this->_conditionalStylesCollection[strtoupper($pCoordinate)]); return $this; } @@ -1479,7 +1481,7 @@ public function getConditionalStylesCollection() */ public function setConditionalStyles($pCoordinate = 'A1', $pValue) { - $this->_conditionalStylesCollection[$pCoordinate] = $pValue; + $this->_conditionalStylesCollection[strtoupper($pCoordinate)] = $pValue; return $this; } @@ -1902,6 +1904,8 @@ public function getAutoFilter() */ public function setAutoFilter($pValue) { + $pRange = strtoupper($pValue); + if (is_string($pValue)) { $this->_autoFilter->setRange($pValue); } elseif(is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) { From 5e24bcfedc7c7348f5de4e9839311f5c5b8e52c8 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 8 Jan 2015 01:23:11 +0000 Subject: [PATCH 299/467] Fix to getCellStyleXfByHashCode() method --- Classes/PHPExcel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index 27aa77ae7..d27de51a2 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -1011,7 +1011,7 @@ public function getCellStyleXfByIndex($pIndex = 0) */ public function getCellStyleXfByHashCode($pValue = '') { - foreach ($this->_cellXfStyleCollection as $cellStyleXf) { + foreach ($this->_cellStyleXfCollection as $cellStyleXf) { if ($cellStyleXf->getHashCode() == $pValue) { return $cellStyleXf; } From c7da475ef926db2dea3066b9bf0904a563cbb026 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 12 Jan 2015 23:18:46 +0000 Subject: [PATCH 300/467] Inline styles for HTML not yet implemented --- Classes/PHPExcel/Reader/HTML.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 103c2c643..c07cb3ac4 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -395,13 +395,13 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, $this->_flushCell($sheet, $column, $row, $cellContent); - if (isset($attributeArray['style']) && !empty($attributeArray['style'])) { - $styleAry = $this->getPhpExcelStyleArray($attributeArray['style']); - - if (!empty($styleAry)) { - $sheet->getStyle($column . $row)->applyFromArray($styleAry); - } - } +// if (isset($attributeArray['style']) && !empty($attributeArray['style'])) { +// $styleAry = $this->getPhpExcelStyleArray($attributeArray['style']); +// +// if (!empty($styleAry)) { +// $sheet->getStyle($column . $row)->applyFromArray($styleAry); +// } +// } if (isset($attributeArray['rowspan']) && isset($attributeArray['colspan'])) { //create merging rowspan and colspan From 98f4754048074054147a64fa550de3298588181c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 13 Jan 2015 18:47:29 +0000 Subject: [PATCH 301/467] GH-496 - Error for superscript handling in HTML to Rich Text helper --- Classes/PHPExcel/Helper/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index a3e040518..48845aea0 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -706,7 +706,7 @@ protected function startSuperscriptTag() { $this->superscript = true; } - protected function endSupercriptTag() { + protected function endSuperscriptTag() { $this->superscript = false; } From 16f2eb63a126add20c06eebf901940500672b46e Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 13 Jan 2015 23:44:38 +0000 Subject: [PATCH 302/467] Additional examples for HTML to Rich Text helper (superscript and subscript) --- Examples/42richText.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Examples/42richText.php b/Examples/42richText.php index 001627237..4e99b8535 100644 --- a/Examples/42richText.php +++ b/Examples/42richText.php @@ -78,11 +78,16 @@

'; +$html3='23 equals 8'; + +$html4='H2SO4 is the chemical formula for Sulphuric acid'; + + $wizard = new PHPExcel_Helper_HTML; $richText = $wizard->toRichTextObject($html1); $objPHPExcel->setActiveSheetIndex(0) - ->setCellValue('A1', $richText); + ->setCellValue('A1', $richText); $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(48); $objPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(-1); @@ -93,13 +98,19 @@ $richText = $wizard->toRichTextObject($html2); $objPHPExcel->setActiveSheetIndex(0) - ->setCellValue('A2', $richText); + ->setCellValue('A2', $richText); $objPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(-1); $objPHPExcel->getActiveSheet()->getStyle('A2') ->getAlignment() ->setWrapText(true); +$objPHPExcel->setActiveSheetIndex(0) + ->setCellValue('A3', $wizard->toRichTextObject($html3)); + +$objPHPExcel->setActiveSheetIndex(0) + ->setCellValue('A4', $wizard->toRichTextObject($html4)); + // Rename worksheet echo date('H:i:s') , " Rename worksheet" , EOL; From c089cfd53f07b2ba002ab37fb516c8cc15e923b2 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 17 Jan 2015 22:51:48 +0000 Subject: [PATCH 303/467] Modify numeric comparisons in calculation engine to make allowance for floating point imprecision --- Classes/PHPExcel/Calculation.php | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 1f8c93238..7887a4a94 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -1726,6 +1726,7 @@ private function __construct(PHPExcel $workbook = NULL) { if ($this->_savedPrecision < $setPrecision) { ini_set('precision',$setPrecision); } + $this->delta = 1 * pow(10, -$setPrecision); if ($workbook !== NULL) { self::$_workbookSets[$workbook->getID()] = $this; @@ -3600,27 +3601,39 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 break; // Equality case '=': - $result = ($operand1 == $operand2); + if (is_numeric($operand1) && is_numeric($operand2)) { + $result = (abs($operand1 - $operand2) < $this->delta); + } else { + $result = strcmp($operand1, $operand2) == 0; + } break; // Greater than or equal case '>=': - if ($useLowercaseFirstComparison) { + if (is_numeric($operand1) && is_numeric($operand2)) { + $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 > $operand2)); + } elseif ($useLowercaseFirstComparison) { $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0; } else { - $result = ($operand1 >= $operand2); + $result = strcmp($operand1, $operand2) >= 0; } break; // Less than or equal case '<=': - if ($useLowercaseFirstComparison) { + if (is_numeric($operand1) && is_numeric($operand2)) { + $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 < $operand2)); + } elseif ($useLowercaseFirstComparison) { $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0; } else { - $result = ($operand1 <= $operand2); + $result = strcmp($operand1, $operand2) <= 0; } break; // Inequality case '<>': - $result = ($operand1 != $operand2); + if (is_numeric($operand1) && is_numeric($operand2)) { + $result = (abs($operand1 - $operand2) > 1E-14); + } else { + $result = strcmp($operand1, $operand2) != 0; + } break; } From dc137c293afc3caf69d8934f06b8dc3d7c685578 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 18 Jan 2015 12:31:18 +0000 Subject: [PATCH 304/467] Method for reversing the case of a string, for use in comparisons where lower-case/upper-case is reversed --- Classes/PHPExcel/Calculation.php | 16 ++++---- Classes/PHPExcel/Shared/String.php | 37 ++++++++++++++++++- .../Worksheet/AutoFilter/Column/Rule.php | 2 +- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 7887a4a94..1b0101632 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -3641,21 +3641,19 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack $stack->push('Value',$result); - return TRUE; - } // function _executeBinaryComparisonOperation() + return true; + } /** * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters - * @param string $str1 - * @param string $str2 - * @return integer + * @param string $str1 First string value for the comparison + * @param string $str2 Second string value for the comparison + * @return integer */ private function strcmpLowercaseFirst($str1, $str2) { - $from = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; - $to = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $inversedStr1 = strtr($str1, $from, $to); - $inversedStr2 = strtr($str2, $from, $to); + $inversedStr1 = PHPExcel_Shared_String::StrCaseReverse($str1); + $inversedStr2 = PHPExcel_Shared_String::StrCaseReverse($str2); return strcmp($inversedStr1, $inversedStr2); } diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 4921dc958..7d6b4192b 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -626,6 +626,41 @@ public static function StrToTitle($pValue = '') return ucwords($pValue); } + public static function mb_is_upper($char) + { + return mb_strtolower($char, "UTF-8") != $char; + } + + public static function mb_str_split($string) + { + # Split at all position not after the start: ^ + # and not before the end: $ + return preg_split('/(? Date: Fri, 23 Jan 2015 15:40:54 +0000 Subject: [PATCH 305/467] Fix to negative number handling with complex number format masks, so that the sign only appears once --- Classes/PHPExcel/Style/NumberFormat.php | 17 +++++++++++------ unitTests/rawTestData/Style/NumberFormat.data | 1 + 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index e098f6f20..39e5dfab8 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -498,12 +498,14 @@ private static function _formatAsFraction(&$value, &$format) } } - private static function _complexNumberFormatMask($number, $mask) { + private static function _complexNumberFormatMask($number, $mask, $level = 0) { + $sign = ($number < 0.0); + $number = abs($number); if (strpos($mask,'.') !== false) { $numbers = explode('.', $number . '.0'); $masks = explode('.', $mask . '.0'); - $result1 = self::_complexNumberFormatMask($numbers[0], $masks[0]); - $result2 = strrev(self::_complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]))); + $result1 = self::_complexNumberFormatMask($numbers[0], $masks[0], 1); + $result2 = strrev(self::_complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1])), 1); return $result1 . '.' . $result2; } @@ -521,7 +523,7 @@ private static function _complexNumberFormatMask($number, $mask) { fmod($number, $divisor) ); $number = floor($number / $divisor); - $mask = substr_replace($mask,$blockValue, $offset, $size); + $mask = substr_replace($mask, $blockValue, $offset, $size); } if ($number > 0) { $mask = substr_replace($mask, $number, $offset, 0); @@ -531,7 +533,7 @@ private static function _complexNumberFormatMask($number, $mask) { $result = $number; } - return $result; + return (($sign) ? '-' : '') . $result; } /** @@ -614,9 +616,12 @@ public static function toFormattedString($value = '0', $format = PHPExcel_Style_ // Some non-number characters are escaped with \, which we don't need $format = preg_replace("/\\\\/", '', $format); +// Handle escaped characters, such as \" to display a literal " or \\ to display a literal \ +// $format = preg_replace('/(? Date: Fri, 23 Jan 2015 16:09:36 +0000 Subject: [PATCH 306/467] Fix to complex number format signing when mask has a decimal --- Classes/PHPExcel/Style/NumberFormat.php | 4 ++-- unitTests/rawTestData/Style/NumberFormat.data | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index 39e5dfab8..62ab3e275 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -505,8 +505,8 @@ private static function _complexNumberFormatMask($number, $mask, $level = 0) { $numbers = explode('.', $number . '.0'); $masks = explode('.', $mask . '.0'); $result1 = self::_complexNumberFormatMask($numbers[0], $masks[0], 1); - $result2 = strrev(self::_complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1])), 1); - return $result1 . '.' . $result2; + $result2 = strrev(self::_complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]), 1)); + return (($sign) ? '-' : '') . $result1 . '.' . $result2; } $r = preg_match_all('/0+/', $mask, $result, PREG_OFFSET_CAPTURE); diff --git a/unitTests/rawTestData/Style/NumberFormat.data b/unitTests/rawTestData/Style/NumberFormat.data index 08a0d6a7b..49acaccfc 100644 --- a/unitTests/rawTestData/Style/NumberFormat.data +++ b/unitTests/rawTestData/Style/NumberFormat.data @@ -33,3 +33,5 @@ 123456789, '0 (+00) 0000 00 00 00', "0 (+00) 0123 45 67 89" 123456789, '0000:00:00', "12345:67:89" -123456789, '0000:00:00', "-12345:67:89" +1234567.89, '0000:00.00', "12345:67.89" +-1234567.89,'0000:00.00', "-12345:67.89" From 976e7f064a0aec1865683feb29138b87fadf49d4 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 23 Jan 2015 16:49:20 +0000 Subject: [PATCH 307/467] Excel TRIM function only trims spaces, not tabs or other spacing characters --- Classes/PHPExcel/Calculation/TextData.php | 3 +-- unitTests/rawTestData/Calculation/TextData/TRIM.data | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php index 7a52d2e7f..148a5b756 100644 --- a/Classes/PHPExcel/Calculation/TextData.php +++ b/Classes/PHPExcel/Calculation/TextData.php @@ -118,13 +118,12 @@ public static function TRIMNONPRINTABLE($stringValue = '') { */ public static function TRIMSPACES($stringValue = '') { $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); - if (is_bool($stringValue)) { return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); } if (is_string($stringValue) || is_numeric($stringValue)) { - return trim(preg_replace('/ +/',' ',trim($stringValue,' '))); + return trim(preg_replace('/ +/',' ',trim($stringValue, ' ')), ' '); } return NULL; } // function TRIMSPACES() diff --git a/unitTests/rawTestData/Calculation/TextData/TRIM.data b/unitTests/rawTestData/Calculation/TextData/TRIM.data index ea1bd0503..ea800963c 100644 --- a/unitTests/rawTestData/Calculation/TextData/TRIM.data +++ b/unitTests/rawTestData/Calculation/TextData/TRIM.data @@ -1,6 +1,6 @@ "HELLO ", "HELLO" " HELLO", "HELLO" -" HELLO ", "HELLO" +" HELLO ", "HELLO" " HELLO", " HELLO" "HELLO WORLD", "HELLO WORLD" TRUE, "TRUE" From b3c5e98022b409f405ade65c778aa1ddc6819697 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 23 Jan 2015 17:06:30 +0000 Subject: [PATCH 308/467] I shouldn't modify compatibility mode in calculation tests without resetting it TODO - should include setting/resetting this in all setup/teardown --- unitTests/Classes/PHPExcel/CalculationTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unitTests/Classes/PHPExcel/CalculationTest.php b/unitTests/Classes/PHPExcel/CalculationTest.php index 8f8ce7e0a..1a510a02d 100644 --- a/unitTests/Classes/PHPExcel/CalculationTest.php +++ b/unitTests/Classes/PHPExcel/CalculationTest.php @@ -25,6 +25,8 @@ public function testBinaryComparisonOperation($formula, $expectedResultExcel, $e PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE); $resultOpenOffice = \PHPExcel_Calculation::getInstance()->_calculateFormulaValue($formula); $this->assertEquals($expectedResultOpenOffice, $resultOpenOffice, 'should be OpenOffice compatible'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } public function providerBinaryComparisonOperation() From 71dba49fffff1e42529f4ea72fbc487d9b5ed3fe Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 23 Jan 2015 23:44:32 +0000 Subject: [PATCH 309/467] Improvements to array arithmetic (MMULT) Better setup of calculation function tests to ensure consistent environment --- Classes/PHPExcel/Calculation/MathTrig.php | 38 ++++++++++--------- Classes/PHPExcel/Shared/JAMA/Matrix.php | 4 +- .../PHPExcel/Calculation/DateTimeTest.php | 2 + .../PHPExcel/Calculation/EngineeringTest.php | 2 + .../PHPExcel/Calculation/FinancialTest.php | 2 + .../PHPExcel/Calculation/FunctionsTest.php | 2 + .../PHPExcel/Calculation/LogicalTest.php | 2 + .../PHPExcel/Calculation/LookupRefTest.php | 2 + .../PHPExcel/Calculation/MathTrigTest.php | 2 + .../PHPExcel/Calculation/TextDataTest.php | 2 + .../Classes/PHPExcel/CalculationTest.php | 4 +- .../Calculation/MathTrig/MINVERSE.data | 7 +++- .../Calculation/MathTrig/MMULT.data | 19 +++++----- 13 files changed, 56 insertions(+), 32 deletions(-) diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index f3ae111e4..689d59ffc 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -316,14 +316,17 @@ public static function FLOOR($number, $significance = NULL) { } if ((is_numeric($number)) && (is_numeric($significance))) { - if (($number == 0.0 ) || ($significance == 0.0)) { + if ($significance == 0.0) { + return PHPExcel_Calculation_Functions::DIV0(); + } elseif ($number == 0.0) { return 0.0; } elseif (self::SIGN($number) == self::SIGN($significance)) { return floor($number / $significance) * $significance; } else { return PHPExcel_Calculation_Functions::NaN(); } - } + } else + return PHPExcel_Calculation_Functions::VALUE(); } // function FLOOR() @@ -606,27 +609,27 @@ public static function MMULT($matrixData1,$matrixData2) { if (!is_array($matrixData1)) { $matrixData1 = array(array($matrixData1)); } if (!is_array($matrixData2)) { $matrixData2 = array(array($matrixData2)); } - $rowA = 0; - foreach($matrixData1 as $matrixRow) { - if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } - $columnA = 0; - foreach($matrixRow as $matrixCell) { - if ((is_string($matrixCell)) || ($matrixCell === null)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $matrixAData[$rowA][$columnA] = $matrixCell; - ++$columnA; - } - ++$rowA; - } try { + $rowA = 0; + foreach($matrixData1 as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $columnA = 0; + foreach($matrixRow as $matrixCell) { + if ((!is_numeric($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixAData[$rowA][$columnA] = $matrixCell; + ++$columnA; + } + ++$rowA; + } $matrixA = new PHPExcel_Shared_JAMA_Matrix($matrixAData); $rowB = 0; foreach($matrixData2 as $matrixRow) { if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } $columnB = 0; foreach($matrixRow as $matrixCell) { - if ((is_string($matrixCell)) || ($matrixCell === null)) { + if ((!is_numeric($matrixCell)) || ($matrixCell === null)) { return PHPExcel_Calculation_Functions::VALUE(); } $matrixBData[$rowB][$columnB] = $matrixCell; @@ -636,12 +639,13 @@ public static function MMULT($matrixData1,$matrixData2) { } $matrixB = new PHPExcel_Shared_JAMA_Matrix($matrixBData); - if (($rowA != $columnB) || ($rowB != $columnA)) { + if ($columnA != $rowB) { return PHPExcel_Calculation_Functions::VALUE(); } return $matrixA->times($matrixB)->getArray(); } catch (PHPExcel_Exception $ex) { + var_dump($ex->getMessage()); return PHPExcel_Calculation_Functions::VALUE(); } } // function MMULT() diff --git a/Classes/PHPExcel/Shared/JAMA/Matrix.php b/Classes/PHPExcel/Shared/JAMA/Matrix.php index b893a447a..1e7c334ac 100644 --- a/Classes/PHPExcel/Shared/JAMA/Matrix.php +++ b/Classes/PHPExcel/Shared/JAMA/Matrix.php @@ -1028,7 +1028,7 @@ public function solve($B) { $LU = new PHPExcel_Shared_JAMA_LUDecomposition($this); return $LU->solve($B); } else { - $QR = new QRDecomposition($this); + $QR = new PHPExcel_Shared_JAMA_QRDecomposition($this); return $QR->solve($B); } } // function solve() @@ -1054,6 +1054,4 @@ public function det() { $L = new PHPExcel_Shared_JAMA_LUDecomposition($this); return $L->det(); } // function det() - - } // class PHPExcel_Shared_JAMA_Matrix diff --git a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php index 57692a341..d4bdc5abf 100644 --- a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php @@ -13,6 +13,8 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php b/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php index 647da09f4..1f511ffac 100644 --- a/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php @@ -17,6 +17,8 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php b/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php index b27a6a7df..f5689c950 100644 --- a/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php @@ -13,6 +13,8 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php b/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php index 5e6ef962a..013332940 100644 --- a/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php @@ -13,6 +13,8 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } public function testDUMMY() diff --git a/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php b/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php index 46749d12c..cc8f8b333 100644 --- a/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php @@ -13,6 +13,8 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } public function testTRUE() diff --git a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php index 454422a15..6450b0822 100644 --- a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php @@ -13,6 +13,8 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php index e3d8c9d98..0059ed08e 100644 --- a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php @@ -13,6 +13,8 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php index ea7882b6c..4b1caf517 100644 --- a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php @@ -13,6 +13,8 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** diff --git a/unitTests/Classes/PHPExcel/CalculationTest.php b/unitTests/Classes/PHPExcel/CalculationTest.php index 1a510a02d..1de827ca8 100644 --- a/unitTests/Classes/PHPExcel/CalculationTest.php +++ b/unitTests/Classes/PHPExcel/CalculationTest.php @@ -11,6 +11,8 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } /** @@ -25,8 +27,6 @@ public function testBinaryComparisonOperation($formula, $expectedResultExcel, $e PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE); $resultOpenOffice = \PHPExcel_Calculation::getInstance()->_calculateFormulaValue($formula); $this->assertEquals($expectedResultOpenOffice, $resultOpenOffice, 'should be OpenOffice compatible'); - - PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); } public function providerBinaryComparisonOperation() diff --git a/unitTests/rawTestData/Calculation/MathTrig/MINVERSE.data b/unitTests/rawTestData/Calculation/MathTrig/MINVERSE.data index 47586b229..40ee42840 100644 --- a/unitTests/rawTestData/Calculation/MathTrig/MINVERSE.data +++ b/unitTests/rawTestData/Calculation/MathTrig/MINVERSE.data @@ -1,4 +1,4 @@ -{1|2|3;4|5|6;7|8|9}, {-4.50359962737050E+15|9.00719925474099E+15|-4.50359962737050E+15;9.00719925474100E+15|-1.80143985094820E+16|9.00719925474099E+15;-4.50359962737050E+15|9.00719925474099E+15|-4.50359962737050E+15} +{1|2|3;4|5|6;7|8|9}, {-4.50359962737050E+15|9.00719925474099E+15|-4.50359962737050E+15;9.00719925474100E+15|-1.80143985094820E+16|9.00719925474099E+15;-4.50359962737050E+15|9.00719925474099E+15|-4.50359962737050E+15} {10|20|30;40|50|60;70|80|90}, {7.03687441776639E+13|-1.40737488355328E+14|7.03687441776640E+13;-1.40737488355328E+14|2.81474976710656E+14|-1.40737488355328E+14;7.03687441776641E+13|-1.40737488355328E+14|7.03687441776640E+13} {8|1|6;3|5|7;4|9|2}, {1.47222222222222E-01|-1.44444444444444E-01|6.38888888888889E-02;-6.11111111111111E-02|2.22222222222222E-02|1.05555555555556E-01;-1.94444444444444E-02|1.88888888888889E-01|-1.02777777777778E-01} {4|-1;2|0}, {0|0.5;-1|2} @@ -8,3 +8,8 @@ {0.2|1|-0.9;0.35|10.8|4;-3.15|5}, "#VALUE!" {1|2;3|4}, {-2|1;1.5|-0.5} {1|2|1;3|4|2;1|1|2}, {-2|1|0;1.33333333333333|-0.33333333333333|-0.33333333333333;0.33333333333333|-0.33333333333333|0.66666666666667} +{2|3;4|5}, {-2.5|1.5;2|-1} +{5|8;7|9}, {-0.818181818181818|0.727272727272727;0.636363636363636|-0.454545454545455} +{45|78;17|50}, {0.054112554112554|-0.084415584415584;-0.018398268398268|0.048701298701299} +{2|2;2|1}, {-0.5|1.0;1|-1} +{1|4|6;7|4|10;15|16|20}, {-0.2941176470588230|0.0588235294117647|0.0588235294117647;0.0367647058823529|-0.2573529411764710|0.1176470588235290;0.1911764705882350|0.1617647058823530|-0.0882352941176471} \ No newline at end of file diff --git a/unitTests/rawTestData/Calculation/MathTrig/MMULT.data b/unitTests/rawTestData/Calculation/MathTrig/MMULT.data index 430dd88d1..06af83a07 100644 --- a/unitTests/rawTestData/Calculation/MathTrig/MMULT.data +++ b/unitTests/rawTestData/Calculation/MathTrig/MMULT.data @@ -1,11 +1,12 @@ {1|2;3|4}, {1|2;3|4}, {7|10;15|22} {1|2|3;4|5|6;7|8|9}, {1|2|3;4|5|6;7|8|9}, {30|36|42;66|81|96;102|126|150} -{1|2;3|4}, 2, {2|4;6|8} -{1|2;3|4}, {2}, {2|4;6|8} -2, {1|2;3|4}, {2|4;6|8} -{2}, {1|2;3|4}, {2|4;6|8} -{1|2;3|4}, {2|4}, {2|4;6|8} -{1|2;3|4}, {2;4}, {2|4;6|8} -{2|4}, {1|2;3|4}, {2|4;6|8} -{2;4}, {1|2;3|4}, {2|4;6|8} -{1|2;3|4;5|6}, {1|2|3;4|5|6}, {1|2|3;4|5|6;7|8|9} +{1|2;3|4}, 2, "#VALUE!" // Mismatched dimensions +{1|2;3|4}, {2}, "#VALUE!" // Mismatched dimensions +{1.2;2.4}, {3.6|4.5}, {14.43|14.43;14.43|14.43} +2, {1|2;3|4}, "#VALUE!" // Mismatched dimensions +{2}, {1|2;3|4}, "#VALUE!" // Mismatched dimensions +{1|2;3|4}, {2|4}, "#VALUE!" +{1|2;3|4}, {2;4}, {{10};{22}} +{2|4}, {1|2;3|4}, {14|20} +{2;4}, {1|2;3|4}, "#VALUE!" // Mismatched dimensions +{1|2;3|4;5|6}, {1|2|3;4|5|6}, {9|12|15;19|26|33;29|40|51} From 391d7cbd9dfaee7da0c56a11762bb7052bd7fa6b Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 2 Feb 2015 16:45:59 +0000 Subject: [PATCH 310/467] Fix use of < and > (by escaping) in documentation for createSheet() --- Documentation/markdown/Overview/06-Worksheets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/markdown/Overview/06-Worksheets.md b/Documentation/markdown/Overview/06-Worksheets.md index 1c2a9ea5c..a6a231ccf 100644 --- a/Documentation/markdown/Overview/06-Worksheets.md +++ b/Documentation/markdown/Overview/06-Worksheets.md @@ -46,7 +46,7 @@ You can add a new worksheet to the workbook using the `createSheet()` method of $objPHPExcel->createSheet(); ``` -A new worksheet created using this method will be called "Worksheet"� where ""� is the lowest number possible to guarantee that the title is unique. +A new worksheet created using this method will be called "Worksheet\"� where "\"� is the lowest number possible to guarantee that the title is unique. Alternatively, you can instantiate a new worksheet (setting the title to whatever you choose) and then insert it into your workbook using the addSheet() method. From 31aa953c0b97a22a98d67f00905840bd2d0499bd Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 4 Feb 2015 15:41:59 +0000 Subject: [PATCH 311/467] Remove trailing white space from PCLZip --- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index 4bf05a523..5b81e6790 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -5689,6 +5689,3 @@ function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) return $p_path; } // -------------------------------------------------------------------------------- - - -?> From 26e75b1f7af3bb042a08d7a81ac164db29f25a8b Mon Sep 17 00:00:00 2001 From: Andrey Yantsen Date: Tue, 10 Feb 2015 09:44:13 +0300 Subject: [PATCH 312/467] Check for variable before using it In some cases $xfrm is empty SimpleXmlElement, so we should check for it before using $xfrm->ext->attributes() --- Classes/PHPExcel/Reader/Excel2007.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 277d278d8..c3473245d 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1510,10 +1510,9 @@ public function load($pFilename) $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff)); $objDrawing->setResizeProportional(false); - $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cx"))); - $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cy"))); - if ($xfrm) { + $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cx"))); + $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cy"))); $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); } if ($outerShdw) { From 518fbc1d36218fa1a7d5da0da2ba3045164b405a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 14 Feb 2015 23:52:57 +0000 Subject: [PATCH 313/467] GH-514 HTML Reader incorrectly converts some UTF-8 string cells to FALSE after regexp space trim --- Classes/PHPExcel/Reader/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index c07cb3ac4..508672ce4 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -217,7 +217,7 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, { foreach ($element->childNodes as $child) { if ($child instanceof DOMText) { - $domText = preg_replace('/\s+/', ' ', trim($child->nodeValue)); + $domText = preg_replace('/\s+/u', ' ', trim($child->nodeValue)); if (is_string($cellContent)) { // simply append the text if the cell content is a plain text string $cellContent .= $domText; From 538fbcd2e807c14609ade41cad0b4ecf33355d84 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 15 Feb 2015 00:01:01 +0000 Subject: [PATCH 314/467] Additional regexp handling for UTF-8 strings --- Classes/PHPExcel/Calculation.php | 4 ++-- Classes/PHPExcel/Helper/HTML.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 1b0101632..48fb4a422 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2920,11 +2920,11 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { // echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function
'; if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { - $val = preg_replace('/\s/','',$val); + $val = preg_replace('/\s/u','',$val); // echo 'Element '.$val.' is a Function
'; if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function $stack->push('Function', strtoupper($val)); - $ax = preg_match('/^\s*(\s*\))/i', substr($formula, $index+$length), $amatch); + $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch); if ($ax) { $stack->push('Operand Count for Function '.strtoupper($val).')', 0); $expectingOperator = TRUE; diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index 48845aea0..9e30ae8a7 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -723,7 +723,7 @@ protected function breakTag() { } protected function parseTextNode(DOMText $textNode) { - $domText = preg_replace('/\s+/', ' ', ltrim($textNode->nodeValue)); + $domText = preg_replace('/\s+/u', ' ', ltrim($textNode->nodeValue)); $this->stringData .= $domText; $this->buildTextRun(); } From a95e3f6607c5c1adc330ec493b6366c103681cdd Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 4 Mar 2015 23:36:38 +0000 Subject: [PATCH 315/467] Bugfix: Remove cells cleanly when calling RemoveRow() or RemoveColumn() --- .../CachedObjectStorage/CacheBase.php | 31 ++++++++++++++++++- Classes/PHPExcel/Worksheet.php | 14 +++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index 9f780b2a6..84cededf5 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -206,7 +206,7 @@ public function getHighestRowAndColumn() sscanf($coord,'%[A-Z]%d', $c, $r); $row[$r] = $r; $col[$c] = strlen($c).$c; - } + } if (!empty($row)) { // Determine highest column and row $highestRow = max($row); @@ -333,6 +333,35 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) { } } // function copyCellCollection() + /** + * Remove a row, deleting all cells in that row + * + * @param string $row Row number to remove + * @return void + */ + public function removeRow($row) { + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $c, $r); + if ($r == $row) { + $this->deleteCacheData($coord); + } + } + } + + /** + * Remove a column, deleting all cells in that column + * + * @param string $column Column ID to remove + * @return void + */ + public function removeColumn($column) { + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $c, $r); + if ($c == $column) { + $this->deleteCacheData($coord); + } + } + } /** * Identify whether the caching method is currently available diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 88ffa315a..51edf4abb 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -2064,8 +2064,13 @@ public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) { */ public function removeRow($pRow = 1, $pNumRows = 1) { if ($pRow >= 1) { + $highestRow = $this->getHighestDataRow(); $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this); + for($r = 0; $r < $pNumRows; ++$r) { + $this->getCellCacheController()->removeRow($highestRow); + --$highestRow; + } } else { throw new PHPExcel_Exception("Rows to be deleted should at least start from row 1."); } @@ -2075,16 +2080,21 @@ public function removeRow($pRow = 1, $pNumRows = 1) { /** * Remove a column, updating all possible related data * - * @param int $pColumn Remove starting with this one - * @param int $pNumCols Number of columns to remove + * @param string $pColumn Remove starting with this one + * @param int $pNumCols Number of columns to remove * @throws PHPExcel_Exception * @return PHPExcel_Worksheet */ public function removeColumn($pColumn = 'A', $pNumCols = 1) { if (!is_numeric($pColumn)) { + $highestColumn = $this->getHighestDataColumn(); $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols); $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this); + for($c = 0; $c < $pNumCols; ++$c) { + $this->getCellCacheController()->removeColumn($highestColumn); + $highestColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($highestColumn) - 2); + } } else { throw new PHPExcel_Exception("Column references should not be numeric."); } From de9fc7b8888a40719bcdedc53ae3964a339a5d9b Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 4 Mar 2015 23:37:52 +0000 Subject: [PATCH 316/467] Update latest bugfix details in changelog --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index f8f2170f2..04a0ed559 100644 --- a/changelog.txt +++ b/changelog.txt @@ -38,6 +38,7 @@ Planned for v1.8.1 - Bugfix: (wiseloren) Work Item CP21454 - "No Impact" conditional formatting fix for NumberFormat - Bugfix: (bobwitlox) Work Item GH-467 - Bug in Excel2003XML reader, parsing merged cells - Bugfix: (MBaker) Work Item GH-302 - Fix for CEIL() and FLOOR() when number argument is zero +- Bugfix: (MBaker) - Remove cells cleanly when calling RemoveRow() or RemoveColumn() - General: (MBaker) - Small performance improvement for autosize columns - General: (frost-nzcr4) Work Item GH-379 - Change the getter/setter for zeroHeight to camel case - General: (MBaker) Work Item GH-394 - DefaultValueBinder is too much aggressive when converting string to numeric From 412a2520cdb19e0d57f54ef1cf9e03ff9c45855a Mon Sep 17 00:00:00 2001 From: Pierre Skowron Date: Mon, 9 Mar 2015 14:17:28 +0100 Subject: [PATCH 317/467] Set default plotDirection --- Classes/PHPExcel/Chart/DataSeries.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index 86e61eb17..56faf6ee0 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -137,7 +137,7 @@ class PHPExcel_Chart_DataSeries /** * Create a new PHPExcel_Chart_DataSeries */ - public function __construct($plotType = null, $plotGrouping = null, $plotOrder = array(), $plotLabel = array(), $plotCategory = array(), $plotValues = array(), $smoothLine = null, $plotStyle = null) + public function __construct($plotType = null, $plotGrouping = null, $plotOrder = array(), $plotLabel = array(), $plotCategory = array(), $plotValues = array(), $plotDirection = null, $smoothLine = null, $plotStyle = null) { $this->_plotType = $plotType; $this->_plotGrouping = $plotGrouping; @@ -155,6 +155,11 @@ public function __construct($plotType = null, $plotGrouping = null, $plotOrder = $this->_plotCategory = $plotCategory; $this->_smoothLine = $smoothLine; $this->_plotStyle = $plotStyle; + + if (is_null($plotDirection)) { + $plotDirection = self::DIRECTION_COL; + } + $this->_plotDirection = $plotDirection; } /** From d3148bdcdb4d9918eaa85310c871137a1f35ecab Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 9 Mar 2015 23:59:13 +0000 Subject: [PATCH 318/467] Minor bugfixes --- Classes/PHPExcel/Shared/Font.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php index ee0702e44..8e5b27b8f 100644 --- a/Classes/PHPExcel/Shared/Font.php +++ b/Classes/PHPExcel/Shared/Font.php @@ -258,7 +258,7 @@ public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText // Special case if there are one or more newline characters ("\n") if (strpos($cellText, "\n") !== false) { $lineTexts = explode("\n", $cellText); - $lineWitdhs = array(); + $lineWidths = array(); foreach ($lineTexts as $lineText) { $lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont); } @@ -274,7 +274,7 @@ public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText // and addition because Excel adds some padding, just use approx width of 'n' glyph $columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation) + $columnWidthAdjust; } catch (PHPExcel_Exception $e) { - $approximate == true; + $approximate = true; } } From d44aebc0a41a0eb5ca4dd6965f76c1b2ee8a4e4a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 26 Mar 2015 23:25:24 +0000 Subject: [PATCH 319/467] Improve default value binder handling of string/numeric values - Modified regexp to handle scientific notation and apply appropriate tests rather than drop through to string - modified handler to detect integers too long for PHP, and treat as string rather than convert to float --- Classes/PHPExcel/Cell/DefaultValueBinder.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Cell/DefaultValueBinder.php b/Classes/PHPExcel/Cell/DefaultValueBinder.php index 59a9c7137..a9dae410e 100644 --- a/Classes/PHPExcel/Cell/DefaultValueBinder.php +++ b/Classes/PHPExcel/Cell/DefaultValueBinder.php @@ -86,8 +86,11 @@ public static function dataTypeForValue($pValue = null) { return PHPExcel_Cell_DataType::TYPE_BOOL; } elseif (is_float($pValue) || is_int($pValue)) { return PHPExcel_Cell_DataType::TYPE_NUMERIC; - } elseif (preg_match('/^\-?([0-9]+\\.?[0-9]*|[0-9]*\\.?[0-9]+)$/', $pValue)) { - if (is_string($pValue) && $pValue{0} === '0' && strlen($pValue) > 1 && $pValue{1} !== '.' ) { + } elseif (preg_match('/^[\+\-]?([0-9]+\\.?[0-9]*|[0-9]*\\.?[0-9]+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $pValue)) { + $tValue = ltrim($pValue, '+-'); + if (is_string($pValue) && $tValue{0} === '0' && strlen($tValue) > 1 && $tValue{1} !== '.' ) { + return PHPExcel_Cell_DataType::TYPE_STRING; + } elseif((strpos($pValue, '.') === false) && ($pValue > PHP_INT_MAX)) { return PHPExcel_Cell_DataType::TYPE_STRING; } return PHPExcel_Cell_DataType::TYPE_NUMERIC; From d9cda3f287d9d6dc496a732b68814ce572d6fd3b Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 27 Mar 2015 21:28:26 +0000 Subject: [PATCH 320/467] Unit tests for default value binder --- .../PHPExcel/Cell/DefaultValueBinderTest.php | 33 +++++++++++++++++++ .../rawTestData/Cell/DefaultValueBinder.data | 19 +++++++++++ 2 files changed, 52 insertions(+) create mode 100644 unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php create mode 100644 unitTests/rawTestData/Cell/DefaultValueBinder.data diff --git a/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php b/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php new file mode 100644 index 000000000..59b1dd047 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php @@ -0,0 +1,33 @@ +assertEquals($expectedResult, $result); + } + + public function providerDataTypeForValue() + { + return new testDataFileIterator('rawTestData/Cell/DefaultValueBinder.data'); + } + +} diff --git a/unitTests/rawTestData/Cell/DefaultValueBinder.data b/unitTests/rawTestData/Cell/DefaultValueBinder.data new file mode 100644 index 000000000..446ded6cd --- /dev/null +++ b/unitTests/rawTestData/Cell/DefaultValueBinder.data @@ -0,0 +1,19 @@ +NULL, "null" +, "null" +"#NULL!", "e" +FALSE, "b" +TRUE, "b" +"FALSE", "s" +"TRUE", "s" +"", "s" +"ABC", "s" +"123", "n" +123, "n" +0.123, "n" +"-123", "n" +"1.23E4", "n" +"-1.23E4", "n" +"1.23E-4", "n" +"000123", "s" +"=123", "f" +"#DIV/0!", "e" From caad6b1956b6b407baa3a2d0cca0caf5e2d09bfa Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 28 Mar 2015 17:45:49 +0000 Subject: [PATCH 321/467] Minor bugfixes for date/time edge cases --- Classes/PHPExcel/Calculation/DateTime.php | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Classes/PHPExcel/Calculation/DateTime.php b/Classes/PHPExcel/Calculation/DateTime.php index 6eb96fd2c..56c14079a 100644 --- a/Classes/PHPExcel/Calculation/DateTime.php +++ b/Classes/PHPExcel/Calculation/DateTime.php @@ -1071,7 +1071,9 @@ public static function WORKDAY($startDate,$endDays) { public static function DAYOFMONTH($dateValue = 1) { $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); - if (is_string($dateValue = self::_getDateValue($dateValue))) { + if ($dateValue === null) { + $dateValue = 1; + } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($dateValue == 0.0) { return 0; @@ -1114,7 +1116,9 @@ public static function DAYOFWEEK($dateValue = 1, $style = 1) { } $style = floor($style); - if (is_string($dateValue = self::_getDateValue($dateValue))) { + if ($dateValue === null) { + $dateValue = 1; + } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($dateValue < 0.0) { return PHPExcel_Calculation_Functions::NaN(); @@ -1180,7 +1184,9 @@ public static function WEEKOFYEAR($dateValue = 1, $method = 1) { } $method = floor($method); - if (is_string($dateValue = self::_getDateValue($dateValue))) { + if ($dateValue === null) { + $dateValue = 1; + } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($dateValue < 0.0) { return PHPExcel_Calculation_Functions::NaN(); @@ -1216,7 +1222,9 @@ public static function WEEKOFYEAR($dateValue = 1, $method = 1) { public static function MONTHOFYEAR($dateValue = 1) { $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); - if (is_string($dateValue = self::_getDateValue($dateValue))) { + if ($dateValue === null) { + $dateValue = 1; + } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($dateValue < 0.0) { return PHPExcel_Calculation_Functions::NaN(); @@ -1245,7 +1253,9 @@ public static function MONTHOFYEAR($dateValue = 1) { public static function YEAR($dateValue = 1) { $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); - if (is_string($dateValue = self::_getDateValue($dateValue))) { + if ($dateValue === null) { + $dateValue = 1; + } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($dateValue < 0.0) { return PHPExcel_Calculation_Functions::NaN(); From eedcc49f81a8aabd2a86b9458fbcf6649c948acb Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 8 Apr 2015 17:27:14 +0100 Subject: [PATCH 322/467] Minor documentation fix --- Documentation/markdown/Overview/08-Recipes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/markdown/Overview/08-Recipes.md b/Documentation/markdown/Overview/08-Recipes.md index 165bb5473..6ee9c693c 100644 --- a/Documentation/markdown/Overview/08-Recipes.md +++ b/Documentation/markdown/Overview/08-Recipes.md @@ -88,7 +88,9 @@ __Notes:__ See section "Using value binders to facilitate data entry" to learn more about the AdvancedValueBinder used in the first example. In previous versions of PHPExcel up to and including 1.6.6, when a cell had a date-like number format code, it was possible to enter a date directly using an integer PHP-time without converting to Excel date format. Starting with PHPExcel 1.6.7 this is no longer supported. -Excel can also operate in a 1904-based calendar (default for workbooks saved on Mac). Normally, you do not have to worry about this when using PHPExcel.### Write a formula into a cell +Excel can also operate in a 1904-based calendar (default for workbooks saved on Mac). Normally, you do not have to worry about this when using PHPExcel. + +### Write a formula into a cell Inside the Excel file, formulas are always stored as they would appear in an English version of Microsoft Office Excel, and PHPExcel handles all formulae internally in this format. This means that the following rules hold: From 2736af79941fc276a0c155d8c5aa6e7ce9dd635f Mon Sep 17 00:00:00 2001 From: Jared Hall Date: Thu, 9 Apr 2015 14:46:42 -0600 Subject: [PATCH 323/467] Update CacheBase.php to prevent fatal error When deleteCacheData() is called it will throw a fatal error if the _currentObject is null. --- Classes/PHPExcel/CachedObjectStorage/CacheBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index 84cededf5..7d68e944f 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -151,7 +151,7 @@ public function updateCacheData(PHPExcel_Cell $cell) { * @throws PHPExcel_Exception */ public function deleteCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { + if ($pCoord === $this->_currentObjectID && !is_null($this->_currentObject)) { $this->_currentObject->detach(); $this->_currentObjectID = $this->_currentObject = null; } From 61f5baac4a24f2311d55ea7d596aa361bea3ea92 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 16 Apr 2015 01:09:29 +0100 Subject: [PATCH 324/467] GH-543 - Datetime at DefaultValueBinder Personally, I don't call it a bug if people pass invalid arguments and it complains with an exception; but I've made some basic changes to support DateTime objects and objects with a __toString() method... Any other objects will throw a catchable fatal error, and it's up to user code to implement any exception handler to convert it to an exception and handle it --- Classes/PHPExcel/Cell/DefaultValueBinder.php | 11 +++- .../PHPExcel/Cell/DefaultValueBinderTest.php | 54 ++++++++++++++++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Cell/DefaultValueBinder.php b/Classes/PHPExcel/Cell/DefaultValueBinder.php index a9dae410e..252048f7d 100644 --- a/Classes/PHPExcel/Cell/DefaultValueBinder.php +++ b/Classes/PHPExcel/Cell/DefaultValueBinder.php @@ -57,13 +57,20 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) // sanitize UTF-8 strings if (is_string($value)) { $value = PHPExcel_Shared_String::SanitizeUTF8($value); + } elseif (is_object($value)) { + // Handle any objects that might be injected + if ($value instanceof DateTime) { + $value = $value->format('Y-m-d H:i:s'); + } elseif (!($value instanceof PHPExcel_RichText)) { + $value = (string) $value; + } } // Set value explicit $cell->setValueExplicit( $value, self::dataTypeForValue($value) ); // Done! - return TRUE; + return true; } /** @@ -74,7 +81,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) */ public static function dataTypeForValue($pValue = null) { // Match the value against a few data types - if (is_null($pValue)) { + if ($pValue === null) { return PHPExcel_Cell_DataType::TYPE_NULL; } elseif ($pValue === '') { return PHPExcel_Cell_DataType::TYPE_STRING; diff --git a/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php b/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php index 59b1dd047..1c74d96f6 100644 --- a/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php +++ b/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php @@ -4,6 +4,7 @@ class DefaultValueBinderTest extends PHPUnit_Framework_TestCase { + protected $cellStub; public function setUp() { @@ -14,6 +15,48 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } + protected function createCellStub() + { + // Create a stub for the Cell class. + $this->cellStub = $this->getMockBuilder('PHPExcel_Cell') + ->disableOriginalConstructor() + ->getMock(); + // Configure the stub. + $this->cellStub->expects($this->any()) + ->method('setValueExplicit') + ->will($this->returnValue(true)); + + } + + /** + * @dataProvider binderProvider + */ + public function testBindValue($value) + { + $this->createCellStub(); + $binder = new PHPExcel_Cell_DefaultValueBinder(); + $result = $binder->bindValue($this->cellStub, $value); + $this->assertTrue($result); + } + + public function binderProvider() + { + return array( + array(null), + array(''), + array('ABC'), + array('=SUM(A1:B2)'), + array(true), + array(false), + array(123), + array(-123.456), + array('123'), + array('-123.456'), + array('#REF!'), + array(new DateTime()), + ); + } + /** * @dataProvider providerDataTypeForValue */ @@ -21,7 +64,7 @@ public function testDataTypeForValue() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell_DefaultValueBinder','dataTypeForValue'),$args); + $result = call_user_func_array(array('PHPExcel_Cell_DefaultValueBinder','dataTypeForValue'), $args); $this->assertEquals($expectedResult, $result); } @@ -30,4 +73,13 @@ public function providerDataTypeForValue() return new testDataFileIterator('rawTestData/Cell/DefaultValueBinder.data'); } + public function testDataTypeForRichTextObject() + { + $objRichText = new PHPExcel_RichText(); + $objRichText->createText('Hello World'); + + $expectedResult = PHPExcel_Cell_DataType::TYPE_INLINE; + $result = call_user_func(array('PHPExcel_Cell_DefaultValueBinder','dataTypeForValue'), $objRichText); + $this->assertEquals($expectedResult, $result); + } } From f96d9cedba8ce6f0b63bfed96823c295e295258c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 25 Apr 2015 21:49:30 +0100 Subject: [PATCH 325/467] Added RowIterator support for end row, and throws exceptions for invalid arguments --- Classes/PHPExcel/Worksheet.php | 8 +- Classes/PHPExcel/Worksheet/RowIterator.php | 40 +++++++-- .../PHPExcel/Worksheet/RowIteratorTest.php | 87 +++++++++++++++++++ 3 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 51edf4abb..bb6a22fdb 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -2559,11 +2559,13 @@ public function toArray($nullValue = null, $calculateFormulas = true, $formatDat /** * Get row iterator * - * @param integer $startRow The row number at which to start iterating + * @param integer $startRow The row number at which to start iterating + * @param integer $endRow The row number at which to stop iterating + * * @return PHPExcel_Worksheet_RowIterator */ - public function getRowIterator($startRow = 1) { - return new PHPExcel_Worksheet_RowIterator($this,$startRow); + public function getRowIterator($startRow = 1, $endRow = null) { + return new PHPExcel_Worksheet_RowIterator($this, $startRow, $endRow); } /** diff --git a/Classes/PHPExcel/Worksheet/RowIterator.php b/Classes/PHPExcel/Worksheet/RowIterator.php index 642ec763d..295ed60e0 100644 --- a/Classes/PHPExcel/Worksheet/RowIterator.php +++ b/Classes/PHPExcel/Worksheet/RowIterator.php @@ -59,15 +59,25 @@ class PHPExcel_Worksheet_RowIterator implements Iterator private $_startRow = 1; + /** + * End position + * + * @var int + */ + private $_endRow = 1; + + /** * Create a new row iterator * * @param PHPExcel_Worksheet $subject The worksheet to iterate over * @param integer $startRow The row number at which to start iterating + * @param integer $endRow Optionally, the row number at which to stop iterating */ - public function __construct(PHPExcel_Worksheet $subject = null, $startRow = 1) { + public function __construct(PHPExcel_Worksheet $subject = null, $startRow = 1, $endRow = null) { // Set subject $this->_subject = $subject; + $this->resetEnd($endRow); $this->resetStart($startRow); } @@ -86,6 +96,19 @@ public function __destruct() { public function resetStart($startRow = 1) { $this->_startRow = $startRow; $this->seek($startRow); + + return $this; + } + + /** + * (Re)Set the end row + * + * @param integer $endRow The row number at which to stop iterating + */ + public function resetEnd($endRow = null) { + $this->_endRow = ($endRow) ? $endRow : $this->_subject->getHighestRow(); + + return $this; } /** @@ -94,6 +117,10 @@ public function resetStart($startRow = 1) { * @param integer $row The row number to set the current pointer at */ public function seek($row = 1) { + if (($row < $this->_startRow) || ($row > $this->_endRow)) { + throw new PHPExcel_Exception("Row $row is out of range ({$this->_startRow} - {$this->_endRow})"); + } + $this->_position = $row; } @@ -133,16 +160,19 @@ public function next() { * Set the iterator to its previous value */ public function prev() { - if ($this->_position > 1) - --$this->_position; + if ($this->_position <= $this->_startRow) { + throw new PHPExcel_Exception("Row is already at the beginning of range ({$this->_startRow} - {$this->_endRow})"); + } + + --$this->_position; } /** - * Indicate if more rows exist in the worksheet + * Indicate if more rows exist in the worksheet range of rows that we're iterating * * @return boolean */ public function valid() { - return $this->_position <= $this->_subject->getHighestRow(); + return $this->_position <= $this->_endRow; } } diff --git a/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php new file mode 100644 index 000000000..f39f33d56 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php @@ -0,0 +1,87 @@ +mockRow = $this->getMockBuilder('PHPExcel_Worksheet_Row') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet->expects($this->any()) + ->method('getHighestRow') + ->will($this->returnValue(5)); + $this->mockWorksheet->expects($this->any()) + ->method('current') + ->will($this->returnValue($this->mockRow)); + } + + + public function testIteratorFullRange() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet); + $rowIndexResult = 1; + $this->assertEquals($rowIndexResult, $iterator->key()); + + foreach($iterator as $key => $row) { + $this->assertEquals($rowIndexResult++, $key); + $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row); + } + } + + public function testIteratorStartEndRange() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); + $rowIndexResult = 2; + $this->assertEquals($rowIndexResult, $iterator->key()); + + foreach($iterator as $key => $row) { + $this->assertEquals($rowIndexResult++, $key); + $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row); + } + } + + public function testIteratorSeekAndPrev() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet); + $columnIndexResult = 4; + $iterator->seek(4); + $this->assertEquals($columnIndexResult, $iterator->key(), 2, 4); + + for($i = 1; $i < $columnIndexResult; $i++) { + $iterator->prev(); + $this->assertEquals($columnIndexResult - $i, $iterator->key()); + } + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testSeekOutOfRange() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); + $iterator->seek(1); + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testPrevOutOfRange() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); + $iterator->prev(); + } + +} From ceddc13f8253ec59c7ce0aca872c1eebf1f3b330 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 26 Apr 2015 13:00:58 +0100 Subject: [PATCH 326/467] Implement a ColumnIterator, refactoring of RowIterator Currently this disables the setIterateOnlyExistingCells option TODO Re-Implement setIterateOnlyExistingCells logic with the new structure TODO Rationalise and abstract common methods in the iterator classes --- Classes/PHPExcel/Worksheet.php | 12 + Classes/PHPExcel/Worksheet/CellIterator.php | 2 +- Classes/PHPExcel/Worksheet/Column.php | 90 +++++++ .../PHPExcel/Worksheet/ColumnCellIterator.php | 215 +++++++++++++++++ Classes/PHPExcel/Worksheet/ColumnIterator.php | 192 +++++++++++++++ Classes/PHPExcel/Worksheet/Row.php | 2 +- .../PHPExcel/Worksheet/RowCellIterator.php | 224 ++++++++++++++++++ Classes/PHPExcel/Worksheet/RowIterator.php | 7 +- .../PHPExcel/Worksheet/ColumnIteratorTest.php | 89 +++++++ .../PHPExcel/Worksheet/RowIteratorTest.php | 6 +- .../Worksheet/WorksheetColumnTest.php | 43 ++++ .../PHPExcel/Worksheet/WorksheetRowTest.php | 43 ++++ unitTests/phpunit.xml | 3 + 13 files changed, 922 insertions(+), 6 deletions(-) create mode 100644 Classes/PHPExcel/Worksheet/Column.php create mode 100644 Classes/PHPExcel/Worksheet/ColumnCellIterator.php create mode 100644 Classes/PHPExcel/Worksheet/ColumnIterator.php create mode 100644 Classes/PHPExcel/Worksheet/RowCellIterator.php create mode 100644 unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php create mode 100644 unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php create mode 100644 unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index bb6a22fdb..2b0b57ae4 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -2568,6 +2568,18 @@ public function getRowIterator($startRow = 1, $endRow = null) { return new PHPExcel_Worksheet_RowIterator($this, $startRow, $endRow); } + /** + * Get column iterator + * + * @param string $startColumn The column address at which to start iterating + * @param string $endColumn The column address at which to stop iterating + * + * @return PHPExcel_Worksheet_ColumnIterator + */ + public function getColumnIterator($startColumn = 'A', $endColumn = null) { + return new PHPExcel_Worksheet_ColumnIterator($this, $startColumn, $endColumn); + } + /** * Run PHPExcel garabage collector. * diff --git a/Classes/PHPExcel/Worksheet/CellIterator.php b/Classes/PHPExcel/Worksheet/CellIterator.php index 27cdc94c3..4b968167a 100644 --- a/Classes/PHPExcel/Worksheet/CellIterator.php +++ b/Classes/PHPExcel/Worksheet/CellIterator.php @@ -22,7 +22,7 @@ * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @version 1.8.0, 2014-03-02 */ diff --git a/Classes/PHPExcel/Worksheet/Column.php b/Classes/PHPExcel/Worksheet/Column.php new file mode 100644 index 000000000..a251f3960 --- /dev/null +++ b/Classes/PHPExcel/Worksheet/Column.php @@ -0,0 +1,90 @@ +_parent = $parent; + $this->_columnIndex = $columnIndex; + } + + /** + * Destructor + */ + public function __destruct() { + unset($this->_parent); + } + + /** + * Get column index + * + * @return int + */ + public function getColumnIndex() { + return $this->_columnIndex; + } + + /** + * Get cell iterator + * + * @return PHPExcel_Worksheet_CellIterator + */ + public function getCellIterator() { + return new PHPExcel_Worksheet_ColumnCellIterator($this->_parent, $this->_columnIndex); + } +} diff --git a/Classes/PHPExcel/Worksheet/ColumnCellIterator.php b/Classes/PHPExcel/Worksheet/ColumnCellIterator.php new file mode 100644 index 000000000..ac4c87a25 --- /dev/null +++ b/Classes/PHPExcel/Worksheet/ColumnCellIterator.php @@ -0,0 +1,215 @@ +_subject = $subject; + $this->_columnIndex = PHPExcel_Cell::columnIndexFromString($columnIndex) - 1; + $this->resetEnd($endRow); + $this->resetStart($startRow); + } + + /** + * Destructor + */ + public function __destruct() { + unset($this->_subject); + } + + /** + * (Re)Set the start row and the current row pointer + * + * @param integer $startRow The row number at which to start iterating + * @return PHPExcel_Worksheet_RowIterator + */ + public function resetStart($startRow = 1) { + $this->_startRow = $startRow; + $this->seek($startRow); + + return $this; + } + + /** + * (Re)Set the end row + * + * @param integer $endRow The row number at which to stop iterating + * @return PHPExcel_Worksheet_RowIterator + */ + public function resetEnd($endRow = null) { + $this->_endRow = ($endRow) ? $endRow : $this->_subject->getHighestRow(); + + return $this; + } + + /** + * Set the row pointer to the selected row + * + * @param integer $row The row number to set the current pointer at + * @return PHPExcel_Worksheet_RowIterator + * @throws PHPExcel_Exception + */ + public function seek($row = 1) { + if (($row < $this->_startRow) || ($row > $this->_endRow)) { + throw new PHPExcel_Exception("Row $row is out of range ({$this->_startRow} - {$this->_endRow})"); + } + $this->_position = $row; + + return $this; + } + + /** + * Rewind the iterator to the starting row + */ + public function rewind() { + $this->_position = $this->_startRow; + } + + /** + * Return the current row in this worksheet + * + * @return PHPExcel_Worksheet_Row + */ + public function current() { + return $this->_subject->getCellByColumnAndRow($this->_columnIndex, $this->_position); + } + + /** + * Return the current iterator key + * + * @return int + */ + public function key() { + return $this->_position; + } + + /** + * Set the iterator to its next value + */ + public function next() { + ++$this->_position; + } + + /** + * Set the iterator to its previous value + */ + public function prev() { + if ($this->_position <= $this->_startRow) { + throw new PHPExcel_Exception("Row is already at the beginning of range ({$this->_startRow} - {$this->_endRow})"); + } + + --$this->_position; + } + + /** + * Indicate if more rows exist in the worksheet range of rows that we're iterating + * + * @return boolean + */ + public function valid() { + return $this->_position <= $this->_endRow; + } + + /** + * Get loop only existing cells + * + * @return boolean + */ + public function getIterateOnlyExistingCells() { + return $this->_onlyExistingCells; + } + + /** + * Set the iterator to loop only existing cells + * + * @param boolean $value + */ + public function setIterateOnlyExistingCells($value = true) { + $this->_onlyExistingCells = $value; + } +} diff --git a/Classes/PHPExcel/Worksheet/ColumnIterator.php b/Classes/PHPExcel/Worksheet/ColumnIterator.php new file mode 100644 index 000000000..3030b3f43 --- /dev/null +++ b/Classes/PHPExcel/Worksheet/ColumnIterator.php @@ -0,0 +1,192 @@ +_subject = $subject; + $this->resetEnd($endColumn); + $this->resetStart($startColumn); + } + + /** + * Destructor + */ + public function __destruct() { + unset($this->_subject); + } + + /** + * (Re)Set the start column and the current column pointer + * + * @param integer $startColumn The column address at which to start iterating + * @return PHPExcel_Worksheet_ColumnIterator + */ + public function resetStart($startColumn = 'A') { + $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; + $this->_startColumn = $startColumnIndex; + $this->seek($startColumn); + + return $this; + } + + /** + * (Re)Set the end column + * + * @param string $endColumn The column address at which to stop iterating + * @return PHPExcel_Worksheet_ColumnIterator + */ + public function resetEnd($endColumn = null) { + $endColumn = ($endColumn) ? $endColumn : $this->_subject->getHighestColumn(); + $this->_endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; + + return $this; + } + + /** + * Set the column pointer to the selected column + * + * @param string $column The column address to set the current pointer at + * @return PHPExcel_Worksheet_ColumnIterator + * @throws PHPExcel_Exception + */ + public function seek($column = 'A') { + $column = PHPExcel_Cell::columnIndexFromString($column) - 1; + if (($column < $this->_startColumn) || ($column > $this->_endColumn)) { + throw new PHPExcel_Exception("Column $column is out of range ({$this->_startColumn} - {$this->_endColumn})"); + } + $this->_position = $column; + + return $this; + } + + /** + * Rewind the iterator to the starting column + */ + public function rewind() { + $this->_position = $this->_startColumn; + } + + /** + * Return the current column in this worksheet + * + * @return PHPExcel_Worksheet_Column + */ + public function current() { + return new PHPExcel_Worksheet_Column($this->_subject, PHPExcel_Cell::stringFromColumnIndex($this->_position)); + } + + /** + * Return the current iterator key + * + * @return string + */ + public function key() { + return PHPExcel_Cell::stringFromColumnIndex($this->_position); + } + + /** + * Set the iterator to its next value + */ + public function next() { + ++$this->_position; + } + + /** + * Set the iterator to its previous value + * + * @throws PHPExcel_Exception + */ + public function prev() { + if ($this->_position <= $this->_startColumn) { + throw new PHPExcel_Exception( + "Column is already at the beginning of range (" . + PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . " - " . + PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . ")" + ); + } + + --$this->_position; + } + + /** + * Indicate if more columns exist in the worksheet range of columns that we're iterating + * + * @return boolean + */ + public function valid() { + return $this->_position <= $this->_endColumn; + } +} diff --git a/Classes/PHPExcel/Worksheet/Row.php b/Classes/PHPExcel/Worksheet/Row.php index df16d33c2..32b63cea8 100644 --- a/Classes/PHPExcel/Worksheet/Row.php +++ b/Classes/PHPExcel/Worksheet/Row.php @@ -85,6 +85,6 @@ public function getRowIndex() { * @return PHPExcel_Worksheet_CellIterator */ public function getCellIterator() { - return new PHPExcel_Worksheet_CellIterator($this->_parent, $this->_rowIndex); + return new PHPExcel_Worksheet_RowCellIterator($this->_parent, $this->_rowIndex); } } diff --git a/Classes/PHPExcel/Worksheet/RowCellIterator.php b/Classes/PHPExcel/Worksheet/RowCellIterator.php new file mode 100644 index 000000000..048ca9d37 --- /dev/null +++ b/Classes/PHPExcel/Worksheet/RowCellIterator.php @@ -0,0 +1,224 @@ +_subject = $subject; + $this->_rowIndex = $rowIndex; + $this->resetEnd($endColumn); + $this->resetStart($startColumn); + } + + /** + * Destructor + */ + public function __destruct() { + unset($this->_subject); + } + + /** + * (Re)Set the start column and the current column pointer + * + * @param integer $startColumn The column address at which to start iterating + * @return PHPExcel_Worksheet_RowCellIterator + */ + public function resetStart($startColumn = 'A') { + $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; + $this->_startColumn = $startColumnIndex; + $this->seek($startColumn); + + return $this; + } + + /** + * (Re)Set the end column + * + * @param string $endColumn The column address at which to stop iterating + * @return PHPExcel_Worksheet_RowCellIterator + */ + public function resetEnd($endColumn = null) { + $endColumn = ($endColumn) ? $endColumn : $this->_subject->getHighestColumn(); + $this->_endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; + + return $this; + } + + /** + * Set the column pointer to the selected column + * + * @param string $column The column address to set the current pointer at + * @return PHPExcel_Worksheet_RowCellIterator + * @throws PHPExcel_Exception + */ + public function seek($column = 'A') { + $column = PHPExcel_Cell::columnIndexFromString($column) - 1; + if (($column < $this->_startColumn) || ($column > $this->_endColumn)) { + throw new PHPExcel_Exception("Column $column is out of range ({$this->_startColumn} - {$this->_endColumn})"); + } + $this->_position = $column; + + return $this; + } + + /** + * Rewind the iterator to the starting column + */ + public function rewind() { + $this->_position = $this->_startColumn; + } + + /** + * Return the current cell in this worksheet row + * + * @return PHPExcel_Cell + */ + public function current() { + return $this->_subject->getCellByColumnAndRow($this->_position, $this->_rowIndex); + } + + /** + * Return the current iterator key + * + * @return string + */ + public function key() { + return PHPExcel_Cell::stringFromColumnIndex($this->_position); + } + + /** + * Set the iterator to its next value + */ + public function next() { + ++$this->_position; + } + + /** + * Set the iterator to its previous value + * + * @throws PHPExcel_Exception + */ + public function prev() { + if ($this->_position <= $this->_startColumn) { + throw new PHPExcel_Exception( + "Column is already at the beginning of range (" . + PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . " - " . + PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . ")" + ); + } + + --$this->_position; + } + + /** + * Indicate if more columns exist in the worksheet range of columns that we're iterating + * + * @return boolean + */ + public function valid() { + return $this->_position <= $this->_endColumn; + } + + /** + * Get loop only existing cells + * + * @return boolean + */ + public function getIterateOnlyExistingCells() { + return $this->_onlyExistingCells; + } + + /** + * Set the iterator to loop only existing cells + * + * @param boolean $value + */ + public function setIterateOnlyExistingCells($value = true) { + $this->_onlyExistingCells = $value; + } +} diff --git a/Classes/PHPExcel/Worksheet/RowIterator.php b/Classes/PHPExcel/Worksheet/RowIterator.php index 295ed60e0..110d86214 100644 --- a/Classes/PHPExcel/Worksheet/RowIterator.php +++ b/Classes/PHPExcel/Worksheet/RowIterator.php @@ -92,6 +92,7 @@ public function __destruct() { * (Re)Set the start row and the current row pointer * * @param integer $startRow The row number at which to start iterating + * @return PHPExcel_Worksheet_RowIterator */ public function resetStart($startRow = 1) { $this->_startRow = $startRow; @@ -104,6 +105,7 @@ public function resetStart($startRow = 1) { * (Re)Set the end row * * @param integer $endRow The row number at which to stop iterating + * @return PHPExcel_Worksheet_RowIterator */ public function resetEnd($endRow = null) { $this->_endRow = ($endRow) ? $endRow : $this->_subject->getHighestRow(); @@ -115,13 +117,16 @@ public function resetEnd($endRow = null) { * Set the row pointer to the selected row * * @param integer $row The row number to set the current pointer at + * @return PHPExcel_Worksheet_RowIterator + * @throws PHPExcel_Exception */ public function seek($row = 1) { if (($row < $this->_startRow) || ($row > $this->_endRow)) { throw new PHPExcel_Exception("Row $row is out of range ({$this->_startRow} - {$this->_endRow})"); } - $this->_position = $row; + + return $this; } /** diff --git a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php new file mode 100644 index 000000000..4129b85c4 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php @@ -0,0 +1,89 @@ +mockColumn = $this->getMockBuilder('PHPExcel_Worksheet_Column') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet->expects($this->any()) + ->method('getHighestColumn') + ->will($this->returnValue('E')); + $this->mockWorksheet->expects($this->any()) + ->method('current') + ->will($this->returnValue($this->mockColumn)); + } + + + public function testIteratorFullRange() + { + $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet); + $columnIndexResult = 'A'; + $this->assertEquals($columnIndexResult, $iterator->key()); + + foreach($iterator as $key => $column) { + $this->assertEquals($columnIndexResult++, $key); + $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column); + } + } + + public function testIteratorStartEndRange() + { + $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D'); + $columnIndexResult = 'B'; + $this->assertEquals($columnIndexResult, $iterator->key()); + + foreach($iterator as $key => $column) { + $this->assertEquals($columnIndexResult++, $key); + $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column); + } + } + + public function testIteratorSeekAndPrev() + { + $ranges = range('A','E'); + $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D'); + $columnIndexResult = 'D'; + $iterator->seek('D'); + $this->assertEquals($columnIndexResult, $iterator->key()); + + for($i = 1; $i < array_search($columnIndexResult, $ranges); $i++) { + $iterator->prev(); + $expectedResult = $ranges[array_search($columnIndexResult, $ranges) - $i]; + $this->assertEquals($expectedResult, $iterator->key()); + } + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testSeekOutOfRange() + { + $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D'); + $iterator->seek(1); + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testPrevOutOfRange() + { + $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D'); + $iterator->prev(); + } + +} diff --git a/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php index f39f33d56..48d8b6bb1 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php @@ -55,12 +55,12 @@ public function testIteratorStartEndRange() public function testIteratorSeekAndPrev() { - $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet); + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); $columnIndexResult = 4; $iterator->seek(4); - $this->assertEquals($columnIndexResult, $iterator->key(), 2, 4); + $this->assertEquals($columnIndexResult, $iterator->key()); - for($i = 1; $i < $columnIndexResult; $i++) { + for($i = 1; $i < $columnIndexResult-1; $i++) { $iterator->prev(); $this->assertEquals($columnIndexResult - $i, $iterator->key()); } diff --git a/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php b/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php new file mode 100644 index 000000000..a867bd7d6 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php @@ -0,0 +1,43 @@ +mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') + ->disableOriginalConstructor() + ->getMock(); + } + + + public function testInstantiateColumnDefault() + { + $column = new PHPExcel_Worksheet_Column($this->mockWorksheet); + $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column); + $columnIndex = $column->getColumnIndex(); + $this->assertEquals('A', $columnIndex); + } + + public function testInstantiateColumnSpecified() + { + $column = new PHPExcel_Worksheet_Column($this->mockWorksheet, 'E'); + $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column); + $columnIndex = $column->getColumnIndex(); + $this->assertEquals('E', $columnIndex); + } + + public function testGetCellIterator() + { + $column = new PHPExcel_Worksheet_Column($this->mockWorksheet); + $cellIterator = $column->getCellIterator(); + $this->assertInstanceOf('PHPExcel_Worksheet_CellIterator', $cellIterator); + } +} diff --git a/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php b/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php new file mode 100644 index 000000000..dd80e0d5c --- /dev/null +++ b/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php @@ -0,0 +1,43 @@ +mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') + ->disableOriginalConstructor() + ->getMock(); + } + + + public function testInstantiateRowDefault() + { + $row = new PHPExcel_Worksheet_Row($this->mockWorksheet); + $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row); + $rowIndex = $row->getRowIndex(); + $this->assertEquals(1, $rowIndex); + } + + public function testInstantiateRowSpecified() + { + $row = new PHPExcel_Worksheet_Row($this->mockWorksheet, 5); + $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row); + $rowIndex = $row->getRowIndex(); + $this->assertEquals(5, $rowIndex); + } + + public function testGetCellIterator() + { + $row = new PHPExcel_Worksheet_Row($this->mockWorksheet); + $cellIterator = $row->getCellIterator(); + $this->assertInstanceOf('PHPExcel_Worksheet_CellIterator', $cellIterator); + } +} diff --git a/unitTests/phpunit.xml b/unitTests/phpunit.xml index d18d14610..d024c28f9 100644 --- a/unitTests/phpunit.xml +++ b/unitTests/phpunit.xml @@ -13,6 +13,9 @@ stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false"> + + + ./Classes From d2b0ef2ad97d1075e7794f931ff1a3f93df88b2a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 26 Apr 2015 17:37:48 +0100 Subject: [PATCH 327/467] Pass arguments from Row to RowCellIterator and from Column to ColumnCellIterator --- Classes/PHPExcel/Worksheet/Column.php | 6 ++++-- Classes/PHPExcel/Worksheet/Row.php | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/Worksheet/Column.php b/Classes/PHPExcel/Worksheet/Column.php index a251f3960..94af21357 100644 --- a/Classes/PHPExcel/Worksheet/Column.php +++ b/Classes/PHPExcel/Worksheet/Column.php @@ -82,9 +82,11 @@ public function getColumnIndex() { /** * Get cell iterator * + * @param integer $startRow The row number at which to start iterating + * @param integer $endRow Optionally, the row number at which to stop iterating * @return PHPExcel_Worksheet_CellIterator */ - public function getCellIterator() { - return new PHPExcel_Worksheet_ColumnCellIterator($this->_parent, $this->_columnIndex); + public function getCellIterator($startRow = 1, $endRow = null) { + return new PHPExcel_Worksheet_ColumnCellIterator($this->_parent, $this->_columnIndex, $startRow, $endRow); } } diff --git a/Classes/PHPExcel/Worksheet/Row.php b/Classes/PHPExcel/Worksheet/Row.php index 32b63cea8..330432790 100644 --- a/Classes/PHPExcel/Worksheet/Row.php +++ b/Classes/PHPExcel/Worksheet/Row.php @@ -82,9 +82,11 @@ public function getRowIndex() { /** * Get cell iterator * + * @param string $startColumn The column address at which to start iterating + * @param string $endColumn Optionally, the column address at which to stop iterating * @return PHPExcel_Worksheet_CellIterator */ - public function getCellIterator() { - return new PHPExcel_Worksheet_RowCellIterator($this->_parent, $this->_rowIndex); + public function getCellIterator($startColumn = 'A', $endColumn = null) { + return new PHPExcel_Worksheet_RowCellIterator($this->_parent, $this->_rowIndex, $startColumn, $endColumn); } } From f317842e2bdc59f3fce1ffb462c72d195e9703ca Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 27 Apr 2015 22:47:47 +0100 Subject: [PATCH 328/467] Unit tests for row and column iterators --- .../Worksheet/AutoFilter/ColumnTest.php | 2 +- .../Worksheet/ColumnCellIteratorTest.php | 87 ++++++++++++++++++ .../Worksheet/RowCellIteratorTest.php | 89 +++++++++++++++++++ .../Worksheet/WorksheetColumnTest.php | 7 +- .../PHPExcel/Worksheet/WorksheetRowTest.php | 5 +- 5 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/Worksheet/ColumnCellIteratorTest.php create mode 100644 unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php diff --git a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php index c8411f5e3..3c1821bad 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php @@ -1,7 +1,7 @@ mockCell = $this->getMockBuilder('PHPExcel_Cell') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet->expects($this->any()) + ->method('getHighestRow') + ->will($this->returnValue(5)); + $this->mockWorksheet->expects($this->any()) + ->method('getCellByColumnAndRow') + ->will($this->returnValue($this->mockCell)); + } + + + public function testIteratorFullRange() + { + $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A'); + $ColumnCellIndexResult = 1; + $this->assertEquals($ColumnCellIndexResult, $iterator->key()); + + foreach($iterator as $key => $ColumnCell) { + $this->assertEquals($ColumnCellIndexResult++, $key); + $this->assertInstanceOf('PHPExcel_Cell', $ColumnCell); + } + } + + public function testIteratorStartEndRange() + { + $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); + $ColumnCellIndexResult = 2; + $this->assertEquals($ColumnCellIndexResult, $iterator->key()); + + foreach($iterator as $key => $ColumnCell) { + $this->assertEquals($ColumnCellIndexResult++, $key); + $this->assertInstanceOf('PHPExcel_Cell', $ColumnCell); + } + } + + public function testIteratorSeekAndPrev() + { + $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); + $columnIndexResult = 4; + $iterator->seek(4); + $this->assertEquals($columnIndexResult, $iterator->key()); + + for($i = 1; $i < $columnIndexResult-1; $i++) { + $iterator->prev(); + $this->assertEquals($columnIndexResult - $i, $iterator->key()); + } + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testSeekOutOfRange() + { + $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); + $iterator->seek(1); + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testPrevOutOfRange() + { + $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); + $iterator->prev(); + } + +} diff --git a/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php new file mode 100644 index 000000000..cdd3c84d4 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php @@ -0,0 +1,89 @@ +mockCell = $this->getMockBuilder('PHPExcel_Cell') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet->expects($this->any()) + ->method('getHighestColumn') + ->will($this->returnValue('E')); + $this->mockWorksheet->expects($this->any()) + ->method('getCellByColumnAndRow') + ->will($this->returnValue($this->mockCell)); + } + + + public function testIteratorFullRange() + { + $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet); + $RowCellIndexResult = 'A'; + $this->assertEquals($RowCellIndexResult, $iterator->key()); + + foreach($iterator as $key => $RowCell) { + $this->assertEquals($RowCellIndexResult++, $key); + $this->assertInstanceOf('PHPExcel_Cell', $RowCell); + } + } + + public function testIteratorStartEndRange() + { + $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); + $RowCellIndexResult = 'B'; + $this->assertEquals($RowCellIndexResult, $iterator->key()); + + foreach($iterator as $key => $RowCell) { + $this->assertEquals($RowCellIndexResult++, $key); + $this->assertInstanceOf('PHPExcel_Cell', $RowCell); + } + } + + public function testIteratorSeekAndPrev() + { + $ranges = range('A','E'); + $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); + $RowCellIndexResult = 'D'; + $iterator->seek('D'); + $this->assertEquals($RowCellIndexResult, $iterator->key()); + + for($i = 1; $i < array_search($RowCellIndexResult, $ranges); $i++) { + $iterator->prev(); + $expectedResult = $ranges[array_search($RowCellIndexResult, $ranges) - $i]; + $this->assertEquals($expectedResult, $iterator->key()); + } + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testSeekOutOfRange() + { + $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); + $iterator->seek(1); + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testPrevOutOfRange() + { + $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); + $iterator->prev(); + } + +} diff --git a/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php b/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php index a867bd7d6..c70c38d36 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php @@ -1,6 +1,6 @@ mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') ->disableOriginalConstructor() ->getMock(); + $this->mockWorksheet->expects($this->any()) + ->method('getHighestRow') + ->will($this->returnValue(5)); } @@ -38,6 +41,6 @@ public function testGetCellIterator() { $column = new PHPExcel_Worksheet_Column($this->mockWorksheet); $cellIterator = $column->getCellIterator(); - $this->assertInstanceOf('PHPExcel_Worksheet_CellIterator', $cellIterator); + $this->assertInstanceOf('PHPExcel_Worksheet_ColumnCellIterator', $cellIterator); } } diff --git a/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php b/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php index dd80e0d5c..2761b52be 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php @@ -15,6 +15,9 @@ public function setUp() $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') ->disableOriginalConstructor() ->getMock(); + $this->mockWorksheet->expects($this->any()) + ->method('getHighestColumn') + ->will($this->returnValue('E')); } @@ -38,6 +41,6 @@ public function testGetCellIterator() { $row = new PHPExcel_Worksheet_Row($this->mockWorksheet); $cellIterator = $row->getCellIterator(); - $this->assertInstanceOf('PHPExcel_Worksheet_CellIterator', $cellIterator); + $this->assertInstanceOf('PHPExcel_Worksheet_RowCellIterator', $cellIterator); } } From 72f3a3b6f4e71e6a5292d9c1c6a1f982893dd2c3 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 27 Apr 2015 23:07:30 +0100 Subject: [PATCH 329/467] Fix unit test for iterator --- unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php index 4129b85c4..7d78b6179 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php @@ -74,7 +74,7 @@ public function testIteratorSeekAndPrev() public function testSeekOutOfRange() { $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D'); - $iterator->seek(1); + $iterator->seek('A'); } /** From 0ab614fd952f82f9b7a9280731daa2300e6b000c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 29 Apr 2015 00:43:04 +0100 Subject: [PATCH 330/467] Security: XML filescan in XML-based Readers to prevent XML Entity Expansion (XEE) (see http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion for an explanation of XEE injection) attacks --- Classes/PHPExcel/Reader/Abstract.php | 24 +++++++++ Classes/PHPExcel/Reader/Excel2003XML.php | 22 ++++----- Classes/PHPExcel/Reader/Excel2007.php | 62 ++++++++++++------------ Classes/PHPExcel/Reader/Gnumeric.php | 10 ++-- Classes/PHPExcel/Reader/HTML.php | 2 +- Classes/PHPExcel/Reader/OOCalc.php | 10 ++-- changelog.txt | 6 +++ 7 files changed, 83 insertions(+), 53 deletions(-) diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php index 1a6b422ff..fdbd2669c 100644 --- a/Classes/PHPExcel/Reader/Abstract.php +++ b/Classes/PHPExcel/Reader/Abstract.php @@ -227,4 +227,28 @@ public function canRead($pFilename) return $readable; } + /** + * Scan theXML for use of securityScan(file_get_contents($filestream)); + } } diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index e8abeb4af..851eaab18 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -49,14 +49,14 @@ class PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements P * * @var array */ - private $_styles = array(); + protected $_styles = array(); /** * Character set used in the file * * @var string */ - private $_charSet = 'UTF-8'; + protected $_charSet = 'UTF-8'; /** @@ -137,7 +137,7 @@ public function listWorksheetNames($pFilename) $worksheetNames = array(); - $xml = simplexml_load_string(file_get_contents($pFilename), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespaces = $xml->getNamespaces(true); $xml_ss = $xml->children($namespaces['ss']); @@ -165,7 +165,7 @@ public function listWorksheetInfo($pFilename) $worksheetInfo = array(); - $xml = simplexml_load_string(file_get_contents($pFilename), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespaces = $xml->getNamespaces(true); $worksheetID = 1; @@ -239,7 +239,7 @@ public function load($pFilename) } - private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { + protected static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { $styleAttributeValue = strtolower($styleAttributeValue); foreach($styleList as $style) { if ($styleAttributeValue == strtolower($style)) { @@ -256,7 +256,7 @@ private static function identifyFixedStyleValue($styleList,&$styleAttributeValue * @param pxs * @return */ - private static function _pixel2WidthUnits($pxs) { + protected static function _pixel2WidthUnits($pxs) { $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); $widthUnits = 256 * ($pxs / 7); @@ -270,7 +270,7 @@ private static function _pixel2WidthUnits($pxs) { * @param widthUnits * @return */ - private static function _widthUnits2Pixel($widthUnits) { + protected static function _widthUnits2Pixel($widthUnits) { $pixels = ($widthUnits / 256) * 7; $offsetWidthUnits = $widthUnits % 256; $pixels += round($offsetWidthUnits / (256 / 7)); @@ -278,7 +278,7 @@ private static function _widthUnits2Pixel($widthUnits) { } - private static function _hex2str($hex) { + protected static function _hex2str($hex) { return chr(hexdec($hex[1])); } @@ -331,7 +331,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } - $xml = simplexml_load_string(file_get_contents($pFilename), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespaces = $xml->getNamespaces(true); $docProps = $objPHPExcel->getProperties(); @@ -790,7 +790,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } - private static function _convertStringEncoding($string,$charset) { + protected static function _convertStringEncoding($string,$charset) { if ($charset != 'UTF-8') { return PHPExcel_Shared_String::ConvertEncoding($string,'UTF-8',$charset); } @@ -798,7 +798,7 @@ private static function _convertStringEncoding($string,$charset) { } - private function _parseRichText($is = '') { + protected function _parseRichText($is = '') { $value = new PHPExcel_RichText(); $value->createText(self::_convertStringEncoding($is,$this->_charSet)); diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index c3473245d..e41596afc 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -94,7 +94,7 @@ public function canRead($pFilename) $zip = new $zipClass; if ($zip->open($pFilename) === true) { // check if it is an OOXML archive - $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if ($rels !== false) { foreach ($rels->Relationship as $rel) { switch ($rel["Type"]) { @@ -136,13 +136,13 @@ public function listWorksheetNames($pFilename) // The files we're looking at here are small enough that simpleXML is more efficient than XMLReader $rels = simplexml_load_string( - $this->_getFromZipArchive($zip, "_rels/.rels", 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) + $this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($rels->Relationship as $rel) { switch ($rel["Type"]) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": $xmlWorkbook = simplexml_load_string( - $this->_getFromZipArchive($zip, "{$rel['Target']}", 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) + $this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) ); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); if ($xmlWorkbook->sheets) { @@ -180,11 +180,11 @@ public function listWorksheetInfo($pFilename) $zip = new $zipClass; $zip->open($pFilename); - $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($rels->Relationship as $rel) { if ($rel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument") { $dir = dirname($rel["Target"]); - $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); $worksheets = array(); @@ -194,7 +194,7 @@ public function listWorksheetInfo($pFilename) } } - $xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); if ($xmlWorkbook->sheets) { $dir = dirname($rel["Target"]); foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { @@ -209,7 +209,7 @@ public function listWorksheetInfo($pFilename) $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; $xml = new XMLReader(); - $res = $xml->open('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet", null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $res = $xml->xml($this->securityScanFile('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet"), null, PHPExcel_Settings::getLibXmlLoaderOptions()); $xml->setParserProperty(2,true); $currCells = 0; @@ -362,14 +362,14 @@ public function load($pFilename) $zip->open($pFilename); // Read the theme first, because we need the colour scheme when reading the styles - $wbRels = simplexml_load_string($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $wbRels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($wbRels->Relationship as $rel) { switch ($rel["Type"]) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme": $themeOrderArray = array('lt1','dk1','lt2','dk2'); $themeOrderAdditional = count($themeOrderArray); - $xmlTheme = simplexml_load_string($this->_getFromZipArchive($zip, "xl/{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xmlTheme = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "xl/{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlTheme)) { $xmlThemeName = $xmlTheme->attributes(); $xmlTheme = $xmlTheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); @@ -399,11 +399,11 @@ public function load($pFilename) } } - $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($rels->Relationship as $rel) { switch ($rel["Type"]) { case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties": - $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { $xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/"); $xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/"); @@ -422,7 +422,7 @@ public function load($pFilename) break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties": - $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { $docProps = $excel->getProperties(); if (isset($xmlCore->Company)) @@ -433,7 +433,7 @@ public function load($pFilename) break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties": - $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { $docProps = $excel->getProperties(); foreach ($xmlCore as $xmlProperty) { @@ -459,12 +459,12 @@ public function load($pFilename) break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": $dir = dirname($rel["Target"]); - $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); $sharedStrings = array(); $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']")); - $xmlStrings = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlStrings = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); if (isset($xmlStrings) && isset($xmlStrings->si)) { foreach ($xmlStrings->si as $val) { if (isset($val->t)) { @@ -503,7 +503,7 @@ public function load($pFilename) $styles = array(); $cellStyles = array(); $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); - $xmlStyles = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlStyles = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); $numFmts = null; if ($xmlStyles && $xmlStyles->numFmts[0]) { $numFmts = $xmlStyles->numFmts[0]; @@ -607,7 +607,7 @@ public function load($pFilename) } } - $xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); // Set base date if ($xmlWorkbook->workbookPr) { @@ -650,7 +650,7 @@ public function load($pFilename) // reverse $docSheet->setTitle((string) $eleSheet["name"],false); $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; - $xmlSheet = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$fileWorksheet"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlSheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$fileWorksheet")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); $sharedFormulas = array(); @@ -1239,7 +1239,7 @@ public function load($pFilename) if (!$this->_readDataOnly) { // Locate hyperlink relations if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") { $hyperlinks[(string)$ele["Id"]] = (string)$ele["Target"]; @@ -1280,7 +1280,7 @@ public function load($pFilename) if (!$this->_readDataOnly) { // Locate comment relations if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") { $comments[(string)$ele["Id"]] = (string)$ele["Target"]; @@ -1295,7 +1295,7 @@ public function load($pFilename) foreach ($comments as $relName => $relPath) { // Load comments file $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); - $commentsFile = simplexml_load_string($this->_getFromZipArchive($zip, $relPath) , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $commentsFile = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); // Utility variables $authors = array(); @@ -1317,7 +1317,7 @@ public function load($pFilename) foreach ($vmlComments as $relName => $relPath) { // Load VML comments file $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); - $vmlCommentsFile = simplexml_load_string( $this->_getFromZipArchive($zip, $relPath) , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $vmlCommentsFile = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); $shapes = $vmlCommentsFile->xpath('//v:shape'); @@ -1368,7 +1368,7 @@ public function load($pFilename) // Header/footer images if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) { if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $vmlRelationship = ''; foreach ($relsWorksheet->Relationship as $ele) { @@ -1379,7 +1379,7 @@ public function load($pFilename) if ($vmlRelationship != '') { // Fetch linked images - $relsVML = simplexml_load_string($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels' ), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsVML = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $drawings = array(); foreach ($relsVML->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { @@ -1388,7 +1388,7 @@ public function load($pFilename) } // Fetch VML document - $vmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $vmlRelationship), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $vmlDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $vmlRelationship)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); $hfImages = array(); @@ -1427,7 +1427,7 @@ public function load($pFilename) // TODO: Autoshapes from twoCellAnchors! if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $drawings = array(); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing") { @@ -1437,7 +1437,7 @@ public function load($pFilename) if ($xmlSheet->drawing && !$this->_readDataOnly) { foreach ($xmlSheet->drawing as $drawing) { $fileDrawing = $drawings[(string) self::array_item($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; - $relsDrawing = simplexml_load_string($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $images = array(); if ($relsDrawing && $relsDrawing->Relationship) { @@ -1453,7 +1453,7 @@ public function load($pFilename) } } } - $xmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $fileDrawing), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"); + $xmlDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $fileDrawing)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"); if ($xmlDrawing->oneCellAnchor) { foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) { @@ -1722,13 +1722,13 @@ public function load($pFilename) if (!$this->_readDataOnly) { - $contentTypes = simplexml_load_string($this->_getFromZipArchive($zip, "[Content_Types].xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $contentTypes = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "[Content_Types].xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); foreach ($contentTypes->Override as $contentType) { switch ($contentType["ContentType"]) { case "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": if ($this->_includeCharts) { $chartEntryRef = ltrim($contentType['PartName'],'/'); - $chartElements = simplexml_load_string($this->_getFromZipArchive($zip, $chartEntryRef), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $chartElements = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $chartEntryRef)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef,'.xml')); // echo 'Chart ',$chartEntryRef,'
'; @@ -2005,7 +2005,7 @@ private function _readRibbon($excel, $customUITarget, $zip) $dataRels = $this->_getFromZipArchive($zip, $pathRels); if ($dataRels) { // exists and not empty if the ribbon have some pictures (other than internal MSO) - $UIRels = simplexml_load_string($dataRels, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $UIRels = simplexml_load_string($this->securityScan($dataRels), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if ($UIRels) { // we need to save id and target to avoid parsing customUI.xml and "guess" if it's a pseudo callback who load the image foreach ($UIRels->Relationship as $ele) { diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index d8121495d..584ded287 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -116,8 +116,8 @@ public function listWorksheetNames($pFilename) } $xml = new XMLReader(); - $xml->open( - 'compress.zlib://'.realpath($pFilename), null, PHPExcel_Settings::getLibXmlLoaderOptions() + $xml->xml( + $this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions() ); $xml->setParserProperty(2,true); @@ -150,8 +150,8 @@ public function listWorksheetInfo($pFilename) } $xml = new XMLReader(); - $xml->open( - 'compress.zlib://'.realpath($pFilename), null, PHPExcel_Settings::getLibXmlLoaderOptions() + $xml->xml( + $this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions() ); $xml->setParserProperty(2,true); @@ -243,7 +243,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo htmlentities($gFileData,ENT_QUOTES,'UTF-8'); // echo '
'; // - $xml = simplexml_load_string($gFileData, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml = simplexml_load_string($this->securityScan($gFileData), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespacesMeta = $xml->getNamespaces(true); // var_dump($namespacesMeta); diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 508672ce4..fa762e6b4 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -475,7 +475,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Create a new DOM object $dom = new domDocument; // Reload the HTML file into the DOM object - $loaded = $dom->loadHTMLFile($pFilename); + $loaded = $dom->loadHTML($this->securityScanFile($pFilename)); if ($loaded === FALSE) { throw new PHPExcel_Reader_Exception('Failed to load ', $pFilename, ' as a DOM Document'); } diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 4ffed2b3b..7644df941 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -90,7 +90,7 @@ public function canRead($pFilename) if ($stat && ($stat['size'] <= 255)) { $mimeType = $zip->getFromName($stat['name']); } elseif($stat = $zip->statName('META-INF/manifest.xml')) { - $xml = simplexml_load_string($zip->getFromName('META-INF/manifest.xml'), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml = simplexml_load_string($this->securityScan($zip->getFromName('META-INF/manifest.xml')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespacesContent = $xml->getNamespaces(true); if (isset($namespacesContent['manifest'])) { $manifest = $xml->children($namespacesContent['manifest']); @@ -136,7 +136,7 @@ public function listWorksheetNames($pFilename) $worksheetNames = array(); $xml = new XMLReader(); - $res = $xml->open('zip://'.realpath($pFilename).'#content.xml', null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions()); $xml->setParserProperty(2,true); // Step into the first level of content of the XML @@ -188,7 +188,7 @@ public function listWorksheetInfo($pFilename) } $xml = new XMLReader(); - $res = $xml->open('zip://'.realpath($pFilename).'#content.xml', null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions()); $xml->setParserProperty(2,true); // Step into the first level of content of the XML @@ -345,7 +345,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } // echo '

Meta Information

'; - $xml = simplexml_load_string($zip->getFromName("meta.xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml = simplexml_load_string($this->securityScan($zip->getFromName("meta.xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespacesMeta = $xml->getNamespaces(true); // echo '
';
 //		print_r($namespacesMeta);
@@ -431,7 +431,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
 
 
 //		echo '

Workbook Content

'; - $xml = simplexml_load_string($zip->getFromName("content.xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml = simplexml_load_string($this->securityScan($zip->getFromName("content.xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespacesContent = $xml->getNamespaces(true); // echo '
';
 //		print_r($namespacesContent);
diff --git a/changelog.txt b/changelog.txt
index 04a0ed559..0d9b937f1 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -52,6 +52,12 @@ Planned for v1.8.1
 - Feature:  (MBaker)                            - New methods added for testing cell status within merge groups
 - Feature:  (cifren/MBaker)   Work Item GH-205  - Handling merge cells in HTML Reader
 - Feature:  (MBaker)                            - Helper to convert basic HTML markup to a Rich Text object
+- Feature:  (MBaker)                            - Improved Iterators
+                                                    New Column Iterator
+                                                    Support for row and column ranges
+                                                    Improved handling for next/prev
+- Security: (MBaker)                            - XML filescan in XML-based Readers to prevent XML Entity Expansion (XEE)
+                                                    (see http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion for an explanation of XEE injection) attacks
 
 
 2014-03-02 (v1.8.0):

From bc7028ae4e72643a6feae86325ba44fc14364484 Mon Sep 17 00:00:00 2001
From: MarkBaker 
Date: Wed, 29 Apr 2015 22:23:14 +0100
Subject: [PATCH 331/467] Modified XEE security scan to handle UTF-16 charset,
 and added unit tests for the security scan

---
 Classes/PHPExcel/Reader/Abstract.php          |   3 +-
 .../PHPExcel/Reader/XEEValidatorTest.php      |  55 ++++++++++++++++++
 .../Reader/XEETestInvalidUTF-16.xml           | Bin 0 -> 276 bytes
 .../Reader/XEETestInvalidUTF-16BE.xml         | Bin 0 -> 278 bytes
 .../Reader/XEETestInvalidUTF-16LE.xml         | Bin 0 -> 278 bytes
 .../Reader/XEETestInvalidUTF-8.xml            |   8 +++
 .../rawTestData/Reader/XEETestValidUTF-16.xml | Bin 0 -> 176 bytes
 .../Reader/XEETestValidUTF-16BE.xml           | Bin 0 -> 178 bytes
 .../Reader/XEETestValidUTF-16LE.xml           | Bin 0 -> 178 bytes
 .../rawTestData/Reader/XEETestValidUTF-8.xml  |   4 ++
 10 files changed, 69 insertions(+), 1 deletion(-)
 create mode 100644 unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php
 create mode 100644 unitTests/rawTestData/Reader/XEETestInvalidUTF-16.xml
 create mode 100644 unitTests/rawTestData/Reader/XEETestInvalidUTF-16BE.xml
 create mode 100644 unitTests/rawTestData/Reader/XEETestInvalidUTF-16LE.xml
 create mode 100644 unitTests/rawTestData/Reader/XEETestInvalidUTF-8.xml
 create mode 100644 unitTests/rawTestData/Reader/XEETestValidUTF-16.xml
 create mode 100644 unitTests/rawTestData/Reader/XEETestValidUTF-16BE.xml
 create mode 100644 unitTests/rawTestData/Reader/XEETestValidUTF-16LE.xml
 create mode 100644 unitTests/rawTestData/Reader/XEETestValidUTF-8.xml

diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php
index fdbd2669c..0036dff9a 100644
--- a/Classes/PHPExcel/Reader/Abstract.php
+++ b/Classes/PHPExcel/Reader/Abstract.php
@@ -235,7 +235,8 @@ public function canRead($pFilename)
 	 */
 	public function securityScan($xml)
 	{
-        if (strpos($xml, 'getMockForAbstractClass('PHPExcel_Reader_Abstract');
+        $expectedResult = 'FAILURE: Should throw an Exception rather than return a value';
+		$result = $reader->securityScanFile($filename);
+		$this->assertEquals($expectedResult, $result);
+	}
+
+    public function providerInvalidXML()
+    {
+        $tests = [];
+        foreach(glob('rawTestData/Reader/XEETestInvalid*.xml') as $file) {
+            $tests[] = [realpath($file), true];
+        }
+        return $tests;
+	}
+
+    /**
+     * @dataProvider providerValidXML
+     */
+	public function testValidXML($filename, $expectedResult)
+	{
+        $reader = $this->getMockForAbstractClass('PHPExcel_Reader_Abstract');
+		$result = $reader->securityScanFile($filename);
+		$this->assertEquals($expectedResult, $result);
+	}
+
+    public function providerValidXML()
+    {
+        $tests = [];
+        foreach(glob('rawTestData/Reader/XEETestValid*.xml') as $file) {
+            $tests[] = [realpath($file), file_get_contents($file)];
+        }
+        return $tests;
+	}
+
+}
diff --git a/unitTests/rawTestData/Reader/XEETestInvalidUTF-16.xml b/unitTests/rawTestData/Reader/XEETestInvalidUTF-16.xml
new file mode 100644
index 0000000000000000000000000000000000000000..94eaedfc2aec6c1eb2e723c914acf0afcdbbfd65
GIT binary patch
literal 276
zcmX|*O%K697=)iIiT|*A5Dut|gO57+NL-NMAmSj}h@{#?MfmfW?v`w_?`G$jnfLu+
zz=$VTVhj%=Ze(0YNf_eMp@pw$q$Hg5A4*L)TXoBZ8BI}L%VgX+N)2_#HY2j!OYTg>
zh=2-Zbyk_MWGw%V6;tKk#HaEb_Lebvxs%gV7Gmd?H`>>i<|!j(t?5z^#dHn7Jg1eE
VobPa_Cug0S&FIr8_G$n7gD--qCxrk2

literal 0
HcmV?d00001

diff --git a/unitTests/rawTestData/Reader/XEETestInvalidUTF-16BE.xml b/unitTests/rawTestData/Reader/XEETestInvalidUTF-16BE.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1d186ff443435bec745501c2d7bfc81271e4c3c5
GIT binary patch
literal 278
zcmX|*!4APd6h+UL#6JuRVS(CMP;G)rY>;3fVjOWMPaI@)wJxh9`M$8B-myvT35$cYuC$j8EhD?Ny
zM}s;pO%`mJ%W-6@Zll?$POjI+J3Go+a-{53OY6C+<%FNF%xW?h
UJLHVj*`aM66S~ztga3T*3-^U44*&oF

literal 0
HcmV?d00001

diff --git a/unitTests/rawTestData/Reader/XEETestInvalidUTF-16LE.xml b/unitTests/rawTestData/Reader/XEETestInvalidUTF-16LE.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c3913f71bb84e44fb3659848c69c0434945a2642
GIT binary patch
literal 278
zcmX|*!4APd6h+UL#6JuRVS(CMQ0;f@4L_Ep3laer{#gIOZs!@_~)qkio;bzkVdlvLWjaU&_E+gk6BGesQPh{DT44DWY
zj|O#In#|cSljF!%-A1!hom{VzWsF|sDd>Q;*rnx-c6OAt
+
+]>
+
+
+	test: (&x0;)
+
\ No newline at end of file
diff --git a/unitTests/rawTestData/Reader/XEETestValidUTF-16.xml b/unitTests/rawTestData/Reader/XEETestValidUTF-16.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6473fe6b6382c7f6993f3c9f0187bd0636613a98
GIT binary patch
literal 176
zcmYL?I}Ug^iD-dB
+
+	test: Valid
+
\ No newline at end of file

From 75bb9d7edad717a339300d6b4323dcc3939c27e5 Mon Sep 17 00:00:00 2001
From: MarkBaker 
Date: Wed, 29 Apr 2015 22:41:54 +0100
Subject: [PATCH 332/467] Fix regexp for XEE validation

---
 Classes/PHPExcel/Reader/Abstract.php |  2 +-
 Classes/PHPExcel/Reader/HTML.php     | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php
index 0036dff9a..2d3c964b6 100644
--- a/Classes/PHPExcel/Reader/Abstract.php
+++ b/Classes/PHPExcel/Reader/Abstract.php
@@ -235,7 +235,7 @@ public function canRead($pFilename)
 	 */
 	public function securityScan($xml)
 	{
-        $pattern = '/\0?<\0?!\0?E\0?N\0?T\0?I\0?T\0?Y\0?/';
+        $pattern = '/\\0?' . implode('\\0?', str_split('
Date: Thu, 30 Apr 2015 19:07:49 +0100
Subject: [PATCH 333/467] Rework of Iterators for existing cells only

---
 Classes/PHPExcel/Worksheet/CellIterator.php   | 101 ++++--------------
 .../PHPExcel/Worksheet/ColumnCellIterator.php |  88 +++++++--------
 .../PHPExcel/Worksheet/RowCellIterator.php    |  80 +++++++-------
 changelog.txt                                 |   3 +-
 4 files changed, 104 insertions(+), 168 deletions(-)

diff --git a/Classes/PHPExcel/Worksheet/CellIterator.php b/Classes/PHPExcel/Worksheet/CellIterator.php
index 4b968167a..77c5d2e31 100644
--- a/Classes/PHPExcel/Worksheet/CellIterator.php
+++ b/Classes/PHPExcel/Worksheet/CellIterator.php
@@ -35,47 +35,28 @@
  * @package    PHPExcel_Worksheet
  * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
-class PHPExcel_Worksheet_CellIterator implements Iterator
+abstract class PHPExcel_Worksheet_CellIterator
 {
 	/**
 	 * PHPExcel_Worksheet to iterate
 	 *
 	 * @var PHPExcel_Worksheet
 	 */
-	private $_subject;
-
-	/**
-	 * Row index
-	 *
-	 * @var int
-	 */
-	private $_rowIndex;
+	protected $_subject;
 
 	/**
 	 * Current iterator position
 	 *
-	 * @var int
+	 * @var mixed
 	 */
-	private $_position = 0;
+	protected $_position = null;
 
 	/**
-	 * Loop only existing cells
+	 * Iterate only existing cells
 	 *
 	 * @var boolean
 	 */
-	private $_onlyExistingCells = true;
-
-	/**
-	 * Create a new cell iterator
-	 *
-	 * @param PHPExcel_Worksheet 		$subject
-	 * @param int						$rowIndex
-	 */
-	public function __construct(PHPExcel_Worksheet $subject = null, $rowIndex = 1) {
-		// Set subject and row index
-		$this->_subject 	= $subject;
-		$this->_rowIndex 	= $rowIndex;
-	}
+	protected $_onlyExistingCells = false;
 
 	/**
 	 * Destructor
@@ -84,63 +65,6 @@ public function __destruct() {
 		unset($this->_subject);
 	}
 
-	/**
-	 * Rewind iterator
-	 */
-    public function rewind() {
-        $this->_position = 0;
-    }
-
-    /**
-     * Current PHPExcel_Cell
-     *
-     * @return PHPExcel_Cell
-     */
-    public function current() {
-		return $this->_subject->getCellByColumnAndRow($this->_position, $this->_rowIndex);
-    }
-
-    /**
-     * Current key
-     *
-     * @return int
-     */
-    public function key() {
-        return $this->_position;
-    }
-
-    /**
-     * Next value
-     */
-    public function next() {
-        ++$this->_position;
-    }
-
-    /**
-     * Are there any more PHPExcel_Cell instances available?
-     *
-     * @return boolean
-     */
-    public function valid() {
-        // columnIndexFromString() returns an index based at one,
-        // treat it as a count when comparing it to the base zero
-        // position.
-        $columnCount = PHPExcel_Cell::columnIndexFromString($this->_subject->getHighestColumn());
-
-        if ($this->_onlyExistingCells) {
-            // If we aren't looking at an existing cell, either
-            // because the first column doesn't exist or next() has
-            // been called onto a nonexistent cell, then loop until we
-            // find one, or pass the last column.
-            while ($this->_position < $columnCount &&
-                   !$this->_subject->cellExistsByColumnAndRow($this->_position, $this->_rowIndex)) {
-                ++$this->_position;
-            }
-        }
-
-        return $this->_position < $columnCount;
-    }
-
 	/**
 	 * Get loop only existing cells
 	 *
@@ -150,12 +74,23 @@ public function getIterateOnlyExistingCells() {
     	return $this->_onlyExistingCells;
     }
 
+	/**
+	 * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary
+	 *
+     * @throws PHPExcel_Exception
+	 */
+    abstract protected function adjustForExistingOnlyRange() {
+    }
+
 	/**
 	 * Set the iterator to loop only existing cells
 	 *
 	 * @param	boolean		$value
+     * @throws PHPExcel_Exception
 	 */
     public function setIterateOnlyExistingCells($value = true) {
-    	$this->_onlyExistingCells = $value;
+    	$this->_onlyExistingCells = (boolean) $value;
+
+        $this->adjustForExistingOnlyRange();
     }
 }
diff --git a/Classes/PHPExcel/Worksheet/ColumnCellIterator.php b/Classes/PHPExcel/Worksheet/ColumnCellIterator.php
index ac4c87a25..a9ef49f00 100644
--- a/Classes/PHPExcel/Worksheet/ColumnCellIterator.php
+++ b/Classes/PHPExcel/Worksheet/ColumnCellIterator.php
@@ -35,49 +35,28 @@
  * @package	PHPExcel_Worksheet
  * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
-class PHPExcel_Worksheet_ColumnCellIterator implements Iterator
+class PHPExcel_Worksheet_ColumnCellIterator extends PHPExcel_Worksheet_CellIterator implements Iterator
 {
-	/**
-	 * PHPExcel_Worksheet to iterate
-	 *
-	 * @var PHPExcel_Worksheet
-	 */
-	private $_subject;
-
 	/**
 	 * Column index
 	 *
 	 * @var string
 	 */
-	private $_columnIndex;
-
-	/**
-	 * Current iterator position
-	 *
-	 * @var int
-	 */
-	private $_position = 1;
+	protected $_columnIndex;
 
-	/**
+    /**
 	 * Start position
 	 *
 	 * @var int
 	 */
-	private $_startRow = 1;
+	protected $_startRow = 1;
 
 	/**
 	 * End position
 	 *
 	 * @var int
 	 */
-	private $_endRow = 1;
-
-	/**
-	 * Loop only existing cells
-	 *
-	 * @var boolean
-	 */
-	private $_onlyExistingCells = true;
+	protected $_endRow = 1;
 
 	/**
 	 * Create a new row iterator
@@ -106,10 +85,12 @@ public function __destruct() {
 	 * (Re)Set the start row and the current row pointer
 	 *
 	 * @param integer	$startRow	The row number at which to start iterating
-     * @return PHPExcel_Worksheet_RowIterator
+     * @return PHPExcel_Worksheet_ColumnCellIterator
+     * @throws PHPExcel_Exception
 	 */
 	public function resetStart($startRow = 1) {
 		$this->_startRow = $startRow;
+        $this->adjustForExistingOnlyRange();
 		$this->seek($startRow);
 
         return $this;
@@ -119,10 +100,12 @@ public function resetStart($startRow = 1) {
 	 * (Re)Set the end row
 	 *
 	 * @param integer	$endRow	The row number at which to stop iterating
-     * @return PHPExcel_Worksheet_RowIterator
+     * @return PHPExcel_Worksheet_ColumnCellIterator
+     * @throws PHPExcel_Exception
 	 */
 	public function resetEnd($endRow = null) {
 		$this->_endRow = ($endRow) ? $endRow : $this->_subject->getHighestRow();
+        $this->adjustForExistingOnlyRange();
 
         return $this;
 	}
@@ -131,12 +114,14 @@ public function resetEnd($endRow = null) {
 	 * Set the row pointer to the selected row
 	 *
 	 * @param integer	$row	The row number to set the current pointer at
-     * @return PHPExcel_Worksheet_RowIterator
+     * @return PHPExcel_Worksheet_ColumnCellIterator
      * @throws PHPExcel_Exception
 	 */
 	public function seek($row = 1) {
         if (($row < $this->_startRow) || ($row > $this->_endRow)) {
             throw new PHPExcel_Exception("Row $row is out of range ({$this->_startRow} - {$this->_endRow})");
+        } elseif ($this->_onlyExistingCells && !($this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $row))) {
+            throw new PHPExcel_Exception('In "IterateOnlyExistingCells" mode and Cell does not exist');
         }
 		$this->_position = $row;
 
@@ -151,7 +136,7 @@ public function rewind() {
 	}
 
 	/**
-	 * Return the current row in this worksheet
+	 * Return the current cell in this worksheet column
 	 *
 	 * @return PHPExcel_Worksheet_Row
 	 */
@@ -172,7 +157,11 @@ public function key() {
 	 * Set the iterator to its next value
 	 */
 	public function next() {
-		++$this->_position;
+        do {
+            ++$this->_position;
+        } while (($this->_onlyExistingCells) &&
+            (!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_position)) &&
+            ($this->_position <= $this->_endRow));
 	}
 
 	/**
@@ -183,7 +172,11 @@ public function prev() {
             throw new PHPExcel_Exception("Row is already at the beginning of range ({$this->_startRow} - {$this->_endRow})");
         }
 
-        --$this->_position;
+        do {
+            --$this->_position;
+        } while (($this->_onlyExistingCells) &&
+            (!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_position)) &&
+            ($this->_position >= $this->_startRow));
 	}
 
 	/**
@@ -196,20 +189,27 @@ public function valid() {
 	}
 
 	/**
-	 * Get loop only existing cells
+	 * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary
 	 *
-	 * @return boolean
+     * @throws PHPExcel_Exception
 	 */
-    public function getIterateOnlyExistingCells() {
-    	return $this->_onlyExistingCells;
+    protected function adjustForExistingOnlyRange() {
+        if ($this->_onlyExistingCells) {
+            while ((!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_startRow)) &&
+                ($this->_startRow <= $this->_endRow)) {
+                ++$this->_startRow;
+            }
+            if ($this->_startRow > $this->_endRow) {
+                throw new PHPExcel_Exception('No cells exist within the specified range');
+            }
+            while ((!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_endRow)) &&
+                ($this->_endRow >= $this->_startRow)) {
+                --$this->_endRow;
+            }
+            if ($this->_endRow < $this->_startRow) {
+                throw new PHPExcel_Exception('No cells exist within the specified range');
+            }
+        }
     }
 
-	/**
-	 * Set the iterator to loop only existing cells
-	 *
-	 * @param	boolean		$value
-	 */
-    public function setIterateOnlyExistingCells($value = true) {
-    	$this->_onlyExistingCells = $value;
-    }
 }
diff --git a/Classes/PHPExcel/Worksheet/RowCellIterator.php b/Classes/PHPExcel/Worksheet/RowCellIterator.php
index 048ca9d37..96c6b419c 100644
--- a/Classes/PHPExcel/Worksheet/RowCellIterator.php
+++ b/Classes/PHPExcel/Worksheet/RowCellIterator.php
@@ -35,49 +35,28 @@
  * @package	PHPExcel_Worksheet
  * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
-class PHPExcel_Worksheet_RowCellIterator implements Iterator
+class PHPExcel_Worksheet_RowCellIterator extends PHPExcel_Worksheet_CellIterator implements Iterator
 {
-	/**
-	 * PHPExcel_Worksheet to iterate in
-	 *
-	 * @var PHPExcel_Worksheet
-	 */
-	private $_subject;
-
 	/**
 	 * Row index
 	 *
 	 * @var int
 	 */
-	private $_rowIndex;
-
-	/**
-	 * Current iterator position
-	 *
-	 * @var int
-	 */
-	private $_position = 0;
+	protected $_rowIndex;
 
 	/**
 	 * Start position
 	 *
 	 * @var int
 	 */
-	private $_startColumn = 0;
+	protected $_startColumn = 0;
 
 	/**
 	 * End position
 	 *
 	 * @var int
 	 */
-	private $_endColumn = 0;
-
-	/**
-	 * Loop only existing cells
-	 *
-	 * @var boolean
-	 */
-	private $_onlyExistingCells = true;
+	protected $_endColumn = 0;
 
 	/**
 	 * Create a new column iterator
@@ -107,11 +86,13 @@ public function __destruct() {
 	 *
 	 * @param integer	$startColumn	The column address at which to start iterating
      * @return PHPExcel_Worksheet_RowCellIterator
+     * @throws PHPExcel_Exception
 	 */
 	public function resetStart($startColumn = 'A') {
         $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1;
 		$this->_startColumn = $startColumnIndex;
-		$this->seek($startColumn);
+        $this->adjustForExistingOnlyRange();
+		$this->seek(PHPExcel_Cell::stringFromColumnIndex($this->_startColumn));
 
         return $this;
 	}
@@ -121,10 +102,12 @@ public function resetStart($startColumn = 'A') {
 	 *
 	 * @param string	$endColumn	The column address at which to stop iterating
      * @return PHPExcel_Worksheet_RowCellIterator
+     * @throws PHPExcel_Exception
 	 */
 	public function resetEnd($endColumn = null) {
 		$endColumn = ($endColumn) ? $endColumn : $this->_subject->getHighestColumn();
 		$this->_endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1;
+        $this->adjustForExistingOnlyRange();
 
         return $this;
 	}
@@ -140,6 +123,8 @@ public function seek($column = 'A') {
         $column = PHPExcel_Cell::columnIndexFromString($column) - 1;
         if (($column < $this->_startColumn) || ($column > $this->_endColumn)) {
             throw new PHPExcel_Exception("Column $column is out of range ({$this->_startColumn} - {$this->_endColumn})");
+        } elseif ($this->_onlyExistingCells && !($this->_subject->cellExistsByColumnAndRow($column, $this->_rowIndex))) {
+            throw new PHPExcel_Exception('In "IterateOnlyExistingCells" mode and Cell does not exist');
         }
 		$this->_position = $column;
 
@@ -175,7 +160,11 @@ public function key() {
 	 * Set the iterator to its next value
 	 */
 	public function next() {
-		++$this->_position;
+        do {
+            ++$this->_position;
+        } while (($this->_onlyExistingCells) &&
+            (!$this->_subject->cellExistsByColumnAndRow($this->_position, $this->_rowIndex)) &&
+            ($this->_position <= $this->_endColumn));
 	}
 
 	/**
@@ -192,7 +181,11 @@ public function prev() {
             );
         }
 
-        --$this->_position;
+        do {
+            --$this->_position;
+        } while (($this->_onlyExistingCells) &&
+            (!$this->_subject->cellExistsByColumnAndRow($this->_position, $this->_rowIndex)) &&
+            ($this->_position >= $this->_startColumn));
 	}
 
 	/**
@@ -205,20 +198,27 @@ public function valid() {
 	}
 
 	/**
-	 * Get loop only existing cells
+	 * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary
 	 *
-	 * @return boolean
+     * @throws PHPExcel_Exception
 	 */
-    public function getIterateOnlyExistingCells() {
-    	return $this->_onlyExistingCells;
+    protected function adjustForExistingOnlyRange() {
+        if ($this->_onlyExistingCells) {
+            while ((!$this->_subject->cellExistsByColumnAndRow($this->_startColumn, $this->_rowIndex)) &&
+                ($this->_startColumn <= $this->_endColumn)) {
+                ++$this->_startColumn;
+            }
+            if ($this->_startColumn > $this->_endColumn) {
+                throw new PHPExcel_Exception('No cells exist within the specified range');
+            }
+            while ((!$this->_subject->cellExistsByColumnAndRow($this->_endColumn, $this->_rowIndex)) &&
+                ($this->_endColumn >= $this->_startColumn)) {
+                --$this->_endColumn;
+            }
+            if ($this->_endColumn < $this->_startColumn) {
+                throw new PHPExcel_Exception('No cells exist within the specified range');
+            }
+        }
     }
 
-	/**
-	 * Set the iterator to loop only existing cells
-	 *
-	 * @param	boolean		$value
-	 */
-    public function setIterateOnlyExistingCells($value = true) {
-    	$this->_onlyExistingCells = $value;
-    }
 }
diff --git a/changelog.txt b/changelog.txt
index 0d9b937f1..3220049a7 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -58,9 +58,10 @@ Planned for v1.8.1
                                                     Improved handling for next/prev
 - Security: (MBaker)                            - XML filescan in XML-based Readers to prevent XML Entity Expansion (XEE)
                                                     (see http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion for an explanation of XEE injection) attacks
+                                                  Reference CVE-2015-3542 - Identification of problem courtesy of Dawid Golunski (Pentest Ltd.)
 
 
-2014-03-02 (v1.8.0):
+                                                  2014-03-02 (v1.8.0):
 - Bugfix:   (MBaker)          Work item CP19830 - Undefined variable: fileHandle in CSV Reader
 - Bugfix:   (MBaker)          Work item CP19968 - Out of memory in style/supervisor.php
 - Bugfix:   (MBaker)                            - Style error with merged cells in PDF Writer

From 2b6380693d766c28f316559325126e64b0da92f3 Mon Sep 17 00:00:00 2001
From: MarkBaker 
Date: Thu, 30 Apr 2015 23:54:21 +0100
Subject: [PATCH 334/467] change log

---
 changelog.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/changelog.txt b/changelog.txt
index 3220049a7..29377308d 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -19,10 +19,10 @@
 *
 * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
-* @version    ##VERSION##, ##DATE##
+* @version    1.8.1, 2015-04-30
 **************************************************************************************
 
-Planned for v1.8.1
+2015-04-30 (v1.8.1):
 - Bugfix:   (goncons)         Work Item GH-397  - Fix for Writing an Open Document cell with non-numeric formula
 - Bugfix:   (sarciszewski)    Work Item GH-329  - Avoid potential divide by zero in basedrawing
 - Bugfix:   (ymaerschalck)    Work Item GH-405  - XML External Entity (XXE) Processing, different behaviour between simplexml_load_string() and simplexml_load_file().

From c9cb4d4286f2cac15887c90170e023148b591c9f Mon Sep 17 00:00:00 2001
From: MarkBaker 
Date: Fri, 1 May 2015 08:06:07 +0100
Subject: [PATCH 335/467] Abstract function
 PHPExcel_Worksheet_CellIterator::adjustForExistingOnlyRange() cannot contain
 body

---
 Classes/PHPExcel/Worksheet/CellIterator.php | 3 +--
 changelog.txt                               | 6 +++++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Classes/PHPExcel/Worksheet/CellIterator.php b/Classes/PHPExcel/Worksheet/CellIterator.php
index 77c5d2e31..239cb4ff1 100644
--- a/Classes/PHPExcel/Worksheet/CellIterator.php
+++ b/Classes/PHPExcel/Worksheet/CellIterator.php
@@ -79,8 +79,7 @@ public function getIterateOnlyExistingCells() {
 	 *
      * @throws PHPExcel_Exception
 	 */
-    abstract protected function adjustForExistingOnlyRange() {
-    }
+    abstract protected function adjustForExistingOnlyRange();
 
 	/**
 	 * Set the iterator to loop only existing cells
diff --git a/changelog.txt b/changelog.txt
index 29377308d..7d988cbe7 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -19,9 +19,13 @@
 *
 * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
-* @version    1.8.1, 2015-04-30
+* @version    ##VERSION##, ##DATE##
 **************************************************************************************
 
+
+Planned for 1.8.2
+
+
 2015-04-30 (v1.8.1):
 - Bugfix:   (goncons)         Work Item GH-397  - Fix for Writing an Open Document cell with non-numeric formula
 - Bugfix:   (sarciszewski)    Work Item GH-329  - Avoid potential divide by zero in basedrawing

From fca778225c01d699c69afccb482310933499aac2 Mon Sep 17 00:00:00 2001
From: MarkBaker 
Date: Sat, 2 May 2015 23:50:37 +0100
Subject: [PATCH 336/467] Ajust copyright to 2015

---
 Classes/PHPExcel.php                          |   6 +-
 Classes/PHPExcel/Autoloader.php               |   6 +-
 Classes/PHPExcel/CachedObjectStorage/APC.php  |   6 +-
 .../CachedObjectStorage/CacheBase.php         |   6 +-
 .../PHPExcel/CachedObjectStorage/DiscISAM.php |   6 +-
 .../PHPExcel/CachedObjectStorage/ICache.php   |   6 +-
 .../PHPExcel/CachedObjectStorage/Igbinary.php |   6 +-
 .../PHPExcel/CachedObjectStorage/Memcache.php |   6 +-
 .../PHPExcel/CachedObjectStorage/Memory.php   |   6 +-
 .../CachedObjectStorage/MemoryGZip.php        |   6 +-
 .../CachedObjectStorage/MemorySerialized.php  |   6 +-
 .../PHPExcel/CachedObjectStorage/PHPTemp.php  |   6 +-
 .../PHPExcel/CachedObjectStorage/SQLite.php   |   6 +-
 .../PHPExcel/CachedObjectStorage/SQLite3.php  |   6 +-
 .../PHPExcel/CachedObjectStorage/Wincache.php |   6 +-
 .../PHPExcel/CachedObjectStorageFactory.php   |   6 +-
 .../CalcEngine/CyclicReferenceStack.php       |   6 +-
 Classes/PHPExcel/CalcEngine/Logger.php        |   6 +-
 Classes/PHPExcel/Calculation.php              |   6 +-
 Classes/PHPExcel/Calculation/Database.php     |   6 +-
 Classes/PHPExcel/Calculation/DateTime.php     |   6 +-
 Classes/PHPExcel/Calculation/Engineering.php  |   6 +-
 Classes/PHPExcel/Calculation/Exception.php    |   6 +-
 .../PHPExcel/Calculation/ExceptionHandler.php |   6 +-
 Classes/PHPExcel/Calculation/Financial.php    |   6 +-
 .../PHPExcel/Calculation/FormulaParser.php    |   6 +-
 Classes/PHPExcel/Calculation/FormulaToken.php |   6 +-
 Classes/PHPExcel/Calculation/Function.php     |   6 +-
 Classes/PHPExcel/Calculation/Functions.php    |   6 +-
 Classes/PHPExcel/Calculation/Logical.php      |   6 +-
 Classes/PHPExcel/Calculation/LookupRef.php    |   6 +-
 Classes/PHPExcel/Calculation/MathTrig.php     |   6 +-
 Classes/PHPExcel/Calculation/Statistical.php  |   6 +-
 Classes/PHPExcel/Calculation/TextData.php     |   6 +-
 Classes/PHPExcel/Calculation/Token/Stack.php  |   6 +-
 Classes/PHPExcel/Cell.php                     |   6 +-
 Classes/PHPExcel/Cell/AdvancedValueBinder.php |   6 +-
 Classes/PHPExcel/Cell/DataType.php            |   6 +-
 Classes/PHPExcel/Cell/DataValidation.php      |   6 +-
 Classes/PHPExcel/Cell/DefaultValueBinder.php  |   6 +-
 Classes/PHPExcel/Cell/Hyperlink.php           |   6 +-
 Classes/PHPExcel/Cell/IValueBinder.php        |   6 +-
 Classes/PHPExcel/Chart.php                    |   6 +-
 Classes/PHPExcel/Chart/Axis.php               | 503 +++++++++---------
 Classes/PHPExcel/Chart/DataSeries.php         |   6 +-
 Classes/PHPExcel/Chart/DataSeriesValues.php   |   6 +-
 Classes/PHPExcel/Chart/Exception.php          |   6 +-
 Classes/PHPExcel/Chart/GridLines.php          | 176 +++---
 Classes/PHPExcel/Chart/Layout.php             |   6 +-
 Classes/PHPExcel/Chart/Legend.php             |   6 +-
 Classes/PHPExcel/Chart/PlotArea.php           |   6 +-
 Classes/PHPExcel/Chart/Properties.php         |   3 +-
 Classes/PHPExcel/Chart/Renderer/jpgraph.php   |   6 +-
 Classes/PHPExcel/Chart/Title.php              |   6 +-
 Classes/PHPExcel/Comment.php                  |   6 +-
 Classes/PHPExcel/DocumentProperties.php       |   6 +-
 Classes/PHPExcel/DocumentSecurity.php         |   6 +-
 Classes/PHPExcel/Exception.php                |   6 +-
 Classes/PHPExcel/HashTable.php                |   6 +-
 Classes/PHPExcel/IComparable.php              |   4 +-
 Classes/PHPExcel/IOFactory.php                |   6 +-
 Classes/PHPExcel/NamedRange.php               |   6 +-
 Classes/PHPExcel/Reader/Abstract.php          |   6 +-
 Classes/PHPExcel/Reader/CSV.php               |   6 +-
 Classes/PHPExcel/Reader/DefaultReadFilter.php |   6 +-
 Classes/PHPExcel/Reader/Excel2003XML.php      |   6 +-
 Classes/PHPExcel/Reader/Excel2007.php         |   6 +-
 Classes/PHPExcel/Reader/Excel2007/Chart.php   |   6 +-
 Classes/PHPExcel/Reader/Excel2007/Theme.php   |   6 +-
 Classes/PHPExcel/Reader/Excel5.php            |   6 +-
 Classes/PHPExcel/Reader/Excel5/Escher.php     |   6 +-
 Classes/PHPExcel/Reader/Excel5/MD5.php        |   6 +-
 Classes/PHPExcel/Reader/Excel5/RC4.php        |   6 +-
 Classes/PHPExcel/Reader/Exception.php         |   6 +-
 Classes/PHPExcel/Reader/Gnumeric.php          |   6 +-
 Classes/PHPExcel/Reader/HTML.php              |   6 +-
 Classes/PHPExcel/Reader/IReadFilter.php       |   6 +-
 Classes/PHPExcel/Reader/IReader.php           |   6 +-
 Classes/PHPExcel/Reader/OOCalc.php            |   6 +-
 Classes/PHPExcel/Reader/SYLK.php              |   6 +-
 Classes/PHPExcel/ReferenceHelper.php          |   6 +-
 Classes/PHPExcel/RichText.php                 |   6 +-
 Classes/PHPExcel/RichText/ITextElement.php    |   4 +-
 Classes/PHPExcel/RichText/Run.php             |   4 +-
 Classes/PHPExcel/RichText/TextElement.php     |   4 +-
 Classes/PHPExcel/Settings.php                 |   4 +-
 Classes/PHPExcel/Shared/CodePage.php          |   6 +-
 Classes/PHPExcel/Shared/Date.php              |   6 +-
 Classes/PHPExcel/Shared/Drawing.php           |   6 +-
 Classes/PHPExcel/Shared/Escher.php            |   6 +-
 .../PHPExcel/Shared/Escher/DgContainer.php    |   6 +-
 .../Escher/DgContainer/SpgrContainer.php      |   6 +-
 .../DgContainer/SpgrContainer/SpContainer.php |   6 +-
 .../PHPExcel/Shared/Escher/DggContainer.php   |   6 +-
 .../Escher/DggContainer/BstoreContainer.php   |   6 +-
 .../DggContainer/BstoreContainer/BSE.php      |   6 +-
 .../DggContainer/BstoreContainer/BSE/Blip.php |   6 +-
 Classes/PHPExcel/Shared/Excel5.php            |   6 +-
 Classes/PHPExcel/Shared/File.php              |   6 +-
 Classes/PHPExcel/Shared/Font.php              |   6 +-
 .../Shared/OLE/ChainedBlockStream.php         |   2 +-
 Classes/PHPExcel/Shared/OLERead.php           |   4 +-
 Classes/PHPExcel/Shared/PasswordHasher.php    |   6 +-
 Classes/PHPExcel/Shared/String.php            |   6 +-
 Classes/PHPExcel/Shared/TimeZone.php          |   6 +-
 Classes/PHPExcel/Shared/XMLWriter.php         |   6 +-
 Classes/PHPExcel/Shared/ZipArchive.php        |   6 +-
 Classes/PHPExcel/Shared/ZipStreamWrapper.php  |   6 +-
 .../PHPExcel/Shared/trend/bestFitClass.php    |   6 +-
 .../Shared/trend/exponentialBestFitClass.php  |   6 +-
 .../Shared/trend/linearBestFitClass.php       |   6 +-
 .../Shared/trend/logarithmicBestFitClass.php  |   6 +-
 .../Shared/trend/polynomialBestFitClass.php   |   6 +-
 .../Shared/trend/powerBestFitClass.php        |   6 +-
 Classes/PHPExcel/Shared/trend/trendClass.php  |   6 +-
 Classes/PHPExcel/Style.php                    |   6 +-
 Classes/PHPExcel/Style/Alignment.php          |   6 +-
 Classes/PHPExcel/Style/Border.php             |   6 +-
 Classes/PHPExcel/Style/Borders.php            |   6 +-
 Classes/PHPExcel/Style/Color.php              |   6 +-
 Classes/PHPExcel/Style/Conditional.php        |   6 +-
 Classes/PHPExcel/Style/Fill.php               |   6 +-
 Classes/PHPExcel/Style/Font.php               |   6 +-
 Classes/PHPExcel/Style/NumberFormat.php       |   6 +-
 Classes/PHPExcel/Style/Protection.php         |   6 +-
 Classes/PHPExcel/Style/Supervisor.php         |   6 +-
 Classes/PHPExcel/Worksheet.php                |   6 +-
 Classes/PHPExcel/Worksheet/AutoFilter.php     |   6 +-
 .../PHPExcel/Worksheet/AutoFilter/Column.php  |   6 +-
 .../Worksheet/AutoFilter/Column/Rule.php      |   6 +-
 Classes/PHPExcel/Worksheet/BaseDrawing.php    |   6 +-
 Classes/PHPExcel/Worksheet/CellIterator.php   |   6 +-
 Classes/PHPExcel/Worksheet/Column.php         |   6 +-
 .../PHPExcel/Worksheet/ColumnCellIterator.php |   6 +-
 .../PHPExcel/Worksheet/ColumnDimension.php    |   6 +-
 Classes/PHPExcel/Worksheet/ColumnIterator.php |   6 +-
 Classes/PHPExcel/Worksheet/Drawing.php        |   6 +-
 Classes/PHPExcel/Worksheet/Drawing/Shadow.php |   6 +-
 Classes/PHPExcel/Worksheet/HeaderFooter.php   |   6 +-
 .../Worksheet/HeaderFooterDrawing.php         |   6 +-
 Classes/PHPExcel/Worksheet/MemoryDrawing.php  |   6 +-
 Classes/PHPExcel/Worksheet/PageMargins.php    |   6 +-
 Classes/PHPExcel/Worksheet/PageSetup.php      |   6 +-
 Classes/PHPExcel/Worksheet/Protection.php     |   6 +-
 Classes/PHPExcel/Worksheet/Row.php            |   6 +-
 .../PHPExcel/Worksheet/RowCellIterator.php    |   6 +-
 Classes/PHPExcel/Worksheet/RowDimension.php   |   6 +-
 Classes/PHPExcel/Worksheet/RowIterator.php    |   6 +-
 Classes/PHPExcel/Worksheet/SheetView.php      |   6 +-
 Classes/PHPExcel/WorksheetIterator.php        |   6 +-
 Classes/PHPExcel/Writer/Abstract.php          |   6 +-
 Classes/PHPExcel/Writer/CSV.php               |   6 +-
 Classes/PHPExcel/Writer/Excel2007.php         |   6 +-
 Classes/PHPExcel/Writer/Excel2007/Chart.php   |   6 +-
 .../PHPExcel/Writer/Excel2007/Comments.php    |   6 +-
 .../Writer/Excel2007/ContentTypes.php         |   6 +-
 .../PHPExcel/Writer/Excel2007/DocProps.php    |   6 +-
 Classes/PHPExcel/Writer/Excel2007/Drawing.php |   6 +-
 Classes/PHPExcel/Writer/Excel2007/Rels.php    |   6 +-
 .../PHPExcel/Writer/Excel2007/RelsRibbon.php  |   6 +-
 Classes/PHPExcel/Writer/Excel2007/RelsVBA.php |   6 +-
 .../PHPExcel/Writer/Excel2007/StringTable.php |   6 +-
 Classes/PHPExcel/Writer/Excel2007/Style.php   |   6 +-
 Classes/PHPExcel/Writer/Excel2007/Theme.php   |   6 +-
 .../PHPExcel/Writer/Excel2007/Workbook.php    |   6 +-
 .../PHPExcel/Writer/Excel2007/Worksheet.php   |   6 +-
 .../PHPExcel/Writer/Excel2007/WriterPart.php  |   6 +-
 Classes/PHPExcel/Writer/Excel5.php            |   6 +-
 Classes/PHPExcel/Writer/Excel5/BIFFwriter.php |   6 +-
 Classes/PHPExcel/Writer/Excel5/Escher.php     |   6 +-
 Classes/PHPExcel/Writer/Excel5/Font.php       |   6 +-
 Classes/PHPExcel/Writer/Excel5/Parser.php     |   6 +-
 Classes/PHPExcel/Writer/Excel5/Workbook.php   |   6 +-
 Classes/PHPExcel/Writer/Excel5/Worksheet.php  |   6 +-
 Classes/PHPExcel/Writer/Excel5/Xf.php         |   6 +-
 Classes/PHPExcel/Writer/Exception.php         |   6 +-
 Classes/PHPExcel/Writer/HTML.php              |   6 +-
 Classes/PHPExcel/Writer/IWriter.php           |   6 +-
 Classes/PHPExcel/Writer/OpenDocument.php      |   6 +-
 .../Writer/OpenDocument/Cell/Comment.php      |   6 +-
 .../PHPExcel/Writer/OpenDocument/Content.php  |   6 +-
 Classes/PHPExcel/Writer/OpenDocument/Meta.php |   6 +-
 .../PHPExcel/Writer/OpenDocument/MetaInf.php  |   6 +-
 .../PHPExcel/Writer/OpenDocument/Mimetype.php |   6 +-
 .../PHPExcel/Writer/OpenDocument/Settings.php |   6 +-
 .../PHPExcel/Writer/OpenDocument/Styles.php   |   6 +-
 .../Writer/OpenDocument/Thumbnails.php        |   6 +-
 .../Writer/OpenDocument/WriterPart.php        |   6 +-
 Classes/PHPExcel/Writer/PDF.php               |   6 +-
 Classes/PHPExcel/Writer/PDF/Core.php          |   6 +-
 Classes/PHPExcel/Writer/PDF/DomPDF.php        |   6 +-
 Classes/PHPExcel/Writer/PDF/mPDF.php          |   6 +-
 Classes/PHPExcel/Writer/PDF/tcPDF.php         |   6 +-
 Examples/01pharSimple.php                     |   4 +-
 Examples/01simple-download-ods.php            |   4 +-
 Examples/01simple-download-pdf.php            |   4 +-
 Examples/01simple-download-xls.php            |   4 +-
 Examples/01simple-download-xlsx.php           |   4 +-
 Examples/01simple.php                         |   4 +-
 Examples/01simplePCLZip.php                   |   4 +-
 Examples/02types-xls.php                      |   4 +-
 Examples/02types.php                          |   4 +-
 Examples/03formulas.php                       |   4 +-
 Examples/04printing.php                       |   4 +-
 Examples/05featuredemo.inc.php                |   4 +-
 Examples/05featuredemo.php                    |   4 +-
 .../06largescale-with-cellcaching-sqlite.php  |   4 +-
 .../06largescale-with-cellcaching-sqlite3.php |   4 +-
 Examples/06largescale-with-cellcaching.php    |   4 +-
 Examples/06largescale-xls.php                 |   4 +-
 Examples/06largescale.php                     |   4 +-
 Examples/07reader.php                         |   4 +-
 Examples/07readerPCLZip.php                   |   4 +-
 Examples/08conditionalformatting.php          |   4 +-
 Examples/08conditionalformatting2.php         |   4 +-
 Examples/09pagebreaks.php                     |   4 +-
 Examples/10autofilter-selection-1.php         |   4 +-
 Examples/10autofilter-selection-2.php         |   4 +-
 Examples/10autofilter-selection-display.php   |   4 +-
 Examples/10autofilter.php                     |   4 +-
 Examples/11documentsecurity-xls.php           |   4 +-
 Examples/11documentsecurity.php               |   4 +-
 Examples/12cellProtection.php                 |   4 +-
 Examples/13calculation.php                    |   4 +-
 Examples/14excel5.php                         |   4 +-
 Examples/15datavalidation-xls.php             |   4 +-
 Examples/15datavalidation.php                 |   4 +-
 Examples/16csv.php                            |   4 +-
 Examples/17html.php                           |   4 +-
 Examples/18extendedcalculation.php            |   4 +-
 Examples/19namedrange.php                     |   4 +-
 Examples/20readexcel5.php                     |   4 +-
 Examples/21pdf.php                            |   4 +-
 Examples/22heavilyformatted.php               |   4 +-
 Examples/23sharedstyles.php                   |   4 +-
 Examples/24readfilter.php                     |   4 +-
 Examples/25inmemoryimage.php                  |   4 +-
 Examples/26utf8.php                           |   4 +-
 Examples/27imagesexcel5.php                   |   4 +-
 Examples/28iterator.php                       |   4 +-
 Examples/29advancedvaluebinder.php            |   4 +-
 Examples/30template.php                       |   4 +-
 Examples/31docproperties_write-xls.php        |   4 +-
 Examples/31docproperties_write.php            |   4 +-
 Examples/32chartreadwrite.php                 |   4 +-
 Examples/33chartcreate-area.php               |   4 +-
 Examples/33chartcreate-bar-stacked.php        |   4 +-
 Examples/33chartcreate-bar.php                |   4 +-
 Examples/33chartcreate-column-2.php           |   4 +-
 Examples/33chartcreate-column.php             |   4 +-
 Examples/33chartcreate-composite.php          |   4 +-
 Examples/33chartcreate-line.php               |   4 +-
 Examples/33chartcreate-multiple-charts.php    |   4 +-
 Examples/33chartcreate-pie.php                |   4 +-
 Examples/33chartcreate-radar.php              |   4 +-
 Examples/33chartcreate-scatter.php            |   4 +-
 Examples/33chartcreate-stock.php              |   4 +-
 Examples/34chartupdate.php                    |   4 +-
 Examples/35chartrender.php                    |   4 +-
 Examples/36chartreadwriteHTML.php             |   4 +-
 Examples/36chartreadwritePDF.php              |   4 +-
 Examples/37page_layout_view.php               |   4 +-
 Examples/38cloneWorksheet.php                 |   4 +-
 Examples/39dropdown.php                       |   4 +-
 Examples/41password.php                       |   4 +-
 Examples/42richText.php                       |   4 +-
 Examples/Excel2003XMLReader.php               |   4 +-
 Examples/GnumericReader.php                   |   4 +-
 Examples/OOCalcReader.php                     |   4 +-
 Examples/OOCalcReaderPCLZip.php               |   4 +-
 Examples/SylkReader.php                       |   4 +-
 Examples/XMLReader.php                        |   4 +-
 Examples/runall.php                           |   4 +-
 273 files changed, 1048 insertions(+), 1078 deletions(-)

diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php
index d27de51a2..c94fa9754 100644
--- a/Classes/PHPExcel.php
+++ b/Classes/PHPExcel.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -38,7 +38,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel
 {
diff --git a/Classes/PHPExcel/Autoloader.php b/Classes/PHPExcel/Autoloader.php
index f0b225163..90e5f6cbb 100644
--- a/Classes/PHPExcel/Autoloader.php
+++ b/Classes/PHPExcel/Autoloader.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -41,7 +41,7 @@
  *
  * @category    PHPExcel
  * @package     PHPExcel
- * @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Autoloader
 {
diff --git a/Classes/PHPExcel/CachedObjectStorage/APC.php b/Classes/PHPExcel/CachedObjectStorage/APC.php
index 8bde7fe3e..9bdeab43f 100644
--- a/Classes/PHPExcel/CachedObjectStorage/APC.php
+++ b/Classes/PHPExcel/CachedObjectStorage/APC.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php
index 7d68e944f..1d83600ac 100644
--- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php
+++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 abstract class PHPExcel_CachedObjectStorage_CacheBase {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php
index cb38d0de4..05b57ed26 100644
--- a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php
+++ b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/ICache.php b/Classes/PHPExcel/CachedObjectStorage/ICache.php
index 220905cd4..97ea223a0 100644
--- a/Classes/PHPExcel/CachedObjectStorage/ICache.php
+++ b/Classes/PHPExcel/CachedObjectStorage/ICache.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 interface PHPExcel_CachedObjectStorage_ICache
 {
diff --git a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php
index 8bd11f116..76d4566d2 100644
--- a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php
+++ b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_Igbinary extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/Memcache.php b/Classes/PHPExcel/CachedObjectStorage/Memcache.php
index 6a096769e..7e3659d77 100644
--- a/Classes/PHPExcel/CachedObjectStorage/Memcache.php
+++ b/Classes/PHPExcel/CachedObjectStorage/Memcache.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/Memory.php b/Classes/PHPExcel/CachedObjectStorage/Memory.php
index 1319a18de..e11321476 100644
--- a/Classes/PHPExcel/CachedObjectStorage/Memory.php
+++ b/Classes/PHPExcel/CachedObjectStorage/Memory.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php
index e35563c4e..3c1b7564c 100644
--- a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php
+++ b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_MemoryGZip extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php
index 1082deae5..aad8db870 100644
--- a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php
+++ b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_MemorySerialized extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php
index e28429dec..04d30999e 100644
--- a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php
+++ b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_PHPTemp extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php
index dd4f0e99d..92179a286 100644
--- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php
+++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_SQLite extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php
index bdc1d9793..c54adb4ef 100644
--- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php
+++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorage/Wincache.php b/Classes/PHPExcel/CachedObjectStorage/Wincache.php
index cdbef641b..6eeeef603 100644
--- a/Classes/PHPExcel/CachedObjectStorage/Wincache.php
+++ b/Classes/PHPExcel/CachedObjectStorage/Wincache.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorage_Wincache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
 
diff --git a/Classes/PHPExcel/CachedObjectStorageFactory.php b/Classes/PHPExcel/CachedObjectStorageFactory.php
index 2da92346e..81baa2fd9 100644
--- a/Classes/PHPExcel/CachedObjectStorageFactory.php
+++ b/Classes/PHPExcel/CachedObjectStorageFactory.php
@@ -3,7 +3,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_CachedObjectStorage
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -32,7 +32,7 @@
  *
  * @category    PHPExcel
  * @package        PHPExcel_CachedObjectStorage
- * @copyright    Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright    Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CachedObjectStorageFactory
 {
diff --git a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php
index 5cd0b909e..7cf3f24da 100644
--- a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php
+++ b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel_CalcEngine_CyclicReferenceStack
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CalcEngine_CyclicReferenceStack {
 
diff --git a/Classes/PHPExcel/CalcEngine/Logger.php b/Classes/PHPExcel/CalcEngine/Logger.php
index fe43ae4f6..3ff9746e7 100644
--- a/Classes/PHPExcel/CalcEngine/Logger.php
+++ b/Classes/PHPExcel/CalcEngine/Logger.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_CalcEngine_Logger {
 
diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php
index 48fb4a422..6f0f3a896 100644
--- a/Classes/PHPExcel/Calculation.php
+++ b/Classes/PHPExcel/Calculation.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -57,7 +57,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation {
 
diff --git a/Classes/PHPExcel/Calculation/Database.php b/Classes/PHPExcel/Calculation/Database.php
index 908decfc4..e340a589f 100644
--- a/Classes/PHPExcel/Calculation/Database.php
+++ b/Classes/PHPExcel/Calculation/Database.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -41,7 +41,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_Database {
 
diff --git a/Classes/PHPExcel/Calculation/DateTime.php b/Classes/PHPExcel/Calculation/DateTime.php
index 56c14079a..a14da243d 100644
--- a/Classes/PHPExcel/Calculation/DateTime.php
+++ b/Classes/PHPExcel/Calculation/DateTime.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -41,7 +41,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_DateTime {
 
diff --git a/Classes/PHPExcel/Calculation/Engineering.php b/Classes/PHPExcel/Calculation/Engineering.php
index b60163e56..15039a74c 100644
--- a/Classes/PHPExcel/Calculation/Engineering.php
+++ b/Classes/PHPExcel/Calculation/Engineering.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -45,7 +45,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_Engineering {
 
diff --git a/Classes/PHPExcel/Calculation/Exception.php b/Classes/PHPExcel/Calculation/Exception.php
index 2ddf666df..77f8ca05c 100644
--- a/Classes/PHPExcel/Calculation/Exception.php
+++ b/Classes/PHPExcel/Calculation/Exception.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_Exception extends PHPExcel_Exception {
 	/**
diff --git a/Classes/PHPExcel/Calculation/ExceptionHandler.php b/Classes/PHPExcel/Calculation/ExceptionHandler.php
index 41c42d7ac..01d60b9e3 100644
--- a/Classes/PHPExcel/Calculation/ExceptionHandler.php
+++ b/Classes/PHPExcel/Calculation/ExceptionHandler.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_ExceptionHandler {
 	/**
diff --git a/Classes/PHPExcel/Calculation/Financial.php b/Classes/PHPExcel/Calculation/Financial.php
index 912a26961..556acabfc 100644
--- a/Classes/PHPExcel/Calculation/Financial.php
+++ b/Classes/PHPExcel/Calculation/Financial.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -48,7 +48,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_Financial {
 
diff --git a/Classes/PHPExcel/Calculation/FormulaParser.php b/Classes/PHPExcel/Calculation/FormulaParser.php
index 3884fd20a..c78c36029 100644
--- a/Classes/PHPExcel/Calculation/FormulaParser.php
+++ b/Classes/PHPExcel/Calculation/FormulaParser.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -54,7 +54,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_FormulaParser {
 	/* Character constants */
diff --git a/Classes/PHPExcel/Calculation/FormulaToken.php b/Classes/PHPExcel/Calculation/FormulaToken.php
index ad10c00a2..54fe9a417 100644
--- a/Classes/PHPExcel/Calculation/FormulaToken.php
+++ b/Classes/PHPExcel/Calculation/FormulaToken.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -55,7 +55,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_FormulaToken {
 	/* Token types */
diff --git a/Classes/PHPExcel/Calculation/Function.php b/Classes/PHPExcel/Calculation/Function.php
index 1301cd096..eb272e063 100644
--- a/Classes/PHPExcel/Calculation/Function.php
+++ b/Classes/PHPExcel/Calculation/Function.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_Function {
 	/* Function categories */
diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php
index 7f6240141..c995ee24b 100644
--- a/Classes/PHPExcel/Calculation/Functions.php
+++ b/Classes/PHPExcel/Calculation/Functions.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -54,7 +54,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_Functions {
 
diff --git a/Classes/PHPExcel/Calculation/Logical.php b/Classes/PHPExcel/Calculation/Logical.php
index 48fdb17f4..266a66278 100644
--- a/Classes/PHPExcel/Calculation/Logical.php
+++ b/Classes/PHPExcel/Calculation/Logical.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -41,7 +41,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_Logical {
 
diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php
index 75e7f69ce..8a4e066ac 100644
--- a/Classes/PHPExcel/Calculation/LookupRef.php
+++ b/Classes/PHPExcel/Calculation/LookupRef.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -41,7 +41,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_LookupRef {
 
diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php
index 689d59ffc..ab22046b3 100644
--- a/Classes/PHPExcel/Calculation/MathTrig.php
+++ b/Classes/PHPExcel/Calculation/MathTrig.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -41,7 +41,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_MathTrig {
 
diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php
index 67e1951c2..8641118c0 100644
--- a/Classes/PHPExcel/Calculation/Statistical.php
+++ b/Classes/PHPExcel/Calculation/Statistical.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -57,7 +57,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_Statistical {
 
diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php
index 148a5b756..8c7c05f0d 100644
--- a/Classes/PHPExcel/Calculation/TextData.php
+++ b/Classes/PHPExcel/Calculation/TextData.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -41,7 +41,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_TextData {
 
diff --git a/Classes/PHPExcel/Calculation/Token/Stack.php b/Classes/PHPExcel/Calculation/Token/Stack.php
index 57963e738..b91794e44 100644
--- a/Classes/PHPExcel/Calculation/Token/Stack.php
+++ b/Classes/PHPExcel/Calculation/Token/Stack.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Calculation
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel_Calculation_Token_Stack
  * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Calculation_Token_Stack {
 
diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php
index 2d5f9102d..ae5b557d5 100644
--- a/Classes/PHPExcel/Cell.php
+++ b/Classes/PHPExcel/Cell.php
@@ -2,7 +2,7 @@
 /**
  *	PHPExcel
  *
- *	Copyright (c) 2006 - 2014 PHPExcel
+ *	Copyright (c) 2006 - 2015 PHPExcel
  *
  *	This library is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  *	@category	PHPExcel
  *	@package	PHPExcel_Cell
- *	@copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *	@copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  *	@license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  *	@version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  *	@category   PHPExcel
  *	@package	PHPExcel_Cell
- *	@copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *	@copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Cell
 {
diff --git a/Classes/PHPExcel/Cell/AdvancedValueBinder.php b/Classes/PHPExcel/Cell/AdvancedValueBinder.php
index f4280ac49..f6031f08d 100644
--- a/Classes/PHPExcel/Cell/AdvancedValueBinder.php
+++ b/Classes/PHPExcel/Cell/AdvancedValueBinder.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -41,7 +41,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Cell_AdvancedValueBinder extends PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder
 {
diff --git a/Classes/PHPExcel/Cell/DataType.php b/Classes/PHPExcel/Cell/DataType.php
index 07e148a50..144937a67 100644
--- a/Classes/PHPExcel/Cell/DataType.php
+++ b/Classes/PHPExcel/Cell/DataType.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Cell_DataType
 {
diff --git a/Classes/PHPExcel/Cell/DataValidation.php b/Classes/PHPExcel/Cell/DataValidation.php
index 538ecd1fb..61fee106d 100644
--- a/Classes/PHPExcel/Cell/DataValidation.php
+++ b/Classes/PHPExcel/Cell/DataValidation.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Cell_DataValidation
 {
diff --git a/Classes/PHPExcel/Cell/DefaultValueBinder.php b/Classes/PHPExcel/Cell/DefaultValueBinder.php
index 252048f7d..48a563df6 100644
--- a/Classes/PHPExcel/Cell/DefaultValueBinder.php
+++ b/Classes/PHPExcel/Cell/DefaultValueBinder.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -41,7 +41,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder
 {
diff --git a/Classes/PHPExcel/Cell/Hyperlink.php b/Classes/PHPExcel/Cell/Hyperlink.php
index 178ba7ee2..a9b281c28 100644
--- a/Classes/PHPExcel/Cell/Hyperlink.php
+++ b/Classes/PHPExcel/Cell/Hyperlink.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Cell_Hyperlink
 {
diff --git a/Classes/PHPExcel/Cell/IValueBinder.php b/Classes/PHPExcel/Cell/IValueBinder.php
index 551815523..5b8d1ca17 100644
--- a/Classes/PHPExcel/Cell/IValueBinder.php
+++ b/Classes/PHPExcel/Cell/IValueBinder.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Cell
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 interface PHPExcel_Cell_IValueBinder
 {
diff --git a/Classes/PHPExcel/Chart.php b/Classes/PHPExcel/Chart.php
index 9bf72dbbd..04af7b968 100644
--- a/Classes/PHPExcel/Chart.php
+++ b/Classes/PHPExcel/Chart.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Chart
 {
diff --git a/Classes/PHPExcel/Chart/Axis.php b/Classes/PHPExcel/Chart/Axis.php
index efb39e9f4..f50181837 100644
--- a/Classes/PHPExcel/Chart/Axis.php
+++ b/Classes/PHPExcel/Chart/Axis.php
@@ -1,5 +1,4 @@
  self::FORMAT_CODE_GENERAL,
-      'source_linked' => 1
-  );
-
-  /**
-   * Axis Options
-   *
-   * @var  array of mixed
-   */
-
-  private $_axis_options = array(
-      'minimum' => NULL,
-      'maximum' => NULL,
-      'major_unit' => NULL,
-      'minor_unit' => NULL,
-      'orientation' => self::ORIENTATION_NORMAL,
-      'minor_tick_mark' => self::TICK_MARK_NONE,
-      'major_tick_mark' => self::TICK_MARK_NONE,
-      'axis_labels' => self::AXIS_LABELS_NEXT_TO,
-      'horizontal_crosses' => self::HORIZONTAL_CROSSES_AUTOZERO,
-      'horizontal_crosses_value' => NULL
-  );
-
-  /**
-   * Fill Properties
-   *
-   * @var  array of mixed
-   */
-
-  private $_fill_properties = array(
-      'type' => self::EXCEL_COLOR_TYPE_ARGB,
-      'value' => NULL,
-      'alpha' => 0
-  );
-
-  /**
-   * Line Properties
-   *
-   * @var  array of mixed
-   */
-
-  private $_line_properties = array(
-      'type' => self::EXCEL_COLOR_TYPE_ARGB,
-      'value' => NULL,
-      'alpha' => 0
-  );
-
-  /**
-   * Line Style Properties
-   *
-   * @var  array of mixed
-   */
-
-  private $_line_style_properties = array(
-      'width' => '9525',
-      'compound' => self::LINE_STYLE_COMPOUND_SIMPLE,
-      'dash' => self::LINE_STYLE_DASH_SOLID,
-      'cap' => self::LINE_STYLE_CAP_FLAT,
-      'join' => self::LINE_STYLE_JOIN_BEVEL,
-      'arrow' => array(
-          'head' => array(
-              'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW,
-              'size' => self::LINE_STYLE_ARROW_SIZE_5
-          ),
-          'end' => array(
-              'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW,
-              'size' => self::LINE_STYLE_ARROW_SIZE_8
-          ),
-      )
-  );
-
-  /**
-   * Shadow Properties
-   *
-   * @var  array of mixed
-   */
-
-  private $_shadow_properties = array(
-      'presets' => self::SHADOW_PRESETS_NOSHADOW,
-      'effect' => NULL,
-      'color' => array(
-          'type' => self::EXCEL_COLOR_TYPE_STANDARD,
-          'value' => 'black',
-          'alpha' => 40,
-      ),
-      'size' => array(
-          'sx' => NULL,
-          'sy' => NULL,
-          'kx' => NULL
-      ),
-      'blur' => NULL,
-      'direction' => NULL,
-      'distance' => NULL,
-      'algn' => NULL,
-      'rotWithShape' => NULL
-  );
-
-  /**
-   * Glow Properties
-   *
-   * @var  array of mixed
-   */
-
-  private $_glow_properties = array(
-      'size' => NULL,
-      'color' => array(
-          'type' => self::EXCEL_COLOR_TYPE_STANDARD,
-          'value' => 'black',
-          'alpha' => 40
-      )
-  );
-
-  /**
-   * Soft Edge Properties
-   *
-   * @var  array of mixed
-   */
-
-  private $_soft_edges = array(
-      'size' => NULL
-  );
-
-  /**
-   * Get Series Data Type
-   *
-   * @return  string
-   */
-
-  public function setAxisNumberProperties($format_code) {
-    $this->_axis_number['format'] = (string) $format_code;
-    $this->_axis_number['source_linked'] = 0;
-  }
-
-  /**
-   * Get Axis Number Format Data Type
-   *
-   * @return  string
-   */
-
-  public function getAxisNumberFormat() {
-    return $this->_axis_number['format'];
-  }
-
-  /**
-   * Get Axis Number Source Linked
-   *
-   * @return  string
-   */
-
-  public function getAxisNumberSourceLinked() {
-    return (string) $this->_axis_number['source_linked'];
-  }
-
-  /**
-   * Set Axis Options Properties
-   *
-   * @param string $axis_labels
-   * @param string $horizontal_crosses_value
-   * @param string $horizontal_crosses
-   * @param string $axis_orientation
-   * @param string $major_tmt
-   * @param string $minor_tmt
-   * @param string $minimum
-   * @param string $maximum
-   * @param string $major_unit
-   * @param string $minor_unit
-   *
-   */
-
-  public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = NULL, $horizontal_crosses = NULL,
-      $axis_orientation = NULL, $major_tmt = NULL, $minor_tmt = NULL, $minimum = NULL, $maximum = NULL, $major_unit = NULL,
-      $minor_unit = NULL) {
-
-    $this->_axis_options['axis_labels'] = (string) $axis_labels;
-    ($horizontal_crosses_value !== NULL)
-        ? $this->_axis_options['horizontal_crosses_value'] = (string) $horizontal_crosses_value : NULL;
-    ($horizontal_crosses !== NULL) ? $this->_axis_options['horizontal_crosses'] = (string) $horizontal_crosses : NULL;
-    ($axis_orientation !== NULL) ? $this->_axis_options['orientation'] = (string) $axis_orientation : NULL;
-    ($major_tmt !== NULL) ? $this->_axis_options['major_tick_mark'] = (string) $major_tmt : NULL;
-    ($minor_tmt !== NULL) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : NULL;
-    ($minor_tmt !== NULL) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : NULL;
-    ($minimum !== NULL) ? $this->_axis_options['minimum'] = (string) $minimum : NULL;
-    ($maximum !== NULL) ? $this->_axis_options['maximum'] = (string) $maximum : NULL;
-    ($major_unit !== NULL) ? $this->_axis_options['major_unit'] = (string) $major_unit : NULL;
-    ($minor_unit !== NULL) ? $this->_axis_options['minor_unit'] = (string) $minor_unit : NULL;
-  }
-
-  /**
-   * Get Axis Options Property
-   *
-   * @param string $property
-   *
-   * @return string
-   */
-
-  public function getAxisOptionsProperty($property) {
-    return $this->_axis_options[$property];
-  }
-
-  /**
-   * Set Axis Orientation Property
-   *
-   * @param string $orientation
-   *
-   */
+class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties {
+
+    /**
+     * Axis Number
+     *
+     * @var  array of mixed
+     */
+    private $_axis_number = array(
+        'format' => self::FORMAT_CODE_GENERAL,
+        'source_linked' => 1
+    );
+
+    /**
+     * Axis Options
+     *
+     * @var  array of mixed
+     */
+    private $_axis_options = array(
+        'minimum' => NULL,
+        'maximum' => NULL,
+        'major_unit' => NULL,
+        'minor_unit' => NULL,
+        'orientation' => self::ORIENTATION_NORMAL,
+        'minor_tick_mark' => self::TICK_MARK_NONE,
+        'major_tick_mark' => self::TICK_MARK_NONE,
+        'axis_labels' => self::AXIS_LABELS_NEXT_TO,
+        'horizontal_crosses' => self::HORIZONTAL_CROSSES_AUTOZERO,
+        'horizontal_crosses_value' => NULL
+    );
+
+    /**
+     * Fill Properties
+     *
+     * @var  array of mixed
+     */
+    private $_fill_properties = array(
+        'type' => self::EXCEL_COLOR_TYPE_ARGB,
+        'value' => NULL,
+        'alpha' => 0
+    );
+
+    /**
+     * Line Properties
+     *
+     * @var  array of mixed
+     */
+    private $_line_properties = array(
+        'type' => self::EXCEL_COLOR_TYPE_ARGB,
+        'value' => NULL,
+        'alpha' => 0
+    );
+
+    /**
+     * Line Style Properties
+     *
+     * @var  array of mixed
+     */
+    private $_line_style_properties = array(
+        'width' => '9525',
+        'compound' => self::LINE_STYLE_COMPOUND_SIMPLE,
+        'dash' => self::LINE_STYLE_DASH_SOLID,
+        'cap' => self::LINE_STYLE_CAP_FLAT,
+        'join' => self::LINE_STYLE_JOIN_BEVEL,
+        'arrow' => array(
+            'head' => array(
+                'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW,
+                'size' => self::LINE_STYLE_ARROW_SIZE_5
+            ),
+            'end' => array(
+                'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW,
+                'size' => self::LINE_STYLE_ARROW_SIZE_8
+            ),
+        )
+    );
+
+    /**
+     * Shadow Properties
+     *
+     * @var  array of mixed
+     */
+    private $_shadow_properties = array(
+        'presets' => self::SHADOW_PRESETS_NOSHADOW,
+        'effect' => NULL,
+        'color' => array(
+            'type' => self::EXCEL_COLOR_TYPE_STANDARD,
+            'value' => 'black',
+            'alpha' => 40,
+        ),
+        'size' => array(
+            'sx' => NULL,
+            'sy' => NULL,
+            'kx' => NULL
+        ),
+        'blur' => NULL,
+        'direction' => NULL,
+        'distance' => NULL,
+        'algn' => NULL,
+        'rotWithShape' => NULL
+    );
+
+    /**
+     * Glow Properties
+     *
+     * @var  array of mixed
+     */
+    private $_glow_properties = array(
+        'size' => NULL,
+        'color' => array(
+            'type' => self::EXCEL_COLOR_TYPE_STANDARD,
+            'value' => 'black',
+            'alpha' => 40
+        )
+    );
+
+    /**
+     * Soft Edge Properties
+     *
+     * @var  array of mixed
+     */
+    private $_soft_edges = array(
+        'size' => NULL
+    );
+
+    /**
+     * Get Series Data Type
+     *
+     * @return  string
+     */
+    public function setAxisNumberProperties($format_code) {
+        $this->_axis_number['format'] = (string) $format_code;
+        $this->_axis_number['source_linked'] = 0;
+    }
 
-  public function setAxisOrientation($orientation) {
-    $this->orientation = (string) $orientation;
-  }
+    /**
+     * Get Axis Number Format Data Type
+     *
+     * @return  string
+     */
+    public function getAxisNumberFormat() {
+        return $this->_axis_number['format'];
+    }
 
-  /**
-   * Set Fill Property
-   *
-   * @param string $color
-   * @param int $alpha
-   * @param string $type
-   *
-   */
+    /**
+     * Get Axis Number Source Linked
+     *
+     * @return  string
+     */
+    public function getAxisNumberSourceLinked() {
+        return (string) $this->_axis_number['source_linked'];
+    }
 
-  public function setFillParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) {
-    $this->_fill_properties = $this->setColorProperties($color, $alpha, $type);
-  }
+    /**
+     * Set Axis Options Properties
+     *
+     * @param string $axis_labels
+     * @param string $horizontal_crosses_value
+     * @param string $horizontal_crosses
+     * @param string $axis_orientation
+     * @param string $major_tmt
+     * @param string $minor_tmt
+     * @param string $minimum
+     * @param string $maximum
+     * @param string $major_unit
+     * @param string $minor_unit
+     *
+     */
+    public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = NULL, $horizontal_crosses = NULL,
+        $axis_orientation = NULL, $major_tmt = NULL, $minor_tmt = NULL, $minimum = NULL, $maximum = NULL, $major_unit = NULL,
+        $minor_unit = NULL)
+    {
+        $this->_axis_options['axis_labels'] = (string) $axis_labels;
+        ($horizontal_crosses_value !== NULL)
+            ? $this->_axis_options['horizontal_crosses_value'] = (string) $horizontal_crosses_value : NULL;
+        ($horizontal_crosses !== NULL) ? $this->_axis_options['horizontal_crosses'] = (string) $horizontal_crosses : NULL;
+        ($axis_orientation !== NULL) ? $this->_axis_options['orientation'] = (string) $axis_orientation : NULL;
+        ($major_tmt !== NULL) ? $this->_axis_options['major_tick_mark'] = (string) $major_tmt : NULL;
+        ($minor_tmt !== NULL) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : NULL;
+        ($minor_tmt !== NULL) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : NULL;
+        ($minimum !== NULL) ? $this->_axis_options['minimum'] = (string) $minimum : NULL;
+        ($maximum !== NULL) ? $this->_axis_options['maximum'] = (string) $maximum : NULL;
+        ($major_unit !== NULL) ? $this->_axis_options['major_unit'] = (string) $major_unit : NULL;
+        ($minor_unit !== NULL) ? $this->_axis_options['minor_unit'] = (string) $minor_unit : NULL;
+    }
 
-  /**
-   * Set Line Property
-   *
-   * @param string $color
-   * @param int $alpha
-   * @param string $type
-   *
-   */
+    /**
+     * Get Axis Options Property
+     *
+     * @param string $property
+     *
+     * @return string
+     */
+    public function getAxisOptionsProperty($property) {
+        return $this->_axis_options[$property];
+    }
 
-  public function setLineParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) {
-    $this->_line_properties = $this->setColorProperties($color, $alpha, $type);
-  }
+    /**
+     * Set Axis Orientation Property
+     *
+     * @param string $orientation
+     *
+     */
+    public function setAxisOrientation($orientation) {
+        $this->orientation = (string) $orientation;
+    }
 
-  /**
-   * Get Fill Property
-   *
-   * @param string $property
-   *
-   * @return string
-   */
+    /**
+     * Set Fill Property
+     *
+     * @param string $color
+     * @param int $alpha
+     * @param string $type
+     *
+     */
+    public function setFillParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) {
+        $this->_fill_properties = $this->setColorProperties($color, $alpha, $type);
+    }
 
-  public function getFillProperty($property) {
-    return $this->_fill_properties[$property];
-  }
+    /**
+     * Set Line Property
+     *
+     * @param string $color
+     * @param int $alpha
+     * @param string $type
+     *
+     */
+    public function setLineParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) {
+        $this->_line_properties = $this->setColorProperties($color, $alpha, $type);
+    }
 
-  /**
-   * Get Line Property
-   *
-   * @param string $property
-   *
-   * @return string
-   */
+    /**
+     * Get Fill Property
+     *
+     * @param string $property
+     *
+     * @return string
+     */
+    public function getFillProperty($property) {
+        return $this->_fill_properties[$property];
+    }
 
-  public function getLineProperty($property) {
-    return $this->_line_properties[$property];
-  }
+    /**
+     * Get Line Property
+     *
+     * @param string $property
+     *
+     * @return string
+     */
+    public function getLineProperty($property) {
+        return $this->_line_properties[$property];
+    }
 
   /**
    * Set Line Style Properties
diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php
index 56faf6ee0..e6d277121 100644
--- a/Classes/PHPExcel/Chart/DataSeries.php
+++ b/Classes/PHPExcel/Chart/DataSeries.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Chart_DataSeries
 {
diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php
index 731d2c922..eda73fd6c 100644
--- a/Classes/PHPExcel/Chart/DataSeriesValues.php
+++ b/Classes/PHPExcel/Chart/DataSeriesValues.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Chart_DataSeriesValues
 {
diff --git a/Classes/PHPExcel/Chart/Exception.php b/Classes/PHPExcel/Chart/Exception.php
index 58b5b5822..4b5514fcb 100644
--- a/Classes/PHPExcel/Chart/Exception.php
+++ b/Classes/PHPExcel/Chart/Exception.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Chart
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Chart
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Chart_Exception extends PHPExcel_Exception {
 	/**
diff --git a/Classes/PHPExcel/Chart/GridLines.php b/Classes/PHPExcel/Chart/GridLines.php
index 269860ca1..72cb8e4ed 100644
--- a/Classes/PHPExcel/Chart/GridLines.php
+++ b/Classes/PHPExcel/Chart/GridLines.php
@@ -1,5 +1,5 @@
 _shadow_properties['color']['value'] = (string) $color;
+        }
+        if (!is_null($alpha)) {
+            $this->_shadow_properties['color']['alpha'] = $this->getTrueAlpha((int) $alpha);
+        }
+        if (!is_null($type)) {
+            $this->_shadow_properties['color']['type'] = (string) $type;
+        }
 
-  private function _setShadowColor($color, $alpha, $type) {
-    if (!is_null($color)) {
-      $this->_shadow_properties['color']['value'] = (string) $color;
-    }
-    if (!is_null($alpha)) {
-      $this->_shadow_properties['color']['alpha'] = $this->getTrueAlpha((int) $alpha);
-    }
-    if (!is_null($type)) {
-      $this->_shadow_properties['color']['type'] = (string) $type;
+        return $this;
     }
 
-    return $this;
-  }
-
-  /**
-   * Set Shadow Blur
-   *
-   * @param float $blur
-   *
-   * @return PHPExcel_Chart_GridLines
-   */
+    /**
+     * Set Shadow Blur
+     *
+     * @param float $blur
+     *
+     * @return PHPExcel_Chart_GridLines
+     */
+    private function _setShadowBlur($blur) {
+        if ($blur !== NULL) {
+            $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur);
+        }
 
-  private function _setShadowBlur($blur) {
-    if ($blur !== NULL) {
-      $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur);
+        return $this;
     }
 
-    return $this;
-  }
+    /**
+     * Set Shadow Angle
+     *
+     * @param int $angle
+     * @return PHPExcel_Chart_GridLines
+     */
 
-  /**
-   * Set Shadow Angle
-   *
-   * @param int $angle
-   *
-   * @return PHPExcel_Chart_GridLines
-   */
+    private function _setShadowAngle($angle) {
+        if ($angle !== NULL) {
+            $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle);
+        }
 
-  private function _setShadowAngle($angle) {
-    if ($angle !== NULL) {
-      $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle);
+        return $this;
     }
 
-    return $this;
-  }
-
-  /**
-   * Set Shadow Distance
-   *
-   * @param float $distance
-   *
-   * @return PHPExcel_Chart_GridLines
-   */
+    /**
+     * Set Shadow Distance
+     *
+     * @param float $distance
+     * @return PHPExcel_Chart_GridLines
+     */
+    private function _setShadowDistance($distance) {
+        if ($distance !== NULL) {
+            $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance);
+        }
 
-  private function _setShadowDistance($distance) {
-    if ($distance !== NULL) {
-      $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance);
+        return $this;
     }
 
-    return $this;
-  }
-
-  /**
-   * Get Shadow Property
-   *
-   * @param string $elements
-   * @param array $elements
-   *
-   * @return string
-   */
-
-  public function getShadowProperty($elements) {
-    return $this->getArrayElementsValue($this->_shadow_properties, $elements);
-  }
-
-  /**
-   * Set Soft Edges Size
-   *
-   * @param float $size
-   */
-
-  public function setSoftEdgesSize($size) {
-    if (!is_null($size)) {
-      $this->_activateObject();
-      $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size);
+    /**
+     * Get Shadow Property
+     *
+     * @param string $elements
+     * @param array $elements
+     * @return string
+     */
+    public function getShadowProperty($elements) {
+        return $this->getArrayElementsValue($this->_shadow_properties, $elements);
     }
-  }
 
-  /**
-   * Get Soft Edges Size
-   *
-   * @return string
-   */
+    /**
+     * Set Soft Edges Size
+     *
+     * @param float $size
+     */
+    public function setSoftEdgesSize($size) {
+        if (!is_null($size)) {
+            $this->_activateObject();
+            $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size);
+        }
+    }
 
-  public function getSoftEdgesSize() {
-    return $this->_soft_edges['size'];
-  }
+    /**
+     * Get Soft Edges Size
+     *
+     * @return string
+     */
+    public function getSoftEdgesSize() {
+        return $this->_soft_edges['size'];
+    }
 }
\ No newline at end of file
diff --git a/Classes/PHPExcel/Chart/Layout.php b/Classes/PHPExcel/Chart/Layout.php
index eefa157a9..cb55b2d0b 100644
--- a/Classes/PHPExcel/Chart/Layout.php
+++ b/Classes/PHPExcel/Chart/Layout.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Chart_Layout
 {
diff --git a/Classes/PHPExcel/Chart/Legend.php b/Classes/PHPExcel/Chart/Legend.php
index 783b3d429..5a61e6017 100644
--- a/Classes/PHPExcel/Chart/Legend.php
+++ b/Classes/PHPExcel/Chart/Legend.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Chart_Legend
 {
diff --git a/Classes/PHPExcel/Chart/PlotArea.php b/Classes/PHPExcel/Chart/PlotArea.php
index c917ce305..a055ae648 100644
--- a/Classes/PHPExcel/Chart/PlotArea.php
+++ b/Classes/PHPExcel/Chart/PlotArea.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Chart_PlotArea
 {
diff --git a/Classes/PHPExcel/Chart/Properties.php b/Classes/PHPExcel/Chart/Properties.php
index 7593983c0..e0bbb56ae 100644
--- a/Classes/PHPExcel/Chart/Properties.php
+++ b/Classes/PHPExcel/Chart/Properties.php
@@ -6,7 +6,8 @@
  * Time: 5:45 PM
  */
 
-abstract class PHPExcel_Properties {
+abstract class PHPExcel_Chart_Properties
+{
 
   const
       EXCEL_COLOR_TYPE_STANDARD = 'prstClr',
diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php
index 99a0b97ad..ec1fb2524 100644
--- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php
+++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php
@@ -3,7 +3,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart_Renderer
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -35,7 +35,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart_Renderer
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Chart_Renderer_jpgraph
 {
diff --git a/Classes/PHPExcel/Chart/Title.php b/Classes/PHPExcel/Chart/Title.php
index 5d226c4b2..1a222326f 100644
--- a/Classes/PHPExcel/Chart/Title.php
+++ b/Classes/PHPExcel/Chart/Title.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Chart
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Chart_Title
 {
diff --git a/Classes/PHPExcel/Comment.php b/Classes/PHPExcel/Comment.php
index 8b8cfdcc4..4d5ef18f4 100644
--- a/Classes/PHPExcel/Comment.php
+++ b/Classes/PHPExcel/Comment.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Comment implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/DocumentProperties.php b/Classes/PHPExcel/DocumentProperties.php
index 7b4a0e435..feaa15463 100644
--- a/Classes/PHPExcel/DocumentProperties.php
+++ b/Classes/PHPExcel/DocumentProperties.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category    PHPExcel
  * @package    PHPExcel
- * @copyright    Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright    Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category    PHPExcel
  * @package        PHPExcel
- * @copyright    Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright    Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_DocumentProperties
 {
diff --git a/Classes/PHPExcel/DocumentSecurity.php b/Classes/PHPExcel/DocumentSecurity.php
index cf7ffb57c..b194ecd8c 100644
--- a/Classes/PHPExcel/DocumentSecurity.php
+++ b/Classes/PHPExcel/DocumentSecurity.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_DocumentSecurity
 {
diff --git a/Classes/PHPExcel/Exception.php b/Classes/PHPExcel/Exception.php
index 578b9eeee..c2694adde 100644
--- a/Classes/PHPExcel/Exception.php
+++ b/Classes/PHPExcel/Exception.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Exception extends Exception {
     /**
diff --git a/Classes/PHPExcel/HashTable.php b/Classes/PHPExcel/HashTable.php
index 77106e1e0..4fb41adb3 100644
--- a/Classes/PHPExcel/HashTable.php
+++ b/Classes/PHPExcel/HashTable.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_HashTable
 {
diff --git a/Classes/PHPExcel/IComparable.php b/Classes/PHPExcel/IComparable.php
index adb9a016d..3afbf4bc4 100644
--- a/Classes/PHPExcel/IComparable.php
+++ b/Classes/PHPExcel/IComparable.php
@@ -18,7 +18,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -29,7 +29,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 interface PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/IOFactory.php b/Classes/PHPExcel/IOFactory.php
index 1daa06a53..5db362e02 100644
--- a/Classes/PHPExcel/IOFactory.php
+++ b/Classes/PHPExcel/IOFactory.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -40,7 +40,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_IOFactory
 {
diff --git a/Classes/PHPExcel/NamedRange.php b/Classes/PHPExcel/NamedRange.php
index fe245e3ee..cab3c7ec7 100644
--- a/Classes/PHPExcel/NamedRange.php
+++ b/Classes/PHPExcel/NamedRange.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_NamedRange
 {
diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php
index 2d3c964b6..8fa961b04 100644
--- a/Classes/PHPExcel/Reader/Abstract.php
+++ b/Classes/PHPExcel/Reader/Abstract.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel
  * @package	PHPExcel_Reader
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
 {
diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php
index 22176fdc9..2942e804b 100644
--- a/Classes/PHPExcel/Reader/CSV.php
+++ b/Classes/PHPExcel/Reader/CSV.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -40,7 +40,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
 {
diff --git a/Classes/PHPExcel/Reader/DefaultReadFilter.php b/Classes/PHPExcel/Reader/DefaultReadFilter.php
index dc55fc6bd..6fb5eb334 100644
--- a/Classes/PHPExcel/Reader/DefaultReadFilter.php
+++ b/Classes/PHPExcel/Reader/DefaultReadFilter.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -40,7 +40,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_DefaultReadFilter implements PHPExcel_Reader_IReadFilter
 {
diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php
index 851eaab18..38bb349ac 100644
--- a/Classes/PHPExcel/Reader/Excel2003XML.php
+++ b/Classes/PHPExcel/Reader/Excel2003XML.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -40,7 +40,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
 {
diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php
index e41596afc..bff2147d3 100644
--- a/Classes/PHPExcel/Reader/Excel2007.php
+++ b/Classes/PHPExcel/Reader/Excel2007.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -40,7 +40,7 @@
  *
  * @category	PHPExcel
  * @package	PHPExcel_Reader
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
 {
diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php
index 1424276c6..a72b92936 100644
--- a/Classes/PHPExcel/Reader/Excel2007/Chart.php
+++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Reader_Excel2007
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Reader_Excel2007
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_Excel2007_Chart
 {
diff --git a/Classes/PHPExcel/Reader/Excel2007/Theme.php b/Classes/PHPExcel/Reader/Excel2007/Theme.php
index a371c6208..9647e1212 100644
--- a/Classes/PHPExcel/Reader/Excel2007/Theme.php
+++ b/Classes/PHPExcel/Reader/Excel2007/Theme.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_Excel2007_Theme
 {
diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php
index f2893ece7..a9acfc472 100644
--- a/Classes/PHPExcel/Reader/Excel5.php
+++ b/Classes/PHPExcel/Reader/Excel5.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -73,7 +73,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Reader_Excel5
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
 {
diff --git a/Classes/PHPExcel/Reader/Excel5/Escher.php b/Classes/PHPExcel/Reader/Excel5/Escher.php
index 8dc5e902e..f18382965 100644
--- a/Classes/PHPExcel/Reader/Excel5/Escher.php
+++ b/Classes/PHPExcel/Reader/Excel5/Escher.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_Excel5_Escher
 {
diff --git a/Classes/PHPExcel/Reader/Excel5/MD5.php b/Classes/PHPExcel/Reader/Excel5/MD5.php
index 097e9753f..1c9ede02b 100644
--- a/Classes/PHPExcel/Reader/Excel5/MD5.php
+++ b/Classes/PHPExcel/Reader/Excel5/MD5.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt        LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category        PHPExcel
  * @package                PHPExcel_Reader_Excel5
- * @copyright        Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright        Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_Excel5_MD5
 {
diff --git a/Classes/PHPExcel/Reader/Excel5/RC4.php b/Classes/PHPExcel/Reader/Excel5/RC4.php
index 199ee1921..4f23c7bd7 100644
--- a/Classes/PHPExcel/Reader/Excel5/RC4.php
+++ b/Classes/PHPExcel/Reader/Excel5/RC4.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Reader_Excel5
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_Excel5_RC4
 {
diff --git a/Classes/PHPExcel/Reader/Exception.php b/Classes/PHPExcel/Reader/Exception.php
index d0e2f5707..c712fe0eb 100644
--- a/Classes/PHPExcel/Reader/Exception.php
+++ b/Classes/PHPExcel/Reader/Exception.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_Exception extends PHPExcel_Exception {
 	/**
diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php
index 584ded287..534a2143c 100644
--- a/Classes/PHPExcel/Reader/Gnumeric.php
+++ b/Classes/PHPExcel/Reader/Gnumeric.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -40,7 +40,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Reader
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
 {
diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php
index 26cc598c1..68fd30c8b 100644
--- a/Classes/PHPExcel/Reader/HTML.php
+++ b/Classes/PHPExcel/Reader/HTML.php
@@ -3,7 +3,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -39,7 +39,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_HTML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
 {
diff --git a/Classes/PHPExcel/Reader/IReadFilter.php b/Classes/PHPExcel/Reader/IReadFilter.php
index f27cff8b9..f20dd97a1 100644
--- a/Classes/PHPExcel/Reader/IReadFilter.php
+++ b/Classes/PHPExcel/Reader/IReadFilter.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 interface PHPExcel_Reader_IReadFilter
 {
diff --git a/Classes/PHPExcel/Reader/IReader.php b/Classes/PHPExcel/Reader/IReader.php
index b543df4a7..bc3a4bd8c 100644
--- a/Classes/PHPExcel/Reader/IReader.php
+++ b/Classes/PHPExcel/Reader/IReader.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 interface PHPExcel_Reader_IReader
 {
diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php
index 7644df941..888aefb65 100644
--- a/Classes/PHPExcel/Reader/OOCalc.php
+++ b/Classes/PHPExcel/Reader/OOCalc.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -40,7 +40,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Reader
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
 {
diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php
index b61118a3b..4048d4fc3 100644
--- a/Classes/PHPExcel/Reader/SYLK.php
+++ b/Classes/PHPExcel/Reader/SYLK.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -40,7 +40,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Reader
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
 {
diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php
index 9eadab4d5..dfd5b4c8a 100644
--- a/Classes/PHPExcel/ReferenceHelper.php
+++ b/Classes/PHPExcel/ReferenceHelper.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_ReferenceHelper
 {
diff --git a/Classes/PHPExcel/RichText.php b/Classes/PHPExcel/RichText.php
index 19326315b..30ba2c347 100644
--- a/Classes/PHPExcel/RichText.php
+++ b/Classes/PHPExcel/RichText.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_RichText
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_RichText
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_RichText implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/RichText/ITextElement.php b/Classes/PHPExcel/RichText/ITextElement.php
index 9f1c6240a..816cc6963 100644
--- a/Classes/PHPExcel/RichText/ITextElement.php
+++ b/Classes/PHPExcel/RichText/ITextElement.php
@@ -18,7 +18,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_RichText
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -29,7 +29,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_RichText
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 interface PHPExcel_RichText_ITextElement
 {
diff --git a/Classes/PHPExcel/RichText/Run.php b/Classes/PHPExcel/RichText/Run.php
index 4a8c592e3..6d54e57df 100644
--- a/Classes/PHPExcel/RichText/Run.php
+++ b/Classes/PHPExcel/RichText/Run.php
@@ -18,7 +18,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_RichText
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -29,7 +29,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_RichText
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_RichText_Run extends PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement
 {
diff --git a/Classes/PHPExcel/RichText/TextElement.php b/Classes/PHPExcel/RichText/TextElement.php
index ec7c2644e..3524446ab 100644
--- a/Classes/PHPExcel/RichText/TextElement.php
+++ b/Classes/PHPExcel/RichText/TextElement.php
@@ -18,7 +18,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_RichText
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -29,7 +29,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_RichText
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement
 {
diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php
index c78d9350d..69beb1a14 100644
--- a/Classes/PHPExcel/Settings.php
+++ b/Classes/PHPExcel/Settings.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Settings
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php
index 89e2d19cf..ebda1b243 100644
--- a/Classes/PHPExcel/Shared/CodePage.php
+++ b/Classes/PHPExcel/Shared/CodePage.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_CodePage
 {
diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php
index 75f367eac..c3fe23001 100644
--- a/Classes/PHPExcel/Shared/Date.php
+++ b/Classes/PHPExcel/Shared/Date.php
@@ -3,7 +3,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -32,7 +32,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Date
 {
diff --git a/Classes/PHPExcel/Shared/Drawing.php b/Classes/PHPExcel/Shared/Drawing.php
index dbff74abc..aeae3bd3d 100644
--- a/Classes/PHPExcel/Shared/Drawing.php
+++ b/Classes/PHPExcel/Shared/Drawing.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Drawing
 {
diff --git a/Classes/PHPExcel/Shared/Escher.php b/Classes/PHPExcel/Shared/Escher.php
index ddf68c65b..88cb1c6fd 100644
--- a/Classes/PHPExcel/Shared/Escher.php
+++ b/Classes/PHPExcel/Shared/Escher.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Escher
 {
diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer.php
index cb826db10..b7c9fd9e8 100644
--- a/Classes/PHPExcel/Shared/Escher/DgContainer.php
+++ b/Classes/PHPExcel/Shared/Escher/DgContainer.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Escher_DgContainer
 {
diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php
index b8ad8eafd..c60c641cd 100644
--- a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php
+++ b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Escher_DgContainer_SpgrContainer
 {
diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php
index 682314801..97792af55 100644
--- a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php
+++ b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer
 {
diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer.php
index 26696ec9d..b5dd3eecf 100644
--- a/Classes/PHPExcel/Shared/Escher/DggContainer.php
+++ b/Classes/PHPExcel/Shared/Escher/DggContainer.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Escher_DggContainer
 {
diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php
index fba2e73fa..468ca2465 100644
--- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php
+++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Escher_DggContainer_BstoreContainer
 {
diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php
index 418896a34..0b1239de4 100644
--- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php
+++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE
 {
diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php
index d9cc2f5c0..80e83bc36 100644
--- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php
+++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Escher
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip
 {
diff --git a/Classes/PHPExcel/Shared/Excel5.php b/Classes/PHPExcel/Shared/Excel5.php
index 3caf675dd..5564c6b7d 100644
--- a/Classes/PHPExcel/Shared/Excel5.php
+++ b/Classes/PHPExcel/Shared/Excel5.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Excel5
 {
diff --git a/Classes/PHPExcel/Shared/File.php b/Classes/PHPExcel/Shared/File.php
index 52c9b9796..8dfb66e2f 100644
--- a/Classes/PHPExcel/Shared/File.php
+++ b/Classes/PHPExcel/Shared/File.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_File
 {
diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php
index 8e5b27b8f..a59aa504a 100644
--- a/Classes/PHPExcel/Shared/Font.php
+++ b/Classes/PHPExcel/Shared/Font.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_Font
 {
diff --git a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php
index 0736fc232..03a9e48f1 100644
--- a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php
+++ b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/Classes/PHPExcel/Shared/OLERead.php b/Classes/PHPExcel/Shared/OLERead.php
index 261bdde58..b50fd0554 100644
--- a/Classes/PHPExcel/Shared/OLERead.php
+++ b/Classes/PHPExcel/Shared/OLERead.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Classes/PHPExcel/Shared/PasswordHasher.php b/Classes/PHPExcel/Shared/PasswordHasher.php
index 891b6bc15..db0707f2b 100644
--- a/Classes/PHPExcel/Shared/PasswordHasher.php
+++ b/Classes/PHPExcel/Shared/PasswordHasher.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_PasswordHasher
 {
diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php
index 7d6b4192b..7c6978846 100644
--- a/Classes/PHPExcel/Shared/String.php
+++ b/Classes/PHPExcel/Shared/String.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_String
 {
diff --git a/Classes/PHPExcel/Shared/TimeZone.php b/Classes/PHPExcel/Shared/TimeZone.php
index 1792a2953..3aa1884e3 100644
--- a/Classes/PHPExcel/Shared/TimeZone.php
+++ b/Classes/PHPExcel/Shared/TimeZone.php
@@ -3,7 +3,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -32,7 +32,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_TimeZone
 {
diff --git a/Classes/PHPExcel/Shared/XMLWriter.php b/Classes/PHPExcel/Shared/XMLWriter.php
index beca51fc5..8ec38e223 100644
--- a/Classes/PHPExcel/Shared/XMLWriter.php
+++ b/Classes/PHPExcel/Shared/XMLWriter.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -39,7 +39,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_XMLWriter extends XMLWriter {
 	/** Temporary storage method */
diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php
index 9a801a841..4af9c3d13 100644
--- a/Classes/PHPExcel/Shared/ZipArchive.php
+++ b/Classes/PHPExcel/Shared/ZipArchive.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_ZipArchive
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -36,7 +36,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_ZipArchive
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_ZipArchive
 {
diff --git a/Classes/PHPExcel/Shared/ZipStreamWrapper.php b/Classes/PHPExcel/Shared/ZipStreamWrapper.php
index 6e63d3ce3..a5ceb1e4d 100644
--- a/Classes/PHPExcel/Shared/ZipStreamWrapper.php
+++ b/Classes/PHPExcel/Shared/ZipStreamWrapper.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Shared_ZipStreamWrapper {
 	/**
diff --git a/Classes/PHPExcel/Shared/trend/bestFitClass.php b/Classes/PHPExcel/Shared/trend/bestFitClass.php
index 9ae8b006d..b797d664f 100644
--- a/Classes/PHPExcel/Shared/trend/bestFitClass.php
+++ b/Classes/PHPExcel/Shared/trend/bestFitClass.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Best_Fit
 {
diff --git a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php
index b524b5fe4..541e22919 100644
--- a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php
+++ b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -34,7 +34,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit
 {
diff --git a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php
index 7d811aa5b..c6575a4b0 100644
--- a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php
+++ b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -34,7 +34,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit
 {
diff --git a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php
index b43cd5edf..77e9ad29d 100644
--- a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php
+++ b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -34,7 +34,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit
 {
diff --git a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php
index 3d329eb7d..5c9fec419 100644
--- a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php
+++ b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -35,7 +35,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit
 {
diff --git a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php
index 832669c9f..5da232d7c 100644
--- a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php
+++ b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -34,7 +34,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit
 {
diff --git a/Classes/PHPExcel/Shared/trend/trendClass.php b/Classes/PHPExcel/Shared/trend/trendClass.php
index 25d7eb1d8..4ccb517d4 100644
--- a/Classes/PHPExcel/Shared/trend/trendClass.php
+++ b/Classes/PHPExcel/Shared/trend/trendClass.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -38,7 +38,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Shared_Trend
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class trendClass
 {
diff --git a/Classes/PHPExcel/Style.php b/Classes/PHPExcel/Style.php
index 9c29320ea..a6672c925 100644
--- a/Classes/PHPExcel/Style.php
+++ b/Classes/PHPExcel/Style.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Style extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Style/Alignment.php b/Classes/PHPExcel/Style/Alignment.php
index 00825debf..83eaa317e 100644
--- a/Classes/PHPExcel/Style/Alignment.php
+++ b/Classes/PHPExcel/Style/Alignment.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Style_Alignment extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Style/Border.php b/Classes/PHPExcel/Style/Border.php
index ec737bf0f..f795f5642 100644
--- a/Classes/PHPExcel/Style/Border.php
+++ b/Classes/PHPExcel/Style/Border.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Style_Border extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Style/Borders.php b/Classes/PHPExcel/Style/Borders.php
index 21dcfeeef..f5216f616 100644
--- a/Classes/PHPExcel/Style/Borders.php
+++ b/Classes/PHPExcel/Style/Borders.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Style_Borders extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Style/Color.php b/Classes/PHPExcel/Style/Color.php
index a56c9a633..f1fd40dad 100644
--- a/Classes/PHPExcel/Style/Color.php
+++ b/Classes/PHPExcel/Style/Color.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Style_Color extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Style/Conditional.php b/Classes/PHPExcel/Style/Conditional.php
index aebf1e313..17ac564cb 100644
--- a/Classes/PHPExcel/Style/Conditional.php
+++ b/Classes/PHPExcel/Style/Conditional.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Style_Conditional implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Style/Fill.php b/Classes/PHPExcel/Style/Fill.php
index 6412ba634..29e3a6eac 100644
--- a/Classes/PHPExcel/Style/Fill.php
+++ b/Classes/PHPExcel/Style/Fill.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Style_Fill extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Style/Font.php b/Classes/PHPExcel/Style/Font.php
index 296e34855..53b606387 100644
--- a/Classes/PHPExcel/Style/Font.php
+++ b/Classes/PHPExcel/Style/Font.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Style_Font extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php
index 62ab3e275..cff58acb4 100644
--- a/Classes/PHPExcel/Style/NumberFormat.php
+++ b/Classes/PHPExcel/Style/NumberFormat.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Style_NumberFormat extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Style/Protection.php b/Classes/PHPExcel/Style/Protection.php
index 8dc1f31ad..54a05d987 100644
--- a/Classes/PHPExcel/Style/Protection.php
+++ b/Classes/PHPExcel/Style/Protection.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    1.4.5, 2007-08-23
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Style_Protection extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Style/Supervisor.php b/Classes/PHPExcel/Style/Supervisor.php
index 2d21f5293..c732d30f5 100644
--- a/Classes/PHPExcel/Style/Supervisor.php
+++ b/Classes/PHPExcel/Style/Supervisor.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Style
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 abstract class PHPExcel_Style_Supervisor
 {
diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php
index 2b0b57ae4..c5c4119fc 100644
--- a/Classes/PHPExcel/Worksheet.php
+++ b/Classes/PHPExcel/Worksheet.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php
index 22c357489..77ad376ac 100644
--- a/Classes/PHPExcel/Worksheet/AutoFilter.php
+++ b/Classes/PHPExcel/Worksheet/AutoFilter.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_AutoFilter
 {
diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php
index 1a6fb4eb8..e2ea1bb3e 100644
--- a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php
+++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Worksheet
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Worksheet
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_AutoFilter_Column
 {
diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php
index e60264640..eb9f71ff4 100644
--- a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php
+++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Worksheet
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version		##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category	PHPExcel
  * @package		PHPExcel_Worksheet
- * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_AutoFilter_Column_Rule
 {
diff --git a/Classes/PHPExcel/Worksheet/BaseDrawing.php b/Classes/PHPExcel/Worksheet/BaseDrawing.php
index 5a760fcad..e1d4715bd 100644
--- a/Classes/PHPExcel/Worksheet/BaseDrawing.php
+++ b/Classes/PHPExcel/Worksheet/BaseDrawing.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Worksheet/CellIterator.php b/Classes/PHPExcel/Worksheet/CellIterator.php
index 239cb4ff1..37f6a12a8 100644
--- a/Classes/PHPExcel/Worksheet/CellIterator.php
+++ b/Classes/PHPExcel/Worksheet/CellIterator.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    1.8.0, 2014-03-02
  */
@@ -33,7 +33,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 abstract class PHPExcel_Worksheet_CellIterator
 {
diff --git a/Classes/PHPExcel/Worksheet/Column.php b/Classes/PHPExcel/Worksheet/Column.php
index 94af21357..b0ba6837a 100644
--- a/Classes/PHPExcel/Worksheet/Column.php
+++ b/Classes/PHPExcel/Worksheet/Column.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -33,7 +33,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_Column
 {
diff --git a/Classes/PHPExcel/Worksheet/ColumnCellIterator.php b/Classes/PHPExcel/Worksheet/ColumnCellIterator.php
index a9ef49f00..c7953ea27 100644
--- a/Classes/PHPExcel/Worksheet/ColumnCellIterator.php
+++ b/Classes/PHPExcel/Worksheet/ColumnCellIterator.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -33,7 +33,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_ColumnCellIterator extends PHPExcel_Worksheet_CellIterator implements Iterator
 {
diff --git a/Classes/PHPExcel/Worksheet/ColumnDimension.php b/Classes/PHPExcel/Worksheet/ColumnDimension.php
index bc6a042eb..e52a3f40c 100644
--- a/Classes/PHPExcel/Worksheet/ColumnDimension.php
+++ b/Classes/PHPExcel/Worksheet/ColumnDimension.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_ColumnDimension
 {
diff --git a/Classes/PHPExcel/Worksheet/ColumnIterator.php b/Classes/PHPExcel/Worksheet/ColumnIterator.php
index 3030b3f43..bec14d5a9 100644
--- a/Classes/PHPExcel/Worksheet/ColumnIterator.php
+++ b/Classes/PHPExcel/Worksheet/ColumnIterator.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -33,7 +33,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_ColumnIterator implements Iterator
 {
diff --git a/Classes/PHPExcel/Worksheet/Drawing.php b/Classes/PHPExcel/Worksheet/Drawing.php
index e8d87f1d0..d58fcebd8 100644
--- a/Classes/PHPExcel/Worksheet/Drawing.php
+++ b/Classes/PHPExcel/Worksheet/Drawing.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet_Drawing
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet_Drawing
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php
index 98b95b1a7..cc6289a00 100644
--- a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php
+++ b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet_Drawing
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet_Drawing
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Worksheet/HeaderFooter.php b/Classes/PHPExcel/Worksheet/HeaderFooter.php
index 803741638..6620682f3 100644
--- a/Classes/PHPExcel/Worksheet/HeaderFooter.php
+++ b/Classes/PHPExcel/Worksheet/HeaderFooter.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -91,7 +91,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_HeaderFooter
 {
diff --git a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php
index 966664f93..99085b73f 100644
--- a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php
+++ b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Worksheet/MemoryDrawing.php b/Classes/PHPExcel/Worksheet/MemoryDrawing.php
index 80fc6d1f0..b6c71af99 100644
--- a/Classes/PHPExcel/Worksheet/MemoryDrawing.php
+++ b/Classes/PHPExcel/Worksheet/MemoryDrawing.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable
 {
diff --git a/Classes/PHPExcel/Worksheet/PageMargins.php b/Classes/PHPExcel/Worksheet/PageMargins.php
index b05a291ff..3b83afb53 100644
--- a/Classes/PHPExcel/Worksheet/PageMargins.php
+++ b/Classes/PHPExcel/Worksheet/PageMargins.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_PageMargins
 {
diff --git a/Classes/PHPExcel/Worksheet/PageSetup.php b/Classes/PHPExcel/Worksheet/PageSetup.php
index ba2792fac..86af283d4 100644
--- a/Classes/PHPExcel/Worksheet/PageSetup.php
+++ b/Classes/PHPExcel/Worksheet/PageSetup.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -102,7 +102,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_PageSetup
 {
diff --git a/Classes/PHPExcel/Worksheet/Protection.php b/Classes/PHPExcel/Worksheet/Protection.php
index da66bf763..1290a9143 100644
--- a/Classes/PHPExcel/Worksheet/Protection.php
+++ b/Classes/PHPExcel/Worksheet/Protection.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_Protection
 {
diff --git a/Classes/PHPExcel/Worksheet/Row.php b/Classes/PHPExcel/Worksheet/Row.php
index 330432790..11fadba53 100644
--- a/Classes/PHPExcel/Worksheet/Row.php
+++ b/Classes/PHPExcel/Worksheet/Row.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -33,7 +33,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_Row
 {
diff --git a/Classes/PHPExcel/Worksheet/RowCellIterator.php b/Classes/PHPExcel/Worksheet/RowCellIterator.php
index 96c6b419c..df5bbe5a6 100644
--- a/Classes/PHPExcel/Worksheet/RowCellIterator.php
+++ b/Classes/PHPExcel/Worksheet/RowCellIterator.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -33,7 +33,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_RowCellIterator extends PHPExcel_Worksheet_CellIterator implements Iterator
 {
diff --git a/Classes/PHPExcel/Worksheet/RowDimension.php b/Classes/PHPExcel/Worksheet/RowDimension.php
index bff89a080..00f7c56b0 100644
--- a/Classes/PHPExcel/Worksheet/RowDimension.php
+++ b/Classes/PHPExcel/Worksheet/RowDimension.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_RowDimension
 {
diff --git a/Classes/PHPExcel/Worksheet/RowIterator.php b/Classes/PHPExcel/Worksheet/RowIterator.php
index 110d86214..f01c7f502 100644
--- a/Classes/PHPExcel/Worksheet/RowIterator.php
+++ b/Classes/PHPExcel/Worksheet/RowIterator.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -33,7 +33,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_RowIterator implements Iterator
 {
diff --git a/Classes/PHPExcel/Worksheet/SheetView.php b/Classes/PHPExcel/Worksheet/SheetView.php
index 8ced835dd..2396ddaa3 100644
--- a/Classes/PHPExcel/Worksheet/SheetView.php
+++ b/Classes/PHPExcel/Worksheet/SheetView.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Worksheet
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Worksheet_SheetView
 {
diff --git a/Classes/PHPExcel/WorksheetIterator.php b/Classes/PHPExcel/WorksheetIterator.php
index ad17fd903..065bfe3f8 100644
--- a/Classes/PHPExcel/WorksheetIterator.php
+++ b/Classes/PHPExcel/WorksheetIterator.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -33,7 +33,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_WorksheetIterator implements Iterator
 {
diff --git a/Classes/PHPExcel/Writer/Abstract.php b/Classes/PHPExcel/Writer/Abstract.php
index fca6a60cc..c064722cf 100644
--- a/Classes/PHPExcel/Writer/Abstract.php
+++ b/Classes/PHPExcel/Writer/Abstract.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter
 {
diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php
index 97961ccca..b81270d64 100644
--- a/Classes/PHPExcel/Writer/CSV.php
+++ b/Classes/PHPExcel/Writer/CSV.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Writer_CSV
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Writer_CSV
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter {
 	/**
diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php
index 4cf14ac1c..a3abe16ab 100644
--- a/Classes/PHPExcel/Writer/Excel2007.php
+++ b/Classes/PHPExcel/Writer/Excel2007.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php
index 4846910fa..91c12bbbf 100644
--- a/Classes/PHPExcel/Writer/Excel2007/Chart.php
+++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -30,7 +30,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_Chart extends
   PHPExcel_Writer_Excel2007_WriterPart {
diff --git a/Classes/PHPExcel/Writer/Excel2007/Comments.php b/Classes/PHPExcel/Writer/Excel2007/Comments.php
index dc809fa8e..a6faaaa91 100644
--- a/Classes/PHPExcel/Writer/Excel2007/Comments.php
+++ b/Classes/PHPExcel/Writer/Excel2007/Comments.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_Comments extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php
index 557853654..a410b8549 100644
--- a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php
+++ b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_ContentTypes extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/DocProps.php b/Classes/PHPExcel/Writer/Excel2007/DocProps.php
index f8821379c..c4a4b2d44 100644
--- a/Classes/PHPExcel/Writer/Excel2007/DocProps.php
+++ b/Classes/PHPExcel/Writer/Excel2007/DocProps.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_DocProps extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/Drawing.php b/Classes/PHPExcel/Writer/Excel2007/Drawing.php
index 1cf971ed4..2cda60353 100644
--- a/Classes/PHPExcel/Writer/Excel2007/Drawing.php
+++ b/Classes/PHPExcel/Writer/Excel2007/Drawing.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_Drawing extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/Rels.php b/Classes/PHPExcel/Writer/Excel2007/Rels.php
index a7d36c0a9..cf9b6bed0 100644
--- a/Classes/PHPExcel/Writer/Excel2007/Rels.php
+++ b/Classes/PHPExcel/Writer/Excel2007/Rels.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_Rels extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php
index 615f2cbd9..3cb81804e 100644
--- a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php
+++ b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version     ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_RelsRibbon extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php
index 3f87d81f2..bd2bbb667 100644
--- a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php
+++ b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version     ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_RelsVBA extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Classes/PHPExcel/Writer/Excel2007/StringTable.php
index e8ca1c5a5..1d7bbfded 100644
--- a/Classes/PHPExcel/Writer/Excel2007/StringTable.php
+++ b/Classes/PHPExcel/Writer/Excel2007/StringTable.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_StringTable extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/Style.php b/Classes/PHPExcel/Writer/Excel2007/Style.php
index d38c6eacc..d0a7ce9f1 100644
--- a/Classes/PHPExcel/Writer/Excel2007/Style.php
+++ b/Classes/PHPExcel/Writer/Excel2007/Style.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_Style extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/Theme.php b/Classes/PHPExcel/Writer/Excel2007/Theme.php
index c67b94816..f9c2fd1d0 100644
--- a/Classes/PHPExcel/Writer/Excel2007/Theme.php
+++ b/Classes/PHPExcel/Writer/Excel2007/Theme.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/Workbook.php b/Classes/PHPExcel/Writer/Excel2007/Workbook.php
index f30929476..56a3939b7 100644
--- a/Classes/PHPExcel/Writer/Excel2007/Workbook.php
+++ b/Classes/PHPExcel/Writer/Excel2007/Workbook.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php
index 5cb803e52..6ca93c035 100644
--- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php
+++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php
index 68b1124fd..4c2f9b4b9 100644
--- a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php
+++ b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel2007
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 abstract class PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php
index 1a990d045..6875d9b24 100644
--- a/Classes/PHPExcel/Writer/Excel5.php
+++ b/Classes/PHPExcel/Writer/Excel5.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter
 {
diff --git a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php
index 86201134d..43eb5099f 100644
--- a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php
+++ b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -65,7 +65,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel5_BIFFwriter
 {
diff --git a/Classes/PHPExcel/Writer/Excel5/Escher.php b/Classes/PHPExcel/Writer/Excel5/Escher.php
index 92e6a8d88..a9007867c 100644
--- a/Classes/PHPExcel/Writer/Excel5/Escher.php
+++ b/Classes/PHPExcel/Writer/Excel5/Escher.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel5_Escher
 {
diff --git a/Classes/PHPExcel/Writer/Excel5/Font.php b/Classes/PHPExcel/Writer/Excel5/Font.php
index 0df194382..997791693 100644
--- a/Classes/PHPExcel/Writer/Excel5/Font.php
+++ b/Classes/PHPExcel/Writer/Excel5/Font.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel5_Font
 {
diff --git a/Classes/PHPExcel/Writer/Excel5/Parser.php b/Classes/PHPExcel/Writer/Excel5/Parser.php
index bc6ddb132..0379631b3 100644
--- a/Classes/PHPExcel/Writer/Excel5/Parser.php
+++ b/Classes/PHPExcel/Writer/Excel5/Parser.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -55,7 +55,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel5_Parser
 {
diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php
index ecfac5dc0..f1b3cc725 100644
--- a/Classes/PHPExcel/Writer/Excel5/Workbook.php
+++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -66,7 +66,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter
 {
diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php
index fb75499b1..f73ac35a4 100644
--- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php
+++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -66,7 +66,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
 {
diff --git a/Classes/PHPExcel/Writer/Excel5/Xf.php b/Classes/PHPExcel/Writer/Excel5/Xf.php
index 99f1b2a0c..0fcdc691a 100644
--- a/Classes/PHPExcel/Writer/Excel5/Xf.php
+++ b/Classes/PHPExcel/Writer/Excel5/Xf.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -66,7 +66,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_Excel5
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Excel5_Xf
 {
diff --git a/Classes/PHPExcel/Writer/Exception.php b/Classes/PHPExcel/Writer/Exception.php
index 1715587a2..5da3efd6b 100644
--- a/Classes/PHPExcel/Writer/Exception.php
+++ b/Classes/PHPExcel/Writer/Exception.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_Exception extends PHPExcel_Exception {
 	/**
diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php
index 63c5d4787..788c03cb0 100644
--- a/Classes/PHPExcel/Writer/HTML.php
+++ b/Classes/PHPExcel/Writer/HTML.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Writer_HTML
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version	##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package	PHPExcel_Writer_HTML
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter {
 	/**
diff --git a/Classes/PHPExcel/Writer/IWriter.php b/Classes/PHPExcel/Writer/IWriter.php
index f0b94b9e9..31624e502 100644
--- a/Classes/PHPExcel/Writer/IWriter.php
+++ b/Classes/PHPExcel/Writer/IWriter.php
@@ -2,7 +2,7 @@
 /**
  *  PHPExcel
  *
- *  Copyright (c) 2006 - 2014 PHPExcel
+ *  Copyright (c) 2006 - 2015 PHPExcel
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  *  @category   PHPExcel
  *  @package    PHPExcel_Writer
- *  @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  *  @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  *  @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  *  @category   PHPExcel
  *  @package    PHPExcel_Writer
- *  @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 interface PHPExcel_Writer_IWriter
 {
diff --git a/Classes/PHPExcel/Writer/OpenDocument.php b/Classes/PHPExcel/Writer/OpenDocument.php
index 2cbe6f904..ef967e092 100644
--- a/Classes/PHPExcel/Writer/OpenDocument.php
+++ b/Classes/PHPExcel/Writer/OpenDocument.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @author     Alexander Pervakov 
  * @link       http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os.html
  */
diff --git a/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php b/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php
index 88406ed1a..c85e36a02 100644
--- a/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php
+++ b/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @author     Alexander Pervakov 
  */
 class PHPExcel_Writer_OpenDocument_Cell_Comment
diff --git a/Classes/PHPExcel/Writer/OpenDocument/Content.php b/Classes/PHPExcel/Writer/OpenDocument/Content.php
index 625b35417..1f6ddc4d2 100644
--- a/Classes/PHPExcel/Writer/OpenDocument/Content.php
+++ b/Classes/PHPExcel/Writer/OpenDocument/Content.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @author     Alexander Pervakov 
  */
 class PHPExcel_Writer_OpenDocument_Content extends PHPExcel_Writer_OpenDocument_WriterPart
diff --git a/Classes/PHPExcel/Writer/OpenDocument/Meta.php b/Classes/PHPExcel/Writer/OpenDocument/Meta.php
index 7f39e5589..b1542105e 100644
--- a/Classes/PHPExcel/Writer/OpenDocument/Meta.php
+++ b/Classes/PHPExcel/Writer/OpenDocument/Meta.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @author     Alexander Pervakov 
  */
 class PHPExcel_Writer_OpenDocument_Meta extends PHPExcel_Writer_OpenDocument_WriterPart
diff --git a/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php b/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php
index 301d39db9..f4c03cf95 100644
--- a/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php
+++ b/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @author     Alexander Pervakov 
  */
 class PHPExcel_Writer_OpenDocument_MetaInf extends PHPExcel_Writer_OpenDocument_WriterPart
diff --git a/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php b/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php
index 99ff638a9..d93e4d149 100644
--- a/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php
+++ b/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @author     Alexander Pervakov 
  */
 class PHPExcel_Writer_OpenDocument_Mimetype extends PHPExcel_Writer_OpenDocument_WriterPart
diff --git a/Classes/PHPExcel/Writer/OpenDocument/Settings.php b/Classes/PHPExcel/Writer/OpenDocument/Settings.php
index 557e748d4..75363a8e8 100644
--- a/Classes/PHPExcel/Writer/OpenDocument/Settings.php
+++ b/Classes/PHPExcel/Writer/OpenDocument/Settings.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @author     Alexander Pervakov 
  */
 class PHPExcel_Writer_OpenDocument_Settings extends PHPExcel_Writer_OpenDocument_WriterPart
diff --git a/Classes/PHPExcel/Writer/OpenDocument/Styles.php b/Classes/PHPExcel/Writer/OpenDocument/Styles.php
index d88673632..e2934d108 100644
--- a/Classes/PHPExcel/Writer/OpenDocument/Styles.php
+++ b/Classes/PHPExcel/Writer/OpenDocument/Styles.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @author     Alexander Pervakov 
  */
 class PHPExcel_Writer_OpenDocument_Styles extends PHPExcel_Writer_OpenDocument_WriterPart
diff --git a/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php b/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php
index a7e85c456..b48731f5e 100644
--- a/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php
+++ b/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @author     Alexander Pervakov 
  */
 class PHPExcel_Writer_OpenDocument_Thumbnails extends PHPExcel_Writer_OpenDocument_WriterPart
diff --git a/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php b/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php
index e6e713a1b..1b2e52c3d 100644
--- a/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php
+++ b/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (c) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel_Writer_OpenDocument
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 abstract class PHPExcel_Writer_OpenDocument_WriterPart extends PHPExcel_Writer_Excel2007_WriterPart
 {
diff --git a/Classes/PHPExcel/Writer/PDF.php b/Classes/PHPExcel/Writer/PDF.php
index 3131ee0a1..8e495b410 100644
--- a/Classes/PHPExcel/Writer/PDF.php
+++ b/Classes/PHPExcel/Writer/PDF.php
@@ -2,7 +2,7 @@
 /**
  *  PHPExcel
  *
- *  Copyright (c) 2006 - 2014 PHPExcel
+ *  Copyright (c) 2006 - 2015 PHPExcel
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  *  @category    PHPExcel
  *  @package     PHPExcel_Writer_PDF
- *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  *  @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  *  @version     ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  *  @category    PHPExcel
  *  @package     PHPExcel_Writer_PDF
- *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_PDF implements PHPExcel_Writer_IWriter
 {
diff --git a/Classes/PHPExcel/Writer/PDF/Core.php b/Classes/PHPExcel/Writer/PDF/Core.php
index 3842334d9..b1693b3a7 100644
--- a/Classes/PHPExcel/Writer/PDF/Core.php
+++ b/Classes/PHPExcel/Writer/PDF/Core.php
@@ -2,7 +2,7 @@
 /**
  *  PHPExcel
  *
- *  Copyright (c) 2006 - 2014 PHPExcel
+ *  Copyright (c) 2006 - 2015 PHPExcel
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  *  @category    PHPExcel
  *  @package     PHPExcel_Writer_PDF
- *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  *  @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  *  @version     ##VERSION##, ##DATE##
  */
@@ -31,7 +31,7 @@
  *
  *  @category    PHPExcel
  *  @package     PHPExcel_Writer_PDF
- *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 abstract class PHPExcel_Writer_PDF_Core extends PHPExcel_Writer_HTML
 {
diff --git a/Classes/PHPExcel/Writer/PDF/DomPDF.php b/Classes/PHPExcel/Writer/PDF/DomPDF.php
index 01e4e0122..c695206fb 100644
--- a/Classes/PHPExcel/Writer/PDF/DomPDF.php
+++ b/Classes/PHPExcel/Writer/PDF/DomPDF.php
@@ -2,7 +2,7 @@
 /**
  *  PHPExcel
  *
- *  Copyright (c) 2006 - 2014 PHPExcel
+ *  Copyright (c) 2006 - 2015 PHPExcel
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  *  @category    PHPExcel
  *  @package     PHPExcel_Writer_PDF
- *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  *  @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  *  @version     ##VERSION##, ##DATE##
  */
@@ -39,7 +39,7 @@
  *
  *  @category    PHPExcel
  *  @package     PHPExcel_Writer_PDF
- *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_PDF_DomPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter
 {
diff --git a/Classes/PHPExcel/Writer/PDF/mPDF.php b/Classes/PHPExcel/Writer/PDF/mPDF.php
index dddc097d3..e6f0cdbab 100644
--- a/Classes/PHPExcel/Writer/PDF/mPDF.php
+++ b/Classes/PHPExcel/Writer/PDF/mPDF.php
@@ -2,7 +2,7 @@
 /**
  *  PHPExcel
  *
- *  Copyright (c) 2006 - 2014 PHPExcel
+ *  Copyright (c) 2006 - 2015 PHPExcel
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  *  @category    PHPExcel
  *  @package     PHPExcel_Writer_PDF
- *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  *  @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  *  @version     ##VERSION##, ##DATE##
  */
@@ -39,7 +39,7 @@
  *
  *  @category    PHPExcel
  *  @package     PHPExcel_Writer_PDF
- *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_PDF_mPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter
 {
diff --git a/Classes/PHPExcel/Writer/PDF/tcPDF.php b/Classes/PHPExcel/Writer/PDF/tcPDF.php
index 4e1937afc..201e0a290 100644
--- a/Classes/PHPExcel/Writer/PDF/tcPDF.php
+++ b/Classes/PHPExcel/Writer/PDF/tcPDF.php
@@ -2,7 +2,7 @@
 /**
  *  PHPExcel
  *
- *  Copyright (c) 2006 - 2014 PHPExcel
+ *  Copyright (c) 2006 - 2015 PHPExcel
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  *  @category    PHPExcel
  *  @package     PHPExcel_Writer_PDF
- *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  *  @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  *  @version     ##VERSION##, ##DATE##
  */
@@ -40,7 +40,7 @@
  *
  *  @category    PHPExcel
  *  @package     PHPExcel_Writer_PDF
- *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ *  @copyright   Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  */
 class PHPExcel_Writer_PDF_tcPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter
 {
diff --git a/Examples/01pharSimple.php b/Examples/01pharSimple.php
index a88047701..84b86cc5e 100644
--- a/Examples/01pharSimple.php
+++ b/Examples/01pharSimple.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/01simple-download-ods.php b/Examples/01simple-download-ods.php
index 574fb0113..30dbd7e35 100644
--- a/Examples/01simple-download-ods.php
+++ b/Examples/01simple-download-ods.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/01simple-download-pdf.php b/Examples/01simple-download-pdf.php
index 287b0e891..133af3a69 100644
--- a/Examples/01simple-download-pdf.php
+++ b/Examples/01simple-download-pdf.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/01simple-download-xls.php b/Examples/01simple-download-xls.php
index 60fc901bf..96bb780b5 100644
--- a/Examples/01simple-download-xls.php
+++ b/Examples/01simple-download-xls.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/01simple-download-xlsx.php b/Examples/01simple-download-xlsx.php
index 538888ea7..d441f4191 100644
--- a/Examples/01simple-download-xlsx.php
+++ b/Examples/01simple-download-xlsx.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/01simple.php b/Examples/01simple.php
index 965fefafe..5e1912b80 100644
--- a/Examples/01simple.php
+++ b/Examples/01simple.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/01simplePCLZip.php b/Examples/01simplePCLZip.php
index 0b7a46c17..0af4cbdd8 100644
--- a/Examples/01simplePCLZip.php
+++ b/Examples/01simplePCLZip.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/02types-xls.php b/Examples/02types-xls.php
index cc1dc3744..93ce17e59 100644
--- a/Examples/02types-xls.php
+++ b/Examples/02types-xls.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/02types.php b/Examples/02types.php
index ff5421e4b..6ac11c7b0 100644
--- a/Examples/02types.php
+++ b/Examples/02types.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/03formulas.php b/Examples/03formulas.php
index 1396717d7..6c5d1ddc9 100644
--- a/Examples/03formulas.php
+++ b/Examples/03formulas.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/04printing.php b/Examples/04printing.php
index 14358b05e..58d5f6a8e 100644
--- a/Examples/04printing.php
+++ b/Examples/04printing.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/05featuredemo.inc.php b/Examples/05featuredemo.inc.php
index b543ca46b..003379cce 100644
--- a/Examples/05featuredemo.inc.php
+++ b/Examples/05featuredemo.inc.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/05featuredemo.php b/Examples/05featuredemo.php
index 66d4980ec..9e502acb6 100644
--- a/Examples/05featuredemo.php
+++ b/Examples/05featuredemo.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/06largescale-with-cellcaching-sqlite.php b/Examples/06largescale-with-cellcaching-sqlite.php
index cbdb59b91..8baa7431a 100644
--- a/Examples/06largescale-with-cellcaching-sqlite.php
+++ b/Examples/06largescale-with-cellcaching-sqlite.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/06largescale-with-cellcaching-sqlite3.php b/Examples/06largescale-with-cellcaching-sqlite3.php
index ca04f85e9..1f480d1d2 100644
--- a/Examples/06largescale-with-cellcaching-sqlite3.php
+++ b/Examples/06largescale-with-cellcaching-sqlite3.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/06largescale-with-cellcaching.php b/Examples/06largescale-with-cellcaching.php
index aa23b8cbb..d20b29f24 100644
--- a/Examples/06largescale-with-cellcaching.php
+++ b/Examples/06largescale-with-cellcaching.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/06largescale-xls.php b/Examples/06largescale-xls.php
index 00137ad89..5adc3d259 100644
--- a/Examples/06largescale-xls.php
+++ b/Examples/06largescale-xls.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/06largescale.php b/Examples/06largescale.php
index b0fa44047..cb21caf50 100644
--- a/Examples/06largescale.php
+++ b/Examples/06largescale.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/07reader.php b/Examples/07reader.php
index 616b6622f..318ba1891 100644
--- a/Examples/07reader.php
+++ b/Examples/07reader.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/07readerPCLZip.php b/Examples/07readerPCLZip.php
index 90e859050..f1da9c574 100644
--- a/Examples/07readerPCLZip.php
+++ b/Examples/07readerPCLZip.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/08conditionalformatting.php b/Examples/08conditionalformatting.php
index f65ec9efd..514a8bb63 100644
--- a/Examples/08conditionalformatting.php
+++ b/Examples/08conditionalformatting.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/08conditionalformatting2.php b/Examples/08conditionalformatting2.php
index bbe084a26..aeb2a3136 100644
--- a/Examples/08conditionalformatting2.php
+++ b/Examples/08conditionalformatting2.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/09pagebreaks.php b/Examples/09pagebreaks.php
index 6b8c185e3..36e21ae4b 100644
--- a/Examples/09pagebreaks.php
+++ b/Examples/09pagebreaks.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/10autofilter-selection-1.php b/Examples/10autofilter-selection-1.php
index 7542a5295..8cdc0def4 100644
--- a/Examples/10autofilter-selection-1.php
+++ b/Examples/10autofilter-selection-1.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/10autofilter-selection-2.php b/Examples/10autofilter-selection-2.php
index c89173f5c..e2aea748d 100644
--- a/Examples/10autofilter-selection-2.php
+++ b/Examples/10autofilter-selection-2.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/10autofilter-selection-display.php b/Examples/10autofilter-selection-display.php
index cf2b8acfd..ba3fed9e0 100644
--- a/Examples/10autofilter-selection-display.php
+++ b/Examples/10autofilter-selection-display.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/10autofilter.php b/Examples/10autofilter.php
index ea3f76343..015e9cfe3 100644
--- a/Examples/10autofilter.php
+++ b/Examples/10autofilter.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/11documentsecurity-xls.php b/Examples/11documentsecurity-xls.php
index b104c7b8a..2348ce959 100644
--- a/Examples/11documentsecurity-xls.php
+++ b/Examples/11documentsecurity-xls.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/11documentsecurity.php b/Examples/11documentsecurity.php
index 96f5d9930..9fd4fb2a4 100644
--- a/Examples/11documentsecurity.php
+++ b/Examples/11documentsecurity.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/12cellProtection.php b/Examples/12cellProtection.php
index 77bfee4ce..e12c9ae47 100644
--- a/Examples/12cellProtection.php
+++ b/Examples/12cellProtection.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/13calculation.php b/Examples/13calculation.php
index 01e63ea77..e255d115f 100644
--- a/Examples/13calculation.php
+++ b/Examples/13calculation.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/14excel5.php b/Examples/14excel5.php
index 3fd3d69f3..7a9f6856f 100644
--- a/Examples/14excel5.php
+++ b/Examples/14excel5.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/15datavalidation-xls.php b/Examples/15datavalidation-xls.php
index 2f8fa5ee9..22ed62654 100644
--- a/Examples/15datavalidation-xls.php
+++ b/Examples/15datavalidation-xls.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/15datavalidation.php b/Examples/15datavalidation.php
index 932bacc6f..e6688c5f2 100644
--- a/Examples/15datavalidation.php
+++ b/Examples/15datavalidation.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/16csv.php b/Examples/16csv.php
index 71ebfd00d..813651bdd 100644
--- a/Examples/16csv.php
+++ b/Examples/16csv.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/17html.php b/Examples/17html.php
index 0dc825b04..b84f8d4ed 100644
--- a/Examples/17html.php
+++ b/Examples/17html.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/18extendedcalculation.php b/Examples/18extendedcalculation.php
index 3c6fcb492..59aeb3005 100644
--- a/Examples/18extendedcalculation.php
+++ b/Examples/18extendedcalculation.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/19namedrange.php b/Examples/19namedrange.php
index acea22b6d..7876ea58b 100644
--- a/Examples/19namedrange.php
+++ b/Examples/19namedrange.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/20readexcel5.php b/Examples/20readexcel5.php
index d99b2306f..7625c7b81 100644
--- a/Examples/20readexcel5.php
+++ b/Examples/20readexcel5.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/21pdf.php b/Examples/21pdf.php
index 11c56b2ca..b26ddb8b1 100644
--- a/Examples/21pdf.php
+++ b/Examples/21pdf.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/22heavilyformatted.php b/Examples/22heavilyformatted.php
index c17bc8683..98c7d184e 100644
--- a/Examples/22heavilyformatted.php
+++ b/Examples/22heavilyformatted.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/23sharedstyles.php b/Examples/23sharedstyles.php
index 652b4ed2f..22eadba1c 100644
--- a/Examples/23sharedstyles.php
+++ b/Examples/23sharedstyles.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/24readfilter.php b/Examples/24readfilter.php
index afa6d0c41..000d180a4 100644
--- a/Examples/24readfilter.php
+++ b/Examples/24readfilter.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/25inmemoryimage.php b/Examples/25inmemoryimage.php
index 7a3424e20..167a861a7 100644
--- a/Examples/25inmemoryimage.php
+++ b/Examples/25inmemoryimage.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/26utf8.php b/Examples/26utf8.php
index ad0b40059..112c5c73f 100644
--- a/Examples/26utf8.php
+++ b/Examples/26utf8.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/27imagesexcel5.php b/Examples/27imagesexcel5.php
index 17db771c3..a4f6a9d7d 100644
--- a/Examples/27imagesexcel5.php
+++ b/Examples/27imagesexcel5.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/28iterator.php b/Examples/28iterator.php
index 3e1e681de..92c4192a5 100644
--- a/Examples/28iterator.php
+++ b/Examples/28iterator.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/29advancedvaluebinder.php b/Examples/29advancedvaluebinder.php
index bb387f9cd..a172c6cde 100644
--- a/Examples/29advancedvaluebinder.php
+++ b/Examples/29advancedvaluebinder.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/30template.php b/Examples/30template.php
index 33d553f78..db9cbb451 100644
--- a/Examples/30template.php
+++ b/Examples/30template.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/31docproperties_write-xls.php b/Examples/31docproperties_write-xls.php
index cbb9aa352..e9a5e876a 100644
--- a/Examples/31docproperties_write-xls.php
+++ b/Examples/31docproperties_write-xls.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/31docproperties_write.php b/Examples/31docproperties_write.php
index 1b01f6fe0..4cd477956 100644
--- a/Examples/31docproperties_write.php
+++ b/Examples/31docproperties_write.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/32chartreadwrite.php b/Examples/32chartreadwrite.php
index e4c249d3f..5aeedcaeb 100644
--- a/Examples/32chartreadwrite.php
+++ b/Examples/32chartreadwrite.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-area.php b/Examples/33chartcreate-area.php
index 53fe52398..fac8ce93f 100644
--- a/Examples/33chartcreate-area.php
+++ b/Examples/33chartcreate-area.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-bar-stacked.php b/Examples/33chartcreate-bar-stacked.php
index cac29f29f..af9493f7a 100644
--- a/Examples/33chartcreate-bar-stacked.php
+++ b/Examples/33chartcreate-bar-stacked.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-bar.php b/Examples/33chartcreate-bar.php
index 14fd5d485..653675d69 100644
--- a/Examples/33chartcreate-bar.php
+++ b/Examples/33chartcreate-bar.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-column-2.php b/Examples/33chartcreate-column-2.php
index 00bf0d71b..0ade332c9 100644
--- a/Examples/33chartcreate-column-2.php
+++ b/Examples/33chartcreate-column-2.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-column.php b/Examples/33chartcreate-column.php
index ae9c6185e..67f417847 100644
--- a/Examples/33chartcreate-column.php
+++ b/Examples/33chartcreate-column.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-composite.php b/Examples/33chartcreate-composite.php
index 8ea72126c..be7ad94a7 100644
--- a/Examples/33chartcreate-composite.php
+++ b/Examples/33chartcreate-composite.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-line.php b/Examples/33chartcreate-line.php
index 145ae72e8..90c2e60c0 100644
--- a/Examples/33chartcreate-line.php
+++ b/Examples/33chartcreate-line.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-multiple-charts.php b/Examples/33chartcreate-multiple-charts.php
index a95c27633..0e5ac60e2 100644
--- a/Examples/33chartcreate-multiple-charts.php
+++ b/Examples/33chartcreate-multiple-charts.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-pie.php b/Examples/33chartcreate-pie.php
index 5af02905b..78b6293f8 100644
--- a/Examples/33chartcreate-pie.php
+++ b/Examples/33chartcreate-pie.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-radar.php b/Examples/33chartcreate-radar.php
index b8b427f3b..0c28addf0 100644
--- a/Examples/33chartcreate-radar.php
+++ b/Examples/33chartcreate-radar.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-scatter.php b/Examples/33chartcreate-scatter.php
index 250c61d7e..7fc5b5ad4 100644
--- a/Examples/33chartcreate-scatter.php
+++ b/Examples/33chartcreate-scatter.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/33chartcreate-stock.php b/Examples/33chartcreate-stock.php
index b38fd5181..465107b3a 100644
--- a/Examples/33chartcreate-stock.php
+++ b/Examples/33chartcreate-stock.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/34chartupdate.php b/Examples/34chartupdate.php
index cb586a318..f4b36c6bf 100644
--- a/Examples/34chartupdate.php
+++ b/Examples/34chartupdate.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/35chartrender.php b/Examples/35chartrender.php
index f0e79636b..62719e51d 100644
--- a/Examples/35chartrender.php
+++ b/Examples/35chartrender.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/36chartreadwriteHTML.php b/Examples/36chartreadwriteHTML.php
index b4bae11cb..3ee8242de 100644
--- a/Examples/36chartreadwriteHTML.php
+++ b/Examples/36chartreadwriteHTML.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/36chartreadwritePDF.php b/Examples/36chartreadwritePDF.php
index 10d62cd04..0a428a2b6 100644
--- a/Examples/36chartreadwritePDF.php
+++ b/Examples/36chartreadwritePDF.php
@@ -13,7 +13,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/37page_layout_view.php b/Examples/37page_layout_view.php
index 070f512a2..810ca3d21 100644
--- a/Examples/37page_layout_view.php
+++ b/Examples/37page_layout_view.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/38cloneWorksheet.php b/Examples/38cloneWorksheet.php
index 901b887ee..245f7da43 100644
--- a/Examples/38cloneWorksheet.php
+++ b/Examples/38cloneWorksheet.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/39dropdown.php b/Examples/39dropdown.php
index 5dadc0992..c8dcff67c 100644
--- a/Examples/39dropdown.php
+++ b/Examples/39dropdown.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/41password.php b/Examples/41password.php
index 7b03e4f9a..15aea7ba0 100644
--- a/Examples/41password.php
+++ b/Examples/41password.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/42richText.php b/Examples/42richText.php
index 4e99b8535..b8f994e6c 100644
--- a/Examples/42richText.php
+++ b/Examples/42richText.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/Excel2003XMLReader.php b/Examples/Excel2003XMLReader.php
index 00d96ddd8..e77f8a97a 100644
--- a/Examples/Excel2003XMLReader.php
+++ b/Examples/Excel2003XMLReader.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/GnumericReader.php b/Examples/GnumericReader.php
index 7ddd74df0..1b22e2cb3 100644
--- a/Examples/GnumericReader.php
+++ b/Examples/GnumericReader.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/OOCalcReader.php b/Examples/OOCalcReader.php
index b96dcbbc5..70f360639 100644
--- a/Examples/OOCalcReader.php
+++ b/Examples/OOCalcReader.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/OOCalcReaderPCLZip.php b/Examples/OOCalcReaderPCLZip.php
index 45a5cdacb..2fc771cdd 100644
--- a/Examples/OOCalcReaderPCLZip.php
+++ b/Examples/OOCalcReaderPCLZip.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/SylkReader.php b/Examples/SylkReader.php
index ab144e0a4..a16a4f057 100644
--- a/Examples/SylkReader.php
+++ b/Examples/SylkReader.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/XMLReader.php b/Examples/XMLReader.php
index 33eda282a..836f6b2df 100644
--- a/Examples/XMLReader.php
+++ b/Examples/XMLReader.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */
diff --git a/Examples/runall.php b/Examples/runall.php
index b2af1ccd0..e7707f811 100644
--- a/Examples/runall.php
+++ b/Examples/runall.php
@@ -2,7 +2,7 @@
 /**
  * PHPExcel
  *
- * Copyright (C) 2006 - 2014 PHPExcel
+ * Copyright (c) 2006 - 2015 PHPExcel
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
  *
  * @category   PHPExcel
  * @package    PHPExcel
- * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
  * @version    ##VERSION##, ##DATE##
  */

From e83c359c7c8e5798feb0a7790e90a5efa896f00f Mon Sep 17 00:00:00 2001
From: MarkBaker 
Date: Sun, 3 May 2015 23:37:32 +0100
Subject: [PATCH 337/467] Move toward PSR-2 coding standards

---
 Classes/PHPExcel.php                          | 813 +++++++++---------
 Classes/PHPExcel/Autoloader.php               |  62 +-
 Classes/PHPExcel/CachedObjectStorage/APC.php  | 145 ++--
 .../CachedObjectStorage/CacheBase.php         | 744 ++++++++--------
 .../PHPExcel/CachedObjectStorage/DiscISAM.php | 427 +++++----
 .../PHPExcel/CachedObjectStorage/ICache.php   | 113 ++-
 .../PHPExcel/CachedObjectStorage/Igbinary.php | 301 ++++---
 .../PHPExcel/CachedObjectStorage/Memcache.php | 620 +++++++------
 .../PHPExcel/CachedObjectStorage/Memory.php   | 243 +++---
 .../CachedObjectStorage/MemoryGZip.php        | 270 +++---
 .../CachedObjectStorage/MemorySerialized.php  | 266 +++---
 .../PHPExcel/CachedObjectStorage/PHPTemp.php  | 406 +++++----
 .../PHPExcel/CachedObjectStorage/SQLite.php   | 613 ++++++-------
 .../PHPExcel/CachedObjectStorage/SQLite3.php  | 691 +++++++--------
 .../PHPExcel/CachedObjectStorage/Wincache.php | 583 +++++++------
 .../PHPExcel/CachedObjectStorageFactory.php   |  86 +-
 .../CalcEngine/CyclicReferenceStack.php       | 132 ++-
 Classes/PHPExcel/CalcEngine/Logger.php        | 236 +++--
 Classes/PHPExcel/Calculation/Token/Stack.php  | 167 ++--
 19 files changed, 3412 insertions(+), 3506 deletions(-)

diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php
index c94fa9754..c3ec05197 100644
--- a/Classes/PHPExcel.php
+++ b/Classes/PHPExcel.php
@@ -1,4 +1,11 @@
 _hasMacros;
-	}
-
-	/**
-	* Define if a workbook has macros
-	*
-	* @param true|false
-	*/
-	public function setHasMacros($hasMacros=false){
-		$this->_hasMacros=(bool)$hasMacros;
-	}
-
-	/**
-	* Set the macros code
-	*
-	* @param binary string|null
-	*/
-	public function setMacrosCode($MacrosCode){
-		$this->_macrosCode=$MacrosCode;
-		$this->setHasMacros(!is_null($MacrosCode));
-	}
-
-	/**
-	* Return the macros code
-	*
-	* @return binary|null
-	*/
-	public function getMacrosCode(){
-		return $this->_macrosCode;
-	}
-
-	/**
-	* Set the macros certificate
-	*
-	* @param binary|null
-	*/
-	public function setMacrosCertificate($Certificate=NULL){
-		$this->_macrosCertificate=$Certificate;
-	}
-
-	/**
-	* Is the project signed ?
-	*
-	* @return true|false
-	*/
-	public function hasMacrosCertificate(){
-		return !is_null($this->_macrosCertificate);
-	}
-
-	/**
-	* Return the macros certificate
-	*
-	* @return binary|null
-	*/
-	public function getMacrosCertificate(){
-		return $this->_macrosCertificate;
-	}
-
-	/**
-	* Remove all macros, certificate from spreadsheet
-	*
-	* @param none
-	* @return void
-	*/
-	public function discardMacros(){
-		$this->_hasMacros=false;
-		$this->_macrosCode=NULL;
-		$this->_macrosCertificate=NULL;
-	}
-
-	/**
-	* set ribbon XML data
-	*
-	*/
-	public function setRibbonXMLData($Target=NULL, $XMLData=NULL){
-		if(!is_null($Target) && !is_null($XMLData)){
-			$this->_ribbonXMLData=array('target'=>$Target, 'data'=>$XMLData);
-		}else{
-			$this->_ribbonXMLData=NULL;
-		}
-	}
-
-	/**
-	* retrieve ribbon XML Data
-	*
-	* return string|null|array
-	*/
-	public function getRibbonXMLData($What='all'){//we need some constants here...
-		$ReturnData=NULL;
-		$What=strtolower($What);
-		switch($What){
-		case 'all':
-			$ReturnData=$this->_ribbonXMLData;
-			break;
-		case 'target':
-		case 'data':
-			if(is_array($this->_ribbonXMLData) && array_key_exists($What,$this->_ribbonXMLData)){
-				$ReturnData=$this->_ribbonXMLData[$What];
-			}//else $ReturnData stay at null
-			break;
-		}//default: $ReturnData at null
-		return $ReturnData;
-	}
-
-	/**
-	* store binaries ribbon objects (pictures)
-	*
-	*/
-	public function setRibbonBinObjects($BinObjectsNames=NULL, $BinObjectsData=NULL){
-		if(!is_null($BinObjectsNames) && !is_null($BinObjectsData)){
-			$this->_ribbonBinObjects=array('names'=>$BinObjectsNames, 'data'=>$BinObjectsData);
-		}else{
-			$this->_ribbonBinObjects=NULL;
-		}
-	}
-	/**
-	* return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function)
-	*
-	*/
-	private function _getExtensionOnly($ThePath){
-		return pathinfo($ThePath, PATHINFO_EXTENSION);
-	}
-
-	/**
-	* retrieve Binaries Ribbon Objects
-	*
-	*/
-	public function getRibbonBinObjects($What='all'){
-		$ReturnData=NULL;
-		$What=strtolower($What);
-		switch($What){
-		case 'all':
-			return $this->_ribbonBinObjects;
-			break;
-		case 'names':
-		case 'data':
-			if(is_array($this->_ribbonBinObjects) && array_key_exists($What, $this->_ribbonBinObjects)){
-				$ReturnData=$this->_ribbonBinObjects[$What];
-			}
-			break;
-		case 'types':
-			if(is_array($this->_ribbonBinObjects) && array_key_exists('data', $this->_ribbonBinObjects) && is_array($this->_ribbonBinObjects['data'])){
-				$tmpTypes=array_keys($this->_ribbonBinObjects['data']);
-				$ReturnData=array_unique(array_map(array($this,'_getExtensionOnly'), $tmpTypes));
-			}else
-				$ReturnData=array();//the caller want an array... not null if empty
-			break;
-		}
-		return $ReturnData;
-	}
-
-	/**
-	* This workbook have a custom UI ?
-	*
-	* @return true|false
-	*/
-	public function hasRibbon(){
-		return !is_null($this->_ribbonXMLData);
-	}
-
-	/**
-	* This workbook have additionnal object for the ribbon ?
-	*
-	* @return true|false
-	*/
-	public function hasRibbonBinObjects(){
-		return !is_null($this->_ribbonBinObjects);
-	}
-
-	/**
+    private $cellStyleXfCollection = array();
+
+    /**
+    * hasMacros : this workbook have macros ?
+    *
+    * @var bool
+    */
+    private $hasMacros = false;
+
+    /**
+    * macrosCode : all macros code (the vbaProject.bin file, this include form, code,  etc.), null if no macro
+    *
+    * @var binary
+    */
+    private $macrosCode;
+    /**
+    * macrosCertificate : if macros are signed, contains vbaProjectSignature.bin file, null if not signed
+    *
+    * @var binary
+    */
+    private $macrosCertificate;
+
+    /**
+    * ribbonXMLData : null if workbook is'nt Excel 2007 or not contain a customized UI
+    *
+    * @var null|string
+    */
+    private $ribbonXMLData;
+
+    /**
+    * ribbonBinObjects : null if workbook is'nt Excel 2007 or not contain embedded objects (picture(s)) for Ribbon Elements
+    * ignored if $ribbonXMLData is null
+    *
+    * @var null|array
+    */
+    private $ribbonBinObjects;
+
+    /**
+    * The workbook has macros ?
+    *
+    * @return true if workbook has macros, false if not
+    */
+    public function hasMacros()
+    {
+        return $this->hasMacros;
+    }
+
+    /**
+    * Define if a workbook has macros
+    *
+    * @param boolean $hasMacros true|false
+    */
+    public function setHasMacros($hasMacros = false)
+    {
+        $this->hasMacros = (bool) $hasMacros;
+    }
+
+    /**
+    * Set the macros code
+    *
+    * @param string $MacrosCode string|null
+    */
+    public function setMacrosCode($MacrosCode = null)
+    {
+        $this->macrosCode=$MacrosCode;
+        $this->setHasMacros(!is_null($MacrosCode));
+    }
+
+    /**
+    * Return the macros code
+    *
+    * @return string|null
+    */
+    public function getMacrosCode()
+    {
+        return $this->macrosCode;
+    }
+
+    /**
+    * Set the macros certificate
+    *
+    * @param string|null $Certificate
+    */
+    public function setMacrosCertificate($Certificate = null)
+    {
+        $this->macrosCertificate=$Certificate;
+    }
+
+    /**
+    * Is the project signed ?
+    *
+    * @return boolean true|false
+    */
+    public function hasMacrosCertificate()
+    {
+        return !is_null($this->macrosCertificate);
+    }
+
+    /**
+    * Return the macros certificate
+    *
+    * @return string|null
+    */
+    public function getMacrosCertificate()
+    {
+        return $this->macrosCertificate;
+    }
+
+    /**
+    * Remove all macros, certificate from spreadsheet
+    *
+    */
+    public function discardMacros()
+    {
+        $this->hasMacros=false;
+        $this->macrosCode=null;
+        $this->macrosCertificate=null;
+    }
+
+    /**
+    * set ribbon XML data
+    *
+    */
+    public function setRibbonXMLData($Target = null, $XMLData = null)
+    {
+        if (!is_null($Target) && !is_null($XMLData)) {
+            $this->ribbonXMLData = array('target' => $Target, 'data' => $XMLData);
+        } else {
+            $this->ribbonXMLData = null;
+        }
+    }
+
+    /**
+    * retrieve ribbon XML Data
+    *
+    * return string|null|array
+    */
+    public function getRibbonXMLData($What = 'all') //we need some constants here...
+    {
+        $ReturnData = null;
+        $What = strtolower($What);
+        switch ($What){
+            case 'all':
+                $ReturnData = $this->ribbonXMLData;
+                break;
+            case 'target':
+            case 'data':
+                if (is_array($this->ribbonXMLData) && array_key_exists($What, $this->ribbonXMLData)) {
+                    $ReturnData = $this->ribbonXMLData[$What];
+                }
+                break;
+        }
+
+        return $ReturnData;
+    }
+
+    /**
+    * store binaries ribbon objects (pictures)
+    *
+    */
+    public function setRibbonBinObjects($BinObjectsNames = null, $BinObjectsData = null)
+    {
+        if (!is_null($BinObjectsNames) && !is_null($BinObjectsData)) {
+            $this->ribbonBinObjects = array('names' => $BinObjectsNames, 'data' => $BinObjectsData);
+        } else {
+            $this->ribbonBinObjects = null;
+        }
+    }
+    /**
+    * return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function)
+    *
+    */
+    private function getExtensionOnly($ThePath)
+    {
+        return pathinfo($ThePath, PATHINFO_EXTENSION);
+    }
+
+    /**
+    * retrieve Binaries Ribbon Objects
+    *
+    */
+    public function getRibbonBinObjects($What = 'all')
+    {
+        $ReturnData = null;
+        $What = strtolower($What);
+        switch($What) {
+            case 'all':
+                return $this->ribbonBinObjects;
+                break;
+            case 'names':
+            case 'data':
+                if (is_array($this->ribbonBinObjects) && array_key_exists($What, $this->ribbonBinObjects)) {
+                    $ReturnData=$this->ribbonBinObjects[$What];
+                }
+                break;
+            case 'types':
+                if (is_array($this->ribbonBinObjects) &&
+                    array_key_exists('data', $this->ribbonBinObjects) && is_array($this->ribbonBinObjects['data'])) {
+                    $tmpTypes=array_keys($this->ribbonBinObjects['data']);
+                    $ReturnData = array_unique(array_map(array($this, 'getExtensionOnly'), $tmpTypes));
+                } else {
+                    $ReturnData=array(); // the caller want an array... not null if empty
+                }
+                break;
+        }
+        return $ReturnData;
+    }
+
+    /**
+    * This workbook have a custom UI ?
+    *
+    * @return true|false
+    */
+    public function hasRibbon()
+    {
+        return !is_null($this->ribbonXMLData);
+    }
+
+    /**
+    * This workbook have additionnal object for the ribbon ?
+    *
+    * @return true|false
+    */
+    public function hasRibbonBinObjects()
+    {
+        return !is_null($this->ribbonBinObjects);
+    }
+
+    /**
      * Check if a sheet with a specified code name already exists
      *
      * @param string $pSheetCodeName  Name of the worksheet to check
@@ -330,52 +337,52 @@ public function hasRibbonBinObjects(){
      */
     public function sheetCodeNameExists($pSheetCodeName)
     {
-		return ($this->getSheetByCodeName($pSheetCodeName) !== NULL);
+        return ($this->getSheetByCodeName($pSheetCodeName) !== null);
     }
 
-	/**
-	 * Get sheet by code name. Warning : sheet don't have always a code name !
-	 *
-	 * @param string $pName Sheet name
-	 * @return PHPExcel_Worksheet
-	 */
-	public function getSheetByCodeName($pName = '')
-	{
-		$worksheetCount = count($this->_workSheetCollection);
-		for ($i = 0; $i < $worksheetCount; ++$i) {
-			if ($this->_workSheetCollection[$i]->getCodeName() == $pName) {
-				return $this->_workSheetCollection[$i];
-			}
-		}
-
-		return null;
-	}
-
-	 /**
-	 * Create a new PHPExcel with one Worksheet
-	 */
-	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);
-		$this->_activeSheetIndex = 0;
+    /**
+     * Get sheet by code name. Warning : sheet don't have always a code name !
+     *
+     * @param string $pName Sheet name
+     * @return PHPExcel_Worksheet
+     */
+    public function getSheetByCodeName($pName = '')
+    {
+        $worksheetCount = count($this->workSheetCollection);
+        for ($i = 0; $i < $worksheetCount; ++$i) {
+            if ($this->workSheetCollection[$i]->getCodeName() == $pName) {
+                return $this->workSheetCollection[$i];
+            }
+        }
+
+        return null;
+    }
+
+     /**
+     * Create a new PHPExcel with one Worksheet
+     */
+    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);
+        $this->activeSheetIndex = 0;
 
         // Create document properties
-        $this->_properties = new PHPExcel_DocumentProperties();
+        $this->properties = new PHPExcel_DocumentProperties();
 
         // Create document security
-        $this->_security = new PHPExcel_DocumentSecurity();
+        $this->security = new PHPExcel_DocumentSecurity();
 
         // Set named ranges
-        $this->_namedRanges = array();
+        $this->namedRanges = array();
 
         // Create the cellXf supervisor
-        $this->_cellXfSupervisor = new PHPExcel_Style(true);
-        $this->_cellXfSupervisor->bindParent($this);
+        $this->cellXfSupervisor = new PHPExcel_Style(true);
+        $this->cellXfSupervisor->bindParent($this);
 
         // Create the default style
         $this->addCellXf(new PHPExcel_Style);
@@ -386,10 +393,11 @@ public function __construct()
      * Code to execute when this worksheet is unset()
      *
      */
-    public function __destruct() {
+    public function __destruct()
+    {
         PHPExcel_Calculation::unsetInstance($this);
         $this->disconnectWorksheets();
-    }    //    function __destruct()
+    }
 
     /**
      * Disconnect all worksheets from this PHPExcel workbook object,
@@ -398,24 +406,24 @@ public function __destruct() {
      */
     public function disconnectWorksheets()
     {
-    	$worksheet = NULL;
-        foreach($this->_workSheetCollection as $k => &$worksheet) {
+        $worksheet = null;
+        foreach ($this->workSheetCollection as $k => &$worksheet) {
             $worksheet->disconnectCells();
-            $this->_workSheetCollection[$k] = null;
+            $this->workSheetCollection[$k] = null;
         }
         unset($worksheet);
-        $this->_workSheetCollection = array();
+        $this->workSheetCollection = array();
     }
 
-	/**
-	 * Return the calculation engine for this worksheet
-	 *
-	 * @return PHPExcel_Calculation
-	 */
-	public function getCalculationEngine()
-	{
-		return $this->_calculationEngine;
-	}	//	function getCellCacheController()
+    /**
+     * Return the calculation engine for this worksheet
+     *
+     * @return PHPExcel_Calculation
+     */
+    public function getCalculationEngine()
+    {
+        return $this->calculationEngine;
+    }    //    function getCellCacheController()
 
     /**
      * Get properties
@@ -424,7 +432,7 @@ public function getCalculationEngine()
      */
     public function getProperties()
     {
-        return $this->_properties;
+        return $this->properties;
     }
 
     /**
@@ -434,7 +442,7 @@ public function getProperties()
      */
     public function setProperties(PHPExcel_DocumentProperties $pValue)
     {
-        $this->_properties = $pValue;
+        $this->properties = $pValue;
     }
 
     /**
@@ -444,7 +452,7 @@ public function setProperties(PHPExcel_DocumentProperties $pValue)
      */
     public function getSecurity()
     {
-        return $this->_security;
+        return $this->security;
     }
 
     /**
@@ -454,7 +462,7 @@ public function getSecurity()
      */
     public function setSecurity(PHPExcel_DocumentSecurity $pValue)
     {
-        $this->_security = $pValue;
+        $this->security = $pValue;
     }
 
     /**
@@ -466,7 +474,7 @@ public function setSecurity(PHPExcel_DocumentSecurity $pValue)
      */
     public function getActiveSheet()
     {
-        return $this->getSheet($this->_activeSheetIndex);
+        return $this->getSheet($this->activeSheetIndex);
     }
 
     /**
@@ -476,7 +484,7 @@ public function getActiveSheet()
      * @return PHPExcel_Worksheet
      * @throws PHPExcel_Exception
      */
-    public function createSheet($iSheetIndex = NULL)
+    public function createSheet($iSheetIndex = null)
     {
         $newSheet = new PHPExcel_Worksheet($this);
         $this->addSheet($newSheet, $iSheetIndex);
@@ -491,7 +499,7 @@ public function createSheet($iSheetIndex = NULL)
      */
     public function sheetNameExists($pSheetName)
     {
-        return ($this->getSheetByName($pSheetName) !== NULL);
+        return ($this->getSheetByName($pSheetName) !== null);
     }
 
     /**
@@ -502,31 +510,31 @@ public function sheetNameExists($pSheetName)
      * @return PHPExcel_Worksheet
      * @throws PHPExcel_Exception
      */
-    public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = NULL)
+    public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null)
     {
         if ($this->sheetNameExists($pSheet->getTitle())) {
             throw new PHPExcel_Exception(
-            	"Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first."
+                "Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first."
             );
         }
 
-        if($iSheetIndex === NULL) {
-            if ($this->_activeSheetIndex < 0) {
-                $this->_activeSheetIndex = 0;
+        if ($iSheetIndex === null) {
+            if ($this->activeSheetIndex < 0) {
+                $this->activeSheetIndex = 0;
             }
-            $this->_workSheetCollection[] = $pSheet;
+            $this->workSheetCollection[] = $pSheet;
         } else {
             // Insert the sheet at the requested index
             array_splice(
-                $this->_workSheetCollection,
+                $this->workSheetCollection,
                 $iSheetIndex,
                 0,
                 array($pSheet)
-                );
+            );
 
             // Adjust active sheet index if necessary
-            if ($this->_activeSheetIndex >= $iSheetIndex) {
-                ++$this->_activeSheetIndex;
+            if ($this->activeSheetIndex >= $iSheetIndex) {
+                ++$this->activeSheetIndex;
             }
         }
 
@@ -546,19 +554,18 @@ public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = NULL)
     public function removeSheetByIndex($pIndex = 0)
     {
 
-        $numSheets = count($this->_workSheetCollection);
-
+        $numSheets = count($this->workSheetCollection);
         if ($pIndex > $numSheets - 1) {
             throw new PHPExcel_Exception(
-            	"You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
+                "You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
             );
         } else {
-            array_splice($this->_workSheetCollection, $pIndex, 1);
+            array_splice($this->workSheetCollection, $pIndex, 1);
         }
         // Adjust active sheet index if necessary
-        if (($this->_activeSheetIndex >= $pIndex) &&
-            ($pIndex > count($this->_workSheetCollection) - 1)) {
-            --$this->_activeSheetIndex;
+        if (($this->activeSheetIndex >= $pIndex) &&
+            ($pIndex > count($this->workSheetCollection) - 1)) {
+            --$this->activeSheetIndex;
         }
 
     }
@@ -572,14 +579,14 @@ public function removeSheetByIndex($pIndex = 0)
      */
     public function getSheet($pIndex = 0)
     {
-        if (!isset($this->_workSheetCollection[$pIndex])) {
+        if (!isset($this->workSheetCollection[$pIndex])) {
             $numSheets = $this->getSheetCount();
             throw new PHPExcel_Exception(
                 "Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}."
             );
         }
 
-        return $this->_workSheetCollection[$pIndex];
+        return $this->workSheetCollection[$pIndex];
     }
 
     /**
@@ -589,7 +596,7 @@ public function getSheet($pIndex = 0)
      */
     public function getAllSheets()
     {
-        return $this->_workSheetCollection;
+        return $this->workSheetCollection;
     }
 
     /**
@@ -600,14 +607,14 @@ public function getAllSheets()
      */
     public function getSheetByName($pName = '')
     {
-        $worksheetCount = count($this->_workSheetCollection);
+        $worksheetCount = count($this->workSheetCollection);
         for ($i = 0; $i < $worksheetCount; ++$i) {
-            if ($this->_workSheetCollection[$i]->getTitle() === $pName) {
-                return $this->_workSheetCollection[$i];
+            if ($this->workSheetCollection[$i]->getTitle() === $pName) {
+                return $this->workSheetCollection[$i];
             }
         }
 
-        return NULL;
+        return null;
     }
 
     /**
@@ -619,7 +626,7 @@ public function getSheetByName($pName = '')
      */
     public function getIndex(PHPExcel_Worksheet $pSheet)
     {
-        foreach ($this->_workSheetCollection as $key => $value) {
+        foreach ($this->workSheetCollection as $key => $value) {
             if ($value->getHashCode() == $pSheet->getHashCode()) {
                 return $key;
             }
@@ -640,12 +647,12 @@ public function setIndexByName($sheetName, $newIndex)
     {
         $oldIndex = $this->getIndex($this->getSheetByName($sheetName));
         $pSheet = array_splice(
-            $this->_workSheetCollection,
+            $this->workSheetCollection,
             $oldIndex,
             1
         );
         array_splice(
-            $this->_workSheetCollection,
+            $this->workSheetCollection,
             $newIndex,
             0,
             $pSheet
@@ -660,7 +667,7 @@ public function setIndexByName($sheetName, $newIndex)
      */
     public function getSheetCount()
     {
-        return count($this->_workSheetCollection);
+        return count($this->workSheetCollection);
     }
 
     /**
@@ -670,7 +677,7 @@ public function getSheetCount()
      */
     public function getActiveSheetIndex()
     {
-        return $this->_activeSheetIndex;
+        return $this->activeSheetIndex;
     }
 
     /**
@@ -682,14 +689,14 @@ public function getActiveSheetIndex()
      */
     public function setActiveSheetIndex($pIndex = 0)
     {
-        $numSheets = count($this->_workSheetCollection);
+        $numSheets = count($this->workSheetCollection);
 
         if ($pIndex > $numSheets - 1) {
             throw new PHPExcel_Exception(
-            	"You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
+                "You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
             );
         } else {
-            $this->_activeSheetIndex = $pIndex;
+            $this->activeSheetIndex = $pIndex;
         }
         return $this->getActiveSheet();
     }
@@ -735,13 +742,14 @@ public function getSheetNames()
      * @throws PHPExcel_Exception
      * @return PHPExcel_Worksheet
      */
-    public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null) {
+    public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null)
+    {
         if ($this->sheetNameExists($pSheet->getTitle())) {
             throw new PHPExcel_Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first.");
         }
 
         // count how many cellXfs there are in this workbook currently, we will need this below
-        $countCellXfs = count($this->_cellXfCollection);
+        $countCellXfs = count($this->cellXfCollection);
 
         // copy all the shared cellXfs from the external workbook and append them to the current
         foreach ($pSheet->getParent()->getCellXfCollection() as $cellXf) {
@@ -754,7 +762,7 @@ public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null
         // update the cellXfs
         foreach ($pSheet->getCellCollection(false) as $cellID) {
             $cell = $pSheet->getCell($cellID);
-            $cell->setXfIndex( $cell->getXfIndex() + $countCellXfs );
+            $cell->setXfIndex($cell->getXfIndex() + $countCellXfs);
         }
 
         return $this->addSheet($pSheet, $iSheetIndex);
@@ -765,8 +773,9 @@ public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null
      *
      * @return PHPExcel_NamedRange[]
      */
-    public function getNamedRanges() {
-        return $this->_namedRanges;
+    public function getNamedRanges()
+    {
+        return $this->namedRanges;
     }
 
     /**
@@ -775,13 +784,14 @@ public function getNamedRanges() {
      * @param  PHPExcel_NamedRange $namedRange
      * @return PHPExcel
      */
-    public function addNamedRange(PHPExcel_NamedRange $namedRange) {
+    public function addNamedRange(PHPExcel_NamedRange $namedRange)
+    {
         if ($namedRange->getScope() == null) {
             // global scope
-            $this->_namedRanges[$namedRange->getName()] = $namedRange;
+            $this->namedRanges[$namedRange->getName()] = $namedRange;
         } else {
             // local scope
-            $this->_namedRanges[$namedRange->getScope()->getTitle().'!'.$namedRange->getName()] = $namedRange;
+            $this->namedRanges[$namedRange->getScope()->getTitle().'!'.$namedRange->getName()] = $namedRange;
         }
         return true;
     }
@@ -793,18 +803,19 @@ public function addNamedRange(PHPExcel_NamedRange $namedRange) {
      * @param  PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope
      * @return PHPExcel_NamedRange|null
      */
-    public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {
+    public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null)
+    {
         $returnValue = null;
 
-        if ($namedRange != '' && ($namedRange !== NULL)) {
+        if ($namedRange != '' && ($namedRange !== null)) {
             // first look for global defined name
-            if (isset($this->_namedRanges[$namedRange])) {
-                $returnValue = $this->_namedRanges[$namedRange];
+            if (isset($this->namedRanges[$namedRange])) {
+                $returnValue = $this->namedRanges[$namedRange];
             }
 
             // then look for local defined name (has priority over global defined name if both names exist)
-            if (($pSheet !== NULL) && isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
-                $returnValue = $this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange];
+            if (($pSheet !== null) && isset($this->namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
+                $returnValue = $this->namedRanges[$pSheet->getTitle() . '!' . $namedRange];
             }
         }
 
@@ -818,14 +829,15 @@ public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {
      * @param  PHPExcel_Worksheet|null  $pSheet  Scope: use null for global scope.
      * @return PHPExcel
      */
-    public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {
-        if ($pSheet === NULL) {
-            if (isset($this->_namedRanges[$namedRange])) {
-                unset($this->_namedRanges[$namedRange]);
+    public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null)
+    {
+        if ($pSheet === null) {
+            if (isset($this->namedRanges[$namedRange])) {
+                unset($this->namedRanges[$namedRange]);
             }
         } else {
-            if (isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
-                unset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange]);
+            if (isset($this->namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
+                unset($this->namedRanges[$pSheet->getTitle() . '!' . $namedRange]);
             }
         }
         return $this;
@@ -836,7 +848,8 @@ public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null)
      *
      * @return PHPExcel_WorksheetIterator
      */
-    public function getWorksheetIterator() {
+    public function getWorksheetIterator()
+    {
         return new PHPExcel_WorksheetIterator($this);
     }
 
@@ -845,13 +858,14 @@ public function getWorksheetIterator() {
      *
      * @return PHPExcel
      */
-    public function copy() {
+    public function copy()
+    {
         $copied = clone $this;
 
-        $worksheetCount = count($this->_workSheetCollection);
+        $worksheetCount = count($this->workSheetCollection);
         for ($i = 0; $i < $worksheetCount; ++$i) {
-            $this->_workSheetCollection[$i] = $this->_workSheetCollection[$i]->copy();
-            $this->_workSheetCollection[$i]->rebindParent($this);
+            $this->workSheetCollection[$i] = $this->workSheetCollection[$i]->copy();
+            $this->workSheetCollection[$i]->rebindParent($this);
         }
 
         return $copied;
@@ -860,8 +874,9 @@ public function copy() {
     /**
      * Implement PHP __clone to create a deep clone, not just a shallow copy.
      */
-    public function __clone() {
-        foreach($this as $key => $val) {
+    public function __clone()
+    {
+        foreach ($this as $key => $val) {
             if (is_object($val) || (is_array($val))) {
                 $this->{$key} = unserialize(serialize($val));
             }
@@ -875,7 +890,7 @@ public function __clone() {
      */
     public function getCellXfCollection()
     {
-        return $this->_cellXfCollection;
+        return $this->cellXfCollection;
     }
 
     /**
@@ -886,7 +901,7 @@ public function getCellXfCollection()
      */
     public function getCellXfByIndex($pIndex = 0)
     {
-        return $this->_cellXfCollection[$pIndex];
+        return $this->cellXfCollection[$pIndex];
     }
 
     /**
@@ -897,7 +912,7 @@ public function getCellXfByIndex($pIndex = 0)
      */
     public function getCellXfByHashCode($pValue = '')
     {
-        foreach ($this->_cellXfCollection as $cellXf) {
+        foreach ($this->cellXfCollection as $cellXf) {
             if ($cellXf->getHashCode() == $pValue) {
                 return $cellXf;
             }
@@ -913,7 +928,7 @@ public function getCellXfByHashCode($pValue = '')
      */
     public function cellXfExists($pCellStyle = null)
     {
-        return in_array($pCellStyle, $this->_cellXfCollection, true);
+        return in_array($pCellStyle, $this->cellXfCollection, true);
     }
 
     /**
@@ -924,8 +939,8 @@ public function cellXfExists($pCellStyle = null)
      */
     public function getDefaultStyle()
     {
-        if (isset($this->_cellXfCollection[0])) {
-            return $this->_cellXfCollection[0];
+        if (isset($this->cellXfCollection[0])) {
+            return $this->cellXfCollection[0];
         }
         throw new PHPExcel_Exception('No default style found for this workbook');
     }
@@ -937,33 +952,33 @@ public function getDefaultStyle()
      */
     public function addCellXf(PHPExcel_Style $style)
     {
-        $this->_cellXfCollection[] = $style;
-        $style->setIndex(count($this->_cellXfCollection) - 1);
+        $this->cellXfCollection[] = $style;
+        $style->setIndex(count($this->cellXfCollection) - 1);
     }
 
     /**
      * Remove cellXf by index. It is ensured that all cells get their xf index updated.
      *
-     * @param  int $pIndex Index to cellXf
+     * @param integer $pIndex Index to cellXf
      * @throws PHPExcel_Exception
      */
     public function removeCellXfByIndex($pIndex = 0)
     {
-        if ($pIndex > count($this->_cellXfCollection) - 1) {
+        if ($pIndex > count($this->cellXfCollection) - 1) {
             throw new PHPExcel_Exception("CellXf index is out of bounds.");
         } else {
             // first remove the cellXf
-            array_splice($this->_cellXfCollection, $pIndex, 1);
+            array_splice($this->cellXfCollection, $pIndex, 1);
 
             // then update cellXf indexes for cells
-            foreach ($this->_workSheetCollection as $worksheet) {
+            foreach ($this->workSheetCollection as $worksheet) {
                 foreach ($worksheet->getCellCollection(false) as $cellID) {
                     $cell = $worksheet->getCell($cellID);
                     $xfIndex = $cell->getXfIndex();
-                    if ($xfIndex > $pIndex ) {
+                    if ($xfIndex > $pIndex) {
                         // decrease xf index by 1
                         $cell->setXfIndex($xfIndex - 1);
-                    } else if ($xfIndex == $pIndex) {
+                    } elseif ($xfIndex == $pIndex) {
                         // set to default xf index 0
                         $cell->setXfIndex(0);
                     }
@@ -979,7 +994,7 @@ public function removeCellXfByIndex($pIndex = 0)
      */
     public function getCellXfSupervisor()
     {
-        return $this->_cellXfSupervisor;
+        return $this->cellXfSupervisor;
     }
 
     /**
@@ -989,18 +1004,18 @@ public function getCellXfSupervisor()
      */
     public function getCellStyleXfCollection()
     {
-        return $this->_cellStyleXfCollection;
+        return $this->cellStyleXfCollection;
     }
 
     /**
      * Get cellStyleXf by index
      *
-     * @param  int $pIndex
+     * @param integer $pIndex Index to cellXf
      * @return PHPExcel_Style
      */
     public function getCellStyleXfByIndex($pIndex = 0)
     {
-        return $this->_cellStyleXfCollection[$pIndex];
+        return $this->cellStyleXfCollection[$pIndex];
     }
 
     /**
@@ -1011,7 +1026,7 @@ public function getCellStyleXfByIndex($pIndex = 0)
      */
     public function getCellStyleXfByHashCode($pValue = '')
     {
-        foreach ($this->_cellStyleXfCollection as $cellStyleXf) {
+        foreach ($this->cellStyleXfCollection as $cellStyleXf) {
             if ($cellStyleXf->getHashCode() == $pValue) {
                 return $cellStyleXf;
             }
@@ -1026,22 +1041,22 @@ public function getCellStyleXfByHashCode($pValue = '')
      */
     public function addCellStyleXf(PHPExcel_Style $pStyle)
     {
-        $this->_cellStyleXfCollection[] = $pStyle;
-        $pStyle->setIndex(count($this->_cellStyleXfCollection) - 1);
+        $this->cellStyleXfCollection[] = $pStyle;
+        $pStyle->setIndex(count($this->cellStyleXfCollection) - 1);
     }
 
     /**
      * Remove cellStyleXf by index
      *
-     * @param int $pIndex
+     * @param integer $pIndex Index to cellXf
      * @throws PHPExcel_Exception
      */
     public function removeCellStyleXfByIndex($pIndex = 0)
     {
-        if ($pIndex > count($this->_cellStyleXfCollection) - 1) {
+        if ($pIndex > count($this->cellStyleXfCollection) - 1) {
             throw new PHPExcel_Exception("CellStyleXf index is out of bounds.");
         } else {
-            array_splice($this->_cellStyleXfCollection, $pIndex, 1);
+            array_splice($this->cellStyleXfCollection, $pIndex, 1);
         }
     }
 
@@ -1053,12 +1068,11 @@ public function garbageCollect()
     {
         // how many references are there to each cellXf ?
         $countReferencesCellXf = array();
-        foreach ($this->_cellXfCollection as $index => $cellXf) {
+        foreach ($this->cellXfCollection as $index => $cellXf) {
             $countReferencesCellXf[$index] = 0;
         }
 
         foreach ($this->getWorksheetIterator() as $sheet) {
-
             // from cells
             foreach ($sheet->getCellCollection(false) as $cellID) {
                 $cell = $sheet->getCell($cellID);
@@ -1081,48 +1095,47 @@ public function garbageCollect()
         // remove cellXfs without references and create mapping so we can update xfIndex
         // for all cells and columns
         $countNeededCellXfs = 0;
-        foreach ($this->_cellXfCollection as $index => $cellXf) {
+        foreach ($this->cellXfCollection as $index => $cellXf) {
             if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf
                 ++$countNeededCellXfs;
             } else {
-                unset($this->_cellXfCollection[$index]);
+                unset($this->cellXfCollection[$index]);
             }
             $map[$index] = $countNeededCellXfs - 1;
         }
-        $this->_cellXfCollection = array_values($this->_cellXfCollection);
+        $this->cellXfCollection = array_values($this->cellXfCollection);
 
         // update the index for all cellXfs
-        foreach ($this->_cellXfCollection as $i => $cellXf) {
+        foreach ($this->cellXfCollection as $i => $cellXf) {
             $cellXf->setIndex($i);
         }
 
         // make sure there is always at least one cellXf (there should be)
-        if (empty($this->_cellXfCollection)) {
-            $this->_cellXfCollection[] = new PHPExcel_Style();
+        if (empty($this->cellXfCollection)) {
+            $this->cellXfCollection[] = new PHPExcel_Style();
         }
 
         // update the xfIndex for all cells, row dimensions, column dimensions
         foreach ($this->getWorksheetIterator() as $sheet) {
-
             // for all cells
             foreach ($sheet->getCellCollection(false) as $cellID) {
                 $cell = $sheet->getCell($cellID);
-                $cell->setXfIndex( $map[$cell->getXfIndex()] );
+                $cell->setXfIndex($map[$cell->getXfIndex()]);
             }
 
             // for all row dimensions
             foreach ($sheet->getRowDimensions() as $rowDimension) {
                 if ($rowDimension->getXfIndex() !== null) {
-                    $rowDimension->setXfIndex( $map[$rowDimension->getXfIndex()] );
+                    $rowDimension->setXfIndex($map[$rowDimension->getXfIndex()]);
                 }
             }
 
             // for all column dimensions
             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
             $sheet->garbageCollect();
         }
     }
@@ -1132,8 +1145,8 @@ public function garbageCollect()
      *
      * @return string
      */
-    public function getID() {
-        return $this->_uniqueID;
+    public function getID()
+    {
+        return $this->uniqueID;
     }
-
 }
diff --git a/Classes/PHPExcel/Autoloader.php b/Classes/PHPExcel/Autoloader.php
index 90e5f6cbb..3557e8656 100644
--- a/Classes/PHPExcel/Autoloader.php
+++ b/Classes/PHPExcel/Autoloader.php
@@ -1,4 +1,15 @@
 = 0) {
             return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'), true, true);
         } else {
             return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'));
         }
-    }   //    function Register()
-
+    }
 
     /**
      * Autoload a class identified by name
      *
      * @param    string    $pClassName        Name of the object to load
      */
-    public static function Load($pClassName){
-        if ((class_exists($pClassName,FALSE)) || (strpos($pClassName, 'PHPExcel') !== 0)) {
-            //    Either already loaded, or not a PHPExcel class request
-            return FALSE;
+    public static function Load($pClassName)
+    {
+        if ((class_exists($pClassName, false)) || (strpos($pClassName, 'PHPExcel') !== 0)) {
+            // Either already loaded, or not a PHPExcel class request
+            return false;
         }
 
         $pClassFilePath = PHPEXCEL_ROOT .
-                          str_replace('_',DIRECTORY_SEPARATOR,$pClassName) .
-                          '.php';
+            str_replace('_', DIRECTORY_SEPARATOR, $pClassName) .
+            '.php';
 
-        if ((file_exists($pClassFilePath) === FALSE) || (is_readable($pClassFilePath) === FALSE)) {
-            //    Can't load
-            return FALSE;
+        if ((file_exists($pClassFilePath) === false) || (is_readable($pClassFilePath) === false)) {
+            // Can't load
+            return false;
         }
 
         require($pClassFilePath);
-    }   //    function Load()
-
+    }
 }
diff --git a/Classes/PHPExcel/CachedObjectStorage/APC.php b/Classes/PHPExcel/CachedObjectStorage/APC.php
index 9bdeab43f..d2ad6e37d 100644
--- a/Classes/PHPExcel/CachedObjectStorage/APC.php
+++ b/Classes/PHPExcel/CachedObjectStorage/APC.php
@@ -1,6 +1,7 @@
 _currentCellIsDirty && !empty($this->_currentObjectID)) {
             $this->_currentObject->detach();
 
-            if (!apc_store($this->_cachePrefix.$this->_currentObjectID.'.cache',serialize($this->_currentObject),$this->_cacheTime)) {
+            if (!apc_store(
+                $this->_cachePrefix . $this->_currentObjectID . '.cache',
+                serialize($this->_currentObject),
+                $this->_cacheTime
+            )) {
                 $this->__destruct();
-                throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in APC');
+                throw new PHPExcel_Exception('Failed to store cell ' . $this->_currentObjectID . ' in APC');
             }
             $this->_currentCellIsDirty = false;
         }
         $this->_currentObjectID = $this->_currentObject = null;
-    }    //    function _storeData()
-
+    }
 
     /**
      * Add or Update a cell in cache identified by coordinate address
@@ -83,7 +78,8 @@ protected function _storeData() {
      * @return  PHPExcel_Cell
      * @throws  PHPExcel_Exception
      */
-    public function addCacheData($pCoord, PHPExcel_Cell $cell) {
+    public function addCacheData($pCoord, PHPExcel_Cell $cell)
+    {
         if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
             $this->_storeData();
         }
@@ -94,8 +90,7 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) {
         $this->_currentCellIsDirty = true;
 
         return $cell;
-    }    //    function addCacheData()
-
+    }
 
     /**
      * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
@@ -105,7 +100,8 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) {
      * @throws  PHPExcel_Exception
      * @return  boolean
      */
-    public function isDataSet($pCoord) {
+    public function isDataSet($pCoord)
+    {
         //    Check if the requested entry is the current object, or exists in the cache
         if (parent::isDataSet($pCoord)) {
             if ($this->_currentObjectID == $pCoord) {
@@ -113,7 +109,7 @@ public function isDataSet($pCoord) {
             }
             //    Check if the requested entry still exists in apc
             $success = apc_fetch($this->_cachePrefix.$pCoord.'.cache');
-            if ($success === FALSE) {
+            if ($success === false) {
                 //    Entry no longer exists in APC, so clear it from the cache array
                 parent::deleteCacheData($pCoord);
                 throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache');
@@ -121,8 +117,7 @@ public function isDataSet($pCoord) {
             return true;
         }
         return false;
-    }    //    function isDataSet()
-
+    }
 
     /**
      * Get cell at a specific coordinate
@@ -132,7 +127,8 @@ public function isDataSet($pCoord) {
      * @throws  PHPExcel_Exception
      * @return  PHPExcel_Cell  Cell that was found, or null if not found
      */
-    public function getCacheData($pCoord) {
+    public function getCacheData($pCoord)
+    {
         if ($pCoord === $this->_currentObjectID) {
             return $this->_currentObject;
         }
@@ -140,8 +136,8 @@ public function getCacheData($pCoord) {
 
         //    Check if the entry that has been requested actually exists
         if (parent::isDataSet($pCoord)) {
-            $obj = apc_fetch($this->_cachePrefix.$pCoord.'.cache');
-            if ($obj === FALSE) {
+            $obj = apc_fetch($this->_cachePrefix . $pCoord . '.cache');
+            if ($obj === false) {
                 //    Entry no longer exists in APC, so clear it from the cache array
                 parent::deleteCacheData($pCoord);
                 throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache');
@@ -159,22 +155,21 @@ public function getCacheData($pCoord) {
 
         //    Return requested entry
         return $this->_currentObject;
-    }    //    function getCacheData()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return  string[]
-	 */
-	public function getCellList() {
-		if ($this->_currentObjectID !== null) {
-			$this->_storeData();
-		}
+    }
 
-		return parent::getCellList();
-	}
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return  string[]
+     */
+    public function getCellList()
+    {
+        if ($this->_currentObjectID !== null) {
+            $this->_storeData();
+        }
 
+        return parent::getCellList();
+    }
 
     /**
      * Delete a cell in cache identified by coordinate address
@@ -183,14 +178,14 @@ public function getCellList() {
      * @param   string  $pCoord  Coordinate address of the cell to delete
      * @throws  PHPExcel_Exception
      */
-    public function deleteCacheData($pCoord) {
+    public function deleteCacheData($pCoord)
+    {
         //    Delete the entry from APC
         apc_delete($this->_cachePrefix.$pCoord.'.cache');
 
         //    Delete the entry from our cell address array
         parent::deleteCacheData($pCoord);
-    }    //    function deleteCacheData()
-
+    }
 
     /**
      * Clone the cell collection
@@ -200,37 +195,38 @@ public function deleteCacheData($pCoord) {
      * @throws  PHPExcel_Exception
      * @return  void
      */
-    public function copyCellCollection(PHPExcel_Worksheet $parent) {
+    public function copyCellCollection(PHPExcel_Worksheet $parent)
+    {
         parent::copyCellCollection($parent);
         //    Get a new id for the new file name
         $baseUnique = $this->_getUniqueID();
-        $newCachePrefix = substr(md5($baseUnique),0,8).'.';
+        $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.';
         $cacheList = $this->getCellList();
-        foreach($cacheList as $cellID) {
+        foreach ($cacheList as $cellID) {
             if ($cellID != $this->_currentObjectID) {
-                $obj = apc_fetch($this->_cachePrefix.$cellID.'.cache');
-                if ($obj === FALSE) {
+                $obj = apc_fetch($this->_cachePrefix . $cellID . '.cache');
+                if ($obj === false) {
                     //    Entry no longer exists in APC, so clear it from the cache array
                     parent::deleteCacheData($cellID);
-                    throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in APC');
+                    throw new PHPExcel_Exception('Cell entry ' . $cellID . ' no longer exists in APC');
                 }
-                if (!apc_store($newCachePrefix.$cellID.'.cache',$obj,$this->_cacheTime)) {
+                if (!apc_store($newCachePrefix . $cellID . '.cache', $obj, $this->_cacheTime)) {
                     $this->__destruct();
-                    throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in APC');
+                    throw new PHPExcel_Exception('Failed to store cell ' . $cellID . ' in APC');
                 }
             }
         }
         $this->_cachePrefix = $newCachePrefix;
-    }    //    function copyCellCollection()
-
+    }
 
     /**
      * Clear the cell collection and disconnect from our parent
      *
      * @return  void
      */
-    public function unsetWorksheetCells() {
-        if ($this->_currentObject !== NULL) {
+    public function unsetWorksheetCells()
+    {
+        if ($this->_currentObject !== null) {
             $this->_currentObject->detach();
             $this->_currentObject = $this->_currentObjectID = null;
         }
@@ -242,8 +238,7 @@ public function unsetWorksheetCells() {
 
         //    detach ourself from the worksheet, so that it can then delete this object successfully
         $this->_parent = null;
-    }    //    function unsetWorksheetCells()
-
+    }
 
     /**
      * Initialise this new cell collection
@@ -251,29 +246,29 @@ public function unsetWorksheetCells() {
      * @param  PHPExcel_Worksheet  $parent     The worksheet for this cell collection
      * @param  array of mixed      $arguments  Additional initialisation arguments
      */
-    public function __construct(PHPExcel_Worksheet $parent, $arguments) {
+    public function __construct(PHPExcel_Worksheet $parent, $arguments)
+    {
         $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600;
 
-        if ($this->_cachePrefix === NULL) {
+        if ($this->_cachePrefix === null) {
             $baseUnique = $this->_getUniqueID();
-            $this->_cachePrefix = substr(md5($baseUnique),0,8).'.';
+            $this->_cachePrefix = substr(md5($baseUnique), 0, 8) . '.';
             $this->_cacheTime = $cacheTime;
 
             parent::__construct($parent);
         }
-    }    //    function __construct()
-
+    }
 
     /**
      * Destroy this cell collection
      */
-    public function __destruct() {
+    public function __destruct()
+    {
         $cacheList = $this->getCellList();
-        foreach($cacheList as $cellID) {
-            apc_delete($this->_cachePrefix.$cellID.'.cache');
+        foreach ($cacheList as $cellID) {
+            apc_delete($this->_cachePrefix . $cellID . '.cache');
         }
-    }    //    function __destruct()
-
+    }
 
     /**
      * Identify whether the caching method is currently available
@@ -281,15 +276,15 @@ public function __destruct() {
      *
      * @return  boolean
      */
-    public static function cacheMethodIsAvailable() {
+    public static function cacheMethodIsAvailable()
+    {
         if (!function_exists('apc_store')) {
-            return FALSE;
+            return false;
         }
-        if (apc_sma_info() === FALSE) {
-            return FALSE;
+        if (apc_sma_info() === false) {
+            return false;
         }
 
-        return TRUE;
+        return true;
     }
-
 }
diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php
index 1d83600ac..a7c25ed20 100644
--- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php
+++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php
@@ -1,376 +1,368 @@
-_parent = $parent;
-	}	//	function __construct()
-
-
-	/**
-	 * Return the parent worksheet for this cell collection
-	 *
-	 * @return	PHPExcel_Worksheet
-	 */
-	public function getParent()
-	{
-		return $this->_parent;
-	}
-
-	/**
-	 * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
-	 *
-	 * @param	string		$pCoord		Coordinate address of the cell to check
-	 * @return	boolean
-	 */
-	public function isDataSet($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return true;
-		}
-		//	Check if the requested entry exists in the cache
-		return isset($this->_cellCache[$pCoord]);
-	}	//	function isDataSet()
-
-
-	/**
-	 * Move a cell object from one address to another
-	 *
-	 * @param	string		$fromAddress	Current address of the cell to move
-	 * @param	string		$toAddress		Destination address of the cell to move
-	 * @return	boolean
-	 */
-	public function moveCell($fromAddress, $toAddress) {
-		if ($fromAddress === $this->_currentObjectID) {
-			$this->_currentObjectID = $toAddress;
-		}
-		$this->_currentCellIsDirty = true;
-		if (isset($this->_cellCache[$fromAddress])) {
-			$this->_cellCache[$toAddress] = &$this->_cellCache[$fromAddress];
-			unset($this->_cellCache[$fromAddress]);
-		}
-
-		return TRUE;
-	}	//	function moveCell()
-
-
-    /**
-     * Add or Update a cell in cache
-     *
-     * @param	PHPExcel_Cell	$cell		Cell to update
-	 * @return	PHPExcel_Cell
-     * @throws	PHPExcel_Exception
-     */
-	public function updateCacheData(PHPExcel_Cell $cell) {
-		return $this->addCacheData($cell->getCoordinate(),$cell);
-	}	//	function updateCacheData()
-
-
-    /**
-     * Delete a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to delete
-     * @throws	PHPExcel_Exception
-     */
-	public function deleteCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID && !is_null($this->_currentObject)) {
-			$this->_currentObject->detach();
-			$this->_currentObjectID = $this->_currentObject = null;
-		}
-
-		if (is_object($this->_cellCache[$pCoord])) {
-			$this->_cellCache[$pCoord]->detach();
-			unset($this->_cellCache[$pCoord]);
-		}
-		$this->_currentCellIsDirty = false;
-	}	//	function deleteCacheData()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return	string[]
-	 */
-	public function getCellList() {
-		return array_keys($this->_cellCache);
-	}	//	function getCellList()
-
-
-	/**
-	 * Sort the list of all cell addresses currently held in cache by row and column
-	 *
-	 * @return	string[]
-	 */
-	public function getSortedCellList() {
-		$sortKeys = array();
-		foreach ($this->getCellList() as $coord) {
-			sscanf($coord,'%[A-Z]%d', $column, $row);
-			$sortKeys[sprintf('%09d%3s',$row,$column)] = $coord;
-		}
-		ksort($sortKeys);
-
-		return array_values($sortKeys);
-	}	//	function sortCellList()
-
-
-
-	/**
-	 * Get highest worksheet column and highest row that have cell records
-	 *
-	 * @return array Highest column name and highest row number
-	 */
-	public function getHighestRowAndColumn()
-	{
-		// Lookup highest column and highest row
-		$col = array('A' => '1A');
-		$row = array(1);
-		foreach ($this->getCellList() as $coord) {
-			sscanf($coord,'%[A-Z]%d', $c, $r);
-			$row[$r] = $r;
-			$col[$c] = strlen($c).$c;
- 		}
-		if (!empty($row)) {
-			// Determine highest column and row
-			$highestRow = max($row);
-			$highestColumn = substr(max($col),1);
-		}
-
-		return array( 'row'	   => $highestRow,
-					  'column' => $highestColumn
-					);
-	}
-
-
-	/**
-	 * Return the cell address of the currently active cell object
-	 *
-	 * @return	string
-	 */
-	public function getCurrentAddress()
-	{
-		return $this->_currentObjectID;
-	}
-
-	/**
-	 * Return the column address of the currently active cell object
-	 *
-	 * @return	string
-	 */
-	public function getCurrentColumn()
-	{
-		sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row);
-		return $column;
-	}
-
-	/**
-	 * Return the row address of the currently active cell object
-	 *
-	 * @return	integer
-	 */
-	public function getCurrentRow()
-	{
-		sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row);
-		return (integer) $row;
-	}
-
-	/**
-	 * Get highest worksheet column
-	 *
-     * @param   string     $row        Return the highest column for the specified row,
-     *                                     or the highest column of any row if no row number is passed
-	 * @return  string     Highest column name
-	 */
-	public function getHighestColumn($row = null)
-	{
-        if ($row == null) {
-    		$colRow = $this->getHighestRowAndColumn();
-	    	return $colRow['column'];
-        }
-
-        $columnList = array(1);
-        foreach ($this->getCellList() as $coord) {
-            sscanf($coord,'%[A-Z]%d', $c, $r);
-            if ($r != $row) {
-                continue;
-            }
-            $columnList[] = PHPExcel_Cell::columnIndexFromString($c);
-        }
-        return PHPExcel_Cell::stringFromColumnIndex(max($columnList) - 1);
-    }
-
-	/**
-	 * Get highest worksheet row
-	 *
-     * @param   string     $column     Return the highest row for the specified column,
-     *                                     or the highest row of any column if no column letter is passed
-	 * @return  int        Highest row number
-	 */
-	public function getHighestRow($column = null)
-	{
-        if ($column == null) {
-	    	$colRow = $this->getHighestRowAndColumn();
-    		return $colRow['row'];
-        }
-
-        $rowList = array(0);
-        foreach ($this->getCellList() as $coord) {
-            sscanf($coord,'%[A-Z]%d', $c, $r);
-            if ($c != $column) {
-                continue;
-            }
-            $rowList[] = $r;
-        }
-
-        return max($rowList);
-	}
-
-
-	/**
-	 * Generate a unique ID for cache referencing
-	 *
-	 * @return string Unique Reference
-	 */
-	protected function _getUniqueID() {
-		if (function_exists('posix_getpid')) {
-			$baseUnique = posix_getpid();
-		} else {
-			$baseUnique = mt_rand();
-		}
-		return uniqid($baseUnique,true);
-	}
-
-	/**
-	 * Clone the cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The new worksheet
-	 * @return	void
-	 */
-	public function copyCellCollection(PHPExcel_Worksheet $parent) {
-		$this->_currentCellIsDirty;
-        $this->_storeData();
-
-		$this->_parent = $parent;
-		if (($this->_currentObject !== NULL) && (is_object($this->_currentObject))) {
-			$this->_currentObject->attach($this);
-		}
-	}	//	function copyCellCollection()
-
-    /**
-     * Remove a row, deleting all cells in that row
-     *
-     * @param string    $row    Row number to remove
-     * @return void
-     */
-    public function removeRow($row) {
-        foreach ($this->getCellList() as $coord) {
-            sscanf($coord,'%[A-Z]%d', $c, $r);
-            if ($r == $row) {
-                $this->deleteCacheData($coord);
-            }
-        }
-    }
-
-    /**
-     * Remove a column, deleting all cells in that column
-     *
-     * @param string    $column    Column ID to remove
-     * @return void
-     */
-    public function removeColumn($column) {
-        foreach ($this->getCellList() as $coord) {
-            sscanf($coord,'%[A-Z]%d', $c, $r);
-            if ($c == $column) {
-                $this->deleteCacheData($coord);
-            }
-        }
-    }
-
-	/**
-	 * Identify whether the caching method is currently available
-	 * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
-	 *
-	 * @return	boolean
-	 */
-	public static function cacheMethodIsAvailable() {
-		return true;
-	}
-
-}
+_parent = $parent;
+    }
+
+    /**
+     * Return the parent worksheet for this cell collection
+     *
+     * @return    PHPExcel_Worksheet
+     */
+    public function getParent()
+    {
+        return $this->_parent;
+    }
+
+    /**
+     * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
+     *
+     * @param    string        $pCoord        Coordinate address of the cell to check
+     * @return    boolean
+     */
+    public function isDataSet($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return true;
+        }
+        //    Check if the requested entry exists in the cache
+        return isset($this->_cellCache[$pCoord]);
+    }
+
+    /**
+     * Move a cell object from one address to another
+     *
+     * @param    string        $fromAddress    Current address of the cell to move
+     * @param    string        $toAddress        Destination address of the cell to move
+     * @return    boolean
+     */
+    public function moveCell($fromAddress, $toAddress)
+    {
+        if ($fromAddress === $this->_currentObjectID) {
+            $this->_currentObjectID = $toAddress;
+        }
+        $this->_currentCellIsDirty = true;
+        if (isset($this->_cellCache[$fromAddress])) {
+            $this->_cellCache[$toAddress] = &$this->_cellCache[$fromAddress];
+            unset($this->_cellCache[$fromAddress]);
+        }
+
+        return true;
+    }
+
+    /**
+     * Add or Update a cell in cache
+     *
+     * @param    PHPExcel_Cell    $cell        Cell to update
+     * @return    PHPExcel_Cell
+     * @throws    PHPExcel_Exception
+     */
+    public function updateCacheData(PHPExcel_Cell $cell)
+    {
+        return $this->addCacheData($cell->getCoordinate(), $cell);
+    }
+
+    /**
+     * Delete a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to delete
+     * @throws    PHPExcel_Exception
+     */
+    public function deleteCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID && !is_null($this->_currentObject)) {
+            $this->_currentObject->detach();
+            $this->_currentObjectID = $this->_currentObject = null;
+        }
+
+        if (is_object($this->_cellCache[$pCoord])) {
+            $this->_cellCache[$pCoord]->detach();
+            unset($this->_cellCache[$pCoord]);
+        }
+        $this->_currentCellIsDirty = false;
+    }
+
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return    string[]
+     */
+    public function getCellList()
+    {
+        return array_keys($this->_cellCache);
+    }
+
+    /**
+     * Sort the list of all cell addresses currently held in cache by row and column
+     *
+     * @return    string[]
+     */
+    public function getSortedCellList()
+    {
+        $sortKeys = array();
+        foreach ($this->getCellList() as $coord) {
+            sscanf($coord, '%[A-Z]%d', $column, $row);
+            $sortKeys[sprintf('%09d%3s', $row, $column)] = $coord;
+        }
+        ksort($sortKeys);
+
+        return array_values($sortKeys);
+    }
+
+    /**
+     * Get highest worksheet column and highest row that have cell records
+     *
+     * @return array Highest column name and highest row number
+     */
+    public function getHighestRowAndColumn()
+    {
+        // Lookup highest column and highest row
+        $col = array('A' => '1A');
+        $row = array(1);
+        foreach ($this->getCellList() as $coord) {
+            sscanf($coord, '%[A-Z]%d', $c, $r);
+            $row[$r] = $r;
+            $col[$c] = strlen($c).$c;
+        }
+        if (!empty($row)) {
+            // Determine highest column and row
+            $highestRow = max($row);
+            $highestColumn = substr(max($col), 1);
+        }
+
+        return array(
+            'row'    => $highestRow,
+            'column' => $highestColumn
+        );
+    }
+
+    /**
+     * Return the cell address of the currently active cell object
+     *
+     * @return    string
+     */
+    public function getCurrentAddress()
+    {
+        return $this->_currentObjectID;
+    }
+
+    /**
+     * Return the column address of the currently active cell object
+     *
+     * @return    string
+     */
+    public function getCurrentColumn()
+    {
+        sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row);
+        return $column;
+    }
+
+    /**
+     * Return the row address of the currently active cell object
+     *
+     * @return    integer
+     */
+    public function getCurrentRow()
+    {
+        sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row);
+        return (integer) $row;
+    }
+
+    /**
+     * Get highest worksheet column
+     *
+     * @param   string     $row        Return the highest column for the specified row,
+     *                                     or the highest column of any row if no row number is passed
+     * @return  string     Highest column name
+     */
+    public function getHighestColumn($row = null)
+    {
+        if ($row == null) {
+            $colRow = $this->getHighestRowAndColumn();
+            return $colRow['column'];
+        }
+
+        $columnList = array(1);
+        foreach ($this->getCellList() as $coord) {
+            sscanf($coord, '%[A-Z]%d', $c, $r);
+            if ($r != $row) {
+                continue;
+            }
+            $columnList[] = PHPExcel_Cell::columnIndexFromString($c);
+        }
+        return PHPExcel_Cell::stringFromColumnIndex(max($columnList) - 1);
+    }
+
+    /**
+     * Get highest worksheet row
+     *
+     * @param   string     $column     Return the highest row for the specified column,
+     *                                     or the highest row of any column if no column letter is passed
+     * @return  int        Highest row number
+     */
+    public function getHighestRow($column = null)
+    {
+        if ($column == null) {
+            $colRow = $this->getHighestRowAndColumn();
+            return $colRow['row'];
+        }
+
+        $rowList = array(0);
+        foreach ($this->getCellList() as $coord) {
+            sscanf($coord, '%[A-Z]%d', $c, $r);
+            if ($c != $column) {
+                continue;
+            }
+            $rowList[] = $r;
+        }
+
+        return max($rowList);
+    }
+
+    /**
+     * Generate a unique ID for cache referencing
+     *
+     * @return string Unique Reference
+     */
+    protected function _getUniqueID()
+    {
+        if (function_exists('posix_getpid')) {
+            $baseUnique = posix_getpid();
+        } else {
+            $baseUnique = mt_rand();
+        }
+        return uniqid($baseUnique, true);
+    }
+
+    /**
+     * Clone the cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The new worksheet
+     * @return    void
+     */
+    public function copyCellCollection(PHPExcel_Worksheet $parent)
+    {
+        $this->_currentCellIsDirty;
+        $this->_storeData();
+
+        $this->_parent = $parent;
+        if (($this->_currentObject !== null) && (is_object($this->_currentObject))) {
+            $this->_currentObject->attach($this);
+        }
+    }    //    function copyCellCollection()
+
+    /**
+     * Remove a row, deleting all cells in that row
+     *
+     * @param string    $row    Row number to remove
+     * @return void
+     */
+    public function removeRow($row)
+    {
+        foreach ($this->getCellList() as $coord) {
+            sscanf($coord, '%[A-Z]%d', $c, $r);
+            if ($r == $row) {
+                $this->deleteCacheData($coord);
+            }
+        }
+    }
+
+    /**
+     * Remove a column, deleting all cells in that column
+     *
+     * @param string    $column    Column ID to remove
+     * @return void
+     */
+    public function removeColumn($column)
+    {
+        foreach ($this->getCellList() as $coord) {
+            sscanf($coord, '%[A-Z]%d', $c, $r);
+            if ($c == $column) {
+                $this->deleteCacheData($coord);
+            }
+        }
+    }
+
+    /**
+     * Identify whether the caching method is currently available
+     * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
+     *
+     * @return    boolean
+     */
+    public static function cacheMethodIsAvailable()
+    {
+        return true;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php
index 05b57ed26..65afa3cf9 100644
--- a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php
+++ b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php
@@ -1,219 +1,208 @@
-_currentCellIsDirty && !empty($this->_currentObjectID)) {
-			$this->_currentObject->detach();
-
-			fseek($this->_fileHandle,0,SEEK_END);
-
-			$this->_cellCache[$this->_currentObjectID] = array(
-                'ptr' => ftell($this->_fileHandle),
-				'sz'  => fwrite($this->_fileHandle, serialize($this->_currentObject))
-			);
-			$this->_currentCellIsDirty = false;
-		}
-		$this->_currentObjectID = $this->_currentObject = null;
-	}	//	function _storeData()
-
-
-    /**
-     * Add or Update a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to update
-     * @param	PHPExcel_Cell	$cell		Cell to update
-	 * @return	PHPExcel_Cell
-     * @throws	PHPExcel_Exception
-     */
-	public function addCacheData($pCoord, PHPExcel_Cell $cell) {
-		if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
-			$this->_storeData();
-		}
-
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = $cell;
-		$this->_currentCellIsDirty = true;
-
-		return $cell;
-	}	//	function addCacheData()
-
-
-    /**
-     * Get cell at a specific coordinate
-     *
-     * @param 	string 			$pCoord		Coordinate of the cell
-     * @throws 	PHPExcel_Exception
-     * @return 	PHPExcel_Cell 	Cell that was found, or null if not found
-     */
-	public function getCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return $this->_currentObject;
-		}
-		$this->_storeData();
-
-		//	Check if the entry that has been requested actually exists
-		if (!isset($this->_cellCache[$pCoord])) {
-			//	Return null if requested entry doesn't exist in cache
-			return null;
-		}
-
-		//	Set current entry to the requested entry
-		$this->_currentObjectID = $pCoord;
-		fseek($this->_fileHandle, $this->_cellCache[$pCoord]['ptr']);
-		$this->_currentObject = unserialize(fread($this->_fileHandle, $this->_cellCache[$pCoord]['sz']));
-        //    Re-attach this as the cell's parent
-        $this->_currentObject->attach($this);
-
-		//	Return requested entry
-		return $this->_currentObject;
-	}	//	function getCacheData()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return  string[]
-	 */
-	public function getCellList() {
-		if ($this->_currentObjectID !== null) {
-			$this->_storeData();
-		}
-
-		return parent::getCellList();
-	}
-
-
-	/**
-	 * Clone the cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The new worksheet
-	 * @return	void
-	 */
-	public function copyCellCollection(PHPExcel_Worksheet $parent) {
-		parent::copyCellCollection($parent);
-		//	Get a new id for the new file name
-		$baseUnique = $this->_getUniqueID();
-		$newFileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache';
-		//	Copy the existing cell cache file
-		copy ($this->_fileName,$newFileName);
-		$this->_fileName = $newFileName;
-		//	Open the copied cell cache file
-		$this->_fileHandle = fopen($this->_fileName,'a+');
-	}	//	function copyCellCollection()
-
-
-	/**
-	 * Clear the cell collection and disconnect from our parent
-	 *
-	 * @return	void
-	 */
-	public function unsetWorksheetCells() {
-		if(!is_null($this->_currentObject)) {
-			$this->_currentObject->detach();
-			$this->_currentObject = $this->_currentObjectID = null;
-		}
-		$this->_cellCache = array();
-
-		//	detach ourself from the worksheet, so that it can then delete this object successfully
-		$this->_parent = null;
-
-		//	Close down the temporary cache file
-		$this->__destruct();
-	}	//	function unsetWorksheetCells()
-
-
-	/**
-	 * Initialise this new cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The worksheet for this cell collection
-	 * @param	array of mixed		$arguments	Additional initialisation arguments
-	 */
-	public function __construct(PHPExcel_Worksheet $parent, $arguments) {
-		$this->_cacheDirectory	= ((isset($arguments['dir'])) && ($arguments['dir'] !== NULL))
-									? $arguments['dir']
-									: PHPExcel_Shared_File::sys_get_temp_dir();
-
-		parent::__construct($parent);
-		if (is_null($this->_fileHandle)) {
-			$baseUnique = $this->_getUniqueID();
-			$this->_fileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache';
-			$this->_fileHandle = fopen($this->_fileName,'a+');
-		}
-	}	//	function __construct()
-
-
-	/**
-	 * Destroy this cell collection
-	 */
-	public function __destruct() {
-		if (!is_null($this->_fileHandle)) {
-			fclose($this->_fileHandle);
-			unlink($this->_fileName);
-		}
-		$this->_fileHandle = null;
-	}	//	function __destruct()
-
-}
+_currentCellIsDirty && !empty($this->_currentObjectID)) {
+            $this->_currentObject->detach();
+
+            fseek($this->_fileHandle, 0, SEEK_END);
+
+            $this->_cellCache[$this->_currentObjectID] = array(
+                'ptr' => ftell($this->_fileHandle),
+                'sz'  => fwrite($this->_fileHandle, serialize($this->_currentObject))
+            );
+            $this->_currentCellIsDirty = false;
+        }
+        $this->_currentObjectID = $this->_currentObject = null;
+    }
+
+    /**
+     * Add or Update a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to update
+     * @param    PHPExcel_Cell    $cell        Cell to update
+     * @return    PHPExcel_Cell
+     * @throws    PHPExcel_Exception
+     */
+    public function addCacheData($pCoord, PHPExcel_Cell $cell)
+    {
+        if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
+            $this->_storeData();
+        }
+
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = $cell;
+        $this->_currentCellIsDirty = true;
+
+        return $cell;
+    }
+
+    /**
+     * Get cell at a specific coordinate
+     *
+     * @param     string             $pCoord        Coordinate of the cell
+     * @throws     PHPExcel_Exception
+     * @return     PHPExcel_Cell     Cell that was found, or null if not found
+     */
+    public function getCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return $this->_currentObject;
+        }
+        $this->_storeData();
+
+        //    Check if the entry that has been requested actually exists
+        if (!isset($this->_cellCache[$pCoord])) {
+            //    Return null if requested entry doesn't exist in cache
+            return null;
+        }
+
+        //    Set current entry to the requested entry
+        $this->_currentObjectID = $pCoord;
+        fseek($this->_fileHandle, $this->_cellCache[$pCoord]['ptr']);
+        $this->_currentObject = unserialize(fread($this->_fileHandle, $this->_cellCache[$pCoord]['sz']));
+        //    Re-attach this as the cell's parent
+        $this->_currentObject->attach($this);
+
+        //    Return requested entry
+        return $this->_currentObject;
+    }
+
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return  string[]
+     */
+    public function getCellList()
+    {
+        if ($this->_currentObjectID !== null) {
+            $this->_storeData();
+        }
+
+        return parent::getCellList();
+    }
+
+    /**
+     * Clone the cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The new worksheet
+     */
+    public function copyCellCollection(PHPExcel_Worksheet $parent)
+    {
+        parent::copyCellCollection($parent);
+        //    Get a new id for the new file name
+        $baseUnique = $this->_getUniqueID();
+        $newFileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache';
+        //    Copy the existing cell cache file
+        copy($this->_fileName, $newFileName);
+        $this->_fileName = $newFileName;
+        //    Open the copied cell cache file
+        $this->_fileHandle = fopen($this->_fileName, 'a+');
+    }
+
+    /**
+     * Clear the cell collection and disconnect from our parent
+     *
+     */
+    public function unsetWorksheetCells()
+    {
+        if (!is_null($this->_currentObject)) {
+            $this->_currentObject->detach();
+            $this->_currentObject = $this->_currentObjectID = null;
+        }
+        $this->_cellCache = array();
+
+        //    detach ourself from the worksheet, so that it can then delete this object successfully
+        $this->_parent = null;
+
+        //    Close down the temporary cache file
+        $this->__destruct();
+    }
+
+    /**
+     * Initialise this new cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The worksheet for this cell collection
+     * @param    array of mixed        $arguments    Additional initialisation arguments
+     */
+    public function __construct(PHPExcel_Worksheet $parent, $arguments)
+    {
+        $this->_cacheDirectory    = ((isset($arguments['dir'])) && ($arguments['dir'] !== null))
+                                    ? $arguments['dir']
+                                    : PHPExcel_Shared_File::sys_get_temp_dir();
+
+        parent::__construct($parent);
+        if (is_null($this->_fileHandle)) {
+            $baseUnique = $this->_getUniqueID();
+            $this->_fileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache';
+            $this->_fileHandle = fopen($this->_fileName, 'a+');
+        }
+    }
+
+    /**
+     * Destroy this cell collection
+     */
+    public function __destruct()
+    {
+        if (!is_null($this->_fileHandle)) {
+            fclose($this->_fileHandle);
+            unlink($this->_fileName);
+        }
+        $this->_fileHandle = null;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorage/ICache.php b/Classes/PHPExcel/CachedObjectStorage/ICache.php
index 97ea223a0..aafef6e9c 100644
--- a/Classes/PHPExcel/CachedObjectStorage/ICache.php
+++ b/Classes/PHPExcel/CachedObjectStorage/ICache.php
@@ -1,6 +1,7 @@
 _currentCellIsDirty && !empty($this->_currentObjectID)) {
-			$this->_currentObject->detach();
-
-			$this->_cellCache[$this->_currentObjectID] = igbinary_serialize($this->_currentObject);
-			$this->_currentCellIsDirty = false;
-		}
-		$this->_currentObjectID = $this->_currentObject = null;
-	}	//	function _storeData()
-
-
-    /**
-     * Add or Update a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to update
-     * @param	PHPExcel_Cell	$cell		Cell to update
-	 * @return	PHPExcel_Cell
-     * @throws	PHPExcel_Exception
-     */
-	public function addCacheData($pCoord, PHPExcel_Cell $cell) {
-		if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
-			$this->_storeData();
-		}
-
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = $cell;
-		$this->_currentCellIsDirty = true;
-
-		return $cell;
-	}	//	function addCacheData()
-
-
-    /**
-     * Get cell at a specific coordinate
-     *
-     * @param 	string 			$pCoord		Coordinate of the cell
-     * @throws 	PHPExcel_Exception
-     * @return 	PHPExcel_Cell 	Cell that was found, or null if not found
-     */
-	public function getCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return $this->_currentObject;
-		}
-		$this->_storeData();
-
-		//	Check if the entry that has been requested actually exists
-		if (!isset($this->_cellCache[$pCoord])) {
-			//	Return null if requested entry doesn't exist in cache
-			return null;
-		}
-
-		//	Set current entry to the requested entry
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = igbinary_unserialize($this->_cellCache[$pCoord]);
-        //    Re-attach this as the cell's parent
-        $this->_currentObject->attach($this);
-
-		//	Return requested entry
-		return $this->_currentObject;
-	}	//	function getCacheData()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return  string[]
-	 */
-	public function getCellList() {
-		if ($this->_currentObjectID !== null) {
-			$this->_storeData();
-		}
-
-		return parent::getCellList();
-	}
-
-
-	/**
-	 * Clear the cell collection and disconnect from our parent
-	 *
-	 * @return	void
-	 */
-	public function unsetWorksheetCells() {
-		if(!is_null($this->_currentObject)) {
-			$this->_currentObject->detach();
-			$this->_currentObject = $this->_currentObjectID = null;
-		}
-		$this->_cellCache = array();
-
-		//	detach ourself from the worksheet, so that it can then delete this object successfully
-		$this->_parent = null;
-	}	//	function unsetWorksheetCells()
-
-
-	/**
-	 * Identify whether the caching method is currently available
-	 * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
-	 *
-	 * @return	boolean
-	 */
-	public static function cacheMethodIsAvailable() {
-		if (!function_exists('igbinary_serialize')) {
-			return false;
-		}
-
-		return true;
-	}
-
-}
+_currentCellIsDirty && !empty($this->_currentObjectID)) {
+            $this->_currentObject->detach();
+
+            $this->_cellCache[$this->_currentObjectID] = igbinary_serialize($this->_currentObject);
+            $this->_currentCellIsDirty = false;
+        }
+        $this->_currentObjectID = $this->_currentObject = null;
+    }    //    function _storeData()
+
+
+    /**
+     * Add or Update a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to update
+     * @param    PHPExcel_Cell    $cell        Cell to update
+     * @return    PHPExcel_Cell
+     * @throws    PHPExcel_Exception
+     */
+    public function addCacheData($pCoord, PHPExcel_Cell $cell)
+    {
+        if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
+            $this->_storeData();
+        }
+
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = $cell;
+        $this->_currentCellIsDirty = true;
+
+        return $cell;
+    }    //    function addCacheData()
+
+
+    /**
+     * Get cell at a specific coordinate
+     *
+     * @param     string             $pCoord        Coordinate of the cell
+     * @throws     PHPExcel_Exception
+     * @return     PHPExcel_Cell     Cell that was found, or null if not found
+     */
+    public function getCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return $this->_currentObject;
+        }
+        $this->_storeData();
+
+        //    Check if the entry that has been requested actually exists
+        if (!isset($this->_cellCache[$pCoord])) {
+            //    Return null if requested entry doesn't exist in cache
+            return null;
+        }
+
+        //    Set current entry to the requested entry
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = igbinary_unserialize($this->_cellCache[$pCoord]);
+        //    Re-attach this as the cell's parent
+        $this->_currentObject->attach($this);
+
+        //    Return requested entry
+        return $this->_currentObject;
+    }    //    function getCacheData()
+
+
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return  string[]
+     */
+    public function getCellList()
+    {
+        if ($this->_currentObjectID !== null) {
+            $this->_storeData();
+        }
+
+        return parent::getCellList();
+    }
+
+
+    /**
+     * Clear the cell collection and disconnect from our parent
+     *
+     * @return    void
+     */
+    public function unsetWorksheetCells()
+    {
+        if (!is_null($this->_currentObject)) {
+            $this->_currentObject->detach();
+            $this->_currentObject = $this->_currentObjectID = null;
+        }
+        $this->_cellCache = array();
+
+        //    detach ourself from the worksheet, so that it can then delete this object successfully
+        $this->_parent = null;
+    }    //    function unsetWorksheetCells()
+
+
+    /**
+     * Identify whether the caching method is currently available
+     * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
+     *
+     * @return    boolean
+     */
+    public static function cacheMethodIsAvailable()
+    {
+        if (!function_exists('igbinary_serialize')) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorage/Memcache.php b/Classes/PHPExcel/CachedObjectStorage/Memcache.php
index 7e3659d77..1ffcf47ab 100644
--- a/Classes/PHPExcel/CachedObjectStorage/Memcache.php
+++ b/Classes/PHPExcel/CachedObjectStorage/Memcache.php
@@ -1,312 +1,308 @@
-_currentCellIsDirty && !empty($this->_currentObjectID)) {
-			$this->_currentObject->detach();
-
-			$obj = serialize($this->_currentObject);
-			if (!$this->_memcache->replace($this->_cachePrefix.$this->_currentObjectID.'.cache',$obj,NULL,$this->_cacheTime)) {
-				if (!$this->_memcache->add($this->_cachePrefix.$this->_currentObjectID.'.cache',$obj,NULL,$this->_cacheTime)) {
-					$this->__destruct();
-					throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in MemCache');
-				}
-			}
-			$this->_currentCellIsDirty = false;
-		}
-		$this->_currentObjectID = $this->_currentObject = null;
-	}	//	function _storeData()
-
-
-    /**
-     * Add or Update a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to update
-     * @param	PHPExcel_Cell	$cell		Cell to update
-	 * @return	PHPExcel_Cell
-     * @throws	PHPExcel_Exception
-     */
-	public function addCacheData($pCoord, PHPExcel_Cell $cell) {
-		if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
-			$this->_storeData();
-		}
-		$this->_cellCache[$pCoord] = true;
-
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = $cell;
-		$this->_currentCellIsDirty = true;
-
-		return $cell;
-	}	//	function addCacheData()
-
-
-	/**
-	 * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
-	 *
-	 * @param	string		$pCoord		Coordinate address of the cell to check
-	 * @return	boolean
-	 * @return	boolean
-	 */
-	public function isDataSet($pCoord) {
-		//	Check if the requested entry is the current object, or exists in the cache
-		if (parent::isDataSet($pCoord)) {
-			if ($this->_currentObjectID == $pCoord) {
-				return true;
-			}
-			//	Check if the requested entry still exists in Memcache
-			$success = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache');
-			if ($success === false) {
-				//	Entry no longer exists in Memcache, so clear it from the cache array
-				parent::deleteCacheData($pCoord);
-				throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache');
-			}
-			return true;
-		}
-		return false;
-	}	//	function isDataSet()
-
-
-	/**
-     * Get cell at a specific coordinate
-     *
-     * @param 	string 			$pCoord		Coordinate of the cell
-     * @throws 	PHPExcel_Exception
-     * @return 	PHPExcel_Cell 	Cell that was found, or null if not found
-     */
-	public function getCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return $this->_currentObject;
-		}
-		$this->_storeData();
-
-		//	Check if the entry that has been requested actually exists
-		if (parent::isDataSet($pCoord)) {
-			$obj = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache');
-			if ($obj === false) {
-				//	Entry no longer exists in Memcache, so clear it from the cache array
-				parent::deleteCacheData($pCoord);
-				throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache');
-			}
-		} else {
-			//	Return null if requested entry doesn't exist in cache
-			return null;
-		}
-
-		//	Set current entry to the requested entry
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = unserialize($obj);
-        //    Re-attach this as the cell's parent
-        $this->_currentObject->attach($this);
-
-		//	Return requested entry
-		return $this->_currentObject;
-	}	//	function getCacheData()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return  string[]
-	 */
-	public function getCellList() {
-		if ($this->_currentObjectID !== null) {
-			$this->_storeData();
-		}
-
-		return parent::getCellList();
-	}
-
-
-    /**
-     * Delete a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to delete
-     * @throws	PHPExcel_Exception
-     */
-	public function deleteCacheData($pCoord) {
-		//	Delete the entry from Memcache
-		$this->_memcache->delete($this->_cachePrefix.$pCoord.'.cache');
-
-		//	Delete the entry from our cell address array
-		parent::deleteCacheData($pCoord);
-	}	//	function deleteCacheData()
-
-
-	/**
-	 * Clone the cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The new worksheet
-	 * @return	void
-	 */
-	public function copyCellCollection(PHPExcel_Worksheet $parent) {
-		parent::copyCellCollection($parent);
-		//	Get a new id for the new file name
-		$baseUnique = $this->_getUniqueID();
-		$newCachePrefix = substr(md5($baseUnique),0,8).'.';
-		$cacheList = $this->getCellList();
-		foreach($cacheList as $cellID) {
-			if ($cellID != $this->_currentObjectID) {
-				$obj = $this->_memcache->get($this->_cachePrefix.$cellID.'.cache');
-				if ($obj === false) {
-					//	Entry no longer exists in Memcache, so clear it from the cache array
-					parent::deleteCacheData($cellID);
-					throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in MemCache');
-				}
-				if (!$this->_memcache->add($newCachePrefix.$cellID.'.cache',$obj,NULL,$this->_cacheTime)) {
-					$this->__destruct();
-					throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in MemCache');
-				}
-			}
-		}
-		$this->_cachePrefix = $newCachePrefix;
-	}	//	function copyCellCollection()
-
-
-	/**
-	 * Clear the cell collection and disconnect from our parent
-	 *
-	 * @return	void
-	 */
-	public function unsetWorksheetCells() {
-		if(!is_null($this->_currentObject)) {
-			$this->_currentObject->detach();
-			$this->_currentObject = $this->_currentObjectID = null;
-		}
-
-		//	Flush the Memcache cache
-		$this->__destruct();
-
-		$this->_cellCache = array();
-
-		//	detach ourself from the worksheet, so that it can then delete this object successfully
-		$this->_parent = null;
-	}	//	function unsetWorksheetCells()
-
-
-	/**
-	 * Initialise this new cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The worksheet for this cell collection
-	 * @param	array of mixed		$arguments	Additional initialisation arguments
-	 */
-	public function __construct(PHPExcel_Worksheet $parent, $arguments) {
-		$memcacheServer	= (isset($arguments['memcacheServer']))	? $arguments['memcacheServer']	: 'localhost';
-		$memcachePort	= (isset($arguments['memcachePort']))	? $arguments['memcachePort']	: 11211;
-		$cacheTime		= (isset($arguments['cacheTime']))		? $arguments['cacheTime']		: 600;
-
-		if (is_null($this->_cachePrefix)) {
-			$baseUnique = $this->_getUniqueID();
-			$this->_cachePrefix = substr(md5($baseUnique),0,8).'.';
-
-			//	Set a new Memcache object and connect to the Memcache server
-			$this->_memcache = new Memcache();
-			if (!$this->_memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) {
-				throw new PHPExcel_Exception('Could not connect to MemCache server at '.$memcacheServer.':'.$memcachePort);
-			}
-			$this->_cacheTime = $cacheTime;
-
-			parent::__construct($parent);
-		}
-	}	//	function __construct()
-
-
-	/**
-	 * Memcache error handler
-	 *
-	 * @param	string	$host		Memcache server
-	 * @param	integer	$port		Memcache port
-     * @throws	PHPExcel_Exception
-	 */
-	public function failureCallback($host, $port) {
-		throw new PHPExcel_Exception('memcache '.$host.':'.$port.' failed');
-	}
-
-
-	/**
-	 * Destroy this cell collection
-	 */
-	public function __destruct() {
-		$cacheList = $this->getCellList();
-		foreach($cacheList as $cellID) {
-			$this->_memcache->delete($this->_cachePrefix.$cellID.'.cache');
-		}
-	}	//	function __destruct()
-
-	/**
-	 * Identify whether the caching method is currently available
-	 * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
-	 *
-	 * @return	boolean
-	 */
-	public static function cacheMethodIsAvailable() {
-		if (!function_exists('memcache_add')) {
-			return false;
-		}
-
-		return true;
-	}
-
-}
+_currentCellIsDirty && !empty($this->_currentObjectID)) {
+            $this->_currentObject->detach();
+
+            $obj = serialize($this->_currentObject);
+            if (!$this->_memcache->replace($this->_cachePrefix . $this->_currentObjectID . '.cache', $obj, null, $this->_cacheTime)) {
+                if (!$this->_memcache->add($this->_cachePrefix . $this->_currentObjectID . '.cache', $obj, null, $this->_cacheTime)) {
+                    $this->__destruct();
+                    throw new PHPExcel_Exception("Failed to store cell {$this->_currentObjectID} in MemCache");
+                }
+            }
+            $this->_currentCellIsDirty = false;
+        }
+        $this->_currentObjectID = $this->_currentObject = null;
+    }    //    function _storeData()
+
+
+    /**
+     * Add or Update a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to update
+     * @param    PHPExcel_Cell    $cell        Cell to update
+     * @return    PHPExcel_Cell
+     * @throws    PHPExcel_Exception
+     */
+    public function addCacheData($pCoord, PHPExcel_Cell $cell)
+    {
+        if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
+            $this->_storeData();
+        }
+        $this->_cellCache[$pCoord] = true;
+
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = $cell;
+        $this->_currentCellIsDirty = true;
+
+        return $cell;
+    }    //    function addCacheData()
+
+
+    /**
+     * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
+     *
+     * @param    string        $pCoord        Coordinate address of the cell to check
+     * @return    boolean
+     * @return    boolean
+     */
+    public function isDataSet($pCoord)
+    {
+        //    Check if the requested entry is the current object, or exists in the cache
+        if (parent::isDataSet($pCoord)) {
+            if ($this->_currentObjectID == $pCoord) {
+                return true;
+            }
+            //    Check if the requested entry still exists in Memcache
+            $success = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache');
+            if ($success === false) {
+                //    Entry no longer exists in Memcache, so clear it from the cache array
+                parent::deleteCacheData($pCoord);
+                throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache');
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Get cell at a specific coordinate
+     *
+     * @param     string             $pCoord        Coordinate of the cell
+     * @throws     PHPExcel_Exception
+     * @return     PHPExcel_Cell     Cell that was found, or null if not found
+     */
+    public function getCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return $this->_currentObject;
+        }
+        $this->_storeData();
+
+        //    Check if the entry that has been requested actually exists
+        if (parent::isDataSet($pCoord)) {
+            $obj = $this->_memcache->get($this->_cachePrefix . $pCoord . '.cache');
+            if ($obj === false) {
+                //    Entry no longer exists in Memcache, so clear it from the cache array
+                parent::deleteCacheData($pCoord);
+                throw new PHPExcel_Exception("Cell entry {$pCoord} no longer exists in MemCache");
+            }
+        } else {
+            //    Return null if requested entry doesn't exist in cache
+            return null;
+        }
+
+        //    Set current entry to the requested entry
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = unserialize($obj);
+        //    Re-attach this as the cell's parent
+        $this->_currentObject->attach($this);
+
+        //    Return requested entry
+        return $this->_currentObject;
+    }
+
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return  string[]
+     */
+    public function getCellList()
+    {
+        if ($this->_currentObjectID !== null) {
+            $this->_storeData();
+        }
+
+        return parent::getCellList();
+    }
+
+    /**
+     * Delete a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to delete
+     * @throws    PHPExcel_Exception
+     */
+    public function deleteCacheData($pCoord)
+    {
+        //    Delete the entry from Memcache
+        $this->_memcache->delete($this->_cachePrefix . $pCoord . '.cache');
+
+        //    Delete the entry from our cell address array
+        parent::deleteCacheData($pCoord);
+    }
+
+    /**
+     * Clone the cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The new worksheet
+     * @return    void
+     */
+    public function copyCellCollection(PHPExcel_Worksheet $parent)
+    {
+        parent::copyCellCollection($parent);
+        //    Get a new id for the new file name
+        $baseUnique = $this->_getUniqueID();
+        $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.';
+        $cacheList = $this->getCellList();
+        foreach ($cacheList as $cellID) {
+            if ($cellID != $this->_currentObjectID) {
+                $obj = $this->_memcache->get($this->_cachePrefix.$cellID.'.cache');
+                if ($obj === false) {
+                    //    Entry no longer exists in Memcache, so clear it from the cache array
+                    parent::deleteCacheData($cellID);
+                    throw new PHPExcel_Exception("Cell entry {$cellID} no longer exists in MemCache");
+                }
+                if (!$this->_memcache->add($newCachePrefix . $cellID . '.cache', $obj, null, $this->_cacheTime)) {
+                    $this->__destruct();
+                    throw new PHPExcel_Exception("Failed to store cell {$cellID} in MemCache");
+                }
+            }
+        }
+        $this->_cachePrefix = $newCachePrefix;
+    }
+
+    /**
+     * Clear the cell collection and disconnect from our parent
+     *
+     * @return    void
+     */
+    public function unsetWorksheetCells()
+    {
+        if (!is_null($this->_currentObject)) {
+            $this->_currentObject->detach();
+            $this->_currentObject = $this->_currentObjectID = null;
+        }
+
+        //    Flush the Memcache cache
+        $this->__destruct();
+
+        $this->_cellCache = array();
+
+        //    detach ourself from the worksheet, so that it can then delete this object successfully
+        $this->_parent = null;
+    }
+
+    /**
+     * Initialise this new cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The worksheet for this cell collection
+     * @param    array of mixed        $arguments    Additional initialisation arguments
+     */
+    public function __construct(PHPExcel_Worksheet $parent, $arguments)
+    {
+        $memcacheServer = (isset($arguments['memcacheServer'])) ? $arguments['memcacheServer'] : 'localhost';
+        $memcachePort = (isset($arguments['memcachePort'])) ? $arguments['memcachePort'] : 11211;
+        $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600;
+
+        if (is_null($this->_cachePrefix)) {
+            $baseUnique = $this->_getUniqueID();
+            $this->_cachePrefix = substr(md5($baseUnique), 0, 8) . '.';
+
+            //    Set a new Memcache object and connect to the Memcache server
+            $this->_memcache = new Memcache();
+            if (!$this->_memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) {
+                throw new PHPExcel_Exception("Could not connect to MemCache server at {$memcacheServer}:{$memcachePort}";
+            }
+            $this->_cacheTime = $cacheTime;
+
+            parent::__construct($parent);
+        }
+    }
+
+    /**
+     * Memcache error handler
+     *
+     * @param    string    $host        Memcache server
+     * @param    integer    $port        Memcache port
+     * @throws    PHPExcel_Exception
+     */
+    public function failureCallback($host, $port)
+    {
+        throw new PHPExcel_Exception("memcache {$host}:{$port} failed");
+    }
+
+    /**
+     * Destroy this cell collection
+     */
+    public function __destruct()
+    {
+        $cacheList = $this->getCellList();
+        foreach ($cacheList as $cellID) {
+            $this->_memcache->delete($this->_cachePrefix.$cellID . '.cache');
+        }
+    }
+
+    /**
+     * Identify whether the caching method is currently available
+     * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
+     *
+     * @return    boolean
+     */
+    public static function cacheMethodIsAvailable()
+    {
+        if (!function_exists('memcache_add')) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorage/Memory.php b/Classes/PHPExcel/CachedObjectStorage/Memory.php
index e11321476..aa3e1bb3d 100644
--- a/Classes/PHPExcel/CachedObjectStorage/Memory.php
+++ b/Classes/PHPExcel/CachedObjectStorage/Memory.php
@@ -1,125 +1,118 @@
-_cellCache[$pCoord] = $cell;
-
-		//	Set current entry to the new/updated entry
-		$this->_currentObjectID = $pCoord;
-
-		return $cell;
-	}	//	function addCacheData()
-
-
-    /**
-     * Get cell at a specific coordinate
-     *
-     * @param 	string 			$pCoord		Coordinate of the cell
-     * @throws 	PHPExcel_Exception
-     * @return 	PHPExcel_Cell 	Cell that was found, or null if not found
-     */
-	public function getCacheData($pCoord) {
-		//	Check if the entry that has been requested actually exists
-		if (!isset($this->_cellCache[$pCoord])) {
-			$this->_currentObjectID = NULL;
-			//	Return null if requested entry doesn't exist in cache
-			return null;
-		}
-
-		//	Set current entry to the requested entry
-		$this->_currentObjectID = $pCoord;
-
-		//	Return requested entry
-		return $this->_cellCache[$pCoord];
-	}	//	function getCacheData()
-
-
-	/**
-	 * Clone the cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The new worksheet
-	 * @return	void
-	 */
-	public function copyCellCollection(PHPExcel_Worksheet $parent) {
-		parent::copyCellCollection($parent);
-
-		$newCollection = array();
-		foreach($this->_cellCache as $k => &$cell) {
-			$newCollection[$k] = clone $cell;
-			$newCollection[$k]->attach($this);
-		}
-
-		$this->_cellCache = $newCollection;
-	}
-
-
-	/**
-	 * Clear the cell collection and disconnect from our parent
-	 *
-	 * @return	void
-	 */
-	public function unsetWorksheetCells() {
-		//	Because cells are all stored as intact objects in memory, we need to detach each one from the parent
-		foreach($this->_cellCache as $k => &$cell) {
-			$cell->detach();
-			$this->_cellCache[$k] = null;
-		}
-		unset($cell);
-
-		$this->_cellCache = array();
-
-		//	detach ourself from the worksheet, so that it can then delete this object successfully
-		$this->_parent = null;
-	}	//	function unsetWorksheetCells()
-
-}
+_cellCache[$pCoord] = $cell;
+
+        //    Set current entry to the new/updated entry
+        $this->_currentObjectID = $pCoord;
+
+        return $cell;
+    }
+
+
+    /**
+     * Get cell at a specific coordinate
+     *
+     * @param     string             $pCoord        Coordinate of the cell
+     * @throws     PHPExcel_Exception
+     * @return     PHPExcel_Cell     Cell that was found, or null if not found
+     */
+    public function getCacheData($pCoord)
+    {
+        //    Check if the entry that has been requested actually exists
+        if (!isset($this->_cellCache[$pCoord])) {
+            $this->_currentObjectID = null;
+            //    Return null if requested entry doesn't exist in cache
+            return null;
+        }
+
+        //    Set current entry to the requested entry
+        $this->_currentObjectID = $pCoord;
+
+        //    Return requested entry
+        return $this->_cellCache[$pCoord];
+    }
+
+
+    /**
+     * Clone the cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The new worksheet
+     */
+    public function copyCellCollection(PHPExcel_Worksheet $parent)
+    {
+        parent::copyCellCollection($parent);
+
+        $newCollection = array();
+        foreach ($this->_cellCache as $k => &$cell) {
+            $newCollection[$k] = clone $cell;
+            $newCollection[$k]->attach($this);
+        }
+
+        $this->_cellCache = $newCollection;
+    }
+
+    /**
+     * Clear the cell collection and disconnect from our parent
+     *
+     */
+    public function unsetWorksheetCells()
+    {
+        // Because cells are all stored as intact objects in memory, we need to detach each one from the parent
+        foreach ($this->_cellCache as $k => &$cell) {
+            $cell->detach();
+            $this->_cellCache[$k] = null;
+        }
+        unset($cell);
+
+        $this->_cellCache = array();
+
+        //    detach ourself from the worksheet, so that it can then delete this object successfully
+        $this->_parent = null;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php
index 3c1b7564c..16f010516 100644
--- a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php
+++ b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php
@@ -1,137 +1,133 @@
-_currentCellIsDirty && !empty($this->_currentObjectID)) {
-			$this->_currentObject->detach();
-
-			$this->_cellCache[$this->_currentObjectID] = gzdeflate(serialize($this->_currentObject));
-			$this->_currentCellIsDirty = false;
-		}
-		$this->_currentObjectID = $this->_currentObject = null;
-	}	//	function _storeData()
-
-
-    /**
-     * Add or Update a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to update
-     * @param	PHPExcel_Cell	$cell		Cell to update
-	 * @return	PHPExcel_Cell
-     * @throws	PHPExcel_Exception
-     */
-	public function addCacheData($pCoord, PHPExcel_Cell $cell) {
-		if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
-			$this->_storeData();
-		}
-
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = $cell;
-		$this->_currentCellIsDirty = true;
-
-		return $cell;
-	}	//	function addCacheData()
-
-
-    /**
-     * Get cell at a specific coordinate
-     *
-     * @param 	string 			$pCoord		Coordinate of the cell
-     * @throws 	PHPExcel_Exception
-     * @return 	PHPExcel_Cell 	Cell that was found, or null if not found
-     */
-	public function getCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return $this->_currentObject;
-		}
-		$this->_storeData();
-
-		//	Check if the entry that has been requested actually exists
-		if (!isset($this->_cellCache[$pCoord])) {
-			//	Return null if requested entry doesn't exist in cache
-			return null;
-		}
-
-		//	Set current entry to the requested entry
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = unserialize(gzinflate($this->_cellCache[$pCoord]));
-        //    Re-attach this as the cell's parent
-        $this->_currentObject->attach($this);
-
-		//	Return requested entry
-		return $this->_currentObject;
-	}	//	function getCacheData()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return  string[]
-	 */
-	public function getCellList() {
-		if ($this->_currentObjectID !== null) {
-			$this->_storeData();
-		}
-
-		return parent::getCellList();
-	}
-
-
-	/**
-	 * Clear the cell collection and disconnect from our parent
-	 *
-	 * @return	void
-	 */
-	public function unsetWorksheetCells() {
-		if(!is_null($this->_currentObject)) {
-			$this->_currentObject->detach();
-			$this->_currentObject = $this->_currentObjectID = null;
-		}
-		$this->_cellCache = array();
-
-		//	detach ourself from the worksheet, so that it can then delete this object successfully
-		$this->_parent = null;
-	}	//	function unsetWorksheetCells()
-
-}
+_currentCellIsDirty && !empty($this->_currentObjectID)) {
+            $this->_currentObject->detach();
+
+            $this->_cellCache[$this->_currentObjectID] = gzdeflate(serialize($this->_currentObject));
+            $this->_currentCellIsDirty = false;
+        }
+        $this->_currentObjectID = $this->_currentObject = null;
+    }
+
+
+    /**
+     * Add or Update a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to update
+     * @param    PHPExcel_Cell    $cell        Cell to update
+     * @return    PHPExcel_Cell
+     * @throws    PHPExcel_Exception
+     */
+    public function addCacheData($pCoord, PHPExcel_Cell $cell)
+    {
+        if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
+            $this->_storeData();
+        }
+
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = $cell;
+        $this->_currentCellIsDirty = true;
+
+        return $cell;
+    }
+
+
+    /**
+     * Get cell at a specific coordinate
+     *
+     * @param     string             $pCoord        Coordinate of the cell
+     * @throws     PHPExcel_Exception
+     * @return     PHPExcel_Cell     Cell that was found, or null if not found
+     */
+    public function getCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return $this->_currentObject;
+        }
+        $this->_storeData();
+
+        //    Check if the entry that has been requested actually exists
+        if (!isset($this->_cellCache[$pCoord])) {
+            //    Return null if requested entry doesn't exist in cache
+            return null;
+        }
+
+        //    Set current entry to the requested entry
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = unserialize(gzinflate($this->_cellCache[$pCoord]));
+        //    Re-attach this as the cell's parent
+        $this->_currentObject->attach($this);
+
+        //    Return requested entry
+        return $this->_currentObject;
+    }
+
+
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return  string[]
+     */
+    public function getCellList()
+    {
+        if ($this->_currentObjectID !== null) {
+            $this->_storeData();
+        }
+
+        return parent::getCellList();
+    }
+
+
+    /**
+     * Clear the cell collection and disconnect from our parent
+     *
+     * @return    void
+     */
+    public function unsetWorksheetCells()
+    {
+        if (!is_null($this->_currentObject)) {
+            $this->_currentObject->detach();
+            $this->_currentObject = $this->_currentObjectID = null;
+        }
+        $this->_cellCache = array();
+
+        //    detach ourself from the worksheet, so that it can then delete this object successfully
+        $this->_parent = null;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php
index aad8db870..285d0d8fa 100644
--- a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php
+++ b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php
@@ -1,137 +1,129 @@
-_currentCellIsDirty && !empty($this->_currentObjectID)) {
-			$this->_currentObject->detach();
-
-			$this->_cellCache[$this->_currentObjectID] = serialize($this->_currentObject);
-			$this->_currentCellIsDirty = false;
-		}
-		$this->_currentObjectID = $this->_currentObject = null;
-	}	//	function _storeData()
-
-
-    /**
-     * Add or Update a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to update
-     * @param	PHPExcel_Cell	$cell		Cell to update
-	 * @return	PHPExcel_Cell
-     * @throws	PHPExcel_Exception
-     */
-	public function addCacheData($pCoord, PHPExcel_Cell $cell) {
-		if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
-			$this->_storeData();
-		}
-
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = $cell;
-		$this->_currentCellIsDirty = true;
-
-		return $cell;
-	}	//	function addCacheData()
-
-
-    /**
-     * Get cell at a specific coordinate
-     *
-     * @param 	string 			$pCoord		Coordinate of the cell
-     * @throws 	PHPExcel_Exception
-     * @return 	PHPExcel_Cell 	Cell that was found, or null if not found
-     */
-	public function getCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return $this->_currentObject;
-		}
-		$this->_storeData();
-
-		//	Check if the entry that has been requested actually exists
-		if (!isset($this->_cellCache[$pCoord])) {
-			//	Return null if requested entry doesn't exist in cache
-			return null;
-		}
-
-		//	Set current entry to the requested entry
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = unserialize($this->_cellCache[$pCoord]);
-        //    Re-attach this as the cell's parent
-        $this->_currentObject->attach($this);
-
-		//	Return requested entry
-		return $this->_currentObject;
-	}	//	function getCacheData()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return  string[]
-	 */
-	public function getCellList() {
-		if ($this->_currentObjectID !== null) {
-			$this->_storeData();
-		}
-
-		return parent::getCellList();
-	}
-
-
-	/**
-	 * Clear the cell collection and disconnect from our parent
-	 *
-	 * @return	void
-	 */
-	public function unsetWorksheetCells() {
-		if(!is_null($this->_currentObject)) {
-			$this->_currentObject->detach();
-			$this->_currentObject = $this->_currentObjectID = null;
-		}
-		$this->_cellCache = array();
-
-		//	detach ourself from the worksheet, so that it can then delete this object successfully
-		$this->_parent = null;
-	}	//	function unsetWorksheetCells()
-
-}
+_currentCellIsDirty && !empty($this->_currentObjectID)) {
+            $this->_currentObject->detach();
+
+            $this->_cellCache[$this->_currentObjectID] = serialize($this->_currentObject);
+            $this->_currentCellIsDirty = false;
+        }
+        $this->_currentObjectID = $this->_currentObject = null;
+    }
+
+    /**
+     * Add or Update a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to update
+     * @param    PHPExcel_Cell    $cell        Cell to update
+     * @return    PHPExcel_Cell
+     * @throws    PHPExcel_Exception
+     */
+    public function addCacheData($pCoord, PHPExcel_Cell $cell)
+    {
+        if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
+            $this->_storeData();
+        }
+
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = $cell;
+        $this->_currentCellIsDirty = true;
+
+        return $cell;
+    }
+
+    /**
+     * Get cell at a specific coordinate
+     *
+     * @param     string             $pCoord        Coordinate of the cell
+     * @throws     PHPExcel_Exception
+     * @return     PHPExcel_Cell     Cell that was found, or null if not found
+     */
+    public function getCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return $this->_currentObject;
+        }
+        $this->_storeData();
+
+        //    Check if the entry that has been requested actually exists
+        if (!isset($this->_cellCache[$pCoord])) {
+            //    Return null if requested entry doesn't exist in cache
+            return null;
+        }
+
+        //    Set current entry to the requested entry
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = unserialize($this->_cellCache[$pCoord]);
+        //    Re-attach this as the cell's parent
+        $this->_currentObject->attach($this);
+
+        //    Return requested entry
+        return $this->_currentObject;
+    }
+
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return  string[]
+     */
+    public function getCellList()
+    {
+        if ($this->_currentObjectID !== null) {
+            $this->_storeData();
+        }
+
+        return parent::getCellList();
+    }
+
+    /**
+     * Clear the cell collection and disconnect from our parent
+     *
+     * @return    void
+     */
+    public function unsetWorksheetCells()
+    {
+        if (!is_null($this->_currentObject)) {
+            $this->_currentObject->detach();
+            $this->_currentObject = $this->_currentObjectID = null;
+        }
+        $this->_cellCache = array();
+
+        //    detach ourself from the worksheet, so that it can then delete this object successfully
+        $this->_parent = null;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php
index 04d30999e..6176bf1e9 100644
--- a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php
+++ b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php
@@ -1,206 +1,200 @@
-_currentCellIsDirty && !empty($this->_currentObjectID)) {
-			$this->_currentObject->detach();
-
-			fseek($this->_fileHandle,0,SEEK_END);
-
-			$this->_cellCache[$this->_currentObjectID] = array(
-                'ptr' => ftell($this->_fileHandle),
-				'sz'  => fwrite($this->_fileHandle, serialize($this->_currentObject))
-			);
-			$this->_currentCellIsDirty = false;
-		}
-		$this->_currentObjectID = $this->_currentObject = null;
-	}	//	function _storeData()
-
-
-    /**
-     * Add or Update a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to update
-     * @param	PHPExcel_Cell	$cell		Cell to update
-	 * @return	PHPExcel_Cell
-     * @throws	PHPExcel_Exception
-     */
-	public function addCacheData($pCoord, PHPExcel_Cell $cell) {
-		if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
-			$this->_storeData();
-		}
-
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = $cell;
-		$this->_currentCellIsDirty = true;
-
-		return $cell;
-	}	//	function addCacheData()
-
-
-    /**
-     * Get cell at a specific coordinate
-     *
-     * @param 	string 			$pCoord		Coordinate of the cell
-     * @throws 	PHPExcel_Exception
-     * @return 	PHPExcel_Cell 	Cell that was found, or null if not found
-     */
-	public function getCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return $this->_currentObject;
-		}
-		$this->_storeData();
-
-		//	Check if the entry that has been requested actually exists
-		if (!isset($this->_cellCache[$pCoord])) {
-			//	Return null if requested entry doesn't exist in cache
-			return null;
-		}
-
-		//	Set current entry to the requested entry
-		$this->_currentObjectID = $pCoord;
-		fseek($this->_fileHandle,$this->_cellCache[$pCoord]['ptr']);
-		$this->_currentObject = unserialize(fread($this->_fileHandle,$this->_cellCache[$pCoord]['sz']));
-        //    Re-attach this as the cell's parent
-        $this->_currentObject->attach($this);
-
-		//	Return requested entry
-		return $this->_currentObject;
-	}	//	function getCacheData()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return  string[]
-	 */
-	public function getCellList() {
-		if ($this->_currentObjectID !== null) {
-			$this->_storeData();
-		}
-
-		return parent::getCellList();
-	}
-
-
-	/**
-	 * Clone the cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The new worksheet
-	 * @return	void
-	 */
-	public function copyCellCollection(PHPExcel_Worksheet $parent) {
-		parent::copyCellCollection($parent);
-		//	Open a new stream for the cell cache data
-		$newFileHandle = fopen('php://temp/maxmemory:'.$this->_memoryCacheSize,'a+');
-		//	Copy the existing cell cache data to the new stream
-		fseek($this->_fileHandle,0);
-		while (!feof($this->_fileHandle)) {
-			fwrite($newFileHandle,fread($this->_fileHandle, 1024));
-		}
-		$this->_fileHandle = $newFileHandle;
-	}	//	function copyCellCollection()
-
-
-	/**
-	 * Clear the cell collection and disconnect from our parent
-	 *
-	 * @return	void
-	 */
-	public function unsetWorksheetCells() {
-		if(!is_null($this->_currentObject)) {
-			$this->_currentObject->detach();
-			$this->_currentObject = $this->_currentObjectID = null;
-		}
-		$this->_cellCache = array();
-
-		//	detach ourself from the worksheet, so that it can then delete this object successfully
-		$this->_parent = null;
-
-		//	Close down the php://temp file
-		$this->__destruct();
-	}	//	function unsetWorksheetCells()
-
-
-	/**
-	 * Initialise this new cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The worksheet for this cell collection
-	 * @param	array of mixed		$arguments	Additional initialisation arguments
-	 */
-	public function __construct(PHPExcel_Worksheet $parent, $arguments) {
-		$this->_memoryCacheSize	= (isset($arguments['memoryCacheSize']))	? $arguments['memoryCacheSize']	: '1MB';
-
-		parent::__construct($parent);
-		if (is_null($this->_fileHandle)) {
-			$this->_fileHandle = fopen('php://temp/maxmemory:'.$this->_memoryCacheSize,'a+');
-		}
-	}	//	function __construct()
-
-
-	/**
-	 * Destroy this cell collection
-	 */
-	public function __destruct() {
-		if (!is_null($this->_fileHandle)) {
-			fclose($this->_fileHandle);
-		}
-		$this->_fileHandle = null;
-	}	//	function __destruct()
-
-}
+_currentCellIsDirty && !empty($this->_currentObjectID)) {
+            $this->_currentObject->detach();
+
+            fseek($this->_fileHandle, 0, SEEK_END);
+
+            $this->_cellCache[$this->_currentObjectID] = array(
+                'ptr' => ftell($this->_fileHandle),
+                'sz'  => fwrite($this->_fileHandle, serialize($this->_currentObject))
+            );
+            $this->_currentCellIsDirty = false;
+        }
+        $this->_currentObjectID = $this->_currentObject = null;
+    }
+
+
+    /**
+     * Add or Update a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to update
+     * @param    PHPExcel_Cell    $cell        Cell to update
+     * @return    PHPExcel_Cell
+     * @throws    PHPExcel_Exception
+     */
+    public function addCacheData($pCoord, PHPExcel_Cell $cell)
+    {
+        if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
+            $this->_storeData();
+        }
+
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = $cell;
+        $this->_currentCellIsDirty = true;
+
+        return $cell;
+    }
+
+
+    /**
+     * Get cell at a specific coordinate
+     *
+     * @param     string             $pCoord        Coordinate of the cell
+     * @throws     PHPExcel_Exception
+     * @return     PHPExcel_Cell     Cell that was found, or null if not found
+     */
+    public function getCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return $this->_currentObject;
+        }
+        $this->_storeData();
+
+        //    Check if the entry that has been requested actually exists
+        if (!isset($this->_cellCache[$pCoord])) {
+            //    Return null if requested entry doesn't exist in cache
+            return null;
+        }
+
+        //    Set current entry to the requested entry
+        $this->_currentObjectID = $pCoord;
+        fseek($this->_fileHandle, $this->_cellCache[$pCoord]['ptr']);
+        $this->_currentObject = unserialize(fread($this->_fileHandle, $this->_cellCache[$pCoord]['sz']));
+        //    Re-attach this as the cell's parent
+        $this->_currentObject->attach($this);
+
+        //    Return requested entry
+        return $this->_currentObject;
+    }
+
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return  string[]
+     */
+    public function getCellList()
+    {
+        if ($this->_currentObjectID !== null) {
+            $this->_storeData();
+        }
+
+        return parent::getCellList();
+    }
+
+    /**
+     * Clone the cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The new worksheet
+     * @return    void
+     */
+    public function copyCellCollection(PHPExcel_Worksheet $parent)
+    {
+        parent::copyCellCollection($parent);
+        //    Open a new stream for the cell cache data
+        $newFileHandle = fopen('php://temp/maxmemory:' . $this->_memoryCacheSize, 'a+');
+        //    Copy the existing cell cache data to the new stream
+        fseek($this->_fileHandle, 0);
+        while (!feof($this->_fileHandle)) {
+            fwrite($newFileHandle, fread($this->_fileHandle, 1024));
+        }
+        $this->_fileHandle = $newFileHandle;
+    }
+
+    /**
+     * Clear the cell collection and disconnect from our parent
+     *
+     * @return    void
+     */
+    public function unsetWorksheetCells()
+    {
+        if (!is_null($this->_currentObject)) {
+            $this->_currentObject->detach();
+            $this->_currentObject = $this->_currentObjectID = null;
+        }
+        $this->_cellCache = array();
+
+        //    detach ourself from the worksheet, so that it can then delete this object successfully
+        $this->_parent = null;
+
+        //    Close down the php://temp file
+        $this->__destruct();
+    }
+
+    /**
+     * Initialise this new cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The worksheet for this cell collection
+     * @param    array of mixed        $arguments    Additional initialisation arguments
+     */
+    public function __construct(PHPExcel_Worksheet $parent, $arguments)
+    {
+        $this->_memoryCacheSize = (isset($arguments['memoryCacheSize'])) ? $arguments['memoryCacheSize'] : '1MB';
+
+        parent::__construct($parent);
+        if (is_null($this->_fileHandle)) {
+            $this->_fileHandle = fopen('php://temp/maxmemory:' . $this->_memoryCacheSize, 'a+');
+        }
+    }
+
+    /**
+     * Destroy this cell collection
+     */
+    public function __destruct()
+    {
+        if (!is_null($this->_fileHandle)) {
+            fclose($this->_fileHandle);
+        }
+        $this->_fileHandle = null;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php
index 92179a286..0a63cd2d8 100644
--- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php
+++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php
@@ -1,306 +1,307 @@
-_currentCellIsDirty && !empty($this->_currentObjectID)) {
-			$this->_currentObject->detach();
-
-			if (!$this->_DBHandle->queryExec("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES('".$this->_currentObjectID."','".sqlite_escape_string(serialize($this->_currentObject))."')"))
-				throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
-			$this->_currentCellIsDirty = false;
-		}
-		$this->_currentObjectID = $this->_currentObject = null;
-	}	//	function _storeData()
-
-
-    /**
-     * Add or Update a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to update
-     * @param	PHPExcel_Cell	$cell		Cell to update
-	 * @return	PHPExcel_Cell
-     * @throws	PHPExcel_Exception
-     */
-	public function addCacheData($pCoord, PHPExcel_Cell $cell) {
-		if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
-			$this->_storeData();
-		}
-
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = $cell;
-		$this->_currentCellIsDirty = true;
-
-		return $cell;
-	}	//	function addCacheData()
-
-
-    /**
-     * Get cell at a specific coordinate
-     *
-     * @param 	string 			$pCoord		Coordinate of the cell
-     * @throws 	PHPExcel_Exception
-     * @return 	PHPExcel_Cell 	Cell that was found, or null if not found
-     */
-	public function getCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return $this->_currentObject;
-		}
-		$this->_storeData();
-
-		$query = "SELECT value FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'";
-		$cellResultSet = $this->_DBHandle->query($query,SQLITE_ASSOC);
-		if ($cellResultSet === false) {
-			throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
-		} elseif ($cellResultSet->numRows() == 0) {
-			//	Return null if requested entry doesn't exist in cache
-			return null;
-		}
-
-		//	Set current entry to the requested entry
-		$this->_currentObjectID = $pCoord;
-
-		$cellResult = $cellResultSet->fetchSingle();
-		$this->_currentObject = unserialize($cellResult);
-        //    Re-attach this as the cell's parent
-        $this->_currentObject->attach($this);
-
-		//	Return requested entry
-		return $this->_currentObject;
-	}	//	function getCacheData()
-
-
-	/**
-	 * Is a value set for an indexed cell?
-	 *
-	 * @param	string		$pCoord		Coordinate address of the cell to check
-	 * @return	boolean
-	 */
-	public function isDataSet($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return true;
-		}
-
-		//	Check if the requested entry exists in the cache
-		$query = "SELECT id FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'";
-		$cellResultSet = $this->_DBHandle->query($query,SQLITE_ASSOC);
-		if ($cellResultSet === false) {
-			throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
-		} elseif ($cellResultSet->numRows() == 0) {
-			//	Return null if requested entry doesn't exist in cache
-			return false;
-		}
-		return true;
-	}	//	function isDataSet()
-
-
-    /**
-     * Delete a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to delete
-     * @throws	PHPExcel_Exception
-     */
-	public function deleteCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			$this->_currentObject->detach();
-			$this->_currentObjectID = $this->_currentObject = null;
-		}
-
-		//	Check if the requested entry exists in the cache
-		$query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'";
-		if (!$this->_DBHandle->queryExec($query))
-			throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
-
-		$this->_currentCellIsDirty = false;
-	}	//	function deleteCacheData()
-
-
-	/**
-	 * Move a cell object from one address to another
-	 *
-	 * @param	string		$fromAddress	Current address of the cell to move
-	 * @param	string		$toAddress		Destination address of the cell to move
-	 * @return	boolean
-	 */
-	public function moveCell($fromAddress, $toAddress) {
-		if ($fromAddress === $this->_currentObjectID) {
-			$this->_currentObjectID = $toAddress;
-		}
-
-		$query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$toAddress."'";
-		$result = $this->_DBHandle->exec($query);
-		if ($result === false)
-			throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-
-		$query = "UPDATE kvp_".$this->_TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'";
-		$result = $this->_DBHandle->exec($query);
-		if ($result === false)
-			throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-
-		return TRUE;
-	}	//	function moveCell()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return	string[]
-	 */
-	public function getCellList() {
-		if ($this->_currentObjectID !== null) {
-			$this->_storeData();
-		}
-
-		$query = "SELECT id FROM kvp_".$this->_TableName;
-		$cellIdsResult = $this->_DBHandle->unbufferedQuery($query,SQLITE_ASSOC);
-		if ($cellIdsResult === false)
-			throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
-
-		$cellKeys = array();
-		foreach($cellIdsResult as $row) {
-			$cellKeys[] = $row['id'];
-		}
-
-		return $cellKeys;
-	}	//	function getCellList()
-
-
-	/**
-	 * Clone the cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The new worksheet
-	 * @return	void
-	 */
-	public function copyCellCollection(PHPExcel_Worksheet $parent) {
-		$this->_currentCellIsDirty;
-        $this->_storeData();
-
-		//	Get a new id for the new table name
-		$tableName = str_replace('.','_',$this->_getUniqueID());
-		if (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)
-													AS SELECT * FROM kvp_'.$this->_TableName))
-			throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
-
-		//	Copy the existing cell cache file
-		$this->_TableName = $tableName;
-	}	//	function copyCellCollection()
-
-
-	/**
-	 * Clear the cell collection and disconnect from our parent
-	 *
-	 * @return	void
-	 */
-	public function unsetWorksheetCells() {
-		if(!is_null($this->_currentObject)) {
-			$this->_currentObject->detach();
-			$this->_currentObject = $this->_currentObjectID = null;
-		}
-		//	detach ourself from the worksheet, so that it can then delete this object successfully
-		$this->_parent = null;
-
-		//	Close down the temporary cache file
-		$this->__destruct();
-	}	//	function unsetWorksheetCells()
-
-
-	/**
-	 * Initialise this new cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The worksheet for this cell collection
-	 */
-	public function __construct(PHPExcel_Worksheet $parent) {
-		parent::__construct($parent);
-		if (is_null($this->_DBHandle)) {
-			$this->_TableName = str_replace('.','_',$this->_getUniqueID());
-			$_DBName = ':memory:';
-
-			$this->_DBHandle = new SQLiteDatabase($_DBName);
-			if ($this->_DBHandle === false)
-				throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
-			if (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)'))
-				throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
-		}
-	}	//	function __construct()
-
-
-	/**
-	 * Destroy this cell collection
-	 */
-	public function __destruct() {
-		if (!is_null($this->_DBHandle)) {
-			$this->_DBHandle->queryExec('DROP TABLE kvp_'.$this->_TableName);
-		}
-		$this->_DBHandle = null;
-	}	//	function __destruct()
-
-
-	/**
-	 * Identify whether the caching method is currently available
-	 * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
-	 *
-	 * @return	boolean
-	 */
-	public static function cacheMethodIsAvailable() {
-		if (!function_exists('sqlite_open')) {
-			return false;
-		}
-
-		return true;
-	}
-
-}
+_currentCellIsDirty && !empty($this->_currentObjectID)) {
+            $this->_currentObject->detach();
+
+            if (!$this->_DBHandle->queryExec("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES('".$this->_currentObjectID."','".sqlite_escape_string(serialize($this->_currentObject))."')")) {
+                throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
+            }
+            $this->_currentCellIsDirty = false;
+        }
+        $this->_currentObjectID = $this->_currentObject = null;
+    }
+
+    /**
+     * Add or Update a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to update
+     * @param    PHPExcel_Cell    $cell        Cell to update
+     * @return    PHPExcel_Cell
+     * @throws    PHPExcel_Exception
+     */
+    public function addCacheData($pCoord, PHPExcel_Cell $cell)
+    {
+        if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
+            $this->_storeData();
+        }
+
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = $cell;
+        $this->_currentCellIsDirty = true;
+
+        return $cell;
+    }
+
+    /**
+     * Get cell at a specific coordinate
+     *
+     * @param     string             $pCoord        Coordinate of the cell
+     * @throws     PHPExcel_Exception
+     * @return     PHPExcel_Cell     Cell that was found, or null if not found
+     */
+    public function getCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return $this->_currentObject;
+        }
+        $this->_storeData();
+
+        $query = "SELECT value FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'";
+        $cellResultSet = $this->_DBHandle->query($query, SQLITE_ASSOC);
+        if ($cellResultSet === false) {
+            throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
+        } elseif ($cellResultSet->numRows() == 0) {
+            //    Return null if requested entry doesn't exist in cache
+            return null;
+        }
+
+        //    Set current entry to the requested entry
+        $this->_currentObjectID = $pCoord;
+
+        $cellResult = $cellResultSet->fetchSingle();
+        $this->_currentObject = unserialize($cellResult);
+        //    Re-attach this as the cell's parent
+        $this->_currentObject->attach($this);
+
+        //    Return requested entry
+        return $this->_currentObject;
+    }
+
+    /**
+     * Is a value set for an indexed cell?
+     *
+     * @param    string        $pCoord        Coordinate address of the cell to check
+     * @return    boolean
+     */
+    public function isDataSet($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return true;
+        }
+
+        //    Check if the requested entry exists in the cache
+        $query = "SELECT id FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'";
+        $cellResultSet = $this->_DBHandle->query($query, SQLITE_ASSOC);
+        if ($cellResultSet === false) {
+            throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
+        } elseif ($cellResultSet->numRows() == 0) {
+            //    Return null if requested entry doesn't exist in cache
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Delete a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to delete
+     * @throws    PHPExcel_Exception
+     */
+    public function deleteCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            $this->_currentObject->detach();
+            $this->_currentObjectID = $this->_currentObject = null;
+        }
+
+        //    Check if the requested entry exists in the cache
+        $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'";
+        if (!$this->_DBHandle->queryExec($query)) {
+            throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
+        }
+
+        $this->_currentCellIsDirty = false;
+    }
+
+    /**
+     * Move a cell object from one address to another
+     *
+     * @param    string        $fromAddress    Current address of the cell to move
+     * @param    string        $toAddress        Destination address of the cell to move
+     * @return    boolean
+     */
+    public function moveCell($fromAddress, $toAddress)
+    {
+        if ($fromAddress === $this->_currentObjectID) {
+            $this->_currentObjectID = $toAddress;
+        }
+
+        $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$toAddress."'";
+        $result = $this->_DBHandle->exec($query);
+        if ($result === false) {
+            throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+        }
+
+        $query = "UPDATE kvp_".$this->_TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'";
+        $result = $this->_DBHandle->exec($query);
+        if ($result === false) {
+            throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+        }
+
+        return true;
+    }
+
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return    string[]
+     */
+    public function getCellList()
+    {
+        if ($this->_currentObjectID !== null) {
+            $this->_storeData();
+        }
+
+        $query = "SELECT id FROM kvp_".$this->_TableName;
+        $cellIdsResult = $this->_DBHandle->unbufferedQuery($query, SQLITE_ASSOC);
+        if ($cellIdsResult === false) {
+            throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
+        }
+
+        $cellKeys = array();
+        foreach ($cellIdsResult as $row) {
+            $cellKeys[] = $row['id'];
+        }
+
+        return $cellKeys;
+    }
+
+    /**
+     * Clone the cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The new worksheet
+     * @return    void
+     */
+    public function copyCellCollection(PHPExcel_Worksheet $parent)
+    {
+        $this->_currentCellIsDirty;
+        $this->_storeData();
+
+        //    Get a new id for the new table name
+        $tableName = str_replace('.', '_', $this->_getUniqueID());
+        if (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)
+            AS SELECT * FROM kvp_'.$this->_TableName)
+        ) {
+            throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
+        }
+
+        //    Copy the existing cell cache file
+        $this->_TableName = $tableName;
+    }
+
+    /**
+     * Clear the cell collection and disconnect from our parent
+     *
+     * @return    void
+     */
+    public function unsetWorksheetCells()
+    {
+        if (!is_null($this->_currentObject)) {
+            $this->_currentObject->detach();
+            $this->_currentObject = $this->_currentObjectID = null;
+        }
+        //    detach ourself from the worksheet, so that it can then delete this object successfully
+        $this->_parent = null;
+
+        //    Close down the temporary cache file
+        $this->__destruct();
+    }
+
+    /**
+     * Initialise this new cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The worksheet for this cell collection
+     */
+    public function __construct(PHPExcel_Worksheet $parent)
+    {
+        parent::__construct($parent);
+        if (is_null($this->_DBHandle)) {
+            $this->_TableName = str_replace('.', '_', $this->_getUniqueID());
+            $_DBName = ':memory:';
+
+            $this->_DBHandle = new SQLiteDatabase($_DBName);
+            if ($this->_DBHandle === false) {
+                throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
+            }
+            if (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) {
+                throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));
+            }
+        }
+    }
+
+    /**
+     * Destroy this cell collection
+     */
+    public function __destruct()
+    {
+        if (!is_null($this->_DBHandle)) {
+            $this->_DBHandle->queryExec('DROP TABLE kvp_'.$this->_TableName);
+        }
+        $this->_DBHandle = null;
+    }
+
+    /**
+     * Identify whether the caching method is currently available
+     * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
+     *
+     * @return    boolean
+     */
+    public static function cacheMethodIsAvailable()
+    {
+        if (!function_exists('sqlite_open')) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php
index c54adb4ef..4d013eff6 100644
--- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php
+++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php
@@ -1,345 +1,346 @@
-_currentCellIsDirty && !empty($this->_currentObjectID)) {
-			$this->_currentObject->detach();
-
-			$this->_insertQuery->bindValue('id',$this->_currentObjectID,SQLITE3_TEXT);
-			$this->_insertQuery->bindValue('data',serialize($this->_currentObject),SQLITE3_BLOB);
-			$result = $this->_insertQuery->execute();
-			if ($result === false)
-				throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-			$this->_currentCellIsDirty = false;
-		}
-		$this->_currentObjectID = $this->_currentObject = null;
-	}	//	function _storeData()
-
-
-    /**
-     * Add or Update a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to update
-     * @param	PHPExcel_Cell	$cell		Cell to update
-	 * @return	PHPExcel_Cell
-     * @throws	PHPExcel_Exception
-     */
-	public function addCacheData($pCoord, PHPExcel_Cell $cell) {
-		if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
-			$this->_storeData();
-		}
-
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = $cell;
-		$this->_currentCellIsDirty = true;
-
-		return $cell;
-	}	//	function addCacheData()
-
-
-    /**
-     * Get cell at a specific coordinate
-     *
-     * @param 	string 			$pCoord		Coordinate of the cell
-     * @throws 	PHPExcel_Exception
-     * @return 	PHPExcel_Cell 	Cell that was found, or null if not found
-     */
-	public function getCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return $this->_currentObject;
-		}
-		$this->_storeData();
-
-		$this->_selectQuery->bindValue('id',$pCoord,SQLITE3_TEXT);
-		$cellResult = $this->_selectQuery->execute();
-		if ($cellResult === FALSE) {
-			throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-		}
-		$cellData = $cellResult->fetchArray(SQLITE3_ASSOC);
-		if ($cellData === FALSE) {
-			//	Return null if requested entry doesn't exist in cache
-			return NULL;
-		}
-
-		//	Set current entry to the requested entry
-		$this->_currentObjectID = $pCoord;
-
-		$this->_currentObject = unserialize($cellData['value']);
-        //    Re-attach this as the cell's parent
-        $this->_currentObject->attach($this);
-
-		//	Return requested entry
-		return $this->_currentObject;
-	}	//	function getCacheData()
-
-
-	/**
-	 *	Is a value set for an indexed cell?
-	 *
-	 * @param	string		$pCoord		Coordinate address of the cell to check
-	 * @return	boolean
-	 */
-	public function isDataSet($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return TRUE;
-		}
-
-		//	Check if the requested entry exists in the cache
-		$this->_selectQuery->bindValue('id',$pCoord,SQLITE3_TEXT);
-		$cellResult = $this->_selectQuery->execute();
-		if ($cellResult === FALSE) {
-			throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-		}
-		$cellData = $cellResult->fetchArray(SQLITE3_ASSOC);
-
-		return ($cellData === FALSE) ? FALSE : TRUE;
-	}	//	function isDataSet()
-
-
-    /**
-     *	Delete a cell in cache identified by coordinate address
-     *
-     * @param	string			$pCoord		Coordinate address of the cell to delete
-     * @throws	PHPExcel_Exception
-     */
-	public function deleteCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			$this->_currentObject->detach();
-			$this->_currentObjectID = $this->_currentObject = NULL;
-		}
-
-		//	Check if the requested entry exists in the cache
-		$this->_deleteQuery->bindValue('id',$pCoord,SQLITE3_TEXT);
-		$result = $this->_deleteQuery->execute();
-		if ($result === FALSE)
-			throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-
-		$this->_currentCellIsDirty = FALSE;
-	}	//	function deleteCacheData()
-
-
-	/**
-	 * Move a cell object from one address to another
-	 *
-	 * @param	string		$fromAddress	Current address of the cell to move
-	 * @param	string		$toAddress		Destination address of the cell to move
-	 * @return	boolean
-	 */
-	public function moveCell($fromAddress, $toAddress) {
-		if ($fromAddress === $this->_currentObjectID) {
-			$this->_currentObjectID = $toAddress;
-		}
-
-		$this->_deleteQuery->bindValue('id',$toAddress,SQLITE3_TEXT);
-		$result = $this->_deleteQuery->execute();
-		if ($result === false)
-			throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-
-		$this->_updateQuery->bindValue('toid',$toAddress,SQLITE3_TEXT);
-		$this->_updateQuery->bindValue('fromid',$fromAddress,SQLITE3_TEXT);
-		$result = $this->_updateQuery->execute();
-		if ($result === false)
-			throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-
-		return TRUE;
-	}	//	function moveCell()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return	string[]
-	 */
-	public function getCellList() {
-		if ($this->_currentObjectID !== null) {
-			$this->_storeData();
-		}
-
-		$query = "SELECT id FROM kvp_".$this->_TableName;
-		$cellIdsResult = $this->_DBHandle->query($query);
-		if ($cellIdsResult === false)
-			throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-
-		$cellKeys = array();
-		while ($row = $cellIdsResult->fetchArray(SQLITE3_ASSOC)) {
-			$cellKeys[] = $row['id'];
-		}
-
-		return $cellKeys;
-	}	//	function getCellList()
-
-
-	/**
-	 * Clone the cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The new worksheet
-	 * @return	void
-	 */
-	public function copyCellCollection(PHPExcel_Worksheet $parent) {
-		$this->_currentCellIsDirty;
-        $this->_storeData();
-
-		//	Get a new id for the new table name
-		$tableName = str_replace('.','_',$this->_getUniqueID());
-		if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)
-		                                       AS SELECT * FROM kvp_'.$this->_TableName))
-			throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-
-		//	Copy the existing cell cache file
-		$this->_TableName = $tableName;
-	}	//	function copyCellCollection()
-
-
-	/**
-	 * Clear the cell collection and disconnect from our parent
-	 *
-	 * @return	void
-	 */
-	public function unsetWorksheetCells() {
-		if(!is_null($this->_currentObject)) {
-			$this->_currentObject->detach();
-			$this->_currentObject = $this->_currentObjectID = null;
-		}
-		//	detach ourself from the worksheet, so that it can then delete this object successfully
-		$this->_parent = null;
-
-		//	Close down the temporary cache file
-		$this->__destruct();
-	}	//	function unsetWorksheetCells()
-
-
-	/**
-	 * Initialise this new cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The worksheet for this cell collection
-	 */
-	public function __construct(PHPExcel_Worksheet $parent) {
-		parent::__construct($parent);
-		if (is_null($this->_DBHandle)) {
-			$this->_TableName = str_replace('.','_',$this->_getUniqueID());
-			$_DBName = ':memory:';
-
-			$this->_DBHandle = new SQLite3($_DBName);
-			if ($this->_DBHandle === false)
-				throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-			if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)'))
-				throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
-		}
-
-		$this->_selectQuery = $this->_DBHandle->prepare("SELECT value FROM kvp_".$this->_TableName." WHERE id = :id");
-		$this->_insertQuery = $this->_DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES(:id,:data)");
-		$this->_updateQuery = $this->_DBHandle->prepare("UPDATE kvp_".$this->_TableName." SET id=:toId WHERE id=:fromId");
-		$this->_deleteQuery = $this->_DBHandle->prepare("DELETE FROM kvp_".$this->_TableName." WHERE id = :id");
-	}	//	function __construct()
-
-
-	/**
-	 * Destroy this cell collection
-	 */
-	public function __destruct() {
-		if (!is_null($this->_DBHandle)) {
-			$this->_DBHandle->exec('DROP TABLE kvp_'.$this->_TableName);
-			$this->_DBHandle->close();
-		}
-		$this->_DBHandle = null;
-	}	//	function __destruct()
-
-
-	/**
-	 * Identify whether the caching method is currently available
-	 * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
-	 *
-	 * @return	boolean
-	 */
-	public static function cacheMethodIsAvailable() {
-		if (!class_exists('SQLite3',FALSE)) {
-			return false;
-		}
-
-		return true;
-	}
-
-}
+_currentCellIsDirty && !empty($this->_currentObjectID)) {
+            $this->_currentObject->detach();
+
+            $this->_insertQuery->bindValue('id', $this->_currentObjectID, SQLITE3_TEXT);
+            $this->_insertQuery->bindValue('data', serialize($this->_currentObject), SQLITE3_BLOB);
+            $result = $this->_insertQuery->execute();
+            if ($result === false) {
+                throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+            }
+            $this->_currentCellIsDirty = false;
+        }
+        $this->_currentObjectID = $this->_currentObject = null;
+    }
+
+    /**
+     * Add or Update a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to update
+     * @param    PHPExcel_Cell    $cell        Cell to update
+     * @return    PHPExcel_Cell
+     * @throws    PHPExcel_Exception
+     */
+    public function addCacheData($pCoord, PHPExcel_Cell $cell)
+    {
+        if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
+            $this->_storeData();
+        }
+
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = $cell;
+        $this->_currentCellIsDirty = true;
+
+        return $cell;
+    }
+
+    /**
+     * Get cell at a specific coordinate
+     *
+     * @param     string             $pCoord        Coordinate of the cell
+     * @throws     PHPExcel_Exception
+     * @return     PHPExcel_Cell     Cell that was found, or null if not found
+     */
+    public function getCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return $this->_currentObject;
+        }
+        $this->_storeData();
+
+        $this->_selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT);
+        $cellResult = $this->_selectQuery->execute();
+        if ($cellResult === false) {
+            throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+        }
+        $cellData = $cellResult->fetchArray(SQLITE3_ASSOC);
+        if ($cellData === false) {
+            //    Return null if requested entry doesn't exist in cache
+            return null;
+        }
+
+        //    Set current entry to the requested entry
+        $this->_currentObjectID = $pCoord;
+
+        $this->_currentObject = unserialize($cellData['value']);
+        //    Re-attach this as the cell's parent
+        $this->_currentObject->attach($this);
+
+        //    Return requested entry
+        return $this->_currentObject;
+    }
+
+    /**
+     *    Is a value set for an indexed cell?
+     *
+     * @param    string        $pCoord        Coordinate address of the cell to check
+     * @return    boolean
+     */
+    public function isDataSet($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return true;
+        }
+
+        //    Check if the requested entry exists in the cache
+        $this->_selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT);
+        $cellResult = $this->_selectQuery->execute();
+        if ($cellResult === false) {
+            throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+        }
+        $cellData = $cellResult->fetchArray(SQLITE3_ASSOC);
+
+        return ($cellData === false) ? false : true;
+    }
+
+    /**
+     *    Delete a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to delete
+     * @throws    PHPExcel_Exception
+     */
+    public function deleteCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            $this->_currentObject->detach();
+            $this->_currentObjectID = $this->_currentObject = null;
+        }
+
+        //    Check if the requested entry exists in the cache
+        $this->_deleteQuery->bindValue('id', $pCoord, SQLITE3_TEXT);
+        $result = $this->_deleteQuery->execute();
+        if ($result === false) {
+            throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+        }
+
+        $this->_currentCellIsDirty = false;
+    }
+
+    /**
+     * Move a cell object from one address to another
+     *
+     * @param    string        $fromAddress    Current address of the cell to move
+     * @param    string        $toAddress        Destination address of the cell to move
+     * @return    boolean
+     */
+    public function moveCell($fromAddress, $toAddress)
+    {
+        if ($fromAddress === $this->_currentObjectID) {
+            $this->_currentObjectID = $toAddress;
+        }
+
+        $this->_deleteQuery->bindValue('id', $toAddress, SQLITE3_TEXT);
+        $result = $this->_deleteQuery->execute();
+        if ($result === false) {
+            throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+        }
+
+        $this->_updateQuery->bindValue('toid', $toAddress, SQLITE3_TEXT);
+        $this->_updateQuery->bindValue('fromid', $fromAddress, SQLITE3_TEXT);
+        $result = $this->_updateQuery->execute();
+        if ($result === false) {
+            throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+        }
+
+        return true;
+    }
+
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return    string[]
+     */
+    public function getCellList()
+    {
+        if ($this->_currentObjectID !== null) {
+            $this->_storeData();
+        }
+
+        $query = "SELECT id FROM kvp_".$this->_TableName;
+        $cellIdsResult = $this->_DBHandle->query($query);
+        if ($cellIdsResult === false) {
+            throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+        }
+
+        $cellKeys = array();
+        while ($row = $cellIdsResult->fetchArray(SQLITE3_ASSOC)) {
+            $cellKeys[] = $row['id'];
+        }
+
+        return $cellKeys;
+    }
+
+    /**
+     * Clone the cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The new worksheet
+     * @return    void
+     */
+    public function copyCellCollection(PHPExcel_Worksheet $parent)
+    {
+        $this->_currentCellIsDirty;
+        $this->_storeData();
+
+        //    Get a new id for the new table name
+        $tableName = str_replace('.', '_', $this->_getUniqueID());
+        if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)
+            AS SELECT * FROM kvp_'.$this->_TableName)
+        ) {
+            throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+        }
+
+        //    Copy the existing cell cache file
+        $this->_TableName = $tableName;
+    }
+
+    /**
+     * Clear the cell collection and disconnect from our parent
+     *
+     * @return    void
+     */
+    public function unsetWorksheetCells()
+    {
+        if (!is_null($this->_currentObject)) {
+            $this->_currentObject->detach();
+            $this->_currentObject = $this->_currentObjectID = null;
+        }
+        //    detach ourself from the worksheet, so that it can then delete this object successfully
+        $this->_parent = null;
+
+        //    Close down the temporary cache file
+        $this->__destruct();
+    }
+
+    /**
+     * Initialise this new cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The worksheet for this cell collection
+     */
+    public function __construct(PHPExcel_Worksheet $parent)
+    {
+        parent::__construct($parent);
+        if (is_null($this->_DBHandle)) {
+            $this->_TableName = str_replace('.', '_', $this->_getUniqueID());
+            $_DBName = ':memory:';
+
+            $this->_DBHandle = new SQLite3($_DBName);
+            if ($this->_DBHandle === false) {
+                throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+            }
+            if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) {
+                throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());
+            }
+        }
+
+        $this->_selectQuery = $this->_DBHandle->prepare("SELECT value FROM kvp_".$this->_TableName." WHERE id = :id");
+        $this->_insertQuery = $this->_DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES(:id,:data)");
+        $this->_updateQuery = $this->_DBHandle->prepare("UPDATE kvp_".$this->_TableName." SET id=:toId WHERE id=:fromId");
+        $this->_deleteQuery = $this->_DBHandle->prepare("DELETE FROM kvp_".$this->_TableName." WHERE id = :id");
+    }
+
+    /**
+     * Destroy this cell collection
+     */
+    public function __destruct()
+    {
+        if (!is_null($this->_DBHandle)) {
+            $this->_DBHandle->exec('DROP TABLE kvp_'.$this->_TableName);
+            $this->_DBHandle->close();
+        }
+        $this->_DBHandle = null;
+    }
+
+    /**
+     * Identify whether the caching method is currently available
+     * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
+     *
+     * @return    boolean
+     */
+    public static function cacheMethodIsAvailable()
+    {
+        if (!class_exists('SQLite3', false)) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorage/Wincache.php b/Classes/PHPExcel/CachedObjectStorage/Wincache.php
index 6eeeef603..5b1fc43dc 100644
--- a/Classes/PHPExcel/CachedObjectStorage/Wincache.php
+++ b/Classes/PHPExcel/CachedObjectStorage/Wincache.php
@@ -1,294 +1,289 @@
-_currentCellIsDirty && !empty($this->_currentObjectID)) {
-			$this->_currentObject->detach();
-
-			$obj = serialize($this->_currentObject);
-			if (wincache_ucache_exists($this->_cachePrefix.$this->_currentObjectID.'.cache')) {
-				if (!wincache_ucache_set($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) {
-					$this->__destruct();
-					throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache');
-				}
-			} else {
-				if (!wincache_ucache_add($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) {
-					$this->__destruct();
-					throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache');
-				}
-			}
-			$this->_currentCellIsDirty = false;
-		}
-
-		$this->_currentObjectID = $this->_currentObject = null;
-	}	//	function _storeData()
-
-
-	/**
-	 * Add or Update a cell in cache identified by coordinate address
-	 *
-	 * @param	string			$pCoord		Coordinate address of the cell to update
-	 * @param	PHPExcel_Cell	$cell		Cell to update
-	 * @return	PHPExcel_Cell
-	 * @throws	PHPExcel_Exception
-	 */
-	public function addCacheData($pCoord, PHPExcel_Cell $cell) {
-		if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
-			$this->_storeData();
-		}
-		$this->_cellCache[$pCoord] = true;
-
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = $cell;
-		$this->_currentCellIsDirty = true;
-
-		return $cell;
-	}	//	function addCacheData()
-
-
-	/**
-	 * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
-	 *
-	 * @param	string		$pCoord		Coordinate address of the cell to check
-	 * @return	boolean
-	 */
-	public function isDataSet($pCoord) {
-		//	Check if the requested entry is the current object, or exists in the cache
-		if (parent::isDataSet($pCoord)) {
-			if ($this->_currentObjectID == $pCoord) {
-				return true;
-			}
-			//	Check if the requested entry still exists in cache
-			$success = wincache_ucache_exists($this->_cachePrefix.$pCoord.'.cache');
-			if ($success === false) {
-				//	Entry no longer exists in Wincache, so clear it from the cache array
-				parent::deleteCacheData($pCoord);
-				throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache');
-			}
-			return true;
-		}
-		return false;
-	}	//	function isDataSet()
-
-
-	/**
-	 * Get cell at a specific coordinate
-	 *
-	 * @param	string			$pCoord		Coordinate of the cell
-	 * @throws	PHPExcel_Exception
-	 * @return	PHPExcel_Cell	Cell that was found, or null if not found
-	 */
-	public function getCacheData($pCoord) {
-		if ($pCoord === $this->_currentObjectID) {
-			return $this->_currentObject;
-		}
-		$this->_storeData();
-
-		//	Check if the entry that has been requested actually exists
-		$obj = null;
-		if (parent::isDataSet($pCoord)) {
-			$success = false;
-			$obj = wincache_ucache_get($this->_cachePrefix.$pCoord.'.cache', $success);
-			if ($success === false) {
-				//	Entry no longer exists in WinCache, so clear it from the cache array
-				parent::deleteCacheData($pCoord);
-				throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache');
-			}
-		} else {
-			//	Return null if requested entry doesn't exist in cache
-			return null;
-		}
-
-		//	Set current entry to the requested entry
-		$this->_currentObjectID = $pCoord;
-		$this->_currentObject = unserialize($obj);
-        //    Re-attach this as the cell's parent
-        $this->_currentObject->attach($this);
-
-		//	Return requested entry
-		return $this->_currentObject;
-	}	//	function getCacheData()
-
-
-	/**
-	 * Get a list of all cell addresses currently held in cache
-	 *
-	 * @return  string[]
-	 */
-	public function getCellList() {
-		if ($this->_currentObjectID !== null) {
-			$this->_storeData();
-		}
-
-		return parent::getCellList();
-	}
-
-
-	/**
-	 * Delete a cell in cache identified by coordinate address
-	 *
-	 * @param	string			$pCoord		Coordinate address of the cell to delete
-	 * @throws	PHPExcel_Exception
-	 */
-	public function deleteCacheData($pCoord) {
-		//	Delete the entry from Wincache
-		wincache_ucache_delete($this->_cachePrefix.$pCoord.'.cache');
-
-		//	Delete the entry from our cell address array
-		parent::deleteCacheData($pCoord);
-	}	//	function deleteCacheData()
-
-
-	/**
-	 * Clone the cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The new worksheet
-	 * @return	void
-	 */
-	public function copyCellCollection(PHPExcel_Worksheet $parent) {
-		parent::copyCellCollection($parent);
-		//	Get a new id for the new file name
-		$baseUnique = $this->_getUniqueID();
-		$newCachePrefix = substr(md5($baseUnique),0,8).'.';
-		$cacheList = $this->getCellList();
-		foreach($cacheList as $cellID) {
-			if ($cellID != $this->_currentObjectID) {
-				$success = false;
-				$obj = wincache_ucache_get($this->_cachePrefix.$cellID.'.cache', $success);
-				if ($success === false) {
-					//	Entry no longer exists in WinCache, so clear it from the cache array
-					parent::deleteCacheData($cellID);
-					throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in Wincache');
-				}
-				if (!wincache_ucache_add($newCachePrefix.$cellID.'.cache', $obj, $this->_cacheTime)) {
-					$this->__destruct();
-					throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in Wincache');
-				}
-			}
-		}
-		$this->_cachePrefix = $newCachePrefix;
-	}	//	function copyCellCollection()
-
-
-	/**
-	 * Clear the cell collection and disconnect from our parent
-	 *
-	 * @return	void
-	 */
-	public function unsetWorksheetCells() {
-		if(!is_null($this->_currentObject)) {
-			$this->_currentObject->detach();
-			$this->_currentObject = $this->_currentObjectID = null;
-		}
-
-		//	Flush the WinCache cache
-		$this->__destruct();
-
-		$this->_cellCache = array();
-
-		//	detach ourself from the worksheet, so that it can then delete this object successfully
-		$this->_parent = null;
-	}	//	function unsetWorksheetCells()
-
-
-	/**
-	 * Initialise this new cell collection
-	 *
-	 * @param	PHPExcel_Worksheet	$parent		The worksheet for this cell collection
-	 * @param	array of mixed		$arguments	Additional initialisation arguments
-	 */
-	public function __construct(PHPExcel_Worksheet $parent, $arguments) {
-		$cacheTime	= (isset($arguments['cacheTime']))	? $arguments['cacheTime']	: 600;
-
-		if (is_null($this->_cachePrefix)) {
-			$baseUnique = $this->_getUniqueID();
-			$this->_cachePrefix = substr(md5($baseUnique),0,8).'.';
-			$this->_cacheTime = $cacheTime;
-
-			parent::__construct($parent);
-		}
-	}	//	function __construct()
-
-
-	/**
-	 * Destroy this cell collection
-	 */
-	public function __destruct() {
-		$cacheList = $this->getCellList();
-		foreach($cacheList as $cellID) {
-			wincache_ucache_delete($this->_cachePrefix.$cellID.'.cache');
-		}
-	}	//	function __destruct()
-
-
-	/**
-	 * Identify whether the caching method is currently available
-	 * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
-	 *
-	 * @return	boolean
-	 */
-	public static function cacheMethodIsAvailable() {
-		if (!function_exists('wincache_ucache_add')) {
-			return false;
-		}
-
-		return true;
-	}
-
-}
+_currentCellIsDirty && !empty($this->_currentObjectID)) {
+            $this->_currentObject->detach();
+
+            $obj = serialize($this->_currentObject);
+            if (wincache_ucache_exists($this->_cachePrefix.$this->_currentObjectID.'.cache')) {
+                if (!wincache_ucache_set($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) {
+                    $this->__destruct();
+                    throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache');
+                }
+            } else {
+                if (!wincache_ucache_add($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) {
+                    $this->__destruct();
+                    throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache');
+                }
+            }
+            $this->_currentCellIsDirty = false;
+        }
+
+        $this->_currentObjectID = $this->_currentObject = null;
+    }
+
+    /**
+     * Add or Update a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to update
+     * @param    PHPExcel_Cell    $cell        Cell to update
+     * @return    PHPExcel_Cell
+     * @throws    PHPExcel_Exception
+     */
+    public function addCacheData($pCoord, PHPExcel_Cell $cell)
+    {
+        if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
+            $this->_storeData();
+        }
+        $this->_cellCache[$pCoord] = true;
+
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = $cell;
+        $this->_currentCellIsDirty = true;
+
+        return $cell;
+    }
+
+    /**
+     * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
+     *
+     * @param    string        $pCoord        Coordinate address of the cell to check
+     * @return    boolean
+     */
+    public function isDataSet($pCoord)
+    {
+        //    Check if the requested entry is the current object, or exists in the cache
+        if (parent::isDataSet($pCoord)) {
+            if ($this->_currentObjectID == $pCoord) {
+                return true;
+            }
+            //    Check if the requested entry still exists in cache
+            $success = wincache_ucache_exists($this->_cachePrefix.$pCoord.'.cache');
+            if ($success === false) {
+                //    Entry no longer exists in Wincache, so clear it from the cache array
+                parent::deleteCacheData($pCoord);
+                throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache');
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Get cell at a specific coordinate
+     *
+     * @param    string            $pCoord        Coordinate of the cell
+     * @throws    PHPExcel_Exception
+     * @return    PHPExcel_Cell    Cell that was found, or null if not found
+     */
+    public function getCacheData($pCoord)
+    {
+        if ($pCoord === $this->_currentObjectID) {
+            return $this->_currentObject;
+        }
+        $this->_storeData();
+
+        //    Check if the entry that has been requested actually exists
+        $obj = null;
+        if (parent::isDataSet($pCoord)) {
+            $success = false;
+            $obj = wincache_ucache_get($this->_cachePrefix.$pCoord.'.cache', $success);
+            if ($success === false) {
+                //    Entry no longer exists in WinCache, so clear it from the cache array
+                parent::deleteCacheData($pCoord);
+                throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache');
+            }
+        } else {
+            //    Return null if requested entry doesn't exist in cache
+            return null;
+        }
+
+        //    Set current entry to the requested entry
+        $this->_currentObjectID = $pCoord;
+        $this->_currentObject = unserialize($obj);
+        //    Re-attach this as the cell's parent
+        $this->_currentObject->attach($this);
+
+        //    Return requested entry
+        return $this->_currentObject;
+    }
+
+
+    /**
+     * Get a list of all cell addresses currently held in cache
+     *
+     * @return  string[]
+     */
+    public function getCellList()
+    {
+        if ($this->_currentObjectID !== null) {
+            $this->_storeData();
+        }
+
+        return parent::getCellList();
+    }
+
+    /**
+     * Delete a cell in cache identified by coordinate address
+     *
+     * @param    string            $pCoord        Coordinate address of the cell to delete
+     * @throws    PHPExcel_Exception
+     */
+    public function deleteCacheData($pCoord)
+    {
+        //    Delete the entry from Wincache
+        wincache_ucache_delete($this->_cachePrefix.$pCoord.'.cache');
+
+        //    Delete the entry from our cell address array
+        parent::deleteCacheData($pCoord);
+    }
+
+    /**
+     * Clone the cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The new worksheet
+     * @return    void
+     */
+    public function copyCellCollection(PHPExcel_Worksheet $parent)
+    {
+        parent::copyCellCollection($parent);
+        //    Get a new id for the new file name
+        $baseUnique = $this->_getUniqueID();
+        $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.';
+        $cacheList = $this->getCellList();
+        foreach ($cacheList as $cellID) {
+            if ($cellID != $this->_currentObjectID) {
+                $success = false;
+                $obj = wincache_ucache_get($this->_cachePrefix.$cellID.'.cache', $success);
+                if ($success === false) {
+                    //    Entry no longer exists in WinCache, so clear it from the cache array
+                    parent::deleteCacheData($cellID);
+                    throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in Wincache');
+                }
+                if (!wincache_ucache_add($newCachePrefix.$cellID.'.cache', $obj, $this->_cacheTime)) {
+                    $this->__destruct();
+                    throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in Wincache');
+                }
+            }
+        }
+        $this->_cachePrefix = $newCachePrefix;
+    }
+
+
+    /**
+     * Clear the cell collection and disconnect from our parent
+     *
+     * @return    void
+     */
+    public function unsetWorksheetCells()
+    {
+        if (!is_null($this->_currentObject)) {
+            $this->_currentObject->detach();
+            $this->_currentObject = $this->_currentObjectID = null;
+        }
+
+        //    Flush the WinCache cache
+        $this->__destruct();
+
+        $this->_cellCache = array();
+
+        //    detach ourself from the worksheet, so that it can then delete this object successfully
+        $this->_parent = null;
+    }
+
+    /**
+     * Initialise this new cell collection
+     *
+     * @param    PHPExcel_Worksheet    $parent        The worksheet for this cell collection
+     * @param    array of mixed        $arguments    Additional initialisation arguments
+     */
+    public function __construct(PHPExcel_Worksheet $parent, $arguments)
+    {
+        $cacheTime    = (isset($arguments['cacheTime']))    ? $arguments['cacheTime']    : 600;
+
+        if (is_null($this->_cachePrefix)) {
+            $baseUnique = $this->_getUniqueID();
+            $this->_cachePrefix = substr(md5($baseUnique), 0, 8).'.';
+            $this->_cacheTime = $cacheTime;
+
+            parent::__construct($parent);
+        }
+    }
+
+    /**
+     * Destroy this cell collection
+     */
+    public function __destruct()
+    {
+        $cacheList = $this->getCellList();
+        foreach ($cacheList as $cellID) {
+            wincache_ucache_delete($this->_cachePrefix.$cellID.'.cache');
+        }
+    }
+
+    /**
+     * Identify whether the caching method is currently available
+     * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
+     *
+     * @return    boolean
+     */
+    public static function cacheMethodIsAvailable()
+    {
+        if (!function_exists('wincache_ucache_add')) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/Classes/PHPExcel/CachedObjectStorageFactory.php b/Classes/PHPExcel/CachedObjectStorageFactory.php
index 81baa2fd9..251c3ef85 100644
--- a/Classes/PHPExcel/CachedObjectStorageFactory.php
+++ b/Classes/PHPExcel/CachedObjectStorageFactory.php
@@ -1,7 +1,7 @@
  array( 'memoryCacheSize' => '1MB'
                                                     ),
-        self::cache_to_discISAM             => array( 'dir'             => NULL
+        self::cache_to_discISAM             => array( 'dir'             => null
                                                     ),
         self::cache_to_apc                  => array( 'cacheTime'       => 600
                                                     ),
@@ -116,7 +104,6 @@ class PHPExcel_CachedObjectStorageFactory
                                                     ),
     );
 
-
     /**
      * Arguments for the active cache storage method
      *
@@ -124,28 +111,25 @@ class PHPExcel_CachedObjectStorageFactory
      */
     private static $_storageMethodParameters = array();
 
-
     /**
      * Return the current cache storage method
      *
-     * @return string|NULL
+     * @return string|null
      **/
     public static function getCacheStorageMethod()
     {
         return self::$_cacheStorageMethod;
-    }   //    function getCacheStorageMethod()
-
+    }
 
     /**
      * Return the current cache storage class
      *
-     * @return PHPExcel_CachedObjectStorage_ICache|NULL
+     * @return PHPExcel_CachedObjectStorage_ICache|null
      **/
     public static function getCacheStorageClass()
     {
         return self::$_cacheStorageClass;
-    }   //    function getCacheStorageClass()
-
+    }
 
     /**
      * Return the list of all possible cache storage methods
@@ -155,8 +139,7 @@ public static function getCacheStorageClass()
     public static function getAllCacheStorageMethods()
     {
         return self::$_storageMethods;
-    }   //    function getCacheStorageMethods()
-
+    }
 
     /**
      * Return the list of all available cache storage methods
@@ -166,15 +149,14 @@ public static function getAllCacheStorageMethods()
     public static function getCacheStorageMethods()
     {
         $activeMethods = array();
-        foreach(self::$_storageMethods as $storageMethod) {
+        foreach (self::$_storageMethods as $storageMethod) {
             $cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $storageMethod;
             if (call_user_func(array($cacheStorageClass, 'cacheMethodIsAvailable'))) {
                 $activeMethods[] = $storageMethod;
             }
         }
         return $activeMethods;
-    }   //    function getCacheStorageMethods()
-
+    }
 
     /**
      * Identify the cache storage method to use
@@ -186,30 +168,29 @@ public static function getCacheStorageMethods()
      **/
     public static function initialize($method = self::cache_in_memory, $arguments = array())
     {
-        if (!in_array($method,self::$_storageMethods)) {
-            return FALSE;
+        if (!in_array($method, self::$_storageMethods)) {
+            return false;
         }
 
         $cacheStorageClass = 'PHPExcel_CachedObjectStorage_'.$method;
         if (!call_user_func(array( $cacheStorageClass,
                                    'cacheMethodIsAvailable'))) {
-            return FALSE;
+            return false;
         }
 
         self::$_storageMethodParameters[$method] = self::$_storageMethodDefaultParameters[$method];
-        foreach($arguments as $k => $v) {
+        foreach ($arguments as $k => $v) {
             if (array_key_exists($k, self::$_storageMethodParameters[$method])) {
                 self::$_storageMethodParameters[$method][$k] = $v;
             }
         }
 
-        if (self::$_cacheStorageMethod === NULL) {
+        if (self::$_cacheStorageMethod === null) {
             self::$_cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $method;
             self::$_cacheStorageMethod = $method;
         }
-        return TRUE;
-    }   //    function initialize()
-
+        return true;
+    }
 
     /**
      * Initialise the cache storage
@@ -219,33 +200,32 @@ public static function initialize($method = self::cache_in_memory, $arguments =
      **/
     public static function getInstance(PHPExcel_Worksheet $parent)
     {
-        $cacheMethodIsAvailable = TRUE;
-        if (self::$_cacheStorageMethod === NULL) {
+        $cacheMethodIsAvailable = true;
+        if (self::$_cacheStorageMethod === null) {
             $cacheMethodIsAvailable = self::initialize();
         }
 
         if ($cacheMethodIsAvailable) {
-            $instance = new self::$_cacheStorageClass( $parent,
-                                                       self::$_storageMethodParameters[self::$_cacheStorageMethod]
-                                                     );
-            if ($instance !== NULL) {
+            $instance = new self::$_cacheStorageClass(
+                $parent,
+                self::$_storageMethodParameters[self::$_cacheStorageMethod]
+            );
+            if ($instance !== null) {
                 return $instance;
             }
         }
 
-        return FALSE;
-    }   //    function getInstance()
-
+        return false;
+    }
 
     /**
      * Clear the cache storage
      *
      **/
-	public static function finalize()
-	{
-		self::$_cacheStorageMethod = NULL;
-		self::$_cacheStorageClass = NULL;
-		self::$_storageMethodParameters = array();
-	}
-
+    public static function finalize()
+    {
+        self::$_cacheStorageMethod = null;
+        self::$_cacheStorageClass = null;
+        self::$_storageMethodParameters = array();
+    }
 }
diff --git a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php
index 7cf3f24da..b3bb2bf13 100644
--- a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php
+++ b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php
@@ -1,6 +1,7 @@
 _stack);
+    }
 
-/**
- * PHPExcel_CalcEngine_CyclicReferenceStack
- *
- * @category	PHPExcel_CalcEngine_CyclicReferenceStack
- * @package		PHPExcel_Calculation
- * @copyright	Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
- */
-class PHPExcel_CalcEngine_CyclicReferenceStack {
-
-	/**
-	 *  The call stack for calculated cells
-	 *
-	 *  @var mixed[]
-	 */
-	private $_stack = array();
-
-
-	/**
-	 * Return the number of entries on the stack
-	 *
-	 * @return  integer
-	 */
-	public function count() {
-		return count($this->_stack);
-	}
-
-	/**
-	 * Push a new entry onto the stack
-	 *
-	 * @param  mixed  $value
-	 */
-	public function push($value) {
-		$this->_stack[$value] = $value;
-	}
-
-	/**
-	 * Pop the last entry from the stack
-	 *
-	 * @return  mixed
-	 */
-	public function pop() {
-		return array_pop($this->_stack);
-	}
+    /**
+     * Push a new entry onto the stack
+     *
+     * @param  mixed  $value
+     */
+    public function push($value)
+    {
+        $this->_stack[$value] = $value;
+    }
 
-	/**
-	 * Test to see if a specified entry exists on the stack
-	 *
-	 * @param  mixed  $value  The value to test
-	 */
-	public function onStack($value) {
-		return isset($this->_stack[$value]);
-	}
+    /**
+     * Pop the last entry from the stack
+     *
+     * @return  mixed
+     */
+    public function pop()
+    {
+        return array_pop($this->_stack);
+    }
 
-	/**
-	 * Clear the stack
-	 */
-	public function clear() {
-		$this->_stack = array();
-	}
+    /**
+     * Test to see if a specified entry exists on the stack
+     *
+     * @param  mixed  $value  The value to test
+     */
+    public function onStack($value)
+    {
+        return isset($this->_stack[$value]);
+    }
 
-	/**
-	 * Return an array of all entries on the stack
-	 *
-	 * @return  mixed[]
-	 */
-	public function showStack() {
-		return $this->_stack;
-	}
+    /**
+     * Clear the stack
+     */
+    public function clear()
+    {
+        $this->_stack = array();
+    }
 
+    /**
+     * Return an array of all entries on the stack
+     *
+     * @return  mixed[]
+     */
+    public function showStack()
+    {
+        return $this->_stack;
+    }
 }
diff --git a/Classes/PHPExcel/CalcEngine/Logger.php b/Classes/PHPExcel/CalcEngine/Logger.php
index 3ff9746e7..9fd1d7d79 100644
--- a/Classes/PHPExcel/CalcEngine/Logger.php
+++ b/Classes/PHPExcel/CalcEngine/Logger.php
@@ -1,6 +1,7 @@
 _cellStack = $stack;
-	}
+    /**
+     * The debug log generated by the calculation engine
+     *
+     * @var string[]
+     */
+    private $_debugLog = array();
 
-	/**
-	 * Enable/Disable Calculation engine logging
-	 *
-	 * @param  boolean $pValue
-	 */
-	public function setWriteDebugLog($pValue = FALSE) {
-		$this->_writeDebugLog = $pValue;
-	}
+    /**
+     * The calculation engine cell reference stack
+     *
+     * @var PHPExcel_CalcEngine_CyclicReferenceStack
+     */
+    private $_cellStack;
 
-	/**
-	 * Return whether calculation engine logging is enabled or disabled
-	 *
-	 * @return  boolean
-	 */
-	public function getWriteDebugLog() {
-		return $this->_writeDebugLog;
-	}
+    /**
+     * Instantiate a Calculation engine logger
+     *
+     * @param  PHPExcel_CalcEngine_CyclicReferenceStack $stack
+     */
+    public function __construct(PHPExcel_CalcEngine_CyclicReferenceStack $stack)
+    {
+        $this->_cellStack = $stack;
+    }
 
-	/**
-	 * Enable/Disable echoing of debug log information
-	 *
-	 * @param  boolean $pValue
-	 */
-	public function setEchoDebugLog($pValue = FALSE) {
-		$this->_echoDebugLog = $pValue;
-	}
+    /**
+     * Enable/Disable Calculation engine logging
+     *
+     * @param  boolean $pValue
+     */
+    public function setWriteDebugLog($pValue = false)
+    {
+        $this->_writeDebugLog = $pValue;
+    }
 
-	/**
-	 * Return whether echoing of debug log information is enabled or disabled
-	 *
-	 * @return  boolean
-	 */
-	public function getEchoDebugLog() {
-		return $this->_echoDebugLog;
-	}
+    /**
+     * Return whether calculation engine logging is enabled or disabled
+     *
+     * @return  boolean
+     */
+    public function getWriteDebugLog()
+    {
+        return $this->_writeDebugLog;
+    }
 
-	/**
-	 * Write an entry to the calculation engine debug log
-	 */
-	public function writeDebugLog() {
-		//	Only write the debug log if logging is enabled
-		if ($this->_writeDebugLog) {
-			$message = implode(func_get_args());
-			$cellReference = implode(' -> ', $this->_cellStack->showStack());
-			if ($this->_echoDebugLog) {
-				echo $cellReference, 
-					($this->_cellStack->count() > 0 ? ' => ' : ''), 
-					$message, 
-					PHP_EOL;
-			}
-			$this->_debugLog[] = $cellReference . 
-				($this->_cellStack->count() > 0 ? ' => ' : '') . 
-				$message;
-		}
-	}	//	function _writeDebug()
+    /**
+     * Enable/Disable echoing of debug log information
+     *
+     * @param  boolean $pValue
+     */
+    public function setEchoDebugLog($pValue = false)
+    {
+        $this->_echoDebugLog = $pValue;
+    }
 
-	/**
-	 * Clear the calculation engine debug log
-	 */
-	public function clearLog() {
-		$this->_debugLog = array();
-	}	//	function flushLogger()
+    /**
+     * Return whether echoing of debug log information is enabled or disabled
+     *
+     * @return  boolean
+     */
+    public function getEchoDebugLog()
+    {
+        return $this->_echoDebugLog;
+    }
 
-	/**
-	 * Return the calculation engine debug log
-	 *
-	 * @return  string[]
-	 */
-	public function getLog() {
-		return $this->_debugLog;
-	}	//	function flushLogger()
+    /**
+     * Write an entry to the calculation engine debug log
+     */
+    public function writeDebugLog()
+    {
+        //    Only write the debug log if logging is enabled
+        if ($this->_writeDebugLog) {
+            $message = implode(func_get_args());
+            $cellReference = implode(' -> ', $this->_cellStack->showStack());
+            if ($this->_echoDebugLog) {
+                echo $cellReference,
+                    ($this->_cellStack->count() > 0 ? ' => ' : ''),
+                    $message,
+                    PHP_EOL;
+            }
+            $this->_debugLog[] = $cellReference .
+                ($this->_cellStack->count() > 0 ? ' => ' : '') .
+                $message;
+        }
+    }
 
-}	//	class PHPExcel_CalcEngine_Logger
+    /**
+     * Clear the calculation engine debug log
+     */
+    public function clearLog()
+    {
+        $this->_debugLog = array();
+    }
 
+    /**
+     * Return the calculation engine debug log
+     *
+     * @return  string[]
+     */
+    public function getLog()
+    {
+        return $this->_debugLog;
+    }
+}
diff --git a/Classes/PHPExcel/Calculation/Token/Stack.php b/Classes/PHPExcel/Calculation/Token/Stack.php
index b91794e44..2b27bb8ee 100644
--- a/Classes/PHPExcel/Calculation/Token/Stack.php
+++ b/Classes/PHPExcel/Calculation/Token/Stack.php
@@ -1,6 +1,6 @@
 _count;
-	}	//	function count()
+    /**
+     *  Count of entries in the parser stack
+     *
+     *  @var integer
+     */
+    private $_count = 0;
 
-	/**
-	 * Push a new entry onto the stack
-	 *
-	 * @param  mixed  $type
-	 * @param  mixed  $value
-	 * @param  mixed  $reference
-	 */
-	public function push($type, $value, $reference = NULL) {
-		$this->_stack[$this->_count++] = array('type'		=> $type,
-											   'value'		=> $value,
-											   'reference'	=> $reference
-											  );
-		if ($type == 'Function') {
-			$localeFunction = PHPExcel_Calculation::_localeFunc($value);
-			if ($localeFunction != $value) {
-				$this->_stack[($this->_count - 1)]['localeValue'] = $localeFunction;
-			}
-		}
-	}	//	function push()
+    /**
+     * Return the number of entries on the stack
+     *
+     * @return  integer
+     */
+    public function count()
+    {
+        return $this->_count;
+    }
 
-	/**
-	 * Pop the last entry from the stack
-	 *
-	 * @return  mixed
-	 */
-	public function pop() {
-		if ($this->_count > 0) {
-			return $this->_stack[--$this->_count];
-		}
-		return NULL;
-	}	//	function pop()
+    /**
+     * Push a new entry onto the stack
+     *
+     * @param  mixed  $type
+     * @param  mixed  $value
+     * @param  mixed  $reference
+     */
+    public function push($type, $value, $reference = null)
+    {
+        $this->_stack[$this->_count++] = array(
+            'type'        => $type,
+            'value'        => $value,
+            'reference'    => $reference
+        );
+        if ($type == 'Function') {
+            $localeFunction = PHPExcel_Calculation::_localeFunc($value);
+            if ($localeFunction != $value) {
+                $this->_stack[($this->_count - 1)]['localeValue'] = $localeFunction;
+            }
+        }
+    }
 
-	/**
-	 * Return an entry from the stack without removing it
-	 *
-	 * @param   integer  $n  number indicating how far back in the stack we want to look
-	 * @return  mixed
-	 */
-	public function last($n = 1) {
-		if ($this->_count - $n < 0) {
-			return NULL;
-		}
-		return $this->_stack[$this->_count - $n];
-	}	//	function last()
+    /**
+     * Pop the last entry from the stack
+     *
+     * @return  mixed
+     */
+    public function pop()
+    {
+        if ($this->_count > 0) {
+            return $this->_stack[--$this->_count];
+        }
+        return null;
+    }
 
-	/**
-	 * Clear the stack
-	 */
-	function clear() {
-		$this->_stack = array();
-		$this->_count = 0;
-	}
+    /**
+     * Return an entry from the stack without removing it
+     *
+     * @param   integer  $n  number indicating how far back in the stack we want to look
+     * @return  mixed
+     */
+    public function last($n = 1)
+    {
+        if ($this->_count - $n < 0) {
+            return null;
+        }
+        return $this->_stack[$this->_count - $n];
+    }
 
-}	//	class PHPExcel_Calculation_Token_Stack
+    /**
+     * Clear the stack
+     */
+    function clear()
+    {
+        $this->_stack = array();
+        $this->_count = 0;
+    }
+}

From b3d2db79ea47f717a6c3936c5605bebe8f2c72e1 Mon Sep 17 00:00:00 2001
From: MarkBaker 
Date: Mon, 4 May 2015 23:36:20 +0100
Subject: [PATCH 338/467] Minor case-sensitivity bugfix to getCell when cell
 reference is a worksheet!cell Work on PSR2 Coding standards

---
 Classes/PHPExcel/Style.php              |  161 ++-
 Classes/PHPExcel/Style/Alignment.php    |  871 ++++++++-------
 Classes/PHPExcel/Style/Border.php       |  492 ++++----
 Classes/PHPExcel/Style/Borders.php      |  577 +++++-----
 Classes/PHPExcel/Style/Color.php        |  764 ++++++-------
 Classes/PHPExcel/Style/Conditional.php  |  272 ++---
 Classes/PHPExcel/Style/Fill.php         |  551 ++++-----
 Classes/PHPExcel/Style/Font.php         | 1025 ++++++++---------
 Classes/PHPExcel/Style/NumberFormat.php | 1367 +++++++++++------------
 Classes/PHPExcel/Style/Protection.php   |  253 +++--
 Classes/PHPExcel/Style/Supervisor.php   |  191 ++--
 Classes/PHPExcel/Worksheet.php          |   12 +-
 Examples/16csv.php                      |    2 -
 13 files changed, 3267 insertions(+), 3271 deletions(-)

diff --git a/Classes/PHPExcel/Style.php b/Classes/PHPExcel/Style.php
index a6672c925..33ad3caa4 100644
--- a/Classes/PHPExcel/Style.php
+++ b/Classes/PHPExcel/Style.php
@@ -1,6 +1,7 @@
 _isSupervisor = $isSupervisor;
+        $this->isSupervisor = $isSupervisor;
 
         // Initialise values
-        $this->_conditionalStyles	= array();
-        $this->_font              = new PHPExcel_Style_Font($isSupervisor, $isConditional);
-        $this->_fill              = new PHPExcel_Style_Fill($isSupervisor, $isConditional);
-        $this->_borders           = new PHPExcel_Style_Borders($isSupervisor, $isConditional);
-        $this->_alignment         = new PHPExcel_Style_Alignment($isSupervisor, $isConditional);
-        $this->_numberFormat      = new PHPExcel_Style_NumberFormat($isSupervisor, $isConditional);
-        $this->_protection        = new PHPExcel_Style_Protection($isSupervisor, $isConditional);
+        $this->conditionalStyles = array();
+        $this->font         = new PHPExcel_Style_Font($isSupervisor, $isConditional);
+        $this->fill         = new PHPExcel_Style_Fill($isSupervisor, $isConditional);
+        $this->borders      = new PHPExcel_Style_Borders($isSupervisor, $isConditional);
+        $this->alignment    = new PHPExcel_Style_Alignment($isSupervisor, $isConditional);
+        $this->numberFormat = new PHPExcel_Style_NumberFormat($isSupervisor, $isConditional);
+        $this->protection   = new PHPExcel_Style_Protection($isSupervisor, $isConditional);
 
         // bind parent if we are a supervisor
         if ($isSupervisor) {
-            $this->_font->bindParent($this);
-            $this->_fill->bindParent($this);
-            $this->_borders->bindParent($this);
-            $this->_alignment->bindParent($this);
-            $this->_numberFormat->bindParent($this);
-            $this->_protection->bindParent($this);
+            $this->font->bindParent($this);
+            $this->fill->bindParent($this);
+            $this->borders->bindParent($this);
+            $this->alignment->bindParent($this);
+            $this->numberFormat->bindParent($this);
+            $this->protection->bindParent($this);
         }
     }
 
@@ -150,7 +142,7 @@ public function getSharedComponent()
             $xfIndex = 0;
         }
 
-        return $this->_parent->getCellXfByIndex($xfIndex);
+        return $this->parent->getCellXfByIndex($xfIndex);
     }
 
     /**
@@ -160,19 +152,19 @@ public function getSharedComponent()
      */
     public function getParent()
     {
-        return $this->_parent;
+        return $this->parent;
     }
 
-	/**
-	 * Build style array from subcomponents
-	 *
-	 * @param array $array
-	 * @return array
-	 */
-	public function getStyleArray($array)
-	{
-		return array('quotePrefix' => $array);
-	}
+    /**
+     * Build style array from subcomponents
+     *
+     * @param array $array
+     * @return array
+     */
+    public function getStyleArray($array)
+    {
+        return array('quotePrefix' => $array);
+    }
 
     /**
      * Apply styles from array
@@ -217,7 +209,7 @@ public function getStyleArray($array)
     public function applyFromArray($pStyles = null, $pAdvanced = true)
     {
         if (is_array($pStyles)) {
-            if ($this->_isSupervisor) {
+            if ($this->isSupervisor) {
 
                 $pRange = $this->getSelectedCells();
 
@@ -234,7 +226,7 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
 
                 // Calculate range outer borders
                 $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);
-                $rangeEnd     = PHPExcel_Cell::coordinateFromString($rangeB);
+                $rangeEnd   = PHPExcel_Cell::coordinateFromString($rangeB);
 
                 // Translate column into index
                 $rangeStart[0]    = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1;
@@ -248,9 +240,7 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
                 }
 
                 // ADVANCED MODE:
-
                 if ($pAdvanced && isset($pStyles['borders'])) {
-
                     // 'allborders' is a shorthand property for 'outline' and 'inside' and
                     //        it applies to components that have not been set explicitly
                     if (isset($pStyles['borders']['allborders'])) {
@@ -261,7 +251,6 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
                         }
                         unset($pStyles['borders']['allborders']); // not needed any more
                     }
-
                     // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left'
                     //        it applies to components that have not been set explicitly
                     if (isset($pStyles['borders']['outline'])) {
@@ -272,7 +261,6 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
                         }
                         unset($pStyles['borders']['outline']); // not needed any more
                     }
-
                     // 'inside' is a shorthand property for 'vertical' and 'horizontal'
                     //        it applies to components that have not been set explicitly
                     if (isset($pStyles['borders']['inside'])) {
@@ -283,7 +271,6 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
                         }
                         unset($pStyles['borders']['inside']); // not needed any more
                     }
-
                     // width and height characteristics of selection, 1, 2, or 3 (for 3 or more)
                     $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3);
                     $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3);
@@ -294,34 +281,28 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
                         $colStart = ($x == 3) ?
                             PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0])
                                 : PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $x - 1);
-
                         // end column index for region
                         $colEnd = ($x == 1) ?
                             PHPExcel_Cell::stringFromColumnIndex($rangeStart[0])
                                 : PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] - $xMax + $x);
 
                         for ($y = 1; $y <= $yMax; ++$y) {
-
                             // which edges are touching the region
                             $edges = array();
-
-                            // are we at left edge
                             if ($x == 1) {
+                                // are we at left edge
                                 $edges[] = 'left';
                             }
-
-                            // are we at right edge
                             if ($x == $xMax) {
+                                // are we at right edge
                                 $edges[] = 'right';
                             }
-
-                            // are we at top edge?
                             if ($y == 1) {
+                                // are we at top edge?
                                 $edges[] = 'top';
                             }
-
-                            // are we at bottom edge?
                             if ($y == $yMax) {
+                                // are we at bottom edge?
                                 $edges[] = 'bottom';
                             }
 
@@ -375,7 +356,6 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
                 }
 
                 // SIMPLE MODE:
-
                 // Selection type, inspect
                 if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) {
                     $selectionType = 'COLUMN';
@@ -393,7 +373,6 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
                             $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
                         }
                         break;
-
                     case 'ROW':
                         $oldXfIndexes = array();
                         for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
@@ -404,7 +383,6 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
                             }
                         }
                         break;
-
                     case 'CELL':
                         $oldXfIndexes = array();
                         for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
@@ -483,7 +461,7 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
                     $this->getProtection()->applyFromArray($pStyles['protection']);
                 }
                 if (array_key_exists('quotePrefix', $pStyles)) {
-                    $this->_quotePrefix = $pStyles['quotePrefix'];
+                    $this->quotePrefix = $pStyles['quotePrefix'];
                 }
             }
         } else {
@@ -499,7 +477,7 @@ public function applyFromArray($pStyles = null, $pAdvanced = true)
      */
     public function getFill()
     {
-        return $this->_fill;
+        return $this->fill;
     }
 
     /**
@@ -509,7 +487,7 @@ public function getFill()
      */
     public function getFont()
     {
-        return $this->_font;
+        return $this->font;
     }
 
     /**
@@ -520,7 +498,7 @@ public function getFont()
      */
     public function setFont(PHPExcel_Style_Font $font)
     {
-        $this->_font = $font;
+        $this->font = $font;
         return $this;
     }
 
@@ -531,7 +509,7 @@ public function setFont(PHPExcel_Style_Font $font)
      */
     public function getBorders()
     {
-        return $this->_borders;
+        return $this->borders;
     }
 
     /**
@@ -541,7 +519,7 @@ public function getBorders()
      */
     public function getAlignment()
     {
-        return $this->_alignment;
+        return $this->alignment;
     }
 
     /**
@@ -551,7 +529,7 @@ public function getAlignment()
      */
     public function getNumberFormat()
     {
-        return $this->_numberFormat;
+        return $this->numberFormat;
     }
 
     /**
@@ -585,7 +563,7 @@ public function setConditionalStyles($pValue = null)
      */
     public function getProtection()
     {
-        return $this->_protection;
+        return $this->protection;
     }
 
     /**
@@ -595,10 +573,10 @@ public function getProtection()
      */
     public function getQuotePrefix()
     {
-        if ($this->_isSupervisor) {
+        if ($this->isSupervisor) {
             return $this->getSharedComponent()->getQuotePrefix();
         }
-        return $this->_quotePrefix;
+        return $this->quotePrefix;
     }
 
     /**
@@ -611,11 +589,11 @@ public function setQuotePrefix($pValue)
         if ($pValue == '') {
             $pValue = false;
         }
-        if ($this->_isSupervisor) {
+        if ($this->isSupervisor) {
             $styleArray = array('quotePrefix' => $pValue);
             $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
         } else {
-            $this->_quotePrefix = (boolean) $pValue;
+            $this->quotePrefix = (boolean) $pValue;
         }
         return $this;
     }
@@ -628,20 +606,20 @@ public function setQuotePrefix($pValue)
     public function getHashCode()
     {
         $hashConditionals = '';
-        foreach ($this->_conditionalStyles as $conditional) {
+        foreach ($this->conditionalStyles as $conditional) {
             $hashConditionals .= $conditional->getHashCode();
         }
 
         return md5(
-              $this->_fill->getHashCode()
-            . $this->_font->getHashCode()
-            . $this->_borders->getHashCode()
-            . $this->_alignment->getHashCode()
-            . $this->_numberFormat->getHashCode()
-            . $hashConditionals
-            . $this->_protection->getHashCode()
-            . ($this->_quotePrefix  ? 't' : 'f')
-            . __CLASS__
+            $this->fill->getHashCode() .
+            $this->font->getHashCode() .
+            $this->borders->getHashCode() .
+            $this->alignment->getHashCode() .
+            $this->numberFormat->getHashCode() .
+            $hashConditionals .
+            $this->protection->getHashCode() .
+            ($this->quotePrefix  ? 't' : 'f') .
+            __CLASS__
         );
     }
 
@@ -652,7 +630,7 @@ public function getHashCode()
      */
     public function getIndex()
     {
-        return $this->_index;
+        return $this->index;
     }
 
     /**
@@ -662,7 +640,6 @@ public function getIndex()
      */
     public function setIndex($pValue)
     {
-        $this->_index = $pValue;
+        $this->index = $pValue;
     }
-
 }
diff --git a/Classes/PHPExcel/Style/Alignment.php b/Classes/PHPExcel/Style/Alignment.php
index 83eaa317e..bfc494771 100644
--- a/Classes/PHPExcel/Style/Alignment.php
+++ b/Classes/PHPExcel/Style/Alignment.php
@@ -1,6 +1,6 @@
 _horizontal		= NULL;
-			$this->_vertical		= NULL;
-			$this->_textRotation	= NULL;
-		}
-	}
-
-	/**
-	 * Get the shared style component for the currently active cell in currently active sheet.
-	 * Only used for style supervisor
-	 *
-	 * @return PHPExcel_Style_Alignment
-	 */
-	public function getSharedComponent()
-	{
-		return $this->_parent->getSharedComponent()->getAlignment();
-	}
-
-	/**
-	 * Build style array from subcomponents
-	 *
-	 * @param array $array
-	 * @return array
-	 */
-	public function getStyleArray($array)
-	{
-		return array('alignment' => $array);
-	}
-
-	/**
-	 * Apply styles from array
-	 *
-	 * 
-	 * $objPHPExcel->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray(
-	 *		array(
-	 *			'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
-	 *			'vertical'   => PHPExcel_Style_Alignment::VERTICAL_CENTER,
-	 *			'rotation'   => 0,
-	 *			'wrap'			=> TRUE
-	 *		)
-	 * );
-	 * 
-	 *
-	 * @param	array	$pStyles	Array containing style information
-	 * @throws	PHPExcel_Exception
-	 * @return PHPExcel_Style_Alignment
-	 */
-	public function applyFromArray($pStyles = NULL) {
-		if (is_array($pStyles)) {
-			if ($this->_isSupervisor) {
-				$this->getActiveSheet()->getStyle($this->getSelectedCells())
-				    ->applyFromArray($this->getStyleArray($pStyles));
-			} else {
-				if (isset($pStyles['horizontal'])) {
-					$this->setHorizontal($pStyles['horizontal']);
-				}
-				if (isset($pStyles['vertical'])) {
-					$this->setVertical($pStyles['vertical']);
-				}
-				if (isset($pStyles['rotation'])) {
-					$this->setTextRotation($pStyles['rotation']);
-				}
-				if (isset($pStyles['wrap'])) {
-					$this->setWrapText($pStyles['wrap']);
-				}
-				if (isset($pStyles['shrinkToFit'])) {
-					$this->setShrinkToFit($pStyles['shrinkToFit']);
-				}
-				if (isset($pStyles['indent'])) {
-					$this->setIndent($pStyles['indent']);
-				}
-				if (isset($pStyles['readorder'])) {
-					$this->setReadorder($pStyles['readorder']);
-				}
-			}
-		} else {
-			throw new PHPExcel_Exception("Invalid style array passed.");
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Horizontal
-	 *
-	 * @return string
-	 */
-	public function getHorizontal() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getHorizontal();
-		}
-		return $this->_horizontal;
-	}
-
-	/**
-	 * Set Horizontal
-	 *
-	 * @param string $pValue
-	 * @return PHPExcel_Style_Alignment
-	 */
-	public function setHorizontal($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) {
-		if ($pValue == '') {
-			$pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL;
-		}
-
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('horizontal' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		}
-		else {
-			$this->_horizontal = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Vertical
-	 *
-	 * @return string
-	 */
-	public function getVertical() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getVertical();
-		}
-		return $this->_vertical;
-	}
-
-	/**
-	 * Set Vertical
-	 *
-	 * @param string $pValue
-	 * @return PHPExcel_Style_Alignment
-	 */
-	public function setVertical($pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM) {
-		if ($pValue == '') {
-			$pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM;
-		}
-
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('vertical' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_vertical = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get TextRotation
-	 *
-	 * @return int
-	 */
-	public function getTextRotation() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getTextRotation();
-		}
-		return $this->_textRotation;
-	}
-
-	/**
-	 * Set TextRotation
-	 *
-	 * @param int $pValue
-	 * @throws PHPExcel_Exception
-	 * @return PHPExcel_Style_Alignment
-	 */
-	public function setTextRotation($pValue = 0) {
-		// Excel2007 value 255 => PHPExcel value -165
-		if ($pValue == 255) {
-			$pValue = -165;
-		}
-
-		// Set rotation
-		if ( ($pValue >= -90 && $pValue <= 90) || $pValue == -165 ) {
-			if ($this->_isSupervisor) {
-				$styleArray = $this->getStyleArray(array('rotation' => $pValue));
-				$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-			} else {
-				$this->_textRotation = $pValue;
-			}
-		} else {
-			throw new PHPExcel_Exception("Text rotation should be a value between -90 and 90.");
-		}
-
-		return $this;
-	}
-
-	/**
-	 * Get Wrap Text
-	 *
-	 * @return boolean
-	 */
-	public function getWrapText() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getWrapText();
-		}
-		return $this->_wrapText;
-	}
-
-	/**
-	 * Set Wrap Text
-	 *
-	 * @param boolean $pValue
-	 * @return PHPExcel_Style_Alignment
-	 */
-	public function setWrapText($pValue = FALSE) {
-		if ($pValue == '') {
-			$pValue = FALSE;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('wrap' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_wrapText = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Shrink to fit
-	 *
-	 * @return boolean
-	 */
-	public function getShrinkToFit() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getShrinkToFit();
-		}
-		return $this->_shrinkToFit;
-	}
-
-	/**
-	 * Set Shrink to fit
-	 *
-	 * @param boolean $pValue
-	 * @return PHPExcel_Style_Alignment
-	 */
-	public function setShrinkToFit($pValue = FALSE) {
-		if ($pValue == '') {
-			$pValue = FALSE;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('shrinkToFit' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_shrinkToFit = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get indent
-	 *
-	 * @return int
-	 */
-	public function getIndent() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getIndent();
-		}
-		return $this->_indent;
-	}
-
-	/**
-	 * Set indent
-	 *
-	 * @param int $pValue
-	 * @return PHPExcel_Style_Alignment
-	 */
-	public function setIndent($pValue = 0) {
-		if ($pValue > 0) {
-			if ($this->getHorizontal() != self::HORIZONTAL_GENERAL &&
-				$this->getHorizontal() != self::HORIZONTAL_LEFT &&
-				$this->getHorizontal() != self::HORIZONTAL_RIGHT) {
-				$pValue = 0; // indent not supported
-			}
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('indent' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_indent = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get read order
-	 *
-	 * @return integer
-	 */
-	public function getReadorder() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getReadorder();
-		}
-		return $this->_readorder;
-	}
-
-	/**
-	 * Set read order
-	 *
-	 * @param int $pValue
-	 * @return PHPExcel_Style_Alignment
-	 */
-	public function setReadorder($pValue = 0) {
-		if ($pValue < 0 || $pValue > 2) {
+    /* Horizontal alignment styles */
+    const HORIZONTAL_GENERAL           = 'general';
+    const HORIZONTAL_LEFT              = 'left';
+    const HORIZONTAL_RIGHT             = 'right';
+    const HORIZONTAL_CENTER            = 'center';
+    const HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous';
+    const HORIZONTAL_JUSTIFY           = 'justify';
+    const HORIZONTAL_FILL              = 'fill';
+    const HORIZONTAL_DISTRIBUTED       = 'distributed';        // Excel2007 only
+
+    /* Vertical alignment styles */
+    const VERTICAL_BOTTOM      = 'bottom';
+    const VERTICAL_TOP         = 'top';
+    const VERTICAL_CENTER      = 'center';
+    const VERTICAL_JUSTIFY     = 'justify';
+    const VERTICAL_DISTRIBUTED = 'distributed';        // Excel2007 only
+
+    /* Read order */
+    const READORDER_CONTEXT = 0;
+    const READORDER_LTR     = 1;
+    const READORDER_RTL     = 2;
+
+    /**
+     * Horizontal alignment
+     *
+     * @var string
+     */
+    protected $horizontal = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL;
+
+    /**
+     * Vertical alignment
+     *
+     * @var string
+     */
+    protected $vertical = PHPExcel_Style_Alignment::VERTICAL_BOTTOM;
+
+    /**
+     * Text rotation
+     *
+     * @var integer
+     */
+    protected $textRotation = 0;
+
+    /**
+     * Wrap text
+     *
+     * @var boolean
+     */
+    protected $wrapText = false;
+
+    /**
+     * Shrink to fit
+     *
+     * @var boolean
+     */
+    protected $shrinkToFit = false;
+
+    /**
+     * Indent - only possible with horizontal alignment left and right
+     *
+     * @var integer
+     */
+    protected $indent = 0;
+
+    /**
+     * Read order
+     *
+     * @var integer
+     */
+    protected $readorder = 0;
+
+    /**
+     * Create a new PHPExcel_Style_Alignment
+     *
+     * @param    boolean    $isSupervisor    Flag indicating if this is a supervisor or not
+     *                                       Leave this value at default unless you understand exactly what
+     *                                          its ramifications are
+     * @param    boolean    $isConditional   Flag indicating if this is a conditional style or not
+     *                                       Leave this value at default unless you understand exactly what
+     *                                          its ramifications are
+     */
+    public function __construct($isSupervisor = false, $isConditional = false)
+    {
+        // Supervisor?
+        parent::__construct($isSupervisor);
+
+        if ($isConditional) {
+            $this->horizontal   = null;
+            $this->vertical     = null;
+            $this->textRotation = null;
+        }
+    }
+
+    /**
+     * Get the shared style component for the currently active cell in currently active sheet.
+     * Only used for style supervisor
+     *
+     * @return PHPExcel_Style_Alignment
+     */
+    public function getSharedComponent()
+    {
+        return $this->parent->getSharedComponent()->getAlignment();
+    }
+
+    /**
+     * Build style array from subcomponents
+     *
+     * @param array $array
+     * @return array
+     */
+    public function getStyleArray($array)
+    {
+        return array('alignment' => $array);
+    }
+
+    /**
+     * Apply styles from array
+     *
+     * 
+     * $objPHPExcel->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray(
+     *        array(
+     *            'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
+     *            'vertical'   => PHPExcel_Style_Alignment::VERTICAL_CENTER,
+     *            'rotation'   => 0,
+     *            'wrap'            => TRUE
+     *        )
+     * );
+     * 
+     *
+     * @param    array    $pStyles    Array containing style information
+     * @throws    PHPExcel_Exception
+     * @return PHPExcel_Style_Alignment
+     */
+    public function applyFromArray($pStyles = null)
+    {
+        if (is_array($pStyles)) {
+            if ($this->isSupervisor) {
+                $this->getActiveSheet()->getStyle($this->getSelectedCells())
+                    ->applyFromArray($this->getStyleArray($pStyles));
+            } else {
+                if (isset($pStyles['horizontal'])) {
+                    $this->setHorizontal($pStyles['horizontal']);
+                }
+                if (isset($pStyles['vertical'])) {
+                    $this->setVertical($pStyles['vertical']);
+                }
+                if (isset($pStyles['rotation'])) {
+                    $this->setTextRotation($pStyles['rotation']);
+                }
+                if (isset($pStyles['wrap'])) {
+                    $this->setWrapText($pStyles['wrap']);
+                }
+                if (isset($pStyles['shrinkToFit'])) {
+                    $this->setShrinkToFit($pStyles['shrinkToFit']);
+                }
+                if (isset($pStyles['indent'])) {
+                    $this->setIndent($pStyles['indent']);
+                }
+                if (isset($pStyles['readorder'])) {
+                    $this->setReadorder($pStyles['readorder']);
+                }
+            }
+        } else {
+            throw new PHPExcel_Exception("Invalid style array passed.");
+        }
+        return $this;
+    }
+
+    /**
+     * Get Horizontal
+     *
+     * @return string
+     */
+    public function getHorizontal()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getHorizontal();
+        }
+        return $this->horizontal;
+    }
+
+    /**
+     * Set Horizontal
+     *
+     * @param string $pValue
+     * @return PHPExcel_Style_Alignment
+     */
+    public function setHorizontal($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL)
+    {
+        if ($pValue == '') {
+            $pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL;
+        }
+
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('horizontal' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->horizontal = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get Vertical
+     *
+     * @return string
+     */
+    public function getVertical()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getVertical();
+        }
+        return $this->vertical;
+    }
+
+    /**
+     * Set Vertical
+     *
+     * @param string $pValue
+     * @return PHPExcel_Style_Alignment
+     */
+    public function setVertical($pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM)
+    {
+        if ($pValue == '') {
+            $pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM;
+        }
+
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('vertical' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->vertical = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get TextRotation
+     *
+     * @return int
+     */
+    public function getTextRotation()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getTextRotation();
+        }
+        return $this->textRotation;
+    }
+
+    /**
+     * Set TextRotation
+     *
+     * @param int $pValue
+     * @throws PHPExcel_Exception
+     * @return PHPExcel_Style_Alignment
+     */
+    public function setTextRotation($pValue = 0)
+    {
+        // Excel2007 value 255 => PHPExcel value -165
+        if ($pValue == 255) {
+            $pValue = -165;
+        }
+
+        // Set rotation
+        if (($pValue >= -90 && $pValue <= 90) || $pValue == -165) {
+            if ($this->isSupervisor) {
+                $styleArray = $this->getStyleArray(array('rotation' => $pValue));
+                $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+            } else {
+                $this->textRotation = $pValue;
+            }
+        } else {
+            throw new PHPExcel_Exception("Text rotation should be a value between -90 and 90.");
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get Wrap Text
+     *
+     * @return boolean
+     */
+    public function getWrapText()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getWrapText();
+        }
+        return $this->wrapText;
+    }
+
+    /**
+     * Set Wrap Text
+     *
+     * @param boolean $pValue
+     * @return PHPExcel_Style_Alignment
+     */
+    public function setWrapText($pValue = false)
+    {
+        if ($pValue == '') {
+            $pValue = false;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('wrap' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->wrapText = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get Shrink to fit
+     *
+     * @return boolean
+     */
+    public function getShrinkToFit()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getShrinkToFit();
+        }
+        return $this->shrinkToFit;
+    }
+
+    /**
+     * Set Shrink to fit
+     *
+     * @param boolean $pValue
+     * @return PHPExcel_Style_Alignment
+     */
+    public function setShrinkToFit($pValue = false)
+    {
+        if ($pValue == '') {
+            $pValue = false;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('shrinkToFit' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->shrinkToFit = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get indent
+     *
+     * @return int
+     */
+    public function getIndent()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getIndent();
+        }
+        return $this->indent;
+    }
+
+    /**
+     * Set indent
+     *
+     * @param int $pValue
+     * @return PHPExcel_Style_Alignment
+     */
+    public function setIndent($pValue = 0)
+    {
+        if ($pValue > 0) {
+            if ($this->getHorizontal() != self::HORIZONTAL_GENERAL &&
+                $this->getHorizontal() != self::HORIZONTAL_LEFT &&
+                $this->getHorizontal() != self::HORIZONTAL_RIGHT) {
+                $pValue = 0; // indent not supported
+            }
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('indent' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->indent = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get read order
+     *
+     * @return integer
+     */
+    public function getReadorder()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getReadorder();
+        }
+        return $this->readorder;
+    }
+
+    /**
+     * Set read order
+     *
+     * @param int $pValue
+     * @return PHPExcel_Style_Alignment
+     */
+    public function setReadorder($pValue = 0)
+    {
+        if ($pValue < 0 || $pValue > 2) {
             $pValue = 0;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('readorder' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_readorder = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get hash code
-	 *
-	 * @return string	Hash code
-	 */
-	public function getHashCode() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getHashCode();
-		}
-		return md5(
-			  $this->_horizontal
-			. $this->_vertical
-			. $this->_textRotation
-			. ($this->_wrapText ? 't' : 'f')
-			. ($this->_shrinkToFit ? 't' : 'f')
-			. $this->_indent
-			. $this->_readorder
-			. __CLASS__
-		);
-	}
-
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('readorder' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->readorder = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get hash code
+     *
+     * @return string    Hash code
+     */
+    public function getHashCode()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getHashCode();
+        }
+        return md5(
+            $this->horizontal .
+            $this->vertical .
+            $this->textRotation .
+            ($this->wrapText ? 't' : 'f') .
+            ($this->shrinkToFit ? 't' : 'f') .
+            $this->indent .
+            $this->readorder .
+            __CLASS__
+        );
+    }
 }
diff --git a/Classes/PHPExcel/Style/Border.php b/Classes/PHPExcel/Style/Border.php
index f795f5642..55efc501e 100644
--- a/Classes/PHPExcel/Style/Border.php
+++ b/Classes/PHPExcel/Style/Border.php
@@ -1,6 +1,7 @@
 _color	= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor);
+    /**
+     * Parent property name
+     *
+     * @var string
+     */
+    protected $parentPropertyName;
 
-		// bind parent if we are a supervisor
-		if ($isSupervisor) {
-			$this->_color->bindParent($this, '_color');
-		}
-	}
+    /**
+     * Create a new PHPExcel_Style_Border
+     *
+     * @param    boolean    $isSupervisor    Flag indicating if this is a supervisor or not
+     *                                    Leave this value at default unless you understand exactly what
+     *                                        its ramifications are
+     * @param    boolean    $isConditional    Flag indicating if this is a conditional style or not
+     *                                    Leave this value at default unless you understand exactly what
+     *                                        its ramifications are
+     */
+    public function __construct($isSupervisor = false, $isConditional = false)
+    {
+        // Supervisor?
+        parent::__construct($isSupervisor);
 
-	/**
-	 * Bind parent. Only used for supervisor
-	 *
-	 * @param PHPExcel_Style_Borders $parent
-	 * @param string $parentPropertyName
-	 * @return PHPExcel_Style_Border
-	 */
-	public function bindParent($parent, $parentPropertyName=NULL)
-	{
-		$this->_parent = $parent;
-		$this->_parentPropertyName = $parentPropertyName;
-		return $this;
-	}
+        // Initialise values
+        $this->color    = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor);
 
-	/**
-	 * Get the shared style component for the currently active cell in currently active sheet.
-	 * Only used for style supervisor
-	 *
-	 * @return PHPExcel_Style_Border
-	 * @throws PHPExcel_Exception
-	 */
-	public function getSharedComponent()
-	{
-		switch ($this->_parentPropertyName) {
-			case '_allBorders':
-			case '_horizontal':
-			case '_inside':
-			case '_outline':
-			case '_vertical':
-				throw new PHPExcel_Exception('Cannot get shared component for a pseudo-border.');
-				break;
-			case '_bottom':
-				return $this->_parent->getSharedComponent()->getBottom();		break;
-			case '_diagonal':
-				return $this->_parent->getSharedComponent()->getDiagonal();		break;
-			case '_left':
-				return $this->_parent->getSharedComponent()->getLeft();			break;
-			case '_right':
-				return $this->_parent->getSharedComponent()->getRight();		break;
-			case '_top':
-				return $this->_parent->getSharedComponent()->getTop();			break;
+        // bind parent if we are a supervisor
+        if ($isSupervisor) {
+            $this->color->bindParent($this, 'color');
+        }
+    }
 
-		}
-	}
+    /**
+     * Bind parent. Only used for supervisor
+     *
+     * @param PHPExcel_Style_Borders $parent
+     * @param string $parentPropertyName
+     * @return PHPExcel_Style_Border
+     */
+    public function bindParent($parent, $parentPropertyName = null)
+    {
+        $this->parent = $parent;
+        $this->parentPropertyName = $parentPropertyName;
+        return $this;
+    }
 
-	/**
-	 * Build style array from subcomponents
-	 *
-	 * @param array $array
-	 * @return array
-	 */
-	public function getStyleArray($array)
-	{
-		switch ($this->_parentPropertyName) {
-		case '_allBorders':
-				$key = 'allborders';	break;
-		case '_bottom':
-				$key = 'bottom';		break;
-		case '_diagonal':
-				$key = 'diagonal';		break;
-		case '_horizontal':
-				$key = 'horizontal';	break;
-		case '_inside':
-				$key = 'inside';		break;
-		case '_left':
-				$key = 'left';			break;
-		case '_outline':
-				$key = 'outline';		break;
-		case '_right':
-				$key = 'right';			break;
-		case '_top':
-				$key = 'top';			break;
-		case '_vertical':
-				$key = 'vertical';		break;
-		}
-		return $this->_parent->getStyleArray(array($key => $array));
-	}
+    /**
+     * Get the shared style component for the currently active cell in currently active sheet.
+     * Only used for style supervisor
+     *
+     * @return PHPExcel_Style_Border
+     * @throws PHPExcel_Exception
+     */
+    public function getSharedComponent()
+    {
+        switch ($this->parentPropertyName) {
+            case 'allBorders':
+            case 'horizontal':
+            case 'inside':
+            case 'outline':
+            case 'vertical':
+                throw new PHPExcel_Exception('Cannot get shared component for a pseudo-border.');
+                break;
+            case 'bottom':
+                return $this->parent->getSharedComponent()->getBottom();
+            case 'diagonal':
+                return $this->parent->getSharedComponent()->getDiagonal();
+            case 'left':
+                return $this->parent->getSharedComponent()->getLeft();
+            case 'right':
+                return $this->parent->getSharedComponent()->getRight();
+            case 'top':
+                return $this->parent->getSharedComponent()->getTop();
+        }
+    }
 
-	/**
-	 * Apply styles from array
-	 *
-	 * 
-	 * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->applyFromArray(
-	 *		array(
-	 *			'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
-	 *			'color' => array(
-	 *				'rgb' => '808080'
-	 *			)
-	 *		)
-	 * );
-	 * 
-	 *
-	 * @param	array	$pStyles	Array containing style information
-	 * @throws	PHPExcel_Exception
-	 * @return PHPExcel_Style_Border
-	 */
-	public function applyFromArray($pStyles = null) {
-		if (is_array($pStyles)) {
-			if ($this->_isSupervisor) {
-				$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
-			} else {
-				if (isset($pStyles['style'])) {
-					$this->setBorderStyle($pStyles['style']);
-				}
-				if (isset($pStyles['color'])) {
-					$this->getColor()->applyFromArray($pStyles['color']);
-				}
-			}
-		} else {
-			throw new PHPExcel_Exception("Invalid style array passed.");
-		}
-		return $this;
-	}
+    /**
+     * Build style array from subcomponents
+     *
+     * @param array $array
+     * @return array
+     */
+    public function getStyleArray($array)
+    {
+        switch ($this->parentPropertyName) {
+            case 'allBorders':
+            case 'bottom':
+            case 'diagonal':
+            case 'horizontal':
+            case 'inside':
+            case 'left':
+            case 'outline':
+            case 'right':
+            case 'top':
+            case 'vertical':
+                $key = strtolower('vertical');
+                break;
+        }
+        return $this->parent->getStyleArray(array($key => $array));
+    }
 
-	/**
-	 * Get Border style
-	 *
-	 * @return string
-	 */
-	public function getBorderStyle() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getBorderStyle();
-		}
-		return $this->_borderStyle;
-	}
+    /**
+     * Apply styles from array
+     *
+     * 
+     * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->applyFromArray(
+     *        array(
+     *            'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
+     *            'color' => array(
+     *                'rgb' => '808080'
+     *            )
+     *        )
+     * );
+     * 
+     *
+     * @param    array    $pStyles    Array containing style information
+     * @throws    PHPExcel_Exception
+     * @return PHPExcel_Style_Border
+     */
+    public function applyFromArray($pStyles = null)
+    {
+        if (is_array($pStyles)) {
+            if ($this->isSupervisor) {
+                $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+            } else {
+                if (isset($pStyles['style'])) {
+                    $this->setBorderStyle($pStyles['style']);
+                }
+                if (isset($pStyles['color'])) {
+                    $this->getColor()->applyFromArray($pStyles['color']);
+                }
+            }
+        } else {
+            throw new PHPExcel_Exception("Invalid style array passed.");
+        }
+        return $this;
+    }
 
-	/**
-	 * Set Border style
-	 *
-	 * @param string|boolean	$pValue
-	 *							When passing a boolean, FALSE equates PHPExcel_Style_Border::BORDER_NONE
-	 *								and TRUE to PHPExcel_Style_Border::BORDER_MEDIUM
-	 * @return PHPExcel_Style_Border
-	 */
-	public function setBorderStyle($pValue = PHPExcel_Style_Border::BORDER_NONE) {
+    /**
+     * Get Border style
+     *
+     * @return string
+     */
+    public function getBorderStyle()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getBorderStyle();
+        }
+        return $this->borderStyle;
+    }
 
-		if (empty($pValue)) {
-			$pValue = PHPExcel_Style_Border::BORDER_NONE;
-		} elseif(is_bool($pValue) && $pValue) {
-			$pValue = PHPExcel_Style_Border::BORDER_MEDIUM;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('style' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_borderStyle = $pValue;
-		}
-		return $this;
-	}
+    /**
+     * Set Border style
+     *
+     * @param string|boolean    $pValue
+     *                            When passing a boolean, FALSE equates PHPExcel_Style_Border::BORDER_NONE
+     *                                and TRUE to PHPExcel_Style_Border::BORDER_MEDIUM
+     * @return PHPExcel_Style_Border
+     */
+    public function setBorderStyle($pValue = PHPExcel_Style_Border::BORDER_NONE)
+    {
 
-	/**
-	 * Get Border Color
-	 *
-	 * @return PHPExcel_Style_Color
-	 */
-	public function getColor() {
-		return $this->_color;
-	}
+        if (empty($pValue)) {
+            $pValue = PHPExcel_Style_Border::BORDER_NONE;
+        } elseif (is_bool($pValue) && $pValue) {
+            $pValue = PHPExcel_Style_Border::BORDER_MEDIUM;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('style' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->borderStyle = $pValue;
+        }
+        return $this;
+    }
 
-	/**
-	 * Set Border Color
-	 *
-	 * @param	PHPExcel_Style_Color $pValue
-	 * @throws	PHPExcel_Exception
-	 * @return PHPExcel_Style_Border
-	 */
-	public function setColor(PHPExcel_Style_Color $pValue = null) {
-		// make sure parameter is a real color and not a supervisor
-		$color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
+    /**
+     * Get Border Color
+     *
+     * @return PHPExcel_Style_Color
+     */
+    public function getColor()
+    {
+        return $this->color;
+    }
 
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB()));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_color = $color;
-		}
-		return $this;
-	}
+    /**
+     * Set Border Color
+     *
+     * @param    PHPExcel_Style_Color $pValue
+     * @throws    PHPExcel_Exception
+     * @return PHPExcel_Style_Border
+     */
+    public function setColor(PHPExcel_Style_Color $pValue = null)
+    {
+        // make sure parameter is a real color and not a supervisor
+        $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
 
-	/**
-	 * Get hash code
-	 *
-	 * @return string	Hash code
-	 */
-	public function getHashCode() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getHashCode();
-		}
-		return md5(
-			  $this->_borderStyle
-			. $this->_color->getHashCode()
-			. __CLASS__
-		);
-	}
+        if ($this->isSupervisor) {
+            $styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB()));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->color = $color;
+        }
+        return $this;
+    }
 
+    /**
+     * Get hash code
+     *
+     * @return string    Hash code
+     */
+    public function getHashCode()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getHashCode();
+        }
+        return md5(
+            $this->borderStyle .
+            $this->color->getHashCode() .
+            __CLASS__
+        );
+    }
 }
diff --git a/Classes/PHPExcel/Style/Borders.php b/Classes/PHPExcel/Style/Borders.php
index f5216f616..27c40a48e 100644
--- a/Classes/PHPExcel/Style/Borders.php
+++ b/Classes/PHPExcel/Style/Borders.php
@@ -1,6 +1,7 @@
 _left				= new PHPExcel_Style_Border($isSupervisor, $isConditional);
-    	$this->_right				= new PHPExcel_Style_Border($isSupervisor, $isConditional);
-    	$this->_top					= new PHPExcel_Style_Border($isSupervisor, $isConditional);
-    	$this->_bottom				= new PHPExcel_Style_Border($isSupervisor, $isConditional);
-    	$this->_diagonal			= new PHPExcel_Style_Border($isSupervisor, $isConditional);
-		$this->_diagonalDirection	= PHPExcel_Style_Borders::DIAGONAL_NONE;
-
-		// Specially for supervisor
-		if ($isSupervisor) {
-			// Initialize pseudo-borders
-			$this->_allBorders			= new PHPExcel_Style_Border(TRUE);
-			$this->_outline				= new PHPExcel_Style_Border(TRUE);
-			$this->_inside				= new PHPExcel_Style_Border(TRUE);
-			$this->_vertical			= new PHPExcel_Style_Border(TRUE);
-			$this->_horizontal			= new PHPExcel_Style_Border(TRUE);
-
-			// bind parent if we are a supervisor
-			$this->_left->bindParent($this, '_left');
-			$this->_right->bindParent($this, '_right');
-			$this->_top->bindParent($this, '_top');
-			$this->_bottom->bindParent($this, '_bottom');
-			$this->_diagonal->bindParent($this, '_diagonal');
-			$this->_allBorders->bindParent($this, '_allBorders');
-			$this->_outline->bindParent($this, '_outline');
-			$this->_inside->bindParent($this, '_inside');
-			$this->_vertical->bindParent($this, '_vertical');
-			$this->_horizontal->bindParent($this, '_horizontal');
-		}
+        // Supervisor?
+        parent::__construct($isSupervisor);
+
+        // Initialise values
+        $this->left = new PHPExcel_Style_Border($isSupervisor, $isConditional);
+        $this->right = new PHPExcel_Style_Border($isSupervisor, $isConditional);
+        $this->top = new PHPExcel_Style_Border($isSupervisor, $isConditional);
+        $this->bottom = new PHPExcel_Style_Border($isSupervisor, $isConditional);
+        $this->diagonal = new PHPExcel_Style_Border($isSupervisor, $isConditional);
+        $this->diagonalDirection = PHPExcel_Style_Borders::DIAGONAL_NONE;
+
+        // Specially for supervisor
+        if ($isSupervisor) {
+            // Initialize pseudo-borders
+            $this->allBorders = new PHPExcel_Style_Border(true);
+            $this->outline = new PHPExcel_Style_Border(true);
+            $this->inside = new PHPExcel_Style_Border(true);
+            $this->vertical = new PHPExcel_Style_Border(true);
+            $this->horizontal = new PHPExcel_Style_Border(true);
+
+            // bind parent if we are a supervisor
+            $this->left->bindParent($this, 'left');
+            $this->right->bindParent($this, 'right');
+            $this->top->bindParent($this, 'top');
+            $this->bottom->bindParent($this, 'bottom');
+            $this->diagonal->bindParent($this, 'diagonal');
+            $this->allBorders->bindParent($this, 'allBorders');
+            $this->outline->bindParent($this, 'outline');
+            $this->inside->bindParent($this, 'inside');
+            $this->vertical->bindParent($this, 'vertical');
+            $this->horizontal->bindParent($this, 'horizontal');
+        }
     }
 
-	/**
-	 * Get the shared style component for the currently active cell in currently active sheet.
-	 * Only used for style supervisor
-	 *
-	 * @return PHPExcel_Style_Borders
-	 */
-	public function getSharedComponent()
-	{
-		return $this->_parent->getSharedComponent()->getBorders();
-	}
-
-	/**
-	 * Build style array from subcomponents
-	 *
-	 * @param array $array
-	 * @return array
-	 */
-	public function getStyleArray($array)
-	{
-		return array('borders' => $array);
-	}
-
-	/**
+    /**
+     * Get the shared style component for the currently active cell in currently active sheet.
+     * Only used for style supervisor
+     *
+     * @return PHPExcel_Style_Borders
+     */
+    public function getSharedComponent()
+    {
+        return $this->parent->getSharedComponent()->getBorders();
+    }
+
+    /**
+     * Build style array from subcomponents
+     *
+     * @param array $array
+     * @return array
+     */
+    public function getStyleArray($array)
+    {
+        return array('borders' => $array);
+    }
+
+    /**
      * Apply styles from array
      *
      * 
      * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray(
-     * 		array(
-     * 			'bottom'     => array(
-     * 				'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
-     * 				'color' => array(
-     * 					'rgb' => '808080'
-     * 				)
-     * 			),
-     * 			'top'     => array(
-     * 				'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
-     * 				'color' => array(
-     * 					'rgb' => '808080'
-     * 				)
-     * 			)
-     * 		)
+     *         array(
+     *             'bottom'     => array(
+     *                 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
+     *                 'color' => array(
+     *                     'rgb' => '808080'
+     *                 )
+     *             ),
+     *             'top'     => array(
+     *                 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
+     *                 'color' => array(
+     *                     'rgb' => '808080'
+     *                 )
+     *             )
+     *         )
      * );
      * 
      * 
      * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray(
-     * 		array(
-     * 			'allborders' => array(
-     * 				'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
-     * 				'color' => array(
-     * 					'rgb' => '808080'
-     * 				)
-     * 			)
-     * 		)
+     *         array(
+     *             'allborders' => array(
+     *                 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
+     *                 'color' => array(
+     *                     'rgb' => '808080'
+     *                 )
+     *             )
+     *         )
      * );
      * 
      *
-     * @param	array	$pStyles	Array containing style information
-     * @throws	PHPExcel_Exception
+     * @param    array    $pStyles    Array containing style information
+     * @throws    PHPExcel_Exception
      * @return PHPExcel_Style_Borders
      */
-	public function applyFromArray($pStyles = null) {
-		if (is_array($pStyles)) {
-			if ($this->_isSupervisor) {
-				$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
-			} else {
-				if (array_key_exists('left', $pStyles)) {
-					$this->getLeft()->applyFromArray($pStyles['left']);
-				}
-				if (array_key_exists('right', $pStyles)) {
-					$this->getRight()->applyFromArray($pStyles['right']);
-				}
-				if (array_key_exists('top', $pStyles)) {
-					$this->getTop()->applyFromArray($pStyles['top']);
-				}
-				if (array_key_exists('bottom', $pStyles)) {
-					$this->getBottom()->applyFromArray($pStyles['bottom']);
-				}
-				if (array_key_exists('diagonal', $pStyles)) {
-					$this->getDiagonal()->applyFromArray($pStyles['diagonal']);
-				}
-				if (array_key_exists('diagonaldirection', $pStyles)) {
-					$this->setDiagonalDirection($pStyles['diagonaldirection']);
-				}
-				if (array_key_exists('allborders', $pStyles)) {
-					$this->getLeft()->applyFromArray($pStyles['allborders']);
-					$this->getRight()->applyFromArray($pStyles['allborders']);
-					$this->getTop()->applyFromArray($pStyles['allborders']);
-					$this->getBottom()->applyFromArray($pStyles['allborders']);
-				}
-			}
-		} else {
-			throw new PHPExcel_Exception("Invalid style array passed.");
-		}
-		return $this;
-	}
+    public function applyFromArray($pStyles = null)
+    {
+        if (is_array($pStyles)) {
+            if ($this->isSupervisor) {
+                $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+            } else {
+                if (array_key_exists('left', $pStyles)) {
+                    $this->getLeft()->applyFromArray($pStyles['left']);
+                }
+                if (array_key_exists('right', $pStyles)) {
+                    $this->getRight()->applyFromArray($pStyles['right']);
+                }
+                if (array_key_exists('top', $pStyles)) {
+                    $this->getTop()->applyFromArray($pStyles['top']);
+                }
+                if (array_key_exists('bottom', $pStyles)) {
+                    $this->getBottom()->applyFromArray($pStyles['bottom']);
+                }
+                if (array_key_exists('diagonal', $pStyles)) {
+                    $this->getDiagonal()->applyFromArray($pStyles['diagonal']);
+                }
+                if (array_key_exists('diagonaldirection', $pStyles)) {
+                    $this->setDiagonalDirection($pStyles['diagonaldirection']);
+                }
+                if (array_key_exists('allborders', $pStyles)) {
+                    $this->getLeft()->applyFromArray($pStyles['allborders']);
+                    $this->getRight()->applyFromArray($pStyles['allborders']);
+                    $this->getTop()->applyFromArray($pStyles['allborders']);
+                    $this->getBottom()->applyFromArray($pStyles['allborders']);
+                }
+            }
+        } else {
+            throw new PHPExcel_Exception("Invalid style array passed.");
+        }
+        return $this;
+    }
 
     /**
      * Get Left
      *
      * @return PHPExcel_Style_Border
      */
-    public function getLeft() {
-		return $this->_left;
+    public function getLeft()
+    {
+        return $this->left;
     }
 
     /**
@@ -274,8 +268,9 @@ public function getLeft() {
      *
      * @return PHPExcel_Style_Border
      */
-    public function getRight() {
-		return $this->_right;
+    public function getRight()
+    {
+        return $this->right;
     }
 
     /**
@@ -283,8 +278,9 @@ public function getRight() {
      *
      * @return PHPExcel_Style_Border
      */
-    public function getTop() {
-		return $this->_top;
+    public function getTop()
+    {
+        return $this->top;
     }
 
     /**
@@ -292,8 +288,9 @@ public function getTop() {
      *
      * @return PHPExcel_Style_Border
      */
-    public function getBottom() {
-		return $this->_bottom;
+    public function getBottom()
+    {
+        return $this->bottom;
     }
 
     /**
@@ -301,8 +298,9 @@ public function getBottom() {
      *
      * @return PHPExcel_Style_Border
      */
-    public function getDiagonal() {
-		return $this->_diagonal;
+    public function getDiagonal()
+    {
+        return $this->diagonal;
     }
 
     /**
@@ -311,11 +309,12 @@ public function getDiagonal() {
      * @return PHPExcel_Style_Border
      * @throws PHPExcel_Exception
      */
-    public function getAllBorders() {
-		if (!$this->_isSupervisor) {
-			throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
-		}
-		return $this->_allBorders;
+    public function getAllBorders()
+    {
+        if (!$this->isSupervisor) {
+            throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
+        }
+        return $this->allBorders;
     }
 
     /**
@@ -324,11 +323,12 @@ public function getAllBorders() {
      * @return boolean
      * @throws PHPExcel_Exception
      */
-    public function getOutline() {
-		if (!$this->_isSupervisor) {
-			throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
-		}
-    	return $this->_outline;
+    public function getOutline()
+    {
+        if (!$this->isSupervisor) {
+            throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
+        }
+        return $this->outline;
     }
 
     /**
@@ -337,11 +337,12 @@ public function getOutline() {
      * @return boolean
      * @throws PHPExcel_Exception
      */
-    public function getInside() {
-		if (!$this->_isSupervisor) {
-			throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
-		}
-    	return $this->_inside;
+    public function getInside()
+    {
+        if (!$this->isSupervisor) {
+            throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
+        }
+        return $this->inside;
     }
 
     /**
@@ -350,11 +351,12 @@ public function getInside() {
      * @return PHPExcel_Style_Border
      * @throws PHPExcel_Exception
      */
-    public function getVertical() {
-		if (!$this->_isSupervisor) {
-			throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
-		}
-		return $this->_vertical;
+    public function getVertical()
+    {
+        if (!$this->isSupervisor) {
+            throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
+        }
+        return $this->vertical;
     }
 
     /**
@@ -363,11 +365,12 @@ public function getVertical() {
      * @return PHPExcel_Style_Border
      * @throws PHPExcel_Exception
      */
-    public function getHorizontal() {
-		if (!$this->_isSupervisor) {
-			throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
-		}
-		return $this->_horizontal;
+    public function getHorizontal()
+    {
+        if (!$this->isSupervisor) {
+            throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.');
+        }
+        return $this->horizontal;
     }
 
     /**
@@ -375,11 +378,12 @@ public function getHorizontal() {
      *
      * @return int
      */
-    public function getDiagonalDirection() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getDiagonalDirection();
-		}
-    	return $this->_diagonalDirection;
+    public function getDiagonalDirection()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getDiagonalDirection();
+        }
+        return $this->diagonalDirection;
     }
 
     /**
@@ -388,37 +392,38 @@ public function getDiagonalDirection() {
      * @param int $pValue
      * @return PHPExcel_Style_Borders
      */
-    public function setDiagonalDirection($pValue = PHPExcel_Style_Borders::DIAGONAL_NONE) {
+    public function setDiagonalDirection($pValue = PHPExcel_Style_Borders::DIAGONAL_NONE)
+    {
         if ($pValue == '') {
-    		$pValue = PHPExcel_Style_Borders::DIAGONAL_NONE;
-    	}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('diagonaldirection' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_diagonalDirection = $pValue;
-		}
-		return $this;
+            $pValue = PHPExcel_Style_Borders::DIAGONAL_NONE;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('diagonaldirection' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->diagonalDirection = $pValue;
+        }
+        return $this;
     }
 
-	/**
-	 * Get hash code
-	 *
-	 * @return string	Hash code
-	 */
-	public function getHashCode() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getHashcode();
-		}
-    	return md5(
-    		  $this->getLeft()->getHashCode()
-    		. $this->getRight()->getHashCode()
-    		. $this->getTop()->getHashCode()
-    		. $this->getBottom()->getHashCode()
-    		. $this->getDiagonal()->getHashCode()
-    		. $this->getDiagonalDirection()
-    		. __CLASS__
-    	);
+    /**
+     * Get hash code
+     *
+     * @return string    Hash code
+     */
+    public function getHashCode()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getHashcode();
+        }
+        return md5(
+            $this->getLeft()->getHashCode() .
+            $this->getRight()->getHashCode() .
+            $this->getTop()->getHashCode() .
+            $this->getBottom()->getHashCode() .
+            $this->getDiagonal()->getHashCode() .
+            $this->getDiagonalDirection() .
+            __CLASS__
+        );
     }
-
 }
diff --git a/Classes/PHPExcel/Style/Color.php b/Classes/PHPExcel/Style/Color.php
index f1fd40dad..9c7790f00 100644
--- a/Classes/PHPExcel/Style/Color.php
+++ b/Classes/PHPExcel/Style/Color.php
@@ -1,6 +1,7 @@
 _argb = $pARGB;
-		}
-	}
+    /**
+     * Create a new PHPExcel_Style_Color
+     *
+     * @param    string    $pARGB            ARGB value for the colour
+     * @param    boolean    $isSupervisor    Flag indicating if this is a supervisor or not
+     *                                    Leave this value at default unless you understand exactly what
+     *                                        its ramifications are
+     * @param    boolean    $isConditional    Flag indicating if this is a conditional style or not
+     *                                    Leave this value at default unless you understand exactly what
+     *                                        its ramifications are
+     */
+    public function __construct($pARGB = PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor = false, $isConditional = false)
+    {
+        //    Supervisor?
+        parent::__construct($isSupervisor);
 
-	/**
-	 * Bind parent. Only used for supervisor
-	 *
-	 * @param mixed $parent
-	 * @param string $parentPropertyName
-	 * @return PHPExcel_Style_Color
-	 */
-	public function bindParent($parent, $parentPropertyName=NULL)
-	{
-		$this->_parent = $parent;
-		$this->_parentPropertyName = $parentPropertyName;
-		return $this;
-	}
+        //    Initialise values
+        if (!$isConditional) {
+            $this->argb = $pARGB;
+        }
+    }
 
-	/**
-	 * Get the shared style component for the currently active cell in currently active sheet.
-	 * Only used for style supervisor
-	 *
-	 * @return PHPExcel_Style_Color
-	 */
-	public function getSharedComponent()
-	{
-		switch ($this->_parentPropertyName) {
-			case '_endColor':
-				return $this->_parent->getSharedComponent()->getEndColor();		break;
-			case '_color':
-				return $this->_parent->getSharedComponent()->getColor();		break;
-			case '_startColor':
-				return $this->_parent->getSharedComponent()->getStartColor();	break;
-		}
-	}
+    /**
+     * Bind parent. Only used for supervisor
+     *
+     * @param mixed $parent
+     * @param string $parentPropertyName
+     * @return PHPExcel_Style_Color
+     */
+    public function bindParent($parent, $parentPropertyName = null)
+    {
+        $this->parent = $parent;
+        $this->parentPropertyName = $parentPropertyName;
+        return $this;
+    }
 
-	/**
-	 * Build style array from subcomponents
-	 *
-	 * @param array $array
-	 * @return array
-	 */
-	public function getStyleArray($array)
-	{
-		switch ($this->_parentPropertyName) {
-			case '_endColor':
-				$key = 'endcolor';
-				break;
-			case '_color':
-				$key = 'color';
-				break;
-			case '_startColor':
-				$key = 'startcolor';
-				break;
+    /**
+     * Get the shared style component for the currently active cell in currently active sheet.
+     * Only used for style supervisor
+     *
+     * @return PHPExcel_Style_Color
+     */
+    public function getSharedComponent()
+    {
+        switch ($this->parentPropertyName) {
+            case 'endColor':
+                return $this->parent->getSharedComponent()->getEndColor();
+            case 'color':
+                return $this->parent->getSharedComponent()->getColor();
+            case 'startColor':
+                return $this->parent->getSharedComponent()->getStartColor();
+        }
+    }
 
-		}
-		return $this->_parent->getStyleArray(array($key => $array));
-	}
+    /**
+     * Build style array from subcomponents
+     *
+     * @param array $array
+     * @return array
+     */
+    public function getStyleArray($array)
+    {
+        switch ($this->parentPropertyName) {
+            case 'endColor':
+                $key = 'endcolor';
+                break;
+            case 'color':
+                $key = 'color';
+                break;
+            case 'startColor':
+                $key = 'startcolor';
+                break;
 
-	/**
-	 * Apply styles from array
-	 *
-	 * 
-	 * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->getColor()->applyFromArray( array('rgb' => '808080') );
-	 * 
-	 *
-	 * @param	array	$pStyles	Array containing style information
-	 * @throws	PHPExcel_Exception
-	 * @return PHPExcel_Style_Color
-	 */
-	public function applyFromArray($pStyles = NULL) {
-		if (is_array($pStyles)) {
-			if ($this->_isSupervisor) {
-				$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
-			} else {
-				if (array_key_exists('rgb', $pStyles)) {
-					$this->setRGB($pStyles['rgb']);
-				}
-				if (array_key_exists('argb', $pStyles)) {
-					$this->setARGB($pStyles['argb']);
-				}
-			}
-		} else {
-			throw new PHPExcel_Exception("Invalid style array passed.");
-		}
-		return $this;
-	}
+        }
+        return $this->parent->getStyleArray(array($key => $array));
+    }
 
-	/**
-	 * Get ARGB
-	 *
-	 * @return string
-	 */
-	public function getARGB() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getARGB();
-		}
-		return $this->_argb;
-	}
+    /**
+     * Apply styles from array
+     *
+     * 
+     * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->getColor()->applyFromArray( array('rgb' => '808080') );
+     * 
+     *
+     * @param    array    $pStyles    Array containing style information
+     * @throws    PHPExcel_Exception
+     * @return PHPExcel_Style_Color
+     */
+    public function applyFromArray($pStyles = null)
+    {
+        if (is_array($pStyles)) {
+            if ($this->isSupervisor) {
+                $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+            } else {
+                if (array_key_exists('rgb', $pStyles)) {
+                    $this->setRGB($pStyles['rgb']);
+                }
+                if (array_key_exists('argb', $pStyles)) {
+                    $this->setARGB($pStyles['argb']);
+                }
+            }
+        } else {
+            throw new PHPExcel_Exception("Invalid style array passed.");
+        }
+        return $this;
+    }
 
-	/**
-	 * Set ARGB
-	 *
-	 * @param string $pValue
-	 * @return PHPExcel_Style_Color
-	 */
-	public function setARGB($pValue = PHPExcel_Style_Color::COLOR_BLACK) {
-		if ($pValue == '') {
-			$pValue = PHPExcel_Style_Color::COLOR_BLACK;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('argb' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_argb = $pValue;
-		}
-		return $this;
-	}
+    /**
+     * Get ARGB
+     *
+     * @return string
+     */
+    public function getARGB()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getARGB();
+        }
+        return $this->argb;
+    }
 
-	/**
-	 * Get RGB
-	 *
-	 * @return string
-	 */
-	public function getRGB() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getRGB();
-		}
-		return substr($this->_argb, 2);
-	}
+    /**
+     * Set ARGB
+     *
+     * @param string $pValue
+     * @return PHPExcel_Style_Color
+     */
+    public function setARGB($pValue = PHPExcel_Style_Color::COLOR_BLACK)
+    {
+        if ($pValue == '') {
+            $pValue = PHPExcel_Style_Color::COLOR_BLACK;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('argb' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->argb = $pValue;
+        }
+        return $this;
+    }
 
-	/**
-	 * Set RGB
-	 *
-	 * @param	string	$pValue	RGB value
-	 * @return PHPExcel_Style_Color
-	 */
-	public function setRGB($pValue = '000000') {
-		if ($pValue == '') {
-			$pValue = '000000';
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('argb' => 'FF' . $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_argb = 'FF' . $pValue;
-		}
-		return $this;
-	}
+    /**
+     * Get RGB
+     *
+     * @return string
+     */
+    public function getRGB()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getRGB();
+        }
+        return substr($this->argb, 2);
+    }
 
-	/**
-	 * Get a specified colour component of an RGB value
-	 *
-	 * @private
-	 * @param	string		$RGB		The colour as an RGB value (e.g. FF00CCCC or CCDDEE
-	 * @param	int			$offset		Position within the RGB value to extract
-	 * @param	boolean		$hex		Flag indicating whether the component should be returned as a hex or a
-	 *									decimal value
-	 * @return	string		The extracted colour component
-	 */
-	private static function _getColourComponent($RGB,$offset,$hex=TRUE) {
-		$colour = substr($RGB, $offset, 2);
-		if (!$hex)
-			$colour = hexdec($colour);
-		return $colour;
-	}
+    /**
+     * Set RGB
+     *
+     * @param    string    $pValue    RGB value
+     * @return PHPExcel_Style_Color
+     */
+    public function setRGB($pValue = '000000')
+    {
+        if ($pValue == '') {
+            $pValue = '000000';
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('argb' => 'FF' . $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->argb = 'FF' . $pValue;
+        }
+        return $this;
+    }
 
-	/**
-	 * Get the red colour component of an RGB value
-	 *
-	 * @param	string		$RGB		The colour as an RGB value (e.g. FF00CCCC or CCDDEE
-	 * @param	boolean		$hex		Flag indicating whether the component should be returned as a hex or a
-	 *									decimal value
-	 * @return	string		The red colour component
-	 */
-	public static function getRed($RGB,$hex=TRUE) {
-		return self::_getColourComponent($RGB, strlen($RGB) - 6, $hex);
-	}
+    /**
+     * Get a specified colour component of an RGB value
+     *
+     * @private
+     * @param    string        $RGB        The colour as an RGB value (e.g. FF00CCCC or CCDDEE
+     * @param    int            $offset        Position within the RGB value to extract
+     * @param    boolean        $hex        Flag indicating whether the component should be returned as a hex or a
+     *                                    decimal value
+     * @return    string        The extracted colour component
+     */
+    private static function getColourComponent($RGB, $offset, $hex = true)
+    {
+        $colour = substr($RGB, $offset, 2);
+        if (!$hex) {
+            $colour = hexdec($colour);
+        }
+        return $colour;
+    }
 
-	/**
-	 * Get the green colour component of an RGB value
-	 *
-	 * @param	string		$RGB		The colour as an RGB value (e.g. FF00CCCC or CCDDEE
-	 * @param	boolean		$hex		Flag indicating whether the component should be returned as a hex or a
-	 *									decimal value
-	 * @return	string		The green colour component
-	 */
-	public static function getGreen($RGB,$hex=TRUE) {
-		return self::_getColourComponent($RGB, strlen($RGB) - 4, $hex);
-	}
+    /**
+     * Get the red colour component of an RGB value
+     *
+     * @param    string        $RGB        The colour as an RGB value (e.g. FF00CCCC or CCDDEE
+     * @param    boolean        $hex        Flag indicating whether the component should be returned as a hex or a
+     *                                    decimal value
+     * @return    string        The red colour component
+     */
+    public static function getRed($RGB, $hex = true)
+    {
+        return self::getColourComponent($RGB, strlen($RGB) - 6, $hex);
+    }
 
-	/**
-	 * Get the blue colour component of an RGB value
-	 *
-	 * @param	string		$RGB		The colour as an RGB value (e.g. FF00CCCC or CCDDEE
-	 * @param	boolean		$hex		Flag indicating whether the component should be returned as a hex or a
-	 *									decimal value
-	 * @return	string		The blue colour component
-	 */
-	public static function getBlue($RGB,$hex=TRUE) {
-		return self::_getColourComponent($RGB, strlen($RGB) - 2, $hex);
-	}
+    /**
+     * Get the green colour component of an RGB value
+     *
+     * @param    string        $RGB        The colour as an RGB value (e.g. FF00CCCC or CCDDEE
+     * @param    boolean        $hex        Flag indicating whether the component should be returned as a hex or a
+     *                                    decimal value
+     * @return    string        The green colour component
+     */
+    public static function getGreen($RGB, $hex = true)
+    {
+        return self::getColourComponent($RGB, strlen($RGB) - 4, $hex);
+    }
 
-	/**
-	 * Adjust the brightness of a color
-	 *
-	 * @param	string		$hex	The colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)
-	 * @param	float		$adjustPercentage	The percentage by which to adjust the colour as a float from -1 to 1
-	 * @return	string		The adjusted colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)
-	 */
-	public static function changeBrightness($hex, $adjustPercentage) {
-		$rgba = (strlen($hex) == 8);
+    /**
+     * Get the blue colour component of an RGB value
+     *
+     * @param    string        $RGB        The colour as an RGB value (e.g. FF00CCCC or CCDDEE
+     * @param    boolean        $hex        Flag indicating whether the component should be returned as a hex or a
+     *                                    decimal value
+     * @return    string        The blue colour component
+     */
+    public static function getBlue($RGB, $hex = true)
+    {
+        return self::getColourComponent($RGB, strlen($RGB) - 2, $hex);
+    }
 
-		$red	= self::getRed($hex, FALSE);
-		$green	= self::getGreen($hex, FALSE);
-		$blue	= self::getBlue($hex, FALSE);
-		if ($adjustPercentage > 0) {
-			$red	+= (255 - $red) * $adjustPercentage;
-			$green	+= (255 - $green) * $adjustPercentage;
-			$blue	+= (255 - $blue) * $adjustPercentage;
-		} else {
-			$red	+= $red * $adjustPercentage;
-			$green	+= $green * $adjustPercentage;
-			$blue	+= $blue * $adjustPercentage;
-		}
+    /**
+     * Adjust the brightness of a color
+     *
+     * @param    string        $hex    The colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)
+     * @param    float        $adjustPercentage    The percentage by which to adjust the colour as a float from -1 to 1
+     * @return    string        The adjusted colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)
+     */
+    public static function changeBrightness($hex, $adjustPercentage)
+    {
+        $rgba = (strlen($hex) == 8);
 
-		if ($red < 0) $red = 0;
-		elseif ($red > 255) $red = 255;
-		if ($green < 0) $green = 0;
-		elseif ($green > 255) $green = 255;
-		if ($blue < 0) $blue = 0;
-		elseif ($blue > 255) $blue = 255;
+        $red = self::getRed($hex, false);
+        $green = self::getGreen($hex, false);
+        $blue = self::getBlue($hex, false);
+        if ($adjustPercentage > 0) {
+            $red += (255 - $red) * $adjustPercentage;
+            $green += (255 - $green) * $adjustPercentage;
+            $blue += (255 - $blue) * $adjustPercentage;
+        } else {
+            $red += $red * $adjustPercentage;
+            $green += $green * $adjustPercentage;
+            $blue += $blue * $adjustPercentage;
+        }
 
-		$rgb = strtoupper(	str_pad(dechex($red), 2, '0', 0) .
-							str_pad(dechex($green), 2, '0', 0) .
-							str_pad(dechex($blue), 2, '0', 0)
-						 );
-		return (($rgba) ? 'FF' : '') . $rgb;
-	}
+        if ($red < 0) {
+            $red = 0;
+        } elseif ($red > 255) {
+            $red = 255;
+        }
+        if ($green < 0) {
+            $green = 0;
+        } elseif ($green > 255) {
+            $green = 255;
+        }
+        if ($blue < 0) {
+            $blue = 0;
+        } elseif ($blue > 255) {
+            $blue = 255;
+        }
 
-	/**
-	 * Get indexed color
-	 *
-	 * @param	int			$pIndex			Index entry point into the colour array
-	 * @param	boolean		$background		Flag to indicate whether default background or foreground colour
-	 *											should be returned if the indexed colour doesn't exist
-	 * @return	PHPExcel_Style_Color
-	 */
-	public static function indexedColor($pIndex, $background=FALSE) {
-		// Clean parameter
-		$pIndex = intval($pIndex);
+        $rgb = strtoupper(
+            str_pad(dechex($red), 2, '0', 0) .
+            str_pad(dechex($green), 2, '0', 0) .
+            str_pad(dechex($blue), 2, '0', 0)
+        );
+        return (($rgba) ? 'FF' : '') . $rgb;
+    }
 
-		// Indexed colors
-		if (is_null(self::$_indexedColors)) {
-			self::$_indexedColors = array(
-					1	=> 'FF000000',	//	System Colour #1 - Black
-					2	=> 'FFFFFFFF',	//	System Colour #2 - White
-					3	=> 'FFFF0000',	//	System Colour #3 - Red
-					4	=> 'FF00FF00',	//	System Colour #4 - Green
-					5	=> 'FF0000FF',	//	System Colour #5 - Blue
-					6	=> 'FFFFFF00',	//	System Colour #6 - Yellow
-					7	=> 'FFFF00FF',	//	System Colour #7- Magenta
-					8	=> 'FF00FFFF',	//	System Colour #8- Cyan
-					9	=> 'FF800000',	//	Standard Colour #9
-					10	=> 'FF008000',	//	Standard Colour #10
-					11	=> 'FF000080',	//	Standard Colour #11
-					12	=> 'FF808000',	//	Standard Colour #12
-					13	=> 'FF800080',	//	Standard Colour #13
-					14	=> 'FF008080',	//	Standard Colour #14
-					15	=> 'FFC0C0C0',	//	Standard Colour #15
-					16	=> 'FF808080',	//	Standard Colour #16
-					17	=> 'FF9999FF',	//	Chart Fill Colour #17
-					18	=> 'FF993366',	//	Chart Fill Colour #18
-					19	=> 'FFFFFFCC',	//	Chart Fill Colour #19
-					20	=> 'FFCCFFFF',	//	Chart Fill Colour #20
-					21	=> 'FF660066',	//	Chart Fill Colour #21
-					22	=> 'FFFF8080',	//	Chart Fill Colour #22
-					23	=> 'FF0066CC',	//	Chart Fill Colour #23
-					24	=> 'FFCCCCFF',	//	Chart Fill Colour #24
-					25	=> 'FF000080',	//	Chart Line Colour #25
-					26	=> 'FFFF00FF',	//	Chart Line Colour #26
-					27	=> 'FFFFFF00',	//	Chart Line Colour #27
-					28	=> 'FF00FFFF',	//	Chart Line Colour #28
-					29	=> 'FF800080',	//	Chart Line Colour #29
-					30	=> 'FF800000',	//	Chart Line Colour #30
-					31	=> 'FF008080',	//	Chart Line Colour #31
-					32	=> 'FF0000FF',	//	Chart Line Colour #32
-					33	=> 'FF00CCFF',	//	Standard Colour #33
-					34	=> 'FFCCFFFF',	//	Standard Colour #34
-					35	=> 'FFCCFFCC',	//	Standard Colour #35
-					36	=> 'FFFFFF99',	//	Standard Colour #36
-					37	=> 'FF99CCFF',	//	Standard Colour #37
-					38	=> 'FFFF99CC',	//	Standard Colour #38
-					39	=> 'FFCC99FF',	//	Standard Colour #39
-					40	=> 'FFFFCC99',	//	Standard Colour #40
-					41	=> 'FF3366FF',	//	Standard Colour #41
-					42	=> 'FF33CCCC',	//	Standard Colour #42
-					43	=> 'FF99CC00',	//	Standard Colour #43
-					44	=> 'FFFFCC00',	//	Standard Colour #44
-					45	=> 'FFFF9900',	//	Standard Colour #45
-					46	=> 'FFFF6600',	//	Standard Colour #46
-					47	=> 'FF666699',	//	Standard Colour #47
-					48	=> 'FF969696',	//	Standard Colour #48
-					49	=> 'FF003366',	//	Standard Colour #49
-					50	=> 'FF339966',	//	Standard Colour #50
-					51	=> 'FF003300',	//	Standard Colour #51
-					52	=> 'FF333300',	//	Standard Colour #52
-					53	=> 'FF993300',	//	Standard Colour #53
-					54	=> 'FF993366',	//	Standard Colour #54
-					55	=> 'FF333399',	//	Standard Colour #55
-					56	=> 'FF333333'	//	Standard Colour #56
-				);
-		}
+    /**
+     * Get indexed color
+     *
+     * @param    int            $pIndex            Index entry point into the colour array
+     * @param    boolean        $background        Flag to indicate whether default background or foreground colour
+     *                                            should be returned if the indexed colour doesn't exist
+     * @return    PHPExcel_Style_Color
+     */
+    public static function indexedColor($pIndex, $background = false)
+    {
+        // Clean parameter
+        $pIndex = intval($pIndex);
 
-		if (array_key_exists($pIndex, self::$_indexedColors)) {
-			return new PHPExcel_Style_Color(self::$_indexedColors[$pIndex]);
-		}
+        // Indexed colors
+        if (is_null(self::$indexedColors)) {
+            self::$indexedColors = array(
+                    1    => 'FF000000',    //    System Colour #1 - Black
+                    2    => 'FFFFFFFF',    //    System Colour #2 - White
+                    3    => 'FFFF0000',    //    System Colour #3 - Red
+                    4    => 'FF00FF00',    //    System Colour #4 - Green
+                    5    => 'FF0000FF',    //    System Colour #5 - Blue
+                    6    => 'FFFFFF00',    //    System Colour #6 - Yellow
+                    7    => 'FFFF00FF',    //    System Colour #7- Magenta
+                    8    => 'FF00FFFF',    //    System Colour #8- Cyan
+                    9    => 'FF800000',    //    Standard Colour #9
+                    10    => 'FF008000',    //    Standard Colour #10
+                    11    => 'FF000080',    //    Standard Colour #11
+                    12    => 'FF808000',    //    Standard Colour #12
+                    13    => 'FF800080',    //    Standard Colour #13
+                    14    => 'FF008080',    //    Standard Colour #14
+                    15    => 'FFC0C0C0',    //    Standard Colour #15
+                    16    => 'FF808080',    //    Standard Colour #16
+                    17    => 'FF9999FF',    //    Chart Fill Colour #17
+                    18    => 'FF993366',    //    Chart Fill Colour #18
+                    19    => 'FFFFFFCC',    //    Chart Fill Colour #19
+                    20    => 'FFCCFFFF',    //    Chart Fill Colour #20
+                    21    => 'FF660066',    //    Chart Fill Colour #21
+                    22    => 'FFFF8080',    //    Chart Fill Colour #22
+                    23    => 'FF0066CC',    //    Chart Fill Colour #23
+                    24    => 'FFCCCCFF',    //    Chart Fill Colour #24
+                    25    => 'FF000080',    //    Chart Line Colour #25
+                    26    => 'FFFF00FF',    //    Chart Line Colour #26
+                    27    => 'FFFFFF00',    //    Chart Line Colour #27
+                    28    => 'FF00FFFF',    //    Chart Line Colour #28
+                    29    => 'FF800080',    //    Chart Line Colour #29
+                    30    => 'FF800000',    //    Chart Line Colour #30
+                    31    => 'FF008080',    //    Chart Line Colour #31
+                    32    => 'FF0000FF',    //    Chart Line Colour #32
+                    33    => 'FF00CCFF',    //    Standard Colour #33
+                    34    => 'FFCCFFFF',    //    Standard Colour #34
+                    35    => 'FFCCFFCC',    //    Standard Colour #35
+                    36    => 'FFFFFF99',    //    Standard Colour #36
+                    37    => 'FF99CCFF',    //    Standard Colour #37
+                    38    => 'FFFF99CC',    //    Standard Colour #38
+                    39    => 'FFCC99FF',    //    Standard Colour #39
+                    40    => 'FFFFCC99',    //    Standard Colour #40
+                    41    => 'FF3366FF',    //    Standard Colour #41
+                    42    => 'FF33CCCC',    //    Standard Colour #42
+                    43    => 'FF99CC00',    //    Standard Colour #43
+                    44    => 'FFFFCC00',    //    Standard Colour #44
+                    45    => 'FFFF9900',    //    Standard Colour #45
+                    46    => 'FFFF6600',    //    Standard Colour #46
+                    47    => 'FF666699',    //    Standard Colour #47
+                    48    => 'FF969696',    //    Standard Colour #48
+                    49    => 'FF003366',    //    Standard Colour #49
+                    50    => 'FF339966',    //    Standard Colour #50
+                    51    => 'FF003300',    //    Standard Colour #51
+                    52    => 'FF333300',    //    Standard Colour #52
+                    53    => 'FF993300',    //    Standard Colour #53
+                    54    => 'FF993366',    //    Standard Colour #54
+                    55    => 'FF333399',    //    Standard Colour #55
+                    56    => 'FF333333'    //    Standard Colour #56
+                );
+        }
 
-		if ($background) {
-			return new PHPExcel_Style_Color('FFFFFFFF');
-		}
-		return new PHPExcel_Style_Color('FF000000');
-	}
+        if (array_key_exists($pIndex, self::$indexedColors)) {
+            return new PHPExcel_Style_Color(self::$indexedColors[$pIndex]);
+        }
 
-	/**
-	 * Get hash code
-	 *
-	 * @return string	Hash code
-	 */
-	public function getHashCode() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getHashCode();
-		}
-		return md5(
-			  $this->_argb
-			. __CLASS__
-		);
-	}
+        if ($background) {
+            return new PHPExcel_Style_Color(self::COLOR_WHITE);
+        }
+        return new PHPExcel_Style_Color(self::COLOR_BLACK);
+    }
 
+    /**
+     * Get hash code
+     *
+     * @return string    Hash code
+     */
+    public function getHashCode()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getHashCode();
+        }
+        return md5(
+            $this->argb .
+            __CLASS__
+        );
+    }
 }
diff --git a/Classes/PHPExcel/Style/Conditional.php b/Classes/PHPExcel/Style/Conditional.php
index 17ac564cb..331362b42 100644
--- a/Classes/PHPExcel/Style/Conditional.php
+++ b/Classes/PHPExcel/Style/Conditional.php
@@ -21,7 +21,7 @@
  * @category   PHPExcel
  * @package    PHPExcel_Style
  * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
- * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
+ * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  * @version    ##VERSION##, ##DATE##
  */
 
@@ -35,72 +35,72 @@
  */
 class PHPExcel_Style_Conditional implements PHPExcel_IComparable
 {
-	/* Condition types */
-	const CONDITION_NONE					= 'none';
-	const CONDITION_CELLIS					= 'cellIs';
-	const CONDITION_CONTAINSTEXT			= 'containsText';
-	const CONDITION_EXPRESSION 				= 'expression';
+    /* Condition types */
+    const CONDITION_NONE         = 'none';
+    const CONDITION_CELLIS       = 'cellIs';
+    const CONDITION_CONTAINSTEXT = 'containsText';
+    const CONDITION_EXPRESSION   = 'expression';
 
-	/* Operator types */
-	const OPERATOR_NONE						= '';
-	const OPERATOR_BEGINSWITH				= 'beginsWith';
-	const OPERATOR_ENDSWITH					= 'endsWith';
-	const OPERATOR_EQUAL					= 'equal';
-	const OPERATOR_GREATERTHAN				= 'greaterThan';
-	const OPERATOR_GREATERTHANOREQUAL		= 'greaterThanOrEqual';
-	const OPERATOR_LESSTHAN					= 'lessThan';
-	const OPERATOR_LESSTHANOREQUAL			= 'lessThanOrEqual';
-	const OPERATOR_NOTEQUAL					= 'notEqual';
-	const OPERATOR_CONTAINSTEXT				= 'containsText';
-	const OPERATOR_NOTCONTAINS				= 'notContains';
-	const OPERATOR_BETWEEN					= 'between';
+    /* Operator types */
+    const OPERATOR_NONE               = '';
+    const OPERATOR_BEGINSWITH         = 'beginsWith';
+    const OPERATOR_ENDSWITH           = 'endsWith';
+    const OPERATOR_EQUAL              = 'equal';
+    const OPERATOR_GREATERTHAN        = 'greaterThan';
+    const OPERATOR_GREATERTHANOREQUAL = 'greaterThanOrEqual';
+    const OPERATOR_LESSTHAN           = 'lessThan';
+    const OPERATOR_LESSTHANOREQUAL    = 'lessThanOrEqual';
+    const OPERATOR_NOTEQUAL           = 'notEqual';
+    const OPERATOR_CONTAINSTEXT       = 'containsText';
+    const OPERATOR_NOTCONTAINS        = 'notContains';
+    const OPERATOR_BETWEEN            = 'between';
 
-	/**
-	 * Condition type
-	 *
-	 * @var int
-	 */
-	private $_conditionType;
+    /**
+     * Condition type
+     *
+     * @var int
+     */
+    private $conditionType;
 
-	/**
-	 * Operator type
-	 *
-	 * @var int
-	 */
-	private $_operatorType;
+    /**
+     * Operator type
+     *
+     * @var int
+     */
+    private $operatorType;
 
-	/**
-	 * Text
-	 *
-	 * @var string
-	 */
-	private $_text;
+    /**
+     * Text
+     *
+     * @var string
+     */
+    private $text;
 
-	/**
-	 * Condition
-	 *
-	 * @var string[]
-	 */
-	private $_condition = array();
+    /**
+     * Condition
+     *
+     * @var string[]
+     */
+    private $condition = array();
 
-	/**
-	 * Style
-	 *
-	 * @var PHPExcel_Style
-	 */
-	private $_style;
+    /**
+     * Style
+     *
+     * @var PHPExcel_Style
+     */
+    private $style;
 
     /**
      * Create a new PHPExcel_Style_Conditional
      */
     public function __construct()
     {
-    	// Initialise values
-    	$this->_conditionType		= PHPExcel_Style_Conditional::CONDITION_NONE;
-    	$this->_operatorType		= PHPExcel_Style_Conditional::OPERATOR_NONE;
-    	$this->_text    			= null;
-    	$this->_condition			= array();
-    	$this->_style				= new PHPExcel_Style(FALSE, TRUE);
+        // Initialise values
+        $this->conditionType = PHPExcel_Style_Conditional::CONDITION_NONE;
+        $this->operatorType  = PHPExcel_Style_Conditional::OPERATOR_NONE;
+        $this->text          = null;
+        $this->condition     = array();
+        $this->style         = new PHPExcel_Style(false, true);
     }
 
     /**
@@ -108,19 +108,21 @@ public function __construct()
      *
      * @return string
      */
-    public function getConditionType() {
-    	return $this->_conditionType;
+    public function getConditionType()
+    {
+        return $this->conditionType;
     }
 
     /**
      * Set Condition type
      *
-     * @param string $pValue	PHPExcel_Style_Conditional condition type
+     * @param string $pValue    PHPExcel_Style_Conditional condition type
      * @return PHPExcel_Style_Conditional
      */
-    public function setConditionType($pValue = PHPExcel_Style_Conditional::CONDITION_NONE) {
-    	$this->_conditionType = $pValue;
-    	return $this;
+    public function setConditionType($pValue = PHPExcel_Style_Conditional::CONDITION_NONE)
+    {
+        $this->conditionType = $pValue;
+        return $this;
     }
 
     /**
@@ -128,19 +130,21 @@ public function setConditionType($pValue = PHPExcel_Style_Conditional::CONDITION
      *
      * @return string
      */
-    public function getOperatorType() {
-    	return $this->_operatorType;
+    public function getOperatorType()
+    {
+        return $this->operatorType;
     }
 
     /**
      * Set Operator type
      *
-     * @param string $pValue	PHPExcel_Style_Conditional operator type
+     * @param string $pValue    PHPExcel_Style_Conditional operator type
      * @return PHPExcel_Style_Conditional
      */
-    public function setOperatorType($pValue = PHPExcel_Style_Conditional::OPERATOR_NONE) {
-    	$this->_operatorType = $pValue;
-    	return $this;
+    public function setOperatorType($pValue = PHPExcel_Style_Conditional::OPERATOR_NONE)
+    {
+        $this->operatorType = $pValue;
+        return $this;
     }
 
     /**
@@ -148,8 +152,9 @@ public function setOperatorType($pValue = PHPExcel_Style_Conditional::OPERATOR_N
      *
      * @return string
      */
-    public function getText() {
-        return $this->_text;
+    public function getText()
+    {
+        return $this->text;
     }
 
     /**
@@ -158,9 +163,10 @@ public function getText() {
      * @param string $value
      * @return PHPExcel_Style_Conditional
      */
-    public function setText($value = null) {
-           $this->_text = $value;
-           return $this;
+    public function setText($value = null)
+    {
+        $this->text = $value;
+        return $this;
     }
 
     /**
@@ -169,26 +175,29 @@ public function setText($value = null) {
      * @deprecated Deprecated, use getConditions instead
      * @return string
      */
-    public function getCondition() {
-    	if (isset($this->_condition[0])) {
-    		return $this->_condition[0];
-    	}
+    public function getCondition()
+    {
+        if (isset($this->condition[0])) {
+            return $this->condition[0];
+        }
 
-    	return '';
+        return '';
     }
 
     /**
      * Set Condition
      *
      * @deprecated Deprecated, use setConditions instead
-     * @param string $pValue	Condition
+     * @param string $pValue    Condition
      * @return PHPExcel_Style_Conditional
      */
-    public function setCondition($pValue = '') {
-    	if (!is_array($pValue))
-    		$pValue = array($pValue);
+    public function setCondition($pValue = '')
+    {
+        if (!is_array($pValue)) {
+            $pValue = array($pValue);
+        }
 
-    	return $this->setConditions($pValue);
+        return $this->setConditions($pValue);
     }
 
     /**
@@ -196,33 +205,36 @@ public function setCondition($pValue = '') {
      *
      * @return string[]
      */
-    public function getConditions() {
-    	return $this->_condition;
+    public function getConditions()
+    {
+        return $this->condition;
     }
 
     /**
      * Set Conditions
      *
-     * @param string[] $pValue	Condition
+     * @param string[] $pValue    Condition
      * @return PHPExcel_Style_Conditional
      */
-    public function setConditions($pValue) {
-    	if (!is_array($pValue))
-    		$pValue = array($pValue);
-
-    	$this->_condition = $pValue;
-    	return $this;
+    public function setConditions($pValue)
+    {
+        if (!is_array($pValue)) {
+            $pValue = array($pValue);
+        }
+        $this->condition = $pValue;
+        return $this;
     }
 
     /**
      * Add Condition
      *
-     * @param string $pValue	Condition
+     * @param string $pValue    Condition
      * @return PHPExcel_Style_Conditional
      */
-    public function addCondition($pValue = '') {
-    	$this->_condition[] = $pValue;
-    	return $this;
+    public function addCondition($pValue = '')
+    {
+        $this->condition[] = $pValue;
+        return $this;
     }
 
     /**
@@ -230,48 +242,52 @@ public function addCondition($pValue = '') {
      *
      * @return PHPExcel_Style
      */
-    public function getStyle() {
-    	return $this->_style;
+    public function getStyle()
+    {
+        return $this->style;
     }
 
     /**
      * Set Style
      *
-     * @param 	PHPExcel_Style $pValue
-     * @throws 	PHPExcel_Exception
+     * @param     PHPExcel_Style $pValue
+     * @throws     PHPExcel_Exception
      * @return PHPExcel_Style_Conditional
      */
-    public function setStyle(PHPExcel_Style $pValue = null) {
-   		$this->_style = $pValue;
-   		return $this;
+    public function setStyle(PHPExcel_Style $pValue = null)
+    {
+           $this->style = $pValue;
+           return $this;
     }
 
-	/**
-	 * Get hash code
-	 *
-	 * @return string	Hash code
-	 */
-	public function getHashCode() {
-    	return md5(
-    		  $this->_conditionType
-    		. $this->_operatorType
-    		. implode(';', $this->_condition)
-    		. $this->_style->getHashCode()
-    		. __CLASS__
-    	);
+    /**
+     * Get hash code
+     *
+     * @return string    Hash code
+     */
+    public function getHashCode()
+    {
+        return md5(
+            $this->conditionType .
+            $this->operatorType .
+            implode(';', $this->condition) .
+            $this->style->getHashCode() .
+            __CLASS__
+        );
     }
 
-	/**
-	 * Implement PHP __clone to create a deep clone, not just a shallow copy.
-	 */
-	public function __clone() {
-		$vars = get_object_vars($this);
-		foreach ($vars as $key => $value) {
-			if (is_object($value)) {
-				$this->$key = clone $value;
-			} else {
-				$this->$key = $value;
-			}
-		}
-	}
+    /**
+     * Implement PHP __clone to create a deep clone, not just a shallow copy.
+     */
+    public function __clone()
+    {
+        $vars = get_object_vars($this);
+        foreach ($vars as $key => $value) {
+            if (is_object($value)) {
+                $this->$key = clone $value;
+            } else {
+                $this->$key = $value;
+            }
+        }
+    }
 }
diff --git a/Classes/PHPExcel/Style/Fill.php b/Classes/PHPExcel/Style/Fill.php
index 29e3a6eac..26343ff5a 100644
--- a/Classes/PHPExcel/Style/Fill.php
+++ b/Classes/PHPExcel/Style/Fill.php
@@ -1,6 +1,7 @@
 _fillType = NULL;
-		}
-		$this->_startColor			= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_WHITE, $isSupervisor, $isConditional);
-		$this->_endColor			= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional);
+    /**
+     * Create a new PHPExcel_Style_Fill
+     *
+     * @param    boolean    $isSupervisor    Flag indicating if this is a supervisor or not
+     *                                    Leave this value at default unless you understand exactly what
+     *                                        its ramifications are
+     * @param    boolean    $isConditional    Flag indicating if this is a conditional style or not
+     *                                    Leave this value at default unless you understand exactly what
+     *                                        its ramifications are
+     */
+    public function __construct($isSupervisor = false, $isConditional = false)
+    {
+        // Supervisor?
+        parent::__construct($isSupervisor);
 
-		// bind parent if we are a supervisor
-		if ($isSupervisor) {
-			$this->_startColor->bindParent($this, '_startColor');
-			$this->_endColor->bindParent($this, '_endColor');
-		}
-	}
+        // Initialise values
+        if ($isConditional) {
+            $this->fillType = null;
+        }
+        $this->startColor = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_WHITE, $isSupervisor, $isConditional);
+        $this->endColor = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional);
 
-	/**
-	 * Get the shared style component for the currently active cell in currently active sheet.
-	 * Only used for style supervisor
-	 *
-	 * @return PHPExcel_Style_Fill
-	 */
-	public function getSharedComponent()
-	{
-		return $this->_parent->getSharedComponent()->getFill();
-	}
+        // bind parent if we are a supervisor
+        if ($isSupervisor) {
+            $this->startColor->bindParent($this, 'startColor');
+            $this->endColor->bindParent($this, 'endColor');
+        }
+    }
 
-	/**
-	 * Build style array from subcomponents
-	 *
-	 * @param array $array
-	 * @return array
-	 */
-	public function getStyleArray($array)
-	{
-		return array('fill' => $array);
-	}
+    /**
+     * Get the shared style component for the currently active cell in currently active sheet.
+     * Only used for style supervisor
+     *
+     * @return PHPExcel_Style_Fill
+     */
+    public function getSharedComponent()
+    {
+        return $this->parent->getSharedComponent()->getFill();
+    }
 
-	/**
-	 * Apply styles from array
-	 *
-	 * 
-	 * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFill()->applyFromArray(
-	 *		array(
-	 *			'type'	   => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR,
-	 *			'rotation'   => 0,
-	 *			'startcolor' => array(
-	 *				'rgb' => '000000'
-	 *			),
-	 *			'endcolor'   => array(
-	 *				'argb' => 'FFFFFFFF'
-	 *			)
-	 *		)
-	 * );
-	 * 
-	 *
-	 * @param	array	$pStyles	Array containing style information
-	 * @throws	PHPExcel_Exception
-	 * @return PHPExcel_Style_Fill
-	 */
-	public function applyFromArray($pStyles = null) {
-		if (is_array($pStyles)) {
-			if ($this->_isSupervisor) {
-				$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
-			} else {
-				if (array_key_exists('type', $pStyles)) {
-					$this->setFillType($pStyles['type']);
-				}
-				if (array_key_exists('rotation', $pStyles)) {
-					$this->setRotation($pStyles['rotation']);
-				}
-				if (array_key_exists('startcolor', $pStyles)) {
-					$this->getStartColor()->applyFromArray($pStyles['startcolor']);
-				}
-				if (array_key_exists('endcolor', $pStyles)) {
-					$this->getEndColor()->applyFromArray($pStyles['endcolor']);
-				}
-				if (array_key_exists('color', $pStyles)) {
-					$this->getStartColor()->applyFromArray($pStyles['color']);
-				}
-			}
-		} else {
-			throw new PHPExcel_Exception("Invalid style array passed.");
-		}
-		return $this;
-	}
+    /**
+     * Build style array from subcomponents
+     *
+     * @param array $array
+     * @return array
+     */
+    public function getStyleArray($array)
+    {
+        return array('fill' => $array);
+    }
 
-	/**
-	 * Get Fill Type
-	 *
-	 * @return string
-	 */
-	public function getFillType() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getFillType();
-		}
-		return $this->_fillType;
-	}
+    /**
+     * Apply styles from array
+     *
+     * 
+     * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFill()->applyFromArray(
+     *        array(
+     *            'type'       => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR,
+     *            'rotation'   => 0,
+     *            'startcolor' => array(
+     *                'rgb' => '000000'
+     *            ),
+     *            'endcolor'   => array(
+     *                'argb' => 'FFFFFFFF'
+     *            )
+     *        )
+     * );
+     * 
+     *
+     * @param    array    $pStyles    Array containing style information
+     * @throws    PHPExcel_Exception
+     * @return PHPExcel_Style_Fill
+     */
+    public function applyFromArray($pStyles = null)
+    {
+        if (is_array($pStyles)) {
+            if ($this->isSupervisor) {
+                $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+            } else {
+                if (array_key_exists('type', $pStyles)) {
+                    $this->setFillType($pStyles['type']);
+                }
+                if (array_key_exists('rotation', $pStyles)) {
+                    $this->setRotation($pStyles['rotation']);
+                }
+                if (array_key_exists('startcolor', $pStyles)) {
+                    $this->getStartColor()->applyFromArray($pStyles['startcolor']);
+                }
+                if (array_key_exists('endcolor', $pStyles)) {
+                    $this->getEndColor()->applyFromArray($pStyles['endcolor']);
+                }
+                if (array_key_exists('color', $pStyles)) {
+                    $this->getStartColor()->applyFromArray($pStyles['color']);
+                }
+            }
+        } else {
+            throw new PHPExcel_Exception("Invalid style array passed.");
+        }
+        return $this;
+    }
 
-	/**
-	 * Set Fill Type
-	 *
-	 * @param string $pValue	PHPExcel_Style_Fill fill type
-	 * @return PHPExcel_Style_Fill
-	 */
-	public function setFillType($pValue = PHPExcel_Style_Fill::FILL_NONE) {
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('type' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_fillType = $pValue;
-		}
-		return $this;
-	}
+    /**
+     * Get Fill Type
+     *
+     * @return string
+     */
+    public function getFillType()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getFillType();
+        }
+        return $this->fillType;
+    }
 
-	/**
-	 * Get Rotation
-	 *
-	 * @return double
-	 */
-	public function getRotation() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getRotation();
-		}
-		return $this->_rotation;
-	}
+    /**
+     * Set Fill Type
+     *
+     * @param string $pValue    PHPExcel_Style_Fill fill type
+     * @return PHPExcel_Style_Fill
+     */
+    public function setFillType($pValue = PHPExcel_Style_Fill::FILL_NONE)
+    {
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('type' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->fillType = $pValue;
+        }
+        return $this;
+    }
 
-	/**
-	 * Set Rotation
-	 *
-	 * @param double $pValue
-	 * @return PHPExcel_Style_Fill
-	 */
-	public function setRotation($pValue = 0) {
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('rotation' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_rotation = $pValue;
-		}
-		return $this;
-	}
+    /**
+     * Get Rotation
+     *
+     * @return double
+     */
+    public function getRotation()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getRotation();
+        }
+        return $this->rotation;
+    }
 
-	/**
-	 * Get Start Color
-	 *
-	 * @return PHPExcel_Style_Color
-	 */
-	public function getStartColor() {
-		return $this->_startColor;
-	}
+    /**
+     * Set Rotation
+     *
+     * @param double $pValue
+     * @return PHPExcel_Style_Fill
+     */
+    public function setRotation($pValue = 0)
+    {
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('rotation' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->rotation = $pValue;
+        }
+        return $this;
+    }
 
-	/**
-	 * Set Start Color
-	 *
-	 * @param	PHPExcel_Style_Color $pValue
-	 * @throws	PHPExcel_Exception
-	 * @return PHPExcel_Style_Fill
-	 */
-	public function setStartColor(PHPExcel_Style_Color $pValue = null) {
-		// make sure parameter is a real color and not a supervisor
-		$color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
+    /**
+     * Get Start Color
+     *
+     * @return PHPExcel_Style_Color
+     */
+    public function getStartColor()
+    {
+        return $this->startColor;
+    }
 
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStartColor()->getStyleArray(array('argb' => $color->getARGB()));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_startColor = $color;
-		}
-		return $this;
-	}
+    /**
+     * Set Start Color
+     *
+     * @param    PHPExcel_Style_Color $pValue
+     * @throws    PHPExcel_Exception
+     * @return PHPExcel_Style_Fill
+     */
+    public function setStartColor(PHPExcel_Style_Color $pValue = null)
+    {
+        // make sure parameter is a real color and not a supervisor
+        $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
 
-	/**
-	 * Get End Color
-	 *
-	 * @return PHPExcel_Style_Color
-	 */
-	public function getEndColor() {
-		return $this->_endColor;
-	}
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStartColor()->getStyleArray(array('argb' => $color->getARGB()));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->startColor = $color;
+        }
+        return $this;
+    }
 
-	/**
-	 * Set End Color
-	 *
-	 * @param	PHPExcel_Style_Color $pValue
-	 * @throws	PHPExcel_Exception
-	 * @return PHPExcel_Style_Fill
-	 */
-	public function setEndColor(PHPExcel_Style_Color $pValue = null) {
-		// make sure parameter is a real color and not a supervisor
-		$color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
+    /**
+     * Get End Color
+     *
+     * @return PHPExcel_Style_Color
+     */
+    public function getEndColor()
+    {
+        return $this->endColor;
+    }
 
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getEndColor()->getStyleArray(array('argb' => $color->getARGB()));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_endColor = $color;
-		}
-		return $this;
-	}
+    /**
+     * Set End Color
+     *
+     * @param    PHPExcel_Style_Color $pValue
+     * @throws    PHPExcel_Exception
+     * @return PHPExcel_Style_Fill
+     */
+    public function setEndColor(PHPExcel_Style_Color $pValue = null)
+    {
+        // make sure parameter is a real color and not a supervisor
+        $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
 
-	/**
-	 * Get hash code
-	 *
-	 * @return string	Hash code
-	 */
-	public function getHashCode() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getHashCode();
-		}
-		return md5(
-			  $this->getFillType()
-			. $this->getRotation()
-			. $this->getStartColor()->getHashCode()
-			. $this->getEndColor()->getHashCode()
-			. __CLASS__
-		);
-	}
+        if ($this->isSupervisor) {
+            $styleArray = $this->getEndColor()->getStyleArray(array('argb' => $color->getARGB()));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->endColor = $color;
+        }
+        return $this;
+    }
 
+    /**
+     * Get hash code
+     *
+     * @return string    Hash code
+     */
+    public function getHashCode()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getHashCode();
+        }
+        return md5(
+            $this->getFillType() .
+            $this->getRotation() .
+            $this->getStartColor()->getHashCode() .
+            $this->getEndColor()->getHashCode() .
+            __CLASS__
+        );
+    }
 }
diff --git a/Classes/PHPExcel/Style/Font.php b/Classes/PHPExcel/Style/Font.php
index 53b606387..9566e1dfa 100644
--- a/Classes/PHPExcel/Style/Font.php
+++ b/Classes/PHPExcel/Style/Font.php
@@ -1,6 +1,7 @@
 _name			= NULL;
-			$this->_size			= NULL;
-			$this->_bold			= NULL;
-			$this->_italic			= NULL;
-			$this->_superScript		= NULL;
-			$this->_subScript		= NULL;
-			$this->_underline		= NULL;
-			$this->_strikethrough	= NULL;
-			$this->_color			= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional);
-		} else {
-			$this->_color	= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor);
-		}
-		// bind parent if we are a supervisor
-		if ($isSupervisor) {
-			$this->_color->bindParent($this, '_color');
-		}
-	}
-
-	/**
-	 * Get the shared style component for the currently active cell in currently active sheet.
-	 * Only used for style supervisor
-	 *
-	 * @return PHPExcel_Style_Font
-	 */
-	public function getSharedComponent()
-	{
-		return $this->_parent->getSharedComponent()->getFont();
-	}
-
-	/**
-	 * Build style array from subcomponents
-	 *
-	 * @param array $array
-	 * @return array
-	 */
-	public function getStyleArray($array)
-	{
-		return array('font' => $array);
-	}
-
-	/**
-	 * Apply styles from array
-	 *
-	 * 
-	 * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->applyFromArray(
-	 *		array(
-	 *			'name'		=> 'Arial',
-	 *			'bold'		=> TRUE,
-	 *			'italic'	=> FALSE,
-	 *			'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE,
-	 *			'strike'	=> FALSE,
-	 *			'color'		=> array(
-	 *				'rgb' => '808080'
-	 *			)
-	 *		)
-	 * );
-	 * 
-	 *
-	 * @param	array	$pStyles	Array containing style information
-	 * @throws	PHPExcel_Exception
-	 * @return PHPExcel_Style_Font
-	 */
-	public function applyFromArray($pStyles = null) {
-		if (is_array($pStyles)) {
-			if ($this->_isSupervisor) {
-				$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
-			} else {
-				if (array_key_exists('name', $pStyles)) {
-					$this->setName($pStyles['name']);
-				}
-				if (array_key_exists('bold', $pStyles)) {
-					$this->setBold($pStyles['bold']);
-				}
-				if (array_key_exists('italic', $pStyles)) {
-					$this->setItalic($pStyles['italic']);
-				}
-				if (array_key_exists('superScript', $pStyles)) {
-					$this->setSuperScript($pStyles['superScript']);
-				}
-				if (array_key_exists('subScript', $pStyles)) {
-					$this->setSubScript($pStyles['subScript']);
-				}
-				if (array_key_exists('underline', $pStyles)) {
-					$this->setUnderline($pStyles['underline']);
-				}
-				if (array_key_exists('strike', $pStyles)) {
-					$this->setStrikethrough($pStyles['strike']);
-				}
-				if (array_key_exists('color', $pStyles)) {
-					$this->getColor()->applyFromArray($pStyles['color']);
-				}
-				if (array_key_exists('size', $pStyles)) {
-					$this->setSize($pStyles['size']);
-				}
-			}
-		} else {
-			throw new PHPExcel_Exception("Invalid style array passed.");
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Name
-	 *
-	 * @return string
-	 */
-	public function getName() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getName();
-		}
-		return $this->_name;
-	}
-
-	/**
-	 * Set Name
-	 *
-	 * @param string $pValue
-	 * @return PHPExcel_Style_Font
-	 */
-	public function setName($pValue = 'Calibri') {
-  		if ($pValue == '') {
-			$pValue = 'Calibri';
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('name' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_name = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Size
-	 *
-	 * @return double
-	 */
-	public function getSize() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getSize();
-		}
-		return $this->_size;
-	}
-
-	/**
-	 * Set Size
-	 *
-	 * @param double $pValue
-	 * @return PHPExcel_Style_Font
-	 */
-	public function setSize($pValue = 10) {
-		if ($pValue == '') {
-			$pValue = 10;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('size' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_size = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Bold
-	 *
-	 * @return boolean
-	 */
-	public function getBold() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getBold();
-		}
-		return $this->_bold;
-	}
-
-	/**
-	 * Set Bold
-	 *
-	 * @param boolean $pValue
-	 * @return PHPExcel_Style_Font
-	 */
-	public function setBold($pValue = false) {
-		if ($pValue == '') {
-			$pValue = false;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('bold' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_bold = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Italic
-	 *
-	 * @return boolean
-	 */
-	public function getItalic() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getItalic();
-		}
-		return $this->_italic;
-	}
-
-	/**
-	 * Set Italic
-	 *
-	 * @param boolean $pValue
-	 * @return PHPExcel_Style_Font
-	 */
-	public function setItalic($pValue = false) {
-		if ($pValue == '') {
-			$pValue = false;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('italic' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_italic = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get SuperScript
-	 *
-	 * @return boolean
-	 */
-	public function getSuperScript() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getSuperScript();
-		}
-		return $this->_superScript;
-	}
-
-	/**
-	 * Set SuperScript
-	 *
-	 * @param boolean $pValue
-	 * @return PHPExcel_Style_Font
-	 */
-	public function setSuperScript($pValue = false) {
-		if ($pValue == '') {
-			$pValue = false;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('superScript' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_superScript = $pValue;
-			$this->_subScript = !$pValue;
-		}
-		return $this;
-	}
-
-		/**
-	 * Get SubScript
-	 *
-	 * @return boolean
-	 */
-	public function getSubScript() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getSubScript();
-		}
-		return $this->_subScript;
-	}
-
-	/**
-	 * Set SubScript
-	 *
-	 * @param boolean $pValue
-	 * @return PHPExcel_Style_Font
-	 */
-	public function setSubScript($pValue = false) {
-		if ($pValue == '') {
-			$pValue = false;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('subScript' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_subScript = $pValue;
-			$this->_superScript = !$pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Underline
-	 *
-	 * @return string
-	 */
-	public function getUnderline() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getUnderline();
-		}
-		return $this->_underline;
-	}
-
-	/**
-	 * Set Underline
-	 *
-	 * @param string|boolean $pValue	PHPExcel_Style_Font underline type
-	 *									If a boolean is passed, then TRUE equates to UNDERLINE_SINGLE,
-	 *										false equates to UNDERLINE_NONE
-	 * @return PHPExcel_Style_Font
-	 */
-	public function setUnderline($pValue = self::UNDERLINE_NONE) {
-		if (is_bool($pValue)) {
-			$pValue = ($pValue) ? self::UNDERLINE_SINGLE : self::UNDERLINE_NONE;
-		} elseif ($pValue == '') {
-			$pValue = self::UNDERLINE_NONE;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('underline' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_underline = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Strikethrough
-	 *
-	 * @return boolean
-	 */
-	public function getStrikethrough() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getStrikethrough();
-		}
-		return $this->_strikethrough;
-	}
-
-	/**
-	 * Set Strikethrough
-	 *
-	 * @param boolean $pValue
-	 * @return PHPExcel_Style_Font
-	 */
-	public function setStrikethrough($pValue = false) {
-		if ($pValue == '') {
-			$pValue = false;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('strike' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_strikethrough = $pValue;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Color
-	 *
-	 * @return PHPExcel_Style_Color
-	 */
-	public function getColor() {
-		return $this->_color;
-	}
-
-	/**
-	 * Set Color
-	 *
-	 * @param	PHPExcel_Style_Color $pValue
-	 * @throws	PHPExcel_Exception
-	 * @return PHPExcel_Style_Font
-	 */
-	public function setColor(PHPExcel_Style_Color $pValue = null) {
-		// make sure parameter is a real color and not a supervisor
-		$color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
-
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB()));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_color = $color;
-		}
-		return $this;
-	}
-
-	/**
-	 * Get hash code
-	 *
-	 * @return string	Hash code
-	 */
-	public function getHashCode() {
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getHashCode();
-		}
-		return md5(
-			  $this->_name
-			. $this->_size
-			. ($this->_bold ? 't' : 'f')
-			. ($this->_italic ? 't' : 'f')
-			. ($this->_superScript ? 't' : 'f')
-			. ($this->_subScript ? 't' : 'f')
-			. $this->_underline
-			. ($this->_strikethrough ? 't' : 'f')
-			. $this->_color->getHashCode()
-			. __CLASS__
-		);
-	}
-
+    /* Underline types */
+    const UNDERLINE_NONE             = 'none';
+    const UNDERLINE_DOUBLE           = 'double';
+    const UNDERLINE_DOUBLEACCOUNTING = 'doubleAccounting';
+    const UNDERLINE_SINGLE           = 'single';
+    const UNDERLINE_SINGLEACCOUNTING = 'singleAccounting';
+
+    /**
+     * Font Name
+     *
+     * @var string
+     */
+    protected $name = 'Calibri';
+
+    /**
+     * Font Size
+     *
+     * @var float
+     */
+    protected $size = 11;
+
+    /**
+     * Bold
+     *
+     * @var boolean
+     */
+    protected $bold = false;
+
+    /**
+     * Italic
+     *
+     * @var boolean
+     */
+    protected $italic = false;
+
+    /**
+     * Superscript
+     *
+     * @var boolean
+     */
+    protected $superScript = false;
+
+    /**
+     * Subscript
+     *
+     * @var boolean
+     */
+    protected $subScript = false;
+
+    /**
+     * Underline
+     *
+     * @var string
+     */
+    protected $underline = self::UNDERLINE_NONE;
+
+    /**
+     * Strikethrough
+     *
+     * @var boolean
+     */
+    protected $strikethrough = false;
+
+    /**
+     * Foreground color
+     *
+     * @var PHPExcel_Style_Color
+     */
+    protected $color;
+
+    /**
+     * Create a new PHPExcel_Style_Font
+     *
+     * @param    boolean    $isSupervisor    Flag indicating if this is a supervisor or not
+     *                                    Leave this value at default unless you understand exactly what
+     *                                        its ramifications are
+     * @param    boolean    $isConditional    Flag indicating if this is a conditional style or not
+     *                                    Leave this value at default unless you understand exactly what
+     *                                        its ramifications are
+     */
+    public function __construct($isSupervisor = false, $isConditional = false)
+    {
+        // Supervisor?
+        parent::__construct($isSupervisor);
+
+        // Initialise values
+        if ($isConditional) {
+            $this->name = null;
+            $this->size = null;
+            $this->bold = null;
+            $this->italic = null;
+            $this->superScript = null;
+            $this->subScript = null;
+            $this->underline = null;
+            $this->strikethrough = null;
+            $this->color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional);
+        } else {
+            $this->color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor);
+        }
+        // bind parent if we are a supervisor
+        if ($isSupervisor) {
+            $this->color->bindParent($this, 'color');
+        }
+    }
+
+    /**
+     * Get the shared style component for the currently active cell in currently active sheet.
+     * Only used for style supervisor
+     *
+     * @return PHPExcel_Style_Font
+     */
+    public function getSharedComponent()
+    {
+        return $this->parent->getSharedComponent()->getFont();
+    }
+
+    /**
+     * Build style array from subcomponents
+     *
+     * @param array $array
+     * @return array
+     */
+    public function getStyleArray($array)
+    {
+        return array('font' => $array);
+    }
+
+    /**
+     * Apply styles from array
+     *
+     * 
+     * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->applyFromArray(
+     *        array(
+     *            'name'        => 'Arial',
+     *            'bold'        => TRUE,
+     *            'italic'    => FALSE,
+     *            'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE,
+     *            'strike'    => FALSE,
+     *            'color'        => array(
+     *                'rgb' => '808080'
+     *            )
+     *        )
+     * );
+     * 
+     *
+     * @param    array    $pStyles    Array containing style information
+     * @throws    PHPExcel_Exception
+     * @return PHPExcel_Style_Font
+     */
+    public function applyFromArray($pStyles = null)
+    {
+        if (is_array($pStyles)) {
+            if ($this->isSupervisor) {
+                $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+            } else {
+                if (array_key_exists('name', $pStyles)) {
+                    $this->setName($pStyles['name']);
+                }
+                if (array_key_exists('bold', $pStyles)) {
+                    $this->setBold($pStyles['bold']);
+                }
+                if (array_key_exists('italic', $pStyles)) {
+                    $this->setItalic($pStyles['italic']);
+                }
+                if (array_key_exists('superScript', $pStyles)) {
+                    $this->setSuperScript($pStyles['superScript']);
+                }
+                if (array_key_exists('subScript', $pStyles)) {
+                    $this->setSubScript($pStyles['subScript']);
+                }
+                if (array_key_exists('underline', $pStyles)) {
+                    $this->setUnderline($pStyles['underline']);
+                }
+                if (array_key_exists('strike', $pStyles)) {
+                    $this->setStrikethrough($pStyles['strike']);
+                }
+                if (array_key_exists('color', $pStyles)) {
+                    $this->getColor()->applyFromArray($pStyles['color']);
+                }
+                if (array_key_exists('size', $pStyles)) {
+                    $this->setSize($pStyles['size']);
+                }
+            }
+        } else {
+            throw new PHPExcel_Exception("Invalid style array passed.");
+        }
+        return $this;
+    }
+
+    /**
+     * Get Name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getName();
+        }
+        return $this->name;
+    }
+
+    /**
+     * Set Name
+     *
+     * @param string $pValue
+     * @return PHPExcel_Style_Font
+     */
+    public function setName($pValue = 'Calibri')
+    {
+        if ($pValue == '') {
+            $pValue = 'Calibri';
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('name' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->name = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get Size
+     *
+     * @return double
+     */
+    public function getSize()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getSize();
+        }
+        return $this->size;
+    }
+
+    /**
+     * Set Size
+     *
+     * @param double $pValue
+     * @return PHPExcel_Style_Font
+     */
+    public function setSize($pValue = 10)
+    {
+        if ($pValue == '') {
+            $pValue = 10;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('size' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->size = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get Bold
+     *
+     * @return boolean
+     */
+    public function getBold()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getBold();
+        }
+        return $this->bold;
+    }
+
+    /**
+     * Set Bold
+     *
+     * @param boolean $pValue
+     * @return PHPExcel_Style_Font
+     */
+    public function setBold($pValue = false)
+    {
+        if ($pValue == '') {
+            $pValue = false;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('bold' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->bold = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get Italic
+     *
+     * @return boolean
+     */
+    public function getItalic()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getItalic();
+        }
+        return $this->italic;
+    }
+
+    /**
+     * Set Italic
+     *
+     * @param boolean $pValue
+     * @return PHPExcel_Style_Font
+     */
+    public function setItalic($pValue = false)
+    {
+        if ($pValue == '') {
+            $pValue = false;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('italic' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->italic = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get SuperScript
+     *
+     * @return boolean
+     */
+    public function getSuperScript()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getSuperScript();
+        }
+        return $this->superScript;
+    }
+
+    /**
+     * Set SuperScript
+     *
+     * @param boolean $pValue
+     * @return PHPExcel_Style_Font
+     */
+    public function setSuperScript($pValue = false)
+    {
+        if ($pValue == '') {
+            $pValue = false;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('superScript' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->superScript = $pValue;
+            $this->subScript = !$pValue;
+        }
+        return $this;
+    }
+
+        /**
+     * Get SubScript
+     *
+     * @return boolean
+     */
+    public function getSubScript()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getSubScript();
+        }
+        return $this->subScript;
+    }
+
+    /**
+     * Set SubScript
+     *
+     * @param boolean $pValue
+     * @return PHPExcel_Style_Font
+     */
+    public function setSubScript($pValue = false)
+    {
+        if ($pValue == '') {
+            $pValue = false;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('subScript' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->subScript = $pValue;
+            $this->superScript = !$pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get Underline
+     *
+     * @return string
+     */
+    public function getUnderline()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getUnderline();
+        }
+        return $this->underline;
+    }
+
+    /**
+     * Set Underline
+     *
+     * @param string|boolean $pValue    PHPExcel_Style_Font underline type
+     *                                    If a boolean is passed, then TRUE equates to UNDERLINE_SINGLE,
+     *                                        false equates to UNDERLINE_NONE
+     * @return PHPExcel_Style_Font
+     */
+    public function setUnderline($pValue = self::UNDERLINE_NONE)
+    {
+        if (is_bool($pValue)) {
+            $pValue = ($pValue) ? self::UNDERLINE_SINGLE : self::UNDERLINE_NONE;
+        } elseif ($pValue == '') {
+            $pValue = self::UNDERLINE_NONE;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('underline' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->underline = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get Strikethrough
+     *
+     * @return boolean
+     */
+    public function getStrikethrough()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getStrikethrough();
+        }
+        return $this->strikethrough;
+    }
+
+    /**
+     * Set Strikethrough
+     *
+     * @param boolean $pValue
+     * @return PHPExcel_Style_Font
+     */
+    public function setStrikethrough($pValue = false)
+    {
+        if ($pValue == '') {
+            $pValue = false;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('strike' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->strikethrough = $pValue;
+        }
+        return $this;
+    }
+
+    /**
+     * Get Color
+     *
+     * @return PHPExcel_Style_Color
+     */
+    public function getColor()
+    {
+        return $this->color;
+    }
+
+    /**
+     * Set Color
+     *
+     * @param    PHPExcel_Style_Color $pValue
+     * @throws    PHPExcel_Exception
+     * @return PHPExcel_Style_Font
+     */
+    public function setColor(PHPExcel_Style_Color $pValue = null)
+    {
+        // make sure parameter is a real color and not a supervisor
+        $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
+
+        if ($this->isSupervisor) {
+            $styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB()));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->color = $color;
+        }
+        return $this;
+    }
+
+    /**
+     * Get hash code
+     *
+     * @return string    Hash code
+     */
+    public function getHashCode()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getHashCode();
+        }
+        return md5(
+            $this->name .
+            $this->size .
+            ($this->bold ? 't' : 'f') .
+            ($this->italic ? 't' : 'f') .
+            ($this->superScript ? 't' : 'f') .
+            ($this->subScript ? 't' : 'f') .
+            $this->underline .
+            ($this->strikethrough ? 't' : 'f') .
+            $this->color->getHashCode() .
+            __CLASS__
+        );
+    }
 }
diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php
index cff58acb4..8b7f300dc 100644
--- a/Classes/PHPExcel/Style/NumberFormat.php
+++ b/Classes/PHPExcel/Style/NumberFormat.php
@@ -1,6 +1,7 @@
 _formatCode = NULL;
-			$this->_builtInFormatCode = FALSE;
-		}
-	}
-
-	/**
-	 * Get the shared style component for the currently active cell in currently active sheet.
-	 * Only used for style supervisor
-	 *
-	 * @return PHPExcel_Style_NumberFormat
-	 */
-	public function getSharedComponent()
-	{
-		return $this->_parent->getSharedComponent()->getNumberFormat();
-	}
-
-	/**
-	 * Build style array from subcomponents
-	 *
-	 * @param array $array
-	 * @return array
-	 */
-	public function getStyleArray($array)
-	{
-		return array('numberformat' => $array);
-	}
-
-	/**
-	 * Apply styles from array
-	 *
-	 * 
-	 * $objPHPExcel->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray(
-	 *		array(
-	 *			'code' => PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE
-	 *		)
-	 * );
-	 * 
-	 *
-	 * @param	array	$pStyles	Array containing style information
-	 * @throws	PHPExcel_Exception
-	 * @return PHPExcel_Style_NumberFormat
-	 */
-	public function applyFromArray($pStyles = null)
-	{
-		if (is_array($pStyles)) {
-			if ($this->_isSupervisor) {
-				$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
-			} else {
-				if (array_key_exists('code', $pStyles)) {
-					$this->setFormatCode($pStyles['code']);
-				}
-			}
-		} else {
-			throw new PHPExcel_Exception("Invalid style array passed.");
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Format Code
-	 *
-	 * @return string
-	 */
-	public function getFormatCode()
-	{
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getFormatCode();
-		}
-		if ($this->_builtInFormatCode !== false)
-		{
-			return self::builtInFormatCode($this->_builtInFormatCode);
-		}
-		return $this->_formatCode;
-	}
-
-	/**
-	 * Set Format Code
-	 *
-	 * @param string $pValue
-	 * @return PHPExcel_Style_NumberFormat
-	 */
-	public function setFormatCode($pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL)
-	{
-		if ($pValue == '') {
-			$pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
-		}
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('code' => $pValue));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_formatCode = $pValue;
-			$this->_builtInFormatCode = self::builtInFormatCodeIndex($pValue);
-		}
-		return $this;
-	}
-
-	/**
-	 * Get Built-In Format Code
-	 *
-	 * @return int
-	 */
-	public function getBuiltInFormatCode()
-	{
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getBuiltInFormatCode();
-		}
-		return $this->_builtInFormatCode;
-	}
-
-	/**
-	 * Set Built-In Format Code
-	 *
-	 * @param int $pValue
-	 * @return PHPExcel_Style_NumberFormat
-	 */
-	public function setBuiltInFormatCode($pValue = 0)
-	{
-
-		if ($this->_isSupervisor) {
-			$styleArray = $this->getStyleArray(array('code' => self::builtInFormatCode($pValue)));
-			$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
-		} else {
-			$this->_builtInFormatCode = $pValue;
-			$this->_formatCode = self::builtInFormatCode($pValue);
-		}
-		return $this;
-	}
-
-	/**
-	 * Fill built-in format codes
-	 */
-	private static function fillBuiltInFormatCodes()
-	{
-		// Built-in format codes
-		if (is_null(self::$_builtInFormats)) {
-			self::$_builtInFormats = array();
-
-			// General
-			self::$_builtInFormats[0] = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
-			self::$_builtInFormats[1] = '0';
-			self::$_builtInFormats[2] = '0.00';
-			self::$_builtInFormats[3] = '#,##0';
-			self::$_builtInFormats[4] = '#,##0.00';
-
-			self::$_builtInFormats[9] = '0%';
-			self::$_builtInFormats[10] = '0.00%';
-			self::$_builtInFormats[11] = '0.00E+00';
-			self::$_builtInFormats[12] = '# ?/?';
-			self::$_builtInFormats[13] = '# ??/??';
-			self::$_builtInFormats[14] = 'mm-dd-yy';
-			self::$_builtInFormats[15] = 'd-mmm-yy';
-			self::$_builtInFormats[16] = 'd-mmm';
-			self::$_builtInFormats[17] = 'mmm-yy';
-			self::$_builtInFormats[18] = 'h:mm AM/PM';
-			self::$_builtInFormats[19] = 'h:mm:ss AM/PM';
-			self::$_builtInFormats[20] = 'h:mm';
-			self::$_builtInFormats[21] = 'h:mm:ss';
-			self::$_builtInFormats[22] = 'm/d/yy h:mm';
-
-			self::$_builtInFormats[37] = '#,##0 ;(#,##0)';
-			self::$_builtInFormats[38] = '#,##0 ;[Red](#,##0)';
-			self::$_builtInFormats[39] = '#,##0.00;(#,##0.00)';
-			self::$_builtInFormats[40] = '#,##0.00;[Red](#,##0.00)';
-
-			self::$_builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)';
-			self::$_builtInFormats[45] = 'mm:ss';
-			self::$_builtInFormats[46] = '[h]:mm:ss';
-			self::$_builtInFormats[47] = 'mmss.0';
-			self::$_builtInFormats[48] = '##0.0E+0';
-			self::$_builtInFormats[49] = '@';
-
-			// CHT
-			self::$_builtInFormats[27] = '[$-404]e/m/d';
-			self::$_builtInFormats[30] = 'm/d/yy';
-			self::$_builtInFormats[36] = '[$-404]e/m/d';
-			self::$_builtInFormats[50] = '[$-404]e/m/d';
-			self::$_builtInFormats[57] = '[$-404]e/m/d';
-
-			// THA
-			self::$_builtInFormats[59] = 't0';
-			self::$_builtInFormats[60] = 't0.00';
-			self::$_builtInFormats[61] = 't#,##0';
-			self::$_builtInFormats[62] = 't#,##0.00';
-			self::$_builtInFormats[67] = 't0%';
-			self::$_builtInFormats[68] = 't0.00%';
-			self::$_builtInFormats[69] = 't# ?/?';
-			self::$_builtInFormats[70] = 't# ??/??';
-
-			// Flip array (for faster lookups)
-			self::$_flippedBuiltInFormats = array_flip(self::$_builtInFormats);
-		}
-	}
-
-	/**
-	 * Get built-in format code
-	 *
-	 * @param	int		$pIndex
-	 * @return	string
-	 */
-	public static function builtInFormatCode($pIndex)
-	{
-		// Clean parameter
-		$pIndex = intval($pIndex);
-
-		// Ensure built-in format codes are available
-		self::fillBuiltInFormatCodes();
-
-		// Lookup format code
-		if (isset(self::$_builtInFormats[$pIndex])) {
-			return self::$_builtInFormats[$pIndex];
-		}
-
-		return '';
-	}
-
-	/**
-	 * Get built-in format code index
-	 *
-	 * @param	string		$formatCode
-	 * @return	int|boolean
-	 */
-	public static function builtInFormatCodeIndex($formatCode)
-	{
-		// Ensure built-in format codes are available
-		self::fillBuiltInFormatCodes();
-
-		// Lookup format code
-		if (isset(self::$_flippedBuiltInFormats[$formatCode])) {
-			return self::$_flippedBuiltInFormats[$formatCode];
-		}
-
-		return false;
-	}
-
-	/**
-	 * Get hash code
-	 *
-	 * @return string	Hash code
-	 */
-	public function getHashCode()
-	{
-		if ($this->_isSupervisor) {
-			return $this->getSharedComponent()->getHashCode();
-		}
-		return md5(
-			  $this->_formatCode
-			. $this->_builtInFormatCode
-			. __CLASS__
-		);
-	}
-
-	/**
-	 * Search/replace values to convert Excel date/time format masks to PHP format masks
-	 *
-	 * @var array
-	 */
-	private static $_dateFormatReplacements = array(
-			// first remove escapes related to non-format characters
-			'\\'	=> '',
-			//	12-hour suffix
-			'am/pm'	=> 'A',
-			//	4-digit year
-			'e'	=> 'Y',
-			'yyyy'	=> 'Y',
-			//	2-digit year
-			'yy'	=> 'y',
-			//	first letter of month - no php equivalent
-			'mmmmm'	=> 'M',
-			//	full month name
-			'mmmm'	=> 'F',
-			//	short month name
-			'mmm'	=> 'M',
-			//	mm is minutes if time, but can also be month w/leading zero
-			//	so we try to identify times be the inclusion of a : separator in the mask
-			//	It isn't perfect, but the best way I know how
-			':mm'	=> ':i',
-			'mm:'	=> 'i:',
-			//	month leading zero
-			'mm'	=> 'm',
-			//	month no leading zero
-			'm'		=> 'n',
-			//	full day of week name
-			'dddd'	=> 'l',
-			//	short day of week name
-			'ddd'	=> 'D',
-			//	days leading zero
-			'dd'	=> 'd',
-			//	days no leading zero
-			'd'		=> 'j',
-			//	seconds
-			'ss'	=> 's',
-			//	fractional seconds - no php equivalent
-			'.s'	=> ''
-		);
-	/**
-	 * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock)
-	 *
-	 * @var array
-	 */
-	private static $_dateFormatReplacements24 = array(
-			'hh'	=> 'H',
-			'h'		=> 'G'
-		);
-	/**
-	 * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock)
-	 *
-	 * @var array
-	 */
-	private static $_dateFormatReplacements12 = array(
-			'hh'	=> 'h',
-			'h'		=> 'g'
-		);
-
-	private static function _formatAsDate(&$value, &$format)
-	{
-		// dvc: convert Excel formats to PHP date formats
-
-		// strip off first part containing e.g. [$-F800] or [$USD-409]
-		// general syntax: [$-]
-		// language info is in hexadecimal
-		$format = preg_replace('/^(\[\$[A-Z]*-[0-9A-F]*\])/i', '', $format);
-
-		// OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case
-		$format = strtolower($format);
-
-		$format = strtr($format,self::$_dateFormatReplacements);
-		if (!strpos($format,'A')) {	// 24-hour time format
-			$format = strtr($format,self::$_dateFormatReplacements24);
-		} else {					// 12-hour time format
-			$format = strtr($format,self::$_dateFormatReplacements12);
-		}
-
-		$dateObj = PHPExcel_Shared_Date::ExcelToPHPObject($value);
-		$value = $dateObj->format($format);
-	}
-
-	private static function _formatAsPercentage(&$value, &$format)
-	{
-		if ($format === self::FORMAT_PERCENTAGE) {
-			$value = round( (100 * $value), 0) . '%';
-		} else {
-			if (preg_match('/\.[#0]+/i', $format, $m)) {
-				$s = substr($m[0], 0, 1) . (strlen($m[0]) - 1);
-				$format = str_replace($m[0], $s, $format);
-			}
-			if (preg_match('/^[#0]+/', $format, $m)) {
-				$format = str_replace($m[0], strlen($m[0]), $format);
-			}
-			$format = '%' . str_replace('%', 'f%%', $format);
-
-			$value = sprintf($format, 100 * $value);
-		}
-	}
-
-	private static function _formatAsFraction(&$value, &$format)
-	{
-		$sign = ($value < 0) ? '-' : '';
-
-		$integerPart = floor(abs($value));
-		$decimalPart = trim(fmod(abs($value),1),'0.');
-		$decimalLength = strlen($decimalPart);
-		$decimalDivisor = pow(10,$decimalLength);
-
-		$GCD = PHPExcel_Calculation_MathTrig::GCD($decimalPart,$decimalDivisor);
-
-		$adjustedDecimalPart = $decimalPart/$GCD;
-		$adjustedDecimalDivisor = $decimalDivisor/$GCD;
-
-		if ((strpos($format,'0') !== false) || (strpos($format,'#') !== false) || (substr($format,0,3) == '? ?')) {
-			if ($integerPart == 0) {
-				$integerPart = '';
-			}
-			$value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor";
-		} else {
-			$adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor;
-			$value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor";
-		}
-	}
-
-	private static function _complexNumberFormatMask($number, $mask, $level = 0) {
+    /* Pre-defined formats */
+    const FORMAT_GENERAL                 = 'General';
+
+    const FORMAT_TEXT                    = '@';
+
+    const FORMAT_NUMBER                  = '0';
+    const FORMAT_NUMBER_00               = '0.00';
+    const FORMAT_NUMBER_COMMA_SEPARATED1 = '#,##0.00';
+    const FORMAT_NUMBER_COMMA_SEPARATED2 = '#,##0.00_-';
+
+    const FORMAT_PERCENTAGE              = '0%';
+    const FORMAT_PERCENTAGE_00           = '0.00%';
+
+    const FORMAT_DATE_YYYYMMDD2          = 'yyyy-mm-dd';
+    const FORMAT_DATE_YYYYMMDD           = 'yy-mm-dd';
+    const FORMAT_DATE_DDMMYYYY           = 'dd/mm/yy';
+    const FORMAT_DATE_DMYSLASH           = 'd/m/y';
+    const FORMAT_DATE_DMYMINUS           = 'd-m-y';
+    const FORMAT_DATE_DMMINUS            = 'd-m';
+    const FORMAT_DATE_MYMINUS            = 'm-y';
+    const FORMAT_DATE_XLSX14             = 'mm-dd-yy';
+    const FORMAT_DATE_XLSX15             = 'd-mmm-yy';
+    const FORMAT_DATE_XLSX16             = 'd-mmm';
+    const FORMAT_DATE_XLSX17             = 'mmm-yy';
+    const FORMAT_DATE_XLSX22             = 'm/d/yy h:mm';
+    const FORMAT_DATE_DATETIME           = 'd/m/y h:mm';
+    const FORMAT_DATE_TIME1              = 'h:mm AM/PM';
+    const FORMAT_DATE_TIME2              = 'h:mm:ss AM/PM';
+    const FORMAT_DATE_TIME3              = 'h:mm';
+    const FORMAT_DATE_TIME4              = 'h:mm:ss';
+    const FORMAT_DATE_TIME5              = 'mm:ss';
+    const FORMAT_DATE_TIME6              = 'h:mm:ss';
+    const FORMAT_DATE_TIME7              = 'i:s.S';
+    const FORMAT_DATE_TIME8              = 'h:mm:ss;@';
+    const FORMAT_DATE_YYYYMMDDSLASH      = 'yy/mm/dd;@';
+
+    const FORMAT_CURRENCY_USD_SIMPLE     = '"$"#,##0.00_-';
+    const FORMAT_CURRENCY_USD            = '$#,##0_-';
+    const FORMAT_CURRENCY_EUR_SIMPLE     = '[$EUR ]#,##0.00_-';
+
+    /**
+     * Excel built-in number formats
+     *
+     * @var array
+     */
+    protected static $builtInFormats;
+
+    /**
+     * Excel built-in number formats (flipped, for faster lookups)
+     *
+     * @var array
+     */
+    protected static $flippedBuiltInFormats;
+
+    /**
+     * Format Code
+     *
+     * @var string
+     */
+    protected $formatCode = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
+
+    /**
+     * Built-in format Code
+     *
+     * @var string
+     */
+    protected $builtInFormatCode    = 0;
+
+    /**
+     * Create a new PHPExcel_Style_NumberFormat
+     *
+     * @param    boolean    $isSupervisor    Flag indicating if this is a supervisor or not
+     *                                    Leave this value at default unless you understand exactly what
+     *                                        its ramifications are
+     * @param    boolean    $isConditional    Flag indicating if this is a conditional style or not
+     *                                    Leave this value at default unless you understand exactly what
+     *                                        its ramifications are
+     */
+    public function __construct($isSupervisor = false, $isConditional = false)
+    {
+        // Supervisor?
+        parent::__construct($isSupervisor);
+
+        if ($isConditional) {
+            $this->formatCode = null;
+            $this->builtInFormatCode = false;
+        }
+    }
+
+    /**
+     * Get the shared style component for the currently active cell in currently active sheet.
+     * Only used for style supervisor
+     *
+     * @return PHPExcel_Style_NumberFormat
+     */
+    public function getSharedComponent()
+    {
+        return $this->parent->getSharedComponent()->getNumberFormat();
+    }
+
+    /**
+     * Build style array from subcomponents
+     *
+     * @param array $array
+     * @return array
+     */
+    public function getStyleArray($array)
+    {
+        return array('numberformat' => $array);
+    }
+
+    /**
+     * Apply styles from array
+     *
+     * 
+     * $objPHPExcel->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray(
+     *        array(
+     *            'code' => PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE
+     *        )
+     * );
+     * 
+     *
+     * @param    array    $pStyles    Array containing style information
+     * @throws    PHPExcel_Exception
+     * @return PHPExcel_Style_NumberFormat
+     */
+    public function applyFromArray($pStyles = null)
+    {
+        if (is_array($pStyles)) {
+            if ($this->isSupervisor) {
+                $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
+            } else {
+                if (array_key_exists('code', $pStyles)) {
+                    $this->setFormatCode($pStyles['code']);
+                }
+            }
+        } else {
+            throw new PHPExcel_Exception("Invalid style array passed.");
+        }
+        return $this;
+    }
+
+    /**
+     * Get Format Code
+     *
+     * @return string
+     */
+    public function getFormatCode()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getFormatCode();
+        }
+        if ($this->builtInFormatCode !== false) {
+            return self::builtInFormatCode($this->builtInFormatCode);
+        }
+        return $this->formatCode;
+    }
+
+    /**
+     * Set Format Code
+     *
+     * @param string $pValue
+     * @return PHPExcel_Style_NumberFormat
+     */
+    public function setFormatCode($pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL)
+    {
+        if ($pValue == '') {
+            $pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
+        }
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('code' => $pValue));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->formatCode = $pValue;
+            $this->builtInFormatCode = self::builtInFormatCodeIndex($pValue);
+        }
+        return $this;
+    }
+
+    /**
+     * Get Built-In Format Code
+     *
+     * @return int
+     */
+    public function getBuiltInFormatCode()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getBuiltInFormatCode();
+        }
+        return $this->builtInFormatCode;
+    }
+
+    /**
+     * Set Built-In Format Code
+     *
+     * @param int $pValue
+     * @return PHPExcel_Style_NumberFormat
+     */
+    public function setBuiltInFormatCode($pValue = 0)
+    {
+
+        if ($this->isSupervisor) {
+            $styleArray = $this->getStyleArray(array('code' => self::builtInFormatCode($pValue)));
+            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
+        } else {
+            $this->builtInFormatCode = $pValue;
+            $this->formatCode = self::builtInFormatCode($pValue);
+        }
+        return $this;
+    }
+
+    /**
+     * Fill built-in format codes
+     */
+    private static function fillBuiltInFormatCodes()
+    {
+        // Built-in format codes
+        if (is_null(self::$builtInFormats)) {
+            self::$builtInFormats = array();
+
+            // General
+            self::$builtInFormats[0] = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
+            self::$builtInFormats[1] = '0';
+            self::$builtInFormats[2] = '0.00';
+            self::$builtInFormats[3] = '#,##0';
+            self::$builtInFormats[4] = '#,##0.00';
+
+            self::$builtInFormats[9] = '0%';
+            self::$builtInFormats[10] = '0.00%';
+            self::$builtInFormats[11] = '0.00E+00';
+            self::$builtInFormats[12] = '# ?/?';
+            self::$builtInFormats[13] = '# ??/??';
+            self::$builtInFormats[14] = 'mm-dd-yy';
+            self::$builtInFormats[15] = 'd-mmm-yy';
+            self::$builtInFormats[16] = 'd-mmm';
+            self::$builtInFormats[17] = 'mmm-yy';
+            self::$builtInFormats[18] = 'h:mm AM/PM';
+            self::$builtInFormats[19] = 'h:mm:ss AM/PM';
+            self::$builtInFormats[20] = 'h:mm';
+            self::$builtInFormats[21] = 'h:mm:ss';
+            self::$builtInFormats[22] = 'm/d/yy h:mm';
+
+            self::$builtInFormats[37] = '#,##0 ;(#,##0)';
+            self::$builtInFormats[38] = '#,##0 ;[Red](#,##0)';
+            self::$builtInFormats[39] = '#,##0.00;(#,##0.00)';
+            self::$builtInFormats[40] = '#,##0.00;[Red](#,##0.00)';
+
+            self::$builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)';
+            self::$builtInFormats[45] = 'mm:ss';
+            self::$builtInFormats[46] = '[h]:mm:ss';
+            self::$builtInFormats[47] = 'mmss.0';
+            self::$builtInFormats[48] = '##0.0E+0';
+            self::$builtInFormats[49] = '@';
+
+            // CHT
+            self::$builtInFormats[27] = '[$-404]e/m/d';
+            self::$builtInFormats[30] = 'm/d/yy';
+            self::$builtInFormats[36] = '[$-404]e/m/d';
+            self::$builtInFormats[50] = '[$-404]e/m/d';
+            self::$builtInFormats[57] = '[$-404]e/m/d';
+
+            // THA
+            self::$builtInFormats[59] = 't0';
+            self::$builtInFormats[60] = 't0.00';
+            self::$builtInFormats[61] = 't#,##0';
+            self::$builtInFormats[62] = 't#,##0.00';
+            self::$builtInFormats[67] = 't0%';
+            self::$builtInFormats[68] = 't0.00%';
+            self::$builtInFormats[69] = 't# ?/?';
+            self::$builtInFormats[70] = 't# ??/??';
+
+            // Flip array (for faster lookups)
+            self::$flippedBuiltInFormats = array_flip(self::$builtInFormats);
+        }
+    }
+
+    /**
+     * Get built-in format code
+     *
+     * @param    int        $pIndex
+     * @return    string
+     */
+    public static function builtInFormatCode($pIndex)
+    {
+        // Clean parameter
+        $pIndex = intval($pIndex);
+
+        // Ensure built-in format codes are available
+        self::fillBuiltInFormatCodes();
+
+        // Lookup format code
+        if (isset(self::$builtInFormats[$pIndex])) {
+            return self::$builtInFormats[$pIndex];
+        }
+
+        return '';
+    }
+
+    /**
+     * Get built-in format code index
+     *
+     * @param    string        $formatCode
+     * @return    int|boolean
+     */
+    public static function builtInFormatCodeIndex($formatCode)
+    {
+        // Ensure built-in format codes are available
+        self::fillBuiltInFormatCodes();
+
+        // Lookup format code
+        if (isset(self::$flippedBuiltInFormats[$formatCode])) {
+            return self::$flippedBuiltInFormats[$formatCode];
+        }
+
+        return false;
+    }
+
+    /**
+     * Get hash code
+     *
+     * @return string    Hash code
+     */
+    public function getHashCode()
+    {
+        if ($this->isSupervisor) {
+            return $this->getSharedComponent()->getHashCode();
+        }
+        return md5(
+            $this->formatCode .
+            $this->builtInFormatCode .
+            __CLASS__
+        );
+    }
+
+    /**
+     * Search/replace values to convert Excel date/time format masks to PHP format masks
+     *
+     * @var array
+     */
+    private static $dateFormatReplacements = array(
+            // first remove escapes related to non-format characters
+            '\\'    => '',
+            //    12-hour suffix
+            'am/pm' => 'A',
+            //    4-digit year
+            'e'     => 'Y',
+            'yyyy'  => 'Y',
+            //    2-digit year
+            'yy'    => 'y',
+            //    first letter of month - no php equivalent
+            'mmmmm' => 'M',
+            //    full month name
+            'mmmm'  => 'F',
+            //    short month name
+            'mmm'   => 'M',
+            //    mm is minutes if time, but can also be month w/leading zero
+            //    so we try to identify times be the inclusion of a : separator in the mask
+            //    It isn't perfect, but the best way I know how
+            ':mm'   => ':i',
+            'mm:'   => 'i:',
+            //    month leading zero
+            'mm'    => 'm',
+            //    month no leading zero
+            'm'     => 'n',
+            //    full day of week name
+            'dddd'  => 'l',
+            //    short day of week name
+            'ddd'   => 'D',
+            //    days leading zero
+            'dd'    => 'd',
+            //    days no leading zero
+            'd'     => 'j',
+            //    seconds
+            'ss'    => 's',
+            //    fractional seconds - no php equivalent
+            '.s'    => ''
+        );
+    /**
+     * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock)
+     *
+     * @var array
+     */
+    private static $dateFormatReplacements24 = array(
+            'hh' => 'H',
+            'h'  => 'G'
+        );
+    /**
+     * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock)
+     *
+     * @var array
+     */
+    private static $dateFormatReplacements12 = array(
+            'hh' => 'h',
+            'h'  => 'g'
+        );
+
+    private static function formatAsDate(&$value, &$format)
+    {
+        // dvc: convert Excel formats to PHP date formats
+
+        // strip off first part containing e.g. [$-F800] or [$USD-409]
+        // general syntax: [$-]
+        // language info is in hexadecimal
+        $format = preg_replace('/^(\[\$[A-Z]*-[0-9A-F]*\])/i', '', $format);
+
+        // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case
+        $format = strtolower($format);
+
+        $format = strtr($format, self::$dateFormatReplacements);
+        if (!strpos($format, 'A')) {
+            // 24-hour time format
+            $format = strtr($format, self::$dateFormatReplacements24);
+        } else {
+            // 12-hour time format
+            $format = strtr($format, self::$dateFormatReplacements12);
+        }
+
+        $dateObj = PHPExcel_Shared_Date::ExcelToPHPObject($value);
+        $value = $dateObj->format($format);
+    }
+
+    private static function formatAsPercentage(&$value, &$format)
+    {
+        if ($format === self::FORMAT_PERCENTAGE) {
+            $value = round((100 * $value), 0) . '%';
+        } else {
+            if (preg_match('/\.[#0]+/i', $format, $m)) {
+                $s = substr($m[0], 0, 1) . (strlen($m[0]) - 1);
+                $format = str_replace($m[0], $s, $format);
+            }
+            if (preg_match('/^[#0]+/', $format, $m)) {
+                $format = str_replace($m[0], strlen($m[0]), $format);
+            }
+            $format = '%' . str_replace('%', 'f%%', $format);
+
+            $value = sprintf($format, 100 * $value);
+        }
+    }
+
+    private static function formatAsFraction(&$value, &$format)
+    {
+        $sign = ($value < 0) ? '-' : '';
+
+        $integerPart = floor(abs($value));
+        $decimalPart = trim(fmod(abs($value), 1), '0.');
+        $decimalLength = strlen($decimalPart);
+        $decimalDivisor = pow(10, $decimalLength);
+
+        $GCD = PHPExcel_Calculation_MathTrig::GCD($decimalPart, $decimalDivisor);
+
+        $adjustedDecimalPart = $decimalPart/$GCD;
+        $adjustedDecimalDivisor = $decimalDivisor/$GCD;
+
+        if ((strpos($format, '0') !== false) || (strpos($format, '#') !== false) || (substr($format, 0, 3) == '? ?')) {
+            if ($integerPart == 0) {
+                $integerPart = '';
+            }
+            $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor";
+        } else {
+            $adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor;
+            $value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor";
+        }
+    }
+
+    private static function complexNumberFormatMask($number, $mask, $level = 0)
+    {
         $sign = ($number < 0.0);
         $number = abs($number);
-		if (strpos($mask,'.') !== false) {
-			$numbers = explode('.', $number . '.0');
-			$masks = explode('.', $mask . '.0');
-			$result1 = self::_complexNumberFormatMask($numbers[0], $masks[0], 1);
-			$result2 = strrev(self::_complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]), 1));
-			return (($sign) ? '-' : '') . $result1 . '.' . $result2;
-		}
-
-		$r = preg_match_all('/0+/', $mask, $result, PREG_OFFSET_CAPTURE);
-		if ($r > 1) {
-			$result = array_reverse($result[0]);
-
-			foreach($result as $block) {
-				$divisor = 1 . $block[0];
-				$size = strlen($block[0]);
-				$offset = $block[1];
-
-				$blockValue = sprintf(
-					'%0' . $size . 'd',
-					fmod($number, $divisor)
-				);
-				$number = floor($number / $divisor);
-				$mask = substr_replace($mask, $blockValue, $offset, $size);
-			}
-			if ($number > 0) {
-				$mask = substr_replace($mask, $number, $offset, 0);
-			}
-			$result = $mask;
-		} else {
-			$result = $number;
-		}
-
-		return (($sign) ? '-' : '') . $result;
-	}
-
-	/**
-	 * Convert a value in a pre-defined format to a PHP string
-	 *
-	 * @param mixed	$value		Value to format
-	 * @param string	$format		Format code
-	 * @param array		$callBack	Callback function for additional formatting of string
-	 * @return string	Formatted string
-	 */
-	public static function toFormattedString($value = '0', $format = PHPExcel_Style_NumberFormat::FORMAT_GENERAL, $callBack = null)
-	{
-		// For now we do not treat strings although section 4 of a format code affects strings
-		if (!is_numeric($value)) return $value;
-
-		// For 'General' format code, we just pass the value although this is not entirely the way Excel does it,
-		// it seems to round numbers to a total of 10 digits.
-		if (($format === PHPExcel_Style_NumberFormat::FORMAT_GENERAL) || ($format === PHPExcel_Style_NumberFormat::FORMAT_TEXT)) {
-			return $value;
-		}
-
-		// Get the sections, there can be up to four sections
-		$sections = explode(';', $format);
-
-		// Fetch the relevant section depending on whether number is positive, negative, or zero?
-		// Text not supported yet.
-		// Here is how the sections apply to various values in Excel:
-		//   1 section:   [POSITIVE/NEGATIVE/ZERO/TEXT]
-		//   2 sections:  [POSITIVE/ZERO/TEXT] [NEGATIVE]
-		//   3 sections:  [POSITIVE/TEXT] [NEGATIVE] [ZERO]
-		//   4 sections:  [POSITIVE] [NEGATIVE] [ZERO] [TEXT]
-		switch (count($sections)) {
-			case 1:
-				$format = $sections[0];
-				break;
-
-			case 2:
-				$format = ($value >= 0) ? $sections[0] : $sections[1];
-				$value = abs($value); // Use the absolute value
-				break;
-
-			case 3:
-				$format = ($value > 0) ?
-					$sections[0] : ( ($value < 0) ?
-						$sections[1] : $sections[2]);
-				$value = abs($value); // Use the absolute value
-				break;
-
-			case 4:
-				$format = ($value > 0) ?
-					$sections[0] : ( ($value < 0) ?
-						$sections[1] : $sections[2]);
-				$value = abs($value); // Use the absolute value
-				break;
-
-			default:
-				// something is wrong, just use first section
-				$format = $sections[0];
-				break;
-		}
-
-		// Save format with color information for later use below
-		$formatColor = $format;
-
-		// Strip color information
-		$color_regex = '/^\\[[a-zA-Z]+\\]/';
-		$format = preg_replace($color_regex, '', $format);
-
-		// Let's begin inspecting the format and converting the value to a formatted string
-		if (preg_match('/^(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy]/i', $format)) { // datetime format
-			self::_formatAsDate($value, $format);
-		} else if (preg_match('/%$/', $format)) { // % number format
-			self::_formatAsPercentage($value, $format);
-		} else {
-			if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) {
-				$value = 'EUR ' . sprintf('%1.2f', $value);
-			} else {
-				// In Excel formats, "_" is used to add spacing, which we can't do in HTML
-				$format = preg_replace('/_./', '', $format);
-
-				// Some non-number characters are escaped with \, which we don't need
-				$format = preg_replace("/\\\\/", '', $format);
+        if (strpos($mask, '.') !== false) {
+            $numbers = explode('.', $number . '.0');
+            $masks = explode('.', $mask . '.0');
+            $result1 = self::complexNumberFormatMask($numbers[0], $masks[0], 1);
+            $result2 = strrev(self::complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]), 1));
+            return (($sign) ? '-' : '') . $result1 . '.' . $result2;
+        }
+
+        $r = preg_match_all('/0+/', $mask, $result, PREG_OFFSET_CAPTURE);
+        if ($r > 1) {
+            $result = array_reverse($result[0]);
+
+            foreach ($result as $block) {
+                $divisor = 1 . $block[0];
+                $size = strlen($block[0]);
+                $offset = $block[1];
+
+                $blockValue = sprintf(
+                    '%0' . $size . 'd',
+                    fmod($number, $divisor)
+                );
+                $number = floor($number / $divisor);
+                $mask = substr_replace($mask, $blockValue, $offset, $size);
+            }
+            if ($number > 0) {
+                $mask = substr_replace($mask, $number, $offset, 0);
+            }
+            $result = $mask;
+        } else {
+            $result = $number;
+        }
+
+        return (($sign) ? '-' : '') . $result;
+    }
+
+    /**
+     * Convert a value in a pre-defined format to a PHP string
+     *
+     * @param mixed    $value        Value to format
+     * @param string    $format        Format code
+     * @param array        $callBack    Callback function for additional formatting of string
+     * @return string    Formatted string
+     */
+    public static function toFormattedString($value = '0', $format = PHPExcel_Style_NumberFormat::FORMAT_GENERAL, $callBack = null)
+    {
+        // For now we do not treat strings although section 4 of a format code affects strings
+        if (!is_numeric($value)) {
+            return $value;
+        }
+
+        // For 'General' format code, we just pass the value although this is not entirely the way Excel does it,
+        // it seems to round numbers to a total of 10 digits.
+        if (($format === PHPExcel_Style_NumberFormat::FORMAT_GENERAL) || ($format === PHPExcel_Style_NumberFormat::FORMAT_TEXT)) {
+            return $value;
+        }
+
+        // Get the sections, there can be up to four sections
+        $sections = explode(';', $format);
+
+        // Fetch the relevant section depending on whether number is positive, negative, or zero?
+        // Text not supported yet.
+        // Here is how the sections apply to various values in Excel:
+        //   1 section:   [POSITIVE/NEGATIVE/ZERO/TEXT]
+        //   2 sections:  [POSITIVE/ZERO/TEXT] [NEGATIVE]
+        //   3 sections:  [POSITIVE/TEXT] [NEGATIVE] [ZERO]
+        //   4 sections:  [POSITIVE] [NEGATIVE] [ZERO] [TEXT]
+        switch (count($sections)) {
+            case 1:
+                $format = $sections[0];
+                break;
+            case 2:
+                $format = ($value >= 0) ? $sections[0] : $sections[1];
+                $value = abs($value); // Use the absolute value
+                break;
+            case 3:
+                $format = ($value > 0) ?
+                    $sections[0] : ( ($value < 0) ?
+                        $sections[1] : $sections[2]);
+                $value = abs($value); // Use the absolute value
+                break;
+            case 4:
+                $format = ($value > 0) ?
+                    $sections[0] : ( ($value < 0) ?
+                        $sections[1] : $sections[2]);
+                $value = abs($value); // Use the absolute value
+                break;
+            default:
+                // something is wrong, just use first section
+                $format = $sections[0];
+                break;
+        }
+
+        // Save format with color information for later use below
+        $formatColor = $format;
+
+        // Strip color information
+        $color_regex = '/^\\[[a-zA-Z]+\\]/';
+        $format = preg_replace($color_regex, '', $format);
+
+        // Let's begin inspecting the format and converting the value to a formatted string
+        if (preg_match('/^(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy]/i', $format)) { // datetime format
+            self::formatAsDate($value, $format);
+        } elseif (preg_match('/%$/', $format)) { // % number format
+            self::formatAsPercentage($value, $format);
+        } else {
+            if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) {
+                $value = 'EUR ' . sprintf('%1.2f', $value);
+            } else {
+                // In Excel formats, "_" is used to add spacing, which we can't do in HTML
+                $format = preg_replace('/_./', '', $format);
+
+                // Some non-number characters are escaped with \, which we don't need
+                $format = preg_replace("/\\\\/", '', $format);
 //              Handle escaped characters, such as \" to display a literal " or \\ to display a literal \
 //              $format = preg_replace('/(?';
-					if ($value != (int)$value) {
-						self::_formatAsFraction($value, $format);
-					}
-
-				} else {
-					// Handle the number itself
-
-					// scale number
-					$value = $value / $scale;
-
-					// Strip #
-					$format = preg_replace('/\\#/', '0', $format);
-
-					$n = "/\[[^\]]+\]/";
-					$m = preg_replace($n, '', $format);
-					$number_regex = "/(0+)(\.?)(0*)/";
-					if (preg_match($number_regex, $m, $matches)) {
-						$left = $matches[1];
-						$dec = $matches[2];
-						$right = $matches[3];
-
-						// minimun width of formatted number (including dot)
-						$minWidth = strlen($left) + strlen($dec) + strlen($right);
-						if ($useThousands) {
-							$value = number_format(
-										$value
-										, strlen($right)
-										, PHPExcel_Shared_String::getDecimalSeparator()
-										, PHPExcel_Shared_String::getThousandsSeparator()
-									);
-							$value = preg_replace($number_regex, $value, $format);
-						} else {
-							if (preg_match('/[0#]E[+-]0/i', $format)) {
-								//	Scientific format
-								$value = sprintf('%5.2E', $value);
-							} elseif (preg_match('/0([^\d\.]+)0/', $format)) {
-								$value = self::_complexNumberFormatMask($value, $format);
-							} else {
-								$sprintf_pattern = "%0$minWidth." . strlen($right) . "f";
-								$value = sprintf($sprintf_pattern, $value);
-								$value = preg_replace($number_regex, $value, $format);
-							}
-						}
-					}
-				}
-				if (preg_match('/\[\$(.*)\]/u', $format, $m)) {
-					//	Currency or Accounting
-					$currencyFormat = $m[0];
-					$currencyCode = $m[1];
-					list($currencyCode) = explode('-',$currencyCode);
-					if ($currencyCode == '') {
-						$currencyCode = PHPExcel_Shared_String::getCurrencyCode();
-					}
-					$value = preg_replace('/\[\$([^\]]*)\]/u',$currencyCode,$value);
-				}
-			}
-		}
-
-		// Additional formatting provided by callback function
-		if ($callBack !== null) {
-			list($writerInstance, $function) = $callBack;
-			$value = $writerInstance->$function($value, $formatColor);
-		}
-
-		return $value;
-	}
-
+//                $format = str_replace(array('\\"', '*'), array('"', ''), $format);
+
+                // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols
+                $format = str_replace(array('"', '*'), '', $format);
+
+                // Find out if we need thousands separator
+                // This is indicated by a comma enclosed by a digit placeholder:
+                //        #,#   or   0,0
+                $useThousands = preg_match('/(#,#|0,0)/', $format);
+                if ($useThousands) {
+                    $format = preg_replace('/0,0/', '00', $format);
+                    $format = preg_replace('/#,#/', '##', $format);
+                }
+
+                // Scale thousands, millions,...
+                // This is indicated by a number of commas after a digit placeholder:
+                //        #,   or    0.0,,
+                $scale = 1; // same as no scale
+                $matches = array();
+                if (preg_match('/(#|0)(,+)/', $format, $matches)) {
+                    $scale = pow(1000, strlen($matches[2]));
+
+                    // strip the commas
+                    $format = preg_replace('/0,+/', '0', $format);
+                    $format = preg_replace('/#,+/', '#', $format);
+                }
+
+                if (preg_match('/#?.*\?\/\?/', $format, $m)) {
+                    //echo 'Format mask is fractional '.$format.' 
'; + if ($value != (int)$value) { + self::formatAsFraction($value, $format); + } + + } else { + // Handle the number itself + + // scale number + $value = $value / $scale; + + // Strip # + $format = preg_replace('/\\#/', '0', $format); + + $n = "/\[[^\]]+\]/"; + $m = preg_replace($n, '', $format); + $number_regex = "/(0+)(\.?)(0*)/"; + if (preg_match($number_regex, $m, $matches)) { + $left = $matches[1]; + $dec = $matches[2]; + $right = $matches[3]; + + // minimun width of formatted number (including dot) + $minWidth = strlen($left) + strlen($dec) + strlen($right); + if ($useThousands) { + $value = number_format( + $value, + strlen($right), + PHPExcel_Shared_String::getDecimalSeparator(), + PHPExcel_Shared_String::getThousandsSeparator() + ); + $value = preg_replace($number_regex, $value, $format); + } else { + if (preg_match('/[0#]E[+-]0/i', $format)) { + // Scientific format + $value = sprintf('%5.2E', $value); + } elseif (preg_match('/0([^\d\.]+)0/', $format)) { + $value = self::complexNumberFormatMask($value, $format); + } else { + $sprintf_pattern = "%0$minWidth." . strlen($right) . "f"; + $value = sprintf($sprintf_pattern, $value); + $value = preg_replace($number_regex, $value, $format); + } + } + } + } + if (preg_match('/\[\$(.*)\]/u', $format, $m)) { + // Currency or Accounting + $currencyFormat = $m[0]; + $currencyCode = $m[1]; + list($currencyCode) = explode('-', $currencyCode); + if ($currencyCode == '') { + $currencyCode = PHPExcel_Shared_String::getCurrencyCode(); + } + $value = preg_replace('/\[\$([^\]]*)\]/u', $currencyCode, $value); + } + } + } + + // Additional formatting provided by callback function + if ($callBack !== null) { + list($writerInstance, $function) = $callBack; + $value = $writerInstance->$function($value, $formatColor); + } + + return $value; + } } diff --git a/Classes/PHPExcel/Style/Protection.php b/Classes/PHPExcel/Style/Protection.php index 54a05d987..d5568f655 100644 --- a/Classes/PHPExcel/Style/Protection.php +++ b/Classes/PHPExcel/Style/Protection.php @@ -1,6 +1,7 @@ _locked = self::PROTECTION_INHERIT; - $this->_hidden = self::PROTECTION_INHERIT; - } + // Initialise values + if (!$isConditional) { + $this->locked = self::PROTECTION_INHERIT; + $this->hidden = self::PROTECTION_INHERIT; + } } - /** - * Get the shared style component for the currently active cell in currently active sheet. - * Only used for style supervisor - * - * @return PHPExcel_Style_Protection - */ - public function getSharedComponent() - { - return $this->_parent->getSharedComponent()->getProtection(); - } + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Protection + */ + public function getSharedComponent() + { + return $this->parent->getSharedComponent()->getProtection(); + } - /** - * Build style array from subcomponents - * - * @param array $array - * @return array - */ - public function getStyleArray($array) - { - return array('protection' => $array); - } + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('protection' => $array); + } /** * Apply styles from array * * * $objPHPExcel->getActiveSheet()->getStyle('B2')->getLocked()->applyFromArray( - * array( - * 'locked' => TRUE, - * 'hidden' => FALSE - * ) + * array( + * 'locked' => TRUE, + * 'hidden' => FALSE + * ) * ); * * - * @param array $pStyles Array containing style information - * @throws PHPExcel_Exception + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception * @return PHPExcel_Style_Protection */ - public function applyFromArray($pStyles = NULL) { - if (is_array($pStyles)) { - if ($this->_isSupervisor) { - $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); - } else { - if (isset($pStyles['locked'])) { - $this->setLocked($pStyles['locked']); - } - if (isset($pStyles['hidden'])) { - $this->setHidden($pStyles['hidden']); - } - } - } else { - throw new PHPExcel_Exception("Invalid style array passed."); - } - return $this; - } + public function applyFromArray($pStyles = null) + { + if (is_array($pStyles)) { + if ($this->isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (isset($pStyles['locked'])) { + $this->setLocked($pStyles['locked']); + } + if (isset($pStyles['hidden'])) { + $this->setHidden($pStyles['hidden']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } /** * Get locked * * @return string */ - public function getLocked() { - if ($this->_isSupervisor) { - return $this->getSharedComponent()->getLocked(); - } - return $this->_locked; + public function getLocked() + { + if ($this->isSupervisor) { + return $this->getSharedComponent()->getLocked(); + } + return $this->locked; } /** @@ -150,14 +144,15 @@ public function getLocked() { * @param string $pValue * @return PHPExcel_Style_Protection */ - public function setLocked($pValue = self::PROTECTION_INHERIT) { - if ($this->_isSupervisor) { - $styleArray = $this->getStyleArray(array('locked' => $pValue)); - $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); - } else { - $this->_locked = $pValue; - } - return $this; + public function setLocked($pValue = self::PROTECTION_INHERIT) + { + if ($this->isSupervisor) { + $styleArray = $this->getStyleArray(array('locked' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->locked = $pValue; + } + return $this; } /** @@ -165,11 +160,12 @@ public function setLocked($pValue = self::PROTECTION_INHERIT) { * * @return string */ - public function getHidden() { - if ($this->_isSupervisor) { - return $this->getSharedComponent()->getHidden(); - } - return $this->_hidden; + public function getHidden() + { + if ($this->isSupervisor) { + return $this->getSharedComponent()->getHidden(); + } + return $this->hidden; } /** @@ -178,30 +174,31 @@ public function getHidden() { * @param string $pValue * @return PHPExcel_Style_Protection */ - public function setHidden($pValue = self::PROTECTION_INHERIT) { - if ($this->_isSupervisor) { - $styleArray = $this->getStyleArray(array('hidden' => $pValue)); - $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); - } else { - $this->_hidden = $pValue; - } - return $this; + public function setHidden($pValue = self::PROTECTION_INHERIT) + { + if ($this->isSupervisor) { + $styleArray = $this->getStyleArray(array('hidden' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->hidden = $pValue; + } + return $this; } - /** - * Get hash code - * - * @return string Hash code - */ - public function getHashCode() { - if ($this->_isSupervisor) { - return $this->getSharedComponent()->getHashCode(); - } - return md5( - $this->_locked - . $this->_hidden - . __CLASS__ - ); + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + if ($this->isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->locked . + $this->hidden . + __CLASS__ + ); } - } diff --git a/Classes/PHPExcel/Style/Supervisor.php b/Classes/PHPExcel/Style/Supervisor.php index c732d30f5..a90e1c6a9 100644 --- a/Classes/PHPExcel/Style/Supervisor.php +++ b/Classes/PHPExcel/Style/Supervisor.php @@ -1,6 +1,7 @@ _isSupervisor = $isSupervisor; - } + /** + * Create a new PHPExcel_Style_Alignment + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = false) + { + // Supervisor? + $this->isSupervisor = $isSupervisor; + } - /** - * Bind parent. Only used for supervisor - * - * @param PHPExcel $parent - * @return PHPExcel_Style_Supervisor - */ - public function bindParent($parent, $parentPropertyName=NULL) - { - $this->_parent = $parent; - return $this; - } + /** + * Bind parent. Only used for supervisor + * + * @param PHPExcel $parent + * @return PHPExcel_Style_Supervisor + */ + public function bindParent($parent, $parentPropertyName = null) + { + $this->parent = $parent; + return $this; + } - /** - * Is this a supervisor or a cell style component? - * - * @return boolean - */ - public function getIsSupervisor() - { - return $this->_isSupervisor; - } + /** + * Is this a supervisor or a cell style component? + * + * @return boolean + */ + public function getIsSupervisor() + { + return $this->isSupervisor; + } - /** - * Get the currently active sheet. Only used for supervisor - * - * @return PHPExcel_Worksheet - */ - public function getActiveSheet() - { - return $this->_parent->getActiveSheet(); - } + /** + * Get the currently active sheet. Only used for supervisor + * + * @return PHPExcel_Worksheet + */ + public function getActiveSheet() + { + return $this->parent->getActiveSheet(); + } - /** - * Get the currently active cell coordinate in currently active sheet. - * Only used for supervisor - * - * @return string E.g. 'A1' - */ - public function getSelectedCells() - { - return $this->getActiveSheet()->getSelectedCells(); - } + /** + * Get the currently active cell coordinate in currently active sheet. + * Only used for supervisor + * + * @return string E.g. 'A1' + */ + public function getSelectedCells() + { + return $this->getActiveSheet()->getSelectedCells(); + } - /** - * Get the currently active cell coordinate in currently active sheet. - * Only used for supervisor - * - * @return string E.g. 'A1' - */ - public function getActiveCell() - { - return $this->getActiveSheet()->getActiveCell(); - } + /** + * Get the currently active cell coordinate in currently active sheet. + * Only used for supervisor + * + * @return string E.g. 'A1' + */ + public function getActiveCell() + { + return $this->getActiveSheet()->getActiveCell(); + } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if ((is_object($value)) && ($key != '_parent')) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() + { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if ((is_object($value)) && ($key != 'parent')) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index c5c4119fc..f3f89d52f 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1152,16 +1152,15 @@ public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pVa */ public function getCell($pCoordinate = 'A1') { - $pCoordinate = strtoupper($pCoordinate); // Check cell collection - if ($this->_cellCollection->isDataSet($pCoordinate)) { + if ($this->_cellCollection->isDataSet(strtoupper($pCoordinate))) { return $this->_cellCollection->getCacheData($pCoordinate); } // Worksheet reference? if (strpos($pCoordinate, '!') !== false) { $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); - return $this->_parent->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]); + return $this->_parent->getSheetByName($worksheetReference[0])->getCell(strtoupper($worksheetReference[1])); } // Named range? @@ -2658,9 +2657,10 @@ public static function extractSheetTitle($pRange, $returnRange = false) { } if ($returnRange) { - return array( trim(substr($pRange, 0, $sep),"'"), - substr($pRange, $sep + 1) - ); + return array( + trim(substr($pRange, 0, $sep),"'"), + substr($pRange, $sep + 1) + ); } return substr($pRange, $sep + 1); diff --git a/Examples/16csv.php b/Examples/16csv.php index 813651bdd..8d42fcbba 100644 --- a/Examples/16csv.php +++ b/Examples/16csv.php @@ -46,7 +46,6 @@ $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV')->setDelimiter(',') ->setEnclosure('"') - ->setLineEnding("\r\n") ->setSheetIndex(0) ->save(str_replace('.php', '.csv', __FILE__)); $callEndTime = microtime(true); @@ -61,7 +60,6 @@ $callStartTime = microtime(true); $objReader = PHPExcel_IOFactory::createReader('CSV')->setDelimiter(',') ->setEnclosure('"') - ->setLineEnding("\r\n") ->setSheetIndex(0); $objPHPExcelFromCSV = $objReader->load(str_replace('.php', '.csv', __FILE__)); From b88a6f49471f1c4ef92b26a0efb196b873725810 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 4 May 2015 23:41:52 +0100 Subject: [PATCH 339/467] Calculation example with cyclic formula --- Examples/13calculationCyclicFormulae.php | 97 ++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 Examples/13calculationCyclicFormulae.php diff --git a/Examples/13calculationCyclicFormulae.php b/Examples/13calculationCyclicFormulae.php new file mode 100644 index 000000000..8512a3e85 --- /dev/null +++ b/Examples/13calculationCyclicFormulae.php @@ -0,0 +1,97 @@ +'); + +date_default_timezone_set('Europe/London'); + +/** Include PHPExcel */ +require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; + + +// Create new PHPExcel object +echo date('H:i:s') , " Create new PHPExcel object" , EOL; +$objPHPExcel = new PHPExcel(); + +// Add some data, we will use some formulas here +echo date('H:i:s') , " Add some data and formulas" , EOL; +$objPHPExcel->getActiveSheet()->setCellValue('A1', '=B1') + ->setCellValue('A2', '=B2+1') + ->setCellValue('B1', '=A1+1') + ->setCellValue('B2', '=A2'); + +PHPExcel_Calculation::getInstance($objPHPExcel)->cyclicFormulaCount = 100; + +// Calculated data +echo date('H:i:s') , " Calculated data" , EOL; +for($row = 1; $row <= 2; ++$row) { + for ($col = 'A'; $col != 'C'; ++$col) { + if ((!is_null($formula = $objPHPExcel->getActiveSheet()->getCell($col.$row)->getValue())) && + ($formula[0] == '=')) { + echo 'Value of ' , $col , $row , ' [' , $formula , ']: ' , + $objPHPExcel->getActiveSheet()->getCell($col.$row)->getCalculatedValue() . EOL; + } + } +} + + +// Save Excel 2007 file +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); + +// +// If we set Pre Calculated Formulas to true then PHPExcel will calculate all formulae in the +// workbook before saving. This adds time and memory overhead, and can cause some problems with formulae +// using functions or features (such as array formulae) that aren't yet supported by the calculation engine +// If the value is false (the default) for the Excel2007 Writer, then MS Excel (or the application used to +// open the file) will need to recalculate values itself to guarantee that the correct results are available. +// +//$objWriter->setPreCalculateFormulas(true); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; From e885ef9196277435b4c65a1edacae729186b00b5 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 5 May 2015 01:37:34 +0100 Subject: [PATCH 340/467] Fix typo in memcache constructor --- Classes/PHPExcel/CachedObjectStorage/Memcache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/Memcache.php b/Classes/PHPExcel/CachedObjectStorage/Memcache.php index 1ffcf47ab..f3c3e1f02 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memcache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memcache.php @@ -260,7 +260,7 @@ public function __construct(PHPExcel_Worksheet $parent, $arguments) // Set a new Memcache object and connect to the Memcache server $this->_memcache = new Memcache(); if (!$this->_memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) { - throw new PHPExcel_Exception("Could not connect to MemCache server at {$memcacheServer}:{$memcachePort}"; + throw new PHPExcel_Exception("Could not connect to MemCache server at {$memcacheServer}:{$memcachePort}"); } $this->_cacheTime = $cacheTime; From 3c3154c4a3901b708206fb83a504a87865d0e390 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 5 May 2015 19:40:34 +0100 Subject: [PATCH 341/467] PSR-2 variable naming for caching classes, remove leading underscores --- Classes/PHPExcel/CachedObjectStorage/APC.php | 90 +++++----- .../CachedObjectStorage/CacheBase.php | 64 +++---- .../PHPExcel/CachedObjectStorage/DiscISAM.php | 94 +++++----- .../PHPExcel/CachedObjectStorage/Igbinary.php | 52 +++--- .../PHPExcel/CachedObjectStorage/Memcache.php | 96 +++++------ .../PHPExcel/CachedObjectStorage/Memory.php | 26 +-- .../CachedObjectStorage/MemoryGZip.php | 52 +++--- .../CachedObjectStorage/MemorySerialized.php | 52 +++--- .../PHPExcel/CachedObjectStorage/PHPTemp.php | 86 +++++----- .../PHPExcel/CachedObjectStorage/SQLite.php | 138 +++++++-------- .../PHPExcel/CachedObjectStorage/SQLite3.php | 162 +++++++++--------- .../PHPExcel/CachedObjectStorage/Wincache.php | 94 +++++----- .../PHPExcel/CachedObjectStorageFactory.php | 44 ++--- .../CalcEngine/CyclicReferenceStack.php | 14 +- Classes/PHPExcel/CalcEngine/Logger.php | 34 ++-- changelog.txt | 1 + 16 files changed, 550 insertions(+), 549 deletions(-) diff --git a/Classes/PHPExcel/CachedObjectStorage/APC.php b/Classes/PHPExcel/CachedObjectStorage/APC.php index d2ad6e37d..c74b07fee 100644 --- a/Classes/PHPExcel/CachedObjectStorage/APC.php +++ b/Classes/PHPExcel/CachedObjectStorage/APC.php @@ -33,7 +33,7 @@ class PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_Cach * @access private * @var string */ - private $_cachePrefix = null; + private $cachePrefix = null; /** * Cache timeout @@ -41,7 +41,7 @@ class PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_Cach * @access private * @var integer */ - private $_cacheTime = 600; + private $cacheTime = 600; /** * Store cell data in cache for the current cell object if it's "dirty", @@ -51,22 +51,22 @@ class PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_Cach * @return void * @throws PHPExcel_Exception */ - protected function _storeData() + protected function storeData() { - if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { - $this->_currentObject->detach(); + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { + $this->currentObject->detach(); if (!apc_store( - $this->_cachePrefix . $this->_currentObjectID . '.cache', - serialize($this->_currentObject), - $this->_cacheTime + $this->cachePrefix . $this->currentObjectID . '.cache', + serialize($this->currentObject), + $this->cacheTime )) { $this->__destruct(); - throw new PHPExcel_Exception('Failed to store cell ' . $this->_currentObjectID . ' in APC'); + throw new PHPExcel_Exception('Failed to store cell ' . $this->currentObjectID . ' in APC'); } - $this->_currentCellIsDirty = false; + $this->currentCellIsDirty = false; } - $this->_currentObjectID = $this->_currentObject = null; + $this->currentObjectID = $this->currentObject = null; } /** @@ -80,14 +80,14 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { - $this->_storeData(); + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { + $this->storeData(); } - $this->_cellCache[$pCoord] = true; + $this->cellCache[$pCoord] = true; - $this->_currentObjectID = $pCoord; - $this->_currentObject = $cell; - $this->_currentCellIsDirty = true; + $this->currentObjectID = $pCoord; + $this->currentObject = $cell; + $this->currentCellIsDirty = true; return $cell; } @@ -104,11 +104,11 @@ public function isDataSet($pCoord) { // Check if the requested entry is the current object, or exists in the cache if (parent::isDataSet($pCoord)) { - if ($this->_currentObjectID == $pCoord) { + if ($this->currentObjectID == $pCoord) { return true; } // Check if the requested entry still exists in apc - $success = apc_fetch($this->_cachePrefix.$pCoord.'.cache'); + $success = apc_fetch($this->cachePrefix.$pCoord.'.cache'); if ($success === false) { // Entry no longer exists in APC, so clear it from the cache array parent::deleteCacheData($pCoord); @@ -129,14 +129,14 @@ public function isDataSet($pCoord) */ public function getCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - return $this->_currentObject; + if ($pCoord === $this->currentObjectID) { + return $this->currentObject; } - $this->_storeData(); + $this->storeData(); // Check if the entry that has been requested actually exists if (parent::isDataSet($pCoord)) { - $obj = apc_fetch($this->_cachePrefix . $pCoord . '.cache'); + $obj = apc_fetch($this->cachePrefix . $pCoord . '.cache'); if ($obj === false) { // Entry no longer exists in APC, so clear it from the cache array parent::deleteCacheData($pCoord); @@ -148,13 +148,13 @@ public function getCacheData($pCoord) } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; - $this->_currentObject = unserialize($obj); + $this->currentObjectID = $pCoord; + $this->currentObject = unserialize($obj); // Re-attach this as the cell's parent - $this->_currentObject->attach($this); + $this->currentObject->attach($this); // Return requested entry - return $this->_currentObject; + return $this->currentObject; } /** @@ -164,8 +164,8 @@ public function getCacheData($pCoord) */ public function getCellList() { - if ($this->_currentObjectID !== null) { - $this->_storeData(); + if ($this->currentObjectID !== null) { + $this->storeData(); } return parent::getCellList(); @@ -181,7 +181,7 @@ public function getCellList() public function deleteCacheData($pCoord) { // Delete the entry from APC - apc_delete($this->_cachePrefix.$pCoord.'.cache'); + apc_delete($this->cachePrefix.$pCoord.'.cache'); // Delete the entry from our cell address array parent::deleteCacheData($pCoord); @@ -199,24 +199,24 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) { parent::copyCellCollection($parent); // Get a new id for the new file name - $baseUnique = $this->_getUniqueID(); + $baseUnique = $this->getUniqueID(); $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.'; $cacheList = $this->getCellList(); foreach ($cacheList as $cellID) { - if ($cellID != $this->_currentObjectID) { - $obj = apc_fetch($this->_cachePrefix . $cellID . '.cache'); + if ($cellID != $this->currentObjectID) { + $obj = apc_fetch($this->cachePrefix . $cellID . '.cache'); if ($obj === false) { // Entry no longer exists in APC, so clear it from the cache array parent::deleteCacheData($cellID); throw new PHPExcel_Exception('Cell entry ' . $cellID . ' no longer exists in APC'); } - if (!apc_store($newCachePrefix . $cellID . '.cache', $obj, $this->_cacheTime)) { + if (!apc_store($newCachePrefix . $cellID . '.cache', $obj, $this->cacheTime)) { $this->__destruct(); throw new PHPExcel_Exception('Failed to store cell ' . $cellID . ' in APC'); } } } - $this->_cachePrefix = $newCachePrefix; + $this->cachePrefix = $newCachePrefix; } /** @@ -226,18 +226,18 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) */ public function unsetWorksheetCells() { - if ($this->_currentObject !== null) { - $this->_currentObject->detach(); - $this->_currentObject = $this->_currentObjectID = null; + if ($this->currentObject !== null) { + $this->currentObject->detach(); + $this->currentObject = $this->currentObjectID = null; } // Flush the APC cache $this->__destruct(); - $this->_cellCache = array(); + $this->cellCache = array(); // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; } /** @@ -250,10 +250,10 @@ public function __construct(PHPExcel_Worksheet $parent, $arguments) { $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; - if ($this->_cachePrefix === null) { - $baseUnique = $this->_getUniqueID(); - $this->_cachePrefix = substr(md5($baseUnique), 0, 8) . '.'; - $this->_cacheTime = $cacheTime; + if ($this->cachePrefix === null) { + $baseUnique = $this->getUniqueID(); + $this->cachePrefix = substr(md5($baseUnique), 0, 8) . '.'; + $this->cacheTime = $cacheTime; parent::__construct($parent); } @@ -266,7 +266,7 @@ public function __destruct() { $cacheList = $this->getCellList(); foreach ($cacheList as $cellID) { - apc_delete($this->_cachePrefix . $cellID . '.cache'); + apc_delete($this->cachePrefix . $cellID . '.cache'); } } diff --git a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php index a7c25ed20..9a12ec86e 100644 --- a/Classes/PHPExcel/CachedObjectStorage/CacheBase.php +++ b/Classes/PHPExcel/CachedObjectStorage/CacheBase.php @@ -32,28 +32,28 @@ abstract class PHPExcel_CachedObjectStorage_CacheBase * * @var PHPExcel_Worksheet */ - protected $_parent; + protected $parent; /** * The currently active Cell * * @var PHPExcel_Cell */ - protected $_currentObject = null; + protected $currentObject = null; /** * Coordinate address of the currently active Cell * * @var string */ - protected $_currentObjectID = null; + protected $currentObjectID = null; /** * Flag indicating whether the currently active Cell requires saving * * @var boolean */ - protected $_currentCellIsDirty = true; + protected $currentCellIsDirty = true; /** * An array of cells or cell pointers for the worksheet cells held in this cache, @@ -61,7 +61,7 @@ abstract class PHPExcel_CachedObjectStorage_CacheBase * * @var array of mixed */ - protected $_cellCache = array(); + protected $cellCache = array(); /** * Initialise this new cell collection @@ -73,7 +73,7 @@ public function __construct(PHPExcel_Worksheet $parent) // Set our parent worksheet. // This is maintained within the cache controller to facilitate re-attaching it to PHPExcel_Cell objects when // they are woken from a serialized state - $this->_parent = $parent; + $this->parent = $parent; } /** @@ -83,7 +83,7 @@ public function __construct(PHPExcel_Worksheet $parent) */ public function getParent() { - return $this->_parent; + return $this->parent; } /** @@ -94,11 +94,11 @@ public function getParent() */ public function isDataSet($pCoord) { - if ($pCoord === $this->_currentObjectID) { + if ($pCoord === $this->currentObjectID) { return true; } // Check if the requested entry exists in the cache - return isset($this->_cellCache[$pCoord]); + return isset($this->cellCache[$pCoord]); } /** @@ -110,13 +110,13 @@ public function isDataSet($pCoord) */ public function moveCell($fromAddress, $toAddress) { - if ($fromAddress === $this->_currentObjectID) { - $this->_currentObjectID = $toAddress; + if ($fromAddress === $this->currentObjectID) { + $this->currentObjectID = $toAddress; } - $this->_currentCellIsDirty = true; - if (isset($this->_cellCache[$fromAddress])) { - $this->_cellCache[$toAddress] = &$this->_cellCache[$fromAddress]; - unset($this->_cellCache[$fromAddress]); + $this->currentCellIsDirty = true; + if (isset($this->cellCache[$fromAddress])) { + $this->cellCache[$toAddress] = &$this->cellCache[$fromAddress]; + unset($this->cellCache[$fromAddress]); } return true; @@ -142,16 +142,16 @@ public function updateCacheData(PHPExcel_Cell $cell) */ public function deleteCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID && !is_null($this->_currentObject)) { - $this->_currentObject->detach(); - $this->_currentObjectID = $this->_currentObject = null; + if ($pCoord === $this->currentObjectID && !is_null($this->currentObject)) { + $this->currentObject->detach(); + $this->currentObjectID = $this->currentObject = null; } - if (is_object($this->_cellCache[$pCoord])) { - $this->_cellCache[$pCoord]->detach(); - unset($this->_cellCache[$pCoord]); + if (is_object($this->cellCache[$pCoord])) { + $this->cellCache[$pCoord]->detach(); + unset($this->cellCache[$pCoord]); } - $this->_currentCellIsDirty = false; + $this->currentCellIsDirty = false; } /** @@ -161,7 +161,7 @@ public function deleteCacheData($pCoord) */ public function getCellList() { - return array_keys($this->_cellCache); + return array_keys($this->cellCache); } /** @@ -215,7 +215,7 @@ public function getHighestRowAndColumn() */ public function getCurrentAddress() { - return $this->_currentObjectID; + return $this->currentObjectID; } /** @@ -225,7 +225,7 @@ public function getCurrentAddress() */ public function getCurrentColumn() { - sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); + sscanf($this->currentObjectID, '%[A-Z]%d', $column, $row); return $column; } @@ -236,7 +236,7 @@ public function getCurrentColumn() */ public function getCurrentRow() { - sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); + sscanf($this->currentObjectID, '%[A-Z]%d', $column, $row); return (integer) $row; } @@ -296,7 +296,7 @@ public function getHighestRow($column = null) * * @return string Unique Reference */ - protected function _getUniqueID() + protected function getUniqueID() { if (function_exists('posix_getpid')) { $baseUnique = posix_getpid(); @@ -314,12 +314,12 @@ protected function _getUniqueID() */ public function copyCellCollection(PHPExcel_Worksheet $parent) { - $this->_currentCellIsDirty; - $this->_storeData(); + $this->currentCellIsDirty; + $this->storeData(); - $this->_parent = $parent; - if (($this->_currentObject !== null) && (is_object($this->_currentObject))) { - $this->_currentObject->attach($this); + $this->parent = $parent; + if (($this->currentObject !== null) && (is_object($this->currentObject))) { + $this->currentObject->attach($this); } } // function copyCellCollection() diff --git a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php index 65afa3cf9..13bc03375 100644 --- a/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php +++ b/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php @@ -32,21 +32,21 @@ class PHPExcel_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage * * @var string */ - private $_fileName = null; + private $fileName = null; /** * File handle for this cache file * * @var resource */ - private $_fileHandle = null; + private $fileHandle = null; /** * Directory/Folder where the cache file is located * * @var string */ - private $_cacheDirectory = null; + private $cacheDirectory = null; /** * Store cell data in cache for the current cell object if it's "dirty", @@ -55,20 +55,20 @@ class PHPExcel_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage * @return void * @throws PHPExcel_Exception */ - protected function _storeData() + protected function storeData() { - if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { - $this->_currentObject->detach(); + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { + $this->currentObject->detach(); - fseek($this->_fileHandle, 0, SEEK_END); + fseek($this->fileHandle, 0, SEEK_END); - $this->_cellCache[$this->_currentObjectID] = array( - 'ptr' => ftell($this->_fileHandle), - 'sz' => fwrite($this->_fileHandle, serialize($this->_currentObject)) + $this->cellCache[$this->currentObjectID] = array( + 'ptr' => ftell($this->fileHandle), + 'sz' => fwrite($this->fileHandle, serialize($this->currentObject)) ); - $this->_currentCellIsDirty = false; + $this->currentCellIsDirty = false; } - $this->_currentObjectID = $this->_currentObject = null; + $this->currentObjectID = $this->currentObject = null; } /** @@ -81,13 +81,13 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { - $this->_storeData(); + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { + $this->storeData(); } - $this->_currentObjectID = $pCoord; - $this->_currentObject = $cell; - $this->_currentCellIsDirty = true; + $this->currentObjectID = $pCoord; + $this->currentObject = $cell; + $this->currentCellIsDirty = true; return $cell; } @@ -101,26 +101,26 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) */ public function getCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - return $this->_currentObject; + if ($pCoord === $this->currentObjectID) { + return $this->currentObject; } - $this->_storeData(); + $this->storeData(); // Check if the entry that has been requested actually exists - if (!isset($this->_cellCache[$pCoord])) { + if (!isset($this->cellCache[$pCoord])) { // Return null if requested entry doesn't exist in cache return null; } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; - fseek($this->_fileHandle, $this->_cellCache[$pCoord]['ptr']); - $this->_currentObject = unserialize(fread($this->_fileHandle, $this->_cellCache[$pCoord]['sz'])); + $this->currentObjectID = $pCoord; + fseek($this->fileHandle, $this->cellCache[$pCoord]['ptr']); + $this->currentObject = unserialize(fread($this->fileHandle, $this->cellCache[$pCoord]['sz'])); // Re-attach this as the cell's parent - $this->_currentObject->attach($this); + $this->currentObject->attach($this); // Return requested entry - return $this->_currentObject; + return $this->currentObject; } /** @@ -130,8 +130,8 @@ public function getCacheData($pCoord) */ public function getCellList() { - if ($this->_currentObjectID !== null) { - $this->_storeData(); + if ($this->currentObjectID !== null) { + $this->storeData(); } return parent::getCellList(); @@ -146,13 +146,13 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) { parent::copyCellCollection($parent); // Get a new id for the new file name - $baseUnique = $this->_getUniqueID(); - $newFileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; + $baseUnique = $this->getUniqueID(); + $newFileName = $this->cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; // Copy the existing cell cache file - copy($this->_fileName, $newFileName); - $this->_fileName = $newFileName; + copy($this->fileName, $newFileName); + $this->fileName = $newFileName; // Open the copied cell cache file - $this->_fileHandle = fopen($this->_fileName, 'a+'); + $this->fileHandle = fopen($this->fileName, 'a+'); } /** @@ -161,14 +161,14 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) */ public function unsetWorksheetCells() { - if (!is_null($this->_currentObject)) { - $this->_currentObject->detach(); - $this->_currentObject = $this->_currentObjectID = null; + if (!is_null($this->currentObject)) { + $this->currentObject->detach(); + $this->currentObject = $this->currentObjectID = null; } - $this->_cellCache = array(); + $this->cellCache = array(); // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; // Close down the temporary cache file $this->__destruct(); @@ -182,15 +182,15 @@ public function unsetWorksheetCells() */ public function __construct(PHPExcel_Worksheet $parent, $arguments) { - $this->_cacheDirectory = ((isset($arguments['dir'])) && ($arguments['dir'] !== null)) + $this->cacheDirectory = ((isset($arguments['dir'])) && ($arguments['dir'] !== null)) ? $arguments['dir'] : PHPExcel_Shared_File::sys_get_temp_dir(); parent::__construct($parent); - if (is_null($this->_fileHandle)) { - $baseUnique = $this->_getUniqueID(); - $this->_fileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; - $this->_fileHandle = fopen($this->_fileName, 'a+'); + if (is_null($this->fileHandle)) { + $baseUnique = $this->getUniqueID(); + $this->fileName = $this->cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; + $this->fileHandle = fopen($this->fileName, 'a+'); } } @@ -199,10 +199,10 @@ public function __construct(PHPExcel_Worksheet $parent, $arguments) */ public function __destruct() { - if (!is_null($this->_fileHandle)) { - fclose($this->_fileHandle); - unlink($this->_fileName); + if (!is_null($this->fileHandle)) { + fclose($this->fileHandle); + unlink($this->fileName); } - $this->_fileHandle = null; + $this->fileHandle = null; } } diff --git a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php index e49f3fca7..5f3527b57 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Igbinary.php +++ b/Classes/PHPExcel/CachedObjectStorage/Igbinary.php @@ -34,15 +34,15 @@ class PHPExcel_CachedObjectStorage_Igbinary extends PHPExcel_CachedObjectStorage * @return void * @throws PHPExcel_Exception */ - protected function _storeData() + protected function storeData() { - if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { - $this->_currentObject->detach(); + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { + $this->currentObject->detach(); - $this->_cellCache[$this->_currentObjectID] = igbinary_serialize($this->_currentObject); - $this->_currentCellIsDirty = false; + $this->cellCache[$this->currentObjectID] = igbinary_serialize($this->currentObject); + $this->currentCellIsDirty = false; } - $this->_currentObjectID = $this->_currentObject = null; + $this->currentObjectID = $this->currentObject = null; } // function _storeData() @@ -56,13 +56,13 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { - $this->_storeData(); + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { + $this->storeData(); } - $this->_currentObjectID = $pCoord; - $this->_currentObject = $cell; - $this->_currentCellIsDirty = true; + $this->currentObjectID = $pCoord; + $this->currentObject = $cell; + $this->currentCellIsDirty = true; return $cell; } // function addCacheData() @@ -77,25 +77,25 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) */ public function getCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - return $this->_currentObject; + if ($pCoord === $this->currentObjectID) { + return $this->currentObject; } - $this->_storeData(); + $this->storeData(); // Check if the entry that has been requested actually exists - if (!isset($this->_cellCache[$pCoord])) { + if (!isset($this->cellCache[$pCoord])) { // Return null if requested entry doesn't exist in cache return null; } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; - $this->_currentObject = igbinary_unserialize($this->_cellCache[$pCoord]); + $this->currentObjectID = $pCoord; + $this->currentObject = igbinary_unserialize($this->cellCache[$pCoord]); // Re-attach this as the cell's parent - $this->_currentObject->attach($this); + $this->currentObject->attach($this); // Return requested entry - return $this->_currentObject; + return $this->currentObject; } // function getCacheData() @@ -106,8 +106,8 @@ public function getCacheData($pCoord) */ public function getCellList() { - if ($this->_currentObjectID !== null) { - $this->_storeData(); + if ($this->currentObjectID !== null) { + $this->storeData(); } return parent::getCellList(); @@ -121,14 +121,14 @@ public function getCellList() */ public function unsetWorksheetCells() { - if (!is_null($this->_currentObject)) { - $this->_currentObject->detach(); - $this->_currentObject = $this->_currentObjectID = null; + if (!is_null($this->currentObject)) { + $this->currentObject->detach(); + $this->currentObject = $this->currentObjectID = null; } - $this->_cellCache = array(); + $this->cellCache = array(); // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; } // function unsetWorksheetCells() diff --git a/Classes/PHPExcel/CachedObjectStorage/Memcache.php b/Classes/PHPExcel/CachedObjectStorage/Memcache.php index f3c3e1f02..07942cc3f 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memcache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memcache.php @@ -32,21 +32,21 @@ class PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage * * @var string */ - private $_cachePrefix = null; + private $cachePrefix = null; /** * Cache timeout * * @var integer */ - private $_cacheTime = 600; + private $cacheTime = 600; /** * Memcache interface * * @var resource */ - private $_memcache = null; + private $memcache = null; /** @@ -56,21 +56,21 @@ class PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage * @return void * @throws PHPExcel_Exception */ - protected function _storeData() + protected function storeData() { - if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { - $this->_currentObject->detach(); + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { + $this->currentObject->detach(); - $obj = serialize($this->_currentObject); - if (!$this->_memcache->replace($this->_cachePrefix . $this->_currentObjectID . '.cache', $obj, null, $this->_cacheTime)) { - if (!$this->_memcache->add($this->_cachePrefix . $this->_currentObjectID . '.cache', $obj, null, $this->_cacheTime)) { + $obj = serialize($this->currentObject); + if (!$this->memcache->replace($this->cachePrefix . $this->currentObjectID . '.cache', $obj, null, $this->cacheTime)) { + if (!$this->memcache->add($this->cachePrefix . $this->currentObjectID . '.cache', $obj, null, $this->cacheTime)) { $this->__destruct(); - throw new PHPExcel_Exception("Failed to store cell {$this->_currentObjectID} in MemCache"); + throw new PHPExcel_Exception("Failed to store cell {$this->currentObjectID} in MemCache"); } } - $this->_currentCellIsDirty = false; + $this->currentCellIsDirty = false; } - $this->_currentObjectID = $this->_currentObject = null; + $this->currentObjectID = $this->currentObject = null; } // function _storeData() @@ -84,14 +84,14 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { - $this->_storeData(); + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { + $this->storeData(); } - $this->_cellCache[$pCoord] = true; + $this->cellCache[$pCoord] = true; - $this->_currentObjectID = $pCoord; - $this->_currentObject = $cell; - $this->_currentCellIsDirty = true; + $this->currentObjectID = $pCoord; + $this->currentObject = $cell; + $this->currentCellIsDirty = true; return $cell; } // function addCacheData() @@ -108,11 +108,11 @@ public function isDataSet($pCoord) { // Check if the requested entry is the current object, or exists in the cache if (parent::isDataSet($pCoord)) { - if ($this->_currentObjectID == $pCoord) { + if ($this->currentObjectID == $pCoord) { return true; } // Check if the requested entry still exists in Memcache - $success = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache'); + $success = $this->memcache->get($this->cachePrefix.$pCoord.'.cache'); if ($success === false) { // Entry no longer exists in Memcache, so clear it from the cache array parent::deleteCacheData($pCoord); @@ -133,14 +133,14 @@ public function isDataSet($pCoord) */ public function getCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - return $this->_currentObject; + if ($pCoord === $this->currentObjectID) { + return $this->currentObject; } - $this->_storeData(); + $this->storeData(); // Check if the entry that has been requested actually exists if (parent::isDataSet($pCoord)) { - $obj = $this->_memcache->get($this->_cachePrefix . $pCoord . '.cache'); + $obj = $this->memcache->get($this->cachePrefix . $pCoord . '.cache'); if ($obj === false) { // Entry no longer exists in Memcache, so clear it from the cache array parent::deleteCacheData($pCoord); @@ -152,13 +152,13 @@ public function getCacheData($pCoord) } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; - $this->_currentObject = unserialize($obj); + $this->currentObjectID = $pCoord; + $this->currentObject = unserialize($obj); // Re-attach this as the cell's parent - $this->_currentObject->attach($this); + $this->currentObject->attach($this); // Return requested entry - return $this->_currentObject; + return $this->currentObject; } /** @@ -168,8 +168,8 @@ public function getCacheData($pCoord) */ public function getCellList() { - if ($this->_currentObjectID !== null) { - $this->_storeData(); + if ($this->currentObjectID !== null) { + $this->storeData(); } return parent::getCellList(); @@ -184,7 +184,7 @@ public function getCellList() public function deleteCacheData($pCoord) { // Delete the entry from Memcache - $this->_memcache->delete($this->_cachePrefix . $pCoord . '.cache'); + $this->memcache->delete($this->cachePrefix . $pCoord . '.cache'); // Delete the entry from our cell address array parent::deleteCacheData($pCoord); @@ -200,24 +200,24 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) { parent::copyCellCollection($parent); // Get a new id for the new file name - $baseUnique = $this->_getUniqueID(); + $baseUnique = $this->getUniqueID(); $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.'; $cacheList = $this->getCellList(); foreach ($cacheList as $cellID) { - if ($cellID != $this->_currentObjectID) { - $obj = $this->_memcache->get($this->_cachePrefix.$cellID.'.cache'); + if ($cellID != $this->currentObjectID) { + $obj = $this->memcache->get($this->cachePrefix.$cellID.'.cache'); if ($obj === false) { // Entry no longer exists in Memcache, so clear it from the cache array parent::deleteCacheData($cellID); throw new PHPExcel_Exception("Cell entry {$cellID} no longer exists in MemCache"); } - if (!$this->_memcache->add($newCachePrefix . $cellID . '.cache', $obj, null, $this->_cacheTime)) { + if (!$this->memcache->add($newCachePrefix . $cellID . '.cache', $obj, null, $this->cacheTime)) { $this->__destruct(); throw new PHPExcel_Exception("Failed to store cell {$cellID} in MemCache"); } } } - $this->_cachePrefix = $newCachePrefix; + $this->cachePrefix = $newCachePrefix; } /** @@ -227,18 +227,18 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) */ public function unsetWorksheetCells() { - if (!is_null($this->_currentObject)) { - $this->_currentObject->detach(); - $this->_currentObject = $this->_currentObjectID = null; + if (!is_null($this->currentObject)) { + $this->currentObject->detach(); + $this->currentObject = $this->currentObjectID = null; } // Flush the Memcache cache $this->__destruct(); - $this->_cellCache = array(); + $this->cellCache = array(); // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; } /** @@ -253,16 +253,16 @@ public function __construct(PHPExcel_Worksheet $parent, $arguments) $memcachePort = (isset($arguments['memcachePort'])) ? $arguments['memcachePort'] : 11211; $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; - if (is_null($this->_cachePrefix)) { - $baseUnique = $this->_getUniqueID(); - $this->_cachePrefix = substr(md5($baseUnique), 0, 8) . '.'; + if (is_null($this->cachePrefix)) { + $baseUnique = $this->getUniqueID(); + $this->cachePrefix = substr(md5($baseUnique), 0, 8) . '.'; // Set a new Memcache object and connect to the Memcache server - $this->_memcache = new Memcache(); - if (!$this->_memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) { + $this->memcache = new Memcache(); + if (!$this->memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) { throw new PHPExcel_Exception("Could not connect to MemCache server at {$memcacheServer}:{$memcachePort}"); } - $this->_cacheTime = $cacheTime; + $this->cacheTime = $cacheTime; parent::__construct($parent); } @@ -287,7 +287,7 @@ public function __destruct() { $cacheList = $this->getCellList(); foreach ($cacheList as $cellID) { - $this->_memcache->delete($this->_cachePrefix.$cellID . '.cache'); + $this->memcache->delete($this->cachePrefix.$cellID . '.cache'); } } diff --git a/Classes/PHPExcel/CachedObjectStorage/Memory.php b/Classes/PHPExcel/CachedObjectStorage/Memory.php index aa3e1bb3d..0e2ea0b07 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Memory.php +++ b/Classes/PHPExcel/CachedObjectStorage/Memory.php @@ -32,7 +32,7 @@ class PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_C * * @return void */ - protected function _storeData() + protected function storeData() { } @@ -46,10 +46,10 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - $this->_cellCache[$pCoord] = $cell; + $this->cellCache[$pCoord] = $cell; // Set current entry to the new/updated entry - $this->_currentObjectID = $pCoord; + $this->currentObjectID = $pCoord; return $cell; } @@ -65,17 +65,17 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) public function getCacheData($pCoord) { // Check if the entry that has been requested actually exists - if (!isset($this->_cellCache[$pCoord])) { - $this->_currentObjectID = null; + if (!isset($this->cellCache[$pCoord])) { + $this->currentObjectID = null; // Return null if requested entry doesn't exist in cache return null; } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; + $this->currentObjectID = $pCoord; // Return requested entry - return $this->_cellCache[$pCoord]; + return $this->cellCache[$pCoord]; } @@ -89,12 +89,12 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) parent::copyCellCollection($parent); $newCollection = array(); - foreach ($this->_cellCache as $k => &$cell) { + foreach ($this->cellCache as $k => &$cell) { $newCollection[$k] = clone $cell; $newCollection[$k]->attach($this); } - $this->_cellCache = $newCollection; + $this->cellCache = $newCollection; } /** @@ -104,15 +104,15 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) public function unsetWorksheetCells() { // Because cells are all stored as intact objects in memory, we need to detach each one from the parent - foreach ($this->_cellCache as $k => &$cell) { + foreach ($this->cellCache as $k => &$cell) { $cell->detach(); - $this->_cellCache[$k] = null; + $this->cellCache[$k] = null; } unset($cell); - $this->_cellCache = array(); + $this->cellCache = array(); // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; } } diff --git a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php index 16f010516..c06ec714f 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php @@ -34,15 +34,15 @@ class PHPExcel_CachedObjectStorage_MemoryGZip extends PHPExcel_CachedObjectStora * @return void * @throws PHPExcel_Exception */ - protected function _storeData() + protected function storeData() { - if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { - $this->_currentObject->detach(); + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { + $this->currentObject->detach(); - $this->_cellCache[$this->_currentObjectID] = gzdeflate(serialize($this->_currentObject)); - $this->_currentCellIsDirty = false; + $this->cellCache[$this->currentObjectID] = gzdeflate(serialize($this->currentObject)); + $this->currentCellIsDirty = false; } - $this->_currentObjectID = $this->_currentObject = null; + $this->currentObjectID = $this->currentObject = null; } @@ -56,13 +56,13 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { - $this->_storeData(); + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { + $this->storeData(); } - $this->_currentObjectID = $pCoord; - $this->_currentObject = $cell; - $this->_currentCellIsDirty = true; + $this->currentObjectID = $pCoord; + $this->currentObject = $cell; + $this->currentCellIsDirty = true; return $cell; } @@ -77,25 +77,25 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) */ public function getCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - return $this->_currentObject; + if ($pCoord === $this->currentObjectID) { + return $this->currentObject; } - $this->_storeData(); + $this->storeData(); // Check if the entry that has been requested actually exists - if (!isset($this->_cellCache[$pCoord])) { + if (!isset($this->cellCache[$pCoord])) { // Return null if requested entry doesn't exist in cache return null; } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; - $this->_currentObject = unserialize(gzinflate($this->_cellCache[$pCoord])); + $this->currentObjectID = $pCoord; + $this->currentObject = unserialize(gzinflate($this->cellCache[$pCoord])); // Re-attach this as the cell's parent - $this->_currentObject->attach($this); + $this->currentObject->attach($this); // Return requested entry - return $this->_currentObject; + return $this->currentObject; } @@ -106,8 +106,8 @@ public function getCacheData($pCoord) */ public function getCellList() { - if ($this->_currentObjectID !== null) { - $this->_storeData(); + if ($this->currentObjectID !== null) { + $this->storeData(); } return parent::getCellList(); @@ -121,13 +121,13 @@ public function getCellList() */ public function unsetWorksheetCells() { - if (!is_null($this->_currentObject)) { - $this->_currentObject->detach(); - $this->_currentObject = $this->_currentObjectID = null; + if (!is_null($this->currentObject)) { + $this->currentObject->detach(); + $this->currentObject = $this->currentObjectID = null; } - $this->_cellCache = array(); + $this->cellCache = array(); // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; } } diff --git a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php index 285d0d8fa..133251499 100644 --- a/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php +++ b/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php @@ -34,15 +34,15 @@ class PHPExcel_CachedObjectStorage_MemorySerialized extends PHPExcel_CachedObjec * @return void * @throws PHPExcel_Exception */ - protected function _storeData() + protected function storeData() { - if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { - $this->_currentObject->detach(); + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { + $this->currentObject->detach(); - $this->_cellCache[$this->_currentObjectID] = serialize($this->_currentObject); - $this->_currentCellIsDirty = false; + $this->cellCache[$this->currentObjectID] = serialize($this->currentObject); + $this->currentCellIsDirty = false; } - $this->_currentObjectID = $this->_currentObject = null; + $this->currentObjectID = $this->currentObject = null; } /** @@ -55,13 +55,13 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { - $this->_storeData(); + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { + $this->storeData(); } - $this->_currentObjectID = $pCoord; - $this->_currentObject = $cell; - $this->_currentCellIsDirty = true; + $this->currentObjectID = $pCoord; + $this->currentObject = $cell; + $this->currentCellIsDirty = true; return $cell; } @@ -75,25 +75,25 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) */ public function getCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - return $this->_currentObject; + if ($pCoord === $this->currentObjectID) { + return $this->currentObject; } - $this->_storeData(); + $this->storeData(); // Check if the entry that has been requested actually exists - if (!isset($this->_cellCache[$pCoord])) { + if (!isset($this->cellCache[$pCoord])) { // Return null if requested entry doesn't exist in cache return null; } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; - $this->_currentObject = unserialize($this->_cellCache[$pCoord]); + $this->currentObjectID = $pCoord; + $this->currentObject = unserialize($this->cellCache[$pCoord]); // Re-attach this as the cell's parent - $this->_currentObject->attach($this); + $this->currentObject->attach($this); // Return requested entry - return $this->_currentObject; + return $this->currentObject; } /** @@ -103,8 +103,8 @@ public function getCacheData($pCoord) */ public function getCellList() { - if ($this->_currentObjectID !== null) { - $this->_storeData(); + if ($this->currentObjectID !== null) { + $this->storeData(); } return parent::getCellList(); @@ -117,13 +117,13 @@ public function getCellList() */ public function unsetWorksheetCells() { - if (!is_null($this->_currentObject)) { - $this->_currentObject->detach(); - $this->_currentObject = $this->_currentObjectID = null; + if (!is_null($this->currentObject)) { + $this->currentObject->detach(); + $this->currentObject = $this->currentObjectID = null; } - $this->_cellCache = array(); + $this->cellCache = array(); // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; } } diff --git a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php index 6176bf1e9..43c781971 100644 --- a/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php +++ b/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php @@ -32,14 +32,14 @@ class PHPExcel_CachedObjectStorage_PHPTemp extends PHPExcel_CachedObjectStorage_ * * @var string */ - private $_fileHandle = null; + private $fileHandle = null; /** * Memory limit to use before reverting to file cache * * @var integer */ - private $_memoryCacheSize = null; + private $memoryCacheSize = null; /** * Store cell data in cache for the current cell object if it's "dirty", @@ -48,20 +48,20 @@ class PHPExcel_CachedObjectStorage_PHPTemp extends PHPExcel_CachedObjectStorage_ * @return void * @throws PHPExcel_Exception */ - protected function _storeData() + protected function storeData() { - if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { - $this->_currentObject->detach(); + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { + $this->currentObject->detach(); - fseek($this->_fileHandle, 0, SEEK_END); + fseek($this->fileHandle, 0, SEEK_END); - $this->_cellCache[$this->_currentObjectID] = array( - 'ptr' => ftell($this->_fileHandle), - 'sz' => fwrite($this->_fileHandle, serialize($this->_currentObject)) + $this->cellCache[$this->currentObjectID] = array( + 'ptr' => ftell($this->fileHandle), + 'sz' => fwrite($this->fileHandle, serialize($this->currentObject)) ); - $this->_currentCellIsDirty = false; + $this->currentCellIsDirty = false; } - $this->_currentObjectID = $this->_currentObject = null; + $this->currentObjectID = $this->currentObject = null; } @@ -75,13 +75,13 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { - $this->_storeData(); + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { + $this->storeData(); } - $this->_currentObjectID = $pCoord; - $this->_currentObject = $cell; - $this->_currentCellIsDirty = true; + $this->currentObjectID = $pCoord; + $this->currentObject = $cell; + $this->currentCellIsDirty = true; return $cell; } @@ -96,26 +96,26 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) */ public function getCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - return $this->_currentObject; + if ($pCoord === $this->currentObjectID) { + return $this->currentObject; } - $this->_storeData(); + $this->storeData(); // Check if the entry that has been requested actually exists - if (!isset($this->_cellCache[$pCoord])) { + if (!isset($this->cellCache[$pCoord])) { // Return null if requested entry doesn't exist in cache return null; } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; - fseek($this->_fileHandle, $this->_cellCache[$pCoord]['ptr']); - $this->_currentObject = unserialize(fread($this->_fileHandle, $this->_cellCache[$pCoord]['sz'])); + $this->currentObjectID = $pCoord; + fseek($this->fileHandle, $this->cellCache[$pCoord]['ptr']); + $this->currentObject = unserialize(fread($this->fileHandle, $this->cellCache[$pCoord]['sz'])); // Re-attach this as the cell's parent - $this->_currentObject->attach($this); + $this->currentObject->attach($this); // Return requested entry - return $this->_currentObject; + return $this->currentObject; } /** @@ -125,8 +125,8 @@ public function getCacheData($pCoord) */ public function getCellList() { - if ($this->_currentObjectID !== null) { - $this->_storeData(); + if ($this->currentObjectID !== null) { + $this->storeData(); } return parent::getCellList(); @@ -142,13 +142,13 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) { parent::copyCellCollection($parent); // Open a new stream for the cell cache data - $newFileHandle = fopen('php://temp/maxmemory:' . $this->_memoryCacheSize, 'a+'); + $newFileHandle = fopen('php://temp/maxmemory:' . $this->memoryCacheSize, 'a+'); // Copy the existing cell cache data to the new stream - fseek($this->_fileHandle, 0); - while (!feof($this->_fileHandle)) { - fwrite($newFileHandle, fread($this->_fileHandle, 1024)); + fseek($this->fileHandle, 0); + while (!feof($this->fileHandle)) { + fwrite($newFileHandle, fread($this->fileHandle, 1024)); } - $this->_fileHandle = $newFileHandle; + $this->fileHandle = $newFileHandle; } /** @@ -158,14 +158,14 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) */ public function unsetWorksheetCells() { - if (!is_null($this->_currentObject)) { - $this->_currentObject->detach(); - $this->_currentObject = $this->_currentObjectID = null; + if (!is_null($this->currentObject)) { + $this->currentObject->detach(); + $this->currentObject = $this->currentObjectID = null; } - $this->_cellCache = array(); + $this->cellCache = array(); // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; // Close down the php://temp file $this->__destruct(); @@ -179,11 +179,11 @@ public function unsetWorksheetCells() */ public function __construct(PHPExcel_Worksheet $parent, $arguments) { - $this->_memoryCacheSize = (isset($arguments['memoryCacheSize'])) ? $arguments['memoryCacheSize'] : '1MB'; + $this->memoryCacheSize = (isset($arguments['memoryCacheSize'])) ? $arguments['memoryCacheSize'] : '1MB'; parent::__construct($parent); - if (is_null($this->_fileHandle)) { - $this->_fileHandle = fopen('php://temp/maxmemory:' . $this->_memoryCacheSize, 'a+'); + if (is_null($this->fileHandle)) { + $this->fileHandle = fopen('php://temp/maxmemory:' . $this->memoryCacheSize, 'a+'); } } @@ -192,9 +192,9 @@ public function __construct(PHPExcel_Worksheet $parent, $arguments) */ public function __destruct() { - if (!is_null($this->_fileHandle)) { - fclose($this->_fileHandle); + if (!is_null($this->fileHandle)) { + fclose($this->fileHandle); } - $this->_fileHandle = null; + $this->fileHandle = null; } } diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite.php b/Classes/PHPExcel/CachedObjectStorage/SQLite.php index 0a63cd2d8..e7b50c5bd 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite.php @@ -32,14 +32,14 @@ class PHPExcel_CachedObjectStorage_SQLite extends PHPExcel_CachedObjectStorage_C * * @var string */ - private $_TableName = null; + private $TableName = null; /** * Database handle * * @var resource */ - private $_DBHandle = null; + private $DBHandle = null; /** * Store cell data in cache for the current cell object if it's "dirty", @@ -48,17 +48,17 @@ class PHPExcel_CachedObjectStorage_SQLite extends PHPExcel_CachedObjectStorage_C * @return void * @throws PHPExcel_Exception */ - protected function _storeData() + protected function storeData() { - if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { - $this->_currentObject->detach(); + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { + $this->currentObject->detach(); - if (!$this->_DBHandle->queryExec("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES('".$this->_currentObjectID."','".sqlite_escape_string(serialize($this->_currentObject))."')")) { - throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + if (!$this->DBHandle->queryExec("INSERT OR REPLACE INTO kvp_".$this->TableName." VALUES('".$this->currentObjectID."','".sqlite_escape_string(serialize($this->currentObject))."')")) { + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); } - $this->_currentCellIsDirty = false; + $this->currentCellIsDirty = false; } - $this->_currentObjectID = $this->_currentObject = null; + $this->currentObjectID = $this->currentObject = null; } /** @@ -71,13 +71,13 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { - $this->_storeData(); + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { + $this->storeData(); } - $this->_currentObjectID = $pCoord; - $this->_currentObject = $cell; - $this->_currentCellIsDirty = true; + $this->currentObjectID = $pCoord; + $this->currentObject = $cell; + $this->currentCellIsDirty = true; return $cell; } @@ -91,30 +91,30 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) */ public function getCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - return $this->_currentObject; + if ($pCoord === $this->currentObjectID) { + return $this->currentObject; } - $this->_storeData(); + $this->storeData(); - $query = "SELECT value FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; - $cellResultSet = $this->_DBHandle->query($query, SQLITE_ASSOC); + $query = "SELECT value FROM kvp_".$this->TableName." WHERE id='".$pCoord."'"; + $cellResultSet = $this->DBHandle->query($query, SQLITE_ASSOC); if ($cellResultSet === false) { - throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); } elseif ($cellResultSet->numRows() == 0) { // Return null if requested entry doesn't exist in cache return null; } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; + $this->currentObjectID = $pCoord; $cellResult = $cellResultSet->fetchSingle(); - $this->_currentObject = unserialize($cellResult); + $this->currentObject = unserialize($cellResult); // Re-attach this as the cell's parent - $this->_currentObject->attach($this); + $this->currentObject->attach($this); // Return requested entry - return $this->_currentObject; + return $this->currentObject; } /** @@ -125,15 +125,15 @@ public function getCacheData($pCoord) */ public function isDataSet($pCoord) { - if ($pCoord === $this->_currentObjectID) { + if ($pCoord === $this->currentObjectID) { return true; } // Check if the requested entry exists in the cache - $query = "SELECT id FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; - $cellResultSet = $this->_DBHandle->query($query, SQLITE_ASSOC); + $query = "SELECT id FROM kvp_".$this->TableName." WHERE id='".$pCoord."'"; + $cellResultSet = $this->DBHandle->query($query, SQLITE_ASSOC); if ($cellResultSet === false) { - throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); } elseif ($cellResultSet->numRows() == 0) { // Return null if requested entry doesn't exist in cache return false; @@ -149,18 +149,18 @@ public function isDataSet($pCoord) */ public function deleteCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - $this->_currentObject->detach(); - $this->_currentObjectID = $this->_currentObject = null; + if ($pCoord === $this->currentObjectID) { + $this->currentObject->detach(); + $this->currentObjectID = $this->currentObject = null; } // Check if the requested entry exists in the cache - $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; - if (!$this->_DBHandle->queryExec($query)) { - throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + $query = "DELETE FROM kvp_".$this->TableName." WHERE id='".$pCoord."'"; + if (!$this->DBHandle->queryExec($query)) { + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); } - $this->_currentCellIsDirty = false; + $this->currentCellIsDirty = false; } /** @@ -172,20 +172,20 @@ public function deleteCacheData($pCoord) */ public function moveCell($fromAddress, $toAddress) { - if ($fromAddress === $this->_currentObjectID) { - $this->_currentObjectID = $toAddress; + if ($fromAddress === $this->currentObjectID) { + $this->currentObjectID = $toAddress; } - $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$toAddress."'"; - $result = $this->_DBHandle->exec($query); + $query = "DELETE FROM kvp_".$this->TableName." WHERE id='".$toAddress."'"; + $result = $this->DBHandle->exec($query); if ($result === false) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } - $query = "UPDATE kvp_".$this->_TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'"; - $result = $this->_DBHandle->exec($query); + $query = "UPDATE kvp_".$this->TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'"; + $result = $this->DBHandle->exec($query); if ($result === false) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } return true; @@ -198,14 +198,14 @@ public function moveCell($fromAddress, $toAddress) */ public function getCellList() { - if ($this->_currentObjectID !== null) { - $this->_storeData(); + if ($this->currentObjectID !== null) { + $this->storeData(); } - $query = "SELECT id FROM kvp_".$this->_TableName; - $cellIdsResult = $this->_DBHandle->unbufferedQuery($query, SQLITE_ASSOC); + $query = "SELECT id FROM kvp_".$this->TableName; + $cellIdsResult = $this->DBHandle->unbufferedQuery($query, SQLITE_ASSOC); if ($cellIdsResult === false) { - throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); } $cellKeys = array(); @@ -224,19 +224,19 @@ public function getCellList() */ public function copyCellCollection(PHPExcel_Worksheet $parent) { - $this->_currentCellIsDirty; - $this->_storeData(); + $this->currentCellIsDirty; + $this->storeData(); // Get a new id for the new table name - $tableName = str_replace('.', '_', $this->_getUniqueID()); - if (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) - AS SELECT * FROM kvp_'.$this->_TableName) + $tableName = str_replace('.', '_', $this->getUniqueID()); + if (!$this->DBHandle->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) + AS SELECT * FROM kvp_'.$this->TableName) ) { - throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); } // Copy the existing cell cache file - $this->_TableName = $tableName; + $this->TableName = $tableName; } /** @@ -246,12 +246,12 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) */ public function unsetWorksheetCells() { - if (!is_null($this->_currentObject)) { - $this->_currentObject->detach(); - $this->_currentObject = $this->_currentObjectID = null; + if (!is_null($this->currentObject)) { + $this->currentObject->detach(); + $this->currentObject = $this->currentObjectID = null; } // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; // Close down the temporary cache file $this->__destruct(); @@ -265,16 +265,16 @@ public function unsetWorksheetCells() public function __construct(PHPExcel_Worksheet $parent) { parent::__construct($parent); - if (is_null($this->_DBHandle)) { - $this->_TableName = str_replace('.', '_', $this->_getUniqueID()); + if (is_null($this->DBHandle)) { + $this->TableName = str_replace('.', '_', $this->getUniqueID()); $_DBName = ':memory:'; - $this->_DBHandle = new SQLiteDatabase($_DBName); - if ($this->_DBHandle === false) { - throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + $this->DBHandle = new SQLiteDatabase($_DBName); + if ($this->DBHandle === false) { + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); } - if (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) { - throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + if (!$this->DBHandle->queryExec('CREATE TABLE kvp_'.$this->TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) { + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); } } } @@ -284,10 +284,10 @@ public function __construct(PHPExcel_Worksheet $parent) */ public function __destruct() { - if (!is_null($this->_DBHandle)) { - $this->_DBHandle->queryExec('DROP TABLE kvp_'.$this->_TableName); + if (!is_null($this->DBHandle)) { + $this->DBHandle->queryExec('DROP TABLE kvp_'.$this->TableName); } - $this->_DBHandle = null; + $this->DBHandle = null; } /** diff --git a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php index 4d013eff6..27473d6c3 100644 --- a/Classes/PHPExcel/CachedObjectStorage/SQLite3.php +++ b/Classes/PHPExcel/CachedObjectStorage/SQLite3.php @@ -32,42 +32,42 @@ class PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_ * * @var string */ - private $_TableName = null; + private $TableName = null; /** * Database handle * * @var resource */ - private $_DBHandle = null; + private $DBHandle = null; /** * Prepared statement for a SQLite3 select query * * @var SQLite3Stmt */ - private $_selectQuery; + private $selectQuery; /** * Prepared statement for a SQLite3 insert query * * @var SQLite3Stmt */ - private $_insertQuery; + private $insertQuery; /** * Prepared statement for a SQLite3 update query * * @var SQLite3Stmt */ - private $_updateQuery; + private $updateQuery; /** * Prepared statement for a SQLite3 delete query * * @var SQLite3Stmt */ - private $_deleteQuery; + private $deleteQuery; /** * Store cell data in cache for the current cell object if it's "dirty", @@ -76,20 +76,20 @@ class PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_ * @return void * @throws PHPExcel_Exception */ - protected function _storeData() + protected function storeData() { - if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { - $this->_currentObject->detach(); + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { + $this->currentObject->detach(); - $this->_insertQuery->bindValue('id', $this->_currentObjectID, SQLITE3_TEXT); - $this->_insertQuery->bindValue('data', serialize($this->_currentObject), SQLITE3_BLOB); - $result = $this->_insertQuery->execute(); + $this->insertQuery->bindValue('id', $this->currentObjectID, SQLITE3_TEXT); + $this->insertQuery->bindValue('data', serialize($this->currentObject), SQLITE3_BLOB); + $result = $this->insertQuery->execute(); if ($result === false) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } - $this->_currentCellIsDirty = false; + $this->currentCellIsDirty = false; } - $this->_currentObjectID = $this->_currentObject = null; + $this->currentObjectID = $this->currentObject = null; } /** @@ -102,13 +102,13 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { - $this->_storeData(); + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { + $this->storeData(); } - $this->_currentObjectID = $pCoord; - $this->_currentObject = $cell; - $this->_currentCellIsDirty = true; + $this->currentObjectID = $pCoord; + $this->currentObject = $cell; + $this->currentCellIsDirty = true; return $cell; } @@ -122,15 +122,15 @@ public function addCacheData($pCoord, PHPExcel_Cell $cell) */ public function getCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - return $this->_currentObject; + if ($pCoord === $this->currentObjectID) { + return $this->currentObject; } - $this->_storeData(); + $this->storeData(); - $this->_selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT); - $cellResult = $this->_selectQuery->execute(); + $this->selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT); + $cellResult = $this->selectQuery->execute(); if ($cellResult === false) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } $cellData = $cellResult->fetchArray(SQLITE3_ASSOC); if ($cellData === false) { @@ -139,14 +139,14 @@ public function getCacheData($pCoord) } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; + $this->currentObjectID = $pCoord; - $this->_currentObject = unserialize($cellData['value']); + $this->currentObject = unserialize($cellData['value']); // Re-attach this as the cell's parent - $this->_currentObject->attach($this); + $this->currentObject->attach($this); // Return requested entry - return $this->_currentObject; + return $this->currentObject; } /** @@ -157,15 +157,15 @@ public function getCacheData($pCoord) */ public function isDataSet($pCoord) { - if ($pCoord === $this->_currentObjectID) { + if ($pCoord === $this->currentObjectID) { return true; } // Check if the requested entry exists in the cache - $this->_selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT); - $cellResult = $this->_selectQuery->execute(); + $this->selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT); + $cellResult = $this->selectQuery->execute(); if ($cellResult === false) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } $cellData = $cellResult->fetchArray(SQLITE3_ASSOC); @@ -180,19 +180,19 @@ public function isDataSet($pCoord) */ public function deleteCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - $this->_currentObject->detach(); - $this->_currentObjectID = $this->_currentObject = null; + if ($pCoord === $this->currentObjectID) { + $this->currentObject->detach(); + $this->currentObjectID = $this->currentObject = null; } // Check if the requested entry exists in the cache - $this->_deleteQuery->bindValue('id', $pCoord, SQLITE3_TEXT); - $result = $this->_deleteQuery->execute(); + $this->deleteQuery->bindValue('id', $pCoord, SQLITE3_TEXT); + $result = $this->deleteQuery->execute(); if ($result === false) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } - $this->_currentCellIsDirty = false; + $this->currentCellIsDirty = false; } /** @@ -204,21 +204,21 @@ public function deleteCacheData($pCoord) */ public function moveCell($fromAddress, $toAddress) { - if ($fromAddress === $this->_currentObjectID) { - $this->_currentObjectID = $toAddress; + if ($fromAddress === $this->currentObjectID) { + $this->currentObjectID = $toAddress; } - $this->_deleteQuery->bindValue('id', $toAddress, SQLITE3_TEXT); - $result = $this->_deleteQuery->execute(); + $this->deleteQuery->bindValue('id', $toAddress, SQLITE3_TEXT); + $result = $this->deleteQuery->execute(); if ($result === false) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } - $this->_updateQuery->bindValue('toid', $toAddress, SQLITE3_TEXT); - $this->_updateQuery->bindValue('fromid', $fromAddress, SQLITE3_TEXT); - $result = $this->_updateQuery->execute(); + $this->updateQuery->bindValue('toid', $toAddress, SQLITE3_TEXT); + $this->updateQuery->bindValue('fromid', $fromAddress, SQLITE3_TEXT); + $result = $this->updateQuery->execute(); if ($result === false) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } return true; @@ -231,14 +231,14 @@ public function moveCell($fromAddress, $toAddress) */ public function getCellList() { - if ($this->_currentObjectID !== null) { - $this->_storeData(); + if ($this->currentObjectID !== null) { + $this->storeData(); } - $query = "SELECT id FROM kvp_".$this->_TableName; - $cellIdsResult = $this->_DBHandle->query($query); + $query = "SELECT id FROM kvp_".$this->TableName; + $cellIdsResult = $this->DBHandle->query($query); if ($cellIdsResult === false) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } $cellKeys = array(); @@ -257,19 +257,19 @@ public function getCellList() */ public function copyCellCollection(PHPExcel_Worksheet $parent) { - $this->_currentCellIsDirty; - $this->_storeData(); + $this->currentCellIsDirty; + $this->storeData(); // Get a new id for the new table name - $tableName = str_replace('.', '_', $this->_getUniqueID()); - if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) - AS SELECT * FROM kvp_'.$this->_TableName) + $tableName = str_replace('.', '_', $this->getUniqueID()); + if (!$this->DBHandle->exec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) + AS SELECT * FROM kvp_'.$this->TableName) ) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } // Copy the existing cell cache file - $this->_TableName = $tableName; + $this->TableName = $tableName; } /** @@ -279,12 +279,12 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) */ public function unsetWorksheetCells() { - if (!is_null($this->_currentObject)) { - $this->_currentObject->detach(); - $this->_currentObject = $this->_currentObjectID = null; + if (!is_null($this->currentObject)) { + $this->currentObject->detach(); + $this->currentObject = $this->currentObjectID = null; } // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; // Close down the temporary cache file $this->__destruct(); @@ -298,23 +298,23 @@ public function unsetWorksheetCells() public function __construct(PHPExcel_Worksheet $parent) { parent::__construct($parent); - if (is_null($this->_DBHandle)) { - $this->_TableName = str_replace('.', '_', $this->_getUniqueID()); + if (is_null($this->DBHandle)) { + $this->TableName = str_replace('.', '_', $this->getUniqueID()); $_DBName = ':memory:'; - $this->_DBHandle = new SQLite3($_DBName); - if ($this->_DBHandle === false) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + $this->DBHandle = new SQLite3($_DBName); + if ($this->DBHandle === false) { + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } - if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) { - throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + if (!$this->DBHandle->exec('CREATE TABLE kvp_'.$this->TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) { + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); } } - $this->_selectQuery = $this->_DBHandle->prepare("SELECT value FROM kvp_".$this->_TableName." WHERE id = :id"); - $this->_insertQuery = $this->_DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES(:id,:data)"); - $this->_updateQuery = $this->_DBHandle->prepare("UPDATE kvp_".$this->_TableName." SET id=:toId WHERE id=:fromId"); - $this->_deleteQuery = $this->_DBHandle->prepare("DELETE FROM kvp_".$this->_TableName." WHERE id = :id"); + $this->selectQuery = $this->DBHandle->prepare("SELECT value FROM kvp_".$this->TableName." WHERE id = :id"); + $this->insertQuery = $this->DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->TableName." VALUES(:id,:data)"); + $this->updateQuery = $this->DBHandle->prepare("UPDATE kvp_".$this->TableName." SET id=:toId WHERE id=:fromId"); + $this->deleteQuery = $this->DBHandle->prepare("DELETE FROM kvp_".$this->TableName." WHERE id = :id"); } /** @@ -322,11 +322,11 @@ public function __construct(PHPExcel_Worksheet $parent) */ public function __destruct() { - if (!is_null($this->_DBHandle)) { - $this->_DBHandle->exec('DROP TABLE kvp_'.$this->_TableName); - $this->_DBHandle->close(); + if (!is_null($this->DBHandle)) { + $this->DBHandle->exec('DROP TABLE kvp_'.$this->TableName); + $this->DBHandle->close(); } - $this->_DBHandle = null; + $this->DBHandle = null; } /** diff --git a/Classes/PHPExcel/CachedObjectStorage/Wincache.php b/Classes/PHPExcel/CachedObjectStorage/Wincache.php index 5b1fc43dc..1567874ff 100644 --- a/Classes/PHPExcel/CachedObjectStorage/Wincache.php +++ b/Classes/PHPExcel/CachedObjectStorage/Wincache.php @@ -32,14 +32,14 @@ class PHPExcel_CachedObjectStorage_Wincache extends PHPExcel_CachedObjectStorage * * @var string */ - private $_cachePrefix = null; + private $cachePrefix = null; /** * Cache timeout * * @var integer */ - private $_cacheTime = 600; + private $cacheTime = 600; /** @@ -49,27 +49,27 @@ class PHPExcel_CachedObjectStorage_Wincache extends PHPExcel_CachedObjectStorage * @return void * @throws PHPExcel_Exception */ - protected function _storeData() + protected function storeData() { - if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { - $this->_currentObject->detach(); + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { + $this->currentObject->detach(); - $obj = serialize($this->_currentObject); - if (wincache_ucache_exists($this->_cachePrefix.$this->_currentObjectID.'.cache')) { - if (!wincache_ucache_set($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) { + $obj = serialize($this->currentObject); + if (wincache_ucache_exists($this->cachePrefix.$this->currentObjectID.'.cache')) { + if (!wincache_ucache_set($this->cachePrefix.$this->currentObjectID.'.cache', $obj, $this->cacheTime)) { $this->__destruct(); - throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache'); + throw new PHPExcel_Exception('Failed to store cell '.$this->currentObjectID.' in WinCache'); } } else { - if (!wincache_ucache_add($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) { + if (!wincache_ucache_add($this->cachePrefix.$this->currentObjectID.'.cache', $obj, $this->cacheTime)) { $this->__destruct(); - throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache'); + throw new PHPExcel_Exception('Failed to store cell '.$this->currentObjectID.' in WinCache'); } } - $this->_currentCellIsDirty = false; + $this->currentCellIsDirty = false; } - $this->_currentObjectID = $this->_currentObject = null; + $this->currentObjectID = $this->currentObject = null; } /** @@ -82,14 +82,14 @@ protected function _storeData() */ public function addCacheData($pCoord, PHPExcel_Cell $cell) { - if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { - $this->_storeData(); + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { + $this->storeData(); } - $this->_cellCache[$pCoord] = true; + $this->cellCache[$pCoord] = true; - $this->_currentObjectID = $pCoord; - $this->_currentObject = $cell; - $this->_currentCellIsDirty = true; + $this->currentObjectID = $pCoord; + $this->currentObject = $cell; + $this->currentCellIsDirty = true; return $cell; } @@ -104,11 +104,11 @@ public function isDataSet($pCoord) { // Check if the requested entry is the current object, or exists in the cache if (parent::isDataSet($pCoord)) { - if ($this->_currentObjectID == $pCoord) { + if ($this->currentObjectID == $pCoord) { return true; } // Check if the requested entry still exists in cache - $success = wincache_ucache_exists($this->_cachePrefix.$pCoord.'.cache'); + $success = wincache_ucache_exists($this->cachePrefix.$pCoord.'.cache'); if ($success === false) { // Entry no longer exists in Wincache, so clear it from the cache array parent::deleteCacheData($pCoord); @@ -129,16 +129,16 @@ public function isDataSet($pCoord) */ public function getCacheData($pCoord) { - if ($pCoord === $this->_currentObjectID) { - return $this->_currentObject; + if ($pCoord === $this->currentObjectID) { + return $this->currentObject; } - $this->_storeData(); + $this->storeData(); // Check if the entry that has been requested actually exists $obj = null; if (parent::isDataSet($pCoord)) { $success = false; - $obj = wincache_ucache_get($this->_cachePrefix.$pCoord.'.cache', $success); + $obj = wincache_ucache_get($this->cachePrefix.$pCoord.'.cache', $success); if ($success === false) { // Entry no longer exists in WinCache, so clear it from the cache array parent::deleteCacheData($pCoord); @@ -150,13 +150,13 @@ public function getCacheData($pCoord) } // Set current entry to the requested entry - $this->_currentObjectID = $pCoord; - $this->_currentObject = unserialize($obj); + $this->currentObjectID = $pCoord; + $this->currentObject = unserialize($obj); // Re-attach this as the cell's parent - $this->_currentObject->attach($this); + $this->currentObject->attach($this); // Return requested entry - return $this->_currentObject; + return $this->currentObject; } @@ -167,8 +167,8 @@ public function getCacheData($pCoord) */ public function getCellList() { - if ($this->_currentObjectID !== null) { - $this->_storeData(); + if ($this->currentObjectID !== null) { + $this->storeData(); } return parent::getCellList(); @@ -183,7 +183,7 @@ public function getCellList() public function deleteCacheData($pCoord) { // Delete the entry from Wincache - wincache_ucache_delete($this->_cachePrefix.$pCoord.'.cache'); + wincache_ucache_delete($this->cachePrefix.$pCoord.'.cache'); // Delete the entry from our cell address array parent::deleteCacheData($pCoord); @@ -199,25 +199,25 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) { parent::copyCellCollection($parent); // Get a new id for the new file name - $baseUnique = $this->_getUniqueID(); + $baseUnique = $this->getUniqueID(); $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.'; $cacheList = $this->getCellList(); foreach ($cacheList as $cellID) { - if ($cellID != $this->_currentObjectID) { + if ($cellID != $this->currentObjectID) { $success = false; - $obj = wincache_ucache_get($this->_cachePrefix.$cellID.'.cache', $success); + $obj = wincache_ucache_get($this->cachePrefix.$cellID.'.cache', $success); if ($success === false) { // Entry no longer exists in WinCache, so clear it from the cache array parent::deleteCacheData($cellID); throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in Wincache'); } - if (!wincache_ucache_add($newCachePrefix.$cellID.'.cache', $obj, $this->_cacheTime)) { + if (!wincache_ucache_add($newCachePrefix.$cellID.'.cache', $obj, $this->cacheTime)) { $this->__destruct(); throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in Wincache'); } } } - $this->_cachePrefix = $newCachePrefix; + $this->cachePrefix = $newCachePrefix; } @@ -228,18 +228,18 @@ public function copyCellCollection(PHPExcel_Worksheet $parent) */ public function unsetWorksheetCells() { - if (!is_null($this->_currentObject)) { - $this->_currentObject->detach(); - $this->_currentObject = $this->_currentObjectID = null; + if (!is_null($this->currentObject)) { + $this->currentObject->detach(); + $this->currentObject = $this->currentObjectID = null; } // Flush the WinCache cache $this->__destruct(); - $this->_cellCache = array(); + $this->cellCache = array(); // detach ourself from the worksheet, so that it can then delete this object successfully - $this->_parent = null; + $this->parent = null; } /** @@ -252,10 +252,10 @@ public function __construct(PHPExcel_Worksheet $parent, $arguments) { $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; - if (is_null($this->_cachePrefix)) { - $baseUnique = $this->_getUniqueID(); - $this->_cachePrefix = substr(md5($baseUnique), 0, 8).'.'; - $this->_cacheTime = $cacheTime; + if (is_null($this->cachePrefix)) { + $baseUnique = $this->getUniqueID(); + $this->cachePrefix = substr(md5($baseUnique), 0, 8).'.'; + $this->cacheTime = $cacheTime; parent::__construct($parent); } @@ -268,7 +268,7 @@ public function __destruct() { $cacheList = $this->getCellList(); foreach ($cacheList as $cellID) { - wincache_ucache_delete($this->_cachePrefix.$cellID.'.cache'); + wincache_ucache_delete($this->cachePrefix.$cellID.'.cache'); } } diff --git a/Classes/PHPExcel/CachedObjectStorageFactory.php b/Classes/PHPExcel/CachedObjectStorageFactory.php index 251c3ef85..0a969786e 100644 --- a/Classes/PHPExcel/CachedObjectStorageFactory.php +++ b/Classes/PHPExcel/CachedObjectStorageFactory.php @@ -44,21 +44,21 @@ class PHPExcel_CachedObjectStorageFactory * * @var string */ - private static $_cacheStorageMethod = null; + private static $cacheStorageMethod = null; /** * Name of the class used for cell cacheing * * @var string */ - private static $_cacheStorageClass = null; + private static $cacheStorageClass = null; /** * List of all possible cache storage methods * * @var string[] */ - private static $_storageMethods = array( + private static $storageMethods = array( self::cache_in_memory, self::cache_in_memory_gzip, self::cache_in_memory_serialized, @@ -77,7 +77,7 @@ class PHPExcel_CachedObjectStorageFactory * * @var array of mixed array */ - private static $_storageMethodDefaultParameters = array( + private static $storageMethodDefaultParameters = array( self::cache_in_memory => array( ), self::cache_in_memory_gzip => array( @@ -109,7 +109,7 @@ class PHPExcel_CachedObjectStorageFactory * * @var array of mixed array */ - private static $_storageMethodParameters = array(); + private static $storageMethodParameters = array(); /** * Return the current cache storage method @@ -118,7 +118,7 @@ class PHPExcel_CachedObjectStorageFactory **/ public static function getCacheStorageMethod() { - return self::$_cacheStorageMethod; + return self::$cacheStorageMethod; } /** @@ -128,7 +128,7 @@ public static function getCacheStorageMethod() **/ public static function getCacheStorageClass() { - return self::$_cacheStorageClass; + return self::$cacheStorageClass; } /** @@ -138,7 +138,7 @@ public static function getCacheStorageClass() **/ public static function getAllCacheStorageMethods() { - return self::$_storageMethods; + return self::$storageMethods; } /** @@ -149,7 +149,7 @@ public static function getAllCacheStorageMethods() public static function getCacheStorageMethods() { $activeMethods = array(); - foreach (self::$_storageMethods as $storageMethod) { + foreach (self::$storageMethods as $storageMethod) { $cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $storageMethod; if (call_user_func(array($cacheStorageClass, 'cacheMethodIsAvailable'))) { $activeMethods[] = $storageMethod; @@ -168,7 +168,7 @@ public static function getCacheStorageMethods() **/ public static function initialize($method = self::cache_in_memory, $arguments = array()) { - if (!in_array($method, self::$_storageMethods)) { + if (!in_array($method, self::$storageMethods)) { return false; } @@ -178,16 +178,16 @@ public static function initialize($method = self::cache_in_memory, $arguments = return false; } - self::$_storageMethodParameters[$method] = self::$_storageMethodDefaultParameters[$method]; + self::$storageMethodParameters[$method] = self::$storageMethodDefaultParameters[$method]; foreach ($arguments as $k => $v) { - if (array_key_exists($k, self::$_storageMethodParameters[$method])) { - self::$_storageMethodParameters[$method][$k] = $v; + if (array_key_exists($k, self::$storageMethodParameters[$method])) { + self::$storageMethodParameters[$method][$k] = $v; } } - if (self::$_cacheStorageMethod === null) { - self::$_cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $method; - self::$_cacheStorageMethod = $method; + if (self::$cacheStorageMethod === null) { + self::$cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $method; + self::$cacheStorageMethod = $method; } return true; } @@ -201,14 +201,14 @@ public static function initialize($method = self::cache_in_memory, $arguments = public static function getInstance(PHPExcel_Worksheet $parent) { $cacheMethodIsAvailable = true; - if (self::$_cacheStorageMethod === null) { + if (self::$cacheStorageMethod === null) { $cacheMethodIsAvailable = self::initialize(); } if ($cacheMethodIsAvailable) { - $instance = new self::$_cacheStorageClass( + $instance = new self::$cacheStorageClass( $parent, - self::$_storageMethodParameters[self::$_cacheStorageMethod] + self::$storageMethodParameters[self::$cacheStorageMethod] ); if ($instance !== null) { return $instance; @@ -224,8 +224,8 @@ public static function getInstance(PHPExcel_Worksheet $parent) **/ public static function finalize() { - self::$_cacheStorageMethod = null; - self::$_cacheStorageClass = null; - self::$_storageMethodParameters = array(); + self::$cacheStorageMethod = null; + self::$cacheStorageClass = null; + self::$storageMethodParameters = array(); } } diff --git a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php index b3bb2bf13..1072fc75f 100644 --- a/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php +++ b/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php @@ -32,7 +32,7 @@ class PHPExcel_CalcEngine_CyclicReferenceStack * * @var mixed[] */ - private $_stack = array(); + private $stack = array(); /** * Return the number of entries on the stack @@ -41,7 +41,7 @@ class PHPExcel_CalcEngine_CyclicReferenceStack */ public function count() { - return count($this->_stack); + return count($this->stack); } /** @@ -51,7 +51,7 @@ public function count() */ public function push($value) { - $this->_stack[$value] = $value; + $this->stack[$value] = $value; } /** @@ -61,7 +61,7 @@ public function push($value) */ public function pop() { - return array_pop($this->_stack); + return array_pop($this->stack); } /** @@ -71,7 +71,7 @@ public function pop() */ public function onStack($value) { - return isset($this->_stack[$value]); + return isset($this->stack[$value]); } /** @@ -79,7 +79,7 @@ public function onStack($value) */ public function clear() { - $this->_stack = array(); + $this->stack = array(); } /** @@ -89,6 +89,6 @@ public function clear() */ public function showStack() { - return $this->_stack; + return $this->stack; } } diff --git a/Classes/PHPExcel/CalcEngine/Logger.php b/Classes/PHPExcel/CalcEngine/Logger.php index 9fd1d7d79..c5ffe73e9 100644 --- a/Classes/PHPExcel/CalcEngine/Logger.php +++ b/Classes/PHPExcel/CalcEngine/Logger.php @@ -34,7 +34,7 @@ class PHPExcel_CalcEngine_Logger * * @var boolean */ - private $_writeDebugLog = false; + private $writeDebugLog = false; /** * Flag to determine whether a debug log should be echoed by the calculation engine @@ -44,21 +44,21 @@ class PHPExcel_CalcEngine_Logger * * @var boolean */ - private $_echoDebugLog = false; + private $echoDebugLog = false; /** * The debug log generated by the calculation engine * * @var string[] */ - private $_debugLog = array(); + private $debugLog = array(); /** * The calculation engine cell reference stack * * @var PHPExcel_CalcEngine_CyclicReferenceStack */ - private $_cellStack; + private $cellStack; /** * Instantiate a Calculation engine logger @@ -67,7 +67,7 @@ class PHPExcel_CalcEngine_Logger */ public function __construct(PHPExcel_CalcEngine_CyclicReferenceStack $stack) { - $this->_cellStack = $stack; + $this->cellStack = $stack; } /** @@ -77,7 +77,7 @@ public function __construct(PHPExcel_CalcEngine_CyclicReferenceStack $stack) */ public function setWriteDebugLog($pValue = false) { - $this->_writeDebugLog = $pValue; + $this->writeDebugLog = $pValue; } /** @@ -87,7 +87,7 @@ public function setWriteDebugLog($pValue = false) */ public function getWriteDebugLog() { - return $this->_writeDebugLog; + return $this->writeDebugLog; } /** @@ -97,7 +97,7 @@ public function getWriteDebugLog() */ public function setEchoDebugLog($pValue = false) { - $this->_echoDebugLog = $pValue; + $this->echoDebugLog = $pValue; } /** @@ -107,7 +107,7 @@ public function setEchoDebugLog($pValue = false) */ public function getEchoDebugLog() { - return $this->_echoDebugLog; + return $this->echoDebugLog; } /** @@ -116,17 +116,17 @@ public function getEchoDebugLog() public function writeDebugLog() { // Only write the debug log if logging is enabled - if ($this->_writeDebugLog) { + if ($this->writeDebugLog) { $message = implode(func_get_args()); - $cellReference = implode(' -> ', $this->_cellStack->showStack()); - if ($this->_echoDebugLog) { + $cellReference = implode(' -> ', $this->cellStack->showStack()); + if ($this->echoDebugLog) { echo $cellReference, - ($this->_cellStack->count() > 0 ? ' => ' : ''), + ($this->cellStack->count() > 0 ? ' => ' : ''), $message, PHP_EOL; } - $this->_debugLog[] = $cellReference . - ($this->_cellStack->count() > 0 ? ' => ' : '') . + $this->debugLog[] = $cellReference . + ($this->cellStack->count() > 0 ? ' => ' : '') . $message; } } @@ -136,7 +136,7 @@ public function writeDebugLog() */ public function clearLog() { - $this->_debugLog = array(); + $this->debugLog = array(); } /** @@ -146,6 +146,6 @@ public function clearLog() */ public function getLog() { - return $this->_debugLog; + return $this->debugLog; } } diff --git a/changelog.txt b/changelog.txt index 7d988cbe7..d12660c22 100644 --- a/changelog.txt +++ b/changelog.txt @@ -24,6 +24,7 @@ Planned for 1.8.2 +- Bugfix: (MBaker) - Fix to getCell() method when cell reference includes a worksheet reference 2015-04-30 (v1.8.1): From 4f8c9bfc966c0b77a8353f422b8f485d035edd2a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 7 May 2015 01:14:36 +0100 Subject: [PATCH 342/467] More PSR-2 work --- Classes/PHPExcel/RichText.php | 32 +- Classes/PHPExcel/RichText/ITextElement.php | 64 ++-- Classes/PHPExcel/RichText/Run.php | 124 ++++--- Classes/PHPExcel/RichText/TextElement.php | 135 ++++---- Classes/PHPExcel/Settings.php | 212 ++++++------ Classes/PHPExcel/Worksheet/CellIterator.php | 105 +++--- Classes/PHPExcel/Worksheet/Column.php | 114 +++---- .../PHPExcel/Worksheet/ColumnCellIterator.php | 313 ++++++++--------- .../PHPExcel/Worksheet/ColumnDimension.php | 253 +++++++------- Classes/PHPExcel/Worksheet/ColumnIterator.php | 289 ++++++++-------- Classes/PHPExcel/Worksheet/Row.php | 114 +++---- .../PHPExcel/Worksheet/RowCellIterator.php | 319 +++++++++--------- Classes/PHPExcel/Worksheet/RowDimension.php | 281 +++++++-------- Classes/PHPExcel/Worksheet/RowIterator.php | 287 ++++++++-------- Classes/PHPExcel/WorksheetIterator.php | 32 +- 15 files changed, 1316 insertions(+), 1358 deletions(-) diff --git a/Classes/PHPExcel/RichText.php b/Classes/PHPExcel/RichText.php index 30ba2c347..74a3534af 100644 --- a/Classes/PHPExcel/RichText.php +++ b/Classes/PHPExcel/RichText.php @@ -1,6 +1,7 @@ _richTextElements = array(); + $this->richTextElements = array(); // Rich-Text string attached to cell? - if ($pCell !== NULL) { + if ($pCell !== null) { // Add cell text and style if ($pCell->getValue() != "") { $objRun = new PHPExcel_RichText_Run($pCell->getValue()); @@ -76,7 +68,7 @@ public function __construct(PHPExcel_Cell $pCell = null) */ public function addText(PHPExcel_RichText_ITextElement $pText = null) { - $this->_richTextElements[] = $pText; + $this->richTextElements[] = $pText; return $this; } @@ -119,7 +111,7 @@ public function getPlainText() $returnValue = ''; // Loop through all PHPExcel_RichText_ITextElement - foreach ($this->_richTextElements as $text) { + foreach ($this->richTextElements as $text) { $returnValue .= $text->getText(); } @@ -144,7 +136,7 @@ public function __toString() */ public function getRichTextElements() { - return $this->_richTextElements; + return $this->richTextElements; } /** @@ -157,7 +149,7 @@ public function getRichTextElements() public function setRichTextElements($pElements = null) { if (is_array($pElements)) { - $this->_richTextElements = $pElements; + $this->richTextElements = $pElements; } else { throw new PHPExcel_Exception("Invalid PHPExcel_RichText_ITextElement[] array passed."); } @@ -172,13 +164,13 @@ public function setRichTextElements($pElements = null) public function getHashCode() { $hashElements = ''; - foreach ($this->_richTextElements as $element) { + foreach ($this->richTextElements as $element) { $hashElements .= $element->getHashCode(); } return md5( - $hashElements - . __CLASS__ + $hashElements . + __CLASS__ ); } diff --git a/Classes/PHPExcel/RichText/ITextElement.php b/Classes/PHPExcel/RichText/ITextElement.php index 816cc6963..5db343201 100644 --- a/Classes/PHPExcel/RichText/ITextElement.php +++ b/Classes/PHPExcel/RichText/ITextElement.php @@ -1,6 +1,7 @@ setText($pText); - $this->_font = new PHPExcel_Style_Font(); + // Initialise variables + $this->setText($pText); + $this->font = new PHPExcel_Style_Font(); } - /** - * Get font - * - * @return PHPExcel_Style_Font - */ - public function getFont() { - return $this->_font; - } + /** + * Get font + * + * @return PHPExcel_Style_Font + */ + public function getFont() + { + return $this->font; + } - /** - * Set font - * - * @param PHPExcel_Style_Font $pFont Font - * @throws PHPExcel_Exception - * @return PHPExcel_RichText_ITextElement - */ - public function setFont(PHPExcel_Style_Font $pFont = null) { - $this->_font = $pFont; - return $this; - } + /** + * Set font + * + * @param PHPExcel_Style_Font $pFont Font + * @throws PHPExcel_Exception + * @return PHPExcel_RichText_ITextElement + */ + public function setFont(PHPExcel_Style_Font $pFont = null) + { + $this->font = $pFont; + return $this; + } - /** - * Get hash code - * - * @return string Hash code - */ - public function getHashCode() { - return md5( - $this->getText() - . $this->_font->getHashCode() - . __CLASS__ - ); + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + return md5( + $this->getText() . + $this->_font->getHashCode() . + __CLASS__ + ); } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() + { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/RichText/TextElement.php b/Classes/PHPExcel/RichText/TextElement.php index 3524446ab..3558db326 100644 --- a/Classes/PHPExcel/RichText/TextElement.php +++ b/Classes/PHPExcel/RichText/TextElement.php @@ -1,6 +1,7 @@ _text = $pText; + // Initialise variables + $this->text = $pText; } - /** - * Get text - * - * @return string Text - */ - public function getText() { - return $this->_text; - } + /** + * Get text + * + * @return string Text + */ + public function getText() + { + return $this->text; + } - /** - * Set text - * - * @param $pText string Text - * @return PHPExcel_RichText_ITextElement - */ - public function setText($pText = '') { - $this->_text = $pText; - return $this; - } + /** + * Set text + * + * @param $pText string Text + * @return PHPExcel_RichText_ITextElement + */ + public function setText($pText = '') + { + $this->text = $pText; + return $this; + } - /** - * Get font - * - * @return PHPExcel_Style_Font - */ - public function getFont() { - return null; - } + /** + * Get font + * + * @return PHPExcel_Style_Font + */ + public function getFont() + { + return null; + } - /** - * Get hash code - * - * @return string Hash code - */ - public function getHashCode() { - return md5( - $this->_text - . __CLASS__ - ); + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + return md5( + $this->_text . + __CLASS__ + ); } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() + { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php index 69beb1a14..13655422b 100644 --- a/Classes/PHPExcel/Settings.php +++ b/Classes/PHPExcel/Settings.php @@ -1,6 +1,16 @@ setLocale($locale); - } // function setLocale() + } /** * Set details of the external library that PHPExcel should use for rendering charts * - * @param string $libraryName Internal reference name of the library - * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH + * @param string $libraryName Internal reference name of the library + * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH * @param string $libraryBaseDir Directory path to the library's base folder * - * @return boolean Success or failure + * @return boolean Success or failure */ public static function setChartRenderer($libraryName, $libraryBaseDir) { - if (!self::setChartRendererName($libraryName)) - return FALSE; + if (!self::setChartRendererName($libraryName)) { + return false; + } return self::setChartRendererPath($libraryBaseDir); - } // function setChartRenderer() + } /** * Identify to PHPExcel the external library to use for rendering charts * - * @param string $libraryName Internal reference name of the library - * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH + * @param string $libraryName Internal reference name of the library + * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH * - * @return boolean Success or failure + * @return boolean Success or failure */ public static function setChartRendererName($libraryName) { - if (!in_array($libraryName,self::$_chartRenderers)) { - return FALSE; + if (!in_array($libraryName, self::$chartRenderers)) { + return false; } + self::$chartRendererName = $libraryName; - self::$_chartRendererName = $libraryName; - - return TRUE; - } // function setChartRendererName() + return true; + } /** * Tell PHPExcel where to find the external library to use for rendering charts * - * @param string $libraryBaseDir Directory path to the library's base folder - * @return boolean Success or failure + * @param string $libraryBaseDir Directory path to the library's base folder + * @return boolean Success or failure */ public static function setChartRendererPath($libraryBaseDir) { if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) { - return FALSE; + return false; } - self::$_chartRendererPath = $libraryBaseDir; + self::$chartRendererPath = $libraryBaseDir; - return TRUE; - } // function setChartRendererPath() + return true; + } /** * Return the Chart Rendering Library that PHPExcel is currently configured to use (e.g. jpgraph) * * @return string|NULL Internal reference name of the Chart Rendering Library that PHPExcel is - * currently configured to use - * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH + * currently configured to use + * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH */ public static function getChartRendererName() { - return self::$_chartRendererName; - } // function getChartRendererName() + return self::$chartRendererName; + } /** * Return the directory path to the Chart Rendering Library that PHPExcel is currently configured to use * * @return string|NULL Directory Path to the Chart Rendering Library that PHPExcel is - * currently configured to use + * currently configured to use */ public static function getChartRendererPath() { - return self::$_chartRendererPath; - } // function getChartRendererPath() + return self::$chartRendererPath; + } /** * Set details of the external library that PHPExcel should use for rendering PDF files * * @param string $libraryName Internal reference name of the library - * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, - * PHPExcel_Settings::PDF_RENDERER_DOMPDF + * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, + * PHPExcel_Settings::PDF_RENDERER_DOMPDF * or PHPExcel_Settings::PDF_RENDERER_MPDF * @param string $libraryBaseDir Directory path to the library's base folder * @@ -286,32 +282,32 @@ public static function getChartRendererPath() */ public static function setPdfRenderer($libraryName, $libraryBaseDir) { - if (!self::setPdfRendererName($libraryName)) - return FALSE; + if (!self::setPdfRendererName($libraryName)) { + return false; + } return self::setPdfRendererPath($libraryBaseDir); - } // function setPdfRenderer() + } /** * Identify to PHPExcel the external library to use for rendering PDF files * * @param string $libraryName Internal reference name of the library - * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, - * PHPExcel_Settings::PDF_RENDERER_DOMPDF - * or PHPExcel_Settings::PDF_RENDERER_MPDF + * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, + * PHPExcel_Settings::PDF_RENDERER_DOMPDF + * or PHPExcel_Settings::PDF_RENDERER_MPDF * * @return boolean Success or failure */ public static function setPdfRendererName($libraryName) { - if (!in_array($libraryName,self::$_pdfRenderers)) { - return FALSE; + if (!in_array($libraryName, self::$pdfRenderers)) { + return false; } - self::$_pdfRendererName = $libraryName; - return TRUE; - } // function setPdfRendererName() + return true; + } /** @@ -323,38 +319,38 @@ public static function setPdfRendererName($libraryName) public static function setPdfRendererPath($libraryBaseDir) { if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) { - return FALSE; + return false; } - self::$_pdfRendererPath = $libraryBaseDir; + self::$pdfRendererPath = $libraryBaseDir; - return TRUE; - } // function setPdfRendererPath() + return true; + } /** * Return the PDF Rendering Library that PHPExcel is currently configured to use (e.g. dompdf) * * @return string|NULL Internal reference name of the PDF Rendering Library that PHPExcel is - * currently configured to use + * currently configured to use * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, * PHPExcel_Settings::PDF_RENDERER_DOMPDF * or PHPExcel_Settings::PDF_RENDERER_MPDF */ public static function getPdfRendererName() { - return self::$_pdfRendererName; - } // function getPdfRendererName() + return self::$pdfRendererName; + } /** * Return the directory path to the PDF Rendering Library that PHPExcel is currently configured to use * * @return string|NULL Directory Path to the PDF Rendering Library that PHPExcel is - * currently configured to use + * currently configured to use */ public static function getPdfRendererPath() { - return self::$_pdfRendererPath; - } // function getPdfRendererPath() + return self::$pdfRendererPath; + } /** * Set default options for libxml loader @@ -367,10 +363,10 @@ public static function setLibXmlLoaderOptions($options = null) $options = LIBXML_DTDLOAD | LIBXML_DTDATTR; } if (version_compare(PHP_VERSION, '5.2.11') >= 0) { - @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); } self::$_libXmlLoaderOptions = $options; - } // function setLibXmlLoaderOptions + } /** * Get default options for libxml loader. @@ -384,8 +380,8 @@ public static function getLibXmlLoaderOptions() self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR); } if (version_compare(PHP_VERSION, '5.2.11') >= 0) { - @libxml_disable_entity_loader(self::$_libXmlLoaderOptions == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + @libxml_disable_entity_loader(self::$libXmlLoaderOptions == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); } return self::$_libXmlLoaderOptions; - } // function getLibXmlLoaderOptions + } } diff --git a/Classes/PHPExcel/Worksheet/CellIterator.php b/Classes/PHPExcel/Worksheet/CellIterator.php index 37f6a12a8..151c17f53 100644 --- a/Classes/PHPExcel/Worksheet/CellIterator.php +++ b/Classes/PHPExcel/Worksheet/CellIterator.php @@ -1,6 +1,7 @@ _subject); - } + /** + * Destructor + */ + public function __destruct() + { + unset($this->subject); + } - /** - * Get loop only existing cells - * - * @return boolean - */ - public function getIterateOnlyExistingCells() { - return $this->_onlyExistingCells; + /** + * Get loop only existing cells + * + * @return boolean + */ + public function getIterateOnlyExistingCells() + { + return $this->onlyExistingCells; } - /** - * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary - * + /** + * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary + * * @throws PHPExcel_Exception - */ + */ abstract protected function adjustForExistingOnlyRange(); - /** - * Set the iterator to loop only existing cells - * - * @param boolean $value + /** + * Set the iterator to loop only existing cells + * + * @param boolean $value * @throws PHPExcel_Exception - */ - public function setIterateOnlyExistingCells($value = true) { - $this->_onlyExistingCells = (boolean) $value; + */ + public function setIterateOnlyExistingCells($value = true) + { + $this->onlyExistingCells = (boolean) $value; $this->adjustForExistingOnlyRange(); } diff --git a/Classes/PHPExcel/Worksheet/Column.php b/Classes/PHPExcel/Worksheet/Column.php index b0ba6837a..8c561fa8c 100644 --- a/Classes/PHPExcel/Worksheet/Column.php +++ b/Classes/PHPExcel/Worksheet/Column.php @@ -1,6 +1,7 @@ _parent = $parent; - $this->_columnIndex = $columnIndex; - } + /** + * Create a new column + * + * @param PHPExcel_Worksheet $parent + * @param string $columnIndex + */ + public function __construct(PHPExcel_Worksheet $parent = null, $columnIndex = 'A') + { + // Set parent and column index + $this->parent = $parent; + $this->columnIndex = $columnIndex; + } - /** - * Destructor - */ - public function __destruct() { - unset($this->_parent); - } + /** + * Destructor + */ + public function __destruct() + { + unset($this->parent); + } - /** - * Get column index - * - * @return int - */ - public function getColumnIndex() { - return $this->_columnIndex; - } + /** + * Get column index + * + * @return int + */ + public function getColumnIndex() + { + return $this->columnIndex; + } - /** - * Get cell iterator - * - * @param integer $startRow The row number at which to start iterating - * @param integer $endRow Optionally, the row number at which to stop iterating - * @return PHPExcel_Worksheet_CellIterator - */ - public function getCellIterator($startRow = 1, $endRow = null) { - return new PHPExcel_Worksheet_ColumnCellIterator($this->_parent, $this->_columnIndex, $startRow, $endRow); - } + /** + * Get cell iterator + * + * @param integer $startRow The row number at which to start iterating + * @param integer $endRow Optionally, the row number at which to stop iterating + * @return PHPExcel_Worksheet_CellIterator + */ + public function getCellIterator($startRow = 1, $endRow = null) + { + return new PHPExcel_Worksheet_ColumnCellIterator($this->parent, $this->columnIndex, $startRow, $endRow); + } } diff --git a/Classes/PHPExcel/Worksheet/ColumnCellIterator.php b/Classes/PHPExcel/Worksheet/ColumnCellIterator.php index c7953ea27..7b8c2190a 100644 --- a/Classes/PHPExcel/Worksheet/ColumnCellIterator.php +++ b/Classes/PHPExcel/Worksheet/ColumnCellIterator.php @@ -1,6 +1,7 @@ _subject = $subject; - $this->_columnIndex = PHPExcel_Cell::columnIndexFromString($columnIndex) - 1; - $this->resetEnd($endRow); - $this->resetStart($startRow); - } - - /** - * Destructor - */ - public function __destruct() { - unset($this->_subject); - } - - /** - * (Re)Set the start row and the current row pointer - * - * @param integer $startRow The row number at which to start iterating + * @param integer $startRow The row number at which to start iterating + * @param integer $endRow Optionally, the row number at which to stop iterating + */ + public function __construct(PHPExcel_Worksheet $subject = null, $columnIndex = 'A', $startRow = 1, $endRow = null) + { + // Set subject + $this->subject = $subject; + $this->columnIndex = PHPExcel_Cell::columnIndexFromString($columnIndex) - 1; + $this->resetEnd($endRow); + $this->resetStart($startRow); + } + + /** + * Destructor + */ + public function __destruct() + { + unset($this->subject); + } + + /** + * (Re)Set the start row and the current row pointer + * + * @param integer $startRow The row number at which to start iterating * @return PHPExcel_Worksheet_ColumnCellIterator * @throws PHPExcel_Exception - */ - public function resetStart($startRow = 1) { - $this->_startRow = $startRow; + */ + public function resetStart($startRow = 1) + { + $this->startRow = $startRow; $this->adjustForExistingOnlyRange(); - $this->seek($startRow); + $this->seek($startRow); return $this; - } + } - /** - * (Re)Set the end row - * - * @param integer $endRow The row number at which to stop iterating + /** + * (Re)Set the end row + * + * @param integer $endRow The row number at which to stop iterating * @return PHPExcel_Worksheet_ColumnCellIterator * @throws PHPExcel_Exception - */ - public function resetEnd($endRow = null) { - $this->_endRow = ($endRow) ? $endRow : $this->_subject->getHighestRow(); + */ + public function resetEnd($endRow = null) + { + $this->endRow = ($endRow) ? $endRow : $this->subject->getHighestRow(); $this->adjustForExistingOnlyRange(); return $this; - } + } - /** - * Set the row pointer to the selected row - * - * @param integer $row The row number to set the current pointer at + /** + * Set the row pointer to the selected row + * + * @param integer $row The row number to set the current pointer at * @return PHPExcel_Worksheet_ColumnCellIterator * @throws PHPExcel_Exception - */ - public function seek($row = 1) { - if (($row < $this->_startRow) || ($row > $this->_endRow)) { - throw new PHPExcel_Exception("Row $row is out of range ({$this->_startRow} - {$this->_endRow})"); - } elseif ($this->_onlyExistingCells && !($this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $row))) { + */ + public function seek($row = 1) + { + if (($row < $this->startRow) || ($row > $this->endRow)) { + throw new PHPExcel_Exception("Row $row is out of range ({$this->startRow} - {$this->endRow})"); + } elseif ($this->onlyExistingCells && !($this->subject->cellExistsByColumnAndRow($this->columnIndex, $row))) { throw new PHPExcel_Exception('In "IterateOnlyExistingCells" mode and Cell does not exist'); } - $this->_position = $row; + $this->position = $row; return $this; - } - - /** - * Rewind the iterator to the starting row - */ - public function rewind() { - $this->_position = $this->_startRow; - } - - /** - * Return the current cell in this worksheet column - * - * @return PHPExcel_Worksheet_Row - */ - public function current() { - return $this->_subject->getCellByColumnAndRow($this->_columnIndex, $this->_position); - } - - /** - * Return the current iterator key - * - * @return int - */ - public function key() { - return $this->_position; - } - - /** - * Set the iterator to its next value - */ - public function next() { + } + + /** + * Rewind the iterator to the starting row + */ + public function rewind() + { + $this->position = $this->startRow; + } + + /** + * Return the current cell in this worksheet column + * + * @return PHPExcel_Worksheet_Row + */ + public function current() + { + return $this->subject->getCellByColumnAndRow($this->columnIndex, $this->position); + } + + /** + * Return the current iterator key + * + * @return int + */ + public function key() + { + return $this->position; + } + + /** + * Set the iterator to its next value + */ + public function next() + { do { - ++$this->_position; - } while (($this->_onlyExistingCells) && - (!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_position)) && - ($this->_position <= $this->_endRow)); - } - - /** - * Set the iterator to its previous value - */ - public function prev() { - if ($this->_position <= $this->_startRow) { - throw new PHPExcel_Exception("Row is already at the beginning of range ({$this->_startRow} - {$this->_endRow})"); + ++$this->position; + } while (($this->onlyExistingCells) && + (!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->position)) && + ($this->position <= $this->endRow)); + } + + /** + * Set the iterator to its previous value + */ + public function prev() + { + if ($this->position <= $this->startRow) { + throw new PHPExcel_Exception("Row is already at the beginning of range ({$this->startRow} - {$this->endRow})"); } do { - --$this->_position; - } while (($this->_onlyExistingCells) && - (!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_position)) && - ($this->_position >= $this->_startRow)); - } - - /** - * Indicate if more rows exist in the worksheet range of rows that we're iterating - * - * @return boolean - */ - public function valid() { - return $this->_position <= $this->_endRow; - } - - /** - * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary - * + --$this->position; + } while (($this->onlyExistingCells) && + (!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->position)) && + ($this->position >= $this->startRow)); + } + + /** + * Indicate if more rows exist in the worksheet range of rows that we're iterating + * + * @return boolean + */ + public function valid() + { + return $this->position <= $this->endRow; + } + + /** + * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary + * * @throws PHPExcel_Exception - */ - protected function adjustForExistingOnlyRange() { - if ($this->_onlyExistingCells) { - while ((!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_startRow)) && - ($this->_startRow <= $this->_endRow)) { - ++$this->_startRow; + */ + protected function adjustForExistingOnlyRange() + { + if ($this->onlyExistingCells) { + while ((!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->startRow)) && + ($this->startRow <= $this->endRow)) { + ++$this->startRow; } - if ($this->_startRow > $this->_endRow) { + if ($this->startRow > $this->endRow) { throw new PHPExcel_Exception('No cells exist within the specified range'); } - while ((!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_endRow)) && - ($this->_endRow >= $this->_startRow)) { - --$this->_endRow; + while ((!$this->subject->cellExistsByColumnAndRow($this->columnIndex, $this->endRow)) && + ($this->endRow >= $this->startRow)) { + --$this->endRow; } - if ($this->_endRow < $this->_startRow) { + if ($this->endRow < $this->startRow) { throw new PHPExcel_Exception('No cells exist within the specified range'); } } } - } diff --git a/Classes/PHPExcel/Worksheet/ColumnDimension.php b/Classes/PHPExcel/Worksheet/ColumnDimension.php index e52a3f40c..956ffdce9 100644 --- a/Classes/PHPExcel/Worksheet/ColumnDimension.php +++ b/Classes/PHPExcel/Worksheet/ColumnDimension.php @@ -1,6 +1,7 @@ _columnIndex = $pIndex; + // Initialise values + $this->_columnIndex = $pIndex; - // set default index to cellXf - $this->_xfIndex = 0; + // set default index to cellXf + $this->_xfIndex = 0; } /** @@ -105,8 +97,9 @@ public function __construct($pIndex = 'A') * * @return string */ - public function getColumnIndex() { - return $this->_columnIndex; + public function getColumnIndex() + { + return $this->_columnIndex; } /** @@ -115,9 +108,10 @@ public function getColumnIndex() { * @param string $pValue * @return PHPExcel_Worksheet_ColumnDimension */ - public function setColumnIndex($pValue) { - $this->_columnIndex = $pValue; - return $this; + public function setColumnIndex($pValue) + { + $this->_columnIndex = $pValue; + return $this; } /** @@ -125,8 +119,9 @@ public function setColumnIndex($pValue) { * * @return double */ - public function getWidth() { - return $this->_width; + public function getWidth() + { + return $this->_width; } /** @@ -135,9 +130,10 @@ public function getWidth() { * @param double $pValue * @return PHPExcel_Worksheet_ColumnDimension */ - public function setWidth($pValue = -1) { - $this->_width = $pValue; - return $this; + public function setWidth($pValue = -1) + { + $this->_width = $pValue; + return $this; } /** @@ -145,8 +141,9 @@ public function setWidth($pValue = -1) { * * @return bool */ - public function getAutoSize() { - return $this->_autoSize; + public function getAutoSize() + { + return $this->_autoSize; } /** @@ -155,9 +152,10 @@ public function getAutoSize() { * @param bool $pValue * @return PHPExcel_Worksheet_ColumnDimension */ - public function setAutoSize($pValue = false) { - $this->_autoSize = $pValue; - return $this; + public function setAutoSize($pValue = false) + { + $this->_autoSize = $pValue; + return $this; } /** @@ -165,8 +163,9 @@ public function setAutoSize($pValue = false) { * * @return bool */ - public function getVisible() { - return $this->_visible; + public function getVisible() + { + return $this->_visible; } /** @@ -175,9 +174,10 @@ public function getVisible() { * @param bool $pValue * @return PHPExcel_Worksheet_ColumnDimension */ - public function setVisible($pValue = true) { - $this->_visible = $pValue; - return $this; + public function setVisible($pValue = true) + { + $this->_visible = $pValue; + return $this; } /** @@ -185,8 +185,9 @@ public function setVisible($pValue = true) { * * @return int */ - public function getOutlineLevel() { - return $this->_outlineLevel; + public function getOutlineLevel() + { + return $this->_outlineLevel; } /** @@ -198,13 +199,14 @@ public function getOutlineLevel() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_ColumnDimension */ - public function setOutlineLevel($pValue) { - if ($pValue < 0 || $pValue > 7) { - throw new PHPExcel_Exception("Outline level must range between 0 and 7."); - } + public function setOutlineLevel($pValue) + { + if ($pValue < 0 || $pValue > 7) { + throw new PHPExcel_Exception("Outline level must range between 0 and 7."); + } - $this->_outlineLevel = $pValue; - return $this; + $this->_outlineLevel = $pValue; + return $this; } /** @@ -212,8 +214,9 @@ public function setOutlineLevel($pValue) { * * @return bool */ - public function getCollapsed() { - return $this->_collapsed; + public function getCollapsed() + { + return $this->_collapsed; } /** @@ -222,45 +225,47 @@ public function getCollapsed() { * @param bool $pValue * @return PHPExcel_Worksheet_ColumnDimension */ - public function setCollapsed($pValue = true) { - $this->_collapsed = $pValue; - return $this; + public function setCollapsed($pValue = true) + { + $this->_collapsed = $pValue; + return $this; } - /** - * Get index to cellXf - * - * @return int - */ - public function getXfIndex() - { - return $this->_xfIndex; - } + /** + * Get index to cellXf + * + * @return int + */ + public function getXfIndex() + { + return $this->_xfIndex; + } - /** - * Set index to cellXf - * - * @param int $pValue - * @return PHPExcel_Worksheet_ColumnDimension - */ - public function setXfIndex($pValue = 0) - { - $this->_xfIndex = $pValue; - return $this; - } + /** + * Set index to cellXf + * + * @param int $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setXfIndex($pValue = 0) + { + $this->_xfIndex = $pValue; + return $this; + } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() + { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/ColumnIterator.php b/Classes/PHPExcel/Worksheet/ColumnIterator.php index bec14d5a9..270bca65e 100644 --- a/Classes/PHPExcel/Worksheet/ColumnIterator.php +++ b/Classes/PHPExcel/Worksheet/ColumnIterator.php @@ -1,6 +1,7 @@ _subject = $subject; - $this->resetEnd($endColumn); - $this->resetStart($startColumn); - } - - /** - * Destructor - */ - public function __destruct() { - unset($this->_subject); - } - - /** - * (Re)Set the start column and the current column pointer - * - * @param integer $startColumn The column address at which to start iterating + /** + * PHPExcel_Worksheet to iterate + * + * @var PHPExcel_Worksheet + */ + private $subject; + + /** + * Current iterator position + * + * @var int + */ + private $position = 0; + + /** + * Start position + * + * @var int + */ + private $startColumn = 0; + + + /** + * End position + * + * @var int + */ + private $endColumn = 0; + + + /** + * Create a new column iterator + * + * @param PHPExcel_Worksheet $subject The worksheet to iterate over + * @param string $startColumn The column address at which to start iterating + * @param string $endColumn Optionally, the column address at which to stop iterating + */ + public function __construct(PHPExcel_Worksheet $subject = null, $startColumn = 'A', $endColumn = null) + { + // Set subject + $this->subject = $subject; + $this->resetEnd($endColumn); + $this->resetStart($startColumn); + } + + /** + * Destructor + */ + public function __destruct() + { + unset($this->subject); + } + + /** + * (Re)Set the start column and the current column pointer + * + * @param integer $startColumn The column address at which to start iterating * @return PHPExcel_Worksheet_ColumnIterator - */ - public function resetStart($startColumn = 'A') { + */ + public function resetStart($startColumn = 'A') + { $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; - $this->_startColumn = $startColumnIndex; - $this->seek($startColumn); + $this->startColumn = $startColumnIndex; + $this->seek($startColumn); return $this; - } + } - /** - * (Re)Set the end column - * - * @param string $endColumn The column address at which to stop iterating + /** + * (Re)Set the end column + * + * @param string $endColumn The column address at which to stop iterating * @return PHPExcel_Worksheet_ColumnIterator - */ - public function resetEnd($endColumn = null) { - $endColumn = ($endColumn) ? $endColumn : $this->_subject->getHighestColumn(); - $this->_endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; + */ + public function resetEnd($endColumn = null) + { + $endColumn = ($endColumn) ? $endColumn : $this->subject->getHighestColumn(); + $this->endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; return $this; - } + } - /** - * Set the column pointer to the selected column - * - * @param string $column The column address to set the current pointer at + /** + * Set the column pointer to the selected column + * + * @param string $column The column address to set the current pointer at * @return PHPExcel_Worksheet_ColumnIterator * @throws PHPExcel_Exception - */ - public function seek($column = 'A') { + */ + public function seek($column = 'A') + { $column = PHPExcel_Cell::columnIndexFromString($column) - 1; - if (($column < $this->_startColumn) || ($column > $this->_endColumn)) { - throw new PHPExcel_Exception("Column $column is out of range ({$this->_startColumn} - {$this->_endColumn})"); + if (($column < $this->startColumn) || ($column > $this->endColumn)) { + throw new PHPExcel_Exception("Column $column is out of range ({$this->startColumn} - {$this->endColumn})"); } - $this->_position = $column; + $this->position = $column; return $this; } - /** - * Rewind the iterator to the starting column - */ - public function rewind() { - $this->_position = $this->_startColumn; - } - - /** - * Return the current column in this worksheet - * - * @return PHPExcel_Worksheet_Column - */ - public function current() { - return new PHPExcel_Worksheet_Column($this->_subject, PHPExcel_Cell::stringFromColumnIndex($this->_position)); - } - - /** - * Return the current iterator key - * - * @return string - */ - public function key() { - return PHPExcel_Cell::stringFromColumnIndex($this->_position); - } - - /** - * Set the iterator to its next value - */ - public function next() { - ++$this->_position; - } - - /** - * Set the iterator to its previous value + /** + * Rewind the iterator to the starting column + */ + public function rewind() + { + $this->position = $this->startColumn; + } + + /** + * Return the current column in this worksheet + * + * @return PHPExcel_Worksheet_Column + */ + public function current() + { + return new PHPExcel_Worksheet_Column($this->subject, PHPExcel_Cell::stringFromColumnIndex($this->position)); + } + + /** + * Return the current iterator key + * + * @return string + */ + public function key() + { + return PHPExcel_Cell::stringFromColumnIndex($this->position); + } + + /** + * Set the iterator to its next value + */ + public function next() + { + ++$this->position; + } + + /** + * Set the iterator to its previous value * * @throws PHPExcel_Exception - */ - public function prev() { - if ($this->_position <= $this->_startColumn) { + */ + public function prev() + { + if ($this->position <= $this->startColumn) { throw new PHPExcel_Exception( - "Column is already at the beginning of range (" . - PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . " - " . - PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . ")" + "Column is already at the beginning of range (" . + PHPExcel_Cell::stringFromColumnIndex($this->endColumn) . " - " . + PHPExcel_Cell::stringFromColumnIndex($this->endColumn) . ")" ); } - --$this->_position; - } - - /** - * Indicate if more columns exist in the worksheet range of columns that we're iterating - * - * @return boolean - */ - public function valid() { - return $this->_position <= $this->_endColumn; - } + --$this->position; + } + + /** + * Indicate if more columns exist in the worksheet range of columns that we're iterating + * + * @return boolean + */ + public function valid() + { + return $this->position <= $this->endColumn; + } } diff --git a/Classes/PHPExcel/Worksheet/Row.php b/Classes/PHPExcel/Worksheet/Row.php index 11fadba53..4f6034f53 100644 --- a/Classes/PHPExcel/Worksheet/Row.php +++ b/Classes/PHPExcel/Worksheet/Row.php @@ -1,6 +1,7 @@ _parent = $parent; - $this->_rowIndex = $rowIndex; - } + /** + * Create a new row + * + * @param PHPExcel_Worksheet $parent + * @param int $rowIndex + */ + public function __construct(PHPExcel_Worksheet $parent = null, $rowIndex = 1) + { + // Set parent and row index + $this->parent = $parent; + $this->rowIndex = $rowIndex; + } - /** - * Destructor - */ - public function __destruct() { - unset($this->_parent); - } + /** + * Destructor + */ + public function __destruct() + { + unset($this->parent); + } - /** - * Get row index - * - * @return int - */ - public function getRowIndex() { - return $this->_rowIndex; - } + /** + * Get row index + * + * @return int + */ + public function getRowIndex() + { + return $this->rowIndex; + } - /** - * Get cell iterator - * - * @param string $startColumn The column address at which to start iterating - * @param string $endColumn Optionally, the column address at which to stop iterating - * @return PHPExcel_Worksheet_CellIterator - */ - public function getCellIterator($startColumn = 'A', $endColumn = null) { - return new PHPExcel_Worksheet_RowCellIterator($this->_parent, $this->_rowIndex, $startColumn, $endColumn); - } + /** + * Get cell iterator + * + * @param string $startColumn The column address at which to start iterating + * @param string $endColumn Optionally, the column address at which to stop iterating + * @return PHPExcel_Worksheet_CellIterator + */ + public function getCellIterator($startColumn = 'A', $endColumn = null) + { + return new PHPExcel_Worksheet_RowCellIterator($this->parent, $this->rowIndex, $startColumn, $endColumn); + } } diff --git a/Classes/PHPExcel/Worksheet/RowCellIterator.php b/Classes/PHPExcel/Worksheet/RowCellIterator.php index df5bbe5a6..90eb9c9f2 100644 --- a/Classes/PHPExcel/Worksheet/RowCellIterator.php +++ b/Classes/PHPExcel/Worksheet/RowCellIterator.php @@ -1,6 +1,7 @@ _subject = $subject; - $this->_rowIndex = $rowIndex; - $this->resetEnd($endColumn); - $this->resetStart($startColumn); - } - - /** - * Destructor - */ - public function __destruct() { - unset($this->_subject); - } - - /** - * (Re)Set the start column and the current column pointer - * - * @param integer $startColumn The column address at which to start iterating + * @param string $startColumn The column address at which to start iterating + * @param string $endColumn Optionally, the column address at which to stop iterating + */ + public function __construct(PHPExcel_Worksheet $subject = null, $rowIndex = 1, $startColumn = 'A', $endColumn = null) + { + // Set subject and row index + $this->subject = $subject; + $this->rowIndex = $rowIndex; + $this->resetEnd($endColumn); + $this->resetStart($startColumn); + } + + /** + * Destructor + */ + public function __destruct() + { + unset($this->subject); + } + + /** + * (Re)Set the start column and the current column pointer + * + * @param integer $startColumn The column address at which to start iterating * @return PHPExcel_Worksheet_RowCellIterator * @throws PHPExcel_Exception - */ - public function resetStart($startColumn = 'A') { + */ + public function resetStart($startColumn = 'A') + { $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; - $this->_startColumn = $startColumnIndex; + $this->startColumn = $startColumnIndex; $this->adjustForExistingOnlyRange(); - $this->seek(PHPExcel_Cell::stringFromColumnIndex($this->_startColumn)); + $this->seek(PHPExcel_Cell::stringFromColumnIndex($this->startColumn)); return $this; - } + } - /** - * (Re)Set the end column - * - * @param string $endColumn The column address at which to stop iterating + /** + * (Re)Set the end column + * + * @param string $endColumn The column address at which to stop iterating * @return PHPExcel_Worksheet_RowCellIterator * @throws PHPExcel_Exception - */ - public function resetEnd($endColumn = null) { - $endColumn = ($endColumn) ? $endColumn : $this->_subject->getHighestColumn(); - $this->_endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; + */ + public function resetEnd($endColumn = null) + { + $endColumn = ($endColumn) ? $endColumn : $this->subject->getHighestColumn(); + $this->endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; $this->adjustForExistingOnlyRange(); return $this; - } + } - /** - * Set the column pointer to the selected column - * - * @param string $column The column address to set the current pointer at + /** + * Set the column pointer to the selected column + * + * @param string $column The column address to set the current pointer at * @return PHPExcel_Worksheet_RowCellIterator * @throws PHPExcel_Exception - */ - public function seek($column = 'A') { + */ + public function seek($column = 'A') + { $column = PHPExcel_Cell::columnIndexFromString($column) - 1; - if (($column < $this->_startColumn) || ($column > $this->_endColumn)) { - throw new PHPExcel_Exception("Column $column is out of range ({$this->_startColumn} - {$this->_endColumn})"); - } elseif ($this->_onlyExistingCells && !($this->_subject->cellExistsByColumnAndRow($column, $this->_rowIndex))) { + if (($column < $this->startColumn) || ($column > $this->endColumn)) { + throw new PHPExcel_Exception("Column $column is out of range ({$this->startColumn} - {$this->endColumn})"); + } elseif ($this->onlyExistingCells && !($this->subject->cellExistsByColumnAndRow($column, $this->rowIndex))) { throw new PHPExcel_Exception('In "IterateOnlyExistingCells" mode and Cell does not exist'); } - $this->_position = $column; + $this->position = $column; return $this; } - /** - * Rewind the iterator to the starting column - */ - public function rewind() { - $this->_position = $this->_startColumn; - } - - /** - * Return the current cell in this worksheet row - * - * @return PHPExcel_Cell - */ - public function current() { - return $this->_subject->getCellByColumnAndRow($this->_position, $this->_rowIndex); - } - - /** - * Return the current iterator key - * - * @return string - */ - public function key() { - return PHPExcel_Cell::stringFromColumnIndex($this->_position); - } - - /** - * Set the iterator to its next value - */ - public function next() { + /** + * Rewind the iterator to the starting column + */ + public function rewind() + { + $this->position = $this->startColumn; + } + + /** + * Return the current cell in this worksheet row + * + * @return PHPExcel_Cell + */ + public function current() + { + return $this->subject->getCellByColumnAndRow($this->position, $this->rowIndex); + } + + /** + * Return the current iterator key + * + * @return string + */ + public function key() + { + return PHPExcel_Cell::stringFromColumnIndex($this->position); + } + + /** + * Set the iterator to its next value + */ + public function next() + { do { - ++$this->_position; - } while (($this->_onlyExistingCells) && - (!$this->_subject->cellExistsByColumnAndRow($this->_position, $this->_rowIndex)) && - ($this->_position <= $this->_endColumn)); - } - - /** - * Set the iterator to its previous value + ++$this->position; + } while (($this->onlyExistingCells) && + (!$this->subject->cellExistsByColumnAndRow($this->position, $this->rowIndex)) && + ($this->position <= $this->endColumn)); + } + + /** + * Set the iterator to its previous value * * @throws PHPExcel_Exception - */ - public function prev() { - if ($this->_position <= $this->_startColumn) { + */ + public function prev() + { + if ($this->position <= $this->startColumn) { throw new PHPExcel_Exception( - "Column is already at the beginning of range (" . - PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . " - " . - PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . ")" + "Column is already at the beginning of range (" . + PHPExcel_Cell::stringFromColumnIndex($this->endColumn) . " - " . + PHPExcel_Cell::stringFromColumnIndex($this->endColumn) . ")" ); } do { - --$this->_position; - } while (($this->_onlyExistingCells) && - (!$this->_subject->cellExistsByColumnAndRow($this->_position, $this->_rowIndex)) && - ($this->_position >= $this->_startColumn)); - } - - /** - * Indicate if more columns exist in the worksheet range of columns that we're iterating - * - * @return boolean - */ - public function valid() { - return $this->_position <= $this->_endColumn; - } - - /** - * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary - * + --$this->position; + } while (($this->onlyExistingCells) && + (!$this->subject->cellExistsByColumnAndRow($this->position, $this->rowIndex)) && + ($this->position >= $this->startColumn)); + } + + /** + * Indicate if more columns exist in the worksheet range of columns that we're iterating + * + * @return boolean + */ + public function valid() + { + return $this->position <= $this->endColumn; + } + + /** + * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary + * * @throws PHPExcel_Exception - */ - protected function adjustForExistingOnlyRange() { - if ($this->_onlyExistingCells) { - while ((!$this->_subject->cellExistsByColumnAndRow($this->_startColumn, $this->_rowIndex)) && - ($this->_startColumn <= $this->_endColumn)) { - ++$this->_startColumn; + */ + protected function adjustForExistingOnlyRange() + { + if ($this->onlyExistingCells) { + while ((!$this->subject->cellExistsByColumnAndRow($this->startColumn, $this->rowIndex)) && + ($this->startColumn <= $this->endColumn)) { + ++$this->startColumn; } - if ($this->_startColumn > $this->_endColumn) { + if ($this->startColumn > $this->endColumn) { throw new PHPExcel_Exception('No cells exist within the specified range'); } - while ((!$this->_subject->cellExistsByColumnAndRow($this->_endColumn, $this->_rowIndex)) && - ($this->_endColumn >= $this->_startColumn)) { - --$this->_endColumn; + while ((!$this->subject->cellExistsByColumnAndRow($this->endColumn, $this->rowIndex)) && + ($this->endColumn >= $this->startColumn)) { + --$this->endColumn; } - if ($this->_endColumn < $this->_startColumn) { + if ($this->endColumn < $this->startColumn) { throw new PHPExcel_Exception('No cells exist within the specified range'); } } } - } diff --git a/Classes/PHPExcel/Worksheet/RowDimension.php b/Classes/PHPExcel/Worksheet/RowDimension.php index 00f7c56b0..5314f9c19 100644 --- a/Classes/PHPExcel/Worksheet/RowDimension.php +++ b/Classes/PHPExcel/Worksheet/RowDimension.php @@ -1,6 +1,7 @@ _rowIndex = $pIndex; + // Initialise values + $this->_rowIndex = $pIndex; - // set row dimension as unformatted by default - $this->_xfIndex = null; + // set row dimension as unformatted by default + $this->_xfIndex = null; } /** @@ -105,8 +97,9 @@ public function __construct($pIndex = 0) * * @return int */ - public function getRowIndex() { - return $this->_rowIndex; + public function getRowIndex() + { + return $this->_rowIndex; } /** @@ -115,9 +108,10 @@ public function getRowIndex() { * @param int $pValue * @return PHPExcel_Worksheet_RowDimension */ - public function setRowIndex($pValue) { - $this->_rowIndex = $pValue; - return $this; + public function setRowIndex($pValue) + { + $this->_rowIndex = $pValue; + return $this; } /** @@ -125,8 +119,9 @@ public function setRowIndex($pValue) { * * @return double */ - public function getRowHeight() { - return $this->_rowHeight; + public function getRowHeight() + { + return $this->_rowHeight; } /** @@ -135,38 +130,42 @@ public function getRowHeight() { * @param double $pValue * @return PHPExcel_Worksheet_RowDimension */ - public function setRowHeight($pValue = -1) { - $this->_rowHeight = $pValue; - return $this; + public function setRowHeight($pValue = -1) + { + $this->_rowHeight = $pValue; + return $this; } - /** - * Get ZeroHeight - * - * @return bool - */ - public function getZeroHeight() { - return $this->_zeroHeight; - } + /** + * Get ZeroHeight + * + * @return bool + */ + public function getZeroHeight() + { + return $this->_zeroHeight; + } - /** - * Set ZeroHeight - * - * @param bool $pValue - * @return PHPExcel_Worksheet_RowDimension - */ - public function setZeroHeight($pValue = false) { - $this->_zeroHeight = $pValue; - return $this; - } + /** + * Set ZeroHeight + * + * @param bool $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setZeroHeight($pValue = false) + { + $this->_zeroHeight = $pValue; + return $this; + } /** * Get Visible * * @return bool */ - public function getVisible() { - return $this->_visible; + public function getVisible() + { + return $this->_visible; } /** @@ -175,9 +174,10 @@ public function getVisible() { * @param bool $pValue * @return PHPExcel_Worksheet_RowDimension */ - public function setVisible($pValue = true) { - $this->_visible = $pValue; - return $this; + public function setVisible($pValue = true) + { + $this->_visible = $pValue; + return $this; } /** @@ -185,8 +185,9 @@ public function setVisible($pValue = true) { * * @return int */ - public function getOutlineLevel() { - return $this->_outlineLevel; + public function getOutlineLevel() + { + return $this->_outlineLevel; } /** @@ -198,13 +199,14 @@ public function getOutlineLevel() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_RowDimension */ - public function setOutlineLevel($pValue) { - if ($pValue < 0 || $pValue > 7) { - throw new PHPExcel_Exception("Outline level must range between 0 and 7."); - } + public function setOutlineLevel($pValue) + { + if ($pValue < 0 || $pValue > 7) { + throw new PHPExcel_Exception("Outline level must range between 0 and 7."); + } - $this->_outlineLevel = $pValue; - return $this; + $this->_outlineLevel = $pValue; + return $this; } /** @@ -212,8 +214,9 @@ public function setOutlineLevel($pValue) { * * @return bool */ - public function getCollapsed() { - return $this->_collapsed; + public function getCollapsed() + { + return $this->_collapsed; } /** @@ -222,44 +225,46 @@ public function getCollapsed() { * @param bool $pValue * @return PHPExcel_Worksheet_RowDimension */ - public function setCollapsed($pValue = true) { - $this->_collapsed = $pValue; - return $this; + public function setCollapsed($pValue = true) + { + $this->_collapsed = $pValue; + return $this; } - /** - * Get index to cellXf - * - * @return int - */ - public function getXfIndex() - { - return $this->_xfIndex; - } + /** + * Get index to cellXf + * + * @return int + */ + public function getXfIndex() + { + return $this->_xfIndex; + } - /** - * Set index to cellXf - * - * @param int $pValue - * @return PHPExcel_Worksheet_RowDimension - */ - public function setXfIndex($pValue = 0) - { - $this->_xfIndex = $pValue; - return $this; - } + /** + * Set index to cellXf + * + * @param int $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setXfIndex($pValue = 0) + { + $this->_xfIndex = $pValue; + return $this; + } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() + { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/RowIterator.php b/Classes/PHPExcel/Worksheet/RowIterator.php index f01c7f502..6c88d50c7 100644 --- a/Classes/PHPExcel/Worksheet/RowIterator.php +++ b/Classes/PHPExcel/Worksheet/RowIterator.php @@ -1,6 +1,7 @@ _subject = $subject; - $this->resetEnd($endRow); - $this->resetStart($startRow); - } - - /** - * Destructor - */ - public function __destruct() { - unset($this->_subject); - } - - /** - * (Re)Set the start row and the current row pointer - * - * @param integer $startRow The row number at which to start iterating + /** + * PHPExcel_Worksheet to iterate + * + * @var PHPExcel_Worksheet + */ + private $subject; + + /** + * Current iterator position + * + * @var int + */ + private $position = 1; + + /** + * Start position + * + * @var int + */ + private $startRow = 1; + + + /** + * End position + * + * @var int + */ + private $endRow = 1; + + + /** + * Create a new row iterator + * + * @param PHPExcel_Worksheet $subject The worksheet to iterate over + * @param integer $startRow The row number at which to start iterating + * @param integer $endRow Optionally, the row number at which to stop iterating + */ + public function __construct(PHPExcel_Worksheet $subject = null, $startRow = 1, $endRow = null) + { + // Set subject + $this->subject = $subject; + $this->resetEnd($endRow); + $this->resetStart($startRow); + } + + /** + * Destructor + */ + public function __destruct() + { + unset($this->subject); + } + + /** + * (Re)Set the start row and the current row pointer + * + * @param integer $startRow The row number at which to start iterating * @return PHPExcel_Worksheet_RowIterator - */ - public function resetStart($startRow = 1) { - $this->_startRow = $startRow; - $this->seek($startRow); + */ + public function resetStart($startRow = 1) + { + $this->startRow = $startRow; + $this->seek($startRow); return $this; - } + } - /** - * (Re)Set the end row - * - * @param integer $endRow The row number at which to stop iterating + /** + * (Re)Set the end row + * + * @param integer $endRow The row number at which to stop iterating * @return PHPExcel_Worksheet_RowIterator - */ - public function resetEnd($endRow = null) { - $this->_endRow = ($endRow) ? $endRow : $this->_subject->getHighestRow(); + */ + public function resetEnd($endRow = null) + { + $this->endRow = ($endRow) ? $endRow : $this->subject->getHighestRow(); return $this; - } + } - /** - * Set the row pointer to the selected row - * - * @param integer $row The row number to set the current pointer at + /** + * Set the row pointer to the selected row + * + * @param integer $row The row number to set the current pointer at * @return PHPExcel_Worksheet_RowIterator * @throws PHPExcel_Exception - */ - public function seek($row = 1) { - if (($row < $this->_startRow) || ($row > $this->_endRow)) { - throw new PHPExcel_Exception("Row $row is out of range ({$this->_startRow} - {$this->_endRow})"); + */ + public function seek($row = 1) + { + if (($row < $this->startRow) || ($row > $this->endRow)) { + throw new PHPExcel_Exception("Row $row is out of range ({$this->startRow} - {$this->endRow})"); } - $this->_position = $row; + $this->position = $row; return $this; - } - - /** - * Rewind the iterator to the starting row - */ - public function rewind() { - $this->_position = $this->_startRow; - } - - /** - * Return the current row in this worksheet - * - * @return PHPExcel_Worksheet_Row - */ - public function current() { - return new PHPExcel_Worksheet_Row($this->_subject, $this->_position); - } - - /** - * Return the current iterator key - * - * @return int - */ - public function key() { - return $this->_position; - } - - /** - * Set the iterator to its next value - */ - public function next() { - ++$this->_position; - } - - /** - * Set the iterator to its previous value - */ - public function prev() { - if ($this->_position <= $this->_startRow) { - throw new PHPExcel_Exception("Row is already at the beginning of range ({$this->_startRow} - {$this->_endRow})"); + } + + /** + * Rewind the iterator to the starting row + */ + public function rewind() + { + $this->position = $this->startRow; + } + + /** + * Return the current row in this worksheet + * + * @return PHPExcel_Worksheet_Row + */ + public function current() + { + return new PHPExcel_Worksheet_Row($this->subject, $this->position); + } + + /** + * Return the current iterator key + * + * @return int + */ + public function key() + { + return $this->position; + } + + /** + * Set the iterator to its next value + */ + public function next() + { + ++$this->position; + } + + /** + * Set the iterator to its previous value + */ + public function prev() + { + if ($this->position <= $this->startRow) { + throw new PHPExcel_Exception("Row is already at the beginning of range ({$this->startRow} - {$this->endRow})"); } - --$this->_position; - } - - /** - * Indicate if more rows exist in the worksheet range of rows that we're iterating - * - * @return boolean - */ - public function valid() { - return $this->_position <= $this->_endRow; - } + --$this->position; + } + + /** + * Indicate if more rows exist in the worksheet range of rows that we're iterating + * + * @return boolean + */ + public function valid() + { + return $this->position <= $this->endRow; + } } diff --git a/Classes/PHPExcel/WorksheetIterator.php b/Classes/PHPExcel/WorksheetIterator.php index 065bfe3f8..cb1b28118 100644 --- a/Classes/PHPExcel/WorksheetIterator.php +++ b/Classes/PHPExcel/WorksheetIterator.php @@ -1,6 +1,7 @@ _subject = $subject; + $this->subject = $subject; } /** @@ -67,7 +57,7 @@ public function __construct(PHPExcel $subject = null) */ public function __destruct() { - unset($this->_subject); + unset($this->subject); } /** @@ -75,7 +65,7 @@ public function __destruct() */ public function rewind() { - $this->_position = 0; + $this->position = 0; } /** @@ -85,7 +75,7 @@ public function rewind() */ public function current() { - return $this->_subject->getSheet($this->_position); + return $this->subject->getSheet($this->position); } /** @@ -95,7 +85,7 @@ public function current() */ public function key() { - return $this->_position; + return $this->position; } /** @@ -103,7 +93,7 @@ public function key() */ public function next() { - ++$this->_position; + ++$this->position; } /** @@ -113,6 +103,6 @@ public function next() */ public function valid() { - return $this->_position < $this->_subject->getSheetCount(); + return $this->position < $this->subject->getSheetCount(); } } From b8f67c6f4dfff72ccf0167a34c6be16a4379970a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 8 May 2015 01:09:27 +0100 Subject: [PATCH 343/467] More PSR-2 changes, and fixes for a couple of breakages introduced by the last commit --- Classes/PHPExcel/Autoloader.php | 10 +- Classes/PHPExcel/Calculation/Database.php | 1359 ++-- Classes/PHPExcel/Calculation/DateTime.php | 2967 +++---- Classes/PHPExcel/Calculation/Engineering.php | 5093 ++++++------ Classes/PHPExcel/Calculation/Exception.php | 34 +- .../PHPExcel/Calculation/ExceptionHandler.php | 28 +- Classes/PHPExcel/Calculation/Financial.php | 4500 +++++------ .../PHPExcel/Calculation/FormulaParser.php | 1048 +-- Classes/PHPExcel/Calculation/FormulaToken.php | 156 +- Classes/PHPExcel/Calculation/Function.php | 114 +- Classes/PHPExcel/Calculation/Functions.php | 1320 +-- Classes/PHPExcel/Calculation/Logical.php | 470 +- Classes/PHPExcel/Calculation/LookupRef.php | 1556 ++-- Classes/PHPExcel/Calculation/MathTrig.php | 2644 +++--- Classes/PHPExcel/Calculation/Statistical.php | 7200 ++++++++--------- Classes/PHPExcel/Calculation/TextData.php | 1138 +-- Classes/PHPExcel/Calculation/Token/Stack.php | 1 + Classes/PHPExcel/Cell/AdvancedValueBinder.php | 57 +- Classes/PHPExcel/Cell/DataType.php | 24 +- Classes/PHPExcel/Cell/DataValidation.php | 12 +- Classes/PHPExcel/Cell/DefaultValueBinder.php | 36 +- Classes/PHPExcel/Cell/Hyperlink.php | 54 +- Classes/PHPExcel/Cell/IValueBinder.php | 3 +- Classes/PHPExcel/RichText/Run.php | 2 +- Classes/PHPExcel/RichText/TextElement.php | 2 +- Classes/PHPExcel/Settings.php | 8 +- Classes/PHPExcel/Writer/PDF.php | 22 +- Classes/PHPExcel/Writer/PDF/Core.php | 43 +- Classes/PHPExcel/Writer/PDF/DomPDF.php | 48 +- Classes/PHPExcel/Writer/PDF/mPDF.php | 48 +- Classes/PHPExcel/Writer/PDF/tcPDF.php | 57 +- 31 files changed, 15075 insertions(+), 14979 deletions(-) diff --git a/Classes/PHPExcel/Autoloader.php b/Classes/PHPExcel/Autoloader.php index 3557e8656..c3b95a20c 100644 --- a/Classes/PHPExcel/Autoloader.php +++ b/Classes/PHPExcel/Autoloader.php @@ -1,6 +1,6 @@ = 0) { - return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'), true, true); + return spl_autoload_register(array('PHPExcel_Autoloader', 'load'), true, true); } else { - return spl_autoload_register(array('PHPExcel_Autoloader', 'Load')); + return spl_autoload_register(array('PHPExcel_Autoloader', 'load')); } } @@ -60,7 +60,7 @@ public static function Register() * * @param string $pClassName Name of the object to load */ - public static function Load($pClassName) + public static function load($pClassName) { if ((class_exists($pClassName, false)) || (strpos($pClassName, 'PHPExcel') !== 0)) { // Either already loaded, or not a PHPExcel class request diff --git a/Classes/PHPExcel/Calculation/Database.php b/Classes/PHPExcel/Calculation/Database.php index e340a589f..9afcffd49 100644 --- a/Classes/PHPExcel/Calculation/Database.php +++ b/Classes/PHPExcel/Calculation/Database.php @@ -1,6 +1,16 @@ $criteriaName) { + $testCondition = array(); + $testConditionCount = 0; + foreach ($criteria as $row => $criterion) { + if ($criterion[$key] > '') { + $testCondition[] = '[:'.$criteriaName.']'.PHPExcel_Calculation_Functions::_ifCondition($criterion[$key]); + $testConditionCount++; + } + } + if ($testConditionCount > 1) { + $testConditions[] = 'OR(' . implode(',', $testCondition) . ')'; + $testConditionsCount++; + } elseif ($testConditionCount == 1) { + $testConditions[] = $testCondition[0]; + $testConditionsCount++; + } + } + + if ($testConditionsCount > 1) { + $testConditionSet = 'AND(' . implode(',', $testConditions) . ')'; + } elseif ($testConditionsCount == 1) { + $testConditionSet = $testConditions[0]; + } + + // Loop through each row of the database + foreach ($database as $dataRow => $dataValues) { + // Substitute actual values from the database row for our [:placeholders] + $testConditionList = $testConditionSet; + foreach ($criteriaNames as $key => $criteriaName) { + $k = array_search($criteriaName, $fieldNames); + if (isset($dataValues[$k])) { + $dataValue = $dataValues[$k]; + $dataValue = (is_string($dataValue)) ? PHPExcel_Calculation::_wrapResult(strtoupper($dataValue)) : $dataValue; + $testConditionList = str_replace('[:' . $criteriaName . ']', $dataValue, $testConditionList); + } + } + // evaluate the criteria against the row data + $result = PHPExcel_Calculation::getInstance()->_calculateFormulaValue('='.$testConditionList); + // If the row failed to meet the criteria, remove it from the database + if (!$result) { + unset($database[$dataRow]); + } + } + + return $database; + } + + + private static function getFilteredColumn($database, $field, $criteria) + { + // reduce the database to a set of rows that match all the criteria + $database = self::filter($database, $criteria); + // extract an array of values for the requested column + $colData = array(); + foreach ($database as $row) { + $colData[] = $row[$field]; + } + + return $colData; + } + + /** + * DAVERAGE + * + * Averages the values in a column of a list or database that match conditions you specify. + * + * Excel Function: + * DAVERAGE(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DAVERAGE($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + return PHPExcel_Calculation_Statistical::AVERAGE( + self::getFilteredColumn($database, $field, $criteria) + ); + } + + + /** + * DCOUNT + * + * Counts the cells that contain numbers in a column of a list or database that match conditions + * that you specify. + * + * Excel Function: + * DCOUNT(database,[field],criteria) + * + * Excel Function: + * DAVERAGE(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return integer + * + * @TODO The field argument is optional. If field is omitted, DCOUNT counts all records in the + * database that match the criteria. + * + */ + public static function DCOUNT($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + return PHPExcel_Calculation_Statistical::COUNT( + self::getFilteredColumn($database, $field, $criteria) + ); + } + + + /** + * DCOUNTA + * + * Counts the nonblank cells in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DCOUNTA(database,[field],criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return integer + * + * @TODO The field argument is optional. If field is omitted, DCOUNTA counts all records in the + * database that match the criteria. + * + */ + public static function DCOUNTA($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::filter($database, $criteria); + // extract an array of values for the requested column + $colData = array(); + foreach ($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::COUNTA( + self::getFilteredColumn($database, $field, $criteria) + ); + } + + + /** + * DGET + * + * Extracts a single value from a column of a list or database that matches conditions that you + * specify. + * + * Excel Function: + * DGET(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return mixed + * + */ + public static function DGET($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + $colData = self::getFilteredColumn($database, $field, $criteria); + if (count($colData) > 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return $colData[0]; + } + + + /** + * DMAX + * + * Returns the largest number in a column of a list or database that matches conditions you that + * specify. + * + * Excel Function: + * DMAX(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DMAX($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + return PHPExcel_Calculation_Statistical::MAX( + self::getFilteredColumn($database, $field, $criteria) + ); + } + + + /** + * DMIN + * + * Returns the smallest number in a column of a list or database that matches conditions you that + * specify. + * + * Excel Function: + * DMIN(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DMIN($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + return PHPExcel_Calculation_Statistical::MIN( + self::getFilteredColumn($database, $field, $criteria) + ); + } + + + /** + * DPRODUCT + * + * Multiplies the values in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DPRODUCT(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DPRODUCT($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + return PHPExcel_Calculation_MathTrig::PRODUCT( + self::getFilteredColumn($database, $field, $criteria) + ); + } + + + /** + * DSTDEV + * + * Estimates the standard deviation of a population based on a sample by using the numbers in a + * column of a list or database that match conditions that you specify. + * + * Excel Function: + * DSTDEV(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DSTDEV($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + return PHPExcel_Calculation_Statistical::STDEV( + self::getFilteredColumn($database, $field, $criteria) + ); + } + + + /** + * DSTDEVP + * + * Calculates the standard deviation of a population based on the entire population by using the + * numbers in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DSTDEVP(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DSTDEVP($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + return PHPExcel_Calculation_Statistical::STDEVP( + self::getFilteredColumn($database, $field, $criteria) + ); + } + + + /** + * DSUM + * + * Adds the numbers in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DSUM(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DSUM($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + return PHPExcel_Calculation_MathTrig::SUM( + self::getFilteredColumn($database, $field, $criteria) + ); + } + + + /** + * DVAR + * + * Estimates the variance of a population based on a sample by using the numbers in a column + * of a list or database that match conditions that you specify. + * + * Excel Function: + * DVAR(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DVAR($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + return PHPExcel_Calculation_Statistical::VARFunc( + self::getFilteredColumn($database, $field, $criteria) + ); + } + + + /** + * DVARP + * + * Calculates the variance of a population based on the entire population by using the numbers + * in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DVARP(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DVARP($database, $field, $criteria) + { + $field = self::fieldExtract($database, $field); + if (is_null($field)) { + return null; + } + + // Return + return PHPExcel_Calculation_Statistical::VARP( + self::getFilteredColumn($database, $field, $criteria) + ); + } } - - -/** - * PHPExcel_Calculation_Database - * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ -class PHPExcel_Calculation_Database { - - - /** - * __fieldExtract - * - * Extracts the column ID to use for the data field. - * - * @access private - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param mixed $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @return string|NULL - * - */ - private static function __fieldExtract($database,$field) { - $field = strtoupper(PHPExcel_Calculation_Functions::flattenSingleValue($field)); - $fieldNames = array_map('strtoupper',array_shift($database)); - - if (is_numeric($field)) { - $keys = array_keys($fieldNames); - return $keys[$field-1]; - } - $key = array_search($field,$fieldNames); - return ($key) ? $key : NULL; - } - - /** - * __filter - * - * Parses the selection criteria, extracts the database rows that match those criteria, and - * returns that subset of rows. - * - * @access private - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return array of mixed - * - */ - private static function __filter($database,$criteria) { - $fieldNames = array_shift($database); - $criteriaNames = array_shift($criteria); - - // Convert the criteria into a set of AND/OR conditions with [:placeholders] - $testConditions = $testValues = array(); - $testConditionsCount = 0; - foreach($criteriaNames as $key => $criteriaName) { - $testCondition = array(); - $testConditionCount = 0; - foreach($criteria as $row => $criterion) { - if ($criterion[$key] > '') { - $testCondition[] = '[:'.$criteriaName.']'.PHPExcel_Calculation_Functions::_ifCondition($criterion[$key]); - $testConditionCount++; - } - } - if ($testConditionCount > 1) { - $testConditions[] = 'OR('.implode(',',$testCondition).')'; - $testConditionsCount++; - } elseif($testConditionCount == 1) { - $testConditions[] = $testCondition[0]; - $testConditionsCount++; - } - } - - if ($testConditionsCount > 1) { - $testConditionSet = 'AND('.implode(',',$testConditions).')'; - } elseif($testConditionsCount == 1) { - $testConditionSet = $testConditions[0]; - } - - // Loop through each row of the database - foreach($database as $dataRow => $dataValues) { - // Substitute actual values from the database row for our [:placeholders] - $testConditionList = $testConditionSet; - foreach($criteriaNames as $key => $criteriaName) { - $k = array_search($criteriaName,$fieldNames); - if (isset($dataValues[$k])) { - $dataValue = $dataValues[$k]; - $dataValue = (is_string($dataValue)) ? PHPExcel_Calculation::_wrapResult(strtoupper($dataValue)) : $dataValue; - $testConditionList = str_replace('[:'.$criteriaName.']',$dataValue,$testConditionList); - } - } - // evaluate the criteria against the row data - $result = PHPExcel_Calculation::getInstance()->_calculateFormulaValue('='.$testConditionList); - // If the row failed to meet the criteria, remove it from the database - if (!$result) { - unset($database[$dataRow]); - } - } - - return $database; - } - - - /** - * DAVERAGE - * - * Averages the values in a column of a list or database that match conditions you specify. - * - * Excel Function: - * DAVERAGE(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return float - * - */ - public static function DAVERAGE($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_Statistical::AVERAGE($colData); - } // function DAVERAGE() - - - /** - * DCOUNT - * - * Counts the cells that contain numbers in a column of a list or database that match conditions - * that you specify. - * - * Excel Function: - * DCOUNT(database,[field],criteria) - * - * Excel Function: - * DAVERAGE(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return integer - * - * @TODO The field argument is optional. If field is omitted, DCOUNT counts all records in the - * database that match the criteria. - * - */ - public static function DCOUNT($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_Statistical::COUNT($colData); - } // function DCOUNT() - - - /** - * DCOUNTA - * - * Counts the nonblank cells in a column of a list or database that match conditions that you specify. - * - * Excel Function: - * DCOUNTA(database,[field],criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return integer - * - * @TODO The field argument is optional. If field is omitted, DCOUNTA counts all records in the - * database that match the criteria. - * - */ - public static function DCOUNTA($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_Statistical::COUNTA($colData); - } // function DCOUNTA() - - - /** - * DGET - * - * Extracts a single value from a column of a list or database that matches conditions that you - * specify. - * - * Excel Function: - * DGET(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return mixed - * - */ - public static function DGET($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - if (count($colData) > 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - - return $colData[0]; - } // function DGET() - - - /** - * DMAX - * - * Returns the largest number in a column of a list or database that matches conditions you that - * specify. - * - * Excel Function: - * DMAX(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return float - * - */ - public static function DMAX($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_Statistical::MAX($colData); - } // function DMAX() - - - /** - * DMIN - * - * Returns the smallest number in a column of a list or database that matches conditions you that - * specify. - * - * Excel Function: - * DMIN(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return float - * - */ - public static function DMIN($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_Statistical::MIN($colData); - } // function DMIN() - - - /** - * DPRODUCT - * - * Multiplies the values in a column of a list or database that match conditions that you specify. - * - * Excel Function: - * DPRODUCT(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return float - * - */ - public static function DPRODUCT($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_MathTrig::PRODUCT($colData); - } // function DPRODUCT() - - - /** - * DSTDEV - * - * Estimates the standard deviation of a population based on a sample by using the numbers in a - * column of a list or database that match conditions that you specify. - * - * Excel Function: - * DSTDEV(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return float - * - */ - public static function DSTDEV($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_Statistical::STDEV($colData); - } // function DSTDEV() - - - /** - * DSTDEVP - * - * Calculates the standard deviation of a population based on the entire population by using the - * numbers in a column of a list or database that match conditions that you specify. - * - * Excel Function: - * DSTDEVP(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return float - * - */ - public static function DSTDEVP($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_Statistical::STDEVP($colData); - } // function DSTDEVP() - - - /** - * DSUM - * - * Adds the numbers in a column of a list or database that match conditions that you specify. - * - * Excel Function: - * DSUM(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return float - * - */ - public static function DSUM($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_MathTrig::SUM($colData); - } // function DSUM() - - - /** - * DVAR - * - * Estimates the variance of a population based on a sample by using the numbers in a column - * of a list or database that match conditions that you specify. - * - * Excel Function: - * DVAR(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return float - * - */ - public static function DVAR($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_Statistical::VARFunc($colData); - } // function DVAR() - - - /** - * DVARP - * - * Calculates the variance of a population based on the entire population by using the numbers - * in a column of a list or database that match conditions that you specify. - * - * Excel Function: - * DVARP(database,field,criteria) - * - * @access public - * @category Database Functions - * @param mixed[] $database The range of cells that makes up the list or database. - * A database is a list of related data in which rows of related - * information are records, and columns of data are fields. The - * first row of the list contains labels for each column. - * @param string|integer $field Indicates which column is used in the function. Enter the - * column label enclosed between double quotation marks, such as - * "Age" or "Yield," or a number (without quotation marks) that - * represents the position of the column within the list: 1 for - * the first column, 2 for the second column, and so on. - * @param mixed[] $criteria The range of cells that contains the conditions you specify. - * You can use any range for the criteria argument, as long as it - * includes at least one column label and at least one cell below - * the column label in which you specify a condition for the - * column. - * @return float - * - */ - public static function DVARP($database,$field,$criteria) { - $field = self::__fieldExtract($database,$field); - if (is_null($field)) { - return NULL; - } - - // reduce the database to a set of rows that match all the criteria - $database = self::__filter($database,$criteria); - // extract an array of values for the requested column - $colData = array(); - foreach($database as $row) { - $colData[] = $row[$field]; - } - - // Return - return PHPExcel_Calculation_Statistical::VARP($colData); - } // function DVARP() - - -} // class PHPExcel_Calculation_Database diff --git a/Classes/PHPExcel/Calculation/DateTime.php b/Classes/PHPExcel/Calculation/DateTime.php index a14da243d..fabd60c6b 100644 --- a/Classes/PHPExcel/Calculation/DateTime.php +++ b/Classes/PHPExcel/Calculation/DateTime.php @@ -18,1468 +18,1545 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** * PHPExcel_Calculation_DateTime * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ -class PHPExcel_Calculation_DateTime { - - /** - * Identify if a year is a leap year or not - * - * @param integer $year The year to test - * @return boolean TRUE if the year is a leap year, otherwise FALSE - */ - public static function _isLeapYear($year) { - return ((($year % 4) == 0) && (($year % 100) != 0) || (($year % 400) == 0)); - } // function _isLeapYear() - - - /** - * Return the number of days between two dates based on a 360 day calendar - * - * @param integer $startDay Day of month of the start date - * @param integer $startMonth Month of the start date - * @param integer $startYear Year of the start date - * @param integer $endDay Day of month of the start date - * @param integer $endMonth Month of the start date - * @param integer $endYear Year of the start date - * @param boolean $methodUS Whether to use the US method or the European method of calculation - * @return integer Number of days between the start date and the end date - */ - private static function _dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, $methodUS) { - if ($startDay == 31) { - --$startDay; - } elseif ($methodUS && ($startMonth == 2 && ($startDay == 29 || ($startDay == 28 && !self::_isLeapYear($startYear))))) { - $startDay = 30; - } - if ($endDay == 31) { - if ($methodUS && $startDay != 30) { - $endDay = 1; - if ($endMonth == 12) { - ++$endYear; - $endMonth = 1; - } else { - ++$endMonth; - } - } else { - $endDay = 30; - } - } - - return $endDay + $endMonth * 30 + $endYear * 360 - $startDay - $startMonth * 30 - $startYear * 360; - } // function _dateDiff360() - - - /** - * _getDateValue - * - * @param string $dateValue - * @return mixed Excel date/time serial value, or string if error - */ - public static function _getDateValue($dateValue) { - if (!is_numeric($dateValue)) { - if ((is_string($dateValue)) && - (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { - $dateValue = PHPExcel_Shared_Date::PHPToExcel($dateValue); - } else { - $saveReturnDateType = PHPExcel_Calculation_Functions::getReturnDateType(); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $dateValue = self::DATEVALUE($dateValue); - PHPExcel_Calculation_Functions::setReturnDateType($saveReturnDateType); - } - } - return $dateValue; - } // function _getDateValue() - - - /** - * _getTimeValue - * - * @param string $timeValue - * @return mixed Excel date/time serial value, or string if error - */ - private static function _getTimeValue($timeValue) { - $saveReturnDateType = PHPExcel_Calculation_Functions::getReturnDateType(); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $timeValue = self::TIMEVALUE($timeValue); - PHPExcel_Calculation_Functions::setReturnDateType($saveReturnDateType); - return $timeValue; - } // function _getTimeValue() - - - private static function _adjustDateByMonths($dateValue = 0, $adjustmentMonths = 0) { - // Execute function - $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); - $oMonth = (int) $PHPDateObject->format('m'); - $oYear = (int) $PHPDateObject->format('Y'); - - $adjustmentMonthsString = (string) $adjustmentMonths; - if ($adjustmentMonths > 0) { - $adjustmentMonthsString = '+'.$adjustmentMonths; - } - if ($adjustmentMonths != 0) { - $PHPDateObject->modify($adjustmentMonthsString.' months'); - } - $nMonth = (int) $PHPDateObject->format('m'); - $nYear = (int) $PHPDateObject->format('Y'); - - $monthDiff = ($nMonth - $oMonth) + (($nYear - $oYear) * 12); - if ($monthDiff != $adjustmentMonths) { - $adjustDays = (int) $PHPDateObject->format('d'); - $adjustDaysString = '-'.$adjustDays.' days'; - $PHPDateObject->modify($adjustDaysString); - } - return $PHPDateObject; - } // function _adjustDateByMonths() - - - /** - * DATETIMENOW - * - * Returns the current date and time. - * The NOW function is useful when you need to display the current date and time on a worksheet or - * calculate a value based on the current date and time, and have that value updated each time you - * open the worksheet. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date - * and time format of your regional settings. PHPExcel does not change cell formatting in this way. - * - * Excel Function: - * NOW() - * - * @access public - * @category Date/Time Functions - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function DATETIMENOW() { - $saveTimeZone = date_default_timezone_get(); - date_default_timezone_set('UTC'); - $retValue = False; - switch (PHPExcel_Calculation_Functions::getReturnDateType()) { - case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : - $retValue = (float) PHPExcel_Shared_Date::PHPToExcel(time()); - break; - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : - $retValue = (integer) time(); - break; - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : - $retValue = new DateTime(); - break; - } - date_default_timezone_set($saveTimeZone); - - return $retValue; - } // function DATETIMENOW() - - - /** - * DATENOW - * - * Returns the current date. - * The NOW function is useful when you need to display the current date and time on a worksheet or - * calculate a value based on the current date and time, and have that value updated each time you - * open the worksheet. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date - * and time format of your regional settings. PHPExcel does not change cell formatting in this way. - * - * Excel Function: - * TODAY() - * - * @access public - * @category Date/Time Functions - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function DATENOW() { - $saveTimeZone = date_default_timezone_get(); - date_default_timezone_set('UTC'); - $retValue = False; - $excelDateTime = floor(PHPExcel_Shared_Date::PHPToExcel(time())); - switch (PHPExcel_Calculation_Functions::getReturnDateType()) { - case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : - $retValue = (float) $excelDateTime; - break; - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : - $retValue = (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateTime); - break; - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : - $retValue = PHPExcel_Shared_Date::ExcelToPHPObject($excelDateTime); - break; - } - date_default_timezone_set($saveTimeZone); - - return $retValue; - } // function DATENOW() - - - /** - * DATE - * - * The DATE function returns a value that represents a particular date. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date - * format of your regional settings. PHPExcel does not change cell formatting in this way. - * - * Excel Function: - * DATE(year,month,day) - * - * PHPExcel is a lot more forgiving than MS Excel when passing non numeric values to this function. - * A Month name or abbreviation (English only at this point) such as 'January' or 'Jan' will still be accepted, - * as will a day value with a suffix (e.g. '21st' rather than simply 21); again only English language. - * - * @access public - * @category Date/Time Functions - * @param integer $year The value of the year argument can include one to four digits. - * Excel interprets the year argument according to the configured - * date system: 1900 or 1904. - * If year is between 0 (zero) and 1899 (inclusive), Excel adds that - * value to 1900 to calculate the year. For example, DATE(108,1,2) - * returns January 2, 2008 (1900+108). - * If year is between 1900 and 9999 (inclusive), Excel uses that - * value as the year. For example, DATE(2008,1,2) returns January 2, - * 2008. - * If year is less than 0 or is 10000 or greater, Excel returns the - * #NUM! error value. - * @param integer $month A positive or negative integer representing the month of the year - * from 1 to 12 (January to December). - * If month is greater than 12, month adds that number of months to - * the first month in the year specified. For example, DATE(2008,14,2) - * returns the serial number representing February 2, 2009. - * If month is less than 1, month subtracts the magnitude of that - * number of months, plus 1, from the first month in the year - * specified. For example, DATE(2008,-3,2) returns the serial number - * representing September 2, 2007. - * @param integer $day A positive or negative integer representing the day of the month - * from 1 to 31. - * If day is greater than the number of days in the month specified, - * day adds that number of days to the first day in the month. For - * example, DATE(2008,1,35) returns the serial number representing - * February 4, 2008. - * If day is less than 1, day subtracts the magnitude that number of - * days, plus one, from the first day of the month specified. For - * example, DATE(2008,1,-15) returns the serial number representing - * December 16, 2007. - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function DATE($year = 0, $month = 1, $day = 1) { - $year = PHPExcel_Calculation_Functions::flattenSingleValue($year); - $month = PHPExcel_Calculation_Functions::flattenSingleValue($month); - $day = PHPExcel_Calculation_Functions::flattenSingleValue($day); - - if (($month !== NULL) && (!is_numeric($month))) { +class PHPExcel_Calculation_DateTime +{ + /** + * Identify if a year is a leap year or not + * + * @param integer $year The year to test + * @return boolean TRUE if the year is a leap year, otherwise FALSE + */ + public static function isLeapYear($year) + { + return ((($year % 4) == 0) && (($year % 100) != 0) || (($year % 400) == 0)); + } + + + /** + * Return the number of days between two dates based on a 360 day calendar + * + * @param integer $startDay Day of month of the start date + * @param integer $startMonth Month of the start date + * @param integer $startYear Year of the start date + * @param integer $endDay Day of month of the start date + * @param integer $endMonth Month of the start date + * @param integer $endYear Year of the start date + * @param boolean $methodUS Whether to use the US method or the European method of calculation + * @return integer Number of days between the start date and the end date + */ + private static function dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, $methodUS) + { + if ($startDay == 31) { + --$startDay; + } elseif ($methodUS && ($startMonth == 2 && ($startDay == 29 || ($startDay == 28 && !self::isLeapYear($startYear))))) { + $startDay = 30; + } + if ($endDay == 31) { + if ($methodUS && $startDay != 30) { + $endDay = 1; + if ($endMonth == 12) { + ++$endYear; + $endMonth = 1; + } else { + ++$endMonth; + } + } else { + $endDay = 30; + } + } + + return $endDay + $endMonth * 30 + $endYear * 360 - $startDay - $startMonth * 30 - $startYear * 360; + } + + + /** + * _getDateValue + * + * @param string $dateValue + * @return mixed Excel date/time serial value, or string if error + */ + public static function _getDateValue($dateValue) + { + if (!is_numeric($dateValue)) { + if ((is_string($dateValue)) && + (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { + $dateValue = PHPExcel_Shared_Date::PHPToExcel($dateValue); + } else { + $saveReturnDateType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $dateValue = self::DATEVALUE($dateValue); + PHPExcel_Calculation_Functions::setReturnDateType($saveReturnDateType); + } + } + return $dateValue; + } + + + /** + * _getTimeValue + * + * @param string $timeValue + * @return mixed Excel date/time serial value, or string if error + */ + private static function _getTimeValue($timeValue) + { + $saveReturnDateType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $timeValue = self::TIMEVALUE($timeValue); + PHPExcel_Calculation_Functions::setReturnDateType($saveReturnDateType); + return $timeValue; + } + + + private static function _adjustDateByMonths($dateValue = 0, $adjustmentMonths = 0) + { + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + $oMonth = (int) $PHPDateObject->format('m'); + $oYear = (int) $PHPDateObject->format('Y'); + + $adjustmentMonthsString = (string) $adjustmentMonths; + if ($adjustmentMonths > 0) { + $adjustmentMonthsString = '+'.$adjustmentMonths; + } + if ($adjustmentMonths != 0) { + $PHPDateObject->modify($adjustmentMonthsString.' months'); + } + $nMonth = (int) $PHPDateObject->format('m'); + $nYear = (int) $PHPDateObject->format('Y'); + + $monthDiff = ($nMonth - $oMonth) + (($nYear - $oYear) * 12); + if ($monthDiff != $adjustmentMonths) { + $adjustDays = (int) $PHPDateObject->format('d'); + $adjustDaysString = '-'.$adjustDays.' days'; + $PHPDateObject->modify($adjustDaysString); + } + return $PHPDateObject; + } + + + /** + * DATETIMENOW + * + * Returns the current date and time. + * The NOW function is useful when you need to display the current date and time on a worksheet or + * calculate a value based on the current date and time, and have that value updated each time you + * open the worksheet. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * and time format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * NOW() + * + * @access public + * @category Date/Time Functions + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATETIMENOW() + { + $saveTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $retValue = false; + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL: + $retValue = (float) PHPExcel_Shared_Date::PHPToExcel(time()); + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC: + $retValue = (integer) time(); + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT: + $retValue = new DateTime(); + break; + } + date_default_timezone_set($saveTimeZone); + + return $retValue; + } + + + /** + * DATENOW + * + * Returns the current date. + * The NOW function is useful when you need to display the current date and time on a worksheet or + * calculate a value based on the current date and time, and have that value updated each time you + * open the worksheet. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * and time format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * TODAY() + * + * @access public + * @category Date/Time Functions + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATENOW() + { + $saveTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $retValue = false; + $excelDateTime = floor(PHPExcel_Shared_Date::PHPToExcel(time())); + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL: + $retValue = (float) $excelDateTime; + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC: + $retValue = (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateTime); + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT: + $retValue = PHPExcel_Shared_Date::ExcelToPHPObject($excelDateTime); + break; + } + date_default_timezone_set($saveTimeZone); + + return $retValue; + } + + + /** + * DATE + * + * The DATE function returns a value that represents a particular date. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * DATE(year,month,day) + * + * PHPExcel is a lot more forgiving than MS Excel when passing non numeric values to this function. + * A Month name or abbreviation (English only at this point) such as 'January' or 'Jan' will still be accepted, + * as will a day value with a suffix (e.g. '21st' rather than simply 21); again only English language. + * + * @access public + * @category Date/Time Functions + * @param integer $year The value of the year argument can include one to four digits. + * Excel interprets the year argument according to the configured + * date system: 1900 or 1904. + * If year is between 0 (zero) and 1899 (inclusive), Excel adds that + * value to 1900 to calculate the year. For example, DATE(108,1,2) + * returns January 2, 2008 (1900+108). + * If year is between 1900 and 9999 (inclusive), Excel uses that + * value as the year. For example, DATE(2008,1,2) returns January 2, + * 2008. + * If year is less than 0 or is 10000 or greater, Excel returns the + * #NUM! error value. + * @param integer $month A positive or negative integer representing the month of the year + * from 1 to 12 (January to December). + * If month is greater than 12, month adds that number of months to + * the first month in the year specified. For example, DATE(2008,14,2) + * returns the serial number representing February 2, 2009. + * If month is less than 1, month subtracts the magnitude of that + * number of months, plus 1, from the first month in the year + * specified. For example, DATE(2008,-3,2) returns the serial number + * representing September 2, 2007. + * @param integer $day A positive or negative integer representing the day of the month + * from 1 to 31. + * If day is greater than the number of days in the month specified, + * day adds that number of days to the first day in the month. For + * example, DATE(2008,1,35) returns the serial number representing + * February 4, 2008. + * If day is less than 1, day subtracts the magnitude that number of + * days, plus one, from the first day of the month specified. For + * example, DATE(2008,1,-15) returns the serial number representing + * December 16, 2007. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATE($year = 0, $month = 1, $day = 1) + { + $year = PHPExcel_Calculation_Functions::flattenSingleValue($year); + $month = PHPExcel_Calculation_Functions::flattenSingleValue($month); + $day = PHPExcel_Calculation_Functions::flattenSingleValue($day); + + if (($month !== null) && (!is_numeric($month))) { $month = PHPExcel_Shared_Date::monthStringToNumber($month); - } + } - if (($day !== NULL) && (!is_numeric($day))) { + if (($day !== null) && (!is_numeric($day))) { $day = PHPExcel_Shared_Date::dayStringToNumber($day); - } - - $year = ($year !== NULL) ? PHPExcel_Shared_String::testStringAsNumeric($year) : 0; - $month = ($month !== NULL) ? PHPExcel_Shared_String::testStringAsNumeric($month) : 0; - $day = ($day !== NULL) ? PHPExcel_Shared_String::testStringAsNumeric($day) : 0; - if ((!is_numeric($year)) || - (!is_numeric($month)) || - (!is_numeric($day))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $year = (integer) $year; - $month = (integer) $month; - $day = (integer) $day; - - $baseYear = PHPExcel_Shared_Date::getExcelCalendar(); - // Validate parameters - if ($year < ($baseYear-1900)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ((($baseYear-1900) != 0) && ($year < $baseYear) && ($year >= 1900)) { - return PHPExcel_Calculation_Functions::NaN(); - } - - if (($year < $baseYear) && ($year >= ($baseYear-1900))) { - $year += 1900; - } - - if ($month < 1) { - // Handle year/month adjustment if month < 1 - --$month; - $year += ceil($month / 12) - 1; - $month = 13 - abs($month % 12); - } elseif ($month > 12) { - // Handle year/month adjustment if month > 12 - $year += floor($month / 12); - $month = ($month % 12); - } - - // Re-validate the year parameter after adjustments - if (($year < $baseYear) || ($year >= 10000)) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Execute function - $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year, $month, $day); - switch (PHPExcel_Calculation_Functions::getReturnDateType()) { - case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : - return (float) $excelDateValue; - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : - return (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateValue); - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : - return PHPExcel_Shared_Date::ExcelToPHPObject($excelDateValue); - } - } // function DATE() - - - /** - * TIME - * - * The TIME function returns a value that represents a particular time. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time - * format of your regional settings. PHPExcel does not change cell formatting in this way. - * - * Excel Function: - * TIME(hour,minute,second) - * - * @access public - * @category Date/Time Functions - * @param integer $hour A number from 0 (zero) to 32767 representing the hour. - * Any value greater than 23 will be divided by 24 and the remainder - * will be treated as the hour value. For example, TIME(27,0,0) = - * TIME(3,0,0) = .125 or 3:00 AM. - * @param integer $minute A number from 0 to 32767 representing the minute. - * Any value greater than 59 will be converted to hours and minutes. - * For example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM. - * @param integer $second A number from 0 to 32767 representing the second. - * Any value greater than 59 will be converted to hours, minutes, - * and seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148 - * or 12:33:20 AM - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function TIME($hour = 0, $minute = 0, $second = 0) { - $hour = PHPExcel_Calculation_Functions::flattenSingleValue($hour); - $minute = PHPExcel_Calculation_Functions::flattenSingleValue($minute); - $second = PHPExcel_Calculation_Functions::flattenSingleValue($second); - - if ($hour == '') { $hour = 0; } - if ($minute == '') { $minute = 0; } - if ($second == '') { $second = 0; } - - if ((!is_numeric($hour)) || (!is_numeric($minute)) || (!is_numeric($second))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $hour = (integer) $hour; - $minute = (integer) $minute; - $second = (integer) $second; - - if ($second < 0) { - $minute += floor($second / 60); - $second = 60 - abs($second % 60); - if ($second == 60) { $second = 0; } - } elseif ($second >= 60) { - $minute += floor($second / 60); - $second = $second % 60; - } - if ($minute < 0) { - $hour += floor($minute / 60); - $minute = 60 - abs($minute % 60); - if ($minute == 60) { $minute = 0; } - } elseif ($minute >= 60) { - $hour += floor($minute / 60); - $minute = $minute % 60; - } - - if ($hour > 23) { - $hour = $hour % 24; - } elseif ($hour < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Execute function - switch (PHPExcel_Calculation_Functions::getReturnDateType()) { - case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : - $date = 0; - $calendar = PHPExcel_Shared_Date::getExcelCalendar(); - if ($calendar != PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900) { - $date = 1; - } - return (float) PHPExcel_Shared_Date::FormattedPHPToExcel($calendar, 1, $date, $hour, $minute, $second); - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : - return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::FormattedPHPToExcel(1970, 1, 1, $hour, $minute, $second)); // -2147468400; // -2147472000 + 3600 - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : - $dayAdjust = 0; - if ($hour < 0) { - $dayAdjust = floor($hour / 24); - $hour = 24 - abs($hour % 24); - if ($hour == 24) { $hour = 0; } - } elseif ($hour >= 24) { - $dayAdjust = floor($hour / 24); - $hour = $hour % 24; - } - $phpDateObject = new DateTime('1900-01-01 '.$hour.':'.$minute.':'.$second); - if ($dayAdjust != 0) { - $phpDateObject->modify($dayAdjust.' days'); - } - return $phpDateObject; - } - } // function TIME() - - - /** - * DATEVALUE - * - * Returns a value that represents a particular date. - * Use DATEVALUE to convert a date represented by a text string to an Excel or PHP date/time stamp - * value. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date - * format of your regional settings. PHPExcel does not change cell formatting in this way. - * - * Excel Function: - * DATEVALUE(dateValue) - * - * @access public - * @category Date/Time Functions - * @param string $dateValue Text that represents a date in a Microsoft Excel date format. - * For example, "1/30/2008" or "30-Jan-2008" are text strings within - * quotation marks that represent dates. Using the default date - * system in Excel for Windows, date_text must represent a date from - * January 1, 1900, to December 31, 9999. Using the default date - * system in Excel for the Macintosh, date_text must represent a date - * from January 1, 1904, to December 31, 9999. DATEVALUE returns the - * #VALUE! error value if date_text is out of this range. - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function DATEVALUE($dateValue = 1) { - $dateValue = trim(PHPExcel_Calculation_Functions::flattenSingleValue($dateValue),'"'); - // Strip any ordinals because they're allowed in Excel (English only) - $dateValue = preg_replace('/(\d)(st|nd|rd|th)([ -\/])/Ui','$1$3',$dateValue); - // Convert separators (/ . or space) to hyphens (should also handle dot used for ordinals in some countries, e.g. Denmark, Germany) - $dateValue = str_replace(array('/','.','-',' '),array(' ',' ',' ',' '),$dateValue); - - $yearFound = false; - $t1 = explode(' ',$dateValue); - foreach($t1 as &$t) { - if ((is_numeric($t)) && ($t > 31)) { - if ($yearFound) { - return PHPExcel_Calculation_Functions::VALUE(); - } else { - if ($t < 100) { $t += 1900; } - $yearFound = true; - } - } - } - if ((count($t1) == 1) && (strpos($t,':') != false)) { - // We've been fed a time value without any date - return 0.0; - } elseif (count($t1) == 2) { - // We only have two parts of the date: either day/month or month/year - if ($yearFound) { - array_unshift($t1,1); - } else { - array_push($t1,date('Y')); - } - } - unset($t); - $dateValue = implode(' ',$t1); - - $PHPDateArray = date_parse($dateValue); - if (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) { - $testVal1 = strtok($dateValue,'- '); - if ($testVal1 !== False) { - $testVal2 = strtok('- '); - if ($testVal2 !== False) { - $testVal3 = strtok('- '); - if ($testVal3 === False) { - $testVal3 = strftime('%Y'); - } - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - $PHPDateArray = date_parse($testVal1.'-'.$testVal2.'-'.$testVal3); - if (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) { - $PHPDateArray = date_parse($testVal2.'-'.$testVal1.'-'.$testVal3); - if (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - } - - if (($PHPDateArray !== False) && ($PHPDateArray['error_count'] == 0)) { - // Execute function - if ($PHPDateArray['year'] == '') { $PHPDateArray['year'] = strftime('%Y'); } - if ($PHPDateArray['year'] < 1900) - return PHPExcel_Calculation_Functions::VALUE(); - if ($PHPDateArray['month'] == '') { $PHPDateArray['month'] = strftime('%m'); } - if ($PHPDateArray['day'] == '') { $PHPDateArray['day'] = strftime('%d'); } - $excelDateValue = floor(PHPExcel_Shared_Date::FormattedPHPToExcel($PHPDateArray['year'],$PHPDateArray['month'],$PHPDateArray['day'],$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second'])); - - switch (PHPExcel_Calculation_Functions::getReturnDateType()) { - case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : - return (float) $excelDateValue; - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : - return (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateValue); - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : - return new DateTime($PHPDateArray['year'].'-'.$PHPDateArray['month'].'-'.$PHPDateArray['day'].' 00:00:00'); - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function DATEVALUE() - - - /** - * TIMEVALUE - * - * Returns a value that represents a particular time. - * Use TIMEVALUE to convert a time represented by a text string to an Excel or PHP date/time stamp - * value. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time - * format of your regional settings. PHPExcel does not change cell formatting in this way. - * - * Excel Function: - * TIMEVALUE(timeValue) - * - * @access public - * @category Date/Time Functions - * @param string $timeValue A text string that represents a time in any one of the Microsoft - * Excel time formats; for example, "6:45 PM" and "18:45" text strings - * within quotation marks that represent time. - * Date information in time_text is ignored. - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function TIMEVALUE($timeValue) { - $timeValue = trim(PHPExcel_Calculation_Functions::flattenSingleValue($timeValue),'"'); - $timeValue = str_replace(array('/','.'),array('-','-'),$timeValue); - - $PHPDateArray = date_parse($timeValue); - if (($PHPDateArray !== False) && ($PHPDateArray['error_count'] == 0)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel($PHPDateArray['year'],$PHPDateArray['month'],$PHPDateArray['day'],$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second']); - } else { - $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel(1900,1,1,$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second']) - 1; - } - - switch (PHPExcel_Calculation_Functions::getReturnDateType()) { - case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : - return (float) $excelDateValue; - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : - return (integer) $phpDateValue = PHPExcel_Shared_Date::ExcelToPHP($excelDateValue+25569) - 3600;; - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : - return new DateTime('1900-01-01 '.$PHPDateArray['hour'].':'.$PHPDateArray['minute'].':'.$PHPDateArray['second']); - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function TIMEVALUE() - - - /** - * DATEDIF - * - * @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object - * or a standard date string - * @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object - * or a standard date string - * @param string $unit - * @return integer Interval between the dates - */ - public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') { - $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); - $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); - $unit = strtoupper(PHPExcel_Calculation_Functions::flattenSingleValue($unit)); - - if (is_string($startDate = self::_getDateValue($startDate))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (is_string($endDate = self::_getDateValue($endDate))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - // Validate parameters - if ($startDate >= $endDate) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Execute function - $difference = $endDate - $startDate; - - $PHPStartDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($startDate); - $startDays = $PHPStartDateObject->format('j'); - $startMonths = $PHPStartDateObject->format('n'); - $startYears = $PHPStartDateObject->format('Y'); - - $PHPEndDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($endDate); - $endDays = $PHPEndDateObject->format('j'); - $endMonths = $PHPEndDateObject->format('n'); - $endYears = $PHPEndDateObject->format('Y'); - - $retVal = PHPExcel_Calculation_Functions::NaN(); - switch ($unit) { - case 'D': - $retVal = intval($difference); - break; - case 'M': - $retVal = intval($endMonths - $startMonths) + (intval($endYears - $startYears) * 12); - // We're only interested in full months - if ($endDays < $startDays) { - --$retVal; - } - break; - case 'Y': - $retVal = intval($endYears - $startYears); - // We're only interested in full months - if ($endMonths < $startMonths) { - --$retVal; - } elseif (($endMonths == $startMonths) && ($endDays < $startDays)) { - --$retVal; - } - break; - case 'MD': - if ($endDays < $startDays) { - $retVal = $endDays; - $PHPEndDateObject->modify('-'.$endDays.' days'); - $adjustDays = $PHPEndDateObject->format('j'); - if ($adjustDays > $startDays) { - $retVal += ($adjustDays - $startDays); - } - } else { - $retVal = $endDays - $startDays; - } - break; - case 'YM': - $retVal = intval($endMonths - $startMonths); - if ($retVal < 0) $retVal = 12 + $retVal; - // We're only interested in full months - if ($endDays < $startDays) { - --$retVal; - } - break; - case 'YD': - $retVal = intval($difference); - if ($endYears > $startYears) { - while ($endYears > $startYears) { - $PHPEndDateObject->modify('-1 year'); - $endYears = $PHPEndDateObject->format('Y'); - } - $retVal = $PHPEndDateObject->format('z') - $PHPStartDateObject->format('z'); - if ($retVal < 0) { $retVal += 365; } - } - break; - default: - $retVal = PHPExcel_Calculation_Functions::NaN(); - } - return $retVal; - } // function DATEDIF() - - - /** - * DAYS360 - * - * Returns the number of days between two dates based on a 360-day year (twelve 30-day months), - * which is used in some accounting calculations. Use this function to help compute payments if - * your accounting system is based on twelve 30-day months. - * - * Excel Function: - * DAYS360(startDate,endDate[,method]) - * - * @access public - * @category Date/Time Functions - * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param boolean $method US or European Method - * FALSE or omitted: U.S. (NASD) method. If the starting date is - * the last day of a month, it becomes equal to the 30th of the - * same month. If the ending date is the last day of a month and - * the starting date is earlier than the 30th of a month, the - * ending date becomes equal to the 1st of the next month; - * otherwise the ending date becomes equal to the 30th of the - * same month. - * TRUE: European method. Starting dates and ending dates that - * occur on the 31st of a month become equal to the 30th of the - * same month. - * @return integer Number of days between start date and end date - */ - public static function DAYS360($startDate = 0, $endDate = 0, $method = false) { - $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); - $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); - - if (is_string($startDate = self::_getDateValue($startDate))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (is_string($endDate = self::_getDateValue($endDate))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (!is_bool($method)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - // Execute function - $PHPStartDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($startDate); - $startDay = $PHPStartDateObject->format('j'); - $startMonth = $PHPStartDateObject->format('n'); - $startYear = $PHPStartDateObject->format('Y'); - - $PHPEndDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($endDate); - $endDay = $PHPEndDateObject->format('j'); - $endMonth = $PHPEndDateObject->format('n'); - $endYear = $PHPEndDateObject->format('Y'); - - return self::_dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, !$method); - } // function DAYS360() - - - /** - * YEARFRAC - * - * Calculates the fraction of the year represented by the number of whole days between two dates - * (the start_date and the end_date). - * Use the YEARFRAC worksheet function to identify the proportion of a whole year's benefits or - * obligations to assign to a specific term. - * - * Excel Function: - * YEARFRAC(startDate,endDate[,method]) - * - * @access public - * @category Date/Time Functions - * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param integer $method Method used for the calculation - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float fraction of the year - */ - public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) { - $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); - $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); - $method = PHPExcel_Calculation_Functions::flattenSingleValue($method); - - if (is_string($startDate = self::_getDateValue($startDate))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (is_string($endDate = self::_getDateValue($endDate))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (((is_numeric($method)) && (!is_string($method))) || ($method == '')) { - switch($method) { - case 0 : - return self::DAYS360($startDate,$endDate) / 360; - case 1 : - $days = self::DATEDIF($startDate,$endDate); - $startYear = self::YEAR($startDate); - $endYear = self::YEAR($endDate); - $years = $endYear - $startYear + 1; - $leapDays = 0; - if ($years == 1) { - if (self::_isLeapYear($endYear)) { - $startMonth = self::MONTHOFYEAR($startDate); - $endMonth = self::MONTHOFYEAR($endDate); - $endDay = self::DAYOFMONTH($endDate); - if (($startMonth < 3) || - (($endMonth * 100 + $endDay) >= (2 * 100 + 29))) { - $leapDays += 1; - } - } - } else { - for($year = $startYear; $year <= $endYear; ++$year) { - if ($year == $startYear) { - $startMonth = self::MONTHOFYEAR($startDate); - $startDay = self::DAYOFMONTH($startDate); - if ($startMonth < 3) { - $leapDays += (self::_isLeapYear($year)) ? 1 : 0; - } - } elseif($year == $endYear) { - $endMonth = self::MONTHOFYEAR($endDate); - $endDay = self::DAYOFMONTH($endDate); - if (($endMonth * 100 + $endDay) >= (2 * 100 + 29)) { - $leapDays += (self::_isLeapYear($year)) ? 1 : 0; - } - } else { - $leapDays += (self::_isLeapYear($year)) ? 1 : 0; - } - } - if ($years == 2) { - if (($leapDays == 0) && (self::_isLeapYear($startYear)) && ($days > 365)) { - $leapDays = 1; - } elseif ($days < 366) { - $years = 1; - } - } - $leapDays /= $years; - } - return $days / (365 + $leapDays); - case 2 : - return self::DATEDIF($startDate,$endDate) / 360; - case 3 : - return self::DATEDIF($startDate,$endDate) / 365; - case 4 : - return self::DAYS360($startDate,$endDate,True) / 360; - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function YEARFRAC() - - - /** - * NETWORKDAYS - * - * Returns the number of whole working days between start_date and end_date. Working days - * exclude weekends and any dates identified in holidays. - * Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days - * worked during a specific term. - * - * Excel Function: - * NETWORKDAYS(startDate,endDate[,holidays[,holiday[,...]]]) - * - * @access public - * @category Date/Time Functions - * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param mixed $holidays,... Optional series of Excel date serial value (float), PHP date - * timestamp (integer), PHP DateTime object, or a standard date - * strings that will be excluded from the working calendar, such - * as state and federal holidays and floating holidays. - * @return integer Interval between the dates - */ - public static function NETWORKDAYS($startDate,$endDate) { - // Retrieve the mandatory start and end date that are referenced in the function definition - $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); - $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); - // Flush the mandatory start and end date that are referenced in the function definition, and get the optional days - $dateArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - array_shift($dateArgs); - array_shift($dateArgs); - - // Validate the start and end dates - if (is_string($startDate = $sDate = self::_getDateValue($startDate))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $startDate = (float) floor($startDate); - if (is_string($endDate = $eDate = self::_getDateValue($endDate))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $endDate = (float) floor($endDate); - - if ($sDate > $eDate) { - $startDate = $eDate; - $endDate = $sDate; - } - - // Execute function - $startDoW = 6 - self::DAYOFWEEK($startDate,2); - if ($startDoW < 0) { $startDoW = 0; } - $endDoW = self::DAYOFWEEK($endDate,2); - if ($endDoW >= 6) { $endDoW = 0; } - - $wholeWeekDays = floor(($endDate - $startDate) / 7) * 5; - $partWeekDays = $endDoW + $startDoW; - if ($partWeekDays > 5) { - $partWeekDays -= 5; - } - - // Test any extra holiday parameters - $holidayCountedArray = array(); - foreach ($dateArgs as $holidayDate) { - if (is_string($holidayDate = self::_getDateValue($holidayDate))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { - if ((self::DAYOFWEEK($holidayDate,2) < 6) && (!in_array($holidayDate,$holidayCountedArray))) { - --$partWeekDays; - $holidayCountedArray[] = $holidayDate; - } - } - } - - if ($sDate > $eDate) { - return 0 - ($wholeWeekDays + $partWeekDays); - } - return $wholeWeekDays + $partWeekDays; - } // function NETWORKDAYS() - - - /** - * WORKDAY - * - * Returns the date that is the indicated number of working days before or after a date (the - * starting date). Working days exclude weekends and any dates identified as holidays. - * Use WORKDAY to exclude weekends or holidays when you calculate invoice due dates, expected - * delivery times, or the number of days of work performed. - * - * Excel Function: - * WORKDAY(startDate,endDays[,holidays[,holiday[,...]]]) - * - * @access public - * @category Date/Time Functions - * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param integer $endDays The number of nonweekend and nonholiday days before or after - * startDate. A positive value for days yields a future date; a - * negative value yields a past date. - * @param mixed $holidays,... Optional series of Excel date serial value (float), PHP date - * timestamp (integer), PHP DateTime object, or a standard date - * strings that will be excluded from the working calendar, such - * as state and federal holidays and floating holidays. - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function WORKDAY($startDate,$endDays) { - // Retrieve the mandatory start date and days that are referenced in the function definition - $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); - $endDays = PHPExcel_Calculation_Functions::flattenSingleValue($endDays); - // Flush the mandatory start date and days that are referenced in the function definition, and get the optional days - $dateArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - array_shift($dateArgs); - array_shift($dateArgs); - - if ((is_string($startDate = self::_getDateValue($startDate))) || (!is_numeric($endDays))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $startDate = (float) floor($startDate); - $endDays = (int) floor($endDays); - // If endDays is 0, we always return startDate - if ($endDays == 0) { return $startDate; } - - $decrementing = ($endDays < 0) ? True : False; - - // Adjust the start date if it falls over a weekend - - $startDoW = self::DAYOFWEEK($startDate,3); - if (self::DAYOFWEEK($startDate,3) >= 5) { - $startDate += ($decrementing) ? -$startDoW + 4: 7 - $startDoW; - ($decrementing) ? $endDays++ : $endDays--; - } - - // Add endDays - $endDate = (float) $startDate + (intval($endDays / 5) * 7) + ($endDays % 5); - - // Adjust the calculated end date if it falls over a weekend - $endDoW = self::DAYOFWEEK($endDate,3); - if ($endDoW >= 5) { - $endDate += ($decrementing) ? -$endDoW + 4: 7 - $endDoW; - } - - // Test any extra holiday parameters - if (!empty($dateArgs)) { - $holidayCountedArray = $holidayDates = array(); - foreach ($dateArgs as $holidayDate) { - if (($holidayDate !== NULL) && (trim($holidayDate) > '')) { - if (is_string($holidayDate = self::_getDateValue($holidayDate))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (self::DAYOFWEEK($holidayDate,3) < 5) { - $holidayDates[] = $holidayDate; - } - } - } - if ($decrementing) { - rsort($holidayDates, SORT_NUMERIC); - } else { - sort($holidayDates, SORT_NUMERIC); - } - foreach ($holidayDates as $holidayDate) { - if ($decrementing) { - if (($holidayDate <= $startDate) && ($holidayDate >= $endDate)) { - if (!in_array($holidayDate,$holidayCountedArray)) { - --$endDate; - $holidayCountedArray[] = $holidayDate; - } - } - } else { - if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { - if (!in_array($holidayDate,$holidayCountedArray)) { - ++$endDate; - $holidayCountedArray[] = $holidayDate; - } - } - } - // Adjust the calculated end date if it falls over a weekend - $endDoW = self::DAYOFWEEK($endDate,3); - if ($endDoW >= 5) { - $endDate += ($decrementing) ? -$endDoW + 4: 7 - $endDoW; - } - - } - } - - switch (PHPExcel_Calculation_Functions::getReturnDateType()) { - case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : - return (float) $endDate; - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : - return (integer) PHPExcel_Shared_Date::ExcelToPHP($endDate); - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : - return PHPExcel_Shared_Date::ExcelToPHPObject($endDate); - } - } // function WORKDAY() - - - /** - * DAYOFMONTH - * - * Returns the day of the month, for a specified date. The day is given as an integer - * ranging from 1 to 31. - * - * Excel Function: - * DAY(dateValue) - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @return int Day of the month - */ - public static function DAYOFMONTH($dateValue = 1) { - $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); - - if ($dateValue === null) { + } + + $year = ($year !== null) ? PHPExcel_Shared_String::testStringAsNumeric($year) : 0; + $month = ($month !== null) ? PHPExcel_Shared_String::testStringAsNumeric($month) : 0; + $day = ($day !== null) ? PHPExcel_Shared_String::testStringAsNumeric($day) : 0; + if ((!is_numeric($year)) || + (!is_numeric($month)) || + (!is_numeric($day))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $year = (integer) $year; + $month = (integer) $month; + $day = (integer) $day; + + $baseYear = PHPExcel_Shared_Date::getExcelCalendar(); + // Validate parameters + if ($year < ($baseYear-1900)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((($baseYear-1900) != 0) && ($year < $baseYear) && ($year >= 1900)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (($year < $baseYear) && ($year >= ($baseYear-1900))) { + $year += 1900; + } + + if ($month < 1) { + // Handle year/month adjustment if month < 1 + --$month; + $year += ceil($month / 12) - 1; + $month = 13 - abs($month % 12); + } elseif ($month > 12) { + // Handle year/month adjustment if month > 12 + $year += floor($month / 12); + $month = ($month % 12); + } + + // Re-validate the year parameter after adjustments + if (($year < $baseYear) || ($year >= 10000)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year, $month, $day); + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL: + return (float) $excelDateValue; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC: + return (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateValue); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT: + return PHPExcel_Shared_Date::ExcelToPHPObject($excelDateValue); + } + } + + + /** + * TIME + * + * The TIME function returns a value that represents a particular time. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * TIME(hour,minute,second) + * + * @access public + * @category Date/Time Functions + * @param integer $hour A number from 0 (zero) to 32767 representing the hour. + * Any value greater than 23 will be divided by 24 and the remainder + * will be treated as the hour value. For example, TIME(27,0,0) = + * TIME(3,0,0) = .125 or 3:00 AM. + * @param integer $minute A number from 0 to 32767 representing the minute. + * Any value greater than 59 will be converted to hours and minutes. + * For example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM. + * @param integer $second A number from 0 to 32767 representing the second. + * Any value greater than 59 will be converted to hours, minutes, + * and seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148 + * or 12:33:20 AM + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function TIME($hour = 0, $minute = 0, $second = 0) + { + $hour = PHPExcel_Calculation_Functions::flattenSingleValue($hour); + $minute = PHPExcel_Calculation_Functions::flattenSingleValue($minute); + $second = PHPExcel_Calculation_Functions::flattenSingleValue($second); + + if ($hour == '') { + $hour = 0; + } + if ($minute == '') { + $minute = 0; + } + if ($second == '') { + $second = 0; + } + + if ((!is_numeric($hour)) || (!is_numeric($minute)) || (!is_numeric($second))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $hour = (integer) $hour; + $minute = (integer) $minute; + $second = (integer) $second; + + if ($second < 0) { + $minute += floor($second / 60); + $second = 60 - abs($second % 60); + if ($second == 60) { + $second = 0; + } + } elseif ($second >= 60) { + $minute += floor($second / 60); + $second = $second % 60; + } + if ($minute < 0) { + $hour += floor($minute / 60); + $minute = 60 - abs($minute % 60); + if ($minute == 60) { + $minute = 0; + } + } elseif ($minute >= 60) { + $hour += floor($minute / 60); + $minute = $minute % 60; + } + + if ($hour > 23) { + $hour = $hour % 24; + } elseif ($hour < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL: + $date = 0; + $calendar = PHPExcel_Shared_Date::getExcelCalendar(); + if ($calendar != PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900) { + $date = 1; + } + return (float) PHPExcel_Shared_Date::FormattedPHPToExcel($calendar, 1, $date, $hour, $minute, $second); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC: + return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::FormattedPHPToExcel(1970, 1, 1, $hour, $minute, $second)); // -2147468400; // -2147472000 + 3600 + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT: + $dayAdjust = 0; + if ($hour < 0) { + $dayAdjust = floor($hour / 24); + $hour = 24 - abs($hour % 24); + if ($hour == 24) { + $hour = 0; + } + } elseif ($hour >= 24) { + $dayAdjust = floor($hour / 24); + $hour = $hour % 24; + } + $phpDateObject = new DateTime('1900-01-01 '.$hour.':'.$minute.':'.$second); + if ($dayAdjust != 0) { + $phpDateObject->modify($dayAdjust.' days'); + } + return $phpDateObject; + } + } + + + /** + * DATEVALUE + * + * Returns a value that represents a particular date. + * Use DATEVALUE to convert a date represented by a text string to an Excel or PHP date/time stamp + * value. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * DATEVALUE(dateValue) + * + * @access public + * @category Date/Time Functions + * @param string $dateValue Text that represents a date in a Microsoft Excel date format. + * For example, "1/30/2008" or "30-Jan-2008" are text strings within + * quotation marks that represent dates. Using the default date + * system in Excel for Windows, date_text must represent a date from + * January 1, 1900, to December 31, 9999. Using the default date + * system in Excel for the Macintosh, date_text must represent a date + * from January 1, 1904, to December 31, 9999. DATEVALUE returns the + * #VALUE! error value if date_text is out of this range. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATEVALUE($dateValue = 1) + { + $dateValue = trim(PHPExcel_Calculation_Functions::flattenSingleValue($dateValue), '"'); + // Strip any ordinals because they're allowed in Excel (English only) + $dateValue = preg_replace('/(\d)(st|nd|rd|th)([ -\/])/Ui', '$1$3', $dateValue); + // Convert separators (/ . or space) to hyphens (should also handle dot used for ordinals in some countries, e.g. Denmark, Germany) + $dateValue = str_replace(array('/', '.', '-', ' '), array(' ', ' ', ' ', ' '), $dateValue); + + $yearFound = false; + $t1 = explode(' ', $dateValue); + foreach ($t1 as &$t) { + if ((is_numeric($t)) && ($t > 31)) { + if ($yearFound) { + return PHPExcel_Calculation_Functions::VALUE(); + } else { + if ($t < 100) { + $t += 1900; + } + $yearFound = true; + } + } + } + if ((count($t1) == 1) && (strpos($t, ':') != false)) { + // We've been fed a time value without any date + return 0.0; + } elseif (count($t1) == 2) { + // We only have two parts of the date: either day/month or month/year + if ($yearFound) { + array_unshift($t1, 1); + } else { + array_push($t1, date('Y')); + } + } + unset($t); + $dateValue = implode(' ', $t1); + + $PHPDateArray = date_parse($dateValue); + if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) { + $testVal1 = strtok($dateValue, '- '); + if ($testVal1 !== false) { + $testVal2 = strtok('- '); + if ($testVal2 !== false) { + $testVal3 = strtok('- '); + if ($testVal3 === false) { + $testVal3 = strftime('%Y'); + } + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $PHPDateArray = date_parse($testVal1.'-'.$testVal2.'-'.$testVal3); + if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) { + $PHPDateArray = date_parse($testVal2.'-'.$testVal1.'-'.$testVal3); + if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + } + + if (($PHPDateArray !== false) && ($PHPDateArray['error_count'] == 0)) { + // Execute function + if ($PHPDateArray['year'] == '') { + $PHPDateArray['year'] = strftime('%Y'); + } + if ($PHPDateArray['year'] < 1900) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if ($PHPDateArray['month'] == '') { + $PHPDateArray['month'] = strftime('%m'); + } + if ($PHPDateArray['day'] == '') { + $PHPDateArray['day'] = strftime('%d'); + } + $excelDateValue = floor( + PHPExcel_Shared_Date::FormattedPHPToExcel( + $PHPDateArray['year'], + $PHPDateArray['month'], + $PHPDateArray['day'], + $PHPDateArray['hour'], + $PHPDateArray['minute'], + $PHPDateArray['second'] + ) + ); + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL: + return (float) $excelDateValue; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC: + return (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateValue); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT: + return new DateTime($PHPDateArray['year'].'-'.$PHPDateArray['month'].'-'.$PHPDateArray['day'].' 00:00:00'); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + /** + * TIMEVALUE + * + * Returns a value that represents a particular time. + * Use TIMEVALUE to convert a time represented by a text string to an Excel or PHP date/time stamp + * value. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * TIMEVALUE(timeValue) + * + * @access public + * @category Date/Time Functions + * @param string $timeValue A text string that represents a time in any one of the Microsoft + * Excel time formats; for example, "6:45 PM" and "18:45" text strings + * within quotation marks that represent time. + * Date information in time_text is ignored. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function TIMEVALUE($timeValue) + { + $timeValue = trim(PHPExcel_Calculation_Functions::flattenSingleValue($timeValue), '"'); + $timeValue = str_replace(array('/', '.'), array('-', '-'), $timeValue); + + $PHPDateArray = date_parse($timeValue); + if (($PHPDateArray !== false) && ($PHPDateArray['error_count'] == 0)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel( + $PHPDateArray['year'], + $PHPDateArray['month'], + $PHPDateArray['day'], + $PHPDateArray['hour'], + $PHPDateArray['minute'], + $PHPDateArray['second'] + ); + } else { + $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel(1900, 1, 1, $PHPDateArray['hour'], $PHPDateArray['minute'], $PHPDateArray['second']) - 1; + } + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL: + return (float) $excelDateValue; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC: + return (integer) $phpDateValue = PHPExcel_Shared_Date::ExcelToPHP($excelDateValue+25569) - 3600; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT: + return new DateTime('1900-01-01 '.$PHPDateArray['hour'].':'.$PHPDateArray['minute'].':'.$PHPDateArray['second']); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + /** + * DATEDIF + * + * @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object + * or a standard date string + * @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object + * or a standard date string + * @param string $unit + * @return integer Interval between the dates + */ + public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') + { + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + $unit = strtoupper(PHPExcel_Calculation_Functions::flattenSingleValue($unit)); + + if (is_string($startDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($endDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Validate parameters + if ($startDate >= $endDate) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $difference = $endDate - $startDate; + + $PHPStartDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($startDate); + $startDays = $PHPStartDateObject->format('j'); + $startMonths = $PHPStartDateObject->format('n'); + $startYears = $PHPStartDateObject->format('Y'); + + $PHPEndDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($endDate); + $endDays = $PHPEndDateObject->format('j'); + $endMonths = $PHPEndDateObject->format('n'); + $endYears = $PHPEndDateObject->format('Y'); + + $retVal = PHPExcel_Calculation_Functions::NaN(); + switch ($unit) { + case 'D': + $retVal = intval($difference); + break; + case 'M': + $retVal = intval($endMonths - $startMonths) + (intval($endYears - $startYears) * 12); + // We're only interested in full months + if ($endDays < $startDays) { + --$retVal; + } + break; + case 'Y': + $retVal = intval($endYears - $startYears); + // We're only interested in full months + if ($endMonths < $startMonths) { + --$retVal; + } elseif (($endMonths == $startMonths) && ($endDays < $startDays)) { + --$retVal; + } + break; + case 'MD': + if ($endDays < $startDays) { + $retVal = $endDays; + $PHPEndDateObject->modify('-'.$endDays.' days'); + $adjustDays = $PHPEndDateObject->format('j'); + if ($adjustDays > $startDays) { + $retVal += ($adjustDays - $startDays); + } + } else { + $retVal = $endDays - $startDays; + } + break; + case 'YM': + $retVal = intval($endMonths - $startMonths); + if ($retVal < 0) { + $retVal += 12; + } + // We're only interested in full months + if ($endDays < $startDays) { + --$retVal; + } + break; + case 'YD': + $retVal = intval($difference); + if ($endYears > $startYears) { + while ($endYears > $startYears) { + $PHPEndDateObject->modify('-1 year'); + $endYears = $PHPEndDateObject->format('Y'); + } + $retVal = $PHPEndDateObject->format('z') - $PHPStartDateObject->format('z'); + if ($retVal < 0) { + $retVal += 365; + } + } + break; + default: + $retVal = PHPExcel_Calculation_Functions::NaN(); + } + return $retVal; + } + + + /** + * DAYS360 + * + * Returns the number of days between two dates based on a 360-day year (twelve 30-day months), + * which is used in some accounting calculations. Use this function to help compute payments if + * your accounting system is based on twelve 30-day months. + * + * Excel Function: + * DAYS360(startDate,endDate[,method]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param boolean $method US or European Method + * FALSE or omitted: U.S. (NASD) method. If the starting date is + * the last day of a month, it becomes equal to the 30th of the + * same month. If the ending date is the last day of a month and + * the starting date is earlier than the 30th of a month, the + * ending date becomes equal to the 1st of the next month; + * otherwise the ending date becomes equal to the 30th of the + * same month. + * TRUE: European method. Starting dates and ending dates that + * occur on the 31st of a month become equal to the 30th of the + * same month. + * @return integer Number of days between start date and end date + */ + public static function DAYS360($startDate = 0, $endDate = 0, $method = false) + { + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + + if (is_string($startDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($endDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (!is_bool($method)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Execute function + $PHPStartDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($startDate); + $startDay = $PHPStartDateObject->format('j'); + $startMonth = $PHPStartDateObject->format('n'); + $startYear = $PHPStartDateObject->format('Y'); + + $PHPEndDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($endDate); + $endDay = $PHPEndDateObject->format('j'); + $endMonth = $PHPEndDateObject->format('n'); + $endYear = $PHPEndDateObject->format('Y'); + + return self::dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, !$method); + } + + + /** + * YEARFRAC + * + * Calculates the fraction of the year represented by the number of whole days between two dates + * (the start_date and the end_date). + * Use the YEARFRAC worksheet function to identify the proportion of a whole year's benefits or + * obligations to assign to a specific term. + * + * Excel Function: + * YEARFRAC(startDate,endDate[,method]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param integer $method Method used for the calculation + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float fraction of the year + */ + public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) + { + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + $method = PHPExcel_Calculation_Functions::flattenSingleValue($method); + + if (is_string($startDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($endDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (((is_numeric($method)) && (!is_string($method))) || ($method == '')) { + switch($method) { + case 0: + return self::DAYS360($startDate, $endDate) / 360; + case 1: + $days = self::DATEDIF($startDate, $endDate); + $startYear = self::YEAR($startDate); + $endYear = self::YEAR($endDate); + $years = $endYear - $startYear + 1; + $leapDays = 0; + if ($years == 1) { + if (self::isLeapYear($endYear)) { + $startMonth = self::MONTHOFYEAR($startDate); + $endMonth = self::MONTHOFYEAR($endDate); + $endDay = self::DAYOFMONTH($endDate); + if (($startMonth < 3) || + (($endMonth * 100 + $endDay) >= (2 * 100 + 29))) { + $leapDays += 1; + } + } + } else { + for ($year = $startYear; $year <= $endYear; ++$year) { + if ($year == $startYear) { + $startMonth = self::MONTHOFYEAR($startDate); + $startDay = self::DAYOFMONTH($startDate); + if ($startMonth < 3) { + $leapDays += (self::isLeapYear($year)) ? 1 : 0; + } + } elseif ($year == $endYear) { + $endMonth = self::MONTHOFYEAR($endDate); + $endDay = self::DAYOFMONTH($endDate); + if (($endMonth * 100 + $endDay) >= (2 * 100 + 29)) { + $leapDays += (self::isLeapYear($year)) ? 1 : 0; + } + } else { + $leapDays += (self::isLeapYear($year)) ? 1 : 0; + } + } + if ($years == 2) { + if (($leapDays == 0) && (self::isLeapYear($startYear)) && ($days > 365)) { + $leapDays = 1; + } elseif ($days < 366) { + $years = 1; + } + } + $leapDays /= $years; + } + return $days / (365 + $leapDays); + case 2: + return self::DATEDIF($startDate, $endDate) / 360; + case 3: + return self::DATEDIF($startDate, $endDate) / 365; + case 4: + return self::DAYS360($startDate, $endDate, true) / 360; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + /** + * NETWORKDAYS + * + * Returns the number of whole working days between start_date and end_date. Working days + * exclude weekends and any dates identified in holidays. + * Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days + * worked during a specific term. + * + * Excel Function: + * NETWORKDAYS(startDate,endDate[,holidays[,holiday[,...]]]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $holidays,... Optional series of Excel date serial value (float), PHP date + * timestamp (integer), PHP DateTime object, or a standard date + * strings that will be excluded from the working calendar, such + * as state and federal holidays and floating holidays. + * @return integer Interval between the dates + */ + public static function NETWORKDAYS($startDate, $endDate) + { + // Retrieve the mandatory start and end date that are referenced in the function definition + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + // Flush the mandatory start and end date that are referenced in the function definition, and get the optional days + $dateArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + array_shift($dateArgs); + array_shift($dateArgs); + + // Validate the start and end dates + if (is_string($startDate = $sDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $startDate = (float) floor($startDate); + if (is_string($endDate = $eDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $endDate = (float) floor($endDate); + + if ($sDate > $eDate) { + $startDate = $eDate; + $endDate = $sDate; + } + + // Execute function + $startDoW = 6 - self::DAYOFWEEK($startDate, 2); + if ($startDoW < 0) { + $startDoW = 0; + } + $endDoW = self::DAYOFWEEK($endDate, 2); + if ($endDoW >= 6) { + $endDoW = 0; + } + + $wholeWeekDays = floor(($endDate - $startDate) / 7) * 5; + $partWeekDays = $endDoW + $startDoW; + if ($partWeekDays > 5) { + $partWeekDays -= 5; + } + + // Test any extra holiday parameters + $holidayCountedArray = array(); + foreach ($dateArgs as $holidayDate) { + if (is_string($holidayDate = self::_getDateValue($holidayDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { + if ((self::DAYOFWEEK($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) { + --$partWeekDays; + $holidayCountedArray[] = $holidayDate; + } + } + } + + if ($sDate > $eDate) { + return 0 - ($wholeWeekDays + $partWeekDays); + } + return $wholeWeekDays + $partWeekDays; + } + + + /** + * WORKDAY + * + * Returns the date that is the indicated number of working days before or after a date (the + * starting date). Working days exclude weekends and any dates identified as holidays. + * Use WORKDAY to exclude weekends or holidays when you calculate invoice due dates, expected + * delivery times, or the number of days of work performed. + * + * Excel Function: + * WORKDAY(startDate,endDays[,holidays[,holiday[,...]]]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param integer $endDays The number of nonweekend and nonholiday days before or after + * startDate. A positive value for days yields a future date; a + * negative value yields a past date. + * @param mixed $holidays,... Optional series of Excel date serial value (float), PHP date + * timestamp (integer), PHP DateTime object, or a standard date + * strings that will be excluded from the working calendar, such + * as state and federal holidays and floating holidays. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function WORKDAY($startDate, $endDays) + { + // Retrieve the mandatory start date and days that are referenced in the function definition + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDays = PHPExcel_Calculation_Functions::flattenSingleValue($endDays); + // Flush the mandatory start date and days that are referenced in the function definition, and get the optional days + $dateArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + array_shift($dateArgs); + array_shift($dateArgs); + + if ((is_string($startDate = self::_getDateValue($startDate))) || (!is_numeric($endDays))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $startDate = (float) floor($startDate); + $endDays = (int) floor($endDays); + // If endDays is 0, we always return startDate + if ($endDays == 0) { + return $startDate; + } + + $decrementing = ($endDays < 0) ? true : false; + + // Adjust the start date if it falls over a weekend + + $startDoW = self::DAYOFWEEK($startDate, 3); + if (self::DAYOFWEEK($startDate, 3) >= 5) { + $startDate += ($decrementing) ? -$startDoW + 4: 7 - $startDoW; + ($decrementing) ? $endDays++ : $endDays--; + } + + // Add endDays + $endDate = (float) $startDate + (intval($endDays / 5) * 7) + ($endDays % 5); + + // Adjust the calculated end date if it falls over a weekend + $endDoW = self::DAYOFWEEK($endDate, 3); + if ($endDoW >= 5) { + $endDate += ($decrementing) ? -$endDoW + 4: 7 - $endDoW; + } + + // Test any extra holiday parameters + if (!empty($dateArgs)) { + $holidayCountedArray = $holidayDates = array(); + foreach ($dateArgs as $holidayDate) { + if (($holidayDate !== null) && (trim($holidayDate) > '')) { + if (is_string($holidayDate = self::_getDateValue($holidayDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (self::DAYOFWEEK($holidayDate, 3) < 5) { + $holidayDates[] = $holidayDate; + } + } + } + if ($decrementing) { + rsort($holidayDates, SORT_NUMERIC); + } else { + sort($holidayDates, SORT_NUMERIC); + } + foreach ($holidayDates as $holidayDate) { + if ($decrementing) { + if (($holidayDate <= $startDate) && ($holidayDate >= $endDate)) { + if (!in_array($holidayDate, $holidayCountedArray)) { + --$endDate; + $holidayCountedArray[] = $holidayDate; + } + } + } else { + if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { + if (!in_array($holidayDate, $holidayCountedArray)) { + ++$endDate; + $holidayCountedArray[] = $holidayDate; + } + } + } + // Adjust the calculated end date if it falls over a weekend + $endDoW = self::DAYOFWEEK($endDate, 3); + if ($endDoW >= 5) { + $endDate += ($decrementing) ? -$endDoW + 4 : 7 - $endDoW; + } + } + } + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL: + return (float) $endDate; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC: + return (integer) PHPExcel_Shared_Date::ExcelToPHP($endDate); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT: + return PHPExcel_Shared_Date::ExcelToPHPObject($endDate); + } + } + + + /** + * DAYOFMONTH + * + * Returns the day of the month, for a specified date. The day is given as an integer + * ranging from 1 to 31. + * + * Excel Function: + * DAY(dateValue) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @return int Day of the month + */ + public static function DAYOFMONTH($dateValue = 1) + { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + + if ($dateValue === null) { $dateValue = 1; - } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif ($dateValue == 0.0) { - return 0; - } elseif ($dateValue < 0.0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Execute function - $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); - - return (int) $PHPDateObject->format('j'); - } // function DAYOFMONTH() - - - /** - * DAYOFWEEK - * - * Returns the day of the week for a specified date. The day is given as an integer - * ranging from 0 to 7 (dependent on the requested style). - * - * Excel Function: - * WEEKDAY(dateValue[,style]) - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param int $style A number that determines the type of return value - * 1 or omitted Numbers 1 (Sunday) through 7 (Saturday). - * 2 Numbers 1 (Monday) through 7 (Sunday). - * 3 Numbers 0 (Monday) through 6 (Sunday). - * @return int Day of the week value - */ - public static function DAYOFWEEK($dateValue = 1, $style = 1) { - $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); - $style = PHPExcel_Calculation_Functions::flattenSingleValue($style); - - if (!is_numeric($style)) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif (($style < 1) || ($style > 3)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $style = floor($style); - - if ($dateValue === null) { + } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue == 0.0) { + return 0; + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + + return (int) $PHPDateObject->format('j'); + } + + + /** + * DAYOFWEEK + * + * Returns the day of the week for a specified date. The day is given as an integer + * ranging from 0 to 7 (dependent on the requested style). + * + * Excel Function: + * WEEKDAY(dateValue[,style]) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param int $style A number that determines the type of return value + * 1 or omitted Numbers 1 (Sunday) through 7 (Saturday). + * 2 Numbers 1 (Monday) through 7 (Sunday). + * 3 Numbers 0 (Monday) through 6 (Sunday). + * @return int Day of the week value + */ + public static function DAYOFWEEK($dateValue = 1, $style = 1) + { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $style = PHPExcel_Calculation_Functions::flattenSingleValue($style); + + if (!is_numeric($style)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif (($style < 1) || ($style > 3)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $style = floor($style); + + if ($dateValue === null) { $dateValue = 1; - } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif ($dateValue < 0.0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Execute function - $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); - $DoW = $PHPDateObject->format('w'); - - $firstDay = 1; - switch ($style) { - case 1: ++$DoW; - break; - case 2: if ($DoW == 0) { $DoW = 7; } - break; - case 3: if ($DoW == 0) { $DoW = 7; } - $firstDay = 0; - --$DoW; - break; - } - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL) { - // Test for Excel's 1900 leap year, and introduce the error as required - if (($PHPDateObject->format('Y') == 1900) && ($PHPDateObject->format('n') <= 2)) { - --$DoW; - if ($DoW < $firstDay) { - $DoW += 7; - } - } - } - - return (int) $DoW; - } // function DAYOFWEEK() - - - /** - * WEEKOFYEAR - * - * Returns the week of the year for a specified date. - * The WEEKNUM function considers the week containing January 1 to be the first week of the year. - * However, there is a European standard that defines the first week as the one with the majority - * of days (four or more) falling in the new year. This means that for years in which there are - * three days or less in the first week of January, the WEEKNUM function returns week numbers - * that are incorrect according to the European standard. - * - * Excel Function: - * WEEKNUM(dateValue[,style]) - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param boolean $method Week begins on Sunday or Monday - * 1 or omitted Week begins on Sunday. - * 2 Week begins on Monday. - * @return int Week Number - */ - public static function WEEKOFYEAR($dateValue = 1, $method = 1) { - $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); - $method = PHPExcel_Calculation_Functions::flattenSingleValue($method); - - if (!is_numeric($method)) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif (($method < 1) || ($method > 2)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $method = floor($method); - - if ($dateValue === null) { + } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + $DoW = $PHPDateObject->format('w'); + + $firstDay = 1; + switch ($style) { + case 1: + ++$DoW; + break; + case 2: + if ($DoW == 0) { + $DoW = 7; + } + break; + case 3: + if ($DoW == 0) { + $DoW = 7; + } + $firstDay = 0; + --$DoW; + break; + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL) { + // Test for Excel's 1900 leap year, and introduce the error as required + if (($PHPDateObject->format('Y') == 1900) && ($PHPDateObject->format('n') <= 2)) { + --$DoW; + if ($DoW < $firstDay) { + $DoW += 7; + } + } + } + + return (int) $DoW; + } + + + /** + * WEEKOFYEAR + * + * Returns the week of the year for a specified date. + * The WEEKNUM function considers the week containing January 1 to be the first week of the year. + * However, there is a European standard that defines the first week as the one with the majority + * of days (four or more) falling in the new year. This means that for years in which there are + * three days or less in the first week of January, the WEEKNUM function returns week numbers + * that are incorrect according to the European standard. + * + * Excel Function: + * WEEKNUM(dateValue[,style]) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param boolean $method Week begins on Sunday or Monday + * 1 or omitted Week begins on Sunday. + * 2 Week begins on Monday. + * @return int Week Number + */ + public static function WEEKOFYEAR($dateValue = 1, $method = 1) + { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $method = PHPExcel_Calculation_Functions::flattenSingleValue($method); + + if (!is_numeric($method)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif (($method < 1) || ($method > 2)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $method = floor($method); + + if ($dateValue === null) { $dateValue = 1; - } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif ($dateValue < 0.0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Execute function - $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); - $dayOfYear = $PHPDateObject->format('z'); - $dow = $PHPDateObject->format('w'); - $PHPDateObject->modify('-'.$dayOfYear.' days'); - $dow = $PHPDateObject->format('w'); - $daysInFirstWeek = 7 - (($dow + (2 - $method)) % 7); - $dayOfYear -= $daysInFirstWeek; - $weekOfYear = ceil($dayOfYear / 7) + 1; - - return (int) $weekOfYear; - } // function WEEKOFYEAR() - - - /** - * MONTHOFYEAR - * - * Returns the month of a date represented by a serial number. - * The month is given as an integer, ranging from 1 (January) to 12 (December). - * - * Excel Function: - * MONTH(dateValue) - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @return int Month of the year - */ - public static function MONTHOFYEAR($dateValue = 1) { - $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); - - if ($dateValue === null) { + } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + $dayOfYear = $PHPDateObject->format('z'); + $dow = $PHPDateObject->format('w'); + $PHPDateObject->modify('-' . $dayOfYear . ' days'); + $dow = $PHPDateObject->format('w'); + $daysInFirstWeek = 7 - (($dow + (2 - $method)) % 7); + $dayOfYear -= $daysInFirstWeek; + $weekOfYear = ceil($dayOfYear / 7) + 1; + + return (int) $weekOfYear; + } + + + /** + * MONTHOFYEAR + * + * Returns the month of a date represented by a serial number. + * The month is given as an integer, ranging from 1 (January) to 12 (December). + * + * Excel Function: + * MONTH(dateValue) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @return int Month of the year + */ + public static function MONTHOFYEAR($dateValue = 1) + { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + + if ($dateValue === null) { $dateValue = 1; - } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif ($dateValue < 0.0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Execute function - $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); - - return (int) $PHPDateObject->format('n'); - } // function MONTHOFYEAR() - - - /** - * YEAR - * - * Returns the year corresponding to a date. - * The year is returned as an integer in the range 1900-9999. - * - * Excel Function: - * YEAR(dateValue) - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @return int Year - */ - public static function YEAR($dateValue = 1) { - $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); - - if ($dateValue === null) { + } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + + return (int) $PHPDateObject->format('n'); + } + + + /** + * YEAR + * + * Returns the year corresponding to a date. + * The year is returned as an integer in the range 1900-9999. + * + * Excel Function: + * YEAR(dateValue) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @return int Year + */ + public static function YEAR($dateValue = 1) + { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + + if ($dateValue === null) { $dateValue = 1; - } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif ($dateValue < 0.0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Execute function - $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); - - return (int) $PHPDateObject->format('Y'); - } // function YEAR() - - - /** - * HOUROFDAY - * - * Returns the hour of a time value. - * The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.). - * - * Excel Function: - * HOUR(timeValue) - * - * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard time string - * @return int Hour - */ - public static function HOUROFDAY($timeValue = 0) { - $timeValue = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); - - if (!is_numeric($timeValue)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - $testVal = strtok($timeValue,'/-: '); - if (strlen($testVal) < strlen($timeValue)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - $timeValue = self::_getTimeValue($timeValue); - if (is_string($timeValue)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - // Execute function - if ($timeValue >= 1) { - $timeValue = fmod($timeValue,1); - } elseif ($timeValue < 0.0) { - return PHPExcel_Calculation_Functions::NaN(); - } - $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); - - return (int) gmdate('G',$timeValue); - } // function HOUROFDAY() - - - /** - * MINUTEOFHOUR - * - * Returns the minutes of a time value. - * The minute is given as an integer, ranging from 0 to 59. - * - * Excel Function: - * MINUTE(timeValue) - * - * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard time string - * @return int Minute - */ - public static function MINUTEOFHOUR($timeValue = 0) { - $timeValue = $timeTester = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); - - if (!is_numeric($timeValue)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - $testVal = strtok($timeValue,'/-: '); - if (strlen($testVal) < strlen($timeValue)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - $timeValue = self::_getTimeValue($timeValue); - if (is_string($timeValue)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - // Execute function - if ($timeValue >= 1) { - $timeValue = fmod($timeValue,1); - } elseif ($timeValue < 0.0) { - return PHPExcel_Calculation_Functions::NaN(); - } - $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); - - return (int) gmdate('i',$timeValue); - } // function MINUTEOFHOUR() - - - /** - * SECONDOFMINUTE - * - * Returns the seconds of a time value. - * The second is given as an integer in the range 0 (zero) to 59. - * - * Excel Function: - * SECOND(timeValue) - * - * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard time string - * @return int Second - */ - public static function SECONDOFMINUTE($timeValue = 0) { - $timeValue = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); - - if (!is_numeric($timeValue)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - $testVal = strtok($timeValue,'/-: '); - if (strlen($testVal) < strlen($timeValue)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - $timeValue = self::_getTimeValue($timeValue); - if (is_string($timeValue)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - // Execute function - if ($timeValue >= 1) { - $timeValue = fmod($timeValue,1); - } elseif ($timeValue < 0.0) { - return PHPExcel_Calculation_Functions::NaN(); - } - $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); - - return (int) gmdate('s',$timeValue); - } // function SECONDOFMINUTE() - - - /** - * EDATE - * - * Returns the serial number that represents the date that is the indicated number of months - * before or after a specified date (the start_date). - * Use EDATE to calculate maturity dates or due dates that fall on the same day of the month - * as the date of issue. - * - * Excel Function: - * EDATE(dateValue,adjustmentMonths) - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param int $adjustmentMonths The number of months before or after start_date. - * A positive value for months yields a future date; - * a negative value yields a past date. - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function EDATE($dateValue = 1, $adjustmentMonths = 0) { - $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); - $adjustmentMonths = PHPExcel_Calculation_Functions::flattenSingleValue($adjustmentMonths); - - if (!is_numeric($adjustmentMonths)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $adjustmentMonths = floor($adjustmentMonths); - - if (is_string($dateValue = self::_getDateValue($dateValue))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - // Execute function - $PHPDateObject = self::_adjustDateByMonths($dateValue,$adjustmentMonths); - - switch (PHPExcel_Calculation_Functions::getReturnDateType()) { - case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : - return (float) PHPExcel_Shared_Date::PHPToExcel($PHPDateObject); - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : - return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::PHPToExcel($PHPDateObject)); - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : - return $PHPDateObject; - } - } // function EDATE() - - - /** - * EOMONTH - * - * Returns the date value for the last day of the month that is the indicated number of months - * before or after start_date. - * Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month. - * - * Excel Function: - * EOMONTH(dateValue,adjustmentMonths) - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param int $adjustmentMonths The number of months before or after start_date. - * A positive value for months yields a future date; - * a negative value yields a past date. - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function EOMONTH($dateValue = 1, $adjustmentMonths = 0) { - $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); - $adjustmentMonths = PHPExcel_Calculation_Functions::flattenSingleValue($adjustmentMonths); - - if (!is_numeric($adjustmentMonths)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $adjustmentMonths = floor($adjustmentMonths); - - if (is_string($dateValue = self::_getDateValue($dateValue))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - // Execute function - $PHPDateObject = self::_adjustDateByMonths($dateValue,$adjustmentMonths+1); - $adjustDays = (int) $PHPDateObject->format('d'); - $adjustDaysString = '-'.$adjustDays.' days'; - $PHPDateObject->modify($adjustDaysString); - - switch (PHPExcel_Calculation_Functions::getReturnDateType()) { - case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : - return (float) PHPExcel_Shared_Date::PHPToExcel($PHPDateObject); - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : - return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::PHPToExcel($PHPDateObject)); - case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : - return $PHPDateObject; - } - } // function EOMONTH() - -} // class PHPExcel_Calculation_DateTime - + } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + + return (int) $PHPDateObject->format('Y'); + } + + + /** + * HOUROFDAY + * + * Returns the hour of a time value. + * The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.). + * + * Excel Function: + * HOUR(timeValue) + * + * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard time string + * @return int Hour + */ + public static function HOUROFDAY($timeValue = 0) + { + $timeValue = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); + + if (!is_numeric($timeValue)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $testVal = strtok($timeValue, '/-: '); + if (strlen($testVal) < strlen($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $timeValue = self::_getTimeValue($timeValue); + if (is_string($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Execute function + if ($timeValue >= 1) { + $timeValue = fmod($timeValue, 1); + } elseif ($timeValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); + + return (int) gmdate('G', $timeValue); + } + + + /** + * MINUTEOFHOUR + * + * Returns the minutes of a time value. + * The minute is given as an integer, ranging from 0 to 59. + * + * Excel Function: + * MINUTE(timeValue) + * + * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard time string + * @return int Minute + */ + public static function MINUTEOFHOUR($timeValue = 0) + { + $timeValue = $timeTester = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); + + if (!is_numeric($timeValue)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $testVal = strtok($timeValue, '/-: '); + if (strlen($testVal) < strlen($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $timeValue = self::_getTimeValue($timeValue); + if (is_string($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Execute function + if ($timeValue >= 1) { + $timeValue = fmod($timeValue, 1); + } elseif ($timeValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); + + return (int) gmdate('i', $timeValue); + } + + + /** + * SECONDOFMINUTE + * + * Returns the seconds of a time value. + * The second is given as an integer in the range 0 (zero) to 59. + * + * Excel Function: + * SECOND(timeValue) + * + * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard time string + * @return int Second + */ + public static function SECONDOFMINUTE($timeValue = 0) + { + $timeValue = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); + + if (!is_numeric($timeValue)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $testVal = strtok($timeValue, '/-: '); + if (strlen($testVal) < strlen($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $timeValue = self::_getTimeValue($timeValue); + if (is_string($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Execute function + if ($timeValue >= 1) { + $timeValue = fmod($timeValue, 1); + } elseif ($timeValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); + + return (int) gmdate('s', $timeValue); + } + + + /** + * EDATE + * + * Returns the serial number that represents the date that is the indicated number of months + * before or after a specified date (the start_date). + * Use EDATE to calculate maturity dates or due dates that fall on the same day of the month + * as the date of issue. + * + * Excel Function: + * EDATE(dateValue,adjustmentMonths) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param int $adjustmentMonths The number of months before or after start_date. + * A positive value for months yields a future date; + * a negative value yields a past date. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function EDATE($dateValue = 1, $adjustmentMonths = 0) + { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $adjustmentMonths = PHPExcel_Calculation_Functions::flattenSingleValue($adjustmentMonths); + + if (!is_numeric($adjustmentMonths)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $adjustmentMonths = floor($adjustmentMonths); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Execute function + $PHPDateObject = self::_adjustDateByMonths($dateValue, $adjustmentMonths); + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL: + return (float) PHPExcel_Shared_Date::PHPToExcel($PHPDateObject); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC: + return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::PHPToExcel($PHPDateObject)); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT: + return $PHPDateObject; + } + } + + + /** + * EOMONTH + * + * Returns the date value for the last day of the month that is the indicated number of months + * before or after start_date. + * Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month. + * + * Excel Function: + * EOMONTH(dateValue,adjustmentMonths) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param int $adjustmentMonths The number of months before or after start_date. + * A positive value for months yields a future date; + * a negative value yields a past date. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function EOMONTH($dateValue = 1, $adjustmentMonths = 0) + { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $adjustmentMonths = PHPExcel_Calculation_Functions::flattenSingleValue($adjustmentMonths); + + if (!is_numeric($adjustmentMonths)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $adjustmentMonths = floor($adjustmentMonths); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Execute function + $PHPDateObject = self::_adjustDateByMonths($dateValue, $adjustmentMonths+1); + $adjustDays = (int) $PHPDateObject->format('d'); + $adjustDaysString = '-' . $adjustDays . ' days'; + $PHPDateObject->modify($adjustDaysString); + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL: + return (float) PHPExcel_Shared_Date::PHPToExcel($PHPDateObject); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC: + return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::PHPToExcel($PHPDateObject)); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT: + return $PHPDateObject; + } + } +} diff --git a/Classes/PHPExcel/Calculation/Engineering.php b/Classes/PHPExcel/Calculation/Engineering.php index 15039a74c..d7c632984 100644 --- a/Classes/PHPExcel/Calculation/Engineering.php +++ b/Classes/PHPExcel/Calculation/Engineering.php @@ -18,21 +18,21 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } @@ -43,2463 +43,2618 @@ /** * PHPExcel_Calculation_Engineering * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ -class PHPExcel_Calculation_Engineering { - - /** - * Details of the Units of measure that can be used in CONVERTUOM() - * - * @var mixed[] - */ - private static $_conversionUnits = array( 'g' => array( 'Group' => 'Mass', 'Unit Name' => 'Gram', 'AllowPrefix' => True ), - 'sg' => array( 'Group' => 'Mass', 'Unit Name' => 'Slug', 'AllowPrefix' => False ), - 'lbm' => array( 'Group' => 'Mass', 'Unit Name' => 'Pound mass (avoirdupois)', 'AllowPrefix' => False ), - 'u' => array( 'Group' => 'Mass', 'Unit Name' => 'U (atomic mass unit)', 'AllowPrefix' => True ), - 'ozm' => array( 'Group' => 'Mass', 'Unit Name' => 'Ounce mass (avoirdupois)', 'AllowPrefix' => False ), - 'm' => array( 'Group' => 'Distance', 'Unit Name' => 'Meter', 'AllowPrefix' => True ), - 'mi' => array( 'Group' => 'Distance', 'Unit Name' => 'Statute mile', 'AllowPrefix' => False ), - 'Nmi' => array( 'Group' => 'Distance', 'Unit Name' => 'Nautical mile', 'AllowPrefix' => False ), - 'in' => array( 'Group' => 'Distance', 'Unit Name' => 'Inch', 'AllowPrefix' => False ), - 'ft' => array( 'Group' => 'Distance', 'Unit Name' => 'Foot', 'AllowPrefix' => False ), - 'yd' => array( 'Group' => 'Distance', 'Unit Name' => 'Yard', 'AllowPrefix' => False ), - 'ang' => array( 'Group' => 'Distance', 'Unit Name' => 'Angstrom', 'AllowPrefix' => True ), - 'Pica' => array( 'Group' => 'Distance', 'Unit Name' => 'Pica (1/72 in)', 'AllowPrefix' => False ), - 'yr' => array( 'Group' => 'Time', 'Unit Name' => 'Year', 'AllowPrefix' => False ), - 'day' => array( 'Group' => 'Time', 'Unit Name' => 'Day', 'AllowPrefix' => False ), - 'hr' => array( 'Group' => 'Time', 'Unit Name' => 'Hour', 'AllowPrefix' => False ), - 'mn' => array( 'Group' => 'Time', 'Unit Name' => 'Minute', 'AllowPrefix' => False ), - 'sec' => array( 'Group' => 'Time', 'Unit Name' => 'Second', 'AllowPrefix' => True ), - 'Pa' => array( 'Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => True ), - 'p' => array( 'Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => True ), - 'atm' => array( 'Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => True ), - 'at' => array( 'Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => True ), - 'mmHg' => array( 'Group' => 'Pressure', 'Unit Name' => 'mm of Mercury', 'AllowPrefix' => True ), - 'N' => array( 'Group' => 'Force', 'Unit Name' => 'Newton', 'AllowPrefix' => True ), - 'dyn' => array( 'Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => True ), - 'dy' => array( 'Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => True ), - 'lbf' => array( 'Group' => 'Force', 'Unit Name' => 'Pound force', 'AllowPrefix' => False ), - 'J' => array( 'Group' => 'Energy', 'Unit Name' => 'Joule', 'AllowPrefix' => True ), - 'e' => array( 'Group' => 'Energy', 'Unit Name' => 'Erg', 'AllowPrefix' => True ), - 'c' => array( 'Group' => 'Energy', 'Unit Name' => 'Thermodynamic calorie', 'AllowPrefix' => True ), - 'cal' => array( 'Group' => 'Energy', 'Unit Name' => 'IT calorie', 'AllowPrefix' => True ), - 'eV' => array( 'Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => True ), - 'ev' => array( 'Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => True ), - 'HPh' => array( 'Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => False ), - 'hh' => array( 'Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => False ), - 'Wh' => array( 'Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => True ), - 'wh' => array( 'Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => True ), - 'flb' => array( 'Group' => 'Energy', 'Unit Name' => 'Foot-pound', 'AllowPrefix' => False ), - 'BTU' => array( 'Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => False ), - 'btu' => array( 'Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => False ), - 'HP' => array( 'Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => False ), - 'h' => array( 'Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => False ), - 'W' => array( 'Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => True ), - 'w' => array( 'Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => True ), - 'T' => array( 'Group' => 'Magnetism', 'Unit Name' => 'Tesla', 'AllowPrefix' => True ), - 'ga' => array( 'Group' => 'Magnetism', 'Unit Name' => 'Gauss', 'AllowPrefix' => True ), - 'C' => array( 'Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => False ), - 'cel' => array( 'Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => False ), - 'F' => array( 'Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => False ), - 'fah' => array( 'Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => False ), - 'K' => array( 'Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => False ), - 'kel' => array( 'Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => False ), - 'tsp' => array( 'Group' => 'Liquid', 'Unit Name' => 'Teaspoon', 'AllowPrefix' => False ), - 'tbs' => array( 'Group' => 'Liquid', 'Unit Name' => 'Tablespoon', 'AllowPrefix' => False ), - 'oz' => array( 'Group' => 'Liquid', 'Unit Name' => 'Fluid Ounce', 'AllowPrefix' => False ), - 'cup' => array( 'Group' => 'Liquid', 'Unit Name' => 'Cup', 'AllowPrefix' => False ), - 'pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => False ), - 'us_pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => False ), - 'uk_pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.K. Pint', 'AllowPrefix' => False ), - 'qt' => array( 'Group' => 'Liquid', 'Unit Name' => 'Quart', 'AllowPrefix' => False ), - 'gal' => array( 'Group' => 'Liquid', 'Unit Name' => 'Gallon', 'AllowPrefix' => False ), - 'l' => array( 'Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => True ), - 'lt' => array( 'Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => True ) - ); - - /** - * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM() - * - * @var mixed[] - */ - private static $_conversionMultipliers = array( 'Y' => array( 'multiplier' => 1E24, 'name' => 'yotta' ), - 'Z' => array( 'multiplier' => 1E21, 'name' => 'zetta' ), - 'E' => array( 'multiplier' => 1E18, 'name' => 'exa' ), - 'P' => array( 'multiplier' => 1E15, 'name' => 'peta' ), - 'T' => array( 'multiplier' => 1E12, 'name' => 'tera' ), - 'G' => array( 'multiplier' => 1E9, 'name' => 'giga' ), - 'M' => array( 'multiplier' => 1E6, 'name' => 'mega' ), - 'k' => array( 'multiplier' => 1E3, 'name' => 'kilo' ), - 'h' => array( 'multiplier' => 1E2, 'name' => 'hecto' ), - 'e' => array( 'multiplier' => 1E1, 'name' => 'deka' ), - 'd' => array( 'multiplier' => 1E-1, 'name' => 'deci' ), - 'c' => array( 'multiplier' => 1E-2, 'name' => 'centi' ), - 'm' => array( 'multiplier' => 1E-3, 'name' => 'milli' ), - 'u' => array( 'multiplier' => 1E-6, 'name' => 'micro' ), - 'n' => array( 'multiplier' => 1E-9, 'name' => 'nano' ), - 'p' => array( 'multiplier' => 1E-12, 'name' => 'pico' ), - 'f' => array( 'multiplier' => 1E-15, 'name' => 'femto' ), - 'a' => array( 'multiplier' => 1E-18, 'name' => 'atto' ), - 'z' => array( 'multiplier' => 1E-21, 'name' => 'zepto' ), - 'y' => array( 'multiplier' => 1E-24, 'name' => 'yocto' ) - ); - - /** - * Details of the Units of measure conversion factors, organised by group - * - * @var mixed[] - */ - private static $_unitConversions = array( 'Mass' => array( 'g' => array( 'g' => 1.0, - 'sg' => 6.85220500053478E-05, - 'lbm' => 2.20462291469134E-03, - 'u' => 6.02217000000000E+23, - 'ozm' => 3.52739718003627E-02 - ), - 'sg' => array( 'g' => 1.45938424189287E+04, - 'sg' => 1.0, - 'lbm' => 3.21739194101647E+01, - 'u' => 8.78866000000000E+27, - 'ozm' => 5.14782785944229E+02 - ), - 'lbm' => array( 'g' => 4.5359230974881148E+02, - 'sg' => 3.10810749306493E-02, - 'lbm' => 1.0, - 'u' => 2.73161000000000E+26, - 'ozm' => 1.60000023429410E+01 - ), - 'u' => array( 'g' => 1.66053100460465E-24, - 'sg' => 1.13782988532950E-28, - 'lbm' => 3.66084470330684E-27, - 'u' => 1.0, - 'ozm' => 5.85735238300524E-26 - ), - 'ozm' => array( 'g' => 2.83495152079732E+01, - 'sg' => 1.94256689870811E-03, - 'lbm' => 6.24999908478882E-02, - 'u' => 1.70725600000000E+25, - 'ozm' => 1.0 - ) - ), - 'Distance' => array( 'm' => array( 'm' => 1.0, - 'mi' => 6.21371192237334E-04, - 'Nmi' => 5.39956803455724E-04, - 'in' => 3.93700787401575E+01, - 'ft' => 3.28083989501312E+00, - 'yd' => 1.09361329797891E+00, - 'ang' => 1.00000000000000E+10, - 'Pica' => 2.83464566929116E+03 - ), - 'mi' => array( 'm' => 1.60934400000000E+03, - 'mi' => 1.0, - 'Nmi' => 8.68976241900648E-01, - 'in' => 6.33600000000000E+04, - 'ft' => 5.28000000000000E+03, - 'yd' => 1.76000000000000E+03, - 'ang' => 1.60934400000000E+13, - 'Pica' => 4.56191999999971E+06 - ), - 'Nmi' => array( 'm' => 1.85200000000000E+03, - 'mi' => 1.15077944802354E+00, - 'Nmi' => 1.0, - 'in' => 7.29133858267717E+04, - 'ft' => 6.07611548556430E+03, - 'yd' => 2.02537182785694E+03, - 'ang' => 1.85200000000000E+13, - 'Pica' => 5.24976377952723E+06 - ), - 'in' => array( 'm' => 2.54000000000000E-02, - 'mi' => 1.57828282828283E-05, - 'Nmi' => 1.37149028077754E-05, - 'in' => 1.0, - 'ft' => 8.33333333333333E-02, - 'yd' => 2.77777777686643E-02, - 'ang' => 2.54000000000000E+08, - 'Pica' => 7.19999999999955E+01 - ), - 'ft' => array( 'm' => 3.04800000000000E-01, - 'mi' => 1.89393939393939E-04, - 'Nmi' => 1.64578833693305E-04, - 'in' => 1.20000000000000E+01, - 'ft' => 1.0, - 'yd' => 3.33333333223972E-01, - 'ang' => 3.04800000000000E+09, - 'Pica' => 8.63999999999946E+02 - ), - 'yd' => array( 'm' => 9.14400000300000E-01, - 'mi' => 5.68181818368230E-04, - 'Nmi' => 4.93736501241901E-04, - 'in' => 3.60000000118110E+01, - 'ft' => 3.00000000000000E+00, - 'yd' => 1.0, - 'ang' => 9.14400000300000E+09, - 'Pica' => 2.59200000085023E+03 - ), - 'ang' => array( 'm' => 1.00000000000000E-10, - 'mi' => 6.21371192237334E-14, - 'Nmi' => 5.39956803455724E-14, - 'in' => 3.93700787401575E-09, - 'ft' => 3.28083989501312E-10, - 'yd' => 1.09361329797891E-10, - 'ang' => 1.0, - 'Pica' => 2.83464566929116E-07 - ), - 'Pica' => array( 'm' => 3.52777777777800E-04, - 'mi' => 2.19205948372629E-07, - 'Nmi' => 1.90484761219114E-07, - 'in' => 1.38888888888898E-02, - 'ft' => 1.15740740740748E-03, - 'yd' => 3.85802469009251E-04, - 'ang' => 3.52777777777800E+06, - 'Pica' => 1.0 - ) - ), - 'Time' => array( 'yr' => array( 'yr' => 1.0, - 'day' => 365.25, - 'hr' => 8766.0, - 'mn' => 525960.0, - 'sec' => 31557600.0 - ), - 'day' => array( 'yr' => 2.73785078713210E-03, - 'day' => 1.0, - 'hr' => 24.0, - 'mn' => 1440.0, - 'sec' => 86400.0 - ), - 'hr' => array( 'yr' => 1.14077116130504E-04, - 'day' => 4.16666666666667E-02, - 'hr' => 1.0, - 'mn' => 60.0, - 'sec' => 3600.0 - ), - 'mn' => array( 'yr' => 1.90128526884174E-06, - 'day' => 6.94444444444444E-04, - 'hr' => 1.66666666666667E-02, - 'mn' => 1.0, - 'sec' => 60.0 - ), - 'sec' => array( 'yr' => 3.16880878140289E-08, - 'day' => 1.15740740740741E-05, - 'hr' => 2.77777777777778E-04, - 'mn' => 1.66666666666667E-02, - 'sec' => 1.0 - ) - ), - 'Pressure' => array( 'Pa' => array( 'Pa' => 1.0, - 'p' => 1.0, - 'atm' => 9.86923299998193E-06, - 'at' => 9.86923299998193E-06, - 'mmHg' => 7.50061707998627E-03 - ), - 'p' => array( 'Pa' => 1.0, - 'p' => 1.0, - 'atm' => 9.86923299998193E-06, - 'at' => 9.86923299998193E-06, - 'mmHg' => 7.50061707998627E-03 - ), - 'atm' => array( 'Pa' => 1.01324996583000E+05, - 'p' => 1.01324996583000E+05, - 'atm' => 1.0, - 'at' => 1.0, - 'mmHg' => 760.0 - ), - 'at' => array( 'Pa' => 1.01324996583000E+05, - 'p' => 1.01324996583000E+05, - 'atm' => 1.0, - 'at' => 1.0, - 'mmHg' => 760.0 - ), - 'mmHg' => array( 'Pa' => 1.33322363925000E+02, - 'p' => 1.33322363925000E+02, - 'atm' => 1.31578947368421E-03, - 'at' => 1.31578947368421E-03, - 'mmHg' => 1.0 - ) - ), - 'Force' => array( 'N' => array( 'N' => 1.0, - 'dyn' => 1.0E+5, - 'dy' => 1.0E+5, - 'lbf' => 2.24808923655339E-01 - ), - 'dyn' => array( 'N' => 1.0E-5, - 'dyn' => 1.0, - 'dy' => 1.0, - 'lbf' => 2.24808923655339E-06 - ), - 'dy' => array( 'N' => 1.0E-5, - 'dyn' => 1.0, - 'dy' => 1.0, - 'lbf' => 2.24808923655339E-06 - ), - 'lbf' => array( 'N' => 4.448222, - 'dyn' => 4.448222E+5, - 'dy' => 4.448222E+5, - 'lbf' => 1.0 - ) - ), - 'Energy' => array( 'J' => array( 'J' => 1.0, - 'e' => 9.99999519343231E+06, - 'c' => 2.39006249473467E-01, - 'cal' => 2.38846190642017E-01, - 'eV' => 6.24145700000000E+18, - 'ev' => 6.24145700000000E+18, - 'HPh' => 3.72506430801000E-07, - 'hh' => 3.72506430801000E-07, - 'Wh' => 2.77777916238711E-04, - 'wh' => 2.77777916238711E-04, - 'flb' => 2.37304222192651E+01, - 'BTU' => 9.47815067349015E-04, - 'btu' => 9.47815067349015E-04 - ), - 'e' => array( 'J' => 1.00000048065700E-07, - 'e' => 1.0, - 'c' => 2.39006364353494E-08, - 'cal' => 2.38846305445111E-08, - 'eV' => 6.24146000000000E+11, - 'ev' => 6.24146000000000E+11, - 'HPh' => 3.72506609848824E-14, - 'hh' => 3.72506609848824E-14, - 'Wh' => 2.77778049754611E-11, - 'wh' => 2.77778049754611E-11, - 'flb' => 2.37304336254586E-06, - 'BTU' => 9.47815522922962E-11, - 'btu' => 9.47815522922962E-11 - ), - 'c' => array( 'J' => 4.18399101363672E+00, - 'e' => 4.18398900257312E+07, - 'c' => 1.0, - 'cal' => 9.99330315287563E-01, - 'eV' => 2.61142000000000E+19, - 'ev' => 2.61142000000000E+19, - 'HPh' => 1.55856355899327E-06, - 'hh' => 1.55856355899327E-06, - 'Wh' => 1.16222030532950E-03, - 'wh' => 1.16222030532950E-03, - 'flb' => 9.92878733152102E+01, - 'BTU' => 3.96564972437776E-03, - 'btu' => 3.96564972437776E-03 - ), - 'cal' => array( 'J' => 4.18679484613929E+00, - 'e' => 4.18679283372801E+07, - 'c' => 1.00067013349059E+00, - 'cal' => 1.0, - 'eV' => 2.61317000000000E+19, - 'ev' => 2.61317000000000E+19, - 'HPh' => 1.55960800463137E-06, - 'hh' => 1.55960800463137E-06, - 'Wh' => 1.16299914807955E-03, - 'wh' => 1.16299914807955E-03, - 'flb' => 9.93544094443283E+01, - 'BTU' => 3.96830723907002E-03, - 'btu' => 3.96830723907002E-03 - ), - 'eV' => array( 'J' => 1.60219000146921E-19, - 'e' => 1.60218923136574E-12, - 'c' => 3.82933423195043E-20, - 'cal' => 3.82676978535648E-20, - 'eV' => 1.0, - 'ev' => 1.0, - 'HPh' => 5.96826078912344E-26, - 'hh' => 5.96826078912344E-26, - 'Wh' => 4.45053000026614E-23, - 'wh' => 4.45053000026614E-23, - 'flb' => 3.80206452103492E-18, - 'BTU' => 1.51857982414846E-22, - 'btu' => 1.51857982414846E-22 - ), - 'ev' => array( 'J' => 1.60219000146921E-19, - 'e' => 1.60218923136574E-12, - 'c' => 3.82933423195043E-20, - 'cal' => 3.82676978535648E-20, - 'eV' => 1.0, - 'ev' => 1.0, - 'HPh' => 5.96826078912344E-26, - 'hh' => 5.96826078912344E-26, - 'Wh' => 4.45053000026614E-23, - 'wh' => 4.45053000026614E-23, - 'flb' => 3.80206452103492E-18, - 'BTU' => 1.51857982414846E-22, - 'btu' => 1.51857982414846E-22 - ), - 'HPh' => array( 'J' => 2.68451741316170E+06, - 'e' => 2.68451612283024E+13, - 'c' => 6.41616438565991E+05, - 'cal' => 6.41186757845835E+05, - 'eV' => 1.67553000000000E+25, - 'ev' => 1.67553000000000E+25, - 'HPh' => 1.0, - 'hh' => 1.0, - 'Wh' => 7.45699653134593E+02, - 'wh' => 7.45699653134593E+02, - 'flb' => 6.37047316692964E+07, - 'BTU' => 2.54442605275546E+03, - 'btu' => 2.54442605275546E+03 - ), - 'hh' => array( 'J' => 2.68451741316170E+06, - 'e' => 2.68451612283024E+13, - 'c' => 6.41616438565991E+05, - 'cal' => 6.41186757845835E+05, - 'eV' => 1.67553000000000E+25, - 'ev' => 1.67553000000000E+25, - 'HPh' => 1.0, - 'hh' => 1.0, - 'Wh' => 7.45699653134593E+02, - 'wh' => 7.45699653134593E+02, - 'flb' => 6.37047316692964E+07, - 'BTU' => 2.54442605275546E+03, - 'btu' => 2.54442605275546E+03 - ), - 'Wh' => array( 'J' => 3.59999820554720E+03, - 'e' => 3.59999647518369E+10, - 'c' => 8.60422069219046E+02, - 'cal' => 8.59845857713046E+02, - 'eV' => 2.24692340000000E+22, - 'ev' => 2.24692340000000E+22, - 'HPh' => 1.34102248243839E-03, - 'hh' => 1.34102248243839E-03, - 'Wh' => 1.0, - 'wh' => 1.0, - 'flb' => 8.54294774062316E+04, - 'BTU' => 3.41213254164705E+00, - 'btu' => 3.41213254164705E+00 - ), - 'wh' => array( 'J' => 3.59999820554720E+03, - 'e' => 3.59999647518369E+10, - 'c' => 8.60422069219046E+02, - 'cal' => 8.59845857713046E+02, - 'eV' => 2.24692340000000E+22, - 'ev' => 2.24692340000000E+22, - 'HPh' => 1.34102248243839E-03, - 'hh' => 1.34102248243839E-03, - 'Wh' => 1.0, - 'wh' => 1.0, - 'flb' => 8.54294774062316E+04, - 'BTU' => 3.41213254164705E+00, - 'btu' => 3.41213254164705E+00 - ), - 'flb' => array( 'J' => 4.21400003236424E-02, - 'e' => 4.21399800687660E+05, - 'c' => 1.00717234301644E-02, - 'cal' => 1.00649785509554E-02, - 'eV' => 2.63015000000000E+17, - 'ev' => 2.63015000000000E+17, - 'HPh' => 1.56974211145130E-08, - 'hh' => 1.56974211145130E-08, - 'Wh' => 1.17055614802000E-05, - 'wh' => 1.17055614802000E-05, - 'flb' => 1.0, - 'BTU' => 3.99409272448406E-05, - 'btu' => 3.99409272448406E-05 - ), - 'BTU' => array( 'J' => 1.05505813786749E+03, - 'e' => 1.05505763074665E+10, - 'c' => 2.52165488508168E+02, - 'cal' => 2.51996617135510E+02, - 'eV' => 6.58510000000000E+21, - 'ev' => 6.58510000000000E+21, - 'HPh' => 3.93015941224568E-04, - 'hh' => 3.93015941224568E-04, - 'Wh' => 2.93071851047526E-01, - 'wh' => 2.93071851047526E-01, - 'flb' => 2.50369750774671E+04, - 'BTU' => 1.0, - 'btu' => 1.0, - ), - 'btu' => array( 'J' => 1.05505813786749E+03, - 'e' => 1.05505763074665E+10, - 'c' => 2.52165488508168E+02, - 'cal' => 2.51996617135510E+02, - 'eV' => 6.58510000000000E+21, - 'ev' => 6.58510000000000E+21, - 'HPh' => 3.93015941224568E-04, - 'hh' => 3.93015941224568E-04, - 'Wh' => 2.93071851047526E-01, - 'wh' => 2.93071851047526E-01, - 'flb' => 2.50369750774671E+04, - 'BTU' => 1.0, - 'btu' => 1.0, - ) - ), - 'Power' => array( 'HP' => array( 'HP' => 1.0, - 'h' => 1.0, - 'W' => 7.45701000000000E+02, - 'w' => 7.45701000000000E+02 - ), - 'h' => array( 'HP' => 1.0, - 'h' => 1.0, - 'W' => 7.45701000000000E+02, - 'w' => 7.45701000000000E+02 - ), - 'W' => array( 'HP' => 1.34102006031908E-03, - 'h' => 1.34102006031908E-03, - 'W' => 1.0, - 'w' => 1.0 - ), - 'w' => array( 'HP' => 1.34102006031908E-03, - 'h' => 1.34102006031908E-03, - 'W' => 1.0, - 'w' => 1.0 - ) - ), - 'Magnetism' => array( 'T' => array( 'T' => 1.0, - 'ga' => 10000.0 - ), - 'ga' => array( 'T' => 0.0001, - 'ga' => 1.0 - ) - ), - 'Liquid' => array( 'tsp' => array( 'tsp' => 1.0, - 'tbs' => 3.33333333333333E-01, - 'oz' => 1.66666666666667E-01, - 'cup' => 2.08333333333333E-02, - 'pt' => 1.04166666666667E-02, - 'us_pt' => 1.04166666666667E-02, - 'uk_pt' => 8.67558516821960E-03, - 'qt' => 5.20833333333333E-03, - 'gal' => 1.30208333333333E-03, - 'l' => 4.92999408400710E-03, - 'lt' => 4.92999408400710E-03 - ), - 'tbs' => array( 'tsp' => 3.00000000000000E+00, - 'tbs' => 1.0, - 'oz' => 5.00000000000000E-01, - 'cup' => 6.25000000000000E-02, - 'pt' => 3.12500000000000E-02, - 'us_pt' => 3.12500000000000E-02, - 'uk_pt' => 2.60267555046588E-02, - 'qt' => 1.56250000000000E-02, - 'gal' => 3.90625000000000E-03, - 'l' => 1.47899822520213E-02, - 'lt' => 1.47899822520213E-02 - ), - 'oz' => array( 'tsp' => 6.00000000000000E+00, - 'tbs' => 2.00000000000000E+00, - 'oz' => 1.0, - 'cup' => 1.25000000000000E-01, - 'pt' => 6.25000000000000E-02, - 'us_pt' => 6.25000000000000E-02, - 'uk_pt' => 5.20535110093176E-02, - 'qt' => 3.12500000000000E-02, - 'gal' => 7.81250000000000E-03, - 'l' => 2.95799645040426E-02, - 'lt' => 2.95799645040426E-02 - ), - 'cup' => array( 'tsp' => 4.80000000000000E+01, - 'tbs' => 1.60000000000000E+01, - 'oz' => 8.00000000000000E+00, - 'cup' => 1.0, - 'pt' => 5.00000000000000E-01, - 'us_pt' => 5.00000000000000E-01, - 'uk_pt' => 4.16428088074541E-01, - 'qt' => 2.50000000000000E-01, - 'gal' => 6.25000000000000E-02, - 'l' => 2.36639716032341E-01, - 'lt' => 2.36639716032341E-01 - ), - 'pt' => array( 'tsp' => 9.60000000000000E+01, - 'tbs' => 3.20000000000000E+01, - 'oz' => 1.60000000000000E+01, - 'cup' => 2.00000000000000E+00, - 'pt' => 1.0, - 'us_pt' => 1.0, - 'uk_pt' => 8.32856176149081E-01, - 'qt' => 5.00000000000000E-01, - 'gal' => 1.25000000000000E-01, - 'l' => 4.73279432064682E-01, - 'lt' => 4.73279432064682E-01 - ), - 'us_pt' => array( 'tsp' => 9.60000000000000E+01, - 'tbs' => 3.20000000000000E+01, - 'oz' => 1.60000000000000E+01, - 'cup' => 2.00000000000000E+00, - 'pt' => 1.0, - 'us_pt' => 1.0, - 'uk_pt' => 8.32856176149081E-01, - 'qt' => 5.00000000000000E-01, - 'gal' => 1.25000000000000E-01, - 'l' => 4.73279432064682E-01, - 'lt' => 4.73279432064682E-01 - ), - 'uk_pt' => array( 'tsp' => 1.15266000000000E+02, - 'tbs' => 3.84220000000000E+01, - 'oz' => 1.92110000000000E+01, - 'cup' => 2.40137500000000E+00, - 'pt' => 1.20068750000000E+00, - 'us_pt' => 1.20068750000000E+00, - 'uk_pt' => 1.0, - 'qt' => 6.00343750000000E-01, - 'gal' => 1.50085937500000E-01, - 'l' => 5.68260698087162E-01, - 'lt' => 5.68260698087162E-01 - ), - 'qt' => array( 'tsp' => 1.92000000000000E+02, - 'tbs' => 6.40000000000000E+01, - 'oz' => 3.20000000000000E+01, - 'cup' => 4.00000000000000E+00, - 'pt' => 2.00000000000000E+00, - 'us_pt' => 2.00000000000000E+00, - 'uk_pt' => 1.66571235229816E+00, - 'qt' => 1.0, - 'gal' => 2.50000000000000E-01, - 'l' => 9.46558864129363E-01, - 'lt' => 9.46558864129363E-01 - ), - 'gal' => array( 'tsp' => 7.68000000000000E+02, - 'tbs' => 2.56000000000000E+02, - 'oz' => 1.28000000000000E+02, - 'cup' => 1.60000000000000E+01, - 'pt' => 8.00000000000000E+00, - 'us_pt' => 8.00000000000000E+00, - 'uk_pt' => 6.66284940919265E+00, - 'qt' => 4.00000000000000E+00, - 'gal' => 1.0, - 'l' => 3.78623545651745E+00, - 'lt' => 3.78623545651745E+00 - ), - 'l' => array( 'tsp' => 2.02840000000000E+02, - 'tbs' => 6.76133333333333E+01, - 'oz' => 3.38066666666667E+01, - 'cup' => 4.22583333333333E+00, - 'pt' => 2.11291666666667E+00, - 'us_pt' => 2.11291666666667E+00, - 'uk_pt' => 1.75975569552166E+00, - 'qt' => 1.05645833333333E+00, - 'gal' => 2.64114583333333E-01, - 'l' => 1.0, - 'lt' => 1.0 - ), - 'lt' => array( 'tsp' => 2.02840000000000E+02, - 'tbs' => 6.76133333333333E+01, - 'oz' => 3.38066666666667E+01, - 'cup' => 4.22583333333333E+00, - 'pt' => 2.11291666666667E+00, - 'us_pt' => 2.11291666666667E+00, - 'uk_pt' => 1.75975569552166E+00, - 'qt' => 1.05645833333333E+00, - 'gal' => 2.64114583333333E-01, - 'l' => 1.0, - 'lt' => 1.0 - ) - ) - ); - - - /** - * _parseComplex - * - * Parses a complex number into its real and imaginary parts, and an I or J suffix - * - * @param string $complexNumber The complex number - * @return string[] Indexed on "real", "imaginary" and "suffix" - */ - public static function _parseComplex($complexNumber) { - $workString = (string) $complexNumber; - - $realNumber = $imaginary = 0; - // Extract the suffix, if there is one - $suffix = substr($workString,-1); - if (!is_numeric($suffix)) { - $workString = substr($workString,0,-1); - } else { - $suffix = ''; - } - - // Split the input into its Real and Imaginary components - $leadingSign = 0; - if (strlen($workString) > 0) { - $leadingSign = (($workString{0} == '+') || ($workString{0} == '-')) ? 1 : 0; - } - $power = ''; - $realNumber = strtok($workString, '+-'); - if (strtoupper(substr($realNumber,-1)) == 'E') { - $power = strtok('+-'); - ++$leadingSign; - } - - $realNumber = substr($workString,0,strlen($realNumber)+strlen($power)+$leadingSign); - - if ($suffix != '') { - $imaginary = substr($workString,strlen($realNumber)); - - if (($imaginary == '') && (($realNumber == '') || ($realNumber == '+') || ($realNumber == '-'))) { - $imaginary = $realNumber.'1'; - $realNumber = '0'; - } else if ($imaginary == '') { - $imaginary = $realNumber; - $realNumber = '0'; - } elseif (($imaginary == '+') || ($imaginary == '-')) { - $imaginary .= '1'; - } - } - - return array( 'real' => $realNumber, - 'imaginary' => $imaginary, - 'suffix' => $suffix - ); - } // function _parseComplex() - - - /** - * Cleans the leading characters in a complex number string - * - * @param string $complexNumber The complex number to clean - * @return string The "cleaned" complex number - */ - private static function _cleanComplex($complexNumber) { - if ($complexNumber{0} == '+') $complexNumber = substr($complexNumber,1); - if ($complexNumber{0} == '0') $complexNumber = substr($complexNumber,1); - if ($complexNumber{0} == '.') $complexNumber = '0'.$complexNumber; - if ($complexNumber{0} == '+') $complexNumber = substr($complexNumber,1); - return $complexNumber; - } - - /** - * Formats a number base string value with leading zeroes - * - * @param string $xVal The "number" to pad - * @param integer $places The length that we want to pad this value - * @return string The padded "number" - */ - private static function _nbrConversionFormat($xVal, $places) { - if (!is_null($places)) { - if (strlen($xVal) <= $places) { - return substr(str_pad($xVal, $places, '0', STR_PAD_LEFT), -10); - } else { - return PHPExcel_Calculation_Functions::NaN(); - } - } - - return substr($xVal, -10); - } // function _nbrConversionFormat() - - /** - * BESSELI - * - * Returns the modified Bessel function In(x), which is equivalent to the Bessel function evaluated - * for purely imaginary arguments - * - * Excel Function: - * BESSELI(x,ord) - * - * @access public - * @category Engineering Functions - * @param float $x The value at which to evaluate the function. - * If x is nonnumeric, BESSELI returns the #VALUE! error value. - * @param integer $ord The order of the Bessel function. - * If ord is not an integer, it is truncated. - * If $ord is nonnumeric, BESSELI returns the #VALUE! error value. - * If $ord < 0, BESSELI returns the #NUM! error value. - * @return float - * - */ - public static function BESSELI($x, $ord) { - $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); - $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); - - if ((is_numeric($x)) && (is_numeric($ord))) { - $ord = floor($ord); - if ($ord < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - if (abs($x) <= 30) { - $fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord); - $ordK = 1; - $fSqrX = ($x * $x) / 4; - do { - $fTerm *= $fSqrX; - $fTerm /= ($ordK * ($ordK + $ord)); - $fResult += $fTerm; - } while ((abs($fTerm) > 1e-12) && (++$ordK < 100)); - } else { - $f_2_PI = 2 * M_PI; - - $fXAbs = abs($x); - $fResult = exp($fXAbs) / sqrt($f_2_PI * $fXAbs); - if (($ord & 1) && ($x < 0)) { - $fResult = -$fResult; - } - } - return (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function BESSELI() - - - /** - * BESSELJ - * - * Returns the Bessel function - * - * Excel Function: - * BESSELJ(x,ord) - * - * @access public - * @category Engineering Functions - * @param float $x The value at which to evaluate the function. - * If x is nonnumeric, BESSELJ returns the #VALUE! error value. - * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. - * If $ord is nonnumeric, BESSELJ returns the #VALUE! error value. - * If $ord < 0, BESSELJ returns the #NUM! error value. - * @return float - * - */ - public static function BESSELJ($x, $ord) { - $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); - $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); - - if ((is_numeric($x)) && (is_numeric($ord))) { - $ord = floor($ord); - if ($ord < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - $fResult = 0; - if (abs($x) <= 30) { - $fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord); - $ordK = 1; - $fSqrX = ($x * $x) / -4; - do { - $fTerm *= $fSqrX; - $fTerm /= ($ordK * ($ordK + $ord)); - $fResult += $fTerm; - } while ((abs($fTerm) > 1e-12) && (++$ordK < 100)); - } else { - $f_PI_DIV_2 = M_PI / 2; - $f_PI_DIV_4 = M_PI / 4; - - $fXAbs = abs($x); - $fResult = sqrt(M_2DIVPI / $fXAbs) * cos($fXAbs - $ord * $f_PI_DIV_2 - $f_PI_DIV_4); - if (($ord & 1) && ($x < 0)) { - $fResult = -$fResult; - } - } - return (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function BESSELJ() - - - private static function _Besselk0($fNum) { - if ($fNum <= 2) { - $fNum2 = $fNum * 0.5; - $y = ($fNum2 * $fNum2); - $fRet = -log($fNum2) * self::BESSELI($fNum, 0) + - (-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y * - (0.10750e-3 + $y * 0.74e-5)))))); - } else { - $y = 2 / $fNum; - $fRet = exp(-$fNum) / sqrt($fNum) * - (1.25331414 + $y * (-0.7832358e-1 + $y * (0.2189568e-1 + $y * (-0.1062446e-1 + $y * - (0.587872e-2 + $y * (-0.251540e-2 + $y * 0.53208e-3)))))); - } - return $fRet; - } // function _Besselk0() - - - private static function _Besselk1($fNum) { - if ($fNum <= 2) { - $fNum2 = $fNum * 0.5; - $y = ($fNum2 * $fNum2); - $fRet = log($fNum2) * self::BESSELI($fNum, 1) + - (1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y * - (-0.110404e-2 + $y * (-0.4686e-4))))))) / $fNum; - } else { - $y = 2 / $fNum; - $fRet = exp(-$fNum) / sqrt($fNum) * - (1.25331414 + $y * (0.23498619 + $y * (-0.3655620e-1 + $y * (0.1504268e-1 + $y * (-0.780353e-2 + $y * - (0.325614e-2 + $y * (-0.68245e-3))))))); - } - return $fRet; - } // function _Besselk1() - - - /** - * BESSELK - * - * Returns the modified Bessel function Kn(x), which is equivalent to the Bessel functions evaluated - * for purely imaginary arguments. - * - * Excel Function: - * BESSELK(x,ord) - * - * @access public - * @category Engineering Functions - * @param float $x The value at which to evaluate the function. - * If x is nonnumeric, BESSELK returns the #VALUE! error value. - * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. - * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. - * If $ord < 0, BESSELK returns the #NUM! error value. - * @return float - * - */ - public static function BESSELK($x, $ord) { - $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); - $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); - - if ((is_numeric($x)) && (is_numeric($ord))) { - if (($ord < 0) || ($x == 0.0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - - switch(floor($ord)) { - case 0 : return self::_Besselk0($x); - break; - case 1 : return self::_Besselk1($x); - break; - default : $fTox = 2 / $x; - $fBkm = self::_Besselk0($x); - $fBk = self::_Besselk1($x); - for ($n = 1; $n < $ord; ++$n) { - $fBkp = $fBkm + $n * $fTox * $fBk; - $fBkm = $fBk; - $fBk = $fBkp; - } - } - return (is_nan($fBk)) ? PHPExcel_Calculation_Functions::NaN() : $fBk; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function BESSELK() - - - private static function _Bessely0($fNum) { - if ($fNum < 8.0) { - $y = ($fNum * $fNum); - $f1 = -2957821389.0 + $y * (7062834065.0 + $y * (-512359803.6 + $y * (10879881.29 + $y * (-86327.92757 + $y * 228.4622733)))); - $f2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y * (47447.26470 + $y * (226.1030244 + $y)))); - $fRet = $f1 / $f2 + 0.636619772 * self::BESSELJ($fNum, 0) * log($fNum); - } else { - $z = 8.0 / $fNum; - $y = ($z * $z); - $xx = $fNum - 0.785398164; - $f1 = 1 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6))); - $f2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 + $y * (-0.934945152e-7)))); - $fRet = sqrt(0.636619772 / $fNum) * (sin($xx) * $f1 + $z * cos($xx) * $f2); - } - return $fRet; - } // function _Bessely0() - - - private static function _Bessely1($fNum) { - if ($fNum < 8.0) { - $y = ($fNum * $fNum); - $f1 = $fNum * (-0.4900604943e13 + $y * (0.1275274390e13 + $y * (-0.5153438139e11 + $y * (0.7349264551e9 + $y * - (-0.4237922726e7 + $y * 0.8511937935e4))))); - $f2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y * - (0.1020426050e6 + $y * (0.3549632885e3 + $y))))); - $fRet = $f1 / $f2 + 0.636619772 * ( self::BESSELJ($fNum, 1) * log($fNum) - 1 / $fNum); - } else { - $fRet = sqrt(0.636619772 / $fNum) * sin($fNum - 2.356194491); - } - return $fRet; - } // function _Bessely1() - - - /** - * BESSELY - * - * Returns the Bessel function, which is also called the Weber function or the Neumann function. - * - * Excel Function: - * BESSELY(x,ord) - * - * @access public - * @category Engineering Functions - * @param float $x The value at which to evaluate the function. - * If x is nonnumeric, BESSELK returns the #VALUE! error value. - * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. - * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. - * If $ord < 0, BESSELK returns the #NUM! error value. - * - * @return float - */ - public static function BESSELY($x, $ord) { - $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); - $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); - - if ((is_numeric($x)) && (is_numeric($ord))) { - if (($ord < 0) || ($x == 0.0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - - switch(floor($ord)) { - case 0 : return self::_Bessely0($x); - break; - case 1 : return self::_Bessely1($x); - break; - default: $fTox = 2 / $x; - $fBym = self::_Bessely0($x); - $fBy = self::_Bessely1($x); - for ($n = 1; $n < $ord; ++$n) { - $fByp = $n * $fTox * $fBy - $fBym; - $fBym = $fBy; - $fBy = $fByp; - } - } - return (is_nan($fBy)) ? PHPExcel_Calculation_Functions::NaN() : $fBy; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function BESSELY() - - - /** - * BINTODEC - * - * Return a binary value as decimal. - * - * Excel Function: - * BIN2DEC(x) - * - * @access public - * @category Engineering Functions - * @param string $x The binary number (as a string) that you want to convert. The number - * cannot contain more than 10 characters (10 bits). The most significant - * bit of number is the sign bit. The remaining 9 bits are magnitude bits. - * Negative numbers are represented using two's-complement notation. - * If number is not a valid binary number, or if number contains more than - * 10 characters (10 bits), BIN2DEC returns the #NUM! error value. - * @return string - */ - public static function BINTODEC($x) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - - if (is_bool($x)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - $x = (int) $x; - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - $x = floor($x); - } - $x = (string) $x; - if (strlen($x) > preg_match_all('/[01]/',$x,$out)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (strlen($x) > 10) { - return PHPExcel_Calculation_Functions::NaN(); - } elseif (strlen($x) == 10) { - // Two's Complement - $x = substr($x,-9); - return '-'.(512-bindec($x)); - } - return bindec($x); - } // function BINTODEC() - - - /** - * BINTOHEX - * - * Return a binary value as hex. - * - * Excel Function: - * BIN2HEX(x[,places]) - * - * @access public - * @category Engineering Functions - * @param string $x The binary number (as a string) that you want to convert. The number - * cannot contain more than 10 characters (10 bits). The most significant - * bit of number is the sign bit. The remaining 9 bits are magnitude bits. - * Negative numbers are represented using two's-complement notation. - * If number is not a valid binary number, or if number contains more than - * 10 characters (10 bits), BIN2HEX returns the #NUM! error value. - * @param integer $places The number of characters to use. If places is omitted, BIN2HEX uses the - * minimum number of characters necessary. Places is useful for padding the - * return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, BIN2HEX returns the #VALUE! error value. - * If places is negative, BIN2HEX returns the #NUM! error value. - * @return string - */ - public static function BINTOHEX($x, $places=NULL) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); - - if (is_bool($x)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - $x = (int) $x; - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - $x = floor($x); - } - $x = (string) $x; - if (strlen($x) > preg_match_all('/[01]/',$x,$out)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (strlen($x) > 10) { - return PHPExcel_Calculation_Functions::NaN(); - } elseif (strlen($x) == 10) { - // Two's Complement - return str_repeat('F',8).substr(strtoupper(dechex(bindec(substr($x,-9)))),-2); - } - $hexVal = (string) strtoupper(dechex(bindec($x))); - - return self::_nbrConversionFormat($hexVal,$places); - } // function BINTOHEX() - - - /** - * BINTOOCT - * - * Return a binary value as octal. - * - * Excel Function: - * BIN2OCT(x[,places]) - * - * @access public - * @category Engineering Functions - * @param string $x The binary number (as a string) that you want to convert. The number - * cannot contain more than 10 characters (10 bits). The most significant - * bit of number is the sign bit. The remaining 9 bits are magnitude bits. - * Negative numbers are represented using two's-complement notation. - * If number is not a valid binary number, or if number contains more than - * 10 characters (10 bits), BIN2OCT returns the #NUM! error value. - * @param integer $places The number of characters to use. If places is omitted, BIN2OCT uses the - * minimum number of characters necessary. Places is useful for padding the - * return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, BIN2OCT returns the #VALUE! error value. - * If places is negative, BIN2OCT returns the #NUM! error value. - * @return string - */ - public static function BINTOOCT($x, $places=NULL) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); - - if (is_bool($x)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - $x = (int) $x; - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - $x = floor($x); - } - $x = (string) $x; - if (strlen($x) > preg_match_all('/[01]/',$x,$out)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (strlen($x) > 10) { - return PHPExcel_Calculation_Functions::NaN(); - } elseif (strlen($x) == 10) { - // Two's Complement - return str_repeat('7',7).substr(strtoupper(decoct(bindec(substr($x,-9)))),-3); - } - $octVal = (string) decoct(bindec($x)); - - return self::_nbrConversionFormat($octVal,$places); - } // function BINTOOCT() - - - /** - * DECTOBIN - * - * Return a decimal value as binary. - * - * Excel Function: - * DEC2BIN(x[,places]) - * - * @access public - * @category Engineering Functions - * @param string $x The decimal integer you want to convert. If number is negative, - * valid place values are ignored and DEC2BIN returns a 10-character - * (10-bit) binary number in which the most significant bit is the sign - * bit. The remaining 9 bits are magnitude bits. Negative numbers are - * represented using two's-complement notation. - * If number < -512 or if number > 511, DEC2BIN returns the #NUM! error - * value. - * If number is nonnumeric, DEC2BIN returns the #VALUE! error value. - * If DEC2BIN requires more than places characters, it returns the #NUM! - * error value. - * @param integer $places The number of characters to use. If places is omitted, DEC2BIN uses - * the minimum number of characters necessary. Places is useful for - * padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, DEC2BIN returns the #VALUE! error value. - * If places is zero or negative, DEC2BIN returns the #NUM! error value. - * @return string - */ - public static function DECTOBIN($x, $places=NULL) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); - - if (is_bool($x)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - $x = (int) $x; - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - $x = (string) $x; - if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $x = (string) floor($x); - $r = decbin($x); - if (strlen($r) == 32) { - // Two's Complement - $r = substr($r,-10); - } elseif (strlen($r) > 11) { - return PHPExcel_Calculation_Functions::NaN(); - } - - return self::_nbrConversionFormat($r,$places); - } // function DECTOBIN() - - - /** - * DECTOHEX - * - * Return a decimal value as hex. - * - * Excel Function: - * DEC2HEX(x[,places]) - * - * @access public - * @category Engineering Functions - * @param string $x The decimal integer you want to convert. If number is negative, - * places is ignored and DEC2HEX returns a 10-character (40-bit) - * hexadecimal number in which the most significant bit is the sign - * bit. The remaining 39 bits are magnitude bits. Negative numbers - * are represented using two's-complement notation. - * If number < -549,755,813,888 or if number > 549,755,813,887, - * DEC2HEX returns the #NUM! error value. - * If number is nonnumeric, DEC2HEX returns the #VALUE! error value. - * If DEC2HEX requires more than places characters, it returns the - * #NUM! error value. - * @param integer $places The number of characters to use. If places is omitted, DEC2HEX uses - * the minimum number of characters necessary. Places is useful for - * padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, DEC2HEX returns the #VALUE! error value. - * If places is zero or negative, DEC2HEX returns the #NUM! error value. - * @return string - */ - public static function DECTOHEX($x, $places=null) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); - - if (is_bool($x)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - $x = (int) $x; - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - $x = (string) $x; - if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $x = (string) floor($x); - $r = strtoupper(dechex($x)); - if (strlen($r) == 8) { - // Two's Complement - $r = 'FF'.$r; - } - - return self::_nbrConversionFormat($r,$places); - } // function DECTOHEX() - - - /** - * DECTOOCT - * - * Return an decimal value as octal. - * - * Excel Function: - * DEC2OCT(x[,places]) - * - * @access public - * @category Engineering Functions - * @param string $x The decimal integer you want to convert. If number is negative, - * places is ignored and DEC2OCT returns a 10-character (30-bit) - * octal number in which the most significant bit is the sign bit. - * The remaining 29 bits are magnitude bits. Negative numbers are - * represented using two's-complement notation. - * If number < -536,870,912 or if number > 536,870,911, DEC2OCT - * returns the #NUM! error value. - * If number is nonnumeric, DEC2OCT returns the #VALUE! error value. - * If DEC2OCT requires more than places characters, it returns the - * #NUM! error value. - * @param integer $places The number of characters to use. If places is omitted, DEC2OCT uses - * the minimum number of characters necessary. Places is useful for - * padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, DEC2OCT returns the #VALUE! error value. - * If places is zero or negative, DEC2OCT returns the #NUM! error value. - * @return string - */ - public static function DECTOOCT($x, $places=null) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); - - if (is_bool($x)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - $x = (int) $x; - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - $x = (string) $x; - if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $x = (string) floor($x); - $r = decoct($x); - if (strlen($r) == 11) { - // Two's Complement - $r = substr($r,-10); - } - - return self::_nbrConversionFormat($r,$places); - } // function DECTOOCT() - - - /** - * HEXTOBIN - * - * Return a hex value as binary. - * - * Excel Function: - * HEX2BIN(x[,places]) - * - * @access public - * @category Engineering Functions - * @param string $x the hexadecimal number you want to convert. Number cannot - * contain more than 10 characters. The most significant bit of - * number is the sign bit (40th bit from the right). The remaining - * 9 bits are magnitude bits. Negative numbers are represented - * using two's-complement notation. - * If number is negative, HEX2BIN ignores places and returns a - * 10-character binary number. - * If number is negative, it cannot be less than FFFFFFFE00, and - * if number is positive, it cannot be greater than 1FF. - * If number is not a valid hexadecimal number, HEX2BIN returns - * the #NUM! error value. - * If HEX2BIN requires more than places characters, it returns - * the #NUM! error value. - * @param integer $places The number of characters to use. If places is omitted, - * HEX2BIN uses the minimum number of characters necessary. Places - * is useful for padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, HEX2BIN returns the #VALUE! error value. - * If places is negative, HEX2BIN returns the #NUM! error value. - * @return string - */ - public static function HEXTOBIN($x, $places=null) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); - - if (is_bool($x)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $x = (string) $x; - if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $binVal = decbin(hexdec($x)); - - return substr(self::_nbrConversionFormat($binVal,$places),-10); - } // function HEXTOBIN() - - - /** - * HEXTODEC - * - * Return a hex value as decimal. - * - * Excel Function: - * HEX2DEC(x) - * - * @access public - * @category Engineering Functions - * @param string $x The hexadecimal number you want to convert. This number cannot - * contain more than 10 characters (40 bits). The most significant - * bit of number is the sign bit. The remaining 39 bits are magnitude - * bits. Negative numbers are represented using two's-complement - * notation. - * If number is not a valid hexadecimal number, HEX2DEC returns the - * #NUM! error value. - * @return string - */ - public static function HEXTODEC($x) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - - if (is_bool($x)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $x = (string) $x; - if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) { - return PHPExcel_Calculation_Functions::NaN(); - } - return hexdec($x); - } // function HEXTODEC() - - - /** - * HEXTOOCT - * - * Return a hex value as octal. - * - * Excel Function: - * HEX2OCT(x[,places]) - * - * @access public - * @category Engineering Functions - * @param string $x The hexadecimal number you want to convert. Number cannot - * contain more than 10 characters. The most significant bit of - * number is the sign bit. The remaining 39 bits are magnitude - * bits. Negative numbers are represented using two's-complement - * notation. - * If number is negative, HEX2OCT ignores places and returns a - * 10-character octal number. - * If number is negative, it cannot be less than FFE0000000, and - * if number is positive, it cannot be greater than 1FFFFFFF. - * If number is not a valid hexadecimal number, HEX2OCT returns - * the #NUM! error value. - * If HEX2OCT requires more than places characters, it returns - * the #NUM! error value. - * @param integer $places The number of characters to use. If places is omitted, HEX2OCT - * uses the minimum number of characters necessary. Places is - * useful for padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, HEX2OCT returns the #VALUE! error - * value. - * If places is negative, HEX2OCT returns the #NUM! error value. - * @return string - */ - public static function HEXTOOCT($x, $places=null) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); - - if (is_bool($x)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $x = (string) $x; - if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $octVal = decoct(hexdec($x)); - - return self::_nbrConversionFormat($octVal,$places); - } // function HEXTOOCT() - - - /** - * OCTTOBIN - * - * Return an octal value as binary. - * - * Excel Function: - * OCT2BIN(x[,places]) - * - * @access public - * @category Engineering Functions - * @param string $x The octal number you want to convert. Number may not - * contain more than 10 characters. The most significant - * bit of number is the sign bit. The remaining 29 bits - * are magnitude bits. Negative numbers are represented - * using two's-complement notation. - * If number is negative, OCT2BIN ignores places and returns - * a 10-character binary number. - * If number is negative, it cannot be less than 7777777000, - * and if number is positive, it cannot be greater than 777. - * If number is not a valid octal number, OCT2BIN returns - * the #NUM! error value. - * If OCT2BIN requires more than places characters, it - * returns the #NUM! error value. - * @param integer $places The number of characters to use. If places is omitted, - * OCT2BIN uses the minimum number of characters necessary. - * Places is useful for padding the return value with - * leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, OCT2BIN returns the #VALUE! - * error value. - * If places is negative, OCT2BIN returns the #NUM! error - * value. - * @return string - */ - public static function OCTTOBIN($x, $places=null) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); - - if (is_bool($x)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $x = (string) $x; - if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $r = decbin(octdec($x)); - - return self::_nbrConversionFormat($r,$places); - } // function OCTTOBIN() - - - /** - * OCTTODEC - * - * Return an octal value as decimal. - * - * Excel Function: - * OCT2DEC(x) - * - * @access public - * @category Engineering Functions - * @param string $x The octal number you want to convert. Number may not contain - * more than 10 octal characters (30 bits). The most significant - * bit of number is the sign bit. The remaining 29 bits are - * magnitude bits. Negative numbers are represented using - * two's-complement notation. - * If number is not a valid octal number, OCT2DEC returns the - * #NUM! error value. - * @return string - */ - public static function OCTTODEC($x) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - - if (is_bool($x)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $x = (string) $x; - if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) { - return PHPExcel_Calculation_Functions::NaN(); - } - return octdec($x); - } // function OCTTODEC() - - - /** - * OCTTOHEX - * - * Return an octal value as hex. - * - * Excel Function: - * OCT2HEX(x[,places]) - * - * @access public - * @category Engineering Functions - * @param string $x The octal number you want to convert. Number may not contain - * more than 10 octal characters (30 bits). The most significant - * bit of number is the sign bit. The remaining 29 bits are - * magnitude bits. Negative numbers are represented using - * two's-complement notation. - * If number is negative, OCT2HEX ignores places and returns a - * 10-character hexadecimal number. - * If number is not a valid octal number, OCT2HEX returns the - * #NUM! error value. - * If OCT2HEX requires more than places characters, it returns - * the #NUM! error value. - * @param integer $places The number of characters to use. If places is omitted, OCT2HEX - * uses the minimum number of characters necessary. Places is useful - * for padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, OCT2HEX returns the #VALUE! error value. - * If places is negative, OCT2HEX returns the #NUM! error value. - * @return string - */ - public static function OCTTOHEX($x, $places=null) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); - - if (is_bool($x)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $x = (string) $x; - if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $hexVal = strtoupper(dechex(octdec($x))); - - return self::_nbrConversionFormat($hexVal,$places); - } // function OCTTOHEX() - - - /** - * COMPLEX - * - * Converts real and imaginary coefficients into a complex number of the form x + yi or x + yj. - * - * Excel Function: - * COMPLEX(realNumber,imaginary[,places]) - * - * @access public - * @category Engineering Functions - * @param float $realNumber The real coefficient of the complex number. - * @param float $imaginary The imaginary coefficient of the complex number. - * @param string $suffix The suffix for the imaginary component of the complex number. - * If omitted, the suffix is assumed to be "i". - * @return string - */ - public static function COMPLEX($realNumber=0.0, $imaginary=0.0, $suffix='i') { - $realNumber = (is_null($realNumber)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($realNumber); - $imaginary = (is_null($imaginary)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($imaginary); - $suffix = (is_null($suffix)) ? 'i' : PHPExcel_Calculation_Functions::flattenSingleValue($suffix); - - if (((is_numeric($realNumber)) && (is_numeric($imaginary))) && - (($suffix == 'i') || ($suffix == 'j') || ($suffix == ''))) { - $realNumber = (float) $realNumber; - $imaginary = (float) $imaginary; - - if ($suffix == '') $suffix = 'i'; - if ($realNumber == 0.0) { - if ($imaginary == 0.0) { - return (string) '0'; - } elseif ($imaginary == 1.0) { - return (string) $suffix; - } elseif ($imaginary == -1.0) { - return (string) '-'.$suffix; - } - return (string) $imaginary.$suffix; - } elseif ($imaginary == 0.0) { - return (string) $realNumber; - } elseif ($imaginary == 1.0) { - return (string) $realNumber.'+'.$suffix; - } elseif ($imaginary == -1.0) { - return (string) $realNumber.'-'.$suffix; - } - if ($imaginary > 0) { $imaginary = (string) '+'.$imaginary; } - return (string) $realNumber.$imaginary.$suffix; - } - - return PHPExcel_Calculation_Functions::VALUE(); - } // function COMPLEX() - - - /** - * IMAGINARY - * - * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMAGINARY(complexNumber) - * - * @access public - * @category Engineering Functions - * @param string $complexNumber The complex number for which you want the imaginary - * coefficient. - * @return float - */ - public static function IMAGINARY($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - return $parsedComplex['imaginary']; - } // function IMAGINARY() - - - /** - * IMREAL - * - * Returns the real coefficient of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMREAL(complexNumber) - * - * @access public - * @category Engineering Functions - * @param string $complexNumber The complex number for which you want the real coefficient. - * @return float - */ - public static function IMREAL($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - return $parsedComplex['real']; - } // function IMREAL() - - - /** - * IMABS - * - * Returns the absolute value (modulus) of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMABS(complexNumber) - * - * @param string $complexNumber The complex number for which you want the absolute value. - * @return float - */ - public static function IMABS($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - - return sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])); - } // function IMABS() - - - /** - * IMARGUMENT - * - * Returns the argument theta of a complex number, i.e. the angle in radians from the real - * axis to the representation of the number in polar coordinates. - * - * Excel Function: - * IMARGUMENT(complexNumber) - * - * @param string $complexNumber The complex number for which you want the argument theta. - * @return float - */ - public static function IMARGUMENT($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - - if ($parsedComplex['real'] == 0.0) { - if ($parsedComplex['imaginary'] == 0.0) { - return 0.0; - } elseif($parsedComplex['imaginary'] < 0.0) { - return M_PI / -2; - } else { - return M_PI / 2; - } - } elseif ($parsedComplex['real'] > 0.0) { - return atan($parsedComplex['imaginary'] / $parsedComplex['real']); - } elseif ($parsedComplex['imaginary'] < 0.0) { - return 0 - (M_PI - atan(abs($parsedComplex['imaginary']) / abs($parsedComplex['real']))); - } else { - return M_PI - atan($parsedComplex['imaginary'] / abs($parsedComplex['real'])); - } - } // function IMARGUMENT() - - - /** - * IMCONJUGATE - * - * Returns the complex conjugate of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMCONJUGATE(complexNumber) - * - * @param string $complexNumber The complex number for which you want the conjugate. - * @return string - */ - public static function IMCONJUGATE($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - - if ($parsedComplex['imaginary'] == 0.0) { - return $parsedComplex['real']; - } else { - return self::_cleanComplex( self::COMPLEX( $parsedComplex['real'], - 0 - $parsedComplex['imaginary'], - $parsedComplex['suffix'] - ) - ); - } - } // function IMCONJUGATE() - - - /** - * IMCOS - * - * Returns the cosine of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMCOS(complexNumber) - * - * @param string $complexNumber The complex number for which you want the cosine. - * @return string|float - */ - public static function IMCOS($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - - if ($parsedComplex['imaginary'] == 0.0) { - return cos($parsedComplex['real']); - } else { - return self::IMCONJUGATE(self::COMPLEX(cos($parsedComplex['real']) * cosh($parsedComplex['imaginary']),sin($parsedComplex['real']) * sinh($parsedComplex['imaginary']),$parsedComplex['suffix'])); - } - } // function IMCOS() - - - /** - * IMSIN - * - * Returns the sine of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMSIN(complexNumber) - * - * @param string $complexNumber The complex number for which you want the sine. - * @return string|float - */ - public static function IMSIN($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - - if ($parsedComplex['imaginary'] == 0.0) { - return sin($parsedComplex['real']); - } else { - return self::COMPLEX(sin($parsedComplex['real']) * cosh($parsedComplex['imaginary']),cos($parsedComplex['real']) * sinh($parsedComplex['imaginary']),$parsedComplex['suffix']); - } - } // function IMSIN() - - - /** - * IMSQRT - * - * Returns the square root of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMSQRT(complexNumber) - * - * @param string $complexNumber The complex number for which you want the square root. - * @return string - */ - public static function IMSQRT($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - - $theta = self::IMARGUMENT($complexNumber); - $d1 = cos($theta / 2); - $d2 = sin($theta / 2); - $r = sqrt(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']))); - - if ($parsedComplex['suffix'] == '') { - return self::COMPLEX($d1 * $r,$d2 * $r); - } else { - return self::COMPLEX($d1 * $r,$d2 * $r,$parsedComplex['suffix']); - } - } // function IMSQRT() - - - /** - * IMLN - * - * Returns the natural logarithm of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMLN(complexNumber) - * - * @param string $complexNumber The complex number for which you want the natural logarithm. - * @return string - */ - public static function IMLN($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - - if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - - $logR = log(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']))); - $t = self::IMARGUMENT($complexNumber); - - if ($parsedComplex['suffix'] == '') { - return self::COMPLEX($logR,$t); - } else { - return self::COMPLEX($logR,$t,$parsedComplex['suffix']); - } - } // function IMLN() - - - /** - * IMLOG10 - * - * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMLOG10(complexNumber) - * - * @param string $complexNumber The complex number for which you want the common logarithm. - * @return string - */ - public static function IMLOG10($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - - if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { - return PHPExcel_Calculation_Functions::NaN(); - } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) { - return log10($parsedComplex['real']); - } - - return self::IMPRODUCT(log10(EULER),self::IMLN($complexNumber)); - } // function IMLOG10() - - - /** - * IMLOG2 - * - * Returns the base-2 logarithm of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMLOG2(complexNumber) - * - * @param string $complexNumber The complex number for which you want the base-2 logarithm. - * @return string - */ - public static function IMLOG2($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - - if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { - return PHPExcel_Calculation_Functions::NaN(); - } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) { - return log($parsedComplex['real'],2); - } - - return self::IMPRODUCT(log(EULER,2),self::IMLN($complexNumber)); - } // function IMLOG2() - - - /** - * IMEXP - * - * Returns the exponential of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMEXP(complexNumber) - * - * @param string $complexNumber The complex number for which you want the exponential. - * @return string - */ - public static function IMEXP($complexNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - - $parsedComplex = self::_parseComplex($complexNumber); - - if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { - return '1'; - } - - $e = exp($parsedComplex['real']); - $eX = $e * cos($parsedComplex['imaginary']); - $eY = $e * sin($parsedComplex['imaginary']); - - if ($parsedComplex['suffix'] == '') { - return self::COMPLEX($eX,$eY); - } else { - return self::COMPLEX($eX,$eY,$parsedComplex['suffix']); - } - } // function IMEXP() - - - /** - * IMPOWER - * - * Returns a complex number in x + yi or x + yj text format raised to a power. - * - * Excel Function: - * IMPOWER(complexNumber,realNumber) - * - * @param string $complexNumber The complex number you want to raise to a power. - * @param float $realNumber The power to which you want to raise the complex number. - * @return string - */ - public static function IMPOWER($complexNumber,$realNumber) { - $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $realNumber = PHPExcel_Calculation_Functions::flattenSingleValue($realNumber); - - if (!is_numeric($realNumber)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - $parsedComplex = self::_parseComplex($complexNumber); - - $r = sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])); - $rPower = pow($r,$realNumber); - $theta = self::IMARGUMENT($complexNumber) * $realNumber; - if ($theta == 0) { - return 1; - } elseif ($parsedComplex['imaginary'] == 0.0) { - return self::COMPLEX($rPower * cos($theta),$rPower * sin($theta),$parsedComplex['suffix']); - } else { - return self::COMPLEX($rPower * cos($theta),$rPower * sin($theta),$parsedComplex['suffix']); - } - } // function IMPOWER() - - - /** - * IMDIV - * - * Returns the quotient of two complex numbers in x + yi or x + yj text format. - * - * Excel Function: - * IMDIV(complexDividend,complexDivisor) - * - * @param string $complexDividend The complex numerator or dividend. - * @param string $complexDivisor The complex denominator or divisor. - * @return string - */ - public static function IMDIV($complexDividend,$complexDivisor) { - $complexDividend = PHPExcel_Calculation_Functions::flattenSingleValue($complexDividend); - $complexDivisor = PHPExcel_Calculation_Functions::flattenSingleValue($complexDivisor); - - $parsedComplexDividend = self::_parseComplex($complexDividend); - $parsedComplexDivisor = self::_parseComplex($complexDivisor); - - if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] != '') && - ($parsedComplexDividend['suffix'] != $parsedComplexDivisor['suffix'])) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] == '')) { - $parsedComplexDivisor['suffix'] = $parsedComplexDividend['suffix']; - } - - $d1 = ($parsedComplexDividend['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['imaginary']); - $d2 = ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['real']) - ($parsedComplexDividend['real'] * $parsedComplexDivisor['imaginary']); - $d3 = ($parsedComplexDivisor['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDivisor['imaginary'] * $parsedComplexDivisor['imaginary']); - - $r = $d1/$d3; - $i = $d2/$d3; - - if ($i > 0.0) { - return self::_cleanComplex($r.'+'.$i.$parsedComplexDivisor['suffix']); - } elseif ($i < 0.0) { - return self::_cleanComplex($r.$i.$parsedComplexDivisor['suffix']); - } else { - return $r; - } - } // function IMDIV() - - - /** - * IMSUB - * - * Returns the difference of two complex numbers in x + yi or x + yj text format. - * - * Excel Function: - * IMSUB(complexNumber1,complexNumber2) - * - * @param string $complexNumber1 The complex number from which to subtract complexNumber2. - * @param string $complexNumber2 The complex number to subtract from complexNumber1. - * @return string - */ - public static function IMSUB($complexNumber1,$complexNumber2) { - $complexNumber1 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber1); - $complexNumber2 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber2); - - $parsedComplex1 = self::_parseComplex($complexNumber1); - $parsedComplex2 = self::_parseComplex($complexNumber2); - - if ((($parsedComplex1['suffix'] != '') && ($parsedComplex2['suffix'] != '')) && - ($parsedComplex1['suffix'] != $parsedComplex2['suffix'])) { - return PHPExcel_Calculation_Functions::NaN(); - } elseif (($parsedComplex1['suffix'] == '') && ($parsedComplex2['suffix'] != '')) { - $parsedComplex1['suffix'] = $parsedComplex2['suffix']; - } - - $d1 = $parsedComplex1['real'] - $parsedComplex2['real']; - $d2 = $parsedComplex1['imaginary'] - $parsedComplex2['imaginary']; - - return self::COMPLEX($d1,$d2,$parsedComplex1['suffix']); - } // function IMSUB() - - - /** - * IMSUM - * - * Returns the sum of two or more complex numbers in x + yi or x + yj text format. - * - * Excel Function: - * IMSUM(complexNumber[,complexNumber[,...]]) - * - * @param string $complexNumber,... Series of complex numbers to add - * @return string - */ - public static function IMSUM() { - // Return value - $returnValue = self::_parseComplex('0'); - $activeSuffix = ''; - - // Loop through the arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - foreach ($aArgs as $arg) { - $parsedComplex = self::_parseComplex($arg); - - if ($activeSuffix == '') { - $activeSuffix = $parsedComplex['suffix']; - } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - $returnValue['real'] += $parsedComplex['real']; - $returnValue['imaginary'] += $parsedComplex['imaginary']; - } - - if ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; } - return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix); - } // function IMSUM() - - - /** - * IMPRODUCT - * - * Returns the product of two or more complex numbers in x + yi or x + yj text format. - * - * Excel Function: - * IMPRODUCT(complexNumber[,complexNumber[,...]]) - * - * @param string $complexNumber,... Series of complex numbers to multiply - * @return string - */ - public static function IMPRODUCT() { - // Return value - $returnValue = self::_parseComplex('1'); - $activeSuffix = ''; - - // Loop through the arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - foreach ($aArgs as $arg) { - $parsedComplex = self::_parseComplex($arg); - - $workValue = $returnValue; - if (($parsedComplex['suffix'] != '') && ($activeSuffix == '')) { - $activeSuffix = $parsedComplex['suffix']; - } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) { - return PHPExcel_Calculation_Functions::NaN(); - } - $returnValue['real'] = ($workValue['real'] * $parsedComplex['real']) - ($workValue['imaginary'] * $parsedComplex['imaginary']); - $returnValue['imaginary'] = ($workValue['real'] * $parsedComplex['imaginary']) + ($workValue['imaginary'] * $parsedComplex['real']); - } - - if ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; } - return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix); - } // function IMPRODUCT() - - - /** - * DELTA - * - * Tests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise. - * Use this function to filter a set of values. For example, by summing several DELTA - * functions you calculate the count of equal pairs. This function is also known as the - * Kronecker Delta function. - * - * Excel Function: - * DELTA(a[,b]) - * - * @param float $a The first number. - * @param float $b The second number. If omitted, b is assumed to be zero. - * @return int - */ - public static function DELTA($a, $b=0) { - $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); - $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); - - return (int) ($a == $b); - } // function DELTA() - - - /** - * GESTEP - * - * Excel Function: - * GESTEP(number[,step]) - * - * Returns 1 if number >= step; returns 0 (zero) otherwise - * Use this function to filter a set of values. For example, by summing several GESTEP - * functions you calculate the count of values that exceed a threshold. - * - * @param float $number The value to test against step. - * @param float $step The threshold value. - * If you omit a value for step, GESTEP uses zero. - * @return int - */ - public static function GESTEP($number, $step=0) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - $step = PHPExcel_Calculation_Functions::flattenSingleValue($step); - - return (int) ($number >= $step); - } // function GESTEP() - - - // - // Private method to calculate the erf value - // - private static $_two_sqrtpi = 1.128379167095512574; - - public static function _erfVal($x) { - if (abs($x) > 2.2) { - return 1 - self::_erfcVal($x); - } - $sum = $term = $x; - $xsqr = ($x * $x); - $j = 1; - do { - $term *= $xsqr / $j; - $sum -= $term / (2 * $j + 1); - ++$j; - $term *= $xsqr / $j; - $sum += $term / (2 * $j + 1); - ++$j; - if ($sum == 0.0) { - break; - } - } while (abs($term / $sum) > PRECISION); - return self::$_two_sqrtpi * $sum; - } // function _erfVal() - - - /** - * ERF - * - * Returns the error function integrated between the lower and upper bound arguments. - * - * Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments, - * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was - * improved, so that it can now calculate the function for both positive and negative ranges. - * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments. - * - * Excel Function: - * ERF(lower[,upper]) - * - * @param float $lower lower bound for integrating ERF - * @param float $upper upper bound for integrating ERF. - * If omitted, ERF integrates between zero and lower_limit - * @return float - */ - public static function ERF($lower, $upper = NULL) { - $lower = PHPExcel_Calculation_Functions::flattenSingleValue($lower); - $upper = PHPExcel_Calculation_Functions::flattenSingleValue($upper); - - if (is_numeric($lower)) { - if (is_null($upper)) { - return self::_erfVal($lower); - } - if (is_numeric($upper)) { - return self::_erfVal($upper) - self::_erfVal($lower); - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function ERF() - - - // - // Private method to calculate the erfc value - // - private static $_one_sqrtpi = 0.564189583547756287; - - private static function _erfcVal($x) { - if (abs($x) < 2.2) { - return 1 - self::_erfVal($x); - } - if ($x < 0) { - return 2 - self::ERFC(-$x); - } - $a = $n = 1; - $b = $c = $x; - $d = ($x * $x) + 0.5; - $q1 = $q2 = $b / $d; - $t = 0; - do { - $t = $a * $n + $b * $x; - $a = $b; - $b = $t; - $t = $c * $n + $d * $x; - $c = $d; - $d = $t; - $n += 0.5; - $q1 = $q2; - $q2 = $b / $d; - } while ((abs($q1 - $q2) / $q2) > PRECISION); - return self::$_one_sqrtpi * exp(-$x * $x) * $q2; - } // function _erfcVal() - - - /** - * ERFC - * - * Returns the complementary ERF function integrated between x and infinity - * - * Note: In Excel 2007 or earlier, if you input a negative value for the lower bound argument, - * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was - * improved, so that it can now calculate the function for both positive and negative x values. - * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments. - * - * Excel Function: - * ERFC(x) - * - * @param float $x The lower bound for integrating ERFC - * @return float - */ - public static function ERFC($x) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - - if (is_numeric($x)) { - return self::_erfcVal($x); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function ERFC() - - - /** - * getConversionGroups - * Returns a list of the different conversion groups for UOM conversions - * - * @return array - */ - public static function getConversionGroups() { - $conversionGroups = array(); - foreach(self::$_conversionUnits as $conversionUnit) { - $conversionGroups[] = $conversionUnit['Group']; - } - return array_merge(array_unique($conversionGroups)); - } // function getConversionGroups() - - - /** - * getConversionGroupUnits - * Returns an array of units of measure, for a specified conversion group, or for all groups - * - * @param string $group The group whose units of measure you want to retrieve - * @return array - */ - public static function getConversionGroupUnits($group = NULL) { - $conversionGroups = array(); - foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) { - if ((is_null($group)) || ($conversionGroup['Group'] == $group)) { - $conversionGroups[$conversionGroup['Group']][] = $conversionUnit; - } - } - return $conversionGroups; - } // function getConversionGroupUnits() - - - /** - * getConversionGroupUnitDetails - * - * @param string $group The group whose units of measure you want to retrieve - * @return array - */ - public static function getConversionGroupUnitDetails($group = NULL) { - $conversionGroups = array(); - foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) { - if ((is_null($group)) || ($conversionGroup['Group'] == $group)) { - $conversionGroups[$conversionGroup['Group']][] = array( 'unit' => $conversionUnit, - 'description' => $conversionGroup['Unit Name'] - ); - } - } - return $conversionGroups; - } // function getConversionGroupUnitDetails() - - - /** - * getConversionMultipliers - * Returns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM() - * - * @return array of mixed - */ - public static function getConversionMultipliers() { - return self::$_conversionMultipliers; - } // function getConversionGroups() - - - /** - * CONVERTUOM - * - * Converts a number from one measurement system to another. - * For example, CONVERT can translate a table of distances in miles to a table of distances - * in kilometers. - * - * Excel Function: - * CONVERT(value,fromUOM,toUOM) - * - * @param float $value The value in fromUOM to convert. - * @param string $fromUOM The units for value. - * @param string $toUOM The units for the result. - * - * @return float - */ - public static function CONVERTUOM($value, $fromUOM, $toUOM) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $fromUOM = PHPExcel_Calculation_Functions::flattenSingleValue($fromUOM); - $toUOM = PHPExcel_Calculation_Functions::flattenSingleValue($toUOM); - - if (!is_numeric($value)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $fromMultiplier = 1.0; - if (isset(self::$_conversionUnits[$fromUOM])) { - $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group']; - } else { - $fromMultiplier = substr($fromUOM,0,1); - $fromUOM = substr($fromUOM,1); - if (isset(self::$_conversionMultipliers[$fromMultiplier])) { - $fromMultiplier = self::$_conversionMultipliers[$fromMultiplier]['multiplier']; - } else { - return PHPExcel_Calculation_Functions::NA(); - } - if ((isset(self::$_conversionUnits[$fromUOM])) && (self::$_conversionUnits[$fromUOM]['AllowPrefix'])) { - $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group']; - } else { - return PHPExcel_Calculation_Functions::NA(); - } - } - $value *= $fromMultiplier; - - $toMultiplier = 1.0; - if (isset(self::$_conversionUnits[$toUOM])) { - $unitGroup2 = self::$_conversionUnits[$toUOM]['Group']; - } else { - $toMultiplier = substr($toUOM,0,1); - $toUOM = substr($toUOM,1); - if (isset(self::$_conversionMultipliers[$toMultiplier])) { - $toMultiplier = self::$_conversionMultipliers[$toMultiplier]['multiplier']; - } else { - return PHPExcel_Calculation_Functions::NA(); - } - if ((isset(self::$_conversionUnits[$toUOM])) && (self::$_conversionUnits[$toUOM]['AllowPrefix'])) { - $unitGroup2 = self::$_conversionUnits[$toUOM]['Group']; - } else { - return PHPExcel_Calculation_Functions::NA(); - } - } - if ($unitGroup1 != $unitGroup2) { - return PHPExcel_Calculation_Functions::NA(); - } - - if (($fromUOM == $toUOM) && ($fromMultiplier == $toMultiplier)) { - // We've already factored $fromMultiplier into the value, so we need - // to reverse it again - return $value / $fromMultiplier; - } elseif ($unitGroup1 == 'Temperature') { - if (($fromUOM == 'F') || ($fromUOM == 'fah')) { - if (($toUOM == 'F') || ($toUOM == 'fah')) { - return $value; - } else { - $value = (($value - 32) / 1.8); - if (($toUOM == 'K') || ($toUOM == 'kel')) { - $value += 273.15; - } - return $value; - } - } elseif ((($fromUOM == 'K') || ($fromUOM == 'kel')) && - (($toUOM == 'K') || ($toUOM == 'kel'))) { - return $value; - } elseif ((($fromUOM == 'C') || ($fromUOM == 'cel')) && - (($toUOM == 'C') || ($toUOM == 'cel'))) { - return $value; - } - if (($toUOM == 'F') || ($toUOM == 'fah')) { - if (($fromUOM == 'K') || ($fromUOM == 'kel')) { - $value -= 273.15; - } - return ($value * 1.8) + 32; - } - if (($toUOM == 'C') || ($toUOM == 'cel')) { - return $value - 273.15; - } - return $value + 273.15; - } - return ($value * self::$_unitConversions[$unitGroup1][$fromUOM][$toUOM]) / $toMultiplier; - } // function CONVERTUOM() - -} // class PHPExcel_Calculation_Engineering +class PHPExcel_Calculation_Engineering +{ + /** + * Details of the Units of measure that can be used in CONVERTUOM() + * + * @var mixed[] + */ + private static $_conversionUnits = array( + 'g' => array('Group' => 'Mass', 'Unit Name' => 'Gram', 'AllowPrefix' => true), + 'sg' => array('Group' => 'Mass', 'Unit Name' => 'Slug', 'AllowPrefix' => false), + 'lbm' => array('Group' => 'Mass', 'Unit Name' => 'Pound mass (avoirdupois)', 'AllowPrefix' => false), + 'u' => array('Group' => 'Mass', 'Unit Name' => 'U (atomic mass unit)', 'AllowPrefix' => true), + 'ozm' => array('Group' => 'Mass', 'Unit Name' => 'Ounce mass (avoirdupois)', 'AllowPrefix' => false), + 'm' => array('Group' => 'Distance', 'Unit Name' => 'Meter', 'AllowPrefix' => true), + 'mi' => array('Group' => 'Distance', 'Unit Name' => 'Statute mile', 'AllowPrefix' => false), + 'Nmi' => array('Group' => 'Distance', 'Unit Name' => 'Nautical mile', 'AllowPrefix' => false), + 'in' => array('Group' => 'Distance', 'Unit Name' => 'Inch', 'AllowPrefix' => false), + 'ft' => array('Group' => 'Distance', 'Unit Name' => 'Foot', 'AllowPrefix' => false), + 'yd' => array('Group' => 'Distance', 'Unit Name' => 'Yard', 'AllowPrefix' => false), + 'ang' => array('Group' => 'Distance', 'Unit Name' => 'Angstrom', 'AllowPrefix' => true), + 'Pica' => array('Group' => 'Distance', 'Unit Name' => 'Pica (1/72 in)', 'AllowPrefix' => false), + 'yr' => array('Group' => 'Time', 'Unit Name' => 'Year', 'AllowPrefix' => false), + 'day' => array('Group' => 'Time', 'Unit Name' => 'Day', 'AllowPrefix' => false), + 'hr' => array('Group' => 'Time', 'Unit Name' => 'Hour', 'AllowPrefix' => false), + 'mn' => array('Group' => 'Time', 'Unit Name' => 'Minute', 'AllowPrefix' => false), + 'sec' => array('Group' => 'Time', 'Unit Name' => 'Second', 'AllowPrefix' => true), + 'Pa' => array('Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => true), + 'p' => array('Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => true), + 'atm' => array('Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => true), + 'at' => array('Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => true), + 'mmHg' => array('Group' => 'Pressure', 'Unit Name' => 'mm of Mercury', 'AllowPrefix' => true), + 'N' => array('Group' => 'Force', 'Unit Name' => 'Newton', 'AllowPrefix' => true), + 'dyn' => array('Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => true), + 'dy' => array('Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => true), + 'lbf' => array('Group' => 'Force', 'Unit Name' => 'Pound force', 'AllowPrefix' => false), + 'J' => array('Group' => 'Energy', 'Unit Name' => 'Joule', 'AllowPrefix' => true), + 'e' => array('Group' => 'Energy', 'Unit Name' => 'Erg', 'AllowPrefix' => true), + 'c' => array('Group' => 'Energy', 'Unit Name' => 'Thermodynamic calorie', 'AllowPrefix' => true), + 'cal' => array('Group' => 'Energy', 'Unit Name' => 'IT calorie', 'AllowPrefix' => true), + 'eV' => array('Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => true), + 'ev' => array('Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => true), + 'HPh' => array('Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => false), + 'hh' => array('Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => false), + 'Wh' => array('Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => true), + 'wh' => array('Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => true), + 'flb' => array('Group' => 'Energy', 'Unit Name' => 'Foot-pound', 'AllowPrefix' => false), + 'BTU' => array('Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => false), + 'btu' => array('Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => false), + 'HP' => array('Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => false), + 'h' => array('Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => false), + 'W' => array('Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => true), + 'w' => array('Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => true), + 'T' => array('Group' => 'Magnetism', 'Unit Name' => 'Tesla', 'AllowPrefix' => true), + 'ga' => array('Group' => 'Magnetism', 'Unit Name' => 'Gauss', 'AllowPrefix' => true), + 'C' => array('Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => false), + 'cel' => array('Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => false), + 'F' => array('Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => false), + 'fah' => array('Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => false), + 'K' => array('Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => false), + 'kel' => array('Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => false), + 'tsp' => array('Group' => 'Liquid', 'Unit Name' => 'Teaspoon', 'AllowPrefix' => false), + 'tbs' => array('Group' => 'Liquid', 'Unit Name' => 'Tablespoon', 'AllowPrefix' => false), + 'oz' => array('Group' => 'Liquid', 'Unit Name' => 'Fluid Ounce', 'AllowPrefix' => false), + 'cup' => array('Group' => 'Liquid', 'Unit Name' => 'Cup', 'AllowPrefix' => false), + 'pt' => array('Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => false), + 'us_pt' => array('Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => false), + 'uk_pt' => array('Group' => 'Liquid', 'Unit Name' => 'U.K. Pint', 'AllowPrefix' => false), + 'qt' => array('Group' => 'Liquid', 'Unit Name' => 'Quart', 'AllowPrefix' => false), + 'gal' => array('Group' => 'Liquid', 'Unit Name' => 'Gallon', 'AllowPrefix' => false), + 'l' => array('Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => true), + 'lt' => array('Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => true), + ); + + /** + * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM() + * + * @var mixed[] + */ + private static $_conversionMultipliers = array( + 'Y' => array('multiplier' => 1E24, 'name' => 'yotta'), + 'Z' => array('multiplier' => 1E21, 'name' => 'zetta'), + 'E' => array('multiplier' => 1E18, 'name' => 'exa'), + 'P' => array('multiplier' => 1E15, 'name' => 'peta'), + 'T' => array('multiplier' => 1E12, 'name' => 'tera'), + 'G' => array('multiplier' => 1E9, 'name' => 'giga'), + 'M' => array('multiplier' => 1E6, 'name' => 'mega'), + 'k' => array('multiplier' => 1E3, 'name' => 'kilo'), + 'h' => array('multiplier' => 1E2, 'name' => 'hecto'), + 'e' => array('multiplier' => 1E1, 'name' => 'deka'), + 'd' => array('multiplier' => 1E-1, 'name' => 'deci'), + 'c' => array('multiplier' => 1E-2, 'name' => 'centi'), + 'm' => array('multiplier' => 1E-3, 'name' => 'milli'), + 'u' => array('multiplier' => 1E-6, 'name' => 'micro'), + 'n' => array('multiplier' => 1E-9, 'name' => 'nano'), + 'p' => array('multiplier' => 1E-12, 'name' => 'pico'), + 'f' => array('multiplier' => 1E-15, 'name' => 'femto'), + 'a' => array('multiplier' => 1E-18, 'name' => 'atto'), + 'z' => array('multiplier' => 1E-21, 'name' => 'zepto'), + 'y' => array('multiplier' => 1E-24, 'name' => 'yocto'), + ); + + /** + * Details of the Units of measure conversion factors, organised by group + * + * @var mixed[] + */ + private static $_unitConversions = array( + 'Mass' => array( + 'g' => array( + 'g' => 1.0, + 'sg' => 6.85220500053478E-05, + 'lbm' => 2.20462291469134E-03, + 'u' => 6.02217000000000E+23, + 'ozm' => 3.52739718003627E-02, + ), + 'sg' => array( + 'g' => 1.45938424189287E+04, + 'sg' => 1.0, + 'lbm' => 3.21739194101647E+01, + 'u' => 8.78866000000000E+27, + 'ozm' => 5.14782785944229E+02, + ), + 'lbm' => array( + 'g' => 4.5359230974881148E+02, + 'sg' => 3.10810749306493E-02, + 'lbm' => 1.0, + 'u' => 2.73161000000000E+26, + 'ozm' => 1.60000023429410E+01, + ), + 'u' => array( + 'g' => 1.66053100460465E-24, + 'sg' => 1.13782988532950E-28, + 'lbm' => 3.66084470330684E-27, + 'u' => 1.0, + 'ozm' => 5.85735238300524E-26, + ), + 'ozm' => array( + 'g' => 2.83495152079732E+01, + 'sg' => 1.94256689870811E-03, + 'lbm' => 6.24999908478882E-02, + 'u' => 1.70725600000000E+25, + 'ozm' => 1.0, + ), + ), + 'Distance' => array( + 'm' => array( + 'm' => 1.0, + 'mi' => 6.21371192237334E-04, + 'Nmi' => 5.39956803455724E-04, + 'in' => 3.93700787401575E+01, + 'ft' => 3.28083989501312E+00, + 'yd' => 1.09361329797891E+00, + 'ang' => 1.00000000000000E+10, + 'Pica' => 2.83464566929116E+03, + ), + 'mi' => array( + 'm' => 1.60934400000000E+03, + 'mi' => 1.0, + 'Nmi' => 8.68976241900648E-01, + 'in' => 6.33600000000000E+04, + 'ft' => 5.28000000000000E+03, + 'yd' => 1.76000000000000E+03, + 'ang' => 1.60934400000000E+13, + 'Pica' => 4.56191999999971E+06, + ), + 'Nmi' => array( + 'm' => 1.85200000000000E+03, + 'mi' => 1.15077944802354E+00, + 'Nmi' => 1.0, + 'in' => 7.29133858267717E+04, + 'ft' => 6.07611548556430E+03, + 'yd' => 2.02537182785694E+03, + 'ang' => 1.85200000000000E+13, + 'Pica' => 5.24976377952723E+06, + ), + 'in' => array( + 'm' => 2.54000000000000E-02, + 'mi' => 1.57828282828283E-05, + 'Nmi' => 1.37149028077754E-05, + 'in' => 1.0, + 'ft' => 8.33333333333333E-02, + 'yd' => 2.77777777686643E-02, + 'ang' => 2.54000000000000E+08, + 'Pica' => 7.19999999999955E+01, + ), + 'ft' => array( + 'm' => 3.04800000000000E-01, + 'mi' => 1.89393939393939E-04, + 'Nmi' => 1.64578833693305E-04, + 'in' => 1.20000000000000E+01, + 'ft' => 1.0, + 'yd' => 3.33333333223972E-01, + 'ang' => 3.04800000000000E+09, + 'Pica' => 8.63999999999946E+02, + ), + 'yd' => array( + 'm' => 9.14400000300000E-01, + 'mi' => 5.68181818368230E-04, + 'Nmi' => 4.93736501241901E-04, + 'in' => 3.60000000118110E+01, + 'ft' => 3.00000000000000E+00, + 'yd' => 1.0, + 'ang' => 9.14400000300000E+09, + 'Pica' => 2.59200000085023E+03, + ), + 'ang' => array( + 'm' => 1.00000000000000E-10, + 'mi' => 6.21371192237334E-14, + 'Nmi' => 5.39956803455724E-14, + 'in' => 3.93700787401575E-09, + 'ft' => 3.28083989501312E-10, + 'yd' => 1.09361329797891E-10, + 'ang' => 1.0, + 'Pica' => 2.83464566929116E-07, + ), + 'Pica' => array( + 'm' => 3.52777777777800E-04, + 'mi' => 2.19205948372629E-07, + 'Nmi' => 1.90484761219114E-07, + 'in' => 1.38888888888898E-02, + 'ft' => 1.15740740740748E-03, + 'yd' => 3.85802469009251E-04, + 'ang' => 3.52777777777800E+06, + 'Pica' => 1.0, + ), + ), + 'Time' => array( + 'yr' => array( + 'yr' => 1.0, + 'day' => 365.25, + 'hr' => 8766.0, + 'mn' => 525960.0, + 'sec' => 31557600.0, + ), + 'day' => array( + 'yr' => 2.73785078713210E-03, + 'day' => 1.0, + 'hr' => 24.0, + 'mn' => 1440.0, + 'sec' => 86400.0, + ), + 'hr' => array( + 'yr' => 1.14077116130504E-04, + 'day' => 4.16666666666667E-02, + 'hr' => 1.0, + 'mn' => 60.0, + 'sec' => 3600.0, + ), + 'mn' => array( + 'yr' => 1.90128526884174E-06, + 'day' => 6.94444444444444E-04, + 'hr' => 1.66666666666667E-02, + 'mn' => 1.0, + 'sec' => 60.0, + ), + 'sec' => array( + 'yr' => 3.16880878140289E-08, + 'day' => 1.15740740740741E-05, + 'hr' => 2.77777777777778E-04, + 'mn' => 1.66666666666667E-02, + 'sec' => 1.0, + ), + ), + 'Pressure' => array( + 'Pa' => array( + 'Pa' => 1.0, + 'p' => 1.0, + 'atm' => 9.86923299998193E-06, + 'at' => 9.86923299998193E-06, + 'mmHg' => 7.50061707998627E-03, + ), + 'p' => array( + 'Pa' => 1.0, + 'p' => 1.0, + 'atm' => 9.86923299998193E-06, + 'at' => 9.86923299998193E-06, + 'mmHg' => 7.50061707998627E-03, + ), + 'atm' => array( + 'Pa' => 1.01324996583000E+05, + 'p' => 1.01324996583000E+05, + 'atm' => 1.0, + 'at' => 1.0, + 'mmHg' => 760.0, + ), + 'at' => array( + 'Pa' => 1.01324996583000E+05, + 'p' => 1.01324996583000E+05, + 'atm' => 1.0, + 'at' => 1.0, + 'mmHg' => 760.0, + ), + 'mmHg' => array( + 'Pa' => 1.33322363925000E+02, + 'p' => 1.33322363925000E+02, + 'atm' => 1.31578947368421E-03, + 'at' => 1.31578947368421E-03, + 'mmHg' => 1.0, + ), + ), + 'Force' => array( + 'N' => array( + 'N' => 1.0, + 'dyn' => 1.0E+5, + 'dy' => 1.0E+5, + 'lbf' => 2.24808923655339E-01, + ), + 'dyn' => array( + 'N' => 1.0E-5, + 'dyn' => 1.0, + 'dy' => 1.0, + 'lbf' => 2.24808923655339E-06, + ), + 'dy' => array( + 'N' => 1.0E-5, + 'dyn' => 1.0, + 'dy' => 1.0, + 'lbf' => 2.24808923655339E-06, + ), + 'lbf' => array( + 'N' => 4.448222, + 'dyn' => 4.448222E+5, + 'dy' => 4.448222E+5, + 'lbf' => 1.0, + ), + ), + 'Energy' => array( + 'J' => array( + 'J' => 1.0, + 'e' => 9.99999519343231E+06, + 'c' => 2.39006249473467E-01, + 'cal' => 2.38846190642017E-01, + 'eV' => 6.24145700000000E+18, + 'ev' => 6.24145700000000E+18, + 'HPh' => 3.72506430801000E-07, + 'hh' => 3.72506430801000E-07, + 'Wh' => 2.77777916238711E-04, + 'wh' => 2.77777916238711E-04, + 'flb' => 2.37304222192651E+01, + 'BTU' => 9.47815067349015E-04, + 'btu' => 9.47815067349015E-04, + ), + 'e' => array( + 'J' => 1.00000048065700E-07, + 'e' => 1.0, + 'c' => 2.39006364353494E-08, + 'cal' => 2.38846305445111E-08, + 'eV' => 6.24146000000000E+11, + 'ev' => 6.24146000000000E+11, + 'HPh' => 3.72506609848824E-14, + 'hh' => 3.72506609848824E-14, + 'Wh' => 2.77778049754611E-11, + 'wh' => 2.77778049754611E-11, + 'flb' => 2.37304336254586E-06, + 'BTU' => 9.47815522922962E-11, + 'btu' => 9.47815522922962E-11, + ), + 'c' => array( + 'J' => 4.18399101363672E+00, + 'e' => 4.18398900257312E+07, + 'c' => 1.0, + 'cal' => 9.99330315287563E-01, + 'eV' => 2.61142000000000E+19, + 'ev' => 2.61142000000000E+19, + 'HPh' => 1.55856355899327E-06, + 'hh' => 1.55856355899327E-06, + 'Wh' => 1.16222030532950E-03, + 'wh' => 1.16222030532950E-03, + 'flb' => 9.92878733152102E+01, + 'BTU' => 3.96564972437776E-03, + 'btu' => 3.96564972437776E-03, + ), + 'cal' => array( + 'J' => 4.18679484613929E+00, + 'e' => 4.18679283372801E+07, + 'c' => 1.00067013349059E+00, + 'cal' => 1.0, + 'eV' => 2.61317000000000E+19, + 'ev' => 2.61317000000000E+19, + 'HPh' => 1.55960800463137E-06, + 'hh' => 1.55960800463137E-06, + 'Wh' => 1.16299914807955E-03, + 'wh' => 1.16299914807955E-03, + 'flb' => 9.93544094443283E+01, + 'BTU' => 3.96830723907002E-03, + 'btu' => 3.96830723907002E-03, + ), + 'eV' => array( + 'J' => 1.60219000146921E-19, + 'e' => 1.60218923136574E-12, + 'c' => 3.82933423195043E-20, + 'cal' => 3.82676978535648E-20, + 'eV' => 1.0, + 'ev' => 1.0, + 'HPh' => 5.96826078912344E-26, + 'hh' => 5.96826078912344E-26, + 'Wh' => 4.45053000026614E-23, + 'wh' => 4.45053000026614E-23, + 'flb' => 3.80206452103492E-18, + 'BTU' => 1.51857982414846E-22, + 'btu' => 1.51857982414846E-22, + ), + 'ev' => array( + 'J' => 1.60219000146921E-19, + 'e' => 1.60218923136574E-12, + 'c' => 3.82933423195043E-20, + 'cal' => 3.82676978535648E-20, + 'eV' => 1.0, + 'ev' => 1.0, + 'HPh' => 5.96826078912344E-26, + 'hh' => 5.96826078912344E-26, + 'Wh' => 4.45053000026614E-23, + 'wh' => 4.45053000026614E-23, + 'flb' => 3.80206452103492E-18, + 'BTU' => 1.51857982414846E-22, + 'btu' => 1.51857982414846E-22, + ), + 'HPh' => array( + 'J' => 2.68451741316170E+06, + 'e' => 2.68451612283024E+13, + 'c' => 6.41616438565991E+05, + 'cal' => 6.41186757845835E+05, + 'eV' => 1.67553000000000E+25, + 'ev' => 1.67553000000000E+25, + 'HPh' => 1.0, + 'hh' => 1.0, + 'Wh' => 7.45699653134593E+02, + 'wh' => 7.45699653134593E+02, + 'flb' => 6.37047316692964E+07, + 'BTU' => 2.54442605275546E+03, + 'btu' => 2.54442605275546E+03, + ), + 'hh' => array( + 'J' => 2.68451741316170E+06, + 'e' => 2.68451612283024E+13, + 'c' => 6.41616438565991E+05, + 'cal' => 6.41186757845835E+05, + 'eV' => 1.67553000000000E+25, + 'ev' => 1.67553000000000E+25, + 'HPh' => 1.0, + 'hh' => 1.0, + 'Wh' => 7.45699653134593E+02, + 'wh' => 7.45699653134593E+02, + 'flb' => 6.37047316692964E+07, + 'BTU' => 2.54442605275546E+03, + 'btu' => 2.54442605275546E+03, + ), + 'Wh' => array( + 'J' => 3.59999820554720E+03, + 'e' => 3.59999647518369E+10, + 'c' => 8.60422069219046E+02, + 'cal' => 8.59845857713046E+02, + 'eV' => 2.24692340000000E+22, + 'ev' => 2.24692340000000E+22, + 'HPh' => 1.34102248243839E-03, + 'hh' => 1.34102248243839E-03, + 'Wh' => 1.0, + 'wh' => 1.0, + 'flb' => 8.54294774062316E+04, + 'BTU' => 3.41213254164705E+00, + 'btu' => 3.41213254164705E+00, + ), + 'wh' => array( + 'J' => 3.59999820554720E+03, + 'e' => 3.59999647518369E+10, + 'c' => 8.60422069219046E+02, + 'cal' => 8.59845857713046E+02, + 'eV' => 2.24692340000000E+22, + 'ev' => 2.24692340000000E+22, + 'HPh' => 1.34102248243839E-03, + 'hh' => 1.34102248243839E-03, + 'Wh' => 1.0, + 'wh' => 1.0, + 'flb' => 8.54294774062316E+04, + 'BTU' => 3.41213254164705E+00, + 'btu' => 3.41213254164705E+00, + ), + 'flb' => array( + 'J' => 4.21400003236424E-02, + 'e' => 4.21399800687660E+05, + 'c' => 1.00717234301644E-02, + 'cal' => 1.00649785509554E-02, + 'eV' => 2.63015000000000E+17, + 'ev' => 2.63015000000000E+17, + 'HPh' => 1.56974211145130E-08, + 'hh' => 1.56974211145130E-08, + 'Wh' => 1.17055614802000E-05, + 'wh' => 1.17055614802000E-05, + 'flb' => 1.0, + 'BTU' => 3.99409272448406E-05, + 'btu' => 3.99409272448406E-05, + ), + 'BTU' => array( + 'J' => 1.05505813786749E+03, + 'e' => 1.05505763074665E+10, + 'c' => 2.52165488508168E+02, + 'cal' => 2.51996617135510E+02, + 'eV' => 6.58510000000000E+21, + 'ev' => 6.58510000000000E+21, + 'HPh' => 3.93015941224568E-04, + 'hh' => 3.93015941224568E-04, + 'Wh' => 2.93071851047526E-01, + 'wh' => 2.93071851047526E-01, + 'flb' => 2.50369750774671E+04, + 'BTU' => 1.0, + 'btu' => 1.0, + ), + 'btu' => array( + 'J' => 1.05505813786749E+03, + 'e' => 1.05505763074665E+10, + 'c' => 2.52165488508168E+02, + 'cal' => 2.51996617135510E+02, + 'eV' => 6.58510000000000E+21, + 'ev' => 6.58510000000000E+21, + 'HPh' => 3.93015941224568E-04, + 'hh' => 3.93015941224568E-04, + 'Wh' => 2.93071851047526E-01, + 'wh' => 2.93071851047526E-01, + 'flb' => 2.50369750774671E+04, + 'BTU' => 1.0, + 'btu' => 1.0, + ), + ), + 'Power' => array( + 'HP' => array( + 'HP' => 1.0, + 'h' => 1.0, + 'W' => 7.45701000000000E+02, + 'w' => 7.45701000000000E+02, + ), + 'h' => array( + 'HP' => 1.0, + 'h' => 1.0, + 'W' => 7.45701000000000E+02, + 'w' => 7.45701000000000E+02, + ), + 'W' => array( + 'HP' => 1.34102006031908E-03, + 'h' => 1.34102006031908E-03, + 'W' => 1.0, + 'w' => 1.0, + ), + 'w' => array( + 'HP' => 1.34102006031908E-03, + 'h' => 1.34102006031908E-03, + 'W' => 1.0, + 'w' => 1.0, + ), + ), + 'Magnetism' => array( + 'T' => array( + 'T' => 1.0, + 'ga' => 10000.0, + ), + 'ga' => array( + 'T' => 0.0001, + 'ga' => 1.0, + ), + ), + 'Liquid' => array( + 'tsp' => array( + 'tsp' => 1.0, + 'tbs' => 3.33333333333333E-01, + 'oz' => 1.66666666666667E-01, + 'cup' => 2.08333333333333E-02, + 'pt' => 1.04166666666667E-02, + 'us_pt' => 1.04166666666667E-02, + 'uk_pt' => 8.67558516821960E-03, + 'qt' => 5.20833333333333E-03, + 'gal' => 1.30208333333333E-03, + 'l' => 4.92999408400710E-03, + 'lt' => 4.92999408400710E-03, + ), + 'tbs' => array( + 'tsp' => 3.00000000000000E+00, + 'tbs' => 1.0, + 'oz' => 5.00000000000000E-01, + 'cup' => 6.25000000000000E-02, + 'pt' => 3.12500000000000E-02, + 'us_pt' => 3.12500000000000E-02, + 'uk_pt' => 2.60267555046588E-02, + 'qt' => 1.56250000000000E-02, + 'gal' => 3.90625000000000E-03, + 'l' => 1.47899822520213E-02, + 'lt' => 1.47899822520213E-02, + ), + 'oz' => array( + 'tsp' => 6.00000000000000E+00, + 'tbs' => 2.00000000000000E+00, + 'oz' => 1.0, + 'cup' => 1.25000000000000E-01, + 'pt' => 6.25000000000000E-02, + 'us_pt' => 6.25000000000000E-02, + 'uk_pt' => 5.20535110093176E-02, + 'qt' => 3.12500000000000E-02, + 'gal' => 7.81250000000000E-03, + 'l' => 2.95799645040426E-02, + 'lt' => 2.95799645040426E-02, + ), + 'cup' => array( + 'tsp' => 4.80000000000000E+01, + 'tbs' => 1.60000000000000E+01, + 'oz' => 8.00000000000000E+00, + 'cup' => 1.0, + 'pt' => 5.00000000000000E-01, + 'us_pt' => 5.00000000000000E-01, + 'uk_pt' => 4.16428088074541E-01, + 'qt' => 2.50000000000000E-01, + 'gal' => 6.25000000000000E-02, + 'l' => 2.36639716032341E-01, + 'lt' => 2.36639716032341E-01, + ), + 'pt' => array( + 'tsp' => 9.60000000000000E+01, + 'tbs' => 3.20000000000000E+01, + 'oz' => 1.60000000000000E+01, + 'cup' => 2.00000000000000E+00, + 'pt' => 1.0, + 'us_pt' => 1.0, + 'uk_pt' => 8.32856176149081E-01, + 'qt' => 5.00000000000000E-01, + 'gal' => 1.25000000000000E-01, + 'l' => 4.73279432064682E-01, + 'lt' => 4.73279432064682E-01, + ), + 'us_pt' => array( + 'tsp' => 9.60000000000000E+01, + 'tbs' => 3.20000000000000E+01, + 'oz' => 1.60000000000000E+01, + 'cup' => 2.00000000000000E+00, + 'pt' => 1.0, + 'us_pt' => 1.0, + 'uk_pt' => 8.32856176149081E-01, + 'qt' => 5.00000000000000E-01, + 'gal' => 1.25000000000000E-01, + 'l' => 4.73279432064682E-01, + 'lt' => 4.73279432064682E-01, + ), + 'uk_pt' => array( + 'tsp' => 1.15266000000000E+02, + 'tbs' => 3.84220000000000E+01, + 'oz' => 1.92110000000000E+01, + 'cup' => 2.40137500000000E+00, + 'pt' => 1.20068750000000E+00, + 'us_pt' => 1.20068750000000E+00, + 'uk_pt' => 1.0, + 'qt' => 6.00343750000000E-01, + 'gal' => 1.50085937500000E-01, + 'l' => 5.68260698087162E-01, + 'lt' => 5.68260698087162E-01, + ), + 'qt' => array( + 'tsp' => 1.92000000000000E+02, + 'tbs' => 6.40000000000000E+01, + 'oz' => 3.20000000000000E+01, + 'cup' => 4.00000000000000E+00, + 'pt' => 2.00000000000000E+00, + 'us_pt' => 2.00000000000000E+00, + 'uk_pt' => 1.66571235229816E+00, + 'qt' => 1.0, + 'gal' => 2.50000000000000E-01, + 'l' => 9.46558864129363E-01, + 'lt' => 9.46558864129363E-01, + ), + 'gal' => array( + 'tsp' => 7.68000000000000E+02, + 'tbs' => 2.56000000000000E+02, + 'oz' => 1.28000000000000E+02, + 'cup' => 1.60000000000000E+01, + 'pt' => 8.00000000000000E+00, + 'us_pt' => 8.00000000000000E+00, + 'uk_pt' => 6.66284940919265E+00, + 'qt' => 4.00000000000000E+00, + 'gal' => 1.0, + 'l' => 3.78623545651745E+00, + 'lt' => 3.78623545651745E+00, + ), + 'l' => array( + 'tsp' => 2.02840000000000E+02, + 'tbs' => 6.76133333333333E+01, + 'oz' => 3.38066666666667E+01, + 'cup' => 4.22583333333333E+00, + 'pt' => 2.11291666666667E+00, + 'us_pt' => 2.11291666666667E+00, + 'uk_pt' => 1.75975569552166E+00, + 'qt' => 1.05645833333333E+00, + 'gal' => 2.64114583333333E-01, + 'l' => 1.0, + 'lt' => 1.0, + ), + 'lt' => array( + 'tsp' => 2.02840000000000E+02, + 'tbs' => 6.76133333333333E+01, + 'oz' => 3.38066666666667E+01, + 'cup' => 4.22583333333333E+00, + 'pt' => 2.11291666666667E+00, + 'us_pt' => 2.11291666666667E+00, + 'uk_pt' => 1.75975569552166E+00, + 'qt' => 1.05645833333333E+00, + 'gal' => 2.64114583333333E-01, + 'l' => 1.0, + 'lt' => 1.0, + ), + ), + ); + + + /** + * _parseComplex + * + * Parses a complex number into its real and imaginary parts, and an I or J suffix + * + * @param string $complexNumber The complex number + * @return string[] Indexed on "real", "imaginary" and "suffix" + */ + public static function _parseComplex($complexNumber) + { + $workString = (string) $complexNumber; + + $realNumber = $imaginary = 0; + // Extract the suffix, if there is one + $suffix = substr($workString, -1); + if (!is_numeric($suffix)) { + $workString = substr($workString, 0, -1); + } else { + $suffix = ''; + } + + // Split the input into its Real and Imaginary components + $leadingSign = 0; + if (strlen($workString) > 0) { + $leadingSign = (($workString{0} == '+') || ($workString{0} == '-')) ? 1 : 0; + } + $power = ''; + $realNumber = strtok($workString, '+-'); + if (strtoupper(substr($realNumber, -1)) == 'E') { + $power = strtok('+-'); + ++$leadingSign; + } + + $realNumber = substr($workString, 0, strlen($realNumber)+strlen($power)+$leadingSign); + + if ($suffix != '') { + $imaginary = substr($workString, strlen($realNumber)); + + if (($imaginary == '') && (($realNumber == '') || ($realNumber == '+') || ($realNumber == '-'))) { + $imaginary = $realNumber.'1'; + $realNumber = '0'; + } elseif ($imaginary == '') { + $imaginary = $realNumber; + $realNumber = '0'; + } elseif (($imaginary == '+') || ($imaginary == '-')) { + $imaginary .= '1'; + } + } + + return array( + 'real' => $realNumber, + 'imaginary' => $imaginary, + 'suffix' => $suffix + ); + } + + + /** + * Cleans the leading characters in a complex number string + * + * @param string $complexNumber The complex number to clean + * @return string The "cleaned" complex number + */ + private static function _cleanComplex($complexNumber) + { + if ($complexNumber{0} == '+') { + $complexNumber = substr($complexNumber, 1); + } + if ($complexNumber{0} == '0') { + $complexNumber = substr($complexNumber, 1); + } + if ($complexNumber{0} == '.') { + $complexNumber = '0'.$complexNumber; + } + if ($complexNumber{0} == '+') { + $complexNumber = substr($complexNumber, 1); + } + return $complexNumber; + } + + /** + * Formats a number base string value with leading zeroes + * + * @param string $xVal The "number" to pad + * @param integer $places The length that we want to pad this value + * @return string The padded "number" + */ + private static function _nbrConversionFormat($xVal, $places) + { + if (!is_null($places)) { + if (strlen($xVal) <= $places) { + return substr(str_pad($xVal, $places, '0', STR_PAD_LEFT), -10); + } else { + return PHPExcel_Calculation_Functions::NaN(); + } + } + + return substr($xVal, -10); + } + + /** + * BESSELI + * + * Returns the modified Bessel function In(x), which is equivalent to the Bessel function evaluated + * for purely imaginary arguments + * + * Excel Function: + * BESSELI(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELI returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. + * If ord is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELI returns the #VALUE! error value. + * If $ord < 0, BESSELI returns the #NUM! error value. + * @return float + * + */ + public static function BESSELI($x, $ord) + { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + $ord = floor($ord); + if ($ord < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (abs($x) <= 30) { + $fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord); + $ordK = 1; + $fSqrX = ($x * $x) / 4; + do { + $fTerm *= $fSqrX; + $fTerm /= ($ordK * ($ordK + $ord)); + $fResult += $fTerm; + } while ((abs($fTerm) > 1e-12) && (++$ordK < 100)); + } else { + $f_2_PI = 2 * M_PI; + + $fXAbs = abs($x); + $fResult = exp($fXAbs) / sqrt($f_2_PI * $fXAbs); + if (($ord & 1) && ($x < 0)) { + $fResult = -$fResult; + } + } + return (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult; + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + /** + * BESSELJ + * + * Returns the Bessel function + * + * Excel Function: + * BESSELJ(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELJ returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELJ returns the #VALUE! error value. + * If $ord < 0, BESSELJ returns the #NUM! error value. + * @return float + * + */ + public static function BESSELJ($x, $ord) + { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + $ord = floor($ord); + if ($ord < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $fResult = 0; + if (abs($x) <= 30) { + $fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord); + $ordK = 1; + $fSqrX = ($x * $x) / -4; + do { + $fTerm *= $fSqrX; + $fTerm /= ($ordK * ($ordK + $ord)); + $fResult += $fTerm; + } while ((abs($fTerm) > 1e-12) && (++$ordK < 100)); + } else { + $f_PI_DIV_2 = M_PI / 2; + $f_PI_DIV_4 = M_PI / 4; + + $fXAbs = abs($x); + $fResult = sqrt(M_2DIVPI / $fXAbs) * cos($fXAbs - $ord * $f_PI_DIV_2 - $f_PI_DIV_4); + if (($ord & 1) && ($x < 0)) { + $fResult = -$fResult; + } + } + return (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult; + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + private static function _Besselk0($fNum) + { + if ($fNum <= 2) { + $fNum2 = $fNum * 0.5; + $y = ($fNum2 * $fNum2); + $fRet = -log($fNum2) * self::BESSELI($fNum, 0) + + (-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y * + (0.10750e-3 + $y * 0.74e-5)))))); + } else { + $y = 2 / $fNum; + $fRet = exp(-$fNum) / sqrt($fNum) * + (1.25331414 + $y * (-0.7832358e-1 + $y * (0.2189568e-1 + $y * (-0.1062446e-1 + $y * + (0.587872e-2 + $y * (-0.251540e-2 + $y * 0.53208e-3)))))); + } + return $fRet; + } + + + private static function _Besselk1($fNum) + { + if ($fNum <= 2) { + $fNum2 = $fNum * 0.5; + $y = ($fNum2 * $fNum2); + $fRet = log($fNum2) * self::BESSELI($fNum, 1) + + (1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y * + (-0.110404e-2 + $y * (-0.4686e-4))))))) / $fNum; + } else { + $y = 2 / $fNum; + $fRet = exp(-$fNum) / sqrt($fNum) * + (1.25331414 + $y * (0.23498619 + $y * (-0.3655620e-1 + $y * (0.1504268e-1 + $y * (-0.780353e-2 + $y * + (0.325614e-2 + $y * (-0.68245e-3))))))); + } + return $fRet; + } + + + /** + * BESSELK + * + * Returns the modified Bessel function Kn(x), which is equivalent to the Bessel functions evaluated + * for purely imaginary arguments. + * + * Excel Function: + * BESSELK(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELK returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. + * If $ord < 0, BESSELK returns the #NUM! error value. + * @return float + * + */ + public static function BESSELK($x, $ord) + { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + if (($ord < 0) || ($x == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + switch(floor($ord)) { + case 0: + return self::_Besselk0($x); + case 1: + return self::_Besselk1($x); + default: + $fTox = 2 / $x; + $fBkm = self::_Besselk0($x); + $fBk = self::_Besselk1($x); + for ($n = 1; $n < $ord; ++$n) { + $fBkp = $fBkm + $n * $fTox * $fBk; + $fBkm = $fBk; + $fBk = $fBkp; + } + } + return (is_nan($fBk)) ? PHPExcel_Calculation_Functions::NaN() : $fBk; + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + private static function _Bessely0($fNum) + { + if ($fNum < 8.0) { + $y = ($fNum * $fNum); + $f1 = -2957821389.0 + $y * (7062834065.0 + $y * (-512359803.6 + $y * (10879881.29 + $y * (-86327.92757 + $y * 228.4622733)))); + $f2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y * (47447.26470 + $y * (226.1030244 + $y)))); + $fRet = $f1 / $f2 + 0.636619772 * self::BESSELJ($fNum, 0) * log($fNum); + } else { + $z = 8.0 / $fNum; + $y = ($z * $z); + $xx = $fNum - 0.785398164; + $f1 = 1 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6))); + $f2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 + $y * (-0.934945152e-7)))); + $fRet = sqrt(0.636619772 / $fNum) * (sin($xx) * $f1 + $z * cos($xx) * $f2); + } + return $fRet; + } + + + private static function _Bessely1($fNum) + { + if ($fNum < 8.0) { + $y = ($fNum * $fNum); + $f1 = $fNum * (-0.4900604943e13 + $y * (0.1275274390e13 + $y * (-0.5153438139e11 + $y * (0.7349264551e9 + $y * + (-0.4237922726e7 + $y * 0.8511937935e4))))); + $f2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y * + (0.1020426050e6 + $y * (0.3549632885e3 + $y))))); + $fRet = $f1 / $f2 + 0.636619772 * ( self::BESSELJ($fNum, 1) * log($fNum) - 1 / $fNum); + } else { + $fRet = sqrt(0.636619772 / $fNum) * sin($fNum - 2.356194491); + } + return $fRet; + } + + + /** + * BESSELY + * + * Returns the Bessel function, which is also called the Weber function or the Neumann function. + * + * Excel Function: + * BESSELY(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELK returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. + * If $ord < 0, BESSELK returns the #NUM! error value. + * + * @return float + */ + public static function BESSELY($x, $ord) + { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + if (($ord < 0) || ($x == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + switch(floor($ord)) { + case 0: + return self::_Bessely0($x); + case 1: + return self::_Bessely1($x); + default: + $fTox = 2 / $x; + $fBym = self::_Bessely0($x); + $fBy = self::_Bessely1($x); + for ($n = 1; $n < $ord; ++$n) { + $fByp = $n * $fTox * $fBy - $fBym; + $fBym = $fBy; + $fBy = $fByp; + } + } + return (is_nan($fBy)) ? PHPExcel_Calculation_Functions::NaN() : $fBy; + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + /** + * BINTODEC + * + * Return a binary value as decimal. + * + * Excel Function: + * BIN2DEC(x) + * + * @access public + * @category Engineering Functions + * @param string $x The binary number (as a string) that you want to convert. The number + * cannot contain more than 10 characters (10 bits). The most significant + * bit of number is the sign bit. The remaining 9 bits are magnitude bits. + * Negative numbers are represented using two's-complement notation. + * If number is not a valid binary number, or if number contains more than + * 10 characters (10 bits), BIN2DEC returns the #NUM! error value. + * @return string + */ + public static function BINTODEC($x) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $x = floor($x); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[01]/', $x, $out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (strlen($x) > 10) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (strlen($x) == 10) { + // Two's Complement + $x = substr($x, -9); + return '-'.(512-bindec($x)); + } + return bindec($x); + } + + + /** + * BINTOHEX + * + * Return a binary value as hex. + * + * Excel Function: + * BIN2HEX(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The binary number (as a string) that you want to convert. The number + * cannot contain more than 10 characters (10 bits). The most significant + * bit of number is the sign bit. The remaining 9 bits are magnitude bits. + * Negative numbers are represented using two's-complement notation. + * If number is not a valid binary number, or if number contains more than + * 10 characters (10 bits), BIN2HEX returns the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, BIN2HEX uses the + * minimum number of characters necessary. Places is useful for padding the + * return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, BIN2HEX returns the #VALUE! error value. + * If places is negative, BIN2HEX returns the #NUM! error value. + * @return string + */ + public static function BINTOHEX($x, $places = null) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $x = floor($x); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[01]/', $x, $out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (strlen($x) > 10) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (strlen($x) == 10) { + // Two's Complement + return str_repeat('F', 8).substr(strtoupper(dechex(bindec(substr($x, -9)))), -2); + } + $hexVal = (string) strtoupper(dechex(bindec($x))); + + return self::_nbrConversionFormat($hexVal, $places); + } + + + /** + * BINTOOCT + * + * Return a binary value as octal. + * + * Excel Function: + * BIN2OCT(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The binary number (as a string) that you want to convert. The number + * cannot contain more than 10 characters (10 bits). The most significant + * bit of number is the sign bit. The remaining 9 bits are magnitude bits. + * Negative numbers are represented using two's-complement notation. + * If number is not a valid binary number, or if number contains more than + * 10 characters (10 bits), BIN2OCT returns the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, BIN2OCT uses the + * minimum number of characters necessary. Places is useful for padding the + * return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, BIN2OCT returns the #VALUE! error value. + * If places is negative, BIN2OCT returns the #NUM! error value. + * @return string + */ + public static function BINTOOCT($x, $places = null) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $x = floor($x); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[01]/', $x, $out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (strlen($x) > 10) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (strlen($x) == 10) { + // Two's Complement + return str_repeat('7', 7).substr(strtoupper(decoct(bindec(substr($x, -9)))), -3); + } + $octVal = (string) decoct(bindec($x)); + + return self::_nbrConversionFormat($octVal, $places); + } + + + /** + * DECTOBIN + * + * Return a decimal value as binary. + * + * Excel Function: + * DEC2BIN(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The decimal integer you want to convert. If number is negative, + * valid place values are ignored and DEC2BIN returns a 10-character + * (10-bit) binary number in which the most significant bit is the sign + * bit. The remaining 9 bits are magnitude bits. Negative numbers are + * represented using two's-complement notation. + * If number < -512 or if number > 511, DEC2BIN returns the #NUM! error + * value. + * If number is nonnumeric, DEC2BIN returns the #VALUE! error value. + * If DEC2BIN requires more than places characters, it returns the #NUM! + * error value. + * @param integer $places The number of characters to use. If places is omitted, DEC2BIN uses + * the minimum number of characters necessary. Places is useful for + * padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, DEC2BIN returns the #VALUE! error value. + * If places is zero or negative, DEC2BIN returns the #NUM! error value. + * @return string + */ + public static function DECTOBIN($x, $places = null) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[-0123456789.]/', $x, $out)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) floor($x); + $r = decbin($x); + if (strlen($r) == 32) { + // Two's Complement + $r = substr($r, -10); + } elseif (strlen($r) > 11) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return self::_nbrConversionFormat($r, $places); + } + + + /** + * DECTOHEX + * + * Return a decimal value as hex. + * + * Excel Function: + * DEC2HEX(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The decimal integer you want to convert. If number is negative, + * places is ignored and DEC2HEX returns a 10-character (40-bit) + * hexadecimal number in which the most significant bit is the sign + * bit. The remaining 39 bits are magnitude bits. Negative numbers + * are represented using two's-complement notation. + * If number < -549,755,813,888 or if number > 549,755,813,887, + * DEC2HEX returns the #NUM! error value. + * If number is nonnumeric, DEC2HEX returns the #VALUE! error value. + * If DEC2HEX requires more than places characters, it returns the + * #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, DEC2HEX uses + * the minimum number of characters necessary. Places is useful for + * padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, DEC2HEX returns the #VALUE! error value. + * If places is zero or negative, DEC2HEX returns the #NUM! error value. + * @return string + */ + public static function DECTOHEX($x, $places = null) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[-0123456789.]/', $x, $out)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) floor($x); + $r = strtoupper(dechex($x)); + if (strlen($r) == 8) { + // Two's Complement + $r = 'FF'.$r; + } + + return self::_nbrConversionFormat($r, $places); + } + + + /** + * DECTOOCT + * + * Return an decimal value as octal. + * + * Excel Function: + * DEC2OCT(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The decimal integer you want to convert. If number is negative, + * places is ignored and DEC2OCT returns a 10-character (30-bit) + * octal number in which the most significant bit is the sign bit. + * The remaining 29 bits are magnitude bits. Negative numbers are + * represented using two's-complement notation. + * If number < -536,870,912 or if number > 536,870,911, DEC2OCT + * returns the #NUM! error value. + * If number is nonnumeric, DEC2OCT returns the #VALUE! error value. + * If DEC2OCT requires more than places characters, it returns the + * #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, DEC2OCT uses + * the minimum number of characters necessary. Places is useful for + * padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, DEC2OCT returns the #VALUE! error value. + * If places is zero or negative, DEC2OCT returns the #NUM! error value. + * @return string + */ + public static function DECTOOCT($x, $places = null) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[-0123456789.]/', $x, $out)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) floor($x); + $r = decoct($x); + if (strlen($r) == 11) { + // Two's Complement + $r = substr($r, -10); + } + + return self::_nbrConversionFormat($r, $places); + } + + + /** + * HEXTOBIN + * + * Return a hex value as binary. + * + * Excel Function: + * HEX2BIN(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x the hexadecimal number you want to convert. Number cannot + * contain more than 10 characters. The most significant bit of + * number is the sign bit (40th bit from the right). The remaining + * 9 bits are magnitude bits. Negative numbers are represented + * using two's-complement notation. + * If number is negative, HEX2BIN ignores places and returns a + * 10-character binary number. + * If number is negative, it cannot be less than FFFFFFFE00, and + * if number is positive, it cannot be greater than 1FF. + * If number is not a valid hexadecimal number, HEX2BIN returns + * the #NUM! error value. + * If HEX2BIN requires more than places characters, it returns + * the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, + * HEX2BIN uses the minimum number of characters necessary. Places + * is useful for padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, HEX2BIN returns the #VALUE! error value. + * If places is negative, HEX2BIN returns the #NUM! error value. + * @return string + */ + public static function HEXTOBIN($x, $places = null) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $binVal = decbin(hexdec($x)); + + return substr(self::_nbrConversionFormat($binVal, $places), -10); + } + + + /** + * HEXTODEC + * + * Return a hex value as decimal. + * + * Excel Function: + * HEX2DEC(x) + * + * @access public + * @category Engineering Functions + * @param string $x The hexadecimal number you want to convert. This number cannot + * contain more than 10 characters (40 bits). The most significant + * bit of number is the sign bit. The remaining 39 bits are magnitude + * bits. Negative numbers are represented using two's-complement + * notation. + * If number is not a valid hexadecimal number, HEX2DEC returns the + * #NUM! error value. + * @return string + */ + public static function HEXTODEC($x) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return hexdec($x); + } + + + /** + * HEXTOOCT + * + * Return a hex value as octal. + * + * Excel Function: + * HEX2OCT(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The hexadecimal number you want to convert. Number cannot + * contain more than 10 characters. The most significant bit of + * number is the sign bit. The remaining 39 bits are magnitude + * bits. Negative numbers are represented using two's-complement + * notation. + * If number is negative, HEX2OCT ignores places and returns a + * 10-character octal number. + * If number is negative, it cannot be less than FFE0000000, and + * if number is positive, it cannot be greater than 1FFFFFFF. + * If number is not a valid hexadecimal number, HEX2OCT returns + * the #NUM! error value. + * If HEX2OCT requires more than places characters, it returns + * the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, HEX2OCT + * uses the minimum number of characters necessary. Places is + * useful for padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, HEX2OCT returns the #VALUE! error + * value. + * If places is negative, HEX2OCT returns the #NUM! error value. + * @return string + */ + public static function HEXTOOCT($x, $places = null) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $octVal = decoct(hexdec($x)); + + return self::_nbrConversionFormat($octVal, $places); + } // function HEXTOOCT() + + + /** + * OCTTOBIN + * + * Return an octal value as binary. + * + * Excel Function: + * OCT2BIN(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The octal number you want to convert. Number may not + * contain more than 10 characters. The most significant + * bit of number is the sign bit. The remaining 29 bits + * are magnitude bits. Negative numbers are represented + * using two's-complement notation. + * If number is negative, OCT2BIN ignores places and returns + * a 10-character binary number. + * If number is negative, it cannot be less than 7777777000, + * and if number is positive, it cannot be greater than 777. + * If number is not a valid octal number, OCT2BIN returns + * the #NUM! error value. + * If OCT2BIN requires more than places characters, it + * returns the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, + * OCT2BIN uses the minimum number of characters necessary. + * Places is useful for padding the return value with + * leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, OCT2BIN returns the #VALUE! + * error value. + * If places is negative, OCT2BIN returns the #NUM! error + * value. + * @return string + */ + public static function OCTTOBIN($x, $places = null) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (preg_match_all('/[01234567]/', $x, $out) != strlen($x)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $r = decbin(octdec($x)); + + return self::_nbrConversionFormat($r, $places); + } + + + /** + * OCTTODEC + * + * Return an octal value as decimal. + * + * Excel Function: + * OCT2DEC(x) + * + * @access public + * @category Engineering Functions + * @param string $x The octal number you want to convert. Number may not contain + * more than 10 octal characters (30 bits). The most significant + * bit of number is the sign bit. The remaining 29 bits are + * magnitude bits. Negative numbers are represented using + * two's-complement notation. + * If number is not a valid octal number, OCT2DEC returns the + * #NUM! error value. + * @return string + */ + public static function OCTTODEC($x) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (preg_match_all('/[01234567]/', $x, $out) != strlen($x)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return octdec($x); + } + + + /** + * OCTTOHEX + * + * Return an octal value as hex. + * + * Excel Function: + * OCT2HEX(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The octal number you want to convert. Number may not contain + * more than 10 octal characters (30 bits). The most significant + * bit of number is the sign bit. The remaining 29 bits are + * magnitude bits. Negative numbers are represented using + * two's-complement notation. + * If number is negative, OCT2HEX ignores places and returns a + * 10-character hexadecimal number. + * If number is not a valid octal number, OCT2HEX returns the + * #NUM! error value. + * If OCT2HEX requires more than places characters, it returns + * the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, OCT2HEX + * uses the minimum number of characters necessary. Places is useful + * for padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, OCT2HEX returns the #VALUE! error value. + * If places is negative, OCT2HEX returns the #NUM! error value. + * @return string + */ + public static function OCTTOHEX($x, $places = null) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (preg_match_all('/[01234567]/', $x, $out) != strlen($x)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $hexVal = strtoupper(dechex(octdec($x))); + + return self::_nbrConversionFormat($hexVal, $places); + } + + + /** + * COMPLEX + * + * Converts real and imaginary coefficients into a complex number of the form x + yi or x + yj. + * + * Excel Function: + * COMPLEX(realNumber,imaginary[,places]) + * + * @access public + * @category Engineering Functions + * @param float $realNumber The real coefficient of the complex number. + * @param float $imaginary The imaginary coefficient of the complex number. + * @param string $suffix The suffix for the imaginary component of the complex number. + * If omitted, the suffix is assumed to be "i". + * @return string + */ + public static function COMPLEX($realNumber = 0.0, $imaginary = 0.0, $suffix = 'i') + { + $realNumber = (is_null($realNumber)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($realNumber); + $imaginary = (is_null($imaginary)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($imaginary); + $suffix = (is_null($suffix)) ? 'i' : PHPExcel_Calculation_Functions::flattenSingleValue($suffix); + + if (((is_numeric($realNumber)) && (is_numeric($imaginary))) && + (($suffix == 'i') || ($suffix == 'j') || ($suffix == ''))) { + $realNumber = (float) $realNumber; + $imaginary = (float) $imaginary; + + if ($suffix == '') { + $suffix = 'i'; + } + if ($realNumber == 0.0) { + if ($imaginary == 0.0) { + return (string) '0'; + } elseif ($imaginary == 1.0) { + return (string) $suffix; + } elseif ($imaginary == -1.0) { + return (string) '-'.$suffix; + } + return (string) $imaginary.$suffix; + } elseif ($imaginary == 0.0) { + return (string) $realNumber; + } elseif ($imaginary == 1.0) { + return (string) $realNumber.'+'.$suffix; + } elseif ($imaginary == -1.0) { + return (string) $realNumber.'-'.$suffix; + } + if ($imaginary > 0) { + $imaginary = (string) '+'.$imaginary; + } + return (string) $realNumber.$imaginary.$suffix; + } + + return PHPExcel_Calculation_Functions::VALUE(); + } + + + /** + * IMAGINARY + * + * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMAGINARY(complexNumber) + * + * @access public + * @category Engineering Functions + * @param string $complexNumber The complex number for which you want the imaginary + * coefficient. + * @return float + */ + public static function IMAGINARY($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + return $parsedComplex['imaginary']; + } + + + /** + * IMREAL + * + * Returns the real coefficient of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMREAL(complexNumber) + * + * @access public + * @category Engineering Functions + * @param string $complexNumber The complex number for which you want the real coefficient. + * @return float + */ + public static function IMREAL($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + return $parsedComplex['real']; + } + + + /** + * IMABS + * + * Returns the absolute value (modulus) of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMABS(complexNumber) + * + * @param string $complexNumber The complex number for which you want the absolute value. + * @return float + */ + public static function IMABS($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + return sqrt( + ($parsedComplex['real'] * $parsedComplex['real']) + + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']) + ); + } + + + /** + * IMARGUMENT + * + * Returns the argument theta of a complex number, i.e. the angle in radians from the real + * axis to the representation of the number in polar coordinates. + * + * Excel Function: + * IMARGUMENT(complexNumber) + * + * @param string $complexNumber The complex number for which you want the argument theta. + * @return float + */ + public static function IMARGUMENT($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['real'] == 0.0) { + if ($parsedComplex['imaginary'] == 0.0) { + return 0.0; + } elseif ($parsedComplex['imaginary'] < 0.0) { + return M_PI / -2; + } else { + return M_PI / 2; + } + } elseif ($parsedComplex['real'] > 0.0) { + return atan($parsedComplex['imaginary'] / $parsedComplex['real']); + } elseif ($parsedComplex['imaginary'] < 0.0) { + return 0 - (M_PI - atan(abs($parsedComplex['imaginary']) / abs($parsedComplex['real']))); + } else { + return M_PI - atan($parsedComplex['imaginary'] / abs($parsedComplex['real'])); + } + } + + + /** + * IMCONJUGATE + * + * Returns the complex conjugate of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMCONJUGATE(complexNumber) + * + * @param string $complexNumber The complex number for which you want the conjugate. + * @return string + */ + public static function IMCONJUGATE($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['imaginary'] == 0.0) { + return $parsedComplex['real']; + } else { + return self::_cleanComplex( + self::COMPLEX( + $parsedComplex['real'], + 0 - $parsedComplex['imaginary'], + $parsedComplex['suffix'] + ) + ); + } + } + + + /** + * IMCOS + * + * Returns the cosine of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMCOS(complexNumber) + * + * @param string $complexNumber The complex number for which you want the cosine. + * @return string|float + */ + public static function IMCOS($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['imaginary'] == 0.0) { + return cos($parsedComplex['real']); + } else { + return self::IMCONJUGATE( + self::COMPLEX( + cos($parsedComplex['real']) * cosh($parsedComplex['imaginary']), + sin($parsedComplex['real']) * sinh($parsedComplex['imaginary']), + $parsedComplex['suffix'] + ) + ); + } + } + + + /** + * IMSIN + * + * Returns the sine of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMSIN(complexNumber) + * + * @param string $complexNumber The complex number for which you want the sine. + * @return string|float + */ + public static function IMSIN($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['imaginary'] == 0.0) { + return sin($parsedComplex['real']); + } else { + return self::COMPLEX( + sin($parsedComplex['real']) * cosh($parsedComplex['imaginary']), + cos($parsedComplex['real']) * sinh($parsedComplex['imaginary']), + $parsedComplex['suffix'] + ); + } + } + + + /** + * IMSQRT + * + * Returns the square root of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMSQRT(complexNumber) + * + * @param string $complexNumber The complex number for which you want the square root. + * @return string + */ + public static function IMSQRT($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + $theta = self::IMARGUMENT($complexNumber); + $d1 = cos($theta / 2); + $d2 = sin($theta / 2); + $r = sqrt(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']))); + + if ($parsedComplex['suffix'] == '') { + return self::COMPLEX($d1 * $r, $d2 * $r); + } else { + return self::COMPLEX($d1 * $r, $d2 * $r, $parsedComplex['suffix']); + } + } + + + /** + * IMLN + * + * Returns the natural logarithm of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMLN(complexNumber) + * + * @param string $complexNumber The complex number for which you want the natural logarithm. + * @return string + */ + public static function IMLN($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $logR = log(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']))); + $t = self::IMARGUMENT($complexNumber); + + if ($parsedComplex['suffix'] == '') { + return self::COMPLEX($logR, $t); + } else { + return self::COMPLEX($logR, $t, $parsedComplex['suffix']); + } + } + + + /** + * IMLOG10 + * + * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMLOG10(complexNumber) + * + * @param string $complexNumber The complex number for which you want the common logarithm. + * @return string + */ + public static function IMLOG10($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return log10($parsedComplex['real']); + } + + return self::IMPRODUCT(log10(EULER), self::IMLN($complexNumber)); + } + + + /** + * IMLOG2 + * + * Returns the base-2 logarithm of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMLOG2(complexNumber) + * + * @param string $complexNumber The complex number for which you want the base-2 logarithm. + * @return string + */ + public static function IMLOG2($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return log($parsedComplex['real'], 2); + } + + return self::IMPRODUCT(log(EULER, 2), self::IMLN($complexNumber)); + } + + + /** + * IMEXP + * + * Returns the exponential of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMEXP(complexNumber) + * + * @param string $complexNumber The complex number for which you want the exponential. + * @return string + */ + public static function IMEXP($complexNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return '1'; + } + + $e = exp($parsedComplex['real']); + $eX = $e * cos($parsedComplex['imaginary']); + $eY = $e * sin($parsedComplex['imaginary']); + + if ($parsedComplex['suffix'] == '') { + return self::COMPLEX($eX, $eY); + } else { + return self::COMPLEX($eX, $eY, $parsedComplex['suffix']); + } + } + + + /** + * IMPOWER + * + * Returns a complex number in x + yi or x + yj text format raised to a power. + * + * Excel Function: + * IMPOWER(complexNumber,realNumber) + * + * @param string $complexNumber The complex number you want to raise to a power. + * @param float $realNumber The power to which you want to raise the complex number. + * @return string + */ + public static function IMPOWER($complexNumber, $realNumber) + { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + $realNumber = PHPExcel_Calculation_Functions::flattenSingleValue($realNumber); + + if (!is_numeric($realNumber)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $parsedComplex = self::_parseComplex($complexNumber); + + $r = sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])); + $rPower = pow($r, $realNumber); + $theta = self::IMARGUMENT($complexNumber) * $realNumber; + if ($theta == 0) { + return 1; + } elseif ($parsedComplex['imaginary'] == 0.0) { + return self::COMPLEX($rPower * cos($theta), $rPower * sin($theta), $parsedComplex['suffix']); + } else { + return self::COMPLEX($rPower * cos($theta), $rPower * sin($theta), $parsedComplex['suffix']); + } + } + + + /** + * IMDIV + * + * Returns the quotient of two complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMDIV(complexDividend,complexDivisor) + * + * @param string $complexDividend The complex numerator or dividend. + * @param string $complexDivisor The complex denominator or divisor. + * @return string + */ + public static function IMDIV($complexDividend, $complexDivisor) + { + $complexDividend = PHPExcel_Calculation_Functions::flattenSingleValue($complexDividend); + $complexDivisor = PHPExcel_Calculation_Functions::flattenSingleValue($complexDivisor); + + $parsedComplexDividend = self::_parseComplex($complexDividend); + $parsedComplexDivisor = self::_parseComplex($complexDivisor); + + if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] != '') && + ($parsedComplexDividend['suffix'] != $parsedComplexDivisor['suffix'])) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] == '')) { + $parsedComplexDivisor['suffix'] = $parsedComplexDividend['suffix']; + } + + $d1 = ($parsedComplexDividend['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['imaginary']); + $d2 = ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['real']) - ($parsedComplexDividend['real'] * $parsedComplexDivisor['imaginary']); + $d3 = ($parsedComplexDivisor['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDivisor['imaginary'] * $parsedComplexDivisor['imaginary']); + + $r = $d1 / $d3; + $i = $d2 / $d3; + + if ($i > 0.0) { + return self::_cleanComplex($r.'+'.$i.$parsedComplexDivisor['suffix']); + } elseif ($i < 0.0) { + return self::_cleanComplex($r.$i.$parsedComplexDivisor['suffix']); + } else { + return $r; + } + } + + + /** + * IMSUB + * + * Returns the difference of two complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMSUB(complexNumber1,complexNumber2) + * + * @param string $complexNumber1 The complex number from which to subtract complexNumber2. + * @param string $complexNumber2 The complex number to subtract from complexNumber1. + * @return string + */ + public static function IMSUB($complexNumber1, $complexNumber2) + { + $complexNumber1 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber1); + $complexNumber2 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber2); + + $parsedComplex1 = self::_parseComplex($complexNumber1); + $parsedComplex2 = self::_parseComplex($complexNumber2); + + if ((($parsedComplex1['suffix'] != '') && ($parsedComplex2['suffix'] != '')) && + ($parsedComplex1['suffix'] != $parsedComplex2['suffix'])) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (($parsedComplex1['suffix'] == '') && ($parsedComplex2['suffix'] != '')) { + $parsedComplex1['suffix'] = $parsedComplex2['suffix']; + } + + $d1 = $parsedComplex1['real'] - $parsedComplex2['real']; + $d2 = $parsedComplex1['imaginary'] - $parsedComplex2['imaginary']; + + return self::COMPLEX($d1,$d2,$parsedComplex1['suffix']); + } + + + /** + * IMSUM + * + * Returns the sum of two or more complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMSUM(complexNumber[,complexNumber[,...]]) + * + * @param string $complexNumber,... Series of complex numbers to add + * @return string + */ + public static function IMSUM() + { + // Return value + $returnValue = self::_parseComplex('0'); + $activeSuffix = ''; + + // Loop through the arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + $parsedComplex = self::_parseComplex($arg); + + if ($activeSuffix == '') { + $activeSuffix = $parsedComplex['suffix']; + } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $returnValue['real'] += $parsedComplex['real']; + $returnValue['imaginary'] += $parsedComplex['imaginary']; + } + + if ($returnValue['imaginary'] == 0.0) { + $activeSuffix = ''; + } + return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix); + } + + + /** + * IMPRODUCT + * + * Returns the product of two or more complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMPRODUCT(complexNumber[,complexNumber[,...]]) + * + * @param string $complexNumber,... Series of complex numbers to multiply + * @return string + */ + public static function IMPRODUCT() + { + // Return value + $returnValue = self::_parseComplex('1'); + $activeSuffix = ''; + + // Loop through the arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + $parsedComplex = self::_parseComplex($arg); + + $workValue = $returnValue; + if (($parsedComplex['suffix'] != '') && ($activeSuffix == '')) { + $activeSuffix = $parsedComplex['suffix']; + } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) { + return PHPExcel_Calculation_Functions::NaN(); + } + $returnValue['real'] = ($workValue['real'] * $parsedComplex['real']) - ($workValue['imaginary'] * $parsedComplex['imaginary']); + $returnValue['imaginary'] = ($workValue['real'] * $parsedComplex['imaginary']) + ($workValue['imaginary'] * $parsedComplex['real']); + } + + if ($returnValue['imaginary'] == 0.0) { + $activeSuffix = ''; + } + return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix); + } + + + /** + * DELTA + * + * Tests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise. + * Use this function to filter a set of values. For example, by summing several DELTA + * functions you calculate the count of equal pairs. This function is also known as the + * Kronecker Delta function. + * + * Excel Function: + * DELTA(a[,b]) + * + * @param float $a The first number. + * @param float $b The second number. If omitted, b is assumed to be zero. + * @return int + */ + public static function DELTA($a, $b = 0) + { + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + + return (int) ($a == $b); + } + + + /** + * GESTEP + * + * Excel Function: + * GESTEP(number[,step]) + * + * Returns 1 if number >= step; returns 0 (zero) otherwise + * Use this function to filter a set of values. For example, by summing several GESTEP + * functions you calculate the count of values that exceed a threshold. + * + * @param float $number The value to test against step. + * @param float $step The threshold value. + * If you omit a value for step, GESTEP uses zero. + * @return int + */ + public static function GESTEP($number, $step = 0) + { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $step = PHPExcel_Calculation_Functions::flattenSingleValue($step); + + return (int) ($number >= $step); + } + + + // + // Private method to calculate the erf value + // + private static $_two_sqrtpi = 1.128379167095512574; + + public static function _erfVal($x) + { + if (abs($x) > 2.2) { + return 1 - self::_erfcVal($x); + } + $sum = $term = $x; + $xsqr = ($x * $x); + $j = 1; + do { + $term *= $xsqr / $j; + $sum -= $term / (2 * $j + 1); + ++$j; + $term *= $xsqr / $j; + $sum += $term / (2 * $j + 1); + ++$j; + if ($sum == 0.0) { + break; + } + } while (abs($term / $sum) > PRECISION); + return self::$_two_sqrtpi * $sum; + } + + + /** + * ERF + * + * Returns the error function integrated between the lower and upper bound arguments. + * + * Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments, + * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was + * improved, so that it can now calculate the function for both positive and negative ranges. + * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments. + * + * Excel Function: + * ERF(lower[,upper]) + * + * @param float $lower lower bound for integrating ERF + * @param float $upper upper bound for integrating ERF. + * If omitted, ERF integrates between zero and lower_limit + * @return float + */ + public static function ERF($lower, $upper = null) + { + $lower = PHPExcel_Calculation_Functions::flattenSingleValue($lower); + $upper = PHPExcel_Calculation_Functions::flattenSingleValue($upper); + + if (is_numeric($lower)) { + if (is_null($upper)) { + return self::_erfVal($lower); + } + if (is_numeric($upper)) { + return self::_erfVal($upper) - self::_erfVal($lower); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + // + // Private method to calculate the erfc value + // + private static $_one_sqrtpi = 0.564189583547756287; + + private static function _erfcVal($x) + { + if (abs($x) < 2.2) { + return 1 - self::_erfVal($x); + } + if ($x < 0) { + return 2 - self::ERFC(-$x); + } + $a = $n = 1; + $b = $c = $x; + $d = ($x * $x) + 0.5; + $q1 = $q2 = $b / $d; + $t = 0; + do { + $t = $a * $n + $b * $x; + $a = $b; + $b = $t; + $t = $c * $n + $d * $x; + $c = $d; + $d = $t; + $n += 0.5; + $q1 = $q2; + $q2 = $b / $d; + } while ((abs($q1 - $q2) / $q2) > PRECISION); + return self::$_one_sqrtpi * exp(-$x * $x) * $q2; + } + + + /** + * ERFC + * + * Returns the complementary ERF function integrated between x and infinity + * + * Note: In Excel 2007 or earlier, if you input a negative value for the lower bound argument, + * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was + * improved, so that it can now calculate the function for both positive and negative x values. + * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments. + * + * Excel Function: + * ERFC(x) + * + * @param float $x The lower bound for integrating ERFC + * @return float + */ + public static function ERFC($x) + { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_numeric($x)) { + return self::_erfcVal($x); + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + /** + * getConversionGroups + * Returns a list of the different conversion groups for UOM conversions + * + * @return array + */ + public static function getConversionGroups() + { + $conversionGroups = array(); + foreach (self::$_conversionUnits as $conversionUnit) { + $conversionGroups[] = $conversionUnit['Group']; + } + return array_merge(array_unique($conversionGroups)); + } + + + /** + * getConversionGroupUnits + * Returns an array of units of measure, for a specified conversion group, or for all groups + * + * @param string $group The group whose units of measure you want to retrieve + * @return array + */ + public static function getConversionGroupUnits($group = null) + { + $conversionGroups = array(); + foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) { + if ((is_null($group)) || ($conversionGroup['Group'] == $group)) { + $conversionGroups[$conversionGroup['Group']][] = $conversionUnit; + } + } + return $conversionGroups; + } + + + /** + * getConversionGroupUnitDetails + * + * @param string $group The group whose units of measure you want to retrieve + * @return array + */ + public static function getConversionGroupUnitDetails($group = null) + { + $conversionGroups = array(); + foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) { + if ((is_null($group)) || ($conversionGroup['Group'] == $group)) { + $conversionGroups[$conversionGroup['Group']][] = array( + 'unit' => $conversionUnit, + 'description' => $conversionGroup['Unit Name'] + ); + } + } + return $conversionGroups; + } + + + /** + * getConversionMultipliers + * Returns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM() + * + * @return array of mixed + */ + public static function getConversionMultipliers() + { + return self::$_conversionMultipliers; + } + + + /** + * CONVERTUOM + * + * Converts a number from one measurement system to another. + * For example, CONVERT can translate a table of distances in miles to a table of distances + * in kilometers. + * + * Excel Function: + * CONVERT(value,fromUOM,toUOM) + * + * @param float $value The value in fromUOM to convert. + * @param string $fromUOM The units for value. + * @param string $toUOM The units for the result. + * + * @return float + */ + public static function CONVERTUOM($value, $fromUOM, $toUOM) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $fromUOM = PHPExcel_Calculation_Functions::flattenSingleValue($fromUOM); + $toUOM = PHPExcel_Calculation_Functions::flattenSingleValue($toUOM); + + if (!is_numeric($value)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $fromMultiplier = 1.0; + if (isset(self::$_conversionUnits[$fromUOM])) { + $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group']; + } else { + $fromMultiplier = substr($fromUOM,0,1); + $fromUOM = substr($fromUOM,1); + if (isset(self::$_conversionMultipliers[$fromMultiplier])) { + $fromMultiplier = self::$_conversionMultipliers[$fromMultiplier]['multiplier']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + if ((isset(self::$_conversionUnits[$fromUOM])) && (self::$_conversionUnits[$fromUOM]['AllowPrefix'])) { + $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + } + $value *= $fromMultiplier; + + $toMultiplier = 1.0; + if (isset(self::$_conversionUnits[$toUOM])) { + $unitGroup2 = self::$_conversionUnits[$toUOM]['Group']; + } else { + $toMultiplier = substr($toUOM,0,1); + $toUOM = substr($toUOM,1); + if (isset(self::$_conversionMultipliers[$toMultiplier])) { + $toMultiplier = self::$_conversionMultipliers[$toMultiplier]['multiplier']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + if ((isset(self::$_conversionUnits[$toUOM])) && (self::$_conversionUnits[$toUOM]['AllowPrefix'])) { + $unitGroup2 = self::$_conversionUnits[$toUOM]['Group']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + } + if ($unitGroup1 != $unitGroup2) { + return PHPExcel_Calculation_Functions::NA(); + } + + if (($fromUOM == $toUOM) && ($fromMultiplier == $toMultiplier)) { + // We've already factored $fromMultiplier into the value, so we need + // to reverse it again + return $value / $fromMultiplier; + } elseif ($unitGroup1 == 'Temperature') { + if (($fromUOM == 'F') || ($fromUOM == 'fah')) { + if (($toUOM == 'F') || ($toUOM == 'fah')) { + return $value; + } else { + $value = (($value - 32) / 1.8); + if (($toUOM == 'K') || ($toUOM == 'kel')) { + $value += 273.15; + } + return $value; + } + } elseif ((($fromUOM == 'K') || ($fromUOM == 'kel')) && + (($toUOM == 'K') || ($toUOM == 'kel'))) { + return $value; + } elseif ((($fromUOM == 'C') || ($fromUOM == 'cel')) && + (($toUOM == 'C') || ($toUOM == 'cel'))) { + return $value; + } + if (($toUOM == 'F') || ($toUOM == 'fah')) { + if (($fromUOM == 'K') || ($fromUOM == 'kel')) { + $value -= 273.15; + } + return ($value * 1.8) + 32; + } + if (($toUOM == 'C') || ($toUOM == 'cel')) { + return $value - 273.15; + } + return $value + 273.15; + } + return ($value * self::$_unitConversions[$unitGroup1][$fromUOM][$toUOM]) / $toMultiplier; + } +} diff --git a/Classes/PHPExcel/Calculation/Exception.php b/Classes/PHPExcel/Calculation/Exception.php index 77f8ca05c..bd6e22f11 100644 --- a/Classes/PHPExcel/Calculation/Exception.php +++ b/Classes/PHPExcel/Calculation/Exception.php @@ -21,8 +21,8 @@ * @category PHPExcel * @package PHPExcel_Calculation * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ @@ -34,19 +34,19 @@ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Exception extends PHPExcel_Exception { - /** - * Error handler callback - * - * @param mixed $code - * @param mixed $string - * @param mixed $file - * @param mixed $line - * @param mixed $context - */ - public static function errorHandlerCallback($code, $string, $file, $line, $context) { - $e = new self($string, $code); - $e->line = $line; - $e->file = $file; - throw $e; - } + /** + * Error handler callback + * + * @param mixed $code + * @param mixed $string + * @param mixed $file + * @param mixed $line + * @param mixed $context + */ + public static function errorHandlerCallback($code, $string, $file, $line, $context) { + $e = new self($string, $code); + $e->line = $line; + $e->file = $file; + throw $e; + } } diff --git a/Classes/PHPExcel/Calculation/ExceptionHandler.php b/Classes/PHPExcel/Calculation/ExceptionHandler.php index 01d60b9e3..4f3d247d1 100644 --- a/Classes/PHPExcel/Calculation/ExceptionHandler.php +++ b/Classes/PHPExcel/Calculation/ExceptionHandler.php @@ -21,8 +21,8 @@ * @category PHPExcel * @package PHPExcel_Calculation * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** @@ -33,17 +33,17 @@ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_ExceptionHandler { - /** - * Register errorhandler - */ - public function __construct() { - set_error_handler(array('PHPExcel_Calculation_Exception', 'errorHandlerCallback'), E_ALL); - } + /** + * Register errorhandler + */ + public function __construct() { + set_error_handler(array('PHPExcel_Calculation_Exception', 'errorHandlerCallback'), E_ALL); + } - /** - * Unregister errorhandler - */ - public function __destruct() { - restore_error_handler(); - } + /** + * Unregister errorhandler + */ + public function __destruct() { + restore_error_handler(); + } } diff --git a/Classes/PHPExcel/Calculation/Financial.php b/Classes/PHPExcel/Calculation/Financial.php index 556acabfc..b78b176a0 100644 --- a/Classes/PHPExcel/Calculation/Financial.php +++ b/Classes/PHPExcel/Calculation/Financial.php @@ -18,21 +18,21 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } @@ -46,2247 +46,2247 @@ /** * PHPExcel_Calculation_Financial * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Financial { - /** - * _lastDayOfMonth - * - * Returns a boolean TRUE/FALSE indicating if this date is the last date of the month - * - * @param DateTime $testDate The date for testing - * @return boolean - */ - private static function _lastDayOfMonth($testDate) - { - return ($testDate->format('d') == $testDate->format('t')); - } // function _lastDayOfMonth() - - - /** - * _firstDayOfMonth - * - * Returns a boolean TRUE/FALSE indicating if this date is the first date of the month - * - * @param DateTime $testDate The date for testing - * @return boolean - */ - private static function _firstDayOfMonth($testDate) - { - return ($testDate->format('d') == 1); - } // function _firstDayOfMonth() - - - private static function _coupFirstPeriodDate($settlement, $maturity, $frequency, $next) - { - $months = 12 / $frequency; - - $result = PHPExcel_Shared_Date::ExcelToPHPObject($maturity); - $eom = self::_lastDayOfMonth($result); - - while ($settlement < PHPExcel_Shared_Date::PHPToExcel($result)) { - $result->modify('-'.$months.' months'); - } - if ($next) { - $result->modify('+'.$months.' months'); - } - - if ($eom) { - $result->modify('-1 day'); - } - - return PHPExcel_Shared_Date::PHPToExcel($result); - } // function _coupFirstPeriodDate() - - - private static function _validFrequency($frequency) - { - if (($frequency == 1) || ($frequency == 2) || ($frequency == 4)) { - return true; - } - if ((PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) && - (($frequency == 6) || ($frequency == 12))) { - return true; - } - return false; - } // function _validFrequency() - - - /** - * _daysPerYear - * - * Returns the number of days in a specified year, as defined by the "basis" value - * - * @param integer $year The year against which we're testing - * @param integer $basis The type of day count: - * 0 or omitted US (NASD) 360 - * 1 Actual (365 or 366 in a leap year) - * 2 360 - * 3 365 - * 4 European 360 - * @return integer - */ - private static function _daysPerYear($year, $basis=0) - { - switch ($basis) { - case 0 : - case 2 : - case 4 : - $daysPerYear = 360; - break; - case 3 : - $daysPerYear = 365; - break; - case 1 : - $daysPerYear = (PHPExcel_Calculation_DateTime::_isLeapYear($year)) ? 366 : 365; - break; - default : - return PHPExcel_Calculation_Functions::NaN(); - } - return $daysPerYear; - } // function _daysPerYear() - - - private static function _interestAndPrincipal($rate=0, $per=0, $nper=0, $pv=0, $fv=0, $type=0) - { - $pmt = self::PMT($rate, $nper, $pv, $fv, $type); - $capital = $pv; - for ($i = 1; $i<= $per; ++$i) { - $interest = ($type && $i == 1) ? 0 : -$capital * $rate; - $principal = $pmt - $interest; - $capital += $principal; - } - return array($interest, $principal); - } // function _interestAndPrincipal() - - - /** - * ACCRINT - * - * Returns the accrued interest for a security that pays periodic interest. - * - * Excel Function: - * ACCRINT(issue,firstinterest,settlement,rate,par,frequency[,basis]) - * - * @access public - * @category Financial Functions - * @param mixed $issue The security's issue date. - * @param mixed $firstinterest The security's first interest date. - * @param mixed $settlement The security's settlement date. - * The security settlement date is the date after the issue date - * when the security is traded to the buyer. - * @param float $rate The security's annual coupon rate. - * @param float $par The security's par value. - * If you omit par, ACCRINT uses $1,000. - * @param integer $frequency the number of coupon payments per year. - * Valid frequency values are: - * 1 Annual - * 2 Semi-Annual - * 4 Quarterly - * If working in Gnumeric Mode, the following frequency options are - * also available - * 6 Bimonthly - * 12 Monthly - * @param integer $basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par=1000, $frequency=1, $basis=0) - { - $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); - $firstinterest = PHPExcel_Calculation_Functions::flattenSingleValue($firstinterest); - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $par = (is_null($par)) ? 1000 : PHPExcel_Calculation_Functions::flattenSingleValue($par); - $frequency = (is_null($frequency)) ? 1 : PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - // Validate - if ((is_numeric($rate)) && (is_numeric($par))) { - $rate = (float) $rate; - $par = (float) $par; - if (($rate <= 0) || ($par <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); - if (!is_numeric($daysBetweenIssueAndSettlement)) { - // return date error - return $daysBetweenIssueAndSettlement; - } - - return $par * $rate * $daysBetweenIssueAndSettlement; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function ACCRINT() - - - /** - * ACCRINTM - * - * Returns the accrued interest for a security that pays interest at maturity. - * - * Excel Function: - * ACCRINTM(issue,settlement,rate[,par[,basis]]) - * - * @access public - * @category Financial Functions - * @param mixed issue The security's issue date. - * @param mixed settlement The security's settlement (or maturity) date. - * @param float rate The security's annual coupon rate. - * @param float par The security's par value. - * If you omit par, ACCRINT uses $1,000. - * @param integer basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function ACCRINTM($issue, $settlement, $rate, $par=1000, $basis=0) { - $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $par = (is_null($par)) ? 1000 : PHPExcel_Calculation_Functions::flattenSingleValue($par); - $basis = (is_null($basis)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - // Validate - if ((is_numeric($rate)) && (is_numeric($par))) { - $rate = (float) $rate; - $par = (float) $par; - if (($rate <= 0) || ($par <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); - if (!is_numeric($daysBetweenIssueAndSettlement)) { - // return date error - return $daysBetweenIssueAndSettlement; - } - return $par * $rate * $daysBetweenIssueAndSettlement; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function ACCRINTM() - - - /** - * AMORDEGRC - * - * Returns the depreciation for each accounting period. - * This function is provided for the French accounting system. If an asset is purchased in - * the middle of the accounting period, the prorated depreciation is taken into account. - * The function is similar to AMORLINC, except that a depreciation coefficient is applied in - * the calculation depending on the life of the assets. - * This function will return the depreciation until the last period of the life of the assets - * or until the cumulated value of depreciation is greater than the cost of the assets minus - * the salvage value. - * - * Excel Function: - * AMORDEGRC(cost,purchased,firstPeriod,salvage,period,rate[,basis]) - * - * @access public - * @category Financial Functions - * @param float cost The cost of the asset. - * @param mixed purchased Date of the purchase of the asset. - * @param mixed firstPeriod Date of the end of the first period. - * @param mixed salvage The salvage value at the end of the life of the asset. - * @param float period The period. - * @param float rate Rate of depreciation. - * @param integer basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function AMORDEGRC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) { - $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); - $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); - $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); - $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); - $period = floor(PHPExcel_Calculation_Functions::flattenSingleValue($period)); - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - // The depreciation coefficients are: - // Life of assets (1/rate) Depreciation coefficient - // Less than 3 years 1 - // Between 3 and 4 years 1.5 - // Between 5 and 6 years 2 - // More than 6 years 2.5 - $fUsePer = 1.0 / $rate; - if ($fUsePer < 3.0) { - $amortiseCoeff = 1.0; - } elseif ($fUsePer < 5.0) { - $amortiseCoeff = 1.5; - } elseif ($fUsePer <= 6.0) { - $amortiseCoeff = 2.0; - } else { - $amortiseCoeff = 2.5; - } - - $rate *= $amortiseCoeff; - $fNRate = round(PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis) * $rate * $cost,0); - $cost -= $fNRate; - $fRest = $cost - $salvage; - - for ($n = 0; $n < $period; ++$n) { - $fNRate = round($rate * $cost,0); - $fRest -= $fNRate; - - if ($fRest < 0.0) { - switch ($period - $n) { - case 0 : - case 1 : return round($cost * 0.5, 0); - break; - default : return 0.0; - break; - } - } - $cost -= $fNRate; - } - return $fNRate; - } // function AMORDEGRC() - - - /** - * AMORLINC - * - * Returns the depreciation for each accounting period. - * This function is provided for the French accounting system. If an asset is purchased in - * the middle of the accounting period, the prorated depreciation is taken into account. - * - * Excel Function: - * AMORLINC(cost,purchased,firstPeriod,salvage,period,rate[,basis]) - * - * @access public - * @category Financial Functions - * @param float cost The cost of the asset. - * @param mixed purchased Date of the purchase of the asset. - * @param mixed firstPeriod Date of the end of the first period. - * @param mixed salvage The salvage value at the end of the life of the asset. - * @param float period The period. - * @param float rate Rate of depreciation. - * @param integer basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function AMORLINC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) { - $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); - $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); - $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); - $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); - $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - $fOneRate = $cost * $rate; - $fCostDelta = $cost - $salvage; - // Note, quirky variation for leap years on the YEARFRAC for this function - $purchasedYear = PHPExcel_Calculation_DateTime::YEAR($purchased); - $yearFrac = PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis); - - if (($basis == 1) && ($yearFrac < 1) && (PHPExcel_Calculation_DateTime::_isLeapYear($purchasedYear))) { - $yearFrac *= 365 / 366; - } - - $f0Rate = $yearFrac * $rate * $cost; - $nNumOfFullPeriods = intval(($cost - $salvage - $f0Rate) / $fOneRate); - - if ($period == 0) { - return $f0Rate; - } elseif ($period <= $nNumOfFullPeriods) { - return $fOneRate; - } elseif ($period == ($nNumOfFullPeriods + 1)) { + /** + * _lastDayOfMonth + * + * Returns a boolean TRUE/FALSE indicating if this date is the last date of the month + * + * @param DateTime $testDate The date for testing + * @return boolean + */ + private static function _lastDayOfMonth($testDate) + { + return ($testDate->format('d') == $testDate->format('t')); + } // function _lastDayOfMonth() + + + /** + * _firstDayOfMonth + * + * Returns a boolean TRUE/FALSE indicating if this date is the first date of the month + * + * @param DateTime $testDate The date for testing + * @return boolean + */ + private static function _firstDayOfMonth($testDate) + { + return ($testDate->format('d') == 1); + } // function _firstDayOfMonth() + + + private static function _coupFirstPeriodDate($settlement, $maturity, $frequency, $next) + { + $months = 12 / $frequency; + + $result = PHPExcel_Shared_Date::ExcelToPHPObject($maturity); + $eom = self::_lastDayOfMonth($result); + + while ($settlement < PHPExcel_Shared_Date::PHPToExcel($result)) { + $result->modify('-'.$months.' months'); + } + if ($next) { + $result->modify('+'.$months.' months'); + } + + if ($eom) { + $result->modify('-1 day'); + } + + return PHPExcel_Shared_Date::PHPToExcel($result); + } // function _coupFirstPeriodDate() + + + private static function _validFrequency($frequency) + { + if (($frequency == 1) || ($frequency == 2) || ($frequency == 4)) { + return true; + } + if ((PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) && + (($frequency == 6) || ($frequency == 12))) { + return true; + } + return false; + } // function _validFrequency() + + + /** + * _daysPerYear + * + * Returns the number of days in a specified year, as defined by the "basis" value + * + * @param integer $year The year against which we're testing + * @param integer $basis The type of day count: + * 0 or omitted US (NASD) 360 + * 1 Actual (365 or 366 in a leap year) + * 2 360 + * 3 365 + * 4 European 360 + * @return integer + */ + private static function _daysPerYear($year, $basis=0) + { + switch ($basis) { + case 0 : + case 2 : + case 4 : + $daysPerYear = 360; + break; + case 3 : + $daysPerYear = 365; + break; + case 1 : + $daysPerYear = (PHPExcel_Calculation_DateTime::isLeapYear($year)) ? 366 : 365; + break; + default : + return PHPExcel_Calculation_Functions::NaN(); + } + return $daysPerYear; + } // function _daysPerYear() + + + private static function _interestAndPrincipal($rate=0, $per=0, $nper=0, $pv=0, $fv=0, $type=0) + { + $pmt = self::PMT($rate, $nper, $pv, $fv, $type); + $capital = $pv; + for ($i = 1; $i<= $per; ++$i) { + $interest = ($type && $i == 1) ? 0 : -$capital * $rate; + $principal = $pmt - $interest; + $capital += $principal; + } + return array($interest, $principal); + } // function _interestAndPrincipal() + + + /** + * ACCRINT + * + * Returns the accrued interest for a security that pays periodic interest. + * + * Excel Function: + * ACCRINT(issue,firstinterest,settlement,rate,par,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed $issue The security's issue date. + * @param mixed $firstinterest The security's first interest date. + * @param mixed $settlement The security's settlement date. + * The security settlement date is the date after the issue date + * when the security is traded to the buyer. + * @param float $rate The security's annual coupon rate. + * @param float $par The security's par value. + * If you omit par, ACCRINT uses $1,000. + * @param integer $frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer $basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par=1000, $frequency=1, $basis=0) + { + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $firstinterest = PHPExcel_Calculation_Functions::flattenSingleValue($firstinterest); + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $par = (is_null($par)) ? 1000 : PHPExcel_Calculation_Functions::flattenSingleValue($par); + $frequency = (is_null($frequency)) ? 1 : PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($rate)) && (is_numeric($par))) { + $rate = (float) $rate; + $par = (float) $par; + if (($rate <= 0) || ($par <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + + return $par * $rate * $daysBetweenIssueAndSettlement; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ACCRINT() + + + /** + * ACCRINTM + * + * Returns the accrued interest for a security that pays interest at maturity. + * + * Excel Function: + * ACCRINTM(issue,settlement,rate[,par[,basis]]) + * + * @access public + * @category Financial Functions + * @param mixed issue The security's issue date. + * @param mixed settlement The security's settlement (or maturity) date. + * @param float rate The security's annual coupon rate. + * @param float par The security's par value. + * If you omit par, ACCRINT uses $1,000. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function ACCRINTM($issue, $settlement, $rate, $par=1000, $basis=0) { + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $par = (is_null($par)) ? 1000 : PHPExcel_Calculation_Functions::flattenSingleValue($par); + $basis = (is_null($basis)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($rate)) && (is_numeric($par))) { + $rate = (float) $rate; + $par = (float) $par; + if (($rate <= 0) || ($par <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + return $par * $rate * $daysBetweenIssueAndSettlement; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ACCRINTM() + + + /** + * AMORDEGRC + * + * Returns the depreciation for each accounting period. + * This function is provided for the French accounting system. If an asset is purchased in + * the middle of the accounting period, the prorated depreciation is taken into account. + * The function is similar to AMORLINC, except that a depreciation coefficient is applied in + * the calculation depending on the life of the assets. + * This function will return the depreciation until the last period of the life of the assets + * or until the cumulated value of depreciation is greater than the cost of the assets minus + * the salvage value. + * + * Excel Function: + * AMORDEGRC(cost,purchased,firstPeriod,salvage,period,rate[,basis]) + * + * @access public + * @category Financial Functions + * @param float cost The cost of the asset. + * @param mixed purchased Date of the purchase of the asset. + * @param mixed firstPeriod Date of the end of the first period. + * @param mixed salvage The salvage value at the end of the life of the asset. + * @param float period The period. + * @param float rate Rate of depreciation. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function AMORDEGRC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); + $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $period = floor(PHPExcel_Calculation_Functions::flattenSingleValue($period)); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // The depreciation coefficients are: + // Life of assets (1/rate) Depreciation coefficient + // Less than 3 years 1 + // Between 3 and 4 years 1.5 + // Between 5 and 6 years 2 + // More than 6 years 2.5 + $fUsePer = 1.0 / $rate; + if ($fUsePer < 3.0) { + $amortiseCoeff = 1.0; + } elseif ($fUsePer < 5.0) { + $amortiseCoeff = 1.5; + } elseif ($fUsePer <= 6.0) { + $amortiseCoeff = 2.0; + } else { + $amortiseCoeff = 2.5; + } + + $rate *= $amortiseCoeff; + $fNRate = round(PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis) * $rate * $cost,0); + $cost -= $fNRate; + $fRest = $cost - $salvage; + + for ($n = 0; $n < $period; ++$n) { + $fNRate = round($rate * $cost,0); + $fRest -= $fNRate; + + if ($fRest < 0.0) { + switch ($period - $n) { + case 0 : + case 1 : return round($cost * 0.5, 0); + break; + default : return 0.0; + break; + } + } + $cost -= $fNRate; + } + return $fNRate; + } // function AMORDEGRC() + + + /** + * AMORLINC + * + * Returns the depreciation for each accounting period. + * This function is provided for the French accounting system. If an asset is purchased in + * the middle of the accounting period, the prorated depreciation is taken into account. + * + * Excel Function: + * AMORLINC(cost,purchased,firstPeriod,salvage,period,rate[,basis]) + * + * @access public + * @category Financial Functions + * @param float cost The cost of the asset. + * @param mixed purchased Date of the purchase of the asset. + * @param mixed firstPeriod Date of the end of the first period. + * @param mixed salvage The salvage value at the end of the life of the asset. + * @param float period The period. + * @param float rate Rate of depreciation. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function AMORLINC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); + $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + $fOneRate = $cost * $rate; + $fCostDelta = $cost - $salvage; + // Note, quirky variation for leap years on the YEARFRAC for this function + $purchasedYear = PHPExcel_Calculation_DateTime::YEAR($purchased); + $yearFrac = PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis); + + if (($basis == 1) && ($yearFrac < 1) && (PHPExcel_Calculation_DateTime::isLeapYear($purchasedYear))) { + $yearFrac *= 365 / 366; + } + + $f0Rate = $yearFrac * $rate * $cost; + $nNumOfFullPeriods = intval(($cost - $salvage - $f0Rate) / $fOneRate); + + if ($period == 0) { + return $f0Rate; + } elseif ($period <= $nNumOfFullPeriods) { + return $fOneRate; + } elseif ($period == ($nNumOfFullPeriods + 1)) { return ($fCostDelta - $fOneRate * $nNumOfFullPeriods - $f0Rate); - } else { - return 0.0; - } - } // function AMORLINC() - - - /** - * COUPDAYBS - * - * Returns the number of days from the beginning of the coupon period to the settlement date. - * - * Excel Function: - * COUPDAYBS(settlement,maturity,frequency[,basis]) - * - * @access public - * @category Financial Functions - * @param mixed settlement The security's settlement date. - * The security settlement date is the date after the issue - * date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param mixed frequency the number of coupon payments per year. - * Valid frequency values are: - * 1 Annual - * 2 Semi-Annual - * 4 Quarterly - * If working in Gnumeric Mode, the following frequency options are - * also available - * 6 Bimonthly - * 12 Monthly - * @param integer basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function COUPDAYBS($settlement, $maturity, $frequency, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || - (($basis < 0) || ($basis > 4))) { - return PHPExcel_Calculation_Functions::NaN(); - } - - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); - $prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); - - return PHPExcel_Calculation_DateTime::YEARFRAC($prev, $settlement, $basis) * $daysPerYear; - } // function COUPDAYBS() - - - /** - * COUPDAYS - * - * Returns the number of days in the coupon period that contains the settlement date. - * - * Excel Function: - * COUPDAYS(settlement,maturity,frequency[,basis]) - * - * @access public - * @category Financial Functions - * @param mixed settlement The security's settlement date. - * The security settlement date is the date after the issue - * date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param mixed frequency the number of coupon payments per year. - * Valid frequency values are: - * 1 Annual - * 2 Semi-Annual - * 4 Quarterly - * If working in Gnumeric Mode, the following frequency options are - * also available - * 6 Bimonthly - * 12 Monthly - * @param integer basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function COUPDAYS($settlement, $maturity, $frequency, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || - (($basis < 0) || ($basis > 4))) { - return PHPExcel_Calculation_Functions::NaN(); - } - - switch ($basis) { - case 3: // Actual/365 - return 365 / $frequency; - case 1: // Actual/actual - if ($frequency == 1) { - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($maturity),$basis); - return ($daysPerYear / $frequency); - } else { - $prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); - $next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); - return ($next - $prev); - } - default: // US (NASD) 30/360, Actual/360 or European 30/360 - return 360 / $frequency; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function COUPDAYS() - - - /** - * COUPDAYSNC - * - * Returns the number of days from the settlement date to the next coupon date. - * - * Excel Function: - * COUPDAYSNC(settlement,maturity,frequency[,basis]) - * - * @access public - * @category Financial Functions - * @param mixed settlement The security's settlement date. - * The security settlement date is the date after the issue - * date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param mixed frequency the number of coupon payments per year. - * Valid frequency values are: - * 1 Annual - * 2 Semi-Annual - * 4 Quarterly - * If working in Gnumeric Mode, the following frequency options are - * also available - * 6 Bimonthly - * 12 Monthly - * @param integer basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function COUPDAYSNC($settlement, $maturity, $frequency, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || - (($basis < 0) || ($basis > 4))) { - return PHPExcel_Calculation_Functions::NaN(); - } - - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); - $next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); - - return PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $next, $basis) * $daysPerYear; - } // function COUPDAYSNC() - - - /** - * COUPNCD - * - * Returns the next coupon date after the settlement date. - * - * Excel Function: - * COUPNCD(settlement,maturity,frequency[,basis]) - * - * @access public - * @category Financial Functions - * @param mixed settlement The security's settlement date. - * The security settlement date is the date after the issue - * date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param mixed frequency the number of coupon payments per year. - * Valid frequency values are: - * 1 Annual - * 2 Semi-Annual - * 4 Quarterly - * If working in Gnumeric Mode, the following frequency options are - * also available - * 6 Bimonthly - * 12 Monthly - * @param integer basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function COUPNCD($settlement, $maturity, $frequency, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || - (($basis < 0) || ($basis > 4))) { - return PHPExcel_Calculation_Functions::NaN(); - } - - return self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); - } // function COUPNCD() - - - /** - * COUPNUM - * - * Returns the number of coupons payable between the settlement date and maturity date, - * rounded up to the nearest whole coupon. - * - * Excel Function: - * COUPNUM(settlement,maturity,frequency[,basis]) - * - * @access public - * @category Financial Functions - * @param mixed settlement The security's settlement date. - * The security settlement date is the date after the issue - * date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param mixed frequency the number of coupon payments per year. - * Valid frequency values are: - * 1 Annual - * 2 Semi-Annual - * 4 Quarterly - * If working in Gnumeric Mode, the following frequency options are - * also available - * 6 Bimonthly - * 12 Monthly - * @param integer basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return integer - */ - public static function COUPNUM($settlement, $maturity, $frequency, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || - (($basis < 0) || ($basis > 4))) { - return PHPExcel_Calculation_Functions::NaN(); - } - - $settlement = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis) * 365; - - switch ($frequency) { - case 1: // annual payments - return ceil($daysBetweenSettlementAndMaturity / 360); - case 2: // half-yearly - return ceil($daysBetweenSettlementAndMaturity / 180); - case 4: // quarterly - return ceil($daysBetweenSettlementAndMaturity / 90); - case 6: // bimonthly - return ceil($daysBetweenSettlementAndMaturity / 60); - case 12: // monthly - return ceil($daysBetweenSettlementAndMaturity / 30); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function COUPNUM() - - - /** - * COUPPCD - * - * Returns the previous coupon date before the settlement date. - * - * Excel Function: - * COUPPCD(settlement,maturity,frequency[,basis]) - * - * @access public - * @category Financial Functions - * @param mixed settlement The security's settlement date. - * The security settlement date is the date after the issue - * date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param mixed frequency the number of coupon payments per year. - * Valid frequency values are: - * 1 Annual - * 2 Semi-Annual - * 4 Quarterly - * If working in Gnumeric Mode, the following frequency options are - * also available - * 6 Bimonthly - * 12 Monthly - * @param integer basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function COUPPCD($settlement, $maturity, $frequency, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || - (($basis < 0) || ($basis > 4))) { - return PHPExcel_Calculation_Functions::NaN(); - } - - return self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); - } // function COUPPCD() - - - /** - * CUMIPMT - * - * Returns the cumulative interest paid on a loan between the start and end periods. - * - * Excel Function: - * CUMIPMT(rate,nper,pv,start,end[,type]) - * - * @access public - * @category Financial Functions - * @param float $rate The Interest rate - * @param integer $nper The total number of payment periods - * @param float $pv Present Value - * @param integer $start The first period in the calculation. - * Payment periods are numbered beginning with 1. - * @param integer $end The last period in the calculation. - * @param integer $type A number 0 or 1 and indicates when payments are due: - * 0 or omitted At the end of the period. - * 1 At the beginning of the period. - * @return float - */ - public static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0) { - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); - $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); - $start = (int) PHPExcel_Calculation_Functions::flattenSingleValue($start); - $end = (int) PHPExcel_Calculation_Functions::flattenSingleValue($end); - $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); - - // Validate parameters - if ($type != 0 && $type != 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($start < 1 || $start > $end) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - // Calculate - $interest = 0; - for ($per = $start; $per <= $end; ++$per) { - $interest += self::IPMT($rate, $per, $nper, $pv, 0, $type); - } - - return $interest; - } // function CUMIPMT() - - - /** - * CUMPRINC - * - * Returns the cumulative principal paid on a loan between the start and end periods. - * - * Excel Function: - * CUMPRINC(rate,nper,pv,start,end[,type]) - * - * @access public - * @category Financial Functions - * @param float $rate The Interest rate - * @param integer $nper The total number of payment periods - * @param float $pv Present Value - * @param integer $start The first period in the calculation. - * Payment periods are numbered beginning with 1. - * @param integer $end The last period in the calculation. - * @param integer $type A number 0 or 1 and indicates when payments are due: - * 0 or omitted At the end of the period. - * 1 At the beginning of the period. - * @return float - */ - public static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0) { - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); - $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); - $start = (int) PHPExcel_Calculation_Functions::flattenSingleValue($start); - $end = (int) PHPExcel_Calculation_Functions::flattenSingleValue($end); - $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); - - // Validate parameters - if ($type != 0 && $type != 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($start < 1 || $start > $end) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - // Calculate - $principal = 0; - for ($per = $start; $per <= $end; ++$per) { - $principal += self::PPMT($rate, $per, $nper, $pv, 0, $type); - } - - return $principal; - } // function CUMPRINC() - - - /** - * DB - * - * Returns the depreciation of an asset for a specified period using the - * fixed-declining balance method. - * This form of depreciation is used if you want to get a higher depreciation value - * at the beginning of the depreciation (as opposed to linear depreciation). The - * depreciation value is reduced with every depreciation period by the depreciation - * already deducted from the initial cost. - * - * Excel Function: - * DB(cost,salvage,life,period[,month]) - * - * @access public - * @category Financial Functions - * @param float cost Initial cost of the asset. - * @param float salvage Value at the end of the depreciation. - * (Sometimes called the salvage value of the asset) - * @param integer life Number of periods over which the asset is depreciated. - * (Sometimes called the useful life of the asset) - * @param integer period The period for which you want to calculate the - * depreciation. Period must use the same units as life. - * @param integer month Number of months in the first year. If month is omitted, - * it defaults to 12. - * @return float - */ - public static function DB($cost, $salvage, $life, $period, $month=12) { - $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); - $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); - $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); - $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); - $month = PHPExcel_Calculation_Functions::flattenSingleValue($month); - - // Validate - if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($month))) { - $cost = (float) $cost; - $salvage = (float) $salvage; - $life = (int) $life; - $period = (int) $period; - $month = (int) $month; - if ($cost == 0) { - return 0.0; - } elseif (($cost < 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($month < 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - // Set Fixed Depreciation Rate - $fixedDepreciationRate = 1 - pow(($salvage / $cost), (1 / $life)); - $fixedDepreciationRate = round($fixedDepreciationRate, 3); - - // Loop through each period calculating the depreciation - $previousDepreciation = 0; - for ($per = 1; $per <= $period; ++$per) { - if ($per == 1) { - $depreciation = $cost * $fixedDepreciationRate * $month / 12; - } elseif ($per == ($life + 1)) { - $depreciation = ($cost - $previousDepreciation) * $fixedDepreciationRate * (12 - $month) / 12; - } else { - $depreciation = ($cost - $previousDepreciation) * $fixedDepreciationRate; - } - $previousDepreciation += $depreciation; - } - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - $depreciation = round($depreciation,2); - } - return $depreciation; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function DB() - - - /** - * DDB - * - * Returns the depreciation of an asset for a specified period using the - * double-declining balance method or some other method you specify. - * - * Excel Function: - * DDB(cost,salvage,life,period[,factor]) - * - * @access public - * @category Financial Functions - * @param float cost Initial cost of the asset. - * @param float salvage Value at the end of the depreciation. - * (Sometimes called the salvage value of the asset) - * @param integer life Number of periods over which the asset is depreciated. - * (Sometimes called the useful life of the asset) - * @param integer period The period for which you want to calculate the - * depreciation. Period must use the same units as life. - * @param float factor The rate at which the balance declines. - * If factor is omitted, it is assumed to be 2 (the - * double-declining balance method). - * @return float - */ - public static function DDB($cost, $salvage, $life, $period, $factor=2.0) { - $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); - $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); - $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); - $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); - $factor = PHPExcel_Calculation_Functions::flattenSingleValue($factor); - - // Validate - if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($factor))) { - $cost = (float) $cost; - $salvage = (float) $salvage; - $life = (int) $life; - $period = (int) $period; - $factor = (float) $factor; - if (($cost <= 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($factor <= 0.0) || ($period > $life)) { - return PHPExcel_Calculation_Functions::NaN(); - } - // Set Fixed Depreciation Rate - $fixedDepreciationRate = 1 - pow(($salvage / $cost), (1 / $life)); - $fixedDepreciationRate = round($fixedDepreciationRate, 3); - - // Loop through each period calculating the depreciation - $previousDepreciation = 0; - for ($per = 1; $per <= $period; ++$per) { - $depreciation = min( ($cost - $previousDepreciation) * ($factor / $life), ($cost - $salvage - $previousDepreciation) ); - $previousDepreciation += $depreciation; - } - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - $depreciation = round($depreciation,2); - } - return $depreciation; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function DDB() - - - /** - * DISC - * - * Returns the discount rate for a security. - * - * Excel Function: - * DISC(settlement,maturity,price,redemption[,basis]) - * - * @access public - * @category Financial Functions - * @param mixed settlement The security's settlement date. - * The security settlement date is the date after the issue - * date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param integer price The security's price per $100 face value. - * @param integer redemption The security's redemption value per $100 face value. - * @param integer basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function DISC($settlement, $maturity, $price, $redemption, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); - $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); - $basis = PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - // Validate - if ((is_numeric($price)) && (is_numeric($redemption)) && (is_numeric($basis))) { - $price = (float) $price; - $redemption = (float) $redemption; - $basis = (int) $basis; - if (($price <= 0) || ($redemption <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); - if (!is_numeric($daysBetweenSettlementAndMaturity)) { - // return date error - return $daysBetweenSettlementAndMaturity; - } - - return ((1 - $price / $redemption) / $daysBetweenSettlementAndMaturity); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function DISC() - - - /** - * DOLLARDE - * - * Converts a dollar price expressed as an integer part and a fraction - * part into a dollar price expressed as a decimal number. - * Fractional dollar numbers are sometimes used for security prices. - * - * Excel Function: - * DOLLARDE(fractional_dollar,fraction) - * - * @access public - * @category Financial Functions - * @param float $fractional_dollar Fractional Dollar - * @param integer $fraction Fraction - * @return float - */ - public static function DOLLARDE($fractional_dollar = Null, $fraction = 0) { - $fractional_dollar = PHPExcel_Calculation_Functions::flattenSingleValue($fractional_dollar); - $fraction = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction); - - // Validate parameters - if (is_null($fractional_dollar) || $fraction < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($fraction == 0) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - $dollars = floor($fractional_dollar); - $cents = fmod($fractional_dollar,1); - $cents /= $fraction; - $cents *= pow(10,ceil(log10($fraction))); - return $dollars + $cents; - } // function DOLLARDE() - - - /** - * DOLLARFR - * - * Converts a dollar price expressed as a decimal number into a dollar price - * expressed as a fraction. - * Fractional dollar numbers are sometimes used for security prices. - * - * Excel Function: - * DOLLARFR(decimal_dollar,fraction) - * - * @access public - * @category Financial Functions - * @param float $decimal_dollar Decimal Dollar - * @param integer $fraction Fraction - * @return float - */ - public static function DOLLARFR($decimal_dollar = Null, $fraction = 0) { - $decimal_dollar = PHPExcel_Calculation_Functions::flattenSingleValue($decimal_dollar); - $fraction = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction); - - // Validate parameters - if (is_null($decimal_dollar) || $fraction < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($fraction == 0) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - $dollars = floor($decimal_dollar); - $cents = fmod($decimal_dollar,1); - $cents *= $fraction; - $cents *= pow(10,-ceil(log10($fraction))); - return $dollars + $cents; - } // function DOLLARFR() - - - /** - * EFFECT - * - * Returns the effective interest rate given the nominal rate and the number of - * compounding payments per year. - * - * Excel Function: - * EFFECT(nominal_rate,npery) - * - * @access public - * @category Financial Functions - * @param float $nominal_rate Nominal interest rate - * @param integer $npery Number of compounding payments per year - * @return float - */ - public static function EFFECT($nominal_rate = 0, $npery = 0) { - $nominal_rate = PHPExcel_Calculation_Functions::flattenSingleValue($nominal_rate); - $npery = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery); - - // Validate parameters - if ($nominal_rate <= 0 || $npery < 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - - return pow((1 + $nominal_rate / $npery), $npery) - 1; - } // function EFFECT() - - - /** - * FV - * - * Returns the Future Value of a cash flow with constant payments and interest rate (annuities). - * - * Excel Function: - * FV(rate,nper,pmt[,pv[,type]]) - * - * @access public - * @category Financial Functions - * @param float $rate The interest rate per period - * @param int $nper Total number of payment periods in an annuity - * @param float $pmt The payment made each period: it cannot change over the - * life of the annuity. Typically, pmt contains principal - * and interest but no other fees or taxes. - * @param float $pv Present Value, or the lump-sum amount that a series of - * future payments is worth right now. - * @param integer $type A number 0 or 1 and indicates when payments are due: - * 0 or omitted At the end of the period. - * 1 At the beginning of the period. - * @return float - */ - public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) { - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); - $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); - $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); - $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); - - // Validate parameters - if ($type != 0 && $type != 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Calculate - if (!is_null($rate) && $rate != 0) { - return -$pv * pow(1 + $rate, $nper) - $pmt * (1 + $rate * $type) * (pow(1 + $rate, $nper) - 1) / $rate; - } else { - return -$pv - $pmt * $nper; - } - } // function FV() - - - /** - * FVSCHEDULE - * - * Returns the future value of an initial principal after applying a series of compound interest rates. - * Use FVSCHEDULE to calculate the future value of an investment with a variable or adjustable rate. - * - * Excel Function: - * FVSCHEDULE(principal,schedule) - * - * @param float $principal The present value. - * @param float[] $schedule An array of interest rates to apply. - * @return float - */ - public static function FVSCHEDULE($principal, $schedule) { - $principal = PHPExcel_Calculation_Functions::flattenSingleValue($principal); - $schedule = PHPExcel_Calculation_Functions::flattenArray($schedule); - - foreach($schedule as $rate) { - $principal *= 1 + $rate; - } - - return $principal; - } // function FVSCHEDULE() - - - /** - * INTRATE - * - * Returns the interest rate for a fully invested security. - * - * Excel Function: - * INTRATE(settlement,maturity,investment,redemption[,basis]) - * - * @param mixed $settlement The security's settlement date. - * The security settlement date is the date after the issue date when the security is traded to the buyer. - * @param mixed $maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param integer $investment The amount invested in the security. - * @param integer $redemption The amount to be received at maturity. - * @param integer $basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function INTRATE($settlement, $maturity, $investment, $redemption, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $investment = PHPExcel_Calculation_Functions::flattenSingleValue($investment); - $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); - $basis = PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - // Validate - if ((is_numeric($investment)) && (is_numeric($redemption)) && (is_numeric($basis))) { - $investment = (float) $investment; - $redemption = (float) $redemption; - $basis = (int) $basis; - if (($investment <= 0) || ($redemption <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); - if (!is_numeric($daysBetweenSettlementAndMaturity)) { - // return date error - return $daysBetweenSettlementAndMaturity; - } - - return (($redemption / $investment) - 1) / ($daysBetweenSettlementAndMaturity); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function INTRATE() - - - /** - * IPMT - * - * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate. - * - * Excel Function: - * IPMT(rate,per,nper,pv[,fv][,type]) - * - * @param float $rate Interest rate per period - * @param int $per Period for which we want to find the interest - * @param int $nper Number of periods - * @param float $pv Present Value - * @param float $fv Future Value - * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period - * @return float - */ - public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $per = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per); - $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); - $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); - $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); - $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); - - // Validate parameters - if ($type != 0 && $type != 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($per <= 0 || $per > $nper) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - // Calculate - $interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); - return $interestAndPrincipal[0]; - } // function IPMT() - - /** - * IRR - * - * Returns the internal rate of return for a series of cash flows represented by the numbers in values. - * These cash flows do not have to be even, as they would be for an annuity. However, the cash flows must occur - * at regular intervals, such as monthly or annually. The internal rate of return is the interest rate received - * for an investment consisting of payments (negative values) and income (positive values) that occur at regular - * periods. - * - * Excel Function: - * IRR(values[,guess]) - * - * @param float[] $values An array or a reference to cells that contain numbers for which you want - * to calculate the internal rate of return. - * Values must contain at least one positive value and one negative value to - * calculate the internal rate of return. - * @param float $guess A number that you guess is close to the result of IRR - * @return float - */ - public static function IRR($values, $guess = 0.1) { - if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); - $values = PHPExcel_Calculation_Functions::flattenArray($values); - $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); - - // create an initial range, with a root somewhere between 0 and guess - $x1 = 0.0; - $x2 = $guess; - $f1 = self::NPV($x1, $values); - $f2 = self::NPV($x2, $values); - for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { - if (($f1 * $f2) < 0.0) break; - if (abs($f1) < abs($f2)) { - $f1 = self::NPV($x1 += 1.6 * ($x1 - $x2), $values); - } else { - $f2 = self::NPV($x2 += 1.6 * ($x2 - $x1), $values); - } - } - if (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE(); - - $f = self::NPV($x1, $values); - if ($f < 0.0) { - $rtb = $x1; - $dx = $x2 - $x1; - } else { - $rtb = $x2; - $dx = $x1 - $x2; - } - - for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { - $dx *= 0.5; - $x_mid = $rtb + $dx; - $f_mid = self::NPV($x_mid, $values); - if ($f_mid <= 0.0) - $rtb = $x_mid; - if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) - return $x_mid; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function IRR() - - - /** - * ISPMT - * - * Returns the interest payment for an investment based on an interest rate and a constant payment schedule. - * - * Excel Function: - * =ISPMT(interest_rate, period, number_payments, PV) - * - * interest_rate is the interest rate for the investment - * - * period is the period to calculate the interest rate. It must be betweeen 1 and number_payments. - * - * number_payments is the number of payments for the annuity - * - * PV is the loan amount or present value of the payments - */ - public static function ISPMT() { - // Return value - $returnValue = 0; - - // Get the parameters - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - $interestRate = array_shift($aArgs); - $period = array_shift($aArgs); - $numberPeriods = array_shift($aArgs); - $principleRemaining = array_shift($aArgs); - - // Calculate - $principlePayment = ($principleRemaining * 1.0) / ($numberPeriods * 1.0); - for($i=0; $i <= $period; ++$i) { - $returnValue = $interestRate * $principleRemaining * -1; - $principleRemaining -= $principlePayment; - // principle needs to be 0 after the last payment, don't let floating point screw it up - if($i == $numberPeriods) { - $returnValue = 0; - } - } - return($returnValue); - } // function ISPMT() - - - /** - * MIRR - * - * Returns the modified internal rate of return for a series of periodic cash flows. MIRR considers both - * the cost of the investment and the interest received on reinvestment of cash. - * - * Excel Function: - * MIRR(values,finance_rate, reinvestment_rate) - * - * @param float[] $values An array or a reference to cells that contain a series of payments and - * income occurring at regular intervals. - * Payments are negative value, income is positive values. - * @param float $finance_rate The interest rate you pay on the money used in the cash flows - * @param float $reinvestment_rate The interest rate you receive on the cash flows as you reinvest them - * @return float - */ - public static function MIRR($values, $finance_rate, $reinvestment_rate) { - if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); - $values = PHPExcel_Calculation_Functions::flattenArray($values); - $finance_rate = PHPExcel_Calculation_Functions::flattenSingleValue($finance_rate); - $reinvestment_rate = PHPExcel_Calculation_Functions::flattenSingleValue($reinvestment_rate); - $n = count($values); - - $rr = 1.0 + $reinvestment_rate; - $fr = 1.0 + $finance_rate; - - $npv_pos = $npv_neg = 0.0; - foreach($values as $i => $v) { - if ($v >= 0) { - $npv_pos += $v / pow($rr, $i); - } else { - $npv_neg += $v / pow($fr, $i); - } - } - - if (($npv_neg == 0) || ($npv_pos == 0) || ($reinvestment_rate <= -1)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - $mirr = pow((-$npv_pos * pow($rr, $n)) - / ($npv_neg * ($rr)), (1.0 / ($n - 1))) - 1.0; - - return (is_finite($mirr) ? $mirr : PHPExcel_Calculation_Functions::VALUE()); - } // function MIRR() - - - /** - * NOMINAL - * - * Returns the nominal interest rate given the effective rate and the number of compounding payments per year. - * - * @param float $effect_rate Effective interest rate - * @param int $npery Number of compounding payments per year - * @return float - */ - public static function NOMINAL($effect_rate = 0, $npery = 0) { - $effect_rate = PHPExcel_Calculation_Functions::flattenSingleValue($effect_rate); - $npery = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery); - - // Validate parameters - if ($effect_rate <= 0 || $npery < 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Calculate - return $npery * (pow($effect_rate + 1, 1 / $npery) - 1); - } // function NOMINAL() - - - /** - * NPER - * - * Returns the number of periods for a cash flow with constant periodic payments (annuities), and interest rate. - * - * @param float $rate Interest rate per period - * @param int $pmt Periodic payment (annuity) - * @param float $pv Present Value - * @param float $fv Future Value - * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period - * @return float - */ - public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) { - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); - $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); - $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); - $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); - - // Validate parameters - if ($type != 0 && $type != 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Calculate - if (!is_null($rate) && $rate != 0) { - if ($pmt == 0 && $pv == 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - return log(($pmt * (1 + $rate * $type) / $rate - $fv) / ($pv + $pmt * (1 + $rate * $type) / $rate)) / log(1 + $rate); - } else { - if ($pmt == 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - return (-$pv -$fv) / $pmt; - } - } // function NPER() - - /** - * NPV - * - * Returns the Net Present Value of a cash flow series given a discount rate. - * - * @return float - */ - public static function NPV() { - // Return value - $returnValue = 0; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - - // Calculate - $rate = array_shift($aArgs); - for ($i = 1; $i <= count($aArgs); ++$i) { - // Is it a numeric value? - if (is_numeric($aArgs[$i - 1])) { - $returnValue += $aArgs[$i - 1] / pow(1 + $rate, $i); - } - } - - // Return - return $returnValue; - } // function NPV() - - /** - * PMT - * - * Returns the constant payment (annuity) for a cash flow with a constant interest rate. - * - * @param float $rate Interest rate per period - * @param int $nper Number of periods - * @param float $pv Present Value - * @param float $fv Future Value - * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period - * @return float - */ - public static function PMT($rate = 0, $nper = 0, $pv = 0, $fv = 0, $type = 0) { - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); - $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); - $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); - $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); - - // Validate parameters - if ($type != 0 && $type != 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Calculate - if (!is_null($rate) && $rate != 0) { - return (-$fv - $pv * pow(1 + $rate, $nper)) / (1 + $rate * $type) / ((pow(1 + $rate, $nper) - 1) / $rate); - } else { - return (-$pv - $fv) / $nper; - } - } // function PMT() - - - /** - * PPMT - * - * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate. - * - * @param float $rate Interest rate per period - * @param int $per Period for which we want to find the interest - * @param int $nper Number of periods - * @param float $pv Present Value - * @param float $fv Future Value - * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period - * @return float - */ - public static function PPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $per = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per); - $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); - $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); - $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); - $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); - - // Validate parameters - if ($type != 0 && $type != 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($per <= 0 || $per > $nper) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - // Calculate - $interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); - return $interestAndPrincipal[1]; - } // function PPMT() - - - public static function PRICE($settlement, $maturity, $rate, $yield, $redemption, $frequency, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $rate = (float) PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $yield = (float) PHPExcel_Calculation_Functions::flattenSingleValue($yield); - $redemption = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption); - $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || - (($basis < 0) || ($basis > 4))) { - return PHPExcel_Calculation_Functions::NaN(); - } - - $dsc = self::COUPDAYSNC($settlement, $maturity, $frequency, $basis); - $e = self::COUPDAYS($settlement, $maturity, $frequency, $basis); - $n = self::COUPNUM($settlement, $maturity, $frequency, $basis); - $a = self::COUPDAYBS($settlement, $maturity, $frequency, $basis); - - $baseYF = 1.0 + ($yield / $frequency); - $rfp = 100 * ($rate / $frequency); - $de = $dsc / $e; - - $result = $redemption / pow($baseYF, (--$n + $de)); - for($k = 0; $k <= $n; ++$k) { - $result += $rfp / (pow($baseYF, ($k + $de))); - } - $result -= $rfp * ($a / $e); - - return $result; - } // function PRICE() - - - /** - * PRICEDISC - * - * Returns the price per $100 face value of a discounted security. - * - * @param mixed settlement The security's settlement date. - * The security settlement date is the date after the issue date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param int discount The security's discount rate. - * @param int redemption The security's redemption value per $100 face value. - * @param int basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function PRICEDISC($settlement, $maturity, $discount, $redemption, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $discount = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount); - $redemption = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption); - $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - // Validate - if ((is_numeric($discount)) && (is_numeric($redemption)) && (is_numeric($basis))) { - if (($discount <= 0) || ($redemption <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); - if (!is_numeric($daysBetweenSettlementAndMaturity)) { - // return date error - return $daysBetweenSettlementAndMaturity; - } - - return $redemption * (1 - $discount * $daysBetweenSettlementAndMaturity); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function PRICEDISC() - - - /** - * PRICEMAT - * - * Returns the price per $100 face value of a security that pays interest at maturity. - * - * @param mixed settlement The security's settlement date. - * The security's settlement date is the date after the issue date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param mixed issue The security's issue date. - * @param int rate The security's interest rate at date of issue. - * @param int yield The security's annual yield. - * @param int basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function PRICEMAT($settlement, $maturity, $issue, $rate, $yield, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $yield = PHPExcel_Calculation_Functions::flattenSingleValue($yield); - $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - // Validate - if (is_numeric($rate) && is_numeric($yield)) { - if (($rate <= 0) || ($yield <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); - if (!is_numeric($daysPerYear)) { - return $daysPerYear; - } - $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); - if (!is_numeric($daysBetweenIssueAndSettlement)) { - // return date error - return $daysBetweenIssueAndSettlement; - } - $daysBetweenIssueAndSettlement *= $daysPerYear; - $daysBetweenIssueAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $maturity, $basis); - if (!is_numeric($daysBetweenIssueAndMaturity)) { - // return date error - return $daysBetweenIssueAndMaturity; - } - $daysBetweenIssueAndMaturity *= $daysPerYear; - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); - if (!is_numeric($daysBetweenSettlementAndMaturity)) { - // return date error - return $daysBetweenSettlementAndMaturity; - } - $daysBetweenSettlementAndMaturity *= $daysPerYear; - - return ((100 + (($daysBetweenIssueAndMaturity / $daysPerYear) * $rate * 100)) / - (1 + (($daysBetweenSettlementAndMaturity / $daysPerYear) * $yield)) - - (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate * 100)); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function PRICEMAT() - - - /** - * PV - * - * Returns the Present Value of a cash flow with constant payments and interest rate (annuities). - * - * @param float $rate Interest rate per period - * @param int $nper Number of periods - * @param float $pmt Periodic payment (annuity) - * @param float $fv Future Value - * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period - * @return float - */ - public static function PV($rate = 0, $nper = 0, $pmt = 0, $fv = 0, $type = 0) { - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); - $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); - $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); - $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); - - // Validate parameters - if ($type != 0 && $type != 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - - // Calculate - if (!is_null($rate) && $rate != 0) { - return (-$pmt * (1 + $rate * $type) * ((pow(1 + $rate, $nper) - 1) / $rate) - $fv) / pow(1 + $rate, $nper); - } else { - return -$fv - $pmt * $nper; - } - } // function PV() - - - /** - * RATE - * - * Returns the interest rate per period of an annuity. - * RATE is calculated by iteration and can have zero or more solutions. - * If the successive results of RATE do not converge to within 0.0000001 after 20 iterations, - * RATE returns the #NUM! error value. - * - * Excel Function: - * RATE(nper,pmt,pv[,fv[,type[,guess]]]) - * - * @access public - * @category Financial Functions - * @param float nper The total number of payment periods in an annuity. - * @param float pmt The payment made each period and cannot change over the life - * of the annuity. - * Typically, pmt includes principal and interest but no other - * fees or taxes. - * @param float pv The present value - the total amount that a series of future - * payments is worth now. - * @param float fv The future value, or a cash balance you want to attain after - * the last payment is made. If fv is omitted, it is assumed - * to be 0 (the future value of a loan, for example, is 0). - * @param integer type A number 0 or 1 and indicates when payments are due: - * 0 or omitted At the end of the period. - * 1 At the beginning of the period. - * @param float guess Your guess for what the rate will be. - * If you omit guess, it is assumed to be 10 percent. - * @return float - **/ - public static function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) { - $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); - $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); - $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); - $fv = (is_null($fv)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($fv); - $type = (is_null($type)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); - $guess = (is_null($guess)) ? 0.1 : PHPExcel_Calculation_Functions::flattenSingleValue($guess); - - $rate = $guess; - if (abs($rate) < FINANCIAL_PRECISION) { - $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; - } else { - $f = exp($nper * log(1 + $rate)); - $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; - } - $y0 = $pv + $pmt * $nper + $fv; - $y1 = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; - - // find root by secant method - $i = $x0 = 0.0; - $x1 = $rate; - while ((abs($y0 - $y1) > FINANCIAL_PRECISION) && ($i < FINANCIAL_MAX_ITERATIONS)) { - $rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0); - $x0 = $x1; - $x1 = $rate; - if (($nper * abs($pmt)) > ($pv - $fv)) - $x1 = abs($x1); - - if (abs($rate) < FINANCIAL_PRECISION) { - $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; - } else { - $f = exp($nper * log(1 + $rate)); - $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; - } - - $y0 = $y1; - $y1 = $y; - ++$i; - } - return $rate; - } // function RATE() - - - /** - * RECEIVED - * - * Returns the price per $100 face value of a discounted security. - * - * @param mixed settlement The security's settlement date. - * The security settlement date is the date after the issue date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param int investment The amount invested in the security. - * @param int discount The security's discount rate. - * @param int basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function RECEIVED($settlement, $maturity, $investment, $discount, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $investment = (float) PHPExcel_Calculation_Functions::flattenSingleValue($investment); - $discount = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount); - $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - // Validate - if ((is_numeric($investment)) && (is_numeric($discount)) && (is_numeric($basis))) { - if (($investment <= 0) || ($discount <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); - if (!is_numeric($daysBetweenSettlementAndMaturity)) { - // return date error - return $daysBetweenSettlementAndMaturity; - } - - return $investment / ( 1 - ($discount * $daysBetweenSettlementAndMaturity)); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function RECEIVED() - - - /** - * SLN - * - * Returns the straight-line depreciation of an asset for one period - * - * @param cost Initial cost of the asset - * @param salvage Value at the end of the depreciation - * @param life Number of periods over which the asset is depreciated - * @return float - */ - public static function SLN($cost, $salvage, $life) { - $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); - $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); - $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); - - // Calculate - if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life))) { - if ($life < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - return ($cost - $salvage) / $life; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function SLN() - - - /** - * SYD - * - * Returns the sum-of-years' digits depreciation of an asset for a specified period. - * - * @param cost Initial cost of the asset - * @param salvage Value at the end of the depreciation - * @param life Number of periods over which the asset is depreciated - * @param period Period - * @return float - */ - public static function SYD($cost, $salvage, $life, $period) { - $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); - $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); - $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); - $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); - - // Calculate - if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period))) { - if (($life < 1) || ($period > $life)) { - return PHPExcel_Calculation_Functions::NaN(); - } - return (($cost - $salvage) * ($life - $period + 1) * 2) / ($life * ($life + 1)); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function SYD() - - - /** - * TBILLEQ - * - * Returns the bond-equivalent yield for a Treasury bill. - * - * @param mixed settlement The Treasury bill's settlement date. - * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. - * @param mixed maturity The Treasury bill's maturity date. - * The maturity date is the date when the Treasury bill expires. - * @param int discount The Treasury bill's discount rate. - * @return float - */ - public static function TBILLEQ($settlement, $maturity, $discount) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $discount = PHPExcel_Calculation_Functions::flattenSingleValue($discount); - - // Use TBILLPRICE for validation - $testValue = self::TBILLPRICE($settlement, $maturity, $discount); - if (is_string($testValue)) { - return $testValue; - } - - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - ++$maturity; - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; - } else { - $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); - } - - return (365 * $discount) / (360 - $discount * $daysBetweenSettlementAndMaturity); - } // function TBILLEQ() - - - /** - * TBILLPRICE - * - * Returns the yield for a Treasury bill. - * - * @param mixed settlement The Treasury bill's settlement date. - * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. - * @param mixed maturity The Treasury bill's maturity date. - * The maturity date is the date when the Treasury bill expires. - * @param int discount The Treasury bill's discount rate. - * @return float - */ - public static function TBILLPRICE($settlement, $maturity, $discount) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $discount = PHPExcel_Calculation_Functions::flattenSingleValue($discount); - - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - // Validate - if (is_numeric($discount)) { - if ($discount <= 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - ++$maturity; - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; - if (!is_numeric($daysBetweenSettlementAndMaturity)) { - // return date error - return $daysBetweenSettlementAndMaturity; - } - } else { - $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); - } - - if ($daysBetweenSettlementAndMaturity > 360) { - return PHPExcel_Calculation_Functions::NaN(); - } - - $price = 100 * (1 - (($discount * $daysBetweenSettlementAndMaturity) / 360)); - if ($price <= 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - return $price; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function TBILLPRICE() - - - /** - * TBILLYIELD - * - * Returns the yield for a Treasury bill. - * - * @param mixed settlement The Treasury bill's settlement date. - * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. - * @param mixed maturity The Treasury bill's maturity date. - * The maturity date is the date when the Treasury bill expires. - * @param int price The Treasury bill's price per $100 face value. - * @return float - */ - public static function TBILLYIELD($settlement, $maturity, $price) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); - - // Validate - if (is_numeric($price)) { - if ($price <= 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - ++$maturity; - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; - if (!is_numeric($daysBetweenSettlementAndMaturity)) { - // return date error - return $daysBetweenSettlementAndMaturity; - } - } else { - $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); - } - - if ($daysBetweenSettlementAndMaturity > 360) { - return PHPExcel_Calculation_Functions::NaN(); - } - - return ((100 - $price) / $price) * (360 / $daysBetweenSettlementAndMaturity); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function TBILLYIELD() - - - public static function XIRR($values, $dates, $guess = 0.1) { - if ((!is_array($values)) && (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE(); - $values = PHPExcel_Calculation_Functions::flattenArray($values); - $dates = PHPExcel_Calculation_Functions::flattenArray($dates); - $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); - if (count($values) != count($dates)) return PHPExcel_Calculation_Functions::NaN(); - - // create an initial range, with a root somewhere between 0 and guess - $x1 = 0.0; - $x2 = $guess; - $f1 = self::XNPV($x1, $values, $dates); - $f2 = self::XNPV($x2, $values, $dates); - for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { - if (($f1 * $f2) < 0.0) break; - if (abs($f1) < abs($f2)) { - $f1 = self::XNPV($x1 += 1.6 * ($x1 - $x2), $values, $dates); - } else { - $f2 = self::XNPV($x2 += 1.6 * ($x2 - $x1), $values, $dates); - } - } - if (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE(); - - $f = self::XNPV($x1, $values, $dates); - if ($f < 0.0) { - $rtb = $x1; - $dx = $x2 - $x1; - } else { - $rtb = $x2; - $dx = $x1 - $x2; - } - - for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { - $dx *= 0.5; - $x_mid = $rtb + $dx; - $f_mid = self::XNPV($x_mid, $values, $dates); - if ($f_mid <= 0.0) $rtb = $x_mid; - if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) return $x_mid; - } - return PHPExcel_Calculation_Functions::VALUE(); - } - - - /** - * XNPV - * - * Returns the net present value for a schedule of cash flows that is not necessarily periodic. - * To calculate the net present value for a series of cash flows that is periodic, use the NPV function. - * - * Excel Function: - * =XNPV(rate,values,dates) - * - * @param float $rate The discount rate to apply to the cash flows. - * @param array of float $values A series of cash flows that corresponds to a schedule of payments in dates. The first payment is optional and corresponds to a cost or payment that occurs at the beginning of the investment. If the first value is a cost or payment, it must be a negative value. All succeeding payments are discounted based on a 365-day year. The series of values must contain at least one positive value and one negative value. - * @param array of mixed $dates A schedule of payment dates that corresponds to the cash flow payments. The first payment date indicates the beginning of the schedule of payments. All other dates must be later than this date, but they may occur in any order. - * @return float - */ - public static function XNPV($rate, $values, $dates) { - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - if (!is_numeric($rate)) return PHPExcel_Calculation_Functions::VALUE(); - if ((!is_array($values)) || (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE(); - $values = PHPExcel_Calculation_Functions::flattenArray($values); - $dates = PHPExcel_Calculation_Functions::flattenArray($dates); - $valCount = count($values); - if ($valCount != count($dates)) return PHPExcel_Calculation_Functions::NaN(); - if ((min($values) > 0) || (max($values) < 0)) return PHPExcel_Calculation_Functions::VALUE(); - - $xnpv = 0.0; - for ($i = 0; $i < $valCount; ++$i) { - if (!is_numeric($values[$i])) return PHPExcel_Calculation_Functions::VALUE(); - $xnpv += $values[$i] / pow(1 + $rate, PHPExcel_Calculation_DateTime::DATEDIF($dates[0],$dates[$i],'d') / 365); - } - return (is_finite($xnpv)) ? $xnpv : PHPExcel_Calculation_Functions::VALUE(); - } // function XNPV() - - - /** - * YIELDDISC - * - * Returns the annual yield of a security that pays interest at maturity. - * - * @param mixed settlement The security's settlement date. - * The security's settlement date is the date after the issue date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param int price The security's price per $100 face value. - * @param int redemption The security's redemption value per $100 face value. - * @param int basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function YIELDDISC($settlement, $maturity, $price, $redemption, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); - $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); - $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - // Validate - if (is_numeric($price) && is_numeric($redemption)) { - if (($price <= 0) || ($redemption <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); - if (!is_numeric($daysPerYear)) { - return $daysPerYear; - } - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity,$basis); - if (!is_numeric($daysBetweenSettlementAndMaturity)) { - // return date error - return $daysBetweenSettlementAndMaturity; - } - $daysBetweenSettlementAndMaturity *= $daysPerYear; - - return (($redemption - $price) / $price) * ($daysPerYear / $daysBetweenSettlementAndMaturity); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function YIELDDISC() - - - /** - * YIELDMAT - * - * Returns the annual yield of a security that pays interest at maturity. - * - * @param mixed settlement The security's settlement date. - * The security's settlement date is the date after the issue date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param mixed issue The security's issue date. - * @param int rate The security's interest rate at date of issue. - * @param int price The security's price per $100 face value. - * @param int basis The type of day count to use. - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * @return float - */ - public static function YIELDMAT($settlement, $maturity, $issue, $rate, $price, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); - $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - - // Validate - if (is_numeric($rate) && is_numeric($price)) { - if (($rate <= 0) || ($price <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); - if (!is_numeric($daysPerYear)) { - return $daysPerYear; - } - $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); - if (!is_numeric($daysBetweenIssueAndSettlement)) { - // return date error - return $daysBetweenIssueAndSettlement; - } - $daysBetweenIssueAndSettlement *= $daysPerYear; - $daysBetweenIssueAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $maturity, $basis); - if (!is_numeric($daysBetweenIssueAndMaturity)) { - // return date error - return $daysBetweenIssueAndMaturity; - } - $daysBetweenIssueAndMaturity *= $daysPerYear; - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); - if (!is_numeric($daysBetweenSettlementAndMaturity)) { - // return date error - return $daysBetweenSettlementAndMaturity; - } - $daysBetweenSettlementAndMaturity *= $daysPerYear; - - return ((1 + (($daysBetweenIssueAndMaturity / $daysPerYear) * $rate) - (($price / 100) + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate))) / - (($price / 100) + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate))) * - ($daysPerYear / $daysBetweenSettlementAndMaturity); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function YIELDMAT() - -} // class PHPExcel_Calculation_Financial + } else { + return 0.0; + } + } // function AMORLINC() + + + /** + * COUPDAYBS + * + * Returns the number of days from the beginning of the coupon period to the settlement date. + * + * Excel Function: + * COUPDAYBS(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function COUPDAYBS($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + $prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); + + return PHPExcel_Calculation_DateTime::YEARFRAC($prev, $settlement, $basis) * $daysPerYear; + } // function COUPDAYBS() + + + /** + * COUPDAYS + * + * Returns the number of days in the coupon period that contains the settlement date. + * + * Excel Function: + * COUPDAYS(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function COUPDAYS($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + switch ($basis) { + case 3: // Actual/365 + return 365 / $frequency; + case 1: // Actual/actual + if ($frequency == 1) { + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($maturity),$basis); + return ($daysPerYear / $frequency); + } else { + $prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); + $next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + return ($next - $prev); + } + default: // US (NASD) 30/360, Actual/360 or European 30/360 + return 360 / $frequency; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function COUPDAYS() + + + /** + * COUPDAYSNC + * + * Returns the number of days from the settlement date to the next coupon date. + * + * Excel Function: + * COUPDAYSNC(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function COUPDAYSNC($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + $next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + + return PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $next, $basis) * $daysPerYear; + } // function COUPDAYSNC() + + + /** + * COUPNCD + * + * Returns the next coupon date after the settlement date. + * + * Excel Function: + * COUPNCD(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function COUPNCD($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + } // function COUPNCD() + + + /** + * COUPNUM + * + * Returns the number of coupons payable between the settlement date and maturity date, + * rounded up to the nearest whole coupon. + * + * Excel Function: + * COUPNUM(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return integer + */ + public static function COUPNUM($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $settlement = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis) * 365; + + switch ($frequency) { + case 1: // annual payments + return ceil($daysBetweenSettlementAndMaturity / 360); + case 2: // half-yearly + return ceil($daysBetweenSettlementAndMaturity / 180); + case 4: // quarterly + return ceil($daysBetweenSettlementAndMaturity / 90); + case 6: // bimonthly + return ceil($daysBetweenSettlementAndMaturity / 60); + case 12: // monthly + return ceil($daysBetweenSettlementAndMaturity / 30); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function COUPNUM() + + + /** + * COUPPCD + * + * Returns the previous coupon date before the settlement date. + * + * Excel Function: + * COUPPCD(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function COUPPCD($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); + } // function COUPPCD() + + + /** + * CUMIPMT + * + * Returns the cumulative interest paid on a loan between the start and end periods. + * + * Excel Function: + * CUMIPMT(rate,nper,pv,start,end[,type]) + * + * @access public + * @category Financial Functions + * @param float $rate The Interest rate + * @param integer $nper The total number of payment periods + * @param float $pv Present Value + * @param integer $start The first period in the calculation. + * Payment periods are numbered beginning with 1. + * @param integer $end The last period in the calculation. + * @param integer $type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @return float + */ + public static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $start = (int) PHPExcel_Calculation_Functions::flattenSingleValue($start); + $end = (int) PHPExcel_Calculation_Functions::flattenSingleValue($end); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($start < 1 || $start > $end) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $interest = 0; + for ($per = $start; $per <= $end; ++$per) { + $interest += self::IPMT($rate, $per, $nper, $pv, 0, $type); + } + + return $interest; + } // function CUMIPMT() + + + /** + * CUMPRINC + * + * Returns the cumulative principal paid on a loan between the start and end periods. + * + * Excel Function: + * CUMPRINC(rate,nper,pv,start,end[,type]) + * + * @access public + * @category Financial Functions + * @param float $rate The Interest rate + * @param integer $nper The total number of payment periods + * @param float $pv Present Value + * @param integer $start The first period in the calculation. + * Payment periods are numbered beginning with 1. + * @param integer $end The last period in the calculation. + * @param integer $type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @return float + */ + public static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $start = (int) PHPExcel_Calculation_Functions::flattenSingleValue($start); + $end = (int) PHPExcel_Calculation_Functions::flattenSingleValue($end); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($start < 1 || $start > $end) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $principal = 0; + for ($per = $start; $per <= $end; ++$per) { + $principal += self::PPMT($rate, $per, $nper, $pv, 0, $type); + } + + return $principal; + } // function CUMPRINC() + + + /** + * DB + * + * Returns the depreciation of an asset for a specified period using the + * fixed-declining balance method. + * This form of depreciation is used if you want to get a higher depreciation value + * at the beginning of the depreciation (as opposed to linear depreciation). The + * depreciation value is reduced with every depreciation period by the depreciation + * already deducted from the initial cost. + * + * Excel Function: + * DB(cost,salvage,life,period[,month]) + * + * @access public + * @category Financial Functions + * @param float cost Initial cost of the asset. + * @param float salvage Value at the end of the depreciation. + * (Sometimes called the salvage value of the asset) + * @param integer life Number of periods over which the asset is depreciated. + * (Sometimes called the useful life of the asset) + * @param integer period The period for which you want to calculate the + * depreciation. Period must use the same units as life. + * @param integer month Number of months in the first year. If month is omitted, + * it defaults to 12. + * @return float + */ + public static function DB($cost, $salvage, $life, $period, $month=12) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + $month = PHPExcel_Calculation_Functions::flattenSingleValue($month); + + // Validate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($month))) { + $cost = (float) $cost; + $salvage = (float) $salvage; + $life = (int) $life; + $period = (int) $period; + $month = (int) $month; + if ($cost == 0) { + return 0.0; + } elseif (($cost < 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($month < 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + // Set Fixed Depreciation Rate + $fixedDepreciationRate = 1 - pow(($salvage / $cost), (1 / $life)); + $fixedDepreciationRate = round($fixedDepreciationRate, 3); + + // Loop through each period calculating the depreciation + $previousDepreciation = 0; + for ($per = 1; $per <= $period; ++$per) { + if ($per == 1) { + $depreciation = $cost * $fixedDepreciationRate * $month / 12; + } elseif ($per == ($life + 1)) { + $depreciation = ($cost - $previousDepreciation) * $fixedDepreciationRate * (12 - $month) / 12; + } else { + $depreciation = ($cost - $previousDepreciation) * $fixedDepreciationRate; + } + $previousDepreciation += $depreciation; + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $depreciation = round($depreciation,2); + } + return $depreciation; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DB() + + + /** + * DDB + * + * Returns the depreciation of an asset for a specified period using the + * double-declining balance method or some other method you specify. + * + * Excel Function: + * DDB(cost,salvage,life,period[,factor]) + * + * @access public + * @category Financial Functions + * @param float cost Initial cost of the asset. + * @param float salvage Value at the end of the depreciation. + * (Sometimes called the salvage value of the asset) + * @param integer life Number of periods over which the asset is depreciated. + * (Sometimes called the useful life of the asset) + * @param integer period The period for which you want to calculate the + * depreciation. Period must use the same units as life. + * @param float factor The rate at which the balance declines. + * If factor is omitted, it is assumed to be 2 (the + * double-declining balance method). + * @return float + */ + public static function DDB($cost, $salvage, $life, $period, $factor=2.0) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + $factor = PHPExcel_Calculation_Functions::flattenSingleValue($factor); + + // Validate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($factor))) { + $cost = (float) $cost; + $salvage = (float) $salvage; + $life = (int) $life; + $period = (int) $period; + $factor = (float) $factor; + if (($cost <= 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($factor <= 0.0) || ($period > $life)) { + return PHPExcel_Calculation_Functions::NaN(); + } + // Set Fixed Depreciation Rate + $fixedDepreciationRate = 1 - pow(($salvage / $cost), (1 / $life)); + $fixedDepreciationRate = round($fixedDepreciationRate, 3); + + // Loop through each period calculating the depreciation + $previousDepreciation = 0; + for ($per = 1; $per <= $period; ++$per) { + $depreciation = min( ($cost - $previousDepreciation) * ($factor / $life), ($cost - $salvage - $previousDepreciation) ); + $previousDepreciation += $depreciation; + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $depreciation = round($depreciation,2); + } + return $depreciation; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DDB() + + + /** + * DISC + * + * Returns the discount rate for a security. + * + * Excel Function: + * DISC(settlement,maturity,price,redemption[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param integer price The security's price per $100 face value. + * @param integer redemption The security's redemption value per $100 face value. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function DISC($settlement, $maturity, $price, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($price)) && (is_numeric($redemption)) && (is_numeric($basis))) { + $price = (float) $price; + $redemption = (float) $redemption; + $basis = (int) $basis; + if (($price <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return ((1 - $price / $redemption) / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DISC() + + + /** + * DOLLARDE + * + * Converts a dollar price expressed as an integer part and a fraction + * part into a dollar price expressed as a decimal number. + * Fractional dollar numbers are sometimes used for security prices. + * + * Excel Function: + * DOLLARDE(fractional_dollar,fraction) + * + * @access public + * @category Financial Functions + * @param float $fractional_dollar Fractional Dollar + * @param integer $fraction Fraction + * @return float + */ + public static function DOLLARDE($fractional_dollar = Null, $fraction = 0) { + $fractional_dollar = PHPExcel_Calculation_Functions::flattenSingleValue($fractional_dollar); + $fraction = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction); + + // Validate parameters + if (is_null($fractional_dollar) || $fraction < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($fraction == 0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $dollars = floor($fractional_dollar); + $cents = fmod($fractional_dollar,1); + $cents /= $fraction; + $cents *= pow(10,ceil(log10($fraction))); + return $dollars + $cents; + } // function DOLLARDE() + + + /** + * DOLLARFR + * + * Converts a dollar price expressed as a decimal number into a dollar price + * expressed as a fraction. + * Fractional dollar numbers are sometimes used for security prices. + * + * Excel Function: + * DOLLARFR(decimal_dollar,fraction) + * + * @access public + * @category Financial Functions + * @param float $decimal_dollar Decimal Dollar + * @param integer $fraction Fraction + * @return float + */ + public static function DOLLARFR($decimal_dollar = Null, $fraction = 0) { + $decimal_dollar = PHPExcel_Calculation_Functions::flattenSingleValue($decimal_dollar); + $fraction = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction); + + // Validate parameters + if (is_null($decimal_dollar) || $fraction < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($fraction == 0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $dollars = floor($decimal_dollar); + $cents = fmod($decimal_dollar,1); + $cents *= $fraction; + $cents *= pow(10,-ceil(log10($fraction))); + return $dollars + $cents; + } // function DOLLARFR() + + + /** + * EFFECT + * + * Returns the effective interest rate given the nominal rate and the number of + * compounding payments per year. + * + * Excel Function: + * EFFECT(nominal_rate,npery) + * + * @access public + * @category Financial Functions + * @param float $nominal_rate Nominal interest rate + * @param integer $npery Number of compounding payments per year + * @return float + */ + public static function EFFECT($nominal_rate = 0, $npery = 0) { + $nominal_rate = PHPExcel_Calculation_Functions::flattenSingleValue($nominal_rate); + $npery = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery); + + // Validate parameters + if ($nominal_rate <= 0 || $npery < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return pow((1 + $nominal_rate / $npery), $npery) - 1; + } // function EFFECT() + + + /** + * FV + * + * Returns the Future Value of a cash flow with constant payments and interest rate (annuities). + * + * Excel Function: + * FV(rate,nper,pmt[,pv[,type]]) + * + * @access public + * @category Financial Functions + * @param float $rate The interest rate per period + * @param int $nper Total number of payment periods in an annuity + * @param float $pmt The payment made each period: it cannot change over the + * life of the annuity. Typically, pmt contains principal + * and interest but no other fees or taxes. + * @param float $pv Present Value, or the lump-sum amount that a series of + * future payments is worth right now. + * @param integer $type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @return float + */ + public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + return -$pv * pow(1 + $rate, $nper) - $pmt * (1 + $rate * $type) * (pow(1 + $rate, $nper) - 1) / $rate; + } else { + return -$pv - $pmt * $nper; + } + } // function FV() + + + /** + * FVSCHEDULE + * + * Returns the future value of an initial principal after applying a series of compound interest rates. + * Use FVSCHEDULE to calculate the future value of an investment with a variable or adjustable rate. + * + * Excel Function: + * FVSCHEDULE(principal,schedule) + * + * @param float $principal The present value. + * @param float[] $schedule An array of interest rates to apply. + * @return float + */ + public static function FVSCHEDULE($principal, $schedule) { + $principal = PHPExcel_Calculation_Functions::flattenSingleValue($principal); + $schedule = PHPExcel_Calculation_Functions::flattenArray($schedule); + + foreach($schedule as $rate) { + $principal *= 1 + $rate; + } + + return $principal; + } // function FVSCHEDULE() + + + /** + * INTRATE + * + * Returns the interest rate for a fully invested security. + * + * Excel Function: + * INTRATE(settlement,maturity,investment,redemption[,basis]) + * + * @param mixed $settlement The security's settlement date. + * The security settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed $maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param integer $investment The amount invested in the security. + * @param integer $redemption The amount to be received at maturity. + * @param integer $basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function INTRATE($settlement, $maturity, $investment, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $investment = PHPExcel_Calculation_Functions::flattenSingleValue($investment); + $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($investment)) && (is_numeric($redemption)) && (is_numeric($basis))) { + $investment = (float) $investment; + $redemption = (float) $redemption; + $basis = (int) $basis; + if (($investment <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return (($redemption / $investment) - 1) / ($daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function INTRATE() + + + /** + * IPMT + * + * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate. + * + * Excel Function: + * IPMT(rate,per,nper,pv[,fv][,type]) + * + * @param float $rate Interest rate per period + * @param int $per Period for which we want to find the interest + * @param int $nper Number of periods + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $per = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($per <= 0 || $per > $nper) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); + return $interestAndPrincipal[0]; + } // function IPMT() + + /** + * IRR + * + * Returns the internal rate of return for a series of cash flows represented by the numbers in values. + * These cash flows do not have to be even, as they would be for an annuity. However, the cash flows must occur + * at regular intervals, such as monthly or annually. The internal rate of return is the interest rate received + * for an investment consisting of payments (negative values) and income (positive values) that occur at regular + * periods. + * + * Excel Function: + * IRR(values[,guess]) + * + * @param float[] $values An array or a reference to cells that contain numbers for which you want + * to calculate the internal rate of return. + * Values must contain at least one positive value and one negative value to + * calculate the internal rate of return. + * @param float $guess A number that you guess is close to the result of IRR + * @return float + */ + public static function IRR($values, $guess = 0.1) { + if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); + + // create an initial range, with a root somewhere between 0 and guess + $x1 = 0.0; + $x2 = $guess; + $f1 = self::NPV($x1, $values); + $f2 = self::NPV($x2, $values); + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + if (($f1 * $f2) < 0.0) break; + if (abs($f1) < abs($f2)) { + $f1 = self::NPV($x1 += 1.6 * ($x1 - $x2), $values); + } else { + $f2 = self::NPV($x2 += 1.6 * ($x2 - $x1), $values); + } + } + if (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE(); + + $f = self::NPV($x1, $values); + if ($f < 0.0) { + $rtb = $x1; + $dx = $x2 - $x1; + } else { + $rtb = $x2; + $dx = $x1 - $x2; + } + + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + $dx *= 0.5; + $x_mid = $rtb + $dx; + $f_mid = self::NPV($x_mid, $values); + if ($f_mid <= 0.0) + $rtb = $x_mid; + if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) + return $x_mid; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function IRR() + + + /** + * ISPMT + * + * Returns the interest payment for an investment based on an interest rate and a constant payment schedule. + * + * Excel Function: + * =ISPMT(interest_rate, period, number_payments, PV) + * + * interest_rate is the interest rate for the investment + * + * period is the period to calculate the interest rate. It must be betweeen 1 and number_payments. + * + * number_payments is the number of payments for the annuity + * + * PV is the loan amount or present value of the payments + */ + public static function ISPMT() { + // Return value + $returnValue = 0; + + // Get the parameters + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $interestRate = array_shift($aArgs); + $period = array_shift($aArgs); + $numberPeriods = array_shift($aArgs); + $principleRemaining = array_shift($aArgs); + + // Calculate + $principlePayment = ($principleRemaining * 1.0) / ($numberPeriods * 1.0); + for($i=0; $i <= $period; ++$i) { + $returnValue = $interestRate * $principleRemaining * -1; + $principleRemaining -= $principlePayment; + // principle needs to be 0 after the last payment, don't let floating point screw it up + if($i == $numberPeriods) { + $returnValue = 0; + } + } + return($returnValue); + } // function ISPMT() + + + /** + * MIRR + * + * Returns the modified internal rate of return for a series of periodic cash flows. MIRR considers both + * the cost of the investment and the interest received on reinvestment of cash. + * + * Excel Function: + * MIRR(values,finance_rate, reinvestment_rate) + * + * @param float[] $values An array or a reference to cells that contain a series of payments and + * income occurring at regular intervals. + * Payments are negative value, income is positive values. + * @param float $finance_rate The interest rate you pay on the money used in the cash flows + * @param float $reinvestment_rate The interest rate you receive on the cash flows as you reinvest them + * @return float + */ + public static function MIRR($values, $finance_rate, $reinvestment_rate) { + if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $finance_rate = PHPExcel_Calculation_Functions::flattenSingleValue($finance_rate); + $reinvestment_rate = PHPExcel_Calculation_Functions::flattenSingleValue($reinvestment_rate); + $n = count($values); + + $rr = 1.0 + $reinvestment_rate; + $fr = 1.0 + $finance_rate; + + $npv_pos = $npv_neg = 0.0; + foreach($values as $i => $v) { + if ($v >= 0) { + $npv_pos += $v / pow($rr, $i); + } else { + $npv_neg += $v / pow($fr, $i); + } + } + + if (($npv_neg == 0) || ($npv_pos == 0) || ($reinvestment_rate <= -1)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $mirr = pow((-$npv_pos * pow($rr, $n)) + / ($npv_neg * ($rr)), (1.0 / ($n - 1))) - 1.0; + + return (is_finite($mirr) ? $mirr : PHPExcel_Calculation_Functions::VALUE()); + } // function MIRR() + + + /** + * NOMINAL + * + * Returns the nominal interest rate given the effective rate and the number of compounding payments per year. + * + * @param float $effect_rate Effective interest rate + * @param int $npery Number of compounding payments per year + * @return float + */ + public static function NOMINAL($effect_rate = 0, $npery = 0) { + $effect_rate = PHPExcel_Calculation_Functions::flattenSingleValue($effect_rate); + $npery = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery); + + // Validate parameters + if ($effect_rate <= 0 || $npery < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + return $npery * (pow($effect_rate + 1, 1 / $npery) - 1); + } // function NOMINAL() + + + /** + * NPER + * + * Returns the number of periods for a cash flow with constant periodic payments (annuities), and interest rate. + * + * @param float $rate Interest rate per period + * @param int $pmt Periodic payment (annuity) + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + if ($pmt == 0 && $pv == 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return log(($pmt * (1 + $rate * $type) / $rate - $fv) / ($pv + $pmt * (1 + $rate * $type) / $rate)) / log(1 + $rate); + } else { + if ($pmt == 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return (-$pv -$fv) / $pmt; + } + } // function NPER() + + /** + * NPV + * + * Returns the Net Present Value of a cash flow series given a discount rate. + * + * @return float + */ + public static function NPV() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $rate = array_shift($aArgs); + for ($i = 1; $i <= count($aArgs); ++$i) { + // Is it a numeric value? + if (is_numeric($aArgs[$i - 1])) { + $returnValue += $aArgs[$i - 1] / pow(1 + $rate, $i); + } + } + + // Return + return $returnValue; + } // function NPV() + + /** + * PMT + * + * Returns the constant payment (annuity) for a cash flow with a constant interest rate. + * + * @param float $rate Interest rate per period + * @param int $nper Number of periods + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function PMT($rate = 0, $nper = 0, $pv = 0, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + return (-$fv - $pv * pow(1 + $rate, $nper)) / (1 + $rate * $type) / ((pow(1 + $rate, $nper) - 1) / $rate); + } else { + return (-$pv - $fv) / $nper; + } + } // function PMT() + + + /** + * PPMT + * + * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate. + * + * @param float $rate Interest rate per period + * @param int $per Period for which we want to find the interest + * @param int $nper Number of periods + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function PPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $per = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($per <= 0 || $per > $nper) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); + return $interestAndPrincipal[1]; + } // function PPMT() + + + public static function PRICE($settlement, $maturity, $rate, $yield, $redemption, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $rate = (float) PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $yield = (float) PHPExcel_Calculation_Functions::flattenSingleValue($yield); + $redemption = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $dsc = self::COUPDAYSNC($settlement, $maturity, $frequency, $basis); + $e = self::COUPDAYS($settlement, $maturity, $frequency, $basis); + $n = self::COUPNUM($settlement, $maturity, $frequency, $basis); + $a = self::COUPDAYBS($settlement, $maturity, $frequency, $basis); + + $baseYF = 1.0 + ($yield / $frequency); + $rfp = 100 * ($rate / $frequency); + $de = $dsc / $e; + + $result = $redemption / pow($baseYF, (--$n + $de)); + for($k = 0; $k <= $n; ++$k) { + $result += $rfp / (pow($baseYF, ($k + $de))); + } + $result -= $rfp * ($a / $e); + + return $result; + } // function PRICE() + + + /** + * PRICEDISC + * + * Returns the price per $100 face value of a discounted security. + * + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param int discount The security's discount rate. + * @param int redemption The security's redemption value per $100 face value. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function PRICEDISC($settlement, $maturity, $discount, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $discount = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount); + $redemption = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($discount)) && (is_numeric($redemption)) && (is_numeric($basis))) { + if (($discount <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return $redemption * (1 - $discount * $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PRICEDISC() + + + /** + * PRICEMAT + * + * Returns the price per $100 face value of a security that pays interest at maturity. + * + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed issue The security's issue date. + * @param int rate The security's interest rate at date of issue. + * @param int yield The security's annual yield. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function PRICEMAT($settlement, $maturity, $issue, $rate, $yield, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $yield = PHPExcel_Calculation_Functions::flattenSingleValue($yield); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if (is_numeric($rate) && is_numeric($yield)) { + if (($rate <= 0) || ($yield <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + if (!is_numeric($daysPerYear)) { + return $daysPerYear; + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + $daysBetweenIssueAndSettlement *= $daysPerYear; + $daysBetweenIssueAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $maturity, $basis); + if (!is_numeric($daysBetweenIssueAndMaturity)) { + // return date error + return $daysBetweenIssueAndMaturity; + } + $daysBetweenIssueAndMaturity *= $daysPerYear; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + $daysBetweenSettlementAndMaturity *= $daysPerYear; + + return ((100 + (($daysBetweenIssueAndMaturity / $daysPerYear) * $rate * 100)) / + (1 + (($daysBetweenSettlementAndMaturity / $daysPerYear) * $yield)) - + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate * 100)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PRICEMAT() + + + /** + * PV + * + * Returns the Present Value of a cash flow with constant payments and interest rate (annuities). + * + * @param float $rate Interest rate per period + * @param int $nper Number of periods + * @param float $pmt Periodic payment (annuity) + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function PV($rate = 0, $nper = 0, $pmt = 0, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + return (-$pmt * (1 + $rate * $type) * ((pow(1 + $rate, $nper) - 1) / $rate) - $fv) / pow(1 + $rate, $nper); + } else { + return -$fv - $pmt * $nper; + } + } // function PV() + + + /** + * RATE + * + * Returns the interest rate per period of an annuity. + * RATE is calculated by iteration and can have zero or more solutions. + * If the successive results of RATE do not converge to within 0.0000001 after 20 iterations, + * RATE returns the #NUM! error value. + * + * Excel Function: + * RATE(nper,pmt,pv[,fv[,type[,guess]]]) + * + * @access public + * @category Financial Functions + * @param float nper The total number of payment periods in an annuity. + * @param float pmt The payment made each period and cannot change over the life + * of the annuity. + * Typically, pmt includes principal and interest but no other + * fees or taxes. + * @param float pv The present value - the total amount that a series of future + * payments is worth now. + * @param float fv The future value, or a cash balance you want to attain after + * the last payment is made. If fv is omitted, it is assumed + * to be 0 (the future value of a loan, for example, is 0). + * @param integer type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @param float guess Your guess for what the rate will be. + * If you omit guess, it is assumed to be 10 percent. + * @return float + **/ + public static function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) { + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = (is_null($fv)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = (is_null($type)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + $guess = (is_null($guess)) ? 0.1 : PHPExcel_Calculation_Functions::flattenSingleValue($guess); + + $rate = $guess; + if (abs($rate) < FINANCIAL_PRECISION) { + $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; + } else { + $f = exp($nper * log(1 + $rate)); + $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; + } + $y0 = $pv + $pmt * $nper + $fv; + $y1 = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; + + // find root by secant method + $i = $x0 = 0.0; + $x1 = $rate; + while ((abs($y0 - $y1) > FINANCIAL_PRECISION) && ($i < FINANCIAL_MAX_ITERATIONS)) { + $rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0); + $x0 = $x1; + $x1 = $rate; + if (($nper * abs($pmt)) > ($pv - $fv)) + $x1 = abs($x1); + + if (abs($rate) < FINANCIAL_PRECISION) { + $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; + } else { + $f = exp($nper * log(1 + $rate)); + $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; + } + + $y0 = $y1; + $y1 = $y; + ++$i; + } + return $rate; + } // function RATE() + + + /** + * RECEIVED + * + * Returns the price per $100 face value of a discounted security. + * + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param int investment The amount invested in the security. + * @param int discount The security's discount rate. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function RECEIVED($settlement, $maturity, $investment, $discount, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $investment = (float) PHPExcel_Calculation_Functions::flattenSingleValue($investment); + $discount = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($investment)) && (is_numeric($discount)) && (is_numeric($basis))) { + if (($investment <= 0) || ($discount <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return $investment / ( 1 - ($discount * $daysBetweenSettlementAndMaturity)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function RECEIVED() + + + /** + * SLN + * + * Returns the straight-line depreciation of an asset for one period + * + * @param cost Initial cost of the asset + * @param salvage Value at the end of the depreciation + * @param life Number of periods over which the asset is depreciated + * @return float + */ + public static function SLN($cost, $salvage, $life) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + + // Calculate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life))) { + if ($life < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return ($cost - $salvage) / $life; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SLN() + + + /** + * SYD + * + * Returns the sum-of-years' digits depreciation of an asset for a specified period. + * + * @param cost Initial cost of the asset + * @param salvage Value at the end of the depreciation + * @param life Number of periods over which the asset is depreciated + * @param period Period + * @return float + */ + public static function SYD($cost, $salvage, $life, $period) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + + // Calculate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period))) { + if (($life < 1) || ($period > $life)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return (($cost - $salvage) * ($life - $period + 1) * 2) / ($life * ($life + 1)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SYD() + + + /** + * TBILLEQ + * + * Returns the bond-equivalent yield for a Treasury bill. + * + * @param mixed settlement The Treasury bill's settlement date. + * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. + * @param mixed maturity The Treasury bill's maturity date. + * The maturity date is the date when the Treasury bill expires. + * @param int discount The Treasury bill's discount rate. + * @return float + */ + public static function TBILLEQ($settlement, $maturity, $discount) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $discount = PHPExcel_Calculation_Functions::flattenSingleValue($discount); + + // Use TBILLPRICE for validation + $testValue = self::TBILLPRICE($settlement, $maturity, $discount); + if (is_string($testValue)) { + return $testValue; + } + + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + ++$maturity; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; + } else { + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + } + + return (365 * $discount) / (360 - $discount * $daysBetweenSettlementAndMaturity); + } // function TBILLEQ() + + + /** + * TBILLPRICE + * + * Returns the yield for a Treasury bill. + * + * @param mixed settlement The Treasury bill's settlement date. + * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. + * @param mixed maturity The Treasury bill's maturity date. + * The maturity date is the date when the Treasury bill expires. + * @param int discount The Treasury bill's discount rate. + * @return float + */ + public static function TBILLPRICE($settlement, $maturity, $discount) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $discount = PHPExcel_Calculation_Functions::flattenSingleValue($discount); + + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Validate + if (is_numeric($discount)) { + if ($discount <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + ++$maturity; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + } else { + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + } + + if ($daysBetweenSettlementAndMaturity > 360) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $price = 100 * (1 - (($discount * $daysBetweenSettlementAndMaturity) / 360)); + if ($price <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $price; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TBILLPRICE() + + + /** + * TBILLYIELD + * + * Returns the yield for a Treasury bill. + * + * @param mixed settlement The Treasury bill's settlement date. + * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. + * @param mixed maturity The Treasury bill's maturity date. + * The maturity date is the date when the Treasury bill expires. + * @param int price The Treasury bill's price per $100 face value. + * @return float + */ + public static function TBILLYIELD($settlement, $maturity, $price) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + + // Validate + if (is_numeric($price)) { + if ($price <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + ++$maturity; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + } else { + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + } + + if ($daysBetweenSettlementAndMaturity > 360) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return ((100 - $price) / $price) * (360 / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TBILLYIELD() + + + public static function XIRR($values, $dates, $guess = 0.1) { + if ((!is_array($values)) && (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $dates = PHPExcel_Calculation_Functions::flattenArray($dates); + $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); + if (count($values) != count($dates)) return PHPExcel_Calculation_Functions::NaN(); + + // create an initial range, with a root somewhere between 0 and guess + $x1 = 0.0; + $x2 = $guess; + $f1 = self::XNPV($x1, $values, $dates); + $f2 = self::XNPV($x2, $values, $dates); + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + if (($f1 * $f2) < 0.0) break; + if (abs($f1) < abs($f2)) { + $f1 = self::XNPV($x1 += 1.6 * ($x1 - $x2), $values, $dates); + } else { + $f2 = self::XNPV($x2 += 1.6 * ($x2 - $x1), $values, $dates); + } + } + if (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE(); + + $f = self::XNPV($x1, $values, $dates); + if ($f < 0.0) { + $rtb = $x1; + $dx = $x2 - $x1; + } else { + $rtb = $x2; + $dx = $x1 - $x2; + } + + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + $dx *= 0.5; + $x_mid = $rtb + $dx; + $f_mid = self::XNPV($x_mid, $values, $dates); + if ($f_mid <= 0.0) $rtb = $x_mid; + if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) return $x_mid; + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + /** + * XNPV + * + * Returns the net present value for a schedule of cash flows that is not necessarily periodic. + * To calculate the net present value for a series of cash flows that is periodic, use the NPV function. + * + * Excel Function: + * =XNPV(rate,values,dates) + * + * @param float $rate The discount rate to apply to the cash flows. + * @param array of float $values A series of cash flows that corresponds to a schedule of payments in dates. The first payment is optional and corresponds to a cost or payment that occurs at the beginning of the investment. If the first value is a cost or payment, it must be a negative value. All succeeding payments are discounted based on a 365-day year. The series of values must contain at least one positive value and one negative value. + * @param array of mixed $dates A schedule of payment dates that corresponds to the cash flow payments. The first payment date indicates the beginning of the schedule of payments. All other dates must be later than this date, but they may occur in any order. + * @return float + */ + public static function XNPV($rate, $values, $dates) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + if (!is_numeric($rate)) return PHPExcel_Calculation_Functions::VALUE(); + if ((!is_array($values)) || (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $dates = PHPExcel_Calculation_Functions::flattenArray($dates); + $valCount = count($values); + if ($valCount != count($dates)) return PHPExcel_Calculation_Functions::NaN(); + if ((min($values) > 0) || (max($values) < 0)) return PHPExcel_Calculation_Functions::VALUE(); + + $xnpv = 0.0; + for ($i = 0; $i < $valCount; ++$i) { + if (!is_numeric($values[$i])) return PHPExcel_Calculation_Functions::VALUE(); + $xnpv += $values[$i] / pow(1 + $rate, PHPExcel_Calculation_DateTime::DATEDIF($dates[0],$dates[$i],'d') / 365); + } + return (is_finite($xnpv)) ? $xnpv : PHPExcel_Calculation_Functions::VALUE(); + } // function XNPV() + + + /** + * YIELDDISC + * + * Returns the annual yield of a security that pays interest at maturity. + * + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param int price The security's price per $100 face value. + * @param int redemption The security's redemption value per $100 face value. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function YIELDDISC($settlement, $maturity, $price, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if (is_numeric($price) && is_numeric($redemption)) { + if (($price <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + if (!is_numeric($daysPerYear)) { + return $daysPerYear; + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity,$basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + $daysBetweenSettlementAndMaturity *= $daysPerYear; + + return (($redemption - $price) / $price) * ($daysPerYear / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function YIELDDISC() + + + /** + * YIELDMAT + * + * Returns the annual yield of a security that pays interest at maturity. + * + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed issue The security's issue date. + * @param int rate The security's interest rate at date of issue. + * @param int price The security's price per $100 face value. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function YIELDMAT($settlement, $maturity, $issue, $rate, $price, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if (is_numeric($rate) && is_numeric($price)) { + if (($rate <= 0) || ($price <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + if (!is_numeric($daysPerYear)) { + return $daysPerYear; + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + $daysBetweenIssueAndSettlement *= $daysPerYear; + $daysBetweenIssueAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $maturity, $basis); + if (!is_numeric($daysBetweenIssueAndMaturity)) { + // return date error + return $daysBetweenIssueAndMaturity; + } + $daysBetweenIssueAndMaturity *= $daysPerYear; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + $daysBetweenSettlementAndMaturity *= $daysPerYear; + + return ((1 + (($daysBetweenIssueAndMaturity / $daysPerYear) * $rate) - (($price / 100) + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate))) / + (($price / 100) + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate))) * + ($daysPerYear / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function YIELDMAT() + +} // class PHPExcel_Calculation_Financial diff --git a/Classes/PHPExcel/Calculation/FormulaParser.php b/Classes/PHPExcel/Calculation/FormulaParser.php index c78c36029..1a97c7d66 100644 --- a/Classes/PHPExcel/Calculation/FormulaParser.php +++ b/Classes/PHPExcel/Calculation/FormulaParser.php @@ -21,32 +21,32 @@ * @category PHPExcel * @package PHPExcel_Calculation * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /* PARTLY BASED ON: - Copyright (c) 2007 E. W. Bachtal, Inc. + Copyright (c) 2007 E. W. Bachtal, Inc. - Permission is hereby granted, free of charge, to any person obtaining a copy of this software - and associated documentation files (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The above copyright notice and this permission notice shall be included in all copies or substantial - portions of the Software. + The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software. - The software is provided "as is", without warranty of any kind, express or implied, including but not - limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In - no event shall the authors or copyright holders be liable for any claim, damages or other liability, - whether in an action of contract, tort or otherwise, arising from, out of or in connection with the - software or the use or other dealings in the software. + The software is provided "as is", without warranty of any kind, express or implied, including but not + limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In + no event shall the authors or copyright holders be liable for any claim, damages or other liability, + whether in an action of contract, tort or otherwise, arising from, out of or in connection with the + software or the use or other dealings in the software. - http://ewbi.blogs.com/develops/2007/03/excel_formula_p.html - http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html + http://ewbi.blogs.com/develops/2007/03/excel_formula_p.html + http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html */ /** @@ -57,55 +57,55 @@ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_FormulaParser { - /* Character constants */ - const QUOTE_DOUBLE = '"'; - const QUOTE_SINGLE = '\''; - const BRACKET_CLOSE = ']'; - const BRACKET_OPEN = '['; - const BRACE_OPEN = '{'; - const BRACE_CLOSE = '}'; - const PAREN_OPEN = '('; - const PAREN_CLOSE = ')'; - const SEMICOLON = ';'; - const WHITESPACE = ' '; - const COMMA = ','; - const ERROR_START = '#'; - - const OPERATORS_SN = "+-"; - const OPERATORS_INFIX = "+-*/^&=><"; - const OPERATORS_POSTFIX = "%"; - - /** - * Formula - * - * @var string - */ - private $_formula; - - /** - * Tokens - * - * @var PHPExcel_Calculation_FormulaToken[] - */ - private $_tokens = array(); + /* Character constants */ + const QUOTE_DOUBLE = '"'; + const QUOTE_SINGLE = '\''; + const BRACKET_CLOSE = ']'; + const BRACKET_OPEN = '['; + const BRACE_OPEN = '{'; + const BRACE_CLOSE = '}'; + const PAREN_OPEN = '('; + const PAREN_CLOSE = ')'; + const SEMICOLON = ';'; + const WHITESPACE = ' '; + const COMMA = ','; + const ERROR_START = '#'; + + const OPERATORS_SN = "+-"; + const OPERATORS_INFIX = "+-*/^&=><"; + const OPERATORS_POSTFIX = "%"; + + /** + * Formula + * + * @var string + */ + private $_formula; + + /** + * Tokens + * + * @var PHPExcel_Calculation_FormulaToken[] + */ + private $_tokens = array(); /** * Create a new PHPExcel_Calculation_FormulaParser * - * @param string $pFormula Formula to parse - * @throws PHPExcel_Calculation_Exception + * @param string $pFormula Formula to parse + * @throws PHPExcel_Calculation_Exception */ public function __construct($pFormula = '') { - // Check parameters - if (is_null($pFormula)) { - throw new PHPExcel_Calculation_Exception("Invalid parameter passed: formula"); - } - - // Initialise values - $this->_formula = trim($pFormula); - // Parse! - $this->_parseToTokens(); + // Check parameters + if (is_null($pFormula)) { + throw new PHPExcel_Calculation_Exception("Invalid parameter passed: formula"); + } + + // Initialise values + $this->_formula = trim($pFormula); + // Parse! + $this->_parseToTokens(); } /** @@ -114,22 +114,22 @@ public function __construct($pFormula = '') * @return string */ public function getFormula() { - return $this->_formula; + return $this->_formula; } /** * Get Token * - * @param int $pId Token id - * @return string + * @param int $pId Token id + * @return string * @throws PHPExcel_Calculation_Exception */ public function getToken($pId = 0) { - if (isset($this->_tokens[$pId])) { - return $this->_tokens[$pId]; - } else { - throw new PHPExcel_Calculation_Exception("Token with id $pId does not exist."); - } + if (isset($this->_tokens[$pId])) { + return $this->_tokens[$pId]; + } else { + throw new PHPExcel_Calculation_Exception("Token with id $pId does not exist."); + } } /** @@ -138,7 +138,7 @@ public function getToken($pId = 0) { * @return string */ public function getTokenCount() { - return count($this->_tokens); + return count($this->_tokens); } /** @@ -147,468 +147,468 @@ public function getTokenCount() { * @return PHPExcel_Calculation_FormulaToken[] */ public function getTokens() { - return $this->_tokens; + return $this->_tokens; } /** * Parse to tokens */ private function _parseToTokens() { - // No attempt is made to verify formulas; assumes formulas are derived from Excel, where - // they can only exist if valid; stack overflows/underflows sunk as nulls without exceptions. - - // Check if the formula has a valid starting = - $formulaLength = strlen($this->_formula); - if ($formulaLength < 2 || $this->_formula{0} != '=') return; - - // Helper variables - $tokens1 = $tokens2 = $stack = array(); - $inString = $inPath = $inRange = $inError = false; - $token = $previousToken = $nextToken = null; - - $index = 1; - $value = ''; - - $ERRORS = array("#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A"); - $COMPARATORS_MULTI = array(">=", "<=", "<>"); - - while ($index < $formulaLength) { - // state-dependent character evaluation (order is important) - - // double-quoted strings - // embeds are doubled - // end marks token - if ($inString) { - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { - if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) { - $value .= PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE; - ++$index; - } else { - $inString = false; - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_TEXT); - $value = ""; - } - } else { - $value .= $this->_formula{$index}; - } - ++$index; - continue; - } - - // single-quoted strings (links) - // embeds are double - // end does not mark a token - if ($inPath) { - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { - if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) { - $value .= PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE; - ++$index; - } else { - $inPath = false; - } - } else { - $value .= $this->_formula{$index}; - } - ++$index; - continue; - } - - // bracked strings (R1C1 range index or linked workbook name) - // no embeds (changed to "()" by Excel) - // end does not mark a token - if ($inRange) { - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) { - $inRange = false; - } - $value .= $this->_formula{$index}; - ++$index; - continue; - } - - // error values - // end marks a token, determined from absolute list of values - if ($inError) { - $value .= $this->_formula{$index}; - ++$index; - if (in_array($value, $ERRORS)) { - $inError = false; - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_ERROR); - $value = ""; - } - continue; - } - - // scientific notation check - if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->_formula{$index}) !== false) { - if (strlen($value) > 1) { - if (preg_match("/^[1-9]{1}(\.[0-9]+)?E{1}$/", $this->_formula{$index}) != 0) { - $value .= $this->_formula{$index}; - ++$index; - continue; - } - } - } - - // independent character evaluation (order not important) - - // establish state-dependent character evaluations - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { - if (strlen($value > 0)) { // unexpected - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); - $value = ""; - } - $inString = true; - ++$index; - continue; - } - - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { - if (strlen($value) > 0) { // unexpected - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); - $value = ""; - } - $inPath = true; - ++$index; - continue; - } - - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) { - $inRange = true; - $value .= PHPExcel_Calculation_FormulaParser::BRACKET_OPEN; - ++$index; - continue; - } - - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::ERROR_START) { - if (strlen($value) > 0) { // unexpected - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); - $value = ""; - } - $inError = true; - $value .= PHPExcel_Calculation_FormulaParser::ERROR_START; - ++$index; - continue; - } - - // mark start and end of arrays and array rows - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) { - if (strlen($value) > 0) { // unexpected - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); - $value = ""; - } - - $tmp = new PHPExcel_Calculation_FormulaToken("ARRAY", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); - $tokens1[] = $tmp; - $stack[] = clone $tmp; - - $tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); - $tokens1[] = $tmp; - $stack[] = clone $tmp; - - ++$index; - continue; - } - - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::SEMICOLON) { - if (strlen($value) > 0) { - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); - $value = ""; - } - - $tmp = array_pop($stack); - $tmp->setValue(""); - $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); - $tokens1[] = $tmp; - - $tmp = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); - $tokens1[] = $tmp; - - $tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); - $tokens1[] = $tmp; - $stack[] = clone $tmp; - - ++$index; - continue; - } - - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) { - if (strlen($value) > 0) { - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); - $value = ""; - } - - $tmp = array_pop($stack); - $tmp->setValue(""); - $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); - $tokens1[] = $tmp; - - $tmp = array_pop($stack); - $tmp->setValue(""); - $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); - $tokens1[] = $tmp; - - ++$index; - continue; - } - - // trim white-space - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) { - if (strlen($value) > 0) { - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); - $value = ""; - } - $tokens1[] = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE); - ++$index; - while (($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) { - ++$index; - } - continue; - } - - // multi-character comparators - if (($index + 2) <= $formulaLength) { - if (in_array(substr($this->_formula, $index, 2), $COMPARATORS_MULTI)) { - if (strlen($value) > 0) { - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); - $value = ""; - } - $tokens1[] = new PHPExcel_Calculation_FormulaToken(substr($this->_formula, $index, 2), PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); - $index += 2; - continue; - } - } - - // standard infix operators - if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->_formula{$index}) !== false) { - if (strlen($value) > 0) { - $tokens1[] =new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); - $value = ""; - } - $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX); - ++$index; - continue; - } - - // standard postfix operators (only one) - if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->_formula{$index}) !== false) { - if (strlen($value) > 0) { - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); - $value = ""; - } - $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX); - ++$index; - continue; - } - - // start subexpression or function - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) { - if (strlen($value) > 0) { - $tmp = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); - $tokens1[] = $tmp; - $stack[] = clone $tmp; - $value = ""; - } else { - $tmp = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); - $tokens1[] = $tmp; - $stack[] = clone $tmp; - } - ++$index; - continue; - } - - // function, subexpression, or array parameters, or operand unions - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::COMMA) { - if (strlen($value) > 0) { - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); - $value = ""; - } - - $tmp = array_pop($stack); - $tmp->setValue(""); - $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); - $stack[] = $tmp; - - if ($tmp->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { - $tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_UNION); - } else { - $tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); - } - ++$index; - continue; - } - - // stop subexpression - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) { - if (strlen($value) > 0) { - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); - $value = ""; - } - - $tmp = array_pop($stack); - $tmp->setValue(""); - $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); - $tokens1[] = $tmp; - - ++$index; - continue; - } - - // token accumulation - $value .= $this->_formula{$index}; - ++$index; - } - - // dump remaining accumulation - if (strlen($value) > 0) { - $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); - } - - // move tokenList to new set, excluding unnecessary white-space tokens and converting necessary ones to intersections - $tokenCount = count($tokens1); - for ($i = 0; $i < $tokenCount; ++$i) { - $token = $tokens1[$i]; - if (isset($tokens1[$i - 1])) { - $previousToken = $tokens1[$i - 1]; - } else { - $previousToken = null; - } - if (isset($tokens1[$i + 1])) { - $nextToken = $tokens1[$i + 1]; - } else { - $nextToken = null; - } - - if (is_null($token)) { - continue; - } - - if ($token->getTokenType() != PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE) { - $tokens2[] = $token; - continue; - } - - if (is_null($previousToken)) { - continue; - } - - if (! ( - (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || - (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || - ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) - ) ) { - continue; - } - - if (is_null($nextToken)) { - continue; - } - - if (! ( - (($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || - (($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || - ($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) - ) ) { - continue; - } - - $tokens2[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_INTERSECTION); - } - - // move tokens to final list, switching infix "-" operators to prefix when appropriate, switching infix "+" operators - // to noop when appropriate, identifying operand and infix-operator subtypes, and pulling "@" from function names - $this->_tokens = array(); - - $tokenCount = count($tokens2); - for ($i = 0; $i < $tokenCount; ++$i) { - $token = $tokens2[$i]; - if (isset($tokens2[$i - 1])) { - $previousToken = $tokens2[$i - 1]; - } else { - $previousToken = null; - } - if (isset($tokens2[$i + 1])) { - $nextToken = $tokens2[$i + 1]; - } else { - $nextToken = null; - } - - if (is_null($token)) { - continue; - } - - if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "-") { - if ($i == 0) { - $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); - } else if ( - (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || - (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || - ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || - ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) - ) { - $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); - } else { - $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); - } - - $this->_tokens[] = $token; - continue; - } - - if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "+") { - if ($i == 0) { - continue; - } else if ( - (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || - (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || - ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || - ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) - ) { - $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); - } else { - continue; - } - - $this->_tokens[] = $token; - continue; - } - - if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { - if (strpos("<>=", substr($token->getValue(), 0, 1)) !== false) { - $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); - } else if ($token->getValue() == "&") { - $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_CONCATENATION); - } else { - $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); - } - - $this->_tokens[] = $token; - continue; - } - - if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { - if (!is_numeric($token->getValue())) { - if (strtoupper($token->getValue()) == "TRUE" || strtoupper($token->getValue() == "FALSE")) { - $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); - } else { - $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_RANGE); - } - } else { - $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NUMBER); - } - - $this->_tokens[] = $token; - continue; - } - - if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { - if (strlen($token->getValue() > 0)) { - if (substr($token->getValue(), 0, 1) == "@") { - $token->setValue(substr($token->getValue(), 1)); - } - } - } - - $this->_tokens[] = $token; - } + // No attempt is made to verify formulas; assumes formulas are derived from Excel, where + // they can only exist if valid; stack overflows/underflows sunk as nulls without exceptions. + + // Check if the formula has a valid starting = + $formulaLength = strlen($this->_formula); + if ($formulaLength < 2 || $this->_formula{0} != '=') return; + + // Helper variables + $tokens1 = $tokens2 = $stack = array(); + $inString = $inPath = $inRange = $inError = false; + $token = $previousToken = $nextToken = null; + + $index = 1; + $value = ''; + + $ERRORS = array("#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A"); + $COMPARATORS_MULTI = array(">=", "<=", "<>"); + + while ($index < $formulaLength) { + // state-dependent character evaluation (order is important) + + // double-quoted strings + // embeds are doubled + // end marks token + if ($inString) { + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { + if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) { + $value .= PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE; + ++$index; + } else { + $inString = false; + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_TEXT); + $value = ""; + } + } else { + $value .= $this->_formula{$index}; + } + ++$index; + continue; + } + + // single-quoted strings (links) + // embeds are double + // end does not mark a token + if ($inPath) { + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { + if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) { + $value .= PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE; + ++$index; + } else { + $inPath = false; + } + } else { + $value .= $this->_formula{$index}; + } + ++$index; + continue; + } + + // bracked strings (R1C1 range index or linked workbook name) + // no embeds (changed to "()" by Excel) + // end does not mark a token + if ($inRange) { + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) { + $inRange = false; + } + $value .= $this->_formula{$index}; + ++$index; + continue; + } + + // error values + // end marks a token, determined from absolute list of values + if ($inError) { + $value .= $this->_formula{$index}; + ++$index; + if (in_array($value, $ERRORS)) { + $inError = false; + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_ERROR); + $value = ""; + } + continue; + } + + // scientific notation check + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->_formula{$index}) !== false) { + if (strlen($value) > 1) { + if (preg_match("/^[1-9]{1}(\.[0-9]+)?E{1}$/", $this->_formula{$index}) != 0) { + $value .= $this->_formula{$index}; + ++$index; + continue; + } + } + } + + // independent character evaluation (order not important) + + // establish state-dependent character evaluations + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { + if (strlen($value > 0)) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + $inString = true; + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { + if (strlen($value) > 0) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + $inPath = true; + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) { + $inRange = true; + $value .= PHPExcel_Calculation_FormulaParser::BRACKET_OPEN; + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::ERROR_START) { + if (strlen($value) > 0) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + $inError = true; + $value .= PHPExcel_Calculation_FormulaParser::ERROR_START; + ++$index; + continue; + } + + // mark start and end of arrays and array rows + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) { + if (strlen($value) > 0) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + + $tmp = new PHPExcel_Calculation_FormulaToken("ARRAY", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + + $tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::SEMICOLON) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + $tmp = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); + $tokens1[] = $tmp; + + $tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + ++$index; + continue; + } + + // trim white-space + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE); + ++$index; + while (($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) { + ++$index; + } + continue; + } + + // multi-character comparators + if (($index + 2) <= $formulaLength) { + if (in_array(substr($this->_formula, $index, 2), $COMPARATORS_MULTI)) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken(substr($this->_formula, $index, 2), PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); + $index += 2; + continue; + } + } + + // standard infix operators + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->_formula{$index}) !== false) { + if (strlen($value) > 0) { + $tokens1[] =new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX); + ++$index; + continue; + } + + // standard postfix operators (only one) + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->_formula{$index}) !== false) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX); + ++$index; + continue; + } + + // start subexpression or function + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) { + if (strlen($value) > 0) { + $tmp = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + $value = ""; + } else { + $tmp = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + } + ++$index; + continue; + } + + // function, subexpression, or array parameters, or operand unions + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::COMMA) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $stack[] = $tmp; + + if ($tmp->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_UNION); + } else { + $tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); + } + ++$index; + continue; + } + + // stop subexpression + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + ++$index; + continue; + } + + // token accumulation + $value .= $this->_formula{$index}; + ++$index; + } + + // dump remaining accumulation + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + } + + // move tokenList to new set, excluding unnecessary white-space tokens and converting necessary ones to intersections + $tokenCount = count($tokens1); + for ($i = 0; $i < $tokenCount; ++$i) { + $token = $tokens1[$i]; + if (isset($tokens1[$i - 1])) { + $previousToken = $tokens1[$i - 1]; + } else { + $previousToken = null; + } + if (isset($tokens1[$i + 1])) { + $nextToken = $tokens1[$i + 1]; + } else { + $nextToken = null; + } + + if (is_null($token)) { + continue; + } + + if ($token->getTokenType() != PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE) { + $tokens2[] = $token; + continue; + } + + if (is_null($previousToken)) { + continue; + } + + if (! ( + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) ) { + continue; + } + + if (is_null($nextToken)) { + continue; + } + + if (! ( + (($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || + (($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || + ($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) ) { + continue; + } + + $tokens2[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_INTERSECTION); + } + + // move tokens to final list, switching infix "-" operators to prefix when appropriate, switching infix "+" operators + // to noop when appropriate, identifying operand and infix-operator subtypes, and pulling "@" from function names + $this->_tokens = array(); + + $tokenCount = count($tokens2); + for ($i = 0; $i < $tokenCount; ++$i) { + $token = $tokens2[$i]; + if (isset($tokens2[$i - 1])) { + $previousToken = $tokens2[$i - 1]; + } else { + $previousToken = null; + } + if (isset($tokens2[$i + 1])) { + $nextToken = $tokens2[$i + 1]; + } else { + $nextToken = null; + } + + if (is_null($token)) { + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "-") { + if ($i == 0) { + $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); + } else if ( + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); + } else { + $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "+") { + if ($i == 0) { + continue; + } else if ( + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); + } else { + continue; + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { + if (strpos("<>=", substr($token->getValue(), 0, 1)) !== false) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); + } else if ($token->getValue() == "&") { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_CONCATENATION); + } else { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { + if (!is_numeric($token->getValue())) { + if (strtoupper($token->getValue()) == "TRUE" || strtoupper($token->getValue() == "FALSE")) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); + } else { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_RANGE); + } + } else { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NUMBER); + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { + if (strlen($token->getValue() > 0)) { + if (substr($token->getValue(), 0, 1) == "@") { + $token->setValue(substr($token->getValue(), 1)); + } + } + } + + $this->_tokens[] = $token; + } } } diff --git a/Classes/PHPExcel/Calculation/FormulaToken.php b/Classes/PHPExcel/Calculation/FormulaToken.php index 54fe9a417..f52556177 100644 --- a/Classes/PHPExcel/Calculation/FormulaToken.php +++ b/Classes/PHPExcel/Calculation/FormulaToken.php @@ -21,32 +21,32 @@ * @category PHPExcel * @package PHPExcel_Calculation * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /* PARTLY BASED ON: - Copyright (c) 2007 E. W. Bachtal, Inc. + Copyright (c) 2007 E. W. Bachtal, Inc. - Permission is hereby granted, free of charge, to any person obtaining a copy of this software - and associated documentation files (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: - The above copyright notice and this permission notice shall be included in all copies or substantial - portions of the Software. + The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software. - The software is provided "as is", without warranty of any kind, express or implied, including but not - limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In - no event shall the authors or copyright holders be liable for any claim, damages or other liability, - whether in an action of contract, tort or otherwise, arising from, out of or in connection with the - software or the use or other dealings in the software. + The software is provided "as is", without warranty of any kind, express or implied, including but not + limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In + no event shall the authors or copyright holders be liable for any claim, damages or other liability, + whether in an action of contract, tort or otherwise, arising from, out of or in connection with the + software or the use or other dealings in the software. - http://ewbi.blogs.com/develops/2007/03/excel_formula_p.html - http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html + http://ewbi.blogs.com/develops/2007/03/excel_formula_p.html + http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html */ @@ -58,66 +58,66 @@ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_FormulaToken { - /* Token types */ - const TOKEN_TYPE_NOOP = 'Noop'; - const TOKEN_TYPE_OPERAND = 'Operand'; - const TOKEN_TYPE_FUNCTION = 'Function'; - const TOKEN_TYPE_SUBEXPRESSION = 'Subexpression'; - const TOKEN_TYPE_ARGUMENT = 'Argument'; - const TOKEN_TYPE_OPERATORPREFIX = 'OperatorPrefix'; - const TOKEN_TYPE_OPERATORINFIX = 'OperatorInfix'; - const TOKEN_TYPE_OPERATORPOSTFIX = 'OperatorPostfix'; - const TOKEN_TYPE_WHITESPACE = 'Whitespace'; - const TOKEN_TYPE_UNKNOWN = 'Unknown'; - - /* Token subtypes */ - const TOKEN_SUBTYPE_NOTHING = 'Nothing'; - const TOKEN_SUBTYPE_START = 'Start'; - const TOKEN_SUBTYPE_STOP = 'Stop'; - const TOKEN_SUBTYPE_TEXT = 'Text'; - const TOKEN_SUBTYPE_NUMBER = 'Number'; - const TOKEN_SUBTYPE_LOGICAL = 'Logical'; - const TOKEN_SUBTYPE_ERROR = 'Error'; - const TOKEN_SUBTYPE_RANGE = 'Range'; - const TOKEN_SUBTYPE_MATH = 'Math'; - const TOKEN_SUBTYPE_CONCATENATION = 'Concatenation'; - const TOKEN_SUBTYPE_INTERSECTION = 'Intersection'; - const TOKEN_SUBTYPE_UNION = 'Union'; - - /** - * Value - * - * @var string - */ - private $_value; - - /** - * Token Type (represented by TOKEN_TYPE_*) - * - * @var string - */ - private $_tokenType; - - /** - * Token SubType (represented by TOKEN_SUBTYPE_*) - * - * @var string - */ - private $_tokenSubType; + /* Token types */ + const TOKEN_TYPE_NOOP = 'Noop'; + const TOKEN_TYPE_OPERAND = 'Operand'; + const TOKEN_TYPE_FUNCTION = 'Function'; + const TOKEN_TYPE_SUBEXPRESSION = 'Subexpression'; + const TOKEN_TYPE_ARGUMENT = 'Argument'; + const TOKEN_TYPE_OPERATORPREFIX = 'OperatorPrefix'; + const TOKEN_TYPE_OPERATORINFIX = 'OperatorInfix'; + const TOKEN_TYPE_OPERATORPOSTFIX = 'OperatorPostfix'; + const TOKEN_TYPE_WHITESPACE = 'Whitespace'; + const TOKEN_TYPE_UNKNOWN = 'Unknown'; + + /* Token subtypes */ + const TOKEN_SUBTYPE_NOTHING = 'Nothing'; + const TOKEN_SUBTYPE_START = 'Start'; + const TOKEN_SUBTYPE_STOP = 'Stop'; + const TOKEN_SUBTYPE_TEXT = 'Text'; + const TOKEN_SUBTYPE_NUMBER = 'Number'; + const TOKEN_SUBTYPE_LOGICAL = 'Logical'; + const TOKEN_SUBTYPE_ERROR = 'Error'; + const TOKEN_SUBTYPE_RANGE = 'Range'; + const TOKEN_SUBTYPE_MATH = 'Math'; + const TOKEN_SUBTYPE_CONCATENATION = 'Concatenation'; + const TOKEN_SUBTYPE_INTERSECTION = 'Intersection'; + const TOKEN_SUBTYPE_UNION = 'Union'; + + /** + * Value + * + * @var string + */ + private $_value; + + /** + * Token Type (represented by TOKEN_TYPE_*) + * + * @var string + */ + private $_tokenType; + + /** + * Token SubType (represented by TOKEN_SUBTYPE_*) + * + * @var string + */ + private $_tokenSubType; /** * Create a new PHPExcel_Calculation_FormulaToken * - * @param string $pValue - * @param string $pTokenType Token type (represented by TOKEN_TYPE_*) - * @param string $pTokenSubType Token Subtype (represented by TOKEN_SUBTYPE_*) + * @param string $pValue + * @param string $pTokenType Token type (represented by TOKEN_TYPE_*) + * @param string $pTokenSubType Token Subtype (represented by TOKEN_SUBTYPE_*) */ public function __construct($pValue, $pTokenType = PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN, $pTokenSubType = PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { - // Initialise values - $this->_value = $pValue; - $this->_tokenType = $pTokenType; - $this->_tokenSubType = $pTokenSubType; + // Initialise values + $this->_value = $pValue; + $this->_tokenType = $pTokenType; + $this->_tokenSubType = $pTokenSubType; } /** @@ -126,16 +126,16 @@ public function __construct($pValue, $pTokenType = PHPExcel_Calculation_FormulaT * @return string */ public function getValue() { - return $this->_value; + return $this->_value; } /** * Set Value * - * @param string $value + * @param string $value */ public function setValue($value) { - $this->_value = $value; + $this->_value = $value; } /** @@ -144,16 +144,16 @@ public function setValue($value) { * @return string */ public function getTokenType() { - return $this->_tokenType; + return $this->_tokenType; } /** * Set Token Type * - * @param string $value + * @param string $value */ public function setTokenType($value = PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN) { - $this->_tokenType = $value; + $this->_tokenType = $value; } /** @@ -162,15 +162,15 @@ public function setTokenType($value = PHPExcel_Calculation_FormulaToken::TOKEN_T * @return string */ public function getTokenSubType() { - return $this->_tokenSubType; + return $this->_tokenSubType; } /** * Set Token SubType * - * @param string $value + * @param string $value */ public function setTokenSubType($value = PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { - $this->_tokenSubType = $value; + $this->_tokenSubType = $value; } } diff --git a/Classes/PHPExcel/Calculation/Function.php b/Classes/PHPExcel/Calculation/Function.php index eb272e063..5cda0f122 100644 --- a/Classes/PHPExcel/Calculation/Function.php +++ b/Classes/PHPExcel/Calculation/Function.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Calculation * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,58 +34,58 @@ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Function { - /* Function categories */ - const CATEGORY_CUBE = 'Cube'; - const CATEGORY_DATABASE = 'Database'; - const CATEGORY_DATE_AND_TIME = 'Date and Time'; - const CATEGORY_ENGINEERING = 'Engineering'; - const CATEGORY_FINANCIAL = 'Financial'; - const CATEGORY_INFORMATION = 'Information'; - const CATEGORY_LOGICAL = 'Logical'; - const CATEGORY_LOOKUP_AND_REFERENCE = 'Lookup and Reference'; - const CATEGORY_MATH_AND_TRIG = 'Math and Trig'; - const CATEGORY_STATISTICAL = 'Statistical'; - const CATEGORY_TEXT_AND_DATA = 'Text and Data'; + /* Function categories */ + const CATEGORY_CUBE = 'Cube'; + const CATEGORY_DATABASE = 'Database'; + const CATEGORY_DATE_AND_TIME = 'Date and Time'; + const CATEGORY_ENGINEERING = 'Engineering'; + const CATEGORY_FINANCIAL = 'Financial'; + const CATEGORY_INFORMATION = 'Information'; + const CATEGORY_LOGICAL = 'Logical'; + const CATEGORY_LOOKUP_AND_REFERENCE = 'Lookup and Reference'; + const CATEGORY_MATH_AND_TRIG = 'Math and Trig'; + const CATEGORY_STATISTICAL = 'Statistical'; + const CATEGORY_TEXT_AND_DATA = 'Text and Data'; - /** - * Category (represented by CATEGORY_*) - * - * @var string - */ - private $_category; + /** + * Category (represented by CATEGORY_*) + * + * @var string + */ + private $_category; - /** - * Excel name - * - * @var string - */ - private $_excelName; + /** + * Excel name + * + * @var string + */ + private $_excelName; - /** - * PHPExcel name - * - * @var string - */ - private $_phpExcelName; + /** + * PHPExcel name + * + * @var string + */ + private $_phpExcelName; /** * Create a new PHPExcel_Calculation_Function * - * @param string $pCategory Category (represented by CATEGORY_*) - * @param string $pExcelName Excel function name - * @param string $pPHPExcelName PHPExcel function mapping - * @throws PHPExcel_Calculation_Exception + * @param string $pCategory Category (represented by CATEGORY_*) + * @param string $pExcelName Excel function name + * @param string $pPHPExcelName PHPExcel function mapping + * @throws PHPExcel_Calculation_Exception */ public function __construct($pCategory = NULL, $pExcelName = NULL, $pPHPExcelName = NULL) { - if (($pCategory !== NULL) && ($pExcelName !== NULL) && ($pPHPExcelName !== NULL)) { - // Initialise values - $this->_category = $pCategory; - $this->_excelName = $pExcelName; - $this->_phpExcelName = $pPHPExcelName; - } else { - throw new PHPExcel_Calculation_Exception("Invalid parameters passed."); - } + if (($pCategory !== NULL) && ($pExcelName !== NULL) && ($pPHPExcelName !== NULL)) { + // Initialise values + $this->_category = $pCategory; + $this->_excelName = $pExcelName; + $this->_phpExcelName = $pPHPExcelName; + } else { + throw new PHPExcel_Calculation_Exception("Invalid parameters passed."); + } } /** @@ -94,21 +94,21 @@ public function __construct($pCategory = NULL, $pExcelName = NULL, $pPHPExcelNam * @return string */ public function getCategory() { - return $this->_category; + return $this->_category; } /** * Set Category (represented by CATEGORY_*) * - * @param string $value - * @throws PHPExcel_Calculation_Exception + * @param string $value + * @throws PHPExcel_Calculation_Exception */ public function setCategory($value = null) { - if (!is_null($value)) { - $this->_category = $value; - } else { - throw new PHPExcel_Calculation_Exception("Invalid parameter passed."); - } + if (!is_null($value)) { + $this->_category = $value; + } else { + throw new PHPExcel_Calculation_Exception("Invalid parameter passed."); + } } /** @@ -117,16 +117,16 @@ public function setCategory($value = null) { * @return string */ public function getExcelName() { - return $this->_excelName; + return $this->_excelName; } /** * Set Excel name * - * @param string $value + * @param string $value */ public function setExcelName($value) { - $this->_excelName = $value; + $this->_excelName = $value; } /** @@ -135,15 +135,15 @@ public function setExcelName($value) { * @return string */ public function getPHPExcelName() { - return $this->_phpExcelName; + return $this->_phpExcelName; } /** * Set PHPExcel name * - * @param string $value + * @param string $value */ public function setPHPExcelName($value) { - $this->_phpExcelName = $value; + $this->_phpExcelName = $value; } } diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index c995ee24b..8b9da3115 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -18,21 +18,21 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } @@ -52,674 +52,674 @@ /** * PHPExcel_Calculation_Functions * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Functions { - /** constants */ - const COMPATIBILITY_EXCEL = 'Excel'; - const COMPATIBILITY_GNUMERIC = 'Gnumeric'; - const COMPATIBILITY_OPENOFFICE = 'OpenOfficeCalc'; - - const RETURNDATE_PHP_NUMERIC = 'P'; - const RETURNDATE_PHP_OBJECT = 'O'; - const RETURNDATE_EXCEL = 'E'; - - - /** - * Compatibility mode to use for error checking and responses - * - * @access private - * @var string - */ - protected static $compatibilityMode = self::COMPATIBILITY_EXCEL; - - /** - * Data Type to use when returning date values - * - * @access private - * @var string - */ - protected static $ReturnDateType = self::RETURNDATE_EXCEL; - - /** - * List of error codes - * - * @access private - * @var array - */ - protected static $_errorCodes = array( 'null' => '#NULL!', - 'divisionbyzero' => '#DIV/0!', - 'value' => '#VALUE!', - 'reference' => '#REF!', - 'name' => '#NAME?', - 'num' => '#NUM!', - 'na' => '#N/A', - 'gettingdata' => '#GETTING_DATA' - ); - - - /** - * Set the Compatibility Mode - * - * @access public - * @category Function Configuration - * @param string $compatibilityMode Compatibility Mode - * Permitted values are: - * PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' - * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' - * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' - * @return boolean (Success or Failure) - */ - public static function setCompatibilityMode($compatibilityMode) { - if (($compatibilityMode == self::COMPATIBILITY_EXCEL) || - ($compatibilityMode == self::COMPATIBILITY_GNUMERIC) || - ($compatibilityMode == self::COMPATIBILITY_OPENOFFICE)) { - self::$compatibilityMode = $compatibilityMode; - return True; - } - return False; - } // function setCompatibilityMode() - - - /** - * Return the current Compatibility Mode - * - * @access public - * @category Function Configuration - * @return string Compatibility Mode - * Possible Return values are: - * PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' - * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' - * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' - */ - public static function getCompatibilityMode() { - return self::$compatibilityMode; - } // function getCompatibilityMode() - - - /** - * Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) - * - * @access public - * @category Function Configuration - * @param string $returnDateType Return Date Format - * Permitted values are: - * PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' - * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' - * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' - * @return boolean Success or failure - */ - public static function setReturnDateType($returnDateType) { - if (($returnDateType == self::RETURNDATE_PHP_NUMERIC) || - ($returnDateType == self::RETURNDATE_PHP_OBJECT) || - ($returnDateType == self::RETURNDATE_EXCEL)) { - self::$ReturnDateType = $returnDateType; - return True; - } - return False; - } // function setReturnDateType() - - - /** - * Return the current Return Date Format for functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) - * - * @access public - * @category Function Configuration - * @return string Return Date Format - * Possible Return values are: - * PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' - * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' - * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' - */ - public static function getReturnDateType() { - return self::$ReturnDateType; - } // function getReturnDateType() - - - /** - * DUMMY - * - * @access public - * @category Error Returns - * @return string #Not Yet Implemented - */ - public static function DUMMY() { - return '#Not Yet Implemented'; - } // function DUMMY() - - - /** - * DIV0 - * - * @access public - * @category Error Returns - * @return string #Not Yet Implemented - */ - public static function DIV0() { - return self::$_errorCodes['divisionbyzero']; - } // function DIV0() - - - /** - * NA - * - * Excel Function: - * =NA() - * - * Returns the error value #N/A - * #N/A is the error value that means "no value is available." - * - * @access public - * @category Logical Functions - * @return string #N/A! - */ - public static function NA() { - return self::$_errorCodes['na']; - } // function NA() - - - /** - * NaN - * - * Returns the error value #NUM! - * - * @access public - * @category Error Returns - * @return string #NUM! - */ - public static function NaN() { - return self::$_errorCodes['num']; - } // function NaN() - - - /** - * NAME - * - * Returns the error value #NAME? - * - * @access public - * @category Error Returns - * @return string #NAME? - */ - public static function NAME() { - return self::$_errorCodes['name']; - } // function NAME() - - - /** - * REF - * - * Returns the error value #REF! - * - * @access public - * @category Error Returns - * @return string #REF! - */ - public static function REF() { - return self::$_errorCodes['reference']; - } // function REF() - - - /** - * NULL - * - * Returns the error value #NULL! - * - * @access public - * @category Error Returns - * @return string #NULL! - */ - public static function NULL() { - return self::$_errorCodes['null']; - } // function NULL() - - - /** - * VALUE - * - * Returns the error value #VALUE! - * - * @access public - * @category Error Returns - * @return string #VALUE! - */ - public static function VALUE() { - return self::$_errorCodes['value']; - } // function VALUE() - - - public static function isMatrixValue($idx) { - return ((substr_count($idx,'.') <= 1) || (preg_match('/\.[A-Z]/',$idx) > 0)); - } - - - public static function isValue($idx) { - return (substr_count($idx,'.') == 0); - } - - - public static function isCellValue($idx) { - return (substr_count($idx,'.') > 1); - } - - - public static function _ifCondition($condition) { - $condition = PHPExcel_Calculation_Functions::flattenSingleValue($condition); - if (!isset($condition{0})) - $condition = '=""'; - if (!in_array($condition{0},array('>', '<', '='))) { - if (!is_numeric($condition)) { $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); } - return '='.$condition; - } else { - preg_match('/([<>=]+)(.*)/',$condition,$matches); - list(,$operator,$operand) = $matches; - - if (!is_numeric($operand)) { - $operand = str_replace('"', '""', $operand); - $operand = PHPExcel_Calculation::_wrapResult(strtoupper($operand)); - } - - return $operator.$operand; - } - } // function _ifCondition() - - - /** - * ERROR_TYPE - * - * @param mixed $value Value to check - * @return boolean - */ - public static function ERROR_TYPE($value = '') { - $value = self::flattenSingleValue($value); - - $i = 1; - foreach(self::$_errorCodes as $errorCode) { - if ($value === $errorCode) { - return $i; - } - ++$i; - } - return self::NA(); - } // function ERROR_TYPE() - - - /** - * IS_BLANK - * - * @param mixed $value Value to check - * @return boolean - */ - public static function IS_BLANK($value = NULL) { - if (!is_null($value)) { - $value = self::flattenSingleValue($value); - } - - return is_null($value); - } // function IS_BLANK() - - - /** - * IS_ERR - * - * @param mixed $value Value to check - * @return boolean - */ - public static function IS_ERR($value = '') { - $value = self::flattenSingleValue($value); - - return self::IS_ERROR($value) && (!self::IS_NA($value)); - } // function IS_ERR() - - - /** - * IS_ERROR - * - * @param mixed $value Value to check - * @return boolean - */ - public static function IS_ERROR($value = '') { - $value = self::flattenSingleValue($value); - - if (!is_string($value)) - return false; - return in_array($value, array_values(self::$_errorCodes)); - } // function IS_ERROR() - - - /** - * IS_NA - * - * @param mixed $value Value to check - * @return boolean - */ - public static function IS_NA($value = '') { - $value = self::flattenSingleValue($value); - - return ($value === self::NA()); - } // function IS_NA() - - - /** - * IS_EVEN - * - * @param mixed $value Value to check - * @return boolean - */ - public static function IS_EVEN($value = NULL) { - $value = self::flattenSingleValue($value); - - if ($value === NULL) - return self::NAME(); - if ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) - return self::VALUE(); - return ($value % 2 == 0); - } // function IS_EVEN() - - - /** - * IS_ODD - * - * @param mixed $value Value to check - * @return boolean - */ - public static function IS_ODD($value = NULL) { - $value = self::flattenSingleValue($value); - - if ($value === NULL) - return self::NAME(); - if ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) - return self::VALUE(); - return (abs($value) % 2 == 1); - } // function IS_ODD() - - - /** - * IS_NUMBER - * - * @param mixed $value Value to check - * @return boolean - */ - public static function IS_NUMBER($value = NULL) { - $value = self::flattenSingleValue($value); - - if (is_string($value)) { - return False; - } - return is_numeric($value); - } // function IS_NUMBER() - - - /** - * IS_LOGICAL - * - * @param mixed $value Value to check - * @return boolean - */ - public static function IS_LOGICAL($value = NULL) { - $value = self::flattenSingleValue($value); - - return is_bool($value); - } // function IS_LOGICAL() - - - /** - * IS_TEXT - * - * @param mixed $value Value to check - * @return boolean - */ - public static function IS_TEXT($value = NULL) { - $value = self::flattenSingleValue($value); - - return (is_string($value) && !self::IS_ERROR($value)); - } // function IS_TEXT() - - - /** - * IS_NONTEXT - * - * @param mixed $value Value to check - * @return boolean - */ - public static function IS_NONTEXT($value = NULL) { - return !self::IS_TEXT($value); - } // function IS_NONTEXT() - - - /** - * VERSION - * - * @return string Version information - */ - public static function VERSION() { - return 'PHPExcel ##VERSION##, ##DATE##'; - } // function VERSION() - - - /** - * N - * - * Returns a value converted to a number - * - * @param value The value you want converted - * @return number N converts values listed in the following table - * If value is or refers to N returns - * A number That number - * A date The serial number of that date - * TRUE 1 - * FALSE 0 - * An error value The error value - * Anything else 0 - */ - public static function N($value = NULL) { - while (is_array($value)) { - $value = array_shift($value); - } - - switch (gettype($value)) { - case 'double' : - case 'float' : - case 'integer' : - return $value; - break; - case 'boolean' : - return (integer) $value; - break; - case 'string' : - // Errors - if ((strlen($value) > 0) && ($value{0} == '#')) { - return $value; - } - break; - } - return 0; - } // function N() - - - /** - * TYPE - * - * Returns a number that identifies the type of a value - * - * @param value The value you want tested - * @return number N converts values listed in the following table - * If value is or refers to N returns - * A number 1 - * Text 2 - * Logical Value 4 - * An error value 16 - * Array or Matrix 64 - */ - public static function TYPE($value = NULL) { - $value = self::flattenArrayIndexed($value); - if (is_array($value) && (count($value) > 1)) { - $a = array_keys($value); - $a = array_pop($a); - // Range of cells is an error - if (self::isCellValue($a)) { - return 16; - // Test for Matrix - } elseif (self::isMatrixValue($a)) { - return 64; - } - } elseif(empty($value)) { - // Empty Cell - return 1; - } - $value = self::flattenSingleValue($value); - - if (($value === NULL) || (is_float($value)) || (is_int($value))) { - return 1; - } elseif(is_bool($value)) { - return 4; - } elseif(is_array($value)) { - return 64; - } elseif(is_string($value)) { - // Errors - if ((strlen($value) > 0) && ($value{0} == '#')) { - return 16; - } - return 2; - } - return 0; - } // function TYPE() - - - /** - * Convert a multi-dimensional array to a simple 1-dimensional array - * - * @param array $array Array to be flattened - * @return array Flattened array - */ - public static function flattenArray($array) { - if (!is_array($array)) { - return (array) $array; - } - - $arrayValues = array(); - foreach ($array as $value) { - if (is_array($value)) { - foreach ($value as $val) { - if (is_array($val)) { - foreach ($val as $v) { - $arrayValues[] = $v; - } - } else { - $arrayValues[] = $val; - } - } - } else { - $arrayValues[] = $value; - } - } - - return $arrayValues; - } // function flattenArray() - - - /** - * Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing - * - * @param array $array Array to be flattened - * @return array Flattened array - */ - public static function flattenArrayIndexed($array) { - if (!is_array($array)) { - return (array) $array; - } - - $arrayValues = array(); - foreach ($array as $k1 => $value) { - if (is_array($value)) { - foreach ($value as $k2 => $val) { - if (is_array($val)) { - foreach ($val as $k3 => $v) { - $arrayValues[$k1.'.'.$k2.'.'.$k3] = $v; - } - } else { - $arrayValues[$k1.'.'.$k2] = $val; - } - } - } else { - $arrayValues[$k1] = $value; - } - } - - return $arrayValues; - } // function flattenArrayIndexed() - - - /** - * Convert an array to a single scalar value by extracting the first element - * - * @param mixed $value Array or scalar value - * @return mixed - */ - public static function flattenSingleValue($value = '') { - while (is_array($value)) { - $value = array_pop($value); - } - - return $value; - } // function flattenSingleValue() - -} // class PHPExcel_Calculation_Functions + /** constants */ + const COMPATIBILITY_EXCEL = 'Excel'; + const COMPATIBILITY_GNUMERIC = 'Gnumeric'; + const COMPATIBILITY_OPENOFFICE = 'OpenOfficeCalc'; + + const RETURNDATE_PHP_NUMERIC = 'P'; + const RETURNDATE_PHP_OBJECT = 'O'; + const RETURNDATE_EXCEL = 'E'; + + + /** + * Compatibility mode to use for error checking and responses + * + * @access private + * @var string + */ + protected static $compatibilityMode = self::COMPATIBILITY_EXCEL; + + /** + * Data Type to use when returning date values + * + * @access private + * @var string + */ + protected static $ReturnDateType = self::RETURNDATE_EXCEL; + + /** + * List of error codes + * + * @access private + * @var array + */ + protected static $_errorCodes = array( 'null' => '#NULL!', + 'divisionbyzero' => '#DIV/0!', + 'value' => '#VALUE!', + 'reference' => '#REF!', + 'name' => '#NAME?', + 'num' => '#NUM!', + 'na' => '#N/A', + 'gettingdata' => '#GETTING_DATA' + ); + + + /** + * Set the Compatibility Mode + * + * @access public + * @category Function Configuration + * @param string $compatibilityMode Compatibility Mode + * Permitted values are: + * PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' + * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' + * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' + * @return boolean (Success or Failure) + */ + public static function setCompatibilityMode($compatibilityMode) { + if (($compatibilityMode == self::COMPATIBILITY_EXCEL) || + ($compatibilityMode == self::COMPATIBILITY_GNUMERIC) || + ($compatibilityMode == self::COMPATIBILITY_OPENOFFICE)) { + self::$compatibilityMode = $compatibilityMode; + return True; + } + return False; + } // function setCompatibilityMode() + + + /** + * Return the current Compatibility Mode + * + * @access public + * @category Function Configuration + * @return string Compatibility Mode + * Possible Return values are: + * PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' + * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' + * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' + */ + public static function getCompatibilityMode() { + return self::$compatibilityMode; + } // function getCompatibilityMode() + + + /** + * Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) + * + * @access public + * @category Function Configuration + * @param string $returnDateType Return Date Format + * Permitted values are: + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' + * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' + * @return boolean Success or failure + */ + public static function setReturnDateType($returnDateType) { + if (($returnDateType == self::RETURNDATE_PHP_NUMERIC) || + ($returnDateType == self::RETURNDATE_PHP_OBJECT) || + ($returnDateType == self::RETURNDATE_EXCEL)) { + self::$ReturnDateType = $returnDateType; + return True; + } + return False; + } // function setReturnDateType() + + + /** + * Return the current Return Date Format for functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) + * + * @access public + * @category Function Configuration + * @return string Return Date Format + * Possible Return values are: + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' + * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' + */ + public static function getReturnDateType() { + return self::$ReturnDateType; + } // function getReturnDateType() + + + /** + * DUMMY + * + * @access public + * @category Error Returns + * @return string #Not Yet Implemented + */ + public static function DUMMY() { + return '#Not Yet Implemented'; + } // function DUMMY() + + + /** + * DIV0 + * + * @access public + * @category Error Returns + * @return string #Not Yet Implemented + */ + public static function DIV0() { + return self::$_errorCodes['divisionbyzero']; + } // function DIV0() + + + /** + * NA + * + * Excel Function: + * =NA() + * + * Returns the error value #N/A + * #N/A is the error value that means "no value is available." + * + * @access public + * @category Logical Functions + * @return string #N/A! + */ + public static function NA() { + return self::$_errorCodes['na']; + } // function NA() + + + /** + * NaN + * + * Returns the error value #NUM! + * + * @access public + * @category Error Returns + * @return string #NUM! + */ + public static function NaN() { + return self::$_errorCodes['num']; + } // function NaN() + + + /** + * NAME + * + * Returns the error value #NAME? + * + * @access public + * @category Error Returns + * @return string #NAME? + */ + public static function NAME() { + return self::$_errorCodes['name']; + } // function NAME() + + + /** + * REF + * + * Returns the error value #REF! + * + * @access public + * @category Error Returns + * @return string #REF! + */ + public static function REF() { + return self::$_errorCodes['reference']; + } // function REF() + + + /** + * NULL + * + * Returns the error value #NULL! + * + * @access public + * @category Error Returns + * @return string #NULL! + */ + public static function NULL() { + return self::$_errorCodes['null']; + } // function NULL() + + + /** + * VALUE + * + * Returns the error value #VALUE! + * + * @access public + * @category Error Returns + * @return string #VALUE! + */ + public static function VALUE() { + return self::$_errorCodes['value']; + } // function VALUE() + + + public static function isMatrixValue($idx) { + return ((substr_count($idx,'.') <= 1) || (preg_match('/\.[A-Z]/',$idx) > 0)); + } + + + public static function isValue($idx) { + return (substr_count($idx,'.') == 0); + } + + + public static function isCellValue($idx) { + return (substr_count($idx,'.') > 1); + } + + + public static function _ifCondition($condition) { + $condition = PHPExcel_Calculation_Functions::flattenSingleValue($condition); + if (!isset($condition{0})) + $condition = '=""'; + if (!in_array($condition{0},array('>', '<', '='))) { + if (!is_numeric($condition)) { $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); } + return '='.$condition; + } else { + preg_match('/([<>=]+)(.*)/',$condition,$matches); + list(,$operator,$operand) = $matches; + + if (!is_numeric($operand)) { + $operand = str_replace('"', '""', $operand); + $operand = PHPExcel_Calculation::_wrapResult(strtoupper($operand)); + } + + return $operator.$operand; + } + } // function _ifCondition() + + + /** + * ERROR_TYPE + * + * @param mixed $value Value to check + * @return boolean + */ + public static function ERROR_TYPE($value = '') { + $value = self::flattenSingleValue($value); + + $i = 1; + foreach(self::$_errorCodes as $errorCode) { + if ($value === $errorCode) { + return $i; + } + ++$i; + } + return self::NA(); + } // function ERROR_TYPE() + + + /** + * IS_BLANK + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_BLANK($value = NULL) { + if (!is_null($value)) { + $value = self::flattenSingleValue($value); + } + + return is_null($value); + } // function IS_BLANK() + + + /** + * IS_ERR + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_ERR($value = '') { + $value = self::flattenSingleValue($value); + + return self::IS_ERROR($value) && (!self::IS_NA($value)); + } // function IS_ERR() + + + /** + * IS_ERROR + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_ERROR($value = '') { + $value = self::flattenSingleValue($value); + + if (!is_string($value)) + return false; + return in_array($value, array_values(self::$_errorCodes)); + } // function IS_ERROR() + + + /** + * IS_NA + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_NA($value = '') { + $value = self::flattenSingleValue($value); + + return ($value === self::NA()); + } // function IS_NA() + + + /** + * IS_EVEN + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_EVEN($value = NULL) { + $value = self::flattenSingleValue($value); + + if ($value === NULL) + return self::NAME(); + if ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) + return self::VALUE(); + return ($value % 2 == 0); + } // function IS_EVEN() + + + /** + * IS_ODD + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_ODD($value = NULL) { + $value = self::flattenSingleValue($value); + + if ($value === NULL) + return self::NAME(); + if ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) + return self::VALUE(); + return (abs($value) % 2 == 1); + } // function IS_ODD() + + + /** + * IS_NUMBER + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_NUMBER($value = NULL) { + $value = self::flattenSingleValue($value); + + if (is_string($value)) { + return False; + } + return is_numeric($value); + } // function IS_NUMBER() + + + /** + * IS_LOGICAL + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_LOGICAL($value = NULL) { + $value = self::flattenSingleValue($value); + + return is_bool($value); + } // function IS_LOGICAL() + + + /** + * IS_TEXT + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_TEXT($value = NULL) { + $value = self::flattenSingleValue($value); + + return (is_string($value) && !self::IS_ERROR($value)); + } // function IS_TEXT() + + + /** + * IS_NONTEXT + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_NONTEXT($value = NULL) { + return !self::IS_TEXT($value); + } // function IS_NONTEXT() + + + /** + * VERSION + * + * @return string Version information + */ + public static function VERSION() { + return 'PHPExcel ##VERSION##, ##DATE##'; + } // function VERSION() + + + /** + * N + * + * Returns a value converted to a number + * + * @param value The value you want converted + * @return number N converts values listed in the following table + * If value is or refers to N returns + * A number That number + * A date The serial number of that date + * TRUE 1 + * FALSE 0 + * An error value The error value + * Anything else 0 + */ + public static function N($value = NULL) { + while (is_array($value)) { + $value = array_shift($value); + } + + switch (gettype($value)) { + case 'double' : + case 'float' : + case 'integer' : + return $value; + break; + case 'boolean' : + return (integer) $value; + break; + case 'string' : + // Errors + if ((strlen($value) > 0) && ($value{0} == '#')) { + return $value; + } + break; + } + return 0; + } // function N() + + + /** + * TYPE + * + * Returns a number that identifies the type of a value + * + * @param value The value you want tested + * @return number N converts values listed in the following table + * If value is or refers to N returns + * A number 1 + * Text 2 + * Logical Value 4 + * An error value 16 + * Array or Matrix 64 + */ + public static function TYPE($value = NULL) { + $value = self::flattenArrayIndexed($value); + if (is_array($value) && (count($value) > 1)) { + $a = array_keys($value); + $a = array_pop($a); + // Range of cells is an error + if (self::isCellValue($a)) { + return 16; + // Test for Matrix + } elseif (self::isMatrixValue($a)) { + return 64; + } + } elseif(empty($value)) { + // Empty Cell + return 1; + } + $value = self::flattenSingleValue($value); + + if (($value === NULL) || (is_float($value)) || (is_int($value))) { + return 1; + } elseif(is_bool($value)) { + return 4; + } elseif(is_array($value)) { + return 64; + } elseif(is_string($value)) { + // Errors + if ((strlen($value) > 0) && ($value{0} == '#')) { + return 16; + } + return 2; + } + return 0; + } // function TYPE() + + + /** + * Convert a multi-dimensional array to a simple 1-dimensional array + * + * @param array $array Array to be flattened + * @return array Flattened array + */ + public static function flattenArray($array) { + if (!is_array($array)) { + return (array) $array; + } + + $arrayValues = array(); + foreach ($array as $value) { + if (is_array($value)) { + foreach ($value as $val) { + if (is_array($val)) { + foreach ($val as $v) { + $arrayValues[] = $v; + } + } else { + $arrayValues[] = $val; + } + } + } else { + $arrayValues[] = $value; + } + } + + return $arrayValues; + } // function flattenArray() + + + /** + * Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing + * + * @param array $array Array to be flattened + * @return array Flattened array + */ + public static function flattenArrayIndexed($array) { + if (!is_array($array)) { + return (array) $array; + } + + $arrayValues = array(); + foreach ($array as $k1 => $value) { + if (is_array($value)) { + foreach ($value as $k2 => $val) { + if (is_array($val)) { + foreach ($val as $k3 => $v) { + $arrayValues[$k1.'.'.$k2.'.'.$k3] = $v; + } + } else { + $arrayValues[$k1.'.'.$k2] = $val; + } + } + } else { + $arrayValues[$k1] = $value; + } + } + + return $arrayValues; + } // function flattenArrayIndexed() + + + /** + * Convert an array to a single scalar value by extracting the first element + * + * @param mixed $value Array or scalar value + * @return mixed + */ + public static function flattenSingleValue($value = '') { + while (is_array($value)) { + $value = array_pop($value); + } + + return $value; + } // function flattenSingleValue() + +} // class PHPExcel_Calculation_Functions // -// There are a few mathematical functions that aren't available on all versions of PHP for all platforms -// These functions aren't available in Windows implementations of PHP prior to version 5.3.0 -// So we test if they do exist for this version of PHP/operating platform; and if not we create them +// There are a few mathematical functions that aren't available on all versions of PHP for all platforms +// These functions aren't available in Windows implementations of PHP prior to version 5.3.0 +// So we test if they do exist for this version of PHP/operating platform; and if not we create them // if (!function_exists('acosh')) { - function acosh($x) { - return 2 * log(sqrt(($x + 1) / 2) + sqrt(($x - 1) / 2)); - } // function acosh() + function acosh($x) { + return 2 * log(sqrt(($x + 1) / 2) + sqrt(($x - 1) / 2)); + } // function acosh() } if (!function_exists('asinh')) { - function asinh($x) { - return log($x + sqrt(1 + $x * $x)); - } // function asinh() + function asinh($x) { + return log($x + sqrt(1 + $x * $x)); + } // function asinh() } if (!function_exists('atanh')) { - function atanh($x) { - return (log(1 + $x) - log(1 - $x)) / 2; - } // function atanh() + function atanh($x) { + return (log(1 + $x) - log(1 - $x)) / 2; + } // function atanh() } // -// Strangely, PHP doesn't have a mb_str_replace multibyte function -// As we'll only ever use this function with UTF-8 characters, we can simply "hard-code" the character set +// Strangely, PHP doesn't have a mb_str_replace multibyte function +// As we'll only ever use this function with UTF-8 characters, we can simply "hard-code" the character set // if ((!function_exists('mb_str_replace')) && - (function_exists('mb_substr')) && (function_exists('mb_strlen')) && (function_exists('mb_strpos'))) { - function mb_str_replace($search, $replace, $subject) { - if(is_array($subject)) { - $ret = array(); - foreach($subject as $key => $val) { - $ret[$key] = mb_str_replace($search, $replace, $val); - } - return $ret; - } - - foreach((array) $search as $key => $s) { - if($s == '' && $s !== 0) { - continue; - } - $r = !is_array($replace) ? $replace : (array_key_exists($key, $replace) ? $replace[$key] : ''); - $pos = mb_strpos($subject, $s, 0, 'UTF-8'); - while($pos !== false) { - $subject = mb_substr($subject, 0, $pos, 'UTF-8') . $r . mb_substr($subject, $pos + mb_strlen($s, 'UTF-8'), 65535, 'UTF-8'); - $pos = mb_strpos($subject, $s, $pos + mb_strlen($r, 'UTF-8'), 'UTF-8'); - } - } - return $subject; - } + (function_exists('mb_substr')) && (function_exists('mb_strlen')) && (function_exists('mb_strpos'))) { + function mb_str_replace($search, $replace, $subject) { + if(is_array($subject)) { + $ret = array(); + foreach($subject as $key => $val) { + $ret[$key] = mb_str_replace($search, $replace, $val); + } + return $ret; + } + + foreach((array) $search as $key => $s) { + if($s == '' && $s !== 0) { + continue; + } + $r = !is_array($replace) ? $replace : (array_key_exists($key, $replace) ? $replace[$key] : ''); + $pos = mb_strpos($subject, $s, 0, 'UTF-8'); + while($pos !== false) { + $subject = mb_substr($subject, 0, $pos, 'UTF-8') . $r . mb_substr($subject, $pos + mb_strlen($s, 'UTF-8'), 65535, 'UTF-8'); + $pos = mb_strpos($subject, $s, $pos + mb_strlen($r, 'UTF-8'), 'UTF-8'); + } + } + return $subject; + } } diff --git a/Classes/PHPExcel/Calculation/Logical.php b/Classes/PHPExcel/Calculation/Logical.php index 266a66278..ca5575cf3 100644 --- a/Classes/PHPExcel/Calculation/Logical.php +++ b/Classes/PHPExcel/Calculation/Logical.php @@ -18,271 +18,271 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** * PHPExcel_Calculation_Logical * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Logical { - /** - * TRUE - * - * Returns the boolean TRUE. - * - * Excel Function: - * =TRUE() - * - * @access public - * @category Logical Functions - * @return boolean True - */ - public static function TRUE() { - return TRUE; - } // function TRUE() + /** + * TRUE + * + * Returns the boolean TRUE. + * + * Excel Function: + * =TRUE() + * + * @access public + * @category Logical Functions + * @return boolean True + */ + public static function TRUE() { + return TRUE; + } // function TRUE() - /** - * FALSE - * - * Returns the boolean FALSE. - * - * Excel Function: - * =FALSE() - * - * @access public - * @category Logical Functions - * @return boolean False - */ - public static function FALSE() { - return FALSE; - } // function FALSE() + /** + * FALSE + * + * Returns the boolean FALSE. + * + * Excel Function: + * =FALSE() + * + * @access public + * @category Logical Functions + * @return boolean False + */ + public static function FALSE() { + return FALSE; + } // function FALSE() - /** - * LOGICAL_AND - * - * Returns boolean TRUE if all its arguments are TRUE; returns FALSE if one or more argument is FALSE. - * - * Excel Function: - * =AND(logical1[,logical2[, ...]]) - * - * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays - * or references that contain logical values. - * - * Boolean arguments are treated as True or False as appropriate - * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False - * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds - * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value - * - * @access public - * @category Logical Functions - * @param mixed $arg,... Data values - * @return boolean The logical AND of the arguments. - */ - public static function LOGICAL_AND() { - // Return value - $returnValue = TRUE; + /** + * LOGICAL_AND + * + * Returns boolean TRUE if all its arguments are TRUE; returns FALSE if one or more argument is FALSE. + * + * Excel Function: + * =AND(logical1[,logical2[, ...]]) + * + * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays + * or references that contain logical values. + * + * Boolean arguments are treated as True or False as appropriate + * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False + * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds + * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value + * + * @access public + * @category Logical Functions + * @param mixed $arg,... Data values + * @return boolean The logical AND of the arguments. + */ + public static function LOGICAL_AND() { + // Return value + $returnValue = TRUE; - // Loop through the arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - $argCount = -1; - foreach ($aArgs as $argCount => $arg) { - // Is it a boolean value? - if (is_bool($arg)) { - $returnValue = $returnValue && $arg; - } elseif ((is_numeric($arg)) && (!is_string($arg))) { - $returnValue = $returnValue && ($arg != 0); - } elseif (is_string($arg)) { - $arg = strtoupper($arg); - if (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) { - $arg = TRUE; - } elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) { - $arg = FALSE; - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - $returnValue = $returnValue && ($arg != 0); - } - } + // Loop through the arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $argCount = -1; + foreach ($aArgs as $argCount => $arg) { + // Is it a boolean value? + if (is_bool($arg)) { + $returnValue = $returnValue && $arg; + } elseif ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue = $returnValue && ($arg != 0); + } elseif (is_string($arg)) { + $arg = strtoupper($arg); + if (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) { + $arg = TRUE; + } elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) { + $arg = FALSE; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $returnValue = $returnValue && ($arg != 0); + } + } - // Return - if ($argCount < 0) { - return PHPExcel_Calculation_Functions::VALUE(); - } - return $returnValue; - } // function LOGICAL_AND() + // Return + if ($argCount < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + return $returnValue; + } // function LOGICAL_AND() - /** - * LOGICAL_OR - * - * Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE. - * - * Excel Function: - * =OR(logical1[,logical2[, ...]]) - * - * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays - * or references that contain logical values. - * - * Boolean arguments are treated as True or False as appropriate - * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False - * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds - * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value - * - * @access public - * @category Logical Functions - * @param mixed $arg,... Data values - * @return boolean The logical OR of the arguments. - */ - public static function LOGICAL_OR() { - // Return value - $returnValue = FALSE; + /** + * LOGICAL_OR + * + * Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE. + * + * Excel Function: + * =OR(logical1[,logical2[, ...]]) + * + * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays + * or references that contain logical values. + * + * Boolean arguments are treated as True or False as appropriate + * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False + * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds + * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value + * + * @access public + * @category Logical Functions + * @param mixed $arg,... Data values + * @return boolean The logical OR of the arguments. + */ + public static function LOGICAL_OR() { + // Return value + $returnValue = FALSE; - // Loop through the arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - $argCount = -1; - foreach ($aArgs as $argCount => $arg) { - // Is it a boolean value? - if (is_bool($arg)) { - $returnValue = $returnValue || $arg; - } elseif ((is_numeric($arg)) && (!is_string($arg))) { - $returnValue = $returnValue || ($arg != 0); - } elseif (is_string($arg)) { - $arg = strtoupper($arg); - if (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) { - $arg = TRUE; - } elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) { - $arg = FALSE; - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - $returnValue = $returnValue || ($arg != 0); - } - } + // Loop through the arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $argCount = -1; + foreach ($aArgs as $argCount => $arg) { + // Is it a boolean value? + if (is_bool($arg)) { + $returnValue = $returnValue || $arg; + } elseif ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue = $returnValue || ($arg != 0); + } elseif (is_string($arg)) { + $arg = strtoupper($arg); + if (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) { + $arg = TRUE; + } elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) { + $arg = FALSE; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $returnValue = $returnValue || ($arg != 0); + } + } - // Return - if ($argCount < 0) { - return PHPExcel_Calculation_Functions::VALUE(); - } - return $returnValue; - } // function LOGICAL_OR() + // Return + if ($argCount < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + return $returnValue; + } // function LOGICAL_OR() - /** - * NOT - * - * Returns the boolean inverse of the argument. - * - * Excel Function: - * =NOT(logical) - * - * The argument must evaluate to a logical value such as TRUE or FALSE - * - * Boolean arguments are treated as True or False as appropriate - * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False - * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds - * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value - * - * @access public - * @category Logical Functions - * @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE - * @return boolean The boolean inverse of the argument. - */ - public static function NOT($logical=FALSE) { - $logical = PHPExcel_Calculation_Functions::flattenSingleValue($logical); - if (is_string($logical)) { - $logical = strtoupper($logical); - if (($logical == 'TRUE') || ($logical == PHPExcel_Calculation::getTRUE())) { - return FALSE; - } elseif (($logical == 'FALSE') || ($logical == PHPExcel_Calculation::getFALSE())) { - return TRUE; - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - } + /** + * NOT + * + * Returns the boolean inverse of the argument. + * + * Excel Function: + * =NOT(logical) + * + * The argument must evaluate to a logical value such as TRUE or FALSE + * + * Boolean arguments are treated as True or False as appropriate + * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False + * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds + * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value + * + * @access public + * @category Logical Functions + * @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE + * @return boolean The boolean inverse of the argument. + */ + public static function NOT($logical=FALSE) { + $logical = PHPExcel_Calculation_Functions::flattenSingleValue($logical); + if (is_string($logical)) { + $logical = strtoupper($logical); + if (($logical == 'TRUE') || ($logical == PHPExcel_Calculation::getTRUE())) { + return FALSE; + } elseif (($logical == 'FALSE') || ($logical == PHPExcel_Calculation::getFALSE())) { + return TRUE; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } - return !$logical; - } // function NOT() + return !$logical; + } // function NOT() - /** - * STATEMENT_IF - * - * Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE. - * - * Excel Function: - * =IF(condition[,returnIfTrue[,returnIfFalse]]) - * - * Condition is any value or expression that can be evaluated to TRUE or FALSE. - * For example, A10=100 is a logical expression; if the value in cell A10 is equal to 100, - * the expression evaluates to TRUE. Otherwise, the expression evaluates to FALSE. - * This argument can use any comparison calculation operator. - * ReturnIfTrue is the value that is returned if condition evaluates to TRUE. - * For example, if this argument is the text string "Within budget" and the condition argument evaluates to TRUE, - * then the IF function returns the text "Within budget" - * If condition is TRUE and ReturnIfTrue is blank, this argument returns 0 (zero). To display the word TRUE, use - * the logical value TRUE for this argument. - * ReturnIfTrue can be another formula. - * ReturnIfFalse is the value that is returned if condition evaluates to FALSE. - * For example, if this argument is the text string "Over budget" and the condition argument evaluates to FALSE, - * then the IF function returns the text "Over budget". - * If condition is FALSE and ReturnIfFalse is omitted, then the logical value FALSE is returned. - * If condition is FALSE and ReturnIfFalse is blank, then the value 0 (zero) is returned. - * ReturnIfFalse can be another formula. - * - * @access public - * @category Logical Functions - * @param mixed $condition Condition to evaluate - * @param mixed $returnIfTrue Value to return when condition is true - * @param mixed $returnIfFalse Optional value to return when condition is false - * @return mixed The value of returnIfTrue or returnIfFalse determined by condition - */ - public static function STATEMENT_IF($condition = TRUE, $returnIfTrue = 0, $returnIfFalse = FALSE) { - $condition = (is_null($condition)) ? TRUE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($condition); - $returnIfTrue = (is_null($returnIfTrue)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($returnIfTrue); - $returnIfFalse = (is_null($returnIfFalse)) ? FALSE : PHPExcel_Calculation_Functions::flattenSingleValue($returnIfFalse); + /** + * STATEMENT_IF + * + * Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE. + * + * Excel Function: + * =IF(condition[,returnIfTrue[,returnIfFalse]]) + * + * Condition is any value or expression that can be evaluated to TRUE or FALSE. + * For example, A10=100 is a logical expression; if the value in cell A10 is equal to 100, + * the expression evaluates to TRUE. Otherwise, the expression evaluates to FALSE. + * This argument can use any comparison calculation operator. + * ReturnIfTrue is the value that is returned if condition evaluates to TRUE. + * For example, if this argument is the text string "Within budget" and the condition argument evaluates to TRUE, + * then the IF function returns the text "Within budget" + * If condition is TRUE and ReturnIfTrue is blank, this argument returns 0 (zero). To display the word TRUE, use + * the logical value TRUE for this argument. + * ReturnIfTrue can be another formula. + * ReturnIfFalse is the value that is returned if condition evaluates to FALSE. + * For example, if this argument is the text string "Over budget" and the condition argument evaluates to FALSE, + * then the IF function returns the text "Over budget". + * If condition is FALSE and ReturnIfFalse is omitted, then the logical value FALSE is returned. + * If condition is FALSE and ReturnIfFalse is blank, then the value 0 (zero) is returned. + * ReturnIfFalse can be another formula. + * + * @access public + * @category Logical Functions + * @param mixed $condition Condition to evaluate + * @param mixed $returnIfTrue Value to return when condition is true + * @param mixed $returnIfFalse Optional value to return when condition is false + * @return mixed The value of returnIfTrue or returnIfFalse determined by condition + */ + public static function STATEMENT_IF($condition = TRUE, $returnIfTrue = 0, $returnIfFalse = FALSE) { + $condition = (is_null($condition)) ? TRUE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($condition); + $returnIfTrue = (is_null($returnIfTrue)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($returnIfTrue); + $returnIfFalse = (is_null($returnIfFalse)) ? FALSE : PHPExcel_Calculation_Functions::flattenSingleValue($returnIfFalse); - return ($condition) ? $returnIfTrue : $returnIfFalse; - } // function STATEMENT_IF() + return ($condition) ? $returnIfTrue : $returnIfFalse; + } // function STATEMENT_IF() - /** - * IFERROR - * - * Excel Function: - * =IFERROR(testValue,errorpart) - * - * @access public - * @category Logical Functions - * @param mixed $testValue Value to check, is also the value returned when no error - * @param mixed $errorpart Value to return when testValue is an error condition - * @return mixed The value of errorpart or testValue determined by error condition - */ - public static function IFERROR($testValue = '', $errorpart = '') { - $testValue = (is_null($testValue)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($testValue); - $errorpart = (is_null($errorpart)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($errorpart); + /** + * IFERROR + * + * Excel Function: + * =IFERROR(testValue,errorpart) + * + * @access public + * @category Logical Functions + * @param mixed $testValue Value to check, is also the value returned when no error + * @param mixed $errorpart Value to return when testValue is an error condition + * @return mixed The value of errorpart or testValue determined by error condition + */ + public static function IFERROR($testValue = '', $errorpart = '') { + $testValue = (is_null($testValue)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($testValue); + $errorpart = (is_null($errorpart)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($errorpart); - return self::STATEMENT_IF(PHPExcel_Calculation_Functions::IS_ERROR($testValue), $errorpart, $testValue); - } // function IFERROR() + return self::STATEMENT_IF(PHPExcel_Calculation_Functions::IS_ERROR($testValue), $errorpart, $testValue); + } // function IFERROR() -} // class PHPExcel_Calculation_Logical +} // class PHPExcel_Calculation_Logical diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index 8a4e066ac..be2295431 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -18,729 +18,729 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** * PHPExcel_Calculation_LookupRef * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_LookupRef { - /** - * CELL_ADDRESS - * - * Creates a cell address as text, given specified row and column numbers. - * - * Excel Function: - * =ADDRESS(row, column, [relativity], [referenceStyle], [sheetText]) - * - * @param row Row number to use in the cell reference - * @param column Column number to use in the cell reference - * @param relativity Flag indicating the type of reference to return - * 1 or omitted Absolute - * 2 Absolute row; relative column - * 3 Relative row; absolute column - * 4 Relative - * @param referenceStyle A logical value that specifies the A1 or R1C1 reference style. - * TRUE or omitted CELL_ADDRESS returns an A1-style reference - * FALSE CELL_ADDRESS returns an R1C1-style reference - * @param sheetText Optional Name of worksheet to use - * @return string - */ - public static function CELL_ADDRESS($row, $column, $relativity=1, $referenceStyle=True, $sheetText='') { - $row = PHPExcel_Calculation_Functions::flattenSingleValue($row); - $column = PHPExcel_Calculation_Functions::flattenSingleValue($column); - $relativity = PHPExcel_Calculation_Functions::flattenSingleValue($relativity); - $sheetText = PHPExcel_Calculation_Functions::flattenSingleValue($sheetText); - - if (($row < 1) || ($column < 1)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if ($sheetText > '') { - if (strpos($sheetText,' ') !== False) { $sheetText = "'".$sheetText."'"; } - $sheetText .='!'; - } - if ((!is_bool($referenceStyle)) || $referenceStyle) { - $rowRelative = $columnRelative = '$'; - $column = PHPExcel_Cell::stringFromColumnIndex($column-1); - if (($relativity == 2) || ($relativity == 4)) { $columnRelative = ''; } - if (($relativity == 3) || ($relativity == 4)) { $rowRelative = ''; } - return $sheetText.$columnRelative.$column.$rowRelative.$row; - } else { - if (($relativity == 2) || ($relativity == 4)) { $column = '['.$column.']'; } - if (($relativity == 3) || ($relativity == 4)) { $row = '['.$row.']'; } - return $sheetText.'R'.$row.'C'.$column; - } - } // function CELL_ADDRESS() - - - /** - * COLUMN - * - * Returns the column number of the given cell reference - * If the cell reference is a range of cells, COLUMN returns the column numbers of each column in the reference as a horizontal array. - * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the - * reference of the cell in which the COLUMN function appears; otherwise this function returns 0. - * - * Excel Function: - * =COLUMN([cellAddress]) - * - * @param cellAddress A reference to a range of cells for which you want the column numbers - * @return integer or array of integer - */ - public static function COLUMN($cellAddress=Null) { - if (is_null($cellAddress) || trim($cellAddress) === '') { return 0; } - - if (is_array($cellAddress)) { - foreach($cellAddress as $columnKey => $value) { - $columnKey = preg_replace('/[^a-z]/i','',$columnKey); - return (integer) PHPExcel_Cell::columnIndexFromString($columnKey); - } - } else { - if (strpos($cellAddress,'!') !== false) { - list($sheet,$cellAddress) = explode('!',$cellAddress); - } - if (strpos($cellAddress,':') !== false) { - list($startAddress,$endAddress) = explode(':',$cellAddress); - $startAddress = preg_replace('/[^a-z]/i','',$startAddress); - $endAddress = preg_replace('/[^a-z]/i','',$endAddress); - $returnValue = array(); - do { - $returnValue[] = (integer) PHPExcel_Cell::columnIndexFromString($startAddress); - } while ($startAddress++ != $endAddress); - return $returnValue; - } else { - $cellAddress = preg_replace('/[^a-z]/i','',$cellAddress); - return (integer) PHPExcel_Cell::columnIndexFromString($cellAddress); - } - } - } // function COLUMN() - - - /** - * COLUMNS - * - * Returns the number of columns in an array or reference. - * - * Excel Function: - * =COLUMNS(cellAddress) - * - * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of columns - * @return integer The number of columns in cellAddress - */ - public static function COLUMNS($cellAddress=Null) { - if (is_null($cellAddress) || $cellAddress === '') { - return 1; - } elseif (!is_array($cellAddress)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - $x = array_keys($cellAddress); - $x = array_shift($x); - $isMatrix = (is_numeric($x)); - list($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); - - if ($isMatrix) { - return $rows; - } else { - return $columns; - } - } // function COLUMNS() - - - /** - * ROW - * - * Returns the row number of the given cell reference - * If the cell reference is a range of cells, ROW returns the row numbers of each row in the reference as a vertical array. - * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the - * reference of the cell in which the ROW function appears; otherwise this function returns 0. - * - * Excel Function: - * =ROW([cellAddress]) - * - * @param cellAddress A reference to a range of cells for which you want the row numbers - * @return integer or array of integer - */ - public static function ROW($cellAddress=Null) { - if (is_null($cellAddress) || trim($cellAddress) === '') { return 0; } - - if (is_array($cellAddress)) { - foreach($cellAddress as $columnKey => $rowValue) { - foreach($rowValue as $rowKey => $cellValue) { - return (integer) preg_replace('/[^0-9]/i','',$rowKey); - } - } - } else { - if (strpos($cellAddress,'!') !== false) { - list($sheet,$cellAddress) = explode('!',$cellAddress); - } - if (strpos($cellAddress,':') !== false) { - list($startAddress,$endAddress) = explode(':',$cellAddress); - $startAddress = preg_replace('/[^0-9]/','',$startAddress); - $endAddress = preg_replace('/[^0-9]/','',$endAddress); - $returnValue = array(); - do { - $returnValue[][] = (integer) $startAddress; - } while ($startAddress++ != $endAddress); - return $returnValue; - } else { - list($cellAddress) = explode(':',$cellAddress); - return (integer) preg_replace('/[^0-9]/','',$cellAddress); - } - } - } // function ROW() - - - /** - * ROWS - * - * Returns the number of rows in an array or reference. - * - * Excel Function: - * =ROWS(cellAddress) - * - * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of rows - * @return integer The number of rows in cellAddress - */ - public static function ROWS($cellAddress=Null) { - if (is_null($cellAddress) || $cellAddress === '') { - return 1; - } elseif (!is_array($cellAddress)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - $i = array_keys($cellAddress); - $isMatrix = (is_numeric(array_shift($i))); - list($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); - - if ($isMatrix) { - return $columns; - } else { - return $rows; - } - } // function ROWS() - - - /** - * HYPERLINK - * - * Excel Function: - * =HYPERLINK(linkURL,displayName) - * - * @access public - * @category Logical Functions - * @param string $linkURL Value to check, is also the value returned when no error - * @param string $displayName Value to return when testValue is an error condition - * @param PHPExcel_Cell $pCell The cell to set the hyperlink in - * @return mixed The value of $displayName (or $linkURL if $displayName was blank) - */ - public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Cell $pCell = null) { - $args = func_get_args(); - $pCell = array_pop($args); - - $linkURL = (is_null($linkURL)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($linkURL); - $displayName = (is_null($displayName)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($displayName); - - if ((!is_object($pCell)) || (trim($linkURL) == '')) { - return PHPExcel_Calculation_Functions::REF(); - } - - if ((is_object($displayName)) || trim($displayName) == '') { - $displayName = $linkURL; - } - - $pCell->getHyperlink()->setUrl($linkURL); - - return $displayName; - } // function HYPERLINK() - - - /** - * INDIRECT - * - * Returns the reference specified by a text string. - * References are immediately evaluated to display their contents. - * - * Excel Function: - * =INDIRECT(cellAddress) - * - * NOTE - INDIRECT() does not yet support the optional a1 parameter introduced in Excel 2010 - * - * @param cellAddress $cellAddress The cell address of the current cell (containing this formula) - * @param PHPExcel_Cell $pCell The current cell (containing this formula) - * @return mixed The cells referenced by cellAddress - * - * @todo Support for the optional a1 parameter introduced in Excel 2010 - * - */ - public static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL) { - $cellAddress = PHPExcel_Calculation_Functions::flattenSingleValue($cellAddress); - if (is_null($cellAddress) || $cellAddress === '') { - return PHPExcel_Calculation_Functions::REF(); - } - - $cellAddress1 = $cellAddress; - $cellAddress2 = NULL; - if (strpos($cellAddress,':') !== false) { - list($cellAddress1,$cellAddress2) = explode(':',$cellAddress); - } - - if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress1, $matches)) || - ((!is_null($cellAddress2)) && (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress2, $matches)))) { - if (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $cellAddress1, $matches)) { - return PHPExcel_Calculation_Functions::REF(); - } - - if (strpos($cellAddress,'!') !== FALSE) { - list($sheetName, $cellAddress) = explode('!',$cellAddress); - $sheetName = trim($sheetName, "'"); - $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); - } else { - $pSheet = $pCell->getWorksheet(); - } - - return PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, FALSE); - } - - if (strpos($cellAddress,'!') !== FALSE) { - list($sheetName,$cellAddress) = explode('!',$cellAddress); - $sheetName = trim($sheetName, "'"); - $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); - } else { - $pSheet = $pCell->getWorksheet(); - } - - return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, FALSE); - } // function INDIRECT() - - - /** - * OFFSET - * - * Returns a reference to a range that is a specified number of rows and columns from a cell or range of cells. - * The reference that is returned can be a single cell or a range of cells. You can specify the number of rows and - * the number of columns to be returned. - * - * Excel Function: - * =OFFSET(cellAddress, rows, cols, [height], [width]) - * - * @param cellAddress The reference from which you want to base the offset. Reference must refer to a cell or - * range of adjacent cells; otherwise, OFFSET returns the #VALUE! error value. - * @param rows The number of rows, up or down, that you want the upper-left cell to refer to. - * Using 5 as the rows argument specifies that the upper-left cell in the reference is - * five rows below reference. Rows can be positive (which means below the starting reference) - * or negative (which means above the starting reference). - * @param cols The number of columns, to the left or right, that you want the upper-left cell of the result - * to refer to. Using 5 as the cols argument specifies that the upper-left cell in the - * reference is five columns to the right of reference. Cols can be positive (which means - * to the right of the starting reference) or negative (which means to the left of the - * starting reference). - * @param height The height, in number of rows, that you want the returned reference to be. Height must be a positive number. - * @param width The width, in number of columns, that you want the returned reference to be. Width must be a positive number. - * @return string A reference to a cell or range of cells - */ - public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null,$width=null) { - $rows = PHPExcel_Calculation_Functions::flattenSingleValue($rows); - $columns = PHPExcel_Calculation_Functions::flattenSingleValue($columns); - $height = PHPExcel_Calculation_Functions::flattenSingleValue($height); - $width = PHPExcel_Calculation_Functions::flattenSingleValue($width); - if ($cellAddress == Null) { - return 0; - } - - $args = func_get_args(); - $pCell = array_pop($args); - if (!is_object($pCell)) { - return PHPExcel_Calculation_Functions::REF(); - } - - $sheetName = NULL; - if (strpos($cellAddress,"!")) { - list($sheetName,$cellAddress) = explode("!",$cellAddress); - $sheetName = trim($sheetName, "'"); - } - if (strpos($cellAddress,":")) { - list($startCell,$endCell) = explode(":",$cellAddress); - } else { - $startCell = $endCell = $cellAddress; - } - list($startCellColumn,$startCellRow) = PHPExcel_Cell::coordinateFromString($startCell); - list($endCellColumn,$endCellRow) = PHPExcel_Cell::coordinateFromString($endCell); - - $startCellRow += $rows; - $startCellColumn = PHPExcel_Cell::columnIndexFromString($startCellColumn) - 1; - $startCellColumn += $columns; - - if (($startCellRow <= 0) || ($startCellColumn < 0)) { - return PHPExcel_Calculation_Functions::REF(); - } - $endCellColumn = PHPExcel_Cell::columnIndexFromString($endCellColumn) - 1; - if (($width != null) && (!is_object($width))) { - $endCellColumn = $startCellColumn + $width - 1; - } else { - $endCellColumn += $columns; - } - $startCellColumn = PHPExcel_Cell::stringFromColumnIndex($startCellColumn); - - if (($height != null) && (!is_object($height))) { - $endCellRow = $startCellRow + $height - 1; - } else { - $endCellRow += $rows; - } - - if (($endCellRow <= 0) || ($endCellColumn < 0)) { - return PHPExcel_Calculation_Functions::REF(); - } - $endCellColumn = PHPExcel_Cell::stringFromColumnIndex($endCellColumn); - - $cellAddress = $startCellColumn.$startCellRow; - if (($startCellColumn != $endCellColumn) || ($startCellRow != $endCellRow)) { - $cellAddress .= ':'.$endCellColumn.$endCellRow; - } - - if ($sheetName !== NULL) { - $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); - } else { - $pSheet = $pCell->getWorksheet(); - } - - return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, False); - } // function OFFSET() - - - /** - * CHOOSE - * - * Uses lookup_value to return a value from the list of value arguments. - * Use CHOOSE to select one of up to 254 values based on the lookup_value. - * - * Excel Function: - * =CHOOSE(index_num, value1, [value2], ...) - * - * @param index_num Specifies which value argument is selected. - * Index_num must be a number between 1 and 254, or a formula or reference to a cell containing a number - * between 1 and 254. - * @param value1... Value1 is required, subsequent values are optional. - * Between 1 to 254 value arguments from which CHOOSE selects a value or an action to perform based on - * index_num. The arguments can be numbers, cell references, defined names, formulas, functions, or - * text. - * @return mixed The selected value - */ - public static function CHOOSE() { - $chooseArgs = func_get_args(); - $chosenEntry = PHPExcel_Calculation_Functions::flattenArray(array_shift($chooseArgs)); - $entryCount = count($chooseArgs) - 1; - - if(is_array($chosenEntry)) { - $chosenEntry = array_shift($chosenEntry); - } - if ((is_numeric($chosenEntry)) && (!is_bool($chosenEntry))) { - --$chosenEntry; - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - $chosenEntry = floor($chosenEntry); - if (($chosenEntry < 0) || ($chosenEntry > $entryCount)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (is_array($chooseArgs[$chosenEntry])) { - return PHPExcel_Calculation_Functions::flattenArray($chooseArgs[$chosenEntry]); - } else { - return $chooseArgs[$chosenEntry]; - } - } // function CHOOSE() - - - /** - * MATCH - * - * The MATCH function searches for a specified item in a range of cells - * - * Excel Function: - * =MATCH(lookup_value, lookup_array, [match_type]) - * - * @param lookup_value The value that you want to match in lookup_array - * @param lookup_array The range of cells being searched - * @param match_type The number -1, 0, or 1. -1 means above, 0 means exact match, 1 means below. If match_type is 1 or -1, the list has to be ordered. - * @return integer The relative position of the found item - */ - public static function MATCH($lookup_value, $lookup_array, $match_type=1) { - $lookup_array = PHPExcel_Calculation_Functions::flattenArray($lookup_array); - $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); - $match_type = (is_null($match_type)) ? 1 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($match_type); - // MATCH is not case sensitive - $lookup_value = strtolower($lookup_value); - - // lookup_value type has to be number, text, or logical values - if ((!is_numeric($lookup_value)) && (!is_string($lookup_value)) && (!is_bool($lookup_value))) { - return PHPExcel_Calculation_Functions::NA(); - } - - // match_type is 0, 1 or -1 - if (($match_type !== 0) && ($match_type !== -1) && ($match_type !== 1)) { - return PHPExcel_Calculation_Functions::NA(); - } - - // lookup_array should not be empty - $lookupArraySize = count($lookup_array); - if ($lookupArraySize <= 0) { - return PHPExcel_Calculation_Functions::NA(); - } - - // lookup_array should contain only number, text, or logical values, or empty (null) cells - foreach($lookup_array as $i => $lookupArrayValue) { - // check the type of the value - if ((!is_numeric($lookupArrayValue)) && (!is_string($lookupArrayValue)) && - (!is_bool($lookupArrayValue)) && (!is_null($lookupArrayValue))) { - return PHPExcel_Calculation_Functions::NA(); - } - // convert strings to lowercase for case-insensitive testing - if (is_string($lookupArrayValue)) { - $lookup_array[$i] = strtolower($lookupArrayValue); - } - if ((is_null($lookupArrayValue)) && (($match_type == 1) || ($match_type == -1))) { - $lookup_array = array_slice($lookup_array,0,$i-1); - } - } - - // if match_type is 1 or -1, the list has to be ordered - if ($match_type == 1) { - asort($lookup_array); - $keySet = array_keys($lookup_array); - } elseif($match_type == -1) { - arsort($lookup_array); - $keySet = array_keys($lookup_array); - } - - // ** - // find the match - // ** - // loop on the cells -// var_dump($lookup_array); -// echo '
'; - foreach($lookup_array as $i => $lookupArrayValue) { - if (($match_type == 0) && ($lookupArrayValue == $lookup_value)) { - // exact match - return ++$i; - } elseif (($match_type == -1) && ($lookupArrayValue <= $lookup_value)) { -// echo '$i = '.$i.' => '; -// var_dump($lookupArrayValue); -// echo '
'; -// echo 'Keyset = '; -// var_dump($keySet); -// echo '
'; - $i = array_search($i,$keySet); -// echo '$i='.$i.'
'; - // if match_type is -1 <=> find the smallest value that is greater than or equal to lookup_value - if ($i < 1){ - // 1st cell was allready smaller than the lookup_value - break; - } else { - // the previous cell was the match - return $keySet[$i-1]+1; - } - } elseif (($match_type == 1) && ($lookupArrayValue >= $lookup_value)) { -// echo '$i = '.$i.' => '; -// var_dump($lookupArrayValue); -// echo '
'; -// echo 'Keyset = '; -// var_dump($keySet); -// echo '
'; - $i = array_search($i,$keySet); -// echo '$i='.$i.'
'; - // if match_type is 1 <=> find the largest value that is less than or equal to lookup_value - if ($i < 1){ - // 1st cell was allready bigger than the lookup_value - break; - } else { - // the previous cell was the match - return $keySet[$i-1]+1; - } - } - } - - // unsuccessful in finding a match, return #N/A error value - return PHPExcel_Calculation_Functions::NA(); - } // function MATCH() - - - /** - * INDEX - * - * Uses an index to choose a value from a reference or array - * - * Excel Function: - * =INDEX(range_array, row_num, [column_num]) - * - * @param range_array A range of cells or an array constant - * @param row_num The row in array from which to return a value. If row_num is omitted, column_num is required. - * @param column_num The column in array from which to return a value. If column_num is omitted, row_num is required. - * @return mixed the value of a specified cell or array of cells - */ - public static function INDEX($arrayValues,$rowNum = 0,$columnNum = 0) { - - if (($rowNum < 0) || ($columnNum < 0)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (!is_array($arrayValues)) { - return PHPExcel_Calculation_Functions::REF(); - } - - $rowKeys = array_keys($arrayValues); - $columnKeys = @array_keys($arrayValues[$rowKeys[0]]); - - if ($columnNum > count($columnKeys)) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif ($columnNum == 0) { - if ($rowNum == 0) { - return $arrayValues; - } - $rowNum = $rowKeys[--$rowNum]; - $returnArray = array(); - foreach($arrayValues as $arrayColumn) { - if (is_array($arrayColumn)) { - if (isset($arrayColumn[$rowNum])) { - $returnArray[] = $arrayColumn[$rowNum]; - } else { - return $arrayValues[$rowNum]; - } - } else { - return $arrayValues[$rowNum]; - } - } - return $returnArray; - } - $columnNum = $columnKeys[--$columnNum]; - if ($rowNum > count($rowKeys)) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif ($rowNum == 0) { - return $arrayValues[$columnNum]; - } - $rowNum = $rowKeys[--$rowNum]; - - return $arrayValues[$rowNum][$columnNum]; - } // function INDEX() - - - /** - * TRANSPOSE - * - * @param array $matrixData A matrix of values - * @return array - * - * Unlike the Excel TRANSPOSE function, which will only work on a single row or column, this function will transpose a full matrix. - */ - public static function TRANSPOSE($matrixData) { - $returnMatrix = array(); - if (!is_array($matrixData)) { $matrixData = array(array($matrixData)); } - - $column = 0; - foreach($matrixData as $matrixRow) { - $row = 0; - foreach($matrixRow as $matrixCell) { - $returnMatrix[$row][$column] = $matrixCell; - ++$row; - } - ++$column; - } - return $returnMatrix; - } // function TRANSPOSE() - - - private static function _vlookupSort($a,$b) { - $f = array_keys($a); - $firstColumn = array_shift($f); - if (strtolower($a[$firstColumn]) == strtolower($b[$firstColumn])) { - return 0; - } - return (strtolower($a[$firstColumn]) < strtolower($b[$firstColumn])) ? -1 : 1; - } // function _vlookupSort() - - - /** - * VLOOKUP - * The VLOOKUP function searches for value in the left-most column of lookup_array and returns the value in the same row based on the index_number. - * @param lookup_value The value that you want to match in lookup_array - * @param lookup_array The range of cells being searched - * @param index_number The column number in table_array from which the matching value must be returned. The first column is 1. - * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. - * @return mixed The value of the found cell - */ - public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) { - $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); - $index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); - $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); - - // index_number must be greater than or equal to 1 - if ($index_number < 1) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - // index_number must be less than or equal to the number of columns in lookup_array - if ((!is_array($lookup_array)) || (empty($lookup_array))) { - return PHPExcel_Calculation_Functions::REF(); - } else { - $f = array_keys($lookup_array); - $firstRow = array_pop($f); - if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) { - return PHPExcel_Calculation_Functions::REF(); - } else { - $columnKeys = array_keys($lookup_array[$firstRow]); - $returnColumn = $columnKeys[--$index_number]; - $firstColumn = array_shift($columnKeys); - } - } - - if (!$not_exact_match) { - uasort($lookup_array,array('self','_vlookupSort')); - } - - $rowNumber = $rowValue = False; - foreach($lookup_array as $rowKey => $rowData) { - if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) || - (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) { - break; - } - $rowNumber = $rowKey; - $rowValue = $rowData[$firstColumn]; - } - - if ($rowNumber !== false) { - if ((!$not_exact_match) && ($rowValue != $lookup_value)) { - // if an exact match is required, we have what we need to return an appropriate response - return PHPExcel_Calculation_Functions::NA(); - } else { - // otherwise return the appropriate value - return $lookup_array[$rowNumber][$returnColumn]; - } - } - - return PHPExcel_Calculation_Functions::NA(); - } // function VLOOKUP() + /** + * CELL_ADDRESS + * + * Creates a cell address as text, given specified row and column numbers. + * + * Excel Function: + * =ADDRESS(row, column, [relativity], [referenceStyle], [sheetText]) + * + * @param row Row number to use in the cell reference + * @param column Column number to use in the cell reference + * @param relativity Flag indicating the type of reference to return + * 1 or omitted Absolute + * 2 Absolute row; relative column + * 3 Relative row; absolute column + * 4 Relative + * @param referenceStyle A logical value that specifies the A1 or R1C1 reference style. + * TRUE or omitted CELL_ADDRESS returns an A1-style reference + * FALSE CELL_ADDRESS returns an R1C1-style reference + * @param sheetText Optional Name of worksheet to use + * @return string + */ + public static function CELL_ADDRESS($row, $column, $relativity=1, $referenceStyle=True, $sheetText='') { + $row = PHPExcel_Calculation_Functions::flattenSingleValue($row); + $column = PHPExcel_Calculation_Functions::flattenSingleValue($column); + $relativity = PHPExcel_Calculation_Functions::flattenSingleValue($relativity); + $sheetText = PHPExcel_Calculation_Functions::flattenSingleValue($sheetText); + + if (($row < 1) || ($column < 1)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if ($sheetText > '') { + if (strpos($sheetText,' ') !== False) { $sheetText = "'".$sheetText."'"; } + $sheetText .='!'; + } + if ((!is_bool($referenceStyle)) || $referenceStyle) { + $rowRelative = $columnRelative = '$'; + $column = PHPExcel_Cell::stringFromColumnIndex($column-1); + if (($relativity == 2) || ($relativity == 4)) { $columnRelative = ''; } + if (($relativity == 3) || ($relativity == 4)) { $rowRelative = ''; } + return $sheetText.$columnRelative.$column.$rowRelative.$row; + } else { + if (($relativity == 2) || ($relativity == 4)) { $column = '['.$column.']'; } + if (($relativity == 3) || ($relativity == 4)) { $row = '['.$row.']'; } + return $sheetText.'R'.$row.'C'.$column; + } + } // function CELL_ADDRESS() + + + /** + * COLUMN + * + * Returns the column number of the given cell reference + * If the cell reference is a range of cells, COLUMN returns the column numbers of each column in the reference as a horizontal array. + * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the + * reference of the cell in which the COLUMN function appears; otherwise this function returns 0. + * + * Excel Function: + * =COLUMN([cellAddress]) + * + * @param cellAddress A reference to a range of cells for which you want the column numbers + * @return integer or array of integer + */ + public static function COLUMN($cellAddress=Null) { + if (is_null($cellAddress) || trim($cellAddress) === '') { return 0; } + + if (is_array($cellAddress)) { + foreach($cellAddress as $columnKey => $value) { + $columnKey = preg_replace('/[^a-z]/i','',$columnKey); + return (integer) PHPExcel_Cell::columnIndexFromString($columnKey); + } + } else { + if (strpos($cellAddress,'!') !== false) { + list($sheet,$cellAddress) = explode('!',$cellAddress); + } + if (strpos($cellAddress,':') !== false) { + list($startAddress,$endAddress) = explode(':',$cellAddress); + $startAddress = preg_replace('/[^a-z]/i','',$startAddress); + $endAddress = preg_replace('/[^a-z]/i','',$endAddress); + $returnValue = array(); + do { + $returnValue[] = (integer) PHPExcel_Cell::columnIndexFromString($startAddress); + } while ($startAddress++ != $endAddress); + return $returnValue; + } else { + $cellAddress = preg_replace('/[^a-z]/i','',$cellAddress); + return (integer) PHPExcel_Cell::columnIndexFromString($cellAddress); + } + } + } // function COLUMN() + + + /** + * COLUMNS + * + * Returns the number of columns in an array or reference. + * + * Excel Function: + * =COLUMNS(cellAddress) + * + * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of columns + * @return integer The number of columns in cellAddress + */ + public static function COLUMNS($cellAddress=Null) { + if (is_null($cellAddress) || $cellAddress === '') { + return 1; + } elseif (!is_array($cellAddress)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $x = array_keys($cellAddress); + $x = array_shift($x); + $isMatrix = (is_numeric($x)); + list($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); + + if ($isMatrix) { + return $rows; + } else { + return $columns; + } + } // function COLUMNS() + + + /** + * ROW + * + * Returns the row number of the given cell reference + * If the cell reference is a range of cells, ROW returns the row numbers of each row in the reference as a vertical array. + * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the + * reference of the cell in which the ROW function appears; otherwise this function returns 0. + * + * Excel Function: + * =ROW([cellAddress]) + * + * @param cellAddress A reference to a range of cells for which you want the row numbers + * @return integer or array of integer + */ + public static function ROW($cellAddress=Null) { + if (is_null($cellAddress) || trim($cellAddress) === '') { return 0; } + + if (is_array($cellAddress)) { + foreach($cellAddress as $columnKey => $rowValue) { + foreach($rowValue as $rowKey => $cellValue) { + return (integer) preg_replace('/[^0-9]/i','',$rowKey); + } + } + } else { + if (strpos($cellAddress,'!') !== false) { + list($sheet,$cellAddress) = explode('!',$cellAddress); + } + if (strpos($cellAddress,':') !== false) { + list($startAddress,$endAddress) = explode(':',$cellAddress); + $startAddress = preg_replace('/[^0-9]/','',$startAddress); + $endAddress = preg_replace('/[^0-9]/','',$endAddress); + $returnValue = array(); + do { + $returnValue[][] = (integer) $startAddress; + } while ($startAddress++ != $endAddress); + return $returnValue; + } else { + list($cellAddress) = explode(':',$cellAddress); + return (integer) preg_replace('/[^0-9]/','',$cellAddress); + } + } + } // function ROW() + + + /** + * ROWS + * + * Returns the number of rows in an array or reference. + * + * Excel Function: + * =ROWS(cellAddress) + * + * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of rows + * @return integer The number of rows in cellAddress + */ + public static function ROWS($cellAddress=Null) { + if (is_null($cellAddress) || $cellAddress === '') { + return 1; + } elseif (!is_array($cellAddress)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $i = array_keys($cellAddress); + $isMatrix = (is_numeric(array_shift($i))); + list($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); + + if ($isMatrix) { + return $columns; + } else { + return $rows; + } + } // function ROWS() + + + /** + * HYPERLINK + * + * Excel Function: + * =HYPERLINK(linkURL,displayName) + * + * @access public + * @category Logical Functions + * @param string $linkURL Value to check, is also the value returned when no error + * @param string $displayName Value to return when testValue is an error condition + * @param PHPExcel_Cell $pCell The cell to set the hyperlink in + * @return mixed The value of $displayName (or $linkURL if $displayName was blank) + */ + public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Cell $pCell = null) { + $args = func_get_args(); + $pCell = array_pop($args); + + $linkURL = (is_null($linkURL)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($linkURL); + $displayName = (is_null($displayName)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($displayName); + + if ((!is_object($pCell)) || (trim($linkURL) == '')) { + return PHPExcel_Calculation_Functions::REF(); + } + + if ((is_object($displayName)) || trim($displayName) == '') { + $displayName = $linkURL; + } + + $pCell->getHyperlink()->setUrl($linkURL); + + return $displayName; + } // function HYPERLINK() + + + /** + * INDIRECT + * + * Returns the reference specified by a text string. + * References are immediately evaluated to display their contents. + * + * Excel Function: + * =INDIRECT(cellAddress) + * + * NOTE - INDIRECT() does not yet support the optional a1 parameter introduced in Excel 2010 + * + * @param cellAddress $cellAddress The cell address of the current cell (containing this formula) + * @param PHPExcel_Cell $pCell The current cell (containing this formula) + * @return mixed The cells referenced by cellAddress + * + * @todo Support for the optional a1 parameter introduced in Excel 2010 + * + */ + public static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL) { + $cellAddress = PHPExcel_Calculation_Functions::flattenSingleValue($cellAddress); + if (is_null($cellAddress) || $cellAddress === '') { + return PHPExcel_Calculation_Functions::REF(); + } + + $cellAddress1 = $cellAddress; + $cellAddress2 = NULL; + if (strpos($cellAddress,':') !== false) { + list($cellAddress1,$cellAddress2) = explode(':',$cellAddress); + } + + if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress1, $matches)) || + ((!is_null($cellAddress2)) && (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress2, $matches)))) { + if (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $cellAddress1, $matches)) { + return PHPExcel_Calculation_Functions::REF(); + } + + if (strpos($cellAddress,'!') !== FALSE) { + list($sheetName, $cellAddress) = explode('!',$cellAddress); + $sheetName = trim($sheetName, "'"); + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); + } else { + $pSheet = $pCell->getWorksheet(); + } + + return PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, FALSE); + } + + if (strpos($cellAddress,'!') !== FALSE) { + list($sheetName,$cellAddress) = explode('!',$cellAddress); + $sheetName = trim($sheetName, "'"); + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); + } else { + $pSheet = $pCell->getWorksheet(); + } + + return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, FALSE); + } // function INDIRECT() + + + /** + * OFFSET + * + * Returns a reference to a range that is a specified number of rows and columns from a cell or range of cells. + * The reference that is returned can be a single cell or a range of cells. You can specify the number of rows and + * the number of columns to be returned. + * + * Excel Function: + * =OFFSET(cellAddress, rows, cols, [height], [width]) + * + * @param cellAddress The reference from which you want to base the offset. Reference must refer to a cell or + * range of adjacent cells; otherwise, OFFSET returns the #VALUE! error value. + * @param rows The number of rows, up or down, that you want the upper-left cell to refer to. + * Using 5 as the rows argument specifies that the upper-left cell in the reference is + * five rows below reference. Rows can be positive (which means below the starting reference) + * or negative (which means above the starting reference). + * @param cols The number of columns, to the left or right, that you want the upper-left cell of the result + * to refer to. Using 5 as the cols argument specifies that the upper-left cell in the + * reference is five columns to the right of reference. Cols can be positive (which means + * to the right of the starting reference) or negative (which means to the left of the + * starting reference). + * @param height The height, in number of rows, that you want the returned reference to be. Height must be a positive number. + * @param width The width, in number of columns, that you want the returned reference to be. Width must be a positive number. + * @return string A reference to a cell or range of cells + */ + public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null,$width=null) { + $rows = PHPExcel_Calculation_Functions::flattenSingleValue($rows); + $columns = PHPExcel_Calculation_Functions::flattenSingleValue($columns); + $height = PHPExcel_Calculation_Functions::flattenSingleValue($height); + $width = PHPExcel_Calculation_Functions::flattenSingleValue($width); + if ($cellAddress == Null) { + return 0; + } + + $args = func_get_args(); + $pCell = array_pop($args); + if (!is_object($pCell)) { + return PHPExcel_Calculation_Functions::REF(); + } + + $sheetName = NULL; + if (strpos($cellAddress,"!")) { + list($sheetName,$cellAddress) = explode("!",$cellAddress); + $sheetName = trim($sheetName, "'"); + } + if (strpos($cellAddress,":")) { + list($startCell,$endCell) = explode(":",$cellAddress); + } else { + $startCell = $endCell = $cellAddress; + } + list($startCellColumn,$startCellRow) = PHPExcel_Cell::coordinateFromString($startCell); + list($endCellColumn,$endCellRow) = PHPExcel_Cell::coordinateFromString($endCell); + + $startCellRow += $rows; + $startCellColumn = PHPExcel_Cell::columnIndexFromString($startCellColumn) - 1; + $startCellColumn += $columns; + + if (($startCellRow <= 0) || ($startCellColumn < 0)) { + return PHPExcel_Calculation_Functions::REF(); + } + $endCellColumn = PHPExcel_Cell::columnIndexFromString($endCellColumn) - 1; + if (($width != null) && (!is_object($width))) { + $endCellColumn = $startCellColumn + $width - 1; + } else { + $endCellColumn += $columns; + } + $startCellColumn = PHPExcel_Cell::stringFromColumnIndex($startCellColumn); + + if (($height != null) && (!is_object($height))) { + $endCellRow = $startCellRow + $height - 1; + } else { + $endCellRow += $rows; + } + + if (($endCellRow <= 0) || ($endCellColumn < 0)) { + return PHPExcel_Calculation_Functions::REF(); + } + $endCellColumn = PHPExcel_Cell::stringFromColumnIndex($endCellColumn); + + $cellAddress = $startCellColumn.$startCellRow; + if (($startCellColumn != $endCellColumn) || ($startCellRow != $endCellRow)) { + $cellAddress .= ':'.$endCellColumn.$endCellRow; + } + + if ($sheetName !== NULL) { + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); + } else { + $pSheet = $pCell->getWorksheet(); + } + + return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, False); + } // function OFFSET() + + + /** + * CHOOSE + * + * Uses lookup_value to return a value from the list of value arguments. + * Use CHOOSE to select one of up to 254 values based on the lookup_value. + * + * Excel Function: + * =CHOOSE(index_num, value1, [value2], ...) + * + * @param index_num Specifies which value argument is selected. + * Index_num must be a number between 1 and 254, or a formula or reference to a cell containing a number + * between 1 and 254. + * @param value1... Value1 is required, subsequent values are optional. + * Between 1 to 254 value arguments from which CHOOSE selects a value or an action to perform based on + * index_num. The arguments can be numbers, cell references, defined names, formulas, functions, or + * text. + * @return mixed The selected value + */ + public static function CHOOSE() { + $chooseArgs = func_get_args(); + $chosenEntry = PHPExcel_Calculation_Functions::flattenArray(array_shift($chooseArgs)); + $entryCount = count($chooseArgs) - 1; + + if(is_array($chosenEntry)) { + $chosenEntry = array_shift($chosenEntry); + } + if ((is_numeric($chosenEntry)) && (!is_bool($chosenEntry))) { + --$chosenEntry; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $chosenEntry = floor($chosenEntry); + if (($chosenEntry < 0) || ($chosenEntry > $entryCount)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_array($chooseArgs[$chosenEntry])) { + return PHPExcel_Calculation_Functions::flattenArray($chooseArgs[$chosenEntry]); + } else { + return $chooseArgs[$chosenEntry]; + } + } // function CHOOSE() + + + /** + * MATCH + * + * The MATCH function searches for a specified item in a range of cells + * + * Excel Function: + * =MATCH(lookup_value, lookup_array, [match_type]) + * + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param match_type The number -1, 0, or 1. -1 means above, 0 means exact match, 1 means below. If match_type is 1 or -1, the list has to be ordered. + * @return integer The relative position of the found item + */ + public static function MATCH($lookup_value, $lookup_array, $match_type=1) { + $lookup_array = PHPExcel_Calculation_Functions::flattenArray($lookup_array); + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + $match_type = (is_null($match_type)) ? 1 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($match_type); + // MATCH is not case sensitive + $lookup_value = strtolower($lookup_value); + + // lookup_value type has to be number, text, or logical values + if ((!is_numeric($lookup_value)) && (!is_string($lookup_value)) && (!is_bool($lookup_value))) { + return PHPExcel_Calculation_Functions::NA(); + } + + // match_type is 0, 1 or -1 + if (($match_type !== 0) && ($match_type !== -1) && ($match_type !== 1)) { + return PHPExcel_Calculation_Functions::NA(); + } + + // lookup_array should not be empty + $lookupArraySize = count($lookup_array); + if ($lookupArraySize <= 0) { + return PHPExcel_Calculation_Functions::NA(); + } + + // lookup_array should contain only number, text, or logical values, or empty (null) cells + foreach($lookup_array as $i => $lookupArrayValue) { + // check the type of the value + if ((!is_numeric($lookupArrayValue)) && (!is_string($lookupArrayValue)) && + (!is_bool($lookupArrayValue)) && (!is_null($lookupArrayValue))) { + return PHPExcel_Calculation_Functions::NA(); + } + // convert strings to lowercase for case-insensitive testing + if (is_string($lookupArrayValue)) { + $lookup_array[$i] = strtolower($lookupArrayValue); + } + if ((is_null($lookupArrayValue)) && (($match_type == 1) || ($match_type == -1))) { + $lookup_array = array_slice($lookup_array,0,$i-1); + } + } + + // if match_type is 1 or -1, the list has to be ordered + if ($match_type == 1) { + asort($lookup_array); + $keySet = array_keys($lookup_array); + } elseif($match_type == -1) { + arsort($lookup_array); + $keySet = array_keys($lookup_array); + } + + // ** + // find the match + // ** + // loop on the cells +// var_dump($lookup_array); +// echo '
'; + foreach($lookup_array as $i => $lookupArrayValue) { + if (($match_type == 0) && ($lookupArrayValue == $lookup_value)) { + // exact match + return ++$i; + } elseif (($match_type == -1) && ($lookupArrayValue <= $lookup_value)) { +// echo '$i = '.$i.' => '; +// var_dump($lookupArrayValue); +// echo '
'; +// echo 'Keyset = '; +// var_dump($keySet); +// echo '
'; + $i = array_search($i,$keySet); +// echo '$i='.$i.'
'; + // if match_type is -1 <=> find the smallest value that is greater than or equal to lookup_value + if ($i < 1){ + // 1st cell was allready smaller than the lookup_value + break; + } else { + // the previous cell was the match + return $keySet[$i-1]+1; + } + } elseif (($match_type == 1) && ($lookupArrayValue >= $lookup_value)) { +// echo '$i = '.$i.' => '; +// var_dump($lookupArrayValue); +// echo '
'; +// echo 'Keyset = '; +// var_dump($keySet); +// echo '
'; + $i = array_search($i,$keySet); +// echo '$i='.$i.'
'; + // if match_type is 1 <=> find the largest value that is less than or equal to lookup_value + if ($i < 1){ + // 1st cell was allready bigger than the lookup_value + break; + } else { + // the previous cell was the match + return $keySet[$i-1]+1; + } + } + } + + // unsuccessful in finding a match, return #N/A error value + return PHPExcel_Calculation_Functions::NA(); + } // function MATCH() + + + /** + * INDEX + * + * Uses an index to choose a value from a reference or array + * + * Excel Function: + * =INDEX(range_array, row_num, [column_num]) + * + * @param range_array A range of cells or an array constant + * @param row_num The row in array from which to return a value. If row_num is omitted, column_num is required. + * @param column_num The column in array from which to return a value. If column_num is omitted, row_num is required. + * @return mixed the value of a specified cell or array of cells + */ + public static function INDEX($arrayValues,$rowNum = 0,$columnNum = 0) { + + if (($rowNum < 0) || ($columnNum < 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (!is_array($arrayValues)) { + return PHPExcel_Calculation_Functions::REF(); + } + + $rowKeys = array_keys($arrayValues); + $columnKeys = @array_keys($arrayValues[$rowKeys[0]]); + + if ($columnNum > count($columnKeys)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($columnNum == 0) { + if ($rowNum == 0) { + return $arrayValues; + } + $rowNum = $rowKeys[--$rowNum]; + $returnArray = array(); + foreach($arrayValues as $arrayColumn) { + if (is_array($arrayColumn)) { + if (isset($arrayColumn[$rowNum])) { + $returnArray[] = $arrayColumn[$rowNum]; + } else { + return $arrayValues[$rowNum]; + } + } else { + return $arrayValues[$rowNum]; + } + } + return $returnArray; + } + $columnNum = $columnKeys[--$columnNum]; + if ($rowNum > count($rowKeys)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($rowNum == 0) { + return $arrayValues[$columnNum]; + } + $rowNum = $rowKeys[--$rowNum]; + + return $arrayValues[$rowNum][$columnNum]; + } // function INDEX() + + + /** + * TRANSPOSE + * + * @param array $matrixData A matrix of values + * @return array + * + * Unlike the Excel TRANSPOSE function, which will only work on a single row or column, this function will transpose a full matrix. + */ + public static function TRANSPOSE($matrixData) { + $returnMatrix = array(); + if (!is_array($matrixData)) { $matrixData = array(array($matrixData)); } + + $column = 0; + foreach($matrixData as $matrixRow) { + $row = 0; + foreach($matrixRow as $matrixCell) { + $returnMatrix[$row][$column] = $matrixCell; + ++$row; + } + ++$column; + } + return $returnMatrix; + } // function TRANSPOSE() + + + private static function _vlookupSort($a,$b) { + $f = array_keys($a); + $firstColumn = array_shift($f); + if (strtolower($a[$firstColumn]) == strtolower($b[$firstColumn])) { + return 0; + } + return (strtolower($a[$firstColumn]) < strtolower($b[$firstColumn])) ? -1 : 1; + } // function _vlookupSort() + + + /** + * VLOOKUP + * The VLOOKUP function searches for value in the left-most column of lookup_array and returns the value in the same row based on the index_number. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param index_number The column number in table_array from which the matching value must be returned. The first column is 1. + * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. + * @return mixed The value of the found cell + */ + public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) { + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + $index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); + $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); + + // index_number must be greater than or equal to 1 + if ($index_number < 1) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // index_number must be less than or equal to the number of columns in lookup_array + if ((!is_array($lookup_array)) || (empty($lookup_array))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $f = array_keys($lookup_array); + $firstRow = array_pop($f); + if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $columnKeys = array_keys($lookup_array[$firstRow]); + $returnColumn = $columnKeys[--$index_number]; + $firstColumn = array_shift($columnKeys); + } + } + + if (!$not_exact_match) { + uasort($lookup_array,array('self','_vlookupSort')); + } + + $rowNumber = $rowValue = False; + foreach($lookup_array as $rowKey => $rowData) { + if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) || + (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) { + break; + } + $rowNumber = $rowKey; + $rowValue = $rowData[$firstColumn]; + } + + if ($rowNumber !== false) { + if ((!$not_exact_match) && ($rowValue != $lookup_value)) { + // if an exact match is required, we have what we need to return an appropriate response + return PHPExcel_Calculation_Functions::NA(); + } else { + // otherwise return the appropriate value + return $lookup_array[$rowNumber][$returnColumn]; + } + } + + return PHPExcel_Calculation_Functions::NA(); + } // function VLOOKUP() /** @@ -784,8 +784,8 @@ public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not $rowNumber = $rowValue = False; foreach($lookup_array[$firstColumn] as $rowKey => $rowData) { - if ((is_numeric($lookup_value) && is_numeric($rowData) && ($rowData > $lookup_value)) || - (!is_numeric($lookup_value) && !is_numeric($rowData) && (strtolower($rowData) > strtolower($lookup_value)))) { + if ((is_numeric($lookup_value) && is_numeric($rowData) && ($rowData > $lookup_value)) || + (!is_numeric($lookup_value) && !is_numeric($rowData) && (strtolower($rowData) > strtolower($lookup_value)))) { break; } $rowNumber = $rowKey; @@ -806,71 +806,71 @@ public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not } // function HLOOKUP() - /** - * LOOKUP - * The LOOKUP function searches for value either from a one-row or one-column range or from an array. - * @param lookup_value The value that you want to match in lookup_array - * @param lookup_vector The range of cells being searched - * @param result_vector The column from which the matching value must be returned - * @return mixed The value of the found cell - */ - public static function LOOKUP($lookup_value, $lookup_vector, $result_vector=null) { - $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); - - if (!is_array($lookup_vector)) { - return PHPExcel_Calculation_Functions::NA(); - } - $lookupRows = count($lookup_vector); - $l = array_keys($lookup_vector); - $l = array_shift($l); - $lookupColumns = count($lookup_vector[$l]); - if ((($lookupRows == 1) && ($lookupColumns > 1)) || (($lookupRows == 2) && ($lookupColumns != 2))) { - $lookup_vector = self::TRANSPOSE($lookup_vector); - $lookupRows = count($lookup_vector); - $l = array_keys($lookup_vector); - $lookupColumns = count($lookup_vector[array_shift($l)]); - } - - if (is_null($result_vector)) { - $result_vector = $lookup_vector; - } - $resultRows = count($result_vector); - $l = array_keys($result_vector); - $l = array_shift($l); - $resultColumns = count($result_vector[$l]); - if ((($resultRows == 1) && ($resultColumns > 1)) || (($resultRows == 2) && ($resultColumns != 2))) { - $result_vector = self::TRANSPOSE($result_vector); - $resultRows = count($result_vector); - $r = array_keys($result_vector); - $resultColumns = count($result_vector[array_shift($r)]); - } - - if ($lookupRows == 2) { - $result_vector = array_pop($lookup_vector); - $lookup_vector = array_shift($lookup_vector); - } - if ($lookupColumns != 2) { - foreach($lookup_vector as &$value) { - if (is_array($value)) { - $k = array_keys($value); - $key1 = $key2 = array_shift($k); - $key2++; - $dataValue1 = $value[$key1]; - } else { - $key1 = 0; - $key2 = 1; - $dataValue1 = $value; - } - $dataValue2 = array_shift($result_vector); - if (is_array($dataValue2)) { - $dataValue2 = array_shift($dataValue2); - } - $value = array($key1 => $dataValue1, $key2 => $dataValue2); - } - unset($value); - } - - return self::VLOOKUP($lookup_value,$lookup_vector,2); - } // function LOOKUP() - -} // class PHPExcel_Calculation_LookupRef + /** + * LOOKUP + * The LOOKUP function searches for value either from a one-row or one-column range or from an array. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_vector The range of cells being searched + * @param result_vector The column from which the matching value must be returned + * @return mixed The value of the found cell + */ + public static function LOOKUP($lookup_value, $lookup_vector, $result_vector=null) { + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + + if (!is_array($lookup_vector)) { + return PHPExcel_Calculation_Functions::NA(); + } + $lookupRows = count($lookup_vector); + $l = array_keys($lookup_vector); + $l = array_shift($l); + $lookupColumns = count($lookup_vector[$l]); + if ((($lookupRows == 1) && ($lookupColumns > 1)) || (($lookupRows == 2) && ($lookupColumns != 2))) { + $lookup_vector = self::TRANSPOSE($lookup_vector); + $lookupRows = count($lookup_vector); + $l = array_keys($lookup_vector); + $lookupColumns = count($lookup_vector[array_shift($l)]); + } + + if (is_null($result_vector)) { + $result_vector = $lookup_vector; + } + $resultRows = count($result_vector); + $l = array_keys($result_vector); + $l = array_shift($l); + $resultColumns = count($result_vector[$l]); + if ((($resultRows == 1) && ($resultColumns > 1)) || (($resultRows == 2) && ($resultColumns != 2))) { + $result_vector = self::TRANSPOSE($result_vector); + $resultRows = count($result_vector); + $r = array_keys($result_vector); + $resultColumns = count($result_vector[array_shift($r)]); + } + + if ($lookupRows == 2) { + $result_vector = array_pop($lookup_vector); + $lookup_vector = array_shift($lookup_vector); + } + if ($lookupColumns != 2) { + foreach($lookup_vector as &$value) { + if (is_array($value)) { + $k = array_keys($value); + $key1 = $key2 = array_shift($k); + $key2++; + $dataValue1 = $value[$key1]; + } else { + $key1 = 0; + $key2 = 1; + $dataValue1 = $value; + } + $dataValue2 = array_shift($result_vector); + if (is_array($dataValue2)) { + $dataValue2 = array_shift($dataValue2); + } + $value = array($key1 => $dataValue1, $key2 => $dataValue2); + } + unset($value); + } + + return self::VLOOKUP($lookup_value,$lookup_vector,2); + } // function LOOKUP() + +} // class PHPExcel_Calculation_LookupRef diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index ab22046b3..3b3d64fe6 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -18,598 +18,598 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** * PHPExcel_Calculation_MathTrig * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_MathTrig { - // - // Private method to return an array of the factors of the input value - // - private static function _factors($value) { - $startVal = floor(sqrt($value)); - - $factorArray = array(); - for ($i = $startVal; $i > 1; --$i) { - if (($value % $i) == 0) { - $factorArray = array_merge($factorArray,self::_factors($value / $i)); - $factorArray = array_merge($factorArray,self::_factors($i)); - if ($i <= sqrt($value)) { - break; - } - } - } - if (!empty($factorArray)) { - rsort($factorArray); - return $factorArray; - } else { - return array((integer) $value); - } - } // function _factors() - - - private static function _romanCut($num, $n) { - return ($num - ($num % $n ) ) / $n; - } // function _romanCut() - - - /** - * ATAN2 - * - * This function calculates the arc tangent of the two variables x and y. It is similar to - * calculating the arc tangent of y ÷ x, except that the signs of both arguments are used - * to determine the quadrant of the result. - * The arctangent is the angle from the x-axis to a line containing the origin (0, 0) and a - * point with coordinates (xCoordinate, yCoordinate). The angle is given in radians between - * -pi and pi, excluding -pi. - * - * Note that the Excel ATAN2() function accepts its arguments in the reverse order to the standard - * PHP atan2() function, so we need to reverse them here before calling the PHP atan() function. - * - * Excel Function: - * ATAN2(xCoordinate,yCoordinate) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param float $xCoordinate The x-coordinate of the point. - * @param float $yCoordinate The y-coordinate of the point. - * @return float The inverse tangent of the specified x- and y-coordinates. - */ - public static function ATAN2($xCoordinate = NULL, $yCoordinate = NULL) { - $xCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($xCoordinate); - $yCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($yCoordinate); - - $xCoordinate = ($xCoordinate !== NULL) ? $xCoordinate : 0.0; - $yCoordinate = ($yCoordinate !== NULL) ? $yCoordinate : 0.0; - - if (((is_numeric($xCoordinate)) || (is_bool($xCoordinate))) && - ((is_numeric($yCoordinate))) || (is_bool($yCoordinate))) { - $xCoordinate = (float) $xCoordinate; - $yCoordinate = (float) $yCoordinate; - - if (($xCoordinate == 0) && ($yCoordinate == 0)) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - return atan2($yCoordinate, $xCoordinate); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function ATAN2() - - - /** - * CEILING - * - * Returns number rounded up, away from zero, to the nearest multiple of significance. - * For example, if you want to avoid using pennies in your prices and your product is - * priced at $4.42, use the formula =CEILING(4.42,0.05) to round prices up to the - * nearest nickel. - * - * Excel Function: - * CEILING(number[,significance]) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param float $number The number you want to round. - * @param float $significance The multiple to which you want to round. - * @return float Rounded Number - */ - public static function CEILING($number, $significance = NULL) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); - - if ((is_null($significance)) && - (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { - $significance = $number/abs($number); - } + // + // Private method to return an array of the factors of the input value + // + private static function _factors($value) { + $startVal = floor(sqrt($value)); + + $factorArray = array(); + for ($i = $startVal; $i > 1; --$i) { + if (($value % $i) == 0) { + $factorArray = array_merge($factorArray,self::_factors($value / $i)); + $factorArray = array_merge($factorArray,self::_factors($i)); + if ($i <= sqrt($value)) { + break; + } + } + } + if (!empty($factorArray)) { + rsort($factorArray); + return $factorArray; + } else { + return array((integer) $value); + } + } // function _factors() + + + private static function _romanCut($num, $n) { + return ($num - ($num % $n ) ) / $n; + } // function _romanCut() + + + /** + * ATAN2 + * + * This function calculates the arc tangent of the two variables x and y. It is similar to + * calculating the arc tangent of y ÷ x, except that the signs of both arguments are used + * to determine the quadrant of the result. + * The arctangent is the angle from the x-axis to a line containing the origin (0, 0) and a + * point with coordinates (xCoordinate, yCoordinate). The angle is given in radians between + * -pi and pi, excluding -pi. + * + * Note that the Excel ATAN2() function accepts its arguments in the reverse order to the standard + * PHP atan2() function, so we need to reverse them here before calling the PHP atan() function. + * + * Excel Function: + * ATAN2(xCoordinate,yCoordinate) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $xCoordinate The x-coordinate of the point. + * @param float $yCoordinate The y-coordinate of the point. + * @return float The inverse tangent of the specified x- and y-coordinates. + */ + public static function ATAN2($xCoordinate = NULL, $yCoordinate = NULL) { + $xCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($xCoordinate); + $yCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($yCoordinate); + + $xCoordinate = ($xCoordinate !== NULL) ? $xCoordinate : 0.0; + $yCoordinate = ($yCoordinate !== NULL) ? $yCoordinate : 0.0; + + if (((is_numeric($xCoordinate)) || (is_bool($xCoordinate))) && + ((is_numeric($yCoordinate))) || (is_bool($yCoordinate))) { + $xCoordinate = (float) $xCoordinate; + $yCoordinate = (float) $yCoordinate; + + if (($xCoordinate == 0) && ($yCoordinate == 0)) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + return atan2($yCoordinate, $xCoordinate); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ATAN2() + + + /** + * CEILING + * + * Returns number rounded up, away from zero, to the nearest multiple of significance. + * For example, if you want to avoid using pennies in your prices and your product is + * priced at $4.42, use the formula =CEILING(4.42,0.05) to round prices up to the + * nearest nickel. + * + * Excel Function: + * CEILING(number[,significance]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number The number you want to round. + * @param float $significance The multiple to which you want to round. + * @return float Rounded Number + */ + public static function CEILING($number, $significance = NULL) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); + + if ((is_null($significance)) && + (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { + $significance = $number/abs($number); + } if ((is_numeric($number)) && (is_numeric($significance))) { if (($number == 0.0 ) || ($significance == 0.0)) { - return 0.0; - } elseif (self::SIGN($number) == self::SIGN($significance)) { - return ceil($number / $significance) * $significance; - } else { - return PHPExcel_Calculation_Functions::NaN(); - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function CEILING() - - - /** - * COMBIN - * - * Returns the number of combinations for a given number of items. Use COMBIN to - * determine the total possible number of groups for a given number of items. - * - * Excel Function: - * COMBIN(numObjs,numInSet) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param int $numObjs Number of different objects - * @param int $numInSet Number of objects in each combination - * @return int Number of combinations - */ - public static function COMBIN($numObjs, $numInSet) { - $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); - $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); - - if ((is_numeric($numObjs)) && (is_numeric($numInSet))) { - if ($numObjs < $numInSet) { - return PHPExcel_Calculation_Functions::NaN(); - } elseif ($numInSet < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - return round(self::FACT($numObjs) / self::FACT($numObjs - $numInSet)) / self::FACT($numInSet); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function COMBIN() - - - /** - * EVEN - * - * Returns number rounded up to the nearest even integer. - * You can use this function for processing items that come in twos. For example, - * a packing crate accepts rows of one or two items. The crate is full when - * the number of items, rounded up to the nearest two, matches the crate's - * capacity. - * - * Excel Function: - * EVEN(number) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param float $number Number to round - * @return int Rounded Number - */ - public static function EVEN($number) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - - if (is_null($number)) { - return 0; - } elseif (is_bool($number)) { - $number = (int) $number; - } - - if (is_numeric($number)) { - $significance = 2 * self::SIGN($number); - return (int) self::CEILING($number,$significance); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function EVEN() - - - /** - * FACT - * - * Returns the factorial of a number. - * The factorial of a number is equal to 1*2*3*...* number. - * - * Excel Function: - * FACT(factVal) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param float $factVal Factorial Value - * @return int Factorial - */ - public static function FACT($factVal) { - $factVal = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); - - if (is_numeric($factVal)) { - if ($factVal < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - $factLoop = floor($factVal); - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - if ($factVal > $factLoop) { - return PHPExcel_Calculation_Functions::NaN(); - } - } - - $factorial = 1; - while ($factLoop > 1) { - $factorial *= $factLoop--; - } - return $factorial ; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function FACT() - - - /** - * FACTDOUBLE - * - * Returns the double factorial of a number. - * - * Excel Function: - * FACTDOUBLE(factVal) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param float $factVal Factorial Value - * @return int Double Factorial - */ - public static function FACTDOUBLE($factVal) { - $factLoop = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); - - if (is_numeric($factLoop)) { - $factLoop = floor($factLoop); - if ($factVal < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - $factorial = 1; - while ($factLoop > 1) { - $factorial *= $factLoop--; - --$factLoop; - } - return $factorial ; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function FACTDOUBLE() - - - /** - * FLOOR - * - * Rounds number down, toward zero, to the nearest multiple of significance. - * - * Excel Function: - * FLOOR(number[,significance]) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param float $number Number to round - * @param float $significance Significance - * @return float Rounded Number - */ - public static function FLOOR($number, $significance = NULL) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); - - if ((is_null($significance)) && (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { - $significance = $number/abs($number); - } - - if ((is_numeric($number)) && (is_numeric($significance))) { + return 0.0; + } elseif (self::SIGN($number) == self::SIGN($significance)) { + return ceil($number / $significance) * $significance; + } else { + return PHPExcel_Calculation_Functions::NaN(); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CEILING() + + + /** + * COMBIN + * + * Returns the number of combinations for a given number of items. Use COMBIN to + * determine the total possible number of groups for a given number of items. + * + * Excel Function: + * COMBIN(numObjs,numInSet) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param int $numObjs Number of different objects + * @param int $numInSet Number of objects in each combination + * @return int Number of combinations + */ + public static function COMBIN($numObjs, $numInSet) { + $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); + $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); + + if ((is_numeric($numObjs)) && (is_numeric($numInSet))) { + if ($numObjs < $numInSet) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif ($numInSet < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return round(self::FACT($numObjs) / self::FACT($numObjs - $numInSet)) / self::FACT($numInSet); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function COMBIN() + + + /** + * EVEN + * + * Returns number rounded up to the nearest even integer. + * You can use this function for processing items that come in twos. For example, + * a packing crate accepts rows of one or two items. The crate is full when + * the number of items, rounded up to the nearest two, matches the crate's + * capacity. + * + * Excel Function: + * EVEN(number) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number Number to round + * @return int Rounded Number + */ + public static function EVEN($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_null($number)) { + return 0; + } elseif (is_bool($number)) { + $number = (int) $number; + } + + if (is_numeric($number)) { + $significance = 2 * self::SIGN($number); + return (int) self::CEILING($number,$significance); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function EVEN() + + + /** + * FACT + * + * Returns the factorial of a number. + * The factorial of a number is equal to 1*2*3*...* number. + * + * Excel Function: + * FACT(factVal) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $factVal Factorial Value + * @return int Factorial + */ + public static function FACT($factVal) { + $factVal = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); + + if (is_numeric($factVal)) { + if ($factVal < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $factLoop = floor($factVal); + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + if ($factVal > $factLoop) { + return PHPExcel_Calculation_Functions::NaN(); + } + } + + $factorial = 1; + while ($factLoop > 1) { + $factorial *= $factLoop--; + } + return $factorial ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FACT() + + + /** + * FACTDOUBLE + * + * Returns the double factorial of a number. + * + * Excel Function: + * FACTDOUBLE(factVal) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $factVal Factorial Value + * @return int Double Factorial + */ + public static function FACTDOUBLE($factVal) { + $factLoop = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); + + if (is_numeric($factLoop)) { + $factLoop = floor($factLoop); + if ($factVal < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $factorial = 1; + while ($factLoop > 1) { + $factorial *= $factLoop--; + --$factLoop; + } + return $factorial ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FACTDOUBLE() + + + /** + * FLOOR + * + * Rounds number down, toward zero, to the nearest multiple of significance. + * + * Excel Function: + * FLOOR(number[,significance]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number Number to round + * @param float $significance Significance + * @return float Rounded Number + */ + public static function FLOOR($number, $significance = NULL) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); + + if ((is_null($significance)) && (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { + $significance = $number/abs($number); + } + + if ((is_numeric($number)) && (is_numeric($significance))) { if ($significance == 0.0) { return PHPExcel_Calculation_Functions::DIV0(); } elseif ($number == 0.0) { - return 0.0; - } elseif (self::SIGN($number) == self::SIGN($significance)) { - return floor($number / $significance) * $significance; - } else { - return PHPExcel_Calculation_Functions::NaN(); - } - } else - - return PHPExcel_Calculation_Functions::VALUE(); - } // function FLOOR() - - - /** - * GCD - * - * Returns the greatest common divisor of a series of numbers. - * The greatest common divisor is the largest integer that divides both - * number1 and number2 without a remainder. - * - * Excel Function: - * GCD(number1[,number2[, ...]]) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @return integer Greatest Common Divisor - */ - public static function GCD() { - $returnValue = 1; - $allValuesFactors = array(); - // Loop through arguments - foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { - if (!is_numeric($value)) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif ($value == 0) { - continue; - } elseif($value < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - $myFactors = self::_factors($value); - $myCountedFactors = array_count_values($myFactors); - $allValuesFactors[] = $myCountedFactors; - } - $allValuesCount = count($allValuesFactors); - if ($allValuesCount == 0) { - return 0; - } - - $mergedArray = $allValuesFactors[0]; - for ($i=1;$i < $allValuesCount; ++$i) { - $mergedArray = array_intersect_key($mergedArray,$allValuesFactors[$i]); - } - $mergedArrayValues = count($mergedArray); - if ($mergedArrayValues == 0) { - return $returnValue; - } elseif ($mergedArrayValues > 1) { - foreach($mergedArray as $mergedKey => $mergedValue) { - foreach($allValuesFactors as $highestPowerTest) { - foreach($highestPowerTest as $testKey => $testValue) { - if (($testKey == $mergedKey) && ($testValue < $mergedValue)) { - $mergedArray[$mergedKey] = $testValue; - $mergedValue = $testValue; - } - } - } - } - - $returnValue = 1; - foreach($mergedArray as $key => $value) { - $returnValue *= pow($key,$value); - } - return $returnValue; - } else { - $keys = array_keys($mergedArray); - $key = $keys[0]; - $value = $mergedArray[$key]; - foreach($allValuesFactors as $testValue) { - foreach($testValue as $mergedKey => $mergedValue) { - if (($mergedKey == $key) && ($mergedValue < $value)) { - $value = $mergedValue; - } - } - } - return pow($key,$value); - } - } // function GCD() - - - /** - * INT - * - * Casts a floating point value to an integer - * - * Excel Function: - * INT(number) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param float $number Number to cast to an integer - * @return integer Integer value - */ - public static function INT($number) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - - if (is_null($number)) { - return 0; - } elseif (is_bool($number)) { - return (int) $number; - } - if (is_numeric($number)) { - return (int) floor($number); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function INT() - - - /** - * LCM - * - * Returns the lowest common multiplier of a series of numbers - * The least common multiple is the smallest positive integer that is a multiple - * of all integer arguments number1, number2, and so on. Use LCM to add fractions - * with different denominators. - * - * Excel Function: - * LCM(number1[,number2[, ...]]) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @return int Lowest Common Multiplier - */ - public static function LCM() { - $returnValue = 1; - $allPoweredFactors = array(); - // Loop through arguments - foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { - if (!is_numeric($value)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if ($value == 0) { - return 0; - } elseif ($value < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - $myFactors = self::_factors(floor($value)); - $myCountedFactors = array_count_values($myFactors); - $myPoweredFactors = array(); - foreach($myCountedFactors as $myCountedFactor => $myCountedPower) { - $myPoweredFactors[$myCountedFactor] = pow($myCountedFactor,$myCountedPower); - } - foreach($myPoweredFactors as $myPoweredValue => $myPoweredFactor) { - if (array_key_exists($myPoweredValue,$allPoweredFactors)) { - if ($allPoweredFactors[$myPoweredValue] < $myPoweredFactor) { - $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; - } - } else { - $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; - } - } - } - foreach($allPoweredFactors as $allPoweredFactor) { - $returnValue *= (integer) $allPoweredFactor; - } - return $returnValue; - } // function LCM() - - - /** - * LOG_BASE - * - * Returns the logarithm of a number to a specified base. The default base is 10. - * - * Excel Function: - * LOG(number[,base]) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param float $number The positive real number for which you want the logarithm - * @param float $base The base of the logarithm. If base is omitted, it is assumed to be 10. - * @return float - */ - public static function LOG_BASE($number = NULL, $base = 10) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - $base = (is_null($base)) ? 10 : (float) PHPExcel_Calculation_Functions::flattenSingleValue($base); - - if ((!is_numeric($base)) || (!is_numeric($number))) - return PHPExcel_Calculation_Functions::VALUE(); - if (($base <= 0) || ($number <= 0)) - return PHPExcel_Calculation_Functions::NaN(); - return log($number, $base); - } // function LOG_BASE() - - - /** - * MDETERM - * - * Returns the matrix determinant of an array. - * - * Excel Function: - * MDETERM(array) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param array $matrixValues A matrix of values - * @return float - */ - public static function MDETERM($matrixValues) { - $matrixData = array(); - if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); } - - $row = $maxColumn = 0; - foreach($matrixValues as $matrixRow) { - if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } - $column = 0; - foreach($matrixRow as $matrixCell) { - if ((is_string($matrixCell)) || ($matrixCell === null)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $matrixData[$column][$row] = $matrixCell; - ++$column; - } - if ($column > $maxColumn) { $maxColumn = $column; } - ++$row; - } - if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); } - - try { - $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); - return $matrix->det(); - } catch (PHPExcel_Exception $ex) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } // function MDETERM() - - - /** - * MINVERSE - * - * Returns the inverse matrix for the matrix stored in an array. - * - * Excel Function: - * MINVERSE(array) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param array $matrixValues A matrix of values - * @return array - */ - public static function MINVERSE($matrixValues) { - $matrixData = array(); - if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); } - - $row = $maxColumn = 0; - foreach($matrixValues as $matrixRow) { - if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } - $column = 0; - foreach($matrixRow as $matrixCell) { - if ((is_string($matrixCell)) || ($matrixCell === null)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $matrixData[$column][$row] = $matrixCell; - ++$column; - } - if ($column > $maxColumn) { $maxColumn = $column; } - ++$row; - } - if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); } - - try { - $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); - return $matrix->inverse()->getArray(); - } catch (PHPExcel_Exception $ex) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } // function MINVERSE() - - - /** - * MMULT - * - * @param array $matrixData1 A matrix of values - * @param array $matrixData2 A matrix of values - * @return array - */ - public static function MMULT($matrixData1,$matrixData2) { - $matrixAData = $matrixBData = array(); - if (!is_array($matrixData1)) { $matrixData1 = array(array($matrixData1)); } - if (!is_array($matrixData2)) { $matrixData2 = array(array($matrixData2)); } - - try { + return 0.0; + } elseif (self::SIGN($number) == self::SIGN($significance)) { + return floor($number / $significance) * $significance; + } else { + return PHPExcel_Calculation_Functions::NaN(); + } + } else + + return PHPExcel_Calculation_Functions::VALUE(); + } // function FLOOR() + + + /** + * GCD + * + * Returns the greatest common divisor of a series of numbers. + * The greatest common divisor is the largest integer that divides both + * number1 and number2 without a remainder. + * + * Excel Function: + * GCD(number1[,number2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return integer Greatest Common Divisor + */ + public static function GCD() { + $returnValue = 1; + $allValuesFactors = array(); + // Loop through arguments + foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { + if (!is_numeric($value)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($value == 0) { + continue; + } elseif($value < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $myFactors = self::_factors($value); + $myCountedFactors = array_count_values($myFactors); + $allValuesFactors[] = $myCountedFactors; + } + $allValuesCount = count($allValuesFactors); + if ($allValuesCount == 0) { + return 0; + } + + $mergedArray = $allValuesFactors[0]; + for ($i=1;$i < $allValuesCount; ++$i) { + $mergedArray = array_intersect_key($mergedArray,$allValuesFactors[$i]); + } + $mergedArrayValues = count($mergedArray); + if ($mergedArrayValues == 0) { + return $returnValue; + } elseif ($mergedArrayValues > 1) { + foreach($mergedArray as $mergedKey => $mergedValue) { + foreach($allValuesFactors as $highestPowerTest) { + foreach($highestPowerTest as $testKey => $testValue) { + if (($testKey == $mergedKey) && ($testValue < $mergedValue)) { + $mergedArray[$mergedKey] = $testValue; + $mergedValue = $testValue; + } + } + } + } + + $returnValue = 1; + foreach($mergedArray as $key => $value) { + $returnValue *= pow($key,$value); + } + return $returnValue; + } else { + $keys = array_keys($mergedArray); + $key = $keys[0]; + $value = $mergedArray[$key]; + foreach($allValuesFactors as $testValue) { + foreach($testValue as $mergedKey => $mergedValue) { + if (($mergedKey == $key) && ($mergedValue < $value)) { + $value = $mergedValue; + } + } + } + return pow($key,$value); + } + } // function GCD() + + + /** + * INT + * + * Casts a floating point value to an integer + * + * Excel Function: + * INT(number) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number Number to cast to an integer + * @return integer Integer value + */ + public static function INT($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_null($number)) { + return 0; + } elseif (is_bool($number)) { + return (int) $number; + } + if (is_numeric($number)) { + return (int) floor($number); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function INT() + + + /** + * LCM + * + * Returns the lowest common multiplier of a series of numbers + * The least common multiple is the smallest positive integer that is a multiple + * of all integer arguments number1, number2, and so on. Use LCM to add fractions + * with different denominators. + * + * Excel Function: + * LCM(number1[,number2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return int Lowest Common Multiplier + */ + public static function LCM() { + $returnValue = 1; + $allPoweredFactors = array(); + // Loop through arguments + foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { + if (!is_numeric($value)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if ($value == 0) { + return 0; + } elseif ($value < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $myFactors = self::_factors(floor($value)); + $myCountedFactors = array_count_values($myFactors); + $myPoweredFactors = array(); + foreach($myCountedFactors as $myCountedFactor => $myCountedPower) { + $myPoweredFactors[$myCountedFactor] = pow($myCountedFactor,$myCountedPower); + } + foreach($myPoweredFactors as $myPoweredValue => $myPoweredFactor) { + if (array_key_exists($myPoweredValue,$allPoweredFactors)) { + if ($allPoweredFactors[$myPoweredValue] < $myPoweredFactor) { + $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; + } + } else { + $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; + } + } + } + foreach($allPoweredFactors as $allPoweredFactor) { + $returnValue *= (integer) $allPoweredFactor; + } + return $returnValue; + } // function LCM() + + + /** + * LOG_BASE + * + * Returns the logarithm of a number to a specified base. The default base is 10. + * + * Excel Function: + * LOG(number[,base]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number The positive real number for which you want the logarithm + * @param float $base The base of the logarithm. If base is omitted, it is assumed to be 10. + * @return float + */ + public static function LOG_BASE($number = NULL, $base = 10) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $base = (is_null($base)) ? 10 : (float) PHPExcel_Calculation_Functions::flattenSingleValue($base); + + if ((!is_numeric($base)) || (!is_numeric($number))) + return PHPExcel_Calculation_Functions::VALUE(); + if (($base <= 0) || ($number <= 0)) + return PHPExcel_Calculation_Functions::NaN(); + return log($number, $base); + } // function LOG_BASE() + + + /** + * MDETERM + * + * Returns the matrix determinant of an array. + * + * Excel Function: + * MDETERM(array) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param array $matrixValues A matrix of values + * @return float + */ + public static function MDETERM($matrixValues) { + $matrixData = array(); + if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); } + + $row = $maxColumn = 0; + foreach($matrixValues as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $column = 0; + foreach($matrixRow as $matrixCell) { + if ((is_string($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixData[$column][$row] = $matrixCell; + ++$column; + } + if ($column > $maxColumn) { $maxColumn = $column; } + ++$row; + } + if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); } + + try { + $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); + return $matrix->det(); + } catch (PHPExcel_Exception $ex) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } // function MDETERM() + + + /** + * MINVERSE + * + * Returns the inverse matrix for the matrix stored in an array. + * + * Excel Function: + * MINVERSE(array) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param array $matrixValues A matrix of values + * @return array + */ + public static function MINVERSE($matrixValues) { + $matrixData = array(); + if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); } + + $row = $maxColumn = 0; + foreach($matrixValues as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $column = 0; + foreach($matrixRow as $matrixCell) { + if ((is_string($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixData[$column][$row] = $matrixCell; + ++$column; + } + if ($column > $maxColumn) { $maxColumn = $column; } + ++$row; + } + if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); } + + try { + $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); + return $matrix->inverse()->getArray(); + } catch (PHPExcel_Exception $ex) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } // function MINVERSE() + + + /** + * MMULT + * + * @param array $matrixData1 A matrix of values + * @param array $matrixData2 A matrix of values + * @return array + */ + public static function MMULT($matrixData1,$matrixData2) { + $matrixAData = $matrixBData = array(); + if (!is_array($matrixData1)) { $matrixData1 = array(array($matrixData1)); } + if (!is_array($matrixData2)) { $matrixData2 = array(array($matrixData2)); } + + try { $rowA = 0; foreach($matrixData1 as $matrixRow) { if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } @@ -623,754 +623,754 @@ public static function MMULT($matrixData1,$matrixData2) { } ++$rowA; } - $matrixA = new PHPExcel_Shared_JAMA_Matrix($matrixAData); - $rowB = 0; - foreach($matrixData2 as $matrixRow) { - if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } - $columnB = 0; - foreach($matrixRow as $matrixCell) { - if ((!is_numeric($matrixCell)) || ($matrixCell === null)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $matrixBData[$rowB][$columnB] = $matrixCell; - ++$columnB; - } - ++$rowB; - } - $matrixB = new PHPExcel_Shared_JAMA_Matrix($matrixBData); - - if ($columnA != $rowB) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - return $matrixA->times($matrixB)->getArray(); - } catch (PHPExcel_Exception $ex) { + $matrixA = new PHPExcel_Shared_JAMA_Matrix($matrixAData); + $rowB = 0; + foreach($matrixData2 as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $columnB = 0; + foreach($matrixRow as $matrixCell) { + if ((!is_numeric($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixBData[$rowB][$columnB] = $matrixCell; + ++$columnB; + } + ++$rowB; + } + $matrixB = new PHPExcel_Shared_JAMA_Matrix($matrixBData); + + if ($columnA != $rowB) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + return $matrixA->times($matrixB)->getArray(); + } catch (PHPExcel_Exception $ex) { var_dump($ex->getMessage()); - return PHPExcel_Calculation_Functions::VALUE(); - } - } // function MMULT() - - - /** - * MOD - * - * @param int $a Dividend - * @param int $b Divisor - * @return int Remainder - */ - public static function MOD($a = 1, $b = 1) { - $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); - $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); - - if ($b == 0.0) { - return PHPExcel_Calculation_Functions::DIV0(); - } elseif (($a < 0.0) && ($b > 0.0)) { - return $b - fmod(abs($a),$b); - } elseif (($a > 0.0) && ($b < 0.0)) { - return $b + fmod($a,abs($b)); - } - - return fmod($a,$b); - } // function MOD() - - - /** - * MROUND - * - * Rounds a number to the nearest multiple of a specified value - * - * @param float $number Number to round - * @param int $multiple Multiple to which you want to round $number - * @return float Rounded Number - */ - public static function MROUND($number,$multiple) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - $multiple = PHPExcel_Calculation_Functions::flattenSingleValue($multiple); - - if ((is_numeric($number)) && (is_numeric($multiple))) { - if ($multiple == 0) { - return 0; - } - if ((self::SIGN($number)) == (self::SIGN($multiple))) { - $multiplier = 1 / $multiple; - return round($number * $multiplier) / $multiplier; - } - return PHPExcel_Calculation_Functions::NaN(); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function MROUND() - - - /** - * MULTINOMIAL - * - * Returns the ratio of the factorial of a sum of values to the product of factorials. - * - * @param array of mixed Data Series - * @return float - */ - public static function MULTINOMIAL() { - $summer = 0; - $divisor = 1; - // Loop through arguments - foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { - // Is it a numeric value? - if (is_numeric($arg)) { - if ($arg < 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - $summer += floor($arg); - $divisor *= self::FACT($arg); - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - - // Return - if ($summer > 0) { - $summer = self::FACT($summer); - return $summer / $divisor; - } - return 0; - } // function MULTINOMIAL() - - - /** - * ODD - * - * Returns number rounded up to the nearest odd integer. - * - * @param float $number Number to round - * @return int Rounded Number - */ - public static function ODD($number) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - - if (is_null($number)) { - return 1; - } elseif (is_bool($number)) { - $number = (int) $number; - } - - if (is_numeric($number)) { - $significance = self::SIGN($number); - if ($significance == 0) { - return 1; - } - - $result = self::CEILING($number,$significance); - if ($result == self::EVEN($result)) { - $result += $significance; - } - - return (int) $result; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function ODD() - - - /** - * POWER - * - * Computes x raised to the power y. - * - * @param float $x - * @param float $y - * @return float - */ - public static function POWER($x = 0, $y = 2) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); - $y = PHPExcel_Calculation_Functions::flattenSingleValue($y); - - // Validate parameters - if ($x == 0.0 && $y == 0.0) { - return PHPExcel_Calculation_Functions::NaN(); - } elseif ($x == 0.0 && $y < 0.0) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - // Return - $result = pow($x, $y); - return (!is_nan($result) && !is_infinite($result)) ? $result : PHPExcel_Calculation_Functions::NaN(); - } // function POWER() - - - /** - * PRODUCT - * - * PRODUCT returns the product of all the values and cells referenced in the argument list. - * - * Excel Function: - * PRODUCT(value1[,value2[, ...]]) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function PRODUCT() { - // Return value - $returnValue = null; - - // Loop through arguments - foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - if (is_null($returnValue)) { - $returnValue = $arg; - } else { - $returnValue *= $arg; - } - } - } - - // Return - if (is_null($returnValue)) { - return 0; - } - return $returnValue; - } // function PRODUCT() - - - /** - * QUOTIENT - * - * QUOTIENT function returns the integer portion of a division. Numerator is the divided number - * and denominator is the divisor. - * - * Excel Function: - * QUOTIENT(value1[,value2[, ...]]) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function QUOTIENT() { - // Return value - $returnValue = null; - - // Loop through arguments - foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - if (is_null($returnValue)) { - $returnValue = ($arg == 0) ? 0 : $arg; - } else { - if (($returnValue == 0) || ($arg == 0)) { - $returnValue = 0; - } else { - $returnValue /= $arg; - } - } - } - } - - // Return - return intval($returnValue); - } // function QUOTIENT() - - - /** - * RAND - * - * @param int $min Minimal value - * @param int $max Maximal value - * @return int Random number - */ - public static function RAND($min = 0, $max = 0) { - $min = PHPExcel_Calculation_Functions::flattenSingleValue($min); - $max = PHPExcel_Calculation_Functions::flattenSingleValue($max); - - if ($min == 0 && $max == 0) { - return (mt_rand(0,10000000)) / 10000000; - } else { - return mt_rand($min, $max); - } - } // function RAND() - - - public static function ROMAN($aValue, $style=0) { - $aValue = PHPExcel_Calculation_Functions::flattenSingleValue($aValue); - $style = (is_null($style)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($style); - if ((!is_numeric($aValue)) || ($aValue < 0) || ($aValue >= 4000)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $aValue = (integer) $aValue; - if ($aValue == 0) { - return ''; - } - - $mill = Array('', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM'); - $cent = Array('', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'); - $tens = Array('', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'); - $ones = Array('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'); - - $roman = ''; - while ($aValue > 5999) { - $roman .= 'M'; - $aValue -= 1000; - } - $m = self::_romanCut($aValue, 1000); $aValue %= 1000; - $c = self::_romanCut($aValue, 100); $aValue %= 100; - $t = self::_romanCut($aValue, 10); $aValue %= 10; - - return $roman.$mill[$m].$cent[$c].$tens[$t].$ones[$aValue]; - } // function ROMAN() - - - /** - * ROUNDUP - * - * Rounds a number up to a specified number of decimal places - * - * @param float $number Number to round - * @param int $digits Number of digits to which you want to round $number - * @return float Rounded Number - */ - public static function ROUNDUP($number,$digits) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); - - if ((is_numeric($number)) && (is_numeric($digits))) { - $significance = pow(10,(int) $digits); - if ($number < 0.0) { - return floor($number * $significance) / $significance; - } else { - return ceil($number * $significance) / $significance; - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function ROUNDUP() - - - /** - * ROUNDDOWN - * - * Rounds a number down to a specified number of decimal places - * - * @param float $number Number to round - * @param int $digits Number of digits to which you want to round $number - * @return float Rounded Number - */ - public static function ROUNDDOWN($number,$digits) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); - - if ((is_numeric($number)) && (is_numeric($digits))) { - $significance = pow(10,(int) $digits); - if ($number < 0.0) { - return ceil($number * $significance) / $significance; - } else { - return floor($number * $significance) / $significance; - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function ROUNDDOWN() - - - /** - * SERIESSUM - * - * Returns the sum of a power series - * - * @param float $x Input value to the power series - * @param float $n Initial power to which you want to raise $x - * @param float $m Step by which to increase $n for each term in the series - * @param array of mixed Data Series - * @return float - */ - public static function SERIESSUM() { - // Return value - $returnValue = 0; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - - $x = array_shift($aArgs); - $n = array_shift($aArgs); - $m = array_shift($aArgs); - - if ((is_numeric($x)) && (is_numeric($n)) && (is_numeric($m))) { - // Calculate - $i = 0; - foreach($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $returnValue += $arg * pow($x,$n + ($m * $i++)); - } else { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - // Return - return $returnValue; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function SERIESSUM() - - - /** - * SIGN - * - * Determines the sign of a number. Returns 1 if the number is positive, zero (0) - * if the number is 0, and -1 if the number is negative. - * - * @param float $number Number to round - * @return int sign value - */ - public static function SIGN($number) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - - if (is_bool($number)) - return (int) $number; - if (is_numeric($number)) { - if ($number == 0.0) { - return 0; - } - return $number / abs($number); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function SIGN() - - - /** - * SQRTPI - * - * Returns the square root of (number * pi). - * - * @param float $number Number - * @return float Square Root of Number * Pi - */ - public static function SQRTPI($number) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - - if (is_numeric($number)) { - if ($number < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - return sqrt($number * M_PI) ; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function SQRTPI() - - - /** - * SUBTOTAL - * - * Returns a subtotal in a list or database. - * - * @param int the number 1 to 11 that specifies which function to - * use in calculating subtotals within a list. - * @param array of mixed Data Series - * @return float - */ - public static function SUBTOTAL() { - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - - // Calculate - $subtotal = array_shift($aArgs); - - if ((is_numeric($subtotal)) && (!is_string($subtotal))) { - switch($subtotal) { - case 1 : - return PHPExcel_Calculation_Statistical::AVERAGE($aArgs); - break; - case 2 : - return PHPExcel_Calculation_Statistical::COUNT($aArgs); - break; - case 3 : - return PHPExcel_Calculation_Statistical::COUNTA($aArgs); - break; - case 4 : - return PHPExcel_Calculation_Statistical::MAX($aArgs); - break; - case 5 : - return PHPExcel_Calculation_Statistical::MIN($aArgs); - break; - case 6 : - return self::PRODUCT($aArgs); - break; - case 7 : - return PHPExcel_Calculation_Statistical::STDEV($aArgs); - break; - case 8 : - return PHPExcel_Calculation_Statistical::STDEVP($aArgs); - break; - case 9 : - return self::SUM($aArgs); - break; - case 10 : - return PHPExcel_Calculation_Statistical::VARFunc($aArgs); - break; - case 11 : - return PHPExcel_Calculation_Statistical::VARP($aArgs); - break; - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function SUBTOTAL() - - - /** - * SUM - * - * SUM computes the sum of all the values and cells referenced in the argument list. - * - * Excel Function: - * SUM(value1[,value2[, ...]]) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function SUM() { - // Return value - $returnValue = 0; - - // Loop through the arguments - foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $returnValue += $arg; - } - } - - // Return - return $returnValue; - } // function SUM() - - - /** - * SUMIF - * - * Counts the number of cells that contain numbers within the list of arguments - * - * Excel Function: - * SUMIF(value1[,value2[, ...]],condition) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @param string $condition The criteria that defines which cells will be summed. - * @return float - */ - public static function SUMIF($aArgs,$condition,$sumArgs = array()) { - // Return value - $returnValue = 0; - - $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); - $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); - if (empty($sumArgs)) { - $sumArgs = $aArgs; - } - $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); - // Loop through arguments - foreach ($aArgs as $key => $arg) { - if (!is_numeric($arg)) { - $arg = str_replace('"', '""', $arg); - $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); - } - - $testCondition = '='.$arg.$condition; - if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { - // Is it a value within our criteria - $returnValue += $sumArgs[$key]; - } - } - - // Return - return $returnValue; - } // function SUMIF() - - - /** - * SUMPRODUCT - * - * Excel Function: - * SUMPRODUCT(value1[,value2[, ...]]) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function SUMPRODUCT() { - $arrayList = func_get_args(); - - $wrkArray = PHPExcel_Calculation_Functions::flattenArray(array_shift($arrayList)); - $wrkCellCount = count($wrkArray); - - for ($i=0; $i< $wrkCellCount; ++$i) { - if ((!is_numeric($wrkArray[$i])) || (is_string($wrkArray[$i]))) { - $wrkArray[$i] = 0; - } - } - - foreach($arrayList as $matrixData) { - $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData); - $count = count($array2); - if ($wrkCellCount != $count) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - foreach ($array2 as $i => $val) { - if ((!is_numeric($val)) || (is_string($val))) { - $val = 0; - } - $wrkArray[$i] *= $val; - } - } - - return array_sum($wrkArray); - } // function SUMPRODUCT() - - - /** - * SUMSQ - * - * SUMSQ returns the sum of the squares of the arguments - * - * Excel Function: - * SUMSQ(value1[,value2[, ...]]) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function SUMSQ() { - // Return value - $returnValue = 0; - - // Loop through arguments - foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $returnValue += ($arg * $arg); - } - } - - // Return - return $returnValue; - } // function SUMSQ() - - - /** - * SUMX2MY2 - * - * @param mixed[] $matrixData1 Matrix #1 - * @param mixed[] $matrixData2 Matrix #2 - * @return float - */ - public static function SUMX2MY2($matrixData1,$matrixData2) { - $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); - $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); - $count1 = count($array1); - $count2 = count($array2); - if ($count1 < $count2) { - $count = $count1; - } else { - $count = $count2; - } - - $result = 0; - for ($i = 0; $i < $count; ++$i) { - if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && - ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { - $result += ($array1[$i] * $array1[$i]) - ($array2[$i] * $array2[$i]); - } - } - - return $result; - } // function SUMX2MY2() - - - /** - * SUMX2PY2 - * - * @param mixed[] $matrixData1 Matrix #1 - * @param mixed[] $matrixData2 Matrix #2 - * @return float - */ - public static function SUMX2PY2($matrixData1,$matrixData2) { - $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); - $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); - $count1 = count($array1); - $count2 = count($array2); - if ($count1 < $count2) { - $count = $count1; - } else { - $count = $count2; - } - - $result = 0; - for ($i = 0; $i < $count; ++$i) { - if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && - ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { - $result += ($array1[$i] * $array1[$i]) + ($array2[$i] * $array2[$i]); - } - } - - return $result; - } // function SUMX2PY2() - - - /** - * SUMXMY2 - * - * @param mixed[] $matrixData1 Matrix #1 - * @param mixed[] $matrixData2 Matrix #2 - * @return float - */ - public static function SUMXMY2($matrixData1,$matrixData2) { - $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); - $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); - $count1 = count($array1); - $count2 = count($array2); - if ($count1 < $count2) { - $count = $count1; - } else { - $count = $count2; - } - - $result = 0; - for ($i = 0; $i < $count; ++$i) { - if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && - ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { - $result += ($array1[$i] - $array2[$i]) * ($array1[$i] - $array2[$i]); - } - } - - return $result; - } // function SUMXMY2() - - - /** - * TRUNC - * - * Truncates value to the number of fractional digits by number_digits. - * - * @param float $value - * @param int $digits - * @return float Truncated value - */ - public static function TRUNC($value = 0, $digits = 0) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); - - // Validate parameters - if ((!is_numeric($value)) || (!is_numeric($digits))) - return PHPExcel_Calculation_Functions::VALUE(); - $digits = floor($digits); - - // Truncate - $adjust = pow(10, $digits); - - if (($digits > 0) && (rtrim(intval((abs($value) - abs(intval($value))) * $adjust),'0') < $adjust/10)) - return $value; - - return (intval($value * $adjust)) / $adjust; - } // function TRUNC() - -} // class PHPExcel_Calculation_MathTrig + return PHPExcel_Calculation_Functions::VALUE(); + } + } // function MMULT() + + + /** + * MOD + * + * @param int $a Dividend + * @param int $b Divisor + * @return int Remainder + */ + public static function MOD($a = 1, $b = 1) { + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + + if ($b == 0.0) { + return PHPExcel_Calculation_Functions::DIV0(); + } elseif (($a < 0.0) && ($b > 0.0)) { + return $b - fmod(abs($a),$b); + } elseif (($a > 0.0) && ($b < 0.0)) { + return $b + fmod($a,abs($b)); + } + + return fmod($a,$b); + } // function MOD() + + + /** + * MROUND + * + * Rounds a number to the nearest multiple of a specified value + * + * @param float $number Number to round + * @param int $multiple Multiple to which you want to round $number + * @return float Rounded Number + */ + public static function MROUND($number,$multiple) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $multiple = PHPExcel_Calculation_Functions::flattenSingleValue($multiple); + + if ((is_numeric($number)) && (is_numeric($multiple))) { + if ($multiple == 0) { + return 0; + } + if ((self::SIGN($number)) == (self::SIGN($multiple))) { + $multiplier = 1 / $multiple; + return round($number * $multiplier) / $multiplier; + } + return PHPExcel_Calculation_Functions::NaN(); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function MROUND() + + + /** + * MULTINOMIAL + * + * Returns the ratio of the factorial of a sum of values to the product of factorials. + * + * @param array of mixed Data Series + * @return float + */ + public static function MULTINOMIAL() { + $summer = 0; + $divisor = 1; + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if (is_numeric($arg)) { + if ($arg < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + $summer += floor($arg); + $divisor *= self::FACT($arg); + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + + // Return + if ($summer > 0) { + $summer = self::FACT($summer); + return $summer / $divisor; + } + return 0; + } // function MULTINOMIAL() + + + /** + * ODD + * + * Returns number rounded up to the nearest odd integer. + * + * @param float $number Number to round + * @return int Rounded Number + */ + public static function ODD($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_null($number)) { + return 1; + } elseif (is_bool($number)) { + $number = (int) $number; + } + + if (is_numeric($number)) { + $significance = self::SIGN($number); + if ($significance == 0) { + return 1; + } + + $result = self::CEILING($number,$significance); + if ($result == self::EVEN($result)) { + $result += $significance; + } + + return (int) $result; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ODD() + + + /** + * POWER + * + * Computes x raised to the power y. + * + * @param float $x + * @param float $y + * @return float + */ + public static function POWER($x = 0, $y = 2) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $y = PHPExcel_Calculation_Functions::flattenSingleValue($y); + + // Validate parameters + if ($x == 0.0 && $y == 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif ($x == 0.0 && $y < 0.0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + // Return + $result = pow($x, $y); + return (!is_nan($result) && !is_infinite($result)) ? $result : PHPExcel_Calculation_Functions::NaN(); + } // function POWER() + + + /** + * PRODUCT + * + * PRODUCT returns the product of all the values and cells referenced in the argument list. + * + * Excel Function: + * PRODUCT(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function PRODUCT() { + // Return value + $returnValue = null; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = $arg; + } else { + $returnValue *= $arg; + } + } + } + + // Return + if (is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function PRODUCT() + + + /** + * QUOTIENT + * + * QUOTIENT function returns the integer portion of a division. Numerator is the divided number + * and denominator is the divisor. + * + * Excel Function: + * QUOTIENT(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function QUOTIENT() { + // Return value + $returnValue = null; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = ($arg == 0) ? 0 : $arg; + } else { + if (($returnValue == 0) || ($arg == 0)) { + $returnValue = 0; + } else { + $returnValue /= $arg; + } + } + } + } + + // Return + return intval($returnValue); + } // function QUOTIENT() + + + /** + * RAND + * + * @param int $min Minimal value + * @param int $max Maximal value + * @return int Random number + */ + public static function RAND($min = 0, $max = 0) { + $min = PHPExcel_Calculation_Functions::flattenSingleValue($min); + $max = PHPExcel_Calculation_Functions::flattenSingleValue($max); + + if ($min == 0 && $max == 0) { + return (mt_rand(0,10000000)) / 10000000; + } else { + return mt_rand($min, $max); + } + } // function RAND() + + + public static function ROMAN($aValue, $style=0) { + $aValue = PHPExcel_Calculation_Functions::flattenSingleValue($aValue); + $style = (is_null($style)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($style); + if ((!is_numeric($aValue)) || ($aValue < 0) || ($aValue >= 4000)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $aValue = (integer) $aValue; + if ($aValue == 0) { + return ''; + } + + $mill = Array('', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM'); + $cent = Array('', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'); + $tens = Array('', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'); + $ones = Array('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'); + + $roman = ''; + while ($aValue > 5999) { + $roman .= 'M'; + $aValue -= 1000; + } + $m = self::_romanCut($aValue, 1000); $aValue %= 1000; + $c = self::_romanCut($aValue, 100); $aValue %= 100; + $t = self::_romanCut($aValue, 10); $aValue %= 10; + + return $roman.$mill[$m].$cent[$c].$tens[$t].$ones[$aValue]; + } // function ROMAN() + + + /** + * ROUNDUP + * + * Rounds a number up to a specified number of decimal places + * + * @param float $number Number to round + * @param int $digits Number of digits to which you want to round $number + * @return float Rounded Number + */ + public static function ROUNDUP($number,$digits) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); + + if ((is_numeric($number)) && (is_numeric($digits))) { + $significance = pow(10,(int) $digits); + if ($number < 0.0) { + return floor($number * $significance) / $significance; + } else { + return ceil($number * $significance) / $significance; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ROUNDUP() + + + /** + * ROUNDDOWN + * + * Rounds a number down to a specified number of decimal places + * + * @param float $number Number to round + * @param int $digits Number of digits to which you want to round $number + * @return float Rounded Number + */ + public static function ROUNDDOWN($number,$digits) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); + + if ((is_numeric($number)) && (is_numeric($digits))) { + $significance = pow(10,(int) $digits); + if ($number < 0.0) { + return ceil($number * $significance) / $significance; + } else { + return floor($number * $significance) / $significance; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ROUNDDOWN() + + + /** + * SERIESSUM + * + * Returns the sum of a power series + * + * @param float $x Input value to the power series + * @param float $n Initial power to which you want to raise $x + * @param float $m Step by which to increase $n for each term in the series + * @param array of mixed Data Series + * @return float + */ + public static function SERIESSUM() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + $x = array_shift($aArgs); + $n = array_shift($aArgs); + $m = array_shift($aArgs); + + if ((is_numeric($x)) && (is_numeric($n)) && (is_numeric($m))) { + // Calculate + $i = 0; + foreach($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue += $arg * pow($x,$n + ($m * $i++)); + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Return + return $returnValue; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SERIESSUM() + + + /** + * SIGN + * + * Determines the sign of a number. Returns 1 if the number is positive, zero (0) + * if the number is 0, and -1 if the number is negative. + * + * @param float $number Number to round + * @return int sign value + */ + public static function SIGN($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_bool($number)) + return (int) $number; + if (is_numeric($number)) { + if ($number == 0.0) { + return 0; + } + return $number / abs($number); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SIGN() + + + /** + * SQRTPI + * + * Returns the square root of (number * pi). + * + * @param float $number Number + * @return float Square Root of Number * Pi + */ + public static function SQRTPI($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_numeric($number)) { + if ($number < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return sqrt($number * M_PI) ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SQRTPI() + + + /** + * SUBTOTAL + * + * Returns a subtotal in a list or database. + * + * @param int the number 1 to 11 that specifies which function to + * use in calculating subtotals within a list. + * @param array of mixed Data Series + * @return float + */ + public static function SUBTOTAL() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $subtotal = array_shift($aArgs); + + if ((is_numeric($subtotal)) && (!is_string($subtotal))) { + switch($subtotal) { + case 1 : + return PHPExcel_Calculation_Statistical::AVERAGE($aArgs); + break; + case 2 : + return PHPExcel_Calculation_Statistical::COUNT($aArgs); + break; + case 3 : + return PHPExcel_Calculation_Statistical::COUNTA($aArgs); + break; + case 4 : + return PHPExcel_Calculation_Statistical::MAX($aArgs); + break; + case 5 : + return PHPExcel_Calculation_Statistical::MIN($aArgs); + break; + case 6 : + return self::PRODUCT($aArgs); + break; + case 7 : + return PHPExcel_Calculation_Statistical::STDEV($aArgs); + break; + case 8 : + return PHPExcel_Calculation_Statistical::STDEVP($aArgs); + break; + case 9 : + return self::SUM($aArgs); + break; + case 10 : + return PHPExcel_Calculation_Statistical::VARFunc($aArgs); + break; + case 11 : + return PHPExcel_Calculation_Statistical::VARP($aArgs); + break; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SUBTOTAL() + + + /** + * SUM + * + * SUM computes the sum of all the values and cells referenced in the argument list. + * + * Excel Function: + * SUM(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function SUM() { + // Return value + $returnValue = 0; + + // Loop through the arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue += $arg; + } + } + + // Return + return $returnValue; + } // function SUM() + + + /** + * SUMIF + * + * Counts the number of cells that contain numbers within the list of arguments + * + * Excel Function: + * SUMIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be summed. + * @return float + */ + public static function SUMIF($aArgs,$condition,$sumArgs = array()) { + // Return value + $returnValue = 0; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); + if (empty($sumArgs)) { + $sumArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { + $arg = str_replace('"', '""', $arg); + $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + } + + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + // Is it a value within our criteria + $returnValue += $sumArgs[$key]; + } + } + + // Return + return $returnValue; + } // function SUMIF() + + + /** + * SUMPRODUCT + * + * Excel Function: + * SUMPRODUCT(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function SUMPRODUCT() { + $arrayList = func_get_args(); + + $wrkArray = PHPExcel_Calculation_Functions::flattenArray(array_shift($arrayList)); + $wrkCellCount = count($wrkArray); + + for ($i=0; $i< $wrkCellCount; ++$i) { + if ((!is_numeric($wrkArray[$i])) || (is_string($wrkArray[$i]))) { + $wrkArray[$i] = 0; + } + } + + foreach($arrayList as $matrixData) { + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData); + $count = count($array2); + if ($wrkCellCount != $count) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + foreach ($array2 as $i => $val) { + if ((!is_numeric($val)) || (is_string($val))) { + $val = 0; + } + $wrkArray[$i] *= $val; + } + } + + return array_sum($wrkArray); + } // function SUMPRODUCT() + + + /** + * SUMSQ + * + * SUMSQ returns the sum of the squares of the arguments + * + * Excel Function: + * SUMSQ(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function SUMSQ() { + // Return value + $returnValue = 0; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue += ($arg * $arg); + } + } + + // Return + return $returnValue; + } // function SUMSQ() + + + /** + * SUMX2MY2 + * + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 + * @return float + */ + public static function SUMX2MY2($matrixData1,$matrixData2) { + $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); + $count1 = count($array1); + $count2 = count($array2); + if ($count1 < $count2) { + $count = $count1; + } else { + $count = $count2; + } + + $result = 0; + for ($i = 0; $i < $count; ++$i) { + if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && + ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { + $result += ($array1[$i] * $array1[$i]) - ($array2[$i] * $array2[$i]); + } + } + + return $result; + } // function SUMX2MY2() + + + /** + * SUMX2PY2 + * + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 + * @return float + */ + public static function SUMX2PY2($matrixData1,$matrixData2) { + $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); + $count1 = count($array1); + $count2 = count($array2); + if ($count1 < $count2) { + $count = $count1; + } else { + $count = $count2; + } + + $result = 0; + for ($i = 0; $i < $count; ++$i) { + if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && + ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { + $result += ($array1[$i] * $array1[$i]) + ($array2[$i] * $array2[$i]); + } + } + + return $result; + } // function SUMX2PY2() + + + /** + * SUMXMY2 + * + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 + * @return float + */ + public static function SUMXMY2($matrixData1,$matrixData2) { + $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); + $count1 = count($array1); + $count2 = count($array2); + if ($count1 < $count2) { + $count = $count1; + } else { + $count = $count2; + } + + $result = 0; + for ($i = 0; $i < $count; ++$i) { + if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && + ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { + $result += ($array1[$i] - $array2[$i]) * ($array1[$i] - $array2[$i]); + } + } + + return $result; + } // function SUMXMY2() + + + /** + * TRUNC + * + * Truncates value to the number of fractional digits by number_digits. + * + * @param float $value + * @param int $digits + * @return float Truncated value + */ + public static function TRUNC($value = 0, $digits = 0) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); + + // Validate parameters + if ((!is_numeric($value)) || (!is_numeric($digits))) + return PHPExcel_Calculation_Functions::VALUE(); + $digits = floor($digits); + + // Truncate + $adjust = pow(10, $digits); + + if (($digits > 0) && (rtrim(intval((abs($value) - abs(intval($value))) * $adjust),'0') < $adjust/10)) + return $value; + + return (intval($value * $adjust)) / $adjust; + } // function TRUNC() + +} // class PHPExcel_Calculation_MathTrig diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php index 8641118c0..acdb93bd7 100644 --- a/Classes/PHPExcel/Calculation/Statistical.php +++ b/Classes/PHPExcel/Calculation/Statistical.php @@ -18,21 +18,21 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } @@ -55,3597 +55,3597 @@ /** * PHPExcel_Calculation_Statistical * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_Statistical { - private static function _checkTrendArrays(&$array1,&$array2) { - if (!is_array($array1)) { $array1 = array($array1); } - if (!is_array($array2)) { $array2 = array($array2); } - - $array1 = PHPExcel_Calculation_Functions::flattenArray($array1); - $array2 = PHPExcel_Calculation_Functions::flattenArray($array2); - foreach($array1 as $key => $value) { - if ((is_bool($value)) || (is_string($value)) || (is_null($value))) { - unset($array1[$key]); - unset($array2[$key]); - } - } - foreach($array2 as $key => $value) { - if ((is_bool($value)) || (is_string($value)) || (is_null($value))) { - unset($array1[$key]); - unset($array2[$key]); - } - } - $array1 = array_merge($array1); - $array2 = array_merge($array2); - - return True; - } // function _checkTrendArrays() - - - /** - * Beta function. - * - * @author Jaco van Kooten - * - * @param p require p>0 - * @param q require q>0 - * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow - */ - private static function _beta($p, $q) { - if ($p <= 0.0 || $q <= 0.0 || ($p + $q) > LOG_GAMMA_X_MAX_VALUE) { - return 0.0; - } else { - return exp(self::_logBeta($p, $q)); - } - } // function _beta() - - - /** - * Incomplete beta function - * - * @author Jaco van Kooten - * @author Paul Meagher - * - * The computation is based on formulas from Numerical Recipes, Chapter 6.4 (W.H. Press et al, 1992). - * @param x require 0<=x<=1 - * @param p require p>0 - * @param q require q>0 - * @return 0 if x<0, p<=0, q<=0 or p+q>2.55E305 and 1 if x>1 to avoid errors and over/underflow - */ - private static function _incompleteBeta($x, $p, $q) { - if ($x <= 0.0) { - return 0.0; - } elseif ($x >= 1.0) { - return 1.0; - } elseif (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { - return 0.0; - } - $beta_gam = exp((0 - self::_logBeta($p, $q)) + $p * log($x) + $q * log(1.0 - $x)); - if ($x < ($p + 1.0) / ($p + $q + 2.0)) { - return $beta_gam * self::_betaFraction($x, $p, $q) / $p; - } else { - return 1.0 - ($beta_gam * self::_betaFraction(1 - $x, $q, $p) / $q); - } - } // function _incompleteBeta() - - - // Function cache for _logBeta function - private static $_logBetaCache_p = 0.0; - private static $_logBetaCache_q = 0.0; - private static $_logBetaCache_result = 0.0; - - /** - * The natural logarithm of the beta function. - * - * @param p require p>0 - * @param q require q>0 - * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow - * @author Jaco van Kooten - */ - private static function _logBeta($p, $q) { - if ($p != self::$_logBetaCache_p || $q != self::$_logBetaCache_q) { - self::$_logBetaCache_p = $p; - self::$_logBetaCache_q = $q; - if (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { - self::$_logBetaCache_result = 0.0; - } else { - self::$_logBetaCache_result = self::_logGamma($p) + self::_logGamma($q) - self::_logGamma($p + $q); - } - } - return self::$_logBetaCache_result; - } // function _logBeta() - - - /** - * Evaluates of continued fraction part of incomplete beta function. - * Based on an idea from Numerical Recipes (W.H. Press et al, 1992). - * @author Jaco van Kooten - */ - private static function _betaFraction($x, $p, $q) { - $c = 1.0; - $sum_pq = $p + $q; - $p_plus = $p + 1.0; - $p_minus = $p - 1.0; - $h = 1.0 - $sum_pq * $x / $p_plus; - if (abs($h) < XMININ) { - $h = XMININ; - } - $h = 1.0 / $h; - $frac = $h; - $m = 1; - $delta = 0.0; - while ($m <= MAX_ITERATIONS && abs($delta-1.0) > PRECISION ) { - $m2 = 2 * $m; - // even index for d - $d = $m * ($q - $m) * $x / ( ($p_minus + $m2) * ($p + $m2)); - $h = 1.0 + $d * $h; - if (abs($h) < XMININ) { - $h = XMININ; - } - $h = 1.0 / $h; - $c = 1.0 + $d / $c; - if (abs($c) < XMININ) { - $c = XMININ; - } - $frac *= $h * $c; - // odd index for d - $d = -($p + $m) * ($sum_pq + $m) * $x / (($p + $m2) * ($p_plus + $m2)); - $h = 1.0 + $d * $h; - if (abs($h) < XMININ) { - $h = XMININ; - } - $h = 1.0 / $h; - $c = 1.0 + $d / $c; - if (abs($c) < XMININ) { - $c = XMININ; - } - $delta = $h * $c; - $frac *= $delta; - ++$m; - } - return $frac; - } // function _betaFraction() - - - /** - * logGamma function - * - * @version 1.1 - * @author Jaco van Kooten - * - * Original author was Jaco van Kooten. Ported to PHP by Paul Meagher. - * - * The natural logarithm of the gamma function.
- * Based on public domain NETLIB (Fortran) code by W. J. Cody and L. Stoltz
- * Applied Mathematics Division
- * Argonne National Laboratory
- * Argonne, IL 60439
- *

- * References: - *

    - *
  1. W. J. Cody and K. E. Hillstrom, 'Chebyshev Approximations for the Natural - * Logarithm of the Gamma Function,' Math. Comp. 21, 1967, pp. 198-203.
  2. - *
  3. K. E. Hillstrom, ANL/AMD Program ANLC366S, DGAMMA/DLGAMA, May, 1969.
  4. - *
  5. Hart, Et. Al., Computer Approximations, Wiley and sons, New York, 1968.
  6. - *
- *

- *

- * From the original documentation: - *

- *

- * This routine calculates the LOG(GAMMA) function for a positive real argument X. - * Computation is based on an algorithm outlined in references 1 and 2. - * The program uses rational functions that theoretically approximate LOG(GAMMA) - * to at least 18 significant decimal digits. The approximation for X > 12 is from - * reference 3, while approximations for X < 12.0 are similar to those in reference - * 1, but are unpublished. The accuracy achieved depends on the arithmetic system, - * the compiler, the intrinsic functions, and proper selection of the - * machine-dependent constants. - *

- *

- * Error returns:
- * The program returns the value XINF for X .LE. 0.0 or when overflow would occur. - * The computation is believed to be free of underflow and overflow. - *

- * @return MAX_VALUE for x < 0.0 or when overflow would occur, i.e. x > 2.55E305 - */ - - // Function cache for logGamma - private static $_logGammaCache_result = 0.0; - private static $_logGammaCache_x = 0.0; - - private static function _logGamma($x) { - // Log Gamma related constants - static $lg_d1 = -0.5772156649015328605195174; - static $lg_d2 = 0.4227843350984671393993777; - static $lg_d4 = 1.791759469228055000094023; - - static $lg_p1 = array( 4.945235359296727046734888, - 201.8112620856775083915565, - 2290.838373831346393026739, - 11319.67205903380828685045, - 28557.24635671635335736389, - 38484.96228443793359990269, - 26377.48787624195437963534, - 7225.813979700288197698961 ); - static $lg_p2 = array( 4.974607845568932035012064, - 542.4138599891070494101986, - 15506.93864978364947665077, - 184793.2904445632425417223, - 1088204.76946882876749847, - 3338152.967987029735917223, - 5106661.678927352456275255, - 3074109.054850539556250927 ); - static $lg_p4 = array( 14745.02166059939948905062, - 2426813.369486704502836312, - 121475557.4045093227939592, - 2663432449.630976949898078, - 29403789566.34553899906876, - 170266573776.5398868392998, - 492612579337.743088758812, - 560625185622.3951465078242 ); - - static $lg_q1 = array( 67.48212550303777196073036, - 1113.332393857199323513008, - 7738.757056935398733233834, - 27639.87074403340708898585, - 54993.10206226157329794414, - 61611.22180066002127833352, - 36351.27591501940507276287, - 8785.536302431013170870835 ); - static $lg_q2 = array( 183.0328399370592604055942, - 7765.049321445005871323047, - 133190.3827966074194402448, - 1136705.821321969608938755, - 5267964.117437946917577538, - 13467014.54311101692290052, - 17827365.30353274213975932, - 9533095.591844353613395747 ); - static $lg_q4 = array( 2690.530175870899333379843, - 639388.5654300092398984238, - 41355999.30241388052042842, - 1120872109.61614794137657, - 14886137286.78813811542398, - 101680358627.2438228077304, - 341747634550.7377132798597, - 446315818741.9713286462081 ); - - static $lg_c = array( -0.001910444077728, - 8.4171387781295e-4, - -5.952379913043012e-4, - 7.93650793500350248e-4, - -0.002777777777777681622553, - 0.08333333333333333331554247, - 0.0057083835261 ); - - // Rough estimate of the fourth root of logGamma_xBig - static $lg_frtbig = 2.25e76; - static $pnt68 = 0.6796875; - - - if ($x == self::$_logGammaCache_x) { - return self::$_logGammaCache_result; - } - $y = $x; - if ($y > 0.0 && $y <= LOG_GAMMA_X_MAX_VALUE) { - if ($y <= EPS) { - $res = -log(y); - } elseif ($y <= 1.5) { - // --------------------- - // EPS .LT. X .LE. 1.5 - // --------------------- - if ($y < $pnt68) { - $corr = -log($y); - $xm1 = $y; - } else { - $corr = 0.0; - $xm1 = $y - 1.0; - } - if ($y <= 0.5 || $y >= $pnt68) { - $xden = 1.0; - $xnum = 0.0; - for ($i = 0; $i < 8; ++$i) { - $xnum = $xnum * $xm1 + $lg_p1[$i]; - $xden = $xden * $xm1 + $lg_q1[$i]; - } - $res = $corr + $xm1 * ($lg_d1 + $xm1 * ($xnum / $xden)); - } else { - $xm2 = $y - 1.0; - $xden = 1.0; - $xnum = 0.0; - for ($i = 0; $i < 8; ++$i) { - $xnum = $xnum * $xm2 + $lg_p2[$i]; - $xden = $xden * $xm2 + $lg_q2[$i]; - } - $res = $corr + $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); - } - } elseif ($y <= 4.0) { - // --------------------- - // 1.5 .LT. X .LE. 4.0 - // --------------------- - $xm2 = $y - 2.0; - $xden = 1.0; - $xnum = 0.0; - for ($i = 0; $i < 8; ++$i) { - $xnum = $xnum * $xm2 + $lg_p2[$i]; - $xden = $xden * $xm2 + $lg_q2[$i]; - } - $res = $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); - } elseif ($y <= 12.0) { - // ---------------------- - // 4.0 .LT. X .LE. 12.0 - // ---------------------- - $xm4 = $y - 4.0; - $xden = -1.0; - $xnum = 0.0; - for ($i = 0; $i < 8; ++$i) { - $xnum = $xnum * $xm4 + $lg_p4[$i]; - $xden = $xden * $xm4 + $lg_q4[$i]; - } - $res = $lg_d4 + $xm4 * ($xnum / $xden); - } else { - // --------------------------------- - // Evaluate for argument .GE. 12.0 - // --------------------------------- - $res = 0.0; - if ($y <= $lg_frtbig) { - $res = $lg_c[6]; - $ysq = $y * $y; - for ($i = 0; $i < 6; ++$i) - $res = $res / $ysq + $lg_c[$i]; - } - $res /= $y; - $corr = log($y); - $res = $res + log(SQRT2PI) - 0.5 * $corr; - $res += $y * ($corr - 1.0); - } - } else { - // -------------------------- - // Return for bad arguments - // -------------------------- - $res = MAX_VALUE; - } - // ------------------------------ - // Final adjustments and return - // ------------------------------ - self::$_logGammaCache_x = $x; - self::$_logGammaCache_result = $res; - return $res; - } // function _logGamma() - - - // - // Private implementation of the incomplete Gamma function - // - private static function _incompleteGamma($a,$x) { - static $max = 32; - $summer = 0; - for ($n=0; $n<=$max; ++$n) { - $divisor = $a; - for ($i=1; $i<=$n; ++$i) { - $divisor *= ($a + $i); - } - $summer += (pow($x,$n) / $divisor); - } - return pow($x,$a) * exp(0-$x) * $summer; - } // function _incompleteGamma() - - - // - // Private implementation of the Gamma function - // - private static function _gamma($data) { - if ($data == 0.0) return 0; - - static $p0 = 1.000000000190015; - static $p = array ( 1 => 76.18009172947146, - 2 => -86.50532032941677, - 3 => 24.01409824083091, - 4 => -1.231739572450155, - 5 => 1.208650973866179e-3, - 6 => -5.395239384953e-6 - ); - - $y = $x = $data; - $tmp = $x + 5.5; - $tmp -= ($x + 0.5) * log($tmp); - - $summer = $p0; - for ($j=1;$j<=6;++$j) { - $summer += ($p[$j] / ++$y); - } - return exp(0 - $tmp + log(SQRT2PI * $summer / $x)); - } // function _gamma() - - - /*************************************************************************** - * inverse_ncdf.php - * ------------------- - * begin : Friday, January 16, 2004 - * copyright : (C) 2004 Michael Nickerson - * email : nickersonm@yahoo.com - * - ***************************************************************************/ - private static function _inverse_ncdf($p) { - // Inverse ncdf approximation by Peter J. Acklam, implementation adapted to - // PHP by Michael Nickerson, using Dr. Thomas Ziegler's C implementation as - // a guide. http://home.online.no/~pjacklam/notes/invnorm/index.html - // I have not checked the accuracy of this implementation. Be aware that PHP - // will truncate the coeficcients to 14 digits. - - // You have permission to use and distribute this function freely for - // whatever purpose you want, but please show common courtesy and give credit - // where credit is due. - - // Input paramater is $p - probability - where 0 < p < 1. - - // Coefficients in rational approximations - static $a = array( 1 => -3.969683028665376e+01, - 2 => 2.209460984245205e+02, - 3 => -2.759285104469687e+02, - 4 => 1.383577518672690e+02, - 5 => -3.066479806614716e+01, - 6 => 2.506628277459239e+00 - ); - - static $b = array( 1 => -5.447609879822406e+01, - 2 => 1.615858368580409e+02, - 3 => -1.556989798598866e+02, - 4 => 6.680131188771972e+01, - 5 => -1.328068155288572e+01 - ); - - static $c = array( 1 => -7.784894002430293e-03, - 2 => -3.223964580411365e-01, - 3 => -2.400758277161838e+00, - 4 => -2.549732539343734e+00, - 5 => 4.374664141464968e+00, - 6 => 2.938163982698783e+00 - ); - - static $d = array( 1 => 7.784695709041462e-03, - 2 => 3.224671290700398e-01, - 3 => 2.445134137142996e+00, - 4 => 3.754408661907416e+00 - ); - - // Define lower and upper region break-points. - $p_low = 0.02425; //Use lower region approx. below this - $p_high = 1 - $p_low; //Use upper region approx. above this - - if (0 < $p && $p < $p_low) { - // Rational approximation for lower region. - $q = sqrt(-2 * log($p)); - return ((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) / - (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1); - } elseif ($p_low <= $p && $p <= $p_high) { - // Rational approximation for central region. - $q = $p - 0.5; - $r = $q * $q; - return ((((($a[1] * $r + $a[2]) * $r + $a[3]) * $r + $a[4]) * $r + $a[5]) * $r + $a[6]) * $q / - ((((($b[1] * $r + $b[2]) * $r + $b[3]) * $r + $b[4]) * $r + $b[5]) * $r + 1); - } elseif ($p_high < $p && $p < 1) { - // Rational approximation for upper region. - $q = sqrt(-2 * log(1 - $p)); - return -((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) / - (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1); - } - // If 0 < p < 1, return a null value - return PHPExcel_Calculation_Functions::NULL(); - } // function _inverse_ncdf() - - - private static function _inverse_ncdf2($prob) { - // Approximation of inverse standard normal CDF developed by - // B. Moro, "The Full Monte," Risk 8(2), Feb 1995, 57-58. - - $a1 = 2.50662823884; - $a2 = -18.61500062529; - $a3 = 41.39119773534; - $a4 = -25.44106049637; - - $b1 = -8.4735109309; - $b2 = 23.08336743743; - $b3 = -21.06224101826; - $b4 = 3.13082909833; - - $c1 = 0.337475482272615; - $c2 = 0.976169019091719; - $c3 = 0.160797971491821; - $c4 = 2.76438810333863E-02; - $c5 = 3.8405729373609E-03; - $c6 = 3.951896511919E-04; - $c7 = 3.21767881768E-05; - $c8 = 2.888167364E-07; - $c9 = 3.960315187E-07; - - $y = $prob - 0.5; - if (abs($y) < 0.42) { - $z = ($y * $y); - $z = $y * ((($a4 * $z + $a3) * $z + $a2) * $z + $a1) / (((($b4 * $z + $b3) * $z + $b2) * $z + $b1) * $z + 1); - } else { - if ($y > 0) { - $z = log(-log(1 - $prob)); - } else { - $z = log(-log($prob)); - } - $z = $c1 + $z * ($c2 + $z * ($c3 + $z * ($c4 + $z * ($c5 + $z * ($c6 + $z * ($c7 + $z * ($c8 + $z * $c9))))))); - if ($y < 0) { - $z = -$z; - } - } - return $z; - } // function _inverse_ncdf2() - - - private static function _inverse_ncdf3($p) { - // ALGORITHM AS241 APPL. STATIST. (1988) VOL. 37, NO. 3. - // Produces the normal deviate Z corresponding to a given lower - // tail area of P; Z is accurate to about 1 part in 10**16. - // - // This is a PHP version of the original FORTRAN code that can - // be found at http://lib.stat.cmu.edu/apstat/ - $split1 = 0.425; - $split2 = 5; - $const1 = 0.180625; - $const2 = 1.6; - - // coefficients for p close to 0.5 - $a0 = 3.3871328727963666080; - $a1 = 1.3314166789178437745E+2; - $a2 = 1.9715909503065514427E+3; - $a3 = 1.3731693765509461125E+4; - $a4 = 4.5921953931549871457E+4; - $a5 = 6.7265770927008700853E+4; - $a6 = 3.3430575583588128105E+4; - $a7 = 2.5090809287301226727E+3; - - $b1 = 4.2313330701600911252E+1; - $b2 = 6.8718700749205790830E+2; - $b3 = 5.3941960214247511077E+3; - $b4 = 2.1213794301586595867E+4; - $b5 = 3.9307895800092710610E+4; - $b6 = 2.8729085735721942674E+4; - $b7 = 5.2264952788528545610E+3; - - // coefficients for p not close to 0, 0.5 or 1. - $c0 = 1.42343711074968357734; - $c1 = 4.63033784615654529590; - $c2 = 5.76949722146069140550; - $c3 = 3.64784832476320460504; - $c4 = 1.27045825245236838258; - $c5 = 2.41780725177450611770E-1; - $c6 = 2.27238449892691845833E-2; - $c7 = 7.74545014278341407640E-4; - - $d1 = 2.05319162663775882187; - $d2 = 1.67638483018380384940; - $d3 = 6.89767334985100004550E-1; - $d4 = 1.48103976427480074590E-1; - $d5 = 1.51986665636164571966E-2; - $d6 = 5.47593808499534494600E-4; - $d7 = 1.05075007164441684324E-9; - - // coefficients for p near 0 or 1. - $e0 = 6.65790464350110377720; - $e1 = 5.46378491116411436990; - $e2 = 1.78482653991729133580; - $e3 = 2.96560571828504891230E-1; - $e4 = 2.65321895265761230930E-2; - $e5 = 1.24266094738807843860E-3; - $e6 = 2.71155556874348757815E-5; - $e7 = 2.01033439929228813265E-7; - - $f1 = 5.99832206555887937690E-1; - $f2 = 1.36929880922735805310E-1; - $f3 = 1.48753612908506148525E-2; - $f4 = 7.86869131145613259100E-4; - $f5 = 1.84631831751005468180E-5; - $f6 = 1.42151175831644588870E-7; - $f7 = 2.04426310338993978564E-15; - - $q = $p - 0.5; - - // computation for p close to 0.5 - if (abs($q) <= split1) { - $R = $const1 - $q * $q; - $z = $q * ((((((($a7 * $R + $a6) * $R + $a5) * $R + $a4) * $R + $a3) * $R + $a2) * $R + $a1) * $R + $a0) / - ((((((($b7 * $R + $b6) * $R + $b5) * $R + $b4) * $R + $b3) * $R + $b2) * $R + $b1) * $R + 1); - } else { - if ($q < 0) { - $R = $p; - } else { - $R = 1 - $p; - } - $R = pow(-log($R),2); - - // computation for p not close to 0, 0.5 or 1. - If ($R <= $split2) { - $R = $R - $const2; - $z = ((((((($c7 * $R + $c6) * $R + $c5) * $R + $c4) * $R + $c3) * $R + $c2) * $R + $c1) * $R + $c0) / - ((((((($d7 * $R + $d6) * $R + $d5) * $R + $d4) * $R + $d3) * $R + $d2) * $R + $d1) * $R + 1); - } else { - // computation for p near 0 or 1. - $R = $R - $split2; - $z = ((((((($e7 * $R + $e6) * $R + $e5) * $R + $e4) * $R + $e3) * $R + $e2) * $R + $e1) * $R + $e0) / - ((((((($f7 * $R + $f6) * $R + $f5) * $R + $f4) * $R + $f3) * $R + $f2) * $R + $f1) * $R + 1); - } - if ($q < 0) { - $z = -$z; - } - } - return $z; - } // function _inverse_ncdf3() - - - /** - * AVEDEV - * - * Returns the average of the absolute deviations of data points from their mean. - * AVEDEV is a measure of the variability in a data set. - * - * Excel Function: - * AVEDEV(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function AVEDEV() { - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - - // Return value - $returnValue = null; - - $aMean = self::AVERAGE($aArgs); - if ($aMean != PHPExcel_Calculation_Functions::DIV0()) { - $aCount = 0; - foreach ($aArgs as $k => $arg) { - if ((is_bool($arg)) && - ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { - $arg = (integer) $arg; - } - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - if (is_null($returnValue)) { - $returnValue = abs($arg - $aMean); - } else { - $returnValue += abs($arg - $aMean); - } - ++$aCount; - } - } - - // Return - if ($aCount == 0) { - return PHPExcel_Calculation_Functions::DIV0(); - } - return $returnValue / $aCount; - } - return PHPExcel_Calculation_Functions::NaN(); - } // function AVEDEV() - - - /** - * AVERAGE - * - * Returns the average (arithmetic mean) of the arguments - * - * Excel Function: - * AVERAGE(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function AVERAGE() { - $returnValue = $aCount = 0; - - // Loop through arguments - foreach (PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()) as $k => $arg) { - if ((is_bool($arg)) && - ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { - $arg = (integer) $arg; - } - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - if (is_null($returnValue)) { - $returnValue = $arg; - } else { - $returnValue += $arg; - } - ++$aCount; - } - } - - // Return - if ($aCount > 0) { - return $returnValue / $aCount; - } else { - return PHPExcel_Calculation_Functions::DIV0(); - } - } // function AVERAGE() - - - /** - * AVERAGEA - * - * Returns the average of its arguments, including numbers, text, and logical values - * - * Excel Function: - * AVERAGEA(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function AVERAGEA() { - // Return value - $returnValue = null; - - $aCount = 0; - // Loop through arguments - foreach (PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()) as $k => $arg) { - if ((is_bool($arg)) && - (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { - } else { - if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { - if (is_bool($arg)) { - $arg = (integer) $arg; - } elseif (is_string($arg)) { - $arg = 0; - } - if (is_null($returnValue)) { - $returnValue = $arg; - } else { - $returnValue += $arg; - } - ++$aCount; - } - } - } - - // Return - if ($aCount > 0) { - return $returnValue / $aCount; - } else { - return PHPExcel_Calculation_Functions::DIV0(); - } - } // function AVERAGEA() - - - /** - * AVERAGEIF - * - * Returns the average value from a range of cells that contain numbers within the list of arguments - * - * Excel Function: - * AVERAGEIF(value1[,value2[, ...]],condition) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @param string $condition The criteria that defines which cells will be checked. - * @param mixed[] $averageArgs Data values - * @return float - */ - public static function AVERAGEIF($aArgs,$condition,$averageArgs = array()) { - // Return value - $returnValue = 0; - - $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); - $averageArgs = PHPExcel_Calculation_Functions::flattenArray($averageArgs); - if (empty($averageArgs)) { - $averageArgs = $aArgs; - } - $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); - // Loop through arguments - $aCount = 0; - foreach ($aArgs as $key => $arg) { - if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } - $testCondition = '='.$arg.$condition; - if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { - if ((is_null($returnValue)) || ($arg > $returnValue)) { - $returnValue += $arg; - ++$aCount; - } - } - } - - // Return - if ($aCount > 0) { - return $returnValue / $aCount; - } else { - return PHPExcel_Calculation_Functions::DIV0(); - } - } // function AVERAGEIF() - - - /** - * BETADIST - * - * Returns the beta distribution. - * - * @param float $value Value at which you want to evaluate the distribution - * @param float $alpha Parameter to the distribution - * @param float $beta Parameter to the distribution - * @param boolean $cumulative - * @return float - * - */ - public static function BETADIST($value,$alpha,$beta,$rMin=0,$rMax=1) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); - $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); - $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); - - if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) { - if (($value < $rMin) || ($value > $rMax) || ($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($rMin > $rMax) { - $tmp = $rMin; - $rMin = $rMax; - $rMax = $tmp; - } - $value -= $rMin; - $value /= ($rMax - $rMin); - return self::_incompleteBeta($value,$alpha,$beta); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function BETADIST() - - - /** - * BETAINV - * - * Returns the inverse of the beta distribution. - * - * @param float $probability Probability at which you want to evaluate the distribution - * @param float $alpha Parameter to the distribution - * @param float $beta Parameter to the distribution - * @param float $rMin Minimum value - * @param float $rMax Maximum value - * @param boolean $cumulative - * @return float - * - */ - public static function BETAINV($probability,$alpha,$beta,$rMin=0,$rMax=1) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); - $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); - $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); - - if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) { - if (($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax) || ($probability <= 0) || ($probability > 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($rMin > $rMax) { - $tmp = $rMin; - $rMin = $rMax; - $rMax = $tmp; - } - $a = 0; - $b = 2; - - $i = 0; - while ((($b - $a) > PRECISION) && ($i++ < MAX_ITERATIONS)) { - $guess = ($a + $b) / 2; - $result = self::BETADIST($guess, $alpha, $beta); - if (($result == $probability) || ($result == 0)) { - $b = $a; - } elseif ($result > $probability) { - $b = $guess; - } else { - $a = $guess; - } - } - if ($i == MAX_ITERATIONS) { - return PHPExcel_Calculation_Functions::NA(); - } - return round($rMin + $guess * ($rMax - $rMin),12); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function BETAINV() - - - /** - * BINOMDIST - * - * Returns the individual term binomial distribution probability. Use BINOMDIST in problems with - * a fixed number of tests or trials, when the outcomes of any trial are only success or failure, - * when trials are independent, and when the probability of success is constant throughout the - * experiment. For example, BINOMDIST can calculate the probability that two of the next three - * babies born are male. - * - * @param float $value Number of successes in trials - * @param float $trials Number of trials - * @param float $probability Probability of success on each trial - * @param boolean $cumulative - * @return float - * - * @todo Cumulative distribution function - * - */ - public static function BINOMDIST($value, $trials, $probability, $cumulative) { - $value = floor(PHPExcel_Calculation_Functions::flattenSingleValue($value)); - $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - - if ((is_numeric($value)) && (is_numeric($trials)) && (is_numeric($probability))) { - if (($value < 0) || ($value > $trials)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (($probability < 0) || ($probability > 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ((is_numeric($cumulative)) || (is_bool($cumulative))) { - if ($cumulative) { - $summer = 0; - for ($i = 0; $i <= $value; ++$i) { - $summer += PHPExcel_Calculation_MathTrig::COMBIN($trials,$i) * pow($probability,$i) * pow(1 - $probability,$trials - $i); - } - return $summer; - } else { - return PHPExcel_Calculation_MathTrig::COMBIN($trials,$value) * pow($probability,$value) * pow(1 - $probability,$trials - $value) ; - } - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function BINOMDIST() - - - /** - * CHIDIST - * - * Returns the one-tailed probability of the chi-squared distribution. - * - * @param float $value Value for the function - * @param float $degrees degrees of freedom - * @return float - */ - public static function CHIDIST($value, $degrees) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); - - if ((is_numeric($value)) && (is_numeric($degrees))) { - if ($degrees < 1) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($value < 0) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - return 1; - } - return PHPExcel_Calculation_Functions::NaN(); - } - return 1 - (self::_incompleteGamma($degrees/2,$value/2) / self::_gamma($degrees/2)); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function CHIDIST() - - - /** - * CHIINV - * - * Returns the one-tailed probability of the chi-squared distribution. - * - * @param float $probability Probability for the function - * @param float $degrees degrees of freedom - * @return float - */ - public static function CHIINV($probability, $degrees) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); - - if ((is_numeric($probability)) && (is_numeric($degrees))) { - - $xLo = 100; - $xHi = 0; - - $x = $xNew = 1; - $dx = 1; - $i = 0; - - while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { - // Apply Newton-Raphson step - $result = self::CHIDIST($x, $degrees); - $error = $result - $probability; - if ($error == 0.0) { - $dx = 0; - } elseif ($error < 0.0) { - $xLo = $x; - } else { - $xHi = $x; - } - // Avoid division by zero - if ($result != 0.0) { - $dx = $error / $result; - $xNew = $x - $dx; - } - // If the NR fails to converge (which for example may be the - // case if the initial guess is too rough) we apply a bisection - // step to determine a more narrow interval around the root. - if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) { - $xNew = ($xLo + $xHi) / 2; - $dx = $xNew - $x; - } - $x = $xNew; - } - if ($i == MAX_ITERATIONS) { - return PHPExcel_Calculation_Functions::NA(); - } - return round($x,12); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function CHIINV() - - - /** - * CONFIDENCE - * - * Returns the confidence interval for a population mean - * - * @param float $alpha - * @param float $stdDev Standard Deviation - * @param float $size - * @return float - * - */ - public static function CONFIDENCE($alpha,$stdDev,$size) { - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); - $size = floor(PHPExcel_Calculation_Functions::flattenSingleValue($size)); - - if ((is_numeric($alpha)) && (is_numeric($stdDev)) && (is_numeric($size))) { - if (($alpha <= 0) || ($alpha >= 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (($stdDev <= 0) || ($size < 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - return self::NORMSINV(1 - $alpha / 2) * $stdDev / sqrt($size); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function CONFIDENCE() - - - /** - * CORREL - * - * Returns covariance, the average of the products of deviations for each data point pair. - * - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @return float - */ - public static function CORREL($yValues,$xValues=null) { - if ((is_null($xValues)) || (!is_array($yValues)) || (!is_array($xValues))) { - return PHPExcel_Calculation_Functions::VALUE(); - } - if (!self::_checkTrendArrays($yValues,$xValues)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $yValueCount = count($yValues); - $xValueCount = count($xValues); - - if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { - return PHPExcel_Calculation_Functions::NA(); - } elseif ($yValueCount == 1) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); - return $bestFitLinear->getCorrelation(); - } // function CORREL() - - - /** - * COUNT - * - * Counts the number of cells that contain numbers within the list of arguments - * - * Excel Function: - * COUNT(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return int - */ - public static function COUNT() { - // Return value - $returnValue = 0; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - foreach ($aArgs as $k => $arg) { - if ((is_bool($arg)) && - ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { - $arg = (integer) $arg; - } - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - ++$returnValue; - } - } - - // Return - return $returnValue; - } // function COUNT() - - - /** - * COUNTA - * - * Counts the number of cells that are not empty within the list of arguments - * - * Excel Function: - * COUNTA(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return int - */ - public static function COUNTA() { - // Return value - $returnValue = 0; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - foreach ($aArgs as $arg) { - // Is it a numeric, boolean or string value? - if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { - ++$returnValue; - } - } - - // Return - return $returnValue; - } // function COUNTA() - - - /** - * COUNTBLANK - * - * Counts the number of empty cells within the list of arguments - * - * Excel Function: - * COUNTBLANK(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return int - */ - public static function COUNTBLANK() { - // Return value - $returnValue = 0; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - foreach ($aArgs as $arg) { - // Is it a blank cell? - if ((is_null($arg)) || ((is_string($arg)) && ($arg == ''))) { - ++$returnValue; - } - } - - // Return - return $returnValue; - } // function COUNTBLANK() - - - /** - * COUNTIF - * - * Counts the number of cells that contain numbers within the list of arguments - * - * Excel Function: - * COUNTIF(value1[,value2[, ...]],condition) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @param string $condition The criteria that defines which cells will be counted. - * @return int - */ - public static function COUNTIF($aArgs,$condition) { - // Return value - $returnValue = 0; - - $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); - $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); - // Loop through arguments - foreach ($aArgs as $arg) { - if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } - $testCondition = '='.$arg.$condition; - if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { - // Is it a value within our criteria - ++$returnValue; - } - } - - // Return - return $returnValue; - } // function COUNTIF() - - - /** - * COVAR - * - * Returns covariance, the average of the products of deviations for each data point pair. - * - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @return float - */ - public static function COVAR($yValues,$xValues) { - if (!self::_checkTrendArrays($yValues,$xValues)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $yValueCount = count($yValues); - $xValueCount = count($xValues); - - if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { - return PHPExcel_Calculation_Functions::NA(); - } elseif ($yValueCount == 1) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); - return $bestFitLinear->getCovariance(); - } // function COVAR() - - - /** - * CRITBINOM - * - * Returns the smallest value for which the cumulative binomial distribution is greater - * than or equal to a criterion value - * - * See http://support.microsoft.com/kb/828117/ for details of the algorithm used - * - * @param float $trials number of Bernoulli trials - * @param float $probability probability of a success on each trial - * @param float $alpha criterion value - * @return int - * - * @todo Warning. This implementation differs from the algorithm detailed on the MS - * web site in that $CumPGuessMinus1 = $CumPGuess - 1 rather than $CumPGuess - $PGuess - * This eliminates a potential endless loop error, but may have an adverse affect on the - * accuracy of the function (although all my tests have so far returned correct results). - * - */ - public static function CRITBINOM($trials, $probability, $alpha) { - $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - - if ((is_numeric($trials)) && (is_numeric($probability)) && (is_numeric($alpha))) { - if ($trials < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (($probability < 0) || ($probability > 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (($alpha < 0) || ($alpha > 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($alpha <= 0.5) { - $t = sqrt(log(1 / ($alpha * $alpha))); - $trialsApprox = 0 - ($t + (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t)); - } else { - $t = sqrt(log(1 / pow(1 - $alpha,2))); - $trialsApprox = $t - (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t); - } - $Guess = floor($trials * $probability + $trialsApprox * sqrt($trials * $probability * (1 - $probability))); - if ($Guess < 0) { - $Guess = 0; - } elseif ($Guess > $trials) { - $Guess = $trials; - } - - $TotalUnscaledProbability = $UnscaledPGuess = $UnscaledCumPGuess = 0.0; - $EssentiallyZero = 10e-12; - - $m = floor($trials * $probability); - ++$TotalUnscaledProbability; - if ($m == $Guess) { ++$UnscaledPGuess; } - if ($m <= $Guess) { ++$UnscaledCumPGuess; } - - $PreviousValue = 1; - $Done = False; - $k = $m + 1; - while ((!$Done) && ($k <= $trials)) { - $CurrentValue = $PreviousValue * ($trials - $k + 1) * $probability / ($k * (1 - $probability)); - $TotalUnscaledProbability += $CurrentValue; - if ($k == $Guess) { $UnscaledPGuess += $CurrentValue; } - if ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; } - if ($CurrentValue <= $EssentiallyZero) { $Done = True; } - $PreviousValue = $CurrentValue; - ++$k; - } - - $PreviousValue = 1; - $Done = False; - $k = $m - 1; - while ((!$Done) && ($k >= 0)) { - $CurrentValue = $PreviousValue * $k + 1 * (1 - $probability) / (($trials - $k) * $probability); - $TotalUnscaledProbability += $CurrentValue; - if ($k == $Guess) { $UnscaledPGuess += $CurrentValue; } - if ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; } - if ($CurrentValue <= $EssentiallyZero) { $Done = True; } - $PreviousValue = $CurrentValue; - --$k; - } - - $PGuess = $UnscaledPGuess / $TotalUnscaledProbability; - $CumPGuess = $UnscaledCumPGuess / $TotalUnscaledProbability; - -// $CumPGuessMinus1 = $CumPGuess - $PGuess; - $CumPGuessMinus1 = $CumPGuess - 1; - - while (True) { - if (($CumPGuessMinus1 < $alpha) && ($CumPGuess >= $alpha)) { - return $Guess; - } elseif (($CumPGuessMinus1 < $alpha) && ($CumPGuess < $alpha)) { - $PGuessPlus1 = $PGuess * ($trials - $Guess) * $probability / $Guess / (1 - $probability); - $CumPGuessMinus1 = $CumPGuess; - $CumPGuess = $CumPGuess + $PGuessPlus1; - $PGuess = $PGuessPlus1; - ++$Guess; - } elseif (($CumPGuessMinus1 >= $alpha) && ($CumPGuess >= $alpha)) { - $PGuessMinus1 = $PGuess * $Guess * (1 - $probability) / ($trials - $Guess + 1) / $probability; - $CumPGuess = $CumPGuessMinus1; - $CumPGuessMinus1 = $CumPGuessMinus1 - $PGuess; - $PGuess = $PGuessMinus1; - --$Guess; - } - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function CRITBINOM() - - - /** - * DEVSQ - * - * Returns the sum of squares of deviations of data points from their sample mean. - * - * Excel Function: - * DEVSQ(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function DEVSQ() { - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - - // Return value - $returnValue = null; - - $aMean = self::AVERAGE($aArgs); - if ($aMean != PHPExcel_Calculation_Functions::DIV0()) { - $aCount = -1; - foreach ($aArgs as $k => $arg) { - // Is it a numeric value? - if ((is_bool($arg)) && - ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { - $arg = (integer) $arg; - } - if ((is_numeric($arg)) && (!is_string($arg))) { - if (is_null($returnValue)) { - $returnValue = pow(($arg - $aMean),2); - } else { - $returnValue += pow(($arg - $aMean),2); - } - ++$aCount; - } - } - - // Return - if (is_null($returnValue)) { - return PHPExcel_Calculation_Functions::NaN(); - } else { - return $returnValue; - } - } - return self::NA(); - } // function DEVSQ() - - - /** - * EXPONDIST - * - * Returns the exponential distribution. Use EXPONDIST to model the time between events, - * such as how long an automated bank teller takes to deliver cash. For example, you can - * use EXPONDIST to determine the probability that the process takes at most 1 minute. - * - * @param float $value Value of the function - * @param float $lambda The parameter value - * @param boolean $cumulative - * @return float - */ - public static function EXPONDIST($value, $lambda, $cumulative) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $lambda = PHPExcel_Calculation_Functions::flattenSingleValue($lambda); - $cumulative = PHPExcel_Calculation_Functions::flattenSingleValue($cumulative); - - if ((is_numeric($value)) && (is_numeric($lambda))) { - if (($value < 0) || ($lambda < 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ((is_numeric($cumulative)) || (is_bool($cumulative))) { - if ($cumulative) { - return 1 - exp(0-$value*$lambda); - } else { - return $lambda * exp(0-$value*$lambda); - } - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function EXPONDIST() - - - /** - * FISHER - * - * Returns the Fisher transformation at x. This transformation produces a function that - * is normally distributed rather than skewed. Use this function to perform hypothesis - * testing on the correlation coefficient. - * - * @param float $value - * @return float - */ - public static function FISHER($value) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - - if (is_numeric($value)) { - if (($value <= -1) || ($value >= 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - return 0.5 * log((1+$value)/(1-$value)); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function FISHER() - - - /** - * FISHERINV - * - * Returns the inverse of the Fisher transformation. Use this transformation when - * analyzing correlations between ranges or arrays of data. If y = FISHER(x), then - * FISHERINV(y) = x. - * - * @param float $value - * @return float - */ - public static function FISHERINV($value) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - - if (is_numeric($value)) { - return (exp(2 * $value) - 1) / (exp(2 * $value) + 1); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function FISHERINV() - - - /** - * FORECAST - * - * Calculates, or predicts, a future value by using existing values. The predicted value is a y-value for a given x-value. - * - * @param float Value of X for which we want to find Y - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @return float - */ - public static function FORECAST($xValue,$yValues,$xValues) { - $xValue = PHPExcel_Calculation_Functions::flattenSingleValue($xValue); - if (!is_numeric($xValue)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (!self::_checkTrendArrays($yValues,$xValues)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $yValueCount = count($yValues); - $xValueCount = count($xValues); - - if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { - return PHPExcel_Calculation_Functions::NA(); - } elseif ($yValueCount == 1) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); - return $bestFitLinear->getValueOfYForX($xValue); - } // function FORECAST() - - - /** - * GAMMADIST - * - * Returns the gamma distribution. - * - * @param float $value Value at which you want to evaluate the distribution - * @param float $a Parameter to the distribution - * @param float $b Parameter to the distribution - * @param boolean $cumulative - * @return float - * - */ - public static function GAMMADIST($value,$a,$b,$cumulative) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); - $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); - - if ((is_numeric($value)) && (is_numeric($a)) && (is_numeric($b))) { - if (($value < 0) || ($a <= 0) || ($b <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ((is_numeric($cumulative)) || (is_bool($cumulative))) { - if ($cumulative) { - return self::_incompleteGamma($a,$value / $b) / self::_gamma($a); - } else { - return (1 / (pow($b,$a) * self::_gamma($a))) * pow($value,$a-1) * exp(0-($value / $b)); - } - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function GAMMADIST() - - - /** - * GAMMAINV - * - * Returns the inverse of the beta distribution. - * - * @param float $probability Probability at which you want to evaluate the distribution - * @param float $alpha Parameter to the distribution - * @param float $beta Parameter to the distribution - * @return float - * - */ - public static function GAMMAINV($probability,$alpha,$beta) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); - - if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta))) { - if (($alpha <= 0) || ($beta <= 0) || ($probability < 0) || ($probability > 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - - $xLo = 0; - $xHi = $alpha * $beta * 5; - - $x = $xNew = 1; - $error = $pdf = 0; - $dx = 1024; - $i = 0; - - while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { - // Apply Newton-Raphson step - $error = self::GAMMADIST($x, $alpha, $beta, True) - $probability; - if ($error < 0.0) { - $xLo = $x; - } else { - $xHi = $x; - } - $pdf = self::GAMMADIST($x, $alpha, $beta, False); - // Avoid division by zero - if ($pdf != 0.0) { - $dx = $error / $pdf; - $xNew = $x - $dx; - } - // If the NR fails to converge (which for example may be the - // case if the initial guess is too rough) we apply a bisection - // step to determine a more narrow interval around the root. - if (($xNew < $xLo) || ($xNew > $xHi) || ($pdf == 0.0)) { - $xNew = ($xLo + $xHi) / 2; - $dx = $xNew - $x; - } - $x = $xNew; - } - if ($i == MAX_ITERATIONS) { - return PHPExcel_Calculation_Functions::NA(); - } - return $x; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function GAMMAINV() - - - /** - * GAMMALN - * - * Returns the natural logarithm of the gamma function. - * - * @param float $value - * @return float - */ - public static function GAMMALN($value) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - - if (is_numeric($value)) { - if ($value <= 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - return log(self::_gamma($value)); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function GAMMALN() - - - /** - * GEOMEAN - * - * Returns the geometric mean of an array or range of positive data. For example, you - * can use GEOMEAN to calculate average growth rate given compound interest with - * variable rates. - * - * Excel Function: - * GEOMEAN(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function GEOMEAN() { - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - - $aMean = PHPExcel_Calculation_MathTrig::PRODUCT($aArgs); - if (is_numeric($aMean) && ($aMean > 0)) { - $aCount = self::COUNT($aArgs) ; - if (self::MIN($aArgs) > 0) { - return pow($aMean, (1 / $aCount)); - } - } - return PHPExcel_Calculation_Functions::NaN(); - } // GEOMEAN() - - - /** - * GROWTH - * - * Returns values along a predicted emponential trend - * - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @param array of mixed Values of X for which we want to find Y - * @param boolean A logical value specifying whether to force the intersect to equal 0. - * @return array of float - */ - public static function GROWTH($yValues,$xValues=array(),$newValues=array(),$const=True) { - $yValues = PHPExcel_Calculation_Functions::flattenArray($yValues); - $xValues = PHPExcel_Calculation_Functions::flattenArray($xValues); - $newValues = PHPExcel_Calculation_Functions::flattenArray($newValues); - $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); - - $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const); - if (empty($newValues)) { - $newValues = $bestFitExponential->getXValues(); - } - - $returnArray = array(); - foreach($newValues as $xValue) { - $returnArray[0][] = $bestFitExponential->getValueOfYForX($xValue); - } - - return $returnArray; - } // function GROWTH() - - - /** - * HARMEAN - * - * Returns the harmonic mean of a data set. The harmonic mean is the reciprocal of the - * arithmetic mean of reciprocals. - * - * Excel Function: - * HARMEAN(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function HARMEAN() { - // Return value - $returnValue = PHPExcel_Calculation_Functions::NA(); - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - if (self::MIN($aArgs) < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - $aCount = 0; - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - if ($arg <= 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (is_null($returnValue)) { - $returnValue = (1 / $arg); - } else { - $returnValue += (1 / $arg); - } - ++$aCount; - } - } - - // Return - if ($aCount > 0) { - return 1 / ($returnValue / $aCount); - } else { - return $returnValue; - } - } // function HARMEAN() - - - /** - * HYPGEOMDIST - * - * Returns the hypergeometric distribution. HYPGEOMDIST returns the probability of a given number of - * sample successes, given the sample size, population successes, and population size. - * - * @param float $sampleSuccesses Number of successes in the sample - * @param float $sampleNumber Size of the sample - * @param float $populationSuccesses Number of successes in the population - * @param float $populationNumber Population size - * @return float - * - */ - public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber) { - $sampleSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleSuccesses)); - $sampleNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleNumber)); - $populationSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationSuccesses)); - $populationNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationNumber)); - - if ((is_numeric($sampleSuccesses)) && (is_numeric($sampleNumber)) && (is_numeric($populationSuccesses)) && (is_numeric($populationNumber))) { - if (($sampleSuccesses < 0) || ($sampleSuccesses > $sampleNumber) || ($sampleSuccesses > $populationSuccesses)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (($sampleNumber <= 0) || ($sampleNumber > $populationNumber)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (($populationSuccesses <= 0) || ($populationSuccesses > $populationNumber)) { - return PHPExcel_Calculation_Functions::NaN(); - } - return PHPExcel_Calculation_MathTrig::COMBIN($populationSuccesses,$sampleSuccesses) * - PHPExcel_Calculation_MathTrig::COMBIN($populationNumber - $populationSuccesses,$sampleNumber - $sampleSuccesses) / - PHPExcel_Calculation_MathTrig::COMBIN($populationNumber,$sampleNumber); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function HYPGEOMDIST() - - - /** - * INTERCEPT - * - * Calculates the point at which a line will intersect the y-axis by using existing x-values and y-values. - * - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @return float - */ - public static function INTERCEPT($yValues,$xValues) { - if (!self::_checkTrendArrays($yValues,$xValues)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $yValueCount = count($yValues); - $xValueCount = count($xValues); - - if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { - return PHPExcel_Calculation_Functions::NA(); - } elseif ($yValueCount == 1) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); - return $bestFitLinear->getIntersect(); - } // function INTERCEPT() - - - /** - * KURT - * - * Returns the kurtosis of a data set. Kurtosis characterizes the relative peakedness - * or flatness of a distribution compared with the normal distribution. Positive - * kurtosis indicates a relatively peaked distribution. Negative kurtosis indicates a - * relatively flat distribution. - * - * @param array Data Series - * @return float - */ - public static function KURT() { - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - $mean = self::AVERAGE($aArgs); - $stdDev = self::STDEV($aArgs); - - if ($stdDev > 0) { - $count = $summer = 0; - // Loop through arguments - foreach ($aArgs as $k => $arg) { - if ((is_bool($arg)) && - (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { - } else { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $summer += pow((($arg - $mean) / $stdDev),4) ; - ++$count; - } - } - } - - // Return - if ($count > 3) { - return $summer * ($count * ($count+1) / (($count-1) * ($count-2) * ($count-3))) - (3 * pow($count-1,2) / (($count-2) * ($count-3))); - } - } - return PHPExcel_Calculation_Functions::DIV0(); - } // function KURT() - - - /** - * LARGE - * - * Returns the nth largest value in a data set. You can use this function to - * select a value based on its relative standing. - * - * Excel Function: - * LARGE(value1[,value2[, ...]],entry) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @param int $entry Position (ordered from the largest) in the array or range of data to return - * @return float - * - */ - public static function LARGE() { - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - - // Calculate - $entry = floor(array_pop($aArgs)); - - if ((is_numeric($entry)) && (!is_string($entry))) { - $mArgs = array(); - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $mArgs[] = $arg; - } - } - $count = self::COUNT($mArgs); - $entry = floor(--$entry); - if (($entry < 0) || ($entry >= $count) || ($count == 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - rsort($mArgs); - return $mArgs[$entry]; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function LARGE() - - - /** - * LINEST - * - * Calculates the statistics for a line by using the "least squares" method to calculate a straight line that best fits your data, - * and then returns an array that describes the line. - * - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @param boolean A logical value specifying whether to force the intersect to equal 0. - * @param boolean A logical value specifying whether to return additional regression statistics. - * @return array - */ - public static function LINEST($yValues, $xValues = NULL, $const = TRUE, $stats = FALSE) { - $const = (is_null($const)) ? TRUE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); - $stats = (is_null($stats)) ? FALSE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); - if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); - - if (!self::_checkTrendArrays($yValues,$xValues)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $yValueCount = count($yValues); - $xValueCount = count($xValues); - - - if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { - return PHPExcel_Calculation_Functions::NA(); - } elseif ($yValueCount == 1) { - return 0; - } - - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const); - if ($stats) { - return array( array( $bestFitLinear->getSlope(), - $bestFitLinear->getSlopeSE(), - $bestFitLinear->getGoodnessOfFit(), - $bestFitLinear->getF(), - $bestFitLinear->getSSRegression(), - ), - array( $bestFitLinear->getIntersect(), - $bestFitLinear->getIntersectSE(), - $bestFitLinear->getStdevOfResiduals(), - $bestFitLinear->getDFResiduals(), - $bestFitLinear->getSSResiduals() - ) - ); - } else { - return array( $bestFitLinear->getSlope(), - $bestFitLinear->getIntersect() - ); - } - } // function LINEST() - - - /** - * LOGEST - * - * Calculates an exponential curve that best fits the X and Y data series, - * and then returns an array that describes the line. - * - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @param boolean A logical value specifying whether to force the intersect to equal 0. - * @param boolean A logical value specifying whether to return additional regression statistics. - * @return array - */ - public static function LOGEST($yValues,$xValues=null,$const=True,$stats=False) { - $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); - $stats = (is_null($stats)) ? False : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); - if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); - - if (!self::_checkTrendArrays($yValues,$xValues)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $yValueCount = count($yValues); - $xValueCount = count($xValues); - - foreach($yValues as $value) { - if ($value <= 0.0) { - return PHPExcel_Calculation_Functions::NaN(); - } - } - - - if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { - return PHPExcel_Calculation_Functions::NA(); - } elseif ($yValueCount == 1) { - return 1; - } - - $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const); - if ($stats) { - return array( array( $bestFitExponential->getSlope(), - $bestFitExponential->getSlopeSE(), - $bestFitExponential->getGoodnessOfFit(), - $bestFitExponential->getF(), - $bestFitExponential->getSSRegression(), - ), - array( $bestFitExponential->getIntersect(), - $bestFitExponential->getIntersectSE(), - $bestFitExponential->getStdevOfResiduals(), - $bestFitExponential->getDFResiduals(), - $bestFitExponential->getSSResiduals() - ) - ); - } else { - return array( $bestFitExponential->getSlope(), - $bestFitExponential->getIntersect() - ); - } - } // function LOGEST() - - - /** - * LOGINV - * - * Returns the inverse of the normal cumulative distribution - * - * @param float $probability - * @param float $mean - * @param float $stdDev - * @return float - * - * @todo Try implementing P J Acklam's refinement algorithm for greater - * accuracy if I can get my head round the mathematics - * (as described at) http://home.online.no/~pjacklam/notes/invnorm/ - */ - public static function LOGINV($probability, $mean, $stdDev) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); - - if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) { - if (($probability < 0) || ($probability > 1) || ($stdDev <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - return exp($mean + $stdDev * self::NORMSINV($probability)); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function LOGINV() - - - /** - * LOGNORMDIST - * - * Returns the cumulative lognormal distribution of x, where ln(x) is normally distributed - * with parameters mean and standard_dev. - * - * @param float $value - * @param float $mean - * @param float $stdDev - * @return float - */ - public static function LOGNORMDIST($value, $mean, $stdDev) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); - - if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { - if (($value <= 0) || ($stdDev <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - return self::NORMSDIST((log($value) - $mean) / $stdDev); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function LOGNORMDIST() - - - /** - * MAX - * - * MAX returns the value of the element of the values passed that has the highest value, - * with negative numbers considered smaller than positive numbers. - * - * Excel Function: - * MAX(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function MAX() { - // Return value - $returnValue = null; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - if ((is_null($returnValue)) || ($arg > $returnValue)) { - $returnValue = $arg; - } - } - } - - // Return - if(is_null($returnValue)) { - return 0; - } - return $returnValue; - } // function MAX() - - - /** - * MAXA - * - * Returns the greatest value in a list of arguments, including numbers, text, and logical values - * - * Excel Function: - * MAXA(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function MAXA() { - // Return value - $returnValue = null; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { - if (is_bool($arg)) { - $arg = (integer) $arg; - } elseif (is_string($arg)) { - $arg = 0; - } - if ((is_null($returnValue)) || ($arg > $returnValue)) { - $returnValue = $arg; - } - } - } - - // Return - if(is_null($returnValue)) { - return 0; - } - return $returnValue; - } // function MAXA() - - - /** - * MAXIF - * - * Counts the maximum value within a range of cells that contain numbers within the list of arguments - * - * Excel Function: - * MAXIF(value1[,value2[, ...]],condition) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @param string $condition The criteria that defines which cells will be checked. - * @return float - */ - public static function MAXIF($aArgs,$condition,$sumArgs = array()) { - // Return value - $returnValue = null; - - $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); - $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); - if (empty($sumArgs)) { - $sumArgs = $aArgs; - } - $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); - // Loop through arguments - foreach ($aArgs as $key => $arg) { - if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } - $testCondition = '='.$arg.$condition; - if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { - if ((is_null($returnValue)) || ($arg > $returnValue)) { - $returnValue = $arg; - } - } - } - - // Return - return $returnValue; - } // function MAXIF() - - - /** - * MEDIAN - * - * Returns the median of the given numbers. The median is the number in the middle of a set of numbers. - * - * Excel Function: - * MEDIAN(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function MEDIAN() { - // Return value - $returnValue = PHPExcel_Calculation_Functions::NaN(); - - $mArgs = array(); - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $mArgs[] = $arg; - } - } - - $mValueCount = count($mArgs); - if ($mValueCount > 0) { - sort($mArgs,SORT_NUMERIC); - $mValueCount = $mValueCount / 2; - if ($mValueCount == floor($mValueCount)) { - $returnValue = ($mArgs[$mValueCount--] + $mArgs[$mValueCount]) / 2; - } else { - $mValueCount == floor($mValueCount); - $returnValue = $mArgs[$mValueCount]; - } - } - - // Return - return $returnValue; - } // function MEDIAN() - - - /** - * MIN - * - * MIN returns the value of the element of the values passed that has the smallest value, - * with negative numbers considered smaller than positive numbers. - * - * Excel Function: - * MIN(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function MIN() { - // Return value - $returnValue = null; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - if ((is_null($returnValue)) || ($arg < $returnValue)) { - $returnValue = $arg; - } - } - } - - // Return - if(is_null($returnValue)) { - return 0; - } - return $returnValue; - } // function MIN() - - - /** - * MINA - * - * Returns the smallest value in a list of arguments, including numbers, text, and logical values - * - * Excel Function: - * MINA(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function MINA() { - // Return value - $returnValue = null; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { - if (is_bool($arg)) { - $arg = (integer) $arg; - } elseif (is_string($arg)) { - $arg = 0; - } - if ((is_null($returnValue)) || ($arg < $returnValue)) { - $returnValue = $arg; - } - } - } - - // Return - if(is_null($returnValue)) { - return 0; - } - return $returnValue; - } // function MINA() - - - /** - * MINIF - * - * Returns the minimum value within a range of cells that contain numbers within the list of arguments - * - * Excel Function: - * MINIF(value1[,value2[, ...]],condition) - * - * @access public - * @category Mathematical and Trigonometric Functions - * @param mixed $arg,... Data values - * @param string $condition The criteria that defines which cells will be checked. - * @return float - */ - public static function MINIF($aArgs,$condition,$sumArgs = array()) { - // Return value - $returnValue = null; - - $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); - $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); - if (empty($sumArgs)) { - $sumArgs = $aArgs; - } - $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); - // Loop through arguments - foreach ($aArgs as $key => $arg) { - if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } - $testCondition = '='.$arg.$condition; - if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { - if ((is_null($returnValue)) || ($arg < $returnValue)) { - $returnValue = $arg; - } - } - } - - // Return - return $returnValue; - } // function MINIF() - - - // - // Special variant of array_count_values that isn't limited to strings and integers, - // but can work with floating point numbers as values - // - private static function _modeCalc($data) { - $frequencyArray = array(); - foreach($data as $datum) { - $found = False; - foreach($frequencyArray as $key => $value) { - if ((string) $value['value'] == (string) $datum) { - ++$frequencyArray[$key]['frequency']; - $found = True; - break; - } - } - if (!$found) { - $frequencyArray[] = array('value' => $datum, - 'frequency' => 1 ); - } - } - - foreach($frequencyArray as $key => $value) { - $frequencyList[$key] = $value['frequency']; - $valueList[$key] = $value['value']; - } - array_multisort($frequencyList, SORT_DESC, $valueList, SORT_ASC, SORT_NUMERIC, $frequencyArray); - - if ($frequencyArray[0]['frequency'] == 1) { - return PHPExcel_Calculation_Functions::NA(); - } - return $frequencyArray[0]['value']; - } // function _modeCalc() - - - /** - * MODE - * - * Returns the most frequently occurring, or repetitive, value in an array or range of data - * - * Excel Function: - * MODE(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function MODE() { - // Return value - $returnValue = PHPExcel_Calculation_Functions::NA(); - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - - $mArgs = array(); - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $mArgs[] = $arg; - } - } - - if (!empty($mArgs)) { - return self::_modeCalc($mArgs); - } - - // Return - return $returnValue; - } // function MODE() - - - /** - * NEGBINOMDIST - * - * Returns the negative binomial distribution. NEGBINOMDIST returns the probability that - * there will be number_f failures before the number_s-th success, when the constant - * probability of a success is probability_s. This function is similar to the binomial - * distribution, except that the number of successes is fixed, and the number of trials is - * variable. Like the binomial, trials are assumed to be independent. - * - * @param float $failures Number of Failures - * @param float $successes Threshold number of Successes - * @param float $probability Probability of success on each trial - * @return float - * - */ - public static function NEGBINOMDIST($failures, $successes, $probability) { - $failures = floor(PHPExcel_Calculation_Functions::flattenSingleValue($failures)); - $successes = floor(PHPExcel_Calculation_Functions::flattenSingleValue($successes)); - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - - if ((is_numeric($failures)) && (is_numeric($successes)) && (is_numeric($probability))) { - if (($failures < 0) || ($successes < 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (($probability < 0) || ($probability > 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - if (($failures + $successes - 1) <= 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - } - return (PHPExcel_Calculation_MathTrig::COMBIN($failures + $successes - 1,$successes - 1)) * (pow($probability,$successes)) * (pow(1 - $probability,$failures)) ; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function NEGBINOMDIST() - - - /** - * NORMDIST - * - * Returns the normal distribution for the specified mean and standard deviation. This - * function has a very wide range of applications in statistics, including hypothesis - * testing. - * - * @param float $value - * @param float $mean Mean Value - * @param float $stdDev Standard Deviation - * @param boolean $cumulative - * @return float - * - */ - public static function NORMDIST($value, $mean, $stdDev, $cumulative) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); - - if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { - if ($stdDev < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ((is_numeric($cumulative)) || (is_bool($cumulative))) { - if ($cumulative) { - return 0.5 * (1 + PHPExcel_Calculation_Engineering::_erfVal(($value - $mean) / ($stdDev * sqrt(2)))); - } else { - return (1 / (SQRT2PI * $stdDev)) * exp(0 - (pow($value - $mean,2) / (2 * ($stdDev * $stdDev)))); - } - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function NORMDIST() - - - /** - * NORMINV - * - * Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation. - * - * @param float $value - * @param float $mean Mean Value - * @param float $stdDev Standard Deviation - * @return float - * - */ - public static function NORMINV($probability,$mean,$stdDev) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); - - if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) { - if (($probability < 0) || ($probability > 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ($stdDev < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - return (self::_inverse_ncdf($probability) * $stdDev) + $mean; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function NORMINV() - - - /** - * NORMSDIST - * - * Returns the standard normal cumulative distribution function. The distribution has - * a mean of 0 (zero) and a standard deviation of one. Use this function in place of a - * table of standard normal curve areas. - * - * @param float $value - * @return float - */ - public static function NORMSDIST($value) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - - return self::NORMDIST($value, 0, 1, True); - } // function NORMSDIST() - - - /** - * NORMSINV - * - * Returns the inverse of the standard normal cumulative distribution - * - * @param float $value - * @return float - */ - public static function NORMSINV($value) { - return self::NORMINV($value, 0, 1); - } // function NORMSINV() - - - /** - * PERCENTILE - * - * Returns the nth percentile of values in a range.. - * - * Excel Function: - * PERCENTILE(value1[,value2[, ...]],entry) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @param float $entry Percentile value in the range 0..1, inclusive. - * @return float - */ - public static function PERCENTILE() { - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - - // Calculate - $entry = array_pop($aArgs); - - if ((is_numeric($entry)) && (!is_string($entry))) { - if (($entry < 0) || ($entry > 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $mArgs = array(); - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $mArgs[] = $arg; - } - } - $mValueCount = count($mArgs); - if ($mValueCount > 0) { - sort($mArgs); - $count = self::COUNT($mArgs); - $index = $entry * ($count-1); - $iBase = floor($index); - if ($index == $iBase) { - return $mArgs[$index]; - } else { - $iNext = $iBase + 1; - $iProportion = $index - $iBase; - return $mArgs[$iBase] + (($mArgs[$iNext] - $mArgs[$iBase]) * $iProportion) ; - } - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function PERCENTILE() - - - /** - * PERCENTRANK - * - * Returns the rank of a value in a data set as a percentage of the data set. - * - * @param array of number An array of, or a reference to, a list of numbers. - * @param number The number whose rank you want to find. - * @param number The number of significant digits for the returned percentage value. - * @return float - */ - public static function PERCENTRANK($valueSet,$value,$significance=3) { - $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $significance = (is_null($significance)) ? 3 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($significance); - - foreach($valueSet as $key => $valueEntry) { - if (!is_numeric($valueEntry)) { - unset($valueSet[$key]); - } - } - sort($valueSet,SORT_NUMERIC); - $valueCount = count($valueSet); - if ($valueCount == 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - - $valueAdjustor = $valueCount - 1; - if (($value < $valueSet[0]) || ($value > $valueSet[$valueAdjustor])) { - return PHPExcel_Calculation_Functions::NA(); - } - - $pos = array_search($value,$valueSet); - if ($pos === False) { - $pos = 0; - $testValue = $valueSet[0]; - while ($testValue < $value) { - $testValue = $valueSet[++$pos]; - } - --$pos; - $pos += (($value - $valueSet[$pos]) / ($testValue - $valueSet[$pos])); - } - - return round($pos / $valueAdjustor,$significance); - } // function PERCENTRANK() - - - /** - * PERMUT - * - * Returns the number of permutations for a given number of objects that can be - * selected from number objects. A permutation is any set or subset of objects or - * events where internal order is significant. Permutations are different from - * combinations, for which the internal order is not significant. Use this function - * for lottery-style probability calculations. - * - * @param int $numObjs Number of different objects - * @param int $numInSet Number of objects in each permutation - * @return int Number of permutations - */ - public static function PERMUT($numObjs,$numInSet) { - $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); - $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); - - if ((is_numeric($numObjs)) && (is_numeric($numInSet))) { - $numInSet = floor($numInSet); - if ($numObjs < $numInSet) { - return PHPExcel_Calculation_Functions::NaN(); - } - return round(PHPExcel_Calculation_MathTrig::FACT($numObjs) / PHPExcel_Calculation_MathTrig::FACT($numObjs - $numInSet)); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function PERMUT() - - - /** - * POISSON - * - * Returns the Poisson distribution. A common application of the Poisson distribution - * is predicting the number of events over a specific time, such as the number of - * cars arriving at a toll plaza in 1 minute. - * - * @param float $value - * @param float $mean Mean Value - * @param boolean $cumulative - * @return float - * - */ - public static function POISSON($value, $mean, $cumulative) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - - if ((is_numeric($value)) && (is_numeric($mean))) { - if (($value < 0) || ($mean <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ((is_numeric($cumulative)) || (is_bool($cumulative))) { - if ($cumulative) { - $summer = 0; - for ($i = 0; $i <= floor($value); ++$i) { - $summer += pow($mean,$i) / PHPExcel_Calculation_MathTrig::FACT($i); - } - return exp(0-$mean) * $summer; - } else { - return (exp(0-$mean) * pow($mean,$value)) / PHPExcel_Calculation_MathTrig::FACT($value); - } - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function POISSON() - - - /** - * QUARTILE - * - * Returns the quartile of a data set. - * - * Excel Function: - * QUARTILE(value1[,value2[, ...]],entry) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @param int $entry Quartile value in the range 1..3, inclusive. - * @return float - */ - public static function QUARTILE() { - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - - // Calculate - $entry = floor(array_pop($aArgs)); - - if ((is_numeric($entry)) && (!is_string($entry))) { - $entry /= 4; - if (($entry < 0) || ($entry > 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - return self::PERCENTILE($aArgs,$entry); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function QUARTILE() - - - /** - * RANK - * - * Returns the rank of a number in a list of numbers. - * - * @param number The number whose rank you want to find. - * @param array of number An array of, or a reference to, a list of numbers. - * @param mixed Order to sort the values in the value set - * @return float - */ - public static function RANK($value,$valueSet,$order=0) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); - $order = (is_null($order)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($order); - - foreach($valueSet as $key => $valueEntry) { - if (!is_numeric($valueEntry)) { - unset($valueSet[$key]); - } - } - - if ($order == 0) { - rsort($valueSet,SORT_NUMERIC); - } else { - sort($valueSet,SORT_NUMERIC); - } - $pos = array_search($value,$valueSet); - if ($pos === False) { - return PHPExcel_Calculation_Functions::NA(); - } - - return ++$pos; - } // function RANK() - - - /** - * RSQ - * - * Returns the square of the Pearson product moment correlation coefficient through data points in known_y's and known_x's. - * - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @return float - */ - public static function RSQ($yValues,$xValues) { - if (!self::_checkTrendArrays($yValues,$xValues)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $yValueCount = count($yValues); - $xValueCount = count($xValues); - - if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { - return PHPExcel_Calculation_Functions::NA(); - } elseif ($yValueCount == 1) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); - return $bestFitLinear->getGoodnessOfFit(); - } // function RSQ() - - - /** - * SKEW - * - * Returns the skewness of a distribution. Skewness characterizes the degree of asymmetry - * of a distribution around its mean. Positive skewness indicates a distribution with an - * asymmetric tail extending toward more positive values. Negative skewness indicates a - * distribution with an asymmetric tail extending toward more negative values. - * - * @param array Data Series - * @return float - */ - public static function SKEW() { - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - $mean = self::AVERAGE($aArgs); - $stdDev = self::STDEV($aArgs); - - $count = $summer = 0; - // Loop through arguments - foreach ($aArgs as $k => $arg) { - if ((is_bool($arg)) && - (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { - } else { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $summer += pow((($arg - $mean) / $stdDev),3) ; - ++$count; - } - } - } - - // Return - if ($count > 2) { - return $summer * ($count / (($count-1) * ($count-2))); - } - return PHPExcel_Calculation_Functions::DIV0(); - } // function SKEW() - - - /** - * SLOPE - * - * Returns the slope of the linear regression line through data points in known_y's and known_x's. - * - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @return float - */ - public static function SLOPE($yValues,$xValues) { - if (!self::_checkTrendArrays($yValues,$xValues)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $yValueCount = count($yValues); - $xValueCount = count($xValues); - - if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { - return PHPExcel_Calculation_Functions::NA(); - } elseif ($yValueCount == 1) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); - return $bestFitLinear->getSlope(); - } // function SLOPE() - - - /** - * SMALL - * - * Returns the nth smallest value in a data set. You can use this function to - * select a value based on its relative standing. - * - * Excel Function: - * SMALL(value1[,value2[, ...]],entry) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @param int $entry Position (ordered from the smallest) in the array or range of data to return - * @return float - */ - public static function SMALL() { - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - - // Calculate - $entry = array_pop($aArgs); - - if ((is_numeric($entry)) && (!is_string($entry))) { - $mArgs = array(); - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $mArgs[] = $arg; - } - } - $count = self::COUNT($mArgs); - $entry = floor(--$entry); - if (($entry < 0) || ($entry >= $count) || ($count == 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - sort($mArgs); - return $mArgs[$entry]; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function SMALL() - - - /** - * STANDARDIZE - * - * Returns a normalized value from a distribution characterized by mean and standard_dev. - * - * @param float $value Value to normalize - * @param float $mean Mean Value - * @param float $stdDev Standard Deviation - * @return float Standardized value - */ - public static function STANDARDIZE($value,$mean,$stdDev) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); - - if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { - if ($stdDev <= 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - return ($value - $mean) / $stdDev ; - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function STANDARDIZE() - - - /** - * STDEV - * - * Estimates standard deviation based on a sample. The standard deviation is a measure of how - * widely values are dispersed from the average value (the mean). - * - * Excel Function: - * STDEV(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function STDEV() { - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - - // Return value - $returnValue = null; - - $aMean = self::AVERAGE($aArgs); - if (!is_null($aMean)) { - $aCount = -1; - foreach ($aArgs as $k => $arg) { - if ((is_bool($arg)) && - ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { - $arg = (integer) $arg; - } - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - if (is_null($returnValue)) { - $returnValue = pow(($arg - $aMean),2); - } else { - $returnValue += pow(($arg - $aMean),2); - } - ++$aCount; - } - } - - // Return - if (($aCount > 0) && ($returnValue >= 0)) { - return sqrt($returnValue / $aCount); - } - } - return PHPExcel_Calculation_Functions::DIV0(); - } // function STDEV() - - - /** - * STDEVA - * - * Estimates standard deviation based on a sample, including numbers, text, and logical values - * - * Excel Function: - * STDEVA(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function STDEVA() { - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - - // Return value - $returnValue = null; - - $aMean = self::AVERAGEA($aArgs); - if (!is_null($aMean)) { - $aCount = -1; - foreach ($aArgs as $k => $arg) { - if ((is_bool($arg)) && - (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { - } else { - // Is it a numeric value? - if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { - if (is_bool($arg)) { - $arg = (integer) $arg; - } elseif (is_string($arg)) { - $arg = 0; - } - if (is_null($returnValue)) { - $returnValue = pow(($arg - $aMean),2); - } else { - $returnValue += pow(($arg - $aMean),2); - } - ++$aCount; - } - } - } - - // Return - if (($aCount > 0) && ($returnValue >= 0)) { - return sqrt($returnValue / $aCount); - } - } - return PHPExcel_Calculation_Functions::DIV0(); - } // function STDEVA() - - - /** - * STDEVP - * - * Calculates standard deviation based on the entire population - * - * Excel Function: - * STDEVP(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function STDEVP() { - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - - // Return value - $returnValue = null; - - $aMean = self::AVERAGE($aArgs); - if (!is_null($aMean)) { - $aCount = 0; - foreach ($aArgs as $k => $arg) { - if ((is_bool($arg)) && - ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { - $arg = (integer) $arg; - } - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - if (is_null($returnValue)) { - $returnValue = pow(($arg - $aMean),2); - } else { - $returnValue += pow(($arg - $aMean),2); - } - ++$aCount; - } - } - - // Return - if (($aCount > 0) && ($returnValue >= 0)) { - return sqrt($returnValue / $aCount); - } - } - return PHPExcel_Calculation_Functions::DIV0(); - } // function STDEVP() - - - /** - * STDEVPA - * - * Calculates standard deviation based on the entire population, including numbers, text, and logical values - * - * Excel Function: - * STDEVPA(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function STDEVPA() { - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - - // Return value - $returnValue = null; - - $aMean = self::AVERAGEA($aArgs); - if (!is_null($aMean)) { - $aCount = 0; - foreach ($aArgs as $k => $arg) { - if ((is_bool($arg)) && - (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { - } else { - // Is it a numeric value? - if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { - if (is_bool($arg)) { - $arg = (integer) $arg; - } elseif (is_string($arg)) { - $arg = 0; - } - if (is_null($returnValue)) { - $returnValue = pow(($arg - $aMean),2); - } else { - $returnValue += pow(($arg - $aMean),2); - } - ++$aCount; - } - } - } - - // Return - if (($aCount > 0) && ($returnValue >= 0)) { - return sqrt($returnValue / $aCount); - } - } - return PHPExcel_Calculation_Functions::DIV0(); - } // function STDEVPA() - - - /** - * STEYX - * - * Returns the standard error of the predicted y-value for each x in the regression. - * - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @return float - */ - public static function STEYX($yValues,$xValues) { - if (!self::_checkTrendArrays($yValues,$xValues)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - $yValueCount = count($yValues); - $xValueCount = count($xValues); - - if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { - return PHPExcel_Calculation_Functions::NA(); - } elseif ($yValueCount == 1) { - return PHPExcel_Calculation_Functions::DIV0(); - } - - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); - return $bestFitLinear->getStdevOfResiduals(); - } // function STEYX() - - - /** - * TDIST - * - * Returns the probability of Student's T distribution. - * - * @param float $value Value for the function - * @param float $degrees degrees of freedom - * @param float $tails number of tails (1 or 2) - * @return float - */ - public static function TDIST($value, $degrees, $tails) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); - $tails = floor(PHPExcel_Calculation_Functions::flattenSingleValue($tails)); - - if ((is_numeric($value)) && (is_numeric($degrees)) && (is_numeric($tails))) { - if (($value < 0) || ($degrees < 1) || ($tails < 1) || ($tails > 2)) { - return PHPExcel_Calculation_Functions::NaN(); - } - // tdist, which finds the probability that corresponds to a given value - // of t with k degrees of freedom. This algorithm is translated from a - // pascal function on p81 of "Statistical Computing in Pascal" by D - // Cooke, A H Craven & G M Clark (1985: Edward Arnold (Pubs.) Ltd: - // London). The above Pascal algorithm is itself a translation of the - // fortran algoritm "AS 3" by B E Cooper of the Atlas Computer - // Laboratory as reported in (among other places) "Applied Statistics - // Algorithms", editied by P Griffiths and I D Hill (1985; Ellis - // Horwood Ltd.; W. Sussex, England). - $tterm = $degrees; - $ttheta = atan2($value,sqrt($tterm)); - $tc = cos($ttheta); - $ts = sin($ttheta); - $tsum = 0; - - if (($degrees % 2) == 1) { - $ti = 3; - $tterm = $tc; - } else { - $ti = 2; - $tterm = 1; - } - - $tsum = $tterm; - while ($ti < $degrees) { - $tterm *= $tc * $tc * ($ti - 1) / $ti; - $tsum += $tterm; - $ti += 2; - } - $tsum *= $ts; - if (($degrees % 2) == 1) { $tsum = M_2DIVPI * ($tsum + $ttheta); } - $tValue = 0.5 * (1 + $tsum); - if ($tails == 1) { - return 1 - abs($tValue); - } else { - return 1 - abs((1 - $tValue) - $tValue); - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function TDIST() - - - /** - * TINV - * - * Returns the one-tailed probability of the chi-squared distribution. - * - * @param float $probability Probability for the function - * @param float $degrees degrees of freedom - * @return float - */ - public static function TINV($probability, $degrees) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); - - if ((is_numeric($probability)) && (is_numeric($degrees))) { - $xLo = 100; - $xHi = 0; - - $x = $xNew = 1; - $dx = 1; - $i = 0; - - while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { - // Apply Newton-Raphson step - $result = self::TDIST($x, $degrees, 2); - $error = $result - $probability; - if ($error == 0.0) { - $dx = 0; - } elseif ($error < 0.0) { - $xLo = $x; - } else { - $xHi = $x; - } - // Avoid division by zero - if ($result != 0.0) { - $dx = $error / $result; - $xNew = $x - $dx; - } - // If the NR fails to converge (which for example may be the - // case if the initial guess is too rough) we apply a bisection - // step to determine a more narrow interval around the root. - if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) { - $xNew = ($xLo + $xHi) / 2; - $dx = $xNew - $x; - } - $x = $xNew; - } - if ($i == MAX_ITERATIONS) { - return PHPExcel_Calculation_Functions::NA(); - } - return round($x,12); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function TINV() - - - /** - * TREND - * - * Returns values along a linear trend - * - * @param array of mixed Data Series Y - * @param array of mixed Data Series X - * @param array of mixed Values of X for which we want to find Y - * @param boolean A logical value specifying whether to force the intersect to equal 0. - * @return array of float - */ - public static function TREND($yValues,$xValues=array(),$newValues=array(),$const=True) { - $yValues = PHPExcel_Calculation_Functions::flattenArray($yValues); - $xValues = PHPExcel_Calculation_Functions::flattenArray($xValues); - $newValues = PHPExcel_Calculation_Functions::flattenArray($newValues); - $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); - - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const); - if (empty($newValues)) { - $newValues = $bestFitLinear->getXValues(); - } - - $returnArray = array(); - foreach($newValues as $xValue) { - $returnArray[0][] = $bestFitLinear->getValueOfYForX($xValue); - } - - return $returnArray; - } // function TREND() - - - /** - * TRIMMEAN - * - * Returns the mean of the interior of a data set. TRIMMEAN calculates the mean - * taken by excluding a percentage of data points from the top and bottom tails - * of a data set. - * - * Excel Function: - * TRIMEAN(value1[,value2[, ...]],$discard) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @param float $discard Percentage to discard - * @return float - */ - public static function TRIMMEAN() { - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - - // Calculate - $percent = array_pop($aArgs); - - if ((is_numeric($percent)) && (!is_string($percent))) { - if (($percent < 0) || ($percent > 1)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $mArgs = array(); - foreach ($aArgs as $arg) { - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $mArgs[] = $arg; - } - } - $discard = floor(self::COUNT($mArgs) * $percent / 2); - sort($mArgs); - for ($i=0; $i < $discard; ++$i) { - array_pop($mArgs); - array_shift($mArgs); - } - return self::AVERAGE($mArgs); - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function TRIMMEAN() - - - /** - * VARFunc - * - * Estimates variance based on a sample. - * - * Excel Function: - * VAR(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function VARFunc() { - // Return value - $returnValue = PHPExcel_Calculation_Functions::DIV0(); - - $summerA = $summerB = 0; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - $aCount = 0; - foreach ($aArgs as $arg) { - if (is_bool($arg)) { $arg = (integer) $arg; } - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $summerA += ($arg * $arg); - $summerB += $arg; - ++$aCount; - } - } - - // Return - if ($aCount > 1) { - $summerA *= $aCount; - $summerB *= $summerB; - $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1)); - } - return $returnValue; - } // function VARFunc() - - - /** - * VARA - * - * Estimates variance based on a sample, including numbers, text, and logical values - * - * Excel Function: - * VARA(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function VARA() { - // Return value - $returnValue = PHPExcel_Calculation_Functions::DIV0(); - - $summerA = $summerB = 0; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - $aCount = 0; - foreach ($aArgs as $k => $arg) { - if ((is_string($arg)) && - (PHPExcel_Calculation_Functions::isValue($k))) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif ((is_string($arg)) && - (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { - } else { - // Is it a numeric value? - if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { - if (is_bool($arg)) { - $arg = (integer) $arg; - } elseif (is_string($arg)) { - $arg = 0; - } - $summerA += ($arg * $arg); - $summerB += $arg; - ++$aCount; - } - } - } - - // Return - if ($aCount > 1) { - $summerA *= $aCount; - $summerB *= $summerB; - $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1)); - } - return $returnValue; - } // function VARA() - - - /** - * VARP - * - * Calculates variance based on the entire population - * - * Excel Function: - * VARP(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function VARP() { - // Return value - $returnValue = PHPExcel_Calculation_Functions::DIV0(); - - $summerA = $summerB = 0; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - $aCount = 0; - foreach ($aArgs as $arg) { - if (is_bool($arg)) { $arg = (integer) $arg; } - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $summerA += ($arg * $arg); - $summerB += $arg; - ++$aCount; - } - } - - // Return - if ($aCount > 0) { - $summerA *= $aCount; - $summerB *= $summerB; - $returnValue = ($summerA - $summerB) / ($aCount * $aCount); - } - return $returnValue; - } // function VARP() - - - /** - * VARPA - * - * Calculates variance based on the entire population, including numbers, text, and logical values - * - * Excel Function: - * VARPA(value1[,value2[, ...]]) - * - * @access public - * @category Statistical Functions - * @param mixed $arg,... Data values - * @return float - */ - public static function VARPA() { - // Return value - $returnValue = PHPExcel_Calculation_Functions::DIV0(); - - $summerA = $summerB = 0; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - $aCount = 0; - foreach ($aArgs as $k => $arg) { - if ((is_string($arg)) && - (PHPExcel_Calculation_Functions::isValue($k))) { - return PHPExcel_Calculation_Functions::VALUE(); - } elseif ((is_string($arg)) && - (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { - } else { - // Is it a numeric value? - if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { - if (is_bool($arg)) { - $arg = (integer) $arg; - } elseif (is_string($arg)) { - $arg = 0; - } - $summerA += ($arg * $arg); - $summerB += $arg; - ++$aCount; - } - } - } - - // Return - if ($aCount > 0) { - $summerA *= $aCount; - $summerB *= $summerB; - $returnValue = ($summerA - $summerB) / ($aCount * $aCount); - } - return $returnValue; - } // function VARPA() - - - /** - * WEIBULL - * - * Returns the Weibull distribution. Use this distribution in reliability - * analysis, such as calculating a device's mean time to failure. - * - * @param float $value - * @param float $alpha Alpha Parameter - * @param float $beta Beta Parameter - * @param boolean $cumulative - * @return float - * - */ - public static function WEIBULL($value, $alpha, $beta, $cumulative) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); - - if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta))) { - if (($value < 0) || ($alpha <= 0) || ($beta <= 0)) { - return PHPExcel_Calculation_Functions::NaN(); - } - if ((is_numeric($cumulative)) || (is_bool($cumulative))) { - if ($cumulative) { - return 1 - exp(0 - pow($value / $beta,$alpha)); - } else { - return ($alpha / pow($beta,$alpha)) * pow($value,$alpha - 1) * exp(0 - pow($value / $beta,$alpha)); - } - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function WEIBULL() - - - /** - * ZTEST - * - * Returns the Weibull distribution. Use this distribution in reliability - * analysis, such as calculating a device's mean time to failure. - * - * @param float $dataSet - * @param float $m0 Alpha Parameter - * @param float $sigma Beta Parameter - * @param boolean $cumulative - * @return float - * - */ - public static function ZTEST($dataSet, $m0, $sigma = NULL) { - $dataSet = PHPExcel_Calculation_Functions::flattenArrayIndexed($dataSet); - $m0 = PHPExcel_Calculation_Functions::flattenSingleValue($m0); - $sigma = PHPExcel_Calculation_Functions::flattenSingleValue($sigma); - - if (is_null($sigma)) { - $sigma = self::STDEV($dataSet); - } - $n = count($dataSet); - - return 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0)/($sigma/SQRT($n))); - } // function ZTEST() - -} // class PHPExcel_Calculation_Statistical + private static function _checkTrendArrays(&$array1,&$array2) { + if (!is_array($array1)) { $array1 = array($array1); } + if (!is_array($array2)) { $array2 = array($array2); } + + $array1 = PHPExcel_Calculation_Functions::flattenArray($array1); + $array2 = PHPExcel_Calculation_Functions::flattenArray($array2); + foreach($array1 as $key => $value) { + if ((is_bool($value)) || (is_string($value)) || (is_null($value))) { + unset($array1[$key]); + unset($array2[$key]); + } + } + foreach($array2 as $key => $value) { + if ((is_bool($value)) || (is_string($value)) || (is_null($value))) { + unset($array1[$key]); + unset($array2[$key]); + } + } + $array1 = array_merge($array1); + $array2 = array_merge($array2); + + return True; + } // function _checkTrendArrays() + + + /** + * Beta function. + * + * @author Jaco van Kooten + * + * @param p require p>0 + * @param q require q>0 + * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow + */ + private static function _beta($p, $q) { + if ($p <= 0.0 || $q <= 0.0 || ($p + $q) > LOG_GAMMA_X_MAX_VALUE) { + return 0.0; + } else { + return exp(self::_logBeta($p, $q)); + } + } // function _beta() + + + /** + * Incomplete beta function + * + * @author Jaco van Kooten + * @author Paul Meagher + * + * The computation is based on formulas from Numerical Recipes, Chapter 6.4 (W.H. Press et al, 1992). + * @param x require 0<=x<=1 + * @param p require p>0 + * @param q require q>0 + * @return 0 if x<0, p<=0, q<=0 or p+q>2.55E305 and 1 if x>1 to avoid errors and over/underflow + */ + private static function _incompleteBeta($x, $p, $q) { + if ($x <= 0.0) { + return 0.0; + } elseif ($x >= 1.0) { + return 1.0; + } elseif (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { + return 0.0; + } + $beta_gam = exp((0 - self::_logBeta($p, $q)) + $p * log($x) + $q * log(1.0 - $x)); + if ($x < ($p + 1.0) / ($p + $q + 2.0)) { + return $beta_gam * self::_betaFraction($x, $p, $q) / $p; + } else { + return 1.0 - ($beta_gam * self::_betaFraction(1 - $x, $q, $p) / $q); + } + } // function _incompleteBeta() + + + // Function cache for _logBeta function + private static $_logBetaCache_p = 0.0; + private static $_logBetaCache_q = 0.0; + private static $_logBetaCache_result = 0.0; + + /** + * The natural logarithm of the beta function. + * + * @param p require p>0 + * @param q require q>0 + * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow + * @author Jaco van Kooten + */ + private static function _logBeta($p, $q) { + if ($p != self::$_logBetaCache_p || $q != self::$_logBetaCache_q) { + self::$_logBetaCache_p = $p; + self::$_logBetaCache_q = $q; + if (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { + self::$_logBetaCache_result = 0.0; + } else { + self::$_logBetaCache_result = self::_logGamma($p) + self::_logGamma($q) - self::_logGamma($p + $q); + } + } + return self::$_logBetaCache_result; + } // function _logBeta() + + + /** + * Evaluates of continued fraction part of incomplete beta function. + * Based on an idea from Numerical Recipes (W.H. Press et al, 1992). + * @author Jaco van Kooten + */ + private static function _betaFraction($x, $p, $q) { + $c = 1.0; + $sum_pq = $p + $q; + $p_plus = $p + 1.0; + $p_minus = $p - 1.0; + $h = 1.0 - $sum_pq * $x / $p_plus; + if (abs($h) < XMININ) { + $h = XMININ; + } + $h = 1.0 / $h; + $frac = $h; + $m = 1; + $delta = 0.0; + while ($m <= MAX_ITERATIONS && abs($delta-1.0) > PRECISION ) { + $m2 = 2 * $m; + // even index for d + $d = $m * ($q - $m) * $x / ( ($p_minus + $m2) * ($p + $m2)); + $h = 1.0 + $d * $h; + if (abs($h) < XMININ) { + $h = XMININ; + } + $h = 1.0 / $h; + $c = 1.0 + $d / $c; + if (abs($c) < XMININ) { + $c = XMININ; + } + $frac *= $h * $c; + // odd index for d + $d = -($p + $m) * ($sum_pq + $m) * $x / (($p + $m2) * ($p_plus + $m2)); + $h = 1.0 + $d * $h; + if (abs($h) < XMININ) { + $h = XMININ; + } + $h = 1.0 / $h; + $c = 1.0 + $d / $c; + if (abs($c) < XMININ) { + $c = XMININ; + } + $delta = $h * $c; + $frac *= $delta; + ++$m; + } + return $frac; + } // function _betaFraction() + + + /** + * logGamma function + * + * @version 1.1 + * @author Jaco van Kooten + * + * Original author was Jaco van Kooten. Ported to PHP by Paul Meagher. + * + * The natural logarithm of the gamma function.
+ * Based on public domain NETLIB (Fortran) code by W. J. Cody and L. Stoltz
+ * Applied Mathematics Division
+ * Argonne National Laboratory
+ * Argonne, IL 60439
+ *

+ * References: + *

    + *
  1. W. J. Cody and K. E. Hillstrom, 'Chebyshev Approximations for the Natural + * Logarithm of the Gamma Function,' Math. Comp. 21, 1967, pp. 198-203.
  2. + *
  3. K. E. Hillstrom, ANL/AMD Program ANLC366S, DGAMMA/DLGAMA, May, 1969.
  4. + *
  5. Hart, Et. Al., Computer Approximations, Wiley and sons, New York, 1968.
  6. + *
+ *

+ *

+ * From the original documentation: + *

+ *

+ * This routine calculates the LOG(GAMMA) function for a positive real argument X. + * Computation is based on an algorithm outlined in references 1 and 2. + * The program uses rational functions that theoretically approximate LOG(GAMMA) + * to at least 18 significant decimal digits. The approximation for X > 12 is from + * reference 3, while approximations for X < 12.0 are similar to those in reference + * 1, but are unpublished. The accuracy achieved depends on the arithmetic system, + * the compiler, the intrinsic functions, and proper selection of the + * machine-dependent constants. + *

+ *

+ * Error returns:
+ * The program returns the value XINF for X .LE. 0.0 or when overflow would occur. + * The computation is believed to be free of underflow and overflow. + *

+ * @return MAX_VALUE for x < 0.0 or when overflow would occur, i.e. x > 2.55E305 + */ + + // Function cache for logGamma + private static $_logGammaCache_result = 0.0; + private static $_logGammaCache_x = 0.0; + + private static function _logGamma($x) { + // Log Gamma related constants + static $lg_d1 = -0.5772156649015328605195174; + static $lg_d2 = 0.4227843350984671393993777; + static $lg_d4 = 1.791759469228055000094023; + + static $lg_p1 = array( 4.945235359296727046734888, + 201.8112620856775083915565, + 2290.838373831346393026739, + 11319.67205903380828685045, + 28557.24635671635335736389, + 38484.96228443793359990269, + 26377.48787624195437963534, + 7225.813979700288197698961 ); + static $lg_p2 = array( 4.974607845568932035012064, + 542.4138599891070494101986, + 15506.93864978364947665077, + 184793.2904445632425417223, + 1088204.76946882876749847, + 3338152.967987029735917223, + 5106661.678927352456275255, + 3074109.054850539556250927 ); + static $lg_p4 = array( 14745.02166059939948905062, + 2426813.369486704502836312, + 121475557.4045093227939592, + 2663432449.630976949898078, + 29403789566.34553899906876, + 170266573776.5398868392998, + 492612579337.743088758812, + 560625185622.3951465078242 ); + + static $lg_q1 = array( 67.48212550303777196073036, + 1113.332393857199323513008, + 7738.757056935398733233834, + 27639.87074403340708898585, + 54993.10206226157329794414, + 61611.22180066002127833352, + 36351.27591501940507276287, + 8785.536302431013170870835 ); + static $lg_q2 = array( 183.0328399370592604055942, + 7765.049321445005871323047, + 133190.3827966074194402448, + 1136705.821321969608938755, + 5267964.117437946917577538, + 13467014.54311101692290052, + 17827365.30353274213975932, + 9533095.591844353613395747 ); + static $lg_q4 = array( 2690.530175870899333379843, + 639388.5654300092398984238, + 41355999.30241388052042842, + 1120872109.61614794137657, + 14886137286.78813811542398, + 101680358627.2438228077304, + 341747634550.7377132798597, + 446315818741.9713286462081 ); + + static $lg_c = array( -0.001910444077728, + 8.4171387781295e-4, + -5.952379913043012e-4, + 7.93650793500350248e-4, + -0.002777777777777681622553, + 0.08333333333333333331554247, + 0.0057083835261 ); + + // Rough estimate of the fourth root of logGamma_xBig + static $lg_frtbig = 2.25e76; + static $pnt68 = 0.6796875; + + + if ($x == self::$_logGammaCache_x) { + return self::$_logGammaCache_result; + } + $y = $x; + if ($y > 0.0 && $y <= LOG_GAMMA_X_MAX_VALUE) { + if ($y <= EPS) { + $res = -log(y); + } elseif ($y <= 1.5) { + // --------------------- + // EPS .LT. X .LE. 1.5 + // --------------------- + if ($y < $pnt68) { + $corr = -log($y); + $xm1 = $y; + } else { + $corr = 0.0; + $xm1 = $y - 1.0; + } + if ($y <= 0.5 || $y >= $pnt68) { + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm1 + $lg_p1[$i]; + $xden = $xden * $xm1 + $lg_q1[$i]; + } + $res = $corr + $xm1 * ($lg_d1 + $xm1 * ($xnum / $xden)); + } else { + $xm2 = $y - 1.0; + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm2 + $lg_p2[$i]; + $xden = $xden * $xm2 + $lg_q2[$i]; + } + $res = $corr + $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); + } + } elseif ($y <= 4.0) { + // --------------------- + // 1.5 .LT. X .LE. 4.0 + // --------------------- + $xm2 = $y - 2.0; + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm2 + $lg_p2[$i]; + $xden = $xden * $xm2 + $lg_q2[$i]; + } + $res = $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); + } elseif ($y <= 12.0) { + // ---------------------- + // 4.0 .LT. X .LE. 12.0 + // ---------------------- + $xm4 = $y - 4.0; + $xden = -1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm4 + $lg_p4[$i]; + $xden = $xden * $xm4 + $lg_q4[$i]; + } + $res = $lg_d4 + $xm4 * ($xnum / $xden); + } else { + // --------------------------------- + // Evaluate for argument .GE. 12.0 + // --------------------------------- + $res = 0.0; + if ($y <= $lg_frtbig) { + $res = $lg_c[6]; + $ysq = $y * $y; + for ($i = 0; $i < 6; ++$i) + $res = $res / $ysq + $lg_c[$i]; + } + $res /= $y; + $corr = log($y); + $res = $res + log(SQRT2PI) - 0.5 * $corr; + $res += $y * ($corr - 1.0); + } + } else { + // -------------------------- + // Return for bad arguments + // -------------------------- + $res = MAX_VALUE; + } + // ------------------------------ + // Final adjustments and return + // ------------------------------ + self::$_logGammaCache_x = $x; + self::$_logGammaCache_result = $res; + return $res; + } // function _logGamma() + + + // + // Private implementation of the incomplete Gamma function + // + private static function _incompleteGamma($a,$x) { + static $max = 32; + $summer = 0; + for ($n=0; $n<=$max; ++$n) { + $divisor = $a; + for ($i=1; $i<=$n; ++$i) { + $divisor *= ($a + $i); + } + $summer += (pow($x,$n) / $divisor); + } + return pow($x,$a) * exp(0-$x) * $summer; + } // function _incompleteGamma() + + + // + // Private implementation of the Gamma function + // + private static function _gamma($data) { + if ($data == 0.0) return 0; + + static $p0 = 1.000000000190015; + static $p = array ( 1 => 76.18009172947146, + 2 => -86.50532032941677, + 3 => 24.01409824083091, + 4 => -1.231739572450155, + 5 => 1.208650973866179e-3, + 6 => -5.395239384953e-6 + ); + + $y = $x = $data; + $tmp = $x + 5.5; + $tmp -= ($x + 0.5) * log($tmp); + + $summer = $p0; + for ($j=1;$j<=6;++$j) { + $summer += ($p[$j] / ++$y); + } + return exp(0 - $tmp + log(SQRT2PI * $summer / $x)); + } // function _gamma() + + + /*************************************************************************** + * inverse_ncdf.php + * ------------------- + * begin : Friday, January 16, 2004 + * copyright : (C) 2004 Michael Nickerson + * email : nickersonm@yahoo.com + * + ***************************************************************************/ + private static function _inverse_ncdf($p) { + // Inverse ncdf approximation by Peter J. Acklam, implementation adapted to + // PHP by Michael Nickerson, using Dr. Thomas Ziegler's C implementation as + // a guide. http://home.online.no/~pjacklam/notes/invnorm/index.html + // I have not checked the accuracy of this implementation. Be aware that PHP + // will truncate the coeficcients to 14 digits. + + // You have permission to use and distribute this function freely for + // whatever purpose you want, but please show common courtesy and give credit + // where credit is due. + + // Input paramater is $p - probability - where 0 < p < 1. + + // Coefficients in rational approximations + static $a = array( 1 => -3.969683028665376e+01, + 2 => 2.209460984245205e+02, + 3 => -2.759285104469687e+02, + 4 => 1.383577518672690e+02, + 5 => -3.066479806614716e+01, + 6 => 2.506628277459239e+00 + ); + + static $b = array( 1 => -5.447609879822406e+01, + 2 => 1.615858368580409e+02, + 3 => -1.556989798598866e+02, + 4 => 6.680131188771972e+01, + 5 => -1.328068155288572e+01 + ); + + static $c = array( 1 => -7.784894002430293e-03, + 2 => -3.223964580411365e-01, + 3 => -2.400758277161838e+00, + 4 => -2.549732539343734e+00, + 5 => 4.374664141464968e+00, + 6 => 2.938163982698783e+00 + ); + + static $d = array( 1 => 7.784695709041462e-03, + 2 => 3.224671290700398e-01, + 3 => 2.445134137142996e+00, + 4 => 3.754408661907416e+00 + ); + + // Define lower and upper region break-points. + $p_low = 0.02425; //Use lower region approx. below this + $p_high = 1 - $p_low; //Use upper region approx. above this + + if (0 < $p && $p < $p_low) { + // Rational approximation for lower region. + $q = sqrt(-2 * log($p)); + return ((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) / + (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1); + } elseif ($p_low <= $p && $p <= $p_high) { + // Rational approximation for central region. + $q = $p - 0.5; + $r = $q * $q; + return ((((($a[1] * $r + $a[2]) * $r + $a[3]) * $r + $a[4]) * $r + $a[5]) * $r + $a[6]) * $q / + ((((($b[1] * $r + $b[2]) * $r + $b[3]) * $r + $b[4]) * $r + $b[5]) * $r + 1); + } elseif ($p_high < $p && $p < 1) { + // Rational approximation for upper region. + $q = sqrt(-2 * log(1 - $p)); + return -((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) / + (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1); + } + // If 0 < p < 1, return a null value + return PHPExcel_Calculation_Functions::NULL(); + } // function _inverse_ncdf() + + + private static function _inverse_ncdf2($prob) { + // Approximation of inverse standard normal CDF developed by + // B. Moro, "The Full Monte," Risk 8(2), Feb 1995, 57-58. + + $a1 = 2.50662823884; + $a2 = -18.61500062529; + $a3 = 41.39119773534; + $a4 = -25.44106049637; + + $b1 = -8.4735109309; + $b2 = 23.08336743743; + $b3 = -21.06224101826; + $b4 = 3.13082909833; + + $c1 = 0.337475482272615; + $c2 = 0.976169019091719; + $c3 = 0.160797971491821; + $c4 = 2.76438810333863E-02; + $c5 = 3.8405729373609E-03; + $c6 = 3.951896511919E-04; + $c7 = 3.21767881768E-05; + $c8 = 2.888167364E-07; + $c9 = 3.960315187E-07; + + $y = $prob - 0.5; + if (abs($y) < 0.42) { + $z = ($y * $y); + $z = $y * ((($a4 * $z + $a3) * $z + $a2) * $z + $a1) / (((($b4 * $z + $b3) * $z + $b2) * $z + $b1) * $z + 1); + } else { + if ($y > 0) { + $z = log(-log(1 - $prob)); + } else { + $z = log(-log($prob)); + } + $z = $c1 + $z * ($c2 + $z * ($c3 + $z * ($c4 + $z * ($c5 + $z * ($c6 + $z * ($c7 + $z * ($c8 + $z * $c9))))))); + if ($y < 0) { + $z = -$z; + } + } + return $z; + } // function _inverse_ncdf2() + + + private static function _inverse_ncdf3($p) { + // ALGORITHM AS241 APPL. STATIST. (1988) VOL. 37, NO. 3. + // Produces the normal deviate Z corresponding to a given lower + // tail area of P; Z is accurate to about 1 part in 10**16. + // + // This is a PHP version of the original FORTRAN code that can + // be found at http://lib.stat.cmu.edu/apstat/ + $split1 = 0.425; + $split2 = 5; + $const1 = 0.180625; + $const2 = 1.6; + + // coefficients for p close to 0.5 + $a0 = 3.3871328727963666080; + $a1 = 1.3314166789178437745E+2; + $a2 = 1.9715909503065514427E+3; + $a3 = 1.3731693765509461125E+4; + $a4 = 4.5921953931549871457E+4; + $a5 = 6.7265770927008700853E+4; + $a6 = 3.3430575583588128105E+4; + $a7 = 2.5090809287301226727E+3; + + $b1 = 4.2313330701600911252E+1; + $b2 = 6.8718700749205790830E+2; + $b3 = 5.3941960214247511077E+3; + $b4 = 2.1213794301586595867E+4; + $b5 = 3.9307895800092710610E+4; + $b6 = 2.8729085735721942674E+4; + $b7 = 5.2264952788528545610E+3; + + // coefficients for p not close to 0, 0.5 or 1. + $c0 = 1.42343711074968357734; + $c1 = 4.63033784615654529590; + $c2 = 5.76949722146069140550; + $c3 = 3.64784832476320460504; + $c4 = 1.27045825245236838258; + $c5 = 2.41780725177450611770E-1; + $c6 = 2.27238449892691845833E-2; + $c7 = 7.74545014278341407640E-4; + + $d1 = 2.05319162663775882187; + $d2 = 1.67638483018380384940; + $d3 = 6.89767334985100004550E-1; + $d4 = 1.48103976427480074590E-1; + $d5 = 1.51986665636164571966E-2; + $d6 = 5.47593808499534494600E-4; + $d7 = 1.05075007164441684324E-9; + + // coefficients for p near 0 or 1. + $e0 = 6.65790464350110377720; + $e1 = 5.46378491116411436990; + $e2 = 1.78482653991729133580; + $e3 = 2.96560571828504891230E-1; + $e4 = 2.65321895265761230930E-2; + $e5 = 1.24266094738807843860E-3; + $e6 = 2.71155556874348757815E-5; + $e7 = 2.01033439929228813265E-7; + + $f1 = 5.99832206555887937690E-1; + $f2 = 1.36929880922735805310E-1; + $f3 = 1.48753612908506148525E-2; + $f4 = 7.86869131145613259100E-4; + $f5 = 1.84631831751005468180E-5; + $f6 = 1.42151175831644588870E-7; + $f7 = 2.04426310338993978564E-15; + + $q = $p - 0.5; + + // computation for p close to 0.5 + if (abs($q) <= split1) { + $R = $const1 - $q * $q; + $z = $q * ((((((($a7 * $R + $a6) * $R + $a5) * $R + $a4) * $R + $a3) * $R + $a2) * $R + $a1) * $R + $a0) / + ((((((($b7 * $R + $b6) * $R + $b5) * $R + $b4) * $R + $b3) * $R + $b2) * $R + $b1) * $R + 1); + } else { + if ($q < 0) { + $R = $p; + } else { + $R = 1 - $p; + } + $R = pow(-log($R),2); + + // computation for p not close to 0, 0.5 or 1. + If ($R <= $split2) { + $R = $R - $const2; + $z = ((((((($c7 * $R + $c6) * $R + $c5) * $R + $c4) * $R + $c3) * $R + $c2) * $R + $c1) * $R + $c0) / + ((((((($d7 * $R + $d6) * $R + $d5) * $R + $d4) * $R + $d3) * $R + $d2) * $R + $d1) * $R + 1); + } else { + // computation for p near 0 or 1. + $R = $R - $split2; + $z = ((((((($e7 * $R + $e6) * $R + $e5) * $R + $e4) * $R + $e3) * $R + $e2) * $R + $e1) * $R + $e0) / + ((((((($f7 * $R + $f6) * $R + $f5) * $R + $f4) * $R + $f3) * $R + $f2) * $R + $f1) * $R + 1); + } + if ($q < 0) { + $z = -$z; + } + } + return $z; + } // function _inverse_ncdf3() + + + /** + * AVEDEV + * + * Returns the average of the absolute deviations of data points from their mean. + * AVEDEV is a measure of the variability in a data set. + * + * Excel Function: + * AVEDEV(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function AVEDEV() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if ($aMean != PHPExcel_Calculation_Functions::DIV0()) { + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = abs($arg - $aMean); + } else { + $returnValue += abs($arg - $aMean); + } + ++$aCount; + } + } + + // Return + if ($aCount == 0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + return $returnValue / $aCount; + } + return PHPExcel_Calculation_Functions::NaN(); + } // function AVEDEV() + + + /** + * AVERAGE + * + * Returns the average (arithmetic mean) of the arguments + * + * Excel Function: + * AVERAGE(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function AVERAGE() { + $returnValue = $aCount = 0; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()) as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = $arg; + } else { + $returnValue += $arg; + } + ++$aCount; + } + } + + // Return + if ($aCount > 0) { + return $returnValue / $aCount; + } else { + return PHPExcel_Calculation_Functions::DIV0(); + } + } // function AVERAGE() + + + /** + * AVERAGEA + * + * Returns the average of its arguments, including numbers, text, and logical values + * + * Excel Function: + * AVERAGEA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function AVERAGEA() { + // Return value + $returnValue = null; + + $aCount = 0; + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()) as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if (is_null($returnValue)) { + $returnValue = $arg; + } else { + $returnValue += $arg; + } + ++$aCount; + } + } + } + + // Return + if ($aCount > 0) { + return $returnValue / $aCount; + } else { + return PHPExcel_Calculation_Functions::DIV0(); + } + } // function AVERAGEA() + + + /** + * AVERAGEIF + * + * Returns the average value from a range of cells that contain numbers within the list of arguments + * + * Excel Function: + * AVERAGEIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be checked. + * @param mixed[] $averageArgs Data values + * @return float + */ + public static function AVERAGEIF($aArgs,$condition,$averageArgs = array()) { + // Return value + $returnValue = 0; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $averageArgs = PHPExcel_Calculation_Functions::flattenArray($averageArgs); + if (empty($averageArgs)) { + $averageArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + $aCount = 0; + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue += $arg; + ++$aCount; + } + } + } + + // Return + if ($aCount > 0) { + return $returnValue / $aCount; + } else { + return PHPExcel_Calculation_Functions::DIV0(); + } + } // function AVERAGEIF() + + + /** + * BETADIST + * + * Returns the beta distribution. + * + * @param float $value Value at which you want to evaluate the distribution + * @param float $alpha Parameter to the distribution + * @param float $beta Parameter to the distribution + * @param boolean $cumulative + * @return float + * + */ + public static function BETADIST($value,$alpha,$beta,$rMin=0,$rMax=1) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); + $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); + + if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) { + if (($value < $rMin) || ($value > $rMax) || ($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($rMin > $rMax) { + $tmp = $rMin; + $rMin = $rMax; + $rMax = $tmp; + } + $value -= $rMin; + $value /= ($rMax - $rMin); + return self::_incompleteBeta($value,$alpha,$beta); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BETADIST() + + + /** + * BETAINV + * + * Returns the inverse of the beta distribution. + * + * @param float $probability Probability at which you want to evaluate the distribution + * @param float $alpha Parameter to the distribution + * @param float $beta Parameter to the distribution + * @param float $rMin Minimum value + * @param float $rMax Maximum value + * @param boolean $cumulative + * @return float + * + */ + public static function BETAINV($probability,$alpha,$beta,$rMin=0,$rMax=1) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); + $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); + + if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) { + if (($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax) || ($probability <= 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($rMin > $rMax) { + $tmp = $rMin; + $rMin = $rMax; + $rMax = $tmp; + } + $a = 0; + $b = 2; + + $i = 0; + while ((($b - $a) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + $guess = ($a + $b) / 2; + $result = self::BETADIST($guess, $alpha, $beta); + if (($result == $probability) || ($result == 0)) { + $b = $a; + } elseif ($result > $probability) { + $b = $guess; + } else { + $a = $guess; + } + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return round($rMin + $guess * ($rMax - $rMin),12); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BETAINV() + + + /** + * BINOMDIST + * + * Returns the individual term binomial distribution probability. Use BINOMDIST in problems with + * a fixed number of tests or trials, when the outcomes of any trial are only success or failure, + * when trials are independent, and when the probability of success is constant throughout the + * experiment. For example, BINOMDIST can calculate the probability that two of the next three + * babies born are male. + * + * @param float $value Number of successes in trials + * @param float $trials Number of trials + * @param float $probability Probability of success on each trial + * @param boolean $cumulative + * @return float + * + * @todo Cumulative distribution function + * + */ + public static function BINOMDIST($value, $trials, $probability, $cumulative) { + $value = floor(PHPExcel_Calculation_Functions::flattenSingleValue($value)); + $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + + if ((is_numeric($value)) && (is_numeric($trials)) && (is_numeric($probability))) { + if (($value < 0) || ($value > $trials)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + $summer = 0; + for ($i = 0; $i <= $value; ++$i) { + $summer += PHPExcel_Calculation_MathTrig::COMBIN($trials,$i) * pow($probability,$i) * pow(1 - $probability,$trials - $i); + } + return $summer; + } else { + return PHPExcel_Calculation_MathTrig::COMBIN($trials,$value) * pow($probability,$value) * pow(1 - $probability,$trials - $value) ; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BINOMDIST() + + + /** + * CHIDIST + * + * Returns the one-tailed probability of the chi-squared distribution. + * + * @param float $value Value for the function + * @param float $degrees degrees of freedom + * @return float + */ + public static function CHIDIST($value, $degrees) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + + if ((is_numeric($value)) && (is_numeric($degrees))) { + if ($degrees < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($value < 0) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + return 1; + } + return PHPExcel_Calculation_Functions::NaN(); + } + return 1 - (self::_incompleteGamma($degrees/2,$value/2) / self::_gamma($degrees/2)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CHIDIST() + + + /** + * CHIINV + * + * Returns the one-tailed probability of the chi-squared distribution. + * + * @param float $probability Probability for the function + * @param float $degrees degrees of freedom + * @return float + */ + public static function CHIINV($probability, $degrees) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + + if ((is_numeric($probability)) && (is_numeric($degrees))) { + + $xLo = 100; + $xHi = 0; + + $x = $xNew = 1; + $dx = 1; + $i = 0; + + while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + // Apply Newton-Raphson step + $result = self::CHIDIST($x, $degrees); + $error = $result - $probability; + if ($error == 0.0) { + $dx = 0; + } elseif ($error < 0.0) { + $xLo = $x; + } else { + $xHi = $x; + } + // Avoid division by zero + if ($result != 0.0) { + $dx = $error / $result; + $xNew = $x - $dx; + } + // If the NR fails to converge (which for example may be the + // case if the initial guess is too rough) we apply a bisection + // step to determine a more narrow interval around the root. + if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) { + $xNew = ($xLo + $xHi) / 2; + $dx = $xNew - $x; + } + $x = $xNew; + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return round($x,12); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CHIINV() + + + /** + * CONFIDENCE + * + * Returns the confidence interval for a population mean + * + * @param float $alpha + * @param float $stdDev Standard Deviation + * @param float $size + * @return float + * + */ + public static function CONFIDENCE($alpha,$stdDev,$size) { + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + $size = floor(PHPExcel_Calculation_Functions::flattenSingleValue($size)); + + if ((is_numeric($alpha)) && (is_numeric($stdDev)) && (is_numeric($size))) { + if (($alpha <= 0) || ($alpha >= 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($stdDev <= 0) || ($size < 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return self::NORMSINV(1 - $alpha / 2) * $stdDev / sqrt($size); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CONFIDENCE() + + + /** + * CORREL + * + * Returns covariance, the average of the products of deviations for each data point pair. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function CORREL($yValues,$xValues=null) { + if ((is_null($xValues)) || (!is_array($yValues)) || (!is_array($xValues))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getCorrelation(); + } // function CORREL() + + + /** + * COUNT + * + * Counts the number of cells that contain numbers within the list of arguments + * + * Excel Function: + * COUNT(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return int + */ + public static function COUNT() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNT() + + + /** + * COUNTA + * + * Counts the number of cells that are not empty within the list of arguments + * + * Excel Function: + * COUNTA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return int + */ + public static function COUNTA() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric, boolean or string value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNTA() + + + /** + * COUNTBLANK + * + * Counts the number of empty cells within the list of arguments + * + * Excel Function: + * COUNTBLANK(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return int + */ + public static function COUNTBLANK() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a blank cell? + if ((is_null($arg)) || ((is_string($arg)) && ($arg == ''))) { + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNTBLANK() + + + /** + * COUNTIF + * + * Counts the number of cells that contain numbers within the list of arguments + * + * Excel Function: + * COUNTIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be counted. + * @return int + */ + public static function COUNTIF($aArgs,$condition) { + // Return value + $returnValue = 0; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + // Is it a value within our criteria + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNTIF() + + + /** + * COVAR + * + * Returns covariance, the average of the products of deviations for each data point pair. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function COVAR($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getCovariance(); + } // function COVAR() + + + /** + * CRITBINOM + * + * Returns the smallest value for which the cumulative binomial distribution is greater + * than or equal to a criterion value + * + * See http://support.microsoft.com/kb/828117/ for details of the algorithm used + * + * @param float $trials number of Bernoulli trials + * @param float $probability probability of a success on each trial + * @param float $alpha criterion value + * @return int + * + * @todo Warning. This implementation differs from the algorithm detailed on the MS + * web site in that $CumPGuessMinus1 = $CumPGuess - 1 rather than $CumPGuess - $PGuess + * This eliminates a potential endless loop error, but may have an adverse affect on the + * accuracy of the function (although all my tests have so far returned correct results). + * + */ + public static function CRITBINOM($trials, $probability, $alpha) { + $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + + if ((is_numeric($trials)) && (is_numeric($probability)) && (is_numeric($alpha))) { + if ($trials < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($alpha < 0) || ($alpha > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($alpha <= 0.5) { + $t = sqrt(log(1 / ($alpha * $alpha))); + $trialsApprox = 0 - ($t + (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t)); + } else { + $t = sqrt(log(1 / pow(1 - $alpha,2))); + $trialsApprox = $t - (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t); + } + $Guess = floor($trials * $probability + $trialsApprox * sqrt($trials * $probability * (1 - $probability))); + if ($Guess < 0) { + $Guess = 0; + } elseif ($Guess > $trials) { + $Guess = $trials; + } + + $TotalUnscaledProbability = $UnscaledPGuess = $UnscaledCumPGuess = 0.0; + $EssentiallyZero = 10e-12; + + $m = floor($trials * $probability); + ++$TotalUnscaledProbability; + if ($m == $Guess) { ++$UnscaledPGuess; } + if ($m <= $Guess) { ++$UnscaledCumPGuess; } + + $PreviousValue = 1; + $Done = False; + $k = $m + 1; + while ((!$Done) && ($k <= $trials)) { + $CurrentValue = $PreviousValue * ($trials - $k + 1) * $probability / ($k * (1 - $probability)); + $TotalUnscaledProbability += $CurrentValue; + if ($k == $Guess) { $UnscaledPGuess += $CurrentValue; } + if ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; } + if ($CurrentValue <= $EssentiallyZero) { $Done = True; } + $PreviousValue = $CurrentValue; + ++$k; + } + + $PreviousValue = 1; + $Done = False; + $k = $m - 1; + while ((!$Done) && ($k >= 0)) { + $CurrentValue = $PreviousValue * $k + 1 * (1 - $probability) / (($trials - $k) * $probability); + $TotalUnscaledProbability += $CurrentValue; + if ($k == $Guess) { $UnscaledPGuess += $CurrentValue; } + if ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; } + if ($CurrentValue <= $EssentiallyZero) { $Done = True; } + $PreviousValue = $CurrentValue; + --$k; + } + + $PGuess = $UnscaledPGuess / $TotalUnscaledProbability; + $CumPGuess = $UnscaledCumPGuess / $TotalUnscaledProbability; + +// $CumPGuessMinus1 = $CumPGuess - $PGuess; + $CumPGuessMinus1 = $CumPGuess - 1; + + while (True) { + if (($CumPGuessMinus1 < $alpha) && ($CumPGuess >= $alpha)) { + return $Guess; + } elseif (($CumPGuessMinus1 < $alpha) && ($CumPGuess < $alpha)) { + $PGuessPlus1 = $PGuess * ($trials - $Guess) * $probability / $Guess / (1 - $probability); + $CumPGuessMinus1 = $CumPGuess; + $CumPGuess = $CumPGuess + $PGuessPlus1; + $PGuess = $PGuessPlus1; + ++$Guess; + } elseif (($CumPGuessMinus1 >= $alpha) && ($CumPGuess >= $alpha)) { + $PGuessMinus1 = $PGuess * $Guess * (1 - $probability) / ($trials - $Guess + 1) / $probability; + $CumPGuess = $CumPGuessMinus1; + $CumPGuessMinus1 = $CumPGuessMinus1 - $PGuess; + $PGuess = $PGuessMinus1; + --$Guess; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CRITBINOM() + + + /** + * DEVSQ + * + * Returns the sum of squares of deviations of data points from their sample mean. + * + * Excel Function: + * DEVSQ(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function DEVSQ() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if ($aMean != PHPExcel_Calculation_Functions::DIV0()) { + $aCount = -1; + foreach ($aArgs as $k => $arg) { + // Is it a numeric value? + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + + // Return + if (is_null($returnValue)) { + return PHPExcel_Calculation_Functions::NaN(); + } else { + return $returnValue; + } + } + return self::NA(); + } // function DEVSQ() + + + /** + * EXPONDIST + * + * Returns the exponential distribution. Use EXPONDIST to model the time between events, + * such as how long an automated bank teller takes to deliver cash. For example, you can + * use EXPONDIST to determine the probability that the process takes at most 1 minute. + * + * @param float $value Value of the function + * @param float $lambda The parameter value + * @param boolean $cumulative + * @return float + */ + public static function EXPONDIST($value, $lambda, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $lambda = PHPExcel_Calculation_Functions::flattenSingleValue($lambda); + $cumulative = PHPExcel_Calculation_Functions::flattenSingleValue($cumulative); + + if ((is_numeric($value)) && (is_numeric($lambda))) { + if (($value < 0) || ($lambda < 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return 1 - exp(0-$value*$lambda); + } else { + return $lambda * exp(0-$value*$lambda); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function EXPONDIST() + + + /** + * FISHER + * + * Returns the Fisher transformation at x. This transformation produces a function that + * is normally distributed rather than skewed. Use this function to perform hypothesis + * testing on the correlation coefficient. + * + * @param float $value + * @return float + */ + public static function FISHER($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_numeric($value)) { + if (($value <= -1) || ($value >= 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return 0.5 * log((1+$value)/(1-$value)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FISHER() + + + /** + * FISHERINV + * + * Returns the inverse of the Fisher transformation. Use this transformation when + * analyzing correlations between ranges or arrays of data. If y = FISHER(x), then + * FISHERINV(y) = x. + * + * @param float $value + * @return float + */ + public static function FISHERINV($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_numeric($value)) { + return (exp(2 * $value) - 1) / (exp(2 * $value) + 1); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FISHERINV() + + + /** + * FORECAST + * + * Calculates, or predicts, a future value by using existing values. The predicted value is a y-value for a given x-value. + * + * @param float Value of X for which we want to find Y + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function FORECAST($xValue,$yValues,$xValues) { + $xValue = PHPExcel_Calculation_Functions::flattenSingleValue($xValue); + if (!is_numeric($xValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getValueOfYForX($xValue); + } // function FORECAST() + + + /** + * GAMMADIST + * + * Returns the gamma distribution. + * + * @param float $value Value at which you want to evaluate the distribution + * @param float $a Parameter to the distribution + * @param float $b Parameter to the distribution + * @param boolean $cumulative + * @return float + * + */ + public static function GAMMADIST($value,$a,$b,$cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + + if ((is_numeric($value)) && (is_numeric($a)) && (is_numeric($b))) { + if (($value < 0) || ($a <= 0) || ($b <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return self::_incompleteGamma($a,$value / $b) / self::_gamma($a); + } else { + return (1 / (pow($b,$a) * self::_gamma($a))) * pow($value,$a-1) * exp(0-($value / $b)); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function GAMMADIST() + + + /** + * GAMMAINV + * + * Returns the inverse of the beta distribution. + * + * @param float $probability Probability at which you want to evaluate the distribution + * @param float $alpha Parameter to the distribution + * @param float $beta Parameter to the distribution + * @return float + * + */ + public static function GAMMAINV($probability,$alpha,$beta) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + + if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta))) { + if (($alpha <= 0) || ($beta <= 0) || ($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $xLo = 0; + $xHi = $alpha * $beta * 5; + + $x = $xNew = 1; + $error = $pdf = 0; + $dx = 1024; + $i = 0; + + while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + // Apply Newton-Raphson step + $error = self::GAMMADIST($x, $alpha, $beta, True) - $probability; + if ($error < 0.0) { + $xLo = $x; + } else { + $xHi = $x; + } + $pdf = self::GAMMADIST($x, $alpha, $beta, False); + // Avoid division by zero + if ($pdf != 0.0) { + $dx = $error / $pdf; + $xNew = $x - $dx; + } + // If the NR fails to converge (which for example may be the + // case if the initial guess is too rough) we apply a bisection + // step to determine a more narrow interval around the root. + if (($xNew < $xLo) || ($xNew > $xHi) || ($pdf == 0.0)) { + $xNew = ($xLo + $xHi) / 2; + $dx = $xNew - $x; + } + $x = $xNew; + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return $x; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function GAMMAINV() + + + /** + * GAMMALN + * + * Returns the natural logarithm of the gamma function. + * + * @param float $value + * @return float + */ + public static function GAMMALN($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_numeric($value)) { + if ($value <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return log(self::_gamma($value)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function GAMMALN() + + + /** + * GEOMEAN + * + * Returns the geometric mean of an array or range of positive data. For example, you + * can use GEOMEAN to calculate average growth rate given compound interest with + * variable rates. + * + * Excel Function: + * GEOMEAN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function GEOMEAN() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + $aMean = PHPExcel_Calculation_MathTrig::PRODUCT($aArgs); + if (is_numeric($aMean) && ($aMean > 0)) { + $aCount = self::COUNT($aArgs) ; + if (self::MIN($aArgs) > 0) { + return pow($aMean, (1 / $aCount)); + } + } + return PHPExcel_Calculation_Functions::NaN(); + } // GEOMEAN() + + + /** + * GROWTH + * + * Returns values along a predicted emponential trend + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param array of mixed Values of X for which we want to find Y + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @return array of float + */ + public static function GROWTH($yValues,$xValues=array(),$newValues=array(),$const=True) { + $yValues = PHPExcel_Calculation_Functions::flattenArray($yValues); + $xValues = PHPExcel_Calculation_Functions::flattenArray($xValues); + $newValues = PHPExcel_Calculation_Functions::flattenArray($newValues); + $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + + $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const); + if (empty($newValues)) { + $newValues = $bestFitExponential->getXValues(); + } + + $returnArray = array(); + foreach($newValues as $xValue) { + $returnArray[0][] = $bestFitExponential->getValueOfYForX($xValue); + } + + return $returnArray; + } // function GROWTH() + + + /** + * HARMEAN + * + * Returns the harmonic mean of a data set. The harmonic mean is the reciprocal of the + * arithmetic mean of reciprocals. + * + * Excel Function: + * HARMEAN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function HARMEAN() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::NA(); + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + if (self::MIN($aArgs) < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $aCount = 0; + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if ($arg <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (is_null($returnValue)) { + $returnValue = (1 / $arg); + } else { + $returnValue += (1 / $arg); + } + ++$aCount; + } + } + + // Return + if ($aCount > 0) { + return 1 / ($returnValue / $aCount); + } else { + return $returnValue; + } + } // function HARMEAN() + + + /** + * HYPGEOMDIST + * + * Returns the hypergeometric distribution. HYPGEOMDIST returns the probability of a given number of + * sample successes, given the sample size, population successes, and population size. + * + * @param float $sampleSuccesses Number of successes in the sample + * @param float $sampleNumber Size of the sample + * @param float $populationSuccesses Number of successes in the population + * @param float $populationNumber Population size + * @return float + * + */ + public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber) { + $sampleSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleSuccesses)); + $sampleNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleNumber)); + $populationSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationSuccesses)); + $populationNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationNumber)); + + if ((is_numeric($sampleSuccesses)) && (is_numeric($sampleNumber)) && (is_numeric($populationSuccesses)) && (is_numeric($populationNumber))) { + if (($sampleSuccesses < 0) || ($sampleSuccesses > $sampleNumber) || ($sampleSuccesses > $populationSuccesses)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($sampleNumber <= 0) || ($sampleNumber > $populationNumber)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($populationSuccesses <= 0) || ($populationSuccesses > $populationNumber)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return PHPExcel_Calculation_MathTrig::COMBIN($populationSuccesses,$sampleSuccesses) * + PHPExcel_Calculation_MathTrig::COMBIN($populationNumber - $populationSuccesses,$sampleNumber - $sampleSuccesses) / + PHPExcel_Calculation_MathTrig::COMBIN($populationNumber,$sampleNumber); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function HYPGEOMDIST() + + + /** + * INTERCEPT + * + * Calculates the point at which a line will intersect the y-axis by using existing x-values and y-values. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function INTERCEPT($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getIntersect(); + } // function INTERCEPT() + + + /** + * KURT + * + * Returns the kurtosis of a data set. Kurtosis characterizes the relative peakedness + * or flatness of a distribution compared with the normal distribution. Positive + * kurtosis indicates a relatively peaked distribution. Negative kurtosis indicates a + * relatively flat distribution. + * + * @param array Data Series + * @return float + */ + public static function KURT() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $mean = self::AVERAGE($aArgs); + $stdDev = self::STDEV($aArgs); + + if ($stdDev > 0) { + $count = $summer = 0; + // Loop through arguments + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summer += pow((($arg - $mean) / $stdDev),4) ; + ++$count; + } + } + } + + // Return + if ($count > 3) { + return $summer * ($count * ($count+1) / (($count-1) * ($count-2) * ($count-3))) - (3 * pow($count-1,2) / (($count-2) * ($count-3))); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function KURT() + + + /** + * LARGE + * + * Returns the nth largest value in a data set. You can use this function to + * select a value based on its relative standing. + * + * Excel Function: + * LARGE(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param int $entry Position (ordered from the largest) in the array or range of data to return + * @return float + * + */ + public static function LARGE() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = floor(array_pop($aArgs)); + + if ((is_numeric($entry)) && (!is_string($entry))) { + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $count = self::COUNT($mArgs); + $entry = floor(--$entry); + if (($entry < 0) || ($entry >= $count) || ($count == 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + rsort($mArgs); + return $mArgs[$entry]; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function LARGE() + + + /** + * LINEST + * + * Calculates the statistics for a line by using the "least squares" method to calculate a straight line that best fits your data, + * and then returns an array that describes the line. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @param boolean A logical value specifying whether to return additional regression statistics. + * @return array + */ + public static function LINEST($yValues, $xValues = NULL, $const = TRUE, $stats = FALSE) { + $const = (is_null($const)) ? TRUE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $stats = (is_null($stats)) ? FALSE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); + if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); + + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return 0; + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const); + if ($stats) { + return array( array( $bestFitLinear->getSlope(), + $bestFitLinear->getSlopeSE(), + $bestFitLinear->getGoodnessOfFit(), + $bestFitLinear->getF(), + $bestFitLinear->getSSRegression(), + ), + array( $bestFitLinear->getIntersect(), + $bestFitLinear->getIntersectSE(), + $bestFitLinear->getStdevOfResiduals(), + $bestFitLinear->getDFResiduals(), + $bestFitLinear->getSSResiduals() + ) + ); + } else { + return array( $bestFitLinear->getSlope(), + $bestFitLinear->getIntersect() + ); + } + } // function LINEST() + + + /** + * LOGEST + * + * Calculates an exponential curve that best fits the X and Y data series, + * and then returns an array that describes the line. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @param boolean A logical value specifying whether to return additional regression statistics. + * @return array + */ + public static function LOGEST($yValues,$xValues=null,$const=True,$stats=False) { + $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $stats = (is_null($stats)) ? False : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); + if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); + + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + foreach($yValues as $value) { + if ($value <= 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + } + + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return 1; + } + + $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const); + if ($stats) { + return array( array( $bestFitExponential->getSlope(), + $bestFitExponential->getSlopeSE(), + $bestFitExponential->getGoodnessOfFit(), + $bestFitExponential->getF(), + $bestFitExponential->getSSRegression(), + ), + array( $bestFitExponential->getIntersect(), + $bestFitExponential->getIntersectSE(), + $bestFitExponential->getStdevOfResiduals(), + $bestFitExponential->getDFResiduals(), + $bestFitExponential->getSSResiduals() + ) + ); + } else { + return array( $bestFitExponential->getSlope(), + $bestFitExponential->getIntersect() + ); + } + } // function LOGEST() + + + /** + * LOGINV + * + * Returns the inverse of the normal cumulative distribution + * + * @param float $probability + * @param float $mean + * @param float $stdDev + * @return float + * + * @todo Try implementing P J Acklam's refinement algorithm for greater + * accuracy if I can get my head round the mathematics + * (as described at) http://home.online.no/~pjacklam/notes/invnorm/ + */ + public static function LOGINV($probability, $mean, $stdDev) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if (($probability < 0) || ($probability > 1) || ($stdDev <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return exp($mean + $stdDev * self::NORMSINV($probability)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function LOGINV() + + + /** + * LOGNORMDIST + * + * Returns the cumulative lognormal distribution of x, where ln(x) is normally distributed + * with parameters mean and standard_dev. + * + * @param float $value + * @param float $mean + * @param float $stdDev + * @return float + */ + public static function LOGNORMDIST($value, $mean, $stdDev) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if (($value <= 0) || ($stdDev <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return self::NORMSDIST((log($value) - $mean) / $stdDev); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function LOGNORMDIST() + + + /** + * MAX + * + * MAX returns the value of the element of the values passed that has the highest value, + * with negative numbers considered smaller than positive numbers. + * + * Excel Function: + * MAX(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MAX() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MAX() + + + /** + * MAXA + * + * Returns the greatest value in a list of arguments, including numbers, text, and logical values + * + * Excel Function: + * MAXA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MAXA() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MAXA() + + + /** + * MAXIF + * + * Counts the maximum value within a range of cells that contain numbers within the list of arguments + * + * Excel Function: + * MAXIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be checked. + * @return float + */ + public static function MAXIF($aArgs,$condition,$sumArgs = array()) { + // Return value + $returnValue = null; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); + if (empty($sumArgs)) { + $sumArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + return $returnValue; + } // function MAXIF() + + + /** + * MEDIAN + * + * Returns the median of the given numbers. The median is the number in the middle of a set of numbers. + * + * Excel Function: + * MEDIAN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MEDIAN() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::NaN(); + + $mArgs = array(); + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + + $mValueCount = count($mArgs); + if ($mValueCount > 0) { + sort($mArgs,SORT_NUMERIC); + $mValueCount = $mValueCount / 2; + if ($mValueCount == floor($mValueCount)) { + $returnValue = ($mArgs[$mValueCount--] + $mArgs[$mValueCount]) / 2; + } else { + $mValueCount == floor($mValueCount); + $returnValue = $mArgs[$mValueCount]; + } + } + + // Return + return $returnValue; + } // function MEDIAN() + + + /** + * MIN + * + * MIN returns the value of the element of the values passed that has the smallest value, + * with negative numbers considered smaller than positive numbers. + * + * Excel Function: + * MIN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MIN() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if ((is_null($returnValue)) || ($arg < $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MIN() + + + /** + * MINA + * + * Returns the smallest value in a list of arguments, including numbers, text, and logical values + * + * Excel Function: + * MINA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MINA() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if ((is_null($returnValue)) || ($arg < $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MINA() + + + /** + * MINIF + * + * Returns the minimum value within a range of cells that contain numbers within the list of arguments + * + * Excel Function: + * MINIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be checked. + * @return float + */ + public static function MINIF($aArgs,$condition,$sumArgs = array()) { + // Return value + $returnValue = null; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); + if (empty($sumArgs)) { + $sumArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + if ((is_null($returnValue)) || ($arg < $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + return $returnValue; + } // function MINIF() + + + // + // Special variant of array_count_values that isn't limited to strings and integers, + // but can work with floating point numbers as values + // + private static function _modeCalc($data) { + $frequencyArray = array(); + foreach($data as $datum) { + $found = False; + foreach($frequencyArray as $key => $value) { + if ((string) $value['value'] == (string) $datum) { + ++$frequencyArray[$key]['frequency']; + $found = True; + break; + } + } + if (!$found) { + $frequencyArray[] = array('value' => $datum, + 'frequency' => 1 ); + } + } + + foreach($frequencyArray as $key => $value) { + $frequencyList[$key] = $value['frequency']; + $valueList[$key] = $value['value']; + } + array_multisort($frequencyList, SORT_DESC, $valueList, SORT_ASC, SORT_NUMERIC, $frequencyArray); + + if ($frequencyArray[0]['frequency'] == 1) { + return PHPExcel_Calculation_Functions::NA(); + } + return $frequencyArray[0]['value']; + } // function _modeCalc() + + + /** + * MODE + * + * Returns the most frequently occurring, or repetitive, value in an array or range of data + * + * Excel Function: + * MODE(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MODE() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::NA(); + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + + if (!empty($mArgs)) { + return self::_modeCalc($mArgs); + } + + // Return + return $returnValue; + } // function MODE() + + + /** + * NEGBINOMDIST + * + * Returns the negative binomial distribution. NEGBINOMDIST returns the probability that + * there will be number_f failures before the number_s-th success, when the constant + * probability of a success is probability_s. This function is similar to the binomial + * distribution, except that the number of successes is fixed, and the number of trials is + * variable. Like the binomial, trials are assumed to be independent. + * + * @param float $failures Number of Failures + * @param float $successes Threshold number of Successes + * @param float $probability Probability of success on each trial + * @return float + * + */ + public static function NEGBINOMDIST($failures, $successes, $probability) { + $failures = floor(PHPExcel_Calculation_Functions::flattenSingleValue($failures)); + $successes = floor(PHPExcel_Calculation_Functions::flattenSingleValue($successes)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + + if ((is_numeric($failures)) && (is_numeric($successes)) && (is_numeric($probability))) { + if (($failures < 0) || ($successes < 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + if (($failures + $successes - 1) <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + } + return (PHPExcel_Calculation_MathTrig::COMBIN($failures + $successes - 1,$successes - 1)) * (pow($probability,$successes)) * (pow(1 - $probability,$failures)) ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function NEGBINOMDIST() + + + /** + * NORMDIST + * + * Returns the normal distribution for the specified mean and standard deviation. This + * function has a very wide range of applications in statistics, including hypothesis + * testing. + * + * @param float $value + * @param float $mean Mean Value + * @param float $stdDev Standard Deviation + * @param boolean $cumulative + * @return float + * + */ + public static function NORMDIST($value, $mean, $stdDev, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if ($stdDev < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return 0.5 * (1 + PHPExcel_Calculation_Engineering::_erfVal(($value - $mean) / ($stdDev * sqrt(2)))); + } else { + return (1 / (SQRT2PI * $stdDev)) * exp(0 - (pow($value - $mean,2) / (2 * ($stdDev * $stdDev)))); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function NORMDIST() + + + /** + * NORMINV + * + * Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation. + * + * @param float $value + * @param float $mean Mean Value + * @param float $stdDev Standard Deviation + * @return float + * + */ + public static function NORMINV($probability,$mean,$stdDev) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($stdDev < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return (self::_inverse_ncdf($probability) * $stdDev) + $mean; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function NORMINV() + + + /** + * NORMSDIST + * + * Returns the standard normal cumulative distribution function. The distribution has + * a mean of 0 (zero) and a standard deviation of one. Use this function in place of a + * table of standard normal curve areas. + * + * @param float $value + * @return float + */ + public static function NORMSDIST($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + return self::NORMDIST($value, 0, 1, True); + } // function NORMSDIST() + + + /** + * NORMSINV + * + * Returns the inverse of the standard normal cumulative distribution + * + * @param float $value + * @return float + */ + public static function NORMSINV($value) { + return self::NORMINV($value, 0, 1); + } // function NORMSINV() + + + /** + * PERCENTILE + * + * Returns the nth percentile of values in a range.. + * + * Excel Function: + * PERCENTILE(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param float $entry Percentile value in the range 0..1, inclusive. + * @return float + */ + public static function PERCENTILE() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = array_pop($aArgs); + + if ((is_numeric($entry)) && (!is_string($entry))) { + if (($entry < 0) || ($entry > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $mValueCount = count($mArgs); + if ($mValueCount > 0) { + sort($mArgs); + $count = self::COUNT($mArgs); + $index = $entry * ($count-1); + $iBase = floor($index); + if ($index == $iBase) { + return $mArgs[$index]; + } else { + $iNext = $iBase + 1; + $iProportion = $index - $iBase; + return $mArgs[$iBase] + (($mArgs[$iNext] - $mArgs[$iBase]) * $iProportion) ; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PERCENTILE() + + + /** + * PERCENTRANK + * + * Returns the rank of a value in a data set as a percentage of the data set. + * + * @param array of number An array of, or a reference to, a list of numbers. + * @param number The number whose rank you want to find. + * @param number The number of significant digits for the returned percentage value. + * @return float + */ + public static function PERCENTRANK($valueSet,$value,$significance=3) { + $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $significance = (is_null($significance)) ? 3 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($significance); + + foreach($valueSet as $key => $valueEntry) { + if (!is_numeric($valueEntry)) { + unset($valueSet[$key]); + } + } + sort($valueSet,SORT_NUMERIC); + $valueCount = count($valueSet); + if ($valueCount == 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $valueAdjustor = $valueCount - 1; + if (($value < $valueSet[0]) || ($value > $valueSet[$valueAdjustor])) { + return PHPExcel_Calculation_Functions::NA(); + } + + $pos = array_search($value,$valueSet); + if ($pos === False) { + $pos = 0; + $testValue = $valueSet[0]; + while ($testValue < $value) { + $testValue = $valueSet[++$pos]; + } + --$pos; + $pos += (($value - $valueSet[$pos]) / ($testValue - $valueSet[$pos])); + } + + return round($pos / $valueAdjustor,$significance); + } // function PERCENTRANK() + + + /** + * PERMUT + * + * Returns the number of permutations for a given number of objects that can be + * selected from number objects. A permutation is any set or subset of objects or + * events where internal order is significant. Permutations are different from + * combinations, for which the internal order is not significant. Use this function + * for lottery-style probability calculations. + * + * @param int $numObjs Number of different objects + * @param int $numInSet Number of objects in each permutation + * @return int Number of permutations + */ + public static function PERMUT($numObjs,$numInSet) { + $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); + $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); + + if ((is_numeric($numObjs)) && (is_numeric($numInSet))) { + $numInSet = floor($numInSet); + if ($numObjs < $numInSet) { + return PHPExcel_Calculation_Functions::NaN(); + } + return round(PHPExcel_Calculation_MathTrig::FACT($numObjs) / PHPExcel_Calculation_MathTrig::FACT($numObjs - $numInSet)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PERMUT() + + + /** + * POISSON + * + * Returns the Poisson distribution. A common application of the Poisson distribution + * is predicting the number of events over a specific time, such as the number of + * cars arriving at a toll plaza in 1 minute. + * + * @param float $value + * @param float $mean Mean Value + * @param boolean $cumulative + * @return float + * + */ + public static function POISSON($value, $mean, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + + if ((is_numeric($value)) && (is_numeric($mean))) { + if (($value < 0) || ($mean <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + $summer = 0; + for ($i = 0; $i <= floor($value); ++$i) { + $summer += pow($mean,$i) / PHPExcel_Calculation_MathTrig::FACT($i); + } + return exp(0-$mean) * $summer; + } else { + return (exp(0-$mean) * pow($mean,$value)) / PHPExcel_Calculation_MathTrig::FACT($value); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function POISSON() + + + /** + * QUARTILE + * + * Returns the quartile of a data set. + * + * Excel Function: + * QUARTILE(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param int $entry Quartile value in the range 1..3, inclusive. + * @return float + */ + public static function QUARTILE() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = floor(array_pop($aArgs)); + + if ((is_numeric($entry)) && (!is_string($entry))) { + $entry /= 4; + if (($entry < 0) || ($entry > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return self::PERCENTILE($aArgs,$entry); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function QUARTILE() + + + /** + * RANK + * + * Returns the rank of a number in a list of numbers. + * + * @param number The number whose rank you want to find. + * @param array of number An array of, or a reference to, a list of numbers. + * @param mixed Order to sort the values in the value set + * @return float + */ + public static function RANK($value,$valueSet,$order=0) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); + $order = (is_null($order)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($order); + + foreach($valueSet as $key => $valueEntry) { + if (!is_numeric($valueEntry)) { + unset($valueSet[$key]); + } + } + + if ($order == 0) { + rsort($valueSet,SORT_NUMERIC); + } else { + sort($valueSet,SORT_NUMERIC); + } + $pos = array_search($value,$valueSet); + if ($pos === False) { + return PHPExcel_Calculation_Functions::NA(); + } + + return ++$pos; + } // function RANK() + + + /** + * RSQ + * + * Returns the square of the Pearson product moment correlation coefficient through data points in known_y's and known_x's. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function RSQ($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getGoodnessOfFit(); + } // function RSQ() + + + /** + * SKEW + * + * Returns the skewness of a distribution. Skewness characterizes the degree of asymmetry + * of a distribution around its mean. Positive skewness indicates a distribution with an + * asymmetric tail extending toward more positive values. Negative skewness indicates a + * distribution with an asymmetric tail extending toward more negative values. + * + * @param array Data Series + * @return float + */ + public static function SKEW() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $mean = self::AVERAGE($aArgs); + $stdDev = self::STDEV($aArgs); + + $count = $summer = 0; + // Loop through arguments + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summer += pow((($arg - $mean) / $stdDev),3) ; + ++$count; + } + } + } + + // Return + if ($count > 2) { + return $summer * ($count / (($count-1) * ($count-2))); + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function SKEW() + + + /** + * SLOPE + * + * Returns the slope of the linear regression line through data points in known_y's and known_x's. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function SLOPE($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getSlope(); + } // function SLOPE() + + + /** + * SMALL + * + * Returns the nth smallest value in a data set. You can use this function to + * select a value based on its relative standing. + * + * Excel Function: + * SMALL(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param int $entry Position (ordered from the smallest) in the array or range of data to return + * @return float + */ + public static function SMALL() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = array_pop($aArgs); + + if ((is_numeric($entry)) && (!is_string($entry))) { + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $count = self::COUNT($mArgs); + $entry = floor(--$entry); + if (($entry < 0) || ($entry >= $count) || ($count == 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + sort($mArgs); + return $mArgs[$entry]; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SMALL() + + + /** + * STANDARDIZE + * + * Returns a normalized value from a distribution characterized by mean and standard_dev. + * + * @param float $value Value to normalize + * @param float $mean Mean Value + * @param float $stdDev Standard Deviation + * @return float Standardized value + */ + public static function STANDARDIZE($value,$mean,$stdDev) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if ($stdDev <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return ($value - $mean) / $stdDev ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function STANDARDIZE() + + + /** + * STDEV + * + * Estimates standard deviation based on a sample. The standard deviation is a measure of how + * widely values are dispersed from the average value (the mean). + * + * Excel Function: + * STDEV(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEV() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if (!is_null($aMean)) { + $aCount = -1; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEV() + + + /** + * STDEVA + * + * Estimates standard deviation based on a sample, including numbers, text, and logical values + * + * Excel Function: + * STDEVA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEVA() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGEA($aArgs); + if (!is_null($aMean)) { + $aCount = -1; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEVA() + + + /** + * STDEVP + * + * Calculates standard deviation based on the entire population + * + * Excel Function: + * STDEVP(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEVP() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if (!is_null($aMean)) { + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEVP() + + + /** + * STDEVPA + * + * Calculates standard deviation based on the entire population, including numbers, text, and logical values + * + * Excel Function: + * STDEVPA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEVPA() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGEA($aArgs); + if (!is_null($aMean)) { + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEVPA() + + + /** + * STEYX + * + * Returns the standard error of the predicted y-value for each x in the regression. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function STEYX($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getStdevOfResiduals(); + } // function STEYX() + + + /** + * TDIST + * + * Returns the probability of Student's T distribution. + * + * @param float $value Value for the function + * @param float $degrees degrees of freedom + * @param float $tails number of tails (1 or 2) + * @return float + */ + public static function TDIST($value, $degrees, $tails) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + $tails = floor(PHPExcel_Calculation_Functions::flattenSingleValue($tails)); + + if ((is_numeric($value)) && (is_numeric($degrees)) && (is_numeric($tails))) { + if (($value < 0) || ($degrees < 1) || ($tails < 1) || ($tails > 2)) { + return PHPExcel_Calculation_Functions::NaN(); + } + // tdist, which finds the probability that corresponds to a given value + // of t with k degrees of freedom. This algorithm is translated from a + // pascal function on p81 of "Statistical Computing in Pascal" by D + // Cooke, A H Craven & G M Clark (1985: Edward Arnold (Pubs.) Ltd: + // London). The above Pascal algorithm is itself a translation of the + // fortran algoritm "AS 3" by B E Cooper of the Atlas Computer + // Laboratory as reported in (among other places) "Applied Statistics + // Algorithms", editied by P Griffiths and I D Hill (1985; Ellis + // Horwood Ltd.; W. Sussex, England). + $tterm = $degrees; + $ttheta = atan2($value,sqrt($tterm)); + $tc = cos($ttheta); + $ts = sin($ttheta); + $tsum = 0; + + if (($degrees % 2) == 1) { + $ti = 3; + $tterm = $tc; + } else { + $ti = 2; + $tterm = 1; + } + + $tsum = $tterm; + while ($ti < $degrees) { + $tterm *= $tc * $tc * ($ti - 1) / $ti; + $tsum += $tterm; + $ti += 2; + } + $tsum *= $ts; + if (($degrees % 2) == 1) { $tsum = M_2DIVPI * ($tsum + $ttheta); } + $tValue = 0.5 * (1 + $tsum); + if ($tails == 1) { + return 1 - abs($tValue); + } else { + return 1 - abs((1 - $tValue) - $tValue); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TDIST() + + + /** + * TINV + * + * Returns the one-tailed probability of the chi-squared distribution. + * + * @param float $probability Probability for the function + * @param float $degrees degrees of freedom + * @return float + */ + public static function TINV($probability, $degrees) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + + if ((is_numeric($probability)) && (is_numeric($degrees))) { + $xLo = 100; + $xHi = 0; + + $x = $xNew = 1; + $dx = 1; + $i = 0; + + while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + // Apply Newton-Raphson step + $result = self::TDIST($x, $degrees, 2); + $error = $result - $probability; + if ($error == 0.0) { + $dx = 0; + } elseif ($error < 0.0) { + $xLo = $x; + } else { + $xHi = $x; + } + // Avoid division by zero + if ($result != 0.0) { + $dx = $error / $result; + $xNew = $x - $dx; + } + // If the NR fails to converge (which for example may be the + // case if the initial guess is too rough) we apply a bisection + // step to determine a more narrow interval around the root. + if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) { + $xNew = ($xLo + $xHi) / 2; + $dx = $xNew - $x; + } + $x = $xNew; + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return round($x,12); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TINV() + + + /** + * TREND + * + * Returns values along a linear trend + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param array of mixed Values of X for which we want to find Y + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @return array of float + */ + public static function TREND($yValues,$xValues=array(),$newValues=array(),$const=True) { + $yValues = PHPExcel_Calculation_Functions::flattenArray($yValues); + $xValues = PHPExcel_Calculation_Functions::flattenArray($xValues); + $newValues = PHPExcel_Calculation_Functions::flattenArray($newValues); + $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const); + if (empty($newValues)) { + $newValues = $bestFitLinear->getXValues(); + } + + $returnArray = array(); + foreach($newValues as $xValue) { + $returnArray[0][] = $bestFitLinear->getValueOfYForX($xValue); + } + + return $returnArray; + } // function TREND() + + + /** + * TRIMMEAN + * + * Returns the mean of the interior of a data set. TRIMMEAN calculates the mean + * taken by excluding a percentage of data points from the top and bottom tails + * of a data set. + * + * Excel Function: + * TRIMEAN(value1[,value2[, ...]],$discard) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param float $discard Percentage to discard + * @return float + */ + public static function TRIMMEAN() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $percent = array_pop($aArgs); + + if ((is_numeric($percent)) && (!is_string($percent))) { + if (($percent < 0) || ($percent > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $discard = floor(self::COUNT($mArgs) * $percent / 2); + sort($mArgs); + for ($i=0; $i < $discard; ++$i) { + array_pop($mArgs); + array_shift($mArgs); + } + return self::AVERAGE($mArgs); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TRIMMEAN() + + + /** + * VARFunc + * + * Estimates variance based on a sample. + * + * Excel Function: + * VAR(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARFunc() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $aCount = 0; + foreach ($aArgs as $arg) { + if (is_bool($arg)) { $arg = (integer) $arg; } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + + // Return + if ($aCount > 1) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1)); + } + return $returnValue; + } // function VARFunc() + + + /** + * VARA + * + * Estimates variance based on a sample, including numbers, text, and logical values + * + * Excel Function: + * VARA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARA() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_string($arg)) && + (PHPExcel_Calculation_Functions::isValue($k))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ((is_string($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + } + + // Return + if ($aCount > 1) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1)); + } + return $returnValue; + } // function VARA() + + + /** + * VARP + * + * Calculates variance based on the entire population + * + * Excel Function: + * VARP(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARP() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $aCount = 0; + foreach ($aArgs as $arg) { + if (is_bool($arg)) { $arg = (integer) $arg; } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + + // Return + if ($aCount > 0) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * $aCount); + } + return $returnValue; + } // function VARP() + + + /** + * VARPA + * + * Calculates variance based on the entire population, including numbers, text, and logical values + * + * Excel Function: + * VARPA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARPA() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_string($arg)) && + (PHPExcel_Calculation_Functions::isValue($k))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ((is_string($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + } + + // Return + if ($aCount > 0) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * $aCount); + } + return $returnValue; + } // function VARPA() + + + /** + * WEIBULL + * + * Returns the Weibull distribution. Use this distribution in reliability + * analysis, such as calculating a device's mean time to failure. + * + * @param float $value + * @param float $alpha Alpha Parameter + * @param float $beta Beta Parameter + * @param boolean $cumulative + * @return float + * + */ + public static function WEIBULL($value, $alpha, $beta, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + + if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta))) { + if (($value < 0) || ($alpha <= 0) || ($beta <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return 1 - exp(0 - pow($value / $beta,$alpha)); + } else { + return ($alpha / pow($beta,$alpha)) * pow($value,$alpha - 1) * exp(0 - pow($value / $beta,$alpha)); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function WEIBULL() + + + /** + * ZTEST + * + * Returns the Weibull distribution. Use this distribution in reliability + * analysis, such as calculating a device's mean time to failure. + * + * @param float $dataSet + * @param float $m0 Alpha Parameter + * @param float $sigma Beta Parameter + * @param boolean $cumulative + * @return float + * + */ + public static function ZTEST($dataSet, $m0, $sigma = NULL) { + $dataSet = PHPExcel_Calculation_Functions::flattenArrayIndexed($dataSet); + $m0 = PHPExcel_Calculation_Functions::flattenSingleValue($m0); + $sigma = PHPExcel_Calculation_Functions::flattenSingleValue($sigma); + + if (is_null($sigma)) { + $sigma = self::STDEV($dataSet); + } + $n = count($dataSet); + + return 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0)/($sigma/SQRT($n))); + } // function ZTEST() + +} // class PHPExcel_Calculation_Statistical diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php index 8c7c05f0d..0a5e9f9f4 100644 --- a/Classes/PHPExcel/Calculation/TextData.php +++ b/Classes/PHPExcel/Calculation/TextData.php @@ -18,584 +18,584 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** * PHPExcel_Calculation_TextData * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation_TextData { - private static $_invalidChars = Null; - - private static function _uniord($c) { - if (ord($c{0}) >=0 && ord($c{0}) <= 127) - return ord($c{0}); - if (ord($c{0}) >= 192 && ord($c{0}) <= 223) - return (ord($c{0})-192)*64 + (ord($c{1})-128); - if (ord($c{0}) >= 224 && ord($c{0}) <= 239) - return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128); - if (ord($c{0}) >= 240 && ord($c{0}) <= 247) - return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128); - if (ord($c{0}) >= 248 && ord($c{0}) <= 251) - return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128); - if (ord($c{0}) >= 252 && ord($c{0}) <= 253) - return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128); - if (ord($c{0}) >= 254 && ord($c{0}) <= 255) //error - return PHPExcel_Calculation_Functions::VALUE(); - return 0; - } // function _uniord() - - /** - * CHARACTER - * - * @param string $character Value - * @return int - */ - public static function CHARACTER($character) { - $character = PHPExcel_Calculation_Functions::flattenSingleValue($character); - - if ((!is_numeric($character)) || ($character < 0)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (function_exists('mb_convert_encoding')) { - return mb_convert_encoding('&#'.intval($character).';', 'UTF-8', 'HTML-ENTITIES'); - } else { - return chr(intval($character)); - } - } - - - /** - * TRIMNONPRINTABLE - * - * @param mixed $stringValue Value to check - * @return string - */ - public static function TRIMNONPRINTABLE($stringValue = '') { - $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); - - if (is_bool($stringValue)) { - return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - if (self::$_invalidChars == Null) { - self::$_invalidChars = range(chr(0),chr(31)); - } - - if (is_string($stringValue) || is_numeric($stringValue)) { - return str_replace(self::$_invalidChars, '', trim($stringValue, "\x00..\x1F")); - } - return NULL; - } // function TRIMNONPRINTABLE() - - - /** - * TRIMSPACES - * - * @param mixed $stringValue Value to check - * @return string - */ - public static function TRIMSPACES($stringValue = '') { - $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); - if (is_bool($stringValue)) { - return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - if (is_string($stringValue) || is_numeric($stringValue)) { - return trim(preg_replace('/ +/',' ',trim($stringValue, ' ')), ' '); - } - return NULL; - } // function TRIMSPACES() - - - /** - * ASCIICODE - * - * @param string $characters Value - * @return int - */ - public static function ASCIICODE($characters) { - if (($characters === NULL) || ($characters === '')) - return PHPExcel_Calculation_Functions::VALUE(); - $characters = PHPExcel_Calculation_Functions::flattenSingleValue($characters); - if (is_bool($characters)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - $characters = (int) $characters; - } else { - $characters = ($characters) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - } - - $character = $characters; - if ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) { - if (mb_strlen($characters, 'UTF-8') > 1) { $character = mb_substr($characters, 0, 1, 'UTF-8'); } - return self::_uniord($character); - } else { - if (strlen($characters) > 0) { $character = substr($characters, 0, 1); } - return ord($character); - } - } // function ASCIICODE() - - - /** - * CONCATENATE - * - * @return string - */ - public static function CONCATENATE() { - // Return value - $returnValue = ''; - - // Loop through arguments - $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); - foreach ($aArgs as $arg) { - if (is_bool($arg)) { - if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { - $arg = (int) $arg; - } else { - $arg = ($arg) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - } - $returnValue .= $arg; - } - - // Return - return $returnValue; - } // function CONCATENATE() - - - /** - * DOLLAR - * - * This function converts a number to text using currency format, with the decimals rounded to the specified place. - * The format used is $#,##0.00_);($#,##0.00).. - * - * @param float $value The value to format - * @param int $decimals The number of digits to display to the right of the decimal point. - * If decimals is negative, number is rounded to the left of the decimal point. - * If you omit decimals, it is assumed to be 2 - * @return string - */ - public static function DOLLAR($value = 0, $decimals = 2) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $decimals = is_null($decimals) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($decimals); - - // Validate parameters - if (!is_numeric($value) || !is_numeric($decimals)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $decimals = floor($decimals); - - $mask = '$#,##0'; - if ($decimals > 0) { - $mask .= '.' . str_repeat('0',$decimals); - } else { - $round = pow(10,abs($decimals)); - if ($value < 0) { $round = 0-$round; } - $value = PHPExcel_Calculation_MathTrig::MROUND($value, $round); - } - - return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask); - - } // function DOLLAR() - - - /** - * SEARCHSENSITIVE - * - * @param string $needle The string to look for - * @param string $haystack The string in which to look - * @param int $offset Offset within $haystack - * @return string - */ - public static function SEARCHSENSITIVE($needle,$haystack,$offset=1) { - $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); - $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); - $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); - - if (!is_bool($needle)) { - if (is_bool($haystack)) { - $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { - if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { - return $offset; - } - if (function_exists('mb_strpos')) { - $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8'); - } else { - $pos = strpos($haystack, $needle, --$offset); - } - if ($pos !== false) { - return ++$pos; - } - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function SEARCHSENSITIVE() - - - /** - * SEARCHINSENSITIVE - * - * @param string $needle The string to look for - * @param string $haystack The string in which to look - * @param int $offset Offset within $haystack - * @return string - */ - public static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) { - $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); - $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); - $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); - - if (!is_bool($needle)) { - if (is_bool($haystack)) { - $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { - if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { - return $offset; - } - if (function_exists('mb_stripos')) { - $pos = mb_stripos($haystack, $needle, --$offset,'UTF-8'); - } else { - $pos = stripos($haystack, $needle, --$offset); - } - if ($pos !== false) { - return ++$pos; - } - } - } - return PHPExcel_Calculation_Functions::VALUE(); - } // function SEARCHINSENSITIVE() - - - /** - * FIXEDFORMAT - * - * @param mixed $value Value to check - * @param integer $decimals - * @param boolean $no_commas - * @return boolean - */ - public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = FALSE) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $decimals = PHPExcel_Calculation_Functions::flattenSingleValue($decimals); - $no_commas = PHPExcel_Calculation_Functions::flattenSingleValue($no_commas); - - // Validate parameters - if (!is_numeric($value) || !is_numeric($decimals)) { - return PHPExcel_Calculation_Functions::NaN(); - } - $decimals = floor($decimals); - - $valueResult = round($value,$decimals); - if ($decimals < 0) { $decimals = 0; } - if (!$no_commas) { - $valueResult = number_format($valueResult,$decimals); - } - - return (string) $valueResult; - } // function FIXEDFORMAT() - - - /** - * LEFT - * - * @param string $value Value - * @param int $chars Number of characters - * @return string - */ - public static function LEFT($value = '', $chars = 1) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); - - if ($chars < 0) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (is_bool($value)) { - $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - if (function_exists('mb_substr')) { - return mb_substr($value, 0, $chars, 'UTF-8'); - } else { - return substr($value, 0, $chars); - } - } // function LEFT() - - - /** - * MID - * - * @param string $value Value - * @param int $start Start character - * @param int $chars Number of characters - * @return string - */ - public static function MID($value = '', $start = 1, $chars = null) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); - $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); - - if (($start < 1) || ($chars < 0)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (is_bool($value)) { - $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - if (function_exists('mb_substr')) { - return mb_substr($value, --$start, $chars, 'UTF-8'); - } else { - return substr($value, --$start, $chars); - } - } // function MID() - - - /** - * RIGHT - * - * @param string $value Value - * @param int $chars Number of characters - * @return string - */ - public static function RIGHT($value = '', $chars = 1) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); - - if ($chars < 0) { - return PHPExcel_Calculation_Functions::VALUE(); - } - - if (is_bool($value)) { - $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - if ((function_exists('mb_substr')) && (function_exists('mb_strlen'))) { - return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8'); - } else { - return substr($value, strlen($value) - $chars); - } - } // function RIGHT() - - - /** - * STRINGLENGTH - * - * @param string $value Value - * @return string - */ - public static function STRINGLENGTH($value = '') { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - - if (is_bool($value)) { - $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - if (function_exists('mb_strlen')) { - return mb_strlen($value, 'UTF-8'); - } else { - return strlen($value); - } - } // function STRINGLENGTH() - - - /** - * LOWERCASE - * - * Converts a string value to upper case. - * - * @param string $mixedCaseString - * @return string - */ - public static function LOWERCASE($mixedCaseString) { - $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); - - if (is_bool($mixedCaseString)) { - $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - return PHPExcel_Shared_String::StrToLower($mixedCaseString); - } // function LOWERCASE() - - - /** - * UPPERCASE - * - * Converts a string value to upper case. - * - * @param string $mixedCaseString - * @return string - */ - public static function UPPERCASE($mixedCaseString) { - $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); - - if (is_bool($mixedCaseString)) { - $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - return PHPExcel_Shared_String::StrToUpper($mixedCaseString); - } // function UPPERCASE() - - - /** - * PROPERCASE - * - * Converts a string value to upper case. - * - * @param string $mixedCaseString - * @return string - */ - public static function PROPERCASE($mixedCaseString) { - $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); - - if (is_bool($mixedCaseString)) { - $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); - } - - return PHPExcel_Shared_String::StrToTitle($mixedCaseString); - } // function PROPERCASE() - - - /** - * REPLACE - * - * @param string $oldText String to modify - * @param int $start Start character - * @param int $chars Number of characters - * @param string $newText String to replace in defined position - * @return string - */ - public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) { - $oldText = PHPExcel_Calculation_Functions::flattenSingleValue($oldText); - $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); - $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); - $newText = PHPExcel_Calculation_Functions::flattenSingleValue($newText); - - $left = self::LEFT($oldText,$start-1); - $right = self::RIGHT($oldText,self::STRINGLENGTH($oldText)-($start+$chars)+1); - - return $left.$newText.$right; - } // function REPLACE() - - - /** - * SUBSTITUTE - * - * @param string $text Value - * @param string $fromText From Value - * @param string $toText To Value - * @param integer $instance Instance Number - * @return string - */ - public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0) { - $text = PHPExcel_Calculation_Functions::flattenSingleValue($text); - $fromText = PHPExcel_Calculation_Functions::flattenSingleValue($fromText); - $toText = PHPExcel_Calculation_Functions::flattenSingleValue($toText); - $instance = floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance)); - - if ($instance == 0) { - if(function_exists('mb_str_replace')) { - return mb_str_replace($fromText,$toText,$text); - } else { - return str_replace($fromText,$toText,$text); - } - } else { - $pos = -1; - while($instance > 0) { - if (function_exists('mb_strpos')) { - $pos = mb_strpos($text, $fromText, $pos+1, 'UTF-8'); - } else { - $pos = strpos($text, $fromText, $pos+1); - } - if ($pos === false) { - break; - } - --$instance; - } - if ($pos !== false) { - if (function_exists('mb_strlen')) { - return self::REPLACE($text,++$pos,mb_strlen($fromText, 'UTF-8'),$toText); - } else { - return self::REPLACE($text,++$pos,strlen($fromText),$toText); - } - } - } - - return $text; - } // function SUBSTITUTE() - - - /** - * RETURNSTRING - * - * @param mixed $testValue Value to check - * @return boolean - */ - public static function RETURNSTRING($testValue = '') { - $testValue = PHPExcel_Calculation_Functions::flattenSingleValue($testValue); - - if (is_string($testValue)) { - return $testValue; - } - return Null; - } // function RETURNSTRING() - - - /** - * TEXTFORMAT - * - * @param mixed $value Value to check - * @param string $format Format mask to use - * @return boolean - */ - public static function TEXTFORMAT($value,$format) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $format = PHPExcel_Calculation_Functions::flattenSingleValue($format); - - if ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date::isDateTimeFormatCode($format)) { - $value = PHPExcel_Calculation_DateTime::DATEVALUE($value); - } - - return (string) PHPExcel_Style_NumberFormat::toFormattedString($value,$format); - } // function TEXTFORMAT() - - /** - * VALUE - * - * @param mixed $value Value to check - * @return boolean - */ - public static function VALUE($value = '') { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - - if (!is_numeric($value)) { + private static $_invalidChars = Null; + + private static function _uniord($c) { + if (ord($c{0}) >=0 && ord($c{0}) <= 127) + return ord($c{0}); + if (ord($c{0}) >= 192 && ord($c{0}) <= 223) + return (ord($c{0})-192)*64 + (ord($c{1})-128); + if (ord($c{0}) >= 224 && ord($c{0}) <= 239) + return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128); + if (ord($c{0}) >= 240 && ord($c{0}) <= 247) + return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128); + if (ord($c{0}) >= 248 && ord($c{0}) <= 251) + return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128); + if (ord($c{0}) >= 252 && ord($c{0}) <= 253) + return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128); + if (ord($c{0}) >= 254 && ord($c{0}) <= 255) //error + return PHPExcel_Calculation_Functions::VALUE(); + return 0; + } // function _uniord() + + /** + * CHARACTER + * + * @param string $character Value + * @return int + */ + public static function CHARACTER($character) { + $character = PHPExcel_Calculation_Functions::flattenSingleValue($character); + + if ((!is_numeric($character)) || ($character < 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (function_exists('mb_convert_encoding')) { + return mb_convert_encoding('&#'.intval($character).';', 'UTF-8', 'HTML-ENTITIES'); + } else { + return chr(intval($character)); + } + } + + + /** + * TRIMNONPRINTABLE + * + * @param mixed $stringValue Value to check + * @return string + */ + public static function TRIMNONPRINTABLE($stringValue = '') { + $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); + + if (is_bool($stringValue)) { + return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (self::$_invalidChars == Null) { + self::$_invalidChars = range(chr(0),chr(31)); + } + + if (is_string($stringValue) || is_numeric($stringValue)) { + return str_replace(self::$_invalidChars, '', trim($stringValue, "\x00..\x1F")); + } + return NULL; + } // function TRIMNONPRINTABLE() + + + /** + * TRIMSPACES + * + * @param mixed $stringValue Value to check + * @return string + */ + public static function TRIMSPACES($stringValue = '') { + $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); + if (is_bool($stringValue)) { + return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (is_string($stringValue) || is_numeric($stringValue)) { + return trim(preg_replace('/ +/',' ',trim($stringValue, ' ')), ' '); + } + return NULL; + } // function TRIMSPACES() + + + /** + * ASCIICODE + * + * @param string $characters Value + * @return int + */ + public static function ASCIICODE($characters) { + if (($characters === NULL) || ($characters === '')) + return PHPExcel_Calculation_Functions::VALUE(); + $characters = PHPExcel_Calculation_Functions::flattenSingleValue($characters); + if (is_bool($characters)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $characters = (int) $characters; + } else { + $characters = ($characters) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + } + + $character = $characters; + if ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) { + if (mb_strlen($characters, 'UTF-8') > 1) { $character = mb_substr($characters, 0, 1, 'UTF-8'); } + return self::_uniord($character); + } else { + if (strlen($characters) > 0) { $character = substr($characters, 0, 1); } + return ord($character); + } + } // function ASCIICODE() + + + /** + * CONCATENATE + * + * @return string + */ + public static function CONCATENATE() { + // Return value + $returnValue = ''; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + if (is_bool($arg)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $arg = (int) $arg; + } else { + $arg = ($arg) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + } + $returnValue .= $arg; + } + + // Return + return $returnValue; + } // function CONCATENATE() + + + /** + * DOLLAR + * + * This function converts a number to text using currency format, with the decimals rounded to the specified place. + * The format used is $#,##0.00_);($#,##0.00).. + * + * @param float $value The value to format + * @param int $decimals The number of digits to display to the right of the decimal point. + * If decimals is negative, number is rounded to the left of the decimal point. + * If you omit decimals, it is assumed to be 2 + * @return string + */ + public static function DOLLAR($value = 0, $decimals = 2) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $decimals = is_null($decimals) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($decimals); + + // Validate parameters + if (!is_numeric($value) || !is_numeric($decimals)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $decimals = floor($decimals); + + $mask = '$#,##0'; + if ($decimals > 0) { + $mask .= '.' . str_repeat('0',$decimals); + } else { + $round = pow(10,abs($decimals)); + if ($value < 0) { $round = 0-$round; } + $value = PHPExcel_Calculation_MathTrig::MROUND($value, $round); + } + + return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask); + + } // function DOLLAR() + + + /** + * SEARCHSENSITIVE + * + * @param string $needle The string to look for + * @param string $haystack The string in which to look + * @param int $offset Offset within $haystack + * @return string + */ + public static function SEARCHSENSITIVE($needle,$haystack,$offset=1) { + $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); + $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); + $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); + + if (!is_bool($needle)) { + if (is_bool($haystack)) { + $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { + if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { + return $offset; + } + if (function_exists('mb_strpos')) { + $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8'); + } else { + $pos = strpos($haystack, $needle, --$offset); + } + if ($pos !== false) { + return ++$pos; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SEARCHSENSITIVE() + + + /** + * SEARCHINSENSITIVE + * + * @param string $needle The string to look for + * @param string $haystack The string in which to look + * @param int $offset Offset within $haystack + * @return string + */ + public static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) { + $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); + $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); + $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); + + if (!is_bool($needle)) { + if (is_bool($haystack)) { + $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { + if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { + return $offset; + } + if (function_exists('mb_stripos')) { + $pos = mb_stripos($haystack, $needle, --$offset,'UTF-8'); + } else { + $pos = stripos($haystack, $needle, --$offset); + } + if ($pos !== false) { + return ++$pos; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SEARCHINSENSITIVE() + + + /** + * FIXEDFORMAT + * + * @param mixed $value Value to check + * @param integer $decimals + * @param boolean $no_commas + * @return boolean + */ + public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = FALSE) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $decimals = PHPExcel_Calculation_Functions::flattenSingleValue($decimals); + $no_commas = PHPExcel_Calculation_Functions::flattenSingleValue($no_commas); + + // Validate parameters + if (!is_numeric($value) || !is_numeric($decimals)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $decimals = floor($decimals); + + $valueResult = round($value,$decimals); + if ($decimals < 0) { $decimals = 0; } + if (!$no_commas) { + $valueResult = number_format($valueResult,$decimals); + } + + return (string) $valueResult; + } // function FIXEDFORMAT() + + + /** + * LEFT + * + * @param string $value Value + * @param int $chars Number of characters + * @return string + */ + public static function LEFT($value = '', $chars = 1) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + + if ($chars < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (function_exists('mb_substr')) { + return mb_substr($value, 0, $chars, 'UTF-8'); + } else { + return substr($value, 0, $chars); + } + } // function LEFT() + + + /** + * MID + * + * @param string $value Value + * @param int $start Start character + * @param int $chars Number of characters + * @return string + */ + public static function MID($value = '', $start = 1, $chars = null) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + + if (($start < 1) || ($chars < 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (function_exists('mb_substr')) { + return mb_substr($value, --$start, $chars, 'UTF-8'); + } else { + return substr($value, --$start, $chars); + } + } // function MID() + + + /** + * RIGHT + * + * @param string $value Value + * @param int $chars Number of characters + * @return string + */ + public static function RIGHT($value = '', $chars = 1) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + + if ($chars < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if ((function_exists('mb_substr')) && (function_exists('mb_strlen'))) { + return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8'); + } else { + return substr($value, strlen($value) - $chars); + } + } // function RIGHT() + + + /** + * STRINGLENGTH + * + * @param string $value Value + * @return string + */ + public static function STRINGLENGTH($value = '') { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (function_exists('mb_strlen')) { + return mb_strlen($value, 'UTF-8'); + } else { + return strlen($value); + } + } // function STRINGLENGTH() + + + /** + * LOWERCASE + * + * Converts a string value to upper case. + * + * @param string $mixedCaseString + * @return string + */ + public static function LOWERCASE($mixedCaseString) { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + + if (is_bool($mixedCaseString)) { + $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + return PHPExcel_Shared_String::StrToLower($mixedCaseString); + } // function LOWERCASE() + + + /** + * UPPERCASE + * + * Converts a string value to upper case. + * + * @param string $mixedCaseString + * @return string + */ + public static function UPPERCASE($mixedCaseString) { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + + if (is_bool($mixedCaseString)) { + $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + return PHPExcel_Shared_String::StrToUpper($mixedCaseString); + } // function UPPERCASE() + + + /** + * PROPERCASE + * + * Converts a string value to upper case. + * + * @param string $mixedCaseString + * @return string + */ + public static function PROPERCASE($mixedCaseString) { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + + if (is_bool($mixedCaseString)) { + $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + return PHPExcel_Shared_String::StrToTitle($mixedCaseString); + } // function PROPERCASE() + + + /** + * REPLACE + * + * @param string $oldText String to modify + * @param int $start Start character + * @param int $chars Number of characters + * @param string $newText String to replace in defined position + * @return string + */ + public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) { + $oldText = PHPExcel_Calculation_Functions::flattenSingleValue($oldText); + $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + $newText = PHPExcel_Calculation_Functions::flattenSingleValue($newText); + + $left = self::LEFT($oldText,$start-1); + $right = self::RIGHT($oldText,self::STRINGLENGTH($oldText)-($start+$chars)+1); + + return $left.$newText.$right; + } // function REPLACE() + + + /** + * SUBSTITUTE + * + * @param string $text Value + * @param string $fromText From Value + * @param string $toText To Value + * @param integer $instance Instance Number + * @return string + */ + public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0) { + $text = PHPExcel_Calculation_Functions::flattenSingleValue($text); + $fromText = PHPExcel_Calculation_Functions::flattenSingleValue($fromText); + $toText = PHPExcel_Calculation_Functions::flattenSingleValue($toText); + $instance = floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance)); + + if ($instance == 0) { + if(function_exists('mb_str_replace')) { + return mb_str_replace($fromText,$toText,$text); + } else { + return str_replace($fromText,$toText,$text); + } + } else { + $pos = -1; + while($instance > 0) { + if (function_exists('mb_strpos')) { + $pos = mb_strpos($text, $fromText, $pos+1, 'UTF-8'); + } else { + $pos = strpos($text, $fromText, $pos+1); + } + if ($pos === false) { + break; + } + --$instance; + } + if ($pos !== false) { + if (function_exists('mb_strlen')) { + return self::REPLACE($text,++$pos,mb_strlen($fromText, 'UTF-8'),$toText); + } else { + return self::REPLACE($text,++$pos,strlen($fromText),$toText); + } + } + } + + return $text; + } // function SUBSTITUTE() + + + /** + * RETURNSTRING + * + * @param mixed $testValue Value to check + * @return boolean + */ + public static function RETURNSTRING($testValue = '') { + $testValue = PHPExcel_Calculation_Functions::flattenSingleValue($testValue); + + if (is_string($testValue)) { + return $testValue; + } + return Null; + } // function RETURNSTRING() + + + /** + * TEXTFORMAT + * + * @param mixed $value Value to check + * @param string $format Format mask to use + * @return boolean + */ + public static function TEXTFORMAT($value,$format) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $format = PHPExcel_Calculation_Functions::flattenSingleValue($format); + + if ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date::isDateTimeFormatCode($format)) { + $value = PHPExcel_Calculation_DateTime::DATEVALUE($value); + } + + return (string) PHPExcel_Style_NumberFormat::toFormattedString($value,$format); + } // function TEXTFORMAT() + + /** + * VALUE + * + * @param mixed $value Value to check + * @return boolean + */ + public static function VALUE($value = '') { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (!is_numeric($value)) { $numberValue = str_replace( PHPExcel_Shared_String::getThousandsSeparator(), '', @@ -615,16 +615,16 @@ public static function VALUE($value = '') { return $timeValue; } } - $dateValue = PHPExcel_Calculation_DateTime::DATEVALUE($value); + $dateValue = PHPExcel_Calculation_DateTime::DATEVALUE($value); if ($dateValue !== PHPExcel_Calculation_Functions::VALUE()) { PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); return $dateValue; } PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); - return PHPExcel_Calculation_Functions::VALUE(); - } - return (float) $value; - } + return PHPExcel_Calculation_Functions::VALUE(); + } + return (float) $value; + } } diff --git a/Classes/PHPExcel/Calculation/Token/Stack.php b/Classes/PHPExcel/Calculation/Token/Stack.php index 2b27bb8ee..7d561d4d3 100644 --- a/Classes/PHPExcel/Calculation/Token/Stack.php +++ b/Classes/PHPExcel/Calculation/Token/Stack.php @@ -1,4 +1,5 @@ setValueExplicit( TRUE, PHPExcel_Cell_DataType::TYPE_BOOL); + $cell->setValueExplicit(true, PHPExcel_Cell_DataType::TYPE_BOOL); return true; } elseif($value == PHPExcel_Calculation::getFALSE()) { - $cell->setValueExplicit( FALSE, PHPExcel_Cell_DataType::TYPE_BOOL); + $cell->setValueExplicit(false, PHPExcel_Cell_DataType::TYPE_BOOL); return true; } // Check for number in scientific format if (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NUMBER.'$/', $value)) { - $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + $cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); return true; } @@ -84,7 +75,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) // Convert value to number $value = $matches[2] / $matches[3]; if ($matches[1] == '-') $value = 0 - $value; - $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + $cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode( '??/??' ); @@ -93,7 +84,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) // Convert value to number $value = $matches[2] + ($matches[3] / $matches[4]); if ($matches[1] == '-') $value = 0 - $value; - $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + $cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode( '# ??/??' ); @@ -107,7 +98,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) - ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00 ); + ->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00); return true; } @@ -122,7 +113,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) // Set style $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) ->getNumberFormat()->setFormatCode( - str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE ) + str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE) ); return true; } elseif (preg_match('/^\$ *(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/', $value)) { @@ -131,7 +122,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) - ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE ); + ->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE); return true; } @@ -143,7 +134,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) - ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3 ); + ->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3); return true; } @@ -156,7 +147,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) - ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4 ); + ->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4); return true; } @@ -176,12 +167,12 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) } // Check for newline character "\n" - if (strpos($value, "\n") !== FALSE) { + if (strpos($value, "\n") !== false) { $value = PHPExcel_Shared_String::SanitizeUTF8($value); $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); // Set style - $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) - ->getAlignment()->setWrapText(TRUE); + $cell->getWorksheet()->getStyle($cell->getCoordinate()) + ->getAlignment()->setWrapText(true); return true; } } diff --git a/Classes/PHPExcel/Cell/DataType.php b/Classes/PHPExcel/Cell/DataType.php index 144937a67..dda18ed8f 100644 --- a/Classes/PHPExcel/Cell/DataType.php +++ b/Classes/PHPExcel/Cell/DataType.php @@ -1,6 +1,7 @@ 0, '#DIV/0!' => 1, '#VALUE!' => 2, @@ -65,8 +57,9 @@ class PHPExcel_Cell_DataType * * @return array */ - public static function getErrorCodes() { - return self::$_errorCodes; + public static function getErrorCodes() + { + return self::$errorCodes; } /** @@ -76,7 +69,8 @@ public static function getErrorCodes() { * @param mixed $pValue * @return string */ - public static function dataTypeForValue($pValue = null) { + public static function dataTypeForValue($pValue = null) + { return PHPExcel_Cell_DefaultValueBinder::dataTypeForValue($pValue); } @@ -112,7 +106,7 @@ public static function checkErrorCode($pValue = null) { $pValue = (string) $pValue; - if ( !array_key_exists($pValue, self::$_errorCodes) ) { + if (!array_key_exists($pValue, self::$errorCodes)) { $pValue = '#NULL!'; } diff --git a/Classes/PHPExcel/Cell/DataValidation.php b/Classes/PHPExcel/Cell/DataValidation.php index 61fee106d..38d59e851 100644 --- a/Classes/PHPExcel/Cell/DataValidation.php +++ b/Classes/PHPExcel/Cell/DataValidation.php @@ -1,6 +1,7 @@ setValueExplicit( $value, self::dataTypeForValue($value) ); + $cell->setValueExplicit($value, self::dataTypeForValue($value)); // Done! return true; @@ -79,7 +70,8 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) * @param mixed $pValue * @return string */ - public static function dataTypeForValue($pValue = null) { + public static function dataTypeForValue($pValue = null) + { // Match the value against a few data types if ($pValue === null) { return PHPExcel_Cell_DataType::TYPE_NULL; diff --git a/Classes/PHPExcel/Cell/Hyperlink.php b/Classes/PHPExcel/Cell/Hyperlink.php index a9b281c28..daab54c84 100644 --- a/Classes/PHPExcel/Cell/Hyperlink.php +++ b/Classes/PHPExcel/Cell/Hyperlink.php @@ -1,6 +1,7 @@ _url = $pUrl; - $this->_tooltip = $pTooltip; + $this->url = $pUrl; + $this->tooltip = $pTooltip; } /** @@ -67,8 +59,9 @@ public function __construct($pUrl = '', $pTooltip = '') * * @return string */ - public function getUrl() { - return $this->_url; + public function getUrl() + { + return $this->url; } /** @@ -77,8 +70,9 @@ public function getUrl() { * @param string $value * @return PHPExcel_Cell_Hyperlink */ - public function setUrl($value = '') { - $this->_url = $value; + public function setUrl($value = '') + { + $this->url = $value; return $this; } @@ -87,8 +81,9 @@ public function setUrl($value = '') { * * @return string */ - public function getTooltip() { - return $this->_tooltip; + public function getTooltip() + { + return $this->tooltip; } /** @@ -97,8 +92,9 @@ public function getTooltip() { * @param string $value * @return PHPExcel_Cell_Hyperlink */ - public function setTooltip($value = '') { - $this->_tooltip = $value; + public function setTooltip($value = '') + { + $this->tooltip = $value; return $this; } @@ -107,8 +103,9 @@ public function setTooltip($value = '') { * * @return boolean */ - public function isInternal() { - return strpos($this->_url, 'sheet://') !== false; + public function isInternal() + { + return strpos($this->url, 'sheet://') !== false; } /** @@ -116,11 +113,12 @@ public function isInternal() { * * @return string Hash code */ - public function getHashCode() { + public function getHashCode() + { return md5( - $this->_url - . $this->_tooltip - . __CLASS__ + $this->url . + $this->tooltip . + __CLASS__ ); } } diff --git a/Classes/PHPExcel/Cell/IValueBinder.php b/Classes/PHPExcel/Cell/IValueBinder.php index 5b8d1ca17..de2d0ac0c 100644 --- a/Classes/PHPExcel/Cell/IValueBinder.php +++ b/Classes/PHPExcel/Cell/IValueBinder.php @@ -1,4 +1,5 @@ getText() . - $this->_font->getHashCode() . + $this->font->getHashCode() . __CLASS__ ); } diff --git a/Classes/PHPExcel/RichText/TextElement.php b/Classes/PHPExcel/RichText/TextElement.php index 3558db326..f86e70315 100644 --- a/Classes/PHPExcel/RichText/TextElement.php +++ b/Classes/PHPExcel/RichText/TextElement.php @@ -83,7 +83,7 @@ public function getFont() public function getHashCode() { return md5( - $this->_text . + $this->text . __CLASS__ ); } diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php index 13655422b..eff33f0f9 100644 --- a/Classes/PHPExcel/Settings.php +++ b/Classes/PHPExcel/Settings.php @@ -304,7 +304,7 @@ public static function setPdfRendererName($libraryName) if (!in_array($libraryName, self::$pdfRenderers)) { return false; } - self::$_pdfRendererName = $libraryName; + self::$pdfRendererName = $libraryName; return true; } @@ -365,7 +365,7 @@ public static function setLibXmlLoaderOptions($options = null) if (version_compare(PHP_VERSION, '5.2.11') >= 0) { @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); } - self::$_libXmlLoaderOptions = $options; + self::$libXmlLoaderOptions = $options; } /** @@ -376,12 +376,12 @@ public static function setLibXmlLoaderOptions($options = null) */ public static function getLibXmlLoaderOptions() { - if (is_null(self::$_libXmlLoaderOptions) && defined(LIBXML_DTDLOAD)) { + if (is_null(self::$libXmlLoaderOptions) && defined(LIBXML_DTDLOAD)) { self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR); } if (version_compare(PHP_VERSION, '5.2.11') >= 0) { @libxml_disable_entity_loader(self::$libXmlLoaderOptions == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); } - return self::$_libXmlLoaderOptions; + return self::$libXmlLoaderOptions; } } diff --git a/Classes/PHPExcel/Writer/PDF.php b/Classes/PHPExcel/Writer/PDF.php index 8e495b410..579edfa53 100644 --- a/Classes/PHPExcel/Writer/PDF.php +++ b/Classes/PHPExcel/Writer/PDF.php @@ -1,6 +1,7 @@ _renderer = new $rendererName($phpExcel); + $this->renderer = new $rendererName($phpExcel); } @@ -80,11 +72,11 @@ public function __construct(PHPExcel $phpExcel) */ public function __call($name, $arguments) { - if ($this->_renderer === NULL) { + if ($this->renderer === null) { throw new PHPExcel_Writer_Exception("PDF Rendering library has not been defined."); } - return call_user_func_array(array($this->_renderer, $name), $arguments); + return call_user_func_array(array($this->renderer, $name), $arguments); } /** @@ -92,6 +84,6 @@ public function __call($name, $arguments) */ public function save($pFilename = null) { - $this->_renderer->save($pFilename); + $this->renderer->save($pFilename); } } diff --git a/Classes/PHPExcel/Writer/PDF/Core.php b/Classes/PHPExcel/Writer/PDF/Core.php index b1693b3a7..8075c555b 100644 --- a/Classes/PHPExcel/Writer/PDF/Core.php +++ b/Classes/PHPExcel/Writer/PDF/Core.php @@ -1,6 +1,7 @@ 'LETTER', // (8.5 in. by 11 in.) PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_SMALL @@ -219,7 +211,7 @@ abstract class PHPExcel_Writer_PDF_Core extends PHPExcel_Writer_HTML public function __construct(PHPExcel $phpExcel) { parent::__construct($phpExcel); - $this->setUseInlineCss(TRUE); + $this->setUseInlineCss(true); $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); } @@ -255,7 +247,7 @@ public function setFont($fontName) */ public function getPaperSize() { - return $this->_paperSize; + return $this->paperSize; } /** @@ -266,7 +258,7 @@ public function getPaperSize() */ public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) { - $this->_paperSize = $pValue; + $this->paperSize = $pValue; return $this; } @@ -277,7 +269,7 @@ public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_L */ public function getOrientation() { - return $this->_orientation; + return $this->orientation; } /** @@ -288,7 +280,7 @@ public function getOrientation() */ public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) { - $this->_orientation = $pValue; + $this->orientation = $pValue; return $this; } @@ -325,24 +317,24 @@ public function setTempDir($pValue = '') * @param string $pFilename Name of the file to save as * @throws PHPExcel_Writer_Exception */ - protected function prepareForSave($pFilename = NULL) + protected function prepareForSave($pFilename = null) { // garbage collect $this->_phpExcel->garbageCollect(); - $this->_saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); + $this->saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); // Open file $fileHandle = fopen($pFilename, 'w'); - if ($fileHandle === FALSE) { + if ($fileHandle === false) { throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); } // Set PDF - $this->_isPdf = TRUE; + $this->_isPdf = true; // Build CSS - $this->buildCSS(TRUE); + $this->buildCSS(true); return $fileHandle; } @@ -358,7 +350,6 @@ protected function restoreStateAfterSave($fileHandle) // Close file fclose($fileHandle); - PHPExcel_Calculation::setArrayReturnType($this->_saveArrayReturnType); + PHPExcel_Calculation::setArrayReturnType($this->saveArrayReturnType); } - } diff --git a/Classes/PHPExcel/Writer/PDF/DomPDF.php b/Classes/PHPExcel/Writer/PDF/DomPDF.php index c695206fb..45247ed79 100644 --- a/Classes/PHPExcel/Writer/PDF/DomPDF.php +++ b/Classes/PHPExcel/Writer/PDF/DomPDF.php @@ -1,6 +1,15 @@ getSheetIndex())) { $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() - == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) - ? 'L' - : 'P'; + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); } else { $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() - == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) - ? 'L' - : 'P'; + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); } - $orientation = ($orientation == 'L') ? 'landscape' : 'portrait'; @@ -97,8 +84,8 @@ public function save($pFilename = NULL) $printPaperSize = $this->getPaperSize(); } - if (isset(self::$_paperSizes[$printPaperSize])) { - $paperSize = self::$_paperSizes[$printPaperSize]; + if (isset(self::$paperSizes[$printPaperSize])) { + $paperSize = self::$paperSizes[$printPaperSize]; } @@ -107,7 +94,7 @@ public function save($pFilename = NULL) $pdf->set_paper(strtolower($paperSize), $orientation); $pdf->load_html( - $this->generateHTMLHeader(FALSE) . + $this->generateHTMLHeader(false) . $this->generateSheetData() . $this->generateHTMLFooter() ); @@ -116,7 +103,6 @@ public function save($pFilename = NULL) // Write to file fwrite($fileHandle, $pdf->output()); - parent::restoreStateAfterSave($fileHandle); + parent::restoreStateAfterSave($fileHandle); } - } diff --git a/Classes/PHPExcel/Writer/PDF/mPDF.php b/Classes/PHPExcel/Writer/PDF/mPDF.php index e6f0cdbab..d13b982d6 100644 --- a/Classes/PHPExcel/Writer/PDF/mPDF.php +++ b/Classes/PHPExcel/Writer/PDF/mPDF.php @@ -1,6 +1,15 @@ getSheetIndex())) { $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() - == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) - ? 'L' - : 'P'; + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); } else { $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() - == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) - ? 'L' - : 'P'; + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); } @@ -97,10 +85,11 @@ public function save($pFilename = NULL) $printPaperSize = $this->getPaperSize(); } - if (isset(self::$_paperSizes[$printPaperSize])) { - $paperSize = self::$_paperSizes[$printPaperSize]; + if (isset(self::$paperSizes[$printPaperSize])) { + $paperSize = self::$paperSizes[$printPaperSize]; } + // Create PDF $pdf = new mpdf(); $ortmp = $orientation; @@ -116,7 +105,7 @@ public function save($pFilename = NULL) $pdf->SetCreator($this->_phpExcel->getProperties()->getCreator()); $pdf->WriteHTML( - $this->generateHTMLHeader(FALSE) . + $this->generateHTMLHeader(false) . $this->generateSheetData() . $this->generateHTMLFooter() ); @@ -124,7 +113,6 @@ public function save($pFilename = NULL) // Write to file fwrite($fileHandle, $pdf->Output('', 'S')); - parent::restoreStateAfterSave($fileHandle); + parent::restoreStateAfterSave($fileHandle); } - } diff --git a/Classes/PHPExcel/Writer/PDF/tcPDF.php b/Classes/PHPExcel/Writer/PDF/tcPDF.php index 201e0a290..8b6c0bca3 100644 --- a/Classes/PHPExcel/Writer/PDF/tcPDF.php +++ b/Classes/PHPExcel/Writer/PDF/tcPDF.php @@ -1,6 +1,16 @@ getSheetIndex())) { $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() - == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) - ? 'L' - : 'P'; + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); } else { $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() - == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) - ? 'L' - : 'P'; + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); } @@ -95,27 +83,27 @@ public function save($pFilename = NULL) $printPaperSize = $this->getPaperSize(); } - if (isset(self::$_paperSizes[$printPaperSize])) { - $paperSize = self::$_paperSizes[$printPaperSize]; + if (isset(self::$paperSizes[$printPaperSize])) { + $paperSize = self::$paperSizes[$printPaperSize]; } // Create PDF $pdf = new TCPDF($orientation, 'pt', $paperSize); - $pdf->setFontSubsetting(FALSE); + $pdf->setFontSubsetting(false); // Set margins, converting inches to points (using 72 dpi) $pdf->SetMargins($printMargins->getLeft() * 72, $printMargins->getTop() * 72, $printMargins->getRight() * 72); - $pdf->SetAutoPageBreak(TRUE, $printMargins->getBottom() * 72); + $pdf->SetAutoPageBreak(true, $printMargins->getBottom() * 72); - $pdf->setPrintHeader(FALSE); - $pdf->setPrintFooter(FALSE); + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); $pdf->AddPage(); // Set the appropriate font $pdf->SetFont($this->getFont()); $pdf->writeHTML( - $this->generateHTMLHeader(FALSE) . + $this->generateHTMLHeader(false) . $this->generateSheetData() . $this->generateHTMLFooter() ); @@ -130,7 +118,6 @@ public function save($pFilename = NULL) // Write to file fwrite($fileHandle, $pdf->output($pFilename, 'S')); - parent::restoreStateAfterSave($fileHandle); + parent::restoreStateAfterSave($fileHandle); } - } From c07b54172a2cd222135a9ca5abde02a8bba12503 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 9 May 2015 14:33:20 +0100 Subject: [PATCH 344/467] More PSR-2 modifications --- Classes/PHPExcel/Calculation/DateTime.php | 87 +- Classes/PHPExcel/Calculation/Engineering.php | 1140 ++++++++--------- Classes/PHPExcel/Calculation/Exception.php | 18 +- .../PHPExcel/Calculation/ExceptionHandler.php | 20 +- Classes/PHPExcel/Calculation/Financial.php | 667 +++++----- .../PHPExcel/Calculation/FormulaParser.php | 208 +-- Classes/PHPExcel/Calculation/FormulaToken.php | 136 +- Classes/PHPExcel/Calculation/Function.php | 83 +- Classes/PHPExcel/Calculation/Functions.php | 353 ++--- Classes/PHPExcel/Calculation/Logical.php | 103 +- Classes/PHPExcel/Calculation/LookupRef.php | 15 +- Classes/PHPExcel/Calculation/Statistical.php | 2 +- Examples/runall.php | 2 +- 13 files changed, 1456 insertions(+), 1378 deletions(-) diff --git a/Classes/PHPExcel/Calculation/DateTime.php b/Classes/PHPExcel/Calculation/DateTime.php index fabd60c6b..359f6ef5c 100644 --- a/Classes/PHPExcel/Calculation/DateTime.php +++ b/Classes/PHPExcel/Calculation/DateTime.php @@ -1,6 +1,16 @@ = $startDate) && ($holidayDate <= $endDate)) { @@ -1035,7 +1026,7 @@ public static function WORKDAY($startDate, $endDays) array_shift($dateArgs); array_shift($dateArgs); - if ((is_string($startDate = self::_getDateValue($startDate))) || (!is_numeric($endDays))) { + if ((is_string($startDate = self::getDateValue($startDate))) || (!is_numeric($endDays))) { return PHPExcel_Calculation_Functions::VALUE(); } $startDate = (float) floor($startDate); @@ -1069,7 +1060,7 @@ public static function WORKDAY($startDate, $endDays) $holidayCountedArray = $holidayDates = array(); foreach ($dateArgs as $holidayDate) { if (($holidayDate !== null) && (trim($holidayDate) > '')) { - if (is_string($holidayDate = self::_getDateValue($holidayDate))) { + if (is_string($holidayDate = self::getDateValue($holidayDate))) { return PHPExcel_Calculation_Functions::VALUE(); } if (self::DAYOFWEEK($holidayDate, 3) < 5) { @@ -1136,7 +1127,7 @@ public static function DAYOFMONTH($dateValue = 1) if ($dateValue === null) { $dateValue = 1; - } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { + } elseif (is_string($dateValue = self::getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($dateValue == 0.0) { return 0; @@ -1182,7 +1173,7 @@ public static function DAYOFWEEK($dateValue = 1, $style = 1) if ($dateValue === null) { $dateValue = 1; - } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { + } elseif (is_string($dateValue = self::getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($dateValue < 0.0) { return PHPExcel_Calculation_Functions::NaN(); @@ -1258,7 +1249,7 @@ public static function WEEKOFYEAR($dateValue = 1, $method = 1) if ($dateValue === null) { $dateValue = 1; - } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { + } elseif (is_string($dateValue = self::getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($dateValue < 0.0) { return PHPExcel_Calculation_Functions::NaN(); @@ -1297,7 +1288,7 @@ public static function MONTHOFYEAR($dateValue = 1) if ($dateValue === null) { $dateValue = 1; - } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { + } elseif (is_string($dateValue = self::getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($dateValue < 0.0) { return PHPExcel_Calculation_Functions::NaN(); @@ -1329,7 +1320,7 @@ public static function YEAR($dateValue = 1) if ($dateValue === null) { $dateValue = 1; - } elseif (is_string($dateValue = self::_getDateValue($dateValue))) { + } elseif (is_string($dateValue = self::getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($dateValue < 0.0) { return PHPExcel_Calculation_Functions::NaN(); @@ -1366,7 +1357,7 @@ public static function HOUROFDAY($timeValue = 0) return PHPExcel_Calculation_Functions::VALUE(); } } - $timeValue = self::_getTimeValue($timeValue); + $timeValue = self::getTimeValue($timeValue); if (is_string($timeValue)) { return PHPExcel_Calculation_Functions::VALUE(); } @@ -1407,7 +1398,7 @@ public static function MINUTEOFHOUR($timeValue = 0) return PHPExcel_Calculation_Functions::VALUE(); } } - $timeValue = self::_getTimeValue($timeValue); + $timeValue = self::getTimeValue($timeValue); if (is_string($timeValue)) { return PHPExcel_Calculation_Functions::VALUE(); } @@ -1448,7 +1439,7 @@ public static function SECONDOFMINUTE($timeValue = 0) return PHPExcel_Calculation_Functions::VALUE(); } } - $timeValue = self::_getTimeValue($timeValue); + $timeValue = self::getTimeValue($timeValue); if (is_string($timeValue)) { return PHPExcel_Calculation_Functions::VALUE(); } @@ -1494,12 +1485,12 @@ public static function EDATE($dateValue = 1, $adjustmentMonths = 0) } $adjustmentMonths = floor($adjustmentMonths); - if (is_string($dateValue = self::_getDateValue($dateValue))) { + if (is_string($dateValue = self::getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } // Execute function - $PHPDateObject = self::_adjustDateByMonths($dateValue, $adjustmentMonths); + $PHPDateObject = self::adjustDateByMonths($dateValue, $adjustmentMonths); switch (PHPExcel_Calculation_Functions::getReturnDateType()) { case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL: @@ -1540,12 +1531,12 @@ public static function EOMONTH($dateValue = 1, $adjustmentMonths = 0) } $adjustmentMonths = floor($adjustmentMonths); - if (is_string($dateValue = self::_getDateValue($dateValue))) { + if (is_string($dateValue = self::getDateValue($dateValue))) { return PHPExcel_Calculation_Functions::VALUE(); } // Execute function - $PHPDateObject = self::_adjustDateByMonths($dateValue, $adjustmentMonths+1); + $PHPDateObject = self::adjustDateByMonths($dateValue, $adjustmentMonths+1); $adjustDays = (int) $PHPDateObject->format('d'); $adjustDaysString = '-' . $adjustDays . ' days'; $PHPDateObject->modify($adjustDaysString); diff --git a/Classes/PHPExcel/Calculation/Engineering.php b/Classes/PHPExcel/Calculation/Engineering.php index d7c632984..8c027d12b 100644 --- a/Classes/PHPExcel/Calculation/Engineering.php +++ b/Classes/PHPExcel/Calculation/Engineering.php @@ -1,6 +1,19 @@ array('Group' => 'Mass', 'Unit Name' => 'Gram', 'AllowPrefix' => true), 'sg' => array('Group' => 'Mass', 'Unit Name' => 'Slug', 'AllowPrefix' => false), 'lbm' => array('Group' => 'Mass', 'Unit Name' => 'Pound mass (avoirdupois)', 'AllowPrefix' => false), @@ -125,7 +115,7 @@ class PHPExcel_Calculation_Engineering * * @var mixed[] */ - private static $_conversionMultipliers = array( + private static $conversionMultipliers = array( 'Y' => array('multiplier' => 1E24, 'name' => 'yotta'), 'Z' => array('multiplier' => 1E21, 'name' => 'zetta'), 'E' => array('multiplier' => 1E18, 'name' => 'exa'), @@ -153,616 +143,616 @@ class PHPExcel_Calculation_Engineering * * @var mixed[] */ - private static $_unitConversions = array( - 'Mass' => array( - 'g' => array( - 'g' => 1.0, - 'sg' => 6.85220500053478E-05, + private static $unitConversions = array( + 'Mass' => array( + 'g' => array( + 'g' => 1.0, + 'sg' => 6.85220500053478E-05, 'lbm' => 2.20462291469134E-03, - 'u' => 6.02217000000000E+23, + 'u' => 6.02217000000000E+23, 'ozm' => 3.52739718003627E-02, ), 'sg' => array( - 'g' => 1.45938424189287E+04, - 'sg' => 1.0, + 'g' => 1.45938424189287E+04, + 'sg' => 1.0, 'lbm' => 3.21739194101647E+01, - 'u' => 8.78866000000000E+27, + 'u' => 8.78866000000000E+27, 'ozm' => 5.14782785944229E+02, ), 'lbm' => array( - 'g' => 4.5359230974881148E+02, - 'sg' => 3.10810749306493E-02, + 'g' => 4.5359230974881148E+02, + 'sg' => 3.10810749306493E-02, 'lbm' => 1.0, - 'u' => 2.73161000000000E+26, + 'u' => 2.73161000000000E+26, 'ozm' => 1.60000023429410E+01, ), - 'u' => array( - 'g' => 1.66053100460465E-24, - 'sg' => 1.13782988532950E-28, + 'u' => array( + 'g' => 1.66053100460465E-24, + 'sg' => 1.13782988532950E-28, 'lbm' => 3.66084470330684E-27, - 'u' => 1.0, + 'u' => 1.0, 'ozm' => 5.85735238300524E-26, ), 'ozm' => array( - 'g' => 2.83495152079732E+01, - 'sg' => 1.94256689870811E-03, + 'g' => 2.83495152079732E+01, + 'sg' => 1.94256689870811E-03, 'lbm' => 6.24999908478882E-02, - 'u' => 1.70725600000000E+25, + 'u' => 1.70725600000000E+25, 'ozm' => 1.0, ), ), 'Distance' => array( - 'm' => array( - 'm' => 1.0, - 'mi' => 6.21371192237334E-04, - 'Nmi' => 5.39956803455724E-04, - 'in' => 3.93700787401575E+01, - 'ft' => 3.28083989501312E+00, - 'yd' => 1.09361329797891E+00, - 'ang' => 1.00000000000000E+10, + 'm' => array( + 'm' => 1.0, + 'mi' => 6.21371192237334E-04, + 'Nmi' => 5.39956803455724E-04, + 'in' => 3.93700787401575E+01, + 'ft' => 3.28083989501312E+00, + 'yd' => 1.09361329797891E+00, + 'ang' => 1.00000000000000E+10, 'Pica' => 2.83464566929116E+03, ), 'mi' => array( - 'm' => 1.60934400000000E+03, - 'mi' => 1.0, - 'Nmi' => 8.68976241900648E-01, - 'in' => 6.33600000000000E+04, - 'ft' => 5.28000000000000E+03, - 'yd' => 1.76000000000000E+03, - 'ang' => 1.60934400000000E+13, + 'm' => 1.60934400000000E+03, + 'mi' => 1.0, + 'Nmi' => 8.68976241900648E-01, + 'in' => 6.33600000000000E+04, + 'ft' => 5.28000000000000E+03, + 'yd' => 1.76000000000000E+03, + 'ang' => 1.60934400000000E+13, 'Pica' => 4.56191999999971E+06, ), 'Nmi' => array( - 'm' => 1.85200000000000E+03, - 'mi' => 1.15077944802354E+00, - 'Nmi' => 1.0, - 'in' => 7.29133858267717E+04, - 'ft' => 6.07611548556430E+03, - 'yd' => 2.02537182785694E+03, - 'ang' => 1.85200000000000E+13, + 'm' => 1.85200000000000E+03, + 'mi' => 1.15077944802354E+00, + 'Nmi' => 1.0, + 'in' => 7.29133858267717E+04, + 'ft' => 6.07611548556430E+03, + 'yd' => 2.02537182785694E+03, + 'ang' => 1.85200000000000E+13, 'Pica' => 5.24976377952723E+06, ), 'in' => array( - 'm' => 2.54000000000000E-02, - 'mi' => 1.57828282828283E-05, - 'Nmi' => 1.37149028077754E-05, - 'in' => 1.0, - 'ft' => 8.33333333333333E-02, - 'yd' => 2.77777777686643E-02, - 'ang' => 2.54000000000000E+08, + 'm' => 2.54000000000000E-02, + 'mi' => 1.57828282828283E-05, + 'Nmi' => 1.37149028077754E-05, + 'in' => 1.0, + 'ft' => 8.33333333333333E-02, + 'yd' => 2.77777777686643E-02, + 'ang' => 2.54000000000000E+08, 'Pica' => 7.19999999999955E+01, ), 'ft' => array( - 'm' => 3.04800000000000E-01, - 'mi' => 1.89393939393939E-04, - 'Nmi' => 1.64578833693305E-04, - 'in' => 1.20000000000000E+01, - 'ft' => 1.0, - 'yd' => 3.33333333223972E-01, - 'ang' => 3.04800000000000E+09, + 'm' => 3.04800000000000E-01, + 'mi' => 1.89393939393939E-04, + 'Nmi' => 1.64578833693305E-04, + 'in' => 1.20000000000000E+01, + 'ft' => 1.0, + 'yd' => 3.33333333223972E-01, + 'ang' => 3.04800000000000E+09, 'Pica' => 8.63999999999946E+02, ), 'yd' => array( - 'm' => 9.14400000300000E-01, - 'mi' => 5.68181818368230E-04, - 'Nmi' => 4.93736501241901E-04, - 'in' => 3.60000000118110E+01, - 'ft' => 3.00000000000000E+00, - 'yd' => 1.0, - 'ang' => 9.14400000300000E+09, + 'm' => 9.14400000300000E-01, + 'mi' => 5.68181818368230E-04, + 'Nmi' => 4.93736501241901E-04, + 'in' => 3.60000000118110E+01, + 'ft' => 3.00000000000000E+00, + 'yd' => 1.0, + 'ang' => 9.14400000300000E+09, 'Pica' => 2.59200000085023E+03, ), 'ang' => array( - 'm' => 1.00000000000000E-10, - 'mi' => 6.21371192237334E-14, - 'Nmi' => 5.39956803455724E-14, - 'in' => 3.93700787401575E-09, - 'ft' => 3.28083989501312E-10, - 'yd' => 1.09361329797891E-10, - 'ang' => 1.0, + 'm' => 1.00000000000000E-10, + 'mi' => 6.21371192237334E-14, + 'Nmi' => 5.39956803455724E-14, + 'in' => 3.93700787401575E-09, + 'ft' => 3.28083989501312E-10, + 'yd' => 1.09361329797891E-10, + 'ang' => 1.0, 'Pica' => 2.83464566929116E-07, ), 'Pica' => array( - 'm' => 3.52777777777800E-04, - 'mi' => 2.19205948372629E-07, - 'Nmi' => 1.90484761219114E-07, - 'in' => 1.38888888888898E-02, - 'ft' => 1.15740740740748E-03, - 'yd' => 3.85802469009251E-04, - 'ang' => 3.52777777777800E+06, + 'm' => 3.52777777777800E-04, + 'mi' => 2.19205948372629E-07, + 'Nmi' => 1.90484761219114E-07, + 'in' => 1.38888888888898E-02, + 'ft' => 1.15740740740748E-03, + 'yd' => 3.85802469009251E-04, + 'ang' => 3.52777777777800E+06, 'Pica' => 1.0, ), ), - 'Time' => array( + 'Time' => array( 'yr' => array( - 'yr' => 1.0, - 'day' => 365.25, - 'hr' => 8766.0, - 'mn' => 525960.0, - 'sec' => 31557600.0, + 'yr' => 1.0, + 'day' => 365.25, + 'hr' => 8766.0, + 'mn' => 525960.0, + 'sec' => 31557600.0, ), 'day' => array( - 'yr' => 2.73785078713210E-03, - 'day' => 1.0, - 'hr' => 24.0, - 'mn' => 1440.0, - 'sec' => 86400.0, + 'yr' => 2.73785078713210E-03, + 'day' => 1.0, + 'hr' => 24.0, + 'mn' => 1440.0, + 'sec' => 86400.0, ), 'hr' => array( - 'yr' => 1.14077116130504E-04, - 'day' => 4.16666666666667E-02, - 'hr' => 1.0, - 'mn' => 60.0, - 'sec' => 3600.0, + 'yr' => 1.14077116130504E-04, + 'day' => 4.16666666666667E-02, + 'hr' => 1.0, + 'mn' => 60.0, + 'sec' => 3600.0, ), 'mn' => array( - 'yr' => 1.90128526884174E-06, - 'day' => 6.94444444444444E-04, - 'hr' => 1.66666666666667E-02, - 'mn' => 1.0, - 'sec' => 60.0, + 'yr' => 1.90128526884174E-06, + 'day' => 6.94444444444444E-04, + 'hr' => 1.66666666666667E-02, + 'mn' => 1.0, + 'sec' => 60.0, ), 'sec' => array( - 'yr' => 3.16880878140289E-08, - 'day' => 1.15740740740741E-05, - 'hr' => 2.77777777777778E-04, - 'mn' => 1.66666666666667E-02, - 'sec' => 1.0, + 'yr' => 3.16880878140289E-08, + 'day' => 1.15740740740741E-05, + 'hr' => 2.77777777777778E-04, + 'mn' => 1.66666666666667E-02, + 'sec' => 1.0, ), ), 'Pressure' => array( 'Pa' => array( - 'Pa' => 1.0, - 'p' => 1.0, - 'atm' => 9.86923299998193E-06, - 'at' => 9.86923299998193E-06, - 'mmHg' => 7.50061707998627E-03, + 'Pa' => 1.0, + 'p' => 1.0, + 'atm' => 9.86923299998193E-06, + 'at' => 9.86923299998193E-06, + 'mmHg' => 7.50061707998627E-03, ), - 'p' => array( - 'Pa' => 1.0, - 'p' => 1.0, - 'atm' => 9.86923299998193E-06, - 'at' => 9.86923299998193E-06, - 'mmHg' => 7.50061707998627E-03, + 'p' => array( + 'Pa' => 1.0, + 'p' => 1.0, + 'atm' => 9.86923299998193E-06, + 'at' => 9.86923299998193E-06, + 'mmHg' => 7.50061707998627E-03, ), 'atm' => array( - 'Pa' => 1.01324996583000E+05, - 'p' => 1.01324996583000E+05, - 'atm' => 1.0, - 'at' => 1.0, - 'mmHg' => 760.0, + 'Pa' => 1.01324996583000E+05, + 'p' => 1.01324996583000E+05, + 'atm' => 1.0, + 'at' => 1.0, + 'mmHg' => 760.0, ), 'at' => array( - 'Pa' => 1.01324996583000E+05, - 'p' => 1.01324996583000E+05, - 'atm' => 1.0, - 'at' => 1.0, - 'mmHg' => 760.0, + 'Pa' => 1.01324996583000E+05, + 'p' => 1.01324996583000E+05, + 'atm' => 1.0, + 'at' => 1.0, + 'mmHg' => 760.0, ), 'mmHg' => array( - 'Pa' => 1.33322363925000E+02, - 'p' => 1.33322363925000E+02, - 'atm' => 1.31578947368421E-03, - 'at' => 1.31578947368421E-03, - 'mmHg' => 1.0, + 'Pa' => 1.33322363925000E+02, + 'p' => 1.33322363925000E+02, + 'atm' => 1.31578947368421E-03, + 'at' => 1.31578947368421E-03, + 'mmHg' => 1.0, ), ), - 'Force' => array( - 'N' => array( - 'N' => 1.0, - 'dyn' => 1.0E+5, - 'dy' => 1.0E+5, - 'lbf' => 2.24808923655339E-01, + 'Force' => array( + 'N' => array( + 'N' => 1.0, + 'dyn' => 1.0E+5, + 'dy' => 1.0E+5, + 'lbf' => 2.24808923655339E-01, ), 'dyn' => array( - 'N' => 1.0E-5, - 'dyn' => 1.0, - 'dy' => 1.0, - 'lbf' => 2.24808923655339E-06, + 'N' => 1.0E-5, + 'dyn' => 1.0, + 'dy' => 1.0, + 'lbf' => 2.24808923655339E-06, ), 'dy' => array( - 'N' => 1.0E-5, - 'dyn' => 1.0, - 'dy' => 1.0, - 'lbf' => 2.24808923655339E-06, + 'N' => 1.0E-5, + 'dyn' => 1.0, + 'dy' => 1.0, + 'lbf' => 2.24808923655339E-06, ), 'lbf' => array( - 'N' => 4.448222, - 'dyn' => 4.448222E+5, - 'dy' => 4.448222E+5, - 'lbf' => 1.0, + 'N' => 4.448222, + 'dyn' => 4.448222E+5, + 'dy' => 4.448222E+5, + 'lbf' => 1.0, ), ), 'Energy' => array( - 'J' => array( - 'J' => 1.0, - 'e' => 9.99999519343231E+06, - 'c' => 2.39006249473467E-01, - 'cal' => 2.38846190642017E-01, - 'eV' => 6.24145700000000E+18, - 'ev' => 6.24145700000000E+18, - 'HPh' => 3.72506430801000E-07, - 'hh' => 3.72506430801000E-07, - 'Wh' => 2.77777916238711E-04, - 'wh' => 2.77777916238711E-04, - 'flb' => 2.37304222192651E+01, - 'BTU' => 9.47815067349015E-04, - 'btu' => 9.47815067349015E-04, + 'J' => array( + 'J' => 1.0, + 'e' => 9.99999519343231E+06, + 'c' => 2.39006249473467E-01, + 'cal' => 2.38846190642017E-01, + 'eV' => 6.24145700000000E+18, + 'ev' => 6.24145700000000E+18, + 'HPh' => 3.72506430801000E-07, + 'hh' => 3.72506430801000E-07, + 'Wh' => 2.77777916238711E-04, + 'wh' => 2.77777916238711E-04, + 'flb' => 2.37304222192651E+01, + 'BTU' => 9.47815067349015E-04, + 'btu' => 9.47815067349015E-04, ), - 'e' => array( - 'J' => 1.00000048065700E-07, - 'e' => 1.0, - 'c' => 2.39006364353494E-08, - 'cal' => 2.38846305445111E-08, - 'eV' => 6.24146000000000E+11, - 'ev' => 6.24146000000000E+11, - 'HPh' => 3.72506609848824E-14, - 'hh' => 3.72506609848824E-14, - 'Wh' => 2.77778049754611E-11, - 'wh' => 2.77778049754611E-11, - 'flb' => 2.37304336254586E-06, - 'BTU' => 9.47815522922962E-11, - 'btu' => 9.47815522922962E-11, + 'e' => array( + 'J' => 1.00000048065700E-07, + 'e' => 1.0, + 'c' => 2.39006364353494E-08, + 'cal' => 2.38846305445111E-08, + 'eV' => 6.24146000000000E+11, + 'ev' => 6.24146000000000E+11, + 'HPh' => 3.72506609848824E-14, + 'hh' => 3.72506609848824E-14, + 'Wh' => 2.77778049754611E-11, + 'wh' => 2.77778049754611E-11, + 'flb' => 2.37304336254586E-06, + 'BTU' => 9.47815522922962E-11, + 'btu' => 9.47815522922962E-11, ), - 'c' => array( - 'J' => 4.18399101363672E+00, - 'e' => 4.18398900257312E+07, - 'c' => 1.0, - 'cal' => 9.99330315287563E-01, - 'eV' => 2.61142000000000E+19, - 'ev' => 2.61142000000000E+19, - 'HPh' => 1.55856355899327E-06, - 'hh' => 1.55856355899327E-06, - 'Wh' => 1.16222030532950E-03, - 'wh' => 1.16222030532950E-03, - 'flb' => 9.92878733152102E+01, - 'BTU' => 3.96564972437776E-03, - 'btu' => 3.96564972437776E-03, + 'c' => array( + 'J' => 4.18399101363672E+00, + 'e' => 4.18398900257312E+07, + 'c' => 1.0, + 'cal' => 9.99330315287563E-01, + 'eV' => 2.61142000000000E+19, + 'ev' => 2.61142000000000E+19, + 'HPh' => 1.55856355899327E-06, + 'hh' => 1.55856355899327E-06, + 'Wh' => 1.16222030532950E-03, + 'wh' => 1.16222030532950E-03, + 'flb' => 9.92878733152102E+01, + 'BTU' => 3.96564972437776E-03, + 'btu' => 3.96564972437776E-03, ), 'cal' => array( - 'J' => 4.18679484613929E+00, - 'e' => 4.18679283372801E+07, - 'c' => 1.00067013349059E+00, - 'cal' => 1.0, - 'eV' => 2.61317000000000E+19, - 'ev' => 2.61317000000000E+19, - 'HPh' => 1.55960800463137E-06, - 'hh' => 1.55960800463137E-06, - 'Wh' => 1.16299914807955E-03, - 'wh' => 1.16299914807955E-03, - 'flb' => 9.93544094443283E+01, - 'BTU' => 3.96830723907002E-03, - 'btu' => 3.96830723907002E-03, + 'J' => 4.18679484613929E+00, + 'e' => 4.18679283372801E+07, + 'c' => 1.00067013349059E+00, + 'cal' => 1.0, + 'eV' => 2.61317000000000E+19, + 'ev' => 2.61317000000000E+19, + 'HPh' => 1.55960800463137E-06, + 'hh' => 1.55960800463137E-06, + 'Wh' => 1.16299914807955E-03, + 'wh' => 1.16299914807955E-03, + 'flb' => 9.93544094443283E+01, + 'BTU' => 3.96830723907002E-03, + 'btu' => 3.96830723907002E-03, ), 'eV' => array( - 'J' => 1.60219000146921E-19, - 'e' => 1.60218923136574E-12, - 'c' => 3.82933423195043E-20, - 'cal' => 3.82676978535648E-20, - 'eV' => 1.0, - 'ev' => 1.0, - 'HPh' => 5.96826078912344E-26, - 'hh' => 5.96826078912344E-26, - 'Wh' => 4.45053000026614E-23, - 'wh' => 4.45053000026614E-23, - 'flb' => 3.80206452103492E-18, - 'BTU' => 1.51857982414846E-22, - 'btu' => 1.51857982414846E-22, + 'J' => 1.60219000146921E-19, + 'e' => 1.60218923136574E-12, + 'c' => 3.82933423195043E-20, + 'cal' => 3.82676978535648E-20, + 'eV' => 1.0, + 'ev' => 1.0, + 'HPh' => 5.96826078912344E-26, + 'hh' => 5.96826078912344E-26, + 'Wh' => 4.45053000026614E-23, + 'wh' => 4.45053000026614E-23, + 'flb' => 3.80206452103492E-18, + 'BTU' => 1.51857982414846E-22, + 'btu' => 1.51857982414846E-22, ), 'ev' => array( - 'J' => 1.60219000146921E-19, - 'e' => 1.60218923136574E-12, - 'c' => 3.82933423195043E-20, - 'cal' => 3.82676978535648E-20, - 'eV' => 1.0, - 'ev' => 1.0, - 'HPh' => 5.96826078912344E-26, - 'hh' => 5.96826078912344E-26, - 'Wh' => 4.45053000026614E-23, - 'wh' => 4.45053000026614E-23, - 'flb' => 3.80206452103492E-18, - 'BTU' => 1.51857982414846E-22, - 'btu' => 1.51857982414846E-22, + 'J' => 1.60219000146921E-19, + 'e' => 1.60218923136574E-12, + 'c' => 3.82933423195043E-20, + 'cal' => 3.82676978535648E-20, + 'eV' => 1.0, + 'ev' => 1.0, + 'HPh' => 5.96826078912344E-26, + 'hh' => 5.96826078912344E-26, + 'Wh' => 4.45053000026614E-23, + 'wh' => 4.45053000026614E-23, + 'flb' => 3.80206452103492E-18, + 'BTU' => 1.51857982414846E-22, + 'btu' => 1.51857982414846E-22, ), 'HPh' => array( - 'J' => 2.68451741316170E+06, - 'e' => 2.68451612283024E+13, - 'c' => 6.41616438565991E+05, - 'cal' => 6.41186757845835E+05, - 'eV' => 1.67553000000000E+25, - 'ev' => 1.67553000000000E+25, - 'HPh' => 1.0, - 'hh' => 1.0, - 'Wh' => 7.45699653134593E+02, - 'wh' => 7.45699653134593E+02, - 'flb' => 6.37047316692964E+07, - 'BTU' => 2.54442605275546E+03, - 'btu' => 2.54442605275546E+03, + 'J' => 2.68451741316170E+06, + 'e' => 2.68451612283024E+13, + 'c' => 6.41616438565991E+05, + 'cal' => 6.41186757845835E+05, + 'eV' => 1.67553000000000E+25, + 'ev' => 1.67553000000000E+25, + 'HPh' => 1.0, + 'hh' => 1.0, + 'Wh' => 7.45699653134593E+02, + 'wh' => 7.45699653134593E+02, + 'flb' => 6.37047316692964E+07, + 'BTU' => 2.54442605275546E+03, + 'btu' => 2.54442605275546E+03, ), 'hh' => array( - 'J' => 2.68451741316170E+06, - 'e' => 2.68451612283024E+13, - 'c' => 6.41616438565991E+05, - 'cal' => 6.41186757845835E+05, - 'eV' => 1.67553000000000E+25, - 'ev' => 1.67553000000000E+25, - 'HPh' => 1.0, - 'hh' => 1.0, - 'Wh' => 7.45699653134593E+02, - 'wh' => 7.45699653134593E+02, - 'flb' => 6.37047316692964E+07, - 'BTU' => 2.54442605275546E+03, - 'btu' => 2.54442605275546E+03, + 'J' => 2.68451741316170E+06, + 'e' => 2.68451612283024E+13, + 'c' => 6.41616438565991E+05, + 'cal' => 6.41186757845835E+05, + 'eV' => 1.67553000000000E+25, + 'ev' => 1.67553000000000E+25, + 'HPh' => 1.0, + 'hh' => 1.0, + 'Wh' => 7.45699653134593E+02, + 'wh' => 7.45699653134593E+02, + 'flb' => 6.37047316692964E+07, + 'BTU' => 2.54442605275546E+03, + 'btu' => 2.54442605275546E+03, ), 'Wh' => array( - 'J' => 3.59999820554720E+03, - 'e' => 3.59999647518369E+10, - 'c' => 8.60422069219046E+02, - 'cal' => 8.59845857713046E+02, - 'eV' => 2.24692340000000E+22, - 'ev' => 2.24692340000000E+22, - 'HPh' => 1.34102248243839E-03, - 'hh' => 1.34102248243839E-03, - 'Wh' => 1.0, - 'wh' => 1.0, - 'flb' => 8.54294774062316E+04, - 'BTU' => 3.41213254164705E+00, - 'btu' => 3.41213254164705E+00, + 'J' => 3.59999820554720E+03, + 'e' => 3.59999647518369E+10, + 'c' => 8.60422069219046E+02, + 'cal' => 8.59845857713046E+02, + 'eV' => 2.24692340000000E+22, + 'ev' => 2.24692340000000E+22, + 'HPh' => 1.34102248243839E-03, + 'hh' => 1.34102248243839E-03, + 'Wh' => 1.0, + 'wh' => 1.0, + 'flb' => 8.54294774062316E+04, + 'BTU' => 3.41213254164705E+00, + 'btu' => 3.41213254164705E+00, ), 'wh' => array( - 'J' => 3.59999820554720E+03, - 'e' => 3.59999647518369E+10, - 'c' => 8.60422069219046E+02, - 'cal' => 8.59845857713046E+02, - 'eV' => 2.24692340000000E+22, - 'ev' => 2.24692340000000E+22, - 'HPh' => 1.34102248243839E-03, - 'hh' => 1.34102248243839E-03, - 'Wh' => 1.0, - 'wh' => 1.0, - 'flb' => 8.54294774062316E+04, - 'BTU' => 3.41213254164705E+00, - 'btu' => 3.41213254164705E+00, + 'J' => 3.59999820554720E+03, + 'e' => 3.59999647518369E+10, + 'c' => 8.60422069219046E+02, + 'cal' => 8.59845857713046E+02, + 'eV' => 2.24692340000000E+22, + 'ev' => 2.24692340000000E+22, + 'HPh' => 1.34102248243839E-03, + 'hh' => 1.34102248243839E-03, + 'Wh' => 1.0, + 'wh' => 1.0, + 'flb' => 8.54294774062316E+04, + 'BTU' => 3.41213254164705E+00, + 'btu' => 3.41213254164705E+00, ), 'flb' => array( - 'J' => 4.21400003236424E-02, - 'e' => 4.21399800687660E+05, - 'c' => 1.00717234301644E-02, - 'cal' => 1.00649785509554E-02, - 'eV' => 2.63015000000000E+17, - 'ev' => 2.63015000000000E+17, - 'HPh' => 1.56974211145130E-08, - 'hh' => 1.56974211145130E-08, - 'Wh' => 1.17055614802000E-05, - 'wh' => 1.17055614802000E-05, - 'flb' => 1.0, - 'BTU' => 3.99409272448406E-05, - 'btu' => 3.99409272448406E-05, + 'J' => 4.21400003236424E-02, + 'e' => 4.21399800687660E+05, + 'c' => 1.00717234301644E-02, + 'cal' => 1.00649785509554E-02, + 'eV' => 2.63015000000000E+17, + 'ev' => 2.63015000000000E+17, + 'HPh' => 1.56974211145130E-08, + 'hh' => 1.56974211145130E-08, + 'Wh' => 1.17055614802000E-05, + 'wh' => 1.17055614802000E-05, + 'flb' => 1.0, + 'BTU' => 3.99409272448406E-05, + 'btu' => 3.99409272448406E-05, ), 'BTU' => array( - 'J' => 1.05505813786749E+03, - 'e' => 1.05505763074665E+10, - 'c' => 2.52165488508168E+02, - 'cal' => 2.51996617135510E+02, - 'eV' => 6.58510000000000E+21, - 'ev' => 6.58510000000000E+21, - 'HPh' => 3.93015941224568E-04, - 'hh' => 3.93015941224568E-04, - 'Wh' => 2.93071851047526E-01, - 'wh' => 2.93071851047526E-01, - 'flb' => 2.50369750774671E+04, - 'BTU' => 1.0, - 'btu' => 1.0, + 'J' => 1.05505813786749E+03, + 'e' => 1.05505763074665E+10, + 'c' => 2.52165488508168E+02, + 'cal' => 2.51996617135510E+02, + 'eV' => 6.58510000000000E+21, + 'ev' => 6.58510000000000E+21, + 'HPh' => 3.93015941224568E-04, + 'hh' => 3.93015941224568E-04, + 'Wh' => 2.93071851047526E-01, + 'wh' => 2.93071851047526E-01, + 'flb' => 2.50369750774671E+04, + 'BTU' => 1.0, + 'btu' => 1.0, ), 'btu' => array( - 'J' => 1.05505813786749E+03, - 'e' => 1.05505763074665E+10, - 'c' => 2.52165488508168E+02, - 'cal' => 2.51996617135510E+02, - 'eV' => 6.58510000000000E+21, - 'ev' => 6.58510000000000E+21, - 'HPh' => 3.93015941224568E-04, - 'hh' => 3.93015941224568E-04, - 'Wh' => 2.93071851047526E-01, - 'wh' => 2.93071851047526E-01, - 'flb' => 2.50369750774671E+04, - 'BTU' => 1.0, - 'btu' => 1.0, + 'J' => 1.05505813786749E+03, + 'e' => 1.05505763074665E+10, + 'c' => 2.52165488508168E+02, + 'cal' => 2.51996617135510E+02, + 'eV' => 6.58510000000000E+21, + 'ev' => 6.58510000000000E+21, + 'HPh' => 3.93015941224568E-04, + 'hh' => 3.93015941224568E-04, + 'Wh' => 2.93071851047526E-01, + 'wh' => 2.93071851047526E-01, + 'flb' => 2.50369750774671E+04, + 'BTU' => 1.0, + 'btu' => 1.0, ), ), - 'Power' => array( + 'Power' => array( 'HP' => array( - 'HP' => 1.0, - 'h' => 1.0, - 'W' => 7.45701000000000E+02, - 'w' => 7.45701000000000E+02, + 'HP' => 1.0, + 'h' => 1.0, + 'W' => 7.45701000000000E+02, + 'w' => 7.45701000000000E+02, ), - 'h' => array( - 'HP' => 1.0, - 'h' => 1.0, - 'W' => 7.45701000000000E+02, - 'w' => 7.45701000000000E+02, + 'h' => array( + 'HP' => 1.0, + 'h' => 1.0, + 'W' => 7.45701000000000E+02, + 'w' => 7.45701000000000E+02, ), - 'W' => array( - 'HP' => 1.34102006031908E-03, - 'h' => 1.34102006031908E-03, - 'W' => 1.0, - 'w' => 1.0, + 'W' => array( + 'HP' => 1.34102006031908E-03, + 'h' => 1.34102006031908E-03, + 'W' => 1.0, + 'w' => 1.0, ), - 'w' => array( - 'HP' => 1.34102006031908E-03, - 'h' => 1.34102006031908E-03, - 'W' => 1.0, - 'w' => 1.0, + 'w' => array( + 'HP' => 1.34102006031908E-03, + 'h' => 1.34102006031908E-03, + 'W' => 1.0, + 'w' => 1.0, ), ), 'Magnetism' => array( - 'T' => array( - 'T' => 1.0, - 'ga' => 10000.0, + 'T' => array( + 'T' => 1.0, + 'ga' => 10000.0, ), 'ga' => array( - 'T' => 0.0001, - 'ga' => 1.0, + 'T' => 0.0001, + 'ga' => 1.0, ), ), 'Liquid' => array( 'tsp' => array( - 'tsp' => 1.0, - 'tbs' => 3.33333333333333E-01, - 'oz' => 1.66666666666667E-01, - 'cup' => 2.08333333333333E-02, - 'pt' => 1.04166666666667E-02, - 'us_pt' => 1.04166666666667E-02, - 'uk_pt' => 8.67558516821960E-03, - 'qt' => 5.20833333333333E-03, - 'gal' => 1.30208333333333E-03, - 'l' => 4.92999408400710E-03, - 'lt' => 4.92999408400710E-03, + 'tsp' => 1.0, + 'tbs' => 3.33333333333333E-01, + 'oz' => 1.66666666666667E-01, + 'cup' => 2.08333333333333E-02, + 'pt' => 1.04166666666667E-02, + 'us_pt' => 1.04166666666667E-02, + 'uk_pt' => 8.67558516821960E-03, + 'qt' => 5.20833333333333E-03, + 'gal' => 1.30208333333333E-03, + 'l' => 4.92999408400710E-03, + 'lt' => 4.92999408400710E-03, ), 'tbs' => array( - 'tsp' => 3.00000000000000E+00, - 'tbs' => 1.0, - 'oz' => 5.00000000000000E-01, - 'cup' => 6.25000000000000E-02, - 'pt' => 3.12500000000000E-02, - 'us_pt' => 3.12500000000000E-02, - 'uk_pt' => 2.60267555046588E-02, - 'qt' => 1.56250000000000E-02, - 'gal' => 3.90625000000000E-03, - 'l' => 1.47899822520213E-02, - 'lt' => 1.47899822520213E-02, + 'tsp' => 3.00000000000000E+00, + 'tbs' => 1.0, + 'oz' => 5.00000000000000E-01, + 'cup' => 6.25000000000000E-02, + 'pt' => 3.12500000000000E-02, + 'us_pt' => 3.12500000000000E-02, + 'uk_pt' => 2.60267555046588E-02, + 'qt' => 1.56250000000000E-02, + 'gal' => 3.90625000000000E-03, + 'l' => 1.47899822520213E-02, + 'lt' => 1.47899822520213E-02, ), 'oz' => array( - 'tsp' => 6.00000000000000E+00, - 'tbs' => 2.00000000000000E+00, - 'oz' => 1.0, - 'cup' => 1.25000000000000E-01, - 'pt' => 6.25000000000000E-02, - 'us_pt' => 6.25000000000000E-02, - 'uk_pt' => 5.20535110093176E-02, - 'qt' => 3.12500000000000E-02, - 'gal' => 7.81250000000000E-03, - 'l' => 2.95799645040426E-02, - 'lt' => 2.95799645040426E-02, + 'tsp' => 6.00000000000000E+00, + 'tbs' => 2.00000000000000E+00, + 'oz' => 1.0, + 'cup' => 1.25000000000000E-01, + 'pt' => 6.25000000000000E-02, + 'us_pt' => 6.25000000000000E-02, + 'uk_pt' => 5.20535110093176E-02, + 'qt' => 3.12500000000000E-02, + 'gal' => 7.81250000000000E-03, + 'l' => 2.95799645040426E-02, + 'lt' => 2.95799645040426E-02, ), 'cup' => array( - 'tsp' => 4.80000000000000E+01, - 'tbs' => 1.60000000000000E+01, - 'oz' => 8.00000000000000E+00, - 'cup' => 1.0, - 'pt' => 5.00000000000000E-01, - 'us_pt' => 5.00000000000000E-01, - 'uk_pt' => 4.16428088074541E-01, - 'qt' => 2.50000000000000E-01, - 'gal' => 6.25000000000000E-02, - 'l' => 2.36639716032341E-01, - 'lt' => 2.36639716032341E-01, + 'tsp' => 4.80000000000000E+01, + 'tbs' => 1.60000000000000E+01, + 'oz' => 8.00000000000000E+00, + 'cup' => 1.0, + 'pt' => 5.00000000000000E-01, + 'us_pt' => 5.00000000000000E-01, + 'uk_pt' => 4.16428088074541E-01, + 'qt' => 2.50000000000000E-01, + 'gal' => 6.25000000000000E-02, + 'l' => 2.36639716032341E-01, + 'lt' => 2.36639716032341E-01, ), 'pt' => array( - 'tsp' => 9.60000000000000E+01, - 'tbs' => 3.20000000000000E+01, - 'oz' => 1.60000000000000E+01, - 'cup' => 2.00000000000000E+00, - 'pt' => 1.0, - 'us_pt' => 1.0, - 'uk_pt' => 8.32856176149081E-01, - 'qt' => 5.00000000000000E-01, - 'gal' => 1.25000000000000E-01, - 'l' => 4.73279432064682E-01, - 'lt' => 4.73279432064682E-01, + 'tsp' => 9.60000000000000E+01, + 'tbs' => 3.20000000000000E+01, + 'oz' => 1.60000000000000E+01, + 'cup' => 2.00000000000000E+00, + 'pt' => 1.0, + 'us_pt' => 1.0, + 'uk_pt' => 8.32856176149081E-01, + 'qt' => 5.00000000000000E-01, + 'gal' => 1.25000000000000E-01, + 'l' => 4.73279432064682E-01, + 'lt' => 4.73279432064682E-01, ), 'us_pt' => array( - 'tsp' => 9.60000000000000E+01, - 'tbs' => 3.20000000000000E+01, - 'oz' => 1.60000000000000E+01, - 'cup' => 2.00000000000000E+00, - 'pt' => 1.0, - 'us_pt' => 1.0, - 'uk_pt' => 8.32856176149081E-01, - 'qt' => 5.00000000000000E-01, - 'gal' => 1.25000000000000E-01, - 'l' => 4.73279432064682E-01, - 'lt' => 4.73279432064682E-01, + 'tsp' => 9.60000000000000E+01, + 'tbs' => 3.20000000000000E+01, + 'oz' => 1.60000000000000E+01, + 'cup' => 2.00000000000000E+00, + 'pt' => 1.0, + 'us_pt' => 1.0, + 'uk_pt' => 8.32856176149081E-01, + 'qt' => 5.00000000000000E-01, + 'gal' => 1.25000000000000E-01, + 'l' => 4.73279432064682E-01, + 'lt' => 4.73279432064682E-01, ), 'uk_pt' => array( - 'tsp' => 1.15266000000000E+02, - 'tbs' => 3.84220000000000E+01, - 'oz' => 1.92110000000000E+01, - 'cup' => 2.40137500000000E+00, - 'pt' => 1.20068750000000E+00, - 'us_pt' => 1.20068750000000E+00, - 'uk_pt' => 1.0, - 'qt' => 6.00343750000000E-01, - 'gal' => 1.50085937500000E-01, - 'l' => 5.68260698087162E-01, - 'lt' => 5.68260698087162E-01, + 'tsp' => 1.15266000000000E+02, + 'tbs' => 3.84220000000000E+01, + 'oz' => 1.92110000000000E+01, + 'cup' => 2.40137500000000E+00, + 'pt' => 1.20068750000000E+00, + 'us_pt' => 1.20068750000000E+00, + 'uk_pt' => 1.0, + 'qt' => 6.00343750000000E-01, + 'gal' => 1.50085937500000E-01, + 'l' => 5.68260698087162E-01, + 'lt' => 5.68260698087162E-01, ), 'qt' => array( - 'tsp' => 1.92000000000000E+02, - 'tbs' => 6.40000000000000E+01, - 'oz' => 3.20000000000000E+01, - 'cup' => 4.00000000000000E+00, - 'pt' => 2.00000000000000E+00, - 'us_pt' => 2.00000000000000E+00, - 'uk_pt' => 1.66571235229816E+00, - 'qt' => 1.0, - 'gal' => 2.50000000000000E-01, - 'l' => 9.46558864129363E-01, - 'lt' => 9.46558864129363E-01, + 'tsp' => 1.92000000000000E+02, + 'tbs' => 6.40000000000000E+01, + 'oz' => 3.20000000000000E+01, + 'cup' => 4.00000000000000E+00, + 'pt' => 2.00000000000000E+00, + 'us_pt' => 2.00000000000000E+00, + 'uk_pt' => 1.66571235229816E+00, + 'qt' => 1.0, + 'gal' => 2.50000000000000E-01, + 'l' => 9.46558864129363E-01, + 'lt' => 9.46558864129363E-01, ), 'gal' => array( - 'tsp' => 7.68000000000000E+02, - 'tbs' => 2.56000000000000E+02, - 'oz' => 1.28000000000000E+02, - 'cup' => 1.60000000000000E+01, - 'pt' => 8.00000000000000E+00, - 'us_pt' => 8.00000000000000E+00, - 'uk_pt' => 6.66284940919265E+00, - 'qt' => 4.00000000000000E+00, - 'gal' => 1.0, - 'l' => 3.78623545651745E+00, - 'lt' => 3.78623545651745E+00, + 'tsp' => 7.68000000000000E+02, + 'tbs' => 2.56000000000000E+02, + 'oz' => 1.28000000000000E+02, + 'cup' => 1.60000000000000E+01, + 'pt' => 8.00000000000000E+00, + 'us_pt' => 8.00000000000000E+00, + 'uk_pt' => 6.66284940919265E+00, + 'qt' => 4.00000000000000E+00, + 'gal' => 1.0, + 'l' => 3.78623545651745E+00, + 'lt' => 3.78623545651745E+00, ), - 'l' => array( - 'tsp' => 2.02840000000000E+02, - 'tbs' => 6.76133333333333E+01, - 'oz' => 3.38066666666667E+01, - 'cup' => 4.22583333333333E+00, - 'pt' => 2.11291666666667E+00, - 'us_pt' => 2.11291666666667E+00, - 'uk_pt' => 1.75975569552166E+00, - 'qt' => 1.05645833333333E+00, - 'gal' => 2.64114583333333E-01, - 'l' => 1.0, - 'lt' => 1.0, + 'l' => array( + 'tsp' => 2.02840000000000E+02, + 'tbs' => 6.76133333333333E+01, + 'oz' => 3.38066666666667E+01, + 'cup' => 4.22583333333333E+00, + 'pt' => 2.11291666666667E+00, + 'us_pt' => 2.11291666666667E+00, + 'uk_pt' => 1.75975569552166E+00, + 'qt' => 1.05645833333333E+00, + 'gal' => 2.64114583333333E-01, + 'l' => 1.0, + 'lt' => 1.0, ), 'lt' => array( - 'tsp' => 2.02840000000000E+02, - 'tbs' => 6.76133333333333E+01, - 'oz' => 3.38066666666667E+01, - 'cup' => 4.22583333333333E+00, - 'pt' => 2.11291666666667E+00, - 'us_pt' => 2.11291666666667E+00, - 'uk_pt' => 1.75975569552166E+00, - 'qt' => 1.05645833333333E+00, - 'gal' => 2.64114583333333E-01, - 'l' => 1.0, - 'lt' => 1.0, + 'tsp' => 2.02840000000000E+02, + 'tbs' => 6.76133333333333E+01, + 'oz' => 3.38066666666667E+01, + 'cup' => 4.22583333333333E+00, + 'pt' => 2.11291666666667E+00, + 'us_pt' => 2.11291666666667E+00, + 'uk_pt' => 1.75975569552166E+00, + 'qt' => 1.05645833333333E+00, + 'gal' => 2.64114583333333E-01, + 'l' => 1.0, + 'lt' => 1.0, ), ), ); /** - * _parseComplex + * parseComplex * * Parses a complex number into its real and imaginary parts, and an I or J suffix * * @param string $complexNumber The complex number * @return string[] Indexed on "real", "imaginary" and "suffix" */ - public static function _parseComplex($complexNumber) + public static function parseComplex($complexNumber) { $workString = (string) $complexNumber; @@ -817,7 +807,7 @@ public static function _parseComplex($complexNumber) * @param string $complexNumber The complex number to clean * @return string The "cleaned" complex number */ - private static function _cleanComplex($complexNumber) + private static function cleanComplex($complexNumber) { if ($complexNumber{0} == '+') { $complexNumber = substr($complexNumber, 1); @@ -841,7 +831,7 @@ private static function _cleanComplex($complexNumber) * @param integer $places The length that we want to pad this value * @return string The padded "number" */ - private static function _nbrConversionFormat($xVal, $places) + private static function nbrConversionFormat($xVal, $places) { if (!is_null($places)) { if (strlen($xVal) <= $places) { @@ -964,7 +954,7 @@ public static function BESSELJ($x, $ord) } - private static function _Besselk0($fNum) + private static function besselK0($fNum) { if ($fNum <= 2) { $fNum2 = $fNum * 0.5; @@ -982,7 +972,7 @@ private static function _Besselk0($fNum) } - private static function _Besselk1($fNum) + private static function besselK1($fNum) { if ($fNum <= 2) { $fNum2 = $fNum * 0.5; @@ -1031,13 +1021,13 @@ public static function BESSELK($x, $ord) switch(floor($ord)) { case 0: - return self::_Besselk0($x); + return self::besselK0($x); case 1: - return self::_Besselk1($x); + return self::besselK1($x); default: $fTox = 2 / $x; - $fBkm = self::_Besselk0($x); - $fBk = self::_Besselk1($x); + $fBkm = self::besselK0($x); + $fBk = self::besselK1($x); for ($n = 1; $n < $ord; ++$n) { $fBkp = $fBkm + $n * $fTox * $fBk; $fBkm = $fBk; @@ -1050,7 +1040,7 @@ public static function BESSELK($x, $ord) } - private static function _Bessely0($fNum) + private static function besselY0($fNum) { if ($fNum < 8.0) { $y = ($fNum * $fNum); @@ -1069,7 +1059,7 @@ private static function _Bessely0($fNum) } - private static function _Bessely1($fNum) + private static function besselY1($fNum) { if ($fNum < 8.0) { $y = ($fNum * $fNum); @@ -1115,13 +1105,13 @@ public static function BESSELY($x, $ord) switch(floor($ord)) { case 0: - return self::_Bessely0($x); + return self::besselY0($x); case 1: - return self::_Bessely1($x); + return self::besselY1($x); default: $fTox = 2 / $x; - $fBym = self::_Bessely0($x); - $fBy = self::_Bessely1($x); + $fBym = self::besselY0($x); + $fBy = self::besselY1($x); for ($n = 1; $n < $ord; ++$n) { $fByp = $n * $fTox * $fBy - $fBym; $fBym = $fBy; @@ -1232,7 +1222,7 @@ public static function BINTOHEX($x, $places = null) } $hexVal = (string) strtoupper(dechex(bindec($x))); - return self::_nbrConversionFormat($hexVal, $places); + return self::nbrConversionFormat($hexVal, $places); } @@ -1287,7 +1277,7 @@ public static function BINTOOCT($x, $places = null) } $octVal = (string) decoct(bindec($x)); - return self::_nbrConversionFormat($octVal, $places); + return self::nbrConversionFormat($octVal, $places); } @@ -1344,7 +1334,7 @@ public static function DECTOBIN($x, $places = null) return PHPExcel_Calculation_Functions::NaN(); } - return self::_nbrConversionFormat($r, $places); + return self::nbrConversionFormat($r, $places); } @@ -1399,7 +1389,7 @@ public static function DECTOHEX($x, $places = null) $r = 'FF'.$r; } - return self::_nbrConversionFormat($r, $places); + return self::nbrConversionFormat($r, $places); } @@ -1454,7 +1444,7 @@ public static function DECTOOCT($x, $places = null) $r = substr($r, -10); } - return self::_nbrConversionFormat($r, $places); + return self::nbrConversionFormat($r, $places); } @@ -1503,7 +1493,7 @@ public static function HEXTOBIN($x, $places = null) } $binVal = decbin(hexdec($x)); - return substr(self::_nbrConversionFormat($binVal, $places), -10); + return substr(self::nbrConversionFormat($binVal, $places), -10); } @@ -1587,7 +1577,7 @@ public static function HEXTOOCT($x, $places = null) } $octVal = decoct(hexdec($x)); - return self::_nbrConversionFormat($octVal, $places); + return self::nbrConversionFormat($octVal, $places); } // function HEXTOOCT() @@ -1639,7 +1629,7 @@ public static function OCTTOBIN($x, $places = null) } $r = decbin(octdec($x)); - return self::_nbrConversionFormat($r, $places); + return self::nbrConversionFormat($r, $places); } @@ -1720,7 +1710,7 @@ public static function OCTTOHEX($x, $places = null) } $hexVal = strtoupper(dechex(octdec($x))); - return self::_nbrConversionFormat($hexVal, $places); + return self::nbrConversionFormat($hexVal, $places); } @@ -1798,7 +1788,7 @@ public static function IMAGINARY($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); return $parsedComplex['imaginary']; } @@ -1820,7 +1810,7 @@ public static function IMREAL($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); return $parsedComplex['real']; } @@ -1840,7 +1830,7 @@ public static function IMABS($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); return sqrt( ($parsedComplex['real'] * $parsedComplex['real']) + @@ -1865,7 +1855,7 @@ public static function IMARGUMENT($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); if ($parsedComplex['real'] == 0.0) { if ($parsedComplex['imaginary'] == 0.0) { @@ -1900,12 +1890,12 @@ public static function IMCONJUGATE($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); if ($parsedComplex['imaginary'] == 0.0) { return $parsedComplex['real']; } else { - return self::_cleanComplex( + return self::cleanComplex( self::COMPLEX( $parsedComplex['real'], 0 - $parsedComplex['imaginary'], @@ -1931,7 +1921,7 @@ public static function IMCOS($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); if ($parsedComplex['imaginary'] == 0.0) { return cos($parsedComplex['real']); @@ -1962,7 +1952,7 @@ public static function IMSIN($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); if ($parsedComplex['imaginary'] == 0.0) { return sin($parsedComplex['real']); @@ -1991,7 +1981,7 @@ public static function IMSQRT($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); $theta = self::IMARGUMENT($complexNumber); $d1 = cos($theta / 2); @@ -2021,7 +2011,7 @@ public static function IMLN($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { return PHPExcel_Calculation_Functions::NaN(); @@ -2053,7 +2043,7 @@ public static function IMLOG10($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { return PHPExcel_Calculation_Functions::NaN(); @@ -2080,7 +2070,7 @@ public static function IMLOG2($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { return PHPExcel_Calculation_Functions::NaN(); @@ -2107,7 +2097,7 @@ public static function IMEXP($complexNumber) { $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { return '1'; @@ -2146,7 +2136,7 @@ public static function IMPOWER($complexNumber, $realNumber) return PHPExcel_Calculation_Functions::VALUE(); } - $parsedComplex = self::_parseComplex($complexNumber); + $parsedComplex = self::parseComplex($complexNumber); $r = sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])); $rPower = pow($r, $realNumber); @@ -2178,8 +2168,8 @@ public static function IMDIV($complexDividend, $complexDivisor) $complexDividend = PHPExcel_Calculation_Functions::flattenSingleValue($complexDividend); $complexDivisor = PHPExcel_Calculation_Functions::flattenSingleValue($complexDivisor); - $parsedComplexDividend = self::_parseComplex($complexDividend); - $parsedComplexDivisor = self::_parseComplex($complexDivisor); + $parsedComplexDividend = self::parseComplex($complexDividend); + $parsedComplexDivisor = self::parseComplex($complexDivisor); if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] != '') && ($parsedComplexDividend['suffix'] != $parsedComplexDivisor['suffix'])) { @@ -2197,9 +2187,9 @@ public static function IMDIV($complexDividend, $complexDivisor) $i = $d2 / $d3; if ($i > 0.0) { - return self::_cleanComplex($r.'+'.$i.$parsedComplexDivisor['suffix']); + return self::cleanComplex($r.'+'.$i.$parsedComplexDivisor['suffix']); } elseif ($i < 0.0) { - return self::_cleanComplex($r.$i.$parsedComplexDivisor['suffix']); + return self::cleanComplex($r.$i.$parsedComplexDivisor['suffix']); } else { return $r; } @@ -2223,8 +2213,8 @@ public static function IMSUB($complexNumber1, $complexNumber2) $complexNumber1 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber1); $complexNumber2 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber2); - $parsedComplex1 = self::_parseComplex($complexNumber1); - $parsedComplex2 = self::_parseComplex($complexNumber2); + $parsedComplex1 = self::parseComplex($complexNumber1); + $parsedComplex2 = self::parseComplex($complexNumber2); if ((($parsedComplex1['suffix'] != '') && ($parsedComplex2['suffix'] != '')) && ($parsedComplex1['suffix'] != $parsedComplex2['suffix'])) { @@ -2236,7 +2226,7 @@ public static function IMSUB($complexNumber1, $complexNumber2) $d1 = $parsedComplex1['real'] - $parsedComplex2['real']; $d2 = $parsedComplex1['imaginary'] - $parsedComplex2['imaginary']; - return self::COMPLEX($d1,$d2,$parsedComplex1['suffix']); + return self::COMPLEX($d1, $d2, $parsedComplex1['suffix']); } @@ -2254,13 +2244,13 @@ public static function IMSUB($complexNumber1, $complexNumber2) public static function IMSUM() { // Return value - $returnValue = self::_parseComplex('0'); + $returnValue = self::parseComplex('0'); $activeSuffix = ''; // Loop through the arguments $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); foreach ($aArgs as $arg) { - $parsedComplex = self::_parseComplex($arg); + $parsedComplex = self::parseComplex($arg); if ($activeSuffix == '') { $activeSuffix = $parsedComplex['suffix']; @@ -2275,7 +2265,7 @@ public static function IMSUM() if ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; } - return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix); + return self::COMPLEX($returnValue['real'], $returnValue['imaginary'], $activeSuffix); } @@ -2293,13 +2283,13 @@ public static function IMSUM() public static function IMPRODUCT() { // Return value - $returnValue = self::_parseComplex('1'); + $returnValue = self::parseComplex('1'); $activeSuffix = ''; // Loop through the arguments $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); foreach ($aArgs as $arg) { - $parsedComplex = self::_parseComplex($arg); + $parsedComplex = self::parseComplex($arg); $workValue = $returnValue; if (($parsedComplex['suffix'] != '') && ($activeSuffix == '')) { @@ -2314,7 +2304,7 @@ public static function IMPRODUCT() if ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; } - return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix); + return self::COMPLEX($returnValue['real'], $returnValue['imaginary'], $activeSuffix); } @@ -2369,12 +2359,12 @@ public static function GESTEP($number, $step = 0) // // Private method to calculate the erf value // - private static $_two_sqrtpi = 1.128379167095512574; + private static $twoSqrtPi = 1.128379167095512574; - public static function _erfVal($x) + public static function erfVal($x) { if (abs($x) > 2.2) { - return 1 - self::_erfcVal($x); + return 1 - self::erfcVal($x); } $sum = $term = $x; $xsqr = ($x * $x); @@ -2390,7 +2380,7 @@ public static function _erfVal($x) break; } } while (abs($term / $sum) > PRECISION); - return self::$_two_sqrtpi * $sum; + return self::$twoSqrtPi * $sum; } @@ -2419,10 +2409,10 @@ public static function ERF($lower, $upper = null) if (is_numeric($lower)) { if (is_null($upper)) { - return self::_erfVal($lower); + return self::erfVal($lower); } if (is_numeric($upper)) { - return self::_erfVal($upper) - self::_erfVal($lower); + return self::erfVal($upper) - self::erfVal($lower); } } return PHPExcel_Calculation_Functions::VALUE(); @@ -2432,12 +2422,12 @@ public static function ERF($lower, $upper = null) // // Private method to calculate the erfc value // - private static $_one_sqrtpi = 0.564189583547756287; + private static $oneSqrtPi = 0.564189583547756287; - private static function _erfcVal($x) + private static function erfcVal($x) { if (abs($x) < 2.2) { - return 1 - self::_erfVal($x); + return 1 - self::erfVal($x); } if ($x < 0) { return 2 - self::ERFC(-$x); @@ -2458,7 +2448,7 @@ private static function _erfcVal($x) $q1 = $q2; $q2 = $b / $d; } while ((abs($q1 - $q2) / $q2) > PRECISION); - return self::$_one_sqrtpi * exp(-$x * $x) * $q2; + return self::$oneSqrtPi * exp(-$x * $x) * $q2; } @@ -2483,7 +2473,7 @@ public static function ERFC($x) $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); if (is_numeric($x)) { - return self::_erfcVal($x); + return self::erfcVal($x); } return PHPExcel_Calculation_Functions::VALUE(); } @@ -2498,7 +2488,7 @@ public static function ERFC($x) public static function getConversionGroups() { $conversionGroups = array(); - foreach (self::$_conversionUnits as $conversionUnit) { + foreach (self::$conversionUnits as $conversionUnit) { $conversionGroups[] = $conversionUnit['Group']; } return array_merge(array_unique($conversionGroups)); @@ -2515,7 +2505,7 @@ public static function getConversionGroups() public static function getConversionGroupUnits($group = null) { $conversionGroups = array(); - foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) { + foreach (self::$conversionUnits as $conversionUnit => $conversionGroup) { if ((is_null($group)) || ($conversionGroup['Group'] == $group)) { $conversionGroups[$conversionGroup['Group']][] = $conversionUnit; } @@ -2533,7 +2523,7 @@ public static function getConversionGroupUnits($group = null) public static function getConversionGroupUnitDetails($group = null) { $conversionGroups = array(); - foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) { + foreach (self::$conversionUnits as $conversionUnit => $conversionGroup) { if ((is_null($group)) || ($conversionGroup['Group'] == $group)) { $conversionGroups[$conversionGroup['Group']][] = array( 'unit' => $conversionUnit, @@ -2553,7 +2543,7 @@ public static function getConversionGroupUnitDetails($group = null) */ public static function getConversionMultipliers() { - return self::$_conversionMultipliers; + return self::$conversionMultipliers; } @@ -2583,18 +2573,18 @@ public static function CONVERTUOM($value, $fromUOM, $toUOM) return PHPExcel_Calculation_Functions::VALUE(); } $fromMultiplier = 1.0; - if (isset(self::$_conversionUnits[$fromUOM])) { - $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group']; + if (isset(self::$conversionUnits[$fromUOM])) { + $unitGroup1 = self::$conversionUnits[$fromUOM]['Group']; } else { - $fromMultiplier = substr($fromUOM,0,1); - $fromUOM = substr($fromUOM,1); - if (isset(self::$_conversionMultipliers[$fromMultiplier])) { - $fromMultiplier = self::$_conversionMultipliers[$fromMultiplier]['multiplier']; + $fromMultiplier = substr($fromUOM, 0, 1); + $fromUOM = substr($fromUOM, 1); + if (isset(self::$conversionMultipliers[$fromMultiplier])) { + $fromMultiplier = self::$conversionMultipliers[$fromMultiplier]['multiplier']; } else { return PHPExcel_Calculation_Functions::NA(); } - if ((isset(self::$_conversionUnits[$fromUOM])) && (self::$_conversionUnits[$fromUOM]['AllowPrefix'])) { - $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group']; + if ((isset(self::$conversionUnits[$fromUOM])) && (self::$conversionUnits[$fromUOM]['AllowPrefix'])) { + $unitGroup1 = self::$conversionUnits[$fromUOM]['Group']; } else { return PHPExcel_Calculation_Functions::NA(); } @@ -2602,18 +2592,18 @@ public static function CONVERTUOM($value, $fromUOM, $toUOM) $value *= $fromMultiplier; $toMultiplier = 1.0; - if (isset(self::$_conversionUnits[$toUOM])) { - $unitGroup2 = self::$_conversionUnits[$toUOM]['Group']; + if (isset(self::$conversionUnits[$toUOM])) { + $unitGroup2 = self::$conversionUnits[$toUOM]['Group']; } else { - $toMultiplier = substr($toUOM,0,1); - $toUOM = substr($toUOM,1); - if (isset(self::$_conversionMultipliers[$toMultiplier])) { - $toMultiplier = self::$_conversionMultipliers[$toMultiplier]['multiplier']; + $toMultiplier = substr($toUOM, 0, 1); + $toUOM = substr($toUOM, 1); + if (isset(self::$conversionMultipliers[$toMultiplier])) { + $toMultiplier = self::$conversionMultipliers[$toMultiplier]['multiplier']; } else { return PHPExcel_Calculation_Functions::NA(); } - if ((isset(self::$_conversionUnits[$toUOM])) && (self::$_conversionUnits[$toUOM]['AllowPrefix'])) { - $unitGroup2 = self::$_conversionUnits[$toUOM]['Group']; + if ((isset(self::$conversionUnits[$toUOM])) && (self::$conversionUnits[$toUOM]['AllowPrefix'])) { + $unitGroup2 = self::$conversionUnits[$toUOM]['Group']; } else { return PHPExcel_Calculation_Functions::NA(); } @@ -2655,6 +2645,6 @@ public static function CONVERTUOM($value, $fromUOM, $toUOM) } return $value + 273.15; } - return ($value * self::$_unitConversions[$unitGroup1][$fromUOM][$toUOM]) / $toMultiplier; + return ($value * self::$unitConversions[$unitGroup1][$fromUOM][$toUOM]) / $toMultiplier; } } diff --git a/Classes/PHPExcel/Calculation/Exception.php b/Classes/PHPExcel/Calculation/Exception.php index bd6e22f11..52d73fc4f 100644 --- a/Classes/PHPExcel/Calculation/Exception.php +++ b/Classes/PHPExcel/Calculation/Exception.php @@ -1,6 +1,7 @@ line = $line; $e->file = $file; diff --git a/Classes/PHPExcel/Calculation/ExceptionHandler.php b/Classes/PHPExcel/Calculation/ExceptionHandler.php index 4f3d247d1..4cb0a6880 100644 --- a/Classes/PHPExcel/Calculation/ExceptionHandler.php +++ b/Classes/PHPExcel/Calculation/ExceptionHandler.php @@ -1,6 +1,7 @@ format('d') == $testDate->format('t')); - } // function _lastDayOfMonth() + } /** - * _firstDayOfMonth + * isFirstDayOfMonth * * Returns a boolean TRUE/FALSE indicating if this date is the first date of the month * * @param DateTime $testDate The date for testing * @return boolean */ - private static function _firstDayOfMonth($testDate) + private static function isFirstDayOfMonth($testDate) { return ($testDate->format('d') == 1); - } // function _firstDayOfMonth() + } - private static function _coupFirstPeriodDate($settlement, $maturity, $frequency, $next) + private static function couponFirstPeriodDate($settlement, $maturity, $frequency, $next) { $months = 12 / $frequency; $result = PHPExcel_Shared_Date::ExcelToPHPObject($maturity); - $eom = self::_lastDayOfMonth($result); + $eom = self::isLastDayOfMonth($result); while ($settlement < PHPExcel_Shared_Date::PHPToExcel($result)) { $result->modify('-'.$months.' months'); @@ -99,10 +89,10 @@ private static function _coupFirstPeriodDate($settlement, $maturity, $frequency, } return PHPExcel_Shared_Date::PHPToExcel($result); - } // function _coupFirstPeriodDate() + } - private static function _validFrequency($frequency) + private static function isValidFrequency($frequency) { if (($frequency == 1) || ($frequency == 2) || ($frequency == 4)) { return true; @@ -112,11 +102,11 @@ private static function _validFrequency($frequency) return true; } return false; - } // function _validFrequency() + } /** - * _daysPerYear + * daysPerYear * * Returns the number of days in a specified year, as defined by the "basis" value * @@ -129,28 +119,28 @@ private static function _validFrequency($frequency) * 4 European 360 * @return integer */ - private static function _daysPerYear($year, $basis=0) + private static function daysPerYear($year, $basis = 0) { switch ($basis) { - case 0 : - case 2 : - case 4 : + case 0: + case 2: + case 4: $daysPerYear = 360; break; - case 3 : + case 3: $daysPerYear = 365; break; - case 1 : + case 1: $daysPerYear = (PHPExcel_Calculation_DateTime::isLeapYear($year)) ? 366 : 365; break; - default : + default: return PHPExcel_Calculation_Functions::NaN(); } return $daysPerYear; - } // function _daysPerYear() + } - private static function _interestAndPrincipal($rate=0, $per=0, $nper=0, $pv=0, $fv=0, $type=0) + private static function interestAndPrincipal($rate = 0, $per = 0, $nper = 0, $pv = 0, $fv = 0, $type = 0) { $pmt = self::PMT($rate, $nper, $pv, $fv, $type); $capital = $pv; @@ -160,7 +150,7 @@ private static function _interestAndPrincipal($rate=0, $per=0, $nper=0, $pv=0, $ $capital += $principal; } return array($interest, $principal); - } // function _interestAndPrincipal() + } /** @@ -198,7 +188,7 @@ private static function _interestAndPrincipal($rate=0, $per=0, $nper=0, $pv=0, $ * 4 European 30/360 * @return float */ - public static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par=1000, $frequency=1, $basis=0) + public static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par = 1000, $frequency = 1, $basis = 0) { $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); $firstinterest = PHPExcel_Calculation_Functions::flattenSingleValue($firstinterest); @@ -224,7 +214,7 @@ public static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par= return $par * $rate * $daysBetweenIssueAndSettlement; } return PHPExcel_Calculation_Functions::VALUE(); - } // function ACCRINT() + } /** @@ -250,7 +240,8 @@ public static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par= * 4 European 30/360 * @return float */ - public static function ACCRINTM($issue, $settlement, $rate, $par=1000, $basis=0) { + public static function ACCRINTM($issue, $settlement, $rate, $par = 1000, $basis = 0) + { $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); @@ -272,7 +263,7 @@ public static function ACCRINTM($issue, $settlement, $rate, $par=1000, $basis=0) return $par * $rate * $daysBetweenIssueAndSettlement; } return PHPExcel_Calculation_Functions::VALUE(); - } // function ACCRINTM() + } /** @@ -306,7 +297,8 @@ public static function ACCRINTM($issue, $settlement, $rate, $par=1000, $basis=0) * 4 European 30/360 * @return float */ - public static function AMORDEGRC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) { + public static function AMORDEGRC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis = 0) + { $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); @@ -333,27 +325,27 @@ public static function AMORDEGRC($cost, $purchased, $firstPeriod, $salvage, $per } $rate *= $amortiseCoeff; - $fNRate = round(PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis) * $rate * $cost,0); + $fNRate = round(PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis) * $rate * $cost, 0); $cost -= $fNRate; $fRest = $cost - $salvage; for ($n = 0; $n < $period; ++$n) { - $fNRate = round($rate * $cost,0); + $fNRate = round($rate * $cost, 0); $fRest -= $fNRate; if ($fRest < 0.0) { switch ($period - $n) { - case 0 : - case 1 : return round($cost * 0.5, 0); - break; - default : return 0.0; - break; + case 0: + case 1: + return round($cost * 0.5, 0); + default: + return 0.0; } } $cost -= $fNRate; } return $fNRate; - } // function AMORDEGRC() + } /** @@ -382,14 +374,15 @@ public static function AMORDEGRC($cost, $purchased, $firstPeriod, $salvage, $per * 4 European 30/360 * @return float */ - public static function AMORLINC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) { - $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); - $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); - $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); - $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); - $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); - $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + public static function AMORLINC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis = 0) + { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); + $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); $fOneRate = $cost * $rate; $fCostDelta = $cost - $salvage; @@ -413,7 +406,7 @@ public static function AMORLINC($cost, $purchased, $firstPeriod, $salvage, $peri } else { return 0.0; } - } // function AMORLINC() + } /** @@ -448,30 +441,31 @@ public static function AMORLINC($cost, $purchased, $firstPeriod, $salvage, $peri * 4 European 30/360 * @return float */ - public static function COUPDAYBS($settlement, $maturity, $frequency, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + public static function COUPDAYBS($settlement, $maturity, $frequency, $basis = 0) + { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + if (is_string($settlement = PHPExcel_Calculation_DateTime::getDateValue($settlement))) { return PHPExcel_Calculation_Functions::VALUE(); } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + if (is_string($maturity = PHPExcel_Calculation_DateTime::getDateValue($maturity))) { return PHPExcel_Calculation_Functions::VALUE(); } if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || + (!self::isValidFrequency($frequency)) || (($basis < 0) || ($basis > 4))) { return PHPExcel_Calculation_Functions::NaN(); } - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); - $prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); + $daysPerYear = self::daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement), $basis); + $prev = self::couponFirstPeriodDate($settlement, $maturity, $frequency, false); return PHPExcel_Calculation_DateTime::YEARFRAC($prev, $settlement, $basis) * $daysPerYear; - } // function COUPDAYBS() + } /** @@ -506,42 +500,45 @@ public static function COUPDAYBS($settlement, $maturity, $frequency, $basis=0) { * 4 European 30/360 * @return float */ - public static function COUPDAYS($settlement, $maturity, $frequency, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + public static function COUPDAYS($settlement, $maturity, $frequency, $basis = 0) + { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + if (is_string($settlement = PHPExcel_Calculation_DateTime::getDateValue($settlement))) { return PHPExcel_Calculation_Functions::VALUE(); } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + if (is_string($maturity = PHPExcel_Calculation_DateTime::getDateValue($maturity))) { return PHPExcel_Calculation_Functions::VALUE(); } if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || + (!self::isValidFrequency($frequency)) || (($basis < 0) || ($basis > 4))) { return PHPExcel_Calculation_Functions::NaN(); } switch ($basis) { - case 3: // Actual/365 - return 365 / $frequency; - case 1: // Actual/actual - if ($frequency == 1) { - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($maturity),$basis); - return ($daysPerYear / $frequency); - } else { - $prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); - $next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); - return ($next - $prev); - } - default: // US (NASD) 30/360, Actual/360 or European 30/360 - return 360 / $frequency; + case 3: + // Actual/365 + return 365 / $frequency; + case 1: + // Actual/actual + if ($frequency == 1) { + $daysPerYear = self::daysPerYear(PHPExcel_Calculation_DateTime::YEAR($maturity), $basis); + return ($daysPerYear / $frequency); + } + $prev = self::couponFirstPeriodDate($settlement, $maturity, $frequency, false); + $next = self::couponFirstPeriodDate($settlement, $maturity, $frequency, true); + return ($next - $prev); + default: + // US (NASD) 30/360, Actual/360 or European 30/360 + return 360 / $frequency; } return PHPExcel_Calculation_Functions::VALUE(); - } // function COUPDAYS() + } /** @@ -576,30 +573,31 @@ public static function COUPDAYS($settlement, $maturity, $frequency, $basis=0) { * 4 European 30/360 * @return float */ - public static function COUPDAYSNC($settlement, $maturity, $frequency, $basis=0) { - $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); - $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); - $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); - $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + public static function COUPDAYSNC($settlement, $maturity, $frequency, $basis = 0) + { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + if (is_string($settlement = PHPExcel_Calculation_DateTime::getDateValue($settlement))) { return PHPExcel_Calculation_Functions::VALUE(); } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + if (is_string($maturity = PHPExcel_Calculation_DateTime::getDateValue($maturity))) { return PHPExcel_Calculation_Functions::VALUE(); } if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || + (!self::isValidFrequency($frequency)) || (($basis < 0) || ($basis > 4))) { return PHPExcel_Calculation_Functions::NaN(); } - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); - $next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + $daysPerYear = self::daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement), $basis); + $next = self::couponFirstPeriodDate($settlement, $maturity, $frequency, true); return PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $next, $basis) * $daysPerYear; - } // function COUPDAYSNC() + } /** @@ -635,27 +633,28 @@ public static function COUPDAYSNC($settlement, $maturity, $frequency, $basis=0) * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ - public static function COUPNCD($settlement, $maturity, $frequency, $basis=0) { + public static function COUPNCD($settlement, $maturity, $frequency, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + if (is_string($settlement = PHPExcel_Calculation_DateTime::getDateValue($settlement))) { return PHPExcel_Calculation_Functions::VALUE(); } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + if (is_string($maturity = PHPExcel_Calculation_DateTime::getDateValue($maturity))) { return PHPExcel_Calculation_Functions::VALUE(); } if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || + (!self::isValidFrequency($frequency)) || (($basis < 0) || ($basis > 4))) { return PHPExcel_Calculation_Functions::NaN(); } - return self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); - } // function COUPNCD() + return self::couponFirstPeriodDate($settlement, $maturity, $frequency, true); + } /** @@ -691,42 +690,43 @@ public static function COUPNCD($settlement, $maturity, $frequency, $basis=0) { * 4 European 30/360 * @return integer */ - public static function COUPNUM($settlement, $maturity, $frequency, $basis=0) { + public static function COUPNUM($settlement, $maturity, $frequency, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + if (is_string($settlement = PHPExcel_Calculation_DateTime::getDateValue($settlement))) { return PHPExcel_Calculation_Functions::VALUE(); } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + if (is_string($maturity = PHPExcel_Calculation_DateTime::getDateValue($maturity))) { return PHPExcel_Calculation_Functions::VALUE(); } if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || + (!self::isValidFrequency($frequency)) || (($basis < 0) || ($basis > 4))) { return PHPExcel_Calculation_Functions::NaN(); } - $settlement = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + $settlement = self::couponFirstPeriodDate($settlement, $maturity, $frequency, true); $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis) * 365; switch ($frequency) { case 1: // annual payments - return ceil($daysBetweenSettlementAndMaturity / 360); + return ceil($daysBetweenSettlementAndMaturity / 360); case 2: // half-yearly - return ceil($daysBetweenSettlementAndMaturity / 180); + return ceil($daysBetweenSettlementAndMaturity / 180); case 4: // quarterly - return ceil($daysBetweenSettlementAndMaturity / 90); + return ceil($daysBetweenSettlementAndMaturity / 90); case 6: // bimonthly - return ceil($daysBetweenSettlementAndMaturity / 60); + return ceil($daysBetweenSettlementAndMaturity / 60); case 12: // monthly - return ceil($daysBetweenSettlementAndMaturity / 30); + return ceil($daysBetweenSettlementAndMaturity / 30); } return PHPExcel_Calculation_Functions::VALUE(); - } // function COUPNUM() + } /** @@ -762,27 +762,28 @@ public static function COUPNUM($settlement, $maturity, $frequency, $basis=0) { * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ - public static function COUPPCD($settlement, $maturity, $frequency, $basis=0) { + public static function COUPPCD($settlement, $maturity, $frequency, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + if (is_string($settlement = PHPExcel_Calculation_DateTime::getDateValue($settlement))) { return PHPExcel_Calculation_Functions::VALUE(); } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + if (is_string($maturity = PHPExcel_Calculation_DateTime::getDateValue($maturity))) { return PHPExcel_Calculation_Functions::VALUE(); } if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || + (!self::isValidFrequency($frequency)) || (($basis < 0) || ($basis > 4))) { return PHPExcel_Calculation_Functions::NaN(); } - return self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); - } // function COUPPCD() + return self::couponFirstPeriodDate($settlement, $maturity, $frequency, false); + } /** @@ -806,7 +807,8 @@ public static function COUPPCD($settlement, $maturity, $frequency, $basis=0) { * 1 At the beginning of the period. * @return float */ - public static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0) { + public static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0) + { $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); @@ -829,7 +831,7 @@ public static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0) { } return $interest; - } // function CUMIPMT() + } /** @@ -853,7 +855,8 @@ public static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0) { * 1 At the beginning of the period. * @return float */ - public static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0) { + public static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0) + { $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); @@ -876,7 +879,7 @@ public static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0) { } return $principal; - } // function CUMPRINC() + } /** @@ -905,7 +908,8 @@ public static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0) { * it defaults to 12. * @return float */ - public static function DB($cost, $salvage, $life, $period, $month=12) { + public static function DB($cost, $salvage, $life, $period, $month = 12) + { $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); @@ -914,11 +918,11 @@ public static function DB($cost, $salvage, $life, $period, $month=12) { // Validate if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($month))) { - $cost = (float) $cost; - $salvage = (float) $salvage; - $life = (int) $life; - $period = (int) $period; - $month = (int) $month; + $cost = (float) $cost; + $salvage = (float) $salvage; + $life = (int) $life; + $period = (int) $period; + $month = (int) $month; if ($cost == 0) { return 0.0; } elseif (($cost < 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($month < 1)) { @@ -941,12 +945,12 @@ public static function DB($cost, $salvage, $life, $period, $month=12) { $previousDepreciation += $depreciation; } if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - $depreciation = round($depreciation,2); + $depreciation = round($depreciation, 2); } return $depreciation; } return PHPExcel_Calculation_Functions::VALUE(); - } // function DB() + } /** @@ -972,7 +976,8 @@ public static function DB($cost, $salvage, $life, $period, $month=12) { * double-declining balance method). * @return float */ - public static function DDB($cost, $salvage, $life, $period, $factor=2.0) { + public static function DDB($cost, $salvage, $life, $period, $factor = 2.0) + { $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); @@ -981,11 +986,11 @@ public static function DDB($cost, $salvage, $life, $period, $factor=2.0) { // Validate if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($factor))) { - $cost = (float) $cost; - $salvage = (float) $salvage; - $life = (int) $life; - $period = (int) $period; - $factor = (float) $factor; + $cost = (float) $cost; + $salvage = (float) $salvage; + $life = (int) $life; + $period = (int) $period; + $factor = (float) $factor; if (($cost <= 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($factor <= 0.0) || ($period > $life)) { return PHPExcel_Calculation_Functions::NaN(); } @@ -996,16 +1001,16 @@ public static function DDB($cost, $salvage, $life, $period, $factor=2.0) { // Loop through each period calculating the depreciation $previousDepreciation = 0; for ($per = 1; $per <= $period; ++$per) { - $depreciation = min( ($cost - $previousDepreciation) * ($factor / $life), ($cost - $salvage - $previousDepreciation) ); + $depreciation = min(($cost - $previousDepreciation) * ($factor / $life), ($cost - $salvage - $previousDepreciation)); $previousDepreciation += $depreciation; } if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { - $depreciation = round($depreciation,2); + $depreciation = round($depreciation, 2); } return $depreciation; } return PHPExcel_Calculation_Functions::VALUE(); - } // function DDB() + } /** @@ -1033,7 +1038,8 @@ public static function DDB($cost, $salvage, $life, $period, $factor=2.0) { * 4 European 30/360 * @return float */ - public static function DISC($settlement, $maturity, $price, $redemption, $basis=0) { + public static function DISC($settlement, $maturity, $price, $redemption, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); @@ -1057,7 +1063,7 @@ public static function DISC($settlement, $maturity, $price, $redemption, $basis= return ((1 - $price / $redemption) / $daysBetweenSettlementAndMaturity); } return PHPExcel_Calculation_Functions::VALUE(); - } // function DISC() + } /** @@ -1076,7 +1082,8 @@ public static function DISC($settlement, $maturity, $price, $redemption, $basis= * @param integer $fraction Fraction * @return float */ - public static function DOLLARDE($fractional_dollar = Null, $fraction = 0) { + public static function DOLLARDE($fractional_dollar = null, $fraction = 0) + { $fractional_dollar = PHPExcel_Calculation_Functions::flattenSingleValue($fractional_dollar); $fraction = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction); @@ -1089,11 +1096,11 @@ public static function DOLLARDE($fractional_dollar = Null, $fraction = 0) { } $dollars = floor($fractional_dollar); - $cents = fmod($fractional_dollar,1); + $cents = fmod($fractional_dollar, 1); $cents /= $fraction; - $cents *= pow(10,ceil(log10($fraction))); + $cents *= pow(10, ceil(log10($fraction))); return $dollars + $cents; - } // function DOLLARDE() + } /** @@ -1112,7 +1119,8 @@ public static function DOLLARDE($fractional_dollar = Null, $fraction = 0) { * @param integer $fraction Fraction * @return float */ - public static function DOLLARFR($decimal_dollar = Null, $fraction = 0) { + public static function DOLLARFR($decimal_dollar = null, $fraction = 0) + { $decimal_dollar = PHPExcel_Calculation_Functions::flattenSingleValue($decimal_dollar); $fraction = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction); @@ -1125,11 +1133,11 @@ public static function DOLLARFR($decimal_dollar = Null, $fraction = 0) { } $dollars = floor($decimal_dollar); - $cents = fmod($decimal_dollar,1); + $cents = fmod($decimal_dollar, 1); $cents *= $fraction; - $cents *= pow(10,-ceil(log10($fraction))); + $cents *= pow(10, -ceil(log10($fraction))); return $dollars + $cents; - } // function DOLLARFR() + } /** @@ -1147,7 +1155,8 @@ public static function DOLLARFR($decimal_dollar = Null, $fraction = 0) { * @param integer $npery Number of compounding payments per year * @return float */ - public static function EFFECT($nominal_rate = 0, $npery = 0) { + public static function EFFECT($nominal_rate = 0, $npery = 0) + { $nominal_rate = PHPExcel_Calculation_Functions::flattenSingleValue($nominal_rate); $npery = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery); @@ -1157,7 +1166,7 @@ public static function EFFECT($nominal_rate = 0, $npery = 0) { } return pow((1 + $nominal_rate / $npery), $npery) - 1; - } // function EFFECT() + } /** @@ -1182,7 +1191,8 @@ public static function EFFECT($nominal_rate = 0, $npery = 0) { * 1 At the beginning of the period. * @return float */ - public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) { + public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) + { $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); @@ -1197,10 +1207,9 @@ public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) { // Calculate if (!is_null($rate) && $rate != 0) { return -$pv * pow(1 + $rate, $nper) - $pmt * (1 + $rate * $type) * (pow(1 + $rate, $nper) - 1) / $rate; - } else { - return -$pv - $pmt * $nper; } - } // function FV() + return -$pv - $pmt * $nper; + } /** @@ -1216,16 +1225,17 @@ public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) { * @param float[] $schedule An array of interest rates to apply. * @return float */ - public static function FVSCHEDULE($principal, $schedule) { + public static function FVSCHEDULE($principal, $schedule) + { $principal = PHPExcel_Calculation_Functions::flattenSingleValue($principal); $schedule = PHPExcel_Calculation_Functions::flattenArray($schedule); - foreach($schedule as $rate) { + foreach ($schedule as $rate) { $principal *= 1 + $rate; } return $principal; - } // function FVSCHEDULE() + } /** @@ -1250,7 +1260,8 @@ public static function FVSCHEDULE($principal, $schedule) { * 4 European 30/360 * @return float */ - public static function INTRATE($settlement, $maturity, $investment, $redemption, $basis=0) { + public static function INTRATE($settlement, $maturity, $investment, $redemption, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $investment = PHPExcel_Calculation_Functions::flattenSingleValue($investment); @@ -1274,7 +1285,7 @@ public static function INTRATE($settlement, $maturity, $investment, $redemption, return (($redemption / $investment) - 1) / ($daysBetweenSettlementAndMaturity); } return PHPExcel_Calculation_Functions::VALUE(); - } // function INTRATE() + } /** @@ -1293,7 +1304,8 @@ public static function INTRATE($settlement, $maturity, $investment, $redemption, * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period * @return float */ - public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { + public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) + { $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); $per = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per); $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); @@ -1310,17 +1322,17 @@ public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { } // Calculate - $interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); + $interestAndPrincipal = self::interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); return $interestAndPrincipal[0]; - } // function IPMT() + } /** * IRR * - * Returns the internal rate of return for a series of cash flows represented by the numbers in values. - * These cash flows do not have to be even, as they would be for an annuity. However, the cash flows must occur + * Returns the internal rate of return for a series of cash flows represented by the numbers in values. + * These cash flows do not have to be even, as they would be for an annuity. However, the cash flows must occur * at regular intervals, such as monthly or annually. The internal rate of return is the interest rate received - * for an investment consisting of payments (negative values) and income (positive values) that occur at regular + * for an investment consisting of payments (negative values) and income (positive values) that occur at regular * periods. * * Excel Function: @@ -1328,13 +1340,16 @@ public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { * * @param float[] $values An array or a reference to cells that contain numbers for which you want * to calculate the internal rate of return. - * Values must contain at least one positive value and one negative value to + * Values must contain at least one positive value and one negative value to * calculate the internal rate of return. * @param float $guess A number that you guess is close to the result of IRR * @return float */ - public static function IRR($values, $guess = 0.1) { - if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); + public static function IRR($values, $guess = 0.1) + { + if (!is_array($values)) { + return PHPExcel_Calculation_Functions::VALUE(); + } $values = PHPExcel_Calculation_Functions::flattenArray($values); $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); @@ -1344,14 +1359,18 @@ public static function IRR($values, $guess = 0.1) { $f1 = self::NPV($x1, $values); $f2 = self::NPV($x2, $values); for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { - if (($f1 * $f2) < 0.0) break; + if (($f1 * $f2) < 0.0) { + break; + } if (abs($f1) < abs($f2)) { $f1 = self::NPV($x1 += 1.6 * ($x1 - $x2), $values); } else { $f2 = self::NPV($x2 += 1.6 * ($x2 - $x1), $values); } } - if (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE(); + if (($f1 * $f2) > 0.0) { + return PHPExcel_Calculation_Functions::VALUE(); + } $f = self::NPV($x1, $values); if ($f < 0.0) { @@ -1362,17 +1381,19 @@ public static function IRR($values, $guess = 0.1) { $dx = $x1 - $x2; } - for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { $dx *= 0.5; $x_mid = $rtb + $dx; $f_mid = self::NPV($x_mid, $values); - if ($f_mid <= 0.0) + if ($f_mid <= 0.0) { $rtb = $x_mid; - if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) + } + if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) { return $x_mid; + } } return PHPExcel_Calculation_Functions::VALUE(); - } // function IRR() + } /** @@ -1391,7 +1412,8 @@ public static function IRR($values, $guess = 0.1) { * * PV is the loan amount or present value of the payments */ - public static function ISPMT() { + public static function ISPMT() + { // Return value $returnValue = 0; @@ -1404,22 +1426,22 @@ public static function ISPMT() { // Calculate $principlePayment = ($principleRemaining * 1.0) / ($numberPeriods * 1.0); - for($i=0; $i <= $period; ++$i) { + for ($i=0; $i <= $period; ++$i) { $returnValue = $interestRate * $principleRemaining * -1; $principleRemaining -= $principlePayment; // principle needs to be 0 after the last payment, don't let floating point screw it up - if($i == $numberPeriods) { + if ($i == $numberPeriods) { $returnValue = 0; } } return($returnValue); - } // function ISPMT() + } /** * MIRR * - * Returns the modified internal rate of return for a series of periodic cash flows. MIRR considers both + * Returns the modified internal rate of return for a series of periodic cash flows. MIRR considers both * the cost of the investment and the interest received on reinvestment of cash. * * Excel Function: @@ -1432,8 +1454,11 @@ public static function ISPMT() { * @param float $reinvestment_rate The interest rate you receive on the cash flows as you reinvest them * @return float */ - public static function MIRR($values, $finance_rate, $reinvestment_rate) { - if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); + public static function MIRR($values, $finance_rate, $reinvestment_rate) + { + if (!is_array($values)) { + return PHPExcel_Calculation_Functions::VALUE(); + } $values = PHPExcel_Calculation_Functions::flattenArray($values); $finance_rate = PHPExcel_Calculation_Functions::flattenSingleValue($finance_rate); $reinvestment_rate = PHPExcel_Calculation_Functions::flattenSingleValue($reinvestment_rate); @@ -1443,7 +1468,7 @@ public static function MIRR($values, $finance_rate, $reinvestment_rate) { $fr = 1.0 + $finance_rate; $npv_pos = $npv_neg = 0.0; - foreach($values as $i => $v) { + foreach ($values as $i => $v) { if ($v >= 0) { $npv_pos += $v / pow($rr, $i); } else { @@ -1459,7 +1484,7 @@ public static function MIRR($values, $finance_rate, $reinvestment_rate) { / ($npv_neg * ($rr)), (1.0 / ($n - 1))) - 1.0; return (is_finite($mirr) ? $mirr : PHPExcel_Calculation_Functions::VALUE()); - } // function MIRR() + } /** @@ -1471,7 +1496,8 @@ public static function MIRR($values, $finance_rate, $reinvestment_rate) { * @param int $npery Number of compounding payments per year * @return float */ - public static function NOMINAL($effect_rate = 0, $npery = 0) { + public static function NOMINAL($effect_rate = 0, $npery = 0) + { $effect_rate = PHPExcel_Calculation_Functions::flattenSingleValue($effect_rate); $npery = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery); @@ -1482,7 +1508,7 @@ public static function NOMINAL($effect_rate = 0, $npery = 0) { // Calculate return $npery * (pow($effect_rate + 1, 1 / $npery) - 1); - } // function NOMINAL() + } /** @@ -1497,7 +1523,8 @@ public static function NOMINAL($effect_rate = 0, $npery = 0) { * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period * @return float */ - public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) { + public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) + { $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); @@ -1515,13 +1542,12 @@ public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) { return PHPExcel_Calculation_Functions::NaN(); } return log(($pmt * (1 + $rate * $type) / $rate - $fv) / ($pv + $pmt * (1 + $rate * $type) / $rate)) / log(1 + $rate); - } else { - if ($pmt == 0) { - return PHPExcel_Calculation_Functions::NaN(); - } - return (-$pv -$fv) / $pmt; } - } // function NPER() + if ($pmt == 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return (-$pv -$fv) / $pmt; + } /** * NPV @@ -1530,7 +1556,8 @@ public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) { * * @return float */ - public static function NPV() { + public static function NPV() + { // Return value $returnValue = 0; @@ -1548,7 +1575,7 @@ public static function NPV() { // Return return $returnValue; - } // function NPV() + } /** * PMT @@ -1562,7 +1589,8 @@ public static function NPV() { * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period * @return float */ - public static function PMT($rate = 0, $nper = 0, $pv = 0, $fv = 0, $type = 0) { + public static function PMT($rate = 0, $nper = 0, $pv = 0, $fv = 0, $type = 0) + { $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); @@ -1577,10 +1605,9 @@ public static function PMT($rate = 0, $nper = 0, $pv = 0, $fv = 0, $type = 0) { // Calculate if (!is_null($rate) && $rate != 0) { return (-$fv - $pv * pow(1 + $rate, $nper)) / (1 + $rate * $type) / ((pow(1 + $rate, $nper) - 1) / $rate); - } else { - return (-$pv - $fv) / $nper; } - } // function PMT() + return (-$pv - $fv) / $nper; + } /** @@ -1596,7 +1623,8 @@ public static function PMT($rate = 0, $nper = 0, $pv = 0, $fv = 0, $type = 0) { * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period * @return float */ - public static function PPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { + public static function PPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) + { $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); $per = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per); $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); @@ -1613,12 +1641,13 @@ public static function PPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { } // Calculate - $interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); + $interestAndPrincipal = self::interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); return $interestAndPrincipal[1]; - } // function PPMT() + } - public static function PRICE($settlement, $maturity, $rate, $yield, $redemption, $frequency, $basis=0) { + public static function PRICE($settlement, $maturity, $rate, $yield, $redemption, $frequency, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $rate = (float) PHPExcel_Calculation_Functions::flattenSingleValue($rate); @@ -1627,15 +1656,15 @@ public static function PRICE($settlement, $maturity, $rate, $yield, $redemption, $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); - if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + if (is_string($settlement = PHPExcel_Calculation_DateTime::getDateValue($settlement))) { return PHPExcel_Calculation_Functions::VALUE(); } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + if (is_string($maturity = PHPExcel_Calculation_DateTime::getDateValue($maturity))) { return PHPExcel_Calculation_Functions::VALUE(); } if (($settlement > $maturity) || - (!self::_validFrequency($frequency)) || + (!self::isValidFrequency($frequency)) || (($basis < 0) || ($basis > 4))) { return PHPExcel_Calculation_Functions::NaN(); } @@ -1650,13 +1679,13 @@ public static function PRICE($settlement, $maturity, $rate, $yield, $redemption, $de = $dsc / $e; $result = $redemption / pow($baseYF, (--$n + $de)); - for($k = 0; $k <= $n; ++$k) { + for ($k = 0; $k <= $n; ++$k) { $result += $rfp / (pow($baseYF, ($k + $de))); } $result -= $rfp * ($a / $e); return $result; - } // function PRICE() + } /** @@ -1678,7 +1707,8 @@ public static function PRICE($settlement, $maturity, $rate, $yield, $redemption, * 4 European 30/360 * @return float */ - public static function PRICEDISC($settlement, $maturity, $discount, $redemption, $basis=0) { + public static function PRICEDISC($settlement, $maturity, $discount, $redemption, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $discount = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount); @@ -1699,7 +1729,7 @@ public static function PRICEDISC($settlement, $maturity, $discount, $redemption, return $redemption * (1 - $discount * $daysBetweenSettlementAndMaturity); } return PHPExcel_Calculation_Functions::VALUE(); - } // function PRICEDISC() + } /** @@ -1722,7 +1752,8 @@ public static function PRICEDISC($settlement, $maturity, $discount, $redemption, * 4 European 30/360 * @return float */ - public static function PRICEMAT($settlement, $maturity, $issue, $rate, $yield, $basis=0) { + public static function PRICEMAT($settlement, $maturity, $issue, $rate, $yield, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); @@ -1735,7 +1766,7 @@ public static function PRICEMAT($settlement, $maturity, $issue, $rate, $yield, $ if (($rate <= 0) || ($yield <= 0)) { return PHPExcel_Calculation_Functions::NaN(); } - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + $daysPerYear = self::daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement), $basis); if (!is_numeric($daysPerYear)) { return $daysPerYear; } @@ -1763,7 +1794,7 @@ public static function PRICEMAT($settlement, $maturity, $issue, $rate, $yield, $ (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate * 100)); } return PHPExcel_Calculation_Functions::VALUE(); - } // function PRICEMAT() + } /** @@ -1778,7 +1809,8 @@ public static function PRICEMAT($settlement, $maturity, $issue, $rate, $yield, $ * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period * @return float */ - public static function PV($rate = 0, $nper = 0, $pmt = 0, $fv = 0, $type = 0) { + public static function PV($rate = 0, $nper = 0, $pmt = 0, $fv = 0, $type = 0) + { $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); @@ -1793,10 +1825,9 @@ public static function PV($rate = 0, $nper = 0, $pmt = 0, $fv = 0, $type = 0) { // Calculate if (!is_null($rate) && $rate != 0) { return (-$pmt * (1 + $rate * $type) * ((pow(1 + $rate, $nper) - 1) / $rate) - $fv) / pow(1 + $rate, $nper); - } else { - return -$fv - $pmt * $nper; } - } // function PV() + return -$fv - $pmt * $nper; + } /** @@ -1829,7 +1860,8 @@ public static function PV($rate = 0, $nper = 0, $pmt = 0, $fv = 0, $type = 0) { * If you omit guess, it is assumed to be 10 percent. * @return float **/ - public static function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) { + public static function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) + { $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); @@ -1854,9 +1886,9 @@ public static function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1 $rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0); $x0 = $x1; $x1 = $rate; - if (($nper * abs($pmt)) > ($pv - $fv)) + if (($nper * abs($pmt)) > ($pv - $fv)) { $x1 = abs($x1); - + } if (abs($rate) < FINANCIAL_PRECISION) { $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; } else { @@ -1869,7 +1901,7 @@ public static function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1 ++$i; } return $rate; - } // function RATE() + } /** @@ -1891,7 +1923,8 @@ public static function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1 * 4 European 30/360 * @return float */ - public static function RECEIVED($settlement, $maturity, $investment, $discount, $basis=0) { + public static function RECEIVED($settlement, $maturity, $investment, $discount, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $investment = (float) PHPExcel_Calculation_Functions::flattenSingleValue($investment); @@ -1912,7 +1945,7 @@ public static function RECEIVED($settlement, $maturity, $investment, $discount, return $investment / ( 1 - ($discount * $daysBetweenSettlementAndMaturity)); } return PHPExcel_Calculation_Functions::VALUE(); - } // function RECEIVED() + } /** @@ -1925,7 +1958,8 @@ public static function RECEIVED($settlement, $maturity, $investment, $discount, * @param life Number of periods over which the asset is depreciated * @return float */ - public static function SLN($cost, $salvage, $life) { + public static function SLN($cost, $salvage, $life) + { $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); @@ -1938,7 +1972,7 @@ public static function SLN($cost, $salvage, $life) { return ($cost - $salvage) / $life; } return PHPExcel_Calculation_Functions::VALUE(); - } // function SLN() + } /** @@ -1952,7 +1986,8 @@ public static function SLN($cost, $salvage, $life) { * @param period Period * @return float */ - public static function SYD($cost, $salvage, $life, $period) { + public static function SYD($cost, $salvage, $life, $period) + { $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); @@ -1966,7 +2001,7 @@ public static function SYD($cost, $salvage, $life, $period) { return (($cost - $salvage) * ($life - $period + 1) * 2) / ($life * ($life + 1)); } return PHPExcel_Calculation_Functions::VALUE(); - } // function SYD() + } /** @@ -1981,7 +2016,8 @@ public static function SYD($cost, $salvage, $life, $period) { * @param int discount The Treasury bill's discount rate. * @return float */ - public static function TBILLEQ($settlement, $maturity, $discount) { + public static function TBILLEQ($settlement, $maturity, $discount) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $discount = PHPExcel_Calculation_Functions::flattenSingleValue($discount); @@ -1992,7 +2028,7 @@ public static function TBILLEQ($settlement, $maturity, $discount) { return $testValue; } - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + if (is_string($maturity = PHPExcel_Calculation_DateTime::getDateValue($maturity))) { return PHPExcel_Calculation_Functions::VALUE(); } @@ -2000,11 +2036,11 @@ public static function TBILLEQ($settlement, $maturity, $discount) { ++$maturity; $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; } else { - $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::getDateValue($maturity) - PHPExcel_Calculation_DateTime::getDateValue($settlement)); } return (365 * $discount) / (360 - $discount * $daysBetweenSettlementAndMaturity); - } // function TBILLEQ() + } /** @@ -2019,12 +2055,13 @@ public static function TBILLEQ($settlement, $maturity, $discount) { * @param int discount The Treasury bill's discount rate. * @return float */ - public static function TBILLPRICE($settlement, $maturity, $discount) { + public static function TBILLPRICE($settlement, $maturity, $discount) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $discount = PHPExcel_Calculation_Functions::flattenSingleValue($discount); - if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + if (is_string($maturity = PHPExcel_Calculation_DateTime::getDateValue($maturity))) { return PHPExcel_Calculation_Functions::VALUE(); } @@ -2042,7 +2079,7 @@ public static function TBILLPRICE($settlement, $maturity, $discount) { return $daysBetweenSettlementAndMaturity; } } else { - $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::getDateValue($maturity) - PHPExcel_Calculation_DateTime::getDateValue($settlement)); } if ($daysBetweenSettlementAndMaturity > 360) { @@ -2056,7 +2093,7 @@ public static function TBILLPRICE($settlement, $maturity, $discount) { return $price; } return PHPExcel_Calculation_Functions::VALUE(); - } // function TBILLPRICE() + } /** @@ -2071,7 +2108,8 @@ public static function TBILLPRICE($settlement, $maturity, $discount) { * @param int price The Treasury bill's price per $100 face value. * @return float */ - public static function TBILLYIELD($settlement, $maturity, $price) { + public static function TBILLYIELD($settlement, $maturity, $price) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); @@ -2090,7 +2128,7 @@ public static function TBILLYIELD($settlement, $maturity, $price) { return $daysBetweenSettlementAndMaturity; } } else { - $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::getDateValue($maturity) - PHPExcel_Calculation_DateTime::getDateValue($settlement)); } if ($daysBetweenSettlementAndMaturity > 360) { @@ -2100,15 +2138,20 @@ public static function TBILLYIELD($settlement, $maturity, $price) { return ((100 - $price) / $price) * (360 / $daysBetweenSettlementAndMaturity); } return PHPExcel_Calculation_Functions::VALUE(); - } // function TBILLYIELD() + } - public static function XIRR($values, $dates, $guess = 0.1) { - if ((!is_array($values)) && (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE(); + public static function XIRR($values, $dates, $guess = 0.1) + { + if ((!is_array($values)) && (!is_array($dates))) { + return PHPExcel_Calculation_Functions::VALUE(); + } $values = PHPExcel_Calculation_Functions::flattenArray($values); $dates = PHPExcel_Calculation_Functions::flattenArray($dates); $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); - if (count($values) != count($dates)) return PHPExcel_Calculation_Functions::NaN(); + if (count($values) != count($dates)) { + return PHPExcel_Calculation_Functions::NaN(); + } // create an initial range, with a root somewhere between 0 and guess $x1 = 0.0; @@ -2116,14 +2159,17 @@ public static function XIRR($values, $dates, $guess = 0.1) { $f1 = self::XNPV($x1, $values, $dates); $f2 = self::XNPV($x2, $values, $dates); for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { - if (($f1 * $f2) < 0.0) break; - if (abs($f1) < abs($f2)) { + if (($f1 * $f2) < 0.0) { + break; + } elseif (abs($f1) < abs($f2)) { $f1 = self::XNPV($x1 += 1.6 * ($x1 - $x2), $values, $dates); } else { $f2 = self::XNPV($x2 += 1.6 * ($x2 - $x1), $values, $dates); } } - if (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE(); + if (($f1 * $f2) > 0.0) { + return PHPExcel_Calculation_Functions::VALUE(); + } $f = self::XNPV($x1, $values, $dates); if ($f < 0.0) { @@ -2134,12 +2180,16 @@ public static function XIRR($values, $dates, $guess = 0.1) { $dx = $x1 - $x2; } - for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { $dx *= 0.5; $x_mid = $rtb + $dx; $f_mid = self::XNPV($x_mid, $values, $dates); - if ($f_mid <= 0.0) $rtb = $x_mid; - if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) return $x_mid; + if ($f_mid <= 0.0) { + $rtb = $x_mid; + } + if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) { + return $x_mid; + } } return PHPExcel_Calculation_Functions::VALUE(); } @@ -2155,27 +2205,43 @@ public static function XIRR($values, $dates, $guess = 0.1) { * =XNPV(rate,values,dates) * * @param float $rate The discount rate to apply to the cash flows. - * @param array of float $values A series of cash flows that corresponds to a schedule of payments in dates. The first payment is optional and corresponds to a cost or payment that occurs at the beginning of the investment. If the first value is a cost or payment, it must be a negative value. All succeeding payments are discounted based on a 365-day year. The series of values must contain at least one positive value and one negative value. - * @param array of mixed $dates A schedule of payment dates that corresponds to the cash flow payments. The first payment date indicates the beginning of the schedule of payments. All other dates must be later than this date, but they may occur in any order. + * @param array of float $values A series of cash flows that corresponds to a schedule of payments in dates. + * The first payment is optional and corresponds to a cost or payment that occurs at the beginning of the investment. + * If the first value is a cost or payment, it must be a negative value. All succeeding payments are discounted based on a 365-day year. + * The series of values must contain at least one positive value and one negative value. + * @param array of mixed $dates A schedule of payment dates that corresponds to the cash flow payments. + * The first payment date indicates the beginning of the schedule of payments. + * All other dates must be later than this date, but they may occur in any order. * @return float */ - public static function XNPV($rate, $values, $dates) { + public static function XNPV($rate, $values, $dates) + { $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); - if (!is_numeric($rate)) return PHPExcel_Calculation_Functions::VALUE(); - if ((!is_array($values)) || (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE(); + if (!is_numeric($rate)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if ((!is_array($values)) || (!is_array($dates))) { + return PHPExcel_Calculation_Functions::VALUE(); + } $values = PHPExcel_Calculation_Functions::flattenArray($values); $dates = PHPExcel_Calculation_Functions::flattenArray($dates); $valCount = count($values); - if ($valCount != count($dates)) return PHPExcel_Calculation_Functions::NaN(); - if ((min($values) > 0) || (max($values) < 0)) return PHPExcel_Calculation_Functions::VALUE(); + if ($valCount != count($dates)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((min($values) > 0) || (max($values) < 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } $xnpv = 0.0; for ($i = 0; $i < $valCount; ++$i) { - if (!is_numeric($values[$i])) return PHPExcel_Calculation_Functions::VALUE(); - $xnpv += $values[$i] / pow(1 + $rate, PHPExcel_Calculation_DateTime::DATEDIF($dates[0],$dates[$i],'d') / 365); + if (!is_numeric($values[$i])) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $xnpv += $values[$i] / pow(1 + $rate, PHPExcel_Calculation_DateTime::DATEDIF($dates[0], $dates[$i], 'd') / 365); } return (is_finite($xnpv)) ? $xnpv : PHPExcel_Calculation_Functions::VALUE(); - } // function XNPV() + } /** @@ -2183,13 +2249,13 @@ public static function XNPV($rate, $values, $dates) { * * Returns the annual yield of a security that pays interest at maturity. * - * @param mixed settlement The security's settlement date. - * The security's settlement date is the date after the issue date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param int price The security's price per $100 face value. + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param int price The security's price per $100 face value. * @param int redemption The security's redemption value per $100 face value. - * @param int basis The type of day count to use. + * @param int basis The type of day count to use. * 0 or omitted US (NASD) 30/360 * 1 Actual/actual * 2 Actual/360 @@ -2197,7 +2263,8 @@ public static function XNPV($rate, $values, $dates) { * 4 European 30/360 * @return float */ - public static function YIELDDISC($settlement, $maturity, $price, $redemption, $basis=0) { + public static function YIELDDISC($settlement, $maturity, $price, $redemption, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); @@ -2209,11 +2276,11 @@ public static function YIELDDISC($settlement, $maturity, $price, $redemption, $b if (($price <= 0) || ($redemption <= 0)) { return PHPExcel_Calculation_Functions::NaN(); } - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + $daysPerYear = self::daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement), $basis); if (!is_numeric($daysPerYear)) { return $daysPerYear; } - $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity,$basis); + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); if (!is_numeric($daysBetweenSettlementAndMaturity)) { // return date error return $daysBetweenSettlementAndMaturity; @@ -2223,7 +2290,7 @@ public static function YIELDDISC($settlement, $maturity, $price, $redemption, $b return (($redemption - $price) / $price) * ($daysPerYear / $daysBetweenSettlementAndMaturity); } return PHPExcel_Calculation_Functions::VALUE(); - } // function YIELDDISC() + } /** @@ -2231,12 +2298,12 @@ public static function YIELDDISC($settlement, $maturity, $price, $redemption, $b * * Returns the annual yield of a security that pays interest at maturity. * - * @param mixed settlement The security's settlement date. - * The security's settlement date is the date after the issue date when the security is traded to the buyer. - * @param mixed maturity The security's maturity date. - * The maturity date is the date when the security expires. - * @param mixed issue The security's issue date. - * @param int rate The security's interest rate at date of issue. + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed issue The security's issue date. + * @param int rate The security's interest rate at date of issue. * @param int price The security's price per $100 face value. * @param int basis The type of day count to use. * 0 or omitted US (NASD) 30/360 @@ -2246,7 +2313,8 @@ public static function YIELDDISC($settlement, $maturity, $price, $redemption, $b * 4 European 30/360 * @return float */ - public static function YIELDMAT($settlement, $maturity, $issue, $rate, $price, $basis=0) { + public static function YIELDMAT($settlement, $maturity, $issue, $rate, $price, $basis = 0) + { $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); @@ -2259,7 +2327,7 @@ public static function YIELDMAT($settlement, $maturity, $issue, $rate, $price, $ if (($rate <= 0) || ($price <= 0)) { return PHPExcel_Calculation_Functions::NaN(); } - $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + $daysPerYear = self::daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement), $basis); if (!is_numeric($daysPerYear)) { return $daysPerYear; } @@ -2287,6 +2355,5 @@ public static function YIELDMAT($settlement, $maturity, $issue, $rate, $price, $ ($daysPerYear / $daysBetweenSettlementAndMaturity); } return PHPExcel_Calculation_Functions::VALUE(); - } // function YIELDMAT() - -} // class PHPExcel_Calculation_Financial + } +} diff --git a/Classes/PHPExcel/Calculation/FormulaParser.php b/Classes/PHPExcel/Calculation/FormulaParser.php index 1a97c7d66..893f19e94 100644 --- a/Classes/PHPExcel/Calculation/FormulaParser.php +++ b/Classes/PHPExcel/Calculation/FormulaParser.php @@ -1,30 +1,4 @@ _formula = trim($pFormula); + $this->formula = trim($pFormula); // Parse! - $this->_parseToTokens(); + $this->parseToTokens(); } /** @@ -113,8 +108,9 @@ public function __construct($pFormula = '') * * @return string */ - public function getFormula() { - return $this->_formula; + public function getFormula() + { + return $this->formula; } /** @@ -124,9 +120,10 @@ public function getFormula() { * @return string * @throws PHPExcel_Calculation_Exception */ - public function getToken($pId = 0) { - if (isset($this->_tokens[$pId])) { - return $this->_tokens[$pId]; + public function getToken($pId = 0) + { + if (isset($this->tokens[$pId])) { + return $this->tokens[$pId]; } else { throw new PHPExcel_Calculation_Exception("Token with id $pId does not exist."); } @@ -137,8 +134,9 @@ public function getToken($pId = 0) { * * @return string */ - public function getTokenCount() { - return count($this->_tokens); + public function getTokenCount() + { + return count($this->tokens); } /** @@ -146,20 +144,24 @@ public function getTokenCount() { * * @return PHPExcel_Calculation_FormulaToken[] */ - public function getTokens() { - return $this->_tokens; + public function getTokens() + { + return $this->tokens; } /** * Parse to tokens */ - private function _parseToTokens() { + private function parseToTokens() + { // No attempt is made to verify formulas; assumes formulas are derived from Excel, where // they can only exist if valid; stack overflows/underflows sunk as nulls without exceptions. // Check if the formula has a valid starting = - $formulaLength = strlen($this->_formula); - if ($formulaLength < 2 || $this->_formula{0} != '=') return; + $formulaLength = strlen($this->formula); + if ($formulaLength < 2 || $this->formula{0} != '=') { + return; + } // Helper variables $tokens1 = $tokens2 = $stack = array(); @@ -179,8 +181,8 @@ private function _parseToTokens() { // embeds are doubled // end marks token if ($inString) { - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { - if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) { + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { + if ((($index + 2) <= $formulaLength) && ($this->formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) { $value .= PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE; ++$index; } else { @@ -189,7 +191,7 @@ private function _parseToTokens() { $value = ""; } } else { - $value .= $this->_formula{$index}; + $value .= $this->formula{$index}; } ++$index; continue; @@ -199,15 +201,15 @@ private function _parseToTokens() { // embeds are double // end does not mark a token if ($inPath) { - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { - if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) { + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { + if ((($index + 2) <= $formulaLength) && ($this->formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) { $value .= PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE; ++$index; } else { $inPath = false; } } else { - $value .= $this->_formula{$index}; + $value .= $this->formula{$index}; } ++$index; continue; @@ -217,10 +219,10 @@ private function _parseToTokens() { // no embeds (changed to "()" by Excel) // end does not mark a token if ($inRange) { - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) { + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) { $inRange = false; } - $value .= $this->_formula{$index}; + $value .= $this->formula{$index}; ++$index; continue; } @@ -228,7 +230,7 @@ private function _parseToTokens() { // error values // end marks a token, determined from absolute list of values if ($inError) { - $value .= $this->_formula{$index}; + $value .= $this->formula{$index}; ++$index; if (in_array($value, $ERRORS)) { $inError = false; @@ -239,10 +241,10 @@ private function _parseToTokens() { } // scientific notation check - if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->_formula{$index}) !== false) { + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->formula{$index}) !== false) { if (strlen($value) > 1) { - if (preg_match("/^[1-9]{1}(\.[0-9]+)?E{1}$/", $this->_formula{$index}) != 0) { - $value .= $this->_formula{$index}; + if (preg_match("/^[1-9]{1}(\.[0-9]+)?E{1}$/", $this->formula{$index}) != 0) { + $value .= $this->formula{$index}; ++$index; continue; } @@ -252,18 +254,20 @@ private function _parseToTokens() { // independent character evaluation (order not important) // establish state-dependent character evaluations - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { - if (strlen($value > 0)) { // unexpected + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { + if (strlen($value > 0)) { + // unexpected $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); $value = ""; } $inString = true; ++$index; continue; - } + } - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { - if (strlen($value) > 0) { // unexpected + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { + if (strlen($value) > 0) { + // unexpected $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); $value = ""; } @@ -272,15 +276,16 @@ private function _parseToTokens() { continue; } - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) { + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) { $inRange = true; $value .= PHPExcel_Calculation_FormulaParser::BRACKET_OPEN; ++$index; continue; } - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::ERROR_START) { - if (strlen($value) > 0) { // unexpected + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::ERROR_START) { + if (strlen($value) > 0) { + // unexpected $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); $value = ""; } @@ -291,8 +296,9 @@ private function _parseToTokens() { } // mark start and end of arrays and array rows - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) { - if (strlen($value) > 0) { // unexpected + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) { + if (strlen($value) > 0) { + // unexpected $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); $value = ""; } @@ -309,7 +315,7 @@ private function _parseToTokens() { continue; } - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::SEMICOLON) { + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::SEMICOLON) { if (strlen($value) > 0) { $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); $value = ""; @@ -331,7 +337,7 @@ private function _parseToTokens() { continue; } - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) { + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) { if (strlen($value) > 0) { $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); $value = ""; @@ -352,14 +358,14 @@ private function _parseToTokens() { } // trim white-space - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) { + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) { if (strlen($value) > 0) { $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); $value = ""; } $tokens1[] = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE); ++$index; - while (($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) { + while (($this->formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) { ++$index; } continue; @@ -367,41 +373,41 @@ private function _parseToTokens() { // multi-character comparators if (($index + 2) <= $formulaLength) { - if (in_array(substr($this->_formula, $index, 2), $COMPARATORS_MULTI)) { + if (in_array(substr($this->formula, $index, 2), $COMPARATORS_MULTI)) { if (strlen($value) > 0) { $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); $value = ""; } - $tokens1[] = new PHPExcel_Calculation_FormulaToken(substr($this->_formula, $index, 2), PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); + $tokens1[] = new PHPExcel_Calculation_FormulaToken(substr($this->formula, $index, 2), PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); $index += 2; continue; } } // standard infix operators - if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->_formula{$index}) !== false) { + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->formula{$index}) !== false) { if (strlen($value) > 0) { $tokens1[] =new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); $value = ""; } - $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX); + $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX); ++$index; continue; } // standard postfix operators (only one) - if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->_formula{$index}) !== false) { + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->formula{$index}) !== false) { if (strlen($value) > 0) { $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); $value = ""; } - $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX); + $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX); ++$index; continue; } // start subexpression or function - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) { + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) { if (strlen($value) > 0) { $tmp = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); $tokens1[] = $tmp; @@ -417,7 +423,7 @@ private function _parseToTokens() { } // function, subexpression, or array parameters, or operand unions - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::COMMA) { + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::COMMA) { if (strlen($value) > 0) { $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); $value = ""; @@ -438,7 +444,7 @@ private function _parseToTokens() { } // stop subexpression - if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) { + if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) { if (strlen($value) > 0) { $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); $value = ""; @@ -454,7 +460,7 @@ private function _parseToTokens() { } // token accumulation - $value .= $this->_formula{$index}; + $value .= $this->formula{$index}; ++$index; } @@ -516,7 +522,7 @@ private function _parseToTokens() { // move tokens to final list, switching infix "-" operators to prefix when appropriate, switching infix "+" operators // to noop when appropriate, identifying operand and infix-operator subtypes, and pulling "@" from function names - $this->_tokens = array(); + $this->tokens = array(); $tokenCount = count($tokens2); for ($i = 0; $i < $tokenCount; ++$i) { @@ -539,53 +545,55 @@ private function _parseToTokens() { if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "-") { if ($i == 0) { $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); - } else if ( - (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || - (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || - ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || - ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) - ) { + } elseif ((($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && + ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && + ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)) { $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); } else { $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); } - $this->_tokens[] = $token; + $this->tokens[] = $token; continue; } if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "+") { if ($i == 0) { continue; - } else if ( - (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || - (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || - ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || - ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) - ) { + } elseif ((($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && + ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && + ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)) { $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); } else { continue; } - $this->_tokens[] = $token; + $this->tokens[] = $token; continue; } - if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && + $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { if (strpos("<>=", substr($token->getValue(), 0, 1)) !== false) { $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); - } else if ($token->getValue() == "&") { + } elseif ($token->getValue() == "&") { $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_CONCATENATION); } else { $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); } - $this->_tokens[] = $token; + $this->tokens[] = $token; continue; } - if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND && + $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { if (!is_numeric($token->getValue())) { if (strtoupper($token->getValue()) == "TRUE" || strtoupper($token->getValue() == "FALSE")) { $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); @@ -596,7 +604,7 @@ private function _parseToTokens() { $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NUMBER); } - $this->_tokens[] = $token; + $this->tokens[] = $token; continue; } @@ -608,7 +616,7 @@ private function _parseToTokens() { } } - $this->_tokens[] = $token; + $this->tokens[] = $token; } } } diff --git a/Classes/PHPExcel/Calculation/FormulaToken.php b/Classes/PHPExcel/Calculation/FormulaToken.php index f52556177..41c6e3d5d 100644 --- a/Classes/PHPExcel/Calculation/FormulaToken.php +++ b/Classes/PHPExcel/Calculation/FormulaToken.php @@ -1,30 +1,4 @@ _value = $pValue; - $this->_tokenType = $pTokenType; - $this->_tokenSubType = $pTokenSubType; + $this->value = $pValue; + $this->tokenType = $pTokenType; + $this->tokenSubType = $pTokenSubType; } /** @@ -125,8 +119,9 @@ public function __construct($pValue, $pTokenType = PHPExcel_Calculation_FormulaT * * @return string */ - public function getValue() { - return $this->_value; + public function getValue() + { + return $this->value; } /** @@ -134,8 +129,9 @@ public function getValue() { * * @param string $value */ - public function setValue($value) { - $this->_value = $value; + public function setValue($value) + { + $this->value = $value; } /** @@ -143,8 +139,9 @@ public function setValue($value) { * * @return string */ - public function getTokenType() { - return $this->_tokenType; + public function getTokenType() + { + return $this->tokenType; } /** @@ -152,8 +149,9 @@ public function getTokenType() { * * @param string $value */ - public function setTokenType($value = PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN) { - $this->_tokenType = $value; + public function setTokenType($value = PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN) + { + $this->tokenType = $value; } /** @@ -161,8 +159,9 @@ public function setTokenType($value = PHPExcel_Calculation_FormulaToken::TOKEN_T * * @return string */ - public function getTokenSubType() { - return $this->_tokenSubType; + public function getTokenSubType() + { + return $this->tokenSubType; } /** @@ -170,7 +169,8 @@ public function getTokenSubType() { * * @param string $value */ - public function setTokenSubType($value = PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { - $this->_tokenSubType = $value; + public function setTokenSubType($value = PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) + { + $this->tokenSubType = $value; } } diff --git a/Classes/PHPExcel/Calculation/Function.php b/Classes/PHPExcel/Calculation/Function.php index 5cda0f122..d58cef253 100644 --- a/Classes/PHPExcel/Calculation/Function.php +++ b/Classes/PHPExcel/Calculation/Function.php @@ -1,6 +1,7 @@ _category = $pCategory; - $this->_excelName = $pExcelName; - $this->_phpExcelName = $pPHPExcelName; + $this->category = $pCategory; + $this->excelName = $pExcelName; + $this->phpExcelName = $pPHPExcelName; } else { throw new PHPExcel_Calculation_Exception("Invalid parameters passed."); } @@ -93,8 +86,9 @@ public function __construct($pCategory = NULL, $pExcelName = NULL, $pPHPExcelNam * * @return string */ - public function getCategory() { - return $this->_category; + public function getCategory() + { + return $this->category; } /** @@ -103,9 +97,10 @@ public function getCategory() { * @param string $value * @throws PHPExcel_Calculation_Exception */ - public function setCategory($value = null) { + public function setCategory($value = null) + { if (!is_null($value)) { - $this->_category = $value; + $this->category = $value; } else { throw new PHPExcel_Calculation_Exception("Invalid parameter passed."); } @@ -116,8 +111,9 @@ public function setCategory($value = null) { * * @return string */ - public function getExcelName() { - return $this->_excelName; + public function getExcelName() + { + return $this->excelName; } /** @@ -125,8 +121,9 @@ public function getExcelName() { * * @param string $value */ - public function setExcelName($value) { - $this->_excelName = $value; + public function setExcelName($value) + { + $this->excelName = $value; } /** @@ -134,8 +131,9 @@ public function setExcelName($value) { * * @return string */ - public function getPHPExcelName() { - return $this->_phpExcelName; + public function getPHPExcelName() + { + return $this->phpExcelName; } /** @@ -143,7 +141,8 @@ public function getPHPExcelName() { * * @param string $value */ - public function setPHPExcelName($value) { - $this->_phpExcelName = $value; + public function setPHPExcelName($value) + { + $this->phpExcelName = $value; } } diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index 8b9da3115..b10f242c5 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -1,30 +1,4 @@ '#NULL!', - 'divisionbyzero' => '#DIV/0!', - 'value' => '#VALUE!', - 'reference' => '#REF!', - 'name' => '#NAME?', - 'num' => '#NUM!', - 'na' => '#N/A', - 'gettingdata' => '#GETTING_DATA' - ); + protected static $_errorCodes = array( + 'null' => '#NULL!', + 'divisionbyzero' => '#DIV/0!', + 'value' => '#VALUE!', + 'reference' => '#REF!', + 'name' => '#NAME?', + 'num' => '#NUM!', + 'na' => '#N/A', + 'gettingdata' => '#GETTING_DATA' + ); /** @@ -113,15 +107,16 @@ class PHPExcel_Calculation_Functions { * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' * @return boolean (Success or Failure) */ - public static function setCompatibilityMode($compatibilityMode) { + public static function setCompatibilityMode($compatibilityMode) + { if (($compatibilityMode == self::COMPATIBILITY_EXCEL) || ($compatibilityMode == self::COMPATIBILITY_GNUMERIC) || ($compatibilityMode == self::COMPATIBILITY_OPENOFFICE)) { self::$compatibilityMode = $compatibilityMode; - return True; + return true; } - return False; - } // function setCompatibilityMode() + return false; + } /** @@ -135,9 +130,10 @@ public static function setCompatibilityMode($compatibilityMode) { * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' */ - public static function getCompatibilityMode() { + public static function getCompatibilityMode() + { return self::$compatibilityMode; - } // function getCompatibilityMode() + } /** @@ -152,15 +148,16 @@ public static function getCompatibilityMode() { * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' * @return boolean Success or failure */ - public static function setReturnDateType($returnDateType) { + public static function setReturnDateType($returnDateType) + { if (($returnDateType == self::RETURNDATE_PHP_NUMERIC) || ($returnDateType == self::RETURNDATE_PHP_OBJECT) || ($returnDateType == self::RETURNDATE_EXCEL)) { self::$ReturnDateType = $returnDateType; - return True; + return true; } - return False; - } // function setReturnDateType() + return false; + } /** @@ -174,9 +171,10 @@ public static function setReturnDateType($returnDateType) { * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' */ - public static function getReturnDateType() { + public static function getReturnDateType() + { return self::$ReturnDateType; - } // function getReturnDateType() + } /** @@ -186,9 +184,10 @@ public static function getReturnDateType() { * @category Error Returns * @return string #Not Yet Implemented */ - public static function DUMMY() { + public static function DUMMY() + { return '#Not Yet Implemented'; - } // function DUMMY() + } /** @@ -198,9 +197,10 @@ public static function DUMMY() { * @category Error Returns * @return string #Not Yet Implemented */ - public static function DIV0() { + public static function DIV0() + { return self::$_errorCodes['divisionbyzero']; - } // function DIV0() + } /** @@ -216,9 +216,10 @@ public static function DIV0() { * @category Logical Functions * @return string #N/A! */ - public static function NA() { + public static function NA() + { return self::$_errorCodes['na']; - } // function NA() + } /** @@ -230,9 +231,10 @@ public static function NA() { * @category Error Returns * @return string #NUM! */ - public static function NaN() { + public static function NaN() + { return self::$_errorCodes['num']; - } // function NaN() + } /** @@ -244,9 +246,10 @@ public static function NaN() { * @category Error Returns * @return string #NAME? */ - public static function NAME() { + public static function NAME() + { return self::$_errorCodes['name']; - } // function NAME() + } /** @@ -258,9 +261,10 @@ public static function NAME() { * @category Error Returns * @return string #REF! */ - public static function REF() { + public static function REF() + { return self::$_errorCodes['reference']; - } // function REF() + } /** @@ -272,9 +276,10 @@ public static function REF() { * @category Error Returns * @return string #NULL! */ - public static function NULL() { + public static function NULL() + { return self::$_errorCodes['null']; - } // function NULL() + } /** @@ -286,36 +291,44 @@ public static function NULL() { * @category Error Returns * @return string #VALUE! */ - public static function VALUE() { + public static function VALUE() + { return self::$_errorCodes['value']; - } // function VALUE() + } - public static function isMatrixValue($idx) { - return ((substr_count($idx,'.') <= 1) || (preg_match('/\.[A-Z]/',$idx) > 0)); + public static function isMatrixValue($idx) + { + return ((substr_count($idx, '.') <= 1) || (preg_match('/\.[A-Z]/', $idx) > 0)); } - public static function isValue($idx) { - return (substr_count($idx,'.') == 0); + public static function isValue($idx) + { + return (substr_count($idx, '.') == 0); } - public static function isCellValue($idx) { - return (substr_count($idx,'.') > 1); + public static function isCellValue($idx) + { + return (substr_count($idx, '.') > 1); } - public static function _ifCondition($condition) { + public static function _ifCondition($condition) + { $condition = PHPExcel_Calculation_Functions::flattenSingleValue($condition); - if (!isset($condition{0})) + if (!isset($condition{0})) { $condition = '=""'; - if (!in_array($condition{0},array('>', '<', '='))) { - if (!is_numeric($condition)) { $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); } - return '='.$condition; + } + if (!in_array($condition{0}, array('>', '<', '='))) { + if (!is_numeric($condition)) { + $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); + } + return '=' . $condition; } else { - preg_match('/([<>=]+)(.*)/',$condition,$matches); - list(,$operator,$operand) = $matches; + preg_match('/([<>=]+)(.*)/', $condition, $matches); + list(, $operator, $operand) = $matches; if (!is_numeric($operand)) { $operand = str_replace('"', '""', $operand); @@ -324,8 +337,7 @@ public static function _ifCondition($condition) { return $operator.$operand; } - } // function _ifCondition() - + } /** * ERROR_TYPE @@ -333,18 +345,19 @@ public static function _ifCondition($condition) { * @param mixed $value Value to check * @return boolean */ - public static function ERROR_TYPE($value = '') { - $value = self::flattenSingleValue($value); + public static function ERROR_TYPE($value = '') + { + $value = self::flattenSingleValue($value); $i = 1; - foreach(self::$_errorCodes as $errorCode) { + foreach (self::$_errorCodes as $errorCode) { if ($value === $errorCode) { return $i; } ++$i; } return self::NA(); - } // function ERROR_TYPE() + } /** @@ -353,13 +366,14 @@ public static function ERROR_TYPE($value = '') { * @param mixed $value Value to check * @return boolean */ - public static function IS_BLANK($value = NULL) { + public static function IS_BLANK($value = null) + { if (!is_null($value)) { $value = self::flattenSingleValue($value); } return is_null($value); - } // function IS_BLANK() + } /** @@ -368,11 +382,12 @@ public static function IS_BLANK($value = NULL) { * @param mixed $value Value to check * @return boolean */ - public static function IS_ERR($value = '') { - $value = self::flattenSingleValue($value); + public static function IS_ERR($value = '') + { + $value = self::flattenSingleValue($value); return self::IS_ERROR($value) && (!self::IS_NA($value)); - } // function IS_ERR() + } /** @@ -381,13 +396,15 @@ public static function IS_ERR($value = '') { * @param mixed $value Value to check * @return boolean */ - public static function IS_ERROR($value = '') { - $value = self::flattenSingleValue($value); + public static function IS_ERROR($value = '') + { + $value = self::flattenSingleValue($value); - if (!is_string($value)) + if (!is_string($value)) { return false; + } return in_array($value, array_values(self::$_errorCodes)); - } // function IS_ERROR() + } /** @@ -396,11 +413,12 @@ public static function IS_ERROR($value = '') { * @param mixed $value Value to check * @return boolean */ - public static function IS_NA($value = '') { - $value = self::flattenSingleValue($value); + public static function IS_NA($value = '') + { + $value = self::flattenSingleValue($value); return ($value === self::NA()); - } // function IS_NA() + } /** @@ -409,15 +427,18 @@ public static function IS_NA($value = '') { * @param mixed $value Value to check * @return boolean */ - public static function IS_EVEN($value = NULL) { + public static function IS_EVEN($value = null) + { $value = self::flattenSingleValue($value); - if ($value === NULL) + if ($value === null) { return self::NAME(); - if ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) + } elseif ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) { return self::VALUE(); + } + return ($value % 2 == 0); - } // function IS_EVEN() + } /** @@ -426,15 +447,18 @@ public static function IS_EVEN($value = NULL) { * @param mixed $value Value to check * @return boolean */ - public static function IS_ODD($value = NULL) { + public static function IS_ODD($value = null) + { $value = self::flattenSingleValue($value); - if ($value === NULL) + if ($value === null) { return self::NAME(); - if ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) + } elseif ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) { return self::VALUE(); + } + return (abs($value) % 2 == 1); - } // function IS_ODD() + } /** @@ -443,14 +467,15 @@ public static function IS_ODD($value = NULL) { * @param mixed $value Value to check * @return boolean */ - public static function IS_NUMBER($value = NULL) { - $value = self::flattenSingleValue($value); + public static function IS_NUMBER($value = null) + { + $value = self::flattenSingleValue($value); if (is_string($value)) { - return False; + return false; } return is_numeric($value); - } // function IS_NUMBER() + } /** @@ -459,11 +484,12 @@ public static function IS_NUMBER($value = NULL) { * @param mixed $value Value to check * @return boolean */ - public static function IS_LOGICAL($value = NULL) { - $value = self::flattenSingleValue($value); + public static function IS_LOGICAL($value = null) + { + $value = self::flattenSingleValue($value); return is_bool($value); - } // function IS_LOGICAL() + } /** @@ -472,11 +498,12 @@ public static function IS_LOGICAL($value = NULL) { * @param mixed $value Value to check * @return boolean */ - public static function IS_TEXT($value = NULL) { - $value = self::flattenSingleValue($value); + public static function IS_TEXT($value = null) + { + $value = self::flattenSingleValue($value); return (is_string($value) && !self::IS_ERROR($value)); - } // function IS_TEXT() + } /** @@ -485,9 +512,10 @@ public static function IS_TEXT($value = NULL) { * @param mixed $value Value to check * @return boolean */ - public static function IS_NONTEXT($value = NULL) { + public static function IS_NONTEXT($value = null) + { return !self::IS_TEXT($value); - } // function IS_NONTEXT() + } /** @@ -495,9 +523,10 @@ public static function IS_NONTEXT($value = NULL) { * * @return string Version information */ - public static function VERSION() { + public static function VERSION() + { return 'PHPExcel ##VERSION##, ##DATE##'; - } // function VERSION() + } /** @@ -515,21 +544,22 @@ public static function VERSION() { * An error value The error value * Anything else 0 */ - public static function N($value = NULL) { + public static function N($value = null) + { while (is_array($value)) { $value = array_shift($value); } switch (gettype($value)) { - case 'double' : - case 'float' : - case 'integer' : + case 'double': + case 'float': + case 'integer': return $value; break; - case 'boolean' : + case 'boolean': return (integer) $value; break; - case 'string' : + case 'string': // Errors if ((strlen($value) > 0) && ($value{0} == '#')) { return $value; @@ -537,7 +567,7 @@ public static function N($value = NULL) { break; } return 0; - } // function N() + } /** @@ -554,11 +584,12 @@ public static function N($value = NULL) { * An error value 16 * Array or Matrix 64 */ - public static function TYPE($value = NULL) { - $value = self::flattenArrayIndexed($value); + public static function TYPE($value = null) + { + $value = self::flattenArrayIndexed($value); if (is_array($value) && (count($value) > 1)) { - $a = array_keys($value); - $a = array_pop($a); + end($value); + $a = key($value); // Range of cells is an error if (self::isCellValue($a)) { return 16; @@ -566,19 +597,19 @@ public static function TYPE($value = NULL) { } elseif (self::isMatrixValue($a)) { return 64; } - } elseif(empty($value)) { + } elseif (empty($value)) { // Empty Cell return 1; } - $value = self::flattenSingleValue($value); + $value = self::flattenSingleValue($value); - if (($value === NULL) || (is_float($value)) || (is_int($value))) { + if (($value === null) || (is_float($value)) || (is_int($value))) { return 1; - } elseif(is_bool($value)) { + } elseif (is_bool($value)) { return 4; - } elseif(is_array($value)) { + } elseif (is_array($value)) { return 64; - } elseif(is_string($value)) { + } elseif (is_string($value)) { // Errors if ((strlen($value) > 0) && ($value{0} == '#')) { return 16; @@ -586,7 +617,7 @@ public static function TYPE($value = NULL) { return 2; } return 0; - } // function TYPE() + } /** @@ -595,7 +626,8 @@ public static function TYPE($value = NULL) { * @param array $array Array to be flattened * @return array Flattened array */ - public static function flattenArray($array) { + public static function flattenArray($array) + { if (!is_array($array)) { return (array) $array; } @@ -618,7 +650,7 @@ public static function flattenArray($array) { } return $arrayValues; - } // function flattenArray() + } /** @@ -627,7 +659,8 @@ public static function flattenArray($array) { * @param array $array Array to be flattened * @return array Flattened array */ - public static function flattenArrayIndexed($array) { + public static function flattenArrayIndexed($array) + { if (!is_array($array)) { return (array) $array; } @@ -650,7 +683,7 @@ public static function flattenArrayIndexed($array) { } return $arrayValues; - } // function flattenArrayIndexed() + } /** @@ -659,15 +692,15 @@ public static function flattenArrayIndexed($array) { * @param mixed $value Array or scalar value * @return mixed */ - public static function flattenSingleValue($value = '') { + public static function flattenSingleValue($value = '') + { while (is_array($value)) { $value = array_pop($value); } return $value; - } // function flattenSingleValue() - -} // class PHPExcel_Calculation_Functions + } +} // @@ -676,19 +709,22 @@ public static function flattenSingleValue($value = '') { // So we test if they do exist for this version of PHP/operating platform; and if not we create them // if (!function_exists('acosh')) { - function acosh($x) { + function acosh($x) + { return 2 * log(sqrt(($x + 1) / 2) + sqrt(($x - 1) / 2)); } // function acosh() } if (!function_exists('asinh')) { - function asinh($x) { + function asinh($x) + { return log($x + sqrt(1 + $x * $x)); } // function asinh() } if (!function_exists('atanh')) { - function atanh($x) { + function atanh($x) + { return (log(1 + $x) - log(1 - $x)) / 2; } // function atanh() } @@ -700,22 +736,23 @@ function atanh($x) { // if ((!function_exists('mb_str_replace')) && (function_exists('mb_substr')) && (function_exists('mb_strlen')) && (function_exists('mb_strpos'))) { - function mb_str_replace($search, $replace, $subject) { - if(is_array($subject)) { + function mb_str_replace($search, $replace, $subject) + { + if (is_array($subject)) { $ret = array(); - foreach($subject as $key => $val) { + foreach ($subject as $key => $val) { $ret[$key] = mb_str_replace($search, $replace, $val); } return $ret; } - foreach((array) $search as $key => $s) { - if($s == '' && $s !== 0) { + foreach ((array) $search as $key => $s) { + if ($s == '' && $s !== 0) { continue; } $r = !is_array($replace) ? $replace : (array_key_exists($key, $replace) ? $replace[$key] : ''); $pos = mb_strpos($subject, $s, 0, 'UTF-8'); - while($pos !== false) { + while ($pos !== false) { $subject = mb_substr($subject, 0, $pos, 'UTF-8') . $r . mb_substr($subject, $pos + mb_strlen($s, 'UTF-8'), 65535, 'UTF-8'); $pos = mb_strpos($subject, $s, $pos + mb_strlen($r, 'UTF-8'), 'UTF-8'); } diff --git a/Classes/PHPExcel/Calculation/Logical.php b/Classes/PHPExcel/Calculation/Logical.php index ca5575cf3..dd65f0104 100644 --- a/Classes/PHPExcel/Calculation/Logical.php +++ b/Classes/PHPExcel/Calculation/Logical.php @@ -1,6 +1,16 @@ Date: Sun, 10 May 2015 23:25:04 +0100 Subject: [PATCH 345/467] More PSR-2 adjustments --- Classes/PHPExcel/Calculation/LookupRef.php | 347 ++--- Classes/PHPExcel/Calculation/MathTrig.php | 503 ++++--- Classes/PHPExcel/Calculation/Statistical.php | 1420 ++++++++++-------- Classes/PHPExcel/Calculation/TextData.php | 299 ++-- Classes/PHPExcel/Calculation/Token/Stack.php | 30 +- 5 files changed, 1370 insertions(+), 1229 deletions(-) diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index 86208f0d0..640f0c2eb 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -1,6 +1,16 @@ '') { - if (strpos($sheetText,' ') !== False) { $sheetText = "'".$sheetText."'"; } + if (strpos($sheetText, ' ') !== false) { + $sheetText = "'".$sheetText."'"; + } $sheetText .='!'; } if ((!is_bool($referenceStyle)) || $referenceStyle) { $rowRelative = $columnRelative = '$'; $column = PHPExcel_Cell::stringFromColumnIndex($column-1); - if (($relativity == 2) || ($relativity == 4)) { $columnRelative = ''; } - if (($relativity == 3) || ($relativity == 4)) { $rowRelative = ''; } + if (($relativity == 2) || ($relativity == 4)) { + $columnRelative = ''; + } + if (($relativity == 3) || ($relativity == 4)) { + $rowRelative = ''; + } return $sheetText.$columnRelative.$column.$rowRelative.$row; } else { - if (($relativity == 2) || ($relativity == 4)) { $column = '['.$column.']'; } - if (($relativity == 3) || ($relativity == 4)) { $row = '['.$row.']'; } + if (($relativity == 2) || ($relativity == 4)) { + $column = '['.$column.']'; + } + if (($relativity == 3) || ($relativity == 4)) { + $row = '['.$row.']'; + } return $sheetText.'R'.$row.'C'.$column; } - } // function CELL_ADDRESS() + } /** @@ -109,33 +110,36 @@ public static function CELL_ADDRESS($row, $column, $relativity=1, $referenceStyl * @param cellAddress A reference to a range of cells for which you want the column numbers * @return integer or array of integer */ - public static function COLUMN($cellAddress=Null) { - if (is_null($cellAddress) || trim($cellAddress) === '') { return 0; } + public static function COLUMN($cellAddress = null) + { + if (is_null($cellAddress) || trim($cellAddress) === '') { + return 0; + } if (is_array($cellAddress)) { - foreach($cellAddress as $columnKey => $value) { - $columnKey = preg_replace('/[^a-z]/i','',$columnKey); + foreach ($cellAddress as $columnKey => $value) { + $columnKey = preg_replace('/[^a-z]/i', '', $columnKey); return (integer) PHPExcel_Cell::columnIndexFromString($columnKey); } } else { - if (strpos($cellAddress,'!') !== false) { - list($sheet,$cellAddress) = explode('!',$cellAddress); + if (strpos($cellAddress, '!') !== false) { + list($sheet, $cellAddress) = explode('!', $cellAddress); } - if (strpos($cellAddress,':') !== false) { - list($startAddress,$endAddress) = explode(':',$cellAddress); - $startAddress = preg_replace('/[^a-z]/i','',$startAddress); - $endAddress = preg_replace('/[^a-z]/i','',$endAddress); + if (strpos($cellAddress, ':') !== false) { + list($startAddress, $endAddress) = explode(':', $cellAddress); + $startAddress = preg_replace('/[^a-z]/i', '', $startAddress); + $endAddress = preg_replace('/[^a-z]/i', '', $endAddress); $returnValue = array(); do { $returnValue[] = (integer) PHPExcel_Cell::columnIndexFromString($startAddress); } while ($startAddress++ != $endAddress); return $returnValue; } else { - $cellAddress = preg_replace('/[^a-z]/i','',$cellAddress); + $cellAddress = preg_replace('/[^a-z]/i', '', $cellAddress); return (integer) PHPExcel_Cell::columnIndexFromString($cellAddress); } } - } // function COLUMN() + } /** @@ -149,7 +153,8 @@ public static function COLUMN($cellAddress=Null) { * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of columns * @return integer The number of columns in cellAddress */ - public static function COLUMNS($cellAddress = null) { + public static function COLUMNS($cellAddress = null) + { if (is_null($cellAddress) || $cellAddress === '') { return 1; } elseif (!is_array($cellAddress)) { @@ -158,14 +163,14 @@ public static function COLUMNS($cellAddress = null) { reset($cellAddress); $isMatrix = (is_numeric(key($cellAddress))); - list($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); + list($columns, $rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); if ($isMatrix) { return $rows; } else { return $columns; } - } // function COLUMNS() + } /** @@ -182,34 +187,37 @@ public static function COLUMNS($cellAddress = null) { * @param cellAddress A reference to a range of cells for which you want the row numbers * @return integer or array of integer */ - public static function ROW($cellAddress=Null) { - if (is_null($cellAddress) || trim($cellAddress) === '') { return 0; } + public static function ROW($cellAddress = null) + { + if (is_null($cellAddress) || trim($cellAddress) === '') { + return 0; + } if (is_array($cellAddress)) { - foreach($cellAddress as $columnKey => $rowValue) { - foreach($rowValue as $rowKey => $cellValue) { - return (integer) preg_replace('/[^0-9]/i','',$rowKey); + foreach ($cellAddress as $columnKey => $rowValue) { + foreach ($rowValue as $rowKey => $cellValue) { + return (integer) preg_replace('/[^0-9]/i', '', $rowKey); } } } else { - if (strpos($cellAddress,'!') !== false) { - list($sheet,$cellAddress) = explode('!',$cellAddress); + if (strpos($cellAddress, '!') !== false) { + list($sheet, $cellAddress) = explode('!', $cellAddress); } - if (strpos($cellAddress,':') !== false) { - list($startAddress,$endAddress) = explode(':',$cellAddress); - $startAddress = preg_replace('/[^0-9]/','',$startAddress); - $endAddress = preg_replace('/[^0-9]/','',$endAddress); + if (strpos($cellAddress, ':') !== false) { + list($startAddress, $endAddress) = explode(':', $cellAddress); + $startAddress = preg_replace('/[^0-9]/', '', $startAddress); + $endAddress = preg_replace('/[^0-9]/', '', $endAddress); $returnValue = array(); do { $returnValue[][] = (integer) $startAddress; } while ($startAddress++ != $endAddress); return $returnValue; } else { - list($cellAddress) = explode(':',$cellAddress); - return (integer) preg_replace('/[^0-9]/','',$cellAddress); + list($cellAddress) = explode(':', $cellAddress); + return (integer) preg_replace('/[^0-9]/', '', $cellAddress); } } - } // function ROW() + } /** @@ -223,7 +231,8 @@ public static function ROW($cellAddress=Null) { * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of rows * @return integer The number of rows in cellAddress */ - public static function ROWS($cellAddress=Null) { + public static function ROWS($cellAddress = null) + { if (is_null($cellAddress) || $cellAddress === '') { return 1; } elseif (!is_array($cellAddress)) { @@ -232,14 +241,14 @@ public static function ROWS($cellAddress=Null) { reset($cellAddress); $isMatrix = (is_numeric(key($cellAddress))); - list($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); + list($columns, $rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); if ($isMatrix) { return $columns; } else { return $rows; } - } // function ROWS() + } /** @@ -255,12 +264,13 @@ public static function ROWS($cellAddress=Null) { * @param PHPExcel_Cell $pCell The cell to set the hyperlink in * @return mixed The value of $displayName (or $linkURL if $displayName was blank) */ - public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Cell $pCell = null) { + public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Cell $pCell = null) + { $args = func_get_args(); $pCell = array_pop($args); - $linkURL = (is_null($linkURL)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($linkURL); - $displayName = (is_null($displayName)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($displayName); + $linkURL = (is_null($linkURL)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($linkURL); + $displayName = (is_null($displayName)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($displayName); if ((!is_object($pCell)) || (trim($linkURL) == '')) { return PHPExcel_Calculation_Functions::REF(); @@ -273,7 +283,7 @@ public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Ce $pCell->getHyperlink()->setUrl($linkURL); return $displayName; - } // function HYPERLINK() + } /** @@ -294,16 +304,17 @@ public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Ce * @todo Support for the optional a1 parameter introduced in Excel 2010 * */ - public static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL) { + public static function INDIRECT($cellAddress = null, PHPExcel_Cell $pCell = null) + { $cellAddress = PHPExcel_Calculation_Functions::flattenSingleValue($cellAddress); if (is_null($cellAddress) || $cellAddress === '') { return PHPExcel_Calculation_Functions::REF(); } $cellAddress1 = $cellAddress; - $cellAddress2 = NULL; - if (strpos($cellAddress,':') !== false) { - list($cellAddress1,$cellAddress2) = explode(':',$cellAddress); + $cellAddress2 = null; + if (strpos($cellAddress, ':') !== false) { + list($cellAddress1, $cellAddress2) = explode(':', $cellAddress); } if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress1, $matches)) || @@ -312,27 +323,27 @@ public static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL return PHPExcel_Calculation_Functions::REF(); } - if (strpos($cellAddress,'!') !== FALSE) { - list($sheetName, $cellAddress) = explode('!',$cellAddress); + if (strpos($cellAddress, '!') !== false) { + list($sheetName, $cellAddress) = explode('!', $cellAddress); $sheetName = trim($sheetName, "'"); $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); } else { $pSheet = $pCell->getWorksheet(); } - return PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, FALSE); + return PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, false); } - if (strpos($cellAddress,'!') !== FALSE) { - list($sheetName,$cellAddress) = explode('!',$cellAddress); + if (strpos($cellAddress, '!') !== false) { + list($sheetName, $cellAddress) = explode('!', $cellAddress); $sheetName = trim($sheetName, "'"); $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); } else { $pSheet = $pCell->getWorksheet(); } - return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, FALSE); - } // function INDIRECT() + return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, false); + } /** @@ -360,12 +371,13 @@ public static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL * @param width The width, in number of columns, that you want the returned reference to be. Width must be a positive number. * @return string A reference to a cell or range of cells */ - public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null,$width=null) { - $rows = PHPExcel_Calculation_Functions::flattenSingleValue($rows); - $columns = PHPExcel_Calculation_Functions::flattenSingleValue($columns); - $height = PHPExcel_Calculation_Functions::flattenSingleValue($height); - $width = PHPExcel_Calculation_Functions::flattenSingleValue($width); - if ($cellAddress == Null) { + public static function OFFSET($cellAddress = null, $rows = 0, $columns = 0, $height = null, $width = null) + { + $rows = PHPExcel_Calculation_Functions::flattenSingleValue($rows); + $columns = PHPExcel_Calculation_Functions::flattenSingleValue($columns); + $height = PHPExcel_Calculation_Functions::flattenSingleValue($height); + $width = PHPExcel_Calculation_Functions::flattenSingleValue($width); + if ($cellAddress == null) { return 0; } @@ -375,18 +387,18 @@ public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null, return PHPExcel_Calculation_Functions::REF(); } - $sheetName = NULL; - if (strpos($cellAddress,"!")) { - list($sheetName,$cellAddress) = explode("!",$cellAddress); + $sheetName = null; + if (strpos($cellAddress, "!")) { + list($sheetName, $cellAddress) = explode("!", $cellAddress); $sheetName = trim($sheetName, "'"); } - if (strpos($cellAddress,":")) { - list($startCell,$endCell) = explode(":",$cellAddress); + if (strpos($cellAddress, ":")) { + list($startCell, $endCell) = explode(":", $cellAddress); } else { $startCell = $endCell = $cellAddress; } - list($startCellColumn,$startCellRow) = PHPExcel_Cell::coordinateFromString($startCell); - list($endCellColumn,$endCellRow) = PHPExcel_Cell::coordinateFromString($endCell); + list($startCellColumn, $startCellRow) = PHPExcel_Cell::coordinateFromString($startCell); + list($endCellColumn, $endCellRow) = PHPExcel_Cell::coordinateFromString($endCell); $startCellRow += $rows; $startCellColumn = PHPExcel_Cell::columnIndexFromString($startCellColumn) - 1; @@ -419,14 +431,14 @@ public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null, $cellAddress .= ':'.$endCellColumn.$endCellRow; } - if ($sheetName !== NULL) { + if ($sheetName !== null) { $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); } else { $pSheet = $pCell->getWorksheet(); } - return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, False); - } // function OFFSET() + return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, false); + } /** @@ -447,12 +459,13 @@ public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null, * text. * @return mixed The selected value */ - public static function CHOOSE() { + public static function CHOOSE() + { $chooseArgs = func_get_args(); $chosenEntry = PHPExcel_Calculation_Functions::flattenArray(array_shift($chooseArgs)); $entryCount = count($chooseArgs) - 1; - if(is_array($chosenEntry)) { + if (is_array($chosenEntry)) { $chosenEntry = array_shift($chosenEntry); } if ((is_numeric($chosenEntry)) && (!is_bool($chosenEntry))) { @@ -470,7 +483,7 @@ public static function CHOOSE() { } else { return $chooseArgs[$chosenEntry]; } - } // function CHOOSE() + } /** @@ -486,7 +499,8 @@ public static function CHOOSE() { * @param match_type The number -1, 0, or 1. -1 means above, 0 means exact match, 1 means below. If match_type is 1 or -1, the list has to be ordered. * @return integer The relative position of the found item */ - public static function MATCH($lookup_value, $lookup_array, $match_type=1) { + public static function MATCH($lookup_value, $lookup_array, $match_type = 1) + { $lookup_array = PHPExcel_Calculation_Functions::flattenArray($lookup_array); $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); $match_type = (is_null($match_type)) ? 1 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($match_type); @@ -510,7 +524,7 @@ public static function MATCH($lookup_value, $lookup_array, $match_type=1) { } // lookup_array should contain only number, text, or logical values, or empty (null) cells - foreach($lookup_array as $i => $lookupArrayValue) { + foreach ($lookup_array as $i => $lookupArrayValue) { // check the type of the value if ((!is_numeric($lookupArrayValue)) && (!is_string($lookupArrayValue)) && (!is_bool($lookupArrayValue)) && (!is_null($lookupArrayValue))) { @@ -521,7 +535,7 @@ public static function MATCH($lookup_value, $lookup_array, $match_type=1) { $lookup_array[$i] = strtolower($lookupArrayValue); } if ((is_null($lookupArrayValue)) && (($match_type == 1) || ($match_type == -1))) { - $lookup_array = array_slice($lookup_array,0,$i-1); + $lookup_array = array_slice($lookup_array, 0, $i-1); } } @@ -529,7 +543,7 @@ public static function MATCH($lookup_value, $lookup_array, $match_type=1) { if ($match_type == 1) { asort($lookup_array); $keySet = array_keys($lookup_array); - } elseif($match_type == -1) { + } elseif ($match_type == -1) { arsort($lookup_array); $keySet = array_keys($lookup_array); } @@ -537,42 +551,25 @@ public static function MATCH($lookup_value, $lookup_array, $match_type=1) { // ** // find the match // ** - // loop on the cells -// var_dump($lookup_array); -// echo '
'; - foreach($lookup_array as $i => $lookupArrayValue) { + foreach ($lookup_array as $i => $lookupArrayValue) { if (($match_type == 0) && ($lookupArrayValue == $lookup_value)) { // exact match return ++$i; } elseif (($match_type == -1) && ($lookupArrayValue <= $lookup_value)) { -// echo '$i = '.$i.' => '; -// var_dump($lookupArrayValue); -// echo '
'; -// echo 'Keyset = '; -// var_dump($keySet); -// echo '
'; - $i = array_search($i,$keySet); -// echo '$i='.$i.'
'; + $i = array_search($i, $keySet); // if match_type is -1 <=> find the smallest value that is greater than or equal to lookup_value - if ($i < 1){ - // 1st cell was allready smaller than the lookup_value + if ($i < 1) { + // 1st cell was already smaller than the lookup_value break; } else { // the previous cell was the match return $keySet[$i-1]+1; } } elseif (($match_type == 1) && ($lookupArrayValue >= $lookup_value)) { -// echo '$i = '.$i.' => '; -// var_dump($lookupArrayValue); -// echo '
'; -// echo 'Keyset = '; -// var_dump($keySet); -// echo '
'; - $i = array_search($i,$keySet); -// echo '$i='.$i.'
'; + $i = array_search($i, $keySet); // if match_type is 1 <=> find the largest value that is less than or equal to lookup_value - if ($i < 1){ - // 1st cell was allready bigger than the lookup_value + if ($i < 1) { + // 1st cell was already bigger than the lookup_value break; } else { // the previous cell was the match @@ -583,7 +580,7 @@ public static function MATCH($lookup_value, $lookup_array, $match_type=1) { // unsuccessful in finding a match, return #N/A error value return PHPExcel_Calculation_Functions::NA(); - } // function MATCH() + } /** @@ -599,8 +596,8 @@ public static function MATCH($lookup_value, $lookup_array, $match_type=1) { * @param column_num The column in array from which to return a value. If column_num is omitted, row_num is required. * @return mixed the value of a specified cell or array of cells */ - public static function INDEX($arrayValues,$rowNum = 0,$columnNum = 0) { - + public static function INDEX($arrayValues, $rowNum = 0, $columnNum = 0) + { if (($rowNum < 0) || ($columnNum < 0)) { return PHPExcel_Calculation_Functions::VALUE(); } @@ -620,7 +617,7 @@ public static function INDEX($arrayValues,$rowNum = 0,$columnNum = 0) { } $rowNum = $rowKeys[--$rowNum]; $returnArray = array(); - foreach($arrayValues as $arrayColumn) { + foreach ($arrayValues as $arrayColumn) { if (is_array($arrayColumn)) { if (isset($arrayColumn[$rowNum])) { $returnArray[] = $arrayColumn[$rowNum]; @@ -642,7 +639,7 @@ public static function INDEX($arrayValues,$rowNum = 0,$columnNum = 0) { $rowNum = $rowKeys[--$rowNum]; return $arrayValues[$rowNum][$columnNum]; - } // function INDEX() + } /** @@ -653,43 +650,48 @@ public static function INDEX($arrayValues,$rowNum = 0,$columnNum = 0) { * * Unlike the Excel TRANSPOSE function, which will only work on a single row or column, this function will transpose a full matrix. */ - public static function TRANSPOSE($matrixData) { + public static function TRANSPOSE($matrixData) + { $returnMatrix = array(); - if (!is_array($matrixData)) { $matrixData = array(array($matrixData)); } + if (!is_array($matrixData)) { + $matrixData = array(array($matrixData)); + } $column = 0; - foreach($matrixData as $matrixRow) { + foreach ($matrixData as $matrixRow) { $row = 0; - foreach($matrixRow as $matrixCell) { + foreach ($matrixRow as $matrixCell) { $returnMatrix[$row][$column] = $matrixCell; ++$row; } ++$column; } return $returnMatrix; - } // function TRANSPOSE() + } - private static function _vlookupSort($a,$b) { + private static function vlookupSort($a, $b) + { reset($a); $firstColumn = key($a); if (strtolower($a[$firstColumn]) == strtolower($b[$firstColumn])) { return 0; } return (strtolower($a[$firstColumn]) < strtolower($b[$firstColumn])) ? -1 : 1; - } // function _vlookupSort() + } /** - * VLOOKUP - * The VLOOKUP function searches for value in the left-most column of lookup_array and returns the value in the same row based on the index_number. - * @param lookup_value The value that you want to match in lookup_array - * @param lookup_array The range of cells being searched - * @param index_number The column number in table_array from which the matching value must be returned. The first column is 1. - * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. - * @return mixed The value of the found cell - */ - public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) { + * VLOOKUP + * The VLOOKUP function searches for value in the left-most column of lookup_array and returns the value in the same row based on the index_number. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param index_number The column number in table_array from which the matching value must be returned. The first column is 1. + * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. + * @return mixed The value of the found cell + */ + public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match = true) + { $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); $index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); @@ -715,11 +717,11 @@ public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not } if (!$not_exact_match) { - uasort($lookup_array,array('self','_vlookupSort')); + uasort($lookup_array, array('self', 'vlookupSort')); } - $rowNumber = $rowValue = False; - foreach($lookup_array as $rowKey => $rowData) { + $rowNumber = $rowValue = false; + foreach ($lookup_array as $rowKey => $rowData) { if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) || (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) { break; @@ -739,19 +741,20 @@ public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not } return PHPExcel_Calculation_Functions::NA(); - } // function VLOOKUP() + } -/** - * HLOOKUP - * The HLOOKUP function searches for value in the top-most row of lookup_array and returns the value in the same column based on the index_number. - * @param lookup_value The value that you want to match in lookup_array - * @param lookup_array The range of cells being searched - * @param index_number The row number in table_array from which the matching value must be returned. The first row is 1. - * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. - * @return mixed The value of the found cell - */ - public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) { + /** + * HLOOKUP + * The HLOOKUP function searches for value in the top-most row of lookup_array and returns the value in the same column based on the index_number. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param index_number The row number in table_array from which the matching value must be returned. The first row is 1. + * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. + * @return mixed The value of the found cell + */ + public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match = true) + { $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); $index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); @@ -781,8 +784,8 @@ public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not $firstRowH = asort($lookup_array[$firstColumn]); } - $rowNumber = $rowValue = False; - foreach($lookup_array[$firstColumn] as $rowKey => $rowData) { + $rowNumber = $rowValue = false; + foreach ($lookup_array[$firstColumn] as $rowKey => $rowData) { if ((is_numeric($lookup_value) && is_numeric($rowData) && ($rowData > $lookup_value)) || (!is_numeric($lookup_value) && !is_numeric($rowData) && (strtolower($rowData) > strtolower($lookup_value)))) { break; @@ -802,7 +805,7 @@ public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not } return PHPExcel_Calculation_Functions::NA(); - } // function HLOOKUP() + } /** @@ -813,8 +816,9 @@ public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not * @param result_vector The column from which the matching value must be returned * @return mixed The value of the found cell */ - public static function LOOKUP($lookup_value, $lookup_vector, $result_vector=null) { - $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + public static function LOOKUP($lookup_value, $lookup_vector, $result_vector = null) + { + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); if (!is_array($lookup_vector)) { return PHPExcel_Calculation_Functions::NA(); @@ -849,7 +853,7 @@ public static function LOOKUP($lookup_value, $lookup_vector, $result_vector=null $lookup_vector = array_shift($lookup_vector); } if ($lookupColumns != 2) { - foreach($lookup_vector as &$value) { + foreach ($lookup_vector as &$value) { if (is_array($value)) { $k = array_keys($value); $key1 = $key2 = array_shift($k); @@ -869,7 +873,6 @@ public static function LOOKUP($lookup_value, $lookup_vector, $result_vector=null unset($value); } - return self::VLOOKUP($lookup_value,$lookup_vector,2); - } // function LOOKUP() - -} // class PHPExcel_Calculation_LookupRef + return self::VLOOKUP($lookup_value, $lookup_vector, 2); + } +} diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index 3b3d64fe6..df0c88b8d 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -1,6 +1,16 @@ 1; --$i) { if (($value % $i) == 0) { - $factorArray = array_merge($factorArray,self::_factors($value / $i)); - $factorArray = array_merge($factorArray,self::_factors($i)); + $factorArray = array_merge($factorArray, self::factors($value / $i)); + $factorArray = array_merge($factorArray, self::factors($i)); if ($i <= sqrt($value)) { break; } @@ -67,12 +59,13 @@ private static function _factors($value) { } else { return array((integer) $value); } - } // function _factors() + } - private static function _romanCut($num, $n) { + private static function romanCut($num, $n) + { return ($num - ($num % $n ) ) / $n; - } // function _romanCut() + } /** @@ -97,12 +90,13 @@ private static function _romanCut($num, $n) { * @param float $yCoordinate The y-coordinate of the point. * @return float The inverse tangent of the specified x- and y-coordinates. */ - public static function ATAN2($xCoordinate = NULL, $yCoordinate = NULL) { - $xCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($xCoordinate); - $yCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($yCoordinate); + public static function ATAN2($xCoordinate = null, $yCoordinate = null) + { + $xCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($xCoordinate); + $yCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($yCoordinate); - $xCoordinate = ($xCoordinate !== NULL) ? $xCoordinate : 0.0; - $yCoordinate = ($yCoordinate !== NULL) ? $yCoordinate : 0.0; + $xCoordinate = ($xCoordinate !== null) ? $xCoordinate : 0.0; + $yCoordinate = ($yCoordinate !== null) ? $yCoordinate : 0.0; if (((is_numeric($xCoordinate)) || (is_bool($xCoordinate))) && ((is_numeric($yCoordinate))) || (is_bool($yCoordinate))) { @@ -116,7 +110,7 @@ public static function ATAN2($xCoordinate = NULL, $yCoordinate = NULL) { return atan2($yCoordinate, $xCoordinate); } return PHPExcel_Calculation_Functions::VALUE(); - } // function ATAN2() + } /** @@ -136,13 +130,14 @@ public static function ATAN2($xCoordinate = NULL, $yCoordinate = NULL) { * @param float $significance The multiple to which you want to round. * @return float Rounded Number */ - public static function CEILING($number, $significance = NULL) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); + public static function CEILING($number, $significance = null) + { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); if ((is_null($significance)) && (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { - $significance = $number/abs($number); + $significance = $number / abs($number); } if ((is_numeric($number)) && (is_numeric($significance))) { @@ -155,7 +150,7 @@ public static function CEILING($number, $significance = NULL) { } } return PHPExcel_Calculation_Functions::VALUE(); - } // function CEILING() + } /** @@ -173,7 +168,8 @@ public static function CEILING($number, $significance = NULL) { * @param int $numInSet Number of objects in each combination * @return int Number of combinations */ - public static function COMBIN($numObjs, $numInSet) { + public static function COMBIN($numObjs, $numInSet) + { $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); @@ -186,7 +182,7 @@ public static function COMBIN($numObjs, $numInSet) { return round(self::FACT($numObjs) / self::FACT($numObjs - $numInSet)) / self::FACT($numInSet); } return PHPExcel_Calculation_Functions::VALUE(); - } // function COMBIN() + } /** @@ -206,8 +202,9 @@ public static function COMBIN($numObjs, $numInSet) { * @param float $number Number to round * @return int Rounded Number */ - public static function EVEN($number) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + public static function EVEN($number) + { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); if (is_null($number)) { return 0; @@ -217,10 +214,10 @@ public static function EVEN($number) { if (is_numeric($number)) { $significance = 2 * self::SIGN($number); - return (int) self::CEILING($number,$significance); + return (int) self::CEILING($number, $significance); } return PHPExcel_Calculation_Functions::VALUE(); - } // function EVEN() + } /** @@ -237,7 +234,8 @@ public static function EVEN($number) { * @param float $factVal Factorial Value * @return int Factorial */ - public static function FACT($factVal) { + public static function FACT($factVal) + { $factVal = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); if (is_numeric($factVal)) { @@ -258,7 +256,7 @@ public static function FACT($factVal) { return $factorial ; } return PHPExcel_Calculation_Functions::VALUE(); - } // function FACT() + } /** @@ -274,7 +272,8 @@ public static function FACT($factVal) { * @param float $factVal Factorial Value * @return int Double Factorial */ - public static function FACTDOUBLE($factVal) { + public static function FACTDOUBLE($factVal) + { $factLoop = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); if (is_numeric($factLoop)) { @@ -290,7 +289,7 @@ public static function FACTDOUBLE($factVal) { return $factorial ; } return PHPExcel_Calculation_Functions::VALUE(); - } // function FACTDOUBLE() + } /** @@ -307,11 +306,13 @@ public static function FACTDOUBLE($factVal) { * @param float $significance Significance * @return float Rounded Number */ - public static function FLOOR($number, $significance = NULL) { + public static function FLOOR($number, $significance = null) + { $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); - if ((is_null($significance)) && (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { + if ((is_null($significance)) && + (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { $significance = $number/abs($number); } @@ -325,10 +326,10 @@ public static function FLOOR($number, $significance = NULL) { } else { return PHPExcel_Calculation_Functions::NaN(); } - } else + } return PHPExcel_Calculation_Functions::VALUE(); - } // function FLOOR() + } /** @@ -346,19 +347,20 @@ public static function FLOOR($number, $significance = NULL) { * @param mixed $arg,... Data values * @return integer Greatest Common Divisor */ - public static function GCD() { + public static function GCD() + { $returnValue = 1; $allValuesFactors = array(); // Loop through arguments - foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { if (!is_numeric($value)) { return PHPExcel_Calculation_Functions::VALUE(); } elseif ($value == 0) { continue; - } elseif($value < 0) { + } elseif ($value < 0) { return PHPExcel_Calculation_Functions::NaN(); } - $myFactors = self::_factors($value); + $myFactors = self::factors($value); $myCountedFactors = array_count_values($myFactors); $allValuesFactors[] = $myCountedFactors; } @@ -368,16 +370,16 @@ public static function GCD() { } $mergedArray = $allValuesFactors[0]; - for ($i=1;$i < $allValuesCount; ++$i) { - $mergedArray = array_intersect_key($mergedArray,$allValuesFactors[$i]); + for ($i=1; $i < $allValuesCount; ++$i) { + $mergedArray = array_intersect_key($mergedArray, $allValuesFactors[$i]); } $mergedArrayValues = count($mergedArray); if ($mergedArrayValues == 0) { return $returnValue; } elseif ($mergedArrayValues > 1) { - foreach($mergedArray as $mergedKey => $mergedValue) { - foreach($allValuesFactors as $highestPowerTest) { - foreach($highestPowerTest as $testKey => $testValue) { + foreach ($mergedArray as $mergedKey => $mergedValue) { + foreach ($allValuesFactors as $highestPowerTest) { + foreach ($highestPowerTest as $testKey => $testValue) { if (($testKey == $mergedKey) && ($testValue < $mergedValue)) { $mergedArray[$mergedKey] = $testValue; $mergedValue = $testValue; @@ -387,24 +389,24 @@ public static function GCD() { } $returnValue = 1; - foreach($mergedArray as $key => $value) { - $returnValue *= pow($key,$value); + foreach ($mergedArray as $key => $value) { + $returnValue *= pow($key, $value); } return $returnValue; } else { $keys = array_keys($mergedArray); $key = $keys[0]; $value = $mergedArray[$key]; - foreach($allValuesFactors as $testValue) { - foreach($testValue as $mergedKey => $mergedValue) { + foreach ($allValuesFactors as $testValue) { + foreach ($testValue as $mergedKey => $mergedValue) { if (($mergedKey == $key) && ($mergedValue < $value)) { $value = $mergedValue; } } } - return pow($key,$value); + return pow($key, $value); } - } // function GCD() + } /** @@ -420,7 +422,8 @@ public static function GCD() { * @param float $number Number to cast to an integer * @return integer Integer value */ - public static function INT($number) { + public static function INT($number) + { $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); if (is_null($number)) { @@ -432,7 +435,7 @@ public static function INT($number) { return (int) floor($number); } return PHPExcel_Calculation_Functions::VALUE(); - } // function INT() + } /** @@ -451,11 +454,12 @@ public static function INT($number) { * @param mixed $arg,... Data values * @return int Lowest Common Multiplier */ - public static function LCM() { + public static function LCM() + { $returnValue = 1; $allPoweredFactors = array(); // Loop through arguments - foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { if (!is_numeric($value)) { return PHPExcel_Calculation_Functions::VALUE(); } @@ -464,14 +468,14 @@ public static function LCM() { } elseif ($value < 0) { return PHPExcel_Calculation_Functions::NaN(); } - $myFactors = self::_factors(floor($value)); + $myFactors = self::factors(floor($value)); $myCountedFactors = array_count_values($myFactors); $myPoweredFactors = array(); - foreach($myCountedFactors as $myCountedFactor => $myCountedPower) { - $myPoweredFactors[$myCountedFactor] = pow($myCountedFactor,$myCountedPower); + foreach ($myCountedFactors as $myCountedFactor => $myCountedPower) { + $myPoweredFactors[$myCountedFactor] = pow($myCountedFactor, $myCountedPower); } - foreach($myPoweredFactors as $myPoweredValue => $myPoweredFactor) { - if (array_key_exists($myPoweredValue,$allPoweredFactors)) { + foreach ($myPoweredFactors as $myPoweredValue => $myPoweredFactor) { + if (array_key_exists($myPoweredValue, $allPoweredFactors)) { if ($allPoweredFactors[$myPoweredValue] < $myPoweredFactor) { $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; } @@ -480,11 +484,11 @@ public static function LCM() { } } } - foreach($allPoweredFactors as $allPoweredFactor) { + foreach ($allPoweredFactors as $allPoweredFactor) { $returnValue *= (integer) $allPoweredFactor; } return $returnValue; - } // function LCM() + } /** @@ -501,16 +505,19 @@ public static function LCM() { * @param float $base The base of the logarithm. If base is omitted, it is assumed to be 10. * @return float */ - public static function LOG_BASE($number = NULL, $base = 10) { + public static function LOG_BASE($number = null, $base = 10) + { $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); $base = (is_null($base)) ? 10 : (float) PHPExcel_Calculation_Functions::flattenSingleValue($base); - if ((!is_numeric($base)) || (!is_numeric($number))) + if ((!is_numeric($base)) || (!is_numeric($number))) { return PHPExcel_Calculation_Functions::VALUE(); - if (($base <= 0) || ($number <= 0)) + } + if (($base <= 0) || ($number <= 0)) { return PHPExcel_Calculation_Functions::NaN(); + } return log($number, $base); - } // function LOG_BASE() + } /** @@ -526,25 +533,34 @@ public static function LOG_BASE($number = NULL, $base = 10) { * @param array $matrixValues A matrix of values * @return float */ - public static function MDETERM($matrixValues) { + public static function MDETERM($matrixValues) + { $matrixData = array(); - if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); } + if (!is_array($matrixValues)) { + $matrixValues = array(array($matrixValues)); + } $row = $maxColumn = 0; - foreach($matrixValues as $matrixRow) { - if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + foreach ($matrixValues as $matrixRow) { + if (!is_array($matrixRow)) { + $matrixRow = array($matrixRow); + } $column = 0; - foreach($matrixRow as $matrixCell) { + foreach ($matrixRow as $matrixCell) { if ((is_string($matrixCell)) || ($matrixCell === null)) { return PHPExcel_Calculation_Functions::VALUE(); } $matrixData[$column][$row] = $matrixCell; ++$column; } - if ($column > $maxColumn) { $maxColumn = $column; } + if ($column > $maxColumn) { + $maxColumn = $column; + } ++$row; } - if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); } + if ($row != $maxColumn) { + return PHPExcel_Calculation_Functions::VALUE(); + } try { $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); @@ -552,7 +568,7 @@ public static function MDETERM($matrixValues) { } catch (PHPExcel_Exception $ex) { return PHPExcel_Calculation_Functions::VALUE(); } - } // function MDETERM() + } /** @@ -568,25 +584,34 @@ public static function MDETERM($matrixValues) { * @param array $matrixValues A matrix of values * @return array */ - public static function MINVERSE($matrixValues) { + public static function MINVERSE($matrixValues) + { $matrixData = array(); - if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); } + if (!is_array($matrixValues)) { + $matrixValues = array(array($matrixValues)); + } $row = $maxColumn = 0; - foreach($matrixValues as $matrixRow) { - if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + foreach ($matrixValues as $matrixRow) { + if (!is_array($matrixRow)) { + $matrixRow = array($matrixRow); + } $column = 0; - foreach($matrixRow as $matrixCell) { + foreach ($matrixRow as $matrixCell) { if ((is_string($matrixCell)) || ($matrixCell === null)) { return PHPExcel_Calculation_Functions::VALUE(); } $matrixData[$column][$row] = $matrixCell; ++$column; } - if ($column > $maxColumn) { $maxColumn = $column; } + if ($column > $maxColumn) { + $maxColumn = $column; + } ++$row; } - if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); } + if ($row != $maxColumn) { + return PHPExcel_Calculation_Functions::VALUE(); + } try { $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); @@ -594,7 +619,7 @@ public static function MINVERSE($matrixValues) { } catch (PHPExcel_Exception $ex) { return PHPExcel_Calculation_Functions::VALUE(); } - } // function MINVERSE() + } /** @@ -604,17 +629,24 @@ public static function MINVERSE($matrixValues) { * @param array $matrixData2 A matrix of values * @return array */ - public static function MMULT($matrixData1,$matrixData2) { + public static function MMULT($matrixData1, $matrixData2) + { $matrixAData = $matrixBData = array(); - if (!is_array($matrixData1)) { $matrixData1 = array(array($matrixData1)); } - if (!is_array($matrixData2)) { $matrixData2 = array(array($matrixData2)); } + if (!is_array($matrixData1)) { + $matrixData1 = array(array($matrixData1)); + } + if (!is_array($matrixData2)) { + $matrixData2 = array(array($matrixData2)); + } try { $rowA = 0; - foreach($matrixData1 as $matrixRow) { - if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + foreach ($matrixData1 as $matrixRow) { + if (!is_array($matrixRow)) { + $matrixRow = array($matrixRow); + } $columnA = 0; - foreach($matrixRow as $matrixCell) { + foreach ($matrixRow as $matrixCell) { if ((!is_numeric($matrixCell)) || ($matrixCell === null)) { return PHPExcel_Calculation_Functions::VALUE(); } @@ -625,10 +657,12 @@ public static function MMULT($matrixData1,$matrixData2) { } $matrixA = new PHPExcel_Shared_JAMA_Matrix($matrixAData); $rowB = 0; - foreach($matrixData2 as $matrixRow) { - if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + foreach ($matrixData2 as $matrixRow) { + if (!is_array($matrixRow)) { + $matrixRow = array($matrixRow); + } $columnB = 0; - foreach($matrixRow as $matrixCell) { + foreach ($matrixRow as $matrixCell) { if ((!is_numeric($matrixCell)) || ($matrixCell === null)) { return PHPExcel_Calculation_Functions::VALUE(); } @@ -648,7 +682,7 @@ public static function MMULT($matrixData1,$matrixData2) { var_dump($ex->getMessage()); return PHPExcel_Calculation_Functions::VALUE(); } - } // function MMULT() + } /** @@ -658,20 +692,21 @@ public static function MMULT($matrixData1,$matrixData2) { * @param int $b Divisor * @return int Remainder */ - public static function MOD($a = 1, $b = 1) { - $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); - $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + public static function MOD($a = 1, $b = 1) + { + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); if ($b == 0.0) { return PHPExcel_Calculation_Functions::DIV0(); } elseif (($a < 0.0) && ($b > 0.0)) { - return $b - fmod(abs($a),$b); + return $b - fmod(abs($a), $b); } elseif (($a > 0.0) && ($b < 0.0)) { - return $b + fmod($a,abs($b)); + return $b + fmod($a, abs($b)); } - return fmod($a,$b); - } // function MOD() + return fmod($a, $b); + } /** @@ -683,9 +718,10 @@ public static function MOD($a = 1, $b = 1) { * @param int $multiple Multiple to which you want to round $number * @return float Rounded Number */ - public static function MROUND($number,$multiple) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - $multiple = PHPExcel_Calculation_Functions::flattenSingleValue($multiple); + public static function MROUND($number, $multiple) + { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $multiple = PHPExcel_Calculation_Functions::flattenSingleValue($multiple); if ((is_numeric($number)) && (is_numeric($multiple))) { if ($multiple == 0) { @@ -698,7 +734,7 @@ public static function MROUND($number,$multiple) { return PHPExcel_Calculation_Functions::NaN(); } return PHPExcel_Calculation_Functions::VALUE(); - } // function MROUND() + } /** @@ -709,7 +745,8 @@ public static function MROUND($number,$multiple) { * @param array of mixed Data Series * @return float */ - public static function MULTINOMIAL() { + public static function MULTINOMIAL() + { $summer = 0; $divisor = 1; // Loop through arguments @@ -732,7 +769,7 @@ public static function MULTINOMIAL() { return $summer / $divisor; } return 0; - } // function MULTINOMIAL() + } /** @@ -743,22 +780,21 @@ public static function MULTINOMIAL() { * @param float $number Number to round * @return int Rounded Number */ - public static function ODD($number) { - $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + public static function ODD($number) + { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); if (is_null($number)) { return 1; } elseif (is_bool($number)) { - $number = (int) $number; - } - - if (is_numeric($number)) { + return 1; + } elseif (is_numeric($number)) { $significance = self::SIGN($number); if ($significance == 0) { return 1; } - $result = self::CEILING($number,$significance); + $result = self::CEILING($number, $significance); if ($result == self::EVEN($result)) { $result += $significance; } @@ -766,7 +802,7 @@ public static function ODD($number) { return (int) $result; } return PHPExcel_Calculation_Functions::VALUE(); - } // function ODD() + } /** @@ -778,7 +814,8 @@ public static function ODD($number) { * @param float $y * @return float */ - public static function POWER($x = 0, $y = 2) { + public static function POWER($x = 0, $y = 2) + { $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); $y = PHPExcel_Calculation_Functions::flattenSingleValue($y); @@ -792,7 +829,7 @@ public static function POWER($x = 0, $y = 2) { // Return $result = pow($x, $y); return (!is_nan($result) && !is_infinite($result)) ? $result : PHPExcel_Calculation_Functions::NaN(); - } // function POWER() + } /** @@ -808,7 +845,8 @@ public static function POWER($x = 0, $y = 2) { * @param mixed $arg,... Data values * @return float */ - public static function PRODUCT() { + public static function PRODUCT() + { // Return value $returnValue = null; @@ -829,7 +867,7 @@ public static function PRODUCT() { return 0; } return $returnValue; - } // function PRODUCT() + } /** @@ -846,7 +884,8 @@ public static function PRODUCT() { * @param mixed $arg,... Data values * @return float */ - public static function QUOTIENT() { + public static function QUOTIENT() + { // Return value $returnValue = null; @@ -868,7 +907,7 @@ public static function QUOTIENT() { // Return return intval($returnValue); - } // function QUOTIENT() + } /** @@ -878,19 +917,21 @@ public static function QUOTIENT() { * @param int $max Maximal value * @return int Random number */ - public static function RAND($min = 0, $max = 0) { - $min = PHPExcel_Calculation_Functions::flattenSingleValue($min); - $max = PHPExcel_Calculation_Functions::flattenSingleValue($max); + public static function RAND($min = 0, $max = 0) + { + $min = PHPExcel_Calculation_Functions::flattenSingleValue($min); + $max = PHPExcel_Calculation_Functions::flattenSingleValue($max); if ($min == 0 && $max == 0) { - return (mt_rand(0,10000000)) / 10000000; + return (mt_rand(0, 10000000)) / 10000000; } else { return mt_rand($min, $max); } - } // function RAND() + } - public static function ROMAN($aValue, $style=0) { + public static function ROMAN($aValue, $style = 0) + { $aValue = PHPExcel_Calculation_Functions::flattenSingleValue($aValue); $style = (is_null($style)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($style); if ((!is_numeric($aValue)) || ($aValue < 0) || ($aValue >= 4000)) { @@ -901,22 +942,25 @@ public static function ROMAN($aValue, $style=0) { return ''; } - $mill = Array('', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM'); - $cent = Array('', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'); - $tens = Array('', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'); - $ones = Array('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'); + $mill = array('', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM'); + $cent = array('', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'); + $tens = array('', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'); + $ones = array('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'); $roman = ''; while ($aValue > 5999) { $roman .= 'M'; $aValue -= 1000; } - $m = self::_romanCut($aValue, 1000); $aValue %= 1000; - $c = self::_romanCut($aValue, 100); $aValue %= 100; - $t = self::_romanCut($aValue, 10); $aValue %= 10; + $m = self::romanCut($aValue, 1000); + $aValue %= 1000; + $c = self::romanCut($aValue, 100); + $aValue %= 100; + $t = self::romanCut($aValue, 10); + $aValue %= 10; return $roman.$mill[$m].$cent[$c].$tens[$t].$ones[$aValue]; - } // function ROMAN() + } /** @@ -928,12 +972,13 @@ public static function ROMAN($aValue, $style=0) { * @param int $digits Number of digits to which you want to round $number * @return float Rounded Number */ - public static function ROUNDUP($number,$digits) { + public static function ROUNDUP($number, $digits) + { $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); if ((is_numeric($number)) && (is_numeric($digits))) { - $significance = pow(10,(int) $digits); + $significance = pow(10, (int) $digits); if ($number < 0.0) { return floor($number * $significance) / $significance; } else { @@ -941,7 +986,7 @@ public static function ROUNDUP($number,$digits) { } } return PHPExcel_Calculation_Functions::VALUE(); - } // function ROUNDUP() + } /** @@ -953,12 +998,13 @@ public static function ROUNDUP($number,$digits) { * @param int $digits Number of digits to which you want to round $number * @return float Rounded Number */ - public static function ROUNDDOWN($number,$digits) { + public static function ROUNDDOWN($number, $digits) + { $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); if ((is_numeric($number)) && (is_numeric($digits))) { - $significance = pow(10,(int) $digits); + $significance = pow(10, (int) $digits); if ($number < 0.0) { return ceil($number * $significance) / $significance; } else { @@ -966,7 +1012,7 @@ public static function ROUNDDOWN($number,$digits) { } } return PHPExcel_Calculation_Functions::VALUE(); - } // function ROUNDDOWN() + } /** @@ -980,8 +1026,8 @@ public static function ROUNDDOWN($number,$digits) { * @param array of mixed Data Series * @return float */ - public static function SERIESSUM() { - // Return value + public static function SERIESSUM() + { $returnValue = 0; // Loop through arguments @@ -994,19 +1040,18 @@ public static function SERIESSUM() { if ((is_numeric($x)) && (is_numeric($n)) && (is_numeric($m))) { // Calculate $i = 0; - foreach($aArgs as $arg) { + foreach ($aArgs as $arg) { // Is it a numeric value? if ((is_numeric($arg)) && (!is_string($arg))) { - $returnValue += $arg * pow($x,$n + ($m * $i++)); + $returnValue += $arg * pow($x, $n + ($m * $i++)); } else { return PHPExcel_Calculation_Functions::VALUE(); } } - // Return return $returnValue; } return PHPExcel_Calculation_Functions::VALUE(); - } // function SERIESSUM() + } /** @@ -1018,11 +1063,13 @@ public static function SERIESSUM() { * @param float $number Number to round * @return int sign value */ - public static function SIGN($number) { + public static function SIGN($number) + { $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); - if (is_bool($number)) + if (is_bool($number)) { return (int) $number; + } if (is_numeric($number)) { if ($number == 0.0) { return 0; @@ -1030,7 +1077,7 @@ public static function SIGN($number) { return $number / abs($number); } return PHPExcel_Calculation_Functions::VALUE(); - } // function SIGN() + } /** @@ -1041,7 +1088,8 @@ public static function SIGN($number) { * @param float $number Number * @return float Square Root of Number * Pi */ - public static function SQRTPI($number) { + public static function SQRTPI($number) + { $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); if (is_numeric($number)) { @@ -1051,7 +1099,7 @@ public static function SQRTPI($number) { return sqrt($number * M_PI) ; } return PHPExcel_Calculation_Functions::VALUE(); - } // function SQRTPI() + } /** @@ -1064,7 +1112,8 @@ public static function SQRTPI($number) { * @param array of mixed Data Series * @return float */ - public static function SUBTOTAL() { + public static function SUBTOTAL() + { $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); // Calculate @@ -1072,43 +1121,32 @@ public static function SUBTOTAL() { if ((is_numeric($subtotal)) && (!is_string($subtotal))) { switch($subtotal) { - case 1 : + case 1: return PHPExcel_Calculation_Statistical::AVERAGE($aArgs); - break; - case 2 : + case 2: return PHPExcel_Calculation_Statistical::COUNT($aArgs); - break; - case 3 : + case 3: return PHPExcel_Calculation_Statistical::COUNTA($aArgs); - break; - case 4 : + case 4: return PHPExcel_Calculation_Statistical::MAX($aArgs); - break; - case 5 : + case 5: return PHPExcel_Calculation_Statistical::MIN($aArgs); - break; - case 6 : + case 6: return self::PRODUCT($aArgs); - break; - case 7 : + case 7: return PHPExcel_Calculation_Statistical::STDEV($aArgs); - break; - case 8 : + case 8: return PHPExcel_Calculation_Statistical::STDEVP($aArgs); - break; - case 9 : + case 9: return self::SUM($aArgs); - break; - case 10 : + case 10: return PHPExcel_Calculation_Statistical::VARFunc($aArgs); - break; - case 11 : + case 11: return PHPExcel_Calculation_Statistical::VARP($aArgs); - break; } } return PHPExcel_Calculation_Functions::VALUE(); - } // function SUBTOTAL() + } /** @@ -1124,8 +1162,8 @@ public static function SUBTOTAL() { * @param mixed $arg,... Data values * @return float */ - public static function SUM() { - // Return value + public static function SUM() + { $returnValue = 0; // Loop through the arguments @@ -1136,9 +1174,8 @@ public static function SUM() { } } - // Return return $returnValue; - } // function SUM() + } /** @@ -1155,8 +1192,8 @@ public static function SUM() { * @param string $condition The criteria that defines which cells will be summed. * @return float */ - public static function SUMIF($aArgs,$condition,$sumArgs = array()) { - // Return value + public static function SUMIF($aArgs, $condition, $sumArgs = array()) + { $returnValue = 0; $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); @@ -1179,9 +1216,8 @@ public static function SUMIF($aArgs,$condition,$sumArgs = array()) { } } - // Return return $returnValue; - } // function SUMIF() + } /** @@ -1195,7 +1231,8 @@ public static function SUMIF($aArgs,$condition,$sumArgs = array()) { * @param mixed $arg,... Data values * @return float */ - public static function SUMPRODUCT() { + public static function SUMPRODUCT() + { $arrayList = func_get_args(); $wrkArray = PHPExcel_Calculation_Functions::flattenArray(array_shift($arrayList)); @@ -1207,7 +1244,7 @@ public static function SUMPRODUCT() { } } - foreach($arrayList as $matrixData) { + foreach ($arrayList as $matrixData) { $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData); $count = count($array2); if ($wrkCellCount != $count) { @@ -1223,7 +1260,7 @@ public static function SUMPRODUCT() { } return array_sum($wrkArray); - } // function SUMPRODUCT() + } /** @@ -1239,8 +1276,8 @@ public static function SUMPRODUCT() { * @param mixed $arg,... Data values * @return float */ - public static function SUMSQ() { - // Return value + public static function SUMSQ() + { $returnValue = 0; // Loop through arguments @@ -1251,9 +1288,8 @@ public static function SUMSQ() { } } - // Return return $returnValue; - } // function SUMSQ() + } /** @@ -1263,16 +1299,11 @@ public static function SUMSQ() { * @param mixed[] $matrixData2 Matrix #2 * @return float */ - public static function SUMX2MY2($matrixData1,$matrixData2) { + public static function SUMX2MY2($matrixData1, $matrixData2) + { $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); - $count1 = count($array1); - $count2 = count($array2); - if ($count1 < $count2) { - $count = $count1; - } else { - $count = $count2; - } + $count = min(count($array1), count($array2)); $result = 0; for ($i = 0; $i < $count; ++$i) { @@ -1283,7 +1314,7 @@ public static function SUMX2MY2($matrixData1,$matrixData2) { } return $result; - } // function SUMX2MY2() + } /** @@ -1293,16 +1324,11 @@ public static function SUMX2MY2($matrixData1,$matrixData2) { * @param mixed[] $matrixData2 Matrix #2 * @return float */ - public static function SUMX2PY2($matrixData1,$matrixData2) { + public static function SUMX2PY2($matrixData1, $matrixData2) + { $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); - $count1 = count($array1); - $count2 = count($array2); - if ($count1 < $count2) { - $count = $count1; - } else { - $count = $count2; - } + $count = min(count($array1), count($array2)); $result = 0; for ($i = 0; $i < $count; ++$i) { @@ -1313,7 +1339,7 @@ public static function SUMX2PY2($matrixData1,$matrixData2) { } return $result; - } // function SUMX2PY2() + } /** @@ -1323,16 +1349,11 @@ public static function SUMX2PY2($matrixData1,$matrixData2) { * @param mixed[] $matrixData2 Matrix #2 * @return float */ - public static function SUMXMY2($matrixData1,$matrixData2) { + public static function SUMXMY2($matrixData1, $matrixData2) + { $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); - $count1 = count($array1); - $count2 = count($array2); - if ($count1 < $count2) { - $count = $count1; - } else { - $count = $count2; - } + $count = min(count($array1), count($array2)); $result = 0; for ($i = 0; $i < $count; ++$i) { @@ -1343,7 +1364,7 @@ public static function SUMXMY2($matrixData1,$matrixData2) { } return $result; - } // function SUMXMY2() + } /** @@ -1355,22 +1376,24 @@ public static function SUMXMY2($matrixData1,$matrixData2) { * @param int $digits * @return float Truncated value */ - public static function TRUNC($value = 0, $digits = 0) { + public static function TRUNC($value = 0, $digits = 0) + { $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); // Validate parameters - if ((!is_numeric($value)) || (!is_numeric($digits))) + if ((!is_numeric($value)) || (!is_numeric($digits))) { return PHPExcel_Calculation_Functions::VALUE(); - $digits = floor($digits); + } + $digits = floor($digits); // Truncate $adjust = pow(10, $digits); - if (($digits > 0) && (rtrim(intval((abs($value) - abs(intval($value))) * $adjust),'0') < $adjust/10)) + if (($digits > 0) && (rtrim(intval((abs($value) - abs(intval($value))) * $adjust), '0') < $adjust/10)) { return $value; + } return (intval($value * $adjust)) / $adjust; - } // function TRUNC() - -} // class PHPExcel_Calculation_MathTrig + } +} diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php index 64e568b0c..ad523f67d 100644 --- a/Classes/PHPExcel/Calculation/Statistical.php +++ b/Classes/PHPExcel/Calculation/Statistical.php @@ -1,30 +1,4 @@ $value) { + foreach ($array1 as $key => $value) { if ((is_bool($value)) || (is_string($value)) || (is_null($value))) { unset($array1[$key]); unset($array2[$key]); } } - foreach($array2 as $key => $value) { + foreach ($array2 as $key => $value) { if ((is_bool($value)) || (is_string($value)) || (is_null($value))) { unset($array1[$key]); unset($array2[$key]); @@ -83,8 +78,8 @@ private static function _checkTrendArrays(&$array1,&$array2) { $array1 = array_merge($array1); $array2 = array_merge($array2); - return True; - } // function _checkTrendArrays() + return true; + } /** @@ -96,13 +91,14 @@ private static function _checkTrendArrays(&$array1,&$array2) { * @param q require q>0 * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow */ - private static function _beta($p, $q) { + private static function _beta($p, $q) + { if ($p <= 0.0 || $q <= 0.0 || ($p + $q) > LOG_GAMMA_X_MAX_VALUE) { return 0.0; } else { return exp(self::_logBeta($p, $q)); } - } // function _beta() + } /** @@ -117,7 +113,8 @@ private static function _beta($p, $q) { * @param q require q>0 * @return 0 if x<0, p<=0, q<=0 or p+q>2.55E305 and 1 if x>1 to avoid errors and over/underflow */ - private static function _incompleteBeta($x, $p, $q) { + private static function _incompleteBeta($x, $p, $q) + { if ($x <= 0.0) { return 0.0; } elseif ($x >= 1.0) { @@ -131,13 +128,13 @@ private static function _incompleteBeta($x, $p, $q) { } else { return 1.0 - ($beta_gam * self::_betaFraction(1 - $x, $q, $p) / $q); } - } // function _incompleteBeta() + } // Function cache for _logBeta function - private static $_logBetaCache_p = 0.0; - private static $_logBetaCache_q = 0.0; - private static $_logBetaCache_result = 0.0; + private static $logBetaCacheP = 0.0; + private static $logBetaCacheQ = 0.0; + private static $logBetaCacheResult = 0.0; /** * The natural logarithm of the beta function. @@ -147,18 +144,19 @@ private static function _incompleteBeta($x, $p, $q) { * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow * @author Jaco van Kooten */ - private static function _logBeta($p, $q) { - if ($p != self::$_logBetaCache_p || $q != self::$_logBetaCache_q) { - self::$_logBetaCache_p = $p; - self::$_logBetaCache_q = $q; + private static function _logBeta($p, $q) + { + if ($p != self::$logBetaCacheP || $q != self::$logBetaCacheQ) { + self::$logBetaCacheP = $p; + self::$logBetaCacheQ = $q; if (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { - self::$_logBetaCache_result = 0.0; + self::$logBetaCacheResult = 0.0; } else { - self::$_logBetaCache_result = self::_logGamma($p) + self::_logGamma($q) - self::_logGamma($p + $q); + self::$logBetaCacheResult = self::_logGamma($p) + self::_logGamma($q) - self::_logGamma($p + $q); } } - return self::$_logBetaCache_result; - } // function _logBeta() + return self::$logBetaCacheResult; + } /** @@ -166,7 +164,8 @@ private static function _logBeta($p, $q) { * Based on an idea from Numerical Recipes (W.H. Press et al, 1992). * @author Jaco van Kooten */ - private static function _betaFraction($x, $p, $q) { + private static function _betaFraction($x, $p, $q) + { $c = 1.0; $sum_pq = $p + $q; $p_plus = $p + 1.0; @@ -179,7 +178,7 @@ private static function _betaFraction($x, $p, $q) { $frac = $h; $m = 1; $delta = 0.0; - while ($m <= MAX_ITERATIONS && abs($delta-1.0) > PRECISION ) { + while ($m <= MAX_ITERATIONS && abs($delta-1.0) > PRECISION) { $m2 = 2 * $m; // even index for d $d = $m * ($q - $m) * $x / ( ($p_minus + $m2) * ($p + $m2)); @@ -209,7 +208,7 @@ private static function _betaFraction($x, $p, $q) { ++$m; } return $frac; - } // function _betaFraction() + } /** @@ -256,153 +255,167 @@ private static function _betaFraction($x, $p, $q) { */ // Function cache for logGamma - private static $_logGammaCache_result = 0.0; - private static $_logGammaCache_x = 0.0; + private static $logGammaCacheResult = 0.0; + private static $logGammaCacheX = 0.0; - private static function _logGamma($x) { + private static function _logGamma($x) + { // Log Gamma related constants static $lg_d1 = -0.5772156649015328605195174; static $lg_d2 = 0.4227843350984671393993777; static $lg_d4 = 1.791759469228055000094023; - static $lg_p1 = array( 4.945235359296727046734888, - 201.8112620856775083915565, - 2290.838373831346393026739, - 11319.67205903380828685045, - 28557.24635671635335736389, - 38484.96228443793359990269, - 26377.48787624195437963534, - 7225.813979700288197698961 ); - static $lg_p2 = array( 4.974607845568932035012064, - 542.4138599891070494101986, - 15506.93864978364947665077, - 184793.2904445632425417223, - 1088204.76946882876749847, - 3338152.967987029735917223, - 5106661.678927352456275255, - 3074109.054850539556250927 ); - static $lg_p4 = array( 14745.02166059939948905062, - 2426813.369486704502836312, - 121475557.4045093227939592, - 2663432449.630976949898078, - 29403789566.34553899906876, - 170266573776.5398868392998, - 492612579337.743088758812, - 560625185622.3951465078242 ); - - static $lg_q1 = array( 67.48212550303777196073036, - 1113.332393857199323513008, - 7738.757056935398733233834, - 27639.87074403340708898585, - 54993.10206226157329794414, - 61611.22180066002127833352, - 36351.27591501940507276287, - 8785.536302431013170870835 ); - static $lg_q2 = array( 183.0328399370592604055942, - 7765.049321445005871323047, - 133190.3827966074194402448, - 1136705.821321969608938755, - 5267964.117437946917577538, - 13467014.54311101692290052, - 17827365.30353274213975932, - 9533095.591844353613395747 ); - static $lg_q4 = array( 2690.530175870899333379843, - 639388.5654300092398984238, - 41355999.30241388052042842, - 1120872109.61614794137657, - 14886137286.78813811542398, - 101680358627.2438228077304, - 341747634550.7377132798597, - 446315818741.9713286462081 ); - - static $lg_c = array( -0.001910444077728, - 8.4171387781295e-4, - -5.952379913043012e-4, - 7.93650793500350248e-4, - -0.002777777777777681622553, - 0.08333333333333333331554247, - 0.0057083835261 ); - - // Rough estimate of the fourth root of logGamma_xBig - static $lg_frtbig = 2.25e76; - static $pnt68 = 0.6796875; - - - if ($x == self::$_logGammaCache_x) { - return self::$_logGammaCache_result; - } - $y = $x; - if ($y > 0.0 && $y <= LOG_GAMMA_X_MAX_VALUE) { - if ($y <= EPS) { - $res = -log(y); - } elseif ($y <= 1.5) { - // --------------------- - // EPS .LT. X .LE. 1.5 - // --------------------- - if ($y < $pnt68) { - $corr = -log($y); - $xm1 = $y; - } else { - $corr = 0.0; - $xm1 = $y - 1.0; - } - if ($y <= 0.5 || $y >= $pnt68) { - $xden = 1.0; - $xnum = 0.0; - for ($i = 0; $i < 8; ++$i) { - $xnum = $xnum * $xm1 + $lg_p1[$i]; - $xden = $xden * $xm1 + $lg_q1[$i]; + static $lg_p1 = array( + 4.945235359296727046734888, + 201.8112620856775083915565, + 2290.838373831346393026739, + 11319.67205903380828685045, + 28557.24635671635335736389, + 38484.96228443793359990269, + 26377.48787624195437963534, + 7225.813979700288197698961 + ); + static $lg_p2 = array( + 4.974607845568932035012064, + 542.4138599891070494101986, + 15506.93864978364947665077, + 184793.2904445632425417223, + 1088204.76946882876749847, + 3338152.967987029735917223, + 5106661.678927352456275255, + 3074109.054850539556250927 + ); + static $lg_p4 = array( + 14745.02166059939948905062, + 2426813.369486704502836312, + 121475557.4045093227939592, + 2663432449.630976949898078, + 29403789566.34553899906876, + 170266573776.5398868392998, + 492612579337.743088758812, + 560625185622.3951465078242 + ); + static $lg_q1 = array( + 67.48212550303777196073036, + 1113.332393857199323513008, + 7738.757056935398733233834, + 27639.87074403340708898585, + 54993.10206226157329794414, + 61611.22180066002127833352, + 36351.27591501940507276287, + 8785.536302431013170870835 + ); + static $lg_q2 = array( + 183.0328399370592604055942, + 7765.049321445005871323047, + 133190.3827966074194402448, + 1136705.821321969608938755, + 5267964.117437946917577538, + 13467014.54311101692290052, + 17827365.30353274213975932, + 9533095.591844353613395747 + ); + static $lg_q4 = array( + 2690.530175870899333379843, + 639388.5654300092398984238, + 41355999.30241388052042842, + 1120872109.61614794137657, + 14886137286.78813811542398, + 101680358627.2438228077304, + 341747634550.7377132798597, + 446315818741.9713286462081 + ); + static $lg_c = array( + -0.001910444077728, + 8.4171387781295e-4, + -5.952379913043012e-4, + 7.93650793500350248e-4, + -0.002777777777777681622553, + 0.08333333333333333331554247, + 0.0057083835261 + ); + + // Rough estimate of the fourth root of logGamma_xBig + static $lg_frtbig = 2.25e76; + static $pnt68 = 0.6796875; + + + if ($x == self::$logGammaCacheX) { + return self::$logGammaCacheResult; + } + $y = $x; + if ($y > 0.0 && $y <= LOG_GAMMA_X_MAX_VALUE) { + if ($y <= EPS) { + $res = -log(y); + } elseif ($y <= 1.5) { + // --------------------- + // EPS .LT. X .LE. 1.5 + // --------------------- + if ($y < $pnt68) { + $corr = -log($y); + $xm1 = $y; + } else { + $corr = 0.0; + $xm1 = $y - 1.0; } - $res = $corr + $xm1 * ($lg_d1 + $xm1 * ($xnum / $xden)); - } else { - $xm2 = $y - 1.0; + if ($y <= 0.5 || $y >= $pnt68) { + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm1 + $lg_p1[$i]; + $xden = $xden * $xm1 + $lg_q1[$i]; + } + $res = $corr + $xm1 * ($lg_d1 + $xm1 * ($xnum / $xden)); + } else { + $xm2 = $y - 1.0; + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm2 + $lg_p2[$i]; + $xden = $xden * $xm2 + $lg_q2[$i]; + } + $res = $corr + $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); + } + } elseif ($y <= 4.0) { + // --------------------- + // 1.5 .LT. X .LE. 4.0 + // --------------------- + $xm2 = $y - 2.0; $xden = 1.0; $xnum = 0.0; for ($i = 0; $i < 8; ++$i) { $xnum = $xnum * $xm2 + $lg_p2[$i]; $xden = $xden * $xm2 + $lg_q2[$i]; } - $res = $corr + $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); - } - } elseif ($y <= 4.0) { - // --------------------- - // 1.5 .LT. X .LE. 4.0 - // --------------------- - $xm2 = $y - 2.0; - $xden = 1.0; - $xnum = 0.0; - for ($i = 0; $i < 8; ++$i) { - $xnum = $xnum * $xm2 + $lg_p2[$i]; - $xden = $xden * $xm2 + $lg_q2[$i]; - } - $res = $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); - } elseif ($y <= 12.0) { - // ---------------------- - // 4.0 .LT. X .LE. 12.0 - // ---------------------- - $xm4 = $y - 4.0; - $xden = -1.0; - $xnum = 0.0; - for ($i = 0; $i < 8; ++$i) { - $xnum = $xnum * $xm4 + $lg_p4[$i]; - $xden = $xden * $xm4 + $lg_q4[$i]; - } - $res = $lg_d4 + $xm4 * ($xnum / $xden); - } else { - // --------------------------------- - // Evaluate for argument .GE. 12.0 - // --------------------------------- - $res = 0.0; - if ($y <= $lg_frtbig) { - $res = $lg_c[6]; - $ysq = $y * $y; - for ($i = 0; $i < 6; ++$i) - $res = $res / $ysq + $lg_c[$i]; + $res = $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); + } elseif ($y <= 12.0) { + // ---------------------- + // 4.0 .LT. X .LE. 12.0 + // ---------------------- + $xm4 = $y - 4.0; + $xden = -1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm4 + $lg_p4[$i]; + $xden = $xden * $xm4 + $lg_q4[$i]; + } + $res = $lg_d4 + $xm4 * ($xnum / $xden); + } else { + // --------------------------------- + // Evaluate for argument .GE. 12.0 + // --------------------------------- + $res = 0.0; + if ($y <= $lg_frtbig) { + $res = $lg_c[6]; + $ysq = $y * $y; + for ($i = 0; $i < 6; ++$i) { + $res = $res / $ysq + $lg_c[$i]; + } + $res /= $y; + $corr = log($y); + $res = $res + log(SQRT2PI) - 0.5 * $corr; + $res += $y * ($corr - 1.0); } - $res /= $y; - $corr = log($y); - $res = $res + log(SQRT2PI) - 0.5 * $corr; - $res += $y * ($corr - 1.0); } } else { // -------------------------- @@ -413,16 +426,17 @@ private static function _logGamma($x) { // ------------------------------ // Final adjustments and return // ------------------------------ - self::$_logGammaCache_x = $x; - self::$_logGammaCache_result = $res; + self::$logGammaCacheX = $x; + self::$logGammaCacheResult = $res; return $res; - } // function _logGamma() + } // // Private implementation of the incomplete Gamma function // - private static function _incompleteGamma($a,$x) { + private static function _incompleteGamma($a, $x) + { static $max = 32; $summer = 0; for ($n=0; $n<=$max; ++$n) { @@ -430,37 +444,41 @@ private static function _incompleteGamma($a,$x) { for ($i=1; $i<=$n; ++$i) { $divisor *= ($a + $i); } - $summer += (pow($x,$n) / $divisor); + $summer += (pow($x, $n) / $divisor); } - return pow($x,$a) * exp(0-$x) * $summer; - } // function _incompleteGamma() + return pow($x, $a) * exp(0-$x) * $summer; + } // // Private implementation of the Gamma function // - private static function _gamma($data) { - if ($data == 0.0) return 0; + private static function _gamma($data) + { + if ($data == 0.0) { + return 0; + } static $p0 = 1.000000000190015; - static $p = array ( 1 => 76.18009172947146, - 2 => -86.50532032941677, - 3 => 24.01409824083091, - 4 => -1.231739572450155, - 5 => 1.208650973866179e-3, - 6 => -5.395239384953e-6 - ); + static $p = array( + 1 => 76.18009172947146, + 2 => -86.50532032941677, + 3 => 24.01409824083091, + 4 => -1.231739572450155, + 5 => 1.208650973866179e-3, + 6 => -5.395239384953e-6 + ); $y = $x = $data; $tmp = $x + 5.5; $tmp -= ($x + 0.5) * log($tmp); $summer = $p0; - for ($j=1;$j<=6;++$j) { + for ($j=1; $j<=6; ++$j) { $summer += ($p[$j] / ++$y); } return exp(0 - $tmp + log(SQRT2PI * $summer / $x)); - } // function _gamma() + } /*************************************************************************** @@ -471,7 +489,8 @@ private static function _gamma($data) { * email : nickersonm@yahoo.com * ***************************************************************************/ - private static function _inverse_ncdf($p) { + private static function inverseNcdf($p) + { // Inverse ncdf approximation by Peter J. Acklam, implementation adapted to // PHP by Michael Nickerson, using Dr. Thomas Ziegler's C implementation as // a guide. http://home.online.no/~pjacklam/notes/invnorm/index.html @@ -485,34 +504,38 @@ private static function _inverse_ncdf($p) { // Input paramater is $p - probability - where 0 < p < 1. // Coefficients in rational approximations - static $a = array( 1 => -3.969683028665376e+01, - 2 => 2.209460984245205e+02, - 3 => -2.759285104469687e+02, - 4 => 1.383577518672690e+02, - 5 => -3.066479806614716e+01, - 6 => 2.506628277459239e+00 - ); - - static $b = array( 1 => -5.447609879822406e+01, - 2 => 1.615858368580409e+02, - 3 => -1.556989798598866e+02, - 4 => 6.680131188771972e+01, - 5 => -1.328068155288572e+01 - ); - - static $c = array( 1 => -7.784894002430293e-03, - 2 => -3.223964580411365e-01, - 3 => -2.400758277161838e+00, - 4 => -2.549732539343734e+00, - 5 => 4.374664141464968e+00, - 6 => 2.938163982698783e+00 - ); - - static $d = array( 1 => 7.784695709041462e-03, - 2 => 3.224671290700398e-01, - 3 => 2.445134137142996e+00, - 4 => 3.754408661907416e+00 - ); + static $a = array( + 1 => -3.969683028665376e+01, + 2 => 2.209460984245205e+02, + 3 => -2.759285104469687e+02, + 4 => 1.383577518672690e+02, + 5 => -3.066479806614716e+01, + 6 => 2.506628277459239e+00 + ); + + static $b = array( + 1 => -5.447609879822406e+01, + 2 => 1.615858368580409e+02, + 3 => -1.556989798598866e+02, + 4 => 6.680131188771972e+01, + 5 => -1.328068155288572e+01 + ); + + static $c = array( + 1 => -7.784894002430293e-03, + 2 => -3.223964580411365e-01, + 3 => -2.400758277161838e+00, + 4 => -2.549732539343734e+00, + 5 => 4.374664141464968e+00, + 6 => 2.938163982698783e+00 + ); + + static $d = array( + 1 => 7.784695709041462e-03, + 2 => 3.224671290700398e-01, + 3 => 2.445134137142996e+00, + 4 => 3.754408661907416e+00 + ); // Define lower and upper region break-points. $p_low = 0.02425; //Use lower region approx. below this @@ -537,10 +560,11 @@ private static function _inverse_ncdf($p) { } // If 0 < p < 1, return a null value return PHPExcel_Calculation_Functions::NULL(); - } // function _inverse_ncdf() + } - private static function _inverse_ncdf2($prob) { + private static function inverseNcdf2($prob) + { // Approximation of inverse standard normal CDF developed by // B. Moro, "The Full Monte," Risk 8(2), Feb 1995, 57-58. @@ -580,10 +604,11 @@ private static function _inverse_ncdf2($prob) { } } return $z; - } // function _inverse_ncdf2() + } // function inverseNcdf2() - private static function _inverse_ncdf3($p) { + private static function inverseNcdf3($p) + { // ALGORITHM AS241 APPL. STATIST. (1988) VOL. 37, NO. 3. // Produces the normal deviate Z corresponding to a given lower // tail area of P; Z is accurate to about 1 part in 10**16. @@ -662,10 +687,10 @@ private static function _inverse_ncdf3($p) { } else { $R = 1 - $p; } - $R = pow(-log($R),2); + $R = pow(-log($R), 2); // computation for p not close to 0, 0.5 or 1. - If ($R <= $split2) { + if ($R <= $split2) { $R = $R - $const2; $z = ((((((($c7 * $R + $c6) * $R + $c5) * $R + $c4) * $R + $c3) * $R + $c2) * $R + $c1) * $R + $c0) / ((((((($d7 * $R + $d6) * $R + $d5) * $R + $d4) * $R + $d3) * $R + $d2) * $R + $d1) * $R + 1); @@ -680,7 +705,7 @@ private static function _inverse_ncdf3($p) { } } return $z; - } // function _inverse_ncdf3() + } /** @@ -697,7 +722,8 @@ private static function _inverse_ncdf3($p) { * @param mixed $arg,... Data values * @return float */ - public static function AVEDEV() { + public static function AVEDEV() + { $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); // Return value @@ -729,7 +755,7 @@ public static function AVEDEV() { return $returnValue / $aCount; } return PHPExcel_Calculation_Functions::NaN(); - } // function AVEDEV() + } /** @@ -745,7 +771,8 @@ public static function AVEDEV() { * @param mixed $arg,... Data values * @return float */ - public static function AVERAGE() { + public static function AVERAGE() + { $returnValue = $aCount = 0; // Loop through arguments @@ -771,7 +798,7 @@ public static function AVERAGE() { } else { return PHPExcel_Calculation_Functions::DIV0(); } - } // function AVERAGE() + } /** @@ -787,8 +814,8 @@ public static function AVERAGE() { * @param mixed $arg,... Data values * @return float */ - public static function AVERAGEA() { - // Return value + public static function AVERAGEA() + { $returnValue = null; $aCount = 0; @@ -813,13 +840,12 @@ public static function AVERAGEA() { } } - // Return if ($aCount > 0) { return $returnValue / $aCount; } else { return PHPExcel_Calculation_Functions::DIV0(); } - } // function AVERAGEA() + } /** @@ -837,8 +863,8 @@ public static function AVERAGEA() { * @param mixed[] $averageArgs Data values * @return float */ - public static function AVERAGEIF($aArgs,$condition,$averageArgs = array()) { - // Return value + public static function AVERAGEIF($aArgs, $condition, $averageArgs = array()) + { $returnValue = 0; $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); @@ -850,7 +876,9 @@ public static function AVERAGEIF($aArgs,$condition,$averageArgs = array()) { // Loop through arguments $aCount = 0; foreach ($aArgs as $key => $arg) { - if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + if (!is_numeric($arg)) { + $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + } $testCondition = '='.$arg.$condition; if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { if ((is_null($returnValue)) || ($arg > $returnValue)) { @@ -860,13 +888,11 @@ public static function AVERAGEIF($aArgs,$condition,$averageArgs = array()) { } } - // Return if ($aCount > 0) { return $returnValue / $aCount; - } else { - return PHPExcel_Calculation_Functions::DIV0(); } - } // function AVERAGEIF() + return PHPExcel_Calculation_Functions::DIV0(); + } /** @@ -881,12 +907,13 @@ public static function AVERAGEIF($aArgs,$condition,$averageArgs = array()) { * @return float * */ - public static function BETADIST($value,$alpha,$beta,$rMin=0,$rMax=1) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); - $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); - $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); + public static function BETADIST($value, $alpha, $beta, $rMin = 0, $rMax = 1) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); + $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) { if (($value < $rMin) || ($value > $rMax) || ($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax)) { @@ -899,10 +926,10 @@ public static function BETADIST($value,$alpha,$beta,$rMin=0,$rMax=1) { } $value -= $rMin; $value /= ($rMax - $rMin); - return self::_incompleteBeta($value,$alpha,$beta); + return self::_incompleteBeta($value, $alpha, $beta); } return PHPExcel_Calculation_Functions::VALUE(); - } // function BETADIST() + } /** @@ -919,12 +946,13 @@ public static function BETADIST($value,$alpha,$beta,$rMin=0,$rMax=1) { * @return float * */ - public static function BETAINV($probability,$alpha,$beta,$rMin=0,$rMax=1) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); - $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); - $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); + public static function BETAINV($probability, $alpha, $beta, $rMin = 0, $rMax = 1) + { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); + $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) { if (($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax) || ($probability <= 0) || ($probability > 1)) { @@ -953,10 +981,10 @@ public static function BETAINV($probability,$alpha,$beta,$rMin=0,$rMax=1) { if ($i == MAX_ITERATIONS) { return PHPExcel_Calculation_Functions::NA(); } - return round($rMin + $guess * ($rMax - $rMin),12); + return round($rMin + $guess * ($rMax - $rMin), 12); } return PHPExcel_Calculation_Functions::VALUE(); - } // function BETAINV() + } /** @@ -977,10 +1005,11 @@ public static function BETAINV($probability,$alpha,$beta,$rMin=0,$rMax=1) { * @todo Cumulative distribution function * */ - public static function BINOMDIST($value, $trials, $probability, $cumulative) { - $value = floor(PHPExcel_Calculation_Functions::flattenSingleValue($value)); - $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + public static function BINOMDIST($value, $trials, $probability, $cumulative) + { + $value = floor(PHPExcel_Calculation_Functions::flattenSingleValue($value)); + $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); if ((is_numeric($value)) && (is_numeric($trials)) && (is_numeric($probability))) { if (($value < 0) || ($value > $trials)) { @@ -993,16 +1022,16 @@ public static function BINOMDIST($value, $trials, $probability, $cumulative) { if ($cumulative) { $summer = 0; for ($i = 0; $i <= $value; ++$i) { - $summer += PHPExcel_Calculation_MathTrig::COMBIN($trials,$i) * pow($probability,$i) * pow(1 - $probability,$trials - $i); + $summer += PHPExcel_Calculation_MathTrig::COMBIN($trials, $i) * pow($probability, $i) * pow(1 - $probability, $trials - $i); } return $summer; } else { - return PHPExcel_Calculation_MathTrig::COMBIN($trials,$value) * pow($probability,$value) * pow(1 - $probability,$trials - $value) ; + return PHPExcel_Calculation_MathTrig::COMBIN($trials, $value) * pow($probability, $value) * pow(1 - $probability, $trials - $value) ; } } } return PHPExcel_Calculation_Functions::VALUE(); - } // function BINOMDIST() + } /** @@ -1014,9 +1043,10 @@ public static function BINOMDIST($value, $trials, $probability, $cumulative) { * @param float $degrees degrees of freedom * @return float */ - public static function CHIDIST($value, $degrees) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + public static function CHIDIST($value, $degrees) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); if ((is_numeric($value)) && (is_numeric($degrees))) { if ($degrees < 1) { @@ -1028,10 +1058,10 @@ public static function CHIDIST($value, $degrees) { } return PHPExcel_Calculation_Functions::NaN(); } - return 1 - (self::_incompleteGamma($degrees/2,$value/2) / self::_gamma($degrees/2)); + return 1 - (self::_incompleteGamma($degrees/2, $value/2) / self::_gamma($degrees/2)); } return PHPExcel_Calculation_Functions::VALUE(); - } // function CHIDIST() + } /** @@ -1043,12 +1073,12 @@ public static function CHIDIST($value, $degrees) { * @param float $degrees degrees of freedom * @return float */ - public static function CHIINV($probability, $degrees) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + public static function CHIINV($probability, $degrees) + { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); if ((is_numeric($probability)) && (is_numeric($degrees))) { - $xLo = 100; $xHi = 0; @@ -1084,10 +1114,10 @@ public static function CHIINV($probability, $degrees) { if ($i == MAX_ITERATIONS) { return PHPExcel_Calculation_Functions::NA(); } - return round($x,12); + return round($x, 12); } return PHPExcel_Calculation_Functions::VALUE(); - } // function CHIINV() + } /** @@ -1101,10 +1131,11 @@ public static function CHIINV($probability, $degrees) { * @return float * */ - public static function CONFIDENCE($alpha,$stdDev,$size) { - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); - $size = floor(PHPExcel_Calculation_Functions::flattenSingleValue($size)); + public static function CONFIDENCE($alpha, $stdDev, $size) + { + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + $size = floor(PHPExcel_Calculation_Functions::flattenSingleValue($size)); if ((is_numeric($alpha)) && (is_numeric($stdDev)) && (is_numeric($size))) { if (($alpha <= 0) || ($alpha >= 1)) { @@ -1116,7 +1147,7 @@ public static function CONFIDENCE($alpha,$stdDev,$size) { return self::NORMSINV(1 - $alpha / 2) * $stdDev / sqrt($size); } return PHPExcel_Calculation_Functions::VALUE(); - } // function CONFIDENCE() + } /** @@ -1128,11 +1159,12 @@ public static function CONFIDENCE($alpha,$stdDev,$size) { * @param array of mixed Data Series X * @return float */ - public static function CORREL($yValues,$xValues=null) { + public static function CORREL($yValues, $xValues = null) + { if ((is_null($xValues)) || (!is_array($yValues)) || (!is_array($xValues))) { return PHPExcel_Calculation_Functions::VALUE(); } - if (!self::_checkTrendArrays($yValues,$xValues)) { + if (!self::checkTrendArrays($yValues, $xValues)) { return PHPExcel_Calculation_Functions::VALUE(); } $yValueCount = count($yValues); @@ -1144,9 +1176,9 @@ public static function CORREL($yValues,$xValues=null) { return PHPExcel_Calculation_Functions::DIV0(); } - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR, $yValues, $xValues); return $bestFitLinear->getCorrelation(); - } // function CORREL() + } /** @@ -1162,8 +1194,8 @@ public static function CORREL($yValues,$xValues=null) { * @param mixed $arg,... Data values * @return int */ - public static function COUNT() { - // Return value + public static function COUNT() + { $returnValue = 0; // Loop through arguments @@ -1179,9 +1211,8 @@ public static function COUNT() { } } - // Return return $returnValue; - } // function COUNT() + } /** @@ -1197,8 +1228,8 @@ public static function COUNT() { * @param mixed $arg,... Data values * @return int */ - public static function COUNTA() { - // Return value + public static function COUNTA() + { $returnValue = 0; // Loop through arguments @@ -1210,9 +1241,8 @@ public static function COUNTA() { } } - // Return return $returnValue; - } // function COUNTA() + } /** @@ -1228,8 +1258,8 @@ public static function COUNTA() { * @param mixed $arg,... Data values * @return int */ - public static function COUNTBLANK() { - // Return value + public static function COUNTBLANK() + { $returnValue = 0; // Loop through arguments @@ -1241,9 +1271,8 @@ public static function COUNTBLANK() { } } - // Return return $returnValue; - } // function COUNTBLANK() + } /** @@ -1260,15 +1289,17 @@ public static function COUNTBLANK() { * @param string $condition The criteria that defines which cells will be counted. * @return int */ - public static function COUNTIF($aArgs,$condition) { - // Return value + public static function COUNTIF($aArgs, $condition) + { $returnValue = 0; $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); // Loop through arguments foreach ($aArgs as $arg) { - if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + if (!is_numeric($arg)) { + $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + } $testCondition = '='.$arg.$condition; if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { // Is it a value within our criteria @@ -1276,9 +1307,8 @@ public static function COUNTIF($aArgs,$condition) { } } - // Return return $returnValue; - } // function COUNTIF() + } /** @@ -1290,8 +1320,9 @@ public static function COUNTIF($aArgs,$condition) { * @param array of mixed Data Series X * @return float */ - public static function COVAR($yValues,$xValues) { - if (!self::_checkTrendArrays($yValues,$xValues)) { + public static function COVAR($yValues, $xValues) + { + if (!self::checkTrendArrays($yValues, $xValues)) { return PHPExcel_Calculation_Functions::VALUE(); } $yValueCount = count($yValues); @@ -1303,9 +1334,9 @@ public static function COVAR($yValues,$xValues) { return PHPExcel_Calculation_Functions::DIV0(); } - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR, $yValues, $xValues); return $bestFitLinear->getCovariance(); - } // function COVAR() + } /** @@ -1327,26 +1358,24 @@ public static function COVAR($yValues,$xValues) { * accuracy of the function (although all my tests have so far returned correct results). * */ - public static function CRITBINOM($trials, $probability, $alpha) { - $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + public static function CRITBINOM($trials, $probability, $alpha) + { + $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); if ((is_numeric($trials)) && (is_numeric($probability)) && (is_numeric($alpha))) { if ($trials < 0) { return PHPExcel_Calculation_Functions::NaN(); - } - if (($probability < 0) || ($probability > 1)) { + } elseif (($probability < 0) || ($probability > 1)) { return PHPExcel_Calculation_Functions::NaN(); - } - if (($alpha < 0) || ($alpha > 1)) { + } elseif (($alpha < 0) || ($alpha > 1)) { return PHPExcel_Calculation_Functions::NaN(); - } - if ($alpha <= 0.5) { + } elseif ($alpha <= 0.5) { $t = sqrt(log(1 / ($alpha * $alpha))); $trialsApprox = 0 - ($t + (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t)); } else { - $t = sqrt(log(1 / pow(1 - $alpha,2))); + $t = sqrt(log(1 / pow(1 - $alpha, 2))); $trialsApprox = $t - (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t); } $Guess = floor($trials * $probability + $trialsApprox * sqrt($trials * $probability * (1 - $probability))); @@ -1361,31 +1390,47 @@ public static function CRITBINOM($trials, $probability, $alpha) { $m = floor($trials * $probability); ++$TotalUnscaledProbability; - if ($m == $Guess) { ++$UnscaledPGuess; } - if ($m <= $Guess) { ++$UnscaledCumPGuess; } + if ($m == $Guess) { + ++$UnscaledPGuess; + } + if ($m <= $Guess) { + ++$UnscaledCumPGuess; + } $PreviousValue = 1; - $Done = False; + $Done = false; $k = $m + 1; while ((!$Done) && ($k <= $trials)) { $CurrentValue = $PreviousValue * ($trials - $k + 1) * $probability / ($k * (1 - $probability)); $TotalUnscaledProbability += $CurrentValue; - if ($k == $Guess) { $UnscaledPGuess += $CurrentValue; } - if ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; } - if ($CurrentValue <= $EssentiallyZero) { $Done = True; } + if ($k == $Guess) { + $UnscaledPGuess += $CurrentValue; + } + if ($k <= $Guess) { + $UnscaledCumPGuess += $CurrentValue; + } + if ($CurrentValue <= $EssentiallyZero) { + $Done = true; + } $PreviousValue = $CurrentValue; ++$k; } $PreviousValue = 1; - $Done = False; + $Done = false; $k = $m - 1; while ((!$Done) && ($k >= 0)) { $CurrentValue = $PreviousValue * $k + 1 * (1 - $probability) / (($trials - $k) * $probability); $TotalUnscaledProbability += $CurrentValue; - if ($k == $Guess) { $UnscaledPGuess += $CurrentValue; } - if ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; } - if ($CurrentValue <= $EssentiallyZero) { $Done = True; } + if ($k == $Guess) { + $UnscaledPGuess += $CurrentValue; + } + if ($k <= $Guess) { + $UnscaledCumPGuess += $CurrentValue; + } + if ($CurrentValue <= $EssentiallyZero) { + $Done = true; + } $PreviousValue = $CurrentValue; --$k; } @@ -1396,7 +1441,7 @@ public static function CRITBINOM($trials, $probability, $alpha) { // $CumPGuessMinus1 = $CumPGuess - $PGuess; $CumPGuessMinus1 = $CumPGuess - 1; - while (True) { + while (true) { if (($CumPGuessMinus1 < $alpha) && ($CumPGuess >= $alpha)) { return $Guess; } elseif (($CumPGuessMinus1 < $alpha) && ($CumPGuess < $alpha)) { @@ -1415,7 +1460,7 @@ public static function CRITBINOM($trials, $probability, $alpha) { } } return PHPExcel_Calculation_Functions::VALUE(); - } // function CRITBINOM() + } /** @@ -1431,7 +1476,8 @@ public static function CRITBINOM($trials, $probability, $alpha) { * @param mixed $arg,... Data values * @return float */ - public static function DEVSQ() { + public static function DEVSQ() + { $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); // Return value @@ -1443,14 +1489,15 @@ public static function DEVSQ() { foreach ($aArgs as $k => $arg) { // Is it a numeric value? if ((is_bool($arg)) && - ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || + (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { $arg = (integer) $arg; } if ((is_numeric($arg)) && (!is_string($arg))) { if (is_null($returnValue)) { - $returnValue = pow(($arg - $aMean),2); + $returnValue = pow(($arg - $aMean), 2); } else { - $returnValue += pow(($arg - $aMean),2); + $returnValue += pow(($arg - $aMean), 2); } ++$aCount; } @@ -1464,7 +1511,7 @@ public static function DEVSQ() { } } return self::NA(); - } // function DEVSQ() + } /** @@ -1479,7 +1526,8 @@ public static function DEVSQ() { * @param boolean $cumulative * @return float */ - public static function EXPONDIST($value, $lambda, $cumulative) { + public static function EXPONDIST($value, $lambda, $cumulative) + { $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); $lambda = PHPExcel_Calculation_Functions::flattenSingleValue($lambda); $cumulative = PHPExcel_Calculation_Functions::flattenSingleValue($cumulative); @@ -1497,7 +1545,7 @@ public static function EXPONDIST($value, $lambda, $cumulative) { } } return PHPExcel_Calculation_Functions::VALUE(); - } // function EXPONDIST() + } /** @@ -1510,7 +1558,8 @@ public static function EXPONDIST($value, $lambda, $cumulative) { * @param float $value * @return float */ - public static function FISHER($value) { + public static function FISHER($value) + { $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); if (is_numeric($value)) { @@ -1520,7 +1569,7 @@ public static function FISHER($value) { return 0.5 * log((1+$value)/(1-$value)); } return PHPExcel_Calculation_Functions::VALUE(); - } // function FISHER() + } /** @@ -1533,14 +1582,15 @@ public static function FISHER($value) { * @param float $value * @return float */ - public static function FISHERINV($value) { + public static function FISHERINV($value) + { $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); if (is_numeric($value)) { return (exp(2 * $value) - 1) / (exp(2 * $value) + 1); } return PHPExcel_Calculation_Functions::VALUE(); - } // function FISHERINV() + } /** @@ -1553,13 +1603,12 @@ public static function FISHERINV($value) { * @param array of mixed Data Series X * @return float */ - public static function FORECAST($xValue,$yValues,$xValues) { + public static function FORECAST($xValue, $yValues, $xValues) + { $xValue = PHPExcel_Calculation_Functions::flattenSingleValue($xValue); if (!is_numeric($xValue)) { return PHPExcel_Calculation_Functions::VALUE(); - } - - if (!self::_checkTrendArrays($yValues,$xValues)) { + } elseif (!self::checkTrendArrays($yValues, $xValues)) { return PHPExcel_Calculation_Functions::VALUE(); } $yValueCount = count($yValues); @@ -1571,9 +1620,9 @@ public static function FORECAST($xValue,$yValues,$xValues) { return PHPExcel_Calculation_Functions::DIV0(); } - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR, $yValues, $xValues); return $bestFitLinear->getValueOfYForX($xValue); - } // function FORECAST() + } /** @@ -1588,10 +1637,11 @@ public static function FORECAST($xValue,$yValues,$xValues) { * @return float * */ - public static function GAMMADIST($value,$a,$b,$cumulative) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); - $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + public static function GAMMADIST($value, $a, $b, $cumulative) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); if ((is_numeric($value)) && (is_numeric($a)) && (is_numeric($b))) { if (($value < 0) || ($a <= 0) || ($b <= 0)) { @@ -1599,14 +1649,14 @@ public static function GAMMADIST($value,$a,$b,$cumulative) { } if ((is_numeric($cumulative)) || (is_bool($cumulative))) { if ($cumulative) { - return self::_incompleteGamma($a,$value / $b) / self::_gamma($a); + return self::_incompleteGamma($a, $value / $b) / self::_gamma($a); } else { - return (1 / (pow($b,$a) * self::_gamma($a))) * pow($value,$a-1) * exp(0-($value / $b)); + return (1 / (pow($b, $a) * self::_gamma($a))) * pow($value, $a-1) * exp(0-($value / $b)); } } } return PHPExcel_Calculation_Functions::VALUE(); - } // function GAMMADIST() + } /** @@ -1620,10 +1670,11 @@ public static function GAMMADIST($value,$a,$b,$cumulative) { * @return float * */ - public static function GAMMAINV($probability,$alpha,$beta) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + public static function GAMMAINV($probability, $alpha, $beta) + { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta))) { if (($alpha <= 0) || ($beta <= 0) || ($probability < 0) || ($probability > 1)) { @@ -1640,13 +1691,13 @@ public static function GAMMAINV($probability,$alpha,$beta) { while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { // Apply Newton-Raphson step - $error = self::GAMMADIST($x, $alpha, $beta, True) - $probability; + $error = self::GAMMADIST($x, $alpha, $beta, true) - $probability; if ($error < 0.0) { $xLo = $x; } else { $xHi = $x; } - $pdf = self::GAMMADIST($x, $alpha, $beta, False); + $pdf = self::GAMMADIST($x, $alpha, $beta, false); // Avoid division by zero if ($pdf != 0.0) { $dx = $error / $pdf; @@ -1667,7 +1718,7 @@ public static function GAMMAINV($probability,$alpha,$beta) { return $x; } return PHPExcel_Calculation_Functions::VALUE(); - } // function GAMMAINV() + } /** @@ -1678,7 +1729,8 @@ public static function GAMMAINV($probability,$alpha,$beta) { * @param float $value * @return float */ - public static function GAMMALN($value) { + public static function GAMMALN($value) + { $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); if (is_numeric($value)) { @@ -1688,7 +1740,7 @@ public static function GAMMALN($value) { return log(self::_gamma($value)); } return PHPExcel_Calculation_Functions::VALUE(); - } // function GAMMALN() + } /** @@ -1706,7 +1758,8 @@ public static function GAMMALN($value) { * @param mixed $arg,... Data values * @return float */ - public static function GEOMEAN() { + public static function GEOMEAN() + { $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); $aMean = PHPExcel_Calculation_MathTrig::PRODUCT($aArgs); @@ -1717,7 +1770,7 @@ public static function GEOMEAN() { } } return PHPExcel_Calculation_Functions::NaN(); - } // GEOMEAN() + } /** @@ -1731,24 +1784,25 @@ public static function GEOMEAN() { * @param boolean A logical value specifying whether to force the intersect to equal 0. * @return array of float */ - public static function GROWTH($yValues,$xValues=array(),$newValues=array(),$const=True) { + public static function GROWTH($yValues, $xValues = array(), $newValues = array(), $const = true) + { $yValues = PHPExcel_Calculation_Functions::flattenArray($yValues); $xValues = PHPExcel_Calculation_Functions::flattenArray($xValues); $newValues = PHPExcel_Calculation_Functions::flattenArray($newValues); - $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $const = (is_null($const)) ? true : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); - $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const); + $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL, $yValues, $xValues, $const); if (empty($newValues)) { $newValues = $bestFitExponential->getXValues(); } $returnArray = array(); - foreach($newValues as $xValue) { + foreach ($newValues as $xValue) { $returnArray[0][] = $bestFitExponential->getValueOfYForX($xValue); } return $returnArray; - } // function GROWTH() + } /** @@ -1765,7 +1819,8 @@ public static function GROWTH($yValues,$xValues=array(),$newValues=array(),$cons * @param mixed $arg,... Data values * @return float */ - public static function HARMEAN() { + public static function HARMEAN() + { // Return value $returnValue = PHPExcel_Calculation_Functions::NA(); @@ -1796,7 +1851,7 @@ public static function HARMEAN() { } else { return $returnValue; } - } // function HARMEAN() + } /** @@ -1812,11 +1867,12 @@ public static function HARMEAN() { * @return float * */ - public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber) { - $sampleSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleSuccesses)); - $sampleNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleNumber)); - $populationSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationSuccesses)); - $populationNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationNumber)); + public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber) + { + $sampleSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleSuccesses)); + $sampleNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleNumber)); + $populationSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationSuccesses)); + $populationNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationNumber)); if ((is_numeric($sampleSuccesses)) && (is_numeric($sampleNumber)) && (is_numeric($populationSuccesses)) && (is_numeric($populationNumber))) { if (($sampleSuccesses < 0) || ($sampleSuccesses > $sampleNumber) || ($sampleSuccesses > $populationSuccesses)) { @@ -1828,12 +1884,12 @@ public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationS if (($populationSuccesses <= 0) || ($populationSuccesses > $populationNumber)) { return PHPExcel_Calculation_Functions::NaN(); } - return PHPExcel_Calculation_MathTrig::COMBIN($populationSuccesses,$sampleSuccesses) * - PHPExcel_Calculation_MathTrig::COMBIN($populationNumber - $populationSuccesses,$sampleNumber - $sampleSuccesses) / - PHPExcel_Calculation_MathTrig::COMBIN($populationNumber,$sampleNumber); + return PHPExcel_Calculation_MathTrig::COMBIN($populationSuccesses, $sampleSuccesses) * + PHPExcel_Calculation_MathTrig::COMBIN($populationNumber - $populationSuccesses, $sampleNumber - $sampleSuccesses) / + PHPExcel_Calculation_MathTrig::COMBIN($populationNumber, $sampleNumber); } return PHPExcel_Calculation_Functions::VALUE(); - } // function HYPGEOMDIST() + } /** @@ -1845,8 +1901,9 @@ public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationS * @param array of mixed Data Series X * @return float */ - public static function INTERCEPT($yValues,$xValues) { - if (!self::_checkTrendArrays($yValues,$xValues)) { + public static function INTERCEPT($yValues, $xValues) + { + if (!self::checkTrendArrays($yValues, $xValues)) { return PHPExcel_Calculation_Functions::VALUE(); } $yValueCount = count($yValues); @@ -1858,9 +1915,9 @@ public static function INTERCEPT($yValues,$xValues) { return PHPExcel_Calculation_Functions::DIV0(); } - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR, $yValues, $xValues); return $bestFitLinear->getIntersect(); - } // function INTERCEPT() + } /** @@ -1874,7 +1931,8 @@ public static function INTERCEPT($yValues,$xValues) { * @param array Data Series * @return float */ - public static function KURT() { + public static function KURT() + { $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); $mean = self::AVERAGE($aArgs); $stdDev = self::STDEV($aArgs); @@ -1888,7 +1946,7 @@ public static function KURT() { } else { // Is it a numeric value? if ((is_numeric($arg)) && (!is_string($arg))) { - $summer += pow((($arg - $mean) / $stdDev),4) ; + $summer += pow((($arg - $mean) / $stdDev), 4); ++$count; } } @@ -1896,11 +1954,11 @@ public static function KURT() { // Return if ($count > 3) { - return $summer * ($count * ($count+1) / (($count-1) * ($count-2) * ($count-3))) - (3 * pow($count-1,2) / (($count-2) * ($count-3))); + return $summer * ($count * ($count+1) / (($count-1) * ($count-2) * ($count-3))) - (3 * pow($count-1, 2) / (($count-2) * ($count-3))); } } return PHPExcel_Calculation_Functions::DIV0(); - } // function KURT() + } /** @@ -1919,7 +1977,8 @@ public static function KURT() { * @return float * */ - public static function LARGE() { + public static function LARGE() + { $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); // Calculate @@ -1942,7 +2001,7 @@ public static function LARGE() { return $mArgs[$entry]; } return PHPExcel_Calculation_Functions::VALUE(); - } // function LARGE() + } /** @@ -1957,12 +2016,15 @@ public static function LARGE() { * @param boolean A logical value specifying whether to return additional regression statistics. * @return array */ - public static function LINEST($yValues, $xValues = NULL, $const = TRUE, $stats = FALSE) { - $const = (is_null($const)) ? TRUE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); - $stats = (is_null($stats)) ? FALSE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); - if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); + public static function LINEST($yValues, $xValues = null, $const = true, $stats = false) + { + $const = (is_null($const)) ? true : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $stats = (is_null($stats)) ? false : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); + if (is_null($xValues)) { + $xValues = range(1, count(PHPExcel_Calculation_Functions::flattenArray($yValues))); + } - if (!self::_checkTrendArrays($yValues,$xValues)) { + if (!self::checkTrendArrays($yValues, $xValues)) { return PHPExcel_Calculation_Functions::VALUE(); } $yValueCount = count($yValues); @@ -1975,27 +2037,31 @@ public static function LINEST($yValues, $xValues = NULL, $const = TRUE, $stats = return 0; } - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const); + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR, $yValues, $xValues, $const); if ($stats) { - return array( array( $bestFitLinear->getSlope(), - $bestFitLinear->getSlopeSE(), - $bestFitLinear->getGoodnessOfFit(), - $bestFitLinear->getF(), - $bestFitLinear->getSSRegression(), - ), - array( $bestFitLinear->getIntersect(), - $bestFitLinear->getIntersectSE(), - $bestFitLinear->getStdevOfResiduals(), - $bestFitLinear->getDFResiduals(), - $bestFitLinear->getSSResiduals() - ) - ); + return array( + array( + $bestFitLinear->getSlope(), + $bestFitLinear->getSlopeSE(), + $bestFitLinear->getGoodnessOfFit(), + $bestFitLinear->getF(), + $bestFitLinear->getSSRegression(), + ), + array( + $bestFitLinear->getIntersect(), + $bestFitLinear->getIntersectSE(), + $bestFitLinear->getStdevOfResiduals(), + $bestFitLinear->getDFResiduals(), + $bestFitLinear->getSSResiduals() + ) + ); } else { - return array( $bestFitLinear->getSlope(), - $bestFitLinear->getIntersect() - ); + return array( + $bestFitLinear->getSlope(), + $bestFitLinear->getIntersect() + ); } - } // function LINEST() + } /** @@ -2010,18 +2076,21 @@ public static function LINEST($yValues, $xValues = NULL, $const = TRUE, $stats = * @param boolean A logical value specifying whether to return additional regression statistics. * @return array */ - public static function LOGEST($yValues,$xValues=null,$const=True,$stats=False) { - $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); - $stats = (is_null($stats)) ? False : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); - if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); + public static function LOGEST($yValues, $xValues = null, $const = true, $stats = false) + { + $const = (is_null($const)) ? true : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $stats = (is_null($stats)) ? false : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); + if (is_null($xValues)) { + $xValues = range(1, count(PHPExcel_Calculation_Functions::flattenArray($yValues))); + } - if (!self::_checkTrendArrays($yValues,$xValues)) { + if (!self::checkTrendArrays($yValues, $xValues)) { return PHPExcel_Calculation_Functions::VALUE(); } $yValueCount = count($yValues); $xValueCount = count($xValues); - foreach($yValues as $value) { + foreach ($yValues as $value) { if ($value <= 0.0) { return PHPExcel_Calculation_Functions::NaN(); } @@ -2034,27 +2103,31 @@ public static function LOGEST($yValues,$xValues=null,$const=True,$stats=False) { return 1; } - $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const); + $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL, $yValues, $xValues, $const); if ($stats) { - return array( array( $bestFitExponential->getSlope(), - $bestFitExponential->getSlopeSE(), - $bestFitExponential->getGoodnessOfFit(), - $bestFitExponential->getF(), - $bestFitExponential->getSSRegression(), - ), - array( $bestFitExponential->getIntersect(), - $bestFitExponential->getIntersectSE(), - $bestFitExponential->getStdevOfResiduals(), - $bestFitExponential->getDFResiduals(), - $bestFitExponential->getSSResiduals() - ) - ); + return array( + array( + $bestFitExponential->getSlope(), + $bestFitExponential->getSlopeSE(), + $bestFitExponential->getGoodnessOfFit(), + $bestFitExponential->getF(), + $bestFitExponential->getSSRegression(), + ), + array( + $bestFitExponential->getIntersect(), + $bestFitExponential->getIntersectSE(), + $bestFitExponential->getStdevOfResiduals(), + $bestFitExponential->getDFResiduals(), + $bestFitExponential->getSSResiduals() + ) + ); } else { - return array( $bestFitExponential->getSlope(), - $bestFitExponential->getIntersect() - ); + return array( + $bestFitExponential->getSlope(), + $bestFitExponential->getIntersect() + ); } - } // function LOGEST() + } /** @@ -2071,10 +2144,11 @@ public static function LOGEST($yValues,$xValues=null,$const=True,$stats=False) { * accuracy if I can get my head round the mathematics * (as described at) http://home.online.no/~pjacklam/notes/invnorm/ */ - public static function LOGINV($probability, $mean, $stdDev) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + public static function LOGINV($probability, $mean, $stdDev) + { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) { if (($probability < 0) || ($probability > 1) || ($stdDev <= 0)) { @@ -2083,7 +2157,7 @@ public static function LOGINV($probability, $mean, $stdDev) { return exp($mean + $stdDev * self::NORMSINV($probability)); } return PHPExcel_Calculation_Functions::VALUE(); - } // function LOGINV() + } /** @@ -2097,10 +2171,11 @@ public static function LOGINV($probability, $mean, $stdDev) { * @param float $stdDev * @return float */ - public static function LOGNORMDIST($value, $mean, $stdDev) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + public static function LOGNORMDIST($value, $mean, $stdDev) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { if (($value <= 0) || ($stdDev <= 0)) { @@ -2109,7 +2184,7 @@ public static function LOGNORMDIST($value, $mean, $stdDev) { return self::NORMSDIST((log($value) - $mean) / $stdDev); } return PHPExcel_Calculation_Functions::VALUE(); - } // function LOGNORMDIST() + } /** @@ -2126,8 +2201,8 @@ public static function LOGNORMDIST($value, $mean, $stdDev) { * @param mixed $arg,... Data values * @return float */ - public static function MAX() { - // Return value + public static function MAX() + { $returnValue = null; // Loop through arguments @@ -2141,12 +2216,11 @@ public static function MAX() { } } - // Return - if(is_null($returnValue)) { + if (is_null($returnValue)) { return 0; } return $returnValue; - } // function MAX() + } /** @@ -2162,8 +2236,8 @@ public static function MAX() { * @param mixed $arg,... Data values * @return float */ - public static function MAXA() { - // Return value + public static function MAXA() + { $returnValue = null; // Loop through arguments @@ -2182,12 +2256,11 @@ public static function MAXA() { } } - // Return - if(is_null($returnValue)) { + if (is_null($returnValue)) { return 0; } return $returnValue; - } // function MAXA() + } /** @@ -2204,8 +2277,8 @@ public static function MAXA() { * @param string $condition The criteria that defines which cells will be checked. * @return float */ - public static function MAXIF($aArgs,$condition,$sumArgs = array()) { - // Return value + public static function MAXIF($aArgs, $condition, $sumArgs = array()) + { $returnValue = null; $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); @@ -2216,7 +2289,9 @@ public static function MAXIF($aArgs,$condition,$sumArgs = array()) { $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); // Loop through arguments foreach ($aArgs as $key => $arg) { - if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + if (!is_numeric($arg)) { + $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + } $testCondition = '='.$arg.$condition; if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { if ((is_null($returnValue)) || ($arg > $returnValue)) { @@ -2225,10 +2300,8 @@ public static function MAXIF($aArgs,$condition,$sumArgs = array()) { } } - // Return return $returnValue; - } // function MAXIF() - + } /** * MEDIAN @@ -2243,8 +2316,8 @@ public static function MAXIF($aArgs,$condition,$sumArgs = array()) { * @param mixed $arg,... Data values * @return float */ - public static function MEDIAN() { - // Return value + public static function MEDIAN() + { $returnValue = PHPExcel_Calculation_Functions::NaN(); $mArgs = array(); @@ -2259,7 +2332,7 @@ public static function MEDIAN() { $mValueCount = count($mArgs); if ($mValueCount > 0) { - sort($mArgs,SORT_NUMERIC); + sort($mArgs, SORT_NUMERIC); $mValueCount = $mValueCount / 2; if ($mValueCount == floor($mValueCount)) { $returnValue = ($mArgs[$mValueCount--] + $mArgs[$mValueCount]) / 2; @@ -2269,9 +2342,8 @@ public static function MEDIAN() { } } - // Return return $returnValue; - } // function MEDIAN() + } /** @@ -2288,8 +2360,8 @@ public static function MEDIAN() { * @param mixed $arg,... Data values * @return float */ - public static function MIN() { - // Return value + public static function MIN() + { $returnValue = null; // Loop through arguments @@ -2303,12 +2375,11 @@ public static function MIN() { } } - // Return - if(is_null($returnValue)) { + if (is_null($returnValue)) { return 0; } return $returnValue; - } // function MIN() + } /** @@ -2324,8 +2395,8 @@ public static function MIN() { * @param mixed $arg,... Data values * @return float */ - public static function MINA() { - // Return value + public static function MINA() + { $returnValue = null; // Loop through arguments @@ -2344,12 +2415,11 @@ public static function MINA() { } } - // Return - if(is_null($returnValue)) { + if (is_null($returnValue)) { return 0; } return $returnValue; - } // function MINA() + } /** @@ -2366,8 +2436,8 @@ public static function MINA() { * @param string $condition The criteria that defines which cells will be checked. * @return float */ - public static function MINIF($aArgs,$condition,$sumArgs = array()) { - // Return value + public static function MINIF($aArgs, $condition, $sumArgs = array()) + { $returnValue = null; $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); @@ -2378,7 +2448,9 @@ public static function MINIF($aArgs,$condition,$sumArgs = array()) { $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); // Loop through arguments foreach ($aArgs as $key => $arg) { - if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + if (!is_numeric($arg)) { + $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + } $testCondition = '='.$arg.$condition; if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { if ((is_null($returnValue)) || ($arg < $returnValue)) { @@ -2387,33 +2459,35 @@ public static function MINIF($aArgs,$condition,$sumArgs = array()) { } } - // Return return $returnValue; - } // function MINIF() + } // // Special variant of array_count_values that isn't limited to strings and integers, // but can work with floating point numbers as values // - private static function _modeCalc($data) { + private static function modeCalc($data) + { $frequencyArray = array(); - foreach($data as $datum) { - $found = False; - foreach($frequencyArray as $key => $value) { + foreach ($data as $datum) { + $found = false; + foreach ($frequencyArray as $key => $value) { if ((string) $value['value'] == (string) $datum) { ++$frequencyArray[$key]['frequency']; - $found = True; + $found = true; break; } } if (!$found) { - $frequencyArray[] = array('value' => $datum, - 'frequency' => 1 ); + $frequencyArray[] = array( + 'value' => $datum, + 'frequency' => 1 + ); } } - foreach($frequencyArray as $key => $value) { + foreach ($frequencyArray as $key => $value) { $frequencyList[$key] = $value['frequency']; $valueList[$key] = $value['value']; } @@ -2423,7 +2497,7 @@ private static function _modeCalc($data) { return PHPExcel_Calculation_Functions::NA(); } return $frequencyArray[0]['value']; - } // function _modeCalc() + } /** @@ -2439,8 +2513,8 @@ private static function _modeCalc($data) { * @param mixed $arg,... Data values * @return float */ - public static function MODE() { - // Return value + public static function MODE() + { $returnValue = PHPExcel_Calculation_Functions::NA(); // Loop through arguments @@ -2455,12 +2529,11 @@ public static function MODE() { } if (!empty($mArgs)) { - return self::_modeCalc($mArgs); + return self::modeCalc($mArgs); } - // Return return $returnValue; - } // function MODE() + } /** @@ -2478,16 +2551,16 @@ public static function MODE() { * @return float * */ - public static function NEGBINOMDIST($failures, $successes, $probability) { - $failures = floor(PHPExcel_Calculation_Functions::flattenSingleValue($failures)); - $successes = floor(PHPExcel_Calculation_Functions::flattenSingleValue($successes)); - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + public static function NEGBINOMDIST($failures, $successes, $probability) + { + $failures = floor(PHPExcel_Calculation_Functions::flattenSingleValue($failures)); + $successes = floor(PHPExcel_Calculation_Functions::flattenSingleValue($successes)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); if ((is_numeric($failures)) && (is_numeric($successes)) && (is_numeric($probability))) { if (($failures < 0) || ($successes < 1)) { return PHPExcel_Calculation_Functions::NaN(); - } - if (($probability < 0) || ($probability > 1)) { + } elseif (($probability < 0) || ($probability > 1)) { return PHPExcel_Calculation_Functions::NaN(); } if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { @@ -2495,10 +2568,10 @@ public static function NEGBINOMDIST($failures, $successes, $probability) { return PHPExcel_Calculation_Functions::NaN(); } } - return (PHPExcel_Calculation_MathTrig::COMBIN($failures + $successes - 1,$successes - 1)) * (pow($probability,$successes)) * (pow(1 - $probability,$failures)) ; + return (PHPExcel_Calculation_MathTrig::COMBIN($failures + $successes - 1, $successes - 1)) * (pow($probability, $successes)) * (pow(1 - $probability, $failures)); } return PHPExcel_Calculation_Functions::VALUE(); - } // function NEGBINOMDIST() + } /** @@ -2515,10 +2588,11 @@ public static function NEGBINOMDIST($failures, $successes, $probability) { * @return float * */ - public static function NORMDIST($value, $mean, $stdDev, $cumulative) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + public static function NORMDIST($value, $mean, $stdDev, $cumulative) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { if ($stdDev < 0) { @@ -2528,12 +2602,12 @@ public static function NORMDIST($value, $mean, $stdDev, $cumulative) { if ($cumulative) { return 0.5 * (1 + PHPExcel_Calculation_Engineering::erfVal(($value - $mean) / ($stdDev * sqrt(2)))); } else { - return (1 / (SQRT2PI * $stdDev)) * exp(0 - (pow($value - $mean,2) / (2 * ($stdDev * $stdDev)))); + return (1 / (SQRT2PI * $stdDev)) * exp(0 - (pow($value - $mean, 2) / (2 * ($stdDev * $stdDev)))); } } } return PHPExcel_Calculation_Functions::VALUE(); - } // function NORMDIST() + } /** @@ -2547,10 +2621,11 @@ public static function NORMDIST($value, $mean, $stdDev, $cumulative) { * @return float * */ - public static function NORMINV($probability,$mean,$stdDev) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + public static function NORMINV($probability, $mean, $stdDev) + { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) { if (($probability < 0) || ($probability > 1)) { @@ -2559,10 +2634,10 @@ public static function NORMINV($probability,$mean,$stdDev) { if ($stdDev < 0) { return PHPExcel_Calculation_Functions::NaN(); } - return (self::_inverse_ncdf($probability) * $stdDev) + $mean; + return (self::inverseNcdf($probability) * $stdDev) + $mean; } return PHPExcel_Calculation_Functions::VALUE(); - } // function NORMINV() + } /** @@ -2575,11 +2650,12 @@ public static function NORMINV($probability,$mean,$stdDev) { * @param float $value * @return float */ - public static function NORMSDIST($value) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + public static function NORMSDIST($value) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - return self::NORMDIST($value, 0, 1, True); - } // function NORMSDIST() + return self::NORMDIST($value, 0, 1, true); + } /** @@ -2590,9 +2666,10 @@ public static function NORMSDIST($value) { * @param float $value * @return float */ - public static function NORMSINV($value) { + public static function NORMSINV($value) + { return self::NORMINV($value, 0, 1); - } // function NORMSINV() + } /** @@ -2609,7 +2686,8 @@ public static function NORMSINV($value) { * @param float $entry Percentile value in the range 0..1, inclusive. * @return float */ - public static function PERCENTILE() { + public static function PERCENTILE() + { $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); // Calculate @@ -2642,7 +2720,7 @@ public static function PERCENTILE() { } } return PHPExcel_Calculation_Functions::VALUE(); - } // function PERCENTILE() + } /** @@ -2655,17 +2733,18 @@ public static function PERCENTILE() { * @param number The number of significant digits for the returned percentage value. * @return float */ - public static function PERCENTRANK($valueSet,$value,$significance=3) { - $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); + public static function PERCENTRANK($valueSet, $value, $significance = 3) + { + $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $significance = (is_null($significance)) ? 3 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($significance); + $significance = (is_null($significance)) ? 3 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($significance); - foreach($valueSet as $key => $valueEntry) { + foreach ($valueSet as $key => $valueEntry) { if (!is_numeric($valueEntry)) { unset($valueSet[$key]); } } - sort($valueSet,SORT_NUMERIC); + sort($valueSet, SORT_NUMERIC); $valueCount = count($valueSet); if ($valueCount == 0) { return PHPExcel_Calculation_Functions::NaN(); @@ -2676,8 +2755,8 @@ public static function PERCENTRANK($valueSet,$value,$significance=3) { return PHPExcel_Calculation_Functions::NA(); } - $pos = array_search($value,$valueSet); - if ($pos === False) { + $pos = array_search($value, $valueSet); + if ($pos === false) { $pos = 0; $testValue = $valueSet[0]; while ($testValue < $value) { @@ -2687,8 +2766,8 @@ public static function PERCENTRANK($valueSet,$value,$significance=3) { $pos += (($value - $valueSet[$pos]) / ($testValue - $valueSet[$pos])); } - return round($pos / $valueAdjustor,$significance); - } // function PERCENTRANK() + return round($pos / $valueAdjustor, $significance); + } /** @@ -2704,9 +2783,10 @@ public static function PERCENTRANK($valueSet,$value,$significance=3) { * @param int $numInSet Number of objects in each permutation * @return int Number of permutations */ - public static function PERMUT($numObjs,$numInSet) { - $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); - $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); + public static function PERMUT($numObjs, $numInSet) + { + $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); + $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); if ((is_numeric($numObjs)) && (is_numeric($numInSet))) { $numInSet = floor($numInSet); @@ -2716,7 +2796,7 @@ public static function PERMUT($numObjs,$numInSet) { return round(PHPExcel_Calculation_MathTrig::FACT($numObjs) / PHPExcel_Calculation_MathTrig::FACT($numObjs - $numInSet)); } return PHPExcel_Calculation_Functions::VALUE(); - } // function PERMUT() + } /** @@ -2732,9 +2812,10 @@ public static function PERMUT($numObjs,$numInSet) { * @return float * */ - public static function POISSON($value, $mean, $cumulative) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + public static function POISSON($value, $mean, $cumulative) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); if ((is_numeric($value)) && (is_numeric($mean))) { if (($value < 0) || ($mean <= 0)) { @@ -2744,16 +2825,16 @@ public static function POISSON($value, $mean, $cumulative) { if ($cumulative) { $summer = 0; for ($i = 0; $i <= floor($value); ++$i) { - $summer += pow($mean,$i) / PHPExcel_Calculation_MathTrig::FACT($i); + $summer += pow($mean, $i) / PHPExcel_Calculation_MathTrig::FACT($i); } return exp(0-$mean) * $summer; } else { - return (exp(0-$mean) * pow($mean,$value)) / PHPExcel_Calculation_MathTrig::FACT($value); + return (exp(0-$mean) * pow($mean, $value)) / PHPExcel_Calculation_MathTrig::FACT($value); } } } return PHPExcel_Calculation_Functions::VALUE(); - } // function POISSON() + } /** @@ -2770,7 +2851,8 @@ public static function POISSON($value, $mean, $cumulative) { * @param int $entry Quartile value in the range 1..3, inclusive. * @return float */ - public static function QUARTILE() { + public static function QUARTILE() + { $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); // Calculate @@ -2781,10 +2863,10 @@ public static function QUARTILE() { if (($entry < 0) || ($entry > 1)) { return PHPExcel_Calculation_Functions::NaN(); } - return self::PERCENTILE($aArgs,$entry); + return self::PERCENTILE($aArgs, $entry); } return PHPExcel_Calculation_Functions::VALUE(); - } // function QUARTILE() + } /** @@ -2797,29 +2879,30 @@ public static function QUARTILE() { * @param mixed Order to sort the values in the value set * @return float */ - public static function RANK($value,$valueSet,$order=0) { + public static function RANK($value, $valueSet, $order = 0) + { $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); - $order = (is_null($order)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($order); + $order = (is_null($order)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($order); - foreach($valueSet as $key => $valueEntry) { + foreach ($valueSet as $key => $valueEntry) { if (!is_numeric($valueEntry)) { unset($valueSet[$key]); } } if ($order == 0) { - rsort($valueSet,SORT_NUMERIC); + rsort($valueSet, SORT_NUMERIC); } else { - sort($valueSet,SORT_NUMERIC); + sort($valueSet, SORT_NUMERIC); } - $pos = array_search($value,$valueSet); - if ($pos === False) { + $pos = array_search($value, $valueSet); + if ($pos === false) { return PHPExcel_Calculation_Functions::NA(); } return ++$pos; - } // function RANK() + } /** @@ -2831,8 +2914,9 @@ public static function RANK($value,$valueSet,$order=0) { * @param array of mixed Data Series X * @return float */ - public static function RSQ($yValues,$xValues) { - if (!self::_checkTrendArrays($yValues,$xValues)) { + public static function RSQ($yValues, $xValues) + { + if (!self::checkTrendArrays($yValues, $xValues)) { return PHPExcel_Calculation_Functions::VALUE(); } $yValueCount = count($yValues); @@ -2844,9 +2928,9 @@ public static function RSQ($yValues,$xValues) { return PHPExcel_Calculation_Functions::DIV0(); } - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR, $yValues, $xValues); return $bestFitLinear->getGoodnessOfFit(); - } // function RSQ() + } /** @@ -2860,7 +2944,8 @@ public static function RSQ($yValues,$xValues) { * @param array Data Series * @return float */ - public static function SKEW() { + public static function SKEW() + { $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); $mean = self::AVERAGE($aArgs); $stdDev = self::STDEV($aArgs); @@ -2873,18 +2958,17 @@ public static function SKEW() { } else { // Is it a numeric value? if ((is_numeric($arg)) && (!is_string($arg))) { - $summer += pow((($arg - $mean) / $stdDev),3) ; + $summer += pow((($arg - $mean) / $stdDev), 3); ++$count; } } } - // Return if ($count > 2) { return $summer * ($count / (($count-1) * ($count-2))); } return PHPExcel_Calculation_Functions::DIV0(); - } // function SKEW() + } /** @@ -2896,8 +2980,9 @@ public static function SKEW() { * @param array of mixed Data Series X * @return float */ - public static function SLOPE($yValues,$xValues) { - if (!self::_checkTrendArrays($yValues,$xValues)) { + public static function SLOPE($yValues, $xValues) + { + if (!self::checkTrendArrays($yValues, $xValues)) { return PHPExcel_Calculation_Functions::VALUE(); } $yValueCount = count($yValues); @@ -2909,9 +2994,9 @@ public static function SLOPE($yValues,$xValues) { return PHPExcel_Calculation_Functions::DIV0(); } - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR, $yValues, $xValues); return $bestFitLinear->getSlope(); - } // function SLOPE() + } /** @@ -2929,7 +3014,8 @@ public static function SLOPE($yValues,$xValues) { * @param int $entry Position (ordered from the smallest) in the array or range of data to return * @return float */ - public static function SMALL() { + public static function SMALL() + { $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); // Calculate @@ -2952,7 +3038,7 @@ public static function SMALL() { return $mArgs[$entry]; } return PHPExcel_Calculation_Functions::VALUE(); - } // function SMALL() + } /** @@ -2965,10 +3051,11 @@ public static function SMALL() { * @param float $stdDev Standard Deviation * @return float Standardized value */ - public static function STANDARDIZE($value,$mean,$stdDev) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); - $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + public static function STANDARDIZE($value, $mean, $stdDev) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { if ($stdDev <= 0) { @@ -2977,7 +3064,7 @@ public static function STANDARDIZE($value,$mean,$stdDev) { return ($value - $mean) / $stdDev ; } return PHPExcel_Calculation_Functions::VALUE(); - } // function STANDARDIZE() + } /** @@ -2994,7 +3081,8 @@ public static function STANDARDIZE($value,$mean,$stdDev) { * @param mixed $arg,... Data values * @return float */ - public static function STDEV() { + public static function STDEV() + { $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); // Return value @@ -3011,9 +3099,9 @@ public static function STDEV() { // Is it a numeric value? if ((is_numeric($arg)) && (!is_string($arg))) { if (is_null($returnValue)) { - $returnValue = pow(($arg - $aMean),2); + $returnValue = pow(($arg - $aMean), 2); } else { - $returnValue += pow(($arg - $aMean),2); + $returnValue += pow(($arg - $aMean), 2); } ++$aCount; } @@ -3025,7 +3113,7 @@ public static function STDEV() { } } return PHPExcel_Calculation_Functions::DIV0(); - } // function STDEV() + } /** @@ -3041,10 +3129,10 @@ public static function STDEV() { * @param mixed $arg,... Data values * @return float */ - public static function STDEVA() { + public static function STDEVA() + { $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - // Return value $returnValue = null; $aMean = self::AVERAGEA($aArgs); @@ -3062,22 +3150,21 @@ public static function STDEVA() { $arg = 0; } if (is_null($returnValue)) { - $returnValue = pow(($arg - $aMean),2); + $returnValue = pow(($arg - $aMean), 2); } else { - $returnValue += pow(($arg - $aMean),2); + $returnValue += pow(($arg - $aMean), 2); } ++$aCount; } } } - // Return if (($aCount > 0) && ($returnValue >= 0)) { return sqrt($returnValue / $aCount); } } return PHPExcel_Calculation_Functions::DIV0(); - } // function STDEVA() + } /** @@ -3093,10 +3180,10 @@ public static function STDEVA() { * @param mixed $arg,... Data values * @return float */ - public static function STDEVP() { + public static function STDEVP() + { $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - // Return value $returnValue = null; $aMean = self::AVERAGE($aArgs); @@ -3110,21 +3197,20 @@ public static function STDEVP() { // Is it a numeric value? if ((is_numeric($arg)) && (!is_string($arg))) { if (is_null($returnValue)) { - $returnValue = pow(($arg - $aMean),2); + $returnValue = pow(($arg - $aMean), 2); } else { - $returnValue += pow(($arg - $aMean),2); + $returnValue += pow(($arg - $aMean), 2); } ++$aCount; } } - // Return if (($aCount > 0) && ($returnValue >= 0)) { return sqrt($returnValue / $aCount); } } return PHPExcel_Calculation_Functions::DIV0(); - } // function STDEVP() + } /** @@ -3140,10 +3226,10 @@ public static function STDEVP() { * @param mixed $arg,... Data values * @return float */ - public static function STDEVPA() { + public static function STDEVPA() + { $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); - // Return value $returnValue = null; $aMean = self::AVERAGEA($aArgs); @@ -3161,22 +3247,21 @@ public static function STDEVPA() { $arg = 0; } if (is_null($returnValue)) { - $returnValue = pow(($arg - $aMean),2); + $returnValue = pow(($arg - $aMean), 2); } else { - $returnValue += pow(($arg - $aMean),2); + $returnValue += pow(($arg - $aMean), 2); } ++$aCount; } } } - // Return if (($aCount > 0) && ($returnValue >= 0)) { return sqrt($returnValue / $aCount); } } return PHPExcel_Calculation_Functions::DIV0(); - } // function STDEVPA() + } /** @@ -3188,8 +3273,9 @@ public static function STDEVPA() { * @param array of mixed Data Series X * @return float */ - public static function STEYX($yValues,$xValues) { - if (!self::_checkTrendArrays($yValues,$xValues)) { + public static function STEYX($yValues, $xValues) + { + if (!self::checkTrendArrays($yValues, $xValues)) { return PHPExcel_Calculation_Functions::VALUE(); } $yValueCount = count($yValues); @@ -3201,9 +3287,9 @@ public static function STEYX($yValues,$xValues) { return PHPExcel_Calculation_Functions::DIV0(); } - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR, $yValues, $xValues); return $bestFitLinear->getStdevOfResiduals(); - } // function STEYX() + } /** @@ -3216,7 +3302,8 @@ public static function STEYX($yValues,$xValues) { * @param float $tails number of tails (1 or 2) * @return float */ - public static function TDIST($value, $degrees, $tails) { + public static function TDIST($value, $degrees, $tails) + { $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); $tails = floor(PHPExcel_Calculation_Functions::flattenSingleValue($tails)); @@ -3235,7 +3322,7 @@ public static function TDIST($value, $degrees, $tails) { // Algorithms", editied by P Griffiths and I D Hill (1985; Ellis // Horwood Ltd.; W. Sussex, England). $tterm = $degrees; - $ttheta = atan2($value,sqrt($tterm)); + $ttheta = atan2($value, sqrt($tterm)); $tc = cos($ttheta); $ts = sin($ttheta); $tsum = 0; @@ -3255,7 +3342,9 @@ public static function TDIST($value, $degrees, $tails) { $ti += 2; } $tsum *= $ts; - if (($degrees % 2) == 1) { $tsum = M_2DIVPI * ($tsum + $ttheta); } + if (($degrees % 2) == 1) { + $tsum = M_2DIVPI * ($tsum + $ttheta); + } $tValue = 0.5 * (1 + $tsum); if ($tails == 1) { return 1 - abs($tValue); @@ -3264,7 +3353,7 @@ public static function TDIST($value, $degrees, $tails) { } } return PHPExcel_Calculation_Functions::VALUE(); - } // function TDIST() + } /** @@ -3276,9 +3365,10 @@ public static function TDIST($value, $degrees, $tails) { * @param float $degrees degrees of freedom * @return float */ - public static function TINV($probability, $degrees) { - $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); - $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + public static function TINV($probability, $degrees) + { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); if ((is_numeric($probability)) && (is_numeric($degrees))) { $xLo = 100; @@ -3316,10 +3406,10 @@ public static function TINV($probability, $degrees) { if ($i == MAX_ITERATIONS) { return PHPExcel_Calculation_Functions::NA(); } - return round($x,12); + return round($x, 12); } return PHPExcel_Calculation_Functions::VALUE(); - } // function TINV() + } /** @@ -3333,24 +3423,25 @@ public static function TINV($probability, $degrees) { * @param boolean A logical value specifying whether to force the intersect to equal 0. * @return array of float */ - public static function TREND($yValues,$xValues=array(),$newValues=array(),$const=True) { + public static function TREND($yValues, $xValues = array(), $newValues = array(), $const = true) + { $yValues = PHPExcel_Calculation_Functions::flattenArray($yValues); $xValues = PHPExcel_Calculation_Functions::flattenArray($xValues); $newValues = PHPExcel_Calculation_Functions::flattenArray($newValues); - $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $const = (is_null($const)) ? true : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); - $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const); + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR, $yValues, $xValues, $const); if (empty($newValues)) { $newValues = $bestFitLinear->getXValues(); } $returnArray = array(); - foreach($newValues as $xValue) { + foreach ($newValues as $xValue) { $returnArray[0][] = $bestFitLinear->getValueOfYForX($xValue); } return $returnArray; - } // function TREND() + } /** @@ -3369,7 +3460,8 @@ public static function TREND($yValues,$xValues=array(),$newValues=array(),$const * @param float $discard Percentage to discard * @return float */ - public static function TRIMMEAN() { + public static function TRIMMEAN() + { $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); // Calculate @@ -3395,7 +3487,7 @@ public static function TRIMMEAN() { return self::AVERAGE($mArgs); } return PHPExcel_Calculation_Functions::VALUE(); - } // function TRIMMEAN() + } /** @@ -3411,8 +3503,8 @@ public static function TRIMMEAN() { * @param mixed $arg,... Data values * @return float */ - public static function VARFunc() { - // Return value + public static function VARFunc() + { $returnValue = PHPExcel_Calculation_Functions::DIV0(); $summerA = $summerB = 0; @@ -3421,7 +3513,9 @@ public static function VARFunc() { $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); $aCount = 0; foreach ($aArgs as $arg) { - if (is_bool($arg)) { $arg = (integer) $arg; } + if (is_bool($arg)) { + $arg = (integer) $arg; + } // Is it a numeric value? if ((is_numeric($arg)) && (!is_string($arg))) { $summerA += ($arg * $arg); @@ -3430,14 +3524,13 @@ public static function VARFunc() { } } - // Return if ($aCount > 1) { $summerA *= $aCount; $summerB *= $summerB; $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1)); } return $returnValue; - } // function VARFunc() + } /** @@ -3453,8 +3546,8 @@ public static function VARFunc() { * @param mixed $arg,... Data values * @return float */ - public static function VARA() { - // Return value + public static function VARA() + { $returnValue = PHPExcel_Calculation_Functions::DIV0(); $summerA = $summerB = 0; @@ -3483,14 +3576,13 @@ public static function VARA() { } } - // Return if ($aCount > 1) { $summerA *= $aCount; $summerB *= $summerB; $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1)); } return $returnValue; - } // function VARA() + } /** @@ -3506,7 +3598,8 @@ public static function VARA() { * @param mixed $arg,... Data values * @return float */ - public static function VARP() { + public static function VARP() + { // Return value $returnValue = PHPExcel_Calculation_Functions::DIV0(); @@ -3516,7 +3609,9 @@ public static function VARP() { $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); $aCount = 0; foreach ($aArgs as $arg) { - if (is_bool($arg)) { $arg = (integer) $arg; } + if (is_bool($arg)) { + $arg = (integer) $arg; + } // Is it a numeric value? if ((is_numeric($arg)) && (!is_string($arg))) { $summerA += ($arg * $arg); @@ -3525,14 +3620,13 @@ public static function VARP() { } } - // Return if ($aCount > 0) { $summerA *= $aCount; $summerB *= $summerB; $returnValue = ($summerA - $summerB) / ($aCount * $aCount); } return $returnValue; - } // function VARP() + } /** @@ -3548,8 +3642,8 @@ public static function VARP() { * @param mixed $arg,... Data values * @return float */ - public static function VARPA() { - // Return value + public static function VARPA() + { $returnValue = PHPExcel_Calculation_Functions::DIV0(); $summerA = $summerB = 0; @@ -3578,14 +3672,13 @@ public static function VARPA() { } } - // Return if ($aCount > 0) { $summerA *= $aCount; $summerB *= $summerB; $returnValue = ($summerA - $summerB) / ($aCount * $aCount); } return $returnValue; - } // function VARPA() + } /** @@ -3601,10 +3694,11 @@ public static function VARPA() { * @return float * */ - public static function WEIBULL($value, $alpha, $beta, $cumulative) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); - $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + public static function WEIBULL($value, $alpha, $beta, $cumulative) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta))) { if (($value < 0) || ($alpha <= 0) || ($beta <= 0)) { @@ -3612,14 +3706,14 @@ public static function WEIBULL($value, $alpha, $beta, $cumulative) { } if ((is_numeric($cumulative)) || (is_bool($cumulative))) { if ($cumulative) { - return 1 - exp(0 - pow($value / $beta,$alpha)); + return 1 - exp(0 - pow($value / $beta, $alpha)); } else { - return ($alpha / pow($beta,$alpha)) * pow($value,$alpha - 1) * exp(0 - pow($value / $beta,$alpha)); + return ($alpha / pow($beta, $alpha)) * pow($value, $alpha - 1) * exp(0 - pow($value / $beta, $alpha)); } } } return PHPExcel_Calculation_Functions::VALUE(); - } // function WEIBULL() + } /** @@ -3635,17 +3729,17 @@ public static function WEIBULL($value, $alpha, $beta, $cumulative) { * @return float * */ - public static function ZTEST($dataSet, $m0, $sigma = NULL) { - $dataSet = PHPExcel_Calculation_Functions::flattenArrayIndexed($dataSet); - $m0 = PHPExcel_Calculation_Functions::flattenSingleValue($m0); - $sigma = PHPExcel_Calculation_Functions::flattenSingleValue($sigma); + public static function ZTEST($dataSet, $m0, $sigma = null) + { + $dataSet = PHPExcel_Calculation_Functions::flattenArrayIndexed($dataSet); + $m0 = PHPExcel_Calculation_Functions::flattenSingleValue($m0); + $sigma = PHPExcel_Calculation_Functions::flattenSingleValue($sigma); if (is_null($sigma)) { $sigma = self::STDEV($dataSet); } $n = count($dataSet); - return 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0)/($sigma/SQRT($n))); - } // function ZTEST() - -} // class PHPExcel_Calculation_Statistical + return 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0) / ($sigma / SQRT($n))); + } +} diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php index 0a5e9f9f4..6461d0601 100644 --- a/Classes/PHPExcel/Calculation/TextData.php +++ b/Classes/PHPExcel/Calculation/TextData.php @@ -1,6 +1,16 @@ =0 && ord($c{0}) <= 127) + private static function unicodeToOrd($c) + { + if (ord($c{0}) >=0 && ord($c{0}) <= 127) { return ord($c{0}); - if (ord($c{0}) >= 192 && ord($c{0}) <= 223) + } elseif (ord($c{0}) >= 192 && ord($c{0}) <= 223) { return (ord($c{0})-192)*64 + (ord($c{1})-128); - if (ord($c{0}) >= 224 && ord($c{0}) <= 239) + } elseif (ord($c{0}) >= 224 && ord($c{0}) <= 239) { return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128); - if (ord($c{0}) >= 240 && ord($c{0}) <= 247) + } elseif (ord($c{0}) >= 240 && ord($c{0}) <= 247) { return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128); - if (ord($c{0}) >= 248 && ord($c{0}) <= 251) + } elseif (ord($c{0}) >= 248 && ord($c{0}) <= 251) { return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128); - if (ord($c{0}) >= 252 && ord($c{0}) <= 253) + } elseif (ord($c{0}) >= 252 && ord($c{0}) <= 253) { return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128); - if (ord($c{0}) >= 254 && ord($c{0}) <= 255) //error + } elseif (ord($c{0}) >= 254 && ord($c{0}) <= 255) { + // error return PHPExcel_Calculation_Functions::VALUE(); + } return 0; - } // function _uniord() + } /** * CHARACTER @@ -71,8 +65,9 @@ private static function _uniord($c) { * @param string $character Value * @return int */ - public static function CHARACTER($character) { - $character = PHPExcel_Calculation_Functions::flattenSingleValue($character); + public static function CHARACTER($character) + { + $character = PHPExcel_Calculation_Functions::flattenSingleValue($character); if ((!is_numeric($character)) || ($character < 0)) { return PHPExcel_Calculation_Functions::VALUE(); @@ -92,22 +87,23 @@ public static function CHARACTER($character) { * @param mixed $stringValue Value to check * @return string */ - public static function TRIMNONPRINTABLE($stringValue = '') { + public static function TRIMNONPRINTABLE($stringValue = '') + { $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); if (is_bool($stringValue)) { return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); } - if (self::$_invalidChars == Null) { - self::$_invalidChars = range(chr(0),chr(31)); + if (self::$invalidChars == null) { + self::$invalidChars = range(chr(0), chr(31)); } if (is_string($stringValue) || is_numeric($stringValue)) { - return str_replace(self::$_invalidChars, '', trim($stringValue, "\x00..\x1F")); + return str_replace(self::$invalidChars, '', trim($stringValue, "\x00..\x1F")); } - return NULL; - } // function TRIMNONPRINTABLE() + return null; + } /** @@ -116,17 +112,18 @@ public static function TRIMNONPRINTABLE($stringValue = '') { * @param mixed $stringValue Value to check * @return string */ - public static function TRIMSPACES($stringValue = '') { - $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); + public static function TRIMSPACES($stringValue = '') + { + $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); if (is_bool($stringValue)) { return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); } if (is_string($stringValue) || is_numeric($stringValue)) { - return trim(preg_replace('/ +/',' ',trim($stringValue, ' ')), ' '); + return trim(preg_replace('/ +/', ' ', trim($stringValue, ' ')), ' '); } - return NULL; - } // function TRIMSPACES() + return null; + } /** @@ -135,9 +132,11 @@ public static function TRIMSPACES($stringValue = '') { * @param string $characters Value * @return int */ - public static function ASCIICODE($characters) { - if (($characters === NULL) || ($characters === '')) + public static function ASCIICODE($characters) + { + if (($characters === null) || ($characters === '')) { return PHPExcel_Calculation_Functions::VALUE(); + } $characters = PHPExcel_Calculation_Functions::flattenSingleValue($characters); if (is_bool($characters)) { if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { @@ -149,13 +148,17 @@ public static function ASCIICODE($characters) { $character = $characters; if ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) { - if (mb_strlen($characters, 'UTF-8') > 1) { $character = mb_substr($characters, 0, 1, 'UTF-8'); } - return self::_uniord($character); + if (mb_strlen($characters, 'UTF-8') > 1) { + $character = mb_substr($characters, 0, 1, 'UTF-8'); + } + return self::unicodeToOrd($character); } else { - if (strlen($characters) > 0) { $character = substr($characters, 0, 1); } + if (strlen($characters) > 0) { + $character = substr($characters, 0, 1); + } return ord($character); } - } // function ASCIICODE() + } /** @@ -163,8 +166,8 @@ public static function ASCIICODE($characters) { * * @return string */ - public static function CONCATENATE() { - // Return value + public static function CONCATENATE() + { $returnValue = ''; // Loop through arguments @@ -180,9 +183,8 @@ public static function CONCATENATE() { $returnValue .= $arg; } - // Return return $returnValue; - } // function CONCATENATE() + } /** @@ -197,7 +199,8 @@ public static function CONCATENATE() { * If you omit decimals, it is assumed to be 2 * @return string */ - public static function DOLLAR($value = 0, $decimals = 2) { + public static function DOLLAR($value = 0, $decimals = 2) + { $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); $decimals = is_null($decimals) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($decimals); @@ -209,16 +212,18 @@ public static function DOLLAR($value = 0, $decimals = 2) { $mask = '$#,##0'; if ($decimals > 0) { - $mask .= '.' . str_repeat('0',$decimals); + $mask .= '.' . str_repeat('0', $decimals); } else { - $round = pow(10,abs($decimals)); - if ($value < 0) { $round = 0-$round; } + $round = pow(10, abs($decimals)); + if ($value < 0) { + $round = 0-$round; + } $value = PHPExcel_Calculation_MathTrig::MROUND($value, $round); } return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask); - } // function DOLLAR() + } /** @@ -229,10 +234,11 @@ public static function DOLLAR($value = 0, $decimals = 2) { * @param int $offset Offset within $haystack * @return string */ - public static function SEARCHSENSITIVE($needle,$haystack,$offset=1) { - $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); - $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); - $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); + public static function SEARCHSENSITIVE($needle, $haystack, $offset = 1) + { + $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); + $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); + $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); if (!is_bool($needle)) { if (is_bool($haystack)) { @@ -254,7 +260,7 @@ public static function SEARCHSENSITIVE($needle,$haystack,$offset=1) { } } return PHPExcel_Calculation_Functions::VALUE(); - } // function SEARCHSENSITIVE() + } /** @@ -265,10 +271,11 @@ public static function SEARCHSENSITIVE($needle,$haystack,$offset=1) { * @param int $offset Offset within $haystack * @return string */ - public static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) { - $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); - $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); - $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); + public static function SEARCHINSENSITIVE($needle, $haystack, $offset = 1) + { + $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); + $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); + $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); if (!is_bool($needle)) { if (is_bool($haystack)) { @@ -280,7 +287,7 @@ public static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) { return $offset; } if (function_exists('mb_stripos')) { - $pos = mb_stripos($haystack, $needle, --$offset,'UTF-8'); + $pos = mb_stripos($haystack, $needle, --$offset, 'UTF-8'); } else { $pos = stripos($haystack, $needle, --$offset); } @@ -290,7 +297,7 @@ public static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) { } } return PHPExcel_Calculation_Functions::VALUE(); - } // function SEARCHINSENSITIVE() + } /** @@ -301,10 +308,11 @@ public static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) { * @param boolean $no_commas * @return boolean */ - public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = FALSE) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $decimals = PHPExcel_Calculation_Functions::flattenSingleValue($decimals); - $no_commas = PHPExcel_Calculation_Functions::flattenSingleValue($no_commas); + public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = false) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $decimals = PHPExcel_Calculation_Functions::flattenSingleValue($decimals); + $no_commas = PHPExcel_Calculation_Functions::flattenSingleValue($no_commas); // Validate parameters if (!is_numeric($value) || !is_numeric($decimals)) { @@ -312,14 +320,16 @@ public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = FALSE) { } $decimals = floor($decimals); - $valueResult = round($value,$decimals); - if ($decimals < 0) { $decimals = 0; } + $valueResult = round($value, $decimals); + if ($decimals < 0) { + $decimals = 0; + } if (!$no_commas) { - $valueResult = number_format($valueResult,$decimals); + $valueResult = number_format($valueResult, $decimals); } return (string) $valueResult; - } // function FIXEDFORMAT() + } /** @@ -329,9 +339,10 @@ public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = FALSE) { * @param int $chars Number of characters * @return string */ - public static function LEFT($value = '', $chars = 1) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + public static function LEFT($value = '', $chars = 1) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); if ($chars < 0) { return PHPExcel_Calculation_Functions::VALUE(); @@ -346,7 +357,7 @@ public static function LEFT($value = '', $chars = 1) { } else { return substr($value, 0, $chars); } - } // function LEFT() + } /** @@ -357,10 +368,11 @@ public static function LEFT($value = '', $chars = 1) { * @param int $chars Number of characters * @return string */ - public static function MID($value = '', $start = 1, $chars = null) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); - $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + public static function MID($value = '', $start = 1, $chars = null) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); if (($start < 1) || ($chars < 0)) { return PHPExcel_Calculation_Functions::VALUE(); @@ -375,7 +387,7 @@ public static function MID($value = '', $start = 1, $chars = null) { } else { return substr($value, --$start, $chars); } - } // function MID() + } /** @@ -385,9 +397,10 @@ public static function MID($value = '', $start = 1, $chars = null) { * @param int $chars Number of characters * @return string */ - public static function RIGHT($value = '', $chars = 1) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + public static function RIGHT($value = '', $chars = 1) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); if ($chars < 0) { return PHPExcel_Calculation_Functions::VALUE(); @@ -402,7 +415,7 @@ public static function RIGHT($value = '', $chars = 1) { } else { return substr($value, strlen($value) - $chars); } - } // function RIGHT() + } /** @@ -411,8 +424,9 @@ public static function RIGHT($value = '', $chars = 1) { * @param string $value Value * @return string */ - public static function STRINGLENGTH($value = '') { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + public static function STRINGLENGTH($value = '') + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); if (is_bool($value)) { $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); @@ -423,7 +437,7 @@ public static function STRINGLENGTH($value = '') { } else { return strlen($value); } - } // function STRINGLENGTH() + } /** @@ -434,15 +448,16 @@ public static function STRINGLENGTH($value = '') { * @param string $mixedCaseString * @return string */ - public static function LOWERCASE($mixedCaseString) { - $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + public static function LOWERCASE($mixedCaseString) + { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); if (is_bool($mixedCaseString)) { $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); } return PHPExcel_Shared_String::StrToLower($mixedCaseString); - } // function LOWERCASE() + } /** @@ -453,15 +468,16 @@ public static function LOWERCASE($mixedCaseString) { * @param string $mixedCaseString * @return string */ - public static function UPPERCASE($mixedCaseString) { - $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + public static function UPPERCASE($mixedCaseString) + { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); if (is_bool($mixedCaseString)) { $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); } return PHPExcel_Shared_String::StrToUpper($mixedCaseString); - } // function UPPERCASE() + } /** @@ -472,15 +488,16 @@ public static function UPPERCASE($mixedCaseString) { * @param string $mixedCaseString * @return string */ - public static function PROPERCASE($mixedCaseString) { - $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + public static function PROPERCASE($mixedCaseString) + { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); if (is_bool($mixedCaseString)) { $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); } return PHPExcel_Shared_String::StrToTitle($mixedCaseString); - } // function PROPERCASE() + } /** @@ -489,20 +506,21 @@ public static function PROPERCASE($mixedCaseString) { * @param string $oldText String to modify * @param int $start Start character * @param int $chars Number of characters - * @param string $newText String to replace in defined position + * @param string $newText String to replace in defined position * @return string */ - public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) { - $oldText = PHPExcel_Calculation_Functions::flattenSingleValue($oldText); - $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); - $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); - $newText = PHPExcel_Calculation_Functions::flattenSingleValue($newText); + public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) + { + $oldText = PHPExcel_Calculation_Functions::flattenSingleValue($oldText); + $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + $newText = PHPExcel_Calculation_Functions::flattenSingleValue($newText); - $left = self::LEFT($oldText,$start-1); - $right = self::RIGHT($oldText,self::STRINGLENGTH($oldText)-($start+$chars)+1); + $left = self::LEFT($oldText, $start-1); + $right = self::RIGHT($oldText, self::STRINGLENGTH($oldText)-($start+$chars)+1); return $left.$newText.$right; - } // function REPLACE() + } /** @@ -514,21 +532,22 @@ public static function REPLACE($oldText = '', $start = 1, $chars = null, $newTex * @param integer $instance Instance Number * @return string */ - public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0) { - $text = PHPExcel_Calculation_Functions::flattenSingleValue($text); - $fromText = PHPExcel_Calculation_Functions::flattenSingleValue($fromText); - $toText = PHPExcel_Calculation_Functions::flattenSingleValue($toText); - $instance = floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance)); + public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0) + { + $text = PHPExcel_Calculation_Functions::flattenSingleValue($text); + $fromText = PHPExcel_Calculation_Functions::flattenSingleValue($fromText); + $toText = PHPExcel_Calculation_Functions::flattenSingleValue($toText); + $instance = floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance)); if ($instance == 0) { - if(function_exists('mb_str_replace')) { - return mb_str_replace($fromText,$toText,$text); + if (function_exists('mb_str_replace')) { + return mb_str_replace($fromText, $toText, $text); } else { - return str_replace($fromText,$toText,$text); + return str_replace($fromText, $toText, $text); } } else { $pos = -1; - while($instance > 0) { + while ($instance > 0) { if (function_exists('mb_strpos')) { $pos = mb_strpos($text, $fromText, $pos+1, 'UTF-8'); } else { @@ -541,15 +560,15 @@ public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $ins } if ($pos !== false) { if (function_exists('mb_strlen')) { - return self::REPLACE($text,++$pos,mb_strlen($fromText, 'UTF-8'),$toText); + return self::REPLACE($text, ++$pos, mb_strlen($fromText, 'UTF-8'), $toText); } else { - return self::REPLACE($text,++$pos,strlen($fromText),$toText); + return self::REPLACE($text, ++$pos, strlen($fromText), $toText); } } } return $text; - } // function SUBSTITUTE() + } /** @@ -558,14 +577,15 @@ public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $ins * @param mixed $testValue Value to check * @return boolean */ - public static function RETURNSTRING($testValue = '') { - $testValue = PHPExcel_Calculation_Functions::flattenSingleValue($testValue); + public static function RETURNSTRING($testValue = '') + { + $testValue = PHPExcel_Calculation_Functions::flattenSingleValue($testValue); if (is_string($testValue)) { return $testValue; } - return Null; - } // function RETURNSTRING() + return null; + } /** @@ -575,16 +595,17 @@ public static function RETURNSTRING($testValue = '') { * @param string $format Format mask to use * @return boolean */ - public static function TEXTFORMAT($value,$format) { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); - $format = PHPExcel_Calculation_Functions::flattenSingleValue($format); + public static function TEXTFORMAT($value, $format) + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $format = PHPExcel_Calculation_Functions::flattenSingleValue($format); if ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date::isDateTimeFormatCode($format)) { $value = PHPExcel_Calculation_DateTime::DATEVALUE($value); } - return (string) PHPExcel_Style_NumberFormat::toFormattedString($value,$format); - } // function TEXTFORMAT() + return (string) PHPExcel_Style_NumberFormat::toFormattedString($value, $format); + } /** * VALUE @@ -592,13 +613,14 @@ public static function TEXTFORMAT($value,$format) { * @param mixed $value Value to check * @return boolean */ - public static function VALUE($value = '') { - $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + public static function VALUE($value = '') + { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); if (!is_numeric($value)) { $numberValue = str_replace( - PHPExcel_Shared_String::getThousandsSeparator(), - '', + PHPExcel_Shared_String::getThousandsSeparator(), + '', trim($value, " \t\n\r\0\x0B" . PHPExcel_Shared_String::getCurrencyCode()) ); if (is_numeric($numberValue)) { @@ -626,5 +648,4 @@ public static function VALUE($value = '') { } return (float) $value; } - } diff --git a/Classes/PHPExcel/Calculation/Token/Stack.php b/Classes/PHPExcel/Calculation/Token/Stack.php index 7d561d4d3..13f446ab9 100644 --- a/Classes/PHPExcel/Calculation/Token/Stack.php +++ b/Classes/PHPExcel/Calculation/Token/Stack.php @@ -32,14 +32,14 @@ class PHPExcel_Calculation_Token_Stack * * @var mixed[] */ - private $_stack = array(); + private $stack = array(); /** * Count of entries in the parser stack * * @var integer */ - private $_count = 0; + private $count = 0; /** * Return the number of entries on the stack @@ -48,7 +48,7 @@ class PHPExcel_Calculation_Token_Stack */ public function count() { - return $this->_count; + return $this->count; } /** @@ -60,15 +60,15 @@ public function count() */ public function push($type, $value, $reference = null) { - $this->_stack[$this->_count++] = array( - 'type' => $type, - 'value' => $value, - 'reference' => $reference + $this->stack[$this->count++] = array( + 'type' => $type, + 'value' => $value, + 'reference' => $reference ); if ($type == 'Function') { $localeFunction = PHPExcel_Calculation::_localeFunc($value); if ($localeFunction != $value) { - $this->_stack[($this->_count - 1)]['localeValue'] = $localeFunction; + $this->stack[($this->count - 1)]['localeValue'] = $localeFunction; } } } @@ -80,8 +80,8 @@ public function push($type, $value, $reference = null) */ public function pop() { - if ($this->_count > 0) { - return $this->_stack[--$this->_count]; + if ($this->count > 0) { + return $this->stack[--$this->count]; } return null; } @@ -94,18 +94,18 @@ public function pop() */ public function last($n = 1) { - if ($this->_count - $n < 0) { + if ($this->count - $n < 0) { return null; } - return $this->_stack[$this->_count - $n]; + return $this->stack[$this->count - $n]; } /** * Clear the stack */ - function clear() + public function clear() { - $this->_stack = array(); - $this->_count = 0; + $this->stack = array(); + $this->count = 0; } } From 547d2bd3b24cf4c6207f9b086dd2c64390ecf571 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 11 May 2015 01:31:26 +0100 Subject: [PATCH 346/467] More PSR-2 --- Classes/PHPExcel/Calculation/Database.php | 2 +- Classes/PHPExcel/Calculation/Functions.php | 30 +- Classes/PHPExcel/Calculation/MathTrig.php | 2 +- Classes/PHPExcel/Calculation/Statistical.php | 44 +- Classes/PHPExcel/Cell.php | 1908 +++++++++--------- 5 files changed, 989 insertions(+), 997 deletions(-) diff --git a/Classes/PHPExcel/Calculation/Database.php b/Classes/PHPExcel/Calculation/Database.php index 9afcffd49..af150fe03 100644 --- a/Classes/PHPExcel/Calculation/Database.php +++ b/Classes/PHPExcel/Calculation/Database.php @@ -99,7 +99,7 @@ private static function filter($database, $criteria) $testConditionCount = 0; foreach ($criteria as $row => $criterion) { if ($criterion[$key] > '') { - $testCondition[] = '[:'.$criteriaName.']'.PHPExcel_Calculation_Functions::_ifCondition($criterion[$key]); + $testCondition[] = '[:'.$criteriaName.']'.PHPExcel_Calculation_Functions::ifCondition($criterion[$key]); $testConditionCount++; } } diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index b10f242c5..4d1771b9d 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -67,7 +67,7 @@ class PHPExcel_Calculation_Functions * @access private * @var string */ - protected static $compatibilityMode = self::COMPATIBILITY_EXCEL; + protected static $compatibilityMode = self::COMPATIBILITY_EXCEL; /** * Data Type to use when returning date values @@ -75,7 +75,7 @@ class PHPExcel_Calculation_Functions * @access private * @var string */ - protected static $ReturnDateType = self::RETURNDATE_EXCEL; + protected static $returnDateType = self::RETURNDATE_EXCEL; /** * List of error codes @@ -83,7 +83,7 @@ class PHPExcel_Calculation_Functions * @access private * @var array */ - protected static $_errorCodes = array( + protected static $errorCodes = array( 'null' => '#NULL!', 'divisionbyzero' => '#DIV/0!', 'value' => '#VALUE!', @@ -153,7 +153,7 @@ public static function setReturnDateType($returnDateType) if (($returnDateType == self::RETURNDATE_PHP_NUMERIC) || ($returnDateType == self::RETURNDATE_PHP_OBJECT) || ($returnDateType == self::RETURNDATE_EXCEL)) { - self::$ReturnDateType = $returnDateType; + self::$returnDateType = $returnDateType; return true; } return false; @@ -173,7 +173,7 @@ public static function setReturnDateType($returnDateType) */ public static function getReturnDateType() { - return self::$ReturnDateType; + return self::$returnDateType; } @@ -199,7 +199,7 @@ public static function DUMMY() */ public static function DIV0() { - return self::$_errorCodes['divisionbyzero']; + return self::$errorCodes['divisionbyzero']; } @@ -218,7 +218,7 @@ public static function DIV0() */ public static function NA() { - return self::$_errorCodes['na']; + return self::$errorCodes['na']; } @@ -233,7 +233,7 @@ public static function NA() */ public static function NaN() { - return self::$_errorCodes['num']; + return self::$errorCodes['num']; } @@ -248,7 +248,7 @@ public static function NaN() */ public static function NAME() { - return self::$_errorCodes['name']; + return self::$errorCodes['name']; } @@ -263,7 +263,7 @@ public static function NAME() */ public static function REF() { - return self::$_errorCodes['reference']; + return self::$errorCodes['reference']; } @@ -278,7 +278,7 @@ public static function REF() */ public static function NULL() { - return self::$_errorCodes['null']; + return self::$errorCodes['null']; } @@ -293,7 +293,7 @@ public static function NULL() */ public static function VALUE() { - return self::$_errorCodes['value']; + return self::$errorCodes['value']; } @@ -315,7 +315,7 @@ public static function isCellValue($idx) } - public static function _ifCondition($condition) + public static function ifCondition($condition) { $condition = PHPExcel_Calculation_Functions::flattenSingleValue($condition); if (!isset($condition{0})) { @@ -350,7 +350,7 @@ public static function ERROR_TYPE($value = '') $value = self::flattenSingleValue($value); $i = 1; - foreach (self::$_errorCodes as $errorCode) { + foreach (self::$errorCodes as $errorCode) { if ($value === $errorCode) { return $i; } @@ -403,7 +403,7 @@ public static function IS_ERROR($value = '') if (!is_string($value)) { return false; } - return in_array($value, array_values(self::$_errorCodes)); + return in_array($value, array_values(self::$errorCodes)); } diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index df0c88b8d..d062d032f 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -1201,7 +1201,7 @@ public static function SUMIF($aArgs, $condition, $sumArgs = array()) if (empty($sumArgs)) { $sumArgs = $aArgs; } - $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + $condition = PHPExcel_Calculation_Functions::ifCondition($condition); // Loop through arguments foreach ($aArgs as $key => $arg) { if (!is_numeric($arg)) { diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php index ad523f67d..11e54a5e4 100644 --- a/Classes/PHPExcel/Calculation/Statistical.php +++ b/Classes/PHPExcel/Calculation/Statistical.php @@ -91,12 +91,12 @@ private static function checkTrendArrays(&$array1, &$array2) * @param q require q>0 * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow */ - private static function _beta($p, $q) + private static function beta($p, $q) { if ($p <= 0.0 || $q <= 0.0 || ($p + $q) > LOG_GAMMA_X_MAX_VALUE) { return 0.0; } else { - return exp(self::_logBeta($p, $q)); + return exp(self::logBeta($p, $q)); } } @@ -113,7 +113,7 @@ private static function _beta($p, $q) * @param q require q>0 * @return 0 if x<0, p<=0, q<=0 or p+q>2.55E305 and 1 if x>1 to avoid errors and over/underflow */ - private static function _incompleteBeta($x, $p, $q) + private static function incompleteBeta($x, $p, $q) { if ($x <= 0.0) { return 0.0; @@ -122,16 +122,16 @@ private static function _incompleteBeta($x, $p, $q) } elseif (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { return 0.0; } - $beta_gam = exp((0 - self::_logBeta($p, $q)) + $p * log($x) + $q * log(1.0 - $x)); + $beta_gam = exp((0 - self::logBeta($p, $q)) + $p * log($x) + $q * log(1.0 - $x)); if ($x < ($p + 1.0) / ($p + $q + 2.0)) { - return $beta_gam * self::_betaFraction($x, $p, $q) / $p; + return $beta_gam * self::betaFraction($x, $p, $q) / $p; } else { - return 1.0 - ($beta_gam * self::_betaFraction(1 - $x, $q, $p) / $q); + return 1.0 - ($beta_gam * self::betaFraction(1 - $x, $q, $p) / $q); } } - // Function cache for _logBeta function + // Function cache for logBeta function private static $logBetaCacheP = 0.0; private static $logBetaCacheQ = 0.0; private static $logBetaCacheResult = 0.0; @@ -144,7 +144,7 @@ private static function _incompleteBeta($x, $p, $q) * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow * @author Jaco van Kooten */ - private static function _logBeta($p, $q) + private static function logBeta($p, $q) { if ($p != self::$logBetaCacheP || $q != self::$logBetaCacheQ) { self::$logBetaCacheP = $p; @@ -152,7 +152,7 @@ private static function _logBeta($p, $q) if (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { self::$logBetaCacheResult = 0.0; } else { - self::$logBetaCacheResult = self::_logGamma($p) + self::_logGamma($q) - self::_logGamma($p + $q); + self::$logBetaCacheResult = self::logGamma($p) + self::logGamma($q) - self::logGamma($p + $q); } } return self::$logBetaCacheResult; @@ -164,7 +164,7 @@ private static function _logBeta($p, $q) * Based on an idea from Numerical Recipes (W.H. Press et al, 1992). * @author Jaco van Kooten */ - private static function _betaFraction($x, $p, $q) + private static function betaFraction($x, $p, $q) { $c = 1.0; $sum_pq = $p + $q; @@ -258,7 +258,7 @@ private static function _betaFraction($x, $p, $q) private static $logGammaCacheResult = 0.0; private static $logGammaCacheX = 0.0; - private static function _logGamma($x) + private static function logGamma($x) { // Log Gamma related constants static $lg_d1 = -0.5772156649015328605195174; @@ -435,7 +435,7 @@ private static function _logGamma($x) // // Private implementation of the incomplete Gamma function // - private static function _incompleteGamma($a, $x) + private static function incompleteGamma($a, $x) { static $max = 32; $summer = 0; @@ -453,7 +453,7 @@ private static function _incompleteGamma($a, $x) // // Private implementation of the Gamma function // - private static function _gamma($data) + private static function gamma($data) { if ($data == 0.0) { return 0; @@ -872,7 +872,7 @@ public static function AVERAGEIF($aArgs, $condition, $averageArgs = array()) if (empty($averageArgs)) { $averageArgs = $aArgs; } - $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + $condition = PHPExcel_Calculation_Functions::ifCondition($condition); // Loop through arguments $aCount = 0; foreach ($aArgs as $key => $arg) { @@ -926,7 +926,7 @@ public static function BETADIST($value, $alpha, $beta, $rMin = 0, $rMax = 1) } $value -= $rMin; $value /= ($rMax - $rMin); - return self::_incompleteBeta($value, $alpha, $beta); + return self::incompleteBeta($value, $alpha, $beta); } return PHPExcel_Calculation_Functions::VALUE(); } @@ -1058,7 +1058,7 @@ public static function CHIDIST($value, $degrees) } return PHPExcel_Calculation_Functions::NaN(); } - return 1 - (self::_incompleteGamma($degrees/2, $value/2) / self::_gamma($degrees/2)); + return 1 - (self::incompleteGamma($degrees/2, $value/2) / self::gamma($degrees/2)); } return PHPExcel_Calculation_Functions::VALUE(); } @@ -1294,7 +1294,7 @@ public static function COUNTIF($aArgs, $condition) $returnValue = 0; $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); - $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + $condition = PHPExcel_Calculation_Functions::ifCondition($condition); // Loop through arguments foreach ($aArgs as $arg) { if (!is_numeric($arg)) { @@ -1649,9 +1649,9 @@ public static function GAMMADIST($value, $a, $b, $cumulative) } if ((is_numeric($cumulative)) || (is_bool($cumulative))) { if ($cumulative) { - return self::_incompleteGamma($a, $value / $b) / self::_gamma($a); + return self::incompleteGamma($a, $value / $b) / self::gamma($a); } else { - return (1 / (pow($b, $a) * self::_gamma($a))) * pow($value, $a-1) * exp(0-($value / $b)); + return (1 / (pow($b, $a) * self::gamma($a))) * pow($value, $a-1) * exp(0-($value / $b)); } } } @@ -1737,7 +1737,7 @@ public static function GAMMALN($value) if ($value <= 0) { return PHPExcel_Calculation_Functions::NaN(); } - return log(self::_gamma($value)); + return log(self::gamma($value)); } return PHPExcel_Calculation_Functions::VALUE(); } @@ -2286,7 +2286,7 @@ public static function MAXIF($aArgs, $condition, $sumArgs = array()) if (empty($sumArgs)) { $sumArgs = $aArgs; } - $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + $condition = PHPExcel_Calculation_Functions::ifCondition($condition); // Loop through arguments foreach ($aArgs as $key => $arg) { if (!is_numeric($arg)) { @@ -2445,7 +2445,7 @@ public static function MINIF($aArgs, $condition, $sumArgs = array()) if (empty($sumArgs)) { $sumArgs = $aArgs; } - $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + $condition = PHPExcel_Calculation_Functions::ifCondition($condition); // Loop through arguments foreach ($aArgs as $key => $arg) { if (!is_numeric($arg)) { diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index ae5b557d5..4e1c863c7 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -1,369 +1,361 @@ _parent->updateCacheData($this); - - return $this; - } - - public function detach() { - $this->_parent = NULL; - } - - public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) { - $this->_parent = $parent; - } - - - /** - * Create a new Cell - * - * @param mixed $pValue - * @param string $pDataType - * @param PHPExcel_Worksheet $pSheet - * @throws PHPExcel_Exception - */ - public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL) - { - // Initialise cell value - $this->_value = $pValue; - - // Set worksheet cache - $this->_parent = $pSheet->getCellCacheController(); - - // Set datatype? - if ($pDataType !== NULL) { - if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) - $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; - $this->_dataType = $pDataType; - } elseif (!self::getValueBinder()->bindValue($this, $pValue)) { + /** + * Default range variable constant + * + * @var string + */ + const DEFAULT_RANGE = 'A1:A1'; + + /** + * Value binder to use + * + * @var PHPExcel_Cell_IValueBinder + */ + private static $_valueBinder = NULL; + + /** + * Value of the cell + * + * @var mixed + */ + private $_value; + + /** + * Calculated value of the cell (used for caching) + * This returns the value last calculated by MS Excel or whichever spreadsheet program was used to + * create the original spreadsheet file. + * Note that this value is not guaranteed to reflect the actual calculated value because it is + * possible that auto-calculation was disabled in the original spreadsheet, and underlying data + * values used by the formula have changed since it was last calculated. + * + * @var mixed + */ + private $_calculatedValue = NULL; + + /** + * Type of the cell data + * + * @var string + */ + private $_dataType; + + /** + * Parent worksheet + * + * @var PHPExcel_CachedObjectStorage_CacheBase + */ + private $_parent; + + /** + * Index to cellXf + * + * @var int + */ + private $_xfIndex = 0; + + /** + * Attributes of the formula + * + */ + private $_formulaAttributes; + + + /** + * Send notification to the cache controller + * + * @return void + **/ + public function notifyCacheController() { + $this->_parent->updateCacheData($this); + + return $this; + } + + public function detach() { + $this->_parent = NULL; + } + + public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) { + $this->_parent = $parent; + } + + + /** + * Create a new Cell + * + * @param mixed $pValue + * @param string $pDataType + * @param PHPExcel_Worksheet $pSheet + * @throws PHPExcel_Exception + */ + public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL) + { + // Initialise cell value + $this->_value = $pValue; + + // Set worksheet cache + $this->_parent = $pSheet->getCellCacheController(); + + // Set datatype? + if ($pDataType !== NULL) { + if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) + $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + $this->_dataType = $pDataType; + } elseif (!self::getValueBinder()->bindValue($this, $pValue)) { + throw new PHPExcel_Exception("Value could not be bound to cell."); + } + } + + /** + * Get cell coordinate column + * + * @return string + */ + public function getColumn() + { + return $this->_parent->getCurrentColumn(); + } + + /** + * Get cell coordinate row + * + * @return int + */ + public function getRow() + { + return $this->_parent->getCurrentRow(); + } + + /** + * Get cell coordinate + * + * @return string + */ + public function getCoordinate() + { + return $this->_parent->getCurrentAddress(); + } + + /** + * Get cell value + * + * @return mixed + */ + public function getValue() + { + return $this->_value; + } + + /** + * Get cell value with formatting + * + * @return string + */ + public function getFormattedValue() + { + return (string) PHPExcel_Style_NumberFormat::toFormattedString( + $this->getCalculatedValue(), + $this->getStyle() + ->getNumberFormat()->getFormatCode() + ); + } + + /** + * Set cell value + * + * Sets the value for a cell, automatically determining the datatype using the value binder + * + * @param mixed $pValue Value + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setValue($pValue = NULL) + { + if (!self::getValueBinder()->bindValue($this, $pValue)) { throw new PHPExcel_Exception("Value could not be bound to cell."); - } - } - - /** - * Get cell coordinate column - * - * @return string - */ - public function getColumn() - { - return $this->_parent->getCurrentColumn(); - } - - /** - * Get cell coordinate row - * - * @return int - */ - public function getRow() - { - return $this->_parent->getCurrentRow(); - } - - /** - * Get cell coordinate - * - * @return string - */ - public function getCoordinate() - { - return $this->_parent->getCurrentAddress(); - } - - /** - * Get cell value - * - * @return mixed - */ - public function getValue() - { - return $this->_value; - } - - /** - * Get cell value with formatting - * - * @return string - */ - public function getFormattedValue() - { - return (string) PHPExcel_Style_NumberFormat::toFormattedString( - $this->getCalculatedValue(), - $this->getStyle() - ->getNumberFormat()->getFormatCode() - ); - } - - /** - * Set cell value - * - * Sets the value for a cell, automatically determining the datatype using the value binder - * - * @param mixed $pValue Value - * @return PHPExcel_Cell - * @throws PHPExcel_Exception - */ - public function setValue($pValue = NULL) - { - if (!self::getValueBinder()->bindValue($this, $pValue)) { - throw new PHPExcel_Exception("Value could not be bound to cell."); - } - return $this; - } - - /** - * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder) - * - * @param mixed $pValue Value - * @param string $pDataType Explicit data type - * @return PHPExcel_Cell - * @throws PHPExcel_Exception - */ - public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) - { - // set the value according to data type - switch ($pDataType) { - case PHPExcel_Cell_DataType::TYPE_NULL: - $this->_value = $pValue; - break; - case PHPExcel_Cell_DataType::TYPE_STRING2: - $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; - case PHPExcel_Cell_DataType::TYPE_STRING: - case PHPExcel_Cell_DataType::TYPE_INLINE: - $this->_value = PHPExcel_Cell_DataType::checkString($pValue); - break; - case PHPExcel_Cell_DataType::TYPE_NUMERIC: - $this->_value = (float)$pValue; - break; - case PHPExcel_Cell_DataType::TYPE_FORMULA: - $this->_value = (string)$pValue; - break; - case PHPExcel_Cell_DataType::TYPE_BOOL: - $this->_value = (bool)$pValue; - break; - case PHPExcel_Cell_DataType::TYPE_ERROR: - $this->_value = PHPExcel_Cell_DataType::checkErrorCode($pValue); - break; - default: - throw new PHPExcel_Exception('Invalid datatype: ' . $pDataType); - break; - } - - // set the datatype - $this->_dataType = $pDataType; - - return $this->notifyCacheController(); - } - - /** - * Get calculated cell value - * - * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling - * - * @param boolean $resetLog Whether the calculation engine logger should be reset or not - * @return mixed - * @throws PHPExcel_Exception - */ - public function getCalculatedValue($resetLog = TRUE) - { + } + return $this; + } + + /** + * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder) + * + * @param mixed $pValue Value + * @param string $pDataType Explicit data type + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) + { + // set the value according to data type + switch ($pDataType) { + case PHPExcel_Cell_DataType::TYPE_NULL: + $this->_value = $pValue; + break; + case PHPExcel_Cell_DataType::TYPE_STRING2: + $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + case PHPExcel_Cell_DataType::TYPE_STRING: + case PHPExcel_Cell_DataType::TYPE_INLINE: + $this->_value = PHPExcel_Cell_DataType::checkString($pValue); + break; + case PHPExcel_Cell_DataType::TYPE_NUMERIC: + $this->_value = (float)$pValue; + break; + case PHPExcel_Cell_DataType::TYPE_FORMULA: + $this->_value = (string)$pValue; + break; + case PHPExcel_Cell_DataType::TYPE_BOOL: + $this->_value = (bool)$pValue; + break; + case PHPExcel_Cell_DataType::TYPE_ERROR: + $this->_value = PHPExcel_Cell_DataType::checkErrorCode($pValue); + break; + default: + throw new PHPExcel_Exception('Invalid datatype: ' . $pDataType); + break; + } + + // set the datatype + $this->_dataType = $pDataType; + + return $this->notifyCacheController(); + } + + /** + * Get calculated cell value + * + * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling + * + * @param boolean $resetLog Whether the calculation engine logger should be reset or not + * @return mixed + * @throws PHPExcel_Exception + */ + public function getCalculatedValue($resetLog = TRUE) + { //echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().PHP_EOL; - if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { - try { + if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { + try { //echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value'.PHP_EOL; - $result = PHPExcel_Calculation::getInstance( - $this->getWorksheet()->getParent() - )->calculateCellValue($this,$resetLog); + $result = PHPExcel_Calculation::getInstance( + $this->getWorksheet()->getParent() + )->calculateCellValue($this,$resetLog); //echo $this->getCoordinate().' calculation result is '.$result.PHP_EOL; - // We don't yet handle array returns - if (is_array($result)) { - while (is_array($result)) { - $result = array_pop($result); - } - } - } catch ( PHPExcel_Exception $ex ) { - if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) { + // We don't yet handle array returns + if (is_array($result)) { + while (is_array($result)) { + $result = array_pop($result); + } + } + } catch ( PHPExcel_Exception $ex ) { + if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) { //echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; - return $this->_calculatedValue; // Fallback for calculations referencing external files. - } + return $this->_calculatedValue; // Fallback for calculations referencing external files. + } //echo 'Calculation Exception: '.$ex->getMessage().PHP_EOL; - $result = '#N/A'; - throw new PHPExcel_Calculation_Exception( - $this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage() - ); - } + $result = '#N/A'; + throw new PHPExcel_Calculation_Exception( + $this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage() + ); + } - if ($result === '#Not Yet Implemented') { + if ($result === '#Not Yet Implemented') { //echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; - return $this->_calculatedValue; // Fallback if calculation engine does not support the formula. - } + return $this->_calculatedValue; // Fallback if calculation engine does not support the formula. + } //echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL; - return $result; - } elseif($this->_value instanceof PHPExcel_RichText) { -// echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->_value.'
'; - return $this->_value->getPlainText(); - } -// echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'
'; - return $this->_value; - } - - /** - * Set old calculated value (cached) - * - * @param mixed $pValue Value - * @return PHPExcel_Cell - */ - public function setCalculatedValue($pValue = NULL) - { - if ($pValue !== NULL) { - $this->_calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue; - } - - return $this->notifyCacheController(); - } - - /** - * Get old calculated value (cached) - * This returns the value last calculated by MS Excel or whichever spreadsheet program was used to - * create the original spreadsheet file. - * Note that this value is not guaranteed to refelect the actual calculated value because it is - * possible that auto-calculation was disabled in the original spreadsheet, and underlying data - * values used by the formula have changed since it was last calculated. - * - * @return mixed - */ - public function getOldCalculatedValue() - { - return $this->_calculatedValue; - } - - /** - * Get cell data type - * - * @return string - */ - public function getDataType() - { - return $this->_dataType; - } - - /** - * Set cell data type - * - * @param string $pDataType - * @return PHPExcel_Cell - */ - public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING) - { - if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) - $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; - - $this->_dataType = $pDataType; - - return $this->notifyCacheController(); - } + return $result; + } elseif($this->_value instanceof PHPExcel_RichText) { +// echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->_value.'
'; + return $this->_value->getPlainText(); + } +// echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'
'; + return $this->_value; + } + + /** + * Set old calculated value (cached) + * + * @param mixed $pValue Value + * @return PHPExcel_Cell + */ + public function setCalculatedValue($pValue = NULL) + { + if ($pValue !== NULL) { + $this->_calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue; + } + + return $this->notifyCacheController(); + } + + /** + * Get old calculated value (cached) + * This returns the value last calculated by MS Excel or whichever spreadsheet program was used to + * create the original spreadsheet file. + * Note that this value is not guaranteed to refelect the actual calculated value because it is + * possible that auto-calculation was disabled in the original spreadsheet, and underlying data + * values used by the formula have changed since it was last calculated. + * + * @return mixed + */ + public function getOldCalculatedValue() + { + return $this->_calculatedValue; + } + + /** + * Get cell data type + * + * @return string + */ + public function getDataType() + { + return $this->_dataType; + } + + /** + * Set cell data type + * + * @param string $pDataType + * @return PHPExcel_Cell + */ + public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING) + { + if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) + $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + + $this->_dataType = $pDataType; + + return $this->notifyCacheController(); + } /** * Identify if the cell contains a formula @@ -375,134 +367,134 @@ public function isFormula() return $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA; } - /** - * Does this cell contain Data validation rules? - * - * @return boolean - * @throws PHPExcel_Exception - */ - public function hasDataValidation() - { - if (!isset($this->_parent)) { - throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet'); - } - - return $this->getWorksheet()->dataValidationExists($this->getCoordinate()); - } - - /** - * Get Data validation rules - * - * @return PHPExcel_Cell_DataValidation - * @throws PHPExcel_Exception - */ - public function getDataValidation() - { - if (!isset($this->_parent)) { - throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet'); - } - - return $this->getWorksheet()->getDataValidation($this->getCoordinate()); - } - - /** - * Set Data validation rules - * - * @param PHPExcel_Cell_DataValidation $pDataValidation - * @return PHPExcel_Cell - * @throws PHPExcel_Exception - */ - public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = NULL) - { - if (!isset($this->_parent)) { - throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet'); - } - - $this->getWorksheet()->setDataValidation($this->getCoordinate(), $pDataValidation); - - return $this->notifyCacheController(); - } - - /** - * Does this cell contain a Hyperlink? - * - * @return boolean - * @throws PHPExcel_Exception - */ - public function hasHyperlink() - { - if (!isset($this->_parent)) { - throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); - } - - return $this->getWorksheet()->hyperlinkExists($this->getCoordinate()); - } - - /** - * Get Hyperlink - * - * @return PHPExcel_Cell_Hyperlink - * @throws PHPExcel_Exception - */ - public function getHyperlink() - { - if (!isset($this->_parent)) { - throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); - } - - return $this->getWorksheet()->getHyperlink($this->getCoordinate()); - } - - /** - * Set Hyperlink - * - * @param PHPExcel_Cell_Hyperlink $pHyperlink - * @return PHPExcel_Cell - * @throws PHPExcel_Exception - */ - public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL) - { - if (!isset($this->_parent)) { - throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); - } - - $this->getWorksheet()->setHyperlink($this->getCoordinate(), $pHyperlink); - - return $this->notifyCacheController(); - } - - /** - * Get parent worksheet - * - * @return PHPExcel_CachedObjectStorage_CacheBase - */ - public function getParent() { - return $this->_parent; - } - - /** - * Get parent worksheet - * - * @return PHPExcel_Worksheet - */ - public function getWorksheet() { - return $this->_parent->getParent(); - } - - /** - * Is this cell in a merge range - * - * @return boolean - */ + /** + * Does this cell contain Data validation rules? + * + * @return boolean + * @throws PHPExcel_Exception + */ + public function hasDataValidation() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet'); + } + + return $this->getWorksheet()->dataValidationExists($this->getCoordinate()); + } + + /** + * Get Data validation rules + * + * @return PHPExcel_Cell_DataValidation + * @throws PHPExcel_Exception + */ + public function getDataValidation() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet'); + } + + return $this->getWorksheet()->getDataValidation($this->getCoordinate()); + } + + /** + * Set Data validation rules + * + * @param PHPExcel_Cell_DataValidation $pDataValidation + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = NULL) + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet'); + } + + $this->getWorksheet()->setDataValidation($this->getCoordinate(), $pDataValidation); + + return $this->notifyCacheController(); + } + + /** + * Does this cell contain a Hyperlink? + * + * @return boolean + * @throws PHPExcel_Exception + */ + public function hasHyperlink() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); + } + + return $this->getWorksheet()->hyperlinkExists($this->getCoordinate()); + } + + /** + * Get Hyperlink + * + * @return PHPExcel_Cell_Hyperlink + * @throws PHPExcel_Exception + */ + public function getHyperlink() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); + } + + return $this->getWorksheet()->getHyperlink($this->getCoordinate()); + } + + /** + * Set Hyperlink + * + * @param PHPExcel_Cell_Hyperlink $pHyperlink + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL) + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); + } + + $this->getWorksheet()->setHyperlink($this->getCoordinate(), $pHyperlink); + + return $this->notifyCacheController(); + } + + /** + * Get parent worksheet + * + * @return PHPExcel_CachedObjectStorage_CacheBase + */ + public function getParent() { + return $this->_parent; + } + + /** + * Get parent worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() { + return $this->_parent->getParent(); + } + + /** + * Is this cell in a merge range + * + * @return boolean + */ public function isInMergeRange() { return (boolean) $this->getMergeRange(); } - /** - * Is this cell the master (top left cell) in a merge range (that holds the actual data value) - * - * @return boolean - */ + /** + * Is this cell the master (top left cell) in a merge range (that holds the actual data value) + * + * @return boolean + */ public function isMergeRangeValueCell() { if ($mergeRange = $this->getMergeRange()) { $mergeRange = PHPExcel_Cell::splitRange($mergeRange); @@ -514,11 +506,11 @@ public function isMergeRangeValueCell() { return false; } - /** - * If this cell is in a merge range, then return the range - * - * @return string - */ + /** + * If this cell is in a merge range, then return the range + * + * @return string + */ public function getMergeRange() { foreach($this->getWorksheet()->getMergeCells() as $mergeRange) { if ($this->isInRange($mergeRange)) { @@ -528,495 +520,495 @@ public function getMergeRange() { return false; } - /** - * Get cell style - * - * @return PHPExcel_Style - */ - public function getStyle() - { - return $this->getWorksheet()->getStyle($this->getCoordinate()); - } - - /** - * Re-bind parent - * - * @param PHPExcel_Worksheet $parent - * @return PHPExcel_Cell - */ - public function rebindParent(PHPExcel_Worksheet $parent) { - $this->_parent = $parent->getCellCacheController(); - - return $this->notifyCacheController(); - } - - /** - * Is cell in a specific range? - * - * @param string $pRange Cell range (e.g. A1:A1) - * @return boolean - */ - public function isInRange($pRange = 'A1:A1') - { - list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); - - // Translate properties - $myColumn = self::columnIndexFromString($this->getColumn()); - $myRow = $this->getRow(); - - // Verify if cell is in range - return (($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) && - ($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow) - ); - } - - /** - * Coordinate from string - * - * @param string $pCoordinateString - * @return array Array containing column and row (indexes 0 and 1) - * @throws PHPExcel_Exception - */ - public static function coordinateFromString($pCoordinateString = 'A1') - { - if (preg_match("/^([$]?[A-Z]{1,3})([$]?\d{1,7})$/", $pCoordinateString, $matches)) { - return array($matches[1],$matches[2]); - } elseif ((strpos($pCoordinateString,':') !== FALSE) || (strpos($pCoordinateString,',') !== FALSE)) { - throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); - } elseif ($pCoordinateString == '') { - throw new PHPExcel_Exception('Cell coordinate can not be zero-length string'); - } - - throw new PHPExcel_Exception('Invalid cell coordinate '.$pCoordinateString); - } - - /** - * Make string row, column or cell coordinate absolute - * - * @param string $pCoordinateString e.g. 'A' or '1' or 'A1' - * Note that this value can be a row or column reference as well as a cell reference - * @return string Absolute coordinate e.g. '$A' or '$1' or '$A$1' - * @throws PHPExcel_Exception - */ - public static function absoluteReference($pCoordinateString = 'A1') - { - if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { - // Split out any worksheet name from the reference - $worksheet = ''; - $cellAddress = explode('!',$pCoordinateString); - if (count($cellAddress) > 1) { - list($worksheet,$pCoordinateString) = $cellAddress; - } - if ($worksheet > '') $worksheet .= '!'; - - // Create absolute coordinate - if (ctype_digit($pCoordinateString)) { - return $worksheet . '$' . $pCoordinateString; - } elseif (ctype_alpha($pCoordinateString)) { - return $worksheet . '$' . strtoupper($pCoordinateString); - } - return $worksheet . self::absoluteCoordinate($pCoordinateString); - } - - throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); - } - - /** - * Make string coordinate absolute - * - * @param string $pCoordinateString e.g. 'A1' - * @return string Absolute coordinate e.g. '$A$1' - * @throws PHPExcel_Exception - */ - public static function absoluteCoordinate($pCoordinateString = 'A1') - { - if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { - // Split out any worksheet name from the coordinate - $worksheet = ''; - $cellAddress = explode('!',$pCoordinateString); - if (count($cellAddress) > 1) { - list($worksheet,$pCoordinateString) = $cellAddress; - } - if ($worksheet > '') $worksheet .= '!'; - - // Create absolute coordinate - list($column, $row) = self::coordinateFromString($pCoordinateString); - $column = ltrim($column,'$'); - $row = ltrim($row,'$'); - return $worksheet . '$' . $column . '$' . $row; - } - - throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); - } - - /** - * Split range into coordinate strings - * - * @param string $pRange e.g. 'B4:D9' or 'B4:D9,H2:O11' or 'B4' - * @return array Array containg one or more arrays containing one or two coordinate strings - * e.g. array('B4','D9') or array(array('B4','D9'),array('H2','O11')) - * or array('B4') - */ - public static function splitRange($pRange = 'A1:A1') - { - // Ensure $pRange is a valid range - if(empty($pRange)) { - $pRange = self::DEFAULT_RANGE; - } - - $exploded = explode(',', $pRange); - $counter = count($exploded); - for ($i = 0; $i < $counter; ++$i) { - $exploded[$i] = explode(':', $exploded[$i]); - } - return $exploded; - } - - /** - * Build range from coordinate strings - * - * @param array $pRange Array containg one or more arrays containing one or two coordinate strings - * @return string String representation of $pRange - * @throws PHPExcel_Exception - */ - public static function buildRange($pRange) - { - // Verify range - if (!is_array($pRange) || empty($pRange) || !is_array($pRange[0])) { - throw new PHPExcel_Exception('Range does not contain any information'); - } - - // Build range - $imploded = array(); - $counter = count($pRange); - for ($i = 0; $i < $counter; ++$i) { - $pRange[$i] = implode(':', $pRange[$i]); - } - $imploded = implode(',', $pRange); - - return $imploded; - } - - /** - * Calculate range boundaries - * - * @param string $pRange Cell range (e.g. A1:A1) - * @return array Range coordinates array(Start Cell, End Cell) - * where Start Cell and End Cell are arrays (Column Number, Row Number) - */ - public static function rangeBoundaries($pRange = 'A1:A1') - { - // Ensure $pRange is a valid range - if(empty($pRange)) { - $pRange = self::DEFAULT_RANGE; - } - - // Uppercase coordinate - $pRange = strtoupper($pRange); - - // Extract range - if (strpos($pRange, ':') === FALSE) { - $rangeA = $rangeB = $pRange; - } else { - list($rangeA, $rangeB) = explode(':', $pRange); - } - - // Calculate range outer borders - $rangeStart = self::coordinateFromString($rangeA); - $rangeEnd = self::coordinateFromString($rangeB); - - // Translate column into index - $rangeStart[0] = self::columnIndexFromString($rangeStart[0]); - $rangeEnd[0] = self::columnIndexFromString($rangeEnd[0]); - - return array($rangeStart, $rangeEnd); - } - - /** - * Calculate range dimension - * - * @param string $pRange Cell range (e.g. A1:A1) - * @return array Range dimension (width, height) - */ - public static function rangeDimension($pRange = 'A1:A1') - { - // Calculate range outer borders - list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); - - return array( ($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1) ); - } - - /** - * Calculate range boundaries - * - * @param string $pRange Cell range (e.g. A1:A1) - * @return array Range coordinates array(Start Cell, End Cell) - * where Start Cell and End Cell are arrays (Column ID, Row Number) - */ - public static function getRangeBoundaries($pRange = 'A1:A1') - { - // Ensure $pRange is a valid range - if(empty($pRange)) { - $pRange = self::DEFAULT_RANGE; - } - - // Uppercase coordinate - $pRange = strtoupper($pRange); - - // Extract range - if (strpos($pRange, ':') === FALSE) { - $rangeA = $rangeB = $pRange; - } else { - list($rangeA, $rangeB) = explode(':', $pRange); - } - - return array( self::coordinateFromString($rangeA), self::coordinateFromString($rangeB)); - } - - /** - * Column index from string - * - * @param string $pString - * @return int Column index (base 1 !!!) - */ - public static function columnIndexFromString($pString = 'A') - { - // Using a lookup cache adds a slight memory overhead, but boosts speed - // caching using a static within the method is faster than a class static, - // though it's additional memory overhead - static $_indexCache = array(); - - if (isset($_indexCache[$pString])) - return $_indexCache[$pString]; - - // It's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array rather than use ord() - // and make it case insensitive to get rid of the strtoupper() as well. Because it's a static, there's no significant - // memory overhead either - static $_columnLookup = array( - 'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8, 'I' => 9, 'J' => 10, 'K' => 11, 'L' => 12, 'M' => 13, - 'N' => 14, 'O' => 15, 'P' => 16, 'Q' => 17, 'R' => 18, 'S' => 19, 'T' => 20, 'U' => 21, 'V' => 22, 'W' => 23, 'X' => 24, 'Y' => 25, 'Z' => 26, - 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6, 'g' => 7, 'h' => 8, 'i' => 9, 'j' => 10, 'k' => 11, 'l' => 12, 'm' => 13, - 'n' => 14, 'o' => 15, 'p' => 16, 'q' => 17, 'r' => 18, 's' => 19, 't' => 20, 'u' => 21, 'v' => 22, 'w' => 23, 'x' => 24, 'y' => 25, 'z' => 26 - ); - - // We also use the language construct isset() rather than the more costly strlen() function to match the length of $pString - // for improved performance - if (isset($pString{0})) { - if (!isset($pString{1})) { - $_indexCache[$pString] = $_columnLookup[$pString]; - return $_indexCache[$pString]; - } elseif(!isset($pString{2})) { - $_indexCache[$pString] = $_columnLookup[$pString{0}] * 26 + $_columnLookup[$pString{1}]; - return $_indexCache[$pString]; - } elseif(!isset($pString{3})) { - $_indexCache[$pString] = $_columnLookup[$pString{0}] * 676 + $_columnLookup[$pString{1}] * 26 + $_columnLookup[$pString{2}]; - return $_indexCache[$pString]; - } - } - throw new PHPExcel_Exception("Column string index can not be " . ((isset($pString{0})) ? "longer than 3 characters" : "empty")); - } - - /** - * String from columnindex - * - * @param int $pColumnIndex Column index (base 0 !!!) - * @return string - */ - public static function stringFromColumnIndex($pColumnIndex = 0) - { - // Using a lookup cache adds a slight memory overhead, but boosts speed - // caching using a static within the method is faster than a class static, - // though it's additional memory overhead - static $_indexCache = array(); - - if (!isset($_indexCache[$pColumnIndex])) { - // Determine column string - if ($pColumnIndex < 26) { - $_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex); - } elseif ($pColumnIndex < 702) { - $_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)) . - chr(65 + $pColumnIndex % 26); - } else { - $_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)) . - chr(65 + ((($pColumnIndex - 26) % 676) / 26)) . - chr(65 + $pColumnIndex % 26); - } - } - return $_indexCache[$pColumnIndex]; - } - - /** - * Extract all cell references in range - * - * @param string $pRange Range (e.g. A1 or A1:C10 or A1:E10 A20:E25) - * @return array Array containing single cell references - */ - public static function extractAllCellReferencesInRange($pRange = 'A1') { - // Returnvalue - $returnValue = array(); - - // Explode spaces - $cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange))); - foreach ($cellBlocks as $cellBlock) { - // Single cell? - if (strpos($cellBlock,':') === FALSE && strpos($cellBlock,',') === FALSE) { - $returnValue[] = $cellBlock; - continue; - } - - // Range... - $ranges = self::splitRange($cellBlock); - foreach($ranges as $range) { - // Single cell? - if (!isset($range[1])) { - $returnValue[] = $range[0]; - continue; - } - - // Range... - list($rangeStart, $rangeEnd) = $range; - sscanf($rangeStart,'%[A-Z]%d', $startCol, $startRow); - sscanf($rangeEnd,'%[A-Z]%d', $endCol, $endRow); - $endCol++; - - // Current data - $currentCol = $startCol; - $currentRow = $startRow; - - // Loop cells - while ($currentCol != $endCol) { - while ($currentRow <= $endRow) { - $returnValue[] = $currentCol.$currentRow; - ++$currentRow; - } - ++$currentCol; - $currentRow = $startRow; - } - } - } - - // Sort the result by column and row - $sortKeys = array(); - foreach (array_unique($returnValue) as $coord) { - sscanf($coord,'%[A-Z]%d', $column, $row); - $sortKeys[sprintf('%3s%09d',$column,$row)] = $coord; - } - ksort($sortKeys); - - // Return value - return array_values($sortKeys); - } - - /** - * Compare 2 cells - * - * @param PHPExcel_Cell $a Cell a - * @param PHPExcel_Cell $b Cell b - * @return int Result of comparison (always -1 or 1, never zero!) - */ - public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b) - { - if ($a->getRow() < $b->getRow()) { - return -1; - } elseif ($a->getRow() > $b->getRow()) { - return 1; - } elseif (self::columnIndexFromString($a->getColumn()) < self::columnIndexFromString($b->getColumn())) { - return -1; - } else { - return 1; - } - } - - /** - * Get value binder to use - * - * @return PHPExcel_Cell_IValueBinder - */ - public static function getValueBinder() { - if (self::$_valueBinder === NULL) { - self::$_valueBinder = new PHPExcel_Cell_DefaultValueBinder(); - } - - return self::$_valueBinder; - } - - /** - * Set value binder to use - * - * @param PHPExcel_Cell_IValueBinder $binder - * @throws PHPExcel_Exception - */ - public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) { - if ($binder === NULL) { - throw new PHPExcel_Exception("A PHPExcel_Cell_IValueBinder is required for PHPExcel to function correctly."); - } - - self::$_valueBinder = $binder; - } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if ((is_object($value)) && ($key != '_parent')) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } - - /** - * Get index to cellXf - * - * @return int - */ - public function getXfIndex() - { - return $this->_xfIndex; - } - - /** - * Set index to cellXf - * - * @param int $pValue - * @return PHPExcel_Cell - */ - public function setXfIndex($pValue = 0) - { - $this->_xfIndex = $pValue; - - return $this->notifyCacheController(); - } - - /** - * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling - */ - public function setFormulaAttributes($pAttributes) - { - $this->_formulaAttributes = $pAttributes; - return $this; - } - - /** - * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling - */ - public function getFormulaAttributes() - { - return $this->_formulaAttributes; - } + /** + * Get cell style + * + * @return PHPExcel_Style + */ + public function getStyle() + { + return $this->getWorksheet()->getStyle($this->getCoordinate()); + } + + /** + * Re-bind parent + * + * @param PHPExcel_Worksheet $parent + * @return PHPExcel_Cell + */ + public function rebindParent(PHPExcel_Worksheet $parent) { + $this->_parent = $parent->getCellCacheController(); + + return $this->notifyCacheController(); + } + + /** + * Is cell in a specific range? + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return boolean + */ + public function isInRange($pRange = 'A1:A1') + { + list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); + + // Translate properties + $myColumn = self::columnIndexFromString($this->getColumn()); + $myRow = $this->getRow(); + + // Verify if cell is in range + return (($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) && + ($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow) + ); + } + + /** + * Coordinate from string + * + * @param string $pCoordinateString + * @return array Array containing column and row (indexes 0 and 1) + * @throws PHPExcel_Exception + */ + public static function coordinateFromString($pCoordinateString = 'A1') + { + if (preg_match("/^([$]?[A-Z]{1,3})([$]?\d{1,7})$/", $pCoordinateString, $matches)) { + return array($matches[1],$matches[2]); + } elseif ((strpos($pCoordinateString,':') !== FALSE) || (strpos($pCoordinateString,',') !== FALSE)) { + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); + } elseif ($pCoordinateString == '') { + throw new PHPExcel_Exception('Cell coordinate can not be zero-length string'); + } + + throw new PHPExcel_Exception('Invalid cell coordinate '.$pCoordinateString); + } + + /** + * Make string row, column or cell coordinate absolute + * + * @param string $pCoordinateString e.g. 'A' or '1' or 'A1' + * Note that this value can be a row or column reference as well as a cell reference + * @return string Absolute coordinate e.g. '$A' or '$1' or '$A$1' + * @throws PHPExcel_Exception + */ + public static function absoluteReference($pCoordinateString = 'A1') + { + if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { + // Split out any worksheet name from the reference + $worksheet = ''; + $cellAddress = explode('!',$pCoordinateString); + if (count($cellAddress) > 1) { + list($worksheet,$pCoordinateString) = $cellAddress; + } + if ($worksheet > '') $worksheet .= '!'; + + // Create absolute coordinate + if (ctype_digit($pCoordinateString)) { + return $worksheet . '$' . $pCoordinateString; + } elseif (ctype_alpha($pCoordinateString)) { + return $worksheet . '$' . strtoupper($pCoordinateString); + } + return $worksheet . self::absoluteCoordinate($pCoordinateString); + } + + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); + } + + /** + * Make string coordinate absolute + * + * @param string $pCoordinateString e.g. 'A1' + * @return string Absolute coordinate e.g. '$A$1' + * @throws PHPExcel_Exception + */ + public static function absoluteCoordinate($pCoordinateString = 'A1') + { + if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { + // Split out any worksheet name from the coordinate + $worksheet = ''; + $cellAddress = explode('!',$pCoordinateString); + if (count($cellAddress) > 1) { + list($worksheet,$pCoordinateString) = $cellAddress; + } + if ($worksheet > '') $worksheet .= '!'; + + // Create absolute coordinate + list($column, $row) = self::coordinateFromString($pCoordinateString); + $column = ltrim($column,'$'); + $row = ltrim($row,'$'); + return $worksheet . '$' . $column . '$' . $row; + } + + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); + } + + /** + * Split range into coordinate strings + * + * @param string $pRange e.g. 'B4:D9' or 'B4:D9,H2:O11' or 'B4' + * @return array Array containg one or more arrays containing one or two coordinate strings + * e.g. array('B4','D9') or array(array('B4','D9'),array('H2','O11')) + * or array('B4') + */ + public static function splitRange($pRange = 'A1:A1') + { + // Ensure $pRange is a valid range + if(empty($pRange)) { + $pRange = self::DEFAULT_RANGE; + } + + $exploded = explode(',', $pRange); + $counter = count($exploded); + for ($i = 0; $i < $counter; ++$i) { + $exploded[$i] = explode(':', $exploded[$i]); + } + return $exploded; + } + + /** + * Build range from coordinate strings + * + * @param array $pRange Array containg one or more arrays containing one or two coordinate strings + * @return string String representation of $pRange + * @throws PHPExcel_Exception + */ + public static function buildRange($pRange) + { + // Verify range + if (!is_array($pRange) || empty($pRange) || !is_array($pRange[0])) { + throw new PHPExcel_Exception('Range does not contain any information'); + } + + // Build range + $imploded = array(); + $counter = count($pRange); + for ($i = 0; $i < $counter; ++$i) { + $pRange[$i] = implode(':', $pRange[$i]); + } + $imploded = implode(',', $pRange); + + return $imploded; + } + + /** + * Calculate range boundaries + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range coordinates array(Start Cell, End Cell) + * where Start Cell and End Cell are arrays (Column Number, Row Number) + */ + public static function rangeBoundaries($pRange = 'A1:A1') + { + // Ensure $pRange is a valid range + if(empty($pRange)) { + $pRange = self::DEFAULT_RANGE; + } + + // Uppercase coordinate + $pRange = strtoupper($pRange); + + // Extract range + if (strpos($pRange, ':') === FALSE) { + $rangeA = $rangeB = $pRange; + } else { + list($rangeA, $rangeB) = explode(':', $pRange); + } + + // Calculate range outer borders + $rangeStart = self::coordinateFromString($rangeA); + $rangeEnd = self::coordinateFromString($rangeB); + + // Translate column into index + $rangeStart[0] = self::columnIndexFromString($rangeStart[0]); + $rangeEnd[0] = self::columnIndexFromString($rangeEnd[0]); + + return array($rangeStart, $rangeEnd); + } + + /** + * Calculate range dimension + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range dimension (width, height) + */ + public static function rangeDimension($pRange = 'A1:A1') + { + // Calculate range outer borders + list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); + + return array( ($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1) ); + } + + /** + * Calculate range boundaries + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range coordinates array(Start Cell, End Cell) + * where Start Cell and End Cell are arrays (Column ID, Row Number) + */ + public static function getRangeBoundaries($pRange = 'A1:A1') + { + // Ensure $pRange is a valid range + if(empty($pRange)) { + $pRange = self::DEFAULT_RANGE; + } + + // Uppercase coordinate + $pRange = strtoupper($pRange); + + // Extract range + if (strpos($pRange, ':') === FALSE) { + $rangeA = $rangeB = $pRange; + } else { + list($rangeA, $rangeB) = explode(':', $pRange); + } + + return array( self::coordinateFromString($rangeA), self::coordinateFromString($rangeB)); + } + + /** + * Column index from string + * + * @param string $pString + * @return int Column index (base 1 !!!) + */ + public static function columnIndexFromString($pString = 'A') + { + // Using a lookup cache adds a slight memory overhead, but boosts speed + // caching using a static within the method is faster than a class static, + // though it's additional memory overhead + static $_indexCache = array(); + + if (isset($_indexCache[$pString])) + return $_indexCache[$pString]; + + // It's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array rather than use ord() + // and make it case insensitive to get rid of the strtoupper() as well. Because it's a static, there's no significant + // memory overhead either + static $_columnLookup = array( + 'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8, 'I' => 9, 'J' => 10, 'K' => 11, 'L' => 12, 'M' => 13, + 'N' => 14, 'O' => 15, 'P' => 16, 'Q' => 17, 'R' => 18, 'S' => 19, 'T' => 20, 'U' => 21, 'V' => 22, 'W' => 23, 'X' => 24, 'Y' => 25, 'Z' => 26, + 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6, 'g' => 7, 'h' => 8, 'i' => 9, 'j' => 10, 'k' => 11, 'l' => 12, 'm' => 13, + 'n' => 14, 'o' => 15, 'p' => 16, 'q' => 17, 'r' => 18, 's' => 19, 't' => 20, 'u' => 21, 'v' => 22, 'w' => 23, 'x' => 24, 'y' => 25, 'z' => 26 + ); + + // We also use the language construct isset() rather than the more costly strlen() function to match the length of $pString + // for improved performance + if (isset($pString{0})) { + if (!isset($pString{1})) { + $_indexCache[$pString] = $_columnLookup[$pString]; + return $_indexCache[$pString]; + } elseif(!isset($pString{2})) { + $_indexCache[$pString] = $_columnLookup[$pString{0}] * 26 + $_columnLookup[$pString{1}]; + return $_indexCache[$pString]; + } elseif(!isset($pString{3})) { + $_indexCache[$pString] = $_columnLookup[$pString{0}] * 676 + $_columnLookup[$pString{1}] * 26 + $_columnLookup[$pString{2}]; + return $_indexCache[$pString]; + } + } + throw new PHPExcel_Exception("Column string index can not be " . ((isset($pString{0})) ? "longer than 3 characters" : "empty")); + } + + /** + * String from columnindex + * + * @param int $pColumnIndex Column index (base 0 !!!) + * @return string + */ + public static function stringFromColumnIndex($pColumnIndex = 0) + { + // Using a lookup cache adds a slight memory overhead, but boosts speed + // caching using a static within the method is faster than a class static, + // though it's additional memory overhead + static $_indexCache = array(); + + if (!isset($_indexCache[$pColumnIndex])) { + // Determine column string + if ($pColumnIndex < 26) { + $_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex); + } elseif ($pColumnIndex < 702) { + $_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)) . + chr(65 + $pColumnIndex % 26); + } else { + $_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)) . + chr(65 + ((($pColumnIndex - 26) % 676) / 26)) . + chr(65 + $pColumnIndex % 26); + } + } + return $_indexCache[$pColumnIndex]; + } + + /** + * Extract all cell references in range + * + * @param string $pRange Range (e.g. A1 or A1:C10 or A1:E10 A20:E25) + * @return array Array containing single cell references + */ + public static function extractAllCellReferencesInRange($pRange = 'A1') { + // Returnvalue + $returnValue = array(); + + // Explode spaces + $cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange))); + foreach ($cellBlocks as $cellBlock) { + // Single cell? + if (strpos($cellBlock,':') === FALSE && strpos($cellBlock,',') === FALSE) { + $returnValue[] = $cellBlock; + continue; + } + + // Range... + $ranges = self::splitRange($cellBlock); + foreach($ranges as $range) { + // Single cell? + if (!isset($range[1])) { + $returnValue[] = $range[0]; + continue; + } + + // Range... + list($rangeStart, $rangeEnd) = $range; + sscanf($rangeStart,'%[A-Z]%d', $startCol, $startRow); + sscanf($rangeEnd,'%[A-Z]%d', $endCol, $endRow); + $endCol++; + + // Current data + $currentCol = $startCol; + $currentRow = $startRow; + + // Loop cells + while ($currentCol != $endCol) { + while ($currentRow <= $endRow) { + $returnValue[] = $currentCol.$currentRow; + ++$currentRow; + } + ++$currentCol; + $currentRow = $startRow; + } + } + } + + // Sort the result by column and row + $sortKeys = array(); + foreach (array_unique($returnValue) as $coord) { + sscanf($coord,'%[A-Z]%d', $column, $row); + $sortKeys[sprintf('%3s%09d',$column,$row)] = $coord; + } + ksort($sortKeys); + + // Return value + return array_values($sortKeys); + } + + /** + * Compare 2 cells + * + * @param PHPExcel_Cell $a Cell a + * @param PHPExcel_Cell $b Cell b + * @return int Result of comparison (always -1 or 1, never zero!) + */ + public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b) + { + if ($a->getRow() < $b->getRow()) { + return -1; + } elseif ($a->getRow() > $b->getRow()) { + return 1; + } elseif (self::columnIndexFromString($a->getColumn()) < self::columnIndexFromString($b->getColumn())) { + return -1; + } else { + return 1; + } + } + + /** + * Get value binder to use + * + * @return PHPExcel_Cell_IValueBinder + */ + public static function getValueBinder() { + if (self::$_valueBinder === NULL) { + self::$_valueBinder = new PHPExcel_Cell_DefaultValueBinder(); + } + + return self::$_valueBinder; + } + + /** + * Set value binder to use + * + * @param PHPExcel_Cell_IValueBinder $binder + * @throws PHPExcel_Exception + */ + public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) { + if ($binder === NULL) { + throw new PHPExcel_Exception("A PHPExcel_Cell_IValueBinder is required for PHPExcel to function correctly."); + } + + self::$_valueBinder = $binder; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if ((is_object($value)) && ($key != '_parent')) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } + + /** + * Get index to cellXf + * + * @return int + */ + public function getXfIndex() + { + return $this->_xfIndex; + } + + /** + * Set index to cellXf + * + * @param int $pValue + * @return PHPExcel_Cell + */ + public function setXfIndex($pValue = 0) + { + $this->_xfIndex = $pValue; + + return $this->notifyCacheController(); + } + + /** + * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling + */ + public function setFormulaAttributes($pAttributes) + { + $this->_formulaAttributes = $pAttributes; + return $this; + } + + /** + * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling + */ + public function getFormulaAttributes() + { + return $this->_formulaAttributes; + } /** * Convert to string * * @return string */ - public function __toString() - { - return (string) $this->getValue(); - } + public function __toString() + { + return (string) $this->getValue(); + } } From 46dfaa9f8a4ea6240d24c447a5e7712d6c5a8340 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Mon, 11 May 2015 12:30:15 +0200 Subject: [PATCH 347/467] Travis CI : Support for PSR-2 test --- .travis.yml | 16 +++++++++++++--- composer.json | 5 ++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c35625b13..01dece576 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,11 +10,21 @@ php: - hhvm matrix: - allow_failures: - - php: hhvm + allow_failures: + - php: hhvm + +before_script: + ## Packages + - sudo apt-get -qq update > /dev/null + ## Composer + - composer self-update + - composer install --prefer-source --dev script: - - phpunit -c ./unitTests/ + ## PHP_CodeSniffer + - ./vendor/bin/phpcs Classes/ unitTests/ --standard=PSR2 -n --ignore=Classes/PHPExcel/Shared/PCLZip + ## PHPUnit + - phpunit -c ./unitTests/ notifications: email: false diff --git a/composer.json b/composer.json index ff18cb842..da7faa0eb 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ }, { "name": "Franck Lefevre", - "homepage": "http://blog.rootslabs.net/" + "homepage": "http://rootslabs.net/" }, { "name": "Erik Tilt" @@ -26,6 +26,9 @@ "ext-xml": "*", "ext-xmlwriter": "*" }, + "require-dev": { + "squizlabs/php_codesniffer": "1.*" + }, "recommend": { "ext-zip": "*", "ext-gd2": "*" From bb13357dcb58a1ce4d5c135629ce865715df35f3 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Mon, 11 May 2015 12:58:26 +0200 Subject: [PATCH 348/467] Travis CI : Support for PSR-2 test --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 01dece576..5c9631565 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: php php: - 5.2 - - 5.3.3 - 5.3 + - 5.3.3 - 5.4 - 5.5 - 5.6 @@ -17,8 +17,11 @@ before_script: ## Packages - sudo apt-get -qq update > /dev/null ## Composer + ##@todo Remove when support of 5.2 will be dropped + - phpenv global 5.3 - composer self-update - composer install --prefer-source --dev + - phpenv global "$TRAVIS_PHP_VERSION" script: ## PHP_CodeSniffer From c70e289dacc794ac37e11c4f5ee035b126aea8df Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 11 May 2015 22:38:52 +0100 Subject: [PATCH 349/467] More efforts to get codebase to conform with PSR-2 coding standards --- Classes/PHPExcel/Chart.php | 1114 +- Classes/PHPExcel/Comment.php | 20 +- Classes/PHPExcel/DocumentProperties.php | 280 +- Classes/PHPExcel/DocumentSecurity.php | 210 +- Classes/PHPExcel/HashTable.php | 356 +- Classes/PHPExcel/IComparable.php | 26 +- Classes/PHPExcel/IOFactory.php | 467 +- Classes/PHPExcel/NamedRange.php | 212 +- Classes/PHPExcel/Reader/Abstract.php | 416 +- Classes/PHPExcel/Reader/CSV.php | 690 +- Classes/PHPExcel/Reader/DefaultReadFilter.php | 34 +- Classes/PHPExcel/Reader/Excel2003XML.php | 1490 +- Classes/PHPExcel/Reader/Excel2007.php | 3840 ++--- Classes/PHPExcel/Reader/Excel5.php | 13966 ++++++++-------- Classes/PHPExcel/Reader/Exception.php | 38 +- Classes/PHPExcel/Reader/Gnumeric.php | 1660 +- Classes/PHPExcel/Reader/HTML.php | 124 +- Classes/PHPExcel/Reader/IReadFilter.php | 32 +- Classes/PHPExcel/Reader/IReader.php | 30 +- Classes/PHPExcel/Reader/OOCalc.php | 1306 +- Classes/PHPExcel/Reader/SYLK.php | 816 +- Classes/PHPExcel/ReferenceHelper.php | 1764 +- Classes/PHPExcel/Worksheet.php | 300 +- Classes/PHPExcel/Writer/Abstract.php | 207 +- Classes/PHPExcel/Writer/CSV.php | 563 +- Classes/PHPExcel/Writer/Excel2007.php | 814 +- Classes/PHPExcel/Writer/Excel2007/Chart.php | 30 +- .../PHPExcel/Writer/Excel2007/Comments.php | 462 +- .../Writer/Excel2007/ContentTypes.php | 444 +- .../PHPExcel/Writer/Excel2007/DocProps.php | 466 +- Classes/PHPExcel/Writer/Excel2007/Drawing.php | 1054 +- Classes/PHPExcel/Writer/Excel2007/Rels.php | 798 +- .../PHPExcel/Writer/Excel2007/RelsRibbon.php | 70 +- Classes/PHPExcel/Writer/Excel2007/RelsVBA.php | 60 +- .../PHPExcel/Writer/Excel2007/StringTable.php | 558 +- Classes/PHPExcel/Writer/Excel2007/Style.php | 1334 +- Classes/PHPExcel/Writer/Excel2007/Theme.php | 1352 +- .../PHPExcel/Writer/Excel2007/Workbook.php | 834 +- .../PHPExcel/Writer/Excel2007/Worksheet.php | 2372 +-- .../PHPExcel/Writer/Excel2007/WriterPart.php | 78 +- Classes/PHPExcel/Writer/Excel5.php | 1802 +- Classes/PHPExcel/Writer/Excel5/BIFFwriter.php | 366 +- Classes/PHPExcel/Writer/Excel5/Escher.php | 824 +- Classes/PHPExcel/Writer/Excel5/Font.php | 232 +- Classes/PHPExcel/Writer/Excel5/Parser.php | 3010 ++-- Classes/PHPExcel/Writer/Excel5/Workbook.php | 2756 +-- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 7218 ++++---- Classes/PHPExcel/Writer/Excel5/Xf.php | 946 +- Classes/PHPExcel/Writer/Exception.php | 50 +- Classes/PHPExcel/Writer/HTML.php | 2991 ++-- Classes/PHPExcel/Writer/IWriter.php | 14 +- Classes/PHPExcel/Writer/OpenDocument.php | 50 +- Classes/PHPExcel/Writer/OpenDocument/Meta.php | 79 +- .../PHPExcel/Writer/OpenDocument/MetaInf.php | 15 +- .../PHPExcel/Writer/OpenDocument/Mimetype.php | 15 +- .../PHPExcel/Writer/OpenDocument/Settings.php | 15 +- .../PHPExcel/Writer/OpenDocument/Styles.php | 15 +- .../Writer/OpenDocument/Thumbnails.php | 15 +- .../Writer/OpenDocument/WriterPart.php | 14 +- 59 files changed, 30513 insertions(+), 30601 deletions(-) diff --git a/Classes/PHPExcel/Chart.php b/Classes/PHPExcel/Chart.php index 04af7b968..c8d96529a 100644 --- a/Classes/PHPExcel/Chart.php +++ b/Classes/PHPExcel/Chart.php @@ -1,6 +1,7 @@ _name = $name; - $this->_title = $title; - $this->_legend = $legend; - $this->_xAxisLabel = $xAxisLabel; - $this->_yAxisLabel = $yAxisLabel; - $this->_plotArea = $plotArea; - $this->_plotVisibleOnly = $plotVisibleOnly; - $this->_displayBlanksAs = $displayBlanksAs; - $this->_xAxis = $xAxis; - $this->_yAxis = $yAxis; - $this->_majorGridlines = $majorGridlines; - $this->_minorGridlines = $minorGridlines; - } - - /** - * Get Name - * - * @return string - */ - public function getName() { - return $this->_name; - } - - /** - * Get Worksheet - * - * @return PHPExcel_Worksheet - */ - public function getWorksheet() { - return $this->_worksheet; - } - - /** - * Set Worksheet - * - * @param PHPExcel_Worksheet $pValue - * @throws PHPExcel_Chart_Exception - * @return PHPExcel_Chart - */ - public function setWorksheet(PHPExcel_Worksheet $pValue = null) { - $this->_worksheet = $pValue; - - return $this; - } - - /** - * Get Title - * - * @return PHPExcel_Chart_Title - */ - public function getTitle() { - return $this->_title; - } - - /** - * Set Title - * - * @param PHPExcel_Chart_Title $title - * @return PHPExcel_Chart - */ - public function setTitle(PHPExcel_Chart_Title $title) { - $this->_title = $title; - - return $this; - } - - /** - * Get Legend - * - * @return PHPExcel_Chart_Legend - */ - public function getLegend() { - return $this->_legend; - } - - /** - * Set Legend - * - * @param PHPExcel_Chart_Legend $legend - * @return PHPExcel_Chart - */ - public function setLegend(PHPExcel_Chart_Legend $legend) { - $this->_legend = $legend; - - return $this; - } - - /** - * Get X-Axis Label - * - * @return PHPExcel_Chart_Title - */ - public function getXAxisLabel() { - return $this->_xAxisLabel; - } - - /** - * Set X-Axis Label - * - * @param PHPExcel_Chart_Title $label - * @return PHPExcel_Chart - */ - public function setXAxisLabel(PHPExcel_Chart_Title $label) { - $this->_xAxisLabel = $label; - - return $this; - } - - /** - * Get Y-Axis Label - * - * @return PHPExcel_Chart_Title - */ - public function getYAxisLabel() { - return $this->_yAxisLabel; - } - - /** - * Set Y-Axis Label - * - * @param PHPExcel_Chart_Title $label - * @return PHPExcel_Chart - */ - public function setYAxisLabel(PHPExcel_Chart_Title $label) { - $this->_yAxisLabel = $label; - - return $this; - } - - /** - * Get Plot Area - * - * @return PHPExcel_Chart_PlotArea - */ - public function getPlotArea() { - return $this->_plotArea; - } - - /** - * Get Plot Visible Only - * - * @return boolean - */ - public function getPlotVisibleOnly() { - return $this->_plotVisibleOnly; - } - - /** - * Set Plot Visible Only - * - * @param boolean $plotVisibleOnly - * @return PHPExcel_Chart - */ - public function setPlotVisibleOnly($plotVisibleOnly = true) { - $this->_plotVisibleOnly = $plotVisibleOnly; - - return $this; - } - - /** - * Get Display Blanks as - * - * @return string - */ - public function getDisplayBlanksAs() { - return $this->_displayBlanksAs; - } - - /** - * Set Display Blanks as - * - * @param string $displayBlanksAs - * @return PHPExcel_Chart - */ - public function setDisplayBlanksAs($displayBlanksAs = '0') { - $this->_displayBlanksAs = $displayBlanksAs; - } + /** + * Top-Left Cell Position + * + * @var string + */ + private $_topLeftCellRef = 'A1'; + + + /** + * Top-Left X-Offset + * + * @var integer + */ + private $_topLeftXOffset = 0; + + + /** + * Top-Left Y-Offset + * + * @var integer + */ + private $_topLeftYOffset = 0; + + + /** + * Bottom-Right Cell Position + * + * @var string + */ + private $_bottomRightCellRef = 'A1'; + + + /** + * Bottom-Right X-Offset + * + * @var integer + */ + private $_bottomRightXOffset = 10; + + + /** + * Bottom-Right Y-Offset + * + * @var integer + */ + private $_bottomRightYOffset = 10; + + + /** + * Create a new PHPExcel_Chart + */ + public function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_Chart_Legend $legend = null, PHPExcel_Chart_PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = '0', PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, PHPExcel_Chart_Axis $xAxis = null, PHPExcel_Chart_Axis $yAxis = null, PHPExcel_Chart_GridLines $majorGridlines = null, PHPExcel_Chart_GridLines $minorGridlines = null) + { + $this->_name = $name; + $this->_title = $title; + $this->_legend = $legend; + $this->_xAxisLabel = $xAxisLabel; + $this->_yAxisLabel = $yAxisLabel; + $this->_plotArea = $plotArea; + $this->_plotVisibleOnly = $plotVisibleOnly; + $this->_displayBlanksAs = $displayBlanksAs; + $this->_xAxis = $xAxis; + $this->_yAxis = $yAxis; + $this->_majorGridlines = $majorGridlines; + $this->_minorGridlines = $minorGridlines; + } + + /** + * Get Name + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Get Worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() + { + return $this->_worksheet; + } + + /** + * Set Worksheet + * + * @param PHPExcel_Worksheet $pValue + * @throws PHPExcel_Chart_Exception + * @return PHPExcel_Chart + */ + public function setWorksheet(PHPExcel_Worksheet $pValue = null) + { + $this->_worksheet = $pValue; + + return $this; + } + + /** + * Get Title + * + * @return PHPExcel_Chart_Title + */ + public function getTitle() + { + return $this->_title; + } + + /** + * Set Title + * + * @param PHPExcel_Chart_Title $title + * @return PHPExcel_Chart + */ + public function setTitle(PHPExcel_Chart_Title $title) + { + $this->_title = $title; + + return $this; + } + + /** + * Get Legend + * + * @return PHPExcel_Chart_Legend + */ + public function getLegend() + { + return $this->_legend; + } + + /** + * Set Legend + * + * @param PHPExcel_Chart_Legend $legend + * @return PHPExcel_Chart + */ + public function setLegend(PHPExcel_Chart_Legend $legend) + { + $this->_legend = $legend; + + return $this; + } + + /** + * Get X-Axis Label + * + * @return PHPExcel_Chart_Title + */ + public function getXAxisLabel() + { + return $this->_xAxisLabel; + } + + /** + * Set X-Axis Label + * + * @param PHPExcel_Chart_Title $label + * @return PHPExcel_Chart + */ + public function setXAxisLabel(PHPExcel_Chart_Title $label) + { + $this->_xAxisLabel = $label; + + return $this; + } + + /** + * Get Y-Axis Label + * + * @return PHPExcel_Chart_Title + */ + public function getYAxisLabel() + { + return $this->_yAxisLabel; + } + + /** + * Set Y-Axis Label + * + * @param PHPExcel_Chart_Title $label + * @return PHPExcel_Chart + */ + public function setYAxisLabel(PHPExcel_Chart_Title $label) { + $this->_yAxisLabel = $label; + + return $this; + } + + /** + * Get Plot Area + * + * @return PHPExcel_Chart_PlotArea + */ + public function getPlotArea() + { + return $this->_plotArea; + } + + /** + * Get Plot Visible Only + * + * @return boolean + */ + public function getPlotVisibleOnly() + { + return $this->_plotVisibleOnly; + } + + /** + * Set Plot Visible Only + * + * @param boolean $plotVisibleOnly + * @return PHPExcel_Chart + */ + public function setPlotVisibleOnly($plotVisibleOnly = true) + { + $this->_plotVisibleOnly = $plotVisibleOnly; + + return $this; + } + + /** + * Get Display Blanks as + * + * @return string + */ + public function getDisplayBlanksAs() + { + return $this->_displayBlanksAs; + } + + /** + * Set Display Blanks as + * + * @param string $displayBlanksAs + * @return PHPExcel_Chart + */ + public function setDisplayBlanksAs($displayBlanksAs = '0') + { + $this->_displayBlanksAs = $displayBlanksAs; + } /** @@ -363,8 +370,9 @@ public function setDisplayBlanksAs($displayBlanksAs = '0') { * * @return PHPExcel_Chart_Axis */ - public function getChartAxisY() { - if($this->_yAxis !== NULL){ + public function getChartAxisY() + { + if ($this->_yAxis !== null) { return $this->_yAxis; } @@ -376,8 +384,9 @@ public function getChartAxisY() { * * @return PHPExcel_Chart_Axis */ - public function getChartAxisX() { - if($this->_xAxis !== NULL){ + public function getChartAxisX() + { + if ($this->_xAxis !== null) { return $this->_xAxis; } @@ -389,8 +398,9 @@ public function getChartAxisX() { * * @return PHPExcel_Chart_GridLines */ - public function getMajorGridlines() { - if($this->_majorGridlines !== NULL){ + public function getMajorGridlines() + { + if ($this->_majorGridlines !== null) { return $this->_majorGridlines; } @@ -402,8 +412,9 @@ public function getMajorGridlines() { * * @return PHPExcel_Chart_GridLines */ - public function getMinorGridlines() { - if($this->_minorGridlines !== NULL){ + public function getMinorGridlines() + { + if ($this->_minorGridlines !== null) { return $this->_minorGridlines; } @@ -411,225 +422,258 @@ public function getMinorGridlines() { } - /** - * Set the Top Left position for the chart - * - * @param string $cell - * @param integer $xOffset - * @param integer $yOffset - * @return PHPExcel_Chart - */ - public function setTopLeftPosition($cell, $xOffset=null, $yOffset=null) { - $this->_topLeftCellRef = $cell; - if (!is_null($xOffset)) - $this->setTopLeftXOffset($xOffset); - if (!is_null($yOffset)) - $this->setTopLeftYOffset($yOffset); - - return $this; - } - - /** - * Get the top left position of the chart - * - * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell - */ - public function getTopLeftPosition() { - return array( 'cell' => $this->_topLeftCellRef, - 'xOffset' => $this->_topLeftXOffset, - 'yOffset' => $this->_topLeftYOffset - ); - } - - /** - * Get the cell address where the top left of the chart is fixed - * - * @return string - */ - public function getTopLeftCell() { - return $this->_topLeftCellRef; - } - - /** - * Set the Top Left cell position for the chart - * - * @param string $cell - * @return PHPExcel_Chart - */ - public function setTopLeftCell($cell) { - $this->_topLeftCellRef = $cell; - - return $this; - } - - /** - * Set the offset position within the Top Left cell for the chart - * - * @param integer $xOffset - * @param integer $yOffset - * @return PHPExcel_Chart - */ - public function setTopLeftOffset($xOffset=null,$yOffset=null) { - if (!is_null($xOffset)) - $this->setTopLeftXOffset($xOffset); - if (!is_null($yOffset)) - $this->setTopLeftYOffset($yOffset); - - return $this; - } - - /** - * Get the offset position within the Top Left cell for the chart - * - * @return integer[] - */ - public function getTopLeftOffset() { - return array( 'X' => $this->_topLeftXOffset, - 'Y' => $this->_topLeftYOffset - ); - } - - public function setTopLeftXOffset($xOffset) { - $this->_topLeftXOffset = $xOffset; - - return $this; - } - - public function getTopLeftXOffset() { - return $this->_topLeftXOffset; - } - - public function setTopLeftYOffset($yOffset) { - $this->_topLeftYOffset = $yOffset; - - return $this; - } - - public function getTopLeftYOffset() { - return $this->_topLeftYOffset; - } - - /** - * Set the Bottom Right position of the chart - * - * @param string $cell - * @param integer $xOffset - * @param integer $yOffset - * @return PHPExcel_Chart - */ - public function setBottomRightPosition($cell, $xOffset=null, $yOffset=null) { - $this->_bottomRightCellRef = $cell; - if (!is_null($xOffset)) - $this->setBottomRightXOffset($xOffset); - if (!is_null($yOffset)) - $this->setBottomRightYOffset($yOffset); - - return $this; - } - - /** - * Get the bottom right position of the chart - * - * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell - */ - public function getBottomRightPosition() { - return array( 'cell' => $this->_bottomRightCellRef, - 'xOffset' => $this->_bottomRightXOffset, - 'yOffset' => $this->_bottomRightYOffset - ); - } - - public function setBottomRightCell($cell) { - $this->_bottomRightCellRef = $cell; - - return $this; - } - - /** - * Get the cell address where the bottom right of the chart is fixed - * - * @return string - */ - public function getBottomRightCell() { - return $this->_bottomRightCellRef; - } - - /** - * Set the offset position within the Bottom Right cell for the chart - * - * @param integer $xOffset - * @param integer $yOffset - * @return PHPExcel_Chart - */ - public function setBottomRightOffset($xOffset=null,$yOffset=null) { - if (!is_null($xOffset)) - $this->setBottomRightXOffset($xOffset); - if (!is_null($yOffset)) - $this->setBottomRightYOffset($yOffset); - - return $this; - } - - /** - * Get the offset position within the Bottom Right cell for the chart - * - * @return integer[] - */ - public function getBottomRightOffset() { - return array( 'X' => $this->_bottomRightXOffset, - 'Y' => $this->_bottomRightYOffset - ); - } - - public function setBottomRightXOffset($xOffset) { - $this->_bottomRightXOffset = $xOffset; - - return $this; - } - - public function getBottomRightXOffset() { - return $this->_bottomRightXOffset; - } - - public function setBottomRightYOffset($yOffset) { - $this->_bottomRightYOffset = $yOffset; - - return $this; - } - - public function getBottomRightYOffset() { - return $this->_bottomRightYOffset; - } - - - public function refresh() { - if ($this->_worksheet !== NULL) { - $this->_plotArea->refresh($this->_worksheet); - } - } - - public function render($outputDestination = null) { - $libraryName = PHPExcel_Settings::getChartRendererName(); - if (is_null($libraryName)) { - return false; - } - // Ensure that data series values are up-to-date before we render - $this->refresh(); - - $libraryPath = PHPExcel_Settings::getChartRendererPath(); - $includePath = str_replace('\\','/',get_include_path()); - $rendererPath = str_replace('\\','/',$libraryPath); - if (strpos($rendererPath,$includePath) === false) { - set_include_path(get_include_path() . PATH_SEPARATOR . $libraryPath); - } - - $rendererName = 'PHPExcel_Chart_Renderer_'.$libraryName; - $renderer = new $rendererName($this); - - if ($outputDestination == 'php://output') { - $outputDestination = null; - } - return $renderer->render($outputDestination); - } + /** + * Set the Top Left position for the chart + * + * @param string $cell + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setTopLeftPosition($cell, $xOffset=null, $yOffset=null) + { + $this->_topLeftCellRef = $cell; + if (!is_null($xOffset)) { + $this->setTopLeftXOffset($xOffset); + } + if (!is_null($yOffset)) { + $this->setTopLeftYOffset($yOffset); + } + + return $this; + } + + /** + * Get the top left position of the chart + * + * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell + */ + public function getTopLeftPosition() + { + return array( + 'cell' => $this->_topLeftCellRef, + 'xOffset' => $this->_topLeftXOffset, + 'yOffset' => $this->_topLeftYOffset + ); + } + + /** + * Get the cell address where the top left of the chart is fixed + * + * @return string + */ + public function getTopLeftCell() + { + return $this->_topLeftCellRef; + } + + /** + * Set the Top Left cell position for the chart + * + * @param string $cell + * @return PHPExcel_Chart + */ + public function setTopLeftCell($cell) + { + $this->_topLeftCellRef = $cell; + + return $this; + } + + /** + * Set the offset position within the Top Left cell for the chart + * + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setTopLeftOffset($xOffset = null, $yOffset = null) + { + if (!is_null($xOffset)) { + $this->setTopLeftXOffset($xOffset); + } + if (!is_null($yOffset)) { + $this->setTopLeftYOffset($yOffset); + } + + return $this; + } + + /** + * Get the offset position within the Top Left cell for the chart + * + * @return integer[] + */ + public function getTopLeftOffset() + { + return array( + 'X' => $this->_topLeftXOffset, + 'Y' => $this->_topLeftYOffset + ); + } + + public function setTopLeftXOffset($xOffset) + { + $this->_topLeftXOffset = $xOffset; + + return $this; + } + + public function getTopLeftXOffset() + { + return $this->_topLeftXOffset; + } + + public function setTopLeftYOffset($yOffset) + { + $this->_topLeftYOffset = $yOffset; + + return $this; + } + + public function getTopLeftYOffset() + { + return $this->_topLeftYOffset; + } + + /** + * Set the Bottom Right position of the chart + * + * @param string $cell + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setBottomRightPosition($cell, $xOffset = null, $yOffset = null) + { + $this->_bottomRightCellRef = $cell; + if (!is_null($xOffset)) { + $this->setBottomRightXOffset($xOffset); + } + if (!is_null($yOffset)) { + $this->setBottomRightYOffset($yOffset); + } + + return $this; + } + + /** + * Get the bottom right position of the chart + * + * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell + */ + public function getBottomRightPosition() + { + return array( + 'cell' => $this->_bottomRightCellRef, + 'xOffset' => $this->_bottomRightXOffset, + 'yOffset' => $this->_bottomRightYOffset + ); + } + + public function setBottomRightCell($cell) + { + $this->_bottomRightCellRef = $cell; + return $this; + } + + /** + * Get the cell address where the bottom right of the chart is fixed + * + * @return string + */ + public function getBottomRightCell() + { + return $this->_bottomRightCellRef; + } + + /** + * Set the offset position within the Bottom Right cell for the chart + * + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setBottomRightOffset($xOffset = null, $yOffset = null) + { + if (!is_null($xOffset)) { + $this->setBottomRightXOffset($xOffset); + } + if (!is_null($yOffset)) { + $this->setBottomRightYOffset($yOffset); + } + + return $this; + } + + /** + * Get the offset position within the Bottom Right cell for the chart + * + * @return integer[] + */ + public function getBottomRightOffset() + { + return array( + 'X' => $this->_bottomRightXOffset, + 'Y' => $this->_bottomRightYOffset + ); + } + + public function setBottomRightXOffset($xOffset) + { + $this->_bottomRightXOffset = $xOffset; + + return $this; + } + + public function getBottomRightXOffset() + { + return $this->_bottomRightXOffset; + } + + public function setBottomRightYOffset($yOffset) + { + $this->_bottomRightYOffset = $yOffset; + + return $this; + } + + public function getBottomRightYOffset() + { + return $this->_bottomRightYOffset; + } + + + public function refresh() + { + if ($this->_worksheet !== null) { + $this->_plotArea->refresh($this->_worksheet); + } + } + + public function render($outputDestination = null) + { + $libraryName = PHPExcel_Settings::getChartRendererName(); + if (is_null($libraryName)) { + return false; + } + // Ensure that data series values are up-to-date before we render + $this->refresh(); + + $libraryPath = PHPExcel_Settings::getChartRendererPath(); + $includePath = str_replace('\\','/',get_include_path()); + $rendererPath = str_replace('\\','/',$libraryPath); + if (strpos($rendererPath,$includePath) === false) { + set_include_path(get_include_path() . PATH_SEPARATOR . $libraryPath); + } + + $rendererName = 'PHPExcel_Chart_Renderer_'.$libraryName; + $renderer = new $rendererName($this); + + if ($outputDestination == 'php://output') { + $outputDestination = null; + } + return $renderer->render($outputDestination); + } } diff --git a/Classes/PHPExcel/Comment.php b/Classes/PHPExcel/Comment.php index 4d5ef18f4..bdadfbf5f 100644 --- a/Classes/PHPExcel/Comment.php +++ b/Classes/PHPExcel/Comment.php @@ -1,6 +1,7 @@ _author = 'Author'; - $this->_text = new PHPExcel_RichText(); - $this->_fillColor = new PHPExcel_Style_Color('FFFFFFE1'); - $this->_alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + $this->_author = 'Author'; + $this->_text = new PHPExcel_RichText(); + $this->_fillColor = new PHPExcel_Style_Color('FFFFFFE1'); + $this->_alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; } /** diff --git a/Classes/PHPExcel/DocumentProperties.php b/Classes/PHPExcel/DocumentProperties.php index feaa15463..d872142cd 100644 --- a/Classes/PHPExcel/DocumentProperties.php +++ b/Classes/PHPExcel/DocumentProperties.php @@ -1,6 +1,7 @@ _creator; } @@ -154,7 +147,8 @@ public function getCreator() { * @param string $pValue * @return PHPExcel_DocumentProperties */ - public function setCreator($pValue = '') { + public function setCreator($pValue = '') + { $this->_creator = $pValue; return $this; } @@ -164,7 +158,8 @@ public function setCreator($pValue = '') { * * @return string */ - public function getLastModifiedBy() { + public function getLastModifiedBy() + { return $this->_lastModifiedBy; } @@ -174,7 +169,8 @@ public function getLastModifiedBy() { * @param string $pValue * @return PHPExcel_DocumentProperties */ - public function setLastModifiedBy($pValue = '') { + public function setLastModifiedBy($pValue = '') + { $this->_lastModifiedBy = $pValue; return $this; } @@ -184,7 +180,8 @@ public function setLastModifiedBy($pValue = '') { * * @return datetime */ - public function getCreated() { + public function getCreated() + { return $this->_created; } @@ -194,8 +191,9 @@ public function getCreated() { * @param datetime $pValue * @return PHPExcel_DocumentProperties */ - public function setCreated($pValue = null) { - if ($pValue === NULL) { + public function setCreated($pValue = null) + { + if ($pValue === null) { $pValue = time(); } elseif (is_string($pValue)) { if (is_numeric($pValue)) { @@ -214,7 +212,8 @@ public function setCreated($pValue = null) { * * @return datetime */ - public function getModified() { + public function getModified() + { return $this->_modified; } @@ -224,8 +223,9 @@ public function getModified() { * @param datetime $pValue * @return PHPExcel_DocumentProperties */ - public function setModified($pValue = null) { - if ($pValue === NULL) { + public function setModified($pValue = null) + { + if ($pValue === null) { $pValue = time(); } elseif (is_string($pValue)) { if (is_numeric($pValue)) { @@ -244,7 +244,8 @@ public function setModified($pValue = null) { * * @return string */ - public function getTitle() { + public function getTitle() + { return $this->_title; } @@ -254,7 +255,8 @@ public function getTitle() { * @param string $pValue * @return PHPExcel_DocumentProperties */ - public function setTitle($pValue = '') { + public function setTitle($pValue = '') + { $this->_title = $pValue; return $this; } @@ -264,7 +266,8 @@ public function setTitle($pValue = '') { * * @return string */ - public function getDescription() { + public function getDescription() + { return $this->_description; } @@ -274,7 +277,8 @@ public function getDescription() { * @param string $pValue * @return PHPExcel_DocumentProperties */ - public function setDescription($pValue = '') { + public function setDescription($pValue = '') + { $this->_description = $pValue; return $this; } @@ -284,7 +288,8 @@ public function setDescription($pValue = '') { * * @return string */ - public function getSubject() { + public function getSubject() + { return $this->_subject; } @@ -294,7 +299,8 @@ public function getSubject() { * @param string $pValue * @return PHPExcel_DocumentProperties */ - public function setSubject($pValue = '') { + public function setSubject($pValue = '') + { $this->_subject = $pValue; return $this; } @@ -304,7 +310,8 @@ public function setSubject($pValue = '') { * * @return string */ - public function getKeywords() { + public function getKeywords() + { return $this->_keywords; } @@ -314,7 +321,8 @@ public function getKeywords() { * @param string $pValue * @return PHPExcel_DocumentProperties */ - public function setKeywords($pValue = '') { + public function setKeywords($pValue = '') + { $this->_keywords = $pValue; return $this; } @@ -324,7 +332,8 @@ public function setKeywords($pValue = '') { * * @return string */ - public function getCategory() { + public function getCategory() + { return $this->_category; } @@ -334,7 +343,8 @@ public function getCategory() { * @param string $pValue * @return PHPExcel_DocumentProperties */ - public function setCategory($pValue = '') { + public function setCategory($pValue = '') + { $this->_category = $pValue; return $this; } @@ -344,7 +354,8 @@ public function setCategory($pValue = '') { * * @return string */ - public function getCompany() { + public function getCompany() + { return $this->_company; } @@ -354,7 +365,8 @@ public function getCompany() { * @param string $pValue * @return PHPExcel_DocumentProperties */ - public function setCompany($pValue = '') { + public function setCompany($pValue = '') + { $this->_company = $pValue; return $this; } @@ -364,7 +376,8 @@ public function setCompany($pValue = '') { * * @return string */ - public function getManager() { + public function getManager() + { return $this->_manager; } @@ -374,7 +387,8 @@ public function getManager() { * @param string $pValue * @return PHPExcel_DocumentProperties */ - public function setManager($pValue = '') { + public function setManager($pValue = '') + { $this->_manager = $pValue; return $this; } @@ -384,7 +398,8 @@ public function setManager($pValue = '') { * * @return array of string */ - public function getCustomProperties() { + public function getCustomProperties() + { return array_keys($this->_customProperties); } @@ -394,7 +409,8 @@ public function getCustomProperties() { * @param string $propertyName * @return boolean */ - public function isCustomPropertySet($propertyName) { + public function isCustomPropertySet($propertyName) + { return isset($this->_customProperties[$propertyName]); } @@ -404,7 +420,8 @@ public function isCustomPropertySet($propertyName) { * @param string $propertyName * @return string */ - public function getCustomPropertyValue($propertyName) { + public function getCustomPropertyValue($propertyName) + { if (isset($this->_customProperties[$propertyName])) { return $this->_customProperties[$propertyName]['value']; } @@ -417,7 +434,8 @@ public function getCustomPropertyValue($propertyName) { * @param string $propertyName * @return string */ - public function getCustomPropertyType($propertyName) { + public function getCustomPropertyType($propertyName) + { if (isset($this->_customProperties[$propertyName])) { return $this->_customProperties[$propertyName]['type']; } @@ -430,20 +448,21 @@ public function getCustomPropertyType($propertyName) { * @param string $propertyName * @param mixed $propertyValue * @param string $propertyType - * 'i' : Integer + * 'i' : Integer * 'f' : Floating Point * 's' : String * 'd' : Date/Time * 'b' : Boolean * @return PHPExcel_DocumentProperties */ - public function setCustomProperty($propertyName,$propertyValue='',$propertyType=NULL) { - if (($propertyType === NULL) || (!in_array($propertyType,array(self::PROPERTY_TYPE_INTEGER, - self::PROPERTY_TYPE_FLOAT, - self::PROPERTY_TYPE_STRING, - self::PROPERTY_TYPE_DATE, - self::PROPERTY_TYPE_BOOLEAN)))) { - if ($propertyValue === NULL) { + public function setCustomProperty($propertyName, $propertyValue = '', $propertyType = null) + { + if (($propertyType === null) || (!in_array($propertyType, array(self::PROPERTY_TYPE_INTEGER, + self::PROPERTY_TYPE_FLOAT, + self::PROPERTY_TYPE_STRING, + self::PROPERTY_TYPE_DATE, + self::PROPERTY_TYPE_BOOLEAN)))) { + if ($propertyValue === null) { $propertyType = self::PROPERTY_TYPE_STRING; } elseif (is_float($propertyValue)) { $propertyType = self::PROPERTY_TYPE_FLOAT; @@ -456,14 +475,18 @@ public function setCustomProperty($propertyName,$propertyValue='',$propertyType= } } - $this->_customProperties[$propertyName] = array('value' => $propertyValue, 'type' => $propertyType); + $this->_customProperties[$propertyName] = array( + 'value' => $propertyValue, + 'type' => $propertyType + ); return $this; } /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { @@ -474,58 +497,59 @@ public function __clone() { } } - public static function convertProperty($propertyValue,$propertyType) { + public static function convertProperty($propertyValue,$propertyType) + { switch ($propertyType) { - case 'empty' : // Empty + case 'empty': // Empty return ''; break; - case 'null' : // Null - return NULL; + case 'null': // Null + return null; break; - case 'i1' : // 1-Byte Signed Integer - case 'i2' : // 2-Byte Signed Integer - case 'i4' : // 4-Byte Signed Integer - case 'i8' : // 8-Byte Signed Integer - case 'int' : // Integer + case 'i1': // 1-Byte Signed Integer + case 'i2': // 2-Byte Signed Integer + case 'i4': // 4-Byte Signed Integer + case 'i8': // 8-Byte Signed Integer + case 'int': // Integer return (int) $propertyValue; break; - case 'ui1' : // 1-Byte Unsigned Integer - case 'ui2' : // 2-Byte Unsigned Integer - case 'ui4' : // 4-Byte Unsigned Integer - case 'ui8' : // 8-Byte Unsigned Integer - case 'uint' : // Unsigned Integer + case 'ui1': // 1-Byte Unsigned Integer + case 'ui2': // 2-Byte Unsigned Integer + case 'ui4': // 4-Byte Unsigned Integer + case 'ui8': // 8-Byte Unsigned Integer + case 'uint': // Unsigned Integer return abs((int) $propertyValue); break; - case 'r4' : // 4-Byte Real Number - case 'r8' : // 8-Byte Real Number - case 'decimal' : // Decimal + case 'r4': // 4-Byte Real Number + case 'r8': // 8-Byte Real Number + case 'decimal': // Decimal return (float) $propertyValue; break; - case 'lpstr' : // LPSTR - case 'lpwstr' : // LPWSTR - case 'bstr' : // Basic String + case 'lpstr': // LPSTR + case 'lpwstr': // LPWSTR + case 'bstr': // Basic String return $propertyValue; break; - case 'date' : // Date and Time - case 'filetime' : // File Time + case 'date': // Date and Time + case 'filetime': // File Time return strtotime($propertyValue); break; - case 'bool' : // Boolean + case 'bool': // Boolean return ($propertyValue == 'true') ? True : False; break; - case 'cy' : // Currency - case 'error' : // Error Status Code - case 'vector' : // Vector - case 'array' : // Array - case 'blob' : // Binary Blob - case 'oblob' : // Binary Blob Object - case 'stream' : // Binary Stream - case 'ostream' : // Binary Stream Object - case 'storage' : // Binary Storage - case 'ostorage' : // Binary Storage Object - case 'vstream' : // Binary Versioned Stream - case 'clsid' : // Class ID - case 'cf' : // Clipboard Data + case 'cy': // Currency + case 'error': // Error Status Code + case 'vector': // Vector + case 'array': // Array + case 'blob': // Binary Blob + case 'oblob': // Binary Blob Object + case 'stream': // Binary Stream + case 'ostream': // Binary Stream Object + case 'storage': // Binary Storage + case 'ostorage': // Binary Storage Object + case 'vstream': // Binary Versioned Stream + case 'clsid': // Class ID + case 'cf': // Clipboard Data return $propertyValue; break; } @@ -534,50 +558,50 @@ public static function convertProperty($propertyValue,$propertyType) { public static function convertPropertyType($propertyType) { switch ($propertyType) { - case 'i1' : // 1-Byte Signed Integer - case 'i2' : // 2-Byte Signed Integer - case 'i4' : // 4-Byte Signed Integer - case 'i8' : // 8-Byte Signed Integer - case 'int' : // Integer - case 'ui1' : // 1-Byte Unsigned Integer - case 'ui2' : // 2-Byte Unsigned Integer - case 'ui4' : // 4-Byte Unsigned Integer - case 'ui8' : // 8-Byte Unsigned Integer - case 'uint' : // Unsigned Integer + case 'i1': // 1-Byte Signed Integer + case 'i2': // 2-Byte Signed Integer + case 'i4': // 4-Byte Signed Integer + case 'i8': // 8-Byte Signed Integer + case 'int': // Integer + case 'ui1': // 1-Byte Unsigned Integer + case 'ui2': // 2-Byte Unsigned Integer + case 'ui4': // 4-Byte Unsigned Integer + case 'ui8': // 8-Byte Unsigned Integer + case 'uint': // Unsigned Integer return self::PROPERTY_TYPE_INTEGER; break; - case 'r4' : // 4-Byte Real Number - case 'r8' : // 8-Byte Real Number - case 'decimal' : // Decimal + case 'r4': // 4-Byte Real Number + case 'r8': // 8-Byte Real Number + case 'decimal': // Decimal return self::PROPERTY_TYPE_FLOAT; break; - case 'empty' : // Empty - case 'null' : // Null - case 'lpstr' : // LPSTR - case 'lpwstr' : // LPWSTR - case 'bstr' : // Basic String + case 'empty': // Empty + case 'null': // Null + case 'lpstr': // LPSTR + case 'lpwstr': // LPWSTR + case 'bstr': // Basic String return self::PROPERTY_TYPE_STRING; break; - case 'date' : // Date and Time - case 'filetime' : // File Time + case 'date': // Date and Time + case 'filetime': // File Time return self::PROPERTY_TYPE_DATE; break; - case 'bool' : // Boolean + case 'bool': // Boolean return self::PROPERTY_TYPE_BOOLEAN; break; - case 'cy' : // Currency - case 'error' : // Error Status Code - case 'vector' : // Vector - case 'array' : // Array - case 'blob' : // Binary Blob - case 'oblob' : // Binary Blob Object - case 'stream' : // Binary Stream - case 'ostream' : // Binary Stream Object - case 'storage' : // Binary Storage - case 'ostorage' : // Binary Storage Object - case 'vstream' : // Binary Versioned Stream - case 'clsid' : // Class ID - case 'cf' : // Clipboard Data + case 'cy': // Currency + case 'error': // Error Status Code + case 'vector': // Vector + case 'array': // Array + case 'blob': // Binary Blob + case 'oblob': // Binary Blob Object + case 'stream': // Binary Stream + case 'ostream': // Binary Stream Object + case 'storage': // Binary Storage + case 'ostorage': // Binary Storage Object + case 'vstream': // Binary Versioned Stream + case 'clsid': // Class ID + case 'cf': // Clipboard Data return self::PROPERTY_TYPE_UNKNOWN; break; } diff --git a/Classes/PHPExcel/DocumentSecurity.php b/Classes/PHPExcel/DocumentSecurity.php index b194ecd8c..095501934 100644 --- a/Classes/PHPExcel/DocumentSecurity.php +++ b/Classes/PHPExcel/DocumentSecurity.php @@ -1,6 +1,7 @@ _lockRevision = false; - $this->_lockStructure = false; - $this->_lockWindows = false; - $this->_revisionsPassword = ''; - $this->_workbookPassword = ''; + // Initialise values + $this->_lockRevision = false; + $this->_lockStructure = false; + $this->_lockWindows = false; + $this->_revisionsPassword = ''; + $this->_workbookPassword = ''; } /** @@ -88,10 +80,11 @@ public function __construct() * * @return boolean */ - function isSecurityEnabled() { - return $this->_lockRevision || - $this->_lockStructure || - $this->_lockWindows; + function isSecurityEnabled() + { + return $this->_lockRevision || + $this->_lockStructure || + $this->_lockWindows; } /** @@ -99,8 +92,9 @@ function isSecurityEnabled() { * * @return boolean */ - function getLockRevision() { - return $this->_lockRevision; + function getLockRevision() + { + return $this->_lockRevision; } /** @@ -109,9 +103,10 @@ function getLockRevision() { * @param boolean $pValue * @return PHPExcel_DocumentSecurity */ - function setLockRevision($pValue = false) { - $this->_lockRevision = $pValue; - return $this; + function setLockRevision($pValue = false) + { + $this->_lockRevision = $pValue; + return $this; } /** @@ -119,8 +114,9 @@ function setLockRevision($pValue = false) { * * @return boolean */ - function getLockStructure() { - return $this->_lockStructure; + function getLockStructure() + { + return $this->_lockStructure; } /** @@ -129,9 +125,10 @@ function getLockStructure() { * @param boolean $pValue * @return PHPExcel_DocumentSecurity */ - function setLockStructure($pValue = false) { - $this->_lockStructure = $pValue; - return $this; + function setLockStructure($pValue = false) + { + $this->_lockStructure = $pValue; + return $this; } /** @@ -139,8 +136,9 @@ function setLockStructure($pValue = false) { * * @return boolean */ - function getLockWindows() { - return $this->_lockWindows; + function getLockWindows() + { + return $this->_lockWindows; } /** @@ -149,9 +147,10 @@ function getLockWindows() { * @param boolean $pValue * @return PHPExcel_DocumentSecurity */ - function setLockWindows($pValue = false) { - $this->_lockWindows = $pValue; - return $this; + function setLockWindows($pValue = false) + { + $this->_lockWindows = $pValue; + return $this; } /** @@ -159,23 +158,25 @@ function setLockWindows($pValue = false) { * * @return string */ - function getRevisionsPassword() { - return $this->_revisionsPassword; + function getRevisionsPassword() + { + return $this->_revisionsPassword; } /** * Set RevisionsPassword * - * @param string $pValue - * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @param string $pValue + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true * @return PHPExcel_DocumentSecurity */ - function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) { - if (!$pAlreadyHashed) { - $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); - } - $this->_revisionsPassword = $pValue; - return $this; + function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) + { + if (!$pAlreadyHashed) { + $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); + } + $this->_revisionsPassword = $pValue; + return $this; } /** @@ -183,36 +184,39 @@ function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) { * * @return string */ - function getWorkbookPassword() { - return $this->_workbookPassword; + function getWorkbookPassword() + { + return $this->_workbookPassword; } /** * Set WorkbookPassword * - * @param string $pValue - * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @param string $pValue + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true * @return PHPExcel_DocumentSecurity */ - function setWorkbookPassword($pValue = '', $pAlreadyHashed = false) { - if (!$pAlreadyHashed) { - $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); - } - $this->_workbookPassword = $pValue; - return $this; + function setWorkbookPassword($pValue = '', $pAlreadyHashed = false) + { + if (!$pAlreadyHashed) { + $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); + } + $this->_workbookPassword = $pValue; + return $this; } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() + { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/HashTable.php b/Classes/PHPExcel/HashTable.php index 4fb41adb3..8ec020ba5 100644 --- a/Classes/PHPExcel/HashTable.php +++ b/Classes/PHPExcel/HashTable.php @@ -1,6 +1,7 @@ addFromSource($pSource); - } - } - - /** - * Add HashTable items from source - * - * @param PHPExcel_IComparable[] $pSource Source array to create HashTable from - * @throws PHPExcel_Exception - */ - public function addFromSource($pSource = null) { - // Check if an array was passed - if ($pSource == null) { - return; - } else if (!is_array($pSource)) { - throw new PHPExcel_Exception('Invalid array parameter passed.'); - } - - foreach ($pSource as $item) { - $this->add($item); - } - } - - /** - * Add HashTable item - * - * @param PHPExcel_IComparable $pSource Item to add - * @throws PHPExcel_Exception - */ - public function add(PHPExcel_IComparable $pSource = null) { - $hash = $pSource->getHashCode(); - if (!isset($this->_items[$hash])) { - $this->_items[$hash] = $pSource; - $this->_keyMap[count($this->_items) - 1] = $hash; - } - } - - /** - * Remove HashTable item - * - * @param PHPExcel_IComparable $pSource Item to remove - * @throws PHPExcel_Exception - */ - public function remove(PHPExcel_IComparable $pSource = null) { - $hash = $pSource->getHashCode(); - if (isset($this->_items[$hash])) { - unset($this->_items[$hash]); - - $deleteKey = -1; - foreach ($this->_keyMap as $key => $value) { - if ($deleteKey >= 0) { - $this->_keyMap[$key - 1] = $value; - } - - if ($value == $hash) { - $deleteKey = $key; - } - } - unset($this->_keyMap[count($this->_keyMap) - 1]); - } - } - - /** - * Clear HashTable - * - */ - public function clear() { - $this->_items = array(); - $this->_keyMap = array(); - } - - /** - * Count - * - * @return int - */ - public function count() { - return count($this->_items); - } - - /** - * Get index for hash code - * - * @param string $pHashCode - * @return int Index - */ - public function getIndexForHashCode($pHashCode = '') { - return array_search($pHashCode, $this->_keyMap); - } - - /** - * Get by index - * - * @param int $pIndex - * @return PHPExcel_IComparable - * - */ - public function getByIndex($pIndex = 0) { - if (isset($this->_keyMap[$pIndex])) { - return $this->getByHashCode( $this->_keyMap[$pIndex] ); - } - - return null; - } - - /** - * Get by hashcode - * - * @param string $pHashCode - * @return PHPExcel_IComparable - * - */ - public function getByHashCode($pHashCode = '') { - if (isset($this->_items[$pHashCode])) { - return $this->_items[$pHashCode]; - } - - return null; - } - - /** - * HashTable to array - * - * @return PHPExcel_IComparable[] - */ - public function toArray() { - return $this->_items; - } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } - } - } + /** + * HashTable elements + * + * @var array + */ + public $_items = array(); + + /** + * HashTable key map + * + * @var array + */ + public $_keyMap = array(); + + /** + * Create a new PHPExcel_HashTable + * + * @param PHPExcel_IComparable[] $pSource Optional source array to create HashTable from + * @throws PHPExcel_Exception + */ + public function __construct($pSource = null) + { + if ($pSource !== null) { + // Create HashTable + $this->addFromSource($pSource); + } + } + + /** + * Add HashTable items from source + * + * @param PHPExcel_IComparable[] $pSource Source array to create HashTable from + * @throws PHPExcel_Exception + */ + public function addFromSource($pSource = null) + { + // Check if an array was passed + if ($pSource == null) { + return; + } else if (!is_array($pSource)) { + throw new PHPExcel_Exception('Invalid array parameter passed.'); + } + + foreach ($pSource as $item) { + $this->add($item); + } + } + + /** + * Add HashTable item + * + * @param PHPExcel_IComparable $pSource Item to add + * @throws PHPExcel_Exception + */ + public function add(PHPExcel_IComparable $pSource = null) + { + $hash = $pSource->getHashCode(); + if (!isset($this->_items[$hash])) { + $this->_items[$hash] = $pSource; + $this->_keyMap[count($this->_items) - 1] = $hash; + } + } + + /** + * Remove HashTable item + * + * @param PHPExcel_IComparable $pSource Item to remove + * @throws PHPExcel_Exception + */ + public function remove(PHPExcel_IComparable $pSource = null) + { + $hash = $pSource->getHashCode(); + if (isset($this->_items[$hash])) { + unset($this->_items[$hash]); + + $deleteKey = -1; + foreach ($this->_keyMap as $key => $value) { + if ($deleteKey >= 0) { + $this->_keyMap[$key - 1] = $value; + } + + if ($value == $hash) { + $deleteKey = $key; + } + } + unset($this->_keyMap[count($this->_keyMap) - 1]); + } + } + + /** + * Clear HashTable + * + */ + public function clear() + { + $this->_items = array(); + $this->_keyMap = array(); + } + + /** + * Count + * + * @return int + */ + public function count() + { + return count($this->_items); + } + + /** + * Get index for hash code + * + * @param string $pHashCode + * @return int Index + */ + public function getIndexForHashCode($pHashCode = '') + { + return array_search($pHashCode, $this->_keyMap); + } + + /** + * Get by index + * + * @param int $pIndex + * @return PHPExcel_IComparable + * + */ + public function getByIndex($pIndex = 0) + { + if (isset($this->_keyMap[$pIndex])) { + return $this->getByHashCode( $this->_keyMap[$pIndex] ); + } + + return null; + } + + /** + * Get by hashcode + * + * @param string $pHashCode + * @return PHPExcel_IComparable + * + */ + public function getByHashCode($pHashCode = '') + { + if (isset($this->_items[$pHashCode])) { + return $this->_items[$pHashCode]; + } + + return null; + } + + /** + * HashTable to array + * + * @return PHPExcel_IComparable[] + */ + public function toArray() + { + return $this->_items; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() + { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } + } + } } diff --git a/Classes/PHPExcel/IComparable.php b/Classes/PHPExcel/IComparable.php index 3afbf4bc4..62a06aea9 100644 --- a/Classes/PHPExcel/IComparable.php +++ b/Classes/PHPExcel/IComparable.php @@ -1,6 +1,7 @@ 'IWriter', 'path' => 'PHPExcel/Writer/{0}.php', 'class' => 'PHPExcel_Writer_{0}' ), - array( 'type' => 'IReader', 'path' => 'PHPExcel/Reader/{0}.php', 'class' => 'PHPExcel_Reader_{0}' ) - ); + /** + * Search locations + * + * @var array + * @access private + * @static + */ + private static $_searchLocations = array( + array( 'type' => 'IWriter', 'path' => 'PHPExcel/Writer/{0}.php', 'class' => 'PHPExcel_Writer_{0}' ), + array( 'type' => 'IReader', 'path' => 'PHPExcel/Reader/{0}.php', 'class' => 'PHPExcel_Reader_{0}' ) + ); - /** - * Autoresolve classes - * - * @var array - * @access private - * @static - */ - private static $_autoResolveClasses = array( - 'Excel2007', - 'Excel5', - 'Excel2003XML', - 'OOCalc', - 'SYLK', - 'Gnumeric', - 'HTML', - 'CSV', - ); + /** + * Autoresolve classes + * + * @var array + * @access private + * @static + */ + private static $_autoResolveClasses = array( + 'Excel2007', + 'Excel5', + 'Excel2003XML', + 'OOCalc', + 'SYLK', + 'Gnumeric', + 'HTML', + 'CSV', + ); /** - * Private constructor for PHPExcel_IOFactory + * Private constructor for PHPExcel_IOFactory */ private function __construct() { } /** * Get search locations * - * @static - * @access public - * @return array + * @static + * @access public + * @return array */ - public static function getSearchLocations() { - return self::$_searchLocations; - } // function getSearchLocations() - - /** - * Set search locations - * - * @static - * @access public - * @param array $value - * @throws PHPExcel_Reader_Exception - */ - public static function setSearchLocations($value) { - if (is_array($value)) { - self::$_searchLocations = $value; - } else { - throw new PHPExcel_Reader_Exception('Invalid parameter passed.'); - } - } // function setSearchLocations() + public static function getSearchLocations() + { + return self::$_searchLocations; + } - /** - * Add search location - * - * @static - * @access public - * @param string $type Example: IWriter - * @param string $location Example: PHPExcel/Writer/{0}.php - * @param string $classname Example: PHPExcel_Writer_{0} - */ - public static function addSearchLocation($type = '', $location = '', $classname = '') { - self::$_searchLocations[] = array( 'type' => $type, 'path' => $location, 'class' => $classname ); - } // function addSearchLocation() + /** + * Set search locations + * + * @static + * @access public + * @param array $value + * @throws PHPExcel_Reader_Exception + */ + public static function setSearchLocations($value) + { + if (is_array($value)) { + self::$_searchLocations = $value; + } else { + throw new PHPExcel_Reader_Exception('Invalid parameter passed.'); + } + } - /** - * Create PHPExcel_Writer_IWriter - * - * @static - * @access public - * @param PHPExcel $phpExcel - * @param string $writerType Example: Excel2007 - * @return PHPExcel_Writer_IWriter - * @throws PHPExcel_Reader_Exception - */ - public static function createWriter(PHPExcel $phpExcel, $writerType = '') { - // Search type - $searchType = 'IWriter'; + /** + * Add search location + * + * @static + * @access public + * @param string $type Example: IWriter + * @param string $location Example: PHPExcel/Writer/{0}.php + * @param string $classname Example: PHPExcel_Writer_{0} + */ + public static function addSearchLocation($type = '', $location = '', $classname = '') + { + self::$_searchLocations[] = array( 'type' => $type, 'path' => $location, 'class' => $classname ); + } - // Include class - foreach (self::$_searchLocations as $searchLocation) { - if ($searchLocation['type'] == $searchType) { - $className = str_replace('{0}', $writerType, $searchLocation['class']); + /** + * Create PHPExcel_Writer_IWriter + * + * @static + * @access public + * @param PHPExcel $phpExcel + * @param string $writerType Example: Excel2007 + * @return PHPExcel_Writer_IWriter + * @throws PHPExcel_Reader_Exception + */ + public static function createWriter(PHPExcel $phpExcel, $writerType = '') + { + // Search type + $searchType = 'IWriter'; - $instance = new $className($phpExcel); - if ($instance !== NULL) { - return $instance; - } - } - } + // Include class + foreach (self::$_searchLocations as $searchLocation) { + if ($searchLocation['type'] == $searchType) { + $className = str_replace('{0}', $writerType, $searchLocation['class']); - // Nothing found... - throw new PHPExcel_Reader_Exception("No $searchType found for type $writerType"); - } // function createWriter() + $instance = new $className($phpExcel); + if ($instance !== NULL) { + return $instance; + } + } + } - /** - * Create PHPExcel_Reader_IReader - * - * @static - * @access public - * @param string $readerType Example: Excel2007 - * @return PHPExcel_Reader_IReader - * @throws PHPExcel_Reader_Exception - */ - public static function createReader($readerType = '') { - // Search type - $searchType = 'IReader'; + // Nothing found... + throw new PHPExcel_Reader_Exception("No $searchType found for type $writerType"); + } - // Include class - foreach (self::$_searchLocations as $searchLocation) { - if ($searchLocation['type'] == $searchType) { - $className = str_replace('{0}', $readerType, $searchLocation['class']); + /** + * Create PHPExcel_Reader_IReader + * + * @static + * @access public + * @param string $readerType Example: Excel2007 + * @return PHPExcel_Reader_IReader + * @throws PHPExcel_Reader_Exception + */ + public static function createReader($readerType = '') + { + // Search type + $searchType = 'IReader'; - $instance = new $className(); - if ($instance !== NULL) { - return $instance; - } - } - } + // Include class + foreach (self::$_searchLocations as $searchLocation) { + if ($searchLocation['type'] == $searchType) { + $className = str_replace('{0}', $readerType, $searchLocation['class']); - // Nothing found... - throw new PHPExcel_Reader_Exception("No $searchType found for type $readerType"); - } // function createReader() + $instance = new $className(); + if ($instance !== NULL) { + return $instance; + } + } + } - /** - * Loads PHPExcel from file using automatic PHPExcel_Reader_IReader resolution - * - * @static - * @access public - * @param string $pFilename The name of the spreadsheet file - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public static function load($pFilename) { - $reader = self::createReaderForFile($pFilename); - return $reader->load($pFilename); - } // function load() + // Nothing found... + throw new PHPExcel_Reader_Exception("No $searchType found for type $readerType"); + } - /** - * Identify file type using automatic PHPExcel_Reader_IReader resolution - * - * @static - * @access public - * @param string $pFilename The name of the spreadsheet file to identify - * @return string - * @throws PHPExcel_Reader_Exception - */ - public static function identify($pFilename) { - $reader = self::createReaderForFile($pFilename); - $className = get_class($reader); - $classType = explode('_',$className); - unset($reader); - return array_pop($classType); - } // function identify() + /** + * Loads PHPExcel from file using automatic PHPExcel_Reader_IReader resolution + * + * @static + * @access public + * @param string $pFilename The name of the spreadsheet file + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public static function load($pFilename) + { + $reader = self::createReaderForFile($pFilename); + return $reader->load($pFilename); + } - /** - * Create PHPExcel_Reader_IReader for file using automatic PHPExcel_Reader_IReader resolution - * - * @static - * @access public - * @param string $pFilename The name of the spreadsheet file - * @return PHPExcel_Reader_IReader - * @throws PHPExcel_Reader_Exception - */ - public static function createReaderForFile($pFilename) { + /** + * Identify file type using automatic PHPExcel_Reader_IReader resolution + * + * @static + * @access public + * @param string $pFilename The name of the spreadsheet file to identify + * @return string + * @throws PHPExcel_Reader_Exception + */ + public static function identify($pFilename) + { + $reader = self::createReaderForFile($pFilename); + $className = get_class($reader); + $classType = explode('_',$className); + unset($reader); + return array_pop($classType); + } - // First, lucky guess by inspecting file extension - $pathinfo = pathinfo($pFilename); + /** + * Create PHPExcel_Reader_IReader for file using automatic PHPExcel_Reader_IReader resolution + * + * @static + * @access public + * @param string $pFilename The name of the spreadsheet file + * @return PHPExcel_Reader_IReader + * @throws PHPExcel_Reader_Exception + */ + public static function createReaderForFile($pFilename) + { + // First, lucky guess by inspecting file extension + $pathinfo = pathinfo($pFilename); - $extensionType = NULL; - if (isset($pathinfo['extension'])) { - switch (strtolower($pathinfo['extension'])) { - case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet - case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded) - case 'xltx': // Excel (OfficeOpenXML) Template - case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded) - $extensionType = 'Excel2007'; - break; - case 'xls': // Excel (BIFF) Spreadsheet - case 'xlt': // Excel (BIFF) Template - $extensionType = 'Excel5'; - break; - case 'ods': // Open/Libre Offic Calc - case 'ots': // Open/Libre Offic Calc Template - $extensionType = 'OOCalc'; - break; - case 'slk': - $extensionType = 'SYLK'; - break; - case 'xml': // Excel 2003 SpreadSheetML - $extensionType = 'Excel2003XML'; - break; - case 'gnumeric': - $extensionType = 'Gnumeric'; - break; - case 'htm': - case 'html': - $extensionType = 'HTML'; - break; - case 'csv': - // Do nothing - // We must not try to use CSV reader since it loads - // all files including Excel files etc. - break; - default: - break; - } + $extensionType = NULL; + if (isset($pathinfo['extension'])) { + switch (strtolower($pathinfo['extension'])) { + case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet + case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded) + case 'xltx': // Excel (OfficeOpenXML) Template + case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded) + $extensionType = 'Excel2007'; + break; + case 'xls': // Excel (BIFF) Spreadsheet + case 'xlt': // Excel (BIFF) Template + $extensionType = 'Excel5'; + break; + case 'ods': // Open/Libre Offic Calc + case 'ots': // Open/Libre Offic Calc Template + $extensionType = 'OOCalc'; + break; + case 'slk': + $extensionType = 'SYLK'; + break; + case 'xml': // Excel 2003 SpreadSheetML + $extensionType = 'Excel2003XML'; + break; + case 'gnumeric': + $extensionType = 'Gnumeric'; + break; + case 'htm': + case 'html': + $extensionType = 'HTML'; + break; + case 'csv': + // Do nothing + // We must not try to use CSV reader since it loads + // all files including Excel files etc. + break; + default: + break; + } - if ($extensionType !== NULL) { - $reader = self::createReader($extensionType); - // Let's see if we are lucky - if (isset($reader) && $reader->canRead($pFilename)) { - return $reader; - } - } - } + if ($extensionType !== null) { + $reader = self::createReader($extensionType); + // Let's see if we are lucky + if (isset($reader) && $reader->canRead($pFilename)) { + return $reader; + } + } + } - // If we reach here then "lucky guess" didn't give any result - // Try walking through all the options in self::$_autoResolveClasses - foreach (self::$_autoResolveClasses as $autoResolveClass) { - // Ignore our original guess, we know that won't work - if ($autoResolveClass !== $extensionType) { - $reader = self::createReader($autoResolveClass); - if ($reader->canRead($pFilename)) { - return $reader; - } - } - } + // If we reach here then "lucky guess" didn't give any result + // Try walking through all the options in self::$_autoResolveClasses + foreach (self::$_autoResolveClasses as $autoResolveClass) { + // Ignore our original guess, we know that won't work + if ($autoResolveClass !== $extensionType) { + $reader = self::createReader($autoResolveClass); + if ($reader->canRead($pFilename)) { + return $reader; + } + } + } - throw new PHPExcel_Reader_Exception('Unable to identify a reader for this file'); - } // function createReaderForFile() + throw new PHPExcel_Reader_Exception('Unable to identify a reader for this file'); + } } diff --git a/Classes/PHPExcel/NamedRange.php b/Classes/PHPExcel/NamedRange.php index cab3c7ec7..164246fe9 100644 --- a/Classes/PHPExcel/NamedRange.php +++ b/Classes/PHPExcel/NamedRange.php @@ -1,6 +1,7 @@ _worksheet) - * - * @var bool - */ - private $_localOnly; - - /** - * Scope - * - * @var PHPExcel_Worksheet - */ - private $_scope; + /** + * Range name + * + * @var string + */ + private $_name; + + /** + * Worksheet on which the named range can be resolved + * + * @var PHPExcel_Worksheet + */ + private $_worksheet; + + /** + * Range of the referenced cells + * + * @var string + */ + private $_range; + + /** + * Is the named range local? (i.e. can only be used on $this->_worksheet) + * + * @var bool + */ + private $_localOnly; + + /** + * Scope + * + * @var PHPExcel_Worksheet + */ + private $_scope; /** * Create a new NamedRange @@ -77,23 +69,23 @@ class PHPExcel_NamedRange * @param PHPExcel_Worksheet $pWorksheet * @param string $pRange * @param bool $pLocalOnly - * @param PHPExcel_Worksheet|null $pScope Scope. Only applies when $pLocalOnly = true. Null for global scope. + * @param PHPExcel_Worksheet|null $pScope Scope. Only applies when $pLocalOnly = true. Null for global scope. * @throws PHPExcel_Exception */ public function __construct($pName = null, PHPExcel_Worksheet $pWorksheet, $pRange = 'A1', $pLocalOnly = false, $pScope = null) { - // Validate data - if (($pName === NULL) || ($pWorksheet === NULL) || ($pRange === NULL)) { - throw new PHPExcel_Exception('Parameters can not be null.'); - } - - // Set local members - $this->_name = $pName; - $this->_worksheet = $pWorksheet; - $this->_range = $pRange; - $this->_localOnly = $pLocalOnly; - $this->_scope = ($pLocalOnly == true) ? - (($pScope == null) ? $pWorksheet : $pScope) : null; + // Validate data + if (($pName === NULL) || ($pWorksheet === NULL) || ($pRange === NULL)) { + throw new PHPExcel_Exception('Parameters can not be null.'); + } + + // Set local members + $this->_name = $pName; + $this->_worksheet = $pWorksheet; + $this->_range = $pRange; + $this->_localOnly = $pLocalOnly; + $this->_scope = ($pLocalOnly == true) ? + (($pScope == null) ? $pWorksheet : $pScope) : null; } /** @@ -102,7 +94,7 @@ public function __construct($pName = null, PHPExcel_Worksheet $pWorksheet, $pRan * @return string */ public function getName() { - return $this->_name; + return $this->_name; } /** @@ -112,25 +104,25 @@ public function getName() { * @return PHPExcel_NamedRange */ public function setName($value = null) { - if ($value !== NULL) { - // Old title - $oldTitle = $this->_name; - - // Re-attach - if ($this->_worksheet !== NULL) { - $this->_worksheet->getParent()->removeNamedRange($this->_name,$this->_worksheet); - } - $this->_name = $value; - - if ($this->_worksheet !== NULL) { - $this->_worksheet->getParent()->addNamedRange($this); - } - - // New title - $newTitle = $this->_name; - PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_worksheet->getParent(), $oldTitle, $newTitle); - } - return $this; + if ($value !== NULL) { + // Old title + $oldTitle = $this->_name; + + // Re-attach + if ($this->_worksheet !== NULL) { + $this->_worksheet->getParent()->removeNamedRange($this->_name,$this->_worksheet); + } + $this->_name = $value; + + if ($this->_worksheet !== NULL) { + $this->_worksheet->getParent()->addNamedRange($this); + } + + // New title + $newTitle = $this->_name; + PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_worksheet->getParent(), $oldTitle, $newTitle); + } + return $this; } /** @@ -139,7 +131,7 @@ public function setName($value = null) { * @return PHPExcel_Worksheet */ public function getWorksheet() { - return $this->_worksheet; + return $this->_worksheet; } /** @@ -149,10 +141,10 @@ public function getWorksheet() { * @return PHPExcel_NamedRange */ public function setWorksheet(PHPExcel_Worksheet $value = null) { - if ($value !== NULL) { - $this->_worksheet = $value; - } - return $this; + if ($value !== NULL) { + $this->_worksheet = $value; + } + return $this; } /** @@ -161,7 +153,7 @@ public function setWorksheet(PHPExcel_Worksheet $value = null) { * @return string */ public function getRange() { - return $this->_range; + return $this->_range; } /** @@ -171,10 +163,10 @@ public function getRange() { * @return PHPExcel_NamedRange */ public function setRange($value = null) { - if ($value !== NULL) { - $this->_range = $value; - } - return $this; + if ($value !== NULL) { + $this->_range = $value; + } + return $this; } /** @@ -183,7 +175,7 @@ public function setRange($value = null) { * @return bool */ public function getLocalOnly() { - return $this->_localOnly; + return $this->_localOnly; } /** @@ -193,9 +185,9 @@ public function getLocalOnly() { * @return PHPExcel_NamedRange */ public function setLocalOnly($value = false) { - $this->_localOnly = $value; - $this->_scope = $value ? $this->_worksheet : null; - return $this; + $this->_localOnly = $value; + $this->_scope = $value ? $this->_worksheet : null; + return $this; } /** @@ -204,7 +196,7 @@ public function setLocalOnly($value = false) { * @return PHPExcel_Worksheet|null */ public function getScope() { - return $this->_scope; + return $this->_scope; } /** @@ -214,9 +206,9 @@ public function getScope() { * @return PHPExcel_NamedRange */ public function setScope(PHPExcel_Worksheet $value = null) { - $this->_scope = $value; - $this->_localOnly = ($value == null) ? false : true; - return $this; + $this->_scope = $value; + $this->_localOnly = ($value == null) ? false : true; + return $this; } /** @@ -227,20 +219,20 @@ public function setScope(PHPExcel_Worksheet $value = null) { * @return PHPExcel_NamedRange */ public static function resolveRange($pNamedRange = '', PHPExcel_Worksheet $pSheet) { - return $pSheet->getParent()->getNamedRange($pNamedRange, $pSheet); + return $pSheet->getParent()->getNamedRange($pNamedRange, $pSheet); } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php index 8fa961b04..a0201366c 100644 --- a/Classes/PHPExcel/Reader/Abstract.php +++ b/Classes/PHPExcel/Reader/Abstract.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -29,212 +29,212 @@ /** * PHPExcel_Reader_Abstract * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { - /** - * Read data only? - * Identifies whether the Reader should only read data values for cells, and ignore any formatting information; - * or whether it should read both data and formatting - * - * @var boolean - */ - protected $_readDataOnly = FALSE; - - /** - * Read charts that are defined in the workbook? - * Identifies whether the Reader should read the definitions for any charts that exist in the workbook; - * - * @var boolean - */ - protected $_includeCharts = FALSE; - - /** - * Restrict which sheets should be loaded? - * This property holds an array of worksheet names to be loaded. If null, then all worksheets will be loaded. - * - * @var array of string - */ - protected $_loadSheetsOnly = NULL; - - /** - * PHPExcel_Reader_IReadFilter instance - * - * @var PHPExcel_Reader_IReadFilter - */ - protected $_readFilter = NULL; - - protected $_fileHandle = NULL; - - - /** - * Read data only? - * If this is true, then the Reader will only read data values for cells, it will not read any formatting information. - * If false (the default) it will read data and formatting. - * - * @return boolean - */ - public function getReadDataOnly() { - return $this->_readDataOnly; - } - - /** - * Set read data only - * Set to true, to advise the Reader only to read data values for cells, and to ignore any formatting information. - * Set to false (the default) to advise the Reader to read both data and formatting for cells. - * - * @param boolean $pValue - * - * @return PHPExcel_Reader_IReader - */ - public function setReadDataOnly($pValue = FALSE) { - $this->_readDataOnly = $pValue; - return $this; - } - - /** - * Read charts in workbook? - * If this is true, then the Reader will include any charts that exist in the workbook. - * Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. - * If false (the default) it will ignore any charts defined in the workbook file. - * - * @return boolean - */ - public function getIncludeCharts() { - return $this->_includeCharts; - } - - /** - * Set read charts in workbook - * Set to true, to advise the Reader to include any charts that exist in the workbook. - * Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. - * Set to false (the default) to discard charts. - * - * @param boolean $pValue - * - * @return PHPExcel_Reader_IReader - */ - public function setIncludeCharts($pValue = FALSE) { - $this->_includeCharts = (boolean) $pValue; - return $this; - } - - /** - * Get which sheets to load - * Returns either an array of worksheet names (the list of worksheets that should be loaded), or a null - * indicating that all worksheets in the workbook should be loaded. - * - * @return mixed - */ - public function getLoadSheetsOnly() - { - return $this->_loadSheetsOnly; - } - - /** - * Set which sheets to load - * - * @param mixed $value - * This should be either an array of worksheet names to be loaded, or a string containing a single worksheet name. - * If NULL, then it tells the Reader to read all worksheets in the workbook - * - * @return PHPExcel_Reader_IReader - */ - public function setLoadSheetsOnly($value = NULL) - { + /** + * Read data only? + * Identifies whether the Reader should only read data values for cells, and ignore any formatting information; + * or whether it should read both data and formatting + * + * @var boolean + */ + protected $_readDataOnly = FALSE; + + /** + * Read charts that are defined in the workbook? + * Identifies whether the Reader should read the definitions for any charts that exist in the workbook; + * + * @var boolean + */ + protected $_includeCharts = FALSE; + + /** + * Restrict which sheets should be loaded? + * This property holds an array of worksheet names to be loaded. If null, then all worksheets will be loaded. + * + * @var array of string + */ + protected $_loadSheetsOnly = NULL; + + /** + * PHPExcel_Reader_IReadFilter instance + * + * @var PHPExcel_Reader_IReadFilter + */ + protected $_readFilter = NULL; + + protected $_fileHandle = NULL; + + + /** + * Read data only? + * If this is true, then the Reader will only read data values for cells, it will not read any formatting information. + * If false (the default) it will read data and formatting. + * + * @return boolean + */ + public function getReadDataOnly() { + return $this->_readDataOnly; + } + + /** + * Set read data only + * Set to true, to advise the Reader only to read data values for cells, and to ignore any formatting information. + * Set to false (the default) to advise the Reader to read both data and formatting for cells. + * + * @param boolean $pValue + * + * @return PHPExcel_Reader_IReader + */ + public function setReadDataOnly($pValue = FALSE) { + $this->_readDataOnly = $pValue; + return $this; + } + + /** + * Read charts in workbook? + * If this is true, then the Reader will include any charts that exist in the workbook. + * Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. + * If false (the default) it will ignore any charts defined in the workbook file. + * + * @return boolean + */ + public function getIncludeCharts() { + return $this->_includeCharts; + } + + /** + * Set read charts in workbook + * Set to true, to advise the Reader to include any charts that exist in the workbook. + * Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. + * Set to false (the default) to discard charts. + * + * @param boolean $pValue + * + * @return PHPExcel_Reader_IReader + */ + public function setIncludeCharts($pValue = FALSE) { + $this->_includeCharts = (boolean) $pValue; + return $this; + } + + /** + * Get which sheets to load + * Returns either an array of worksheet names (the list of worksheets that should be loaded), or a null + * indicating that all worksheets in the workbook should be loaded. + * + * @return mixed + */ + public function getLoadSheetsOnly() + { + return $this->_loadSheetsOnly; + } + + /** + * Set which sheets to load + * + * @param mixed $value + * This should be either an array of worksheet names to be loaded, or a string containing a single worksheet name. + * If NULL, then it tells the Reader to read all worksheets in the workbook + * + * @return PHPExcel_Reader_IReader + */ + public function setLoadSheetsOnly($value = NULL) + { if ($value === NULL) return $this->setLoadAllSheets(); $this->_loadSheetsOnly = is_array($value) ? - $value : array($value); - return $this; - } - - /** - * Set all sheets to load - * Tells the Reader to load all worksheets from the workbook. - * - * @return PHPExcel_Reader_IReader - */ - public function setLoadAllSheets() - { - $this->_loadSheetsOnly = NULL; - return $this; - } - - /** - * Read filter - * - * @return PHPExcel_Reader_IReadFilter - */ - public function getReadFilter() { - return $this->_readFilter; - } - - /** - * Set read filter - * - * @param PHPExcel_Reader_IReadFilter $pValue - * @return PHPExcel_Reader_IReader - */ - public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) { - $this->_readFilter = $pValue; - return $this; - } - - /** - * Open file for reading - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - * @return resource - */ - protected function _openFile($pFilename) - { - // Check if file exists - if (!file_exists($pFilename) || !is_readable($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - // Open file - $this->_fileHandle = fopen($pFilename, 'r'); - if ($this->_fileHandle === FALSE) { - throw new PHPExcel_Reader_Exception("Could not open file " . $pFilename . " for reading."); - } - } - - /** - * Can the current PHPExcel_Reader_IReader read the file? - * - * @param string $pFilename - * @return boolean - * @throws PHPExcel_Reader_Exception - */ - public function canRead($pFilename) - { - // Check if file exists - try { - $this->_openFile($pFilename); - } catch (Exception $e) { - return FALSE; - } - - $readable = $this->_isValidFormat(); - fclose ($this->_fileHandle); - return $readable; - } - - /** - * Scan theXML for use of _loadSheetsOnly = NULL; + return $this; + } + + /** + * Read filter + * + * @return PHPExcel_Reader_IReadFilter + */ + public function getReadFilter() { + return $this->_readFilter; + } + + /** + * Set read filter + * + * @param PHPExcel_Reader_IReadFilter $pValue + * @return PHPExcel_Reader_IReader + */ + public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) { + $this->_readFilter = $pValue; + return $this; + } + + /** + * Open file for reading + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + * @return resource + */ + protected function _openFile($pFilename) + { + // Check if file exists + if (!file_exists($pFilename) || !is_readable($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Open file + $this->_fileHandle = fopen($pFilename, 'r'); + if ($this->_fileHandle === FALSE) { + throw new PHPExcel_Reader_Exception("Could not open file " . $pFilename . " for reading."); + } + } + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + try { + $this->_openFile($pFilename); + } catch (Exception $e) { + return FALSE; + } + + $readable = $this->_isValidFormat(); + fclose ($this->_fileHandle); + return $readable; + } + + /** + * Scan theXML for use of securityScan(file_get_contents($filestream)); } } diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index 2942e804b..e92c93eb2 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -21,18 +21,18 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** @@ -44,344 +44,344 @@ */ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { - /** - * Input encoding - * - * @access private - * @var string - */ - private $_inputEncoding = 'UTF-8'; - - /** - * Delimiter - * - * @access private - * @var string - */ - private $_delimiter = ','; - - /** - * Enclosure - * - * @access private - * @var string - */ - private $_enclosure = '"'; - - /** - * Sheet index to read - * - * @access private - * @var int - */ - private $_sheetIndex = 0; - - /** - * Load rows contiguously - * - * @access private - * @var int - */ - private $_contiguous = false; - - /** - * Row counter for loading rows contiguously - * - * @var int - */ - private $_contiguousRow = -1; - - - /** - * Create a new PHPExcel_Reader_CSV - */ - public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - } - - /** - * Validate that the current file is a CSV file - * - * @return boolean - */ - protected function _isValidFormat() - { - return TRUE; - } - - /** - * Set input encoding - * - * @param string $pValue Input encoding - */ - public function setInputEncoding($pValue = 'UTF-8') - { - $this->_inputEncoding = $pValue; - return $this; - } - - /** - * Get input encoding - * - * @return string - */ - public function getInputEncoding() - { - return $this->_inputEncoding; - } - - /** - * Move filepointer past any BOM marker - * - */ - protected function _skipBOM() - { - rewind($this->_fileHandle); - - switch ($this->_inputEncoding) { - case 'UTF-8': - fgets($this->_fileHandle, 4) == "\xEF\xBB\xBF" ? - fseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0); - break; - case 'UTF-16LE': - fgets($this->_fileHandle, 3) == "\xFF\xFE" ? - fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); - break; - case 'UTF-16BE': - fgets($this->_fileHandle, 3) == "\xFE\xFF" ? - fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); - break; - case 'UTF-32LE': - fgets($this->_fileHandle, 5) == "\xFF\xFE\x00\x00" ? - fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); - break; - case 'UTF-32BE': - fgets($this->_fileHandle, 5) == "\x00\x00\xFE\xFF" ? - fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); - break; - default: - break; - } - } - - /** - * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetInfo($pFilename) - { - // Open file - $this->_openFile($pFilename); - if (!$this->_isValidFormat()) { - fclose ($this->_fileHandle); - throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); - } - $fileHandle = $this->_fileHandle; - - // Skip BOM, if any - $this->_skipBOM(); - - $escapeEnclosures = array( "\\" . $this->_enclosure, $this->_enclosure . $this->_enclosure ); - - $worksheetInfo = array(); - $worksheetInfo[0]['worksheetName'] = 'Worksheet'; - $worksheetInfo[0]['lastColumnLetter'] = 'A'; - $worksheetInfo[0]['lastColumnIndex'] = 0; - $worksheetInfo[0]['totalRows'] = 0; - $worksheetInfo[0]['totalColumns'] = 0; - - // Loop through each line of the file in turn - while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { - $worksheetInfo[0]['totalRows']++; - $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1); - } - - $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']); - $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1; - - // Close file - fclose($fileHandle); - - return $worksheetInfo; - } - - /** - * Loads PHPExcel from file - * - * @param string $pFilename - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function load($pFilename) - { - // Create new PHPExcel - $objPHPExcel = new PHPExcel(); - - // Load into this instance - return $this->loadIntoExisting($pFilename, $objPHPExcel); - } - - /** - * Loads PHPExcel from file into PHPExcel instance - * - * @param string $pFilename - * @param PHPExcel $objPHPExcel - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) - { - $lineEnding = ini_get('auto_detect_line_endings'); - ini_set('auto_detect_line_endings', true); - - // Open file - $this->_openFile($pFilename); - if (!$this->_isValidFormat()) { - fclose ($this->_fileHandle); - throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); - } - $fileHandle = $this->_fileHandle; - - // Skip BOM, if any - $this->_skipBOM(); - - // Create new PHPExcel object - while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { - $objPHPExcel->createSheet(); - } - $sheet = $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); - - $escapeEnclosures = array( "\\" . $this->_enclosure, - $this->_enclosure . $this->_enclosure - ); - - // Set our starting row based on whether we're in contiguous mode or not - $currentRow = 1; - if ($this->_contiguous) { - $currentRow = ($this->_contiguousRow == -1) ? $sheet->getHighestRow(): $this->_contiguousRow; - } - - // Loop through each line of the file in turn - while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { - $columnLetter = 'A'; - foreach($rowData as $rowDatum) { - if ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) { - // Unescape enclosures - $rowDatum = str_replace($escapeEnclosures, $this->_enclosure, $rowDatum); - - // Convert encoding if necessary - if ($this->_inputEncoding !== 'UTF-8') { - $rowDatum = PHPExcel_Shared_String::ConvertEncoding($rowDatum, 'UTF-8', $this->_inputEncoding); - } - - // Set cell value - $sheet->getCell($columnLetter . $currentRow)->setValue($rowDatum); - } - ++$columnLetter; - } - ++$currentRow; - } - - // Close file - fclose($fileHandle); - - if ($this->_contiguous) { - $this->_contiguousRow = $currentRow; - } - - ini_set('auto_detect_line_endings', $lineEnding); - - // Return - return $objPHPExcel; - } - - /** - * Get delimiter - * - * @return string - */ - public function getDelimiter() { - return $this->_delimiter; - } - - /** - * Set delimiter - * - * @param string $pValue Delimiter, defaults to , - * @return PHPExcel_Reader_CSV - */ - public function setDelimiter($pValue = ',') { - $this->_delimiter = $pValue; - return $this; - } - - /** - * Get enclosure - * - * @return string - */ - public function getEnclosure() { - return $this->_enclosure; - } - - /** - * Set enclosure - * - * @param string $pValue Enclosure, defaults to " - * @return PHPExcel_Reader_CSV - */ - public function setEnclosure($pValue = '"') { - if ($pValue == '') { - $pValue = '"'; - } - $this->_enclosure = $pValue; - return $this; - } - - /** - * Get sheet index - * - * @return integer - */ - public function getSheetIndex() { - return $this->_sheetIndex; - } - - /** - * Set sheet index - * - * @param integer $pValue Sheet index - * @return PHPExcel_Reader_CSV - */ - public function setSheetIndex($pValue = 0) { - $this->_sheetIndex = $pValue; - return $this; - } - - /** - * Set Contiguous - * - * @param boolean $contiguous - */ - public function setContiguous($contiguous = FALSE) - { - $this->_contiguous = (bool) $contiguous; - if (!$contiguous) { - $this->_contiguousRow = -1; - } - - return $this; - } - - /** - * Get Contiguous - * - * @return boolean - */ - public function getContiguous() { - return $this->_contiguous; - } + /** + * Input encoding + * + * @access private + * @var string + */ + private $_inputEncoding = 'UTF-8'; + + /** + * Delimiter + * + * @access private + * @var string + */ + private $_delimiter = ','; + + /** + * Enclosure + * + * @access private + * @var string + */ + private $_enclosure = '"'; + + /** + * Sheet index to read + * + * @access private + * @var int + */ + private $_sheetIndex = 0; + + /** + * Load rows contiguously + * + * @access private + * @var int + */ + private $_contiguous = false; + + /** + * Row counter for loading rows contiguously + * + * @var int + */ + private $_contiguousRow = -1; + + + /** + * Create a new PHPExcel_Reader_CSV + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + /** + * Validate that the current file is a CSV file + * + * @return boolean + */ + protected function _isValidFormat() + { + return TRUE; + } + + /** + * Set input encoding + * + * @param string $pValue Input encoding + */ + public function setInputEncoding($pValue = 'UTF-8') + { + $this->_inputEncoding = $pValue; + return $this; + } + + /** + * Get input encoding + * + * @return string + */ + public function getInputEncoding() + { + return $this->_inputEncoding; + } + + /** + * Move filepointer past any BOM marker + * + */ + protected function _skipBOM() + { + rewind($this->_fileHandle); + + switch ($this->_inputEncoding) { + case 'UTF-8': + fgets($this->_fileHandle, 4) == "\xEF\xBB\xBF" ? + fseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0); + break; + case 'UTF-16LE': + fgets($this->_fileHandle, 3) == "\xFF\xFE" ? + fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); + break; + case 'UTF-16BE': + fgets($this->_fileHandle, 3) == "\xFE\xFF" ? + fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); + break; + case 'UTF-32LE': + fgets($this->_fileHandle, 5) == "\xFF\xFE\x00\x00" ? + fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); + break; + case 'UTF-32BE': + fgets($this->_fileHandle, 5) == "\x00\x00\xFE\xFF" ? + fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); + break; + default: + break; + } + } + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + + // Skip BOM, if any + $this->_skipBOM(); + + $escapeEnclosures = array( "\\" . $this->_enclosure, $this->_enclosure . $this->_enclosure ); + + $worksheetInfo = array(); + $worksheetInfo[0]['worksheetName'] = 'Worksheet'; + $worksheetInfo[0]['lastColumnLetter'] = 'A'; + $worksheetInfo[0]['lastColumnIndex'] = 0; + $worksheetInfo[0]['totalRows'] = 0; + $worksheetInfo[0]['totalColumns'] = 0; + + // Loop through each line of the file in turn + while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { + $worksheetInfo[0]['totalRows']++; + $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1); + } + + $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']); + $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1; + + // Close file + fclose($fileHandle); + + return $worksheetInfo; + } + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + $lineEnding = ini_get('auto_detect_line_endings'); + ini_set('auto_detect_line_endings', true); + + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + + // Skip BOM, if any + $this->_skipBOM(); + + // Create new PHPExcel object + while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + $objPHPExcel->createSheet(); + } + $sheet = $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); + + $escapeEnclosures = array( "\\" . $this->_enclosure, + $this->_enclosure . $this->_enclosure + ); + + // Set our starting row based on whether we're in contiguous mode or not + $currentRow = 1; + if ($this->_contiguous) { + $currentRow = ($this->_contiguousRow == -1) ? $sheet->getHighestRow(): $this->_contiguousRow; + } + + // Loop through each line of the file in turn + while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { + $columnLetter = 'A'; + foreach($rowData as $rowDatum) { + if ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) { + // Unescape enclosures + $rowDatum = str_replace($escapeEnclosures, $this->_enclosure, $rowDatum); + + // Convert encoding if necessary + if ($this->_inputEncoding !== 'UTF-8') { + $rowDatum = PHPExcel_Shared_String::ConvertEncoding($rowDatum, 'UTF-8', $this->_inputEncoding); + } + + // Set cell value + $sheet->getCell($columnLetter . $currentRow)->setValue($rowDatum); + } + ++$columnLetter; + } + ++$currentRow; + } + + // Close file + fclose($fileHandle); + + if ($this->_contiguous) { + $this->_contiguousRow = $currentRow; + } + + ini_set('auto_detect_line_endings', $lineEnding); + + // Return + return $objPHPExcel; + } + + /** + * Get delimiter + * + * @return string + */ + public function getDelimiter() { + return $this->_delimiter; + } + + /** + * Set delimiter + * + * @param string $pValue Delimiter, defaults to , + * @return PHPExcel_Reader_CSV + */ + public function setDelimiter($pValue = ',') { + $this->_delimiter = $pValue; + return $this; + } + + /** + * Get enclosure + * + * @return string + */ + public function getEnclosure() { + return $this->_enclosure; + } + + /** + * Set enclosure + * + * @param string $pValue Enclosure, defaults to " + * @return PHPExcel_Reader_CSV + */ + public function setEnclosure($pValue = '"') { + if ($pValue == '') { + $pValue = '"'; + } + $this->_enclosure = $pValue; + return $this; + } + + /** + * Get sheet index + * + * @return integer + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param integer $pValue Sheet index + * @return PHPExcel_Reader_CSV + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + + /** + * Set Contiguous + * + * @param boolean $contiguous + */ + public function setContiguous($contiguous = FALSE) + { + $this->_contiguous = (bool) $contiguous; + if (!$contiguous) { + $this->_contiguousRow = -1; + } + + return $this; + } + + /** + * Get Contiguous + * + * @return boolean + */ + public function getContiguous() { + return $this->_contiguous; + } } diff --git a/Classes/PHPExcel/Reader/DefaultReadFilter.php b/Classes/PHPExcel/Reader/DefaultReadFilter.php index 6fb5eb334..7caf26058 100644 --- a/Classes/PHPExcel/Reader/DefaultReadFilter.php +++ b/Classes/PHPExcel/Reader/DefaultReadFilter.php @@ -21,18 +21,18 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** @@ -44,15 +44,15 @@ */ class PHPExcel_Reader_DefaultReadFilter implements PHPExcel_Reader_IReadFilter { - /** - * Should this cell be read? - * - * @param $column String column index - * @param $row Row index - * @param $worksheetName Optional worksheet name - * @return boolean - */ - public function readCell($column, $row, $worksheetName = '') { - return true; - } + /** + * Should this cell be read? + * + * @param $column String column index + * @param $row Row index + * @param $worksheetName Optional worksheet name + * @return boolean + */ + public function readCell($column, $row, $worksheetName = '') { + return true; + } } diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index 38bb349ac..3b62b7515 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -21,18 +21,18 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** @@ -44,766 +44,766 @@ */ class PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { - /** - * Formats - * - * @var array - */ - protected $_styles = array(); - - /** - * Character set used in the file - * - * @var string - */ - protected $_charSet = 'UTF-8'; - - - /** - * Create a new PHPExcel_Reader_Excel2003XML - */ - public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - } - - - /** - * Can the current PHPExcel_Reader_IReader read the file? - * - * @param string $pFilename - * @return boolean - * @throws PHPExcel_Reader_Exception - */ - public function canRead($pFilename) - { - - // Office xmlns:o="urn:schemas-microsoft-com:office:office" - // Excel xmlns:x="urn:schemas-microsoft-com:office:excel" - // XML Spreadsheet xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" - // Spreadsheet component xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" - // XML schema xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" - // XML data type xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" - // MS-persist recordset xmlns:rs="urn:schemas-microsoft-com:rowset" - // Rowset xmlns:z="#RowsetSchema" - // - - $signature = array( - '' - ); - - // Open file - $this->_openFile($pFilename); - $fileHandle = $this->_fileHandle; - - // Read sample data (first 2 KB will do) - $data = fread($fileHandle, 2048); - fclose($fileHandle); - - $valid = true; - foreach($signature as $match) { - // every part of the signature must be present - if (strpos($data, $match) === false) { - $valid = false; - break; - } - } - - // Retrieve charset encoding - if(preg_match('//um',$data,$matches)) { - $this->_charSet = strtoupper($matches[1]); - } -// echo 'Character Set is ',$this->_charSet,'
'; - - return $valid; - } - - - /** - * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetNames($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - if (!$this->canRead($pFilename)) { - throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); - } - - $worksheetNames = array(); - - $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $namespaces = $xml->getNamespaces(true); - - $xml_ss = $xml->children($namespaces['ss']); - foreach($xml_ss->Worksheet as $worksheet) { - $worksheet_ss = $worksheet->attributes($namespaces['ss']); - $worksheetNames[] = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet); - } - - return $worksheetNames; - } - - - /** - * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetInfo($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $worksheetInfo = array(); - - $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $namespaces = $xml->getNamespaces(true); - - $worksheetID = 1; - $xml_ss = $xml->children($namespaces['ss']); - foreach($xml_ss->Worksheet as $worksheet) { - $worksheet_ss = $worksheet->attributes($namespaces['ss']); - - $tmpInfo = array(); - $tmpInfo['worksheetName'] = ''; - $tmpInfo['lastColumnLetter'] = 'A'; - $tmpInfo['lastColumnIndex'] = 0; - $tmpInfo['totalRows'] = 0; - $tmpInfo['totalColumns'] = 0; - - if (isset($worksheet_ss['Name'])) { - $tmpInfo['worksheetName'] = (string) $worksheet_ss['Name']; - } else { - $tmpInfo['worksheetName'] = "Worksheet_{$worksheetID}"; - } - - if (isset($worksheet->Table->Row)) { - $rowIndex = 0; - - foreach($worksheet->Table->Row as $rowData) { - $columnIndex = 0; - $rowHasData = false; - - foreach($rowData->Cell as $cell) { - if (isset($cell->Data)) { - $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); - $rowHasData = true; - } - - ++$columnIndex; - } - - ++$rowIndex; - - if ($rowHasData) { - $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); - } - } - } - - $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); - $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; - - $worksheetInfo[] = $tmpInfo; - ++$worksheetID; - } - - return $worksheetInfo; - } + /** + * Formats + * + * @var array + */ + protected $_styles = array(); + + /** + * Character set used in the file + * + * @var string + */ + protected $_charSet = 'UTF-8'; + + + /** + * Create a new PHPExcel_Reader_Excel2003XML + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + + // Office xmlns:o="urn:schemas-microsoft-com:office:office" + // Excel xmlns:x="urn:schemas-microsoft-com:office:excel" + // XML Spreadsheet xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" + // Spreadsheet component xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" + // XML schema xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" + // XML data type xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" + // MS-persist recordset xmlns:rs="urn:schemas-microsoft-com:rowset" + // Rowset xmlns:z="#RowsetSchema" + // + + $signature = array( + '' + ); + + // Open file + $this->_openFile($pFilename); + $fileHandle = $this->_fileHandle; + + // Read sample data (first 2 KB will do) + $data = fread($fileHandle, 2048); + fclose($fileHandle); + + $valid = true; + foreach($signature as $match) { + // every part of the signature must be present + if (strpos($data, $match) === false) { + $valid = false; + break; + } + } + + // Retrieve charset encoding + if(preg_match('//um',$data,$matches)) { + $this->_charSet = strtoupper($matches[1]); + } +// echo 'Character Set is ',$this->_charSet,'
'; + + return $valid; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + if (!$this->canRead($pFilename)) { + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + + $worksheetNames = array(); + + $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespaces = $xml->getNamespaces(true); + + $xml_ss = $xml->children($namespaces['ss']); + foreach($xml_ss->Worksheet as $worksheet) { + $worksheet_ss = $worksheet->attributes($namespaces['ss']); + $worksheetNames[] = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet); + } + + return $worksheetNames; + } /** - * Loads PHPExcel from file - * - * @param string $pFilename - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function load($pFilename) - { - // Create new PHPExcel - $objPHPExcel = new PHPExcel(); + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespaces = $xml->getNamespaces(true); + + $worksheetID = 1; + $xml_ss = $xml->children($namespaces['ss']); + foreach($xml_ss->Worksheet as $worksheet) { + $worksheet_ss = $worksheet->attributes($namespaces['ss']); + + $tmpInfo = array(); + $tmpInfo['worksheetName'] = ''; + $tmpInfo['lastColumnLetter'] = 'A'; + $tmpInfo['lastColumnIndex'] = 0; + $tmpInfo['totalRows'] = 0; + $tmpInfo['totalColumns'] = 0; + + if (isset($worksheet_ss['Name'])) { + $tmpInfo['worksheetName'] = (string) $worksheet_ss['Name']; + } else { + $tmpInfo['worksheetName'] = "Worksheet_{$worksheetID}"; + } + + if (isset($worksheet->Table->Row)) { + $rowIndex = 0; + + foreach($worksheet->Table->Row as $rowData) { + $columnIndex = 0; + $rowHasData = false; + + foreach($rowData->Cell as $cell) { + if (isset($cell->Data)) { + $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); + $rowHasData = true; + } + + ++$columnIndex; + } + + ++$rowIndex; + + if ($rowHasData) { + $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); + } + } + } + + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; + + $worksheetInfo[] = $tmpInfo; + ++$worksheetID; + } + + return $worksheetInfo; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); $objPHPExcel->removeSheetByIndex(0); - // Load into this instance - return $this->loadIntoExisting($pFilename, $objPHPExcel); - } - - - protected static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { - $styleAttributeValue = strtolower($styleAttributeValue); - foreach($styleList as $style) { - if ($styleAttributeValue == strtolower($style)) { - $styleAttributeValue = $style; - return true; - } - } - return false; - } - - - /** - * pixel units to excel width units(units of 1/256th of a character width) - * @param pxs - * @return - */ - protected static function _pixel2WidthUnits($pxs) { - $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); - - $widthUnits = 256 * ($pxs / 7); - $widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)]; - return $widthUnits; - } - - - /** - * excel width units(units of 1/256th of a character width) to pixel units - * @param widthUnits - * @return - */ - protected static function _widthUnits2Pixel($widthUnits) { - $pixels = ($widthUnits / 256) * 7; - $offsetWidthUnits = $widthUnits % 256; - $pixels += round($offsetWidthUnits / (256 / 7)); - return $pixels; - } - - - protected static function _hex2str($hex) { - return chr(hexdec($hex[1])); - } - - - /** - * Loads PHPExcel from file into PHPExcel instance - * - * @param string $pFilename - * @param PHPExcel $objPHPExcel - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) - { - $fromFormats = array('\-', '\ '); - $toFormats = array('-', ' '); - - $underlineStyles = array ( - PHPExcel_Style_Font::UNDERLINE_NONE, - PHPExcel_Style_Font::UNDERLINE_DOUBLE, - PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING, - PHPExcel_Style_Font::UNDERLINE_SINGLE, - PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING - ); - $verticalAlignmentStyles = array ( - PHPExcel_Style_Alignment::VERTICAL_BOTTOM, - PHPExcel_Style_Alignment::VERTICAL_TOP, - PHPExcel_Style_Alignment::VERTICAL_CENTER, - PHPExcel_Style_Alignment::VERTICAL_JUSTIFY - ); - $horizontalAlignmentStyles = array ( - PHPExcel_Style_Alignment::HORIZONTAL_GENERAL, - PHPExcel_Style_Alignment::HORIZONTAL_LEFT, - PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, - PHPExcel_Style_Alignment::HORIZONTAL_CENTER, - PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS, - PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY - ); - - $timezoneObj = new DateTimeZone('Europe/London'); - $GMT = new DateTimeZone('UTC'); - - - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - if (!$this->canRead($pFilename)) { - throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); - } - - $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $namespaces = $xml->getNamespaces(true); - - $docProps = $objPHPExcel->getProperties(); - if (isset($xml->DocumentProperties[0])) { - foreach($xml->DocumentProperties[0] as $propertyName => $propertyValue) { - switch ($propertyName) { - case 'Title' : - $docProps->setTitle(self::_convertStringEncoding($propertyValue,$this->_charSet)); - break; - case 'Subject' : - $docProps->setSubject(self::_convertStringEncoding($propertyValue,$this->_charSet)); - break; - case 'Author' : - $docProps->setCreator(self::_convertStringEncoding($propertyValue,$this->_charSet)); - break; - case 'Created' : - $creationDate = strtotime($propertyValue); - $docProps->setCreated($creationDate); - break; - case 'LastAuthor' : - $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue,$this->_charSet)); - break; - case 'LastSaved' : - $lastSaveDate = strtotime($propertyValue); - $docProps->setModified($lastSaveDate); - break; - case 'Company' : - $docProps->setCompany(self::_convertStringEncoding($propertyValue,$this->_charSet)); - break; - case 'Category' : - $docProps->setCategory(self::_convertStringEncoding($propertyValue,$this->_charSet)); - break; - case 'Manager' : - $docProps->setManager(self::_convertStringEncoding($propertyValue,$this->_charSet)); - break; - case 'Keywords' : - $docProps->setKeywords(self::_convertStringEncoding($propertyValue,$this->_charSet)); - break; - case 'Description' : - $docProps->setDescription(self::_convertStringEncoding($propertyValue,$this->_charSet)); - break; - } - } - } - if (isset($xml->CustomDocumentProperties)) { - foreach($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { - $propertyAttributes = $propertyValue->attributes($namespaces['dt']); - $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/','PHPExcel_Reader_Excel2003XML::_hex2str',$propertyName); - $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN; - switch((string) $propertyAttributes) { - case 'string' : - $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; - $propertyValue = trim($propertyValue); - break; - case 'boolean' : - $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; - $propertyValue = (bool) $propertyValue; - break; - case 'integer' : - $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_INTEGER; - $propertyValue = intval($propertyValue); - break; - case 'float' : - $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; - $propertyValue = floatval($propertyValue); - break; - case 'dateTime.tz' : - $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; - $propertyValue = strtotime(trim($propertyValue)); - break; - } - $docProps->setCustomProperty($propertyName,$propertyValue,$propertyType); - } - } - - foreach($xml->Styles[0] as $style) { - $style_ss = $style->attributes($namespaces['ss']); - $styleID = (string) $style_ss['ID']; -// echo 'Style ID = '.$styleID.'
'; - if ($styleID == 'Default') { - $this->_styles['Default'] = array(); - } else { - $this->_styles[$styleID] = $this->_styles['Default']; - } - foreach ($style as $styleType => $styleData) { - $styleAttributes = $styleData->attributes($namespaces['ss']); -// echo $styleType.'
'; - switch ($styleType) { - case 'Alignment' : - foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { -// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; - $styleAttributeValue = (string) $styleAttributeValue; - switch ($styleAttributeKey) { - case 'Vertical' : - if (self::identifyFixedStyleValue($verticalAlignmentStyles,$styleAttributeValue)) { - $this->_styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; - } - break; - case 'Horizontal' : - if (self::identifyFixedStyleValue($horizontalAlignmentStyles,$styleAttributeValue)) { - $this->_styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; - } - break; - case 'WrapText' : - $this->_styles[$styleID]['alignment']['wrap'] = true; - break; - } - } - break; - case 'Borders' : - foreach($styleData->Border as $borderStyle) { - $borderAttributes = $borderStyle->attributes($namespaces['ss']); - $thisBorder = array(); - foreach($borderAttributes as $borderStyleKey => $borderStyleValue) { -// echo $borderStyleKey.' = '.$borderStyleValue.'
'; - switch ($borderStyleKey) { - case 'LineStyle' : - $thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; -// $thisBorder['style'] = $borderStyleValue; - break; - case 'Weight' : -// $thisBorder['style'] = $borderStyleValue; - break; - case 'Position' : - $borderPosition = strtolower($borderStyleValue); - break; - case 'Color' : - $borderColour = substr($borderStyleValue,1); - $thisBorder['color']['rgb'] = $borderColour; - break; - } - } - if (!empty($thisBorder)) { - if (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) { - $this->_styles[$styleID]['borders'][$borderPosition] = $thisBorder; - } - } - } - break; - case 'Font' : - foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { -// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; - $styleAttributeValue = (string) $styleAttributeValue; - switch ($styleAttributeKey) { - case 'FontName' : - $this->_styles[$styleID]['font']['name'] = $styleAttributeValue; - break; - case 'Size' : - $this->_styles[$styleID]['font']['size'] = $styleAttributeValue; - break; - case 'Color' : - $this->_styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue,1); - break; - case 'Bold' : - $this->_styles[$styleID]['font']['bold'] = true; - break; - case 'Italic' : - $this->_styles[$styleID]['font']['italic'] = true; - break; - case 'Underline' : - if (self::identifyFixedStyleValue($underlineStyles,$styleAttributeValue)) { - $this->_styles[$styleID]['font']['underline'] = $styleAttributeValue; - } - break; - } - } - break; - case 'Interior' : - foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { -// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; - switch ($styleAttributeKey) { - case 'Color' : - $this->_styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue,1); - break; - } - } - break; - case 'NumberFormat' : - foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { -// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; - $styleAttributeValue = str_replace($fromFormats,$toFormats,$styleAttributeValue); - switch ($styleAttributeValue) { - case 'Short Date' : - $styleAttributeValue = 'dd/mm/yyyy'; - break; - } - if ($styleAttributeValue > '') { - $this->_styles[$styleID]['numberformat']['code'] = $styleAttributeValue; - } - } - break; - case 'Protection' : - foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { -// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; - } - break; - } - } -// print_r($this->_styles[$styleID]); -// echo '
'; - } -// echo '
'; - - $worksheetID = 0; - $xml_ss = $xml->children($namespaces['ss']); - - foreach($xml_ss->Worksheet as $worksheet) { - $worksheet_ss = $worksheet->attributes($namespaces['ss']); - - if ((isset($this->_loadSheetsOnly)) && (isset($worksheet_ss['Name'])) && - (!in_array($worksheet_ss['Name'], $this->_loadSheetsOnly))) { - continue; - } - -// echo '

Worksheet: ',$worksheet_ss['Name'],'

'; + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + + protected static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { + $styleAttributeValue = strtolower($styleAttributeValue); + foreach($styleList as $style) { + if ($styleAttributeValue == strtolower($style)) { + $styleAttributeValue = $style; + return true; + } + } + return false; + } + + + /** + * pixel units to excel width units(units of 1/256th of a character width) + * @param pxs + * @return + */ + protected static function _pixel2WidthUnits($pxs) { + $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); + + $widthUnits = 256 * ($pxs / 7); + $widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)]; + return $widthUnits; + } + + + /** + * excel width units(units of 1/256th of a character width) to pixel units + * @param widthUnits + * @return + */ + protected static function _widthUnits2Pixel($widthUnits) { + $pixels = ($widthUnits / 256) * 7; + $offsetWidthUnits = $widthUnits % 256; + $pixels += round($offsetWidthUnits / (256 / 7)); + return $pixels; + } + + + protected static function _hex2str($hex) { + return chr(hexdec($hex[1])); + } + + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + $fromFormats = array('\-', '\ '); + $toFormats = array('-', ' '); + + $underlineStyles = array ( + PHPExcel_Style_Font::UNDERLINE_NONE, + PHPExcel_Style_Font::UNDERLINE_DOUBLE, + PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING, + PHPExcel_Style_Font::UNDERLINE_SINGLE, + PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING + ); + $verticalAlignmentStyles = array ( + PHPExcel_Style_Alignment::VERTICAL_BOTTOM, + PHPExcel_Style_Alignment::VERTICAL_TOP, + PHPExcel_Style_Alignment::VERTICAL_CENTER, + PHPExcel_Style_Alignment::VERTICAL_JUSTIFY + ); + $horizontalAlignmentStyles = array ( + PHPExcel_Style_Alignment::HORIZONTAL_GENERAL, + PHPExcel_Style_Alignment::HORIZONTAL_LEFT, + PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS, + PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY + ); + + $timezoneObj = new DateTimeZone('Europe/London'); + $GMT = new DateTimeZone('UTC'); + + + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + if (!$this->canRead($pFilename)) { + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + + $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespaces = $xml->getNamespaces(true); + + $docProps = $objPHPExcel->getProperties(); + if (isset($xml->DocumentProperties[0])) { + foreach($xml->DocumentProperties[0] as $propertyName => $propertyValue) { + switch ($propertyName) { + case 'Title' : + $docProps->setTitle(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Subject' : + $docProps->setSubject(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Author' : + $docProps->setCreator(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Created' : + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + break; + case 'LastAuthor' : + $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'LastSaved' : + $lastSaveDate = strtotime($propertyValue); + $docProps->setModified($lastSaveDate); + break; + case 'Company' : + $docProps->setCompany(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Category' : + $docProps->setCategory(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Manager' : + $docProps->setManager(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Keywords' : + $docProps->setKeywords(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Description' : + $docProps->setDescription(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + } + } + } + if (isset($xml->CustomDocumentProperties)) { + foreach($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { + $propertyAttributes = $propertyValue->attributes($namespaces['dt']); + $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/','PHPExcel_Reader_Excel2003XML::_hex2str',$propertyName); + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN; + switch((string) $propertyAttributes) { + case 'string' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; + $propertyValue = trim($propertyValue); + break; + case 'boolean' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; + $propertyValue = (bool) $propertyValue; + break; + case 'integer' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_INTEGER; + $propertyValue = intval($propertyValue); + break; + case 'float' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; + $propertyValue = floatval($propertyValue); + break; + case 'dateTime.tz' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; + $propertyValue = strtotime(trim($propertyValue)); + break; + } + $docProps->setCustomProperty($propertyName,$propertyValue,$propertyType); + } + } + + foreach($xml->Styles[0] as $style) { + $style_ss = $style->attributes($namespaces['ss']); + $styleID = (string) $style_ss['ID']; +// echo 'Style ID = '.$styleID.'
'; + if ($styleID == 'Default') { + $this->_styles['Default'] = array(); + } else { + $this->_styles[$styleID] = $this->_styles['Default']; + } + foreach ($style as $styleType => $styleData) { + $styleAttributes = $styleData->attributes($namespaces['ss']); +// echo $styleType.'
'; + switch ($styleType) { + case 'Alignment' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; + $styleAttributeValue = (string) $styleAttributeValue; + switch ($styleAttributeKey) { + case 'Vertical' : + if (self::identifyFixedStyleValue($verticalAlignmentStyles,$styleAttributeValue)) { + $this->_styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; + } + break; + case 'Horizontal' : + if (self::identifyFixedStyleValue($horizontalAlignmentStyles,$styleAttributeValue)) { + $this->_styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; + } + break; + case 'WrapText' : + $this->_styles[$styleID]['alignment']['wrap'] = true; + break; + } + } + break; + case 'Borders' : + foreach($styleData->Border as $borderStyle) { + $borderAttributes = $borderStyle->attributes($namespaces['ss']); + $thisBorder = array(); + foreach($borderAttributes as $borderStyleKey => $borderStyleValue) { +// echo $borderStyleKey.' = '.$borderStyleValue.'
'; + switch ($borderStyleKey) { + case 'LineStyle' : + $thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; +// $thisBorder['style'] = $borderStyleValue; + break; + case 'Weight' : +// $thisBorder['style'] = $borderStyleValue; + break; + case 'Position' : + $borderPosition = strtolower($borderStyleValue); + break; + case 'Color' : + $borderColour = substr($borderStyleValue,1); + $thisBorder['color']['rgb'] = $borderColour; + break; + } + } + if (!empty($thisBorder)) { + if (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) { + $this->_styles[$styleID]['borders'][$borderPosition] = $thisBorder; + } + } + } + break; + case 'Font' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; + $styleAttributeValue = (string) $styleAttributeValue; + switch ($styleAttributeKey) { + case 'FontName' : + $this->_styles[$styleID]['font']['name'] = $styleAttributeValue; + break; + case 'Size' : + $this->_styles[$styleID]['font']['size'] = $styleAttributeValue; + break; + case 'Color' : + $this->_styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue,1); + break; + case 'Bold' : + $this->_styles[$styleID]['font']['bold'] = true; + break; + case 'Italic' : + $this->_styles[$styleID]['font']['italic'] = true; + break; + case 'Underline' : + if (self::identifyFixedStyleValue($underlineStyles,$styleAttributeValue)) { + $this->_styles[$styleID]['font']['underline'] = $styleAttributeValue; + } + break; + } + } + break; + case 'Interior' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; + switch ($styleAttributeKey) { + case 'Color' : + $this->_styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue,1); + break; + } + } + break; + case 'NumberFormat' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; + $styleAttributeValue = str_replace($fromFormats,$toFormats,$styleAttributeValue); + switch ($styleAttributeValue) { + case 'Short Date' : + $styleAttributeValue = 'dd/mm/yyyy'; + break; + } + if ($styleAttributeValue > '') { + $this->_styles[$styleID]['numberformat']['code'] = $styleAttributeValue; + } + } + break; + case 'Protection' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; + } + break; + } + } +// print_r($this->_styles[$styleID]); +// echo '
'; + } +// echo '
'; + + $worksheetID = 0; + $xml_ss = $xml->children($namespaces['ss']); + + foreach($xml_ss->Worksheet as $worksheet) { + $worksheet_ss = $worksheet->attributes($namespaces['ss']); + + if ((isset($this->_loadSheetsOnly)) && (isset($worksheet_ss['Name'])) && + (!in_array($worksheet_ss['Name'], $this->_loadSheetsOnly))) { + continue; + } + +// echo '

Worksheet: ',$worksheet_ss['Name'],'

'; // - // Create new Worksheet - $objPHPExcel->createSheet(); - $objPHPExcel->setActiveSheetIndex($worksheetID); - if (isset($worksheet_ss['Name'])) { - $worksheetName = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet); - // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in - // formula cells... during the load, all formulae should be correct, and we're simply bringing - // the worksheet name in line with the formula, not the reverse - $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); - } - - $columnID = 'A'; - if (isset($worksheet->Table->Column)) { - foreach($worksheet->Table->Column as $columnData) { - $columnData_ss = $columnData->attributes($namespaces['ss']); - if (isset($columnData_ss['Index'])) { - $columnID = PHPExcel_Cell::stringFromColumnIndex($columnData_ss['Index']-1); - } - if (isset($columnData_ss['Width'])) { - $columnWidth = $columnData_ss['Width']; -// echo 'Setting column width for '.$columnID.' to '.$columnWidth.'
'; - $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setWidth($columnWidth / 5.4); - } - ++$columnID; - } - } - - $rowID = 1; - if (isset($worksheet->Table->Row)) { + // Create new Worksheet + $objPHPExcel->createSheet(); + $objPHPExcel->setActiveSheetIndex($worksheetID); + if (isset($worksheet_ss['Name'])) { + $worksheetName = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in + // formula cells... during the load, all formulae should be correct, and we're simply bringing + // the worksheet name in line with the formula, not the reverse + $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + } + + $columnID = 'A'; + if (isset($worksheet->Table->Column)) { + foreach($worksheet->Table->Column as $columnData) { + $columnData_ss = $columnData->attributes($namespaces['ss']); + if (isset($columnData_ss['Index'])) { + $columnID = PHPExcel_Cell::stringFromColumnIndex($columnData_ss['Index']-1); + } + if (isset($columnData_ss['Width'])) { + $columnWidth = $columnData_ss['Width']; +// echo 'Setting column width for '.$columnID.' to '.$columnWidth.'
'; + $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setWidth($columnWidth / 5.4); + } + ++$columnID; + } + } + + $rowID = 1; + if (isset($worksheet->Table->Row)) { $additionalMergedCells = 0; - foreach($worksheet->Table->Row as $rowData) { - $rowHasData = false; - $row_ss = $rowData->attributes($namespaces['ss']); - if (isset($row_ss['Index'])) { - $rowID = (integer) $row_ss['Index']; - } -// echo 'Row '.$rowID.'
'; - - $columnID = 'A'; - foreach($rowData->Cell as $cell) { - - $cell_ss = $cell->attributes($namespaces['ss']); - if (isset($cell_ss['Index'])) { - $columnID = PHPExcel_Cell::stringFromColumnIndex($cell_ss['Index']-1); - } - $cellRange = $columnID.$rowID; - - if ($this->getReadFilter() !== NULL) { - if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { - continue; - } - } - - if ((isset($cell_ss['MergeAcross'])) || (isset($cell_ss['MergeDown']))) { - $columnTo = $columnID; - if (isset($cell_ss['MergeAcross'])) { + foreach($worksheet->Table->Row as $rowData) { + $rowHasData = false; + $row_ss = $rowData->attributes($namespaces['ss']); + if (isset($row_ss['Index'])) { + $rowID = (integer) $row_ss['Index']; + } +// echo 'Row '.$rowID.'
'; + + $columnID = 'A'; + foreach($rowData->Cell as $cell) { + + $cell_ss = $cell->attributes($namespaces['ss']); + if (isset($cell_ss['Index'])) { + $columnID = PHPExcel_Cell::stringFromColumnIndex($cell_ss['Index']-1); + } + $cellRange = $columnID.$rowID; + + if ($this->getReadFilter() !== NULL) { + if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { + continue; + } + } + + if ((isset($cell_ss['MergeAcross'])) || (isset($cell_ss['MergeDown']))) { + $columnTo = $columnID; + if (isset($cell_ss['MergeAcross'])) { $additionalMergedCells += (int)$cell_ss['MergeAcross']; - $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cell_ss['MergeAcross'] -1); - } - $rowTo = $rowID; - if (isset($cell_ss['MergeDown'])) { - $rowTo = $rowTo + $cell_ss['MergeDown']; - } - $cellRange .= ':'.$columnTo.$rowTo; - $objPHPExcel->getActiveSheet()->mergeCells($cellRange); - } - - $cellIsSet = $hasCalculatedValue = false; - $cellDataFormula = ''; - if (isset($cell_ss['Formula'])) { - $cellDataFormula = $cell_ss['Formula']; - // added this as a check for array formulas - if (isset($cell_ss['ArrayRange'])) { - $cellDataCSEFormula = $cell_ss['ArrayRange']; -// echo "found an array formula at ".$columnID.$rowID."
"; - } - $hasCalculatedValue = true; - } - if (isset($cell->Data)) { - $cellValue = $cellData = $cell->Data; - $type = PHPExcel_Cell_DataType::TYPE_NULL; - $cellData_ss = $cellData->attributes($namespaces['ss']); - if (isset($cellData_ss['Type'])) { - $cellDataType = $cellData_ss['Type']; - switch ($cellDataType) { - /* - const TYPE_STRING = 's'; - const TYPE_FORMULA = 'f'; - const TYPE_NUMERIC = 'n'; - const TYPE_BOOL = 'b'; - const TYPE_NULL = 'null'; - const TYPE_INLINE = 'inlineStr'; - const TYPE_ERROR = 'e'; - */ - case 'String' : - $cellValue = self::_convertStringEncoding($cellValue,$this->_charSet); - $type = PHPExcel_Cell_DataType::TYPE_STRING; - break; - case 'Number' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $cellValue = (float) $cellValue; - if (floor($cellValue) == $cellValue) { - $cellValue = (integer) $cellValue; - } - break; - case 'Boolean' : - $type = PHPExcel_Cell_DataType::TYPE_BOOL; - $cellValue = ($cellValue != 0); - break; - case 'DateTime' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $cellValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellValue)); - break; - case 'Error' : - $type = PHPExcel_Cell_DataType::TYPE_ERROR; - break; - } - } - - if ($hasCalculatedValue) { -// echo 'FORMULA
'; - $type = PHPExcel_Cell_DataType::TYPE_FORMULA; - $columnNumber = PHPExcel_Cell::columnIndexFromString($columnID); - if (substr($cellDataFormula,0,3) == 'of:') { - $cellDataFormula = substr($cellDataFormula,3); -// echo 'Before: ',$cellDataFormula,'
'; - $temp = explode('"',$cellDataFormula); - $key = false; - foreach($temp as &$value) { - // Only replace in alternate array entries (i.e. non-quoted blocks) - if ($key = !$key) { - $value = str_replace(array('[.','.',']'),'',$value); - } - } - } else { - // Convert R1C1 style references to A1 style references (but only when not quoted) -// echo 'Before: ',$cellDataFormula,'
'; - $temp = explode('"',$cellDataFormula); - $key = false; - foreach($temp as &$value) { - // Only replace in alternate array entries (i.e. non-quoted blocks) - if ($key = !$key) { - preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); - // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way - // through the formula from left to right. Reversing means that we work right to left.through - // the formula - $cellReferences = array_reverse($cellReferences); - // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, - // then modify the formula to use that new reference - foreach($cellReferences as $cellReference) { - $rowReference = $cellReference[2][0]; - // Empty R reference is the current row - if ($rowReference == '') $rowReference = $rowID; - // Bracketed R references are relative to the current row - if ($rowReference{0} == '[') $rowReference = $rowID + trim($rowReference,'[]'); - $columnReference = $cellReference[4][0]; - // Empty C reference is the current column - if ($columnReference == '') $columnReference = $columnNumber; - // Bracketed C references are relative to the current column - if ($columnReference{0} == '[') $columnReference = $columnNumber + trim($columnReference,'[]'); - $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; - $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0])); - } - } - } - } - unset($value); - // Then rebuild the formula string - $cellDataFormula = implode('"',$temp); -// echo 'After: ',$cellDataFormula,'
'; - } - -// echo 'Cell '.$columnID.$rowID.' is a '.$type.' with a value of '.(($hasCalculatedValue) ? $cellDataFormula : $cellValue).'
'; + $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cell_ss['MergeAcross'] -1); + } + $rowTo = $rowID; + if (isset($cell_ss['MergeDown'])) { + $rowTo = $rowTo + $cell_ss['MergeDown']; + } + $cellRange .= ':'.$columnTo.$rowTo; + $objPHPExcel->getActiveSheet()->mergeCells($cellRange); + } + + $cellIsSet = $hasCalculatedValue = false; + $cellDataFormula = ''; + if (isset($cell_ss['Formula'])) { + $cellDataFormula = $cell_ss['Formula']; + // added this as a check for array formulas + if (isset($cell_ss['ArrayRange'])) { + $cellDataCSEFormula = $cell_ss['ArrayRange']; +// echo "found an array formula at ".$columnID.$rowID."
"; + } + $hasCalculatedValue = true; + } + if (isset($cell->Data)) { + $cellValue = $cellData = $cell->Data; + $type = PHPExcel_Cell_DataType::TYPE_NULL; + $cellData_ss = $cellData->attributes($namespaces['ss']); + if (isset($cellData_ss['Type'])) { + $cellDataType = $cellData_ss['Type']; + switch ($cellDataType) { + /* + const TYPE_STRING = 's'; + const TYPE_FORMULA = 'f'; + const TYPE_NUMERIC = 'n'; + const TYPE_BOOL = 'b'; + const TYPE_NULL = 'null'; + const TYPE_INLINE = 'inlineStr'; + const TYPE_ERROR = 'e'; + */ + case 'String' : + $cellValue = self::_convertStringEncoding($cellValue,$this->_charSet); + $type = PHPExcel_Cell_DataType::TYPE_STRING; + break; + case 'Number' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $cellValue = (float) $cellValue; + if (floor($cellValue) == $cellValue) { + $cellValue = (integer) $cellValue; + } + break; + case 'Boolean' : + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $cellValue = ($cellValue != 0); + break; + case 'DateTime' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $cellValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellValue)); + break; + case 'Error' : + $type = PHPExcel_Cell_DataType::TYPE_ERROR; + break; + } + } + + if ($hasCalculatedValue) { +// echo 'FORMULA
'; + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; + $columnNumber = PHPExcel_Cell::columnIndexFromString($columnID); + if (substr($cellDataFormula,0,3) == 'of:') { + $cellDataFormula = substr($cellDataFormula,3); +// echo 'Before: ',$cellDataFormula,'
'; + $temp = explode('"',$cellDataFormula); + $key = false; + foreach($temp as &$value) { + // Only replace in alternate array entries (i.e. non-quoted blocks) + if ($key = !$key) { + $value = str_replace(array('[.','.',']'),'',$value); + } + } + } else { + // Convert R1C1 style references to A1 style references (but only when not quoted) +// echo 'Before: ',$cellDataFormula,'
'; + $temp = explode('"',$cellDataFormula); + $key = false; + foreach($temp as &$value) { + // Only replace in alternate array entries (i.e. non-quoted blocks) + if ($key = !$key) { + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way + // through the formula from left to right. Reversing means that we work right to left.through + // the formula + $cellReferences = array_reverse($cellReferences); + // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, + // then modify the formula to use that new reference + foreach($cellReferences as $cellReference) { + $rowReference = $cellReference[2][0]; + // Empty R reference is the current row + if ($rowReference == '') $rowReference = $rowID; + // Bracketed R references are relative to the current row + if ($rowReference{0} == '[') $rowReference = $rowID + trim($rowReference,'[]'); + $columnReference = $cellReference[4][0]; + // Empty C reference is the current column + if ($columnReference == '') $columnReference = $columnNumber; + // Bracketed C references are relative to the current column + if ($columnReference{0} == '[') $columnReference = $columnNumber + trim($columnReference,'[]'); + $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; + $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0])); + } + } + } + } + unset($value); + // Then rebuild the formula string + $cellDataFormula = implode('"',$temp); +// echo 'After: ',$cellDataFormula,'
'; + } + +// echo 'Cell '.$columnID.$rowID.' is a '.$type.' with a value of '.(($hasCalculatedValue) ? $cellDataFormula : $cellValue).'
'; // - $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $cellValue),$type); - if ($hasCalculatedValue) { -// echo 'Formula result is '.$cellValue.'
'; - $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($cellValue); - } - $cellIsSet = $rowHasData = true; - } - - if (isset($cell->Comment)) { -// echo 'comment found
'; - $commentAttributes = $cell->Comment->attributes($namespaces['ss']); - $author = 'unknown'; - if (isset($commentAttributes->Author)) { - $author = (string)$commentAttributes->Author; -// echo 'Author: ',$author,'
'; - } - $node = $cell->Comment->Data->asXML(); -// $annotation = str_replace('html:','',substr($node,49,-10)); -// echo $annotation,'
'; - $annotation = strip_tags($node); -// echo 'Annotation: ',$annotation,'
'; - $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) - ->setAuthor(self::_convertStringEncoding($author ,$this->_charSet)) - ->setText($this->_parseRichText($annotation) ); - } - - if (($cellIsSet) && (isset($cell_ss['StyleID']))) { - $style = (string) $cell_ss['StyleID']; -// echo 'Cell style for '.$columnID.$rowID.' is '.$style.'
'; - if ((isset($this->_styles[$style])) && (!empty($this->_styles[$style]))) { -// echo 'Cell '.$columnID.$rowID.'
'; -// print_r($this->_styles[$style]); -// echo '
'; - if (!$objPHPExcel->getActiveSheet()->cellExists($columnID.$rowID)) { - $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValue(NULL); - } - $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->_styles[$style]); - } - } - ++$columnID; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $cellValue),$type); + if ($hasCalculatedValue) { +// echo 'Formula result is '.$cellValue.'
'; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($cellValue); + } + $cellIsSet = $rowHasData = true; + } + + if (isset($cell->Comment)) { +// echo 'comment found
'; + $commentAttributes = $cell->Comment->attributes($namespaces['ss']); + $author = 'unknown'; + if (isset($commentAttributes->Author)) { + $author = (string)$commentAttributes->Author; +// echo 'Author: ',$author,'
'; + } + $node = $cell->Comment->Data->asXML(); +// $annotation = str_replace('html:','',substr($node,49,-10)); +// echo $annotation,'
'; + $annotation = strip_tags($node); +// echo 'Annotation: ',$annotation,'
'; + $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) + ->setAuthor(self::_convertStringEncoding($author ,$this->_charSet)) + ->setText($this->_parseRichText($annotation) ); + } + + if (($cellIsSet) && (isset($cell_ss['StyleID']))) { + $style = (string) $cell_ss['StyleID']; +// echo 'Cell style for '.$columnID.$rowID.' is '.$style.'
'; + if ((isset($this->_styles[$style])) && (!empty($this->_styles[$style]))) { +// echo 'Cell '.$columnID.$rowID.'
'; +// print_r($this->_styles[$style]); +// echo '
'; + if (!$objPHPExcel->getActiveSheet()->cellExists($columnID.$rowID)) { + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValue(NULL); + } + $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->_styles[$style]); + } + } + ++$columnID; while ($additionalMergedCells > 0) { ++$columnID; $additionalMergedCells--; } - } + } - if ($rowHasData) { - if (isset($row_ss['StyleID'])) { - $rowStyle = $row_ss['StyleID']; - } - if (isset($row_ss['Height'])) { - $rowHeight = $row_ss['Height']; -// echo 'Setting row height to '.$rowHeight.'
'; - $objPHPExcel->getActiveSheet()->getRowDimension($rowID)->setRowHeight($rowHeight); - } - } + if ($rowHasData) { + if (isset($row_ss['StyleID'])) { + $rowStyle = $row_ss['StyleID']; + } + if (isset($row_ss['Height'])) { + $rowHeight = $row_ss['Height']; +// echo 'Setting row height to '.$rowHeight.'
'; + $objPHPExcel->getActiveSheet()->getRowDimension($rowID)->setRowHeight($rowHeight); + } + } - ++$rowID; - } - } - ++$worksheetID; - } + ++$rowID; + } + } + ++$worksheetID; + } - // Return - return $objPHPExcel; - } + // Return + return $objPHPExcel; + } - protected static function _convertStringEncoding($string,$charset) { - if ($charset != 'UTF-8') { - return PHPExcel_Shared_String::ConvertEncoding($string,'UTF-8',$charset); - } - return $string; - } + protected static function _convertStringEncoding($string,$charset) { + if ($charset != 'UTF-8') { + return PHPExcel_Shared_String::ConvertEncoding($string,'UTF-8',$charset); + } + return $string; + } - protected function _parseRichText($is = '') { - $value = new PHPExcel_RichText(); + protected function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); - $value->createText(self::_convertStringEncoding($is,$this->_charSet)); + $value->createText(self::_convertStringEncoding($is,$this->_charSet)); - return $value; - } + return $value; + } } diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index bff2147d3..101424ea5 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -21,991 +21,991 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** * PHPExcel_Reader_Excel2007 * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { - /** - * PHPExcel_ReferenceHelper instance - * - * @var PHPExcel_ReferenceHelper - */ - private $_referenceHelper = NULL; - - /** - * PHPExcel_Reader_Excel2007_Theme instance - * - * @var PHPExcel_Reader_Excel2007_Theme - */ - private static $_theme = NULL; - - - /** - * Create a new PHPExcel_Reader_Excel2007 instance - */ - public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); - } - - - /** - * Can the current PHPExcel_Reader_IReader read the file? - * - * @param string $pFilename - * @return boolean - * @throws PHPExcel_Reader_Exception - */ - public function canRead($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } + /** + * PHPExcel_ReferenceHelper instance + * + * @var PHPExcel_ReferenceHelper + */ + private $_referenceHelper = NULL; + + /** + * PHPExcel_Reader_Excel2007_Theme instance + * + * @var PHPExcel_Reader_Excel2007_Theme + */ + private static $_theme = NULL; + + + /** + * Create a new PHPExcel_Reader_Excel2007 instance + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } $zipClass = PHPExcel_Settings::getZipClass(); - // Check if zip class exists -// if (!class_exists($zipClass, FALSE)) { -// throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); -// } - - $xl = false; - // Load file - $zip = new $zipClass; - if ($zip->open($pFilename) === true) { - // check if it is an OOXML archive - $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - if ($rels !== false) { - foreach ($rels->Relationship as $rel) { - switch ($rel["Type"]) { - case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": - if (basename($rel["Target"]) == 'workbook.xml') { - $xl = true; - } - break; - - } - } - } - $zip->close(); - } - - return $xl; - } - - - /** - * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetNames($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $worksheetNames = array(); + // Check if zip class exists +// if (!class_exists($zipClass, FALSE)) { +// throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); +// } + + $xl = false; + // Load file + $zip = new $zipClass; + if ($zip->open($pFilename) === true) { + // check if it is an OOXML archive + $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if ($rels !== false) { + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + if (basename($rel["Target"]) == 'workbook.xml') { + $xl = true; + } + break; + + } + } + } + $zip->close(); + } + + return $xl; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetNames = array(); $zipClass = PHPExcel_Settings::getZipClass(); - $zip = new $zipClass; - $zip->open($pFilename); - - // The files we're looking at here are small enough that simpleXML is more efficient than XMLReader - $rels = simplexml_load_string( - $this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) - ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - foreach ($rels->Relationship as $rel) { - switch ($rel["Type"]) { - case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": - $xmlWorkbook = simplexml_load_string( - $this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) - ); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - - if ($xmlWorkbook->sheets) { - foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { - // Check if sheet should be skipped - $worksheetNames[] = (string) $eleSheet["name"]; - } - } - } - } - - $zip->close(); - - return $worksheetNames; - } - - - /** - * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetInfo($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $worksheetInfo = array(); + $zip = new $zipClass; + $zip->open($pFilename); + + // The files we're looking at here are small enough that simpleXML is more efficient than XMLReader + $rels = simplexml_load_string( + $this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) + ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + $xmlWorkbook = simplexml_load_string( + $this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) + ); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + + if ($xmlWorkbook->sheets) { + foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { + // Check if sheet should be skipped + $worksheetNames[] = (string) $eleSheet["name"]; + } + } + } + } + + $zip->close(); + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); $zipClass = PHPExcel_Settings::getZipClass(); - $zip = new $zipClass; - $zip->open($pFilename); - - $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - foreach ($rels->Relationship as $rel) { - if ($rel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument") { - $dir = dirname($rel["Target"]); - $relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); - - $worksheets = array(); - foreach ($relsWorkbook->Relationship as $ele) { - if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet") { - $worksheets[(string) $ele["Id"]] = $ele["Target"]; - } - } - - $xmlWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - if ($xmlWorkbook->sheets) { - $dir = dirname($rel["Target"]); - foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { - $tmpInfo = array( - 'worksheetName' => (string) $eleSheet["name"], - 'lastColumnLetter' => 'A', - 'lastColumnIndex' => 0, - 'totalRows' => 0, - 'totalColumns' => 0, - ); - - $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; - - $xml = new XMLReader(); - $res = $xml->xml($this->securityScanFile('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet"), null, PHPExcel_Settings::getLibXmlLoaderOptions()); - $xml->setParserProperty(2,true); - - $currCells = 0; - while ($xml->read()) { - if ($xml->name == 'row' && $xml->nodeType == XMLReader::ELEMENT) { - $row = $xml->getAttribute('r'); - $tmpInfo['totalRows'] = $row; - $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); - $currCells = 0; - } elseif ($xml->name == 'c' && $xml->nodeType == XMLReader::ELEMENT) { - $currCells++; - } - } - $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); - $xml->close(); - - $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; - $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); - - $worksheetInfo[] = $tmpInfo; - } - } - } - } - - $zip->close(); - - return $worksheetInfo; - } - - - private static function _castToBool($c) { -// echo 'Initial Cast to Boolean', PHP_EOL; - $value = isset($c->v) ? (string) $c->v : NULL; - if ($value == '0') { - return FALSE; - } elseif ($value == '1') { - return TRUE; - } else { - return (bool)$c->v; - } - return $value; - } // function _castToBool() - - - private static function _castToError($c) { -// echo 'Initial Cast to Error', PHP_EOL; - return isset($c->v) ? (string) $c->v : NULL; - } // function _castToError() - - - private static function _castToString($c) { -// echo 'Initial Cast to String, PHP_EOL; - return isset($c->v) ? (string) $c->v : NULL; - } // function _castToString() - - - private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) { -// echo 'Formula', PHP_EOL; -// echo '$c->f is ', $c->f, PHP_EOL; - $cellDataType = 'f'; - $value = "={$c->f}"; - $calculatedValue = self::$castBaseType($c); - - // Shared formula? - if (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') { -// echo 'SHARED FORMULA', PHP_EOL; - $instance = (string)$c->f['si']; - -// echo 'Instance ID = ', $instance, PHP_EOL; + $zip = new $zipClass; + $zip->open($pFilename); + + $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($rels->Relationship as $rel) { + if ($rel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument") { + $dir = dirname($rel["Target"]); + $relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); + + $worksheets = array(); + foreach ($relsWorkbook->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet") { + $worksheets[(string) $ele["Id"]] = $ele["Target"]; + } + } + + $xmlWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + if ($xmlWorkbook->sheets) { + $dir = dirname($rel["Target"]); + foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { + $tmpInfo = array( + 'worksheetName' => (string) $eleSheet["name"], + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, + ); + + $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + + $xml = new XMLReader(); + $res = $xml->xml($this->securityScanFile('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet"), null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml->setParserProperty(2,true); + + $currCells = 0; + while ($xml->read()) { + if ($xml->name == 'row' && $xml->nodeType == XMLReader::ELEMENT) { + $row = $xml->getAttribute('r'); + $tmpInfo['totalRows'] = $row; + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $currCells = 0; + } elseif ($xml->name == 'c' && $xml->nodeType == XMLReader::ELEMENT) { + $currCells++; + } + } + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $xml->close(); + + $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + + $worksheetInfo[] = $tmpInfo; + } + } + } + } + + $zip->close(); + + return $worksheetInfo; + } + + + private static function _castToBool($c) { +// echo 'Initial Cast to Boolean', PHP_EOL; + $value = isset($c->v) ? (string) $c->v : NULL; + if ($value == '0') { + return FALSE; + } elseif ($value == '1') { + return TRUE; + } else { + return (bool)$c->v; + } + return $value; + } // function _castToBool() + + + private static function _castToError($c) { +// echo 'Initial Cast to Error', PHP_EOL; + return isset($c->v) ? (string) $c->v : NULL; + } // function _castToError() + + + private static function _castToString($c) { +// echo 'Initial Cast to String, PHP_EOL; + return isset($c->v) ? (string) $c->v : NULL; + } // function _castToString() + + + private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) { +// echo 'Formula', PHP_EOL; +// echo '$c->f is ', $c->f, PHP_EOL; + $cellDataType = 'f'; + $value = "={$c->f}"; + $calculatedValue = self::$castBaseType($c); + + // Shared formula? + if (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') { +// echo 'SHARED FORMULA', PHP_EOL; + $instance = (string)$c->f['si']; + +// echo 'Instance ID = ', $instance, PHP_EOL; // -// echo 'Shared Formula Array:', PHP_EOL; -// print_r($sharedFormulas); - if (!isset($sharedFormulas[(string)$c->f['si']])) { -// echo 'SETTING NEW SHARED FORMULA', PHP_EOL; -// echo 'Master is ', $r, PHP_EOL; -// echo 'Formula is ', $value, PHP_EOL; - $sharedFormulas[$instance] = array( 'master' => $r, - 'formula' => $value - ); -// echo 'New Shared Formula Array:', PHP_EOL; -// print_r($sharedFormulas); - } else { -// echo 'GETTING SHARED FORMULA', PHP_EOL; -// echo 'Master is ', $sharedFormulas[$instance]['master'], PHP_EOL; -// echo 'Formula is ', $sharedFormulas[$instance]['formula'], PHP_EOL; - $master = PHPExcel_Cell::coordinateFromString($sharedFormulas[$instance]['master']); - $current = PHPExcel_Cell::coordinateFromString($r); - - $difference = array(0, 0); - $difference[0] = PHPExcel_Cell::columnIndexFromString($current[0]) - PHPExcel_Cell::columnIndexFromString($master[0]); - $difference[1] = $current[1] - $master[1]; - - $value = $this->_referenceHelper->updateFormulaReferences( $sharedFormulas[$instance]['formula'], - 'A1', - $difference[0], - $difference[1] - ); -// echo 'Adjusted Formula is ', $value, PHP_EOL; - } - } - } - - - public function _getFromZipArchive($archive, $fileName = '') - { - // Root-relative paths - if (strpos($fileName, '//') !== false) - { - $fileName = substr($fileName, strpos($fileName, '//') + 1); - } - $fileName = PHPExcel_Shared_File::realpath($fileName); - - // Apache POI fixes - $contents = $archive->getFromName($fileName); - if ($contents === false) - { - $contents = $archive->getFromName(substr($fileName, 1)); - } - - return $contents; - } - - - /** - * Loads PHPExcel from file - * - * @param string $pFilename +// echo 'Shared Formula Array:', PHP_EOL; +// print_r($sharedFormulas); + if (!isset($sharedFormulas[(string)$c->f['si']])) { +// echo 'SETTING NEW SHARED FORMULA', PHP_EOL; +// echo 'Master is ', $r, PHP_EOL; +// echo 'Formula is ', $value, PHP_EOL; + $sharedFormulas[$instance] = array( 'master' => $r, + 'formula' => $value + ); +// echo 'New Shared Formula Array:', PHP_EOL; +// print_r($sharedFormulas); + } else { +// echo 'GETTING SHARED FORMULA', PHP_EOL; +// echo 'Master is ', $sharedFormulas[$instance]['master'], PHP_EOL; +// echo 'Formula is ', $sharedFormulas[$instance]['formula'], PHP_EOL; + $master = PHPExcel_Cell::coordinateFromString($sharedFormulas[$instance]['master']); + $current = PHPExcel_Cell::coordinateFromString($r); + + $difference = array(0, 0); + $difference[0] = PHPExcel_Cell::columnIndexFromString($current[0]) - PHPExcel_Cell::columnIndexFromString($master[0]); + $difference[1] = $current[1] - $master[1]; + + $value = $this->_referenceHelper->updateFormulaReferences( $sharedFormulas[$instance]['formula'], + 'A1', + $difference[0], + $difference[1] + ); +// echo 'Adjusted Formula is ', $value, PHP_EOL; + } + } + } + + + public function _getFromZipArchive($archive, $fileName = '') + { + // Root-relative paths + if (strpos($fileName, '//') !== false) + { + $fileName = substr($fileName, strpos($fileName, '//') + 1); + } + $fileName = PHPExcel_Shared_File::realpath($fileName); + + // Apache POI fixes + $contents = $archive->getFromName($fileName); + if ($contents === false) + { + $contents = $archive->getFromName(substr($fileName, 1)); + } + + return $contents; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function load($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - // Initialisations - $excel = new PHPExcel; - $excel->removeSheetByIndex(0); - if (!$this->_readDataOnly) { - $excel->removeCellStyleXfByIndex(0); // remove the default style - $excel->removeCellXfByIndex(0); // remove the default style - } + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Initialisations + $excel = new PHPExcel; + $excel->removeSheetByIndex(0); + if (!$this->_readDataOnly) { + $excel->removeCellStyleXfByIndex(0); // remove the default style + $excel->removeCellXfByIndex(0); // remove the default style + } $zipClass = PHPExcel_Settings::getZipClass(); - $zip = new $zipClass; - $zip->open($pFilename); - - // Read the theme first, because we need the colour scheme when reading the styles - $wbRels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - foreach ($wbRels->Relationship as $rel) { - switch ($rel["Type"]) { - case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme": - $themeOrderArray = array('lt1','dk1','lt2','dk2'); - $themeOrderAdditional = count($themeOrderArray); - - $xmlTheme = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "xl/{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - if (is_object($xmlTheme)) { - $xmlThemeName = $xmlTheme->attributes(); - $xmlTheme = $xmlTheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); - $themeName = (string)$xmlThemeName['name']; - - $colourScheme = $xmlTheme->themeElements->clrScheme->attributes(); - $colourSchemeName = (string)$colourScheme['name']; - $colourScheme = $xmlTheme->themeElements->clrScheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); - - $themeColours = array(); - foreach ($colourScheme as $k => $xmlColour) { - $themePos = array_search($k,$themeOrderArray); - if ($themePos === false) { - $themePos = $themeOrderAdditional++; - } - if (isset($xmlColour->sysClr)) { - $xmlColourData = $xmlColour->sysClr->attributes(); - $themeColours[$themePos] = $xmlColourData['lastClr']; - } elseif (isset($xmlColour->srgbClr)) { - $xmlColourData = $xmlColour->srgbClr->attributes(); - $themeColours[$themePos] = $xmlColourData['val']; - } - } - self::$_theme = new PHPExcel_Reader_Excel2007_Theme($themeName,$colourSchemeName,$themeColours); - } - break; - } - } - - $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - foreach ($rels->Relationship as $rel) { - switch ($rel["Type"]) { - case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties": - $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - if (is_object($xmlCore)) { - $xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/"); - $xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/"); - $xmlCore->registerXPathNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"); - $docProps = $excel->getProperties(); - $docProps->setCreator((string) self::array_item($xmlCore->xpath("dc:creator"))); - $docProps->setLastModifiedBy((string) self::array_item($xmlCore->xpath("cp:lastModifiedBy"))); - $docProps->setCreated(strtotime(self::array_item($xmlCore->xpath("dcterms:created")))); //! respect xsi:type - $docProps->setModified(strtotime(self::array_item($xmlCore->xpath("dcterms:modified")))); //! respect xsi:type - $docProps->setTitle((string) self::array_item($xmlCore->xpath("dc:title"))); - $docProps->setDescription((string) self::array_item($xmlCore->xpath("dc:description"))); - $docProps->setSubject((string) self::array_item($xmlCore->xpath("dc:subject"))); - $docProps->setKeywords((string) self::array_item($xmlCore->xpath("cp:keywords"))); - $docProps->setCategory((string) self::array_item($xmlCore->xpath("cp:category"))); - } - break; - - case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties": - $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - if (is_object($xmlCore)) { - $docProps = $excel->getProperties(); - if (isset($xmlCore->Company)) - $docProps->setCompany((string) $xmlCore->Company); - if (isset($xmlCore->Manager)) - $docProps->setManager((string) $xmlCore->Manager); - } - break; - - case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties": - $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - if (is_object($xmlCore)) { - $docProps = $excel->getProperties(); - foreach ($xmlCore as $xmlProperty) { - $cellDataOfficeAttributes = $xmlProperty->attributes(); - if (isset($cellDataOfficeAttributes['name'])) { - $propertyName = (string) $cellDataOfficeAttributes['name']; - $cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); - $attributeType = $cellDataOfficeChildren->getName(); - $attributeValue = (string) $cellDataOfficeChildren->{$attributeType}; - $attributeValue = PHPExcel_DocumentProperties::convertProperty($attributeValue,$attributeType); - $attributeType = PHPExcel_DocumentProperties::convertPropertyType($attributeType); - $docProps->setCustomProperty($propertyName,$attributeValue,$attributeType); - } - } - } - break; - //Ribbon - case "http://schemas.microsoft.com/office/2006/relationships/ui/extensibility": - $customUI = $rel['Target']; - if(!is_null($customUI)){ - $this->_readRibbon($excel, $customUI, $zip); - } - break; - case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": - $dir = dirname($rel["Target"]); - $relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); - - $sharedStrings = array(); - $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']")); - $xmlStrings = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - if (isset($xmlStrings) && isset($xmlStrings->si)) { - foreach ($xmlStrings->si as $val) { - if (isset($val->t)) { - $sharedStrings[] = PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $val->t ); - } elseif (isset($val->r)) { - $sharedStrings[] = $this->_parseRichText($val); - } - } - } - - $worksheets = array(); + $zip = new $zipClass; + $zip->open($pFilename); + + // Read the theme first, because we need the colour scheme when reading the styles + $wbRels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($wbRels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme": + $themeOrderArray = array('lt1','dk1','lt2','dk2'); + $themeOrderAdditional = count($themeOrderArray); + + $xmlTheme = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "xl/{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlTheme)) { + $xmlThemeName = $xmlTheme->attributes(); + $xmlTheme = $xmlTheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); + $themeName = (string)$xmlThemeName['name']; + + $colourScheme = $xmlTheme->themeElements->clrScheme->attributes(); + $colourSchemeName = (string)$colourScheme['name']; + $colourScheme = $xmlTheme->themeElements->clrScheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); + + $themeColours = array(); + foreach ($colourScheme as $k => $xmlColour) { + $themePos = array_search($k,$themeOrderArray); + if ($themePos === false) { + $themePos = $themeOrderAdditional++; + } + if (isset($xmlColour->sysClr)) { + $xmlColourData = $xmlColour->sysClr->attributes(); + $themeColours[$themePos] = $xmlColourData['lastClr']; + } elseif (isset($xmlColour->srgbClr)) { + $xmlColourData = $xmlColour->srgbClr->attributes(); + $themeColours[$themePos] = $xmlColourData['val']; + } + } + self::$_theme = new PHPExcel_Reader_Excel2007_Theme($themeName,$colourSchemeName,$themeColours); + } + break; + } + } + + $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties": + $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlCore)) { + $xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/"); + $xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/"); + $xmlCore->registerXPathNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"); + $docProps = $excel->getProperties(); + $docProps->setCreator((string) self::array_item($xmlCore->xpath("dc:creator"))); + $docProps->setLastModifiedBy((string) self::array_item($xmlCore->xpath("cp:lastModifiedBy"))); + $docProps->setCreated(strtotime(self::array_item($xmlCore->xpath("dcterms:created")))); //! respect xsi:type + $docProps->setModified(strtotime(self::array_item($xmlCore->xpath("dcterms:modified")))); //! respect xsi:type + $docProps->setTitle((string) self::array_item($xmlCore->xpath("dc:title"))); + $docProps->setDescription((string) self::array_item($xmlCore->xpath("dc:description"))); + $docProps->setSubject((string) self::array_item($xmlCore->xpath("dc:subject"))); + $docProps->setKeywords((string) self::array_item($xmlCore->xpath("cp:keywords"))); + $docProps->setCategory((string) self::array_item($xmlCore->xpath("cp:category"))); + } + break; + + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties": + $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlCore)) { + $docProps = $excel->getProperties(); + if (isset($xmlCore->Company)) + $docProps->setCompany((string) $xmlCore->Company); + if (isset($xmlCore->Manager)) + $docProps->setManager((string) $xmlCore->Manager); + } + break; + + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties": + $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlCore)) { + $docProps = $excel->getProperties(); + foreach ($xmlCore as $xmlProperty) { + $cellDataOfficeAttributes = $xmlProperty->attributes(); + if (isset($cellDataOfficeAttributes['name'])) { + $propertyName = (string) $cellDataOfficeAttributes['name']; + $cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + $attributeType = $cellDataOfficeChildren->getName(); + $attributeValue = (string) $cellDataOfficeChildren->{$attributeType}; + $attributeValue = PHPExcel_DocumentProperties::convertProperty($attributeValue,$attributeType); + $attributeType = PHPExcel_DocumentProperties::convertPropertyType($attributeType); + $docProps->setCustomProperty($propertyName,$attributeValue,$attributeType); + } + } + } + break; + //Ribbon + case "http://schemas.microsoft.com/office/2006/relationships/ui/extensibility": + $customUI = $rel['Target']; + if(!is_null($customUI)){ + $this->_readRibbon($excel, $customUI, $zip); + } + break; + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + $dir = dirname($rel["Target"]); + $relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); + + $sharedStrings = array(); + $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']")); + $xmlStrings = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + if (isset($xmlStrings) && isset($xmlStrings->si)) { + foreach ($xmlStrings->si as $val) { + if (isset($val->t)) { + $sharedStrings[] = PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $val->t ); + } elseif (isset($val->r)) { + $sharedStrings[] = $this->_parseRichText($val); + } + } + } + + $worksheets = array(); $macros = $customUI = NULL; - foreach ($relsWorkbook->Relationship as $ele) { - switch($ele['Type']){ - case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": - $worksheets[(string) $ele["Id"]] = $ele["Target"]; - break; - // a vbaProject ? (: some macros) - case "http://schemas.microsoft.com/office/2006/relationships/vbaProject": - $macros = $ele["Target"]; - break; - } - } - - if(!is_null($macros)){ - $macrosCode = $this->_getFromZipArchive($zip, 'xl/vbaProject.bin');//vbaProject.bin always in 'xl' dir and always named vbaProject.bin - if($macrosCode !== false){ - $excel->setMacrosCode($macrosCode); - $excel->setHasMacros(true); - //short-circuit : not reading vbaProject.bin.rel to get Signature =>allways vbaProjectSignature.bin in 'xl' dir - $Certificate = $this->_getFromZipArchive($zip, 'xl/vbaProjectSignature.bin'); - if($Certificate !== false) - $excel->setMacrosCertificate($Certificate); - } - } - $styles = array(); - $cellStyles = array(); - $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); - $xmlStyles = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - $numFmts = null; - if ($xmlStyles && $xmlStyles->numFmts[0]) { - $numFmts = $xmlStyles->numFmts[0]; - } - if (isset($numFmts) && ($numFmts !== NULL)) { - $numFmts->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - } - if (!$this->_readDataOnly && $xmlStyles) { - foreach ($xmlStyles->cellXfs->xf as $xf) { - $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; - - if ($xf["numFmtId"]) { - if (isset($numFmts)) { - $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); - - if (isset($tmpNumFmt["formatCode"])) { - $numFmt = (string) $tmpNumFmt["formatCode"]; - } - } - - if ((int)$xf["numFmtId"] < 164) { - $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); - } - } + foreach ($relsWorkbook->Relationship as $ele) { + switch($ele['Type']){ + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": + $worksheets[(string) $ele["Id"]] = $ele["Target"]; + break; + // a vbaProject ? (: some macros) + case "http://schemas.microsoft.com/office/2006/relationships/vbaProject": + $macros = $ele["Target"]; + break; + } + } + + if(!is_null($macros)){ + $macrosCode = $this->_getFromZipArchive($zip, 'xl/vbaProject.bin');//vbaProject.bin always in 'xl' dir and always named vbaProject.bin + if($macrosCode !== false){ + $excel->setMacrosCode($macrosCode); + $excel->setHasMacros(true); + //short-circuit : not reading vbaProject.bin.rel to get Signature =>allways vbaProjectSignature.bin in 'xl' dir + $Certificate = $this->_getFromZipArchive($zip, 'xl/vbaProjectSignature.bin'); + if($Certificate !== false) + $excel->setMacrosCertificate($Certificate); + } + } + $styles = array(); + $cellStyles = array(); + $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); + $xmlStyles = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $numFmts = null; + if ($xmlStyles && $xmlStyles->numFmts[0]) { + $numFmts = $xmlStyles->numFmts[0]; + } + if (isset($numFmts) && ($numFmts !== NULL)) { + $numFmts->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + } + if (!$this->_readDataOnly && $xmlStyles) { + foreach ($xmlStyles->cellXfs->xf as $xf) { + $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + + if ($xf["numFmtId"]) { + if (isset($numFmts)) { + $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); + + if (isset($tmpNumFmt["formatCode"])) { + $numFmt = (string) $tmpNumFmt["formatCode"]; + } + } + + if ((int)$xf["numFmtId"] < 164) { + $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); + } + } $quotePrefix = false; - if (isset($xf["quotePrefix"])) { + if (isset($xf["quotePrefix"])) { $quotePrefix = (boolean) $xf["quotePrefix"]; } - //$numFmt = str_replace('mm', 'i', $numFmt); - //$numFmt = str_replace('h', 'H', $numFmt); - - $style = (object) array( - "numFmt" => $numFmt, - "font" => $xmlStyles->fonts->font[intval($xf["fontId"])], - "fill" => $xmlStyles->fills->fill[intval($xf["fillId"])], - "border" => $xmlStyles->borders->border[intval($xf["borderId"])], - "alignment" => $xf->alignment, - "protection" => $xf->protection, - "quotePrefix" => $quotePrefix, - ); - $styles[] = $style; - - // add style to cellXf collection - $objStyle = new PHPExcel_Style; - self::_readStyle($objStyle, $style); - $excel->addCellXf($objStyle); - } - - foreach ($xmlStyles->cellStyleXfs->xf as $xf) { - $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; - if ($numFmts && $xf["numFmtId"]) { - $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); - if (isset($tmpNumFmt["formatCode"])) { - $numFmt = (string) $tmpNumFmt["formatCode"]; - } else if ((int)$xf["numFmtId"] < 165) { - $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); - } - } - - $cellStyle = (object) array( - "numFmt" => $numFmt, - "font" => $xmlStyles->fonts->font[intval($xf["fontId"])], - "fill" => $xmlStyles->fills->fill[intval($xf["fillId"])], - "border" => $xmlStyles->borders->border[intval($xf["borderId"])], - "alignment" => $xf->alignment, - "protection" => $xf->protection, - "quotePrefix" => $quotePrefix, - ); - $cellStyles[] = $cellStyle; - - // add style to cellStyleXf collection - $objStyle = new PHPExcel_Style; - self::_readStyle($objStyle, $cellStyle); - $excel->addCellStyleXf($objStyle); - } - } - - $dxfs = array(); - if (!$this->_readDataOnly && $xmlStyles) { - // Conditional Styles - if ($xmlStyles->dxfs) { - foreach ($xmlStyles->dxfs->dxf as $dxf) { - $style = new PHPExcel_Style(FALSE, TRUE); - self::_readStyle($style, $dxf); - $dxfs[] = $style; - } - } - // Cell Styles - if ($xmlStyles->cellStyles) { - foreach ($xmlStyles->cellStyles->cellStyle as $cellStyle) { - if (intval($cellStyle['builtinId']) == 0) { - if (isset($cellStyles[intval($cellStyle['xfId'])])) { - // Set default style - $style = new PHPExcel_Style; - self::_readStyle($style, $cellStyles[intval($cellStyle['xfId'])]); - - // normal style, currently not using it for anything - } - } - } - } - } - - $xmlWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - - // Set base date - if ($xmlWorkbook->workbookPr) { - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); - if (isset($xmlWorkbook->workbookPr['date1904'])) { - if (self::boolean((string) $xmlWorkbook->workbookPr['date1904'])) { - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); - } - } - } - - $sheetId = 0; // keep track of new sheet id in final workbook - $oldSheetId = -1; // keep track of old sheet id in final workbook - $countSkippedSheets = 0; // keep track of number of skipped sheets - $mapSheetId = array(); // mapping of sheet ids from old to new - - - $charts = $chartDetails = array(); - - if ($xmlWorkbook->sheets) { - foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { - ++$oldSheetId; - - // Check if sheet should be skipped - if (isset($this->_loadSheetsOnly) && !in_array((string) $eleSheet["name"], $this->_loadSheetsOnly)) { - ++$countSkippedSheets; - $mapSheetId[$oldSheetId] = null; - continue; - } - - // Map old sheet id in original workbook to new sheet id. - // They will differ if loadSheetsOnly() is being used - $mapSheetId[$oldSheetId] = $oldSheetId - $countSkippedSheets; - - // Load sheet - $docSheet = $excel->createSheet(); - // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet - // references in formula cells... during the load, all formulae should be correct, - // and we're simply bringing the worksheet name in line with the formula, not the - // reverse - $docSheet->setTitle((string) $eleSheet["name"],false); - $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; - $xmlSheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$fileWorksheet")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - - $sharedFormulas = array(); - - if (isset($eleSheet["state"]) && (string) $eleSheet["state"] != '') { - $docSheet->setSheetState( (string) $eleSheet["state"] ); - } - - if (isset($xmlSheet->sheetViews) && isset($xmlSheet->sheetViews->sheetView)) { - if (isset($xmlSheet->sheetViews->sheetView['zoomScale'])) { - $docSheet->getSheetView()->setZoomScale( intval($xmlSheet->sheetViews->sheetView['zoomScale']) ); - } - - if (isset($xmlSheet->sheetViews->sheetView['zoomScaleNormal'])) { - $docSheet->getSheetView()->setZoomScaleNormal( intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal']) ); - } - - if (isset($xmlSheet->sheetViews->sheetView['view'])) { - $docSheet->getSheetView()->setView((string) $xmlSheet->sheetViews->sheetView['view']); - } - - if (isset($xmlSheet->sheetViews->sheetView['showGridLines'])) { - $docSheet->setShowGridLines(self::boolean((string)$xmlSheet->sheetViews->sheetView['showGridLines'])); - } - - if (isset($xmlSheet->sheetViews->sheetView['showRowColHeaders'])) { - $docSheet->setShowRowColHeaders(self::boolean((string)$xmlSheet->sheetViews->sheetView['showRowColHeaders'])); - } - - if (isset($xmlSheet->sheetViews->sheetView['rightToLeft'])) { - $docSheet->setRightToLeft(self::boolean((string)$xmlSheet->sheetViews->sheetView['rightToLeft'])); - } - - if (isset($xmlSheet->sheetViews->sheetView->pane)) { - if (isset($xmlSheet->sheetViews->sheetView->pane['topLeftCell'])) { - $docSheet->freezePane( (string)$xmlSheet->sheetViews->sheetView->pane['topLeftCell'] ); - } else { - $xSplit = 0; - $ySplit = 0; - - if (isset($xmlSheet->sheetViews->sheetView->pane['xSplit'])) { - $xSplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['xSplit']); - } - - if (isset($xmlSheet->sheetViews->sheetView->pane['ySplit'])) { - $ySplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['ySplit']); - } - - $docSheet->freezePaneByColumnAndRow($xSplit, $ySplit); - } - } - - if (isset($xmlSheet->sheetViews->sheetView->selection)) { - if (isset($xmlSheet->sheetViews->sheetView->selection['sqref'])) { - $sqref = (string)$xmlSheet->sheetViews->sheetView->selection['sqref']; - $sqref = explode(' ', $sqref); - $sqref = $sqref[0]; - $docSheet->setSelectedCells($sqref); - } - } - - } - - if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->tabColor)) { - if (isset($xmlSheet->sheetPr->tabColor['rgb'])) { - $docSheet->getTabColor()->setARGB( (string)$xmlSheet->sheetPr->tabColor['rgb'] ); - } - } - if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr['codeName'])) { - $docSheet->setCodeName((string) $xmlSheet->sheetPr['codeName']); - } - if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->outlinePr)) { - if (isset($xmlSheet->sheetPr->outlinePr['summaryRight']) && - !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryRight'])) { - $docSheet->setShowSummaryRight(FALSE); - } else { - $docSheet->setShowSummaryRight(TRUE); - } - - if (isset($xmlSheet->sheetPr->outlinePr['summaryBelow']) && - !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryBelow'])) { - $docSheet->setShowSummaryBelow(FALSE); - } else { - $docSheet->setShowSummaryBelow(TRUE); - } - } - - if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->pageSetUpPr)) { - if (isset($xmlSheet->sheetPr->pageSetUpPr['fitToPage']) && - !self::boolean((string) $xmlSheet->sheetPr->pageSetUpPr['fitToPage'])) { - $docSheet->getPageSetup()->setFitToPage(FALSE); - } else { - $docSheet->getPageSetup()->setFitToPage(TRUE); - } - } - - if (isset($xmlSheet->sheetFormatPr)) { - if (isset($xmlSheet->sheetFormatPr['customHeight']) && - self::boolean((string) $xmlSheet->sheetFormatPr['customHeight']) && - isset($xmlSheet->sheetFormatPr['defaultRowHeight'])) { - $docSheet->getDefaultRowDimension()->setRowHeight( (float)$xmlSheet->sheetFormatPr['defaultRowHeight'] ); - } - if (isset($xmlSheet->sheetFormatPr['defaultColWidth'])) { - $docSheet->getDefaultColumnDimension()->setWidth( (float)$xmlSheet->sheetFormatPr['defaultColWidth'] ); - } - if (isset($xmlSheet->sheetFormatPr['zeroHeight']) && - ((string)$xmlSheet->sheetFormatPr['zeroHeight'] == '1')) { - $docSheet->getDefaultRowDimension()->setZeroHeight(true); - } - } - - if (isset($xmlSheet->cols) && !$this->_readDataOnly) { - foreach ($xmlSheet->cols->col as $col) { + //$numFmt = str_replace('mm', 'i', $numFmt); + //$numFmt = str_replace('h', 'H', $numFmt); + + $style = (object) array( + "numFmt" => $numFmt, + "font" => $xmlStyles->fonts->font[intval($xf["fontId"])], + "fill" => $xmlStyles->fills->fill[intval($xf["fillId"])], + "border" => $xmlStyles->borders->border[intval($xf["borderId"])], + "alignment" => $xf->alignment, + "protection" => $xf->protection, + "quotePrefix" => $quotePrefix, + ); + $styles[] = $style; + + // add style to cellXf collection + $objStyle = new PHPExcel_Style; + self::_readStyle($objStyle, $style); + $excel->addCellXf($objStyle); + } + + foreach ($xmlStyles->cellStyleXfs->xf as $xf) { + $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + if ($numFmts && $xf["numFmtId"]) { + $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); + if (isset($tmpNumFmt["formatCode"])) { + $numFmt = (string) $tmpNumFmt["formatCode"]; + } else if ((int)$xf["numFmtId"] < 165) { + $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); + } + } + + $cellStyle = (object) array( + "numFmt" => $numFmt, + "font" => $xmlStyles->fonts->font[intval($xf["fontId"])], + "fill" => $xmlStyles->fills->fill[intval($xf["fillId"])], + "border" => $xmlStyles->borders->border[intval($xf["borderId"])], + "alignment" => $xf->alignment, + "protection" => $xf->protection, + "quotePrefix" => $quotePrefix, + ); + $cellStyles[] = $cellStyle; + + // add style to cellStyleXf collection + $objStyle = new PHPExcel_Style; + self::_readStyle($objStyle, $cellStyle); + $excel->addCellStyleXf($objStyle); + } + } + + $dxfs = array(); + if (!$this->_readDataOnly && $xmlStyles) { + // Conditional Styles + if ($xmlStyles->dxfs) { + foreach ($xmlStyles->dxfs->dxf as $dxf) { + $style = new PHPExcel_Style(FALSE, TRUE); + self::_readStyle($style, $dxf); + $dxfs[] = $style; + } + } + // Cell Styles + if ($xmlStyles->cellStyles) { + foreach ($xmlStyles->cellStyles->cellStyle as $cellStyle) { + if (intval($cellStyle['builtinId']) == 0) { + if (isset($cellStyles[intval($cellStyle['xfId'])])) { + // Set default style + $style = new PHPExcel_Style; + self::_readStyle($style, $cellStyles[intval($cellStyle['xfId'])]); + + // normal style, currently not using it for anything + } + } + } + } + } + + $xmlWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + + // Set base date + if ($xmlWorkbook->workbookPr) { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + if (isset($xmlWorkbook->workbookPr['date1904'])) { + if (self::boolean((string) $xmlWorkbook->workbookPr['date1904'])) { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + } + } + } + + $sheetId = 0; // keep track of new sheet id in final workbook + $oldSheetId = -1; // keep track of old sheet id in final workbook + $countSkippedSheets = 0; // keep track of number of skipped sheets + $mapSheetId = array(); // mapping of sheet ids from old to new + + + $charts = $chartDetails = array(); + + if ($xmlWorkbook->sheets) { + foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { + ++$oldSheetId; + + // Check if sheet should be skipped + if (isset($this->_loadSheetsOnly) && !in_array((string) $eleSheet["name"], $this->_loadSheetsOnly)) { + ++$countSkippedSheets; + $mapSheetId[$oldSheetId] = null; + continue; + } + + // Map old sheet id in original workbook to new sheet id. + // They will differ if loadSheetsOnly() is being used + $mapSheetId[$oldSheetId] = $oldSheetId - $countSkippedSheets; + + // Load sheet + $docSheet = $excel->createSheet(); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet + // references in formula cells... during the load, all formulae should be correct, + // and we're simply bringing the worksheet name in line with the formula, not the + // reverse + $docSheet->setTitle((string) $eleSheet["name"],false); + $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + $xmlSheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$fileWorksheet")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + + $sharedFormulas = array(); + + if (isset($eleSheet["state"]) && (string) $eleSheet["state"] != '') { + $docSheet->setSheetState( (string) $eleSheet["state"] ); + } + + if (isset($xmlSheet->sheetViews) && isset($xmlSheet->sheetViews->sheetView)) { + if (isset($xmlSheet->sheetViews->sheetView['zoomScale'])) { + $docSheet->getSheetView()->setZoomScale( intval($xmlSheet->sheetViews->sheetView['zoomScale']) ); + } + + if (isset($xmlSheet->sheetViews->sheetView['zoomScaleNormal'])) { + $docSheet->getSheetView()->setZoomScaleNormal( intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal']) ); + } + + if (isset($xmlSheet->sheetViews->sheetView['view'])) { + $docSheet->getSheetView()->setView((string) $xmlSheet->sheetViews->sheetView['view']); + } + + if (isset($xmlSheet->sheetViews->sheetView['showGridLines'])) { + $docSheet->setShowGridLines(self::boolean((string)$xmlSheet->sheetViews->sheetView['showGridLines'])); + } + + if (isset($xmlSheet->sheetViews->sheetView['showRowColHeaders'])) { + $docSheet->setShowRowColHeaders(self::boolean((string)$xmlSheet->sheetViews->sheetView['showRowColHeaders'])); + } + + if (isset($xmlSheet->sheetViews->sheetView['rightToLeft'])) { + $docSheet->setRightToLeft(self::boolean((string)$xmlSheet->sheetViews->sheetView['rightToLeft'])); + } + + if (isset($xmlSheet->sheetViews->sheetView->pane)) { + if (isset($xmlSheet->sheetViews->sheetView->pane['topLeftCell'])) { + $docSheet->freezePane( (string)$xmlSheet->sheetViews->sheetView->pane['topLeftCell'] ); + } else { + $xSplit = 0; + $ySplit = 0; + + if (isset($xmlSheet->sheetViews->sheetView->pane['xSplit'])) { + $xSplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['xSplit']); + } + + if (isset($xmlSheet->sheetViews->sheetView->pane['ySplit'])) { + $ySplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['ySplit']); + } + + $docSheet->freezePaneByColumnAndRow($xSplit, $ySplit); + } + } + + if (isset($xmlSheet->sheetViews->sheetView->selection)) { + if (isset($xmlSheet->sheetViews->sheetView->selection['sqref'])) { + $sqref = (string)$xmlSheet->sheetViews->sheetView->selection['sqref']; + $sqref = explode(' ', $sqref); + $sqref = $sqref[0]; + $docSheet->setSelectedCells($sqref); + } + } + + } + + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->tabColor)) { + if (isset($xmlSheet->sheetPr->tabColor['rgb'])) { + $docSheet->getTabColor()->setARGB( (string)$xmlSheet->sheetPr->tabColor['rgb'] ); + } + } + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr['codeName'])) { + $docSheet->setCodeName((string) $xmlSheet->sheetPr['codeName']); + } + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->outlinePr)) { + if (isset($xmlSheet->sheetPr->outlinePr['summaryRight']) && + !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryRight'])) { + $docSheet->setShowSummaryRight(FALSE); + } else { + $docSheet->setShowSummaryRight(TRUE); + } + + if (isset($xmlSheet->sheetPr->outlinePr['summaryBelow']) && + !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryBelow'])) { + $docSheet->setShowSummaryBelow(FALSE); + } else { + $docSheet->setShowSummaryBelow(TRUE); + } + } + + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->pageSetUpPr)) { + if (isset($xmlSheet->sheetPr->pageSetUpPr['fitToPage']) && + !self::boolean((string) $xmlSheet->sheetPr->pageSetUpPr['fitToPage'])) { + $docSheet->getPageSetup()->setFitToPage(FALSE); + } else { + $docSheet->getPageSetup()->setFitToPage(TRUE); + } + } + + if (isset($xmlSheet->sheetFormatPr)) { + if (isset($xmlSheet->sheetFormatPr['customHeight']) && + self::boolean((string) $xmlSheet->sheetFormatPr['customHeight']) && + isset($xmlSheet->sheetFormatPr['defaultRowHeight'])) { + $docSheet->getDefaultRowDimension()->setRowHeight( (float)$xmlSheet->sheetFormatPr['defaultRowHeight'] ); + } + if (isset($xmlSheet->sheetFormatPr['defaultColWidth'])) { + $docSheet->getDefaultColumnDimension()->setWidth( (float)$xmlSheet->sheetFormatPr['defaultColWidth'] ); + } + if (isset($xmlSheet->sheetFormatPr['zeroHeight']) && + ((string)$xmlSheet->sheetFormatPr['zeroHeight'] == '1')) { + $docSheet->getDefaultRowDimension()->setZeroHeight(true); + } + } + + if (isset($xmlSheet->cols) && !$this->_readDataOnly) { + foreach ($xmlSheet->cols->col as $col) { for ($i = intval($col["min"]) - 1; $i < intval($col["max"]); ++$i) { - if ($col["style"] && !$this->_readDataOnly) { - $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setXfIndex(intval($col["style"])); - } - if (self::boolean($col["bestFit"])) { - //$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(TRUE); - } - if (self::boolean($col["hidden"])) { + if ($col["style"] && !$this->_readDataOnly) { + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setXfIndex(intval($col["style"])); + } + if (self::boolean($col["bestFit"])) { + //$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(TRUE); + } + if (self::boolean($col["hidden"])) { // echo PHPExcel_Cell::stringFromColumnIndex($i),': HIDDEN COLUMN',PHP_EOL; - $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(FALSE); - } - if (self::boolean($col["collapsed"])) { - $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setCollapsed(TRUE); - } - if ($col["outlineLevel"] > 0) { - $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setOutlineLevel(intval($col["outlineLevel"])); - } - $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setWidth(floatval($col["width"])); - - if (intval($col["max"]) == 16384) { - break; - } - } - } - } - - if (isset($xmlSheet->printOptions) && !$this->_readDataOnly) { - if (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) { - $docSheet->setShowGridlines(TRUE); - } - - if (self::boolean((string) $xmlSheet->printOptions['gridLines'])) { - $docSheet->setPrintGridlines(TRUE); - } - - if (self::boolean((string) $xmlSheet->printOptions['horizontalCentered'])) { - $docSheet->getPageSetup()->setHorizontalCentered(TRUE); - } - if (self::boolean((string) $xmlSheet->printOptions['verticalCentered'])) { - $docSheet->getPageSetup()->setVerticalCentered(TRUE); - } - } - - if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) { - foreach ($xmlSheet->sheetData->row as $row) { - if ($row["ht"] && !$this->_readDataOnly) { - $docSheet->getRowDimension(intval($row["r"]))->setRowHeight(floatval($row["ht"])); - } - if (self::boolean($row["hidden"]) && !$this->_readDataOnly) { - $docSheet->getRowDimension(intval($row["r"]))->setVisible(FALSE); - } - if (self::boolean($row["collapsed"])) { - $docSheet->getRowDimension(intval($row["r"]))->setCollapsed(TRUE); - } - if ($row["outlineLevel"] > 0) { - $docSheet->getRowDimension(intval($row["r"]))->setOutlineLevel(intval($row["outlineLevel"])); - } - if ($row["s"] && !$this->_readDataOnly) { - $docSheet->getRowDimension(intval($row["r"]))->setXfIndex(intval($row["s"])); - } - - foreach ($row->c as $c) { - $r = (string) $c["r"]; - $cellDataType = (string) $c["t"]; - $value = null; - $calculatedValue = null; - - // Read cell? - if ($this->getReadFilter() !== NULL) { - $coordinates = PHPExcel_Cell::coordinateFromString($r); - - if (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) { - continue; - } - } - - // echo 'Reading cell ', $coordinates[0], $coordinates[1], PHP_EOL; - // print_r($c); - // echo PHP_EOL; - // echo 'Cell Data Type is ', $cellDataType, ': '; - // - // Read cell! - switch ($cellDataType) { - case "s": - // echo 'String', PHP_EOL; - if ((string)$c->v != '') { - $value = $sharedStrings[intval($c->v)]; - - if ($value instanceof PHPExcel_RichText) { - $value = clone $value; - } - } else { - $value = ''; - } - - break; - case "b": - // echo 'Boolean', PHP_EOL; - if (!isset($c->f)) { - $value = self::_castToBool($c); - } else { - // Formula - $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToBool'); - if (isset($c->f['t'])) { - $att = array(); - $att = $c->f; - $docSheet->getCell($r)->setFormulaAttributes($att); - } - // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; - } - break; - case "inlineStr": - // echo 'Inline String', PHP_EOL; - $value = $this->_parseRichText($c->is); - - break; - case "e": - // echo 'Error', PHP_EOL; - if (!isset($c->f)) { - $value = self::_castToError($c); - } else { - // Formula - $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToError'); - // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; - } - - break; - - default: - // echo 'Default', PHP_EOL; - if (!isset($c->f)) { - // echo 'Not a Formula', PHP_EOL; - $value = self::_castToString($c); - } else { - // echo 'Treat as Formula', PHP_EOL; - // Formula - $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToString'); - // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; - } - - break; - } - // echo 'Value is ', $value, PHP_EOL; - - // Check for numeric values - if (is_numeric($value) && $cellDataType != 's') { - if ($value == (int)$value) $value = (int)$value; - elseif ($value == (float)$value) $value = (float)$value; - elseif ($value == (double)$value) $value = (double)$value; - } - - // Rich text? - if ($value instanceof PHPExcel_RichText && $this->_readDataOnly) { - $value = $value->getPlainText(); - } - - $cell = $docSheet->getCell($r); - // Assign value - if ($cellDataType != '') { - $cell->setValueExplicit($value, $cellDataType); - } else { - $cell->setValue($value); - } - if ($calculatedValue !== NULL) { - $cell->setCalculatedValue($calculatedValue); - } - - // Style information? - if ($c["s"] && !$this->_readDataOnly) { - // no style index means 0, it seems - $cell->setXfIndex(isset($styles[intval($c["s"])]) ? - intval($c["s"]) : 0); - } - } - } - } - - $conditionals = array(); - if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) { - foreach ($xmlSheet->conditionalFormatting as $conditional) { - foreach ($conditional->cfRule as $cfRule) { - if ( - ( - (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_NONE || - (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CELLIS || - (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT || - (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_EXPRESSION - ) && isset($dxfs[intval($cfRule["dxfId"])]) - ) { - $conditionals[(string) $conditional["sqref"]][intval($cfRule["priority"])] = $cfRule; - } - } - } - - foreach ($conditionals as $ref => $cfRules) { - ksort($cfRules); - $conditionalStyles = array(); - foreach ($cfRules as $cfRule) { - $objConditional = new PHPExcel_Style_Conditional(); - $objConditional->setConditionType((string)$cfRule["type"]); - $objConditional->setOperatorType((string)$cfRule["operator"]); - - if ((string)$cfRule["text"] != '') { - $objConditional->setText((string)$cfRule["text"]); - } - - if (count($cfRule->formula) > 1) { - foreach ($cfRule->formula as $formula) { - $objConditional->addCondition((string)$formula); - } - } else { - $objConditional->addCondition((string)$cfRule->formula); - } - $objConditional->setStyle(clone $dxfs[intval($cfRule["dxfId"])]); - $conditionalStyles[] = $objConditional; - } - - // Extract all cell references in $ref - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($ref); - foreach ($aReferences as $reference) { - $docSheet->getStyle($reference)->setConditionalStyles($conditionalStyles); - } - } - } - - $aKeys = array("sheet", "objects", "scenarios", "formatCells", "formatColumns", "formatRows", "insertColumns", "insertRows", "insertHyperlinks", "deleteColumns", "deleteRows", "selectLockedCells", "sort", "autoFilter", "pivotTables", "selectUnlockedCells"); - if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { - foreach ($aKeys as $key) { - $method = "set" . ucfirst($key); - $docSheet->getProtection()->$method(self::boolean((string) $xmlSheet->sheetProtection[$key])); - } - } - - if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { - $docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection["password"], TRUE); - if ($xmlSheet->protectedRanges->protectedRange) { - foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) { - $docSheet->protectCells((string) $protectedRange["sqref"], (string) $protectedRange["password"], true); - } - } - } - - if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(FALSE); + } + if (self::boolean($col["collapsed"])) { + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setCollapsed(TRUE); + } + if ($col["outlineLevel"] > 0) { + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setOutlineLevel(intval($col["outlineLevel"])); + } + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setWidth(floatval($col["width"])); + + if (intval($col["max"]) == 16384) { + break; + } + } + } + } + + if (isset($xmlSheet->printOptions) && !$this->_readDataOnly) { + if (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) { + $docSheet->setShowGridlines(TRUE); + } + + if (self::boolean((string) $xmlSheet->printOptions['gridLines'])) { + $docSheet->setPrintGridlines(TRUE); + } + + if (self::boolean((string) $xmlSheet->printOptions['horizontalCentered'])) { + $docSheet->getPageSetup()->setHorizontalCentered(TRUE); + } + if (self::boolean((string) $xmlSheet->printOptions['verticalCentered'])) { + $docSheet->getPageSetup()->setVerticalCentered(TRUE); + } + } + + if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) { + foreach ($xmlSheet->sheetData->row as $row) { + if ($row["ht"] && !$this->_readDataOnly) { + $docSheet->getRowDimension(intval($row["r"]))->setRowHeight(floatval($row["ht"])); + } + if (self::boolean($row["hidden"]) && !$this->_readDataOnly) { + $docSheet->getRowDimension(intval($row["r"]))->setVisible(FALSE); + } + if (self::boolean($row["collapsed"])) { + $docSheet->getRowDimension(intval($row["r"]))->setCollapsed(TRUE); + } + if ($row["outlineLevel"] > 0) { + $docSheet->getRowDimension(intval($row["r"]))->setOutlineLevel(intval($row["outlineLevel"])); + } + if ($row["s"] && !$this->_readDataOnly) { + $docSheet->getRowDimension(intval($row["r"]))->setXfIndex(intval($row["s"])); + } + + foreach ($row->c as $c) { + $r = (string) $c["r"]; + $cellDataType = (string) $c["t"]; + $value = null; + $calculatedValue = null; + + // Read cell? + if ($this->getReadFilter() !== NULL) { + $coordinates = PHPExcel_Cell::coordinateFromString($r); + + if (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) { + continue; + } + } + + // echo 'Reading cell ', $coordinates[0], $coordinates[1], PHP_EOL; + // print_r($c); + // echo PHP_EOL; + // echo 'Cell Data Type is ', $cellDataType, ': '; + // + // Read cell! + switch ($cellDataType) { + case "s": + // echo 'String', PHP_EOL; + if ((string)$c->v != '') { + $value = $sharedStrings[intval($c->v)]; + + if ($value instanceof PHPExcel_RichText) { + $value = clone $value; + } + } else { + $value = ''; + } + + break; + case "b": + // echo 'Boolean', PHP_EOL; + if (!isset($c->f)) { + $value = self::_castToBool($c); + } else { + // Formula + $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToBool'); + if (isset($c->f['t'])) { + $att = array(); + $att = $c->f; + $docSheet->getCell($r)->setFormulaAttributes($att); + } + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; + } + break; + case "inlineStr": + // echo 'Inline String', PHP_EOL; + $value = $this->_parseRichText($c->is); + + break; + case "e": + // echo 'Error', PHP_EOL; + if (!isset($c->f)) { + $value = self::_castToError($c); + } else { + // Formula + $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToError'); + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; + } + + break; + + default: + // echo 'Default', PHP_EOL; + if (!isset($c->f)) { + // echo 'Not a Formula', PHP_EOL; + $value = self::_castToString($c); + } else { + // echo 'Treat as Formula', PHP_EOL; + // Formula + $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToString'); + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; + } + + break; + } + // echo 'Value is ', $value, PHP_EOL; + + // Check for numeric values + if (is_numeric($value) && $cellDataType != 's') { + if ($value == (int)$value) $value = (int)$value; + elseif ($value == (float)$value) $value = (float)$value; + elseif ($value == (double)$value) $value = (double)$value; + } + + // Rich text? + if ($value instanceof PHPExcel_RichText && $this->_readDataOnly) { + $value = $value->getPlainText(); + } + + $cell = $docSheet->getCell($r); + // Assign value + if ($cellDataType != '') { + $cell->setValueExplicit($value, $cellDataType); + } else { + $cell->setValue($value); + } + if ($calculatedValue !== NULL) { + $cell->setCalculatedValue($calculatedValue); + } + + // Style information? + if ($c["s"] && !$this->_readDataOnly) { + // no style index means 0, it seems + $cell->setXfIndex(isset($styles[intval($c["s"])]) ? + intval($c["s"]) : 0); + } + } + } + } + + $conditionals = array(); + if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) { + foreach ($xmlSheet->conditionalFormatting as $conditional) { + foreach ($conditional->cfRule as $cfRule) { + if ( + ( + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_NONE || + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CELLIS || + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT || + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + ) && isset($dxfs[intval($cfRule["dxfId"])]) + ) { + $conditionals[(string) $conditional["sqref"]][intval($cfRule["priority"])] = $cfRule; + } + } + } + + foreach ($conditionals as $ref => $cfRules) { + ksort($cfRules); + $conditionalStyles = array(); + foreach ($cfRules as $cfRule) { + $objConditional = new PHPExcel_Style_Conditional(); + $objConditional->setConditionType((string)$cfRule["type"]); + $objConditional->setOperatorType((string)$cfRule["operator"]); + + if ((string)$cfRule["text"] != '') { + $objConditional->setText((string)$cfRule["text"]); + } + + if (count($cfRule->formula) > 1) { + foreach ($cfRule->formula as $formula) { + $objConditional->addCondition((string)$formula); + } + } else { + $objConditional->addCondition((string)$cfRule->formula); + } + $objConditional->setStyle(clone $dxfs[intval($cfRule["dxfId"])]); + $conditionalStyles[] = $objConditional; + } + + // Extract all cell references in $ref + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($ref); + foreach ($aReferences as $reference) { + $docSheet->getStyle($reference)->setConditionalStyles($conditionalStyles); + } + } + } + + $aKeys = array("sheet", "objects", "scenarios", "formatCells", "formatColumns", "formatRows", "insertColumns", "insertRows", "insertHyperlinks", "deleteColumns", "deleteRows", "selectLockedCells", "sort", "autoFilter", "pivotTables", "selectUnlockedCells"); + if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { + foreach ($aKeys as $key) { + $method = "set" . ucfirst($key); + $docSheet->getProtection()->$method(self::boolean((string) $xmlSheet->sheetProtection[$key])); + } + } + + if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { + $docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection["password"], TRUE); + if ($xmlSheet->protectedRanges->protectedRange) { + foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) { + $docSheet->protectCells((string) $protectedRange["sqref"], (string) $protectedRange["password"], true); + } + } + } + + if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { $autoFilterRange = (string) $xmlSheet->autoFilter["ref"]; if (strpos($autoFilterRange, ':') !== false) { $autoFilter = $docSheet->getAutoFilter(); @@ -1013,30 +1013,30 @@ public function load($pFilename) foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); - // Check for standard filters + // Check for standard filters if ($filterColumn->filters) { $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER); $filters = $filterColumn->filters; if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL + NULL, // Operator is undefined, but always treated as EQUAL '' ) ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); } - // Standard filters are always an OR join, so no join rule needs to be set - // Entries can be either filter elements + // Standard filters are always an OR join, so no join rule needs to be set + // Entries can be either filter elements foreach ($filters->filter as $filterRule) { $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL + NULL, // Operator is undefined, but always treated as EQUAL (string) $filterRule["val"] ) ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); } - // Or Date Group elements + // Or Date Group elements foreach ($filters->dateGroupItem as $dateGroupItem) { $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL + NULL, // Operator is undefined, but always treated as EQUAL array( 'year' => (string) $dateGroupItem["year"], 'month' => (string) $dateGroupItem["month"], @@ -1050,12 +1050,12 @@ public function load($pFilename) ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); } } - // Check for custom filters + // Check for custom filters if ($filterColumn->customFilters) { $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER); $customFilters = $filterColumn->customFilters; - // Custom filters can an AND or an OR join; - // and there should only ever be one or two entries + // Custom filters can an AND or an OR join; + // and there should only ever be one or two entries if ((isset($customFilters["and"])) && ($customFilters["and"] == 1)) { $column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); } @@ -1067,13 +1067,13 @@ public function load($pFilename) ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); } } - // Check for dynamic filters + // Check for dynamic filters if ($filterColumn->dynamicFilter) { $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); - // We should only ever have one dynamic filter + // We should only ever have one dynamic filter foreach ($filterColumn->dynamicFilter as $filterRule) { $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL + NULL, // Operator is undefined, but always treated as EQUAL (string) $filterRule["val"], (string) $filterRule["type"] ) @@ -1086,10 +1086,10 @@ public function load($pFilename) } } } - // Check for dynamic filters + // Check for dynamic filters if ($filterColumn->top10) { $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER); - // We should only ever have one top10 filter + // We should only ever have one top10 filter foreach ($filterColumn->top10 as $filterRule) { $column->createRule()->setRule( (((isset($filterRule["percent"])) && ($filterRule["percent"] == 1)) @@ -1106,478 +1106,478 @@ public function load($pFilename) } } } - } - } - - if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) { - foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) { - $mergeRef = (string) $mergeCell["ref"]; - if (strpos($mergeRef,':') !== FALSE) { - $docSheet->mergeCells((string) $mergeCell["ref"]); - } - } - } - - if ($xmlSheet && $xmlSheet->pageMargins && !$this->_readDataOnly) { - $docPageMargins = $docSheet->getPageMargins(); - $docPageMargins->setLeft(floatval($xmlSheet->pageMargins["left"])); - $docPageMargins->setRight(floatval($xmlSheet->pageMargins["right"])); - $docPageMargins->setTop(floatval($xmlSheet->pageMargins["top"])); - $docPageMargins->setBottom(floatval($xmlSheet->pageMargins["bottom"])); - $docPageMargins->setHeader(floatval($xmlSheet->pageMargins["header"])); - $docPageMargins->setFooter(floatval($xmlSheet->pageMargins["footer"])); - } - - if ($xmlSheet && $xmlSheet->pageSetup && !$this->_readDataOnly) { - $docPageSetup = $docSheet->getPageSetup(); - - if (isset($xmlSheet->pageSetup["orientation"])) { - $docPageSetup->setOrientation((string) $xmlSheet->pageSetup["orientation"]); - } - if (isset($xmlSheet->pageSetup["paperSize"])) { - $docPageSetup->setPaperSize(intval($xmlSheet->pageSetup["paperSize"])); - } - if (isset($xmlSheet->pageSetup["scale"])) { - $docPageSetup->setScale(intval($xmlSheet->pageSetup["scale"]), FALSE); - } - if (isset($xmlSheet->pageSetup["fitToHeight"]) && intval($xmlSheet->pageSetup["fitToHeight"]) >= 0) { - $docPageSetup->setFitToHeight(intval($xmlSheet->pageSetup["fitToHeight"]), FALSE); - } - if (isset($xmlSheet->pageSetup["fitToWidth"]) && intval($xmlSheet->pageSetup["fitToWidth"]) >= 0) { - $docPageSetup->setFitToWidth(intval($xmlSheet->pageSetup["fitToWidth"]), FALSE); - } - if (isset($xmlSheet->pageSetup["firstPageNumber"]) && isset($xmlSheet->pageSetup["useFirstPageNumber"]) && - self::boolean((string) $xmlSheet->pageSetup["useFirstPageNumber"])) { - $docPageSetup->setFirstPageNumber(intval($xmlSheet->pageSetup["firstPageNumber"])); - } - } - - if ($xmlSheet && $xmlSheet->headerFooter && !$this->_readDataOnly) { - $docHeaderFooter = $docSheet->getHeaderFooter(); - - if (isset($xmlSheet->headerFooter["differentOddEven"]) && - self::boolean((string)$xmlSheet->headerFooter["differentOddEven"])) { - $docHeaderFooter->setDifferentOddEven(TRUE); - } else { - $docHeaderFooter->setDifferentOddEven(FALSE); - } - if (isset($xmlSheet->headerFooter["differentFirst"]) && - self::boolean((string)$xmlSheet->headerFooter["differentFirst"])) { - $docHeaderFooter->setDifferentFirst(TRUE); - } else { - $docHeaderFooter->setDifferentFirst(FALSE); - } - if (isset($xmlSheet->headerFooter["scaleWithDoc"]) && - !self::boolean((string)$xmlSheet->headerFooter["scaleWithDoc"])) { - $docHeaderFooter->setScaleWithDocument(FALSE); - } else { - $docHeaderFooter->setScaleWithDocument(TRUE); - } - if (isset($xmlSheet->headerFooter["alignWithMargins"]) && - !self::boolean((string)$xmlSheet->headerFooter["alignWithMargins"])) { - $docHeaderFooter->setAlignWithMargins(FALSE); - } else { - $docHeaderFooter->setAlignWithMargins(TRUE); - } - - $docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader); - $docHeaderFooter->setOddFooter((string) $xmlSheet->headerFooter->oddFooter); - $docHeaderFooter->setEvenHeader((string) $xmlSheet->headerFooter->evenHeader); - $docHeaderFooter->setEvenFooter((string) $xmlSheet->headerFooter->evenFooter); - $docHeaderFooter->setFirstHeader((string) $xmlSheet->headerFooter->firstHeader); - $docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter); - } - - if ($xmlSheet && $xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk && !$this->_readDataOnly) { - foreach ($xmlSheet->rowBreaks->brk as $brk) { - if ($brk["man"]) { - $docSheet->setBreak("A$brk[id]", PHPExcel_Worksheet::BREAK_ROW); - } - } - } - if ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->_readDataOnly) { - foreach ($xmlSheet->colBreaks->brk as $brk) { - if ($brk["man"]) { - $docSheet->setBreak(PHPExcel_Cell::stringFromColumnIndex((string) $brk["id"]) . "1", PHPExcel_Worksheet::BREAK_COLUMN); - } - } - } - - if ($xmlSheet && $xmlSheet->dataValidations && !$this->_readDataOnly) { - foreach ($xmlSheet->dataValidations->dataValidation as $dataValidation) { - // Uppercase coordinate - $range = strtoupper($dataValidation["sqref"]); - $rangeSet = explode(' ',$range); - foreach($rangeSet as $range) { - $stRange = $docSheet->shrinkRangeToFit($range); - - // Extract all cell references in $range - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); - foreach ($aReferences as $reference) { - // Create validation - $docValidation = $docSheet->getCell($reference)->getDataValidation(); - $docValidation->setType((string) $dataValidation["type"]); - $docValidation->setErrorStyle((string) $dataValidation["errorStyle"]); - $docValidation->setOperator((string) $dataValidation["operator"]); - $docValidation->setAllowBlank($dataValidation["allowBlank"] != 0); - $docValidation->setShowDropDown($dataValidation["showDropDown"] == 0); - $docValidation->setShowInputMessage($dataValidation["showInputMessage"] != 0); - $docValidation->setShowErrorMessage($dataValidation["showErrorMessage"] != 0); - $docValidation->setErrorTitle((string) $dataValidation["errorTitle"]); - $docValidation->setError((string) $dataValidation["error"]); - $docValidation->setPromptTitle((string) $dataValidation["promptTitle"]); - $docValidation->setPrompt((string) $dataValidation["prompt"]); - $docValidation->setFormula1((string) $dataValidation->formula1); - $docValidation->setFormula2((string) $dataValidation->formula2); - } - } - } - } - - // Add hyperlinks - $hyperlinks = array(); - if (!$this->_readDataOnly) { - // Locate hyperlink relations - if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - foreach ($relsWorksheet->Relationship as $ele) { - if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") { - $hyperlinks[(string)$ele["Id"]] = (string)$ele["Target"]; - } - } - } - - // Loop through hyperlinks - if ($xmlSheet && $xmlSheet->hyperlinks) { - foreach ($xmlSheet->hyperlinks->hyperlink as $hyperlink) { - // Link url - $linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - - foreach (PHPExcel_Cell::extractAllCellReferencesInRange($hyperlink['ref']) as $cellReference) { - $cell = $docSheet->getCell( $cellReference ); - if (isset($linkRel['id'])) { - $hyperlinkUrl = $hyperlinks[ (string)$linkRel['id'] ]; - if (isset($hyperlink['location'])) { - $hyperlinkUrl .= '#' . (string) $hyperlink['location']; - } - $cell->getHyperlink()->setUrl($hyperlinkUrl); - } elseif (isset($hyperlink['location'])) { - $cell->getHyperlink()->setUrl( 'sheet://' . (string)$hyperlink['location'] ); - } - - // Tooltip - if (isset($hyperlink['tooltip'])) { - $cell->getHyperlink()->setTooltip( (string)$hyperlink['tooltip'] ); - } - } - } - } - } - - // Add comments - $comments = array(); - $vmlComments = array(); - if (!$this->_readDataOnly) { - // Locate comment relations - if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - foreach ($relsWorksheet->Relationship as $ele) { - if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") { - $comments[(string)$ele["Id"]] = (string)$ele["Target"]; - } - if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") { - $vmlComments[(string)$ele["Id"]] = (string)$ele["Target"]; - } - } - } - - // Loop through comments - foreach ($comments as $relName => $relPath) { - // Load comments file - $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); - $commentsFile = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - - // Utility variables - $authors = array(); - - // Loop through authors - foreach ($commentsFile->authors->author as $author) { - $authors[] = (string)$author; - } - - // Loop through contents - foreach ($commentsFile->commentList->comment as $comment) { - if(!empty($comment['authorId'])) - $docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] ); - $docSheet->getComment( (string)$comment['ref'] )->setText( $this->_parseRichText($comment->text) ); - } - } - - // Loop through VML comments - foreach ($vmlComments as $relName => $relPath) { - // Load VML comments file - $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); - $vmlCommentsFile = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); - - $shapes = $vmlCommentsFile->xpath('//v:shape'); - foreach ($shapes as $shape) { - $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); - - if (isset($shape['style'])) { - $style = (string)$shape['style']; - $fillColor = strtoupper( substr( (string)$shape['fillcolor'], 1 ) ); - $column = null; - $row = null; - - $clientData = $shape->xpath('.//x:ClientData'); - if (is_array($clientData) && !empty($clientData)) { - $clientData = $clientData[0]; - - if ( isset($clientData['ObjectType']) && (string)$clientData['ObjectType'] == 'Note' ) { - $temp = $clientData->xpath('.//x:Row'); - if (is_array($temp)) $row = $temp[0]; - - $temp = $clientData->xpath('.//x:Column'); - if (is_array($temp)) $column = $temp[0]; - } - } - - if (($column !== NULL) && ($row !== NULL)) { - // Set comment properties - $comment = $docSheet->getCommentByColumnAndRow((string) $column, $row + 1); - $comment->getFillColor()->setRGB( $fillColor ); - - // Parse style - $styleArray = explode(';', str_replace(' ', '', $style)); - foreach ($styleArray as $stylePair) { - $stylePair = explode(':', $stylePair); - - if ($stylePair[0] == 'margin-left') $comment->setMarginLeft($stylePair[1]); - if ($stylePair[0] == 'margin-top') $comment->setMarginTop($stylePair[1]); - if ($stylePair[0] == 'width') $comment->setWidth($stylePair[1]); - if ($stylePair[0] == 'height') $comment->setHeight($stylePair[1]); - if ($stylePair[0] == 'visibility') $comment->setVisible( $stylePair[1] == 'visible' ); - - } - } - } - } - } - - // Header/footer images - if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) { - if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - $vmlRelationship = ''; - - foreach ($relsWorksheet->Relationship as $ele) { - if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") { - $vmlRelationship = self::dir_add("$dir/$fileWorksheet", $ele["Target"]); - } - } - - if ($vmlRelationship != '') { - // Fetch linked images - $relsVML = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - $drawings = array(); - foreach ($relsVML->Relationship as $ele) { - if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { - $drawings[(string) $ele["Id"]] = self::dir_add($vmlRelationship, $ele["Target"]); - } - } - - // Fetch VML document - $vmlDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $vmlRelationship)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); - - $hfImages = array(); - - $shapes = $vmlDrawing->xpath('//v:shape'); - foreach ($shapes as $idx => $shape) { - $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); - $imageData = $shape->xpath('//v:imagedata'); - $imageData = $imageData[$idx]; - - $imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office'); - $style = self::toCSSArray( (string)$shape['style'] ); - - $hfImages[ (string)$shape['id'] ] = new PHPExcel_Worksheet_HeaderFooterDrawing(); - if (isset($imageData['title'])) { - $hfImages[ (string)$shape['id'] ]->setName( (string)$imageData['title'] ); - } - - $hfImages[ (string)$shape['id'] ]->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $drawings[(string)$imageData['relid']], false); - $hfImages[ (string)$shape['id'] ]->setResizeProportional(false); - $hfImages[ (string)$shape['id'] ]->setWidth($style['width']); - $hfImages[ (string)$shape['id'] ]->setHeight($style['height']); - if (isset($style['margin-left'])) { - $hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']); - } - $hfImages[ (string)$shape['id'] ]->setOffsetY($style['margin-top']); - $hfImages[ (string)$shape['id'] ]->setResizeProportional(true); - } - - $docSheet->getHeaderFooter()->setImages($hfImages); - } - } - } - - } + } + } + + if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) { + foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) { + $mergeRef = (string) $mergeCell["ref"]; + if (strpos($mergeRef,':') !== FALSE) { + $docSheet->mergeCells((string) $mergeCell["ref"]); + } + } + } + + if ($xmlSheet && $xmlSheet->pageMargins && !$this->_readDataOnly) { + $docPageMargins = $docSheet->getPageMargins(); + $docPageMargins->setLeft(floatval($xmlSheet->pageMargins["left"])); + $docPageMargins->setRight(floatval($xmlSheet->pageMargins["right"])); + $docPageMargins->setTop(floatval($xmlSheet->pageMargins["top"])); + $docPageMargins->setBottom(floatval($xmlSheet->pageMargins["bottom"])); + $docPageMargins->setHeader(floatval($xmlSheet->pageMargins["header"])); + $docPageMargins->setFooter(floatval($xmlSheet->pageMargins["footer"])); + } + + if ($xmlSheet && $xmlSheet->pageSetup && !$this->_readDataOnly) { + $docPageSetup = $docSheet->getPageSetup(); + + if (isset($xmlSheet->pageSetup["orientation"])) { + $docPageSetup->setOrientation((string) $xmlSheet->pageSetup["orientation"]); + } + if (isset($xmlSheet->pageSetup["paperSize"])) { + $docPageSetup->setPaperSize(intval($xmlSheet->pageSetup["paperSize"])); + } + if (isset($xmlSheet->pageSetup["scale"])) { + $docPageSetup->setScale(intval($xmlSheet->pageSetup["scale"]), FALSE); + } + if (isset($xmlSheet->pageSetup["fitToHeight"]) && intval($xmlSheet->pageSetup["fitToHeight"]) >= 0) { + $docPageSetup->setFitToHeight(intval($xmlSheet->pageSetup["fitToHeight"]), FALSE); + } + if (isset($xmlSheet->pageSetup["fitToWidth"]) && intval($xmlSheet->pageSetup["fitToWidth"]) >= 0) { + $docPageSetup->setFitToWidth(intval($xmlSheet->pageSetup["fitToWidth"]), FALSE); + } + if (isset($xmlSheet->pageSetup["firstPageNumber"]) && isset($xmlSheet->pageSetup["useFirstPageNumber"]) && + self::boolean((string) $xmlSheet->pageSetup["useFirstPageNumber"])) { + $docPageSetup->setFirstPageNumber(intval($xmlSheet->pageSetup["firstPageNumber"])); + } + } + + if ($xmlSheet && $xmlSheet->headerFooter && !$this->_readDataOnly) { + $docHeaderFooter = $docSheet->getHeaderFooter(); + + if (isset($xmlSheet->headerFooter["differentOddEven"]) && + self::boolean((string)$xmlSheet->headerFooter["differentOddEven"])) { + $docHeaderFooter->setDifferentOddEven(TRUE); + } else { + $docHeaderFooter->setDifferentOddEven(FALSE); + } + if (isset($xmlSheet->headerFooter["differentFirst"]) && + self::boolean((string)$xmlSheet->headerFooter["differentFirst"])) { + $docHeaderFooter->setDifferentFirst(TRUE); + } else { + $docHeaderFooter->setDifferentFirst(FALSE); + } + if (isset($xmlSheet->headerFooter["scaleWithDoc"]) && + !self::boolean((string)$xmlSheet->headerFooter["scaleWithDoc"])) { + $docHeaderFooter->setScaleWithDocument(FALSE); + } else { + $docHeaderFooter->setScaleWithDocument(TRUE); + } + if (isset($xmlSheet->headerFooter["alignWithMargins"]) && + !self::boolean((string)$xmlSheet->headerFooter["alignWithMargins"])) { + $docHeaderFooter->setAlignWithMargins(FALSE); + } else { + $docHeaderFooter->setAlignWithMargins(TRUE); + } + + $docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader); + $docHeaderFooter->setOddFooter((string) $xmlSheet->headerFooter->oddFooter); + $docHeaderFooter->setEvenHeader((string) $xmlSheet->headerFooter->evenHeader); + $docHeaderFooter->setEvenFooter((string) $xmlSheet->headerFooter->evenFooter); + $docHeaderFooter->setFirstHeader((string) $xmlSheet->headerFooter->firstHeader); + $docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter); + } + + if ($xmlSheet && $xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk && !$this->_readDataOnly) { + foreach ($xmlSheet->rowBreaks->brk as $brk) { + if ($brk["man"]) { + $docSheet->setBreak("A$brk[id]", PHPExcel_Worksheet::BREAK_ROW); + } + } + } + if ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->_readDataOnly) { + foreach ($xmlSheet->colBreaks->brk as $brk) { + if ($brk["man"]) { + $docSheet->setBreak(PHPExcel_Cell::stringFromColumnIndex((string) $brk["id"]) . "1", PHPExcel_Worksheet::BREAK_COLUMN); + } + } + } + + if ($xmlSheet && $xmlSheet->dataValidations && !$this->_readDataOnly) { + foreach ($xmlSheet->dataValidations->dataValidation as $dataValidation) { + // Uppercase coordinate + $range = strtoupper($dataValidation["sqref"]); + $rangeSet = explode(' ',$range); + foreach($rangeSet as $range) { + $stRange = $docSheet->shrinkRangeToFit($range); + + // Extract all cell references in $range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); + foreach ($aReferences as $reference) { + // Create validation + $docValidation = $docSheet->getCell($reference)->getDataValidation(); + $docValidation->setType((string) $dataValidation["type"]); + $docValidation->setErrorStyle((string) $dataValidation["errorStyle"]); + $docValidation->setOperator((string) $dataValidation["operator"]); + $docValidation->setAllowBlank($dataValidation["allowBlank"] != 0); + $docValidation->setShowDropDown($dataValidation["showDropDown"] == 0); + $docValidation->setShowInputMessage($dataValidation["showInputMessage"] != 0); + $docValidation->setShowErrorMessage($dataValidation["showErrorMessage"] != 0); + $docValidation->setErrorTitle((string) $dataValidation["errorTitle"]); + $docValidation->setError((string) $dataValidation["error"]); + $docValidation->setPromptTitle((string) $dataValidation["promptTitle"]); + $docValidation->setPrompt((string) $dataValidation["prompt"]); + $docValidation->setFormula1((string) $dataValidation->formula1); + $docValidation->setFormula2((string) $dataValidation->formula2); + } + } + } + } + + // Add hyperlinks + $hyperlinks = array(); + if (!$this->_readDataOnly) { + // Locate hyperlink relations + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") { + $hyperlinks[(string)$ele["Id"]] = (string)$ele["Target"]; + } + } + } + + // Loop through hyperlinks + if ($xmlSheet && $xmlSheet->hyperlinks) { + foreach ($xmlSheet->hyperlinks->hyperlink as $hyperlink) { + // Link url + $linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($hyperlink['ref']) as $cellReference) { + $cell = $docSheet->getCell( $cellReference ); + if (isset($linkRel['id'])) { + $hyperlinkUrl = $hyperlinks[ (string)$linkRel['id'] ]; + if (isset($hyperlink['location'])) { + $hyperlinkUrl .= '#' . (string) $hyperlink['location']; + } + $cell->getHyperlink()->setUrl($hyperlinkUrl); + } elseif (isset($hyperlink['location'])) { + $cell->getHyperlink()->setUrl( 'sheet://' . (string)$hyperlink['location'] ); + } + + // Tooltip + if (isset($hyperlink['tooltip'])) { + $cell->getHyperlink()->setTooltip( (string)$hyperlink['tooltip'] ); + } + } + } + } + } + + // Add comments + $comments = array(); + $vmlComments = array(); + if (!$this->_readDataOnly) { + // Locate comment relations + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") { + $comments[(string)$ele["Id"]] = (string)$ele["Target"]; + } + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") { + $vmlComments[(string)$ele["Id"]] = (string)$ele["Target"]; + } + } + } + + // Loop through comments + foreach ($comments as $relName => $relPath) { + // Load comments file + $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); + $commentsFile = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + + // Utility variables + $authors = array(); + + // Loop through authors + foreach ($commentsFile->authors->author as $author) { + $authors[] = (string)$author; + } + + // Loop through contents + foreach ($commentsFile->commentList->comment as $comment) { + if(!empty($comment['authorId'])) + $docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] ); + $docSheet->getComment( (string)$comment['ref'] )->setText( $this->_parseRichText($comment->text) ); + } + } + + // Loop through VML comments + foreach ($vmlComments as $relName => $relPath) { + // Load VML comments file + $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); + $vmlCommentsFile = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + + $shapes = $vmlCommentsFile->xpath('//v:shape'); + foreach ($shapes as $shape) { + $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + + if (isset($shape['style'])) { + $style = (string)$shape['style']; + $fillColor = strtoupper( substr( (string)$shape['fillcolor'], 1 ) ); + $column = null; + $row = null; + + $clientData = $shape->xpath('.//x:ClientData'); + if (is_array($clientData) && !empty($clientData)) { + $clientData = $clientData[0]; + + if ( isset($clientData['ObjectType']) && (string)$clientData['ObjectType'] == 'Note' ) { + $temp = $clientData->xpath('.//x:Row'); + if (is_array($temp)) $row = $temp[0]; + + $temp = $clientData->xpath('.//x:Column'); + if (is_array($temp)) $column = $temp[0]; + } + } + + if (($column !== NULL) && ($row !== NULL)) { + // Set comment properties + $comment = $docSheet->getCommentByColumnAndRow((string) $column, $row + 1); + $comment->getFillColor()->setRGB( $fillColor ); + + // Parse style + $styleArray = explode(';', str_replace(' ', '', $style)); + foreach ($styleArray as $stylePair) { + $stylePair = explode(':', $stylePair); + + if ($stylePair[0] == 'margin-left') $comment->setMarginLeft($stylePair[1]); + if ($stylePair[0] == 'margin-top') $comment->setMarginTop($stylePair[1]); + if ($stylePair[0] == 'width') $comment->setWidth($stylePair[1]); + if ($stylePair[0] == 'height') $comment->setHeight($stylePair[1]); + if ($stylePair[0] == 'visibility') $comment->setVisible( $stylePair[1] == 'visible' ); + + } + } + } + } + } + + // Header/footer images + if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) { + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $vmlRelationship = ''; + + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") { + $vmlRelationship = self::dir_add("$dir/$fileWorksheet", $ele["Target"]); + } + } + + if ($vmlRelationship != '') { + // Fetch linked images + $relsVML = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $drawings = array(); + foreach ($relsVML->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { + $drawings[(string) $ele["Id"]] = self::dir_add($vmlRelationship, $ele["Target"]); + } + } + + // Fetch VML document + $vmlDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $vmlRelationship)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + + $hfImages = array(); + + $shapes = $vmlDrawing->xpath('//v:shape'); + foreach ($shapes as $idx => $shape) { + $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + $imageData = $shape->xpath('//v:imagedata'); + $imageData = $imageData[$idx]; + + $imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office'); + $style = self::toCSSArray( (string)$shape['style'] ); + + $hfImages[ (string)$shape['id'] ] = new PHPExcel_Worksheet_HeaderFooterDrawing(); + if (isset($imageData['title'])) { + $hfImages[ (string)$shape['id'] ]->setName( (string)$imageData['title'] ); + } + + $hfImages[ (string)$shape['id'] ]->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $drawings[(string)$imageData['relid']], false); + $hfImages[ (string)$shape['id'] ]->setResizeProportional(false); + $hfImages[ (string)$shape['id'] ]->setWidth($style['width']); + $hfImages[ (string)$shape['id'] ]->setHeight($style['height']); + if (isset($style['margin-left'])) { + $hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']); + } + $hfImages[ (string)$shape['id'] ]->setOffsetY($style['margin-top']); + $hfImages[ (string)$shape['id'] ]->setResizeProportional(true); + } + + $docSheet->getHeaderFooter()->setImages($hfImages); + } + } + } + + } // TODO: Autoshapes from twoCellAnchors! - if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - $drawings = array(); - foreach ($relsWorksheet->Relationship as $ele) { - if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing") { - $drawings[(string) $ele["Id"]] = self::dir_add("$dir/$fileWorksheet", $ele["Target"]); - } - } - if ($xmlSheet->drawing && !$this->_readDataOnly) { - foreach ($xmlSheet->drawing as $drawing) { - $fileDrawing = $drawings[(string) self::array_item($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; - $relsDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); - $images = array(); - - if ($relsDrawing && $relsDrawing->Relationship) { - foreach ($relsDrawing->Relationship as $ele) { - if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { - $images[(string) $ele["Id"]] = self::dir_add($fileDrawing, $ele["Target"]); - } elseif ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart") { - if ($this->_includeCharts) { - $charts[self::dir_add($fileDrawing, $ele["Target"])] = array('id' => (string) $ele["Id"], - 'sheet' => $docSheet->getTitle() - ); - } - } - } - } - $xmlDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $fileDrawing)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"); - - if ($xmlDrawing->oneCellAnchor) { - foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) { - if ($oneCellAnchor->pic->blipFill) { - $blip = $oneCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip; - $xfrm = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm; - $outerShdw = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw; - $objDrawing = new PHPExcel_Worksheet_Drawing; - $objDrawing->setName((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); - $objDrawing->setDescription((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); - $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); - $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1)); - $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff)); - $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff)); - $objDrawing->setResizeProportional(false); - $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx"))); - $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy"))); - if ($xfrm) { - $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); - } - if ($outerShdw) { - $shadow = $objDrawing->getShadow(); - $shadow->setVisible(true); - $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad"))); - $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist"))); - $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir"))); - $shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn")); - $shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val")); - $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); - } - $objDrawing->setWorksheet($docSheet); - } else { - // ? Can charts be positioned with a oneCellAnchor ? - $coordinates = PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1); - $offsetX = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff); - $offsetY = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff); - $width = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx")); - $height = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy")); - } - } - } - if ($xmlDrawing->twoCellAnchor) { - foreach ($xmlDrawing->twoCellAnchor as $twoCellAnchor) { - if ($twoCellAnchor->pic->blipFill) { - $blip = $twoCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip; - $xfrm = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm; - $outerShdw = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw; - $objDrawing = new PHPExcel_Worksheet_Drawing; - $objDrawing->setName((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); - $objDrawing->setDescription((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); - $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); - $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1)); - $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff)); - $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff)); - $objDrawing->setResizeProportional(false); - - if ($xfrm) { - $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cx"))); - $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cy"))); - $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); - } - if ($outerShdw) { - $shadow = $objDrawing->getShadow(); - $shadow->setVisible(true); - $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad"))); - $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist"))); - $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir"))); - $shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn")); - $shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val")); - $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); - } - $objDrawing->setWorksheet($docSheet); - } elseif(($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { - $fromCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1); - $fromOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff); - $fromOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff); - $toCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->to->col) . ($twoCellAnchor->to->row + 1); - $toOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->colOff); - $toOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->rowOff); - $graphic = $twoCellAnchor->graphicFrame->children("http://schemas.openxmlformats.org/drawingml/2006/main")->graphic; - $chartRef = $graphic->graphicData->children("http://schemas.openxmlformats.org/drawingml/2006/chart")->chart; - $thisChart = (string) $chartRef->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"); - - $chartDetails[$docSheet->getTitle().'!'.$thisChart] = - array( 'fromCoordinate' => $fromCoordinate, - 'fromOffsetX' => $fromOffsetX, - 'fromOffsetY' => $fromOffsetY, - 'toCoordinate' => $toCoordinate, - 'toOffsetX' => $toOffsetX, - 'toOffsetY' => $toOffsetY, - 'worksheetTitle' => $docSheet->getTitle() - ); - } - } - } - - } - } - } - - // Loop through definedNames - if ($xmlWorkbook->definedNames) { - foreach ($xmlWorkbook->definedNames->definedName as $definedName) { - // Extract range - $extractedRange = (string)$definedName; - $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); - if (($spos = strpos($extractedRange,'!')) !== false) { - $extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos)); - } else { - $extractedRange = str_replace('$', '', $extractedRange); - } - - // Valid range? - if (stripos((string)$definedName, '#REF!') !== FALSE || $extractedRange == '') { - continue; - } - - // Some definedNames are only applicable if we are on the same sheet... - if ((string)$definedName['localSheetId'] != '' && (string)$definedName['localSheetId'] == $sheetId) { - // Switch on type - switch ((string)$definedName['name']) { - - case '_xlnm._FilterDatabase': - if ((string)$definedName['hidden'] !== '1') { + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $drawings = array(); + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing") { + $drawings[(string) $ele["Id"]] = self::dir_add("$dir/$fileWorksheet", $ele["Target"]); + } + } + if ($xmlSheet->drawing && !$this->_readDataOnly) { + foreach ($xmlSheet->drawing as $drawing) { + $fileDrawing = $drawings[(string) self::array_item($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + $relsDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $images = array(); + + if ($relsDrawing && $relsDrawing->Relationship) { + foreach ($relsDrawing->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { + $images[(string) $ele["Id"]] = self::dir_add($fileDrawing, $ele["Target"]); + } elseif ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart") { + if ($this->_includeCharts) { + $charts[self::dir_add($fileDrawing, $ele["Target"])] = array('id' => (string) $ele["Id"], + 'sheet' => $docSheet->getTitle() + ); + } + } + } + } + $xmlDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $fileDrawing)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"); + + if ($xmlDrawing->oneCellAnchor) { + foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) { + if ($oneCellAnchor->pic->blipFill) { + $blip = $oneCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip; + $xfrm = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm; + $outerShdw = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw; + $objDrawing = new PHPExcel_Worksheet_Drawing; + $objDrawing->setName((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); + $objDrawing->setDescription((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); + $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); + $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1)); + $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff)); + $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff)); + $objDrawing->setResizeProportional(false); + $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx"))); + $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy"))); + if ($xfrm) { + $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); + } + if ($outerShdw) { + $shadow = $objDrawing->getShadow(); + $shadow->setVisible(true); + $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad"))); + $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist"))); + $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir"))); + $shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn")); + $shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val")); + $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); + } + $objDrawing->setWorksheet($docSheet); + } else { + // ? Can charts be positioned with a oneCellAnchor ? + $coordinates = PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1); + $offsetX = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff); + $offsetY = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff); + $width = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx")); + $height = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy")); + } + } + } + if ($xmlDrawing->twoCellAnchor) { + foreach ($xmlDrawing->twoCellAnchor as $twoCellAnchor) { + if ($twoCellAnchor->pic->blipFill) { + $blip = $twoCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip; + $xfrm = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm; + $outerShdw = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw; + $objDrawing = new PHPExcel_Worksheet_Drawing; + $objDrawing->setName((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); + $objDrawing->setDescription((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); + $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); + $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1)); + $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff)); + $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff)); + $objDrawing->setResizeProportional(false); + + if ($xfrm) { + $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cx"))); + $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cy"))); + $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); + } + if ($outerShdw) { + $shadow = $objDrawing->getShadow(); + $shadow->setVisible(true); + $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad"))); + $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist"))); + $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir"))); + $shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn")); + $shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val")); + $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); + } + $objDrawing->setWorksheet($docSheet); + } elseif(($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { + $fromCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1); + $fromOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff); + $fromOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff); + $toCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->to->col) . ($twoCellAnchor->to->row + 1); + $toOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->colOff); + $toOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->rowOff); + $graphic = $twoCellAnchor->graphicFrame->children("http://schemas.openxmlformats.org/drawingml/2006/main")->graphic; + $chartRef = $graphic->graphicData->children("http://schemas.openxmlformats.org/drawingml/2006/chart")->chart; + $thisChart = (string) $chartRef->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + + $chartDetails[$docSheet->getTitle().'!'.$thisChart] = + array( 'fromCoordinate' => $fromCoordinate, + 'fromOffsetX' => $fromOffsetX, + 'fromOffsetY' => $fromOffsetY, + 'toCoordinate' => $toCoordinate, + 'toOffsetX' => $toOffsetX, + 'toOffsetY' => $toOffsetY, + 'worksheetTitle' => $docSheet->getTitle() + ); + } + } + } + + } + } + } + + // Loop through definedNames + if ($xmlWorkbook->definedNames) { + foreach ($xmlWorkbook->definedNames->definedName as $definedName) { + // Extract range + $extractedRange = (string)$definedName; + $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); + if (($spos = strpos($extractedRange,'!')) !== false) { + $extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos)); + } else { + $extractedRange = str_replace('$', '', $extractedRange); + } + + // Valid range? + if (stripos((string)$definedName, '#REF!') !== FALSE || $extractedRange == '') { + continue; + } + + // Some definedNames are only applicable if we are on the same sheet... + if ((string)$definedName['localSheetId'] != '' && (string)$definedName['localSheetId'] == $sheetId) { + // Switch on type + switch ((string)$definedName['name']) { + + case '_xlnm._FilterDatabase': + if ((string)$definedName['hidden'] !== '1') { $extractedRange = explode(',', $extractedRange); foreach ($extractedRange as $range) { $autoFilterRange = $range; @@ -1585,499 +1585,499 @@ public function load($pFilename) $docSheet->getAutoFilter()->setRange($autoFilterRange); } } - } - break; - - case '_xlnm.Print_Titles': - // Split $extractedRange - $extractedRange = explode(',', $extractedRange); - - // Set print titles - foreach ($extractedRange as $range) { - $matches = array(); - $range = str_replace('$', '', $range); - - // check for repeating columns, e g. 'A:A' or 'A:D' - if (preg_match('/!?([A-Z]+)\:([A-Z]+)$/', $range, $matches)) { - $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($matches[1], $matches[2])); - } - // check for repeating rows, e.g. '1:1' or '1:5' - elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) { - $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($matches[1], $matches[2])); - } - } - break; - - case '_xlnm.Print_Area': - $rangeSets = explode(',', $extractedRange); // FIXME: what if sheetname contains comma? - $newRangeSets = array(); - foreach($rangeSets as $rangeSet) { - $range = explode('!', $rangeSet); // FIXME: what if sheetname contains exclamation mark? - $rangeSet = isset($range[1]) ? $range[1] : $range[0]; - if (strpos($rangeSet, ':') === FALSE) { - $rangeSet = $rangeSet . ':' . $rangeSet; - } - $newRangeSets[] = str_replace('$', '', $rangeSet); - } - $docSheet->getPageSetup()->setPrintArea(implode(',',$newRangeSets)); - break; - - default: - break; - } - } - } - } - - // Next sheet id - ++$sheetId; - } - - // Loop through definedNames - if ($xmlWorkbook->definedNames) { - foreach ($xmlWorkbook->definedNames->definedName as $definedName) { - // Extract range - $extractedRange = (string)$definedName; - $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); - if (($spos = strpos($extractedRange,'!')) !== false) { - $extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos)); - } else { - $extractedRange = str_replace('$', '', $extractedRange); - } - - // Valid range? - if (stripos((string)$definedName, '#REF!') !== false || $extractedRange == '') { - continue; - } - - // Some definedNames are only applicable if we are on the same sheet... - if ((string)$definedName['localSheetId'] != '') { - // Local defined name - // Switch on type - switch ((string)$definedName['name']) { - - case '_xlnm._FilterDatabase': - case '_xlnm.Print_Titles': - case '_xlnm.Print_Area': - break; - - default: - if ($mapSheetId[(integer) $definedName['localSheetId']] !== null) { - $range = explode('!', (string)$definedName); - if (count($range) == 2) { - $range[0] = str_replace("''", "'", $range[0]); - $range[0] = str_replace("'", "", $range[0]); - if ($worksheet = $docSheet->getParent()->getSheetByName($range[0])) { - $extractedRange = str_replace('$', '', $range[1]); - $scope = $docSheet->getParent()->getSheet($mapSheetId[(integer) $definedName['localSheetId']]); - $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $worksheet, $extractedRange, true, $scope) ); - } - } - } - break; - } - } else if (!isset($definedName['localSheetId'])) { - // "Global" definedNames - $locatedSheet = null; - $extractedSheetName = ''; - if (strpos( (string)$definedName, '!' ) !== false) { - // Extract sheet name - $extractedSheetName = PHPExcel_Worksheet::extractSheetTitle( (string)$definedName, true ); - $extractedSheetName = $extractedSheetName[0]; - - // Locate sheet - $locatedSheet = $excel->getSheetByName($extractedSheetName); - - // Modify range - $range = explode('!', $extractedRange); - $extractedRange = isset($range[1]) ? $range[1] : $range[0]; - } - - if ($locatedSheet !== NULL) { - $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $locatedSheet, $extractedRange, false) ); - } - } - } - } - } - - if ((!$this->_readDataOnly) || (!empty($this->_loadSheetsOnly))) { - // active sheet index - $activeTab = intval($xmlWorkbook->bookViews->workbookView["activeTab"]); // refers to old sheet index - - // keep active sheet index if sheet is still loaded, else first sheet is set as the active - if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) { - $excel->setActiveSheetIndex($mapSheetId[$activeTab]); - } else { - if ($excel->getSheetCount() == 0) { - $excel->createSheet(); - } - $excel->setActiveSheetIndex(0); - } - } - break; - } - - } - - - if (!$this->_readDataOnly) { - $contentTypes = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "[Content_Types].xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - foreach ($contentTypes->Override as $contentType) { - switch ($contentType["ContentType"]) { - case "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": - if ($this->_includeCharts) { - $chartEntryRef = ltrim($contentType['PartName'],'/'); - $chartElements = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $chartEntryRef)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef,'.xml')); - -// echo 'Chart ',$chartEntryRef,'
'; -// var_dump($charts[$chartEntryRef]); + } + break; + + case '_xlnm.Print_Titles': + // Split $extractedRange + $extractedRange = explode(',', $extractedRange); + + // Set print titles + foreach ($extractedRange as $range) { + $matches = array(); + $range = str_replace('$', '', $range); + + // check for repeating columns, e g. 'A:A' or 'A:D' + if (preg_match('/!?([A-Z]+)\:([A-Z]+)$/', $range, $matches)) { + $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($matches[1], $matches[2])); + } + // check for repeating rows, e.g. '1:1' or '1:5' + elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) { + $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($matches[1], $matches[2])); + } + } + break; + + case '_xlnm.Print_Area': + $rangeSets = explode(',', $extractedRange); // FIXME: what if sheetname contains comma? + $newRangeSets = array(); + foreach($rangeSets as $rangeSet) { + $range = explode('!', $rangeSet); // FIXME: what if sheetname contains exclamation mark? + $rangeSet = isset($range[1]) ? $range[1] : $range[0]; + if (strpos($rangeSet, ':') === FALSE) { + $rangeSet = $rangeSet . ':' . $rangeSet; + } + $newRangeSets[] = str_replace('$', '', $rangeSet); + } + $docSheet->getPageSetup()->setPrintArea(implode(',',$newRangeSets)); + break; + + default: + break; + } + } + } + } + + // Next sheet id + ++$sheetId; + } + + // Loop through definedNames + if ($xmlWorkbook->definedNames) { + foreach ($xmlWorkbook->definedNames->definedName as $definedName) { + // Extract range + $extractedRange = (string)$definedName; + $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); + if (($spos = strpos($extractedRange,'!')) !== false) { + $extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos)); + } else { + $extractedRange = str_replace('$', '', $extractedRange); + } + + // Valid range? + if (stripos((string)$definedName, '#REF!') !== false || $extractedRange == '') { + continue; + } + + // Some definedNames are only applicable if we are on the same sheet... + if ((string)$definedName['localSheetId'] != '') { + // Local defined name + // Switch on type + switch ((string)$definedName['name']) { + + case '_xlnm._FilterDatabase': + case '_xlnm.Print_Titles': + case '_xlnm.Print_Area': + break; + + default: + if ($mapSheetId[(integer) $definedName['localSheetId']] !== null) { + $range = explode('!', (string)$definedName); + if (count($range) == 2) { + $range[0] = str_replace("''", "'", $range[0]); + $range[0] = str_replace("'", "", $range[0]); + if ($worksheet = $docSheet->getParent()->getSheetByName($range[0])) { + $extractedRange = str_replace('$', '', $range[1]); + $scope = $docSheet->getParent()->getSheet($mapSheetId[(integer) $definedName['localSheetId']]); + $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $worksheet, $extractedRange, true, $scope) ); + } + } + } + break; + } + } else if (!isset($definedName['localSheetId'])) { + // "Global" definedNames + $locatedSheet = null; + $extractedSheetName = ''; + if (strpos( (string)$definedName, '!' ) !== false) { + // Extract sheet name + $extractedSheetName = PHPExcel_Worksheet::extractSheetTitle( (string)$definedName, true ); + $extractedSheetName = $extractedSheetName[0]; + + // Locate sheet + $locatedSheet = $excel->getSheetByName($extractedSheetName); + + // Modify range + $range = explode('!', $extractedRange); + $extractedRange = isset($range[1]) ? $range[1] : $range[0]; + } + + if ($locatedSheet !== NULL) { + $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $locatedSheet, $extractedRange, false) ); + } + } + } + } + } + + if ((!$this->_readDataOnly) || (!empty($this->_loadSheetsOnly))) { + // active sheet index + $activeTab = intval($xmlWorkbook->bookViews->workbookView["activeTab"]); // refers to old sheet index + + // keep active sheet index if sheet is still loaded, else first sheet is set as the active + if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) { + $excel->setActiveSheetIndex($mapSheetId[$activeTab]); + } else { + if ($excel->getSheetCount() == 0) { + $excel->createSheet(); + } + $excel->setActiveSheetIndex(0); + } + } + break; + } + + } + + + if (!$this->_readDataOnly) { + $contentTypes = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "[Content_Types].xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + foreach ($contentTypes->Override as $contentType) { + switch ($contentType["ContentType"]) { + case "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": + if ($this->_includeCharts) { + $chartEntryRef = ltrim($contentType['PartName'],'/'); + $chartElements = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $chartEntryRef)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef,'.xml')); + +// echo 'Chart ',$chartEntryRef,'
'; +// var_dump($charts[$chartEntryRef]); // - if (isset($charts[$chartEntryRef])) { - $chartPositionRef = $charts[$chartEntryRef]['sheet'].'!'.$charts[$chartEntryRef]['id']; -// echo 'Position Ref ',$chartPositionRef,'
'; - if (isset($chartDetails[$chartPositionRef])) { -// var_dump($chartDetails[$chartPositionRef]); - - $excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart); - $objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet'])); - $objChart->setTopLeftPosition( $chartDetails[$chartPositionRef]['fromCoordinate'], - $chartDetails[$chartPositionRef]['fromOffsetX'], - $chartDetails[$chartPositionRef]['fromOffsetY'] - ); - $objChart->setBottomRightPosition( $chartDetails[$chartPositionRef]['toCoordinate'], - $chartDetails[$chartPositionRef]['toOffsetX'], - $chartDetails[$chartPositionRef]['toOffsetY'] - ); - } - } - } - } - } - } - - $zip->close(); - - return $excel; - } - - - private static function _readColor($color, $background=FALSE) { - if (isset($color["rgb"])) { - return (string)$color["rgb"]; - } else if (isset($color["indexed"])) { - return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB(); - } else if (isset($color["theme"])) { - if (self::$_theme !== NULL) { - $returnColour = self::$_theme->getColourByIndex((int)$color["theme"]); - if (isset($color["tint"])) { - $tintAdjust = (float) $color["tint"]; - $returnColour = PHPExcel_Style_Color::changeBrightness($returnColour, $tintAdjust); - } - return 'FF'.$returnColour; - } - } - - if ($background) { - return 'FFFFFFFF'; - } - return 'FF000000'; - } - - - private static function _readStyle($docStyle, $style) { - // format code -// if (isset($style->numFmt)) { -// if (isset($style->numFmt['formatCode'])) { -// $docStyle->getNumberFormat()->setFormatCode((string) $style->numFmt['formatCode']); -// } else { - $docStyle->getNumberFormat()->setFormatCode($style->numFmt); -// } -// } - - // font - if (isset($style->font)) { - $docStyle->getFont()->setName((string) $style->font->name["val"]); - $docStyle->getFont()->setSize((string) $style->font->sz["val"]); - if (isset($style->font->b)) { - $docStyle->getFont()->setBold(!isset($style->font->b["val"]) || self::boolean((string) $style->font->b["val"])); - } - if (isset($style->font->i)) { - $docStyle->getFont()->setItalic(!isset($style->font->i["val"]) || self::boolean((string) $style->font->i["val"])); - } - if (isset($style->font->strike)) { - $docStyle->getFont()->setStrikethrough(!isset($style->font->strike["val"]) || self::boolean((string) $style->font->strike["val"])); - } - $docStyle->getFont()->getColor()->setARGB(self::_readColor($style->font->color)); - - if (isset($style->font->u) && !isset($style->font->u["val"])) { - $docStyle->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); - } else if (isset($style->font->u) && isset($style->font->u["val"])) { - $docStyle->getFont()->setUnderline((string)$style->font->u["val"]); - } - - if (isset($style->font->vertAlign) && isset($style->font->vertAlign["val"])) { - $vertAlign = strtolower((string)$style->font->vertAlign["val"]); - if ($vertAlign == 'superscript') { - $docStyle->getFont()->setSuperScript(true); - } - if ($vertAlign == 'subscript') { - $docStyle->getFont()->setSubScript(true); - } - } - } - - // fill - if (isset($style->fill)) { - if ($style->fill->gradientFill) { - $gradientFill = $style->fill->gradientFill[0]; - if(!empty($gradientFill["type"])) { - $docStyle->getFill()->setFillType((string) $gradientFill["type"]); - } - $docStyle->getFill()->setRotation(floatval($gradientFill["degree"])); - $gradientFill->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - $docStyle->getFill()->getStartColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color) ); - $docStyle->getFill()->getEndColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color) ); - } elseif ($style->fill->patternFill) { - $patternType = (string)$style->fill->patternFill["patternType"] != '' ? (string)$style->fill->patternFill["patternType"] : 'solid'; - $docStyle->getFill()->setFillType($patternType); - if ($style->fill->patternFill->fgColor) { - $docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor,true)); - } else { - $docStyle->getFill()->getStartColor()->setARGB('FF000000'); - } - if ($style->fill->patternFill->bgColor) { - $docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor,true)); - } - } - } - - // border - if (isset($style->border)) { - $diagonalUp = self::boolean((string) $style->border["diagonalUp"]); - $diagonalDown = self::boolean((string) $style->border["diagonalDown"]); - if (!$diagonalUp && !$diagonalDown) { - $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); - } elseif ($diagonalUp && !$diagonalDown) { - $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); - } elseif (!$diagonalUp && $diagonalDown) { - $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); - } else { - $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); - } - self::_readBorder($docStyle->getBorders()->getLeft(), $style->border->left); - self::_readBorder($docStyle->getBorders()->getRight(), $style->border->right); - self::_readBorder($docStyle->getBorders()->getTop(), $style->border->top); - self::_readBorder($docStyle->getBorders()->getBottom(), $style->border->bottom); - self::_readBorder($docStyle->getBorders()->getDiagonal(), $style->border->diagonal); - } - - // alignment - if (isset($style->alignment)) { - $docStyle->getAlignment()->setHorizontal((string) $style->alignment["horizontal"]); - $docStyle->getAlignment()->setVertical((string) $style->alignment["vertical"]); - - $textRotation = 0; - if ((int)$style->alignment["textRotation"] <= 90) { - $textRotation = (int)$style->alignment["textRotation"]; - } else if ((int)$style->alignment["textRotation"] > 90) { - $textRotation = 90 - (int)$style->alignment["textRotation"]; - } - - $docStyle->getAlignment()->setTextRotation(intval($textRotation)); - $docStyle->getAlignment()->setWrapText(self::boolean((string) $style->alignment["wrapText"])); - $docStyle->getAlignment()->setShrinkToFit(self::boolean((string) $style->alignment["shrinkToFit"])); - $docStyle->getAlignment()->setIndent( intval((string)$style->alignment["indent"]) > 0 ? intval((string)$style->alignment["indent"]) : 0 ); - $docStyle->getAlignment()->setReadorder( intval((string)$style->alignment["readingOrder"]) > 0 ? intval((string)$style->alignment["readingOrder"]) : 0 ); - } - - // protection - if (isset($style->protection)) { - if (isset($style->protection['locked'])) { - if (self::boolean((string) $style->protection['locked'])) { - $docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_PROTECTED); - } else { - $docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); - } - } - - if (isset($style->protection['hidden'])) { - if (self::boolean((string) $style->protection['hidden'])) { - $docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_PROTECTED); - } else { - $docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); - } - } - } - - // top-level style settings - if (isset($style->quotePrefix)) { - $docStyle->setQuotePrefix($style->quotePrefix); + if (isset($charts[$chartEntryRef])) { + $chartPositionRef = $charts[$chartEntryRef]['sheet'].'!'.$charts[$chartEntryRef]['id']; +// echo 'Position Ref ',$chartPositionRef,'
'; + if (isset($chartDetails[$chartPositionRef])) { +// var_dump($chartDetails[$chartPositionRef]); + + $excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart); + $objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet'])); + $objChart->setTopLeftPosition( $chartDetails[$chartPositionRef]['fromCoordinate'], + $chartDetails[$chartPositionRef]['fromOffsetX'], + $chartDetails[$chartPositionRef]['fromOffsetY'] + ); + $objChart->setBottomRightPosition( $chartDetails[$chartPositionRef]['toCoordinate'], + $chartDetails[$chartPositionRef]['toOffsetX'], + $chartDetails[$chartPositionRef]['toOffsetY'] + ); + } + } + } + } + } + } + + $zip->close(); + + return $excel; + } + + + private static function _readColor($color, $background=FALSE) { + if (isset($color["rgb"])) { + return (string)$color["rgb"]; + } else if (isset($color["indexed"])) { + return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB(); + } else if (isset($color["theme"])) { + if (self::$_theme !== NULL) { + $returnColour = self::$_theme->getColourByIndex((int)$color["theme"]); + if (isset($color["tint"])) { + $tintAdjust = (float) $color["tint"]; + $returnColour = PHPExcel_Style_Color::changeBrightness($returnColour, $tintAdjust); + } + return 'FF'.$returnColour; + } + } + + if ($background) { + return 'FFFFFFFF'; + } + return 'FF000000'; + } + + + private static function _readStyle($docStyle, $style) { + // format code +// if (isset($style->numFmt)) { +// if (isset($style->numFmt['formatCode'])) { +// $docStyle->getNumberFormat()->setFormatCode((string) $style->numFmt['formatCode']); +// } else { + $docStyle->getNumberFormat()->setFormatCode($style->numFmt); +// } +// } + + // font + if (isset($style->font)) { + $docStyle->getFont()->setName((string) $style->font->name["val"]); + $docStyle->getFont()->setSize((string) $style->font->sz["val"]); + if (isset($style->font->b)) { + $docStyle->getFont()->setBold(!isset($style->font->b["val"]) || self::boolean((string) $style->font->b["val"])); + } + if (isset($style->font->i)) { + $docStyle->getFont()->setItalic(!isset($style->font->i["val"]) || self::boolean((string) $style->font->i["val"])); + } + if (isset($style->font->strike)) { + $docStyle->getFont()->setStrikethrough(!isset($style->font->strike["val"]) || self::boolean((string) $style->font->strike["val"])); + } + $docStyle->getFont()->getColor()->setARGB(self::_readColor($style->font->color)); + + if (isset($style->font->u) && !isset($style->font->u["val"])) { + $docStyle->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } else if (isset($style->font->u) && isset($style->font->u["val"])) { + $docStyle->getFont()->setUnderline((string)$style->font->u["val"]); + } + + if (isset($style->font->vertAlign) && isset($style->font->vertAlign["val"])) { + $vertAlign = strtolower((string)$style->font->vertAlign["val"]); + if ($vertAlign == 'superscript') { + $docStyle->getFont()->setSuperScript(true); + } + if ($vertAlign == 'subscript') { + $docStyle->getFont()->setSubScript(true); + } + } + } + + // fill + if (isset($style->fill)) { + if ($style->fill->gradientFill) { + $gradientFill = $style->fill->gradientFill[0]; + if(!empty($gradientFill["type"])) { + $docStyle->getFill()->setFillType((string) $gradientFill["type"]); + } + $docStyle->getFill()->setRotation(floatval($gradientFill["degree"])); + $gradientFill->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $docStyle->getFill()->getStartColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color) ); + $docStyle->getFill()->getEndColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color) ); + } elseif ($style->fill->patternFill) { + $patternType = (string)$style->fill->patternFill["patternType"] != '' ? (string)$style->fill->patternFill["patternType"] : 'solid'; + $docStyle->getFill()->setFillType($patternType); + if ($style->fill->patternFill->fgColor) { + $docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor,true)); + } else { + $docStyle->getFill()->getStartColor()->setARGB('FF000000'); + } + if ($style->fill->patternFill->bgColor) { + $docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor,true)); + } + } + } + + // border + if (isset($style->border)) { + $diagonalUp = self::boolean((string) $style->border["diagonalUp"]); + $diagonalDown = self::boolean((string) $style->border["diagonalDown"]); + if (!$diagonalUp && !$diagonalDown) { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); + } elseif ($diagonalUp && !$diagonalDown) { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); + } elseif (!$diagonalUp && $diagonalDown) { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); + } else { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); + } + self::_readBorder($docStyle->getBorders()->getLeft(), $style->border->left); + self::_readBorder($docStyle->getBorders()->getRight(), $style->border->right); + self::_readBorder($docStyle->getBorders()->getTop(), $style->border->top); + self::_readBorder($docStyle->getBorders()->getBottom(), $style->border->bottom); + self::_readBorder($docStyle->getBorders()->getDiagonal(), $style->border->diagonal); } - } - - - private static function _readBorder($docBorder, $eleBorder) { - if (isset($eleBorder["style"])) { - $docBorder->setBorderStyle((string) $eleBorder["style"]); - } - if (isset($eleBorder->color)) { - $docBorder->getColor()->setARGB(self::_readColor($eleBorder->color)); - } - } - - - private function _parseRichText($is = null) { - $value = new PHPExcel_RichText(); - - if (isset($is->t)) { - $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $is->t ) ); - } else { - if(is_object($is->r)) { - foreach ($is->r as $run) { - if (!isset($run->rPr)) { - $objText = $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); - - } else { - $objText = $value->createTextRun( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); - - if (isset($run->rPr->rFont["val"])) { - $objText->getFont()->setName((string) $run->rPr->rFont["val"]); - } - - if (isset($run->rPr->sz["val"])) { - $objText->getFont()->setSize((string) $run->rPr->sz["val"]); - } - - if (isset($run->rPr->color)) { - $objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($run->rPr->color) ) ); - } - - if ((isset($run->rPr->b["val"]) && self::boolean((string) $run->rPr->b["val"])) || - (isset($run->rPr->b) && !isset($run->rPr->b["val"]))) { - $objText->getFont()->setBold(TRUE); - } - - if ((isset($run->rPr->i["val"]) && self::boolean((string) $run->rPr->i["val"])) || - (isset($run->rPr->i) && !isset($run->rPr->i["val"]))) { - $objText->getFont()->setItalic(TRUE); - } - - if (isset($run->rPr->vertAlign) && isset($run->rPr->vertAlign["val"])) { - $vertAlign = strtolower((string)$run->rPr->vertAlign["val"]); - if ($vertAlign == 'superscript') { - $objText->getFont()->setSuperScript(TRUE); - } - if ($vertAlign == 'subscript') { - $objText->getFont()->setSubScript(TRUE); - } - } - - if (isset($run->rPr->u) && !isset($run->rPr->u["val"])) { - $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); - } else if (isset($run->rPr->u) && isset($run->rPr->u["val"])) { - $objText->getFont()->setUnderline((string)$run->rPr->u["val"]); - } - - if ((isset($run->rPr->strike["val"]) && self::boolean((string) $run->rPr->strike["val"])) || - (isset($run->rPr->strike) && !isset($run->rPr->strike["val"]))) { - $objText->getFont()->setStrikethrough(TRUE); - } - } - } - } - } - - return $value; - } - - private function _readRibbon($excel, $customUITarget, $zip) + + // alignment + if (isset($style->alignment)) { + $docStyle->getAlignment()->setHorizontal((string) $style->alignment["horizontal"]); + $docStyle->getAlignment()->setVertical((string) $style->alignment["vertical"]); + + $textRotation = 0; + if ((int)$style->alignment["textRotation"] <= 90) { + $textRotation = (int)$style->alignment["textRotation"]; + } else if ((int)$style->alignment["textRotation"] > 90) { + $textRotation = 90 - (int)$style->alignment["textRotation"]; + } + + $docStyle->getAlignment()->setTextRotation(intval($textRotation)); + $docStyle->getAlignment()->setWrapText(self::boolean((string) $style->alignment["wrapText"])); + $docStyle->getAlignment()->setShrinkToFit(self::boolean((string) $style->alignment["shrinkToFit"])); + $docStyle->getAlignment()->setIndent( intval((string)$style->alignment["indent"]) > 0 ? intval((string)$style->alignment["indent"]) : 0 ); + $docStyle->getAlignment()->setReadorder( intval((string)$style->alignment["readingOrder"]) > 0 ? intval((string)$style->alignment["readingOrder"]) : 0 ); + } + + // protection + if (isset($style->protection)) { + if (isset($style->protection['locked'])) { + if (self::boolean((string) $style->protection['locked'])) { + $docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_PROTECTED); + } else { + $docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + } + } + + if (isset($style->protection['hidden'])) { + if (self::boolean((string) $style->protection['hidden'])) { + $docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_PROTECTED); + } else { + $docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + } + } + } + + // top-level style settings + if (isset($style->quotePrefix)) { + $docStyle->setQuotePrefix($style->quotePrefix); + } + } + + + private static function _readBorder($docBorder, $eleBorder) { + if (isset($eleBorder["style"])) { + $docBorder->setBorderStyle((string) $eleBorder["style"]); + } + if (isset($eleBorder->color)) { + $docBorder->getColor()->setARGB(self::_readColor($eleBorder->color)); + } + } + + + private function _parseRichText($is = null) { + $value = new PHPExcel_RichText(); + + if (isset($is->t)) { + $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $is->t ) ); + } else { + if(is_object($is->r)) { + foreach ($is->r as $run) { + if (!isset($run->rPr)) { + $objText = $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); + + } else { + $objText = $value->createTextRun( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); + + if (isset($run->rPr->rFont["val"])) { + $objText->getFont()->setName((string) $run->rPr->rFont["val"]); + } + + if (isset($run->rPr->sz["val"])) { + $objText->getFont()->setSize((string) $run->rPr->sz["val"]); + } + + if (isset($run->rPr->color)) { + $objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($run->rPr->color) ) ); + } + + if ((isset($run->rPr->b["val"]) && self::boolean((string) $run->rPr->b["val"])) || + (isset($run->rPr->b) && !isset($run->rPr->b["val"]))) { + $objText->getFont()->setBold(TRUE); + } + + if ((isset($run->rPr->i["val"]) && self::boolean((string) $run->rPr->i["val"])) || + (isset($run->rPr->i) && !isset($run->rPr->i["val"]))) { + $objText->getFont()->setItalic(TRUE); + } + + if (isset($run->rPr->vertAlign) && isset($run->rPr->vertAlign["val"])) { + $vertAlign = strtolower((string)$run->rPr->vertAlign["val"]); + if ($vertAlign == 'superscript') { + $objText->getFont()->setSuperScript(TRUE); + } + if ($vertAlign == 'subscript') { + $objText->getFont()->setSubScript(TRUE); + } + } + + if (isset($run->rPr->u) && !isset($run->rPr->u["val"])) { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } else if (isset($run->rPr->u) && isset($run->rPr->u["val"])) { + $objText->getFont()->setUnderline((string)$run->rPr->u["val"]); + } + + if ((isset($run->rPr->strike["val"]) && self::boolean((string) $run->rPr->strike["val"])) || + (isset($run->rPr->strike) && !isset($run->rPr->strike["val"]))) { + $objText->getFont()->setStrikethrough(TRUE); + } + } + } + } + } + + return $value; + } + + private function _readRibbon($excel, $customUITarget, $zip) { - $baseDir = dirname($customUITarget); - $nameCustomUI = basename($customUITarget); + $baseDir = dirname($customUITarget); + $nameCustomUI = basename($customUITarget); // get the xml file (ribbon) - $localRibbon = $this->_getFromZipArchive($zip, $customUITarget); - $customUIImagesNames = array(); + $localRibbon = $this->_getFromZipArchive($zip, $customUITarget); + $customUIImagesNames = array(); $customUIImagesBinaries = array(); // something like customUI/_rels/customUI.xml.rels - $pathRels = $baseDir . '/_rels/' . $nameCustomUI . '.rels'; - $dataRels = $this->_getFromZipArchive($zip, $pathRels); - if ($dataRels) { + $pathRels = $baseDir . '/_rels/' . $nameCustomUI . '.rels'; + $dataRels = $this->_getFromZipArchive($zip, $pathRels); + if ($dataRels) { // exists and not empty if the ribbon have some pictures (other than internal MSO) - $UIRels = simplexml_load_string($this->securityScan($dataRels), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - if ($UIRels) { - // we need to save id and target to avoid parsing customUI.xml and "guess" if it's a pseudo callback who load the image - foreach ($UIRels->Relationship as $ele) { - if ($ele["Type"] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') { + $UIRels = simplexml_load_string($this->securityScan($dataRels), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if ($UIRels) { + // we need to save id and target to avoid parsing customUI.xml and "guess" if it's a pseudo callback who load the image + foreach ($UIRels->Relationship as $ele) { + if ($ele["Type"] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') { // an image ? - $customUIImagesNames[(string) $ele['Id']] = (string)$ele['Target']; - $customUIImagesBinaries[(string)$ele['Target']] = $this->_getFromZipArchive($zip, $baseDir . '/' . (string) $ele['Target']); - } - } - } - } - if ($localRibbon) { - $excel->setRibbonXMLData($customUITarget, $localRibbon); - if (count($customUIImagesNames) > 0 && count($customUIImagesBinaries) > 0) { - $excel->setRibbonBinObjects($customUIImagesNames, $customUIImagesBinaries); - } else { - $excel->setRibbonBinObjects(NULL); - } - } else { - $excel->setRibbonXMLData(NULL); - $excel->setRibbonBinObjects(NULL); - } - } - - private static function array_item($array, $key = 0) { - return (isset($array[$key]) ? $array[$key] : null); - } - - - private static function dir_add($base, $add) { - return preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add"); - } - - - private static function toCSSArray($style) { - $style = str_replace(array("\r","\n"), "", $style); - - $temp = explode(';', $style); - $style = array(); - foreach ($temp as $item) { - $item = explode(':', $item); - - if (strpos($item[1], 'px') !== false) { - $item[1] = str_replace('px', '', $item[1]); - } - if (strpos($item[1], 'pt') !== false) { - $item[1] = str_replace('pt', '', $item[1]); - $item[1] = PHPExcel_Shared_Font::fontSizeToPixels($item[1]); - } - if (strpos($item[1], 'in') !== false) { - $item[1] = str_replace('in', '', $item[1]); - $item[1] = PHPExcel_Shared_Font::inchSizeToPixels($item[1]); - } - if (strpos($item[1], 'cm') !== false) { - $item[1] = str_replace('cm', '', $item[1]); - $item[1] = PHPExcel_Shared_Font::centimeterSizeToPixels($item[1]); - } - - $style[$item[0]] = $item[1]; - } - - return $style; - } - - private static function boolean($value = NULL) - { + $customUIImagesNames[(string) $ele['Id']] = (string)$ele['Target']; + $customUIImagesBinaries[(string)$ele['Target']] = $this->_getFromZipArchive($zip, $baseDir . '/' . (string) $ele['Target']); + } + } + } + } + if ($localRibbon) { + $excel->setRibbonXMLData($customUITarget, $localRibbon); + if (count($customUIImagesNames) > 0 && count($customUIImagesBinaries) > 0) { + $excel->setRibbonBinObjects($customUIImagesNames, $customUIImagesBinaries); + } else { + $excel->setRibbonBinObjects(NULL); + } + } else { + $excel->setRibbonXMLData(NULL); + $excel->setRibbonBinObjects(NULL); + } + } + + private static function array_item($array, $key = 0) { + return (isset($array[$key]) ? $array[$key] : null); + } + + + private static function dir_add($base, $add) { + return preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add"); + } + + + private static function toCSSArray($style) { + $style = str_replace(array("\r","\n"), "", $style); + + $temp = explode(';', $style); + $style = array(); + foreach ($temp as $item) { + $item = explode(':', $item); + + if (strpos($item[1], 'px') !== false) { + $item[1] = str_replace('px', '', $item[1]); + } + if (strpos($item[1], 'pt') !== false) { + $item[1] = str_replace('pt', '', $item[1]); + $item[1] = PHPExcel_Shared_Font::fontSizeToPixels($item[1]); + } + if (strpos($item[1], 'in') !== false) { + $item[1] = str_replace('in', '', $item[1]); + $item[1] = PHPExcel_Shared_Font::inchSizeToPixels($item[1]); + } + if (strpos($item[1], 'cm') !== false) { + $item[1] = str_replace('cm', '', $item[1]); + $item[1] = PHPExcel_Shared_Font::centimeterSizeToPixels($item[1]); + } + + $style[$item[0]] = $item[1]; + } + + return $style; + } + + private static function boolean($value = NULL) + { if (is_object($value)) { - $value = (string) $value; + $value = (string) $value; } - if (is_numeric($value)) { - return (bool) $value; + if (is_numeric($value)) { + return (bool) $value; } - return ($value === 'true' || $value === 'TRUE'); - } + return ($value === 'true' || $value === 'TRUE'); + } } diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index a9acfc472..b12bf3efb 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Reader_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -31,39 +31,39 @@ // trex005, and mmp11 (SourceForge.net) // http://sourceforge.net/projects/phpexcelreader/ // Primary changes made by canyoncasa (dvc) for ParseXL 1.00 ... -// Modelled moreso after Perl Excel Parse/Write modules -// Added Parse_Excel_Spreadsheet object -// Reads a whole worksheet or tab as row,column array or as -// associated hash of indexed rows and named column fields -// Added variables for worksheet (tab) indexes and names -// Added an object call for loading individual woorksheets -// Changed default indexing defaults to 0 based arrays -// Fixed date/time and percent formats -// Includes patches found at SourceForge... -// unicode patch by nobody -// unpack("d") machine depedency patch by matchy -// boundsheet utf16 patch by bjaenichen -// Renamed functions for shorter names -// General code cleanup and rigor, including <80 column width -// Included a testcase Excel file and PHP example calls -// Code works for PHP 5.x +// Modelled moreso after Perl Excel Parse/Write modules +// Added Parse_Excel_Spreadsheet object +// Reads a whole worksheet or tab as row,column array or as +// associated hash of indexed rows and named column fields +// Added variables for worksheet (tab) indexes and names +// Added an object call for loading individual woorksheets +// Changed default indexing defaults to 0 based arrays +// Fixed date/time and percent formats +// Includes patches found at SourceForge... +// unicode patch by nobody +// unpack("d") machine depedency patch by matchy +// boundsheet utf16 patch by bjaenichen +// Renamed functions for shorter names +// General code cleanup and rigor, including <80 column width +// Included a testcase Excel file and PHP example calls +// Code works for PHP 5.x // Primary changes made by canyoncasa (dvc) for ParseXL 1.10 ... // http://sourceforge.net/tracker/index.php?func=detail&aid=1466964&group_id=99160&atid=623334 -// Decoding of formula conditions, results, and tokens. -// Support for user-defined named cells added as an array "namedcells" -// Patch code for user-defined named cells supports single cells only. -// NOTE: this patch only works for BIFF8 as BIFF5-7 use a different -// external sheet reference structure +// Decoding of formula conditions, results, and tokens. +// Support for user-defined named cells added as an array "namedcells" +// Patch code for user-defined named cells supports single cells only. +// NOTE: this patch only works for BIFF8 as BIFF5-7 use a different +// external sheet reference structure /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** @@ -71,7018 +71,7018 @@ * * This class uses {@link http://sourceforge.net/projects/phpexcelreader/parseXL} * - * @category PHPExcel - * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { - // ParseXL definitions - const XLS_BIFF8 = 0x0600; - const XLS_BIFF7 = 0x0500; - const XLS_WorkbookGlobals = 0x0005; - const XLS_Worksheet = 0x0010; - - // record identifiers - const XLS_Type_FORMULA = 0x0006; - const XLS_Type_EOF = 0x000a; - const XLS_Type_PROTECT = 0x0012; - const XLS_Type_OBJECTPROTECT = 0x0063; - const XLS_Type_SCENPROTECT = 0x00dd; - const XLS_Type_PASSWORD = 0x0013; - const XLS_Type_HEADER = 0x0014; - const XLS_Type_FOOTER = 0x0015; - const XLS_Type_EXTERNSHEET = 0x0017; - const XLS_Type_DEFINEDNAME = 0x0018; - const XLS_Type_VERTICALPAGEBREAKS = 0x001a; - const XLS_Type_HORIZONTALPAGEBREAKS = 0x001b; - const XLS_Type_NOTE = 0x001c; - const XLS_Type_SELECTION = 0x001d; - const XLS_Type_DATEMODE = 0x0022; - const XLS_Type_EXTERNNAME = 0x0023; - const XLS_Type_LEFTMARGIN = 0x0026; - const XLS_Type_RIGHTMARGIN = 0x0027; - const XLS_Type_TOPMARGIN = 0x0028; - const XLS_Type_BOTTOMMARGIN = 0x0029; - const XLS_Type_PRINTGRIDLINES = 0x002b; - const XLS_Type_FILEPASS = 0x002f; - const XLS_Type_FONT = 0x0031; - const XLS_Type_CONTINUE = 0x003c; - const XLS_Type_PANE = 0x0041; - const XLS_Type_CODEPAGE = 0x0042; - const XLS_Type_DEFCOLWIDTH = 0x0055; - const XLS_Type_OBJ = 0x005d; - const XLS_Type_COLINFO = 0x007d; - const XLS_Type_IMDATA = 0x007f; - const XLS_Type_SHEETPR = 0x0081; - const XLS_Type_HCENTER = 0x0083; - const XLS_Type_VCENTER = 0x0084; - const XLS_Type_SHEET = 0x0085; - const XLS_Type_PALETTE = 0x0092; - const XLS_Type_SCL = 0x00a0; - const XLS_Type_PAGESETUP = 0x00a1; - const XLS_Type_MULRK = 0x00bd; - const XLS_Type_MULBLANK = 0x00be; - const XLS_Type_DBCELL = 0x00d7; - const XLS_Type_XF = 0x00e0; - const XLS_Type_MERGEDCELLS = 0x00e5; - const XLS_Type_MSODRAWINGGROUP = 0x00eb; - const XLS_Type_MSODRAWING = 0x00ec; - const XLS_Type_SST = 0x00fc; - const XLS_Type_LABELSST = 0x00fd; - const XLS_Type_EXTSST = 0x00ff; - const XLS_Type_EXTERNALBOOK = 0x01ae; - const XLS_Type_DATAVALIDATIONS = 0x01b2; - const XLS_Type_TXO = 0x01b6; - const XLS_Type_HYPERLINK = 0x01b8; - const XLS_Type_DATAVALIDATION = 0x01be; - const XLS_Type_DIMENSION = 0x0200; - const XLS_Type_BLANK = 0x0201; - const XLS_Type_NUMBER = 0x0203; - const XLS_Type_LABEL = 0x0204; - const XLS_Type_BOOLERR = 0x0205; - const XLS_Type_STRING = 0x0207; - const XLS_Type_ROW = 0x0208; - const XLS_Type_INDEX = 0x020b; - const XLS_Type_ARRAY = 0x0221; - const XLS_Type_DEFAULTROWHEIGHT = 0x0225; - const XLS_Type_WINDOW2 = 0x023e; - const XLS_Type_RK = 0x027e; - const XLS_Type_STYLE = 0x0293; - const XLS_Type_FORMAT = 0x041e; - const XLS_Type_SHAREDFMLA = 0x04bc; - const XLS_Type_BOF = 0x0809; - const XLS_Type_SHEETPROTECTION = 0x0867; - const XLS_Type_RANGEPROTECTION = 0x0868; - const XLS_Type_SHEETLAYOUT = 0x0862; - const XLS_Type_XFEXT = 0x087d; - const XLS_Type_PAGELAYOUTVIEW = 0x088b; - const XLS_Type_UNKNOWN = 0xffff; - - // Encryption type - const MS_BIFF_CRYPTO_NONE = 0; - const MS_BIFF_CRYPTO_XOR = 1; - const MS_BIFF_CRYPTO_RC4 = 2; - - // Size of stream blocks when using RC4 encryption - const REKEY_BLOCK = 0x400; - - /** - * Summary Information stream data. - * - * @var string - */ - private $_summaryInformation; - - /** - * Extended Summary Information stream data. - * - * @var string - */ - private $_documentSummaryInformation; - - /** - * User-Defined Properties stream data. - * - * @var string - */ - private $_userDefinedProperties; - - /** - * Workbook stream data. (Includes workbook globals substream as well as sheet substreams) - * - * @var string - */ - private $_data; - - /** - * Size in bytes of $this->_data - * - * @var int - */ - private $_dataSize; - - /** - * Current position in stream - * - * @var integer - */ - private $_pos; - - /** - * Workbook to be returned by the reader. - * - * @var PHPExcel - */ - private $_phpExcel; - - /** - * Worksheet that is currently being built by the reader. - * - * @var PHPExcel_Worksheet - */ - private $_phpSheet; - - /** - * BIFF version - * - * @var int - */ - private $_version; - - /** - * Codepage set in the Excel file being read. Only important for BIFF5 (Excel 5.0 - Excel 95) - * For BIFF8 (Excel 97 - Excel 2003) this will always have the value 'UTF-16LE' - * - * @var string - */ - private $_codepage; - - /** - * Shared formats - * - * @var array - */ - private $_formats; - - /** - * Shared fonts - * - * @var array - */ - private $_objFonts; - - /** - * Color palette - * - * @var array - */ - private $_palette; - - /** - * Worksheets - * - * @var array - */ - private $_sheets; - - /** - * External books - * - * @var array - */ - private $_externalBooks; - - /** - * REF structures. Only applies to BIFF8. - * - * @var array - */ - private $_ref; - - /** - * External names - * - * @var array - */ - private $_externalNames; - - /** - * Defined names - * - * @var array - */ - private $_definedname; - - /** - * Shared strings. Only applies to BIFF8. - * - * @var array - */ - private $_sst; - - /** - * Panes are frozen? (in sheet currently being read). See WINDOW2 record. - * - * @var boolean - */ - private $_frozen; - - /** - * Fit printout to number of pages? (in sheet currently being read). See SHEETPR record. - * - * @var boolean - */ - private $_isFitToPages; - - /** - * Objects. One OBJ record contributes with one entry. - * - * @var array - */ - private $_objs; - - /** - * Text Objects. One TXO record corresponds with one entry. - * - * @var array - */ - private $_textObjects; - - /** - * Cell Annotations (BIFF8) - * - * @var array - */ - private $_cellNotes; - - /** - * The combined MSODRAWINGGROUP data - * - * @var string - */ - private $_drawingGroupData; - - /** - * The combined MSODRAWING data (per sheet) - * - * @var string - */ - private $_drawingData; - - /** - * Keep track of XF index - * - * @var int - */ - private $_xfIndex; - - /** - * Mapping of XF index (that is a cell XF) to final index in cellXf collection - * - * @var array - */ - private $_mapCellXfIndex; - - /** - * Mapping of XF index (that is a style XF) to final index in cellStyleXf collection - * - * @var array - */ - private $_mapCellStyleXfIndex; - - /** - * The shared formulas in a sheet. One SHAREDFMLA record contributes with one value. - * - * @var array - */ - private $_sharedFormulas; - - /** - * The shared formula parts in a sheet. One FORMULA record contributes with one value if it - * refers to a shared formula. - * - * @var array - */ - private $_sharedFormulaParts; - - /** - * The type of encryption in use - * - * @var int - */ - private $_encryption = 0; - - /** - * The position in the stream after which contents are encrypted - * - * @var int - */ - private $_encryptionStartPos = false; - - /** - * The current RC4 decryption object - * - * @var PHPExcel_Reader_Excel5_RC4 - */ - private $_rc4Key = null; - - /** - * The position in the stream that the RC4 decryption object was left at - * - * @var int - */ - private $_rc4Pos = 0; - - /** - * The current MD5 context state - * - * @var string - */ - private $_md5Ctxt = null; - - /** - * Create a new PHPExcel_Reader_Excel5 instance - */ - public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - } - - - /** - * Can the current PHPExcel_Reader_IReader read the file? - * - * @param string $pFilename - * @return boolean - * @throws PHPExcel_Reader_Exception - */ - public function canRead($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - try { - // Use ParseXL for the hard work. - $ole = new PHPExcel_Shared_OLERead(); - - // get excel data - $res = $ole->read($pFilename); - return true; - } catch (PHPExcel_Exception $e) { - return false; - } - } - - - /** - * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetNames($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $worksheetNames = array(); - - // Read the OLE file - $this->_loadOLE($pFilename); - - // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); - - $this->_pos = 0; - $this->_sheets = array(); - - // Parse Workbook Global Substream - while ($this->_pos < $this->_dataSize) { - $code = self::_GetInt2d($this->_data, $this->_pos); - - switch ($code) { - case self::XLS_Type_BOF: $this->_readBof(); break; - case self::XLS_Type_SHEET: $this->_readSheet(); break; - case self::XLS_Type_EOF: $this->_readDefault(); break 2; - default: $this->_readDefault(); break; - } - } - - foreach ($this->_sheets as $sheet) { - if ($sheet['sheetType'] != 0x00) { - // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module - continue; - } - - $worksheetNames[] = $sheet['name']; - } - - return $worksheetNames; - } - - - /** - * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetInfo($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $worksheetInfo = array(); - - // Read the OLE file - $this->_loadOLE($pFilename); - - // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); - - // initialize - $this->_pos = 0; - $this->_sheets = array(); - - // Parse Workbook Global Substream - while ($this->_pos < $this->_dataSize) { - $code = self::_GetInt2d($this->_data, $this->_pos); - - switch ($code) { - case self::XLS_Type_BOF: $this->_readBof(); break; - case self::XLS_Type_SHEET: $this->_readSheet(); break; - case self::XLS_Type_EOF: $this->_readDefault(); break 2; - default: $this->_readDefault(); break; - } - } - - // Parse the individual sheets - foreach ($this->_sheets as $sheet) { - - if ($sheet['sheetType'] != 0x00) { - // 0x00: Worksheet - // 0x02: Chart - // 0x06: Visual Basic module - continue; - } - - $tmpInfo = array(); - $tmpInfo['worksheetName'] = $sheet['name']; - $tmpInfo['lastColumnLetter'] = 'A'; - $tmpInfo['lastColumnIndex'] = 0; - $tmpInfo['totalRows'] = 0; - $tmpInfo['totalColumns'] = 0; - - $this->_pos = $sheet['offset']; - - while ($this->_pos <= $this->_dataSize - 4) { - $code = self::_GetInt2d($this->_data, $this->_pos); - - switch ($code) { - case self::XLS_Type_RK: - case self::XLS_Type_LABELSST: - case self::XLS_Type_NUMBER: - case self::XLS_Type_FORMULA: - case self::XLS_Type_BOOLERR: - case self::XLS_Type_LABEL: - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - $rowIndex = self::_GetInt2d($recordData, 0) + 1; - $columnIndex = self::_GetInt2d($recordData, 2); - - $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); - $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); - break; - case self::XLS_Type_BOF: $this->_readBof(); break; - case self::XLS_Type_EOF: $this->_readDefault(); break 2; - default: $this->_readDefault(); break; - } - } - - $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); - $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; - - $worksheetInfo[] = $tmpInfo; - } - - return $worksheetInfo; - } - - - /** - * Loads PHPExcel from file - * - * @param string $pFilename - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function load($pFilename) - { - // Read the OLE file - $this->_loadOLE($pFilename); - - // Initialisations - $this->_phpExcel = new PHPExcel; - $this->_phpExcel->removeSheetByIndex(0); // remove 1st sheet - if (!$this->_readDataOnly) { - $this->_phpExcel->removeCellStyleXfByIndex(0); // remove the default style - $this->_phpExcel->removeCellXfByIndex(0); // remove the default style - } - - // Read the summary information stream (containing meta data) - $this->_readSummaryInformation(); - - // Read the Additional document summary information stream (containing application-specific meta data) - $this->_readDocumentSummaryInformation(); - - // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); - - // initialize - $this->_pos = 0; - $this->_codepage = 'CP1252'; - $this->_formats = array(); - $this->_objFonts = array(); - $this->_palette = array(); - $this->_sheets = array(); - $this->_externalBooks = array(); - $this->_ref = array(); - $this->_definedname = array(); - $this->_sst = array(); - $this->_drawingGroupData = ''; - $this->_xfIndex = ''; - $this->_mapCellXfIndex = array(); - $this->_mapCellStyleXfIndex = array(); - - // Parse Workbook Global Substream - while ($this->_pos < $this->_dataSize) { - $code = self::_GetInt2d($this->_data, $this->_pos); - - switch ($code) { - case self::XLS_Type_BOF: $this->_readBof(); break; - case self::XLS_Type_FILEPASS: $this->_readFilepass(); break; - case self::XLS_Type_CODEPAGE: $this->_readCodepage(); break; - case self::XLS_Type_DATEMODE: $this->_readDateMode(); break; - case self::XLS_Type_FONT: $this->_readFont(); break; - case self::XLS_Type_FORMAT: $this->_readFormat(); break; - case self::XLS_Type_XF: $this->_readXf(); break; - case self::XLS_Type_XFEXT: $this->_readXfExt(); break; - case self::XLS_Type_STYLE: $this->_readStyle(); break; - case self::XLS_Type_PALETTE: $this->_readPalette(); break; - case self::XLS_Type_SHEET: $this->_readSheet(); break; - case self::XLS_Type_EXTERNALBOOK: $this->_readExternalBook(); break; - case self::XLS_Type_EXTERNNAME: $this->_readExternName(); break; - case self::XLS_Type_EXTERNSHEET: $this->_readExternSheet(); break; - case self::XLS_Type_DEFINEDNAME: $this->_readDefinedName(); break; - case self::XLS_Type_MSODRAWINGGROUP: $this->_readMsoDrawingGroup(); break; - case self::XLS_Type_SST: $this->_readSst(); break; - case self::XLS_Type_EOF: $this->_readDefault(); break 2; - default: $this->_readDefault(); break; - } - } - - // Resolve indexed colors for font, fill, and border colors - // Cannot be resolved already in XF record, because PALETTE record comes afterwards - if (!$this->_readDataOnly) { - foreach ($this->_objFonts as $objFont) { - if (isset($objFont->colorIndex)) { - $color = self::_readColor($objFont->colorIndex,$this->_palette,$this->_version); - $objFont->getColor()->setRGB($color['rgb']); - } - } - - foreach ($this->_phpExcel->getCellXfCollection() as $objStyle) { - // fill start and end color - $fill = $objStyle->getFill(); - - if (isset($fill->startcolorIndex)) { - $startColor = self::_readColor($fill->startcolorIndex,$this->_palette,$this->_version); - $fill->getStartColor()->setRGB($startColor['rgb']); - } - - if (isset($fill->endcolorIndex)) { - $endColor = self::_readColor($fill->endcolorIndex,$this->_palette,$this->_version); - $fill->getEndColor()->setRGB($endColor['rgb']); - } - - // border colors - $top = $objStyle->getBorders()->getTop(); - $right = $objStyle->getBorders()->getRight(); - $bottom = $objStyle->getBorders()->getBottom(); - $left = $objStyle->getBorders()->getLeft(); - $diagonal = $objStyle->getBorders()->getDiagonal(); - - if (isset($top->colorIndex)) { - $borderTopColor = self::_readColor($top->colorIndex,$this->_palette,$this->_version); - $top->getColor()->setRGB($borderTopColor['rgb']); - } - - if (isset($right->colorIndex)) { - $borderRightColor = self::_readColor($right->colorIndex,$this->_palette,$this->_version); - $right->getColor()->setRGB($borderRightColor['rgb']); - } - - if (isset($bottom->colorIndex)) { - $borderBottomColor = self::_readColor($bottom->colorIndex,$this->_palette,$this->_version); - $bottom->getColor()->setRGB($borderBottomColor['rgb']); - } - - if (isset($left->colorIndex)) { - $borderLeftColor = self::_readColor($left->colorIndex,$this->_palette,$this->_version); - $left->getColor()->setRGB($borderLeftColor['rgb']); - } - - if (isset($diagonal->colorIndex)) { - $borderDiagonalColor = self::_readColor($diagonal->colorIndex,$this->_palette,$this->_version); - $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']); - } - } - } - - // treat MSODRAWINGGROUP records, workbook-level Escher - if (!$this->_readDataOnly && $this->_drawingGroupData) { - $escherWorkbook = new PHPExcel_Shared_Escher(); - $reader = new PHPExcel_Reader_Excel5_Escher($escherWorkbook); - $escherWorkbook = $reader->load($this->_drawingGroupData); - - // debug Escher stream - //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); - //$debug->load($this->_drawingGroupData); - } - - // Parse the individual sheets - foreach ($this->_sheets as $sheet) { - - if ($sheet['sheetType'] != 0x00) { - // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module - continue; - } - - // check if sheet should be skipped - if (isset($this->_loadSheetsOnly) && !in_array($sheet['name'], $this->_loadSheetsOnly)) { - continue; - } - - // add sheet to PHPExcel object - $this->_phpSheet = $this->_phpExcel->createSheet(); - // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula - // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet - // name in line with the formula, not the reverse - $this->_phpSheet->setTitle($sheet['name'],false); - $this->_phpSheet->setSheetState($sheet['sheetState']); - - $this->_pos = $sheet['offset']; - - // Initialize isFitToPages. May change after reading SHEETPR record. - $this->_isFitToPages = false; - - // Initialize drawingData - $this->_drawingData = ''; - - // Initialize objs - $this->_objs = array(); - - // Initialize shared formula parts - $this->_sharedFormulaParts = array(); - - // Initialize shared formulas - $this->_sharedFormulas = array(); - - // Initialize text objs - $this->_textObjects = array(); - - // Initialize cell annotations - $this->_cellNotes = array(); - $this->textObjRef = -1; - - while ($this->_pos <= $this->_dataSize - 4) { - $code = self::_GetInt2d($this->_data, $this->_pos); - - switch ($code) { - case self::XLS_Type_BOF: $this->_readBof(); break; - case self::XLS_Type_PRINTGRIDLINES: $this->_readPrintGridlines(); break; - case self::XLS_Type_DEFAULTROWHEIGHT: $this->_readDefaultRowHeight(); break; - case self::XLS_Type_SHEETPR: $this->_readSheetPr(); break; - case self::XLS_Type_HORIZONTALPAGEBREAKS: $this->_readHorizontalPageBreaks(); break; - case self::XLS_Type_VERTICALPAGEBREAKS: $this->_readVerticalPageBreaks(); break; - case self::XLS_Type_HEADER: $this->_readHeader(); break; - case self::XLS_Type_FOOTER: $this->_readFooter(); break; - case self::XLS_Type_HCENTER: $this->_readHcenter(); break; - case self::XLS_Type_VCENTER: $this->_readVcenter(); break; - case self::XLS_Type_LEFTMARGIN: $this->_readLeftMargin(); break; - case self::XLS_Type_RIGHTMARGIN: $this->_readRightMargin(); break; - case self::XLS_Type_TOPMARGIN: $this->_readTopMargin(); break; - case self::XLS_Type_BOTTOMMARGIN: $this->_readBottomMargin(); break; - case self::XLS_Type_PAGESETUP: $this->_readPageSetup(); break; - case self::XLS_Type_PROTECT: $this->_readProtect(); break; - case self::XLS_Type_SCENPROTECT: $this->_readScenProtect(); break; - case self::XLS_Type_OBJECTPROTECT: $this->_readObjectProtect(); break; - case self::XLS_Type_PASSWORD: $this->_readPassword(); break; - case self::XLS_Type_DEFCOLWIDTH: $this->_readDefColWidth(); break; - case self::XLS_Type_COLINFO: $this->_readColInfo(); break; - case self::XLS_Type_DIMENSION: $this->_readDefault(); break; - case self::XLS_Type_ROW: $this->_readRow(); break; - case self::XLS_Type_DBCELL: $this->_readDefault(); break; - case self::XLS_Type_RK: $this->_readRk(); break; - case self::XLS_Type_LABELSST: $this->_readLabelSst(); break; - case self::XLS_Type_MULRK: $this->_readMulRk(); break; - case self::XLS_Type_NUMBER: $this->_readNumber(); break; - case self::XLS_Type_FORMULA: $this->_readFormula(); break; - case self::XLS_Type_SHAREDFMLA: $this->_readSharedFmla(); break; - case self::XLS_Type_BOOLERR: $this->_readBoolErr(); break; - case self::XLS_Type_MULBLANK: $this->_readMulBlank(); break; - case self::XLS_Type_LABEL: $this->_readLabel(); break; - case self::XLS_Type_BLANK: $this->_readBlank(); break; - case self::XLS_Type_MSODRAWING: $this->_readMsoDrawing(); break; - case self::XLS_Type_OBJ: $this->_readObj(); break; - case self::XLS_Type_WINDOW2: $this->_readWindow2(); break; - case self::XLS_Type_PAGELAYOUTVIEW: $this->_readPageLayoutView(); break; - case self::XLS_Type_SCL: $this->_readScl(); break; - case self::XLS_Type_PANE: $this->_readPane(); break; - case self::XLS_Type_SELECTION: $this->_readSelection(); break; - case self::XLS_Type_MERGEDCELLS: $this->_readMergedCells(); break; - case self::XLS_Type_HYPERLINK: $this->_readHyperLink(); break; - case self::XLS_Type_DATAVALIDATIONS: $this->_readDataValidations(); break; - case self::XLS_Type_DATAVALIDATION: $this->_readDataValidation(); break; - case self::XLS_Type_SHEETLAYOUT: $this->_readSheetLayout(); break; - case self::XLS_Type_SHEETPROTECTION: $this->_readSheetProtection(); break; - case self::XLS_Type_RANGEPROTECTION: $this->_readRangeProtection(); break; - case self::XLS_Type_NOTE: $this->_readNote(); break; - //case self::XLS_Type_IMDATA: $this->_readImData(); break; - case self::XLS_Type_TXO: $this->_readTextObject(); break; - case self::XLS_Type_CONTINUE: $this->_readContinue(); break; - case self::XLS_Type_EOF: $this->_readDefault(); break 2; - default: $this->_readDefault(); break; - } - - } - - // treat MSODRAWING records, sheet-level Escher - if (!$this->_readDataOnly && $this->_drawingData) { - $escherWorksheet = new PHPExcel_Shared_Escher(); - $reader = new PHPExcel_Reader_Excel5_Escher($escherWorksheet); - $escherWorksheet = $reader->load($this->_drawingData); - - // debug Escher stream - //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); - //$debug->load($this->_drawingData); - - // get all spContainers in one long array, so they can be mapped to OBJ records - $allSpContainers = $escherWorksheet->getDgContainer()->getSpgrContainer()->getAllSpContainers(); - } - - // treat OBJ records - foreach ($this->_objs as $n => $obj) { -// echo '
Object reference is ',$n,'
'; -// var_dump($obj); -// echo '
'; - - // the first shape container never has a corresponding OBJ record, hence $n + 1 - if (isset($allSpContainers[$n + 1]) && is_object($allSpContainers[$n + 1])) { - $spContainer = $allSpContainers[$n + 1]; - - // we skip all spContainers that are a part of a group shape since we cannot yet handle those - if ($spContainer->getNestingLevel() > 1) { - continue; - } - - // calculate the width and height of the shape - list($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($spContainer->getStartCoordinates()); - list($endColumn, $endRow) = PHPExcel_Cell::coordinateFromString($spContainer->getEndCoordinates()); - - $startOffsetX = $spContainer->getStartOffsetX(); - $startOffsetY = $spContainer->getStartOffsetY(); - $endOffsetX = $spContainer->getEndOffsetX(); - $endOffsetY = $spContainer->getEndOffsetY(); - - $width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX); - $height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY); - - // calculate offsetX and offsetY of the shape - $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024; - $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256; - - switch ($obj['otObjType']) { - case 0x19: - // Note -// echo 'Cell Annotation Object
'; -// echo 'Object ID is ',$obj['idObjID'],'
'; + // ParseXL definitions + const XLS_BIFF8 = 0x0600; + const XLS_BIFF7 = 0x0500; + const XLS_WorkbookGlobals = 0x0005; + const XLS_Worksheet = 0x0010; + + // record identifiers + const XLS_Type_FORMULA = 0x0006; + const XLS_Type_EOF = 0x000a; + const XLS_Type_PROTECT = 0x0012; + const XLS_Type_OBJECTPROTECT = 0x0063; + const XLS_Type_SCENPROTECT = 0x00dd; + const XLS_Type_PASSWORD = 0x0013; + const XLS_Type_HEADER = 0x0014; + const XLS_Type_FOOTER = 0x0015; + const XLS_Type_EXTERNSHEET = 0x0017; + const XLS_Type_DEFINEDNAME = 0x0018; + const XLS_Type_VERTICALPAGEBREAKS = 0x001a; + const XLS_Type_HORIZONTALPAGEBREAKS = 0x001b; + const XLS_Type_NOTE = 0x001c; + const XLS_Type_SELECTION = 0x001d; + const XLS_Type_DATEMODE = 0x0022; + const XLS_Type_EXTERNNAME = 0x0023; + const XLS_Type_LEFTMARGIN = 0x0026; + const XLS_Type_RIGHTMARGIN = 0x0027; + const XLS_Type_TOPMARGIN = 0x0028; + const XLS_Type_BOTTOMMARGIN = 0x0029; + const XLS_Type_PRINTGRIDLINES = 0x002b; + const XLS_Type_FILEPASS = 0x002f; + const XLS_Type_FONT = 0x0031; + const XLS_Type_CONTINUE = 0x003c; + const XLS_Type_PANE = 0x0041; + const XLS_Type_CODEPAGE = 0x0042; + const XLS_Type_DEFCOLWIDTH = 0x0055; + const XLS_Type_OBJ = 0x005d; + const XLS_Type_COLINFO = 0x007d; + const XLS_Type_IMDATA = 0x007f; + const XLS_Type_SHEETPR = 0x0081; + const XLS_Type_HCENTER = 0x0083; + const XLS_Type_VCENTER = 0x0084; + const XLS_Type_SHEET = 0x0085; + const XLS_Type_PALETTE = 0x0092; + const XLS_Type_SCL = 0x00a0; + const XLS_Type_PAGESETUP = 0x00a1; + const XLS_Type_MULRK = 0x00bd; + const XLS_Type_MULBLANK = 0x00be; + const XLS_Type_DBCELL = 0x00d7; + const XLS_Type_XF = 0x00e0; + const XLS_Type_MERGEDCELLS = 0x00e5; + const XLS_Type_MSODRAWINGGROUP = 0x00eb; + const XLS_Type_MSODRAWING = 0x00ec; + const XLS_Type_SST = 0x00fc; + const XLS_Type_LABELSST = 0x00fd; + const XLS_Type_EXTSST = 0x00ff; + const XLS_Type_EXTERNALBOOK = 0x01ae; + const XLS_Type_DATAVALIDATIONS = 0x01b2; + const XLS_Type_TXO = 0x01b6; + const XLS_Type_HYPERLINK = 0x01b8; + const XLS_Type_DATAVALIDATION = 0x01be; + const XLS_Type_DIMENSION = 0x0200; + const XLS_Type_BLANK = 0x0201; + const XLS_Type_NUMBER = 0x0203; + const XLS_Type_LABEL = 0x0204; + const XLS_Type_BOOLERR = 0x0205; + const XLS_Type_STRING = 0x0207; + const XLS_Type_ROW = 0x0208; + const XLS_Type_INDEX = 0x020b; + const XLS_Type_ARRAY = 0x0221; + const XLS_Type_DEFAULTROWHEIGHT = 0x0225; + const XLS_Type_WINDOW2 = 0x023e; + const XLS_Type_RK = 0x027e; + const XLS_Type_STYLE = 0x0293; + const XLS_Type_FORMAT = 0x041e; + const XLS_Type_SHAREDFMLA = 0x04bc; + const XLS_Type_BOF = 0x0809; + const XLS_Type_SHEETPROTECTION = 0x0867; + const XLS_Type_RANGEPROTECTION = 0x0868; + const XLS_Type_SHEETLAYOUT = 0x0862; + const XLS_Type_XFEXT = 0x087d; + const XLS_Type_PAGELAYOUTVIEW = 0x088b; + const XLS_Type_UNKNOWN = 0xffff; + + // Encryption type + const MS_BIFF_CRYPTO_NONE = 0; + const MS_BIFF_CRYPTO_XOR = 1; + const MS_BIFF_CRYPTO_RC4 = 2; + + // Size of stream blocks when using RC4 encryption + const REKEY_BLOCK = 0x400; + + /** + * Summary Information stream data. + * + * @var string + */ + private $_summaryInformation; + + /** + * Extended Summary Information stream data. + * + * @var string + */ + private $_documentSummaryInformation; + + /** + * User-Defined Properties stream data. + * + * @var string + */ + private $_userDefinedProperties; + + /** + * Workbook stream data. (Includes workbook globals substream as well as sheet substreams) + * + * @var string + */ + private $_data; + + /** + * Size in bytes of $this->_data + * + * @var int + */ + private $_dataSize; + + /** + * Current position in stream + * + * @var integer + */ + private $_pos; + + /** + * Workbook to be returned by the reader. + * + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Worksheet that is currently being built by the reader. + * + * @var PHPExcel_Worksheet + */ + private $_phpSheet; + + /** + * BIFF version + * + * @var int + */ + private $_version; + + /** + * Codepage set in the Excel file being read. Only important for BIFF5 (Excel 5.0 - Excel 95) + * For BIFF8 (Excel 97 - Excel 2003) this will always have the value 'UTF-16LE' + * + * @var string + */ + private $_codepage; + + /** + * Shared formats + * + * @var array + */ + private $_formats; + + /** + * Shared fonts + * + * @var array + */ + private $_objFonts; + + /** + * Color palette + * + * @var array + */ + private $_palette; + + /** + * Worksheets + * + * @var array + */ + private $_sheets; + + /** + * External books + * + * @var array + */ + private $_externalBooks; + + /** + * REF structures. Only applies to BIFF8. + * + * @var array + */ + private $_ref; + + /** + * External names + * + * @var array + */ + private $_externalNames; + + /** + * Defined names + * + * @var array + */ + private $_definedname; + + /** + * Shared strings. Only applies to BIFF8. + * + * @var array + */ + private $_sst; + + /** + * Panes are frozen? (in sheet currently being read). See WINDOW2 record. + * + * @var boolean + */ + private $_frozen; + + /** + * Fit printout to number of pages? (in sheet currently being read). See SHEETPR record. + * + * @var boolean + */ + private $_isFitToPages; + + /** + * Objects. One OBJ record contributes with one entry. + * + * @var array + */ + private $_objs; + + /** + * Text Objects. One TXO record corresponds with one entry. + * + * @var array + */ + private $_textObjects; + + /** + * Cell Annotations (BIFF8) + * + * @var array + */ + private $_cellNotes; + + /** + * The combined MSODRAWINGGROUP data + * + * @var string + */ + private $_drawingGroupData; + + /** + * The combined MSODRAWING data (per sheet) + * + * @var string + */ + private $_drawingData; + + /** + * Keep track of XF index + * + * @var int + */ + private $_xfIndex; + + /** + * Mapping of XF index (that is a cell XF) to final index in cellXf collection + * + * @var array + */ + private $_mapCellXfIndex; + + /** + * Mapping of XF index (that is a style XF) to final index in cellStyleXf collection + * + * @var array + */ + private $_mapCellStyleXfIndex; + + /** + * The shared formulas in a sheet. One SHAREDFMLA record contributes with one value. + * + * @var array + */ + private $_sharedFormulas; + + /** + * The shared formula parts in a sheet. One FORMULA record contributes with one value if it + * refers to a shared formula. + * + * @var array + */ + private $_sharedFormulaParts; + + /** + * The type of encryption in use + * + * @var int + */ + private $_encryption = 0; + + /** + * The position in the stream after which contents are encrypted + * + * @var int + */ + private $_encryptionStartPos = false; + + /** + * The current RC4 decryption object + * + * @var PHPExcel_Reader_Excel5_RC4 + */ + private $_rc4Key = null; + + /** + * The position in the stream that the RC4 decryption object was left at + * + * @var int + */ + private $_rc4Pos = 0; + + /** + * The current MD5 context state + * + * @var string + */ + private $_md5Ctxt = null; + + /** + * Create a new PHPExcel_Reader_Excel5 instance + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + try { + // Use ParseXL for the hard work. + $ole = new PHPExcel_Shared_OLERead(); + + // get excel data + $res = $ole->read($pFilename); + return true; + } catch (PHPExcel_Exception $e) { + return false; + } + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetNames = array(); + + // Read the OLE file + $this->_loadOLE($pFilename); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + $this->_pos = 0; + $this->_sheets = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_SHEET: $this->_readSheet(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + foreach ($this->_sheets as $sheet) { + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module + continue; + } + + $worksheetNames[] = $sheet['name']; + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + // Read the OLE file + $this->_loadOLE($pFilename); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + // initialize + $this->_pos = 0; + $this->_sheets = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_SHEET: $this->_readSheet(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + // Parse the individual sheets + foreach ($this->_sheets as $sheet) { + + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet + // 0x02: Chart + // 0x06: Visual Basic module + continue; + } + + $tmpInfo = array(); + $tmpInfo['worksheetName'] = $sheet['name']; + $tmpInfo['lastColumnLetter'] = 'A'; + $tmpInfo['lastColumnIndex'] = 0; + $tmpInfo['totalRows'] = 0; + $tmpInfo['totalColumns'] = 0; + + $this->_pos = $sheet['offset']; + + while ($this->_pos <= $this->_dataSize - 4) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_RK: + case self::XLS_Type_LABELSST: + case self::XLS_Type_NUMBER: + case self::XLS_Type_FORMULA: + case self::XLS_Type_BOOLERR: + case self::XLS_Type_LABEL: + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + $rowIndex = self::_GetInt2d($recordData, 0) + 1; + $columnIndex = self::_GetInt2d($recordData, 2); + + $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); + $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); + break; + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; + + $worksheetInfo[] = $tmpInfo; + } + + return $worksheetInfo; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Read the OLE file + $this->_loadOLE($pFilename); + + // Initialisations + $this->_phpExcel = new PHPExcel; + $this->_phpExcel->removeSheetByIndex(0); // remove 1st sheet + if (!$this->_readDataOnly) { + $this->_phpExcel->removeCellStyleXfByIndex(0); // remove the default style + $this->_phpExcel->removeCellXfByIndex(0); // remove the default style + } + + // Read the summary information stream (containing meta data) + $this->_readSummaryInformation(); + + // Read the Additional document summary information stream (containing application-specific meta data) + $this->_readDocumentSummaryInformation(); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + // initialize + $this->_pos = 0; + $this->_codepage = 'CP1252'; + $this->_formats = array(); + $this->_objFonts = array(); + $this->_palette = array(); + $this->_sheets = array(); + $this->_externalBooks = array(); + $this->_ref = array(); + $this->_definedname = array(); + $this->_sst = array(); + $this->_drawingGroupData = ''; + $this->_xfIndex = ''; + $this->_mapCellXfIndex = array(); + $this->_mapCellStyleXfIndex = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_FILEPASS: $this->_readFilepass(); break; + case self::XLS_Type_CODEPAGE: $this->_readCodepage(); break; + case self::XLS_Type_DATEMODE: $this->_readDateMode(); break; + case self::XLS_Type_FONT: $this->_readFont(); break; + case self::XLS_Type_FORMAT: $this->_readFormat(); break; + case self::XLS_Type_XF: $this->_readXf(); break; + case self::XLS_Type_XFEXT: $this->_readXfExt(); break; + case self::XLS_Type_STYLE: $this->_readStyle(); break; + case self::XLS_Type_PALETTE: $this->_readPalette(); break; + case self::XLS_Type_SHEET: $this->_readSheet(); break; + case self::XLS_Type_EXTERNALBOOK: $this->_readExternalBook(); break; + case self::XLS_Type_EXTERNNAME: $this->_readExternName(); break; + case self::XLS_Type_EXTERNSHEET: $this->_readExternSheet(); break; + case self::XLS_Type_DEFINEDNAME: $this->_readDefinedName(); break; + case self::XLS_Type_MSODRAWINGGROUP: $this->_readMsoDrawingGroup(); break; + case self::XLS_Type_SST: $this->_readSst(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + // Resolve indexed colors for font, fill, and border colors + // Cannot be resolved already in XF record, because PALETTE record comes afterwards + if (!$this->_readDataOnly) { + foreach ($this->_objFonts as $objFont) { + if (isset($objFont->colorIndex)) { + $color = self::_readColor($objFont->colorIndex,$this->_palette,$this->_version); + $objFont->getColor()->setRGB($color['rgb']); + } + } + + foreach ($this->_phpExcel->getCellXfCollection() as $objStyle) { + // fill start and end color + $fill = $objStyle->getFill(); + + if (isset($fill->startcolorIndex)) { + $startColor = self::_readColor($fill->startcolorIndex,$this->_palette,$this->_version); + $fill->getStartColor()->setRGB($startColor['rgb']); + } + + if (isset($fill->endcolorIndex)) { + $endColor = self::_readColor($fill->endcolorIndex,$this->_palette,$this->_version); + $fill->getEndColor()->setRGB($endColor['rgb']); + } + + // border colors + $top = $objStyle->getBorders()->getTop(); + $right = $objStyle->getBorders()->getRight(); + $bottom = $objStyle->getBorders()->getBottom(); + $left = $objStyle->getBorders()->getLeft(); + $diagonal = $objStyle->getBorders()->getDiagonal(); + + if (isset($top->colorIndex)) { + $borderTopColor = self::_readColor($top->colorIndex,$this->_palette,$this->_version); + $top->getColor()->setRGB($borderTopColor['rgb']); + } + + if (isset($right->colorIndex)) { + $borderRightColor = self::_readColor($right->colorIndex,$this->_palette,$this->_version); + $right->getColor()->setRGB($borderRightColor['rgb']); + } + + if (isset($bottom->colorIndex)) { + $borderBottomColor = self::_readColor($bottom->colorIndex,$this->_palette,$this->_version); + $bottom->getColor()->setRGB($borderBottomColor['rgb']); + } + + if (isset($left->colorIndex)) { + $borderLeftColor = self::_readColor($left->colorIndex,$this->_palette,$this->_version); + $left->getColor()->setRGB($borderLeftColor['rgb']); + } + + if (isset($diagonal->colorIndex)) { + $borderDiagonalColor = self::_readColor($diagonal->colorIndex,$this->_palette,$this->_version); + $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']); + } + } + } + + // treat MSODRAWINGGROUP records, workbook-level Escher + if (!$this->_readDataOnly && $this->_drawingGroupData) { + $escherWorkbook = new PHPExcel_Shared_Escher(); + $reader = new PHPExcel_Reader_Excel5_Escher($escherWorkbook); + $escherWorkbook = $reader->load($this->_drawingGroupData); + + // debug Escher stream + //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); + //$debug->load($this->_drawingGroupData); + } + + // Parse the individual sheets + foreach ($this->_sheets as $sheet) { + + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module + continue; + } + + // check if sheet should be skipped + if (isset($this->_loadSheetsOnly) && !in_array($sheet['name'], $this->_loadSheetsOnly)) { + continue; + } + + // add sheet to PHPExcel object + $this->_phpSheet = $this->_phpExcel->createSheet(); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula + // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet + // name in line with the formula, not the reverse + $this->_phpSheet->setTitle($sheet['name'],false); + $this->_phpSheet->setSheetState($sheet['sheetState']); + + $this->_pos = $sheet['offset']; + + // Initialize isFitToPages. May change after reading SHEETPR record. + $this->_isFitToPages = false; + + // Initialize drawingData + $this->_drawingData = ''; + + // Initialize objs + $this->_objs = array(); + + // Initialize shared formula parts + $this->_sharedFormulaParts = array(); + + // Initialize shared formulas + $this->_sharedFormulas = array(); + + // Initialize text objs + $this->_textObjects = array(); + + // Initialize cell annotations + $this->_cellNotes = array(); + $this->textObjRef = -1; + + while ($this->_pos <= $this->_dataSize - 4) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_PRINTGRIDLINES: $this->_readPrintGridlines(); break; + case self::XLS_Type_DEFAULTROWHEIGHT: $this->_readDefaultRowHeight(); break; + case self::XLS_Type_SHEETPR: $this->_readSheetPr(); break; + case self::XLS_Type_HORIZONTALPAGEBREAKS: $this->_readHorizontalPageBreaks(); break; + case self::XLS_Type_VERTICALPAGEBREAKS: $this->_readVerticalPageBreaks(); break; + case self::XLS_Type_HEADER: $this->_readHeader(); break; + case self::XLS_Type_FOOTER: $this->_readFooter(); break; + case self::XLS_Type_HCENTER: $this->_readHcenter(); break; + case self::XLS_Type_VCENTER: $this->_readVcenter(); break; + case self::XLS_Type_LEFTMARGIN: $this->_readLeftMargin(); break; + case self::XLS_Type_RIGHTMARGIN: $this->_readRightMargin(); break; + case self::XLS_Type_TOPMARGIN: $this->_readTopMargin(); break; + case self::XLS_Type_BOTTOMMARGIN: $this->_readBottomMargin(); break; + case self::XLS_Type_PAGESETUP: $this->_readPageSetup(); break; + case self::XLS_Type_PROTECT: $this->_readProtect(); break; + case self::XLS_Type_SCENPROTECT: $this->_readScenProtect(); break; + case self::XLS_Type_OBJECTPROTECT: $this->_readObjectProtect(); break; + case self::XLS_Type_PASSWORD: $this->_readPassword(); break; + case self::XLS_Type_DEFCOLWIDTH: $this->_readDefColWidth(); break; + case self::XLS_Type_COLINFO: $this->_readColInfo(); break; + case self::XLS_Type_DIMENSION: $this->_readDefault(); break; + case self::XLS_Type_ROW: $this->_readRow(); break; + case self::XLS_Type_DBCELL: $this->_readDefault(); break; + case self::XLS_Type_RK: $this->_readRk(); break; + case self::XLS_Type_LABELSST: $this->_readLabelSst(); break; + case self::XLS_Type_MULRK: $this->_readMulRk(); break; + case self::XLS_Type_NUMBER: $this->_readNumber(); break; + case self::XLS_Type_FORMULA: $this->_readFormula(); break; + case self::XLS_Type_SHAREDFMLA: $this->_readSharedFmla(); break; + case self::XLS_Type_BOOLERR: $this->_readBoolErr(); break; + case self::XLS_Type_MULBLANK: $this->_readMulBlank(); break; + case self::XLS_Type_LABEL: $this->_readLabel(); break; + case self::XLS_Type_BLANK: $this->_readBlank(); break; + case self::XLS_Type_MSODRAWING: $this->_readMsoDrawing(); break; + case self::XLS_Type_OBJ: $this->_readObj(); break; + case self::XLS_Type_WINDOW2: $this->_readWindow2(); break; + case self::XLS_Type_PAGELAYOUTVIEW: $this->_readPageLayoutView(); break; + case self::XLS_Type_SCL: $this->_readScl(); break; + case self::XLS_Type_PANE: $this->_readPane(); break; + case self::XLS_Type_SELECTION: $this->_readSelection(); break; + case self::XLS_Type_MERGEDCELLS: $this->_readMergedCells(); break; + case self::XLS_Type_HYPERLINK: $this->_readHyperLink(); break; + case self::XLS_Type_DATAVALIDATIONS: $this->_readDataValidations(); break; + case self::XLS_Type_DATAVALIDATION: $this->_readDataValidation(); break; + case self::XLS_Type_SHEETLAYOUT: $this->_readSheetLayout(); break; + case self::XLS_Type_SHEETPROTECTION: $this->_readSheetProtection(); break; + case self::XLS_Type_RANGEPROTECTION: $this->_readRangeProtection(); break; + case self::XLS_Type_NOTE: $this->_readNote(); break; + //case self::XLS_Type_IMDATA: $this->_readImData(); break; + case self::XLS_Type_TXO: $this->_readTextObject(); break; + case self::XLS_Type_CONTINUE: $this->_readContinue(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + + } + + // treat MSODRAWING records, sheet-level Escher + if (!$this->_readDataOnly && $this->_drawingData) { + $escherWorksheet = new PHPExcel_Shared_Escher(); + $reader = new PHPExcel_Reader_Excel5_Escher($escherWorksheet); + $escherWorksheet = $reader->load($this->_drawingData); + + // debug Escher stream + //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); + //$debug->load($this->_drawingData); + + // get all spContainers in one long array, so they can be mapped to OBJ records + $allSpContainers = $escherWorksheet->getDgContainer()->getSpgrContainer()->getAllSpContainers(); + } + + // treat OBJ records + foreach ($this->_objs as $n => $obj) { +// echo '
Object reference is ',$n,'
'; +// var_dump($obj); +// echo '
'; + + // the first shape container never has a corresponding OBJ record, hence $n + 1 + if (isset($allSpContainers[$n + 1]) && is_object($allSpContainers[$n + 1])) { + $spContainer = $allSpContainers[$n + 1]; + + // we skip all spContainers that are a part of a group shape since we cannot yet handle those + if ($spContainer->getNestingLevel() > 1) { + continue; + } + + // calculate the width and height of the shape + list($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($spContainer->getStartCoordinates()); + list($endColumn, $endRow) = PHPExcel_Cell::coordinateFromString($spContainer->getEndCoordinates()); + + $startOffsetX = $spContainer->getStartOffsetX(); + $startOffsetY = $spContainer->getStartOffsetY(); + $endOffsetX = $spContainer->getEndOffsetX(); + $endOffsetY = $spContainer->getEndOffsetY(); + + $width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX); + $height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY); + + // calculate offsetX and offsetY of the shape + $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024; + $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256; + + switch ($obj['otObjType']) { + case 0x19: + // Note +// echo 'Cell Annotation Object
'; +// echo 'Object ID is ',$obj['idObjID'],'
'; // - if (isset($this->_cellNotes[$obj['idObjID']])) { - $cellNote = $this->_cellNotes[$obj['idObjID']]; - - if (isset($this->_textObjects[$obj['idObjID']])) { - $textObject = $this->_textObjects[$obj['idObjID']]; - $this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject; - } - } - break; - - case 0x08: -// echo 'Picture Object
'; - // picture - - // get index to BSE entry (1-based) - $BSEindex = $spContainer->getOPT(0x0104); - $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection(); - $BSE = $BSECollection[$BSEindex - 1]; - $blipType = $BSE->getBlipType(); - - // need check because some blip types are not supported by Escher reader such as EMF - if ($blip = $BSE->getBlip()) { - $ih = imagecreatefromstring($blip->getData()); - $drawing = new PHPExcel_Worksheet_MemoryDrawing(); - $drawing->setImageResource($ih); - - // width, height, offsetX, offsetY - $drawing->setResizeProportional(false); - $drawing->setWidth($width); - $drawing->setHeight($height); - $drawing->setOffsetX($offsetX); - $drawing->setOffsetY($offsetY); - - switch ($blipType) { - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: - $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); - $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG); - break; - - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: - $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG); - $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG); - break; - } - - $drawing->setWorksheet($this->_phpSheet); - $drawing->setCoordinates($spContainer->getStartCoordinates()); - } - - break; - - default: - // other object type - break; - - } - } - } - - // treat SHAREDFMLA records - if ($this->_version == self::XLS_BIFF8) { - foreach ($this->_sharedFormulaParts as $cell => $baseCell) { - list($column, $row) = PHPExcel_Cell::coordinateFromString($cell); - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle()) ) { - $formula = $this->_getFormulaFromStructure($this->_sharedFormulas[$baseCell], $cell); - $this->_phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); - } - } - } - - if (!empty($this->_cellNotes)) { - foreach($this->_cellNotes as $note => $noteDetails) { - if (!isset($noteDetails['objTextData'])) { - if (isset($this->_textObjects[$note])) { - $textObject = $this->_textObjects[$note]; - $noteDetails['objTextData'] = $textObject; - } else { - $noteDetails['objTextData']['text'] = ''; - } - } -// echo 'Cell annotation ',$note,'
'; -// var_dump($noteDetails); -// echo '
'; - $cellAddress = str_replace('$','',$noteDetails['cellRef']); - $this->_phpSheet->getComment( $cellAddress ) - ->setAuthor( $noteDetails['author'] ) - ->setText($this->_parseRichText($noteDetails['objTextData']['text']) ); - } - } - } - - // add the named ranges (defined names) - foreach ($this->_definedname as $definedName) { - if ($definedName['isBuiltInName']) { - switch ($definedName['name']) { - - case pack('C', 0x06): - // print area - // in general, formula looks like this: Foo!$C$7:$J$66,Bar!$A$1:$IV$2 - $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? - - $extractedRanges = array(); - foreach ($ranges as $range) { - // $range should look like one of these - // Foo!$C$7:$J$66 - // Bar!$A$1:$IV$2 - - $explodes = explode('!', $range); // FIXME: what if sheetname contains exclamation mark? - $sheetName = trim($explodes[0], "'"); - - if (count($explodes) == 2) { - if (strpos($explodes[1], ':') === FALSE) { - $explodes[1] = $explodes[1] . ':' . $explodes[1]; - } - $extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66 - } - } - if ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) { - $docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges)); // C7:J66,A1:IV2 - } - break; - - case pack('C', 0x07): - // print titles (repeating rows) - // Assuming BIFF8, there are 3 cases - // 1. repeating rows - // formula looks like this: Sheet!$A$1:$IV$2 - // rows 1-2 repeat - // 2. repeating columns - // formula looks like this: Sheet!$A$1:$B$65536 - // columns A-B repeat - // 3. both repeating rows and repeating columns - // formula looks like this: Sheet!$A$1:$B$65536,Sheet!$A$1:$IV$2 - - $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? - - foreach ($ranges as $range) { - // $range should look like this one of these - // Sheet!$A$1:$B$65536 - // Sheet!$A$1:$IV$2 - - $explodes = explode('!', $range); - - if (count($explodes) == 2) { - if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) { - - $extractedRange = $explodes[1]; - $extractedRange = str_replace('$', '', $extractedRange); - - $coordinateStrings = explode(':', $extractedRange); - if (count($coordinateStrings) == 2) { - list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[0]); - list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[1]); - - if ($firstColumn == 'A' and $lastColumn == 'IV') { - // then we have repeating rows - $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($firstRow, $lastRow)); - } elseif ($firstRow == 1 and $lastRow == 65536) { - // then we have repeating columns - $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($firstColumn, $lastColumn)); - } - } - } - } - } - break; - - } - } else { - // Extract range - $explodes = explode('!', $definedName['formula']); - - if (count($explodes) == 2) { - if (($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) || - ($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0],"'")))) { - $extractedRange = $explodes[1]; - $extractedRange = str_replace('$', '', $extractedRange); - - $localOnly = ($definedName['scope'] == 0) ? false : true; - - $scope = ($definedName['scope'] == 0) ? - null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']); - - $this->_phpExcel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope) ); - } - } else { - // Named Value - // TODO Provide support for named values - } - } - } + if (isset($this->_cellNotes[$obj['idObjID']])) { + $cellNote = $this->_cellNotes[$obj['idObjID']]; + + if (isset($this->_textObjects[$obj['idObjID']])) { + $textObject = $this->_textObjects[$obj['idObjID']]; + $this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject; + } + } + break; + + case 0x08: +// echo 'Picture Object
'; + // picture + + // get index to BSE entry (1-based) + $BSEindex = $spContainer->getOPT(0x0104); + $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection(); + $BSE = $BSECollection[$BSEindex - 1]; + $blipType = $BSE->getBlipType(); + + // need check because some blip types are not supported by Escher reader such as EMF + if ($blip = $BSE->getBlip()) { + $ih = imagecreatefromstring($blip->getData()); + $drawing = new PHPExcel_Worksheet_MemoryDrawing(); + $drawing->setImageResource($ih); + + // width, height, offsetX, offsetY + $drawing->setResizeProportional(false); + $drawing->setWidth($width); + $drawing->setHeight($height); + $drawing->setOffsetX($offsetX); + $drawing->setOffsetY($offsetY); + + switch ($blipType) { + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: + $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); + $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG); + break; + + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: + $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG); + $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG); + break; + } + + $drawing->setWorksheet($this->_phpSheet); + $drawing->setCoordinates($spContainer->getStartCoordinates()); + } + + break; + + default: + // other object type + break; + + } + } + } + + // treat SHAREDFMLA records + if ($this->_version == self::XLS_BIFF8) { + foreach ($this->_sharedFormulaParts as $cell => $baseCell) { + list($column, $row) = PHPExcel_Cell::coordinateFromString($cell); + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle()) ) { + $formula = $this->_getFormulaFromStructure($this->_sharedFormulas[$baseCell], $cell); + $this->_phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + } + } + } + + if (!empty($this->_cellNotes)) { + foreach($this->_cellNotes as $note => $noteDetails) { + if (!isset($noteDetails['objTextData'])) { + if (isset($this->_textObjects[$note])) { + $textObject = $this->_textObjects[$note]; + $noteDetails['objTextData'] = $textObject; + } else { + $noteDetails['objTextData']['text'] = ''; + } + } +// echo 'Cell annotation ',$note,'
'; +// var_dump($noteDetails); +// echo '
'; + $cellAddress = str_replace('$','',$noteDetails['cellRef']); + $this->_phpSheet->getComment( $cellAddress ) + ->setAuthor( $noteDetails['author'] ) + ->setText($this->_parseRichText($noteDetails['objTextData']['text']) ); + } + } + } + + // add the named ranges (defined names) + foreach ($this->_definedname as $definedName) { + if ($definedName['isBuiltInName']) { + switch ($definedName['name']) { + + case pack('C', 0x06): + // print area + // in general, formula looks like this: Foo!$C$7:$J$66,Bar!$A$1:$IV$2 + $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? + + $extractedRanges = array(); + foreach ($ranges as $range) { + // $range should look like one of these + // Foo!$C$7:$J$66 + // Bar!$A$1:$IV$2 + + $explodes = explode('!', $range); // FIXME: what if sheetname contains exclamation mark? + $sheetName = trim($explodes[0], "'"); + + if (count($explodes) == 2) { + if (strpos($explodes[1], ':') === FALSE) { + $explodes[1] = $explodes[1] . ':' . $explodes[1]; + } + $extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66 + } + } + if ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) { + $docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges)); // C7:J66,A1:IV2 + } + break; + + case pack('C', 0x07): + // print titles (repeating rows) + // Assuming BIFF8, there are 3 cases + // 1. repeating rows + // formula looks like this: Sheet!$A$1:$IV$2 + // rows 1-2 repeat + // 2. repeating columns + // formula looks like this: Sheet!$A$1:$B$65536 + // columns A-B repeat + // 3. both repeating rows and repeating columns + // formula looks like this: Sheet!$A$1:$B$65536,Sheet!$A$1:$IV$2 + + $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? + + foreach ($ranges as $range) { + // $range should look like this one of these + // Sheet!$A$1:$B$65536 + // Sheet!$A$1:$IV$2 + + $explodes = explode('!', $range); + + if (count($explodes) == 2) { + if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) { + + $extractedRange = $explodes[1]; + $extractedRange = str_replace('$', '', $extractedRange); + + $coordinateStrings = explode(':', $extractedRange); + if (count($coordinateStrings) == 2) { + list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[0]); + list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[1]); + + if ($firstColumn == 'A' and $lastColumn == 'IV') { + // then we have repeating rows + $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($firstRow, $lastRow)); + } elseif ($firstRow == 1 and $lastRow == 65536) { + // then we have repeating columns + $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($firstColumn, $lastColumn)); + } + } + } + } + } + break; + + } + } else { + // Extract range + $explodes = explode('!', $definedName['formula']); + + if (count($explodes) == 2) { + if (($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) || + ($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0],"'")))) { + $extractedRange = $explodes[1]; + $extractedRange = str_replace('$', '', $extractedRange); + + $localOnly = ($definedName['scope'] == 0) ? false : true; + + $scope = ($definedName['scope'] == 0) ? + null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']); + + $this->_phpExcel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope) ); + } + } else { + // Named Value + // TODO Provide support for named values + } + } + } $this->_data = null; - return $this->_phpExcel; - } - - /** - * Read record data from stream, decrypting as required - * - * @param string $data Data stream to read from - * @param int $pos Position to start reading from - * @param int $length Record data length - * - * @return string Record data - */ - private function _readRecordData($data, $pos, $len) - { - $data = substr($data, $pos, $len); - - // File not encrypted, or record before encryption start point - if ($this->_encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->_encryptionStartPos) { - return $data; - } - - $recordData = ''; - if ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) { - - $oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK); - $block = floor($pos / self::REKEY_BLOCK); - $endBlock = floor(($pos + $len) / self::REKEY_BLOCK); - - // Spin an RC4 decryptor to the right spot. If we have a decryptor sitting - // at a point earlier in the current block, re-use it as we can save some time. - if ($block != $oldBlock || $pos < $this->_rc4Pos || !$this->_rc4Key) { - $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); - $step = $pos % self::REKEY_BLOCK; - } else { - $step = $pos - $this->_rc4Pos; - } - $this->_rc4Key->RC4(str_repeat("\0", $step)); - - // Decrypt record data (re-keying at the end of every block) - while ($block != $endBlock) { - $step = self::REKEY_BLOCK - ($pos % self::REKEY_BLOCK); - $recordData .= $this->_rc4Key->RC4(substr($data, 0, $step)); - $data = substr($data, $step); - $pos += $step; - $len -= $step; - $block++; - $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); - } - $recordData .= $this->_rc4Key->RC4(substr($data, 0, $len)); - - // Keep track of the position of this decryptor. - // We'll try and re-use it later if we can to speed things up - $this->_rc4Pos = $pos + $len; - - } elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) { - throw new PHPExcel_Reader_Exception('XOr encryption not supported'); - } - return $recordData; - } - - /** - * Use OLE reader to extract the relevant data streams from the OLE file - * - * @param string $pFilename - */ - private function _loadOLE($pFilename) - { - // OLE reader - $ole = new PHPExcel_Shared_OLERead(); - - // get excel data, - $res = $ole->read($pFilename); - // Get workbook data: workbook stream + sheet streams - $this->_data = $ole->getStream($ole->wrkbook); - - // Get summary information data - $this->_summaryInformation = $ole->getStream($ole->summaryInformation); - - // Get additional document summary information data - $this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation); - - // Get user-defined property data -// $this->_userDefinedProperties = $ole->getUserDefinedProperties(); - } - - - /** - * Read summary information - */ - private function _readSummaryInformation() - { - if (!isset($this->_summaryInformation)) { - return; - } - - // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) - // offset: 2; size: 2; - // offset: 4; size: 2; OS version - // offset: 6; size: 2; OS indicator - // offset: 8; size: 16 - // offset: 24; size: 4; section count - $secCount = self::_GetInt4d($this->_summaryInformation, 24); - - // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 - // offset: 44; size: 4 - $secOffset = self::_GetInt4d($this->_summaryInformation, 44); - - // section header - // offset: $secOffset; size: 4; section length - $secLength = self::_GetInt4d($this->_summaryInformation, $secOffset); - - // offset: $secOffset+4; size: 4; property count - $countProperties = self::_GetInt4d($this->_summaryInformation, $secOffset+4); - - // initialize code page (used to resolve string values) - $codePage = 'CP1252'; - - // offset: ($secOffset+8); size: var - // loop through property decarations and properties - for ($i = 0; $i < $countProperties; ++$i) { - - // offset: ($secOffset+8) + (8 * $i); size: 4; property ID - $id = self::_GetInt4d($this->_summaryInformation, ($secOffset+8) + (8 * $i)); - - // Use value of property id as appropriate - // offset: ($secOffset+12) + (8 * $i); size: 4; offset from beginning of section (48) - $offset = self::_GetInt4d($this->_summaryInformation, ($secOffset+12) + (8 * $i)); - - $type = self::_GetInt4d($this->_summaryInformation, $secOffset + $offset); - - // initialize property value - $value = null; - - // extract property value based on property type - switch ($type) { - case 0x02: // 2 byte signed integer - $value = self::_GetInt2d($this->_summaryInformation, $secOffset + 4 + $offset); - break; - - case 0x03: // 4 byte signed integer - $value = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); - break; - - case 0x13: // 4 byte unsigned integer - // not needed yet, fix later if necessary - break; - - case 0x1E: // null-terminated string prepended by dword string length - $byteLength = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); - $value = substr($this->_summaryInformation, $secOffset + 8 + $offset, $byteLength); - $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); - $value = rtrim($value); - break; - - case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) - // PHP-time - $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_summaryInformation, $secOffset + 4 + $offset, 8)); - break; - - case 0x47: // Clipboard format - // not needed yet, fix later if necessary - break; - } - - switch ($id) { - case 0x01: // Code Page - $codePage = PHPExcel_Shared_CodePage::NumberToName($value); - break; - - case 0x02: // Title - $this->_phpExcel->getProperties()->setTitle($value); - break; - - case 0x03: // Subject - $this->_phpExcel->getProperties()->setSubject($value); - break; - - case 0x04: // Author (Creator) - $this->_phpExcel->getProperties()->setCreator($value); - break; - - case 0x05: // Keywords - $this->_phpExcel->getProperties()->setKeywords($value); - break; - - case 0x06: // Comments (Description) - $this->_phpExcel->getProperties()->setDescription($value); - break; - - case 0x07: // Template - // Not supported by PHPExcel - break; - - case 0x08: // Last Saved By (LastModifiedBy) - $this->_phpExcel->getProperties()->setLastModifiedBy($value); - break; - - case 0x09: // Revision - // Not supported by PHPExcel - break; - - case 0x0A: // Total Editing Time - // Not supported by PHPExcel - break; - - case 0x0B: // Last Printed - // Not supported by PHPExcel - break; - - case 0x0C: // Created Date/Time - $this->_phpExcel->getProperties()->setCreated($value); - break; - - case 0x0D: // Modified Date/Time - $this->_phpExcel->getProperties()->setModified($value); - break; - - case 0x0E: // Number of Pages - // Not supported by PHPExcel - break; - - case 0x0F: // Number of Words - // Not supported by PHPExcel - break; - - case 0x10: // Number of Characters - // Not supported by PHPExcel - break; - - case 0x11: // Thumbnail - // Not supported by PHPExcel - break; - - case 0x12: // Name of creating application - // Not supported by PHPExcel - break; - - case 0x13: // Security - // Not supported by PHPExcel - break; - - } - } - } - - - /** - * Read additional document summary information - */ - private function _readDocumentSummaryInformation() - { - if (!isset($this->_documentSummaryInformation)) { - return; - } - - // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) - // offset: 2; size: 2; - // offset: 4; size: 2; OS version - // offset: 6; size: 2; OS indicator - // offset: 8; size: 16 - // offset: 24; size: 4; section count - $secCount = self::_GetInt4d($this->_documentSummaryInformation, 24); -// echo '$secCount = ',$secCount,'
'; - - // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae - // offset: 44; size: 4; first section offset - $secOffset = self::_GetInt4d($this->_documentSummaryInformation, 44); -// echo '$secOffset = ',$secOffset,'
'; - - // section header - // offset: $secOffset; size: 4; section length - $secLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset); -// echo '$secLength = ',$secLength,'
'; - - // offset: $secOffset+4; size: 4; property count - $countProperties = self::_GetInt4d($this->_documentSummaryInformation, $secOffset+4); -// echo '$countProperties = ',$countProperties,'
'; - - // initialize code page (used to resolve string values) - $codePage = 'CP1252'; - - // offset: ($secOffset+8); size: var - // loop through property decarations and properties - for ($i = 0; $i < $countProperties; ++$i) { -// echo 'Property ',$i,'
'; - // offset: ($secOffset+8) + (8 * $i); size: 4; property ID - $id = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+8) + (8 * $i)); -// echo 'ID is ',$id,'
'; - - // Use value of property id as appropriate - // offset: 60 + 8 * $i; size: 4; offset from beginning of section (48) - $offset = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+12) + (8 * $i)); - - $type = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + $offset); -// echo 'Type is ',$type,', '; - - // initialize property value - $value = null; - - // extract property value based on property type - switch ($type) { - case 0x02: // 2 byte signed integer - $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); - break; - - case 0x03: // 4 byte signed integer - $value = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); - break; - - case 0x0B: // Boolean - $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); - $value = ($value == 0 ? false : true); - break; - - case 0x13: // 4 byte unsigned integer - // not needed yet, fix later if necessary - break; - - case 0x1E: // null-terminated string prepended by dword string length - $byteLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); - $value = substr($this->_documentSummaryInformation, $secOffset + 8 + $offset, $byteLength); - $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); - $value = rtrim($value); - break; - - case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) - // PHP-Time - $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_documentSummaryInformation, $secOffset + 4 + $offset, 8)); - break; - - case 0x47: // Clipboard format - // not needed yet, fix later if necessary - break; - } - - switch ($id) { - case 0x01: // Code Page - $codePage = PHPExcel_Shared_CodePage::NumberToName($value); - break; - - case 0x02: // Category - $this->_phpExcel->getProperties()->setCategory($value); - break; - - case 0x03: // Presentation Target - // Not supported by PHPExcel - break; - - case 0x04: // Bytes - // Not supported by PHPExcel - break; - - case 0x05: // Lines - // Not supported by PHPExcel - break; - - case 0x06: // Paragraphs - // Not supported by PHPExcel - break; - - case 0x07: // Slides - // Not supported by PHPExcel - break; - - case 0x08: // Notes - // Not supported by PHPExcel - break; - - case 0x09: // Hidden Slides - // Not supported by PHPExcel - break; - - case 0x0A: // MM Clips - // Not supported by PHPExcel - break; - - case 0x0B: // Scale Crop - // Not supported by PHPExcel - break; - - case 0x0C: // Heading Pairs - // Not supported by PHPExcel - break; - - case 0x0D: // Titles of Parts - // Not supported by PHPExcel - break; - - case 0x0E: // Manager - $this->_phpExcel->getProperties()->setManager($value); - break; - - case 0x0F: // Company - $this->_phpExcel->getProperties()->setCompany($value); - break; - - case 0x10: // Links up-to-date - // Not supported by PHPExcel - break; - - } - } - } - - - /** - * Reads a general type of BIFF record. Does nothing except for moving stream pointer forward to next record. - */ - private function _readDefault() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); -// $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - } - - - /** - * The NOTE record specifies a comment associated with a particular cell. In Excel 95 (BIFF7) and earlier versions, - * this record stores a note (cell note). This feature was significantly enhanced in Excel 97. - */ - private function _readNote() - { -// echo 'Read Cell Annotation
'; - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - $cellAddress = $this->_readBIFF8CellAddress(substr($recordData, 0, 4)); - if ($this->_version == self::XLS_BIFF8) { - $noteObjID = self::_GetInt2d($recordData, 6); - $noteAuthor = self::_readUnicodeStringLong(substr($recordData, 8)); - $noteAuthor = $noteAuthor['value']; -// echo 'Note Address=',$cellAddress,'
'; -// echo 'Note Object ID=',$noteObjID,'
'; -// echo 'Note Author=',$noteAuthor,'
'; + return $this->_phpExcel; + } + + /** + * Read record data from stream, decrypting as required + * + * @param string $data Data stream to read from + * @param int $pos Position to start reading from + * @param int $length Record data length + * + * @return string Record data + */ + private function _readRecordData($data, $pos, $len) + { + $data = substr($data, $pos, $len); + + // File not encrypted, or record before encryption start point + if ($this->_encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->_encryptionStartPos) { + return $data; + } + + $recordData = ''; + if ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) { + + $oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK); + $block = floor($pos / self::REKEY_BLOCK); + $endBlock = floor(($pos + $len) / self::REKEY_BLOCK); + + // Spin an RC4 decryptor to the right spot. If we have a decryptor sitting + // at a point earlier in the current block, re-use it as we can save some time. + if ($block != $oldBlock || $pos < $this->_rc4Pos || !$this->_rc4Key) { + $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + $step = $pos % self::REKEY_BLOCK; + } else { + $step = $pos - $this->_rc4Pos; + } + $this->_rc4Key->RC4(str_repeat("\0", $step)); + + // Decrypt record data (re-keying at the end of every block) + while ($block != $endBlock) { + $step = self::REKEY_BLOCK - ($pos % self::REKEY_BLOCK); + $recordData .= $this->_rc4Key->RC4(substr($data, 0, $step)); + $data = substr($data, $step); + $pos += $step; + $len -= $step; + $block++; + $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + } + $recordData .= $this->_rc4Key->RC4(substr($data, 0, $len)); + + // Keep track of the position of this decryptor. + // We'll try and re-use it later if we can to speed things up + $this->_rc4Pos = $pos + $len; + + } elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) { + throw new PHPExcel_Reader_Exception('XOr encryption not supported'); + } + return $recordData; + } + + /** + * Use OLE reader to extract the relevant data streams from the OLE file + * + * @param string $pFilename + */ + private function _loadOLE($pFilename) + { + // OLE reader + $ole = new PHPExcel_Shared_OLERead(); + + // get excel data, + $res = $ole->read($pFilename); + // Get workbook data: workbook stream + sheet streams + $this->_data = $ole->getStream($ole->wrkbook); + + // Get summary information data + $this->_summaryInformation = $ole->getStream($ole->summaryInformation); + + // Get additional document summary information data + $this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation); + + // Get user-defined property data +// $this->_userDefinedProperties = $ole->getUserDefinedProperties(); + } + + + /** + * Read summary information + */ + private function _readSummaryInformation() + { + if (!isset($this->_summaryInformation)) { + return; + } + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + // offset: 2; size: 2; + // offset: 4; size: 2; OS version + // offset: 6; size: 2; OS indicator + // offset: 8; size: 16 + // offset: 24; size: 4; section count + $secCount = self::_GetInt4d($this->_summaryInformation, 24); + + // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 + // offset: 44; size: 4 + $secOffset = self::_GetInt4d($this->_summaryInformation, 44); + + // section header + // offset: $secOffset; size: 4; section length + $secLength = self::_GetInt4d($this->_summaryInformation, $secOffset); + + // offset: $secOffset+4; size: 4; property count + $countProperties = self::_GetInt4d($this->_summaryInformation, $secOffset+4); + + // initialize code page (used to resolve string values) + $codePage = 'CP1252'; + + // offset: ($secOffset+8); size: var + // loop through property decarations and properties + for ($i = 0; $i < $countProperties; ++$i) { + + // offset: ($secOffset+8) + (8 * $i); size: 4; property ID + $id = self::_GetInt4d($this->_summaryInformation, ($secOffset+8) + (8 * $i)); + + // Use value of property id as appropriate + // offset: ($secOffset+12) + (8 * $i); size: 4; offset from beginning of section (48) + $offset = self::_GetInt4d($this->_summaryInformation, ($secOffset+12) + (8 * $i)); + + $type = self::_GetInt4d($this->_summaryInformation, $secOffset + $offset); + + // initialize property value + $value = null; + + // extract property value based on property type + switch ($type) { + case 0x02: // 2 byte signed integer + $value = self::_GetInt2d($this->_summaryInformation, $secOffset + 4 + $offset); + break; + + case 0x03: // 4 byte signed integer + $value = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); + break; + + case 0x13: // 4 byte unsigned integer + // not needed yet, fix later if necessary + break; + + case 0x1E: // null-terminated string prepended by dword string length + $byteLength = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); + $value = substr($this->_summaryInformation, $secOffset + 8 + $offset, $byteLength); + $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); + $value = rtrim($value); + break; + + case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + // PHP-time + $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_summaryInformation, $secOffset + 4 + $offset, 8)); + break; + + case 0x47: // Clipboard format + // not needed yet, fix later if necessary + break; + } + + switch ($id) { + case 0x01: // Code Page + $codePage = PHPExcel_Shared_CodePage::NumberToName($value); + break; + + case 0x02: // Title + $this->_phpExcel->getProperties()->setTitle($value); + break; + + case 0x03: // Subject + $this->_phpExcel->getProperties()->setSubject($value); + break; + + case 0x04: // Author (Creator) + $this->_phpExcel->getProperties()->setCreator($value); + break; + + case 0x05: // Keywords + $this->_phpExcel->getProperties()->setKeywords($value); + break; + + case 0x06: // Comments (Description) + $this->_phpExcel->getProperties()->setDescription($value); + break; + + case 0x07: // Template + // Not supported by PHPExcel + break; + + case 0x08: // Last Saved By (LastModifiedBy) + $this->_phpExcel->getProperties()->setLastModifiedBy($value); + break; + + case 0x09: // Revision + // Not supported by PHPExcel + break; + + case 0x0A: // Total Editing Time + // Not supported by PHPExcel + break; + + case 0x0B: // Last Printed + // Not supported by PHPExcel + break; + + case 0x0C: // Created Date/Time + $this->_phpExcel->getProperties()->setCreated($value); + break; + + case 0x0D: // Modified Date/Time + $this->_phpExcel->getProperties()->setModified($value); + break; + + case 0x0E: // Number of Pages + // Not supported by PHPExcel + break; + + case 0x0F: // Number of Words + // Not supported by PHPExcel + break; + + case 0x10: // Number of Characters + // Not supported by PHPExcel + break; + + case 0x11: // Thumbnail + // Not supported by PHPExcel + break; + + case 0x12: // Name of creating application + // Not supported by PHPExcel + break; + + case 0x13: // Security + // Not supported by PHPExcel + break; + + } + } + } + + + /** + * Read additional document summary information + */ + private function _readDocumentSummaryInformation() + { + if (!isset($this->_documentSummaryInformation)) { + return; + } + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + // offset: 2; size: 2; + // offset: 4; size: 2; OS version + // offset: 6; size: 2; OS indicator + // offset: 8; size: 16 + // offset: 24; size: 4; section count + $secCount = self::_GetInt4d($this->_documentSummaryInformation, 24); +// echo '$secCount = ',$secCount,'
'; + + // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae + // offset: 44; size: 4; first section offset + $secOffset = self::_GetInt4d($this->_documentSummaryInformation, 44); +// echo '$secOffset = ',$secOffset,'
'; + + // section header + // offset: $secOffset; size: 4; section length + $secLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset); +// echo '$secLength = ',$secLength,'
'; + + // offset: $secOffset+4; size: 4; property count + $countProperties = self::_GetInt4d($this->_documentSummaryInformation, $secOffset+4); +// echo '$countProperties = ',$countProperties,'
'; + + // initialize code page (used to resolve string values) + $codePage = 'CP1252'; + + // offset: ($secOffset+8); size: var + // loop through property decarations and properties + for ($i = 0; $i < $countProperties; ++$i) { +// echo 'Property ',$i,'
'; + // offset: ($secOffset+8) + (8 * $i); size: 4; property ID + $id = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+8) + (8 * $i)); +// echo 'ID is ',$id,'
'; + + // Use value of property id as appropriate + // offset: 60 + 8 * $i; size: 4; offset from beginning of section (48) + $offset = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+12) + (8 * $i)); + + $type = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + $offset); +// echo 'Type is ',$type,', '; + + // initialize property value + $value = null; + + // extract property value based on property type + switch ($type) { + case 0x02: // 2 byte signed integer + $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + break; + + case 0x03: // 4 byte signed integer + $value = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + break; + + case 0x0B: // Boolean + $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = ($value == 0 ? false : true); + break; + + case 0x13: // 4 byte unsigned integer + // not needed yet, fix later if necessary + break; + + case 0x1E: // null-terminated string prepended by dword string length + $byteLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = substr($this->_documentSummaryInformation, $secOffset + 8 + $offset, $byteLength); + $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); + $value = rtrim($value); + break; + + case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + // PHP-Time + $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_documentSummaryInformation, $secOffset + 4 + $offset, 8)); + break; + + case 0x47: // Clipboard format + // not needed yet, fix later if necessary + break; + } + + switch ($id) { + case 0x01: // Code Page + $codePage = PHPExcel_Shared_CodePage::NumberToName($value); + break; + + case 0x02: // Category + $this->_phpExcel->getProperties()->setCategory($value); + break; + + case 0x03: // Presentation Target + // Not supported by PHPExcel + break; + + case 0x04: // Bytes + // Not supported by PHPExcel + break; + + case 0x05: // Lines + // Not supported by PHPExcel + break; + + case 0x06: // Paragraphs + // Not supported by PHPExcel + break; + + case 0x07: // Slides + // Not supported by PHPExcel + break; + + case 0x08: // Notes + // Not supported by PHPExcel + break; + + case 0x09: // Hidden Slides + // Not supported by PHPExcel + break; + + case 0x0A: // MM Clips + // Not supported by PHPExcel + break; + + case 0x0B: // Scale Crop + // Not supported by PHPExcel + break; + + case 0x0C: // Heading Pairs + // Not supported by PHPExcel + break; + + case 0x0D: // Titles of Parts + // Not supported by PHPExcel + break; + + case 0x0E: // Manager + $this->_phpExcel->getProperties()->setManager($value); + break; + + case 0x0F: // Company + $this->_phpExcel->getProperties()->setCompany($value); + break; + + case 0x10: // Links up-to-date + // Not supported by PHPExcel + break; + + } + } + } + + + /** + * Reads a general type of BIFF record. Does nothing except for moving stream pointer forward to next record. + */ + private function _readDefault() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); +// $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + } + + + /** + * The NOTE record specifies a comment associated with a particular cell. In Excel 95 (BIFF7) and earlier versions, + * this record stores a note (cell note). This feature was significantly enhanced in Excel 97. + */ + private function _readNote() + { +// echo 'Read Cell Annotation
'; + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + $cellAddress = $this->_readBIFF8CellAddress(substr($recordData, 0, 4)); + if ($this->_version == self::XLS_BIFF8) { + $noteObjID = self::_GetInt2d($recordData, 6); + $noteAuthor = self::_readUnicodeStringLong(substr($recordData, 8)); + $noteAuthor = $noteAuthor['value']; +// echo 'Note Address=',$cellAddress,'
'; +// echo 'Note Object ID=',$noteObjID,'
'; +// echo 'Note Author=',$noteAuthor,'
'; // - $this->_cellNotes[$noteObjID] = array('cellRef' => $cellAddress, - 'objectID' => $noteObjID, - 'author' => $noteAuthor - ); - } else { - $extension = false; - if ($cellAddress == '$B$65536') { - // If the address row is -1 and the column is 0, (which translates as $B$65536) then this is a continuation - // note from the previous cell annotation. We're not yet handling this, so annotations longer than the - // max 2048 bytes will probably throw a wobbly. - $row = self::_GetInt2d($recordData, 0); - $extension = true; - $cellAddress = array_pop(array_keys($this->_phpSheet->getComments())); - } -// echo 'Note Address=',$cellAddress,'
'; - - $cellAddress = str_replace('$','',$cellAddress); - $noteLength = self::_GetInt2d($recordData, 4); - $noteText = trim(substr($recordData, 6)); -// echo 'Note Length=',$noteLength,'
'; -// echo 'Note Text=',$noteText,'
'; - - if ($extension) { - // Concatenate this extension with the currently set comment for the cell - $comment = $this->_phpSheet->getComment( $cellAddress ); - $commentText = $comment->getText()->getPlainText(); - $comment->setText($this->_parseRichText($commentText.$noteText) ); - } else { - // Set comment for the cell - $this->_phpSheet->getComment( $cellAddress ) -// ->setAuthor( $author ) - ->setText($this->_parseRichText($noteText) ); - } - } - - } - - - /** - * The TEXT Object record contains the text associated with a cell annotation. - */ - private function _readTextObject() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - // recordData consists of an array of subrecords looking like this: - // grbit: 2 bytes; Option Flags - // rot: 2 bytes; rotation - // cchText: 2 bytes; length of the text (in the first continue record) - // cbRuns: 2 bytes; length of the formatting (in the second continue record) - // followed by the continuation records containing the actual text and formatting - $grbitOpts = self::_GetInt2d($recordData, 0); - $rot = self::_GetInt2d($recordData, 2); - $cchText = self::_GetInt2d($recordData, 10); - $cbRuns = self::_GetInt2d($recordData, 12); - $text = $this->_getSplicedRecordData(); - - $this->_textObjects[$this->textObjRef] = array( - 'text' => substr($text["recordData"],$text["spliceOffsets"][0]+1,$cchText), - 'format' => substr($text["recordData"],$text["spliceOffsets"][1],$cbRuns), - 'alignment' => $grbitOpts, - 'rotation' => $rot - ); - -// echo '_readTextObject()
'; -// var_dump($this->_textObjects[$this->textObjRef]); -// echo '
'; - } - - - /** - * Read BOF - */ - private function _readBof() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 2; size: 2; type of the following data - $substreamType = self::_GetInt2d($recordData, 2); - - switch ($substreamType) { - case self::XLS_WorkbookGlobals: - $version = self::_GetInt2d($recordData, 0); - if (($version != self::XLS_BIFF8) && ($version != self::XLS_BIFF7)) { - throw new PHPExcel_Reader_Exception('Cannot read this Excel file. Version is too old.'); - } - $this->_version = $version; - break; - - case self::XLS_Worksheet: - // do not use this version information for anything - // it is unreliable (OpenOffice doc, 5.8), use only version information from the global stream - break; - - default: - // substream, e.g. chart - // just skip the entire substream - do { - $code = self::_GetInt2d($this->_data, $this->_pos); - $this->_readDefault(); - } while ($code != self::XLS_Type_EOF && $this->_pos < $this->_dataSize); - break; - } - } - - - /** - * FILEPASS - * - * This record is part of the File Protection Block. It - * contains information about the read/write password of the - * file. All record contents following this record will be - * encrypted. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - * - * The decryption functions and objects used from here on in - * are based on the source of Spreadsheet-ParseExcel: - * http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/ - */ - private function _readFilepass() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - - if ($length != 54) { - throw new PHPExcel_Reader_Exception('Unexpected file pass record length'); - } - - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_verifyPassword( - 'VelvetSweatshop', - substr($recordData, 6, 16), - substr($recordData, 22, 16), - substr($recordData, 38, 16), - $this->_md5Ctxt - )) { - throw new PHPExcel_Reader_Exception('Decryption password incorrect'); - } - - $this->_encryption = self::MS_BIFF_CRYPTO_RC4; - - // Decryption required from the record after next onwards - $this->_encryptionStartPos = $this->_pos + self::_GetInt2d($this->_data, $this->_pos + 2); - } - - /** - * Make an RC4 decryptor for the given block - * - * @var int $block Block for which to create decrypto - * @var string $valContext MD5 context state - * - * @return PHPExcel_Reader_Excel5_RC4 - */ - private function _makeKey($block, $valContext) - { - $pwarray = str_repeat("\0", 64); - - for ($i = 0; $i < 5; $i++) { - $pwarray[$i] = $valContext[$i]; - } - - $pwarray[5] = chr($block & 0xff); - $pwarray[6] = chr(($block >> 8) & 0xff); - $pwarray[7] = chr(($block >> 16) & 0xff); - $pwarray[8] = chr(($block >> 24) & 0xff); - - $pwarray[9] = "\x80"; - $pwarray[56] = "\x48"; - - $md5 = new PHPExcel_Reader_Excel5_MD5(); - $md5->add($pwarray); - - $s = $md5->getContext(); - return new PHPExcel_Reader_Excel5_RC4($s); - } - - /** - * Verify RC4 file password - * - * @var string $password Password to check - * @var string $docid Document id - * @var string $salt_data Salt data - * @var string $hashedsalt_data Hashed salt data - * @var string &$valContext Set to the MD5 context of the value - * - * @return bool Success - */ - private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext) - { - $pwarray = str_repeat("\0", 64); - - for ($i = 0; $i < strlen($password); $i++) { - $o = ord(substr($password, $i, 1)); - $pwarray[2 * $i] = chr($o & 0xff); - $pwarray[2 * $i + 1] = chr(($o >> 8) & 0xff); - } - $pwarray[2 * $i] = chr(0x80); - $pwarray[56] = chr(($i << 4) & 0xff); - - $md5 = new PHPExcel_Reader_Excel5_MD5(); - $md5->add($pwarray); - - $mdContext1 = $md5->getContext(); - - $offset = 0; - $keyoffset = 0; - $tocopy = 5; - - $md5->reset(); - - while ($offset != 16) { - if ((64 - $offset) < 5) { - $tocopy = 64 - $offset; - } - - for ($i = 0; $i <= $tocopy; $i++) { - $pwarray[$offset + $i] = $mdContext1[$keyoffset + $i]; - } - - $offset += $tocopy; - - if ($offset == 64) { - $md5->add($pwarray); - $keyoffset = $tocopy; - $tocopy = 5 - $tocopy; - $offset = 0; - continue; - } - - $keyoffset = 0; - $tocopy = 5; - for ($i = 0; $i < 16; $i++) { - $pwarray[$offset + $i] = $docid[$i]; - } - $offset += 16; - } - - $pwarray[16] = "\x80"; - for ($i = 0; $i < 47; $i++) { - $pwarray[17 + $i] = "\0"; - } - $pwarray[56] = "\x80"; - $pwarray[57] = "\x0a"; - - $md5->add($pwarray); - $valContext = $md5->getContext(); - - $key = $this->_makeKey(0, $valContext); - - $salt = $key->RC4($salt_data); - $hashedsalt = $key->RC4($hashedsalt_data); - - $salt .= "\x80" . str_repeat("\0", 47); - $salt[56] = "\x80"; - - $md5->reset(); - $md5->add($salt); - $mdContext2 = $md5->getContext(); - - return $mdContext2 == $hashedsalt; - } - - /** - * CODEPAGE - * - * This record stores the text encoding used to write byte - * strings, stored as MS Windows code page identifier. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readCodepage() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; code page identifier - $codepage = self::_GetInt2d($recordData, 0); - - $this->_codepage = PHPExcel_Shared_CodePage::NumberToName($codepage); - } - - - /** - * DATEMODE - * - * This record specifies the base date for displaying date - * values. All dates are stored as count of days past this - * base date. In BIFF2-BIFF4 this record is part of the - * Calculation Settings Block. In BIFF5-BIFF8 it is - * stored in the Workbook Globals Substream. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readDateMode() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; 0 = base 1900, 1 = base 1904 - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); - if (ord($recordData{0}) == 1) { - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); - } - } - - - /** - * Read a FONT record - */ - private function _readFont() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - $objFont = new PHPExcel_Style_Font(); - - // offset: 0; size: 2; height of the font (in twips = 1/20 of a point) - $size = self::_GetInt2d($recordData, 0); - $objFont->setSize($size / 20); - - // offset: 2; size: 2; option flags - // bit: 0; mask 0x0001; bold (redundant in BIFF5-BIFF8) - // bit: 1; mask 0x0002; italic - $isItalic = (0x0002 & self::_GetInt2d($recordData, 2)) >> 1; - if ($isItalic) $objFont->setItalic(true); - - // bit: 2; mask 0x0004; underlined (redundant in BIFF5-BIFF8) - // bit: 3; mask 0x0008; strike - $isStrike = (0x0008 & self::_GetInt2d($recordData, 2)) >> 3; - if ($isStrike) $objFont->setStrikethrough(true); - - // offset: 4; size: 2; colour index - $colorIndex = self::_GetInt2d($recordData, 4); - $objFont->colorIndex = $colorIndex; - - // offset: 6; size: 2; font weight - $weight = self::_GetInt2d($recordData, 6); - switch ($weight) { - case 0x02BC: - $objFont->setBold(true); - break; - } - - // offset: 8; size: 2; escapement type - $escapement = self::_GetInt2d($recordData, 8); - switch ($escapement) { - case 0x0001: - $objFont->setSuperScript(true); - break; - case 0x0002: - $objFont->setSubScript(true); - break; - } - - // offset: 10; size: 1; underline type - $underlineType = ord($recordData{10}); - switch ($underlineType) { - case 0x00: - break; // no underline - case 0x01: - $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); - break; - case 0x02: - $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); - break; - case 0x21: - $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING); - break; - case 0x22: - $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING); - break; - } - - // offset: 11; size: 1; font family - // offset: 12; size: 1; character set - // offset: 13; size: 1; not used - // offset: 14; size: var; font name - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringShort(substr($recordData, 14)); - } else { - $string = $this->_readByteStringShort(substr($recordData, 14)); - } - $objFont->setName($string['value']); - - $this->_objFonts[] = $objFont; - } - } - - - /** - * FORMAT - * - * This record contains information about a number format. - * All FORMAT records occur together in a sequential list. - * - * In BIFF2-BIFF4 other records referencing a FORMAT record - * contain a zero-based index into this list. From BIFF5 on - * the FORMAT record contains the index itself that will be - * used by other records. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readFormat() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - $indexCode = self::_GetInt2d($recordData, 0); - - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong(substr($recordData, 2)); - } else { - // BIFF7 - $string = $this->_readByteStringShort(substr($recordData, 2)); - } - - $formatString = $string['value']; - $this->_formats[$indexCode] = $formatString; - } - } - - - /** - * XF - Extended Format - * - * This record contains formatting information for cells, rows, columns or styles. - * According to http://support.microsoft.com/kb/147732 there are always at least 15 cell style XF - * and 1 cell XF. - * Inspection of Excel files generated by MS Office Excel shows that XF records 0-14 are cell style XF - * and XF record 15 is a cell XF - * We only read the first cell style XF and skip the remaining cell style XF records - * We read all cell XF records. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readXf() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - $objStyle = new PHPExcel_Style(); - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; Index to FONT record - if (self::_GetInt2d($recordData, 0) < 4) { - $fontIndex = self::_GetInt2d($recordData, 0); - } else { - // this has to do with that index 4 is omitted in all BIFF versions for some strange reason - // check the OpenOffice documentation of the FONT record - $fontIndex = self::_GetInt2d($recordData, 0) - 1; - } - $objStyle->setFont($this->_objFonts[$fontIndex]); - - // offset: 2; size: 2; Index to FORMAT record - $numberFormatIndex = self::_GetInt2d($recordData, 2); - if (isset($this->_formats[$numberFormatIndex])) { - // then we have user-defined format code - $numberformat = array('code' => $this->_formats[$numberFormatIndex]); - } elseif (($code = PHPExcel_Style_NumberFormat::builtInFormatCode($numberFormatIndex)) !== '') { - // then we have built-in format code - $numberformat = array('code' => $code); - } else { - // we set the general format code - $numberformat = array('code' => 'General'); - } - $objStyle->getNumberFormat()->setFormatCode($numberformat['code']); - - // offset: 4; size: 2; XF type, cell protection, and parent style XF - // bit 2-0; mask 0x0007; XF_TYPE_PROT - $xfTypeProt = self::_GetInt2d($recordData, 4); - // bit 0; mask 0x01; 1 = cell is locked - $isLocked = (0x01 & $xfTypeProt) >> 0; - $objStyle->getProtection()->setLocked($isLocked ? - PHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); - - // bit 1; mask 0x02; 1 = Formula is hidden - $isHidden = (0x02 & $xfTypeProt) >> 1; - $objStyle->getProtection()->setHidden($isHidden ? - PHPExcel_Style_Protection::PROTECTION_PROTECTED : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); - - // bit 2; mask 0x04; 0 = Cell XF, 1 = Cell Style XF - $isCellStyleXf = (0x04 & $xfTypeProt) >> 2; - - // offset: 6; size: 1; Alignment and text break - // bit 2-0, mask 0x07; horizontal alignment - $horAlign = (0x07 & ord($recordData{6})) >> 0; - switch ($horAlign) { - case 0: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_GENERAL); - break; - case 1: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT); - break; - case 2: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER); - break; - case 3: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); - break; - case 4: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_FILL); - break; - case 5: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY); - break; - case 6: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS); - break; - } - // bit 3, mask 0x08; wrap text - $wrapText = (0x08 & ord($recordData{6})) >> 3; - switch ($wrapText) { - case 0: - $objStyle->getAlignment()->setWrapText(false); - break; - case 1: - $objStyle->getAlignment()->setWrapText(true); - break; - } - // bit 6-4, mask 0x70; vertical alignment - $vertAlign = (0x70 & ord($recordData{6})) >> 4; - switch ($vertAlign) { - case 0: - $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP); - break; - case 1: - $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER); - break; - case 2: - $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_BOTTOM); - break; - case 3: - $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_JUSTIFY); - break; - } - - if ($this->_version == self::XLS_BIFF8) { - // offset: 7; size: 1; XF_ROTATION: Text rotation angle - $angle = ord($recordData{7}); - $rotation = 0; - if ($angle <= 90) { - $rotation = $angle; - } else if ($angle <= 180) { - $rotation = 90 - $angle; - } else if ($angle == 255) { - $rotation = -165; - } - $objStyle->getAlignment()->setTextRotation($rotation); - - // offset: 8; size: 1; Indentation, shrink to cell size, and text direction - // bit: 3-0; mask: 0x0F; indent level - $indent = (0x0F & ord($recordData{8})) >> 0; - $objStyle->getAlignment()->setIndent($indent); - - // bit: 4; mask: 0x10; 1 = shrink content to fit into cell - $shrinkToFit = (0x10 & ord($recordData{8})) >> 4; - switch ($shrinkToFit) { - case 0: - $objStyle->getAlignment()->setShrinkToFit(false); - break; - case 1: - $objStyle->getAlignment()->setShrinkToFit(true); - break; - } - - // offset: 9; size: 1; Flags used for attribute groups - - // offset: 10; size: 4; Cell border lines and background area - // bit: 3-0; mask: 0x0000000F; left style - if ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) { - $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle); - } - // bit: 7-4; mask: 0x000000F0; right style - if ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) { - $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle); - } - // bit: 11-8; mask: 0x00000F00; top style - if ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) { - $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle); - } - // bit: 15-12; mask: 0x0000F000; bottom style - if ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) { - $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle); - } - // bit: 22-16; mask: 0x007F0000; left color - $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16; - - // bit: 29-23; mask: 0x3F800000; right color - $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23; - - // bit: 30; mask: 0x40000000; 1 = diagonal line from top left to right bottom - $diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ? - true : false; - - // bit: 31; mask: 0x80000000; 1 = diagonal line from bottom left to top right - $diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ? - true : false; - - if ($diagonalUp == false && $diagonalDown == false) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); - } elseif ($diagonalUp == true && $diagonalDown == false) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); - } elseif ($diagonalUp == false && $diagonalDown == true) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); - } elseif ($diagonalUp == true && $diagonalDown == true) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); - } - - // offset: 14; size: 4; - // bit: 6-0; mask: 0x0000007F; top color - $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0; - - // bit: 13-7; mask: 0x00003F80; bottom color - $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7; - - // bit: 20-14; mask: 0x001FC000; diagonal color - $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14; - - // bit: 24-21; mask: 0x01E00000; diagonal style - if ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) { - $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle); - } - - // bit: 31-26; mask: 0xFC000000 fill pattern - if ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) { - $objStyle->getFill()->setFillType($fillType); - } - // offset: 18; size: 2; pattern and background colour - // bit: 6-0; mask: 0x007F; color index for pattern color - $objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0; - - // bit: 13-7; mask: 0x3F80; color index for pattern background - $objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7; - } else { - // BIFF5 - - // offset: 7; size: 1; Text orientation and flags - $orientationAndFlags = ord($recordData{7}); - - // bit: 1-0; mask: 0x03; XF_ORIENTATION: Text orientation - $xfOrientation = (0x03 & $orientationAndFlags) >> 0; - switch ($xfOrientation) { - case 0: - $objStyle->getAlignment()->setTextRotation(0); - break; - case 1: - $objStyle->getAlignment()->setTextRotation(-165); - break; - case 2: - $objStyle->getAlignment()->setTextRotation(90); - break; - case 3: - $objStyle->getAlignment()->setTextRotation(-90); - break; - } - - // offset: 8; size: 4; cell border lines and background area - $borderAndBackground = self::_GetInt4d($recordData, 8); - - // bit: 6-0; mask: 0x0000007F; color index for pattern color - $objStyle->getFill()->startcolorIndex = (0x0000007F & $borderAndBackground) >> 0; - - // bit: 13-7; mask: 0x00003F80; color index for pattern background - $objStyle->getFill()->endcolorIndex = (0x00003F80 & $borderAndBackground) >> 7; - - // bit: 21-16; mask: 0x003F0000; fill pattern - $objStyle->getFill()->setFillType(self::_mapFillPattern((0x003F0000 & $borderAndBackground) >> 16)); - - // bit: 24-22; mask: 0x01C00000; bottom line style - $objStyle->getBorders()->getBottom()->setBorderStyle(self::_mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22)); - - // bit: 31-25; mask: 0xFE000000; bottom line color - $objStyle->getBorders()->getBottom()->colorIndex = (0xFE000000 & $borderAndBackground) >> 25; - - // offset: 12; size: 4; cell border lines - $borderLines = self::_GetInt4d($recordData, 12); - - // bit: 2-0; mask: 0x00000007; top line style - $objStyle->getBorders()->getTop()->setBorderStyle(self::_mapBorderStyle((0x00000007 & $borderLines) >> 0)); - - // bit: 5-3; mask: 0x00000038; left line style - $objStyle->getBorders()->getLeft()->setBorderStyle(self::_mapBorderStyle((0x00000038 & $borderLines) >> 3)); - - // bit: 8-6; mask: 0x000001C0; right line style - $objStyle->getBorders()->getRight()->setBorderStyle(self::_mapBorderStyle((0x000001C0 & $borderLines) >> 6)); - - // bit: 15-9; mask: 0x0000FE00; top line color index - $objStyle->getBorders()->getTop()->colorIndex = (0x0000FE00 & $borderLines) >> 9; - - // bit: 22-16; mask: 0x007F0000; left line color index - $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & $borderLines) >> 16; - - // bit: 29-23; mask: 0x3F800000; right line color index - $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & $borderLines) >> 23; - } - - // add cellStyleXf or cellXf and update mapping - if ($isCellStyleXf) { - // we only read one style XF record which is always the first - if ($this->_xfIndex == 0) { - $this->_phpExcel->addCellStyleXf($objStyle); - $this->_mapCellStyleXfIndex[$this->_xfIndex] = 0; - } - } else { - // we read all cell XF records - $this->_phpExcel->addCellXf($objStyle); - $this->_mapCellXfIndex[$this->_xfIndex] = count($this->_phpExcel->getCellXfCollection()) - 1; - } - - // update XF index for when we read next record - ++$this->_xfIndex; - } - } - - - /** - * - */ - private function _readXfExt() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; 0x087D = repeated header - - // offset: 2; size: 2 - - // offset: 4; size: 8; not used - - // offset: 12; size: 2; record version - - // offset: 14; size: 2; index to XF record which this record modifies - $ixfe = self::_GetInt2d($recordData, 14); - - // offset: 16; size: 2; not used - - // offset: 18; size: 2; number of extension properties that follow - $cexts = self::_GetInt2d($recordData, 18); - - // start reading the actual extension data - $offset = 20; - while ($offset < $length) { - // extension type - $extType = self::_GetInt2d($recordData, $offset); - - // extension length - $cb = self::_GetInt2d($recordData, $offset + 2); - - // extension data - $extData = substr($recordData, $offset + 4, $cb); - - switch ($extType) { - case 4: // fill start color - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { - $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); - $fill->getStartColor()->setRGB($rgb); - unset($fill->startcolorIndex); // normal color index does not apply, discard - } - } - break; - - case 5: // fill end color - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { - $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); - $fill->getEndColor()->setRGB($rgb); - unset($fill->endcolorIndex); // normal color index does not apply, discard - } - } - break; - - case 7: // border color top - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { - $top = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getTop(); - $top->getColor()->setRGB($rgb); - unset($top->colorIndex); // normal color index does not apply, discard - } - } - break; - - case 8: // border color bottom - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { - $bottom = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getBottom(); - $bottom->getColor()->setRGB($rgb); - unset($bottom->colorIndex); // normal color index does not apply, discard - } - } - break; - - case 9: // border color left - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { - $left = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getLeft(); - $left->getColor()->setRGB($rgb); - unset($left->colorIndex); // normal color index does not apply, discard - } - } - break; - - case 10: // border color right - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { - $right = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getRight(); - $right->getColor()->setRGB($rgb); - unset($right->colorIndex); // normal color index does not apply, discard - } - } - break; - - case 11: // border color diagonal - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { - $diagonal = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getDiagonal(); - $diagonal->getColor()->setRGB($rgb); - unset($diagonal->colorIndex); // normal color index does not apply, discard - } - } - break; - - case 13: // font color - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { - $font = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFont(); - $font->getColor()->setRGB($rgb); - unset($font->colorIndex); // normal color index does not apply, discard - } - } - break; - } - - $offset += $cb; - } - } - - } - - - /** - * Read STYLE record - */ - private function _readStyle() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; index to XF record and flag for built-in style - $ixfe = self::_GetInt2d($recordData, 0); - - // bit: 11-0; mask 0x0FFF; index to XF record - $xfIndex = (0x0FFF & $ixfe) >> 0; - - // bit: 15; mask 0x8000; 0 = user-defined style, 1 = built-in style - $isBuiltIn = (bool) ((0x8000 & $ixfe) >> 15); - - if ($isBuiltIn) { - // offset: 2; size: 1; identifier for built-in style - $builtInId = ord($recordData{2}); - - switch ($builtInId) { - case 0x00: - // currently, we are not using this for anything - break; - - default: - break; - } - - } else { - // user-defined; not supported by PHPExcel - } - } - } - - - /** - * Read PALETTE record - */ - private function _readPalette() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; number of following colors - $nm = self::_GetInt2d($recordData, 0); - - // list of RGB colors - for ($i = 0; $i < $nm; ++$i) { - $rgb = substr($recordData, 2 + 4 * $i, 4); - $this->_palette[] = self::_readRGB($rgb); - } - } - } - - - /** - * SHEET - * - * This record is located in the Workbook Globals - * Substream and represents a sheet inside the workbook. - * One SHEET record is written for each sheet. It stores the - * sheet name and a stream offset to the BOF record of the - * respective Sheet Substream within the Workbook Stream. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readSheet() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // offset: 0; size: 4; absolute stream position of the BOF record of the sheet - // NOTE: not encrypted - $rec_offset = self::_GetInt4d($this->_data, $this->_pos + 4); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 4; size: 1; sheet state - switch (ord($recordData{4})) { - case 0x00: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; - case 0x01: $sheetState = PHPExcel_Worksheet::SHEETSTATE_HIDDEN; break; - case 0x02: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN; break; - default: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; - } - - // offset: 5; size: 1; sheet type - $sheetType = ord($recordData{5}); - - // offset: 6; size: var; sheet name - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringShort(substr($recordData, 6)); - $rec_name = $string['value']; - } elseif ($this->_version == self::XLS_BIFF7) { - $string = $this->_readByteStringShort(substr($recordData, 6)); - $rec_name = $string['value']; - } - - $this->_sheets[] = array( - 'name' => $rec_name, - 'offset' => $rec_offset, - 'sheetState' => $sheetState, - 'sheetType' => $sheetType, - ); - } - - - /** - * Read EXTERNALBOOK record - */ - private function _readExternalBook() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset within record data - $offset = 0; - - // there are 4 types of records - if (strlen($recordData) > 4) { - // external reference - // offset: 0; size: 2; number of sheet names ($nm) - $nm = self::_GetInt2d($recordData, 0); - $offset += 2; - - // offset: 2; size: var; encoded URL without sheet name (Unicode string, 16-bit length) - $encodedUrlString = self::_readUnicodeStringLong(substr($recordData, 2)); - $offset += $encodedUrlString['size']; - - // offset: var; size: var; list of $nm sheet names (Unicode strings, 16-bit length) - $externalSheetNames = array(); - for ($i = 0; $i < $nm; ++$i) { - $externalSheetNameString = self::_readUnicodeStringLong(substr($recordData, $offset)); - $externalSheetNames[] = $externalSheetNameString['value']; - $offset += $externalSheetNameString['size']; - } - - // store the record data - $this->_externalBooks[] = array( - 'type' => 'external', - 'encodedUrl' => $encodedUrlString['value'], - 'externalSheetNames' => $externalSheetNames, - ); - - } elseif (substr($recordData, 2, 2) == pack('CC', 0x01, 0x04)) { - // internal reference - // offset: 0; size: 2; number of sheet in this document - // offset: 2; size: 2; 0x01 0x04 - $this->_externalBooks[] = array( - 'type' => 'internal', - ); - } elseif (substr($recordData, 0, 4) == pack('vCC', 0x0001, 0x01, 0x3A)) { - // add-in function - // offset: 0; size: 2; 0x0001 - $this->_externalBooks[] = array( - 'type' => 'addInFunction', - ); - } elseif (substr($recordData, 0, 2) == pack('v', 0x0000)) { - // DDE links, OLE links - // offset: 0; size: 2; 0x0000 - // offset: 2; size: var; encoded source document name - $this->_externalBooks[] = array( - 'type' => 'DDEorOLE', - ); - } - } - - - /** - * Read EXTERNNAME record. - */ - private function _readExternName() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // external sheet references provided for named cells - if ($this->_version == self::XLS_BIFF8) { - // offset: 0; size: 2; options - $options = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; - - // offset: 4; size: 2; not used - - // offset: 6; size: var - $nameString = self::_readUnicodeStringShort(substr($recordData, 6)); - - // offset: var; size: var; formula data - $offset = 6 + $nameString['size']; - $formula = $this->_getFormulaFromStructure(substr($recordData, $offset)); - - $this->_externalNames[] = array( - 'name' => $nameString['value'], - 'formula' => $formula, - ); - } - } - - - /** - * Read EXTERNSHEET record - */ - private function _readExternSheet() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // external sheet references provided for named cells - if ($this->_version == self::XLS_BIFF8) { - // offset: 0; size: 2; number of following ref structures - $nm = self::_GetInt2d($recordData, 0); - for ($i = 0; $i < $nm; ++$i) { - $this->_ref[] = array( - // offset: 2 + 6 * $i; index to EXTERNALBOOK record - 'externalBookIndex' => self::_GetInt2d($recordData, 2 + 6 * $i), - // offset: 4 + 6 * $i; index to first sheet in EXTERNALBOOK record - 'firstSheetIndex' => self::_GetInt2d($recordData, 4 + 6 * $i), - // offset: 6 + 6 * $i; index to last sheet in EXTERNALBOOK record - 'lastSheetIndex' => self::_GetInt2d($recordData, 6 + 6 * $i), - ); - } - } - } - - - /** - * DEFINEDNAME - * - * This record is part of a Link Table. It contains the name - * and the token array of an internal defined name. Token - * arrays of defined names contain tokens with aberrant - * token classes. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readDefinedName() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8) { - // retrieves named cells - - // offset: 0; size: 2; option flags - $opts = self::_GetInt2d($recordData, 0); - - // bit: 5; mask: 0x0020; 0 = user-defined name, 1 = built-in-name - $isBuiltInName = (0x0020 & $opts) >> 5; - - // offset: 2; size: 1; keyboard shortcut - - // offset: 3; size: 1; length of the name (character count) - $nlen = ord($recordData{3}); - - // offset: 4; size: 2; size of the formula data (it can happen that this is zero) - // note: there can also be additional data, this is not included in $flen - $flen = self::_GetInt2d($recordData, 4); - - // offset: 8; size: 2; 0=Global name, otherwise index to sheet (1-based) - $scope = self::_GetInt2d($recordData, 8); - - // offset: 14; size: var; Name (Unicode string without length field) - $string = self::_readUnicodeString(substr($recordData, 14), $nlen); - - // offset: var; size: $flen; formula data - $offset = 14 + $string['size']; - $formulaStructure = pack('v', $flen) . substr($recordData, $offset); - - try { - $formula = $this->_getFormulaFromStructure($formulaStructure); - } catch (PHPExcel_Exception $e) { - $formula = ''; - } - - $this->_definedname[] = array( - 'isBuiltInName' => $isBuiltInName, - 'name' => $string['value'], - 'formula' => $formula, - 'scope' => $scope, - ); - } - } - - - /** - * Read MSODRAWINGGROUP record - */ - private function _readMsoDrawingGroup() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - - // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); - $recordData = $splicedRecordData['recordData']; - - $this->_drawingGroupData .= $recordData; - } - - - /** - * SST - Shared String Table - * - * This record contains a list of all strings used anywhere - * in the workbook. Each string occurs only once. The - * workbook uses indexes into the list to reference the - * strings. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - **/ - private function _readSst() - { - // offset within (spliced) record data - $pos = 0; - - // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); - - $recordData = $splicedRecordData['recordData']; - $spliceOffsets = $splicedRecordData['spliceOffsets']; - - // offset: 0; size: 4; total number of strings in the workbook - $pos += 4; - - // offset: 4; size: 4; number of following strings ($nm) - $nm = self::_GetInt4d($recordData, 4); - $pos += 4; - - // loop through the Unicode strings (16-bit length) - for ($i = 0; $i < $nm; ++$i) { - - // number of characters in the Unicode string - $numChars = self::_GetInt2d($recordData, $pos); - $pos += 2; - - // option flags - $optionFlags = ord($recordData{$pos}); - ++$pos; - - // bit: 0; mask: 0x01; 0 = compressed; 1 = uncompressed - $isCompressed = (($optionFlags & 0x01) == 0) ; - - // bit: 2; mask: 0x02; 0 = ordinary; 1 = Asian phonetic - $hasAsian = (($optionFlags & 0x04) != 0); - - // bit: 3; mask: 0x03; 0 = ordinary; 1 = Rich-Text - $hasRichText = (($optionFlags & 0x08) != 0); - - if ($hasRichText) { - // number of Rich-Text formatting runs - $formattingRuns = self::_GetInt2d($recordData, $pos); - $pos += 2; - } - - if ($hasAsian) { - // size of Asian phonetic setting - $extendedRunLength = self::_GetInt4d($recordData, $pos); - $pos += 4; - } - - // expected byte length of character array if not split - $len = ($isCompressed) ? $numChars : $numChars * 2; - - // look up limit position - foreach ($spliceOffsets as $spliceOffset) { - // it can happen that the string is empty, therefore we need - // <= and not just < - if ($pos <= $spliceOffset) { - $limitpos = $spliceOffset; - break; - } - } - - if ($pos + $len <= $limitpos) { - // character array is not split between records - - $retstr = substr($recordData, $pos, $len); - $pos += $len; - - } else { - // character array is split between records - - // first part of character array - $retstr = substr($recordData, $pos, $limitpos - $pos); - - $bytesRead = $limitpos - $pos; - - // remaining characters in Unicode string - $charsLeft = $numChars - (($isCompressed) ? $bytesRead : ($bytesRead / 2)); - - $pos = $limitpos; - - // keep reading the characters - while ($charsLeft > 0) { - - // look up next limit position, in case the string span more than one continue record - foreach ($spliceOffsets as $spliceOffset) { - if ($pos < $spliceOffset) { - $limitpos = $spliceOffset; - break; - } - } - - // repeated option flags - // OpenOffice.org documentation 5.21 - $option = ord($recordData{$pos}); - ++$pos; - - if ($isCompressed && ($option == 0)) { - // 1st fragment compressed - // this fragment compressed - $len = min($charsLeft, $limitpos - $pos); - $retstr .= substr($recordData, $pos, $len); - $charsLeft -= $len; - $isCompressed = true; - - } elseif (!$isCompressed && ($option != 0)) { - // 1st fragment uncompressed - // this fragment uncompressed - $len = min($charsLeft * 2, $limitpos - $pos); - $retstr .= substr($recordData, $pos, $len); - $charsLeft -= $len / 2; - $isCompressed = false; - - } elseif (!$isCompressed && ($option == 0)) { - // 1st fragment uncompressed - // this fragment compressed - $len = min($charsLeft, $limitpos - $pos); - for ($j = 0; $j < $len; ++$j) { - $retstr .= $recordData{$pos + $j} . chr(0); - } - $charsLeft -= $len; - $isCompressed = false; - - } else { - // 1st fragment compressed - // this fragment uncompressed - $newstr = ''; - for ($j = 0; $j < strlen($retstr); ++$j) { - $newstr .= $retstr[$j] . chr(0); - } - $retstr = $newstr; - $len = min($charsLeft * 2, $limitpos - $pos); - $retstr .= substr($recordData, $pos, $len); - $charsLeft -= $len / 2; - $isCompressed = false; - } - - $pos += $len; - } - } - - // convert to UTF-8 - $retstr = self::_encodeUTF16($retstr, $isCompressed); - - // read additional Rich-Text information, if any - $fmtRuns = array(); - if ($hasRichText) { - // list of formatting runs - for ($j = 0; $j < $formattingRuns; ++$j) { - // first formatted character; zero-based - $charPos = self::_GetInt2d($recordData, $pos + $j * 4); - - // index to font record - $fontIndex = self::_GetInt2d($recordData, $pos + 2 + $j * 4); - - $fmtRuns[] = array( - 'charPos' => $charPos, - 'fontIndex' => $fontIndex, - ); - } - $pos += 4 * $formattingRuns; - } - - // read additional Asian phonetics information, if any - if ($hasAsian) { - // For Asian phonetic settings, we skip the extended string data - $pos += $extendedRunLength; - } - - // store the shared sting - $this->_sst[] = array( - 'value' => $retstr, - 'fmtRuns' => $fmtRuns, - ); - } - - // _getSplicedRecordData() takes care of moving current position in data stream - } - - - /** - * Read PRINTGRIDLINES record - */ - private function _readPrintGridlines() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { - // offset: 0; size: 2; 0 = do not print sheet grid lines; 1 = print sheet gridlines - $printGridlines = (bool) self::_GetInt2d($recordData, 0); - $this->_phpSheet->setPrintGridlines($printGridlines); - } - } - - - /** - * Read DEFAULTROWHEIGHT record - */ - private function _readDefaultRowHeight() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; option flags - // offset: 2; size: 2; default height for unused rows, (twips 1/20 point) - $height = self::_GetInt2d($recordData, 2); - $this->_phpSheet->getDefaultRowDimension()->setRowHeight($height / 20); - } - - - /** - * Read SHEETPR record - */ - private function _readSheetPr() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2 - - // bit: 6; mask: 0x0040; 0 = outline buttons above outline group - $isSummaryBelow = (0x0040 & self::_GetInt2d($recordData, 0)) >> 6; - $this->_phpSheet->setShowSummaryBelow($isSummaryBelow); - - // bit: 7; mask: 0x0080; 0 = outline buttons left of outline group - $isSummaryRight = (0x0080 & self::_GetInt2d($recordData, 0)) >> 7; - $this->_phpSheet->setShowSummaryRight($isSummaryRight); - - // bit: 8; mask: 0x100; 0 = scale printout in percent, 1 = fit printout to number of pages - // this corresponds to radio button setting in page setup dialog in Excel - $this->_isFitToPages = (bool) ((0x0100 & self::_GetInt2d($recordData, 0)) >> 8); - } - - - /** - * Read HORIZONTALPAGEBREAKS record - */ - private function _readHorizontalPageBreaks() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { - - // offset: 0; size: 2; number of the following row index structures - $nm = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 6 * $nm; list of $nm row index structures - for ($i = 0; $i < $nm; ++$i) { - $r = self::_GetInt2d($recordData, 2 + 6 * $i); - $cf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); - $cl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); - - // not sure why two column indexes are necessary? - $this->_phpSheet->setBreakByColumnAndRow($cf, $r, PHPExcel_Worksheet::BREAK_ROW); - } - } - } - - - /** - * Read VERTICALPAGEBREAKS record - */ - private function _readVerticalPageBreaks() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { - // offset: 0; size: 2; number of the following column index structures - $nm = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 6 * $nm; list of $nm row index structures - for ($i = 0; $i < $nm; ++$i) { - $c = self::_GetInt2d($recordData, 2 + 6 * $i); - $rf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); - $rl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); - - // not sure why two row indexes are necessary? - $this->_phpSheet->setBreakByColumnAndRow($c, $rf, PHPExcel_Worksheet::BREAK_COLUMN); - } - } - } - - - /** - * Read HEADER record - */ - private function _readHeader() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: var - // realized that $recordData can be empty even when record exists - if ($recordData) { - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong($recordData); - } else { - $string = $this->_readByteStringShort($recordData); - } - - $this->_phpSheet->getHeaderFooter()->setOddHeader($string['value']); - $this->_phpSheet->getHeaderFooter()->setEvenHeader($string['value']); - } - } - } - - - /** - * Read FOOTER record - */ - private function _readFooter() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: var - // realized that $recordData can be empty even when record exists - if ($recordData) { - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong($recordData); - } else { - $string = $this->_readByteStringShort($recordData); - } - $this->_phpSheet->getHeaderFooter()->setOddFooter($string['value']); - $this->_phpSheet->getHeaderFooter()->setEvenFooter($string['value']); - } - } - } - - - /** - * Read HCENTER record - */ - private function _readHcenter() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; 0 = print sheet left aligned, 1 = print sheet centered horizontally - $isHorizontalCentered = (bool) self::_GetInt2d($recordData, 0); - - $this->_phpSheet->getPageSetup()->setHorizontalCentered($isHorizontalCentered); - } - } - - - /** - * Read VCENTER record - */ - private function _readVcenter() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; 0 = print sheet aligned at top page border, 1 = print sheet vertically centered - $isVerticalCentered = (bool) self::_GetInt2d($recordData, 0); - - $this->_phpSheet->getPageSetup()->setVerticalCentered($isVerticalCentered); - } - } - - - /** - * Read LEFTMARGIN record - */ - private function _readLeftMargin() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setLeft(self::_extractNumber($recordData)); - } - } - - - /** - * Read RIGHTMARGIN record - */ - private function _readRightMargin() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setRight(self::_extractNumber($recordData)); - } - } - - - /** - * Read TOPMARGIN record - */ - private function _readTopMargin() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setTop(self::_extractNumber($recordData)); - } - } - - - /** - * Read BOTTOMMARGIN record - */ - private function _readBottomMargin() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setBottom(self::_extractNumber($recordData)); - } - } - - - /** - * Read PAGESETUP record - */ - private function _readPageSetup() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; paper size - $paperSize = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; scaling factor - $scale = self::_GetInt2d($recordData, 2); - - // offset: 6; size: 2; fit worksheet width to this number of pages, 0 = use as many as needed - $fitToWidth = self::_GetInt2d($recordData, 6); - - // offset: 8; size: 2; fit worksheet height to this number of pages, 0 = use as many as needed - $fitToHeight = self::_GetInt2d($recordData, 8); - - // offset: 10; size: 2; option flags + $this->_cellNotes[$noteObjID] = array('cellRef' => $cellAddress, + 'objectID' => $noteObjID, + 'author' => $noteAuthor + ); + } else { + $extension = false; + if ($cellAddress == '$B$65536') { + // If the address row is -1 and the column is 0, (which translates as $B$65536) then this is a continuation + // note from the previous cell annotation. We're not yet handling this, so annotations longer than the + // max 2048 bytes will probably throw a wobbly. + $row = self::_GetInt2d($recordData, 0); + $extension = true; + $cellAddress = array_pop(array_keys($this->_phpSheet->getComments())); + } +// echo 'Note Address=',$cellAddress,'
'; + + $cellAddress = str_replace('$','',$cellAddress); + $noteLength = self::_GetInt2d($recordData, 4); + $noteText = trim(substr($recordData, 6)); +// echo 'Note Length=',$noteLength,'
'; +// echo 'Note Text=',$noteText,'
'; + + if ($extension) { + // Concatenate this extension with the currently set comment for the cell + $comment = $this->_phpSheet->getComment( $cellAddress ); + $commentText = $comment->getText()->getPlainText(); + $comment->setText($this->_parseRichText($commentText.$noteText) ); + } else { + // Set comment for the cell + $this->_phpSheet->getComment( $cellAddress ) +// ->setAuthor( $author ) + ->setText($this->_parseRichText($noteText) ); + } + } + + } + + + /** + * The TEXT Object record contains the text associated with a cell annotation. + */ + private function _readTextObject() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // recordData consists of an array of subrecords looking like this: + // grbit: 2 bytes; Option Flags + // rot: 2 bytes; rotation + // cchText: 2 bytes; length of the text (in the first continue record) + // cbRuns: 2 bytes; length of the formatting (in the second continue record) + // followed by the continuation records containing the actual text and formatting + $grbitOpts = self::_GetInt2d($recordData, 0); + $rot = self::_GetInt2d($recordData, 2); + $cchText = self::_GetInt2d($recordData, 10); + $cbRuns = self::_GetInt2d($recordData, 12); + $text = $this->_getSplicedRecordData(); + + $this->_textObjects[$this->textObjRef] = array( + 'text' => substr($text["recordData"],$text["spliceOffsets"][0]+1,$cchText), + 'format' => substr($text["recordData"],$text["spliceOffsets"][1],$cbRuns), + 'alignment' => $grbitOpts, + 'rotation' => $rot + ); + +// echo '_readTextObject()
'; +// var_dump($this->_textObjects[$this->textObjRef]); +// echo '
'; + } + + + /** + * Read BOF + */ + private function _readBof() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = substr($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 2; size: 2; type of the following data + $substreamType = self::_GetInt2d($recordData, 2); + + switch ($substreamType) { + case self::XLS_WorkbookGlobals: + $version = self::_GetInt2d($recordData, 0); + if (($version != self::XLS_BIFF8) && ($version != self::XLS_BIFF7)) { + throw new PHPExcel_Reader_Exception('Cannot read this Excel file. Version is too old.'); + } + $this->_version = $version; + break; + + case self::XLS_Worksheet: + // do not use this version information for anything + // it is unreliable (OpenOffice doc, 5.8), use only version information from the global stream + break; + + default: + // substream, e.g. chart + // just skip the entire substream + do { + $code = self::_GetInt2d($this->_data, $this->_pos); + $this->_readDefault(); + } while ($code != self::XLS_Type_EOF && $this->_pos < $this->_dataSize); + break; + } + } + + + /** + * FILEPASS + * + * This record is part of the File Protection Block. It + * contains information about the read/write password of the + * file. All record contents following this record will be + * encrypted. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + * + * The decryption functions and objects used from here on in + * are based on the source of Spreadsheet-ParseExcel: + * http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/ + */ + private function _readFilepass() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + if ($length != 54) { + throw new PHPExcel_Reader_Exception('Unexpected file pass record length'); + } + + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_verifyPassword( + 'VelvetSweatshop', + substr($recordData, 6, 16), + substr($recordData, 22, 16), + substr($recordData, 38, 16), + $this->_md5Ctxt + )) { + throw new PHPExcel_Reader_Exception('Decryption password incorrect'); + } + + $this->_encryption = self::MS_BIFF_CRYPTO_RC4; + + // Decryption required from the record after next onwards + $this->_encryptionStartPos = $this->_pos + self::_GetInt2d($this->_data, $this->_pos + 2); + } + + /** + * Make an RC4 decryptor for the given block + * + * @var int $block Block for which to create decrypto + * @var string $valContext MD5 context state + * + * @return PHPExcel_Reader_Excel5_RC4 + */ + private function _makeKey($block, $valContext) + { + $pwarray = str_repeat("\0", 64); + + for ($i = 0; $i < 5; $i++) { + $pwarray[$i] = $valContext[$i]; + } + + $pwarray[5] = chr($block & 0xff); + $pwarray[6] = chr(($block >> 8) & 0xff); + $pwarray[7] = chr(($block >> 16) & 0xff); + $pwarray[8] = chr(($block >> 24) & 0xff); + + $pwarray[9] = "\x80"; + $pwarray[56] = "\x48"; + + $md5 = new PHPExcel_Reader_Excel5_MD5(); + $md5->add($pwarray); + + $s = $md5->getContext(); + return new PHPExcel_Reader_Excel5_RC4($s); + } + + /** + * Verify RC4 file password + * + * @var string $password Password to check + * @var string $docid Document id + * @var string $salt_data Salt data + * @var string $hashedsalt_data Hashed salt data + * @var string &$valContext Set to the MD5 context of the value + * + * @return bool Success + */ + private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext) + { + $pwarray = str_repeat("\0", 64); + + for ($i = 0; $i < strlen($password); $i++) { + $o = ord(substr($password, $i, 1)); + $pwarray[2 * $i] = chr($o & 0xff); + $pwarray[2 * $i + 1] = chr(($o >> 8) & 0xff); + } + $pwarray[2 * $i] = chr(0x80); + $pwarray[56] = chr(($i << 4) & 0xff); + + $md5 = new PHPExcel_Reader_Excel5_MD5(); + $md5->add($pwarray); + + $mdContext1 = $md5->getContext(); + + $offset = 0; + $keyoffset = 0; + $tocopy = 5; + + $md5->reset(); + + while ($offset != 16) { + if ((64 - $offset) < 5) { + $tocopy = 64 - $offset; + } + + for ($i = 0; $i <= $tocopy; $i++) { + $pwarray[$offset + $i] = $mdContext1[$keyoffset + $i]; + } + + $offset += $tocopy; + + if ($offset == 64) { + $md5->add($pwarray); + $keyoffset = $tocopy; + $tocopy = 5 - $tocopy; + $offset = 0; + continue; + } + + $keyoffset = 0; + $tocopy = 5; + for ($i = 0; $i < 16; $i++) { + $pwarray[$offset + $i] = $docid[$i]; + } + $offset += 16; + } + + $pwarray[16] = "\x80"; + for ($i = 0; $i < 47; $i++) { + $pwarray[17 + $i] = "\0"; + } + $pwarray[56] = "\x80"; + $pwarray[57] = "\x0a"; + + $md5->add($pwarray); + $valContext = $md5->getContext(); + + $key = $this->_makeKey(0, $valContext); + + $salt = $key->RC4($salt_data); + $hashedsalt = $key->RC4($hashedsalt_data); + + $salt .= "\x80" . str_repeat("\0", 47); + $salt[56] = "\x80"; + + $md5->reset(); + $md5->add($salt); + $mdContext2 = $md5->getContext(); + + return $mdContext2 == $hashedsalt; + } + + /** + * CODEPAGE + * + * This record stores the text encoding used to write byte + * strings, stored as MS Windows code page identifier. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readCodepage() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; code page identifier + $codepage = self::_GetInt2d($recordData, 0); + + $this->_codepage = PHPExcel_Shared_CodePage::NumberToName($codepage); + } + + + /** + * DATEMODE + * + * This record specifies the base date for displaying date + * values. All dates are stored as count of days past this + * base date. In BIFF2-BIFF4 this record is part of the + * Calculation Settings Block. In BIFF5-BIFF8 it is + * stored in the Workbook Globals Substream. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readDateMode() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; 0 = base 1900, 1 = base 1904 + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + if (ord($recordData{0}) == 1) { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + } + } + + + /** + * Read a FONT record + */ + private function _readFont() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + $objFont = new PHPExcel_Style_Font(); + + // offset: 0; size: 2; height of the font (in twips = 1/20 of a point) + $size = self::_GetInt2d($recordData, 0); + $objFont->setSize($size / 20); + + // offset: 2; size: 2; option flags + // bit: 0; mask 0x0001; bold (redundant in BIFF5-BIFF8) + // bit: 1; mask 0x0002; italic + $isItalic = (0x0002 & self::_GetInt2d($recordData, 2)) >> 1; + if ($isItalic) $objFont->setItalic(true); + + // bit: 2; mask 0x0004; underlined (redundant in BIFF5-BIFF8) + // bit: 3; mask 0x0008; strike + $isStrike = (0x0008 & self::_GetInt2d($recordData, 2)) >> 3; + if ($isStrike) $objFont->setStrikethrough(true); + + // offset: 4; size: 2; colour index + $colorIndex = self::_GetInt2d($recordData, 4); + $objFont->colorIndex = $colorIndex; + + // offset: 6; size: 2; font weight + $weight = self::_GetInt2d($recordData, 6); + switch ($weight) { + case 0x02BC: + $objFont->setBold(true); + break; + } + + // offset: 8; size: 2; escapement type + $escapement = self::_GetInt2d($recordData, 8); + switch ($escapement) { + case 0x0001: + $objFont->setSuperScript(true); + break; + case 0x0002: + $objFont->setSubScript(true); + break; + } + + // offset: 10; size: 1; underline type + $underlineType = ord($recordData{10}); + switch ($underlineType) { + case 0x00: + break; // no underline + case 0x01: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + break; + case 0x02: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); + break; + case 0x21: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING); + break; + case 0x22: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING); + break; + } + + // offset: 11; size: 1; font family + // offset: 12; size: 1; character set + // offset: 13; size: 1; not used + // offset: 14; size: var; font name + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringShort(substr($recordData, 14)); + } else { + $string = $this->_readByteStringShort(substr($recordData, 14)); + } + $objFont->setName($string['value']); + + $this->_objFonts[] = $objFont; + } + } + + + /** + * FORMAT + * + * This record contains information about a number format. + * All FORMAT records occur together in a sequential list. + * + * In BIFF2-BIFF4 other records referencing a FORMAT record + * contain a zero-based index into this list. From BIFF5 on + * the FORMAT record contains the index itself that will be + * used by other records. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readFormat() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + $indexCode = self::_GetInt2d($recordData, 0); + + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong(substr($recordData, 2)); + } else { + // BIFF7 + $string = $this->_readByteStringShort(substr($recordData, 2)); + } + + $formatString = $string['value']; + $this->_formats[$indexCode] = $formatString; + } + } + + + /** + * XF - Extended Format + * + * This record contains formatting information for cells, rows, columns or styles. + * According to http://support.microsoft.com/kb/147732 there are always at least 15 cell style XF + * and 1 cell XF. + * Inspection of Excel files generated by MS Office Excel shows that XF records 0-14 are cell style XF + * and XF record 15 is a cell XF + * We only read the first cell style XF and skip the remaining cell style XF records + * We read all cell XF records. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readXf() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + $objStyle = new PHPExcel_Style(); + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; Index to FONT record + if (self::_GetInt2d($recordData, 0) < 4) { + $fontIndex = self::_GetInt2d($recordData, 0); + } else { + // this has to do with that index 4 is omitted in all BIFF versions for some strange reason + // check the OpenOffice documentation of the FONT record + $fontIndex = self::_GetInt2d($recordData, 0) - 1; + } + $objStyle->setFont($this->_objFonts[$fontIndex]); + + // offset: 2; size: 2; Index to FORMAT record + $numberFormatIndex = self::_GetInt2d($recordData, 2); + if (isset($this->_formats[$numberFormatIndex])) { + // then we have user-defined format code + $numberformat = array('code' => $this->_formats[$numberFormatIndex]); + } elseif (($code = PHPExcel_Style_NumberFormat::builtInFormatCode($numberFormatIndex)) !== '') { + // then we have built-in format code + $numberformat = array('code' => $code); + } else { + // we set the general format code + $numberformat = array('code' => 'General'); + } + $objStyle->getNumberFormat()->setFormatCode($numberformat['code']); + + // offset: 4; size: 2; XF type, cell protection, and parent style XF + // bit 2-0; mask 0x0007; XF_TYPE_PROT + $xfTypeProt = self::_GetInt2d($recordData, 4); + // bit 0; mask 0x01; 1 = cell is locked + $isLocked = (0x01 & $xfTypeProt) >> 0; + $objStyle->getProtection()->setLocked($isLocked ? + PHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + + // bit 1; mask 0x02; 1 = Formula is hidden + $isHidden = (0x02 & $xfTypeProt) >> 1; + $objStyle->getProtection()->setHidden($isHidden ? + PHPExcel_Style_Protection::PROTECTION_PROTECTED : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + + // bit 2; mask 0x04; 0 = Cell XF, 1 = Cell Style XF + $isCellStyleXf = (0x04 & $xfTypeProt) >> 2; + + // offset: 6; size: 1; Alignment and text break + // bit 2-0, mask 0x07; horizontal alignment + $horAlign = (0x07 & ord($recordData{6})) >> 0; + switch ($horAlign) { + case 0: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_GENERAL); + break; + case 1: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT); + break; + case 2: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER); + break; + case 3: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); + break; + case 4: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_FILL); + break; + case 5: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY); + break; + case 6: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS); + break; + } + // bit 3, mask 0x08; wrap text + $wrapText = (0x08 & ord($recordData{6})) >> 3; + switch ($wrapText) { + case 0: + $objStyle->getAlignment()->setWrapText(false); + break; + case 1: + $objStyle->getAlignment()->setWrapText(true); + break; + } + // bit 6-4, mask 0x70; vertical alignment + $vertAlign = (0x70 & ord($recordData{6})) >> 4; + switch ($vertAlign) { + case 0: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP); + break; + case 1: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER); + break; + case 2: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_BOTTOM); + break; + case 3: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_JUSTIFY); + break; + } + + if ($this->_version == self::XLS_BIFF8) { + // offset: 7; size: 1; XF_ROTATION: Text rotation angle + $angle = ord($recordData{7}); + $rotation = 0; + if ($angle <= 90) { + $rotation = $angle; + } else if ($angle <= 180) { + $rotation = 90 - $angle; + } else if ($angle == 255) { + $rotation = -165; + } + $objStyle->getAlignment()->setTextRotation($rotation); + + // offset: 8; size: 1; Indentation, shrink to cell size, and text direction + // bit: 3-0; mask: 0x0F; indent level + $indent = (0x0F & ord($recordData{8})) >> 0; + $objStyle->getAlignment()->setIndent($indent); + + // bit: 4; mask: 0x10; 1 = shrink content to fit into cell + $shrinkToFit = (0x10 & ord($recordData{8})) >> 4; + switch ($shrinkToFit) { + case 0: + $objStyle->getAlignment()->setShrinkToFit(false); + break; + case 1: + $objStyle->getAlignment()->setShrinkToFit(true); + break; + } + + // offset: 9; size: 1; Flags used for attribute groups + + // offset: 10; size: 4; Cell border lines and background area + // bit: 3-0; mask: 0x0000000F; left style + if ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) { + $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle); + } + // bit: 7-4; mask: 0x000000F0; right style + if ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) { + $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle); + } + // bit: 11-8; mask: 0x00000F00; top style + if ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) { + $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle); + } + // bit: 15-12; mask: 0x0000F000; bottom style + if ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) { + $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle); + } + // bit: 22-16; mask: 0x007F0000; left color + $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16; + + // bit: 29-23; mask: 0x3F800000; right color + $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23; + + // bit: 30; mask: 0x40000000; 1 = diagonal line from top left to right bottom + $diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ? + true : false; + + // bit: 31; mask: 0x80000000; 1 = diagonal line from bottom left to top right + $diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ? + true : false; + + if ($diagonalUp == false && $diagonalDown == false) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); + } elseif ($diagonalUp == true && $diagonalDown == false) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); + } elseif ($diagonalUp == false && $diagonalDown == true) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); + } elseif ($diagonalUp == true && $diagonalDown == true) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); + } + + // offset: 14; size: 4; + // bit: 6-0; mask: 0x0000007F; top color + $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0; + + // bit: 13-7; mask: 0x00003F80; bottom color + $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7; + + // bit: 20-14; mask: 0x001FC000; diagonal color + $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14; + + // bit: 24-21; mask: 0x01E00000; diagonal style + if ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) { + $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle); + } + + // bit: 31-26; mask: 0xFC000000 fill pattern + if ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) { + $objStyle->getFill()->setFillType($fillType); + } + // offset: 18; size: 2; pattern and background colour + // bit: 6-0; mask: 0x007F; color index for pattern color + $objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0; + + // bit: 13-7; mask: 0x3F80; color index for pattern background + $objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7; + } else { + // BIFF5 + + // offset: 7; size: 1; Text orientation and flags + $orientationAndFlags = ord($recordData{7}); + + // bit: 1-0; mask: 0x03; XF_ORIENTATION: Text orientation + $xfOrientation = (0x03 & $orientationAndFlags) >> 0; + switch ($xfOrientation) { + case 0: + $objStyle->getAlignment()->setTextRotation(0); + break; + case 1: + $objStyle->getAlignment()->setTextRotation(-165); + break; + case 2: + $objStyle->getAlignment()->setTextRotation(90); + break; + case 3: + $objStyle->getAlignment()->setTextRotation(-90); + break; + } + + // offset: 8; size: 4; cell border lines and background area + $borderAndBackground = self::_GetInt4d($recordData, 8); + + // bit: 6-0; mask: 0x0000007F; color index for pattern color + $objStyle->getFill()->startcolorIndex = (0x0000007F & $borderAndBackground) >> 0; + + // bit: 13-7; mask: 0x00003F80; color index for pattern background + $objStyle->getFill()->endcolorIndex = (0x00003F80 & $borderAndBackground) >> 7; + + // bit: 21-16; mask: 0x003F0000; fill pattern + $objStyle->getFill()->setFillType(self::_mapFillPattern((0x003F0000 & $borderAndBackground) >> 16)); + + // bit: 24-22; mask: 0x01C00000; bottom line style + $objStyle->getBorders()->getBottom()->setBorderStyle(self::_mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22)); + + // bit: 31-25; mask: 0xFE000000; bottom line color + $objStyle->getBorders()->getBottom()->colorIndex = (0xFE000000 & $borderAndBackground) >> 25; + + // offset: 12; size: 4; cell border lines + $borderLines = self::_GetInt4d($recordData, 12); + + // bit: 2-0; mask: 0x00000007; top line style + $objStyle->getBorders()->getTop()->setBorderStyle(self::_mapBorderStyle((0x00000007 & $borderLines) >> 0)); + + // bit: 5-3; mask: 0x00000038; left line style + $objStyle->getBorders()->getLeft()->setBorderStyle(self::_mapBorderStyle((0x00000038 & $borderLines) >> 3)); + + // bit: 8-6; mask: 0x000001C0; right line style + $objStyle->getBorders()->getRight()->setBorderStyle(self::_mapBorderStyle((0x000001C0 & $borderLines) >> 6)); + + // bit: 15-9; mask: 0x0000FE00; top line color index + $objStyle->getBorders()->getTop()->colorIndex = (0x0000FE00 & $borderLines) >> 9; + + // bit: 22-16; mask: 0x007F0000; left line color index + $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & $borderLines) >> 16; + + // bit: 29-23; mask: 0x3F800000; right line color index + $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & $borderLines) >> 23; + } + + // add cellStyleXf or cellXf and update mapping + if ($isCellStyleXf) { + // we only read one style XF record which is always the first + if ($this->_xfIndex == 0) { + $this->_phpExcel->addCellStyleXf($objStyle); + $this->_mapCellStyleXfIndex[$this->_xfIndex] = 0; + } + } else { + // we read all cell XF records + $this->_phpExcel->addCellXf($objStyle); + $this->_mapCellXfIndex[$this->_xfIndex] = count($this->_phpExcel->getCellXfCollection()) - 1; + } + + // update XF index for when we read next record + ++$this->_xfIndex; + } + } + + + /** + * + */ + private function _readXfExt() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0x087D = repeated header + + // offset: 2; size: 2 + + // offset: 4; size: 8; not used + + // offset: 12; size: 2; record version + + // offset: 14; size: 2; index to XF record which this record modifies + $ixfe = self::_GetInt2d($recordData, 14); + + // offset: 16; size: 2; not used + + // offset: 18; size: 2; number of extension properties that follow + $cexts = self::_GetInt2d($recordData, 18); + + // start reading the actual extension data + $offset = 20; + while ($offset < $length) { + // extension type + $extType = self::_GetInt2d($recordData, $offset); + + // extension length + $cb = self::_GetInt2d($recordData, $offset + 2); + + // extension data + $extData = substr($recordData, $offset + 4, $cb); + + switch ($extType) { + case 4: // fill start color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); + $fill->getStartColor()->setRGB($rgb); + unset($fill->startcolorIndex); // normal color index does not apply, discard + } + } + break; + + case 5: // fill end color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); + $fill->getEndColor()->setRGB($rgb); + unset($fill->endcolorIndex); // normal color index does not apply, discard + } + } + break; + + case 7: // border color top + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $top = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getTop(); + $top->getColor()->setRGB($rgb); + unset($top->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 8: // border color bottom + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $bottom = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getBottom(); + $bottom->getColor()->setRGB($rgb); + unset($bottom->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 9: // border color left + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $left = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getLeft(); + $left->getColor()->setRGB($rgb); + unset($left->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 10: // border color right + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $right = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getRight(); + $right->getColor()->setRGB($rgb); + unset($right->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 11: // border color diagonal + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $diagonal = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getDiagonal(); + $diagonal->getColor()->setRGB($rgb); + unset($diagonal->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 13: // font color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $font = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFont(); + $font->getColor()->setRGB($rgb); + unset($font->colorIndex); // normal color index does not apply, discard + } + } + break; + } + + $offset += $cb; + } + } + + } + + + /** + * Read STYLE record + */ + private function _readStyle() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index to XF record and flag for built-in style + $ixfe = self::_GetInt2d($recordData, 0); + + // bit: 11-0; mask 0x0FFF; index to XF record + $xfIndex = (0x0FFF & $ixfe) >> 0; + + // bit: 15; mask 0x8000; 0 = user-defined style, 1 = built-in style + $isBuiltIn = (bool) ((0x8000 & $ixfe) >> 15); + + if ($isBuiltIn) { + // offset: 2; size: 1; identifier for built-in style + $builtInId = ord($recordData{2}); + + switch ($builtInId) { + case 0x00: + // currently, we are not using this for anything + break; + + default: + break; + } + + } else { + // user-defined; not supported by PHPExcel + } + } + } + + + /** + * Read PALETTE record + */ + private function _readPalette() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; number of following colors + $nm = self::_GetInt2d($recordData, 0); + + // list of RGB colors + for ($i = 0; $i < $nm; ++$i) { + $rgb = substr($recordData, 2 + 4 * $i, 4); + $this->_palette[] = self::_readRGB($rgb); + } + } + } + + + /** + * SHEET + * + * This record is located in the Workbook Globals + * Substream and represents a sheet inside the workbook. + * One SHEET record is written for each sheet. It stores the + * sheet name and a stream offset to the BOF record of the + * respective Sheet Substream within the Workbook Stream. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readSheet() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // offset: 0; size: 4; absolute stream position of the BOF record of the sheet + // NOTE: not encrypted + $rec_offset = self::_GetInt4d($this->_data, $this->_pos + 4); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 4; size: 1; sheet state + switch (ord($recordData{4})) { + case 0x00: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; + case 0x01: $sheetState = PHPExcel_Worksheet::SHEETSTATE_HIDDEN; break; + case 0x02: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN; break; + default: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; + } + + // offset: 5; size: 1; sheet type + $sheetType = ord($recordData{5}); + + // offset: 6; size: var; sheet name + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringShort(substr($recordData, 6)); + $rec_name = $string['value']; + } elseif ($this->_version == self::XLS_BIFF7) { + $string = $this->_readByteStringShort(substr($recordData, 6)); + $rec_name = $string['value']; + } + + $this->_sheets[] = array( + 'name' => $rec_name, + 'offset' => $rec_offset, + 'sheetState' => $sheetState, + 'sheetType' => $sheetType, + ); + } + + + /** + * Read EXTERNALBOOK record + */ + private function _readExternalBook() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset within record data + $offset = 0; + + // there are 4 types of records + if (strlen($recordData) > 4) { + // external reference + // offset: 0; size: 2; number of sheet names ($nm) + $nm = self::_GetInt2d($recordData, 0); + $offset += 2; + + // offset: 2; size: var; encoded URL without sheet name (Unicode string, 16-bit length) + $encodedUrlString = self::_readUnicodeStringLong(substr($recordData, 2)); + $offset += $encodedUrlString['size']; + + // offset: var; size: var; list of $nm sheet names (Unicode strings, 16-bit length) + $externalSheetNames = array(); + for ($i = 0; $i < $nm; ++$i) { + $externalSheetNameString = self::_readUnicodeStringLong(substr($recordData, $offset)); + $externalSheetNames[] = $externalSheetNameString['value']; + $offset += $externalSheetNameString['size']; + } + + // store the record data + $this->_externalBooks[] = array( + 'type' => 'external', + 'encodedUrl' => $encodedUrlString['value'], + 'externalSheetNames' => $externalSheetNames, + ); + + } elseif (substr($recordData, 2, 2) == pack('CC', 0x01, 0x04)) { + // internal reference + // offset: 0; size: 2; number of sheet in this document + // offset: 2; size: 2; 0x01 0x04 + $this->_externalBooks[] = array( + 'type' => 'internal', + ); + } elseif (substr($recordData, 0, 4) == pack('vCC', 0x0001, 0x01, 0x3A)) { + // add-in function + // offset: 0; size: 2; 0x0001 + $this->_externalBooks[] = array( + 'type' => 'addInFunction', + ); + } elseif (substr($recordData, 0, 2) == pack('v', 0x0000)) { + // DDE links, OLE links + // offset: 0; size: 2; 0x0000 + // offset: 2; size: var; encoded source document name + $this->_externalBooks[] = array( + 'type' => 'DDEorOLE', + ); + } + } + + + /** + * Read EXTERNNAME record. + */ + private function _readExternName() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // external sheet references provided for named cells + if ($this->_version == self::XLS_BIFF8) { + // offset: 0; size: 2; options + $options = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; + + // offset: 4; size: 2; not used + + // offset: 6; size: var + $nameString = self::_readUnicodeStringShort(substr($recordData, 6)); + + // offset: var; size: var; formula data + $offset = 6 + $nameString['size']; + $formula = $this->_getFormulaFromStructure(substr($recordData, $offset)); + + $this->_externalNames[] = array( + 'name' => $nameString['value'], + 'formula' => $formula, + ); + } + } + + + /** + * Read EXTERNSHEET record + */ + private function _readExternSheet() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // external sheet references provided for named cells + if ($this->_version == self::XLS_BIFF8) { + // offset: 0; size: 2; number of following ref structures + $nm = self::_GetInt2d($recordData, 0); + for ($i = 0; $i < $nm; ++$i) { + $this->_ref[] = array( + // offset: 2 + 6 * $i; index to EXTERNALBOOK record + 'externalBookIndex' => self::_GetInt2d($recordData, 2 + 6 * $i), + // offset: 4 + 6 * $i; index to first sheet in EXTERNALBOOK record + 'firstSheetIndex' => self::_GetInt2d($recordData, 4 + 6 * $i), + // offset: 6 + 6 * $i; index to last sheet in EXTERNALBOOK record + 'lastSheetIndex' => self::_GetInt2d($recordData, 6 + 6 * $i), + ); + } + } + } + + + /** + * DEFINEDNAME + * + * This record is part of a Link Table. It contains the name + * and the token array of an internal defined name. Token + * arrays of defined names contain tokens with aberrant + * token classes. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readDefinedName() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8) { + // retrieves named cells + + // offset: 0; size: 2; option flags + $opts = self::_GetInt2d($recordData, 0); + + // bit: 5; mask: 0x0020; 0 = user-defined name, 1 = built-in-name + $isBuiltInName = (0x0020 & $opts) >> 5; + + // offset: 2; size: 1; keyboard shortcut + + // offset: 3; size: 1; length of the name (character count) + $nlen = ord($recordData{3}); + + // offset: 4; size: 2; size of the formula data (it can happen that this is zero) + // note: there can also be additional data, this is not included in $flen + $flen = self::_GetInt2d($recordData, 4); + + // offset: 8; size: 2; 0=Global name, otherwise index to sheet (1-based) + $scope = self::_GetInt2d($recordData, 8); + + // offset: 14; size: var; Name (Unicode string without length field) + $string = self::_readUnicodeString(substr($recordData, 14), $nlen); + + // offset: var; size: $flen; formula data + $offset = 14 + $string['size']; + $formulaStructure = pack('v', $flen) . substr($recordData, $offset); + + try { + $formula = $this->_getFormulaFromStructure($formulaStructure); + } catch (PHPExcel_Exception $e) { + $formula = ''; + } + + $this->_definedname[] = array( + 'isBuiltInName' => $isBuiltInName, + 'name' => $string['value'], + 'formula' => $formula, + 'scope' => $scope, + ); + } + } + + + /** + * Read MSODRAWINGGROUP record + */ + private function _readMsoDrawingGroup() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + $this->_drawingGroupData .= $recordData; + } + + + /** + * SST - Shared String Table + * + * This record contains a list of all strings used anywhere + * in the workbook. Each string occurs only once. The + * workbook uses indexes into the list to reference the + * strings. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + **/ + private function _readSst() + { + // offset within (spliced) record data + $pos = 0; + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + + $recordData = $splicedRecordData['recordData']; + $spliceOffsets = $splicedRecordData['spliceOffsets']; + + // offset: 0; size: 4; total number of strings in the workbook + $pos += 4; + + // offset: 4; size: 4; number of following strings ($nm) + $nm = self::_GetInt4d($recordData, 4); + $pos += 4; + + // loop through the Unicode strings (16-bit length) + for ($i = 0; $i < $nm; ++$i) { + + // number of characters in the Unicode string + $numChars = self::_GetInt2d($recordData, $pos); + $pos += 2; + + // option flags + $optionFlags = ord($recordData{$pos}); + ++$pos; + + // bit: 0; mask: 0x01; 0 = compressed; 1 = uncompressed + $isCompressed = (($optionFlags & 0x01) == 0) ; + + // bit: 2; mask: 0x02; 0 = ordinary; 1 = Asian phonetic + $hasAsian = (($optionFlags & 0x04) != 0); + + // bit: 3; mask: 0x03; 0 = ordinary; 1 = Rich-Text + $hasRichText = (($optionFlags & 0x08) != 0); + + if ($hasRichText) { + // number of Rich-Text formatting runs + $formattingRuns = self::_GetInt2d($recordData, $pos); + $pos += 2; + } + + if ($hasAsian) { + // size of Asian phonetic setting + $extendedRunLength = self::_GetInt4d($recordData, $pos); + $pos += 4; + } + + // expected byte length of character array if not split + $len = ($isCompressed) ? $numChars : $numChars * 2; + + // look up limit position + foreach ($spliceOffsets as $spliceOffset) { + // it can happen that the string is empty, therefore we need + // <= and not just < + if ($pos <= $spliceOffset) { + $limitpos = $spliceOffset; + break; + } + } + + if ($pos + $len <= $limitpos) { + // character array is not split between records + + $retstr = substr($recordData, $pos, $len); + $pos += $len; + + } else { + // character array is split between records + + // first part of character array + $retstr = substr($recordData, $pos, $limitpos - $pos); + + $bytesRead = $limitpos - $pos; + + // remaining characters in Unicode string + $charsLeft = $numChars - (($isCompressed) ? $bytesRead : ($bytesRead / 2)); + + $pos = $limitpos; + + // keep reading the characters + while ($charsLeft > 0) { + + // look up next limit position, in case the string span more than one continue record + foreach ($spliceOffsets as $spliceOffset) { + if ($pos < $spliceOffset) { + $limitpos = $spliceOffset; + break; + } + } + + // repeated option flags + // OpenOffice.org documentation 5.21 + $option = ord($recordData{$pos}); + ++$pos; + + if ($isCompressed && ($option == 0)) { + // 1st fragment compressed + // this fragment compressed + $len = min($charsLeft, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len; + $isCompressed = true; + + } elseif (!$isCompressed && ($option != 0)) { + // 1st fragment uncompressed + // this fragment uncompressed + $len = min($charsLeft * 2, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len / 2; + $isCompressed = false; + + } elseif (!$isCompressed && ($option == 0)) { + // 1st fragment uncompressed + // this fragment compressed + $len = min($charsLeft, $limitpos - $pos); + for ($j = 0; $j < $len; ++$j) { + $retstr .= $recordData{$pos + $j} . chr(0); + } + $charsLeft -= $len; + $isCompressed = false; + + } else { + // 1st fragment compressed + // this fragment uncompressed + $newstr = ''; + for ($j = 0; $j < strlen($retstr); ++$j) { + $newstr .= $retstr[$j] . chr(0); + } + $retstr = $newstr; + $len = min($charsLeft * 2, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len / 2; + $isCompressed = false; + } + + $pos += $len; + } + } + + // convert to UTF-8 + $retstr = self::_encodeUTF16($retstr, $isCompressed); + + // read additional Rich-Text information, if any + $fmtRuns = array(); + if ($hasRichText) { + // list of formatting runs + for ($j = 0; $j < $formattingRuns; ++$j) { + // first formatted character; zero-based + $charPos = self::_GetInt2d($recordData, $pos + $j * 4); + + // index to font record + $fontIndex = self::_GetInt2d($recordData, $pos + 2 + $j * 4); + + $fmtRuns[] = array( + 'charPos' => $charPos, + 'fontIndex' => $fontIndex, + ); + } + $pos += 4 * $formattingRuns; + } + + // read additional Asian phonetics information, if any + if ($hasAsian) { + // For Asian phonetic settings, we skip the extended string data + $pos += $extendedRunLength; + } + + // store the shared sting + $this->_sst[] = array( + 'value' => $retstr, + 'fmtRuns' => $fmtRuns, + ); + } + + // _getSplicedRecordData() takes care of moving current position in data stream + } + + + /** + * Read PRINTGRIDLINES record + */ + private function _readPrintGridlines() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + // offset: 0; size: 2; 0 = do not print sheet grid lines; 1 = print sheet gridlines + $printGridlines = (bool) self::_GetInt2d($recordData, 0); + $this->_phpSheet->setPrintGridlines($printGridlines); + } + } + + + /** + * Read DEFAULTROWHEIGHT record + */ + private function _readDefaultRowHeight() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; option flags + // offset: 2; size: 2; default height for unused rows, (twips 1/20 point) + $height = self::_GetInt2d($recordData, 2); + $this->_phpSheet->getDefaultRowDimension()->setRowHeight($height / 20); + } + + + /** + * Read SHEETPR record + */ + private function _readSheetPr() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2 + + // bit: 6; mask: 0x0040; 0 = outline buttons above outline group + $isSummaryBelow = (0x0040 & self::_GetInt2d($recordData, 0)) >> 6; + $this->_phpSheet->setShowSummaryBelow($isSummaryBelow); + + // bit: 7; mask: 0x0080; 0 = outline buttons left of outline group + $isSummaryRight = (0x0080 & self::_GetInt2d($recordData, 0)) >> 7; + $this->_phpSheet->setShowSummaryRight($isSummaryRight); + + // bit: 8; mask: 0x100; 0 = scale printout in percent, 1 = fit printout to number of pages + // this corresponds to radio button setting in page setup dialog in Excel + $this->_isFitToPages = (bool) ((0x0100 & self::_GetInt2d($recordData, 0)) >> 8); + } + + + /** + * Read HORIZONTALPAGEBREAKS record + */ + private function _readHorizontalPageBreaks() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + + // offset: 0; size: 2; number of the following row index structures + $nm = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 6 * $nm; list of $nm row index structures + for ($i = 0; $i < $nm; ++$i) { + $r = self::_GetInt2d($recordData, 2 + 6 * $i); + $cf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); + $cl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); + + // not sure why two column indexes are necessary? + $this->_phpSheet->setBreakByColumnAndRow($cf, $r, PHPExcel_Worksheet::BREAK_ROW); + } + } + } + + + /** + * Read VERTICALPAGEBREAKS record + */ + private function _readVerticalPageBreaks() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + // offset: 0; size: 2; number of the following column index structures + $nm = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 6 * $nm; list of $nm row index structures + for ($i = 0; $i < $nm; ++$i) { + $c = self::_GetInt2d($recordData, 2 + 6 * $i); + $rf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); + $rl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); + + // not sure why two row indexes are necessary? + $this->_phpSheet->setBreakByColumnAndRow($c, $rf, PHPExcel_Worksheet::BREAK_COLUMN); + } + } + } + + + /** + * Read HEADER record + */ + private function _readHeader() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: var + // realized that $recordData can be empty even when record exists + if ($recordData) { + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + } else { + $string = $this->_readByteStringShort($recordData); + } + + $this->_phpSheet->getHeaderFooter()->setOddHeader($string['value']); + $this->_phpSheet->getHeaderFooter()->setEvenHeader($string['value']); + } + } + } + + + /** + * Read FOOTER record + */ + private function _readFooter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: var + // realized that $recordData can be empty even when record exists + if ($recordData) { + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + } else { + $string = $this->_readByteStringShort($recordData); + } + $this->_phpSheet->getHeaderFooter()->setOddFooter($string['value']); + $this->_phpSheet->getHeaderFooter()->setEvenFooter($string['value']); + } + } + } + + + /** + * Read HCENTER record + */ + private function _readHcenter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0 = print sheet left aligned, 1 = print sheet centered horizontally + $isHorizontalCentered = (bool) self::_GetInt2d($recordData, 0); + + $this->_phpSheet->getPageSetup()->setHorizontalCentered($isHorizontalCentered); + } + } + + + /** + * Read VCENTER record + */ + private function _readVcenter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0 = print sheet aligned at top page border, 1 = print sheet vertically centered + $isVerticalCentered = (bool) self::_GetInt2d($recordData, 0); + + $this->_phpSheet->getPageSetup()->setVerticalCentered($isVerticalCentered); + } + } + + + /** + * Read LEFTMARGIN record + */ + private function _readLeftMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setLeft(self::_extractNumber($recordData)); + } + } + + + /** + * Read RIGHTMARGIN record + */ + private function _readRightMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setRight(self::_extractNumber($recordData)); + } + } + + + /** + * Read TOPMARGIN record + */ + private function _readTopMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setTop(self::_extractNumber($recordData)); + } + } + + + /** + * Read BOTTOMMARGIN record + */ + private function _readBottomMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setBottom(self::_extractNumber($recordData)); + } + } + + + /** + * Read PAGESETUP record + */ + private function _readPageSetup() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; paper size + $paperSize = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; scaling factor + $scale = self::_GetInt2d($recordData, 2); + + // offset: 6; size: 2; fit worksheet width to this number of pages, 0 = use as many as needed + $fitToWidth = self::_GetInt2d($recordData, 6); + + // offset: 8; size: 2; fit worksheet height to this number of pages, 0 = use as many as needed + $fitToHeight = self::_GetInt2d($recordData, 8); + + // offset: 10; size: 2; option flags - // bit: 1; mask: 0x0002; 0=landscape, 1=portrait - $isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1; + // bit: 1; mask: 0x0002; 0=landscape, 1=portrait + $isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1; - // bit: 2; mask: 0x0004; 1= paper size, scaling factor, paper orient. not init - // when this bit is set, do not use flags for those properties - $isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2; + // bit: 2; mask: 0x0004; 1= paper size, scaling factor, paper orient. not init + // when this bit is set, do not use flags for those properties + $isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2; - if (!$isNotInit) { - $this->_phpSheet->getPageSetup()->setPaperSize($paperSize); - switch ($isPortrait) { - case 0: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); break; - case 1: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); break; - } + if (!$isNotInit) { + $this->_phpSheet->getPageSetup()->setPaperSize($paperSize); + switch ($isPortrait) { + case 0: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); break; + case 1: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); break; + } - $this->_phpSheet->getPageSetup()->setScale($scale, false); - $this->_phpSheet->getPageSetup()->setFitToPage((bool) $this->_isFitToPages); - $this->_phpSheet->getPageSetup()->setFitToWidth($fitToWidth, false); - $this->_phpSheet->getPageSetup()->setFitToHeight($fitToHeight, false); - } - - // offset: 16; size: 8; header margin (IEEE 754 floating-point value) - $marginHeader = self::_extractNumber(substr($recordData, 16, 8)); - $this->_phpSheet->getPageMargins()->setHeader($marginHeader); + $this->_phpSheet->getPageSetup()->setScale($scale, false); + $this->_phpSheet->getPageSetup()->setFitToPage((bool) $this->_isFitToPages); + $this->_phpSheet->getPageSetup()->setFitToWidth($fitToWidth, false); + $this->_phpSheet->getPageSetup()->setFitToHeight($fitToHeight, false); + } + + // offset: 16; size: 8; header margin (IEEE 754 floating-point value) + $marginHeader = self::_extractNumber(substr($recordData, 16, 8)); + $this->_phpSheet->getPageMargins()->setHeader($marginHeader); - // offset: 24; size: 8; footer margin (IEEE 754 floating-point value) - $marginFooter = self::_extractNumber(substr($recordData, 24, 8)); - $this->_phpSheet->getPageMargins()->setFooter($marginFooter); - } - } + // offset: 24; size: 8; footer margin (IEEE 754 floating-point value) + $marginFooter = self::_extractNumber(substr($recordData, 24, 8)); + $this->_phpSheet->getPageMargins()->setFooter($marginFooter); + } + } - /** - * PROTECT - Sheet protection (BIFF2 through BIFF8) - * if this record is omitted, then it also means no sheet protection - */ - private function _readProtect() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; + /** + * PROTECT - Sheet protection (BIFF2 through BIFF8) + * if this record is omitted, then it also means no sheet protection + */ + private function _readProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; - if ($this->_readDataOnly) { - return; - } - - // offset: 0; size: 2; + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; - // bit 0, mask 0x01; 1 = sheet is protected - $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; - $this->_phpSheet->getProtection()->setSheet((bool)$bool); - } + // bit 0, mask 0x01; 1 = sheet is protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + $this->_phpSheet->getProtection()->setSheet((bool)$bool); + } - /** - * SCENPROTECT - */ - private function _readScenProtect() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + /** + * SCENPROTECT + */ + private function _readScenProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - // move stream pointer to next record - $this->_pos += 4 + $length; + // move stream pointer to next record + $this->_pos += 4 + $length; - if ($this->_readDataOnly) { - return; - } + if ($this->_readDataOnly) { + return; + } - // offset: 0; size: 2; + // offset: 0; size: 2; - // bit: 0, mask 0x01; 1 = scenarios are protected - $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + // bit: 0, mask 0x01; 1 = scenarios are protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; - $this->_phpSheet->getProtection()->setScenarios((bool)$bool); - } + $this->_phpSheet->getProtection()->setScenarios((bool)$bool); + } - /** - * OBJECTPROTECT - */ - private function _readObjectProtect() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + /** + * OBJECTPROTECT + */ + private function _readObjectProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - // move stream pointer to next record - $this->_pos += 4 + $length; + // move stream pointer to next record + $this->_pos += 4 + $length; - if ($this->_readDataOnly) { - return; - } + if ($this->_readDataOnly) { + return; + } - // offset: 0; size: 2; + // offset: 0; size: 2; - // bit: 0, mask 0x01; 1 = objects are protected - $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; - - $this->_phpSheet->getProtection()->setObjects((bool)$bool); - } - - - /** - * PASSWORD - Sheet protection (hashed) password (BIFF2 through BIFF8) - */ - private function _readPassword() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; 16-bit hash value of password - $password = strtoupper(dechex(self::_GetInt2d($recordData, 0))); // the hashed password - $this->_phpSheet->getProtection()->setPassword($password, true); - } - } + // bit: 0, mask 0x01; 1 = objects are protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + + $this->_phpSheet->getProtection()->setObjects((bool)$bool); + } + + + /** + * PASSWORD - Sheet protection (hashed) password (BIFF2 through BIFF8) + */ + private function _readPassword() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 16-bit hash value of password + $password = strtoupper(dechex(self::_GetInt2d($recordData, 0))); // the hashed password + $this->_phpSheet->getProtection()->setPassword($password, true); + } + } - /** - * Read DEFCOLWIDTH record - */ - private function _readDefColWidth() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + /** + * Read DEFCOLWIDTH record + */ + private function _readDefColWidth() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - // move stream pointer to next record - $this->_pos += 4 + $length; + // move stream pointer to next record + $this->_pos += 4 + $length; - // offset: 0; size: 2; default column width - $width = self::_GetInt2d($recordData, 0); - if ($width != 8) { - $this->_phpSheet->getDefaultColumnDimension()->setWidth($width); - } - } + // offset: 0; size: 2; default column width + $width = self::_GetInt2d($recordData, 0); + if ($width != 8) { + $this->_phpSheet->getDefaultColumnDimension()->setWidth($width); + } + } - /** - * Read COLINFO record - */ - private function _readColInfo() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + /** + * Read COLINFO record + */ + private function _readColInfo() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - // move stream pointer to next record - $this->_pos += 4 + $length; + // move stream pointer to next record + $this->_pos += 4 + $length; - if (!$this->_readDataOnly) { - // offset: 0; size: 2; index to first column in range - $fc = self::_GetInt2d($recordData, 0); // first column index + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index to first column in range + $fc = self::_GetInt2d($recordData, 0); // first column index - // offset: 2; size: 2; index to last column in range - $lc = self::_GetInt2d($recordData, 2); // first column index + // offset: 2; size: 2; index to last column in range + $lc = self::_GetInt2d($recordData, 2); // first column index - // offset: 4; size: 2; width of the column in 1/256 of the width of the zero character - $width = self::_GetInt2d($recordData, 4); + // offset: 4; size: 2; width of the column in 1/256 of the width of the zero character + $width = self::_GetInt2d($recordData, 4); - // offset: 6; size: 2; index to XF record for default column formatting - $xfIndex = self::_GetInt2d($recordData, 6); + // offset: 6; size: 2; index to XF record for default column formatting + $xfIndex = self::_GetInt2d($recordData, 6); - // offset: 8; size: 2; option flags + // offset: 8; size: 2; option flags - // bit: 0; mask: 0x0001; 1= columns are hidden - $isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0; + // bit: 0; mask: 0x0001; 1= columns are hidden + $isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0; - // bit: 10-8; mask: 0x0700; outline level of the columns (0 = no outline) - $level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8; + // bit: 10-8; mask: 0x0700; outline level of the columns (0 = no outline) + $level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8; - // bit: 12; mask: 0x1000; 1 = collapsed - $isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12; - - // offset: 10; size: 2; not used - - for ($i = $fc; $i <= $lc; ++$i) { - if ($lc == 255 || $lc == 256) { - $this->_phpSheet->getDefaultColumnDimension()->setWidth($width / 256); - break; - } - $this->_phpSheet->getColumnDimensionByColumn($i)->setWidth($width / 256); - $this->_phpSheet->getColumnDimensionByColumn($i)->setVisible(!$isHidden); - $this->_phpSheet->getColumnDimensionByColumn($i)->setOutlineLevel($level); - $this->_phpSheet->getColumnDimensionByColumn($i)->setCollapsed($isCollapsed); - $this->_phpSheet->getColumnDimensionByColumn($i)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } + // bit: 12; mask: 0x1000; 1 = collapsed + $isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12; + + // offset: 10; size: 2; not used + + for ($i = $fc; $i <= $lc; ++$i) { + if ($lc == 255 || $lc == 256) { + $this->_phpSheet->getDefaultColumnDimension()->setWidth($width / 256); + break; + } + $this->_phpSheet->getColumnDimensionByColumn($i)->setWidth($width / 256); + $this->_phpSheet->getColumnDimensionByColumn($i)->setVisible(!$isHidden); + $this->_phpSheet->getColumnDimensionByColumn($i)->setOutlineLevel($level); + $this->_phpSheet->getColumnDimensionByColumn($i)->setCollapsed($isCollapsed); + $this->_phpSheet->getColumnDimensionByColumn($i)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } - /** - * ROW - * - * This record contains the properties of a single row in a - * sheet. Rows and cells in a sheet are divided into blocks - * of 32 rows. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readRow() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; index of this row - $r = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to column of the first cell which is described by a cell record - - // offset: 4; size: 2; index to column of the last cell which is described by a cell record, increased by 1 - - // offset: 6; size: 2; - - // bit: 14-0; mask: 0x7FFF; height of the row, in twips = 1/20 of a point - $height = (0x7FFF & self::_GetInt2d($recordData, 6)) >> 0; - - // bit: 15: mask: 0x8000; 0 = row has custom height; 1= row has default height - $useDefaultHeight = (0x8000 & self::_GetInt2d($recordData, 6)) >> 15; - - if (!$useDefaultHeight) { - $this->_phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20); - } - - // offset: 8; size: 2; not used - - // offset: 10; size: 2; not used in BIFF5-BIFF8 - - // offset: 12; size: 4; option flags and default row formatting - - // bit: 2-0: mask: 0x00000007; outline level of the row - $level = (0x00000007 & self::_GetInt4d($recordData, 12)) >> 0; - $this->_phpSheet->getRowDimension($r + 1)->setOutlineLevel($level); - - // bit: 4; mask: 0x00000010; 1 = outline group start or ends here... and is collapsed - $isCollapsed = (0x00000010 & self::_GetInt4d($recordData, 12)) >> 4; - $this->_phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed); - - // bit: 5; mask: 0x00000020; 1 = row is hidden - $isHidden = (0x00000020 & self::_GetInt4d($recordData, 12)) >> 5; - $this->_phpSheet->getRowDimension($r + 1)->setVisible(!$isHidden); - - // bit: 7; mask: 0x00000080; 1 = row has explicit format - $hasExplicitFormat = (0x00000080 & self::_GetInt4d($recordData, 12)) >> 7; - - // bit: 27-16; mask: 0x0FFF0000; only applies when hasExplicitFormat = 1; index to XF record - $xfIndex = (0x0FFF0000 & self::_GetInt4d($recordData, 12)) >> 16; - - if ($hasExplicitFormat) { - $this->_phpSheet->getRowDimension($r + 1)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - - /** - * Read RK record - * This record represents a cell that contains an RK value - * (encoded integer or floating-point value). If a - * floating-point value cannot be encoded to an RK value, - * a NUMBER record will be written. This record replaces the - * record INTEGER written in BIFF2. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readRk() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to column - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - // offset: 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); - - // offset: 6; size: 4; RK value - $rknum = self::_GetInt4d($recordData, 6); - $numValue = self::_GetIEEE754($rknum); - - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { - // add style information - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - - // add cell - $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); - } - } - - - /** - * Read LABELSST record - * This record represents a cell that contains a string. It - * replaces the LABEL record and RSTRING record used in - * BIFF2-BIFF5. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readLabelSst() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to column - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - // offset: 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); - - // offset: 6; size: 4; index to SST record - $index = self::_GetInt4d($recordData, 6); - - // add cell - if (($fmtRuns = $this->_sst[$index]['fmtRuns']) && !$this->_readDataOnly) { - // then we should treat as rich text - $richText = new PHPExcel_RichText(); - $charPos = 0; - $sstCount = count($this->_sst[$index]['fmtRuns']); - for ($i = 0; $i <= $sstCount; ++$i) { - if (isset($fmtRuns[$i])) { - $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos); - $charPos = $fmtRuns[$i]['charPos']; - } else { - $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, PHPExcel_Shared_String::CountCharacters($this->_sst[$index]['value'])); - } - - if (PHPExcel_Shared_String::CountCharacters($text) > 0) { - if ($i == 0) { // first text run, no style - $richText->createText($text); - } else { - $textRun = $richText->createTextRun($text); - if (isset($fmtRuns[$i - 1])) { - if ($fmtRuns[$i - 1]['fontIndex'] < 4) { - $fontIndex = $fmtRuns[$i - 1]['fontIndex']; - } else { - // this has to do with that index 4 is omitted in all BIFF versions for some strange reason - // check the OpenOffice documentation of the FONT record - $fontIndex = $fmtRuns[$i - 1]['fontIndex'] - 1; - } - $textRun->setFont(clone $this->_objFonts[$fontIndex]); - } - } - } - } - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - $cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING); - } else { - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - $cell->setValueExplicit($this->_sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING); - } - - if (!$this->_readDataOnly) { - // add style information - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - - /** - * Read MULRK record - * This record represents a cell range containing RK value - * cells. All cells are located in the same row. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readMulRk() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to first column - $colFirst = self::_GetInt2d($recordData, 2); - - // offset: var; size: 2; index to last column - $colLast = self::_GetInt2d($recordData, $length - 2); - $columns = $colLast - $colFirst + 1; - - // offset within record data - $offset = 4; - - for ($i = 0; $i < $columns; ++$i) { - $columnString = PHPExcel_Cell::stringFromColumnIndex($colFirst + $i); - - // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - - // offset: var; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, $offset); - - // offset: var; size: 4; RK value - $numValue = self::_GetIEEE754(self::_GetInt4d($recordData, $offset + 2)); - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { - // add style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - - // add cell value - $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); - } - - $offset += 6; - } - } - - - /** - * Read NUMBER record - * This record represents a cell that contains a - * floating-point value. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readNumber() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size 2; index to column - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - // offset 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); - - $numValue = self::_extractNumber(substr($recordData, 6, 8)); - - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { - // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - - // add cell value - $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); - } - } - - - /** - * Read FORMULA record + perhaps a following STRING record if formula result is a string - * This record contains the token array and the result of a - * formula cell. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readFormula() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; row index - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; col index - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // offset: 20: size: variable; formula structure - $formulaStructure = substr($recordData, 20); - - // offset: 14: size: 2; option flags, recalculate always, recalculate on open etc. - $options = self::_GetInt2d($recordData, 14); - - // bit: 0; mask: 0x0001; 1 = recalculate always - // bit: 1; mask: 0x0002; 1 = calculate on open - // bit: 2; mask: 0x0008; 1 = part of a shared formula - $isPartOfSharedFormula = (bool) (0x0008 & $options); - - // WARNING: - // We can apparently not rely on $isPartOfSharedFormula. Even when $isPartOfSharedFormula = true - // the formula data may be ordinary formula data, therefore we need to check - // explicitly for the tExp token (0x01) - $isPartOfSharedFormula = $isPartOfSharedFormula && ord($formulaStructure{2}) == 0x01; - - if ($isPartOfSharedFormula) { - // part of shared formula which means there will be a formula with a tExp token and nothing else - // get the base cell, grab tExp token - $baseRow = self::_GetInt2d($formulaStructure, 3); - $baseCol = self::_GetInt2d($formulaStructure, 5); - $this->_baseCell = PHPExcel_Cell::stringFromColumnIndex($baseCol). ($baseRow + 1); - } - - // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - - if ($isPartOfSharedFormula) { - // formula is added to this cell after the sheet has been read - $this->_sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell; - } - - // offset: 16: size: 4; not used - - // offset: 4; size: 2; XF index - $xfIndex = self::_GetInt2d($recordData, 4); - - // offset: 6; size: 8; result of the formula - if ( (ord($recordData{6}) == 0) - && (ord($recordData{12}) == 255) - && (ord($recordData{13}) == 255) ) { - - // String formula. Result follows in appended STRING record - $dataType = PHPExcel_Cell_DataType::TYPE_STRING; - - // read possible SHAREDFMLA record - $code = self::_GetInt2d($this->_data, $this->_pos); - if ($code == self::XLS_Type_SHAREDFMLA) { - $this->_readSharedFmla(); - } - - // read STRING record - $value = $this->_readString(); - - } elseif ((ord($recordData{6}) == 1) - && (ord($recordData{12}) == 255) - && (ord($recordData{13}) == 255)) { - - // Boolean formula. Result is in +2; 0=false, 1=true - $dataType = PHPExcel_Cell_DataType::TYPE_BOOL; - $value = (bool) ord($recordData{8}); - - } elseif ((ord($recordData{6}) == 2) - && (ord($recordData{12}) == 255) - && (ord($recordData{13}) == 255)) { - - // Error formula. Error code is in +2 - $dataType = PHPExcel_Cell_DataType::TYPE_ERROR; - $value = self::_mapErrorCode(ord($recordData{8})); - - } elseif ((ord($recordData{6}) == 3) - && (ord($recordData{12}) == 255) - && (ord($recordData{13}) == 255)) { - - // Formula result is a null string - $dataType = PHPExcel_Cell_DataType::TYPE_NULL; - $value = ''; - - } else { - - // forumla result is a number, first 14 bytes like _NUMBER record - $dataType = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $value = self::_extractNumber(substr($recordData, 6, 8)); - - } - - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { - // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - - // store the formula - if (!$isPartOfSharedFormula) { - // not part of shared formula - // add cell value. If we can read formula, populate with formula, otherwise just used cached value - try { - if ($this->_version != self::XLS_BIFF8) { - throw new PHPExcel_Reader_Exception('Not BIFF8. Can only read BIFF8 formulas'); - } - $formula = $this->_getFormulaFromStructure($formulaStructure); // get formula in human language - $cell->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); - - } catch (PHPExcel_Exception $e) { - $cell->setValueExplicit($value, $dataType); - } - } else { - if ($this->_version == self::XLS_BIFF8) { - // do nothing at this point, formula id added later in the code - } else { - $cell->setValueExplicit($value, $dataType); - } - } - - // store the cached calculated value - $cell->setCalculatedValue($value); - } - } - - - /** - * Read a SHAREDFMLA record. This function just stores the binary shared formula in the reader, - * which usually contains relative references. - * These will be used to construct the formula in each shared formula part after the sheet is read. - */ - private function _readSharedFmla() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0, size: 6; cell range address of the area used by the shared formula, not used for anything - $cellRange = substr($recordData, 0, 6); - $cellRange = $this->_readBIFF5CellRangeAddressFixed($cellRange); // note: even BIFF8 uses BIFF5 syntax - - // offset: 6, size: 1; not used - - // offset: 7, size: 1; number of existing FORMULA records for this shared formula - $no = ord($recordData{7}); - - // offset: 8, size: var; Binary token array of the shared formula - $formula = substr($recordData, 8); - - // at this point we only store the shared formula for later use - $this->_sharedFormulas[$this->_baseCell] = $formula; - - } - - - /** - * Read a STRING record from current stream position and advance the stream pointer to next record - * This record is used for storing result from FORMULA record when it is a string, and - * it occurs directly after the FORMULA record - * - * @return string The string contents as UTF-8 - */ - private function _readString() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong($recordData); - $value = $string['value']; - } else { - $string = $this->_readByteStringLong($recordData); - $value = $string['value']; - } - - return $value; - } - - - /** - * Read BOOLERR record - * This record represents a Boolean value or error value - * cell. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readBoolErr() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; row index - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; column index - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - // offset: 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); - - // offset: 6; size: 1; the boolean value or error value - $boolErr = ord($recordData{6}); - - // offset: 7; size: 1; 0=boolean; 1=error - $isError = ord($recordData{7}); - - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - switch ($isError) { - case 0: // boolean - $value = (bool) $boolErr; - - // add cell value - $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL); - break; - - case 1: // error type - $value = self::_mapErrorCode($boolErr); - - // add cell value - $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_ERROR); - break; - } - - if (!$this->_readDataOnly) { - // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - - /** - * Read MULBLANK record - * This record represents a cell range of empty cells. All - * cells are located in the same row - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readMulBlank() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to first column - $fc = self::_GetInt2d($recordData, 2); - - // offset: 4; size: 2 x nc; list of indexes to XF records - // add style information - if (!$this->_readDataOnly) { - for ($i = 0; $i < $length / 2 - 3; ++$i) { - $columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i); - - // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - $xfIndex = self::_GetInt2d($recordData, 4 + 2 * $i); - $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - // offset: 6; size 2; index to last column (not needed) - } - - - /** - * Read LABEL record - * This record represents a cell that contains a string. In - * BIFF8 it is usually replaced by the LABELSST record. - * Excel still uses this record, if it copies unformatted - * text cells to the clipboard. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readLabel() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to column - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - // offset: 4; size: 2; XF index - $xfIndex = self::_GetInt2d($recordData, 4); - - // add cell value - // todo: what if string is very long? continue record - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong(substr($recordData, 6)); - $value = $string['value']; - } else { - $string = $this->_readByteStringLong(substr($recordData, 6)); - $value = $string['value']; - } - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); - - if (!$this->_readDataOnly) { - // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - - /** - * Read BLANK record - */ - private function _readBlank() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; row index - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; col index - $col = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($col); - - // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - // offset: 4; size: 2; XF index - $xfIndex = self::_GetInt2d($recordData, 4); - - // add style information - if (!$this->_readDataOnly) { - $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - - } - - - /** - * Read MSODRAWING record - */ - private function _readMsoDrawing() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - - // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); - $recordData = $splicedRecordData['recordData']; - - $this->_drawingData .= $recordData; - } - - - /** - * Read OBJ record - */ - private function _readObj() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly || $this->_version != self::XLS_BIFF8) { - return; - } - - // recordData consists of an array of subrecords looking like this: - // ft: 2 bytes; ftCmo type (0x15) - // cb: 2 bytes; size in bytes of ftCmo data - // ot: 2 bytes; Object Type - // id: 2 bytes; Object id number - // grbit: 2 bytes; Option Flags - // data: var; subrecord data - - // for now, we are just interested in the second subrecord containing the object type - $ftCmoType = self::_GetInt2d($recordData, 0); - $cbCmoSize = self::_GetInt2d($recordData, 2); - $otObjType = self::_GetInt2d($recordData, 4); - $idObjID = self::_GetInt2d($recordData, 6); - $grbitOpts = self::_GetInt2d($recordData, 6); - - $this->_objs[] = array( - 'ftCmoType' => $ftCmoType, - 'cbCmoSize' => $cbCmoSize, - 'otObjType' => $otObjType, - 'idObjID' => $idObjID, - 'grbitOpts' => $grbitOpts - ); - $this->textObjRef = $idObjID; - -// echo '_readObj()
'; -// var_dump(end($this->_objs)); -// echo '
'; - } - - - /** - * Read WINDOW2 record - */ - private function _readWindow2() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; option flags - $options = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to first visible row - $firstVisibleRow = self::_GetInt2d($recordData, 2); - - // offset: 4; size: 2; index to first visible colum - $firstVisibleColumn = self::_GetInt2d($recordData, 4); - if ($this->_version === self::XLS_BIFF8) { - // offset: 8; size: 2; not used - // offset: 10; size: 2; cached magnification factor in page break preview (in percent); 0 = Default (60%) - // offset: 12; size: 2; cached magnification factor in normal view (in percent); 0 = Default (100%) - // offset: 14; size: 4; not used - $zoomscaleInPageBreakPreview = self::_GetInt2d($recordData, 10); - if ($zoomscaleInPageBreakPreview === 0) $zoomscaleInPageBreakPreview = 60; - $zoomscaleInNormalView = self::_GetInt2d($recordData, 12); - if ($zoomscaleInNormalView === 0) $zoomscaleInNormalView = 100; - } - - // bit: 1; mask: 0x0002; 0 = do not show gridlines, 1 = show gridlines - $showGridlines = (bool) ((0x0002 & $options) >> 1); - $this->_phpSheet->setShowGridlines($showGridlines); - - // bit: 2; mask: 0x0004; 0 = do not show headers, 1 = show headers - $showRowColHeaders = (bool) ((0x0004 & $options) >> 2); - $this->_phpSheet->setShowRowColHeaders($showRowColHeaders); - - // bit: 3; mask: 0x0008; 0 = panes are not frozen, 1 = panes are frozen - $this->_frozen = (bool) ((0x0008 & $options) >> 3); - - // bit: 6; mask: 0x0040; 0 = columns from left to right, 1 = columns from right to left - $this->_phpSheet->setRightToLeft((bool)((0x0040 & $options) >> 6)); - - // bit: 10; mask: 0x0400; 0 = sheet not active, 1 = sheet active - $isActive = (bool) ((0x0400 & $options) >> 10); - if ($isActive) { - $this->_phpExcel->setActiveSheetIndex($this->_phpExcel->getIndex($this->_phpSheet)); - } - - // bit: 11; mask: 0x0800; 0 = normal view, 1 = page break view - $isPageBreakPreview = (bool) ((0x0800 & $options) >> 11); - - //FIXME: set $firstVisibleRow and $firstVisibleColumn - - if ($this->_phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { - //NOTE: this setting is inferior to page layout view(Excel2007-) - $view = $isPageBreakPreview? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW : - PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL; - $this->_phpSheet->getSheetView()->setView($view); - if ($this->_version === self::XLS_BIFF8) { - $zoomScale = $isPageBreakPreview? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView; - $this->_phpSheet->getSheetView()->setZoomScale($zoomScale); - $this->_phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView); - } - } - } - - /** - * Read PLV Record(Created by Excel2007 or upper) - */ - private function _readPageLayoutView(){ - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - //var_dump(unpack("vrt/vgrbitFrt/V2reserved/vwScalePLV/vgrbit", $recordData)); - - // offset: 0; size: 2; rt - //->ignore - $rt = self::_GetInt2d($recordData, 0); - // offset: 2; size: 2; grbitfr - //->ignore - $grbitFrt = self::_GetInt2d($recordData, 2); - // offset: 4; size: 8; reserved - //->ignore - - // offset: 12; size 2; zoom scale - $wScalePLV = self::_GetInt2d($recordData, 12); - // offset: 14; size 2; grbit - $grbit = self::_GetInt2d($recordData, 14); - - // decomprise grbit - $fPageLayoutView = $grbit & 0x01; - $fRulerVisible = ($grbit >> 1) & 0x01; //no support - $fWhitespaceHidden = ($grbit >> 3) & 0x01; //no support - - if ($fPageLayoutView === 1) { - $this->_phpSheet->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT); - $this->_phpSheet->getSheetView()->setZoomScale($wScalePLV); //set by Excel2007 only if SHEETVIEW_PAGE_LAYOUT - } - //otherwise, we cannot know whether SHEETVIEW_PAGE_LAYOUT or SHEETVIEW_PAGE_BREAK_PREVIEW. - } - - /** - * Read SCL record - */ - private function _readScl() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; numerator of the view magnification - $numerator = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; numerator of the view magnification - $denumerator = self::_GetInt2d($recordData, 2); - - // set the zoom scale (in percent) - $this->_phpSheet->getSheetView()->setZoomScale($numerator * 100 / $denumerator); - } - - - /** - * Read PANE record - */ - private function _readPane() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; position of vertical split - $px = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; position of horizontal split - $py = self::_GetInt2d($recordData, 2); - - if ($this->_frozen) { - // frozen panes - $this->_phpSheet->freezePane(PHPExcel_Cell::stringFromColumnIndex($px) . ($py + 1)); - } else { - // unfrozen panes; split windows; not supported by PHPExcel core - } - } - } - - - /** - * Read SELECTION record. There is one such record for each pane in the sheet. - */ - private function _readSelection() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 1; pane identifier - $paneId = ord($recordData{0}); - - // offset: 1; size: 2; index to row of the active cell - $r = self::_GetInt2d($recordData, 1); - - // offset: 3; size: 2; index to column of the active cell - $c = self::_GetInt2d($recordData, 3); - - // offset: 5; size: 2; index into the following cell range list to the - // entry that contains the active cell - $index = self::_GetInt2d($recordData, 5); - - // offset: 7; size: var; cell range address list containing all selected cell ranges - $data = substr($recordData, 7); - $cellRangeAddressList = $this->_readBIFF5CellRangeAddressList($data); // note: also BIFF8 uses BIFF5 syntax - - $selectedCells = $cellRangeAddressList['cellRangeAddresses'][0]; - - // first row '1' + last row '16384' indicates that full column is selected (apparently also in BIFF8!) - if (preg_match('/^([A-Z]+1\:[A-Z]+)16384$/', $selectedCells)) { - $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)16384$/', '${1}1048576', $selectedCells); - } - - // first row '1' + last row '65536' indicates that full column is selected - if (preg_match('/^([A-Z]+1\:[A-Z]+)65536$/', $selectedCells)) { - $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)65536$/', '${1}1048576', $selectedCells); - } - - // first column 'A' + last column 'IV' indicates that full row is selected - if (preg_match('/^(A[0-9]+\:)IV([0-9]+)$/', $selectedCells)) { - $selectedCells = preg_replace('/^(A[0-9]+\:)IV([0-9]+)$/', '${1}XFD${2}', $selectedCells); - } - - $this->_phpSheet->setSelectedCells($selectedCells); - } - } - - - private function _includeCellRangeFiltered($cellRangeAddress) - { - $includeCellRange = true; - if ($this->getReadFilter() !== NULL) { - $includeCellRange = false; - $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($cellRangeAddress); - $rangeBoundaries[1][0]++; - for ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; $row++) { - for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; $column++) { - if ($this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { - $includeCellRange = true; - break 2; - } - } - } - } - return $includeCellRange; - } - - - /** - * MERGEDCELLS - * - * This record contains the addresses of merged cell ranges - * in the current sheet. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readMergedCells() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { - $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData); - foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) { - if ((strpos($cellRangeAddress,':') !== FALSE) && - ($this->_includeCellRangeFiltered($cellRangeAddress))) { - $this->_phpSheet->mergeCells($cellRangeAddress); - } - } - } - } - - - /** - * Read HYPERLINK record - */ - private function _readHyperLink() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer forward to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 8; cell range address of all cells containing this hyperlink - try { - $cellRange = $this->_readBIFF8CellRangeAddressFixed($recordData, 0, 8); - } catch (PHPExcel_Exception $e) { - return; - } - - // offset: 8, size: 16; GUID of StdLink - - // offset: 24, size: 4; unknown value - - // offset: 28, size: 4; option flags - - // bit: 0; mask: 0x00000001; 0 = no link or extant, 1 = file link or URL - $isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0; - - // bit: 1; mask: 0x00000002; 0 = relative path, 1 = absolute path or URL - $isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1; - - // bit: 2 (and 4); mask: 0x00000014; 0 = no description - $hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2; - - // bit: 3; mask: 0x00000008; 0 = no text, 1 = has text - $hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3; - - // bit: 7; mask: 0x00000080; 0 = no target frame, 1 = has target frame - $hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7; - - // bit: 8; mask: 0x00000100; 0 = file link or URL, 1 = UNC path (inc. server name) - $isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8; - - // offset within record data - $offset = 32; - - if ($hasDesc) { - // offset: 32; size: var; character count of description text - $dl = self::_GetInt4d($recordData, 32); - // offset: 36; size: var; character array of description text, no Unicode string header, always 16-bit characters, zero terminated - $desc = self::_encodeUTF16(substr($recordData, 36, 2 * ($dl - 1)), false); - $offset += 4 + 2 * $dl; - } - if ($hasFrame) { - $fl = self::_GetInt4d($recordData, $offset); - $offset += 4 + 2 * $fl; - } - - // detect type of hyperlink (there are 4 types) - $hyperlinkType = null; - - if ($isUNC) { - $hyperlinkType = 'UNC'; - } else if (!$isFileLinkOrUrl) { - $hyperlinkType = 'workbook'; - } else if (ord($recordData{$offset}) == 0x03) { - $hyperlinkType = 'local'; - } else if (ord($recordData{$offset}) == 0xE0) { - $hyperlinkType = 'URL'; - } - - switch ($hyperlinkType) { - case 'URL': - // section 5.58.2: Hyperlink containing a URL - // e.g. http://example.org/index.php - - // offset: var; size: 16; GUID of URL Moniker - $offset += 16; - // offset: var; size: 4; size (in bytes) of character array of the URL including trailing zero word - $us = self::_GetInt4d($recordData, $offset); - $offset += 4; - // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated - $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); + /** + * ROW + * + * This record contains the properties of a single row in a + * sheet. Rows and cells in a sheet are divided into blocks + * of 32 rows. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readRow() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index of this row + $r = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column of the first cell which is described by a cell record + + // offset: 4; size: 2; index to column of the last cell which is described by a cell record, increased by 1 + + // offset: 6; size: 2; + + // bit: 14-0; mask: 0x7FFF; height of the row, in twips = 1/20 of a point + $height = (0x7FFF & self::_GetInt2d($recordData, 6)) >> 0; + + // bit: 15: mask: 0x8000; 0 = row has custom height; 1= row has default height + $useDefaultHeight = (0x8000 & self::_GetInt2d($recordData, 6)) >> 15; + + if (!$useDefaultHeight) { + $this->_phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20); + } + + // offset: 8; size: 2; not used + + // offset: 10; size: 2; not used in BIFF5-BIFF8 + + // offset: 12; size: 4; option flags and default row formatting + + // bit: 2-0: mask: 0x00000007; outline level of the row + $level = (0x00000007 & self::_GetInt4d($recordData, 12)) >> 0; + $this->_phpSheet->getRowDimension($r + 1)->setOutlineLevel($level); + + // bit: 4; mask: 0x00000010; 1 = outline group start or ends here... and is collapsed + $isCollapsed = (0x00000010 & self::_GetInt4d($recordData, 12)) >> 4; + $this->_phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed); + + // bit: 5; mask: 0x00000020; 1 = row is hidden + $isHidden = (0x00000020 & self::_GetInt4d($recordData, 12)) >> 5; + $this->_phpSheet->getRowDimension($r + 1)->setVisible(!$isHidden); + + // bit: 7; mask: 0x00000080; 1 = row has explicit format + $hasExplicitFormat = (0x00000080 & self::_GetInt4d($recordData, 12)) >> 7; + + // bit: 27-16; mask: 0x0FFF0000; only applies when hasExplicitFormat = 1; index to XF record + $xfIndex = (0x0FFF0000 & self::_GetInt4d($recordData, 12)) >> 16; + + if ($hasExplicitFormat) { + $this->_phpSheet->getRowDimension($r + 1)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read RK record + * This record represents a cell that contains an RK value + * (encoded integer or floating-point value). If a + * floating-point value cannot be encoded to an RK value, + * a NUMBER record will be written. This record replaces the + * record INTEGER written in BIFF2. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readRk() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 4; RK value + $rknum = self::_GetInt4d($recordData, 6); + $numValue = self::_GetIEEE754($rknum); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add style information + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + } + + + /** + * Read LABELSST record + * This record represents a cell that contains a string. It + * replaces the LABEL record and RSTRING record used in + * BIFF2-BIFF5. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readLabelSst() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 4; index to SST record + $index = self::_GetInt4d($recordData, 6); + + // add cell + if (($fmtRuns = $this->_sst[$index]['fmtRuns']) && !$this->_readDataOnly) { + // then we should treat as rich text + $richText = new PHPExcel_RichText(); + $charPos = 0; + $sstCount = count($this->_sst[$index]['fmtRuns']); + for ($i = 0; $i <= $sstCount; ++$i) { + if (isset($fmtRuns[$i])) { + $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos); + $charPos = $fmtRuns[$i]['charPos']; + } else { + $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, PHPExcel_Shared_String::CountCharacters($this->_sst[$index]['value'])); + } + + if (PHPExcel_Shared_String::CountCharacters($text) > 0) { + if ($i == 0) { // first text run, no style + $richText->createText($text); + } else { + $textRun = $richText->createTextRun($text); + if (isset($fmtRuns[$i - 1])) { + if ($fmtRuns[$i - 1]['fontIndex'] < 4) { + $fontIndex = $fmtRuns[$i - 1]['fontIndex']; + } else { + // this has to do with that index 4 is omitted in all BIFF versions for some strange reason + // check the OpenOffice documentation of the FONT record + $fontIndex = $fmtRuns[$i - 1]['fontIndex'] - 1; + } + $textRun->setFont(clone $this->_objFonts[$fontIndex]); + } + } + } + } + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING); + } else { + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($this->_sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING); + } + + if (!$this->_readDataOnly) { + // add style information + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read MULRK record + * This record represents a cell range containing RK value + * cells. All cells are located in the same row. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMulRk() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first column + $colFirst = self::_GetInt2d($recordData, 2); + + // offset: var; size: 2; index to last column + $colLast = self::_GetInt2d($recordData, $length - 2); + $columns = $colLast - $colFirst + 1; + + // offset within record data + $offset = 4; + + for ($i = 0; $i < $columns; ++$i) { + $columnString = PHPExcel_Cell::stringFromColumnIndex($colFirst + $i); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + + // offset: var; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, $offset); + + // offset: var; size: 4; RK value + $numValue = self::_GetIEEE754(self::_GetInt4d($recordData, $offset + 2)); + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell value + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + + $offset += 6; + } + } + + + /** + * Read NUMBER record + * This record represents a cell that contains a + * floating-point value. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readNumber() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + $numValue = self::_extractNumber(substr($recordData, 6, 8)); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell value + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + } + + + /** + * Read FORMULA record + perhaps a following STRING record if formula result is a string + * This record contains the token array and the result of a + * formula cell. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readFormula() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; col index + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // offset: 20: size: variable; formula structure + $formulaStructure = substr($recordData, 20); + + // offset: 14: size: 2; option flags, recalculate always, recalculate on open etc. + $options = self::_GetInt2d($recordData, 14); + + // bit: 0; mask: 0x0001; 1 = recalculate always + // bit: 1; mask: 0x0002; 1 = calculate on open + // bit: 2; mask: 0x0008; 1 = part of a shared formula + $isPartOfSharedFormula = (bool) (0x0008 & $options); + + // WARNING: + // We can apparently not rely on $isPartOfSharedFormula. Even when $isPartOfSharedFormula = true + // the formula data may be ordinary formula data, therefore we need to check + // explicitly for the tExp token (0x01) + $isPartOfSharedFormula = $isPartOfSharedFormula && ord($formulaStructure{2}) == 0x01; + + if ($isPartOfSharedFormula) { + // part of shared formula which means there will be a formula with a tExp token and nothing else + // get the base cell, grab tExp token + $baseRow = self::_GetInt2d($formulaStructure, 3); + $baseCol = self::_GetInt2d($formulaStructure, 5); + $this->_baseCell = PHPExcel_Cell::stringFromColumnIndex($baseCol). ($baseRow + 1); + } + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + + if ($isPartOfSharedFormula) { + // formula is added to this cell after the sheet has been read + $this->_sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell; + } + + // offset: 16: size: 4; not used + + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 8; result of the formula + if ( (ord($recordData{6}) == 0) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255) ) { + + // String formula. Result follows in appended STRING record + $dataType = PHPExcel_Cell_DataType::TYPE_STRING; + + // read possible SHAREDFMLA record + $code = self::_GetInt2d($this->_data, $this->_pos); + if ($code == self::XLS_Type_SHAREDFMLA) { + $this->_readSharedFmla(); + } + + // read STRING record + $value = $this->_readString(); + + } elseif ((ord($recordData{6}) == 1) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + + // Boolean formula. Result is in +2; 0=false, 1=true + $dataType = PHPExcel_Cell_DataType::TYPE_BOOL; + $value = (bool) ord($recordData{8}); + + } elseif ((ord($recordData{6}) == 2) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + + // Error formula. Error code is in +2 + $dataType = PHPExcel_Cell_DataType::TYPE_ERROR; + $value = self::_mapErrorCode(ord($recordData{8})); + + } elseif ((ord($recordData{6}) == 3) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + + // Formula result is a null string + $dataType = PHPExcel_Cell_DataType::TYPE_NULL; + $value = ''; + + } else { + + // forumla result is a number, first 14 bytes like _NUMBER record + $dataType = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $value = self::_extractNumber(substr($recordData, 6, 8)); + + } + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // store the formula + if (!$isPartOfSharedFormula) { + // not part of shared formula + // add cell value. If we can read formula, populate with formula, otherwise just used cached value + try { + if ($this->_version != self::XLS_BIFF8) { + throw new PHPExcel_Reader_Exception('Not BIFF8. Can only read BIFF8 formulas'); + } + $formula = $this->_getFormulaFromStructure($formulaStructure); // get formula in human language + $cell->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + + } catch (PHPExcel_Exception $e) { + $cell->setValueExplicit($value, $dataType); + } + } else { + if ($this->_version == self::XLS_BIFF8) { + // do nothing at this point, formula id added later in the code + } else { + $cell->setValueExplicit($value, $dataType); + } + } + + // store the cached calculated value + $cell->setCalculatedValue($value); + } + } + + + /** + * Read a SHAREDFMLA record. This function just stores the binary shared formula in the reader, + * which usually contains relative references. + * These will be used to construct the formula in each shared formula part after the sheet is read. + */ + private function _readSharedFmla() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0, size: 6; cell range address of the area used by the shared formula, not used for anything + $cellRange = substr($recordData, 0, 6); + $cellRange = $this->_readBIFF5CellRangeAddressFixed($cellRange); // note: even BIFF8 uses BIFF5 syntax + + // offset: 6, size: 1; not used + + // offset: 7, size: 1; number of existing FORMULA records for this shared formula + $no = ord($recordData{7}); + + // offset: 8, size: var; Binary token array of the shared formula + $formula = substr($recordData, 8); + + // at this point we only store the shared formula for later use + $this->_sharedFormulas[$this->_baseCell] = $formula; + + } + + + /** + * Read a STRING record from current stream position and advance the stream pointer to next record + * This record is used for storing result from FORMULA record when it is a string, and + * it occurs directly after the FORMULA record + * + * @return string The string contents as UTF-8 + */ + private function _readString() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + $value = $string['value']; + } else { + $string = $this->_readByteStringLong($recordData); + $value = $string['value']; + } + + return $value; + } + + + /** + * Read BOOLERR record + * This record represents a Boolean value or error value + * cell. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readBoolErr() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; column index + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 1; the boolean value or error value + $boolErr = ord($recordData{6}); + + // offset: 7; size: 1; 0=boolean; 1=error + $isError = ord($recordData{7}); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + switch ($isError) { + case 0: // boolean + $value = (bool) $boolErr; + + // add cell value + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL); + break; + + case 1: // error type + $value = self::_mapErrorCode($boolErr); + + // add cell value + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_ERROR); + break; + } + + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read MULBLANK record + * This record represents a cell range of empty cells. All + * cells are located in the same row + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMulBlank() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first column + $fc = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 2 x nc; list of indexes to XF records + // add style information + if (!$this->_readDataOnly) { + for ($i = 0; $i < $length / 2 - 3; ++$i) { + $columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + $xfIndex = self::_GetInt2d($recordData, 4 + 2 * $i); + $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + // offset: 6; size 2; index to last column (not needed) + } + + + /** + * Read LABEL record + * This record represents a cell that contains a string. In + * BIFF8 it is usually replaced by the LABELSST record. + * Excel still uses this record, if it copies unformatted + * text cells to the clipboard. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readLabel() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // add cell value + // todo: what if string is very long? continue record + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong(substr($recordData, 6)); + $value = $string['value']; + } else { + $string = $this->_readByteStringLong(substr($recordData, 6)); + $value = $string['value']; + } + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); + + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read BLANK record + */ + private function _readBlank() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; col index + $col = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($col); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // add style information + if (!$this->_readDataOnly) { + $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + + } + + + /** + * Read MSODRAWING record + */ + private function _readMsoDrawing() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + $this->_drawingData .= $recordData; + } + + + /** + * Read OBJ record + */ + private function _readObj() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly || $this->_version != self::XLS_BIFF8) { + return; + } + + // recordData consists of an array of subrecords looking like this: + // ft: 2 bytes; ftCmo type (0x15) + // cb: 2 bytes; size in bytes of ftCmo data + // ot: 2 bytes; Object Type + // id: 2 bytes; Object id number + // grbit: 2 bytes; Option Flags + // data: var; subrecord data + + // for now, we are just interested in the second subrecord containing the object type + $ftCmoType = self::_GetInt2d($recordData, 0); + $cbCmoSize = self::_GetInt2d($recordData, 2); + $otObjType = self::_GetInt2d($recordData, 4); + $idObjID = self::_GetInt2d($recordData, 6); + $grbitOpts = self::_GetInt2d($recordData, 6); + + $this->_objs[] = array( + 'ftCmoType' => $ftCmoType, + 'cbCmoSize' => $cbCmoSize, + 'otObjType' => $otObjType, + 'idObjID' => $idObjID, + 'grbitOpts' => $grbitOpts + ); + $this->textObjRef = $idObjID; + +// echo '_readObj()
'; +// var_dump(end($this->_objs)); +// echo '
'; + } + + + /** + * Read WINDOW2 record + */ + private function _readWindow2() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; option flags + $options = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first visible row + $firstVisibleRow = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 2; index to first visible colum + $firstVisibleColumn = self::_GetInt2d($recordData, 4); + if ($this->_version === self::XLS_BIFF8) { + // offset: 8; size: 2; not used + // offset: 10; size: 2; cached magnification factor in page break preview (in percent); 0 = Default (60%) + // offset: 12; size: 2; cached magnification factor in normal view (in percent); 0 = Default (100%) + // offset: 14; size: 4; not used + $zoomscaleInPageBreakPreview = self::_GetInt2d($recordData, 10); + if ($zoomscaleInPageBreakPreview === 0) $zoomscaleInPageBreakPreview = 60; + $zoomscaleInNormalView = self::_GetInt2d($recordData, 12); + if ($zoomscaleInNormalView === 0) $zoomscaleInNormalView = 100; + } + + // bit: 1; mask: 0x0002; 0 = do not show gridlines, 1 = show gridlines + $showGridlines = (bool) ((0x0002 & $options) >> 1); + $this->_phpSheet->setShowGridlines($showGridlines); + + // bit: 2; mask: 0x0004; 0 = do not show headers, 1 = show headers + $showRowColHeaders = (bool) ((0x0004 & $options) >> 2); + $this->_phpSheet->setShowRowColHeaders($showRowColHeaders); + + // bit: 3; mask: 0x0008; 0 = panes are not frozen, 1 = panes are frozen + $this->_frozen = (bool) ((0x0008 & $options) >> 3); + + // bit: 6; mask: 0x0040; 0 = columns from left to right, 1 = columns from right to left + $this->_phpSheet->setRightToLeft((bool)((0x0040 & $options) >> 6)); + + // bit: 10; mask: 0x0400; 0 = sheet not active, 1 = sheet active + $isActive = (bool) ((0x0400 & $options) >> 10); + if ($isActive) { + $this->_phpExcel->setActiveSheetIndex($this->_phpExcel->getIndex($this->_phpSheet)); + } + + // bit: 11; mask: 0x0800; 0 = normal view, 1 = page break view + $isPageBreakPreview = (bool) ((0x0800 & $options) >> 11); + + //FIXME: set $firstVisibleRow and $firstVisibleColumn + + if ($this->_phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { + //NOTE: this setting is inferior to page layout view(Excel2007-) + $view = $isPageBreakPreview? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW : + PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL; + $this->_phpSheet->getSheetView()->setView($view); + if ($this->_version === self::XLS_BIFF8) { + $zoomScale = $isPageBreakPreview? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView; + $this->_phpSheet->getSheetView()->setZoomScale($zoomScale); + $this->_phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView); + } + } + } + + /** + * Read PLV Record(Created by Excel2007 or upper) + */ + private function _readPageLayoutView(){ + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + //var_dump(unpack("vrt/vgrbitFrt/V2reserved/vwScalePLV/vgrbit", $recordData)); + + // offset: 0; size: 2; rt + //->ignore + $rt = self::_GetInt2d($recordData, 0); + // offset: 2; size: 2; grbitfr + //->ignore + $grbitFrt = self::_GetInt2d($recordData, 2); + // offset: 4; size: 8; reserved + //->ignore + + // offset: 12; size 2; zoom scale + $wScalePLV = self::_GetInt2d($recordData, 12); + // offset: 14; size 2; grbit + $grbit = self::_GetInt2d($recordData, 14); + + // decomprise grbit + $fPageLayoutView = $grbit & 0x01; + $fRulerVisible = ($grbit >> 1) & 0x01; //no support + $fWhitespaceHidden = ($grbit >> 3) & 0x01; //no support + + if ($fPageLayoutView === 1) { + $this->_phpSheet->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT); + $this->_phpSheet->getSheetView()->setZoomScale($wScalePLV); //set by Excel2007 only if SHEETVIEW_PAGE_LAYOUT + } + //otherwise, we cannot know whether SHEETVIEW_PAGE_LAYOUT or SHEETVIEW_PAGE_BREAK_PREVIEW. + } + + /** + * Read SCL record + */ + private function _readScl() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; numerator of the view magnification + $numerator = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; numerator of the view magnification + $denumerator = self::_GetInt2d($recordData, 2); + + // set the zoom scale (in percent) + $this->_phpSheet->getSheetView()->setZoomScale($numerator * 100 / $denumerator); + } + + + /** + * Read PANE record + */ + private function _readPane() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; position of vertical split + $px = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; position of horizontal split + $py = self::_GetInt2d($recordData, 2); + + if ($this->_frozen) { + // frozen panes + $this->_phpSheet->freezePane(PHPExcel_Cell::stringFromColumnIndex($px) . ($py + 1)); + } else { + // unfrozen panes; split windows; not supported by PHPExcel core + } + } + } + + + /** + * Read SELECTION record. There is one such record for each pane in the sheet. + */ + private function _readSelection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 1; pane identifier + $paneId = ord($recordData{0}); + + // offset: 1; size: 2; index to row of the active cell + $r = self::_GetInt2d($recordData, 1); + + // offset: 3; size: 2; index to column of the active cell + $c = self::_GetInt2d($recordData, 3); + + // offset: 5; size: 2; index into the following cell range list to the + // entry that contains the active cell + $index = self::_GetInt2d($recordData, 5); + + // offset: 7; size: var; cell range address list containing all selected cell ranges + $data = substr($recordData, 7); + $cellRangeAddressList = $this->_readBIFF5CellRangeAddressList($data); // note: also BIFF8 uses BIFF5 syntax + + $selectedCells = $cellRangeAddressList['cellRangeAddresses'][0]; + + // first row '1' + last row '16384' indicates that full column is selected (apparently also in BIFF8!) + if (preg_match('/^([A-Z]+1\:[A-Z]+)16384$/', $selectedCells)) { + $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)16384$/', '${1}1048576', $selectedCells); + } + + // first row '1' + last row '65536' indicates that full column is selected + if (preg_match('/^([A-Z]+1\:[A-Z]+)65536$/', $selectedCells)) { + $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)65536$/', '${1}1048576', $selectedCells); + } + + // first column 'A' + last column 'IV' indicates that full row is selected + if (preg_match('/^(A[0-9]+\:)IV([0-9]+)$/', $selectedCells)) { + $selectedCells = preg_replace('/^(A[0-9]+\:)IV([0-9]+)$/', '${1}XFD${2}', $selectedCells); + } + + $this->_phpSheet->setSelectedCells($selectedCells); + } + } + + + private function _includeCellRangeFiltered($cellRangeAddress) + { + $includeCellRange = true; + if ($this->getReadFilter() !== NULL) { + $includeCellRange = false; + $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($cellRangeAddress); + $rangeBoundaries[1][0]++; + for ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; $row++) { + for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; $column++) { + if ($this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { + $includeCellRange = true; + break 2; + } + } + } + } + return $includeCellRange; + } + + + /** + * MERGEDCELLS + * + * This record contains the addresses of merged cell ranges + * in the current sheet. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMergedCells() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData); + foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) { + if ((strpos($cellRangeAddress,':') !== FALSE) && + ($this->_includeCellRangeFiltered($cellRangeAddress))) { + $this->_phpSheet->mergeCells($cellRangeAddress); + } + } + } + } + + + /** + * Read HYPERLINK record + */ + private function _readHyperLink() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8; cell range address of all cells containing this hyperlink + try { + $cellRange = $this->_readBIFF8CellRangeAddressFixed($recordData, 0, 8); + } catch (PHPExcel_Exception $e) { + return; + } + + // offset: 8, size: 16; GUID of StdLink + + // offset: 24, size: 4; unknown value + + // offset: 28, size: 4; option flags + + // bit: 0; mask: 0x00000001; 0 = no link or extant, 1 = file link or URL + $isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0; + + // bit: 1; mask: 0x00000002; 0 = relative path, 1 = absolute path or URL + $isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1; + + // bit: 2 (and 4); mask: 0x00000014; 0 = no description + $hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2; + + // bit: 3; mask: 0x00000008; 0 = no text, 1 = has text + $hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3; + + // bit: 7; mask: 0x00000080; 0 = no target frame, 1 = has target frame + $hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7; + + // bit: 8; mask: 0x00000100; 0 = file link or URL, 1 = UNC path (inc. server name) + $isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8; + + // offset within record data + $offset = 32; + + if ($hasDesc) { + // offset: 32; size: var; character count of description text + $dl = self::_GetInt4d($recordData, 32); + // offset: 36; size: var; character array of description text, no Unicode string header, always 16-bit characters, zero terminated + $desc = self::_encodeUTF16(substr($recordData, 36, 2 * ($dl - 1)), false); + $offset += 4 + 2 * $dl; + } + if ($hasFrame) { + $fl = self::_GetInt4d($recordData, $offset); + $offset += 4 + 2 * $fl; + } + + // detect type of hyperlink (there are 4 types) + $hyperlinkType = null; + + if ($isUNC) { + $hyperlinkType = 'UNC'; + } else if (!$isFileLinkOrUrl) { + $hyperlinkType = 'workbook'; + } else if (ord($recordData{$offset}) == 0x03) { + $hyperlinkType = 'local'; + } else if (ord($recordData{$offset}) == 0xE0) { + $hyperlinkType = 'URL'; + } + + switch ($hyperlinkType) { + case 'URL': + // section 5.58.2: Hyperlink containing a URL + // e.g. http://example.org/index.php + + // offset: var; size: 16; GUID of URL Moniker + $offset += 16; + // offset: var; size: 4; size (in bytes) of character array of the URL including trailing zero word + $us = self::_GetInt4d($recordData, $offset); + $offset += 4; + // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated + $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); $nullOffset = strpos($url, 0x00); - if ($nullOffset) + if ($nullOffset) $url = substr($url,0,$nullOffset); - $url .= $hasText ? '#' : ''; - $offset += $us; - break; - - case 'local': - // section 5.58.3: Hyperlink to local file - // examples: - // mydoc.txt - // ../../somedoc.xls#Sheet!A1 - - // offset: var; size: 16; GUI of File Moniker - $offset += 16; - - // offset: var; size: 2; directory up-level count. - $upLevelCount = self::_GetInt2d($recordData, $offset); - $offset += 2; - - // offset: var; size: 4; character count of the shortened file path and name, including trailing zero word - $sl = self::_GetInt4d($recordData, $offset); - $offset += 4; - - // offset: var; size: sl; character array of the shortened file path and name in 8.3-DOS-format (compressed Unicode string) - $shortenedFilePath = substr($recordData, $offset, $sl); - $shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true); - $shortenedFilePath = substr($shortenedFilePath, 0, -1); // remove trailing zero - - $offset += $sl; - - // offset: var; size: 24; unknown sequence - $offset += 24; - - // extended file path - // offset: var; size: 4; size of the following file link field including string lenth mark - $sz = self::_GetInt4d($recordData, $offset); - $offset += 4; - - // only present if $sz > 0 - if ($sz > 0) { - // offset: var; size: 4; size of the character array of the extended file path and name - $xl = self::_GetInt4d($recordData, $offset); - $offset += 4; - - // offset: var; size 2; unknown - $offset += 2; - - // offset: var; size $xl; character array of the extended file path and name. - $extendedFilePath = substr($recordData, $offset, $xl); - $extendedFilePath = self::_encodeUTF16($extendedFilePath, false); - $offset += $xl; - } - - // construct the path - $url = str_repeat('..\\', $upLevelCount); - $url .= ($sz > 0) ? - $extendedFilePath : $shortenedFilePath; // use extended path if available - $url .= $hasText ? '#' : ''; - - break; - - - case 'UNC': - // section 5.58.4: Hyperlink to a File with UNC (Universal Naming Convention) Path - // todo: implement - return; - - case 'workbook': - // section 5.58.5: Hyperlink to the Current Workbook - // e.g. Sheet2!B1:C2, stored in text mark field - $url = 'sheet://'; - break; - - default: - return; - - } - - if ($hasText) { - // offset: var; size: 4; character count of text mark including trailing zero word - $tl = self::_GetInt4d($recordData, $offset); - $offset += 4; - // offset: var; size: var; character array of the text mark without the # sign, no Unicode header, always 16-bit characters, zero-terminated - $text = self::_encodeUTF16(substr($recordData, $offset, 2 * ($tl - 1)), false); - $url .= $text; - } - - // apply the hyperlink to all the relevant cells - foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cellRange) as $coordinate) { - $this->_phpSheet->getCell($coordinate)->getHyperLink()->setUrl($url); - } - } - } - - - /** - * Read DATAVALIDATIONS record - */ - private function _readDataValidations() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer forward to next record - $this->_pos += 4 + $length; - } - - - /** - * Read DATAVALIDATION record - */ - private function _readDataValidation() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer forward to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - // offset: 0; size: 4; Options - $options = self::_GetInt4d($recordData, 0); - - // bit: 0-3; mask: 0x0000000F; type - $type = (0x0000000F & $options) >> 0; - switch ($type) { - case 0x00: $type = PHPExcel_Cell_DataValidation::TYPE_NONE; break; - case 0x01: $type = PHPExcel_Cell_DataValidation::TYPE_WHOLE; break; - case 0x02: $type = PHPExcel_Cell_DataValidation::TYPE_DECIMAL; break; - case 0x03: $type = PHPExcel_Cell_DataValidation::TYPE_LIST; break; - case 0x04: $type = PHPExcel_Cell_DataValidation::TYPE_DATE; break; - case 0x05: $type = PHPExcel_Cell_DataValidation::TYPE_TIME; break; - case 0x06: $type = PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH; break; - case 0x07: $type = PHPExcel_Cell_DataValidation::TYPE_CUSTOM; break; - } - - // bit: 4-6; mask: 0x00000070; error type - $errorStyle = (0x00000070 & $options) >> 4; - switch ($errorStyle) { - case 0x00: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; break; - case 0x01: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_WARNING; break; - case 0x02: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_INFORMATION; break; - } - - // bit: 7; mask: 0x00000080; 1= formula is explicit (only applies to list) - // I have only seen cases where this is 1 - $explicitFormula = (0x00000080 & $options) >> 7; - - // bit: 8; mask: 0x00000100; 1= empty cells allowed - $allowBlank = (0x00000100 & $options) >> 8; - - // bit: 9; mask: 0x00000200; 1= suppress drop down arrow in list type validity - $suppressDropDown = (0x00000200 & $options) >> 9; - - // bit: 18; mask: 0x00040000; 1= show prompt box if cell selected - $showInputMessage = (0x00040000 & $options) >> 18; - - // bit: 19; mask: 0x00080000; 1= show error box if invalid values entered - $showErrorMessage = (0x00080000 & $options) >> 19; - - // bit: 20-23; mask: 0x00F00000; condition operator - $operator = (0x00F00000 & $options) >> 20; - switch ($operator) { - case 0x00: $operator = PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN ; break; - case 0x01: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN ; break; - case 0x02: $operator = PHPExcel_Cell_DataValidation::OPERATOR_EQUAL ; break; - case 0x03: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL ; break; - case 0x04: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN ; break; - case 0x05: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN ; break; - case 0x06: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL; break; - case 0x07: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL ; break; - } - - // offset: 4; size: var; title of the prompt box - $offset = 4; - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $promptTitle = $string['value'] !== chr(0) ? - $string['value'] : ''; - $offset += $string['size']; - - // offset: var; size: var; title of the error box - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $errorTitle = $string['value'] !== chr(0) ? - $string['value'] : ''; - $offset += $string['size']; - - // offset: var; size: var; text of the prompt box - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $prompt = $string['value'] !== chr(0) ? - $string['value'] : ''; - $offset += $string['size']; - - // offset: var; size: var; text of the error box - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $error = $string['value'] !== chr(0) ? - $string['value'] : ''; - $offset += $string['size']; - - // offset: var; size: 2; size of the formula data for the first condition - $sz1 = self::_GetInt2d($recordData, $offset); - $offset += 2; - - // offset: var; size: 2; not used - $offset += 2; - - // offset: var; size: $sz1; formula data for first condition (without size field) - $formula1 = substr($recordData, $offset, $sz1); - $formula1 = pack('v', $sz1) . $formula1; // prepend the length - try { - $formula1 = $this->_getFormulaFromStructure($formula1); - - // in list type validity, null characters are used as item separators - if ($type == PHPExcel_Cell_DataValidation::TYPE_LIST) { - $formula1 = str_replace(chr(0), ',', $formula1); - } - } catch (PHPExcel_Exception $e) { - return; - } - $offset += $sz1; - - // offset: var; size: 2; size of the formula data for the first condition - $sz2 = self::_GetInt2d($recordData, $offset); - $offset += 2; - - // offset: var; size: 2; not used - $offset += 2; - - // offset: var; size: $sz2; formula data for second condition (without size field) - $formula2 = substr($recordData, $offset, $sz2); - $formula2 = pack('v', $sz2) . $formula2; // prepend the length - try { - $formula2 = $this->_getFormulaFromStructure($formula2); - } catch (PHPExcel_Exception $e) { - return; - } - $offset += $sz2; - - // offset: var; size: var; cell range address list with - $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList(substr($recordData, $offset)); - $cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses']; - - foreach ($cellRangeAddresses as $cellRange) { - $stRange = $this->_phpSheet->shrinkRangeToFit($cellRange); - $stRange = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); - foreach ($stRange as $coordinate) { - $objValidation = $this->_phpSheet->getCell($coordinate)->getDataValidation(); - $objValidation->setType($type); - $objValidation->setErrorStyle($errorStyle); - $objValidation->setAllowBlank((bool)$allowBlank); - $objValidation->setShowInputMessage((bool)$showInputMessage); - $objValidation->setShowErrorMessage((bool)$showErrorMessage); - $objValidation->setShowDropDown(!$suppressDropDown); - $objValidation->setOperator($operator); - $objValidation->setErrorTitle($errorTitle); - $objValidation->setError($error); - $objValidation->setPromptTitle($promptTitle); - $objValidation->setPrompt($prompt); - $objValidation->setFormula1($formula1); - $objValidation->setFormula2($formula2); - } - } - - } - - - /** - * Read SHEETLAYOUT record. Stores sheet tab color information. - */ - private function _readSheetLayout() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // local pointer in record data - $offset = 0; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; repeated record identifier 0x0862 - - // offset: 2; size: 10; not used - - // offset: 12; size: 4; size of record data - // Excel 2003 uses size of 0x14 (documented), Excel 2007 uses size of 0x28 (not documented?) - $sz = self::_GetInt4d($recordData, 12); - - switch ($sz) { - case 0x14: - // offset: 16; size: 2; color index for sheet tab - $colorIndex = self::_GetInt2d($recordData, 16); - $color = self::_readColor($colorIndex,$this->_palette,$this->_version); - $this->_phpSheet->getTabColor()->setRGB($color['rgb']); - break; - - case 0x28: - // TODO: Investigate structure for .xls SHEETLAYOUT record as saved by MS Office Excel 2007 - return; - break; - } - } - } - - - /** - * Read SHEETPROTECTION record (FEATHEADR) - */ - private function _readSheetProtection() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - // offset: 0; size: 2; repeated record header - - // offset: 2; size: 2; FRT cell reference flag (=0 currently) - - // offset: 4; size: 8; Currently not used and set to 0 - - // offset: 12; size: 2; Shared feature type index (2=Enhanced Protetion, 4=SmartTag) - $isf = self::_GetInt2d($recordData, 12); - if ($isf != 2) { - return; - } - - // offset: 14; size: 1; =1 since this is a feat header - - // offset: 15; size: 4; size of rgbHdrSData - - // rgbHdrSData, assume "Enhanced Protection" - // offset: 19; size: 2; option flags - $options = self::_GetInt2d($recordData, 19); - - // bit: 0; mask 0x0001; 1 = user may edit objects, 0 = users must not edit objects - $bool = (0x0001 & $options) >> 0; - $this->_phpSheet->getProtection()->setObjects(!$bool); - - // bit: 1; mask 0x0002; edit scenarios - $bool = (0x0002 & $options) >> 1; - $this->_phpSheet->getProtection()->setScenarios(!$bool); - - // bit: 2; mask 0x0004; format cells - $bool = (0x0004 & $options) >> 2; - $this->_phpSheet->getProtection()->setFormatCells(!$bool); - - // bit: 3; mask 0x0008; format columns - $bool = (0x0008 & $options) >> 3; - $this->_phpSheet->getProtection()->setFormatColumns(!$bool); - - // bit: 4; mask 0x0010; format rows - $bool = (0x0010 & $options) >> 4; - $this->_phpSheet->getProtection()->setFormatRows(!$bool); + $url .= $hasText ? '#' : ''; + $offset += $us; + break; + + case 'local': + // section 5.58.3: Hyperlink to local file + // examples: + // mydoc.txt + // ../../somedoc.xls#Sheet!A1 + + // offset: var; size: 16; GUI of File Moniker + $offset += 16; + + // offset: var; size: 2; directory up-level count. + $upLevelCount = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 4; character count of the shortened file path and name, including trailing zero word + $sl = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // offset: var; size: sl; character array of the shortened file path and name in 8.3-DOS-format (compressed Unicode string) + $shortenedFilePath = substr($recordData, $offset, $sl); + $shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true); + $shortenedFilePath = substr($shortenedFilePath, 0, -1); // remove trailing zero + + $offset += $sl; + + // offset: var; size: 24; unknown sequence + $offset += 24; + + // extended file path + // offset: var; size: 4; size of the following file link field including string lenth mark + $sz = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // only present if $sz > 0 + if ($sz > 0) { + // offset: var; size: 4; size of the character array of the extended file path and name + $xl = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // offset: var; size 2; unknown + $offset += 2; + + // offset: var; size $xl; character array of the extended file path and name. + $extendedFilePath = substr($recordData, $offset, $xl); + $extendedFilePath = self::_encodeUTF16($extendedFilePath, false); + $offset += $xl; + } + + // construct the path + $url = str_repeat('..\\', $upLevelCount); + $url .= ($sz > 0) ? + $extendedFilePath : $shortenedFilePath; // use extended path if available + $url .= $hasText ? '#' : ''; + + break; + + + case 'UNC': + // section 5.58.4: Hyperlink to a File with UNC (Universal Naming Convention) Path + // todo: implement + return; + + case 'workbook': + // section 5.58.5: Hyperlink to the Current Workbook + // e.g. Sheet2!B1:C2, stored in text mark field + $url = 'sheet://'; + break; + + default: + return; + + } + + if ($hasText) { + // offset: var; size: 4; character count of text mark including trailing zero word + $tl = self::_GetInt4d($recordData, $offset); + $offset += 4; + // offset: var; size: var; character array of the text mark without the # sign, no Unicode header, always 16-bit characters, zero-terminated + $text = self::_encodeUTF16(substr($recordData, $offset, 2 * ($tl - 1)), false); + $url .= $text; + } + + // apply the hyperlink to all the relevant cells + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cellRange) as $coordinate) { + $this->_phpSheet->getCell($coordinate)->getHyperLink()->setUrl($url); + } + } + } + + + /** + * Read DATAVALIDATIONS record + */ + private function _readDataValidations() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + } + + + /** + * Read DATAVALIDATION record + */ + private function _readDataValidation() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 4; Options + $options = self::_GetInt4d($recordData, 0); + + // bit: 0-3; mask: 0x0000000F; type + $type = (0x0000000F & $options) >> 0; + switch ($type) { + case 0x00: $type = PHPExcel_Cell_DataValidation::TYPE_NONE; break; + case 0x01: $type = PHPExcel_Cell_DataValidation::TYPE_WHOLE; break; + case 0x02: $type = PHPExcel_Cell_DataValidation::TYPE_DECIMAL; break; + case 0x03: $type = PHPExcel_Cell_DataValidation::TYPE_LIST; break; + case 0x04: $type = PHPExcel_Cell_DataValidation::TYPE_DATE; break; + case 0x05: $type = PHPExcel_Cell_DataValidation::TYPE_TIME; break; + case 0x06: $type = PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH; break; + case 0x07: $type = PHPExcel_Cell_DataValidation::TYPE_CUSTOM; break; + } + + // bit: 4-6; mask: 0x00000070; error type + $errorStyle = (0x00000070 & $options) >> 4; + switch ($errorStyle) { + case 0x00: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; break; + case 0x01: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_WARNING; break; + case 0x02: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_INFORMATION; break; + } + + // bit: 7; mask: 0x00000080; 1= formula is explicit (only applies to list) + // I have only seen cases where this is 1 + $explicitFormula = (0x00000080 & $options) >> 7; + + // bit: 8; mask: 0x00000100; 1= empty cells allowed + $allowBlank = (0x00000100 & $options) >> 8; + + // bit: 9; mask: 0x00000200; 1= suppress drop down arrow in list type validity + $suppressDropDown = (0x00000200 & $options) >> 9; + + // bit: 18; mask: 0x00040000; 1= show prompt box if cell selected + $showInputMessage = (0x00040000 & $options) >> 18; + + // bit: 19; mask: 0x00080000; 1= show error box if invalid values entered + $showErrorMessage = (0x00080000 & $options) >> 19; + + // bit: 20-23; mask: 0x00F00000; condition operator + $operator = (0x00F00000 & $options) >> 20; + switch ($operator) { + case 0x00: $operator = PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN ; break; + case 0x01: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN ; break; + case 0x02: $operator = PHPExcel_Cell_DataValidation::OPERATOR_EQUAL ; break; + case 0x03: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL ; break; + case 0x04: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN ; break; + case 0x05: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN ; break; + case 0x06: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL; break; + case 0x07: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL ; break; + } + + // offset: 4; size: var; title of the prompt box + $offset = 4; + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $promptTitle = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; title of the error box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $errorTitle = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; text of the prompt box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $prompt = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; text of the error box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $error = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: 2; size of the formula data for the first condition + $sz1 = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 2; not used + $offset += 2; + + // offset: var; size: $sz1; formula data for first condition (without size field) + $formula1 = substr($recordData, $offset, $sz1); + $formula1 = pack('v', $sz1) . $formula1; // prepend the length + try { + $formula1 = $this->_getFormulaFromStructure($formula1); + + // in list type validity, null characters are used as item separators + if ($type == PHPExcel_Cell_DataValidation::TYPE_LIST) { + $formula1 = str_replace(chr(0), ',', $formula1); + } + } catch (PHPExcel_Exception $e) { + return; + } + $offset += $sz1; + + // offset: var; size: 2; size of the formula data for the first condition + $sz2 = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 2; not used + $offset += 2; + + // offset: var; size: $sz2; formula data for second condition (without size field) + $formula2 = substr($recordData, $offset, $sz2); + $formula2 = pack('v', $sz2) . $formula2; // prepend the length + try { + $formula2 = $this->_getFormulaFromStructure($formula2); + } catch (PHPExcel_Exception $e) { + return; + } + $offset += $sz2; + + // offset: var; size: var; cell range address list with + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList(substr($recordData, $offset)); + $cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses']; + + foreach ($cellRangeAddresses as $cellRange) { + $stRange = $this->_phpSheet->shrinkRangeToFit($cellRange); + $stRange = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); + foreach ($stRange as $coordinate) { + $objValidation = $this->_phpSheet->getCell($coordinate)->getDataValidation(); + $objValidation->setType($type); + $objValidation->setErrorStyle($errorStyle); + $objValidation->setAllowBlank((bool)$allowBlank); + $objValidation->setShowInputMessage((bool)$showInputMessage); + $objValidation->setShowErrorMessage((bool)$showErrorMessage); + $objValidation->setShowDropDown(!$suppressDropDown); + $objValidation->setOperator($operator); + $objValidation->setErrorTitle($errorTitle); + $objValidation->setError($error); + $objValidation->setPromptTitle($promptTitle); + $objValidation->setPrompt($prompt); + $objValidation->setFormula1($formula1); + $objValidation->setFormula2($formula2); + } + } + + } + + + /** + * Read SHEETLAYOUT record. Stores sheet tab color information. + */ + private function _readSheetLayout() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // local pointer in record data + $offset = 0; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; repeated record identifier 0x0862 + + // offset: 2; size: 10; not used + + // offset: 12; size: 4; size of record data + // Excel 2003 uses size of 0x14 (documented), Excel 2007 uses size of 0x28 (not documented?) + $sz = self::_GetInt4d($recordData, 12); + + switch ($sz) { + case 0x14: + // offset: 16; size: 2; color index for sheet tab + $colorIndex = self::_GetInt2d($recordData, 16); + $color = self::_readColor($colorIndex,$this->_palette,$this->_version); + $this->_phpSheet->getTabColor()->setRGB($color['rgb']); + break; + + case 0x28: + // TODO: Investigate structure for .xls SHEETLAYOUT record as saved by MS Office Excel 2007 + return; + break; + } + } + } + + + /** + * Read SHEETPROTECTION record (FEATHEADR) + */ + private function _readSheetProtection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; repeated record header + + // offset: 2; size: 2; FRT cell reference flag (=0 currently) + + // offset: 4; size: 8; Currently not used and set to 0 + + // offset: 12; size: 2; Shared feature type index (2=Enhanced Protetion, 4=SmartTag) + $isf = self::_GetInt2d($recordData, 12); + if ($isf != 2) { + return; + } + + // offset: 14; size: 1; =1 since this is a feat header + + // offset: 15; size: 4; size of rgbHdrSData + + // rgbHdrSData, assume "Enhanced Protection" + // offset: 19; size: 2; option flags + $options = self::_GetInt2d($recordData, 19); + + // bit: 0; mask 0x0001; 1 = user may edit objects, 0 = users must not edit objects + $bool = (0x0001 & $options) >> 0; + $this->_phpSheet->getProtection()->setObjects(!$bool); + + // bit: 1; mask 0x0002; edit scenarios + $bool = (0x0002 & $options) >> 1; + $this->_phpSheet->getProtection()->setScenarios(!$bool); + + // bit: 2; mask 0x0004; format cells + $bool = (0x0004 & $options) >> 2; + $this->_phpSheet->getProtection()->setFormatCells(!$bool); + + // bit: 3; mask 0x0008; format columns + $bool = (0x0008 & $options) >> 3; + $this->_phpSheet->getProtection()->setFormatColumns(!$bool); + + // bit: 4; mask 0x0010; format rows + $bool = (0x0010 & $options) >> 4; + $this->_phpSheet->getProtection()->setFormatRows(!$bool); - // bit: 5; mask 0x0020; insert columns - $bool = (0x0020 & $options) >> 5; - $this->_phpSheet->getProtection()->setInsertColumns(!$bool); - - // bit: 6; mask 0x0040; insert rows - $bool = (0x0040 & $options) >> 6; - $this->_phpSheet->getProtection()->setInsertRows(!$bool); - - // bit: 7; mask 0x0080; insert hyperlinks - $bool = (0x0080 & $options) >> 7; - $this->_phpSheet->getProtection()->setInsertHyperlinks(!$bool); - - // bit: 8; mask 0x0100; delete columns - $bool = (0x0100 & $options) >> 8; - $this->_phpSheet->getProtection()->setDeleteColumns(!$bool); - - // bit: 9; mask 0x0200; delete rows - $bool = (0x0200 & $options) >> 9; - $this->_phpSheet->getProtection()->setDeleteRows(!$bool); - - // bit: 10; mask 0x0400; select locked cells - $bool = (0x0400 & $options) >> 10; - $this->_phpSheet->getProtection()->setSelectLockedCells(!$bool); - - // bit: 11; mask 0x0800; sort cell range - $bool = (0x0800 & $options) >> 11; - $this->_phpSheet->getProtection()->setSort(!$bool); - - // bit: 12; mask 0x1000; auto filter - $bool = (0x1000 & $options) >> 12; - $this->_phpSheet->getProtection()->setAutoFilter(!$bool); + // bit: 5; mask 0x0020; insert columns + $bool = (0x0020 & $options) >> 5; + $this->_phpSheet->getProtection()->setInsertColumns(!$bool); + + // bit: 6; mask 0x0040; insert rows + $bool = (0x0040 & $options) >> 6; + $this->_phpSheet->getProtection()->setInsertRows(!$bool); + + // bit: 7; mask 0x0080; insert hyperlinks + $bool = (0x0080 & $options) >> 7; + $this->_phpSheet->getProtection()->setInsertHyperlinks(!$bool); + + // bit: 8; mask 0x0100; delete columns + $bool = (0x0100 & $options) >> 8; + $this->_phpSheet->getProtection()->setDeleteColumns(!$bool); + + // bit: 9; mask 0x0200; delete rows + $bool = (0x0200 & $options) >> 9; + $this->_phpSheet->getProtection()->setDeleteRows(!$bool); + + // bit: 10; mask 0x0400; select locked cells + $bool = (0x0400 & $options) >> 10; + $this->_phpSheet->getProtection()->setSelectLockedCells(!$bool); + + // bit: 11; mask 0x0800; sort cell range + $bool = (0x0800 & $options) >> 11; + $this->_phpSheet->getProtection()->setSort(!$bool); + + // bit: 12; mask 0x1000; auto filter + $bool = (0x1000 & $options) >> 12; + $this->_phpSheet->getProtection()->setAutoFilter(!$bool); - // bit: 13; mask 0x2000; pivot tables - $bool = (0x2000 & $options) >> 13; - $this->_phpSheet->getProtection()->setPivotTables(!$bool); + // bit: 13; mask 0x2000; pivot tables + $bool = (0x2000 & $options) >> 13; + $this->_phpSheet->getProtection()->setPivotTables(!$bool); - // bit: 14; mask 0x4000; select unlocked cells - $bool = (0x4000 & $options) >> 14; - $this->_phpSheet->getProtection()->setSelectUnlockedCells(!$bool); + // bit: 14; mask 0x4000; select unlocked cells + $bool = (0x4000 & $options) >> 14; + $this->_phpSheet->getProtection()->setSelectUnlockedCells(!$bool); - // offset: 21; size: 2; not used - } + // offset: 21; size: 2; not used + } - /** - * Read RANGEPROTECTION record - * Reading of this record is based on Microsoft Office Excel 97-2000 Binary File Format Specification, - * where it is referred to as FEAT record - */ - private function _readRangeProtection() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + /** + * Read RANGEPROTECTION record + * Reading of this record is based on Microsoft Office Excel 97-2000 Binary File Format Specification, + * where it is referred to as FEAT record + */ + private function _readRangeProtection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - // move stream pointer to next record - $this->_pos += 4 + $length; + // move stream pointer to next record + $this->_pos += 4 + $length; - // local pointer in record data - $offset = 0; + // local pointer in record data + $offset = 0; - if (!$this->_readDataOnly) { - $offset += 12; - - // offset: 12; size: 2; shared feature type, 2 = enhanced protection, 4 = smart tag - $isf = self::_GetInt2d($recordData, 12); - if ($isf != 2) { - // we only read FEAT records of type 2 - return; - } - $offset += 2; - - $offset += 5; - - // offset: 19; size: 2; count of ref ranges this feature is on - $cref = self::_GetInt2d($recordData, 19); - $offset += 2; - - $offset += 6; - - // offset: 27; size: 8 * $cref; list of cell ranges (like in hyperlink record) - $cellRanges = array(); - for ($i = 0; $i < $cref; ++$i) { - try { - $cellRange = $this->_readBIFF8CellRangeAddressFixed(substr($recordData, 27 + 8 * $i, 8)); - } catch (PHPExcel_Exception $e) { - return; - } - $cellRanges[] = $cellRange; - $offset += 8; - } - - // offset: var; size: var; variable length of feature specific data - $rgbFeat = substr($recordData, $offset); - $offset += 4; - - // offset: var; size: 4; the encrypted password (only 16-bit although field is 32-bit) - $wPassword = self::_GetInt4d($recordData, $offset); - $offset += 4; - - // Apply range protection to sheet - if ($cellRanges) { - $this->_phpSheet->protectCells(implode(' ', $cellRanges), strtoupper(dechex($wPassword)), true); - } - } - } - - - /** - * Read IMDATA record - */ - private function _readImData() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - - // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); - $recordData = $splicedRecordData['recordData']; - - // UNDER CONSTRUCTION - - // offset: 0; size: 2; image format - $cf = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; environment from which the file was written - $env = self::_GetInt2d($recordData, 2); - - // offset: 4; size: 4; length of the image data - $lcb = self::_GetInt4d($recordData, 4); - - // offset: 8; size: var; image data - $iData = substr($recordData, 8); - - switch ($cf) { - case 0x09: // Windows bitmap format - // BITMAPCOREINFO - // 1. BITMAPCOREHEADER - // offset: 0; size: 4; bcSize, Specifies the number of bytes required by the structure - $bcSize = self::_GetInt4d($iData, 0); -// var_dump($bcSize); - - // offset: 4; size: 2; bcWidth, specifies the width of the bitmap, in pixels - $bcWidth = self::_GetInt2d($iData, 4); -// var_dump($bcWidth); - - // offset: 6; size: 2; bcHeight, specifies the height of the bitmap, in pixels. - $bcHeight = self::_GetInt2d($iData, 6); -// var_dump($bcHeight); - $ih = imagecreatetruecolor($bcWidth, $bcHeight); - - // offset: 8; size: 2; bcPlanes, specifies the number of planes for the target device. This value must be 1 - - // offset: 10; size: 2; bcBitCount specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24 - $bcBitCount = self::_GetInt2d($iData, 10); -// var_dump($bcBitCount); - - $rgbString = substr($iData, 12); - $rgbTriples = array(); - while (strlen($rgbString) > 0) { - $rgbTriples[] = unpack('Cb/Cg/Cr', $rgbString); - $rgbString = substr($rgbString, 3); - } - $x = 0; - $y = 0; - foreach ($rgbTriples as $i => $rgbTriple) { - $color = imagecolorallocate($ih, $rgbTriple['r'], $rgbTriple['g'], $rgbTriple['b']); - imagesetpixel($ih, $x, $bcHeight - 1 - $y, $color); - $x = ($x + 1) % $bcWidth; - $y = $y + floor(($x + 1) / $bcWidth); - } - //imagepng($ih, 'image.png'); - - $drawing = new PHPExcel_Worksheet_Drawing(); - $drawing->setPath($filename); - $drawing->setWorksheet($this->_phpSheet); - - break; - - case 0x02: // Windows metafile or Macintosh PICT format - case 0x0e: // native format - default; - break; - - } - - // _getSplicedRecordData() takes care of moving current position in data stream - } - - - /** - * Read a free CONTINUE record. Free CONTINUE record may be a camouflaged MSODRAWING record - * When MSODRAWING data on a sheet exceeds 8224 bytes, CONTINUE records are used instead. Undocumented. - * In this case, we must treat the CONTINUE record as a MSODRAWING record - */ - private function _readContinue() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // check if we are reading drawing data - // this is in case a free CONTINUE record occurs in other circumstances we are unaware of - if ($this->_drawingData == '') { - // move stream pointer to next record - $this->_pos += 4 + $length; - - return; - } - - // check if record data is at least 4 bytes long, otherwise there is no chance this is MSODRAWING data - if ($length < 4) { - // move stream pointer to next record - $this->_pos += 4 + $length; - - return; - } - - // dirty check to see if CONTINUE record could be a camouflaged MSODRAWING record - // look inside CONTINUE record to see if it looks like a part of an Escher stream - // we know that Escher stream may be split at least at - // 0xF003 MsofbtSpgrContainer - // 0xF004 MsofbtSpContainer - // 0xF00D MsofbtClientTextbox - $validSplitPoints = array(0xF003, 0xF004, 0xF00D); // add identifiers if we find more - - $splitPoint = self::_GetInt2d($recordData, 2); - if (in_array($splitPoint, $validSplitPoints)) { - // get spliced record data (and move pointer to next record) - $splicedRecordData = $this->_getSplicedRecordData(); - $this->_drawingData .= $splicedRecordData['recordData']; - - return; - } - - // move stream pointer to next record - $this->_pos += 4 + $length; - - } - - - /** - * Reads a record from current position in data stream and continues reading data as long as CONTINUE - * records are found. Splices the record data pieces and returns the combined string as if record data - * is in one piece. - * Moves to next current position in data stream to start of next record different from a CONtINUE record - * - * @return array - */ - private function _getSplicedRecordData() - { - $data = ''; - $spliceOffsets = array(); - - $i = 0; - $spliceOffsets[0] = 0; - - do { - ++$i; - - // offset: 0; size: 2; identifier - $identifier = self::_GetInt2d($this->_data, $this->_pos); - // offset: 2; size: 2; length - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $data .= $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - $spliceOffsets[$i] = $spliceOffsets[$i - 1] + $length; - - $this->_pos += 4 + $length; - $nextIdentifier = self::_GetInt2d($this->_data, $this->_pos); - } - while ($nextIdentifier == self::XLS_Type_CONTINUE); - - $splicedData = array( - 'recordData' => $data, - 'spliceOffsets' => $spliceOffsets, - ); - - return $splicedData; - - } - - - /** - * Convert formula structure into human readable Excel formula like 'A3+A5*5' - * - * @param string $formulaStructure The complete binary data for the formula - * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas - * @return string Human readable formula - */ - private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') - { - // offset: 0; size: 2; size of the following formula data - $sz = self::_GetInt2d($formulaStructure, 0); - - // offset: 2; size: sz - $formulaData = substr($formulaStructure, 2, $sz); - - // for debug: dump the formula data - //echo ''; - //echo 'size: ' . $sz . "\n"; - //echo 'the entire formula data: '; - //Debug::dump($formulaData); - //echo "\n----\n"; - - // offset: 2 + sz; size: variable (optional) - if (strlen($formulaStructure) > 2 + $sz) { - $additionalData = substr($formulaStructure, 2 + $sz); - - // for debug: dump the additional data - //echo 'the entire additional data: '; - //Debug::dump($additionalData); - //echo "\n----\n"; - - } else { - $additionalData = ''; - } - - return $this->_getFormulaFromData($formulaData, $additionalData, $baseCell); - } - - - /** - * Take formula data and additional data for formula and return human readable formula - * - * @param string $formulaData The binary data for the formula itself - * @param string $additionalData Additional binary data going with the formula - * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas - * @return string Human readable formula - */ - private function _getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1') - { - // start parsing the formula data - $tokens = array(); - - while (strlen($formulaData) > 0 and $token = $this->_getNextToken($formulaData, $baseCell)) { - $tokens[] = $token; - $formulaData = substr($formulaData, $token['size']); - - // for debug: dump the token - //var_dump($token); - } - - $formulaString = $this->_createFormulaFromTokens($tokens, $additionalData); - - return $formulaString; - } - - - /** - * Take array of tokens together with additional data for formula and return human readable formula - * - * @param array $tokens - * @param array $additionalData Additional binary data going with the formula - * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas - * @return string Human readable formula - */ - private function _createFormulaFromTokens($tokens, $additionalData) - { - // empty formula? - if (empty($tokens)) { - return ''; - } - - $formulaStrings = array(); - foreach ($tokens as $token) { - // initialize spaces - $space0 = isset($space0) ? $space0 : ''; // spaces before next token, not tParen - $space1 = isset($space1) ? $space1 : ''; // carriage returns before next token, not tParen - $space2 = isset($space2) ? $space2 : ''; // spaces before opening parenthesis - $space3 = isset($space3) ? $space3 : ''; // carriage returns before opening parenthesis - $space4 = isset($space4) ? $space4 : ''; // spaces before closing parenthesis - $space5 = isset($space5) ? $space5 : ''; // carriage returns before closing parenthesis - - switch ($token['name']) { - case 'tAdd': // addition - case 'tConcat': // addition - case 'tDiv': // division - case 'tEQ': // equality - case 'tGE': // greater than or equal - case 'tGT': // greater than - case 'tIsect': // intersection - case 'tLE': // less than or equal - case 'tList': // less than or equal - case 'tLT': // less than - case 'tMul': // multiplication - case 'tNE': // multiplication - case 'tPower': // power - case 'tRange': // range - case 'tSub': // subtraction - $op2 = array_pop($formulaStrings); - $op1 = array_pop($formulaStrings); - $formulaStrings[] = "$op1$space1$space0{$token['data']}$op2"; - unset($space0, $space1); - break; - case 'tUplus': // unary plus - case 'tUminus': // unary minus - $op = array_pop($formulaStrings); - $formulaStrings[] = "$space1$space0{$token['data']}$op"; - unset($space0, $space1); - break; - case 'tPercent': // percent sign - $op = array_pop($formulaStrings); - $formulaStrings[] = "$op$space1$space0{$token['data']}"; - unset($space0, $space1); - break; - case 'tAttrVolatile': // indicates volatile function - case 'tAttrIf': - case 'tAttrSkip': - case 'tAttrChoose': - // token is only important for Excel formula evaluator - // do nothing - break; - case 'tAttrSpace': // space / carriage return - // space will be used when next token arrives, do not alter formulaString stack - switch ($token['data']['spacetype']) { - case 'type0': - $space0 = str_repeat(' ', $token['data']['spacecount']); - break; - case 'type1': - $space1 = str_repeat("\n", $token['data']['spacecount']); - break; - case 'type2': - $space2 = str_repeat(' ', $token['data']['spacecount']); - break; - case 'type3': - $space3 = str_repeat("\n", $token['data']['spacecount']); - break; - case 'type4': - $space4 = str_repeat(' ', $token['data']['spacecount']); - break; - case 'type5': - $space5 = str_repeat("\n", $token['data']['spacecount']); - break; - } - break; - case 'tAttrSum': // SUM function with one parameter - $op = array_pop($formulaStrings); - $formulaStrings[] = "{$space1}{$space0}SUM($op)"; - unset($space0, $space1); - break; - case 'tFunc': // function with fixed number of arguments - case 'tFuncV': // function with variable number of arguments - if ($token['data']['function'] != '') { - // normal function - $ops = array(); // array of operators - for ($i = 0; $i < $token['data']['args']; ++$i) { - $ops[] = array_pop($formulaStrings); - } - $ops = array_reverse($ops); - $formulaStrings[] = "$space1$space0{$token['data']['function']}(" . implode(',', $ops) . ")"; - unset($space0, $space1); - } else { - // add-in function - $ops = array(); // array of operators - for ($i = 0; $i < $token['data']['args'] - 1; ++$i) { - $ops[] = array_pop($formulaStrings); - } - $ops = array_reverse($ops); - $function = array_pop($formulaStrings); - $formulaStrings[] = "$space1$space0$function(" . implode(',', $ops) . ")"; - unset($space0, $space1); - } - break; - case 'tParen': // parenthesis - $expression = array_pop($formulaStrings); - $formulaStrings[] = "$space3$space2($expression$space5$space4)"; - unset($space2, $space3, $space4, $space5); - break; - case 'tArray': // array constant - $constantArray = self::_readBIFF8ConstantArray($additionalData); - $formulaStrings[] = $space1 . $space0 . $constantArray['value']; - $additionalData = substr($additionalData, $constantArray['size']); // bite of chunk of additional data - unset($space0, $space1); - break; - case 'tMemArea': - // bite off chunk of additional data - $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData); - $additionalData = substr($additionalData, $cellRangeAddressList['size']); - $formulaStrings[] = "$space1$space0{$token['data']}"; - unset($space0, $space1); - break; - case 'tArea': // cell range address - case 'tBool': // boolean - case 'tErr': // error code - case 'tInt': // integer - case 'tMemErr': - case 'tMemFunc': - case 'tMissArg': - case 'tName': - case 'tNameX': - case 'tNum': // number - case 'tRef': // single cell reference - case 'tRef3d': // 3d cell reference - case 'tArea3d': // 3d cell range reference - case 'tRefN': - case 'tAreaN': - case 'tStr': // string - $formulaStrings[] = "$space1$space0{$token['data']}"; - unset($space0, $space1); - break; - } - } - $formulaString = $formulaStrings[0]; - - // for debug: dump the human readable formula - //echo '----' . "\n"; - //echo 'Formula: ' . $formulaString; - - return $formulaString; - } - - - /** - * Fetch next token from binary formula data - * - * @param string Formula data - * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas - * @return array - * @throws PHPExcel_Reader_Exception - */ - private function _getNextToken($formulaData, $baseCell = 'A1') - { - // offset: 0; size: 1; token id - $id = ord($formulaData[0]); // token id - $name = false; // initialize token name - - switch ($id) { - case 0x03: $name = 'tAdd'; $size = 1; $data = '+'; break; - case 0x04: $name = 'tSub'; $size = 1; $data = '-'; break; - case 0x05: $name = 'tMul'; $size = 1; $data = '*'; break; - case 0x06: $name = 'tDiv'; $size = 1; $data = '/'; break; - case 0x07: $name = 'tPower'; $size = 1; $data = '^'; break; - case 0x08: $name = 'tConcat'; $size = 1; $data = '&'; break; - case 0x09: $name = 'tLT'; $size = 1; $data = '<'; break; - case 0x0A: $name = 'tLE'; $size = 1; $data = '<='; break; - case 0x0B: $name = 'tEQ'; $size = 1; $data = '='; break; - case 0x0C: $name = 'tGE'; $size = 1; $data = '>='; break; - case 0x0D: $name = 'tGT'; $size = 1; $data = '>'; break; - case 0x0E: $name = 'tNE'; $size = 1; $data = '<>'; break; - case 0x0F: $name = 'tIsect'; $size = 1; $data = ' '; break; - case 0x10: $name = 'tList'; $size = 1; $data = ','; break; - case 0x11: $name = 'tRange'; $size = 1; $data = ':'; break; - case 0x12: $name = 'tUplus'; $size = 1; $data = '+'; break; - case 0x13: $name = 'tUminus'; $size = 1; $data = '-'; break; - case 0x14: $name = 'tPercent'; $size = 1; $data = '%'; break; - case 0x15: // parenthesis - $name = 'tParen'; - $size = 1; - $data = null; - break; - case 0x16: // missing argument - $name = 'tMissArg'; - $size = 1; - $data = ''; - break; - case 0x17: // string - $name = 'tStr'; - // offset: 1; size: var; Unicode string, 8-bit string length - $string = self::_readUnicodeStringShort(substr($formulaData, 1)); - $size = 1 + $string['size']; - $data = self::_UTF8toExcelDoubleQuoted($string['value']); - break; - case 0x19: // Special attribute - // offset: 1; size: 1; attribute type flags: - switch (ord($formulaData[1])) { - case 0x01: - $name = 'tAttrVolatile'; - $size = 4; - $data = null; - break; - case 0x02: - $name = 'tAttrIf'; - $size = 4; - $data = null; - break; - case 0x04: - $name = 'tAttrChoose'; - // offset: 2; size: 2; number of choices in the CHOOSE function ($nc, number of parameters decreased by 1) - $nc = self::_GetInt2d($formulaData, 2); - // offset: 4; size: 2 * $nc - // offset: 4 + 2 * $nc; size: 2 - $size = 2 * $nc + 6; - $data = null; - break; - case 0x08: - $name = 'tAttrSkip'; - $size = 4; - $data = null; - break; - case 0x10: - $name = 'tAttrSum'; - $size = 4; - $data = null; - break; - case 0x40: - case 0x41: - $name = 'tAttrSpace'; - $size = 4; - // offset: 2; size: 2; space type and position - switch (ord($formulaData[2])) { - case 0x00: - $spacetype = 'type0'; - break; - case 0x01: - $spacetype = 'type1'; - break; - case 0x02: - $spacetype = 'type2'; - break; - case 0x03: - $spacetype = 'type3'; - break; - case 0x04: - $spacetype = 'type4'; - break; - case 0x05: - $spacetype = 'type5'; - break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized space type in tAttrSpace token'); - break; - } - // offset: 3; size: 1; number of inserted spaces/carriage returns - $spacecount = ord($formulaData[3]); - - $data = array('spacetype' => $spacetype, 'spacecount' => $spacecount); - break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized attribute flag in tAttr token'); - break; - } - break; - case 0x1C: // error code - // offset: 1; size: 1; error code - $name = 'tErr'; - $size = 2; - $data = self::_mapErrorCode(ord($formulaData[1])); - break; - case 0x1D: // boolean - // offset: 1; size: 1; 0 = false, 1 = true; - $name = 'tBool'; - $size = 2; - $data = ord($formulaData[1]) ? 'TRUE' : 'FALSE'; - break; - case 0x1E: // integer - // offset: 1; size: 2; unsigned 16-bit integer - $name = 'tInt'; - $size = 3; - $data = self::_GetInt2d($formulaData, 1); - break; - case 0x1F: // number - // offset: 1; size: 8; - $name = 'tNum'; - $size = 9; - $data = self::_extractNumber(substr($formulaData, 1)); - $data = str_replace(',', '.', (string)$data); // in case non-English locale - break; - case 0x20: // array constant - case 0x40: - case 0x60: - // offset: 1; size: 7; not used - $name = 'tArray'; - $size = 8; - $data = null; - break; - case 0x21: // function with fixed number of arguments - case 0x41: - case 0x61: - $name = 'tFunc'; - $size = 3; - // offset: 1; size: 2; index to built-in sheet function - switch (self::_GetInt2d($formulaData, 1)) { - case 2: $function = 'ISNA'; $args = 1; break; - case 3: $function = 'ISERROR'; $args = 1; break; - case 10: $function = 'NA'; $args = 0; break; - case 15: $function = 'SIN'; $args = 1; break; - case 16: $function = 'COS'; $args = 1; break; - case 17: $function = 'TAN'; $args = 1; break; - case 18: $function = 'ATAN'; $args = 1; break; - case 19: $function = 'PI'; $args = 0; break; - case 20: $function = 'SQRT'; $args = 1; break; - case 21: $function = 'EXP'; $args = 1; break; - case 22: $function = 'LN'; $args = 1; break; - case 23: $function = 'LOG10'; $args = 1; break; - case 24: $function = 'ABS'; $args = 1; break; - case 25: $function = 'INT'; $args = 1; break; - case 26: $function = 'SIGN'; $args = 1; break; - case 27: $function = 'ROUND'; $args = 2; break; - case 30: $function = 'REPT'; $args = 2; break; - case 31: $function = 'MID'; $args = 3; break; - case 32: $function = 'LEN'; $args = 1; break; - case 33: $function = 'VALUE'; $args = 1; break; - case 34: $function = 'TRUE'; $args = 0; break; - case 35: $function = 'FALSE'; $args = 0; break; - case 38: $function = 'NOT'; $args = 1; break; - case 39: $function = 'MOD'; $args = 2; break; - case 40: $function = 'DCOUNT'; $args = 3; break; - case 41: $function = 'DSUM'; $args = 3; break; - case 42: $function = 'DAVERAGE'; $args = 3; break; - case 43: $function = 'DMIN'; $args = 3; break; - case 44: $function = 'DMAX'; $args = 3; break; - case 45: $function = 'DSTDEV'; $args = 3; break; - case 48: $function = 'TEXT'; $args = 2; break; - case 61: $function = 'MIRR'; $args = 3; break; - case 63: $function = 'RAND'; $args = 0; break; - case 65: $function = 'DATE'; $args = 3; break; - case 66: $function = 'TIME'; $args = 3; break; - case 67: $function = 'DAY'; $args = 1; break; - case 68: $function = 'MONTH'; $args = 1; break; - case 69: $function = 'YEAR'; $args = 1; break; - case 71: $function = 'HOUR'; $args = 1; break; - case 72: $function = 'MINUTE'; $args = 1; break; - case 73: $function = 'SECOND'; $args = 1; break; - case 74: $function = 'NOW'; $args = 0; break; - case 75: $function = 'AREAS'; $args = 1; break; - case 76: $function = 'ROWS'; $args = 1; break; - case 77: $function = 'COLUMNS'; $args = 1; break; - case 83: $function = 'TRANSPOSE'; $args = 1; break; - case 86: $function = 'TYPE'; $args = 1; break; - case 97: $function = 'ATAN2'; $args = 2; break; - case 98: $function = 'ASIN'; $args = 1; break; - case 99: $function = 'ACOS'; $args = 1; break; - case 105: $function = 'ISREF'; $args = 1; break; - case 111: $function = 'CHAR'; $args = 1; break; - case 112: $function = 'LOWER'; $args = 1; break; - case 113: $function = 'UPPER'; $args = 1; break; - case 114: $function = 'PROPER'; $args = 1; break; - case 117: $function = 'EXACT'; $args = 2; break; - case 118: $function = 'TRIM'; $args = 1; break; - case 119: $function = 'REPLACE'; $args = 4; break; - case 121: $function = 'CODE'; $args = 1; break; - case 126: $function = 'ISERR'; $args = 1; break; - case 127: $function = 'ISTEXT'; $args = 1; break; - case 128: $function = 'ISNUMBER'; $args = 1; break; - case 129: $function = 'ISBLANK'; $args = 1; break; - case 130: $function = 'T'; $args = 1; break; - case 131: $function = 'N'; $args = 1; break; - case 140: $function = 'DATEVALUE'; $args = 1; break; - case 141: $function = 'TIMEVALUE'; $args = 1; break; - case 142: $function = 'SLN'; $args = 3; break; - case 143: $function = 'SYD'; $args = 4; break; - case 162: $function = 'CLEAN'; $args = 1; break; - case 163: $function = 'MDETERM'; $args = 1; break; - case 164: $function = 'MINVERSE'; $args = 1; break; - case 165: $function = 'MMULT'; $args = 2; break; - case 184: $function = 'FACT'; $args = 1; break; - case 189: $function = 'DPRODUCT'; $args = 3; break; - case 190: $function = 'ISNONTEXT'; $args = 1; break; - case 195: $function = 'DSTDEVP'; $args = 3; break; - case 196: $function = 'DVARP'; $args = 3; break; - case 198: $function = 'ISLOGICAL'; $args = 1; break; - case 199: $function = 'DCOUNTA'; $args = 3; break; - case 207: $function = 'REPLACEB'; $args = 4; break; - case 210: $function = 'MIDB'; $args = 3; break; - case 211: $function = 'LENB'; $args = 1; break; - case 212: $function = 'ROUNDUP'; $args = 2; break; - case 213: $function = 'ROUNDDOWN'; $args = 2; break; - case 214: $function = 'ASC'; $args = 1; break; - case 215: $function = 'DBCS'; $args = 1; break; - case 221: $function = 'TODAY'; $args = 0; break; - case 229: $function = 'SINH'; $args = 1; break; - case 230: $function = 'COSH'; $args = 1; break; - case 231: $function = 'TANH'; $args = 1; break; - case 232: $function = 'ASINH'; $args = 1; break; - case 233: $function = 'ACOSH'; $args = 1; break; - case 234: $function = 'ATANH'; $args = 1; break; - case 235: $function = 'DGET'; $args = 3; break; - case 244: $function = 'INFO'; $args = 1; break; - case 252: $function = 'FREQUENCY'; $args = 2; break; - case 261: $function = 'ERROR.TYPE'; $args = 1; break; - case 271: $function = 'GAMMALN'; $args = 1; break; - case 273: $function = 'BINOMDIST'; $args = 4; break; - case 274: $function = 'CHIDIST'; $args = 2; break; - case 275: $function = 'CHIINV'; $args = 2; break; - case 276: $function = 'COMBIN'; $args = 2; break; - case 277: $function = 'CONFIDENCE'; $args = 3; break; - case 278: $function = 'CRITBINOM'; $args = 3; break; - case 279: $function = 'EVEN'; $args = 1; break; - case 280: $function = 'EXPONDIST'; $args = 3; break; - case 281: $function = 'FDIST'; $args = 3; break; - case 282: $function = 'FINV'; $args = 3; break; - case 283: $function = 'FISHER'; $args = 1; break; - case 284: $function = 'FISHERINV'; $args = 1; break; - case 285: $function = 'FLOOR'; $args = 2; break; - case 286: $function = 'GAMMADIST'; $args = 4; break; - case 287: $function = 'GAMMAINV'; $args = 3; break; - case 288: $function = 'CEILING'; $args = 2; break; - case 289: $function = 'HYPGEOMDIST'; $args = 4; break; - case 290: $function = 'LOGNORMDIST'; $args = 3; break; - case 291: $function = 'LOGINV'; $args = 3; break; - case 292: $function = 'NEGBINOMDIST'; $args = 3; break; - case 293: $function = 'NORMDIST'; $args = 4; break; - case 294: $function = 'NORMSDIST'; $args = 1; break; - case 295: $function = 'NORMINV'; $args = 3; break; - case 296: $function = 'NORMSINV'; $args = 1; break; - case 297: $function = 'STANDARDIZE'; $args = 3; break; - case 298: $function = 'ODD'; $args = 1; break; - case 299: $function = 'PERMUT'; $args = 2; break; - case 300: $function = 'POISSON'; $args = 3; break; - case 301: $function = 'TDIST'; $args = 3; break; - case 302: $function = 'WEIBULL'; $args = 4; break; - case 303: $function = 'SUMXMY2'; $args = 2; break; - case 304: $function = 'SUMX2MY2'; $args = 2; break; - case 305: $function = 'SUMX2PY2'; $args = 2; break; - case 306: $function = 'CHITEST'; $args = 2; break; - case 307: $function = 'CORREL'; $args = 2; break; - case 308: $function = 'COVAR'; $args = 2; break; - case 309: $function = 'FORECAST'; $args = 3; break; - case 310: $function = 'FTEST'; $args = 2; break; - case 311: $function = 'INTERCEPT'; $args = 2; break; - case 312: $function = 'PEARSON'; $args = 2; break; - case 313: $function = 'RSQ'; $args = 2; break; - case 314: $function = 'STEYX'; $args = 2; break; - case 315: $function = 'SLOPE'; $args = 2; break; - case 316: $function = 'TTEST'; $args = 4; break; - case 325: $function = 'LARGE'; $args = 2; break; - case 326: $function = 'SMALL'; $args = 2; break; - case 327: $function = 'QUARTILE'; $args = 2; break; - case 328: $function = 'PERCENTILE'; $args = 2; break; - case 331: $function = 'TRIMMEAN'; $args = 2; break; - case 332: $function = 'TINV'; $args = 2; break; - case 337: $function = 'POWER'; $args = 2; break; - case 342: $function = 'RADIANS'; $args = 1; break; - case 343: $function = 'DEGREES'; $args = 1; break; - case 346: $function = 'COUNTIF'; $args = 2; break; - case 347: $function = 'COUNTBLANK'; $args = 1; break; - case 350: $function = 'ISPMT'; $args = 4; break; - case 351: $function = 'DATEDIF'; $args = 3; break; - case 352: $function = 'DATESTRING'; $args = 1; break; - case 353: $function = 'NUMBERSTRING'; $args = 2; break; - case 360: $function = 'PHONETIC'; $args = 1; break; - case 368: $function = 'BAHTTEXT'; $args = 1; break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); - break; - } - $data = array('function' => $function, 'args' => $args); - break; - case 0x22: // function with variable number of arguments - case 0x42: - case 0x62: - $name = 'tFuncV'; - $size = 4; - // offset: 1; size: 1; number of arguments - $args = ord($formulaData[1]); - // offset: 2: size: 2; index to built-in sheet function - $index = self::_GetInt2d($formulaData, 2); - switch ($index) { - case 0: $function = 'COUNT'; break; - case 1: $function = 'IF'; break; - case 4: $function = 'SUM'; break; - case 5: $function = 'AVERAGE'; break; - case 6: $function = 'MIN'; break; - case 7: $function = 'MAX'; break; - case 8: $function = 'ROW'; break; - case 9: $function = 'COLUMN'; break; - case 11: $function = 'NPV'; break; - case 12: $function = 'STDEV'; break; - case 13: $function = 'DOLLAR'; break; - case 14: $function = 'FIXED'; break; - case 28: $function = 'LOOKUP'; break; - case 29: $function = 'INDEX'; break; - case 36: $function = 'AND'; break; - case 37: $function = 'OR'; break; - case 46: $function = 'VAR'; break; - case 49: $function = 'LINEST'; break; - case 50: $function = 'TREND'; break; - case 51: $function = 'LOGEST'; break; - case 52: $function = 'GROWTH'; break; - case 56: $function = 'PV'; break; - case 57: $function = 'FV'; break; - case 58: $function = 'NPER'; break; - case 59: $function = 'PMT'; break; - case 60: $function = 'RATE'; break; - case 62: $function = 'IRR'; break; - case 64: $function = 'MATCH'; break; - case 70: $function = 'WEEKDAY'; break; - case 78: $function = 'OFFSET'; break; - case 82: $function = 'SEARCH'; break; - case 100: $function = 'CHOOSE'; break; - case 101: $function = 'HLOOKUP'; break; - case 102: $function = 'VLOOKUP'; break; - case 109: $function = 'LOG'; break; - case 115: $function = 'LEFT'; break; - case 116: $function = 'RIGHT'; break; - case 120: $function = 'SUBSTITUTE'; break; - case 124: $function = 'FIND'; break; - case 125: $function = 'CELL'; break; - case 144: $function = 'DDB'; break; - case 148: $function = 'INDIRECT'; break; - case 167: $function = 'IPMT'; break; - case 168: $function = 'PPMT'; break; - case 169: $function = 'COUNTA'; break; - case 183: $function = 'PRODUCT'; break; - case 193: $function = 'STDEVP'; break; - case 194: $function = 'VARP'; break; - case 197: $function = 'TRUNC'; break; - case 204: $function = 'USDOLLAR'; break; - case 205: $function = 'FINDB'; break; - case 206: $function = 'SEARCHB'; break; - case 208: $function = 'LEFTB'; break; - case 209: $function = 'RIGHTB'; break; - case 216: $function = 'RANK'; break; - case 219: $function = 'ADDRESS'; break; - case 220: $function = 'DAYS360'; break; - case 222: $function = 'VDB'; break; - case 227: $function = 'MEDIAN'; break; - case 228: $function = 'SUMPRODUCT'; break; - case 247: $function = 'DB'; break; - case 255: $function = ''; break; - case 269: $function = 'AVEDEV'; break; - case 270: $function = 'BETADIST'; break; - case 272: $function = 'BETAINV'; break; - case 317: $function = 'PROB'; break; - case 318: $function = 'DEVSQ'; break; - case 319: $function = 'GEOMEAN'; break; - case 320: $function = 'HARMEAN'; break; - case 321: $function = 'SUMSQ'; break; - case 322: $function = 'KURT'; break; - case 323: $function = 'SKEW'; break; - case 324: $function = 'ZTEST'; break; - case 329: $function = 'PERCENTRANK'; break; - case 330: $function = 'MODE'; break; - case 336: $function = 'CONCATENATE'; break; - case 344: $function = 'SUBTOTAL'; break; - case 345: $function = 'SUMIF'; break; - case 354: $function = 'ROMAN'; break; - case 358: $function = 'GETPIVOTDATA'; break; - case 359: $function = 'HYPERLINK'; break; - case 361: $function = 'AVERAGEA'; break; - case 362: $function = 'MAXA'; break; - case 363: $function = 'MINA'; break; - case 364: $function = 'STDEVPA'; break; - case 365: $function = 'VARPA'; break; - case 366: $function = 'STDEVA'; break; - case 367: $function = 'VARA'; break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); - break; - } - $data = array('function' => $function, 'args' => $args); - break; - case 0x23: // index to defined name - case 0x43: - case 0x63: - $name = 'tName'; - $size = 5; - // offset: 1; size: 2; one-based index to definedname record - $definedNameIndex = self::_GetInt2d($formulaData, 1) - 1; - // offset: 2; size: 2; not used - $data = $this->_definedname[$definedNameIndex]['name']; - break; - case 0x24: // single cell reference e.g. A5 - case 0x44: - case 0x64: - $name = 'tRef'; - $size = 5; - $data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4)); - break; - case 0x25: // cell range reference to cells in the same sheet (2d) - case 0x45: - case 0x65: - $name = 'tArea'; - $size = 9; - $data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8)); - break; - case 0x26: // Constant reference sub-expression - case 0x46: - case 0x66: - $name = 'tMemArea'; - // offset: 1; size: 4; not used - // offset: 5; size: 2; size of the following subexpression - $subSize = self::_GetInt2d($formulaData, 5); - $size = 7 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); - break; - case 0x27: // Deleted constant reference sub-expression - case 0x47: - case 0x67: - $name = 'tMemErr'; - // offset: 1; size: 4; not used - // offset: 5; size: 2; size of the following subexpression - $subSize = self::_GetInt2d($formulaData, 5); - $size = 7 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); - break; - case 0x29: // Variable reference sub-expression - case 0x49: - case 0x69: - $name = 'tMemFunc'; - // offset: 1; size: 2; size of the following sub-expression - $subSize = self::_GetInt2d($formulaData, 1); - $size = 3 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize)); - break; - - case 0x2C: // Relative 2d cell reference reference, used in shared formulas and some other places - case 0x4C: - case 0x6C: - $name = 'tRefN'; - $size = 5; - $data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell); - break; - - case 0x2D: // Relative 2d range reference - case 0x4D: - case 0x6D: - $name = 'tAreaN'; - $size = 9; - $data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell); - break; - - case 0x39: // External name - case 0x59: - case 0x79: - $name = 'tNameX'; - $size = 7; - // offset: 1; size: 2; index to REF entry in EXTERNSHEET record - // offset: 3; size: 2; one-based index to DEFINEDNAME or EXTERNNAME record - $index = self::_GetInt2d($formulaData, 3); - // assume index is to EXTERNNAME record - $data = $this->_externalNames[$index - 1]['name']; - // offset: 5; size: 2; not used - break; - - case 0x3A: // 3d reference to cell - case 0x5A: - case 0x7A: - $name = 'tRef3d'; - $size = 7; - - try { - // offset: 1; size: 2; index to REF entry - $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); - // offset: 3; size: 4; cell address - $cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4)); - - $data = "$sheetRange!$cellAddress"; - } catch (PHPExcel_Exception $e) { - // deleted sheet reference - $data = '#REF!'; - } - - break; - case 0x3B: // 3d reference to cell range - case 0x5B: - case 0x7B: - $name = 'tArea3d'; - $size = 11; - - try { - // offset: 1; size: 2; index to REF entry - $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); - // offset: 3; size: 8; cell address - $cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8)); - - $data = "$sheetRange!$cellRangeAddress"; - } catch (PHPExcel_Exception $e) { - // deleted sheet reference - $data = '#REF!'; - } - - break; - // Unknown cases // don't know how to deal with - default: - throw new PHPExcel_Reader_Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula'); - break; - } - - return array( - 'id' => $id, - 'name' => $name, - 'size' => $size, - 'data' => $data, - ); - } - - - /** - * Reads a cell address in BIFF8 e.g. 'A2' or '$A$2' - * section 3.3.4 - * - * @param string $cellAddressStructure - * @return string - */ - private function _readBIFF8CellAddress($cellAddressStructure) - { - // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) - $row = self::_GetInt2d($cellAddressStructure, 0) + 1; - - // offset: 2; size: 2; index to column or column offset + relative flags - - // bit: 7-0; mask 0x00FF; column index - $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2)); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { - $column = '$' . $column; - } - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { - $row = '$' . $row; - } - - return $column . $row; - } - - - /** - * Reads a cell address in BIFF8 for shared formulas. Uses positive and negative values for row and column - * to indicate offsets from a base cell - * section 3.3.4 - * - * @param string $cellAddressStructure - * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas - * @return string - */ - private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') - { - list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); - $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; - - // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) - $rowIndex = self::_GetInt2d($cellAddressStructure, 0); - $row = self::_GetInt2d($cellAddressStructure, 0) + 1; - - // offset: 2; size: 2; index to column or column offset + relative flags - - // bit: 7-0; mask 0x00FF; column index - $colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { - $column = PHPExcel_Cell::stringFromColumnIndex($colIndex); - $column = '$' . $column; - } else { - $colIndex = ($colIndex <= 127) ? $colIndex : $colIndex - 256; - $column = PHPExcel_Cell::stringFromColumnIndex($baseCol + $colIndex); - } - - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { - $row = '$' . $row; - } else { - $rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536; - $row = $baseRow + $rowIndex; - } - - return $column . $row; - } - - - /** - * Reads a cell range address in BIFF5 e.g. 'A2:B6' or 'A1' - * always fixed range - * section 2.5.14 - * - * @param string $subData - * @return string - * @throws PHPExcel_Reader_Exception - */ - private function _readBIFF5CellRangeAddressFixed($subData) - { - // offset: 0; size: 2; index to first row - $fr = self::_GetInt2d($subData, 0) + 1; - - // offset: 2; size: 2; index to last row - $lr = self::_GetInt2d($subData, 2) + 1; - - // offset: 4; size: 1; index to first column - $fc = ord($subData{4}); - - // offset: 5; size: 1; index to last column - $lc = ord($subData{5}); - - // check values - if ($fr > $lr || $fc > $lc) { - throw new PHPExcel_Reader_Exception('Not a cell range address'); - } - - // column index to letter - $fc = PHPExcel_Cell::stringFromColumnIndex($fc); - $lc = PHPExcel_Cell::stringFromColumnIndex($lc); - - if ($fr == $lr and $fc == $lc) { - return "$fc$fr"; - } - return "$fc$fr:$lc$lr"; - } - - - /** - * Reads a cell range address in BIFF8 e.g. 'A2:B6' or 'A1' - * always fixed range - * section 2.5.14 - * - * @param string $subData - * @return string - * @throws PHPExcel_Reader_Exception - */ - private function _readBIFF8CellRangeAddressFixed($subData) - { - // offset: 0; size: 2; index to first row - $fr = self::_GetInt2d($subData, 0) + 1; - - // offset: 2; size: 2; index to last row - $lr = self::_GetInt2d($subData, 2) + 1; - - // offset: 4; size: 2; index to first column - $fc = self::_GetInt2d($subData, 4); - - // offset: 6; size: 2; index to last column - $lc = self::_GetInt2d($subData, 6); - - // check values - if ($fr > $lr || $fc > $lc) { - throw new PHPExcel_Reader_Exception('Not a cell range address'); - } - - // column index to letter - $fc = PHPExcel_Cell::stringFromColumnIndex($fc); - $lc = PHPExcel_Cell::stringFromColumnIndex($lc); - - if ($fr == $lr and $fc == $lc) { - return "$fc$fr"; - } - return "$fc$fr:$lc$lr"; - } - - - /** - * Reads a cell range address in BIFF8 e.g. 'A2:B6' or '$A$2:$B$6' - * there are flags indicating whether column/row index is relative - * section 3.3.4 - * - * @param string $subData - * @return string - */ - private function _readBIFF8CellRangeAddress($subData) - { - // todo: if cell range is just a single cell, should this funciton - // not just return e.g. 'A1' and not 'A1:A1' ? - - // offset: 0; size: 2; index to first row (0... 65535) (or offset (-32768... 32767)) - $fr = self::_GetInt2d($subData, 0) + 1; - - // offset: 2; size: 2; index to last row (0... 65535) (or offset (-32768... 32767)) - $lr = self::_GetInt2d($subData, 2) + 1; - - // offset: 4; size: 2; index to first column or column offset + relative flags - - // bit: 7-0; mask 0x00FF; column index - $fc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 4)); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 4))) { - $fc = '$' . $fc; - } - - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 4))) { - $fr = '$' . $fr; - } - - // offset: 6; size: 2; index to last column or column offset + relative flags - - // bit: 7-0; mask 0x00FF; column index - $lc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 6)); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 6))) { - $lc = '$' . $lc; - } - - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 6))) { - $lr = '$' . $lr; - } - - return "$fc$fr:$lc$lr"; - } - - - /** - * Reads a cell range address in BIFF8 for shared formulas. Uses positive and negative values for row and column - * to indicate offsets from a base cell - * section 3.3.4 - * - * @param string $subData - * @param string $baseCell Base cell - * @return string Cell range address - */ - private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') - { - list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); - $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; - - // TODO: if cell range is just a single cell, should this funciton - // not just return e.g. 'A1' and not 'A1:A1' ? - - // offset: 0; size: 2; first row - $frIndex = self::_GetInt2d($subData, 0); // adjust below - - // offset: 2; size: 2; relative index to first row (0... 65535) should be treated as offset (-32768... 32767) - $lrIndex = self::_GetInt2d($subData, 2); // adjust below - - // offset: 4; size: 2; first column with relative/absolute flags - - // bit: 7-0; mask 0x00FF; column index - $fcIndex = 0x00FF & self::_GetInt2d($subData, 4); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 4))) { - // absolute column index - $fc = PHPExcel_Cell::stringFromColumnIndex($fcIndex); - $fc = '$' . $fc; - } else { - // column offset - $fcIndex = ($fcIndex <= 127) ? $fcIndex : $fcIndex - 256; - $fc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $fcIndex); - } - - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 4))) { - // absolute row index - $fr = $frIndex + 1; - $fr = '$' . $fr; - } else { - // row offset - $frIndex = ($frIndex <= 32767) ? $frIndex : $frIndex - 65536; - $fr = $baseRow + $frIndex; - } - - // offset: 6; size: 2; last column with relative/absolute flags - - // bit: 7-0; mask 0x00FF; column index - $lcIndex = 0x00FF & self::_GetInt2d($subData, 6); - $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; - $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 6))) { - // absolute column index - $lc = PHPExcel_Cell::stringFromColumnIndex($lcIndex); - $lc = '$' . $lc; - } else { - // column offset - $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; - $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); - } - - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 6))) { - // absolute row index - $lr = $lrIndex + 1; - $lr = '$' . $lr; - } else { - // row offset - $lrIndex = ($lrIndex <= 32767) ? $lrIndex : $lrIndex - 65536; - $lr = $baseRow + $lrIndex; - } - - return "$fc$fr:$lc$lr"; - } - - - /** - * Read BIFF8 cell range address list - * section 2.5.15 - * - * @param string $subData - * @return array - */ - private function _readBIFF8CellRangeAddressList($subData) - { - $cellRangeAddresses = array(); - - // offset: 0; size: 2; number of the following cell range addresses - $nm = self::_GetInt2d($subData, 0); - - $offset = 2; - // offset: 2; size: 8 * $nm; list of $nm (fixed) cell range addresses - for ($i = 0; $i < $nm; ++$i) { - $cellRangeAddresses[] = $this->_readBIFF8CellRangeAddressFixed(substr($subData, $offset, 8)); - $offset += 8; - } - - return array( - 'size' => 2 + 8 * $nm, - 'cellRangeAddresses' => $cellRangeAddresses, - ); - } - - - /** - * Read BIFF5 cell range address list - * section 2.5.15 - * - * @param string $subData - * @return array - */ - private function _readBIFF5CellRangeAddressList($subData) - { - $cellRangeAddresses = array(); - - // offset: 0; size: 2; number of the following cell range addresses - $nm = self::_GetInt2d($subData, 0); - - $offset = 2; - // offset: 2; size: 6 * $nm; list of $nm (fixed) cell range addresses - for ($i = 0; $i < $nm; ++$i) { - $cellRangeAddresses[] = $this->_readBIFF5CellRangeAddressFixed(substr($subData, $offset, 6)); - $offset += 6; - } - - return array( - 'size' => 2 + 6 * $nm, - 'cellRangeAddresses' => $cellRangeAddresses, - ); - } - - - /** - * Get a sheet range like Sheet1:Sheet3 from REF index - * Note: If there is only one sheet in the range, one gets e.g Sheet1 - * It can also happen that the REF structure uses the -1 (FFFF) code to indicate deleted sheets, - * in which case an PHPExcel_Reader_Exception is thrown - * - * @param int $index - * @return string|false - * @throws PHPExcel_Reader_Exception - */ - private function _readSheetRangeByRefIndex($index) - { - if (isset($this->_ref[$index])) { - - $type = $this->_externalBooks[$this->_ref[$index]['externalBookIndex']]['type']; - - switch ($type) { - case 'internal': - // check if we have a deleted 3d reference - if ($this->_ref[$index]['firstSheetIndex'] == 0xFFFF or $this->_ref[$index]['lastSheetIndex'] == 0xFFFF) { - throw new PHPExcel_Reader_Exception('Deleted sheet reference'); - } - - // we have normal sheet range (collapsed or uncollapsed) - $firstSheetName = $this->_sheets[$this->_ref[$index]['firstSheetIndex']]['name']; - $lastSheetName = $this->_sheets[$this->_ref[$index]['lastSheetIndex']]['name']; - - if ($firstSheetName == $lastSheetName) { - // collapsed sheet range - $sheetRange = $firstSheetName; - } else { - $sheetRange = "$firstSheetName:$lastSheetName"; - } - - // escape the single-quotes - $sheetRange = str_replace("'", "''", $sheetRange); - - // if there are special characters, we need to enclose the range in single-quotes - // todo: check if we have identified the whole set of special characters - // it seems that the following characters are not accepted for sheet names - // and we may assume that they are not present: []*/:\? - if (preg_match("/[ !\"@#£$%&{()}<>=+'|^,;-]/", $sheetRange)) { - $sheetRange = "'$sheetRange'"; - } - - return $sheetRange; - break; - - default: - // TODO: external sheet support - throw new PHPExcel_Reader_Exception('Excel5 reader only supports internal sheets in fomulas'); - break; - } - } - return false; - } - - - /** - * read BIFF8 constant value array from array data - * returns e.g. array('value' => '{1,2;3,4}', 'size' => 40} - * section 2.5.8 - * - * @param string $arrayData - * @return array - */ - private static function _readBIFF8ConstantArray($arrayData) - { - // offset: 0; size: 1; number of columns decreased by 1 - $nc = ord($arrayData[0]); - - // offset: 1; size: 2; number of rows decreased by 1 - $nr = self::_GetInt2d($arrayData, 1); - $size = 3; // initialize - $arrayData = substr($arrayData, 3); - - // offset: 3; size: var; list of ($nc + 1) * ($nr + 1) constant values - $matrixChunks = array(); - for ($r = 1; $r <= $nr + 1; ++$r) { - $items = array(); - for ($c = 1; $c <= $nc + 1; ++$c) { - $constant = self::_readBIFF8Constant($arrayData); - $items[] = $constant['value']; - $arrayData = substr($arrayData, $constant['size']); - $size += $constant['size']; - } - $matrixChunks[] = implode(',', $items); // looks like e.g. '1,"hello"' - } - $matrix = '{' . implode(';', $matrixChunks) . '}'; - - return array( - 'value' => $matrix, - 'size' => $size, - ); - } - - - /** - * read BIFF8 constant value which may be 'Empty Value', 'Number', 'String Value', 'Boolean Value', 'Error Value' - * section 2.5.7 - * returns e.g. array('value' => '5', 'size' => 9) - * - * @param string $valueData - * @return array - */ - private static function _readBIFF8Constant($valueData) - { - // offset: 0; size: 1; identifier for type of constant - $identifier = ord($valueData[0]); - - switch ($identifier) { - case 0x00: // empty constant (what is this?) - $value = ''; - $size = 9; - break; - case 0x01: // number - // offset: 1; size: 8; IEEE 754 floating-point value - $value = self::_extractNumber(substr($valueData, 1, 8)); - $size = 9; - break; - case 0x02: // string value - // offset: 1; size: var; Unicode string, 16-bit string length - $string = self::_readUnicodeStringLong(substr($valueData, 1)); - $value = '"' . $string['value'] . '"'; - $size = 1 + $string['size']; - break; - case 0x04: // boolean - // offset: 1; size: 1; 0 = FALSE, 1 = TRUE - if (ord($valueData[1])) { - $value = 'TRUE'; - } else { - $value = 'FALSE'; - } - $size = 9; - break; - case 0x10: // error code - // offset: 1; size: 1; error code - $value = self::_mapErrorCode(ord($valueData[1])); - $size = 9; - break; - } - return array( - 'value' => $value, - 'size' => $size, - ); - } - - - /** - * Extract RGB color - * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.4 - * - * @param string $rgb Encoded RGB value (4 bytes) - * @return array - */ - private static function _readRGB($rgb) - { - // offset: 0; size 1; Red component - $r = ord($rgb{0}); - - // offset: 1; size: 1; Green component - $g = ord($rgb{1}); - - // offset: 2; size: 1; Blue component - $b = ord($rgb{2}); - - // HEX notation, e.g. 'FF00FC' - $rgb = sprintf('%02X%02X%02X', $r, $g, $b); - - return array('rgb' => $rgb); - } - - - /** - * Read byte string (8-bit string length) - * OpenOffice documentation: 2.5.2 - * - * @param string $subData - * @return array - */ - private function _readByteStringShort($subData) - { - // offset: 0; size: 1; length of the string (character count) - $ln = ord($subData[0]); - - // offset: 1: size: var; character array (8-bit characters) - $value = $this->_decodeCodepage(substr($subData, 1, $ln)); - - return array( - 'value' => $value, - 'size' => 1 + $ln, // size in bytes of data structure - ); - } - - - /** - * Read byte string (16-bit string length) - * OpenOffice documentation: 2.5.2 - * - * @param string $subData - * @return array - */ - private function _readByteStringLong($subData) - { - // offset: 0; size: 2; length of the string (character count) - $ln = self::_GetInt2d($subData, 0); - - // offset: 2: size: var; character array (8-bit characters) - $value = $this->_decodeCodepage(substr($subData, 2)); - - //return $string; - return array( - 'value' => $value, - 'size' => 2 + $ln, // size in bytes of data structure - ); - } - - - /** - * Extracts an Excel Unicode short string (8-bit string length) - * OpenOffice documentation: 2.5.3 - * function will automatically find out where the Unicode string ends. - * - * @param string $subData - * @return array - */ - private static function _readUnicodeStringShort($subData) - { - $value = ''; - - // offset: 0: size: 1; length of the string (character count) - $characterCount = ord($subData[0]); - - $string = self::_readUnicodeString(substr($subData, 1), $characterCount); - - // add 1 for the string length - $string['size'] += 1; - - return $string; - } - - - /** - * Extracts an Excel Unicode long string (16-bit string length) - * OpenOffice documentation: 2.5.3 - * this function is under construction, needs to support rich text, and Asian phonetic settings - * - * @param string $subData - * @return array - */ - private static function _readUnicodeStringLong($subData) - { - $value = ''; - - // offset: 0: size: 2; length of the string (character count) - $characterCount = self::_GetInt2d($subData, 0); - - $string = self::_readUnicodeString(substr($subData, 2), $characterCount); - - // add 2 for the string length - $string['size'] += 2; - - return $string; - } - - - /** - * Read Unicode string with no string length field, but with known character count - * this function is under construction, needs to support rich text, and Asian phonetic settings - * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.3 - * - * @param string $subData - * @param int $characterCount - * @return array - */ - private static function _readUnicodeString($subData, $characterCount) - { - $value = ''; - - // offset: 0: size: 1; option flags - - // bit: 0; mask: 0x01; character compression (0 = compressed 8-bit, 1 = uncompressed 16-bit) - $isCompressed = !((0x01 & ord($subData[0])) >> 0); - - // bit: 2; mask: 0x04; Asian phonetic settings - $hasAsian = (0x04) & ord($subData[0]) >> 2; - - // bit: 3; mask: 0x08; Rich-Text settings - $hasRichText = (0x08) & ord($subData[0]) >> 3; - - // offset: 1: size: var; character array - // this offset assumes richtext and Asian phonetic settings are off which is generally wrong - // needs to be fixed - $value = self::_encodeUTF16(substr($subData, 1, $isCompressed ? $characterCount : 2 * $characterCount), $isCompressed); - - return array( - 'value' => $value, - 'size' => $isCompressed ? 1 + $characterCount : 1 + 2 * $characterCount, // the size in bytes including the option flags - ); - } - - - /** - * Convert UTF-8 string to string surounded by double quotes. Used for explicit string tokens in formulas. - * Example: hello"world --> "hello""world" - * - * @param string $value UTF-8 encoded string - * @return string - */ - private static function _UTF8toExcelDoubleQuoted($value) - { - return '"' . str_replace('"', '""', $value) . '"'; - } - - - /** - * Reads first 8 bytes of a string and return IEEE 754 float - * - * @param string $data Binary string that is at least 8 bytes long - * @return float - */ - private static function _extractNumber($data) - { - $rknumhigh = self::_GetInt4d($data, 4); - $rknumlow = self::_GetInt4d($data, 0); - $sign = ($rknumhigh & 0x80000000) >> 31; - $exp = (($rknumhigh & 0x7ff00000) >> 20) - 1023; - $mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); - $mantissalow1 = ($rknumlow & 0x80000000) >> 31; - $mantissalow2 = ($rknumlow & 0x7fffffff); - $value = $mantissa / pow( 2 , (20 - $exp)); - - if ($mantissalow1 != 0) { - $value += 1 / pow (2 , (21 - $exp)); - } - - $value += $mantissalow2 / pow (2 , (52 - $exp)); - if ($sign) { - $value *= -1; - } - - return $value; - } - - - private static function _GetIEEE754($rknum) - { - if (($rknum & 0x02) != 0) { - $value = $rknum >> 2; - } else { - // changes by mmp, info on IEEE754 encoding from - // research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html - // The RK format calls for using only the most significant 30 bits - // of the 64 bit floating point value. The other 34 bits are assumed - // to be 0 so we use the upper 30 bits of $rknum as follows... - $sign = ($rknum & 0x80000000) >> 31; - $exp = ($rknum & 0x7ff00000) >> 20; - $mantissa = (0x100000 | ($rknum & 0x000ffffc)); - $value = $mantissa / pow( 2 , (20- ($exp - 1023))); - if ($sign) { - $value = -1 * $value; - } - //end of changes by mmp - } - if (($rknum & 0x01) != 0) { - $value /= 100; - } - return $value; - } - - - /** - * Get UTF-8 string from (compressed or uncompressed) UTF-16 string - * - * @param string $string - * @param bool $compressed - * @return string - */ - private static function _encodeUTF16($string, $compressed = '') - { - if ($compressed) { - $string = self::_uncompressByteString($string); - } - - return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE'); - } - - - /** - * Convert UTF-16 string in compressed notation to uncompressed form. Only used for BIFF8. - * - * @param string $string - * @return string - */ - private static function _uncompressByteString($string) - { - $uncompressedString = ''; - $strLen = strlen($string); - for ($i = 0; $i < $strLen; ++$i) { - $uncompressedString .= $string[$i] . "\0"; - } - - return $uncompressedString; - } - - - /** - * Convert string to UTF-8. Only used for BIFF5. - * - * @param string $string - * @return string - */ - private function _decodeCodepage($string) - { - return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->_codepage); - } - - - /** - * Read 16-bit unsigned integer - * - * @param string $data - * @param int $pos - * @return int - */ - public static function _GetInt2d($data, $pos) - { - return ord($data[$pos]) | (ord($data[$pos+1]) << 8); - } - - - /** - * Read 32-bit signed integer - * - * @param string $data - * @param int $pos - * @return int - */ - public static function _GetInt4d($data, $pos) - { - // FIX: represent numbers correctly on 64-bit system - // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 - // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems - $_or_24 = ord($data[$pos + 3]); - if ($_or_24 >= 128) { - // negative number - $_ord_24 = -abs((256 - $_or_24) << 24); - } else { - $_ord_24 = ($_or_24 & 127) << 24; - } - return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24; - } - - - /** - * Read color - * - * @param int $color Indexed color - * @param array $palette Color palette - * @return array RGB color value, example: array('rgb' => 'FF0000') - */ - private static function _readColor($color,$palette,$version) - { - if ($color <= 0x07 || $color >= 0x40) { - // special built-in color - return self::_mapBuiltInColor($color); - } elseif (isset($palette) && isset($palette[$color - 8])) { - // palette color, color index 0x08 maps to pallete index 0 - return $palette[$color - 8]; - } else { - // default color table - if ($version == self::XLS_BIFF8) { - return self::_mapColor($color); - } else { - // BIFF5 - return self::_mapColorBIFF5($color); - } - } - - return $color; - } - - - /** - * Map border style - * OpenOffice documentation: 2.5.11 - * - * @param int $index - * @return string - */ - private static function _mapBorderStyle($index) - { - switch ($index) { - case 0x00: return PHPExcel_Style_Border::BORDER_NONE; - case 0x01: return PHPExcel_Style_Border::BORDER_THIN; - case 0x02: return PHPExcel_Style_Border::BORDER_MEDIUM; - case 0x03: return PHPExcel_Style_Border::BORDER_DASHED; - case 0x04: return PHPExcel_Style_Border::BORDER_DOTTED; - case 0x05: return PHPExcel_Style_Border::BORDER_THICK; - case 0x06: return PHPExcel_Style_Border::BORDER_DOUBLE; - case 0x07: return PHPExcel_Style_Border::BORDER_HAIR; - case 0x08: return PHPExcel_Style_Border::BORDER_MEDIUMDASHED; - case 0x09: return PHPExcel_Style_Border::BORDER_DASHDOT; - case 0x0A: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; - case 0x0B: return PHPExcel_Style_Border::BORDER_DASHDOTDOT; - case 0x0C: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; - case 0x0D: return PHPExcel_Style_Border::BORDER_SLANTDASHDOT; - default: return PHPExcel_Style_Border::BORDER_NONE; - } - } - - - /** - * Get fill pattern from index - * OpenOffice documentation: 2.5.12 - * - * @param int $index - * @return string - */ - private static function _mapFillPattern($index) - { - switch ($index) { - case 0x00: return PHPExcel_Style_Fill::FILL_NONE; - case 0x01: return PHPExcel_Style_Fill::FILL_SOLID; - case 0x02: return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; - case 0x03: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; - case 0x04: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; - case 0x05: return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; - case 0x06: return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; - case 0x07: return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; - case 0x08: return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; - case 0x09: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; - case 0x0A: return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; - case 0x0B: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; - case 0x0C: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; - case 0x0D: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; - case 0x0E: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; - case 0x0F: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; - case 0x10: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; - case 0x11: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; - case 0x12: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; - default: return PHPExcel_Style_Fill::FILL_NONE; - } - } - - - /** - * Map error code, e.g. '#N/A' - * - * @param int $subData - * @return string - */ - private static function _mapErrorCode($subData) - { - switch ($subData) { - case 0x00: return '#NULL!'; break; - case 0x07: return '#DIV/0!'; break; - case 0x0F: return '#VALUE!'; break; - case 0x17: return '#REF!'; break; - case 0x1D: return '#NAME?'; break; - case 0x24: return '#NUM!'; break; - case 0x2A: return '#N/A'; break; - default: return false; - } - } - - - /** - * Map built-in color to RGB value - * - * @param int $color Indexed color - * @return array - */ - private static function _mapBuiltInColor($color) - { - switch ($color) { - case 0x00: return array('rgb' => '000000'); - case 0x01: return array('rgb' => 'FFFFFF'); - case 0x02: return array('rgb' => 'FF0000'); - case 0x03: return array('rgb' => '00FF00'); - case 0x04: return array('rgb' => '0000FF'); - case 0x05: return array('rgb' => 'FFFF00'); - case 0x06: return array('rgb' => 'FF00FF'); - case 0x07: return array('rgb' => '00FFFF'); - case 0x40: return array('rgb' => '000000'); // system window text color - case 0x41: return array('rgb' => 'FFFFFF'); // system window background color - default: return array('rgb' => '000000'); - } - } - - - /** - * Map color array from BIFF5 built-in color index - * - * @param int $subData - * @return array - */ - private static function _mapColorBIFF5($subData) - { - switch ($subData) { - case 0x08: return array('rgb' => '000000'); - case 0x09: return array('rgb' => 'FFFFFF'); - case 0x0A: return array('rgb' => 'FF0000'); - case 0x0B: return array('rgb' => '00FF00'); - case 0x0C: return array('rgb' => '0000FF'); - case 0x0D: return array('rgb' => 'FFFF00'); - case 0x0E: return array('rgb' => 'FF00FF'); - case 0x0F: return array('rgb' => '00FFFF'); - case 0x10: return array('rgb' => '800000'); - case 0x11: return array('rgb' => '008000'); - case 0x12: return array('rgb' => '000080'); - case 0x13: return array('rgb' => '808000'); - case 0x14: return array('rgb' => '800080'); - case 0x15: return array('rgb' => '008080'); - case 0x16: return array('rgb' => 'C0C0C0'); - case 0x17: return array('rgb' => '808080'); - case 0x18: return array('rgb' => '8080FF'); - case 0x19: return array('rgb' => '802060'); - case 0x1A: return array('rgb' => 'FFFFC0'); - case 0x1B: return array('rgb' => 'A0E0F0'); - case 0x1C: return array('rgb' => '600080'); - case 0x1D: return array('rgb' => 'FF8080'); - case 0x1E: return array('rgb' => '0080C0'); - case 0x1F: return array('rgb' => 'C0C0FF'); - case 0x20: return array('rgb' => '000080'); - case 0x21: return array('rgb' => 'FF00FF'); - case 0x22: return array('rgb' => 'FFFF00'); - case 0x23: return array('rgb' => '00FFFF'); - case 0x24: return array('rgb' => '800080'); - case 0x25: return array('rgb' => '800000'); - case 0x26: return array('rgb' => '008080'); - case 0x27: return array('rgb' => '0000FF'); - case 0x28: return array('rgb' => '00CFFF'); - case 0x29: return array('rgb' => '69FFFF'); - case 0x2A: return array('rgb' => 'E0FFE0'); - case 0x2B: return array('rgb' => 'FFFF80'); - case 0x2C: return array('rgb' => 'A6CAF0'); - case 0x2D: return array('rgb' => 'DD9CB3'); - case 0x2E: return array('rgb' => 'B38FEE'); - case 0x2F: return array('rgb' => 'E3E3E3'); - case 0x30: return array('rgb' => '2A6FF9'); - case 0x31: return array('rgb' => '3FB8CD'); - case 0x32: return array('rgb' => '488436'); - case 0x33: return array('rgb' => '958C41'); - case 0x34: return array('rgb' => '8E5E42'); - case 0x35: return array('rgb' => 'A0627A'); - case 0x36: return array('rgb' => '624FAC'); - case 0x37: return array('rgb' => '969696'); - case 0x38: return array('rgb' => '1D2FBE'); - case 0x39: return array('rgb' => '286676'); - case 0x3A: return array('rgb' => '004500'); - case 0x3B: return array('rgb' => '453E01'); - case 0x3C: return array('rgb' => '6A2813'); - case 0x3D: return array('rgb' => '85396A'); - case 0x3E: return array('rgb' => '4A3285'); - case 0x3F: return array('rgb' => '424242'); - default: return array('rgb' => '000000'); - } - } - - - /** - * Map color array from BIFF8 built-in color index - * - * @param int $subData - * @return array - */ - private static function _mapColor($subData) - { - switch ($subData) { - case 0x08: return array('rgb' => '000000'); - case 0x09: return array('rgb' => 'FFFFFF'); - case 0x0A: return array('rgb' => 'FF0000'); - case 0x0B: return array('rgb' => '00FF00'); - case 0x0C: return array('rgb' => '0000FF'); - case 0x0D: return array('rgb' => 'FFFF00'); - case 0x0E: return array('rgb' => 'FF00FF'); - case 0x0F: return array('rgb' => '00FFFF'); - case 0x10: return array('rgb' => '800000'); - case 0x11: return array('rgb' => '008000'); - case 0x12: return array('rgb' => '000080'); - case 0x13: return array('rgb' => '808000'); - case 0x14: return array('rgb' => '800080'); - case 0x15: return array('rgb' => '008080'); - case 0x16: return array('rgb' => 'C0C0C0'); - case 0x17: return array('rgb' => '808080'); - case 0x18: return array('rgb' => '9999FF'); - case 0x19: return array('rgb' => '993366'); - case 0x1A: return array('rgb' => 'FFFFCC'); - case 0x1B: return array('rgb' => 'CCFFFF'); - case 0x1C: return array('rgb' => '660066'); - case 0x1D: return array('rgb' => 'FF8080'); - case 0x1E: return array('rgb' => '0066CC'); - case 0x1F: return array('rgb' => 'CCCCFF'); - case 0x20: return array('rgb' => '000080'); - case 0x21: return array('rgb' => 'FF00FF'); - case 0x22: return array('rgb' => 'FFFF00'); - case 0x23: return array('rgb' => '00FFFF'); - case 0x24: return array('rgb' => '800080'); - case 0x25: return array('rgb' => '800000'); - case 0x26: return array('rgb' => '008080'); - case 0x27: return array('rgb' => '0000FF'); - case 0x28: return array('rgb' => '00CCFF'); - case 0x29: return array('rgb' => 'CCFFFF'); - case 0x2A: return array('rgb' => 'CCFFCC'); - case 0x2B: return array('rgb' => 'FFFF99'); - case 0x2C: return array('rgb' => '99CCFF'); - case 0x2D: return array('rgb' => 'FF99CC'); - case 0x2E: return array('rgb' => 'CC99FF'); - case 0x2F: return array('rgb' => 'FFCC99'); - case 0x30: return array('rgb' => '3366FF'); - case 0x31: return array('rgb' => '33CCCC'); - case 0x32: return array('rgb' => '99CC00'); - case 0x33: return array('rgb' => 'FFCC00'); - case 0x34: return array('rgb' => 'FF9900'); - case 0x35: return array('rgb' => 'FF6600'); - case 0x36: return array('rgb' => '666699'); - case 0x37: return array('rgb' => '969696'); - case 0x38: return array('rgb' => '003366'); - case 0x39: return array('rgb' => '339966'); - case 0x3A: return array('rgb' => '003300'); - case 0x3B: return array('rgb' => '333300'); - case 0x3C: return array('rgb' => '993300'); - case 0x3D: return array('rgb' => '993366'); - case 0x3E: return array('rgb' => '333399'); - case 0x3F: return array('rgb' => '333333'); - default: return array('rgb' => '000000'); - } - } - - - private function _parseRichText($is = '') { - $value = new PHPExcel_RichText(); - - $value->createText($is); - - return $value; - } + if (!$this->_readDataOnly) { + $offset += 12; + + // offset: 12; size: 2; shared feature type, 2 = enhanced protection, 4 = smart tag + $isf = self::_GetInt2d($recordData, 12); + if ($isf != 2) { + // we only read FEAT records of type 2 + return; + } + $offset += 2; + + $offset += 5; + + // offset: 19; size: 2; count of ref ranges this feature is on + $cref = self::_GetInt2d($recordData, 19); + $offset += 2; + + $offset += 6; + + // offset: 27; size: 8 * $cref; list of cell ranges (like in hyperlink record) + $cellRanges = array(); + for ($i = 0; $i < $cref; ++$i) { + try { + $cellRange = $this->_readBIFF8CellRangeAddressFixed(substr($recordData, 27 + 8 * $i, 8)); + } catch (PHPExcel_Exception $e) { + return; + } + $cellRanges[] = $cellRange; + $offset += 8; + } + + // offset: var; size: var; variable length of feature specific data + $rgbFeat = substr($recordData, $offset); + $offset += 4; + + // offset: var; size: 4; the encrypted password (only 16-bit although field is 32-bit) + $wPassword = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // Apply range protection to sheet + if ($cellRanges) { + $this->_phpSheet->protectCells(implode(' ', $cellRanges), strtoupper(dechex($wPassword)), true); + } + } + } + + + /** + * Read IMDATA record + */ + private function _readImData() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + // UNDER CONSTRUCTION + + // offset: 0; size: 2; image format + $cf = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; environment from which the file was written + $env = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 4; length of the image data + $lcb = self::_GetInt4d($recordData, 4); + + // offset: 8; size: var; image data + $iData = substr($recordData, 8); + + switch ($cf) { + case 0x09: // Windows bitmap format + // BITMAPCOREINFO + // 1. BITMAPCOREHEADER + // offset: 0; size: 4; bcSize, Specifies the number of bytes required by the structure + $bcSize = self::_GetInt4d($iData, 0); +// var_dump($bcSize); + + // offset: 4; size: 2; bcWidth, specifies the width of the bitmap, in pixels + $bcWidth = self::_GetInt2d($iData, 4); +// var_dump($bcWidth); + + // offset: 6; size: 2; bcHeight, specifies the height of the bitmap, in pixels. + $bcHeight = self::_GetInt2d($iData, 6); +// var_dump($bcHeight); + $ih = imagecreatetruecolor($bcWidth, $bcHeight); + + // offset: 8; size: 2; bcPlanes, specifies the number of planes for the target device. This value must be 1 + + // offset: 10; size: 2; bcBitCount specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24 + $bcBitCount = self::_GetInt2d($iData, 10); +// var_dump($bcBitCount); + + $rgbString = substr($iData, 12); + $rgbTriples = array(); + while (strlen($rgbString) > 0) { + $rgbTriples[] = unpack('Cb/Cg/Cr', $rgbString); + $rgbString = substr($rgbString, 3); + } + $x = 0; + $y = 0; + foreach ($rgbTriples as $i => $rgbTriple) { + $color = imagecolorallocate($ih, $rgbTriple['r'], $rgbTriple['g'], $rgbTriple['b']); + imagesetpixel($ih, $x, $bcHeight - 1 - $y, $color); + $x = ($x + 1) % $bcWidth; + $y = $y + floor(($x + 1) / $bcWidth); + } + //imagepng($ih, 'image.png'); + + $drawing = new PHPExcel_Worksheet_Drawing(); + $drawing->setPath($filename); + $drawing->setWorksheet($this->_phpSheet); + + break; + + case 0x02: // Windows metafile or Macintosh PICT format + case 0x0e: // native format + default; + break; + + } + + // _getSplicedRecordData() takes care of moving current position in data stream + } + + + /** + * Read a free CONTINUE record. Free CONTINUE record may be a camouflaged MSODRAWING record + * When MSODRAWING data on a sheet exceeds 8224 bytes, CONTINUE records are used instead. Undocumented. + * In this case, we must treat the CONTINUE record as a MSODRAWING record + */ + private function _readContinue() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // check if we are reading drawing data + // this is in case a free CONTINUE record occurs in other circumstances we are unaware of + if ($this->_drawingData == '') { + // move stream pointer to next record + $this->_pos += 4 + $length; + + return; + } + + // check if record data is at least 4 bytes long, otherwise there is no chance this is MSODRAWING data + if ($length < 4) { + // move stream pointer to next record + $this->_pos += 4 + $length; + + return; + } + + // dirty check to see if CONTINUE record could be a camouflaged MSODRAWING record + // look inside CONTINUE record to see if it looks like a part of an Escher stream + // we know that Escher stream may be split at least at + // 0xF003 MsofbtSpgrContainer + // 0xF004 MsofbtSpContainer + // 0xF00D MsofbtClientTextbox + $validSplitPoints = array(0xF003, 0xF004, 0xF00D); // add identifiers if we find more + + $splitPoint = self::_GetInt2d($recordData, 2); + if (in_array($splitPoint, $validSplitPoints)) { + // get spliced record data (and move pointer to next record) + $splicedRecordData = $this->_getSplicedRecordData(); + $this->_drawingData .= $splicedRecordData['recordData']; + + return; + } + + // move stream pointer to next record + $this->_pos += 4 + $length; + + } + + + /** + * Reads a record from current position in data stream and continues reading data as long as CONTINUE + * records are found. Splices the record data pieces and returns the combined string as if record data + * is in one piece. + * Moves to next current position in data stream to start of next record different from a CONtINUE record + * + * @return array + */ + private function _getSplicedRecordData() + { + $data = ''; + $spliceOffsets = array(); + + $i = 0; + $spliceOffsets[0] = 0; + + do { + ++$i; + + // offset: 0; size: 2; identifier + $identifier = self::_GetInt2d($this->_data, $this->_pos); + // offset: 2; size: 2; length + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $data .= $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + $spliceOffsets[$i] = $spliceOffsets[$i - 1] + $length; + + $this->_pos += 4 + $length; + $nextIdentifier = self::_GetInt2d($this->_data, $this->_pos); + } + while ($nextIdentifier == self::XLS_Type_CONTINUE); + + $splicedData = array( + 'recordData' => $data, + 'spliceOffsets' => $spliceOffsets, + ); + + return $splicedData; + + } + + + /** + * Convert formula structure into human readable Excel formula like 'A3+A5*5' + * + * @param string $formulaStructure The complete binary data for the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') + { + // offset: 0; size: 2; size of the following formula data + $sz = self::_GetInt2d($formulaStructure, 0); + + // offset: 2; size: sz + $formulaData = substr($formulaStructure, 2, $sz); + + // for debug: dump the formula data + //echo '<xmp>'; + //echo 'size: ' . $sz . "\n"; + //echo 'the entire formula data: '; + //Debug::dump($formulaData); + //echo "\n----\n"; + + // offset: 2 + sz; size: variable (optional) + if (strlen($formulaStructure) > 2 + $sz) { + $additionalData = substr($formulaStructure, 2 + $sz); + + // for debug: dump the additional data + //echo 'the entire additional data: '; + //Debug::dump($additionalData); + //echo "\n----\n"; + + } else { + $additionalData = ''; + } + + return $this->_getFormulaFromData($formulaData, $additionalData, $baseCell); + } + + + /** + * Take formula data and additional data for formula and return human readable formula + * + * @param string $formulaData The binary data for the formula itself + * @param string $additionalData Additional binary data going with the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1') + { + // start parsing the formula data + $tokens = array(); + + while (strlen($formulaData) > 0 and $token = $this->_getNextToken($formulaData, $baseCell)) { + $tokens[] = $token; + $formulaData = substr($formulaData, $token['size']); + + // for debug: dump the token + //var_dump($token); + } + + $formulaString = $this->_createFormulaFromTokens($tokens, $additionalData); + + return $formulaString; + } + + + /** + * Take array of tokens together with additional data for formula and return human readable formula + * + * @param array $tokens + * @param array $additionalData Additional binary data going with the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _createFormulaFromTokens($tokens, $additionalData) + { + // empty formula? + if (empty($tokens)) { + return ''; + } + + $formulaStrings = array(); + foreach ($tokens as $token) { + // initialize spaces + $space0 = isset($space0) ? $space0 : ''; // spaces before next token, not tParen + $space1 = isset($space1) ? $space1 : ''; // carriage returns before next token, not tParen + $space2 = isset($space2) ? $space2 : ''; // spaces before opening parenthesis + $space3 = isset($space3) ? $space3 : ''; // carriage returns before opening parenthesis + $space4 = isset($space4) ? $space4 : ''; // spaces before closing parenthesis + $space5 = isset($space5) ? $space5 : ''; // carriage returns before closing parenthesis + + switch ($token['name']) { + case 'tAdd': // addition + case 'tConcat': // addition + case 'tDiv': // division + case 'tEQ': // equality + case 'tGE': // greater than or equal + case 'tGT': // greater than + case 'tIsect': // intersection + case 'tLE': // less than or equal + case 'tList': // less than or equal + case 'tLT': // less than + case 'tMul': // multiplication + case 'tNE': // multiplication + case 'tPower': // power + case 'tRange': // range + case 'tSub': // subtraction + $op2 = array_pop($formulaStrings); + $op1 = array_pop($formulaStrings); + $formulaStrings[] = "$op1$space1$space0{$token['data']}$op2"; + unset($space0, $space1); + break; + case 'tUplus': // unary plus + case 'tUminus': // unary minus + $op = array_pop($formulaStrings); + $formulaStrings[] = "$space1$space0{$token['data']}$op"; + unset($space0, $space1); + break; + case 'tPercent': // percent sign + $op = array_pop($formulaStrings); + $formulaStrings[] = "$op$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + case 'tAttrVolatile': // indicates volatile function + case 'tAttrIf': + case 'tAttrSkip': + case 'tAttrChoose': + // token is only important for Excel formula evaluator + // do nothing + break; + case 'tAttrSpace': // space / carriage return + // space will be used when next token arrives, do not alter formulaString stack + switch ($token['data']['spacetype']) { + case 'type0': + $space0 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type1': + $space1 = str_repeat("\n", $token['data']['spacecount']); + break; + case 'type2': + $space2 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type3': + $space3 = str_repeat("\n", $token['data']['spacecount']); + break; + case 'type4': + $space4 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type5': + $space5 = str_repeat("\n", $token['data']['spacecount']); + break; + } + break; + case 'tAttrSum': // SUM function with one parameter + $op = array_pop($formulaStrings); + $formulaStrings[] = "{$space1}{$space0}SUM($op)"; + unset($space0, $space1); + break; + case 'tFunc': // function with fixed number of arguments + case 'tFuncV': // function with variable number of arguments + if ($token['data']['function'] != '') { + // normal function + $ops = array(); // array of operators + for ($i = 0; $i < $token['data']['args']; ++$i) { + $ops[] = array_pop($formulaStrings); + } + $ops = array_reverse($ops); + $formulaStrings[] = "$space1$space0{$token['data']['function']}(" . implode(',', $ops) . ")"; + unset($space0, $space1); + } else { + // add-in function + $ops = array(); // array of operators + for ($i = 0; $i < $token['data']['args'] - 1; ++$i) { + $ops[] = array_pop($formulaStrings); + } + $ops = array_reverse($ops); + $function = array_pop($formulaStrings); + $formulaStrings[] = "$space1$space0$function(" . implode(',', $ops) . ")"; + unset($space0, $space1); + } + break; + case 'tParen': // parenthesis + $expression = array_pop($formulaStrings); + $formulaStrings[] = "$space3$space2($expression$space5$space4)"; + unset($space2, $space3, $space4, $space5); + break; + case 'tArray': // array constant + $constantArray = self::_readBIFF8ConstantArray($additionalData); + $formulaStrings[] = $space1 . $space0 . $constantArray['value']; + $additionalData = substr($additionalData, $constantArray['size']); // bite of chunk of additional data + unset($space0, $space1); + break; + case 'tMemArea': + // bite off chunk of additional data + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData); + $additionalData = substr($additionalData, $cellRangeAddressList['size']); + $formulaStrings[] = "$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + case 'tArea': // cell range address + case 'tBool': // boolean + case 'tErr': // error code + case 'tInt': // integer + case 'tMemErr': + case 'tMemFunc': + case 'tMissArg': + case 'tName': + case 'tNameX': + case 'tNum': // number + case 'tRef': // single cell reference + case 'tRef3d': // 3d cell reference + case 'tArea3d': // 3d cell range reference + case 'tRefN': + case 'tAreaN': + case 'tStr': // string + $formulaStrings[] = "$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + } + } + $formulaString = $formulaStrings[0]; + + // for debug: dump the human readable formula + //echo '----' . "\n"; + //echo 'Formula: ' . $formulaString; + + return $formulaString; + } + + + /** + * Fetch next token from binary formula data + * + * @param string Formula data + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return array + * @throws PHPExcel_Reader_Exception + */ + private function _getNextToken($formulaData, $baseCell = 'A1') + { + // offset: 0; size: 1; token id + $id = ord($formulaData[0]); // token id + $name = false; // initialize token name + + switch ($id) { + case 0x03: $name = 'tAdd'; $size = 1; $data = '+'; break; + case 0x04: $name = 'tSub'; $size = 1; $data = '-'; break; + case 0x05: $name = 'tMul'; $size = 1; $data = '*'; break; + case 0x06: $name = 'tDiv'; $size = 1; $data = '/'; break; + case 0x07: $name = 'tPower'; $size = 1; $data = '^'; break; + case 0x08: $name = 'tConcat'; $size = 1; $data = '&'; break; + case 0x09: $name = 'tLT'; $size = 1; $data = '<'; break; + case 0x0A: $name = 'tLE'; $size = 1; $data = '<='; break; + case 0x0B: $name = 'tEQ'; $size = 1; $data = '='; break; + case 0x0C: $name = 'tGE'; $size = 1; $data = '>='; break; + case 0x0D: $name = 'tGT'; $size = 1; $data = '>'; break; + case 0x0E: $name = 'tNE'; $size = 1; $data = '<>'; break; + case 0x0F: $name = 'tIsect'; $size = 1; $data = ' '; break; + case 0x10: $name = 'tList'; $size = 1; $data = ','; break; + case 0x11: $name = 'tRange'; $size = 1; $data = ':'; break; + case 0x12: $name = 'tUplus'; $size = 1; $data = '+'; break; + case 0x13: $name = 'tUminus'; $size = 1; $data = '-'; break; + case 0x14: $name = 'tPercent'; $size = 1; $data = '%'; break; + case 0x15: // parenthesis + $name = 'tParen'; + $size = 1; + $data = null; + break; + case 0x16: // missing argument + $name = 'tMissArg'; + $size = 1; + $data = ''; + break; + case 0x17: // string + $name = 'tStr'; + // offset: 1; size: var; Unicode string, 8-bit string length + $string = self::_readUnicodeStringShort(substr($formulaData, 1)); + $size = 1 + $string['size']; + $data = self::_UTF8toExcelDoubleQuoted($string['value']); + break; + case 0x19: // Special attribute + // offset: 1; size: 1; attribute type flags: + switch (ord($formulaData[1])) { + case 0x01: + $name = 'tAttrVolatile'; + $size = 4; + $data = null; + break; + case 0x02: + $name = 'tAttrIf'; + $size = 4; + $data = null; + break; + case 0x04: + $name = 'tAttrChoose'; + // offset: 2; size: 2; number of choices in the CHOOSE function ($nc, number of parameters decreased by 1) + $nc = self::_GetInt2d($formulaData, 2); + // offset: 4; size: 2 * $nc + // offset: 4 + 2 * $nc; size: 2 + $size = 2 * $nc + 6; + $data = null; + break; + case 0x08: + $name = 'tAttrSkip'; + $size = 4; + $data = null; + break; + case 0x10: + $name = 'tAttrSum'; + $size = 4; + $data = null; + break; + case 0x40: + case 0x41: + $name = 'tAttrSpace'; + $size = 4; + // offset: 2; size: 2; space type and position + switch (ord($formulaData[2])) { + case 0x00: + $spacetype = 'type0'; + break; + case 0x01: + $spacetype = 'type1'; + break; + case 0x02: + $spacetype = 'type2'; + break; + case 0x03: + $spacetype = 'type3'; + break; + case 0x04: + $spacetype = 'type4'; + break; + case 0x05: + $spacetype = 'type5'; + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized space type in tAttrSpace token'); + break; + } + // offset: 3; size: 1; number of inserted spaces/carriage returns + $spacecount = ord($formulaData[3]); + + $data = array('spacetype' => $spacetype, 'spacecount' => $spacecount); + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized attribute flag in tAttr token'); + break; + } + break; + case 0x1C: // error code + // offset: 1; size: 1; error code + $name = 'tErr'; + $size = 2; + $data = self::_mapErrorCode(ord($formulaData[1])); + break; + case 0x1D: // boolean + // offset: 1; size: 1; 0 = false, 1 = true; + $name = 'tBool'; + $size = 2; + $data = ord($formulaData[1]) ? 'TRUE' : 'FALSE'; + break; + case 0x1E: // integer + // offset: 1; size: 2; unsigned 16-bit integer + $name = 'tInt'; + $size = 3; + $data = self::_GetInt2d($formulaData, 1); + break; + case 0x1F: // number + // offset: 1; size: 8; + $name = 'tNum'; + $size = 9; + $data = self::_extractNumber(substr($formulaData, 1)); + $data = str_replace(',', '.', (string)$data); // in case non-English locale + break; + case 0x20: // array constant + case 0x40: + case 0x60: + // offset: 1; size: 7; not used + $name = 'tArray'; + $size = 8; + $data = null; + break; + case 0x21: // function with fixed number of arguments + case 0x41: + case 0x61: + $name = 'tFunc'; + $size = 3; + // offset: 1; size: 2; index to built-in sheet function + switch (self::_GetInt2d($formulaData, 1)) { + case 2: $function = 'ISNA'; $args = 1; break; + case 3: $function = 'ISERROR'; $args = 1; break; + case 10: $function = 'NA'; $args = 0; break; + case 15: $function = 'SIN'; $args = 1; break; + case 16: $function = 'COS'; $args = 1; break; + case 17: $function = 'TAN'; $args = 1; break; + case 18: $function = 'ATAN'; $args = 1; break; + case 19: $function = 'PI'; $args = 0; break; + case 20: $function = 'SQRT'; $args = 1; break; + case 21: $function = 'EXP'; $args = 1; break; + case 22: $function = 'LN'; $args = 1; break; + case 23: $function = 'LOG10'; $args = 1; break; + case 24: $function = 'ABS'; $args = 1; break; + case 25: $function = 'INT'; $args = 1; break; + case 26: $function = 'SIGN'; $args = 1; break; + case 27: $function = 'ROUND'; $args = 2; break; + case 30: $function = 'REPT'; $args = 2; break; + case 31: $function = 'MID'; $args = 3; break; + case 32: $function = 'LEN'; $args = 1; break; + case 33: $function = 'VALUE'; $args = 1; break; + case 34: $function = 'TRUE'; $args = 0; break; + case 35: $function = 'FALSE'; $args = 0; break; + case 38: $function = 'NOT'; $args = 1; break; + case 39: $function = 'MOD'; $args = 2; break; + case 40: $function = 'DCOUNT'; $args = 3; break; + case 41: $function = 'DSUM'; $args = 3; break; + case 42: $function = 'DAVERAGE'; $args = 3; break; + case 43: $function = 'DMIN'; $args = 3; break; + case 44: $function = 'DMAX'; $args = 3; break; + case 45: $function = 'DSTDEV'; $args = 3; break; + case 48: $function = 'TEXT'; $args = 2; break; + case 61: $function = 'MIRR'; $args = 3; break; + case 63: $function = 'RAND'; $args = 0; break; + case 65: $function = 'DATE'; $args = 3; break; + case 66: $function = 'TIME'; $args = 3; break; + case 67: $function = 'DAY'; $args = 1; break; + case 68: $function = 'MONTH'; $args = 1; break; + case 69: $function = 'YEAR'; $args = 1; break; + case 71: $function = 'HOUR'; $args = 1; break; + case 72: $function = 'MINUTE'; $args = 1; break; + case 73: $function = 'SECOND'; $args = 1; break; + case 74: $function = 'NOW'; $args = 0; break; + case 75: $function = 'AREAS'; $args = 1; break; + case 76: $function = 'ROWS'; $args = 1; break; + case 77: $function = 'COLUMNS'; $args = 1; break; + case 83: $function = 'TRANSPOSE'; $args = 1; break; + case 86: $function = 'TYPE'; $args = 1; break; + case 97: $function = 'ATAN2'; $args = 2; break; + case 98: $function = 'ASIN'; $args = 1; break; + case 99: $function = 'ACOS'; $args = 1; break; + case 105: $function = 'ISREF'; $args = 1; break; + case 111: $function = 'CHAR'; $args = 1; break; + case 112: $function = 'LOWER'; $args = 1; break; + case 113: $function = 'UPPER'; $args = 1; break; + case 114: $function = 'PROPER'; $args = 1; break; + case 117: $function = 'EXACT'; $args = 2; break; + case 118: $function = 'TRIM'; $args = 1; break; + case 119: $function = 'REPLACE'; $args = 4; break; + case 121: $function = 'CODE'; $args = 1; break; + case 126: $function = 'ISERR'; $args = 1; break; + case 127: $function = 'ISTEXT'; $args = 1; break; + case 128: $function = 'ISNUMBER'; $args = 1; break; + case 129: $function = 'ISBLANK'; $args = 1; break; + case 130: $function = 'T'; $args = 1; break; + case 131: $function = 'N'; $args = 1; break; + case 140: $function = 'DATEVALUE'; $args = 1; break; + case 141: $function = 'TIMEVALUE'; $args = 1; break; + case 142: $function = 'SLN'; $args = 3; break; + case 143: $function = 'SYD'; $args = 4; break; + case 162: $function = 'CLEAN'; $args = 1; break; + case 163: $function = 'MDETERM'; $args = 1; break; + case 164: $function = 'MINVERSE'; $args = 1; break; + case 165: $function = 'MMULT'; $args = 2; break; + case 184: $function = 'FACT'; $args = 1; break; + case 189: $function = 'DPRODUCT'; $args = 3; break; + case 190: $function = 'ISNONTEXT'; $args = 1; break; + case 195: $function = 'DSTDEVP'; $args = 3; break; + case 196: $function = 'DVARP'; $args = 3; break; + case 198: $function = 'ISLOGICAL'; $args = 1; break; + case 199: $function = 'DCOUNTA'; $args = 3; break; + case 207: $function = 'REPLACEB'; $args = 4; break; + case 210: $function = 'MIDB'; $args = 3; break; + case 211: $function = 'LENB'; $args = 1; break; + case 212: $function = 'ROUNDUP'; $args = 2; break; + case 213: $function = 'ROUNDDOWN'; $args = 2; break; + case 214: $function = 'ASC'; $args = 1; break; + case 215: $function = 'DBCS'; $args = 1; break; + case 221: $function = 'TODAY'; $args = 0; break; + case 229: $function = 'SINH'; $args = 1; break; + case 230: $function = 'COSH'; $args = 1; break; + case 231: $function = 'TANH'; $args = 1; break; + case 232: $function = 'ASINH'; $args = 1; break; + case 233: $function = 'ACOSH'; $args = 1; break; + case 234: $function = 'ATANH'; $args = 1; break; + case 235: $function = 'DGET'; $args = 3; break; + case 244: $function = 'INFO'; $args = 1; break; + case 252: $function = 'FREQUENCY'; $args = 2; break; + case 261: $function = 'ERROR.TYPE'; $args = 1; break; + case 271: $function = 'GAMMALN'; $args = 1; break; + case 273: $function = 'BINOMDIST'; $args = 4; break; + case 274: $function = 'CHIDIST'; $args = 2; break; + case 275: $function = 'CHIINV'; $args = 2; break; + case 276: $function = 'COMBIN'; $args = 2; break; + case 277: $function = 'CONFIDENCE'; $args = 3; break; + case 278: $function = 'CRITBINOM'; $args = 3; break; + case 279: $function = 'EVEN'; $args = 1; break; + case 280: $function = 'EXPONDIST'; $args = 3; break; + case 281: $function = 'FDIST'; $args = 3; break; + case 282: $function = 'FINV'; $args = 3; break; + case 283: $function = 'FISHER'; $args = 1; break; + case 284: $function = 'FISHERINV'; $args = 1; break; + case 285: $function = 'FLOOR'; $args = 2; break; + case 286: $function = 'GAMMADIST'; $args = 4; break; + case 287: $function = 'GAMMAINV'; $args = 3; break; + case 288: $function = 'CEILING'; $args = 2; break; + case 289: $function = 'HYPGEOMDIST'; $args = 4; break; + case 290: $function = 'LOGNORMDIST'; $args = 3; break; + case 291: $function = 'LOGINV'; $args = 3; break; + case 292: $function = 'NEGBINOMDIST'; $args = 3; break; + case 293: $function = 'NORMDIST'; $args = 4; break; + case 294: $function = 'NORMSDIST'; $args = 1; break; + case 295: $function = 'NORMINV'; $args = 3; break; + case 296: $function = 'NORMSINV'; $args = 1; break; + case 297: $function = 'STANDARDIZE'; $args = 3; break; + case 298: $function = 'ODD'; $args = 1; break; + case 299: $function = 'PERMUT'; $args = 2; break; + case 300: $function = 'POISSON'; $args = 3; break; + case 301: $function = 'TDIST'; $args = 3; break; + case 302: $function = 'WEIBULL'; $args = 4; break; + case 303: $function = 'SUMXMY2'; $args = 2; break; + case 304: $function = 'SUMX2MY2'; $args = 2; break; + case 305: $function = 'SUMX2PY2'; $args = 2; break; + case 306: $function = 'CHITEST'; $args = 2; break; + case 307: $function = 'CORREL'; $args = 2; break; + case 308: $function = 'COVAR'; $args = 2; break; + case 309: $function = 'FORECAST'; $args = 3; break; + case 310: $function = 'FTEST'; $args = 2; break; + case 311: $function = 'INTERCEPT'; $args = 2; break; + case 312: $function = 'PEARSON'; $args = 2; break; + case 313: $function = 'RSQ'; $args = 2; break; + case 314: $function = 'STEYX'; $args = 2; break; + case 315: $function = 'SLOPE'; $args = 2; break; + case 316: $function = 'TTEST'; $args = 4; break; + case 325: $function = 'LARGE'; $args = 2; break; + case 326: $function = 'SMALL'; $args = 2; break; + case 327: $function = 'QUARTILE'; $args = 2; break; + case 328: $function = 'PERCENTILE'; $args = 2; break; + case 331: $function = 'TRIMMEAN'; $args = 2; break; + case 332: $function = 'TINV'; $args = 2; break; + case 337: $function = 'POWER'; $args = 2; break; + case 342: $function = 'RADIANS'; $args = 1; break; + case 343: $function = 'DEGREES'; $args = 1; break; + case 346: $function = 'COUNTIF'; $args = 2; break; + case 347: $function = 'COUNTBLANK'; $args = 1; break; + case 350: $function = 'ISPMT'; $args = 4; break; + case 351: $function = 'DATEDIF'; $args = 3; break; + case 352: $function = 'DATESTRING'; $args = 1; break; + case 353: $function = 'NUMBERSTRING'; $args = 2; break; + case 360: $function = 'PHONETIC'; $args = 1; break; + case 368: $function = 'BAHTTEXT'; $args = 1; break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + break; + } + $data = array('function' => $function, 'args' => $args); + break; + case 0x22: // function with variable number of arguments + case 0x42: + case 0x62: + $name = 'tFuncV'; + $size = 4; + // offset: 1; size: 1; number of arguments + $args = ord($formulaData[1]); + // offset: 2: size: 2; index to built-in sheet function + $index = self::_GetInt2d($formulaData, 2); + switch ($index) { + case 0: $function = 'COUNT'; break; + case 1: $function = 'IF'; break; + case 4: $function = 'SUM'; break; + case 5: $function = 'AVERAGE'; break; + case 6: $function = 'MIN'; break; + case 7: $function = 'MAX'; break; + case 8: $function = 'ROW'; break; + case 9: $function = 'COLUMN'; break; + case 11: $function = 'NPV'; break; + case 12: $function = 'STDEV'; break; + case 13: $function = 'DOLLAR'; break; + case 14: $function = 'FIXED'; break; + case 28: $function = 'LOOKUP'; break; + case 29: $function = 'INDEX'; break; + case 36: $function = 'AND'; break; + case 37: $function = 'OR'; break; + case 46: $function = 'VAR'; break; + case 49: $function = 'LINEST'; break; + case 50: $function = 'TREND'; break; + case 51: $function = 'LOGEST'; break; + case 52: $function = 'GROWTH'; break; + case 56: $function = 'PV'; break; + case 57: $function = 'FV'; break; + case 58: $function = 'NPER'; break; + case 59: $function = 'PMT'; break; + case 60: $function = 'RATE'; break; + case 62: $function = 'IRR'; break; + case 64: $function = 'MATCH'; break; + case 70: $function = 'WEEKDAY'; break; + case 78: $function = 'OFFSET'; break; + case 82: $function = 'SEARCH'; break; + case 100: $function = 'CHOOSE'; break; + case 101: $function = 'HLOOKUP'; break; + case 102: $function = 'VLOOKUP'; break; + case 109: $function = 'LOG'; break; + case 115: $function = 'LEFT'; break; + case 116: $function = 'RIGHT'; break; + case 120: $function = 'SUBSTITUTE'; break; + case 124: $function = 'FIND'; break; + case 125: $function = 'CELL'; break; + case 144: $function = 'DDB'; break; + case 148: $function = 'INDIRECT'; break; + case 167: $function = 'IPMT'; break; + case 168: $function = 'PPMT'; break; + case 169: $function = 'COUNTA'; break; + case 183: $function = 'PRODUCT'; break; + case 193: $function = 'STDEVP'; break; + case 194: $function = 'VARP'; break; + case 197: $function = 'TRUNC'; break; + case 204: $function = 'USDOLLAR'; break; + case 205: $function = 'FINDB'; break; + case 206: $function = 'SEARCHB'; break; + case 208: $function = 'LEFTB'; break; + case 209: $function = 'RIGHTB'; break; + case 216: $function = 'RANK'; break; + case 219: $function = 'ADDRESS'; break; + case 220: $function = 'DAYS360'; break; + case 222: $function = 'VDB'; break; + case 227: $function = 'MEDIAN'; break; + case 228: $function = 'SUMPRODUCT'; break; + case 247: $function = 'DB'; break; + case 255: $function = ''; break; + case 269: $function = 'AVEDEV'; break; + case 270: $function = 'BETADIST'; break; + case 272: $function = 'BETAINV'; break; + case 317: $function = 'PROB'; break; + case 318: $function = 'DEVSQ'; break; + case 319: $function = 'GEOMEAN'; break; + case 320: $function = 'HARMEAN'; break; + case 321: $function = 'SUMSQ'; break; + case 322: $function = 'KURT'; break; + case 323: $function = 'SKEW'; break; + case 324: $function = 'ZTEST'; break; + case 329: $function = 'PERCENTRANK'; break; + case 330: $function = 'MODE'; break; + case 336: $function = 'CONCATENATE'; break; + case 344: $function = 'SUBTOTAL'; break; + case 345: $function = 'SUMIF'; break; + case 354: $function = 'ROMAN'; break; + case 358: $function = 'GETPIVOTDATA'; break; + case 359: $function = 'HYPERLINK'; break; + case 361: $function = 'AVERAGEA'; break; + case 362: $function = 'MAXA'; break; + case 363: $function = 'MINA'; break; + case 364: $function = 'STDEVPA'; break; + case 365: $function = 'VARPA'; break; + case 366: $function = 'STDEVA'; break; + case 367: $function = 'VARA'; break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + break; + } + $data = array('function' => $function, 'args' => $args); + break; + case 0x23: // index to defined name + case 0x43: + case 0x63: + $name = 'tName'; + $size = 5; + // offset: 1; size: 2; one-based index to definedname record + $definedNameIndex = self::_GetInt2d($formulaData, 1) - 1; + // offset: 2; size: 2; not used + $data = $this->_definedname[$definedNameIndex]['name']; + break; + case 0x24: // single cell reference e.g. A5 + case 0x44: + case 0x64: + $name = 'tRef'; + $size = 5; + $data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4)); + break; + case 0x25: // cell range reference to cells in the same sheet (2d) + case 0x45: + case 0x65: + $name = 'tArea'; + $size = 9; + $data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8)); + break; + case 0x26: // Constant reference sub-expression + case 0x46: + case 0x66: + $name = 'tMemArea'; + // offset: 1; size: 4; not used + // offset: 5; size: 2; size of the following subexpression + $subSize = self::_GetInt2d($formulaData, 5); + $size = 7 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + break; + case 0x27: // Deleted constant reference sub-expression + case 0x47: + case 0x67: + $name = 'tMemErr'; + // offset: 1; size: 4; not used + // offset: 5; size: 2; size of the following subexpression + $subSize = self::_GetInt2d($formulaData, 5); + $size = 7 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + break; + case 0x29: // Variable reference sub-expression + case 0x49: + case 0x69: + $name = 'tMemFunc'; + // offset: 1; size: 2; size of the following sub-expression + $subSize = self::_GetInt2d($formulaData, 1); + $size = 3 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize)); + break; + + case 0x2C: // Relative 2d cell reference reference, used in shared formulas and some other places + case 0x4C: + case 0x6C: + $name = 'tRefN'; + $size = 5; + $data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell); + break; + + case 0x2D: // Relative 2d range reference + case 0x4D: + case 0x6D: + $name = 'tAreaN'; + $size = 9; + $data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell); + break; + + case 0x39: // External name + case 0x59: + case 0x79: + $name = 'tNameX'; + $size = 7; + // offset: 1; size: 2; index to REF entry in EXTERNSHEET record + // offset: 3; size: 2; one-based index to DEFINEDNAME or EXTERNNAME record + $index = self::_GetInt2d($formulaData, 3); + // assume index is to EXTERNNAME record + $data = $this->_externalNames[$index - 1]['name']; + // offset: 5; size: 2; not used + break; + + case 0x3A: // 3d reference to cell + case 0x5A: + case 0x7A: + $name = 'tRef3d'; + $size = 7; + + try { + // offset: 1; size: 2; index to REF entry + $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + // offset: 3; size: 4; cell address + $cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4)); + + $data = "$sheetRange!$cellAddress"; + } catch (PHPExcel_Exception $e) { + // deleted sheet reference + $data = '#REF!'; + } + + break; + case 0x3B: // 3d reference to cell range + case 0x5B: + case 0x7B: + $name = 'tArea3d'; + $size = 11; + + try { + // offset: 1; size: 2; index to REF entry + $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + // offset: 3; size: 8; cell address + $cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8)); + + $data = "$sheetRange!$cellRangeAddress"; + } catch (PHPExcel_Exception $e) { + // deleted sheet reference + $data = '#REF!'; + } + + break; + // Unknown cases // don't know how to deal with + default: + throw new PHPExcel_Reader_Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula'); + break; + } + + return array( + 'id' => $id, + 'name' => $name, + 'size' => $size, + 'data' => $data, + ); + } + + + /** + * Reads a cell address in BIFF8 e.g. 'A2' or '$A$2' + * section 3.3.4 + * + * @param string $cellAddressStructure + * @return string + */ + private function _readBIFF8CellAddress($cellAddressStructure) + { + // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) + $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + + // offset: 2; size: 2; index to column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + $column = '$' . $column; + } + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + $row = '$' . $row; + } + + return $column . $row; + } + + + /** + * Reads a cell address in BIFF8 for shared formulas. Uses positive and negative values for row and column + * to indicate offsets from a base cell + * section 3.3.4 + * + * @param string $cellAddressStructure + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string + */ + private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') + { + list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); + $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; + + // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) + $rowIndex = self::_GetInt2d($cellAddressStructure, 0); + $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + + // offset: 2; size: 2; index to column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + $column = PHPExcel_Cell::stringFromColumnIndex($colIndex); + $column = '$' . $column; + } else { + $colIndex = ($colIndex <= 127) ? $colIndex : $colIndex - 256; + $column = PHPExcel_Cell::stringFromColumnIndex($baseCol + $colIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + $row = '$' . $row; + } else { + $rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536; + $row = $baseRow + $rowIndex; + } + + return $column . $row; + } + + + /** + * Reads a cell range address in BIFF5 e.g. 'A2:B6' or 'A1' + * always fixed range + * section 2.5.14 + * + * @param string $subData + * @return string + * @throws PHPExcel_Reader_Exception + */ + private function _readBIFF5CellRangeAddressFixed($subData) + { + // offset: 0; size: 2; index to first row + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 1; index to first column + $fc = ord($subData{4}); + + // offset: 5; size: 1; index to last column + $lc = ord($subData{5}); + + // check values + if ($fr > $lr || $fc > $lc) { + throw new PHPExcel_Reader_Exception('Not a cell range address'); + } + + // column index to letter + $fc = PHPExcel_Cell::stringFromColumnIndex($fc); + $lc = PHPExcel_Cell::stringFromColumnIndex($lc); + + if ($fr == $lr and $fc == $lc) { + return "$fc$fr"; + } + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 e.g. 'A2:B6' or 'A1' + * always fixed range + * section 2.5.14 + * + * @param string $subData + * @return string + * @throws PHPExcel_Reader_Exception + */ + private function _readBIFF8CellRangeAddressFixed($subData) + { + // offset: 0; size: 2; index to first row + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 2; index to first column + $fc = self::_GetInt2d($subData, 4); + + // offset: 6; size: 2; index to last column + $lc = self::_GetInt2d($subData, 6); + + // check values + if ($fr > $lr || $fc > $lc) { + throw new PHPExcel_Reader_Exception('Not a cell range address'); + } + + // column index to letter + $fc = PHPExcel_Cell::stringFromColumnIndex($fc); + $lc = PHPExcel_Cell::stringFromColumnIndex($lc); + + if ($fr == $lr and $fc == $lc) { + return "$fc$fr"; + } + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 e.g. 'A2:B6' or '$A$2:$B$6' + * there are flags indicating whether column/row index is relative + * section 3.3.4 + * + * @param string $subData + * @return string + */ + private function _readBIFF8CellRangeAddress($subData) + { + // todo: if cell range is just a single cell, should this funciton + // not just return e.g. 'A1' and not 'A1:A1' ? + + // offset: 0; size: 2; index to first row (0... 65535) (or offset (-32768... 32767)) + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row (0... 65535) (or offset (-32768... 32767)) + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 2; index to first column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $fc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 4)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 4))) { + $fc = '$' . $fc; + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 4))) { + $fr = '$' . $fr; + } + + // offset: 6; size: 2; index to last column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $lc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 6)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 6))) { + $lc = '$' . $lc; + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 6))) { + $lr = '$' . $lr; + } + + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 for shared formulas. Uses positive and negative values for row and column + * to indicate offsets from a base cell + * section 3.3.4 + * + * @param string $subData + * @param string $baseCell Base cell + * @return string Cell range address + */ + private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') + { + list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); + $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; + + // TODO: if cell range is just a single cell, should this funciton + // not just return e.g. 'A1' and not 'A1:A1' ? + + // offset: 0; size: 2; first row + $frIndex = self::_GetInt2d($subData, 0); // adjust below + + // offset: 2; size: 2; relative index to first row (0... 65535) should be treated as offset (-32768... 32767) + $lrIndex = self::_GetInt2d($subData, 2); // adjust below + + // offset: 4; size: 2; first column with relative/absolute flags + + // bit: 7-0; mask 0x00FF; column index + $fcIndex = 0x00FF & self::_GetInt2d($subData, 4); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 4))) { + // absolute column index + $fc = PHPExcel_Cell::stringFromColumnIndex($fcIndex); + $fc = '$' . $fc; + } else { + // column offset + $fcIndex = ($fcIndex <= 127) ? $fcIndex : $fcIndex - 256; + $fc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $fcIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 4))) { + // absolute row index + $fr = $frIndex + 1; + $fr = '$' . $fr; + } else { + // row offset + $frIndex = ($frIndex <= 32767) ? $frIndex : $frIndex - 65536; + $fr = $baseRow + $frIndex; + } + + // offset: 6; size: 2; last column with relative/absolute flags + + // bit: 7-0; mask 0x00FF; column index + $lcIndex = 0x00FF & self::_GetInt2d($subData, 6); + $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; + $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 6))) { + // absolute column index + $lc = PHPExcel_Cell::stringFromColumnIndex($lcIndex); + $lc = '$' . $lc; + } else { + // column offset + $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; + $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 6))) { + // absolute row index + $lr = $lrIndex + 1; + $lr = '$' . $lr; + } else { + // row offset + $lrIndex = ($lrIndex <= 32767) ? $lrIndex : $lrIndex - 65536; + $lr = $baseRow + $lrIndex; + } + + return "$fc$fr:$lc$lr"; + } + + + /** + * Read BIFF8 cell range address list + * section 2.5.15 + * + * @param string $subData + * @return array + */ + private function _readBIFF8CellRangeAddressList($subData) + { + $cellRangeAddresses = array(); + + // offset: 0; size: 2; number of the following cell range addresses + $nm = self::_GetInt2d($subData, 0); + + $offset = 2; + // offset: 2; size: 8 * $nm; list of $nm (fixed) cell range addresses + for ($i = 0; $i < $nm; ++$i) { + $cellRangeAddresses[] = $this->_readBIFF8CellRangeAddressFixed(substr($subData, $offset, 8)); + $offset += 8; + } + + return array( + 'size' => 2 + 8 * $nm, + 'cellRangeAddresses' => $cellRangeAddresses, + ); + } + + + /** + * Read BIFF5 cell range address list + * section 2.5.15 + * + * @param string $subData + * @return array + */ + private function _readBIFF5CellRangeAddressList($subData) + { + $cellRangeAddresses = array(); + + // offset: 0; size: 2; number of the following cell range addresses + $nm = self::_GetInt2d($subData, 0); + + $offset = 2; + // offset: 2; size: 6 * $nm; list of $nm (fixed) cell range addresses + for ($i = 0; $i < $nm; ++$i) { + $cellRangeAddresses[] = $this->_readBIFF5CellRangeAddressFixed(substr($subData, $offset, 6)); + $offset += 6; + } + + return array( + 'size' => 2 + 6 * $nm, + 'cellRangeAddresses' => $cellRangeAddresses, + ); + } + + + /** + * Get a sheet range like Sheet1:Sheet3 from REF index + * Note: If there is only one sheet in the range, one gets e.g Sheet1 + * It can also happen that the REF structure uses the -1 (FFFF) code to indicate deleted sheets, + * in which case an PHPExcel_Reader_Exception is thrown + * + * @param int $index + * @return string|false + * @throws PHPExcel_Reader_Exception + */ + private function _readSheetRangeByRefIndex($index) + { + if (isset($this->_ref[$index])) { + + $type = $this->_externalBooks[$this->_ref[$index]['externalBookIndex']]['type']; + + switch ($type) { + case 'internal': + // check if we have a deleted 3d reference + if ($this->_ref[$index]['firstSheetIndex'] == 0xFFFF or $this->_ref[$index]['lastSheetIndex'] == 0xFFFF) { + throw new PHPExcel_Reader_Exception('Deleted sheet reference'); + } + + // we have normal sheet range (collapsed or uncollapsed) + $firstSheetName = $this->_sheets[$this->_ref[$index]['firstSheetIndex']]['name']; + $lastSheetName = $this->_sheets[$this->_ref[$index]['lastSheetIndex']]['name']; + + if ($firstSheetName == $lastSheetName) { + // collapsed sheet range + $sheetRange = $firstSheetName; + } else { + $sheetRange = "$firstSheetName:$lastSheetName"; + } + + // escape the single-quotes + $sheetRange = str_replace("'", "''", $sheetRange); + + // if there are special characters, we need to enclose the range in single-quotes + // todo: check if we have identified the whole set of special characters + // it seems that the following characters are not accepted for sheet names + // and we may assume that they are not present: []*/:\? + if (preg_match("/[ !\"@#£$%&{()}<>=+'|^,;-]/", $sheetRange)) { + $sheetRange = "'$sheetRange'"; + } + + return $sheetRange; + break; + + default: + // TODO: external sheet support + throw new PHPExcel_Reader_Exception('Excel5 reader only supports internal sheets in fomulas'); + break; + } + } + return false; + } + + + /** + * read BIFF8 constant value array from array data + * returns e.g. array('value' => '{1,2;3,4}', 'size' => 40} + * section 2.5.8 + * + * @param string $arrayData + * @return array + */ + private static function _readBIFF8ConstantArray($arrayData) + { + // offset: 0; size: 1; number of columns decreased by 1 + $nc = ord($arrayData[0]); + + // offset: 1; size: 2; number of rows decreased by 1 + $nr = self::_GetInt2d($arrayData, 1); + $size = 3; // initialize + $arrayData = substr($arrayData, 3); + + // offset: 3; size: var; list of ($nc + 1) * ($nr + 1) constant values + $matrixChunks = array(); + for ($r = 1; $r <= $nr + 1; ++$r) { + $items = array(); + for ($c = 1; $c <= $nc + 1; ++$c) { + $constant = self::_readBIFF8Constant($arrayData); + $items[] = $constant['value']; + $arrayData = substr($arrayData, $constant['size']); + $size += $constant['size']; + } + $matrixChunks[] = implode(',', $items); // looks like e.g. '1,"hello"' + } + $matrix = '{' . implode(';', $matrixChunks) . '}'; + + return array( + 'value' => $matrix, + 'size' => $size, + ); + } + + + /** + * read BIFF8 constant value which may be 'Empty Value', 'Number', 'String Value', 'Boolean Value', 'Error Value' + * section 2.5.7 + * returns e.g. array('value' => '5', 'size' => 9) + * + * @param string $valueData + * @return array + */ + private static function _readBIFF8Constant($valueData) + { + // offset: 0; size: 1; identifier for type of constant + $identifier = ord($valueData[0]); + + switch ($identifier) { + case 0x00: // empty constant (what is this?) + $value = ''; + $size = 9; + break; + case 0x01: // number + // offset: 1; size: 8; IEEE 754 floating-point value + $value = self::_extractNumber(substr($valueData, 1, 8)); + $size = 9; + break; + case 0x02: // string value + // offset: 1; size: var; Unicode string, 16-bit string length + $string = self::_readUnicodeStringLong(substr($valueData, 1)); + $value = '"' . $string['value'] . '"'; + $size = 1 + $string['size']; + break; + case 0x04: // boolean + // offset: 1; size: 1; 0 = FALSE, 1 = TRUE + if (ord($valueData[1])) { + $value = 'TRUE'; + } else { + $value = 'FALSE'; + } + $size = 9; + break; + case 0x10: // error code + // offset: 1; size: 1; error code + $value = self::_mapErrorCode(ord($valueData[1])); + $size = 9; + break; + } + return array( + 'value' => $value, + 'size' => $size, + ); + } + + + /** + * Extract RGB color + * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.4 + * + * @param string $rgb Encoded RGB value (4 bytes) + * @return array + */ + private static function _readRGB($rgb) + { + // offset: 0; size 1; Red component + $r = ord($rgb{0}); + + // offset: 1; size: 1; Green component + $g = ord($rgb{1}); + + // offset: 2; size: 1; Blue component + $b = ord($rgb{2}); + + // HEX notation, e.g. 'FF00FC' + $rgb = sprintf('%02X%02X%02X', $r, $g, $b); + + return array('rgb' => $rgb); + } + + + /** + * Read byte string (8-bit string length) + * OpenOffice documentation: 2.5.2 + * + * @param string $subData + * @return array + */ + private function _readByteStringShort($subData) + { + // offset: 0; size: 1; length of the string (character count) + $ln = ord($subData[0]); + + // offset: 1: size: var; character array (8-bit characters) + $value = $this->_decodeCodepage(substr($subData, 1, $ln)); + + return array( + 'value' => $value, + 'size' => 1 + $ln, // size in bytes of data structure + ); + } + + + /** + * Read byte string (16-bit string length) + * OpenOffice documentation: 2.5.2 + * + * @param string $subData + * @return array + */ + private function _readByteStringLong($subData) + { + // offset: 0; size: 2; length of the string (character count) + $ln = self::_GetInt2d($subData, 0); + + // offset: 2: size: var; character array (8-bit characters) + $value = $this->_decodeCodepage(substr($subData, 2)); + + //return $string; + return array( + 'value' => $value, + 'size' => 2 + $ln, // size in bytes of data structure + ); + } + + + /** + * Extracts an Excel Unicode short string (8-bit string length) + * OpenOffice documentation: 2.5.3 + * function will automatically find out where the Unicode string ends. + * + * @param string $subData + * @return array + */ + private static function _readUnicodeStringShort($subData) + { + $value = ''; + + // offset: 0: size: 1; length of the string (character count) + $characterCount = ord($subData[0]); + + $string = self::_readUnicodeString(substr($subData, 1), $characterCount); + + // add 1 for the string length + $string['size'] += 1; + + return $string; + } + + + /** + * Extracts an Excel Unicode long string (16-bit string length) + * OpenOffice documentation: 2.5.3 + * this function is under construction, needs to support rich text, and Asian phonetic settings + * + * @param string $subData + * @return array + */ + private static function _readUnicodeStringLong($subData) + { + $value = ''; + + // offset: 0: size: 2; length of the string (character count) + $characterCount = self::_GetInt2d($subData, 0); + + $string = self::_readUnicodeString(substr($subData, 2), $characterCount); + + // add 2 for the string length + $string['size'] += 2; + + return $string; + } + + + /** + * Read Unicode string with no string length field, but with known character count + * this function is under construction, needs to support rich text, and Asian phonetic settings + * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.3 + * + * @param string $subData + * @param int $characterCount + * @return array + */ + private static function _readUnicodeString($subData, $characterCount) + { + $value = ''; + + // offset: 0: size: 1; option flags + + // bit: 0; mask: 0x01; character compression (0 = compressed 8-bit, 1 = uncompressed 16-bit) + $isCompressed = !((0x01 & ord($subData[0])) >> 0); + + // bit: 2; mask: 0x04; Asian phonetic settings + $hasAsian = (0x04) & ord($subData[0]) >> 2; + + // bit: 3; mask: 0x08; Rich-Text settings + $hasRichText = (0x08) & ord($subData[0]) >> 3; + + // offset: 1: size: var; character array + // this offset assumes richtext and Asian phonetic settings are off which is generally wrong + // needs to be fixed + $value = self::_encodeUTF16(substr($subData, 1, $isCompressed ? $characterCount : 2 * $characterCount), $isCompressed); + + return array( + 'value' => $value, + 'size' => $isCompressed ? 1 + $characterCount : 1 + 2 * $characterCount, // the size in bytes including the option flags + ); + } + + + /** + * Convert UTF-8 string to string surounded by double quotes. Used for explicit string tokens in formulas. + * Example: hello"world --> "hello""world" + * + * @param string $value UTF-8 encoded string + * @return string + */ + private static function _UTF8toExcelDoubleQuoted($value) + { + return '"' . str_replace('"', '""', $value) . '"'; + } + + + /** + * Reads first 8 bytes of a string and return IEEE 754 float + * + * @param string $data Binary string that is at least 8 bytes long + * @return float + */ + private static function _extractNumber($data) + { + $rknumhigh = self::_GetInt4d($data, 4); + $rknumlow = self::_GetInt4d($data, 0); + $sign = ($rknumhigh & 0x80000000) >> 31; + $exp = (($rknumhigh & 0x7ff00000) >> 20) - 1023; + $mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); + $mantissalow1 = ($rknumlow & 0x80000000) >> 31; + $mantissalow2 = ($rknumlow & 0x7fffffff); + $value = $mantissa / pow( 2 , (20 - $exp)); + + if ($mantissalow1 != 0) { + $value += 1 / pow (2 , (21 - $exp)); + } + + $value += $mantissalow2 / pow (2 , (52 - $exp)); + if ($sign) { + $value *= -1; + } + + return $value; + } + + + private static function _GetIEEE754($rknum) + { + if (($rknum & 0x02) != 0) { + $value = $rknum >> 2; + } else { + // changes by mmp, info on IEEE754 encoding from + // research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html + // The RK format calls for using only the most significant 30 bits + // of the 64 bit floating point value. The other 34 bits are assumed + // to be 0 so we use the upper 30 bits of $rknum as follows... + $sign = ($rknum & 0x80000000) >> 31; + $exp = ($rknum & 0x7ff00000) >> 20; + $mantissa = (0x100000 | ($rknum & 0x000ffffc)); + $value = $mantissa / pow( 2 , (20- ($exp - 1023))); + if ($sign) { + $value = -1 * $value; + } + //end of changes by mmp + } + if (($rknum & 0x01) != 0) { + $value /= 100; + } + return $value; + } + + + /** + * Get UTF-8 string from (compressed or uncompressed) UTF-16 string + * + * @param string $string + * @param bool $compressed + * @return string + */ + private static function _encodeUTF16($string, $compressed = '') + { + if ($compressed) { + $string = self::_uncompressByteString($string); + } + + return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE'); + } + + + /** + * Convert UTF-16 string in compressed notation to uncompressed form. Only used for BIFF8. + * + * @param string $string + * @return string + */ + private static function _uncompressByteString($string) + { + $uncompressedString = ''; + $strLen = strlen($string); + for ($i = 0; $i < $strLen; ++$i) { + $uncompressedString .= $string[$i] . "\0"; + } + + return $uncompressedString; + } + + + /** + * Convert string to UTF-8. Only used for BIFF5. + * + * @param string $string + * @return string + */ + private function _decodeCodepage($string) + { + return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->_codepage); + } + + + /** + * Read 16-bit unsigned integer + * + * @param string $data + * @param int $pos + * @return int + */ + public static function _GetInt2d($data, $pos) + { + return ord($data[$pos]) | (ord($data[$pos+1]) << 8); + } + + + /** + * Read 32-bit signed integer + * + * @param string $data + * @param int $pos + * @return int + */ + public static function _GetInt4d($data, $pos) + { + // FIX: represent numbers correctly on 64-bit system + // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 + // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems + $_or_24 = ord($data[$pos + 3]); + if ($_or_24 >= 128) { + // negative number + $_ord_24 = -abs((256 - $_or_24) << 24); + } else { + $_ord_24 = ($_or_24 & 127) << 24; + } + return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24; + } + + + /** + * Read color + * + * @param int $color Indexed color + * @param array $palette Color palette + * @return array RGB color value, example: array('rgb' => 'FF0000') + */ + private static function _readColor($color,$palette,$version) + { + if ($color <= 0x07 || $color >= 0x40) { + // special built-in color + return self::_mapBuiltInColor($color); + } elseif (isset($palette) && isset($palette[$color - 8])) { + // palette color, color index 0x08 maps to pallete index 0 + return $palette[$color - 8]; + } else { + // default color table + if ($version == self::XLS_BIFF8) { + return self::_mapColor($color); + } else { + // BIFF5 + return self::_mapColorBIFF5($color); + } + } + + return $color; + } + + + /** + * Map border style + * OpenOffice documentation: 2.5.11 + * + * @param int $index + * @return string + */ + private static function _mapBorderStyle($index) + { + switch ($index) { + case 0x00: return PHPExcel_Style_Border::BORDER_NONE; + case 0x01: return PHPExcel_Style_Border::BORDER_THIN; + case 0x02: return PHPExcel_Style_Border::BORDER_MEDIUM; + case 0x03: return PHPExcel_Style_Border::BORDER_DASHED; + case 0x04: return PHPExcel_Style_Border::BORDER_DOTTED; + case 0x05: return PHPExcel_Style_Border::BORDER_THICK; + case 0x06: return PHPExcel_Style_Border::BORDER_DOUBLE; + case 0x07: return PHPExcel_Style_Border::BORDER_HAIR; + case 0x08: return PHPExcel_Style_Border::BORDER_MEDIUMDASHED; + case 0x09: return PHPExcel_Style_Border::BORDER_DASHDOT; + case 0x0A: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; + case 0x0B: return PHPExcel_Style_Border::BORDER_DASHDOTDOT; + case 0x0C: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + case 0x0D: return PHPExcel_Style_Border::BORDER_SLANTDASHDOT; + default: return PHPExcel_Style_Border::BORDER_NONE; + } + } + + + /** + * Get fill pattern from index + * OpenOffice documentation: 2.5.12 + * + * @param int $index + * @return string + */ + private static function _mapFillPattern($index) + { + switch ($index) { + case 0x00: return PHPExcel_Style_Fill::FILL_NONE; + case 0x01: return PHPExcel_Style_Fill::FILL_SOLID; + case 0x02: return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; + case 0x03: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; + case 0x04: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; + case 0x05: return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; + case 0x06: return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; + case 0x07: return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; + case 0x08: return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; + case 0x09: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; + case 0x0A: return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; + case 0x0B: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; + case 0x0C: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; + case 0x0D: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; + case 0x0E: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; + case 0x0F: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; + case 0x10: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; + case 0x11: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; + case 0x12: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; + default: return PHPExcel_Style_Fill::FILL_NONE; + } + } + + + /** + * Map error code, e.g. '#N/A' + * + * @param int $subData + * @return string + */ + private static function _mapErrorCode($subData) + { + switch ($subData) { + case 0x00: return '#NULL!'; break; + case 0x07: return '#DIV/0!'; break; + case 0x0F: return '#VALUE!'; break; + case 0x17: return '#REF!'; break; + case 0x1D: return '#NAME?'; break; + case 0x24: return '#NUM!'; break; + case 0x2A: return '#N/A'; break; + default: return false; + } + } + + + /** + * Map built-in color to RGB value + * + * @param int $color Indexed color + * @return array + */ + private static function _mapBuiltInColor($color) + { + switch ($color) { + case 0x00: return array('rgb' => '000000'); + case 0x01: return array('rgb' => 'FFFFFF'); + case 0x02: return array('rgb' => 'FF0000'); + case 0x03: return array('rgb' => '00FF00'); + case 0x04: return array('rgb' => '0000FF'); + case 0x05: return array('rgb' => 'FFFF00'); + case 0x06: return array('rgb' => 'FF00FF'); + case 0x07: return array('rgb' => '00FFFF'); + case 0x40: return array('rgb' => '000000'); // system window text color + case 0x41: return array('rgb' => 'FFFFFF'); // system window background color + default: return array('rgb' => '000000'); + } + } + + + /** + * Map color array from BIFF5 built-in color index + * + * @param int $subData + * @return array + */ + private static function _mapColorBIFF5($subData) + { + switch ($subData) { + case 0x08: return array('rgb' => '000000'); + case 0x09: return array('rgb' => 'FFFFFF'); + case 0x0A: return array('rgb' => 'FF0000'); + case 0x0B: return array('rgb' => '00FF00'); + case 0x0C: return array('rgb' => '0000FF'); + case 0x0D: return array('rgb' => 'FFFF00'); + case 0x0E: return array('rgb' => 'FF00FF'); + case 0x0F: return array('rgb' => '00FFFF'); + case 0x10: return array('rgb' => '800000'); + case 0x11: return array('rgb' => '008000'); + case 0x12: return array('rgb' => '000080'); + case 0x13: return array('rgb' => '808000'); + case 0x14: return array('rgb' => '800080'); + case 0x15: return array('rgb' => '008080'); + case 0x16: return array('rgb' => 'C0C0C0'); + case 0x17: return array('rgb' => '808080'); + case 0x18: return array('rgb' => '8080FF'); + case 0x19: return array('rgb' => '802060'); + case 0x1A: return array('rgb' => 'FFFFC0'); + case 0x1B: return array('rgb' => 'A0E0F0'); + case 0x1C: return array('rgb' => '600080'); + case 0x1D: return array('rgb' => 'FF8080'); + case 0x1E: return array('rgb' => '0080C0'); + case 0x1F: return array('rgb' => 'C0C0FF'); + case 0x20: return array('rgb' => '000080'); + case 0x21: return array('rgb' => 'FF00FF'); + case 0x22: return array('rgb' => 'FFFF00'); + case 0x23: return array('rgb' => '00FFFF'); + case 0x24: return array('rgb' => '800080'); + case 0x25: return array('rgb' => '800000'); + case 0x26: return array('rgb' => '008080'); + case 0x27: return array('rgb' => '0000FF'); + case 0x28: return array('rgb' => '00CFFF'); + case 0x29: return array('rgb' => '69FFFF'); + case 0x2A: return array('rgb' => 'E0FFE0'); + case 0x2B: return array('rgb' => 'FFFF80'); + case 0x2C: return array('rgb' => 'A6CAF0'); + case 0x2D: return array('rgb' => 'DD9CB3'); + case 0x2E: return array('rgb' => 'B38FEE'); + case 0x2F: return array('rgb' => 'E3E3E3'); + case 0x30: return array('rgb' => '2A6FF9'); + case 0x31: return array('rgb' => '3FB8CD'); + case 0x32: return array('rgb' => '488436'); + case 0x33: return array('rgb' => '958C41'); + case 0x34: return array('rgb' => '8E5E42'); + case 0x35: return array('rgb' => 'A0627A'); + case 0x36: return array('rgb' => '624FAC'); + case 0x37: return array('rgb' => '969696'); + case 0x38: return array('rgb' => '1D2FBE'); + case 0x39: return array('rgb' => '286676'); + case 0x3A: return array('rgb' => '004500'); + case 0x3B: return array('rgb' => '453E01'); + case 0x3C: return array('rgb' => '6A2813'); + case 0x3D: return array('rgb' => '85396A'); + case 0x3E: return array('rgb' => '4A3285'); + case 0x3F: return array('rgb' => '424242'); + default: return array('rgb' => '000000'); + } + } + + + /** + * Map color array from BIFF8 built-in color index + * + * @param int $subData + * @return array + */ + private static function _mapColor($subData) + { + switch ($subData) { + case 0x08: return array('rgb' => '000000'); + case 0x09: return array('rgb' => 'FFFFFF'); + case 0x0A: return array('rgb' => 'FF0000'); + case 0x0B: return array('rgb' => '00FF00'); + case 0x0C: return array('rgb' => '0000FF'); + case 0x0D: return array('rgb' => 'FFFF00'); + case 0x0E: return array('rgb' => 'FF00FF'); + case 0x0F: return array('rgb' => '00FFFF'); + case 0x10: return array('rgb' => '800000'); + case 0x11: return array('rgb' => '008000'); + case 0x12: return array('rgb' => '000080'); + case 0x13: return array('rgb' => '808000'); + case 0x14: return array('rgb' => '800080'); + case 0x15: return array('rgb' => '008080'); + case 0x16: return array('rgb' => 'C0C0C0'); + case 0x17: return array('rgb' => '808080'); + case 0x18: return array('rgb' => '9999FF'); + case 0x19: return array('rgb' => '993366'); + case 0x1A: return array('rgb' => 'FFFFCC'); + case 0x1B: return array('rgb' => 'CCFFFF'); + case 0x1C: return array('rgb' => '660066'); + case 0x1D: return array('rgb' => 'FF8080'); + case 0x1E: return array('rgb' => '0066CC'); + case 0x1F: return array('rgb' => 'CCCCFF'); + case 0x20: return array('rgb' => '000080'); + case 0x21: return array('rgb' => 'FF00FF'); + case 0x22: return array('rgb' => 'FFFF00'); + case 0x23: return array('rgb' => '00FFFF'); + case 0x24: return array('rgb' => '800080'); + case 0x25: return array('rgb' => '800000'); + case 0x26: return array('rgb' => '008080'); + case 0x27: return array('rgb' => '0000FF'); + case 0x28: return array('rgb' => '00CCFF'); + case 0x29: return array('rgb' => 'CCFFFF'); + case 0x2A: return array('rgb' => 'CCFFCC'); + case 0x2B: return array('rgb' => 'FFFF99'); + case 0x2C: return array('rgb' => '99CCFF'); + case 0x2D: return array('rgb' => 'FF99CC'); + case 0x2E: return array('rgb' => 'CC99FF'); + case 0x2F: return array('rgb' => 'FFCC99'); + case 0x30: return array('rgb' => '3366FF'); + case 0x31: return array('rgb' => '33CCCC'); + case 0x32: return array('rgb' => '99CC00'); + case 0x33: return array('rgb' => 'FFCC00'); + case 0x34: return array('rgb' => 'FF9900'); + case 0x35: return array('rgb' => 'FF6600'); + case 0x36: return array('rgb' => '666699'); + case 0x37: return array('rgb' => '969696'); + case 0x38: return array('rgb' => '003366'); + case 0x39: return array('rgb' => '339966'); + case 0x3A: return array('rgb' => '003300'); + case 0x3B: return array('rgb' => '333300'); + case 0x3C: return array('rgb' => '993300'); + case 0x3D: return array('rgb' => '993366'); + case 0x3E: return array('rgb' => '333399'); + case 0x3F: return array('rgb' => '333333'); + default: return array('rgb' => '000000'); + } + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText($is); + + return $value; + } } diff --git a/Classes/PHPExcel/Reader/Exception.php b/Classes/PHPExcel/Reader/Exception.php index c712fe0eb..158b20756 100644 --- a/Classes/PHPExcel/Reader/Exception.php +++ b/Classes/PHPExcel/Reader/Exception.php @@ -21,8 +21,8 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ @@ -33,20 +33,22 @@ * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ -class PHPExcel_Reader_Exception extends PHPExcel_Exception { - /** - * Error handler callback - * - * @param mixed $code - * @param mixed $string - * @param mixed $file - * @param mixed $line - * @param mixed $context - */ - public static function errorHandlerCallback($code, $string, $file, $line, $context) { - $e = new self($string, $code); - $e->line = $line; - $e->file = $file; - throw $e; - } +class PHPExcel_Reader_Exception extends PHPExcel_Exception +{ + /** + * Error handler callback + * + * @param mixed $code + * @param mixed $string + * @param mixed $file + * @param mixed $line + * @param mixed $context + */ + public static function errorHandlerCallback($code, $string, $file, $line, $context) + { + $e = new self($string, $code); + $e->line = $line; + $e->file = $file; + throw $e; + } } diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index 534a2143c..1f7072f7e 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -21,853 +21,853 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** * PHPExcel_Reader_Gnumeric * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { - /** - * Formats - * - * @var array - */ - private $_styles = array(); - - /** - * Shared Expressions - * - * @var array - */ - private $_expressions = array(); - - private $_referenceHelper = null; - - - /** - * Create a new PHPExcel_Reader_Gnumeric - */ - public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); - } - - - /** - * Can the current PHPExcel_Reader_IReader read the file? - * - * @param string $pFilename - * @return boolean - * @throws PHPExcel_Reader_Exception - */ - public function canRead($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - // Check if gzlib functions are available - if (!function_exists('gzread')) { - throw new PHPExcel_Reader_Exception("gzlib library is not enabled"); - } - - // Read signature data (first 3 bytes) - $fh = fopen($pFilename, 'r'); - $data = fread($fh, 2); - fclose($fh); - - if ($data != chr(0x1F).chr(0x8B)) { - return false; - } - - return true; - } - - - /** - * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetNames($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $xml = new XMLReader(); - $xml->xml( - $this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions() - ); - $xml->setParserProperty(2,true); - - $worksheetNames = array(); - while ($xml->read()) { - if ($xml->name == 'gnm:SheetName' && $xml->nodeType == XMLReader::ELEMENT) { - $xml->read(); // Move onto the value node - $worksheetNames[] = (string) $xml->value; - } elseif ($xml->name == 'gnm:Sheets') { - // break out of the loop once we've got our sheet names rather than parse the entire file - break; - } - } - - return $worksheetNames; - } - - - /** - * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetInfo($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $xml = new XMLReader(); - $xml->xml( - $this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions() - ); - $xml->setParserProperty(2,true); - - $worksheetInfo = array(); - while ($xml->read()) { - if ($xml->name == 'gnm:Sheet' && $xml->nodeType == XMLReader::ELEMENT) { - $tmpInfo = array( - 'worksheetName' => '', - 'lastColumnLetter' => 'A', - 'lastColumnIndex' => 0, - 'totalRows' => 0, - 'totalColumns' => 0, - ); - - while ($xml->read()) { - if ($xml->name == 'gnm:Name' && $xml->nodeType == XMLReader::ELEMENT) { - $xml->read(); // Move onto the value node - $tmpInfo['worksheetName'] = (string) $xml->value; - } elseif ($xml->name == 'gnm:MaxCol' && $xml->nodeType == XMLReader::ELEMENT) { - $xml->read(); // Move onto the value node - $tmpInfo['lastColumnIndex'] = (int) $xml->value; - $tmpInfo['totalColumns'] = (int) $xml->value + 1; - } elseif ($xml->name == 'gnm:MaxRow' && $xml->nodeType == XMLReader::ELEMENT) { - $xml->read(); // Move onto the value node - $tmpInfo['totalRows'] = (int) $xml->value + 1; - break; - } - } - $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); - $worksheetInfo[] = $tmpInfo; - } - } - - return $worksheetInfo; - } - - - private function _gzfileGetContents($filename) { - $file = @gzopen($filename, 'rb'); - if ($file !== false) { - $data = ''; - while (!gzeof($file)) { - $data .= gzread($file, 1024); - } - gzclose($file); - } - return $data; - } - - - /** - * Loads PHPExcel from file - * - * @param string $pFilename - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function load($pFilename) - { - // Create new PHPExcel - $objPHPExcel = new PHPExcel(); - - // Load into this instance - return $this->loadIntoExisting($pFilename, $objPHPExcel); - } - - - /** - * Loads PHPExcel from file into PHPExcel instance - * - * @param string $pFilename - * @param PHPExcel $objPHPExcel - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $timezoneObj = new DateTimeZone('Europe/London'); - $GMT = new DateTimeZone('UTC'); - - $gFileData = $this->_gzfileGetContents($pFilename); - -// echo '<pre>'; -// echo htmlentities($gFileData,ENT_QUOTES,'UTF-8'); -// echo '</pre><hr />'; + /** + * Formats + * + * @var array + */ + private $_styles = array(); + + /** + * Shared Expressions + * + * @var array + */ + private $_expressions = array(); + + private $_referenceHelper = null; + + + /** + * Create a new PHPExcel_Reader_Gnumeric + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Check if gzlib functions are available + if (!function_exists('gzread')) { + throw new PHPExcel_Reader_Exception("gzlib library is not enabled"); + } + + // Read signature data (first 3 bytes) + $fh = fopen($pFilename, 'r'); + $data = fread($fh, 2); + fclose($fh); + + if ($data != chr(0x1F).chr(0x8B)) { + return false; + } + + return true; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $xml = new XMLReader(); + $xml->xml( + $this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions() + ); + $xml->setParserProperty(2,true); + + $worksheetNames = array(); + while ($xml->read()) { + if ($xml->name == 'gnm:SheetName' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $worksheetNames[] = (string) $xml->value; + } elseif ($xml->name == 'gnm:Sheets') { + // break out of the loop once we've got our sheet names rather than parse the entire file + break; + } + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $xml = new XMLReader(); + $xml->xml( + $this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions() + ); + $xml->setParserProperty(2,true); + + $worksheetInfo = array(); + while ($xml->read()) { + if ($xml->name == 'gnm:Sheet' && $xml->nodeType == XMLReader::ELEMENT) { + $tmpInfo = array( + 'worksheetName' => '', + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, + ); + + while ($xml->read()) { + if ($xml->name == 'gnm:Name' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $tmpInfo['worksheetName'] = (string) $xml->value; + } elseif ($xml->name == 'gnm:MaxCol' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $tmpInfo['lastColumnIndex'] = (int) $xml->value; + $tmpInfo['totalColumns'] = (int) $xml->value + 1; + } elseif ($xml->name == 'gnm:MaxRow' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $tmpInfo['totalRows'] = (int) $xml->value + 1; + break; + } + } + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $worksheetInfo[] = $tmpInfo; + } + } + + return $worksheetInfo; + } + + + private function _gzfileGetContents($filename) { + $file = @gzopen($filename, 'rb'); + if ($file !== false) { + $data = ''; + while (!gzeof($file)) { + $data .= gzread($file, 1024); + } + gzclose($file); + } + return $data; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $timezoneObj = new DateTimeZone('Europe/London'); + $GMT = new DateTimeZone('UTC'); + + $gFileData = $this->_gzfileGetContents($pFilename); + +// echo '<pre>'; +// echo htmlentities($gFileData,ENT_QUOTES,'UTF-8'); +// echo '</pre><hr />'; // - $xml = simplexml_load_string($this->securityScan($gFileData), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $namespacesMeta = $xml->getNamespaces(true); + $xml = simplexml_load_string($this->securityScan($gFileData), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesMeta = $xml->getNamespaces(true); -// var_dump($namespacesMeta); +// var_dump($namespacesMeta); // - $gnmXML = $xml->children($namespacesMeta['gnm']); - - $docProps = $objPHPExcel->getProperties(); - // Document Properties are held differently, depending on the version of Gnumeric - if (isset($namespacesMeta['office'])) { - $officeXML = $xml->children($namespacesMeta['office']); - $officeDocXML = $officeXML->{'document-meta'}; - $officeDocMetaXML = $officeDocXML->meta; - - foreach($officeDocMetaXML as $officePropertyData) { - - $officePropertyDC = array(); - if (isset($namespacesMeta['dc'])) { - $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); - } - foreach($officePropertyDC as $propertyName => $propertyValue) { - $propertyValue = (string) $propertyValue; - switch ($propertyName) { - case 'title' : - $docProps->setTitle(trim($propertyValue)); - break; - case 'subject' : - $docProps->setSubject(trim($propertyValue)); - break; - case 'creator' : - $docProps->setCreator(trim($propertyValue)); - $docProps->setLastModifiedBy(trim($propertyValue)); - break; - case 'date' : - $creationDate = strtotime(trim($propertyValue)); - $docProps->setCreated($creationDate); - $docProps->setModified($creationDate); - break; - case 'description' : - $docProps->setDescription(trim($propertyValue)); - break; - } - } - $officePropertyMeta = array(); - if (isset($namespacesMeta['meta'])) { - $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); - } - foreach($officePropertyMeta as $propertyName => $propertyValue) { - $attributes = $propertyValue->attributes($namespacesMeta['meta']); - $propertyValue = (string) $propertyValue; - switch ($propertyName) { - case 'keyword' : - $docProps->setKeywords(trim($propertyValue)); - break; - case 'initial-creator' : - $docProps->setCreator(trim($propertyValue)); - $docProps->setLastModifiedBy(trim($propertyValue)); - break; - case 'creation-date' : - $creationDate = strtotime(trim($propertyValue)); - $docProps->setCreated($creationDate); - $docProps->setModified($creationDate); - break; - case 'user-defined' : - list(,$attrName) = explode(':',$attributes['name']); - switch ($attrName) { - case 'publisher' : - $docProps->setCompany(trim($propertyValue)); - break; - case 'category' : - $docProps->setCategory(trim($propertyValue)); - break; - case 'manager' : - $docProps->setManager(trim($propertyValue)); - break; - } - break; - } - } - } - } elseif (isset($gnmXML->Summary)) { - foreach($gnmXML->Summary->Item as $summaryItem) { - $propertyName = $summaryItem->name; - $propertyValue = $summaryItem->{'val-string'}; - switch ($propertyName) { - case 'title' : - $docProps->setTitle(trim($propertyValue)); - break; - case 'comments' : - $docProps->setDescription(trim($propertyValue)); - break; - case 'keywords' : - $docProps->setKeywords(trim($propertyValue)); - break; - case 'category' : - $docProps->setCategory(trim($propertyValue)); - break; - case 'manager' : - $docProps->setManager(trim($propertyValue)); - break; - case 'author' : - $docProps->setCreator(trim($propertyValue)); - $docProps->setLastModifiedBy(trim($propertyValue)); - break; - case 'company' : - $docProps->setCompany(trim($propertyValue)); - break; - } - } - } - - $worksheetID = 0; - foreach($gnmXML->Sheets->Sheet as $sheet) { - $worksheetName = (string) $sheet->Name; -// echo '<b>Worksheet: ',$worksheetName,'</b><br />'; - if ((isset($this->_loadSheetsOnly)) && (!in_array($worksheetName, $this->_loadSheetsOnly))) { - continue; - } - - $maxRow = $maxCol = 0; - - // Create new Worksheet - $objPHPExcel->createSheet(); - $objPHPExcel->setActiveSheetIndex($worksheetID); - // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula - // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet - // name in line with the formula, not the reverse - $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); - - if ((!$this->_readDataOnly) && (isset($sheet->PrintInformation))) { - if (isset($sheet->PrintInformation->Margins)) { - foreach($sheet->PrintInformation->Margins->children('gnm',TRUE) as $key => $margin) { - $marginAttributes = $margin->attributes(); - $marginSize = 72 / 100; // Default - switch($marginAttributes['PrefUnit']) { - case 'mm' : - $marginSize = intval($marginAttributes['Points']) / 100; - break; - } - switch($key) { - case 'top' : - $objPHPExcel->getActiveSheet()->getPageMargins()->setTop($marginSize); - break; - case 'bottom' : - $objPHPExcel->getActiveSheet()->getPageMargins()->setBottom($marginSize); - break; - case 'left' : - $objPHPExcel->getActiveSheet()->getPageMargins()->setLeft($marginSize); - break; - case 'right' : - $objPHPExcel->getActiveSheet()->getPageMargins()->setRight($marginSize); - break; - case 'header' : - $objPHPExcel->getActiveSheet()->getPageMargins()->setHeader($marginSize); - break; - case 'footer' : - $objPHPExcel->getActiveSheet()->getPageMargins()->setFooter($marginSize); - break; - } - } - } - } - - foreach($sheet->Cells->Cell as $cell) { - $cellAttributes = $cell->attributes(); - $row = (int) $cellAttributes->Row + 1; - $column = (int) $cellAttributes->Col; - - if ($row > $maxRow) $maxRow = $row; - if ($column > $maxCol) $maxCol = $column; - - $column = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if ($this->getReadFilter() !== NULL) { - if (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) { - continue; - } - } - - $ValueType = $cellAttributes->ValueType; - $ExprID = (string) $cellAttributes->ExprID; -// echo 'Cell ',$column,$row,'<br />'; -// echo 'Type is ',$ValueType,'<br />'; -// echo 'Value is ',$cell,'<br />'; - $type = PHPExcel_Cell_DataType::TYPE_FORMULA; - if ($ExprID > '') { - if (((string) $cell) > '') { - - $this->_expressions[$ExprID] = array( 'column' => $cellAttributes->Col, - 'row' => $cellAttributes->Row, - 'formula' => (string) $cell - ); -// echo 'NEW EXPRESSION ',$ExprID,'<br />'; - } else { - $expression = $this->_expressions[$ExprID]; - - $cell = $this->_referenceHelper->updateFormulaReferences( $expression['formula'], - 'A1', - $cellAttributes->Col - $expression['column'], - $cellAttributes->Row - $expression['row'], - $worksheetName - ); -// echo 'SHARED EXPRESSION ',$ExprID,'<br />'; -// echo 'New Value is ',$cell,'<br />'; - } - $type = PHPExcel_Cell_DataType::TYPE_FORMULA; - } else { - switch($ValueType) { - case '10' : // NULL - $type = PHPExcel_Cell_DataType::TYPE_NULL; - break; - case '20' : // Boolean - $type = PHPExcel_Cell_DataType::TYPE_BOOL; - $cell = ($cell == 'TRUE') ? True : False; - break; - case '30' : // Integer - $cell = intval($cell); - case '40' : // Float - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - break; - case '50' : // Error - $type = PHPExcel_Cell_DataType::TYPE_ERROR; - break; - case '60' : // String - $type = PHPExcel_Cell_DataType::TYPE_STRING; - break; - case '70' : // Cell Range - case '80' : // Array - } - } - $objPHPExcel->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell,$type); - } - - if ((!$this->_readDataOnly) && (isset($sheet->Objects))) { - foreach($sheet->Objects->children('gnm',TRUE) as $key => $comment) { - $commentAttributes = $comment->attributes(); - // Only comment objects are handled at the moment - if ($commentAttributes->Text) { - $objPHPExcel->getActiveSheet()->getComment( (string)$commentAttributes->ObjectBound ) - ->setAuthor( (string)$commentAttributes->Author ) - ->setText($this->_parseRichText((string)$commentAttributes->Text) ); - } - } - } -// echo '$maxCol=',$maxCol,'; $maxRow=',$maxRow,'<br />'; + $gnmXML = $xml->children($namespacesMeta['gnm']); + + $docProps = $objPHPExcel->getProperties(); + // Document Properties are held differently, depending on the version of Gnumeric + if (isset($namespacesMeta['office'])) { + $officeXML = $xml->children($namespacesMeta['office']); + $officeDocXML = $officeXML->{'document-meta'}; + $officeDocMetaXML = $officeDocXML->meta; + + foreach($officeDocMetaXML as $officePropertyData) { + + $officePropertyDC = array(); + if (isset($namespacesMeta['dc'])) { + $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); + } + foreach($officePropertyDC as $propertyName => $propertyValue) { + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'title' : + $docProps->setTitle(trim($propertyValue)); + break; + case 'subject' : + $docProps->setSubject(trim($propertyValue)); + break; + case 'creator' : + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'date' : + $creationDate = strtotime(trim($propertyValue)); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'description' : + $docProps->setDescription(trim($propertyValue)); + break; + } + } + $officePropertyMeta = array(); + if (isset($namespacesMeta['meta'])) { + $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); + } + foreach($officePropertyMeta as $propertyName => $propertyValue) { + $attributes = $propertyValue->attributes($namespacesMeta['meta']); + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'keyword' : + $docProps->setKeywords(trim($propertyValue)); + break; + case 'initial-creator' : + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'creation-date' : + $creationDate = strtotime(trim($propertyValue)); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'user-defined' : + list(,$attrName) = explode(':',$attributes['name']); + switch ($attrName) { + case 'publisher' : + $docProps->setCompany(trim($propertyValue)); + break; + case 'category' : + $docProps->setCategory(trim($propertyValue)); + break; + case 'manager' : + $docProps->setManager(trim($propertyValue)); + break; + } + break; + } + } + } + } elseif (isset($gnmXML->Summary)) { + foreach($gnmXML->Summary->Item as $summaryItem) { + $propertyName = $summaryItem->name; + $propertyValue = $summaryItem->{'val-string'}; + switch ($propertyName) { + case 'title' : + $docProps->setTitle(trim($propertyValue)); + break; + case 'comments' : + $docProps->setDescription(trim($propertyValue)); + break; + case 'keywords' : + $docProps->setKeywords(trim($propertyValue)); + break; + case 'category' : + $docProps->setCategory(trim($propertyValue)); + break; + case 'manager' : + $docProps->setManager(trim($propertyValue)); + break; + case 'author' : + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'company' : + $docProps->setCompany(trim($propertyValue)); + break; + } + } + } + + $worksheetID = 0; + foreach($gnmXML->Sheets->Sheet as $sheet) { + $worksheetName = (string) $sheet->Name; +// echo '<b>Worksheet: ',$worksheetName,'</b><br />'; + if ((isset($this->_loadSheetsOnly)) && (!in_array($worksheetName, $this->_loadSheetsOnly))) { + continue; + } + + $maxRow = $maxCol = 0; + + // Create new Worksheet + $objPHPExcel->createSheet(); + $objPHPExcel->setActiveSheetIndex($worksheetID); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula + // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet + // name in line with the formula, not the reverse + $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + + if ((!$this->_readDataOnly) && (isset($sheet->PrintInformation))) { + if (isset($sheet->PrintInformation->Margins)) { + foreach($sheet->PrintInformation->Margins->children('gnm',TRUE) as $key => $margin) { + $marginAttributes = $margin->attributes(); + $marginSize = 72 / 100; // Default + switch($marginAttributes['PrefUnit']) { + case 'mm' : + $marginSize = intval($marginAttributes['Points']) / 100; + break; + } + switch($key) { + case 'top' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setTop($marginSize); + break; + case 'bottom' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setBottom($marginSize); + break; + case 'left' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setLeft($marginSize); + break; + case 'right' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setRight($marginSize); + break; + case 'header' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setHeader($marginSize); + break; + case 'footer' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setFooter($marginSize); + break; + } + } + } + } + + foreach($sheet->Cells->Cell as $cell) { + $cellAttributes = $cell->attributes(); + $row = (int) $cellAttributes->Row + 1; + $column = (int) $cellAttributes->Col; + + if ($row > $maxRow) $maxRow = $row; + if ($column > $maxCol) $maxCol = $column; + + $column = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if ($this->getReadFilter() !== NULL) { + if (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) { + continue; + } + } + + $ValueType = $cellAttributes->ValueType; + $ExprID = (string) $cellAttributes->ExprID; +// echo 'Cell ',$column,$row,'<br />'; +// echo 'Type is ',$ValueType,'<br />'; +// echo 'Value is ',$cell,'<br />'; + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; + if ($ExprID > '') { + if (((string) $cell) > '') { + + $this->_expressions[$ExprID] = array( 'column' => $cellAttributes->Col, + 'row' => $cellAttributes->Row, + 'formula' => (string) $cell + ); +// echo 'NEW EXPRESSION ',$ExprID,'<br />'; + } else { + $expression = $this->_expressions[$ExprID]; + + $cell = $this->_referenceHelper->updateFormulaReferences( $expression['formula'], + 'A1', + $cellAttributes->Col - $expression['column'], + $cellAttributes->Row - $expression['row'], + $worksheetName + ); +// echo 'SHARED EXPRESSION ',$ExprID,'<br />'; +// echo 'New Value is ',$cell,'<br />'; + } + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; + } else { + switch($ValueType) { + case '10' : // NULL + $type = PHPExcel_Cell_DataType::TYPE_NULL; + break; + case '20' : // Boolean + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $cell = ($cell == 'TRUE') ? True : False; + break; + case '30' : // Integer + $cell = intval($cell); + case '40' : // Float + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + break; + case '50' : // Error + $type = PHPExcel_Cell_DataType::TYPE_ERROR; + break; + case '60' : // String + $type = PHPExcel_Cell_DataType::TYPE_STRING; + break; + case '70' : // Cell Range + case '80' : // Array + } + } + $objPHPExcel->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell,$type); + } + + if ((!$this->_readDataOnly) && (isset($sheet->Objects))) { + foreach($sheet->Objects->children('gnm',TRUE) as $key => $comment) { + $commentAttributes = $comment->attributes(); + // Only comment objects are handled at the moment + if ($commentAttributes->Text) { + $objPHPExcel->getActiveSheet()->getComment( (string)$commentAttributes->ObjectBound ) + ->setAuthor( (string)$commentAttributes->Author ) + ->setText($this->_parseRichText((string)$commentAttributes->Text) ); + } + } + } +// echo '$maxCol=',$maxCol,'; $maxRow=',$maxRow,'<br />'; // - foreach($sheet->Styles->StyleRegion as $styleRegion) { - $styleAttributes = $styleRegion->attributes(); - if (($styleAttributes['startRow'] <= $maxRow) && - ($styleAttributes['startCol'] <= $maxCol)) { - - $startColumn = PHPExcel_Cell::stringFromColumnIndex((int) $styleAttributes['startCol']); - $startRow = $styleAttributes['startRow'] + 1; - - $endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol']; - $endColumn = PHPExcel_Cell::stringFromColumnIndex($endColumn); - $endRow = ($styleAttributes['endRow'] > $maxRow) ? $maxRow : $styleAttributes['endRow']; - $endRow += 1; - $cellRange = $startColumn.$startRow.':'.$endColumn.$endRow; -// echo $cellRange,'<br />'; - - $styleAttributes = $styleRegion->Style->attributes(); -// var_dump($styleAttributes); -// echo '<br />'; - - // We still set the number format mask for date/time values, even if _readDataOnly is true - if ((!$this->_readDataOnly) || - (PHPExcel_Shared_Date::isDateTimeFormatCode((string) $styleAttributes['Format']))) { - $styleArray = array(); - $styleArray['numberformat']['code'] = (string) $styleAttributes['Format']; - // If _readDataOnly is false, we set all formatting information - if (!$this->_readDataOnly) { - switch($styleAttributes['HAlign']) { - case '1' : - $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; - break; - case '2' : - $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_LEFT; - break; - case '4' : - $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_RIGHT; - break; - case '8' : - $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER; - break; - case '16' : - case '64' : - $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS; - break; - case '32' : - $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY; - break; - } - - switch($styleAttributes['VAlign']) { - case '1' : - $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_TOP; - break; - case '2' : - $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; - break; - case '4' : - $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_CENTER; - break; - case '8' : - $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_JUSTIFY; - break; - } - - $styleArray['alignment']['wrap'] = ($styleAttributes['WrapText'] == '1') ? True : False; - $styleArray['alignment']['shrinkToFit'] = ($styleAttributes['ShrinkToFit'] == '1') ? True : False; - $styleArray['alignment']['indent'] = (intval($styleAttributes["Indent"]) > 0) ? $styleAttributes["indent"] : 0; - - $RGB = self::_parseGnumericColour($styleAttributes["Fore"]); - $styleArray['font']['color']['rgb'] = $RGB; - $RGB = self::_parseGnumericColour($styleAttributes["Back"]); - $shade = $styleAttributes["Shade"]; - if (($RGB != '000000') || ($shade != '0')) { - $styleArray['fill']['color']['rgb'] = $styleArray['fill']['startcolor']['rgb'] = $RGB; - $RGB2 = self::_parseGnumericColour($styleAttributes["PatternColor"]); - $styleArray['fill']['endcolor']['rgb'] = $RGB2; - switch($shade) { - case '1' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_SOLID; - break; - case '2' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR; - break; - case '3' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_PATH; - break; - case '4' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; - break; - case '5' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; - break; - case '6' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; - break; - case '7' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; - break; - case '8' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; - break; - case '9' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; - break; - case '10' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; - break; - case '11' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; - break; - case '12' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; - break; - case '13' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; - break; - case '14' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; - break; - case '15' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; - break; - case '16' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; - break; - case '17' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; - break; - case '18' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; - break; - case '19' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; - break; - case '20' : - $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; - break; - } - } - - $fontAttributes = $styleRegion->Style->Font->attributes(); -// var_dump($fontAttributes); -// echo '<br />'; - $styleArray['font']['name'] = (string) $styleRegion->Style->Font; - $styleArray['font']['size'] = intval($fontAttributes['Unit']); - $styleArray['font']['bold'] = ($fontAttributes['Bold'] == '1') ? True : False; - $styleArray['font']['italic'] = ($fontAttributes['Italic'] == '1') ? True : False; - $styleArray['font']['strike'] = ($fontAttributes['StrikeThrough'] == '1') ? True : False; - switch($fontAttributes['Underline']) { - case '1' : - $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLE; - break; - case '2' : - $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLE; - break; - case '3' : - $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING; - break; - case '4' : - $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING; - break; - default : - $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_NONE; - break; - } - switch($fontAttributes['Script']) { - case '1' : - $styleArray['font']['superScript'] = True; - break; - case '-1' : - $styleArray['font']['subScript'] = True; - break; - } - - if (isset($styleRegion->Style->StyleBorder)) { - if (isset($styleRegion->Style->StyleBorder->Top)) { - $styleArray['borders']['top'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Top->attributes()); - } - if (isset($styleRegion->Style->StyleBorder->Bottom)) { - $styleArray['borders']['bottom'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Bottom->attributes()); - } - if (isset($styleRegion->Style->StyleBorder->Left)) { - $styleArray['borders']['left'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Left->attributes()); - } - if (isset($styleRegion->Style->StyleBorder->Right)) { - $styleArray['borders']['right'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Right->attributes()); - } - if ((isset($styleRegion->Style->StyleBorder->Diagonal)) && (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}))) { - $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); - $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_BOTH; - } elseif (isset($styleRegion->Style->StyleBorder->Diagonal)) { - $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); - $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_UP; - } elseif (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'})) { - $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}->attributes()); - $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_DOWN; - } - } - if (isset($styleRegion->Style->HyperLink)) { - // TO DO - $hyperlink = $styleRegion->Style->HyperLink->attributes(); - } - } -// var_dump($styleArray); -// echo '<br />'; - $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray); - } - } - } - - if ((!$this->_readDataOnly) && (isset($sheet->Cols))) { - // Column Widths - $columnAttributes = $sheet->Cols->attributes(); - $defaultWidth = $columnAttributes['DefaultSizePts'] / 5.4; - $c = 0; - foreach($sheet->Cols->ColInfo as $columnOverride) { - $columnAttributes = $columnOverride->attributes(); - $column = $columnAttributes['No']; - $columnWidth = $columnAttributes['Unit'] / 5.4; - $hidden = ((isset($columnAttributes['Hidden'])) && ($columnAttributes['Hidden'] == '1')) ? true : false; - $columnCount = (isset($columnAttributes['Count'])) ? $columnAttributes['Count'] : 1; - while ($c < $column) { - $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth); - ++$c; - } - while (($c < ($column+$columnCount)) && ($c <= $maxCol)) { - $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($columnWidth); - if ($hidden) { - $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setVisible(false); - } - ++$c; - } - } - while ($c <= $maxCol) { - $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth); - ++$c; - } - } - - if ((!$this->_readDataOnly) && (isset($sheet->Rows))) { - // Row Heights - $rowAttributes = $sheet->Rows->attributes(); - $defaultHeight = $rowAttributes['DefaultSizePts']; - $r = 0; - - foreach($sheet->Rows->RowInfo as $rowOverride) { - $rowAttributes = $rowOverride->attributes(); - $row = $rowAttributes['No']; - $rowHeight = $rowAttributes['Unit']; - $hidden = ((isset($rowAttributes['Hidden'])) && ($rowAttributes['Hidden'] == '1')) ? true : false; - $rowCount = (isset($rowAttributes['Count'])) ? $rowAttributes['Count'] : 1; - while ($r < $row) { - ++$r; - $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight); - } - while (($r < ($row+$rowCount)) && ($r < $maxRow)) { - ++$r; - $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($rowHeight); - if ($hidden) { - $objPHPExcel->getActiveSheet()->getRowDimension($r)->setVisible(false); - } - } - } - while ($r < $maxRow) { - ++$r; - $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight); - } - } - - // Handle Merged Cells in this worksheet - if (isset($sheet->MergedRegions)) { - foreach($sheet->MergedRegions->Merge as $mergeCells) { - if (strpos($mergeCells,':') !== FALSE) { - $objPHPExcel->getActiveSheet()->mergeCells($mergeCells); - } - } - } - - $worksheetID++; - } - - // Loop through definedNames (global named ranges) - if (isset($gnmXML->Names)) { - foreach($gnmXML->Names->Name as $namedRange) { - $name = (string) $namedRange->name; - $range = (string) $namedRange->value; - if (stripos($range, '#REF!') !== false) { - continue; - } - - $range = explode('!',$range); - $range[0] = trim($range[0],"'");; - if ($worksheet = $objPHPExcel->getSheetByName($range[0])) { - $extractedRange = str_replace('$', '', $range[1]); - $objPHPExcel->addNamedRange( new PHPExcel_NamedRange($name, $worksheet, $extractedRange) ); - } - } - } - - - // Return - return $objPHPExcel; - } - - - private static function _parseBorderAttributes($borderAttributes) - { - $styleArray = array(); - - if (isset($borderAttributes["Color"])) { - $RGB = self::_parseGnumericColour($borderAttributes["Color"]); - $styleArray['color']['rgb'] = $RGB; - } - - switch ($borderAttributes["Style"]) { - case '0' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_NONE; - break; - case '1' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case '2' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; - break; - case '4' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHED; - break; - case '5' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_THICK; - break; - case '6' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOUBLE; - break; - case '7' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOTTED; - break; - case '9' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOT; - break; - case '10' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; - break; - case '11' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOTDOT; - break; - case '12' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; - break; - case '13' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; - break; - case '3' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_SLANTDASHDOT; - break; - case '8' : - $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHED; - break; - } - return $styleArray; - } - - - private function _parseRichText($is = '') { - $value = new PHPExcel_RichText(); - - $value->createText($is); - - return $value; - } - - - private static function _parseGnumericColour($gnmColour) { - list($gnmR,$gnmG,$gnmB) = explode(':',$gnmColour); - $gnmR = substr(str_pad($gnmR,4,'0',STR_PAD_RIGHT),0,2); - $gnmG = substr(str_pad($gnmG,4,'0',STR_PAD_RIGHT),0,2); - $gnmB = substr(str_pad($gnmB,4,'0',STR_PAD_RIGHT),0,2); - $RGB = $gnmR.$gnmG.$gnmB; -// echo 'Excel Colour: ',$RGB,'<br />'; - return $RGB; - } + foreach($sheet->Styles->StyleRegion as $styleRegion) { + $styleAttributes = $styleRegion->attributes(); + if (($styleAttributes['startRow'] <= $maxRow) && + ($styleAttributes['startCol'] <= $maxCol)) { + + $startColumn = PHPExcel_Cell::stringFromColumnIndex((int) $styleAttributes['startCol']); + $startRow = $styleAttributes['startRow'] + 1; + + $endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol']; + $endColumn = PHPExcel_Cell::stringFromColumnIndex($endColumn); + $endRow = ($styleAttributes['endRow'] > $maxRow) ? $maxRow : $styleAttributes['endRow']; + $endRow += 1; + $cellRange = $startColumn.$startRow.':'.$endColumn.$endRow; +// echo $cellRange,'<br />'; + + $styleAttributes = $styleRegion->Style->attributes(); +// var_dump($styleAttributes); +// echo '<br />'; + + // We still set the number format mask for date/time values, even if _readDataOnly is true + if ((!$this->_readDataOnly) || + (PHPExcel_Shared_Date::isDateTimeFormatCode((string) $styleAttributes['Format']))) { + $styleArray = array(); + $styleArray['numberformat']['code'] = (string) $styleAttributes['Format']; + // If _readDataOnly is false, we set all formatting information + if (!$this->_readDataOnly) { + switch($styleAttributes['HAlign']) { + case '1' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + break; + case '2' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_LEFT; + break; + case '4' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_RIGHT; + break; + case '8' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER; + break; + case '16' : + case '64' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS; + break; + case '32' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY; + break; + } + + switch($styleAttributes['VAlign']) { + case '1' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_TOP; + break; + case '2' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; + break; + case '4' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_CENTER; + break; + case '8' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_JUSTIFY; + break; + } + + $styleArray['alignment']['wrap'] = ($styleAttributes['WrapText'] == '1') ? True : False; + $styleArray['alignment']['shrinkToFit'] = ($styleAttributes['ShrinkToFit'] == '1') ? True : False; + $styleArray['alignment']['indent'] = (intval($styleAttributes["Indent"]) > 0) ? $styleAttributes["indent"] : 0; + + $RGB = self::_parseGnumericColour($styleAttributes["Fore"]); + $styleArray['font']['color']['rgb'] = $RGB; + $RGB = self::_parseGnumericColour($styleAttributes["Back"]); + $shade = $styleAttributes["Shade"]; + if (($RGB != '000000') || ($shade != '0')) { + $styleArray['fill']['color']['rgb'] = $styleArray['fill']['startcolor']['rgb'] = $RGB; + $RGB2 = self::_parseGnumericColour($styleAttributes["PatternColor"]); + $styleArray['fill']['endcolor']['rgb'] = $RGB2; + switch($shade) { + case '1' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_SOLID; + break; + case '2' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR; + break; + case '3' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_PATH; + break; + case '4' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; + break; + case '5' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; + break; + case '6' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; + break; + case '7' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; + break; + case '8' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; + break; + case '9' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; + break; + case '10' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; + break; + case '11' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; + break; + case '12' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; + break; + case '13' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; + break; + case '14' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; + break; + case '15' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; + break; + case '16' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; + break; + case '17' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; + break; + case '18' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; + break; + case '19' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; + break; + case '20' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; + break; + } + } + + $fontAttributes = $styleRegion->Style->Font->attributes(); +// var_dump($fontAttributes); +// echo '<br />'; + $styleArray['font']['name'] = (string) $styleRegion->Style->Font; + $styleArray['font']['size'] = intval($fontAttributes['Unit']); + $styleArray['font']['bold'] = ($fontAttributes['Bold'] == '1') ? True : False; + $styleArray['font']['italic'] = ($fontAttributes['Italic'] == '1') ? True : False; + $styleArray['font']['strike'] = ($fontAttributes['StrikeThrough'] == '1') ? True : False; + switch($fontAttributes['Underline']) { + case '1' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLE; + break; + case '2' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLE; + break; + case '3' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING; + break; + case '4' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING; + break; + default : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_NONE; + break; + } + switch($fontAttributes['Script']) { + case '1' : + $styleArray['font']['superScript'] = True; + break; + case '-1' : + $styleArray['font']['subScript'] = True; + break; + } + + if (isset($styleRegion->Style->StyleBorder)) { + if (isset($styleRegion->Style->StyleBorder->Top)) { + $styleArray['borders']['top'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Top->attributes()); + } + if (isset($styleRegion->Style->StyleBorder->Bottom)) { + $styleArray['borders']['bottom'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Bottom->attributes()); + } + if (isset($styleRegion->Style->StyleBorder->Left)) { + $styleArray['borders']['left'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Left->attributes()); + } + if (isset($styleRegion->Style->StyleBorder->Right)) { + $styleArray['borders']['right'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Right->attributes()); + } + if ((isset($styleRegion->Style->StyleBorder->Diagonal)) && (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}))) { + $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); + $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_BOTH; + } elseif (isset($styleRegion->Style->StyleBorder->Diagonal)) { + $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); + $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_UP; + } elseif (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'})) { + $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}->attributes()); + $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_DOWN; + } + } + if (isset($styleRegion->Style->HyperLink)) { + // TO DO + $hyperlink = $styleRegion->Style->HyperLink->attributes(); + } + } +// var_dump($styleArray); +// echo '<br />'; + $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray); + } + } + } + + if ((!$this->_readDataOnly) && (isset($sheet->Cols))) { + // Column Widths + $columnAttributes = $sheet->Cols->attributes(); + $defaultWidth = $columnAttributes['DefaultSizePts'] / 5.4; + $c = 0; + foreach($sheet->Cols->ColInfo as $columnOverride) { + $columnAttributes = $columnOverride->attributes(); + $column = $columnAttributes['No']; + $columnWidth = $columnAttributes['Unit'] / 5.4; + $hidden = ((isset($columnAttributes['Hidden'])) && ($columnAttributes['Hidden'] == '1')) ? true : false; + $columnCount = (isset($columnAttributes['Count'])) ? $columnAttributes['Count'] : 1; + while ($c < $column) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth); + ++$c; + } + while (($c < ($column+$columnCount)) && ($c <= $maxCol)) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($columnWidth); + if ($hidden) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setVisible(false); + } + ++$c; + } + } + while ($c <= $maxCol) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth); + ++$c; + } + } + + if ((!$this->_readDataOnly) && (isset($sheet->Rows))) { + // Row Heights + $rowAttributes = $sheet->Rows->attributes(); + $defaultHeight = $rowAttributes['DefaultSizePts']; + $r = 0; + + foreach($sheet->Rows->RowInfo as $rowOverride) { + $rowAttributes = $rowOverride->attributes(); + $row = $rowAttributes['No']; + $rowHeight = $rowAttributes['Unit']; + $hidden = ((isset($rowAttributes['Hidden'])) && ($rowAttributes['Hidden'] == '1')) ? true : false; + $rowCount = (isset($rowAttributes['Count'])) ? $rowAttributes['Count'] : 1; + while ($r < $row) { + ++$r; + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight); + } + while (($r < ($row+$rowCount)) && ($r < $maxRow)) { + ++$r; + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($rowHeight); + if ($hidden) { + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setVisible(false); + } + } + } + while ($r < $maxRow) { + ++$r; + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight); + } + } + + // Handle Merged Cells in this worksheet + if (isset($sheet->MergedRegions)) { + foreach($sheet->MergedRegions->Merge as $mergeCells) { + if (strpos($mergeCells,':') !== FALSE) { + $objPHPExcel->getActiveSheet()->mergeCells($mergeCells); + } + } + } + + $worksheetID++; + } + + // Loop through definedNames (global named ranges) + if (isset($gnmXML->Names)) { + foreach($gnmXML->Names->Name as $namedRange) { + $name = (string) $namedRange->name; + $range = (string) $namedRange->value; + if (stripos($range, '#REF!') !== false) { + continue; + } + + $range = explode('!',$range); + $range[0] = trim($range[0],"'");; + if ($worksheet = $objPHPExcel->getSheetByName($range[0])) { + $extractedRange = str_replace('$', '', $range[1]); + $objPHPExcel->addNamedRange( new PHPExcel_NamedRange($name, $worksheet, $extractedRange) ); + } + } + } + + + // Return + return $objPHPExcel; + } + + + private static function _parseBorderAttributes($borderAttributes) + { + $styleArray = array(); + + if (isset($borderAttributes["Color"])) { + $RGB = self::_parseGnumericColour($borderAttributes["Color"]); + $styleArray['color']['rgb'] = $RGB; + } + + switch ($borderAttributes["Style"]) { + case '0' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_NONE; + break; + case '1' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case '2' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; + break; + case '4' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHED; + break; + case '5' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_THICK; + break; + case '6' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOUBLE; + break; + case '7' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOTTED; + break; + case '9' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOT; + break; + case '10' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; + break; + case '11' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOTDOT; + break; + case '12' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + break; + case '13' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + break; + case '3' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_SLANTDASHDOT; + break; + case '8' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHED; + break; + } + return $styleArray; + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText($is); + + return $value; + } + + + private static function _parseGnumericColour($gnmColour) { + list($gnmR,$gnmG,$gnmB) = explode(':',$gnmColour); + $gnmR = substr(str_pad($gnmR,4,'0',STR_PAD_RIGHT),0,2); + $gnmG = substr(str_pad($gnmG,4,'0',STR_PAD_RIGHT),0,2); + $gnmB = substr(str_pad($gnmB,4,'0',STR_PAD_RIGHT),0,2); + $RGB = $gnmR.$gnmG.$gnmB; +// echo 'Excel Colour: ',$RGB,'<br />'; + return $RGB; + } } diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 68fd30c8b..6b60f3f01 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -22,7 +22,7 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ @@ -67,38 +67,38 @@ class PHPExcel_Reader_HTML extends PHPExcel_Reader_Abstract implements PHPExcel_ 'h1' => array('font' => array('bold' => true, 'size' => 24, ), - ), // Bold, 24pt + ), // Bold, 24pt 'h2' => array('font' => array('bold' => true, 'size' => 18, ), - ), // Bold, 18pt + ), // Bold, 18pt 'h3' => array('font' => array('bold' => true, 'size' => 13.5, ), - ), // Bold, 13.5pt + ), // Bold, 13.5pt 'h4' => array('font' => array('bold' => true, 'size' => 12, ), - ), // Bold, 12pt + ), // Bold, 12pt 'h5' => array('font' => array('bold' => true, 'size' => 10, ), - ), // Bold, 10pt + ), // Bold, 10pt 'h6' => array('font' => array('bold' => true, 'size' => 7.5, ), - ), // Bold, 7.5pt + ), // Bold, 7.5pt 'a' => array('font' => array('underline' => true, 'color' => array('argb' => PHPExcel_Style_Color::COLOR_BLUE, ), ), - ), // Blue underlined + ), // Blue underlined 'hr' => array('borders' => array('bottom' => array('style' => PHPExcel_Style_Border::BORDER_THIN, 'color' => array(\PHPExcel_Style_Color::COLOR_BLACK, ), ), ), - ), // Bottom border + ), // Bottom border ); protected $rowspan = array(); @@ -118,7 +118,7 @@ public function __construct() */ protected function _isValidFormat() { - // Reading 2048 bytes should be enough to validate that the format is HTML + // Reading 2048 bytes should be enough to validate that the format is HTML $data = fread($this->_fileHandle, 2048); if ((strpos($data, '<') !== FALSE) && (strlen($data) !== strlen(strip_tags($data)))) { @@ -166,7 +166,7 @@ public function getInputEncoding() return $this->_inputEncoding; } - // Data Array used for testing only, should write to PHPExcel object on completion of tests + // Data Array used for testing only, should write to PHPExcel object on completion of tests protected $_dataArray = array(); protected $_tableLevel = 0; protected $_nestedColumn = array('A'); @@ -196,18 +196,18 @@ protected function _releaseTableStartColumn() protected function _flushCell($sheet, $column, $row, &$cellContent) { if (is_string($cellContent)) { - // Simple String content + // Simple String content if (trim($cellContent) > '') { - // Only actually write it if there's content in the string -// echo 'FLUSH CELL: ' , $column , $row , ' => ' , $cellContent , '<br />'; - // Write to worksheet to be done here... - // ... we return the cell so we can mess about with styles more easily + // Only actually write it if there's content in the string +// echo 'FLUSH CELL: ' , $column , $row , ' => ' , $cellContent , '<br />'; + // Write to worksheet to be done here... + // ... we return the cell so we can mess about with styles more easily $sheet->setCellValue($column . $row, $cellContent, true); $this->_dataArray[$row][$column] = $cellContent; } } else { - // We have a Rich Text run - // TODO + // We have a Rich Text run + // TODO $this->_dataArray[$row][$column] = 'RICH TEXT: ' . $cellContent; } $cellContent = (string) ''; @@ -219,18 +219,18 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, if ($child instanceof DOMText) { $domText = preg_replace('/\s+/u', ' ', trim($child->nodeValue)); if (is_string($cellContent)) { - // simply append the text if the cell content is a plain text string + // simply append the text if the cell content is a plain text string $cellContent .= $domText; } else { - // but if we have a rich text run instead, we need to append it correctly - // TODO + // but if we have a rich text run instead, we need to append it correctly + // TODO } } elseif ($child instanceof DOMElement) { -// echo '<b>DOM ELEMENT: </b>' , strtoupper($child->nodeName) , '<br />'; +// echo '<b>DOM ELEMENT: </b>' , strtoupper($child->nodeName) , '<br />'; $attributeArray = array(); foreach ($child->attributes as $attribute) { -// echo '<b>ATTRIBUTE: </b>' , $attribute->name , ' => ' , $attribute->value , '<br />'; +// echo '<b>ATTRIBUTE: </b>' , $attribute->name , ' => ' , $attribute->value , '<br />'; $attributeArray[$attribute->name] = $attribute->value; } @@ -239,8 +239,8 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, foreach ($attributeArray as $attributeName => $attributeValue) { switch ($attributeName) { case 'content': - // TODO - // Extract character set, so we can convert to UTF-8 if required + // TODO + // Extract character set, so we can convert to UTF-8 if required break; } } @@ -258,13 +258,13 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, case 'em' : case 'strong': case 'b' : -// echo 'STYLING, SPAN OR DIV<br />'; +// echo 'STYLING, SPAN OR DIV<br />'; if ($cellContent > '') $cellContent .= ' '; $this->_processDomElement($child, $sheet, $row, $column, $cellContent); if ($cellContent > '') $cellContent .= ' '; -// echo 'END OF STYLING, SPAN OR DIV<br />'; +// echo 'END OF STYLING, SPAN OR DIV<br />'; break; case 'hr' : $this->_flushCell($sheet, $column, $row, $cellContent); @@ -278,21 +278,21 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, ++$row; case 'br' : if ($this->_tableLevel > 0) { - // If we're inside a table, replace with a \n + // If we're inside a table, replace with a \n $cellContent .= "\n"; } else { - // Otherwise flush our existing content and move the row cursor on + // Otherwise flush our existing content and move the row cursor on $this->_flushCell($sheet, $column, $row, $cellContent); ++$row; } -// echo 'HARD LINE BREAK: ' , '<br />'; +// echo 'HARD LINE BREAK: ' , '<br />'; break; case 'a' : -// echo 'START OF HYPERLINK: ' , '<br />'; +// echo 'START OF HYPERLINK: ' , '<br />'; foreach ($attributeArray as $attributeName => $attributeValue) { switch ($attributeName) { case 'href': -// echo 'Link to ' , $attributeValue , '<br />'; +// echo 'Link to ' , $attributeValue , '<br />'; $sheet->getCell($column . $row)->getHyperlink()->setUrl($attributeValue); if (isset($this->_formats[$child->nodeName])) { $sheet->getStyle($column . $row)->applyFromArray($this->_formats[$child->nodeName]); @@ -302,7 +302,7 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, } $cellContent .= ' '; $this->_processDomElement($child, $sheet, $row, $column, $cellContent); -// echo 'END OF HYPERLINK:' , '<br />'; +// echo 'END OF HYPERLINK:' , '<br />'; break; case 'h1' : case 'h2' : @@ -314,19 +314,19 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, case 'ul' : case 'p' : if ($this->_tableLevel > 0) { - // If we're inside a table, replace with a \n + // If we're inside a table, replace with a \n $cellContent .= "\n"; -// echo 'LIST ENTRY: ' , '<br />'; +// echo 'LIST ENTRY: ' , '<br />'; $this->_processDomElement($child, $sheet, $row, $column, $cellContent); -// echo 'END OF LIST ENTRY:' , '<br />'; +// echo 'END OF LIST ENTRY:' , '<br />'; } else { if ($cellContent > '') { $this->_flushCell($sheet, $column, $row, $cellContent); $row++; } -// echo 'START OF PARAGRAPH: ' , '<br />'; +// echo 'START OF PARAGRAPH: ' , '<br />'; $this->_processDomElement($child, $sheet, $row, $column, $cellContent); -// echo 'END OF PARAGRAPH:' , '<br />'; +// echo 'END OF PARAGRAPH:' , '<br />'; $this->_flushCell($sheet, $column, $row, $cellContent); if (isset($this->_formats[$child->nodeName])) { @@ -339,19 +339,19 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, break; case 'li' : if ($this->_tableLevel > 0) { - // If we're inside a table, replace with a \n + // If we're inside a table, replace with a \n $cellContent .= "\n"; -// echo 'LIST ENTRY: ' , '<br />'; +// echo 'LIST ENTRY: ' , '<br />'; $this->_processDomElement($child, $sheet, $row, $column, $cellContent); -// echo 'END OF LIST ENTRY:' , '<br />'; +// echo 'END OF LIST ENTRY:' , '<br />'; } else { if ($cellContent > '') { $this->_flushCell($sheet, $column, $row, $cellContent); } ++$row; -// echo 'LIST ENTRY: ' , '<br />'; +// echo 'LIST ENTRY: ' , '<br />'; $this->_processDomElement($child, $sheet, $row, $column, $cellContent); -// echo 'END OF LIST ENTRY:' , '<br />'; +// echo 'END OF LIST ENTRY:' , '<br />'; $this->_flushCell($sheet, $column, $row, $cellContent); $column = 'A'; } @@ -359,11 +359,11 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, case 'table' : $this->_flushCell($sheet, $column, $row, $cellContent); $column = $this->_setTableStartColumn($column); -// echo 'START OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; +// echo 'START OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; if ($this->_tableLevel > 1) --$row; $this->_processDomElement($child, $sheet, $row, $column, $cellContent); -// echo 'END OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; +// echo 'END OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; $column = $this->_releaseTableStartColumn(); if ($this->_tableLevel > 1) { ++$column; @@ -378,16 +378,16 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, case 'tr' : $column = $this->_getTableStartColumn(); $cellContent = ''; -// echo 'START OF TABLE ' , $this->_tableLevel , ' ROW<br />'; +// echo 'START OF TABLE ' , $this->_tableLevel , ' ROW<br />'; $this->_processDomElement($child, $sheet, $row, $column, $cellContent); ++$row; -// echo 'END OF TABLE ' , $this->_tableLevel , ' ROW<br />'; +// echo 'END OF TABLE ' , $this->_tableLevel , ' ROW<br />'; break; case 'th' : case 'td' : -// echo 'START OF TABLE ' , $this->_tableLevel , ' CELL<br />'; +// echo 'START OF TABLE ' , $this->_tableLevel , ' CELL<br />'; $this->_processDomElement($child, $sheet, $row, $column, $cellContent); -// echo 'END OF TABLE ' , $this->_tableLevel , ' CELL<br />'; +// echo 'END OF TABLE ' , $this->_tableLevel , ' CELL<br />'; while (isset($this->rowspan[$column . $row])) { ++$column; @@ -463,7 +463,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) fclose($this->_fileHandle); throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid HTML file."); } - // Close after validating + // Close after validating fclose($this->_fileHandle); // Create new PHPExcel @@ -472,15 +472,15 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); - // Create a new DOM object + // Create a new DOM object $dom = new domDocument; - // Reload the HTML file into the DOM object + // Reload the HTML file into the DOM object $loaded = $dom->loadHTML($this->securityScanFile($pFilename)); if ($loaded === FALSE) { throw new PHPExcel_Reader_Exception('Failed to load ', $pFilename, ' as a DOM Document'); } - // Discard white space + // Discard white space $dom->preserveWhiteSpace = false; $row = 0; @@ -488,7 +488,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $content = ''; $this->_processDomElement($dom, $objPHPExcel->getActiveSheet(), $row, $column, $content); - // Return + // Return return $objPHPExcel; } @@ -515,14 +515,14 @@ public function setSheetIndex($pValue = 0) return $this; } - /** - * Scan theXML for use of <!ENTITY to prevent XXE/XEE attacks - * - * @param string $xml - * @throws PHPExcel_Reader_Exception - */ - public function securityScan($xml) - { + /** + * Scan theXML for use of <!ENTITY to prevent XXE/XEE attacks + * + * @param string $xml + * @throws PHPExcel_Reader_Exception + */ + public function securityScan($xml) + { $pattern = '/\\0?' . implode('\\0?', str_split('<!ENTITY')) . '\\0?/'; if (preg_match($pattern, $xml)) { throw new PHPExcel_Reader_Exception('Detected use of ENTITY in XML, spreadsheet file load() aborted to prevent XXE/XEE attacks'); diff --git a/Classes/PHPExcel/Reader/IReadFilter.php b/Classes/PHPExcel/Reader/IReadFilter.php index f20dd97a1..0006cf3dc 100644 --- a/Classes/PHPExcel/Reader/IReadFilter.php +++ b/Classes/PHPExcel/Reader/IReadFilter.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Reader_IReadFilter * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,27 +22,18 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Reader_IReadFilter - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ interface PHPExcel_Reader_IReadFilter { - /** - * Should this cell be read? - * - * @param $column String column index - * @param $row Row index - * @param $worksheetName Optional worksheet name - * @return boolean - */ - public function readCell($column, $row, $worksheetName = ''); + /** + * Should this cell be read? + * + * @param $column String column index + * @param $row Row index + * @param $worksheetName Optional worksheet name + * @return boolean + */ + public function readCell($column, $row, $worksheetName = ''); } diff --git a/Classes/PHPExcel/Reader/IReader.php b/Classes/PHPExcel/Reader/IReader.php index bc3a4bd8c..79d098f8d 100644 --- a/Classes/PHPExcel/Reader/IReader.php +++ b/Classes/PHPExcel/Reader/IReader.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,20 +35,20 @@ */ interface PHPExcel_Reader_IReader { - /** - * Can the current PHPExcel_Reader_IReader read the file? - * - * @param string $pFilename - * @return boolean - */ - public function canRead($pFilename); + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + */ + public function canRead($pFilename); - /** - * Loads PHPExcel from file - * - * @param string $pFilename + /** + * Loads PHPExcel from file + * + * @param string $pFilename * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function load($pFilename); + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename); } diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 888aefb65..663bc813a 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -21,691 +21,691 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** * PHPExcel_Reader_OOCalc * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { - /** - * Formats - * - * @var array - */ - private $_styles = array(); - - - /** - * Create a new PHPExcel_Reader_OOCalc - */ - public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - } - - - /** - * Can the current PHPExcel_Reader_IReader read the file? - * - * @param string $pFilename - * @return boolean - * @throws PHPExcel_Reader_Exception - */ - public function canRead($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } + /** + * Formats + * + * @var array + */ + private $_styles = array(); + + + /** + * Create a new PHPExcel_Reader_OOCalc + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } $zipClass = PHPExcel_Settings::getZipClass(); - // Check if zip class exists -// if (!class_exists($zipClass, FALSE)) { -// throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); -// } + // Check if zip class exists +// if (!class_exists($zipClass, FALSE)) { +// throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); +// } $mimeType = 'UNKNOWN'; - // Load file - $zip = new $zipClass; - if ($zip->open($pFilename) === true) { - // check if it is an OOXML archive - $stat = $zip->statName('mimetype'); - if ($stat && ($stat['size'] <= 255)) { - $mimeType = $zip->getFromName($stat['name']); - } elseif($stat = $zip->statName('META-INF/manifest.xml')) { - $xml = simplexml_load_string($this->securityScan($zip->getFromName('META-INF/manifest.xml')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $namespacesContent = $xml->getNamespaces(true); - if (isset($namespacesContent['manifest'])) { - $manifest = $xml->children($namespacesContent['manifest']); - foreach($manifest as $manifestDataSet) { - $manifestAttributes = $manifestDataSet->attributes($namespacesContent['manifest']); - if ($manifestAttributes->{'full-path'} == '/') { - $mimeType = (string) $manifestAttributes->{'media-type'}; - break; - } - } - } - } - - $zip->close(); - - return ($mimeType === 'application/vnd.oasis.opendocument.spreadsheet'); - } - - return FALSE; - } - - - /** - * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetNames($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } + // Load file + $zip = new $zipClass; + if ($zip->open($pFilename) === true) { + // check if it is an OOXML archive + $stat = $zip->statName('mimetype'); + if ($stat && ($stat['size'] <= 255)) { + $mimeType = $zip->getFromName($stat['name']); + } elseif($stat = $zip->statName('META-INF/manifest.xml')) { + $xml = simplexml_load_string($this->securityScan($zip->getFromName('META-INF/manifest.xml')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesContent = $xml->getNamespaces(true); + if (isset($namespacesContent['manifest'])) { + $manifest = $xml->children($namespacesContent['manifest']); + foreach($manifest as $manifestDataSet) { + $manifestAttributes = $manifestDataSet->attributes($namespacesContent['manifest']); + if ($manifestAttributes->{'full-path'} == '/') { + $mimeType = (string) $manifestAttributes->{'media-type'}; + break; + } + } + } + } + + $zip->close(); + + return ($mimeType === 'application/vnd.oasis.opendocument.spreadsheet'); + } + + return FALSE; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } $zipClass = PHPExcel_Settings::getZipClass(); - $zip = new $zipClass; - if (!$zip->open($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); - } - - $worksheetNames = array(); - - $xml = new XMLReader(); - $res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions()); - $xml->setParserProperty(2,true); - - // Step into the first level of content of the XML - $xml->read(); - while ($xml->read()) { - // Quickly jump through to the office:body node - while ($xml->name !== 'office:body') { - if ($xml->isEmptyElement) - $xml->read(); - else - $xml->next(); - } - // Now read each node until we find our first table:table node - while ($xml->read()) { - if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) { - // Loop through each table:table node reading the table:name attribute for each worksheet name - do { - $worksheetNames[] = $xml->getAttribute('table:name'); - $xml->next(); - } while ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT); - } - } - } - - return $worksheetNames; - } - - - /** - * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetInfo($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $worksheetInfo = array(); + $zip = new $zipClass; + if (!$zip->open($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); + } + + $worksheetNames = array(); + + $xml = new XMLReader(); + $res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml->setParserProperty(2,true); + + // Step into the first level of content of the XML + $xml->read(); + while ($xml->read()) { + // Quickly jump through to the office:body node + while ($xml->name !== 'office:body') { + if ($xml->isEmptyElement) + $xml->read(); + else + $xml->next(); + } + // Now read each node until we find our first table:table node + while ($xml->read()) { + if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) { + // Loop through each table:table node reading the table:name attribute for each worksheet name + do { + $worksheetNames[] = $xml->getAttribute('table:name'); + $xml->next(); + } while ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT); + } + } + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); $zipClass = PHPExcel_Settings::getZipClass(); - $zip = new $zipClass; - if (!$zip->open($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); - } - - $xml = new XMLReader(); - $res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions()); - $xml->setParserProperty(2,true); - - // Step into the first level of content of the XML - $xml->read(); - while ($xml->read()) { - // Quickly jump through to the office:body node - while ($xml->name !== 'office:body') { - if ($xml->isEmptyElement) - $xml->read(); - else - $xml->next(); - } - // Now read each node until we find our first table:table node - while ($xml->read()) { - if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) { - $worksheetNames[] = $xml->getAttribute('table:name'); - - $tmpInfo = array( - 'worksheetName' => $xml->getAttribute('table:name'), - 'lastColumnLetter' => 'A', - 'lastColumnIndex' => 0, - 'totalRows' => 0, - 'totalColumns' => 0, - ); - - // Loop through each child node of the table:table element reading - $currCells = 0; - do { - $xml->read(); - if ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) { - $rowspan = $xml->getAttribute('table:number-rows-repeated'); - $rowspan = empty($rowspan) ? 1 : $rowspan; - $tmpInfo['totalRows'] += $rowspan; - $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); - $currCells = 0; - // Step into the row - $xml->read(); - do { - if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) { - if (!$xml->isEmptyElement) { - $currCells++; - $xml->next(); - } else { - $xml->read(); - } - } elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) { - $mergeSize = $xml->getAttribute('table:number-columns-repeated'); - $currCells += $mergeSize; - $xml->read(); - } - } while ($xml->name != 'table:table-row'); - } - } while ($xml->name != 'table:table'); - - $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); - $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; - $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); - $worksheetInfo[] = $tmpInfo; - } - } - -// foreach($workbookData->table as $worksheetDataSet) { -// $worksheetData = $worksheetDataSet->children($namespacesContent['table']); -// $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']); + $zip = new $zipClass; + if (!$zip->open($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); + } + + $xml = new XMLReader(); + $res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml->setParserProperty(2,true); + + // Step into the first level of content of the XML + $xml->read(); + while ($xml->read()) { + // Quickly jump through to the office:body node + while ($xml->name !== 'office:body') { + if ($xml->isEmptyElement) + $xml->read(); + else + $xml->next(); + } + // Now read each node until we find our first table:table node + while ($xml->read()) { + if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) { + $worksheetNames[] = $xml->getAttribute('table:name'); + + $tmpInfo = array( + 'worksheetName' => $xml->getAttribute('table:name'), + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, + ); + + // Loop through each child node of the table:table element reading + $currCells = 0; + do { + $xml->read(); + if ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) { + $rowspan = $xml->getAttribute('table:number-rows-repeated'); + $rowspan = empty($rowspan) ? 1 : $rowspan; + $tmpInfo['totalRows'] += $rowspan; + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $currCells = 0; + // Step into the row + $xml->read(); + do { + if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) { + if (!$xml->isEmptyElement) { + $currCells++; + $xml->next(); + } else { + $xml->read(); + } + } elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) { + $mergeSize = $xml->getAttribute('table:number-columns-repeated'); + $currCells += $mergeSize; + $xml->read(); + } + } while ($xml->name != 'table:table-row'); + } + } while ($xml->name != 'table:table'); + + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $worksheetInfo[] = $tmpInfo; + } + } + +// foreach($workbookData->table as $worksheetDataSet) { +// $worksheetData = $worksheetDataSet->children($namespacesContent['table']); +// $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']); // -// $rowIndex = 0; -// foreach ($worksheetData as $key => $rowData) { -// switch ($key) { -// case 'table-row' : -// $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); -// $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? -// $rowDataTableAttributes['number-rows-repeated'] : 1; -// $columnIndex = 0; +// $rowIndex = 0; +// foreach ($worksheetData as $key => $rowData) { +// switch ($key) { +// case 'table-row' : +// $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); +// $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? +// $rowDataTableAttributes['number-rows-repeated'] : 1; +// $columnIndex = 0; // -// foreach ($rowData as $key => $cellData) { -// $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']); -// $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? -// $cellDataTableAttributes['number-columns-repeated'] : 1; -// $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']); -// if (isset($cellDataOfficeAttributes['value-type'])) { -// $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex + $colRepeats - 1); -// $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex + $rowRepeats); -// } -// $columnIndex += $colRepeats; -// } -// $rowIndex += $rowRepeats; -// break; -// } -// } +// foreach ($rowData as $key => $cellData) { +// $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']); +// $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? +// $cellDataTableAttributes['number-columns-repeated'] : 1; +// $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']); +// if (isset($cellDataOfficeAttributes['value-type'])) { +// $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex + $colRepeats - 1); +// $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex + $rowRepeats); +// } +// $columnIndex += $colRepeats; +// } +// $rowIndex += $rowRepeats; +// break; +// } +// } // -// $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); -// $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; +// $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); +// $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; // -// } -// } - } - - return $worksheetInfo; - } - - - /** - * Loads PHPExcel from file - * - * @param string $pFilename - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function load($pFilename) - { - // Create new PHPExcel - $objPHPExcel = new PHPExcel(); - - // Load into this instance - return $this->loadIntoExisting($pFilename, $objPHPExcel); - } - - - private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { - $styleAttributeValue = strtolower($styleAttributeValue); - foreach($styleList as $style) { - if ($styleAttributeValue == strtolower($style)) { - $styleAttributeValue = $style; - return true; - } - } - return false; - } - - - /** - * Loads PHPExcel from file into PHPExcel instance - * - * @param string $pFilename - * @param PHPExcel $objPHPExcel - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $timezoneObj = new DateTimeZone('Europe/London'); - $GMT = new DateTimeZone('UTC'); +// } +// } + } + + return $worksheetInfo; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + + private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { + $styleAttributeValue = strtolower($styleAttributeValue); + foreach($styleList as $style) { + if ($styleAttributeValue == strtolower($style)) { + $styleAttributeValue = $style; + return true; + } + } + return false; + } + + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $timezoneObj = new DateTimeZone('Europe/London'); + $GMT = new DateTimeZone('UTC'); $zipClass = PHPExcel_Settings::getZipClass(); - $zip = new $zipClass; - if (!$zip->open($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); - } - -// echo '<h1>Meta Information</h1>'; - $xml = simplexml_load_string($this->securityScan($zip->getFromName("meta.xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $namespacesMeta = $xml->getNamespaces(true); -// echo '<pre>'; -// print_r($namespacesMeta); -// echo '</pre><hr />'; - - $docProps = $objPHPExcel->getProperties(); - $officeProperty = $xml->children($namespacesMeta['office']); - foreach($officeProperty as $officePropertyData) { - $officePropertyDC = array(); - if (isset($namespacesMeta['dc'])) { - $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); - } - foreach($officePropertyDC as $propertyName => $propertyValue) { - $propertyValue = (string) $propertyValue; - switch ($propertyName) { - case 'title' : - $docProps->setTitle($propertyValue); - break; - case 'subject' : - $docProps->setSubject($propertyValue); - break; - case 'creator' : - $docProps->setCreator($propertyValue); - $docProps->setLastModifiedBy($propertyValue); - break; - case 'date' : - $creationDate = strtotime($propertyValue); - $docProps->setCreated($creationDate); - $docProps->setModified($creationDate); - break; - case 'description' : - $docProps->setDescription($propertyValue); - break; - } - } - $officePropertyMeta = array(); - if (isset($namespacesMeta['dc'])) { - $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); - } - foreach($officePropertyMeta as $propertyName => $propertyValue) { - $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']); - $propertyValue = (string) $propertyValue; - switch ($propertyName) { - case 'initial-creator' : - $docProps->setCreator($propertyValue); - break; - case 'keyword' : - $docProps->setKeywords($propertyValue); - break; - case 'creation-date' : - $creationDate = strtotime($propertyValue); - $docProps->setCreated($creationDate); - break; - case 'user-defined' : - $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; - foreach ($propertyValueAttributes as $key => $value) { - if ($key == 'name') { - $propertyValueName = (string) $value; - } elseif($key == 'value-type') { - switch ($value) { - case 'date' : - $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date'); - $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; - break; - case 'boolean' : - $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'bool'); - $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; - break; - case 'float' : - $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'r4'); - $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; - break; - default : - $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; - } - } - } - $docProps->setCustomProperty($propertyValueName,$propertyValue,$propertyValueType); - break; - } - } - } - - -// echo '<h1>Workbook Content</h1>'; - $xml = simplexml_load_string($this->securityScan($zip->getFromName("content.xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $namespacesContent = $xml->getNamespaces(true); -// echo '<pre>'; -// print_r($namespacesContent); -// echo '</pre><hr />'; - - $workbook = $xml->children($namespacesContent['office']); - foreach($workbook->body->spreadsheet as $workbookData) { - $workbookData = $workbookData->children($namespacesContent['table']); - $worksheetID = 0; - foreach($workbookData->table as $worksheetDataSet) { - $worksheetData = $worksheetDataSet->children($namespacesContent['table']); -// print_r($worksheetData); -// echo '<br />'; - $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']); -// print_r($worksheetDataAttributes); -// echo '<br />'; - if ((isset($this->_loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) && - (!in_array($worksheetDataAttributes['name'], $this->_loadSheetsOnly))) { - continue; - } - -// echo '<h2>Worksheet '.$worksheetDataAttributes['name'].'</h2>'; - // Create new Worksheet - $objPHPExcel->createSheet(); - $objPHPExcel->setActiveSheetIndex($worksheetID); - if (isset($worksheetDataAttributes['name'])) { - $worksheetName = (string) $worksheetDataAttributes['name']; - // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in - // formula cells... during the load, all formulae should be correct, and we're simply - // bringing the worksheet name in line with the formula, not the reverse - $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); - } - - $rowID = 1; - foreach($worksheetData as $key => $rowData) { -// echo '<b>'.$key.'</b><br />'; - switch ($key) { - case 'table-header-rows': - foreach ($rowData as $key=>$cellData) { - $rowData = $cellData; - break; - } - case 'table-row' : - $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); - $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? - $rowDataTableAttributes['number-rows-repeated'] : 1; - $columnID = 'A'; - foreach($rowData as $key => $cellData) { - if ($this->getReadFilter() !== NULL) { - if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { - continue; - } - } - -// echo '<b>'.$columnID.$rowID.'</b><br />'; - $cellDataText = (isset($namespacesContent['text'])) ? - $cellData->children($namespacesContent['text']) : - ''; - $cellDataOffice = $cellData->children($namespacesContent['office']); - $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']); - $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']); - -// echo 'Office Attributes: '; -// print_r($cellDataOfficeAttributes); -// echo '<br />Table Attributes: '; -// print_r($cellDataTableAttributes); -// echo '<br />Cell Data Text'; -// print_r($cellDataText); -// echo '<br />'; + $zip = new $zipClass; + if (!$zip->open($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); + } + +// echo '<h1>Meta Information</h1>'; + $xml = simplexml_load_string($this->securityScan($zip->getFromName("meta.xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesMeta = $xml->getNamespaces(true); +// echo '<pre>'; +// print_r($namespacesMeta); +// echo '</pre><hr />'; + + $docProps = $objPHPExcel->getProperties(); + $officeProperty = $xml->children($namespacesMeta['office']); + foreach($officeProperty as $officePropertyData) { + $officePropertyDC = array(); + if (isset($namespacesMeta['dc'])) { + $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); + } + foreach($officePropertyDC as $propertyName => $propertyValue) { + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'title' : + $docProps->setTitle($propertyValue); + break; + case 'subject' : + $docProps->setSubject($propertyValue); + break; + case 'creator' : + $docProps->setCreator($propertyValue); + $docProps->setLastModifiedBy($propertyValue); + break; + case 'date' : + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'description' : + $docProps->setDescription($propertyValue); + break; + } + } + $officePropertyMeta = array(); + if (isset($namespacesMeta['dc'])) { + $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); + } + foreach($officePropertyMeta as $propertyName => $propertyValue) { + $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']); + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'initial-creator' : + $docProps->setCreator($propertyValue); + break; + case 'keyword' : + $docProps->setKeywords($propertyValue); + break; + case 'creation-date' : + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + break; + case 'user-defined' : + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; + foreach ($propertyValueAttributes as $key => $value) { + if ($key == 'name') { + $propertyValueName = (string) $value; + } elseif($key == 'value-type') { + switch ($value) { + case 'date' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; + break; + case 'boolean' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'bool'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; + break; + case 'float' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'r4'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; + break; + default : + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; + } + } + } + $docProps->setCustomProperty($propertyValueName,$propertyValue,$propertyValueType); + break; + } + } + } + + +// echo '<h1>Workbook Content</h1>'; + $xml = simplexml_load_string($this->securityScan($zip->getFromName("content.xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesContent = $xml->getNamespaces(true); +// echo '<pre>'; +// print_r($namespacesContent); +// echo '</pre><hr />'; + + $workbook = $xml->children($namespacesContent['office']); + foreach($workbook->body->spreadsheet as $workbookData) { + $workbookData = $workbookData->children($namespacesContent['table']); + $worksheetID = 0; + foreach($workbookData->table as $worksheetDataSet) { + $worksheetData = $worksheetDataSet->children($namespacesContent['table']); +// print_r($worksheetData); +// echo '<br />'; + $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']); +// print_r($worksheetDataAttributes); +// echo '<br />'; + if ((isset($this->_loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) && + (!in_array($worksheetDataAttributes['name'], $this->_loadSheetsOnly))) { + continue; + } + +// echo '<h2>Worksheet '.$worksheetDataAttributes['name'].'</h2>'; + // Create new Worksheet + $objPHPExcel->createSheet(); + $objPHPExcel->setActiveSheetIndex($worksheetID); + if (isset($worksheetDataAttributes['name'])) { + $worksheetName = (string) $worksheetDataAttributes['name']; + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in + // formula cells... during the load, all formulae should be correct, and we're simply + // bringing the worksheet name in line with the formula, not the reverse + $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + } + + $rowID = 1; + foreach($worksheetData as $key => $rowData) { +// echo '<b>'.$key.'</b><br />'; + switch ($key) { + case 'table-header-rows': + foreach ($rowData as $key=>$cellData) { + $rowData = $cellData; + break; + } + case 'table-row' : + $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); + $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? + $rowDataTableAttributes['number-rows-repeated'] : 1; + $columnID = 'A'; + foreach($rowData as $key => $cellData) { + if ($this->getReadFilter() !== NULL) { + if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { + continue; + } + } + +// echo '<b>'.$columnID.$rowID.'</b><br />'; + $cellDataText = (isset($namespacesContent['text'])) ? + $cellData->children($namespacesContent['text']) : + ''; + $cellDataOffice = $cellData->children($namespacesContent['office']); + $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']); + $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']); + +// echo 'Office Attributes: '; +// print_r($cellDataOfficeAttributes); +// echo '<br />Table Attributes: '; +// print_r($cellDataTableAttributes); +// echo '<br />Cell Data Text'; +// print_r($cellDataText); +// echo '<br />'; // - $type = $formatting = $hyperlink = null; - $hasCalculatedValue = false; - $cellDataFormula = ''; - if (isset($cellDataTableAttributes['formula'])) { - $cellDataFormula = $cellDataTableAttributes['formula']; - $hasCalculatedValue = true; - } - - if (isset($cellDataOffice->annotation)) { -// echo 'Cell has comment<br />'; - $annotationText = $cellDataOffice->annotation->children($namespacesContent['text']); - $textArray = array(); - foreach($annotationText as $t) { - if (isset($t->span)) { - foreach($t->span as $text) { - $textArray[] = (string)$text; - } - } else { - $textArray[] = (string) $t; - } - } - $text = implode("\n",$textArray); -// echo $text,'<br />'; - $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) -// ->setAuthor( $author ) - ->setText($this->_parseRichText($text) ); - } - - if (isset($cellDataText->p)) { - // Consolidate if there are multiple p records (maybe with spans as well) - $dataArray = array(); - // Text can have multiple text:p and within those, multiple text:span. - // text:p newlines, but text:span does not. - // Also, here we assume there is no text data is span fields are specified, since - // we have no way of knowing proper positioning anyway. - foreach ($cellDataText->p as $pData) { - if (isset($pData->span)) { - // span sections do not newline, so we just create one large string here - $spanSection = ""; - foreach ($pData->span as $spanData) { - $spanSection .= $spanData; - } - array_push($dataArray, $spanSection); - } else { - array_push($dataArray, $pData); - } - } - $allCellDataText = implode($dataArray, "\n"); - -// echo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />'; - switch ($cellDataOfficeAttributes['value-type']) { - case 'string' : - $type = PHPExcel_Cell_DataType::TYPE_STRING; - $dataValue = $allCellDataText; - if (isset($dataValue->a)) { - $dataValue = $dataValue->a; - $cellXLinkAttributes = $dataValue->attributes($namespacesContent['xlink']); - $hyperlink = $cellXLinkAttributes['href']; - } - break; - case 'boolean' : - $type = PHPExcel_Cell_DataType::TYPE_BOOL; - $dataValue = ($allCellDataText == 'TRUE') ? True : False; - break; - case 'percentage' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dataValue = (float) $cellDataOfficeAttributes['value']; - if (floor($dataValue) == $dataValue) { - $dataValue = (integer) $dataValue; - } - $formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00; - break; - case 'currency' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dataValue = (float) $cellDataOfficeAttributes['value']; - if (floor($dataValue) == $dataValue) { - $dataValue = (integer) $dataValue; - } - $formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE; - break; - case 'float' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dataValue = (float) $cellDataOfficeAttributes['value']; - if (floor($dataValue) == $dataValue) { - if ($dataValue == (integer) $dataValue) - $dataValue = (integer) $dataValue; - else - $dataValue = (float) $dataValue; - } - break; - case 'date' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT); - $dateObj->setTimeZone($timezoneObj); - list($year,$month,$day,$hour,$minute,$second) = explode(' ',$dateObj->format('Y m d H i s')); - $dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year,$month,$day,$hour,$minute,$second); - if ($dataValue != floor($dataValue)) { - $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; - } else { - $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15; - } - break; - case 'time' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'],'PT%dH%dM%dS')))); - $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; - break; - } -// echo 'Data value is '.$dataValue.'<br />'; -// if ($hyperlink !== NULL) { -// echo 'Hyperlink is '.$hyperlink.'<br />'; -// } - } else { - $type = PHPExcel_Cell_DataType::TYPE_NULL; - $dataValue = NULL; - } - - if ($hasCalculatedValue) { - $type = PHPExcel_Cell_DataType::TYPE_FORMULA; -// echo 'Formula: ', $cellDataFormula, PHP_EOL; - $cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1); - $temp = explode('"',$cellDataFormula); - $tKey = false; - foreach($temp as &$value) { - // Only replace in alternate array entries (i.e. non-quoted blocks) - if ($tKey = !$tKey) { - $value = preg_replace('/\[([^\.]+)\.([^\.]+):\.([^\.]+)\]/Ui','$1!$2:$3',$value); // Cell range reference in another sheet - $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/Ui','$1!$2',$value); // Cell reference in another sheet - $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/Ui','$1:$2',$value); // Cell range reference - $value = preg_replace('/\[\.([^\.]+)\]/Ui','$1',$value); // Simple cell reference - $value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces); - } - } - unset($value); - // Then rebuild the formula string - $cellDataFormula = implode('"',$temp); -// echo 'Adjusted Formula: ', $cellDataFormula, PHP_EOL; - } - - $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? - $cellDataTableAttributes['number-columns-repeated'] : 1; - if ($type !== NULL) { - for ($i = 0; $i < $colRepeats; ++$i) { - if ($i > 0) { - ++$columnID; - } - if ($type !== PHPExcel_Cell_DataType::TYPE_NULL) { - for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) { - $rID = $rowID + $rowAdjust; - $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type); - if ($hasCalculatedValue) { -// echo 'Forumla result is '.$dataValue.'<br />'; - $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue); - } - if ($formatting !== NULL) { - $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode($formatting); - } else { - $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL); - } - if ($hyperlink !== NULL) { - $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->getHyperlink()->setUrl($hyperlink); - } - } - } - } - } - - // Merged cells - if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) { - if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) { - $columnTo = $columnID; - if (isset($cellDataTableAttributes['number-columns-spanned'])) { - $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2); - } - $rowTo = $rowID; - if (isset($cellDataTableAttributes['number-rows-spanned'])) { - $rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1; - } - $cellRange = $columnID.$rowID.':'.$columnTo.$rowTo; - $objPHPExcel->getActiveSheet()->mergeCells($cellRange); - } - } - - ++$columnID; - } - $rowID += $rowRepeats; - break; - } - } - ++$worksheetID; - } - } - - // Return - return $objPHPExcel; - } - - - private function _parseRichText($is = '') { - $value = new PHPExcel_RichText(); - - $value->createText($is); - - return $value; - } + $type = $formatting = $hyperlink = null; + $hasCalculatedValue = false; + $cellDataFormula = ''; + if (isset($cellDataTableAttributes['formula'])) { + $cellDataFormula = $cellDataTableAttributes['formula']; + $hasCalculatedValue = true; + } + + if (isset($cellDataOffice->annotation)) { +// echo 'Cell has comment<br />'; + $annotationText = $cellDataOffice->annotation->children($namespacesContent['text']); + $textArray = array(); + foreach($annotationText as $t) { + if (isset($t->span)) { + foreach($t->span as $text) { + $textArray[] = (string)$text; + } + } else { + $textArray[] = (string) $t; + } + } + $text = implode("\n",$textArray); +// echo $text,'<br />'; + $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) +// ->setAuthor( $author ) + ->setText($this->_parseRichText($text) ); + } + + if (isset($cellDataText->p)) { + // Consolidate if there are multiple p records (maybe with spans as well) + $dataArray = array(); + // Text can have multiple text:p and within those, multiple text:span. + // text:p newlines, but text:span does not. + // Also, here we assume there is no text data is span fields are specified, since + // we have no way of knowing proper positioning anyway. + foreach ($cellDataText->p as $pData) { + if (isset($pData->span)) { + // span sections do not newline, so we just create one large string here + $spanSection = ""; + foreach ($pData->span as $spanData) { + $spanSection .= $spanData; + } + array_push($dataArray, $spanSection); + } else { + array_push($dataArray, $pData); + } + } + $allCellDataText = implode($dataArray, "\n"); + +// echo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />'; + switch ($cellDataOfficeAttributes['value-type']) { + case 'string' : + $type = PHPExcel_Cell_DataType::TYPE_STRING; + $dataValue = $allCellDataText; + if (isset($dataValue->a)) { + $dataValue = $dataValue->a; + $cellXLinkAttributes = $dataValue->attributes($namespacesContent['xlink']); + $hyperlink = $cellXLinkAttributes['href']; + } + break; + case 'boolean' : + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $dataValue = ($allCellDataText == 'TRUE') ? True : False; + break; + case 'percentage' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + $dataValue = (integer) $dataValue; + } + $formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00; + break; + case 'currency' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + $dataValue = (integer) $dataValue; + } + $formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE; + break; + case 'float' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + if ($dataValue == (integer) $dataValue) + $dataValue = (integer) $dataValue; + else + $dataValue = (float) $dataValue; + } + break; + case 'date' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT); + $dateObj->setTimeZone($timezoneObj); + list($year,$month,$day,$hour,$minute,$second) = explode(' ',$dateObj->format('Y m d H i s')); + $dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year,$month,$day,$hour,$minute,$second); + if ($dataValue != floor($dataValue)) { + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; + } else { + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15; + } + break; + case 'time' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'],'PT%dH%dM%dS')))); + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; + break; + } +// echo 'Data value is '.$dataValue.'<br />'; +// if ($hyperlink !== NULL) { +// echo 'Hyperlink is '.$hyperlink.'<br />'; +// } + } else { + $type = PHPExcel_Cell_DataType::TYPE_NULL; + $dataValue = NULL; + } + + if ($hasCalculatedValue) { + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; +// echo 'Formula: ', $cellDataFormula, PHP_EOL; + $cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1); + $temp = explode('"',$cellDataFormula); + $tKey = false; + foreach($temp as &$value) { + // Only replace in alternate array entries (i.e. non-quoted blocks) + if ($tKey = !$tKey) { + $value = preg_replace('/\[([^\.]+)\.([^\.]+):\.([^\.]+)\]/Ui','$1!$2:$3',$value); // Cell range reference in another sheet + $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/Ui','$1!$2',$value); // Cell reference in another sheet + $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/Ui','$1:$2',$value); // Cell range reference + $value = preg_replace('/\[\.([^\.]+)\]/Ui','$1',$value); // Simple cell reference + $value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces); + } + } + unset($value); + // Then rebuild the formula string + $cellDataFormula = implode('"',$temp); +// echo 'Adjusted Formula: ', $cellDataFormula, PHP_EOL; + } + + $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? + $cellDataTableAttributes['number-columns-repeated'] : 1; + if ($type !== NULL) { + for ($i = 0; $i < $colRepeats; ++$i) { + if ($i > 0) { + ++$columnID; + } + if ($type !== PHPExcel_Cell_DataType::TYPE_NULL) { + for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) { + $rID = $rowID + $rowAdjust; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type); + if ($hasCalculatedValue) { +// echo 'Forumla result is '.$dataValue.'<br />'; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue); + } + if ($formatting !== NULL) { + $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode($formatting); + } else { + $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL); + } + if ($hyperlink !== NULL) { + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->getHyperlink()->setUrl($hyperlink); + } + } + } + } + } + + // Merged cells + if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) { + if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) { + $columnTo = $columnID; + if (isset($cellDataTableAttributes['number-columns-spanned'])) { + $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2); + } + $rowTo = $rowID; + if (isset($cellDataTableAttributes['number-rows-spanned'])) { + $rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1; + } + $cellRange = $columnID.$rowID.':'.$columnTo.$rowTo; + $objPHPExcel->getActiveSheet()->mergeCells($cellRange); + } + } + + ++$columnID; + } + $rowID += $rowRepeats; + break; + } + } + ++$worksheetID; + } + } + + // Return + return $objPHPExcel; + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText($is); + + return $value; + } } diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index 4048d4fc3..1eee8666b 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -21,18 +21,18 @@ * @category PHPExcel * @package PHPExcel_Reader * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /** @@ -44,407 +44,407 @@ */ class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { - /** - * Input encoding - * - * @var string - */ - private $_inputEncoding = 'ANSI'; - - /** - * Sheet index to read - * - * @var int - */ - private $_sheetIndex = 0; - - /** - * Formats - * - * @var array - */ - private $_formats = array(); - - /** - * Format Count - * - * @var int - */ - private $_format = 0; - - /** - * Create a new PHPExcel_Reader_SYLK - */ - public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - } - - /** - * Validate that the current file is a SYLK file - * - * @return boolean - */ - protected function _isValidFormat() - { - // Read sample data (first 2 KB will do) - $data = fread($this->_fileHandle, 2048); - - // Count delimiters in file - $delimiterCount = substr_count($data, ';'); - if ($delimiterCount < 1) { - return FALSE; - } - - // Analyze first line looking for ID; signature - $lines = explode("\n", $data); - if (substr($lines[0],0,4) != 'ID;P') { - return FALSE; - } - - return TRUE; - } - - /** - * Set input encoding - * - * @param string $pValue Input encoding - */ - public function setInputEncoding($pValue = 'ANSI') - { - $this->_inputEncoding = $pValue; - return $this; - } - - /** - * Get input encoding - * - * @return string - */ - public function getInputEncoding() - { - return $this->_inputEncoding; - } - - /** - * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetInfo($pFilename) - { - // Open file - $this->_openFile($pFilename); - if (!$this->_isValidFormat()) { - fclose ($this->_fileHandle); - throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); - } - $fileHandle = $this->_fileHandle; - rewind($fileHandle); - - $worksheetInfo = array(); - $worksheetInfo[0]['worksheetName'] = 'Worksheet'; - $worksheetInfo[0]['lastColumnLetter'] = 'A'; - $worksheetInfo[0]['lastColumnIndex'] = 0; - $worksheetInfo[0]['totalRows'] = 0; - $worksheetInfo[0]['totalColumns'] = 0; - - // Loop through file - $rowData = array(); - - // loop through one row (line) at a time in the file - $rowIndex = 0; - while (($rowData = fgets($fileHandle)) !== FALSE) { - $columnIndex = 0; - - // convert SYLK encoded $rowData to UTF-8 - $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData); - - // explode each row at semicolons while taking into account that literal semicolon (;) - // is escaped like this (;;) - $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); - - $dataType = array_shift($rowData); - if ($dataType == 'C') { - // Read cell value data - foreach($rowData as $rowDatum) { - switch($rowDatum{0}) { - case 'C' : - case 'X' : - $columnIndex = substr($rowDatum,1) - 1; - break; - case 'R' : - case 'Y' : - $rowIndex = substr($rowDatum,1); - break; - } - - $worksheetInfo[0]['totalRows'] = max($worksheetInfo[0]['totalRows'], $rowIndex); - $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], $columnIndex); - } - } - } - - $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']); - $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1; - - // Close file - fclose($fileHandle); - - return $worksheetInfo; - } - - /** - * Loads PHPExcel from file - * - * @param string $pFilename - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function load($pFilename) - { - // Create new PHPExcel - $objPHPExcel = new PHPExcel(); - - // Load into this instance - return $this->loadIntoExisting($pFilename, $objPHPExcel); - } - - /** - * Loads PHPExcel from file into PHPExcel instance - * - * @param string $pFilename - * @param PHPExcel $objPHPExcel - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) - { - // Open file - $this->_openFile($pFilename); - if (!$this->_isValidFormat()) { - fclose ($this->_fileHandle); - throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); - } - $fileHandle = $this->_fileHandle; - rewind($fileHandle); - - // Create new PHPExcel - while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { - $objPHPExcel->createSheet(); - } - $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex ); - - $fromFormats = array('\-', '\ '); - $toFormats = array('-', ' '); - - // Loop through file - $rowData = array(); - $column = $row = ''; - - // loop through one row (line) at a time in the file - while (($rowData = fgets($fileHandle)) !== FALSE) { - - // convert SYLK encoded $rowData to UTF-8 - $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData); - - // explode each row at semicolons while taking into account that literal semicolon (;) - // is escaped like this (;;) - $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); - - $dataType = array_shift($rowData); - // Read shared styles - if ($dataType == 'P') { - $formatArray = array(); - foreach($rowData as $rowDatum) { - switch($rowDatum{0}) { - case 'P' : $formatArray['numberformat']['code'] = str_replace($fromFormats,$toFormats,substr($rowDatum,1)); - break; - case 'E' : - case 'F' : $formatArray['font']['name'] = substr($rowDatum,1); - break; - case 'L' : $formatArray['font']['size'] = substr($rowDatum,1); - break; - case 'S' : $styleSettings = substr($rowDatum,1); - for ($i=0;$i<strlen($styleSettings);++$i) { - switch ($styleSettings{$i}) { - case 'I' : $formatArray['font']['italic'] = true; - break; - case 'D' : $formatArray['font']['bold'] = true; - break; - case 'T' : $formatArray['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'B' : $formatArray['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'L' : $formatArray['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'R' : $formatArray['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - } - } - break; - } - } - $this->_formats['P'.$this->_format++] = $formatArray; - // Read cell value data - } elseif ($dataType == 'C') { - $hasCalculatedValue = false; - $cellData = $cellDataFormula = ''; - foreach($rowData as $rowDatum) { - switch($rowDatum{0}) { - case 'C' : - case 'X' : $column = substr($rowDatum,1); - break; - case 'R' : - case 'Y' : $row = substr($rowDatum,1); - break; - case 'K' : $cellData = substr($rowDatum,1); - break; - case 'E' : $cellDataFormula = '='.substr($rowDatum,1); - // Convert R1C1 style references to A1 style references (but only when not quoted) - $temp = explode('"',$cellDataFormula); - $key = false; - foreach($temp as &$value) { - // Only count/replace in alternate array entries - if ($key = !$key) { - preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); - // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way - // through the formula from left to right. Reversing means that we work right to left.through - // the formula - $cellReferences = array_reverse($cellReferences); - // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, - // then modify the formula to use that new reference - foreach($cellReferences as $cellReference) { - $rowReference = $cellReference[2][0]; - // Empty R reference is the current row - if ($rowReference == '') $rowReference = $row; - // Bracketed R references are relative to the current row - if ($rowReference{0} == '[') $rowReference = $row + trim($rowReference,'[]'); - $columnReference = $cellReference[4][0]; - // Empty C reference is the current column - if ($columnReference == '') $columnReference = $column; - // Bracketed C references are relative to the current column - if ($columnReference{0} == '[') $columnReference = $column + trim($columnReference,'[]'); - $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; - - $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0])); - } - } - } - unset($value); - // Then rebuild the formula string - $cellDataFormula = implode('"',$temp); - $hasCalculatedValue = true; - break; - } - } - $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); - $cellData = PHPExcel_Calculation::_unwrapResult($cellData); - - // Set cell value - $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setValue(($hasCalculatedValue) ? $cellDataFormula : $cellData); - if ($hasCalculatedValue) { - $cellData = PHPExcel_Calculation::_unwrapResult($cellData); - $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setCalculatedValue($cellData); - } - // Read cell formatting - } elseif ($dataType == 'F') { - $formatStyle = $columnWidth = $styleSettings = ''; - $styleData = array(); - foreach($rowData as $rowDatum) { - switch($rowDatum{0}) { - case 'C' : - case 'X' : $column = substr($rowDatum,1); - break; - case 'R' : - case 'Y' : $row = substr($rowDatum,1); - break; - case 'P' : $formatStyle = $rowDatum; - break; - case 'W' : list($startCol,$endCol,$columnWidth) = explode(' ',substr($rowDatum,1)); - break; - case 'S' : $styleSettings = substr($rowDatum,1); - for ($i=0;$i<strlen($styleSettings);++$i) { - switch ($styleSettings{$i}) { - case 'I' : $styleData['font']['italic'] = true; - break; - case 'D' : $styleData['font']['bold'] = true; - break; - case 'T' : $styleData['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'B' : $styleData['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'L' : $styleData['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'R' : $styleData['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - } - } - break; - } - } - if (($formatStyle > '') && ($column > '') && ($row > '')) { - $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); - if (isset($this->_formats[$formatStyle])) { - $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($this->_formats[$formatStyle]); - } - } - if ((!empty($styleData)) && ($column > '') && ($row > '')) { - $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); - $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($styleData); - } - if ($columnWidth > '') { - if ($startCol == $endCol) { - $startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1); - $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth); - } else { - $startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1); - $endCol = PHPExcel_Cell::stringFromColumnIndex($endCol-1); - $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth); - do { - $objPHPExcel->getActiveSheet()->getColumnDimension(++$startCol)->setWidth($columnWidth); - } while ($startCol != $endCol); - } - } - } else { - foreach($rowData as $rowDatum) { - switch($rowDatum{0}) { - case 'C' : - case 'X' : $column = substr($rowDatum,1); - break; - case 'R' : - case 'Y' : $row = substr($rowDatum,1); - break; - } - } - } - } - - // Close file - fclose($fileHandle); - - // Return - return $objPHPExcel; - } - - /** - * Get sheet index - * - * @return int - */ - public function getSheetIndex() { - return $this->_sheetIndex; - } - - /** - * Set sheet index - * - * @param int $pValue Sheet index - * @return PHPExcel_Reader_SYLK - */ - public function setSheetIndex($pValue = 0) { - $this->_sheetIndex = $pValue; - return $this; - } + /** + * Input encoding + * + * @var string + */ + private $_inputEncoding = 'ANSI'; + + /** + * Sheet index to read + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Formats + * + * @var array + */ + private $_formats = array(); + + /** + * Format Count + * + * @var int + */ + private $_format = 0; + + /** + * Create a new PHPExcel_Reader_SYLK + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + /** + * Validate that the current file is a SYLK file + * + * @return boolean + */ + protected function _isValidFormat() + { + // Read sample data (first 2 KB will do) + $data = fread($this->_fileHandle, 2048); + + // Count delimiters in file + $delimiterCount = substr_count($data, ';'); + if ($delimiterCount < 1) { + return FALSE; + } + + // Analyze first line looking for ID; signature + $lines = explode("\n", $data); + if (substr($lines[0],0,4) != 'ID;P') { + return FALSE; + } + + return TRUE; + } + + /** + * Set input encoding + * + * @param string $pValue Input encoding + */ + public function setInputEncoding($pValue = 'ANSI') + { + $this->_inputEncoding = $pValue; + return $this; + } + + /** + * Get input encoding + * + * @return string + */ + public function getInputEncoding() + { + return $this->_inputEncoding; + } + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + rewind($fileHandle); + + $worksheetInfo = array(); + $worksheetInfo[0]['worksheetName'] = 'Worksheet'; + $worksheetInfo[0]['lastColumnLetter'] = 'A'; + $worksheetInfo[0]['lastColumnIndex'] = 0; + $worksheetInfo[0]['totalRows'] = 0; + $worksheetInfo[0]['totalColumns'] = 0; + + // Loop through file + $rowData = array(); + + // loop through one row (line) at a time in the file + $rowIndex = 0; + while (($rowData = fgets($fileHandle)) !== FALSE) { + $columnIndex = 0; + + // convert SYLK encoded $rowData to UTF-8 + $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData); + + // explode each row at semicolons while taking into account that literal semicolon (;) + // is escaped like this (;;) + $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); + + $dataType = array_shift($rowData); + if ($dataType == 'C') { + // Read cell value data + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : + $columnIndex = substr($rowDatum,1) - 1; + break; + case 'R' : + case 'Y' : + $rowIndex = substr($rowDatum,1); + break; + } + + $worksheetInfo[0]['totalRows'] = max($worksheetInfo[0]['totalRows'], $rowIndex); + $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], $columnIndex); + } + } + } + + $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']); + $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1; + + // Close file + fclose($fileHandle); + + return $worksheetInfo; + } + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + rewind($fileHandle); + + // Create new PHPExcel + while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + $objPHPExcel->createSheet(); + } + $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex ); + + $fromFormats = array('\-', '\ '); + $toFormats = array('-', ' '); + + // Loop through file + $rowData = array(); + $column = $row = ''; + + // loop through one row (line) at a time in the file + while (($rowData = fgets($fileHandle)) !== FALSE) { + + // convert SYLK encoded $rowData to UTF-8 + $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData); + + // explode each row at semicolons while taking into account that literal semicolon (;) + // is escaped like this (;;) + $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); + + $dataType = array_shift($rowData); + // Read shared styles + if ($dataType == 'P') { + $formatArray = array(); + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'P' : $formatArray['numberformat']['code'] = str_replace($fromFormats,$toFormats,substr($rowDatum,1)); + break; + case 'E' : + case 'F' : $formatArray['font']['name'] = substr($rowDatum,1); + break; + case 'L' : $formatArray['font']['size'] = substr($rowDatum,1); + break; + case 'S' : $styleSettings = substr($rowDatum,1); + for ($i=0;$i<strlen($styleSettings);++$i) { + switch ($styleSettings{$i}) { + case 'I' : $formatArray['font']['italic'] = true; + break; + case 'D' : $formatArray['font']['bold'] = true; + break; + case 'T' : $formatArray['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'B' : $formatArray['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'L' : $formatArray['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'R' : $formatArray['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + } + } + break; + } + } + $this->_formats['P'.$this->_format++] = $formatArray; + // Read cell value data + } elseif ($dataType == 'C') { + $hasCalculatedValue = false; + $cellData = $cellDataFormula = ''; + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : $column = substr($rowDatum,1); + break; + case 'R' : + case 'Y' : $row = substr($rowDatum,1); + break; + case 'K' : $cellData = substr($rowDatum,1); + break; + case 'E' : $cellDataFormula = '='.substr($rowDatum,1); + // Convert R1C1 style references to A1 style references (but only when not quoted) + $temp = explode('"',$cellDataFormula); + $key = false; + foreach($temp as &$value) { + // Only count/replace in alternate array entries + if ($key = !$key) { + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way + // through the formula from left to right. Reversing means that we work right to left.through + // the formula + $cellReferences = array_reverse($cellReferences); + // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, + // then modify the formula to use that new reference + foreach($cellReferences as $cellReference) { + $rowReference = $cellReference[2][0]; + // Empty R reference is the current row + if ($rowReference == '') $rowReference = $row; + // Bracketed R references are relative to the current row + if ($rowReference{0} == '[') $rowReference = $row + trim($rowReference,'[]'); + $columnReference = $cellReference[4][0]; + // Empty C reference is the current column + if ($columnReference == '') $columnReference = $column; + // Bracketed C references are relative to the current column + if ($columnReference{0} == '[') $columnReference = $column + trim($columnReference,'[]'); + $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; + + $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0])); + } + } + } + unset($value); + // Then rebuild the formula string + $cellDataFormula = implode('"',$temp); + $hasCalculatedValue = true; + break; + } + } + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); + $cellData = PHPExcel_Calculation::_unwrapResult($cellData); + + // Set cell value + $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setValue(($hasCalculatedValue) ? $cellDataFormula : $cellData); + if ($hasCalculatedValue) { + $cellData = PHPExcel_Calculation::_unwrapResult($cellData); + $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setCalculatedValue($cellData); + } + // Read cell formatting + } elseif ($dataType == 'F') { + $formatStyle = $columnWidth = $styleSettings = ''; + $styleData = array(); + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : $column = substr($rowDatum,1); + break; + case 'R' : + case 'Y' : $row = substr($rowDatum,1); + break; + case 'P' : $formatStyle = $rowDatum; + break; + case 'W' : list($startCol,$endCol,$columnWidth) = explode(' ',substr($rowDatum,1)); + break; + case 'S' : $styleSettings = substr($rowDatum,1); + for ($i=0;$i<strlen($styleSettings);++$i) { + switch ($styleSettings{$i}) { + case 'I' : $styleData['font']['italic'] = true; + break; + case 'D' : $styleData['font']['bold'] = true; + break; + case 'T' : $styleData['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'B' : $styleData['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'L' : $styleData['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'R' : $styleData['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + } + } + break; + } + } + if (($formatStyle > '') && ($column > '') && ($row > '')) { + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); + if (isset($this->_formats[$formatStyle])) { + $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($this->_formats[$formatStyle]); + } + } + if ((!empty($styleData)) && ($column > '') && ($row > '')) { + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); + $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($styleData); + } + if ($columnWidth > '') { + if ($startCol == $endCol) { + $startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth); + } else { + $startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $endCol = PHPExcel_Cell::stringFromColumnIndex($endCol-1); + $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth); + do { + $objPHPExcel->getActiveSheet()->getColumnDimension(++$startCol)->setWidth($columnWidth); + } while ($startCol != $endCol); + } + } + } else { + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : $column = substr($rowDatum,1); + break; + case 'R' : + case 'Y' : $row = substr($rowDatum,1); + break; + } + } + } + } + + // Close file + fclose($fileHandle); + + // Return + return $objPHPExcel; + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Reader_SYLK + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } } diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index dfd5b4c8a..9144c01d2 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_ReferenceHelper (Singleton) * * Copyright (c) 2006 - 2015 PHPExcel * @@ -19,749 +20,740 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category PHPExcel - * @package PHPExcel - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_ReferenceHelper (Singleton) - * - * @category PHPExcel - * @package PHPExcel + * @package PHPExcel * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ class PHPExcel_ReferenceHelper { - /** Constants */ - /** Regular Expressions */ - const REFHELPER_REGEXP_CELLREF = '((\w*|\'[^!]*\')!)?(?<![:a-z\$])(\$?[a-z]{1,3}\$?\d+)(?=[^:!\d\'])'; - const REFHELPER_REGEXP_CELLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}\$?\d+):(\$?[a-z]{1,3}\$?\d+)'; - const REFHELPER_REGEXP_ROWRANGE = '((\w*|\'[^!]*\')!)?(\$?\d+):(\$?\d+)'; - const REFHELPER_REGEXP_COLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}):(\$?[a-z]{1,3})'; - - /** - * Instance of this class - * - * @var PHPExcel_ReferenceHelper - */ - private static $_instance; - - /** - * Get an instance of this class - * - * @return PHPExcel_ReferenceHelper - */ - public static function getInstance() { - if (!isset(self::$_instance) || (self::$_instance === NULL)) { - self::$_instance = new PHPExcel_ReferenceHelper(); - } - - return self::$_instance; - } - - /** - * Create a new PHPExcel_ReferenceHelper - */ - protected function __construct() { - } - - /** - * Compare two column addresses - * Intended for use as a Callback function for sorting column addresses by column - * - * @param string $a First column to test (e.g. 'AA') - * @param string $b Second column to test (e.g. 'Z') - * @return integer - */ - public static function columnSort($a, $b) { - return strcasecmp(strlen($a) . $a, strlen($b) . $b); - } - - /** - * Compare two column addresses - * Intended for use as a Callback function for reverse sorting column addresses by column - * - * @param string $a First column to test (e.g. 'AA') - * @param string $b Second column to test (e.g. 'Z') - * @return integer - */ - public static function columnReverseSort($a, $b) { - return 1 - strcasecmp(strlen($a) . $a, strlen($b) . $b); - } - - /** - * Compare two cell addresses - * Intended for use as a Callback function for sorting cell addresses by column and row - * - * @param string $a First cell to test (e.g. 'AA1') - * @param string $b Second cell to test (e.g. 'Z1') - * @return integer - */ - public static function cellSort($a, $b) { - sscanf($a,'%[A-Z]%d', $ac, $ar); - sscanf($b,'%[A-Z]%d', $bc, $br); - - if ($ar == $br) { - return strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); - } - return ($ar < $br) ? -1 : 1; - } - - /** - * Compare two cell addresses - * Intended for use as a Callback function for sorting cell addresses by column and row - * - * @param string $a First cell to test (e.g. 'AA1') - * @param string $b Second cell to test (e.g. 'Z1') - * @return integer - */ - public static function cellReverseSort($a, $b) { - sscanf($a,'%[A-Z]%d', $ac, $ar); - sscanf($b,'%[A-Z]%d', $bc, $br); - - if ($ar == $br) { - return 1 - strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); - } - return ($ar < $br) ? 1 : -1; - } - - /** - * Test whether a cell address falls within a defined range of cells - * - * @param string $cellAddress Address of the cell we're testing - * @param integer $beforeRow Number of the row we're inserting/deleting before - * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) - * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before - * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) - * @return boolean - */ - private static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols) { - list($cellColumn, $cellRow) = PHPExcel_Cell::coordinateFromString($cellAddress); - $cellColumnIndex = PHPExcel_Cell::columnIndexFromString($cellColumn); - // Is cell within the range of rows/columns if we're deleting - if ($pNumRows < 0 && - ($cellRow >= ($beforeRow + $pNumRows)) && - ($cellRow < $beforeRow)) { - return TRUE; - } elseif ($pNumCols < 0 && - ($cellColumnIndex >= ($beforeColumnIndex + $pNumCols)) && - ($cellColumnIndex < $beforeColumnIndex)) { - return TRUE; - } - return FALSE; - } - - /** - * Update page breaks when inserting/deleting rows/columns - * - * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing - * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') - * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before - * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) - * @param integer $beforeRow Number of the row we're inserting/deleting before - * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) - */ - protected function _adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) - { - $aBreaks = $pSheet->getBreaks(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellSort')); - - foreach ($aBreaks as $key => $value) { - if (self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { - // If we're deleting, then clear any defined breaks that are within the range - // of rows/columns that we're deleting - $pSheet->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); - } else { - // Otherwise update any affected breaks by inserting a new break at the appropriate point - // and removing the old affected break - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - if ($key != $newReference) { - $pSheet->setBreak($newReference, $value) - ->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); - } - } - } - } - - /** - * Update cell comments when inserting/deleting rows/columns - * - * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing - * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') - * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before - * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) - * @param integer $beforeRow Number of the row we're inserting/deleting before - * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) - */ - protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) - { - $aComments = $pSheet->getComments(); - $aNewComments = array(); // the new array of all comments - - foreach ($aComments as $key => &$value) { - // Any comments inside a deleted range will be ignored - if (!self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { - // Otherwise build a new array of comments indexed by the adjusted cell reference - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - $aNewComments[$newReference] = $value; - } - } - // Replace the comments array with the new set of comments - $pSheet->setComments($aNewComments); - } - - /** - * Update hyperlinks when inserting/deleting rows/columns - * - * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing - * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') - * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before - * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) - * @param integer $beforeRow Number of the row we're inserting/deleting before - * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) - */ - protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) - { - $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); - - foreach ($aHyperlinkCollection as $key => $value) { - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - if ($key != $newReference) { - $pSheet->setHyperlink( $newReference, $value ); - $pSheet->setHyperlink( $key, null ); - } - } - } - - /** - * Update data validations when inserting/deleting rows/columns - * - * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing - * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') - * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before - * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) - * @param integer $beforeRow Number of the row we're inserting/deleting before - * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) - */ - protected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) - { - $aDataValidationCollection = $pSheet->getDataValidationCollection(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); - foreach ($aDataValidationCollection as $key => $value) { - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - if ($key != $newReference) { - $pSheet->setDataValidation( $newReference, $value ); - $pSheet->setDataValidation( $key, null ); - } - } - } - - /** - * Update merged cells when inserting/deleting rows/columns - * - * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing - * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') - * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before - * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) - * @param integer $beforeRow Number of the row we're inserting/deleting before - * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) - */ - protected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) - { - $aMergeCells = $pSheet->getMergeCells(); - $aNewMergeCells = array(); // the new array of all merge cells - foreach ($aMergeCells as $key => &$value) { - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - $aNewMergeCells[$newReference] = $newReference; - } - $pSheet->setMergeCells($aNewMergeCells); // replace the merge cells array - } - - /** - * Update protected cells when inserting/deleting rows/columns - * - * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing - * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') - * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before - * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) - * @param integer $beforeRow Number of the row we're inserting/deleting before - * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) - */ - protected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) - { - $aProtectedCells = $pSheet->getProtectedCells(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellSort')); - foreach ($aProtectedCells as $key => $value) { - $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); - if ($key != $newReference) { - $pSheet->protectCells( $newReference, $value, true ); - $pSheet->unprotectCells( $key ); - } - } - } - - /** - * Update column dimensions when inserting/deleting rows/columns - * - * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing - * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') - * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before - * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) - * @param integer $beforeRow Number of the row we're inserting/deleting before - * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) - */ - protected function _adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) - { - $aColumnDimensions = array_reverse($pSheet->getColumnDimensions(), true); - if (!empty($aColumnDimensions)) { - foreach ($aColumnDimensions as $objColumnDimension) { - $newReference = $this->updateCellReference($objColumnDimension->getColumnIndex() . '1', $pBefore, $pNumCols, $pNumRows); - list($newReference) = PHPExcel_Cell::coordinateFromString($newReference); - if ($objColumnDimension->getColumnIndex() != $newReference) { - $objColumnDimension->setColumnIndex($newReference); - } - } - $pSheet->refreshColumnDimensions(); - } - } - - /** - * Update row dimensions when inserting/deleting rows/columns - * - * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing - * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') - * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before - * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) - * @param integer $beforeRow Number of the row we're inserting/deleting before - * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) - */ - protected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) - { - $aRowDimensions = array_reverse($pSheet->getRowDimensions(), true); - if (!empty($aRowDimensions)) { - foreach ($aRowDimensions as $objRowDimension) { - $newReference = $this->updateCellReference('A' . $objRowDimension->getRowIndex(), $pBefore, $pNumCols, $pNumRows); - list(, $newReference) = PHPExcel_Cell::coordinateFromString($newReference); - if ($objRowDimension->getRowIndex() != $newReference) { - $objRowDimension->setRowIndex($newReference); - } - } - $pSheet->refreshRowDimensions(); - - $copyDimension = $pSheet->getRowDimension($beforeRow - 1); - for ($i = $beforeRow; $i <= $beforeRow - 1 + $pNumRows; ++$i) { - $newDimension = $pSheet->getRowDimension($i); - $newDimension->setRowHeight($copyDimension->getRowHeight()); - $newDimension->setVisible($copyDimension->getVisible()); - $newDimension->setOutlineLevel($copyDimension->getOutlineLevel()); - $newDimension->setCollapsed($copyDimension->getCollapsed()); - } - } - } - - /** - * Insert a new column or row, updating all possible related data - * - * @param string $pBefore Insert before this cell address (e.g. 'A1') - * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) - * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) - * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing - * @throws PHPExcel_Exception - */ - public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, PHPExcel_Worksheet $pSheet = NULL) - { - $remove = ($pNumCols < 0 || $pNumRows < 0); - $aCellCollection = $pSheet->getCellCollection(); - - // Get coordinates of $pBefore - $beforeColumn = 'A'; - $beforeRow = 1; - list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString($pBefore); - $beforeColumnIndex = PHPExcel_Cell::columnIndexFromString($beforeColumn); - - // Clear cells if we are removing columns or rows - $highestColumn = $pSheet->getHighestColumn(); - $highestRow = $pSheet->getHighestRow(); - - // 1. Clear column strips if we are removing columns - if ($pNumCols < 0 && $beforeColumnIndex - 2 + $pNumCols > 0) { - for ($i = 1; $i <= $highestRow - 1; ++$i) { - for ($j = $beforeColumnIndex - 1 + $pNumCols; $j <= $beforeColumnIndex - 2; ++$j) { - $coordinate = PHPExcel_Cell::stringFromColumnIndex($j) . $i; - $pSheet->removeConditionalStyles($coordinate); - if ($pSheet->cellExists($coordinate)) { - $pSheet->getCell($coordinate)->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL); - $pSheet->getCell($coordinate)->setXfIndex(0); - } - } - } - } - - // 2. Clear row strips if we are removing rows - if ($pNumRows < 0 && $beforeRow - 1 + $pNumRows > 0) { - for ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) { - for ($j = $beforeRow + $pNumRows; $j <= $beforeRow - 1; ++$j) { - $coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . $j; - $pSheet->removeConditionalStyles($coordinate); - if ($pSheet->cellExists($coordinate)) { - $pSheet->getCell($coordinate)->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL); - $pSheet->getCell($coordinate)->setXfIndex(0); - } - } - } - } - - // Loop through cells, bottom-up, and change cell coordinates + /** Constants */ + /** Regular Expressions */ + const REFHELPER_REGEXP_CELLREF = '((\w*|\'[^!]*\')!)?(?<![:a-z\$])(\$?[a-z]{1,3}\$?\d+)(?=[^:!\d\'])'; + const REFHELPER_REGEXP_CELLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}\$?\d+):(\$?[a-z]{1,3}\$?\d+)'; + const REFHELPER_REGEXP_ROWRANGE = '((\w*|\'[^!]*\')!)?(\$?\d+):(\$?\d+)'; + const REFHELPER_REGEXP_COLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}):(\$?[a-z]{1,3})'; + + /** + * Instance of this class + * + * @var PHPExcel_ReferenceHelper + */ + private static $_instance; + + /** + * Get an instance of this class + * + * @return PHPExcel_ReferenceHelper + */ + public static function getInstance() { + if (!isset(self::$_instance) || (self::$_instance === NULL)) { + self::$_instance = new PHPExcel_ReferenceHelper(); + } + + return self::$_instance; + } + + /** + * Create a new PHPExcel_ReferenceHelper + */ + protected function __construct() { + } + + /** + * Compare two column addresses + * Intended for use as a Callback function for sorting column addresses by column + * + * @param string $a First column to test (e.g. 'AA') + * @param string $b Second column to test (e.g. 'Z') + * @return integer + */ + public static function columnSort($a, $b) { + return strcasecmp(strlen($a) . $a, strlen($b) . $b); + } + + /** + * Compare two column addresses + * Intended for use as a Callback function for reverse sorting column addresses by column + * + * @param string $a First column to test (e.g. 'AA') + * @param string $b Second column to test (e.g. 'Z') + * @return integer + */ + public static function columnReverseSort($a, $b) { + return 1 - strcasecmp(strlen($a) . $a, strlen($b) . $b); + } + + /** + * Compare two cell addresses + * Intended for use as a Callback function for sorting cell addresses by column and row + * + * @param string $a First cell to test (e.g. 'AA1') + * @param string $b Second cell to test (e.g. 'Z1') + * @return integer + */ + public static function cellSort($a, $b) { + sscanf($a,'%[A-Z]%d', $ac, $ar); + sscanf($b,'%[A-Z]%d', $bc, $br); + + if ($ar == $br) { + return strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); + } + return ($ar < $br) ? -1 : 1; + } + + /** + * Compare two cell addresses + * Intended for use as a Callback function for sorting cell addresses by column and row + * + * @param string $a First cell to test (e.g. 'AA1') + * @param string $b Second cell to test (e.g. 'Z1') + * @return integer + */ + public static function cellReverseSort($a, $b) { + sscanf($a,'%[A-Z]%d', $ac, $ar); + sscanf($b,'%[A-Z]%d', $bc, $br); + + if ($ar == $br) { + return 1 - strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); + } + return ($ar < $br) ? 1 : -1; + } + + /** + * Test whether a cell address falls within a defined range of cells + * + * @param string $cellAddress Address of the cell we're testing + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @return boolean + */ + private static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols) { + list($cellColumn, $cellRow) = PHPExcel_Cell::coordinateFromString($cellAddress); + $cellColumnIndex = PHPExcel_Cell::columnIndexFromString($cellColumn); + // Is cell within the range of rows/columns if we're deleting + if ($pNumRows < 0 && + ($cellRow >= ($beforeRow + $pNumRows)) && + ($cellRow < $beforeRow)) { + return TRUE; + } elseif ($pNumCols < 0 && + ($cellColumnIndex >= ($beforeColumnIndex + $pNumCols)) && + ($cellColumnIndex < $beforeColumnIndex)) { + return TRUE; + } + return FALSE; + } + + /** + * Update page breaks when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aBreaks = $pSheet->getBreaks(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellSort')); + + foreach ($aBreaks as $key => $value) { + if (self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { + // If we're deleting, then clear any defined breaks that are within the range + // of rows/columns that we're deleting + $pSheet->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); + } else { + // Otherwise update any affected breaks by inserting a new break at the appropriate point + // and removing the old affected break + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setBreak($newReference, $value) + ->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); + } + } + } + } + + /** + * Update cell comments when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aComments = $pSheet->getComments(); + $aNewComments = array(); // the new array of all comments + + foreach ($aComments as $key => &$value) { + // Any comments inside a deleted range will be ignored + if (!self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { + // Otherwise build a new array of comments indexed by the adjusted cell reference + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + $aNewComments[$newReference] = $value; + } + } + // Replace the comments array with the new set of comments + $pSheet->setComments($aNewComments); + } + + /** + * Update hyperlinks when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); + + foreach ($aHyperlinkCollection as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setHyperlink( $newReference, $value ); + $pSheet->setHyperlink( $key, null ); + } + } + } + + /** + * Update data validations when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aDataValidationCollection = $pSheet->getDataValidationCollection(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); + foreach ($aDataValidationCollection as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setDataValidation( $newReference, $value ); + $pSheet->setDataValidation( $key, null ); + } + } + } + + /** + * Update merged cells when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aMergeCells = $pSheet->getMergeCells(); + $aNewMergeCells = array(); // the new array of all merge cells + foreach ($aMergeCells as $key => &$value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + $aNewMergeCells[$newReference] = $newReference; + } + $pSheet->setMergeCells($aNewMergeCells); // replace the merge cells array + } + + /** + * Update protected cells when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aProtectedCells = $pSheet->getProtectedCells(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellSort')); + foreach ($aProtectedCells as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->protectCells( $newReference, $value, true ); + $pSheet->unprotectCells( $key ); + } + } + } + + /** + * Update column dimensions when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aColumnDimensions = array_reverse($pSheet->getColumnDimensions(), true); + if (!empty($aColumnDimensions)) { + foreach ($aColumnDimensions as $objColumnDimension) { + $newReference = $this->updateCellReference($objColumnDimension->getColumnIndex() . '1', $pBefore, $pNumCols, $pNumRows); + list($newReference) = PHPExcel_Cell::coordinateFromString($newReference); + if ($objColumnDimension->getColumnIndex() != $newReference) { + $objColumnDimension->setColumnIndex($newReference); + } + } + $pSheet->refreshColumnDimensions(); + } + } + + /** + * Update row dimensions when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aRowDimensions = array_reverse($pSheet->getRowDimensions(), true); + if (!empty($aRowDimensions)) { + foreach ($aRowDimensions as $objRowDimension) { + $newReference = $this->updateCellReference('A' . $objRowDimension->getRowIndex(), $pBefore, $pNumCols, $pNumRows); + list(, $newReference) = PHPExcel_Cell::coordinateFromString($newReference); + if ($objRowDimension->getRowIndex() != $newReference) { + $objRowDimension->setRowIndex($newReference); + } + } + $pSheet->refreshRowDimensions(); + + $copyDimension = $pSheet->getRowDimension($beforeRow - 1); + for ($i = $beforeRow; $i <= $beforeRow - 1 + $pNumRows; ++$i) { + $newDimension = $pSheet->getRowDimension($i); + $newDimension->setRowHeight($copyDimension->getRowHeight()); + $newDimension->setVisible($copyDimension->getVisible()); + $newDimension->setOutlineLevel($copyDimension->getOutlineLevel()); + $newDimension->setCollapsed($copyDimension->getCollapsed()); + } + } + } + + /** + * Insert a new column or row, updating all possible related data + * + * @param string $pBefore Insert before this cell address (e.g. 'A1') + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @throws PHPExcel_Exception + */ + public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, PHPExcel_Worksheet $pSheet = NULL) + { + $remove = ($pNumCols < 0 || $pNumRows < 0); + $aCellCollection = $pSheet->getCellCollection(); + + // Get coordinates of $pBefore + $beforeColumn = 'A'; + $beforeRow = 1; + list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString($pBefore); + $beforeColumnIndex = PHPExcel_Cell::columnIndexFromString($beforeColumn); + + // Clear cells if we are removing columns or rows + $highestColumn = $pSheet->getHighestColumn(); + $highestRow = $pSheet->getHighestRow(); + + // 1. Clear column strips if we are removing columns + if ($pNumCols < 0 && $beforeColumnIndex - 2 + $pNumCols > 0) { + for ($i = 1; $i <= $highestRow - 1; ++$i) { + for ($j = $beforeColumnIndex - 1 + $pNumCols; $j <= $beforeColumnIndex - 2; ++$j) { + $coordinate = PHPExcel_Cell::stringFromColumnIndex($j) . $i; + $pSheet->removeConditionalStyles($coordinate); + if ($pSheet->cellExists($coordinate)) { + $pSheet->getCell($coordinate)->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL); + $pSheet->getCell($coordinate)->setXfIndex(0); + } + } + } + } + + // 2. Clear row strips if we are removing rows + if ($pNumRows < 0 && $beforeRow - 1 + $pNumRows > 0) { + for ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) { + for ($j = $beforeRow + $pNumRows; $j <= $beforeRow - 1; ++$j) { + $coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . $j; + $pSheet->removeConditionalStyles($coordinate); + if ($pSheet->cellExists($coordinate)) { + $pSheet->getCell($coordinate)->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL); + $pSheet->getCell($coordinate)->setXfIndex(0); + } + } + } + } + + // Loop through cells, bottom-up, and change cell coordinates if($remove) { // It's faster to reverse and pop than to use unshift, especially with large cell collections $aCellCollection = array_reverse($aCellCollection); } - while ($cellID = array_pop($aCellCollection)) { - $cell = $pSheet->getCell($cellID); - $cellIndex = PHPExcel_Cell::columnIndexFromString($cell->getColumn()); - - if ($cellIndex-1 + $pNumCols < 0) { - continue; - } - - // New coordinates - $newCoordinates = PHPExcel_Cell::stringFromColumnIndex($cellIndex-1 + $pNumCols) . ($cell->getRow() + $pNumRows); - - // Should the cell be updated? Move value and cellXf index from one cell to another. - if (($cellIndex >= $beforeColumnIndex) && - ($cell->getRow() >= $beforeRow)) { - - // Update cell styles - $pSheet->getCell($newCoordinates)->setXfIndex($cell->getXfIndex()); - - // Insert this cell at its new location - if ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) { - // Formula should be adjusted - $pSheet->getCell($newCoordinates) - ->setValue($this->updateFormulaReferences($cell->getValue(), - $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); - } else { - // Formula should not be adjusted - $pSheet->getCell($newCoordinates)->setValue($cell->getValue()); - } - - // Clear the original cell - $pSheet->getCellCacheController()->deleteCacheData($cellID); - - } else { - /* We don't need to update styles for rows/columns before our insertion position, - but we do still need to adjust any formulae in those cells */ - if ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) { - // Formula should be adjusted - $cell->setValue($this->updateFormulaReferences($cell->getValue(), - $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); - } - - } - } - - // Duplicate styles for the newly inserted cells - $highestColumn = $pSheet->getHighestColumn(); - $highestRow = $pSheet->getHighestRow(); - - if ($pNumCols > 0 && $beforeColumnIndex - 2 > 0) { - for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) { - - // Style - $coordinate = PHPExcel_Cell::stringFromColumnIndex( $beforeColumnIndex - 2 ) . $i; - if ($pSheet->cellExists($coordinate)) { - $xfIndex = $pSheet->getCell($coordinate)->getXfIndex(); - $conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ? - $pSheet->getConditionalStyles($coordinate) : false; - for ($j = $beforeColumnIndex - 1; $j <= $beforeColumnIndex - 2 + $pNumCols; ++$j) { - $pSheet->getCellByColumnAndRow($j, $i)->setXfIndex($xfIndex); - if ($conditionalStyles) { - $cloned = array(); - foreach ($conditionalStyles as $conditionalStyle) { - $cloned[] = clone $conditionalStyle; - } - $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($j) . $i, $cloned); - } - } - } - - } - } - - if ($pNumRows > 0 && $beforeRow - 1 > 0) { - for ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) { - - // Style - $coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . ($beforeRow - 1); - if ($pSheet->cellExists($coordinate)) { - $xfIndex = $pSheet->getCell($coordinate)->getXfIndex(); - $conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ? - $pSheet->getConditionalStyles($coordinate) : false; - for ($j = $beforeRow; $j <= $beforeRow - 1 + $pNumRows; ++$j) { - $pSheet->getCell(PHPExcel_Cell::stringFromColumnIndex($i) . $j)->setXfIndex($xfIndex); - if ($conditionalStyles) { - $cloned = array(); - foreach ($conditionalStyles as $conditionalStyle) { - $cloned[] = clone $conditionalStyle; - } - $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($i) . $j, $cloned); - } - } - } - } - } - - // Update worksheet: column dimensions - $this->_adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); - - // Update worksheet: row dimensions - $this->_adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); - - // Update worksheet: page breaks - $this->_adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); - - // Update worksheet: comments - $this->_adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); - - // Update worksheet: hyperlinks - $this->_adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); - - // Update worksheet: data validations - $this->_adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); - - // Update worksheet: merge cells - $this->_adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); - - // Update worksheet: protected cells - $this->_adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); - - // Update worksheet: autofilter - $autoFilter = $pSheet->getAutoFilter(); - $autoFilterRange = $autoFilter->getRange(); - if (!empty($autoFilterRange)) { - if ($pNumCols != 0) { - $autoFilterColumns = array_keys($autoFilter->getColumns()); - if (count($autoFilterColumns) > 0) { - sscanf($pBefore,'%[A-Z]%d', $column, $row); - $columnIndex = PHPExcel_Cell::columnIndexFromString($column); - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($autoFilterRange); - if ($columnIndex <= $rangeEnd[0]) { - if ($pNumCols < 0) { - // If we're actually deleting any columns that fall within the autofilter range, - // then we delete any rules for those columns - $deleteColumn = $columnIndex + $pNumCols - 1; - $deleteCount = abs($pNumCols); - for ($i = 1; $i <= $deleteCount; ++$i) { - if (in_array(PHPExcel_Cell::stringFromColumnIndex($deleteColumn),$autoFilterColumns)) { - $autoFilter->clearColumn(PHPExcel_Cell::stringFromColumnIndex($deleteColumn)); - } - ++$deleteColumn; - } - } - $startCol = ($columnIndex > $rangeStart[0]) ? $columnIndex : $rangeStart[0]; - - // Shuffle columns in autofilter range - if ($pNumCols > 0) { - // For insert, we shuffle from end to beginning to avoid overwriting - $startColID = PHPExcel_Cell::stringFromColumnIndex($startCol-1); - $toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1); - $endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]); - - $startColRef = $startCol; - $endColRef = $rangeEnd[0]; - $toColRef = $rangeEnd[0]+$pNumCols; - - do { - $autoFilter->shiftColumn(PHPExcel_Cell::stringFromColumnIndex($endColRef-1),PHPExcel_Cell::stringFromColumnIndex($toColRef-1)); - --$endColRef; - --$toColRef; - } while ($startColRef <= $endColRef); - } else { - // For delete, we shuffle from beginning to end to avoid overwriting - $startColID = PHPExcel_Cell::stringFromColumnIndex($startCol-1); - $toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1); - $endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]); - do { - $autoFilter->shiftColumn($startColID,$toColID); - ++$startColID; - ++$toColID; - } while ($startColID != $endColID); - } - } - } - } - $pSheet->setAutoFilter( $this->updateCellReference($autoFilterRange, $pBefore, $pNumCols, $pNumRows) ); - } - - // Update worksheet: freeze pane - if ($pSheet->getFreezePane() != '') { - $pSheet->freezePane( $this->updateCellReference($pSheet->getFreezePane(), $pBefore, $pNumCols, $pNumRows) ); - } - - // Page setup - if ($pSheet->getPageSetup()->isPrintAreaSet()) { - $pSheet->getPageSetup()->setPrintArea( $this->updateCellReference($pSheet->getPageSetup()->getPrintArea(), $pBefore, $pNumCols, $pNumRows) ); - } - - // Update worksheet: drawings - $aDrawings = $pSheet->getDrawingCollection(); - foreach ($aDrawings as $objDrawing) { - $newReference = $this->updateCellReference($objDrawing->getCoordinates(), $pBefore, $pNumCols, $pNumRows); - if ($objDrawing->getCoordinates() != $newReference) { - $objDrawing->setCoordinates($newReference); - } - } - - // Update workbook: named ranges - if (count($pSheet->getParent()->getNamedRanges()) > 0) { - foreach ($pSheet->getParent()->getNamedRanges() as $namedRange) { - if ($namedRange->getWorksheet()->getHashCode() == $pSheet->getHashCode()) { - $namedRange->setRange( - $this->updateCellReference($namedRange->getRange(), $pBefore, $pNumCols, $pNumRows) - ); - } - } - } - - // Garbage collect - $pSheet->garbageCollect(); - } - - /** - * Update references within formulas - * - * @param string $pFormula Formula to update - * @param int $pBefore Insert before this one - * @param int $pNumCols Number of columns to insert - * @param int $pNumRows Number of rows to insert - * @param string $sheetName Worksheet name/title - * @return string Updated formula - * @throws PHPExcel_Exception - */ - public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, $sheetName = '') { - // Update cell references in the formula - $formulaBlocks = explode('"',$pFormula); - $i = false; - foreach($formulaBlocks as &$formulaBlock) { - // Ignore blocks that were enclosed in quotes (alternating entries in the $formulaBlocks array after the explode) - if ($i = !$i) { - $adjustCount = 0; - $newCellTokens = $cellTokens = array(); - // Search for row ranges (e.g. 'Sheet1'!3:5 or 3:5) with or without $ absolutes (e.g. $3:5) - $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_ROWRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); - if ($matchCount > 0) { - foreach($matches as $match) { - $fromString = ($match[2] > '') ? $match[2].'!' : ''; - $fromString .= $match[3].':'.$match[4]; - $modified3 = substr($this->updateCellReference('$A'.$match[3],$pBefore,$pNumCols,$pNumRows),2); - $modified4 = substr($this->updateCellReference('$A'.$match[4],$pBefore,$pNumCols,$pNumRows),2); - - if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { - if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { - $toString = ($match[2] > '') ? $match[2].'!' : ''; - $toString .= $modified3.':'.$modified4; - // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more - $column = 100000; - $row = 10000000+trim($match[3],'$'); - $cellIndex = $column.$row; - - $newCellTokens[$cellIndex] = preg_quote($toString); - $cellTokens[$cellIndex] = '/(?<!\d\$\!)'.preg_quote($fromString).'(?!\d)/i'; - ++$adjustCount; - } - } - } - } - // Search for column ranges (e.g. 'Sheet1'!C:E or C:E) with or without $ absolutes (e.g. $C:E) - $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_COLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); - if ($matchCount > 0) { - foreach($matches as $match) { - $fromString = ($match[2] > '') ? $match[2].'!' : ''; - $fromString .= $match[3].':'.$match[4]; - $modified3 = substr($this->updateCellReference($match[3].'$1',$pBefore,$pNumCols,$pNumRows),0,-2); - $modified4 = substr($this->updateCellReference($match[4].'$1',$pBefore,$pNumCols,$pNumRows),0,-2); - - if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { - if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { - $toString = ($match[2] > '') ? $match[2].'!' : ''; - $toString .= $modified3.':'.$modified4; - // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more - $column = PHPExcel_Cell::columnIndexFromString(trim($match[3],'$')) + 100000; - $row = 10000000; - $cellIndex = $column.$row; - - $newCellTokens[$cellIndex] = preg_quote($toString); - $cellTokens[$cellIndex] = '/(?<![A-Z\$\!])'.preg_quote($fromString).'(?![A-Z])/i'; - ++$adjustCount; - } - } - } - } - // Search for cell ranges (e.g. 'Sheet1'!A3:C5 or A3:C5) with or without $ absolutes (e.g. $A1:C$5) - $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); - if ($matchCount > 0) { - foreach($matches as $match) { - $fromString = ($match[2] > '') ? $match[2].'!' : ''; - $fromString .= $match[3].':'.$match[4]; - $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); - $modified4 = $this->updateCellReference($match[4],$pBefore,$pNumCols,$pNumRows); - - if ($match[3].$match[4] !== $modified3.$modified4) { - if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { - $toString = ($match[2] > '') ? $match[2].'!' : ''; - $toString .= $modified3.':'.$modified4; - list($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]); - // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more - $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; - $row = trim($row,'$') + 10000000; - $cellIndex = $column.$row; - - $newCellTokens[$cellIndex] = preg_quote($toString); - $cellTokens[$cellIndex] = '/(?<![A-Z]\$\!)'.preg_quote($fromString).'(?!\d)/i'; - ++$adjustCount; - } - } - } - } - // Search for cell references (e.g. 'Sheet1'!A3 or C5) with or without $ absolutes (e.g. $A1 or C$5) - $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLREF.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); - - if ($matchCount > 0) { - foreach($matches as $match) { - $fromString = ($match[2] > '') ? $match[2].'!' : ''; - $fromString .= $match[3]; - - $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); - if ($match[3] !== $modified3) { - if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { - $toString = ($match[2] > '') ? $match[2].'!' : ''; - $toString .= $modified3; - list($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]); - // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more - $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; - $row = trim($row,'$') + 10000000; - $cellIndex = $row . $column; - - $newCellTokens[$cellIndex] = preg_quote($toString); - $cellTokens[$cellIndex] = '/(?<![A-Z\$\!])'.preg_quote($fromString).'(?!\d)/i'; - ++$adjustCount; - } - } - } - } - if ($adjustCount > 0) { + while ($cellID = array_pop($aCellCollection)) { + $cell = $pSheet->getCell($cellID); + $cellIndex = PHPExcel_Cell::columnIndexFromString($cell->getColumn()); + + if ($cellIndex-1 + $pNumCols < 0) { + continue; + } + + // New coordinates + $newCoordinates = PHPExcel_Cell::stringFromColumnIndex($cellIndex-1 + $pNumCols) . ($cell->getRow() + $pNumRows); + + // Should the cell be updated? Move value and cellXf index from one cell to another. + if (($cellIndex >= $beforeColumnIndex) && + ($cell->getRow() >= $beforeRow)) { + + // Update cell styles + $pSheet->getCell($newCoordinates)->setXfIndex($cell->getXfIndex()); + + // Insert this cell at its new location + if ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) { + // Formula should be adjusted + $pSheet->getCell($newCoordinates) + ->setValue($this->updateFormulaReferences($cell->getValue(), + $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); + } else { + // Formula should not be adjusted + $pSheet->getCell($newCoordinates)->setValue($cell->getValue()); + } + + // Clear the original cell + $pSheet->getCellCacheController()->deleteCacheData($cellID); + + } else { + /* We don't need to update styles for rows/columns before our insertion position, + but we do still need to adjust any formulae in those cells */ + if ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) { + // Formula should be adjusted + $cell->setValue($this->updateFormulaReferences($cell->getValue(), + $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); + } + + } + } + + // Duplicate styles for the newly inserted cells + $highestColumn = $pSheet->getHighestColumn(); + $highestRow = $pSheet->getHighestRow(); + + if ($pNumCols > 0 && $beforeColumnIndex - 2 > 0) { + for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) { + + // Style + $coordinate = PHPExcel_Cell::stringFromColumnIndex( $beforeColumnIndex - 2 ) . $i; + if ($pSheet->cellExists($coordinate)) { + $xfIndex = $pSheet->getCell($coordinate)->getXfIndex(); + $conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ? + $pSheet->getConditionalStyles($coordinate) : false; + for ($j = $beforeColumnIndex - 1; $j <= $beforeColumnIndex - 2 + $pNumCols; ++$j) { + $pSheet->getCellByColumnAndRow($j, $i)->setXfIndex($xfIndex); + if ($conditionalStyles) { + $cloned = array(); + foreach ($conditionalStyles as $conditionalStyle) { + $cloned[] = clone $conditionalStyle; + } + $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($j) . $i, $cloned); + } + } + } + + } + } + + if ($pNumRows > 0 && $beforeRow - 1 > 0) { + for ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) { + + // Style + $coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . ($beforeRow - 1); + if ($pSheet->cellExists($coordinate)) { + $xfIndex = $pSheet->getCell($coordinate)->getXfIndex(); + $conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ? + $pSheet->getConditionalStyles($coordinate) : false; + for ($j = $beforeRow; $j <= $beforeRow - 1 + $pNumRows; ++$j) { + $pSheet->getCell(PHPExcel_Cell::stringFromColumnIndex($i) . $j)->setXfIndex($xfIndex); + if ($conditionalStyles) { + $cloned = array(); + foreach ($conditionalStyles as $conditionalStyle) { + $cloned[] = clone $conditionalStyle; + } + $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($i) . $j, $cloned); + } + } + } + } + } + + // Update worksheet: column dimensions + $this->_adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: row dimensions + $this->_adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: page breaks + $this->_adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: comments + $this->_adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: hyperlinks + $this->_adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: data validations + $this->_adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: merge cells + $this->_adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: protected cells + $this->_adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: autofilter + $autoFilter = $pSheet->getAutoFilter(); + $autoFilterRange = $autoFilter->getRange(); + if (!empty($autoFilterRange)) { + if ($pNumCols != 0) { + $autoFilterColumns = array_keys($autoFilter->getColumns()); + if (count($autoFilterColumns) > 0) { + sscanf($pBefore,'%[A-Z]%d', $column, $row); + $columnIndex = PHPExcel_Cell::columnIndexFromString($column); + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($autoFilterRange); + if ($columnIndex <= $rangeEnd[0]) { + if ($pNumCols < 0) { + // If we're actually deleting any columns that fall within the autofilter range, + // then we delete any rules for those columns + $deleteColumn = $columnIndex + $pNumCols - 1; + $deleteCount = abs($pNumCols); + for ($i = 1; $i <= $deleteCount; ++$i) { + if (in_array(PHPExcel_Cell::stringFromColumnIndex($deleteColumn),$autoFilterColumns)) { + $autoFilter->clearColumn(PHPExcel_Cell::stringFromColumnIndex($deleteColumn)); + } + ++$deleteColumn; + } + } + $startCol = ($columnIndex > $rangeStart[0]) ? $columnIndex : $rangeStart[0]; + + // Shuffle columns in autofilter range + if ($pNumCols > 0) { + // For insert, we shuffle from end to beginning to avoid overwriting + $startColID = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1); + $endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]); + + $startColRef = $startCol; + $endColRef = $rangeEnd[0]; + $toColRef = $rangeEnd[0]+$pNumCols; + + do { + $autoFilter->shiftColumn(PHPExcel_Cell::stringFromColumnIndex($endColRef-1),PHPExcel_Cell::stringFromColumnIndex($toColRef-1)); + --$endColRef; + --$toColRef; + } while ($startColRef <= $endColRef); + } else { + // For delete, we shuffle from beginning to end to avoid overwriting + $startColID = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1); + $endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]); + do { + $autoFilter->shiftColumn($startColID,$toColID); + ++$startColID; + ++$toColID; + } while ($startColID != $endColID); + } + } + } + } + $pSheet->setAutoFilter( $this->updateCellReference($autoFilterRange, $pBefore, $pNumCols, $pNumRows) ); + } + + // Update worksheet: freeze pane + if ($pSheet->getFreezePane() != '') { + $pSheet->freezePane( $this->updateCellReference($pSheet->getFreezePane(), $pBefore, $pNumCols, $pNumRows) ); + } + + // Page setup + if ($pSheet->getPageSetup()->isPrintAreaSet()) { + $pSheet->getPageSetup()->setPrintArea( $this->updateCellReference($pSheet->getPageSetup()->getPrintArea(), $pBefore, $pNumCols, $pNumRows) ); + } + + // Update worksheet: drawings + $aDrawings = $pSheet->getDrawingCollection(); + foreach ($aDrawings as $objDrawing) { + $newReference = $this->updateCellReference($objDrawing->getCoordinates(), $pBefore, $pNumCols, $pNumRows); + if ($objDrawing->getCoordinates() != $newReference) { + $objDrawing->setCoordinates($newReference); + } + } + + // Update workbook: named ranges + if (count($pSheet->getParent()->getNamedRanges()) > 0) { + foreach ($pSheet->getParent()->getNamedRanges() as $namedRange) { + if ($namedRange->getWorksheet()->getHashCode() == $pSheet->getHashCode()) { + $namedRange->setRange( + $this->updateCellReference($namedRange->getRange(), $pBefore, $pNumCols, $pNumRows) + ); + } + } + } + + // Garbage collect + $pSheet->garbageCollect(); + } + + /** + * Update references within formulas + * + * @param string $pFormula Formula to update + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to insert + * @param int $pNumRows Number of rows to insert + * @param string $sheetName Worksheet name/title + * @return string Updated formula + * @throws PHPExcel_Exception + */ + public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, $sheetName = '') { + // Update cell references in the formula + $formulaBlocks = explode('"',$pFormula); + $i = false; + foreach($formulaBlocks as &$formulaBlock) { + // Ignore blocks that were enclosed in quotes (alternating entries in the $formulaBlocks array after the explode) + if ($i = !$i) { + $adjustCount = 0; + $newCellTokens = $cellTokens = array(); + // Search for row ranges (e.g. 'Sheet1'!3:5 or 3:5) with or without $ absolutes (e.g. $3:5) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_ROWRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3].':'.$match[4]; + $modified3 = substr($this->updateCellReference('$A'.$match[3],$pBefore,$pNumCols,$pNumRows),2); + $modified4 = substr($this->updateCellReference('$A'.$match[4],$pBefore,$pNumCols,$pNumRows),2); + + if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3.':'.$modified4; + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = 100000; + $row = 10000000+trim($match[3],'$'); + $cellIndex = $column.$row; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<!\d\$\!)'.preg_quote($fromString).'(?!\d)/i'; + ++$adjustCount; + } + } + } + } + // Search for column ranges (e.g. 'Sheet1'!C:E or C:E) with or without $ absolutes (e.g. $C:E) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_COLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3].':'.$match[4]; + $modified3 = substr($this->updateCellReference($match[3].'$1',$pBefore,$pNumCols,$pNumRows),0,-2); + $modified4 = substr($this->updateCellReference($match[4].'$1',$pBefore,$pNumCols,$pNumRows),0,-2); + + if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3.':'.$modified4; + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = PHPExcel_Cell::columnIndexFromString(trim($match[3],'$')) + 100000; + $row = 10000000; + $cellIndex = $column.$row; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<![A-Z\$\!])'.preg_quote($fromString).'(?![A-Z])/i'; + ++$adjustCount; + } + } + } + } + // Search for cell ranges (e.g. 'Sheet1'!A3:C5 or A3:C5) with or without $ absolutes (e.g. $A1:C$5) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3].':'.$match[4]; + $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); + $modified4 = $this->updateCellReference($match[4],$pBefore,$pNumCols,$pNumRows); + + if ($match[3].$match[4] !== $modified3.$modified4) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3.':'.$modified4; + list($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]); + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; + $row = trim($row,'$') + 10000000; + $cellIndex = $column.$row; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<![A-Z]\$\!)'.preg_quote($fromString).'(?!\d)/i'; + ++$adjustCount; + } + } + } + } + // Search for cell references (e.g. 'Sheet1'!A3 or C5) with or without $ absolutes (e.g. $A1 or C$5) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLREF.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3]; + + $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); + if ($match[3] !== $modified3) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3; + list($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]); + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; + $row = trim($row,'$') + 10000000; + $cellIndex = $row . $column; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<![A-Z\$\!])'.preg_quote($fromString).'(?!\d)/i'; + ++$adjustCount; + } + } + } + } + if ($adjustCount > 0) { if ($pNumCols > 0 || $pNumRows > 0) { krsort($cellTokens); krsort($newCellTokens); @@ -769,154 +761,154 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo ksort($cellTokens); ksort($newCellTokens); } // Update cell references in the formula - $formulaBlock = str_replace('\\','',preg_replace($cellTokens,$newCellTokens,$formulaBlock)); - } - } - } - unset($formulaBlock); - - // Then rebuild the formula string - return implode('"',$formulaBlocks); - } - - /** - * Update cell reference - * - * @param string $pCellRange Cell range - * @param int $pBefore Insert before this one - * @param int $pNumCols Number of columns to increment - * @param int $pNumRows Number of rows to increment - * @return string Updated cell range - * @throws PHPExcel_Exception - */ - public function updateCellReference($pCellRange = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { - // Is it in another worksheet? Will not have to update anything. - if (strpos($pCellRange, "!") !== false) { - return $pCellRange; - // Is it a range or a single cell? - } elseif (strpos($pCellRange, ':') === false && strpos($pCellRange, ',') === false) { - // Single cell - return $this->_updateSingleCellReference($pCellRange, $pBefore, $pNumCols, $pNumRows); - } elseif (strpos($pCellRange, ':') !== false || strpos($pCellRange, ',') !== false) { - // Range - return $this->_updateCellRange($pCellRange, $pBefore, $pNumCols, $pNumRows); - } else { - // Return original - return $pCellRange; - } - } - - /** - * Update named formulas (i.e. containing worksheet references / named ranges) - * - * @param PHPExcel $pPhpExcel Object to update - * @param string $oldName Old name (name to replace) - * @param string $newName New name - */ - public function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName = '') { - if ($oldName == '') { - return; - } - - foreach ($pPhpExcel->getWorksheetIterator() as $sheet) { - foreach ($sheet->getCellCollection(false) as $cellID) { - $cell = $sheet->getCell($cellID); - if (($cell !== NULL) && ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA)) { - $formula = $cell->getValue(); - if (strpos($formula, $oldName) !== false) { - $formula = str_replace("'" . $oldName . "'!", "'" . $newName . "'!", $formula); - $formula = str_replace($oldName . "!", $newName . "!", $formula); - $cell->setValueExplicit($formula, PHPExcel_Cell_DataType::TYPE_FORMULA); - } - } - } - } - } - - /** - * Update cell range - * - * @param string $pCellRange Cell range (e.g. 'B2:D4', 'B:C' or '2:3') - * @param int $pBefore Insert before this one - * @param int $pNumCols Number of columns to increment - * @param int $pNumRows Number of rows to increment - * @return string Updated cell range - * @throws PHPExcel_Exception - */ - private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { - if (strpos($pCellRange,':') !== false || strpos($pCellRange, ',') !== false) { - // Update range - $range = PHPExcel_Cell::splitRange($pCellRange); - $ic = count($range); - for ($i = 0; $i < $ic; ++$i) { - $jc = count($range[$i]); - for ($j = 0; $j < $jc; ++$j) { - if (ctype_alpha($range[$i][$j])) { - $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference($range[$i][$j].'1', $pBefore, $pNumCols, $pNumRows)); - $range[$i][$j] = $r[0]; - } elseif(ctype_digit($range[$i][$j])) { - $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference('A'.$range[$i][$j], $pBefore, $pNumCols, $pNumRows)); - $range[$i][$j] = $r[1]; - } else { - $range[$i][$j] = $this->_updateSingleCellReference($range[$i][$j], $pBefore, $pNumCols, $pNumRows); - } - } - } - - // Recreate range string - return PHPExcel_Cell::buildRange($range); - } else { - throw new PHPExcel_Exception("Only cell ranges may be passed to this method."); - } - } - - /** - * Update single cell reference - * - * @param string $pCellReference Single cell reference - * @param int $pBefore Insert before this one - * @param int $pNumCols Number of columns to increment - * @param int $pNumRows Number of rows to increment - * @return string Updated cell reference - * @throws PHPExcel_Exception - */ - private function _updateSingleCellReference($pCellReference = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { - if (strpos($pCellReference, ':') === false && strpos($pCellReference, ',') === false) { - // Get coordinates of $pBefore - list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString( $pBefore ); - - // Get coordinates of $pCellReference - list($newColumn, $newRow) = PHPExcel_Cell::coordinateFromString( $pCellReference ); - - // Verify which parts should be updated - $updateColumn = (($newColumn{0} != '$') && ($beforeColumn{0} != '$') && - PHPExcel_Cell::columnIndexFromString($newColumn) >= PHPExcel_Cell::columnIndexFromString($beforeColumn)); - $updateRow = (($newRow{0} != '$') && ($beforeRow{0} != '$') && - $newRow >= $beforeRow); - - // Create new column reference - if ($updateColumn) { - $newColumn = PHPExcel_Cell::stringFromColumnIndex( PHPExcel_Cell::columnIndexFromString($newColumn) - 1 + $pNumCols ); - } - - // Create new row reference - if ($updateRow) { - $newRow = $newRow + $pNumRows; - } - - // Return new reference - return $newColumn . $newRow; - } else { - throw new PHPExcel_Exception("Only single cell references may be passed to this method."); - } - } - - /** - * __clone implementation. Cloning should not be allowed in a Singleton! - * - * @throws PHPExcel_Exception - */ - public final function __clone() { - throw new PHPExcel_Exception("Cloning a Singleton is not allowed!"); - } + $formulaBlock = str_replace('\\','',preg_replace($cellTokens,$newCellTokens,$formulaBlock)); + } + } + } + unset($formulaBlock); + + // Then rebuild the formula string + return implode('"',$formulaBlocks); + } + + /** + * Update cell reference + * + * @param string $pCellRange Cell range + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to increment + * @param int $pNumRows Number of rows to increment + * @return string Updated cell range + * @throws PHPExcel_Exception + */ + public function updateCellReference($pCellRange = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + // Is it in another worksheet? Will not have to update anything. + if (strpos($pCellRange, "!") !== false) { + return $pCellRange; + // Is it a range or a single cell? + } elseif (strpos($pCellRange, ':') === false && strpos($pCellRange, ',') === false) { + // Single cell + return $this->_updateSingleCellReference($pCellRange, $pBefore, $pNumCols, $pNumRows); + } elseif (strpos($pCellRange, ':') !== false || strpos($pCellRange, ',') !== false) { + // Range + return $this->_updateCellRange($pCellRange, $pBefore, $pNumCols, $pNumRows); + } else { + // Return original + return $pCellRange; + } + } + + /** + * Update named formulas (i.e. containing worksheet references / named ranges) + * + * @param PHPExcel $pPhpExcel Object to update + * @param string $oldName Old name (name to replace) + * @param string $newName New name + */ + public function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName = '') { + if ($oldName == '') { + return; + } + + foreach ($pPhpExcel->getWorksheetIterator() as $sheet) { + foreach ($sheet->getCellCollection(false) as $cellID) { + $cell = $sheet->getCell($cellID); + if (($cell !== NULL) && ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA)) { + $formula = $cell->getValue(); + if (strpos($formula, $oldName) !== false) { + $formula = str_replace("'" . $oldName . "'!", "'" . $newName . "'!", $formula); + $formula = str_replace($oldName . "!", $newName . "!", $formula); + $cell->setValueExplicit($formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + } + } + } + } + } + + /** + * Update cell range + * + * @param string $pCellRange Cell range (e.g. 'B2:D4', 'B:C' or '2:3') + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to increment + * @param int $pNumRows Number of rows to increment + * @return string Updated cell range + * @throws PHPExcel_Exception + */ + private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + if (strpos($pCellRange,':') !== false || strpos($pCellRange, ',') !== false) { + // Update range + $range = PHPExcel_Cell::splitRange($pCellRange); + $ic = count($range); + for ($i = 0; $i < $ic; ++$i) { + $jc = count($range[$i]); + for ($j = 0; $j < $jc; ++$j) { + if (ctype_alpha($range[$i][$j])) { + $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference($range[$i][$j].'1', $pBefore, $pNumCols, $pNumRows)); + $range[$i][$j] = $r[0]; + } elseif(ctype_digit($range[$i][$j])) { + $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference('A'.$range[$i][$j], $pBefore, $pNumCols, $pNumRows)); + $range[$i][$j] = $r[1]; + } else { + $range[$i][$j] = $this->_updateSingleCellReference($range[$i][$j], $pBefore, $pNumCols, $pNumRows); + } + } + } + + // Recreate range string + return PHPExcel_Cell::buildRange($range); + } else { + throw new PHPExcel_Exception("Only cell ranges may be passed to this method."); + } + } + + /** + * Update single cell reference + * + * @param string $pCellReference Single cell reference + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to increment + * @param int $pNumRows Number of rows to increment + * @return string Updated cell reference + * @throws PHPExcel_Exception + */ + private function _updateSingleCellReference($pCellReference = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + if (strpos($pCellReference, ':') === false && strpos($pCellReference, ',') === false) { + // Get coordinates of $pBefore + list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString( $pBefore ); + + // Get coordinates of $pCellReference + list($newColumn, $newRow) = PHPExcel_Cell::coordinateFromString( $pCellReference ); + + // Verify which parts should be updated + $updateColumn = (($newColumn{0} != '$') && ($beforeColumn{0} != '$') && + PHPExcel_Cell::columnIndexFromString($newColumn) >= PHPExcel_Cell::columnIndexFromString($beforeColumn)); + $updateRow = (($newRow{0} != '$') && ($beforeRow{0} != '$') && + $newRow >= $beforeRow); + + // Create new column reference + if ($updateColumn) { + $newColumn = PHPExcel_Cell::stringFromColumnIndex( PHPExcel_Cell::columnIndexFromString($newColumn) - 1 + $pNumCols ); + } + + // Create new row reference + if ($updateRow) { + $newRow = $newRow + $pNumRows; + } + + // Return new reference + return $newColumn . $newRow; + } else { + throw new PHPExcel_Exception("Only single cell references may be passed to this method."); + } + } + + /** + * __clone implementation. Cloning should not be allowed in a Singleton! + * + * @throws PHPExcel_Exception + */ + public final function __clone() { + throw new PHPExcel_Exception("Cloning a Singleton is not allowed!"); + } } diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index f3f89d52f..8d380848f 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Worksheet * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Worksheet - * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Worksheet implements PHPExcel_IComparable { /* Break types */ @@ -332,7 +324,7 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable */ private $_codeName = null; - /** + /** * Create a new worksheet * * @param PHPExcel $pParent @@ -344,7 +336,7 @@ public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') $this->_parent = $pParent; $this->setTitle($pTitle, FALSE); // setTitle can change $pTitle - $this->setCodeName($this->getTitle()); + $this->setCodeName($this->getTitle()); $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE); $this->_cellCollection = PHPExcel_CachedObjectStorageFactory::getInstance($this); @@ -385,11 +377,11 @@ public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') * typically so that the worksheet object can be unset * */ - public function disconnectCells() { - if ( $this->_cellCollection !== NULL){ + public function disconnectCells() { + if ( $this->_cellCollection !== NULL){ $this->_cellCollection->unsetWorksheetCells(); $this->_cellCollection = NULL; - } + } // detach ourself from the workbook, so that it can then delete this worksheet successfully $this->_parent = null; } @@ -398,19 +390,19 @@ public function disconnectCells() { * Code to execute when this worksheet is unset() * */ - function __destruct() { - PHPExcel_Calculation::getInstance($this->_parent) - ->clearCalculationCacheForWorksheet($this->_title); + function __destruct() { + PHPExcel_Calculation::getInstance($this->_parent) + ->clearCalculationCacheForWorksheet($this->_title); - $this->disconnectCells(); - } + $this->disconnectCells(); + } /** * Return the cache controller for the cell collection * * @return PHPExcel_CachedObjectStorage_xxx */ - public function getCellCacheController() { + public function getCellCacheController() { return $this->_cellCollection; } // function getCellCacheController() @@ -745,22 +737,22 @@ public function calculateColumnWidths($calculateMergeCells = false) // loop through all cells in the worksheet foreach ($this->getCellCollection(false) as $cellID) { $cell = $this->getCell($cellID); - if (isset($autoSizes[$this->_cellCollection->getCurrentColumn()])) { + if (isset($autoSizes[$this->_cellCollection->getCurrentColumn()])) { // Determine width if cell does not participate in a merge - if (!isset($isMergeCell[$this->_cellCollection->getCurrentAddress()])) { + if (!isset($isMergeCell[$this->_cellCollection->getCurrentAddress()])) { // Calculated value // To formatted string - $cellValue = PHPExcel_Style_NumberFormat::toFormattedString( - $cell->getCalculatedValue(), - $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode() - ); + $cellValue = PHPExcel_Style_NumberFormat::toFormattedString( + $cell->getCalculatedValue(), + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode() + ); - $autoSizes[$this->_cellCollection->getCurrentColumn()] = max( - (float) $autoSizes[$this->_cellCollection->getCurrentColumn()], + $autoSizes[$this->_cellCollection->getCurrentColumn()] = max( + (float) $autoSizes[$this->_cellCollection->getCurrentColumn()], (float)PHPExcel_Shared_Font::calculateColumnWidth( - $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(), + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(), $cellValue, - $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(), + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(), $this->getDefaultStyle()->getFont() ) ); @@ -783,7 +775,7 @@ public function calculateColumnWidths($calculateMergeCells = false) * * @return PHPExcel */ - public function getParent() { + public function getParent() { return $this->_parent; } @@ -793,7 +785,7 @@ public function getParent() { * @param PHPExcel $parent * @return PHPExcel_Worksheet */ - public function rebindParent(PHPExcel $parent) { + public function rebindParent(PHPExcel $parent) { if ($this->_parent !== null) { $namedRanges = $this->_parent->getNamedRanges(); foreach ($namedRanges as $namedRange) { @@ -824,7 +816,7 @@ public function getTitle() * * @param string $pValue String containing the dimension of this worksheet * @param string $updateFormulaCellReferences boolean Flag indicating whether cell references in formulae should - * be updated to reflect the new sheet name. + * be updated to reflect the new sheet name. * This should be left as the default true, unless you are * certain that no formula cells on any worksheet contain * references to this worksheet @@ -845,14 +837,14 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t if ($this->_parent) { // Is there already such sheet name? - if ($this->_parent->sheetNameExists($pValue)) { + if ($this->_parent->sheetNameExists($pValue)) { // Use name, but append with lowest possible integer if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); } $i = 1; - while ($this->_parent->sheetNameExists($pValue . ' ' . $i)) { + while ($this->_parent->sheetNameExists($pValue . ' ' . $i)) { ++$i; if ($i == 10) { if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { @@ -877,10 +869,10 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t if ($this->_parent) { // New title $newTitle = $this->getTitle(); - PHPExcel_Calculation::getInstance($this->_parent) - ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); + PHPExcel_Calculation::getInstance($this->_parent) + ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); if ($updateFormulaCellReferences) - PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_parent, $oldTitle, $newTitle); + PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_parent, $oldTitle, $newTitle); } return $this; @@ -891,7 +883,7 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t * * @return string Sheet state (visible, hidden, veryHidden) */ - public function getSheetState() { + public function getSheetState() { return $this->_sheetState; } @@ -901,7 +893,7 @@ public function getSheetState() { * @param string $value Sheet state (visible, hidden, veryHidden) * @return PHPExcel_Worksheet */ - public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) { + public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) { $this->_sheetState = $value; return $this; } @@ -1160,7 +1152,7 @@ public function getCell($pCoordinate = 'A1') // Worksheet reference? if (strpos($pCoordinate, '!') !== false) { $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); - return $this->_parent->getSheetByName($worksheetReference[0])->getCell(strtoupper($worksheetReference[1])); + return $this->_parent->getSheetByName($worksheetReference[0])->getCell(strtoupper($worksheetReference[1])); } // Named range? @@ -1202,7 +1194,7 @@ public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) return $this->_cellCollection->getCacheData($coordinate); } - return $this->_createNewCell($coordinate); + return $this->_createNewCell($coordinate); } /** @@ -1211,16 +1203,16 @@ public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) * @param string $pCoordinate Coordinate of the cell * @return PHPExcel_Cell Cell that was created */ - private function _createNewCell($pCoordinate) - { - $cell = $this->_cellCollection->addCacheData( - $pCoordinate, - new PHPExcel_Cell( - NULL, - PHPExcel_Cell_DataType::TYPE_NULL, - $this - ) - ); + private function _createNewCell($pCoordinate) + { + $cell = $this->_cellCollection->addCacheData( + $pCoordinate, + new PHPExcel_Cell( + NULL, + PHPExcel_Cell_DataType::TYPE_NULL, + $this + ) + ); $this->_cellCollectionIsSorted = false; // Coordinates @@ -1230,7 +1222,7 @@ private function _createNewCell($pCoordinate) $this->_cachedHighestRow = max($this->_cachedHighestRow, $aCoordinates[1]); // Cell needs appropriate xfIndex from dimensions records - // but don't create dimension records if they don't already exist + // but don't create dimension records if they don't already exist $rowDimension = $this->getRowDimension($aCoordinates[1], FALSE); $columnDimension = $this->getColumnDimension($aCoordinates[0], FALSE); @@ -1243,8 +1235,8 @@ private function _createNewCell($pCoordinate) } return $cell; - } - + } + /** * Does the cell at a specific coordinate exist? * @@ -1257,7 +1249,7 @@ public function cellExists($pCoordinate = 'A1') // Worksheet reference? if (strpos($pCoordinate, '!') !== false) { $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); - return $this->_parent->getSheetByName($worksheetReference[0])->cellExists(strtoupper($worksheetReference[1])); + return $this->_parent->getSheetByName($worksheetReference[0])->cellExists(strtoupper($worksheetReference[1])); } // Named range? @@ -1318,8 +1310,8 @@ public function getRowDimension($pRow = 1, $create = TRUE) // Get row dimension if (!isset($this->_rowDimensions[$pRow])) { - if (!$create) - return NULL; + if (!$create) + return NULL; $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow); $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow); @@ -1340,8 +1332,8 @@ public function getColumnDimension($pColumn = 'A', $create = TRUE) // Fetch dimensions if (!isset($this->_columnDimensions[$pColumn])) { - if (!$create) - return NULL; + if (!$create) + return NULL; $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn); if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) @@ -1496,10 +1488,10 @@ public function setConditionalStyles($pCoordinate = 'A1', $pValue) public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1, $pColumn2 = null, $pRow2 = null) { if (!is_null($pColumn2) && !is_null($pRow2)) { - $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow . ':' . + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; - return $this->getStyle($cellRange); - } + return $this->getStyle($cellRange); + } return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); } @@ -1538,7 +1530,7 @@ public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') // Add the style to the workbook if necessary $workbook = $this->_parent; - if ($existingStyle = $this->_parent->getCellXfByHashCode($pCellStyle->getHashCode())) { + if ($existingStyle = $this->_parent->getCellXfByHashCode($pCellStyle->getHashCode())) { // there is already such cell Xf in our collection $xfIndex = $existingStyle->getIndex(); } else { @@ -1572,7 +1564,7 @@ public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') * * Please note that this will overwrite existing cell styles for cells in range! * - * @param array of PHPExcel_Style_Conditional $pCellStyle Cell style to duplicate + * @param array of PHPExcel_Style_Conditional $pCellStyle Cell style to duplicate * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") * @throws PHPExcel_Exception * @return PHPExcel_Worksheet @@ -1639,13 +1631,13 @@ public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE $pCell = strtoupper($pCell); if ($pCell != '') { - if ($pBreak == PHPExcel_Worksheet::BREAK_NONE) { - if (isset($this->_breaks[$pCell])) { - unset($this->_breaks[$pCell]); - } - } else { - $this->_breaks[$pCell] = $pBreak; - } + if ($pBreak == PHPExcel_Worksheet::BREAK_NONE) { + if (isset($this->_breaks[$pCell])) { + unset($this->_breaks[$pCell]); + } + } else { + $this->_breaks[$pCell] = $pBreak; + } } else { throw new PHPExcel_Exception('No cell coordinate specified.'); } @@ -2229,7 +2221,7 @@ public function getComments() /** * Set comments array for the entire sheet. * - * @param array of PHPExcel_Comment + * @param array of PHPExcel_Comment * @return PHPExcel_Worksheet */ public function setComments($pValue = array()) @@ -2447,7 +2439,7 @@ public function fromArray($source = null, $nullValue = null, $startCell = 'A1', * True - Return rows and columns indexed by their actual row and column IDs * @return array */ - public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { // Returnvalue $returnValue = array(); // Identify the range that we need to extract from the worksheet @@ -2485,10 +2477,10 @@ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormul if ($formatData) { $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString( - $returnValue[$rRef][$cRef], - ($style && $style->getNumberFormat()) ? - $style->getNumberFormat()->getFormatCode() : - PHPExcel_Style_NumberFormat::FORMAT_GENERAL + $returnValue[$rRef][$cRef], + ($style && $style->getNumberFormat()) ? + $style->getNumberFormat()->getFormatCode() : + PHPExcel_Style_NumberFormat::FORMAT_GENERAL ); } } else { @@ -2519,14 +2511,14 @@ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormul * @return array * @throws PHPExcel_Exception */ - public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { $namedRange = PHPExcel_NamedRange::resolveRange($pNamedRange, $this); if ($namedRange !== NULL) { $pWorkSheet = $namedRange->getWorksheet(); $pCellRange = $namedRange->getRange(); - return $pWorkSheet->rangeToArray( $pCellRange, - $nullValue, $calculateFormulas, $formatData, $returnCellRef); + return $pWorkSheet->rangeToArray( $pCellRange, + $nullValue, $calculateFormulas, $formatData, $returnCellRef); } throw new PHPExcel_Exception('Named Range '.$pNamedRange.' does not exist.'); @@ -2543,7 +2535,7 @@ public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calcula * True - Return rows and columns indexed by their actual row and column IDs * @return array */ - public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { // Garbage collect... $this->garbageCollect(); @@ -2551,8 +2543,8 @@ public function toArray($nullValue = null, $calculateFormulas = true, $formatDat $maxCol = $this->getHighestColumn(); $maxRow = $this->getHighestRow(); // Return - return $this->rangeToArray( 'A1:'.$maxCol.$maxRow, - $nullValue, $calculateFormulas, $formatData, $returnCellRef); + return $this->rangeToArray( 'A1:'.$maxCol.$maxRow, + $nullValue, $calculateFormulas, $formatData, $returnCellRef); } /** @@ -2563,7 +2555,7 @@ public function toArray($nullValue = null, $calculateFormulas = true, $formatDat * * @return PHPExcel_Worksheet_RowIterator */ - public function getRowIterator($startRow = 1, $endRow = null) { + public function getRowIterator($startRow = 1, $endRow = null) { return new PHPExcel_Worksheet_RowIterator($this, $startRow, $endRow); } @@ -2575,7 +2567,7 @@ public function getRowIterator($startRow = 1, $endRow = null) { * * @return PHPExcel_Worksheet_ColumnIterator */ - public function getColumnIterator($startColumn = 'A', $endColumn = null) { + public function getColumnIterator($startColumn = 'A', $endColumn = null) { return new PHPExcel_Worksheet_ColumnIterator($this, $startColumn, $endColumn); } @@ -2584,7 +2576,7 @@ public function getColumnIterator($startColumn = 'A', $endColumn = null) { * * @return PHPExcel_Worksheet */ - public function garbageCollect() { + public function garbageCollect() { // Flush cache $this->_cellCollection->getCacheData('A1'); // Build a reference table from images @@ -2628,7 +2620,7 @@ public function garbageCollect() { * * @return string Hash code */ - public function getHashCode() { + public function getHashCode() { if ($this->_dirty) { $this->_hash = md5( $this->_title . $this->_autoFilter . @@ -2650,7 +2642,7 @@ public function getHashCode() { * @param bool $returnRange Return range? (see example) * @return mixed */ - public static function extractSheetTitle($pRange, $returnRange = false) { + public static function extractSheetTitle($pRange, $returnRange = false) { // Sheet title included? if (($sep = strpos($pRange, '!')) === false) { return ''; @@ -2782,7 +2774,7 @@ public function getDataValidationCollection() * @param string $range * @return string Adjusted range value */ - public function shrinkRangeToFit($range) { + public function shrinkRangeToFit($range) { $maxCol = $this->getHighestColumn(); $maxRow = $this->getHighestRow(); $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol); @@ -2844,7 +2836,7 @@ public function isTabColorSet() * * @return PHPExcel_Worksheet */ - public function copy() { + public function copy() { $copied = clone $this; return $copied; @@ -2853,7 +2845,7 @@ public function copy() { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() { foreach ($this as $key => $val) { if ($key == '_parent') { continue; @@ -2878,68 +2870,68 @@ public function __clone() { } } /** - * Define the code name of the sheet - * - * @param null|string Same rule as Title minus space not allowed (but, like Excel, change silently space to underscore) - * @return objWorksheet - * @throws PHPExcel_Exception - */ - public function setCodeName($pValue=null){ - // Is this a 'rename' or not? - if ($this->getCodeName() == $pValue) { - return $this; - } - $pValue = str_replace(' ', '_', $pValue);//Excel does this automatically without flinching, we are doing the same - // Syntax check + * Define the code name of the sheet + * + * @param null|string Same rule as Title minus space not allowed (but, like Excel, change silently space to underscore) + * @return objWorksheet + * @throws PHPExcel_Exception + */ + public function setCodeName($pValue=null){ + // Is this a 'rename' or not? + if ($this->getCodeName() == $pValue) { + return $this; + } + $pValue = str_replace(' ', '_', $pValue);//Excel does this automatically without flinching, we are doing the same + // Syntax check // throw an exception if not valid - self::_checkSheetCodeName($pValue); + self::_checkSheetCodeName($pValue); - // We use the same code that setTitle to find a valid codeName else not using a space (Excel don't like) but a '_' - + // We use the same code that setTitle to find a valid codeName else not using a space (Excel don't like) but a '_' + if ($this->getParent()) { - // Is there already such sheet name? - if ($this->getParent()->sheetCodeNameExists($pValue)) { - // Use name, but append with lowest possible integer - - if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); - } - $i = 1; - while ($this->getParent()->sheetCodeNameExists($pValue . '_' . $i)) { - ++$i; - if ($i == 10) { - if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); - } - } elseif ($i == 100) { - if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); - } - } - } - - $pValue = $pValue . '_' . $i;// ok, we have a valid name - //codeName is'nt used in formula : no need to call for an update - //return $this->setTitle($altTitle,$updateFormulaCellReferences); - } - } - - $this->_codeName=$pValue; - return $this; - } - /** - * Return the code name of the sheet - * - * @return null|string - */ - public function getCodeName(){ - return $this->_codeName; - } - /** - * Sheet has a code name ? - * @return boolean - */ - public function hasCodeName(){ - return !(is_null($this->_codeName)); - } + // Is there already such sheet name? + if ($this->getParent()->sheetCodeNameExists($pValue)) { + // Use name, but append with lowest possible integer + + if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); + } + $i = 1; + while ($this->getParent()->sheetCodeNameExists($pValue . '_' . $i)) { + ++$i; + if ($i == 10) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); + } + } elseif ($i == 100) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); + } + } + } + + $pValue = $pValue . '_' . $i;// ok, we have a valid name + //codeName is'nt used in formula : no need to call for an update + //return $this->setTitle($altTitle,$updateFormulaCellReferences); + } + } + + $this->_codeName=$pValue; + return $this; + } + /** + * Return the code name of the sheet + * + * @return null|string + */ + public function getCodeName(){ + return $this->_codeName; + } + /** + * Sheet has a code name ? + * @return boolean + */ + public function hasCodeName(){ + return !(is_null($this->_codeName)); + } } diff --git a/Classes/PHPExcel/Writer/Abstract.php b/Classes/PHPExcel/Writer/Abstract.php index c064722cf..911dc5dda 100644 --- a/Classes/PHPExcel/Writer/Abstract.php +++ b/Classes/PHPExcel/Writer/Abstract.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Abstract * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,138 +22,130 @@ * @category PHPExcel * @package PHPExcel_Writer * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Abstract - * - * @category PHPExcel - * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { - /** - * Write charts that are defined in the workbook? - * Identifies whether the Writer should write definitions for any charts that exist in the PHPExcel object; - * - * @var boolean - */ - protected $_includeCharts = FALSE; + /** + * Write charts that are defined in the workbook? + * Identifies whether the Writer should write definitions for any charts that exist in the PHPExcel object; + * + * @var boolean + */ + protected $_includeCharts = false; - /** - * Pre-calculate formulas - * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are - * immediately available to MS Excel or other office spreadsheet viewer when opening the file - * - * @var boolean - */ - protected $_preCalculateFormulas = TRUE; + /** + * Pre-calculate formulas + * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are + * immediately available to MS Excel or other office spreadsheet viewer when opening the file + * + * @var boolean + */ + protected $_preCalculateFormulas = true; - /** - * Use disk caching where possible? - * - * @var boolean - */ - protected $_useDiskCaching = FALSE; + /** + * Use disk caching where possible? + * + * @var boolean + */ + protected $_useDiskCaching = false; - /** - * Disk caching directory - * - * @var string - */ - protected $_diskCachingDirectory = './'; + /** + * Disk caching directory + * + * @var string + */ + protected $_diskCachingDirectory = './'; - /** - * Write charts in workbook? - * If this is true, then the Writer will write definitions for any charts that exist in the PHPExcel object. - * If false (the default) it will ignore any charts defined in the PHPExcel object. - * - * @return boolean - */ - public function getIncludeCharts() { - return $this->_includeCharts; - } + /** + * Write charts in workbook? + * If this is true, then the Writer will write definitions for any charts that exist in the PHPExcel object. + * If false (the default) it will ignore any charts defined in the PHPExcel object. + * + * @return boolean + */ + public function getIncludeCharts() { + return $this->_includeCharts; + } - /** - * Set write charts in workbook - * Set to true, to advise the Writer to include any charts that exist in the PHPExcel object. - * Set to false (the default) to ignore charts. - * - * @param boolean $pValue - * @return PHPExcel_Writer_IWriter - */ - public function setIncludeCharts($pValue = FALSE) { - $this->_includeCharts = (boolean) $pValue; - return $this; - } + /** + * Set write charts in workbook + * Set to true, to advise the Writer to include any charts that exist in the PHPExcel object. + * Set to false (the default) to ignore charts. + * + * @param boolean $pValue + * @return PHPExcel_Writer_IWriter + */ + public function setIncludeCharts($pValue = false) + { + $this->_includeCharts = (boolean) $pValue; + return $this; + } /** * Get Pre-Calculate Formulas flag - * If this is true (the default), then the writer will recalculate all formulae in a workbook when saving, - * so that the pre-calculated values are immediately available to MS Excel or other office spreadsheet - * viewer when opening the file - * If false, then formulae are not calculated on save. This is faster for saving in PHPExcel, but slower - * when opening the resulting file in MS Excel, because Excel has to recalculate the formulae itself + * If this is true (the default), then the writer will recalculate all formulae in a workbook when saving, + * so that the pre-calculated values are immediately available to MS Excel or other office spreadsheet + * viewer when opening the file + * If false, then formulae are not calculated on save. This is faster for saving in PHPExcel, but slower + * when opening the resulting file in MS Excel, because Excel has to recalculate the formulae itself * * @return boolean */ public function getPreCalculateFormulas() { - return $this->_preCalculateFormulas; + return $this->_preCalculateFormulas; } /** * Set Pre-Calculate Formulas - * Set to true (the default) to advise the Writer to calculate all formulae on save - * Set to false to prevent precalculation of formulae on save. + * Set to true (the default) to advise the Writer to calculate all formulae on save + * Set to false to prevent precalculation of formulae on save. * - * @param boolean $pValue Pre-Calculate Formulas? - * @return PHPExcel_Writer_IWriter + * @param boolean $pValue Pre-Calculate Formulas? + * @return PHPExcel_Writer_IWriter */ public function setPreCalculateFormulas($pValue = TRUE) { - $this->_preCalculateFormulas = (boolean) $pValue; - return $this; + $this->_preCalculateFormulas = (boolean) $pValue; + return $this; } - /** - * Get use disk caching where possible? - * - * @return boolean - */ - public function getUseDiskCaching() { - return $this->_useDiskCaching; - } + /** + * Get use disk caching where possible? + * + * @return boolean + */ + public function getUseDiskCaching() { + return $this->_useDiskCaching; + } - /** - * Set use disk caching where possible? - * - * @param boolean $pValue - * @param string $pDirectory Disk caching directory - * @throws PHPExcel_Writer_Exception when directory does not exist - * @return PHPExcel_Writer_Excel2007 - */ - public function setUseDiskCaching($pValue = FALSE, $pDirectory = NULL) { - $this->_useDiskCaching = $pValue; + /** + * Set use disk caching where possible? + * + * @param boolean $pValue + * @param string $pDirectory Disk caching directory + * @throws PHPExcel_Writer_Exception when directory does not exist + * @return PHPExcel_Writer_Excel2007 + */ + public function setUseDiskCaching($pValue = FALSE, $pDirectory = NULL) { + $this->_useDiskCaching = $pValue; - if ($pDirectory !== NULL) { - if (is_dir($pDirectory)) { - $this->_diskCachingDirectory = $pDirectory; - } else { - throw new PHPExcel_Writer_Exception("Directory does not exist: $pDirectory"); - } - } - return $this; - } + if ($pDirectory !== NULL) { + if (is_dir($pDirectory)) { + $this->_diskCachingDirectory = $pDirectory; + } else { + throw new PHPExcel_Writer_Exception("Directory does not exist: $pDirectory"); + } + } + return $this; + } - /** - * Get disk caching directory - * - * @return string - */ - public function getDiskCachingDirectory() { - return $this->_diskCachingDirectory; - } + /** + * Get disk caching directory + * + * @return string + */ + public function getDiskCachingDirectory() { + return $this->_diskCachingDirectory; + } } diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php index b81270d64..74cbc1a16 100644 --- a/Classes/PHPExcel/Writer/CSV.php +++ b/Classes/PHPExcel/Writer/CSV.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_CSV * * Copyright (c) 2006 - 2015 PHPExcel * @@ -19,292 +20,286 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category PHPExcel - * @package PHPExcel_Writer_CSV - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_Writer_CSV - * - * @category PHPExcel - * @package PHPExcel_Writer_CSV + * @package PHPExcel_Writer_CSV * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ -class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { - /** - * PHPExcel object - * - * @var PHPExcel - */ - private $_phpExcel; - - /** - * Delimiter - * - * @var string - */ - private $_delimiter = ','; - - /** - * Enclosure - * - * @var string - */ - private $_enclosure = '"'; - - /** - * Line ending - * - * @var string - */ - private $_lineEnding = PHP_EOL; - - /** - * Sheet index to write - * - * @var int - */ - private $_sheetIndex = 0; - - /** - * Whether to write a BOM (for UTF8). - * - * @var boolean - */ - private $_useBOM = false; - - /** - * Whether to write a fully Excel compatible CSV file. - * - * @var boolean - */ - private $_excelCompatibility = false; - - /** - * Create a new PHPExcel_Writer_CSV - * - * @param PHPExcel $phpExcel PHPExcel object - */ - public function __construct(PHPExcel $phpExcel) { - $this->_phpExcel = $phpExcel; - } - - /** - * Save PHPExcel to file - * - * @param string $pFilename - * @throws PHPExcel_Writer_Exception - */ - public function save($pFilename = null) { - // Fetch sheet - $sheet = $this->_phpExcel->getSheet($this->_sheetIndex); - - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); - $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); - PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); - - // Open file - $fileHandle = fopen($pFilename, 'wb+'); - if ($fileHandle === false) { - throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); - } - - if ($this->_excelCompatibility) { - fwrite($fileHandle, "\xEF\xBB\xBF"); // Enforce UTF-8 BOM Header - $this->setEnclosure('"'); // Set enclosure to " - $this->setDelimiter(";"); // Set delimiter to a semi-colon +class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter +{ + /** + * PHPExcel object + * + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Delimiter + * + * @var string + */ + private $_delimiter = ','; + + /** + * Enclosure + * + * @var string + */ + private $_enclosure = '"'; + + /** + * Line ending + * + * @var string + */ + private $_lineEnding = PHP_EOL; + + /** + * Sheet index to write + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Whether to write a BOM (for UTF8). + * + * @var boolean + */ + private $_useBOM = false; + + /** + * Whether to write a fully Excel compatible CSV file. + * + * @var boolean + */ + private $_excelCompatibility = false; + + /** + * Create a new PHPExcel_Writer_CSV + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) + { + $this->_phpExcel = $phpExcel; + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) + { + // Fetch sheet + $sheet = $this->_phpExcel->getSheet($this->_sheetIndex); + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); + + // Open file + $fileHandle = fopen($pFilename, 'wb+'); + if ($fileHandle === false) { + throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); + } + + if ($this->_excelCompatibility) { + fwrite($fileHandle, "\xEF\xBB\xBF"); // Enforce UTF-8 BOM Header + $this->setEnclosure('"'); // Set enclosure to " + $this->setDelimiter(";"); // Set delimiter to a semi-colon $this->setLineEnding("\r\n"); - fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->_lineEnding); - } elseif ($this->_useBOM) { - // Write the UTF-8 BOM code if required - fwrite($fileHandle, "\xEF\xBB\xBF"); - } - - // Identify the range that we need to extract from the worksheet - $maxCol = $sheet->getHighestDataColumn(); - $maxRow = $sheet->getHighestDataRow(); - - // Write rows to file - for($row = 1; $row <= $maxRow; ++$row) { - // Convert the row to an array... - $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row,'', $this->_preCalculateFormulas); - // ... and write to the file - $this->_writeLine($fileHandle, $cellsArray[0]); - } - - // Close file - fclose($fileHandle); - - PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); - } - - /** - * Get delimiter - * - * @return string - */ - public function getDelimiter() { - return $this->_delimiter; - } - - /** - * Set delimiter - * - * @param string $pValue Delimiter, defaults to , - * @return PHPExcel_Writer_CSV - */ - public function setDelimiter($pValue = ',') { - $this->_delimiter = $pValue; - return $this; - } - - /** - * Get enclosure - * - * @return string - */ - public function getEnclosure() { - return $this->_enclosure; - } - - /** - * Set enclosure - * - * @param string $pValue Enclosure, defaults to " - * @return PHPExcel_Writer_CSV - */ - public function setEnclosure($pValue = '"') { - if ($pValue == '') { - $pValue = null; - } - $this->_enclosure = $pValue; - return $this; - } - - /** - * Get line ending - * - * @return string - */ - public function getLineEnding() { - return $this->_lineEnding; - } - - /** - * Set line ending - * - * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) - * @return PHPExcel_Writer_CSV - */ - public function setLineEnding($pValue = PHP_EOL) { - $this->_lineEnding = $pValue; - return $this; - } - - /** - * Get whether BOM should be used - * - * @return boolean - */ - public function getUseBOM() { - return $this->_useBOM; - } - - /** - * Set whether BOM should be used - * - * @param boolean $pValue Use UTF-8 byte-order mark? Defaults to false - * @return PHPExcel_Writer_CSV - */ - public function setUseBOM($pValue = false) { - $this->_useBOM = $pValue; - return $this; - } - - /** - * Get whether the file should be saved with full Excel Compatibility - * - * @return boolean - */ - public function getExcelCompatibility() { - return $this->_excelCompatibility; - } - - /** - * Set whether the file should be saved with full Excel Compatibility - * - * @param boolean $pValue Set the file to be written as a fully Excel compatible csv file - * Note that this overrides other settings such as useBOM, enclosure and delimiter - * @return PHPExcel_Writer_CSV - */ - public function setExcelCompatibility($pValue = false) { - $this->_excelCompatibility = $pValue; - return $this; - } - - /** - * Get sheet index - * - * @return int - */ - public function getSheetIndex() { - return $this->_sheetIndex; - } - - /** - * Set sheet index - * - * @param int $pValue Sheet index - * @return PHPExcel_Writer_CSV - */ - public function setSheetIndex($pValue = 0) { - $this->_sheetIndex = $pValue; - return $this; - } - - /** - * Write line to CSV file - * - * @param mixed $pFileHandle PHP filehandle - * @param array $pValues Array containing values in a row - * @throws PHPExcel_Writer_Exception - */ - private function _writeLine($pFileHandle = null, $pValues = null) { - if (is_array($pValues)) { - // No leading delimiter - $writeDelimiter = false; - - // Build the line - $line = ''; - - foreach ($pValues as $element) { - // Escape enclosures - $element = str_replace($this->_enclosure, $this->_enclosure . $this->_enclosure, $element); - - // Add delimiter - if ($writeDelimiter) { - $line .= $this->_delimiter; - } else { - $writeDelimiter = true; - } - - // Add enclosed string - $line .= $this->_enclosure . $element . $this->_enclosure; - } - - // Add line ending - $line .= $this->_lineEnding; - - // Write to file + fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->_lineEnding); + } elseif ($this->_useBOM) { + // Write the UTF-8 BOM code if required + fwrite($fileHandle, "\xEF\xBB\xBF"); + } + + // Identify the range that we need to extract from the worksheet + $maxCol = $sheet->getHighestDataColumn(); + $maxRow = $sheet->getHighestDataRow(); + + // Write rows to file + for($row = 1; $row <= $maxRow; ++$row) { + // Convert the row to an array... + $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row,'', $this->_preCalculateFormulas); + // ... and write to the file + $this->_writeLine($fileHandle, $cellsArray[0]); + } + + // Close file + fclose($fileHandle); + + PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + } + + /** + * Get delimiter + * + * @return string + */ + public function getDelimiter() { + return $this->_delimiter; + } + + /** + * Set delimiter + * + * @param string $pValue Delimiter, defaults to , + * @return PHPExcel_Writer_CSV + */ + public function setDelimiter($pValue = ',') { + $this->_delimiter = $pValue; + return $this; + } + + /** + * Get enclosure + * + * @return string + */ + public function getEnclosure() { + return $this->_enclosure; + } + + /** + * Set enclosure + * + * @param string $pValue Enclosure, defaults to " + * @return PHPExcel_Writer_CSV + */ + public function setEnclosure($pValue = '"') { + if ($pValue == '') { + $pValue = null; + } + $this->_enclosure = $pValue; + return $this; + } + + /** + * Get line ending + * + * @return string + */ + public function getLineEnding() { + return $this->_lineEnding; + } + + /** + * Set line ending + * + * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) + * @return PHPExcel_Writer_CSV + */ + public function setLineEnding($pValue = PHP_EOL) { + $this->_lineEnding = $pValue; + return $this; + } + + /** + * Get whether BOM should be used + * + * @return boolean + */ + public function getUseBOM() { + return $this->_useBOM; + } + + /** + * Set whether BOM should be used + * + * @param boolean $pValue Use UTF-8 byte-order mark? Defaults to false + * @return PHPExcel_Writer_CSV + */ + public function setUseBOM($pValue = false) { + $this->_useBOM = $pValue; + return $this; + } + + /** + * Get whether the file should be saved with full Excel Compatibility + * + * @return boolean + */ + public function getExcelCompatibility() { + return $this->_excelCompatibility; + } + + /** + * Set whether the file should be saved with full Excel Compatibility + * + * @param boolean $pValue Set the file to be written as a fully Excel compatible csv file + * Note that this overrides other settings such as useBOM, enclosure and delimiter + * @return PHPExcel_Writer_CSV + */ + public function setExcelCompatibility($pValue = false) { + $this->_excelCompatibility = $pValue; + return $this; + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Writer_CSV + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + + /** + * Write line to CSV file + * + * @param mixed $pFileHandle PHP filehandle + * @param array $pValues Array containing values in a row + * @throws PHPExcel_Writer_Exception + */ + private function _writeLine($pFileHandle = null, $pValues = null) { + if (is_array($pValues)) { + // No leading delimiter + $writeDelimiter = false; + + // Build the line + $line = ''; + + foreach ($pValues as $element) { + // Escape enclosures + $element = str_replace($this->_enclosure, $this->_enclosure . $this->_enclosure, $element); + + // Add delimiter + if ($writeDelimiter) { + $line .= $this->_delimiter; + } else { + $writeDelimiter = true; + } + + // Add enclosed string + $line .= $this->_enclosure . $element . $this->_enclosure; + } + + // Add line ending + $line .= $this->_lineEnding; + + // Write to file fwrite($pFileHandle, $line); - } else { - throw new PHPExcel_Writer_Exception("Invalid data row passed to CSV writer."); - } - } + } else { + throw new PHPExcel_Writer_Exception("Invalid data row passed to CSV writer."); + } + } } diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index a3abe16ab..6a2be44c5 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007 * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,421 +22,412 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007 - * - * @category PHPExcel - * @package PHPExcel_Writer_2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { - /** - * Pre-calculate formulas - * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are - * immediately available to MS Excel or other office spreadsheet viewer when opening the file - * + /** + * Pre-calculate formulas + * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are + * immediately available to MS Excel or other office spreadsheet viewer when opening the file + * * Overrides the default TRUE for this specific writer for performance reasons * - * @var boolean - */ - protected $_preCalculateFormulas = FALSE; - - /** - * Office2003 compatibility - * - * @var boolean - */ - private $_office2003compatibility = false; - - /** - * Private writer parts - * - * @var PHPExcel_Writer_Excel2007_WriterPart[] - */ - private $_writerParts = array(); - - /** - * Private PHPExcel - * - * @var PHPExcel - */ - private $_spreadSheet; - - /** - * Private string table - * - * @var string[] - */ - private $_stringTable = array(); - - /** - * Private unique PHPExcel_Style_Conditional HashTable - * - * @var PHPExcel_HashTable - */ - private $_stylesConditionalHashTable; - - /** - * Private unique PHPExcel_Style HashTable - * - * @var PHPExcel_HashTable - */ - private $_styleHashTable; - - /** - * Private unique PHPExcel_Style_Fill HashTable - * - * @var PHPExcel_HashTable - */ - private $_fillHashTable; - - /** - * Private unique PHPExcel_Style_Font HashTable - * - * @var PHPExcel_HashTable - */ - private $_fontHashTable; - - /** - * Private unique PHPExcel_Style_Borders HashTable - * - * @var PHPExcel_HashTable - */ - private $_bordersHashTable ; - - /** - * Private unique PHPExcel_Style_NumberFormat HashTable - * - * @var PHPExcel_HashTable - */ - private $_numFmtHashTable; - - /** - * Private unique PHPExcel_Worksheet_BaseDrawing HashTable - * - * @var PHPExcel_HashTable - */ - private $_drawingHashTable; + * @var boolean + */ + protected $_preCalculateFormulas = false; + + /** + * Office2003 compatibility + * + * @var boolean + */ + private $_office2003compatibility = false; + + /** + * Private writer parts + * + * @var PHPExcel_Writer_Excel2007_WriterPart[] + */ + private $_writerParts = array(); + + /** + * Private PHPExcel + * + * @var PHPExcel + */ + private $_spreadSheet; + + /** + * Private string table + * + * @var string[] + */ + private $_stringTable = array(); + + /** + * Private unique PHPExcel_Style_Conditional HashTable + * + * @var PHPExcel_HashTable + */ + private $_stylesConditionalHashTable; + + /** + * Private unique PHPExcel_Style HashTable + * + * @var PHPExcel_HashTable + */ + private $_styleHashTable; + + /** + * Private unique PHPExcel_Style_Fill HashTable + * + * @var PHPExcel_HashTable + */ + private $_fillHashTable; + + /** + * Private unique PHPExcel_Style_Font HashTable + * + * @var PHPExcel_HashTable + */ + private $_fontHashTable; + + /** + * Private unique PHPExcel_Style_Borders HashTable + * + * @var PHPExcel_HashTable + */ + private $_bordersHashTable ; + + /** + * Private unique PHPExcel_Style_NumberFormat HashTable + * + * @var PHPExcel_HashTable + */ + private $_numFmtHashTable; + + /** + * Private unique PHPExcel_Worksheet_BaseDrawing HashTable + * + * @var PHPExcel_HashTable + */ + private $_drawingHashTable; /** * Create a new PHPExcel_Writer_Excel2007 * - * @param PHPExcel $pPHPExcel + * @param PHPExcel $pPHPExcel */ public function __construct(PHPExcel $pPHPExcel = null) { - // Assign PHPExcel - $this->setPHPExcel($pPHPExcel); - - $writerPartsArray = array( 'stringtable' => 'PHPExcel_Writer_Excel2007_StringTable', - 'contenttypes' => 'PHPExcel_Writer_Excel2007_ContentTypes', - 'docprops' => 'PHPExcel_Writer_Excel2007_DocProps', - 'rels' => 'PHPExcel_Writer_Excel2007_Rels', - 'theme' => 'PHPExcel_Writer_Excel2007_Theme', - 'style' => 'PHPExcel_Writer_Excel2007_Style', - 'workbook' => 'PHPExcel_Writer_Excel2007_Workbook', - 'worksheet' => 'PHPExcel_Writer_Excel2007_Worksheet', - 'drawing' => 'PHPExcel_Writer_Excel2007_Drawing', - 'comments' => 'PHPExcel_Writer_Excel2007_Comments', - 'chart' => 'PHPExcel_Writer_Excel2007_Chart', - 'relsvba' => 'PHPExcel_Writer_Excel2007_RelsVBA', - 'relsribbonobjects' => 'PHPExcel_Writer_Excel2007_RelsRibbon' - ); - - // Initialise writer parts - // and Assign their parent IWriters - foreach ($writerPartsArray as $writer => $class) { - $this->_writerParts[$writer] = new $class($this); - } - - $hashTablesArray = array( '_stylesConditionalHashTable', '_fillHashTable', '_fontHashTable', - '_bordersHashTable', '_numFmtHashTable', '_drawingHashTable', + // Assign PHPExcel + $this->setPHPExcel($pPHPExcel); + + $writerPartsArray = array( 'stringtable' => 'PHPExcel_Writer_Excel2007_StringTable', + 'contenttypes' => 'PHPExcel_Writer_Excel2007_ContentTypes', + 'docprops' => 'PHPExcel_Writer_Excel2007_DocProps', + 'rels' => 'PHPExcel_Writer_Excel2007_Rels', + 'theme' => 'PHPExcel_Writer_Excel2007_Theme', + 'style' => 'PHPExcel_Writer_Excel2007_Style', + 'workbook' => 'PHPExcel_Writer_Excel2007_Workbook', + 'worksheet' => 'PHPExcel_Writer_Excel2007_Worksheet', + 'drawing' => 'PHPExcel_Writer_Excel2007_Drawing', + 'comments' => 'PHPExcel_Writer_Excel2007_Comments', + 'chart' => 'PHPExcel_Writer_Excel2007_Chart', + 'relsvba' => 'PHPExcel_Writer_Excel2007_RelsVBA', + 'relsribbonobjects' => 'PHPExcel_Writer_Excel2007_RelsRibbon' + ); + + // Initialise writer parts + // and Assign their parent IWriters + foreach ($writerPartsArray as $writer => $class) { + $this->_writerParts[$writer] = new $class($this); + } + + $hashTablesArray = array( '_stylesConditionalHashTable', '_fillHashTable', '_fontHashTable', + '_bordersHashTable', '_numFmtHashTable', '_drawingHashTable', '_styleHashTable' - ); + ); - // Set HashTable variables - foreach ($hashTablesArray as $tableName) { - $this->$tableName = new PHPExcel_HashTable(); - } + // Set HashTable variables + foreach ($hashTablesArray as $tableName) { + $this->$tableName = new PHPExcel_HashTable(); + } } - /** - * Get writer part - * - * @param string $pPartName Writer part name - * @return PHPExcel_Writer_Excel2007_WriterPart - */ - public function getWriterPart($pPartName = '') { - if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) { - return $this->_writerParts[strtolower($pPartName)]; - } else { - return null; - } - } - - /** - * Save PHPExcel to file - * - * @param string $pFilename - * @throws PHPExcel_Writer_Exception - */ - public function save($pFilename = null) - { - if ($this->_spreadSheet !== NULL) { - // garbage collect - $this->_spreadSheet->garbageCollect(); - - // If $pFilename is php://output or php://stdout, make it a temporary file... - $originalFilename = $pFilename; - if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') { - $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp'); - if ($pFilename == '') { - $pFilename = $originalFilename; - } - } - - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(FALSE); - $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - - // Create string lookup table - $this->_stringTable = array(); - for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { - $this->_stringTable = $this->getWriterPart('StringTable')->createStringTable($this->_spreadSheet->getSheet($i), $this->_stringTable); - } - - // Create styles dictionaries - $this->_styleHashTable->addFromSource( $this->getWriterPart('Style')->allStyles($this->_spreadSheet) ); - $this->_stylesConditionalHashTable->addFromSource( $this->getWriterPart('Style')->allConditionalStyles($this->_spreadSheet) ); - $this->_fillHashTable->addFromSource( $this->getWriterPart('Style')->allFills($this->_spreadSheet) ); - $this->_fontHashTable->addFromSource( $this->getWriterPart('Style')->allFonts($this->_spreadSheet) ); - $this->_bordersHashTable->addFromSource( $this->getWriterPart('Style')->allBorders($this->_spreadSheet) ); - $this->_numFmtHashTable->addFromSource( $this->getWriterPart('Style')->allNumberFormats($this->_spreadSheet) ); - - // Create drawing dictionary - $this->_drawingHashTable->addFromSource( $this->getWriterPart('Drawing')->allDrawings($this->_spreadSheet) ); - - // Create new ZIP file and open it for writing - $zipClass = PHPExcel_Settings::getZipClass(); - $objZip = new $zipClass(); - - // Retrieve OVERWRITE and CREATE constants from the instantiated zip class - // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP - $ro = new ReflectionObject($objZip); - $zipOverWrite = $ro->getConstant('OVERWRITE'); - $zipCreate = $ro->getConstant('CREATE'); - - if (file_exists($pFilename)) { - unlink($pFilename); - } - // Try opening the ZIP file - if ($objZip->open($pFilename, $zipOverWrite) !== true) { - if ($objZip->open($pFilename, $zipCreate) !== true) { - throw new PHPExcel_Writer_Exception("Could not open " . $pFilename . " for writing."); - } - } - - // Add [Content_Types].xml to ZIP file - $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->_includeCharts)); - - //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) - if($this->_spreadSheet->hasMacros()){ - $macrosCode=$this->_spreadSheet->getMacrosCode(); - if(!is_null($macrosCode)){// we have the code ? - $objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin - if($this->_spreadSheet->hasMacrosCertificate()){//signed macros ? - // Yes : add the certificate file and the related rels file - $objZip->addFromString('xl/vbaProjectSignature.bin', $this->_spreadSheet->getMacrosCertificate()); - $objZip->addFromString('xl/_rels/vbaProject.bin.rels', - $this->getWriterPart('RelsVBA')->writeVBARelationships($this->_spreadSheet)); - } - } - } - //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) - if($this->_spreadSheet->hasRibbon()){ - $tmpRibbonTarget=$this->_spreadSheet->getRibbonXMLData('target'); - $objZip->addFromString($tmpRibbonTarget, $this->_spreadSheet->getRibbonXMLData('data')); - if($this->_spreadSheet->hasRibbonBinObjects()){ - $tmpRootPath=dirname($tmpRibbonTarget).'/'; - $ribbonBinObjects=$this->_spreadSheet->getRibbonBinObjects('data');//the files to write - foreach($ribbonBinObjects as $aPath=>$aContent){ - $objZip->addFromString($tmpRootPath.$aPath, $aContent); - } - //the rels for files - $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', - $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->_spreadSheet)); - } - } - - // Add relationships to ZIP file - $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->_spreadSheet)); - $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->_spreadSheet)); - - // Add document properties to ZIP file - $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->_spreadSheet)); - $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->_spreadSheet)); - $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->_spreadSheet); - if ($customPropertiesPart !== NULL) { - $objZip->addFromString('docProps/custom.xml', $customPropertiesPart); - } - - // Add theme to ZIP file - $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->_spreadSheet)); - - // Add string table to ZIP file - $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->_stringTable)); - - // Add styles to ZIP file - $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->_spreadSheet)); - - // Add workbook to ZIP file - $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->_spreadSheet, $this->_preCalculateFormulas)); - - $chartCount = 0; - // Add worksheets - for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { - $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->_spreadSheet->getSheet($i), $this->_stringTable, $this->_includeCharts)); - if ($this->_includeCharts) { - $charts = $this->_spreadSheet->getSheet($i)->getChartCollection(); - if (count($charts) > 0) { - foreach($charts as $chart) { - $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart)); - $chartCount++; - } - } - } - } - - $chartRef1 = $chartRef2 = 0; - // Add worksheet relationships (drawings, ...) - for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { - - // Add relationships - $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->_spreadSheet->getSheet($i), ($i + 1), $this->_includeCharts)); - - $drawings = $this->_spreadSheet->getSheet($i)->getDrawingCollection(); - $drawingCount = count($drawings); - if ($this->_includeCharts) { - $chartCount = $this->_spreadSheet->getSheet($i)->getChartCount(); - } - - // Add drawing and image relationship parts - if (($drawingCount > 0) || ($chartCount > 0)) { - // Drawing relationships - $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->_spreadSheet->getSheet($i),$chartRef1, $this->_includeCharts)); - - // Drawings - $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->_spreadSheet->getSheet($i),$chartRef2,$this->_includeCharts)); - } - - // Add comment relationship parts - if (count($this->_spreadSheet->getSheet($i)->getComments()) > 0) { - // VML Comments - $objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->_spreadSheet->getSheet($i))); - - // Comments - $objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->_spreadSheet->getSheet($i))); - } - - // Add header/footer relationship parts - if (count($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { - // VML Drawings - $objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->_spreadSheet->getSheet($i))); - - // VML Drawing relationships - $objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->_spreadSheet->getSheet($i))); - - // Media - foreach ($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) { - $objZip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath())); - } - } - } - - // Add media - for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) { - if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { - $imageContents = null; - $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath(); - if (strpos($imagePath, 'zip://') !== false) { - $imagePath = substr($imagePath, 6); - $imagePathSplitted = explode('#', $imagePath); - - $imageZip = new ZipArchive(); - $imageZip->open($imagePathSplitted[0]); - $imageContents = $imageZip->getFromName($imagePathSplitted[1]); - $imageZip->close(); - unset($imageZip); - } else { - $imageContents = file_get_contents($imagePath); - } - - $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); - } else if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { - ob_start(); - call_user_func( - $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(), - $this->getDrawingHashTable()->getByIndex($i)->getImageResource() - ); - $imageContents = ob_get_contents(); - ob_end_clean(); - - $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); - } - } - - PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); - PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); - - // Close file - if ($objZip->close() === false) { - throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename."); - } - - // If a temporary file was used, copy it to the correct file stream - if ($originalFilename != $pFilename) { - if (copy($pFilename, $originalFilename) === false) { - throw new PHPExcel_Writer_Exception("Could not copy temporary zip file $pFilename to $originalFilename."); - } - @unlink($pFilename); - } - } else { - throw new PHPExcel_Writer_Exception("PHPExcel object unassigned."); - } - } - - /** - * Get PHPExcel object - * - * @return PHPExcel - * @throws PHPExcel_Writer_Exception - */ - public function getPHPExcel() { - if ($this->_spreadSheet !== null) { - return $this->_spreadSheet; - } else { - throw new PHPExcel_Writer_Exception("No PHPExcel assigned."); - } - } - - /** - * Set PHPExcel object - * - * @param PHPExcel $pPHPExcel PHPExcel object - * @throws PHPExcel_Writer_Exception - * @return PHPExcel_Writer_Excel2007 - */ - public function setPHPExcel(PHPExcel $pPHPExcel = null) { - $this->_spreadSheet = $pPHPExcel; - return $this; - } + /** + * Get writer part + * + * @param string $pPartName Writer part name + * @return PHPExcel_Writer_Excel2007_WriterPart + */ + public function getWriterPart($pPartName = '') { + if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) { + return $this->_writerParts[strtolower($pPartName)]; + } else { + return null; + } + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) + { + if ($this->_spreadSheet !== NULL) { + // garbage collect + $this->_spreadSheet->garbageCollect(); + + // If $pFilename is php://output or php://stdout, make it a temporary file... + $originalFilename = $pFilename; + if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') { + $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp'); + if ($pFilename == '') { + $pFilename = $originalFilename; + } + } + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(FALSE); + $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + + // Create string lookup table + $this->_stringTable = array(); + for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { + $this->_stringTable = $this->getWriterPart('StringTable')->createStringTable($this->_spreadSheet->getSheet($i), $this->_stringTable); + } + + // Create styles dictionaries + $this->_styleHashTable->addFromSource( $this->getWriterPart('Style')->allStyles($this->_spreadSheet) ); + $this->_stylesConditionalHashTable->addFromSource( $this->getWriterPart('Style')->allConditionalStyles($this->_spreadSheet) ); + $this->_fillHashTable->addFromSource( $this->getWriterPart('Style')->allFills($this->_spreadSheet) ); + $this->_fontHashTable->addFromSource( $this->getWriterPart('Style')->allFonts($this->_spreadSheet) ); + $this->_bordersHashTable->addFromSource( $this->getWriterPart('Style')->allBorders($this->_spreadSheet) ); + $this->_numFmtHashTable->addFromSource( $this->getWriterPart('Style')->allNumberFormats($this->_spreadSheet) ); + + // Create drawing dictionary + $this->_drawingHashTable->addFromSource( $this->getWriterPart('Drawing')->allDrawings($this->_spreadSheet) ); + + // Create new ZIP file and open it for writing + $zipClass = PHPExcel_Settings::getZipClass(); + $objZip = new $zipClass(); + + // Retrieve OVERWRITE and CREATE constants from the instantiated zip class + // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP + $ro = new ReflectionObject($objZip); + $zipOverWrite = $ro->getConstant('OVERWRITE'); + $zipCreate = $ro->getConstant('CREATE'); + + if (file_exists($pFilename)) { + unlink($pFilename); + } + // Try opening the ZIP file + if ($objZip->open($pFilename, $zipOverWrite) !== true) { + if ($objZip->open($pFilename, $zipCreate) !== true) { + throw new PHPExcel_Writer_Exception("Could not open " . $pFilename . " for writing."); + } + } + + // Add [Content_Types].xml to ZIP file + $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->_includeCharts)); + + //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) + if($this->_spreadSheet->hasMacros()){ + $macrosCode=$this->_spreadSheet->getMacrosCode(); + if(!is_null($macrosCode)){// we have the code ? + $objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin + if($this->_spreadSheet->hasMacrosCertificate()){//signed macros ? + // Yes : add the certificate file and the related rels file + $objZip->addFromString('xl/vbaProjectSignature.bin', $this->_spreadSheet->getMacrosCertificate()); + $objZip->addFromString('xl/_rels/vbaProject.bin.rels', + $this->getWriterPart('RelsVBA')->writeVBARelationships($this->_spreadSheet)); + } + } + } + //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) + if($this->_spreadSheet->hasRibbon()){ + $tmpRibbonTarget=$this->_spreadSheet->getRibbonXMLData('target'); + $objZip->addFromString($tmpRibbonTarget, $this->_spreadSheet->getRibbonXMLData('data')); + if($this->_spreadSheet->hasRibbonBinObjects()){ + $tmpRootPath=dirname($tmpRibbonTarget).'/'; + $ribbonBinObjects=$this->_spreadSheet->getRibbonBinObjects('data');//the files to write + foreach($ribbonBinObjects as $aPath=>$aContent){ + $objZip->addFromString($tmpRootPath.$aPath, $aContent); + } + //the rels for files + $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', + $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->_spreadSheet)); + } + } + + // Add relationships to ZIP file + $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->_spreadSheet)); + $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->_spreadSheet)); + + // Add document properties to ZIP file + $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->_spreadSheet)); + $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->_spreadSheet)); + $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->_spreadSheet); + if ($customPropertiesPart !== NULL) { + $objZip->addFromString('docProps/custom.xml', $customPropertiesPart); + } + + // Add theme to ZIP file + $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->_spreadSheet)); + + // Add string table to ZIP file + $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->_stringTable)); + + // Add styles to ZIP file + $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->_spreadSheet)); + + // Add workbook to ZIP file + $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->_spreadSheet, $this->_preCalculateFormulas)); + + $chartCount = 0; + // Add worksheets + for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { + $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->_spreadSheet->getSheet($i), $this->_stringTable, $this->_includeCharts)); + if ($this->_includeCharts) { + $charts = $this->_spreadSheet->getSheet($i)->getChartCollection(); + if (count($charts) > 0) { + foreach($charts as $chart) { + $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart)); + $chartCount++; + } + } + } + } + + $chartRef1 = $chartRef2 = 0; + // Add worksheet relationships (drawings, ...) + for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { + + // Add relationships + $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->_spreadSheet->getSheet($i), ($i + 1), $this->_includeCharts)); + + $drawings = $this->_spreadSheet->getSheet($i)->getDrawingCollection(); + $drawingCount = count($drawings); + if ($this->_includeCharts) { + $chartCount = $this->_spreadSheet->getSheet($i)->getChartCount(); + } + + // Add drawing and image relationship parts + if (($drawingCount > 0) || ($chartCount > 0)) { + // Drawing relationships + $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->_spreadSheet->getSheet($i),$chartRef1, $this->_includeCharts)); + + // Drawings + $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->_spreadSheet->getSheet($i),$chartRef2,$this->_includeCharts)); + } + + // Add comment relationship parts + if (count($this->_spreadSheet->getSheet($i)->getComments()) > 0) { + // VML Comments + $objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->_spreadSheet->getSheet($i))); + + // Comments + $objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->_spreadSheet->getSheet($i))); + } + + // Add header/footer relationship parts + if (count($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { + // VML Drawings + $objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->_spreadSheet->getSheet($i))); + + // VML Drawing relationships + $objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->_spreadSheet->getSheet($i))); + + // Media + foreach ($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) { + $objZip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath())); + } + } + } + + // Add media + for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) { + if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { + $imageContents = null; + $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath(); + if (strpos($imagePath, 'zip://') !== false) { + $imagePath = substr($imagePath, 6); + $imagePathSplitted = explode('#', $imagePath); + + $imageZip = new ZipArchive(); + $imageZip->open($imagePathSplitted[0]); + $imageContents = $imageZip->getFromName($imagePathSplitted[1]); + $imageZip->close(); + unset($imageZip); + } else { + $imageContents = file_get_contents($imagePath); + } + + $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); + } else if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { + ob_start(); + call_user_func( + $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(), + $this->getDrawingHashTable()->getByIndex($i)->getImageResource() + ); + $imageContents = ob_get_contents(); + ob_end_clean(); + + $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); + } + } + + PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); + PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); + + // Close file + if ($objZip->close() === false) { + throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename."); + } + + // If a temporary file was used, copy it to the correct file stream + if ($originalFilename != $pFilename) { + if (copy($pFilename, $originalFilename) === false) { + throw new PHPExcel_Writer_Exception("Could not copy temporary zip file $pFilename to $originalFilename."); + } + @unlink($pFilename); + } + } else { + throw new PHPExcel_Writer_Exception("PHPExcel object unassigned."); + } + } + + /** + * Get PHPExcel object + * + * @return PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function getPHPExcel() { + if ($this->_spreadSheet !== null) { + return $this->_spreadSheet; + } else { + throw new PHPExcel_Writer_Exception("No PHPExcel assigned."); + } + } + + /** + * Set PHPExcel object + * + * @param PHPExcel $pPHPExcel PHPExcel object + * @throws PHPExcel_Writer_Exception + * @return PHPExcel_Writer_Excel2007 + */ + public function setPHPExcel(PHPExcel $pPHPExcel = null) { + $this->_spreadSheet = $pPHPExcel; + return $this; + } /** * Get string table @@ -443,7 +435,7 @@ public function setPHPExcel(PHPExcel $pPHPExcel = null) { * @return string[] */ public function getStringTable() { - return $this->_stringTable; + return $this->_stringTable; } /** @@ -452,7 +444,7 @@ public function getStringTable() { * @return PHPExcel_HashTable */ public function getStyleHashTable() { - return $this->_styleHashTable; + return $this->_styleHashTable; } /** @@ -461,7 +453,7 @@ public function getStyleHashTable() { * @return PHPExcel_HashTable */ public function getStylesConditionalHashTable() { - return $this->_stylesConditionalHashTable; + return $this->_stylesConditionalHashTable; } /** @@ -470,7 +462,7 @@ public function getStylesConditionalHashTable() { * @return PHPExcel_HashTable */ public function getFillHashTable() { - return $this->_fillHashTable; + return $this->_fillHashTable; } /** @@ -479,7 +471,7 @@ public function getFillHashTable() { * @return PHPExcel_HashTable */ public function getFontHashTable() { - return $this->_fontHashTable; + return $this->_fontHashTable; } /** @@ -488,7 +480,7 @@ public function getFontHashTable() { * @return PHPExcel_HashTable */ public function getBordersHashTable() { - return $this->_bordersHashTable; + return $this->_bordersHashTable; } /** @@ -497,7 +489,7 @@ public function getBordersHashTable() { * @return PHPExcel_HashTable */ public function getNumFmtHashTable() { - return $this->_numFmtHashTable; + return $this->_numFmtHashTable; } /** @@ -506,7 +498,7 @@ public function getNumFmtHashTable() { * @return PHPExcel_HashTable */ public function getDrawingHashTable() { - return $this->_drawingHashTable; + return $this->_drawingHashTable; } /** @@ -515,18 +507,18 @@ public function getDrawingHashTable() { * @return boolean */ public function getOffice2003Compatibility() { - return $this->_office2003compatibility; + return $this->_office2003compatibility; } /** * Set Office2003 compatibility * - * @param boolean $pValue Office2003 compatibility? + * @param boolean $pValue Office2003 compatibility? * @return PHPExcel_Writer_Excel2007 */ public function setOffice2003Compatibility($pValue = false) { - $this->_office2003compatibility = $pValue; - return $this; + $this->_office2003compatibility = $pValue; + return $this; } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 91c12bbbf..a610a13ed 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -54,7 +54,7 @@ public function writeChart(PHPExcel_Chart $pChart = NULL) { } else { $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } - // Ensure that data series values are up-to-date before we save + // Ensure that data series values are up-to-date before we save $pChart->refresh(); // XML header @@ -284,7 +284,7 @@ private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, $this->_writeDataLbls($objWriter, $layout); if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) { - // Line only, Line3D can't be smoothed + // Line only, Line3D can't be smoothed $objWriter->startElement('c:smooth'); $objWriter->writeAttribute('val', (integer) $plotGroup->getSmoothLine()); @@ -334,11 +334,11 @@ private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, $objWriter->endElement(); } - // Generate 2 unique numbers to use for axId values - // $id1 = $id2 = rand(10000000,99999999); - // do { - // $id2 = rand(10000000,99999999); - // } while ($id1 == $id2); + // Generate 2 unique numbers to use for axId values + // $id1 = $id2 = rand(10000000,99999999); + // do { + // $id2 = rand(10000000,99999999); + // } while ($id1 == $id2); $id1 = '75091328'; $id2 = '75089408'; @@ -490,7 +490,7 @@ private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAx $caption = $caption[0]; } $objWriter->startElement('a:t'); - // $objWriter->writeAttribute('xml:space', 'preserve'); + // $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption)); $objWriter->endElement(); @@ -840,7 +840,7 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx } $objWriter->startElement('a:t'); - // $objWriter->writeAttribute('xml:space', 'preserve'); + // $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption)); $objWriter->endElement(); @@ -1117,7 +1117,7 @@ private function _writePlotGroup($plotGroup, $objWriter->endElement(); } - // Get these details before the loop, because we can use the count to check for varyColors + // Get these details before the loop, because we can use the count to check for varyColors $plotSeriesOrder = $plotGroup->getPlotOrder(); $plotSeriesCount = count($plotSeriesOrder); @@ -1177,7 +1177,7 @@ private function _writePlotGroup($plotGroup, $objWriter->endElement(); } - // Labels + // Labels $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef); if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) { $objWriter->startElement('c:tx'); @@ -1187,7 +1187,7 @@ private function _writePlotGroup($plotGroup, $objWriter->endElement(); } - // Formatting for the points + // Formatting for the points if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) ) { @@ -1231,7 +1231,7 @@ private function _writePlotGroup($plotGroup, $objWriter->endElement(); } - // Category Labels + // Category Labels $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef); if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) { $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); @@ -1263,7 +1263,7 @@ private function _writePlotGroup($plotGroup, $objWriter->endElement(); } - // Values + // Values if ($plotSeriesValues) { $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries(); diff --git a/Classes/PHPExcel/Writer/Excel2007/Comments.php b/Classes/PHPExcel/Writer/Excel2007/Comments.php index a6faaaa91..177e0faeb 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Comments.php +++ b/Classes/PHPExcel/Writer/Excel2007/Comments.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,234 +35,234 @@ */ class PHPExcel_Writer_Excel2007_Comments extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Write comments to XML format - * - * @param PHPExcel_Worksheet $pWorksheet - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeComments(PHPExcel_Worksheet $pWorksheet = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // Comments cache - $comments = $pWorksheet->getComments(); - - // Authors cache - $authors = array(); - $authorId = 0; - foreach ($comments as $comment) { - if (!isset($authors[$comment->getAuthor()])) { - $authors[$comment->getAuthor()] = $authorId++; - } - } - - // comments - $objWriter->startElement('comments'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); - - // Loop through authors - $objWriter->startElement('authors'); - foreach ($authors as $author => $index) { - $objWriter->writeElement('author', $author); - } - $objWriter->endElement(); - - // Loop through comments - $objWriter->startElement('commentList'); - foreach ($comments as $key => $value) { - $this->_writeComment($objWriter, $key, $value, $authors); - } - $objWriter->endElement(); - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write comment to XML format - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param string $pCellReference Cell reference - * @param PHPExcel_Comment $pComment Comment - * @param array $pAuthors Array of authors - * @throws PHPExcel_Writer_Exception - */ - public function _writeComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null, $pAuthors = null) - { - // comment - $objWriter->startElement('comment'); - $objWriter->writeAttribute('ref', $pCellReference); - $objWriter->writeAttribute('authorId', $pAuthors[$pComment->getAuthor()]); - - // text - $objWriter->startElement('text'); - $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText()); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write VML comments to XML format - * - * @param PHPExcel_Worksheet $pWorksheet - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // Comments cache - $comments = $pWorksheet->getComments(); - - // xml - $objWriter->startElement('xml'); - $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); - $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); - $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); - - // o:shapelayout - $objWriter->startElement('o:shapelayout'); - $objWriter->writeAttribute('v:ext', 'edit'); - - // o:idmap - $objWriter->startElement('o:idmap'); - $objWriter->writeAttribute('v:ext', 'edit'); - $objWriter->writeAttribute('data', '1'); - $objWriter->endElement(); - - $objWriter->endElement(); - - // v:shapetype - $objWriter->startElement('v:shapetype'); - $objWriter->writeAttribute('id', '_x0000_t202'); - $objWriter->writeAttribute('coordsize', '21600,21600'); - $objWriter->writeAttribute('o:spt', '202'); - $objWriter->writeAttribute('path', 'm,l,21600r21600,l21600,xe'); - - // v:stroke - $objWriter->startElement('v:stroke'); - $objWriter->writeAttribute('joinstyle', 'miter'); - $objWriter->endElement(); - - // v:path - $objWriter->startElement('v:path'); - $objWriter->writeAttribute('gradientshapeok', 't'); - $objWriter->writeAttribute('o:connecttype', 'rect'); - $objWriter->endElement(); - - $objWriter->endElement(); - - // Loop through comments - foreach ($comments as $key => $value) { - $this->_writeVMLComment($objWriter, $key, $value); - } - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write VML comment to XML format - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param string $pCellReference Cell reference - * @param PHPExcel_Comment $pComment Comment - * @throws PHPExcel_Writer_Exception - */ - public function _writeVMLComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null) - { - // Metadata - list($column, $row) = PHPExcel_Cell::coordinateFromString($pCellReference); - $column = PHPExcel_Cell::columnIndexFromString($column); - $id = 1024 + $column + $row; - $id = substr($id, 0, 4); - - // v:shape - $objWriter->startElement('v:shape'); - $objWriter->writeAttribute('id', '_x0000_s' . $id); - $objWriter->writeAttribute('type', '#_x0000_t202'); - $objWriter->writeAttribute('style', 'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden')); - $objWriter->writeAttribute('fillcolor', '#' . $pComment->getFillColor()->getRGB()); - $objWriter->writeAttribute('o:insetmode', 'auto'); - - // v:fill - $objWriter->startElement('v:fill'); - $objWriter->writeAttribute('color2', '#' . $pComment->getFillColor()->getRGB()); - $objWriter->endElement(); - - // v:shadow - $objWriter->startElement('v:shadow'); - $objWriter->writeAttribute('on', 't'); - $objWriter->writeAttribute('color', 'black'); - $objWriter->writeAttribute('obscured', 't'); - $objWriter->endElement(); - - // v:path - $objWriter->startElement('v:path'); - $objWriter->writeAttribute('o:connecttype', 'none'); - $objWriter->endElement(); - - // v:textbox - $objWriter->startElement('v:textbox'); - $objWriter->writeAttribute('style', 'mso-direction-alt:auto'); - - // div - $objWriter->startElement('div'); - $objWriter->writeAttribute('style', 'text-align:left'); - $objWriter->endElement(); - - $objWriter->endElement(); - - // x:ClientData - $objWriter->startElement('x:ClientData'); - $objWriter->writeAttribute('ObjectType', 'Note'); - - // x:MoveWithCells - $objWriter->writeElement('x:MoveWithCells', ''); - - // x:SizeWithCells - $objWriter->writeElement('x:SizeWithCells', ''); - - // x:Anchor - //$objWriter->writeElement('x:Anchor', $column . ', 15, ' . ($row - 2) . ', 10, ' . ($column + 4) . ', 15, ' . ($row + 5) . ', 18'); - - // x:AutoFill - $objWriter->writeElement('x:AutoFill', 'False'); - - // x:Row - $objWriter->writeElement('x:Row', ($row - 1)); - - // x:Column - $objWriter->writeElement('x:Column', ($column - 1)); - - $objWriter->endElement(); - - $objWriter->endElement(); - } + /** + * Write comments to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeComments(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Comments cache + $comments = $pWorksheet->getComments(); + + // Authors cache + $authors = array(); + $authorId = 0; + foreach ($comments as $comment) { + if (!isset($authors[$comment->getAuthor()])) { + $authors[$comment->getAuthor()] = $authorId++; + } + } + + // comments + $objWriter->startElement('comments'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + + // Loop through authors + $objWriter->startElement('authors'); + foreach ($authors as $author => $index) { + $objWriter->writeElement('author', $author); + } + $objWriter->endElement(); + + // Loop through comments + $objWriter->startElement('commentList'); + foreach ($comments as $key => $value) { + $this->_writeComment($objWriter, $key, $value, $authors); + } + $objWriter->endElement(); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write comment to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pCellReference Cell reference + * @param PHPExcel_Comment $pComment Comment + * @param array $pAuthors Array of authors + * @throws PHPExcel_Writer_Exception + */ + public function _writeComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null, $pAuthors = null) + { + // comment + $objWriter->startElement('comment'); + $objWriter->writeAttribute('ref', $pCellReference); + $objWriter->writeAttribute('authorId', $pAuthors[$pComment->getAuthor()]); + + // text + $objWriter->startElement('text'); + $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText()); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write VML comments to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Comments cache + $comments = $pWorksheet->getComments(); + + // xml + $objWriter->startElement('xml'); + $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); + $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); + $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); + + // o:shapelayout + $objWriter->startElement('o:shapelayout'); + $objWriter->writeAttribute('v:ext', 'edit'); + + // o:idmap + $objWriter->startElement('o:idmap'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('data', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // v:shapetype + $objWriter->startElement('v:shapetype'); + $objWriter->writeAttribute('id', '_x0000_t202'); + $objWriter->writeAttribute('coordsize', '21600,21600'); + $objWriter->writeAttribute('o:spt', '202'); + $objWriter->writeAttribute('path', 'm,l,21600r21600,l21600,xe'); + + // v:stroke + $objWriter->startElement('v:stroke'); + $objWriter->writeAttribute('joinstyle', 'miter'); + $objWriter->endElement(); + + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('gradientshapeok', 't'); + $objWriter->writeAttribute('o:connecttype', 'rect'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Loop through comments + foreach ($comments as $key => $value) { + $this->_writeVMLComment($objWriter, $key, $value); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write VML comment to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pCellReference Cell reference + * @param PHPExcel_Comment $pComment Comment + * @throws PHPExcel_Writer_Exception + */ + public function _writeVMLComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null) + { + // Metadata + list($column, $row) = PHPExcel_Cell::coordinateFromString($pCellReference); + $column = PHPExcel_Cell::columnIndexFromString($column); + $id = 1024 + $column + $row; + $id = substr($id, 0, 4); + + // v:shape + $objWriter->startElement('v:shape'); + $objWriter->writeAttribute('id', '_x0000_s' . $id); + $objWriter->writeAttribute('type', '#_x0000_t202'); + $objWriter->writeAttribute('style', 'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden')); + $objWriter->writeAttribute('fillcolor', '#' . $pComment->getFillColor()->getRGB()); + $objWriter->writeAttribute('o:insetmode', 'auto'); + + // v:fill + $objWriter->startElement('v:fill'); + $objWriter->writeAttribute('color2', '#' . $pComment->getFillColor()->getRGB()); + $objWriter->endElement(); + + // v:shadow + $objWriter->startElement('v:shadow'); + $objWriter->writeAttribute('on', 't'); + $objWriter->writeAttribute('color', 'black'); + $objWriter->writeAttribute('obscured', 't'); + $objWriter->endElement(); + + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('o:connecttype', 'none'); + $objWriter->endElement(); + + // v:textbox + $objWriter->startElement('v:textbox'); + $objWriter->writeAttribute('style', 'mso-direction-alt:auto'); + + // div + $objWriter->startElement('div'); + $objWriter->writeAttribute('style', 'text-align:left'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // x:ClientData + $objWriter->startElement('x:ClientData'); + $objWriter->writeAttribute('ObjectType', 'Note'); + + // x:MoveWithCells + $objWriter->writeElement('x:MoveWithCells', ''); + + // x:SizeWithCells + $objWriter->writeElement('x:SizeWithCells', ''); + + // x:Anchor + //$objWriter->writeElement('x:Anchor', $column . ', 15, ' . ($row - 2) . ', 10, ' . ($column + 4) . ', 15, ' . ($row + 5) . ', 18'); + + // x:AutoFill + $objWriter->writeElement('x:AutoFill', 'False'); + + // x:Row + $objWriter->writeElement('x:Row', ($row - 1)); + + // x:Column + $objWriter->writeElement('x:Column', ($column - 1)); + + $objWriter->endElement(); + + $objWriter->endElement(); + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php index a410b8549..56ebf0bb3 100644 --- a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php +++ b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,253 +35,253 @@ */ class PHPExcel_Writer_Excel2007_ContentTypes extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Write content types to XML format - * - * @param PHPExcel $pPHPExcel - * @param boolean $includeCharts Flag indicating if we should include drawing details for charts - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = FALSE) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } + /** + * Write content types to XML format + * + * @param PHPExcel $pPHPExcel + * @param boolean $includeCharts Flag indicating if we should include drawing details for charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); - // Types - $objWriter->startElement('Types'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types'); + // Types + $objWriter->startElement('Types'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types'); - // Theme - $this->_writeOverrideContentType( - $objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml' - ); + // Theme + $this->_writeOverrideContentType( + $objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml' + ); - // Styles - $this->_writeOverrideContentType( - $objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml' - ); + // Styles + $this->_writeOverrideContentType( + $objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml' + ); - // Rels - $this->_writeDefaultContentType( - $objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml' - ); + // Rels + $this->_writeDefaultContentType( + $objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml' + ); - // XML - $this->_writeDefaultContentType( - $objWriter, 'xml', 'application/xml' - ); + // XML + $this->_writeDefaultContentType( + $objWriter, 'xml', 'application/xml' + ); - // VML - $this->_writeDefaultContentType( - $objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing' - ); + // VML + $this->_writeDefaultContentType( + $objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing' + ); - // Workbook - if($pPHPExcel->hasMacros()){ //Macros in workbook ? - // Yes : not standard content but "macroEnabled" - $this->_writeOverrideContentType( - $objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml' - ); - //... and define a new type for the VBA project - $this->_writeDefaultContentType( - $objWriter, 'bin', 'application/vnd.ms-office.vbaProject' - ); - if($pPHPExcel->hasMacrosCertificate()){// signed macros ? - // Yes : add needed information - $this->_writeOverrideContentType( - $objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature' - ); - } - }else{// no macros in workbook, so standard type - $this->_writeOverrideContentType( - $objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml' - ); - } + // Workbook + if($pPHPExcel->hasMacros()){ //Macros in workbook ? + // Yes : not standard content but "macroEnabled" + $this->_writeOverrideContentType( + $objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml' + ); + //... and define a new type for the VBA project + $this->_writeDefaultContentType( + $objWriter, 'bin', 'application/vnd.ms-office.vbaProject' + ); + if($pPHPExcel->hasMacrosCertificate()){// signed macros ? + // Yes : add needed information + $this->_writeOverrideContentType( + $objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature' + ); + } + }else{// no macros in workbook, so standard type + $this->_writeOverrideContentType( + $objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml' + ); + } - // DocProps - $this->_writeOverrideContentType( - $objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml' - ); + // DocProps + $this->_writeOverrideContentType( + $objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml' + ); - $this->_writeOverrideContentType( - $objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml' - ); + $this->_writeOverrideContentType( + $objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml' + ); - $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); - if (!empty($customPropertyList)) { - $this->_writeOverrideContentType( - $objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml' - ); - } + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (!empty($customPropertyList)) { + $this->_writeOverrideContentType( + $objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml' + ); + } - // Worksheets - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - $this->_writeOverrideContentType( - $objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml' - ); - } + // Worksheets + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $this->_writeOverrideContentType( + $objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml' + ); + } - // Shared strings - $this->_writeOverrideContentType( - $objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml' - ); + // Shared strings + $this->_writeOverrideContentType( + $objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml' + ); - // Add worksheet relationship content types - $chart = 1; - for ($i = 0; $i < $sheetCount; ++$i) { - $drawings = $pPHPExcel->getSheet($i)->getDrawingCollection(); - $drawingCount = count($drawings); - $chartCount = ($includeCharts) ? $pPHPExcel->getSheet($i)->getChartCount() : 0; + // Add worksheet relationship content types + $chart = 1; + for ($i = 0; $i < $sheetCount; ++$i) { + $drawings = $pPHPExcel->getSheet($i)->getDrawingCollection(); + $drawingCount = count($drawings); + $chartCount = ($includeCharts) ? $pPHPExcel->getSheet($i)->getChartCount() : 0; - // We need a drawing relationship for the worksheet if we have either drawings or charts - if (($drawingCount > 0) || ($chartCount > 0)) { - $this->_writeOverrideContentType( - $objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml' - ); - } + // We need a drawing relationship for the worksheet if we have either drawings or charts + if (($drawingCount > 0) || ($chartCount > 0)) { + $this->_writeOverrideContentType( + $objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml' + ); + } - // If we have charts, then we need a chart relationship for every individual chart - if ($chartCount > 0) { - for ($c = 0; $c < $chartCount; ++$c) { - $this->_writeOverrideContentType( - $objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml' - ); - } - } - } + // If we have charts, then we need a chart relationship for every individual chart + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeOverrideContentType( + $objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml' + ); + } + } + } - // Comments - for ($i = 0; $i < $sheetCount; ++$i) { - if (count($pPHPExcel->getSheet($i)->getComments()) > 0) { - $this->_writeOverrideContentType( - $objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml' - ); - } - } + // Comments + for ($i = 0; $i < $sheetCount; ++$i) { + if (count($pPHPExcel->getSheet($i)->getComments()) > 0) { + $this->_writeOverrideContentType( + $objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml' + ); + } + } - // Add media content-types - $aMediaContentTypes = array(); - $mediaCount = $this->getParentWriter()->getDrawingHashTable()->count(); - for ($i = 0; $i < $mediaCount; ++$i) { - $extension = ''; - $mimeType = ''; + // Add media content-types + $aMediaContentTypes = array(); + $mediaCount = $this->getParentWriter()->getDrawingHashTable()->count(); + for ($i = 0; $i < $mediaCount; ++$i) { + $extension = ''; + $mimeType = ''; - if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { - $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); - $mimeType = $this->_getImageMimeType( $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath() ); - } else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { - $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); - $extension = explode('/', $extension); - $extension = $extension[1]; + if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { + $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); + $mimeType = $this->_getImageMimeType( $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath() ); + } else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { + $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); + $extension = explode('/', $extension); + $extension = $extension[1]; - $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType(); - } + $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType(); + } - if (!isset( $aMediaContentTypes[$extension]) ) { - $aMediaContentTypes[$extension] = $mimeType; + if (!isset( $aMediaContentTypes[$extension]) ) { + $aMediaContentTypes[$extension] = $mimeType; - $this->_writeDefaultContentType( - $objWriter, $extension, $mimeType - ); - } - } - if($pPHPExcel->hasRibbonBinObjects()){//Some additional objects in the ribbon ? - //we need to write "Extension" but not already write for media content - $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); - foreach($tabRibbonTypes as $aRibbonType){ - $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor - $this->_writeDefaultContentType( - $objWriter, $aRibbonType, $mimeType - ); - } - } - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) { - foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) { - if (!isset( $aMediaContentTypes[strtolower($image->getExtension())]) ) { - $aMediaContentTypes[strtolower($image->getExtension())] = $this->_getImageMimeType( $image->getPath() ); + $this->_writeDefaultContentType( + $objWriter, $extension, $mimeType + ); + } + } + if($pPHPExcel->hasRibbonBinObjects()){//Some additional objects in the ribbon ? + //we need to write "Extension" but not already write for media content + $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); + foreach($tabRibbonTypes as $aRibbonType){ + $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor + $this->_writeDefaultContentType( + $objWriter, $aRibbonType, $mimeType + ); + } + } + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) { + foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) { + if (!isset( $aMediaContentTypes[strtolower($image->getExtension())]) ) { + $aMediaContentTypes[strtolower($image->getExtension())] = $this->_getImageMimeType( $image->getPath() ); - $this->_writeDefaultContentType( - $objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())] - ); - } - } - } - } + $this->_writeDefaultContentType( + $objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())] + ); + } + } + } + } - $objWriter->endElement(); + $objWriter->endElement(); - // Return - return $objWriter->getData(); - } + // Return + return $objWriter->getData(); + } - /** - * Get image mime type - * - * @param string $pFile Filename - * @return string Mime Type - * @throws PHPExcel_Writer_Exception - */ - private function _getImageMimeType($pFile = '') - { - if (PHPExcel_Shared_File::file_exists($pFile)) { - $image = getimagesize($pFile); - return image_type_to_mime_type($image[2]); - } else { - throw new PHPExcel_Writer_Exception("File $pFile does not exist"); - } - } + /** + * Get image mime type + * + * @param string $pFile Filename + * @return string Mime Type + * @throws PHPExcel_Writer_Exception + */ + private function _getImageMimeType($pFile = '') + { + if (PHPExcel_Shared_File::file_exists($pFile)) { + $image = getimagesize($pFile); + return image_type_to_mime_type($image[2]); + } else { + throw new PHPExcel_Writer_Exception("File $pFile does not exist"); + } + } - /** - * Write Default content type - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param string $pPartname Part name - * @param string $pContentType Content type - * @throws PHPExcel_Writer_Exception - */ - private function _writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') - { - if ($pPartname != '' && $pContentType != '') { - // Write content type - $objWriter->startElement('Default'); - $objWriter->writeAttribute('Extension', $pPartname); - $objWriter->writeAttribute('ContentType', $pContentType); - $objWriter->endElement(); - } else { - throw new PHPExcel_Writer_Exception("Invalid parameters passed."); - } - } + /** + * Write Default content type + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pPartname Part name + * @param string $pContentType Content type + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') + { + if ($pPartname != '' && $pContentType != '') { + // Write content type + $objWriter->startElement('Default'); + $objWriter->writeAttribute('Extension', $pPartname); + $objWriter->writeAttribute('ContentType', $pContentType); + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } - /** - * Write Override content type - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param string $pPartname Part name - * @param string $pContentType Content type - * @throws PHPExcel_Writer_Exception - */ - private function _writeOverrideContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') - { - if ($pPartname != '' && $pContentType != '') { - // Write content type - $objWriter->startElement('Override'); - $objWriter->writeAttribute('PartName', $pPartname); - $objWriter->writeAttribute('ContentType', $pContentType); - $objWriter->endElement(); - } else { - throw new PHPExcel_Writer_Exception("Invalid parameters passed."); - } - } + /** + * Write Override content type + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pPartname Part name + * @param string $pContentType Content type + * @throws PHPExcel_Writer_Exception + */ + private function _writeOverrideContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') + { + if ($pPartname != '' && $pContentType != '') { + // Write content type + $objWriter->startElement('Override'); + $objWriter->writeAttribute('PartName', $pPartname); + $objWriter->writeAttribute('ContentType', $pContentType); + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/DocProps.php b/Classes/PHPExcel/Writer/Excel2007/DocProps.php index c4a4b2d44..a65d39ac4 100644 --- a/Classes/PHPExcel/Writer/Excel2007/DocProps.php +++ b/Classes/PHPExcel/Writer/Excel2007/DocProps.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -36,237 +36,237 @@ class PHPExcel_Writer_Excel2007_DocProps extends PHPExcel_Writer_Excel2007_WriterPart { /** - * Write docProps/app.xml to XML format - * - * @param PHPExcel $pPHPExcel - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeDocPropsApp(PHPExcel $pPHPExcel = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // Properties - $objWriter->startElement('Properties'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties'); - $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); - - // Application - $objWriter->writeElement('Application', 'Microsoft Excel'); - - // DocSecurity - $objWriter->writeElement('DocSecurity', '0'); - - // ScaleCrop - $objWriter->writeElement('ScaleCrop', 'false'); - - // HeadingPairs - $objWriter->startElement('HeadingPairs'); - - // Vector - $objWriter->startElement('vt:vector'); - $objWriter->writeAttribute('size', '2'); - $objWriter->writeAttribute('baseType', 'variant'); - - // Variant - $objWriter->startElement('vt:variant'); - $objWriter->writeElement('vt:lpstr', 'Worksheets'); - $objWriter->endElement(); - - // Variant - $objWriter->startElement('vt:variant'); - $objWriter->writeElement('vt:i4', $pPHPExcel->getSheetCount()); - $objWriter->endElement(); - - $objWriter->endElement(); - - $objWriter->endElement(); - - // TitlesOfParts - $objWriter->startElement('TitlesOfParts'); - - // Vector - $objWriter->startElement('vt:vector'); - $objWriter->writeAttribute('size', $pPHPExcel->getSheetCount()); - $objWriter->writeAttribute('baseType', 'lpstr'); - - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - $objWriter->writeElement('vt:lpstr', $pPHPExcel->getSheet($i)->getTitle()); - } - - $objWriter->endElement(); - - $objWriter->endElement(); - - // Company - $objWriter->writeElement('Company', $pPHPExcel->getProperties()->getCompany()); - - // Company - $objWriter->writeElement('Manager', $pPHPExcel->getProperties()->getManager()); - - // LinksUpToDate - $objWriter->writeElement('LinksUpToDate', 'false'); - - // SharedDoc - $objWriter->writeElement('SharedDoc', 'false'); - - // HyperlinksChanged - $objWriter->writeElement('HyperlinksChanged', 'false'); - - // AppVersion - $objWriter->writeElement('AppVersion', '12.0000'); - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write docProps/core.xml to XML format - * - * @param PHPExcel $pPHPExcel - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeDocPropsCore(PHPExcel $pPHPExcel = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // cp:coreProperties - $objWriter->startElement('cp:coreProperties'); - $objWriter->writeAttribute('xmlns:cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties'); - $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); - $objWriter->writeAttribute('xmlns:dcterms', 'http://purl.org/dc/terms/'); - $objWriter->writeAttribute('xmlns:dcmitype', 'http://purl.org/dc/dcmitype/'); - $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); - - // dc:creator - $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); - - // cp:lastModifiedBy - $objWriter->writeElement('cp:lastModifiedBy', $pPHPExcel->getProperties()->getLastModifiedBy()); - - // dcterms:created - $objWriter->startElement('dcterms:created'); - $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); - $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); - $objWriter->endElement(); - - // dcterms:modified - $objWriter->startElement('dcterms:modified'); - $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); - $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getModified())); - $objWriter->endElement(); - - // dc:title - $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); - - // dc:description - $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); - - // dc:subject - $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); - - // cp:keywords - $objWriter->writeElement('cp:keywords', $pPHPExcel->getProperties()->getKeywords()); - - // cp:category - $objWriter->writeElement('cp:category', $pPHPExcel->getProperties()->getCategory()); - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write docProps/custom.xml to XML format - * - * @param PHPExcel $pPHPExcel - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeDocPropsCustom(PHPExcel $pPHPExcel = null) - { - $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); - if (empty($customPropertyList)) { - return; - } - - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // cp:coreProperties - $objWriter->startElement('Properties'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties'); - $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); - - - foreach($customPropertyList as $key => $customProperty) { - $propertyValue = $pPHPExcel->getProperties()->getCustomPropertyValue($customProperty); - $propertyType = $pPHPExcel->getProperties()->getCustomPropertyType($customProperty); - - $objWriter->startElement('property'); - $objWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'); - $objWriter->writeAttribute('pid', $key+2); - $objWriter->writeAttribute('name', $customProperty); - - switch($propertyType) { - case 'i' : - $objWriter->writeElement('vt:i4', $propertyValue); - break; - case 'f' : - $objWriter->writeElement('vt:r8', $propertyValue); - break; - case 'b' : - $objWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false'); - break; - case 'd' : - $objWriter->startElement('vt:filetime'); - $objWriter->writeRawData(date(DATE_W3C, $propertyValue)); - $objWriter->endElement(); - break; - default : - $objWriter->writeElement('vt:lpwstr', $propertyValue); - break; - } - - $objWriter->endElement(); - } - - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } + * Write docProps/app.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDocPropsApp(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Properties + $objWriter->startElement('Properties'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties'); + $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + + // Application + $objWriter->writeElement('Application', 'Microsoft Excel'); + + // DocSecurity + $objWriter->writeElement('DocSecurity', '0'); + + // ScaleCrop + $objWriter->writeElement('ScaleCrop', 'false'); + + // HeadingPairs + $objWriter->startElement('HeadingPairs'); + + // Vector + $objWriter->startElement('vt:vector'); + $objWriter->writeAttribute('size', '2'); + $objWriter->writeAttribute('baseType', 'variant'); + + // Variant + $objWriter->startElement('vt:variant'); + $objWriter->writeElement('vt:lpstr', 'Worksheets'); + $objWriter->endElement(); + + // Variant + $objWriter->startElement('vt:variant'); + $objWriter->writeElement('vt:i4', $pPHPExcel->getSheetCount()); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // TitlesOfParts + $objWriter->startElement('TitlesOfParts'); + + // Vector + $objWriter->startElement('vt:vector'); + $objWriter->writeAttribute('size', $pPHPExcel->getSheetCount()); + $objWriter->writeAttribute('baseType', 'lpstr'); + + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $objWriter->writeElement('vt:lpstr', $pPHPExcel->getSheet($i)->getTitle()); + } + + $objWriter->endElement(); + + $objWriter->endElement(); + + // Company + $objWriter->writeElement('Company', $pPHPExcel->getProperties()->getCompany()); + + // Company + $objWriter->writeElement('Manager', $pPHPExcel->getProperties()->getManager()); + + // LinksUpToDate + $objWriter->writeElement('LinksUpToDate', 'false'); + + // SharedDoc + $objWriter->writeElement('SharedDoc', 'false'); + + // HyperlinksChanged + $objWriter->writeElement('HyperlinksChanged', 'false'); + + // AppVersion + $objWriter->writeElement('AppVersion', '12.0000'); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write docProps/core.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDocPropsCore(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // cp:coreProperties + $objWriter->startElement('cp:coreProperties'); + $objWriter->writeAttribute('xmlns:cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties'); + $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); + $objWriter->writeAttribute('xmlns:dcterms', 'http://purl.org/dc/terms/'); + $objWriter->writeAttribute('xmlns:dcmitype', 'http://purl.org/dc/dcmitype/'); + $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + + // dc:creator + $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); + + // cp:lastModifiedBy + $objWriter->writeElement('cp:lastModifiedBy', $pPHPExcel->getProperties()->getLastModifiedBy()); + + // dcterms:created + $objWriter->startElement('dcterms:created'); + $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); + $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); + $objWriter->endElement(); + + // dcterms:modified + $objWriter->startElement('dcterms:modified'); + $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); + $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getModified())); + $objWriter->endElement(); + + // dc:title + $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); + + // dc:description + $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); + + // dc:subject + $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); + + // cp:keywords + $objWriter->writeElement('cp:keywords', $pPHPExcel->getProperties()->getKeywords()); + + // cp:category + $objWriter->writeElement('cp:category', $pPHPExcel->getProperties()->getCategory()); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write docProps/custom.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDocPropsCustom(PHPExcel $pPHPExcel = null) + { + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (empty($customPropertyList)) { + return; + } + + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // cp:coreProperties + $objWriter->startElement('Properties'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties'); + $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + + + foreach($customPropertyList as $key => $customProperty) { + $propertyValue = $pPHPExcel->getProperties()->getCustomPropertyValue($customProperty); + $propertyType = $pPHPExcel->getProperties()->getCustomPropertyType($customProperty); + + $objWriter->startElement('property'); + $objWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'); + $objWriter->writeAttribute('pid', $key+2); + $objWriter->writeAttribute('name', $customProperty); + + switch($propertyType) { + case 'i' : + $objWriter->writeElement('vt:i4', $propertyValue); + break; + case 'f' : + $objWriter->writeElement('vt:r8', $propertyValue); + break; + case 'b' : + $objWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false'); + break; + case 'd' : + $objWriter->startElement('vt:filetime'); + $objWriter->writeRawData(date(DATE_W3C, $propertyValue)); + $objWriter->endElement(); + break; + default : + $objWriter->writeElement('vt:lpwstr', $propertyValue); + break; + } + + $objWriter->endElement(); + } + + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Drawing.php b/Classes/PHPExcel/Writer/Excel2007/Drawing.php index 2cda60353..4810542de 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Drawing.php +++ b/Classes/PHPExcel/Writer/Excel2007/Drawing.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,564 +35,564 @@ */ class PHPExcel_Writer_Excel2007_Drawing extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Write drawings to XML format - * - * @param PHPExcel_Worksheet $pWorksheet - * @param int &$chartRef Chart ID - * @param boolean $includeCharts Flag indicating if we should include drawing details for charts - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // xdr:wsDr - $objWriter->startElement('xdr:wsDr'); - $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing'); - $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); - - // Loop through images and write drawings - $i = 1; - $iterator = $pWorksheet->getDrawingCollection()->getIterator(); - while ($iterator->valid()) { - $this->_writeDrawing($objWriter, $iterator->current(), $i); - - $iterator->next(); - ++$i; - } - - if ($includeCharts) { - $chartCount = $pWorksheet->getChartCount(); - // Loop through charts and write the chart position - if ($chartCount > 0) { - for ($c = 0; $c < $chartCount; ++$c) { - $this->_writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i); - } - } - } - - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write drawings to XML format - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Chart $pChart - * @param int $pRelationId - * @throws PHPExcel_Writer_Exception - */ - public function _writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Chart $pChart = null, $pRelationId = -1) - { - $tl = $pChart->getTopLeftPosition(); - $tl['colRow'] = PHPExcel_Cell::coordinateFromString($tl['cell']); - $br = $pChart->getBottomRightPosition(); - $br['colRow'] = PHPExcel_Cell::coordinateFromString($br['cell']); - - $objWriter->startElement('xdr:twoCellAnchor'); - - $objWriter->startElement('xdr:from'); - $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($tl['colRow'][0]) - 1); - $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['xOffset'])); - $objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1); - $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['yOffset'])); - $objWriter->endElement(); - $objWriter->startElement('xdr:to'); - $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($br['colRow'][0]) - 1); - $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['xOffset'])); - $objWriter->writeElement('xdr:row', $br['colRow'][1] - 1); - $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['yOffset'])); - $objWriter->endElement(); - - $objWriter->startElement('xdr:graphicFrame'); - $objWriter->writeAttribute('macro', ''); - $objWriter->startElement('xdr:nvGraphicFramePr'); - $objWriter->startElement('xdr:cNvPr'); - $objWriter->writeAttribute('name', 'Chart '.$pRelationId); - $objWriter->writeAttribute('id', 1025 * $pRelationId); - $objWriter->endElement(); - $objWriter->startElement('xdr:cNvGraphicFramePr'); - $objWriter->startElement('a:graphicFrameLocks'); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('xdr:xfrm'); - $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', '0'); - $objWriter->writeAttribute('y', '0'); - $objWriter->endElement(); - $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', '0'); - $objWriter->writeAttribute('cy', '0'); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('a:graphic'); - $objWriter->startElement('a:graphicData'); - $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); - $objWriter->startElement('c:chart'); - $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); - $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - $objWriter->writeAttribute('r:id', 'rId'.$pRelationId); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('xdr:clientData'); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write drawings to XML format - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet_BaseDrawing $pDrawing - * @param int $pRelationId - * @throws PHPExcel_Writer_Exception - */ - public function _writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet_BaseDrawing $pDrawing = null, $pRelationId = -1) - { - if ($pRelationId >= 0) { - // xdr:oneCellAnchor - $objWriter->startElement('xdr:oneCellAnchor'); - // Image location - $aCoordinates = PHPExcel_Cell::coordinateFromString($pDrawing->getCoordinates()); - $aCoordinates[0] = PHPExcel_Cell::columnIndexFromString($aCoordinates[0]); - - // xdr:from - $objWriter->startElement('xdr:from'); - $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1); - $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX())); - $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1); - $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY())); - $objWriter->endElement(); - - // xdr:ext - $objWriter->startElement('xdr:ext'); - $objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth())); - $objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight())); - $objWriter->endElement(); - - // xdr:pic - $objWriter->startElement('xdr:pic'); - - // xdr:nvPicPr - $objWriter->startElement('xdr:nvPicPr'); - - // xdr:cNvPr - $objWriter->startElement('xdr:cNvPr'); - $objWriter->writeAttribute('id', $pRelationId); - $objWriter->writeAttribute('name', $pDrawing->getName()); - $objWriter->writeAttribute('descr', $pDrawing->getDescription()); - $objWriter->endElement(); - - // xdr:cNvPicPr - $objWriter->startElement('xdr:cNvPicPr'); - - // a:picLocks - $objWriter->startElement('a:picLocks'); - $objWriter->writeAttribute('noChangeAspect', '1'); - $objWriter->endElement(); - - $objWriter->endElement(); - - $objWriter->endElement(); - - // xdr:blipFill - $objWriter->startElement('xdr:blipFill'); - - // a:blip - $objWriter->startElement('a:blip'); - $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId); - $objWriter->endElement(); - - // a:stretch - $objWriter->startElement('a:stretch'); - $objWriter->writeElement('a:fillRect', null); - $objWriter->endElement(); - - $objWriter->endElement(); - - // xdr:spPr - $objWriter->startElement('xdr:spPr'); - - // a:xfrm - $objWriter->startElement('a:xfrm'); - $objWriter->writeAttribute('rot', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getRotation())); - $objWriter->endElement(); - - // a:prstGeom - $objWriter->startElement('a:prstGeom'); - $objWriter->writeAttribute('prst', 'rect'); - - // a:avLst - $objWriter->writeElement('a:avLst', null); - - $objWriter->endElement(); - -// // a:solidFill -// $objWriter->startElement('a:solidFill'); - -// // a:srgbClr -// $objWriter->startElement('a:srgbClr'); -// $objWriter->writeAttribute('val', 'FFFFFF'); + /** + * Write drawings to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @param int &$chartRef Chart ID + * @param boolean $includeCharts Flag indicating if we should include drawing details for charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // xdr:wsDr + $objWriter->startElement('xdr:wsDr'); + $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + + // Loop through images and write drawings + $i = 1; + $iterator = $pWorksheet->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + $this->_writeDrawing($objWriter, $iterator->current(), $i); + + $iterator->next(); + ++$i; + } + + if ($includeCharts) { + $chartCount = $pWorksheet->getChartCount(); + // Loop through charts and write the chart position + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i); + } + } + } + + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write drawings to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart $pChart + * @param int $pRelationId + * @throws PHPExcel_Writer_Exception + */ + public function _writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Chart $pChart = null, $pRelationId = -1) + { + $tl = $pChart->getTopLeftPosition(); + $tl['colRow'] = PHPExcel_Cell::coordinateFromString($tl['cell']); + $br = $pChart->getBottomRightPosition(); + $br['colRow'] = PHPExcel_Cell::coordinateFromString($br['cell']); + + $objWriter->startElement('xdr:twoCellAnchor'); + + $objWriter->startElement('xdr:from'); + $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($tl['colRow'][0]) - 1); + $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['xOffset'])); + $objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1); + $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['yOffset'])); + $objWriter->endElement(); + $objWriter->startElement('xdr:to'); + $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($br['colRow'][0]) - 1); + $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['xOffset'])); + $objWriter->writeElement('xdr:row', $br['colRow'][1] - 1); + $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['yOffset'])); + $objWriter->endElement(); + + $objWriter->startElement('xdr:graphicFrame'); + $objWriter->writeAttribute('macro', ''); + $objWriter->startElement('xdr:nvGraphicFramePr'); + $objWriter->startElement('xdr:cNvPr'); + $objWriter->writeAttribute('name', 'Chart '.$pRelationId); + $objWriter->writeAttribute('id', 1025 * $pRelationId); + $objWriter->endElement(); + $objWriter->startElement('xdr:cNvGraphicFramePr'); + $objWriter->startElement('a:graphicFrameLocks'); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('xdr:xfrm'); + $objWriter->startElement('a:off'); + $objWriter->writeAttribute('x', '0'); + $objWriter->writeAttribute('y', '0'); + $objWriter->endElement(); + $objWriter->startElement('a:ext'); + $objWriter->writeAttribute('cx', '0'); + $objWriter->writeAttribute('cy', '0'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('a:graphic'); + $objWriter->startElement('a:graphicData'); + $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); + $objWriter->startElement('c:chart'); + $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $objWriter->writeAttribute('r:id', 'rId'.$pRelationId); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('xdr:clientData'); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write drawings to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet_BaseDrawing $pDrawing + * @param int $pRelationId + * @throws PHPExcel_Writer_Exception + */ + public function _writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet_BaseDrawing $pDrawing = null, $pRelationId = -1) + { + if ($pRelationId >= 0) { + // xdr:oneCellAnchor + $objWriter->startElement('xdr:oneCellAnchor'); + // Image location + $aCoordinates = PHPExcel_Cell::coordinateFromString($pDrawing->getCoordinates()); + $aCoordinates[0] = PHPExcel_Cell::columnIndexFromString($aCoordinates[0]); + + // xdr:from + $objWriter->startElement('xdr:from'); + $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1); + $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX())); + $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1); + $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY())); + $objWriter->endElement(); + + // xdr:ext + $objWriter->startElement('xdr:ext'); + $objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth())); + $objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight())); + $objWriter->endElement(); + + // xdr:pic + $objWriter->startElement('xdr:pic'); + + // xdr:nvPicPr + $objWriter->startElement('xdr:nvPicPr'); + + // xdr:cNvPr + $objWriter->startElement('xdr:cNvPr'); + $objWriter->writeAttribute('id', $pRelationId); + $objWriter->writeAttribute('name', $pDrawing->getName()); + $objWriter->writeAttribute('descr', $pDrawing->getDescription()); + $objWriter->endElement(); + + // xdr:cNvPicPr + $objWriter->startElement('xdr:cNvPicPr'); + + // a:picLocks + $objWriter->startElement('a:picLocks'); + $objWriter->writeAttribute('noChangeAspect', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // xdr:blipFill + $objWriter->startElement('xdr:blipFill'); + + // a:blip + $objWriter->startElement('a:blip'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId); + $objWriter->endElement(); + + // a:stretch + $objWriter->startElement('a:stretch'); + $objWriter->writeElement('a:fillRect', null); + $objWriter->endElement(); + + $objWriter->endElement(); + + // xdr:spPr + $objWriter->startElement('xdr:spPr'); + + // a:xfrm + $objWriter->startElement('a:xfrm'); + $objWriter->writeAttribute('rot', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getRotation())); + $objWriter->endElement(); + + // a:prstGeom + $objWriter->startElement('a:prstGeom'); + $objWriter->writeAttribute('prst', 'rect'); + + // a:avLst + $objWriter->writeElement('a:avLst', null); + + $objWriter->endElement(); + +// // a:solidFill +// $objWriter->startElement('a:solidFill'); + +// // a:srgbClr +// $objWriter->startElement('a:srgbClr'); +// $objWriter->writeAttribute('val', 'FFFFFF'); ///* SHADE -// // a:shade -// $objWriter->startElement('a:shade'); -// $objWriter->writeAttribute('val', '85000'); -// $objWriter->endElement(); +// // a:shade +// $objWriter->startElement('a:shade'); +// $objWriter->writeAttribute('val', '85000'); +// $objWriter->endElement(); //*/ -// $objWriter->endElement(); +// $objWriter->endElement(); -// $objWriter->endElement(); +// $objWriter->endElement(); /* - // a:ln - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', '88900'); - $objWriter->writeAttribute('cap', 'sq'); + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '88900'); + $objWriter->writeAttribute('cap', 'sq'); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:solidFill + $objWriter->startElement('a:solidFill'); - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', 'FFFFFF'); - $objWriter->endElement(); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FFFFFF'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:miter - $objWriter->startElement('a:miter'); - $objWriter->writeAttribute('lim', '800000'); - $objWriter->endElement(); + // a:miter + $objWriter->startElement('a:miter'); + $objWriter->writeAttribute('lim', '800000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); */ - if ($pDrawing->getShadow()->getVisible()) { - // a:effectLst - $objWriter->startElement('a:effectLst'); + if ($pDrawing->getShadow()->getVisible()) { + // a:effectLst + $objWriter->startElement('a:effectLst'); - // a:outerShdw - $objWriter->startElement('a:outerShdw'); - $objWriter->writeAttribute('blurRad', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius())); - $objWriter->writeAttribute('dist', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance())); - $objWriter->writeAttribute('dir', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getShadow()->getDirection())); - $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment()); - $objWriter->writeAttribute('rotWithShape', '0'); + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius())); + $objWriter->writeAttribute('dist', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance())); + $objWriter->writeAttribute('dir', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getShadow()->getDirection())); + $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment()); + $objWriter->writeAttribute('rotWithShape', '0'); - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB()); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB()); - // a:alpha - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000); - $objWriter->endElement(); + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); - } + $objWriter->endElement(); + } /* - // a:scene3d - $objWriter->startElement('a:scene3d'); + // a:scene3d + $objWriter->startElement('a:scene3d'); - // a:camera - $objWriter->startElement('a:camera'); - $objWriter->writeAttribute('prst', 'orthographicFront'); - $objWriter->endElement(); + // a:camera + $objWriter->startElement('a:camera'); + $objWriter->writeAttribute('prst', 'orthographicFront'); + $objWriter->endElement(); - // a:lightRig - $objWriter->startElement('a:lightRig'); - $objWriter->writeAttribute('rig', 'twoPt'); - $objWriter->writeAttribute('dir', 't'); + // a:lightRig + $objWriter->startElement('a:lightRig'); + $objWriter->writeAttribute('rig', 'twoPt'); + $objWriter->writeAttribute('dir', 't'); - // a:rot - $objWriter->startElement('a:rot'); - $objWriter->writeAttribute('lat', '0'); - $objWriter->writeAttribute('lon', '0'); - $objWriter->writeAttribute('rev', '0'); - $objWriter->endElement(); + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '0'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); */ /* - // a:sp3d - $objWriter->startElement('a:sp3d'); + // a:sp3d + $objWriter->startElement('a:sp3d'); - // a:bevelT - $objWriter->startElement('a:bevelT'); - $objWriter->writeAttribute('w', '25400'); - $objWriter->writeAttribute('h', '19050'); - $objWriter->endElement(); + // a:bevelT + $objWriter->startElement('a:bevelT'); + $objWriter->writeAttribute('w', '25400'); + $objWriter->writeAttribute('h', '19050'); + $objWriter->endElement(); - // a:contourClr - $objWriter->startElement('a:contourClr'); + // a:contourClr + $objWriter->startElement('a:contourClr'); - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', 'FFFFFF'); - $objWriter->endElement(); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FFFFFF'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); */ - $objWriter->endElement(); - - $objWriter->endElement(); - - // xdr:clientData - $objWriter->writeElement('xdr:clientData', null); - - $objWriter->endElement(); - } else { - throw new PHPExcel_Writer_Exception("Invalid parameters passed."); - } - } - - /** - * Write VML header/footer images to XML format - * - * @param PHPExcel_Worksheet $pWorksheet - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // Header/footer images - $images = $pWorksheet->getHeaderFooter()->getImages(); - - // xml - $objWriter->startElement('xml'); - $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); - $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); - $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); - - // o:shapelayout - $objWriter->startElement('o:shapelayout'); - $objWriter->writeAttribute('v:ext', 'edit'); - - // o:idmap - $objWriter->startElement('o:idmap'); - $objWriter->writeAttribute('v:ext', 'edit'); - $objWriter->writeAttribute('data', '1'); - $objWriter->endElement(); - - $objWriter->endElement(); - - // v:shapetype - $objWriter->startElement('v:shapetype'); - $objWriter->writeAttribute('id', '_x0000_t75'); - $objWriter->writeAttribute('coordsize', '21600,21600'); - $objWriter->writeAttribute('o:spt', '75'); - $objWriter->writeAttribute('o:preferrelative', 't'); - $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe'); - $objWriter->writeAttribute('filled', 'f'); - $objWriter->writeAttribute('stroked', 'f'); - - // v:stroke - $objWriter->startElement('v:stroke'); - $objWriter->writeAttribute('joinstyle', 'miter'); - $objWriter->endElement(); - - // v:formulas - $objWriter->startElement('v:formulas'); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'sum @0 1 0'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'sum 0 0 @1'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @2 1 2'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'sum @0 0 1'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @6 1 2'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'sum @8 21600 0'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight'); - $objWriter->endElement(); - - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'sum @10 21600 0'); - $objWriter->endElement(); - - $objWriter->endElement(); - - // v:path - $objWriter->startElement('v:path'); - $objWriter->writeAttribute('o:extrusionok', 'f'); - $objWriter->writeAttribute('gradientshapeok', 't'); - $objWriter->writeAttribute('o:connecttype', 'rect'); - $objWriter->endElement(); - - // o:lock - $objWriter->startElement('o:lock'); - $objWriter->writeAttribute('v:ext', 'edit'); - $objWriter->writeAttribute('aspectratio', 't'); - $objWriter->endElement(); - - $objWriter->endElement(); - - // Loop through images - foreach ($images as $key => $value) { - $this->_writeVMLHeaderFooterImage($objWriter, $key, $value); - } - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write VML comment to XML format - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param string $pReference Reference - * @param PHPExcel_Worksheet_HeaderFooterDrawing $pImage Image - * @throws PHPExcel_Writer_Exception - */ - public function _writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter = null, $pReference = '', PHPExcel_Worksheet_HeaderFooterDrawing $pImage = null) - { - // Calculate object id - preg_match('{(\d+)}', md5($pReference), $m); - $id = 1500 + (substr($m[1], 0, 2) * 1); - - // Calculate offset - $width = $pImage->getWidth(); - $height = $pImage->getHeight(); - $marginLeft = $pImage->getOffsetX(); - $marginTop = $pImage->getOffsetY(); - - // v:shape - $objWriter->startElement('v:shape'); - $objWriter->writeAttribute('id', $pReference); - $objWriter->writeAttribute('o:spid', '_x0000_s' . $id); - $objWriter->writeAttribute('type', '#_x0000_t75'); - $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1"); - - // v:imagedata - $objWriter->startElement('v:imagedata'); - $objWriter->writeAttribute('o:relid', 'rId' . $pReference); - $objWriter->writeAttribute('o:title', $pImage->getName()); - $objWriter->endElement(); - - // o:lock - $objWriter->startElement('o:lock'); - $objWriter->writeAttribute('v:ext', 'edit'); - $objWriter->writeAttribute('rotation', 't'); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - - /** - * Get an array of all drawings - * - * @param PHPExcel $pPHPExcel - * @return PHPExcel_Worksheet_Drawing[] All drawings in PHPExcel - * @throws PHPExcel_Writer_Exception - */ - public function allDrawings(PHPExcel $pPHPExcel = null) - { - // Get an array of all drawings - $aDrawings = array(); - - // Loop through PHPExcel - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - // Loop through images and add to array - $iterator = $pPHPExcel->getSheet($i)->getDrawingCollection()->getIterator(); - while ($iterator->valid()) { - $aDrawings[] = $iterator->current(); - - $iterator->next(); - } - } - - return $aDrawings; - } + $objWriter->endElement(); + + $objWriter->endElement(); + + // xdr:clientData + $objWriter->writeElement('xdr:clientData', null); + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write VML header/footer images to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Header/footer images + $images = $pWorksheet->getHeaderFooter()->getImages(); + + // xml + $objWriter->startElement('xml'); + $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); + $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); + $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); + + // o:shapelayout + $objWriter->startElement('o:shapelayout'); + $objWriter->writeAttribute('v:ext', 'edit'); + + // o:idmap + $objWriter->startElement('o:idmap'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('data', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // v:shapetype + $objWriter->startElement('v:shapetype'); + $objWriter->writeAttribute('id', '_x0000_t75'); + $objWriter->writeAttribute('coordsize', '21600,21600'); + $objWriter->writeAttribute('o:spt', '75'); + $objWriter->writeAttribute('o:preferrelative', 't'); + $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe'); + $objWriter->writeAttribute('filled', 'f'); + $objWriter->writeAttribute('stroked', 'f'); + + // v:stroke + $objWriter->startElement('v:stroke'); + $objWriter->writeAttribute('joinstyle', 'miter'); + $objWriter->endElement(); + + // v:formulas + $objWriter->startElement('v:formulas'); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @0 1 0'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum 0 0 @1'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @2 1 2'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @0 0 1'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @6 1 2'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @8 21600 0'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @10 21600 0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('o:extrusionok', 'f'); + $objWriter->writeAttribute('gradientshapeok', 't'); + $objWriter->writeAttribute('o:connecttype', 'rect'); + $objWriter->endElement(); + + // o:lock + $objWriter->startElement('o:lock'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('aspectratio', 't'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Loop through images + foreach ($images as $key => $value) { + $this->_writeVMLHeaderFooterImage($objWriter, $key, $value); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write VML comment to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pReference Reference + * @param PHPExcel_Worksheet_HeaderFooterDrawing $pImage Image + * @throws PHPExcel_Writer_Exception + */ + public function _writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter = null, $pReference = '', PHPExcel_Worksheet_HeaderFooterDrawing $pImage = null) + { + // Calculate object id + preg_match('{(\d+)}', md5($pReference), $m); + $id = 1500 + (substr($m[1], 0, 2) * 1); + + // Calculate offset + $width = $pImage->getWidth(); + $height = $pImage->getHeight(); + $marginLeft = $pImage->getOffsetX(); + $marginTop = $pImage->getOffsetY(); + + // v:shape + $objWriter->startElement('v:shape'); + $objWriter->writeAttribute('id', $pReference); + $objWriter->writeAttribute('o:spid', '_x0000_s' . $id); + $objWriter->writeAttribute('type', '#_x0000_t75'); + $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1"); + + // v:imagedata + $objWriter->startElement('v:imagedata'); + $objWriter->writeAttribute('o:relid', 'rId' . $pReference); + $objWriter->writeAttribute('o:title', $pImage->getName()); + $objWriter->endElement(); + + // o:lock + $objWriter->startElement('o:lock'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('rotation', 't'); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + + /** + * Get an array of all drawings + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Worksheet_Drawing[] All drawings in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allDrawings(PHPExcel $pPHPExcel = null) + { + // Get an array of all drawings + $aDrawings = array(); + + // Loop through PHPExcel + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + // Loop through images and add to array + $iterator = $pPHPExcel->getSheet($i)->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + $aDrawings[] = $iterator->current(); + + $iterator->next(); + } + } + + return $aDrawings; + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Rels.php b/Classes/PHPExcel/Writer/Excel2007/Rels.php index cf9b6bed0..912d23f2b 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Rels.php +++ b/Classes/PHPExcel/Writer/Excel2007/Rels.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,403 +35,403 @@ */ class PHPExcel_Writer_Excel2007_Rels extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Write relationships to XML format - * - * @param PHPExcel $pPHPExcel - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeRelationships(PHPExcel $pPHPExcel = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // Relationships - $objWriter->startElement('Relationships'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - - $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); - if (!empty($customPropertyList)) { - // Relationship docProps/app.xml - $this->_writeRelationship( - $objWriter, - 4, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties', - 'docProps/custom.xml' - ); - - } - - // Relationship docProps/app.xml - $this->_writeRelationship( - $objWriter, - 3, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties', - 'docProps/app.xml' - ); - - // Relationship docProps/core.xml - $this->_writeRelationship( - $objWriter, - 2, - 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', - 'docProps/core.xml' - ); - - // Relationship xl/workbook.xml - $this->_writeRelationship( - $objWriter, - 1, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', - 'xl/workbook.xml' - ); - // a custom UI in workbook ? - if($pPHPExcel->hasRibbon()){ - $this->_writeRelationShip( - $objWriter, - 5, - 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', - $pPHPExcel->getRibbonXMLData('target') - ); - } - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write workbook relationships to XML format - * - * @param PHPExcel $pPHPExcel - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // Relationships - $objWriter->startElement('Relationships'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - - // Relationship styles.xml - $this->_writeRelationship( - $objWriter, - 1, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles', - 'styles.xml' - ); - - // Relationship theme/theme1.xml - $this->_writeRelationship( - $objWriter, - 2, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', - 'theme/theme1.xml' - ); - - // Relationship sharedStrings.xml - $this->_writeRelationship( - $objWriter, - 3, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', - 'sharedStrings.xml' - ); - - // Relationships with sheets - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - $this->_writeRelationship( - $objWriter, - ($i + 1 + 3), - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', - 'worksheets/sheet' . ($i + 1) . '.xml' - ); - } - // Relationships for vbaProject if needed - // id : just after the last sheet - if($pPHPExcel->hasMacros()){ - $this->_writeRelationShip( - $objWriter, - ($i + 1 + 3), - 'http://schemas.microsoft.com/office/2006/relationships/vbaProject', - 'vbaProject.bin' - ); - ++$i;//increment i if needed for an another relation - } - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write worksheet relationships to XML format - * - * Numbering is as follows: - * rId1 - Drawings - * rId_hyperlink_x - Hyperlinks - * - * @param PHPExcel_Worksheet $pWorksheet - * @param int $pWorksheetId - * @param boolean $includeCharts Flag indicating if we should write charts - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = null, $pWorksheetId = 1, $includeCharts = FALSE) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // Relationships - $objWriter->startElement('Relationships'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - - // Write drawing relationships? - $d = 0; - if ($includeCharts) { - $charts = $pWorksheet->getChartCollection(); - } else { - $charts = array(); - } - if (($pWorksheet->getDrawingCollection()->count() > 0) || - (count($charts) > 0)) { - $this->_writeRelationship( - $objWriter, - ++$d, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', - '../drawings/drawing' . $pWorksheetId . '.xml' - ); - } - - // Write chart relationships? -// $chartCount = 0; -// $charts = $pWorksheet->getChartCollection(); -// echo 'Chart Rels: ' , count($charts) , '<br />'; -// if (count($charts) > 0) { -// foreach($charts as $chart) { -// $this->_writeRelationship( -// $objWriter, -// ++$d, -// 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', -// '../charts/chart' . ++$chartCount . '.xml' -// ); -// } -// } + /** + * Write relationships to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeRelationships(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (!empty($customPropertyList)) { + // Relationship docProps/app.xml + $this->_writeRelationship( + $objWriter, + 4, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties', + 'docProps/custom.xml' + ); + + } + + // Relationship docProps/app.xml + $this->_writeRelationship( + $objWriter, + 3, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties', + 'docProps/app.xml' + ); + + // Relationship docProps/core.xml + $this->_writeRelationship( + $objWriter, + 2, + 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', + 'docProps/core.xml' + ); + + // Relationship xl/workbook.xml + $this->_writeRelationship( + $objWriter, + 1, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', + 'xl/workbook.xml' + ); + // a custom UI in workbook ? + if($pPHPExcel->hasRibbon()){ + $this->_writeRelationShip( + $objWriter, + 5, + 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', + $pPHPExcel->getRibbonXMLData('target') + ); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write workbook relationships to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Relationship styles.xml + $this->_writeRelationship( + $objWriter, + 1, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles', + 'styles.xml' + ); + + // Relationship theme/theme1.xml + $this->_writeRelationship( + $objWriter, + 2, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', + 'theme/theme1.xml' + ); + + // Relationship sharedStrings.xml + $this->_writeRelationship( + $objWriter, + 3, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', + 'sharedStrings.xml' + ); + + // Relationships with sheets + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $this->_writeRelationship( + $objWriter, + ($i + 1 + 3), + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', + 'worksheets/sheet' . ($i + 1) . '.xml' + ); + } + // Relationships for vbaProject if needed + // id : just after the last sheet + if($pPHPExcel->hasMacros()){ + $this->_writeRelationShip( + $objWriter, + ($i + 1 + 3), + 'http://schemas.microsoft.com/office/2006/relationships/vbaProject', + 'vbaProject.bin' + ); + ++$i;//increment i if needed for an another relation + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write worksheet relationships to XML format + * + * Numbering is as follows: + * rId1 - Drawings + * rId_hyperlink_x - Hyperlinks + * + * @param PHPExcel_Worksheet $pWorksheet + * @param int $pWorksheetId + * @param boolean $includeCharts Flag indicating if we should write charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = null, $pWorksheetId = 1, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Write drawing relationships? + $d = 0; + if ($includeCharts) { + $charts = $pWorksheet->getChartCollection(); + } else { + $charts = array(); + } + if (($pWorksheet->getDrawingCollection()->count() > 0) || + (count($charts) > 0)) { + $this->_writeRelationship( + $objWriter, + ++$d, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', + '../drawings/drawing' . $pWorksheetId . '.xml' + ); + } + + // Write chart relationships? +// $chartCount = 0; +// $charts = $pWorksheet->getChartCollection(); +// echo 'Chart Rels: ' , count($charts) , '<br />'; +// if (count($charts) > 0) { +// foreach($charts as $chart) { +// $this->_writeRelationship( +// $objWriter, +// ++$d, +// 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', +// '../charts/chart' . ++$chartCount . '.xml' +// ); +// } +// } // - // Write hyperlink relationships? - $i = 1; - foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) { - if (!$hyperlink->isInternal()) { - $this->_writeRelationship( - $objWriter, - '_hyperlink_' . $i, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', - $hyperlink->getUrl(), - 'External' - ); - - ++$i; - } - } - - // Write comments relationship? - $i = 1; - if (count($pWorksheet->getComments()) > 0) { - $this->_writeRelationship( - $objWriter, - '_comments_vml' . $i, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', - '../drawings/vmlDrawing' . $pWorksheetId . '.vml' - ); - - $this->_writeRelationship( - $objWriter, - '_comments' . $i, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', - '../comments' . $pWorksheetId . '.xml' - ); - } - - // Write header/footer relationship? - $i = 1; - if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) { - $this->_writeRelationship( - $objWriter, - '_headerfooter_vml' . $i, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', - '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml' - ); - } - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write drawing relationships to XML format - * - * @param PHPExcel_Worksheet $pWorksheet - * @param int &$chartRef Chart ID - * @param boolean $includeCharts Flag indicating if we should write charts - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // Relationships - $objWriter->startElement('Relationships'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - - // Loop through images and write relationships - $i = 1; - $iterator = $pWorksheet->getDrawingCollection()->getIterator(); - while ($iterator->valid()) { - if ($iterator->current() instanceof PHPExcel_Worksheet_Drawing - || $iterator->current() instanceof PHPExcel_Worksheet_MemoryDrawing) { - // Write relationship for image drawing - $this->_writeRelationship( - $objWriter, - $i, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', - '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename()) - ); - } - - $iterator->next(); - ++$i; - } - - if ($includeCharts) { - // Loop through charts and write relationships - $chartCount = $pWorksheet->getChartCount(); - if ($chartCount > 0) { - for ($c = 0; $c < $chartCount; ++$c) { - $this->_writeRelationship( - $objWriter, - $i++, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', - '../charts/chart' . ++$chartRef . '.xml' - ); - } - } - } - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write header/footer drawing relationships to XML format - * - * @param PHPExcel_Worksheet $pWorksheet - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // Relationships - $objWriter->startElement('Relationships'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - - // Loop through images and write relationships - foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) { - // Write relationship for image drawing - $this->_writeRelationship( - $objWriter, - $key, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', - '../media/' . $value->getIndexedFilename() - ); - } - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write Override content type - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param int $pId Relationship ID. rId will be prepended! - * @param string $pType Relationship type - * @param string $pTarget Relationship target - * @param string $pTargetMode Relationship target mode - * @throws PHPExcel_Writer_Exception - */ - private function _writeRelationship(PHPExcel_Shared_XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '') - { - if ($pType != '' && $pTarget != '') { - // Write relationship - $objWriter->startElement('Relationship'); - $objWriter->writeAttribute('Id', 'rId' . $pId); - $objWriter->writeAttribute('Type', $pType); - $objWriter->writeAttribute('Target', $pTarget); - - if ($pTargetMode != '') { - $objWriter->writeAttribute('TargetMode', $pTargetMode); - } - - $objWriter->endElement(); - } else { - throw new PHPExcel_Writer_Exception("Invalid parameters passed."); - } - } + // Write hyperlink relationships? + $i = 1; + foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) { + if (!$hyperlink->isInternal()) { + $this->_writeRelationship( + $objWriter, + '_hyperlink_' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', + $hyperlink->getUrl(), + 'External' + ); + + ++$i; + } + } + + // Write comments relationship? + $i = 1; + if (count($pWorksheet->getComments()) > 0) { + $this->_writeRelationship( + $objWriter, + '_comments_vml' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', + '../drawings/vmlDrawing' . $pWorksheetId . '.vml' + ); + + $this->_writeRelationship( + $objWriter, + '_comments' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', + '../comments' . $pWorksheetId . '.xml' + ); + } + + // Write header/footer relationship? + $i = 1; + if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) { + $this->_writeRelationship( + $objWriter, + '_headerfooter_vml' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', + '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml' + ); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write drawing relationships to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @param int &$chartRef Chart ID + * @param boolean $includeCharts Flag indicating if we should write charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Loop through images and write relationships + $i = 1; + $iterator = $pWorksheet->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + if ($iterator->current() instanceof PHPExcel_Worksheet_Drawing + || $iterator->current() instanceof PHPExcel_Worksheet_MemoryDrawing) { + // Write relationship for image drawing + $this->_writeRelationship( + $objWriter, + $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', + '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename()) + ); + } + + $iterator->next(); + ++$i; + } + + if ($includeCharts) { + // Loop through charts and write relationships + $chartCount = $pWorksheet->getChartCount(); + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeRelationship( + $objWriter, + $i++, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', + '../charts/chart' . ++$chartRef . '.xml' + ); + } + } + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write header/footer drawing relationships to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Loop through images and write relationships + foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) { + // Write relationship for image drawing + $this->_writeRelationship( + $objWriter, + $key, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', + '../media/' . $value->getIndexedFilename() + ); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write Override content type + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param int $pId Relationship ID. rId will be prepended! + * @param string $pType Relationship type + * @param string $pTarget Relationship target + * @param string $pTargetMode Relationship target mode + * @throws PHPExcel_Writer_Exception + */ + private function _writeRelationship(PHPExcel_Shared_XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '') + { + if ($pType != '' && $pTarget != '') { + // Write relationship + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', 'rId' . $pId); + $objWriter->writeAttribute('Type', $pType); + $objWriter->writeAttribute('Target', $pTarget); + + if ($pTargetMode != '') { + $objWriter->writeAttribute('TargetMode', $pTargetMode); + } + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php index 3cb81804e..555a8fc26 100644 --- a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php +++ b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,43 +35,43 @@ */ class PHPExcel_Writer_Excel2007_RelsRibbon extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Write relationships for additional objects of custom UI (ribbon) - * - * @param PHPExcel $pPHPExcel - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeRibbonRelationships(PHPExcel $pPHPExcel = null){ - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } + /** + * Write relationships for additional objects of custom UI (ribbon) + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeRibbonRelationships(PHPExcel $pPHPExcel = null){ + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); - // Relationships - $objWriter->startElement('Relationships'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - $localRels=$pPHPExcel->getRibbonBinObjects('names'); - if(is_array($localRels)){ - foreach($localRels as $aId=>$aTarget){ - $objWriter->startElement('Relationship'); - $objWriter->writeAttribute('Id', $aId); - $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); - $objWriter->writeAttribute('Target', $aTarget); - $objWriter->endElement();//Relationship - } - } - $objWriter->endElement();//Relationships + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + $localRels=$pPHPExcel->getRibbonBinObjects('names'); + if(is_array($localRels)){ + foreach($localRels as $aId=>$aTarget){ + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', $aId); + $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); + $objWriter->writeAttribute('Target', $aTarget); + $objWriter->endElement();//Relationship + } + } + $objWriter->endElement();//Relationships - // Return - return $objWriter->getData(); + // Return + return $objWriter->getData(); - } + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php index bd2bbb667..992d0e422 100644 --- a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php +++ b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,38 +35,38 @@ */ class PHPExcel_Writer_Excel2007_RelsVBA extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Write relationships for a signed VBA Project - * - * @param PHPExcel $pPHPExcel - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeVBARelationships(PHPExcel $pPHPExcel = null){ - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } + /** + * Write relationships for a signed VBA Project + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeVBARelationships(PHPExcel $pPHPExcel = null){ + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); - // Relationships - $objWriter->startElement('Relationships'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - $objWriter->startElement('Relationship'); - $objWriter->writeAttribute('Id', 'rId1'); - $objWriter->writeAttribute('Type', 'http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature'); - $objWriter->writeAttribute('Target', 'vbaProjectSignature.bin'); - $objWriter->endElement();//Relationship - $objWriter->endElement();//Relationships + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', 'rId1'); + $objWriter->writeAttribute('Type', 'http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature'); + $objWriter->writeAttribute('Target', 'vbaProjectSignature.bin'); + $objWriter->endElement();//Relationship + $objWriter->endElement();//Relationships - // Return - return $objWriter->getData(); + // Return + return $objWriter->getData(); - } + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Classes/PHPExcel/Writer/Excel2007/StringTable.php index 1d7bbfded..dbadb88bd 100644 --- a/Classes/PHPExcel/Writer/Excel2007/StringTable.php +++ b/Classes/PHPExcel/Writer/Excel2007/StringTable.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,285 +35,285 @@ */ class PHPExcel_Writer_Excel2007_StringTable extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Create worksheet stringtable - * - * @param PHPExcel_Worksheet $pSheet Worksheet - * @param string[] $pExistingTable Existing table to eventually merge with - * @return string[] String table for worksheet - * @throws PHPExcel_Writer_Exception - */ - public function createStringTable($pSheet = null, $pExistingTable = null) - { - if ($pSheet !== NULL) { - // Create string lookup table - $aStringTable = array(); - $cellCollection = null; - $aFlippedStringTable = null; // For faster lookup - - // Is an existing table given? - if (($pExistingTable !== NULL) && is_array($pExistingTable)) { - $aStringTable = $pExistingTable; - } - - // Fill index array - $aFlippedStringTable = $this->flipStringTable($aStringTable); - - // Loop through cells - foreach ($pSheet->getCellCollection() as $cellID) { - $cell = $pSheet->getCell($cellID); - $cellValue = $cell->getValue(); - if (!is_object($cellValue) && - ($cellValue !== NULL) && - $cellValue !== '' && - !isset($aFlippedStringTable[$cellValue]) && - ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING2 || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_NULL)) { - $aStringTable[] = $cellValue; - $aFlippedStringTable[$cellValue] = true; - } elseif ($cellValue instanceof PHPExcel_RichText && - ($cellValue !== NULL) && - !isset($aFlippedStringTable[$cellValue->getHashCode()])) { - $aStringTable[] = $cellValue; - $aFlippedStringTable[$cellValue->getHashCode()] = true; - } - } - - // Return - return $aStringTable; - } else { - throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); - } - } - - /** - * Write string table to XML format - * - * @param string[] $pStringTable - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeStringTable($pStringTable = null) - { - if ($pStringTable !== NULL) { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // String table - $objWriter->startElement('sst'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); - $objWriter->writeAttribute('uniqueCount', count($pStringTable)); - - // Loop through string table - foreach ($pStringTable as $textElement) { - $objWriter->startElement('si'); - - if (! $textElement instanceof PHPExcel_RichText) { - $textToWrite = PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $textElement ); - $objWriter->startElement('t'); - if ($textToWrite !== trim($textToWrite)) { - $objWriter->writeAttribute('xml:space', 'preserve'); - } - $objWriter->writeRawData($textToWrite); - $objWriter->endElement(); - } else if ($textElement instanceof PHPExcel_RichText) { - $this->writeRichText($objWriter, $textElement); - } + /** + * Create worksheet stringtable + * + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param string[] $pExistingTable Existing table to eventually merge with + * @return string[] String table for worksheet + * @throws PHPExcel_Writer_Exception + */ + public function createStringTable($pSheet = null, $pExistingTable = null) + { + if ($pSheet !== NULL) { + // Create string lookup table + $aStringTable = array(); + $cellCollection = null; + $aFlippedStringTable = null; // For faster lookup + + // Is an existing table given? + if (($pExistingTable !== NULL) && is_array($pExistingTable)) { + $aStringTable = $pExistingTable; + } + + // Fill index array + $aFlippedStringTable = $this->flipStringTable($aStringTable); + + // Loop through cells + foreach ($pSheet->getCellCollection() as $cellID) { + $cell = $pSheet->getCell($cellID); + $cellValue = $cell->getValue(); + if (!is_object($cellValue) && + ($cellValue !== NULL) && + $cellValue !== '' && + !isset($aFlippedStringTable[$cellValue]) && + ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING2 || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_NULL)) { + $aStringTable[] = $cellValue; + $aFlippedStringTable[$cellValue] = true; + } elseif ($cellValue instanceof PHPExcel_RichText && + ($cellValue !== NULL) && + !isset($aFlippedStringTable[$cellValue->getHashCode()])) { + $aStringTable[] = $cellValue; + $aFlippedStringTable[$cellValue->getHashCode()] = true; + } + } + + // Return + return $aStringTable; + } else { + throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); + } + } + + /** + * Write string table to XML format + * + * @param string[] $pStringTable + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeStringTable($pStringTable = null) + { + if ($pStringTable !== NULL) { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // String table + $objWriter->startElement('sst'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + $objWriter->writeAttribute('uniqueCount', count($pStringTable)); + + // Loop through string table + foreach ($pStringTable as $textElement) { + $objWriter->startElement('si'); + + if (! $textElement instanceof PHPExcel_RichText) { + $textToWrite = PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $textElement ); + $objWriter->startElement('t'); + if ($textToWrite !== trim($textToWrite)) { + $objWriter->writeAttribute('xml:space', 'preserve'); + } + $objWriter->writeRawData($textToWrite); + $objWriter->endElement(); + } else if ($textElement instanceof PHPExcel_RichText) { + $this->writeRichText($objWriter, $textElement); + } $objWriter->endElement(); - } - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } else { - throw new PHPExcel_Writer_Exception("Invalid string table array passed."); - } - } - - /** - * Write Rich Text - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_RichText $pRichText Rich text - * @param string $prefix Optional Namespace prefix - * @throws PHPExcel_Writer_Exception - */ - public function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_RichText $pRichText = null, $prefix=NULL) - { - if ($prefix !== NULL) - $prefix .= ':'; - // Loop through rich text elements - $elements = $pRichText->getRichTextElements(); - foreach ($elements as $element) { - // r - $objWriter->startElement($prefix.'r'); - - // rPr - if ($element instanceof PHPExcel_RichText_Run) { - // rPr - $objWriter->startElement($prefix.'rPr'); - - // rFont - $objWriter->startElement($prefix.'rFont'); - $objWriter->writeAttribute('val', $element->getFont()->getName()); - $objWriter->endElement(); - - // Bold - $objWriter->startElement($prefix.'b'); - $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false')); - $objWriter->endElement(); - - // Italic - $objWriter->startElement($prefix.'i'); - $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false')); - $objWriter->endElement(); - - // Superscript / subscript - if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { - $objWriter->startElement($prefix.'vertAlign'); - if ($element->getFont()->getSuperScript()) { - $objWriter->writeAttribute('val', 'superscript'); - } else if ($element->getFont()->getSubScript()) { - $objWriter->writeAttribute('val', 'subscript'); - } - $objWriter->endElement(); - } - - // Strikethrough - $objWriter->startElement($prefix.'strike'); - $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false')); - $objWriter->endElement(); - - // Color - $objWriter->startElement($prefix.'color'); - $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); - $objWriter->endElement(); - - // Size - $objWriter->startElement($prefix.'sz'); - $objWriter->writeAttribute('val', $element->getFont()->getSize()); - $objWriter->endElement(); - - // Underline - $objWriter->startElement($prefix.'u'); - $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - // t - $objWriter->startElement($prefix.'t'); - $objWriter->writeAttribute('xml:space', 'preserve'); - $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); - $objWriter->endElement(); - - $objWriter->endElement(); - } - } - - /** - * Write Rich Text - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param string|PHPExcel_RichText $pRichText text string or Rich text - * @param string $prefix Optional Namespace prefix - * @throws PHPExcel_Writer_Exception - */ - public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = null, $pRichText = null, $prefix=NULL) - { - if (!$pRichText instanceof PHPExcel_RichText) { - $textRun = $pRichText; - $pRichText = new PHPExcel_RichText(); - $pRichText->createTextRun($textRun); - } - - if ($prefix !== NULL) - $prefix .= ':'; - // Loop through rich text elements - $elements = $pRichText->getRichTextElements(); - foreach ($elements as $element) { - // r - $objWriter->startElement($prefix.'r'); - - // rPr - $objWriter->startElement($prefix.'rPr'); - - // Bold - $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0)); - // Italic - $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); - // Underline - $underlineType = $element->getFont()->getUnderline(); - switch($underlineType) { - case 'single' : - $underlineType = 'sng'; - break; - case 'double' : - $underlineType = 'dbl'; - break; - } - $objWriter->writeAttribute('u', $underlineType); - // Strikethrough - $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike')); - - // rFont - $objWriter->startElement($prefix.'latin'); - $objWriter->writeAttribute('typeface', $element->getFont()->getName()); - $objWriter->endElement(); - - // Superscript / subscript -// if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { -// $objWriter->startElement($prefix.'vertAlign'); -// if ($element->getFont()->getSuperScript()) { -// $objWriter->writeAttribute('val', 'superscript'); -// } else if ($element->getFont()->getSubScript()) { -// $objWriter->writeAttribute('val', 'subscript'); -// } -// $objWriter->endElement(); -// } + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } else { + throw new PHPExcel_Writer_Exception("Invalid string table array passed."); + } + } + + /** + * Write Rich Text + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_RichText $pRichText Rich text + * @param string $prefix Optional Namespace prefix + * @throws PHPExcel_Writer_Exception + */ + public function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_RichText $pRichText = null, $prefix=NULL) + { + if ($prefix !== NULL) + $prefix .= ':'; + // Loop through rich text elements + $elements = $pRichText->getRichTextElements(); + foreach ($elements as $element) { + // r + $objWriter->startElement($prefix.'r'); + + // rPr + if ($element instanceof PHPExcel_RichText_Run) { + // rPr + $objWriter->startElement($prefix.'rPr'); + + // rFont + $objWriter->startElement($prefix.'rFont'); + $objWriter->writeAttribute('val', $element->getFont()->getName()); + $objWriter->endElement(); + + // Bold + $objWriter->startElement($prefix.'b'); + $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false')); + $objWriter->endElement(); + + // Italic + $objWriter->startElement($prefix.'i'); + $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false')); + $objWriter->endElement(); + + // Superscript / subscript + if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { + $objWriter->startElement($prefix.'vertAlign'); + if ($element->getFont()->getSuperScript()) { + $objWriter->writeAttribute('val', 'superscript'); + } else if ($element->getFont()->getSubScript()) { + $objWriter->writeAttribute('val', 'subscript'); + } + $objWriter->endElement(); + } + + // Strikethrough + $objWriter->startElement($prefix.'strike'); + $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false')); + $objWriter->endElement(); + + // Color + $objWriter->startElement($prefix.'color'); + $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); + $objWriter->endElement(); + + // Size + $objWriter->startElement($prefix.'sz'); + $objWriter->writeAttribute('val', $element->getFont()->getSize()); + $objWriter->endElement(); + + // Underline + $objWriter->startElement($prefix.'u'); + $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + // t + $objWriter->startElement($prefix.'t'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Write Rich Text + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string|PHPExcel_RichText $pRichText text string or Rich text + * @param string $prefix Optional Namespace prefix + * @throws PHPExcel_Writer_Exception + */ + public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = null, $pRichText = null, $prefix=NULL) + { + if (!$pRichText instanceof PHPExcel_RichText) { + $textRun = $pRichText; + $pRichText = new PHPExcel_RichText(); + $pRichText->createTextRun($textRun); + } + + if ($prefix !== NULL) + $prefix .= ':'; + // Loop through rich text elements + $elements = $pRichText->getRichTextElements(); + foreach ($elements as $element) { + // r + $objWriter->startElement($prefix.'r'); + + // rPr + $objWriter->startElement($prefix.'rPr'); + + // Bold + $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0)); + // Italic + $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); + // Underline + $underlineType = $element->getFont()->getUnderline(); + switch($underlineType) { + case 'single' : + $underlineType = 'sng'; + break; + case 'double' : + $underlineType = 'dbl'; + break; + } + $objWriter->writeAttribute('u', $underlineType); + // Strikethrough + $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike')); + + // rFont + $objWriter->startElement($prefix.'latin'); + $objWriter->writeAttribute('typeface', $element->getFont()->getName()); + $objWriter->endElement(); + + // Superscript / subscript +// if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { +// $objWriter->startElement($prefix.'vertAlign'); +// if ($element->getFont()->getSuperScript()) { +// $objWriter->writeAttribute('val', 'superscript'); +// } else if ($element->getFont()->getSubScript()) { +// $objWriter->writeAttribute('val', 'subscript'); +// } +// $objWriter->endElement(); +// } // - $objWriter->endElement(); - - // t - $objWriter->startElement($prefix.'t'); -// $objWriter->writeAttribute('xml:space', 'preserve'); // Excel2010 accepts, Excel2007 complains - $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); - $objWriter->endElement(); - - $objWriter->endElement(); - } - } - - /** - * Flip string table (for index searching) - * - * @param array $stringTable Stringtable - * @return array - */ - public function flipStringTable($stringTable = array()) { - // Return value - $returnValue = array(); - - // Loop through stringtable and add flipped items to $returnValue - foreach ($stringTable as $key => $value) { - if (! $value instanceof PHPExcel_RichText) { - $returnValue[$value] = $key; - } else if ($value instanceof PHPExcel_RichText) { - $returnValue[$value->getHashCode()] = $key; - } - } - - // Return - return $returnValue; - } + $objWriter->endElement(); + + // t + $objWriter->startElement($prefix.'t'); +// $objWriter->writeAttribute('xml:space', 'preserve'); // Excel2010 accepts, Excel2007 complains + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Flip string table (for index searching) + * + * @param array $stringTable Stringtable + * @return array + */ + public function flipStringTable($stringTable = array()) { + // Return value + $returnValue = array(); + + // Loop through stringtable and add flipped items to $returnValue + foreach ($stringTable as $key => $value) { + if (! $value instanceof PHPExcel_RichText) { + $returnValue[$value] = $key; + } else if ($value instanceof PHPExcel_RichText) { + $returnValue[$value->getHashCode()] = $key; + } + } + + // Return + return $returnValue; + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Style.php b/Classes/PHPExcel/Writer/Excel2007/Style.php index d0a7ce9f1..527984b9b 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Style.php +++ b/Classes/PHPExcel/Writer/Excel2007/Style.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,673 +35,673 @@ */ class PHPExcel_Writer_Excel2007_Style extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Write styles to XML format - * - * @param PHPExcel $pPHPExcel - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeStyles(PHPExcel $pPHPExcel = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // styleSheet - $objWriter->startElement('styleSheet'); - $objWriter->writeAttribute('xml:space', 'preserve'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); - - // numFmts - $objWriter->startElement('numFmts'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count()); - - // numFmt - for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) { - $this->_writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i); - } - - $objWriter->endElement(); - - // fonts - $objWriter->startElement('fonts'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count()); - - // font - for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) { - $this->_writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i)); - } - - $objWriter->endElement(); - - // fills - $objWriter->startElement('fills'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count()); - - // fill - for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) { - $this->_writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i)); - } - - $objWriter->endElement(); - - // borders - $objWriter->startElement('borders'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count()); - - // border - for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) { - $this->_writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i)); - } - - $objWriter->endElement(); - - // cellStyleXfs - $objWriter->startElement('cellStyleXfs'); - $objWriter->writeAttribute('count', 1); - - // xf - $objWriter->startElement('xf'); - $objWriter->writeAttribute('numFmtId', 0); - $objWriter->writeAttribute('fontId', 0); - $objWriter->writeAttribute('fillId', 0); - $objWriter->writeAttribute('borderId', 0); - $objWriter->endElement(); - - $objWriter->endElement(); - - // cellXfs - $objWriter->startElement('cellXfs'); - $objWriter->writeAttribute('count', count($pPHPExcel->getCellXfCollection())); - - // xf - foreach ($pPHPExcel->getCellXfCollection() as $cellXf) { - $this->_writeCellStyleXf($objWriter, $cellXf, $pPHPExcel); - } - - $objWriter->endElement(); - - // cellStyles - $objWriter->startElement('cellStyles'); - $objWriter->writeAttribute('count', 1); - - // cellStyle - $objWriter->startElement('cellStyle'); - $objWriter->writeAttribute('name', 'Normal'); - $objWriter->writeAttribute('xfId', 0); - $objWriter->writeAttribute('builtinId', 0); - $objWriter->endElement(); - - $objWriter->endElement(); - - // dxfs - $objWriter->startElement('dxfs'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count()); - - // dxf - for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) { - $this->_writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle()); - } - - $objWriter->endElement(); - - // tableStyles - $objWriter->startElement('tableStyles'); - $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9'); - $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1'); - $objWriter->endElement(); - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write Fill - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Style_Fill $pFill Fill style - * @throws PHPExcel_Writer_Exception - */ - private function _writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) - { - // Check if this is a pattern type or gradient type - if ($pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR || - $pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_PATH) { - // Gradient fill - $this->_writeGradientFill($objWriter, $pFill); - } elseif($pFill->getFillType() !== NULL) { - // Pattern fill - $this->_writePatternFill($objWriter, $pFill); - } - } - - /** - * Write Gradient Fill - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Style_Fill $pFill Fill style - * @throws PHPExcel_Writer_Exception - */ - private function _writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) - { - // fill - $objWriter->startElement('fill'); - - // gradientFill - $objWriter->startElement('gradientFill'); - $objWriter->writeAttribute('type', $pFill->getFillType()); - $objWriter->writeAttribute('degree', $pFill->getRotation()); - - // stop - $objWriter->startElement('stop'); - $objWriter->writeAttribute('position', '0'); - - // color - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); - $objWriter->endElement(); - - $objWriter->endElement(); - - // stop - $objWriter->startElement('stop'); - $objWriter->writeAttribute('position', '1'); - - // color - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); - $objWriter->endElement(); - - $objWriter->endElement(); - - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write Pattern Fill - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Style_Fill $pFill Fill style - * @throws PHPExcel_Writer_Exception - */ - private function _writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) - { - // fill - $objWriter->startElement('fill'); - - // patternFill - $objWriter->startElement('patternFill'); - $objWriter->writeAttribute('patternType', $pFill->getFillType()); - - if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { - // fgColor - if ($pFill->getStartColor()->getARGB()) { - $objWriter->startElement('fgColor'); - $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); - $objWriter->endElement(); - } - } - if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { - // bgColor - if ($pFill->getEndColor()->getARGB()) { - $objWriter->startElement('bgColor'); - $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); - $objWriter->endElement(); - } - } - - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write Font - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Style_Font $pFont Font style - * @throws PHPExcel_Writer_Exception - */ - private function _writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Font $pFont = null) - { - // font - $objWriter->startElement('font'); - // Weird! The order of these elements actually makes a difference when opening Excel2007 - // files in Excel2003 with the compatibility pack. It's not documented behaviour, - // and makes for a real WTF! - - // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does - // for conditional formatting). Otherwise it will apparently not be picked up in conditional - // formatting style dialog - if ($pFont->getBold() !== NULL) { - $objWriter->startElement('b'); - $objWriter->writeAttribute('val', $pFont->getBold() ? '1' : '0'); - $objWriter->endElement(); - } - - // Italic - if ($pFont->getItalic() !== NULL) { - $objWriter->startElement('i'); - $objWriter->writeAttribute('val', $pFont->getItalic() ? '1' : '0'); - $objWriter->endElement(); - } - - // Strikethrough - if ($pFont->getStrikethrough() !== NULL) { - $objWriter->startElement('strike'); - $objWriter->writeAttribute('val', $pFont->getStrikethrough() ? '1' : '0'); - $objWriter->endElement(); - } - - // Underline - if ($pFont->getUnderline() !== NULL) { - $objWriter->startElement('u'); - $objWriter->writeAttribute('val', $pFont->getUnderline()); - $objWriter->endElement(); - } - - // Superscript / subscript - if ($pFont->getSuperScript() === TRUE || $pFont->getSubScript() === TRUE) { - $objWriter->startElement('vertAlign'); - if ($pFont->getSuperScript() === TRUE) { - $objWriter->writeAttribute('val', 'superscript'); - } else if ($pFont->getSubScript() === TRUE) { - $objWriter->writeAttribute('val', 'subscript'); - } - $objWriter->endElement(); - } - - // Size - if ($pFont->getSize() !== NULL) { - $objWriter->startElement('sz'); - $objWriter->writeAttribute('val', $pFont->getSize()); - $objWriter->endElement(); - } - - // Foreground color - if ($pFont->getColor()->getARGB() !== NULL) { - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $pFont->getColor()->getARGB()); - $objWriter->endElement(); - } - - // Name - if ($pFont->getName() !== NULL) { - $objWriter->startElement('name'); - $objWriter->writeAttribute('val', $pFont->getName()); - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - - /** - * Write Border - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Style_Borders $pBorders Borders style - * @throws PHPExcel_Writer_Exception - */ - private function _writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Borders $pBorders = null) - { - // Write border - $objWriter->startElement('border'); - // Diagonal? - switch ($pBorders->getDiagonalDirection()) { - case PHPExcel_Style_Borders::DIAGONAL_UP: - $objWriter->writeAttribute('diagonalUp', 'true'); - $objWriter->writeAttribute('diagonalDown', 'false'); - break; - case PHPExcel_Style_Borders::DIAGONAL_DOWN: - $objWriter->writeAttribute('diagonalUp', 'false'); - $objWriter->writeAttribute('diagonalDown', 'true'); - break; - case PHPExcel_Style_Borders::DIAGONAL_BOTH: - $objWriter->writeAttribute('diagonalUp', 'true'); - $objWriter->writeAttribute('diagonalDown', 'true'); - break; - } - - // BorderPr - $this->_writeBorderPr($objWriter, 'left', $pBorders->getLeft()); - $this->_writeBorderPr($objWriter, 'right', $pBorders->getRight()); - $this->_writeBorderPr($objWriter, 'top', $pBorders->getTop()); - $this->_writeBorderPr($objWriter, 'bottom', $pBorders->getBottom()); - $this->_writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal()); - $objWriter->endElement(); - } - - /** - * Write Cell Style Xf - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Style $pStyle Style - * @param PHPExcel $pPHPExcel Workbook - * @throws PHPExcel_Writer_Exception - */ - private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null, PHPExcel $pPHPExcel = null) - { - // xf - $objWriter->startElement('xf'); - $objWriter->writeAttribute('xfId', 0); - $objWriter->writeAttribute('fontId', (int)$this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode())); + /** + * Write styles to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeStyles(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // styleSheet + $objWriter->startElement('styleSheet'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + + // numFmts + $objWriter->startElement('numFmts'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count()); + + // numFmt + for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) { + $this->_writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i); + } + + $objWriter->endElement(); + + // fonts + $objWriter->startElement('fonts'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count()); + + // font + for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) { + $this->_writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i)); + } + + $objWriter->endElement(); + + // fills + $objWriter->startElement('fills'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count()); + + // fill + for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) { + $this->_writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i)); + } + + $objWriter->endElement(); + + // borders + $objWriter->startElement('borders'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count()); + + // border + for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) { + $this->_writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i)); + } + + $objWriter->endElement(); + + // cellStyleXfs + $objWriter->startElement('cellStyleXfs'); + $objWriter->writeAttribute('count', 1); + + // xf + $objWriter->startElement('xf'); + $objWriter->writeAttribute('numFmtId', 0); + $objWriter->writeAttribute('fontId', 0); + $objWriter->writeAttribute('fillId', 0); + $objWriter->writeAttribute('borderId', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + // cellXfs + $objWriter->startElement('cellXfs'); + $objWriter->writeAttribute('count', count($pPHPExcel->getCellXfCollection())); + + // xf + foreach ($pPHPExcel->getCellXfCollection() as $cellXf) { + $this->_writeCellStyleXf($objWriter, $cellXf, $pPHPExcel); + } + + $objWriter->endElement(); + + // cellStyles + $objWriter->startElement('cellStyles'); + $objWriter->writeAttribute('count', 1); + + // cellStyle + $objWriter->startElement('cellStyle'); + $objWriter->writeAttribute('name', 'Normal'); + $objWriter->writeAttribute('xfId', 0); + $objWriter->writeAttribute('builtinId', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + // dxfs + $objWriter->startElement('dxfs'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count()); + + // dxf + for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) { + $this->_writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle()); + } + + $objWriter->endElement(); + + // tableStyles + $objWriter->startElement('tableStyles'); + $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9'); + $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write Fill + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Fill $pFill Fill style + * @throws PHPExcel_Writer_Exception + */ + private function _writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + { + // Check if this is a pattern type or gradient type + if ($pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR || + $pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_PATH) { + // Gradient fill + $this->_writeGradientFill($objWriter, $pFill); + } elseif($pFill->getFillType() !== NULL) { + // Pattern fill + $this->_writePatternFill($objWriter, $pFill); + } + } + + /** + * Write Gradient Fill + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Fill $pFill Fill style + * @throws PHPExcel_Writer_Exception + */ + private function _writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + { + // fill + $objWriter->startElement('fill'); + + // gradientFill + $objWriter->startElement('gradientFill'); + $objWriter->writeAttribute('type', $pFill->getFillType()); + $objWriter->writeAttribute('degree', $pFill->getRotation()); + + // stop + $objWriter->startElement('stop'); + $objWriter->writeAttribute('position', '0'); + + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + + // stop + $objWriter->startElement('stop'); + $objWriter->writeAttribute('position', '1'); + + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Pattern Fill + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Fill $pFill Fill style + * @throws PHPExcel_Writer_Exception + */ + private function _writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + { + // fill + $objWriter->startElement('fill'); + + // patternFill + $objWriter->startElement('patternFill'); + $objWriter->writeAttribute('patternType', $pFill->getFillType()); + + if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { + // fgColor + if ($pFill->getStartColor()->getARGB()) { + $objWriter->startElement('fgColor'); + $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); + $objWriter->endElement(); + } + } + if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { + // bgColor + if ($pFill->getEndColor()->getARGB()) { + $objWriter->startElement('bgColor'); + $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Font + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Font $pFont Font style + * @throws PHPExcel_Writer_Exception + */ + private function _writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Font $pFont = null) + { + // font + $objWriter->startElement('font'); + // Weird! The order of these elements actually makes a difference when opening Excel2007 + // files in Excel2003 with the compatibility pack. It's not documented behaviour, + // and makes for a real WTF! + + // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does + // for conditional formatting). Otherwise it will apparently not be picked up in conditional + // formatting style dialog + if ($pFont->getBold() !== NULL) { + $objWriter->startElement('b'); + $objWriter->writeAttribute('val', $pFont->getBold() ? '1' : '0'); + $objWriter->endElement(); + } + + // Italic + if ($pFont->getItalic() !== NULL) { + $objWriter->startElement('i'); + $objWriter->writeAttribute('val', $pFont->getItalic() ? '1' : '0'); + $objWriter->endElement(); + } + + // Strikethrough + if ($pFont->getStrikethrough() !== NULL) { + $objWriter->startElement('strike'); + $objWriter->writeAttribute('val', $pFont->getStrikethrough() ? '1' : '0'); + $objWriter->endElement(); + } + + // Underline + if ($pFont->getUnderline() !== NULL) { + $objWriter->startElement('u'); + $objWriter->writeAttribute('val', $pFont->getUnderline()); + $objWriter->endElement(); + } + + // Superscript / subscript + if ($pFont->getSuperScript() === TRUE || $pFont->getSubScript() === TRUE) { + $objWriter->startElement('vertAlign'); + if ($pFont->getSuperScript() === TRUE) { + $objWriter->writeAttribute('val', 'superscript'); + } else if ($pFont->getSubScript() === TRUE) { + $objWriter->writeAttribute('val', 'subscript'); + } + $objWriter->endElement(); + } + + // Size + if ($pFont->getSize() !== NULL) { + $objWriter->startElement('sz'); + $objWriter->writeAttribute('val', $pFont->getSize()); + $objWriter->endElement(); + } + + // Foreground color + if ($pFont->getColor()->getARGB() !== NULL) { + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFont->getColor()->getARGB()); + $objWriter->endElement(); + } + + // Name + if ($pFont->getName() !== NULL) { + $objWriter->startElement('name'); + $objWriter->writeAttribute('val', $pFont->getName()); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Border + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Borders $pBorders Borders style + * @throws PHPExcel_Writer_Exception + */ + private function _writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Borders $pBorders = null) + { + // Write border + $objWriter->startElement('border'); + // Diagonal? + switch ($pBorders->getDiagonalDirection()) { + case PHPExcel_Style_Borders::DIAGONAL_UP: + $objWriter->writeAttribute('diagonalUp', 'true'); + $objWriter->writeAttribute('diagonalDown', 'false'); + break; + case PHPExcel_Style_Borders::DIAGONAL_DOWN: + $objWriter->writeAttribute('diagonalUp', 'false'); + $objWriter->writeAttribute('diagonalDown', 'true'); + break; + case PHPExcel_Style_Borders::DIAGONAL_BOTH: + $objWriter->writeAttribute('diagonalUp', 'true'); + $objWriter->writeAttribute('diagonalDown', 'true'); + break; + } + + // BorderPr + $this->_writeBorderPr($objWriter, 'left', $pBorders->getLeft()); + $this->_writeBorderPr($objWriter, 'right', $pBorders->getRight()); + $this->_writeBorderPr($objWriter, 'top', $pBorders->getTop()); + $this->_writeBorderPr($objWriter, 'bottom', $pBorders->getBottom()); + $this->_writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal()); + $objWriter->endElement(); + } + + /** + * Write Cell Style Xf + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style $pStyle Style + * @param PHPExcel $pPHPExcel Workbook + * @throws PHPExcel_Writer_Exception + */ + private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null, PHPExcel $pPHPExcel = null) + { + // xf + $objWriter->startElement('xf'); + $objWriter->writeAttribute('xfId', 0); + $objWriter->writeAttribute('fontId', (int)$this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode())); if ($pStyle->getQuotePrefix()) { - $objWriter->writeAttribute('quotePrefix', 1); + $objWriter->writeAttribute('quotePrefix', 1); + } + + if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) { + $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164) ); + } else { + $objWriter->writeAttribute('numFmtId', (int)$pStyle->getNumberFormat()->getBuiltInFormatCode()); + } + + $objWriter->writeAttribute('fillId', (int)$this->getParentWriter()->getFillHashTable()->getIndexForHashCode($pStyle->getFill()->getHashCode())); + $objWriter->writeAttribute('borderId', (int)$this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($pStyle->getBorders()->getHashCode())); + + // Apply styles? + $objWriter->writeAttribute('applyFont', ($pPHPExcel->getDefaultStyle()->getFont()->getHashCode() != $pStyle->getFont()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyNumberFormat', ($pPHPExcel->getDefaultStyle()->getNumberFormat()->getHashCode() != $pStyle->getNumberFormat()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyFill', ($pPHPExcel->getDefaultStyle()->getFill()->getHashCode() != $pStyle->getFill()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyBorder', ($pPHPExcel->getDefaultStyle()->getBorders()->getHashCode() != $pStyle->getBorders()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyAlignment', ($pPHPExcel->getDefaultStyle()->getAlignment()->getHashCode() != $pStyle->getAlignment()->getHashCode()) ? '1' : '0'); + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('applyProtection', 'true'); + } + + // alignment + $objWriter->startElement('alignment'); + $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); + $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); + + $textRotation = 0; + if ($pStyle->getAlignment()->getTextRotation() >= 0) { + $textRotation = $pStyle->getAlignment()->getTextRotation(); + } else if ($pStyle->getAlignment()->getTextRotation() < 0) { + $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); + } + $objWriter->writeAttribute('textRotation', $textRotation); + + $objWriter->writeAttribute('wrapText', ($pStyle->getAlignment()->getWrapText() ? 'true' : 'false')); + $objWriter->writeAttribute('shrinkToFit', ($pStyle->getAlignment()->getShrinkToFit() ? 'true' : 'false')); + + if ($pStyle->getAlignment()->getIndent() > 0) { + $objWriter->writeAttribute('indent', $pStyle->getAlignment()->getIndent()); + } + if ($pStyle->getAlignment()->getReadorder() > 0) { + $objWriter->writeAttribute('readingOrder', $pStyle->getAlignment()->getReadorder()); + } + $objWriter->endElement(); + + // protection + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->startElement('protection'); + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + if ($pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Cell Style Dxf + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style $pStyle Style + * @throws PHPExcel_Writer_Exception + */ + private function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null) + { + // dxf + $objWriter->startElement('dxf'); + + // font + $this->_writeFont($objWriter, $pStyle->getFont()); + + // numFmt + $this->_writeNumFmt($objWriter, $pStyle->getNumberFormat()); + + // fill + $this->_writeFill($objWriter, $pStyle->getFill()); + + // alignment + $objWriter->startElement('alignment'); + if ($pStyle->getAlignment()->getHorizontal() !== NULL) { + $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); + } + if ($pStyle->getAlignment()->getVertical() !== NULL) { + $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); + } + + if ($pStyle->getAlignment()->getTextRotation() !== NULL) { + $textRotation = 0; + if ($pStyle->getAlignment()->getTextRotation() >= 0) { + $textRotation = $pStyle->getAlignment()->getTextRotation(); + } else if ($pStyle->getAlignment()->getTextRotation() < 0) { + $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); + } + $objWriter->writeAttribute('textRotation', $textRotation); + } + $objWriter->endElement(); + + // border + $this->_writeBorder($objWriter, $pStyle->getBorders()); + + // protection + if (($pStyle->getProtection()->getLocked() !== NULL) || + ($pStyle->getProtection()->getHidden() !== NULL)) { + if ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT || + $pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->startElement('protection'); + if (($pStyle->getProtection()->getLocked() !== NULL) && + ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { + $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + if (($pStyle->getProtection()->getHidden() !== NULL) && + ($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { + $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } + + /** + * Write BorderPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pName Element name + * @param PHPExcel_Style_Border $pBorder Border style + * @throws PHPExcel_Writer_Exception + */ + private function _writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pName = 'left', PHPExcel_Style_Border $pBorder = null) + { + // Write BorderPr + if ($pBorder->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) { + $objWriter->startElement($pName); + $objWriter->writeAttribute('style', $pBorder->getBorderStyle()); + + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pBorder->getColor()->getARGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Write NumberFormat + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_NumberFormat $pNumberFormat Number Format + * @param int $pId Number Format identifier + * @throws PHPExcel_Writer_Exception + */ + private function _writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_NumberFormat $pNumberFormat = null, $pId = 0) + { + // Translate formatcode + $formatCode = $pNumberFormat->getFormatCode(); + + // numFmt + if ($formatCode !== NULL) { + $objWriter->startElement('numFmt'); + $objWriter->writeAttribute('numFmtId', ($pId + 164)); + $objWriter->writeAttribute('formatCode', $formatCode); + $objWriter->endElement(); + } + } + + /** + * Get an array of all styles + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style[] All styles in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allStyles(PHPExcel $pPHPExcel = null) + { + $aStyles = $pPHPExcel->getCellXfCollection(); + + return $aStyles; + } + + /** + * Get an array of all conditional styles + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Conditional[] All conditional styles in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allConditionalStyles(PHPExcel $pPHPExcel = null) + { + // Get an array of all styles + $aStyles = array(); + + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + foreach ($pPHPExcel->getSheet($i)->getConditionalStylesCollection() as $conditionalStyles) { + foreach ($conditionalStyles as $conditionalStyle) { + $aStyles[] = $conditionalStyle; + } + } + } + + return $aStyles; + } + + /** + * Get an array of all fills + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Fill[] All fills in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allFills(PHPExcel $pPHPExcel = null) + { + // Get an array of unique fills + $aFills = array(); + + // Two first fills are predefined + $fill0 = new PHPExcel_Style_Fill(); + $fill0->setFillType(PHPExcel_Style_Fill::FILL_NONE); + $aFills[] = $fill0; + + $fill1 = new PHPExcel_Style_Fill(); + $fill1->setFillType(PHPExcel_Style_Fill::FILL_PATTERN_GRAY125); + $aFills[] = $fill1; + // The remaining fills + $aStyles = $this->allStyles($pPHPExcel); + foreach ($aStyles as $style) { + if (!array_key_exists($style->getFill()->getHashCode(), $aFills)) { + $aFills[ $style->getFill()->getHashCode() ] = $style->getFill(); + } + } + + return $aFills; + } + + /** + * Get an array of all fonts + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Font[] All fonts in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allFonts(PHPExcel $pPHPExcel = null) + { + // Get an array of unique fonts + $aFonts = array(); + $aStyles = $this->allStyles($pPHPExcel); + + foreach ($aStyles as $style) { + if (!array_key_exists($style->getFont()->getHashCode(), $aFonts)) { + $aFonts[ $style->getFont()->getHashCode() ] = $style->getFont(); + } + } + + return $aFonts; + } + + /** + * Get an array of all borders + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Borders[] All borders in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allBorders(PHPExcel $pPHPExcel = null) + { + // Get an array of unique borders + $aBorders = array(); + $aStyles = $this->allStyles($pPHPExcel); + + foreach ($aStyles as $style) { + if (!array_key_exists($style->getBorders()->getHashCode(), $aBorders)) { + $aBorders[ $style->getBorders()->getHashCode() ] = $style->getBorders(); + } + } + + return $aBorders; + } + + /** + * Get an array of all number formats + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_NumberFormat[] All number formats in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allNumberFormats(PHPExcel $pPHPExcel = null) + { + // Get an array of unique number formats + $aNumFmts = array(); + $aStyles = $this->allStyles($pPHPExcel); + + foreach ($aStyles as $style) { + if ($style->getNumberFormat()->getBuiltInFormatCode() === false && !array_key_exists($style->getNumberFormat()->getHashCode(), $aNumFmts)) { + $aNumFmts[ $style->getNumberFormat()->getHashCode() ] = $style->getNumberFormat(); } + } - if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) { - $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164) ); - } else { - $objWriter->writeAttribute('numFmtId', (int)$pStyle->getNumberFormat()->getBuiltInFormatCode()); - } - - $objWriter->writeAttribute('fillId', (int)$this->getParentWriter()->getFillHashTable()->getIndexForHashCode($pStyle->getFill()->getHashCode())); - $objWriter->writeAttribute('borderId', (int)$this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($pStyle->getBorders()->getHashCode())); - - // Apply styles? - $objWriter->writeAttribute('applyFont', ($pPHPExcel->getDefaultStyle()->getFont()->getHashCode() != $pStyle->getFont()->getHashCode()) ? '1' : '0'); - $objWriter->writeAttribute('applyNumberFormat', ($pPHPExcel->getDefaultStyle()->getNumberFormat()->getHashCode() != $pStyle->getNumberFormat()->getHashCode()) ? '1' : '0'); - $objWriter->writeAttribute('applyFill', ($pPHPExcel->getDefaultStyle()->getFill()->getHashCode() != $pStyle->getFill()->getHashCode()) ? '1' : '0'); - $objWriter->writeAttribute('applyBorder', ($pPHPExcel->getDefaultStyle()->getBorders()->getHashCode() != $pStyle->getBorders()->getHashCode()) ? '1' : '0'); - $objWriter->writeAttribute('applyAlignment', ($pPHPExcel->getDefaultStyle()->getAlignment()->getHashCode() != $pStyle->getAlignment()->getHashCode()) ? '1' : '0'); - if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { - $objWriter->writeAttribute('applyProtection', 'true'); - } - - // alignment - $objWriter->startElement('alignment'); - $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); - $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); - - $textRotation = 0; - if ($pStyle->getAlignment()->getTextRotation() >= 0) { - $textRotation = $pStyle->getAlignment()->getTextRotation(); - } else if ($pStyle->getAlignment()->getTextRotation() < 0) { - $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); - } - $objWriter->writeAttribute('textRotation', $textRotation); - - $objWriter->writeAttribute('wrapText', ($pStyle->getAlignment()->getWrapText() ? 'true' : 'false')); - $objWriter->writeAttribute('shrinkToFit', ($pStyle->getAlignment()->getShrinkToFit() ? 'true' : 'false')); - - if ($pStyle->getAlignment()->getIndent() > 0) { - $objWriter->writeAttribute('indent', $pStyle->getAlignment()->getIndent()); - } - if ($pStyle->getAlignment()->getReadorder() > 0) { - $objWriter->writeAttribute('readingOrder', $pStyle->getAlignment()->getReadorder()); - } - $objWriter->endElement(); - - // protection - if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { - $objWriter->startElement('protection'); - if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { - $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); - } - if ($pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { - $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); - } - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - - /** - * Write Cell Style Dxf - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Style $pStyle Style - * @throws PHPExcel_Writer_Exception - */ - private function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null) - { - // dxf - $objWriter->startElement('dxf'); - - // font - $this->_writeFont($objWriter, $pStyle->getFont()); - - // numFmt - $this->_writeNumFmt($objWriter, $pStyle->getNumberFormat()); - - // fill - $this->_writeFill($objWriter, $pStyle->getFill()); - - // alignment - $objWriter->startElement('alignment'); - if ($pStyle->getAlignment()->getHorizontal() !== NULL) { - $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); - } - if ($pStyle->getAlignment()->getVertical() !== NULL) { - $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); - } - - if ($pStyle->getAlignment()->getTextRotation() !== NULL) { - $textRotation = 0; - if ($pStyle->getAlignment()->getTextRotation() >= 0) { - $textRotation = $pStyle->getAlignment()->getTextRotation(); - } else if ($pStyle->getAlignment()->getTextRotation() < 0) { - $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); - } - $objWriter->writeAttribute('textRotation', $textRotation); - } - $objWriter->endElement(); - - // border - $this->_writeBorder($objWriter, $pStyle->getBorders()); - - // protection - if (($pStyle->getProtection()->getLocked() !== NULL) || - ($pStyle->getProtection()->getHidden() !== NULL)) { - if ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT || - $pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT) { - $objWriter->startElement('protection'); - if (($pStyle->getProtection()->getLocked() !== NULL) && - ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { - $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); - } - if (($pStyle->getProtection()->getHidden() !== NULL) && - ($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { - $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); - } - $objWriter->endElement(); - } - } - - $objWriter->endElement(); - } - - /** - * Write BorderPr - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param string $pName Element name - * @param PHPExcel_Style_Border $pBorder Border style - * @throws PHPExcel_Writer_Exception - */ - private function _writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pName = 'left', PHPExcel_Style_Border $pBorder = null) - { - // Write BorderPr - if ($pBorder->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) { - $objWriter->startElement($pName); - $objWriter->writeAttribute('style', $pBorder->getBorderStyle()); - - // color - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $pBorder->getColor()->getARGB()); - $objWriter->endElement(); - - $objWriter->endElement(); - } - } - - /** - * Write NumberFormat - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Style_NumberFormat $pNumberFormat Number Format - * @param int $pId Number Format identifier - * @throws PHPExcel_Writer_Exception - */ - private function _writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_NumberFormat $pNumberFormat = null, $pId = 0) - { - // Translate formatcode - $formatCode = $pNumberFormat->getFormatCode(); - - // numFmt - if ($formatCode !== NULL) { - $objWriter->startElement('numFmt'); - $objWriter->writeAttribute('numFmtId', ($pId + 164)); - $objWriter->writeAttribute('formatCode', $formatCode); - $objWriter->endElement(); - } - } - - /** - * Get an array of all styles - * - * @param PHPExcel $pPHPExcel - * @return PHPExcel_Style[] All styles in PHPExcel - * @throws PHPExcel_Writer_Exception - */ - public function allStyles(PHPExcel $pPHPExcel = null) - { - $aStyles = $pPHPExcel->getCellXfCollection(); - - return $aStyles; - } - - /** - * Get an array of all conditional styles - * - * @param PHPExcel $pPHPExcel - * @return PHPExcel_Style_Conditional[] All conditional styles in PHPExcel - * @throws PHPExcel_Writer_Exception - */ - public function allConditionalStyles(PHPExcel $pPHPExcel = null) - { - // Get an array of all styles - $aStyles = array(); - - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - foreach ($pPHPExcel->getSheet($i)->getConditionalStylesCollection() as $conditionalStyles) { - foreach ($conditionalStyles as $conditionalStyle) { - $aStyles[] = $conditionalStyle; - } - } - } - - return $aStyles; - } - - /** - * Get an array of all fills - * - * @param PHPExcel $pPHPExcel - * @return PHPExcel_Style_Fill[] All fills in PHPExcel - * @throws PHPExcel_Writer_Exception - */ - public function allFills(PHPExcel $pPHPExcel = null) - { - // Get an array of unique fills - $aFills = array(); - - // Two first fills are predefined - $fill0 = new PHPExcel_Style_Fill(); - $fill0->setFillType(PHPExcel_Style_Fill::FILL_NONE); - $aFills[] = $fill0; - - $fill1 = new PHPExcel_Style_Fill(); - $fill1->setFillType(PHPExcel_Style_Fill::FILL_PATTERN_GRAY125); - $aFills[] = $fill1; - // The remaining fills - $aStyles = $this->allStyles($pPHPExcel); - foreach ($aStyles as $style) { - if (!array_key_exists($style->getFill()->getHashCode(), $aFills)) { - $aFills[ $style->getFill()->getHashCode() ] = $style->getFill(); - } - } - - return $aFills; - } - - /** - * Get an array of all fonts - * - * @param PHPExcel $pPHPExcel - * @return PHPExcel_Style_Font[] All fonts in PHPExcel - * @throws PHPExcel_Writer_Exception - */ - public function allFonts(PHPExcel $pPHPExcel = null) - { - // Get an array of unique fonts - $aFonts = array(); - $aStyles = $this->allStyles($pPHPExcel); - - foreach ($aStyles as $style) { - if (!array_key_exists($style->getFont()->getHashCode(), $aFonts)) { - $aFonts[ $style->getFont()->getHashCode() ] = $style->getFont(); - } - } - - return $aFonts; - } - - /** - * Get an array of all borders - * - * @param PHPExcel $pPHPExcel - * @return PHPExcel_Style_Borders[] All borders in PHPExcel - * @throws PHPExcel_Writer_Exception - */ - public function allBorders(PHPExcel $pPHPExcel = null) - { - // Get an array of unique borders - $aBorders = array(); - $aStyles = $this->allStyles($pPHPExcel); - - foreach ($aStyles as $style) { - if (!array_key_exists($style->getBorders()->getHashCode(), $aBorders)) { - $aBorders[ $style->getBorders()->getHashCode() ] = $style->getBorders(); - } - } - - return $aBorders; - } - - /** - * Get an array of all number formats - * - * @param PHPExcel $pPHPExcel - * @return PHPExcel_Style_NumberFormat[] All number formats in PHPExcel - * @throws PHPExcel_Writer_Exception - */ - public function allNumberFormats(PHPExcel $pPHPExcel = null) - { - // Get an array of unique number formats - $aNumFmts = array(); - $aStyles = $this->allStyles($pPHPExcel); - - foreach ($aStyles as $style) { - if ($style->getNumberFormat()->getBuiltInFormatCode() === false && !array_key_exists($style->getNumberFormat()->getHashCode(), $aNumFmts)) { - $aNumFmts[ $style->getNumberFormat()->getHashCode() ] = $style->getNumberFormat(); - } - } - - return $aNumFmts; - } + return $aNumFmts; + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Theme.php b/Classes/PHPExcel/Writer/Excel2007/Theme.php index f9c2fd1d0..281cd5fef 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Theme.php +++ b/Classes/PHPExcel/Writer/Excel2007/Theme.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,837 +35,837 @@ */ class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Map of Major fonts to write - * @static array of string - * - */ - private static $_majorFonts = array( - 'Jpan' => 'MS Pゴシック', - 'Hang' => '맑은 고딕', - 'Hans' => '宋体', - 'Hant' => '新細明體', - 'Arab' => 'Times New Roman', - 'Hebr' => 'Times New Roman', - 'Thai' => 'Tahoma', - 'Ethi' => 'Nyala', - 'Beng' => 'Vrinda', - 'Gujr' => 'Shruti', - 'Khmr' => 'MoolBoran', - 'Knda' => 'Tunga', - 'Guru' => 'Raavi', - 'Cans' => 'Euphemia', - 'Cher' => 'Plantagenet Cherokee', - 'Yiii' => 'Microsoft Yi Baiti', - 'Tibt' => 'Microsoft Himalaya', - 'Thaa' => 'MV Boli', - 'Deva' => 'Mangal', - 'Telu' => 'Gautami', - 'Taml' => 'Latha', - 'Syrc' => 'Estrangelo Edessa', - 'Orya' => 'Kalinga', - 'Mlym' => 'Kartika', - 'Laoo' => 'DokChampa', - 'Sinh' => 'Iskoola Pota', - 'Mong' => 'Mongolian Baiti', - 'Viet' => 'Times New Roman', - 'Uigh' => 'Microsoft Uighur', - 'Geor' => 'Sylfaen', - ); - - /** - * Map of Minor fonts to write - * @static array of string - * - */ - private static $_minorFonts = array( - 'Jpan' => 'MS Pゴシック', - 'Hang' => '맑은 고딕', - 'Hans' => '宋体', - 'Hant' => '新細明體', - 'Arab' => 'Arial', - 'Hebr' => 'Arial', - 'Thai' => 'Tahoma', - 'Ethi' => 'Nyala', - 'Beng' => 'Vrinda', - 'Gujr' => 'Shruti', - 'Khmr' => 'DaunPenh', - 'Knda' => 'Tunga', - 'Guru' => 'Raavi', - 'Cans' => 'Euphemia', - 'Cher' => 'Plantagenet Cherokee', - 'Yiii' => 'Microsoft Yi Baiti', - 'Tibt' => 'Microsoft Himalaya', - 'Thaa' => 'MV Boli', - 'Deva' => 'Mangal', - 'Telu' => 'Gautami', - 'Taml' => 'Latha', - 'Syrc' => 'Estrangelo Edessa', - 'Orya' => 'Kalinga', - 'Mlym' => 'Kartika', - 'Laoo' => 'DokChampa', - 'Sinh' => 'Iskoola Pota', - 'Mong' => 'Mongolian Baiti', - 'Viet' => 'Arial', - 'Uigh' => 'Microsoft Uighur', - 'Geor' => 'Sylfaen', - ); - - /** - * Map of core colours - * @static array of string - * - */ - private static $_colourScheme = array( - 'dk2' => '1F497D', - 'lt2' => 'EEECE1', - 'accent1' => '4F81BD', - 'accent2' => 'C0504D', - 'accent3' => '9BBB59', - 'accent4' => '8064A2', - 'accent5' => '4BACC6', - 'accent6' => 'F79646', - 'hlink' => '0000FF', - 'folHlink' => '800080', - ); - - /** - * Write theme to XML format - * - * @param PHPExcel $pPHPExcel - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeTheme(PHPExcel $pPHPExcel = null) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // a:theme - $objWriter->startElement('a:theme'); - $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); - $objWriter->writeAttribute('name', 'Office Theme'); - - // a:themeElements - $objWriter->startElement('a:themeElements'); - - // a:clrScheme - $objWriter->startElement('a:clrScheme'); - $objWriter->writeAttribute('name', 'Office'); - - // a:dk1 - $objWriter->startElement('a:dk1'); - - // a:sysClr - $objWriter->startElement('a:sysClr'); - $objWriter->writeAttribute('val', 'windowText'); - $objWriter->writeAttribute('lastClr', '000000'); - $objWriter->endElement(); - - $objWriter->endElement(); - - // a:lt1 - $objWriter->startElement('a:lt1'); - - // a:sysClr - $objWriter->startElement('a:sysClr'); - $objWriter->writeAttribute('val', 'window'); - $objWriter->writeAttribute('lastClr', 'FFFFFF'); - $objWriter->endElement(); - - $objWriter->endElement(); - - // a:dk2 - $this->_writeColourScheme($objWriter); - - $objWriter->endElement(); - - // a:fontScheme - $objWriter->startElement('a:fontScheme'); - $objWriter->writeAttribute('name', 'Office'); - - // a:majorFont - $objWriter->startElement('a:majorFont'); - $this->_writeFonts($objWriter, 'Cambria', self::$_majorFonts); - $objWriter->endElement(); - - // a:minorFont - $objWriter->startElement('a:minorFont'); - $this->_writeFonts($objWriter, 'Calibri', self::$_minorFonts); - $objWriter->endElement(); - - $objWriter->endElement(); - - // a:fmtScheme - $objWriter->startElement('a:fmtScheme'); - $objWriter->writeAttribute('name', 'Office'); - - // a:fillStyleLst - $objWriter->startElement('a:fillStyleLst'); - - // a:solidFill - $objWriter->startElement('a:solidFill'); - - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); - $objWriter->endElement(); - - $objWriter->endElement(); - - // a:gradFill - $objWriter->startElement('a:gradFill'); - $objWriter->writeAttribute('rotWithShape', '1'); + /** + * Map of Major fonts to write + * @static array of string + * + */ + private static $_majorFonts = array( + 'Jpan' => 'MS Pゴシック', + 'Hang' => '맑은 고딕', + 'Hans' => '宋体', + 'Hant' => '新細明體', + 'Arab' => 'Times New Roman', + 'Hebr' => 'Times New Roman', + 'Thai' => 'Tahoma', + 'Ethi' => 'Nyala', + 'Beng' => 'Vrinda', + 'Gujr' => 'Shruti', + 'Khmr' => 'MoolBoran', + 'Knda' => 'Tunga', + 'Guru' => 'Raavi', + 'Cans' => 'Euphemia', + 'Cher' => 'Plantagenet Cherokee', + 'Yiii' => 'Microsoft Yi Baiti', + 'Tibt' => 'Microsoft Himalaya', + 'Thaa' => 'MV Boli', + 'Deva' => 'Mangal', + 'Telu' => 'Gautami', + 'Taml' => 'Latha', + 'Syrc' => 'Estrangelo Edessa', + 'Orya' => 'Kalinga', + 'Mlym' => 'Kartika', + 'Laoo' => 'DokChampa', + 'Sinh' => 'Iskoola Pota', + 'Mong' => 'Mongolian Baiti', + 'Viet' => 'Times New Roman', + 'Uigh' => 'Microsoft Uighur', + 'Geor' => 'Sylfaen', + ); + + /** + * Map of Minor fonts to write + * @static array of string + * + */ + private static $_minorFonts = array( + 'Jpan' => 'MS Pゴシック', + 'Hang' => '맑은 고딕', + 'Hans' => '宋体', + 'Hant' => '新細明體', + 'Arab' => 'Arial', + 'Hebr' => 'Arial', + 'Thai' => 'Tahoma', + 'Ethi' => 'Nyala', + 'Beng' => 'Vrinda', + 'Gujr' => 'Shruti', + 'Khmr' => 'DaunPenh', + 'Knda' => 'Tunga', + 'Guru' => 'Raavi', + 'Cans' => 'Euphemia', + 'Cher' => 'Plantagenet Cherokee', + 'Yiii' => 'Microsoft Yi Baiti', + 'Tibt' => 'Microsoft Himalaya', + 'Thaa' => 'MV Boli', + 'Deva' => 'Mangal', + 'Telu' => 'Gautami', + 'Taml' => 'Latha', + 'Syrc' => 'Estrangelo Edessa', + 'Orya' => 'Kalinga', + 'Mlym' => 'Kartika', + 'Laoo' => 'DokChampa', + 'Sinh' => 'Iskoola Pota', + 'Mong' => 'Mongolian Baiti', + 'Viet' => 'Arial', + 'Uigh' => 'Microsoft Uighur', + 'Geor' => 'Sylfaen', + ); + + /** + * Map of core colours + * @static array of string + * + */ + private static $_colourScheme = array( + 'dk2' => '1F497D', + 'lt2' => 'EEECE1', + 'accent1' => '4F81BD', + 'accent2' => 'C0504D', + 'accent3' => '9BBB59', + 'accent4' => '8064A2', + 'accent5' => '4BACC6', + 'accent6' => 'F79646', + 'hlink' => '0000FF', + 'folHlink' => '800080', + ); + + /** + * Write theme to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeTheme(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // a:theme + $objWriter->startElement('a:theme'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + $objWriter->writeAttribute('name', 'Office Theme'); + + // a:themeElements + $objWriter->startElement('a:themeElements'); + + // a:clrScheme + $objWriter->startElement('a:clrScheme'); + $objWriter->writeAttribute('name', 'Office'); + + // a:dk1 + $objWriter->startElement('a:dk1'); + + // a:sysClr + $objWriter->startElement('a:sysClr'); + $objWriter->writeAttribute('val', 'windowText'); + $objWriter->writeAttribute('lastClr', '000000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lt1 + $objWriter->startElement('a:lt1'); + + // a:sysClr + $objWriter->startElement('a:sysClr'); + $objWriter->writeAttribute('val', 'window'); + $objWriter->writeAttribute('lastClr', 'FFFFFF'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:dk2 + $this->_writeColourScheme($objWriter); + + $objWriter->endElement(); + + // a:fontScheme + $objWriter->startElement('a:fontScheme'); + $objWriter->writeAttribute('name', 'Office'); + + // a:majorFont + $objWriter->startElement('a:majorFont'); + $this->_writeFonts($objWriter, 'Cambria', self::$_majorFonts); + $objWriter->endElement(); + + // a:minorFont + $objWriter->startElement('a:minorFont'); + $this->_writeFonts($objWriter, 'Calibri', self::$_minorFonts); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:fmtScheme + $objWriter->startElement('a:fmtScheme'); + $objWriter->writeAttribute('name', 'Office'); + + // a:fillStyleLst + $objWriter->startElement('a:fillStyleLst'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); - // a:gsLst - $objWriter->startElement('a:gsLst'); + // a:gsLst + $objWriter->startElement('a:gsLst'); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '0'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '50000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '50000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '300000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '35000'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '35000'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '37000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '37000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '300000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '100000'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '15000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '15000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '350000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:lin - $objWriter->startElement('a:lin'); - $objWriter->writeAttribute('ang', '16200000'); - $objWriter->writeAttribute('scaled', '1'); - $objWriter->endElement(); + // a:lin + $objWriter->startElement('a:lin'); + $objWriter->writeAttribute('ang', '16200000'); + $objWriter->writeAttribute('scaled', '1'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:gradFill - $objWriter->startElement('a:gradFill'); - $objWriter->writeAttribute('rotWithShape', '1'); + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); - // a:gsLst - $objWriter->startElement('a:gsLst'); + // a:gsLst + $objWriter->startElement('a:gsLst'); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '0'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '51000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '51000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '130000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '130000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '80000'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '80000'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '93000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '93000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '130000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '130000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '100000'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '94000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '94000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '135000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '135000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:lin - $objWriter->startElement('a:lin'); - $objWriter->writeAttribute('ang', '16200000'); - $objWriter->writeAttribute('scaled', '0'); - $objWriter->endElement(); + // a:lin + $objWriter->startElement('a:lin'); + $objWriter->writeAttribute('ang', '16200000'); + $objWriter->writeAttribute('scaled', '0'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:lnStyleLst - $objWriter->startElement('a:lnStyleLst'); + // a:lnStyleLst + $objWriter->startElement('a:lnStyleLst'); - // a:ln - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', '9525'); - $objWriter->writeAttribute('cap', 'flat'); - $objWriter->writeAttribute('cmpd', 'sng'); - $objWriter->writeAttribute('algn', 'ctr'); + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '9525'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:solidFill + $objWriter->startElement('a:solidFill'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '95000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '95000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '105000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '105000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:prstDash - $objWriter->startElement('a:prstDash'); - $objWriter->writeAttribute('val', 'solid'); - $objWriter->endElement(); + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:ln - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', '25400'); - $objWriter->writeAttribute('cap', 'flat'); - $objWriter->writeAttribute('cmpd', 'sng'); - $objWriter->writeAttribute('algn', 'ctr'); + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '25400'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:solidFill + $objWriter->startElement('a:solidFill'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:prstDash - $objWriter->startElement('a:prstDash'); - $objWriter->writeAttribute('val', 'solid'); - $objWriter->endElement(); + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:ln - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', '38100'); - $objWriter->writeAttribute('cap', 'flat'); - $objWriter->writeAttribute('cmpd', 'sng'); - $objWriter->writeAttribute('algn', 'ctr'); + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '38100'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:solidFill + $objWriter->startElement('a:solidFill'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:prstDash - $objWriter->startElement('a:prstDash'); - $objWriter->writeAttribute('val', 'solid'); - $objWriter->endElement(); + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:effectStyleLst - $objWriter->startElement('a:effectStyleLst'); + // a:effectStyleLst + $objWriter->startElement('a:effectStyleLst'); - // a:effectStyle - $objWriter->startElement('a:effectStyle'); + // a:effectStyle + $objWriter->startElement('a:effectStyle'); - // a:effectLst - $objWriter->startElement('a:effectLst'); + // a:effectLst + $objWriter->startElement('a:effectLst'); - // a:outerShdw - $objWriter->startElement('a:outerShdw'); - $objWriter->writeAttribute('blurRad', '40000'); - $objWriter->writeAttribute('dist', '20000'); - $objWriter->writeAttribute('dir', '5400000'); - $objWriter->writeAttribute('rotWithShape', '0'); + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '20000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', '000000'); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); - // a:alpha - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', '38000'); - $objWriter->endElement(); + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '38000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:effectStyle - $objWriter->startElement('a:effectStyle'); + // a:effectStyle + $objWriter->startElement('a:effectStyle'); - // a:effectLst - $objWriter->startElement('a:effectLst'); + // a:effectLst + $objWriter->startElement('a:effectLst'); - // a:outerShdw - $objWriter->startElement('a:outerShdw'); - $objWriter->writeAttribute('blurRad', '40000'); - $objWriter->writeAttribute('dist', '23000'); - $objWriter->writeAttribute('dir', '5400000'); - $objWriter->writeAttribute('rotWithShape', '0'); + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '23000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', '000000'); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); - // a:alpha - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', '35000'); - $objWriter->endElement(); + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '35000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:effectStyle - $objWriter->startElement('a:effectStyle'); + // a:effectStyle + $objWriter->startElement('a:effectStyle'); - // a:effectLst - $objWriter->startElement('a:effectLst'); + // a:effectLst + $objWriter->startElement('a:effectLst'); - // a:outerShdw - $objWriter->startElement('a:outerShdw'); - $objWriter->writeAttribute('blurRad', '40000'); - $objWriter->writeAttribute('dist', '23000'); - $objWriter->writeAttribute('dir', '5400000'); - $objWriter->writeAttribute('rotWithShape', '0'); + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '23000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', '000000'); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); - // a:alpha - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', '35000'); - $objWriter->endElement(); + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '35000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:scene3d - $objWriter->startElement('a:scene3d'); + // a:scene3d + $objWriter->startElement('a:scene3d'); - // a:camera - $objWriter->startElement('a:camera'); - $objWriter->writeAttribute('prst', 'orthographicFront'); + // a:camera + $objWriter->startElement('a:camera'); + $objWriter->writeAttribute('prst', 'orthographicFront'); - // a:rot - $objWriter->startElement('a:rot'); - $objWriter->writeAttribute('lat', '0'); - $objWriter->writeAttribute('lon', '0'); - $objWriter->writeAttribute('rev', '0'); - $objWriter->endElement(); + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '0'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:lightRig - $objWriter->startElement('a:lightRig'); - $objWriter->writeAttribute('rig', 'threePt'); - $objWriter->writeAttribute('dir', 't'); + // a:lightRig + $objWriter->startElement('a:lightRig'); + $objWriter->writeAttribute('rig', 'threePt'); + $objWriter->writeAttribute('dir', 't'); - // a:rot - $objWriter->startElement('a:rot'); - $objWriter->writeAttribute('lat', '0'); - $objWriter->writeAttribute('lon', '0'); - $objWriter->writeAttribute('rev', '1200000'); - $objWriter->endElement(); + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '1200000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:sp3d - $objWriter->startElement('a:sp3d'); + // a:sp3d + $objWriter->startElement('a:sp3d'); - // a:bevelT - $objWriter->startElement('a:bevelT'); - $objWriter->writeAttribute('w', '63500'); - $objWriter->writeAttribute('h', '25400'); - $objWriter->endElement(); + // a:bevelT + $objWriter->startElement('a:bevelT'); + $objWriter->writeAttribute('w', '63500'); + $objWriter->writeAttribute('h', '25400'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:bgFillStyleLst - $objWriter->startElement('a:bgFillStyleLst'); + // a:bgFillStyleLst + $objWriter->startElement('a:bgFillStyleLst'); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:solidFill + $objWriter->startElement('a:solidFill'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:gradFill - $objWriter->startElement('a:gradFill'); - $objWriter->writeAttribute('rotWithShape', '1'); + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); - // a:gsLst - $objWriter->startElement('a:gsLst'); + // a:gsLst + $objWriter->startElement('a:gsLst'); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '0'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '40000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '40000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '350000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '40000'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '40000'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '45000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '45000'); + $objWriter->endElement(); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '99000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '99000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '350000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '100000'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '20000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '20000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '255000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '255000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:path - $objWriter->startElement('a:path'); - $objWriter->writeAttribute('path', 'circle'); + // a:path + $objWriter->startElement('a:path'); + $objWriter->writeAttribute('path', 'circle'); - // a:fillToRect - $objWriter->startElement('a:fillToRect'); - $objWriter->writeAttribute('l', '50000'); - $objWriter->writeAttribute('t', '-80000'); - $objWriter->writeAttribute('r', '50000'); - $objWriter->writeAttribute('b', '180000'); - $objWriter->endElement(); + // a:fillToRect + $objWriter->startElement('a:fillToRect'); + $objWriter->writeAttribute('l', '50000'); + $objWriter->writeAttribute('t', '-80000'); + $objWriter->writeAttribute('r', '50000'); + $objWriter->writeAttribute('b', '180000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:gradFill - $objWriter->startElement('a:gradFill'); - $objWriter->writeAttribute('rotWithShape', '1'); + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); - // a:gsLst - $objWriter->startElement('a:gsLst'); + // a:gsLst + $objWriter->startElement('a:gsLst'); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '0'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '80000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '80000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '300000'); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '100000'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '30000'); - $objWriter->endElement(); - - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '200000'); - $objWriter->endElement(); - - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '30000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '200000'); + $objWriter->endElement(); + + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:path - $objWriter->startElement('a:path'); - $objWriter->writeAttribute('path', 'circle'); + // a:path + $objWriter->startElement('a:path'); + $objWriter->writeAttribute('path', 'circle'); - // a:fillToRect - $objWriter->startElement('a:fillToRect'); - $objWriter->writeAttribute('l', '50000'); - $objWriter->writeAttribute('t', '50000'); - $objWriter->writeAttribute('r', '50000'); - $objWriter->writeAttribute('b', '50000'); - $objWriter->endElement(); - - $objWriter->endElement(); - - $objWriter->endElement(); - - $objWriter->endElement(); - - $objWriter->endElement(); + // a:fillToRect + $objWriter->startElement('a:fillToRect'); + $objWriter->writeAttribute('l', '50000'); + $objWriter->writeAttribute('t', '50000'); + $objWriter->writeAttribute('r', '50000'); + $objWriter->writeAttribute('b', '50000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); - $objWriter->endElement(); - - // a:objectDefaults - $objWriter->writeElement('a:objectDefaults', null); + $objWriter->endElement(); + + // a:objectDefaults + $objWriter->writeElement('a:objectDefaults', null); - // a:extraClrSchemeLst - $objWriter->writeElement('a:extraClrSchemeLst', null); - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write fonts to XML format - * - * @param PHPExcel_Shared_XMLWriter $objWriter - * @param string $latinFont - * @param array of string $fontSet - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - private function _writeFonts($objWriter, $latinFont, $fontSet) - { - // a:latin - $objWriter->startElement('a:latin'); - $objWriter->writeAttribute('typeface', $latinFont); - $objWriter->endElement(); - - // a:ea - $objWriter->startElement('a:ea'); - $objWriter->writeAttribute('typeface', ''); - $objWriter->endElement(); - - // a:cs - $objWriter->startElement('a:cs'); - $objWriter->writeAttribute('typeface', ''); - $objWriter->endElement(); - - foreach($fontSet as $fontScript => $typeface) { - $objWriter->startElement('a:font'); - $objWriter->writeAttribute('script', $fontScript); - $objWriter->writeAttribute('typeface', $typeface); - $objWriter->endElement(); - } - - } - - /** - * Write colour scheme to XML format - * - * @param PHPExcel_Shared_XMLWriter $objWriter - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - private function _writeColourScheme($objWriter) - { - foreach(self::$_colourScheme as $colourName => $colourValue) { - $objWriter->startElement('a:'.$colourName); - - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', $colourValue); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - } + // a:extraClrSchemeLst + $objWriter->writeElement('a:extraClrSchemeLst', null); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write fonts to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter + * @param string $latinFont + * @param array of string $fontSet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + private function _writeFonts($objWriter, $latinFont, $fontSet) + { + // a:latin + $objWriter->startElement('a:latin'); + $objWriter->writeAttribute('typeface', $latinFont); + $objWriter->endElement(); + + // a:ea + $objWriter->startElement('a:ea'); + $objWriter->writeAttribute('typeface', ''); + $objWriter->endElement(); + + // a:cs + $objWriter->startElement('a:cs'); + $objWriter->writeAttribute('typeface', ''); + $objWriter->endElement(); + + foreach($fontSet as $fontScript => $typeface) { + $objWriter->startElement('a:font'); + $objWriter->writeAttribute('script', $fontScript); + $objWriter->writeAttribute('typeface', $typeface); + $objWriter->endElement(); + } + + } + + /** + * Write colour scheme to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + private function _writeColourScheme($objWriter) + { + foreach(self::$_colourScheme as $colourName => $colourValue) { + $objWriter->startElement('a:'.$colourName); + + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $colourValue); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Workbook.php b/Classes/PHPExcel/Writer/Excel2007/Workbook.php index 56a3939b7..4753d8107 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel2007/Workbook.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,422 +35,422 @@ */ class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Write workbook to XML format - * - * @param PHPExcel $pPHPExcel - * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = FALSE) - { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // workbook - $objWriter->startElement('workbook'); - $objWriter->writeAttribute('xml:space', 'preserve'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); - $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - - // fileVersion - $this->_writeFileVersion($objWriter); - - // workbookPr - $this->_writeWorkbookPr($objWriter); - - // workbookProtection - $this->_writeWorkbookProtection($objWriter, $pPHPExcel); - - // bookViews - if ($this->getParentWriter()->getOffice2003Compatibility() === false) { - $this->_writeBookViews($objWriter, $pPHPExcel); - } - - // sheets - $this->_writeSheets($objWriter, $pPHPExcel); - - // definedNames - $this->_writeDefinedNames($objWriter, $pPHPExcel); - - // calcPr - $this->_writeCalcPr($objWriter,$recalcRequired); - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write file version - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @throws PHPExcel_Writer_Exception - */ - private function _writeFileVersion(PHPExcel_Shared_XMLWriter $objWriter = null) - { - $objWriter->startElement('fileVersion'); - $objWriter->writeAttribute('appName', 'xl'); - $objWriter->writeAttribute('lastEdited', '4'); - $objWriter->writeAttribute('lowestEdited', '4'); - $objWriter->writeAttribute('rupBuild', '4505'); - $objWriter->endElement(); - } - - /** - * Write WorkbookPr - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @throws PHPExcel_Writer_Exception - */ - private function _writeWorkbookPr(PHPExcel_Shared_XMLWriter $objWriter = null) - { - $objWriter->startElement('workbookPr'); - - if (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) { - $objWriter->writeAttribute('date1904', '1'); - } - - $objWriter->writeAttribute('codeName', 'ThisWorkbook'); - - $objWriter->endElement(); - } - - /** - * Write BookViews - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel $pPHPExcel - * @throws PHPExcel_Writer_Exception - */ - private function _writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) - { - // bookViews - $objWriter->startElement('bookViews'); - - // workbookView - $objWriter->startElement('workbookView'); - - $objWriter->writeAttribute('activeTab', $pPHPExcel->getActiveSheetIndex()); - $objWriter->writeAttribute('autoFilterDateGrouping', '1'); - $objWriter->writeAttribute('firstSheet', '0'); - $objWriter->writeAttribute('minimized', '0'); - $objWriter->writeAttribute('showHorizontalScroll', '1'); - $objWriter->writeAttribute('showSheetTabs', '1'); - $objWriter->writeAttribute('showVerticalScroll', '1'); - $objWriter->writeAttribute('tabRatio', '600'); - $objWriter->writeAttribute('visibility', 'visible'); - - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write WorkbookProtection - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel $pPHPExcel - * @throws PHPExcel_Writer_Exception - */ - private function _writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) - { - if ($pPHPExcel->getSecurity()->isSecurityEnabled()) { - $objWriter->startElement('workbookProtection'); - $objWriter->writeAttribute('lockRevision', ($pPHPExcel->getSecurity()->getLockRevision() ? 'true' : 'false')); - $objWriter->writeAttribute('lockStructure', ($pPHPExcel->getSecurity()->getLockStructure() ? 'true' : 'false')); - $objWriter->writeAttribute('lockWindows', ($pPHPExcel->getSecurity()->getLockWindows() ? 'true' : 'false')); - - if ($pPHPExcel->getSecurity()->getRevisionsPassword() != '') { - $objWriter->writeAttribute('revisionsPassword', $pPHPExcel->getSecurity()->getRevisionsPassword()); - } - - if ($pPHPExcel->getSecurity()->getWorkbookPassword() != '') { - $objWriter->writeAttribute('workbookPassword', $pPHPExcel->getSecurity()->getWorkbookPassword()); - } - - $objWriter->endElement(); - } - } - - /** - * Write calcPr - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing - * @throws PHPExcel_Writer_Exception - */ - private function _writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = TRUE) - { - $objWriter->startElement('calcPr'); - - // Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc + /** + * Write workbook to XML format + * + * @param PHPExcel $pPHPExcel + * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // workbook + $objWriter->startElement('workbook'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + // fileVersion + $this->_writeFileVersion($objWriter); + + // workbookPr + $this->_writeWorkbookPr($objWriter); + + // workbookProtection + $this->_writeWorkbookProtection($objWriter, $pPHPExcel); + + // bookViews + if ($this->getParentWriter()->getOffice2003Compatibility() === false) { + $this->_writeBookViews($objWriter, $pPHPExcel); + } + + // sheets + $this->_writeSheets($objWriter, $pPHPExcel); + + // definedNames + $this->_writeDefinedNames($objWriter, $pPHPExcel); + + // calcPr + $this->_writeCalcPr($objWriter,$recalcRequired); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write file version + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeFileVersion(PHPExcel_Shared_XMLWriter $objWriter = null) + { + $objWriter->startElement('fileVersion'); + $objWriter->writeAttribute('appName', 'xl'); + $objWriter->writeAttribute('lastEdited', '4'); + $objWriter->writeAttribute('lowestEdited', '4'); + $objWriter->writeAttribute('rupBuild', '4505'); + $objWriter->endElement(); + } + + /** + * Write WorkbookPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeWorkbookPr(PHPExcel_Shared_XMLWriter $objWriter = null) + { + $objWriter->startElement('workbookPr'); + + if (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) { + $objWriter->writeAttribute('date1904', '1'); + } + + $objWriter->writeAttribute('codeName', 'ThisWorkbook'); + + $objWriter->endElement(); + } + + /** + * Write BookViews + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + // bookViews + $objWriter->startElement('bookViews'); + + // workbookView + $objWriter->startElement('workbookView'); + + $objWriter->writeAttribute('activeTab', $pPHPExcel->getActiveSheetIndex()); + $objWriter->writeAttribute('autoFilterDateGrouping', '1'); + $objWriter->writeAttribute('firstSheet', '0'); + $objWriter->writeAttribute('minimized', '0'); + $objWriter->writeAttribute('showHorizontalScroll', '1'); + $objWriter->writeAttribute('showSheetTabs', '1'); + $objWriter->writeAttribute('showVerticalScroll', '1'); + $objWriter->writeAttribute('tabRatio', '600'); + $objWriter->writeAttribute('visibility', 'visible'); + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write WorkbookProtection + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + if ($pPHPExcel->getSecurity()->isSecurityEnabled()) { + $objWriter->startElement('workbookProtection'); + $objWriter->writeAttribute('lockRevision', ($pPHPExcel->getSecurity()->getLockRevision() ? 'true' : 'false')); + $objWriter->writeAttribute('lockStructure', ($pPHPExcel->getSecurity()->getLockStructure() ? 'true' : 'false')); + $objWriter->writeAttribute('lockWindows', ($pPHPExcel->getSecurity()->getLockWindows() ? 'true' : 'false')); + + if ($pPHPExcel->getSecurity()->getRevisionsPassword() != '') { + $objWriter->writeAttribute('revisionsPassword', $pPHPExcel->getSecurity()->getRevisionsPassword()); + } + + if ($pPHPExcel->getSecurity()->getWorkbookPassword() != '') { + $objWriter->writeAttribute('workbookPassword', $pPHPExcel->getSecurity()->getWorkbookPassword()); + } + + $objWriter->endElement(); + } + } + + /** + * Write calcPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing + * @throws PHPExcel_Writer_Exception + */ + private function _writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = TRUE) + { + $objWriter->startElement('calcPr'); + + // Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc // If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit // because the file has changed - $objWriter->writeAttribute('calcId', '999999'); - $objWriter->writeAttribute('calcMode', 'auto'); - // fullCalcOnLoad isn't needed if we've recalculating for the save - $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0); - $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1); - - $objWriter->endElement(); - } - - /** - * Write sheets - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel $pPHPExcel - * @throws PHPExcel_Writer_Exception - */ - private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) - { - // Write sheets - $objWriter->startElement('sheets'); - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - // sheet - $this->_writeSheet( - $objWriter, - $pPHPExcel->getSheet($i)->getTitle(), - ($i + 1), - ($i + 1 + 3), - $pPHPExcel->getSheet($i)->getSheetState() - ); - } - - $objWriter->endElement(); - } - - /** - * Write sheet - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param string $pSheetname Sheet name - * @param int $pSheetId Sheet id - * @param int $pRelId Relationship ID - * @param string $sheetState Sheet state (visible, hidden, veryHidden) - * @throws PHPExcel_Writer_Exception - */ - private function _writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pSheetname = '', $pSheetId = 1, $pRelId = 1, $sheetState = 'visible') - { - if ($pSheetname != '') { - // Write sheet - $objWriter->startElement('sheet'); - $objWriter->writeAttribute('name', $pSheetname); - $objWriter->writeAttribute('sheetId', $pSheetId); - if ($sheetState != 'visible' && $sheetState != '') { - $objWriter->writeAttribute('state', $sheetState); - } - $objWriter->writeAttribute('r:id', 'rId' . $pRelId); - $objWriter->endElement(); - } else { - throw new PHPExcel_Writer_Exception("Invalid parameters passed."); - } - } - - /** - * Write Defined Names - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel $pPHPExcel - * @throws PHPExcel_Writer_Exception - */ - private function _writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) - { - // Write defined names - $objWriter->startElement('definedNames'); - - // Named ranges - if (count($pPHPExcel->getNamedRanges()) > 0) { - // Named ranges - $this->_writeNamedRanges($objWriter, $pPHPExcel); - } - - // Other defined names - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - // definedName for autoFilter - $this->_writeDefinedNameForAutofilter($objWriter, $pPHPExcel->getSheet($i), $i); - - // definedName for Print_Titles - $this->_writeDefinedNameForPrintTitles($objWriter, $pPHPExcel->getSheet($i), $i); - - // definedName for Print_Area - $this->_writeDefinedNameForPrintArea($objWriter, $pPHPExcel->getSheet($i), $i); - } - - $objWriter->endElement(); - } - - /** - * Write named ranges - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel $pPHPExcel - * @throws PHPExcel_Writer_Exception - */ - private function _writeNamedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel) - { - // Loop named ranges - $namedRanges = $pPHPExcel->getNamedRanges(); - foreach ($namedRanges as $namedRange) { - $this->_writeDefinedNameForNamedRange($objWriter, $namedRange); - } - } - - /** - * Write Defined Name for named range - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_NamedRange $pNamedRange - * @throws PHPExcel_Writer_Exception - */ - private function _writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_NamedRange $pNamedRange) - { - // definedName for named range - $objWriter->startElement('definedName'); - $objWriter->writeAttribute('name', $pNamedRange->getName()); - if ($pNamedRange->getLocalOnly()) { - $objWriter->writeAttribute('localSheetId', $pNamedRange->getScope()->getParent()->getIndex($pNamedRange->getScope())); - } - - // Create absolute coordinate and write as raw text - $range = PHPExcel_Cell::splitRange($pNamedRange->getRange()); - for ($i = 0; $i < count($range); $i++) { - $range[$i][0] = '\'' . str_replace("'", "''", $pNamedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteReference($range[$i][0]); - if (isset($range[$i][1])) { - $range[$i][1] = PHPExcel_Cell::absoluteReference($range[$i][1]); - } - } - $range = PHPExcel_Cell::buildRange($range); - - $objWriter->writeRawData($range); - - $objWriter->endElement(); - } - - /** - * Write Defined Name for autoFilter - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet - * @param int $pSheetId - * @throws PHPExcel_Writer_Exception - */ - private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) - { - // definedName for autoFilter - $autoFilterRange = $pSheet->getAutoFilter()->getRange(); - if (!empty($autoFilterRange)) { - $objWriter->startElement('definedName'); - $objWriter->writeAttribute('name', '_xlnm._FilterDatabase'); - $objWriter->writeAttribute('localSheetId', $pSheetId); - $objWriter->writeAttribute('hidden', '1'); - - // Create absolute coordinate and write as raw text - $range = PHPExcel_Cell::splitRange($autoFilterRange); - $range = $range[0]; - // Strip any worksheet ref so we can make the cell ref absolute - if (strpos($range[0],'!') !== false) { - list($ws,$range[0]) = explode('!',$range[0]); - } - - $range[0] = PHPExcel_Cell::absoluteCoordinate($range[0]); - $range[1] = PHPExcel_Cell::absoluteCoordinate($range[1]); - $range = implode(':', $range); - - $objWriter->writeRawData('\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . $range); - - $objWriter->endElement(); - } - } - - /** - * Write Defined Name for PrintTitles - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet - * @param int $pSheetId - * @throws PHPExcel_Writer_Exception - */ - private function _writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) - { - // definedName for PrintTitles - if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { - $objWriter->startElement('definedName'); - $objWriter->writeAttribute('name', '_xlnm.Print_Titles'); - $objWriter->writeAttribute('localSheetId', $pSheetId); - - // Setting string - $settingString = ''; - - // Columns to repeat - if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) { - $repeat = $pSheet->getPageSetup()->getColumnsToRepeatAtLeft(); - - $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1]; - } - - // Rows to repeat - if ($pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { - if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) { - $settingString .= ','; - } - - $repeat = $pSheet->getPageSetup()->getRowsToRepeatAtTop(); - - $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1]; - } - - $objWriter->writeRawData($settingString); - - $objWriter->endElement(); - } - } - - /** - * Write Defined Name for PrintTitles - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet - * @param int $pSheetId - * @throws PHPExcel_Writer_Exception - */ - private function _writeDefinedNameForPrintArea(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) - { - // definedName for PrintArea - if ($pSheet->getPageSetup()->isPrintAreaSet()) { - $objWriter->startElement('definedName'); - $objWriter->writeAttribute('name', '_xlnm.Print_Area'); - $objWriter->writeAttribute('localSheetId', $pSheetId); - - // Setting string - $settingString = ''; - - // Print area - $printArea = PHPExcel_Cell::splitRange($pSheet->getPageSetup()->getPrintArea()); - - $chunks = array(); - foreach ($printArea as $printAreaRect) { - $printAreaRect[0] = PHPExcel_Cell::absoluteReference($printAreaRect[0]); - $printAreaRect[1] = PHPExcel_Cell::absoluteReference($printAreaRect[1]); - $chunks[] = '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . implode(':', $printAreaRect); - } - - $objWriter->writeRawData(implode(',', $chunks)); - - $objWriter->endElement(); - } - } + $objWriter->writeAttribute('calcId', '999999'); + $objWriter->writeAttribute('calcMode', 'auto'); + // fullCalcOnLoad isn't needed if we've recalculating for the save + $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0); + $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1); + + $objWriter->endElement(); + } + + /** + * Write sheets + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + // Write sheets + $objWriter->startElement('sheets'); + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + // sheet + $this->_writeSheet( + $objWriter, + $pPHPExcel->getSheet($i)->getTitle(), + ($i + 1), + ($i + 1 + 3), + $pPHPExcel->getSheet($i)->getSheetState() + ); + } + + $objWriter->endElement(); + } + + /** + * Write sheet + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pSheetname Sheet name + * @param int $pSheetId Sheet id + * @param int $pRelId Relationship ID + * @param string $sheetState Sheet state (visible, hidden, veryHidden) + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pSheetname = '', $pSheetId = 1, $pRelId = 1, $sheetState = 'visible') + { + if ($pSheetname != '') { + // Write sheet + $objWriter->startElement('sheet'); + $objWriter->writeAttribute('name', $pSheetname); + $objWriter->writeAttribute('sheetId', $pSheetId); + if ($sheetState != 'visible' && $sheetState != '') { + $objWriter->writeAttribute('state', $sheetState); + } + $objWriter->writeAttribute('r:id', 'rId' . $pRelId); + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Defined Names + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + // Write defined names + $objWriter->startElement('definedNames'); + + // Named ranges + if (count($pPHPExcel->getNamedRanges()) > 0) { + // Named ranges + $this->_writeNamedRanges($objWriter, $pPHPExcel); + } + + // Other defined names + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + // definedName for autoFilter + $this->_writeDefinedNameForAutofilter($objWriter, $pPHPExcel->getSheet($i), $i); + + // definedName for Print_Titles + $this->_writeDefinedNameForPrintTitles($objWriter, $pPHPExcel->getSheet($i), $i); + + // definedName for Print_Area + $this->_writeDefinedNameForPrintArea($objWriter, $pPHPExcel->getSheet($i), $i); + } + + $objWriter->endElement(); + } + + /** + * Write named ranges + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeNamedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel) + { + // Loop named ranges + $namedRanges = $pPHPExcel->getNamedRanges(); + foreach ($namedRanges as $namedRange) { + $this->_writeDefinedNameForNamedRange($objWriter, $namedRange); + } + } + + /** + * Write Defined Name for named range + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_NamedRange $pNamedRange + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_NamedRange $pNamedRange) + { + // definedName for named range + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', $pNamedRange->getName()); + if ($pNamedRange->getLocalOnly()) { + $objWriter->writeAttribute('localSheetId', $pNamedRange->getScope()->getParent()->getIndex($pNamedRange->getScope())); + } + + // Create absolute coordinate and write as raw text + $range = PHPExcel_Cell::splitRange($pNamedRange->getRange()); + for ($i = 0; $i < count($range); $i++) { + $range[$i][0] = '\'' . str_replace("'", "''", $pNamedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteReference($range[$i][0]); + if (isset($range[$i][1])) { + $range[$i][1] = PHPExcel_Cell::absoluteReference($range[$i][1]); + } + } + $range = PHPExcel_Cell::buildRange($range); + + $objWriter->writeRawData($range); + + $objWriter->endElement(); + } + + /** + * Write Defined Name for autoFilter + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet + * @param int $pSheetId + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + { + // definedName for autoFilter + $autoFilterRange = $pSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', '_xlnm._FilterDatabase'); + $objWriter->writeAttribute('localSheetId', $pSheetId); + $objWriter->writeAttribute('hidden', '1'); + + // Create absolute coordinate and write as raw text + $range = PHPExcel_Cell::splitRange($autoFilterRange); + $range = $range[0]; + // Strip any worksheet ref so we can make the cell ref absolute + if (strpos($range[0],'!') !== false) { + list($ws,$range[0]) = explode('!',$range[0]); + } + + $range[0] = PHPExcel_Cell::absoluteCoordinate($range[0]); + $range[1] = PHPExcel_Cell::absoluteCoordinate($range[1]); + $range = implode(':', $range); + + $objWriter->writeRawData('\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . $range); + + $objWriter->endElement(); + } + } + + /** + * Write Defined Name for PrintTitles + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet + * @param int $pSheetId + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + { + // definedName for PrintTitles + if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', '_xlnm.Print_Titles'); + $objWriter->writeAttribute('localSheetId', $pSheetId); + + // Setting string + $settingString = ''; + + // Columns to repeat + if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) { + $repeat = $pSheet->getPageSetup()->getColumnsToRepeatAtLeft(); + + $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1]; + } + + // Rows to repeat + if ($pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { + if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) { + $settingString .= ','; + } + + $repeat = $pSheet->getPageSetup()->getRowsToRepeatAtTop(); + + $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1]; + } + + $objWriter->writeRawData($settingString); + + $objWriter->endElement(); + } + } + + /** + * Write Defined Name for PrintTitles + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet + * @param int $pSheetId + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForPrintArea(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + { + // definedName for PrintArea + if ($pSheet->getPageSetup()->isPrintAreaSet()) { + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', '_xlnm.Print_Area'); + $objWriter->writeAttribute('localSheetId', $pSheetId); + + // Setting string + $settingString = ''; + + // Print area + $printArea = PHPExcel_Cell::splitRange($pSheet->getPageSetup()->getPrintArea()); + + $chunks = array(); + foreach ($printArea as $printAreaRect) { + $printAreaRect[0] = PHPExcel_Cell::absoluteReference($printAreaRect[0]); + $printAreaRect[1] = PHPExcel_Cell::absoluteReference($printAreaRect[1]); + $chunks[] = '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . implode(':', $printAreaRect); + } + + $objWriter->writeRawData(implode(',', $chunks)); + + $objWriter->endElement(); + } + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index 6ca93c035..e0ef6f533 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -19,10 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 + * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ @@ -30,1191 +30,1191 @@ * PHPExcel_Writer_Excel2007_Worksheet * * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 + * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_WriterPart { - /** - * Write worksheet to XML format - * - * @param PHPExcel_Worksheet $pSheet - * @param string[] $pStringTable - * @param boolean $includeCharts Flag indicating if we should write charts - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeWorksheet($pSheet = null, $pStringTable = null, $includeCharts = FALSE) - { - if (!is_null($pSheet)) { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); - - // Worksheet - $objWriter->startElement('worksheet'); - $objWriter->writeAttribute('xml:space', 'preserve'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); - $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - - // sheetPr - $this->_writeSheetPr($objWriter, $pSheet); - - // Dimension - $this->_writeDimension($objWriter, $pSheet); - - // sheetViews - $this->_writeSheetViews($objWriter, $pSheet); - - // sheetFormatPr - $this->_writeSheetFormatPr($objWriter, $pSheet); - - // cols - $this->_writeCols($objWriter, $pSheet); - - // sheetData - $this->_writeSheetData($objWriter, $pSheet, $pStringTable); - - // sheetProtection - $this->_writeSheetProtection($objWriter, $pSheet); - - // protectedRanges - $this->_writeProtectedRanges($objWriter, $pSheet); - - // autoFilter - $this->_writeAutoFilter($objWriter, $pSheet); - - // mergeCells - $this->_writeMergeCells($objWriter, $pSheet); - - // conditionalFormatting - $this->_writeConditionalFormatting($objWriter, $pSheet); - - // dataValidations - $this->_writeDataValidations($objWriter, $pSheet); - - // hyperlinks - $this->_writeHyperlinks($objWriter, $pSheet); - - // Print options - $this->_writePrintOptions($objWriter, $pSheet); - - // Page margins - $this->_writePageMargins($objWriter, $pSheet); - - // Page setup - $this->_writePageSetup($objWriter, $pSheet); - - // Header / footer - $this->_writeHeaderFooter($objWriter, $pSheet); - - // Breaks - $this->_writeBreaks($objWriter, $pSheet); - - // Drawings and/or Charts - $this->_writeDrawings($objWriter, $pSheet, $includeCharts); - - // LegacyDrawing - $this->_writeLegacyDrawing($objWriter, $pSheet); - - // LegacyDrawingHF - $this->_writeLegacyDrawingHF($objWriter, $pSheet); - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } else { - throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); - } - } - - /** - * Write SheetPr - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // sheetPr - $objWriter->startElement('sheetPr'); - //$objWriter->writeAttribute('codeName', $pSheet->getTitle()); - if($pSheet->getParent()->hasMacros()){//if the workbook have macros, we need to have codeName for the sheet - if($pSheet->hasCodeName()==false){ - $pSheet->setCodeName($pSheet->getTitle()); - } - $objWriter->writeAttribute('codeName', $pSheet->getCodeName()); - } - $autoFilterRange = $pSheet->getAutoFilter()->getRange(); - if (!empty($autoFilterRange)) { - $objWriter->writeAttribute('filterMode', 1); - $pSheet->getAutoFilter()->showHideRows(); - } - - // tabColor - if ($pSheet->isTabColorSet()) { - $objWriter->startElement('tabColor'); - $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB()); - $objWriter->endElement(); - } - - // outlinePr - $objWriter->startElement('outlinePr'); - $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0')); - $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0')); - $objWriter->endElement(); - - // pageSetUpPr - if ($pSheet->getPageSetup()->getFitToPage()) { - $objWriter->startElement('pageSetUpPr'); - $objWriter->writeAttribute('fitToPage', '1'); - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - - /** - * Write Dimension - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // dimension - $objWriter->startElement('dimension'); - $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension()); - $objWriter->endElement(); - } - - /** - * Write SheetViews - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = NULL, PHPExcel_Worksheet $pSheet = NULL) - { - // sheetViews - $objWriter->startElement('sheetViews'); - - // Sheet selected? - $sheetSelected = false; - if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex()) - $sheetSelected = true; - - - // sheetView - $objWriter->startElement('sheetView'); - $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0'); - $objWriter->writeAttribute('workbookViewId', '0'); - - // Zoom scales - if ($pSheet->getSheetView()->getZoomScale() != 100) { - $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale()); - } - if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) { - $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal()); - } - - // View Layout Type - if ($pSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL) { - $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView()); - } - - // Gridlines - if ($pSheet->getShowGridlines()) { - $objWriter->writeAttribute('showGridLines', 'true'); - } else { - $objWriter->writeAttribute('showGridLines', 'false'); - } - - // Row and column headers - if ($pSheet->getShowRowColHeaders()) { - $objWriter->writeAttribute('showRowColHeaders', '1'); - } else { - $objWriter->writeAttribute('showRowColHeaders', '0'); - } - - // Right-to-left - if ($pSheet->getRightToLeft()) { - $objWriter->writeAttribute('rightToLeft', 'true'); - } - - $activeCell = $pSheet->getActiveCell(); - - // Pane - $pane = ''; - $topLeftCell = $pSheet->getFreezePane(); - if (($topLeftCell != '') && ($topLeftCell != 'A1')) { - $activeCell = $topLeftCell; - // Calculate freeze coordinates - $xSplit = $ySplit = 0; - - list($xSplit, $ySplit) = PHPExcel_Cell::coordinateFromString($topLeftCell); - $xSplit = PHPExcel_Cell::columnIndexFromString($xSplit); - - // pane - $pane = 'topRight'; - $objWriter->startElement('pane'); - if ($xSplit > 1) - $objWriter->writeAttribute('xSplit', $xSplit - 1); - if ($ySplit > 1) { - $objWriter->writeAttribute('ySplit', $ySplit - 1); - $pane = ($xSplit > 1) ? 'bottomRight' : 'bottomLeft'; - } - $objWriter->writeAttribute('topLeftCell', $topLeftCell); - $objWriter->writeAttribute('activePane', $pane); - $objWriter->writeAttribute('state', 'frozen'); - $objWriter->endElement(); - - if (($xSplit > 1) && ($ySplit > 1)) { - // Write additional selections if more than two panes (ie both an X and a Y split) - $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'topRight'); $objWriter->endElement(); - $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'bottomLeft'); $objWriter->endElement(); - } - } - - // Selection -// if ($pane != '') { - // Only need to write selection element if we have a split pane - // We cheat a little by over-riding the active cell selection, setting it to the split cell - $objWriter->startElement('selection'); - if ($pane != '') { - $objWriter->writeAttribute('pane', $pane); - } - $objWriter->writeAttribute('activeCell', $activeCell); - $objWriter->writeAttribute('sqref', $activeCell); - $objWriter->endElement(); -// } - - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write SheetFormatPr - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // sheetFormatPr - $objWriter->startElement('sheetFormatPr'); - - // Default row height - if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) { - $objWriter->writeAttribute('customHeight', 'true'); - $objWriter->writeAttribute('defaultRowHeight', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultRowDimension()->getRowHeight())); - } else { - $objWriter->writeAttribute('defaultRowHeight', '14.4'); - } - - // Set Zero Height row - if ((string)$pSheet->getDefaultRowDimension()->getZeroHeight() == '1' || - strtolower((string)$pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true' ) { - $objWriter->writeAttribute('zeroHeight', '1'); - } - - // Default column width - if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) { - $objWriter->writeAttribute('defaultColWidth', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultColumnDimension()->getWidth())); - } - - // Outline level - row - $outlineLevelRow = 0; - foreach ($pSheet->getRowDimensions() as $dimension) { - if ($dimension->getOutlineLevel() > $outlineLevelRow) { - $outlineLevelRow = $dimension->getOutlineLevel(); - } - } - $objWriter->writeAttribute('outlineLevelRow', (int)$outlineLevelRow); - - // Outline level - column - $outlineLevelCol = 0; - foreach ($pSheet->getColumnDimensions() as $dimension) { - if ($dimension->getOutlineLevel() > $outlineLevelCol) { - $outlineLevelCol = $dimension->getOutlineLevel(); - } - } - $objWriter->writeAttribute('outlineLevelCol', (int)$outlineLevelCol); - - $objWriter->endElement(); - } - - /** - * Write Cols - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // cols - if (count($pSheet->getColumnDimensions()) > 0) { - $objWriter->startElement('cols'); - - $pSheet->calculateColumnWidths(); - - // Loop through column dimensions - foreach ($pSheet->getColumnDimensions() as $colDimension) { - // col - $objWriter->startElement('col'); - $objWriter->writeAttribute('min', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); - $objWriter->writeAttribute('max', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); - - if ($colDimension->getWidth() < 0) { - // No width set, apply default of 10 - $objWriter->writeAttribute('width', '9.10'); - } else { - // Width set - $objWriter->writeAttribute('width', PHPExcel_Shared_String::FormatNumber($colDimension->getWidth())); - } - - // Column visibility - if ($colDimension->getVisible() == false) { - $objWriter->writeAttribute('hidden', 'true'); - } - - // Auto size? - if ($colDimension->getAutoSize()) { - $objWriter->writeAttribute('bestFit', 'true'); - } - - // Custom width? - if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) { - $objWriter->writeAttribute('customWidth', 'true'); - } - - // Collapsed - if ($colDimension->getCollapsed() == true) { - $objWriter->writeAttribute('collapsed', 'true'); - } - - // Outline level - if ($colDimension->getOutlineLevel() > 0) { - $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel()); - } - - // Style - $objWriter->writeAttribute('style', $colDimension->getXfIndex()); - - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - } - - /** - * Write SheetProtection - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // sheetProtection - $objWriter->startElement('sheetProtection'); - - if ($pSheet->getProtection()->getPassword() != '') { - $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword()); - } - - $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false')); - $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false')); - $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false')); - $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false')); - $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false')); - $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false')); - $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false')); - $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false')); - $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false')); - $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false')); - $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false')); - $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false')); - $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false')); - $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false')); - $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false')); - $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false')); - $objWriter->endElement(); - } - - /** - * Write ConditionalFormatting - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // Conditional id - $id = 1; - - // Loop through styles in the current worksheet - foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { - foreach ($conditionalStyles as $conditional) { - // WHY was this again? - // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() ) == '') { - // continue; - // } - if ($conditional->getConditionType() != PHPExcel_Style_Conditional::CONDITION_NONE) { - // conditionalFormatting - $objWriter->startElement('conditionalFormatting'); - $objWriter->writeAttribute('sqref', $cellCoordinate); - - // cfRule - $objWriter->startElement('cfRule'); - $objWriter->writeAttribute('type', $conditional->getConditionType()); - $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() )); - $objWriter->writeAttribute('priority', $id++); - - if (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS - || - $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT) - && $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) { - $objWriter->writeAttribute('operator', $conditional->getOperatorType()); - } - - if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - && !is_null($conditional->getText())) { - $objWriter->writeAttribute('text', $conditional->getText()); - } - - if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT - && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH - && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH - && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS - && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS - || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { - foreach ($conditional->getConditions() as $formula) { - // Formula - $objWriter->writeElement('formula', $formula); - } - } - - $objWriter->endElement(); - - $objWriter->endElement(); - } - } - } - } - - /** - * Write DataValidations - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // Datavalidation collection - $dataValidationCollection = $pSheet->getDataValidationCollection(); - - // Write data validations? - if (!empty($dataValidationCollection)) { - $objWriter->startElement('dataValidations'); - $objWriter->writeAttribute('count', count($dataValidationCollection)); - - foreach ($dataValidationCollection as $coordinate => $dv) { - $objWriter->startElement('dataValidation'); - - if ($dv->getType() != '') { - $objWriter->writeAttribute('type', $dv->getType()); - } - - if ($dv->getErrorStyle() != '') { - $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle()); - } - - if ($dv->getOperator() != '') { - $objWriter->writeAttribute('operator', $dv->getOperator()); - } - - $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0')); - $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0')); - $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0')); - $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0')); - - if ($dv->getErrorTitle() !== '') { - $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle()); - } - if ($dv->getError() !== '') { - $objWriter->writeAttribute('error', $dv->getError()); - } - if ($dv->getPromptTitle() !== '') { - $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle()); - } - if ($dv->getPrompt() !== '') { - $objWriter->writeAttribute('prompt', $dv->getPrompt()); - } - - $objWriter->writeAttribute('sqref', $coordinate); - - if ($dv->getFormula1() !== '') { - $objWriter->writeElement('formula1', $dv->getFormula1()); - } - if ($dv->getFormula2() !== '') { - $objWriter->writeElement('formula2', $dv->getFormula2()); - } - - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - } - - /** - * Write Hyperlinks - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // Hyperlink collection - $hyperlinkCollection = $pSheet->getHyperlinkCollection(); - - // Relation ID - $relationId = 1; - - // Write hyperlinks? - if (!empty($hyperlinkCollection)) { - $objWriter->startElement('hyperlinks'); - - foreach ($hyperlinkCollection as $coordinate => $hyperlink) { - $objWriter->startElement('hyperlink'); - - $objWriter->writeAttribute('ref', $coordinate); - if (!$hyperlink->isInternal()) { - $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId); - ++$relationId; - } else { - $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl())); - } - - if ($hyperlink->getTooltip() != '') { - $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip()); - } - - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - } - - /** - * Write ProtectedRanges - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - if (count($pSheet->getProtectedCells()) > 0) { - // protectedRanges - $objWriter->startElement('protectedRanges'); - - // Loop protectedRanges - foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) { - // protectedRange - $objWriter->startElement('protectedRange'); - $objWriter->writeAttribute('name', 'p' . md5($protectedCell)); - $objWriter->writeAttribute('sqref', $protectedCell); - if (!empty($passwordHash)) { - $objWriter->writeAttribute('password', $passwordHash); - } - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - } - - /** - * Write MergeCells - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - if (count($pSheet->getMergeCells()) > 0) { - // mergeCells - $objWriter->startElement('mergeCells'); - - // Loop mergeCells - foreach ($pSheet->getMergeCells() as $mergeCell) { - // mergeCell - $objWriter->startElement('mergeCell'); - $objWriter->writeAttribute('ref', $mergeCell); - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - } - - /** - * Write PrintOptions - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // printOptions - $objWriter->startElement('printOptions'); - - $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true': 'false')); - $objWriter->writeAttribute('gridLinesSet', 'true'); - - if ($pSheet->getPageSetup()->getHorizontalCentered()) { - $objWriter->writeAttribute('horizontalCentered', 'true'); - } - - if ($pSheet->getPageSetup()->getVerticalCentered()) { - $objWriter->writeAttribute('verticalCentered', 'true'); - } - - $objWriter->endElement(); - } - - /** - * Write PageMargins - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // pageMargins - $objWriter->startElement('pageMargins'); - $objWriter->writeAttribute('left', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft())); - $objWriter->writeAttribute('right', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight())); - $objWriter->writeAttribute('top', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop())); - $objWriter->writeAttribute('bottom', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom())); - $objWriter->writeAttribute('header', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getHeader())); - $objWriter->writeAttribute('footer', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getFooter())); - $objWriter->endElement(); - } - - /** - * Write AutoFilter - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - $autoFilterRange = $pSheet->getAutoFilter()->getRange(); - if (!empty($autoFilterRange)) { - // autoFilter - $objWriter->startElement('autoFilter'); - - // Strip any worksheet reference from the filter coordinates - $range = PHPExcel_Cell::splitRange($autoFilterRange); - $range = $range[0]; - // Strip any worksheet ref - if (strpos($range[0],'!') !== false) { - list($ws,$range[0]) = explode('!',$range[0]); - } - $range = implode(':', $range); - - $objWriter->writeAttribute('ref', str_replace('$','',$range)); - - $columns = $pSheet->getAutoFilter()->getColumns(); - if (count($columns > 0)) { - foreach($columns as $columnID => $column) { - $rules = $column->getRules(); - if (count($rules > 0)) { - $objWriter->startElement('filterColumn'); - $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID)); - - $objWriter->startElement( $column->getFilterType()); - if ($column->getJoin() == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND) { - $objWriter->writeAttribute('and', 1); - } - - foreach ($rules as $rule) { - if (($column->getFilterType() === PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) && - ($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) && - ($rule->getValue() === '')) { - // Filter rule for Blanks - $objWriter->writeAttribute('blank', 1); - } elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { - // Dynamic Filter Rule - $objWriter->writeAttribute('type', $rule->getGrouping()); - $val = $column->getAttribute('val'); - if ($val !== NULL) { - $objWriter->writeAttribute('val', $val); - } - $maxVal = $column->getAttribute('maxVal'); - if ($maxVal !== NULL) { - $objWriter->writeAttribute('maxVal', $maxVal); - } - } elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { - // Top 10 Filter Rule - $objWriter->writeAttribute('val', $rule->getValue()); - $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); - $objWriter->writeAttribute('top', (($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0')); - } else { - // Filter, DateGroupItem or CustomFilter - $objWriter->startElement($rule->getRuleType()); - - if ($rule->getOperator() !== PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) { - $objWriter->writeAttribute('operator', $rule->getOperator()); - } - if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { - // Date Group filters - foreach($rule->getValue() as $key => $value) { - if ($value > '') $objWriter->writeAttribute($key, $value); - } - $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); - } else { - $objWriter->writeAttribute('val', $rule->getValue()); - } - - $objWriter->endElement(); - } - } - - $objWriter->endElement(); - - $objWriter->endElement(); - } - } - } - - $objWriter->endElement(); - } - } - - /** - * Write PageSetup - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // pageSetup - $objWriter->startElement('pageSetup'); - $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize()); - $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation()); - - if (!is_null($pSheet->getPageSetup()->getScale())) { - $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale()); - } - if (!is_null($pSheet->getPageSetup()->getFitToHeight())) { - $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight()); - } else { - $objWriter->writeAttribute('fitToHeight', '0'); - } - if (!is_null($pSheet->getPageSetup()->getFitToWidth())) { - $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth()); - } else { - $objWriter->writeAttribute('fitToWidth', '0'); - } - if (!is_null($pSheet->getPageSetup()->getFirstPageNumber())) { - $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber()); - $objWriter->writeAttribute('useFirstPageNumber', '1'); - } - - $objWriter->endElement(); - } - - /** - * Write Header / Footer - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // headerFooter - $objWriter->startElement('headerFooter'); - $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false')); - $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false')); - $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false')); - $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false')); - - $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader()); - $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter()); - $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader()); - $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter()); - $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader()); - $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter()); - $objWriter->endElement(); - } - - /** - * Write Breaks - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // Get row and column breaks - $aRowBreaks = array(); - $aColumnBreaks = array(); - foreach ($pSheet->getBreaks() as $cell => $breakType) { - if ($breakType == PHPExcel_Worksheet::BREAK_ROW) { - $aRowBreaks[] = $cell; - } else if ($breakType == PHPExcel_Worksheet::BREAK_COLUMN) { - $aColumnBreaks[] = $cell; - } - } - - // rowBreaks - if (!empty($aRowBreaks)) { - $objWriter->startElement('rowBreaks'); - $objWriter->writeAttribute('count', count($aRowBreaks)); - $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks)); - - foreach ($aRowBreaks as $cell) { - $coords = PHPExcel_Cell::coordinateFromString($cell); - - $objWriter->startElement('brk'); - $objWriter->writeAttribute('id', $coords[1]); - $objWriter->writeAttribute('man', '1'); - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - - // Second, write column breaks - if (!empty($aColumnBreaks)) { - $objWriter->startElement('colBreaks'); - $objWriter->writeAttribute('count', count($aColumnBreaks)); - $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks)); - - foreach ($aColumnBreaks as $cell) { - $coords = PHPExcel_Cell::coordinateFromString($cell); - - $objWriter->startElement('brk'); - $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1); - $objWriter->writeAttribute('man', '1'); - $objWriter->endElement(); - } - - $objWriter->endElement(); - } - } - - /** - * Write SheetData - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @param string[] $pStringTable String table - * @throws PHPExcel_Writer_Exception - */ - private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pStringTable = null) - { - if (is_array($pStringTable)) { - // Flipped stringtable, for faster index searching - $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable); - - // sheetData - $objWriter->startElement('sheetData'); - - // Get column count - $colCount = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()); - - // Highest row number - $highestRow = $pSheet->getHighestRow(); - - // Loop through cells - $cellsByRow = array(); - foreach ($pSheet->getCellCollection() as $cellID) { - $cellAddress = PHPExcel_Cell::coordinateFromString($cellID); - $cellsByRow[$cellAddress[1]][] = $cellID; - } - - $currentRow = 0; - while($currentRow++ < $highestRow) { - // Get row dimension - $rowDimension = $pSheet->getRowDimension($currentRow); - - // Write current row? - $writeCurrentRow = isset($cellsByRow[$currentRow]) || - $rowDimension->getRowHeight() >= 0 || - $rowDimension->getVisible() == false || - $rowDimension->getCollapsed() == true || - $rowDimension->getOutlineLevel() > 0 || - $rowDimension->getXfIndex() !== null; - - if ($writeCurrentRow) { - // Start a new row - $objWriter->startElement('row'); - $objWriter->writeAttribute('r', $currentRow); - $objWriter->writeAttribute('spans', '1:' . $colCount); - - // Row dimensions - if ($rowDimension->getRowHeight() >= 0) { - $objWriter->writeAttribute('customHeight', '1'); - $objWriter->writeAttribute('ht', PHPExcel_Shared_String::FormatNumber($rowDimension->getRowHeight())); - } - - // Row visibility - if ($rowDimension->getVisible() == false) { - $objWriter->writeAttribute('hidden', 'true'); - } - - // Collapsed - if ($rowDimension->getCollapsed() == true) { - $objWriter->writeAttribute('collapsed', 'true'); - } - - // Outline level - if ($rowDimension->getOutlineLevel() > 0) { - $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel()); - } - - // Style - if ($rowDimension->getXfIndex() !== null) { - $objWriter->writeAttribute('s', $rowDimension->getXfIndex()); - $objWriter->writeAttribute('customFormat', '1'); - } - - // Write cells - if (isset($cellsByRow[$currentRow])) { - foreach($cellsByRow[$currentRow] as $cellAddress) { - // Write cell - $this->_writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable); - } - } - - // End row - $objWriter->endElement(); - } - } - - $objWriter->endElement(); - } else { - throw new PHPExcel_Writer_Exception("Invalid parameters passed."); - } - } - - /** - * Write Cell - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @param PHPExcel_Cell $pCellAddress Cell Address - * @param string[] $pStringTable String table - * @param string[] $pFlippedStringTable String table (flipped), for faster index searching - * @throws PHPExcel_Writer_Exception - */ - private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pCellAddress = null, $pStringTable = null, $pFlippedStringTable = null) - { - if (is_array($pStringTable) && is_array($pFlippedStringTable)) { - // Cell - $pCell = $pSheet->getCell($pCellAddress); - $objWriter->startElement('c'); - $objWriter->writeAttribute('r', $pCellAddress); - - // Sheet styles - if ($pCell->getXfIndex() != '') { - $objWriter->writeAttribute('s', $pCell->getXfIndex()); - } - - // If cell value is supplied, write cell value - $cellValue = $pCell->getValue(); - if (is_object($cellValue) || $cellValue !== '') { - // Map type - $mappedType = $pCell->getDataType(); - - // Write data type depending on its type - switch (strtolower($mappedType)) { - case 'inlinestr': // Inline string - case 's': // String - case 'b': // Boolean - $objWriter->writeAttribute('t', $mappedType); - break; - case 'f': // Formula - $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ? - $pCell->getCalculatedValue() : - $cellValue; - if (is_string($calculatedValue)) { - $objWriter->writeAttribute('t', 'str'); - } - break; - case 'e': // Error - $objWriter->writeAttribute('t', $mappedType); - } - - // Write data depending on its type - switch (strtolower($mappedType)) { - case 'inlinestr': // Inline string - if (! $cellValue instanceof PHPExcel_RichText) { - $objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML( htmlspecialchars($cellValue) ) ); - } else if ($cellValue instanceof PHPExcel_RichText) { - $objWriter->startElement('is'); - $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue); - $objWriter->endElement(); - } - - break; - case 's': // String - if (! $cellValue instanceof PHPExcel_RichText) { - if (isset($pFlippedStringTable[$cellValue])) { - $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]); - } - } else if ($cellValue instanceof PHPExcel_RichText) { - $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]); - } - - break; - case 'f': // Formula - $attributes = $pCell->getFormulaAttributes(); - if($attributes['t'] == 'array') { - $objWriter->startElement('f'); - $objWriter->writeAttribute('t', 'array'); - $objWriter->writeAttribute('ref', $pCellAddress); - $objWriter->writeAttribute('aca', '1'); - $objWriter->writeAttribute('ca', '1'); - $objWriter->text(substr($cellValue, 1)); - $objWriter->endElement(); - } else { - $objWriter->writeElement('f', substr($cellValue, 1)); - } - if ($this->getParentWriter()->getOffice2003Compatibility() === false) { - if ($this->getParentWriter()->getPreCalculateFormulas()) { -// $calculatedValue = $pCell->getCalculatedValue(); - if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') { - $objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue)); - } else { - $objWriter->writeElement('v', '0'); - } - } else { - $objWriter->writeElement('v', '0'); - } - } - break; - case 'n': // Numeric - // force point as decimal separator in case current locale uses comma - $objWriter->writeElement('v', str_replace(',', '.', $cellValue)); - break; - case 'b': // Boolean - $objWriter->writeElement('v', ($cellValue ? '1' : '0')); - break; - case 'e': // Error - if (substr($cellValue, 0, 1) == '=') { - $objWriter->writeElement('f', substr($cellValue, 1)); - $objWriter->writeElement('v', substr($cellValue, 1)); - } else { - $objWriter->writeElement('v', $cellValue); - } - - break; - } - } - - $objWriter->endElement(); - } else { - throw new PHPExcel_Writer_Exception("Invalid parameters passed."); - } - } - - /** - * Write Drawings - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @param boolean $includeCharts Flag indicating if we should include drawing details for charts - * @throws PHPExcel_Writer_Exception - */ - private function _writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = FALSE) - { - $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0; - // If sheet contains drawings, add the relationships - if (($pSheet->getDrawingCollection()->count() > 0) || - ($chartCount > 0)) { - $objWriter->startElement('drawing'); - $objWriter->writeAttribute('r:id', 'rId1'); - $objWriter->endElement(); - } - } - - /** - * Write LegacyDrawing - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // If sheet contains comments, add the relationships - if (count($pSheet->getComments()) > 0) { - $objWriter->startElement('legacyDrawing'); - $objWriter->writeAttribute('r:id', 'rId_comments_vml1'); - $objWriter->endElement(); - } - } - - /** - * Write LegacyDrawingHF - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet - * @throws PHPExcel_Writer_Exception - */ - private function _writeLegacyDrawingHF(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) - { - // If sheet contains images, add the relationships - if (count($pSheet->getHeaderFooter()->getImages()) > 0) { - $objWriter->startElement('legacyDrawingHF'); - $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1'); - $objWriter->endElement(); - } - } + /** + * Write worksheet to XML format + * + * @param PHPExcel_Worksheet $pSheet + * @param string[] $pStringTable + * @param boolean $includeCharts Flag indicating if we should write charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorksheet($pSheet = null, $pStringTable = null, $includeCharts = FALSE) + { + if (!is_null($pSheet)) { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Worksheet + $objWriter->startElement('worksheet'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + // sheetPr + $this->_writeSheetPr($objWriter, $pSheet); + + // Dimension + $this->_writeDimension($objWriter, $pSheet); + + // sheetViews + $this->_writeSheetViews($objWriter, $pSheet); + + // sheetFormatPr + $this->_writeSheetFormatPr($objWriter, $pSheet); + + // cols + $this->_writeCols($objWriter, $pSheet); + + // sheetData + $this->_writeSheetData($objWriter, $pSheet, $pStringTable); + + // sheetProtection + $this->_writeSheetProtection($objWriter, $pSheet); + + // protectedRanges + $this->_writeProtectedRanges($objWriter, $pSheet); + + // autoFilter + $this->_writeAutoFilter($objWriter, $pSheet); + + // mergeCells + $this->_writeMergeCells($objWriter, $pSheet); + + // conditionalFormatting + $this->_writeConditionalFormatting($objWriter, $pSheet); + + // dataValidations + $this->_writeDataValidations($objWriter, $pSheet); + + // hyperlinks + $this->_writeHyperlinks($objWriter, $pSheet); + + // Print options + $this->_writePrintOptions($objWriter, $pSheet); + + // Page margins + $this->_writePageMargins($objWriter, $pSheet); + + // Page setup + $this->_writePageSetup($objWriter, $pSheet); + + // Header / footer + $this->_writeHeaderFooter($objWriter, $pSheet); + + // Breaks + $this->_writeBreaks($objWriter, $pSheet); + + // Drawings and/or Charts + $this->_writeDrawings($objWriter, $pSheet, $includeCharts); + + // LegacyDrawing + $this->_writeLegacyDrawing($objWriter, $pSheet); + + // LegacyDrawingHF + $this->_writeLegacyDrawingHF($objWriter, $pSheet); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } else { + throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); + } + } + + /** + * Write SheetPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // sheetPr + $objWriter->startElement('sheetPr'); + //$objWriter->writeAttribute('codeName', $pSheet->getTitle()); + if($pSheet->getParent()->hasMacros()){//if the workbook have macros, we need to have codeName for the sheet + if($pSheet->hasCodeName()==false){ + $pSheet->setCodeName($pSheet->getTitle()); + } + $objWriter->writeAttribute('codeName', $pSheet->getCodeName()); + } + $autoFilterRange = $pSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + $objWriter->writeAttribute('filterMode', 1); + $pSheet->getAutoFilter()->showHideRows(); + } + + // tabColor + if ($pSheet->isTabColorSet()) { + $objWriter->startElement('tabColor'); + $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB()); + $objWriter->endElement(); + } + + // outlinePr + $objWriter->startElement('outlinePr'); + $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0')); + $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0')); + $objWriter->endElement(); + + // pageSetUpPr + if ($pSheet->getPageSetup()->getFitToPage()) { + $objWriter->startElement('pageSetUpPr'); + $objWriter->writeAttribute('fitToPage', '1'); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Dimension + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // dimension + $objWriter->startElement('dimension'); + $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension()); + $objWriter->endElement(); + } + + /** + * Write SheetViews + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = NULL, PHPExcel_Worksheet $pSheet = NULL) + { + // sheetViews + $objWriter->startElement('sheetViews'); + + // Sheet selected? + $sheetSelected = false; + if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex()) + $sheetSelected = true; + + + // sheetView + $objWriter->startElement('sheetView'); + $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0'); + $objWriter->writeAttribute('workbookViewId', '0'); + + // Zoom scales + if ($pSheet->getSheetView()->getZoomScale() != 100) { + $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale()); + } + if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) { + $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal()); + } + + // View Layout Type + if ($pSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL) { + $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView()); + } + + // Gridlines + if ($pSheet->getShowGridlines()) { + $objWriter->writeAttribute('showGridLines', 'true'); + } else { + $objWriter->writeAttribute('showGridLines', 'false'); + } + + // Row and column headers + if ($pSheet->getShowRowColHeaders()) { + $objWriter->writeAttribute('showRowColHeaders', '1'); + } else { + $objWriter->writeAttribute('showRowColHeaders', '0'); + } + + // Right-to-left + if ($pSheet->getRightToLeft()) { + $objWriter->writeAttribute('rightToLeft', 'true'); + } + + $activeCell = $pSheet->getActiveCell(); + + // Pane + $pane = ''; + $topLeftCell = $pSheet->getFreezePane(); + if (($topLeftCell != '') && ($topLeftCell != 'A1')) { + $activeCell = $topLeftCell; + // Calculate freeze coordinates + $xSplit = $ySplit = 0; + + list($xSplit, $ySplit) = PHPExcel_Cell::coordinateFromString($topLeftCell); + $xSplit = PHPExcel_Cell::columnIndexFromString($xSplit); + + // pane + $pane = 'topRight'; + $objWriter->startElement('pane'); + if ($xSplit > 1) + $objWriter->writeAttribute('xSplit', $xSplit - 1); + if ($ySplit > 1) { + $objWriter->writeAttribute('ySplit', $ySplit - 1); + $pane = ($xSplit > 1) ? 'bottomRight' : 'bottomLeft'; + } + $objWriter->writeAttribute('topLeftCell', $topLeftCell); + $objWriter->writeAttribute('activePane', $pane); + $objWriter->writeAttribute('state', 'frozen'); + $objWriter->endElement(); + + if (($xSplit > 1) && ($ySplit > 1)) { + // Write additional selections if more than two panes (ie both an X and a Y split) + $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'topRight'); $objWriter->endElement(); + $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'bottomLeft'); $objWriter->endElement(); + } + } + + // Selection +// if ($pane != '') { + // Only need to write selection element if we have a split pane + // We cheat a little by over-riding the active cell selection, setting it to the split cell + $objWriter->startElement('selection'); + if ($pane != '') { + $objWriter->writeAttribute('pane', $pane); + } + $objWriter->writeAttribute('activeCell', $activeCell); + $objWriter->writeAttribute('sqref', $activeCell); + $objWriter->endElement(); +// } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write SheetFormatPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // sheetFormatPr + $objWriter->startElement('sheetFormatPr'); + + // Default row height + if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) { + $objWriter->writeAttribute('customHeight', 'true'); + $objWriter->writeAttribute('defaultRowHeight', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultRowDimension()->getRowHeight())); + } else { + $objWriter->writeAttribute('defaultRowHeight', '14.4'); + } + + // Set Zero Height row + if ((string)$pSheet->getDefaultRowDimension()->getZeroHeight() == '1' || + strtolower((string)$pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true' ) { + $objWriter->writeAttribute('zeroHeight', '1'); + } + + // Default column width + if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) { + $objWriter->writeAttribute('defaultColWidth', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultColumnDimension()->getWidth())); + } + + // Outline level - row + $outlineLevelRow = 0; + foreach ($pSheet->getRowDimensions() as $dimension) { + if ($dimension->getOutlineLevel() > $outlineLevelRow) { + $outlineLevelRow = $dimension->getOutlineLevel(); + } + } + $objWriter->writeAttribute('outlineLevelRow', (int)$outlineLevelRow); + + // Outline level - column + $outlineLevelCol = 0; + foreach ($pSheet->getColumnDimensions() as $dimension) { + if ($dimension->getOutlineLevel() > $outlineLevelCol) { + $outlineLevelCol = $dimension->getOutlineLevel(); + } + } + $objWriter->writeAttribute('outlineLevelCol', (int)$outlineLevelCol); + + $objWriter->endElement(); + } + + /** + * Write Cols + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // cols + if (count($pSheet->getColumnDimensions()) > 0) { + $objWriter->startElement('cols'); + + $pSheet->calculateColumnWidths(); + + // Loop through column dimensions + foreach ($pSheet->getColumnDimensions() as $colDimension) { + // col + $objWriter->startElement('col'); + $objWriter->writeAttribute('min', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); + $objWriter->writeAttribute('max', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); + + if ($colDimension->getWidth() < 0) { + // No width set, apply default of 10 + $objWriter->writeAttribute('width', '9.10'); + } else { + // Width set + $objWriter->writeAttribute('width', PHPExcel_Shared_String::FormatNumber($colDimension->getWidth())); + } + + // Column visibility + if ($colDimension->getVisible() == false) { + $objWriter->writeAttribute('hidden', 'true'); + } + + // Auto size? + if ($colDimension->getAutoSize()) { + $objWriter->writeAttribute('bestFit', 'true'); + } + + // Custom width? + if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) { + $objWriter->writeAttribute('customWidth', 'true'); + } + + // Collapsed + if ($colDimension->getCollapsed() == true) { + $objWriter->writeAttribute('collapsed', 'true'); + } + + // Outline level + if ($colDimension->getOutlineLevel() > 0) { + $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel()); + } + + // Style + $objWriter->writeAttribute('style', $colDimension->getXfIndex()); + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write SheetProtection + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // sheetProtection + $objWriter->startElement('sheetProtection'); + + if ($pSheet->getProtection()->getPassword() != '') { + $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword()); + } + + $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false')); + $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false')); + $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false')); + $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false')); + $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false')); + $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false')); + $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false')); + $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false')); + $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false')); + $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false')); + $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false')); + $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false')); + $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false')); + $objWriter->endElement(); + } + + /** + * Write ConditionalFormatting + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Conditional id + $id = 1; + + // Loop through styles in the current worksheet + foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { + foreach ($conditionalStyles as $conditional) { + // WHY was this again? + // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() ) == '') { + // continue; + // } + if ($conditional->getConditionType() != PHPExcel_Style_Conditional::CONDITION_NONE) { + // conditionalFormatting + $objWriter->startElement('conditionalFormatting'); + $objWriter->writeAttribute('sqref', $cellCoordinate); + + // cfRule + $objWriter->startElement('cfRule'); + $objWriter->writeAttribute('type', $conditional->getConditionType()); + $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() )); + $objWriter->writeAttribute('priority', $id++); + + if (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS + || + $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT) + && $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) { + $objWriter->writeAttribute('operator', $conditional->getOperatorType()); + } + + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && !is_null($conditional->getText())) { + $objWriter->writeAttribute('text', $conditional->getText()); + } + + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { + foreach ($conditional->getConditions() as $formula) { + // Formula + $objWriter->writeElement('formula', $formula); + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + } + } + + /** + * Write DataValidations + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Datavalidation collection + $dataValidationCollection = $pSheet->getDataValidationCollection(); + + // Write data validations? + if (!empty($dataValidationCollection)) { + $objWriter->startElement('dataValidations'); + $objWriter->writeAttribute('count', count($dataValidationCollection)); + + foreach ($dataValidationCollection as $coordinate => $dv) { + $objWriter->startElement('dataValidation'); + + if ($dv->getType() != '') { + $objWriter->writeAttribute('type', $dv->getType()); + } + + if ($dv->getErrorStyle() != '') { + $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle()); + } + + if ($dv->getOperator() != '') { + $objWriter->writeAttribute('operator', $dv->getOperator()); + } + + $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0')); + $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0')); + $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0')); + $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0')); + + if ($dv->getErrorTitle() !== '') { + $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle()); + } + if ($dv->getError() !== '') { + $objWriter->writeAttribute('error', $dv->getError()); + } + if ($dv->getPromptTitle() !== '') { + $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle()); + } + if ($dv->getPrompt() !== '') { + $objWriter->writeAttribute('prompt', $dv->getPrompt()); + } + + $objWriter->writeAttribute('sqref', $coordinate); + + if ($dv->getFormula1() !== '') { + $objWriter->writeElement('formula1', $dv->getFormula1()); + } + if ($dv->getFormula2() !== '') { + $objWriter->writeElement('formula2', $dv->getFormula2()); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write Hyperlinks + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Hyperlink collection + $hyperlinkCollection = $pSheet->getHyperlinkCollection(); + + // Relation ID + $relationId = 1; + + // Write hyperlinks? + if (!empty($hyperlinkCollection)) { + $objWriter->startElement('hyperlinks'); + + foreach ($hyperlinkCollection as $coordinate => $hyperlink) { + $objWriter->startElement('hyperlink'); + + $objWriter->writeAttribute('ref', $coordinate); + if (!$hyperlink->isInternal()) { + $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId); + ++$relationId; + } else { + $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl())); + } + + if ($hyperlink->getTooltip() != '') { + $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip()); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write ProtectedRanges + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + if (count($pSheet->getProtectedCells()) > 0) { + // protectedRanges + $objWriter->startElement('protectedRanges'); + + // Loop protectedRanges + foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) { + // protectedRange + $objWriter->startElement('protectedRange'); + $objWriter->writeAttribute('name', 'p' . md5($protectedCell)); + $objWriter->writeAttribute('sqref', $protectedCell); + if (!empty($passwordHash)) { + $objWriter->writeAttribute('password', $passwordHash); + } + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write MergeCells + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + if (count($pSheet->getMergeCells()) > 0) { + // mergeCells + $objWriter->startElement('mergeCells'); + + // Loop mergeCells + foreach ($pSheet->getMergeCells() as $mergeCell) { + // mergeCell + $objWriter->startElement('mergeCell'); + $objWriter->writeAttribute('ref', $mergeCell); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write PrintOptions + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // printOptions + $objWriter->startElement('printOptions'); + + $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true': 'false')); + $objWriter->writeAttribute('gridLinesSet', 'true'); + + if ($pSheet->getPageSetup()->getHorizontalCentered()) { + $objWriter->writeAttribute('horizontalCentered', 'true'); + } + + if ($pSheet->getPageSetup()->getVerticalCentered()) { + $objWriter->writeAttribute('verticalCentered', 'true'); + } + + $objWriter->endElement(); + } + + /** + * Write PageMargins + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // pageMargins + $objWriter->startElement('pageMargins'); + $objWriter->writeAttribute('left', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft())); + $objWriter->writeAttribute('right', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight())); + $objWriter->writeAttribute('top', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop())); + $objWriter->writeAttribute('bottom', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom())); + $objWriter->writeAttribute('header', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getHeader())); + $objWriter->writeAttribute('footer', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getFooter())); + $objWriter->endElement(); + } + + /** + * Write AutoFilter + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + $autoFilterRange = $pSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + // autoFilter + $objWriter->startElement('autoFilter'); + + // Strip any worksheet reference from the filter coordinates + $range = PHPExcel_Cell::splitRange($autoFilterRange); + $range = $range[0]; + // Strip any worksheet ref + if (strpos($range[0],'!') !== false) { + list($ws,$range[0]) = explode('!',$range[0]); + } + $range = implode(':', $range); + + $objWriter->writeAttribute('ref', str_replace('$','',$range)); + + $columns = $pSheet->getAutoFilter()->getColumns(); + if (count($columns > 0)) { + foreach($columns as $columnID => $column) { + $rules = $column->getRules(); + if (count($rules > 0)) { + $objWriter->startElement('filterColumn'); + $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID)); + + $objWriter->startElement( $column->getFilterType()); + if ($column->getJoin() == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND) { + $objWriter->writeAttribute('and', 1); + } + + foreach ($rules as $rule) { + if (($column->getFilterType() === PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) && + ($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) && + ($rule->getValue() === '')) { + // Filter rule for Blanks + $objWriter->writeAttribute('blank', 1); + } elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { + // Dynamic Filter Rule + $objWriter->writeAttribute('type', $rule->getGrouping()); + $val = $column->getAttribute('val'); + if ($val !== NULL) { + $objWriter->writeAttribute('val', $val); + } + $maxVal = $column->getAttribute('maxVal'); + if ($maxVal !== NULL) { + $objWriter->writeAttribute('maxVal', $maxVal); + } + } elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { + // Top 10 Filter Rule + $objWriter->writeAttribute('val', $rule->getValue()); + $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); + $objWriter->writeAttribute('top', (($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0')); + } else { + // Filter, DateGroupItem or CustomFilter + $objWriter->startElement($rule->getRuleType()); + + if ($rule->getOperator() !== PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) { + $objWriter->writeAttribute('operator', $rule->getOperator()); + } + if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { + // Date Group filters + foreach($rule->getValue() as $key => $value) { + if ($value > '') $objWriter->writeAttribute($key, $value); + } + $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); + } else { + $objWriter->writeAttribute('val', $rule->getValue()); + } + + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + } + } + + /** + * Write PageSetup + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // pageSetup + $objWriter->startElement('pageSetup'); + $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize()); + $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation()); + + if (!is_null($pSheet->getPageSetup()->getScale())) { + $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale()); + } + if (!is_null($pSheet->getPageSetup()->getFitToHeight())) { + $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight()); + } else { + $objWriter->writeAttribute('fitToHeight', '0'); + } + if (!is_null($pSheet->getPageSetup()->getFitToWidth())) { + $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth()); + } else { + $objWriter->writeAttribute('fitToWidth', '0'); + } + if (!is_null($pSheet->getPageSetup()->getFirstPageNumber())) { + $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber()); + $objWriter->writeAttribute('useFirstPageNumber', '1'); + } + + $objWriter->endElement(); + } + + /** + * Write Header / Footer + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // headerFooter + $objWriter->startElement('headerFooter'); + $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false')); + $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false')); + $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false')); + $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false')); + + $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader()); + $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter()); + $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader()); + $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter()); + $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader()); + $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter()); + $objWriter->endElement(); + } + + /** + * Write Breaks + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Get row and column breaks + $aRowBreaks = array(); + $aColumnBreaks = array(); + foreach ($pSheet->getBreaks() as $cell => $breakType) { + if ($breakType == PHPExcel_Worksheet::BREAK_ROW) { + $aRowBreaks[] = $cell; + } else if ($breakType == PHPExcel_Worksheet::BREAK_COLUMN) { + $aColumnBreaks[] = $cell; + } + } + + // rowBreaks + if (!empty($aRowBreaks)) { + $objWriter->startElement('rowBreaks'); + $objWriter->writeAttribute('count', count($aRowBreaks)); + $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks)); + + foreach ($aRowBreaks as $cell) { + $coords = PHPExcel_Cell::coordinateFromString($cell); + + $objWriter->startElement('brk'); + $objWriter->writeAttribute('id', $coords[1]); + $objWriter->writeAttribute('man', '1'); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + // Second, write column breaks + if (!empty($aColumnBreaks)) { + $objWriter->startElement('colBreaks'); + $objWriter->writeAttribute('count', count($aColumnBreaks)); + $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks)); + + foreach ($aColumnBreaks as $cell) { + $coords = PHPExcel_Cell::coordinateFromString($cell); + + $objWriter->startElement('brk'); + $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1); + $objWriter->writeAttribute('man', '1'); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write SheetData + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param string[] $pStringTable String table + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pStringTable = null) + { + if (is_array($pStringTable)) { + // Flipped stringtable, for faster index searching + $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable); + + // sheetData + $objWriter->startElement('sheetData'); + + // Get column count + $colCount = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()); + + // Highest row number + $highestRow = $pSheet->getHighestRow(); + + // Loop through cells + $cellsByRow = array(); + foreach ($pSheet->getCellCollection() as $cellID) { + $cellAddress = PHPExcel_Cell::coordinateFromString($cellID); + $cellsByRow[$cellAddress[1]][] = $cellID; + } + + $currentRow = 0; + while($currentRow++ < $highestRow) { + // Get row dimension + $rowDimension = $pSheet->getRowDimension($currentRow); + + // Write current row? + $writeCurrentRow = isset($cellsByRow[$currentRow]) || + $rowDimension->getRowHeight() >= 0 || + $rowDimension->getVisible() == false || + $rowDimension->getCollapsed() == true || + $rowDimension->getOutlineLevel() > 0 || + $rowDimension->getXfIndex() !== null; + + if ($writeCurrentRow) { + // Start a new row + $objWriter->startElement('row'); + $objWriter->writeAttribute('r', $currentRow); + $objWriter->writeAttribute('spans', '1:' . $colCount); + + // Row dimensions + if ($rowDimension->getRowHeight() >= 0) { + $objWriter->writeAttribute('customHeight', '1'); + $objWriter->writeAttribute('ht', PHPExcel_Shared_String::FormatNumber($rowDimension->getRowHeight())); + } + + // Row visibility + if ($rowDimension->getVisible() == false) { + $objWriter->writeAttribute('hidden', 'true'); + } + + // Collapsed + if ($rowDimension->getCollapsed() == true) { + $objWriter->writeAttribute('collapsed', 'true'); + } + + // Outline level + if ($rowDimension->getOutlineLevel() > 0) { + $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel()); + } + + // Style + if ($rowDimension->getXfIndex() !== null) { + $objWriter->writeAttribute('s', $rowDimension->getXfIndex()); + $objWriter->writeAttribute('customFormat', '1'); + } + + // Write cells + if (isset($cellsByRow[$currentRow])) { + foreach($cellsByRow[$currentRow] as $cellAddress) { + // Write cell + $this->_writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable); + } + } + + // End row + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Cell + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param PHPExcel_Cell $pCellAddress Cell Address + * @param string[] $pStringTable String table + * @param string[] $pFlippedStringTable String table (flipped), for faster index searching + * @throws PHPExcel_Writer_Exception + */ + private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pCellAddress = null, $pStringTable = null, $pFlippedStringTable = null) + { + if (is_array($pStringTable) && is_array($pFlippedStringTable)) { + // Cell + $pCell = $pSheet->getCell($pCellAddress); + $objWriter->startElement('c'); + $objWriter->writeAttribute('r', $pCellAddress); + + // Sheet styles + if ($pCell->getXfIndex() != '') { + $objWriter->writeAttribute('s', $pCell->getXfIndex()); + } + + // If cell value is supplied, write cell value + $cellValue = $pCell->getValue(); + if (is_object($cellValue) || $cellValue !== '') { + // Map type + $mappedType = $pCell->getDataType(); + + // Write data type depending on its type + switch (strtolower($mappedType)) { + case 'inlinestr': // Inline string + case 's': // String + case 'b': // Boolean + $objWriter->writeAttribute('t', $mappedType); + break; + case 'f': // Formula + $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ? + $pCell->getCalculatedValue() : + $cellValue; + if (is_string($calculatedValue)) { + $objWriter->writeAttribute('t', 'str'); + } + break; + case 'e': // Error + $objWriter->writeAttribute('t', $mappedType); + } + + // Write data depending on its type + switch (strtolower($mappedType)) { + case 'inlinestr': // Inline string + if (! $cellValue instanceof PHPExcel_RichText) { + $objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML( htmlspecialchars($cellValue) ) ); + } else if ($cellValue instanceof PHPExcel_RichText) { + $objWriter->startElement('is'); + $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue); + $objWriter->endElement(); + } + + break; + case 's': // String + if (! $cellValue instanceof PHPExcel_RichText) { + if (isset($pFlippedStringTable[$cellValue])) { + $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]); + } + } else if ($cellValue instanceof PHPExcel_RichText) { + $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]); + } + + break; + case 'f': // Formula + $attributes = $pCell->getFormulaAttributes(); + if($attributes['t'] == 'array') { + $objWriter->startElement('f'); + $objWriter->writeAttribute('t', 'array'); + $objWriter->writeAttribute('ref', $pCellAddress); + $objWriter->writeAttribute('aca', '1'); + $objWriter->writeAttribute('ca', '1'); + $objWriter->text(substr($cellValue, 1)); + $objWriter->endElement(); + } else { + $objWriter->writeElement('f', substr($cellValue, 1)); + } + if ($this->getParentWriter()->getOffice2003Compatibility() === false) { + if ($this->getParentWriter()->getPreCalculateFormulas()) { +// $calculatedValue = $pCell->getCalculatedValue(); + if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') { + $objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue)); + } else { + $objWriter->writeElement('v', '0'); + } + } else { + $objWriter->writeElement('v', '0'); + } + } + break; + case 'n': // Numeric + // force point as decimal separator in case current locale uses comma + $objWriter->writeElement('v', str_replace(',', '.', $cellValue)); + break; + case 'b': // Boolean + $objWriter->writeElement('v', ($cellValue ? '1' : '0')); + break; + case 'e': // Error + if (substr($cellValue, 0, 1) == '=') { + $objWriter->writeElement('f', substr($cellValue, 1)); + $objWriter->writeElement('v', substr($cellValue, 1)); + } else { + $objWriter->writeElement('v', $cellValue); + } + + break; + } + } + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Drawings + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param boolean $includeCharts Flag indicating if we should include drawing details for charts + * @throws PHPExcel_Writer_Exception + */ + private function _writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = FALSE) + { + $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0; + // If sheet contains drawings, add the relationships + if (($pSheet->getDrawingCollection()->count() > 0) || + ($chartCount > 0)) { + $objWriter->startElement('drawing'); + $objWriter->writeAttribute('r:id', 'rId1'); + $objWriter->endElement(); + } + } + + /** + * Write LegacyDrawing + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // If sheet contains comments, add the relationships + if (count($pSheet->getComments()) > 0) { + $objWriter->startElement('legacyDrawing'); + $objWriter->writeAttribute('r:id', 'rId_comments_vml1'); + $objWriter->endElement(); + } + } + + /** + * Write LegacyDrawingHF + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeLegacyDrawingHF(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // If sheet contains images, add the relationships + if (count($pSheet->getHeaderFooter()->getImages()) > 0) { + $objWriter->startElement('legacyDrawingHF'); + $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1'); + $objWriter->endElement(); + } + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php index 4c2f9b4b9..1ade577e5 100644 --- a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php +++ b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php @@ -35,47 +35,47 @@ */ abstract class PHPExcel_Writer_Excel2007_WriterPart { - /** - * Parent IWriter object - * - * @var PHPExcel_Writer_IWriter - */ - private $_parentWriter; + /** + * Parent IWriter object + * + * @var PHPExcel_Writer_IWriter + */ + private $_parentWriter; - /** - * Set parent IWriter object - * - * @param PHPExcel_Writer_IWriter $pWriter - * @throws PHPExcel_Writer_Exception - */ - public function setParentWriter(PHPExcel_Writer_IWriter $pWriter = null) { - $this->_parentWriter = $pWriter; - } + /** + * Set parent IWriter object + * + * @param PHPExcel_Writer_IWriter $pWriter + * @throws PHPExcel_Writer_Exception + */ + public function setParentWriter(PHPExcel_Writer_IWriter $pWriter = null) { + $this->_parentWriter = $pWriter; + } - /** - * Get parent IWriter object - * - * @return PHPExcel_Writer_IWriter - * @throws PHPExcel_Writer_Exception - */ - public function getParentWriter() { - if (!is_null($this->_parentWriter)) { - return $this->_parentWriter; - } else { - throw new PHPExcel_Writer_Exception("No parent PHPExcel_Writer_IWriter assigned."); - } - } + /** + * Get parent IWriter object + * + * @return PHPExcel_Writer_IWriter + * @throws PHPExcel_Writer_Exception + */ + public function getParentWriter() { + if (!is_null($this->_parentWriter)) { + return $this->_parentWriter; + } else { + throw new PHPExcel_Writer_Exception("No parent PHPExcel_Writer_IWriter assigned."); + } + } - /** - * Set parent IWriter object - * - * @param PHPExcel_Writer_IWriter $pWriter - * @throws PHPExcel_Writer_Exception - */ - public function __construct(PHPExcel_Writer_IWriter $pWriter = null) { - if (!is_null($pWriter)) { - $this->_parentWriter = $pWriter; - } - } + /** + * Set parent IWriter object + * + * @param PHPExcel_Writer_IWriter $pWriter + * @throws PHPExcel_Writer_Exception + */ + public function __construct(PHPExcel_Writer_IWriter $pWriter = null) { + if (!is_null($pWriter)) { + $this->_parentWriter = $pWriter; + } + } } diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index 6875d9b24..63a4ca721 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel5 * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,915 +22,906 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_Writer_Excel5 - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { - /** - * PHPExcel object - * - * @var PHPExcel - */ - private $_phpExcel; - - /** - * Total number of shared strings in workbook - * - * @var int - */ - private $_str_total = 0; - - /** - * Number of unique shared strings in workbook - * - * @var int - */ - private $_str_unique = 0; - - /** - * Array of unique shared strings in workbook - * - * @var array - */ - private $_str_table = array(); - - /** - * Color cache. Mapping between RGB value and color index. - * - * @var array - */ - private $_colors; - - /** - * Formula parser - * - * @var PHPExcel_Writer_Excel5_Parser - */ - private $_parser; - - /** - * Identifier clusters for drawings. Used in MSODRAWINGGROUP record. - * - * @var array - */ - private $_IDCLs; - - /** - * Basic OLE object summary information - * - * @var array - */ - private $_summaryInformation; - - /** - * Extended OLE object document summary information - * - * @var array - */ - private $_documentSummaryInformation; - - /** - * Create a new PHPExcel_Writer_Excel5 - * - * @param PHPExcel $phpExcel PHPExcel object - */ - public function __construct(PHPExcel $phpExcel) { - $this->_phpExcel = $phpExcel; - - $this->_parser = new PHPExcel_Writer_Excel5_Parser(); - } - - /** - * Save PHPExcel to file - * - * @param string $pFilename - * @throws PHPExcel_Writer_Exception - */ - public function save($pFilename = null) { - - // garbage collect - $this->_phpExcel->garbageCollect(); - - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); - $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - - // initialize colors array - $this->_colors = array(); - - // Initialise workbook writer - $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel, - $this->_str_total, $this->_str_unique, $this->_str_table, - $this->_colors, $this->_parser); - - // Initialise worksheet writers - $countSheets = $this->_phpExcel->getSheetCount(); - for ($i = 0; $i < $countSheets; ++$i) { - $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->_str_total, $this->_str_unique, - $this->_str_table, $this->_colors, - $this->_parser, - $this->_preCalculateFormulas, - $this->_phpExcel->getSheet($i)); - } - - // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook. - $this->_buildWorksheetEschers(); - $this->_buildWorkbookEscher(); - - // add 15 identical cell style Xfs - // for now, we use the first cellXf instead of cellStyleXf - $cellXfCollection = $this->_phpExcel->getCellXfCollection(); - for ($i = 0; $i < 15; ++$i) { - $this->_writerWorkbook->addXfWriter($cellXfCollection[0], true); - } - - // add all the cell Xfs - foreach ($this->_phpExcel->getCellXfCollection() as $style) { - $this->_writerWorkbook->addXfWriter($style, false); - } - - // add fonts from rich text eleemnts - for ($i = 0; $i < $countSheets; ++$i) { - foreach ($this->_writerWorksheets[$i]->_phpSheet->getCellCollection() as $cellID) { - $cell = $this->_writerWorksheets[$i]->_phpSheet->getCell($cellID); - $cVal = $cell->getValue(); - if ($cVal instanceof PHPExcel_RichText) { - $elements = $cVal->getRichTextElements(); - foreach ($elements as $element) { - if ($element instanceof PHPExcel_RichText_Run) { - $font = $element->getFont(); - $this->_writerWorksheets[$i]->_fntHashIndex[$font->getHashCode()] = $this->_writerWorkbook->_addFont($font); - } - } - } - } - } - - // initialize OLE file - $workbookStreamName = 'Workbook'; - $OLE = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs($workbookStreamName)); - - // Write the worksheet streams before the global workbook stream, - // because the byte sizes of these are needed in the global workbook stream - $worksheetSizes = array(); - for ($i = 0; $i < $countSheets; ++$i) { - $this->_writerWorksheets[$i]->close(); - $worksheetSizes[] = $this->_writerWorksheets[$i]->_datasize; - } - - // add binary data for global workbook stream - $OLE->append($this->_writerWorkbook->writeWorkbook($worksheetSizes)); - - // add binary data for sheet streams - for ($i = 0; $i < $countSheets; ++$i) { - $OLE->append($this->_writerWorksheets[$i]->getData()); - } - - $this->_documentSummaryInformation = $this->_writeDocumentSummaryInformation(); - // initialize OLE Document Summary Information - if(isset($this->_documentSummaryInformation) && !empty($this->_documentSummaryInformation)){ - $OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation')); - $OLE_DocumentSummaryInformation->append($this->_documentSummaryInformation); - } - - $this->_summaryInformation = $this->_writeSummaryInformation(); - // initialize OLE Summary Information - if(isset($this->_summaryInformation) && !empty($this->_summaryInformation)){ - $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation')); - $OLE_SummaryInformation->append($this->_summaryInformation); - } - - // define OLE Parts - $arrRootData = array($OLE); - // initialize OLE Properties file - if(isset($OLE_SummaryInformation)){ - $arrRootData[] = $OLE_SummaryInformation; - } - // initialize OLE Extended Properties file - if(isset($OLE_DocumentSummaryInformation)){ - $arrRootData[] = $OLE_DocumentSummaryInformation; - } - - $root = new PHPExcel_Shared_OLE_PPS_Root(time(), time(), $arrRootData); - // save the OLE file - $res = $root->save($pFilename); - - PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); - } - - /** - * Set temporary storage directory - * - * @deprecated - * @param string $pValue Temporary storage directory - * @throws PHPExcel_Writer_Exception when directory does not exist - * @return PHPExcel_Writer_Excel5 - */ - public function setTempDir($pValue = '') { - return $this; - } - - /** - * Build the Worksheet Escher objects - * - */ - private function _buildWorksheetEschers() - { - // 1-based index to BstoreContainer - $blipIndex = 0; - $lastReducedSpId = 0; - $lastSpId = 0; - - foreach ($this->_phpExcel->getAllsheets() as $sheet) { - // sheet index - $sheetIndex = $sheet->getParent()->getIndex($sheet); - - $escher = null; - - // check if there are any shapes for this sheet - $filterRange = $sheet->getAutoFilter()->getRange(); - if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) { - continue; - } - - // create intermediate Escher object - $escher = new PHPExcel_Shared_Escher(); - - // dgContainer - $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); - - // set the drawing index (we use sheet index + 1) - $dgId = $sheet->getParent()->getIndex($sheet) + 1; - $dgContainer->setDgId($dgId); - $escher->setDgContainer($dgContainer); - - // spgrContainer - $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); - $dgContainer->setSpgrContainer($spgrContainer); - - // add one shape which is the group shape - $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); - $spContainer->setSpgr(true); - $spContainer->setSpType(0); - $spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10); - $spgrContainer->addChild($spContainer); - - // add the shapes - - $countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet - - foreach ($sheet->getDrawingCollection() as $drawing) { - ++$blipIndex; - - ++$countShapes[$sheetIndex]; - - // add the shape - $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); - - // set the shape type - $spContainer->setSpType(0x004B); - // set the shape flag - $spContainer->setSpFlag(0x02); - - // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) - $reducedSpId = $countShapes[$sheetIndex]; - $spId = $reducedSpId - | ($sheet->getParent()->getIndex($sheet) + 1) << 10; - $spContainer->setSpId($spId); - - // keep track of last reducedSpId - $lastReducedSpId = $reducedSpId; - - // keep track of last spId - $lastSpId = $spId; - - // set the BLIP index - $spContainer->setOPT(0x4104, $blipIndex); - - // set coordinates and offsets, client anchor - $coordinates = $drawing->getCoordinates(); - $offsetX = $drawing->getOffsetX(); - $offsetY = $drawing->getOffsetY(); - $width = $drawing->getWidth(); - $height = $drawing->getHeight(); - - $twoAnchor = PHPExcel_Shared_Excel5::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height); - - $spContainer->setStartCoordinates($twoAnchor['startCoordinates']); - $spContainer->setStartOffsetX($twoAnchor['startOffsetX']); - $spContainer->setStartOffsetY($twoAnchor['startOffsetY']); - $spContainer->setEndCoordinates($twoAnchor['endCoordinates']); - $spContainer->setEndOffsetX($twoAnchor['endOffsetX']); - $spContainer->setEndOffsetY($twoAnchor['endOffsetY']); - - $spgrContainer->addChild($spContainer); - } - - // AutoFilters - if(!empty($filterRange)){ - $rangeBounds = PHPExcel_Cell::rangeBoundaries($filterRange); - $iNumColStart = $rangeBounds[0][0]; - $iNumColEnd = $rangeBounds[1][0]; - - $iInc = $iNumColStart; - while($iInc <= $iNumColEnd){ - ++$countShapes[$sheetIndex]; - - // create an Drawing Object for the dropdown - $oDrawing = new PHPExcel_Worksheet_BaseDrawing(); - // get the coordinates of drawing - $cDrawing = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1]; - $oDrawing->setCoordinates($cDrawing); - $oDrawing->setWorksheet($sheet); - - // add the shape - $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); - // set the shape type - $spContainer->setSpType(0x00C9); - // set the shape flag - $spContainer->setSpFlag(0x01); - - // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) - $reducedSpId = $countShapes[$sheetIndex]; - $spId = $reducedSpId - | ($sheet->getParent()->getIndex($sheet) + 1) << 10; - $spContainer->setSpId($spId); - - // keep track of last reducedSpId - $lastReducedSpId = $reducedSpId; - - // keep track of last spId - $lastSpId = $spId; - - $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping - $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape - $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest - $spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash - $spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint - - // set coordinates and offsets, client anchor - $endCoordinates = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::stringFromColumnIndex($iInc - 1)); - $endCoordinates .= $rangeBounds[0][1] + 1; - - $spContainer->setStartCoordinates($cDrawing); - $spContainer->setStartOffsetX(0); - $spContainer->setStartOffsetY(0); - $spContainer->setEndCoordinates($endCoordinates); - $spContainer->setEndOffsetX(0); - $spContainer->setEndOffsetY(0); - - $spgrContainer->addChild($spContainer); - $iInc++; - } - } - - // identifier clusters, used for workbook Escher object - $this->_IDCLs[$dgId] = $lastReducedSpId; - - // set last shape index - $dgContainer->setLastSpId($lastSpId); - - // set the Escher object - $this->_writerWorksheets[$sheetIndex]->setEscher($escher); - } - } - - /** - * Build the Escher object corresponding to the MSODRAWINGGROUP record - */ - private function _buildWorkbookEscher() - { - $escher = null; - - // any drawings in this workbook? - $found = false; - foreach ($this->_phpExcel->getAllSheets() as $sheet) { - if (count($sheet->getDrawingCollection()) > 0) { - $found = true; - break; - } - } - - // nothing to do if there are no drawings - if (!$found) { - return; - } - - // if we reach here, then there are drawings in the workbook - $escher = new PHPExcel_Shared_Escher(); - - // dggContainer - $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); - $escher->setDggContainer($dggContainer); - - // set IDCLs (identifier clusters) - $dggContainer->setIDCLs($this->_IDCLs); - - // this loop is for determining maximum shape identifier of all drawing - $spIdMax = 0; - $totalCountShapes = 0; - $countDrawings = 0; - - foreach ($this->_phpExcel->getAllsheets() as $sheet) { - $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet - - if (count($sheet->getDrawingCollection()) > 0) { - ++$countDrawings; - - foreach ($sheet->getDrawingCollection() as $drawing) { - ++$sheetCountShapes; - ++$totalCountShapes; - - $spId = $sheetCountShapes - | ($this->_phpExcel->getIndex($sheet) + 1) << 10; - $spIdMax = max($spId, $spIdMax); - } - } - } - - $dggContainer->setSpIdMax($spIdMax + 1); - $dggContainer->setCDgSaved($countDrawings); - $dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing - - // bstoreContainer - $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); - $dggContainer->setBstoreContainer($bstoreContainer); - - // the BSE's (all the images) - foreach ($this->_phpExcel->getAllsheets() as $sheet) { - foreach ($sheet->getDrawingCollection() as $drawing) { - if ($drawing instanceof PHPExcel_Worksheet_Drawing) { - - $filename = $drawing->getPath(); - - list($imagesx, $imagesy, $imageFormat) = getimagesize($filename); - - switch ($imageFormat) { - - case 1: // GIF, not supported by BIFF8, we convert to PNG - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; - ob_start(); - imagepng(imagecreatefromgif($filename)); - $blipData = ob_get_contents(); - ob_end_clean(); - break; - - case 2: // JPEG - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; - $blipData = file_get_contents($filename); - break; - - case 3: // PNG - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; - $blipData = file_get_contents($filename); - break; - - case 6: // Windows DIB (BMP), we convert to PNG - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; - ob_start(); - imagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename)); - $blipData = ob_get_contents(); - ob_end_clean(); - break; - - default: continue 2; - - } - - $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); - $blip->setData($blipData); - - $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); - $BSE->setBlipType($blipType); - $BSE->setBlip($blip); - - $bstoreContainer->addBSE($BSE); - - } else if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { - - switch ($drawing->getRenderingFunction()) { - - case PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG: - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; - $renderingFunction = 'imagejpeg'; - break; - - case PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF: - case PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG: - case PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT: - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; - $renderingFunction = 'imagepng'; - break; - - } - - ob_start(); - call_user_func($renderingFunction, $drawing->getImageResource()); - $blipData = ob_get_contents(); - ob_end_clean(); - - $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); - $blip->setData($blipData); - - $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); - $BSE->setBlipType($blipType); - $BSE->setBlip($blip); - - $bstoreContainer->addBSE($BSE); - } - } - } - - // Set the Escher object - $this->_writerWorkbook->setEscher($escher); - } - - /** - * Build the OLE Part for DocumentSummary Information - * @return string - */ - private function _writeDocumentSummaryInformation(){ - - // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) - $data = pack('v', 0xFFFE); - // offset: 2; size: 2; - $data .= pack('v', 0x0000); - // offset: 4; size: 2; OS version - $data .= pack('v', 0x0106); - // offset: 6; size: 2; OS indicator - $data .= pack('v', 0x0002); - // offset: 8; size: 16 - $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); - // offset: 24; size: 4; section count - $data .= pack('V', 0x0001); - - // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae - $data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9); - // offset: 44; size: 4; offset of the start - $data .= pack('V', 0x30); - - // SECTION - $dataSection = array(); - $dataSection_NumProps = 0; - $dataSection_Summary = ''; - $dataSection_Content = ''; - - // GKPIDDSI_CODEPAGE: CodePage - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer - 'data' => array('data' => 1252)); - $dataSection_NumProps++; - - // GKPIDDSI_CATEGORY : Category - if($this->_phpExcel->getProperties()->getCategory()){ - $dataProp = $this->_phpExcel->getProperties()->getCategory(); - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x1E), - 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); - $dataSection_NumProps++; - } - // GKPIDDSI_VERSION :Version of the application that wrote the property storage - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x17), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x03), - 'data' => array('pack' => 'V', 'data' => 0x000C0000)); - $dataSection_NumProps++; - // GKPIDDSI_SCALE : FALSE - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0B), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x0B), - 'data' => array('data' => false)); - $dataSection_NumProps++; - // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x10), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x0B), - 'data' => array('data' => false)); - $dataSection_NumProps++; - // GKPIDDSI_SHAREDOC : FALSE - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x0B), - 'data' => array('data' => false)); - $dataSection_NumProps++; - // GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x16), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x0B), - 'data' => array('data' => false)); - $dataSection_NumProps++; - - // GKPIDDSI_DOCSPARTS - // MS-OSHARED p75 (2.3.3.2.2.1) - // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9) - // cElements - $dataProp = pack('v', 0x0001); - $dataProp .= pack('v', 0x0000); - // array of UnalignedLpstr - // cch - $dataProp .= pack('v', 0x000A); - $dataProp .= pack('v', 0x0000); - // value - $dataProp .= 'Worksheet'.chr(0); - - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x101E), - 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); - $dataSection_NumProps++; - - // GKPIDDSI_HEADINGPAIR - // VtVecHeadingPairValue - // cElements - $dataProp = pack('v', 0x0002); - $dataProp .= pack('v', 0x0000); - // Array of vtHeadingPair - // vtUnalignedString - headingString - // stringType - $dataProp .= pack('v', 0x001E); - // padding - $dataProp .= pack('v', 0x0000); - // UnalignedLpstr - // cch - $dataProp .= pack('v', 0x0013); - $dataProp .= pack('v', 0x0000); - // value - $dataProp .= 'Feuilles de calcul'; - // vtUnalignedString - headingParts - // wType : 0x0003 = 32 bit signed integer - $dataProp .= pack('v', 0x0300); - // padding - $dataProp .= pack('v', 0x0000); - // value - $dataProp .= pack('v', 0x0100); - $dataProp .= pack('v', 0x0000); - $dataProp .= pack('v', 0x0000); - $dataProp .= pack('v', 0x0000); + /** + * PHPExcel object + * + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Total number of shared strings in workbook + * + * @var int + */ + private $_str_total = 0; + + /** + * Number of unique shared strings in workbook + * + * @var int + */ + private $_str_unique = 0; + + /** + * Array of unique shared strings in workbook + * + * @var array + */ + private $_str_table = array(); + + /** + * Color cache. Mapping between RGB value and color index. + * + * @var array + */ + private $_colors; + + /** + * Formula parser + * + * @var PHPExcel_Writer_Excel5_Parser + */ + private $_parser; + + /** + * Identifier clusters for drawings. Used in MSODRAWINGGROUP record. + * + * @var array + */ + private $_IDCLs; + + /** + * Basic OLE object summary information + * + * @var array + */ + private $_summaryInformation; + + /** + * Extended OLE object document summary information + * + * @var array + */ + private $_documentSummaryInformation; + + /** + * Create a new PHPExcel_Writer_Excel5 + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) { + $this->_phpExcel = $phpExcel; + + $this->_parser = new PHPExcel_Writer_Excel5_Parser(); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) { + + // garbage collect + $this->_phpExcel->garbageCollect(); + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + + // initialize colors array + $this->_colors = array(); + + // Initialise workbook writer + $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel, + $this->_str_total, $this->_str_unique, $this->_str_table, + $this->_colors, $this->_parser); + + // Initialise worksheet writers + $countSheets = $this->_phpExcel->getSheetCount(); + for ($i = 0; $i < $countSheets; ++$i) { + $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->_str_total, $this->_str_unique, + $this->_str_table, $this->_colors, + $this->_parser, + $this->_preCalculateFormulas, + $this->_phpExcel->getSheet($i)); + } + + // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook. + $this->_buildWorksheetEschers(); + $this->_buildWorkbookEscher(); + + // add 15 identical cell style Xfs + // for now, we use the first cellXf instead of cellStyleXf + $cellXfCollection = $this->_phpExcel->getCellXfCollection(); + for ($i = 0; $i < 15; ++$i) { + $this->_writerWorkbook->addXfWriter($cellXfCollection[0], true); + } + + // add all the cell Xfs + foreach ($this->_phpExcel->getCellXfCollection() as $style) { + $this->_writerWorkbook->addXfWriter($style, false); + } + + // add fonts from rich text eleemnts + for ($i = 0; $i < $countSheets; ++$i) { + foreach ($this->_writerWorksheets[$i]->_phpSheet->getCellCollection() as $cellID) { + $cell = $this->_writerWorksheets[$i]->_phpSheet->getCell($cellID); + $cVal = $cell->getValue(); + if ($cVal instanceof PHPExcel_RichText) { + $elements = $cVal->getRichTextElements(); + foreach ($elements as $element) { + if ($element instanceof PHPExcel_RichText_Run) { + $font = $element->getFont(); + $this->_writerWorksheets[$i]->_fntHashIndex[$font->getHashCode()] = $this->_writerWorkbook->_addFont($font); + } + } + } + } + } + + // initialize OLE file + $workbookStreamName = 'Workbook'; + $OLE = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs($workbookStreamName)); + + // Write the worksheet streams before the global workbook stream, + // because the byte sizes of these are needed in the global workbook stream + $worksheetSizes = array(); + for ($i = 0; $i < $countSheets; ++$i) { + $this->_writerWorksheets[$i]->close(); + $worksheetSizes[] = $this->_writerWorksheets[$i]->_datasize; + } + + // add binary data for global workbook stream + $OLE->append($this->_writerWorkbook->writeWorkbook($worksheetSizes)); + + // add binary data for sheet streams + for ($i = 0; $i < $countSheets; ++$i) { + $OLE->append($this->_writerWorksheets[$i]->getData()); + } + + $this->_documentSummaryInformation = $this->_writeDocumentSummaryInformation(); + // initialize OLE Document Summary Information + if(isset($this->_documentSummaryInformation) && !empty($this->_documentSummaryInformation)){ + $OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation')); + $OLE_DocumentSummaryInformation->append($this->_documentSummaryInformation); + } + + $this->_summaryInformation = $this->_writeSummaryInformation(); + // initialize OLE Summary Information + if(isset($this->_summaryInformation) && !empty($this->_summaryInformation)){ + $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation')); + $OLE_SummaryInformation->append($this->_summaryInformation); + } + + // define OLE Parts + $arrRootData = array($OLE); + // initialize OLE Properties file + if(isset($OLE_SummaryInformation)){ + $arrRootData[] = $OLE_SummaryInformation; + } + // initialize OLE Extended Properties file + if(isset($OLE_DocumentSummaryInformation)){ + $arrRootData[] = $OLE_DocumentSummaryInformation; + } + + $root = new PHPExcel_Shared_OLE_PPS_Root(time(), time(), $arrRootData); + // save the OLE file + $res = $root->save($pFilename); + + PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + } + + /** + * Set temporary storage directory + * + * @deprecated + * @param string $pValue Temporary storage directory + * @throws PHPExcel_Writer_Exception when directory does not exist + * @return PHPExcel_Writer_Excel5 + */ + public function setTempDir($pValue = '') { + return $this; + } + + /** + * Build the Worksheet Escher objects + * + */ + private function _buildWorksheetEschers() + { + // 1-based index to BstoreContainer + $blipIndex = 0; + $lastReducedSpId = 0; + $lastSpId = 0; + + foreach ($this->_phpExcel->getAllsheets() as $sheet) { + // sheet index + $sheetIndex = $sheet->getParent()->getIndex($sheet); + + $escher = null; + + // check if there are any shapes for this sheet + $filterRange = $sheet->getAutoFilter()->getRange(); + if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) { + continue; + } + + // create intermediate Escher object + $escher = new PHPExcel_Shared_Escher(); + + // dgContainer + $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); + + // set the drawing index (we use sheet index + 1) + $dgId = $sheet->getParent()->getIndex($sheet) + 1; + $dgContainer->setDgId($dgId); + $escher->setDgContainer($dgContainer); + + // spgrContainer + $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); + $dgContainer->setSpgrContainer($spgrContainer); + + // add one shape which is the group shape + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + $spContainer->setSpgr(true); + $spContainer->setSpType(0); + $spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10); + $spgrContainer->addChild($spContainer); + + // add the shapes + + $countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet + + foreach ($sheet->getDrawingCollection() as $drawing) { + ++$blipIndex; + + ++$countShapes[$sheetIndex]; + + // add the shape + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + + // set the shape type + $spContainer->setSpType(0x004B); + // set the shape flag + $spContainer->setSpFlag(0x02); + + // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) + $reducedSpId = $countShapes[$sheetIndex]; + $spId = $reducedSpId + | ($sheet->getParent()->getIndex($sheet) + 1) << 10; + $spContainer->setSpId($spId); + + // keep track of last reducedSpId + $lastReducedSpId = $reducedSpId; + + // keep track of last spId + $lastSpId = $spId; + + // set the BLIP index + $spContainer->setOPT(0x4104, $blipIndex); + + // set coordinates and offsets, client anchor + $coordinates = $drawing->getCoordinates(); + $offsetX = $drawing->getOffsetX(); + $offsetY = $drawing->getOffsetY(); + $width = $drawing->getWidth(); + $height = $drawing->getHeight(); + + $twoAnchor = PHPExcel_Shared_Excel5::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height); + + $spContainer->setStartCoordinates($twoAnchor['startCoordinates']); + $spContainer->setStartOffsetX($twoAnchor['startOffsetX']); + $spContainer->setStartOffsetY($twoAnchor['startOffsetY']); + $spContainer->setEndCoordinates($twoAnchor['endCoordinates']); + $spContainer->setEndOffsetX($twoAnchor['endOffsetX']); + $spContainer->setEndOffsetY($twoAnchor['endOffsetY']); + + $spgrContainer->addChild($spContainer); + } + + // AutoFilters + if(!empty($filterRange)){ + $rangeBounds = PHPExcel_Cell::rangeBoundaries($filterRange); + $iNumColStart = $rangeBounds[0][0]; + $iNumColEnd = $rangeBounds[1][0]; + + $iInc = $iNumColStart; + while($iInc <= $iNumColEnd){ + ++$countShapes[$sheetIndex]; + + // create an Drawing Object for the dropdown + $oDrawing = new PHPExcel_Worksheet_BaseDrawing(); + // get the coordinates of drawing + $cDrawing = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1]; + $oDrawing->setCoordinates($cDrawing); + $oDrawing->setWorksheet($sheet); + + // add the shape + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + // set the shape type + $spContainer->setSpType(0x00C9); + // set the shape flag + $spContainer->setSpFlag(0x01); + + // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) + $reducedSpId = $countShapes[$sheetIndex]; + $spId = $reducedSpId + | ($sheet->getParent()->getIndex($sheet) + 1) << 10; + $spContainer->setSpId($spId); + + // keep track of last reducedSpId + $lastReducedSpId = $reducedSpId; + + // keep track of last spId + $lastSpId = $spId; + + $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping + $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape + $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest + $spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash + $spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint + + // set coordinates and offsets, client anchor + $endCoordinates = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::stringFromColumnIndex($iInc - 1)); + $endCoordinates .= $rangeBounds[0][1] + 1; + + $spContainer->setStartCoordinates($cDrawing); + $spContainer->setStartOffsetX(0); + $spContainer->setStartOffsetY(0); + $spContainer->setEndCoordinates($endCoordinates); + $spContainer->setEndOffsetX(0); + $spContainer->setEndOffsetY(0); + + $spgrContainer->addChild($spContainer); + $iInc++; + } + } + + // identifier clusters, used for workbook Escher object + $this->_IDCLs[$dgId] = $lastReducedSpId; + + // set last shape index + $dgContainer->setLastSpId($lastSpId); + + // set the Escher object + $this->_writerWorksheets[$sheetIndex]->setEscher($escher); + } + } + + /** + * Build the Escher object corresponding to the MSODRAWINGGROUP record + */ + private function _buildWorkbookEscher() + { + $escher = null; + + // any drawings in this workbook? + $found = false; + foreach ($this->_phpExcel->getAllSheets() as $sheet) { + if (count($sheet->getDrawingCollection()) > 0) { + $found = true; + break; + } + } + + // nothing to do if there are no drawings + if (!$found) { + return; + } + + // if we reach here, then there are drawings in the workbook + $escher = new PHPExcel_Shared_Escher(); + + // dggContainer + $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); + $escher->setDggContainer($dggContainer); + + // set IDCLs (identifier clusters) + $dggContainer->setIDCLs($this->_IDCLs); + + // this loop is for determining maximum shape identifier of all drawing + $spIdMax = 0; + $totalCountShapes = 0; + $countDrawings = 0; + + foreach ($this->_phpExcel->getAllsheets() as $sheet) { + $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet + + if (count($sheet->getDrawingCollection()) > 0) { + ++$countDrawings; + + foreach ($sheet->getDrawingCollection() as $drawing) { + ++$sheetCountShapes; + ++$totalCountShapes; + + $spId = $sheetCountShapes + | ($this->_phpExcel->getIndex($sheet) + 1) << 10; + $spIdMax = max($spId, $spIdMax); + } + } + } + + $dggContainer->setSpIdMax($spIdMax + 1); + $dggContainer->setCDgSaved($countDrawings); + $dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing + + // bstoreContainer + $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); + $dggContainer->setBstoreContainer($bstoreContainer); + + // the BSE's (all the images) + foreach ($this->_phpExcel->getAllsheets() as $sheet) { + foreach ($sheet->getDrawingCollection() as $drawing) { + if ($drawing instanceof PHPExcel_Worksheet_Drawing) { + + $filename = $drawing->getPath(); + + list($imagesx, $imagesy, $imageFormat) = getimagesize($filename); + + switch ($imageFormat) { + + case 1: // GIF, not supported by BIFF8, we convert to PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + ob_start(); + imagepng(imagecreatefromgif($filename)); + $blipData = ob_get_contents(); + ob_end_clean(); + break; + + case 2: // JPEG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; + $blipData = file_get_contents($filename); + break; + + case 3: // PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + $blipData = file_get_contents($filename); + break; + + case 6: // Windows DIB (BMP), we convert to PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + ob_start(); + imagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename)); + $blipData = ob_get_contents(); + ob_end_clean(); + break; + + default: continue 2; + + } + + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($blipData); + + $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); + $BSE->setBlipType($blipType); + $BSE->setBlip($blip); + + $bstoreContainer->addBSE($BSE); + + } else if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { + + switch ($drawing->getRenderingFunction()) { + + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG: + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; + $renderingFunction = 'imagejpeg'; + break; + + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF: + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG: + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT: + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + $renderingFunction = 'imagepng'; + break; + + } + + ob_start(); + call_user_func($renderingFunction, $drawing->getImageResource()); + $blipData = ob_get_contents(); + ob_end_clean(); + + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($blipData); + + $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); + $BSE->setBlipType($blipType); + $BSE->setBlip($blip); + + $bstoreContainer->addBSE($BSE); + } + } + } + + // Set the Escher object + $this->_writerWorkbook->setEscher($escher); + } + + /** + * Build the OLE Part for DocumentSummary Information + * @return string + */ + private function _writeDocumentSummaryInformation(){ + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + $data = pack('v', 0xFFFE); + // offset: 2; size: 2; + $data .= pack('v', 0x0000); + // offset: 4; size: 2; OS version + $data .= pack('v', 0x0106); + // offset: 6; size: 2; OS indicator + $data .= pack('v', 0x0002); + // offset: 8; size: 16 + $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); + // offset: 24; size: 4; section count + $data .= pack('V', 0x0001); + + // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae + $data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9); + // offset: 44; size: 4; offset of the start + $data .= pack('V', 0x30); + + // SECTION + $dataSection = array(); + $dataSection_NumProps = 0; + $dataSection_Summary = ''; + $dataSection_Content = ''; + + // GKPIDDSI_CODEPAGE: CodePage + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer + 'data' => array('data' => 1252)); + $dataSection_NumProps++; + + // GKPIDDSI_CATEGORY : Category + if($this->_phpExcel->getProperties()->getCategory()){ + $dataProp = $this->_phpExcel->getProperties()->getCategory(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // GKPIDDSI_VERSION :Version of the application that wrote the property storage + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x17), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x03), + 'data' => array('pack' => 'V', 'data' => 0x000C0000)); + $dataSection_NumProps++; + // GKPIDDSI_SCALE : FALSE + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0B), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x10), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + // GKPIDDSI_SHAREDOC : FALSE + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + // GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x16), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + + // GKPIDDSI_DOCSPARTS + // MS-OSHARED p75 (2.3.3.2.2.1) + // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9) + // cElements + $dataProp = pack('v', 0x0001); + $dataProp .= pack('v', 0x0000); + // array of UnalignedLpstr + // cch + $dataProp .= pack('v', 0x000A); + $dataProp .= pack('v', 0x0000); + // value + $dataProp .= 'Worksheet'.chr(0); + + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x101E), + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + + // GKPIDDSI_HEADINGPAIR + // VtVecHeadingPairValue + // cElements + $dataProp = pack('v', 0x0002); + $dataProp .= pack('v', 0x0000); + // Array of vtHeadingPair + // vtUnalignedString - headingString + // stringType + $dataProp .= pack('v', 0x001E); + // padding + $dataProp .= pack('v', 0x0000); + // UnalignedLpstr + // cch + $dataProp .= pack('v', 0x0013); + $dataProp .= pack('v', 0x0000); + // value + $dataProp .= 'Feuilles de calcul'; + // vtUnalignedString - headingParts + // wType : 0x0003 = 32 bit signed integer + $dataProp .= pack('v', 0x0300); + // padding + $dataProp .= pack('v', 0x0000); + // value + $dataProp .= pack('v', 0x0100); + $dataProp .= pack('v', 0x0000); + $dataProp .= pack('v', 0x0000); + $dataProp .= pack('v', 0x0000); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x100C), - 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x100C), + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + + // 4 Section Length + // 4 Property count + // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) + $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; + foreach ($dataSection as $dataProp){ + // Summary + $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); + // Offset + $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); + // DataType + $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); + // Data + if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x0B){ // Boolean + if($dataProp['data']['data'] == false){ + $dataSection_Content .= pack('V', 0x0000); + } else { + $dataSection_Content .= pack('V', 0x0001); + } + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length + // Null-terminated string + $dataProp['data']['data'] .= chr(0); + $dataProp['data']['length'] += 1; + // Complete the string with null string for being a %4 + $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); + $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); + + $dataSection_Content .= pack('V', $dataProp['data']['length']); + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); + } + elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 8; + } + else { + // Data Type Not Used at the moment + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + $dataProp['data']['length']; + } + } + // Now $dataSection_Content_Offset contains the size of the content + + // section header + // offset: $secOffset; size: 4; section length + // + x Size of the content (summary + content) + $data .= pack('V', $dataSection_Content_Offset); + // offset: $secOffset+4; size: 4; property count + $data .= pack('V', $dataSection_NumProps); + // Section Summary + $data .= $dataSection_Summary; + // Section Content + $data .= $dataSection_Content; + + return $data; + } + + /** + * Build the OLE Part for Summary Information + * @return string + */ + private function _writeSummaryInformation(){ + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + $data = pack('v', 0xFFFE); + // offset: 2; size: 2; + $data .= pack('v', 0x0000); + // offset: 4; size: 2; OS version + $data .= pack('v', 0x0106); + // offset: 6; size: 2; OS indicator + $data .= pack('v', 0x0002); + // offset: 8; size: 16 + $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); + // offset: 24; size: 4; section count + $data .= pack('V', 0x0001); + + // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 + $data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3); + // offset: 44; size: 4; offset of the start + $data .= pack('V', 0x30); + + // SECTION + $dataSection = array(); + $dataSection_NumProps = 0; + $dataSection_Summary = ''; + $dataSection_Content = ''; + + // CodePage : CP-1252 + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer + 'data' => array('data' => 1252)); $dataSection_NumProps++; - // 4 Section Length - // 4 Property count - // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) - $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; - foreach ($dataSection as $dataProp){ - // Summary - $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); - // Offset - $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); - // DataType - $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); - // Data - if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer - $dataSection_Content .= pack('V', $dataProp['data']['data']); - - $dataSection_Content_Offset += 4 + 4; - } - elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer - $dataSection_Content .= pack('V', $dataProp['data']['data']); - - $dataSection_Content_Offset += 4 + 4; - } - elseif($dataProp['type']['data'] == 0x0B){ // Boolean - if($dataProp['data']['data'] == false){ - $dataSection_Content .= pack('V', 0x0000); - } else { - $dataSection_Content .= pack('V', 0x0001); - } - $dataSection_Content_Offset += 4 + 4; - } - elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length - // Null-terminated string - $dataProp['data']['data'] .= chr(0); - $dataProp['data']['length'] += 1; - // Complete the string with null string for being a %4 - $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); - $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); - - $dataSection_Content .= pack('V', $dataProp['data']['length']); - $dataSection_Content .= $dataProp['data']['data']; - - $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); - } - elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) - $dataSection_Content .= $dataProp['data']['data']; - - $dataSection_Content_Offset += 4 + 8; - } - else { - // Data Type Not Used at the moment - $dataSection_Content .= $dataProp['data']['data']; - - $dataSection_Content_Offset += 4 + $dataProp['data']['length']; - } - } - // Now $dataSection_Content_Offset contains the size of the content - - // section header - // offset: $secOffset; size: 4; section length - // + x Size of the content (summary + content) - $data .= pack('V', $dataSection_Content_Offset); - // offset: $secOffset+4; size: 4; property count - $data .= pack('V', $dataSection_NumProps); - // Section Summary - $data .= $dataSection_Summary; - // Section Content - $data .= $dataSection_Content; - - return $data; - } - - /** - * Build the OLE Part for Summary Information - * @return string - */ - private function _writeSummaryInformation(){ - // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) - $data = pack('v', 0xFFFE); - // offset: 2; size: 2; - $data .= pack('v', 0x0000); - // offset: 4; size: 2; OS version - $data .= pack('v', 0x0106); - // offset: 6; size: 2; OS indicator - $data .= pack('v', 0x0002); - // offset: 8; size: 16 - $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); - // offset: 24; size: 4; section count - $data .= pack('V', 0x0001); - - // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 - $data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3); - // offset: 44; size: 4; offset of the start - $data .= pack('V', 0x30); - - // SECTION - $dataSection = array(); - $dataSection_NumProps = 0; - $dataSection_Summary = ''; - $dataSection_Content = ''; - - // CodePage : CP-1252 - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer - 'data' => array('data' => 1252)); - $dataSection_NumProps++; - - // Title - if($this->_phpExcel->getProperties()->getTitle()){ - $dataProp = $this->_phpExcel->getProperties()->getTitle(); - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length - 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); - $dataSection_NumProps++; - } - // Subject - if($this->_phpExcel->getProperties()->getSubject()){ - $dataProp = $this->_phpExcel->getProperties()->getSubject(); - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length - 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); - $dataSection_NumProps++; - } - // Author (Creator) - if($this->_phpExcel->getProperties()->getCreator()){ - $dataProp = $this->_phpExcel->getProperties()->getCreator(); - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length - 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); - $dataSection_NumProps++; - } - // Keywords - if($this->_phpExcel->getProperties()->getKeywords()){ - $dataProp = $this->_phpExcel->getProperties()->getKeywords(); - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length - 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); - $dataSection_NumProps++; - } - // Comments (Description) - if($this->_phpExcel->getProperties()->getDescription()){ - $dataProp = $this->_phpExcel->getProperties()->getDescription(); - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length - 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); - $dataSection_NumProps++; - } - // Last Saved By (LastModifiedBy) - if($this->_phpExcel->getProperties()->getLastModifiedBy()){ - $dataProp = $this->_phpExcel->getProperties()->getLastModifiedBy(); - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length - 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); - $dataSection_NumProps++; - } - // Created Date/Time - if($this->_phpExcel->getProperties()->getCreated()){ - $dataProp = $this->_phpExcel->getProperties()->getCreated(); - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) - 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); - $dataSection_NumProps++; - } - // Modified Date/Time - if($this->_phpExcel->getProperties()->getModified()){ - $dataProp = $this->_phpExcel->getProperties()->getModified(); - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) - 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); - $dataSection_NumProps++; - } - // Security - $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), - 'offset' => array('pack' => 'V'), - 'type' => array('pack' => 'V', 'data' => 0x03), // 4 byte signed integer - 'data' => array('data' => 0x00)); - $dataSection_NumProps++; - - - // 4 Section Length - // 4 Property count - // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) - $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; - foreach ($dataSection as $dataProp){ - // Summary - $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); - // Offset - $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); - // DataType - $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); - // Data - if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer - $dataSection_Content .= pack('V', $dataProp['data']['data']); - - $dataSection_Content_Offset += 4 + 4; - } - elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer - $dataSection_Content .= pack('V', $dataProp['data']['data']); - - $dataSection_Content_Offset += 4 + 4; - } - elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length - // Null-terminated string - $dataProp['data']['data'] .= chr(0); - $dataProp['data']['length'] += 1; - // Complete the string with null string for being a %4 - $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); - $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); - - $dataSection_Content .= pack('V', $dataProp['data']['length']); - $dataSection_Content .= $dataProp['data']['data']; - - $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); - } - elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) - $dataSection_Content .= $dataProp['data']['data']; - - $dataSection_Content_Offset += 4 + 8; - } - else { - // Data Type Not Used at the moment - } - } - // Now $dataSection_Content_Offset contains the size of the content - - // section header - // offset: $secOffset; size: 4; section length - // + x Size of the content (summary + content) - $data .= pack('V', $dataSection_Content_Offset); - // offset: $secOffset+4; size: 4; property count - $data .= pack('V', $dataSection_NumProps); - // Section Summary - $data .= $dataSection_Summary; - // Section Content - $data .= $dataSection_Content; - - return $data; - } + // Title + if($this->_phpExcel->getProperties()->getTitle()){ + $dataProp = $this->_phpExcel->getProperties()->getTitle(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Subject + if($this->_phpExcel->getProperties()->getSubject()){ + $dataProp = $this->_phpExcel->getProperties()->getSubject(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Author (Creator) + if($this->_phpExcel->getProperties()->getCreator()){ + $dataProp = $this->_phpExcel->getProperties()->getCreator(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Keywords + if($this->_phpExcel->getProperties()->getKeywords()){ + $dataProp = $this->_phpExcel->getProperties()->getKeywords(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Comments (Description) + if($this->_phpExcel->getProperties()->getDescription()){ + $dataProp = $this->_phpExcel->getProperties()->getDescription(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Last Saved By (LastModifiedBy) + if($this->_phpExcel->getProperties()->getLastModifiedBy()){ + $dataProp = $this->_phpExcel->getProperties()->getLastModifiedBy(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Created Date/Time + if($this->_phpExcel->getProperties()->getCreated()){ + $dataProp = $this->_phpExcel->getProperties()->getCreated(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); + $dataSection_NumProps++; + } + // Modified Date/Time + if($this->_phpExcel->getProperties()->getModified()){ + $dataProp = $this->_phpExcel->getProperties()->getModified(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); + $dataSection_NumProps++; + } + // Security + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x03), // 4 byte signed integer + 'data' => array('data' => 0x00)); + $dataSection_NumProps++; + + + // 4 Section Length + // 4 Property count + // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) + $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; + foreach ($dataSection as $dataProp){ + // Summary + $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); + // Offset + $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); + // DataType + $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); + // Data + if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length + // Null-terminated string + $dataProp['data']['data'] .= chr(0); + $dataProp['data']['length'] += 1; + // Complete the string with null string for being a %4 + $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); + $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); + + $dataSection_Content .= pack('V', $dataProp['data']['length']); + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); + } + elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 8; + } + else { + // Data Type Not Used at the moment + } + } + // Now $dataSection_Content_Offset contains the size of the content + + // section header + // offset: $secOffset; size: 4; section length + // + x Size of the content (summary + content) + $data .= pack('V', $dataSection_Content_Offset); + // offset: $secOffset+4; size: 4; property count + $data .= pack('V', $dataSection_NumProps); + // Section Summary + $data .= $dataSection_Summary; + // Section Content + $data .= $dataSection_Content; + + return $data; + } } diff --git a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php index 43eb5099f..de0624888 100644 --- a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php +++ b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -69,187 +69,187 @@ */ class PHPExcel_Writer_Excel5_BIFFwriter { - /** - * The byte order of this architecture. 0 => little endian, 1 => big endian - * @var integer - */ - private static $_byte_order; - - /** - * The string containing the data of the BIFF stream - * @var string - */ - public $_data; - - /** - * The size of the data in bytes. Should be the same as strlen($this->_data) - * @var integer - */ - public $_datasize; - - /** - * The maximum length for a BIFF record (excluding record header and length field). See _addContinue() - * @var integer - * @see _addContinue() - */ - public $_limit = 8224; - - /** - * Constructor - */ - public function __construct() - { - $this->_data = ''; - $this->_datasize = 0; -// $this->_limit = 8224; - } - - /** - * Determine the byte order and store it as class data to avoid - * recalculating it for each call to new(). - * - * @return int - */ - public static function getByteOrder() - { - if (!isset(self::$_byte_order)) { - // Check if "pack" gives the required IEEE 64bit float - $teststr = pack("d", 1.2345); - $number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F); - if ($number == $teststr) { - $byte_order = 0; // Little Endian - } elseif ($number == strrev($teststr)){ - $byte_order = 1; // Big Endian - } else { - // Give up. I'll fix this in a later version. - throw new PHPExcel_Writer_Exception("Required floating point format not supported on this platform."); - } - self::$_byte_order = $byte_order; - } - - return self::$_byte_order; - } - - /** - * General storage function - * - * @param string $data binary data to append - * @access private - */ - function _append($data) - { - if (strlen($data) - 4 > $this->_limit) { - $data = $this->_addContinue($data); - } - $this->_data .= $data; - $this->_datasize += strlen($data); - } - - /** - * General storage function like _append, but returns string instead of modifying $this->_data - * - * @param string $data binary data to write - * @return string - */ - public function writeData($data) - { - if (strlen($data) - 4 > $this->_limit) { - $data = $this->_addContinue($data); - } - $this->_datasize += strlen($data); - - return $data; - } - - /** - * Writes Excel BOF record to indicate the beginning of a stream or - * sub-stream in the BIFF file. - * - * @param integer $type Type of BIFF file to write: 0x0005 Workbook, - * 0x0010 Worksheet. - * @access private - */ - function _storeBof($type) - { - $record = 0x0809; // Record identifier (BIFF5-BIFF8) - $length = 0x0010; - - // by inspection of real files, MS Office Excel 2007 writes the following - $unknown = pack("VV", 0x000100D1, 0x00000406); - - $build = 0x0DBB; // Excel 97 - $year = 0x07CC; // Excel 97 - - $version = 0x0600; // BIFF8 - - $header = pack("vv", $record, $length); - $data = pack("vvvv", $version, $type, $build, $year); - $this->_append($header . $data . $unknown); - } - - /** - * Writes Excel EOF record to indicate the end of a BIFF stream. - * - * @access private - */ - function _storeEof() - { - $record = 0x000A; // Record identifier - $length = 0x0000; // Number of bytes to follow - - $header = pack("vv", $record, $length); - $this->_append($header); - } - - /** - * Writes Excel EOF record to indicate the end of a BIFF stream. - * - * @access private - */ - public function writeEof() - { - $record = 0x000A; // Record identifier - $length = 0x0000; // Number of bytes to follow - $header = pack("vv", $record, $length); - return $this->writeData($header); - } - - /** - * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In - * Excel 97 the limit is 8228 bytes. Records that are longer than these limits - * must be split up into CONTINUE blocks. - * - * This function takes a long BIFF record and inserts CONTINUE records as - * necessary. - * - * @param string $data The original binary data to be written - * @return string A very convenient string of continue blocks - * @access private - */ - function _addContinue($data) - { - $limit = $this->_limit; - $record = 0x003C; // Record identifier - - // The first 2080/8224 bytes remain intact. However, we have to change - // the length field of the record. - $tmp = substr($data, 0, 2) . pack("v", $limit) . substr($data, 4, $limit); - - $header = pack("vv", $record, $limit); // Headers for continue records - - // Retrieve chunks of 2080/8224 bytes +4 for the header. - $data_length = strlen($data); - for ($i = $limit + 4; $i < ($data_length - $limit); $i += $limit) { - $tmp .= $header; - $tmp .= substr($data, $i, $limit); - } - - // Retrieve the last chunk of data - $header = pack("vv", $record, strlen($data) - $i); - $tmp .= $header; - $tmp .= substr($data, $i, strlen($data) - $i); - - return $tmp; - } + /** + * The byte order of this architecture. 0 => little endian, 1 => big endian + * @var integer + */ + private static $_byte_order; + + /** + * The string containing the data of the BIFF stream + * @var string + */ + public $_data; + + /** + * The size of the data in bytes. Should be the same as strlen($this->_data) + * @var integer + */ + public $_datasize; + + /** + * The maximum length for a BIFF record (excluding record header and length field). See _addContinue() + * @var integer + * @see _addContinue() + */ + public $_limit = 8224; + + /** + * Constructor + */ + public function __construct() + { + $this->_data = ''; + $this->_datasize = 0; +// $this->_limit = 8224; + } + + /** + * Determine the byte order and store it as class data to avoid + * recalculating it for each call to new(). + * + * @return int + */ + public static function getByteOrder() + { + if (!isset(self::$_byte_order)) { + // Check if "pack" gives the required IEEE 64bit float + $teststr = pack("d", 1.2345); + $number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F); + if ($number == $teststr) { + $byte_order = 0; // Little Endian + } elseif ($number == strrev($teststr)){ + $byte_order = 1; // Big Endian + } else { + // Give up. I'll fix this in a later version. + throw new PHPExcel_Writer_Exception("Required floating point format not supported on this platform."); + } + self::$_byte_order = $byte_order; + } + + return self::$_byte_order; + } + + /** + * General storage function + * + * @param string $data binary data to append + * @access private + */ + function _append($data) + { + if (strlen($data) - 4 > $this->_limit) { + $data = $this->_addContinue($data); + } + $this->_data .= $data; + $this->_datasize += strlen($data); + } + + /** + * General storage function like _append, but returns string instead of modifying $this->_data + * + * @param string $data binary data to write + * @return string + */ + public function writeData($data) + { + if (strlen($data) - 4 > $this->_limit) { + $data = $this->_addContinue($data); + } + $this->_datasize += strlen($data); + + return $data; + } + + /** + * Writes Excel BOF record to indicate the beginning of a stream or + * sub-stream in the BIFF file. + * + * @param integer $type Type of BIFF file to write: 0x0005 Workbook, + * 0x0010 Worksheet. + * @access private + */ + function _storeBof($type) + { + $record = 0x0809; // Record identifier (BIFF5-BIFF8) + $length = 0x0010; + + // by inspection of real files, MS Office Excel 2007 writes the following + $unknown = pack("VV", 0x000100D1, 0x00000406); + + $build = 0x0DBB; // Excel 97 + $year = 0x07CC; // Excel 97 + + $version = 0x0600; // BIFF8 + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $version, $type, $build, $year); + $this->_append($header . $data . $unknown); + } + + /** + * Writes Excel EOF record to indicate the end of a BIFF stream. + * + * @access private + */ + function _storeEof() + { + $record = 0x000A; // Record identifier + $length = 0x0000; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $this->_append($header); + } + + /** + * Writes Excel EOF record to indicate the end of a BIFF stream. + * + * @access private + */ + public function writeEof() + { + $record = 0x000A; // Record identifier + $length = 0x0000; // Number of bytes to follow + $header = pack("vv", $record, $length); + return $this->writeData($header); + } + + /** + * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In + * Excel 97 the limit is 8228 bytes. Records that are longer than these limits + * must be split up into CONTINUE blocks. + * + * This function takes a long BIFF record and inserts CONTINUE records as + * necessary. + * + * @param string $data The original binary data to be written + * @return string A very convenient string of continue blocks + * @access private + */ + function _addContinue($data) + { + $limit = $this->_limit; + $record = 0x003C; // Record identifier + + // The first 2080/8224 bytes remain intact. However, we have to change + // the length field of the record. + $tmp = substr($data, 0, 2) . pack("v", $limit) . substr($data, 4, $limit); + + $header = pack("vv", $record, $limit); // Headers for continue records + + // Retrieve chunks of 2080/8224 bytes +4 for the header. + $data_length = strlen($data); + for ($i = $limit + 4; $i < ($data_length - $limit); $i += $limit) { + $tmp .= $header; + $tmp .= substr($data, $i, $limit); + } + + // Retrieve the last chunk of data + $header = pack("vv", $record, strlen($data) - $i); + $tmp .= $header; + $tmp .= substr($data, $i, strlen($data) - $i); + + return $tmp; + } } diff --git a/Classes/PHPExcel/Writer/Excel5/Escher.php b/Classes/PHPExcel/Writer/Excel5/Escher.php index a9007867c..9b8ae8714 100644 --- a/Classes/PHPExcel/Writer/Excel5/Escher.php +++ b/Classes/PHPExcel/Writer/Excel5/Escher.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,503 +35,503 @@ */ class PHPExcel_Writer_Excel5_Escher { - /** - * The object we are writing - */ - private $_object; - - /** - * The written binary data - */ - private $_data; - - /** - * Shape offsets. Positions in binary stream where a new shape record begins - * - * @var array - */ - private $_spOffsets; - - /** - * Shape types. - * - * @var array - */ - private $_spTypes; - - /** - * Constructor - * - * @param mixed - */ - public function __construct($object) - { - $this->_object = $object; - } - - /** - * Process the object to be written - */ - public function close() - { - // initialize - $this->_data = ''; - - switch (get_class($this->_object)) { - - case 'PHPExcel_Shared_Escher': - if ($dggContainer = $this->_object->getDggContainer()) { - $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer); - $this->_data = $writer->close(); - } else if ($dgContainer = $this->_object->getDgContainer()) { - $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer); - $this->_data = $writer->close(); - $this->_spOffsets = $writer->getSpOffsets(); - $this->_spTypes = $writer->getSpTypes(); - } - break; - - case 'PHPExcel_Shared_Escher_DggContainer': - // this is a container record - - // initialize - $innerData = ''; - - // write the dgg - $recVer = 0x0; - $recInstance = 0x0000; - $recType = 0xF006; - - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; - - // dgg data - $dggData = - pack('VVVV' - , $this->_object->getSpIdMax() // maximum shape identifier increased by one - , $this->_object->getCDgSaved() + 1 // number of file identifier clusters increased by one - , $this->_object->getCSpSaved() - , $this->_object->getCDgSaved() // count total number of drawings saved - ); - - // add file identifier clusters (one per drawing) - $IDCLs = $this->_object->getIDCLs(); - - foreach ($IDCLs as $dgId => $maxReducedSpId) { - $dggData .= pack('VV', $dgId, $maxReducedSpId + 1); - } - - $header = pack('vvV', $recVerInstance, $recType, strlen($dggData)); - $innerData .= $header . $dggData; - - // write the bstoreContainer - if ($bstoreContainer = $this->_object->getBstoreContainer()) { - $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer); - $innerData .= $writer->close(); - } - - // write the record - $recVer = 0xF; - $recInstance = 0x0000; - $recType = 0xF000; - $length = strlen($innerData); - - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; - - $header = pack('vvV', $recVerInstance, $recType, $length); - - $this->_data = $header . $innerData; - break; - - case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer': - // this is a container record - - // initialize - $innerData = ''; - - // treat the inner data - if ($BSECollection = $this->_object->getBSECollection()) { - foreach ($BSECollection as $BSE) { - $writer = new PHPExcel_Writer_Excel5_Escher($BSE); - $innerData .= $writer->close(); - } - } - - // write the record - $recVer = 0xF; - $recInstance = count($this->_object->getBSECollection()); - $recType = 0xF001; - $length = strlen($innerData); + /** + * The object we are writing + */ + private $_object; + + /** + * The written binary data + */ + private $_data; + + /** + * Shape offsets. Positions in binary stream where a new shape record begins + * + * @var array + */ + private $_spOffsets; + + /** + * Shape types. + * + * @var array + */ + private $_spTypes; + + /** + * Constructor + * + * @param mixed + */ + public function __construct($object) + { + $this->_object = $object; + } + + /** + * Process the object to be written + */ + public function close() + { + // initialize + $this->_data = ''; + + switch (get_class($this->_object)) { + + case 'PHPExcel_Shared_Escher': + if ($dggContainer = $this->_object->getDggContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer); + $this->_data = $writer->close(); + } else if ($dgContainer = $this->_object->getDgContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer); + $this->_data = $writer->close(); + $this->_spOffsets = $writer->getSpOffsets(); + $this->_spTypes = $writer->getSpTypes(); + } + break; + + case 'PHPExcel_Shared_Escher_DggContainer': + // this is a container record + + // initialize + $innerData = ''; + + // write the dgg + $recVer = 0x0; + $recInstance = 0x0000; + $recType = 0xF006; + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + // dgg data + $dggData = + pack('VVVV' + , $this->_object->getSpIdMax() // maximum shape identifier increased by one + , $this->_object->getCDgSaved() + 1 // number of file identifier clusters increased by one + , $this->_object->getCSpSaved() + , $this->_object->getCDgSaved() // count total number of drawings saved + ); + + // add file identifier clusters (one per drawing) + $IDCLs = $this->_object->getIDCLs(); + + foreach ($IDCLs as $dgId => $maxReducedSpId) { + $dggData .= pack('VV', $dgId, $maxReducedSpId + 1); + } + + $header = pack('vvV', $recVerInstance, $recType, strlen($dggData)); + $innerData .= $header . $dggData; + + // write the bstoreContainer + if ($bstoreContainer = $this->_object->getBstoreContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer); + $innerData .= $writer->close(); + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF000; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $innerData; + break; + + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer': + // this is a container record + + // initialize + $innerData = ''; + + // treat the inner data + if ($BSECollection = $this->_object->getBSECollection()) { + foreach ($BSECollection as $BSE) { + $writer = new PHPExcel_Writer_Excel5_Escher($BSE); + $innerData .= $writer->close(); + } + } + + // write the record + $recVer = 0xF; + $recInstance = count($this->_object->getBSECollection()); + $recType = 0xF001; + $length = strlen($innerData); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); + $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header . $innerData; - break; + $this->_data = $header . $innerData; + break; - case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE': - // this is a semi-container record + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE': + // this is a semi-container record - // initialize - $innerData = ''; + // initialize + $innerData = ''; - // here we treat the inner data - if ($blip = $this->_object->getBlip()) { - $writer = new PHPExcel_Writer_Excel5_Escher($blip); - $innerData .= $writer->close(); - } + // here we treat the inner data + if ($blip = $this->_object->getBlip()) { + $writer = new PHPExcel_Writer_Excel5_Escher($blip); + $innerData .= $writer->close(); + } - // initialize - $data = ''; + // initialize + $data = ''; - $btWin32 = $this->_object->getBlipType(); - $btMacOS = $this->_object->getBlipType(); - $data .= pack('CC', $btWin32, $btMacOS); + $btWin32 = $this->_object->getBlipType(); + $btMacOS = $this->_object->getBlipType(); + $data .= pack('CC', $btWin32, $btMacOS); - $rgbUid = pack('VVVV', 0,0,0,0); // todo - $data .= $rgbUid; + $rgbUid = pack('VVVV', 0,0,0,0); // todo + $data .= $rgbUid; - $tag = 0; - $size = strlen($innerData); - $cRef = 1; - $foDelay = 0; //todo - $unused1 = 0x0; - $cbName = 0x0; - $unused2 = 0x0; - $unused3 = 0x0; - $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3); + $tag = 0; + $size = strlen($innerData); + $cRef = 1; + $foDelay = 0; //todo + $unused1 = 0x0; + $cbName = 0x0; + $unused2 = 0x0; + $unused3 = 0x0; + $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3); - $data .= $innerData; + $data .= $innerData; - // write the record - $recVer = 0x2; - $recInstance = $this->_object->getBlipType(); - $recType = 0xF007; - $length = strlen($data); + // write the record + $recVer = 0x2; + $recInstance = $this->_object->getBlipType(); + $recType = 0xF007; + $length = strlen($data); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); + $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header; + $this->_data = $header; - $this->_data .= $data; - break; + $this->_data .= $data; + break; - case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip': - // this is an atom record + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip': + // this is an atom record - // write the record - switch ($this->_object->getParent()->getBlipType()) { + // write the record + switch ($this->_object->getParent()->getBlipType()) { - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: - // initialize - $innerData = ''; + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: + // initialize + $innerData = ''; - $rgbUid1 = pack('VVVV', 0,0,0,0); // todo - $innerData .= $rgbUid1; + $rgbUid1 = pack('VVVV', 0,0,0,0); // todo + $innerData .= $rgbUid1; - $tag = 0xFF; // todo - $innerData .= pack('C', $tag); + $tag = 0xFF; // todo + $innerData .= pack('C', $tag); - $innerData .= $this->_object->getData(); + $innerData .= $this->_object->getData(); - $recVer = 0x0; - $recInstance = 0x46A; - $recType = 0xF01D; - $length = strlen($innerData); + $recVer = 0x0; + $recInstance = 0x46A; + $recType = 0xF01D; + $length = strlen($innerData); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); + $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header; + $this->_data = $header; - $this->_data .= $innerData; - break; + $this->_data .= $innerData; + break; - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: - // initialize - $innerData = ''; + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: + // initialize + $innerData = ''; - $rgbUid1 = pack('VVVV', 0,0,0,0); // todo - $innerData .= $rgbUid1; + $rgbUid1 = pack('VVVV', 0,0,0,0); // todo + $innerData .= $rgbUid1; - $tag = 0xFF; // todo - $innerData .= pack('C', $tag); + $tag = 0xFF; // todo + $innerData .= pack('C', $tag); - $innerData .= $this->_object->getData(); + $innerData .= $this->_object->getData(); - $recVer = 0x0; - $recInstance = 0x6E0; - $recType = 0xF01E; - $length = strlen($innerData); + $recVer = 0x0; + $recInstance = 0x6E0; + $recType = 0xF01E; + $length = strlen($innerData); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); + $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header; + $this->_data = $header; - $this->_data .= $innerData; - break; + $this->_data .= $innerData; + break; - } - break; + } + break; - case 'PHPExcel_Shared_Escher_DgContainer': - // this is a container record + case 'PHPExcel_Shared_Escher_DgContainer': + // this is a container record - // initialize - $innerData = ''; + // initialize + $innerData = ''; - // write the dg - $recVer = 0x0; - $recInstance = $this->_object->getDgId(); - $recType = 0xF008; - $length = 8; + // write the dg + $recVer = 0x0; + $recInstance = $this->_object->getDgId(); + $recType = 0xF008; + $length = 8; - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); + $header = pack('vvV', $recVerInstance, $recType, $length); - // number of shapes in this drawing (including group shape) - $countShapes = count($this->_object->getSpgrContainer()->getChildren()); - $innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId()); - //$innerData .= $header . pack('VV', 0, 0); + // number of shapes in this drawing (including group shape) + $countShapes = count($this->_object->getSpgrContainer()->getChildren()); + $innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId()); + //$innerData .= $header . pack('VV', 0, 0); - // write the spgrContainer - if ($spgrContainer = $this->_object->getSpgrContainer()) { - $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer); - $innerData .= $writer->close(); + // write the spgrContainer + if ($spgrContainer = $this->_object->getSpgrContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer); + $innerData .= $writer->close(); - // get the shape offsets relative to the spgrContainer record - $spOffsets = $writer->getSpOffsets(); - $spTypes = $writer->getSpTypes(); - - // save the shape offsets relative to dgContainer - foreach ($spOffsets as & $spOffset) { - $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes) - } + // get the shape offsets relative to the spgrContainer record + $spOffsets = $writer->getSpOffsets(); + $spTypes = $writer->getSpTypes(); + + // save the shape offsets relative to dgContainer + foreach ($spOffsets as & $spOffset) { + $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes) + } - $this->_spOffsets = $spOffsets; - $this->_spTypes = $spTypes; - } + $this->_spOffsets = $spOffsets; + $this->_spTypes = $spTypes; + } - // write the record - $recVer = 0xF; - $recInstance = 0x0000; - $recType = 0xF002; - $length = strlen($innerData); + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF002; + $length = strlen($innerData); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); + $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header . $innerData; - break; + $this->_data = $header . $innerData; + break; - case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer': - // this is a container record + case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer': + // this is a container record - // initialize - $innerData = ''; + // initialize + $innerData = ''; - // initialize spape offsets - $totalSize = 8; - $spOffsets = array(); - $spTypes = array(); + // initialize spape offsets + $totalSize = 8; + $spOffsets = array(); + $spTypes = array(); - // treat the inner data - foreach ($this->_object->getChildren() as $spContainer) { - $writer = new PHPExcel_Writer_Excel5_Escher($spContainer); - $spData = $writer->close(); - $innerData .= $spData; + // treat the inner data + foreach ($this->_object->getChildren() as $spContainer) { + $writer = new PHPExcel_Writer_Excel5_Escher($spContainer); + $spData = $writer->close(); + $innerData .= $spData; - // save the shape offsets (where new shape records begin) - $totalSize += strlen($spData); - $spOffsets[] = $totalSize; - - $spTypes = array_merge($spTypes, $writer->getSpTypes()); - } + // save the shape offsets (where new shape records begin) + $totalSize += strlen($spData); + $spOffsets[] = $totalSize; + + $spTypes = array_merge($spTypes, $writer->getSpTypes()); + } - // write the record - $recVer = 0xF; - $recInstance = 0x0000; - $recType = 0xF003; - $length = strlen($innerData); + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF003; + $length = strlen($innerData); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); + $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header . $innerData; - $this->_spOffsets = $spOffsets; - $this->_spTypes = $spTypes; - break; + $this->_data = $header . $innerData; + $this->_spOffsets = $spOffsets; + $this->_spTypes = $spTypes; + break; - case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer': - // initialize - $data = ''; + case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer': + // initialize + $data = ''; - // build the data + // build the data - // write group shape record, if necessary? - if ($this->_object->getSpgr()) { - $recVer = 0x1; - $recInstance = 0x0000; - $recType = 0xF009; - $length = 0x00000010; + // write group shape record, if necessary? + if ($this->_object->getSpgr()) { + $recVer = 0x1; + $recInstance = 0x0000; + $recType = 0xF009; + $length = 0x00000010; - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); + $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . pack('VVVV', 0,0,0,0); - } - $this->_spTypes[] = ($this->_object->getSpType()); + $data .= $header . pack('VVVV', 0,0,0,0); + } + $this->_spTypes[] = ($this->_object->getSpType()); - // write the shape record - $recVer = 0x2; - $recInstance = $this->_object->getSpType(); // shape type - $recType = 0xF00A; - $length = 0x00000008; + // write the shape record + $recVer = 0x2; + $recInstance = $this->_object->getSpType(); // shape type + $recType = 0xF00A; + $length = 0x00000008; - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); + $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x0005 : 0x0A00); + $data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x0005 : 0x0A00); - // the options - if ($this->_object->getOPTCollection()) { - $optData = ''; + // the options + if ($this->_object->getOPTCollection()) { + $optData = ''; - $recVer = 0x3; - $recInstance = count($this->_object->getOPTCollection()); - $recType = 0xF00B; - foreach ($this->_object->getOPTCollection() as $property => $value) { - $optData .= pack('vV', $property, $value); - } - $length = strlen($optData); + $recVer = 0x3; + $recInstance = count($this->_object->getOPTCollection()); + $recType = 0xF00B; + foreach ($this->_object->getOPTCollection() as $property => $value) { + $optData .= pack('vV', $property, $value); + } + $length = strlen($optData); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . $optData; - } + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $optData; + } - // the client anchor - if ($this->_object->getStartCoordinates()) { - $clientAnchorData = ''; - - $recVer = 0x0; - $recInstance = 0x0; - $recType = 0xF010; - - // start coordinates - list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates()); - $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1; - $r1 = $row - 1; - - // start offsetX - $startOffsetX = $this->_object->getStartOffsetX(); - - // start offsetY - $startOffsetY = $this->_object->getStartOffsetY(); - - // end coordinates - list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates()); - $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1; - $r2 = $row - 1; - - // end offsetX - $endOffsetX = $this->_object->getEndOffsetX(); + // the client anchor + if ($this->_object->getStartCoordinates()) { + $clientAnchorData = ''; + + $recVer = 0x0; + $recInstance = 0x0; + $recType = 0xF010; + + // start coordinates + list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates()); + $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1; + $r1 = $row - 1; + + // start offsetX + $startOffsetX = $this->_object->getStartOffsetX(); + + // start offsetY + $startOffsetY = $this->_object->getStartOffsetY(); + + // end coordinates + list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates()); + $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1; + $r2 = $row - 1; + + // end offsetX + $endOffsetX = $this->_object->getEndOffsetX(); - // end offsetY - $endOffsetY = $this->_object->getEndOffsetY(); + // end offsetY + $endOffsetY = $this->_object->getEndOffsetY(); - $clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(), - $c1, $startOffsetX, $r1, $startOffsetY, - $c2, $endOffsetX, $r2, $endOffsetY); - - $length = strlen($clientAnchorData); + $clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(), + $c1, $startOffsetX, $r1, $startOffsetY, + $c2, $endOffsetX, $r2, $endOffsetY); + + $length = strlen($clientAnchorData); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . $clientAnchorData; - } + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $clientAnchorData; + } - // the client data, just empty for now - if (!$this->_object->getSpgr()) { - $clientDataData = ''; + // the client data, just empty for now + if (!$this->_object->getSpgr()) { + $clientDataData = ''; - $recVer = 0x0; - $recInstance = 0x0; - $recType = 0xF011; + $recVer = 0x0; + $recInstance = 0x0; + $recType = 0xF011; - $length = strlen($clientDataData); - - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $length = strlen($clientDataData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . $clientDataData; - } + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $clientDataData; + } - // write the record - $recVer = 0xF; - $recInstance = 0x0000; - $recType = 0xF004; - $length = strlen($data); + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF004; + $length = strlen($data); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; - - $header = pack('vvV', $recVerInstance, $recType, $length); + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header . $data; - break; + $this->_data = $header . $data; + break; - } + } - return $this->_data; - } - - /** - * Gets the shape offsets - * - * @return array - */ - public function getSpOffsets() - { - return $this->_spOffsets; - } - - /** - * Gets the shape types - * - * @return array - */ - public function getSpTypes() - { - return $this->_spTypes; - } - - + return $this->_data; + } + + /** + * Gets the shape offsets + * + * @return array + */ + public function getSpOffsets() + { + return $this->_spOffsets; + } + + /** + * Gets the shape types + * + * @return array + */ + public function getSpTypes() + { + return $this->_spTypes; + } + + } diff --git a/Classes/PHPExcel/Writer/Excel5/Font.php b/Classes/PHPExcel/Writer/Excel5/Font.php index 997791693..d4543db19 100644 --- a/Classes/PHPExcel/Writer/Excel5/Font.php +++ b/Classes/PHPExcel/Writer/Excel5/Font.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,131 +35,131 @@ */ class PHPExcel_Writer_Excel5_Font { - /** - * Color index - * - * @var int - */ - private $_colorIndex; + /** + * Color index + * + * @var int + */ + private $_colorIndex; - /** - * Font - * - * @var PHPExcel_Style_Font - */ - private $_font; + /** + * Font + * + * @var PHPExcel_Style_Font + */ + private $_font; - /** - * Constructor - * - * @param PHPExcel_Style_Font $font - */ - public function __construct(PHPExcel_Style_Font $font = null) - { - $this->_colorIndex = 0x7FFF; - $this->_font = $font; - } + /** + * Constructor + * + * @param PHPExcel_Style_Font $font + */ + public function __construct(PHPExcel_Style_Font $font = null) + { + $this->_colorIndex = 0x7FFF; + $this->_font = $font; + } - /** - * Set the color index - * - * @param int $colorIndex - */ - public function setColorIndex($colorIndex) - { - $this->_colorIndex = $colorIndex; - } + /** + * Set the color index + * + * @param int $colorIndex + */ + public function setColorIndex($colorIndex) + { + $this->_colorIndex = $colorIndex; + } - /** - * Get font record data - * - * @return string - */ - public function writeFont() - { - $font_outline = 0; - $font_shadow = 0; + /** + * Get font record data + * + * @return string + */ + public function writeFont() + { + $font_outline = 0; + $font_shadow = 0; - $icv = $this->_colorIndex; // Index to color palette - if ($this->_font->getSuperScript()) { - $sss = 1; - } else if ($this->_font->getSubScript()) { - $sss = 2; - } else { - $sss = 0; - } - $bFamily = 0; // Font family - $bCharSet = PHPExcel_Shared_Font::getCharsetFromFontName($this->_font->getName()); // Character set + $icv = $this->_colorIndex; // Index to color palette + if ($this->_font->getSuperScript()) { + $sss = 1; + } else if ($this->_font->getSubScript()) { + $sss = 2; + } else { + $sss = 0; + } + $bFamily = 0; // Font family + $bCharSet = PHPExcel_Shared_Font::getCharsetFromFontName($this->_font->getName()); // Character set - $record = 0x31; // Record identifier - $reserved = 0x00; // Reserved - $grbit = 0x00; // Font attributes - if ($this->_font->getItalic()) { - $grbit |= 0x02; - } - if ($this->_font->getStrikethrough()) { - $grbit |= 0x08; - } - if ($font_outline) { - $grbit |= 0x10; - } - if ($font_shadow) { - $grbit |= 0x20; - } + $record = 0x31; // Record identifier + $reserved = 0x00; // Reserved + $grbit = 0x00; // Font attributes + if ($this->_font->getItalic()) { + $grbit |= 0x02; + } + if ($this->_font->getStrikethrough()) { + $grbit |= 0x08; + } + if ($font_outline) { + $grbit |= 0x10; + } + if ($font_shadow) { + $grbit |= 0x20; + } - $data = pack("vvvvvCCCC", - $this->_font->getSize() * 20, // Fontsize (in twips) - $grbit, - $icv, // Colour - self::_mapBold($this->_font->getBold()), // Font weight - $sss, // Superscript/Subscript - self::_mapUnderline($this->_font->getUnderline()), - $bFamily, - $bCharSet, - $reserved - ); - $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($this->_font->getName()); + $data = pack("vvvvvCCCC", + $this->_font->getSize() * 20, // Fontsize (in twips) + $grbit, + $icv, // Colour + self::_mapBold($this->_font->getBold()), // Font weight + $sss, // Superscript/Subscript + self::_mapUnderline($this->_font->getUnderline()), + $bFamily, + $bCharSet, + $reserved + ); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($this->_font->getName()); - $length = strlen($data); - $header = pack("vv", $record, $length); + $length = strlen($data); + $header = pack("vv", $record, $length); - return($header . $data); - } + return($header . $data); + } - /** - * Map to BIFF5-BIFF8 codes for bold - * - * @param boolean $bold - * @return int - */ - private static function _mapBold($bold) { - if ($bold) { - return 0x2BC; // 700 = Bold font weight - } - return 0x190; // 400 = Normal font weight - } + /** + * Map to BIFF5-BIFF8 codes for bold + * + * @param boolean $bold + * @return int + */ + private static function _mapBold($bold) { + if ($bold) { + return 0x2BC; // 700 = Bold font weight + } + return 0x190; // 400 = Normal font weight + } - /** - * Map of BIFF2-BIFF8 codes for underline styles - * @static array of int - * - */ - private static $_mapUnderline = array( PHPExcel_Style_Font::UNDERLINE_NONE => 0x00, - PHPExcel_Style_Font::UNDERLINE_SINGLE => 0x01, - PHPExcel_Style_Font::UNDERLINE_DOUBLE => 0x02, - PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING => 0x21, - PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING => 0x22, - ); - /** - * Map underline - * - * @param string - * @return int - */ - private static function _mapUnderline($underline) { - if (isset(self::$_mapUnderline[$underline])) - return self::$_mapUnderline[$underline]; - return 0x00; - } + /** + * Map of BIFF2-BIFF8 codes for underline styles + * @static array of int + * + */ + private static $_mapUnderline = array( PHPExcel_Style_Font::UNDERLINE_NONE => 0x00, + PHPExcel_Style_Font::UNDERLINE_SINGLE => 0x01, + PHPExcel_Style_Font::UNDERLINE_DOUBLE => 0x02, + PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING => 0x21, + PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING => 0x22, + ); + /** + * Map underline + * + * @param string + * @return int + */ + private static function _mapUnderline($underline) { + if (isset(self::$_mapUnderline[$underline])) + return self::$_mapUnderline[$underline]; + return 0x00; + } } diff --git a/Classes/PHPExcel/Writer/Excel5/Parser.php b/Classes/PHPExcel/Writer/Excel5/Parser.php index 0379631b3..c9b0bef7a 100644 --- a/Classes/PHPExcel/Writer/Excel5/Parser.php +++ b/Classes/PHPExcel/Writer/Excel5/Parser.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -59,1525 +59,1525 @@ */ class PHPExcel_Writer_Excel5_Parser { - /** Constants */ - // Sheet title in unquoted form - // Invalid sheet title characters cannot occur in the sheet title: - // *:/\?[] - // Moreover, there are valid sheet title characters that cannot occur in unquoted form (there may be more?) - // +-% '^&<>=,;#()"{} - const REGEX_SHEET_TITLE_UNQUOTED = '[^\*\:\/\\\\\?\[\]\+\-\% \\\'\^\&\<\>\=\,\;\#\(\)\"\{\}]+'; - - // Sheet title in quoted form (without surrounding quotes) - // Invalid sheet title characters cannot occur in the sheet title: - // *:/\?[] (usual invalid sheet title characters) - // Single quote is represented as a pair '' - const REGEX_SHEET_TITLE_QUOTED = '(([^\*\:\/\\\\\?\[\]\\\'])+|(\\\'\\\')+)+'; - - /** - * The index of the character we are currently looking at - * @var integer - */ - public $_current_char; - - /** - * The token we are working on. - * @var string - */ - public $_current_token; - - /** - * The formula to parse - * @var string - */ - public $_formula; - - /** - * The character ahead of the current char - * @var string - */ - public $_lookahead; - - /** - * The parse tree to be generated - * @var string - */ - public $_parse_tree; - - /** - * Array of external sheets - * @var array - */ - public $_ext_sheets; - - /** - * Array of sheet references in the form of REF structures - * @var array - */ - public $_references; - - /** - * The class constructor - * - */ - public function __construct() - { - $this->_current_char = 0; - $this->_current_token = ''; // The token we are working on. - $this->_formula = ''; // The formula to parse. - $this->_lookahead = ''; // The character ahead of the current char. - $this->_parse_tree = ''; // The parse tree to be generated. - $this->_initializeHashes(); // Initialize the hashes: ptg's and function's ptg's - $this->_ext_sheets = array(); - $this->_references = array(); - } - - /** - * Initialize the ptg and function hashes. - * - * @access private - */ - function _initializeHashes() - { - // The Excel ptg indices - $this->ptg = array( - 'ptgExp' => 0x01, - 'ptgTbl' => 0x02, - 'ptgAdd' => 0x03, - 'ptgSub' => 0x04, - 'ptgMul' => 0x05, - 'ptgDiv' => 0x06, - 'ptgPower' => 0x07, - 'ptgConcat' => 0x08, - 'ptgLT' => 0x09, - 'ptgLE' => 0x0A, - 'ptgEQ' => 0x0B, - 'ptgGE' => 0x0C, - 'ptgGT' => 0x0D, - 'ptgNE' => 0x0E, - 'ptgIsect' => 0x0F, - 'ptgUnion' => 0x10, - 'ptgRange' => 0x11, - 'ptgUplus' => 0x12, - 'ptgUminus' => 0x13, - 'ptgPercent' => 0x14, - 'ptgParen' => 0x15, - 'ptgMissArg' => 0x16, - 'ptgStr' => 0x17, - 'ptgAttr' => 0x19, - 'ptgSheet' => 0x1A, - 'ptgEndSheet' => 0x1B, - 'ptgErr' => 0x1C, - 'ptgBool' => 0x1D, - 'ptgInt' => 0x1E, - 'ptgNum' => 0x1F, - 'ptgArray' => 0x20, - 'ptgFunc' => 0x21, - 'ptgFuncVar' => 0x22, - 'ptgName' => 0x23, - 'ptgRef' => 0x24, - 'ptgArea' => 0x25, - 'ptgMemArea' => 0x26, - 'ptgMemErr' => 0x27, - 'ptgMemNoMem' => 0x28, - 'ptgMemFunc' => 0x29, - 'ptgRefErr' => 0x2A, - 'ptgAreaErr' => 0x2B, - 'ptgRefN' => 0x2C, - 'ptgAreaN' => 0x2D, - 'ptgMemAreaN' => 0x2E, - 'ptgMemNoMemN' => 0x2F, - 'ptgNameX' => 0x39, - 'ptgRef3d' => 0x3A, - 'ptgArea3d' => 0x3B, - 'ptgRefErr3d' => 0x3C, - 'ptgAreaErr3d' => 0x3D, - 'ptgArrayV' => 0x40, - 'ptgFuncV' => 0x41, - 'ptgFuncVarV' => 0x42, - 'ptgNameV' => 0x43, - 'ptgRefV' => 0x44, - 'ptgAreaV' => 0x45, - 'ptgMemAreaV' => 0x46, - 'ptgMemErrV' => 0x47, - 'ptgMemNoMemV' => 0x48, - 'ptgMemFuncV' => 0x49, - 'ptgRefErrV' => 0x4A, - 'ptgAreaErrV' => 0x4B, - 'ptgRefNV' => 0x4C, - 'ptgAreaNV' => 0x4D, - 'ptgMemAreaNV' => 0x4E, - 'ptgMemNoMemN' => 0x4F, - 'ptgFuncCEV' => 0x58, - 'ptgNameXV' => 0x59, - 'ptgRef3dV' => 0x5A, - 'ptgArea3dV' => 0x5B, - 'ptgRefErr3dV' => 0x5C, - 'ptgAreaErr3d' => 0x5D, - 'ptgArrayA' => 0x60, - 'ptgFuncA' => 0x61, - 'ptgFuncVarA' => 0x62, - 'ptgNameA' => 0x63, - 'ptgRefA' => 0x64, - 'ptgAreaA' => 0x65, - 'ptgMemAreaA' => 0x66, - 'ptgMemErrA' => 0x67, - 'ptgMemNoMemA' => 0x68, - 'ptgMemFuncA' => 0x69, - 'ptgRefErrA' => 0x6A, - 'ptgAreaErrA' => 0x6B, - 'ptgRefNA' => 0x6C, - 'ptgAreaNA' => 0x6D, - 'ptgMemAreaNA' => 0x6E, - 'ptgMemNoMemN' => 0x6F, - 'ptgFuncCEA' => 0x78, - 'ptgNameXA' => 0x79, - 'ptgRef3dA' => 0x7A, - 'ptgArea3dA' => 0x7B, - 'ptgRefErr3dA' => 0x7C, - 'ptgAreaErr3d' => 0x7D - ); - - // Thanks to Michael Meeks and Gnumeric for the initial arg values. - // - // The following hash was generated by "function_locale.pl" in the distro. - // Refer to function_locale.pl for non-English function names. - // - // The array elements are as follow: - // ptg: The Excel function ptg code. - // args: The number of arguments that the function takes: - // >=0 is a fixed number of arguments. - // -1 is a variable number of arguments. - // class: The reference, value or array class of the function args. - // vol: The function is volatile. - // - $this->_functions = array( - // function ptg args class vol - 'COUNT' => array( 0, -1, 0, 0 ), - 'IF' => array( 1, -1, 1, 0 ), - 'ISNA' => array( 2, 1, 1, 0 ), - 'ISERROR' => array( 3, 1, 1, 0 ), - 'SUM' => array( 4, -1, 0, 0 ), - 'AVERAGE' => array( 5, -1, 0, 0 ), - 'MIN' => array( 6, -1, 0, 0 ), - 'MAX' => array( 7, -1, 0, 0 ), - 'ROW' => array( 8, -1, 0, 0 ), - 'COLUMN' => array( 9, -1, 0, 0 ), - 'NA' => array( 10, 0, 0, 0 ), - 'NPV' => array( 11, -1, 1, 0 ), - 'STDEV' => array( 12, -1, 0, 0 ), - 'DOLLAR' => array( 13, -1, 1, 0 ), - 'FIXED' => array( 14, -1, 1, 0 ), - 'SIN' => array( 15, 1, 1, 0 ), - 'COS' => array( 16, 1, 1, 0 ), - 'TAN' => array( 17, 1, 1, 0 ), - 'ATAN' => array( 18, 1, 1, 0 ), - 'PI' => array( 19, 0, 1, 0 ), - 'SQRT' => array( 20, 1, 1, 0 ), - 'EXP' => array( 21, 1, 1, 0 ), - 'LN' => array( 22, 1, 1, 0 ), - 'LOG10' => array( 23, 1, 1, 0 ), - 'ABS' => array( 24, 1, 1, 0 ), - 'INT' => array( 25, 1, 1, 0 ), - 'SIGN' => array( 26, 1, 1, 0 ), - 'ROUND' => array( 27, 2, 1, 0 ), - 'LOOKUP' => array( 28, -1, 0, 0 ), - 'INDEX' => array( 29, -1, 0, 1 ), - 'REPT' => array( 30, 2, 1, 0 ), - 'MID' => array( 31, 3, 1, 0 ), - 'LEN' => array( 32, 1, 1, 0 ), - 'VALUE' => array( 33, 1, 1, 0 ), - 'TRUE' => array( 34, 0, 1, 0 ), - 'FALSE' => array( 35, 0, 1, 0 ), - 'AND' => array( 36, -1, 0, 0 ), - 'OR' => array( 37, -1, 0, 0 ), - 'NOT' => array( 38, 1, 1, 0 ), - 'MOD' => array( 39, 2, 1, 0 ), - 'DCOUNT' => array( 40, 3, 0, 0 ), - 'DSUM' => array( 41, 3, 0, 0 ), - 'DAVERAGE' => array( 42, 3, 0, 0 ), - 'DMIN' => array( 43, 3, 0, 0 ), - 'DMAX' => array( 44, 3, 0, 0 ), - 'DSTDEV' => array( 45, 3, 0, 0 ), - 'VAR' => array( 46, -1, 0, 0 ), - 'DVAR' => array( 47, 3, 0, 0 ), - 'TEXT' => array( 48, 2, 1, 0 ), - 'LINEST' => array( 49, -1, 0, 0 ), - 'TREND' => array( 50, -1, 0, 0 ), - 'LOGEST' => array( 51, -1, 0, 0 ), - 'GROWTH' => array( 52, -1, 0, 0 ), - 'PV' => array( 56, -1, 1, 0 ), - 'FV' => array( 57, -1, 1, 0 ), - 'NPER' => array( 58, -1, 1, 0 ), - 'PMT' => array( 59, -1, 1, 0 ), - 'RATE' => array( 60, -1, 1, 0 ), - 'MIRR' => array( 61, 3, 0, 0 ), - 'IRR' => array( 62, -1, 0, 0 ), - 'RAND' => array( 63, 0, 1, 1 ), - 'MATCH' => array( 64, -1, 0, 0 ), - 'DATE' => array( 65, 3, 1, 0 ), - 'TIME' => array( 66, 3, 1, 0 ), - 'DAY' => array( 67, 1, 1, 0 ), - 'MONTH' => array( 68, 1, 1, 0 ), - 'YEAR' => array( 69, 1, 1, 0 ), - 'WEEKDAY' => array( 70, -1, 1, 0 ), - 'HOUR' => array( 71, 1, 1, 0 ), - 'MINUTE' => array( 72, 1, 1, 0 ), - 'SECOND' => array( 73, 1, 1, 0 ), - 'NOW' => array( 74, 0, 1, 1 ), - 'AREAS' => array( 75, 1, 0, 1 ), - 'ROWS' => array( 76, 1, 0, 1 ), - 'COLUMNS' => array( 77, 1, 0, 1 ), - 'OFFSET' => array( 78, -1, 0, 1 ), - 'SEARCH' => array( 82, -1, 1, 0 ), - 'TRANSPOSE' => array( 83, 1, 1, 0 ), - 'TYPE' => array( 86, 1, 1, 0 ), - 'ATAN2' => array( 97, 2, 1, 0 ), - 'ASIN' => array( 98, 1, 1, 0 ), - 'ACOS' => array( 99, 1, 1, 0 ), - 'CHOOSE' => array( 100, -1, 1, 0 ), - 'HLOOKUP' => array( 101, -1, 0, 0 ), - 'VLOOKUP' => array( 102, -1, 0, 0 ), - 'ISREF' => array( 105, 1, 0, 0 ), - 'LOG' => array( 109, -1, 1, 0 ), - 'CHAR' => array( 111, 1, 1, 0 ), - 'LOWER' => array( 112, 1, 1, 0 ), - 'UPPER' => array( 113, 1, 1, 0 ), - 'PROPER' => array( 114, 1, 1, 0 ), - 'LEFT' => array( 115, -1, 1, 0 ), - 'RIGHT' => array( 116, -1, 1, 0 ), - 'EXACT' => array( 117, 2, 1, 0 ), - 'TRIM' => array( 118, 1, 1, 0 ), - 'REPLACE' => array( 119, 4, 1, 0 ), - 'SUBSTITUTE' => array( 120, -1, 1, 0 ), - 'CODE' => array( 121, 1, 1, 0 ), - 'FIND' => array( 124, -1, 1, 0 ), - 'CELL' => array( 125, -1, 0, 1 ), - 'ISERR' => array( 126, 1, 1, 0 ), - 'ISTEXT' => array( 127, 1, 1, 0 ), - 'ISNUMBER' => array( 128, 1, 1, 0 ), - 'ISBLANK' => array( 129, 1, 1, 0 ), - 'T' => array( 130, 1, 0, 0 ), - 'N' => array( 131, 1, 0, 0 ), - 'DATEVALUE' => array( 140, 1, 1, 0 ), - 'TIMEVALUE' => array( 141, 1, 1, 0 ), - 'SLN' => array( 142, 3, 1, 0 ), - 'SYD' => array( 143, 4, 1, 0 ), - 'DDB' => array( 144, -1, 1, 0 ), - 'INDIRECT' => array( 148, -1, 1, 1 ), - 'CALL' => array( 150, -1, 1, 0 ), - 'CLEAN' => array( 162, 1, 1, 0 ), - 'MDETERM' => array( 163, 1, 2, 0 ), - 'MINVERSE' => array( 164, 1, 2, 0 ), - 'MMULT' => array( 165, 2, 2, 0 ), - 'IPMT' => array( 167, -1, 1, 0 ), - 'PPMT' => array( 168, -1, 1, 0 ), - 'COUNTA' => array( 169, -1, 0, 0 ), - 'PRODUCT' => array( 183, -1, 0, 0 ), - 'FACT' => array( 184, 1, 1, 0 ), - 'DPRODUCT' => array( 189, 3, 0, 0 ), - 'ISNONTEXT' => array( 190, 1, 1, 0 ), - 'STDEVP' => array( 193, -1, 0, 0 ), - 'VARP' => array( 194, -1, 0, 0 ), - 'DSTDEVP' => array( 195, 3, 0, 0 ), - 'DVARP' => array( 196, 3, 0, 0 ), - 'TRUNC' => array( 197, -1, 1, 0 ), - 'ISLOGICAL' => array( 198, 1, 1, 0 ), - 'DCOUNTA' => array( 199, 3, 0, 0 ), - 'USDOLLAR' => array( 204, -1, 1, 0 ), - 'FINDB' => array( 205, -1, 1, 0 ), - 'SEARCHB' => array( 206, -1, 1, 0 ), - 'REPLACEB' => array( 207, 4, 1, 0 ), - 'LEFTB' => array( 208, -1, 1, 0 ), - 'RIGHTB' => array( 209, -1, 1, 0 ), - 'MIDB' => array( 210, 3, 1, 0 ), - 'LENB' => array( 211, 1, 1, 0 ), - 'ROUNDUP' => array( 212, 2, 1, 0 ), - 'ROUNDDOWN' => array( 213, 2, 1, 0 ), - 'ASC' => array( 214, 1, 1, 0 ), - 'DBCS' => array( 215, 1, 1, 0 ), - 'RANK' => array( 216, -1, 0, 0 ), - 'ADDRESS' => array( 219, -1, 1, 0 ), - 'DAYS360' => array( 220, -1, 1, 0 ), - 'TODAY' => array( 221, 0, 1, 1 ), - 'VDB' => array( 222, -1, 1, 0 ), - 'MEDIAN' => array( 227, -1, 0, 0 ), - 'SUMPRODUCT' => array( 228, -1, 2, 0 ), - 'SINH' => array( 229, 1, 1, 0 ), - 'COSH' => array( 230, 1, 1, 0 ), - 'TANH' => array( 231, 1, 1, 0 ), - 'ASINH' => array( 232, 1, 1, 0 ), - 'ACOSH' => array( 233, 1, 1, 0 ), - 'ATANH' => array( 234, 1, 1, 0 ), - 'DGET' => array( 235, 3, 0, 0 ), - 'INFO' => array( 244, 1, 1, 1 ), - 'DB' => array( 247, -1, 1, 0 ), - 'FREQUENCY' => array( 252, 2, 0, 0 ), - 'ERROR.TYPE' => array( 261, 1, 1, 0 ), - 'REGISTER.ID' => array( 267, -1, 1, 0 ), - 'AVEDEV' => array( 269, -1, 0, 0 ), - 'BETADIST' => array( 270, -1, 1, 0 ), - 'GAMMALN' => array( 271, 1, 1, 0 ), - 'BETAINV' => array( 272, -1, 1, 0 ), - 'BINOMDIST' => array( 273, 4, 1, 0 ), - 'CHIDIST' => array( 274, 2, 1, 0 ), - 'CHIINV' => array( 275, 2, 1, 0 ), - 'COMBIN' => array( 276, 2, 1, 0 ), - 'CONFIDENCE' => array( 277, 3, 1, 0 ), - 'CRITBINOM' => array( 278, 3, 1, 0 ), - 'EVEN' => array( 279, 1, 1, 0 ), - 'EXPONDIST' => array( 280, 3, 1, 0 ), - 'FDIST' => array( 281, 3, 1, 0 ), - 'FINV' => array( 282, 3, 1, 0 ), - 'FISHER' => array( 283, 1, 1, 0 ), - 'FISHERINV' => array( 284, 1, 1, 0 ), - 'FLOOR' => array( 285, 2, 1, 0 ), - 'GAMMADIST' => array( 286, 4, 1, 0 ), - 'GAMMAINV' => array( 287, 3, 1, 0 ), - 'CEILING' => array( 288, 2, 1, 0 ), - 'HYPGEOMDIST' => array( 289, 4, 1, 0 ), - 'LOGNORMDIST' => array( 290, 3, 1, 0 ), - 'LOGINV' => array( 291, 3, 1, 0 ), - 'NEGBINOMDIST' => array( 292, 3, 1, 0 ), - 'NORMDIST' => array( 293, 4, 1, 0 ), - 'NORMSDIST' => array( 294, 1, 1, 0 ), - 'NORMINV' => array( 295, 3, 1, 0 ), - 'NORMSINV' => array( 296, 1, 1, 0 ), - 'STANDARDIZE' => array( 297, 3, 1, 0 ), - 'ODD' => array( 298, 1, 1, 0 ), - 'PERMUT' => array( 299, 2, 1, 0 ), - 'POISSON' => array( 300, 3, 1, 0 ), - 'TDIST' => array( 301, 3, 1, 0 ), - 'WEIBULL' => array( 302, 4, 1, 0 ), - 'SUMXMY2' => array( 303, 2, 2, 0 ), - 'SUMX2MY2' => array( 304, 2, 2, 0 ), - 'SUMX2PY2' => array( 305, 2, 2, 0 ), - 'CHITEST' => array( 306, 2, 2, 0 ), - 'CORREL' => array( 307, 2, 2, 0 ), - 'COVAR' => array( 308, 2, 2, 0 ), - 'FORECAST' => array( 309, 3, 2, 0 ), - 'FTEST' => array( 310, 2, 2, 0 ), - 'INTERCEPT' => array( 311, 2, 2, 0 ), - 'PEARSON' => array( 312, 2, 2, 0 ), - 'RSQ' => array( 313, 2, 2, 0 ), - 'STEYX' => array( 314, 2, 2, 0 ), - 'SLOPE' => array( 315, 2, 2, 0 ), - 'TTEST' => array( 316, 4, 2, 0 ), - 'PROB' => array( 317, -1, 2, 0 ), - 'DEVSQ' => array( 318, -1, 0, 0 ), - 'GEOMEAN' => array( 319, -1, 0, 0 ), - 'HARMEAN' => array( 320, -1, 0, 0 ), - 'SUMSQ' => array( 321, -1, 0, 0 ), - 'KURT' => array( 322, -1, 0, 0 ), - 'SKEW' => array( 323, -1, 0, 0 ), - 'ZTEST' => array( 324, -1, 0, 0 ), - 'LARGE' => array( 325, 2, 0, 0 ), - 'SMALL' => array( 326, 2, 0, 0 ), - 'QUARTILE' => array( 327, 2, 0, 0 ), - 'PERCENTILE' => array( 328, 2, 0, 0 ), - 'PERCENTRANK' => array( 329, -1, 0, 0 ), - 'MODE' => array( 330, -1, 2, 0 ), - 'TRIMMEAN' => array( 331, 2, 0, 0 ), - 'TINV' => array( 332, 2, 1, 0 ), - 'CONCATENATE' => array( 336, -1, 1, 0 ), - 'POWER' => array( 337, 2, 1, 0 ), - 'RADIANS' => array( 342, 1, 1, 0 ), - 'DEGREES' => array( 343, 1, 1, 0 ), - 'SUBTOTAL' => array( 344, -1, 0, 0 ), - 'SUMIF' => array( 345, -1, 0, 0 ), - 'COUNTIF' => array( 346, 2, 0, 0 ), - 'COUNTBLANK' => array( 347, 1, 0, 0 ), - 'ISPMT' => array( 350, 4, 1, 0 ), - 'DATEDIF' => array( 351, 3, 1, 0 ), - 'DATESTRING' => array( 352, 1, 1, 0 ), - 'NUMBERSTRING' => array( 353, 2, 1, 0 ), - 'ROMAN' => array( 354, -1, 1, 0 ), - 'GETPIVOTDATA' => array( 358, -1, 0, 0 ), - 'HYPERLINK' => array( 359, -1, 1, 0 ), - 'PHONETIC' => array( 360, 1, 0, 0 ), - 'AVERAGEA' => array( 361, -1, 0, 0 ), - 'MAXA' => array( 362, -1, 0, 0 ), - 'MINA' => array( 363, -1, 0, 0 ), - 'STDEVPA' => array( 364, -1, 0, 0 ), - 'VARPA' => array( 365, -1, 0, 0 ), - 'STDEVA' => array( 366, -1, 0, 0 ), - 'VARA' => array( 367, -1, 0, 0 ), - 'BAHTTEXT' => array( 368, 1, 0, 0 ), - ); - } - - /** - * Convert a token to the proper ptg value. - * - * @access private - * @param mixed $token The token to convert. - * @return mixed the converted token on success - */ - function _convert($token) - { - if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token)) { - return $this->_convertString($token); - - } elseif (is_numeric($token)) { - return $this->_convertNumber($token); - - // match references like A1 or $A$1 - } elseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/',$token)) { - return $this->_convertRef2d($token); - - // match external references like Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1 - } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u",$token)) { - return $this->_convertRef3d($token); - - // match external references like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1 - } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u",$token)) { - return $this->_convertRef3d($token); - - // match ranges like A1:B2 or $A$1:$B$2 - } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\:(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/', $token)) { - return $this->_convertRange2d($token); - - // match external ranges like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 - } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u",$token)) { - return $this->_convertRange3d($token); - - // match external ranges like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 - } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u",$token)) { - return $this->_convertRange3d($token); - - // operators (including parentheses) - } elseif (isset($this->ptg[$token])) { - return pack("C", $this->ptg[$token]); + /** Constants */ + // Sheet title in unquoted form + // Invalid sheet title characters cannot occur in the sheet title: + // *:/\?[] + // Moreover, there are valid sheet title characters that cannot occur in unquoted form (there may be more?) + // +-% '^&<>=,;#()"{} + const REGEX_SHEET_TITLE_UNQUOTED = '[^\*\:\/\\\\\?\[\]\+\-\% \\\'\^\&\<\>\=\,\;\#\(\)\"\{\}]+'; + + // Sheet title in quoted form (without surrounding quotes) + // Invalid sheet title characters cannot occur in the sheet title: + // *:/\?[] (usual invalid sheet title characters) + // Single quote is represented as a pair '' + const REGEX_SHEET_TITLE_QUOTED = '(([^\*\:\/\\\\\?\[\]\\\'])+|(\\\'\\\')+)+'; + + /** + * The index of the character we are currently looking at + * @var integer + */ + public $_current_char; + + /** + * The token we are working on. + * @var string + */ + public $_current_token; + + /** + * The formula to parse + * @var string + */ + public $_formula; + + /** + * The character ahead of the current char + * @var string + */ + public $_lookahead; + + /** + * The parse tree to be generated + * @var string + */ + public $_parse_tree; + + /** + * Array of external sheets + * @var array + */ + public $_ext_sheets; + + /** + * Array of sheet references in the form of REF structures + * @var array + */ + public $_references; + + /** + * The class constructor + * + */ + public function __construct() + { + $this->_current_char = 0; + $this->_current_token = ''; // The token we are working on. + $this->_formula = ''; // The formula to parse. + $this->_lookahead = ''; // The character ahead of the current char. + $this->_parse_tree = ''; // The parse tree to be generated. + $this->_initializeHashes(); // Initialize the hashes: ptg's and function's ptg's + $this->_ext_sheets = array(); + $this->_references = array(); + } + + /** + * Initialize the ptg and function hashes. + * + * @access private + */ + function _initializeHashes() + { + // The Excel ptg indices + $this->ptg = array( + 'ptgExp' => 0x01, + 'ptgTbl' => 0x02, + 'ptgAdd' => 0x03, + 'ptgSub' => 0x04, + 'ptgMul' => 0x05, + 'ptgDiv' => 0x06, + 'ptgPower' => 0x07, + 'ptgConcat' => 0x08, + 'ptgLT' => 0x09, + 'ptgLE' => 0x0A, + 'ptgEQ' => 0x0B, + 'ptgGE' => 0x0C, + 'ptgGT' => 0x0D, + 'ptgNE' => 0x0E, + 'ptgIsect' => 0x0F, + 'ptgUnion' => 0x10, + 'ptgRange' => 0x11, + 'ptgUplus' => 0x12, + 'ptgUminus' => 0x13, + 'ptgPercent' => 0x14, + 'ptgParen' => 0x15, + 'ptgMissArg' => 0x16, + 'ptgStr' => 0x17, + 'ptgAttr' => 0x19, + 'ptgSheet' => 0x1A, + 'ptgEndSheet' => 0x1B, + 'ptgErr' => 0x1C, + 'ptgBool' => 0x1D, + 'ptgInt' => 0x1E, + 'ptgNum' => 0x1F, + 'ptgArray' => 0x20, + 'ptgFunc' => 0x21, + 'ptgFuncVar' => 0x22, + 'ptgName' => 0x23, + 'ptgRef' => 0x24, + 'ptgArea' => 0x25, + 'ptgMemArea' => 0x26, + 'ptgMemErr' => 0x27, + 'ptgMemNoMem' => 0x28, + 'ptgMemFunc' => 0x29, + 'ptgRefErr' => 0x2A, + 'ptgAreaErr' => 0x2B, + 'ptgRefN' => 0x2C, + 'ptgAreaN' => 0x2D, + 'ptgMemAreaN' => 0x2E, + 'ptgMemNoMemN' => 0x2F, + 'ptgNameX' => 0x39, + 'ptgRef3d' => 0x3A, + 'ptgArea3d' => 0x3B, + 'ptgRefErr3d' => 0x3C, + 'ptgAreaErr3d' => 0x3D, + 'ptgArrayV' => 0x40, + 'ptgFuncV' => 0x41, + 'ptgFuncVarV' => 0x42, + 'ptgNameV' => 0x43, + 'ptgRefV' => 0x44, + 'ptgAreaV' => 0x45, + 'ptgMemAreaV' => 0x46, + 'ptgMemErrV' => 0x47, + 'ptgMemNoMemV' => 0x48, + 'ptgMemFuncV' => 0x49, + 'ptgRefErrV' => 0x4A, + 'ptgAreaErrV' => 0x4B, + 'ptgRefNV' => 0x4C, + 'ptgAreaNV' => 0x4D, + 'ptgMemAreaNV' => 0x4E, + 'ptgMemNoMemN' => 0x4F, + 'ptgFuncCEV' => 0x58, + 'ptgNameXV' => 0x59, + 'ptgRef3dV' => 0x5A, + 'ptgArea3dV' => 0x5B, + 'ptgRefErr3dV' => 0x5C, + 'ptgAreaErr3d' => 0x5D, + 'ptgArrayA' => 0x60, + 'ptgFuncA' => 0x61, + 'ptgFuncVarA' => 0x62, + 'ptgNameA' => 0x63, + 'ptgRefA' => 0x64, + 'ptgAreaA' => 0x65, + 'ptgMemAreaA' => 0x66, + 'ptgMemErrA' => 0x67, + 'ptgMemNoMemA' => 0x68, + 'ptgMemFuncA' => 0x69, + 'ptgRefErrA' => 0x6A, + 'ptgAreaErrA' => 0x6B, + 'ptgRefNA' => 0x6C, + 'ptgAreaNA' => 0x6D, + 'ptgMemAreaNA' => 0x6E, + 'ptgMemNoMemN' => 0x6F, + 'ptgFuncCEA' => 0x78, + 'ptgNameXA' => 0x79, + 'ptgRef3dA' => 0x7A, + 'ptgArea3dA' => 0x7B, + 'ptgRefErr3dA' => 0x7C, + 'ptgAreaErr3d' => 0x7D + ); + + // Thanks to Michael Meeks and Gnumeric for the initial arg values. + // + // The following hash was generated by "function_locale.pl" in the distro. + // Refer to function_locale.pl for non-English function names. + // + // The array elements are as follow: + // ptg: The Excel function ptg code. + // args: The number of arguments that the function takes: + // >=0 is a fixed number of arguments. + // -1 is a variable number of arguments. + // class: The reference, value or array class of the function args. + // vol: The function is volatile. + // + $this->_functions = array( + // function ptg args class vol + 'COUNT' => array( 0, -1, 0, 0 ), + 'IF' => array( 1, -1, 1, 0 ), + 'ISNA' => array( 2, 1, 1, 0 ), + 'ISERROR' => array( 3, 1, 1, 0 ), + 'SUM' => array( 4, -1, 0, 0 ), + 'AVERAGE' => array( 5, -1, 0, 0 ), + 'MIN' => array( 6, -1, 0, 0 ), + 'MAX' => array( 7, -1, 0, 0 ), + 'ROW' => array( 8, -1, 0, 0 ), + 'COLUMN' => array( 9, -1, 0, 0 ), + 'NA' => array( 10, 0, 0, 0 ), + 'NPV' => array( 11, -1, 1, 0 ), + 'STDEV' => array( 12, -1, 0, 0 ), + 'DOLLAR' => array( 13, -1, 1, 0 ), + 'FIXED' => array( 14, -1, 1, 0 ), + 'SIN' => array( 15, 1, 1, 0 ), + 'COS' => array( 16, 1, 1, 0 ), + 'TAN' => array( 17, 1, 1, 0 ), + 'ATAN' => array( 18, 1, 1, 0 ), + 'PI' => array( 19, 0, 1, 0 ), + 'SQRT' => array( 20, 1, 1, 0 ), + 'EXP' => array( 21, 1, 1, 0 ), + 'LN' => array( 22, 1, 1, 0 ), + 'LOG10' => array( 23, 1, 1, 0 ), + 'ABS' => array( 24, 1, 1, 0 ), + 'INT' => array( 25, 1, 1, 0 ), + 'SIGN' => array( 26, 1, 1, 0 ), + 'ROUND' => array( 27, 2, 1, 0 ), + 'LOOKUP' => array( 28, -1, 0, 0 ), + 'INDEX' => array( 29, -1, 0, 1 ), + 'REPT' => array( 30, 2, 1, 0 ), + 'MID' => array( 31, 3, 1, 0 ), + 'LEN' => array( 32, 1, 1, 0 ), + 'VALUE' => array( 33, 1, 1, 0 ), + 'TRUE' => array( 34, 0, 1, 0 ), + 'FALSE' => array( 35, 0, 1, 0 ), + 'AND' => array( 36, -1, 0, 0 ), + 'OR' => array( 37, -1, 0, 0 ), + 'NOT' => array( 38, 1, 1, 0 ), + 'MOD' => array( 39, 2, 1, 0 ), + 'DCOUNT' => array( 40, 3, 0, 0 ), + 'DSUM' => array( 41, 3, 0, 0 ), + 'DAVERAGE' => array( 42, 3, 0, 0 ), + 'DMIN' => array( 43, 3, 0, 0 ), + 'DMAX' => array( 44, 3, 0, 0 ), + 'DSTDEV' => array( 45, 3, 0, 0 ), + 'VAR' => array( 46, -1, 0, 0 ), + 'DVAR' => array( 47, 3, 0, 0 ), + 'TEXT' => array( 48, 2, 1, 0 ), + 'LINEST' => array( 49, -1, 0, 0 ), + 'TREND' => array( 50, -1, 0, 0 ), + 'LOGEST' => array( 51, -1, 0, 0 ), + 'GROWTH' => array( 52, -1, 0, 0 ), + 'PV' => array( 56, -1, 1, 0 ), + 'FV' => array( 57, -1, 1, 0 ), + 'NPER' => array( 58, -1, 1, 0 ), + 'PMT' => array( 59, -1, 1, 0 ), + 'RATE' => array( 60, -1, 1, 0 ), + 'MIRR' => array( 61, 3, 0, 0 ), + 'IRR' => array( 62, -1, 0, 0 ), + 'RAND' => array( 63, 0, 1, 1 ), + 'MATCH' => array( 64, -1, 0, 0 ), + 'DATE' => array( 65, 3, 1, 0 ), + 'TIME' => array( 66, 3, 1, 0 ), + 'DAY' => array( 67, 1, 1, 0 ), + 'MONTH' => array( 68, 1, 1, 0 ), + 'YEAR' => array( 69, 1, 1, 0 ), + 'WEEKDAY' => array( 70, -1, 1, 0 ), + 'HOUR' => array( 71, 1, 1, 0 ), + 'MINUTE' => array( 72, 1, 1, 0 ), + 'SECOND' => array( 73, 1, 1, 0 ), + 'NOW' => array( 74, 0, 1, 1 ), + 'AREAS' => array( 75, 1, 0, 1 ), + 'ROWS' => array( 76, 1, 0, 1 ), + 'COLUMNS' => array( 77, 1, 0, 1 ), + 'OFFSET' => array( 78, -1, 0, 1 ), + 'SEARCH' => array( 82, -1, 1, 0 ), + 'TRANSPOSE' => array( 83, 1, 1, 0 ), + 'TYPE' => array( 86, 1, 1, 0 ), + 'ATAN2' => array( 97, 2, 1, 0 ), + 'ASIN' => array( 98, 1, 1, 0 ), + 'ACOS' => array( 99, 1, 1, 0 ), + 'CHOOSE' => array( 100, -1, 1, 0 ), + 'HLOOKUP' => array( 101, -1, 0, 0 ), + 'VLOOKUP' => array( 102, -1, 0, 0 ), + 'ISREF' => array( 105, 1, 0, 0 ), + 'LOG' => array( 109, -1, 1, 0 ), + 'CHAR' => array( 111, 1, 1, 0 ), + 'LOWER' => array( 112, 1, 1, 0 ), + 'UPPER' => array( 113, 1, 1, 0 ), + 'PROPER' => array( 114, 1, 1, 0 ), + 'LEFT' => array( 115, -1, 1, 0 ), + 'RIGHT' => array( 116, -1, 1, 0 ), + 'EXACT' => array( 117, 2, 1, 0 ), + 'TRIM' => array( 118, 1, 1, 0 ), + 'REPLACE' => array( 119, 4, 1, 0 ), + 'SUBSTITUTE' => array( 120, -1, 1, 0 ), + 'CODE' => array( 121, 1, 1, 0 ), + 'FIND' => array( 124, -1, 1, 0 ), + 'CELL' => array( 125, -1, 0, 1 ), + 'ISERR' => array( 126, 1, 1, 0 ), + 'ISTEXT' => array( 127, 1, 1, 0 ), + 'ISNUMBER' => array( 128, 1, 1, 0 ), + 'ISBLANK' => array( 129, 1, 1, 0 ), + 'T' => array( 130, 1, 0, 0 ), + 'N' => array( 131, 1, 0, 0 ), + 'DATEVALUE' => array( 140, 1, 1, 0 ), + 'TIMEVALUE' => array( 141, 1, 1, 0 ), + 'SLN' => array( 142, 3, 1, 0 ), + 'SYD' => array( 143, 4, 1, 0 ), + 'DDB' => array( 144, -1, 1, 0 ), + 'INDIRECT' => array( 148, -1, 1, 1 ), + 'CALL' => array( 150, -1, 1, 0 ), + 'CLEAN' => array( 162, 1, 1, 0 ), + 'MDETERM' => array( 163, 1, 2, 0 ), + 'MINVERSE' => array( 164, 1, 2, 0 ), + 'MMULT' => array( 165, 2, 2, 0 ), + 'IPMT' => array( 167, -1, 1, 0 ), + 'PPMT' => array( 168, -1, 1, 0 ), + 'COUNTA' => array( 169, -1, 0, 0 ), + 'PRODUCT' => array( 183, -1, 0, 0 ), + 'FACT' => array( 184, 1, 1, 0 ), + 'DPRODUCT' => array( 189, 3, 0, 0 ), + 'ISNONTEXT' => array( 190, 1, 1, 0 ), + 'STDEVP' => array( 193, -1, 0, 0 ), + 'VARP' => array( 194, -1, 0, 0 ), + 'DSTDEVP' => array( 195, 3, 0, 0 ), + 'DVARP' => array( 196, 3, 0, 0 ), + 'TRUNC' => array( 197, -1, 1, 0 ), + 'ISLOGICAL' => array( 198, 1, 1, 0 ), + 'DCOUNTA' => array( 199, 3, 0, 0 ), + 'USDOLLAR' => array( 204, -1, 1, 0 ), + 'FINDB' => array( 205, -1, 1, 0 ), + 'SEARCHB' => array( 206, -1, 1, 0 ), + 'REPLACEB' => array( 207, 4, 1, 0 ), + 'LEFTB' => array( 208, -1, 1, 0 ), + 'RIGHTB' => array( 209, -1, 1, 0 ), + 'MIDB' => array( 210, 3, 1, 0 ), + 'LENB' => array( 211, 1, 1, 0 ), + 'ROUNDUP' => array( 212, 2, 1, 0 ), + 'ROUNDDOWN' => array( 213, 2, 1, 0 ), + 'ASC' => array( 214, 1, 1, 0 ), + 'DBCS' => array( 215, 1, 1, 0 ), + 'RANK' => array( 216, -1, 0, 0 ), + 'ADDRESS' => array( 219, -1, 1, 0 ), + 'DAYS360' => array( 220, -1, 1, 0 ), + 'TODAY' => array( 221, 0, 1, 1 ), + 'VDB' => array( 222, -1, 1, 0 ), + 'MEDIAN' => array( 227, -1, 0, 0 ), + 'SUMPRODUCT' => array( 228, -1, 2, 0 ), + 'SINH' => array( 229, 1, 1, 0 ), + 'COSH' => array( 230, 1, 1, 0 ), + 'TANH' => array( 231, 1, 1, 0 ), + 'ASINH' => array( 232, 1, 1, 0 ), + 'ACOSH' => array( 233, 1, 1, 0 ), + 'ATANH' => array( 234, 1, 1, 0 ), + 'DGET' => array( 235, 3, 0, 0 ), + 'INFO' => array( 244, 1, 1, 1 ), + 'DB' => array( 247, -1, 1, 0 ), + 'FREQUENCY' => array( 252, 2, 0, 0 ), + 'ERROR.TYPE' => array( 261, 1, 1, 0 ), + 'REGISTER.ID' => array( 267, -1, 1, 0 ), + 'AVEDEV' => array( 269, -1, 0, 0 ), + 'BETADIST' => array( 270, -1, 1, 0 ), + 'GAMMALN' => array( 271, 1, 1, 0 ), + 'BETAINV' => array( 272, -1, 1, 0 ), + 'BINOMDIST' => array( 273, 4, 1, 0 ), + 'CHIDIST' => array( 274, 2, 1, 0 ), + 'CHIINV' => array( 275, 2, 1, 0 ), + 'COMBIN' => array( 276, 2, 1, 0 ), + 'CONFIDENCE' => array( 277, 3, 1, 0 ), + 'CRITBINOM' => array( 278, 3, 1, 0 ), + 'EVEN' => array( 279, 1, 1, 0 ), + 'EXPONDIST' => array( 280, 3, 1, 0 ), + 'FDIST' => array( 281, 3, 1, 0 ), + 'FINV' => array( 282, 3, 1, 0 ), + 'FISHER' => array( 283, 1, 1, 0 ), + 'FISHERINV' => array( 284, 1, 1, 0 ), + 'FLOOR' => array( 285, 2, 1, 0 ), + 'GAMMADIST' => array( 286, 4, 1, 0 ), + 'GAMMAINV' => array( 287, 3, 1, 0 ), + 'CEILING' => array( 288, 2, 1, 0 ), + 'HYPGEOMDIST' => array( 289, 4, 1, 0 ), + 'LOGNORMDIST' => array( 290, 3, 1, 0 ), + 'LOGINV' => array( 291, 3, 1, 0 ), + 'NEGBINOMDIST' => array( 292, 3, 1, 0 ), + 'NORMDIST' => array( 293, 4, 1, 0 ), + 'NORMSDIST' => array( 294, 1, 1, 0 ), + 'NORMINV' => array( 295, 3, 1, 0 ), + 'NORMSINV' => array( 296, 1, 1, 0 ), + 'STANDARDIZE' => array( 297, 3, 1, 0 ), + 'ODD' => array( 298, 1, 1, 0 ), + 'PERMUT' => array( 299, 2, 1, 0 ), + 'POISSON' => array( 300, 3, 1, 0 ), + 'TDIST' => array( 301, 3, 1, 0 ), + 'WEIBULL' => array( 302, 4, 1, 0 ), + 'SUMXMY2' => array( 303, 2, 2, 0 ), + 'SUMX2MY2' => array( 304, 2, 2, 0 ), + 'SUMX2PY2' => array( 305, 2, 2, 0 ), + 'CHITEST' => array( 306, 2, 2, 0 ), + 'CORREL' => array( 307, 2, 2, 0 ), + 'COVAR' => array( 308, 2, 2, 0 ), + 'FORECAST' => array( 309, 3, 2, 0 ), + 'FTEST' => array( 310, 2, 2, 0 ), + 'INTERCEPT' => array( 311, 2, 2, 0 ), + 'PEARSON' => array( 312, 2, 2, 0 ), + 'RSQ' => array( 313, 2, 2, 0 ), + 'STEYX' => array( 314, 2, 2, 0 ), + 'SLOPE' => array( 315, 2, 2, 0 ), + 'TTEST' => array( 316, 4, 2, 0 ), + 'PROB' => array( 317, -1, 2, 0 ), + 'DEVSQ' => array( 318, -1, 0, 0 ), + 'GEOMEAN' => array( 319, -1, 0, 0 ), + 'HARMEAN' => array( 320, -1, 0, 0 ), + 'SUMSQ' => array( 321, -1, 0, 0 ), + 'KURT' => array( 322, -1, 0, 0 ), + 'SKEW' => array( 323, -1, 0, 0 ), + 'ZTEST' => array( 324, -1, 0, 0 ), + 'LARGE' => array( 325, 2, 0, 0 ), + 'SMALL' => array( 326, 2, 0, 0 ), + 'QUARTILE' => array( 327, 2, 0, 0 ), + 'PERCENTILE' => array( 328, 2, 0, 0 ), + 'PERCENTRANK' => array( 329, -1, 0, 0 ), + 'MODE' => array( 330, -1, 2, 0 ), + 'TRIMMEAN' => array( 331, 2, 0, 0 ), + 'TINV' => array( 332, 2, 1, 0 ), + 'CONCATENATE' => array( 336, -1, 1, 0 ), + 'POWER' => array( 337, 2, 1, 0 ), + 'RADIANS' => array( 342, 1, 1, 0 ), + 'DEGREES' => array( 343, 1, 1, 0 ), + 'SUBTOTAL' => array( 344, -1, 0, 0 ), + 'SUMIF' => array( 345, -1, 0, 0 ), + 'COUNTIF' => array( 346, 2, 0, 0 ), + 'COUNTBLANK' => array( 347, 1, 0, 0 ), + 'ISPMT' => array( 350, 4, 1, 0 ), + 'DATEDIF' => array( 351, 3, 1, 0 ), + 'DATESTRING' => array( 352, 1, 1, 0 ), + 'NUMBERSTRING' => array( 353, 2, 1, 0 ), + 'ROMAN' => array( 354, -1, 1, 0 ), + 'GETPIVOTDATA' => array( 358, -1, 0, 0 ), + 'HYPERLINK' => array( 359, -1, 1, 0 ), + 'PHONETIC' => array( 360, 1, 0, 0 ), + 'AVERAGEA' => array( 361, -1, 0, 0 ), + 'MAXA' => array( 362, -1, 0, 0 ), + 'MINA' => array( 363, -1, 0, 0 ), + 'STDEVPA' => array( 364, -1, 0, 0 ), + 'VARPA' => array( 365, -1, 0, 0 ), + 'STDEVA' => array( 366, -1, 0, 0 ), + 'VARA' => array( 367, -1, 0, 0 ), + 'BAHTTEXT' => array( 368, 1, 0, 0 ), + ); + } + + /** + * Convert a token to the proper ptg value. + * + * @access private + * @param mixed $token The token to convert. + * @return mixed the converted token on success + */ + function _convert($token) + { + if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token)) { + return $this->_convertString($token); + + } elseif (is_numeric($token)) { + return $this->_convertNumber($token); + + // match references like A1 or $A$1 + } elseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/',$token)) { + return $this->_convertRef2d($token); + + // match external references like Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1 + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u",$token)) { + return $this->_convertRef3d($token); + + // match external references like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1 + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u",$token)) { + return $this->_convertRef3d($token); + + // match ranges like A1:B2 or $A$1:$B$2 + } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\:(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/', $token)) { + return $this->_convertRange2d($token); + + // match external ranges like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u",$token)) { + return $this->_convertRange3d($token); + + // match external ranges like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u",$token)) { + return $this->_convertRange3d($token); + + // operators (including parentheses) + } elseif (isset($this->ptg[$token])) { + return pack("C", $this->ptg[$token]); // match error codes - } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { - return $this->_convertError($token); - - // commented so argument number can be processed correctly. See toReversePolish(). - /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/",$token)) - { - return($this->_convertFunction($token,$this->_func_args)); - }*/ - - // if it's an argument, ignore the token (the argument remains) - } elseif ($token == 'arg') { - return ''; - } - - // TODO: use real error codes - throw new PHPExcel_Writer_Exception("Unknown token $token"); - } - - /** - * Convert a number token to ptgInt or ptgNum - * - * @access private - * @param mixed $num an integer or double for conversion to its ptg value - */ - function _convertNumber($num) - { - // Integer in the range 0..2**16-1 - if ((preg_match("/^\d+$/", $num)) and ($num <= 65535)) { - return pack("Cv", $this->ptg['ptgInt'], $num); - } else { // A float - if (PHPExcel_Writer_Excel5_BIFFwriter::getByteOrder()) { // if it's Big Endian - $num = strrev($num); - } - return pack("Cd", $this->ptg['ptgNum'], $num); - } - } - - /** - * Convert a string token to ptgStr - * - * @access private - * @param string $string A string for conversion to its ptg value. - * @return mixed the converted token on success - */ - function _convertString($string) - { - // chop away beggining and ending quotes - $string = substr($string, 1, strlen($string) - 2); - if (strlen($string) > 255) { - throw new PHPExcel_Writer_Exception("String is too long"); - } - - return pack('C', $this->ptg['ptgStr']) . PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($string); - } - - /** - * Convert a function to a ptgFunc or ptgFuncVarV depending on the number of - * args that it takes. - * - * @access private - * @param string $token The name of the function for convertion to ptg value. - * @param integer $num_args The number of arguments the function receives. - * @return string The packed ptg for the function - */ - function _convertFunction($token, $num_args) - { - $args = $this->_functions[$token][1]; -// $volatile = $this->_functions[$token][3]; - - // Fixed number of args eg. TIME($i,$j,$k). - if ($args >= 0) { - return pack("Cv", $this->ptg['ptgFuncV'], $this->_functions[$token][0]); - } - // Variable number of args eg. SUM($i,$j,$k, ..). - if ($args == -1) { - return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0]); - } - } - - /** - * Convert an Excel range such as A1:D4 to a ptgRefV. - * - * @access private - * @param string $range An Excel range in the A1:A2 - * @param int $class - */ - function _convertRange2d($range, $class=0) - { - - // TODO: possible class value 0,1,2 check Formula.pm - // Split the range into 2 cell refs - if (preg_match('/^(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)\:(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)$/', $range)) { - list($cell1, $cell2) = explode(':', $range); - } else { - // TODO: use real error codes - throw new PHPExcel_Writer_Exception("Unknown range separator"); - } - - // Convert the cell references - list($row1, $col1) = $this->_cellToPackedRowcol($cell1); - list($row2, $col2) = $this->_cellToPackedRowcol($cell2); - - // The ptg value depends on the class of the ptg. - if ($class == 0) { - $ptgArea = pack("C", $this->ptg['ptgArea']); - } elseif ($class == 1) { - $ptgArea = pack("C", $this->ptg['ptgAreaV']); - } elseif ($class == 2) { - $ptgArea = pack("C", $this->ptg['ptgAreaA']); - } else { - // TODO: use real error codes - throw new PHPExcel_Writer_Exception("Unknown class $class"); - } - return $ptgArea . $row1 . $row2 . $col1. $col2; - } - - /** - * Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to - * a ptgArea3d. - * - * @access private - * @param string $token An Excel range in the Sheet1!A1:A2 format. - * @return mixed The packed ptgArea3d token on success. - */ - function _convertRange3d($token) - { -// $class = 0; // formulas like Sheet1!$A$1:$A$2 in list type data validation need this class (0x3B) - - // Split the ref at the ! symbol - list($ext_ref, $range) = explode('!', $token); - - // Convert the external reference part (different for BIFF8) - $ext_ref = $this->_getRefIndex($ext_ref); - - // Split the range into 2 cell refs - list($cell1, $cell2) = explode(':', $range); - - // Convert the cell references - if (preg_match("/^(\\$)?[A-Ia-i]?[A-Za-z](\\$)?(\d+)$/", $cell1)) { - list($row1, $col1) = $this->_cellToPackedRowcol($cell1); - list($row2, $col2) = $this->_cellToPackedRowcol($cell2); - } else { // It's a rows range (like 26:27) - list($row1, $col1, $row2, $col2) = $this->_rangeToPackedRange($cell1.':'.$cell2); - } - - // The ptg value depends on the class of the ptg. -// if ($class == 0) { - $ptgArea = pack("C", $this->ptg['ptgArea3d']); -// } elseif ($class == 1) { -// $ptgArea = pack("C", $this->ptg['ptgArea3dV']); -// } elseif ($class == 2) { -// $ptgArea = pack("C", $this->ptg['ptgArea3dA']); -// } else { -// throw new PHPExcel_Writer_Exception("Unknown class $class"); -// } - - return $ptgArea . $ext_ref . $row1 . $row2 . $col1. $col2; - } - - /** - * Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV. - * - * @access private - * @param string $cell An Excel cell reference - * @return string The cell in packed() format with the corresponding ptg - */ - function _convertRef2d($cell) - { -// $class = 2; // as far as I know, this is magick. - - // Convert the cell reference - $cell_array = $this->_cellToPackedRowcol($cell); - list($row, $col) = $cell_array; - - // The ptg value depends on the class of the ptg. -// if ($class == 0) { -// $ptgRef = pack("C", $this->ptg['ptgRef']); -// } elseif ($class == 1) { -// $ptgRef = pack("C", $this->ptg['ptgRefV']); -// } elseif ($class == 2) { - $ptgRef = pack("C", $this->ptg['ptgRefA']); -// } else { -// // TODO: use real error codes -// throw new PHPExcel_Writer_Exception("Unknown class $class"); -// } - return $ptgRef.$row.$col; - } - - /** - * Convert an Excel 3d reference such as "Sheet1!A1" or "Sheet1:Sheet2!A1" to a - * ptgRef3d. - * - * @access private - * @param string $cell An Excel cell reference - * @return mixed The packed ptgRef3d token on success. - */ - function _convertRef3d($cell) - { -// $class = 2; // as far as I know, this is magick. - - // Split the ref at the ! symbol - list($ext_ref, $cell) = explode('!', $cell); - - // Convert the external reference part (different for BIFF8) - $ext_ref = $this->_getRefIndex($ext_ref); - - // Convert the cell reference part - list($row, $col) = $this->_cellToPackedRowcol($cell); - - // The ptg value depends on the class of the ptg. -// if ($class == 0) { -// $ptgRef = pack("C", $this->ptg['ptgRef3d']); -// } elseif ($class == 1) { -// $ptgRef = pack("C", $this->ptg['ptgRef3dV']); -// } elseif ($class == 2) { - $ptgRef = pack("C", $this->ptg['ptgRef3dA']); -// } else { -// throw new PHPExcel_Writer_Exception("Unknown class $class"); -// } - - return $ptgRef . $ext_ref. $row . $col; - } + } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { + return $this->_convertError($token); + + // commented so argument number can be processed correctly. See toReversePolish(). + /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/",$token)) + { + return($this->_convertFunction($token,$this->_func_args)); + }*/ + + // if it's an argument, ignore the token (the argument remains) + } elseif ($token == 'arg') { + return ''; + } + + // TODO: use real error codes + throw new PHPExcel_Writer_Exception("Unknown token $token"); + } + + /** + * Convert a number token to ptgInt or ptgNum + * + * @access private + * @param mixed $num an integer or double for conversion to its ptg value + */ + function _convertNumber($num) + { + // Integer in the range 0..2**16-1 + if ((preg_match("/^\d+$/", $num)) and ($num <= 65535)) { + return pack("Cv", $this->ptg['ptgInt'], $num); + } else { // A float + if (PHPExcel_Writer_Excel5_BIFFwriter::getByteOrder()) { // if it's Big Endian + $num = strrev($num); + } + return pack("Cd", $this->ptg['ptgNum'], $num); + } + } + + /** + * Convert a string token to ptgStr + * + * @access private + * @param string $string A string for conversion to its ptg value. + * @return mixed the converted token on success + */ + function _convertString($string) + { + // chop away beggining and ending quotes + $string = substr($string, 1, strlen($string) - 2); + if (strlen($string) > 255) { + throw new PHPExcel_Writer_Exception("String is too long"); + } + + return pack('C', $this->ptg['ptgStr']) . PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($string); + } + + /** + * Convert a function to a ptgFunc or ptgFuncVarV depending on the number of + * args that it takes. + * + * @access private + * @param string $token The name of the function for convertion to ptg value. + * @param integer $num_args The number of arguments the function receives. + * @return string The packed ptg for the function + */ + function _convertFunction($token, $num_args) + { + $args = $this->_functions[$token][1]; +// $volatile = $this->_functions[$token][3]; + + // Fixed number of args eg. TIME($i,$j,$k). + if ($args >= 0) { + return pack("Cv", $this->ptg['ptgFuncV'], $this->_functions[$token][0]); + } + // Variable number of args eg. SUM($i,$j,$k, ..). + if ($args == -1) { + return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0]); + } + } + + /** + * Convert an Excel range such as A1:D4 to a ptgRefV. + * + * @access private + * @param string $range An Excel range in the A1:A2 + * @param int $class + */ + function _convertRange2d($range, $class=0) + { + + // TODO: possible class value 0,1,2 check Formula.pm + // Split the range into 2 cell refs + if (preg_match('/^(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)\:(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)$/', $range)) { + list($cell1, $cell2) = explode(':', $range); + } else { + // TODO: use real error codes + throw new PHPExcel_Writer_Exception("Unknown range separator"); + } + + // Convert the cell references + list($row1, $col1) = $this->_cellToPackedRowcol($cell1); + list($row2, $col2) = $this->_cellToPackedRowcol($cell2); + + // The ptg value depends on the class of the ptg. + if ($class == 0) { + $ptgArea = pack("C", $this->ptg['ptgArea']); + } elseif ($class == 1) { + $ptgArea = pack("C", $this->ptg['ptgAreaV']); + } elseif ($class == 2) { + $ptgArea = pack("C", $this->ptg['ptgAreaA']); + } else { + // TODO: use real error codes + throw new PHPExcel_Writer_Exception("Unknown class $class"); + } + return $ptgArea . $row1 . $row2 . $col1. $col2; + } + + /** + * Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to + * a ptgArea3d. + * + * @access private + * @param string $token An Excel range in the Sheet1!A1:A2 format. + * @return mixed The packed ptgArea3d token on success. + */ + function _convertRange3d($token) + { +// $class = 0; // formulas like Sheet1!$A$1:$A$2 in list type data validation need this class (0x3B) + + // Split the ref at the ! symbol + list($ext_ref, $range) = explode('!', $token); + + // Convert the external reference part (different for BIFF8) + $ext_ref = $this->_getRefIndex($ext_ref); + + // Split the range into 2 cell refs + list($cell1, $cell2) = explode(':', $range); + + // Convert the cell references + if (preg_match("/^(\\$)?[A-Ia-i]?[A-Za-z](\\$)?(\d+)$/", $cell1)) { + list($row1, $col1) = $this->_cellToPackedRowcol($cell1); + list($row2, $col2) = $this->_cellToPackedRowcol($cell2); + } else { // It's a rows range (like 26:27) + list($row1, $col1, $row2, $col2) = $this->_rangeToPackedRange($cell1.':'.$cell2); + } + + // The ptg value depends on the class of the ptg. +// if ($class == 0) { + $ptgArea = pack("C", $this->ptg['ptgArea3d']); +// } elseif ($class == 1) { +// $ptgArea = pack("C", $this->ptg['ptgArea3dV']); +// } elseif ($class == 2) { +// $ptgArea = pack("C", $this->ptg['ptgArea3dA']); +// } else { +// throw new PHPExcel_Writer_Exception("Unknown class $class"); +// } + + return $ptgArea . $ext_ref . $row1 . $row2 . $col1. $col2; + } + + /** + * Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV. + * + * @access private + * @param string $cell An Excel cell reference + * @return string The cell in packed() format with the corresponding ptg + */ + function _convertRef2d($cell) + { +// $class = 2; // as far as I know, this is magick. + + // Convert the cell reference + $cell_array = $this->_cellToPackedRowcol($cell); + list($row, $col) = $cell_array; + + // The ptg value depends on the class of the ptg. +// if ($class == 0) { +// $ptgRef = pack("C", $this->ptg['ptgRef']); +// } elseif ($class == 1) { +// $ptgRef = pack("C", $this->ptg['ptgRefV']); +// } elseif ($class == 2) { + $ptgRef = pack("C", $this->ptg['ptgRefA']); +// } else { +// // TODO: use real error codes +// throw new PHPExcel_Writer_Exception("Unknown class $class"); +// } + return $ptgRef.$row.$col; + } + + /** + * Convert an Excel 3d reference such as "Sheet1!A1" or "Sheet1:Sheet2!A1" to a + * ptgRef3d. + * + * @access private + * @param string $cell An Excel cell reference + * @return mixed The packed ptgRef3d token on success. + */ + function _convertRef3d($cell) + { +// $class = 2; // as far as I know, this is magick. + + // Split the ref at the ! symbol + list($ext_ref, $cell) = explode('!', $cell); + + // Convert the external reference part (different for BIFF8) + $ext_ref = $this->_getRefIndex($ext_ref); + + // Convert the cell reference part + list($row, $col) = $this->_cellToPackedRowcol($cell); + + // The ptg value depends on the class of the ptg. +// if ($class == 0) { +// $ptgRef = pack("C", $this->ptg['ptgRef3d']); +// } elseif ($class == 1) { +// $ptgRef = pack("C", $this->ptg['ptgRef3dV']); +// } elseif ($class == 2) { + $ptgRef = pack("C", $this->ptg['ptgRef3dA']); +// } else { +// throw new PHPExcel_Writer_Exception("Unknown class $class"); +// } + + return $ptgRef . $ext_ref. $row . $col; + } /** * Convert an error code to a ptgErr * - * @access private - * @param string $errorCode The error code for conversion to its ptg value - * @return string The error code ptgErr + * @access private + * @param string $errorCode The error code for conversion to its ptg value + * @return string The error code ptgErr */ function _convertError($errorCode) { - switch ($errorCode) { - case '#NULL!': return pack("C", 0x00); - case '#DIV/0!': return pack("C", 0x07); - case '#VALUE!': return pack("C", 0x0F); - case '#REF!': return pack("C", 0x17); - case '#NAME?': return pack("C", 0x1D); - case '#NUM!': return pack("C", 0x24); - case '#N/A': return pack("C", 0x2A); - } - return pack("C", 0xFF); + switch ($errorCode) { + case '#NULL!': return pack("C", 0x00); + case '#DIV/0!': return pack("C", 0x07); + case '#VALUE!': return pack("C", 0x0F); + case '#REF!': return pack("C", 0x17); + case '#NAME?': return pack("C", 0x1D); + case '#NUM!': return pack("C", 0x24); + case '#N/A': return pack("C", 0x2A); + } + return pack("C", 0xFF); } - /** - * Convert the sheet name part of an external reference, for example "Sheet1" or - * "Sheet1:Sheet2", to a packed structure. - * - * @access private - * @param string $ext_ref The name of the external reference - * @return string The reference index in packed() format - */ - function _packExtRef($ext_ref) - { - $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. - $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. - - // Check if there is a sheet range eg., Sheet1:Sheet2. - if (preg_match("/:/", $ext_ref)) { - list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); - - $sheet1 = $this->_getSheetIndex($sheet_name1); - if ($sheet1 == -1) { - throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); - } - $sheet2 = $this->_getSheetIndex($sheet_name2); - if ($sheet2 == -1) { - throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); - } - - // Reverse max and min sheet numbers if necessary - if ($sheet1 > $sheet2) { - list($sheet1, $sheet2) = array($sheet2, $sheet1); - } - } else { // Single sheet name only. - $sheet1 = $this->_getSheetIndex($ext_ref); - if ($sheet1 == -1) { - throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); - } - $sheet2 = $sheet1; - } - - // References are stored relative to 0xFFFF. - $offset = -1 - $sheet1; - - return pack('vdvv', $offset, 0x00, $sheet1, $sheet2); - } - - /** - * Look up the REF index that corresponds to an external sheet name - * (or range). If it doesn't exist yet add it to the workbook's references - * array. It assumes all sheet names given must exist. - * - * @access private - * @param string $ext_ref The name of the external reference - * @return mixed The reference index in packed() format on success - */ - function _getRefIndex($ext_ref) - { - $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. - $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. - $ext_ref = str_replace('\'\'', '\'', $ext_ref); // Replace escaped '' with ' - - // Check if there is a sheet range eg., Sheet1:Sheet2. - if (preg_match("/:/", $ext_ref)) { - list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); - - $sheet1 = $this->_getSheetIndex($sheet_name1); - if ($sheet1 == -1) { - throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); - } - $sheet2 = $this->_getSheetIndex($sheet_name2); - if ($sheet2 == -1) { - throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); - } - - // Reverse max and min sheet numbers if necessary - if ($sheet1 > $sheet2) { - list($sheet1, $sheet2) = array($sheet2, $sheet1); - } - } else { // Single sheet name only. - $sheet1 = $this->_getSheetIndex($ext_ref); - if ($sheet1 == -1) { - throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); - } - $sheet2 = $sheet1; - } - - // assume all references belong to this document - $supbook_index = 0x00; - $ref = pack('vvv', $supbook_index, $sheet1, $sheet2); - $total_references = count($this->_references); - $index = -1; - for ($i = 0; $i < $total_references; ++$i) { - if ($ref == $this->_references[$i]) { - $index = $i; - break; - } - } - // if REF was not found add it to references array - if ($index == -1) { - $this->_references[$total_references] = $ref; - $index = $total_references; - } - - return pack('v', $index); - } - - /** - * Look up the index that corresponds to an external sheet name. The hash of - * sheet names is updated by the addworksheet() method of the - * PHPExcel_Writer_Excel5_Workbook class. - * - * @access private - * @param string $sheet_name Sheet name - * @return integer The sheet index, -1 if the sheet was not found - */ - function _getSheetIndex($sheet_name) - { - if (!isset($this->_ext_sheets[$sheet_name])) { - return -1; - } else { - return $this->_ext_sheets[$sheet_name]; - } - } - - /** - * This method is used to update the array of sheet names. It is - * called by the addWorksheet() method of the - * PHPExcel_Writer_Excel5_Workbook class. - * - * @access public - * @see PHPExcel_Writer_Excel5_Workbook::addWorksheet() - * @param string $name The name of the worksheet being added - * @param integer $index The index of the worksheet being added - */ - function setExtSheet($name, $index) - { - $this->_ext_sheets[$name] = $index; - } - - /** - * pack() row and column into the required 3 or 4 byte format. - * - * @access private - * @param string $cell The Excel cell reference to be packed - * @return array Array containing the row and column in packed() format - */ - function _cellToPackedRowcol($cell) - { - $cell = strtoupper($cell); - list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell); - if ($col >= 256) { - throw new PHPExcel_Writer_Exception("Column in: $cell greater than 255"); - } - if ($row >= 65536) { - throw new PHPExcel_Writer_Exception("Row in: $cell greater than 65536 "); - } - - // Set the high bits to indicate if row or col are relative. - $col |= $col_rel << 14; - $col |= $row_rel << 15; - $col = pack('v', $col); - - $row = pack('v', $row); - - return array($row, $col); - } - - /** - * pack() row range into the required 3 or 4 byte format. - * Just using maximum col/rows, which is probably not the correct solution - * - * @access private - * @param string $range The Excel range to be packed - * @return array Array containing (row1,col1,row2,col2) in packed() format - */ - function _rangeToPackedRange($range) - { - preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match); - // return absolute rows if there is a $ in the ref - $row1_rel = empty($match[1]) ? 1 : 0; - $row1 = $match[2]; - $row2_rel = empty($match[3]) ? 1 : 0; - $row2 = $match[4]; - // Convert 1-index to zero-index - --$row1; - --$row2; - // Trick poor inocent Excel - $col1 = 0; - $col2 = 65535; // FIXME: maximum possible value for Excel 5 (change this!!!) - - // FIXME: this changes for BIFF8 - if (($row1 >= 65536) or ($row2 >= 65536)) { - throw new PHPExcel_Writer_Exception("Row in: $range greater than 65536 "); - } - - // Set the high bits to indicate if rows are relative. - $col1 |= $row1_rel << 15; - $col2 |= $row2_rel << 15; - $col1 = pack('v', $col1); - $col2 = pack('v', $col2); - - $row1 = pack('v', $row1); - $row2 = pack('v', $row2); - - return array($row1, $col1, $row2, $col2); - } - - /** - * Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero - * indexed row and column number. Also returns two (0,1) values to indicate - * whether the row or column are relative references. - * - * @access private - * @param string $cell The Excel cell reference in A1 format. - * @return array - */ - function _cellToRowcol($cell) - { - preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/',$cell,$match); - // return absolute column if there is a $ in the ref - $col_rel = empty($match[1]) ? 1 : 0; - $col_ref = $match[2]; - $row_rel = empty($match[3]) ? 1 : 0; - $row = $match[4]; - - // Convert base26 column string to a number. - $expn = strlen($col_ref) - 1; - $col = 0; - $col_ref_length = strlen($col_ref); - for ($i = 0; $i < $col_ref_length; ++$i) { - $col += (ord($col_ref{$i}) - 64) * pow(26, $expn); - --$expn; - } - - // Convert 1-index to zero-index - --$row; - --$col; - - return array($row, $col, $row_rel, $col_rel); - } - - /** - * Advance to the next valid token. - * - * @access private - */ - function _advance() - { - $i = $this->_current_char; - $formula_length = strlen($this->_formula); - // eat up white spaces - if ($i < $formula_length) { - while ($this->_formula{$i} == " ") { - ++$i; - } - - if ($i < ($formula_length - 1)) { - $this->_lookahead = $this->_formula{$i+1}; - } - $token = ''; - } - - while ($i < $formula_length) { - $token .= $this->_formula{$i}; - - if ($i < ($formula_length - 1)) { - $this->_lookahead = $this->_formula{$i+1}; - } else { - $this->_lookahead = ''; - } - - if ($this->_match($token) != '') { - //if ($i < strlen($this->_formula) - 1) { - // $this->_lookahead = $this->_formula{$i+1}; - //} - $this->_current_char = $i + 1; - $this->_current_token = $token; - return 1; - } - - if ($i < ($formula_length - 2)) { - $this->_lookahead = $this->_formula{$i+2}; - } else { // if we run out of characters _lookahead becomes empty - $this->_lookahead = ''; - } - ++$i; - } - //die("Lexical error ".$this->_current_char); - } - - /** - * Checks if it's a valid token. - * - * @access private - * @param mixed $token The token to check. - * @return mixed The checked token or false on failure - */ - function _match($token) - { - switch($token) { - case "+": - case "-": - case "*": - case "/": - case "(": - case ")": - case ",": - case ";": - case ">=": - case "<=": - case "=": - case "<>": - case "^": - case "&": - case "%": - return $token; - break; - case ">": - if ($this->_lookahead == '=') { // it's a GE token - break; - } - return $token; - break; - case "<": - // it's a LE or a NE token - if (($this->_lookahead == '=') or ($this->_lookahead == '>')) { - break; - } - return $token; - break; - default: - // if it's a reference A1 or $A$1 or $A1 or A$1 - if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$token) and - !preg_match("/[0-9]/",$this->_lookahead) and - ($this->_lookahead != ':') and ($this->_lookahead != '.') and - ($this->_lookahead != '!')) - { - return $token; - } - // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$token) and - !preg_match("/[0-9]/",$this->_lookahead) and - ($this->_lookahead != ':') and ($this->_lookahead != '.')) - { - return $token; - } - // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$token) and - !preg_match("/[0-9]/",$this->_lookahead) and - ($this->_lookahead != ':') and ($this->_lookahead != '.')) - { - return $token; - } - // if it's a range A1:A2 or $A$1:$A$2 - elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) and - !preg_match("/[0-9]/",$this->_lookahead)) - { - return $token; - } - // If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$token) and - !preg_match("/[0-9]/",$this->_lookahead)) - { - return $token; - } - // If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$token) and - !preg_match("/[0-9]/",$this->_lookahead)) - { - return $token; - } - // If it's a number (check that it's not a sheet name or range) - elseif (is_numeric($token) and - (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and - ($this->_lookahead != '!') and ($this->_lookahead != ':')) - { - return $token; - } - // If it's a string (of maximum 255 characters) - elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/",$token) and $this->_lookahead != '"' and (substr_count($token, '"')%2 == 0)) - { - return $token; - } - // If it's an error code - elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') - { - return $token; - } - // if it's a function call - elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$token) and ($this->_lookahead == "(")) - { - return $token; - } - // It's an argument of some description (e.g. a named range), - // precise nature yet to be determined - elseif(substr($token,-1) == ')') { - return $token; - } - return ''; - } - } - - /** - * The parsing method. It parses a formula. - * - * @access public - * @param string $formula The formula to parse, without the initial equal - * sign (=). - * @return mixed true on success - */ - function parse($formula) - { - $this->_current_char = 0; - $this->_formula = $formula; - $this->_lookahead = isset($formula{1}) ? $formula{1} : ''; - $this->_advance(); - $this->_parse_tree = $this->_condition(); - return true; - } - - /** - * It parses a condition. It assumes the following rule: - * Cond -> Expr [(">" | "<") Expr] - * - * @access private - * @return mixed The parsed ptg'd tree on success - */ - function _condition() - { - $result = $this->_expression(); - if ($this->_current_token == "<") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgLT', $result, $result2); - } elseif ($this->_current_token == ">") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgGT', $result, $result2); - } elseif ($this->_current_token == "<=") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgLE', $result, $result2); - } elseif ($this->_current_token == ">=") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgGE', $result, $result2); - } elseif ($this->_current_token == "=") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgEQ', $result, $result2); - } elseif ($this->_current_token == "<>") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgNE', $result, $result2); - } elseif ($this->_current_token == "&") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgConcat', $result, $result2); - } - return $result; - } - - /** - * It parses a expression. It assumes the following rule: - * Expr -> Term [("+" | "-") Term] - * -> "string" - * -> "-" Term : Negative value - * -> "+" Term : Positive value - * -> Error code - * - * @access private - * @return mixed The parsed ptg'd tree on success - */ - function _expression() - { - // If it's a string return a string node - if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $this->_current_token)) { - $tmp = str_replace('""', '"', $this->_current_token); - if (($tmp == '"') || ($tmp == '')) $tmp = '""'; // Trap for "" that has been used for an empty string - $result = $this->_createTree($tmp, '', ''); - $this->_advance(); - return $result; + /** + * Convert the sheet name part of an external reference, for example "Sheet1" or + * "Sheet1:Sheet2", to a packed structure. + * + * @access private + * @param string $ext_ref The name of the external reference + * @return string The reference index in packed() format + */ + function _packExtRef($ext_ref) + { + $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. + $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. + + // Check if there is a sheet range eg., Sheet1:Sheet2. + if (preg_match("/:/", $ext_ref)) { + list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); + + $sheet1 = $this->_getSheetIndex($sheet_name1); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); + } + $sheet2 = $this->_getSheetIndex($sheet_name2); + if ($sheet2 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); + } + + // Reverse max and min sheet numbers if necessary + if ($sheet1 > $sheet2) { + list($sheet1, $sheet2) = array($sheet2, $sheet1); + } + } else { // Single sheet name only. + $sheet1 = $this->_getSheetIndex($ext_ref); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); + } + $sheet2 = $sheet1; + } + + // References are stored relative to 0xFFFF. + $offset = -1 - $sheet1; + + return pack('vdvv', $offset, 0x00, $sheet1, $sheet2); + } + + /** + * Look up the REF index that corresponds to an external sheet name + * (or range). If it doesn't exist yet add it to the workbook's references + * array. It assumes all sheet names given must exist. + * + * @access private + * @param string $ext_ref The name of the external reference + * @return mixed The reference index in packed() format on success + */ + function _getRefIndex($ext_ref) + { + $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. + $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. + $ext_ref = str_replace('\'\'', '\'', $ext_ref); // Replace escaped '' with ' + + // Check if there is a sheet range eg., Sheet1:Sheet2. + if (preg_match("/:/", $ext_ref)) { + list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); + + $sheet1 = $this->_getSheetIndex($sheet_name1); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); + } + $sheet2 = $this->_getSheetIndex($sheet_name2); + if ($sheet2 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); + } + + // Reverse max and min sheet numbers if necessary + if ($sheet1 > $sheet2) { + list($sheet1, $sheet2) = array($sheet2, $sheet1); + } + } else { // Single sheet name only. + $sheet1 = $this->_getSheetIndex($ext_ref); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); + } + $sheet2 = $sheet1; + } + + // assume all references belong to this document + $supbook_index = 0x00; + $ref = pack('vvv', $supbook_index, $sheet1, $sheet2); + $total_references = count($this->_references); + $index = -1; + for ($i = 0; $i < $total_references; ++$i) { + if ($ref == $this->_references[$i]) { + $index = $i; + break; + } + } + // if REF was not found add it to references array + if ($index == -1) { + $this->_references[$total_references] = $ref; + $index = $total_references; + } + + return pack('v', $index); + } + + /** + * Look up the index that corresponds to an external sheet name. The hash of + * sheet names is updated by the addworksheet() method of the + * PHPExcel_Writer_Excel5_Workbook class. + * + * @access private + * @param string $sheet_name Sheet name + * @return integer The sheet index, -1 if the sheet was not found + */ + function _getSheetIndex($sheet_name) + { + if (!isset($this->_ext_sheets[$sheet_name])) { + return -1; + } else { + return $this->_ext_sheets[$sheet_name]; + } + } + + /** + * This method is used to update the array of sheet names. It is + * called by the addWorksheet() method of the + * PHPExcel_Writer_Excel5_Workbook class. + * + * @access public + * @see PHPExcel_Writer_Excel5_Workbook::addWorksheet() + * @param string $name The name of the worksheet being added + * @param integer $index The index of the worksheet being added + */ + function setExtSheet($name, $index) + { + $this->_ext_sheets[$name] = $index; + } + + /** + * pack() row and column into the required 3 or 4 byte format. + * + * @access private + * @param string $cell The Excel cell reference to be packed + * @return array Array containing the row and column in packed() format + */ + function _cellToPackedRowcol($cell) + { + $cell = strtoupper($cell); + list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell); + if ($col >= 256) { + throw new PHPExcel_Writer_Exception("Column in: $cell greater than 255"); + } + if ($row >= 65536) { + throw new PHPExcel_Writer_Exception("Row in: $cell greater than 65536 "); + } + + // Set the high bits to indicate if row or col are relative. + $col |= $col_rel << 14; + $col |= $row_rel << 15; + $col = pack('v', $col); + + $row = pack('v', $row); + + return array($row, $col); + } + + /** + * pack() row range into the required 3 or 4 byte format. + * Just using maximum col/rows, which is probably not the correct solution + * + * @access private + * @param string $range The Excel range to be packed + * @return array Array containing (row1,col1,row2,col2) in packed() format + */ + function _rangeToPackedRange($range) + { + preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match); + // return absolute rows if there is a $ in the ref + $row1_rel = empty($match[1]) ? 1 : 0; + $row1 = $match[2]; + $row2_rel = empty($match[3]) ? 1 : 0; + $row2 = $match[4]; + // Convert 1-index to zero-index + --$row1; + --$row2; + // Trick poor inocent Excel + $col1 = 0; + $col2 = 65535; // FIXME: maximum possible value for Excel 5 (change this!!!) + + // FIXME: this changes for BIFF8 + if (($row1 >= 65536) or ($row2 >= 65536)) { + throw new PHPExcel_Writer_Exception("Row in: $range greater than 65536 "); + } + + // Set the high bits to indicate if rows are relative. + $col1 |= $row1_rel << 15; + $col2 |= $row2_rel << 15; + $col1 = pack('v', $col1); + $col2 = pack('v', $col2); + + $row1 = pack('v', $row1); + $row2 = pack('v', $row2); + + return array($row1, $col1, $row2, $col2); + } + + /** + * Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero + * indexed row and column number. Also returns two (0,1) values to indicate + * whether the row or column are relative references. + * + * @access private + * @param string $cell The Excel cell reference in A1 format. + * @return array + */ + function _cellToRowcol($cell) + { + preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/',$cell,$match); + // return absolute column if there is a $ in the ref + $col_rel = empty($match[1]) ? 1 : 0; + $col_ref = $match[2]; + $row_rel = empty($match[3]) ? 1 : 0; + $row = $match[4]; + + // Convert base26 column string to a number. + $expn = strlen($col_ref) - 1; + $col = 0; + $col_ref_length = strlen($col_ref); + for ($i = 0; $i < $col_ref_length; ++$i) { + $col += (ord($col_ref{$i}) - 64) * pow(26, $expn); + --$expn; + } + + // Convert 1-index to zero-index + --$row; + --$col; + + return array($row, $col, $row_rel, $col_rel); + } + + /** + * Advance to the next valid token. + * + * @access private + */ + function _advance() + { + $i = $this->_current_char; + $formula_length = strlen($this->_formula); + // eat up white spaces + if ($i < $formula_length) { + while ($this->_formula{$i} == " ") { + ++$i; + } + + if ($i < ($formula_length - 1)) { + $this->_lookahead = $this->_formula{$i+1}; + } + $token = ''; + } + + while ($i < $formula_length) { + $token .= $this->_formula{$i}; + + if ($i < ($formula_length - 1)) { + $this->_lookahead = $this->_formula{$i+1}; + } else { + $this->_lookahead = ''; + } + + if ($this->_match($token) != '') { + //if ($i < strlen($this->_formula) - 1) { + // $this->_lookahead = $this->_formula{$i+1}; + //} + $this->_current_char = $i + 1; + $this->_current_token = $token; + return 1; + } + + if ($i < ($formula_length - 2)) { + $this->_lookahead = $this->_formula{$i+2}; + } else { // if we run out of characters _lookahead becomes empty + $this->_lookahead = ''; + } + ++$i; + } + //die("Lexical error ".$this->_current_char); + } + + /** + * Checks if it's a valid token. + * + * @access private + * @param mixed $token The token to check. + * @return mixed The checked token or false on failure + */ + function _match($token) + { + switch($token) { + case "+": + case "-": + case "*": + case "/": + case "(": + case ")": + case ",": + case ";": + case ">=": + case "<=": + case "=": + case "<>": + case "^": + case "&": + case "%": + return $token; + break; + case ">": + if ($this->_lookahead == '=') { // it's a GE token + break; + } + return $token; + break; + case "<": + // it's a LE or a NE token + if (($this->_lookahead == '=') or ($this->_lookahead == '>')) { + break; + } + return $token; + break; + default: + // if it's a reference A1 or $A$1 or $A1 or A$1 + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$token) and + !preg_match("/[0-9]/",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.') and + ($this->_lookahead != '!')) + { + return $token; + } + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.')) + { + return $token; + } + // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.')) + { + return $token; + } + // if it's a range A1:A2 or $A$1:$A$2 + elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) and + !preg_match("/[0-9]/",$this->_lookahead)) + { + return $token; + } + // If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead)) + { + return $token; + } + // If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead)) + { + return $token; + } + // If it's a number (check that it's not a sheet name or range) + elseif (is_numeric($token) and + (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and + ($this->_lookahead != '!') and ($this->_lookahead != ':')) + { + return $token; + } + // If it's a string (of maximum 255 characters) + elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/",$token) and $this->_lookahead != '"' and (substr_count($token, '"')%2 == 0)) + { + return $token; + } + // If it's an error code + elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') + { + return $token; + } + // if it's a function call + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$token) and ($this->_lookahead == "(")) + { + return $token; + } + // It's an argument of some description (e.g. a named range), + // precise nature yet to be determined + elseif(substr($token,-1) == ')') { + return $token; + } + return ''; + } + } + + /** + * The parsing method. It parses a formula. + * + * @access public + * @param string $formula The formula to parse, without the initial equal + * sign (=). + * @return mixed true on success + */ + function parse($formula) + { + $this->_current_char = 0; + $this->_formula = $formula; + $this->_lookahead = isset($formula{1}) ? $formula{1} : ''; + $this->_advance(); + $this->_parse_tree = $this->_condition(); + return true; + } + + /** + * It parses a condition. It assumes the following rule: + * Cond -> Expr [(">" | "<") Expr] + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _condition() + { + $result = $this->_expression(); + if ($this->_current_token == "<") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgLT', $result, $result2); + } elseif ($this->_current_token == ">") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgGT', $result, $result2); + } elseif ($this->_current_token == "<=") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgLE', $result, $result2); + } elseif ($this->_current_token == ">=") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgGE', $result, $result2); + } elseif ($this->_current_token == "=") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgEQ', $result, $result2); + } elseif ($this->_current_token == "<>") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgNE', $result, $result2); + } elseif ($this->_current_token == "&") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgConcat', $result, $result2); + } + return $result; + } + + /** + * It parses a expression. It assumes the following rule: + * Expr -> Term [("+" | "-") Term] + * -> "string" + * -> "-" Term : Negative value + * -> "+" Term : Positive value + * -> Error code + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _expression() + { + // If it's a string return a string node + if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $this->_current_token)) { + $tmp = str_replace('""', '"', $this->_current_token); + if (($tmp == '"') || ($tmp == '')) $tmp = '""'; // Trap for "" that has been used for an empty string + $result = $this->_createTree($tmp, '', ''); + $this->_advance(); + return $result; // If it's an error code } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $this->_current_token) or $this->_current_token == '#N/A'){ - $result = $this->_createTree($this->_current_token, 'ptgErr', ''); - $this->_advance(); - return $result; - // If it's a negative value + $result = $this->_createTree($this->_current_token, 'ptgErr', ''); + $this->_advance(); + return $result; + // If it's a negative value } elseif ($this->_current_token == "-") { - // catch "-" Term - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgUminus', $result2, ''); - return $result; + // catch "-" Term + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgUminus', $result2, ''); + return $result; // If it's a positive value - } elseif ($this->_current_token == "+") { - // catch "+" Term - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgUplus', $result2, ''); - return $result; - } - $result = $this->_term(); - while (($this->_current_token == "+") or - ($this->_current_token == "-") or - ($this->_current_token == "^")) { - /**/ - if ($this->_current_token == "+") { - $this->_advance(); - $result2 = $this->_term(); - $result = $this->_createTree('ptgAdd', $result, $result2); - } elseif ($this->_current_token == "-") { - $this->_advance(); - $result2 = $this->_term(); - $result = $this->_createTree('ptgSub', $result, $result2); - } else { - $this->_advance(); - $result2 = $this->_term(); - $result = $this->_createTree('ptgPower', $result, $result2); - } - } - return $result; - } - - /** - * This function just introduces a ptgParen element in the tree, so that Excel - * doesn't get confused when working with a parenthesized formula afterwards. - * - * @access private - * @see _fact() - * @return array The parsed ptg'd tree - */ - function _parenthesizedExpression() - { - $result = $this->_createTree('ptgParen', $this->_expression(), ''); - return $result; - } - - /** - * It parses a term. It assumes the following rule: - * Term -> Fact [("*" | "/") Fact] - * - * @access private - * @return mixed The parsed ptg'd tree on success - */ - function _term() - { - $result = $this->_fact(); - while (($this->_current_token == "*") or - ($this->_current_token == "/")) { - /**/ - if ($this->_current_token == "*") { - $this->_advance(); - $result2 = $this->_fact(); - $result = $this->_createTree('ptgMul', $result, $result2); - } else { - $this->_advance(); - $result2 = $this->_fact(); - $result = $this->_createTree('ptgDiv', $result, $result2); - } - } - return $result; - } - - /** - * It parses a factor. It assumes the following rule: - * Fact -> ( Expr ) - * | CellRef - * | CellRange - * | Number - * | Function - * - * @access private - * @return mixed The parsed ptg'd tree on success - */ - function _fact() - { - if ($this->_current_token == "(") { - $this->_advance(); // eat the "(" - $result = $this->_parenthesizedExpression(); - if ($this->_current_token != ")") { - throw new PHPExcel_Writer_Exception("')' token expected."); - } - $this->_advance(); // eat the ")" - return $result; - } - // if it's a reference - if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$this->_current_token)) - { - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); - return $result; - } - // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$this->_current_token)) - { - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); - return $result; - } - // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$this->_current_token)) - { - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); - return $result; - } - // if it's a range A1:B2 or $A$1:$B$2 - elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/',$this->_current_token) or - preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/',$this->_current_token)) - { - // must be an error? - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); - return $result; - } - // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$this->_current_token)) - { - // must be an error? - //$result = $this->_current_token; - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); - return $result; - } - // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$this->_current_token)) - { - // must be an error? - //$result = $this->_current_token; - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); - return $result; - } - // If it's a number or a percent - elseif (is_numeric($this->_current_token)) - { - if($this->_lookahead == '%'){ - $result = $this->_createTree('ptgPercent', $this->_current_token, ''); + } elseif ($this->_current_token == "+") { + // catch "+" Term + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgUplus', $result2, ''); + return $result; + } + $result = $this->_term(); + while (($this->_current_token == "+") or + ($this->_current_token == "-") or + ($this->_current_token == "^")) { + /**/ + if ($this->_current_token == "+") { + $this->_advance(); + $result2 = $this->_term(); + $result = $this->_createTree('ptgAdd', $result, $result2); + } elseif ($this->_current_token == "-") { + $this->_advance(); + $result2 = $this->_term(); + $result = $this->_createTree('ptgSub', $result, $result2); + } else { + $this->_advance(); + $result2 = $this->_term(); + $result = $this->_createTree('ptgPower', $result, $result2); + } + } + return $result; + } + + /** + * This function just introduces a ptgParen element in the tree, so that Excel + * doesn't get confused when working with a parenthesized formula afterwards. + * + * @access private + * @see _fact() + * @return array The parsed ptg'd tree + */ + function _parenthesizedExpression() + { + $result = $this->_createTree('ptgParen', $this->_expression(), ''); + return $result; + } + + /** + * It parses a term. It assumes the following rule: + * Term -> Fact [("*" | "/") Fact] + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _term() + { + $result = $this->_fact(); + while (($this->_current_token == "*") or + ($this->_current_token == "/")) { + /**/ + if ($this->_current_token == "*") { + $this->_advance(); + $result2 = $this->_fact(); + $result = $this->_createTree('ptgMul', $result, $result2); + } else { + $this->_advance(); + $result2 = $this->_fact(); + $result = $this->_createTree('ptgDiv', $result, $result2); + } + } + return $result; + } + + /** + * It parses a factor. It assumes the following rule: + * Fact -> ( Expr ) + * | CellRef + * | CellRange + * | Number + * | Function + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _fact() + { + if ($this->_current_token == "(") { + $this->_advance(); // eat the "(" + $result = $this->_parenthesizedExpression(); + if ($this->_current_token != ")") { + throw new PHPExcel_Writer_Exception("')' token expected."); + } + $this->_advance(); // eat the ")" + return $result; + } + // if it's a reference + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // if it's a range A1:B2 or $A$1:$B$2 + elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/',$this->_current_token) or + preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/',$this->_current_token)) + { + // must be an error? + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$this->_current_token)) + { + // must be an error? + //$result = $this->_current_token; + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$this->_current_token)) + { + // must be an error? + //$result = $this->_current_token; + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's a number or a percent + elseif (is_numeric($this->_current_token)) + { + if($this->_lookahead == '%'){ + $result = $this->_createTree('ptgPercent', $this->_current_token, ''); $this->_advance(); // Skip the percentage operator once we've pre-built that tree - } else { - $result = $this->_createTree($this->_current_token, '', ''); - } - $this->_advance(); - return $result; - } - // if it's a function call - elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$this->_current_token)) - { - $result = $this->_func(); - return $result; - } - throw new PHPExcel_Writer_Exception("Syntax error: ".$this->_current_token. - ", lookahead: ".$this->_lookahead. - ", current char: ".$this->_current_char); - } - - /** - * It parses a function call. It assumes the following rule: - * Func -> ( Expr [,Expr]* ) - * - * @access private - * @return mixed The parsed ptg'd tree on success - */ - function _func() - { - $num_args = 0; // number of arguments received - $function = strtoupper($this->_current_token); - $result = ''; // initialize result - $this->_advance(); - $this->_advance(); // eat the "(" - while ($this->_current_token != ')') { - /**/ - if ($num_args > 0) { - if ($this->_current_token == "," or - $this->_current_token == ";") - { - $this->_advance(); // eat the "," or ";" - } else { - throw new PHPExcel_Writer_Exception("Syntax error: comma expected in ". - "function $function, arg #{$num_args}"); - } - $result2 = $this->_condition(); - $result = $this->_createTree('arg', $result, $result2); - } else { // first argument - $result2 = $this->_condition(); - $result = $this->_createTree('arg', '', $result2); - } - ++$num_args; - } - if (!isset($this->_functions[$function])) { - throw new PHPExcel_Writer_Exception("Function $function() doesn't exist"); - } - $args = $this->_functions[$function][1]; - // If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid. - if (($args >= 0) and ($args != $num_args)) { - throw new PHPExcel_Writer_Exception("Incorrect number of arguments in function $function() "); - } - - $result = $this->_createTree($function, $result, $num_args); - $this->_advance(); // eat the ")" - return $result; - } - - /** - * Creates a tree. In fact an array which may have one or two arrays (sub-trees) - * as elements. - * - * @access private - * @param mixed $value The value of this node. - * @param mixed $left The left array (sub-tree) or a final node. - * @param mixed $right The right array (sub-tree) or a final node. - * @return array A tree - */ - function _createTree($value, $left, $right) - { - return array('value' => $value, 'left' => $left, 'right' => $right); - } - - /** - * Builds a string containing the tree in reverse polish notation (What you - * would use in a HP calculator stack). - * The following tree: - * - * + - * / \ - * 2 3 - * - * produces: "23+" - * - * The following tree: - * - * + - * / \ - * 3 * - * / \ - * 6 A1 - * - * produces: "36A1*+" - * - * In fact all operands, functions, references, etc... are written as ptg's - * - * @access public - * @param array $tree The optional tree to convert. - * @return string The tree in reverse polish notation - */ - function toReversePolish($tree = array()) - { - $polish = ""; // the string we are going to return - if (empty($tree)) { // If it's the first call use _parse_tree - $tree = $this->_parse_tree; - } - - if (is_array($tree['left'])) { - $converted_tree = $this->toReversePolish($tree['left']); - $polish .= $converted_tree; - } elseif ($tree['left'] != '') { // It's a final node - $converted_tree = $this->_convert($tree['left']); - $polish .= $converted_tree; - } - if (is_array($tree['right'])) { - $converted_tree = $this->toReversePolish($tree['right']); - $polish .= $converted_tree; - } elseif ($tree['right'] != '') { // It's a final node - $converted_tree = $this->_convert($tree['right']); - $polish .= $converted_tree; - } - // if it's a function convert it here (so we can set it's arguments) - if (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/",$tree['value']) and - !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/',$tree['value']) and - !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/",$tree['value']) and - !is_numeric($tree['value']) and - !isset($this->ptg[$tree['value']])) - { - // left subtree for a function is always an array. - if ($tree['left'] != '') { - $left_tree = $this->toReversePolish($tree['left']); - } else { - $left_tree = ''; - } - // add it's left subtree and return. - return $left_tree.$this->_convertFunction($tree['value'], $tree['right']); - } else { - $converted_tree = $this->_convert($tree['value']); - } - $polish .= $converted_tree; - return $polish; - } + } else { + $result = $this->_createTree($this->_current_token, '', ''); + } + $this->_advance(); + return $result; + } + // if it's a function call + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$this->_current_token)) + { + $result = $this->_func(); + return $result; + } + throw new PHPExcel_Writer_Exception("Syntax error: ".$this->_current_token. + ", lookahead: ".$this->_lookahead. + ", current char: ".$this->_current_char); + } + + /** + * It parses a function call. It assumes the following rule: + * Func -> ( Expr [,Expr]* ) + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _func() + { + $num_args = 0; // number of arguments received + $function = strtoupper($this->_current_token); + $result = ''; // initialize result + $this->_advance(); + $this->_advance(); // eat the "(" + while ($this->_current_token != ')') { + /**/ + if ($num_args > 0) { + if ($this->_current_token == "," or + $this->_current_token == ";") + { + $this->_advance(); // eat the "," or ";" + } else { + throw new PHPExcel_Writer_Exception("Syntax error: comma expected in ". + "function $function, arg #{$num_args}"); + } + $result2 = $this->_condition(); + $result = $this->_createTree('arg', $result, $result2); + } else { // first argument + $result2 = $this->_condition(); + $result = $this->_createTree('arg', '', $result2); + } + ++$num_args; + } + if (!isset($this->_functions[$function])) { + throw new PHPExcel_Writer_Exception("Function $function() doesn't exist"); + } + $args = $this->_functions[$function][1]; + // If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid. + if (($args >= 0) and ($args != $num_args)) { + throw new PHPExcel_Writer_Exception("Incorrect number of arguments in function $function() "); + } + + $result = $this->_createTree($function, $result, $num_args); + $this->_advance(); // eat the ")" + return $result; + } + + /** + * Creates a tree. In fact an array which may have one or two arrays (sub-trees) + * as elements. + * + * @access private + * @param mixed $value The value of this node. + * @param mixed $left The left array (sub-tree) or a final node. + * @param mixed $right The right array (sub-tree) or a final node. + * @return array A tree + */ + function _createTree($value, $left, $right) + { + return array('value' => $value, 'left' => $left, 'right' => $right); + } + + /** + * Builds a string containing the tree in reverse polish notation (What you + * would use in a HP calculator stack). + * The following tree: + * + * + + * / \ + * 2 3 + * + * produces: "23+" + * + * The following tree: + * + * + + * / \ + * 3 * + * / \ + * 6 A1 + * + * produces: "36A1*+" + * + * In fact all operands, functions, references, etc... are written as ptg's + * + * @access public + * @param array $tree The optional tree to convert. + * @return string The tree in reverse polish notation + */ + function toReversePolish($tree = array()) + { + $polish = ""; // the string we are going to return + if (empty($tree)) { // If it's the first call use _parse_tree + $tree = $this->_parse_tree; + } + + if (is_array($tree['left'])) { + $converted_tree = $this->toReversePolish($tree['left']); + $polish .= $converted_tree; + } elseif ($tree['left'] != '') { // It's a final node + $converted_tree = $this->_convert($tree['left']); + $polish .= $converted_tree; + } + if (is_array($tree['right'])) { + $converted_tree = $this->toReversePolish($tree['right']); + $polish .= $converted_tree; + } elseif ($tree['right'] != '') { // It's a final node + $converted_tree = $this->_convert($tree['right']); + $polish .= $converted_tree; + } + // if it's a function convert it here (so we can set it's arguments) + if (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/",$tree['value']) and + !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/',$tree['value']) and + !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/",$tree['value']) and + !is_numeric($tree['value']) and + !isset($this->ptg[$tree['value']])) + { + // left subtree for a function is always an array. + if ($tree['left'] != '') { + $left_tree = $this->toReversePolish($tree['left']); + } else { + $left_tree = ''; + } + // add it's left subtree and return. + return $left_tree.$this->_convertFunction($tree['value'], $tree['right']); + } else { + $converted_tree = $this->_convert($tree['value']); + } + $polish .= $converted_tree; + return $polish; + } } diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index f1b3cc725..f5a47a431 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -70,1381 +70,1381 @@ */ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter { - /** - * Formula parser - * - * @var PHPExcel_Writer_Excel5_Parser - */ - private $_parser; - - /** - * The BIFF file size for the workbook. - * @var integer - * @see _calcSheetOffsets() - */ - public $_biffsize; - - /** - * XF Writers - * @var PHPExcel_Writer_Excel5_Xf[] - */ - private $_xfWriters = array(); - - /** - * Array containing the colour palette - * @var array - */ - public $_palette; - - /** - * The codepage indicates the text encoding used for strings - * @var integer - */ - public $_codepage; - - /** - * The country code used for localization - * @var integer - */ - public $_country_code; - - /** - * Workbook - * @var PHPExcel - */ - private $_phpExcel; - - /** - * Fonts writers - * - * @var PHPExcel_Writer_Excel5_Font[] - */ - private $_fontWriters = array(); - - /** - * Added fonts. Maps from font's hash => index in workbook - * - * @var array - */ - private $_addedFonts = array(); - - /** - * Shared number formats - * - * @var array - */ - private $_numberFormats = array(); - - /** - * Added number formats. Maps from numberFormat's hash => index in workbook - * - * @var array - */ - private $_addedNumberFormats = array(); - - /** - * Sizes of the binary worksheet streams - * - * @var array - */ - private $_worksheetSizes = array(); - - /** - * Offsets of the binary worksheet streams relative to the start of the global workbook stream - * - * @var array - */ - private $_worksheetOffsets = array(); - - /** - * Total number of shared strings in workbook - * - * @var int - */ - private $_str_total; - - /** - * Number of unique shared strings in workbook - * - * @var int - */ - private $_str_unique; - - /** - * Array of unique shared strings in workbook - * - * @var array - */ - private $_str_table; - - /** - * Color cache - */ - private $_colors; - - /** - * Escher object corresponding to MSODRAWINGGROUP - * - * @var PHPExcel_Shared_Escher - */ - private $_escher; - - - /** - * Class constructor - * - * @param PHPExcel $phpExcel The Workbook - * @param int &$str_total Total number of strings - * @param int &$str_unique Total number of unique strings - * @param array &$str_table String Table - * @param array &$colors Colour Table - * @param mixed $parser The formula parser created for the Workbook - */ - public function __construct(PHPExcel $phpExcel = null, - &$str_total, &$str_unique, &$str_table, &$colors, - $parser ) - { - // It needs to call its parent's constructor explicitly - parent::__construct(); - - $this->_parser = $parser; - $this->_biffsize = 0; - $this->_palette = array(); - $this->_country_code = -1; - - $this->_str_total = &$str_total; - $this->_str_unique = &$str_unique; - $this->_str_table = &$str_table; - $this->_colors = &$colors; - $this->_setPaletteXl97(); - - $this->_phpExcel = $phpExcel; - - // set BIFFwriter limit for CONTINUE records - // $this->_limit = 8224; - $this->_codepage = 0x04B0; - - // Add empty sheets and Build color cache - $countSheets = $phpExcel->getSheetCount(); - for ($i = 0; $i < $countSheets; ++$i) { - $phpSheet = $phpExcel->getSheet($i); - - $this->_parser->setExtSheet($phpSheet->getTitle(), $i); // Register worksheet name with parser - - $supbook_index = 0x00; - $ref = pack('vvv', $supbook_index, $i, $i); - $this->_parser->_references[] = $ref; // Register reference with parser - - // Sheet tab colors? - if ($phpSheet->isTabColorSet()) { - $this->_addColor($phpSheet->getTabColor()->getRGB()); - } - } - - } - - /** - * Add a new XF writer - * - * @param PHPExcel_Style - * @param boolean Is it a style XF? - * @return int Index to XF record - */ - public function addXfWriter($style, $isStyleXf = false) - { - $xfWriter = new PHPExcel_Writer_Excel5_Xf($style); - $xfWriter->setIsStyleXf($isStyleXf); - - // Add the font if not already added - $fontIndex = $this->_addFont($style->getFont()); - - // Assign the font index to the xf record - $xfWriter->setFontIndex($fontIndex); - - // Background colors, best to treat these after the font so black will come after white in custom palette - $xfWriter->setFgColor($this->_addColor($style->getFill()->getStartColor()->getRGB())); - $xfWriter->setBgColor($this->_addColor($style->getFill()->getEndColor()->getRGB())); - $xfWriter->setBottomColor($this->_addColor($style->getBorders()->getBottom()->getColor()->getRGB())); - $xfWriter->setTopColor($this->_addColor($style->getBorders()->getTop()->getColor()->getRGB())); - $xfWriter->setRightColor($this->_addColor($style->getBorders()->getRight()->getColor()->getRGB())); - $xfWriter->setLeftColor($this->_addColor($style->getBorders()->getLeft()->getColor()->getRGB())); - $xfWriter->setDiagColor($this->_addColor($style->getBorders()->getDiagonal()->getColor()->getRGB())); - - // Add the number format if it is not a built-in one and not already added - if ($style->getNumberFormat()->getBuiltInFormatCode() === false) { - $numberFormatHashCode = $style->getNumberFormat()->getHashCode(); - - if (isset($this->_addedNumberFormats[$numberFormatHashCode])) { - $numberFormatIndex = $this->_addedNumberFormats[$numberFormatHashCode]; - } else { - $numberFormatIndex = 164 + count($this->_numberFormats); - $this->_numberFormats[$numberFormatIndex] = $style->getNumberFormat(); - $this->_addedNumberFormats[$numberFormatHashCode] = $numberFormatIndex; - } - } else { - $numberFormatIndex = (int) $style->getNumberFormat()->getBuiltInFormatCode(); - } - - // Assign the number format index to xf record - $xfWriter->setNumberFormatIndex($numberFormatIndex); - - $this->_xfWriters[] = $xfWriter; - - $xfIndex = count($this->_xfWriters) - 1; - return $xfIndex; - } - - /** - * Add a font to added fonts - * - * @param PHPExcel_Style_Font $font - * @return int Index to FONT record - */ - public function _addFont(PHPExcel_Style_Font $font) - { - $fontHashCode = $font->getHashCode(); - if(isset($this->_addedFonts[$fontHashCode])){ - $fontIndex = $this->_addedFonts[$fontHashCode]; - } else { - $countFonts = count($this->_fontWriters); - $fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1; - - $fontWriter = new PHPExcel_Writer_Excel5_Font($font); - $fontWriter->setColorIndex($this->_addColor($font->getColor()->getRGB())); - $this->_fontWriters[] = $fontWriter; - - $this->_addedFonts[$fontHashCode] = $fontIndex; - } - return $fontIndex; - } - - /** - * Alter color palette adding a custom color - * - * @param string $rgb E.g. 'FF00AA' - * @return int Color index - */ - private function _addColor($rgb) { - if (!isset($this->_colors[$rgb])) { - if (count($this->_colors) < 57) { - // then we add a custom color altering the palette - $colorIndex = 8 + count($this->_colors); - $this->_palette[$colorIndex] = - array( - hexdec(substr($rgb, 0, 2)), - hexdec(substr($rgb, 2, 2)), - hexdec(substr($rgb, 4)), - 0 - ); - $this->_colors[$rgb] = $colorIndex; - } else { - // no room for more custom colors, just map to black - $colorIndex = 0; - } - } else { - // fetch already added custom color - $colorIndex = $this->_colors[$rgb]; - } - - return $colorIndex; - } - - /** - * Sets the colour palette to the Excel 97+ default. - * - * @access private - */ - function _setPaletteXl97() - { - $this->_palette = array( - 0x08 => array(0x00, 0x00, 0x00, 0x00), - 0x09 => array(0xff, 0xff, 0xff, 0x00), - 0x0A => array(0xff, 0x00, 0x00, 0x00), - 0x0B => array(0x00, 0xff, 0x00, 0x00), - 0x0C => array(0x00, 0x00, 0xff, 0x00), - 0x0D => array(0xff, 0xff, 0x00, 0x00), - 0x0E => array(0xff, 0x00, 0xff, 0x00), - 0x0F => array(0x00, 0xff, 0xff, 0x00), - 0x10 => array(0x80, 0x00, 0x00, 0x00), - 0x11 => array(0x00, 0x80, 0x00, 0x00), - 0x12 => array(0x00, 0x00, 0x80, 0x00), - 0x13 => array(0x80, 0x80, 0x00, 0x00), - 0x14 => array(0x80, 0x00, 0x80, 0x00), - 0x15 => array(0x00, 0x80, 0x80, 0x00), - 0x16 => array(0xc0, 0xc0, 0xc0, 0x00), - 0x17 => array(0x80, 0x80, 0x80, 0x00), - 0x18 => array(0x99, 0x99, 0xff, 0x00), - 0x19 => array(0x99, 0x33, 0x66, 0x00), - 0x1A => array(0xff, 0xff, 0xcc, 0x00), - 0x1B => array(0xcc, 0xff, 0xff, 0x00), - 0x1C => array(0x66, 0x00, 0x66, 0x00), - 0x1D => array(0xff, 0x80, 0x80, 0x00), - 0x1E => array(0x00, 0x66, 0xcc, 0x00), - 0x1F => array(0xcc, 0xcc, 0xff, 0x00), - 0x20 => array(0x00, 0x00, 0x80, 0x00), - 0x21 => array(0xff, 0x00, 0xff, 0x00), - 0x22 => array(0xff, 0xff, 0x00, 0x00), - 0x23 => array(0x00, 0xff, 0xff, 0x00), - 0x24 => array(0x80, 0x00, 0x80, 0x00), - 0x25 => array(0x80, 0x00, 0x00, 0x00), - 0x26 => array(0x00, 0x80, 0x80, 0x00), - 0x27 => array(0x00, 0x00, 0xff, 0x00), - 0x28 => array(0x00, 0xcc, 0xff, 0x00), - 0x29 => array(0xcc, 0xff, 0xff, 0x00), - 0x2A => array(0xcc, 0xff, 0xcc, 0x00), - 0x2B => array(0xff, 0xff, 0x99, 0x00), - 0x2C => array(0x99, 0xcc, 0xff, 0x00), - 0x2D => array(0xff, 0x99, 0xcc, 0x00), - 0x2E => array(0xcc, 0x99, 0xff, 0x00), - 0x2F => array(0xff, 0xcc, 0x99, 0x00), - 0x30 => array(0x33, 0x66, 0xff, 0x00), - 0x31 => array(0x33, 0xcc, 0xcc, 0x00), - 0x32 => array(0x99, 0xcc, 0x00, 0x00), - 0x33 => array(0xff, 0xcc, 0x00, 0x00), - 0x34 => array(0xff, 0x99, 0x00, 0x00), - 0x35 => array(0xff, 0x66, 0x00, 0x00), - 0x36 => array(0x66, 0x66, 0x99, 0x00), - 0x37 => array(0x96, 0x96, 0x96, 0x00), - 0x38 => array(0x00, 0x33, 0x66, 0x00), - 0x39 => array(0x33, 0x99, 0x66, 0x00), - 0x3A => array(0x00, 0x33, 0x00, 0x00), - 0x3B => array(0x33, 0x33, 0x00, 0x00), - 0x3C => array(0x99, 0x33, 0x00, 0x00), - 0x3D => array(0x99, 0x33, 0x66, 0x00), - 0x3E => array(0x33, 0x33, 0x99, 0x00), - 0x3F => array(0x33, 0x33, 0x33, 0x00), - ); - } - - /** - * Assemble worksheets into a workbook and send the BIFF data to an OLE - * storage. - * - * @param array $pWorksheetSizes The sizes in bytes of the binary worksheet streams - * @return string Binary data for workbook stream - */ - public function writeWorkbook($pWorksheetSizes = null) - { - $this->_worksheetSizes = $pWorksheetSizes; - - // Calculate the number of selected worksheet tabs and call the finalization - // methods for each worksheet - $total_worksheets = $this->_phpExcel->getSheetCount(); - - // Add part 1 of the Workbook globals, what goes before the SHEET records - $this->_storeBof(0x0005); - $this->_writeCodepage(); - $this->_writeWindow1(); - - $this->_writeDatemode(); - $this->_writeAllFonts(); - $this->_writeAllNumFormats(); - $this->_writeAllXfs(); - $this->_writeAllStyles(); - $this->_writePalette(); - - // Prepare part 3 of the workbook global stream, what goes after the SHEET records - $part3 = ''; - if ($this->_country_code != -1) { - $part3 .= $this->_writeCountry(); - } - $part3 .= $this->_writeRecalcId(); - - $part3 .= $this->_writeSupbookInternal(); - /* TODO: store external SUPBOOK records and XCT and CRN records - in case of external references for BIFF8 */ - $part3 .= $this->_writeExternsheetBiff8(); - $part3 .= $this->_writeAllDefinedNamesBiff8(); - $part3 .= $this->_writeMsoDrawingGroup(); - $part3 .= $this->_writeSharedStringsTable(); - - $part3 .= $this->writeEof(); - - // Add part 2 of the Workbook globals, the SHEET records - $this->_calcSheetOffsets(); - for ($i = 0; $i < $total_worksheets; ++$i) { - $this->_writeBoundsheet($this->_phpExcel->getSheet($i), $this->_worksheetOffsets[$i]); - } - - // Add part 3 of the Workbook globals - $this->_data .= $part3; - - return $this->_data; - } - - /** - * Calculate offsets for Worksheet BOF records. - * - * @access private - */ - function _calcSheetOffsets() - { - $boundsheet_length = 10; // fixed length for a BOUNDSHEET record - - // size of Workbook globals part 1 + 3 - $offset = $this->_datasize; - - // add size of Workbook globals part 2, the length of the SHEET records - $total_worksheets = count($this->_phpExcel->getAllSheets()); - foreach ($this->_phpExcel->getWorksheetIterator() as $sheet) { - $offset += $boundsheet_length + strlen(PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheet->getTitle())); - } - - // add the sizes of each of the Sheet substreams, respectively - for ($i = 0; $i < $total_worksheets; ++$i) { - $this->_worksheetOffsets[$i] = $offset; - $offset += $this->_worksheetSizes[$i]; - } - $this->_biffsize = $offset; - } - - /** - * Store the Excel FONT records. - */ - private function _writeAllFonts() - { - foreach ($this->_fontWriters as $fontWriter) { - $this->_append($fontWriter->writeFont()); - } - } - - /** - * Store user defined numerical formats i.e. FORMAT records - */ - private function _writeAllNumFormats() - { - foreach ($this->_numberFormats as $numberFormatIndex => $numberFormat) { - $this->_writeNumFormat($numberFormat->getFormatCode(), $numberFormatIndex); - } - } - - /** - * Write all XF records. - */ - private function _writeAllXfs() - { - foreach ($this->_xfWriters as $xfWriter) { - $this->_append($xfWriter->writeXf()); - } - } - - /** - * Write all STYLE records. - */ - private function _writeAllStyles() - { - $this->_writeStyle(); - } - - /** - * Write the EXTERNCOUNT and EXTERNSHEET records. These are used as indexes for - * the NAME records. - */ - private function _writeExterns() - { - $countSheets = $this->_phpExcel->getSheetCount(); - // Create EXTERNCOUNT with number of worksheets - $this->_writeExterncount($countSheets); - - // Create EXTERNSHEET for each worksheet - for ($i = 0; $i < $countSheets; ++$i) { - $this->_writeExternsheet($this->_phpExcel->getSheet($i)->getTitle()); - } - } - - /** - * Write the NAME record to define the print area and the repeat rows and cols. - */ - private function _writeNames() - { - // total number of sheets - $total_worksheets = $this->_phpExcel->getSheetCount(); - - // Create the print area NAME records - for ($i = 0; $i < $total_worksheets; ++$i) { - $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); - // Write a Name record if the print area has been defined - if ($sheetSetup->isPrintAreaSet()) { - // Print area - $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); - $printArea = $printArea[0]; - $printArea[0] = PHPExcel_Cell::coordinateFromString($printArea[0]); - $printArea[1] = PHPExcel_Cell::coordinateFromString($printArea[1]); - - $print_rowmin = $printArea[0][1] - 1; - $print_rowmax = $printArea[1][1] - 1; - $print_colmin = PHPExcel_Cell::columnIndexFromString($printArea[0][0]) - 1; - $print_colmax = PHPExcel_Cell::columnIndexFromString($printArea[1][0]) - 1; - - $this->_writeNameShort( - $i, // sheet index - 0x06, // NAME type - $print_rowmin, - $print_rowmax, - $print_colmin, - $print_colmax - ); - } - } - - // Create the print title NAME records - for ($i = 0; $i < $total_worksheets; ++$i) { - $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); - - // simultaneous repeatColumns repeatRows - if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { - $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); - $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; - $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; - - $repeat = $sheetSetup->getRowsToRepeatAtTop(); - $rowmin = $repeat[0] - 1; - $rowmax = $repeat[1] - 1; - - $this->_writeNameLong( - $i, // sheet index - 0x07, // NAME type - $rowmin, - $rowmax, - $colmin, - $colmax - ); - - // (exclusive) either repeatColumns or repeatRows - } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { - - // Columns to repeat - if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { - $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); - $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; - $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; - } else { - $colmin = 0; - $colmax = 255; - } - - // Rows to repeat - if ($sheetSetup->isRowsToRepeatAtTopSet()) { - $repeat = $sheetSetup->getRowsToRepeatAtTop(); - $rowmin = $repeat[0] - 1; - $rowmax = $repeat[1] - 1; - } else { - $rowmin = 0; - $rowmax = 65535; - } - - $this->_writeNameShort( - $i, // sheet index - 0x07, // NAME type - $rowmin, - $rowmax, - $colmin, - $colmax - ); - } - } - } - - /** - * Writes all the DEFINEDNAME records (BIFF8). - * So far this is only used for repeating rows/columns (print titles) and print areas - */ - private function _writeAllDefinedNamesBiff8() - { - $chunk = ''; - - // Named ranges - if (count($this->_phpExcel->getNamedRanges()) > 0) { - // Loop named ranges - $namedRanges = $this->_phpExcel->getNamedRanges(); - foreach ($namedRanges as $namedRange) { - - // Create absolute coordinate - $range = PHPExcel_Cell::splitRange($namedRange->getRange()); - for ($i = 0; $i < count($range); $i++) { - $range[$i][0] = '\'' . str_replace("'", "''", $namedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteCoordinate($range[$i][0]); - if (isset($range[$i][1])) { - $range[$i][1] = PHPExcel_Cell::absoluteCoordinate($range[$i][1]); - } - } - $range = PHPExcel_Cell::buildRange($range); // e.g. Sheet1!$A$1:$B$2 - - // parse formula - try { - $error = $this->_parser->parse($range); - $formulaData = $this->_parser->toReversePolish(); - - // make sure tRef3d is of type tRef3dR (0x3A) - if (isset($formulaData{0}) and ($formulaData{0} == "\x7A" or $formulaData{0} == "\x5A")) { - $formulaData = "\x3A" . substr($formulaData, 1); - } - - if ($namedRange->getLocalOnly()) { - // local scope - $scope = $this->_phpExcel->getIndex($namedRange->getScope()) + 1; - } else { - // global scope - $scope = 0; - } - $chunk .= $this->writeData($this->_writeDefinedNameBiff8($namedRange->getName(), $formulaData, $scope, false)); - - } catch(PHPExcel_Exception $e) { - // do nothing - } - } - } - - // total number of sheets - $total_worksheets = $this->_phpExcel->getSheetCount(); - - // write the print titles (repeating rows, columns), if any - for ($i = 0; $i < $total_worksheets; ++$i) { - $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); - // simultaneous repeatColumns repeatRows - if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { - $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); - $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; - $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; - - $repeat = $sheetSetup->getRowsToRepeatAtTop(); - $rowmin = $repeat[0] - 1; - $rowmax = $repeat[1] - 1; - - // construct formula data manually - $formulaData = pack('Cv', 0x29, 0x17); // tMemFunc - $formulaData .= pack('Cvvvvv', 0x3B, $i, 0, 65535, $colmin, $colmax); // tArea3d - $formulaData .= pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, 0, 255); // tArea3d - $formulaData .= pack('C', 0x10); // tList - - // store the DEFINEDNAME record - $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); - - // (exclusive) either repeatColumns or repeatRows - } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { - - // Columns to repeat - if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { - $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); - $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; - $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; - } else { - $colmin = 0; - $colmax = 255; - } - // Rows to repeat - if ($sheetSetup->isRowsToRepeatAtTopSet()) { - $repeat = $sheetSetup->getRowsToRepeatAtTop(); - $rowmin = $repeat[0] - 1; - $rowmax = $repeat[1] - 1; - } else { - $rowmin = 0; - $rowmax = 65535; - } - - // construct formula data manually because parser does not recognize absolute 3d cell references - $formulaData = pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, $colmin, $colmax); - - // store the DEFINEDNAME record - $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); - } - } - - // write the print areas, if any - for ($i = 0; $i < $total_worksheets; ++$i) { - $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); - if ($sheetSetup->isPrintAreaSet()) { - // Print area, e.g. A3:J6,H1:X20 - $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); - $countPrintArea = count($printArea); - - $formulaData = ''; - for ($j = 0; $j < $countPrintArea; ++$j) { - $printAreaRect = $printArea[$j]; // e.g. A3:J6 - $printAreaRect[0] = PHPExcel_Cell::coordinateFromString($printAreaRect[0]); - $printAreaRect[1] = PHPExcel_Cell::coordinateFromString($printAreaRect[1]); - - $print_rowmin = $printAreaRect[0][1] - 1; - $print_rowmax = $printAreaRect[1][1] - 1; - $print_colmin = PHPExcel_Cell::columnIndexFromString($printAreaRect[0][0]) - 1; - $print_colmax = PHPExcel_Cell::columnIndexFromString($printAreaRect[1][0]) - 1; - - // construct formula data manually because parser does not recognize absolute 3d cell references - $formulaData .= pack('Cvvvvv', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax); - - if ($j > 0) { - $formulaData .= pack('C', 0x10); // list operator token ',' - } - } - - // store the DEFINEDNAME record - $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true)); - } - } - - // write autofilters, if any - for ($i = 0; $i < $total_worksheets; ++$i) { - $sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter(); - $autoFilterRange = $sheetAutoFilter->getRange(); - if(!empty($autoFilterRange)) { - $rangeBounds = PHPExcel_Cell::rangeBoundaries($autoFilterRange); - - //Autofilter built in name - $name = pack('C', 0x0D); - - $chunk .= $this->writeData($this->_writeShortNameBiff8($name, $i + 1, $rangeBounds, true)); - } - } - - return $chunk; - } - - /** - * Write a DEFINEDNAME record for BIFF8 using explicit binary formula data - * - * @param string $name The name in UTF-8 - * @param string $formulaData The binary formula data - * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global - * @param boolean $isBuiltIn Built-in name? - * @return string Complete binary record data - */ - private function _writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $isBuiltIn = false) - { - $record = 0x0018; - - // option flags - $options = $isBuiltIn ? 0x20 : 0x00; - - // length of the name, character count - $nlen = PHPExcel_Shared_String::CountCharacters($name); - - // name with stripped length field - $name = substr(PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($name), 2); - - // size of the formula (in bytes) - $sz = strlen($formulaData); - - // combine the parts - $data = pack('vCCvvvCCCC', $options, 0, $nlen, $sz, 0, $sheetIndex, 0, 0, 0, 0) - . $name . $formulaData; - $length = strlen($data); - - $header = pack('vv', $record, $length); - - return $header . $data; - } - - /** - * Write a short NAME record - * - * @param string $name - * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global - * @param integer[][] $rangeBounds range boundaries - * @param boolean $isHidden - * @return string Complete binary record data - * */ - private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){ - $record = 0x0018; - - // option flags - $options = ($isHidden ? 0x21 : 0x00); - - $extra = pack('Cvvvvv', - 0x3B, - $sheetIndex - 1, - $rangeBounds[0][1] - 1, - $rangeBounds[1][1] - 1, - $rangeBounds[0][0] - 1, - $rangeBounds[1][0] - 1); - - // size of the formula (in bytes) - $sz = strlen($extra); - - // combine the parts - $data = pack('vCCvvvCCCCC', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0) - . $name . $extra; - $length = strlen($data); - - $header = pack('vv', $record, $length); - - return $header . $data; - } - - /** - * Stores the CODEPAGE biff record. - */ - private function _writeCodepage() - { - $record = 0x0042; // Record identifier - $length = 0x0002; // Number of bytes to follow - $cv = $this->_codepage; // The code page - - $header = pack('vv', $record, $length); - $data = pack('v', $cv); - - $this->_append($header . $data); - } - - /** - * Write Excel BIFF WINDOW1 record. - */ - private function _writeWindow1() - { - $record = 0x003D; // Record identifier - $length = 0x0012; // Number of bytes to follow - - $xWn = 0x0000; // Horizontal position of window - $yWn = 0x0000; // Vertical position of window - $dxWn = 0x25BC; // Width of window - $dyWn = 0x1572; // Height of window - - $grbit = 0x0038; // Option flags - - // not supported by PHPExcel, so there is only one selected sheet, the active - $ctabsel = 1; // Number of workbook tabs selected - - $wTabRatio = 0x0258; // Tab to scrollbar ratio - - // not supported by PHPExcel, set to 0 - $itabFirst = 0; // 1st displayed worksheet - $itabCur = $this->_phpExcel->getActiveSheetIndex(); // Active worksheet - - $header = pack("vv", $record, $length); - $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, - $grbit, - $itabCur, $itabFirst, - $ctabsel, $wTabRatio); - $this->_append($header . $data); - } - - /** - * Writes Excel BIFF BOUNDSHEET record. - * - * @param PHPExcel_Worksheet $sheet Worksheet name - * @param integer $offset Location of worksheet BOF - */ - private function _writeBoundsheet($sheet, $offset) - { - $sheetname = $sheet->getTitle(); - $record = 0x0085; // Record identifier - - // sheet state - switch ($sheet->getSheetState()) { - case PHPExcel_Worksheet::SHEETSTATE_VISIBLE: $ss = 0x00; break; - case PHPExcel_Worksheet::SHEETSTATE_HIDDEN: $ss = 0x01; break; - case PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN: $ss = 0x02; break; - default: $ss = 0x00; break; - } - - // sheet type - $st = 0x00; - - $grbit = 0x0000; // Visibility and sheet type - - $data = pack("VCC", $offset, $ss, $st); - $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheetname); - - $length = strlen($data); - $header = pack("vv", $record, $length); - $this->_append($header . $data); - } - - /** - * Write Internal SUPBOOK record - */ - private function _writeSupbookInternal() - { - $record = 0x01AE; // Record identifier - $length = 0x0004; // Bytes to follow - - $header = pack("vv", $record, $length); - $data = pack("vv", $this->_phpExcel->getSheetCount(), 0x0401); - return $this->writeData($header . $data); - } - - /** - * Writes the Excel BIFF EXTERNSHEET record. These references are used by - * formulas. - * - */ - private function _writeExternsheetBiff8() - { - $total_references = count($this->_parser->_references); - $record = 0x0017; // Record identifier - $length = 2 + 6 * $total_references; // Number of bytes to follow - - $supbook_index = 0; // FIXME: only using internal SUPBOOK record - $header = pack("vv", $record, $length); - $data = pack('v', $total_references); - for ($i = 0; $i < $total_references; ++$i) { - $data .= $this->_parser->_references[$i]; - } - return $this->writeData($header . $data); - } - - /** - * Write Excel BIFF STYLE records. - */ - private function _writeStyle() - { - $record = 0x0293; // Record identifier - $length = 0x0004; // Bytes to follow - - $ixfe = 0x8000; // Index to cell style XF - $BuiltIn = 0x00; // Built-in style - $iLevel = 0xff; // Outline style level - - $header = pack("vv", $record, $length); - $data = pack("vCC", $ixfe, $BuiltIn, $iLevel); - $this->_append($header . $data); - } - - /** - * Writes Excel FORMAT record for non "built-in" numerical formats. - * - * @param string $format Custom format string - * @param integer $ifmt Format index code - */ - private function _writeNumFormat($format, $ifmt) - { - $record = 0x041E; // Record identifier - - $numberFormatString = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($format); - $length = 2 + strlen($numberFormatString); // Number of bytes to follow - - - $header = pack("vv", $record, $length); - $data = pack("v", $ifmt) . $numberFormatString; - $this->_append($header . $data); - } - - /** - * Write DATEMODE record to indicate the date system in use (1904 or 1900). - */ - private function _writeDatemode() - { - $record = 0x0022; // Record identifier - $length = 0x0002; // Bytes to follow - - $f1904 = (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) ? - 1 : 0; // Flag for 1904 date system - - $header = pack("vv", $record, $length); - $data = pack("v", $f1904); - $this->_append($header . $data); - } - - /** - * Write BIFF record EXTERNCOUNT to indicate the number of external sheet - * references in the workbook. - * - * Excel only stores references to external sheets that are used in NAME. - * The workbook NAME record is required to define the print area and the repeat - * rows and columns. - * - * A similar method is used in Worksheet.php for a slightly different purpose. - * - * @param integer $cxals Number of external references - */ - private function _writeExterncount($cxals) - { - $record = 0x0016; // Record identifier - $length = 0x0002; // Number of bytes to follow - - $header = pack("vv", $record, $length); - $data = pack("v", $cxals); - $this->_append($header . $data); - } - - /** - * Writes the Excel BIFF EXTERNSHEET record. These references are used by - * formulas. NAME record is required to define the print area and the repeat - * rows and columns. - * - * A similar method is used in Worksheet.php for a slightly different purpose. - * - * @param string $sheetname Worksheet name - */ - private function _writeExternsheet($sheetname) - { - $record = 0x0017; // Record identifier - $length = 0x02 + strlen($sheetname); // Number of bytes to follow - - $cch = strlen($sheetname); // Length of sheet name - $rgch = 0x03; // Filename encoding - - $header = pack("vv", $record, $length); - $data = pack("CC", $cch, $rgch); - $this->_append($header . $data . $sheetname); - } - - /** - * Store the NAME record in the short format that is used for storing the print - * area, repeat rows only and repeat columns only. - * - * @param integer $index Sheet index - * @param integer $type Built-in name type - * @param integer $rowmin Start row - * @param integer $rowmax End row - * @param integer $colmin Start colum - * @param integer $colmax End column - */ - private function _writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax) - { - $record = 0x0018; // Record identifier - $length = 0x0024; // Number of bytes to follow - - $grbit = 0x0020; // Option flags - $chKey = 0x00; // Keyboard shortcut - $cch = 0x01; // Length of text name - $cce = 0x0015; // Length of text definition - $ixals = $index + 1; // Sheet index - $itab = $ixals; // Equal to ixals - $cchCustMenu = 0x00; // Length of cust menu text - $cchDescription = 0x00; // Length of description text - $cchHelptopic = 0x00; // Length of help topic text - $cchStatustext = 0x00; // Length of status bar text - $rgch = $type; // Built-in name type - - $unknown03 = 0x3b; - $unknown04 = 0xffff-$index; - $unknown05 = 0x0000; - $unknown06 = 0x0000; - $unknown07 = 0x1087; - $unknown08 = 0x8005; - - $header = pack("vv", $record, $length); - $data = pack("v", $grbit); - $data .= pack("C", $chKey); - $data .= pack("C", $cch); - $data .= pack("v", $cce); - $data .= pack("v", $ixals); - $data .= pack("v", $itab); - $data .= pack("C", $cchCustMenu); - $data .= pack("C", $cchDescription); - $data .= pack("C", $cchHelptopic); - $data .= pack("C", $cchStatustext); - $data .= pack("C", $rgch); - $data .= pack("C", $unknown03); - $data .= pack("v", $unknown04); - $data .= pack("v", $unknown05); - $data .= pack("v", $unknown06); - $data .= pack("v", $unknown07); - $data .= pack("v", $unknown08); - $data .= pack("v", $index); - $data .= pack("v", $index); - $data .= pack("v", $rowmin); - $data .= pack("v", $rowmax); - $data .= pack("C", $colmin); - $data .= pack("C", $colmax); - $this->_append($header . $data); - } - - /** - * Store the NAME record in the long format that is used for storing the repeat - * rows and columns when both are specified. This shares a lot of code with - * _writeNameShort() but we use a separate method to keep the code clean. - * Code abstraction for reuse can be carried too far, and I should know. ;-) - * - * @param integer $index Sheet index - * @param integer $type Built-in name type - * @param integer $rowmin Start row - * @param integer $rowmax End row - * @param integer $colmin Start colum - * @param integer $colmax End column - */ - private function _writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colmax) - { - $record = 0x0018; // Record identifier - $length = 0x003d; // Number of bytes to follow - $grbit = 0x0020; // Option flags - $chKey = 0x00; // Keyboard shortcut - $cch = 0x01; // Length of text name - $cce = 0x002e; // Length of text definition - $ixals = $index + 1; // Sheet index - $itab = $ixals; // Equal to ixals - $cchCustMenu = 0x00; // Length of cust menu text - $cchDescription = 0x00; // Length of description text - $cchHelptopic = 0x00; // Length of help topic text - $cchStatustext = 0x00; // Length of status bar text - $rgch = $type; // Built-in name type - - $unknown01 = 0x29; - $unknown02 = 0x002b; - $unknown03 = 0x3b; - $unknown04 = 0xffff-$index; - $unknown05 = 0x0000; - $unknown06 = 0x0000; - $unknown07 = 0x1087; - $unknown08 = 0x8008; - - $header = pack("vv", $record, $length); - $data = pack("v", $grbit); - $data .= pack("C", $chKey); - $data .= pack("C", $cch); - $data .= pack("v", $cce); - $data .= pack("v", $ixals); - $data .= pack("v", $itab); - $data .= pack("C", $cchCustMenu); - $data .= pack("C", $cchDescription); - $data .= pack("C", $cchHelptopic); - $data .= pack("C", $cchStatustext); - $data .= pack("C", $rgch); - $data .= pack("C", $unknown01); - $data .= pack("v", $unknown02); - // Column definition - $data .= pack("C", $unknown03); - $data .= pack("v", $unknown04); - $data .= pack("v", $unknown05); - $data .= pack("v", $unknown06); - $data .= pack("v", $unknown07); - $data .= pack("v", $unknown08); - $data .= pack("v", $index); - $data .= pack("v", $index); - $data .= pack("v", 0x0000); - $data .= pack("v", 0x3fff); - $data .= pack("C", $colmin); - $data .= pack("C", $colmax); - // Row definition - $data .= pack("C", $unknown03); - $data .= pack("v", $unknown04); - $data .= pack("v", $unknown05); - $data .= pack("v", $unknown06); - $data .= pack("v", $unknown07); - $data .= pack("v", $unknown08); - $data .= pack("v", $index); - $data .= pack("v", $index); - $data .= pack("v", $rowmin); - $data .= pack("v", $rowmax); - $data .= pack("C", 0x00); - $data .= pack("C", 0xff); - // End of data - $data .= pack("C", 0x10); - $this->_append($header . $data); - } - - /** - * Stores the COUNTRY record for localization - * - * @return string - */ - private function _writeCountry() - { - $record = 0x008C; // Record identifier - $length = 4; // Number of bytes to follow - - $header = pack('vv', $record, $length); - /* using the same country code always for simplicity */ - $data = pack('vv', $this->_country_code, $this->_country_code); - //$this->_append($header . $data); - return $this->writeData($header . $data); - } - - /** - * Write the RECALCID record - * - * @return string - */ - private function _writeRecalcId() - { - $record = 0x01C1; // Record identifier - $length = 8; // Number of bytes to follow - - $header = pack('vv', $record, $length); - - // by inspection of real Excel files, MS Office Excel 2007 writes this - $data = pack('VV', 0x000001C1, 0x00001E667); - - return $this->writeData($header . $data); - } - - /** - * Stores the PALETTE biff record. - */ - private function _writePalette() - { - $aref = $this->_palette; - - $record = 0x0092; // Record identifier - $length = 2 + 4 * count($aref); // Number of bytes to follow - $ccv = count($aref); // Number of RGB values to follow - $data = ''; // The RGB data - - // Pack the RGB data - foreach ($aref as $color) { - foreach ($color as $byte) { - $data .= pack("C",$byte); - } - } - - $header = pack("vvv", $record, $length, $ccv); - $this->_append($header . $data); - } - - /** - * Handling of the SST continue blocks is complicated by the need to include an - * additional continuation byte depending on whether the string is split between - * blocks or whether it starts at the beginning of the block. (There are also - * additional complications that will arise later when/if Rich Strings are - * supported). - * - * The Excel documentation says that the SST record should be followed by an - * EXTSST record. The EXTSST record is a hash table that is used to optimise - * access to SST. However, despite the documentation it doesn't seem to be - * required so we will ignore it. - * - * @return string Binary data - */ - private function _writeSharedStringsTable() - { - // maximum size of record data (excluding record header) - $continue_limit = 8224; - - // initialize array of record data blocks - $recordDatas = array(); - - // start SST record data block with total number of strings, total number of unique strings - $recordData = pack("VV", $this->_str_total, $this->_str_unique); - - // loop through all (unique) strings in shared strings table - foreach (array_keys($this->_str_table) as $string) { - - // here $string is a BIFF8 encoded string - - // length = character count - $headerinfo = unpack("vlength/Cencoding", $string); - - // currently, this is always 1 = uncompressed - $encoding = $headerinfo["encoding"]; - - // initialize finished writing current $string - $finished = false; - - while ($finished === false) { - - // normally, there will be only one cycle, but if string cannot immediately be written as is - // there will be need for more than one cylcle, if string longer than one record data block, there - // may be need for even more cycles - - if (strlen($recordData) + strlen($string) <= $continue_limit) { - // then we can write the string (or remainder of string) without any problems - $recordData .= $string; - - if (strlen($recordData) + strlen($string) == $continue_limit) { - // we close the record data block, and initialize a new one - $recordDatas[] = $recordData; - $recordData = ''; - } - - // we are finished writing this string - $finished = true; - } else { - // special treatment writing the string (or remainder of the string) - // If the string is very long it may need to be written in more than one CONTINUE record. - - // check how many bytes more there is room for in the current record - $space_remaining = $continue_limit - strlen($recordData); - - // minimum space needed - // uncompressed: 2 byte string length length field + 1 byte option flags + 2 byte character - // compressed: 2 byte string length length field + 1 byte option flags + 1 byte character - $min_space_needed = ($encoding == 1) ? 5 : 4; - - // We have two cases - // 1. space remaining is less than minimum space needed - // here we must waste the space remaining and move to next record data block - // 2. space remaining is greater than or equal to minimum space needed - // here we write as much as we can in the current block, then move to next record data block - - // 1. space remaining is less than minimum space needed - if ($space_remaining < $min_space_needed) { - // we close the block, store the block data - $recordDatas[] = $recordData; - - // and start new record data block where we start writing the string - $recordData = ''; - - // 2. space remaining is greater than or equal to minimum space needed - } else { - // initialize effective remaining space, for Unicode strings this may need to be reduced by 1, see below - $effective_space_remaining = $space_remaining; - - // for uncompressed strings, sometimes effective space remaining is reduced by 1 - if ( $encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1 ) { - --$effective_space_remaining; - } - - // one block fininshed, store the block data - $recordData .= substr($string, 0, $effective_space_remaining); - - $string = substr($string, $effective_space_remaining); // for next cycle in while loop - $recordDatas[] = $recordData; - - // start new record data block with the repeated option flags - $recordData = pack('C', $encoding); - } - } - } - } - - // Store the last record data block unless it is empty - // if there was no need for any continue records, this will be the for SST record data block itself - if (strlen($recordData) > 0) { - $recordDatas[] = $recordData; - } - - // combine into one chunk with all the blocks SST, CONTINUE,... - $chunk = ''; - foreach ($recordDatas as $i => $recordData) { - // first block should have the SST record header, remaing should have CONTINUE header - $record = ($i == 0) ? 0x00FC : 0x003C; - - $header = pack("vv", $record, strlen($recordData)); - $data = $header . $recordData; - - $chunk .= $this->writeData($data); - } - - return $chunk; - } - - /** - * Writes the MSODRAWINGGROUP record if needed. Possibly split using CONTINUE records. - */ - private function _writeMsoDrawingGroup() - { - // write the Escher stream if necessary - if (isset($this->_escher)) { - $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); - $data = $writer->close(); - - $record = 0x00EB; - $length = strlen($data); - $header = pack("vv", $record, $length); - - return $this->writeData($header . $data); - - } else { - return ''; - } - } - - /** - * Get Escher object - * - * @return PHPExcel_Shared_Escher - */ - public function getEscher() - { - return $this->_escher; - } - - /** - * Set Escher object - * - * @param PHPExcel_Shared_Escher $pValue - */ - public function setEscher(PHPExcel_Shared_Escher $pValue = null) - { - $this->_escher = $pValue; - } + /** + * Formula parser + * + * @var PHPExcel_Writer_Excel5_Parser + */ + private $_parser; + + /** + * The BIFF file size for the workbook. + * @var integer + * @see _calcSheetOffsets() + */ + public $_biffsize; + + /** + * XF Writers + * @var PHPExcel_Writer_Excel5_Xf[] + */ + private $_xfWriters = array(); + + /** + * Array containing the colour palette + * @var array + */ + public $_palette; + + /** + * The codepage indicates the text encoding used for strings + * @var integer + */ + public $_codepage; + + /** + * The country code used for localization + * @var integer + */ + public $_country_code; + + /** + * Workbook + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Fonts writers + * + * @var PHPExcel_Writer_Excel5_Font[] + */ + private $_fontWriters = array(); + + /** + * Added fonts. Maps from font's hash => index in workbook + * + * @var array + */ + private $_addedFonts = array(); + + /** + * Shared number formats + * + * @var array + */ + private $_numberFormats = array(); + + /** + * Added number formats. Maps from numberFormat's hash => index in workbook + * + * @var array + */ + private $_addedNumberFormats = array(); + + /** + * Sizes of the binary worksheet streams + * + * @var array + */ + private $_worksheetSizes = array(); + + /** + * Offsets of the binary worksheet streams relative to the start of the global workbook stream + * + * @var array + */ + private $_worksheetOffsets = array(); + + /** + * Total number of shared strings in workbook + * + * @var int + */ + private $_str_total; + + /** + * Number of unique shared strings in workbook + * + * @var int + */ + private $_str_unique; + + /** + * Array of unique shared strings in workbook + * + * @var array + */ + private $_str_table; + + /** + * Color cache + */ + private $_colors; + + /** + * Escher object corresponding to MSODRAWINGGROUP + * + * @var PHPExcel_Shared_Escher + */ + private $_escher; + + + /** + * Class constructor + * + * @param PHPExcel $phpExcel The Workbook + * @param int &$str_total Total number of strings + * @param int &$str_unique Total number of unique strings + * @param array &$str_table String Table + * @param array &$colors Colour Table + * @param mixed $parser The formula parser created for the Workbook + */ + public function __construct(PHPExcel $phpExcel = null, + &$str_total, &$str_unique, &$str_table, &$colors, + $parser ) + { + // It needs to call its parent's constructor explicitly + parent::__construct(); + + $this->_parser = $parser; + $this->_biffsize = 0; + $this->_palette = array(); + $this->_country_code = -1; + + $this->_str_total = &$str_total; + $this->_str_unique = &$str_unique; + $this->_str_table = &$str_table; + $this->_colors = &$colors; + $this->_setPaletteXl97(); + + $this->_phpExcel = $phpExcel; + + // set BIFFwriter limit for CONTINUE records + // $this->_limit = 8224; + $this->_codepage = 0x04B0; + + // Add empty sheets and Build color cache + $countSheets = $phpExcel->getSheetCount(); + for ($i = 0; $i < $countSheets; ++$i) { + $phpSheet = $phpExcel->getSheet($i); + + $this->_parser->setExtSheet($phpSheet->getTitle(), $i); // Register worksheet name with parser + + $supbook_index = 0x00; + $ref = pack('vvv', $supbook_index, $i, $i); + $this->_parser->_references[] = $ref; // Register reference with parser + + // Sheet tab colors? + if ($phpSheet->isTabColorSet()) { + $this->_addColor($phpSheet->getTabColor()->getRGB()); + } + } + + } + + /** + * Add a new XF writer + * + * @param PHPExcel_Style + * @param boolean Is it a style XF? + * @return int Index to XF record + */ + public function addXfWriter($style, $isStyleXf = false) + { + $xfWriter = new PHPExcel_Writer_Excel5_Xf($style); + $xfWriter->setIsStyleXf($isStyleXf); + + // Add the font if not already added + $fontIndex = $this->_addFont($style->getFont()); + + // Assign the font index to the xf record + $xfWriter->setFontIndex($fontIndex); + + // Background colors, best to treat these after the font so black will come after white in custom palette + $xfWriter->setFgColor($this->_addColor($style->getFill()->getStartColor()->getRGB())); + $xfWriter->setBgColor($this->_addColor($style->getFill()->getEndColor()->getRGB())); + $xfWriter->setBottomColor($this->_addColor($style->getBorders()->getBottom()->getColor()->getRGB())); + $xfWriter->setTopColor($this->_addColor($style->getBorders()->getTop()->getColor()->getRGB())); + $xfWriter->setRightColor($this->_addColor($style->getBorders()->getRight()->getColor()->getRGB())); + $xfWriter->setLeftColor($this->_addColor($style->getBorders()->getLeft()->getColor()->getRGB())); + $xfWriter->setDiagColor($this->_addColor($style->getBorders()->getDiagonal()->getColor()->getRGB())); + + // Add the number format if it is not a built-in one and not already added + if ($style->getNumberFormat()->getBuiltInFormatCode() === false) { + $numberFormatHashCode = $style->getNumberFormat()->getHashCode(); + + if (isset($this->_addedNumberFormats[$numberFormatHashCode])) { + $numberFormatIndex = $this->_addedNumberFormats[$numberFormatHashCode]; + } else { + $numberFormatIndex = 164 + count($this->_numberFormats); + $this->_numberFormats[$numberFormatIndex] = $style->getNumberFormat(); + $this->_addedNumberFormats[$numberFormatHashCode] = $numberFormatIndex; + } + } else { + $numberFormatIndex = (int) $style->getNumberFormat()->getBuiltInFormatCode(); + } + + // Assign the number format index to xf record + $xfWriter->setNumberFormatIndex($numberFormatIndex); + + $this->_xfWriters[] = $xfWriter; + + $xfIndex = count($this->_xfWriters) - 1; + return $xfIndex; + } + + /** + * Add a font to added fonts + * + * @param PHPExcel_Style_Font $font + * @return int Index to FONT record + */ + public function _addFont(PHPExcel_Style_Font $font) + { + $fontHashCode = $font->getHashCode(); + if(isset($this->_addedFonts[$fontHashCode])){ + $fontIndex = $this->_addedFonts[$fontHashCode]; + } else { + $countFonts = count($this->_fontWriters); + $fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1; + + $fontWriter = new PHPExcel_Writer_Excel5_Font($font); + $fontWriter->setColorIndex($this->_addColor($font->getColor()->getRGB())); + $this->_fontWriters[] = $fontWriter; + + $this->_addedFonts[$fontHashCode] = $fontIndex; + } + return $fontIndex; + } + + /** + * Alter color palette adding a custom color + * + * @param string $rgb E.g. 'FF00AA' + * @return int Color index + */ + private function _addColor($rgb) { + if (!isset($this->_colors[$rgb])) { + if (count($this->_colors) < 57) { + // then we add a custom color altering the palette + $colorIndex = 8 + count($this->_colors); + $this->_palette[$colorIndex] = + array( + hexdec(substr($rgb, 0, 2)), + hexdec(substr($rgb, 2, 2)), + hexdec(substr($rgb, 4)), + 0 + ); + $this->_colors[$rgb] = $colorIndex; + } else { + // no room for more custom colors, just map to black + $colorIndex = 0; + } + } else { + // fetch already added custom color + $colorIndex = $this->_colors[$rgb]; + } + + return $colorIndex; + } + + /** + * Sets the colour palette to the Excel 97+ default. + * + * @access private + */ + function _setPaletteXl97() + { + $this->_palette = array( + 0x08 => array(0x00, 0x00, 0x00, 0x00), + 0x09 => array(0xff, 0xff, 0xff, 0x00), + 0x0A => array(0xff, 0x00, 0x00, 0x00), + 0x0B => array(0x00, 0xff, 0x00, 0x00), + 0x0C => array(0x00, 0x00, 0xff, 0x00), + 0x0D => array(0xff, 0xff, 0x00, 0x00), + 0x0E => array(0xff, 0x00, 0xff, 0x00), + 0x0F => array(0x00, 0xff, 0xff, 0x00), + 0x10 => array(0x80, 0x00, 0x00, 0x00), + 0x11 => array(0x00, 0x80, 0x00, 0x00), + 0x12 => array(0x00, 0x00, 0x80, 0x00), + 0x13 => array(0x80, 0x80, 0x00, 0x00), + 0x14 => array(0x80, 0x00, 0x80, 0x00), + 0x15 => array(0x00, 0x80, 0x80, 0x00), + 0x16 => array(0xc0, 0xc0, 0xc0, 0x00), + 0x17 => array(0x80, 0x80, 0x80, 0x00), + 0x18 => array(0x99, 0x99, 0xff, 0x00), + 0x19 => array(0x99, 0x33, 0x66, 0x00), + 0x1A => array(0xff, 0xff, 0xcc, 0x00), + 0x1B => array(0xcc, 0xff, 0xff, 0x00), + 0x1C => array(0x66, 0x00, 0x66, 0x00), + 0x1D => array(0xff, 0x80, 0x80, 0x00), + 0x1E => array(0x00, 0x66, 0xcc, 0x00), + 0x1F => array(0xcc, 0xcc, 0xff, 0x00), + 0x20 => array(0x00, 0x00, 0x80, 0x00), + 0x21 => array(0xff, 0x00, 0xff, 0x00), + 0x22 => array(0xff, 0xff, 0x00, 0x00), + 0x23 => array(0x00, 0xff, 0xff, 0x00), + 0x24 => array(0x80, 0x00, 0x80, 0x00), + 0x25 => array(0x80, 0x00, 0x00, 0x00), + 0x26 => array(0x00, 0x80, 0x80, 0x00), + 0x27 => array(0x00, 0x00, 0xff, 0x00), + 0x28 => array(0x00, 0xcc, 0xff, 0x00), + 0x29 => array(0xcc, 0xff, 0xff, 0x00), + 0x2A => array(0xcc, 0xff, 0xcc, 0x00), + 0x2B => array(0xff, 0xff, 0x99, 0x00), + 0x2C => array(0x99, 0xcc, 0xff, 0x00), + 0x2D => array(0xff, 0x99, 0xcc, 0x00), + 0x2E => array(0xcc, 0x99, 0xff, 0x00), + 0x2F => array(0xff, 0xcc, 0x99, 0x00), + 0x30 => array(0x33, 0x66, 0xff, 0x00), + 0x31 => array(0x33, 0xcc, 0xcc, 0x00), + 0x32 => array(0x99, 0xcc, 0x00, 0x00), + 0x33 => array(0xff, 0xcc, 0x00, 0x00), + 0x34 => array(0xff, 0x99, 0x00, 0x00), + 0x35 => array(0xff, 0x66, 0x00, 0x00), + 0x36 => array(0x66, 0x66, 0x99, 0x00), + 0x37 => array(0x96, 0x96, 0x96, 0x00), + 0x38 => array(0x00, 0x33, 0x66, 0x00), + 0x39 => array(0x33, 0x99, 0x66, 0x00), + 0x3A => array(0x00, 0x33, 0x00, 0x00), + 0x3B => array(0x33, 0x33, 0x00, 0x00), + 0x3C => array(0x99, 0x33, 0x00, 0x00), + 0x3D => array(0x99, 0x33, 0x66, 0x00), + 0x3E => array(0x33, 0x33, 0x99, 0x00), + 0x3F => array(0x33, 0x33, 0x33, 0x00), + ); + } + + /** + * Assemble worksheets into a workbook and send the BIFF data to an OLE + * storage. + * + * @param array $pWorksheetSizes The sizes in bytes of the binary worksheet streams + * @return string Binary data for workbook stream + */ + public function writeWorkbook($pWorksheetSizes = null) + { + $this->_worksheetSizes = $pWorksheetSizes; + + // Calculate the number of selected worksheet tabs and call the finalization + // methods for each worksheet + $total_worksheets = $this->_phpExcel->getSheetCount(); + + // Add part 1 of the Workbook globals, what goes before the SHEET records + $this->_storeBof(0x0005); + $this->_writeCodepage(); + $this->_writeWindow1(); + + $this->_writeDatemode(); + $this->_writeAllFonts(); + $this->_writeAllNumFormats(); + $this->_writeAllXfs(); + $this->_writeAllStyles(); + $this->_writePalette(); + + // Prepare part 3 of the workbook global stream, what goes after the SHEET records + $part3 = ''; + if ($this->_country_code != -1) { + $part3 .= $this->_writeCountry(); + } + $part3 .= $this->_writeRecalcId(); + + $part3 .= $this->_writeSupbookInternal(); + /* TODO: store external SUPBOOK records and XCT and CRN records + in case of external references for BIFF8 */ + $part3 .= $this->_writeExternsheetBiff8(); + $part3 .= $this->_writeAllDefinedNamesBiff8(); + $part3 .= $this->_writeMsoDrawingGroup(); + $part3 .= $this->_writeSharedStringsTable(); + + $part3 .= $this->writeEof(); + + // Add part 2 of the Workbook globals, the SHEET records + $this->_calcSheetOffsets(); + for ($i = 0; $i < $total_worksheets; ++$i) { + $this->_writeBoundsheet($this->_phpExcel->getSheet($i), $this->_worksheetOffsets[$i]); + } + + // Add part 3 of the Workbook globals + $this->_data .= $part3; + + return $this->_data; + } + + /** + * Calculate offsets for Worksheet BOF records. + * + * @access private + */ + function _calcSheetOffsets() + { + $boundsheet_length = 10; // fixed length for a BOUNDSHEET record + + // size of Workbook globals part 1 + 3 + $offset = $this->_datasize; + + // add size of Workbook globals part 2, the length of the SHEET records + $total_worksheets = count($this->_phpExcel->getAllSheets()); + foreach ($this->_phpExcel->getWorksheetIterator() as $sheet) { + $offset += $boundsheet_length + strlen(PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheet->getTitle())); + } + + // add the sizes of each of the Sheet substreams, respectively + for ($i = 0; $i < $total_worksheets; ++$i) { + $this->_worksheetOffsets[$i] = $offset; + $offset += $this->_worksheetSizes[$i]; + } + $this->_biffsize = $offset; + } + + /** + * Store the Excel FONT records. + */ + private function _writeAllFonts() + { + foreach ($this->_fontWriters as $fontWriter) { + $this->_append($fontWriter->writeFont()); + } + } + + /** + * Store user defined numerical formats i.e. FORMAT records + */ + private function _writeAllNumFormats() + { + foreach ($this->_numberFormats as $numberFormatIndex => $numberFormat) { + $this->_writeNumFormat($numberFormat->getFormatCode(), $numberFormatIndex); + } + } + + /** + * Write all XF records. + */ + private function _writeAllXfs() + { + foreach ($this->_xfWriters as $xfWriter) { + $this->_append($xfWriter->writeXf()); + } + } + + /** + * Write all STYLE records. + */ + private function _writeAllStyles() + { + $this->_writeStyle(); + } + + /** + * Write the EXTERNCOUNT and EXTERNSHEET records. These are used as indexes for + * the NAME records. + */ + private function _writeExterns() + { + $countSheets = $this->_phpExcel->getSheetCount(); + // Create EXTERNCOUNT with number of worksheets + $this->_writeExterncount($countSheets); + + // Create EXTERNSHEET for each worksheet + for ($i = 0; $i < $countSheets; ++$i) { + $this->_writeExternsheet($this->_phpExcel->getSheet($i)->getTitle()); + } + } + + /** + * Write the NAME record to define the print area and the repeat rows and cols. + */ + private function _writeNames() + { + // total number of sheets + $total_worksheets = $this->_phpExcel->getSheetCount(); + + // Create the print area NAME records + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + // Write a Name record if the print area has been defined + if ($sheetSetup->isPrintAreaSet()) { + // Print area + $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); + $printArea = $printArea[0]; + $printArea[0] = PHPExcel_Cell::coordinateFromString($printArea[0]); + $printArea[1] = PHPExcel_Cell::coordinateFromString($printArea[1]); + + $print_rowmin = $printArea[0][1] - 1; + $print_rowmax = $printArea[1][1] - 1; + $print_colmin = PHPExcel_Cell::columnIndexFromString($printArea[0][0]) - 1; + $print_colmax = PHPExcel_Cell::columnIndexFromString($printArea[1][0]) - 1; + + $this->_writeNameShort( + $i, // sheet index + 0x06, // NAME type + $print_rowmin, + $print_rowmax, + $print_colmin, + $print_colmax + ); + } + } + + // Create the print title NAME records + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + + // simultaneous repeatColumns repeatRows + if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + + $this->_writeNameLong( + $i, // sheet index + 0x07, // NAME type + $rowmin, + $rowmax, + $colmin, + $colmax + ); + + // (exclusive) either repeatColumns or repeatRows + } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { + + // Columns to repeat + if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + } else { + $colmin = 0; + $colmax = 255; + } + + // Rows to repeat + if ($sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + } else { + $rowmin = 0; + $rowmax = 65535; + } + + $this->_writeNameShort( + $i, // sheet index + 0x07, // NAME type + $rowmin, + $rowmax, + $colmin, + $colmax + ); + } + } + } + + /** + * Writes all the DEFINEDNAME records (BIFF8). + * So far this is only used for repeating rows/columns (print titles) and print areas + */ + private function _writeAllDefinedNamesBiff8() + { + $chunk = ''; + + // Named ranges + if (count($this->_phpExcel->getNamedRanges()) > 0) { + // Loop named ranges + $namedRanges = $this->_phpExcel->getNamedRanges(); + foreach ($namedRanges as $namedRange) { + + // Create absolute coordinate + $range = PHPExcel_Cell::splitRange($namedRange->getRange()); + for ($i = 0; $i < count($range); $i++) { + $range[$i][0] = '\'' . str_replace("'", "''", $namedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteCoordinate($range[$i][0]); + if (isset($range[$i][1])) { + $range[$i][1] = PHPExcel_Cell::absoluteCoordinate($range[$i][1]); + } + } + $range = PHPExcel_Cell::buildRange($range); // e.g. Sheet1!$A$1:$B$2 + + // parse formula + try { + $error = $this->_parser->parse($range); + $formulaData = $this->_parser->toReversePolish(); + + // make sure tRef3d is of type tRef3dR (0x3A) + if (isset($formulaData{0}) and ($formulaData{0} == "\x7A" or $formulaData{0} == "\x5A")) { + $formulaData = "\x3A" . substr($formulaData, 1); + } + + if ($namedRange->getLocalOnly()) { + // local scope + $scope = $this->_phpExcel->getIndex($namedRange->getScope()) + 1; + } else { + // global scope + $scope = 0; + } + $chunk .= $this->writeData($this->_writeDefinedNameBiff8($namedRange->getName(), $formulaData, $scope, false)); + + } catch(PHPExcel_Exception $e) { + // do nothing + } + } + } + + // total number of sheets + $total_worksheets = $this->_phpExcel->getSheetCount(); + + // write the print titles (repeating rows, columns), if any + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + // simultaneous repeatColumns repeatRows + if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + + // construct formula data manually + $formulaData = pack('Cv', 0x29, 0x17); // tMemFunc + $formulaData .= pack('Cvvvvv', 0x3B, $i, 0, 65535, $colmin, $colmax); // tArea3d + $formulaData .= pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, 0, 255); // tArea3d + $formulaData .= pack('C', 0x10); // tList + + // store the DEFINEDNAME record + $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); + + // (exclusive) either repeatColumns or repeatRows + } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { + + // Columns to repeat + if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + } else { + $colmin = 0; + $colmax = 255; + } + // Rows to repeat + if ($sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + } else { + $rowmin = 0; + $rowmax = 65535; + } + + // construct formula data manually because parser does not recognize absolute 3d cell references + $formulaData = pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, $colmin, $colmax); + + // store the DEFINEDNAME record + $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); + } + } + + // write the print areas, if any + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + if ($sheetSetup->isPrintAreaSet()) { + // Print area, e.g. A3:J6,H1:X20 + $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); + $countPrintArea = count($printArea); + + $formulaData = ''; + for ($j = 0; $j < $countPrintArea; ++$j) { + $printAreaRect = $printArea[$j]; // e.g. A3:J6 + $printAreaRect[0] = PHPExcel_Cell::coordinateFromString($printAreaRect[0]); + $printAreaRect[1] = PHPExcel_Cell::coordinateFromString($printAreaRect[1]); + + $print_rowmin = $printAreaRect[0][1] - 1; + $print_rowmax = $printAreaRect[1][1] - 1; + $print_colmin = PHPExcel_Cell::columnIndexFromString($printAreaRect[0][0]) - 1; + $print_colmax = PHPExcel_Cell::columnIndexFromString($printAreaRect[1][0]) - 1; + + // construct formula data manually because parser does not recognize absolute 3d cell references + $formulaData .= pack('Cvvvvv', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax); + + if ($j > 0) { + $formulaData .= pack('C', 0x10); // list operator token ',' + } + } + + // store the DEFINEDNAME record + $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true)); + } + } + + // write autofilters, if any + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter(); + $autoFilterRange = $sheetAutoFilter->getRange(); + if(!empty($autoFilterRange)) { + $rangeBounds = PHPExcel_Cell::rangeBoundaries($autoFilterRange); + + //Autofilter built in name + $name = pack('C', 0x0D); + + $chunk .= $this->writeData($this->_writeShortNameBiff8($name, $i + 1, $rangeBounds, true)); + } + } + + return $chunk; + } + + /** + * Write a DEFINEDNAME record for BIFF8 using explicit binary formula data + * + * @param string $name The name in UTF-8 + * @param string $formulaData The binary formula data + * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global + * @param boolean $isBuiltIn Built-in name? + * @return string Complete binary record data + */ + private function _writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $isBuiltIn = false) + { + $record = 0x0018; + + // option flags + $options = $isBuiltIn ? 0x20 : 0x00; + + // length of the name, character count + $nlen = PHPExcel_Shared_String::CountCharacters($name); + + // name with stripped length field + $name = substr(PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($name), 2); + + // size of the formula (in bytes) + $sz = strlen($formulaData); + + // combine the parts + $data = pack('vCCvvvCCCC', $options, 0, $nlen, $sz, 0, $sheetIndex, 0, 0, 0, 0) + . $name . $formulaData; + $length = strlen($data); + + $header = pack('vv', $record, $length); + + return $header . $data; + } + + /** + * Write a short NAME record + * + * @param string $name + * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global + * @param integer[][] $rangeBounds range boundaries + * @param boolean $isHidden + * @return string Complete binary record data + * */ + private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){ + $record = 0x0018; + + // option flags + $options = ($isHidden ? 0x21 : 0x00); + + $extra = pack('Cvvvvv', + 0x3B, + $sheetIndex - 1, + $rangeBounds[0][1] - 1, + $rangeBounds[1][1] - 1, + $rangeBounds[0][0] - 1, + $rangeBounds[1][0] - 1); + + // size of the formula (in bytes) + $sz = strlen($extra); + + // combine the parts + $data = pack('vCCvvvCCCCC', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0) + . $name . $extra; + $length = strlen($data); + + $header = pack('vv', $record, $length); + + return $header . $data; + } + + /** + * Stores the CODEPAGE biff record. + */ + private function _writeCodepage() + { + $record = 0x0042; // Record identifier + $length = 0x0002; // Number of bytes to follow + $cv = $this->_codepage; // The code page + + $header = pack('vv', $record, $length); + $data = pack('v', $cv); + + $this->_append($header . $data); + } + + /** + * Write Excel BIFF WINDOW1 record. + */ + private function _writeWindow1() + { + $record = 0x003D; // Record identifier + $length = 0x0012; // Number of bytes to follow + + $xWn = 0x0000; // Horizontal position of window + $yWn = 0x0000; // Vertical position of window + $dxWn = 0x25BC; // Width of window + $dyWn = 0x1572; // Height of window + + $grbit = 0x0038; // Option flags + + // not supported by PHPExcel, so there is only one selected sheet, the active + $ctabsel = 1; // Number of workbook tabs selected + + $wTabRatio = 0x0258; // Tab to scrollbar ratio + + // not supported by PHPExcel, set to 0 + $itabFirst = 0; // 1st displayed worksheet + $itabCur = $this->_phpExcel->getActiveSheetIndex(); // Active worksheet + + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, + $grbit, + $itabCur, $itabFirst, + $ctabsel, $wTabRatio); + $this->_append($header . $data); + } + + /** + * Writes Excel BIFF BOUNDSHEET record. + * + * @param PHPExcel_Worksheet $sheet Worksheet name + * @param integer $offset Location of worksheet BOF + */ + private function _writeBoundsheet($sheet, $offset) + { + $sheetname = $sheet->getTitle(); + $record = 0x0085; // Record identifier + + // sheet state + switch ($sheet->getSheetState()) { + case PHPExcel_Worksheet::SHEETSTATE_VISIBLE: $ss = 0x00; break; + case PHPExcel_Worksheet::SHEETSTATE_HIDDEN: $ss = 0x01; break; + case PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN: $ss = 0x02; break; + default: $ss = 0x00; break; + } + + // sheet type + $st = 0x00; + + $grbit = 0x0000; // Visibility and sheet type + + $data = pack("VCC", $offset, $ss, $st); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheetname); + + $length = strlen($data); + $header = pack("vv", $record, $length); + $this->_append($header . $data); + } + + /** + * Write Internal SUPBOOK record + */ + private function _writeSupbookInternal() + { + $record = 0x01AE; // Record identifier + $length = 0x0004; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", $this->_phpExcel->getSheetCount(), 0x0401); + return $this->writeData($header . $data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. + * + */ + private function _writeExternsheetBiff8() + { + $total_references = count($this->_parser->_references); + $record = 0x0017; // Record identifier + $length = 2 + 6 * $total_references; // Number of bytes to follow + + $supbook_index = 0; // FIXME: only using internal SUPBOOK record + $header = pack("vv", $record, $length); + $data = pack('v', $total_references); + for ($i = 0; $i < $total_references; ++$i) { + $data .= $this->_parser->_references[$i]; + } + return $this->writeData($header . $data); + } + + /** + * Write Excel BIFF STYLE records. + */ + private function _writeStyle() + { + $record = 0x0293; // Record identifier + $length = 0x0004; // Bytes to follow + + $ixfe = 0x8000; // Index to cell style XF + $BuiltIn = 0x00; // Built-in style + $iLevel = 0xff; // Outline style level + + $header = pack("vv", $record, $length); + $data = pack("vCC", $ixfe, $BuiltIn, $iLevel); + $this->_append($header . $data); + } + + /** + * Writes Excel FORMAT record for non "built-in" numerical formats. + * + * @param string $format Custom format string + * @param integer $ifmt Format index code + */ + private function _writeNumFormat($format, $ifmt) + { + $record = 0x041E; // Record identifier + + $numberFormatString = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($format); + $length = 2 + strlen($numberFormatString); // Number of bytes to follow + + + $header = pack("vv", $record, $length); + $data = pack("v", $ifmt) . $numberFormatString; + $this->_append($header . $data); + } + + /** + * Write DATEMODE record to indicate the date system in use (1904 or 1900). + */ + private function _writeDatemode() + { + $record = 0x0022; // Record identifier + $length = 0x0002; // Bytes to follow + + $f1904 = (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) ? + 1 : 0; // Flag for 1904 date system + + $header = pack("vv", $record, $length); + $data = pack("v", $f1904); + $this->_append($header . $data); + } + + /** + * Write BIFF record EXTERNCOUNT to indicate the number of external sheet + * references in the workbook. + * + * Excel only stores references to external sheets that are used in NAME. + * The workbook NAME record is required to define the print area and the repeat + * rows and columns. + * + * A similar method is used in Worksheet.php for a slightly different purpose. + * + * @param integer $cxals Number of external references + */ + private function _writeExterncount($cxals) + { + $record = 0x0016; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cxals); + $this->_append($header . $data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. NAME record is required to define the print area and the repeat + * rows and columns. + * + * A similar method is used in Worksheet.php for a slightly different purpose. + * + * @param string $sheetname Worksheet name + */ + private function _writeExternsheet($sheetname) + { + $record = 0x0017; // Record identifier + $length = 0x02 + strlen($sheetname); // Number of bytes to follow + + $cch = strlen($sheetname); // Length of sheet name + $rgch = 0x03; // Filename encoding + + $header = pack("vv", $record, $length); + $data = pack("CC", $cch, $rgch); + $this->_append($header . $data . $sheetname); + } + + /** + * Store the NAME record in the short format that is used for storing the print + * area, repeat rows only and repeat columns only. + * + * @param integer $index Sheet index + * @param integer $type Built-in name type + * @param integer $rowmin Start row + * @param integer $rowmax End row + * @param integer $colmin Start colum + * @param integer $colmax End column + */ + private function _writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax) + { + $record = 0x0018; // Record identifier + $length = 0x0024; // Number of bytes to follow + + $grbit = 0x0020; // Option flags + $chKey = 0x00; // Keyboard shortcut + $cch = 0x01; // Length of text name + $cce = 0x0015; // Length of text definition + $ixals = $index + 1; // Sheet index + $itab = $ixals; // Equal to ixals + $cchCustMenu = 0x00; // Length of cust menu text + $cchDescription = 0x00; // Length of description text + $cchHelptopic = 0x00; // Length of help topic text + $cchStatustext = 0x00; // Length of status bar text + $rgch = $type; // Built-in name type + + $unknown03 = 0x3b; + $unknown04 = 0xffff-$index; + $unknown05 = 0x0000; + $unknown06 = 0x0000; + $unknown07 = 0x1087; + $unknown08 = 0x8005; + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $data .= pack("C", $chKey); + $data .= pack("C", $cch); + $data .= pack("v", $cce); + $data .= pack("v", $ixals); + $data .= pack("v", $itab); + $data .= pack("C", $cchCustMenu); + $data .= pack("C", $cchDescription); + $data .= pack("C", $cchHelptopic); + $data .= pack("C", $cchStatustext); + $data .= pack("C", $rgch); + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", $rowmin); + $data .= pack("v", $rowmax); + $data .= pack("C", $colmin); + $data .= pack("C", $colmax); + $this->_append($header . $data); + } + + /** + * Store the NAME record in the long format that is used for storing the repeat + * rows and columns when both are specified. This shares a lot of code with + * _writeNameShort() but we use a separate method to keep the code clean. + * Code abstraction for reuse can be carried too far, and I should know. ;-) + * + * @param integer $index Sheet index + * @param integer $type Built-in name type + * @param integer $rowmin Start row + * @param integer $rowmax End row + * @param integer $colmin Start colum + * @param integer $colmax End column + */ + private function _writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colmax) + { + $record = 0x0018; // Record identifier + $length = 0x003d; // Number of bytes to follow + $grbit = 0x0020; // Option flags + $chKey = 0x00; // Keyboard shortcut + $cch = 0x01; // Length of text name + $cce = 0x002e; // Length of text definition + $ixals = $index + 1; // Sheet index + $itab = $ixals; // Equal to ixals + $cchCustMenu = 0x00; // Length of cust menu text + $cchDescription = 0x00; // Length of description text + $cchHelptopic = 0x00; // Length of help topic text + $cchStatustext = 0x00; // Length of status bar text + $rgch = $type; // Built-in name type + + $unknown01 = 0x29; + $unknown02 = 0x002b; + $unknown03 = 0x3b; + $unknown04 = 0xffff-$index; + $unknown05 = 0x0000; + $unknown06 = 0x0000; + $unknown07 = 0x1087; + $unknown08 = 0x8008; + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $data .= pack("C", $chKey); + $data .= pack("C", $cch); + $data .= pack("v", $cce); + $data .= pack("v", $ixals); + $data .= pack("v", $itab); + $data .= pack("C", $cchCustMenu); + $data .= pack("C", $cchDescription); + $data .= pack("C", $cchHelptopic); + $data .= pack("C", $cchStatustext); + $data .= pack("C", $rgch); + $data .= pack("C", $unknown01); + $data .= pack("v", $unknown02); + // Column definition + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", 0x0000); + $data .= pack("v", 0x3fff); + $data .= pack("C", $colmin); + $data .= pack("C", $colmax); + // Row definition + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", $rowmin); + $data .= pack("v", $rowmax); + $data .= pack("C", 0x00); + $data .= pack("C", 0xff); + // End of data + $data .= pack("C", 0x10); + $this->_append($header . $data); + } + + /** + * Stores the COUNTRY record for localization + * + * @return string + */ + private function _writeCountry() + { + $record = 0x008C; // Record identifier + $length = 4; // Number of bytes to follow + + $header = pack('vv', $record, $length); + /* using the same country code always for simplicity */ + $data = pack('vv', $this->_country_code, $this->_country_code); + //$this->_append($header . $data); + return $this->writeData($header . $data); + } + + /** + * Write the RECALCID record + * + * @return string + */ + private function _writeRecalcId() + { + $record = 0x01C1; // Record identifier + $length = 8; // Number of bytes to follow + + $header = pack('vv', $record, $length); + + // by inspection of real Excel files, MS Office Excel 2007 writes this + $data = pack('VV', 0x000001C1, 0x00001E667); + + return $this->writeData($header . $data); + } + + /** + * Stores the PALETTE biff record. + */ + private function _writePalette() + { + $aref = $this->_palette; + + $record = 0x0092; // Record identifier + $length = 2 + 4 * count($aref); // Number of bytes to follow + $ccv = count($aref); // Number of RGB values to follow + $data = ''; // The RGB data + + // Pack the RGB data + foreach ($aref as $color) { + foreach ($color as $byte) { + $data .= pack("C",$byte); + } + } + + $header = pack("vvv", $record, $length, $ccv); + $this->_append($header . $data); + } + + /** + * Handling of the SST continue blocks is complicated by the need to include an + * additional continuation byte depending on whether the string is split between + * blocks or whether it starts at the beginning of the block. (There are also + * additional complications that will arise later when/if Rich Strings are + * supported). + * + * The Excel documentation says that the SST record should be followed by an + * EXTSST record. The EXTSST record is a hash table that is used to optimise + * access to SST. However, despite the documentation it doesn't seem to be + * required so we will ignore it. + * + * @return string Binary data + */ + private function _writeSharedStringsTable() + { + // maximum size of record data (excluding record header) + $continue_limit = 8224; + + // initialize array of record data blocks + $recordDatas = array(); + + // start SST record data block with total number of strings, total number of unique strings + $recordData = pack("VV", $this->_str_total, $this->_str_unique); + + // loop through all (unique) strings in shared strings table + foreach (array_keys($this->_str_table) as $string) { + + // here $string is a BIFF8 encoded string + + // length = character count + $headerinfo = unpack("vlength/Cencoding", $string); + + // currently, this is always 1 = uncompressed + $encoding = $headerinfo["encoding"]; + + // initialize finished writing current $string + $finished = false; + + while ($finished === false) { + + // normally, there will be only one cycle, but if string cannot immediately be written as is + // there will be need for more than one cylcle, if string longer than one record data block, there + // may be need for even more cycles + + if (strlen($recordData) + strlen($string) <= $continue_limit) { + // then we can write the string (or remainder of string) without any problems + $recordData .= $string; + + if (strlen($recordData) + strlen($string) == $continue_limit) { + // we close the record data block, and initialize a new one + $recordDatas[] = $recordData; + $recordData = ''; + } + + // we are finished writing this string + $finished = true; + } else { + // special treatment writing the string (or remainder of the string) + // If the string is very long it may need to be written in more than one CONTINUE record. + + // check how many bytes more there is room for in the current record + $space_remaining = $continue_limit - strlen($recordData); + + // minimum space needed + // uncompressed: 2 byte string length length field + 1 byte option flags + 2 byte character + // compressed: 2 byte string length length field + 1 byte option flags + 1 byte character + $min_space_needed = ($encoding == 1) ? 5 : 4; + + // We have two cases + // 1. space remaining is less than minimum space needed + // here we must waste the space remaining and move to next record data block + // 2. space remaining is greater than or equal to minimum space needed + // here we write as much as we can in the current block, then move to next record data block + + // 1. space remaining is less than minimum space needed + if ($space_remaining < $min_space_needed) { + // we close the block, store the block data + $recordDatas[] = $recordData; + + // and start new record data block where we start writing the string + $recordData = ''; + + // 2. space remaining is greater than or equal to minimum space needed + } else { + // initialize effective remaining space, for Unicode strings this may need to be reduced by 1, see below + $effective_space_remaining = $space_remaining; + + // for uncompressed strings, sometimes effective space remaining is reduced by 1 + if ( $encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1 ) { + --$effective_space_remaining; + } + + // one block fininshed, store the block data + $recordData .= substr($string, 0, $effective_space_remaining); + + $string = substr($string, $effective_space_remaining); // for next cycle in while loop + $recordDatas[] = $recordData; + + // start new record data block with the repeated option flags + $recordData = pack('C', $encoding); + } + } + } + } + + // Store the last record data block unless it is empty + // if there was no need for any continue records, this will be the for SST record data block itself + if (strlen($recordData) > 0) { + $recordDatas[] = $recordData; + } + + // combine into one chunk with all the blocks SST, CONTINUE,... + $chunk = ''; + foreach ($recordDatas as $i => $recordData) { + // first block should have the SST record header, remaing should have CONTINUE header + $record = ($i == 0) ? 0x00FC : 0x003C; + + $header = pack("vv", $record, strlen($recordData)); + $data = $header . $recordData; + + $chunk .= $this->writeData($data); + } + + return $chunk; + } + + /** + * Writes the MSODRAWINGGROUP record if needed. Possibly split using CONTINUE records. + */ + private function _writeMsoDrawingGroup() + { + // write the Escher stream if necessary + if (isset($this->_escher)) { + $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); + $data = $writer->close(); + + $record = 0x00EB; + $length = strlen($data); + $header = pack("vv", $record, $length); + + return $this->writeData($header . $data); + + } else { + return ''; + } + } + + /** + * Get Escher object + * + * @return PHPExcel_Shared_Escher + */ + public function getEscher() + { + return $this->_escher; + } + + /** + * Set Escher object + * + * @param PHPExcel_Shared_Escher $pValue + */ + public function setEscher(PHPExcel_Shared_Escher $pValue = null) + { + $this->_escher = $pValue; + } } diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index f73ac35a4..f869abde7 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -70,3612 +70,3612 @@ */ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter { - /** - * Formula parser - * - * @var PHPExcel_Writer_Excel5_Parser - */ - private $_parser; - - /** - * Maximum number of characters for a string (LABEL record in BIFF5) - * @var integer - */ - public $_xls_strmax; - - /** - * Array containing format information for columns - * @var array - */ - public $_colinfo; - - /** - * Array containing the selected area for the worksheet - * @var array - */ - public $_selection; - - /** - * The active pane for the worksheet - * @var integer - */ - public $_active_pane; - - /** - * Whether to use outline. - * @var integer - */ - public $_outline_on; - - /** - * Auto outline styles. - * @var bool - */ - public $_outline_style; - - /** - * Whether to have outline summary below. - * @var bool - */ - public $_outline_below; - - /** - * Whether to have outline summary at the right. - * @var bool - */ - public $_outline_right; - - /** - * Reference to the total number of strings in the workbook - * @var integer - */ - public $_str_total; - - /** - * Reference to the number of unique strings in the workbook - * @var integer - */ - public $_str_unique; - - /** - * Reference to the array containing all the unique strings in the workbook - * @var array - */ - public $_str_table; - - /** - * Color cache - */ - private $_colors; - - /** - * Index of first used row (at least 0) - * @var int - */ - private $_firstRowIndex; - - /** - * Index of last used row. (no used rows means -1) - * @var int - */ - private $_lastRowIndex; - - /** - * Index of first used column (at least 0) - * @var int - */ - private $_firstColumnIndex; - - /** - * Index of last used column (no used columns means -1) - * @var int - */ - private $_lastColumnIndex; - - /** - * Sheet object - * @var PHPExcel_Worksheet - */ - public $_phpSheet; - - /** - * Count cell style Xfs - * - * @var int - */ - private $_countCellStyleXfs; - - /** - * Escher object corresponding to MSODRAWING - * - * @var PHPExcel_Shared_Escher - */ - private $_escher; - - /** - * Array of font hashes associated to FONT records index - * - * @var array - */ - public $_fntHashIndex; - - /** - * Constructor - * - * @param int &$str_total Total number of strings - * @param int &$str_unique Total number of unique strings - * @param array &$str_table String Table - * @param array &$colors Colour Table - * @param mixed $parser The formula parser created for the Workbook - * @param boolean $preCalculateFormulas Flag indicating whether formulas should be calculated or just written - * @param string $phpSheet The worksheet to write - * @param PHPExcel_Worksheet $phpSheet - */ - public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, - $parser, $preCalculateFormulas, $phpSheet) - { - // It needs to call its parent's constructor explicitly - parent::__construct(); - - // change BIFFwriter limit for CONTINUE records -// $this->_limit = 8224; - - - $this->_preCalculateFormulas = $preCalculateFormulas; - $this->_str_total = &$str_total; - $this->_str_unique = &$str_unique; - $this->_str_table = &$str_table; - $this->_colors = &$colors; - $this->_parser = $parser; - - $this->_phpSheet = $phpSheet; - - //$this->ext_sheets = array(); - //$this->offset = 0; - $this->_xls_strmax = 255; - $this->_colinfo = array(); - $this->_selection = array(0,0,0,0); - $this->_active_pane = 3; - - $this->_print_headers = 0; - - $this->_outline_style = 0; - $this->_outline_below = 1; - $this->_outline_right = 1; - $this->_outline_on = 1; - - $this->_fntHashIndex = array(); - - // calculate values for DIMENSIONS record - $minR = 1; - $minC = 'A'; - - $maxR = $this->_phpSheet->getHighestRow(); - $maxC = $this->_phpSheet->getHighestColumn(); - - // Determine lowest and highest column and row -// $this->_firstRowIndex = ($minR > 65535) ? 65535 : $minR; - $this->_lastRowIndex = ($maxR > 65535) ? 65535 : $maxR ; - - $this->_firstColumnIndex = PHPExcel_Cell::columnIndexFromString($minC); - $this->_lastColumnIndex = PHPExcel_Cell::columnIndexFromString($maxC); - -// if ($this->_firstColumnIndex > 255) $this->_firstColumnIndex = 255; - if ($this->_lastColumnIndex > 255) $this->_lastColumnIndex = 255; - - $this->_countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection()); - } - - /** - * Add data to the beginning of the workbook (note the reverse order) - * and to the end of the workbook. - * - * @access public - * @see PHPExcel_Writer_Excel5_Workbook::storeWorkbook() - */ - function close() - { - $_phpSheet = $this->_phpSheet; - - $num_sheets = $_phpSheet->getParent()->getSheetCount(); - - // Write BOF record - $this->_storeBof(0x0010); - - // Write PRINTHEADERS - $this->_writePrintHeaders(); - - // Write PRINTGRIDLINES - $this->_writePrintGridlines(); - - // Write GRIDSET - $this->_writeGridset(); - - // Calculate column widths - $_phpSheet->calculateColumnWidths(); - - // Column dimensions - if (($defaultWidth = $_phpSheet->getDefaultColumnDimension()->getWidth()) < 0) { - $defaultWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($_phpSheet->getParent()->getDefaultStyle()->getFont()); - } - - $columnDimensions = $_phpSheet->getColumnDimensions(); - $maxCol = $this->_lastColumnIndex -1; - for ($i = 0; $i <= $maxCol; ++$i) { - $hidden = 0; - $level = 0; - $xfIndex = 15; // there are 15 cell style Xfs - - $width = $defaultWidth; - - $columnLetter = PHPExcel_Cell::stringFromColumnIndex($i); - if (isset($columnDimensions[$columnLetter])) { - $columnDimension = $columnDimensions[$columnLetter]; - if ($columnDimension->getWidth() >= 0) { - $width = $columnDimension->getWidth(); - } - $hidden = $columnDimension->getVisible() ? 0 : 1; - $level = $columnDimension->getOutlineLevel(); - $xfIndex = $columnDimension->getXfIndex() + 15; // there are 15 cell style Xfs - } - - // Components of _colinfo: - // $firstcol first column on the range - // $lastcol last column on the range - // $width width to set - // $xfIndex The optional cell style Xf index to apply to the columns - // $hidden The optional hidden atribute - // $level The optional outline level - $this->_colinfo[] = array($i, $i, $width, $xfIndex, $hidden, $level); - } - - // Write GUTS - $this->_writeGuts(); - - // Write DEFAULTROWHEIGHT - $this->_writeDefaultRowHeight(); - - // Write WSBOOL - $this->_writeWsbool(); - - // Write horizontal and vertical page breaks - $this->_writeBreaks(); - - // Write page header - $this->_writeHeader(); - - // Write page footer - $this->_writeFooter(); - - // Write page horizontal centering - $this->_writeHcenter(); - - // Write page vertical centering - $this->_writeVcenter(); - - // Write left margin - $this->_writeMarginLeft(); - - // Write right margin - $this->_writeMarginRight(); - - // Write top margin - $this->_writeMarginTop(); - - // Write bottom margin - $this->_writeMarginBottom(); - - // Write page setup - $this->_writeSetup(); - - // Write sheet protection - $this->_writeProtect(); - - // Write SCENPROTECT - $this->_writeScenProtect(); - - // Write OBJECTPROTECT - $this->_writeObjectProtect(); - - // Write sheet password - $this->_writePassword(); - - // Write DEFCOLWIDTH record - $this->_writeDefcol(); - - // Write the COLINFO records if they exist - if (!empty($this->_colinfo)) { - $colcount = count($this->_colinfo); - for ($i = 0; $i < $colcount; ++$i) { - $this->_writeColinfo($this->_colinfo[$i]); - } - } - $autoFilterRange = $_phpSheet->getAutoFilter()->getRange(); - if (!empty($autoFilterRange)) { - // Write AUTOFILTERINFO - $this->_writeAutoFilterInfo(); - } - - // Write sheet dimensions - $this->_writeDimensions(); - - // Row dimensions - foreach ($_phpSheet->getRowDimensions() as $rowDimension) { - $xfIndex = $rowDimension->getXfIndex() + 15; // there are 15 cellXfs - $this->_writeRow( $rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel() ); - } - - // Write Cells - foreach ($_phpSheet->getCellCollection() as $cellID) { - $cell = $_phpSheet->getCell($cellID); - $row = $cell->getRow() - 1; - $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1; - - // Don't break Excel! -// if ($row + 1 > 65536 or $column + 1 > 256) { - if ($row > 65535 || $column > 255) { - break; - } - - // Write cell value - $xfIndex = $cell->getXfIndex() + 15; // there are 15 cell style Xfs - - $cVal = $cell->getValue(); - if ($cVal instanceof PHPExcel_RichText) { - // $this->_writeString($row, $column, $cVal->getPlainText(), $xfIndex); - $arrcRun = array(); - $str_len = PHPExcel_Shared_String::CountCharacters($cVal->getPlainText(), 'UTF-8'); - $str_pos = 0; - $elements = $cVal->getRichTextElements(); - foreach ($elements as $element) { - // FONT Index - if ($element instanceof PHPExcel_RichText_Run) { - $str_fontidx = $this->_fntHashIndex[$element->getFont()->getHashCode()]; - } - else { - $str_fontidx = 0; - } - $arrcRun[] = array('strlen' => $str_pos, 'fontidx' => $str_fontidx); - // Position FROM - $str_pos += PHPExcel_Shared_String::CountCharacters($element->getText(), 'UTF-8'); - } - $this->_writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun); - } else { - switch ($cell->getDatatype()) { - case PHPExcel_Cell_DataType::TYPE_STRING: - case PHPExcel_Cell_DataType::TYPE_NULL: - if ($cVal === '' || $cVal === null) { - $this->_writeBlank($row, $column, $xfIndex); - } else { - $this->_writeString($row, $column, $cVal, $xfIndex); - } - break; - - case PHPExcel_Cell_DataType::TYPE_NUMERIC: - $this->_writeNumber($row, $column, $cVal, $xfIndex); - break; - - case PHPExcel_Cell_DataType::TYPE_FORMULA: - $calculatedValue = $this->_preCalculateFormulas ? - $cell->getCalculatedValue() : null; - $this->_writeFormula($row, $column, $cVal, $xfIndex, $calculatedValue); - break; - - case PHPExcel_Cell_DataType::TYPE_BOOL: - $this->_writeBoolErr($row, $column, $cVal, 0, $xfIndex); - break; - - case PHPExcel_Cell_DataType::TYPE_ERROR: - $this->_writeBoolErr($row, $column, self::_mapErrorCode($cVal), 1, $xfIndex); - break; - - } - } - } - - // Append - $this->_writeMsoDrawing(); - - // Write WINDOW2 record - $this->_writeWindow2(); - - // Write PLV record - $this->_writePageLayoutView(); - - // Write ZOOM record - $this->_writeZoom(); - if ($_phpSheet->getFreezePane()) { - $this->_writePanes(); - } - - // Write SELECTION record - $this->_writeSelection(); - - // Write MergedCellsTable Record - $this->_writeMergedCells(); - - // Hyperlinks - foreach ($_phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) { - list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinate); - - $url = $hyperlink->getUrl(); - - if ( strpos($url, 'sheet://') !== false ) { - // internal to current workbook - $url = str_replace('sheet://', 'internal:', $url); - - } else if ( preg_match('/^(http:|https:|ftp:|mailto:)/', $url) ) { - // URL - // $url = $url; - - } else { - // external (local file) - $url = 'external:' . $url; - } - - $this->_writeUrl($row - 1, PHPExcel_Cell::columnIndexFromString($column) - 1, $url); - } - - $this->_writeDataValidity(); - $this->_writeSheetLayout(); - - // Write SHEETPROTECTION record - $this->_writeSheetProtection(); - $this->_writeRangeProtection(); - - $arrConditionalStyles = $_phpSheet->getConditionalStylesCollection(); - if(!empty($arrConditionalStyles)){ - $arrConditional = array(); - // @todo CFRule & CFHeader - // Write CFHEADER record - $this->_writeCFHeader(); - // Write ConditionalFormattingTable records - foreach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) { - foreach ($conditionalStyles as $conditional) { - if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION - || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ - if(!in_array($conditional->getHashCode(), $arrConditional)){ - $arrConditional[] = $conditional->getHashCode(); - // Write CFRULE record - $this->_writeCFRule($conditional); - } - } - } - } - } - - $this->_storeEof(); - } - - /** - * Write a cell range address in BIFF8 - * always fixed range - * See section 2.5.14 in OpenOffice.org's Documentation of the Microsoft Excel File Format - * - * @param string $range E.g. 'A1' or 'A1:B6' - * @return string Binary data - */ - private function _writeBIFF8CellRangeAddressFixed($range = 'A1') - { - $explodes = explode(':', $range); - - // extract first cell, e.g. 'A1' - $firstCell = $explodes[0]; - - // extract last cell, e.g. 'B6' - if (count($explodes) == 1) { - $lastCell = $firstCell; - } else { - $lastCell = $explodes[1]; - } - - $firstCellCoordinates = PHPExcel_Cell::coordinateFromString($firstCell); // e.g. array(0, 1) - $lastCellCoordinates = PHPExcel_Cell::coordinateFromString($lastCell); // e.g. array(1, 6) - - return(pack('vvvv', - $firstCellCoordinates[1] - 1, - $lastCellCoordinates[1] - 1, - PHPExcel_Cell::columnIndexFromString($firstCellCoordinates[0]) - 1, - PHPExcel_Cell::columnIndexFromString($lastCellCoordinates[0]) - 1 - )); - } - - /** - * Retrieves data from memory in one chunk, or from disk in $buffer - * sized chunks. - * - * @return string The data - */ - function getData() - { - $buffer = 4096; - - // Return data stored in memory - if (isset($this->_data)) { - $tmp = $this->_data; - unset($this->_data); - return $tmp; - } - // No data to return - return false; - } - - /** - * Set the option to print the row and column headers on the printed page. - * - * @access public - * @param integer $print Whether to print the headers or not. Defaults to 1 (print). - */ - function printRowColHeaders($print = 1) - { - $this->_print_headers = $print; - } - - /** - * This method sets the properties for outlining and grouping. The defaults - * correspond to Excel's defaults. - * - * @param bool $visible - * @param bool $symbols_below - * @param bool $symbols_right - * @param bool $auto_style - */ - function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false) - { - $this->_outline_on = $visible; - $this->_outline_below = $symbols_below; - $this->_outline_right = $symbols_right; - $this->_outline_style = $auto_style; - - // Ensure this is a boolean vale for Window2 - if ($this->_outline_on) { - $this->_outline_on = 1; - } - } - - /** - * Write a double to the specified row and column (zero indexed). - * An integer can be written as a double. Excel will display an - * integer. $format is optional. - * - * Returns 0 : normal termination - * -2 : row or column out of range - * - * @param integer $row Zero indexed row - * @param integer $col Zero indexed column - * @param float $num The number to write - * @param mixed $xfIndex The optional XF format - * @return integer - */ - private function _writeNumber($row, $col, $num, $xfIndex) - { - $record = 0x0203; // Record identifier - $length = 0x000E; // Number of bytes to follow - - $header = pack("vv", $record, $length); - $data = pack("vvv", $row, $col, $xfIndex); - $xl_double = pack("d", $num); - if (self::getByteOrder()) { // if it's Big Endian - $xl_double = strrev($xl_double); - } - - $this->_append($header.$data.$xl_double); - return(0); - } - - /** - * Write a LABELSST record or a LABEL record. Which one depends on BIFF version - * - * @param int $row Row index (0-based) - * @param int $col Column index (0-based) - * @param string $str The string - * @param int $xfIndex Index to XF record - */ - private function _writeString($row, $col, $str, $xfIndex) - { - $this->_writeLabelSst($row, $col, $str, $xfIndex); - } - - /** - * Write a LABELSST record or a LABEL record. Which one depends on BIFF version - * It differs from _writeString by the writing of rich text strings. - * @param int $row Row index (0-based) - * @param int $col Column index (0-based) - * @param string $str The string - * @param mixed $xfIndex The XF format index for the cell - * @param array $arrcRun Index to Font record and characters beginning - */ - private function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun){ - $record = 0x00FD; // Record identifier - $length = 0x000A; // Bytes to follow - $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($str, $arrcRun); - - /* check if string is already present */ - if (!isset($this->_str_table[$str])) { - $this->_str_table[$str] = $this->_str_unique++; - } - $this->_str_total++; - - $header = pack('vv', $record, $length); - $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); - $this->_append($header.$data); - } - - /** - * Write a string to the specified row and column (zero indexed). - * NOTE: there is an Excel 5 defined limit of 255 characters. - * $format is optional. - * Returns 0 : normal termination - * -2 : row or column out of range - * -3 : long string truncated to 255 chars - * - * @access public - * @param integer $row Zero indexed row - * @param integer $col Zero indexed column - * @param string $str The string to write - * @param mixed $xfIndex The XF format index for the cell - * @return integer - */ - private function _writeLabel($row, $col, $str, $xfIndex) - { - $strlen = strlen($str); - $record = 0x0204; // Record identifier - $length = 0x0008 + $strlen; // Bytes to follow - - $str_error = 0; - - if ($strlen > $this->_xls_strmax) { // LABEL must be < 255 chars - $str = substr($str, 0, $this->_xls_strmax); - $length = 0x0008 + $this->_xls_strmax; - $strlen = $this->_xls_strmax; - $str_error = -3; - } - - $header = pack("vv", $record, $length); - $data = pack("vvvv", $row, $col, $xfIndex, $strlen); - $this->_append($header . $data . $str); - return($str_error); - } - - /** - * Write a string to the specified row and column (zero indexed). - * This is the BIFF8 version (no 255 chars limit). - * $format is optional. - * Returns 0 : normal termination - * -2 : row or column out of range - * -3 : long string truncated to 255 chars - * - * @access public - * @param integer $row Zero indexed row - * @param integer $col Zero indexed column - * @param string $str The string to write - * @param mixed $xfIndex The XF format index for the cell - * @return integer - */ - private function _writeLabelSst($row, $col, $str, $xfIndex) - { - $record = 0x00FD; // Record identifier - $length = 0x000A; // Bytes to follow - - $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($str); - - /* check if string is already present */ - if (!isset($this->_str_table[$str])) { - $this->_str_table[$str] = $this->_str_unique++; - } - $this->_str_total++; - - $header = pack('vv', $record, $length); - $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); - $this->_append($header.$data); - } - - /** - * Writes a note associated with the cell given by the row and column. - * NOTE records don't have a length limit. - * - * @param integer $row Zero indexed row - * @param integer $col Zero indexed column - * @param string $note The note to write - */ - private function _writeNote($row, $col, $note) - { - $note_length = strlen($note); - $record = 0x001C; // Record identifier - $max_length = 2048; // Maximun length for a NOTE record - - // Length for this record is no more than 2048 + 6 - $length = 0x0006 + min($note_length, 2048); - $header = pack("vv", $record, $length); - $data = pack("vvv", $row, $col, $note_length); - $this->_append($header . $data . substr($note, 0, 2048)); - - for ($i = $max_length; $i < $note_length; $i += $max_length) { - $chunk = substr($note, $i, $max_length); - $length = 0x0006 + strlen($chunk); - $header = pack("vv", $record, $length); - $data = pack("vvv", -1, 0, strlen($chunk)); - $this->_append($header.$data.$chunk); - } - return(0); - } - - /** - * Write a blank cell to the specified row and column (zero indexed). - * A blank cell is used to specify formatting without adding a string - * or a number. - * - * A blank cell without a format serves no purpose. Therefore, we don't write - * a BLANK record unless a format is specified. - * - * Returns 0 : normal termination (including no format) - * -1 : insufficient number of arguments - * -2 : row or column out of range - * - * @param integer $row Zero indexed row - * @param integer $col Zero indexed column - * @param mixed $xfIndex The XF format index - */ - function _writeBlank($row, $col, $xfIndex) - { - $record = 0x0201; // Record identifier - $length = 0x0006; // Number of bytes to follow - - $header = pack("vv", $record, $length); - $data = pack("vvv", $row, $col, $xfIndex); - $this->_append($header . $data); - return 0; - } - - /** - * Write a boolean or an error type to the specified row and column (zero indexed) - * - * @param int $row Row index (0-based) - * @param int $col Column index (0-based) - * @param int $value - * @param boolean $isError Error or Boolean? - * @param int $xfIndex - */ - private function _writeBoolErr($row, $col, $value, $isError, $xfIndex) - { - $record = 0x0205; - $length = 8; - - $header = pack("vv", $record, $length); - $data = pack("vvvCC", $row, $col, $xfIndex, $value, $isError); - $this->_append($header . $data); - return 0; - } - - /** - * Write a formula to the specified row and column (zero indexed). - * The textual representation of the formula is passed to the parser in - * Parser.php which returns a packed binary string. - * - * Returns 0 : normal termination - * -1 : formula errors (bad formula) - * -2 : row or column out of range - * - * @param integer $row Zero indexed row - * @param integer $col Zero indexed column - * @param string $formula The formula text string - * @param mixed $xfIndex The XF format index - * @param mixed $calculatedValue Calculated value - * @return integer - */ - private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) - { - $record = 0x0006; // Record identifier - - // Initialize possible additional value for STRING record that should be written after the FORMULA record? - $stringValue = null; - - // calculated value - if (isset($calculatedValue)) { - // Since we can't yet get the data type of the calculated value, - // we use best effort to determine data type - if (is_bool($calculatedValue)) { - // Boolean value - $num = pack('CCCvCv', 0x01, 0x00, (int)$calculatedValue, 0x00, 0x00, 0xFFFF); - } elseif (is_int($calculatedValue) || is_float($calculatedValue)) { - // Numeric value - $num = pack('d', $calculatedValue); - } elseif (is_string($calculatedValue)) { - if (array_key_exists($calculatedValue, PHPExcel_Cell_DataType::getErrorCodes())) { - // Error value - $num = pack('CCCvCv', 0x02, 0x00, self::_mapErrorCode($calculatedValue), 0x00, 0x00, 0xFFFF); - } elseif ($calculatedValue === '') { - // Empty string (and BIFF8) - $num = pack('CCCvCv', 0x03, 0x00, 0x00, 0x00, 0x00, 0xFFFF); - } else { - // Non-empty string value (or empty string BIFF5) - $stringValue = $calculatedValue; - $num = pack('CCCvCv', 0x00, 0x00, 0x00, 0x00, 0x00, 0xFFFF); - } - } else { - // We are really not supposed to reach here - $num = pack('d', 0x00); - } - } else { - $num = pack('d', 0x00); - } - - $grbit = 0x03; // Option flags - $unknown = 0x0000; // Must be zero - - // Strip the '=' or '@' sign at the beginning of the formula string - if ($formula{0} == '=') { - $formula = substr($formula,1); - } else { - // Error handling - $this->_writeString($row, $col, 'Unrecognised character for formula'); - return -1; - } - - // Parse the formula using the parser in Parser.php - try { - $error = $this->_parser->parse($formula); - $formula = $this->_parser->toReversePolish(); - - $formlen = strlen($formula); // Length of the binary string - $length = 0x16 + $formlen; // Length of the record data - - $header = pack("vv", $record, $length); - - $data = pack("vvv", $row, $col, $xfIndex) - . $num - . pack("vVv", $grbit, $unknown, $formlen); - $this->_append($header . $data . $formula); - - // Append also a STRING record if necessary - if ($stringValue !== null) { - $this->_writeStringRecord($stringValue); - } - - return 0; - - } catch (PHPExcel_Exception $e) { - // do nothing - } - - } - - /** - * Write a STRING record. This - * - * @param string $stringValue - */ - private function _writeStringRecord($stringValue) - { - $record = 0x0207; // Record identifier - $data = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($stringValue); - - $length = strlen($data); - $header = pack('vv', $record, $length); - - $this->_append($header . $data); - } - - /** - * Write a hyperlink. - * This is comprised of two elements: the visible label and - * the invisible link. The visible label is the same as the link unless an - * alternative string is specified. The label is written using the - * _writeString() method. Therefore the 255 characters string limit applies. - * $string and $format are optional. - * - * The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external - * directory url. - * - * Returns 0 : normal termination - * -2 : row or column out of range - * -3 : long string truncated to 255 chars - * - * @param integer $row Row - * @param integer $col Column - * @param string $url URL string - * @return integer - */ - private function _writeUrl($row, $col, $url) - { - // Add start row and col to arg list - return($this->_writeUrlRange($row, $col, $row, $col, $url)); - } - - /** - * This is the more general form of _writeUrl(). It allows a hyperlink to be - * written to a range of cells. This function also decides the type of hyperlink - * to be written. These are either, Web (http, ftp, mailto), Internal - * (Sheet1!A1) or external ('c:\temp\foo.xls#Sheet1!A1'). - * - * @access private - * @see _writeUrl() - * @param integer $row1 Start row - * @param integer $col1 Start column - * @param integer $row2 End row - * @param integer $col2 End column - * @param string $url URL string - * @return integer - */ - function _writeUrlRange($row1, $col1, $row2, $col2, $url) - { - // Check for internal/external sheet links or default to web link - if (preg_match('[^internal:]', $url)) { - return($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url)); - } - if (preg_match('[^external:]', $url)) { - return($this->_writeUrlExternal($row1, $col1, $row2, $col2, $url)); - } - return($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url)); - } - - /** - * Used to write http, ftp and mailto hyperlinks. - * The link type ($options) is 0x03 is the same as absolute dir ref without - * sheet. However it is differentiated by the $unknown2 data stream. - * - * @access private - * @see _writeUrl() - * @param integer $row1 Start row - * @param integer $col1 Start column - * @param integer $row2 End row - * @param integer $col2 End column - * @param string $url URL string - * @return integer - */ - function _writeUrlWeb($row1, $col1, $row2, $col2, $url) - { - $record = 0x01B8; // Record identifier - $length = 0x00000; // Bytes to follow - - // Pack the undocumented parts of the hyperlink stream - $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); - $unknown2 = pack("H*", "E0C9EA79F9BACE118C8200AA004BA90B"); - - // Pack the option flags - $options = pack("V", 0x03); - - // Convert URL to a null terminated wchar string - $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY)); - $url = $url . "\0\0\0"; - - // Pack the length of the URL - $url_len = pack("V", strlen($url)); - - // Calculate the data length - $length = 0x34 + strlen($url); - - // Pack the header data - $header = pack("vv", $record, $length); - $data = pack("vvvv", $row1, $row2, $col1, $col2); - - // Write the packed data - $this->_append($header . $data . - $unknown1 . $options . - $unknown2 . $url_len . $url); - return 0; - } - - /** - * Used to write internal reference hyperlinks such as "Sheet1!A1". - * - * @access private - * @see _writeUrl() - * @param integer $row1 Start row - * @param integer $col1 Start column - * @param integer $row2 End row - * @param integer $col2 End column - * @param string $url URL string - * @return integer - */ - function _writeUrlInternal($row1, $col1, $row2, $col2, $url) - { - $record = 0x01B8; // Record identifier - $length = 0x00000; // Bytes to follow - - // Strip URL type - $url = preg_replace('/^internal:/', '', $url); - - // Pack the undocumented parts of the hyperlink stream - $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); - - // Pack the option flags - $options = pack("V", 0x08); - - // Convert the URL type and to a null terminated wchar string - $url .= "\0"; - - // character count - $url_len = PHPExcel_Shared_String::CountCharacters($url); - $url_len = pack('V', $url_len); - - $url = PHPExcel_Shared_String::ConvertEncoding($url, 'UTF-16LE', 'UTF-8'); - - // Calculate the data length - $length = 0x24 + strlen($url); - - // Pack the header data - $header = pack("vv", $record, $length); - $data = pack("vvvv", $row1, $row2, $col1, $col2); - - // Write the packed data - $this->_append($header . $data . - $unknown1 . $options . - $url_len . $url); - return 0; - } - - /** - * Write links to external directory names such as 'c:\foo.xls', - * c:\foo.xls#Sheet1!A1', '../../foo.xls'. and '../../foo.xls#Sheet1!A1'. - * - * Note: Excel writes some relative links with the $dir_long string. We ignore - * these cases for the sake of simpler code. - * - * @access private - * @see _writeUrl() - * @param integer $row1 Start row - * @param integer $col1 Start column - * @param integer $row2 End row - * @param integer $col2 End column - * @param string $url URL string - * @return integer - */ - function _writeUrlExternal($row1, $col1, $row2, $col2, $url) - { - // Network drives are different. We will handle them separately - // MS/Novell network drives and shares start with \\ - if (preg_match('[^external:\\\\]', $url)) { - return; //($this->_writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format)); - } - - $record = 0x01B8; // Record identifier - $length = 0x00000; // Bytes to follow - - // Strip URL type and change Unix dir separator to Dos style (if needed) - // - $url = preg_replace('/^external:/', '', $url); - $url = preg_replace('/\//', "\\", $url); - - // Determine if the link is relative or absolute: - // relative if link contains no dir separator, "somefile.xls" - // relative if link starts with up-dir, "..\..\somefile.xls" - // otherwise, absolute - - $absolute = 0x00; // relative path - if ( preg_match('/^[A-Z]:/', $url) ) { - $absolute = 0x02; // absolute path on Windows, e.g. C:\... - } - $link_type = 0x01 | $absolute; - - // Determine if the link contains a sheet reference and change some of the - // parameters accordingly. - // Split the dir name and sheet name (if it exists) - $dir_long = $url; - if (preg_match("/\#/", $url)) { - $link_type |= 0x08; - } - - - // Pack the link type - $link_type = pack("V", $link_type); - - // Calculate the up-level dir count e.g.. (..\..\..\ == 3) - $up_count = preg_match_all("/\.\.\\\/", $dir_long, $useless); - $up_count = pack("v", $up_count); - - // Store the short dos dir name (null terminated) - $dir_short = preg_replace("/\.\.\\\/", '', $dir_long) . "\0"; - - // Store the long dir name as a wchar string (non-null terminated) - $dir_long = $dir_long . "\0"; - - // Pack the lengths of the dir strings - $dir_short_len = pack("V", strlen($dir_short) ); - $dir_long_len = pack("V", strlen($dir_long) ); - $stream_len = pack("V", 0);//strlen($dir_long) + 0x06); - - // Pack the undocumented parts of the hyperlink stream - $unknown1 = pack("H*",'D0C9EA79F9BACE118C8200AA004BA90B02000000' ); - $unknown2 = pack("H*",'0303000000000000C000000000000046' ); - $unknown3 = pack("H*",'FFFFADDE000000000000000000000000000000000000000'); - $unknown4 = pack("v", 0x03 ); - - // Pack the main data stream - $data = pack("vvvv", $row1, $row2, $col1, $col2) . - $unknown1 . - $link_type . - $unknown2 . - $up_count . - $dir_short_len. - $dir_short . - $unknown3 . - $stream_len ;/*. - $dir_long_len . - $unknown4 . - $dir_long . - $sheet_len . - $sheet ;*/ - - // Pack the header data - $length = strlen($data); - $header = pack("vv", $record, $length); - - // Write the packed data - $this->_append($header. $data); - return 0; - } - - /** - * This method is used to set the height and format for a row. - * - * @param integer $row The row to set - * @param integer $height Height we are giving to the row. - * Use null to set XF without setting height - * @param integer $xfIndex The optional cell style Xf index to apply to the columns - * @param bool $hidden The optional hidden attribute - * @param integer $level The optional outline level for row, in range [0,7] - */ - private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) - { - $record = 0x0208; // Record identifier - $length = 0x0010; // Number of bytes to follow - - $colMic = 0x0000; // First defined column - $colMac = 0x0000; // Last defined column - $irwMac = 0x0000; // Used by Excel to optimise loading - $reserved = 0x0000; // Reserved - $grbit = 0x0000; // Option flags - $ixfe = $xfIndex; - - if ( $height < 0 ){ - $height = null; - } - - // Use _writeRow($row, null, $XF) to set XF format without setting height - if ($height != null) { - $miyRw = $height * 20; // row height - } else { - $miyRw = 0xff; // default row height is 256 - } - - // Set the options flags. fUnsynced is used to show that the font and row - // heights are not compatible. This is usually the case for WriteExcel. - // The collapsed flag 0x10 doesn't seem to be used to indicate that a row - // is collapsed. Instead it is used to indicate that the previous row is - // collapsed. The zero height flag, 0x20, is used to collapse a row. - - $grbit |= $level; - if ($hidden) { - $grbit |= 0x0030; - } - if ($height !== null) { - $grbit |= 0x0040; // fUnsynced - } - if ($xfIndex !== 0xF) { - $grbit |= 0x0080; - } - $grbit |= 0x0100; - - $header = pack("vv", $record, $length); - $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, - $irwMac,$reserved, $grbit, $ixfe); - $this->_append($header.$data); - } - - /** - * Writes Excel DIMENSIONS to define the area in which there is data. - */ - private function _writeDimensions() - { - $record = 0x0200; // Record identifier - - $length = 0x000E; - $data = pack('VVvvv' - , $this->_firstRowIndex - , $this->_lastRowIndex + 1 - , $this->_firstColumnIndex - , $this->_lastColumnIndex + 1 - , 0x0000 // reserved - ); - - $header = pack("vv", $record, $length); - $this->_append($header.$data); - } - - /** - * Write BIFF record Window2. - */ - private function _writeWindow2() - { - $record = 0x023E; // Record identifier - $length = 0x0012; - - $grbit = 0x00B6; // Option flags - $rwTop = 0x0000; // Top row visible in window - $colLeft = 0x0000; // Leftmost column visible in window - - - // The options flags that comprise $grbit - $fDspFmla = 0; // 0 - bit - $fDspGrid = $this->_phpSheet->getShowGridlines() ? 1 : 0; // 1 - $fDspRwCol = $this->_phpSheet->getShowRowColHeaders() ? 1 : 0; // 2 - $fFrozen = $this->_phpSheet->getFreezePane() ? 1 : 0; // 3 - $fDspZeros = 1; // 4 - $fDefaultHdr = 1; // 5 - $fArabic = $this->_phpSheet->getRightToLeft() ? 1 : 0; // 6 - $fDspGuts = $this->_outline_on; // 7 - $fFrozenNoSplit = 0; // 0 - bit - // no support in PHPExcel for selected sheet, therefore sheet is only selected if it is the active sheet - $fSelected = ($this->_phpSheet === $this->_phpSheet->getParent()->getActiveSheet()) ? 1 : 0; - $fPaged = 1; // 2 - $fPageBreakPreview = $this->_phpSheet->getSheetView()->getView() === PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW; - - $grbit = $fDspFmla; - $grbit |= $fDspGrid << 1; - $grbit |= $fDspRwCol << 2; - $grbit |= $fFrozen << 3; - $grbit |= $fDspZeros << 4; - $grbit |= $fDefaultHdr << 5; - $grbit |= $fArabic << 6; - $grbit |= $fDspGuts << 7; - $grbit |= $fFrozenNoSplit << 8; - $grbit |= $fSelected << 9; - $grbit |= $fPaged << 10; - $grbit |= $fPageBreakPreview << 11; - - $header = pack("vv", $record, $length); - $data = pack("vvv", $grbit, $rwTop, $colLeft); - - // FIXME !!! - $rgbHdr = 0x0040; // Row/column heading and gridline color index - $zoom_factor_page_break = ($fPageBreakPreview? $this->_phpSheet->getSheetView()->getZoomScale() : 0x0000); - $zoom_factor_normal = $this->_phpSheet->getSheetView()->getZoomScaleNormal(); - - $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000); - - $this->_append($header.$data); - } - - /** - * Write BIFF record DEFAULTROWHEIGHT. - */ - private function _writeDefaultRowHeight() - { - $defaultRowHeight = $this->_phpSheet->getDefaultRowDimension()->getRowHeight(); - - if ($defaultRowHeight < 0) { - return; - } - - // convert to twips - $defaultRowHeight = (int) 20 * $defaultRowHeight; - - $record = 0x0225; // Record identifier - $length = 0x0004; // Number of bytes to follow - - $header = pack("vv", $record, $length); - $data = pack("vv", 1, $defaultRowHeight); - $this->_append($header . $data); - } - - /** - * Write BIFF record DEFCOLWIDTH if COLINFO records are in use. - */ - private function _writeDefcol() - { - $defaultColWidth = 8; - - $record = 0x0055; // Record identifier - $length = 0x0002; // Number of bytes to follow - - $header = pack("vv", $record, $length); - $data = pack("v", $defaultColWidth); - $this->_append($header . $data); - } - - /** - * Write BIFF record COLINFO to define column widths - * - * Note: The SDK says the record length is 0x0B but Excel writes a 0x0C - * length record. - * - * @param array $col_array This is the only parameter received and is composed of the following: - * 0 => First formatted column, - * 1 => Last formatted column, - * 2 => Col width (8.43 is Excel default), - * 3 => The optional XF format of the column, - * 4 => Option flags. - * 5 => Optional outline level - */ - private function _writeColinfo($col_array) - { - if (isset($col_array[0])) { - $colFirst = $col_array[0]; - } - if (isset($col_array[1])) { - $colLast = $col_array[1]; - } - if (isset($col_array[2])) { - $coldx = $col_array[2]; - } else { - $coldx = 8.43; - } - if (isset($col_array[3])) { - $xfIndex = $col_array[3]; - } else { - $xfIndex = 15; - } - if (isset($col_array[4])) { - $grbit = $col_array[4]; - } else { - $grbit = 0; - } - if (isset($col_array[5])) { - $level = $col_array[5]; - } else { - $level = 0; - } - $record = 0x007D; // Record identifier - $length = 0x000C; // Number of bytes to follow - - $coldx *= 256; // Convert to units of 1/256 of a char - - $ixfe = $xfIndex; - $reserved = 0x0000; // Reserved - - $level = max(0, min($level, 7)); - $grbit |= $level << 8; - - $header = pack("vv", $record, $length); - $data = pack("vvvvvv", $colFirst, $colLast, $coldx, - $ixfe, $grbit, $reserved); - $this->_append($header.$data); - } - - /** - * Write BIFF record SELECTION. - */ - private function _writeSelection() - { - // look up the selected cell range - $selectedCells = $this->_phpSheet->getSelectedCells(); - $selectedCells = PHPExcel_Cell::splitRange($this->_phpSheet->getSelectedCells()); - $selectedCells = $selectedCells[0]; - if (count($selectedCells) == 2) { - list($first, $last) = $selectedCells; - } else { - $first = $selectedCells[0]; - $last = $selectedCells[0]; - } - - list($colFirst, $rwFirst) = PHPExcel_Cell::coordinateFromString($first); - $colFirst = PHPExcel_Cell::columnIndexFromString($colFirst) - 1; // base 0 column index - --$rwFirst; // base 0 row index - - list($colLast, $rwLast) = PHPExcel_Cell::coordinateFromString($last); - $colLast = PHPExcel_Cell::columnIndexFromString($colLast) - 1; // base 0 column index - --$rwLast; // base 0 row index - - // make sure we are not out of bounds - $colFirst = min($colFirst, 255); - $colLast = min($colLast, 255); - - $rwFirst = min($rwFirst, 65535); - $rwLast = min($rwLast, 65535); - - $record = 0x001D; // Record identifier - $length = 0x000F; // Number of bytes to follow - - $pnn = $this->_active_pane; // Pane position - $rwAct = $rwFirst; // Active row - $colAct = $colFirst; // Active column - $irefAct = 0; // Active cell ref - $cref = 1; // Number of refs - - if (!isset($rwLast)) { - $rwLast = $rwFirst; // Last row in reference - } - if (!isset($colLast)) { - $colLast = $colFirst; // Last col in reference - } - - // Swap last row/col for first row/col as necessary - if ($rwFirst > $rwLast) { - list($rwFirst, $rwLast) = array($rwLast, $rwFirst); - } - - if ($colFirst > $colLast) { - list($colFirst, $colLast) = array($colLast, $colFirst); - } - - $header = pack("vv", $record, $length); - $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct, - $irefAct, $cref, - $rwFirst, $rwLast, - $colFirst, $colLast); - $this->_append($header . $data); - } - - /** - * Store the MERGEDCELLS records for all ranges of merged cells - */ - private function _writeMergedCells() - { - $mergeCells = $this->_phpSheet->getMergeCells(); - $countMergeCells = count($mergeCells); - - if ($countMergeCells == 0) { - return; - } - - // maximum allowed number of merged cells per record - $maxCountMergeCellsPerRecord = 1027; - - // record identifier - $record = 0x00E5; - - // counter for total number of merged cells treated so far by the writer - $i = 0; - - // counter for number of merged cells written in record currently being written - $j = 0; - - // initialize record data - $recordData = ''; - - // loop through the merged cells - foreach ($mergeCells as $mergeCell) { - ++$i; - ++$j; - - // extract the row and column indexes - $range = PHPExcel_Cell::splitRange($mergeCell); - list($first, $last) = $range[0]; - list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($first); - list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($last); - - $recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, PHPExcel_Cell::columnIndexFromString($firstColumn) - 1, PHPExcel_Cell::columnIndexFromString($lastColumn) - 1); - - // flush record if we have reached limit for number of merged cells, or reached final merged cell - if ($j == $maxCountMergeCellsPerRecord or $i == $countMergeCells) { - $recordData = pack('v', $j) . $recordData; - $length = strlen($recordData); - $header = pack('vv', $record, $length); - $this->_append($header . $recordData); - - // initialize for next record, if any - $recordData = ''; - $j = 0; - } - } - } - - /** - * Write SHEETLAYOUT record - */ - private function _writeSheetLayout() - { - if (!$this->_phpSheet->isTabColorSet()) { - return; - } - - $recordData = pack( - 'vvVVVvv' - , 0x0862 - , 0x0000 // unused - , 0x00000000 // unused - , 0x00000000 // unused - , 0x00000014 // size of record data - , $this->_colors[$this->_phpSheet->getTabColor()->getRGB()] // color index - , 0x0000 // unused - ); - - $length = strlen($recordData); - - $record = 0x0862; // Record identifier - $header = pack('vv', $record, $length); - $this->_append($header . $recordData); - } - - /** - * Write SHEETPROTECTION - */ - private function _writeSheetProtection() - { - // record identifier - $record = 0x0867; - - // prepare options - $options = (int) !$this->_phpSheet->getProtection()->getObjects() - | (int) !$this->_phpSheet->getProtection()->getScenarios() << 1 - | (int) !$this->_phpSheet->getProtection()->getFormatCells() << 2 - | (int) !$this->_phpSheet->getProtection()->getFormatColumns() << 3 - | (int) !$this->_phpSheet->getProtection()->getFormatRows() << 4 - | (int) !$this->_phpSheet->getProtection()->getInsertColumns() << 5 - | (int) !$this->_phpSheet->getProtection()->getInsertRows() << 6 - | (int) !$this->_phpSheet->getProtection()->getInsertHyperlinks() << 7 - | (int) !$this->_phpSheet->getProtection()->getDeleteColumns() << 8 - | (int) !$this->_phpSheet->getProtection()->getDeleteRows() << 9 - | (int) !$this->_phpSheet->getProtection()->getSelectLockedCells() << 10 - | (int) !$this->_phpSheet->getProtection()->getSort() << 11 - | (int) !$this->_phpSheet->getProtection()->getAutoFilter() << 12 - | (int) !$this->_phpSheet->getProtection()->getPivotTables() << 13 - | (int) !$this->_phpSheet->getProtection()->getSelectUnlockedCells() << 14 ; - - // record data - $recordData = pack( - 'vVVCVVvv' - , 0x0867 // repeated record identifier - , 0x0000 // not used - , 0x0000 // not used - , 0x00 // not used - , 0x01000200 // unknown data - , 0xFFFFFFFF // unknown data - , $options // options - , 0x0000 // not used - ); - - $length = strlen($recordData); - $header = pack('vv', $record, $length); - - $this->_append($header . $recordData); - } - - /** - * Write BIFF record RANGEPROTECTION - * - * Openoffice.org's Documentaion of the Microsoft Excel File Format uses term RANGEPROTECTION for these records - * Microsoft Office Excel 97-2007 Binary File Format Specification uses term FEAT for these records - */ - private function _writeRangeProtection() - { - foreach ($this->_phpSheet->getProtectedCells() as $range => $password) { - // number of ranges, e.g. 'A1:B3 C20:D25' - $cellRanges = explode(' ', $range); - $cref = count($cellRanges); - - $recordData = pack( - 'vvVVvCVvVv', - 0x0868, - 0x00, - 0x0000, - 0x0000, - 0x02, - 0x0, - 0x0000, - $cref, - 0x0000, - 0x00 - ); - - foreach ($cellRanges as $cellRange) { - $recordData .= $this->_writeBIFF8CellRangeAddressFixed($cellRange); - } - - // the rgbFeat structure - $recordData .= pack( - 'VV', - 0x0000, - hexdec($password) - ); - - $recordData .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong('p' . md5($recordData)); - - $length = strlen($recordData); - - $record = 0x0868; // Record identifier - $header = pack("vv", $record, $length); - $this->_append($header . $recordData); - } - } - - /** - * Write BIFF record EXTERNCOUNT to indicate the number of external sheet - * references in a worksheet. - * - * Excel only stores references to external sheets that are used in formulas. - * For simplicity we store references to all the sheets in the workbook - * regardless of whether they are used or not. This reduces the overall - * complexity and eliminates the need for a two way dialogue between the formula - * parser the worksheet objects. - * - * @param integer $count The number of external sheet references in this worksheet - */ - private function _writeExterncount($count) - { - $record = 0x0016; // Record identifier - $length = 0x0002; // Number of bytes to follow - - $header = pack("vv", $record, $length); - $data = pack("v", $count); - $this->_append($header . $data); - } - - /** - * Writes the Excel BIFF EXTERNSHEET record. These references are used by - * formulas. A formula references a sheet name via an index. Since we store a - * reference to all of the external worksheets the EXTERNSHEET index is the same - * as the worksheet index. - * - * @param string $sheetname The name of a external worksheet - */ - private function _writeExternsheet($sheetname) - { - $record = 0x0017; // Record identifier - - // References to the current sheet are encoded differently to references to - // external sheets. - // - if ($this->_phpSheet->getTitle() == $sheetname) { - $sheetname = ''; - $length = 0x02; // The following 2 bytes - $cch = 1; // The following byte - $rgch = 0x02; // Self reference - } else { - $length = 0x02 + strlen($sheetname); - $cch = strlen($sheetname); - $rgch = 0x03; // Reference to a sheet in the current workbook - } - - $header = pack("vv", $record, $length); - $data = pack("CC", $cch, $rgch); - $this->_append($header . $data . $sheetname); - } - - /** - * Writes the Excel BIFF PANE record. - * The panes can either be frozen or thawed (unfrozen). - * Frozen panes are specified in terms of an integer number of rows and columns. - * Thawed panes are specified in terms of Excel's units for rows and columns. - */ - private function _writePanes() - { - $panes = array(); - if ($freezePane = $this->_phpSheet->getFreezePane()) { - list($column, $row) = PHPExcel_Cell::coordinateFromString($freezePane); - $panes[0] = $row - 1; - $panes[1] = PHPExcel_Cell::columnIndexFromString($column) - 1; - } else { - // thaw panes - return; - } - - $y = isset($panes[0]) ? $panes[0] : null; - $x = isset($panes[1]) ? $panes[1] : null; - $rwTop = isset($panes[2]) ? $panes[2] : null; - $colLeft = isset($panes[3]) ? $panes[3] : null; - if (count($panes) > 4) { // if Active pane was received - $pnnAct = $panes[4]; - } else { - $pnnAct = null; - } - $record = 0x0041; // Record identifier - $length = 0x000A; // Number of bytes to follow - - // Code specific to frozen or thawed panes. - if ($this->_phpSheet->getFreezePane()) { - // Set default values for $rwTop and $colLeft - if (!isset($rwTop)) { - $rwTop = $y; - } - if (!isset($colLeft)) { - $colLeft = $x; - } - } else { - // Set default values for $rwTop and $colLeft - if (!isset($rwTop)) { - $rwTop = 0; - } - if (!isset($colLeft)) { - $colLeft = 0; - } - - // Convert Excel's row and column units to the internal units. - // The default row height is 12.75 - // The default column width is 8.43 - // The following slope and intersection values were interpolated. - // - $y = 20*$y + 255; - $x = 113.879*$x + 390; - } - - - // Determine which pane should be active. There is also the undocumented - // option to override this should it be necessary: may be removed later. - // - if (!isset($pnnAct)) { - if ($x != 0 && $y != 0) { - $pnnAct = 0; // Bottom right - } - if ($x != 0 && $y == 0) { - $pnnAct = 1; // Top right - } - if ($x == 0 && $y != 0) { - $pnnAct = 2; // Bottom left - } - if ($x == 0 && $y == 0) { - $pnnAct = 3; // Top left - } - } - - $this->_active_pane = $pnnAct; // Used in _writeSelection - - $header = pack("vv", $record, $length); - $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); - $this->_append($header . $data); - } - - /** - * Store the page setup SETUP BIFF record. - */ - private function _writeSetup() - { - $record = 0x00A1; // Record identifier - $length = 0x0022; // Number of bytes to follow - - $iPaperSize = $this->_phpSheet->getPageSetup()->getPaperSize(); // Paper size - - $iScale = $this->_phpSheet->getPageSetup()->getScale() ? - $this->_phpSheet->getPageSetup()->getScale() : 100; // Print scaling factor - - $iPageStart = 0x01; // Starting page number - $iFitWidth = (int) $this->_phpSheet->getPageSetup()->getFitToWidth(); // Fit to number of pages wide - $iFitHeight = (int) $this->_phpSheet->getPageSetup()->getFitToHeight(); // Fit to number of pages high - $grbit = 0x00; // Option flags - $iRes = 0x0258; // Print resolution - $iVRes = 0x0258; // Vertical print resolution - - $numHdr = $this->_phpSheet->getPageMargins()->getHeader(); // Header Margin - - $numFtr = $this->_phpSheet->getPageMargins()->getFooter(); // Footer Margin - $iCopies = 0x01; // Number of copies - - $fLeftToRight = 0x0; // Print over then down - - // Page orientation - $fLandscape = ($this->_phpSheet->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? - 0x0 : 0x1; - - $fNoPls = 0x0; // Setup not read from printer - $fNoColor = 0x0; // Print black and white - $fDraft = 0x0; // Print draft quality - $fNotes = 0x0; // Print notes - $fNoOrient = 0x0; // Orientation not set - $fUsePage = 0x0; // Use custom starting page - - $grbit = $fLeftToRight; - $grbit |= $fLandscape << 1; - $grbit |= $fNoPls << 2; - $grbit |= $fNoColor << 3; - $grbit |= $fDraft << 4; - $grbit |= $fNotes << 5; - $grbit |= $fNoOrient << 6; - $grbit |= $fUsePage << 7; - - $numHdr = pack("d", $numHdr); - $numFtr = pack("d", $numFtr); - if (self::getByteOrder()) { // if it's Big Endian - $numHdr = strrev($numHdr); - $numFtr = strrev($numFtr); - } - - $header = pack("vv", $record, $length); - $data1 = pack("vvvvvvvv", $iPaperSize, - $iScale, - $iPageStart, - $iFitWidth, - $iFitHeight, - $grbit, - $iRes, - $iVRes); - $data2 = $numHdr.$numFtr; - $data3 = pack("v", $iCopies); - $this->_append($header . $data1 . $data2 . $data3); - } - - /** - * Store the header caption BIFF record. - */ - private function _writeHeader() - { - $record = 0x0014; // Record identifier - - /* removing for now - // need to fix character count (multibyte!) - if (strlen($this->_phpSheet->getHeaderFooter()->getOddHeader()) <= 255) { - $str = $this->_phpSheet->getHeaderFooter()->getOddHeader(); // header string - } else { - $str = ''; - } - */ - - $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddHeader()); - $length = strlen($recordData); - - $header = pack("vv", $record, $length); - - $this->_append($header . $recordData); - } - - /** - * Store the footer caption BIFF record. - */ - private function _writeFooter() - { - $record = 0x0015; // Record identifier - - /* removing for now - // need to fix character count (multibyte!) - if (strlen($this->_phpSheet->getHeaderFooter()->getOddFooter()) <= 255) { - $str = $this->_phpSheet->getHeaderFooter()->getOddFooter(); - } else { - $str = ''; - } - */ - - $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddFooter()); - $length = strlen($recordData); - - $header = pack("vv", $record, $length); - - $this->_append($header . $recordData); - } - - /** - * Store the horizontal centering HCENTER BIFF record. - * - * @access private - */ - private function _writeHcenter() - { - $record = 0x0083; // Record identifier - $length = 0x0002; // Bytes to follow - - $fHCenter = $this->_phpSheet->getPageSetup()->getHorizontalCentered() ? 1 : 0; // Horizontal centering - - $header = pack("vv", $record, $length); - $data = pack("v", $fHCenter); - - $this->_append($header.$data); - } - - /** - * Store the vertical centering VCENTER BIFF record. - */ - private function _writeVcenter() - { - $record = 0x0084; // Record identifier - $length = 0x0002; // Bytes to follow - - $fVCenter = $this->_phpSheet->getPageSetup()->getVerticalCentered() ? 1 : 0; // Horizontal centering - - $header = pack("vv", $record, $length); - $data = pack("v", $fVCenter); - $this->_append($header . $data); - } - - /** - * Store the LEFTMARGIN BIFF record. - */ - private function _writeMarginLeft() - { - $record = 0x0026; // Record identifier - $length = 0x0008; // Bytes to follow - - $margin = $this->_phpSheet->getPageMargins()->getLeft(); // Margin in inches - - $header = pack("vv", $record, $length); - $data = pack("d", $margin); - if (self::getByteOrder()) { // if it's Big Endian - $data = strrev($data); - } - - $this->_append($header . $data); - } - - /** - * Store the RIGHTMARGIN BIFF record. - */ - private function _writeMarginRight() - { - $record = 0x0027; // Record identifier - $length = 0x0008; // Bytes to follow - - $margin = $this->_phpSheet->getPageMargins()->getRight(); // Margin in inches - - $header = pack("vv", $record, $length); - $data = pack("d", $margin); - if (self::getByteOrder()) { // if it's Big Endian - $data = strrev($data); - } - - $this->_append($header . $data); - } - - /** - * Store the TOPMARGIN BIFF record. - */ - private function _writeMarginTop() - { - $record = 0x0028; // Record identifier - $length = 0x0008; // Bytes to follow - - $margin = $this->_phpSheet->getPageMargins()->getTop(); // Margin in inches - - $header = pack("vv", $record, $length); - $data = pack("d", $margin); - if (self::getByteOrder()) { // if it's Big Endian - $data = strrev($data); - } - - $this->_append($header . $data); - } - - /** - * Store the BOTTOMMARGIN BIFF record. - */ - private function _writeMarginBottom() - { - $record = 0x0029; // Record identifier - $length = 0x0008; // Bytes to follow - - $margin = $this->_phpSheet->getPageMargins()->getBottom(); // Margin in inches - - $header = pack("vv", $record, $length); - $data = pack("d", $margin); - if (self::getByteOrder()) { // if it's Big Endian - $data = strrev($data); - } - - $this->_append($header . $data); - } - - /** - * Write the PRINTHEADERS BIFF record. - */ - private function _writePrintHeaders() - { - $record = 0x002a; // Record identifier - $length = 0x0002; // Bytes to follow - - $fPrintRwCol = $this->_print_headers; // Boolean flag - - $header = pack("vv", $record, $length); - $data = pack("v", $fPrintRwCol); - $this->_append($header . $data); - } - - /** - * Write the PRINTGRIDLINES BIFF record. Must be used in conjunction with the - * GRIDSET record. - */ - private function _writePrintGridlines() - { - $record = 0x002b; // Record identifier - $length = 0x0002; // Bytes to follow - - $fPrintGrid = $this->_phpSheet->getPrintGridlines() ? 1 : 0; // Boolean flag - - $header = pack("vv", $record, $length); - $data = pack("v", $fPrintGrid); - $this->_append($header . $data); - } - - /** - * Write the GRIDSET BIFF record. Must be used in conjunction with the - * PRINTGRIDLINES record. - */ - private function _writeGridset() - { - $record = 0x0082; // Record identifier - $length = 0x0002; // Bytes to follow - - $fGridSet = !$this->_phpSheet->getPrintGridlines(); // Boolean flag - - $header = pack("vv", $record, $length); - $data = pack("v", $fGridSet); - $this->_append($header . $data); - } - - /** - * Write the AUTOFILTERINFO BIFF record. This is used to configure the number of autofilter select used in the sheet. - */ - private function _writeAutoFilterInfo(){ - $record = 0x009D; // Record identifier - $length = 0x0002; // Bytes to follow - - $rangeBounds = PHPExcel_Cell::rangeBoundaries($this->_phpSheet->getAutoFilter()->getRange()); - $iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0]; - - $header = pack("vv", $record, $length); - $data = pack("v", $iNumFilters); - $this->_append($header . $data); - } - - /** - * Write the GUTS BIFF record. This is used to configure the gutter margins - * where Excel outline symbols are displayed. The visibility of the gutters is - * controlled by a flag in WSBOOL. - * - * @see _writeWsbool() - */ - private function _writeGuts() - { - $record = 0x0080; // Record identifier - $length = 0x0008; // Bytes to follow - - $dxRwGut = 0x0000; // Size of row gutter - $dxColGut = 0x0000; // Size of col gutter - - // determine maximum row outline level - $maxRowOutlineLevel = 0; - foreach ($this->_phpSheet->getRowDimensions() as $rowDimension) { - $maxRowOutlineLevel = max($maxRowOutlineLevel, $rowDimension->getOutlineLevel()); - } - - $col_level = 0; - - // Calculate the maximum column outline level. The equivalent calculation - // for the row outline level is carried out in _writeRow(). - $colcount = count($this->_colinfo); - for ($i = 0; $i < $colcount; ++$i) { - $col_level = max($this->_colinfo[$i][5], $col_level); - } - - // Set the limits for the outline levels (0 <= x <= 7). - $col_level = max(0, min($col_level, 7)); - - // The displayed level is one greater than the max outline levels - if ($maxRowOutlineLevel) { - ++$maxRowOutlineLevel; - } - if ($col_level) { - ++$col_level; - } - - $header = pack("vv", $record, $length); - $data = pack("vvvv", $dxRwGut, $dxColGut, $maxRowOutlineLevel, $col_level); - - $this->_append($header.$data); - } - - /** - * Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction - * with the SETUP record. - */ - private function _writeWsbool() - { - $record = 0x0081; // Record identifier - $length = 0x0002; // Bytes to follow - $grbit = 0x0000; - - // The only option that is of interest is the flag for fit to page. So we - // set all the options in one go. - // - // Set the option flags - $grbit |= 0x0001; // Auto page breaks visible - if ($this->_outline_style) { - $grbit |= 0x0020; // Auto outline styles - } - if ($this->_phpSheet->getShowSummaryBelow()) { - $grbit |= 0x0040; // Outline summary below - } - if ($this->_phpSheet->getShowSummaryRight()) { - $grbit |= 0x0080; // Outline summary right - } - if ($this->_phpSheet->getPageSetup()->getFitToPage()) { - $grbit |= 0x0100; // Page setup fit to page - } - if ($this->_outline_on) { - $grbit |= 0x0400; // Outline symbols displayed - } - - $header = pack("vv", $record, $length); - $data = pack("v", $grbit); - $this->_append($header . $data); - } - - /** - * Write the HORIZONTALPAGEBREAKS and VERTICALPAGEBREAKS BIFF records. - */ - private function _writeBreaks() - { - // initialize - $vbreaks = array(); - $hbreaks = array(); - - foreach ($this->_phpSheet->getBreaks() as $cell => $breakType) { - // Fetch coordinates - $coordinates = PHPExcel_Cell::coordinateFromString($cell); - - // Decide what to do by the type of break - switch ($breakType) { - case PHPExcel_Worksheet::BREAK_COLUMN: - // Add to list of vertical breaks - $vbreaks[] = PHPExcel_Cell::columnIndexFromString($coordinates[0]) - 1; - break; - - case PHPExcel_Worksheet::BREAK_ROW: - // Add to list of horizontal breaks - $hbreaks[] = $coordinates[1]; - break; - - case PHPExcel_Worksheet::BREAK_NONE: - default: - // Nothing to do - break; - } - } - - //horizontal page breaks - if (!empty($hbreaks)) { - - // Sort and filter array of page breaks - sort($hbreaks, SORT_NUMERIC); - if ($hbreaks[0] == 0) { // don't use first break if it's 0 - array_shift($hbreaks); - } - - $record = 0x001b; // Record identifier - $cbrk = count($hbreaks); // Number of page breaks - $length = 2 + 6 * $cbrk; // Bytes to follow - - $header = pack("vv", $record, $length); - $data = pack("v", $cbrk); - - // Append each page break - foreach ($hbreaks as $hbreak) { - $data .= pack("vvv", $hbreak, 0x0000, 0x00ff); - } - - $this->_append($header . $data); - } - - // vertical page breaks - if (!empty($vbreaks)) { - - // 1000 vertical pagebreaks appears to be an internal Excel 5 limit. - // It is slightly higher in Excel 97/200, approx. 1026 - $vbreaks = array_slice($vbreaks, 0, 1000); - - // Sort and filter array of page breaks - sort($vbreaks, SORT_NUMERIC); - if ($vbreaks[0] == 0) { // don't use first break if it's 0 - array_shift($vbreaks); - } - - $record = 0x001a; // Record identifier - $cbrk = count($vbreaks); // Number of page breaks - $length = 2 + 6 * $cbrk; // Bytes to follow - - $header = pack("vv", $record, $length); - $data = pack("v", $cbrk); - - // Append each page break - foreach ($vbreaks as $vbreak) { - $data .= pack("vvv", $vbreak, 0x0000, 0xffff); - } - - $this->_append($header . $data); - } - } - - /** - * Set the Biff PROTECT record to indicate that the worksheet is protected. - */ - private function _writeProtect() - { - // Exit unless sheet protection has been specified - if (!$this->_phpSheet->getProtection()->getSheet()) { - return; - } - - $record = 0x0012; // Record identifier - $length = 0x0002; // Bytes to follow - - $fLock = 1; // Worksheet is protected - - $header = pack("vv", $record, $length); - $data = pack("v", $fLock); - - $this->_append($header.$data); - } - - /** - * Write SCENPROTECT - */ - private function _writeScenProtect() - { - // Exit if sheet protection is not active - if (!$this->_phpSheet->getProtection()->getSheet()) { - return; - } - - // Exit if scenarios are not protected - if (!$this->_phpSheet->getProtection()->getScenarios()) { - return; - } - - $record = 0x00DD; // Record identifier - $length = 0x0002; // Bytes to follow - - $header = pack('vv', $record, $length); - $data = pack('v', 1); - - $this->_append($header . $data); - } - - /** - * Write OBJECTPROTECT - */ - private function _writeObjectProtect() - { - // Exit if sheet protection is not active - if (!$this->_phpSheet->getProtection()->getSheet()) { - return; - } - - // Exit if objects are not protected - if (!$this->_phpSheet->getProtection()->getObjects()) { - return; - } - - $record = 0x0063; // Record identifier - $length = 0x0002; // Bytes to follow - - $header = pack('vv', $record, $length); - $data = pack('v', 1); - - $this->_append($header . $data); - } - - /** - * Write the worksheet PASSWORD record. - */ - private function _writePassword() - { - // Exit unless sheet protection and password have been specified - if (!$this->_phpSheet->getProtection()->getSheet() || !$this->_phpSheet->getProtection()->getPassword()) { - return; - } - - $record = 0x0013; // Record identifier - $length = 0x0002; // Bytes to follow - - $wPassword = hexdec($this->_phpSheet->getProtection()->getPassword()); // Encoded password - - $header = pack("vv", $record, $length); - $data = pack("v", $wPassword); - - $this->_append($header . $data); - } - - /** - * Insert a 24bit bitmap image in a worksheet. - * - * @access public - * @param integer $row The row we are going to insert the bitmap into - * @param integer $col The column we are going to insert the bitmap into - * @param mixed $bitmap The bitmap filename or GD-image resource - * @param integer $x The horizontal position (offset) of the image inside the cell. - * @param integer $y The vertical position (offset) of the image inside the cell. - * @param float $scale_x The horizontal scale - * @param float $scale_y The vertical scale - */ - function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) - { - $bitmap_array = (is_resource($bitmap) ? $this->_processBitmapGd($bitmap) : $this->_processBitmap($bitmap)); - list($width, $height, $size, $data) = $bitmap_array; //$this->_processBitmap($bitmap); - - // Scale the frame of the image. - $width *= $scale_x; - $height *= $scale_y; - - // Calculate the vertices of the image and write the OBJ record - $this->_positionImage($col, $row, $x, $y, $width, $height); - - // Write the IMDATA record to store the bitmap data - $record = 0x007f; - $length = 8 + $size; - $cf = 0x09; - $env = 0x01; - $lcb = $size; - - $header = pack("vvvvV", $record, $length, $cf, $env, $lcb); - $this->_append($header.$data); - } - - /** - * Calculate the vertices that define the position of the image as required by - * the OBJ record. - * - * +------------+------------+ - * | A | B | - * +-----+------------+------------+ - * | |(x1,y1) | | - * | 1 |(A1)._______|______ | - * | | | | | - * | | | | | - * +-----+----| BITMAP |-----+ - * | | | | | - * | 2 | |______________. | - * | | | (B2)| - * | | | (x2,y2)| - * +---- +------------+------------+ - * - * Example of a bitmap that covers some of the area from cell A1 to cell B2. - * - * Based on the width and height of the bitmap we need to calculate 8 vars: - * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. - * The width and height of the cells are also variable and have to be taken into - * account. - * The values of $col_start and $row_start are passed in from the calling - * function. The values of $col_end and $row_end are calculated by subtracting - * the width and height of the bitmap from the width and height of the - * underlying cells. - * The vertices are expressed as a percentage of the underlying cell width as - * follows (rhs values are in pixels): - * - * x1 = X / W *1024 - * y1 = Y / H *256 - * x2 = (X-1) / W *1024 - * y2 = (Y-1) / H *256 - * - * Where: X is distance from the left side of the underlying cell - * Y is distance from the top of the underlying cell - * W is the width of the cell - * H is the height of the cell - * The SDK incorrectly states that the height should be expressed as a - * percentage of 1024. - * - * @access private - * @param integer $col_start Col containing upper left corner of object - * @param integer $row_start Row containing top left corner of object - * @param integer $x1 Distance to left side of object - * @param integer $y1 Distance to top of object - * @param integer $width Width of image frame - * @param integer $height Height of image frame - */ - function _positionImage($col_start, $row_start, $x1, $y1, $width, $height) - { - // Initialise end cell to the same as the start cell - $col_end = $col_start; // Col containing lower right corner of object - $row_end = $row_start; // Row containing bottom right corner of object - - // Zero the specified offset if greater than the cell dimensions - if ($x1 >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { - $x1 = 0; - } - if ($y1 >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1)) { - $y1 = 0; - } - - $width = $width + $x1 -1; - $height = $height + $y1 -1; - - // Subtract the underlying cell widths to find the end cell of the image - while ($width >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { - $width -= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); - ++$col_end; - } - - // Subtract the underlying cell heights to find the end cell of the image - while ($height >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1)) { - $height -= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1); - ++$row_end; - } - - // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell - // with zero eight or width. - // - if (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { - return; - } - if (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { - return; - } - if (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) == 0) { - return; - } - if (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) == 0) { - return; - } - - // Convert the pixel values to the percentage value expected by Excel - $x1 = $x1 / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; - $y1 = $y1 / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) * 256; - $x2 = $width / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object - $y2 = $height / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) * 256; // Distance to bottom of object - - $this->_writeObjPicture($col_start, $x1, - $row_start, $y1, - $col_end, $x2, - $row_end, $y2); - } - - /** - * Store the OBJ record that precedes an IMDATA record. This could be generalise - * to support other Excel objects. - * - * @param integer $colL Column containing upper left corner of object - * @param integer $dxL Distance from left side of cell - * @param integer $rwT Row containing top left corner of object - * @param integer $dyT Distance from top of cell - * @param integer $colR Column containing lower right corner of object - * @param integer $dxR Distance from right of cell - * @param integer $rwB Row containing bottom right corner of object - * @param integer $dyB Distance from bottom of cell - */ - private function _writeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB) - { - $record = 0x005d; // Record identifier - $length = 0x003c; // Bytes to follow - - $cObj = 0x0001; // Count of objects in file (set to 1) - $OT = 0x0008; // Object type. 8 = Picture - $id = 0x0001; // Object ID - $grbit = 0x0614; // Option flags - - $cbMacro = 0x0000; // Length of FMLA structure - $Reserved1 = 0x0000; // Reserved - $Reserved2 = 0x0000; // Reserved - - $icvBack = 0x09; // Background colour - $icvFore = 0x09; // Foreground colour - $fls = 0x00; // Fill pattern - $fAuto = 0x00; // Automatic fill - $icv = 0x08; // Line colour - $lns = 0xff; // Line style - $lnw = 0x01; // Line weight - $fAutoB = 0x00; // Automatic border - $frs = 0x0000; // Frame style - $cf = 0x0009; // Image format, 9 = bitmap - $Reserved3 = 0x0000; // Reserved - $cbPictFmla = 0x0000; // Length of FMLA structure - $Reserved4 = 0x0000; // Reserved - $grbit2 = 0x0001; // Option flags - $Reserved5 = 0x0000; // Reserved - - - $header = pack("vv", $record, $length); - $data = pack("V", $cObj); - $data .= pack("v", $OT); - $data .= pack("v", $id); - $data .= pack("v", $grbit); - $data .= pack("v", $colL); - $data .= pack("v", $dxL); - $data .= pack("v", $rwT); - $data .= pack("v", $dyT); - $data .= pack("v", $colR); - $data .= pack("v", $dxR); - $data .= pack("v", $rwB); - $data .= pack("v", $dyB); - $data .= pack("v", $cbMacro); - $data .= pack("V", $Reserved1); - $data .= pack("v", $Reserved2); - $data .= pack("C", $icvBack); - $data .= pack("C", $icvFore); - $data .= pack("C", $fls); - $data .= pack("C", $fAuto); - $data .= pack("C", $icv); - $data .= pack("C", $lns); - $data .= pack("C", $lnw); - $data .= pack("C", $fAutoB); - $data .= pack("v", $frs); - $data .= pack("V", $cf); - $data .= pack("v", $Reserved3); - $data .= pack("v", $cbPictFmla); - $data .= pack("v", $Reserved4); - $data .= pack("v", $grbit2); - $data .= pack("V", $Reserved5); - - $this->_append($header . $data); - } - - /** - * Convert a GD-image into the internal format. - * - * @access private - * @param resource $image The image to process - * @return array Array with data and properties of the bitmap - */ - function _processBitmapGd($image) { - $width = imagesx($image); - $height = imagesy($image); - - $data = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); - for ($j=$height; $j--; ) { - for ($i=0; $i < $width; ++$i) { - $color = imagecolorsforindex($image, imagecolorat($image, $i, $j)); - foreach (array("red", "green", "blue") as $key) { - $color[$key] = $color[$key] + round((255 - $color[$key]) * $color["alpha"] / 127); - } - $data .= chr($color["blue"]) . chr($color["green"]) . chr($color["red"]); - } - if (3*$width % 4) { - $data .= str_repeat("\x00", 4 - 3*$width % 4); - } - } - - return array($width, $height, strlen($data), $data); - } - - /** - * Convert a 24 bit bitmap into the modified internal format used by Windows. - * This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the - * MSDN library. - * - * @access private - * @param string $bitmap The bitmap to process - * @return array Array with data and properties of the bitmap - */ - function _processBitmap($bitmap) - { - // Open file. - $bmp_fd = @fopen($bitmap,"rb"); - if (!$bmp_fd) { - throw new PHPExcel_Writer_Exception("Couldn't import $bitmap"); - } - - // Slurp the file into a string. - $data = fread($bmp_fd, filesize($bitmap)); - - // Check that the file is big enough to be a bitmap. - if (strlen($data) <= 0x36) { - throw new PHPExcel_Writer_Exception("$bitmap doesn't contain enough data.\n"); - } - - // The first 2 bytes are used to identify the bitmap. - $identity = unpack("A2ident", $data); - if ($identity['ident'] != "BM") { - throw new PHPExcel_Writer_Exception("$bitmap doesn't appear to be a valid bitmap image.\n"); - } - - // Remove bitmap data: ID. - $data = substr($data, 2); - - // Read and remove the bitmap size. This is more reliable than reading - // the data size at offset 0x22. - // - $size_array = unpack("Vsa", substr($data, 0, 4)); - $size = $size_array['sa']; - $data = substr($data, 4); - $size -= 0x36; // Subtract size of bitmap header. - $size += 0x0C; // Add size of BIFF header. - - // Remove bitmap data: reserved, offset, header length. - $data = substr($data, 12); - - // Read and remove the bitmap width and height. Verify the sizes. - $width_and_height = unpack("V2", substr($data, 0, 8)); - $width = $width_and_height[1]; - $height = $width_and_height[2]; - $data = substr($data, 8); - if ($width > 0xFFFF) { - throw new PHPExcel_Writer_Exception("$bitmap: largest image width supported is 65k.\n"); - } - if ($height > 0xFFFF) { - throw new PHPExcel_Writer_Exception("$bitmap: largest image height supported is 65k.\n"); - } - - // Read and remove the bitmap planes and bpp data. Verify them. - $planes_and_bitcount = unpack("v2", substr($data, 0, 4)); - $data = substr($data, 4); - if ($planes_and_bitcount[2] != 24) { // Bitcount - throw new PHPExcel_Writer_Exception("$bitmap isn't a 24bit true color bitmap.\n"); - } - if ($planes_and_bitcount[1] != 1) { - throw new PHPExcel_Writer_Exception("$bitmap: only 1 plane supported in bitmap image.\n"); - } - - // Read and remove the bitmap compression. Verify compression. - $compression = unpack("Vcomp", substr($data, 0, 4)); - $data = substr($data, 4); - - //$compression = 0; - if ($compression['comp'] != 0) { - throw new PHPExcel_Writer_Exception("$bitmap: compression not supported in bitmap image.\n"); - } - - // Remove bitmap data: data size, hres, vres, colours, imp. colours. - $data = substr($data, 20); - - // Add the BITMAPCOREHEADER data - $header = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); - $data = $header . $data; - - return (array($width, $height, $size, $data)); - } - - /** - * Store the window zoom factor. This should be a reduced fraction but for - * simplicity we will store all fractions with a numerator of 100. - */ - private function _writeZoom() - { - // If scale is 100 we don't need to write a record - if ($this->_phpSheet->getSheetView()->getZoomScale() == 100) { - return; - } - - $record = 0x00A0; // Record identifier - $length = 0x0004; // Bytes to follow - - $header = pack("vv", $record, $length); - $data = pack("vv", $this->_phpSheet->getSheetView()->getZoomScale(), 100); - $this->_append($header . $data); - } - - /** - * Get Escher object - * - * @return PHPExcel_Shared_Escher - */ - public function getEscher() - { - return $this->_escher; - } - - /** - * Set Escher object - * - * @param PHPExcel_Shared_Escher $pValue - */ - public function setEscher(PHPExcel_Shared_Escher $pValue = null) - { - $this->_escher = $pValue; - } - - /** - * Write MSODRAWING record - */ - private function _writeMsoDrawing() - { - // write the Escher stream if necessary - if (isset($this->_escher)) { - $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); - $data = $writer->close(); - $spOffsets = $writer->getSpOffsets(); - $spTypes = $writer->getSpTypes(); - // write the neccesary MSODRAWING, OBJ records - - // split the Escher stream - $spOffsets[0] = 0; - $nm = count($spOffsets) - 1; // number of shapes excluding first shape - for ($i = 1; $i <= $nm; ++$i) { - // MSODRAWING record - $record = 0x00EC; // Record identifier - - // chunk of Escher stream for one shape - $dataChunk = substr($data, $spOffsets[$i -1], $spOffsets[$i] - $spOffsets[$i - 1]); - - $length = strlen($dataChunk); - $header = pack("vv", $record, $length); - - $this->_append($header . $dataChunk); - - // OBJ record - $record = 0x005D; // record identifier - $objData = ''; - - // ftCmo - if($spTypes[$i] == 0x00C9){ - // Add ftCmo (common object data) subobject - $objData .= - pack('vvvvvVVV' - , 0x0015 // 0x0015 = ftCmo - , 0x0012 // length of ftCmo data - , 0x0014 // object type, 0x0014 = filter - , $i // object id number, Excel seems to use 1-based index, local for the sheet - , 0x2101 // option flags, 0x2001 is what OpenOffice.org uses - , 0 // reserved - , 0 // reserved - , 0 // reserved - ); - - // Add ftSbs Scroll bar subobject - $objData .= pack('vv', 0x00C, 0x0014); - $objData .= pack('H*', '0000000000000000640001000A00000010000100'); - // Add ftLbsData (List box data) subobject - $objData .= pack('vv', 0x0013, 0x1FEE); - $objData .= pack('H*', '00000000010001030000020008005700'); - } - else { - // Add ftCmo (common object data) subobject - $objData .= - pack('vvvvvVVV' - , 0x0015 // 0x0015 = ftCmo - , 0x0012 // length of ftCmo data - , 0x0008 // object type, 0x0008 = picture - , $i // object id number, Excel seems to use 1-based index, local for the sheet - , 0x6011 // option flags, 0x6011 is what OpenOffice.org uses - , 0 // reserved - , 0 // reserved - , 0 // reserved - ); - } - - // ftEnd - $objData .= - pack('vv' - , 0x0000 // 0x0000 = ftEnd - , 0x0000 // length of ftEnd data - ); - - $length = strlen($objData); - $header = pack('vv', $record, $length); - $this->_append($header . $objData); - } - } - } - - /** - * Store the DATAVALIDATIONS and DATAVALIDATION records. - */ - private function _writeDataValidity() - { - // Datavalidation collection - $dataValidationCollection = $this->_phpSheet->getDataValidationCollection(); - - // Write data validations? - if (!empty($dataValidationCollection)) { - - // DATAVALIDATIONS record - $record = 0x01B2; // Record identifier - $length = 0x0012; // Bytes to follow - - $grbit = 0x0000; // Prompt box at cell, no cached validity data at DV records - $horPos = 0x00000000; // Horizontal position of prompt box, if fixed position - $verPos = 0x00000000; // Vertical position of prompt box, if fixed position - $objId = 0xFFFFFFFF; // Object identifier of drop down arrow object, or -1 if not visible - - $header = pack('vv', $record, $length); - $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId, - count($dataValidationCollection)); - $this->_append($header.$data); - - // DATAVALIDATION records - $record = 0x01BE; // Record identifier - - foreach ($dataValidationCollection as $cellCoordinate => $dataValidation) { - // initialize record data - $data = ''; - - // options - $options = 0x00000000; - - // data type - $type = $dataValidation->getType(); - switch ($type) { - case PHPExcel_Cell_DataValidation::TYPE_NONE: $type = 0x00; break; - case PHPExcel_Cell_DataValidation::TYPE_WHOLE: $type = 0x01; break; - case PHPExcel_Cell_DataValidation::TYPE_DECIMAL: $type = 0x02; break; - case PHPExcel_Cell_DataValidation::TYPE_LIST: $type = 0x03; break; - case PHPExcel_Cell_DataValidation::TYPE_DATE: $type = 0x04; break; - case PHPExcel_Cell_DataValidation::TYPE_TIME: $type = 0x05; break; - case PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH: $type = 0x06; break; - case PHPExcel_Cell_DataValidation::TYPE_CUSTOM: $type = 0x07; break; - } - $options |= $type << 0; - - // error style - $errorStyle = $dataValidation->getType(); - switch ($errorStyle) { - case PHPExcel_Cell_DataValidation::STYLE_STOP: $errorStyle = 0x00; break; - case PHPExcel_Cell_DataValidation::STYLE_WARNING: $errorStyle = 0x01; break; - case PHPExcel_Cell_DataValidation::STYLE_INFORMATION: $errorStyle = 0x02; break; - } - $options |= $errorStyle << 4; - - // explicit formula? - if ($type == 0x03 && preg_match('/^\".*\"$/', $dataValidation->getFormula1())) { - $options |= 0x01 << 7; - } - - // empty cells allowed - $options |= $dataValidation->getAllowBlank() << 8; - - // show drop down - $options |= (!$dataValidation->getShowDropDown()) << 9; - - // show input message - $options |= $dataValidation->getShowInputMessage() << 18; - - // show error message - $options |= $dataValidation->getShowErrorMessage() << 19; - - // condition operator - $operator = $dataValidation->getOperator(); - switch ($operator) { - case PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN: $operator = 0x00 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN: $operator = 0x01 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_EQUAL: $operator = 0x02 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL: $operator = 0x03 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN: $operator = 0x04 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN: $operator = 0x05 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL: $operator = 0x06; break; - case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL: $operator = 0x07 ; break; - } - $options |= $operator << 20; - - $data = pack('V', $options); - - // prompt title - $promptTitle = $dataValidation->getPromptTitle() !== '' ? - $dataValidation->getPromptTitle() : chr(0); - $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($promptTitle); - - // error title - $errorTitle = $dataValidation->getErrorTitle() !== '' ? - $dataValidation->getErrorTitle() : chr(0); - $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($errorTitle); - - // prompt text - $prompt = $dataValidation->getPrompt() !== '' ? - $dataValidation->getPrompt() : chr(0); - $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($prompt); - - // error text - $error = $dataValidation->getError() !== '' ? - $dataValidation->getError() : chr(0); - $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($error); - - // formula 1 - try { - $formula1 = $dataValidation->getFormula1(); - if ($type == 0x03) { // list type - $formula1 = str_replace(',', chr(0), $formula1); - } - $this->_parser->parse($formula1); - $formula1 = $this->_parser->toReversePolish(); - $sz1 = strlen($formula1); - - } catch(PHPExcel_Exception $e) { - $sz1 = 0; - $formula1 = ''; - } - $data .= pack('vv', $sz1, 0x0000); - $data .= $formula1; - - // formula 2 - try { - $formula2 = $dataValidation->getFormula2(); - if ($formula2 === '') { - throw new PHPExcel_Writer_Exception('No formula2'); - } - $this->_parser->parse($formula2); - $formula2 = $this->_parser->toReversePolish(); - $sz2 = strlen($formula2); - - } catch(PHPExcel_Exception $e) { - $sz2 = 0; - $formula2 = ''; - } - $data .= pack('vv', $sz2, 0x0000); - $data .= $formula2; - - // cell range address list - $data .= pack('v', 0x0001); - $data .= $this->_writeBIFF8CellRangeAddressFixed($cellCoordinate); - - $length = strlen($data); - $header = pack("vv", $record, $length); - - $this->_append($header . $data); - } - } - } - - /** - * Map Error code - * - * @param string $errorCode - * @return int - */ - private static function _mapErrorCode($errorCode) { - switch ($errorCode) { - case '#NULL!': return 0x00; - case '#DIV/0!': return 0x07; - case '#VALUE!': return 0x0F; - case '#REF!': return 0x17; - case '#NAME?': return 0x1D; - case '#NUM!': return 0x24; - case '#N/A': return 0x2A; - } - - return 0; - } - - /** - * Write PLV Record - */ - private function _writePageLayoutView(){ - $record = 0x088B; // Record identifier - $length = 0x0010; // Bytes to follow - - $rt = 0x088B; // 2 - $grbitFrt = 0x0000; // 2 - $reserved = 0x0000000000000000; // 8 - $wScalvePLV = $this->_phpSheet->getSheetView()->getZoomScale(); // 2 - - // The options flags that comprise $grbit - if($this->_phpSheet->getSheetView()->getView() == PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT){ - $fPageLayoutView = 1; - } else { - $fPageLayoutView = 0; - } - $fRulerVisible = 0; - $fWhitespaceHidden = 0; - - $grbit = $fPageLayoutView; // 2 - $grbit |= $fRulerVisible << 1; - $grbit |= $fWhitespaceHidden << 3; - - $header = pack("vv", $record, $length); - $data = pack("vvVVvv", $rt, $grbitFrt, 0x00000000, 0x00000000, $wScalvePLV, $grbit); - $this->_append($header . $data); - } - - /** - * Write CFRule Record - * @param PHPExcel_Style_Conditional $conditional - */ - private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ - $record = 0x01B1; // Record identifier - - // $type : Type of the CF - // $operatorType : Comparison operator - if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION){ - $type = 0x02; - $operatorType = 0x00; - } else if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ - $type = 0x01; - - switch ($conditional->getOperatorType()){ - case PHPExcel_Style_Conditional::OPERATOR_NONE: - $operatorType = 0x00; - break; - case PHPExcel_Style_Conditional::OPERATOR_EQUAL: - $operatorType = 0x03; - break; - case PHPExcel_Style_Conditional::OPERATOR_GREATERTHAN: - $operatorType = 0x05; - break; - case PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL: - $operatorType = 0x07; - break; - case PHPExcel_Style_Conditional::OPERATOR_LESSTHAN: - $operatorType = 0x06; - break; - case PHPExcel_Style_Conditional::OPERATOR_LESSTHANOREQUAL: - $operatorType = 0x08; - break; - case PHPExcel_Style_Conditional::OPERATOR_NOTEQUAL: - $operatorType = 0x04; - break; - case PHPExcel_Style_Conditional::OPERATOR_BETWEEN: - $operatorType = 0x01; - break; - // not OPERATOR_NOTBETWEEN 0x02 - } - } - - // $szValue1 : size of the formula data for first value or formula - // $szValue2 : size of the formula data for second value or formula - $arrConditions = $conditional->getConditions(); - $numConditions = sizeof($arrConditions); - if($numConditions == 1){ - $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); - $szValue2 = 0x0000; - $operand1 = pack('Cv', 0x1E, $arrConditions[0]); - $operand2 = null; - } else if($numConditions == 2 && ($conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BETWEEN)){ - $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); - $szValue2 = ($arrConditions[1] <= 65535 ? 3 : 0x0000); - $operand1 = pack('Cv', 0x1E, $arrConditions[0]); - $operand2 = pack('Cv', 0x1E, $arrConditions[1]); - } else { - $szValue1 = 0x0000; - $szValue2 = 0x0000; - $operand1 = null; - $operand2 = null; - } - - // $flags : Option flags - // Alignment - $bAlignHz = ($conditional->getStyle()->getAlignment()->getHorizontal() == null ? 1 : 0); - $bAlignVt = ($conditional->getStyle()->getAlignment()->getVertical() == null ? 1 : 0); - $bAlignWrapTx = ($conditional->getStyle()->getAlignment()->getWrapText() == false ? 1 : 0); - $bTxRotation = ($conditional->getStyle()->getAlignment()->getTextRotation() == null ? 1 : 0); - $bIndent = ($conditional->getStyle()->getAlignment()->getIndent() == 0 ? 1 : 0); - $bShrinkToFit = ($conditional->getStyle()->getAlignment()->getShrinkToFit() == false ? 1 : 0); - if($bAlignHz == 0 || $bAlignVt == 0 || $bAlignWrapTx == 0 || $bTxRotation == 0 || $bIndent == 0 || $bShrinkToFit == 0){ - $bFormatAlign = 1; - } else { - $bFormatAlign = 0; - } - // Protection - $bProtLocked = ($conditional->getStyle()->getProtection()->getLocked() == null ? 1 : 0); - $bProtHidden = ($conditional->getStyle()->getProtection()->getHidden() == null ? 1 : 0); - if($bProtLocked == 0 || $bProtHidden == 0){ - $bFormatProt = 1; - } else { - $bFormatProt = 0; - } - // Border - $bBorderLeft = ($conditional->getStyle()->getBorders()->getLeft()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK - && $conditional->getStyle()->getBorders()->getLeft()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); - $bBorderRight = ($conditional->getStyle()->getBorders()->getRight()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK - && $conditional->getStyle()->getBorders()->getRight()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); - $bBorderTop = ($conditional->getStyle()->getBorders()->getTop()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK - && $conditional->getStyle()->getBorders()->getTop()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); - $bBorderBottom = ($conditional->getStyle()->getBorders()->getBottom()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK - && $conditional->getStyle()->getBorders()->getBottom()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); - if($bBorderLeft == 0 || $bBorderRight == 0 || $bBorderTop == 0 || $bBorderBottom == 0){ - $bFormatBorder = 1; - } else { - $bFormatBorder = 0; - } - // Pattern - $bFillStyle = ($conditional->getStyle()->getFill()->getFillType() == null ? 0 : 1); - $bFillColor = ($conditional->getStyle()->getFill()->getStartColor()->getARGB() == null ? 0 : 1); - $bFillColorBg = ($conditional->getStyle()->getFill()->getEndColor()->getARGB() == null ? 0 : 1); - if($bFillStyle == 0 || $bFillColor == 0 || $bFillColorBg == 0){ - $bFormatFill = 1; - } else { - $bFormatFill = 0; - } - // Font - if($conditional->getStyle()->getFont()->getName() != null - || $conditional->getStyle()->getFont()->getSize() != null - || $conditional->getStyle()->getFont()->getBold() != null - || $conditional->getStyle()->getFont()->getItalic() != null - || $conditional->getStyle()->getFont()->getSuperScript() != null - || $conditional->getStyle()->getFont()->getSubScript() != null - || $conditional->getStyle()->getFont()->getUnderline() != null - || $conditional->getStyle()->getFont()->getStrikethrough() != null - || $conditional->getStyle()->getFont()->getColor()->getARGB() != null){ - $bFormatFont = 1; - } else { - $bFormatFont = 0; - } - // Alignment - $flags = 0; - $flags |= (1 == $bAlignHz ? 0x00000001 : 0); - $flags |= (1 == $bAlignVt ? 0x00000002 : 0); - $flags |= (1 == $bAlignWrapTx ? 0x00000004 : 0); - $flags |= (1 == $bTxRotation ? 0x00000008 : 0); - // Justify last line flag - $flags |= (1 == 1 ? 0x00000010 : 0); - $flags |= (1 == $bIndent ? 0x00000020 : 0); - $flags |= (1 == $bShrinkToFit ? 0x00000040 : 0); - // Default - $flags |= (1 == 1 ? 0x00000080 : 0); - // Protection - $flags |= (1 == $bProtLocked ? 0x00000100 : 0); - $flags |= (1 == $bProtHidden ? 0x00000200 : 0); - // Border - $flags |= (1 == $bBorderLeft ? 0x00000400 : 0); - $flags |= (1 == $bBorderRight ? 0x00000800 : 0); - $flags |= (1 == $bBorderTop ? 0x00001000 : 0); - $flags |= (1 == $bBorderBottom ? 0x00002000 : 0); - $flags |= (1 == 1 ? 0x00004000 : 0); // Top left to Bottom right border - $flags |= (1 == 1 ? 0x00008000 : 0); // Bottom left to Top right border - // Pattern - $flags |= (1 == $bFillStyle ? 0x00010000 : 0); - $flags |= (1 == $bFillColor ? 0x00020000 : 0); - $flags |= (1 == $bFillColorBg ? 0x00040000 : 0); - $flags |= (1 == 1 ? 0x00380000 : 0); - // Font - $flags |= (1 == $bFormatFont ? 0x04000000 : 0); - // Alignment : - $flags |= (1 == $bFormatAlign ? 0x08000000 : 0); - // Border - $flags |= (1 == $bFormatBorder ? 0x10000000 : 0); - // Pattern - $flags |= (1 == $bFormatFill ? 0x20000000 : 0); - // Protection - $flags |= (1 == $bFormatProt ? 0x40000000 : 0); - // Text direction - $flags |= (1 == 0 ? 0x80000000 : 0); - - // Data Blocks - if($bFormatFont == 1){ - // Font Name - if($conditional->getStyle()->getFont()->getName() == null){ - $dataBlockFont = pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); - $dataBlockFont .= pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); - } else { - $dataBlockFont = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($conditional->getStyle()->getFont()->getName()); - } - // Font Size - if($conditional->getStyle()->getFont()->getSize() == null){ - $dataBlockFont .= pack('V', 20 * 11); - } else { - $dataBlockFont .= pack('V', 20 * $conditional->getStyle()->getFont()->getSize()); - } - // Font Options - $dataBlockFont .= pack('V', 0); - // Font weight - if($conditional->getStyle()->getFont()->getBold() == true){ - $dataBlockFont .= pack('v', 0x02BC); - } else { - $dataBlockFont .= pack('v', 0x0190); - } - // Escapement type - if($conditional->getStyle()->getFont()->getSubScript() == true){ - $dataBlockFont .= pack('v', 0x02); - $fontEscapement = 0; - } else if($conditional->getStyle()->getFont()->getSuperScript() == true){ - $dataBlockFont .= pack('v', 0x01); - $fontEscapement = 0; - } else { - $dataBlockFont .= pack('v', 0x00); - $fontEscapement = 1; - } - // Underline type - switch ($conditional->getStyle()->getFont()->getUnderline()){ - case PHPExcel_Style_Font::UNDERLINE_NONE : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 0; break; - case PHPExcel_Style_Font::UNDERLINE_DOUBLE : $dataBlockFont .= pack('C', 0x02); $fontUnderline = 0; break; - case PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING : $dataBlockFont .= pack('C', 0x22); $fontUnderline = 0; break; - case PHPExcel_Style_Font::UNDERLINE_SINGLE : $dataBlockFont .= pack('C', 0x01); $fontUnderline = 0; break; - case PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING : $dataBlockFont .= pack('C', 0x21); $fontUnderline = 0; break; - default : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 1; break; - } - // Not used (3) - $dataBlockFont .= pack('vC', 0x0000, 0x00); - // Font color index - switch ($conditional->getStyle()->getFont()->getColor()->getRGB()) { - case '000000': $colorIdx = 0x08; break; - case 'FFFFFF': $colorIdx = 0x09; break; - case 'FF0000': $colorIdx = 0x0A; break; - case '00FF00': $colorIdx = 0x0B; break; - case '0000FF': $colorIdx = 0x0C; break; - case 'FFFF00': $colorIdx = 0x0D; break; - case 'FF00FF': $colorIdx = 0x0E; break; - case '00FFFF': $colorIdx = 0x0F; break; - case '800000': $colorIdx = 0x10; break; - case '008000': $colorIdx = 0x11; break; - case '000080': $colorIdx = 0x12; break; - case '808000': $colorIdx = 0x13; break; - case '800080': $colorIdx = 0x14; break; - case '008080': $colorIdx = 0x15; break; - case 'C0C0C0': $colorIdx = 0x16; break; - case '808080': $colorIdx = 0x17; break; - case '9999FF': $colorIdx = 0x18; break; - case '993366': $colorIdx = 0x19; break; - case 'FFFFCC': $colorIdx = 0x1A; break; - case 'CCFFFF': $colorIdx = 0x1B; break; - case '660066': $colorIdx = 0x1C; break; - case 'FF8080': $colorIdx = 0x1D; break; - case '0066CC': $colorIdx = 0x1E; break; - case 'CCCCFF': $colorIdx = 0x1F; break; - case '000080': $colorIdx = 0x20; break; - case 'FF00FF': $colorIdx = 0x21; break; - case 'FFFF00': $colorIdx = 0x22; break; - case '00FFFF': $colorIdx = 0x23; break; - case '800080': $colorIdx = 0x24; break; - case '800000': $colorIdx = 0x25; break; - case '008080': $colorIdx = 0x26; break; - case '0000FF': $colorIdx = 0x27; break; - case '00CCFF': $colorIdx = 0x28; break; - case 'CCFFFF': $colorIdx = 0x29; break; - case 'CCFFCC': $colorIdx = 0x2A; break; - case 'FFFF99': $colorIdx = 0x2B; break; - case '99CCFF': $colorIdx = 0x2C; break; - case 'FF99CC': $colorIdx = 0x2D; break; - case 'CC99FF': $colorIdx = 0x2E; break; - case 'FFCC99': $colorIdx = 0x2F; break; - case '3366FF': $colorIdx = 0x30; break; - case '33CCCC': $colorIdx = 0x31; break; - case '99CC00': $colorIdx = 0x32; break; - case 'FFCC00': $colorIdx = 0x33; break; - case 'FF9900': $colorIdx = 0x34; break; - case 'FF6600': $colorIdx = 0x35; break; - case '666699': $colorIdx = 0x36; break; - case '969696': $colorIdx = 0x37; break; - case '003366': $colorIdx = 0x38; break; - case '339966': $colorIdx = 0x39; break; - case '003300': $colorIdx = 0x3A; break; - case '333300': $colorIdx = 0x3B; break; - case '993300': $colorIdx = 0x3C; break; - case '993366': $colorIdx = 0x3D; break; - case '333399': $colorIdx = 0x3E; break; - case '333333': $colorIdx = 0x3F; break; - default: $colorIdx = 0x00; break; - } - $dataBlockFont .= pack('V', $colorIdx); - // Not used (4) - $dataBlockFont .= pack('V', 0x00000000); - // Options flags for modified font attributes - $optionsFlags = 0; - $optionsFlagsBold = ($conditional->getStyle()->getFont()->getBold() == null ? 1 : 0); - $optionsFlags |= (1 == $optionsFlagsBold ? 0x00000002 : 0); - $optionsFlags |= (1 == 1 ? 0x00000008 : 0); - $optionsFlags |= (1 == 1 ? 0x00000010 : 0); - $optionsFlags |= (1 == 0 ? 0x00000020 : 0); - $optionsFlags |= (1 == 1 ? 0x00000080 : 0); - $dataBlockFont .= pack('V', $optionsFlags); - // Escapement type - $dataBlockFont .= pack('V', $fontEscapement); - // Underline type - $dataBlockFont .= pack('V', $fontUnderline); - // Always - $dataBlockFont .= pack('V', 0x00000000); - // Always - $dataBlockFont .= pack('V', 0x00000000); - // Not used (8) - $dataBlockFont .= pack('VV', 0x00000000, 0x00000000); - // Always - $dataBlockFont .= pack('v', 0x0001); - } - if($bFormatAlign == 1){ - $blockAlign = 0; - // Alignment and text break - switch ($conditional->getStyle()->getAlignment()->getHorizontal()){ - case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL : $blockAlign = 0; break; - case PHPExcel_Style_Alignment::HORIZONTAL_LEFT : $blockAlign = 1; break; - case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT : $blockAlign = 3; break; - case PHPExcel_Style_Alignment::HORIZONTAL_CENTER : $blockAlign = 2; break; - case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS : $blockAlign = 6; break; - case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY : $blockAlign = 5; break; - } - if($conditional->getStyle()->getAlignment()->getWrapText() == true){ - $blockAlign |= 1 << 3; - } else { - $blockAlign |= 0 << 3; - } - switch ($conditional->getStyle()->getAlignment()->getVertical()){ - case PHPExcel_Style_Alignment::VERTICAL_BOTTOM : $blockAlign = 2 << 4; break; - case PHPExcel_Style_Alignment::VERTICAL_TOP : $blockAlign = 0 << 4; break; - case PHPExcel_Style_Alignment::VERTICAL_CENTER : $blockAlign = 1 << 4; break; - case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY : $blockAlign = 3 << 4; break; - } - $blockAlign |= 0 << 7; - - // Text rotation angle - $blockRotation = $conditional->getStyle()->getAlignment()->getTextRotation(); - - // Indentation - $blockIndent = $conditional->getStyle()->getAlignment()->getIndent(); - if($conditional->getStyle()->getAlignment()->getShrinkToFit() == true){ - $blockIndent |= 1 << 4; - } else { - $blockIndent |= 0 << 4; - } - $blockIndent |= 0 << 6; - - // Relative indentation - $blockIndentRelative = 255; - - $dataBlockAlign = pack('CCvvv', $blockAlign, $blockRotation, $blockIndent, $blockIndentRelative, 0x0000); - } - if($bFormatBorder == 1){ - $blockLineStyle = 0; - switch ($conditional->getStyle()->getBorders()->getLeft()->getBorderStyle()){ - case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00; break; - case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01; break; - case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02; break; - case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03; break; - case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04; break; - case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05; break; - case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06; break; - case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08; break; - case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A; break; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C; break; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D; break; - } - switch ($conditional->getStyle()->getBorders()->getRight()->getBorderStyle()){ - case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 4; break; - case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 4; break; - case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 4; break; - case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 4; break; - case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 4; break; - case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 4; break; - case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 4; break; - case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 4; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 4; break; - case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 4; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 4; break; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 4; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 4; break; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 4; break; - } - switch ($conditional->getStyle()->getBorders()->getTop()->getBorderStyle()){ - case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 8; break; - case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 8; break; - case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 8; break; - case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 8; break; - case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 8; break; - case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 8; break; - case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 8; break; - case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 8; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 8; break; - case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 8; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 8; break; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 8; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 8; break; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 8; break; - } - switch ($conditional->getStyle()->getBorders()->getBottom()->getBorderStyle()){ - case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 12; break; - case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 12; break; - case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 12; break; - case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 12; break; - case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 12; break; - case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 12; break; - case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 12; break; - case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 12; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 12; break; - case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 12; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 12; break; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 12; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 12; break; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 12; break; - } - //@todo _writeCFRule() => $blockLineStyle => Index Color for left line - //@todo _writeCFRule() => $blockLineStyle => Index Color for right line - //@todo _writeCFRule() => $blockLineStyle => Top-left to bottom-right on/off - //@todo _writeCFRule() => $blockLineStyle => Bottom-left to top-right on/off - $blockColor = 0; - //@todo _writeCFRule() => $blockColor => Index Color for top line - //@todo _writeCFRule() => $blockColor => Index Color for bottom line - //@todo _writeCFRule() => $blockColor => Index Color for diagonal line - switch ($conditional->getStyle()->getBorders()->getDiagonal()->getBorderStyle()){ - case PHPExcel_Style_Border::BORDER_NONE : $blockColor |= 0x00 << 21; break; - case PHPExcel_Style_Border::BORDER_THIN : $blockColor |= 0x01 << 21; break; - case PHPExcel_Style_Border::BORDER_MEDIUM : $blockColor |= 0x02 << 21; break; - case PHPExcel_Style_Border::BORDER_DASHED : $blockColor |= 0x03 << 21; break; - case PHPExcel_Style_Border::BORDER_DOTTED : $blockColor |= 0x04 << 21; break; - case PHPExcel_Style_Border::BORDER_THICK : $blockColor |= 0x05 << 21; break; - case PHPExcel_Style_Border::BORDER_DOUBLE : $blockColor |= 0x06 << 21; break; - case PHPExcel_Style_Border::BORDER_HAIR : $blockColor |= 0x07 << 21; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockColor |= 0x08 << 21; break; - case PHPExcel_Style_Border::BORDER_DASHDOT : $blockColor |= 0x09 << 21; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockColor |= 0x0A << 21; break; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockColor |= 0x0B << 21; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockColor |= 0x0C << 21; break; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockColor |= 0x0D << 21; break; - } - $dataBlockBorder = pack('vv', $blockLineStyle, $blockColor); - } - if($bFormatFill == 1){ - // Fill Patern Style - $blockFillPatternStyle = 0; - switch ($conditional->getStyle()->getFill()->getFillType()){ - case PHPExcel_Style_Fill::FILL_NONE : $blockFillPatternStyle = 0x00; break; - case PHPExcel_Style_Fill::FILL_SOLID : $blockFillPatternStyle = 0x01; break; - case PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY : $blockFillPatternStyle = 0x02; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY : $blockFillPatternStyle = 0x03; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY : $blockFillPatternStyle = 0x04; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL : $blockFillPatternStyle = 0x05; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL : $blockFillPatternStyle = 0x06; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN : $blockFillPatternStyle = 0x07; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKUP : $blockFillPatternStyle = 0x08; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID : $blockFillPatternStyle = 0x09; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS : $blockFillPatternStyle = 0x0A; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL : $blockFillPatternStyle = 0x0B; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL : $blockFillPatternStyle = 0x0C; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN : $blockFillPatternStyle = 0x0D; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP : $blockFillPatternStyle = 0x0E; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID : $blockFillPatternStyle = 0x0F; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS : $blockFillPatternStyle = 0x10; break; - case PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 : $blockFillPatternStyle = 0x11; break; - case PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 : $blockFillPatternStyle = 0x12; break; - case PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR : $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 - case PHPExcel_Style_Fill::FILL_GRADIENT_PATH : $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 - default : $blockFillPatternStyle = 0x00; break; - } - // Color - switch ($conditional->getStyle()->getFill()->getStartColor()->getRGB()) { - case '000000': $colorIdxBg = 0x08; break; - case 'FFFFFF': $colorIdxBg = 0x09; break; - case 'FF0000': $colorIdxBg = 0x0A; break; - case '00FF00': $colorIdxBg = 0x0B; break; - case '0000FF': $colorIdxBg = 0x0C; break; - case 'FFFF00': $colorIdxBg = 0x0D; break; - case 'FF00FF': $colorIdxBg = 0x0E; break; - case '00FFFF': $colorIdxBg = 0x0F; break; - case '800000': $colorIdxBg = 0x10; break; - case '008000': $colorIdxBg = 0x11; break; - case '000080': $colorIdxBg = 0x12; break; - case '808000': $colorIdxBg = 0x13; break; - case '800080': $colorIdxBg = 0x14; break; - case '008080': $colorIdxBg = 0x15; break; - case 'C0C0C0': $colorIdxBg = 0x16; break; - case '808080': $colorIdxBg = 0x17; break; - case '9999FF': $colorIdxBg = 0x18; break; - case '993366': $colorIdxBg = 0x19; break; - case 'FFFFCC': $colorIdxBg = 0x1A; break; - case 'CCFFFF': $colorIdxBg = 0x1B; break; - case '660066': $colorIdxBg = 0x1C; break; - case 'FF8080': $colorIdxBg = 0x1D; break; - case '0066CC': $colorIdxBg = 0x1E; break; - case 'CCCCFF': $colorIdxBg = 0x1F; break; - case '000080': $colorIdxBg = 0x20; break; - case 'FF00FF': $colorIdxBg = 0x21; break; - case 'FFFF00': $colorIdxBg = 0x22; break; - case '00FFFF': $colorIdxBg = 0x23; break; - case '800080': $colorIdxBg = 0x24; break; - case '800000': $colorIdxBg = 0x25; break; - case '008080': $colorIdxBg = 0x26; break; - case '0000FF': $colorIdxBg = 0x27; break; - case '00CCFF': $colorIdxBg = 0x28; break; - case 'CCFFFF': $colorIdxBg = 0x29; break; - case 'CCFFCC': $colorIdxBg = 0x2A; break; - case 'FFFF99': $colorIdxBg = 0x2B; break; - case '99CCFF': $colorIdxBg = 0x2C; break; - case 'FF99CC': $colorIdxBg = 0x2D; break; - case 'CC99FF': $colorIdxBg = 0x2E; break; - case 'FFCC99': $colorIdxBg = 0x2F; break; - case '3366FF': $colorIdxBg = 0x30; break; - case '33CCCC': $colorIdxBg = 0x31; break; - case '99CC00': $colorIdxBg = 0x32; break; - case 'FFCC00': $colorIdxBg = 0x33; break; - case 'FF9900': $colorIdxBg = 0x34; break; - case 'FF6600': $colorIdxBg = 0x35; break; - case '666699': $colorIdxBg = 0x36; break; - case '969696': $colorIdxBg = 0x37; break; - case '003366': $colorIdxBg = 0x38; break; - case '339966': $colorIdxBg = 0x39; break; - case '003300': $colorIdxBg = 0x3A; break; - case '333300': $colorIdxBg = 0x3B; break; - case '993300': $colorIdxBg = 0x3C; break; - case '993366': $colorIdxBg = 0x3D; break; - case '333399': $colorIdxBg = 0x3E; break; - case '333333': $colorIdxBg = 0x3F; break; - default: $colorIdxBg = 0x41; break; - } - // Fg Color - switch ($conditional->getStyle()->getFill()->getEndColor()->getRGB()) { - case '000000': $colorIdxFg = 0x08; break; - case 'FFFFFF': $colorIdxFg = 0x09; break; - case 'FF0000': $colorIdxFg = 0x0A; break; - case '00FF00': $colorIdxFg = 0x0B; break; - case '0000FF': $colorIdxFg = 0x0C; break; - case 'FFFF00': $colorIdxFg = 0x0D; break; - case 'FF00FF': $colorIdxFg = 0x0E; break; - case '00FFFF': $colorIdxFg = 0x0F; break; - case '800000': $colorIdxFg = 0x10; break; - case '008000': $colorIdxFg = 0x11; break; - case '000080': $colorIdxFg = 0x12; break; - case '808000': $colorIdxFg = 0x13; break; - case '800080': $colorIdxFg = 0x14; break; - case '008080': $colorIdxFg = 0x15; break; - case 'C0C0C0': $colorIdxFg = 0x16; break; - case '808080': $colorIdxFg = 0x17; break; - case '9999FF': $colorIdxFg = 0x18; break; - case '993366': $colorIdxFg = 0x19; break; - case 'FFFFCC': $colorIdxFg = 0x1A; break; - case 'CCFFFF': $colorIdxFg = 0x1B; break; - case '660066': $colorIdxFg = 0x1C; break; - case 'FF8080': $colorIdxFg = 0x1D; break; - case '0066CC': $colorIdxFg = 0x1E; break; - case 'CCCCFF': $colorIdxFg = 0x1F; break; - case '000080': $colorIdxFg = 0x20; break; - case 'FF00FF': $colorIdxFg = 0x21; break; - case 'FFFF00': $colorIdxFg = 0x22; break; - case '00FFFF': $colorIdxFg = 0x23; break; - case '800080': $colorIdxFg = 0x24; break; - case '800000': $colorIdxFg = 0x25; break; - case '008080': $colorIdxFg = 0x26; break; - case '0000FF': $colorIdxFg = 0x27; break; - case '00CCFF': $colorIdxFg = 0x28; break; - case 'CCFFFF': $colorIdxFg = 0x29; break; - case 'CCFFCC': $colorIdxFg = 0x2A; break; - case 'FFFF99': $colorIdxFg = 0x2B; break; - case '99CCFF': $colorIdxFg = 0x2C; break; - case 'FF99CC': $colorIdxFg = 0x2D; break; - case 'CC99FF': $colorIdxFg = 0x2E; break; - case 'FFCC99': $colorIdxFg = 0x2F; break; - case '3366FF': $colorIdxFg = 0x30; break; - case '33CCCC': $colorIdxFg = 0x31; break; - case '99CC00': $colorIdxFg = 0x32; break; - case 'FFCC00': $colorIdxFg = 0x33; break; - case 'FF9900': $colorIdxFg = 0x34; break; - case 'FF6600': $colorIdxFg = 0x35; break; - case '666699': $colorIdxFg = 0x36; break; - case '969696': $colorIdxFg = 0x37; break; - case '003366': $colorIdxFg = 0x38; break; - case '339966': $colorIdxFg = 0x39; break; - case '003300': $colorIdxFg = 0x3A; break; - case '333300': $colorIdxFg = 0x3B; break; - case '993300': $colorIdxFg = 0x3C; break; - case '993366': $colorIdxFg = 0x3D; break; - case '333399': $colorIdxFg = 0x3E; break; - case '333333': $colorIdxFg = 0x3F; break; - default: $colorIdxFg = 0x40; break; - } - $dataBlockFill = pack('v', $blockFillPatternStyle); - $dataBlockFill .= pack('v', $colorIdxFg | ($colorIdxBg << 7)); - } - if($bFormatProt == 1){ - $dataBlockProtection = 0; - if($conditional->getStyle()->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){ - $dataBlockProtection = 1; - } - if($conditional->getStyle()->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){ - $dataBlockProtection = 1 << 1; - } - } - - $data = pack('CCvvVv', $type, $operatorType, $szValue1, $szValue2, $flags, 0x0000); - if($bFormatFont == 1){ // Block Formatting : OK - $data .= $dataBlockFont; - } - if($bFormatAlign == 1){ - $data .= $dataBlockAlign; - } - if($bFormatBorder == 1){ - $data .= $dataBlockBorder; - } - if($bFormatFill == 1){ // Block Formatting : OK - $data .= $dataBlockFill; - } - if($bFormatProt == 1){ - $data .= $dataBlockProtection; - } - if(!is_null($operand1)){ - $data .= $operand1; - } - if(!is_null($operand2)){ - $data .= $operand2; - } - $header = pack('vv', $record, strlen($data)); - $this->_append($header . $data); - } - - /** - * Write CFHeader record - */ - private function _writeCFHeader(){ - $record = 0x01B0; // Record identifier - $length = 0x0016; // Bytes to follow - - $numColumnMin = null; - $numColumnMax = null; - $numRowMin = null; - $numRowMax = null; - $arrConditional = array(); - foreach ($this->_phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { - foreach ($conditionalStyles as $conditional) { - if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION - || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ - if(!in_array($conditional->getHashCode(), $arrConditional)){ - $arrConditional[] = $conditional->getHashCode(); - } - // Cells - $arrCoord = PHPExcel_Cell::coordinateFromString($cellCoordinate); - if(!is_numeric($arrCoord[0])){ - $arrCoord[0] = PHPExcel_Cell::columnIndexFromString($arrCoord[0]); - } - if(is_null($numColumnMin) || ($numColumnMin > $arrCoord[0])){ - $numColumnMin = $arrCoord[0]; - } - if(is_null($numColumnMax) || ($numColumnMax < $arrCoord[0])){ - $numColumnMax = $arrCoord[0]; - } - if(is_null($numRowMin) || ($numRowMin > $arrCoord[1])){ - $numRowMin = $arrCoord[1]; - } - if(is_null($numRowMax) || ($numRowMax < $arrCoord[1])){ - $numRowMax = $arrCoord[1]; - } - } - } - } - $needRedraw = 1; - $cellRange = pack('vvvv', $numRowMin-1, $numRowMax-1, $numColumnMin-1, $numColumnMax-1); - - $header = pack('vv', $record, $length); - $data = pack('vv', count($arrConditional), $needRedraw); - $data .= $cellRange; - $data .= pack('v', 0x0001); - $data .= $cellRange; - $this->_append($header . $data); - } + /** + * Formula parser + * + * @var PHPExcel_Writer_Excel5_Parser + */ + private $_parser; + + /** + * Maximum number of characters for a string (LABEL record in BIFF5) + * @var integer + */ + public $_xls_strmax; + + /** + * Array containing format information for columns + * @var array + */ + public $_colinfo; + + /** + * Array containing the selected area for the worksheet + * @var array + */ + public $_selection; + + /** + * The active pane for the worksheet + * @var integer + */ + public $_active_pane; + + /** + * Whether to use outline. + * @var integer + */ + public $_outline_on; + + /** + * Auto outline styles. + * @var bool + */ + public $_outline_style; + + /** + * Whether to have outline summary below. + * @var bool + */ + public $_outline_below; + + /** + * Whether to have outline summary at the right. + * @var bool + */ + public $_outline_right; + + /** + * Reference to the total number of strings in the workbook + * @var integer + */ + public $_str_total; + + /** + * Reference to the number of unique strings in the workbook + * @var integer + */ + public $_str_unique; + + /** + * Reference to the array containing all the unique strings in the workbook + * @var array + */ + public $_str_table; + + /** + * Color cache + */ + private $_colors; + + /** + * Index of first used row (at least 0) + * @var int + */ + private $_firstRowIndex; + + /** + * Index of last used row. (no used rows means -1) + * @var int + */ + private $_lastRowIndex; + + /** + * Index of first used column (at least 0) + * @var int + */ + private $_firstColumnIndex; + + /** + * Index of last used column (no used columns means -1) + * @var int + */ + private $_lastColumnIndex; + + /** + * Sheet object + * @var PHPExcel_Worksheet + */ + public $_phpSheet; + + /** + * Count cell style Xfs + * + * @var int + */ + private $_countCellStyleXfs; + + /** + * Escher object corresponding to MSODRAWING + * + * @var PHPExcel_Shared_Escher + */ + private $_escher; + + /** + * Array of font hashes associated to FONT records index + * + * @var array + */ + public $_fntHashIndex; + + /** + * Constructor + * + * @param int &$str_total Total number of strings + * @param int &$str_unique Total number of unique strings + * @param array &$str_table String Table + * @param array &$colors Colour Table + * @param mixed $parser The formula parser created for the Workbook + * @param boolean $preCalculateFormulas Flag indicating whether formulas should be calculated or just written + * @param string $phpSheet The worksheet to write + * @param PHPExcel_Worksheet $phpSheet + */ + public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, + $parser, $preCalculateFormulas, $phpSheet) + { + // It needs to call its parent's constructor explicitly + parent::__construct(); + + // change BIFFwriter limit for CONTINUE records +// $this->_limit = 8224; + + + $this->_preCalculateFormulas = $preCalculateFormulas; + $this->_str_total = &$str_total; + $this->_str_unique = &$str_unique; + $this->_str_table = &$str_table; + $this->_colors = &$colors; + $this->_parser = $parser; + + $this->_phpSheet = $phpSheet; + + //$this->ext_sheets = array(); + //$this->offset = 0; + $this->_xls_strmax = 255; + $this->_colinfo = array(); + $this->_selection = array(0,0,0,0); + $this->_active_pane = 3; + + $this->_print_headers = 0; + + $this->_outline_style = 0; + $this->_outline_below = 1; + $this->_outline_right = 1; + $this->_outline_on = 1; + + $this->_fntHashIndex = array(); + + // calculate values for DIMENSIONS record + $minR = 1; + $minC = 'A'; + + $maxR = $this->_phpSheet->getHighestRow(); + $maxC = $this->_phpSheet->getHighestColumn(); + + // Determine lowest and highest column and row +// $this->_firstRowIndex = ($minR > 65535) ? 65535 : $minR; + $this->_lastRowIndex = ($maxR > 65535) ? 65535 : $maxR ; + + $this->_firstColumnIndex = PHPExcel_Cell::columnIndexFromString($minC); + $this->_lastColumnIndex = PHPExcel_Cell::columnIndexFromString($maxC); + +// if ($this->_firstColumnIndex > 255) $this->_firstColumnIndex = 255; + if ($this->_lastColumnIndex > 255) $this->_lastColumnIndex = 255; + + $this->_countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection()); + } + + /** + * Add data to the beginning of the workbook (note the reverse order) + * and to the end of the workbook. + * + * @access public + * @see PHPExcel_Writer_Excel5_Workbook::storeWorkbook() + */ + function close() + { + $_phpSheet = $this->_phpSheet; + + $num_sheets = $_phpSheet->getParent()->getSheetCount(); + + // Write BOF record + $this->_storeBof(0x0010); + + // Write PRINTHEADERS + $this->_writePrintHeaders(); + + // Write PRINTGRIDLINES + $this->_writePrintGridlines(); + + // Write GRIDSET + $this->_writeGridset(); + + // Calculate column widths + $_phpSheet->calculateColumnWidths(); + + // Column dimensions + if (($defaultWidth = $_phpSheet->getDefaultColumnDimension()->getWidth()) < 0) { + $defaultWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($_phpSheet->getParent()->getDefaultStyle()->getFont()); + } + + $columnDimensions = $_phpSheet->getColumnDimensions(); + $maxCol = $this->_lastColumnIndex -1; + for ($i = 0; $i <= $maxCol; ++$i) { + $hidden = 0; + $level = 0; + $xfIndex = 15; // there are 15 cell style Xfs + + $width = $defaultWidth; + + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($i); + if (isset($columnDimensions[$columnLetter])) { + $columnDimension = $columnDimensions[$columnLetter]; + if ($columnDimension->getWidth() >= 0) { + $width = $columnDimension->getWidth(); + } + $hidden = $columnDimension->getVisible() ? 0 : 1; + $level = $columnDimension->getOutlineLevel(); + $xfIndex = $columnDimension->getXfIndex() + 15; // there are 15 cell style Xfs + } + + // Components of _colinfo: + // $firstcol first column on the range + // $lastcol last column on the range + // $width width to set + // $xfIndex The optional cell style Xf index to apply to the columns + // $hidden The optional hidden atribute + // $level The optional outline level + $this->_colinfo[] = array($i, $i, $width, $xfIndex, $hidden, $level); + } + + // Write GUTS + $this->_writeGuts(); + + // Write DEFAULTROWHEIGHT + $this->_writeDefaultRowHeight(); + + // Write WSBOOL + $this->_writeWsbool(); + + // Write horizontal and vertical page breaks + $this->_writeBreaks(); + + // Write page header + $this->_writeHeader(); + + // Write page footer + $this->_writeFooter(); + + // Write page horizontal centering + $this->_writeHcenter(); + + // Write page vertical centering + $this->_writeVcenter(); + + // Write left margin + $this->_writeMarginLeft(); + + // Write right margin + $this->_writeMarginRight(); + + // Write top margin + $this->_writeMarginTop(); + + // Write bottom margin + $this->_writeMarginBottom(); + + // Write page setup + $this->_writeSetup(); + + // Write sheet protection + $this->_writeProtect(); + + // Write SCENPROTECT + $this->_writeScenProtect(); + + // Write OBJECTPROTECT + $this->_writeObjectProtect(); + + // Write sheet password + $this->_writePassword(); + + // Write DEFCOLWIDTH record + $this->_writeDefcol(); + + // Write the COLINFO records if they exist + if (!empty($this->_colinfo)) { + $colcount = count($this->_colinfo); + for ($i = 0; $i < $colcount; ++$i) { + $this->_writeColinfo($this->_colinfo[$i]); + } + } + $autoFilterRange = $_phpSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + // Write AUTOFILTERINFO + $this->_writeAutoFilterInfo(); + } + + // Write sheet dimensions + $this->_writeDimensions(); + + // Row dimensions + foreach ($_phpSheet->getRowDimensions() as $rowDimension) { + $xfIndex = $rowDimension->getXfIndex() + 15; // there are 15 cellXfs + $this->_writeRow( $rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel() ); + } + + // Write Cells + foreach ($_phpSheet->getCellCollection() as $cellID) { + $cell = $_phpSheet->getCell($cellID); + $row = $cell->getRow() - 1; + $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1; + + // Don't break Excel! +// if ($row + 1 > 65536 or $column + 1 > 256) { + if ($row > 65535 || $column > 255) { + break; + } + + // Write cell value + $xfIndex = $cell->getXfIndex() + 15; // there are 15 cell style Xfs + + $cVal = $cell->getValue(); + if ($cVal instanceof PHPExcel_RichText) { + // $this->_writeString($row, $column, $cVal->getPlainText(), $xfIndex); + $arrcRun = array(); + $str_len = PHPExcel_Shared_String::CountCharacters($cVal->getPlainText(), 'UTF-8'); + $str_pos = 0; + $elements = $cVal->getRichTextElements(); + foreach ($elements as $element) { + // FONT Index + if ($element instanceof PHPExcel_RichText_Run) { + $str_fontidx = $this->_fntHashIndex[$element->getFont()->getHashCode()]; + } + else { + $str_fontidx = 0; + } + $arrcRun[] = array('strlen' => $str_pos, 'fontidx' => $str_fontidx); + // Position FROM + $str_pos += PHPExcel_Shared_String::CountCharacters($element->getText(), 'UTF-8'); + } + $this->_writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun); + } else { + switch ($cell->getDatatype()) { + case PHPExcel_Cell_DataType::TYPE_STRING: + case PHPExcel_Cell_DataType::TYPE_NULL: + if ($cVal === '' || $cVal === null) { + $this->_writeBlank($row, $column, $xfIndex); + } else { + $this->_writeString($row, $column, $cVal, $xfIndex); + } + break; + + case PHPExcel_Cell_DataType::TYPE_NUMERIC: + $this->_writeNumber($row, $column, $cVal, $xfIndex); + break; + + case PHPExcel_Cell_DataType::TYPE_FORMULA: + $calculatedValue = $this->_preCalculateFormulas ? + $cell->getCalculatedValue() : null; + $this->_writeFormula($row, $column, $cVal, $xfIndex, $calculatedValue); + break; + + case PHPExcel_Cell_DataType::TYPE_BOOL: + $this->_writeBoolErr($row, $column, $cVal, 0, $xfIndex); + break; + + case PHPExcel_Cell_DataType::TYPE_ERROR: + $this->_writeBoolErr($row, $column, self::_mapErrorCode($cVal), 1, $xfIndex); + break; + + } + } + } + + // Append + $this->_writeMsoDrawing(); + + // Write WINDOW2 record + $this->_writeWindow2(); + + // Write PLV record + $this->_writePageLayoutView(); + + // Write ZOOM record + $this->_writeZoom(); + if ($_phpSheet->getFreezePane()) { + $this->_writePanes(); + } + + // Write SELECTION record + $this->_writeSelection(); + + // Write MergedCellsTable Record + $this->_writeMergedCells(); + + // Hyperlinks + foreach ($_phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) { + list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinate); + + $url = $hyperlink->getUrl(); + + if ( strpos($url, 'sheet://') !== false ) { + // internal to current workbook + $url = str_replace('sheet://', 'internal:', $url); + + } else if ( preg_match('/^(http:|https:|ftp:|mailto:)/', $url) ) { + // URL + // $url = $url; + + } else { + // external (local file) + $url = 'external:' . $url; + } + + $this->_writeUrl($row - 1, PHPExcel_Cell::columnIndexFromString($column) - 1, $url); + } + + $this->_writeDataValidity(); + $this->_writeSheetLayout(); + + // Write SHEETPROTECTION record + $this->_writeSheetProtection(); + $this->_writeRangeProtection(); + + $arrConditionalStyles = $_phpSheet->getConditionalStylesCollection(); + if(!empty($arrConditionalStyles)){ + $arrConditional = array(); + // @todo CFRule & CFHeader + // Write CFHEADER record + $this->_writeCFHeader(); + // Write ConditionalFormattingTable records + foreach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) { + foreach ($conditionalStyles as $conditional) { + if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ + if(!in_array($conditional->getHashCode(), $arrConditional)){ + $arrConditional[] = $conditional->getHashCode(); + // Write CFRULE record + $this->_writeCFRule($conditional); + } + } + } + } + } + + $this->_storeEof(); + } + + /** + * Write a cell range address in BIFF8 + * always fixed range + * See section 2.5.14 in OpenOffice.org's Documentation of the Microsoft Excel File Format + * + * @param string $range E.g. 'A1' or 'A1:B6' + * @return string Binary data + */ + private function _writeBIFF8CellRangeAddressFixed($range = 'A1') + { + $explodes = explode(':', $range); + + // extract first cell, e.g. 'A1' + $firstCell = $explodes[0]; + + // extract last cell, e.g. 'B6' + if (count($explodes) == 1) { + $lastCell = $firstCell; + } else { + $lastCell = $explodes[1]; + } + + $firstCellCoordinates = PHPExcel_Cell::coordinateFromString($firstCell); // e.g. array(0, 1) + $lastCellCoordinates = PHPExcel_Cell::coordinateFromString($lastCell); // e.g. array(1, 6) + + return(pack('vvvv', + $firstCellCoordinates[1] - 1, + $lastCellCoordinates[1] - 1, + PHPExcel_Cell::columnIndexFromString($firstCellCoordinates[0]) - 1, + PHPExcel_Cell::columnIndexFromString($lastCellCoordinates[0]) - 1 + )); + } + + /** + * Retrieves data from memory in one chunk, or from disk in $buffer + * sized chunks. + * + * @return string The data + */ + function getData() + { + $buffer = 4096; + + // Return data stored in memory + if (isset($this->_data)) { + $tmp = $this->_data; + unset($this->_data); + return $tmp; + } + // No data to return + return false; + } + + /** + * Set the option to print the row and column headers on the printed page. + * + * @access public + * @param integer $print Whether to print the headers or not. Defaults to 1 (print). + */ + function printRowColHeaders($print = 1) + { + $this->_print_headers = $print; + } + + /** + * This method sets the properties for outlining and grouping. The defaults + * correspond to Excel's defaults. + * + * @param bool $visible + * @param bool $symbols_below + * @param bool $symbols_right + * @param bool $auto_style + */ + function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false) + { + $this->_outline_on = $visible; + $this->_outline_below = $symbols_below; + $this->_outline_right = $symbols_right; + $this->_outline_style = $auto_style; + + // Ensure this is a boolean vale for Window2 + if ($this->_outline_on) { + $this->_outline_on = 1; + } + } + + /** + * Write a double to the specified row and column (zero indexed). + * An integer can be written as a double. Excel will display an + * integer. $format is optional. + * + * Returns 0 : normal termination + * -2 : row or column out of range + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param float $num The number to write + * @param mixed $xfIndex The optional XF format + * @return integer + */ + private function _writeNumber($row, $col, $num, $xfIndex) + { + $record = 0x0203; // Record identifier + $length = 0x000E; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $xfIndex); + $xl_double = pack("d", $num); + if (self::getByteOrder()) { // if it's Big Endian + $xl_double = strrev($xl_double); + } + + $this->_append($header.$data.$xl_double); + return(0); + } + + /** + * Write a LABELSST record or a LABEL record. Which one depends on BIFF version + * + * @param int $row Row index (0-based) + * @param int $col Column index (0-based) + * @param string $str The string + * @param int $xfIndex Index to XF record + */ + private function _writeString($row, $col, $str, $xfIndex) + { + $this->_writeLabelSst($row, $col, $str, $xfIndex); + } + + /** + * Write a LABELSST record or a LABEL record. Which one depends on BIFF version + * It differs from _writeString by the writing of rich text strings. + * @param int $row Row index (0-based) + * @param int $col Column index (0-based) + * @param string $str The string + * @param mixed $xfIndex The XF format index for the cell + * @param array $arrcRun Index to Font record and characters beginning + */ + private function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun){ + $record = 0x00FD; // Record identifier + $length = 0x000A; // Bytes to follow + $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($str, $arrcRun); + + /* check if string is already present */ + if (!isset($this->_str_table[$str])) { + $this->_str_table[$str] = $this->_str_unique++; + } + $this->_str_total++; + + $header = pack('vv', $record, $length); + $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); + $this->_append($header.$data); + } + + /** + * Write a string to the specified row and column (zero indexed). + * NOTE: there is an Excel 5 defined limit of 255 characters. + * $format is optional. + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $str The string to write + * @param mixed $xfIndex The XF format index for the cell + * @return integer + */ + private function _writeLabel($row, $col, $str, $xfIndex) + { + $strlen = strlen($str); + $record = 0x0204; // Record identifier + $length = 0x0008 + $strlen; // Bytes to follow + + $str_error = 0; + + if ($strlen > $this->_xls_strmax) { // LABEL must be < 255 chars + $str = substr($str, 0, $this->_xls_strmax); + $length = 0x0008 + $this->_xls_strmax; + $strlen = $this->_xls_strmax; + $str_error = -3; + } + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row, $col, $xfIndex, $strlen); + $this->_append($header . $data . $str); + return($str_error); + } + + /** + * Write a string to the specified row and column (zero indexed). + * This is the BIFF8 version (no 255 chars limit). + * $format is optional. + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $str The string to write + * @param mixed $xfIndex The XF format index for the cell + * @return integer + */ + private function _writeLabelSst($row, $col, $str, $xfIndex) + { + $record = 0x00FD; // Record identifier + $length = 0x000A; // Bytes to follow + + $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($str); + + /* check if string is already present */ + if (!isset($this->_str_table[$str])) { + $this->_str_table[$str] = $this->_str_unique++; + } + $this->_str_total++; + + $header = pack('vv', $record, $length); + $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); + $this->_append($header.$data); + } + + /** + * Writes a note associated with the cell given by the row and column. + * NOTE records don't have a length limit. + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $note The note to write + */ + private function _writeNote($row, $col, $note) + { + $note_length = strlen($note); + $record = 0x001C; // Record identifier + $max_length = 2048; // Maximun length for a NOTE record + + // Length for this record is no more than 2048 + 6 + $length = 0x0006 + min($note_length, 2048); + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $note_length); + $this->_append($header . $data . substr($note, 0, 2048)); + + for ($i = $max_length; $i < $note_length; $i += $max_length) { + $chunk = substr($note, $i, $max_length); + $length = 0x0006 + strlen($chunk); + $header = pack("vv", $record, $length); + $data = pack("vvv", -1, 0, strlen($chunk)); + $this->_append($header.$data.$chunk); + } + return(0); + } + + /** + * Write a blank cell to the specified row and column (zero indexed). + * A blank cell is used to specify formatting without adding a string + * or a number. + * + * A blank cell without a format serves no purpose. Therefore, we don't write + * a BLANK record unless a format is specified. + * + * Returns 0 : normal termination (including no format) + * -1 : insufficient number of arguments + * -2 : row or column out of range + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param mixed $xfIndex The XF format index + */ + function _writeBlank($row, $col, $xfIndex) + { + $record = 0x0201; // Record identifier + $length = 0x0006; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $xfIndex); + $this->_append($header . $data); + return 0; + } + + /** + * Write a boolean or an error type to the specified row and column (zero indexed) + * + * @param int $row Row index (0-based) + * @param int $col Column index (0-based) + * @param int $value + * @param boolean $isError Error or Boolean? + * @param int $xfIndex + */ + private function _writeBoolErr($row, $col, $value, $isError, $xfIndex) + { + $record = 0x0205; + $length = 8; + + $header = pack("vv", $record, $length); + $data = pack("vvvCC", $row, $col, $xfIndex, $value, $isError); + $this->_append($header . $data); + return 0; + } + + /** + * Write a formula to the specified row and column (zero indexed). + * The textual representation of the formula is passed to the parser in + * Parser.php which returns a packed binary string. + * + * Returns 0 : normal termination + * -1 : formula errors (bad formula) + * -2 : row or column out of range + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $formula The formula text string + * @param mixed $xfIndex The XF format index + * @param mixed $calculatedValue Calculated value + * @return integer + */ + private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) + { + $record = 0x0006; // Record identifier + + // Initialize possible additional value for STRING record that should be written after the FORMULA record? + $stringValue = null; + + // calculated value + if (isset($calculatedValue)) { + // Since we can't yet get the data type of the calculated value, + // we use best effort to determine data type + if (is_bool($calculatedValue)) { + // Boolean value + $num = pack('CCCvCv', 0x01, 0x00, (int)$calculatedValue, 0x00, 0x00, 0xFFFF); + } elseif (is_int($calculatedValue) || is_float($calculatedValue)) { + // Numeric value + $num = pack('d', $calculatedValue); + } elseif (is_string($calculatedValue)) { + if (array_key_exists($calculatedValue, PHPExcel_Cell_DataType::getErrorCodes())) { + // Error value + $num = pack('CCCvCv', 0x02, 0x00, self::_mapErrorCode($calculatedValue), 0x00, 0x00, 0xFFFF); + } elseif ($calculatedValue === '') { + // Empty string (and BIFF8) + $num = pack('CCCvCv', 0x03, 0x00, 0x00, 0x00, 0x00, 0xFFFF); + } else { + // Non-empty string value (or empty string BIFF5) + $stringValue = $calculatedValue; + $num = pack('CCCvCv', 0x00, 0x00, 0x00, 0x00, 0x00, 0xFFFF); + } + } else { + // We are really not supposed to reach here + $num = pack('d', 0x00); + } + } else { + $num = pack('d', 0x00); + } + + $grbit = 0x03; // Option flags + $unknown = 0x0000; // Must be zero + + // Strip the '=' or '@' sign at the beginning of the formula string + if ($formula{0} == '=') { + $formula = substr($formula,1); + } else { + // Error handling + $this->_writeString($row, $col, 'Unrecognised character for formula'); + return -1; + } + + // Parse the formula using the parser in Parser.php + try { + $error = $this->_parser->parse($formula); + $formula = $this->_parser->toReversePolish(); + + $formlen = strlen($formula); // Length of the binary string + $length = 0x16 + $formlen; // Length of the record data + + $header = pack("vv", $record, $length); + + $data = pack("vvv", $row, $col, $xfIndex) + . $num + . pack("vVv", $grbit, $unknown, $formlen); + $this->_append($header . $data . $formula); + + // Append also a STRING record if necessary + if ($stringValue !== null) { + $this->_writeStringRecord($stringValue); + } + + return 0; + + } catch (PHPExcel_Exception $e) { + // do nothing + } + + } + + /** + * Write a STRING record. This + * + * @param string $stringValue + */ + private function _writeStringRecord($stringValue) + { + $record = 0x0207; // Record identifier + $data = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($stringValue); + + $length = strlen($data); + $header = pack('vv', $record, $length); + + $this->_append($header . $data); + } + + /** + * Write a hyperlink. + * This is comprised of two elements: the visible label and + * the invisible link. The visible label is the same as the link unless an + * alternative string is specified. The label is written using the + * _writeString() method. Therefore the 255 characters string limit applies. + * $string and $format are optional. + * + * The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external + * directory url. + * + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @param integer $row Row + * @param integer $col Column + * @param string $url URL string + * @return integer + */ + private function _writeUrl($row, $col, $url) + { + // Add start row and col to arg list + return($this->_writeUrlRange($row, $col, $row, $col, $url)); + } + + /** + * This is the more general form of _writeUrl(). It allows a hyperlink to be + * written to a range of cells. This function also decides the type of hyperlink + * to be written. These are either, Web (http, ftp, mailto), Internal + * (Sheet1!A1) or external ('c:\temp\foo.xls#Sheet1!A1'). + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlRange($row1, $col1, $row2, $col2, $url) + { + // Check for internal/external sheet links or default to web link + if (preg_match('[^internal:]', $url)) { + return($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url)); + } + if (preg_match('[^external:]', $url)) { + return($this->_writeUrlExternal($row1, $col1, $row2, $col2, $url)); + } + return($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url)); + } + + /** + * Used to write http, ftp and mailto hyperlinks. + * The link type ($options) is 0x03 is the same as absolute dir ref without + * sheet. However it is differentiated by the $unknown2 data stream. + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlWeb($row1, $col1, $row2, $col2, $url) + { + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); + $unknown2 = pack("H*", "E0C9EA79F9BACE118C8200AA004BA90B"); + + // Pack the option flags + $options = pack("V", 0x03); + + // Convert URL to a null terminated wchar string + $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY)); + $url = $url . "\0\0\0"; + + // Pack the length of the URL + $url_len = pack("V", strlen($url)); + + // Calculate the data length + $length = 0x34 + strlen($url); + + // Pack the header data + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row1, $row2, $col1, $col2); + + // Write the packed data + $this->_append($header . $data . + $unknown1 . $options . + $unknown2 . $url_len . $url); + return 0; + } + + /** + * Used to write internal reference hyperlinks such as "Sheet1!A1". + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlInternal($row1, $col1, $row2, $col2, $url) + { + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + // Strip URL type + $url = preg_replace('/^internal:/', '', $url); + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); + + // Pack the option flags + $options = pack("V", 0x08); + + // Convert the URL type and to a null terminated wchar string + $url .= "\0"; + + // character count + $url_len = PHPExcel_Shared_String::CountCharacters($url); + $url_len = pack('V', $url_len); + + $url = PHPExcel_Shared_String::ConvertEncoding($url, 'UTF-16LE', 'UTF-8'); + + // Calculate the data length + $length = 0x24 + strlen($url); + + // Pack the header data + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row1, $row2, $col1, $col2); + + // Write the packed data + $this->_append($header . $data . + $unknown1 . $options . + $url_len . $url); + return 0; + } + + /** + * Write links to external directory names such as 'c:\foo.xls', + * c:\foo.xls#Sheet1!A1', '../../foo.xls'. and '../../foo.xls#Sheet1!A1'. + * + * Note: Excel writes some relative links with the $dir_long string. We ignore + * these cases for the sake of simpler code. + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlExternal($row1, $col1, $row2, $col2, $url) + { + // Network drives are different. We will handle them separately + // MS/Novell network drives and shares start with \\ + if (preg_match('[^external:\\\\]', $url)) { + return; //($this->_writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format)); + } + + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + // Strip URL type and change Unix dir separator to Dos style (if needed) + // + $url = preg_replace('/^external:/', '', $url); + $url = preg_replace('/\//', "\\", $url); + + // Determine if the link is relative or absolute: + // relative if link contains no dir separator, "somefile.xls" + // relative if link starts with up-dir, "..\..\somefile.xls" + // otherwise, absolute + + $absolute = 0x00; // relative path + if ( preg_match('/^[A-Z]:/', $url) ) { + $absolute = 0x02; // absolute path on Windows, e.g. C:\... + } + $link_type = 0x01 | $absolute; + + // Determine if the link contains a sheet reference and change some of the + // parameters accordingly. + // Split the dir name and sheet name (if it exists) + $dir_long = $url; + if (preg_match("/\#/", $url)) { + $link_type |= 0x08; + } + + + // Pack the link type + $link_type = pack("V", $link_type); + + // Calculate the up-level dir count e.g.. (..\..\..\ == 3) + $up_count = preg_match_all("/\.\.\\\/", $dir_long, $useless); + $up_count = pack("v", $up_count); + + // Store the short dos dir name (null terminated) + $dir_short = preg_replace("/\.\.\\\/", '', $dir_long) . "\0"; + + // Store the long dir name as a wchar string (non-null terminated) + $dir_long = $dir_long . "\0"; + + // Pack the lengths of the dir strings + $dir_short_len = pack("V", strlen($dir_short) ); + $dir_long_len = pack("V", strlen($dir_long) ); + $stream_len = pack("V", 0);//strlen($dir_long) + 0x06); + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*",'D0C9EA79F9BACE118C8200AA004BA90B02000000' ); + $unknown2 = pack("H*",'0303000000000000C000000000000046' ); + $unknown3 = pack("H*",'FFFFADDE000000000000000000000000000000000000000'); + $unknown4 = pack("v", 0x03 ); + + // Pack the main data stream + $data = pack("vvvv", $row1, $row2, $col1, $col2) . + $unknown1 . + $link_type . + $unknown2 . + $up_count . + $dir_short_len. + $dir_short . + $unknown3 . + $stream_len ;/*. + $dir_long_len . + $unknown4 . + $dir_long . + $sheet_len . + $sheet ;*/ + + // Pack the header data + $length = strlen($data); + $header = pack("vv", $record, $length); + + // Write the packed data + $this->_append($header. $data); + return 0; + } + + /** + * This method is used to set the height and format for a row. + * + * @param integer $row The row to set + * @param integer $height Height we are giving to the row. + * Use null to set XF without setting height + * @param integer $xfIndex The optional cell style Xf index to apply to the columns + * @param bool $hidden The optional hidden attribute + * @param integer $level The optional outline level for row, in range [0,7] + */ + private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) + { + $record = 0x0208; // Record identifier + $length = 0x0010; // Number of bytes to follow + + $colMic = 0x0000; // First defined column + $colMac = 0x0000; // Last defined column + $irwMac = 0x0000; // Used by Excel to optimise loading + $reserved = 0x0000; // Reserved + $grbit = 0x0000; // Option flags + $ixfe = $xfIndex; + + if ( $height < 0 ){ + $height = null; + } + + // Use _writeRow($row, null, $XF) to set XF format without setting height + if ($height != null) { + $miyRw = $height * 20; // row height + } else { + $miyRw = 0xff; // default row height is 256 + } + + // Set the options flags. fUnsynced is used to show that the font and row + // heights are not compatible. This is usually the case for WriteExcel. + // The collapsed flag 0x10 doesn't seem to be used to indicate that a row + // is collapsed. Instead it is used to indicate that the previous row is + // collapsed. The zero height flag, 0x20, is used to collapse a row. + + $grbit |= $level; + if ($hidden) { + $grbit |= 0x0030; + } + if ($height !== null) { + $grbit |= 0x0040; // fUnsynced + } + if ($xfIndex !== 0xF) { + $grbit |= 0x0080; + } + $grbit |= 0x0100; + + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, + $irwMac,$reserved, $grbit, $ixfe); + $this->_append($header.$data); + } + + /** + * Writes Excel DIMENSIONS to define the area in which there is data. + */ + private function _writeDimensions() + { + $record = 0x0200; // Record identifier + + $length = 0x000E; + $data = pack('VVvvv' + , $this->_firstRowIndex + , $this->_lastRowIndex + 1 + , $this->_firstColumnIndex + , $this->_lastColumnIndex + 1 + , 0x0000 // reserved + ); + + $header = pack("vv", $record, $length); + $this->_append($header.$data); + } + + /** + * Write BIFF record Window2. + */ + private function _writeWindow2() + { + $record = 0x023E; // Record identifier + $length = 0x0012; + + $grbit = 0x00B6; // Option flags + $rwTop = 0x0000; // Top row visible in window + $colLeft = 0x0000; // Leftmost column visible in window + + + // The options flags that comprise $grbit + $fDspFmla = 0; // 0 - bit + $fDspGrid = $this->_phpSheet->getShowGridlines() ? 1 : 0; // 1 + $fDspRwCol = $this->_phpSheet->getShowRowColHeaders() ? 1 : 0; // 2 + $fFrozen = $this->_phpSheet->getFreezePane() ? 1 : 0; // 3 + $fDspZeros = 1; // 4 + $fDefaultHdr = 1; // 5 + $fArabic = $this->_phpSheet->getRightToLeft() ? 1 : 0; // 6 + $fDspGuts = $this->_outline_on; // 7 + $fFrozenNoSplit = 0; // 0 - bit + // no support in PHPExcel for selected sheet, therefore sheet is only selected if it is the active sheet + $fSelected = ($this->_phpSheet === $this->_phpSheet->getParent()->getActiveSheet()) ? 1 : 0; + $fPaged = 1; // 2 + $fPageBreakPreview = $this->_phpSheet->getSheetView()->getView() === PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW; + + $grbit = $fDspFmla; + $grbit |= $fDspGrid << 1; + $grbit |= $fDspRwCol << 2; + $grbit |= $fFrozen << 3; + $grbit |= $fDspZeros << 4; + $grbit |= $fDefaultHdr << 5; + $grbit |= $fArabic << 6; + $grbit |= $fDspGuts << 7; + $grbit |= $fFrozenNoSplit << 8; + $grbit |= $fSelected << 9; + $grbit |= $fPaged << 10; + $grbit |= $fPageBreakPreview << 11; + + $header = pack("vv", $record, $length); + $data = pack("vvv", $grbit, $rwTop, $colLeft); + + // FIXME !!! + $rgbHdr = 0x0040; // Row/column heading and gridline color index + $zoom_factor_page_break = ($fPageBreakPreview? $this->_phpSheet->getSheetView()->getZoomScale() : 0x0000); + $zoom_factor_normal = $this->_phpSheet->getSheetView()->getZoomScaleNormal(); + + $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000); + + $this->_append($header.$data); + } + + /** + * Write BIFF record DEFAULTROWHEIGHT. + */ + private function _writeDefaultRowHeight() + { + $defaultRowHeight = $this->_phpSheet->getDefaultRowDimension()->getRowHeight(); + + if ($defaultRowHeight < 0) { + return; + } + + // convert to twips + $defaultRowHeight = (int) 20 * $defaultRowHeight; + + $record = 0x0225; // Record identifier + $length = 0x0004; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", 1, $defaultRowHeight); + $this->_append($header . $data); + } + + /** + * Write BIFF record DEFCOLWIDTH if COLINFO records are in use. + */ + private function _writeDefcol() + { + $defaultColWidth = 8; + + $record = 0x0055; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $defaultColWidth); + $this->_append($header . $data); + } + + /** + * Write BIFF record COLINFO to define column widths + * + * Note: The SDK says the record length is 0x0B but Excel writes a 0x0C + * length record. + * + * @param array $col_array This is the only parameter received and is composed of the following: + * 0 => First formatted column, + * 1 => Last formatted column, + * 2 => Col width (8.43 is Excel default), + * 3 => The optional XF format of the column, + * 4 => Option flags. + * 5 => Optional outline level + */ + private function _writeColinfo($col_array) + { + if (isset($col_array[0])) { + $colFirst = $col_array[0]; + } + if (isset($col_array[1])) { + $colLast = $col_array[1]; + } + if (isset($col_array[2])) { + $coldx = $col_array[2]; + } else { + $coldx = 8.43; + } + if (isset($col_array[3])) { + $xfIndex = $col_array[3]; + } else { + $xfIndex = 15; + } + if (isset($col_array[4])) { + $grbit = $col_array[4]; + } else { + $grbit = 0; + } + if (isset($col_array[5])) { + $level = $col_array[5]; + } else { + $level = 0; + } + $record = 0x007D; // Record identifier + $length = 0x000C; // Number of bytes to follow + + $coldx *= 256; // Convert to units of 1/256 of a char + + $ixfe = $xfIndex; + $reserved = 0x0000; // Reserved + + $level = max(0, min($level, 7)); + $grbit |= $level << 8; + + $header = pack("vv", $record, $length); + $data = pack("vvvvvv", $colFirst, $colLast, $coldx, + $ixfe, $grbit, $reserved); + $this->_append($header.$data); + } + + /** + * Write BIFF record SELECTION. + */ + private function _writeSelection() + { + // look up the selected cell range + $selectedCells = $this->_phpSheet->getSelectedCells(); + $selectedCells = PHPExcel_Cell::splitRange($this->_phpSheet->getSelectedCells()); + $selectedCells = $selectedCells[0]; + if (count($selectedCells) == 2) { + list($first, $last) = $selectedCells; + } else { + $first = $selectedCells[0]; + $last = $selectedCells[0]; + } + + list($colFirst, $rwFirst) = PHPExcel_Cell::coordinateFromString($first); + $colFirst = PHPExcel_Cell::columnIndexFromString($colFirst) - 1; // base 0 column index + --$rwFirst; // base 0 row index + + list($colLast, $rwLast) = PHPExcel_Cell::coordinateFromString($last); + $colLast = PHPExcel_Cell::columnIndexFromString($colLast) - 1; // base 0 column index + --$rwLast; // base 0 row index + + // make sure we are not out of bounds + $colFirst = min($colFirst, 255); + $colLast = min($colLast, 255); + + $rwFirst = min($rwFirst, 65535); + $rwLast = min($rwLast, 65535); + + $record = 0x001D; // Record identifier + $length = 0x000F; // Number of bytes to follow + + $pnn = $this->_active_pane; // Pane position + $rwAct = $rwFirst; // Active row + $colAct = $colFirst; // Active column + $irefAct = 0; // Active cell ref + $cref = 1; // Number of refs + + if (!isset($rwLast)) { + $rwLast = $rwFirst; // Last row in reference + } + if (!isset($colLast)) { + $colLast = $colFirst; // Last col in reference + } + + // Swap last row/col for first row/col as necessary + if ($rwFirst > $rwLast) { + list($rwFirst, $rwLast) = array($rwLast, $rwFirst); + } + + if ($colFirst > $colLast) { + list($colFirst, $colLast) = array($colLast, $colFirst); + } + + $header = pack("vv", $record, $length); + $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct, + $irefAct, $cref, + $rwFirst, $rwLast, + $colFirst, $colLast); + $this->_append($header . $data); + } + + /** + * Store the MERGEDCELLS records for all ranges of merged cells + */ + private function _writeMergedCells() + { + $mergeCells = $this->_phpSheet->getMergeCells(); + $countMergeCells = count($mergeCells); + + if ($countMergeCells == 0) { + return; + } + + // maximum allowed number of merged cells per record + $maxCountMergeCellsPerRecord = 1027; + + // record identifier + $record = 0x00E5; + + // counter for total number of merged cells treated so far by the writer + $i = 0; + + // counter for number of merged cells written in record currently being written + $j = 0; + + // initialize record data + $recordData = ''; + + // loop through the merged cells + foreach ($mergeCells as $mergeCell) { + ++$i; + ++$j; + + // extract the row and column indexes + $range = PHPExcel_Cell::splitRange($mergeCell); + list($first, $last) = $range[0]; + list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($first); + list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($last); + + $recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, PHPExcel_Cell::columnIndexFromString($firstColumn) - 1, PHPExcel_Cell::columnIndexFromString($lastColumn) - 1); + + // flush record if we have reached limit for number of merged cells, or reached final merged cell + if ($j == $maxCountMergeCellsPerRecord or $i == $countMergeCells) { + $recordData = pack('v', $j) . $recordData; + $length = strlen($recordData); + $header = pack('vv', $record, $length); + $this->_append($header . $recordData); + + // initialize for next record, if any + $recordData = ''; + $j = 0; + } + } + } + + /** + * Write SHEETLAYOUT record + */ + private function _writeSheetLayout() + { + if (!$this->_phpSheet->isTabColorSet()) { + return; + } + + $recordData = pack( + 'vvVVVvv' + , 0x0862 + , 0x0000 // unused + , 0x00000000 // unused + , 0x00000000 // unused + , 0x00000014 // size of record data + , $this->_colors[$this->_phpSheet->getTabColor()->getRGB()] // color index + , 0x0000 // unused + ); + + $length = strlen($recordData); + + $record = 0x0862; // Record identifier + $header = pack('vv', $record, $length); + $this->_append($header . $recordData); + } + + /** + * Write SHEETPROTECTION + */ + private function _writeSheetProtection() + { + // record identifier + $record = 0x0867; + + // prepare options + $options = (int) !$this->_phpSheet->getProtection()->getObjects() + | (int) !$this->_phpSheet->getProtection()->getScenarios() << 1 + | (int) !$this->_phpSheet->getProtection()->getFormatCells() << 2 + | (int) !$this->_phpSheet->getProtection()->getFormatColumns() << 3 + | (int) !$this->_phpSheet->getProtection()->getFormatRows() << 4 + | (int) !$this->_phpSheet->getProtection()->getInsertColumns() << 5 + | (int) !$this->_phpSheet->getProtection()->getInsertRows() << 6 + | (int) !$this->_phpSheet->getProtection()->getInsertHyperlinks() << 7 + | (int) !$this->_phpSheet->getProtection()->getDeleteColumns() << 8 + | (int) !$this->_phpSheet->getProtection()->getDeleteRows() << 9 + | (int) !$this->_phpSheet->getProtection()->getSelectLockedCells() << 10 + | (int) !$this->_phpSheet->getProtection()->getSort() << 11 + | (int) !$this->_phpSheet->getProtection()->getAutoFilter() << 12 + | (int) !$this->_phpSheet->getProtection()->getPivotTables() << 13 + | (int) !$this->_phpSheet->getProtection()->getSelectUnlockedCells() << 14 ; + + // record data + $recordData = pack( + 'vVVCVVvv' + , 0x0867 // repeated record identifier + , 0x0000 // not used + , 0x0000 // not used + , 0x00 // not used + , 0x01000200 // unknown data + , 0xFFFFFFFF // unknown data + , $options // options + , 0x0000 // not used + ); + + $length = strlen($recordData); + $header = pack('vv', $record, $length); + + $this->_append($header . $recordData); + } + + /** + * Write BIFF record RANGEPROTECTION + * + * Openoffice.org's Documentaion of the Microsoft Excel File Format uses term RANGEPROTECTION for these records + * Microsoft Office Excel 97-2007 Binary File Format Specification uses term FEAT for these records + */ + private function _writeRangeProtection() + { + foreach ($this->_phpSheet->getProtectedCells() as $range => $password) { + // number of ranges, e.g. 'A1:B3 C20:D25' + $cellRanges = explode(' ', $range); + $cref = count($cellRanges); + + $recordData = pack( + 'vvVVvCVvVv', + 0x0868, + 0x00, + 0x0000, + 0x0000, + 0x02, + 0x0, + 0x0000, + $cref, + 0x0000, + 0x00 + ); + + foreach ($cellRanges as $cellRange) { + $recordData .= $this->_writeBIFF8CellRangeAddressFixed($cellRange); + } + + // the rgbFeat structure + $recordData .= pack( + 'VV', + 0x0000, + hexdec($password) + ); + + $recordData .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong('p' . md5($recordData)); + + $length = strlen($recordData); + + $record = 0x0868; // Record identifier + $header = pack("vv", $record, $length); + $this->_append($header . $recordData); + } + } + + /** + * Write BIFF record EXTERNCOUNT to indicate the number of external sheet + * references in a worksheet. + * + * Excel only stores references to external sheets that are used in formulas. + * For simplicity we store references to all the sheets in the workbook + * regardless of whether they are used or not. This reduces the overall + * complexity and eliminates the need for a two way dialogue between the formula + * parser the worksheet objects. + * + * @param integer $count The number of external sheet references in this worksheet + */ + private function _writeExterncount($count) + { + $record = 0x0016; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $count); + $this->_append($header . $data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. A formula references a sheet name via an index. Since we store a + * reference to all of the external worksheets the EXTERNSHEET index is the same + * as the worksheet index. + * + * @param string $sheetname The name of a external worksheet + */ + private function _writeExternsheet($sheetname) + { + $record = 0x0017; // Record identifier + + // References to the current sheet are encoded differently to references to + // external sheets. + // + if ($this->_phpSheet->getTitle() == $sheetname) { + $sheetname = ''; + $length = 0x02; // The following 2 bytes + $cch = 1; // The following byte + $rgch = 0x02; // Self reference + } else { + $length = 0x02 + strlen($sheetname); + $cch = strlen($sheetname); + $rgch = 0x03; // Reference to a sheet in the current workbook + } + + $header = pack("vv", $record, $length); + $data = pack("CC", $cch, $rgch); + $this->_append($header . $data . $sheetname); + } + + /** + * Writes the Excel BIFF PANE record. + * The panes can either be frozen or thawed (unfrozen). + * Frozen panes are specified in terms of an integer number of rows and columns. + * Thawed panes are specified in terms of Excel's units for rows and columns. + */ + private function _writePanes() + { + $panes = array(); + if ($freezePane = $this->_phpSheet->getFreezePane()) { + list($column, $row) = PHPExcel_Cell::coordinateFromString($freezePane); + $panes[0] = $row - 1; + $panes[1] = PHPExcel_Cell::columnIndexFromString($column) - 1; + } else { + // thaw panes + return; + } + + $y = isset($panes[0]) ? $panes[0] : null; + $x = isset($panes[1]) ? $panes[1] : null; + $rwTop = isset($panes[2]) ? $panes[2] : null; + $colLeft = isset($panes[3]) ? $panes[3] : null; + if (count($panes) > 4) { // if Active pane was received + $pnnAct = $panes[4]; + } else { + $pnnAct = null; + } + $record = 0x0041; // Record identifier + $length = 0x000A; // Number of bytes to follow + + // Code specific to frozen or thawed panes. + if ($this->_phpSheet->getFreezePane()) { + // Set default values for $rwTop and $colLeft + if (!isset($rwTop)) { + $rwTop = $y; + } + if (!isset($colLeft)) { + $colLeft = $x; + } + } else { + // Set default values for $rwTop and $colLeft + if (!isset($rwTop)) { + $rwTop = 0; + } + if (!isset($colLeft)) { + $colLeft = 0; + } + + // Convert Excel's row and column units to the internal units. + // The default row height is 12.75 + // The default column width is 8.43 + // The following slope and intersection values were interpolated. + // + $y = 20*$y + 255; + $x = 113.879*$x + 390; + } + + + // Determine which pane should be active. There is also the undocumented + // option to override this should it be necessary: may be removed later. + // + if (!isset($pnnAct)) { + if ($x != 0 && $y != 0) { + $pnnAct = 0; // Bottom right + } + if ($x != 0 && $y == 0) { + $pnnAct = 1; // Top right + } + if ($x == 0 && $y != 0) { + $pnnAct = 2; // Bottom left + } + if ($x == 0 && $y == 0) { + $pnnAct = 3; // Top left + } + } + + $this->_active_pane = $pnnAct; // Used in _writeSelection + + $header = pack("vv", $record, $length); + $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); + $this->_append($header . $data); + } + + /** + * Store the page setup SETUP BIFF record. + */ + private function _writeSetup() + { + $record = 0x00A1; // Record identifier + $length = 0x0022; // Number of bytes to follow + + $iPaperSize = $this->_phpSheet->getPageSetup()->getPaperSize(); // Paper size + + $iScale = $this->_phpSheet->getPageSetup()->getScale() ? + $this->_phpSheet->getPageSetup()->getScale() : 100; // Print scaling factor + + $iPageStart = 0x01; // Starting page number + $iFitWidth = (int) $this->_phpSheet->getPageSetup()->getFitToWidth(); // Fit to number of pages wide + $iFitHeight = (int) $this->_phpSheet->getPageSetup()->getFitToHeight(); // Fit to number of pages high + $grbit = 0x00; // Option flags + $iRes = 0x0258; // Print resolution + $iVRes = 0x0258; // Vertical print resolution + + $numHdr = $this->_phpSheet->getPageMargins()->getHeader(); // Header Margin + + $numFtr = $this->_phpSheet->getPageMargins()->getFooter(); // Footer Margin + $iCopies = 0x01; // Number of copies + + $fLeftToRight = 0x0; // Print over then down + + // Page orientation + $fLandscape = ($this->_phpSheet->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? + 0x0 : 0x1; + + $fNoPls = 0x0; // Setup not read from printer + $fNoColor = 0x0; // Print black and white + $fDraft = 0x0; // Print draft quality + $fNotes = 0x0; // Print notes + $fNoOrient = 0x0; // Orientation not set + $fUsePage = 0x0; // Use custom starting page + + $grbit = $fLeftToRight; + $grbit |= $fLandscape << 1; + $grbit |= $fNoPls << 2; + $grbit |= $fNoColor << 3; + $grbit |= $fDraft << 4; + $grbit |= $fNotes << 5; + $grbit |= $fNoOrient << 6; + $grbit |= $fUsePage << 7; + + $numHdr = pack("d", $numHdr); + $numFtr = pack("d", $numFtr); + if (self::getByteOrder()) { // if it's Big Endian + $numHdr = strrev($numHdr); + $numFtr = strrev($numFtr); + } + + $header = pack("vv", $record, $length); + $data1 = pack("vvvvvvvv", $iPaperSize, + $iScale, + $iPageStart, + $iFitWidth, + $iFitHeight, + $grbit, + $iRes, + $iVRes); + $data2 = $numHdr.$numFtr; + $data3 = pack("v", $iCopies); + $this->_append($header . $data1 . $data2 . $data3); + } + + /** + * Store the header caption BIFF record. + */ + private function _writeHeader() + { + $record = 0x0014; // Record identifier + + /* removing for now + // need to fix character count (multibyte!) + if (strlen($this->_phpSheet->getHeaderFooter()->getOddHeader()) <= 255) { + $str = $this->_phpSheet->getHeaderFooter()->getOddHeader(); // header string + } else { + $str = ''; + } + */ + + $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddHeader()); + $length = strlen($recordData); + + $header = pack("vv", $record, $length); + + $this->_append($header . $recordData); + } + + /** + * Store the footer caption BIFF record. + */ + private function _writeFooter() + { + $record = 0x0015; // Record identifier + + /* removing for now + // need to fix character count (multibyte!) + if (strlen($this->_phpSheet->getHeaderFooter()->getOddFooter()) <= 255) { + $str = $this->_phpSheet->getHeaderFooter()->getOddFooter(); + } else { + $str = ''; + } + */ + + $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddFooter()); + $length = strlen($recordData); + + $header = pack("vv", $record, $length); + + $this->_append($header . $recordData); + } + + /** + * Store the horizontal centering HCENTER BIFF record. + * + * @access private + */ + private function _writeHcenter() + { + $record = 0x0083; // Record identifier + $length = 0x0002; // Bytes to follow + + $fHCenter = $this->_phpSheet->getPageSetup()->getHorizontalCentered() ? 1 : 0; // Horizontal centering + + $header = pack("vv", $record, $length); + $data = pack("v", $fHCenter); + + $this->_append($header.$data); + } + + /** + * Store the vertical centering VCENTER BIFF record. + */ + private function _writeVcenter() + { + $record = 0x0084; // Record identifier + $length = 0x0002; // Bytes to follow + + $fVCenter = $this->_phpSheet->getPageSetup()->getVerticalCentered() ? 1 : 0; // Horizontal centering + + $header = pack("vv", $record, $length); + $data = pack("v", $fVCenter); + $this->_append($header . $data); + } + + /** + * Store the LEFTMARGIN BIFF record. + */ + private function _writeMarginLeft() + { + $record = 0x0026; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getLeft(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Store the RIGHTMARGIN BIFF record. + */ + private function _writeMarginRight() + { + $record = 0x0027; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getRight(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Store the TOPMARGIN BIFF record. + */ + private function _writeMarginTop() + { + $record = 0x0028; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getTop(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Store the BOTTOMMARGIN BIFF record. + */ + private function _writeMarginBottom() + { + $record = 0x0029; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getBottom(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Write the PRINTHEADERS BIFF record. + */ + private function _writePrintHeaders() + { + $record = 0x002a; // Record identifier + $length = 0x0002; // Bytes to follow + + $fPrintRwCol = $this->_print_headers; // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fPrintRwCol); + $this->_append($header . $data); + } + + /** + * Write the PRINTGRIDLINES BIFF record. Must be used in conjunction with the + * GRIDSET record. + */ + private function _writePrintGridlines() + { + $record = 0x002b; // Record identifier + $length = 0x0002; // Bytes to follow + + $fPrintGrid = $this->_phpSheet->getPrintGridlines() ? 1 : 0; // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fPrintGrid); + $this->_append($header . $data); + } + + /** + * Write the GRIDSET BIFF record. Must be used in conjunction with the + * PRINTGRIDLINES record. + */ + private function _writeGridset() + { + $record = 0x0082; // Record identifier + $length = 0x0002; // Bytes to follow + + $fGridSet = !$this->_phpSheet->getPrintGridlines(); // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fGridSet); + $this->_append($header . $data); + } + + /** + * Write the AUTOFILTERINFO BIFF record. This is used to configure the number of autofilter select used in the sheet. + */ + private function _writeAutoFilterInfo(){ + $record = 0x009D; // Record identifier + $length = 0x0002; // Bytes to follow + + $rangeBounds = PHPExcel_Cell::rangeBoundaries($this->_phpSheet->getAutoFilter()->getRange()); + $iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0]; + + $header = pack("vv", $record, $length); + $data = pack("v", $iNumFilters); + $this->_append($header . $data); + } + + /** + * Write the GUTS BIFF record. This is used to configure the gutter margins + * where Excel outline symbols are displayed. The visibility of the gutters is + * controlled by a flag in WSBOOL. + * + * @see _writeWsbool() + */ + private function _writeGuts() + { + $record = 0x0080; // Record identifier + $length = 0x0008; // Bytes to follow + + $dxRwGut = 0x0000; // Size of row gutter + $dxColGut = 0x0000; // Size of col gutter + + // determine maximum row outline level + $maxRowOutlineLevel = 0; + foreach ($this->_phpSheet->getRowDimensions() as $rowDimension) { + $maxRowOutlineLevel = max($maxRowOutlineLevel, $rowDimension->getOutlineLevel()); + } + + $col_level = 0; + + // Calculate the maximum column outline level. The equivalent calculation + // for the row outline level is carried out in _writeRow(). + $colcount = count($this->_colinfo); + for ($i = 0; $i < $colcount; ++$i) { + $col_level = max($this->_colinfo[$i][5], $col_level); + } + + // Set the limits for the outline levels (0 <= x <= 7). + $col_level = max(0, min($col_level, 7)); + + // The displayed level is one greater than the max outline levels + if ($maxRowOutlineLevel) { + ++$maxRowOutlineLevel; + } + if ($col_level) { + ++$col_level; + } + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $dxRwGut, $dxColGut, $maxRowOutlineLevel, $col_level); + + $this->_append($header.$data); + } + + /** + * Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction + * with the SETUP record. + */ + private function _writeWsbool() + { + $record = 0x0081; // Record identifier + $length = 0x0002; // Bytes to follow + $grbit = 0x0000; + + // The only option that is of interest is the flag for fit to page. So we + // set all the options in one go. + // + // Set the option flags + $grbit |= 0x0001; // Auto page breaks visible + if ($this->_outline_style) { + $grbit |= 0x0020; // Auto outline styles + } + if ($this->_phpSheet->getShowSummaryBelow()) { + $grbit |= 0x0040; // Outline summary below + } + if ($this->_phpSheet->getShowSummaryRight()) { + $grbit |= 0x0080; // Outline summary right + } + if ($this->_phpSheet->getPageSetup()->getFitToPage()) { + $grbit |= 0x0100; // Page setup fit to page + } + if ($this->_outline_on) { + $grbit |= 0x0400; // Outline symbols displayed + } + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $this->_append($header . $data); + } + + /** + * Write the HORIZONTALPAGEBREAKS and VERTICALPAGEBREAKS BIFF records. + */ + private function _writeBreaks() + { + // initialize + $vbreaks = array(); + $hbreaks = array(); + + foreach ($this->_phpSheet->getBreaks() as $cell => $breakType) { + // Fetch coordinates + $coordinates = PHPExcel_Cell::coordinateFromString($cell); + + // Decide what to do by the type of break + switch ($breakType) { + case PHPExcel_Worksheet::BREAK_COLUMN: + // Add to list of vertical breaks + $vbreaks[] = PHPExcel_Cell::columnIndexFromString($coordinates[0]) - 1; + break; + + case PHPExcel_Worksheet::BREAK_ROW: + // Add to list of horizontal breaks + $hbreaks[] = $coordinates[1]; + break; + + case PHPExcel_Worksheet::BREAK_NONE: + default: + // Nothing to do + break; + } + } + + //horizontal page breaks + if (!empty($hbreaks)) { + + // Sort and filter array of page breaks + sort($hbreaks, SORT_NUMERIC); + if ($hbreaks[0] == 0) { // don't use first break if it's 0 + array_shift($hbreaks); + } + + $record = 0x001b; // Record identifier + $cbrk = count($hbreaks); // Number of page breaks + $length = 2 + 6 * $cbrk; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cbrk); + + // Append each page break + foreach ($hbreaks as $hbreak) { + $data .= pack("vvv", $hbreak, 0x0000, 0x00ff); + } + + $this->_append($header . $data); + } + + // vertical page breaks + if (!empty($vbreaks)) { + + // 1000 vertical pagebreaks appears to be an internal Excel 5 limit. + // It is slightly higher in Excel 97/200, approx. 1026 + $vbreaks = array_slice($vbreaks, 0, 1000); + + // Sort and filter array of page breaks + sort($vbreaks, SORT_NUMERIC); + if ($vbreaks[0] == 0) { // don't use first break if it's 0 + array_shift($vbreaks); + } + + $record = 0x001a; // Record identifier + $cbrk = count($vbreaks); // Number of page breaks + $length = 2 + 6 * $cbrk; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cbrk); + + // Append each page break + foreach ($vbreaks as $vbreak) { + $data .= pack("vvv", $vbreak, 0x0000, 0xffff); + } + + $this->_append($header . $data); + } + } + + /** + * Set the Biff PROTECT record to indicate that the worksheet is protected. + */ + private function _writeProtect() + { + // Exit unless sheet protection has been specified + if (!$this->_phpSheet->getProtection()->getSheet()) { + return; + } + + $record = 0x0012; // Record identifier + $length = 0x0002; // Bytes to follow + + $fLock = 1; // Worksheet is protected + + $header = pack("vv", $record, $length); + $data = pack("v", $fLock); + + $this->_append($header.$data); + } + + /** + * Write SCENPROTECT + */ + private function _writeScenProtect() + { + // Exit if sheet protection is not active + if (!$this->_phpSheet->getProtection()->getSheet()) { + return; + } + + // Exit if scenarios are not protected + if (!$this->_phpSheet->getProtection()->getScenarios()) { + return; + } + + $record = 0x00DD; // Record identifier + $length = 0x0002; // Bytes to follow + + $header = pack('vv', $record, $length); + $data = pack('v', 1); + + $this->_append($header . $data); + } + + /** + * Write OBJECTPROTECT + */ + private function _writeObjectProtect() + { + // Exit if sheet protection is not active + if (!$this->_phpSheet->getProtection()->getSheet()) { + return; + } + + // Exit if objects are not protected + if (!$this->_phpSheet->getProtection()->getObjects()) { + return; + } + + $record = 0x0063; // Record identifier + $length = 0x0002; // Bytes to follow + + $header = pack('vv', $record, $length); + $data = pack('v', 1); + + $this->_append($header . $data); + } + + /** + * Write the worksheet PASSWORD record. + */ + private function _writePassword() + { + // Exit unless sheet protection and password have been specified + if (!$this->_phpSheet->getProtection()->getSheet() || !$this->_phpSheet->getProtection()->getPassword()) { + return; + } + + $record = 0x0013; // Record identifier + $length = 0x0002; // Bytes to follow + + $wPassword = hexdec($this->_phpSheet->getProtection()->getPassword()); // Encoded password + + $header = pack("vv", $record, $length); + $data = pack("v", $wPassword); + + $this->_append($header . $data); + } + + /** + * Insert a 24bit bitmap image in a worksheet. + * + * @access public + * @param integer $row The row we are going to insert the bitmap into + * @param integer $col The column we are going to insert the bitmap into + * @param mixed $bitmap The bitmap filename or GD-image resource + * @param integer $x The horizontal position (offset) of the image inside the cell. + * @param integer $y The vertical position (offset) of the image inside the cell. + * @param float $scale_x The horizontal scale + * @param float $scale_y The vertical scale + */ + function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) + { + $bitmap_array = (is_resource($bitmap) ? $this->_processBitmapGd($bitmap) : $this->_processBitmap($bitmap)); + list($width, $height, $size, $data) = $bitmap_array; //$this->_processBitmap($bitmap); + + // Scale the frame of the image. + $width *= $scale_x; + $height *= $scale_y; + + // Calculate the vertices of the image and write the OBJ record + $this->_positionImage($col, $row, $x, $y, $width, $height); + + // Write the IMDATA record to store the bitmap data + $record = 0x007f; + $length = 8 + $size; + $cf = 0x09; + $env = 0x01; + $lcb = $size; + + $header = pack("vvvvV", $record, $length, $cf, $env, $lcb); + $this->_append($header.$data); + } + + /** + * Calculate the vertices that define the position of the image as required by + * the OBJ record. + * + * +------------+------------+ + * | A | B | + * +-----+------------+------------+ + * | |(x1,y1) | | + * | 1 |(A1)._______|______ | + * | | | | | + * | | | | | + * +-----+----| BITMAP |-----+ + * | | | | | + * | 2 | |______________. | + * | | | (B2)| + * | | | (x2,y2)| + * +---- +------------+------------+ + * + * Example of a bitmap that covers some of the area from cell A1 to cell B2. + * + * Based on the width and height of the bitmap we need to calculate 8 vars: + * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. + * The width and height of the cells are also variable and have to be taken into + * account. + * The values of $col_start and $row_start are passed in from the calling + * function. The values of $col_end and $row_end are calculated by subtracting + * the width and height of the bitmap from the width and height of the + * underlying cells. + * The vertices are expressed as a percentage of the underlying cell width as + * follows (rhs values are in pixels): + * + * x1 = X / W *1024 + * y1 = Y / H *256 + * x2 = (X-1) / W *1024 + * y2 = (Y-1) / H *256 + * + * Where: X is distance from the left side of the underlying cell + * Y is distance from the top of the underlying cell + * W is the width of the cell + * H is the height of the cell + * The SDK incorrectly states that the height should be expressed as a + * percentage of 1024. + * + * @access private + * @param integer $col_start Col containing upper left corner of object + * @param integer $row_start Row containing top left corner of object + * @param integer $x1 Distance to left side of object + * @param integer $y1 Distance to top of object + * @param integer $width Width of image frame + * @param integer $height Height of image frame + */ + function _positionImage($col_start, $row_start, $x1, $y1, $width, $height) + { + // Initialise end cell to the same as the start cell + $col_end = $col_start; // Col containing lower right corner of object + $row_end = $row_start; // Row containing bottom right corner of object + + // Zero the specified offset if greater than the cell dimensions + if ($x1 >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { + $x1 = 0; + } + if ($y1 >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1)) { + $y1 = 0; + } + + $width = $width + $x1 -1; + $height = $height + $y1 -1; + + // Subtract the underlying cell widths to find the end cell of the image + while ($width >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { + $width -= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); + ++$col_end; + } + + // Subtract the underlying cell heights to find the end cell of the image + while ($height >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1)) { + $height -= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1); + ++$row_end; + } + + // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell + // with zero eight or width. + // + if (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { + return; + } + if (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { + return; + } + if (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) == 0) { + return; + } + if (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) == 0) { + return; + } + + // Convert the pixel values to the percentage value expected by Excel + $x1 = $x1 / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; + $y1 = $y1 / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) * 256; + $x2 = $width / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object + $y2 = $height / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) * 256; // Distance to bottom of object + + $this->_writeObjPicture($col_start, $x1, + $row_start, $y1, + $col_end, $x2, + $row_end, $y2); + } + + /** + * Store the OBJ record that precedes an IMDATA record. This could be generalise + * to support other Excel objects. + * + * @param integer $colL Column containing upper left corner of object + * @param integer $dxL Distance from left side of cell + * @param integer $rwT Row containing top left corner of object + * @param integer $dyT Distance from top of cell + * @param integer $colR Column containing lower right corner of object + * @param integer $dxR Distance from right of cell + * @param integer $rwB Row containing bottom right corner of object + * @param integer $dyB Distance from bottom of cell + */ + private function _writeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB) + { + $record = 0x005d; // Record identifier + $length = 0x003c; // Bytes to follow + + $cObj = 0x0001; // Count of objects in file (set to 1) + $OT = 0x0008; // Object type. 8 = Picture + $id = 0x0001; // Object ID + $grbit = 0x0614; // Option flags + + $cbMacro = 0x0000; // Length of FMLA structure + $Reserved1 = 0x0000; // Reserved + $Reserved2 = 0x0000; // Reserved + + $icvBack = 0x09; // Background colour + $icvFore = 0x09; // Foreground colour + $fls = 0x00; // Fill pattern + $fAuto = 0x00; // Automatic fill + $icv = 0x08; // Line colour + $lns = 0xff; // Line style + $lnw = 0x01; // Line weight + $fAutoB = 0x00; // Automatic border + $frs = 0x0000; // Frame style + $cf = 0x0009; // Image format, 9 = bitmap + $Reserved3 = 0x0000; // Reserved + $cbPictFmla = 0x0000; // Length of FMLA structure + $Reserved4 = 0x0000; // Reserved + $grbit2 = 0x0001; // Option flags + $Reserved5 = 0x0000; // Reserved + + + $header = pack("vv", $record, $length); + $data = pack("V", $cObj); + $data .= pack("v", $OT); + $data .= pack("v", $id); + $data .= pack("v", $grbit); + $data .= pack("v", $colL); + $data .= pack("v", $dxL); + $data .= pack("v", $rwT); + $data .= pack("v", $dyT); + $data .= pack("v", $colR); + $data .= pack("v", $dxR); + $data .= pack("v", $rwB); + $data .= pack("v", $dyB); + $data .= pack("v", $cbMacro); + $data .= pack("V", $Reserved1); + $data .= pack("v", $Reserved2); + $data .= pack("C", $icvBack); + $data .= pack("C", $icvFore); + $data .= pack("C", $fls); + $data .= pack("C", $fAuto); + $data .= pack("C", $icv); + $data .= pack("C", $lns); + $data .= pack("C", $lnw); + $data .= pack("C", $fAutoB); + $data .= pack("v", $frs); + $data .= pack("V", $cf); + $data .= pack("v", $Reserved3); + $data .= pack("v", $cbPictFmla); + $data .= pack("v", $Reserved4); + $data .= pack("v", $grbit2); + $data .= pack("V", $Reserved5); + + $this->_append($header . $data); + } + + /** + * Convert a GD-image into the internal format. + * + * @access private + * @param resource $image The image to process + * @return array Array with data and properties of the bitmap + */ + function _processBitmapGd($image) { + $width = imagesx($image); + $height = imagesy($image); + + $data = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); + for ($j=$height; $j--; ) { + for ($i=0; $i < $width; ++$i) { + $color = imagecolorsforindex($image, imagecolorat($image, $i, $j)); + foreach (array("red", "green", "blue") as $key) { + $color[$key] = $color[$key] + round((255 - $color[$key]) * $color["alpha"] / 127); + } + $data .= chr($color["blue"]) . chr($color["green"]) . chr($color["red"]); + } + if (3*$width % 4) { + $data .= str_repeat("\x00", 4 - 3*$width % 4); + } + } + + return array($width, $height, strlen($data), $data); + } + + /** + * Convert a 24 bit bitmap into the modified internal format used by Windows. + * This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the + * MSDN library. + * + * @access private + * @param string $bitmap The bitmap to process + * @return array Array with data and properties of the bitmap + */ + function _processBitmap($bitmap) + { + // Open file. + $bmp_fd = @fopen($bitmap,"rb"); + if (!$bmp_fd) { + throw new PHPExcel_Writer_Exception("Couldn't import $bitmap"); + } + + // Slurp the file into a string. + $data = fread($bmp_fd, filesize($bitmap)); + + // Check that the file is big enough to be a bitmap. + if (strlen($data) <= 0x36) { + throw new PHPExcel_Writer_Exception("$bitmap doesn't contain enough data.\n"); + } + + // The first 2 bytes are used to identify the bitmap. + $identity = unpack("A2ident", $data); + if ($identity['ident'] != "BM") { + throw new PHPExcel_Writer_Exception("$bitmap doesn't appear to be a valid bitmap image.\n"); + } + + // Remove bitmap data: ID. + $data = substr($data, 2); + + // Read and remove the bitmap size. This is more reliable than reading + // the data size at offset 0x22. + // + $size_array = unpack("Vsa", substr($data, 0, 4)); + $size = $size_array['sa']; + $data = substr($data, 4); + $size -= 0x36; // Subtract size of bitmap header. + $size += 0x0C; // Add size of BIFF header. + + // Remove bitmap data: reserved, offset, header length. + $data = substr($data, 12); + + // Read and remove the bitmap width and height. Verify the sizes. + $width_and_height = unpack("V2", substr($data, 0, 8)); + $width = $width_and_height[1]; + $height = $width_and_height[2]; + $data = substr($data, 8); + if ($width > 0xFFFF) { + throw new PHPExcel_Writer_Exception("$bitmap: largest image width supported is 65k.\n"); + } + if ($height > 0xFFFF) { + throw new PHPExcel_Writer_Exception("$bitmap: largest image height supported is 65k.\n"); + } + + // Read and remove the bitmap planes and bpp data. Verify them. + $planes_and_bitcount = unpack("v2", substr($data, 0, 4)); + $data = substr($data, 4); + if ($planes_and_bitcount[2] != 24) { // Bitcount + throw new PHPExcel_Writer_Exception("$bitmap isn't a 24bit true color bitmap.\n"); + } + if ($planes_and_bitcount[1] != 1) { + throw new PHPExcel_Writer_Exception("$bitmap: only 1 plane supported in bitmap image.\n"); + } + + // Read and remove the bitmap compression. Verify compression. + $compression = unpack("Vcomp", substr($data, 0, 4)); + $data = substr($data, 4); + + //$compression = 0; + if ($compression['comp'] != 0) { + throw new PHPExcel_Writer_Exception("$bitmap: compression not supported in bitmap image.\n"); + } + + // Remove bitmap data: data size, hres, vres, colours, imp. colours. + $data = substr($data, 20); + + // Add the BITMAPCOREHEADER data + $header = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); + $data = $header . $data; + + return (array($width, $height, $size, $data)); + } + + /** + * Store the window zoom factor. This should be a reduced fraction but for + * simplicity we will store all fractions with a numerator of 100. + */ + private function _writeZoom() + { + // If scale is 100 we don't need to write a record + if ($this->_phpSheet->getSheetView()->getZoomScale() == 100) { + return; + } + + $record = 0x00A0; // Record identifier + $length = 0x0004; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", $this->_phpSheet->getSheetView()->getZoomScale(), 100); + $this->_append($header . $data); + } + + /** + * Get Escher object + * + * @return PHPExcel_Shared_Escher + */ + public function getEscher() + { + return $this->_escher; + } + + /** + * Set Escher object + * + * @param PHPExcel_Shared_Escher $pValue + */ + public function setEscher(PHPExcel_Shared_Escher $pValue = null) + { + $this->_escher = $pValue; + } + + /** + * Write MSODRAWING record + */ + private function _writeMsoDrawing() + { + // write the Escher stream if necessary + if (isset($this->_escher)) { + $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); + $data = $writer->close(); + $spOffsets = $writer->getSpOffsets(); + $spTypes = $writer->getSpTypes(); + // write the neccesary MSODRAWING, OBJ records + + // split the Escher stream + $spOffsets[0] = 0; + $nm = count($spOffsets) - 1; // number of shapes excluding first shape + for ($i = 1; $i <= $nm; ++$i) { + // MSODRAWING record + $record = 0x00EC; // Record identifier + + // chunk of Escher stream for one shape + $dataChunk = substr($data, $spOffsets[$i -1], $spOffsets[$i] - $spOffsets[$i - 1]); + + $length = strlen($dataChunk); + $header = pack("vv", $record, $length); + + $this->_append($header . $dataChunk); + + // OBJ record + $record = 0x005D; // record identifier + $objData = ''; + + // ftCmo + if($spTypes[$i] == 0x00C9){ + // Add ftCmo (common object data) subobject + $objData .= + pack('vvvvvVVV' + , 0x0015 // 0x0015 = ftCmo + , 0x0012 // length of ftCmo data + , 0x0014 // object type, 0x0014 = filter + , $i // object id number, Excel seems to use 1-based index, local for the sheet + , 0x2101 // option flags, 0x2001 is what OpenOffice.org uses + , 0 // reserved + , 0 // reserved + , 0 // reserved + ); + + // Add ftSbs Scroll bar subobject + $objData .= pack('vv', 0x00C, 0x0014); + $objData .= pack('H*', '0000000000000000640001000A00000010000100'); + // Add ftLbsData (List box data) subobject + $objData .= pack('vv', 0x0013, 0x1FEE); + $objData .= pack('H*', '00000000010001030000020008005700'); + } + else { + // Add ftCmo (common object data) subobject + $objData .= + pack('vvvvvVVV' + , 0x0015 // 0x0015 = ftCmo + , 0x0012 // length of ftCmo data + , 0x0008 // object type, 0x0008 = picture + , $i // object id number, Excel seems to use 1-based index, local for the sheet + , 0x6011 // option flags, 0x6011 is what OpenOffice.org uses + , 0 // reserved + , 0 // reserved + , 0 // reserved + ); + } + + // ftEnd + $objData .= + pack('vv' + , 0x0000 // 0x0000 = ftEnd + , 0x0000 // length of ftEnd data + ); + + $length = strlen($objData); + $header = pack('vv', $record, $length); + $this->_append($header . $objData); + } + } + } + + /** + * Store the DATAVALIDATIONS and DATAVALIDATION records. + */ + private function _writeDataValidity() + { + // Datavalidation collection + $dataValidationCollection = $this->_phpSheet->getDataValidationCollection(); + + // Write data validations? + if (!empty($dataValidationCollection)) { + + // DATAVALIDATIONS record + $record = 0x01B2; // Record identifier + $length = 0x0012; // Bytes to follow + + $grbit = 0x0000; // Prompt box at cell, no cached validity data at DV records + $horPos = 0x00000000; // Horizontal position of prompt box, if fixed position + $verPos = 0x00000000; // Vertical position of prompt box, if fixed position + $objId = 0xFFFFFFFF; // Object identifier of drop down arrow object, or -1 if not visible + + $header = pack('vv', $record, $length); + $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId, + count($dataValidationCollection)); + $this->_append($header.$data); + + // DATAVALIDATION records + $record = 0x01BE; // Record identifier + + foreach ($dataValidationCollection as $cellCoordinate => $dataValidation) { + // initialize record data + $data = ''; + + // options + $options = 0x00000000; + + // data type + $type = $dataValidation->getType(); + switch ($type) { + case PHPExcel_Cell_DataValidation::TYPE_NONE: $type = 0x00; break; + case PHPExcel_Cell_DataValidation::TYPE_WHOLE: $type = 0x01; break; + case PHPExcel_Cell_DataValidation::TYPE_DECIMAL: $type = 0x02; break; + case PHPExcel_Cell_DataValidation::TYPE_LIST: $type = 0x03; break; + case PHPExcel_Cell_DataValidation::TYPE_DATE: $type = 0x04; break; + case PHPExcel_Cell_DataValidation::TYPE_TIME: $type = 0x05; break; + case PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH: $type = 0x06; break; + case PHPExcel_Cell_DataValidation::TYPE_CUSTOM: $type = 0x07; break; + } + $options |= $type << 0; + + // error style + $errorStyle = $dataValidation->getType(); + switch ($errorStyle) { + case PHPExcel_Cell_DataValidation::STYLE_STOP: $errorStyle = 0x00; break; + case PHPExcel_Cell_DataValidation::STYLE_WARNING: $errorStyle = 0x01; break; + case PHPExcel_Cell_DataValidation::STYLE_INFORMATION: $errorStyle = 0x02; break; + } + $options |= $errorStyle << 4; + + // explicit formula? + if ($type == 0x03 && preg_match('/^\".*\"$/', $dataValidation->getFormula1())) { + $options |= 0x01 << 7; + } + + // empty cells allowed + $options |= $dataValidation->getAllowBlank() << 8; + + // show drop down + $options |= (!$dataValidation->getShowDropDown()) << 9; + + // show input message + $options |= $dataValidation->getShowInputMessage() << 18; + + // show error message + $options |= $dataValidation->getShowErrorMessage() << 19; + + // condition operator + $operator = $dataValidation->getOperator(); + switch ($operator) { + case PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN: $operator = 0x00 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN: $operator = 0x01 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_EQUAL: $operator = 0x02 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL: $operator = 0x03 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN: $operator = 0x04 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN: $operator = 0x05 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL: $operator = 0x06; break; + case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL: $operator = 0x07 ; break; + } + $options |= $operator << 20; + + $data = pack('V', $options); + + // prompt title + $promptTitle = $dataValidation->getPromptTitle() !== '' ? + $dataValidation->getPromptTitle() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($promptTitle); + + // error title + $errorTitle = $dataValidation->getErrorTitle() !== '' ? + $dataValidation->getErrorTitle() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($errorTitle); + + // prompt text + $prompt = $dataValidation->getPrompt() !== '' ? + $dataValidation->getPrompt() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($prompt); + + // error text + $error = $dataValidation->getError() !== '' ? + $dataValidation->getError() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($error); + + // formula 1 + try { + $formula1 = $dataValidation->getFormula1(); + if ($type == 0x03) { // list type + $formula1 = str_replace(',', chr(0), $formula1); + } + $this->_parser->parse($formula1); + $formula1 = $this->_parser->toReversePolish(); + $sz1 = strlen($formula1); + + } catch(PHPExcel_Exception $e) { + $sz1 = 0; + $formula1 = ''; + } + $data .= pack('vv', $sz1, 0x0000); + $data .= $formula1; + + // formula 2 + try { + $formula2 = $dataValidation->getFormula2(); + if ($formula2 === '') { + throw new PHPExcel_Writer_Exception('No formula2'); + } + $this->_parser->parse($formula2); + $formula2 = $this->_parser->toReversePolish(); + $sz2 = strlen($formula2); + + } catch(PHPExcel_Exception $e) { + $sz2 = 0; + $formula2 = ''; + } + $data .= pack('vv', $sz2, 0x0000); + $data .= $formula2; + + // cell range address list + $data .= pack('v', 0x0001); + $data .= $this->_writeBIFF8CellRangeAddressFixed($cellCoordinate); + + $length = strlen($data); + $header = pack("vv", $record, $length); + + $this->_append($header . $data); + } + } + } + + /** + * Map Error code + * + * @param string $errorCode + * @return int + */ + private static function _mapErrorCode($errorCode) { + switch ($errorCode) { + case '#NULL!': return 0x00; + case '#DIV/0!': return 0x07; + case '#VALUE!': return 0x0F; + case '#REF!': return 0x17; + case '#NAME?': return 0x1D; + case '#NUM!': return 0x24; + case '#N/A': return 0x2A; + } + + return 0; + } + + /** + * Write PLV Record + */ + private function _writePageLayoutView(){ + $record = 0x088B; // Record identifier + $length = 0x0010; // Bytes to follow + + $rt = 0x088B; // 2 + $grbitFrt = 0x0000; // 2 + $reserved = 0x0000000000000000; // 8 + $wScalvePLV = $this->_phpSheet->getSheetView()->getZoomScale(); // 2 + + // The options flags that comprise $grbit + if($this->_phpSheet->getSheetView()->getView() == PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT){ + $fPageLayoutView = 1; + } else { + $fPageLayoutView = 0; + } + $fRulerVisible = 0; + $fWhitespaceHidden = 0; + + $grbit = $fPageLayoutView; // 2 + $grbit |= $fRulerVisible << 1; + $grbit |= $fWhitespaceHidden << 3; + + $header = pack("vv", $record, $length); + $data = pack("vvVVvv", $rt, $grbitFrt, 0x00000000, 0x00000000, $wScalvePLV, $grbit); + $this->_append($header . $data); + } + + /** + * Write CFRule Record + * @param PHPExcel_Style_Conditional $conditional + */ + private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ + $record = 0x01B1; // Record identifier + + // $type : Type of the CF + // $operatorType : Comparison operator + if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION){ + $type = 0x02; + $operatorType = 0x00; + } else if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ + $type = 0x01; + + switch ($conditional->getOperatorType()){ + case PHPExcel_Style_Conditional::OPERATOR_NONE: + $operatorType = 0x00; + break; + case PHPExcel_Style_Conditional::OPERATOR_EQUAL: + $operatorType = 0x03; + break; + case PHPExcel_Style_Conditional::OPERATOR_GREATERTHAN: + $operatorType = 0x05; + break; + case PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL: + $operatorType = 0x07; + break; + case PHPExcel_Style_Conditional::OPERATOR_LESSTHAN: + $operatorType = 0x06; + break; + case PHPExcel_Style_Conditional::OPERATOR_LESSTHANOREQUAL: + $operatorType = 0x08; + break; + case PHPExcel_Style_Conditional::OPERATOR_NOTEQUAL: + $operatorType = 0x04; + break; + case PHPExcel_Style_Conditional::OPERATOR_BETWEEN: + $operatorType = 0x01; + break; + // not OPERATOR_NOTBETWEEN 0x02 + } + } + + // $szValue1 : size of the formula data for first value or formula + // $szValue2 : size of the formula data for second value or formula + $arrConditions = $conditional->getConditions(); + $numConditions = sizeof($arrConditions); + if($numConditions == 1){ + $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); + $szValue2 = 0x0000; + $operand1 = pack('Cv', 0x1E, $arrConditions[0]); + $operand2 = null; + } else if($numConditions == 2 && ($conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BETWEEN)){ + $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); + $szValue2 = ($arrConditions[1] <= 65535 ? 3 : 0x0000); + $operand1 = pack('Cv', 0x1E, $arrConditions[0]); + $operand2 = pack('Cv', 0x1E, $arrConditions[1]); + } else { + $szValue1 = 0x0000; + $szValue2 = 0x0000; + $operand1 = null; + $operand2 = null; + } + + // $flags : Option flags + // Alignment + $bAlignHz = ($conditional->getStyle()->getAlignment()->getHorizontal() == null ? 1 : 0); + $bAlignVt = ($conditional->getStyle()->getAlignment()->getVertical() == null ? 1 : 0); + $bAlignWrapTx = ($conditional->getStyle()->getAlignment()->getWrapText() == false ? 1 : 0); + $bTxRotation = ($conditional->getStyle()->getAlignment()->getTextRotation() == null ? 1 : 0); + $bIndent = ($conditional->getStyle()->getAlignment()->getIndent() == 0 ? 1 : 0); + $bShrinkToFit = ($conditional->getStyle()->getAlignment()->getShrinkToFit() == false ? 1 : 0); + if($bAlignHz == 0 || $bAlignVt == 0 || $bAlignWrapTx == 0 || $bTxRotation == 0 || $bIndent == 0 || $bShrinkToFit == 0){ + $bFormatAlign = 1; + } else { + $bFormatAlign = 0; + } + // Protection + $bProtLocked = ($conditional->getStyle()->getProtection()->getLocked() == null ? 1 : 0); + $bProtHidden = ($conditional->getStyle()->getProtection()->getHidden() == null ? 1 : 0); + if($bProtLocked == 0 || $bProtHidden == 0){ + $bFormatProt = 1; + } else { + $bFormatProt = 0; + } + // Border + $bBorderLeft = ($conditional->getStyle()->getBorders()->getLeft()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getLeft()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + $bBorderRight = ($conditional->getStyle()->getBorders()->getRight()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getRight()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + $bBorderTop = ($conditional->getStyle()->getBorders()->getTop()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getTop()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + $bBorderBottom = ($conditional->getStyle()->getBorders()->getBottom()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getBottom()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + if($bBorderLeft == 0 || $bBorderRight == 0 || $bBorderTop == 0 || $bBorderBottom == 0){ + $bFormatBorder = 1; + } else { + $bFormatBorder = 0; + } + // Pattern + $bFillStyle = ($conditional->getStyle()->getFill()->getFillType() == null ? 0 : 1); + $bFillColor = ($conditional->getStyle()->getFill()->getStartColor()->getARGB() == null ? 0 : 1); + $bFillColorBg = ($conditional->getStyle()->getFill()->getEndColor()->getARGB() == null ? 0 : 1); + if($bFillStyle == 0 || $bFillColor == 0 || $bFillColorBg == 0){ + $bFormatFill = 1; + } else { + $bFormatFill = 0; + } + // Font + if($conditional->getStyle()->getFont()->getName() != null + || $conditional->getStyle()->getFont()->getSize() != null + || $conditional->getStyle()->getFont()->getBold() != null + || $conditional->getStyle()->getFont()->getItalic() != null + || $conditional->getStyle()->getFont()->getSuperScript() != null + || $conditional->getStyle()->getFont()->getSubScript() != null + || $conditional->getStyle()->getFont()->getUnderline() != null + || $conditional->getStyle()->getFont()->getStrikethrough() != null + || $conditional->getStyle()->getFont()->getColor()->getARGB() != null){ + $bFormatFont = 1; + } else { + $bFormatFont = 0; + } + // Alignment + $flags = 0; + $flags |= (1 == $bAlignHz ? 0x00000001 : 0); + $flags |= (1 == $bAlignVt ? 0x00000002 : 0); + $flags |= (1 == $bAlignWrapTx ? 0x00000004 : 0); + $flags |= (1 == $bTxRotation ? 0x00000008 : 0); + // Justify last line flag + $flags |= (1 == 1 ? 0x00000010 : 0); + $flags |= (1 == $bIndent ? 0x00000020 : 0); + $flags |= (1 == $bShrinkToFit ? 0x00000040 : 0); + // Default + $flags |= (1 == 1 ? 0x00000080 : 0); + // Protection + $flags |= (1 == $bProtLocked ? 0x00000100 : 0); + $flags |= (1 == $bProtHidden ? 0x00000200 : 0); + // Border + $flags |= (1 == $bBorderLeft ? 0x00000400 : 0); + $flags |= (1 == $bBorderRight ? 0x00000800 : 0); + $flags |= (1 == $bBorderTop ? 0x00001000 : 0); + $flags |= (1 == $bBorderBottom ? 0x00002000 : 0); + $flags |= (1 == 1 ? 0x00004000 : 0); // Top left to Bottom right border + $flags |= (1 == 1 ? 0x00008000 : 0); // Bottom left to Top right border + // Pattern + $flags |= (1 == $bFillStyle ? 0x00010000 : 0); + $flags |= (1 == $bFillColor ? 0x00020000 : 0); + $flags |= (1 == $bFillColorBg ? 0x00040000 : 0); + $flags |= (1 == 1 ? 0x00380000 : 0); + // Font + $flags |= (1 == $bFormatFont ? 0x04000000 : 0); + // Alignment : + $flags |= (1 == $bFormatAlign ? 0x08000000 : 0); + // Border + $flags |= (1 == $bFormatBorder ? 0x10000000 : 0); + // Pattern + $flags |= (1 == $bFormatFill ? 0x20000000 : 0); + // Protection + $flags |= (1 == $bFormatProt ? 0x40000000 : 0); + // Text direction + $flags |= (1 == 0 ? 0x80000000 : 0); + + // Data Blocks + if($bFormatFont == 1){ + // Font Name + if($conditional->getStyle()->getFont()->getName() == null){ + $dataBlockFont = pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); + $dataBlockFont .= pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); + } else { + $dataBlockFont = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($conditional->getStyle()->getFont()->getName()); + } + // Font Size + if($conditional->getStyle()->getFont()->getSize() == null){ + $dataBlockFont .= pack('V', 20 * 11); + } else { + $dataBlockFont .= pack('V', 20 * $conditional->getStyle()->getFont()->getSize()); + } + // Font Options + $dataBlockFont .= pack('V', 0); + // Font weight + if($conditional->getStyle()->getFont()->getBold() == true){ + $dataBlockFont .= pack('v', 0x02BC); + } else { + $dataBlockFont .= pack('v', 0x0190); + } + // Escapement type + if($conditional->getStyle()->getFont()->getSubScript() == true){ + $dataBlockFont .= pack('v', 0x02); + $fontEscapement = 0; + } else if($conditional->getStyle()->getFont()->getSuperScript() == true){ + $dataBlockFont .= pack('v', 0x01); + $fontEscapement = 0; + } else { + $dataBlockFont .= pack('v', 0x00); + $fontEscapement = 1; + } + // Underline type + switch ($conditional->getStyle()->getFont()->getUnderline()){ + case PHPExcel_Style_Font::UNDERLINE_NONE : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_DOUBLE : $dataBlockFont .= pack('C', 0x02); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING : $dataBlockFont .= pack('C', 0x22); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_SINGLE : $dataBlockFont .= pack('C', 0x01); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING : $dataBlockFont .= pack('C', 0x21); $fontUnderline = 0; break; + default : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 1; break; + } + // Not used (3) + $dataBlockFont .= pack('vC', 0x0000, 0x00); + // Font color index + switch ($conditional->getStyle()->getFont()->getColor()->getRGB()) { + case '000000': $colorIdx = 0x08; break; + case 'FFFFFF': $colorIdx = 0x09; break; + case 'FF0000': $colorIdx = 0x0A; break; + case '00FF00': $colorIdx = 0x0B; break; + case '0000FF': $colorIdx = 0x0C; break; + case 'FFFF00': $colorIdx = 0x0D; break; + case 'FF00FF': $colorIdx = 0x0E; break; + case '00FFFF': $colorIdx = 0x0F; break; + case '800000': $colorIdx = 0x10; break; + case '008000': $colorIdx = 0x11; break; + case '000080': $colorIdx = 0x12; break; + case '808000': $colorIdx = 0x13; break; + case '800080': $colorIdx = 0x14; break; + case '008080': $colorIdx = 0x15; break; + case 'C0C0C0': $colorIdx = 0x16; break; + case '808080': $colorIdx = 0x17; break; + case '9999FF': $colorIdx = 0x18; break; + case '993366': $colorIdx = 0x19; break; + case 'FFFFCC': $colorIdx = 0x1A; break; + case 'CCFFFF': $colorIdx = 0x1B; break; + case '660066': $colorIdx = 0x1C; break; + case 'FF8080': $colorIdx = 0x1D; break; + case '0066CC': $colorIdx = 0x1E; break; + case 'CCCCFF': $colorIdx = 0x1F; break; + case '000080': $colorIdx = 0x20; break; + case 'FF00FF': $colorIdx = 0x21; break; + case 'FFFF00': $colorIdx = 0x22; break; + case '00FFFF': $colorIdx = 0x23; break; + case '800080': $colorIdx = 0x24; break; + case '800000': $colorIdx = 0x25; break; + case '008080': $colorIdx = 0x26; break; + case '0000FF': $colorIdx = 0x27; break; + case '00CCFF': $colorIdx = 0x28; break; + case 'CCFFFF': $colorIdx = 0x29; break; + case 'CCFFCC': $colorIdx = 0x2A; break; + case 'FFFF99': $colorIdx = 0x2B; break; + case '99CCFF': $colorIdx = 0x2C; break; + case 'FF99CC': $colorIdx = 0x2D; break; + case 'CC99FF': $colorIdx = 0x2E; break; + case 'FFCC99': $colorIdx = 0x2F; break; + case '3366FF': $colorIdx = 0x30; break; + case '33CCCC': $colorIdx = 0x31; break; + case '99CC00': $colorIdx = 0x32; break; + case 'FFCC00': $colorIdx = 0x33; break; + case 'FF9900': $colorIdx = 0x34; break; + case 'FF6600': $colorIdx = 0x35; break; + case '666699': $colorIdx = 0x36; break; + case '969696': $colorIdx = 0x37; break; + case '003366': $colorIdx = 0x38; break; + case '339966': $colorIdx = 0x39; break; + case '003300': $colorIdx = 0x3A; break; + case '333300': $colorIdx = 0x3B; break; + case '993300': $colorIdx = 0x3C; break; + case '993366': $colorIdx = 0x3D; break; + case '333399': $colorIdx = 0x3E; break; + case '333333': $colorIdx = 0x3F; break; + default: $colorIdx = 0x00; break; + } + $dataBlockFont .= pack('V', $colorIdx); + // Not used (4) + $dataBlockFont .= pack('V', 0x00000000); + // Options flags for modified font attributes + $optionsFlags = 0; + $optionsFlagsBold = ($conditional->getStyle()->getFont()->getBold() == null ? 1 : 0); + $optionsFlags |= (1 == $optionsFlagsBold ? 0x00000002 : 0); + $optionsFlags |= (1 == 1 ? 0x00000008 : 0); + $optionsFlags |= (1 == 1 ? 0x00000010 : 0); + $optionsFlags |= (1 == 0 ? 0x00000020 : 0); + $optionsFlags |= (1 == 1 ? 0x00000080 : 0); + $dataBlockFont .= pack('V', $optionsFlags); + // Escapement type + $dataBlockFont .= pack('V', $fontEscapement); + // Underline type + $dataBlockFont .= pack('V', $fontUnderline); + // Always + $dataBlockFont .= pack('V', 0x00000000); + // Always + $dataBlockFont .= pack('V', 0x00000000); + // Not used (8) + $dataBlockFont .= pack('VV', 0x00000000, 0x00000000); + // Always + $dataBlockFont .= pack('v', 0x0001); + } + if($bFormatAlign == 1){ + $blockAlign = 0; + // Alignment and text break + switch ($conditional->getStyle()->getAlignment()->getHorizontal()){ + case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL : $blockAlign = 0; break; + case PHPExcel_Style_Alignment::HORIZONTAL_LEFT : $blockAlign = 1; break; + case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT : $blockAlign = 3; break; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER : $blockAlign = 2; break; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS : $blockAlign = 6; break; + case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY : $blockAlign = 5; break; + } + if($conditional->getStyle()->getAlignment()->getWrapText() == true){ + $blockAlign |= 1 << 3; + } else { + $blockAlign |= 0 << 3; + } + switch ($conditional->getStyle()->getAlignment()->getVertical()){ + case PHPExcel_Style_Alignment::VERTICAL_BOTTOM : $blockAlign = 2 << 4; break; + case PHPExcel_Style_Alignment::VERTICAL_TOP : $blockAlign = 0 << 4; break; + case PHPExcel_Style_Alignment::VERTICAL_CENTER : $blockAlign = 1 << 4; break; + case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY : $blockAlign = 3 << 4; break; + } + $blockAlign |= 0 << 7; + + // Text rotation angle + $blockRotation = $conditional->getStyle()->getAlignment()->getTextRotation(); + + // Indentation + $blockIndent = $conditional->getStyle()->getAlignment()->getIndent(); + if($conditional->getStyle()->getAlignment()->getShrinkToFit() == true){ + $blockIndent |= 1 << 4; + } else { + $blockIndent |= 0 << 4; + } + $blockIndent |= 0 << 6; + + // Relative indentation + $blockIndentRelative = 255; + + $dataBlockAlign = pack('CCvvv', $blockAlign, $blockRotation, $blockIndent, $blockIndentRelative, 0x0000); + } + if($bFormatBorder == 1){ + $blockLineStyle = 0; + switch ($conditional->getStyle()->getBorders()->getLeft()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D; break; + } + switch ($conditional->getStyle()->getBorders()->getRight()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 4; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 4; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 4; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 4; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 4; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 4; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 4; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 4; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 4; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 4; break; + } + switch ($conditional->getStyle()->getBorders()->getTop()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 8; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 8; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 8; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 8; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 8; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 8; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 8; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 8; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 8; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 8; break; + } + switch ($conditional->getStyle()->getBorders()->getBottom()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 12; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 12; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 12; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 12; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 12; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 12; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 12; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 12; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 12; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 12; break; + } + //@todo _writeCFRule() => $blockLineStyle => Index Color for left line + //@todo _writeCFRule() => $blockLineStyle => Index Color for right line + //@todo _writeCFRule() => $blockLineStyle => Top-left to bottom-right on/off + //@todo _writeCFRule() => $blockLineStyle => Bottom-left to top-right on/off + $blockColor = 0; + //@todo _writeCFRule() => $blockColor => Index Color for top line + //@todo _writeCFRule() => $blockColor => Index Color for bottom line + //@todo _writeCFRule() => $blockColor => Index Color for diagonal line + switch ($conditional->getStyle()->getBorders()->getDiagonal()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockColor |= 0x00 << 21; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockColor |= 0x01 << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockColor |= 0x02 << 21; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockColor |= 0x03 << 21; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockColor |= 0x04 << 21; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockColor |= 0x05 << 21; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockColor |= 0x06 << 21; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockColor |= 0x07 << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockColor |= 0x08 << 21; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockColor |= 0x09 << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockColor |= 0x0A << 21; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockColor |= 0x0B << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockColor |= 0x0C << 21; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockColor |= 0x0D << 21; break; + } + $dataBlockBorder = pack('vv', $blockLineStyle, $blockColor); + } + if($bFormatFill == 1){ + // Fill Patern Style + $blockFillPatternStyle = 0; + switch ($conditional->getStyle()->getFill()->getFillType()){ + case PHPExcel_Style_Fill::FILL_NONE : $blockFillPatternStyle = 0x00; break; + case PHPExcel_Style_Fill::FILL_SOLID : $blockFillPatternStyle = 0x01; break; + case PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY : $blockFillPatternStyle = 0x02; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY : $blockFillPatternStyle = 0x03; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY : $blockFillPatternStyle = 0x04; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL : $blockFillPatternStyle = 0x05; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL : $blockFillPatternStyle = 0x06; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN : $blockFillPatternStyle = 0x07; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKUP : $blockFillPatternStyle = 0x08; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID : $blockFillPatternStyle = 0x09; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS : $blockFillPatternStyle = 0x0A; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL : $blockFillPatternStyle = 0x0B; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL : $blockFillPatternStyle = 0x0C; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN : $blockFillPatternStyle = 0x0D; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP : $blockFillPatternStyle = 0x0E; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID : $blockFillPatternStyle = 0x0F; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS : $blockFillPatternStyle = 0x10; break; + case PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 : $blockFillPatternStyle = 0x11; break; + case PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 : $blockFillPatternStyle = 0x12; break; + case PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR : $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 + case PHPExcel_Style_Fill::FILL_GRADIENT_PATH : $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 + default : $blockFillPatternStyle = 0x00; break; + } + // Color + switch ($conditional->getStyle()->getFill()->getStartColor()->getRGB()) { + case '000000': $colorIdxBg = 0x08; break; + case 'FFFFFF': $colorIdxBg = 0x09; break; + case 'FF0000': $colorIdxBg = 0x0A; break; + case '00FF00': $colorIdxBg = 0x0B; break; + case '0000FF': $colorIdxBg = 0x0C; break; + case 'FFFF00': $colorIdxBg = 0x0D; break; + case 'FF00FF': $colorIdxBg = 0x0E; break; + case '00FFFF': $colorIdxBg = 0x0F; break; + case '800000': $colorIdxBg = 0x10; break; + case '008000': $colorIdxBg = 0x11; break; + case '000080': $colorIdxBg = 0x12; break; + case '808000': $colorIdxBg = 0x13; break; + case '800080': $colorIdxBg = 0x14; break; + case '008080': $colorIdxBg = 0x15; break; + case 'C0C0C0': $colorIdxBg = 0x16; break; + case '808080': $colorIdxBg = 0x17; break; + case '9999FF': $colorIdxBg = 0x18; break; + case '993366': $colorIdxBg = 0x19; break; + case 'FFFFCC': $colorIdxBg = 0x1A; break; + case 'CCFFFF': $colorIdxBg = 0x1B; break; + case '660066': $colorIdxBg = 0x1C; break; + case 'FF8080': $colorIdxBg = 0x1D; break; + case '0066CC': $colorIdxBg = 0x1E; break; + case 'CCCCFF': $colorIdxBg = 0x1F; break; + case '000080': $colorIdxBg = 0x20; break; + case 'FF00FF': $colorIdxBg = 0x21; break; + case 'FFFF00': $colorIdxBg = 0x22; break; + case '00FFFF': $colorIdxBg = 0x23; break; + case '800080': $colorIdxBg = 0x24; break; + case '800000': $colorIdxBg = 0x25; break; + case '008080': $colorIdxBg = 0x26; break; + case '0000FF': $colorIdxBg = 0x27; break; + case '00CCFF': $colorIdxBg = 0x28; break; + case 'CCFFFF': $colorIdxBg = 0x29; break; + case 'CCFFCC': $colorIdxBg = 0x2A; break; + case 'FFFF99': $colorIdxBg = 0x2B; break; + case '99CCFF': $colorIdxBg = 0x2C; break; + case 'FF99CC': $colorIdxBg = 0x2D; break; + case 'CC99FF': $colorIdxBg = 0x2E; break; + case 'FFCC99': $colorIdxBg = 0x2F; break; + case '3366FF': $colorIdxBg = 0x30; break; + case '33CCCC': $colorIdxBg = 0x31; break; + case '99CC00': $colorIdxBg = 0x32; break; + case 'FFCC00': $colorIdxBg = 0x33; break; + case 'FF9900': $colorIdxBg = 0x34; break; + case 'FF6600': $colorIdxBg = 0x35; break; + case '666699': $colorIdxBg = 0x36; break; + case '969696': $colorIdxBg = 0x37; break; + case '003366': $colorIdxBg = 0x38; break; + case '339966': $colorIdxBg = 0x39; break; + case '003300': $colorIdxBg = 0x3A; break; + case '333300': $colorIdxBg = 0x3B; break; + case '993300': $colorIdxBg = 0x3C; break; + case '993366': $colorIdxBg = 0x3D; break; + case '333399': $colorIdxBg = 0x3E; break; + case '333333': $colorIdxBg = 0x3F; break; + default: $colorIdxBg = 0x41; break; + } + // Fg Color + switch ($conditional->getStyle()->getFill()->getEndColor()->getRGB()) { + case '000000': $colorIdxFg = 0x08; break; + case 'FFFFFF': $colorIdxFg = 0x09; break; + case 'FF0000': $colorIdxFg = 0x0A; break; + case '00FF00': $colorIdxFg = 0x0B; break; + case '0000FF': $colorIdxFg = 0x0C; break; + case 'FFFF00': $colorIdxFg = 0x0D; break; + case 'FF00FF': $colorIdxFg = 0x0E; break; + case '00FFFF': $colorIdxFg = 0x0F; break; + case '800000': $colorIdxFg = 0x10; break; + case '008000': $colorIdxFg = 0x11; break; + case '000080': $colorIdxFg = 0x12; break; + case '808000': $colorIdxFg = 0x13; break; + case '800080': $colorIdxFg = 0x14; break; + case '008080': $colorIdxFg = 0x15; break; + case 'C0C0C0': $colorIdxFg = 0x16; break; + case '808080': $colorIdxFg = 0x17; break; + case '9999FF': $colorIdxFg = 0x18; break; + case '993366': $colorIdxFg = 0x19; break; + case 'FFFFCC': $colorIdxFg = 0x1A; break; + case 'CCFFFF': $colorIdxFg = 0x1B; break; + case '660066': $colorIdxFg = 0x1C; break; + case 'FF8080': $colorIdxFg = 0x1D; break; + case '0066CC': $colorIdxFg = 0x1E; break; + case 'CCCCFF': $colorIdxFg = 0x1F; break; + case '000080': $colorIdxFg = 0x20; break; + case 'FF00FF': $colorIdxFg = 0x21; break; + case 'FFFF00': $colorIdxFg = 0x22; break; + case '00FFFF': $colorIdxFg = 0x23; break; + case '800080': $colorIdxFg = 0x24; break; + case '800000': $colorIdxFg = 0x25; break; + case '008080': $colorIdxFg = 0x26; break; + case '0000FF': $colorIdxFg = 0x27; break; + case '00CCFF': $colorIdxFg = 0x28; break; + case 'CCFFFF': $colorIdxFg = 0x29; break; + case 'CCFFCC': $colorIdxFg = 0x2A; break; + case 'FFFF99': $colorIdxFg = 0x2B; break; + case '99CCFF': $colorIdxFg = 0x2C; break; + case 'FF99CC': $colorIdxFg = 0x2D; break; + case 'CC99FF': $colorIdxFg = 0x2E; break; + case 'FFCC99': $colorIdxFg = 0x2F; break; + case '3366FF': $colorIdxFg = 0x30; break; + case '33CCCC': $colorIdxFg = 0x31; break; + case '99CC00': $colorIdxFg = 0x32; break; + case 'FFCC00': $colorIdxFg = 0x33; break; + case 'FF9900': $colorIdxFg = 0x34; break; + case 'FF6600': $colorIdxFg = 0x35; break; + case '666699': $colorIdxFg = 0x36; break; + case '969696': $colorIdxFg = 0x37; break; + case '003366': $colorIdxFg = 0x38; break; + case '339966': $colorIdxFg = 0x39; break; + case '003300': $colorIdxFg = 0x3A; break; + case '333300': $colorIdxFg = 0x3B; break; + case '993300': $colorIdxFg = 0x3C; break; + case '993366': $colorIdxFg = 0x3D; break; + case '333399': $colorIdxFg = 0x3E; break; + case '333333': $colorIdxFg = 0x3F; break; + default: $colorIdxFg = 0x40; break; + } + $dataBlockFill = pack('v', $blockFillPatternStyle); + $dataBlockFill .= pack('v', $colorIdxFg | ($colorIdxBg << 7)); + } + if($bFormatProt == 1){ + $dataBlockProtection = 0; + if($conditional->getStyle()->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){ + $dataBlockProtection = 1; + } + if($conditional->getStyle()->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){ + $dataBlockProtection = 1 << 1; + } + } + + $data = pack('CCvvVv', $type, $operatorType, $szValue1, $szValue2, $flags, 0x0000); + if($bFormatFont == 1){ // Block Formatting : OK + $data .= $dataBlockFont; + } + if($bFormatAlign == 1){ + $data .= $dataBlockAlign; + } + if($bFormatBorder == 1){ + $data .= $dataBlockBorder; + } + if($bFormatFill == 1){ // Block Formatting : OK + $data .= $dataBlockFill; + } + if($bFormatProt == 1){ + $data .= $dataBlockProtection; + } + if(!is_null($operand1)){ + $data .= $operand1; + } + if(!is_null($operand2)){ + $data .= $operand2; + } + $header = pack('vv', $record, strlen($data)); + $this->_append($header . $data); + } + + /** + * Write CFHeader record + */ + private function _writeCFHeader(){ + $record = 0x01B0; // Record identifier + $length = 0x0016; // Bytes to follow + + $numColumnMin = null; + $numColumnMax = null; + $numRowMin = null; + $numRowMax = null; + $arrConditional = array(); + foreach ($this->_phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { + foreach ($conditionalStyles as $conditional) { + if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ + if(!in_array($conditional->getHashCode(), $arrConditional)){ + $arrConditional[] = $conditional->getHashCode(); + } + // Cells + $arrCoord = PHPExcel_Cell::coordinateFromString($cellCoordinate); + if(!is_numeric($arrCoord[0])){ + $arrCoord[0] = PHPExcel_Cell::columnIndexFromString($arrCoord[0]); + } + if(is_null($numColumnMin) || ($numColumnMin > $arrCoord[0])){ + $numColumnMin = $arrCoord[0]; + } + if(is_null($numColumnMax) || ($numColumnMax < $arrCoord[0])){ + $numColumnMax = $arrCoord[0]; + } + if(is_null($numRowMin) || ($numRowMin > $arrCoord[1])){ + $numRowMin = $arrCoord[1]; + } + if(is_null($numRowMax) || ($numRowMax < $arrCoord[1])){ + $numRowMax = $arrCoord[1]; + } + } + } + } + $needRedraw = 1; + $cellRange = pack('vvvv', $numRowMin-1, $numRowMax-1, $numColumnMin-1, $numColumnMax-1); + + $header = pack('vv', $record, $length); + $data = pack('vv', count($arrConditional), $needRedraw); + $data .= $cellRange; + $data .= pack('v', 0x0001); + $data .= $cellRange; + $this->_append($header . $data); + } } \ No newline at end of file diff --git a/Classes/PHPExcel/Writer/Excel5/Xf.php b/Classes/PHPExcel/Writer/Excel5/Xf.php index 0fcdc691a..7347aabb7 100644 --- a/Classes/PHPExcel/Writer/Excel5/Xf.php +++ b/Classes/PHPExcel/Writer/Excel5/Xf.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -71,477 +71,477 @@ class PHPExcel_Writer_Excel5_Xf { /** - * Style XF or a cell XF ? - * - * @var boolean - */ - private $_isStyleXf; - - /** - * Index to the FONT record. Index 4 does not exist - * @var integer - */ - private $_fontIndex; - - /** - * An index (2 bytes) to a FORMAT record (number format). - * @var integer - */ - public $_numberFormatIndex; - - /** - * 1 bit, apparently not used. - * @var integer - */ - public $_text_justlast; - - /** - * The cell's foreground color. - * @var integer - */ - public $_fg_color; - - /** - * The cell's background color. - * @var integer - */ - public $_bg_color; - - /** - * Color of the bottom border of the cell. - * @var integer - */ - public $_bottom_color; - - /** - * Color of the top border of the cell. - * @var integer - */ - public $_top_color; - - /** - * Color of the left border of the cell. - * @var integer - */ - public $_left_color; - - /** - * Color of the right border of the cell. - * @var integer - */ - public $_right_color; - - /** - * Constructor - * - * @access public - * @param PHPExcel_Style The XF format - */ - public function __construct(PHPExcel_Style $style = null) - { - $this->_isStyleXf = false; - $this->_fontIndex = 0; - - $this->_numberFormatIndex = 0; - - $this->_text_justlast = 0; - - $this->_fg_color = 0x40; - $this->_bg_color = 0x41; - - $this->_diag = 0; - - $this->_bottom_color = 0x40; - $this->_top_color = 0x40; - $this->_left_color = 0x40; - $this->_right_color = 0x40; - $this->_diag_color = 0x40; - $this->_style = $style; - - } - - - /** - * Generate an Excel BIFF XF record (style or cell). - * - * @return string The XF record - */ - function writeXf() - { - // Set the type of the XF record and some of the attributes. - if ($this->_isStyleXf) { - $style = 0xFFF5; - } else { - $style = self::_mapLocked($this->_style->getProtection()->getLocked()); - $style |= self::_mapHidden($this->_style->getProtection()->getHidden()) << 1; - } - - // Flags to indicate if attributes have been set. - $atr_num = ($this->_numberFormatIndex != 0)?1:0; - $atr_fnt = ($this->_fontIndex != 0)?1:0; - $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0; - $atr_bdr = (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) || - self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) || - self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) || - self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()))?1:0; - $atr_pat = (($this->_fg_color != 0x40) || - ($this->_bg_color != 0x41) || - self::_mapFillType($this->_style->getFill()->getFillType()))?1:0; - $atr_prot = self::_mapLocked($this->_style->getProtection()->getLocked()) - | self::_mapHidden($this->_style->getProtection()->getHidden()); - - // Zero the default border colour if the border has not been set. - if (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) { - $this->_bottom_color = 0; - } - if (self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) { - $this->_top_color = 0; - } - if (self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) { - $this->_right_color = 0; - } - if (self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) { - $this->_left_color = 0; - } - if (self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) { - $this->_diag_color = 0; - } - - $record = 0x00E0; // Record identifier - $length = 0x0014; // Number of bytes to follow - - $ifnt = $this->_fontIndex; // Index to FONT record - $ifmt = $this->_numberFormatIndex; // Index to FORMAT record - - $align = $this->_mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment - $align |= (int) $this->_style->getAlignment()->getWrapText() << 3; - $align |= self::_mapVAlign($this->_style->getAlignment()->getVertical()) << 4; - $align |= $this->_text_justlast << 7; - - $used_attrib = $atr_num << 2; - $used_attrib |= $atr_fnt << 3; - $used_attrib |= $atr_alc << 4; - $used_attrib |= $atr_bdr << 5; - $used_attrib |= $atr_pat << 6; - $used_attrib |= $atr_prot << 7; - - $icv = $this->_fg_color; // fg and bg pattern colors - $icv |= $this->_bg_color << 7; - - $border1 = self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color - $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4; - $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8; - $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12; - $border1 |= $this->_left_color << 16; - $border1 |= $this->_right_color << 23; - - $diagonalDirection = $this->_style->getBorders()->getDiagonalDirection(); - $diag_tl_to_rb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH - || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_DOWN; - $diag_tr_to_lb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH - || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_UP; - $border1 |= $diag_tl_to_rb << 30; - $border1 |= $diag_tr_to_lb << 31; - - $border2 = $this->_top_color; // Border color - $border2 |= $this->_bottom_color << 7; - $border2 |= $this->_diag_color << 14; - $border2 |= self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21; - $border2 |= self::_mapFillType($this->_style->getFill()->getFillType()) << 26; - - $header = pack("vv", $record, $length); - - //BIFF8 options: identation, shrinkToFit and text direction - $biff8_options = $this->_style->getAlignment()->getIndent(); - $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4; - - $data = pack("vvvC", $ifnt, $ifmt, $style, $align); - $data .= pack("CCC" - , self::_mapTextRotation($this->_style->getAlignment()->getTextRotation()) - , $biff8_options - , $used_attrib - ); - $data .= pack("VVv", $border1, $border2, $icv); - - return($header . $data); - } - - /** - * Is this a style XF ? - * - * @param boolean $value - */ - public function setIsStyleXf($value) - { - $this->_isStyleXf = $value; - } - - /** - * Sets the cell's bottom border color - * - * @access public - * @param int $colorIndex Color index - */ - function setBottomColor($colorIndex) - { - $this->_bottom_color = $colorIndex; - } - - /** - * Sets the cell's top border color - * - * @access public - * @param int $colorIndex Color index - */ - function setTopColor($colorIndex) - { - $this->_top_color = $colorIndex; - } - - /** - * Sets the cell's left border color - * - * @access public - * @param int $colorIndex Color index - */ - function setLeftColor($colorIndex) - { - $this->_left_color = $colorIndex; - } - - /** - * Sets the cell's right border color - * - * @access public - * @param int $colorIndex Color index - */ - function setRightColor($colorIndex) - { - $this->_right_color = $colorIndex; - } - - /** - * Sets the cell's diagonal border color - * - * @access public - * @param int $colorIndex Color index - */ - function setDiagColor($colorIndex) - { - $this->_diag_color = $colorIndex; - } - - - /** - * Sets the cell's foreground color - * - * @access public - * @param int $colorIndex Color index - */ - function setFgColor($colorIndex) - { - $this->_fg_color = $colorIndex; - } - - /** - * Sets the cell's background color - * - * @access public - * @param int $colorIndex Color index - */ - function setBgColor($colorIndex) - { - $this->_bg_color = $colorIndex; - } - - /** - * Sets the index to the number format record - * It can be date, time, currency, etc... - * - * @access public - * @param integer $numberFormatIndex Index to format record - */ - function setNumberFormatIndex($numberFormatIndex) - { - $this->_numberFormatIndex = $numberFormatIndex; - } - - /** - * Set the font index. - * - * @param int $value Font index, note that value 4 does not exist - */ - public function setFontIndex($value) - { - $this->_fontIndex = $value; - } - - /** - * Map of BIFF2-BIFF8 codes for border styles - * @static array of int - * - */ - private static $_mapBorderStyle = array ( PHPExcel_Style_Border::BORDER_NONE => 0x00, - PHPExcel_Style_Border::BORDER_THIN => 0x01, - PHPExcel_Style_Border::BORDER_MEDIUM => 0x02, - PHPExcel_Style_Border::BORDER_DASHED => 0x03, - PHPExcel_Style_Border::BORDER_DOTTED => 0x04, - PHPExcel_Style_Border::BORDER_THICK => 0x05, - PHPExcel_Style_Border::BORDER_DOUBLE => 0x06, - PHPExcel_Style_Border::BORDER_HAIR => 0x07, - PHPExcel_Style_Border::BORDER_MEDIUMDASHED => 0x08, - PHPExcel_Style_Border::BORDER_DASHDOT => 0x09, - PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT => 0x0A, - PHPExcel_Style_Border::BORDER_DASHDOTDOT => 0x0B, - PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT => 0x0C, - PHPExcel_Style_Border::BORDER_SLANTDASHDOT => 0x0D, - ); - - /** - * Map border style - * - * @param string $borderStyle - * @return int - */ - private static function _mapBorderStyle($borderStyle) { - if (isset(self::$_mapBorderStyle[$borderStyle])) - return self::$_mapBorderStyle[$borderStyle]; - return 0x00; - } - - /** - * Map of BIFF2-BIFF8 codes for fill types - * @static array of int - * - */ - private static $_mapFillType = array( PHPExcel_Style_Fill::FILL_NONE => 0x00, - PHPExcel_Style_Fill::FILL_SOLID => 0x01, - PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY => 0x02, - PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY => 0x03, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY => 0x04, - PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL => 0x05, - PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL => 0x06, - PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN => 0x07, - PHPExcel_Style_Fill::FILL_PATTERN_DARKUP => 0x08, - PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID => 0x09, - PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS => 0x0A, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL => 0x0B, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL => 0x0C, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN => 0x0D, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP => 0x0E, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID => 0x0F, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS => 0x10, - PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 => 0x11, - PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 => 0x12, - PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR => 0x00, // does not exist in BIFF8 - PHPExcel_Style_Fill::FILL_GRADIENT_PATH => 0x00, // does not exist in BIFF8 - ); - /** - * Map fill type - * - * @param string $fillType - * @return int - */ - private static function _mapFillType($fillType) { - if (isset(self::$_mapFillType[$fillType])) - return self::$_mapFillType[$fillType]; - return 0x00; - } - - /** - * Map of BIFF2-BIFF8 codes for horizontal alignment - * @static array of int - * - */ - private static $_mapHAlign = array( PHPExcel_Style_Alignment::HORIZONTAL_GENERAL => 0, - PHPExcel_Style_Alignment::HORIZONTAL_LEFT => 1, - PHPExcel_Style_Alignment::HORIZONTAL_CENTER => 2, - PHPExcel_Style_Alignment::HORIZONTAL_RIGHT => 3, - PHPExcel_Style_Alignment::HORIZONTAL_FILL => 4, - PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY => 5, - PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6, - ); - /** - * Map to BIFF2-BIFF8 codes for horizontal alignment - * - * @param string $hAlign - * @return int - */ - private function _mapHAlign($hAlign) - { - if (isset(self::$_mapHAlign[$hAlign])) - return self::$_mapHAlign[$hAlign]; - return 0; - } - - /** - * Map of BIFF2-BIFF8 codes for vertical alignment - * @static array of int - * - */ - private static $_mapVAlign = array( PHPExcel_Style_Alignment::VERTICAL_TOP => 0, - PHPExcel_Style_Alignment::VERTICAL_CENTER => 1, - PHPExcel_Style_Alignment::VERTICAL_BOTTOM => 2, - PHPExcel_Style_Alignment::VERTICAL_JUSTIFY => 3, - ); - /** - * Map to BIFF2-BIFF8 codes for vertical alignment - * - * @param string $vAlign - * @return int - */ - private static function _mapVAlign($vAlign) { - if (isset(self::$_mapVAlign[$vAlign])) - return self::$_mapVAlign[$vAlign]; - return 2; - } - - /** - * Map to BIFF8 codes for text rotation angle - * - * @param int $textRotation - * @return int - */ - private static function _mapTextRotation($textRotation) { - if ($textRotation >= 0) { - return $textRotation; - } - if ($textRotation == -165) { - return 255; - } - if ($textRotation < 0) { - return 90 - $textRotation; - } - } - - /** - * Map locked - * - * @param string - * @return int - */ - private static function _mapLocked($locked) { - switch ($locked) { - case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 1; - case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; - case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; - default: return 1; - } - } - - /** - * Map hidden - * - * @param string - * @return int - */ - private static function _mapHidden($hidden) { - switch ($hidden) { - case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 0; - case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; - case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; - default: return 0; - } - } + * Style XF or a cell XF ? + * + * @var boolean + */ + private $_isStyleXf; + + /** + * Index to the FONT record. Index 4 does not exist + * @var integer + */ + private $_fontIndex; + + /** + * An index (2 bytes) to a FORMAT record (number format). + * @var integer + */ + public $_numberFormatIndex; + + /** + * 1 bit, apparently not used. + * @var integer + */ + public $_text_justlast; + + /** + * The cell's foreground color. + * @var integer + */ + public $_fg_color; + + /** + * The cell's background color. + * @var integer + */ + public $_bg_color; + + /** + * Color of the bottom border of the cell. + * @var integer + */ + public $_bottom_color; + + /** + * Color of the top border of the cell. + * @var integer + */ + public $_top_color; + + /** + * Color of the left border of the cell. + * @var integer + */ + public $_left_color; + + /** + * Color of the right border of the cell. + * @var integer + */ + public $_right_color; + + /** + * Constructor + * + * @access public + * @param PHPExcel_Style The XF format + */ + public function __construct(PHPExcel_Style $style = null) + { + $this->_isStyleXf = false; + $this->_fontIndex = 0; + + $this->_numberFormatIndex = 0; + + $this->_text_justlast = 0; + + $this->_fg_color = 0x40; + $this->_bg_color = 0x41; + + $this->_diag = 0; + + $this->_bottom_color = 0x40; + $this->_top_color = 0x40; + $this->_left_color = 0x40; + $this->_right_color = 0x40; + $this->_diag_color = 0x40; + $this->_style = $style; + + } + + + /** + * Generate an Excel BIFF XF record (style or cell). + * + * @return string The XF record + */ + function writeXf() + { + // Set the type of the XF record and some of the attributes. + if ($this->_isStyleXf) { + $style = 0xFFF5; + } else { + $style = self::_mapLocked($this->_style->getProtection()->getLocked()); + $style |= self::_mapHidden($this->_style->getProtection()->getHidden()) << 1; + } + + // Flags to indicate if attributes have been set. + $atr_num = ($this->_numberFormatIndex != 0)?1:0; + $atr_fnt = ($this->_fontIndex != 0)?1:0; + $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0; + $atr_bdr = (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) || + self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) || + self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) || + self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()))?1:0; + $atr_pat = (($this->_fg_color != 0x40) || + ($this->_bg_color != 0x41) || + self::_mapFillType($this->_style->getFill()->getFillType()))?1:0; + $atr_prot = self::_mapLocked($this->_style->getProtection()->getLocked()) + | self::_mapHidden($this->_style->getProtection()->getHidden()); + + // Zero the default border colour if the border has not been set. + if (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) { + $this->_bottom_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) { + $this->_top_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) { + $this->_right_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) { + $this->_left_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) { + $this->_diag_color = 0; + } + + $record = 0x00E0; // Record identifier + $length = 0x0014; // Number of bytes to follow + + $ifnt = $this->_fontIndex; // Index to FONT record + $ifmt = $this->_numberFormatIndex; // Index to FORMAT record + + $align = $this->_mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment + $align |= (int) $this->_style->getAlignment()->getWrapText() << 3; + $align |= self::_mapVAlign($this->_style->getAlignment()->getVertical()) << 4; + $align |= $this->_text_justlast << 7; + + $used_attrib = $atr_num << 2; + $used_attrib |= $atr_fnt << 3; + $used_attrib |= $atr_alc << 4; + $used_attrib |= $atr_bdr << 5; + $used_attrib |= $atr_pat << 6; + $used_attrib |= $atr_prot << 7; + + $icv = $this->_fg_color; // fg and bg pattern colors + $icv |= $this->_bg_color << 7; + + $border1 = self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color + $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4; + $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8; + $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12; + $border1 |= $this->_left_color << 16; + $border1 |= $this->_right_color << 23; + + $diagonalDirection = $this->_style->getBorders()->getDiagonalDirection(); + $diag_tl_to_rb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH + || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_DOWN; + $diag_tr_to_lb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH + || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_UP; + $border1 |= $diag_tl_to_rb << 30; + $border1 |= $diag_tr_to_lb << 31; + + $border2 = $this->_top_color; // Border color + $border2 |= $this->_bottom_color << 7; + $border2 |= $this->_diag_color << 14; + $border2 |= self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21; + $border2 |= self::_mapFillType($this->_style->getFill()->getFillType()) << 26; + + $header = pack("vv", $record, $length); + + //BIFF8 options: identation, shrinkToFit and text direction + $biff8_options = $this->_style->getAlignment()->getIndent(); + $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4; + + $data = pack("vvvC", $ifnt, $ifmt, $style, $align); + $data .= pack("CCC" + , self::_mapTextRotation($this->_style->getAlignment()->getTextRotation()) + , $biff8_options + , $used_attrib + ); + $data .= pack("VVv", $border1, $border2, $icv); + + return($header . $data); + } + + /** + * Is this a style XF ? + * + * @param boolean $value + */ + public function setIsStyleXf($value) + { + $this->_isStyleXf = $value; + } + + /** + * Sets the cell's bottom border color + * + * @access public + * @param int $colorIndex Color index + */ + function setBottomColor($colorIndex) + { + $this->_bottom_color = $colorIndex; + } + + /** + * Sets the cell's top border color + * + * @access public + * @param int $colorIndex Color index + */ + function setTopColor($colorIndex) + { + $this->_top_color = $colorIndex; + } + + /** + * Sets the cell's left border color + * + * @access public + * @param int $colorIndex Color index + */ + function setLeftColor($colorIndex) + { + $this->_left_color = $colorIndex; + } + + /** + * Sets the cell's right border color + * + * @access public + * @param int $colorIndex Color index + */ + function setRightColor($colorIndex) + { + $this->_right_color = $colorIndex; + } + + /** + * Sets the cell's diagonal border color + * + * @access public + * @param int $colorIndex Color index + */ + function setDiagColor($colorIndex) + { + $this->_diag_color = $colorIndex; + } + + + /** + * Sets the cell's foreground color + * + * @access public + * @param int $colorIndex Color index + */ + function setFgColor($colorIndex) + { + $this->_fg_color = $colorIndex; + } + + /** + * Sets the cell's background color + * + * @access public + * @param int $colorIndex Color index + */ + function setBgColor($colorIndex) + { + $this->_bg_color = $colorIndex; + } + + /** + * Sets the index to the number format record + * It can be date, time, currency, etc... + * + * @access public + * @param integer $numberFormatIndex Index to format record + */ + function setNumberFormatIndex($numberFormatIndex) + { + $this->_numberFormatIndex = $numberFormatIndex; + } + + /** + * Set the font index. + * + * @param int $value Font index, note that value 4 does not exist + */ + public function setFontIndex($value) + { + $this->_fontIndex = $value; + } + + /** + * Map of BIFF2-BIFF8 codes for border styles + * @static array of int + * + */ + private static $_mapBorderStyle = array ( PHPExcel_Style_Border::BORDER_NONE => 0x00, + PHPExcel_Style_Border::BORDER_THIN => 0x01, + PHPExcel_Style_Border::BORDER_MEDIUM => 0x02, + PHPExcel_Style_Border::BORDER_DASHED => 0x03, + PHPExcel_Style_Border::BORDER_DOTTED => 0x04, + PHPExcel_Style_Border::BORDER_THICK => 0x05, + PHPExcel_Style_Border::BORDER_DOUBLE => 0x06, + PHPExcel_Style_Border::BORDER_HAIR => 0x07, + PHPExcel_Style_Border::BORDER_MEDIUMDASHED => 0x08, + PHPExcel_Style_Border::BORDER_DASHDOT => 0x09, + PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT => 0x0A, + PHPExcel_Style_Border::BORDER_DASHDOTDOT => 0x0B, + PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT => 0x0C, + PHPExcel_Style_Border::BORDER_SLANTDASHDOT => 0x0D, + ); + + /** + * Map border style + * + * @param string $borderStyle + * @return int + */ + private static function _mapBorderStyle($borderStyle) { + if (isset(self::$_mapBorderStyle[$borderStyle])) + return self::$_mapBorderStyle[$borderStyle]; + return 0x00; + } + + /** + * Map of BIFF2-BIFF8 codes for fill types + * @static array of int + * + */ + private static $_mapFillType = array( PHPExcel_Style_Fill::FILL_NONE => 0x00, + PHPExcel_Style_Fill::FILL_SOLID => 0x01, + PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY => 0x02, + PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY => 0x03, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY => 0x04, + PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL => 0x05, + PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL => 0x06, + PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN => 0x07, + PHPExcel_Style_Fill::FILL_PATTERN_DARKUP => 0x08, + PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID => 0x09, + PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS => 0x0A, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL => 0x0B, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL => 0x0C, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN => 0x0D, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP => 0x0E, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID => 0x0F, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS => 0x10, + PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 => 0x11, + PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 => 0x12, + PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR => 0x00, // does not exist in BIFF8 + PHPExcel_Style_Fill::FILL_GRADIENT_PATH => 0x00, // does not exist in BIFF8 + ); + /** + * Map fill type + * + * @param string $fillType + * @return int + */ + private static function _mapFillType($fillType) { + if (isset(self::$_mapFillType[$fillType])) + return self::$_mapFillType[$fillType]; + return 0x00; + } + + /** + * Map of BIFF2-BIFF8 codes for horizontal alignment + * @static array of int + * + */ + private static $_mapHAlign = array( PHPExcel_Style_Alignment::HORIZONTAL_GENERAL => 0, + PHPExcel_Style_Alignment::HORIZONTAL_LEFT => 1, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER => 2, + PHPExcel_Style_Alignment::HORIZONTAL_RIGHT => 3, + PHPExcel_Style_Alignment::HORIZONTAL_FILL => 4, + PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY => 5, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6, + ); + /** + * Map to BIFF2-BIFF8 codes for horizontal alignment + * + * @param string $hAlign + * @return int + */ + private function _mapHAlign($hAlign) + { + if (isset(self::$_mapHAlign[$hAlign])) + return self::$_mapHAlign[$hAlign]; + return 0; + } + + /** + * Map of BIFF2-BIFF8 codes for vertical alignment + * @static array of int + * + */ + private static $_mapVAlign = array( PHPExcel_Style_Alignment::VERTICAL_TOP => 0, + PHPExcel_Style_Alignment::VERTICAL_CENTER => 1, + PHPExcel_Style_Alignment::VERTICAL_BOTTOM => 2, + PHPExcel_Style_Alignment::VERTICAL_JUSTIFY => 3, + ); + /** + * Map to BIFF2-BIFF8 codes for vertical alignment + * + * @param string $vAlign + * @return int + */ + private static function _mapVAlign($vAlign) { + if (isset(self::$_mapVAlign[$vAlign])) + return self::$_mapVAlign[$vAlign]; + return 2; + } + + /** + * Map to BIFF8 codes for text rotation angle + * + * @param int $textRotation + * @return int + */ + private static function _mapTextRotation($textRotation) { + if ($textRotation >= 0) { + return $textRotation; + } + if ($textRotation == -165) { + return 255; + } + if ($textRotation < 0) { + return 90 - $textRotation; + } + } + + /** + * Map locked + * + * @param string + * @return int + */ + private static function _mapLocked($locked) { + switch ($locked) { + case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 1; + case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; + case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; + default: return 1; + } + } + + /** + * Map hidden + * + * @param string + * @return int + */ + private static function _mapHidden($hidden) { + switch ($hidden) { + case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 0; + case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; + case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; + default: return 0; + } + } } diff --git a/Classes/PHPExcel/Writer/Exception.php b/Classes/PHPExcel/Writer/Exception.php index 5da3efd6b..bfa005681 100644 --- a/Classes/PHPExcel/Writer/Exception.php +++ b/Classes/PHPExcel/Writer/Exception.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Exception * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,32 +22,25 @@ * @category PHPExcel * @package PHPExcel_Writer * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_Writer_Exception - * - * @category PHPExcel - * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ -class PHPExcel_Writer_Exception extends PHPExcel_Exception { - /** - * Error handler callback - * - * @param mixed $code - * @param mixed $string - * @param mixed $file - * @param mixed $line - * @param mixed $context - */ - public static function errorHandlerCallback($code, $string, $file, $line, $context) { - $e = new self($string, $code); - $e->line = $line; - $e->file = $file; - throw $e; - } +class PHPExcel_Writer_Exception extends PHPExcel_Exception +{ + /** + * Error handler callback + * + * @param mixed $code + * @param mixed $string + * @param mixed $file + * @param mixed $line + * @param mixed $context + */ + public static function errorHandlerCallback($code, $string, $file, $line, $context) + { + $e = new self($string, $code); + $e->line = $line; + $e->file = $file; + throw $e; + } } diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 788c03cb0..42329b0e5 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_HTML * * Copyright (c) 2006 - 2015 PHPExcel * @@ -19,1113 +20,1105 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category PHPExcel - * @package PHPExcel_Writer_HTML + * @package PHPExcel_Writer_HTML * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_HTML - * - * @category PHPExcel - * @package PHPExcel_Writer_HTML - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ -class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { - /** - * PHPExcel object - * - * @var PHPExcel - */ - protected $_phpExcel; - - /** - * Sheet index to write - * - * @var int - */ - private $_sheetIndex = 0; - - /** - * Images root - * - * @var string - */ - private $_imagesRoot = '.'; - - /** - * embed images, or link to images - * - * @var boolean - */ - private $_embedImages = FALSE; - - /** - * Use inline CSS? - * - * @var boolean - */ - private $_useInlineCss = false; - - /** - * Array of CSS styles - * - * @var array - */ - private $_cssStyles = null; - - /** - * Array of column widths in points - * - * @var array - */ - private $_columnWidths = null; - - /** - * Default font - * - * @var PHPExcel_Style_Font - */ - private $_defaultFont; - - /** - * Flag whether spans have been calculated - * - * @var boolean - */ - private $_spansAreCalculated = false; - - /** - * Excel cells that should not be written as HTML cells - * - * @var array - */ - private $_isSpannedCell = array(); - - /** - * Excel cells that are upper-left corner in a cell merge - * - * @var array - */ - private $_isBaseCell = array(); - - /** - * Excel rows that should not be written as HTML rows - * - * @var array - */ - private $_isSpannedRow = array(); - - /** - * Is the current writer creating PDF? - * - * @var boolean - */ - protected $_isPdf = false; - - /** - * Generate the Navigation block - * - * @var boolean - */ - private $_generateSheetNavigationBlock = true; - - /** - * Create a new PHPExcel_Writer_HTML - * - * @param PHPExcel $phpExcel PHPExcel object - */ - public function __construct(PHPExcel $phpExcel) { - $this->_phpExcel = $phpExcel; - $this->_defaultFont = $this->_phpExcel->getDefaultStyle()->getFont(); - } - - /** - * Save PHPExcel to file - * - * @param string $pFilename - * @throws PHPExcel_Writer_Exception - */ - public function save($pFilename = null) { - // garbage collect - $this->_phpExcel->garbageCollect(); - - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); - $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); - PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); - - // Build CSS - $this->buildCSS(!$this->_useInlineCss); - - // Open file - $fileHandle = fopen($pFilename, 'wb+'); - if ($fileHandle === false) { - throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); - } - - // Write headers - fwrite($fileHandle, $this->generateHTMLHeader(!$this->_useInlineCss)); - - // Write navigation (tabs) - if ((!$this->_isPdf) && ($this->_generateSheetNavigationBlock)) { - fwrite($fileHandle, $this->generateNavigation()); - } - - // Write data - fwrite($fileHandle, $this->generateSheetData()); - - // Write footer - fwrite($fileHandle, $this->generateHTMLFooter()); - - // Close file - fclose($fileHandle); - - PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); - } - - /** - * Map VAlign - * - * @param string $vAlign Vertical alignment - * @return string - */ - private function _mapVAlign($vAlign) { - switch ($vAlign) { - case PHPExcel_Style_Alignment::VERTICAL_BOTTOM: return 'bottom'; - case PHPExcel_Style_Alignment::VERTICAL_TOP: return 'top'; - case PHPExcel_Style_Alignment::VERTICAL_CENTER: - case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY: return 'middle'; - default: return 'baseline'; - } - } - - /** - * Map HAlign - * - * @param string $hAlign Horizontal alignment - * @return string|false - */ - private function _mapHAlign($hAlign) { - switch ($hAlign) { - case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL: return false; - case PHPExcel_Style_Alignment::HORIZONTAL_LEFT: return 'left'; - case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: return 'right'; - case PHPExcel_Style_Alignment::HORIZONTAL_CENTER: - case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS: return 'center'; - case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY: return 'justify'; - default: return false; - } - } - - /** - * Map border style - * - * @param int $borderStyle Sheet index - * @return string - */ - private function _mapBorderStyle($borderStyle) { - switch ($borderStyle) { - case PHPExcel_Style_Border::BORDER_NONE: return 'none'; - case PHPExcel_Style_Border::BORDER_DASHDOT: return '1px dashed'; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT: return '1px dotted'; - case PHPExcel_Style_Border::BORDER_DASHED: return '1px dashed'; - case PHPExcel_Style_Border::BORDER_DOTTED: return '1px dotted'; - case PHPExcel_Style_Border::BORDER_DOUBLE: return '3px double'; - case PHPExcel_Style_Border::BORDER_HAIR: return '1px solid'; - case PHPExcel_Style_Border::BORDER_MEDIUM: return '2px solid'; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: return '2px dashed'; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: return '2px dotted'; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: return '2px dashed'; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: return '2px dashed'; - case PHPExcel_Style_Border::BORDER_THICK: return '3px solid'; - case PHPExcel_Style_Border::BORDER_THIN: return '1px solid'; - default: return '1px solid'; // map others to thin - } - } - - /** - * Get sheet index - * - * @return int - */ - public function getSheetIndex() { - return $this->_sheetIndex; - } - - /** - * Set sheet index - * - * @param int $pValue Sheet index - * @return PHPExcel_Writer_HTML - */ - public function setSheetIndex($pValue = 0) { - $this->_sheetIndex = $pValue; - return $this; - } - - /** - * Get sheet index - * - * @return boolean - */ - public function getGenerateSheetNavigationBlock() { - return $this->_generateSheetNavigationBlock; - } - - /** - * Set sheet index - * - * @param boolean $pValue Flag indicating whether the sheet navigation block should be generated or not - * @return PHPExcel_Writer_HTML - */ - public function setGenerateSheetNavigationBlock($pValue = true) { - $this->_generateSheetNavigationBlock = (bool) $pValue; - return $this; - } - - /** - * Write all sheets (resets sheetIndex to NULL) - */ - public function writeAllSheets() { - $this->_sheetIndex = null; - return $this; - } - - /** - * Generate HTML header - * - * @param boolean $pIncludeStyles Include styles? - * @return string - * @throws PHPExcel_Writer_Exception - */ - public function generateHTMLHeader($pIncludeStyles = false) { - // PHPExcel object known? - if (is_null($this->_phpExcel)) { - throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); - } - - // Construct HTML - $properties = $this->_phpExcel->getProperties(); - $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' . PHP_EOL; - $html .= '<!-- Generated by PHPExcel - http://www.phpexcel.net -->' . PHP_EOL; - $html .= '<html>' . PHP_EOL; - $html .= ' <head>' . PHP_EOL; - $html .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . PHP_EOL; - if ($properties->getTitle() > '') - $html .= ' <title>' . htmlspecialchars($properties->getTitle()) . '</title>' . PHP_EOL; - - if ($properties->getCreator() > '') - $html .= ' <meta name="author" content="' . htmlspecialchars($properties->getCreator()) . '" />' . PHP_EOL; - if ($properties->getTitle() > '') - $html .= ' <meta name="title" content="' . htmlspecialchars($properties->getTitle()) . '" />' . PHP_EOL; - if ($properties->getDescription() > '') - $html .= ' <meta name="description" content="' . htmlspecialchars($properties->getDescription()) . '" />' . PHP_EOL; - if ($properties->getSubject() > '') - $html .= ' <meta name="subject" content="' . htmlspecialchars($properties->getSubject()) . '" />' . PHP_EOL; - if ($properties->getKeywords() > '') - $html .= ' <meta name="keywords" content="' . htmlspecialchars($properties->getKeywords()) . '" />' . PHP_EOL; - if ($properties->getCategory() > '') - $html .= ' <meta name="category" content="' . htmlspecialchars($properties->getCategory()) . '" />' . PHP_EOL; - if ($properties->getCompany() > '') - $html .= ' <meta name="company" content="' . htmlspecialchars($properties->getCompany()) . '" />' . PHP_EOL; - if ($properties->getManager() > '') - $html .= ' <meta name="manager" content="' . htmlspecialchars($properties->getManager()) . '" />' . PHP_EOL; - - if ($pIncludeStyles) { - $html .= $this->generateStyles(true); - } - - $html .= ' </head>' . PHP_EOL; - $html .= '' . PHP_EOL; - $html .= ' <body>' . PHP_EOL; - - // Return - return $html; - } - - /** - * Generate sheet data - * - * @return string - * @throws PHPExcel_Writer_Exception - */ - public function generateSheetData() { - // PHPExcel object known? - if (is_null($this->_phpExcel)) { - throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); - } - - // Ensure that Spans have been calculated? - if (!$this->_spansAreCalculated) { - $this->_calculateSpans(); - } - - // Fetch sheets - $sheets = array(); - if (is_null($this->_sheetIndex)) { - $sheets = $this->_phpExcel->getAllSheets(); - } else { - $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); - } - - // Construct HTML - $html = ''; - - // Loop all sheets - $sheetId = 0; - foreach ($sheets as $sheet) { - // Write table header - $html .= $this->_generateTableHeader($sheet); - - // Get worksheet dimension - $dimension = explode(':', $sheet->calculateWorksheetDimension()); - $dimension[0] = PHPExcel_Cell::coordinateFromString($dimension[0]); - $dimension[0][0] = PHPExcel_Cell::columnIndexFromString($dimension[0][0]) - 1; - $dimension[1] = PHPExcel_Cell::coordinateFromString($dimension[1]); - $dimension[1][0] = PHPExcel_Cell::columnIndexFromString($dimension[1][0]) - 1; - - // row min,max - $rowMin = $dimension[0][1]; - $rowMax = $dimension[1][1]; - - // calculate start of <tbody>, <thead> - $tbodyStart = $rowMin; - $theadStart = $theadEnd = 0; // default: no <thead> no </thead> - if ($sheet->getPageSetup()->isRowsToRepeatAtTopSet()) { - $rowsToRepeatAtTop = $sheet->getPageSetup()->getRowsToRepeatAtTop(); - - // we can only support repeating rows that start at top row - if ($rowsToRepeatAtTop[0] == 1) { - $theadStart = $rowsToRepeatAtTop[0]; - $theadEnd = $rowsToRepeatAtTop[1]; - $tbodyStart = $rowsToRepeatAtTop[1] + 1; - } - } - - // Loop through cells - $row = $rowMin-1; - while($row++ < $rowMax) { - // <thead> ? - if ($row == $theadStart) { - $html .= ' <thead>' . PHP_EOL; +class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter +{ + /** + * PHPExcel object + * + * @var PHPExcel + */ + protected $_phpExcel; + + /** + * Sheet index to write + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Images root + * + * @var string + */ + private $_imagesRoot = '.'; + + /** + * embed images, or link to images + * + * @var boolean + */ + private $_embedImages = FALSE; + + /** + * Use inline CSS? + * + * @var boolean + */ + private $_useInlineCss = false; + + /** + * Array of CSS styles + * + * @var array + */ + private $_cssStyles = null; + + /** + * Array of column widths in points + * + * @var array + */ + private $_columnWidths = null; + + /** + * Default font + * + * @var PHPExcel_Style_Font + */ + private $_defaultFont; + + /** + * Flag whether spans have been calculated + * + * @var boolean + */ + private $_spansAreCalculated = false; + + /** + * Excel cells that should not be written as HTML cells + * + * @var array + */ + private $_isSpannedCell = array(); + + /** + * Excel cells that are upper-left corner in a cell merge + * + * @var array + */ + private $_isBaseCell = array(); + + /** + * Excel rows that should not be written as HTML rows + * + * @var array + */ + private $_isSpannedRow = array(); + + /** + * Is the current writer creating PDF? + * + * @var boolean + */ + protected $_isPdf = false; + + /** + * Generate the Navigation block + * + * @var boolean + */ + private $_generateSheetNavigationBlock = true; + + /** + * Create a new PHPExcel_Writer_HTML + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) { + $this->_phpExcel = $phpExcel; + $this->_defaultFont = $this->_phpExcel->getDefaultStyle()->getFont(); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) { + // garbage collect + $this->_phpExcel->garbageCollect(); + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); + + // Build CSS + $this->buildCSS(!$this->_useInlineCss); + + // Open file + $fileHandle = fopen($pFilename, 'wb+'); + if ($fileHandle === false) { + throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); + } + + // Write headers + fwrite($fileHandle, $this->generateHTMLHeader(!$this->_useInlineCss)); + + // Write navigation (tabs) + if ((!$this->_isPdf) && ($this->_generateSheetNavigationBlock)) { + fwrite($fileHandle, $this->generateNavigation()); + } + + // Write data + fwrite($fileHandle, $this->generateSheetData()); + + // Write footer + fwrite($fileHandle, $this->generateHTMLFooter()); + + // Close file + fclose($fileHandle); + + PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + } + + /** + * Map VAlign + * + * @param string $vAlign Vertical alignment + * @return string + */ + private function _mapVAlign($vAlign) { + switch ($vAlign) { + case PHPExcel_Style_Alignment::VERTICAL_BOTTOM: return 'bottom'; + case PHPExcel_Style_Alignment::VERTICAL_TOP: return 'top'; + case PHPExcel_Style_Alignment::VERTICAL_CENTER: + case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY: return 'middle'; + default: return 'baseline'; + } + } + + /** + * Map HAlign + * + * @param string $hAlign Horizontal alignment + * @return string|false + */ + private function _mapHAlign($hAlign) { + switch ($hAlign) { + case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL: return false; + case PHPExcel_Style_Alignment::HORIZONTAL_LEFT: return 'left'; + case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: return 'right'; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER: + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS: return 'center'; + case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY: return 'justify'; + default: return false; + } + } + + /** + * Map border style + * + * @param int $borderStyle Sheet index + * @return string + */ + private function _mapBorderStyle($borderStyle) { + switch ($borderStyle) { + case PHPExcel_Style_Border::BORDER_NONE: return 'none'; + case PHPExcel_Style_Border::BORDER_DASHDOT: return '1px dashed'; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT: return '1px dotted'; + case PHPExcel_Style_Border::BORDER_DASHED: return '1px dashed'; + case PHPExcel_Style_Border::BORDER_DOTTED: return '1px dotted'; + case PHPExcel_Style_Border::BORDER_DOUBLE: return '3px double'; + case PHPExcel_Style_Border::BORDER_HAIR: return '1px solid'; + case PHPExcel_Style_Border::BORDER_MEDIUM: return '2px solid'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: return '2px dashed'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: return '2px dotted'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: return '2px dashed'; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: return '2px dashed'; + case PHPExcel_Style_Border::BORDER_THICK: return '3px solid'; + case PHPExcel_Style_Border::BORDER_THIN: return '1px solid'; + default: return '1px solid'; // map others to thin + } + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Writer_HTML + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + + /** + * Get sheet index + * + * @return boolean + */ + public function getGenerateSheetNavigationBlock() { + return $this->_generateSheetNavigationBlock; + } + + /** + * Set sheet index + * + * @param boolean $pValue Flag indicating whether the sheet navigation block should be generated or not + * @return PHPExcel_Writer_HTML + */ + public function setGenerateSheetNavigationBlock($pValue = true) { + $this->_generateSheetNavigationBlock = (bool) $pValue; + return $this; + } + + /** + * Write all sheets (resets sheetIndex to NULL) + */ + public function writeAllSheets() { + $this->_sheetIndex = null; + return $this; + } + + /** + * Generate HTML header + * + * @param boolean $pIncludeStyles Include styles? + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateHTMLHeader($pIncludeStyles = false) { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Construct HTML + $properties = $this->_phpExcel->getProperties(); + $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' . PHP_EOL; + $html .= '<!-- Generated by PHPExcel - http://www.phpexcel.net -->' . PHP_EOL; + $html .= '<html>' . PHP_EOL; + $html .= ' <head>' . PHP_EOL; + $html .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . PHP_EOL; + if ($properties->getTitle() > '') + $html .= ' <title>' . htmlspecialchars($properties->getTitle()) . '</title>' . PHP_EOL; + + if ($properties->getCreator() > '') + $html .= ' <meta name="author" content="' . htmlspecialchars($properties->getCreator()) . '" />' . PHP_EOL; + if ($properties->getTitle() > '') + $html .= ' <meta name="title" content="' . htmlspecialchars($properties->getTitle()) . '" />' . PHP_EOL; + if ($properties->getDescription() > '') + $html .= ' <meta name="description" content="' . htmlspecialchars($properties->getDescription()) . '" />' . PHP_EOL; + if ($properties->getSubject() > '') + $html .= ' <meta name="subject" content="' . htmlspecialchars($properties->getSubject()) . '" />' . PHP_EOL; + if ($properties->getKeywords() > '') + $html .= ' <meta name="keywords" content="' . htmlspecialchars($properties->getKeywords()) . '" />' . PHP_EOL; + if ($properties->getCategory() > '') + $html .= ' <meta name="category" content="' . htmlspecialchars($properties->getCategory()) . '" />' . PHP_EOL; + if ($properties->getCompany() > '') + $html .= ' <meta name="company" content="' . htmlspecialchars($properties->getCompany()) . '" />' . PHP_EOL; + if ($properties->getManager() > '') + $html .= ' <meta name="manager" content="' . htmlspecialchars($properties->getManager()) . '" />' . PHP_EOL; + + if ($pIncludeStyles) { + $html .= $this->generateStyles(true); + } + + $html .= ' </head>' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= ' <body>' . PHP_EOL; + + // Return + return $html; + } + + /** + * Generate sheet data + * + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateSheetData() { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Ensure that Spans have been calculated? + if (!$this->_spansAreCalculated) { + $this->_calculateSpans(); + } + + // Fetch sheets + $sheets = array(); + if (is_null($this->_sheetIndex)) { + $sheets = $this->_phpExcel->getAllSheets(); + } else { + $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + } + + // Construct HTML + $html = ''; + + // Loop all sheets + $sheetId = 0; + foreach ($sheets as $sheet) { + // Write table header + $html .= $this->_generateTableHeader($sheet); + + // Get worksheet dimension + $dimension = explode(':', $sheet->calculateWorksheetDimension()); + $dimension[0] = PHPExcel_Cell::coordinateFromString($dimension[0]); + $dimension[0][0] = PHPExcel_Cell::columnIndexFromString($dimension[0][0]) - 1; + $dimension[1] = PHPExcel_Cell::coordinateFromString($dimension[1]); + $dimension[1][0] = PHPExcel_Cell::columnIndexFromString($dimension[1][0]) - 1; + + // row min,max + $rowMin = $dimension[0][1]; + $rowMax = $dimension[1][1]; + + // calculate start of <tbody>, <thead> + $tbodyStart = $rowMin; + $theadStart = $theadEnd = 0; // default: no <thead> no </thead> + if ($sheet->getPageSetup()->isRowsToRepeatAtTopSet()) { + $rowsToRepeatAtTop = $sheet->getPageSetup()->getRowsToRepeatAtTop(); + + // we can only support repeating rows that start at top row + if ($rowsToRepeatAtTop[0] == 1) { + $theadStart = $rowsToRepeatAtTop[0]; + $theadEnd = $rowsToRepeatAtTop[1]; + $tbodyStart = $rowsToRepeatAtTop[1] + 1; + } + } + + // Loop through cells + $row = $rowMin-1; + while($row++ < $rowMax) { + // <thead> ? + if ($row == $theadStart) { + $html .= ' <thead>' . PHP_EOL; $cellType = 'th'; - } + } - // <tbody> ? - if ($row == $tbodyStart) { - $html .= ' <tbody>' . PHP_EOL; + // <tbody> ? + if ($row == $tbodyStart) { + $html .= ' <tbody>' . PHP_EOL; $cellType = 'td'; - } - - // Write row if there are HTML table cells in it - if ( !isset($this->_isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row]) ) { - // Start a new rowData - $rowData = array(); - // Loop through columns - $column = $dimension[0][0] - 1; - while($column++ < $dimension[1][0]) { - // Cell exists? - if ($sheet->cellExistsByColumnAndRow($column, $row)) { - $rowData[$column] = PHPExcel_Cell::stringFromColumnIndex($column) . $row; - } else { - $rowData[$column] = ''; - } - } - $html .= $this->_generateRow($sheet, $rowData, $row - 1, $cellType); - } - - // </thead> ? - if ($row == $theadEnd) { - $html .= ' </thead>' . PHP_EOL; - } - } - $html .= $this->_extendRowsForChartsAndImages($sheet, $row); - - // Close table body. - $html .= ' </tbody>' . PHP_EOL; - - // Write table footer - $html .= $this->_generateTableFooter(); - - // Writing PDF? - if ($this->_isPdf) { - if (is_null($this->_sheetIndex) && $sheetId + 1 < $this->_phpExcel->getSheetCount()) { - $html .= '<div style="page-break-before:always" />'; - } - } - - // Next sheet - ++$sheetId; - } - - // Return - return $html; - } - - /** - * Generate sheet tabs - * - * @return string - * @throws PHPExcel_Writer_Exception - */ - public function generateNavigation() - { - // PHPExcel object known? - if (is_null($this->_phpExcel)) { - throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); - } - - // Fetch sheets - $sheets = array(); - if (is_null($this->_sheetIndex)) { - $sheets = $this->_phpExcel->getAllSheets(); - } else { - $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); - } - - // Construct HTML - $html = ''; - - // Only if there are more than 1 sheets - if (count($sheets) > 1) { - // Loop all sheets - $sheetId = 0; - - $html .= '<ul class="navigation">' . PHP_EOL; - - foreach ($sheets as $sheet) { - $html .= ' <li class="sheet' . $sheetId . '"><a href="#sheet' . $sheetId . '">' . $sheet->getTitle() . '</a></li>' . PHP_EOL; - ++$sheetId; - } - - $html .= '</ul>' . PHP_EOL; - } - - return $html; - } - - private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) { - $rowMax = $row; - $colMax = 'A'; - if ($this->_includeCharts) { - foreach ($pSheet->getChartCollection() as $chart) { - if ($chart instanceof PHPExcel_Chart) { - $chartCoordinates = $chart->getTopLeftPosition(); - $chartTL = PHPExcel_Cell::coordinateFromString($chartCoordinates['cell']); - $chartCol = PHPExcel_Cell::columnIndexFromString($chartTL[0]); - if ($chartTL[1] > $rowMax) { - $rowMax = $chartTL[1]; - if ($chartCol > PHPExcel_Cell::columnIndexFromString($colMax)) { - $colMax = $chartTL[0]; - } - } - } - } - } - - foreach ($pSheet->getDrawingCollection() as $drawing) { - if ($drawing instanceof PHPExcel_Worksheet_Drawing) { - $imageTL = PHPExcel_Cell::coordinateFromString($drawing->getCoordinates()); - $imageCol = PHPExcel_Cell::columnIndexFromString($imageTL[0]); - if ($imageTL[1] > $rowMax) { - $rowMax = $imageTL[1]; - if ($imageCol > PHPExcel_Cell::columnIndexFromString($colMax)) { - $colMax = $imageTL[0]; - } - } - } - } - $html = ''; - $colMax++; - while ($row < $rowMax) { - $html .= '<tr>'; - for ($col = 'A'; $col != $colMax; ++$col) { - $html .= '<td>'; - $html .= $this->_writeImageInCell($pSheet, $col.$row); - if ($this->_includeCharts) { - $html .= $this->_writeChartInCell($pSheet, $col.$row); - } - $html .= '</td>'; - } - ++$row; - $html .= '</tr>'; - } - return $html; - } - - - /** - * Generate image tag in cell - * - * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet - * @param string $coordinates Cell coordinates - * @return string - * @throws PHPExcel_Writer_Exception - */ - private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { - // Construct HTML - $html = ''; - - // Write images - foreach ($pSheet->getDrawingCollection() as $drawing) { - if ($drawing instanceof PHPExcel_Worksheet_Drawing) { - if ($drawing->getCoordinates() == $coordinates) { - $filename = $drawing->getPath(); - - // Strip off eventual '.' - if (substr($filename, 0, 1) == '.') { - $filename = substr($filename, 1); - } - - // Prepend images root - $filename = $this->getImagesRoot() . $filename; - - // Strip off eventual '.' - if (substr($filename, 0, 1) == '.' && substr($filename, 0, 2) != './') { - $filename = substr($filename, 1); - } - - // Convert UTF8 data to PCDATA - $filename = htmlspecialchars($filename); - - $html .= PHP_EOL; - if ((!$this->_embedImages) || ($this->_isPdf)) { - $imageData = $filename; - } else { - $imageDetails = getimagesize($filename); - if ($fp = fopen($filename,"rb", 0)) { - $picture = fread($fp,filesize($filename)); - fclose($fp); - // base64 encode the binary data, then break it - // into chunks according to RFC 2045 semantics - $base64 = chunk_split(base64_encode($picture)); - $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64; - } else { - $imageData = $filename; - } - } - - $html .= '<div style="position: relative;">'; - $html .= '<img style="position: absolute; z-index: 1; left: ' . + } + + // Write row if there are HTML table cells in it + if ( !isset($this->_isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row]) ) { + // Start a new rowData + $rowData = array(); + // Loop through columns + $column = $dimension[0][0] - 1; + while($column++ < $dimension[1][0]) { + // Cell exists? + if ($sheet->cellExistsByColumnAndRow($column, $row)) { + $rowData[$column] = PHPExcel_Cell::stringFromColumnIndex($column) . $row; + } else { + $rowData[$column] = ''; + } + } + $html .= $this->_generateRow($sheet, $rowData, $row - 1, $cellType); + } + + // </thead> ? + if ($row == $theadEnd) { + $html .= ' </thead>' . PHP_EOL; + } + } + $html .= $this->_extendRowsForChartsAndImages($sheet, $row); + + // Close table body. + $html .= ' </tbody>' . PHP_EOL; + + // Write table footer + $html .= $this->_generateTableFooter(); + + // Writing PDF? + if ($this->_isPdf) { + if (is_null($this->_sheetIndex) && $sheetId + 1 < $this->_phpExcel->getSheetCount()) { + $html .= '<div style="page-break-before:always" />'; + } + } + + // Next sheet + ++$sheetId; + } + + // Return + return $html; + } + + /** + * Generate sheet tabs + * + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateNavigation() + { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Fetch sheets + $sheets = array(); + if (is_null($this->_sheetIndex)) { + $sheets = $this->_phpExcel->getAllSheets(); + } else { + $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + } + + // Construct HTML + $html = ''; + + // Only if there are more than 1 sheets + if (count($sheets) > 1) { + // Loop all sheets + $sheetId = 0; + + $html .= '<ul class="navigation">' . PHP_EOL; + + foreach ($sheets as $sheet) { + $html .= ' <li class="sheet' . $sheetId . '"><a href="#sheet' . $sheetId . '">' . $sheet->getTitle() . '</a></li>' . PHP_EOL; + ++$sheetId; + } + + $html .= '</ul>' . PHP_EOL; + } + + return $html; + } + + private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) { + $rowMax = $row; + $colMax = 'A'; + if ($this->_includeCharts) { + foreach ($pSheet->getChartCollection() as $chart) { + if ($chart instanceof PHPExcel_Chart) { + $chartCoordinates = $chart->getTopLeftPosition(); + $chartTL = PHPExcel_Cell::coordinateFromString($chartCoordinates['cell']); + $chartCol = PHPExcel_Cell::columnIndexFromString($chartTL[0]); + if ($chartTL[1] > $rowMax) { + $rowMax = $chartTL[1]; + if ($chartCol > PHPExcel_Cell::columnIndexFromString($colMax)) { + $colMax = $chartTL[0]; + } + } + } + } + } + + foreach ($pSheet->getDrawingCollection() as $drawing) { + if ($drawing instanceof PHPExcel_Worksheet_Drawing) { + $imageTL = PHPExcel_Cell::coordinateFromString($drawing->getCoordinates()); + $imageCol = PHPExcel_Cell::columnIndexFromString($imageTL[0]); + if ($imageTL[1] > $rowMax) { + $rowMax = $imageTL[1]; + if ($imageCol > PHPExcel_Cell::columnIndexFromString($colMax)) { + $colMax = $imageTL[0]; + } + } + } + } + $html = ''; + $colMax++; + while ($row < $rowMax) { + $html .= '<tr>'; + for ($col = 'A'; $col != $colMax; ++$col) { + $html .= '<td>'; + $html .= $this->_writeImageInCell($pSheet, $col.$row); + if ($this->_includeCharts) { + $html .= $this->_writeChartInCell($pSheet, $col.$row); + } + $html .= '</td>'; + } + ++$row; + $html .= '</tr>'; + } + return $html; + } + + + /** + * Generate image tag in cell + * + * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet + * @param string $coordinates Cell coordinates + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { + // Construct HTML + $html = ''; + + // Write images + foreach ($pSheet->getDrawingCollection() as $drawing) { + if ($drawing instanceof PHPExcel_Worksheet_Drawing) { + if ($drawing->getCoordinates() == $coordinates) { + $filename = $drawing->getPath(); + + // Strip off eventual '.' + if (substr($filename, 0, 1) == '.') { + $filename = substr($filename, 1); + } + + // Prepend images root + $filename = $this->getImagesRoot() . $filename; + + // Strip off eventual '.' + if (substr($filename, 0, 1) == '.' && substr($filename, 0, 2) != './') { + $filename = substr($filename, 1); + } + + // Convert UTF8 data to PCDATA + $filename = htmlspecialchars($filename); + + $html .= PHP_EOL; + if ((!$this->_embedImages) || ($this->_isPdf)) { + $imageData = $filename; + } else { + $imageDetails = getimagesize($filename); + if ($fp = fopen($filename,"rb", 0)) { + $picture = fread($fp,filesize($filename)); + fclose($fp); + // base64 encode the binary data, then break it + // into chunks according to RFC 2045 semantics + $base64 = chunk_split(base64_encode($picture)); + $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64; + } else { + $imageData = $filename; + } + } + + $html .= '<div style="position: relative;">'; + $html .= '<img style="position: absolute; z-index: 1; left: ' . $drawing->getOffsetX() . 'px; top: ' . $drawing->getOffsetY() . 'px; width: ' . $drawing->getWidth() . 'px; height: ' . $drawing->getHeight() . 'px;" src="' . $imageData . '" border="0" />'; - $html .= '</div>'; - } - } - } - - // Return - return $html; - } - - /** - * Generate chart tag in cell - * - * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet - * @param string $coordinates Cell coordinates - * @return string - * @throws PHPExcel_Writer_Exception - */ - private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) { - // Construct HTML - $html = ''; - - // Write charts - foreach ($pSheet->getChartCollection() as $chart) { - if ($chart instanceof PHPExcel_Chart) { - $chartCoordinates = $chart->getTopLeftPosition(); - if ($chartCoordinates['cell'] == $coordinates) { - $chartFileName = PHPExcel_Shared_File::sys_get_temp_dir().'/'.uniqid().'.png'; - if (!$chart->render($chartFileName)) { - return; - } - - $html .= PHP_EOL; - $imageDetails = getimagesize($chartFileName); - if ($fp = fopen($chartFileName,"rb", 0)) { - $picture = fread($fp,filesize($chartFileName)); - fclose($fp); - // base64 encode the binary data, then break it - // into chunks according to RFC 2045 semantics - $base64 = chunk_split(base64_encode($picture)); - $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64; - - $html .= '<div style="position: relative;">'; - $html .= '<img style="position: absolute; z-index: 1; left: ' . $chartCoordinates['xOffset'] . 'px; top: ' . $chartCoordinates['yOffset'] . 'px; width: ' . $imageDetails[0] . 'px; height: ' . $imageDetails[1] . 'px;" src="' . $imageData . '" border="0" />' . PHP_EOL; - $html .= '</div>'; - - unlink($chartFileName); - } - } - } - } - - // Return - return $html; - } - - /** - * Generate CSS styles - * - * @param boolean $generateSurroundingHTML Generate surrounding HTML tags? (&lt;style&gt; and &lt;/style&gt;) - * @return string - * @throws PHPExcel_Writer_Exception - */ - public function generateStyles($generateSurroundingHTML = true) { - // PHPExcel object known? - if (is_null($this->_phpExcel)) { - throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); - } - - // Build CSS - $css = $this->buildCSS($generateSurroundingHTML); - - // Construct HTML - $html = ''; - - // Start styles - if ($generateSurroundingHTML) { - $html .= ' <style type="text/css">' . PHP_EOL; - $html .= ' html { ' . $this->_assembleCSS($css['html']) . ' }' . PHP_EOL; - } - - // Write all other styles - foreach ($css as $styleName => $styleDefinition) { - if ($styleName != 'html') { - $html .= ' ' . $styleName . ' { ' . $this->_assembleCSS($styleDefinition) . ' }' . PHP_EOL; - } - } - - // End styles - if ($generateSurroundingHTML) { - $html .= ' </style>' . PHP_EOL; - } - - // Return - return $html; - } - - /** - * Build CSS styles - * - * @param boolean $generateSurroundingHTML Generate surrounding HTML style? (html { }) - * @return array - * @throws PHPExcel_Writer_Exception - */ - public function buildCSS($generateSurroundingHTML = true) { - // PHPExcel object known? - if (is_null($this->_phpExcel)) { - throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); - } - - // Cached? - if (!is_null($this->_cssStyles)) { - return $this->_cssStyles; - } - - // Ensure that spans have been calculated - if (!$this->_spansAreCalculated) { - $this->_calculateSpans(); - } - - // Construct CSS - $css = array(); - - // Start styles - if ($generateSurroundingHTML) { - // html { } - $css['html']['font-family'] = 'Calibri, Arial, Helvetica, sans-serif'; - $css['html']['font-size'] = '11pt'; - $css['html']['background-color'] = 'white'; - } - - - // table { } - $css['table']['border-collapse'] = 'collapse'; - if (!$this->_isPdf) { - $css['table']['page-break-after'] = 'always'; - } - - // .gridlines td { } - $css['.gridlines td']['border'] = '1px dotted black'; - $css['.gridlines th']['border'] = '1px dotted black'; - - // .b {} - $css['.b']['text-align'] = 'center'; // BOOL - - // .e {} - $css['.e']['text-align'] = 'center'; // ERROR - - // .f {} - $css['.f']['text-align'] = 'right'; // FORMULA - - // .inlineStr {} - $css['.inlineStr']['text-align'] = 'left'; // INLINE - - // .n {} - $css['.n']['text-align'] = 'right'; // NUMERIC - - // .s {} - $css['.s']['text-align'] = 'left'; // STRING - - // Calculate cell style hashes - foreach ($this->_phpExcel->getCellXfCollection() as $index => $style) { - $css['td.style' . $index] = $this->_createCSSStyle( $style ); - $css['th.style' . $index] = $this->_createCSSStyle( $style ); - } - - // Fetch sheets - $sheets = array(); - if (is_null($this->_sheetIndex)) { - $sheets = $this->_phpExcel->getAllSheets(); - } else { - $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); - } - - // Build styles per sheet - foreach ($sheets as $sheet) { - // Calculate hash code - $sheetIndex = $sheet->getParent()->getIndex($sheet); - - // Build styles - // Calculate column widths - $sheet->calculateColumnWidths(); - - // col elements, initialize - $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()) - 1; - $column = -1; - while($column++ < $highestColumnIndex) { - $this->_columnWidths[$sheetIndex][$column] = 42; // approximation - $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = '42pt'; - } - - // col elements, loop through columnDimensions and set width - foreach ($sheet->getColumnDimensions() as $columnDimension) { - if (($width = PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth(), $this->_defaultFont)) >= 0) { - $width = PHPExcel_Shared_Drawing::pixelsToPoints($width); - $column = PHPExcel_Cell::columnIndexFromString($columnDimension->getColumnIndex()) - 1; - $this->_columnWidths[$sheetIndex][$column] = $width; - $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = $width . 'pt'; - - if ($columnDimension->getVisible() === false) { - $css['table.sheet' . $sheetIndex . ' col.col' . $column]['visibility'] = 'collapse'; - $css['table.sheet' . $sheetIndex . ' col.col' . $column]['*display'] = 'none'; // target IE6+7 - } - } - } - - // Default row height - $rowDimension = $sheet->getDefaultRowDimension(); - - // table.sheetN tr { } - $css['table.sheet' . $sheetIndex . ' tr'] = array(); - - if ($rowDimension->getRowHeight() == -1) { - $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont()); - } else { - $pt_height = $rowDimension->getRowHeight(); - } - $css['table.sheet' . $sheetIndex . ' tr']['height'] = $pt_height . 'pt'; - if ($rowDimension->getVisible() === false) { - $css['table.sheet' . $sheetIndex . ' tr']['display'] = 'none'; - $css['table.sheet' . $sheetIndex . ' tr']['visibility'] = 'hidden'; - } - - // Calculate row heights - foreach ($sheet->getRowDimensions() as $rowDimension) { - $row = $rowDimension->getRowIndex() - 1; - - // table.sheetN tr.rowYYYYYY { } - $css['table.sheet' . $sheetIndex . ' tr.row' . $row] = array(); - - if ($rowDimension->getRowHeight() == -1) { - $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont()); - } else { - $pt_height = $rowDimension->getRowHeight(); - } - $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['height'] = $pt_height . 'pt'; - if ($rowDimension->getVisible() === false) { - $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['display'] = 'none'; - $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['visibility'] = 'hidden'; - } - } - } - - // Cache - if (is_null($this->_cssStyles)) { - $this->_cssStyles = $css; - } - - // Return - return $css; - } - - /** - * Create CSS style - * - * @param PHPExcel_Style $pStyle PHPExcel_Style - * @return array - */ - private function _createCSSStyle(PHPExcel_Style $pStyle) { - // Construct CSS - $css = ''; - - // Create CSS - $css = array_merge( - $this->_createCSSStyleAlignment($pStyle->getAlignment()) - , $this->_createCSSStyleBorders($pStyle->getBorders()) - , $this->_createCSSStyleFont($pStyle->getFont()) - , $this->_createCSSStyleFill($pStyle->getFill()) - ); - - // Return - return $css; - } - - /** - * Create CSS style (PHPExcel_Style_Alignment) - * - * @param PHPExcel_Style_Alignment $pStyle PHPExcel_Style_Alignment - * @return array - */ - private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) { - // Construct CSS - $css = array(); - - // Create CSS - $css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical()); - if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) { - $css['text-align'] = $textAlign; - if(in_array($textAlign,array('left','right'))) - $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px'; - } - - // Return - return $css; - } - - /** - * Create CSS style (PHPExcel_Style_Font) - * - * @param PHPExcel_Style_Font $pStyle PHPExcel_Style_Font - * @return array - */ - private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) { - // Construct CSS - $css = array(); - - // Create CSS - if ($pStyle->getBold()) { - $css['font-weight'] = 'bold'; - } - if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) { - $css['text-decoration'] = 'underline line-through'; - } else if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE) { - $css['text-decoration'] = 'underline'; - } else if ($pStyle->getStrikethrough()) { - $css['text-decoration'] = 'line-through'; - } - if ($pStyle->getItalic()) { - $css['font-style'] = 'italic'; - } - - $css['color'] = '#' . $pStyle->getColor()->getRGB(); - $css['font-family'] = '\'' . $pStyle->getName() . '\''; - $css['font-size'] = $pStyle->getSize() . 'pt'; - - // Return - return $css; - } - - /** - * Create CSS style (PHPExcel_Style_Borders) - * - * @param PHPExcel_Style_Borders $pStyle PHPExcel_Style_Borders - * @return array - */ - private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) { - // Construct CSS - $css = array(); - - // Create CSS - $css['border-bottom'] = $this->_createCSSStyleBorder($pStyle->getBottom()); - $css['border-top'] = $this->_createCSSStyleBorder($pStyle->getTop()); - $css['border-left'] = $this->_createCSSStyleBorder($pStyle->getLeft()); - $css['border-right'] = $this->_createCSSStyleBorder($pStyle->getRight()); - - // Return - return $css; - } - - /** - * Create CSS style (PHPExcel_Style_Border) - * - * @param PHPExcel_Style_Border $pStyle PHPExcel_Style_Border - * @return string - */ - private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) { - // Create CSS -// $css = $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); - // Create CSS - add !important to non-none border styles for merged cells - $borderStyle = $this->_mapBorderStyle($pStyle->getBorderStyle()); - $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); - - // Return - return $css; - } - - /** - * Create CSS style (PHPExcel_Style_Fill) - * - * @param PHPExcel_Style_Fill $pStyle PHPExcel_Style_Fill - * @return array - */ - private function _createCSSStyleFill(PHPExcel_Style_Fill $pStyle) { - // Construct HTML - $css = array(); - - // Create CSS - $value = $pStyle->getFillType() == PHPExcel_Style_Fill::FILL_NONE ? - 'white' : '#' . $pStyle->getStartColor()->getRGB(); - $css['background-color'] = $value; - - // Return - return $css; - } - - /** - * Generate HTML footer - */ - public function generateHTMLFooter() { - // Construct HTML - $html = ''; - $html .= ' </body>' . PHP_EOL; - $html .= '</html>' . PHP_EOL; - - // Return - return $html; - } - - /** - * Generate table header - * - * @param PHPExcel_Worksheet $pSheet The worksheet for the table we are writing - * @return string - * @throws PHPExcel_Writer_Exception - */ - private function _generateTableHeader($pSheet) { - $sheetIndex = $pSheet->getParent()->getIndex($pSheet); - - // Construct HTML - $html = ''; - $html .= $this->_setMargins($pSheet); - - if (!$this->_useInlineCss) { - $gridlines = $pSheet->getShowGridlines() ? ' gridlines' : ''; - $html .= ' <table border="0" cellpadding="0" cellspacing="0" id="sheet' . $sheetIndex . '" class="sheet' . $sheetIndex . $gridlines . '">' . PHP_EOL; - } else { - $style = isset($this->_cssStyles['table']) ? - $this->_assembleCSS($this->_cssStyles['table']) : ''; - - if ($this->_isPdf && $pSheet->getShowGridlines()) { - $html .= ' <table border="1" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="1" style="' . $style . '">' . PHP_EOL; - } else { - $html .= ' <table border="0" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="0" style="' . $style . '">' . PHP_EOL; - } - } - - // Write <col> elements - $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()) - 1; - $i = -1; - while($i++ < $highestColumnIndex) { - if (!$this->_isPdf) { - if (!$this->_useInlineCss) { - $html .= ' <col class="col' . $i . '">' . PHP_EOL; - } else { - $style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) ? - $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) : ''; - $html .= ' <col style="' . $style . '">' . PHP_EOL; - } - } - } - - // Return - return $html; - } - - /** - * Generate table footer - * - * @throws PHPExcel_Writer_Exception - */ - private function _generateTableFooter() { - // Construct HTML - $html = ''; - $html .= ' </table>' . PHP_EOL; - - // Return - return $html; - } - - /** - * Generate row - * - * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet - * @param array $pValues Array containing cells in a row - * @param int $pRow Row number (0-based) - * @return string - * @throws PHPExcel_Writer_Exception - */ - private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td') { - if (is_array($pValues)) { - // Construct HTML - $html = ''; - - // Sheet index - $sheetIndex = $pSheet->getParent()->getIndex($pSheet); - - // DomPDF and breaks - if ($this->_isPdf && count($pSheet->getBreaks()) > 0) { - $breaks = $pSheet->getBreaks(); - - // check if a break is needed before this row - if (isset($breaks['A' . $pRow])) { - // close table: </table> - $html .= $this->_generateTableFooter(); - - // insert page break - $html .= '<div style="page-break-before:always" />'; - - // open table again: <table> + <col> etc. - $html .= $this->_generateTableHeader($pSheet); - } - } - - // Write row start - if (!$this->_useInlineCss) { - $html .= ' <tr class="row' . $pRow . '">' . PHP_EOL; - } else { - $style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) - ? $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : ''; - - $html .= ' <tr style="' . $style . '">' . PHP_EOL; - } - - // Write cells - $colNum = 0; - foreach ($pValues as $cellAddress) { + $html .= '</div>'; + } + } + } + + // Return + return $html; + } + + /** + * Generate chart tag in cell + * + * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet + * @param string $coordinates Cell coordinates + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) { + // Construct HTML + $html = ''; + + // Write charts + foreach ($pSheet->getChartCollection() as $chart) { + if ($chart instanceof PHPExcel_Chart) { + $chartCoordinates = $chart->getTopLeftPosition(); + if ($chartCoordinates['cell'] == $coordinates) { + $chartFileName = PHPExcel_Shared_File::sys_get_temp_dir().'/'.uniqid().'.png'; + if (!$chart->render($chartFileName)) { + return; + } + + $html .= PHP_EOL; + $imageDetails = getimagesize($chartFileName); + if ($fp = fopen($chartFileName,"rb", 0)) { + $picture = fread($fp,filesize($chartFileName)); + fclose($fp); + // base64 encode the binary data, then break it + // into chunks according to RFC 2045 semantics + $base64 = chunk_split(base64_encode($picture)); + $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64; + + $html .= '<div style="position: relative;">'; + $html .= '<img style="position: absolute; z-index: 1; left: ' . $chartCoordinates['xOffset'] . 'px; top: ' . $chartCoordinates['yOffset'] . 'px; width: ' . $imageDetails[0] . 'px; height: ' . $imageDetails[1] . 'px;" src="' . $imageData . '" border="0" />' . PHP_EOL; + $html .= '</div>'; + + unlink($chartFileName); + } + } + } + } + + // Return + return $html; + } + + /** + * Generate CSS styles + * + * @param boolean $generateSurroundingHTML Generate surrounding HTML tags? (&lt;style&gt; and &lt;/style&gt;) + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateStyles($generateSurroundingHTML = true) { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Build CSS + $css = $this->buildCSS($generateSurroundingHTML); + + // Construct HTML + $html = ''; + + // Start styles + if ($generateSurroundingHTML) { + $html .= ' <style type="text/css">' . PHP_EOL; + $html .= ' html { ' . $this->_assembleCSS($css['html']) . ' }' . PHP_EOL; + } + + // Write all other styles + foreach ($css as $styleName => $styleDefinition) { + if ($styleName != 'html') { + $html .= ' ' . $styleName . ' { ' . $this->_assembleCSS($styleDefinition) . ' }' . PHP_EOL; + } + } + + // End styles + if ($generateSurroundingHTML) { + $html .= ' </style>' . PHP_EOL; + } + + // Return + return $html; + } + + /** + * Build CSS styles + * + * @param boolean $generateSurroundingHTML Generate surrounding HTML style? (html { }) + * @return array + * @throws PHPExcel_Writer_Exception + */ + public function buildCSS($generateSurroundingHTML = true) { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Cached? + if (!is_null($this->_cssStyles)) { + return $this->_cssStyles; + } + + // Ensure that spans have been calculated + if (!$this->_spansAreCalculated) { + $this->_calculateSpans(); + } + + // Construct CSS + $css = array(); + + // Start styles + if ($generateSurroundingHTML) { + // html { } + $css['html']['font-family'] = 'Calibri, Arial, Helvetica, sans-serif'; + $css['html']['font-size'] = '11pt'; + $css['html']['background-color'] = 'white'; + } + + + // table { } + $css['table']['border-collapse'] = 'collapse'; + if (!$this->_isPdf) { + $css['table']['page-break-after'] = 'always'; + } + + // .gridlines td { } + $css['.gridlines td']['border'] = '1px dotted black'; + $css['.gridlines th']['border'] = '1px dotted black'; + + // .b {} + $css['.b']['text-align'] = 'center'; // BOOL + + // .e {} + $css['.e']['text-align'] = 'center'; // ERROR + + // .f {} + $css['.f']['text-align'] = 'right'; // FORMULA + + // .inlineStr {} + $css['.inlineStr']['text-align'] = 'left'; // INLINE + + // .n {} + $css['.n']['text-align'] = 'right'; // NUMERIC + + // .s {} + $css['.s']['text-align'] = 'left'; // STRING + + // Calculate cell style hashes + foreach ($this->_phpExcel->getCellXfCollection() as $index => $style) { + $css['td.style' . $index] = $this->_createCSSStyle( $style ); + $css['th.style' . $index] = $this->_createCSSStyle( $style ); + } + + // Fetch sheets + $sheets = array(); + if (is_null($this->_sheetIndex)) { + $sheets = $this->_phpExcel->getAllSheets(); + } else { + $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + } + + // Build styles per sheet + foreach ($sheets as $sheet) { + // Calculate hash code + $sheetIndex = $sheet->getParent()->getIndex($sheet); + + // Build styles + // Calculate column widths + $sheet->calculateColumnWidths(); + + // col elements, initialize + $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()) - 1; + $column = -1; + while($column++ < $highestColumnIndex) { + $this->_columnWidths[$sheetIndex][$column] = 42; // approximation + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = '42pt'; + } + + // col elements, loop through columnDimensions and set width + foreach ($sheet->getColumnDimensions() as $columnDimension) { + if (($width = PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth(), $this->_defaultFont)) >= 0) { + $width = PHPExcel_Shared_Drawing::pixelsToPoints($width); + $column = PHPExcel_Cell::columnIndexFromString($columnDimension->getColumnIndex()) - 1; + $this->_columnWidths[$sheetIndex][$column] = $width; + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = $width . 'pt'; + + if ($columnDimension->getVisible() === false) { + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['visibility'] = 'collapse'; + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['*display'] = 'none'; // target IE6+7 + } + } + } + + // Default row height + $rowDimension = $sheet->getDefaultRowDimension(); + + // table.sheetN tr { } + $css['table.sheet' . $sheetIndex . ' tr'] = array(); + + if ($rowDimension->getRowHeight() == -1) { + $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont()); + } else { + $pt_height = $rowDimension->getRowHeight(); + } + $css['table.sheet' . $sheetIndex . ' tr']['height'] = $pt_height . 'pt'; + if ($rowDimension->getVisible() === false) { + $css['table.sheet' . $sheetIndex . ' tr']['display'] = 'none'; + $css['table.sheet' . $sheetIndex . ' tr']['visibility'] = 'hidden'; + } + + // Calculate row heights + foreach ($sheet->getRowDimensions() as $rowDimension) { + $row = $rowDimension->getRowIndex() - 1; + + // table.sheetN tr.rowYYYYYY { } + $css['table.sheet' . $sheetIndex . ' tr.row' . $row] = array(); + + if ($rowDimension->getRowHeight() == -1) { + $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont()); + } else { + $pt_height = $rowDimension->getRowHeight(); + } + $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['height'] = $pt_height . 'pt'; + if ($rowDimension->getVisible() === false) { + $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['display'] = 'none'; + $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['visibility'] = 'hidden'; + } + } + } + + // Cache + if (is_null($this->_cssStyles)) { + $this->_cssStyles = $css; + } + + // Return + return $css; + } + + /** + * Create CSS style + * + * @param PHPExcel_Style $pStyle PHPExcel_Style + * @return array + */ + private function _createCSSStyle(PHPExcel_Style $pStyle) { + // Construct CSS + $css = ''; + + // Create CSS + $css = array_merge( + $this->_createCSSStyleAlignment($pStyle->getAlignment()) + , $this->_createCSSStyleBorders($pStyle->getBorders()) + , $this->_createCSSStyleFont($pStyle->getFont()) + , $this->_createCSSStyleFill($pStyle->getFill()) + ); + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Alignment) + * + * @param PHPExcel_Style_Alignment $pStyle PHPExcel_Style_Alignment + * @return array + */ + private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) { + // Construct CSS + $css = array(); + + // Create CSS + $css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical()); + if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) { + $css['text-align'] = $textAlign; + if(in_array($textAlign,array('left','right'))) + $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px'; + } + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Font) + * + * @param PHPExcel_Style_Font $pStyle PHPExcel_Style_Font + * @return array + */ + private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) { + // Construct CSS + $css = array(); + + // Create CSS + if ($pStyle->getBold()) { + $css['font-weight'] = 'bold'; + } + if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) { + $css['text-decoration'] = 'underline line-through'; + } else if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE) { + $css['text-decoration'] = 'underline'; + } else if ($pStyle->getStrikethrough()) { + $css['text-decoration'] = 'line-through'; + } + if ($pStyle->getItalic()) { + $css['font-style'] = 'italic'; + } + + $css['color'] = '#' . $pStyle->getColor()->getRGB(); + $css['font-family'] = '\'' . $pStyle->getName() . '\''; + $css['font-size'] = $pStyle->getSize() . 'pt'; + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Borders) + * + * @param PHPExcel_Style_Borders $pStyle PHPExcel_Style_Borders + * @return array + */ + private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) { + // Construct CSS + $css = array(); + + // Create CSS + $css['border-bottom'] = $this->_createCSSStyleBorder($pStyle->getBottom()); + $css['border-top'] = $this->_createCSSStyleBorder($pStyle->getTop()); + $css['border-left'] = $this->_createCSSStyleBorder($pStyle->getLeft()); + $css['border-right'] = $this->_createCSSStyleBorder($pStyle->getRight()); + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Border) + * + * @param PHPExcel_Style_Border $pStyle PHPExcel_Style_Border + * @return string + */ + private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) { + // Create CSS +// $css = $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); + // Create CSS - add !important to non-none border styles for merged cells + $borderStyle = $this->_mapBorderStyle($pStyle->getBorderStyle()); + $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Fill) + * + * @param PHPExcel_Style_Fill $pStyle PHPExcel_Style_Fill + * @return array + */ + private function _createCSSStyleFill(PHPExcel_Style_Fill $pStyle) { + // Construct HTML + $css = array(); + + // Create CSS + $value = $pStyle->getFillType() == PHPExcel_Style_Fill::FILL_NONE ? + 'white' : '#' . $pStyle->getStartColor()->getRGB(); + $css['background-color'] = $value; + + // Return + return $css; + } + + /** + * Generate HTML footer + */ + public function generateHTMLFooter() { + // Construct HTML + $html = ''; + $html .= ' </body>' . PHP_EOL; + $html .= '</html>' . PHP_EOL; + + // Return + return $html; + } + + /** + * Generate table header + * + * @param PHPExcel_Worksheet $pSheet The worksheet for the table we are writing + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _generateTableHeader($pSheet) { + $sheetIndex = $pSheet->getParent()->getIndex($pSheet); + + // Construct HTML + $html = ''; + $html .= $this->_setMargins($pSheet); + + if (!$this->_useInlineCss) { + $gridlines = $pSheet->getShowGridlines() ? ' gridlines' : ''; + $html .= ' <table border="0" cellpadding="0" cellspacing="0" id="sheet' . $sheetIndex . '" class="sheet' . $sheetIndex . $gridlines . '">' . PHP_EOL; + } else { + $style = isset($this->_cssStyles['table']) ? + $this->_assembleCSS($this->_cssStyles['table']) : ''; + + if ($this->_isPdf && $pSheet->getShowGridlines()) { + $html .= ' <table border="1" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="1" style="' . $style . '">' . PHP_EOL; + } else { + $html .= ' <table border="0" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="0" style="' . $style . '">' . PHP_EOL; + } + } + + // Write <col> elements + $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()) - 1; + $i = -1; + while($i++ < $highestColumnIndex) { + if (!$this->_isPdf) { + if (!$this->_useInlineCss) { + $html .= ' <col class="col' . $i . '">' . PHP_EOL; + } else { + $style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) ? + $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) : ''; + $html .= ' <col style="' . $style . '">' . PHP_EOL; + } + } + } + + // Return + return $html; + } + + /** + * Generate table footer + * + * @throws PHPExcel_Writer_Exception + */ + private function _generateTableFooter() { + // Construct HTML + $html = ''; + $html .= ' </table>' . PHP_EOL; + + // Return + return $html; + } + + /** + * Generate row + * + * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet + * @param array $pValues Array containing cells in a row + * @param int $pRow Row number (0-based) + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td') { + if (is_array($pValues)) { + // Construct HTML + $html = ''; + + // Sheet index + $sheetIndex = $pSheet->getParent()->getIndex($pSheet); + + // DomPDF and breaks + if ($this->_isPdf && count($pSheet->getBreaks()) > 0) { + $breaks = $pSheet->getBreaks(); + + // check if a break is needed before this row + if (isset($breaks['A' . $pRow])) { + // close table: </table> + $html .= $this->_generateTableFooter(); + + // insert page break + $html .= '<div style="page-break-before:always" />'; + + // open table again: <table> + <col> etc. + $html .= $this->_generateTableHeader($pSheet); + } + } + + // Write row start + if (!$this->_useInlineCss) { + $html .= ' <tr class="row' . $pRow . '">' . PHP_EOL; + } else { + $style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) + ? $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : ''; + + $html .= ' <tr style="' . $style . '">' . PHP_EOL; + } + + // Write cells + $colNum = 0; + foreach ($pValues as $cellAddress) { $cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : ''; - $coordinate = PHPExcel_Cell::stringFromColumnIndex($colNum) . ($pRow + 1); - if (!$this->_useInlineCss) { - $cssClass = ''; - $cssClass = 'column' . $colNum; - } else { - $cssClass = array(); + $coordinate = PHPExcel_Cell::stringFromColumnIndex($colNum) . ($pRow + 1); + if (!$this->_useInlineCss) { + $cssClass = ''; + $cssClass = 'column' . $colNum; + } else { + $cssClass = array(); if ($cellType == 'th') { if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum])) { $this->_cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum]; @@ -1135,83 +1128,83 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow $this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum]; } } - } - $colSpan = 1; - $rowSpan = 1; - - // initialize - $cellData = '&nbsp;'; - - // PHPExcel_Cell - if ($cell instanceof PHPExcel_Cell) { - $cellData = ''; - if (is_null($cell->getParent())) { - $cell->attach($pSheet); - } - // Value - if ($cell->getValue() instanceof PHPExcel_RichText) { - // Loop through rich text elements - $elements = $cell->getValue()->getRichTextElements(); - foreach ($elements as $element) { - // Rich text start? - if ($element instanceof PHPExcel_RichText_Run) { - $cellData .= '<span style="' . $this->_assembleCSS($this->_createCSSStyleFont($element->getFont())) . '">'; - - if ($element->getFont()->getSuperScript()) { - $cellData .= '<sup>'; - } else if ($element->getFont()->getSubScript()) { - $cellData .= '<sub>'; - } - } - - // Convert UTF8 data to PCDATA - $cellText = $element->getText(); - $cellData .= htmlspecialchars($cellText); - - if ($element instanceof PHPExcel_RichText_Run) { - if ($element->getFont()->getSuperScript()) { - $cellData .= '</sup>'; - } else if ($element->getFont()->getSubScript()) { - $cellData .= '</sub>'; - } - - $cellData .= '</span>'; - } - } - } else { - if ($this->_preCalculateFormulas) { - $cellData = PHPExcel_Style_NumberFormat::toFormattedString( - $cell->getCalculatedValue(), - $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), - array($this, 'formatColor') - ); - } else { - $cellData = PHPExcel_Style_NumberFormat::toFormattedString( - $cell->getValue(), - $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), - array($this, 'formatColor') - ); - } - $cellData = htmlspecialchars($cellData); - if ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSuperScript()) { - $cellData = '<sup>'.$cellData.'</sup>'; - } elseif ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSubScript()) { - $cellData = '<sub>'.$cellData.'</sub>'; - } - } - - // Converts the cell content so that spaces occuring at beginning of each new line are replaced by &nbsp; - // Example: " Hello\n to the world" is converted to "&nbsp;&nbsp;Hello\n&nbsp;to the world" - $cellData = preg_replace("/(?m)(?:^|\\G) /", '&nbsp;', $cellData); - - // convert newline "\n" to '<br>' - $cellData = nl2br($cellData); - - // Extend CSS class? - if (!$this->_useInlineCss) { - $cssClass .= ' style' . $cell->getXfIndex(); - $cssClass .= ' ' . $cell->getDataType(); - } else { + } + $colSpan = 1; + $rowSpan = 1; + + // initialize + $cellData = '&nbsp;'; + + // PHPExcel_Cell + if ($cell instanceof PHPExcel_Cell) { + $cellData = ''; + if (is_null($cell->getParent())) { + $cell->attach($pSheet); + } + // Value + if ($cell->getValue() instanceof PHPExcel_RichText) { + // Loop through rich text elements + $elements = $cell->getValue()->getRichTextElements(); + foreach ($elements as $element) { + // Rich text start? + if ($element instanceof PHPExcel_RichText_Run) { + $cellData .= '<span style="' . $this->_assembleCSS($this->_createCSSStyleFont($element->getFont())) . '">'; + + if ($element->getFont()->getSuperScript()) { + $cellData .= '<sup>'; + } else if ($element->getFont()->getSubScript()) { + $cellData .= '<sub>'; + } + } + + // Convert UTF8 data to PCDATA + $cellText = $element->getText(); + $cellData .= htmlspecialchars($cellText); + + if ($element instanceof PHPExcel_RichText_Run) { + if ($element->getFont()->getSuperScript()) { + $cellData .= '</sup>'; + } else if ($element->getFont()->getSubScript()) { + $cellData .= '</sub>'; + } + + $cellData .= '</span>'; + } + } + } else { + if ($this->_preCalculateFormulas) { + $cellData = PHPExcel_Style_NumberFormat::toFormattedString( + $cell->getCalculatedValue(), + $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), + array($this, 'formatColor') + ); + } else { + $cellData = PHPExcel_Style_NumberFormat::toFormattedString( + $cell->getValue(), + $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), + array($this, 'formatColor') + ); + } + $cellData = htmlspecialchars($cellData); + if ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSuperScript()) { + $cellData = '<sup>'.$cellData.'</sup>'; + } elseif ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSubScript()) { + $cellData = '<sub>'.$cellData.'</sub>'; + } + } + + // Converts the cell content so that spaces occuring at beginning of each new line are replaced by &nbsp; + // Example: " Hello\n to the world" is converted to "&nbsp;&nbsp;Hello\n&nbsp;to the world" + $cellData = preg_replace("/(?m)(?:^|\\G) /", '&nbsp;', $cellData); + + // convert newline "\n" to '<br>' + $cellData = nl2br($cellData); + + // Extend CSS class? + if (!$this->_useInlineCss) { + $cssClass .= ' style' . $cell->getXfIndex(); + $cssClass .= ' ' . $cell->getDataType(); + } else { if ($cellType == 'th') { if (isset($this->_cssStyles['th.style' . $cell->getXfIndex()])) { $cssClass = array_merge($cssClass, $this->_cssStyles['th.style' . $cell->getXfIndex()]); @@ -1222,327 +1215,327 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow } } - // General horizontal alignment: Actual horizontal alignment depends on dataType - $sharedStyle = $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() ); - if ($sharedStyle->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL - && isset($this->_cssStyles['.' . $cell->getDataType()]['text-align'])) - { - $cssClass['text-align'] = $this->_cssStyles['.' . $cell->getDataType()]['text-align']; - } - } - } - - // Hyperlink? - if ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) { - $cellData = '<a href="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getUrl()) . '" title="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getTooltip()) . '">' . $cellData . '</a>'; - } - - // Should the cell be written or is it swallowed by a rowspan or colspan? - $writeCell = ! ( isset($this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]) - && $this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum] ); - - // Colspan and Rowspan - $colspan = 1; - $rowspan = 1; - if (isset($this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) { - $spans = $this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]; - $rowSpan = $spans['rowspan']; - $colSpan = $spans['colspan']; - - // Also apply style from last cell in merge to fix borders - - // relies on !important for non-none border declarations in _createCSSStyleBorder - $endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan); - if (!$this->_useInlineCss) { - $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex(); - } - } - - // Write - if ($writeCell) { - // Column start - $html .= ' <' . $cellType; - if (!$this->_useInlineCss) { - $html .= ' class="' . $cssClass . '"'; - } else { - //** Necessary redundant code for the sake of PHPExcel_Writer_PDF ** - // We must explicitly write the width of the <td> element because TCPDF - // does not recognize e.g. <col style="width:42pt"> - $width = 0; - $i = $colNum - 1; - $e = $colNum + $colSpan - 1; - while($i++ < $e) { - if (isset($this->_columnWidths[$sheetIndex][$i])) { - $width += $this->_columnWidths[$sheetIndex][$i]; - } - } - $cssClass['width'] = $width . 'pt'; - - // We must also explicitly write the height of the <td> element because TCPDF - // does not recognize e.g. <tr style="height:50pt"> - if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) { - $height = $this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height']; - $cssClass['height'] = $height; - } - //** end of redundant code ** - - $html .= ' style="' . $this->_assembleCSS($cssClass) . '"'; - } - if ($colSpan > 1) { - $html .= ' colspan="' . $colSpan . '"'; - } - if ($rowSpan > 1) { - $html .= ' rowspan="' . $rowSpan . '"'; - } - $html .= '>'; - - // Image? - $html .= $this->_writeImageInCell($pSheet, $coordinate); - - // Chart? - if ($this->_includeCharts) { - $html .= $this->_writeChartInCell($pSheet, $coordinate); - } - - // Cell data - $html .= $cellData; - - // Column end - $html .= '</'.$cellType.'>' . PHP_EOL; - } - - // Next column - ++$colNum; - } - - // Write row end - $html .= ' </tr>' . PHP_EOL; - - // Return - return $html; - } else { - throw new PHPExcel_Writer_Exception("Invalid parameters passed."); - } - } - - /** - * Takes array where of CSS properties / values and converts to CSS string - * - * @param array - * @return string - */ - private function _assembleCSS($pValue = array()) - { - $pairs = array(); - foreach ($pValue as $property => $value) { - $pairs[] = $property . ':' . $value; - } - $string = implode('; ', $pairs); - - return $string; - } - - /** - * Get images root - * - * @return string - */ - public function getImagesRoot() { - return $this->_imagesRoot; - } - - /** - * Set images root - * - * @param string $pValue - * @return PHPExcel_Writer_HTML - */ - public function setImagesRoot($pValue = '.') { - $this->_imagesRoot = $pValue; - return $this; - } - - /** - * Get embed images - * - * @return boolean - */ - public function getEmbedImages() { - return $this->_embedImages; - } - - /** - * Set embed images - * - * @param boolean $pValue - * @return PHPExcel_Writer_HTML - */ - public function setEmbedImages($pValue = '.') { - $this->_embedImages = $pValue; - return $this; - } - - /** - * Get use inline CSS? - * - * @return boolean - */ - public function getUseInlineCss() { - return $this->_useInlineCss; - } - - /** - * Set use inline CSS? - * - * @param boolean $pValue - * @return PHPExcel_Writer_HTML - */ - public function setUseInlineCss($pValue = false) { - $this->_useInlineCss = $pValue; - return $this; - } - - /** - * Add color to formatted string as inline style - * - * @param string $pValue Plain formatted value without color - * @param string $pFormat Format code - * @return string - */ - public function formatColor($pValue, $pFormat) - { - // Color information, e.g. [Red] is always at the beginning - $color = null; // initialize - $matches = array(); - - $color_regex = '/^\\[[a-zA-Z]+\\]/'; - if (preg_match($color_regex, $pFormat, $matches)) { - $color = str_replace('[', '', $matches[0]); - $color = str_replace(']', '', $color); - $color = strtolower($color); - } - - // convert to PCDATA - $value = htmlspecialchars($pValue); - - // color span tag - if ($color !== null) { - $value = '<span style="color:' . $color . '">' . $value . '</span>'; - } - - return $value; - } - - /** - * Calculate information about HTML colspan and rowspan which is not always the same as Excel's - */ - private function _calculateSpans() - { - // Identify all cells that should be omitted in HTML due to cell merge. - // In HTML only the upper-left cell should be written and it should have - // appropriate rowspan / colspan attribute - $sheetIndexes = $this->_sheetIndex !== null ? - array($this->_sheetIndex) : range(0, $this->_phpExcel->getSheetCount() - 1); - - foreach ($sheetIndexes as $sheetIndex) { - $sheet = $this->_phpExcel->getSheet($sheetIndex); - - $candidateSpannedRow = array(); - - // loop through all Excel merged cells - foreach ($sheet->getMergeCells() as $cells) { - list($cells, ) = PHPExcel_Cell::splitRange($cells); - $first = $cells[0]; - $last = $cells[1]; - - list($fc, $fr) = PHPExcel_Cell::coordinateFromString($first); - $fc = PHPExcel_Cell::columnIndexFromString($fc) - 1; - - list($lc, $lr) = PHPExcel_Cell::coordinateFromString($last); - $lc = PHPExcel_Cell::columnIndexFromString($lc) - 1; - - // loop through the individual cells in the individual merge - $r = $fr - 1; - while($r++ < $lr) { - // also, flag this row as a HTML row that is candidate to be omitted - $candidateSpannedRow[$r] = $r; - - $c = $fc - 1; - while($c++ < $lc) { - if ( !($c == $fc && $r == $fr) ) { - // not the upper-left cell (should not be written in HTML) - $this->_isSpannedCell[$sheetIndex][$r][$c] = array( - 'baseCell' => array($fr, $fc), - ); - } else { - // upper-left is the base cell that should hold the colspan/rowspan attribute - $this->_isBaseCell[$sheetIndex][$r][$c] = array( - 'xlrowspan' => $lr - $fr + 1, // Excel rowspan - 'rowspan' => $lr - $fr + 1, // HTML rowspan, value may change - 'xlcolspan' => $lc - $fc + 1, // Excel colspan - 'colspan' => $lc - $fc + 1, // HTML colspan, value may change - ); - } - } - } - } - - // Identify which rows should be omitted in HTML. These are the rows where all the cells - // participate in a merge and the where base cells are somewhere above. - $countColumns = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()); - foreach ($candidateSpannedRow as $rowIndex) { - if (isset($this->_isSpannedCell[$sheetIndex][$rowIndex])) { - if (count($this->_isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) { - $this->_isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex; - }; - } - } - - // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1 - if ( isset($this->_isSpannedRow[$sheetIndex]) ) { - foreach ($this->_isSpannedRow[$sheetIndex] as $rowIndex) { - $adjustedBaseCells = array(); - $c = -1; - $e = $countColumns - 1; - while($c++ < $e) { - $baseCell = $this->_isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell']; - - if ( !in_array($baseCell, $adjustedBaseCells) ) { - // subtract rowspan by 1 - --$this->_isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan']; - $adjustedBaseCells[] = $baseCell; - } - } - } - } - - // TODO: Same for columns - } - - // We have calculated the spans - $this->_spansAreCalculated = true; - } - - private function _setMargins(PHPExcel_Worksheet $pSheet) { - $htmlPage = '@page { '; - $htmlBody = 'body { '; - - $left = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()) . 'in; '; - $htmlPage .= 'left-margin: ' . $left; - $htmlBody .= 'left-margin: ' . $left; - $right = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()) . 'in; '; - $htmlPage .= 'right-margin: ' . $right; - $htmlBody .= 'right-margin: ' . $right; - $top = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()) . 'in; '; - $htmlPage .= 'top-margin: ' . $top; - $htmlBody .= 'top-margin: ' . $top; - $bottom = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()) . 'in; '; - $htmlPage .= 'bottom-margin: ' . $bottom; - $htmlBody .= 'bottom-margin: ' . $bottom; - - $htmlPage .= "}\n"; - $htmlBody .= "}\n"; - - return "<style>\n" . $htmlPage . $htmlBody . "</style>\n"; - } - + // General horizontal alignment: Actual horizontal alignment depends on dataType + $sharedStyle = $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() ); + if ($sharedStyle->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL + && isset($this->_cssStyles['.' . $cell->getDataType()]['text-align'])) + { + $cssClass['text-align'] = $this->_cssStyles['.' . $cell->getDataType()]['text-align']; + } + } + } + + // Hyperlink? + if ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) { + $cellData = '<a href="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getUrl()) . '" title="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getTooltip()) . '">' . $cellData . '</a>'; + } + + // Should the cell be written or is it swallowed by a rowspan or colspan? + $writeCell = ! ( isset($this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]) + && $this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum] ); + + // Colspan and Rowspan + $colspan = 1; + $rowspan = 1; + if (isset($this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) { + $spans = $this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]; + $rowSpan = $spans['rowspan']; + $colSpan = $spans['colspan']; + + // Also apply style from last cell in merge to fix borders - + // relies on !important for non-none border declarations in _createCSSStyleBorder + $endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan); + if (!$this->_useInlineCss) { + $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex(); + } + } + + // Write + if ($writeCell) { + // Column start + $html .= ' <' . $cellType; + if (!$this->_useInlineCss) { + $html .= ' class="' . $cssClass . '"'; + } else { + //** Necessary redundant code for the sake of PHPExcel_Writer_PDF ** + // We must explicitly write the width of the <td> element because TCPDF + // does not recognize e.g. <col style="width:42pt"> + $width = 0; + $i = $colNum - 1; + $e = $colNum + $colSpan - 1; + while($i++ < $e) { + if (isset($this->_columnWidths[$sheetIndex][$i])) { + $width += $this->_columnWidths[$sheetIndex][$i]; + } + } + $cssClass['width'] = $width . 'pt'; + + // We must also explicitly write the height of the <td> element because TCPDF + // does not recognize e.g. <tr style="height:50pt"> + if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) { + $height = $this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height']; + $cssClass['height'] = $height; + } + //** end of redundant code ** + + $html .= ' style="' . $this->_assembleCSS($cssClass) . '"'; + } + if ($colSpan > 1) { + $html .= ' colspan="' . $colSpan . '"'; + } + if ($rowSpan > 1) { + $html .= ' rowspan="' . $rowSpan . '"'; + } + $html .= '>'; + + // Image? + $html .= $this->_writeImageInCell($pSheet, $coordinate); + + // Chart? + if ($this->_includeCharts) { + $html .= $this->_writeChartInCell($pSheet, $coordinate); + } + + // Cell data + $html .= $cellData; + + // Column end + $html .= '</'.$cellType.'>' . PHP_EOL; + } + + // Next column + ++$colNum; + } + + // Write row end + $html .= ' </tr>' . PHP_EOL; + + // Return + return $html; + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Takes array where of CSS properties / values and converts to CSS string + * + * @param array + * @return string + */ + private function _assembleCSS($pValue = array()) + { + $pairs = array(); + foreach ($pValue as $property => $value) { + $pairs[] = $property . ':' . $value; + } + $string = implode('; ', $pairs); + + return $string; + } + + /** + * Get images root + * + * @return string + */ + public function getImagesRoot() { + return $this->_imagesRoot; + } + + /** + * Set images root + * + * @param string $pValue + * @return PHPExcel_Writer_HTML + */ + public function setImagesRoot($pValue = '.') { + $this->_imagesRoot = $pValue; + return $this; + } + + /** + * Get embed images + * + * @return boolean + */ + public function getEmbedImages() { + return $this->_embedImages; + } + + /** + * Set embed images + * + * @param boolean $pValue + * @return PHPExcel_Writer_HTML + */ + public function setEmbedImages($pValue = '.') { + $this->_embedImages = $pValue; + return $this; + } + + /** + * Get use inline CSS? + * + * @return boolean + */ + public function getUseInlineCss() { + return $this->_useInlineCss; + } + + /** + * Set use inline CSS? + * + * @param boolean $pValue + * @return PHPExcel_Writer_HTML + */ + public function setUseInlineCss($pValue = false) { + $this->_useInlineCss = $pValue; + return $this; + } + + /** + * Add color to formatted string as inline style + * + * @param string $pValue Plain formatted value without color + * @param string $pFormat Format code + * @return string + */ + public function formatColor($pValue, $pFormat) + { + // Color information, e.g. [Red] is always at the beginning + $color = null; // initialize + $matches = array(); + + $color_regex = '/^\\[[a-zA-Z]+\\]/'; + if (preg_match($color_regex, $pFormat, $matches)) { + $color = str_replace('[', '', $matches[0]); + $color = str_replace(']', '', $color); + $color = strtolower($color); + } + + // convert to PCDATA + $value = htmlspecialchars($pValue); + + // color span tag + if ($color !== null) { + $value = '<span style="color:' . $color . '">' . $value . '</span>'; + } + + return $value; + } + + /** + * Calculate information about HTML colspan and rowspan which is not always the same as Excel's + */ + private function _calculateSpans() + { + // Identify all cells that should be omitted in HTML due to cell merge. + // In HTML only the upper-left cell should be written and it should have + // appropriate rowspan / colspan attribute + $sheetIndexes = $this->_sheetIndex !== null ? + array($this->_sheetIndex) : range(0, $this->_phpExcel->getSheetCount() - 1); + + foreach ($sheetIndexes as $sheetIndex) { + $sheet = $this->_phpExcel->getSheet($sheetIndex); + + $candidateSpannedRow = array(); + + // loop through all Excel merged cells + foreach ($sheet->getMergeCells() as $cells) { + list($cells, ) = PHPExcel_Cell::splitRange($cells); + $first = $cells[0]; + $last = $cells[1]; + + list($fc, $fr) = PHPExcel_Cell::coordinateFromString($first); + $fc = PHPExcel_Cell::columnIndexFromString($fc) - 1; + + list($lc, $lr) = PHPExcel_Cell::coordinateFromString($last); + $lc = PHPExcel_Cell::columnIndexFromString($lc) - 1; + + // loop through the individual cells in the individual merge + $r = $fr - 1; + while($r++ < $lr) { + // also, flag this row as a HTML row that is candidate to be omitted + $candidateSpannedRow[$r] = $r; + + $c = $fc - 1; + while($c++ < $lc) { + if ( !($c == $fc && $r == $fr) ) { + // not the upper-left cell (should not be written in HTML) + $this->_isSpannedCell[$sheetIndex][$r][$c] = array( + 'baseCell' => array($fr, $fc), + ); + } else { + // upper-left is the base cell that should hold the colspan/rowspan attribute + $this->_isBaseCell[$sheetIndex][$r][$c] = array( + 'xlrowspan' => $lr - $fr + 1, // Excel rowspan + 'rowspan' => $lr - $fr + 1, // HTML rowspan, value may change + 'xlcolspan' => $lc - $fc + 1, // Excel colspan + 'colspan' => $lc - $fc + 1, // HTML colspan, value may change + ); + } + } + } + } + + // Identify which rows should be omitted in HTML. These are the rows where all the cells + // participate in a merge and the where base cells are somewhere above. + $countColumns = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()); + foreach ($candidateSpannedRow as $rowIndex) { + if (isset($this->_isSpannedCell[$sheetIndex][$rowIndex])) { + if (count($this->_isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) { + $this->_isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex; + }; + } + } + + // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1 + if ( isset($this->_isSpannedRow[$sheetIndex]) ) { + foreach ($this->_isSpannedRow[$sheetIndex] as $rowIndex) { + $adjustedBaseCells = array(); + $c = -1; + $e = $countColumns - 1; + while($c++ < $e) { + $baseCell = $this->_isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell']; + + if ( !in_array($baseCell, $adjustedBaseCells) ) { + // subtract rowspan by 1 + --$this->_isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan']; + $adjustedBaseCells[] = $baseCell; + } + } + } + } + + // TODO: Same for columns + } + + // We have calculated the spans + $this->_spansAreCalculated = true; + } + + private function _setMargins(PHPExcel_Worksheet $pSheet) { + $htmlPage = '@page { '; + $htmlBody = 'body { '; + + $left = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()) . 'in; '; + $htmlPage .= 'left-margin: ' . $left; + $htmlBody .= 'left-margin: ' . $left; + $right = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()) . 'in; '; + $htmlPage .= 'right-margin: ' . $right; + $htmlBody .= 'right-margin: ' . $right; + $top = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()) . 'in; '; + $htmlPage .= 'top-margin: ' . $top; + $htmlBody .= 'top-margin: ' . $top; + $bottom = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()) . 'in; '; + $htmlPage .= 'bottom-margin: ' . $bottom; + $htmlBody .= 'bottom-margin: ' . $bottom; + + $htmlPage .= "}\n"; + $htmlBody .= "}\n"; + + return "<style>\n" . $htmlPage . $htmlBody . "</style>\n"; + } + } diff --git a/Classes/PHPExcel/Writer/IWriter.php b/Classes/PHPExcel/Writer/IWriter.php index 31624e502..fd993db64 100644 --- a/Classes/PHPExcel/Writer/IWriter.php +++ b/Classes/PHPExcel/Writer/IWriter.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_IWriter * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_IWriter - * - * @category PHPExcel - * @package PHPExcel_Writer - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ interface PHPExcel_Writer_IWriter { /** @@ -41,6 +33,6 @@ interface PHPExcel_Writer_IWriter * @param string $pFilename Name of the file to save * @throws PHPExcel_Writer_Exception */ - public function save($pFilename = NULL); + public function save($pFilename = null); } diff --git a/Classes/PHPExcel/Writer/OpenDocument.php b/Classes/PHPExcel/Writer/OpenDocument.php index ef967e092..912ba9df7 100644 --- a/Classes/PHPExcel/Writer/OpenDocument.php +++ b/Classes/PHPExcel/Writer/OpenDocument.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_OpenDocument * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,20 +22,9 @@ * @category PHPExcel * @package PHPExcel_Writer_OpenDocument * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_OpenDocument - * - * @category PHPExcel - * @package PHPExcel_Writer_OpenDocument - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @author Alexander Pervakov <frost-nzcr4@jagmort.com> - * @link http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os.html - */ class PHPExcel_Writer_OpenDocument extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { /** @@ -42,14 +32,14 @@ class PHPExcel_Writer_OpenDocument extends PHPExcel_Writer_Abstract implements P * * @var PHPExcel_Writer_OpenDocument_WriterPart[] */ - private $_writerParts = array(); + private $writerParts = array(); /** * Private PHPExcel * * @var PHPExcel */ - private $_spreadSheet; + private $spreadSheet; /** * Create a new PHPExcel_Writer_OpenDocument @@ -71,7 +61,7 @@ public function __construct(PHPExcel $pPHPExcel = null) ); foreach ($writerPartsArray as $writer => $class) { - $this->_writerParts[$writer] = new $class($this); + $this->writerParts[$writer] = new $class($this); } } @@ -83,8 +73,8 @@ public function __construct(PHPExcel $pPHPExcel = null) */ public function getWriterPart($pPartName = '') { - if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) { - return $this->_writerParts[strtolower($pPartName)]; + if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) { + return $this->writerParts[strtolower($pPartName)]; } else { return null; } @@ -96,14 +86,14 @@ public function getWriterPart($pPartName = '') * @param string $pFilename * @throws PHPExcel_Writer_Exception */ - public function save($pFilename = NULL) + public function save($pFilename = null) { - if (!$this->_spreadSheet) { + if (!$this->spreadSheet) { throw new PHPExcel_Writer_Exception('PHPExcel object unassigned.'); } // garbage collect - $this->_spreadSheet->garbageCollect(); + $this->spreadSheet->garbageCollect(); // If $pFilename is php://output or php://stdout, make it a temporary file... $originalFilename = $pFilename; @@ -114,15 +104,15 @@ public function save($pFilename = NULL) } } - $objZip = $this->_createZip($pFilename); + $objZip = $this->createZip($pFilename); $objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest()); $objZip->addFromString('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail()); - $objZip->addFromString('content.xml', $this->getWriterPart('content')->write()); - $objZip->addFromString('meta.xml', $this->getWriterPart('meta')->write()); - $objZip->addFromString('mimetype', $this->getWriterPart('mimetype')->write()); + $objZip->addFromString('content.xml', $this->getWriterPart('content')->write()); + $objZip->addFromString('meta.xml', $this->getWriterPart('meta')->write()); + $objZip->addFromString('mimetype', $this->getWriterPart('mimetype')->write()); $objZip->addFromString('settings.xml', $this->getWriterPart('settings')->write()); - $objZip->addFromString('styles.xml', $this->getWriterPart('styles')->write()); + $objZip->addFromString('styles.xml', $this->getWriterPart('styles')->write()); // Close file if ($objZip->close() === false) { @@ -145,7 +135,7 @@ public function save($pFilename = NULL) * @throws PHPExcel_Writer_Exception * @return ZipArchive */ - private function _createZip($pFilename) + private function createZip($pFilename) { // Create new ZIP file and open it for writing $zipClass = PHPExcel_Settings::getZipClass(); @@ -178,8 +168,8 @@ private function _createZip($pFilename) */ public function getPHPExcel() { - if ($this->_spreadSheet !== null) { - return $this->_spreadSheet; + if ($this->spreadSheet !== null) { + return $this->spreadSheet; } else { throw new PHPExcel_Writer_Exception('No PHPExcel assigned.'); } @@ -194,7 +184,7 @@ public function getPHPExcel() */ public function setPHPExcel(PHPExcel $pPHPExcel = null) { - $this->_spreadSheet = $pPHPExcel; + $this->spreadSheet = $pPHPExcel; return $this; } } diff --git a/Classes/PHPExcel/Writer/OpenDocument/Meta.php b/Classes/PHPExcel/Writer/OpenDocument/Meta.php index b1542105e..1a5c5fd0b 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Meta.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Meta.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_OpenDocument_Meta * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,19 +22,9 @@ * @category PHPExcel * @package PHPExcel_Writer_OpenDocument * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_OpenDocument_Meta - * - * @category PHPExcel - * @package PHPExcel_Writer_OpenDocument - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @author Alexander Pervakov <frost-nzcr4@jagmort.com> - */ class PHPExcel_Writer_OpenDocument_Meta extends PHPExcel_Writer_OpenDocument_WriterPart { /** @@ -61,36 +52,42 @@ public function write(PHPExcel $pPHPExcel = null) // Meta $objWriter->startElement('office:document-meta'); - $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); - $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); - $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); - $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'); - $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); - $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#'); - $objWriter->writeAttribute('office:version', '1.2'); - $objWriter->startElement('office:meta'); - $objWriter->writeElement('meta:initial-creator', $pPHPExcel->getProperties()->getCreator()); - $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); - $objWriter->writeElement('meta:creation-date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); - $objWriter->writeElement('dc:date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); - $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); - $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); - $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); - $keywords = explode(' ', $pPHPExcel->getProperties()->getKeywords()); - foreach ($keywords as $keyword) { - $objWriter->writeElement('meta:keyword', $keyword); - } - //<meta:document-statistic meta:table-count="XXX" meta:cell-count="XXX" meta:object-count="XXX"/> - $objWriter->startElement('meta:user-defined'); - $objWriter->writeAttribute('meta:name', 'Company'); - $objWriter->writeRaw($pPHPExcel->getProperties()->getCompany()); - $objWriter->endElement(); - $objWriter->startElement('meta:user-defined'); - $objWriter->writeAttribute('meta:name', 'category'); - $objWriter->writeRaw($pPHPExcel->getProperties()->getCategory()); - $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'); + $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); + $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); + $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0'); + $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office'); + $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#'); + $objWriter->writeAttribute('office:version', '1.2'); + + $objWriter->startElement('office:meta'); + + $objWriter->writeElement('meta:initial-creator', $pPHPExcel->getProperties()->getCreator()); + $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); + $objWriter->writeElement('meta:creation-date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); + $objWriter->writeElement('dc:date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); + $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); + $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); + $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); + $keywords = explode(' ', $pPHPExcel->getProperties()->getKeywords()); + foreach ($keywords as $keyword) { + $objWriter->writeElement('meta:keyword', $keyword); + } + + //<meta:document-statistic meta:table-count="XXX" meta:cell-count="XXX" meta:object-count="XXX"/> + $objWriter->startElement('meta:user-defined'); + $objWriter->writeAttribute('meta:name', 'Company'); + $objWriter->writeRaw($pPHPExcel->getProperties()->getCompany()); + $objWriter->endElement(); + + $objWriter->startElement('meta:user-defined'); + $objWriter->writeAttribute('meta:name', 'category'); + $objWriter->writeRaw($pPHPExcel->getProperties()->getCategory()); + $objWriter->endElement(); + + $objWriter->endElement(); + $objWriter->endElement(); return $objWriter->getData(); diff --git a/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php b/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php index f4c03cf95..c43b72334 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php +++ b/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_OpenDocument_MetaInf * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,19 +22,9 @@ * @category PHPExcel * @package PHPExcel_Writer_OpenDocument * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_OpenDocument_MetaInf - * - * @category PHPExcel - * @package PHPExcel_Writer_OpenDocument - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @author Alexander Pervakov <frost-nzcr4@jagmort.com> - */ class PHPExcel_Writer_OpenDocument_MetaInf extends PHPExcel_Writer_OpenDocument_WriterPart { /** diff --git a/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php b/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php index d93e4d149..d51a8b970 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php @@ -1,8 +1,9 @@ <?php + /** * PHPExcel * - * Copyright (c) 2006 - 2015 PHPExcel + * PHPExcel_Writer_OpenDocument_Mimetype * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,19 +22,9 @@ * @category PHPExcel * @package PHPExcel_Writer_OpenDocument * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_OpenDocument_Mimetype - * - * @category PHPExcel - * @package PHPExcel_Writer_OpenDocument - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @author Alexander Pervakov <frost-nzcr4@jagmort.com> - */ class PHPExcel_Writer_OpenDocument_Mimetype extends PHPExcel_Writer_OpenDocument_WriterPart { /** diff --git a/Classes/PHPExcel/Writer/OpenDocument/Settings.php b/Classes/PHPExcel/Writer/OpenDocument/Settings.php index 75363a8e8..84161b6d7 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Settings.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Settings.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_OpenDocument_Settings * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,19 +22,9 @@ * @category PHPExcel * @package PHPExcel_Writer_OpenDocument * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_OpenDocument_Settings - * - * @category PHPExcel - * @package PHPExcel_Writer_OpenDocument - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @author Alexander Pervakov <frost-nzcr4@jagmort.com> - */ class PHPExcel_Writer_OpenDocument_Settings extends PHPExcel_Writer_OpenDocument_WriterPart { /** diff --git a/Classes/PHPExcel/Writer/OpenDocument/Styles.php b/Classes/PHPExcel/Writer/OpenDocument/Styles.php index e2934d108..cc6e25b48 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Styles.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Styles.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_OpenDocument_Styles * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,19 +22,9 @@ * @category PHPExcel * @package PHPExcel_Writer_OpenDocument * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_OpenDocument_Styles - * - * @category PHPExcel - * @package PHPExcel_Writer_OpenDocument - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @author Alexander Pervakov <frost-nzcr4@jagmort.com> - */ class PHPExcel_Writer_OpenDocument_Styles extends PHPExcel_Writer_OpenDocument_WriterPart { /** diff --git a/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php b/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php index b48731f5e..54247ae2a 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_OpenDocument_Thumbnails * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,19 +22,9 @@ * @category PHPExcel * @package PHPExcel_Writer_OpenDocument * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_OpenDocument_Thumbnails - * - * @category PHPExcel - * @package PHPExcel_Writer_OpenDocument - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @author Alexander Pervakov <frost-nzcr4@jagmort.com> - */ class PHPExcel_Writer_OpenDocument_Thumbnails extends PHPExcel_Writer_OpenDocument_WriterPart { /** diff --git a/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php b/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php index 1b2e52c3d..562787a33 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php +++ b/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_OpenDocument_WriterPart * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,18 +22,9 @@ * @category PHPExcel * @package PHPExcel_Writer_OpenDocument * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_OpenDocument_WriterPart - * - * @category PHPExcel - * @package PHPExcel_Writer_OpenDocument - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ abstract class PHPExcel_Writer_OpenDocument_WriterPart extends PHPExcel_Writer_Excel2007_WriterPart { } From 986b20bbb1bb6f1d81d97f9d2c09cea09f36cca0 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Tue, 12 May 2015 08:02:56 +0200 Subject: [PATCH 350/467] Travis CI : Support for PSR-2 test --- .travis.yml | 23 ++++++++++++++++++----- composer.json | 5 ++++- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index c35625b13..9c5e11a95 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,19 +2,32 @@ language: php php: - 5.2 - - 5.3.3 - 5.3 + - 5.3.3 - 5.4 - 5.5 - 5.6 - hhvm matrix: - allow_failures: - - php: hhvm + allow_failures: + - php: hhvm + +before_script: + ## Packages + - sudo apt-get -qq update > /dev/null + ## Composer + ##@todo Remove when support of 5.2 will be dropped + - phpenv global 5.3 + - composer self-update + - composer install --prefer-source --dev + - phpenv global "$TRAVIS_PHP_VERSION" script: - - phpunit -c ./unitTests/ + ## PHP_CodeSniffer + - ./vendor/bin/phpcs Classes/ unitTests/ --standard=PSR2 -n --ignore=Classes/PHPExcel/Shared/PCLZip + ## PHPUnit + - phpunit -c ./unitTests/ notifications: - email: false + email: false \ No newline at end of file diff --git a/composer.json b/composer.json index ff18cb842..da7faa0eb 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ }, { "name": "Franck Lefevre", - "homepage": "http://blog.rootslabs.net/" + "homepage": "http://rootslabs.net/" }, { "name": "Erik Tilt" @@ -26,6 +26,9 @@ "ext-xml": "*", "ext-xmlwriter": "*" }, + "require-dev": { + "squizlabs/php_codesniffer": "1.*" + }, "recommend": { "ext-zip": "*", "ext-gd2": "*" From 0d855d0627e010d0b46bbe6d9d3730f6dc661517 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Tue, 12 May 2015 08:00:59 +0100 Subject: [PATCH 351/467] More PSR-2 changes --- Classes/PHPExcel/Cell.php | 172 +- Classes/PHPExcel/Cell/AdvancedValueBinder.php | 22 +- Classes/PHPExcel/Cell/DataType.php | 1 - Classes/PHPExcel/Cell/DataValidation.php | 213 ++- Classes/PHPExcel/Cell/DefaultValueBinder.php | 4 +- Classes/PHPExcel/Chart/Axis.php | 117 +- Classes/PHPExcel/Chart/DataSeries.php | 657 ++++--- Classes/PHPExcel/Chart/DataSeriesValues.php | 594 +++---- Classes/PHPExcel/Chart/Exception.php | 50 +- Classes/PHPExcel/Chart/Layout.php | 772 ++++---- Classes/PHPExcel/Chart/Legend.php | 287 ++- Classes/PHPExcel/Chart/PlotArea.php | 176 +- Classes/PHPExcel/Chart/Renderer/jpgraph.php | 1582 ++++++++--------- Classes/PHPExcel/Chart/Title.php | 104 +- Classes/PHPExcel/Writer/HTML.php | 307 ++-- 15 files changed, 2567 insertions(+), 2491 deletions(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 4e1c863c7..4ca7e5321 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -40,7 +40,7 @@ class PHPExcel_Cell * * @var PHPExcel_Cell_IValueBinder */ - private static $_valueBinder = NULL; + private static $_valueBinder; /** * Value of the cell @@ -59,7 +59,7 @@ class PHPExcel_Cell * * @var mixed */ - private $_calculatedValue = NULL; + private $_calculatedValue; /** * Type of the cell data @@ -94,17 +94,20 @@ class PHPExcel_Cell * * @return void **/ - public function notifyCacheController() { + public function notifyCacheController() + { $this->_parent->updateCacheData($this); return $this; } - public function detach() { - $this->_parent = NULL; + public function detach() + { + $this->_parent = null; } - public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) { + public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) + { $this->_parent = $parent; } @@ -117,7 +120,7 @@ public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) { * @param PHPExcel_Worksheet $pSheet * @throws PHPExcel_Exception */ - public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL) + public function __construct($pValue = null, $pDataType = null, PHPExcel_Worksheet $pSheet = null) { // Initialise cell value $this->_value = $pValue; @@ -126,9 +129,10 @@ public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Workshee $this->_parent = $pSheet->getCellCacheController(); // Set datatype? - if ($pDataType !== NULL) { - if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) + if ($pDataType !== null) { + if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) { $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + } $this->_dataType = $pDataType; } elseif (!self::getValueBinder()->bindValue($this, $pValue)) { throw new PHPExcel_Exception("Value could not be bound to cell."); @@ -183,10 +187,10 @@ public function getValue() public function getFormattedValue() { return (string) PHPExcel_Style_NumberFormat::toFormattedString( - $this->getCalculatedValue(), - $this->getStyle() - ->getNumberFormat()->getFormatCode() - ); + $this->getCalculatedValue(), + $this->getStyle() + ->getNumberFormat()->getFormatCode() + ); } /** @@ -198,7 +202,7 @@ public function getFormattedValue() * @return PHPExcel_Cell * @throws PHPExcel_Exception */ - public function setValue($pValue = NULL) + public function setValue($pValue = null) { if (!self::getValueBinder()->bindValue($this, $pValue)) { throw new PHPExcel_Exception("Value could not be bound to cell."); @@ -214,7 +218,7 @@ public function setValue($pValue = NULL) * @return PHPExcel_Cell * @throws PHPExcel_Exception */ - public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) + public function setValueExplicit($pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) { // set the value according to data type switch ($pDataType) { @@ -224,17 +228,19 @@ public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_Data case PHPExcel_Cell_DataType::TYPE_STRING2: $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; case PHPExcel_Cell_DataType::TYPE_STRING: + // Synonym for string case PHPExcel_Cell_DataType::TYPE_INLINE: + // Rich text $this->_value = PHPExcel_Cell_DataType::checkString($pValue); break; case PHPExcel_Cell_DataType::TYPE_NUMERIC: - $this->_value = (float)$pValue; + $this->_value = (float) $pValue; break; case PHPExcel_Cell_DataType::TYPE_FORMULA: - $this->_value = (string)$pValue; + $this->_value = (string) $pValue; break; case PHPExcel_Cell_DataType::TYPE_BOOL: - $this->_value = (bool)$pValue; + $this->_value = (bool) $pValue; break; case PHPExcel_Cell_DataType::TYPE_ERROR: $this->_value = PHPExcel_Cell_DataType::checkErrorCode($pValue); @@ -259,7 +265,7 @@ public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_Data * @return mixed * @throws PHPExcel_Exception */ - public function getCalculatedValue($resetLog = TRUE) + public function getCalculatedValue($resetLog = true) { //echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().PHP_EOL; if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { @@ -267,7 +273,7 @@ public function getCalculatedValue($resetLog = TRUE) //echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value'.PHP_EOL; $result = PHPExcel_Calculation::getInstance( $this->getWorksheet()->getParent() - )->calculateCellValue($this,$resetLog); + )->calculateCellValue($this, $resetLog); //echo $this->getCoordinate().' calculation result is '.$result.PHP_EOL; // We don't yet handle array returns if (is_array($result)) { @@ -275,8 +281,8 @@ public function getCalculatedValue($resetLog = TRUE) $result = array_pop($result); } } - } catch ( PHPExcel_Exception $ex ) { - if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) { + } catch (PHPExcel_Exception $ex) { + if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== null)) { //echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; return $this->_calculatedValue; // Fallback for calculations referencing external files. } @@ -293,7 +299,7 @@ public function getCalculatedValue($resetLog = TRUE) } //echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL; return $result; - } elseif($this->_value instanceof PHPExcel_RichText) { + } elseif ($this->_value instanceof PHPExcel_RichText) { // echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->_value.'<br />'; return $this->_value->getPlainText(); } @@ -307,9 +313,9 @@ public function getCalculatedValue($resetLog = TRUE) * @param mixed $pValue Value * @return PHPExcel_Cell */ - public function setCalculatedValue($pValue = NULL) + public function setCalculatedValue($pValue = null) { - if ($pValue !== NULL) { + if ($pValue !== null) { $this->_calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue; } @@ -349,9 +355,9 @@ public function getDataType() */ public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING) { - if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) + if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) { $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; - + } $this->_dataType = $pDataType; return $this->notifyCacheController(); @@ -404,7 +410,7 @@ public function getDataValidation() * @return PHPExcel_Cell * @throws PHPExcel_Exception */ - public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = NULL) + public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = null) { if (!isset($this->_parent)) { throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet'); @@ -452,7 +458,7 @@ public function getHyperlink() * @return PHPExcel_Cell * @throws PHPExcel_Exception */ - public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL) + public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = null) { if (!isset($this->_parent)) { throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); @@ -468,7 +474,8 @@ public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL) * * @return PHPExcel_CachedObjectStorage_CacheBase */ - public function getParent() { + public function getParent() + { return $this->_parent; } @@ -477,7 +484,8 @@ public function getParent() { * * @return PHPExcel_Worksheet */ - public function getWorksheet() { + public function getWorksheet() + { return $this->_parent->getParent(); } @@ -486,7 +494,8 @@ public function getWorksheet() { * * @return boolean */ - public function isInMergeRange() { + public function isInMergeRange() + { return (boolean) $this->getMergeRange(); } @@ -495,7 +504,8 @@ public function isInMergeRange() { * * @return boolean */ - public function isMergeRangeValueCell() { + public function isMergeRangeValueCell() + { if ($mergeRange = $this->getMergeRange()) { $mergeRange = PHPExcel_Cell::splitRange($mergeRange); list($startCell) = $mergeRange[0]; @@ -511,8 +521,9 @@ public function isMergeRangeValueCell() { * * @return string */ - public function getMergeRange() { - foreach($this->getWorksheet()->getMergeCells() as $mergeRange) { + public function getMergeRange() + { + foreach ($this->getWorksheet()->getMergeCells() as $mergeRange) { if ($this->isInRange($mergeRange)) { return $mergeRange; } @@ -536,7 +547,8 @@ public function getStyle() * @param PHPExcel_Worksheet $parent * @return PHPExcel_Cell */ - public function rebindParent(PHPExcel_Worksheet $parent) { + public function rebindParent(PHPExcel_Worksheet $parent) + { $this->_parent = $parent->getCellCacheController(); return $this->notifyCacheController(); @@ -550,11 +562,11 @@ public function rebindParent(PHPExcel_Worksheet $parent) { */ public function isInRange($pRange = 'A1:A1') { - list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); + list($rangeStart, $rangeEnd) = self::rangeBoundaries($pRange); // Translate properties - $myColumn = self::columnIndexFromString($this->getColumn()); - $myRow = $this->getRow(); + $myColumn = self::columnIndexFromString($this->getColumn()); + $myRow = $this->getRow(); // Verify if cell is in range return (($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) && @@ -573,7 +585,7 @@ public static function coordinateFromString($pCoordinateString = 'A1') { if (preg_match("/^([$]?[A-Z]{1,3})([$]?\d{1,7})$/", $pCoordinateString, $matches)) { return array($matches[1],$matches[2]); - } elseif ((strpos($pCoordinateString,':') !== FALSE) || (strpos($pCoordinateString,',') !== FALSE)) { + } elseif ((strpos($pCoordinateString,':') !== false) || (strpos($pCoordinateString,',') !== false)) { throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); } elseif ($pCoordinateString == '') { throw new PHPExcel_Exception('Cell coordinate can not be zero-length string'); @@ -592,14 +604,16 @@ public static function coordinateFromString($pCoordinateString = 'A1') */ public static function absoluteReference($pCoordinateString = 'A1') { - if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { + if (strpos($pCoordinateString, ':') === false && strpos($pCoordinateString, ',') === false) { // Split out any worksheet name from the reference $worksheet = ''; - $cellAddress = explode('!',$pCoordinateString); + $cellAddress = explode('!', $pCoordinateString); if (count($cellAddress) > 1) { - list($worksheet,$pCoordinateString) = $cellAddress; + list($worksheet, $pCoordinateString) = $cellAddress; + } + if ($worksheet > '') { + $worksheet .= '!'; } - if ($worksheet > '') $worksheet .= '!'; // Create absolute coordinate if (ctype_digit($pCoordinateString)) { @@ -622,19 +636,21 @@ public static function absoluteReference($pCoordinateString = 'A1') */ public static function absoluteCoordinate($pCoordinateString = 'A1') { - if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { + if (strpos($pCoordinateString, ':') === false && strpos($pCoordinateString, ',') === false) { // Split out any worksheet name from the coordinate $worksheet = ''; - $cellAddress = explode('!',$pCoordinateString); + $cellAddress = explode('!', $pCoordinateString); if (count($cellAddress) > 1) { - list($worksheet,$pCoordinateString) = $cellAddress; + list($worksheet, $pCoordinateString) = $cellAddress; + } + if ($worksheet > '') { + $worksheet .= '!'; } - if ($worksheet > '') $worksheet .= '!'; // Create absolute coordinate list($column, $row) = self::coordinateFromString($pCoordinateString); - $column = ltrim($column,'$'); - $row = ltrim($row,'$'); + $column = ltrim($column, '$'); + $row = ltrim($row, '$'); return $worksheet . '$' . $column . '$' . $row; } @@ -652,7 +668,7 @@ public static function absoluteCoordinate($pCoordinateString = 'A1') public static function splitRange($pRange = 'A1:A1') { // Ensure $pRange is a valid range - if(empty($pRange)) { + if (empty($pRange)) { $pRange = self::DEFAULT_RANGE; } @@ -699,7 +715,7 @@ public static function buildRange($pRange) public static function rangeBoundaries($pRange = 'A1:A1') { // Ensure $pRange is a valid range - if(empty($pRange)) { + if (empty($pRange)) { $pRange = self::DEFAULT_RANGE; } @@ -707,7 +723,7 @@ public static function rangeBoundaries($pRange = 'A1:A1') $pRange = strtoupper($pRange); // Extract range - if (strpos($pRange, ':') === FALSE) { + if (strpos($pRange, ':') === false) { $rangeA = $rangeB = $pRange; } else { list($rangeA, $rangeB) = explode(':', $pRange); @@ -733,7 +749,7 @@ public static function rangeBoundaries($pRange = 'A1:A1') public static function rangeDimension($pRange = 'A1:A1') { // Calculate range outer borders - list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); + list($rangeStart, $rangeEnd) = self::rangeBoundaries($pRange); return array( ($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1) ); } @@ -748,7 +764,7 @@ public static function rangeDimension($pRange = 'A1:A1') public static function getRangeBoundaries($pRange = 'A1:A1') { // Ensure $pRange is a valid range - if(empty($pRange)) { + if (empty($pRange)) { $pRange = self::DEFAULT_RANGE; } @@ -756,7 +772,7 @@ public static function getRangeBoundaries($pRange = 'A1:A1') $pRange = strtoupper($pRange); // Extract range - if (strpos($pRange, ':') === FALSE) { + if (strpos($pRange, ':') === false) { $rangeA = $rangeB = $pRange; } else { list($rangeA, $rangeB) = explode(':', $pRange); @@ -778,9 +794,9 @@ public static function columnIndexFromString($pString = 'A') // though it's additional memory overhead static $_indexCache = array(); - if (isset($_indexCache[$pString])) + if (isset($_indexCache[$pString])) { return $_indexCache[$pString]; - + } // It's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array rather than use ord() // and make it case insensitive to get rid of the strtoupper() as well. Because it's a static, there's no significant // memory overhead either @@ -797,10 +813,10 @@ public static function columnIndexFromString($pString = 'A') if (!isset($pString{1})) { $_indexCache[$pString] = $_columnLookup[$pString]; return $_indexCache[$pString]; - } elseif(!isset($pString{2})) { + } elseif (!isset($pString{2})) { $_indexCache[$pString] = $_columnLookup[$pString{0}] * 26 + $_columnLookup[$pString{1}]; return $_indexCache[$pString]; - } elseif(!isset($pString{3})) { + } elseif (!isset($pString{3})) { $_indexCache[$pString] = $_columnLookup[$pString{0}] * 676 + $_columnLookup[$pString{1}] * 26 + $_columnLookup[$pString{2}]; return $_indexCache[$pString]; } @@ -843,7 +859,8 @@ public static function stringFromColumnIndex($pColumnIndex = 0) * @param string $pRange Range (e.g. A1 or A1:C10 or A1:E10 A20:E25) * @return array Array containing single cell references */ - public static function extractAllCellReferencesInRange($pRange = 'A1') { + public static function extractAllCellReferencesInRange($pRange = 'A1') + { // Returnvalue $returnValue = array(); @@ -851,14 +868,14 @@ public static function extractAllCellReferencesInRange($pRange = 'A1') { $cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange))); foreach ($cellBlocks as $cellBlock) { // Single cell? - if (strpos($cellBlock,':') === FALSE && strpos($cellBlock,',') === FALSE) { + if (strpos($cellBlock,':') === false && strpos($cellBlock,',') === false) { $returnValue[] = $cellBlock; continue; } // Range... $ranges = self::splitRange($cellBlock); - foreach($ranges as $range) { + foreach ($ranges as $range) { // Single cell? if (!isset($range[1])) { $returnValue[] = $range[0]; @@ -867,13 +884,13 @@ public static function extractAllCellReferencesInRange($pRange = 'A1') { // Range... list($rangeStart, $rangeEnd) = $range; - sscanf($rangeStart,'%[A-Z]%d', $startCol, $startRow); - sscanf($rangeEnd,'%[A-Z]%d', $endCol, $endRow); - $endCol++; + sscanf($rangeStart, '%[A-Z]%d', $startCol, $startRow); + sscanf($rangeEnd, '%[A-Z]%d', $endCol, $endRow); + ++$endCol; // Current data - $currentCol = $startCol; - $currentRow = $startRow; + $currentCol = $startCol; + $currentRow = $startRow; // Loop cells while ($currentCol != $endCol) { @@ -890,8 +907,8 @@ public static function extractAllCellReferencesInRange($pRange = 'A1') { // Sort the result by column and row $sortKeys = array(); foreach (array_unique($returnValue) as $coord) { - sscanf($coord,'%[A-Z]%d', $column, $row); - $sortKeys[sprintf('%3s%09d',$column,$row)] = $coord; + sscanf($coord, '%[A-Z]%d', $column, $row); + $sortKeys[sprintf('%3s%09d', $column, $row)] = $coord; } ksort($sortKeys); @@ -924,8 +941,9 @@ public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b) * * @return PHPExcel_Cell_IValueBinder */ - public static function getValueBinder() { - if (self::$_valueBinder === NULL) { + public static function getValueBinder() + { + if (self::$_valueBinder === null) { self::$_valueBinder = new PHPExcel_Cell_DefaultValueBinder(); } @@ -938,8 +956,9 @@ public static function getValueBinder() { * @param PHPExcel_Cell_IValueBinder $binder * @throws PHPExcel_Exception */ - public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) { - if ($binder === NULL) { + public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = null) + { + if ($binder === null) { throw new PHPExcel_Exception("A PHPExcel_Cell_IValueBinder is required for PHPExcel to function correctly."); } @@ -949,7 +968,8 @@ public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if ((is_object($value)) && ($key != '_parent')) { @@ -1009,6 +1029,4 @@ public function __toString() { return (string) $this->getValue(); } - } - diff --git a/Classes/PHPExcel/Cell/AdvancedValueBinder.php b/Classes/PHPExcel/Cell/AdvancedValueBinder.php index bc7a19f14..ee2de791d 100644 --- a/Classes/PHPExcel/Cell/AdvancedValueBinder.php +++ b/Classes/PHPExcel/Cell/AdvancedValueBinder.php @@ -59,7 +59,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) if ($value == PHPExcel_Calculation::getTRUE()) { $cell->setValueExplicit(true, PHPExcel_Cell_DataType::TYPE_BOOL); return true; - } elseif($value == PHPExcel_Calculation::getFALSE()) { + } elseif ($value == PHPExcel_Calculation::getFALSE()) { $cell->setValueExplicit(false, PHPExcel_Cell_DataType::TYPE_BOOL); return true; } @@ -74,20 +74,24 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) if (preg_match('/^([+-]?)\s*([0-9]+)\s?\/\s*([0-9]+)$/', $value, $matches)) { // Convert value to number $value = $matches[2] / $matches[3]; - if ($matches[1] == '-') $value = 0 - $value; + if ($matches[1] == '-') { + $value = 0 - $value; + } $cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) - ->getNumberFormat()->setFormatCode( '??/??' ); + $cell->getWorksheet()->getStyle($cell->getCoordinate()) + ->getNumberFormat()->setFormatCode('??/??'); return true; } elseif (preg_match('/^([+-]?)([0-9]*) +([0-9]*)\s?\/\s*([0-9]*)$/', $value, $matches)) { // Convert value to number $value = $matches[2] + ($matches[3] / $matches[4]); - if ($matches[1] == '-') $value = 0 - $value; + if ($matches[1] == '-') { + $value = 0 - $value; + } $cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) - ->getNumberFormat()->setFormatCode( '# ??/??' ); + $cell->getWorksheet()->getStyle($cell->getCoordinate()) + ->getNumberFormat()->setFormatCode('# ??/??'); return true; } @@ -95,9 +99,9 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) if (preg_match('/^\-?[0-9]*\.?[0-9]*\s?\%$/', $value)) { // Convert value to number $value = (float) str_replace('%', '', $value) / 100; - $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00); return true; } diff --git a/Classes/PHPExcel/Cell/DataType.php b/Classes/PHPExcel/Cell/DataType.php index dda18ed8f..fc010e653 100644 --- a/Classes/PHPExcel/Cell/DataType.php +++ b/Classes/PHPExcel/Cell/DataType.php @@ -112,5 +112,4 @@ public static function checkErrorCode($pValue = null) return $pValue; } - } diff --git a/Classes/PHPExcel/Cell/DataValidation.php b/Classes/PHPExcel/Cell/DataValidation.php index 38d59e851..a9963b084 100644 --- a/Classes/PHPExcel/Cell/DataValidation.php +++ b/Classes/PHPExcel/Cell/DataValidation.php @@ -57,91 +57,91 @@ class PHPExcel_Cell_DataValidation * * @var string */ - private $_formula1; + private $formula1; /** * Formula 2 * * @var string */ - private $_formula2; + private $formula2; /** * Type * * @var string */ - private $_type = PHPExcel_Cell_DataValidation::TYPE_NONE; + private $type = PHPExcel_Cell_DataValidation::TYPE_NONE; /** * Error style * * @var string */ - private $_errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; + private $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; /** * Operator * * @var string */ - private $_operator; + private $operator; /** * Allow Blank * * @var boolean */ - private $_allowBlank; + private $allowBlank; /** * Show DropDown * * @var boolean */ - private $_showDropDown; + private $showDropDown; /** * Show InputMessage * * @var boolean */ - private $_showInputMessage; + private $showInputMessage; /** * Show ErrorMessage * * @var boolean */ - private $_showErrorMessage; + private $showErrorMessage; /** * Error title * * @var string */ - private $_errorTitle; + private $errorTitle; /** * Error * * @var string */ - private $_error; + private $error; /** * Prompt title * * @var string */ - private $_promptTitle; + private $promptTitle; /** * Prompt * * @var string */ - private $_prompt; + private $prompt; /** * Create a new PHPExcel_Cell_DataValidation @@ -149,19 +149,19 @@ class PHPExcel_Cell_DataValidation public function __construct() { // Initialise member variables - $this->_formula1 = ''; - $this->_formula2 = ''; - $this->_type = PHPExcel_Cell_DataValidation::TYPE_NONE; - $this->_errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; - $this->_operator = ''; - $this->_allowBlank = FALSE; - $this->_showDropDown = FALSE; - $this->_showInputMessage = FALSE; - $this->_showErrorMessage = FALSE; - $this->_errorTitle = ''; - $this->_error = ''; - $this->_promptTitle = ''; - $this->_prompt = ''; + $this->formula1 = ''; + $this->formula2 = ''; + $this->type = PHPExcel_Cell_DataValidation::TYPE_NONE; + $this->errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; + $this->operator = ''; + $this->allowBlank = false; + $this->showDropDown = false; + $this->showInputMessage = false; + $this->showErrorMessage = false; + $this->errorTitle = ''; + $this->error = ''; + $this->promptTitle = ''; + $this->prompt = ''; } /** @@ -169,8 +169,9 @@ public function __construct() * * @return string */ - public function getFormula1() { - return $this->_formula1; + public function getFormula1() + { + return $this->formula1; } /** @@ -179,8 +180,9 @@ public function getFormula1() { * @param string $value * @return PHPExcel_Cell_DataValidation */ - public function setFormula1($value = '') { - $this->_formula1 = $value; + public function setFormula1($value = '') + { + $this->formula1 = $value; return $this; } @@ -190,7 +192,7 @@ public function setFormula1($value = '') { * @return string */ public function getFormula2() { - return $this->_formula2; + return $this->formula2; } /** @@ -199,8 +201,9 @@ public function getFormula2() { * @param string $value * @return PHPExcel_Cell_DataValidation */ - public function setFormula2($value = '') { - $this->_formula2 = $value; + public function setFormula2($value = '') + { + $this->formula2 = $value; return $this; } @@ -209,8 +212,9 @@ public function setFormula2($value = '') { * * @return string */ - public function getType() { - return $this->_type; + public function getType() + { + return $this->type; } /** @@ -219,8 +223,9 @@ public function getType() { * @param string $value * @return PHPExcel_Cell_DataValidation */ - public function setType($value = PHPExcel_Cell_DataValidation::TYPE_NONE) { - $this->_type = $value; + public function setType($value = PHPExcel_Cell_DataValidation::TYPE_NONE) + { + $this->type = $value; return $this; } @@ -229,8 +234,9 @@ public function setType($value = PHPExcel_Cell_DataValidation::TYPE_NONE) { * * @return string */ - public function getErrorStyle() { - return $this->_errorStyle; + public function getErrorStyle() + { + return $this->errorStyle; } /** @@ -239,8 +245,9 @@ public function getErrorStyle() { * @param string $value * @return PHPExcel_Cell_DataValidation */ - public function setErrorStyle($value = PHPExcel_Cell_DataValidation::STYLE_STOP) { - $this->_errorStyle = $value; + public function setErrorStyle($value = PHPExcel_Cell_DataValidation::STYLE_STOP) + { + $this->errorStyle = $value; return $this; } @@ -249,8 +256,9 @@ public function setErrorStyle($value = PHPExcel_Cell_DataValidation::STYLE_STOP) * * @return string */ - public function getOperator() { - return $this->_operator; + public function getOperator() + { + return $this->operator; } /** @@ -259,8 +267,9 @@ public function getOperator() { * @param string $value * @return PHPExcel_Cell_DataValidation */ - public function setOperator($value = '') { - $this->_operator = $value; + public function setOperator($value = '') + { + $this->operator = $value; return $this; } @@ -269,8 +278,9 @@ public function setOperator($value = '') { * * @return boolean */ - public function getAllowBlank() { - return $this->_allowBlank; + public function getAllowBlank() + { + return $this->allowBlank; } /** @@ -279,8 +289,9 @@ public function getAllowBlank() { * @param boolean $value * @return PHPExcel_Cell_DataValidation */ - public function setAllowBlank($value = false) { - $this->_allowBlank = $value; + public function setAllowBlank($value = false) + { + $this->allowBlank = $value; return $this; } @@ -289,8 +300,9 @@ public function setAllowBlank($value = false) { * * @return boolean */ - public function getShowDropDown() { - return $this->_showDropDown; + public function getShowDropDown() + { + return $this->showDropDown; } /** @@ -299,8 +311,9 @@ public function getShowDropDown() { * @param boolean $value * @return PHPExcel_Cell_DataValidation */ - public function setShowDropDown($value = false) { - $this->_showDropDown = $value; + public function setShowDropDown($value = false) + { + $this->showDropDown = $value; return $this; } @@ -309,8 +322,9 @@ public function setShowDropDown($value = false) { * * @return boolean */ - public function getShowInputMessage() { - return $this->_showInputMessage; + public function getShowInputMessage() + { + return $this->showInputMessage; } /** @@ -319,8 +333,9 @@ public function getShowInputMessage() { * @param boolean $value * @return PHPExcel_Cell_DataValidation */ - public function setShowInputMessage($value = false) { - $this->_showInputMessage = $value; + public function setShowInputMessage($value = false) + { + $this->showInputMessage = $value; return $this; } @@ -329,8 +344,9 @@ public function setShowInputMessage($value = false) { * * @return boolean */ - public function getShowErrorMessage() { - return $this->_showErrorMessage; + public function getShowErrorMessage() + { + return $this->showErrorMessage; } /** @@ -339,8 +355,9 @@ public function getShowErrorMessage() { * @param boolean $value * @return PHPExcel_Cell_DataValidation */ - public function setShowErrorMessage($value = false) { - $this->_showErrorMessage = $value; + public function setShowErrorMessage($value = false) + { + $this->showErrorMessage = $value; return $this; } @@ -349,8 +366,9 @@ public function setShowErrorMessage($value = false) { * * @return string */ - public function getErrorTitle() { - return $this->_errorTitle; + public function getErrorTitle() + { + return $this->errorTitle; } /** @@ -359,8 +377,9 @@ public function getErrorTitle() { * @param string $value * @return PHPExcel_Cell_DataValidation */ - public function setErrorTitle($value = '') { - $this->_errorTitle = $value; + public function setErrorTitle($value = '') + { + $this->errorTitle = $value; return $this; } @@ -369,8 +388,9 @@ public function setErrorTitle($value = '') { * * @return string */ - public function getError() { - return $this->_error; + public function getError() + { + return $this->error; } /** @@ -379,8 +399,9 @@ public function getError() { * @param string $value * @return PHPExcel_Cell_DataValidation */ - public function setError($value = '') { - $this->_error = $value; + public function setError($value = '') + { + $this->error = $value; return $this; } @@ -389,8 +410,9 @@ public function setError($value = '') { * * @return string */ - public function getPromptTitle() { - return $this->_promptTitle; + public function getPromptTitle() + { + return $this->promptTitle; } /** @@ -399,8 +421,9 @@ public function getPromptTitle() { * @param string $value * @return PHPExcel_Cell_DataValidation */ - public function setPromptTitle($value = '') { - $this->_promptTitle = $value; + public function setPromptTitle($value = '') + { + $this->promptTitle = $value; return $this; } @@ -409,8 +432,9 @@ public function setPromptTitle($value = '') { * * @return string */ - public function getPrompt() { - return $this->_prompt; + public function getPrompt() + { + return $this->prompt; } /** @@ -419,8 +443,9 @@ public function getPrompt() { * @param string $value * @return PHPExcel_Cell_DataValidation */ - public function setPrompt($value = '') { - $this->_prompt = $value; + public function setPrompt($value = '') + { + $this->prompt = $value; return $this; } @@ -429,29 +454,31 @@ public function setPrompt($value = '') { * * @return string Hash code */ - public function getHashCode() { + public function getHashCode() + { return md5( - $this->_formula1 - . $this->_formula2 - . $this->_type = PHPExcel_Cell_DataValidation::TYPE_NONE - . $this->_errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP - . $this->_operator - . ($this->_allowBlank ? 't' : 'f') - . ($this->_showDropDown ? 't' : 'f') - . ($this->_showInputMessage ? 't' : 'f') - . ($this->_showErrorMessage ? 't' : 'f') - . $this->_errorTitle - . $this->_error - . $this->_promptTitle - . $this->_prompt - . __CLASS__ + $this->formula1 . + $this->formula2 . + $this->type = PHPExcel_Cell_DataValidation::TYPE_NONE . + $this->errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP . + $this->operator . + ($this->allowBlank ? 't' : 'f') . + ($this->showDropDown ? 't' : 'f') . + ($this->showInputMessage ? 't' : 'f') . + ($this->showErrorMessage ? 't' : 'f') . + $this->errorTitle . + $this->error . + $this->promptTitle . + $this->prompt . + __CLASS__ ); } /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/Cell/DefaultValueBinder.php b/Classes/PHPExcel/Cell/DefaultValueBinder.php index 779380ac7..dc19e6c45 100644 --- a/Classes/PHPExcel/Cell/DefaultValueBinder.php +++ b/Classes/PHPExcel/Cell/DefaultValueBinder.php @@ -87,9 +87,9 @@ public static function dataTypeForValue($pValue = null) return PHPExcel_Cell_DataType::TYPE_NUMERIC; } elseif (preg_match('/^[\+\-]?([0-9]+\\.?[0-9]*|[0-9]*\\.?[0-9]+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $pValue)) { $tValue = ltrim($pValue, '+-'); - if (is_string($pValue) && $tValue{0} === '0' && strlen($tValue) > 1 && $tValue{1} !== '.' ) { + if (is_string($pValue) && $tValue{0} === '0' && strlen($tValue) > 1 && $tValue{1} !== '.') { return PHPExcel_Cell_DataType::TYPE_STRING; - } elseif((strpos($pValue, '.') === false) && ($pValue > PHP_INT_MAX)) { + } elseif ((strpos($pValue, '.') === false) && ($pValue > PHP_INT_MAX)) { return PHPExcel_Cell_DataType::TYPE_STRING; } return PHPExcel_Cell_DataType::TYPE_NUMERIC; diff --git a/Classes/PHPExcel/Chart/Axis.php b/Classes/PHPExcel/Chart/Axis.php index f50181837..65abf9caf 100644 --- a/Classes/PHPExcel/Chart/Axis.php +++ b/Classes/PHPExcel/Chart/Axis.php @@ -7,8 +7,8 @@ * Time: 12:11 PM */ -class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties { - +class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties +{ /** * Axis Number * @@ -25,16 +25,16 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties { * @var array of mixed */ private $_axis_options = array( - 'minimum' => NULL, - 'maximum' => NULL, - 'major_unit' => NULL, - 'minor_unit' => NULL, + 'minimum' => null, + 'maximum' => null, + 'major_unit' => null, + 'minor_unit' => null, 'orientation' => self::ORIENTATION_NORMAL, 'minor_tick_mark' => self::TICK_MARK_NONE, 'major_tick_mark' => self::TICK_MARK_NONE, 'axis_labels' => self::AXIS_LABELS_NEXT_TO, 'horizontal_crosses' => self::HORIZONTAL_CROSSES_AUTOZERO, - 'horizontal_crosses_value' => NULL + 'horizontal_crosses_value' => null ); /** @@ -44,7 +44,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties { */ private $_fill_properties = array( 'type' => self::EXCEL_COLOR_TYPE_ARGB, - 'value' => NULL, + 'value' => null, 'alpha' => 0 ); @@ -55,7 +55,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties { */ private $_line_properties = array( 'type' => self::EXCEL_COLOR_TYPE_ARGB, - 'value' => NULL, + 'value' => null, 'alpha' => 0 ); @@ -89,22 +89,22 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties { */ private $_shadow_properties = array( 'presets' => self::SHADOW_PRESETS_NOSHADOW, - 'effect' => NULL, + 'effect' => null, 'color' => array( 'type' => self::EXCEL_COLOR_TYPE_STANDARD, 'value' => 'black', 'alpha' => 40, ), 'size' => array( - 'sx' => NULL, - 'sy' => NULL, - 'kx' => NULL + 'sx' => null, + 'sy' => null, + 'kx' => null ), - 'blur' => NULL, - 'direction' => NULL, - 'distance' => NULL, - 'algn' => NULL, - 'rotWithShape' => NULL + 'blur' => null, + 'direction' => null, + 'distance' => null, + 'algn' => null, + 'rotWithShape' => null ); /** @@ -113,7 +113,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties { * @var array of mixed */ private $_glow_properties = array( - 'size' => NULL, + 'size' => null, 'color' => array( 'type' => self::EXCEL_COLOR_TYPE_STANDARD, 'value' => 'black', @@ -127,7 +127,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties { * @var array of mixed */ private $_soft_edges = array( - 'size' => NULL + 'size' => null ); /** @@ -135,7 +135,8 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties { * * @return string */ - public function setAxisNumberProperties($format_code) { + public function setAxisNumberProperties($format_code) + { $this->_axis_number['format'] = (string) $format_code; $this->_axis_number['source_linked'] = 0; } @@ -145,7 +146,8 @@ public function setAxisNumberProperties($format_code) { * * @return string */ - public function getAxisNumberFormat() { + public function getAxisNumberFormat() + { return $this->_axis_number['format']; } @@ -154,7 +156,8 @@ public function getAxisNumberFormat() { * * @return string */ - public function getAxisNumberSourceLinked() { + public function getAxisNumberSourceLinked() + { return (string) $this->_axis_number['source_linked']; } @@ -173,22 +176,22 @@ public function getAxisNumberSourceLinked() { * @param string $minor_unit * */ - public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = NULL, $horizontal_crosses = NULL, - $axis_orientation = NULL, $major_tmt = NULL, $minor_tmt = NULL, $minimum = NULL, $maximum = NULL, $major_unit = NULL, - $minor_unit = NULL) + public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = null, $horizontal_crosses = null, + $axis_orientation = null, $major_tmt = null, $minor_tmt = null, $minimum = null, $maximum = null, $major_unit = null, + $minor_unit = null) { $this->_axis_options['axis_labels'] = (string) $axis_labels; - ($horizontal_crosses_value !== NULL) - ? $this->_axis_options['horizontal_crosses_value'] = (string) $horizontal_crosses_value : NULL; - ($horizontal_crosses !== NULL) ? $this->_axis_options['horizontal_crosses'] = (string) $horizontal_crosses : NULL; - ($axis_orientation !== NULL) ? $this->_axis_options['orientation'] = (string) $axis_orientation : NULL; - ($major_tmt !== NULL) ? $this->_axis_options['major_tick_mark'] = (string) $major_tmt : NULL; - ($minor_tmt !== NULL) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : NULL; - ($minor_tmt !== NULL) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : NULL; - ($minimum !== NULL) ? $this->_axis_options['minimum'] = (string) $minimum : NULL; - ($maximum !== NULL) ? $this->_axis_options['maximum'] = (string) $maximum : NULL; - ($major_unit !== NULL) ? $this->_axis_options['major_unit'] = (string) $major_unit : NULL; - ($minor_unit !== NULL) ? $this->_axis_options['minor_unit'] = (string) $minor_unit : NULL; + ($horizontal_crosses_value !== null) + ? $this->_axis_options['horizontal_crosses_value'] = (string) $horizontal_crosses_value : null; + ($horizontal_crosses !== null) ? $this->_axis_options['horizontal_crosses'] = (string) $horizontal_crosses : null; + ($axis_orientation !== null) ? $this->_axis_options['orientation'] = (string) $axis_orientation : null; + ($major_tmt !== null) ? $this->_axis_options['major_tick_mark'] = (string) $major_tmt : null; + ($minor_tmt !== null) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : null; + ($minor_tmt !== null) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : null; + ($minimum !== null) ? $this->_axis_options['minimum'] = (string) $minimum : null; + ($maximum !== null) ? $this->_axis_options['maximum'] = (string) $maximum : null; + ($major_unit !== null) ? $this->_axis_options['major_unit'] = (string) $major_unit : null; + ($minor_unit !== null) ? $this->_axis_options['minor_unit'] = (string) $minor_unit : null; } /** @@ -273,24 +276,24 @@ public function getLineProperty($property) { * */ - public function setLineStyleProperties($line_width = NULL, $compound_type = NULL, - $dash_type = NULL, $cap_type = NULL, $join_type = NULL, $head_arrow_type = NULL, - $head_arrow_size = NULL, $end_arrow_type = NULL, $end_arrow_size = NULL) { + public function setLineStyleProperties($line_width = null, $compound_type = null, + $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, + $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) { (!is_null($line_width)) ? $this->_line_style_properties['width'] = $this->getExcelPointsWidth((float) $line_width) - : NULL; - (!is_null($compound_type)) ? $this->_line_style_properties['compound'] = (string) $compound_type : NULL; - (!is_null($dash_type)) ? $this->_line_style_properties['dash'] = (string) $dash_type : NULL; - (!is_null($cap_type)) ? $this->_line_style_properties['cap'] = (string) $cap_type : NULL; - (!is_null($join_type)) ? $this->_line_style_properties['join'] = (string) $join_type : NULL; + : null; + (!is_null($compound_type)) ? $this->_line_style_properties['compound'] = (string) $compound_type : null; + (!is_null($dash_type)) ? $this->_line_style_properties['dash'] = (string) $dash_type : null; + (!is_null($cap_type)) ? $this->_line_style_properties['cap'] = (string) $cap_type : null; + (!is_null($join_type)) ? $this->_line_style_properties['join'] = (string) $join_type : null; (!is_null($head_arrow_type)) ? $this->_line_style_properties['arrow']['head']['type'] = (string) $head_arrow_type - : NULL; + : null; (!is_null($head_arrow_size)) ? $this->_line_style_properties['arrow']['head']['size'] = (string) $head_arrow_size - : NULL; + : null; (!is_null($end_arrow_type)) ? $this->_line_style_properties['arrow']['end']['type'] = (string) $end_arrow_type - : NULL; + : null; (!is_null($end_arrow_size)) ? $this->_line_style_properties['arrow']['end']['size'] = (string) $end_arrow_size - : NULL; + : null; } /** @@ -342,7 +345,7 @@ public function getLineStyleArrowLength($arrow) { * */ - public function setShadowProperties($sh_presets, $sh_color_value = NULL, $sh_color_type = NULL, $sh_color_alpha = NULL, $sh_blur = NULL, $sh_angle = NULL, $sh_distance = NULL) { + public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_color_type = null, $sh_color_alpha = null, $sh_blur = null, $sh_angle = null, $sh_distance = null) { $this ->_setShadowPresetsProperties((int) $sh_presets) ->_setShadowColor( @@ -378,18 +381,18 @@ private function _setShadowPresetsProperties($shadow_presets) { * @return PHPExcel_Chart_Axis */ - private function _setShadowProperiesMapValues(array $properties_map, &$reference = NULL) { + private function _setShadowProperiesMapValues(array $properties_map, &$reference = null) { $base_reference = $reference; foreach ($properties_map as $property_key => $property_val) { if (is_array($property_val)) { - if ($reference === NULL) { + if ($reference === null) { $reference = & $this->_shadow_properties[$property_key]; } else { $reference = & $reference[$property_key]; } $this->_setShadowProperiesMapValues($property_val, $reference); } else { - if ($base_reference === NULL) { + if ($base_reference === null) { $this->_shadow_properties[$property_key] = $property_val; } else { $reference[$property_key] = $property_val; @@ -425,7 +428,7 @@ private function _setShadowColor($color, $alpha, $type) { */ private function _setShadowBlur($blur) { - if ($blur !== NULL) { + if ($blur !== null) { $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur); } @@ -441,7 +444,7 @@ private function _setShadowBlur($blur) { */ private function _setShadowAngle($angle) { - if ($angle !== NULL) { + if ($angle !== null) { $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle); } @@ -457,7 +460,7 @@ private function _setShadowAngle($angle) { */ private function _setShadowDistance($distance) { - if ($distance !== NULL) { + if ($distance !== null) { $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance); } @@ -486,7 +489,7 @@ public function getShadowProperty($elements) { * @param string $color_type */ - public function setGlowProperties($size, $color_value = NULL, $color_alpha = NULL, $color_type = NULL) { + public function setGlowProperties($size, $color_value = null, $color_alpha = null, $color_type = null) { $this ->_setGlowSize($size) ->_setGlowColor( diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index e6d277121..711f16cee 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -18,353 +18,352 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Chart + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** * PHPExcel_Chart_DataSeries * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Chart + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_DataSeries { - - const TYPE_BARCHART = 'barChart'; - const TYPE_BARCHART_3D = 'bar3DChart'; - const TYPE_LINECHART = 'lineChart'; - const TYPE_LINECHART_3D = 'line3DChart'; - const TYPE_AREACHART = 'areaChart'; - const TYPE_AREACHART_3D = 'area3DChart'; - const TYPE_PIECHART = 'pieChart'; - const TYPE_PIECHART_3D = 'pie3DChart'; - const TYPE_DOUGHTNUTCHART = 'doughnutChart'; - const TYPE_DONUTCHART = self::TYPE_DOUGHTNUTCHART; // Synonym - const TYPE_SCATTERCHART = 'scatterChart'; - const TYPE_SURFACECHART = 'surfaceChart'; - const TYPE_SURFACECHART_3D = 'surface3DChart'; - const TYPE_RADARCHART = 'radarChart'; - const TYPE_BUBBLECHART = 'bubbleChart'; - const TYPE_STOCKCHART = 'stockChart'; - const TYPE_CANDLECHART = self::TYPE_STOCKCHART; // Synonym - - const GROUPING_CLUSTERED = 'clustered'; - const GROUPING_STACKED = 'stacked'; - const GROUPING_PERCENT_STACKED = 'percentStacked'; - const GROUPING_STANDARD = 'standard'; - - const DIRECTION_BAR = 'bar'; - const DIRECTION_HORIZONTAL = self::DIRECTION_BAR; - const DIRECTION_COL = 'col'; - const DIRECTION_COLUMN = self::DIRECTION_COL; - const DIRECTION_VERTICAL = self::DIRECTION_COL; - - const STYLE_LINEMARKER = 'lineMarker'; - const STYLE_SMOOTHMARKER = 'smoothMarker'; - const STYLE_MARKER = 'marker'; - const STYLE_FILLED = 'filled'; - - - /** - * Series Plot Type - * - * @var string - */ - private $_plotType = null; - - /** - * Plot Grouping Type - * - * @var boolean - */ - private $_plotGrouping = null; - - /** - * Plot Direction - * - * @var boolean - */ - private $_plotDirection = null; - - /** - * Plot Style - * - * @var string - */ - private $_plotStyle = null; - - /** - * Order of plots in Series - * - * @var array of integer - */ - private $_plotOrder = array(); - - /** - * Plot Label - * - * @var array of PHPExcel_Chart_DataSeriesValues - */ - private $_plotLabel = array(); - - /** - * Plot Category - * - * @var array of PHPExcel_Chart_DataSeriesValues - */ - private $_plotCategory = array(); - - /** - * Smooth Line - * - * @var string - */ - private $_smoothLine = null; - - /** - * Plot Values - * - * @var array of PHPExcel_Chart_DataSeriesValues - */ - private $_plotValues = array(); - - /** - * Create a new PHPExcel_Chart_DataSeries - */ - public function __construct($plotType = null, $plotGrouping = null, $plotOrder = array(), $plotLabel = array(), $plotCategory = array(), $plotValues = array(), $plotDirection = null, $smoothLine = null, $plotStyle = null) - { - $this->_plotType = $plotType; - $this->_plotGrouping = $plotGrouping; - $this->_plotOrder = $plotOrder; - $keys = array_keys($plotValues); - $this->_plotValues = $plotValues; - if ((count($plotLabel) == 0) || (is_null($plotLabel[$keys[0]]))) { - $plotLabel[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); - } - - $this->_plotLabel = $plotLabel; - if ((count($plotCategory) == 0) || (is_null($plotCategory[$keys[0]]))) { - $plotCategory[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); - } - $this->_plotCategory = $plotCategory; - $this->_smoothLine = $smoothLine; - $this->_plotStyle = $plotStyle; - - if (is_null($plotDirection)) { - $plotDirection = self::DIRECTION_COL; - } - $this->_plotDirection = $plotDirection; - } - - /** - * Get Plot Type - * - * @return string - */ - public function getPlotType() { - return $this->_plotType; - } - - /** - * Set Plot Type - * - * @param string $plotType + const TYPE_BARCHART = 'barChart'; + const TYPE_BARCHART_3D = 'bar3DChart'; + const TYPE_LINECHART = 'lineChart'; + const TYPE_LINECHART_3D = 'line3DChart'; + const TYPE_AREACHART = 'areaChart'; + const TYPE_AREACHART_3D = 'area3DChart'; + const TYPE_PIECHART = 'pieChart'; + const TYPE_PIECHART_3D = 'pie3DChart'; + const TYPE_DOUGHTNUTCHART = 'doughnutChart'; + const TYPE_DONUTCHART = self::TYPE_DOUGHTNUTCHART; // Synonym + const TYPE_SCATTERCHART = 'scatterChart'; + const TYPE_SURFACECHART = 'surfaceChart'; + const TYPE_SURFACECHART_3D = 'surface3DChart'; + const TYPE_RADARCHART = 'radarChart'; + const TYPE_BUBBLECHART = 'bubbleChart'; + const TYPE_STOCKCHART = 'stockChart'; + const TYPE_CANDLECHART = self::TYPE_STOCKCHART; // Synonym + + const GROUPING_CLUSTERED = 'clustered'; + const GROUPING_STACKED = 'stacked'; + const GROUPING_PERCENT_STACKED = 'percentStacked'; + const GROUPING_STANDARD = 'standard'; + + const DIRECTION_BAR = 'bar'; + const DIRECTION_HORIZONTAL = self::DIRECTION_BAR; + const DIRECTION_COL = 'col'; + const DIRECTION_COLUMN = self::DIRECTION_COL; + const DIRECTION_VERTICAL = self::DIRECTION_COL; + + const STYLE_LINEMARKER = 'lineMarker'; + const STYLE_SMOOTHMARKER = 'smoothMarker'; + const STYLE_MARKER = 'marker'; + const STYLE_FILLED = 'filled'; + + + /** + * Series Plot Type + * + * @var string + */ + private $_plotType = null; + + /** + * Plot Grouping Type + * + * @var boolean + */ + private $_plotGrouping = null; + + /** + * Plot Direction + * + * @var boolean + */ + private $_plotDirection = null; + + /** + * Plot Style + * + * @var string + */ + private $_plotStyle = null; + + /** + * Order of plots in Series + * + * @var array of integer + */ + private $_plotOrder = array(); + + /** + * Plot Label + * + * @var array of PHPExcel_Chart_DataSeriesValues + */ + private $_plotLabel = array(); + + /** + * Plot Category + * + * @var array of PHPExcel_Chart_DataSeriesValues + */ + private $_plotCategory = array(); + + /** + * Smooth Line + * + * @var string + */ + private $_smoothLine = null; + + /** + * Plot Values + * + * @var array of PHPExcel_Chart_DataSeriesValues + */ + private $_plotValues = array(); + + /** + * Create a new PHPExcel_Chart_DataSeries + */ + public function __construct($plotType = null, $plotGrouping = null, $plotOrder = array(), $plotLabel = array(), $plotCategory = array(), $plotValues = array(), $plotDirection = null, $smoothLine = null, $plotStyle = null) + { + $this->_plotType = $plotType; + $this->_plotGrouping = $plotGrouping; + $this->_plotOrder = $plotOrder; + $keys = array_keys($plotValues); + $this->_plotValues = $plotValues; + if ((count($plotLabel) == 0) || (is_null($plotLabel[$keys[0]]))) { + $plotLabel[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); + } + + $this->_plotLabel = $plotLabel; + if ((count($plotCategory) == 0) || (is_null($plotCategory[$keys[0]]))) { + $plotCategory[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); + } + $this->_plotCategory = $plotCategory; + $this->_smoothLine = $smoothLine; + $this->_plotStyle = $plotStyle; + + if (is_null($plotDirection)) { + $plotDirection = self::DIRECTION_COL; + } + $this->_plotDirection = $plotDirection; + } + + /** + * Get Plot Type + * + * @return string + */ + public function getPlotType() { + return $this->_plotType; + } + + /** + * Set Plot Type + * + * @param string $plotType * @return PHPExcel_Chart_DataSeries - */ - public function setPlotType($plotType = '') { - $this->_plotType = $plotType; + */ + public function setPlotType($plotType = '') { + $this->_plotType = $plotType; return $this; - } - - /** - * Get Plot Grouping Type - * - * @return string - */ - public function getPlotGrouping() { - return $this->_plotGrouping; - } - - /** - * Set Plot Grouping Type - * - * @param string $groupingType + } + + /** + * Get Plot Grouping Type + * + * @return string + */ + public function getPlotGrouping() { + return $this->_plotGrouping; + } + + /** + * Set Plot Grouping Type + * + * @param string $groupingType * @return PHPExcel_Chart_DataSeries - */ - public function setPlotGrouping($groupingType = null) { - $this->_plotGrouping = $groupingType; + */ + public function setPlotGrouping($groupingType = null) { + $this->_plotGrouping = $groupingType; return $this; - } - - /** - * Get Plot Direction - * - * @return string - */ - public function getPlotDirection() { - return $this->_plotDirection; - } - - /** - * Set Plot Direction - * - * @param string $plotDirection + } + + /** + * Get Plot Direction + * + * @return string + */ + public function getPlotDirection() { + return $this->_plotDirection; + } + + /** + * Set Plot Direction + * + * @param string $plotDirection * @return PHPExcel_Chart_DataSeries - */ - public function setPlotDirection($plotDirection = null) { - $this->_plotDirection = $plotDirection; + */ + public function setPlotDirection($plotDirection = null) { + $this->_plotDirection = $plotDirection; return $this; - } - - /** - * Get Plot Order - * - * @return string - */ - public function getPlotOrder() { - return $this->_plotOrder; - } - - /** - * Get Plot Labels - * - * @return array of PHPExcel_Chart_DataSeriesValues - */ - public function getPlotLabels() { - return $this->_plotLabel; - } - - /** - * Get Plot Label by Index - * - * @return PHPExcel_Chart_DataSeriesValues - */ - public function getPlotLabelByIndex($index) { - $keys = array_keys($this->_plotLabel); - if (in_array($index,$keys)) { - return $this->_plotLabel[$index]; - } elseif(isset($keys[$index])) { - return $this->_plotLabel[$keys[$index]]; - } - return false; - } - - /** - * Get Plot Categories - * - * @return array of PHPExcel_Chart_DataSeriesValues - */ - public function getPlotCategories() { - return $this->_plotCategory; - } - - /** - * Get Plot Category by Index - * - * @return PHPExcel_Chart_DataSeriesValues - */ - public function getPlotCategoryByIndex($index) { - $keys = array_keys($this->_plotCategory); - if (in_array($index,$keys)) { - return $this->_plotCategory[$index]; - } elseif(isset($keys[$index])) { - return $this->_plotCategory[$keys[$index]]; - } - return false; - } - - /** - * Get Plot Style - * - * @return string - */ - public function getPlotStyle() { - return $this->_plotStyle; - } - - /** - * Set Plot Style - * - * @param string $plotStyle + } + + /** + * Get Plot Order + * + * @return string + */ + public function getPlotOrder() { + return $this->_plotOrder; + } + + /** + * Get Plot Labels + * + * @return array of PHPExcel_Chart_DataSeriesValues + */ + public function getPlotLabels() { + return $this->_plotLabel; + } + + /** + * Get Plot Label by Index + * + * @return PHPExcel_Chart_DataSeriesValues + */ + public function getPlotLabelByIndex($index) { + $keys = array_keys($this->_plotLabel); + if (in_array($index,$keys)) { + return $this->_plotLabel[$index]; + } elseif(isset($keys[$index])) { + return $this->_plotLabel[$keys[$index]]; + } + return false; + } + + /** + * Get Plot Categories + * + * @return array of PHPExcel_Chart_DataSeriesValues + */ + public function getPlotCategories() { + return $this->_plotCategory; + } + + /** + * Get Plot Category by Index + * + * @return PHPExcel_Chart_DataSeriesValues + */ + public function getPlotCategoryByIndex($index) { + $keys = array_keys($this->_plotCategory); + if (in_array($index,$keys)) { + return $this->_plotCategory[$index]; + } elseif(isset($keys[$index])) { + return $this->_plotCategory[$keys[$index]]; + } + return false; + } + + /** + * Get Plot Style + * + * @return string + */ + public function getPlotStyle() { + return $this->_plotStyle; + } + + /** + * Set Plot Style + * + * @param string $plotStyle * @return PHPExcel_Chart_DataSeries - */ - public function setPlotStyle($plotStyle = null) { - $this->_plotStyle = $plotStyle; + */ + public function setPlotStyle($plotStyle = null) { + $this->_plotStyle = $plotStyle; return $this; - } - - /** - * Get Plot Values - * - * @return array of PHPExcel_Chart_DataSeriesValues - */ - public function getPlotValues() { - return $this->_plotValues; - } - - /** - * Get Plot Values by Index - * - * @return PHPExcel_Chart_DataSeriesValues - */ - public function getPlotValuesByIndex($index) { - $keys = array_keys($this->_plotValues); - if (in_array($index,$keys)) { - return $this->_plotValues[$index]; - } elseif(isset($keys[$index])) { - return $this->_plotValues[$keys[$index]]; - } - return false; - } - - /** - * Get Number of Plot Series - * - * @return integer - */ - public function getPlotSeriesCount() { - return count($this->_plotValues); - } - - /** - * Get Smooth Line - * - * @return boolean - */ - public function getSmoothLine() { - return $this->_smoothLine; - } - - /** - * Set Smooth Line - * - * @param boolean $smoothLine + } + + /** + * Get Plot Values + * + * @return array of PHPExcel_Chart_DataSeriesValues + */ + public function getPlotValues() { + return $this->_plotValues; + } + + /** + * Get Plot Values by Index + * + * @return PHPExcel_Chart_DataSeriesValues + */ + public function getPlotValuesByIndex($index) { + $keys = array_keys($this->_plotValues); + if (in_array($index,$keys)) { + return $this->_plotValues[$index]; + } elseif(isset($keys[$index])) { + return $this->_plotValues[$keys[$index]]; + } + return false; + } + + /** + * Get Number of Plot Series + * + * @return integer + */ + public function getPlotSeriesCount() { + return count($this->_plotValues); + } + + /** + * Get Smooth Line + * + * @return boolean + */ + public function getSmoothLine() { + return $this->_smoothLine; + } + + /** + * Set Smooth Line + * + * @param boolean $smoothLine * @return PHPExcel_Chart_DataSeries - */ - public function setSmoothLine($smoothLine = TRUE) { - $this->_smoothLine = $smoothLine; + */ + public function setSmoothLine($smoothLine = TRUE) { + $this->_smoothLine = $smoothLine; return $this; - } - - public function refresh(PHPExcel_Worksheet $worksheet) { - foreach($this->_plotValues as $plotValues) { - if ($plotValues !== NULL) - $plotValues->refresh($worksheet, TRUE); - } - foreach($this->_plotLabel as $plotValues) { - if ($plotValues !== NULL) - $plotValues->refresh($worksheet, TRUE); - } - foreach($this->_plotCategory as $plotValues) { - if ($plotValues !== NULL) - $plotValues->refresh($worksheet, FALSE); - } - } + } + + public function refresh(PHPExcel_Worksheet $worksheet) { + foreach($this->_plotValues as $plotValues) { + if ($plotValues !== NULL) + $plotValues->refresh($worksheet, TRUE); + } + foreach($this->_plotLabel as $plotValues) { + if ($plotValues !== NULL) + $plotValues->refresh($worksheet, TRUE); + } + foreach($this->_plotCategory as $plotValues) { + if ($plotValues !== NULL) + $plotValues->refresh($worksheet, FALSE); + } + } } diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index eda73fd6c..a14b47a18 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Chart_DataSeriesValues * * Copyright (c) 2006 - 2015 PHPExcel * @@ -18,310 +19,301 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_Chart_DataSeriesValues - * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Chart + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ class PHPExcel_Chart_DataSeriesValues { - const DATASERIES_TYPE_STRING = 'String'; - const DATASERIES_TYPE_NUMBER = 'Number'; - - private static $_dataTypeValues = array( - self::DATASERIES_TYPE_STRING, - self::DATASERIES_TYPE_NUMBER, - ); - - /** - * Series Data Type - * - * @var string - */ - private $_dataType = null; - - /** - * Series Data Source - * - * @var string - */ - private $_dataSource = null; - - /** - * Format Code - * - * @var string - */ - private $_formatCode = null; - - /** - * Series Point Marker - * - * @var string - */ - private $_marker = null; - - /** - * Point Count (The number of datapoints in the dataseries) - * - * @var integer - */ - private $_pointCount = 0; - - /** - * Data Values - * - * @var array of mixed - */ - private $_dataValues = array(); - - /** - * Create a new PHPExcel_Chart_DataSeriesValues object - */ - public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSource = null, $formatCode = null, $pointCount = 0, $dataValues = array(), $marker = null) - { - $this->setDataType($dataType); - $this->_dataSource = $dataSource; - $this->_formatCode = $formatCode; - $this->_pointCount = $pointCount; - $this->_dataValues = $dataValues; - $this->_marker = $marker; - } - - /** - * Get Series Data Type - * - * @return string - */ - public function getDataType() { - return $this->_dataType; - } - - /** - * Set Series Data Type - * - * @param string $dataType Datatype of this data series - * Typical values are: - * PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_STRING - * Normally used for axis point values - * PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_NUMBER - * Normally used for chart data values - * @return PHPExcel_Chart_DataSeriesValues - */ - public function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) { - if (!in_array($dataType, self::$_dataTypeValues)) { - throw new PHPExcel_Chart_Exception('Invalid datatype for chart data series values'); - } - $this->_dataType = $dataType; - - return $this; - } - - /** - * Get Series Data Source (formula) - * - * @return string - */ - public function getDataSource() { - return $this->_dataSource; - } - - /** - * Set Series Data Source (formula) - * - * @param string $dataSource - * @return PHPExcel_Chart_DataSeriesValues - */ - public function setDataSource($dataSource = null, $refreshDataValues = true) { - $this->_dataSource = $dataSource; - - if ($refreshDataValues) { - // TO DO - } - - return $this; - } - - /** - * Get Point Marker - * - * @return string - */ - public function getPointMarker() { - return $this->_marker; - } - - /** - * Set Point Marker - * - * @param string $marker - * @return PHPExcel_Chart_DataSeriesValues - */ - public function setPointMarker($marker = null) { - $this->_marker = $marker; - - return $this; - } - - /** - * Get Series Format Code - * - * @return string - */ - public function getFormatCode() { - return $this->_formatCode; - } - - /** - * Set Series Format Code - * - * @param string $formatCode - * @return PHPExcel_Chart_DataSeriesValues - */ - public function setFormatCode($formatCode = null) { - $this->_formatCode = $formatCode; - - return $this; - } - - /** - * Get Series Point Count - * - * @return integer - */ - public function getPointCount() { - return $this->_pointCount; - } - - /** - * Identify if the Data Series is a multi-level or a simple series - * - * @return boolean - */ - public function isMultiLevelSeries() { - if (count($this->_dataValues) > 0) { - return is_array($this->_dataValues[0]); - } - return null; - } - - /** - * Return the level count of a multi-level Data Series - * - * @return boolean - */ - public function multiLevelCount() { - $levelCount = 0; - foreach($this->_dataValues as $dataValueSet) { - $levelCount = max($levelCount,count($dataValueSet)); - } - return $levelCount; - } - - /** - * Get Series Data Values - * - * @return array of mixed - */ - public function getDataValues() { - return $this->_dataValues; - } - - /** - * Get the first Series Data value - * - * @return mixed - */ - public function getDataValue() { - $count = count($this->_dataValues); - if ($count == 0) { - return null; - } elseif ($count == 1) { - return $this->_dataValues[0]; - } - return $this->_dataValues; - } - - /** - * Set Series Data Values - * - * @param array $dataValues - * @param boolean $refreshDataSource - * TRUE - refresh the value of _dataSource based on the values of $dataValues - * FALSE - don't change the value of _dataSource - * @return PHPExcel_Chart_DataSeriesValues - */ - public function setDataValues($dataValues = array(), $refreshDataSource = TRUE) { - $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($dataValues); - $this->_pointCount = count($dataValues); - - if ($refreshDataSource) { - // TO DO - } - - return $this; - } - - private function _stripNulls($var) { - return $var !== NULL; - } - - public function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) { + const DATASERIES_TYPE_STRING = 'String'; + const DATASERIES_TYPE_NUMBER = 'Number'; + + private static $_dataTypeValues = array( + self::DATASERIES_TYPE_STRING, + self::DATASERIES_TYPE_NUMBER, + ); + + /** + * Series Data Type + * + * @var string + */ + private $_dataType = null; + + /** + * Series Data Source + * + * @var string + */ + private $_dataSource = null; + + /** + * Format Code + * + * @var string + */ + private $_formatCode = null; + + /** + * Series Point Marker + * + * @var string + */ + private $_marker = null; + + /** + * Point Count (The number of datapoints in the dataseries) + * + * @var integer + */ + private $_pointCount = 0; + + /** + * Data Values + * + * @var array of mixed + */ + private $_dataValues = array(); + + /** + * Create a new PHPExcel_Chart_DataSeriesValues object + */ + public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSource = null, $formatCode = null, $pointCount = 0, $dataValues = array(), $marker = null) + { + $this->setDataType($dataType); + $this->_dataSource = $dataSource; + $this->_formatCode = $formatCode; + $this->_pointCount = $pointCount; + $this->_dataValues = $dataValues; + $this->_marker = $marker; + } + + /** + * Get Series Data Type + * + * @return string + */ + public function getDataType() { + return $this->_dataType; + } + + /** + * Set Series Data Type + * + * @param string $dataType Datatype of this data series + * Typical values are: + * PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_STRING + * Normally used for axis point values + * PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_NUMBER + * Normally used for chart data values + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) { + if (!in_array($dataType, self::$_dataTypeValues)) { + throw new PHPExcel_Chart_Exception('Invalid datatype for chart data series values'); + } + $this->_dataType = $dataType; + + return $this; + } + + /** + * Get Series Data Source (formula) + * + * @return string + */ + public function getDataSource() { + return $this->_dataSource; + } + + /** + * Set Series Data Source (formula) + * + * @param string $dataSource + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setDataSource($dataSource = null, $refreshDataValues = true) { + $this->_dataSource = $dataSource; + + if ($refreshDataValues) { + // TO DO + } + + return $this; + } + + /** + * Get Point Marker + * + * @return string + */ + public function getPointMarker() { + return $this->_marker; + } + + /** + * Set Point Marker + * + * @param string $marker + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setPointMarker($marker = null) { + $this->_marker = $marker; + + return $this; + } + + /** + * Get Series Format Code + * + * @return string + */ + public function getFormatCode() { + return $this->_formatCode; + } + + /** + * Set Series Format Code + * + * @param string $formatCode + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setFormatCode($formatCode = null) { + $this->_formatCode = $formatCode; + + return $this; + } + + /** + * Get Series Point Count + * + * @return integer + */ + public function getPointCount() { + return $this->_pointCount; + } + + /** + * Identify if the Data Series is a multi-level or a simple series + * + * @return boolean + */ + public function isMultiLevelSeries() { + if (count($this->_dataValues) > 0) { + return is_array($this->_dataValues[0]); + } + return null; + } + + /** + * Return the level count of a multi-level Data Series + * + * @return boolean + */ + public function multiLevelCount() { + $levelCount = 0; + foreach($this->_dataValues as $dataValueSet) { + $levelCount = max($levelCount,count($dataValueSet)); + } + return $levelCount; + } + + /** + * Get Series Data Values + * + * @return array of mixed + */ + public function getDataValues() { + return $this->_dataValues; + } + + /** + * Get the first Series Data value + * + * @return mixed + */ + public function getDataValue() { + $count = count($this->_dataValues); + if ($count == 0) { + return null; + } elseif ($count == 1) { + return $this->_dataValues[0]; + } + return $this->_dataValues; + } + + /** + * Set Series Data Values + * + * @param array $dataValues + * @param boolean $refreshDataSource + * TRUE - refresh the value of _dataSource based on the values of $dataValues + * FALSE - don't change the value of _dataSource + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setDataValues($dataValues = array(), $refreshDataSource = TRUE) { + $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($dataValues); + $this->_pointCount = count($dataValues); + + if ($refreshDataSource) { + // TO DO + } + + return $this; + } + + private function _stripNulls($var) { + return $var !== NULL; + } + + public function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) { if ($this->_dataSource !== NULL) { - $calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent()); - $newDataValues = PHPExcel_Calculation::_unwrapResult( - $calcEngine->_calculateFormulaValue( - '='.$this->_dataSource, - NULL, - $worksheet->getCell('A1') - ) - ); - if ($flatten) { - $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); - foreach($this->_dataValues as &$dataValue) { - if ((!empty($dataValue)) && ($dataValue[0] == '#')) { - $dataValue = 0.0; - } - } - unset($dataValue); - } else { - $cellRange = explode('!',$this->_dataSource); - if (count($cellRange) > 1) { - list(,$cellRange) = $cellRange; - } - - $dimensions = PHPExcel_Cell::rangeDimension(str_replace('$','',$cellRange)); - if (($dimensions[0] == 1) || ($dimensions[1] == 1)) { - $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); - } else { - $newArray = array_values(array_shift($newDataValues)); - foreach($newArray as $i => $newDataSet) { - $newArray[$i] = array($newDataSet); - } - - foreach($newDataValues as $newDataSet) { - $i = 0; - foreach($newDataSet as $newDataVal) { - array_unshift($newArray[$i++],$newDataVal); - } - } - $this->_dataValues = $newArray; - } - } - $this->_pointCount = count($this->_dataValues); - } - - } + $calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent()); + $newDataValues = PHPExcel_Calculation::_unwrapResult( + $calcEngine->_calculateFormulaValue( + '='.$this->_dataSource, + NULL, + $worksheet->getCell('A1') + ) + ); + if ($flatten) { + $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); + foreach($this->_dataValues as &$dataValue) { + if ((!empty($dataValue)) && ($dataValue[0] == '#')) { + $dataValue = 0.0; + } + } + unset($dataValue); + } else { + $cellRange = explode('!',$this->_dataSource); + if (count($cellRange) > 1) { + list(,$cellRange) = $cellRange; + } + + $dimensions = PHPExcel_Cell::rangeDimension(str_replace('$','',$cellRange)); + if (($dimensions[0] == 1) || ($dimensions[1] == 1)) { + $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); + } else { + $newArray = array_values(array_shift($newDataValues)); + foreach($newArray as $i => $newDataSet) { + $newArray[$i] = array($newDataSet); + } + + foreach($newDataValues as $newDataSet) { + $i = 0; + foreach($newDataSet as $newDataVal) { + array_unshift($newArray[$i++],$newDataVal); + } + } + $this->_dataValues = $newArray; + } + } + $this->_pointCount = count($this->_dataValues); + } + + } } diff --git a/Classes/PHPExcel/Chart/Exception.php b/Classes/PHPExcel/Chart/Exception.php index 4b5514fcb..e20dfa590 100644 --- a/Classes/PHPExcel/Chart/Exception.php +++ b/Classes/PHPExcel/Chart/Exception.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Chart_Exception * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,32 +22,25 @@ * @category PHPExcel * @package PHPExcel_Chart * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_Chart_Exception - * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ -class PHPExcel_Chart_Exception extends PHPExcel_Exception { - /** - * Error handler callback - * - * @param mixed $code - * @param mixed $string - * @param mixed $file - * @param mixed $line - * @param mixed $context - */ - public static function errorHandlerCallback($code, $string, $file, $line, $context) { - $e = new self($string, $code); - $e->line = $line; - $e->file = $file; - throw $e; - } +class PHPExcel_Chart_Exception extends PHPExcel_Exception +{ + /** + * Error handler callback + * + * @param mixed $code + * @param mixed $string + * @param mixed $file + * @param mixed $line + * @param mixed $context + */ + public static function errorHandlerCallback($code, $string, $file, $line, $context) + { + $e = new self($string, $code); + $e->line = $line; + $e->file = $file; + throw $e; + } } diff --git a/Classes/PHPExcel/Chart/Layout.php b/Classes/PHPExcel/Chart/Layout.php index cb55b2d0b..d524e224f 100644 --- a/Classes/PHPExcel/Chart/Layout.php +++ b/Classes/PHPExcel/Chart/Layout.php @@ -18,428 +18,428 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Chart + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** * PHPExcel_Chart_Layout * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Chart + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Layout { - /** - * layoutTarget - * - * @var string - */ - private $_layoutTarget = NULL; - - /** - * X Mode - * - * @var string - */ - private $_xMode = NULL; - - /** - * Y Mode - * - * @var string - */ - private $_yMode = NULL; - - /** - * X-Position - * - * @var float - */ - private $_xPos = NULL; - - /** - * Y-Position - * - * @var float - */ - private $_yPos = NULL; - - /** - * width - * - * @var float - */ - private $_width = NULL; - - /** - * height - * - * @var float - */ - private $_height = NULL; - - /** - * show legend key - * Specifies that legend keys should be shown in data labels - * - * @var boolean - */ - private $_showLegendKey = NULL; - - /** - * show value - * Specifies that the value should be shown in a data label. - * - * @var boolean - */ - private $_showVal = NULL; - - /** - * show category name - * Specifies that the category name should be shown in the data label. - * - * @var boolean - */ - private $_showCatName = NULL; - - /** - * show data series name - * Specifies that the series name should be shown in the data label. - * - * @var boolean - */ - private $_showSerName = NULL; - - /** - * show percentage - * Specifies that the percentage should be shown in the data label. - * - * @var boolean - */ - private $_showPercent = NULL; - - /** - * show bubble size - * - * @var boolean - */ - private $_showBubbleSize = NULL; - - /** - * show leader lines - * Specifies that leader lines should be shown for the data label. - * - * @var boolean - */ - private $_showLeaderLines = NULL; - - - /** - * Create a new PHPExcel_Chart_Layout - */ - public function __construct($layout=array()) - { - if (isset($layout['layoutTarget'])) { $this->_layoutTarget = $layout['layoutTarget']; } - if (isset($layout['xMode'])) { $this->_xMode = $layout['xMode']; } - if (isset($layout['yMode'])) { $this->_yMode = $layout['yMode']; } - if (isset($layout['x'])) { $this->_xPos = (float) $layout['x']; } - if (isset($layout['y'])) { $this->_yPos = (float) $layout['y']; } - if (isset($layout['w'])) { $this->_width = (float) $layout['w']; } - if (isset($layout['h'])) { $this->_height = (float) $layout['h']; } - } - - /** - * Get Layout Target - * - * @return string - */ - public function getLayoutTarget() { - return $this->_layoutTarget; - } - - /** - * Set Layout Target - * - * @param Layout Target $value + /** + * layoutTarget + * + * @var string + */ + private $_layoutTarget = NULL; + + /** + * X Mode + * + * @var string + */ + private $_xMode = NULL; + + /** + * Y Mode + * + * @var string + */ + private $_yMode = NULL; + + /** + * X-Position + * + * @var float + */ + private $_xPos = NULL; + + /** + * Y-Position + * + * @var float + */ + private $_yPos = NULL; + + /** + * width + * + * @var float + */ + private $_width = NULL; + + /** + * height + * + * @var float + */ + private $_height = NULL; + + /** + * show legend key + * Specifies that legend keys should be shown in data labels + * + * @var boolean + */ + private $_showLegendKey = NULL; + + /** + * show value + * Specifies that the value should be shown in a data label. + * + * @var boolean + */ + private $_showVal = NULL; + + /** + * show category name + * Specifies that the category name should be shown in the data label. + * + * @var boolean + */ + private $_showCatName = NULL; + + /** + * show data series name + * Specifies that the series name should be shown in the data label. + * + * @var boolean + */ + private $_showSerName = NULL; + + /** + * show percentage + * Specifies that the percentage should be shown in the data label. + * + * @var boolean + */ + private $_showPercent = NULL; + + /** + * show bubble size + * + * @var boolean + */ + private $_showBubbleSize = NULL; + + /** + * show leader lines + * Specifies that leader lines should be shown for the data label. + * + * @var boolean + */ + private $_showLeaderLines = NULL; + + + /** + * Create a new PHPExcel_Chart_Layout + */ + public function __construct($layout=array()) + { + if (isset($layout['layoutTarget'])) { $this->_layoutTarget = $layout['layoutTarget']; } + if (isset($layout['xMode'])) { $this->_xMode = $layout['xMode']; } + if (isset($layout['yMode'])) { $this->_yMode = $layout['yMode']; } + if (isset($layout['x'])) { $this->_xPos = (float) $layout['x']; } + if (isset($layout['y'])) { $this->_yPos = (float) $layout['y']; } + if (isset($layout['w'])) { $this->_width = (float) $layout['w']; } + if (isset($layout['h'])) { $this->_height = (float) $layout['h']; } + } + + /** + * Get Layout Target + * + * @return string + */ + public function getLayoutTarget() { + return $this->_layoutTarget; + } + + /** + * Set Layout Target + * + * @param Layout Target $value * @return PHPExcel_Chart_Layout - */ - public function setLayoutTarget($value) { - $this->_layoutTarget = $value; + */ + public function setLayoutTarget($value) { + $this->_layoutTarget = $value; return $this; - } - - /** - * Get X-Mode - * - * @return string - */ - public function getXMode() { - return $this->_xMode; - } - - /** - * Set X-Mode - * - * @param X-Mode $value + } + + /** + * Get X-Mode + * + * @return string + */ + public function getXMode() { + return $this->_xMode; + } + + /** + * Set X-Mode + * + * @param X-Mode $value * @return PHPExcel_Chart_Layout - */ - public function setXMode($value) { - $this->_xMode = $value; + */ + public function setXMode($value) { + $this->_xMode = $value; return $this; - } - - /** - * Get Y-Mode - * - * @return string - */ - public function getYMode() { - return $this->_yMode; - } - - /** - * Set Y-Mode - * - * @param Y-Mode $value + } + + /** + * Get Y-Mode + * + * @return string + */ + public function getYMode() { + return $this->_yMode; + } + + /** + * Set Y-Mode + * + * @param Y-Mode $value * @return PHPExcel_Chart_Layout - */ - public function setYMode($value) { - $this->_yMode = $value; + */ + public function setYMode($value) { + $this->_yMode = $value; return $this; - } - - /** - * Get X-Position - * - * @return number - */ - public function getXPosition() { - return $this->_xPos; - } - - /** - * Set X-Position - * - * @param X-Position $value + } + + /** + * Get X-Position + * + * @return number + */ + public function getXPosition() { + return $this->_xPos; + } + + /** + * Set X-Position + * + * @param X-Position $value * @return PHPExcel_Chart_Layout - */ - public function setXPosition($value) { - $this->_xPos = $value; + */ + public function setXPosition($value) { + $this->_xPos = $value; return $this; - } - - /** - * Get Y-Position - * - * @return number - */ - public function getYPosition() { - return $this->_yPos; - } - - /** - * Set Y-Position - * - * @param Y-Position $value + } + + /** + * Get Y-Position + * + * @return number + */ + public function getYPosition() { + return $this->_yPos; + } + + /** + * Set Y-Position + * + * @param Y-Position $value * @return PHPExcel_Chart_Layout - */ - public function setYPosition($value) { - $this->_yPos = $value; + */ + public function setYPosition($value) { + $this->_yPos = $value; return $this; - } - - /** - * Get Width - * - * @return number - */ - public function getWidth() { - return $this->_width; - } - - /** - * Set Width - * - * @param Width $value + } + + /** + * Get Width + * + * @return number + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set Width + * + * @param Width $value * @return PHPExcel_Chart_Layout - */ - public function setWidth($value) { - $this->_width = $value; + */ + public function setWidth($value) { + $this->_width = $value; return $this; - } - - /** - * Get Height - * - * @return number - */ - public function getHeight() { - return $this->_height; - } - - /** - * Set Height - * - * @param Height $value + } + + /** + * Get Height + * + * @return number + */ + public function getHeight() { + return $this->_height; + } + + /** + * Set Height + * + * @param Height $value * @return PHPExcel_Chart_Layout - */ - public function setHeight($value) { - $this->_height = $value; + */ + public function setHeight($value) { + $this->_height = $value; return $this; - } - - - /** - * Get show legend key - * - * @return boolean - */ - public function getShowLegendKey() { - return $this->_showLegendKey; - } - - /** - * Set show legend key - * Specifies that legend keys should be shown in data labels. - * - * @param boolean $value Show legend key + } + + + /** + * Get show legend key + * + * @return boolean + */ + public function getShowLegendKey() { + return $this->_showLegendKey; + } + + /** + * Set show legend key + * Specifies that legend keys should be shown in data labels. + * + * @param boolean $value Show legend key * @return PHPExcel_Chart_Layout - */ - public function setShowLegendKey($value) { - $this->_showLegendKey = $value; + */ + public function setShowLegendKey($value) { + $this->_showLegendKey = $value; return $this; - } - - /** - * Get show value - * - * @return boolean - */ - public function getShowVal() { - return $this->_showVal; - } - - /** - * Set show val - * Specifies that the value should be shown in data labels. - * - * @param boolean $value Show val + } + + /** + * Get show value + * + * @return boolean + */ + public function getShowVal() { + return $this->_showVal; + } + + /** + * Set show val + * Specifies that the value should be shown in data labels. + * + * @param boolean $value Show val * @return PHPExcel_Chart_Layout - */ - public function setShowVal($value) { - $this->_showVal = $value; + */ + public function setShowVal($value) { + $this->_showVal = $value; return $this; - } - - /** - * Get show category name - * - * @return boolean - */ - public function getShowCatName() { - return $this->_showCatName; - } - - /** - * Set show cat name - * Specifies that the category name should be shown in data labels. - * - * @param boolean $value Show cat name + } + + /** + * Get show category name + * + * @return boolean + */ + public function getShowCatName() { + return $this->_showCatName; + } + + /** + * Set show cat name + * Specifies that the category name should be shown in data labels. + * + * @param boolean $value Show cat name * @return PHPExcel_Chart_Layout - */ - public function setShowCatName($value) { - $this->_showCatName = $value; + */ + public function setShowCatName($value) { + $this->_showCatName = $value; return $this; - } - - /** - * Get show data series name - * - * @return boolean - */ - public function getShowSerName() { - return $this->_showSerName; - } - - /** - * Set show ser name - * Specifies that the series name should be shown in data labels. - * - * @param boolean $value Show series name + } + + /** + * Get show data series name + * + * @return boolean + */ + public function getShowSerName() { + return $this->_showSerName; + } + + /** + * Set show ser name + * Specifies that the series name should be shown in data labels. + * + * @param boolean $value Show series name * @return PHPExcel_Chart_Layout - */ - public function setShowSerName($value) { - $this->_showSerName = $value; + */ + public function setShowSerName($value) { + $this->_showSerName = $value; return $this; - } - - /** - * Get show percentage - * - * @return boolean - */ - public function getShowPercent() { - return $this->_showPercent; - } - - /** - * Set show percentage - * Specifies that the percentage should be shown in data labels. - * - * @param boolean $value Show percentage + } + + /** + * Get show percentage + * + * @return boolean + */ + public function getShowPercent() { + return $this->_showPercent; + } + + /** + * Set show percentage + * Specifies that the percentage should be shown in data labels. + * + * @param boolean $value Show percentage * @return PHPExcel_Chart_Layout - */ - public function setShowPercent($value) { - $this->_showPercent = $value; + */ + public function setShowPercent($value) { + $this->_showPercent = $value; return $this; - } - - /** - * Get show bubble size - * - * @return boolean - */ - public function getShowBubbleSize() { - return $this->_showBubbleSize; - } - - /** - * Set show bubble size - * Specifies that the bubble size should be shown in data labels. - * - * @param boolean $value Show bubble size + } + + /** + * Get show bubble size + * + * @return boolean + */ + public function getShowBubbleSize() { + return $this->_showBubbleSize; + } + + /** + * Set show bubble size + * Specifies that the bubble size should be shown in data labels. + * + * @param boolean $value Show bubble size * @return PHPExcel_Chart_Layout - */ - public function setShowBubbleSize($value) { - $this->_showBubbleSize = $value; + */ + public function setShowBubbleSize($value) { + $this->_showBubbleSize = $value; return $this; - } - - /** - * Get show leader lines - * - * @return boolean - */ - public function getShowLeaderLines() { - return $this->_showLeaderLines; - } - - /** - * Set show leader lines - * Specifies that leader lines should be shown in data labels. - * - * @param boolean $value Show leader lines + } + + /** + * Get show leader lines + * + * @return boolean + */ + public function getShowLeaderLines() { + return $this->_showLeaderLines; + } + + /** + * Set show leader lines + * Specifies that leader lines should be shown in data labels. + * + * @param boolean $value Show leader lines * @return PHPExcel_Chart_Layout - */ - public function setShowLeaderLines($value) { - $this->_showLeaderLines = $value; + */ + public function setShowLeaderLines($value) { + $this->_showLeaderLines = $value; return $this; - } + } } diff --git a/Classes/PHPExcel/Chart/Legend.php b/Classes/PHPExcel/Chart/Legend.php index 5a61e6017..c44003bd0 100644 --- a/Classes/PHPExcel/Chart/Legend.php +++ b/Classes/PHPExcel/Chart/Legend.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Chart_Legend * * Copyright (c) 2006 - 2015 PHPExcel * @@ -18,154 +19,146 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_Chart_Legend - * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Chart + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ class PHPExcel_Chart_Legend { - /** Legend positions */ - const xlLegendPositionBottom = -4107; // Below the chart. - const xlLegendPositionCorner = 2; // In the upper right-hand corner of the chart border. - const xlLegendPositionCustom = -4161; // A custom position. - const xlLegendPositionLeft = -4131; // Left of the chart. - const xlLegendPositionRight = -4152; // Right of the chart. - const xlLegendPositionTop = -4160; // Above the chart. - - const POSITION_RIGHT = 'r'; - const POSITION_LEFT = 'l'; - const POSITION_BOTTOM = 'b'; - const POSITION_TOP = 't'; - const POSITION_TOPRIGHT = 'tr'; - - private static $_positionXLref = array( self::xlLegendPositionBottom => self::POSITION_BOTTOM, - self::xlLegendPositionCorner => self::POSITION_TOPRIGHT, - self::xlLegendPositionCustom => '??', - self::xlLegendPositionLeft => self::POSITION_LEFT, - self::xlLegendPositionRight => self::POSITION_RIGHT, - self::xlLegendPositionTop => self::POSITION_TOP - ); - - /** - * Legend position - * - * @var string - */ - private $_position = self::POSITION_RIGHT; - - /** - * Allow overlay of other elements? - * - * @var boolean - */ - private $_overlay = TRUE; - - /** - * Legend Layout - * - * @var PHPExcel_Chart_Layout - */ - private $_layout = NULL; - - - /** - * Create a new PHPExcel_Chart_Legend - */ - public function __construct($position = self::POSITION_RIGHT, PHPExcel_Chart_Layout $layout = NULL, $overlay = FALSE) - { - $this->setPosition($position); - $this->_layout = $layout; - $this->setOverlay($overlay); - } - - /** - * Get legend position as an excel string value - * - * @return string - */ - public function getPosition() { - return $this->_position; - } - - /** - * Get legend position using an excel string value - * - * @param string $position - */ - public function setPosition($position = self::POSITION_RIGHT) { - if (!in_array($position,self::$_positionXLref)) { - return false; - } - - $this->_position = $position; - return true; - } - - /** - * Get legend position as an Excel internal numeric value - * - * @return number - */ - public function getPositionXL() { - return array_search($this->_position,self::$_positionXLref); - } - - /** - * Set legend position using an Excel internal numeric value - * - * @param number $positionXL - */ - public function setPositionXL($positionXL = self::xlLegendPositionRight) { - if (!array_key_exists($positionXL,self::$_positionXLref)) { - return false; - } - - $this->_position = self::$_positionXLref[$positionXL]; - return true; - } - - /** - * Get allow overlay of other elements? - * - * @return boolean - */ - public function getOverlay() { - return $this->_overlay; - } - - /** - * Set allow overlay of other elements? - * - * @param boolean $overlay - * @return boolean - */ - public function setOverlay($overlay = FALSE) { - if (!is_bool($overlay)) { - return false; - } - - $this->_overlay = $overlay; - return true; - } - - /** - * Get Layout - * - * @return PHPExcel_Chart_Layout - */ - public function getLayout() { - return $this->_layout; - } + /** Legend positions */ + const xlLegendPositionBottom = -4107; // Below the chart. + const xlLegendPositionCorner = 2; // In the upper right-hand corner of the chart border. + const xlLegendPositionCustom = -4161; // A custom position. + const xlLegendPositionLeft = -4131; // Left of the chart. + const xlLegendPositionRight = -4152; // Right of the chart. + const xlLegendPositionTop = -4160; // Above the chart. + + const POSITION_RIGHT = 'r'; + const POSITION_LEFT = 'l'; + const POSITION_BOTTOM = 'b'; + const POSITION_TOP = 't'; + const POSITION_TOPRIGHT = 'tr'; + + private static $_positionXLref = array( + self::xlLegendPositionBottom => self::POSITION_BOTTOM, + self::xlLegendPositionCorner => self::POSITION_TOPRIGHT, + self::xlLegendPositionCustom => '??', + self::xlLegendPositionLeft => self::POSITION_LEFT, + self::xlLegendPositionRight => self::POSITION_RIGHT, + self::xlLegendPositionTop => self::POSITION_TOP + ); + + /** + * Legend position + * + * @var string + */ + private $_position = self::POSITION_RIGHT; + + /** + * Allow overlay of other elements? + * + * @var boolean + */ + private $_overlay = TRUE; + + /** + * Legend Layout + * + * @var PHPExcel_Chart_Layout + */ + private $_layout = NULL; + + + /** + * Create a new PHPExcel_Chart_Legend + */ + public function __construct($position = self::POSITION_RIGHT, PHPExcel_Chart_Layout $layout = NULL, $overlay = FALSE) + { + $this->setPosition($position); + $this->_layout = $layout; + $this->setOverlay($overlay); + } + + /** + * Get legend position as an excel string value + * + * @return string + */ + public function getPosition() { + return $this->_position; + } + + /** + * Get legend position using an excel string value + * + * @param string $position + */ + public function setPosition($position = self::POSITION_RIGHT) { + if (!in_array($position,self::$_positionXLref)) { + return false; + } + + $this->_position = $position; + return true; + } + + /** + * Get legend position as an Excel internal numeric value + * + * @return number + */ + public function getPositionXL() { + return array_search($this->_position,self::$_positionXLref); + } + + /** + * Set legend position using an Excel internal numeric value + * + * @param number $positionXL + */ + public function setPositionXL($positionXL = self::xlLegendPositionRight) { + if (!array_key_exists($positionXL,self::$_positionXLref)) { + return false; + } + + $this->_position = self::$_positionXLref[$positionXL]; + return true; + } + + /** + * Get allow overlay of other elements? + * + * @return boolean + */ + public function getOverlay() { + return $this->_overlay; + } + + /** + * Set allow overlay of other elements? + * + * @param boolean $overlay + * @return boolean + */ + public function setOverlay($overlay = FALSE) { + if (!is_bool($overlay)) { + return false; + } + + $this->_overlay = $overlay; + return true; + } + + /** + * Get Layout + * + * @return PHPExcel_Chart_Layout + */ + public function getLayout() { + return $this->_layout; + } } diff --git a/Classes/PHPExcel/Chart/PlotArea.php b/Classes/PHPExcel/Chart/PlotArea.php index a055ae648..657fe9813 100644 --- a/Classes/PHPExcel/Chart/PlotArea.php +++ b/Classes/PHPExcel/Chart/PlotArea.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Chart_PlotArea * * Copyright (c) 2006 - 2015 PHPExcel * @@ -18,111 +19,102 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_Chart_PlotArea - * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Chart + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ class PHPExcel_Chart_PlotArea { - /** - * PlotArea Layout - * - * @var PHPExcel_Chart_Layout - */ - private $_layout = null; + /** + * PlotArea Layout + * + * @var PHPExcel_Chart_Layout + */ + private $_layout = null; - /** - * Plot Series - * - * @var array of PHPExcel_Chart_DataSeries - */ - private $_plotSeries = array(); + /** + * Plot Series + * + * @var array of PHPExcel_Chart_DataSeries + */ + private $_plotSeries = array(); - /** - * Create a new PHPExcel_Chart_PlotArea - */ - public function __construct(PHPExcel_Chart_Layout $layout = null, $plotSeries = array()) - { - $this->_layout = $layout; - $this->_plotSeries = $plotSeries; - } + /** + * Create a new PHPExcel_Chart_PlotArea + */ + public function __construct(PHPExcel_Chart_Layout $layout = null, $plotSeries = array()) + { + $this->_layout = $layout; + $this->_plotSeries = $plotSeries; + } - /** - * Get Layout - * - * @return PHPExcel_Chart_Layout - */ - public function getLayout() { - return $this->_layout; - } + /** + * Get Layout + * + * @return PHPExcel_Chart_Layout + */ + public function getLayout() { + return $this->_layout; + } - /** - * Get Number of Plot Groups - * - * @return array of PHPExcel_Chart_DataSeries - */ - public function getPlotGroupCount() { - return count($this->_plotSeries); - } + /** + * Get Number of Plot Groups + * + * @return array of PHPExcel_Chart_DataSeries + */ + public function getPlotGroupCount() { + return count($this->_plotSeries); + } - /** - * Get Number of Plot Series - * - * @return integer - */ - public function getPlotSeriesCount() { - $seriesCount = 0; - foreach($this->_plotSeries as $plot) { - $seriesCount += $plot->getPlotSeriesCount(); - } - return $seriesCount; - } + /** + * Get Number of Plot Series + * + * @return integer + */ + public function getPlotSeriesCount() { + $seriesCount = 0; + foreach($this->_plotSeries as $plot) { + $seriesCount += $plot->getPlotSeriesCount(); + } + return $seriesCount; + } - /** - * Get Plot Series - * - * @return array of PHPExcel_Chart_DataSeries - */ - public function getPlotGroup() { - return $this->_plotSeries; - } + /** + * Get Plot Series + * + * @return array of PHPExcel_Chart_DataSeries + */ + public function getPlotGroup() { + return $this->_plotSeries; + } - /** - * Get Plot Series by Index - * - * @return PHPExcel_Chart_DataSeries - */ - public function getPlotGroupByIndex($index) { - return $this->_plotSeries[$index]; - } + /** + * Get Plot Series by Index + * + * @return PHPExcel_Chart_DataSeries + */ + public function getPlotGroupByIndex($index) { + return $this->_plotSeries[$index]; + } - /** - * Set Plot Series - * - * @param [PHPExcel_Chart_DataSeries] + /** + * Set Plot Series + * + * @param [PHPExcel_Chart_DataSeries] * @return PHPExcel_Chart_PlotArea - */ - public function setPlotSeries($plotSeries = array()) { - $this->_plotSeries = $plotSeries; + */ + public function setPlotSeries($plotSeries = array()) { + $this->_plotSeries = $plotSeries; return $this; - } + } - public function refresh(PHPExcel_Worksheet $worksheet) { - foreach($this->_plotSeries as $plotSeries) { - $plotSeries->refresh($worksheet); - } - } + public function refresh(PHPExcel_Worksheet $worksheet) { + foreach($this->_plotSeries as $plotSeries) { + $plotSeries->refresh($worksheet); + } + } } diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index ec1fb2524..5994db37b 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -19,11 +19,11 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Chart_Renderer - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Chart_Renderer + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ @@ -33,823 +33,823 @@ /** * PHPExcel_Chart_Renderer_jpgraph * - * @category PHPExcel - * @package PHPExcel_Chart_Renderer - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Chart_Renderer + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Renderer_jpgraph { - private static $_width = 640; - - private static $_height = 480; - - private static $_colourSet = array( 'mediumpurple1', 'palegreen3', 'gold1', 'cadetblue1', - 'darkmagenta', 'coral', 'dodgerblue3', 'eggplant', - 'mediumblue', 'magenta', 'sandybrown', 'cyan', - 'firebrick1', 'forestgreen', 'deeppink4', 'darkolivegreen', - 'goldenrod2' - ); - - private static $_markSet = array( 'diamond' => MARK_DIAMOND, - 'square' => MARK_SQUARE, - 'triangle' => MARK_UTRIANGLE, - 'x' => MARK_X, - 'star' => MARK_STAR, - 'dot' => MARK_FILLEDCIRCLE, - 'dash' => MARK_DTRIANGLE, - 'circle' => MARK_CIRCLE, - 'plus' => MARK_CROSS - ); - - - private $_chart = null; - - private $_graph = null; - - private static $_plotColour = 0; - - private static $_plotMark = 0; - - - private function _formatPointMarker($seriesPlot,$markerID) { - $plotMarkKeys = array_keys(self::$_markSet); - if (is_null($markerID)) { - // Use default plot marker (next marker in the series) - self::$_plotMark %= count(self::$_markSet); - $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]); - } elseif ($markerID !== 'none') { - // Use specified plot marker (if it exists) - if (isset(self::$_markSet[$markerID])) { - $seriesPlot->mark->SetType(self::$_markSet[$markerID]); - } else { - // If the specified plot marker doesn't exist, use default plot marker (next marker in the series) - self::$_plotMark %= count(self::$_markSet); - $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]); - } - } else { - // Hide plot marker - $seriesPlot->mark->Hide(); - } - $seriesPlot->mark->SetColor(self::$_colourSet[self::$_plotColour]); - $seriesPlot->mark->SetFillColor(self::$_colourSet[self::$_plotColour]); - $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); - - return $seriesPlot; - } // function _formatPointMarker() - - - private function _formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') { - $datasetLabelFormatCode = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); - if (!is_null($datasetLabelFormatCode)) { - // Retrieve any label formatting code - $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); - } - - $testCurrentIndex = 0; - foreach($datasetLabels as $i => $datasetLabel) { - if (is_array($datasetLabel)) { - if ($rotation == 'bar') { - $datasetLabels[$i] = implode(" ",$datasetLabel); - } else { - $datasetLabel = array_reverse($datasetLabel); - $datasetLabels[$i] = implode("\n",$datasetLabel); - } - } else { - // Format labels according to any formatting code - if (!is_null($datasetLabelFormatCode)) { - $datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel,$datasetLabelFormatCode); - } - } - ++$testCurrentIndex; - } - - return $datasetLabels; - } // function _formatDataSetLabels() - - - private function _percentageSumCalculation($groupID,$seriesCount) { - // Adjust our values to a percentage value across all series in the group - for($i = 0; $i < $seriesCount; ++$i) { - if ($i == 0) { - $sumValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - } else { - $nextValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - foreach($nextValues as $k => $value) { - if (isset($sumValues[$k])) { - $sumValues[$k] += $value; - } else { - $sumValues[$k] = $value; - } - } - } - } - - return $sumValues; - } // function _percentageSumCalculation() - - - private function _percentageAdjustValues($dataValues,$sumValues) { - foreach($dataValues as $k => $dataValue) { - $dataValues[$k] = $dataValue / $sumValues[$k] * 100; - } - - return $dataValues; - } // function _percentageAdjustValues() - - - private function _getCaption($captionElement) { - // Read any caption - $caption = (!is_null($captionElement)) ? $captionElement->getCaption() : NULL; - // Test if we have a title caption to display - if (!is_null($caption)) { - // If we do, it could be a plain string or an array - if (is_array($caption)) { - // Implode an array to a plain string - $caption = implode('',$caption); - } - } - return $caption; - } // function _getCaption() - - - private function _renderTitle() { - $title = $this->_getCaption($this->_chart->getTitle()); - if (!is_null($title)) { - $this->_graph->title->Set($title); - } - } // function _renderTitle() - - - private function _renderLegend() { - $legend = $this->_chart->getLegend(); - if (!is_null($legend)) { - $legendPosition = $legend->getPosition(); - $legendOverlay = $legend->getOverlay(); - switch ($legendPosition) { - case 'r' : - $this->_graph->legend->SetPos(0.01,0.5,'right','center'); // right - $this->_graph->legend->SetColumns(1); - break; - case 'l' : - $this->_graph->legend->SetPos(0.01,0.5,'left','center'); // left - $this->_graph->legend->SetColumns(1); - break; - case 't' : - $this->_graph->legend->SetPos(0.5,0.01,'center','top'); // top - break; - case 'b' : - $this->_graph->legend->SetPos(0.5,0.99,'center','bottom'); // bottom - break; - default : - $this->_graph->legend->SetPos(0.01,0.01,'right','top'); // top-right - $this->_graph->legend->SetColumns(1); - break; - } - } else { - $this->_graph->legend->Hide(); - } - } // function _renderLegend() - - - private function _renderCartesianPlotArea($type='textlin') { - $this->_graph = new Graph(self::$_width,self::$_height); - $this->_graph->SetScale($type); - - $this->_renderTitle(); - - // Rotate for bar rather than column chart - $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); - $reverse = ($rotation == 'bar') ? true : false; - - $xAxisLabel = $this->_chart->getXAxisLabel(); - if (!is_null($xAxisLabel)) { - $title = $this->_getCaption($xAxisLabel); - if (!is_null($title)) { - $this->_graph->xaxis->SetTitle($title,'center'); - $this->_graph->xaxis->title->SetMargin(35); - if ($reverse) { - $this->_graph->xaxis->title->SetAngle(90); - $this->_graph->xaxis->title->SetMargin(90); - } - } - } - - $yAxisLabel = $this->_chart->getYAxisLabel(); - if (!is_null($yAxisLabel)) { - $title = $this->_getCaption($yAxisLabel); - if (!is_null($title)) { - $this->_graph->yaxis->SetTitle($title,'center'); - if ($reverse) { - $this->_graph->yaxis->title->SetAngle(0); - $this->_graph->yaxis->title->SetMargin(-55); - } - } - } - } // function _renderCartesianPlotArea() - - - private function _renderPiePlotArea($doughnut = False) { - $this->_graph = new PieGraph(self::$_width,self::$_height); - - $this->_renderTitle(); - } // function _renderPiePlotArea() - - - private function _renderRadarPlotArea() { - $this->_graph = new RadarGraph(self::$_width,self::$_height); - $this->_graph->SetScale('lin'); - - $this->_renderTitle(); - } // function _renderRadarPlotArea() - - - private function _renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') { - $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + private static $_width = 640; + + private static $_height = 480; + + private static $_colourSet = array( 'mediumpurple1', 'palegreen3', 'gold1', 'cadetblue1', + 'darkmagenta', 'coral', 'dodgerblue3', 'eggplant', + 'mediumblue', 'magenta', 'sandybrown', 'cyan', + 'firebrick1', 'forestgreen', 'deeppink4', 'darkolivegreen', + 'goldenrod2' + ); + + private static $_markSet = array( 'diamond' => MARK_DIAMOND, + 'square' => MARK_SQUARE, + 'triangle' => MARK_UTRIANGLE, + 'x' => MARK_X, + 'star' => MARK_STAR, + 'dot' => MARK_FILLEDCIRCLE, + 'dash' => MARK_DTRIANGLE, + 'circle' => MARK_CIRCLE, + 'plus' => MARK_CROSS + ); + + + private $_chart = null; + + private $_graph = null; + + private static $_plotColour = 0; + + private static $_plotMark = 0; + + + private function _formatPointMarker($seriesPlot,$markerID) { + $plotMarkKeys = array_keys(self::$_markSet); + if (is_null($markerID)) { + // Use default plot marker (next marker in the series) + self::$_plotMark %= count(self::$_markSet); + $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]); + } elseif ($markerID !== 'none') { + // Use specified plot marker (if it exists) + if (isset(self::$_markSet[$markerID])) { + $seriesPlot->mark->SetType(self::$_markSet[$markerID]); + } else { + // If the specified plot marker doesn't exist, use default plot marker (next marker in the series) + self::$_plotMark %= count(self::$_markSet); + $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]); + } + } else { + // Hide plot marker + $seriesPlot->mark->Hide(); + } + $seriesPlot->mark->SetColor(self::$_colourSet[self::$_plotColour]); + $seriesPlot->mark->SetFillColor(self::$_colourSet[self::$_plotColour]); + $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + + return $seriesPlot; + } // function _formatPointMarker() + + + private function _formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') { + $datasetLabelFormatCode = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); + if (!is_null($datasetLabelFormatCode)) { + // Retrieve any label formatting code + $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); + } + + $testCurrentIndex = 0; + foreach($datasetLabels as $i => $datasetLabel) { + if (is_array($datasetLabel)) { + if ($rotation == 'bar') { + $datasetLabels[$i] = implode(" ",$datasetLabel); + } else { + $datasetLabel = array_reverse($datasetLabel); + $datasetLabels[$i] = implode("\n",$datasetLabel); + } + } else { + // Format labels according to any formatting code + if (!is_null($datasetLabelFormatCode)) { + $datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel,$datasetLabelFormatCode); + } + } + ++$testCurrentIndex; + } + + return $datasetLabels; + } // function _formatDataSetLabels() + + + private function _percentageSumCalculation($groupID,$seriesCount) { + // Adjust our values to a percentage value across all series in the group + for($i = 0; $i < $seriesCount; ++$i) { + if ($i == 0) { + $sumValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + } else { + $nextValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + foreach($nextValues as $k => $value) { + if (isset($sumValues[$k])) { + $sumValues[$k] += $value; + } else { + $sumValues[$k] = $value; + } + } + } + } + + return $sumValues; + } // function _percentageSumCalculation() + + + private function _percentageAdjustValues($dataValues,$sumValues) { + foreach($dataValues as $k => $dataValue) { + $dataValues[$k] = $dataValue / $sumValues[$k] * 100; + } + + return $dataValues; + } // function _percentageAdjustValues() + + + private function _getCaption($captionElement) { + // Read any caption + $caption = (!is_null($captionElement)) ? $captionElement->getCaption() : NULL; + // Test if we have a title caption to display + if (!is_null($caption)) { + // If we do, it could be a plain string or an array + if (is_array($caption)) { + // Implode an array to a plain string + $caption = implode('',$caption); + } + } + return $caption; + } // function _getCaption() + + + private function _renderTitle() { + $title = $this->_getCaption($this->_chart->getTitle()); + if (!is_null($title)) { + $this->_graph->title->Set($title); + } + } // function _renderTitle() + + + private function _renderLegend() { + $legend = $this->_chart->getLegend(); + if (!is_null($legend)) { + $legendPosition = $legend->getPosition(); + $legendOverlay = $legend->getOverlay(); + switch ($legendPosition) { + case 'r' : + $this->_graph->legend->SetPos(0.01,0.5,'right','center'); // right + $this->_graph->legend->SetColumns(1); + break; + case 'l' : + $this->_graph->legend->SetPos(0.01,0.5,'left','center'); // left + $this->_graph->legend->SetColumns(1); + break; + case 't' : + $this->_graph->legend->SetPos(0.5,0.01,'center','top'); // top + break; + case 'b' : + $this->_graph->legend->SetPos(0.5,0.99,'center','bottom'); // bottom + break; + default : + $this->_graph->legend->SetPos(0.01,0.01,'right','top'); // top-right + $this->_graph->legend->SetColumns(1); + break; + } + } else { + $this->_graph->legend->Hide(); + } + } // function _renderLegend() + + + private function _renderCartesianPlotArea($type='textlin') { + $this->_graph = new Graph(self::$_width,self::$_height); + $this->_graph->SetScale($type); + + $this->_renderTitle(); + + // Rotate for bar rather than column chart + $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); + $reverse = ($rotation == 'bar') ? true : false; + + $xAxisLabel = $this->_chart->getXAxisLabel(); + if (!is_null($xAxisLabel)) { + $title = $this->_getCaption($xAxisLabel); + if (!is_null($title)) { + $this->_graph->xaxis->SetTitle($title,'center'); + $this->_graph->xaxis->title->SetMargin(35); + if ($reverse) { + $this->_graph->xaxis->title->SetAngle(90); + $this->_graph->xaxis->title->SetMargin(90); + } + } + } + + $yAxisLabel = $this->_chart->getYAxisLabel(); + if (!is_null($yAxisLabel)) { + $title = $this->_getCaption($yAxisLabel); + if (!is_null($title)) { + $this->_graph->yaxis->SetTitle($title,'center'); + if ($reverse) { + $this->_graph->yaxis->title->SetAngle(0); + $this->_graph->yaxis->title->SetMargin(-55); + } + } + } + } // function _renderCartesianPlotArea() + + + private function _renderPiePlotArea($doughnut = False) { + $this->_graph = new PieGraph(self::$_width,self::$_height); + + $this->_renderTitle(); + } // function _renderPiePlotArea() + + + private function _renderRadarPlotArea() { + $this->_graph = new RadarGraph(self::$_width,self::$_height); + $this->_graph->SetScale('lin'); + + $this->_renderTitle(); + } // function _renderRadarPlotArea() + + + private function _renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') { + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); - if ($labelCount > 0) { - $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); - $this->_graph->xaxis->SetTickLabels($datasetLabels); - } - - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - if ($grouping == 'percentStacked') { - $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount); - } - - // Loop through each data series in turn - for($i = 0; $i < $seriesCount; ++$i) { - $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - - if ($grouping == 'percentStacked') { - $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues); - } - - // Fill in any missing values in the $dataValues array - $testCurrentIndex = 0; - foreach($dataValues as $k => $dataValue) { - while($k != $testCurrentIndex) { - $dataValues[$testCurrentIndex] = null; - ++$testCurrentIndex; - } - ++$testCurrentIndex; - } - - $seriesPlot = new LinePlot($dataValues); - if ($combination) { - $seriesPlot->SetBarCenter(); - } - - if ($filled) { - $seriesPlot->SetFilled(true); - $seriesPlot->SetColor('black'); - $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); - } else { - // Set the appropriate plot marker - $this->_formatPointMarker($seriesPlot,$marker); - } - $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); - $seriesPlot->SetLegend($dataLabel); - - $seriesPlots[] = $seriesPlot; - } - - if ($grouping == 'standard') { - $groupPlot = $seriesPlots; - } else { - $groupPlot = new AccLinePlot($seriesPlots); - } - $this->_graph->Add($groupPlot); - } // function _renderPlotLine() - - - private function _renderPlotBar($groupID, $dimensions = '2d') { - $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); - // Rotate for bar rather than column chart - if (($groupID == 0) && ($rotation == 'bar')) { - $this->_graph->Set90AndMargin(); - } - $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->_graph->xaxis->SetTickLabels($datasetLabels); + } + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + if ($grouping == 'percentStacked') { + $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount); + } + + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + + if ($grouping == 'percentStacked') { + $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues); + } + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach($dataValues as $k => $dataValue) { + while($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + $seriesPlot = new LinePlot($dataValues); + if ($combination) { + $seriesPlot->SetBarCenter(); + } + + if ($filled) { + $seriesPlot->SetFilled(true); + $seriesPlot->SetColor('black'); + $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); + } else { + // Set the appropriate plot marker + $this->_formatPointMarker($seriesPlot,$marker); + } + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetLegend($dataLabel); + + $seriesPlots[] = $seriesPlot; + } + + if ($grouping == 'standard') { + $groupPlot = $seriesPlots; + } else { + $groupPlot = new AccLinePlot($seriesPlots); + } + $this->_graph->Add($groupPlot); + } // function _renderPlotLine() + + + private function _renderPlotBar($groupID, $dimensions = '2d') { + $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); + // Rotate for bar rather than column chart + if (($groupID == 0) && ($rotation == 'bar')) { + $this->_graph->Set90AndMargin(); + } + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); - if ($labelCount > 0) { - $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); - // Rotate for bar rather than column chart - if ($rotation == 'bar') { - $datasetLabels = array_reverse($datasetLabels); - $this->_graph->yaxis->SetPos('max'); - $this->_graph->yaxis->SetLabelAlign('center','top'); - $this->_graph->yaxis->SetLabelSide(SIDE_RIGHT); - } - $this->_graph->xaxis->SetTickLabels($datasetLabels); - } - - - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - if ($grouping == 'percentStacked') { - $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount); - } - - // Loop through each data series in turn - for($j = 0; $j < $seriesCount; ++$j) { - $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); - if ($grouping == 'percentStacked') { - $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues); - } - - // Fill in any missing values in the $dataValues array - $testCurrentIndex = 0; - foreach($dataValues as $k => $dataValue) { - while($k != $testCurrentIndex) { - $dataValues[$testCurrentIndex] = null; - ++$testCurrentIndex; - } - ++$testCurrentIndex; - } - - // Reverse the $dataValues order for bar rather than column chart - if ($rotation == 'bar') { - $dataValues = array_reverse($dataValues); - } - $seriesPlot = new BarPlot($dataValues); - $seriesPlot->SetColor('black'); - $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); - if ($dimensions == '3d') { - $seriesPlot->SetShadow(); - } - if (!$this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { - $dataLabel = ''; - } else { - $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); - } - $seriesPlot->SetLegend($dataLabel); - - $seriesPlots[] = $seriesPlot; - } - // Reverse the plot order for bar rather than column chart - if (($rotation == 'bar') && (!($grouping == 'percentStacked'))) { - $seriesPlots = array_reverse($seriesPlots); - } - - if ($grouping == 'clustered') { - $groupPlot = new GroupBarPlot($seriesPlots); - } elseif ($grouping == 'standard') { - $groupPlot = new GroupBarPlot($seriesPlots); - } else { - $groupPlot = new AccBarPlot($seriesPlots); - if ($dimensions == '3d') { - $groupPlot->SetShadow(); - } - } - - $this->_graph->Add($groupPlot); - } // function _renderPlotBar() - - - private function _renderPlotScatter($groupID,$bubble) { - $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - $scatterStyle = $bubbleSize = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - - // Loop through each data series in turn - for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - - foreach($dataValuesY as $k => $dataValueY) { - $dataValuesY[$k] = $k; - } - - $seriesPlot = new ScatterPlot($dataValuesX,$dataValuesY); - if ($scatterStyle == 'lineMarker') { - $seriesPlot->SetLinkPoints(); - $seriesPlot->link->SetColor(self::$_colourSet[self::$_plotColour]); - } elseif ($scatterStyle == 'smoothMarker') { - $spline = new Spline($dataValuesY,$dataValuesX); - list($splineDataY,$splineDataX) = $spline->Get(count($dataValuesX) * self::$_width / 20); - $lplot = new LinePlot($splineDataX,$splineDataY); - $lplot->SetColor(self::$_colourSet[self::$_plotColour]); - - $this->_graph->Add($lplot); - } - - if ($bubble) { - $this->_formatPointMarker($seriesPlot,'dot'); - $seriesPlot->mark->SetColor('black'); - $seriesPlot->mark->SetSize($bubbleSize); - } else { - $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - $this->_formatPointMarker($seriesPlot,$marker); - } - $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); - $seriesPlot->SetLegend($dataLabel); - - $this->_graph->Add($seriesPlot); - } - } // function _renderPlotScatter() - - - private function _renderPlotRadar($groupID) { - $radarStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - - // Loop through each data series in turn - for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - - $dataValues = array(); - foreach($dataValuesY as $k => $dataValueY) { - $dataValues[$k] = implode(' ',array_reverse($dataValueY)); - } - $tmp = array_shift($dataValues); - $dataValues[] = $tmp; - $tmp = array_shift($dataValuesX); - $dataValuesX[] = $tmp; - - $this->_graph->SetTitles(array_reverse($dataValues)); - - $seriesPlot = new RadarPlot(array_reverse($dataValuesX)); - - $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); - $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); - if ($radarStyle == 'filled') { - $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour]); - } - $this->_formatPointMarker($seriesPlot,$marker); - $seriesPlot->SetLegend($dataLabel); - - $this->_graph->Add($seriesPlot); - } - } // function _renderPlotRadar() - - - private function _renderPlotContour($groupID) { - $contourStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - - $dataValues = array(); - // Loop through each data series in turn - for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - - $dataValues[$i] = $dataValuesX; - } - $seriesPlot = new ContourPlot($dataValues); - - $this->_graph->Add($seriesPlot); - } // function _renderPlotContour() - - - private function _renderPlotStock($groupID) { - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $plotOrder = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); - - $dataValues = array(); - // Loop through each data series in turn and build the plot arrays - foreach($plotOrder as $i => $v) { - $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); - foreach($dataValuesX as $j => $dataValueX) { - $dataValues[$plotOrder[$i]][$j] = $dataValueX; - } - } - if(empty($dataValues)) { - return; - } - - $dataValuesPlot = array(); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); + // Rotate for bar rather than column chart + if ($rotation == 'bar') { + $datasetLabels = array_reverse($datasetLabels); + $this->_graph->yaxis->SetPos('max'); + $this->_graph->yaxis->SetLabelAlign('center','top'); + $this->_graph->yaxis->SetLabelSide(SIDE_RIGHT); + } + $this->_graph->xaxis->SetTickLabels($datasetLabels); + } + + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + if ($grouping == 'percentStacked') { + $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount); + } + + // Loop through each data series in turn + for($j = 0; $j < $seriesCount; ++$j) { + $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + if ($grouping == 'percentStacked') { + $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues); + } + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach($dataValues as $k => $dataValue) { + while($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + // Reverse the $dataValues order for bar rather than column chart + if ($rotation == 'bar') { + $dataValues = array_reverse($dataValues); + } + $seriesPlot = new BarPlot($dataValues); + $seriesPlot->SetColor('black'); + $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); + if ($dimensions == '3d') { + $seriesPlot->SetShadow(); + } + if (!$this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { + $dataLabel = ''; + } else { + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); + } + $seriesPlot->SetLegend($dataLabel); + + $seriesPlots[] = $seriesPlot; + } + // Reverse the plot order for bar rather than column chart + if (($rotation == 'bar') && (!($grouping == 'percentStacked'))) { + $seriesPlots = array_reverse($seriesPlots); + } + + if ($grouping == 'clustered') { + $groupPlot = new GroupBarPlot($seriesPlots); + } elseif ($grouping == 'standard') { + $groupPlot = new GroupBarPlot($seriesPlots); + } else { + $groupPlot = new AccBarPlot($seriesPlots); + if ($dimensions == '3d') { + $groupPlot->SetShadow(); + } + } + + $this->_graph->Add($groupPlot); + } // function _renderPlotBar() + + + private function _renderPlotScatter($groupID,$bubble) { + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $scatterStyle = $bubbleSize = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + + foreach($dataValuesY as $k => $dataValueY) { + $dataValuesY[$k] = $k; + } + + $seriesPlot = new ScatterPlot($dataValuesX,$dataValuesY); + if ($scatterStyle == 'lineMarker') { + $seriesPlot->SetLinkPoints(); + $seriesPlot->link->SetColor(self::$_colourSet[self::$_plotColour]); + } elseif ($scatterStyle == 'smoothMarker') { + $spline = new Spline($dataValuesY,$dataValuesX); + list($splineDataY,$splineDataX) = $spline->Get(count($dataValuesX) * self::$_width / 20); + $lplot = new LinePlot($splineDataX,$splineDataY); + $lplot->SetColor(self::$_colourSet[self::$_plotColour]); + + $this->_graph->Add($lplot); + } + + if ($bubble) { + $this->_formatPointMarker($seriesPlot,'dot'); + $seriesPlot->mark->SetColor('black'); + $seriesPlot->mark->SetSize($bubbleSize); + } else { + $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + $this->_formatPointMarker($seriesPlot,$marker); + } + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetLegend($dataLabel); + + $this->_graph->Add($seriesPlot); + } + } // function _renderPlotScatter() + + + private function _renderPlotRadar($groupID) { + $radarStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + + $dataValues = array(); + foreach($dataValuesY as $k => $dataValueY) { + $dataValues[$k] = implode(' ',array_reverse($dataValueY)); + } + $tmp = array_shift($dataValues); + $dataValues[] = $tmp; + $tmp = array_shift($dataValuesX); + $dataValuesX[] = $tmp; + + $this->_graph->SetTitles(array_reverse($dataValues)); + + $seriesPlot = new RadarPlot(array_reverse($dataValuesX)); + + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + if ($radarStyle == 'filled') { + $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour]); + } + $this->_formatPointMarker($seriesPlot,$marker); + $seriesPlot->SetLegend($dataLabel); + + $this->_graph->Add($seriesPlot); + } + } // function _renderPlotRadar() + + + private function _renderPlotContour($groupID) { + $contourStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + $dataValues = array(); + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + + $dataValues[$i] = $dataValuesX; + } + $seriesPlot = new ContourPlot($dataValues); + + $this->_graph->Add($seriesPlot); + } // function _renderPlotContour() + + + private function _renderPlotStock($groupID) { + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $plotOrder = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); + + $dataValues = array(); + // Loop through each data series in turn and build the plot arrays + foreach($plotOrder as $i => $v) { + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); + foreach($dataValuesX as $j => $dataValueX) { + $dataValues[$plotOrder[$i]][$j] = $dataValueX; + } + } + if(empty($dataValues)) { + return; + } + + $dataValuesPlot = array(); // Flatten the plot arrays to a single dimensional array to work with jpgraph - for($j = 0; $j < count($dataValues[0]); $j++) { - for($i = 0; $i < $seriesCount; $i++) { - $dataValuesPlot[] = $dataValues[$i][$j]; - } - } + for($j = 0; $j < count($dataValues[0]); $j++) { + for($i = 0; $i < $seriesCount; $i++) { + $dataValuesPlot[] = $dataValues[$i][$j]; + } + } // Set the x-axis labels $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); - if ($labelCount > 0) { - $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); - $this->_graph->xaxis->SetTickLabels($datasetLabels); - } + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->_graph->xaxis->SetTickLabels($datasetLabels); + } - $seriesPlot = new StockPlot($dataValuesPlot); - $seriesPlot->SetWidth(20); + $seriesPlot = new StockPlot($dataValuesPlot); + $seriesPlot->SetWidth(20); - $this->_graph->Add($seriesPlot); - } // function _renderPlotStock() + $this->_graph->Add($seriesPlot); + } // function _renderPlotStock() - private function _renderAreaChart($groupCount, $dimensions = '2d') { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + private function _renderAreaChart($groupCount, $dimensions = '2d') { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); - $this->_renderCartesianPlotArea(); + $this->_renderCartesianPlotArea(); - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotLine($i,True,False,$dimensions); - } - } // function _renderAreaChart() + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotLine($i,True,False,$dimensions); + } + } // function _renderAreaChart() - private function _renderLineChart($groupCount, $dimensions = '2d') { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + private function _renderLineChart($groupCount, $dimensions = '2d') { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); - $this->_renderCartesianPlotArea(); + $this->_renderCartesianPlotArea(); - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotLine($i,False,False,$dimensions); - } - } // function _renderLineChart() - - - private function _renderBarChart($groupCount, $dimensions = '2d') { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); - - $this->_renderCartesianPlotArea(); - - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotBar($i,$dimensions); - } - } // function _renderBarChart() - - - private function _renderScatterChart($groupCount) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotLine($i,False,False,$dimensions); + } + } // function _renderLineChart() + + + private function _renderBarChart($groupCount, $dimensions = '2d') { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); + + $this->_renderCartesianPlotArea(); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotBar($i,$dimensions); + } + } // function _renderBarChart() + + + private function _renderScatterChart($groupCount) { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); - $this->_renderCartesianPlotArea('linlin'); - - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotScatter($i,false); - } - } // function _renderScatterChart() + $this->_renderCartesianPlotArea('linlin'); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotScatter($i,false); + } + } // function _renderScatterChart() - private function _renderBubbleChart($groupCount) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); + private function _renderBubbleChart($groupCount) { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); - $this->_renderCartesianPlotArea('linlin'); + $this->_renderCartesianPlotArea('linlin'); - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotScatter($i,true); - } - } // function _renderBubbleChart() + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotScatter($i,true); + } + } // function _renderBubbleChart() - private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = False, $multiplePlots = False) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie.php'); - if ($dimensions == '3d') { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie3d.php'); - } + private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = False, $multiplePlots = False) { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie.php'); + if ($dimensions == '3d') { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie3d.php'); + } - $this->_renderPiePlotArea($doughnut); + $this->_renderPiePlotArea($doughnut); - $iLimit = ($multiplePlots) ? $groupCount : 1; - for($groupID = 0; $groupID < $iLimit; ++$groupID) { - $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - $exploded = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - if ($groupID == 0) { - $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); - if ($labelCount > 0) { - $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); - } - } + $iLimit = ($multiplePlots) ? $groupCount : 1; + for($groupID = 0; $groupID < $iLimit; ++$groupID) { + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $exploded = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + if ($groupID == 0) { + $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + } + } - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - // For pie charts, we only display the first series: doughnut charts generally display all series - $jLimit = ($multiplePlots) ? $seriesCount : 1; - // Loop through each data series in turn - for($j = 0; $j < $jLimit; ++$j) { - $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + // For pie charts, we only display the first series: doughnut charts generally display all series + $jLimit = ($multiplePlots) ? $seriesCount : 1; + // Loop through each data series in turn + for($j = 0; $j < $jLimit; ++$j) { + $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); - // Fill in any missing values in the $dataValues array - $testCurrentIndex = 0; - foreach($dataValues as $k => $dataValue) { - while($k != $testCurrentIndex) { - $dataValues[$testCurrentIndex] = null; - ++$testCurrentIndex; - } - ++$testCurrentIndex; - } - - if ($dimensions == '3d') { - $seriesPlot = new PiePlot3D($dataValues); - } else { - if ($doughnut) { - $seriesPlot = new PiePlotC($dataValues); - } else { - $seriesPlot = new PiePlot($dataValues); - } - } - - if ($multiplePlots) { - $seriesPlot->SetSize(($jLimit-$j) / ($jLimit * 4)); - } - - if ($doughnut) { - $seriesPlot->SetMidColor('white'); - } - - $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); - if (count($datasetLabels) > 0) - $seriesPlot->SetLabels(array_fill(0,count($datasetLabels),'')); - if ($dimensions != '3d') { - $seriesPlot->SetGuideLines(false); - } - if ($j == 0) { - if ($exploded) { - $seriesPlot->ExplodeAll(); - } - $seriesPlot->SetLegends($datasetLabels); - } - - $this->_graph->Add($seriesPlot); - } - } - } // function _renderPieChart() - - - private function _renderRadarChart($groupCount) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_radar.php'); - - $this->_renderRadarPlotArea(); - - for($groupID = 0; $groupID < $groupCount; ++$groupID) { - $this->_renderPlotRadar($groupID); - } - } // function _renderRadarChart() - - - private function _renderStockChart($groupCount) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_stock.php'); - - $this->_renderCartesianPlotArea('intint'); - - for($groupID = 0; $groupID < $groupCount; ++$groupID) { - $this->_renderPlotStock($groupID); - } - } // function _renderStockChart() - - - private function _renderContourChart($groupCount,$dimensions) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_contour.php'); - - $this->_renderCartesianPlotArea('intint'); - - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotContour($i); - } - } // function _renderContourChart() - - - private function _renderCombinationChart($groupCount,$dimensions,$outputDestination) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); - - $this->_renderCartesianPlotArea(); - - for($i = 0; $i < $groupCount; ++$i) { - $dimensions = null; - $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); - switch ($chartType) { - case 'area3DChart' : - $dimensions = '3d'; - case 'areaChart' : - $this->_renderPlotLine($i,True,True,$dimensions); - break; - case 'bar3DChart' : - $dimensions = '3d'; - case 'barChart' : - $this->_renderPlotBar($i,$dimensions); - break; - case 'line3DChart' : - $dimensions = '3d'; - case 'lineChart' : - $this->_renderPlotLine($i,False,True,$dimensions); - break; - case 'scatterChart' : - $this->_renderPlotScatter($i,false); - break; - case 'bubbleChart' : - $this->_renderPlotScatter($i,true); - break; - default : - $this->_graph = null; - return false; - } - } - - $this->_renderLegend(); - - $this->_graph->Stroke($outputDestination); - return true; - } // function _renderCombinationChart() - - - public function render($outputDestination) { + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach($dataValues as $k => $dataValue) { + while($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + if ($dimensions == '3d') { + $seriesPlot = new PiePlot3D($dataValues); + } else { + if ($doughnut) { + $seriesPlot = new PiePlotC($dataValues); + } else { + $seriesPlot = new PiePlot($dataValues); + } + } + + if ($multiplePlots) { + $seriesPlot->SetSize(($jLimit-$j) / ($jLimit * 4)); + } + + if ($doughnut) { + $seriesPlot->SetMidColor('white'); + } + + $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + if (count($datasetLabels) > 0) + $seriesPlot->SetLabels(array_fill(0,count($datasetLabels),'')); + if ($dimensions != '3d') { + $seriesPlot->SetGuideLines(false); + } + if ($j == 0) { + if ($exploded) { + $seriesPlot->ExplodeAll(); + } + $seriesPlot->SetLegends($datasetLabels); + } + + $this->_graph->Add($seriesPlot); + } + } + } // function _renderPieChart() + + + private function _renderRadarChart($groupCount) { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_radar.php'); + + $this->_renderRadarPlotArea(); + + for($groupID = 0; $groupID < $groupCount; ++$groupID) { + $this->_renderPlotRadar($groupID); + } + } // function _renderRadarChart() + + + private function _renderStockChart($groupCount) { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_stock.php'); + + $this->_renderCartesianPlotArea('intint'); + + for($groupID = 0; $groupID < $groupCount; ++$groupID) { + $this->_renderPlotStock($groupID); + } + } // function _renderStockChart() + + + private function _renderContourChart($groupCount,$dimensions) { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_contour.php'); + + $this->_renderCartesianPlotArea('intint'); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotContour($i); + } + } // function _renderContourChart() + + + private function _renderCombinationChart($groupCount,$dimensions,$outputDestination) { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + + $this->_renderCartesianPlotArea(); + + for($i = 0; $i < $groupCount; ++$i) { + $dimensions = null; + $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + switch ($chartType) { + case 'area3DChart' : + $dimensions = '3d'; + case 'areaChart' : + $this->_renderPlotLine($i,True,True,$dimensions); + break; + case 'bar3DChart' : + $dimensions = '3d'; + case 'barChart' : + $this->_renderPlotBar($i,$dimensions); + break; + case 'line3DChart' : + $dimensions = '3d'; + case 'lineChart' : + $this->_renderPlotLine($i,False,True,$dimensions); + break; + case 'scatterChart' : + $this->_renderPlotScatter($i,false); + break; + case 'bubbleChart' : + $this->_renderPlotScatter($i,true); + break; + default : + $this->_graph = null; + return false; + } + } + + $this->_renderLegend(); + + $this->_graph->Stroke($outputDestination); + return true; + } // function _renderCombinationChart() + + + public function render($outputDestination) { self::$_plotColour = 0; - $groupCount = $this->_chart->getPlotArea()->getPlotGroupCount(); - - $dimensions = null; - if ($groupCount == 1) { - $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); - } else { - $chartTypes = array(); - for($i = 0; $i < $groupCount; ++$i) { - $chartTypes[] = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); - } - $chartTypes = array_unique($chartTypes); - if (count($chartTypes) == 1) { - $chartType = array_pop($chartTypes); - } elseif (count($chartTypes) == 0) { - echo 'Chart is not yet implemented<br />'; - return false; - } else { - return $this->_renderCombinationChart($groupCount,$dimensions,$outputDestination); - } - } - - switch ($chartType) { - case 'area3DChart' : - $dimensions = '3d'; - case 'areaChart' : - $this->_renderAreaChart($groupCount,$dimensions); - break; - case 'bar3DChart' : - $dimensions = '3d'; - case 'barChart' : - $this->_renderBarChart($groupCount,$dimensions); - break; - case 'line3DChart' : - $dimensions = '3d'; - case 'lineChart' : - $this->_renderLineChart($groupCount,$dimensions); - break; - case 'pie3DChart' : - $dimensions = '3d'; - case 'pieChart' : - $this->_renderPieChart($groupCount,$dimensions,False,False); - break; - case 'doughnut3DChart' : - $dimensions = '3d'; - case 'doughnutChart' : - $this->_renderPieChart($groupCount,$dimensions,True,True); - break; - case 'scatterChart' : - $this->_renderScatterChart($groupCount); - break; - case 'bubbleChart' : - $this->_renderBubbleChart($groupCount); - break; - case 'radarChart' : - $this->_renderRadarChart($groupCount); - break; - case 'surface3DChart' : - $dimensions = '3d'; - case 'surfaceChart' : - $this->_renderContourChart($groupCount,$dimensions); - break; - case 'stockChart' : - $this->_renderStockChart($groupCount,$dimensions); - break; - default : - echo $chartType.' is not yet implemented<br />'; - return false; - } - $this->_renderLegend(); - - $this->_graph->Stroke($outputDestination); - return true; - } // function render() - - - /** - * Create a new PHPExcel_Chart_Renderer_jpgraph - */ - public function __construct(PHPExcel_Chart $chart) - { - $this->_graph = null; - $this->_chart = $chart; - } // function __construct() - -} // PHPExcel_Chart_Renderer_jpgraph + $groupCount = $this->_chart->getPlotArea()->getPlotGroupCount(); + + $dimensions = null; + if ($groupCount == 1) { + $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); + } else { + $chartTypes = array(); + for($i = 0; $i < $groupCount; ++$i) { + $chartTypes[] = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + } + $chartTypes = array_unique($chartTypes); + if (count($chartTypes) == 1) { + $chartType = array_pop($chartTypes); + } elseif (count($chartTypes) == 0) { + echo 'Chart is not yet implemented<br />'; + return false; + } else { + return $this->_renderCombinationChart($groupCount,$dimensions,$outputDestination); + } + } + + switch ($chartType) { + case 'area3DChart' : + $dimensions = '3d'; + case 'areaChart' : + $this->_renderAreaChart($groupCount,$dimensions); + break; + case 'bar3DChart' : + $dimensions = '3d'; + case 'barChart' : + $this->_renderBarChart($groupCount,$dimensions); + break; + case 'line3DChart' : + $dimensions = '3d'; + case 'lineChart' : + $this->_renderLineChart($groupCount,$dimensions); + break; + case 'pie3DChart' : + $dimensions = '3d'; + case 'pieChart' : + $this->_renderPieChart($groupCount,$dimensions,False,False); + break; + case 'doughnut3DChart' : + $dimensions = '3d'; + case 'doughnutChart' : + $this->_renderPieChart($groupCount,$dimensions,True,True); + break; + case 'scatterChart' : + $this->_renderScatterChart($groupCount); + break; + case 'bubbleChart' : + $this->_renderBubbleChart($groupCount); + break; + case 'radarChart' : + $this->_renderRadarChart($groupCount); + break; + case 'surface3DChart' : + $dimensions = '3d'; + case 'surfaceChart' : + $this->_renderContourChart($groupCount,$dimensions); + break; + case 'stockChart' : + $this->_renderStockChart($groupCount,$dimensions); + break; + default : + echo $chartType.' is not yet implemented<br />'; + return false; + } + $this->_renderLegend(); + + $this->_graph->Stroke($outputDestination); + return true; + } // function render() + + + /** + * Create a new PHPExcel_Chart_Renderer_jpgraph + */ + public function __construct(PHPExcel_Chart $chart) + { + $this->_graph = null; + $this->_chart = $chart; + } // function __construct() + +} // PHPExcel_Chart_Renderer_jpgraph diff --git a/Classes/PHPExcel/Chart/Title.php b/Classes/PHPExcel/Chart/Title.php index 1a222326f..c68a0b91a 100644 --- a/Classes/PHPExcel/Chart/Title.php +++ b/Classes/PHPExcel/Chart/Title.php @@ -18,75 +18,75 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Chart + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** * PHPExcel_Chart_Title * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Chart + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Chart_Title { - /** - * Title Caption - * - * @var string - */ - private $_caption = null; + /** + * Title Caption + * + * @var string + */ + private $_caption = null; - /** - * Title Layout - * - * @var PHPExcel_Chart_Layout - */ - private $_layout = null; + /** + * Title Layout + * + * @var PHPExcel_Chart_Layout + */ + private $_layout = null; - /** - * Create a new PHPExcel_Chart_Title - */ - public function __construct($caption = null, PHPExcel_Chart_Layout $layout = null) - { - $this->_caption = $caption; - $this->_layout = $layout; - } + /** + * Create a new PHPExcel_Chart_Title + */ + public function __construct($caption = null, PHPExcel_Chart_Layout $layout = null) + { + $this->_caption = $caption; + $this->_layout = $layout; + } - /** - * Get caption - * - * @return string - */ - public function getCaption() { - return $this->_caption; - } + /** + * Get caption + * + * @return string + */ + public function getCaption() { + return $this->_caption; + } - /** - * Set caption - * - * @param string $caption + /** + * Set caption + * + * @param string $caption * @return PHPExcel_Chart_Title - */ - public function setCaption($caption = null) { - $this->_caption = $caption; + */ + public function setCaption($caption = null) { + $this->_caption = $caption; return $this; - } + } - /** - * Get Layout - * - * @return PHPExcel_Chart_Layout - */ - public function getLayout() { - return $this->_layout; - } + /** + * Get Layout + * + * @return PHPExcel_Chart_Layout + */ + public function getLayout() { + return $this->_layout; + } } diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 42329b0e5..99a68630a 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -53,7 +53,7 @@ class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_ * * @var boolean */ - private $_embedImages = FALSE; + private $_embedImages = false; /** * Use inline CSS? @@ -130,7 +130,8 @@ class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_ * * @param PHPExcel $phpExcel PHPExcel object */ - public function __construct(PHPExcel $phpExcel) { + public function __construct(PHPExcel $phpExcel) + { $this->_phpExcel = $phpExcel; $this->_defaultFont = $this->_phpExcel->getDefaultStyle()->getFont(); } @@ -141,12 +142,13 @@ public function __construct(PHPExcel $phpExcel) { * @param string $pFilename * @throws PHPExcel_Writer_Exception */ - public function save($pFilename = null) { + public function save($pFilename = null) + { // garbage collect $this->_phpExcel->garbageCollect(); $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(false); $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); @@ -186,13 +188,18 @@ public function save($pFilename = null) { * @param string $vAlign Vertical alignment * @return string */ - private function _mapVAlign($vAlign) { + private function _mapVAlign($vAlign) + { switch ($vAlign) { - case PHPExcel_Style_Alignment::VERTICAL_BOTTOM: return 'bottom'; - case PHPExcel_Style_Alignment::VERTICAL_TOP: return 'top'; + case PHPExcel_Style_Alignment::VERTICAL_BOTTOM: + return 'bottom'; + case PHPExcel_Style_Alignment::VERTICAL_TOP: + return 'top'; case PHPExcel_Style_Alignment::VERTICAL_CENTER: - case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY: return 'middle'; - default: return 'baseline'; + case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY: + return 'middle'; + default: + return 'baseline'; } } @@ -202,15 +209,22 @@ private function _mapVAlign($vAlign) { * @param string $hAlign Horizontal alignment * @return string|false */ - private function _mapHAlign($hAlign) { + private function _mapHAlign($hAlign) + { switch ($hAlign) { - case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL: return false; - case PHPExcel_Style_Alignment::HORIZONTAL_LEFT: return 'left'; - case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: return 'right'; + case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL: + return false; + case PHPExcel_Style_Alignment::HORIZONTAL_LEFT: + return 'left'; + case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: + return 'right'; case PHPExcel_Style_Alignment::HORIZONTAL_CENTER: - case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS: return 'center'; - case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY: return 'justify'; - default: return false; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS: + return 'center'; + case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY: + return 'justify'; + default: + return false; } } @@ -220,23 +234,40 @@ private function _mapHAlign($hAlign) { * @param int $borderStyle Sheet index * @return string */ - private function _mapBorderStyle($borderStyle) { + private function _mapBorderStyle($borderStyle) + { switch ($borderStyle) { - case PHPExcel_Style_Border::BORDER_NONE: return 'none'; - case PHPExcel_Style_Border::BORDER_DASHDOT: return '1px dashed'; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT: return '1px dotted'; - case PHPExcel_Style_Border::BORDER_DASHED: return '1px dashed'; - case PHPExcel_Style_Border::BORDER_DOTTED: return '1px dotted'; - case PHPExcel_Style_Border::BORDER_DOUBLE: return '3px double'; - case PHPExcel_Style_Border::BORDER_HAIR: return '1px solid'; - case PHPExcel_Style_Border::BORDER_MEDIUM: return '2px solid'; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: return '2px dashed'; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: return '2px dotted'; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: return '2px dashed'; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: return '2px dashed'; - case PHPExcel_Style_Border::BORDER_THICK: return '3px solid'; - case PHPExcel_Style_Border::BORDER_THIN: return '1px solid'; - default: return '1px solid'; // map others to thin + case PHPExcel_Style_Border::BORDER_NONE: + return 'none'; + case PHPExcel_Style_Border::BORDER_DASHDOT: + return '1px dashed'; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT: + return '1px dotted'; + case PHPExcel_Style_Border::BORDER_DASHED: + return '1px dashed'; + case PHPExcel_Style_Border::BORDER_DOTTED: + return '1px dotted'; + case PHPExcel_Style_Border::BORDER_DOUBLE: + return '3px double'; + case PHPExcel_Style_Border::BORDER_HAIR: + return '1px solid'; + case PHPExcel_Style_Border::BORDER_MEDIUM: + return '2px solid'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: + return '2px dashed'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: + return '2px dotted'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: + return '2px dashed'; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: + return '2px dashed'; + case PHPExcel_Style_Border::BORDER_THICK: + return '3px solid'; + case PHPExcel_Style_Border::BORDER_THIN: + return '1px solid'; + default: + // map others to thin + return '1px solid'; } } @@ -245,7 +276,8 @@ private function _mapBorderStyle($borderStyle) { * * @return int */ - public function getSheetIndex() { + public function getSheetIndex() + { return $this->_sheetIndex; } @@ -255,7 +287,8 @@ public function getSheetIndex() { * @param int $pValue Sheet index * @return PHPExcel_Writer_HTML */ - public function setSheetIndex($pValue = 0) { + public function setSheetIndex($pValue = 0) + { $this->_sheetIndex = $pValue; return $this; } @@ -265,7 +298,8 @@ public function setSheetIndex($pValue = 0) { * * @return boolean */ - public function getGenerateSheetNavigationBlock() { + public function getGenerateSheetNavigationBlock() + { return $this->_generateSheetNavigationBlock; } @@ -275,7 +309,8 @@ public function getGenerateSheetNavigationBlock() { * @param boolean $pValue Flag indicating whether the sheet navigation block should be generated or not * @return PHPExcel_Writer_HTML */ - public function setGenerateSheetNavigationBlock($pValue = true) { + public function setGenerateSheetNavigationBlock($pValue = true) + { $this->_generateSheetNavigationBlock = (bool) $pValue; return $this; } @@ -283,7 +318,8 @@ public function setGenerateSheetNavigationBlock($pValue = true) { /** * Write all sheets (resets sheetIndex to NULL) */ - public function writeAllSheets() { + public function writeAllSheets() + { $this->_sheetIndex = null; return $this; } @@ -295,7 +331,8 @@ public function writeAllSheets() { * @return string * @throws PHPExcel_Writer_Exception */ - public function generateHTMLHeader($pIncludeStyles = false) { + public function generateHTMLHeader($pIncludeStyles = false) + { // PHPExcel object known? if (is_null($this->_phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); @@ -308,25 +345,33 @@ public function generateHTMLHeader($pIncludeStyles = false) { $html .= '<html>' . PHP_EOL; $html .= ' <head>' . PHP_EOL; $html .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . PHP_EOL; - if ($properties->getTitle() > '') + if ($properties->getTitle() > '') { $html .= ' <title>' . htmlspecialchars($properties->getTitle()) . '</title>' . PHP_EOL; - - if ($properties->getCreator() > '') + } + if ($properties->getCreator() > '') { $html .= ' <meta name="author" content="' . htmlspecialchars($properties->getCreator()) . '" />' . PHP_EOL; - if ($properties->getTitle() > '') + } + if ($properties->getTitle() > '') { $html .= ' <meta name="title" content="' . htmlspecialchars($properties->getTitle()) . '" />' . PHP_EOL; - if ($properties->getDescription() > '') + } + if ($properties->getDescription() > '') { $html .= ' <meta name="description" content="' . htmlspecialchars($properties->getDescription()) . '" />' . PHP_EOL; - if ($properties->getSubject() > '') + } + if ($properties->getSubject() > '') { $html .= ' <meta name="subject" content="' . htmlspecialchars($properties->getSubject()) . '" />' . PHP_EOL; - if ($properties->getKeywords() > '') + } + if ($properties->getKeywords() > '') { $html .= ' <meta name="keywords" content="' . htmlspecialchars($properties->getKeywords()) . '" />' . PHP_EOL; - if ($properties->getCategory() > '') + } + if ($properties->getCategory() > '') { $html .= ' <meta name="category" content="' . htmlspecialchars($properties->getCategory()) . '" />' . PHP_EOL; - if ($properties->getCompany() > '') + } + if ($properties->getCompany() > '') { $html .= ' <meta name="company" content="' . htmlspecialchars($properties->getCompany()) . '" />' . PHP_EOL; - if ($properties->getManager() > '') + } + if ($properties->getManager() > '') { $html .= ' <meta name="manager" content="' . htmlspecialchars($properties->getManager()) . '" />' . PHP_EOL; + } if ($pIncludeStyles) { $html .= $this->generateStyles(true); @@ -336,7 +381,6 @@ public function generateHTMLHeader($pIncludeStyles = false) { $html .= '' . PHP_EOL; $html .= ' <body>' . PHP_EOL; - // Return return $html; } @@ -346,7 +390,8 @@ public function generateHTMLHeader($pIncludeStyles = false) { * @return string * @throws PHPExcel_Writer_Exception */ - public function generateSheetData() { + public function generateSheetData() + { // PHPExcel object known? if (is_null($this->_phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); @@ -401,7 +446,7 @@ public function generateSheetData() { // Loop through cells $row = $rowMin-1; - while($row++ < $rowMax) { + while ($row++ < $rowMax) { // <thead> ? if ($row == $theadStart) { $html .= ' <thead>' . PHP_EOL; @@ -415,12 +460,12 @@ public function generateSheetData() { } // Write row if there are HTML table cells in it - if ( !isset($this->_isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row]) ) { + if (!isset($this->_isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row])) { // Start a new rowData $rowData = array(); // Loop through columns $column = $dimension[0][0] - 1; - while($column++ < $dimension[1][0]) { + while ($column++ < $dimension[1][0]) { // Cell exists? if ($sheet->cellExistsByColumnAndRow($column, $row)) { $rowData[$column] = PHPExcel_Cell::stringFromColumnIndex($column) . $row; @@ -455,7 +500,6 @@ public function generateSheetData() { ++$sheetId; } - // Return return $html; } @@ -501,7 +545,8 @@ public function generateNavigation() return $html; } - private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) { + private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) + { $rowMax = $row; $colMax = 'A'; if ($this->_includeCharts) { @@ -559,7 +604,8 @@ private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) * @return string * @throws PHPExcel_Writer_Exception */ - private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { + private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) + { // Construct HTML $html = ''; @@ -590,8 +636,8 @@ private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { $imageData = $filename; } else { $imageDetails = getimagesize($filename); - if ($fp = fopen($filename,"rb", 0)) { - $picture = fread($fp,filesize($filename)); + if ($fp = fopen($filename, "rb", 0)) { + $picture = fread($fp, filesize($filename)); fclose($fp); // base64 encode the binary data, then break it // into chunks according to RFC 2045 semantics @@ -603,16 +649,15 @@ private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { } $html .= '<div style="position: relative;">'; - $html .= '<img style="position: absolute; z-index: 1; left: ' . - $drawing->getOffsetX() . 'px; top: ' . $drawing->getOffsetY() . 'px; width: ' . - $drawing->getWidth() . 'px; height: ' . $drawing->getHeight() . 'px;" src="' . + $html .= '<img style="position: absolute; z-index: 1; left: ' . + $drawing->getOffsetX() . 'px; top: ' . $drawing->getOffsetY() . 'px; width: ' . + $drawing->getWidth() . 'px; height: ' . $drawing->getHeight() . 'px;" src="' . $imageData . '" border="0" />'; $html .= '</div>'; } } } - // Return return $html; } @@ -624,7 +669,8 @@ private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { * @return string * @throws PHPExcel_Writer_Exception */ - private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) { + private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) + { // Construct HTML $html = ''; @@ -640,8 +686,8 @@ private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) { $html .= PHP_EOL; $imageDetails = getimagesize($chartFileName); - if ($fp = fopen($chartFileName,"rb", 0)) { - $picture = fread($fp,filesize($chartFileName)); + if ($fp = fopen($chartFileName, "rb", 0)) { + $picture = fread($fp, filesize($chartFileName)); fclose($fp); // base64 encode the binary data, then break it // into chunks according to RFC 2045 semantics @@ -669,7 +715,8 @@ private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) { * @return string * @throws PHPExcel_Writer_Exception */ - public function generateStyles($generateSurroundingHTML = true) { + public function generateStyles($generateSurroundingHTML = true) + { // PHPExcel object known? if (is_null($this->_phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); @@ -710,7 +757,8 @@ public function generateStyles($generateSurroundingHTML = true) { * @return array * @throws PHPExcel_Writer_Exception */ - public function buildCSS($generateSurroundingHTML = true) { + public function buildCSS($generateSurroundingHTML = true) + { // PHPExcel object known? if (is_null($this->_phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); @@ -768,8 +816,8 @@ public function buildCSS($generateSurroundingHTML = true) { // Calculate cell style hashes foreach ($this->_phpExcel->getCellXfCollection() as $index => $style) { - $css['td.style' . $index] = $this->_createCSSStyle( $style ); - $css['th.style' . $index] = $this->_createCSSStyle( $style ); + $css['td.style' . $index] = $this->_createCSSStyle($style); + $css['th.style' . $index] = $this->_createCSSStyle($style); } // Fetch sheets @@ -792,7 +840,7 @@ public function buildCSS($generateSurroundingHTML = true) { // col elements, initialize $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()) - 1; $column = -1; - while($column++ < $highestColumnIndex) { + while ($column++ < $highestColumnIndex) { $this->_columnWidths[$sheetIndex][$column] = 42; // approximation $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = '42pt'; } @@ -864,16 +912,17 @@ public function buildCSS($generateSurroundingHTML = true) { * @param PHPExcel_Style $pStyle PHPExcel_Style * @return array */ - private function _createCSSStyle(PHPExcel_Style $pStyle) { + private function _createCSSStyle(PHPExcel_Style $pStyle) + { // Construct CSS $css = ''; // Create CSS $css = array_merge( - $this->_createCSSStyleAlignment($pStyle->getAlignment()) - , $this->_createCSSStyleBorders($pStyle->getBorders()) - , $this->_createCSSStyleFont($pStyle->getFont()) - , $this->_createCSSStyleFill($pStyle->getFill()) + $this->_createCSSStyleAlignment($pStyle->getAlignment()), + $this->_createCSSStyleBorders($pStyle->getBorders()), + $this->_createCSSStyleFont($pStyle->getFont()), + $this->_createCSSStyleFill($pStyle->getFill()) ); // Return @@ -886,7 +935,8 @@ private function _createCSSStyle(PHPExcel_Style $pStyle) { * @param PHPExcel_Style_Alignment $pStyle PHPExcel_Style_Alignment * @return array */ - private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) { + private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) + { // Construct CSS $css = array(); @@ -894,11 +944,11 @@ private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) { $css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical()); if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) { $css['text-align'] = $textAlign; - if(in_array($textAlign,array('left','right'))) + if (in_array($textAlign,array('left','right'))) { $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px'; + } } - // Return return $css; } @@ -908,7 +958,8 @@ private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) { * @param PHPExcel_Style_Font $pStyle PHPExcel_Style_Font * @return array */ - private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) { + private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) + { // Construct CSS $css = array(); @@ -918,20 +969,19 @@ private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) { } if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) { $css['text-decoration'] = 'underline line-through'; - } else if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE) { + } elseif ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE) { $css['text-decoration'] = 'underline'; - } else if ($pStyle->getStrikethrough()) { + } elseif ($pStyle->getStrikethrough()) { $css['text-decoration'] = 'line-through'; } if ($pStyle->getItalic()) { $css['font-style'] = 'italic'; } - $css['color'] = '#' . $pStyle->getColor()->getRGB(); - $css['font-family'] = '\'' . $pStyle->getName() . '\''; - $css['font-size'] = $pStyle->getSize() . 'pt'; + $css['color'] = '#' . $pStyle->getColor()->getRGB(); + $css['font-family'] = '\'' . $pStyle->getName() . '\''; + $css['font-size'] = $pStyle->getSize() . 'pt'; - // Return return $css; } @@ -941,17 +991,17 @@ private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) { * @param PHPExcel_Style_Borders $pStyle PHPExcel_Style_Borders * @return array */ - private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) { + private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) + { // Construct CSS $css = array(); // Create CSS - $css['border-bottom'] = $this->_createCSSStyleBorder($pStyle->getBottom()); - $css['border-top'] = $this->_createCSSStyleBorder($pStyle->getTop()); - $css['border-left'] = $this->_createCSSStyleBorder($pStyle->getLeft()); - $css['border-right'] = $this->_createCSSStyleBorder($pStyle->getRight()); + $css['border-bottom'] = $this->_createCSSStyleBorder($pStyle->getBottom()); + $css['border-top'] = $this->_createCSSStyleBorder($pStyle->getTop()); + $css['border-left'] = $this->_createCSSStyleBorder($pStyle->getLeft()); + $css['border-right'] = $this->_createCSSStyleBorder($pStyle->getRight()); - // Return return $css; } @@ -961,14 +1011,14 @@ private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) { * @param PHPExcel_Style_Border $pStyle PHPExcel_Style_Border * @return string */ - private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) { + private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) + { // Create CSS // $css = $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); // Create CSS - add !important to non-none border styles for merged cells - $borderStyle = $this->_mapBorderStyle($pStyle->getBorderStyle()); - $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); + $borderStyle = $this->_mapBorderStyle($pStyle->getBorderStyle()); + $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); - // Return return $css; } @@ -978,7 +1028,8 @@ private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) { * @param PHPExcel_Style_Fill $pStyle PHPExcel_Style_Fill * @return array */ - private function _createCSSStyleFill(PHPExcel_Style_Fill $pStyle) { + private function _createCSSStyleFill(PHPExcel_Style_Fill $pStyle) + { // Construct HTML $css = array(); @@ -987,20 +1038,19 @@ private function _createCSSStyleFill(PHPExcel_Style_Fill $pStyle) { 'white' : '#' . $pStyle->getStartColor()->getRGB(); $css['background-color'] = $value; - // Return return $css; } /** * Generate HTML footer */ - public function generateHTMLFooter() { + public function generateHTMLFooter() + { // Construct HTML $html = ''; $html .= ' </body>' . PHP_EOL; $html .= '</html>' . PHP_EOL; - // Return return $html; } @@ -1011,7 +1061,8 @@ public function generateHTMLFooter() { * @return string * @throws PHPExcel_Writer_Exception */ - private function _generateTableHeader($pSheet) { + private function _generateTableHeader($pSheet) + { $sheetIndex = $pSheet->getParent()->getIndex($pSheet); // Construct HTML @@ -1035,7 +1086,7 @@ private function _generateTableHeader($pSheet) { // Write <col> elements $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()) - 1; $i = -1; - while($i++ < $highestColumnIndex) { + while ($i++ < $highestColumnIndex) { if (!$this->_isPdf) { if (!$this->_useInlineCss) { $html .= ' <col class="col' . $i . '">' . PHP_EOL; @@ -1047,7 +1098,6 @@ private function _generateTableHeader($pSheet) { } } - // Return return $html; } @@ -1056,12 +1106,10 @@ private function _generateTableHeader($pSheet) { * * @throws PHPExcel_Writer_Exception */ - private function _generateTableFooter() { - // Construct HTML - $html = ''; - $html .= ' </table>' . PHP_EOL; + private function _generateTableFooter() + { + $html = ' </table>' . PHP_EOL; - // Return return $html; } @@ -1074,7 +1122,8 @@ private function _generateTableFooter() { * @return string * @throws PHPExcel_Writer_Exception */ - private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td') { + private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td') + { if (is_array($pValues)) { // Construct HTML $html = ''; @@ -1152,7 +1201,7 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow if ($element->getFont()->getSuperScript()) { $cellData .= '<sup>'; - } else if ($element->getFont()->getSubScript()) { + } elseif ($element->getFont()->getSubScript()) { $cellData .= '<sub>'; } } @@ -1164,7 +1213,7 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow if ($element instanceof PHPExcel_RichText_Run) { if ($element->getFont()->getSuperScript()) { $cellData .= '</sup>'; - } else if ($element->getFont()->getSubScript()) { + } elseif ($element->getFont()->getSubScript()) { $cellData .= '</sub>'; } @@ -1175,20 +1224,20 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow if ($this->_preCalculateFormulas) { $cellData = PHPExcel_Style_NumberFormat::toFormattedString( $cell->getCalculatedValue(), - $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), + $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(), array($this, 'formatColor') ); } else { $cellData = PHPExcel_Style_NumberFormat::toFormattedString( $cell->getValue(), - $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), + $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(), array($this, 'formatColor') ); } $cellData = htmlspecialchars($cellData); - if ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSuperScript()) { + if ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSuperScript()) { $cellData = '<sup>'.$cellData.'</sup>'; - } elseif ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSubScript()) { + } elseif ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSubScript()) { $cellData = '<sub>'.$cellData.'</sub>'; } } @@ -1231,8 +1280,8 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow } // Should the cell be written or is it swallowed by a rowspan or colspan? - $writeCell = ! ( isset($this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]) - && $this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum] ); + $writeCell = !(isset($this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]) + && $this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]); // Colspan and Rowspan $colspan = 1; @@ -1263,7 +1312,7 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow $width = 0; $i = $colNum - 1; $e = $colNum + $colSpan - 1; - while($i++ < $e) { + while ($i++ < $e) { if (isset($this->_columnWidths[$sheetIndex][$i])) { $width += $this->_columnWidths[$sheetIndex][$i]; } @@ -1286,7 +1335,7 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow if ($rowSpan > 1) { $html .= ' rowspan="' . $rowSpan . '"'; } - $html .= '>'; + $html .= '>'; // Image? $html .= $this->_writeImageInCell($pSheet, $coordinate); @@ -1339,7 +1388,8 @@ private function _assembleCSS($pValue = array()) * * @return string */ - public function getImagesRoot() { + public function getImagesRoot() + { return $this->_imagesRoot; } @@ -1349,7 +1399,8 @@ public function getImagesRoot() { * @param string $pValue * @return PHPExcel_Writer_HTML */ - public function setImagesRoot($pValue = '.') { + public function setImagesRoot($pValue = '.') + { $this->_imagesRoot = $pValue; return $this; } @@ -1359,7 +1410,8 @@ public function setImagesRoot($pValue = '.') { * * @return boolean */ - public function getEmbedImages() { + public function getEmbedImages() + { return $this->_embedImages; } @@ -1369,7 +1421,8 @@ public function getEmbedImages() { * @param boolean $pValue * @return PHPExcel_Writer_HTML */ - public function setEmbedImages($pValue = '.') { + public function setEmbedImages($pValue = '.') + { $this->_embedImages = $pValue; return $this; } @@ -1379,7 +1432,8 @@ public function setEmbedImages($pValue = '.') { * * @return boolean */ - public function getUseInlineCss() { + public function getUseInlineCss() + { return $this->_useInlineCss; } @@ -1389,7 +1443,8 @@ public function getUseInlineCss() { * @param boolean $pValue * @return PHPExcel_Writer_HTML */ - public function setUseInlineCss($pValue = false) { + public function setUseInlineCss($pValue = false) + { $this->_useInlineCss = $pValue; return $this; } @@ -1515,7 +1570,8 @@ private function _calculateSpans() $this->_spansAreCalculated = true; } - private function _setMargins(PHPExcel_Worksheet $pSheet) { + private function _setMargins(PHPExcel_Worksheet $pSheet) + { $htmlPage = '@page { '; $htmlBody = 'body { '; @@ -1537,5 +1593,4 @@ private function _setMargins(PHPExcel_Worksheet $pSheet) { return "<style>\n" . $htmlPage . $htmlBody . "</style>\n"; } - } From 61b5fa0beb2f6ead1a520e9404bc1f5660dfb1cd Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Tue, 12 May 2015 11:22:06 +0200 Subject: [PATCH 352/467] Validation PSR-2 : Tabs to spaces --- Classes/PHPExcel/Calculation.php | 7680 ++++++++--------- Classes/PHPExcel/DocumentSecurity.php | 24 +- Classes/PHPExcel/Helper/HTML.php | 18 +- Classes/PHPExcel/Reader/Excel2007/Chart.php | 974 +-- Classes/PHPExcel/Reader/Excel2007/Theme.php | 114 +- Classes/PHPExcel/Reader/Excel5/Escher.php | 1110 +-- Classes/PHPExcel/Reader/Excel5/RC4.php | 98 +- Classes/PHPExcel/Shared/CodePage.php | 134 +- Classes/PHPExcel/Shared/Date.php | 684 +- Classes/PHPExcel/Shared/Drawing.php | 290 +- Classes/PHPExcel/Shared/Escher.php | 98 +- .../PHPExcel/Shared/Escher/DgContainer.php | 76 +- .../Escher/DgContainer/SpgrContainer.php | 130 +- .../DgContainer/SpgrContainer/SpContainer.php | 718 +- .../PHPExcel/Shared/Escher/DggContainer.php | 334 +- .../Escher/DggContainer/BstoreContainer.php | 52 +- .../DggContainer/BstoreContainer/BSE.php | 150 +- .../DggContainer/BstoreContainer/BSE/Blip.php | 98 +- Classes/PHPExcel/Shared/Excel5.php | 560 +- Classes/PHPExcel/Shared/File.php | 280 +- Classes/PHPExcel/Shared/Font.php | 1428 +-- .../Shared/JAMA/CholeskyDecomposition.php | 280 +- .../Shared/JAMA/EigenvalueDecomposition.php | 1706 ++-- .../PHPExcel/Shared/JAMA/LUDecomposition.php | 454 +- Classes/PHPExcel/Shared/JAMA/Matrix.php | 2082 ++--- .../PHPExcel/Shared/JAMA/QRDecomposition.php | 452 +- .../JAMA/SingularValueDecomposition.php | 1034 +-- Classes/PHPExcel/Shared/JAMA/utils/Error.php | 34 +- Classes/PHPExcel/Shared/JAMA/utils/Maths.php | 58 +- Classes/PHPExcel/Shared/OLE.php | 982 +-- .../Shared/OLE/ChainedBlockStream.php | 366 +- Classes/PHPExcel/Shared/OLE/PPS.php | 396 +- Classes/PHPExcel/Shared/OLE/PPS/File.php | 100 +- Classes/PHPExcel/Shared/OLE/PPS/Root.php | 814 +- Classes/PHPExcel/Shared/OLERead.php | 522 +- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 318 +- Classes/PHPExcel/Shared/PasswordHasher.php | 38 +- Classes/PHPExcel/Shared/String.php | 1500 ++-- Classes/PHPExcel/Shared/TimeZone.php | 187 +- Classes/PHPExcel/Shared/XMLWriter.php | 154 +- Classes/PHPExcel/Shared/ZipArchive.php | 103 +- Classes/PHPExcel/Shared/ZipStreamWrapper.php | 82 +- .../PHPExcel/Shared/trend/bestFitClass.php | 782 +- .../Shared/trend/exponentialBestFitClass.php | 218 +- .../Shared/trend/linearBestFitClass.php | 144 +- .../Shared/trend/logarithmicBestFitClass.php | 162 +- .../Shared/trend/polynomialBestFitClass.php | 368 +- .../Shared/trend/powerBestFitClass.php | 206 +- Classes/PHPExcel/Shared/trend/trendClass.php | 212 +- Classes/PHPExcel/Worksheet/AutoFilter.php | 1612 ++-- .../PHPExcel/Worksheet/AutoFilter/Column.php | 726 +- .../Worksheet/AutoFilter/Column/Rule.php | 866 +- Classes/PHPExcel/Worksheet/BaseDrawing.php | 466 +- .../PHPExcel/Worksheet/ColumnDimension.php | 2 +- Classes/PHPExcel/Worksheet/Drawing.php | 118 +- Classes/PHPExcel/Worksheet/Drawing/Shadow.php | 232 +- Classes/PHPExcel/Worksheet/HeaderFooter.php | 302 +- .../Worksheet/HeaderFooterDrawing.php | 306 +- Classes/PHPExcel/Worksheet/MemoryDrawing.php | 188 +- Classes/PHPExcel/Worksheet/PageMargins.php | 146 +- Classes/PHPExcel/Worksheet/PageSetup.php | 1256 +-- Classes/PHPExcel/Worksheet/Protection.php | 412 +- Classes/PHPExcel/Worksheet/SheetView.php | 284 +- .../PHPExcel/Writer/Excel2007/WriterPart.php | 2 +- .../Writer/OpenDocument/Cell/Comment.php | 2 +- .../PHPExcel/Writer/OpenDocument/Content.php | 2 +- composer.json | 2 +- 67 files changed, 17862 insertions(+), 17866 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 6f0f3a896..34db7738a 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -21,3932 +21,3932 @@ * @category PHPExcel * @package PHPExcel_Calculation * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } if (!defined('CALCULATION_REGEXP_CELLREF')) { - // Test for support of \P (multibyte options) in PCRE - if(defined('PREG_BAD_UTF8_ERROR')) { - // Cell reference (cell or range of cells, with or without a sheet reference) - define('CALCULATION_REGEXP_CELLREF','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})'); - // Named Range of cells - define('CALCULATION_REGEXP_NAMEDRANGE','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)'); - } else { - // Cell reference (cell or range of cells, with or without a sheet reference) - define('CALCULATION_REGEXP_CELLREF','(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)'); - // Named Range of cells - define('CALCULATION_REGEXP_NAMEDRANGE','(((\w*)|(\'.*\')|(\".*\"))!)?([_A-Z][_A-Z0-9\.]*)'); - } + // Test for support of \P (multibyte options) in PCRE + if(defined('PREG_BAD_UTF8_ERROR')) { + // Cell reference (cell or range of cells, with or without a sheet reference) + define('CALCULATION_REGEXP_CELLREF','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})'); + // Named Range of cells + define('CALCULATION_REGEXP_NAMEDRANGE','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)'); + } else { + // Cell reference (cell or range of cells, with or without a sheet reference) + define('CALCULATION_REGEXP_CELLREF','(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)'); + // Named Range of cells + define('CALCULATION_REGEXP_NAMEDRANGE','(((\w*)|(\'.*\')|(\".*\"))!)?([_A-Z][_A-Z0-9\.]*)'); + } } /** * PHPExcel_Calculation (Multiton) * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation { - /** Constants */ - /** Regular Expressions */ - // Numeric operand - const CALCULATION_REGEXP_NUMBER = '[-+]?\d*\.?\d+(e[-+]?\d+)?'; - // String operand - const CALCULATION_REGEXP_STRING = '"(?:[^"]|"")*"'; - // Opening bracket - const CALCULATION_REGEXP_OPENBRACE = '\('; - // Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it) - const CALCULATION_REGEXP_FUNCTION = '@?([A-Z][A-Z0-9\.]*)[\s]*\('; - // Cell reference (cell or range of cells, with or without a sheet reference) - const CALCULATION_REGEXP_CELLREF = CALCULATION_REGEXP_CELLREF; - // Named Range of cells - const CALCULATION_REGEXP_NAMEDRANGE = CALCULATION_REGEXP_NAMEDRANGE; - // Error - const CALCULATION_REGEXP_ERROR = '\#[A-Z][A-Z0_\/]*[!\?]?'; - - - /** constants */ - const RETURN_ARRAY_AS_ERROR = 'error'; - const RETURN_ARRAY_AS_VALUE = 'value'; - const RETURN_ARRAY_AS_ARRAY = 'array'; - - private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; - - - /** - * Instance of this class - * - * @access private - * @var PHPExcel_Calculation - */ - private static $_instance; - - - /** - * Instance of the workbook this Calculation Engine is using - * - * @access private - * @var PHPExcel - */ + /** Constants */ + /** Regular Expressions */ + // Numeric operand + const CALCULATION_REGEXP_NUMBER = '[-+]?\d*\.?\d+(e[-+]?\d+)?'; + // String operand + const CALCULATION_REGEXP_STRING = '"(?:[^"]|"")*"'; + // Opening bracket + const CALCULATION_REGEXP_OPENBRACE = '\('; + // Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it) + const CALCULATION_REGEXP_FUNCTION = '@?([A-Z][A-Z0-9\.]*)[\s]*\('; + // Cell reference (cell or range of cells, with or without a sheet reference) + const CALCULATION_REGEXP_CELLREF = CALCULATION_REGEXP_CELLREF; + // Named Range of cells + const CALCULATION_REGEXP_NAMEDRANGE = CALCULATION_REGEXP_NAMEDRANGE; + // Error + const CALCULATION_REGEXP_ERROR = '\#[A-Z][A-Z0_\/]*[!\?]?'; + + + /** constants */ + const RETURN_ARRAY_AS_ERROR = 'error'; + const RETURN_ARRAY_AS_VALUE = 'value'; + const RETURN_ARRAY_AS_ARRAY = 'array'; + + private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; + + + /** + * Instance of this class + * + * @access private + * @var 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 for individual workbooks - * - * @access private - * @var PHPExcel_Calculation[] - */ + /** + * List of instances of the calculation engine that we've instantiated for individual workbooks + * + * @access private + * @var PHPExcel_Calculation[] + */ private static $_workbookSets; - /** - * Calculation cache - * - * @access private - * @var array - */ - private $_calculationCache = array (); - - - /** - * Calculation cache enabled - * - * @access private - * @var boolean - */ - private $_calculationCacheEnabled = TRUE; - - - /** - * List of operators that can be used within formulae - * The true/false value indicates whether it is a binary operator or a unary operator - * - * @access private - * @var array - */ - private static $_operators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, - '^' => TRUE, '&' => TRUE, '%' => FALSE, '~' => FALSE, - '>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, - '<=' => TRUE, '<>' => TRUE, '|' => TRUE, ':' => TRUE - ); - - - /** - * List of binary operators (those that expect two operands) - * - * @access private - * @var array - */ - private static $_binaryOperators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, - '^' => TRUE, '&' => TRUE, '>' => TRUE, '<' => TRUE, - '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE, - '|' => TRUE, ':' => TRUE - ); - - /** - * The debug log generated by the calculation engine - * - * @access private - * @var PHPExcel_CalcEngine_Logger - * - */ - private $debugLog; - - /** - * Flag to determine how formula errors should be handled - * If true, then a user error will be triggered - * If false, then an exception will be thrown - * - * @access public - * @var boolean - * - */ - public $suppressFormulaErrors = FALSE; - - /** - * Error message for any error that was raised/thrown by the calculation engine - * - * @access public - * @var string - * - */ - public $formulaError = NULL; - - /** - * An array of the nested cell references accessed by the calculation engine, used for the debug log - * - * @access private - * @var array of string - * - */ - private $_cyclicReferenceStack; - - private $_cellStack = array(); - - /** - * Current iteration counter for cyclic formulae - * If the value is 0 (or less) then cyclic formulae will throw an exception, - * otherwise they will iterate to the limit defined here before returning a result - * - * @var integer - * - */ - private $_cyclicFormulaCount = 1; - - private $_cyclicFormulaCell = ''; - - /** - * Number of iterations for cyclic formulae - * - * @var integer - * - */ - public $cyclicFormulaCount = 1; - - /** - * Precision used for calculations - * - * @var integer - * - */ - private $_savedPrecision = 14; - - - /** - * The current locale setting - * - * @var string - * - */ - private static $_localeLanguage = 'en_us'; // US English (default locale) - - /** - * List of available locale settings - * Note that this is read for the locale subdirectory only when requested - * - * @var string[] - * - */ - private static $_validLocaleLanguages = array( 'en' // English (default language) - ); - /** - * Locale-specific argument separator for function arguments - * - * @var string - * - */ - private static $_localeArgumentSeparator = ','; - private static $_localeFunctions = array(); - - /** - * Locale-specific translations for Excel constants (True, False and Null) - * - * @var string[] - * - */ - public static $_localeBoolean = array( 'TRUE' => 'TRUE', - 'FALSE' => 'FALSE', - 'NULL' => 'NULL' - ); - - - /** - * Excel constant string translations to their PHP equivalents - * Constant conversion from text name/value to actual (datatyped) value - * - * @var string[] - * - */ - private static $_ExcelConstants = array('TRUE' => TRUE, - 'FALSE' => FALSE, - 'NULL' => NULL - ); - - // PHPExcel functions - private static $_PHPExcelFunctions = array( // PHPExcel functions - 'ABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'abs', - 'argumentCount' => '1' - ), - 'ACCRINT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', - 'argumentCount' => '4-7' - ), - 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', - 'argumentCount' => '3-5' - ), - 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'acos', - 'argumentCount' => '1' - ), - 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'acosh', - 'argumentCount' => '1' - ), - 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', - 'argumentCount' => '2-5' - ), - 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', - 'argumentCount' => '6,7' - ), - 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', - 'argumentCount' => '6,7' - ), - 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', - 'argumentCount' => '1+' - ), - 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'asin', - 'argumentCount' => '1' - ), - 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'asinh', - 'argumentCount' => '1' - ), - 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'atan', - 'argumentCount' => '1' - ), - 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', - 'argumentCount' => '2' - ), - 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'atanh', - 'argumentCount' => '1' - ), - 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', - 'argumentCount' => '1+' - ), - 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', - 'argumentCount' => '1+' - ), - 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', - 'argumentCount' => '1+' - ), - 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', - 'argumentCount' => '2,3' - ), - 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3+' - ), - 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', - 'argumentCount' => '2' - ), - 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', - 'argumentCount' => '2' - ), - 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', - 'argumentCount' => '2' - ), - 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', - 'argumentCount' => '2' - ), - 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', - 'argumentCount' => '3-5' - ), - 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', - 'argumentCount' => '3-5' - ), - 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', - 'argumentCount' => '1' - ), - 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', - 'argumentCount' => '1,2' - ), - 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', - 'argumentCount' => '1,2' - ), - 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', - 'argumentCount' => '4' - ), - 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', - 'argumentCount' => '2' - ), - 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1,2' - ), - 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', - 'argumentCount' => '1' - ), - 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', - 'argumentCount' => '2' - ), - 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', - 'argumentCount' => '2' - ), - 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', - 'argumentCount' => '2+' - ), - 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', - 'argumentCount' => '1' - ), - 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', - 'argumentCount' => '1' - ), - 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', - 'argumentCount' => '-1', - 'passByReference' => array(TRUE) - ), - 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', - 'argumentCount' => '1' - ), - 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', - 'argumentCount' => '2' - ), - 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', - 'argumentCount' => '2,3' - ), - 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', - 'argumentCount' => '1+' - ), - 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', - 'argumentCount' => '3' - ), - 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', - 'argumentCount' => '3' - ), - 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', - 'argumentCount' => '2' - ), - 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'cos', - 'argumentCount' => '1' - ), - 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'cosh', - 'argumentCount' => '1' - ), - 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', - 'argumentCount' => '1+' - ), - 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', - 'argumentCount' => '1+' - ), - 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', - 'argumentCount' => '1' - ), - 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', - 'argumentCount' => '2' - ), - 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', - 'argumentCount' => '3,4' - ), - 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', - 'argumentCount' => '3,4' - ), - 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', - 'argumentCount' => '3,4' - ), - 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', - 'argumentCount' => '3,4' - ), - 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', - 'argumentCount' => '3,4' - ), - 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', - 'argumentCount' => '3,4' - ), - 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', - 'argumentCount' => '2' - ), - 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', - 'argumentCount' => '3' - ), - 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', - 'argumentCount' => '6' - ), - 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', - 'argumentCount' => '6' - ), - 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', - 'argumentCount' => '3' - ), - 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', - 'argumentCount' => '2,3' - ), - 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', - 'argumentCount' => '1' - ), - 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', - 'argumentCount' => '3' - ), - 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', - 'argumentCount' => '1' - ), - 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', - 'argumentCount' => '2,3' - ), - 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DB', - 'argumentCount' => '4,5' - ), - 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', - 'argumentCount' => '3' - ), - 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', - 'argumentCount' => '3' - ), - 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', - 'argumentCount' => '4,5' - ), - 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', - 'argumentCount' => '1,2' - ), - 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', - 'argumentCount' => '1,2' - ), - 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', - 'argumentCount' => '1,2' - ), - 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'rad2deg', - 'argumentCount' => '1' - ), - 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', - 'argumentCount' => '1,2' - ), - 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', - 'argumentCount' => '1+' - ), - 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DGET', - 'argumentCount' => '3' - ), - 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', - 'argumentCount' => '4,5' - ), - 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', - 'argumentCount' => '3' - ), - 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', - 'argumentCount' => '3' - ), - 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', - 'argumentCount' => '1,2' - ), - 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', - 'argumentCount' => '2' - ), - 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', - 'argumentCount' => '2' - ), - 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', - 'argumentCount' => '3' - ), - 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', - 'argumentCount' => '3' - ), - 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', - 'argumentCount' => '3' - ), - 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', - 'argumentCount' => '3' - ), - 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5,6' - ), - 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', - 'argumentCount' => '3' - ), - 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', - 'argumentCount' => '3' - ), - 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', - 'argumentCount' => '2' - ), - 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', - 'argumentCount' => '2' - ), - 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', - 'argumentCount' => '2' - ), - 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', - 'argumentCount' => '1,2' - ), - 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', - 'argumentCount' => '1' - ), - 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', - 'argumentCount' => '1' - ), - 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', - 'argumentCount' => '1' - ), - 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'exp', - 'argumentCount' => '1' - ), - 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', - 'argumentCount' => '3' - ), - 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', - 'argumentCount' => '1' - ), - 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', - 'argumentCount' => '1' - ), - 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', - 'argumentCount' => '0' - ), - 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3' - ), - 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', - 'argumentCount' => '2,3' - ), - 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', - 'argumentCount' => '2,3' - ), - 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3' - ), - 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', - 'argumentCount' => '1' - ), - 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', - 'argumentCount' => '1' - ), - 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', - 'argumentCount' => '1-3' - ), - 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', - 'argumentCount' => '2' - ), - 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', - 'argumentCount' => '3' - ), - 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::FV', - 'argumentCount' => '3-5' - ), - 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', - 'argumentCount' => '2' - ), - 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', - 'argumentCount' => '4' - ), - 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', - 'argumentCount' => '3' - ), - 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', - 'argumentCount' => '1' - ), - 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', - 'argumentCount' => '1+' - ), - 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', - 'argumentCount' => '1+' - ), - 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', - 'argumentCount' => '1,2' - ), - 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2+' - ), - 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', - 'argumentCount' => '1-4' - ), - 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', - 'argumentCount' => '1+' - ), - 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', - 'argumentCount' => '1,2' - ), - 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', - 'argumentCount' => '1' - ), - 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', - 'argumentCount' => '1,2' - ), - 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', - 'argumentCount' => '3,4' - ), - 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', - 'argumentCount' => '1' - ), - 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', - 'argumentCount' => '1,2', - 'passCellReference'=> TRUE - ), - 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', - 'argumentCount' => '4' - ), - 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', - 'argumentCount' => '1-3' - ), - 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', - 'argumentCount' => '2' - ), - 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', - 'argumentCount' => '1' - ), - 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', - 'argumentCount' => '1' - ), - 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', - 'argumentCount' => '1' - ), - 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', - 'argumentCount' => '1' - ), - 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', - 'argumentCount' => '1' - ), - 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', - 'argumentCount' => '2' - ), - 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', - 'argumentCount' => '1' - ), - 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', - 'argumentCount' => '1' - ), - 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', - 'argumentCount' => '1' - ), - 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', - 'argumentCount' => '1' - ), - 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', - 'argumentCount' => '2' - ), - 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', - 'argumentCount' => '1+' - ), - 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', - 'argumentCount' => '1' - ), - 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', - 'argumentCount' => '1' - ), - 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', - 'argumentCount' => '1' - ), - 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', - 'argumentCount' => '2' - ), - 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', - 'argumentCount' => '1+' - ), - 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', - 'argumentCount' => '1-4' - ), - 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', - 'argumentCount' => '1,2', - 'passCellReference'=> TRUE - ), - 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', - 'argumentCount' => '1' - ), - 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', - 'argumentCount' => '2' - ), - 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', - 'argumentCount' => '4,5' - ), - 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', - 'argumentCount' => '4-6' - ), - 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', - 'argumentCount' => '1,2' - ), - 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', - 'argumentCount' => '1' - ), - 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', - 'argumentCount' => '1' - ), - 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', - 'argumentCount' => '1' - ), - 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', - 'argumentCount' => '1' - ), - 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', - 'argumentCount' => '1' - ), - 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', - 'argumentCount' => '1' - ), - 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', - 'argumentCount' => '1' - ), - 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', - 'argumentCount' => '1' - ), - 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', - 'argumentCount' => '1' - ), - 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', - 'argumentCount' => '4' - ), - 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', - 'argumentCount' => '1' - ), - 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', - 'argumentCount' => '1+' - ), - 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', - 'argumentCount' => '2' - ), - 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', - 'argumentCount' => '1+' - ), - 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', - 'argumentCount' => '1,2' - ), - 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', - 'argumentCount' => '1,2' - ), - 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', - 'argumentCount' => '1' - ), - 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', - 'argumentCount' => '1' - ), - 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', - 'argumentCount' => '1-4' - ), - 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'log', - 'argumentCount' => '1' - ), - 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', - 'argumentCount' => '1,2' - ), - 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'log10', - 'argumentCount' => '1' - ), - 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', - 'argumentCount' => '1-4' - ), - 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', - 'argumentCount' => '3' - ), - 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', - 'argumentCount' => '3' - ), - 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', - 'argumentCount' => '2,3' - ), - 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', - 'argumentCount' => '1' - ), - 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', - 'argumentCount' => '2,3' - ), - 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', - 'argumentCount' => '1+' - ), - 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', - 'argumentCount' => '1+' - ), - 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', - 'argumentCount' => '2+' - ), - 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', - 'argumentCount' => '1' - ), - 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5,6' - ), - 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', - 'argumentCount' => '1+' - ), - 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2+' - ), - 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::MID', - 'argumentCount' => '3' - ), - 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::MID', - 'argumentCount' => '3' - ), - 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', - 'argumentCount' => '1+' - ), - 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', - 'argumentCount' => '1+' - ), - 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', - 'argumentCount' => '2+' - ), - 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', - 'argumentCount' => '1' - ), - 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', - 'argumentCount' => '1' - ), - 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', - 'argumentCount' => '3' - ), - 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', - 'argumentCount' => '2' - ), - 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', - 'argumentCount' => '2' - ), - 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', - 'argumentCount' => '1+' - ), - 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', - 'argumentCount' => '1' - ), - 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', - 'argumentCount' => '2' - ), - 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', - 'argumentCount' => '1+' - ), - 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::N', - 'argumentCount' => '1' - ), - 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::NA', - 'argumentCount' => '0' - ), - 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', - 'argumentCount' => '3' - ), - 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', - 'argumentCount' => '2+' - ), - 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', - 'argumentCount' => '2' - ), - 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', - 'argumentCount' => '4' - ), - 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', - 'argumentCount' => '3' - ), - 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', - 'argumentCount' => '1' - ), - 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', - 'argumentCount' => '1' - ), - 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', - 'argumentCount' => '1' - ), - 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', - 'argumentCount' => '0' - ), - 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', - 'argumentCount' => '3-5' - ), - 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', - 'argumentCount' => '2+' - ), - 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', - 'argumentCount' => '1,2' - ), - 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', - 'argumentCount' => '1' - ), - 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', - 'argumentCount' => '1,2' - ), - 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', - 'argumentCount' => '1' - ), - 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '8,9' - ), - 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '8,9' - ), - 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '7,8' - ), - 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '7,8' - ), - 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', - 'argumentCount' => '3,5', - 'passCellReference'=> TRUE, - 'passByReference' => array(TRUE) - ), - 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', - 'argumentCount' => '1+' - ), - 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', - 'argumentCount' => '2' - ), - 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', - 'argumentCount' => '2' - ), - 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', - 'argumentCount' => '2,3' - ), - 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', - 'argumentCount' => '2' - ), - 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'pi', - 'argumentCount' => '0' - ), - 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', - 'argumentCount' => '3-5' - ), - 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', - 'argumentCount' => '3' - ), - 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', - 'argumentCount' => '2' - ), - 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', - 'argumentCount' => '4-6' - ), - 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', - 'argumentCount' => '6,7' - ), - 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', - 'argumentCount' => '4,5' - ), - 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', - 'argumentCount' => '5,6' - ), - 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3,4' - ), - 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', - 'argumentCount' => '1+' - ), - 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', - 'argumentCount' => '1' - ), - 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PV', - 'argumentCount' => '3-5' - ), - 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', - 'argumentCount' => '2' - ), - 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', - 'argumentCount' => '2' - ), - 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'deg2rad', - 'argumentCount' => '1' - ), - 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', - 'argumentCount' => '0' - ), - 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', - 'argumentCount' => '2' - ), - 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', - 'argumentCount' => '2,3' - ), - 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', - 'argumentCount' => '3-6' - ), - 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', - 'argumentCount' => '4-5' - ), - 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', - 'argumentCount' => '4' - ), - 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', - 'argumentCount' => '4' - ), - 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'str_repeat', - 'argumentCount' => '2' - ), - 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', - 'argumentCount' => '1,2' - ), - 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', - 'argumentCount' => '1,2' - ), - 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', - 'argumentCount' => '1,2' - ), - 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'round', - 'argumentCount' => '2' - ), - 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', - 'argumentCount' => '2' - ), - 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', - 'argumentCount' => '2' - ), - 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', - 'argumentCount' => '-1', - 'passByReference' => array(TRUE) - ), - 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', - 'argumentCount' => '1' - ), - 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', - 'argumentCount' => '2' - ), - 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1+' - ), - 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', - 'argumentCount' => '2,3' - ), - 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', - 'argumentCount' => '2,3' - ), - 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', - 'argumentCount' => '1' - ), - 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', - 'argumentCount' => '4' - ), - 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', - 'argumentCount' => '1' - ), - 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sin', - 'argumentCount' => '1' - ), - 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sinh', - 'argumentCount' => '1' - ), - 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', - 'argumentCount' => '1+' - ), - 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', - 'argumentCount' => '3' - ), - 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', - 'argumentCount' => '2' - ), - 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', - 'argumentCount' => '2' - ), - 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sqrt', - 'argumentCount' => '1' - ), - 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', - 'argumentCount' => '1' - ), - 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', - 'argumentCount' => '3' - ), - 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', - 'argumentCount' => '1+' - ), - 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', - 'argumentCount' => '1+' - ), - 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', - 'argumentCount' => '1+' - ), - 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', - 'argumentCount' => '1+' - ), - 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', - 'argumentCount' => '2' - ), - 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', - 'argumentCount' => '3,4' - ), - 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', - 'argumentCount' => '2+' - ), - 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', - 'argumentCount' => '1+' - ), - 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', - 'argumentCount' => '2,3' - ), - 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', - 'argumentCount' => '1+' - ), - 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', - 'argumentCount' => '1+' - ), - 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', - 'argumentCount' => '2' - ), - 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', - 'argumentCount' => '2' - ), - 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', - 'argumentCount' => '2' - ), - 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', - 'argumentCount' => '4' - ), - 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', - 'argumentCount' => '1' - ), - 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'tan', - 'argumentCount' => '1' - ), - 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'tanh', - 'argumentCount' => '1' - ), - 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', - 'argumentCount' => '3' - ), - 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', - 'argumentCount' => '3' - ), - 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', - 'argumentCount' => '3' - ), - 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', - 'argumentCount' => '3' - ), - 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', - 'argumentCount' => '2' - ), - 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', - 'argumentCount' => '3' - ), - 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', - 'argumentCount' => '1' - ), - 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', - 'argumentCount' => '2' - ), - 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', - 'argumentCount' => '0' - ), - 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', - 'argumentCount' => '1' - ), - 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', - 'argumentCount' => '1-4' - ), - 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', - 'argumentCount' => '1' - ), - 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', - 'argumentCount' => '2' - ), - 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', - 'argumentCount' => '0' - ), - 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', - 'argumentCount' => '1,2' - ), - 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '4' - ), - 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', - 'argumentCount' => '1' - ), - 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', - 'argumentCount' => '1' - ), - 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', - 'argumentCount' => '1' - ), - 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', - 'argumentCount' => '1+' - ), - 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', - 'argumentCount' => '1+' - ), - 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', - 'argumentCount' => '1+' - ), - 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', - 'argumentCount' => '1+' - ), - 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5-7' - ), - 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', - 'argumentCount' => '0' - ), - 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', - 'argumentCount' => '3,4' - ), - 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', - 'argumentCount' => '1,2' - ), - 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', - 'argumentCount' => '1,2' - ), - 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', - 'argumentCount' => '4' - ), - 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', - 'argumentCount' => '2+' - ), - 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', - 'argumentCount' => '2,3' - ), - 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', - 'argumentCount' => '3' - ), - 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', - 'argumentCount' => '1' - ), - 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', - 'argumentCount' => '2,3' - ), - 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '6,7' - ), - 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', - 'argumentCount' => '4,5' - ), - 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', - 'argumentCount' => '5,6' - ), - 'ZTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', - 'argumentCount' => '2-3' - ) - ); - - - // Internal functions used for special control purposes - private static $_controlFunctions = array( - 'MKMATRIX' => array('argumentCount' => '*', - 'functionCall' => 'self::_mkMatrix' - ) - ); - - - - - private function __construct(PHPExcel $workbook = NULL) { - $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; - $this->_savedPrecision = ini_get('precision'); - if ($this->_savedPrecision < $setPrecision) { - ini_set('precision',$setPrecision); - } - $this->delta = 1 * pow(10, -$setPrecision); - - if ($workbook !== NULL) { - self::$_workbookSets[$workbook->getID()] = $this; - } - - $this->_workbook = $workbook; - $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); - $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack); - } // function __construct() - - - public function __destruct() { - if ($this->_savedPrecision != ini_get('precision')) { - ini_set('precision',$this->_savedPrecision); - } - } - - private static function _loadLocales() { - $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/'; - foreach (glob($localeFileDirectory.'/*',GLOB_ONLYDIR) as $filename) { - $filename = substr($filename,strlen($localeFileDirectory)+1); - if ($filename != 'en') { - self::$_validLocaleLanguages[] = $filename; - } - } - } - - /** - * Get an instance of this class - * - * @access public - * @param PHPExcel $workbook Injected workbook for working with a PHPExcel object, - * or NULL to create a standalone claculation engine - * @return PHPExcel_Calculation - */ - 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(); - } - - return self::$_instance; - } // function getInstance() - - /** - * Unset an instance of this class - * - * @access public - * @param PHPExcel $workbook Injected workbook identifying the instance to unset - */ - public static function unsetInstance(PHPExcel $workbook = NULL) { - if ($workbook !== NULL) { - if (isset(self::$_workbookSets[$workbook->getID()])) { - unset(self::$_workbookSets[$workbook->getID()]); - } - } + /** + * Calculation cache + * + * @access private + * @var array + */ + private $_calculationCache = array (); + + + /** + * Calculation cache enabled + * + * @access private + * @var boolean + */ + private $_calculationCacheEnabled = TRUE; + + + /** + * List of operators that can be used within formulae + * The true/false value indicates whether it is a binary operator or a unary operator + * + * @access private + * @var array + */ + private static $_operators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, + '^' => TRUE, '&' => TRUE, '%' => FALSE, '~' => FALSE, + '>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, + '<=' => TRUE, '<>' => TRUE, '|' => TRUE, ':' => TRUE + ); + + + /** + * List of binary operators (those that expect two operands) + * + * @access private + * @var array + */ + private static $_binaryOperators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, + '^' => TRUE, '&' => TRUE, '>' => TRUE, '<' => TRUE, + '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE, + '|' => TRUE, ':' => TRUE + ); + + /** + * The debug log generated by the calculation engine + * + * @access private + * @var PHPExcel_CalcEngine_Logger + * + */ + private $debugLog; + + /** + * Flag to determine how formula errors should be handled + * If true, then a user error will be triggered + * If false, then an exception will be thrown + * + * @access public + * @var boolean + * + */ + public $suppressFormulaErrors = FALSE; + + /** + * Error message for any error that was raised/thrown by the calculation engine + * + * @access public + * @var string + * + */ + public $formulaError = NULL; + + /** + * An array of the nested cell references accessed by the calculation engine, used for the debug log + * + * @access private + * @var array of string + * + */ + private $_cyclicReferenceStack; + + private $_cellStack = array(); + + /** + * Current iteration counter for cyclic formulae + * If the value is 0 (or less) then cyclic formulae will throw an exception, + * otherwise they will iterate to the limit defined here before returning a result + * + * @var integer + * + */ + private $_cyclicFormulaCount = 1; + + private $_cyclicFormulaCell = ''; + + /** + * Number of iterations for cyclic formulae + * + * @var integer + * + */ + public $cyclicFormulaCount = 1; + + /** + * Precision used for calculations + * + * @var integer + * + */ + private $_savedPrecision = 14; + + + /** + * The current locale setting + * + * @var string + * + */ + private static $_localeLanguage = 'en_us'; // US English (default locale) + + /** + * List of available locale settings + * Note that this is read for the locale subdirectory only when requested + * + * @var string[] + * + */ + private static $_validLocaleLanguages = array( 'en' // English (default language) + ); + /** + * Locale-specific argument separator for function arguments + * + * @var string + * + */ + private static $_localeArgumentSeparator = ','; + private static $_localeFunctions = array(); + + /** + * Locale-specific translations for Excel constants (True, False and Null) + * + * @var string[] + * + */ + public static $_localeBoolean = array( 'TRUE' => 'TRUE', + 'FALSE' => 'FALSE', + 'NULL' => 'NULL' + ); + + + /** + * Excel constant string translations to their PHP equivalents + * Constant conversion from text name/value to actual (datatyped) value + * + * @var string[] + * + */ + private static $_ExcelConstants = array('TRUE' => TRUE, + 'FALSE' => FALSE, + 'NULL' => NULL + ); + + // PHPExcel functions + private static $_PHPExcelFunctions = array( // PHPExcel functions + 'ABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'abs', + 'argumentCount' => '1' + ), + 'ACCRINT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', + 'argumentCount' => '4-7' + ), + 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', + 'argumentCount' => '3-5' + ), + 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acos', + 'argumentCount' => '1' + ), + 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acosh', + 'argumentCount' => '1' + ), + 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', + 'argumentCount' => '2-5' + ), + 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', + 'argumentCount' => '6,7' + ), + 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', + 'argumentCount' => '6,7' + ), + 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', + 'argumentCount' => '1+' + ), + 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asin', + 'argumentCount' => '1' + ), + 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asinh', + 'argumentCount' => '1' + ), + 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atan', + 'argumentCount' => '1' + ), + 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', + 'argumentCount' => '2' + ), + 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atanh', + 'argumentCount' => '1' + ), + 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', + 'argumentCount' => '1+' + ), + 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', + 'argumentCount' => '1+' + ), + 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', + 'argumentCount' => '1+' + ), + 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', + 'argumentCount' => '2,3' + ), + 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3+' + ), + 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', + 'argumentCount' => '2' + ), + 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', + 'argumentCount' => '2' + ), + 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', + 'argumentCount' => '2' + ), + 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', + 'argumentCount' => '2' + ), + 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', + 'argumentCount' => '3-5' + ), + 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', + 'argumentCount' => '3-5' + ), + 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', + 'argumentCount' => '1' + ), + 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', + 'argumentCount' => '1,2' + ), + 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', + 'argumentCount' => '1,2' + ), + 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', + 'argumentCount' => '4' + ), + 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', + 'argumentCount' => '2' + ), + 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1,2' + ), + 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', + 'argumentCount' => '1' + ), + 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', + 'argumentCount' => '2' + ), + 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', + 'argumentCount' => '2' + ), + 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', + 'argumentCount' => '2+' + ), + 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', + 'argumentCount' => '1' + ), + 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', + 'argumentCount' => '1' + ), + 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', + 'argumentCount' => '-1', + 'passByReference' => array(TRUE) + ), + 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', + 'argumentCount' => '1' + ), + 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', + 'argumentCount' => '2' + ), + 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', + 'argumentCount' => '2,3' + ), + 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', + 'argumentCount' => '1+' + ), + 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', + 'argumentCount' => '3' + ), + 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', + 'argumentCount' => '3' + ), + 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cos', + 'argumentCount' => '1' + ), + 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cosh', + 'argumentCount' => '1' + ), + 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', + 'argumentCount' => '1+' + ), + 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', + 'argumentCount' => '1+' + ), + 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', + 'argumentCount' => '1' + ), + 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', + 'argumentCount' => '2' + ), + 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', + 'argumentCount' => '3,4' + ), + 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', + 'argumentCount' => '3,4' + ), + 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', + 'argumentCount' => '3,4' + ), + 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', + 'argumentCount' => '3,4' + ), + 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', + 'argumentCount' => '3,4' + ), + 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', + 'argumentCount' => '3,4' + ), + 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', + 'argumentCount' => '2' + ), + 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', + 'argumentCount' => '3' + ), + 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', + 'argumentCount' => '6' + ), + 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', + 'argumentCount' => '6' + ), + 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', + 'argumentCount' => '3' + ), + 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', + 'argumentCount' => '2,3' + ), + 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', + 'argumentCount' => '1' + ), + 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', + 'argumentCount' => '3' + ), + 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', + 'argumentCount' => '1' + ), + 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', + 'argumentCount' => '2,3' + ), + 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DB', + 'argumentCount' => '4,5' + ), + 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', + 'argumentCount' => '3' + ), + 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', + 'argumentCount' => '3' + ), + 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', + 'argumentCount' => '4,5' + ), + 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', + 'argumentCount' => '1,2' + ), + 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', + 'argumentCount' => '1,2' + ), + 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', + 'argumentCount' => '1,2' + ), + 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'rad2deg', + 'argumentCount' => '1' + ), + 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', + 'argumentCount' => '1,2' + ), + 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', + 'argumentCount' => '1+' + ), + 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DGET', + 'argumentCount' => '3' + ), + 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', + 'argumentCount' => '4,5' + ), + 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', + 'argumentCount' => '3' + ), + 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', + 'argumentCount' => '3' + ), + 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', + 'argumentCount' => '1,2' + ), + 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', + 'argumentCount' => '2' + ), + 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', + 'argumentCount' => '2' + ), + 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', + 'argumentCount' => '3' + ), + 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', + 'argumentCount' => '3' + ), + 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', + 'argumentCount' => '3' + ), + 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', + 'argumentCount' => '3' + ), + 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', + 'argumentCount' => '3' + ), + 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', + 'argumentCount' => '3' + ), + 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', + 'argumentCount' => '2' + ), + 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', + 'argumentCount' => '2' + ), + 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', + 'argumentCount' => '2' + ), + 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', + 'argumentCount' => '1,2' + ), + 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', + 'argumentCount' => '1' + ), + 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', + 'argumentCount' => '1' + ), + 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', + 'argumentCount' => '1' + ), + 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'exp', + 'argumentCount' => '1' + ), + 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', + 'argumentCount' => '3' + ), + 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', + 'argumentCount' => '1' + ), + 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', + 'argumentCount' => '1' + ), + 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', + 'argumentCount' => '0' + ), + 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', + 'argumentCount' => '1' + ), + 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', + 'argumentCount' => '1' + ), + 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', + 'argumentCount' => '1-3' + ), + 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', + 'argumentCount' => '2' + ), + 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', + 'argumentCount' => '3' + ), + 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FV', + 'argumentCount' => '3-5' + ), + 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', + 'argumentCount' => '2' + ), + 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', + 'argumentCount' => '4' + ), + 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', + 'argumentCount' => '3' + ), + 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', + 'argumentCount' => '1' + ), + 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', + 'argumentCount' => '1+' + ), + 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', + 'argumentCount' => '1+' + ), + 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', + 'argumentCount' => '1,2' + ), + 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', + 'argumentCount' => '1-4' + ), + 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', + 'argumentCount' => '1+' + ), + 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', + 'argumentCount' => '1,2' + ), + 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', + 'argumentCount' => '1' + ), + 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', + 'argumentCount' => '1,2' + ), + 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', + 'argumentCount' => '3,4' + ), + 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', + 'argumentCount' => '1' + ), + 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', + 'argumentCount' => '1,2', + 'passCellReference'=> TRUE + ), + 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', + 'argumentCount' => '4' + ), + 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', + 'argumentCount' => '1-3' + ), + 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', + 'argumentCount' => '2' + ), + 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', + 'argumentCount' => '1' + ), + 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', + 'argumentCount' => '1' + ), + 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', + 'argumentCount' => '1' + ), + 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', + 'argumentCount' => '1' + ), + 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', + 'argumentCount' => '1' + ), + 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', + 'argumentCount' => '2' + ), + 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', + 'argumentCount' => '1' + ), + 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', + 'argumentCount' => '1' + ), + 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', + 'argumentCount' => '1' + ), + 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', + 'argumentCount' => '1' + ), + 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', + 'argumentCount' => '2' + ), + 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', + 'argumentCount' => '1+' + ), + 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', + 'argumentCount' => '1' + ), + 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', + 'argumentCount' => '1' + ), + 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', + 'argumentCount' => '1' + ), + 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', + 'argumentCount' => '2' + ), + 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', + 'argumentCount' => '1+' + ), + 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', + 'argumentCount' => '1-4' + ), + 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', + 'argumentCount' => '1,2', + 'passCellReference'=> TRUE + ), + 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', + 'argumentCount' => '1' + ), + 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', + 'argumentCount' => '2' + ), + 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', + 'argumentCount' => '4,5' + ), + 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', + 'argumentCount' => '4-6' + ), + 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', + 'argumentCount' => '1,2' + ), + 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', + 'argumentCount' => '1' + ), + 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', + 'argumentCount' => '1' + ), + 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', + 'argumentCount' => '1' + ), + 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', + 'argumentCount' => '1' + ), + 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', + 'argumentCount' => '1' + ), + 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', + 'argumentCount' => '1' + ), + 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', + 'argumentCount' => '1' + ), + 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', + 'argumentCount' => '1' + ), + 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', + 'argumentCount' => '1' + ), + 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', + 'argumentCount' => '4' + ), + 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', + 'argumentCount' => '1' + ), + 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', + 'argumentCount' => '1+' + ), + 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', + 'argumentCount' => '2' + ), + 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', + 'argumentCount' => '1+' + ), + 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', + 'argumentCount' => '1-4' + ), + 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log', + 'argumentCount' => '1' + ), + 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', + 'argumentCount' => '1,2' + ), + 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log10', + 'argumentCount' => '1' + ), + 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', + 'argumentCount' => '1-4' + ), + 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', + 'argumentCount' => '3' + ), + 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', + 'argumentCount' => '3' + ), + 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', + 'argumentCount' => '2,3' + ), + 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', + 'argumentCount' => '1' + ), + 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', + 'argumentCount' => '2,3' + ), + 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', + 'argumentCount' => '1+' + ), + 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', + 'argumentCount' => '1+' + ), + 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', + 'argumentCount' => '2+' + ), + 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', + 'argumentCount' => '1' + ), + 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', + 'argumentCount' => '1+' + ), + 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', + 'argumentCount' => '1+' + ), + 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', + 'argumentCount' => '1+' + ), + 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', + 'argumentCount' => '2+' + ), + 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', + 'argumentCount' => '1' + ), + 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', + 'argumentCount' => '1' + ), + 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', + 'argumentCount' => '3' + ), + 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', + 'argumentCount' => '2' + ), + 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', + 'argumentCount' => '2' + ), + 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', + 'argumentCount' => '1+' + ), + 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', + 'argumentCount' => '1' + ), + 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', + 'argumentCount' => '2' + ), + 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', + 'argumentCount' => '1+' + ), + 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::N', + 'argumentCount' => '1' + ), + 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::NA', + 'argumentCount' => '0' + ), + 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', + 'argumentCount' => '3' + ), + 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', + 'argumentCount' => '2+' + ), + 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', + 'argumentCount' => '2' + ), + 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', + 'argumentCount' => '4' + ), + 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', + 'argumentCount' => '3' + ), + 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', + 'argumentCount' => '1' + ), + 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', + 'argumentCount' => '1' + ), + 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', + 'argumentCount' => '1' + ), + 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', + 'argumentCount' => '0' + ), + 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', + 'argumentCount' => '3-5' + ), + 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', + 'argumentCount' => '2+' + ), + 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', + 'argumentCount' => '1,2' + ), + 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', + 'argumentCount' => '1' + ), + 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', + 'argumentCount' => '1,2' + ), + 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', + 'argumentCount' => '1' + ), + 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', + 'argumentCount' => '3,5', + 'passCellReference'=> TRUE, + 'passByReference' => array(TRUE) + ), + 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', + 'argumentCount' => '1+' + ), + 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', + 'argumentCount' => '2' + ), + 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', + 'argumentCount' => '2,3' + ), + 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', + 'argumentCount' => '2' + ), + 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'pi', + 'argumentCount' => '0' + ), + 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', + 'argumentCount' => '3-5' + ), + 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', + 'argumentCount' => '3' + ), + 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', + 'argumentCount' => '2' + ), + 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', + 'argumentCount' => '4-6' + ), + 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', + 'argumentCount' => '6,7' + ), + 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', + 'argumentCount' => '4,5' + ), + 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', + 'argumentCount' => '5,6' + ), + 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3,4' + ), + 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', + 'argumentCount' => '1+' + ), + 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', + 'argumentCount' => '1' + ), + 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PV', + 'argumentCount' => '3-5' + ), + 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', + 'argumentCount' => '2' + ), + 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', + 'argumentCount' => '2' + ), + 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'deg2rad', + 'argumentCount' => '1' + ), + 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '0' + ), + 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '2' + ), + 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', + 'argumentCount' => '2,3' + ), + 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', + 'argumentCount' => '3-6' + ), + 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', + 'argumentCount' => '4-5' + ), + 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'str_repeat', + 'argumentCount' => '2' + ), + 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', + 'argumentCount' => '1,2' + ), + 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'round', + 'argumentCount' => '2' + ), + 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', + 'argumentCount' => '2' + ), + 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', + 'argumentCount' => '2' + ), + 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', + 'argumentCount' => '-1', + 'passByReference' => array(TRUE) + ), + 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', + 'argumentCount' => '1' + ), + 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', + 'argumentCount' => '2' + ), + 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1+' + ), + 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', + 'argumentCount' => '1' + ), + 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', + 'argumentCount' => '4' + ), + 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', + 'argumentCount' => '1' + ), + 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sin', + 'argumentCount' => '1' + ), + 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sinh', + 'argumentCount' => '1' + ), + 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', + 'argumentCount' => '1+' + ), + 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', + 'argumentCount' => '3' + ), + 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', + 'argumentCount' => '2' + ), + 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', + 'argumentCount' => '2' + ), + 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sqrt', + 'argumentCount' => '1' + ), + 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', + 'argumentCount' => '1' + ), + 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', + 'argumentCount' => '3' + ), + 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', + 'argumentCount' => '1+' + ), + 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', + 'argumentCount' => '1+' + ), + 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', + 'argumentCount' => '1+' + ), + 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', + 'argumentCount' => '1+' + ), + 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', + 'argumentCount' => '2' + ), + 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', + 'argumentCount' => '3,4' + ), + 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', + 'argumentCount' => '2+' + ), + 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', + 'argumentCount' => '1+' + ), + 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', + 'argumentCount' => '2,3' + ), + 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', + 'argumentCount' => '1+' + ), + 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', + 'argumentCount' => '1+' + ), + 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', + 'argumentCount' => '2' + ), + 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', + 'argumentCount' => '2' + ), + 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', + 'argumentCount' => '2' + ), + 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', + 'argumentCount' => '4' + ), + 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', + 'argumentCount' => '1' + ), + 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tan', + 'argumentCount' => '1' + ), + 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tanh', + 'argumentCount' => '1' + ), + 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', + 'argumentCount' => '3' + ), + 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', + 'argumentCount' => '3' + ), + 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', + 'argumentCount' => '3' + ), + 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', + 'argumentCount' => '3' + ), + 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', + 'argumentCount' => '2' + ), + 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', + 'argumentCount' => '3' + ), + 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', + 'argumentCount' => '1' + ), + 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', + 'argumentCount' => '2' + ), + 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', + 'argumentCount' => '0' + ), + 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', + 'argumentCount' => '1' + ), + 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', + 'argumentCount' => '1-4' + ), + 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', + 'argumentCount' => '1' + ), + 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', + 'argumentCount' => '2' + ), + 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', + 'argumentCount' => '0' + ), + 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', + 'argumentCount' => '1,2' + ), + 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '4' + ), + 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', + 'argumentCount' => '1' + ), + 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', + 'argumentCount' => '1' + ), + 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', + 'argumentCount' => '1' + ), + 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', + 'argumentCount' => '1+' + ), + 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', + 'argumentCount' => '1+' + ), + 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', + 'argumentCount' => '1+' + ), + 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', + 'argumentCount' => '1+' + ), + 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5-7' + ), + 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', + 'argumentCount' => '0' + ), + 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', + 'argumentCount' => '3,4' + ), + 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', + 'argumentCount' => '1,2' + ), + 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', + 'argumentCount' => '1,2' + ), + 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', + 'argumentCount' => '4' + ), + 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', + 'argumentCount' => '2+' + ), + 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', + 'argumentCount' => '2,3' + ), + 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', + 'argumentCount' => '3' + ), + 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', + 'argumentCount' => '1' + ), + 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', + 'argumentCount' => '2,3' + ), + 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '6,7' + ), + 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', + 'argumentCount' => '4,5' + ), + 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', + 'argumentCount' => '5,6' + ), + 'ZTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', + 'argumentCount' => '2-3' + ) + ); + + + // Internal functions used for special control purposes + private static $_controlFunctions = array( + 'MKMATRIX' => array('argumentCount' => '*', + 'functionCall' => 'self::_mkMatrix' + ) + ); + + + + + private function __construct(PHPExcel $workbook = NULL) { + $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; + $this->_savedPrecision = ini_get('precision'); + if ($this->_savedPrecision < $setPrecision) { + ini_set('precision',$setPrecision); + } + $this->delta = 1 * pow(10, -$setPrecision); + + if ($workbook !== NULL) { + self::$_workbookSets[$workbook->getID()] = $this; + } + + $this->_workbook = $workbook; + $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); + $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack); + } // function __construct() + + + public function __destruct() { + if ($this->_savedPrecision != ini_get('precision')) { + ini_set('precision',$this->_savedPrecision); + } + } + + private static function _loadLocales() { + $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/'; + foreach (glob($localeFileDirectory.'/*',GLOB_ONLYDIR) as $filename) { + $filename = substr($filename,strlen($localeFileDirectory)+1); + if ($filename != 'en') { + self::$_validLocaleLanguages[] = $filename; + } + } + } + + /** + * Get an instance of this class + * + * @access public + * @param PHPExcel $workbook Injected workbook for working with a PHPExcel object, + * or NULL to create a standalone claculation engine + * @return PHPExcel_Calculation + */ + 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(); + } + + return self::$_instance; + } // function getInstance() + + /** + * Unset an instance of this class + * + * @access public + * @param PHPExcel $workbook Injected workbook identifying the instance to unset + */ + 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 + * but only if a PHPExcel_Calculation instance exists + * + * @access public + * @return null + */ + public function flushInstance() { + $this->clearCalculationCache(); + } // function flushInstance() + + + /** + * Get the debuglog for this claculation engine instance + * + * @access public + * @return PHPExcel_CalcEngine_Logger + */ + public function getDebugLog() { + return $this->_debugLog; } - /** - * Flush the calculation cache for any existing instance of this class - * but only if a PHPExcel_Calculation instance exists - * - * @access public - * @return null - */ - public function flushInstance() { - $this->clearCalculationCache(); - } // function flushInstance() - - - /** - * Get the debuglog for this claculation engine instance - * - * @access public - * @return PHPExcel_CalcEngine_Logger - */ - public function getDebugLog() { - return $this->_debugLog; - } - - /** - * __clone implementation. Cloning should not be allowed in a Singleton! - * - * @access public - * @throws PHPExcel_Calculation_Exception - */ - public final function __clone() { - throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!'); - } // function __clone() - - - /** - * Return the locale-specific translation of TRUE - * - * @access public - * @return string locale-specific translation of TRUE - */ - public static function getTRUE() { - return self::$_localeBoolean['TRUE']; - } - - /** - * Return the locale-specific translation of FALSE - * - * @access public - * @return string locale-specific translation of FALSE - */ - public static function getFALSE() { - return self::$_localeBoolean['FALSE']; - } - - /** - * Set the Array Return Type (Array or Value of first element in the array) - * - * @access public - * @param string $returnType Array return type - * @return boolean Success or failure - */ - public static function setArrayReturnType($returnType) { - if (($returnType == self::RETURN_ARRAY_AS_VALUE) || - ($returnType == self::RETURN_ARRAY_AS_ERROR) || - ($returnType == self::RETURN_ARRAY_AS_ARRAY)) { - self::$returnArrayAsType = $returnType; - return TRUE; - } - return FALSE; - } // function setArrayReturnType() - - - /** - * Return the Array Return Type (Array or Value of first element in the array) - * - * @access public - * @return string $returnType Array return type - */ - public static function getArrayReturnType() { - return self::$returnArrayAsType; - } // function getArrayReturnType() - - - /** - * Is calculation caching enabled? - * - * @access public - * @return boolean - */ - public function getCalculationCacheEnabled() { - return $this->_calculationCacheEnabled; - } // function getCalculationCacheEnabled() - - /** - * Enable/disable calculation cache - * - * @access public - * @param boolean $pValue - */ - public function setCalculationCacheEnabled($pValue = TRUE) { - $this->_calculationCacheEnabled = $pValue; - $this->clearCalculationCache(); - } // function setCalculationCacheEnabled() - - - /** - * Enable calculation cache - */ - public function enableCalculationCache() { - $this->setCalculationCacheEnabled(TRUE); - } // function enableCalculationCache() - - - /** - * Disable calculation cache - */ - public function disableCalculationCache() { - $this->setCalculationCacheEnabled(FALSE); - } // function disableCalculationCache() - - - /** - * Clear calculation cache - */ - public function clearCalculationCache() { - $this->_calculationCache = array(); - } // function clearCalculationCache() - - /** - * Clear calculation cache for a specified worksheet - * - * @param string $worksheetName - */ - public function clearCalculationCacheForWorksheet($worksheetName) { - if (isset($this->_calculationCache[$worksheetName])) { - unset($this->_calculationCache[$worksheetName]); - } - } // function clearCalculationCacheForWorksheet() - - /** - * Rename calculation cache for a specified worksheet - * - * @param string $fromWorksheetName - * @param string $toWorksheetName - */ - public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) { - if (isset($this->_calculationCache[$fromWorksheetName])) { - $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName]; - unset($this->_calculationCache[$fromWorksheetName]); - } - } // function renameCalculationCacheForWorksheet() - - - /** - * Get the currently defined locale code - * - * @return string - */ - public function getLocale() { - return self::$_localeLanguage; - } // function getLocale() - - - /** - * Set the locale code - * - * @param string $locale The locale to use for formula translation - * @return boolean - */ - public function setLocale($locale = 'en_us') { - // Identify our locale and language - $language = $locale = strtolower($locale); - if (strpos($locale,'_') !== FALSE) { - list($language) = explode('_',$locale); - } - - if (count(self::$_validLocaleLanguages) == 1) - self::_loadLocales(); - - // Test whether we have any language data for this language (any locale) - if (in_array($language,self::$_validLocaleLanguages)) { - // initialise language/locale settings - self::$_localeFunctions = array(); - self::$_localeArgumentSeparator = ','; - self::$_localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL'); - // Default is English, if user isn't requesting english, then read the necessary data from the locale files - if ($locale != 'en_us') { - // Search for a file with a list of function names for locale - $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions'; - if (!file_exists($functionNamesFile)) { - // If there isn't a locale specific function file, look for a language specific function file - $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions'; - if (!file_exists($functionNamesFile)) { - return FALSE; - } - } - // Retrieve the list of locale or language specific function names - $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); - foreach ($localeFunctions as $localeFunction) { - list($localeFunction) = explode('##',$localeFunction); // Strip out comments - if (strpos($localeFunction,'=') !== FALSE) { - list($fName,$lfName) = explode('=',$localeFunction); - $fName = trim($fName); - $lfName = trim($lfName); - if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { - self::$_localeFunctions[$fName] = $lfName; - } - } - } - // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions - if (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; } - if (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; } - - $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config'; - if (!file_exists($configFile)) { - $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config'; - } - if (file_exists($configFile)) { - $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); - foreach ($localeSettings as $localeSetting) { - list($localeSetting) = explode('##',$localeSetting); // Strip out comments - if (strpos($localeSetting,'=') !== FALSE) { - list($settingName,$settingValue) = explode('=',$localeSetting); - $settingName = strtoupper(trim($settingName)); - switch ($settingName) { - case 'ARGUMENTSEPARATOR' : - self::$_localeArgumentSeparator = trim($settingValue); - break; - } - } - } - } - } - - self::$functionReplaceFromExcel = self::$functionReplaceToExcel = - self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL; - self::$_localeLanguage = $locale; - return TRUE; - } - return FALSE; - } // function setLocale() - - - - public static function _translateSeparator($fromSeparator,$toSeparator,$formula,&$inBraces) { - $strlen = mb_strlen($formula); - for ($i = 0; $i < $strlen; ++$i) { - $chr = mb_substr($formula,$i,1); - switch ($chr) { - case '{' : $inBraces = TRUE; - break; - case '}' : $inBraces = FALSE; - break; - case $fromSeparator : - if (!$inBraces) { - $formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1); - } - } - } - return $formula; - } - - private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) { - // Convert any Excel function names to the required language - if (self::$_localeLanguage !== 'en_us') { - $inBraces = FALSE; - // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators - if (strpos($formula,'"') !== FALSE) { - // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded - // the formula - $temp = explode('"',$formula); - $i = FALSE; - foreach($temp as &$value) { - // Only count/replace in alternating array entries - if ($i = !$i) { - $value = preg_replace($from,$to,$value); - $value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces); - } - } - unset($value); - // Then rebuild the formula string - $formula = implode('"',$temp); - } else { - // If there's no quoted strings, then we do a simple count/replace - $formula = preg_replace($from,$to,$formula); - $formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces); - } - } - - return $formula; - } - - private static $functionReplaceFromExcel = NULL; - private static $functionReplaceToLocale = NULL; - - public function _translateFormulaToLocale($formula) { - if (self::$functionReplaceFromExcel === NULL) { - self::$functionReplaceFromExcel = array(); - foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { - self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui'; - } - foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { - self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; - } - - } - - if (self::$functionReplaceToLocale === NULL) { - self::$functionReplaceToLocale = array(); - foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { - self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2'; - } - foreach(array_values(self::$_localeBoolean) as $localeBoolean) { - self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2'; - } - } - - return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator); - } // function _translateFormulaToLocale() - - - private static $functionReplaceFromLocale = NULL; - private static $functionReplaceToExcel = NULL; - - public function _translateFormulaToEnglish($formula) { - if (self::$functionReplaceFromLocale === NULL) { - self::$functionReplaceFromLocale = array(); - foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { - self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui'; - } - foreach(array_values(self::$_localeBoolean) as $excelBoolean) { - self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; - } - } - - if (self::$functionReplaceToExcel === NULL) { - self::$functionReplaceToExcel = array(); - foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { - self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2'; - } - foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { - self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2'; - } - } - - return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,','); - } // function _translateFormulaToEnglish() - - - public static function _localeFunc($function) { - if (self::$_localeLanguage !== 'en_us') { - $functionName = trim($function,'('); - if (isset(self::$_localeFunctions[$functionName])) { - $brace = ($functionName != $function); - $function = self::$_localeFunctions[$functionName]; - if ($brace) { $function .= '('; } - } - } - return $function; - } - - - - - /** - * Wrap string values in quotes - * - * @param mixed $value - * @return mixed - */ - public static function _wrapResult($value) { - if (is_string($value)) { - // Error values cannot be "wrapped" - if (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) { - // Return Excel errors "as is" - return $value; - } - // Return strings wrapped in quotes - return '"'.$value.'"'; - // Convert numeric errors to NaN error - } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { - return PHPExcel_Calculation_Functions::NaN(); - } - - return $value; - } // function _wrapResult() - - - /** - * Remove quotes used as a wrapper to identify string values - * - * @param mixed $value - * @return mixed - */ - public static function _unwrapResult($value) { - if (is_string($value)) { - if ((isset($value{0})) && ($value{0} == '"') && (substr($value,-1) == '"')) { - return substr($value,1,-1); - } - // Convert numeric errors to NaN error - } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { - return PHPExcel_Calculation_Functions::NaN(); - } - return $value; - } // function _unwrapResult() - - - - - /** - * Calculate cell value (using formula from a cell ID) - * Retained for backward compatibility - * - * @access public - * @param PHPExcel_Cell $pCell Cell to calculate - * @return mixed - * @throws PHPExcel_Calculation_Exception - */ - public function calculate(PHPExcel_Cell $pCell = NULL) { - try { - return $this->calculateCellValue($pCell); - } catch (PHPExcel_Exception $e) { - throw new PHPExcel_Calculation_Exception($e->getMessage()); - } - } // function calculate() - - - /** - * Calculate the value of a cell formula - * - * @access public - * @param PHPExcel_Cell $pCell Cell to calculate - * @param Boolean $resetLog Flag indicating whether the debug log should be reset or not - * @return mixed - * @throws PHPExcel_Calculation_Exception - */ - public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) { - if ($pCell === NULL) { - return NULL; - } - - $returnArrayAsType = self::$returnArrayAsType; - if ($resetLog) { - // Initialise the logging settings if requested - $this->formulaError = null; - $this->_debugLog->clearLog(); - $this->_cyclicReferenceStack->clear(); - $this->_cyclicFormulaCount = 1; - - self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; - } - - // Execute the calculation for the cell formula + /** + * __clone implementation. Cloning should not be allowed in a Singleton! + * + * @access public + * @throws PHPExcel_Calculation_Exception + */ + public final function __clone() { + throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!'); + } // function __clone() + + + /** + * Return the locale-specific translation of TRUE + * + * @access public + * @return string locale-specific translation of TRUE + */ + public static function getTRUE() { + return self::$_localeBoolean['TRUE']; + } + + /** + * Return the locale-specific translation of FALSE + * + * @access public + * @return string locale-specific translation of FALSE + */ + public static function getFALSE() { + return self::$_localeBoolean['FALSE']; + } + + /** + * Set the Array Return Type (Array or Value of first element in the array) + * + * @access public + * @param string $returnType Array return type + * @return boolean Success or failure + */ + public static function setArrayReturnType($returnType) { + if (($returnType == self::RETURN_ARRAY_AS_VALUE) || + ($returnType == self::RETURN_ARRAY_AS_ERROR) || + ($returnType == self::RETURN_ARRAY_AS_ARRAY)) { + self::$returnArrayAsType = $returnType; + return TRUE; + } + return FALSE; + } // function setArrayReturnType() + + + /** + * Return the Array Return Type (Array or Value of first element in the array) + * + * @access public + * @return string $returnType Array return type + */ + public static function getArrayReturnType() { + return self::$returnArrayAsType; + } // function getArrayReturnType() + + + /** + * Is calculation caching enabled? + * + * @access public + * @return boolean + */ + public function getCalculationCacheEnabled() { + return $this->_calculationCacheEnabled; + } // function getCalculationCacheEnabled() + + /** + * Enable/disable calculation cache + * + * @access public + * @param boolean $pValue + */ + public function setCalculationCacheEnabled($pValue = TRUE) { + $this->_calculationCacheEnabled = $pValue; + $this->clearCalculationCache(); + } // function setCalculationCacheEnabled() + + + /** + * Enable calculation cache + */ + public function enableCalculationCache() { + $this->setCalculationCacheEnabled(TRUE); + } // function enableCalculationCache() + + + /** + * Disable calculation cache + */ + public function disableCalculationCache() { + $this->setCalculationCacheEnabled(FALSE); + } // function disableCalculationCache() + + + /** + * Clear calculation cache + */ + public function clearCalculationCache() { + $this->_calculationCache = array(); + } // function clearCalculationCache() + + /** + * Clear calculation cache for a specified worksheet + * + * @param string $worksheetName + */ + public function clearCalculationCacheForWorksheet($worksheetName) { + if (isset($this->_calculationCache[$worksheetName])) { + unset($this->_calculationCache[$worksheetName]); + } + } // function clearCalculationCacheForWorksheet() + + /** + * Rename calculation cache for a specified worksheet + * + * @param string $fromWorksheetName + * @param string $toWorksheetName + */ + public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) { + if (isset($this->_calculationCache[$fromWorksheetName])) { + $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName]; + unset($this->_calculationCache[$fromWorksheetName]); + } + } // function renameCalculationCacheForWorksheet() + + + /** + * Get the currently defined locale code + * + * @return string + */ + public function getLocale() { + return self::$_localeLanguage; + } // function getLocale() + + + /** + * Set the locale code + * + * @param string $locale The locale to use for formula translation + * @return boolean + */ + public function setLocale($locale = 'en_us') { + // Identify our locale and language + $language = $locale = strtolower($locale); + if (strpos($locale,'_') !== FALSE) { + list($language) = explode('_',$locale); + } + + if (count(self::$_validLocaleLanguages) == 1) + self::_loadLocales(); + + // Test whether we have any language data for this language (any locale) + if (in_array($language,self::$_validLocaleLanguages)) { + // initialise language/locale settings + self::$_localeFunctions = array(); + self::$_localeArgumentSeparator = ','; + self::$_localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL'); + // Default is English, if user isn't requesting english, then read the necessary data from the locale files + if ($locale != 'en_us') { + // Search for a file with a list of function names for locale + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions'; + if (!file_exists($functionNamesFile)) { + // If there isn't a locale specific function file, look for a language specific function file + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions'; + if (!file_exists($functionNamesFile)) { + return FALSE; + } + } + // Retrieve the list of locale or language specific function names + $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($localeFunctions as $localeFunction) { + list($localeFunction) = explode('##',$localeFunction); // Strip out comments + if (strpos($localeFunction,'=') !== FALSE) { + list($fName,$lfName) = explode('=',$localeFunction); + $fName = trim($fName); + $lfName = trim($lfName); + if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { + self::$_localeFunctions[$fName] = $lfName; + } + } + } + // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions + if (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; } + if (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; } + + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config'; + if (!file_exists($configFile)) { + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config'; + } + if (file_exists($configFile)) { + $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($localeSettings as $localeSetting) { + list($localeSetting) = explode('##',$localeSetting); // Strip out comments + if (strpos($localeSetting,'=') !== FALSE) { + list($settingName,$settingValue) = explode('=',$localeSetting); + $settingName = strtoupper(trim($settingName)); + switch ($settingName) { + case 'ARGUMENTSEPARATOR' : + self::$_localeArgumentSeparator = trim($settingValue); + break; + } + } + } + } + } + + self::$functionReplaceFromExcel = self::$functionReplaceToExcel = + self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL; + self::$_localeLanguage = $locale; + return TRUE; + } + return FALSE; + } // function setLocale() + + + + public static function _translateSeparator($fromSeparator,$toSeparator,$formula,&$inBraces) { + $strlen = mb_strlen($formula); + for ($i = 0; $i < $strlen; ++$i) { + $chr = mb_substr($formula,$i,1); + switch ($chr) { + case '{' : $inBraces = TRUE; + break; + case '}' : $inBraces = FALSE; + break; + case $fromSeparator : + if (!$inBraces) { + $formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1); + } + } + } + return $formula; + } + + private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) { + // Convert any Excel function names to the required language + if (self::$_localeLanguage !== 'en_us') { + $inBraces = FALSE; + // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators + if (strpos($formula,'"') !== FALSE) { + // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded + // the formula + $temp = explode('"',$formula); + $i = FALSE; + foreach($temp as &$value) { + // Only count/replace in alternating array entries + if ($i = !$i) { + $value = preg_replace($from,$to,$value); + $value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces); + } + } + unset($value); + // Then rebuild the formula string + $formula = implode('"',$temp); + } else { + // If there's no quoted strings, then we do a simple count/replace + $formula = preg_replace($from,$to,$formula); + $formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces); + } + } + + return $formula; + } + + private static $functionReplaceFromExcel = NULL; + private static $functionReplaceToLocale = NULL; + + public function _translateFormulaToLocale($formula) { + if (self::$functionReplaceFromExcel === NULL) { + self::$functionReplaceFromExcel = array(); + foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui'; + } + foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; + } + + } + + if (self::$functionReplaceToLocale === NULL) { + self::$functionReplaceToLocale = array(); + foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2'; + } + foreach(array_values(self::$_localeBoolean) as $localeBoolean) { + self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2'; + } + } + + return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator); + } // function _translateFormulaToLocale() + + + private static $functionReplaceFromLocale = NULL; + private static $functionReplaceToExcel = NULL; + + public function _translateFormulaToEnglish($formula) { + if (self::$functionReplaceFromLocale === NULL) { + self::$functionReplaceFromLocale = array(); + foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui'; + } + foreach(array_values(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; + } + } + + if (self::$functionReplaceToExcel === NULL) { + self::$functionReplaceToExcel = array(); + foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2'; + } + foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2'; + } + } + + return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,','); + } // function _translateFormulaToEnglish() + + + public static function _localeFunc($function) { + if (self::$_localeLanguage !== 'en_us') { + $functionName = trim($function,'('); + if (isset(self::$_localeFunctions[$functionName])) { + $brace = ($functionName != $function); + $function = self::$_localeFunctions[$functionName]; + if ($brace) { $function .= '('; } + } + } + return $function; + } + + + + + /** + * Wrap string values in quotes + * + * @param mixed $value + * @return mixed + */ + public static function _wrapResult($value) { + if (is_string($value)) { + // Error values cannot be "wrapped" + if (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) { + // Return Excel errors "as is" + return $value; + } + // Return strings wrapped in quotes + return '"'.$value.'"'; + // Convert numeric errors to NaN error + } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return $value; + } // function _wrapResult() + + + /** + * Remove quotes used as a wrapper to identify string values + * + * @param mixed $value + * @return mixed + */ + public static function _unwrapResult($value) { + if (is_string($value)) { + if ((isset($value{0})) && ($value{0} == '"') && (substr($value,-1) == '"')) { + return substr($value,1,-1); + } + // Convert numeric errors to NaN error + } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $value; + } // function _unwrapResult() + + + + + /** + * Calculate cell value (using formula from a cell ID) + * Retained for backward compatibility + * + * @access public + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculate(PHPExcel_Cell $pCell = NULL) { + try { + return $this->calculateCellValue($pCell); + } catch (PHPExcel_Exception $e) { + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + } // function calculate() + + + /** + * Calculate the value of a cell formula + * + * @access public + * @param PHPExcel_Cell $pCell Cell to calculate + * @param Boolean $resetLog Flag indicating whether the debug log should be reset or not + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) { + if ($pCell === NULL) { + return NULL; + } + + $returnArrayAsType = self::$returnArrayAsType; + if ($resetLog) { + // Initialise the logging settings if requested + $this->formulaError = null; + $this->_debugLog->clearLog(); + $this->_cyclicReferenceStack->clear(); + $this->_cyclicFormulaCount = 1; + + self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; + } + + // Execute the calculation for the cell formula $this->_cellStack[] = array( 'sheet' => $pCell->getWorksheet()->getTitle(), 'cell' => $pCell->getCoordinate(), ); - try { - $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); + try { + $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); $cellAddress = array_pop($this->_cellStack); $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); - } catch (PHPExcel_Exception $e) { + } catch (PHPExcel_Exception $e) { $cellAddress = array_pop($this->_cellStack); $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); - throw new PHPExcel_Calculation_Exception($e->getMessage()); - } - - if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { - self::$returnArrayAsType = $returnArrayAsType; - $testResult = PHPExcel_Calculation_Functions::flattenArray($result); - if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) { - return PHPExcel_Calculation_Functions::VALUE(); - } - // If there's only a single cell in the array, then we allow it - if (count($testResult) != 1) { - // If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it - $r = array_keys($result); - $r = array_shift($r); - if (!is_numeric($r)) { return PHPExcel_Calculation_Functions::VALUE(); } - if (is_array($result[$r])) { - $c = array_keys($result[$r]); - $c = array_shift($c); - if (!is_numeric($c)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - } - $result = array_shift($testResult); - } - self::$returnArrayAsType = $returnArrayAsType; - - - if ($result === NULL) { - return 0; - } elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) { - return PHPExcel_Calculation_Functions::NaN(); - } - return $result; - } // function calculateCellValue( - - - /** - * Validate and parse a formula string - * - * @param string $formula Formula to parse - * @return array - * @throws PHPExcel_Calculation_Exception - */ - public function parseFormula($formula) { - // Basic validation that this is indeed a formula - // We return an empty array if not - $formula = trim($formula); - if ((!isset($formula{0})) || ($formula{0} != '=')) return array(); - $formula = ltrim(substr($formula,1)); - if (!isset($formula{0})) return array(); - - // Parse the formula and return the token stack - return $this->_parseFormula($formula); - } // function parseFormula() - - - /** - * Calculate the value of a formula - * - * @param string $formula Formula to parse - * @param string $cellID Address of the cell to calculate - * @param PHPExcel_Cell $pCell Cell to calculate - * @return mixed - * @throws PHPExcel_Calculation_Exception - */ - public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) { - // Initialise the logging settings - $this->formulaError = null; - $this->_debugLog->clearLog(); - $this->_cyclicReferenceStack->clear(); - - // Disable calculation cacheing because it only applies to cell calculations, not straight formulae - // But don't actually flush any cache - $resetCache = $this->getCalculationCacheEnabled(); - $this->_calculationCacheEnabled = FALSE; - // Execute the calculation - try { - $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); - } catch (PHPExcel_Exception $e) { - throw new PHPExcel_Calculation_Exception($e->getMessage()); - } - - // Reset calculation cacheing to its previous state - $this->_calculationCacheEnabled = $resetCache; - - return $result; - } // function calculateFormula() + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + + if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { + self::$returnArrayAsType = $returnArrayAsType; + $testResult = PHPExcel_Calculation_Functions::flattenArray($result); + if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) { + return PHPExcel_Calculation_Functions::VALUE(); + } + // If there's only a single cell in the array, then we allow it + if (count($testResult) != 1) { + // If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it + $r = array_keys($result); + $r = array_shift($r); + if (!is_numeric($r)) { return PHPExcel_Calculation_Functions::VALUE(); } + if (is_array($result[$r])) { + $c = array_keys($result[$r]); + $c = array_shift($c); + if (!is_numeric($c)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + } + $result = array_shift($testResult); + } + self::$returnArrayAsType = $returnArrayAsType; + + + if ($result === NULL) { + return 0; + } elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $result; + } // function calculateCellValue( + + + /** + * Validate and parse a formula string + * + * @param string $formula Formula to parse + * @return array + * @throws PHPExcel_Calculation_Exception + */ + public function parseFormula($formula) { + // Basic validation that this is indeed a formula + // We return an empty array if not + $formula = trim($formula); + if ((!isset($formula{0})) || ($formula{0} != '=')) return array(); + $formula = ltrim(substr($formula,1)); + if (!isset($formula{0})) return array(); + + // Parse the formula and return the token stack + return $this->_parseFormula($formula); + } // function parseFormula() + + + /** + * Calculate the value of a formula + * + * @param string $formula Formula to parse + * @param string $cellID Address of the cell to calculate + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) { + // Initialise the logging settings + $this->formulaError = null; + $this->_debugLog->clearLog(); + $this->_cyclicReferenceStack->clear(); + + // Disable calculation cacheing because it only applies to cell calculations, not straight formulae + // But don't actually flush any cache + $resetCache = $this->getCalculationCacheEnabled(); + $this->_calculationCacheEnabled = FALSE; + // Execute the calculation + try { + $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); + } catch (PHPExcel_Exception $e) { + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + + // Reset calculation cacheing to its previous state + $this->_calculationCacheEnabled = $resetCache; + + return $result; + } // function calculateFormula() public function getValueFromCache($cellReference, &$cellValue) { - // Is calculation cacheing enabled? - // Is the value present in calculation 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[$cellReference]; - return TRUE; - } - return FALSE; + // Is calculation cacheing enabled? + // Is the value present in calculation 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[$cellReference]; + return TRUE; + } + return FALSE; } public function saveValueToCache($cellReference, $cellValue) { - if ($this->_calculationCacheEnabled) { - $this->_calculationCache[$cellReference] = $cellValue; - } - } - - /** - * Parse a cell formula and calculate its value - * - * @param string $formula The formula to parse and calculate - * @param string $cellID The ID (e.g. A3) of the cell that we are calculating - * @param PHPExcel_Cell $pCell Cell to calculate - * @return mixed - * @throws PHPExcel_Calculation_Exception - */ - public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) { - $cellValue = null; - - // Basic validation that this is indeed a formula - // We simply return the cell value if not - $formula = trim($formula); - if ($formula{0} != '=') return self::_wrapResult($formula); - $formula = ltrim(substr($formula, 1)); - if (!isset($formula{0})) return self::_wrapResult($formula); - - $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; - $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; + if ($this->_calculationCacheEnabled) { + $this->_calculationCache[$cellReference] = $cellValue; + } + } + + /** + * Parse a cell formula and calculate its value + * + * @param string $formula The formula to parse and calculate + * @param string $cellID The ID (e.g. A3) of the cell that we are calculating + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) { + $cellValue = null; + + // Basic validation that this is indeed a formula + // We simply return the cell value if not + $formula = trim($formula); + if ($formula{0} != '=') return self::_wrapResult($formula); + $formula = ltrim(substr($formula, 1)); + if (!isset($formula{0})) return self::_wrapResult($formula); + + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; $wsCellReference = $wsTitle . '!' . $cellID; - if (($cellID !== NULL) && ($this->getValueFromCache($wsCellReference, $cellValue))) { - return $cellValue; - } + if (($cellID !== NULL) && ($this->getValueFromCache($wsCellReference, $cellValue))) { + return $cellValue; + } - if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsCellReference))) { + if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsCellReference))) { if ($this->cyclicFormulaCount <= 0) { $this->_cyclicFormulaCell = ''; - return $this->_raiseFormulaError('Cyclic Reference in Formula'); - } elseif ($this->_cyclicFormulaCell === $wsCellReference) { - ++$this->_cyclicFormulaCount; - if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { + return $this->_raiseFormulaError('Cyclic Reference in Formula'); + } elseif ($this->_cyclicFormulaCell === $wsCellReference) { + ++$this->_cyclicFormulaCount; + if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { $this->_cyclicFormulaCell = ''; - return $cellValue; - } - } elseif ($this->_cyclicFormulaCell == '') { - if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { - return $cellValue; - } - $this->_cyclicFormulaCell = $wsCellReference; - } - } - - // Parse the formula onto the token stack and calculate the value - $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($wsCellReference, $cellValue); - } - - // Return the calculated value - return $cellValue; - } // function _calculateFormulaValue() - - - /** - * Ensure that paired matrix operands are both matrices and of the same size - * - * @param mixed &$operand1 First matrix operand - * @param mixed &$operand2 Second matrix operand - * @param integer $resize Flag indicating whether the matrices should be resized to match - * and (if so), whether the smaller dimension should grow or the - * larger should shrink. - * 0 = no resize - * 1 = shrink to fit - * 2 = extend to fit - */ - private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) { - // Examine each of the two operands, and turn them into an array if they aren't one already - // Note that this function should only be called if one or both of the operand is already an array - if (!is_array($operand1)) { - list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2); - $operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1)); - $resize = 0; - } elseif (!is_array($operand2)) { - list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1); - $operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2)); - $resize = 0; - } - - list($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1); - list($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2); - if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { - $resize = 1; - } - - if ($resize == 2) { - // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger - self::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); - } elseif ($resize == 1) { - // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller - self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); - } - return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); - } // function _checkMatrixOperands() - - - /** - * Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0 - * - * @param mixed &$matrix matrix operand - * @return array An array comprising the number of rows, and number of columns - */ - public static function _getMatrixDimensions(&$matrix) { - $matrixRows = count($matrix); - $matrixColumns = 0; - foreach($matrix as $rowKey => $rowValue) { - $matrixColumns = max(count($rowValue),$matrixColumns); - if (!is_array($rowValue)) { - $matrix[$rowKey] = array($rowValue); - } else { - $matrix[$rowKey] = array_values($rowValue); - } - } - $matrix = array_values($matrix); - return array($matrixRows,$matrixColumns); - } // function _getMatrixDimensions() - - - /** - * Ensure that paired matrix operands are both matrices of the same size - * - * @param mixed &$matrix1 First matrix operand - * @param mixed &$matrix2 Second matrix operand - * @param integer $matrix1Rows Row size of first matrix operand - * @param integer $matrix1Columns Column size of first matrix operand - * @param integer $matrix2Rows Row size of second matrix operand - * @param integer $matrix2Columns Column size of second matrix operand - */ - private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { - if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { - if ($matrix2Rows < $matrix1Rows) { - for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { - unset($matrix1[$i]); - } - } - if ($matrix2Columns < $matrix1Columns) { - for ($i = 0; $i < $matrix1Rows; ++$i) { - for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { - unset($matrix1[$i][$j]); - } - } - } - } - - if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { - if ($matrix1Rows < $matrix2Rows) { - for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) { - unset($matrix2[$i]); - } - } - if ($matrix1Columns < $matrix2Columns) { - for ($i = 0; $i < $matrix2Rows; ++$i) { - for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { - unset($matrix2[$i][$j]); - } - } - } - } - } // function _resizeMatricesShrink() - - - /** - * Ensure that paired matrix operands are both matrices of the same size - * - * @param mixed &$matrix1 First matrix operand - * @param mixed &$matrix2 Second matrix operand - * @param integer $matrix1Rows Row size of first matrix operand - * @param integer $matrix1Columns Column size of first matrix operand - * @param integer $matrix2Rows Row size of second matrix operand - * @param integer $matrix2Columns Column size of second matrix operand - */ - private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { - if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { - if ($matrix2Columns < $matrix1Columns) { - for ($i = 0; $i < $matrix2Rows; ++$i) { - $x = $matrix2[$i][$matrix2Columns-1]; - for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { - $matrix2[$i][$j] = $x; - } - } - } - if ($matrix2Rows < $matrix1Rows) { - $x = $matrix2[$matrix2Rows-1]; - for ($i = 0; $i < $matrix1Rows; ++$i) { - $matrix2[$i] = $x; - } - } - } - - if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { - if ($matrix1Columns < $matrix2Columns) { - for ($i = 0; $i < $matrix1Rows; ++$i) { - $x = $matrix1[$i][$matrix1Columns-1]; - for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { - $matrix1[$i][$j] = $x; - } - } - } - if ($matrix1Rows < $matrix2Rows) { - $x = $matrix1[$matrix1Rows-1]; - for ($i = 0; $i < $matrix2Rows; ++$i) { - $matrix1[$i] = $x; - } - } - } - } // function _resizeMatricesExtend() - - - /** - * Format details of an operand for display in the log (based on operand type) - * - * @param mixed $value First matrix operand - * @return mixed - */ - private function _showValue($value) { - if ($this->_debugLog->getWriteDebugLog()) { - $testArray = PHPExcel_Calculation_Functions::flattenArray($value); - if (count($testArray) == 1) { - $value = array_pop($testArray); - } - - if (is_array($value)) { - $returnMatrix = array(); - $pad = $rpad = ', '; - foreach($value as $row) { - if (is_array($row)) { - $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row)); - $rpad = '; '; - } else { - $returnMatrix[] = $this->_showValue($row); - } - } - return '{ '.implode($rpad,$returnMatrix).' }'; - } elseif(is_string($value) && (trim($value,'"') == $value)) { - return '"'.$value.'"'; - } elseif(is_bool($value)) { - return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; - } - } - return PHPExcel_Calculation_Functions::flattenSingleValue($value); - } // function _showValue() - - - /** - * Format type and details of an operand for display in the log (based on operand type) - * - * @param mixed $value First matrix operand - * @return mixed - */ - private function _showTypeDetails($value) { - if ($this->_debugLog->getWriteDebugLog()) { - $testArray = PHPExcel_Calculation_Functions::flattenArray($value); - if (count($testArray) == 1) { - $value = array_pop($testArray); - } - - if ($value === NULL) { - return 'a NULL value'; - } elseif (is_float($value)) { - $typeString = 'a floating point number'; - } elseif(is_int($value)) { - $typeString = 'an integer number'; - } elseif(is_bool($value)) { - $typeString = 'a boolean'; - } elseif(is_array($value)) { - $typeString = 'a matrix'; - } else { - if ($value == '') { - return 'an empty string'; - } elseif ($value{0} == '#') { - return 'a '.$value.' error'; - } else { - $typeString = 'a string'; - } - } - return $typeString.' with a value of '.$this->_showValue($value); - } - } // function _showTypeDetails() - - - private function _convertMatrixReferences($formula) { - static $matrixReplaceFrom = array('{',';','}'); - static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))'); - - // Convert any Excel matrix references to the MKMATRIX() function - if (strpos($formula,'{') !== FALSE) { - // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators - if (strpos($formula,'"') !== FALSE) { - // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded - // the formula - $temp = explode('"',$formula); - // Open and Closed counts used for trapping mismatched braces in the formula - $openCount = $closeCount = 0; - $i = FALSE; - foreach($temp as &$value) { - // Only count/replace in alternating array entries - if ($i = !$i) { - $openCount += substr_count($value,'{'); - $closeCount += substr_count($value,'}'); - $value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value); - } - } - unset($value); - // Then rebuild the formula string - $formula = implode('"',$temp); - } else { - // If there's no quoted strings, then we do a simple count/replace - $openCount = substr_count($formula,'{'); - $closeCount = substr_count($formula,'}'); - $formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula); - } - // Trap for mismatched braces and trigger an appropriate error - if ($openCount < $closeCount) { - if ($openCount > 0) { - return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '}'"); - } else { - return $this->_raiseFormulaError("Formula Error: Unexpected '}' encountered"); - } - } elseif ($openCount > $closeCount) { - if ($closeCount > 0) { - return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '{'"); - } else { - return $this->_raiseFormulaError("Formula Error: Unexpected '{' encountered"); - } - } - } - - return $formula; - } // function _convertMatrixReferences() - - - private static function _mkMatrix() { - return func_get_args(); - } // function _mkMatrix() - - - // Binary Operators - // These operators always work on two values - // Array key is the operator, the value indicates whether this is a left or right associative operator - private static $_operatorAssociativity = array( - '^' => 0, // Exponentiation - '*' => 0, '/' => 0, // Multiplication and Division - '+' => 0, '-' => 0, // Addition and Subtraction - '&' => 0, // Concatenation - '|' => 0, ':' => 0, // Intersect and Range - '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison - ); - - // Comparison (Boolean) Operators - // These operators work on two values, but always return a boolean result - private static $_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE); - - // Operator Precedence - // This list includes all valid operators, whether binary (including boolean) or unary (such as %) - // Array key is the operator, the value is its precedence - private static $_operatorPrecedence = array( - ':' => 8, // Range - '|' => 7, // Intersect - '~' => 6, // Negation - '%' => 5, // Percentage - '^' => 4, // Exponentiation - '*' => 3, '/' => 3, // Multiplication and Division - '+' => 2, '-' => 2, // Addition and Subtraction - '&' => 1, // Concatenation - '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison - ); - - // Convert infix to postfix notation - private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { - if (($formula = $this->_convertMatrixReferences(trim($formula))) === FALSE) { - return FALSE; - } - - // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), - // so we store the parent worksheet so that we can re-attach it when necessary - $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; - - $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION. - '|'.self::CALCULATION_REGEXP_CELLREF. - '|'.self::CALCULATION_REGEXP_NUMBER. - '|'.self::CALCULATION_REGEXP_STRING. - '|'.self::CALCULATION_REGEXP_OPENBRACE. - '|'.self::CALCULATION_REGEXP_NAMEDRANGE. - '|'.self::CALCULATION_REGEXP_ERROR. - ')/si'; - - // Start with initialisation - $index = 0; - $stack = new PHPExcel_Calculation_Token_Stack; - $output = array(); - $expectingOperator = FALSE; // We use this test in syntax-checking the expression to determine when a - // - is a negation or + is a positive operator rather than an operation - $expectingOperand = FALSE; // We use this test in syntax-checking the expression to determine whether an operand - // should be null in a function call - // The guts of the lexical parser - // Loop through the formula extracting each operator and operand in turn - while(TRUE) { + return $cellValue; + } + } elseif ($this->_cyclicFormulaCell == '') { + if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { + return $cellValue; + } + $this->_cyclicFormulaCell = $wsCellReference; + } + } + + // Parse the formula onto the token stack and calculate the value + $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($wsCellReference, $cellValue); + } + + // Return the calculated value + return $cellValue; + } // function _calculateFormulaValue() + + + /** + * Ensure that paired matrix operands are both matrices and of the same size + * + * @param mixed &$operand1 First matrix operand + * @param mixed &$operand2 Second matrix operand + * @param integer $resize Flag indicating whether the matrices should be resized to match + * and (if so), whether the smaller dimension should grow or the + * larger should shrink. + * 0 = no resize + * 1 = shrink to fit + * 2 = extend to fit + */ + private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) { + // Examine each of the two operands, and turn them into an array if they aren't one already + // Note that this function should only be called if one or both of the operand is already an array + if (!is_array($operand1)) { + list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2); + $operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1)); + $resize = 0; + } elseif (!is_array($operand2)) { + list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1); + $operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2)); + $resize = 0; + } + + list($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1); + list($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2); + if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { + $resize = 1; + } + + if ($resize == 2) { + // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger + self::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } elseif ($resize == 1) { + // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller + self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } + return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } // function _checkMatrixOperands() + + + /** + * Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0 + * + * @param mixed &$matrix matrix operand + * @return array An array comprising the number of rows, and number of columns + */ + public static function _getMatrixDimensions(&$matrix) { + $matrixRows = count($matrix); + $matrixColumns = 0; + foreach($matrix as $rowKey => $rowValue) { + $matrixColumns = max(count($rowValue),$matrixColumns); + if (!is_array($rowValue)) { + $matrix[$rowKey] = array($rowValue); + } else { + $matrix[$rowKey] = array_values($rowValue); + } + } + $matrix = array_values($matrix); + return array($matrixRows,$matrixColumns); + } // function _getMatrixDimensions() + + + /** + * Ensure that paired matrix operands are both matrices of the same size + * + * @param mixed &$matrix1 First matrix operand + * @param mixed &$matrix2 Second matrix operand + * @param integer $matrix1Rows Row size of first matrix operand + * @param integer $matrix1Columns Column size of first matrix operand + * @param integer $matrix2Rows Row size of second matrix operand + * @param integer $matrix2Columns Column size of second matrix operand + */ + private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { + if ($matrix2Rows < $matrix1Rows) { + for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { + unset($matrix1[$i]); + } + } + if ($matrix2Columns < $matrix1Columns) { + for ($i = 0; $i < $matrix1Rows; ++$i) { + for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { + unset($matrix1[$i][$j]); + } + } + } + } + + if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { + if ($matrix1Rows < $matrix2Rows) { + for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) { + unset($matrix2[$i]); + } + } + if ($matrix1Columns < $matrix2Columns) { + for ($i = 0; $i < $matrix2Rows; ++$i) { + for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { + unset($matrix2[$i][$j]); + } + } + } + } + } // function _resizeMatricesShrink() + + + /** + * Ensure that paired matrix operands are both matrices of the same size + * + * @param mixed &$matrix1 First matrix operand + * @param mixed &$matrix2 Second matrix operand + * @param integer $matrix1Rows Row size of first matrix operand + * @param integer $matrix1Columns Column size of first matrix operand + * @param integer $matrix2Rows Row size of second matrix operand + * @param integer $matrix2Columns Column size of second matrix operand + */ + private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { + if ($matrix2Columns < $matrix1Columns) { + for ($i = 0; $i < $matrix2Rows; ++$i) { + $x = $matrix2[$i][$matrix2Columns-1]; + for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { + $matrix2[$i][$j] = $x; + } + } + } + if ($matrix2Rows < $matrix1Rows) { + $x = $matrix2[$matrix2Rows-1]; + for ($i = 0; $i < $matrix1Rows; ++$i) { + $matrix2[$i] = $x; + } + } + } + + if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { + if ($matrix1Columns < $matrix2Columns) { + for ($i = 0; $i < $matrix1Rows; ++$i) { + $x = $matrix1[$i][$matrix1Columns-1]; + for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { + $matrix1[$i][$j] = $x; + } + } + } + if ($matrix1Rows < $matrix2Rows) { + $x = $matrix1[$matrix1Rows-1]; + for ($i = 0; $i < $matrix2Rows; ++$i) { + $matrix1[$i] = $x; + } + } + } + } // function _resizeMatricesExtend() + + + /** + * Format details of an operand for display in the log (based on operand type) + * + * @param mixed $value First matrix operand + * @return mixed + */ + private function _showValue($value) { + if ($this->_debugLog->getWriteDebugLog()) { + $testArray = PHPExcel_Calculation_Functions::flattenArray($value); + if (count($testArray) == 1) { + $value = array_pop($testArray); + } + + if (is_array($value)) { + $returnMatrix = array(); + $pad = $rpad = ', '; + foreach($value as $row) { + if (is_array($row)) { + $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row)); + $rpad = '; '; + } else { + $returnMatrix[] = $this->_showValue($row); + } + } + return '{ '.implode($rpad,$returnMatrix).' }'; + } elseif(is_string($value) && (trim($value,'"') == $value)) { + return '"'.$value.'"'; + } elseif(is_bool($value)) { + return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + } + return PHPExcel_Calculation_Functions::flattenSingleValue($value); + } // function _showValue() + + + /** + * Format type and details of an operand for display in the log (based on operand type) + * + * @param mixed $value First matrix operand + * @return mixed + */ + private function _showTypeDetails($value) { + if ($this->_debugLog->getWriteDebugLog()) { + $testArray = PHPExcel_Calculation_Functions::flattenArray($value); + if (count($testArray) == 1) { + $value = array_pop($testArray); + } + + if ($value === NULL) { + return 'a NULL value'; + } elseif (is_float($value)) { + $typeString = 'a floating point number'; + } elseif(is_int($value)) { + $typeString = 'an integer number'; + } elseif(is_bool($value)) { + $typeString = 'a boolean'; + } elseif(is_array($value)) { + $typeString = 'a matrix'; + } else { + if ($value == '') { + return 'an empty string'; + } elseif ($value{0} == '#') { + return 'a '.$value.' error'; + } else { + $typeString = 'a string'; + } + } + return $typeString.' with a value of '.$this->_showValue($value); + } + } // function _showTypeDetails() + + + private function _convertMatrixReferences($formula) { + static $matrixReplaceFrom = array('{',';','}'); + static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))'); + + // Convert any Excel matrix references to the MKMATRIX() function + if (strpos($formula,'{') !== FALSE) { + // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators + if (strpos($formula,'"') !== FALSE) { + // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded + // the formula + $temp = explode('"',$formula); + // Open and Closed counts used for trapping mismatched braces in the formula + $openCount = $closeCount = 0; + $i = FALSE; + foreach($temp as &$value) { + // Only count/replace in alternating array entries + if ($i = !$i) { + $openCount += substr_count($value,'{'); + $closeCount += substr_count($value,'}'); + $value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value); + } + } + unset($value); + // Then rebuild the formula string + $formula = implode('"',$temp); + } else { + // If there's no quoted strings, then we do a simple count/replace + $openCount = substr_count($formula,'{'); + $closeCount = substr_count($formula,'}'); + $formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula); + } + // Trap for mismatched braces and trigger an appropriate error + if ($openCount < $closeCount) { + if ($openCount > 0) { + return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '}'"); + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected '}' encountered"); + } + } elseif ($openCount > $closeCount) { + if ($closeCount > 0) { + return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '{'"); + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected '{' encountered"); + } + } + } + + return $formula; + } // function _convertMatrixReferences() + + + private static function _mkMatrix() { + return func_get_args(); + } // function _mkMatrix() + + + // Binary Operators + // These operators always work on two values + // Array key is the operator, the value indicates whether this is a left or right associative operator + private static $_operatorAssociativity = array( + '^' => 0, // Exponentiation + '*' => 0, '/' => 0, // Multiplication and Division + '+' => 0, '-' => 0, // Addition and Subtraction + '&' => 0, // Concatenation + '|' => 0, ':' => 0, // Intersect and Range + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison + ); + + // Comparison (Boolean) Operators + // These operators work on two values, but always return a boolean result + private static $_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE); + + // Operator Precedence + // This list includes all valid operators, whether binary (including boolean) or unary (such as %) + // Array key is the operator, the value is its precedence + private static $_operatorPrecedence = array( + ':' => 8, // Range + '|' => 7, // Intersect + '~' => 6, // Negation + '%' => 5, // Percentage + '^' => 4, // Exponentiation + '*' => 3, '/' => 3, // Multiplication and Division + '+' => 2, '-' => 2, // Addition and Subtraction + '&' => 1, // Concatenation + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison + ); + + // Convert infix to postfix notation + private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { + if (($formula = $this->_convertMatrixReferences(trim($formula))) === FALSE) { + return FALSE; + } + + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), + // so we store the parent worksheet so that we can re-attach it when necessary + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + + $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION. + '|'.self::CALCULATION_REGEXP_CELLREF. + '|'.self::CALCULATION_REGEXP_NUMBER. + '|'.self::CALCULATION_REGEXP_STRING. + '|'.self::CALCULATION_REGEXP_OPENBRACE. + '|'.self::CALCULATION_REGEXP_NAMEDRANGE. + '|'.self::CALCULATION_REGEXP_ERROR. + ')/si'; + + // Start with initialisation + $index = 0; + $stack = new PHPExcel_Calculation_Token_Stack; + $output = array(); + $expectingOperator = FALSE; // We use this test in syntax-checking the expression to determine when a + // - is a negation or + is a positive operator rather than an operation + $expectingOperand = FALSE; // We use this test in syntax-checking the expression to determine whether an operand + // should be null in a function call + // The guts of the lexical parser + // Loop through the formula extracting each operator and operand in turn + while(TRUE) { //echo 'Assessing Expression '.substr($formula, $index),PHP_EOL; - $opCharacter = $formula{$index}; // Get the first character of the value at the current index position + $opCharacter = $formula{$index}; // Get the first character of the value at the current index position //echo 'Initial character of expression block is '.$opCharacter,PHP_EOL; - if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) { - $opCharacter .= $formula{++$index}; + if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) { + $opCharacter .= $formula{++$index}; //echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL; - } + } - // Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand - $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match); + // Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand + $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match); //echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').PHP_EOL; //var_dump($match); - if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus? + if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus? //echo 'Element is a Negation operator',PHP_EOL; - $stack->push('Unary Operator','~'); // Put a negation on the stack - ++$index; // and drop the negation symbol - } elseif ($opCharacter == '%' && $expectingOperator) { + $stack->push('Unary Operator','~'); // Put a negation on the stack + ++$index; // and drop the negation symbol + } elseif ($opCharacter == '%' && $expectingOperator) { //echo 'Element is a Percentage operator',PHP_EOL; - $stack->push('Unary Operator','%'); // Put a percentage on the stack - ++$index; - } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded? + $stack->push('Unary Operator','%'); // Put a percentage on the stack + ++$index; + } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded? //echo 'Element is a Positive number, not Plus operator',PHP_EOL; - ++$index; // Drop the redundant plus symbol - } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal - return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression + ++$index; // Drop the redundant plus symbol + } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal + return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression - } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? + } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? //echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL; - while($stack->count() > 0 && - ($o2 = $stack->last()) && - isset(self::$_operators[$o2['value']]) && - @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { - $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output - } - $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack - ++$index; - $expectingOperator = FALSE; - - } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis? + while($stack->count() > 0 && + ($o2 = $stack->last()) && + isset(self::$_operators[$o2['value']]) && + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { + $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output + } + $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack + ++$index; + $expectingOperator = FALSE; + + } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis? //echo 'Element is a Closing bracket',PHP_EOL; - $expectingOperand = FALSE; - while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( - if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"'); - else $output[] = $o2; - } - $d = $stack->last(2); - if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function? - $functionName = $matches[1]; // Get the function name + $expectingOperand = FALSE; + while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( + if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"'); + else $output[] = $o2; + } + $d = $stack->last(2); + if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function? + $functionName = $matches[1]; // Get the function name //echo 'Closed Function is '.$functionName,PHP_EOL; - $d = $stack->pop(); - $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack) + $d = $stack->pop(); + $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack) //if ($argumentCount == 0) { -// echo 'With no arguments',PHP_EOL; +// echo 'With no arguments',PHP_EOL; //} elseif ($argumentCount == 1) { -// echo 'With 1 argument',PHP_EOL; +// echo 'With 1 argument',PHP_EOL; //} else { -// echo 'With '.$argumentCount.' arguments',PHP_EOL; +// echo 'With '.$argumentCount.' arguments',PHP_EOL; //} - $output[] = $d; // Dump the argument count on the output - $output[] = $stack->pop(); // Pop the function and push onto the output - if (isset(self::$_controlFunctions[$functionName])) { + $output[] = $d; // Dump the argument count on the output + $output[] = $stack->pop(); // Pop the function and push onto the output + if (isset(self::$_controlFunctions[$functionName])) { //echo 'Built-in function '.$functionName,PHP_EOL; - $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount']; - $functionCall = self::$_controlFunctions[$functionName]['functionCall']; - } elseif (isset(self::$_PHPExcelFunctions[$functionName])) { + $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount']; + $functionCall = self::$_controlFunctions[$functionName]['functionCall']; + } elseif (isset(self::$_PHPExcelFunctions[$functionName])) { //echo 'PHPExcel function '.$functionName,PHP_EOL; - $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount']; - $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; - } else { // did we somehow push a non-function on the stack? this should never happen - return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack"); - } - // Check the argument count - $argumentCountError = FALSE; - if (is_numeric($expectedArgumentCount)) { - if ($expectedArgumentCount < 0) { + $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount']; + $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; + } else { // did we somehow push a non-function on the stack? this should never happen + return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack"); + } + // Check the argument count + $argumentCountError = FALSE; + if (is_numeric($expectedArgumentCount)) { + if ($expectedArgumentCount < 0) { //echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount),PHP_EOL; - if ($argumentCount > abs($expectedArgumentCount)) { - $argumentCountError = TRUE; - $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount); - } - } else { + if ($argumentCount > abs($expectedArgumentCount)) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount); + } + } else { //echo '$expectedArgumentCount is numeric '.$expectedArgumentCount,PHP_EOL; - if ($argumentCount != $expectedArgumentCount) { - $argumentCountError = TRUE; - $expectedArgumentCountString = $expectedArgumentCount; - } - } - } elseif ($expectedArgumentCount != '*') { - $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch); + if ($argumentCount != $expectedArgumentCount) { + $argumentCountError = TRUE; + $expectedArgumentCountString = $expectedArgumentCount; + } + } + } elseif ($expectedArgumentCount != '*') { + $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch); //print_r($argMatch); //echo PHP_EOL; - switch ($argMatch[2]) { - case '+' : - if ($argumentCount < $argMatch[1]) { - $argumentCountError = TRUE; - $expectedArgumentCountString = $argMatch[1].' or more '; - } - break; - case '-' : - if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) { - $argumentCountError = TRUE; - $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3]; - } - break; - case ',' : - if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) { - $argumentCountError = TRUE; - $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3]; - } - break; - } - } - if ($argumentCountError) { - return $this->_raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected"); - } - } - ++$index; - - } elseif ($opCharacter == ',') { // Is this the separator for function arguments? + switch ($argMatch[2]) { + case '+' : + if ($argumentCount < $argMatch[1]) { + $argumentCountError = TRUE; + $expectedArgumentCountString = $argMatch[1].' or more '; + } + break; + case '-' : + if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3]; + } + break; + case ',' : + if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3]; + } + break; + } + } + if ($argumentCountError) { + return $this->_raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected"); + } + } + ++$index; + + } elseif ($opCharacter == ',') { // Is this the separator for function arguments? //echo 'Element is a Function argument separator',PHP_EOL; - while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( - if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,"); - else $output[] = $o2; // pop the argument expression stuff and push onto the output - } - // If we've a comma when we're expecting an operand, then what we actually have is a null operand; - // so push a null onto the stack - if (($expectingOperand) || (!$expectingOperator)) { - $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); - } - // make sure there was a function - $d = $stack->last(2); - if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) - return $this->_raiseFormulaError("Formula Error: Unexpected ,"); - $d = $stack->pop(); - $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count - $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again - $expectingOperator = FALSE; - $expectingOperand = TRUE; - ++$index; - - } elseif ($opCharacter == '(' && !$expectingOperator) { -// echo 'Element is an Opening Bracket<br />'; - $stack->push('Brace', '('); - ++$index; - - } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number? - $expectingOperator = TRUE; - $expectingOperand = FALSE; - $val = $match[1]; - $length = strlen($val); -// echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />'; - - if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { - $val = preg_replace('/\s/u','',$val); -// echo 'Element '.$val.' is a Function<br />'; - if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function - $stack->push('Function', strtoupper($val)); - $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch); - if ($ax) { - $stack->push('Operand Count for Function '.strtoupper($val).')', 0); - $expectingOperator = TRUE; - } else { - $stack->push('Operand Count for Function '.strtoupper($val).')', 1); - $expectingOperator = FALSE; - } - $stack->push('Brace', '('); - } else { // it's a var w/ implicit multiplication - $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL); - } - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) { -// echo 'Element '.$val.' is a Cell reference<br />'; - // Watch for this case-change when modifying to allow cell references in different worksheets... - // Should only be applied to the actual cell column, not the worksheet name - - // If the last entry on the stack was a : operator, then we have a cell range reference - $testPrevOp = $stack->last(1); - if ($testPrevOp['value'] == ':') { - // If we have a worksheet reference, then we're playing with a 3D reference - if ($matches[2] == '') { - // Otherwise, we 'inherit' the worksheet reference from the start cell reference - // The start of the cell range reference should be the last entry in $output - $startCellRef = $output[count($output)-1]['value']; - preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches); - if ($startMatches[2] > '') { - $val = $startMatches[2].'!'.$val; - } - } else { - return $this->_raiseFormulaError("3D Range references are not yet supported"); - } - } - - $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val); -// $expectingOperator = FALSE; - } else { // it's a variable, constant, string, number or boolean -// echo 'Element is a Variable, Constant, String, Number or Boolean<br />'; - // If the last entry on the stack was a : operator, then we may have a row or column range reference - $testPrevOp = $stack->last(1); - if ($testPrevOp['value'] == ':') { - $startRowColRef = $output[count($output)-1]['value']; - $rangeWS1 = ''; - if (strpos('!',$startRowColRef) !== FALSE) { - list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef); - } - if ($rangeWS1 != '') $rangeWS1 .= '!'; - $rangeWS2 = $rangeWS1; - if (strpos('!',$val) !== FALSE) { - list($rangeWS2,$val) = explode('!',$val); - } - if ($rangeWS2 != '') $rangeWS2 .= '!'; - if ((is_integer($startRowColRef)) && (ctype_digit($val)) && - ($startRowColRef <= 1048576) && ($val <= 1048576)) { - // Row range - $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007 - $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef; - $val = $rangeWS2.$endRowColRef.$val; - } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) && - (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) { - // Column range - $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007 - $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1'; - $val = $rangeWS2.$val.$endRowColRef; - } - } - - $localeConstant = FALSE; - if ($opCharacter == '"') { -// echo 'Element is a String<br />'; - // UnEscape any quotes within the string - $val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val))); - } elseif (is_numeric($val)) { -// echo 'Element is a Number<br />'; - if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { -// echo 'Casting '.$val.' to float<br />'; - $val = (float) $val; - } else { -// echo 'Casting '.$val.' to integer<br />'; - $val = (integer) $val; - } - } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) { - $excelConstant = trim(strtoupper($val)); -// echo 'Element '.$excelConstant.' is an Excel Constant<br />'; - $val = self::$_ExcelConstants[$excelConstant]; - } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) { -// echo 'Element '.$localeConstant.' is an Excel Constant<br />'; - $val = self::$_ExcelConstants[$localeConstant]; - } - $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL); - if ($localeConstant) { $details['localeValue'] = $localeConstant; } - $output[] = $details; - } - $index += $length; - - } elseif ($opCharacter == '$') { // absolute row or column range - ++$index; - } elseif ($opCharacter == ')') { // miscellaneous error checking - if ($expectingOperand) { - $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); - $expectingOperand = FALSE; - $expectingOperator = TRUE; - } else { - return $this->_raiseFormulaError("Formula Error: Unexpected ')'"); - } - } elseif (isset(self::$_operators[$opCharacter]) && !$expectingOperator) { - return $this->_raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'"); - } else { // I don't even want to know what you did to get here - return $this->_raiseFormulaError("Formula Error: An unexpected error occured"); - } - // Test for end of formula string - if ($index == strlen($formula)) { - // Did we end with an operator?. - // Only valid for the % unary operator - if ((isset(self::$_operators[$opCharacter])) && ($opCharacter != '%')) { - return $this->_raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands"); - } else { - break; - } - } - // Ignore white space - while (($formula{$index} == "\n") || ($formula{$index} == "\r")) { - ++$index; - } - if ($formula{$index} == ' ') { - while ($formula{$index} == ' ') { - ++$index; - } - // If we're expecting an operator, but only have a space between the previous and next operands (and both are - // Cell References) then we have an INTERSECTION operator -// echo 'Possible Intersect Operator<br />'; - if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) && - ($output[count($output)-1]['type'] == 'Cell Reference')) { -// echo 'Element is an Intersect Operator<br />'; - while($stack->count() > 0 && - ($o2 = $stack->last()) && - isset(self::$_operators[$o2['value']]) && - @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { - $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output - } - $stack->push('Binary Operator','|'); // Put an Intersect Operator on the stack - $expectingOperator = FALSE; - } - } - } - - while (($op = $stack->pop()) !== NULL) { // pop everything off the stack and push onto output - if ((is_array($op) && $op['value'] == '(') || ($op === '(')) - return $this->_raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced - $output[] = $op; - } - return $output; - } // function _parseFormula() - - - private static function _dataTestReference(&$operandData) - { - $operand = $operandData['value']; - if (($operandData['reference'] === NULL) && (is_array($operand))) { - $rKeys = array_keys($operand); - $rowKey = array_shift($rKeys); - $cKeys = array_keys(array_keys($operand[$rowKey])); - $colKey = array_shift($cKeys); - if (ctype_upper($colKey)) { - $operandData['reference'] = $colKey.$rowKey; - } - } - return $operand; - } - - // evaluate postfix notation - private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) { - if ($tokens == FALSE) return FALSE; - - // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection), - // so we store the parent cell collection so that we can re-attach it when necessary - $pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; - $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null; - $stack = new PHPExcel_Calculation_Token_Stack; - - // Loop through each token in turn - foreach ($tokens as $tokenData) { -// print_r($tokenData); -// echo '<br />'; - $token = $tokenData['value']; -// echo '<b>Token is '.$token.'</b><br />'; - // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack - if (isset(self::$_binaryOperators[$token])) { -// echo 'Token is a binary operator<br />'; - // We must have two operands, error if we don't - if (($operand2Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); - if (($operand1Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); - - $operand1 = self::_dataTestReference($operand1Data); - $operand2 = self::_dataTestReference($operand2Data); - - // Log what we're doing - if ($token == ':') { - $this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); - } else { - $this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); - } - - // Process the operation in the appropriate manner - switch ($token) { - // Comparison (Boolean) Operators - case '>' : // Greater than - case '<' : // Less than - case '>=' : // Greater than or Equal to - case '<=' : // Less than or Equal to - case '=' : // Equality - case '<>' : // Inequality - $this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack); - break; - // Binary Operators - case ':' : // Range - $sheet1 = $sheet2 = ''; - if (strpos($operand1Data['reference'],'!') !== FALSE) { - list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']); - } else { - $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : ''; - } - if (strpos($operand2Data['reference'],'!') !== FALSE) { - list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']); - } else { - $sheet2 = $sheet1; - } - if ($sheet1 == $sheet2) { - if ($operand1Data['reference'] === NULL) { - if ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) { - $operand1Data['reference'] = $pCell->getColumn().$operand1Data['value']; - } elseif (trim($operand1Data['reference']) == '') { - $operand1Data['reference'] = $pCell->getCoordinate(); - } else { - $operand1Data['reference'] = $operand1Data['value'].$pCell->getRow(); - } - } - if ($operand2Data['reference'] === NULL) { - if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) { - $operand2Data['reference'] = $pCell->getColumn().$operand2Data['value']; - } elseif (trim($operand2Data['reference']) == '') { - $operand2Data['reference'] = $pCell->getCoordinate(); - } else { - $operand2Data['reference'] = $operand2Data['value'].$pCell->getRow(); - } - } - - $oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference'])); - $oCol = $oRow = array(); - foreach($oData as $oDatum) { - $oCR = PHPExcel_Cell::coordinateFromString($oDatum); - $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1; - $oRow[] = $oCR[1]; - } - $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); - if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE); - } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); - } - $stack->push('Cell Reference',$cellValue,$cellRef); - } else { - $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL); - } - - break; - case '+' : // Addition - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack); - break; - case '-' : // Subtraction - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack); - break; - case '*' : // Multiplication - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack); - break; - case '/' : // Division - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack); - break; - case '^' : // Exponential - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack); - break; - case '&' : // Concatenation - // If either of the operands is a matrix, we need to treat them both as matrices - // (converting the other operand to a matrix if need be); then perform the required - // matrix operation - if (is_bool($operand1)) { - $operand1 = ($operand1) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; - } - if (is_bool($operand2)) { - $operand2 = ($operand2) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; - } - if ((is_array($operand1)) || (is_array($operand2))) { - // Ensure that both operands are arrays/matrices - self::_checkMatrixOperands($operand1,$operand2,2); - try { - // Convert operand 1 from a PHP array to a matrix - $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); - // Perform the required operation against the operand 1 matrix, passing in operand 2 - $matrixResult = $matrix->concat($operand2); - $result = $matrixResult->getArray(); - } catch (PHPExcel_Exception $ex) { - $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); - $result = '#VALUE!'; - } - } else { - $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"'; - } - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - $stack->push('Value',$result); - break; - case '|' : // Intersect - $rowIntersect = array_intersect_key($operand1,$operand2); - $cellIntersect = $oCol = $oRow = array(); - foreach(array_keys($rowIntersect) as $row) { - $oRow[] = $row; - foreach($rowIntersect[$row] as $col => $data) { - $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1; - $cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]); - } - } - $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); - $stack->push('Value',$cellIntersect,$cellRef); - break; - } - - // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on - } elseif (($token === '~') || ($token === '%')) { -// echo 'Token is a unary operator<br />'; - if (($arg = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); - $arg = $arg['value']; - if ($token === '~') { -// echo 'Token is a negation operator<br />'; - $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg)); - $multiplier = -1; - } else { -// echo 'Token is a percentile operator<br />'; - $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg)); - $multiplier = 0.01; - } - if (is_array($arg)) { - self::_checkMatrixOperands($arg,$multiplier,2); - try { - $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg); - $matrixResult = $matrix1->arrayTimesEquals($multiplier); - $result = $matrixResult->getArray(); - } catch (PHPExcel_Exception $ex) { - $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); - $result = '#VALUE!'; - } - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - $stack->push('Value',$result); - } else { - $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack); - } - - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { - $cellRef = NULL; -// echo 'Element '.$token.' is a Cell reference<br />'; - if (isset($matches[8])) { -// echo 'Reference is a Range of cells<br />'; - if ($pCell === NULL) { -// We can't access the range, so return a REF error - $cellValue = PHPExcel_Calculation_Functions::REF(); - } else { - $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10]; - if ($matches[2] > '') { - $matches[2] = trim($matches[2],"\"'"); - if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { - // It's a Reference to an external workbook (not currently supported) - return $this->_raiseFormulaError('Unable to access External Workbook'); - } - $matches[2] = trim($matches[2],"\"'"); -// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; - $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); - if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); - } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); - } - $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); -// $cellRef = $matches[2].'!'.$cellRef; - } else { -// echo '$cellRef='.$cellRef.' in current worksheet<br />'; - $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet'); - if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); - } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); - } - $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); - } - } - } else { -// echo 'Reference is a single Cell<br />'; - if ($pCell === NULL) { -// We can't access the cell, so return a REF error - $cellValue = PHPExcel_Calculation_Functions::REF(); - } else { - $cellRef = $matches[6].$matches[7]; - if ($matches[2] > '') { - $matches[2] = trim($matches[2],"\"'"); - if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { - // It's a Reference to an external workbook (not currently supported) - return $this->_raiseFormulaError('Unable to access External Workbook'); - } -// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; - $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); - if ($pCellParent !== NULL) { - $cellSheet = $this->_workbook->getSheetByName($matches[2]); - if ($cellSheet && $cellSheet->cellExists($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); - $pCell->attach($pCellParent); - } else { - $cellValue = NULL; - } - } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); - } - $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); -// $cellRef = $matches[2].'!'.$cellRef; - } else { -// echo '$cellRef='.$cellRef.' in current worksheet<br />'; - $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet'); - if ($pCellParent->isDataSet($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); - $pCell->attach($pCellParent); - } else { - $cellValue = NULL; - } - $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); - } - } - } - $stack->push('Value',$cellValue,$cellRef); - - // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) { -// echo 'Token is a function<br />'; - $functionName = $matches[1]; - $argCount = $stack->pop(); - $argCount = $argCount['value']; - if ($functionName != 'MKMATRIX') { - $this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); - } - if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function - if (isset(self::$_PHPExcelFunctions[$functionName])) { - $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; - $passByReference = isset(self::$_PHPExcelFunctions[$functionName]['passByReference']); - $passCellReference = isset(self::$_PHPExcelFunctions[$functionName]['passCellReference']); - } elseif (isset(self::$_controlFunctions[$functionName])) { - $functionCall = self::$_controlFunctions[$functionName]['functionCall']; - $passByReference = isset(self::$_controlFunctions[$functionName]['passByReference']); - $passCellReference = isset(self::$_controlFunctions[$functionName]['passCellReference']); - } - // get the arguments for this function -// echo 'Function '.$functionName.' expects '.$argCount.' arguments<br />'; - $args = $argArrayVals = array(); - for ($i = 0; $i < $argCount; ++$i) { - $arg = $stack->pop(); - $a = $argCount - $i - 1; - if (($passByReference) && - (isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) && - (self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) { - if ($arg['reference'] === NULL) { - $args[] = $cellID; - if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($cellID); } - } else { - $args[] = $arg['reference']; - if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['reference']); } - } - } else { - $args[] = self::_unwrapResult($arg['value']); - if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['value']); } - } - } - // Reverse the order of the arguments - krsort($args); - if (($passByReference) && ($argCount == 0)) { - $args[] = $cellID; - $argArrayVals[] = $this->_showValue($cellID); - } -// echo 'Arguments are: '; -// print_r($args); -// echo '<br />'; - if ($functionName != 'MKMATRIX') { - if ($this->_debugLog->getWriteDebugLog()) { - krsort($argArrayVals); - $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); - } - } - // Process each argument in turn, building the return value as an array -// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) { -// $operand1 = $args[1]; -// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1)); -// $result = array(); -// $row = 0; -// foreach($operand1 as $args) { -// if (is_array($args)) { -// foreach($args as $arg) { -// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); -// $r = call_user_func_array($functionCall,$arg); -// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); -// $result[$row][] = $r; -// } -// ++$row; -// } else { -// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); -// $r = call_user_func_array($functionCall,$args); -// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); -// $result[] = $r; -// } -// } -// } else { - // Process the argument with the appropriate function call - if ($passCellReference) { - $args[] = $pCell; - } - if (strpos($functionCall,'::') !== FALSE) { - $result = call_user_func_array(explode('::',$functionCall),$args); - } else { - foreach($args as &$arg) { - $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg); - } - unset($arg); - $result = call_user_func_array($functionCall,$args); - } -// } - if ($functionName != 'MKMATRIX') { - $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); - } - $stack->push('Value',self::_wrapResult($result)); - } - - } else { - // if the token is a number, boolean, string or an Excel error, push it onto the stack - if (isset(self::$_ExcelConstants[strtoupper($token)])) { - $excelConstant = strtoupper($token); -// echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />'; - $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]); - $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); - } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { -// echo 'Token is a number, boolean, string, null or an Excel error<br />'; - $stack->push('Value',$token); - // if the token is a named range, push the named range name onto the stack - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) { -// echo 'Token is a named range<br />'; - $namedRange = $matches[6]; -// echo 'Named Range is '.$namedRange.'<br />'; - $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange); - $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE); - $pCell->attach($pCellParent); - $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); - $stack->push('Named Range',$cellValue,$namedRange); - } else { - return $this->_raiseFormulaError("undefined variable '$token'"); - } - } - } - // when we're out of tokens, the stack should have a single element, the final result - if ($stack->count() != 1) return $this->_raiseFormulaError("internal error"); - $output = $stack->pop(); - $output = $output['value']; - -// if ((is_array($output)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { -// return array_shift(PHPExcel_Calculation_Functions::flattenArray($output)); -// } - return $output; - } // function _processTokenStack() - - - private function _validateBinaryOperand($cellID, &$operand, &$stack) { - if (is_array($operand)) { - if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { - do { - $operand = array_pop($operand); - } while (is_array($operand)); - } - } - // Numbers, matrices and booleans can pass straight through, as they're already valid - if (is_string($operand)) { - // We only need special validations for the operand if it is a string - // Start by stripping off the quotation marks we use to identify true excel string values internally - if ($operand > '' && $operand{0} == '"') { $operand = self::_unwrapResult($operand); } - // If the string is a numeric value, we treat it as a numeric, so no further testing - if (!is_numeric($operand)) { - // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations - if ($operand > '' && $operand{0} == '#') { - $stack->push('Value', $operand); - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand)); - return FALSE; - } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { - // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations - $stack->push('Value', '#VALUE!'); - $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); - return FALSE; - } - } - } - - // return a true if the value of the operand is one that we can use in normal binary operations - return TRUE; - } // function _validateBinaryOperand() - - - private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) { - // If we're dealing with matrix operations, we want a matrix result - if ((is_array($operand1)) || (is_array($operand2))) { - $result = array(); - if ((is_array($operand1)) && (!is_array($operand2))) { - foreach($operand1 as $x => $operandData) { - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); - $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack); - $r = $stack->pop(); - $result[$x] = $r['value']; - } - } elseif ((!is_array($operand1)) && (is_array($operand2))) { - foreach($operand2 as $x => $operandData) { - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); - $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack); - $r = $stack->pop(); - $result[$x] = $r['value']; - } - } else { - if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } - foreach($operand1 as $x => $operandData) { - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); - $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); - $r = $stack->pop(); - $result[$x] = $r['value']; - } - } - // Log the result details - $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); - // And push the result onto the stack - $stack->push('Array',$result); - return TRUE; - } - - // Simple validate the two operands if they are string values - if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); } - if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); } - - // Use case insensitive comparaison if not OpenOffice mode - if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) - { - if (is_string($operand1)) { - $operand1 = strtoupper($operand1); - } - - if (is_string($operand2)) { - $operand2 = strtoupper($operand2); - } - } - - $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE; - - // execute the necessary operation - switch ($operation) { - // Greater than - case '>': - if ($useLowercaseFirstComparison) { - $result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0; - } else { - $result = ($operand1 > $operand2); - } - break; - // Less than - case '<': - if ($useLowercaseFirstComparison) { - $result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0; - } else { - $result = ($operand1 < $operand2); - } - break; - // Equality - case '=': + while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( + if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + else $output[] = $o2; // pop the argument expression stuff and push onto the output + } + // If we've a comma when we're expecting an operand, then what we actually have is a null operand; + // so push a null onto the stack + if (($expectingOperand) || (!$expectingOperator)) { + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); + } + // make sure there was a function + $d = $stack->last(2); + if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) + return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + $d = $stack->pop(); + $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count + $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again + $expectingOperator = FALSE; + $expectingOperand = TRUE; + ++$index; + + } elseif ($opCharacter == '(' && !$expectingOperator) { +// echo 'Element is an Opening Bracket<br />'; + $stack->push('Brace', '('); + ++$index; + + } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number? + $expectingOperator = TRUE; + $expectingOperand = FALSE; + $val = $match[1]; + $length = strlen($val); +// echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />'; + + if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { + $val = preg_replace('/\s/u','',$val); +// echo 'Element '.$val.' is a Function<br />'; + if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function + $stack->push('Function', strtoupper($val)); + $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch); + if ($ax) { + $stack->push('Operand Count for Function '.strtoupper($val).')', 0); + $expectingOperator = TRUE; + } else { + $stack->push('Operand Count for Function '.strtoupper($val).')', 1); + $expectingOperator = FALSE; + } + $stack->push('Brace', '('); + } else { // it's a var w/ implicit multiplication + $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL); + } + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) { +// echo 'Element '.$val.' is a Cell reference<br />'; + // Watch for this case-change when modifying to allow cell references in different worksheets... + // Should only be applied to the actual cell column, not the worksheet name + + // If the last entry on the stack was a : operator, then we have a cell range reference + $testPrevOp = $stack->last(1); + if ($testPrevOp['value'] == ':') { + // If we have a worksheet reference, then we're playing with a 3D reference + if ($matches[2] == '') { + // Otherwise, we 'inherit' the worksheet reference from the start cell reference + // The start of the cell range reference should be the last entry in $output + $startCellRef = $output[count($output)-1]['value']; + preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches); + if ($startMatches[2] > '') { + $val = $startMatches[2].'!'.$val; + } + } else { + return $this->_raiseFormulaError("3D Range references are not yet supported"); + } + } + + $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val); +// $expectingOperator = FALSE; + } else { // it's a variable, constant, string, number or boolean +// echo 'Element is a Variable, Constant, String, Number or Boolean<br />'; + // If the last entry on the stack was a : operator, then we may have a row or column range reference + $testPrevOp = $stack->last(1); + if ($testPrevOp['value'] == ':') { + $startRowColRef = $output[count($output)-1]['value']; + $rangeWS1 = ''; + if (strpos('!',$startRowColRef) !== FALSE) { + list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef); + } + if ($rangeWS1 != '') $rangeWS1 .= '!'; + $rangeWS2 = $rangeWS1; + if (strpos('!',$val) !== FALSE) { + list($rangeWS2,$val) = explode('!',$val); + } + if ($rangeWS2 != '') $rangeWS2 .= '!'; + if ((is_integer($startRowColRef)) && (ctype_digit($val)) && + ($startRowColRef <= 1048576) && ($val <= 1048576)) { + // Row range + $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007 + $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef; + $val = $rangeWS2.$endRowColRef.$val; + } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) && + (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) { + // Column range + $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007 + $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1'; + $val = $rangeWS2.$val.$endRowColRef; + } + } + + $localeConstant = FALSE; + if ($opCharacter == '"') { +// echo 'Element is a String<br />'; + // UnEscape any quotes within the string + $val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val))); + } elseif (is_numeric($val)) { +// echo 'Element is a Number<br />'; + if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { +// echo 'Casting '.$val.' to float<br />'; + $val = (float) $val; + } else { +// echo 'Casting '.$val.' to integer<br />'; + $val = (integer) $val; + } + } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) { + $excelConstant = trim(strtoupper($val)); +// echo 'Element '.$excelConstant.' is an Excel Constant<br />'; + $val = self::$_ExcelConstants[$excelConstant]; + } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) { +// echo 'Element '.$localeConstant.' is an Excel Constant<br />'; + $val = self::$_ExcelConstants[$localeConstant]; + } + $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL); + if ($localeConstant) { $details['localeValue'] = $localeConstant; } + $output[] = $details; + } + $index += $length; + + } elseif ($opCharacter == '$') { // absolute row or column range + ++$index; + } elseif ($opCharacter == ')') { // miscellaneous error checking + if ($expectingOperand) { + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); + $expectingOperand = FALSE; + $expectingOperator = TRUE; + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected ')'"); + } + } elseif (isset(self::$_operators[$opCharacter]) && !$expectingOperator) { + return $this->_raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'"); + } else { // I don't even want to know what you did to get here + return $this->_raiseFormulaError("Formula Error: An unexpected error occured"); + } + // Test for end of formula string + if ($index == strlen($formula)) { + // Did we end with an operator?. + // Only valid for the % unary operator + if ((isset(self::$_operators[$opCharacter])) && ($opCharacter != '%')) { + return $this->_raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands"); + } else { + break; + } + } + // Ignore white space + while (($formula{$index} == "\n") || ($formula{$index} == "\r")) { + ++$index; + } + if ($formula{$index} == ' ') { + while ($formula{$index} == ' ') { + ++$index; + } + // If we're expecting an operator, but only have a space between the previous and next operands (and both are + // Cell References) then we have an INTERSECTION operator +// echo 'Possible Intersect Operator<br />'; + if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) && + ($output[count($output)-1]['type'] == 'Cell Reference')) { +// echo 'Element is an Intersect Operator<br />'; + while($stack->count() > 0 && + ($o2 = $stack->last()) && + isset(self::$_operators[$o2['value']]) && + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { + $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output + } + $stack->push('Binary Operator','|'); // Put an Intersect Operator on the stack + $expectingOperator = FALSE; + } + } + } + + while (($op = $stack->pop()) !== NULL) { // pop everything off the stack and push onto output + if ((is_array($op) && $op['value'] == '(') || ($op === '(')) + return $this->_raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced + $output[] = $op; + } + return $output; + } // function _parseFormula() + + + private static function _dataTestReference(&$operandData) + { + $operand = $operandData['value']; + if (($operandData['reference'] === NULL) && (is_array($operand))) { + $rKeys = array_keys($operand); + $rowKey = array_shift($rKeys); + $cKeys = array_keys(array_keys($operand[$rowKey])); + $colKey = array_shift($cKeys); + if (ctype_upper($colKey)) { + $operandData['reference'] = $colKey.$rowKey; + } + } + return $operand; + } + + // evaluate postfix notation + private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) { + if ($tokens == FALSE) return FALSE; + + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection), + // so we store the parent cell collection so that we can re-attach it when necessary + $pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null; + $stack = new PHPExcel_Calculation_Token_Stack; + + // Loop through each token in turn + foreach ($tokens as $tokenData) { +// print_r($tokenData); +// echo '<br />'; + $token = $tokenData['value']; +// echo '<b>Token is '.$token.'</b><br />'; + // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack + if (isset(self::$_binaryOperators[$token])) { +// echo 'Token is a binary operator<br />'; + // We must have two operands, error if we don't + if (($operand2Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + if (($operand1Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + + $operand1 = self::_dataTestReference($operand1Data); + $operand2 = self::_dataTestReference($operand2Data); + + // Log what we're doing + if ($token == ':') { + $this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); + } else { + $this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); + } + + // Process the operation in the appropriate manner + switch ($token) { + // Comparison (Boolean) Operators + case '>' : // Greater than + case '<' : // Less than + case '>=' : // Greater than or Equal to + case '<=' : // Less than or Equal to + case '=' : // Equality + case '<>' : // Inequality + $this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack); + break; + // Binary Operators + case ':' : // Range + $sheet1 = $sheet2 = ''; + if (strpos($operand1Data['reference'],'!') !== FALSE) { + list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']); + } else { + $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : ''; + } + if (strpos($operand2Data['reference'],'!') !== FALSE) { + list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']); + } else { + $sheet2 = $sheet1; + } + if ($sheet1 == $sheet2) { + if ($operand1Data['reference'] === NULL) { + if ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) { + $operand1Data['reference'] = $pCell->getColumn().$operand1Data['value']; + } elseif (trim($operand1Data['reference']) == '') { + $operand1Data['reference'] = $pCell->getCoordinate(); + } else { + $operand1Data['reference'] = $operand1Data['value'].$pCell->getRow(); + } + } + if ($operand2Data['reference'] === NULL) { + if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) { + $operand2Data['reference'] = $pCell->getColumn().$operand2Data['value']; + } elseif (trim($operand2Data['reference']) == '') { + $operand2Data['reference'] = $pCell->getCoordinate(); + } else { + $operand2Data['reference'] = $operand2Data['value'].$pCell->getRow(); + } + } + + $oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference'])); + $oCol = $oRow = array(); + foreach($oData as $oDatum) { + $oCR = PHPExcel_Cell::coordinateFromString($oDatum); + $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1; + $oRow[] = $oCR[1]; + } + $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $stack->push('Cell Reference',$cellValue,$cellRef); + } else { + $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL); + } + + break; + case '+' : // Addition + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack); + break; + case '-' : // Subtraction + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack); + break; + case '*' : // Multiplication + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack); + break; + case '/' : // Division + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack); + break; + case '^' : // Exponential + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack); + break; + case '&' : // Concatenation + // If either of the operands is a matrix, we need to treat them both as matrices + // (converting the other operand to a matrix if need be); then perform the required + // matrix operation + if (is_bool($operand1)) { + $operand1 = ($operand1) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + if (is_bool($operand2)) { + $operand2 = ($operand2) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + if ((is_array($operand1)) || (is_array($operand2))) { + // Ensure that both operands are arrays/matrices + self::_checkMatrixOperands($operand1,$operand2,2); + try { + // Convert operand 1 from a PHP array to a matrix + $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); + // Perform the required operation against the operand 1 matrix, passing in operand 2 + $matrixResult = $matrix->concat($operand2); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + } else { + $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"'; + } + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $stack->push('Value',$result); + break; + case '|' : // Intersect + $rowIntersect = array_intersect_key($operand1,$operand2); + $cellIntersect = $oCol = $oRow = array(); + foreach(array_keys($rowIntersect) as $row) { + $oRow[] = $row; + foreach($rowIntersect[$row] as $col => $data) { + $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1; + $cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]); + } + } + $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); + $stack->push('Value',$cellIntersect,$cellRef); + break; + } + + // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on + } elseif (($token === '~') || ($token === '%')) { +// echo 'Token is a unary operator<br />'; + if (($arg = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + $arg = $arg['value']; + if ($token === '~') { +// echo 'Token is a negation operator<br />'; + $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg)); + $multiplier = -1; + } else { +// echo 'Token is a percentile operator<br />'; + $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg)); + $multiplier = 0.01; + } + if (is_array($arg)) { + self::_checkMatrixOperands($arg,$multiplier,2); + try { + $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg); + $matrixResult = $matrix1->arrayTimesEquals($multiplier); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $stack->push('Value',$result); + } else { + $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack); + } + + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { + $cellRef = NULL; +// echo 'Element '.$token.' is a Cell reference<br />'; + if (isset($matches[8])) { +// echo 'Reference is a Range of cells<br />'; + if ($pCell === NULL) { +// We can't access the range, so return a REF error + $cellValue = PHPExcel_Calculation_Functions::REF(); + } else { + $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10]; + if ($matches[2] > '') { + $matches[2] = trim($matches[2],"\"'"); + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { + // It's a Reference to an external workbook (not currently supported) + return $this->_raiseFormulaError('Unable to access External Workbook'); + } + $matches[2] = trim($matches[2],"\"'"); +// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); +// $cellRef = $matches[2].'!'.$cellRef; + } else { +// echo '$cellRef='.$cellRef.' in current worksheet<br />'; + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet'); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + } + } + } else { +// echo 'Reference is a single Cell<br />'; + if ($pCell === NULL) { +// We can't access the cell, so return a REF error + $cellValue = PHPExcel_Calculation_Functions::REF(); + } else { + $cellRef = $matches[6].$matches[7]; + if ($matches[2] > '') { + $matches[2] = trim($matches[2],"\"'"); + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { + // It's a Reference to an external workbook (not currently supported) + return $this->_raiseFormulaError('Unable to access External Workbook'); + } +// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); + if ($pCellParent !== NULL) { + $cellSheet = $this->_workbook->getSheetByName($matches[2]); + if ($cellSheet && $cellSheet->cellExists($cellRef)) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); + $pCell->attach($pCellParent); + } else { + $cellValue = NULL; + } + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); +// $cellRef = $matches[2].'!'.$cellRef; + } else { +// echo '$cellRef='.$cellRef.' in current worksheet<br />'; + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet'); + if ($pCellParent->isDataSet($cellRef)) { + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); + $pCell->attach($pCellParent); + } else { + $cellValue = NULL; + } + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + } + } + } + $stack->push('Value',$cellValue,$cellRef); + + // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) { +// echo 'Token is a function<br />'; + $functionName = $matches[1]; + $argCount = $stack->pop(); + $argCount = $argCount['value']; + if ($functionName != 'MKMATRIX') { + $this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); + } + if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function + if (isset(self::$_PHPExcelFunctions[$functionName])) { + $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; + $passByReference = isset(self::$_PHPExcelFunctions[$functionName]['passByReference']); + $passCellReference = isset(self::$_PHPExcelFunctions[$functionName]['passCellReference']); + } elseif (isset(self::$_controlFunctions[$functionName])) { + $functionCall = self::$_controlFunctions[$functionName]['functionCall']; + $passByReference = isset(self::$_controlFunctions[$functionName]['passByReference']); + $passCellReference = isset(self::$_controlFunctions[$functionName]['passCellReference']); + } + // get the arguments for this function +// echo 'Function '.$functionName.' expects '.$argCount.' arguments<br />'; + $args = $argArrayVals = array(); + for ($i = 0; $i < $argCount; ++$i) { + $arg = $stack->pop(); + $a = $argCount - $i - 1; + if (($passByReference) && + (isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) && + (self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) { + if ($arg['reference'] === NULL) { + $args[] = $cellID; + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($cellID); } + } else { + $args[] = $arg['reference']; + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['reference']); } + } + } else { + $args[] = self::_unwrapResult($arg['value']); + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['value']); } + } + } + // Reverse the order of the arguments + krsort($args); + if (($passByReference) && ($argCount == 0)) { + $args[] = $cellID; + $argArrayVals[] = $this->_showValue($cellID); + } +// echo 'Arguments are: '; +// print_r($args); +// echo '<br />'; + if ($functionName != 'MKMATRIX') { + if ($this->_debugLog->getWriteDebugLog()) { + krsort($argArrayVals); + $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); + } + } + // Process each argument in turn, building the return value as an array +// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) { +// $operand1 = $args[1]; +// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1)); +// $result = array(); +// $row = 0; +// foreach($operand1 as $args) { +// if (is_array($args)) { +// foreach($args as $arg) { +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); +// $r = call_user_func_array($functionCall,$arg); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $result[$row][] = $r; +// } +// ++$row; +// } else { +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); +// $r = call_user_func_array($functionCall,$args); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $result[] = $r; +// } +// } +// } else { + // Process the argument with the appropriate function call + if ($passCellReference) { + $args[] = $pCell; + } + if (strpos($functionCall,'::') !== FALSE) { + $result = call_user_func_array(explode('::',$functionCall),$args); + } else { + foreach($args as &$arg) { + $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg); + } + unset($arg); + $result = call_user_func_array($functionCall,$args); + } +// } + if ($functionName != 'MKMATRIX') { + $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); + } + $stack->push('Value',self::_wrapResult($result)); + } + + } else { + // if the token is a number, boolean, string or an Excel error, push it onto the stack + if (isset(self::$_ExcelConstants[strtoupper($token)])) { + $excelConstant = strtoupper($token); +// echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />'; + $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]); + $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); + } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { +// echo 'Token is a number, boolean, string, null or an Excel error<br />'; + $stack->push('Value',$token); + // if the token is a named range, push the named range name onto the stack + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) { +// echo 'Token is a named range<br />'; + $namedRange = $matches[6]; +// echo 'Named Range is '.$namedRange.'<br />'; + $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange); + $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE); + $pCell->attach($pCellParent); + $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); + $stack->push('Named Range',$cellValue,$namedRange); + } else { + return $this->_raiseFormulaError("undefined variable '$token'"); + } + } + } + // when we're out of tokens, the stack should have a single element, the final result + if ($stack->count() != 1) return $this->_raiseFormulaError("internal error"); + $output = $stack->pop(); + $output = $output['value']; + +// if ((is_array($output)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { +// return array_shift(PHPExcel_Calculation_Functions::flattenArray($output)); +// } + return $output; + } // function _processTokenStack() + + + private function _validateBinaryOperand($cellID, &$operand, &$stack) { + if (is_array($operand)) { + if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { + do { + $operand = array_pop($operand); + } while (is_array($operand)); + } + } + // Numbers, matrices and booleans can pass straight through, as they're already valid + if (is_string($operand)) { + // We only need special validations for the operand if it is a string + // Start by stripping off the quotation marks we use to identify true excel string values internally + if ($operand > '' && $operand{0} == '"') { $operand = self::_unwrapResult($operand); } + // If the string is a numeric value, we treat it as a numeric, so no further testing + if (!is_numeric($operand)) { + // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations + if ($operand > '' && $operand{0} == '#') { + $stack->push('Value', $operand); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand)); + return FALSE; + } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { + // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations + $stack->push('Value', '#VALUE!'); + $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); + return FALSE; + } + } + } + + // return a true if the value of the operand is one that we can use in normal binary operations + return TRUE; + } // function _validateBinaryOperand() + + + private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) { + // If we're dealing with matrix operations, we want a matrix result + if ((is_array($operand1)) || (is_array($operand2))) { + $result = array(); + if ((is_array($operand1)) && (!is_array($operand2))) { + foreach($operand1 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } elseif ((!is_array($operand1)) && (is_array($operand2))) { + foreach($operand2 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); + $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } else { + if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } + foreach($operand1 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } + // Log the result details + $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Array',$result); + return TRUE; + } + + // Simple validate the two operands if they are string values + if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); } + if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); } + + // Use case insensitive comparaison if not OpenOffice mode + if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) + { + if (is_string($operand1)) { + $operand1 = strtoupper($operand1); + } + + if (is_string($operand2)) { + $operand2 = strtoupper($operand2); + } + } + + $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE; + + // execute the necessary operation + switch ($operation) { + // Greater than + case '>': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0; + } else { + $result = ($operand1 > $operand2); + } + break; + // Less than + case '<': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0; + } else { + $result = ($operand1 < $operand2); + } + break; + // Equality + case '=': if (is_numeric($operand1) && is_numeric($operand2)) { $result = (abs($operand1 - $operand2) < $this->delta); } else { $result = strcmp($operand1, $operand2) == 0; } - break; - // Greater than or equal - case '>=': + break; + // Greater than or equal + case '>=': if (is_numeric($operand1) && is_numeric($operand2)) { $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 > $operand2)); - } elseif ($useLowercaseFirstComparison) { - $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0; - } else { - $result = strcmp($operand1, $operand2) >= 0; - } - break; - // Less than or equal - case '<=': + } elseif ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0; + } else { + $result = strcmp($operand1, $operand2) >= 0; + } + break; + // Less than or equal + case '<=': if (is_numeric($operand1) && is_numeric($operand2)) { $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 < $operand2)); } elseif ($useLowercaseFirstComparison) { - $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0; - } else { - $result = strcmp($operand1, $operand2) <= 0; - } - break; - // Inequality - case '<>': + $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0; + } else { + $result = strcmp($operand1, $operand2) <= 0; + } + break; + // Inequality + case '<>': if (is_numeric($operand1) && is_numeric($operand2)) { $result = (abs($operand1 - $operand2) > 1E-14); } else { $result = strcmp($operand1, $operand2) != 0; } - break; - } - - // Log the result details - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - // And push the result onto the stack - $stack->push('Value',$result); - return true; - } - - /** - * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters - * @param string $str1 First string value for the comparison - * @param string $str2 Second string value for the comparison - * @return integer - */ - private function strcmpLowercaseFirst($str1, $str2) - { + break; + } + + // Log the result details + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Value',$result); + return true; + } + + /** + * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters + * @param string $str1 First string value for the comparison + * @param string $str2 Second string value for the comparison + * @return integer + */ + private function strcmpLowercaseFirst($str1, $str2) + { $inversedStr1 = PHPExcel_Shared_String::StrCaseReverse($str1); $inversedStr2 = PHPExcel_Shared_String::StrCaseReverse($str2); - return strcmp($inversedStr1, $inversedStr2); - } - - private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { - // Validate the two operands - if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; - if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; - - // If either of the operands is a matrix, we need to treat them both as matrices - // (converting the other operand to a matrix if need be); then perform the required - // matrix operation - if ((is_array($operand1)) || (is_array($operand2))) { - // Ensure that both operands are arrays/matrices of the same size - self::_checkMatrixOperands($operand1, $operand2, 2); - - try { - // Convert operand 1 from a PHP array to a matrix - $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); - // Perform the required operation against the operand 1 matrix, passing in operand 2 - $matrixResult = $matrix->$matrixFunction($operand2); - $result = $matrixResult->getArray(); - } catch (PHPExcel_Exception $ex) { - $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); - $result = '#VALUE!'; - } - } else { - if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) && - ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || + return strcmp($inversedStr1, $inversedStr2); + } + + private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { + // Validate the two operands + if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; + if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; + + // If either of the operands is a matrix, we need to treat them both as matrices + // (converting the other operand to a matrix if need be); then perform the required + // matrix operation + if ((is_array($operand1)) || (is_array($operand2))) { + // Ensure that both operands are arrays/matrices of the same size + self::_checkMatrixOperands($operand1, $operand2, 2); + + try { + // Convert operand 1 from a PHP array to a matrix + $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); + // Perform the required operation against the operand 1 matrix, passing in operand 2 + $matrixResult = $matrix->$matrixFunction($operand2); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + } else { + if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) && + ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) { - $result = PHPExcel_Calculation_Functions::VALUE(); - } else { - // If we're dealing with non-matrix operations, execute the necessary operation - switch ($operation) { - // Addition - case '+': - $result = $operand1 + $operand2; - break; - // Subtraction - case '-': - $result = $operand1 - $operand2; - break; - // Multiplication - case '*': - $result = $operand1 * $operand2; - break; - // Division - case '/': - if ($operand2 == 0) { - // Trap for Divide by Zero error - $stack->push('Value','#DIV/0!'); - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); - return FALSE; - } else { - $result = $operand1 / $operand2; - } - break; - // Power - case '^': - $result = pow($operand1, $operand2); - break; - } - } - } - - // Log the result details - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - // And push the result onto the stack - $stack->push('Value',$result); - return TRUE; - } // function _executeNumericBinaryOperation() - - - // trigger an error, but nicely, if need be - protected function _raiseFormulaError($errorMessage) { - $this->formulaError = $errorMessage; - $this->_cyclicReferenceStack->clear(); - if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); - trigger_error($errorMessage, E_USER_ERROR); - } // function _raiseFormulaError() - - - /** - * Extract range values - * - * @param string &$pRange String based range representation - * @param PHPExcel_Worksheet $pSheet Worksheet - * @param boolean $resetLog Flag indicating whether calculation log should be reset or not - * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. - * @throws PHPExcel_Calculation_Exception - */ - public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { - // Return value - $returnValue = array (); - -// echo 'extractCellRange('.$pRange.')',PHP_EOL; - if ($pSheet !== NULL) { - $pSheetName = $pSheet->getTitle(); -// echo 'Passed sheet name is '.$pSheetName.PHP_EOL; -// echo 'Range reference is '.$pRange.PHP_EOL; - if (strpos ($pRange, '!') !== false) { -// echo '$pRange reference includes sheet reference',PHP_EOL; - list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); -// echo 'New sheet name is '.$pSheetName,PHP_EOL; -// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; - $pSheet = $this->_workbook->getSheetByName($pSheetName); - } - - // Extract range - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); - $pRange = $pSheetName.'!'.$pRange; - if (!isset($aReferences[1])) { - // Single cell in range - sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow); - $cellValue = NULL; - if ($pSheet->cellExists($aReferences[0])) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } else { - // Extract cell data for all cells in the range - foreach ($aReferences as $reference) { - // Extract range - sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow); - $cellValue = NULL; - if ($pSheet->cellExists($reference)) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } - } - } - - // Return - return $returnValue; - } // function extractCellRange() - - - /** - * Extract range values - * - * @param string &$pRange String based range representation - * @param PHPExcel_Worksheet $pSheet Worksheet - * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. - * @param boolean $resetLog Flag indicating whether calculation log should be reset or not - * @throws PHPExcel_Calculation_Exception - */ - public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { - // Return value - $returnValue = array (); - -// echo 'extractNamedRange('.$pRange.')<br />'; - if ($pSheet !== NULL) { - $pSheetName = $pSheet->getTitle(); -// echo 'Current sheet name is '.$pSheetName.'<br />'; -// echo 'Range reference is '.$pRange.'<br />'; - if (strpos ($pRange, '!') !== false) { -// echo '$pRange reference includes sheet reference',PHP_EOL; - list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); -// echo 'New sheet name is '.$pSheetName,PHP_EOL; -// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; - $pSheet = $this->_workbook->getSheetByName($pSheetName); - } - - // Named range? - $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet); - if ($namedRange !== NULL) { - $pSheet = $namedRange->getWorksheet(); -// echo 'Named Range '.$pRange.' ('; - $pRange = $namedRange->getRange(); - $splitRange = PHPExcel_Cell::splitRange($pRange); - // Convert row and column references - if (ctype_alpha($splitRange[0][0])) { - $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow(); - } elseif(ctype_digit($splitRange[0][0])) { - $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1]; - } -// echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />'; - -// if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) { -// if (!$namedRange->getLocalOnly()) { -// $pSheet = $namedRange->getWorksheet(); -// } else { -// return $returnValue; -// } -// } - } else { - return PHPExcel_Calculation_Functions::REF(); - } - - // Extract range - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); -// var_dump($aReferences); - if (!isset($aReferences[1])) { - // Single cell (or single column or row) in range - list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); - $cellValue = NULL; - if ($pSheet->cellExists($aReferences[0])) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } else { - // Extract cell data for all cells in the range - foreach ($aReferences as $reference) { - // Extract range - list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference); -// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />'; - $cellValue = NULL; - if ($pSheet->cellExists($reference)) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } - } -// print_r($returnValue); -// echo '<br />'; - } - - // Return - return $returnValue; - } // function extractNamedRange() - - - /** - * Is a specific function implemented? - * - * @param string $pFunction Function Name - * @return boolean - */ - public function isImplemented($pFunction = '') { - $pFunction = strtoupper ($pFunction); - if (isset(self::$_PHPExcelFunctions[$pFunction])) { - return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); - } else { - return FALSE; - } - } // function isImplemented() - - - /** - * Get a list of all implemented functions as an array of function objects - * - * @return array of PHPExcel_Calculation_Function - */ - public function listFunctions() { - // Return value - $returnValue = array(); - // Loop functions - foreach(self::$_PHPExcelFunctions as $functionName => $function) { - if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { - $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'], - $functionName, - $function['functionCall'] - ); - } - } - - // Return - return $returnValue; - } // function listFunctions() - - - /** - * Get a list of all Excel function names - * - * @return array - */ - public function listAllFunctionNames() { - return array_keys(self::$_PHPExcelFunctions); - } // function listAllFunctionNames() - - /** - * Get a list of implemented Excel function names - * - * @return array - */ - public function listFunctionNames() { - // Return value - $returnValue = array(); - // Loop functions - foreach(self::$_PHPExcelFunctions as $functionName => $function) { - if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { - $returnValue[] = $functionName; - } - } - - // Return - return $returnValue; - } // function listFunctionNames() - -} // class PHPExcel_Calculation + $result = PHPExcel_Calculation_Functions::VALUE(); + } else { + // If we're dealing with non-matrix operations, execute the necessary operation + switch ($operation) { + // Addition + case '+': + $result = $operand1 + $operand2; + break; + // Subtraction + case '-': + $result = $operand1 - $operand2; + break; + // Multiplication + case '*': + $result = $operand1 * $operand2; + break; + // Division + case '/': + if ($operand2 == 0) { + // Trap for Divide by Zero error + $stack->push('Value','#DIV/0!'); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); + return FALSE; + } else { + $result = $operand1 / $operand2; + } + break; + // Power + case '^': + $result = pow($operand1, $operand2); + break; + } + } + } + + // Log the result details + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Value',$result); + return TRUE; + } // function _executeNumericBinaryOperation() + + + // trigger an error, but nicely, if need be + protected function _raiseFormulaError($errorMessage) { + $this->formulaError = $errorMessage; + $this->_cyclicReferenceStack->clear(); + if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); + trigger_error($errorMessage, E_USER_ERROR); + } // function _raiseFormulaError() + + + /** + * Extract range values + * + * @param string &$pRange String based range representation + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not + * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @throws PHPExcel_Calculation_Exception + */ + public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { + // Return value + $returnValue = array (); + +// echo 'extractCellRange('.$pRange.')',PHP_EOL; + if ($pSheet !== NULL) { + $pSheetName = $pSheet->getTitle(); +// echo 'Passed sheet name is '.$pSheetName.PHP_EOL; +// echo 'Range reference is '.$pRange.PHP_EOL; + if (strpos ($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference',PHP_EOL; + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName,PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + $pSheet = $this->_workbook->getSheetByName($pSheetName); + } + + // Extract range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); + $pRange = $pSheetName.'!'.$pRange; + if (!isset($aReferences[1])) { + // Single cell in range + sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow); + $cellValue = NULL; + if ($pSheet->cellExists($aReferences[0])) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } else { + // Extract cell data for all cells in the range + foreach ($aReferences as $reference) { + // Extract range + sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow); + $cellValue = NULL; + if ($pSheet->cellExists($reference)) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } + } + } + + // Return + return $returnValue; + } // function extractCellRange() + + + /** + * Extract range values + * + * @param string &$pRange String based range representation + * @param PHPExcel_Worksheet $pSheet Worksheet + * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not + * @throws PHPExcel_Calculation_Exception + */ + public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { + // Return value + $returnValue = array (); + +// echo 'extractNamedRange('.$pRange.')<br />'; + if ($pSheet !== NULL) { + $pSheetName = $pSheet->getTitle(); +// echo 'Current sheet name is '.$pSheetName.'<br />'; +// echo 'Range reference is '.$pRange.'<br />'; + if (strpos ($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference',PHP_EOL; + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName,PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + $pSheet = $this->_workbook->getSheetByName($pSheetName); + } + + // Named range? + $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet); + if ($namedRange !== NULL) { + $pSheet = $namedRange->getWorksheet(); +// echo 'Named Range '.$pRange.' ('; + $pRange = $namedRange->getRange(); + $splitRange = PHPExcel_Cell::splitRange($pRange); + // Convert row and column references + if (ctype_alpha($splitRange[0][0])) { + $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow(); + } elseif(ctype_digit($splitRange[0][0])) { + $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1]; + } +// echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />'; + +// if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) { +// if (!$namedRange->getLocalOnly()) { +// $pSheet = $namedRange->getWorksheet(); +// } else { +// return $returnValue; +// } +// } + } else { + return PHPExcel_Calculation_Functions::REF(); + } + + // Extract range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); +// var_dump($aReferences); + if (!isset($aReferences[1])) { + // Single cell (or single column or row) in range + list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); + $cellValue = NULL; + if ($pSheet->cellExists($aReferences[0])) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } else { + // Extract cell data for all cells in the range + foreach ($aReferences as $reference) { + // Extract range + list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference); +// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />'; + $cellValue = NULL; + if ($pSheet->cellExists($reference)) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } + } +// print_r($returnValue); +// echo '<br />'; + } + + // Return + return $returnValue; + } // function extractNamedRange() + + + /** + * Is a specific function implemented? + * + * @param string $pFunction Function Name + * @return boolean + */ + public function isImplemented($pFunction = '') { + $pFunction = strtoupper ($pFunction); + if (isset(self::$_PHPExcelFunctions[$pFunction])) { + return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); + } else { + return FALSE; + } + } // function isImplemented() + + + /** + * Get a list of all implemented functions as an array of function objects + * + * @return array of PHPExcel_Calculation_Function + */ + public function listFunctions() { + // Return value + $returnValue = array(); + // Loop functions + foreach(self::$_PHPExcelFunctions as $functionName => $function) { + if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { + $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'], + $functionName, + $function['functionCall'] + ); + } + } + + // Return + return $returnValue; + } // function listFunctions() + + + /** + * Get a list of all Excel function names + * + * @return array + */ + public function listAllFunctionNames() { + return array_keys(self::$_PHPExcelFunctions); + } // function listAllFunctionNames() + + /** + * Get a list of implemented Excel function names + * + * @return array + */ + public function listFunctionNames() { + // Return value + $returnValue = array(); + // Loop functions + foreach(self::$_PHPExcelFunctions as $functionName => $function) { + if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { + $returnValue[] = $functionName; + } + } + + // Return + return $returnValue; + } // function listFunctionNames() + +} // class PHPExcel_Calculation diff --git a/Classes/PHPExcel/DocumentSecurity.php b/Classes/PHPExcel/DocumentSecurity.php index 095501934..0887a2c38 100644 --- a/Classes/PHPExcel/DocumentSecurity.php +++ b/Classes/PHPExcel/DocumentSecurity.php @@ -76,11 +76,11 @@ public function __construct() } /** - * Is some sort of dcument security enabled? + * Is some sort of document security enabled? * * @return boolean */ - function isSecurityEnabled() + public function isSecurityEnabled() { return $this->_lockRevision || $this->_lockStructure || @@ -92,7 +92,7 @@ function isSecurityEnabled() * * @return boolean */ - function getLockRevision() + public function getLockRevision() { return $this->_lockRevision; } @@ -103,7 +103,7 @@ function getLockRevision() * @param boolean $pValue * @return PHPExcel_DocumentSecurity */ - function setLockRevision($pValue = false) + public function setLockRevision($pValue = false) { $this->_lockRevision = $pValue; return $this; @@ -114,7 +114,7 @@ function setLockRevision($pValue = false) * * @return boolean */ - function getLockStructure() + public function getLockStructure() { return $this->_lockStructure; } @@ -125,7 +125,7 @@ function getLockStructure() * @param boolean $pValue * @return PHPExcel_DocumentSecurity */ - function setLockStructure($pValue = false) + public function setLockStructure($pValue = false) { $this->_lockStructure = $pValue; return $this; @@ -136,7 +136,7 @@ function setLockStructure($pValue = false) * * @return boolean */ - function getLockWindows() + public function getLockWindows() { return $this->_lockWindows; } @@ -147,7 +147,7 @@ function getLockWindows() * @param boolean $pValue * @return PHPExcel_DocumentSecurity */ - function setLockWindows($pValue = false) + public function setLockWindows($pValue = false) { $this->_lockWindows = $pValue; return $this; @@ -158,7 +158,7 @@ function setLockWindows($pValue = false) * * @return string */ - function getRevisionsPassword() + public function getRevisionsPassword() { return $this->_revisionsPassword; } @@ -170,7 +170,7 @@ function getRevisionsPassword() * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true * @return PHPExcel_DocumentSecurity */ - function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) + public function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) { if (!$pAlreadyHashed) { $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); @@ -184,7 +184,7 @@ function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) * * @return string */ - function getWorkbookPassword() + public function getWorkbookPassword() { return $this->_workbookPassword; } @@ -196,7 +196,7 @@ function getWorkbookPassword() * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true * @return PHPExcel_DocumentSecurity */ - function setWorkbookPassword($pValue = '', $pAlreadyHashed = false) + public function setWorkbookPassword($pValue = '', $pAlreadyHashed = false) { if (!$pAlreadyHashed) { $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index 9e30ae8a7..d0c9a44d6 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -526,12 +526,12 @@ class PHPExcel_Helper_HTML protected $size; protected $color; - protected $bold = false; - protected $italic = false; - protected $underline = false; - protected $superscript = false; - protected $subscript = false; - protected $strikethrough = false; + protected $bold = false; + protected $italic = false; + protected $underline = false; + protected $superscript = false; + protected $subscript = false; + protected $strikethrough = false; protected $startTagCallbacks = array( 'font' => 'startFontTag', @@ -585,13 +585,13 @@ protected function initialise() { public function toRichTextObject($html) { $this->initialise(); - // Create a new DOM object + // Create a new DOM object $dom = new domDocument; - // Load the HTML file into the DOM object + // Load the HTML file into the DOM object // Note the use of error suppression, because typically this will be an html fragment, so not fully valid markup $loaded = @$dom->loadHTML($html); - // Discard excess white space + // Discard excess white space $dom->preserveWhiteSpace = false; $this->richTextObject = new PHPExcel_RichText();; diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index a72b92936..7226d4a4c 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Chart.php +++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php @@ -18,500 +18,500 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Reader_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Reader_Excel2007 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** * PHPExcel_Reader_Excel2007_Chart * - * @category PHPExcel - * @package PHPExcel_Reader_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Reader_Excel2007 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel2007_Chart { - private static function _getAttribute($component, $name, $format) { - $attributes = $component->attributes(); - if (isset($attributes[$name])) { - if ($format == 'string') { - return (string) $attributes[$name]; - } elseif ($format == 'integer') { - return (integer) $attributes[$name]; - } elseif ($format == 'boolean') { - return (boolean) ($attributes[$name] === '0' || $attributes[$name] !== 'true') ? false : true; - } else { - return (float) $attributes[$name]; - } - } - return null; - } // function _getAttribute() - - - private static function _readColor($color,$background=false) { - if (isset($color["rgb"])) { - return (string)$color["rgb"]; - } else if (isset($color["indexed"])) { - return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB(); - } - } - - - public static function readChart($chartElements,$chartName) { - $namespacesChartMeta = $chartElements->getNamespaces(true); - $chartElementsC = $chartElements->children($namespacesChartMeta['c']); - - $XaxisLabel = $YaxisLabel = $legend = $title = NULL; - $dispBlanksAs = $plotVisOnly = NULL; - - foreach($chartElementsC as $chartElementKey => $chartElement) { - switch ($chartElementKey) { - case "chart": - foreach($chartElement as $chartDetailsKey => $chartDetails) { - $chartDetailsC = $chartDetails->children($namespacesChartMeta['c']); - switch ($chartDetailsKey) { - case "plotArea": - $plotAreaLayout = $XaxisLable = $YaxisLable = null; - $plotSeries = $plotAttributes = array(); - foreach($chartDetails as $chartDetailKey => $chartDetail) { - switch ($chartDetailKey) { - case "layout": - $plotAreaLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'plotArea'); - break; - case "catAx": - if (isset($chartDetail->title)) { - $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); - } - break; - case "dateAx": - if (isset($chartDetail->title)) { - $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); - } - break; - case "valAx": - if (isset($chartDetail->title)) { - $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); - } - break; - case "barChart": - case "bar3DChart": - $barDirection = self::_getAttribute($chartDetail->barDir, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); - $plotSer->setPlotDirection($barDirection); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "lineChart": - case "line3DChart": - $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "areaChart": - case "area3DChart": - $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "doughnutChart": - case "pieChart": - case "pie3DChart": - $explosion = isset($chartDetail->ser->explosion); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); - $plotSer->setPlotStyle($explosion); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "scatterChart": - $scatterStyle = self::_getAttribute($chartDetail->scatterStyle, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); - $plotSer->setPlotStyle($scatterStyle); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "bubbleChart": - $bubbleScale = self::_getAttribute($chartDetail->bubbleScale, 'val', 'integer'); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); - $plotSer->setPlotStyle($bubbleScale); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "radarChart": - $radarStyle = self::_getAttribute($chartDetail->radarStyle, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); - $plotSer->setPlotStyle($radarStyle); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "surfaceChart": - case "surface3DChart": - $wireFrame = self::_getAttribute($chartDetail->wireframe, 'val', 'boolean'); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); - $plotSer->setPlotStyle($wireFrame); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "stockChart": - $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); - $plotAttributes = self::_readChartAttributes($plotAreaLayout); - break; - } - } - if ($plotAreaLayout == NULL) { - $plotAreaLayout = new PHPExcel_Chart_Layout(); - } - $plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout,$plotSeries); - self::_setChartAttributes($plotAreaLayout,$plotAttributes); - break; - case "plotVisOnly": - $plotVisOnly = self::_getAttribute($chartDetails, 'val', 'string'); - break; - case "dispBlanksAs": - $dispBlanksAs = self::_getAttribute($chartDetails, 'val', 'string'); - break; - case "title": - $title = self::_chartTitle($chartDetails,$namespacesChartMeta,'title'); - break; - case "legend": - $legendPos = 'r'; - $legendLayout = null; - $legendOverlay = false; - foreach($chartDetails as $chartDetailKey => $chartDetail) { - switch ($chartDetailKey) { - case "legendPos": - $legendPos = self::_getAttribute($chartDetail, 'val', 'string'); - break; - case "overlay": - $legendOverlay = self::_getAttribute($chartDetail, 'val', 'boolean'); - break; - case "layout": - $legendLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'legend'); - break; - } - } - $legend = new PHPExcel_Chart_Legend($legendPos, $legendLayout, $legendOverlay); - break; - } - } - } - } - $chart = new PHPExcel_Chart($chartName,$title,$legend,$plotArea,$plotVisOnly,$dispBlanksAs,$XaxisLabel,$YaxisLabel); - - return $chart; - } // function readChart() - - - private static function _chartTitle($titleDetails,$namespacesChartMeta,$type) { - $caption = array(); - $titleLayout = null; - foreach($titleDetails as $titleDetailKey => $chartDetail) { - switch ($titleDetailKey) { - case "tx": - $titleDetails = $chartDetail->rich->children($namespacesChartMeta['a']); - foreach($titleDetails as $titleKey => $titleDetail) { - switch ($titleKey) { - case "p": - $titleDetailPart = $titleDetail->children($namespacesChartMeta['a']); - $caption[] = self::_parseRichText($titleDetailPart); - } - } - break; - case "layout": - $titleLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta); - break; - } - } - - return new PHPExcel_Chart_Title($caption, $titleLayout); - } // function _chartTitle() - - - private static function _chartLayoutDetails($chartDetail,$namespacesChartMeta) { - if (!isset($chartDetail->manualLayout)) { - return null; - } - $details = $chartDetail->manualLayout->children($namespacesChartMeta['c']); - if (is_null($details)) { - return null; - } - $layout = array(); - foreach($details as $detailKey => $detail) { -// echo $detailKey,' => ',self::_getAttribute($detail, 'val', 'string'),PHP_EOL; - $layout[$detailKey] = self::_getAttribute($detail, 'val', 'string'); - } - return new PHPExcel_Chart_Layout($layout); - } // function _chartLayoutDetails() - - - private static function _chartDataSeries($chartDetail,$namespacesChartMeta,$plotType) { - $multiSeriesType = NULL; - $smoothLine = false; - $seriesLabel = $seriesCategory = $seriesValues = $plotOrder = array(); - - $seriesDetailSet = $chartDetail->children($namespacesChartMeta['c']); - foreach($seriesDetailSet as $seriesDetailKey => $seriesDetails) { - switch ($seriesDetailKey) { - case "grouping": - $multiSeriesType = self::_getAttribute($chartDetail->grouping, 'val', 'string'); - break; - case "ser": - $marker = NULL; - foreach($seriesDetails as $seriesKey => $seriesDetail) { - switch ($seriesKey) { - case "idx": - $seriesIndex = self::_getAttribute($seriesDetail, 'val', 'integer'); - break; - case "order": - $seriesOrder = self::_getAttribute($seriesDetail, 'val', 'integer'); - $plotOrder[$seriesIndex] = $seriesOrder; - break; - case "tx": - $seriesLabel[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta); - break; - case "marker": - $marker = self::_getAttribute($seriesDetail->symbol, 'val', 'string'); - break; - case "smooth": - $smoothLine = self::_getAttribute($seriesDetail, 'val', 'boolean'); - break; - case "cat": - $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta); - break; - case "val": - $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); - break; - case "xVal": - $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); - break; - case "yVal": - $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); - break; - } - } - } - } - return new PHPExcel_Chart_DataSeries($plotType,$multiSeriesType,$plotOrder,$seriesLabel,$seriesCategory,$seriesValues,$smoothLine); - } // function _chartDataSeries() - - - private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null, $smoothLine = false) { - if (isset($seriesDetail->strRef)) { - $seriesSource = (string) $seriesDetail->strRef->f; - $seriesData = self::_chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']),'s'); - - return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); - } elseif (isset($seriesDetail->numRef)) { - $seriesSource = (string) $seriesDetail->numRef->f; - $seriesData = self::_chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c'])); - - return new PHPExcel_Chart_DataSeriesValues('Number',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); - } elseif (isset($seriesDetail->multiLvlStrRef)) { - $seriesSource = (string) $seriesDetail->multiLvlStrRef->f; - $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']),'s'); - $seriesData['pointCount'] = count($seriesData['dataValues']); - - return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); - } elseif (isset($seriesDetail->multiLvlNumRef)) { - $seriesSource = (string) $seriesDetail->multiLvlNumRef->f; - $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']),'s'); - $seriesData['pointCount'] = count($seriesData['dataValues']); - - return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); - } - return null; - } // function _chartDataSeriesValueSet() - - - private static function _chartDataSeriesValues($seriesValueSet,$dataType='n') { - $seriesVal = array(); - $formatCode = ''; - $pointCount = 0; - - foreach($seriesValueSet as $seriesValueIdx => $seriesValue) { - switch ($seriesValueIdx) { - case 'ptCount': - $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); - break; - case 'formatCode': - $formatCode = (string) $seriesValue; - break; - case 'pt': - $pointVal = self::_getAttribute($seriesValue, 'idx', 'integer'); - if ($dataType == 's') { - $seriesVal[$pointVal] = (string) $seriesValue->v; - } else { - $seriesVal[$pointVal] = (float) $seriesValue->v; - } - break; - } - } - - if (empty($seriesVal)) { - $seriesVal = NULL; - } - - return array( 'formatCode' => $formatCode, - 'pointCount' => $pointCount, - 'dataValues' => $seriesVal - ); - } // function _chartDataSeriesValues() - - - private static function _chartDataSeriesValuesMultiLevel($seriesValueSet,$dataType='n') { - $seriesVal = array(); - $formatCode = ''; - $pointCount = 0; - - foreach($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) { - foreach($seriesLevel as $seriesValueIdx => $seriesValue) { - switch ($seriesValueIdx) { - case 'ptCount': - $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); - break; - case 'formatCode': - $formatCode = (string) $seriesValue; - break; - case 'pt': - $pointVal = self::_getAttribute($seriesValue, 'idx', 'integer'); - if ($dataType == 's') { - $seriesVal[$pointVal][] = (string) $seriesValue->v; - } else { - $seriesVal[$pointVal][] = (float) $seriesValue->v; - } - break; - } - } - } - - return array( 'formatCode' => $formatCode, - 'pointCount' => $pointCount, - 'dataValues' => $seriesVal - ); - } // function _chartDataSeriesValuesMultiLevel() - - private static function _parseRichText($titleDetailPart = null) { - $value = new PHPExcel_RichText(); - - foreach($titleDetailPart as $titleDetailElementKey => $titleDetailElement) { - if (isset($titleDetailElement->t)) { - $objText = $value->createTextRun( (string) $titleDetailElement->t ); - } - if (isset($titleDetailElement->rPr)) { - if (isset($titleDetailElement->rPr->rFont["val"])) { - $objText->getFont()->setName((string) $titleDetailElement->rPr->rFont["val"]); - } - - $fontSize = (self::_getAttribute($titleDetailElement->rPr, 'sz', 'integer')); - if (!is_null($fontSize)) { - $objText->getFont()->setSize(floor($fontSize / 100)); - } - - $fontColor = (self::_getAttribute($titleDetailElement->rPr, 'color', 'string')); - if (!is_null($fontColor)) { - $objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($fontColor) ) ); - } - - $bold = self::_getAttribute($titleDetailElement->rPr, 'b', 'boolean'); - if (!is_null($bold)) { - $objText->getFont()->setBold($bold); - } - - $italic = self::_getAttribute($titleDetailElement->rPr, 'i', 'boolean'); - if (!is_null($italic)) { - $objText->getFont()->setItalic($italic); - } - - $baseline = self::_getAttribute($titleDetailElement->rPr, 'baseline', 'integer'); - if (!is_null($baseline)) { - if ($baseline > 0) { - $objText->getFont()->setSuperScript(true); - } elseif($baseline < 0) { - $objText->getFont()->setSubScript(true); - } - } - - $underscore = (self::_getAttribute($titleDetailElement->rPr, 'u', 'string')); - if (!is_null($underscore)) { - if ($underscore == 'sng') { - $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); - } elseif($underscore == 'dbl') { - $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); - } else { - $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_NONE); - } - } - - $strikethrough = (self::_getAttribute($titleDetailElement->rPr, 's', 'string')); - if (!is_null($strikethrough)) { - if ($strikethrough == 'noStrike') { - $objText->getFont()->setStrikethrough(false); - } else { - $objText->getFont()->setStrikethrough(true); - } - } - } - } - - return $value; - } - - private static function _readChartAttributes($chartDetail) { - $plotAttributes = array(); - if (isset($chartDetail->dLbls)) { - if (isset($chartDetail->dLbls->howLegendKey)) { - $plotAttributes['showLegendKey'] = self::_getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string'); - } - if (isset($chartDetail->dLbls->showVal)) { - $plotAttributes['showVal'] = self::_getAttribute($chartDetail->dLbls->showVal, 'val', 'string'); - } - if (isset($chartDetail->dLbls->showCatName)) { - $plotAttributes['showCatName'] = self::_getAttribute($chartDetail->dLbls->showCatName, 'val', 'string'); - } - if (isset($chartDetail->dLbls->showSerName)) { - $plotAttributes['showSerName'] = self::_getAttribute($chartDetail->dLbls->showSerName, 'val', 'string'); - } - if (isset($chartDetail->dLbls->showPercent)) { - $plotAttributes['showPercent'] = self::_getAttribute($chartDetail->dLbls->showPercent, 'val', 'string'); - } - if (isset($chartDetail->dLbls->showBubbleSize)) { - $plotAttributes['showBubbleSize'] = self::_getAttribute($chartDetail->dLbls->showBubbleSize, 'val', 'string'); - } - if (isset($chartDetail->dLbls->showLeaderLines)) { - $plotAttributes['showLeaderLines'] = self::_getAttribute($chartDetail->dLbls->showLeaderLines, 'val', 'string'); - } - } - - return $plotAttributes; - } - - private static function _setChartAttributes($plotArea,$plotAttributes) - { - foreach($plotAttributes as $plotAttributeKey => $plotAttributeValue) { - switch($plotAttributeKey) { - case 'showLegendKey' : - $plotArea->setShowLegendKey($plotAttributeValue); - break; - case 'showVal' : - $plotArea->setShowVal($plotAttributeValue); - break; - case 'showCatName' : - $plotArea->setShowCatName($plotAttributeValue); - break; - case 'showSerName' : - $plotArea->setShowSerName($plotAttributeValue); - break; - case 'showPercent' : - $plotArea->setShowPercent($plotAttributeValue); - break; - case 'showBubbleSize' : - $plotArea->setShowBubbleSize($plotAttributeValue); - break; - case 'showLeaderLines' : - $plotArea->setShowLeaderLines($plotAttributeValue); - break; - } - } - } + private static function _getAttribute($component, $name, $format) { + $attributes = $component->attributes(); + if (isset($attributes[$name])) { + if ($format == 'string') { + return (string) $attributes[$name]; + } elseif ($format == 'integer') { + return (integer) $attributes[$name]; + } elseif ($format == 'boolean') { + return (boolean) ($attributes[$name] === '0' || $attributes[$name] !== 'true') ? false : true; + } else { + return (float) $attributes[$name]; + } + } + return null; + } // function _getAttribute() + + + private static function _readColor($color,$background=false) { + if (isset($color["rgb"])) { + return (string)$color["rgb"]; + } else if (isset($color["indexed"])) { + return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB(); + } + } + + + public static function readChart($chartElements,$chartName) { + $namespacesChartMeta = $chartElements->getNamespaces(true); + $chartElementsC = $chartElements->children($namespacesChartMeta['c']); + + $XaxisLabel = $YaxisLabel = $legend = $title = NULL; + $dispBlanksAs = $plotVisOnly = NULL; + + foreach($chartElementsC as $chartElementKey => $chartElement) { + switch ($chartElementKey) { + case "chart": + foreach($chartElement as $chartDetailsKey => $chartDetails) { + $chartDetailsC = $chartDetails->children($namespacesChartMeta['c']); + switch ($chartDetailsKey) { + case "plotArea": + $plotAreaLayout = $XaxisLable = $YaxisLable = null; + $plotSeries = $plotAttributes = array(); + foreach($chartDetails as $chartDetailKey => $chartDetail) { + switch ($chartDetailKey) { + case "layout": + $plotAreaLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'plotArea'); + break; + case "catAx": + if (isset($chartDetail->title)) { + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + } + break; + case "dateAx": + if (isset($chartDetail->title)) { + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + } + break; + case "valAx": + if (isset($chartDetail->title)) { + $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + } + break; + case "barChart": + case "bar3DChart": + $barDirection = self::_getAttribute($chartDetail->barDir, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotDirection($barDirection); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "lineChart": + case "line3DChart": + $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "areaChart": + case "area3DChart": + $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "doughnutChart": + case "pieChart": + case "pie3DChart": + $explosion = isset($chartDetail->ser->explosion); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($explosion); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "scatterChart": + $scatterStyle = self::_getAttribute($chartDetail->scatterStyle, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($scatterStyle); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "bubbleChart": + $bubbleScale = self::_getAttribute($chartDetail->bubbleScale, 'val', 'integer'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($bubbleScale); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "radarChart": + $radarStyle = self::_getAttribute($chartDetail->radarStyle, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($radarStyle); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "surfaceChart": + case "surface3DChart": + $wireFrame = self::_getAttribute($chartDetail->wireframe, 'val', 'boolean'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($wireFrame); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "stockChart": + $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotAttributes = self::_readChartAttributes($plotAreaLayout); + break; + } + } + if ($plotAreaLayout == NULL) { + $plotAreaLayout = new PHPExcel_Chart_Layout(); + } + $plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout,$plotSeries); + self::_setChartAttributes($plotAreaLayout,$plotAttributes); + break; + case "plotVisOnly": + $plotVisOnly = self::_getAttribute($chartDetails, 'val', 'string'); + break; + case "dispBlanksAs": + $dispBlanksAs = self::_getAttribute($chartDetails, 'val', 'string'); + break; + case "title": + $title = self::_chartTitle($chartDetails,$namespacesChartMeta,'title'); + break; + case "legend": + $legendPos = 'r'; + $legendLayout = null; + $legendOverlay = false; + foreach($chartDetails as $chartDetailKey => $chartDetail) { + switch ($chartDetailKey) { + case "legendPos": + $legendPos = self::_getAttribute($chartDetail, 'val', 'string'); + break; + case "overlay": + $legendOverlay = self::_getAttribute($chartDetail, 'val', 'boolean'); + break; + case "layout": + $legendLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'legend'); + break; + } + } + $legend = new PHPExcel_Chart_Legend($legendPos, $legendLayout, $legendOverlay); + break; + } + } + } + } + $chart = new PHPExcel_Chart($chartName,$title,$legend,$plotArea,$plotVisOnly,$dispBlanksAs,$XaxisLabel,$YaxisLabel); + + return $chart; + } // function readChart() + + + private static function _chartTitle($titleDetails,$namespacesChartMeta,$type) { + $caption = array(); + $titleLayout = null; + foreach($titleDetails as $titleDetailKey => $chartDetail) { + switch ($titleDetailKey) { + case "tx": + $titleDetails = $chartDetail->rich->children($namespacesChartMeta['a']); + foreach($titleDetails as $titleKey => $titleDetail) { + switch ($titleKey) { + case "p": + $titleDetailPart = $titleDetail->children($namespacesChartMeta['a']); + $caption[] = self::_parseRichText($titleDetailPart); + } + } + break; + case "layout": + $titleLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta); + break; + } + } + + return new PHPExcel_Chart_Title($caption, $titleLayout); + } // function _chartTitle() + + + private static function _chartLayoutDetails($chartDetail,$namespacesChartMeta) { + if (!isset($chartDetail->manualLayout)) { + return null; + } + $details = $chartDetail->manualLayout->children($namespacesChartMeta['c']); + if (is_null($details)) { + return null; + } + $layout = array(); + foreach($details as $detailKey => $detail) { +// echo $detailKey,' => ',self::_getAttribute($detail, 'val', 'string'),PHP_EOL; + $layout[$detailKey] = self::_getAttribute($detail, 'val', 'string'); + } + return new PHPExcel_Chart_Layout($layout); + } // function _chartLayoutDetails() + + + private static function _chartDataSeries($chartDetail,$namespacesChartMeta,$plotType) { + $multiSeriesType = NULL; + $smoothLine = false; + $seriesLabel = $seriesCategory = $seriesValues = $plotOrder = array(); + + $seriesDetailSet = $chartDetail->children($namespacesChartMeta['c']); + foreach($seriesDetailSet as $seriesDetailKey => $seriesDetails) { + switch ($seriesDetailKey) { + case "grouping": + $multiSeriesType = self::_getAttribute($chartDetail->grouping, 'val', 'string'); + break; + case "ser": + $marker = NULL; + foreach($seriesDetails as $seriesKey => $seriesDetail) { + switch ($seriesKey) { + case "idx": + $seriesIndex = self::_getAttribute($seriesDetail, 'val', 'integer'); + break; + case "order": + $seriesOrder = self::_getAttribute($seriesDetail, 'val', 'integer'); + $plotOrder[$seriesIndex] = $seriesOrder; + break; + case "tx": + $seriesLabel[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta); + break; + case "marker": + $marker = self::_getAttribute($seriesDetail->symbol, 'val', 'string'); + break; + case "smooth": + $smoothLine = self::_getAttribute($seriesDetail, 'val', 'boolean'); + break; + case "cat": + $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta); + break; + case "val": + $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + break; + case "xVal": + $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + break; + case "yVal": + $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + break; + } + } + } + } + return new PHPExcel_Chart_DataSeries($plotType,$multiSeriesType,$plotOrder,$seriesLabel,$seriesCategory,$seriesValues,$smoothLine); + } // function _chartDataSeries() + + + private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null, $smoothLine = false) { + if (isset($seriesDetail->strRef)) { + $seriesSource = (string) $seriesDetail->strRef->f; + $seriesData = self::_chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']),'s'); + + return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } elseif (isset($seriesDetail->numRef)) { + $seriesSource = (string) $seriesDetail->numRef->f; + $seriesData = self::_chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c'])); + + return new PHPExcel_Chart_DataSeriesValues('Number',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } elseif (isset($seriesDetail->multiLvlStrRef)) { + $seriesSource = (string) $seriesDetail->multiLvlStrRef->f; + $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']),'s'); + $seriesData['pointCount'] = count($seriesData['dataValues']); + + return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } elseif (isset($seriesDetail->multiLvlNumRef)) { + $seriesSource = (string) $seriesDetail->multiLvlNumRef->f; + $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']),'s'); + $seriesData['pointCount'] = count($seriesData['dataValues']); + + return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } + return null; + } // function _chartDataSeriesValueSet() + + + private static function _chartDataSeriesValues($seriesValueSet,$dataType='n') { + $seriesVal = array(); + $formatCode = ''; + $pointCount = 0; + + foreach($seriesValueSet as $seriesValueIdx => $seriesValue) { + switch ($seriesValueIdx) { + case 'ptCount': + $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); + break; + case 'formatCode': + $formatCode = (string) $seriesValue; + break; + case 'pt': + $pointVal = self::_getAttribute($seriesValue, 'idx', 'integer'); + if ($dataType == 's') { + $seriesVal[$pointVal] = (string) $seriesValue->v; + } else { + $seriesVal[$pointVal] = (float) $seriesValue->v; + } + break; + } + } + + if (empty($seriesVal)) { + $seriesVal = NULL; + } + + return array( 'formatCode' => $formatCode, + 'pointCount' => $pointCount, + 'dataValues' => $seriesVal + ); + } // function _chartDataSeriesValues() + + + private static function _chartDataSeriesValuesMultiLevel($seriesValueSet,$dataType='n') { + $seriesVal = array(); + $formatCode = ''; + $pointCount = 0; + + foreach($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) { + foreach($seriesLevel as $seriesValueIdx => $seriesValue) { + switch ($seriesValueIdx) { + case 'ptCount': + $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); + break; + case 'formatCode': + $formatCode = (string) $seriesValue; + break; + case 'pt': + $pointVal = self::_getAttribute($seriesValue, 'idx', 'integer'); + if ($dataType == 's') { + $seriesVal[$pointVal][] = (string) $seriesValue->v; + } else { + $seriesVal[$pointVal][] = (float) $seriesValue->v; + } + break; + } + } + } + + return array( 'formatCode' => $formatCode, + 'pointCount' => $pointCount, + 'dataValues' => $seriesVal + ); + } // function _chartDataSeriesValuesMultiLevel() + + private static function _parseRichText($titleDetailPart = null) { + $value = new PHPExcel_RichText(); + + foreach($titleDetailPart as $titleDetailElementKey => $titleDetailElement) { + if (isset($titleDetailElement->t)) { + $objText = $value->createTextRun( (string) $titleDetailElement->t ); + } + if (isset($titleDetailElement->rPr)) { + if (isset($titleDetailElement->rPr->rFont["val"])) { + $objText->getFont()->setName((string) $titleDetailElement->rPr->rFont["val"]); + } + + $fontSize = (self::_getAttribute($titleDetailElement->rPr, 'sz', 'integer')); + if (!is_null($fontSize)) { + $objText->getFont()->setSize(floor($fontSize / 100)); + } + + $fontColor = (self::_getAttribute($titleDetailElement->rPr, 'color', 'string')); + if (!is_null($fontColor)) { + $objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($fontColor) ) ); + } + + $bold = self::_getAttribute($titleDetailElement->rPr, 'b', 'boolean'); + if (!is_null($bold)) { + $objText->getFont()->setBold($bold); + } + + $italic = self::_getAttribute($titleDetailElement->rPr, 'i', 'boolean'); + if (!is_null($italic)) { + $objText->getFont()->setItalic($italic); + } + + $baseline = self::_getAttribute($titleDetailElement->rPr, 'baseline', 'integer'); + if (!is_null($baseline)) { + if ($baseline > 0) { + $objText->getFont()->setSuperScript(true); + } elseif($baseline < 0) { + $objText->getFont()->setSubScript(true); + } + } + + $underscore = (self::_getAttribute($titleDetailElement->rPr, 'u', 'string')); + if (!is_null($underscore)) { + if ($underscore == 'sng') { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } elseif($underscore == 'dbl') { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); + } else { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_NONE); + } + } + + $strikethrough = (self::_getAttribute($titleDetailElement->rPr, 's', 'string')); + if (!is_null($strikethrough)) { + if ($strikethrough == 'noStrike') { + $objText->getFont()->setStrikethrough(false); + } else { + $objText->getFont()->setStrikethrough(true); + } + } + } + } + + return $value; + } + + private static function _readChartAttributes($chartDetail) { + $plotAttributes = array(); + if (isset($chartDetail->dLbls)) { + if (isset($chartDetail->dLbls->howLegendKey)) { + $plotAttributes['showLegendKey'] = self::_getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showVal)) { + $plotAttributes['showVal'] = self::_getAttribute($chartDetail->dLbls->showVal, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showCatName)) { + $plotAttributes['showCatName'] = self::_getAttribute($chartDetail->dLbls->showCatName, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showSerName)) { + $plotAttributes['showSerName'] = self::_getAttribute($chartDetail->dLbls->showSerName, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showPercent)) { + $plotAttributes['showPercent'] = self::_getAttribute($chartDetail->dLbls->showPercent, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showBubbleSize)) { + $plotAttributes['showBubbleSize'] = self::_getAttribute($chartDetail->dLbls->showBubbleSize, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showLeaderLines)) { + $plotAttributes['showLeaderLines'] = self::_getAttribute($chartDetail->dLbls->showLeaderLines, 'val', 'string'); + } + } + + return $plotAttributes; + } + + private static function _setChartAttributes($plotArea,$plotAttributes) + { + foreach($plotAttributes as $plotAttributeKey => $plotAttributeValue) { + switch($plotAttributeKey) { + case 'showLegendKey' : + $plotArea->setShowLegendKey($plotAttributeValue); + break; + case 'showVal' : + $plotArea->setShowVal($plotAttributeValue); + break; + case 'showCatName' : + $plotArea->setShowCatName($plotAttributeValue); + break; + case 'showSerName' : + $plotArea->setShowSerName($plotAttributeValue); + break; + case 'showPercent' : + $plotArea->setShowPercent($plotAttributeValue); + break; + case 'showBubbleSize' : + $plotArea->setShowBubbleSize($plotAttributeValue); + break; + case 'showLeaderLines' : + $plotArea->setShowLeaderLines($plotAttributeValue); + break; + } + } + } } diff --git a/Classes/PHPExcel/Reader/Excel2007/Theme.php b/Classes/PHPExcel/Reader/Excel2007/Theme.php index 9647e1212..5d3c1c9b6 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Theme.php +++ b/Classes/PHPExcel/Reader/Excel2007/Theme.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Reader_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,57 +35,57 @@ */ class PHPExcel_Reader_Excel2007_Theme { - /** - * Theme Name - * - * @var string - */ - private $_themeName; + /** + * Theme Name + * + * @var string + */ + private $_themeName; - /** - * Colour Scheme Name - * - * @var string - */ - private $_colourSchemeName; + /** + * Colour Scheme Name + * + * @var string + */ + private $_colourSchemeName; - /** - * Colour Map indexed by position - * - * @var array of string - */ - private $_colourMapValues; + /** + * Colour Map indexed by position + * + * @var array of string + */ + private $_colourMapValues; - /** - * Colour Map - * - * @var array of string - */ - private $_colourMap; + /** + * Colour Map + * + * @var array of string + */ + private $_colourMap; /** * Create a new PHPExcel_Theme - * + * */ public function __construct($themeName,$colourSchemeName,$colourMap) { - // Initialise values - $this->_themeName = $themeName; - $this->_colourSchemeName = $colourSchemeName; - $this->_colourMap = $colourMap; + // Initialise values + $this->_themeName = $themeName; + $this->_colourSchemeName = $colourSchemeName; + $this->_colourMap = $colourMap; } - /** - * Get Theme Name - * - * @return string - */ - public function getThemeName() - { - return $this->_themeName; - } + /** + * Get Theme Name + * + * @return string + */ + public function getThemeName() + { + return $this->_themeName; + } /** * Get colour Scheme Name @@ -93,7 +93,7 @@ public function getThemeName() * @return string */ public function getColourSchemeName() { - return $this->_colourSchemeName; + return $this->_colourSchemeName; } /** @@ -102,23 +102,23 @@ public function getColourSchemeName() { * @return string */ public function getColourByIndex($index=0) { - if (isset($this->_colourMap[$index])) { - return $this->_colourMap[$index]; - } - return null; + if (isset($this->_colourMap[$index])) { + return $this->_colourMap[$index]; + } + return null; } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if ((is_object($value)) && ($key != '_parent')) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if ((is_object($value)) && ($key != '_parent')) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Reader/Excel5/Escher.php b/Classes/PHPExcel/Reader/Excel5/Escher.php index f18382965..9b2338c28 100644 --- a/Classes/PHPExcel/Reader/Excel5/Escher.php +++ b/Classes/PHPExcel/Reader/Excel5/Escher.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Reader_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,607 +34,607 @@ */ class PHPExcel_Reader_Excel5_Escher { - const DGGCONTAINER = 0xF000; - const BSTORECONTAINER = 0xF001; - const DGCONTAINER = 0xF002; - const SPGRCONTAINER = 0xF003; - const SPCONTAINER = 0xF004; - const DGG = 0xF006; - const BSE = 0xF007; - const DG = 0xF008; - const SPGR = 0xF009; - const SP = 0xF00A; - const OPT = 0xF00B; - const CLIENTTEXTBOX = 0xF00D; - const CLIENTANCHOR = 0xF010; - const CLIENTDATA = 0xF011; - const BLIPJPEG = 0xF01D; - const BLIPPNG = 0xF01E; - const SPLITMENUCOLORS = 0xF11E; - const TERTIARYOPT = 0xF122; - - /** - * Escher stream data (binary) - * - * @var string - */ - private $_data; - - /** - * Size in bytes of the Escher stream data - * - * @var int - */ - private $_dataSize; - - /** - * Current position of stream pointer in Escher stream data - * - * @var int - */ - private $_pos; - - /** - * The object to be returned by the reader. Modified during load. - * - * @var mixed - */ - private $_object; - - /** - * Create a new PHPExcel_Reader_Excel5_Escher instance - * - * @param mixed $object - */ - public function __construct($object) - { - $this->_object = $object; - } - - /** - * Load Escher stream data. May be a partial Escher stream. - * - * @param string $data - */ - public function load($data) - { - $this->_data = $data; - - // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); - - $this->_pos = 0; - - // Parse Escher stream - while ($this->_pos < $this->_dataSize) { - - // offset: 2; size: 2: Record Type - $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); - - switch ($fbt) { - case self::DGGCONTAINER: $this->_readDggContainer(); break; - case self::DGG: $this->_readDgg(); break; - case self::BSTORECONTAINER: $this->_readBstoreContainer(); break; - case self::BSE: $this->_readBSE(); break; - case self::BLIPJPEG: $this->_readBlipJPEG(); break; - case self::BLIPPNG: $this->_readBlipPNG(); break; - case self::OPT: $this->_readOPT(); break; - case self::TERTIARYOPT: $this->_readTertiaryOPT(); break; - case self::SPLITMENUCOLORS: $this->_readSplitMenuColors(); break; - case self::DGCONTAINER: $this->_readDgContainer(); break; - case self::DG: $this->_readDg(); break; - case self::SPGRCONTAINER: $this->_readSpgrContainer(); break; - case self::SPCONTAINER: $this->_readSpContainer(); break; - case self::SPGR: $this->_readSpgr(); break; - case self::SP: $this->_readSp(); break; - case self::CLIENTTEXTBOX: $this->_readClientTextbox(); break; - case self::CLIENTANCHOR: $this->_readClientAnchor(); break; - case self::CLIENTDATA: $this->_readClientData(); break; - default: $this->_readDefault(); break; - } - } - - return $this->_object; - } - - /** - * Read a generic record - */ - private function _readDefault() - { - // offset 0; size: 2; recVer and recInstance - $verInstance = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos); - - // offset: 2; size: 2: Record Type - $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); - - // bit: 0-3; mask: 0x000F; recVer - $recVer = (0x000F & $verInstance) >> 0; - - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - } - - /** - * Read DggContainer record (Drawing Group Container) - */ - private function _readDggContainer() - { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - - // record is a container, read contents - $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); - $this->_object->setDggContainer($dggContainer); - $reader = new PHPExcel_Reader_Excel5_Escher($dggContainer); - $reader->load($recordData); - } - - /** - * Read Dgg record (Drawing Group) - */ - private function _readDgg() - { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - } - - /** - * Read BstoreContainer record (Blip Store Container) - */ - private function _readBstoreContainer() - { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - - // record is a container, read contents - $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); - $this->_object->setBstoreContainer($bstoreContainer); - $reader = new PHPExcel_Reader_Excel5_Escher($bstoreContainer); - $reader->load($recordData); - } - - /** - * Read BSE record - */ - private function _readBSE() - { - // offset: 0; size: 2; recVer and recInstance - - // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; - - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - - // add BSE to BstoreContainer - $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); - $this->_object->addBSE($BSE); - - $BSE->setBLIPType($recInstance); - - // offset: 0; size: 1; btWin32 (MSOBLIPTYPE) - $btWin32 = ord($recordData[0]); + const DGGCONTAINER = 0xF000; + const BSTORECONTAINER = 0xF001; + const DGCONTAINER = 0xF002; + const SPGRCONTAINER = 0xF003; + const SPCONTAINER = 0xF004; + const DGG = 0xF006; + const BSE = 0xF007; + const DG = 0xF008; + const SPGR = 0xF009; + const SP = 0xF00A; + const OPT = 0xF00B; + const CLIENTTEXTBOX = 0xF00D; + const CLIENTANCHOR = 0xF010; + const CLIENTDATA = 0xF011; + const BLIPJPEG = 0xF01D; + const BLIPPNG = 0xF01E; + const SPLITMENUCOLORS = 0xF11E; + const TERTIARYOPT = 0xF122; + + /** + * Escher stream data (binary) + * + * @var string + */ + private $_data; + + /** + * Size in bytes of the Escher stream data + * + * @var int + */ + private $_dataSize; + + /** + * Current position of stream pointer in Escher stream data + * + * @var int + */ + private $_pos; + + /** + * The object to be returned by the reader. Modified during load. + * + * @var mixed + */ + private $_object; + + /** + * Create a new PHPExcel_Reader_Excel5_Escher instance + * + * @param mixed $object + */ + public function __construct($object) + { + $this->_object = $object; + } + + /** + * Load Escher stream data. May be a partial Escher stream. + * + * @param string $data + */ + public function load($data) + { + $this->_data = $data; + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + $this->_pos = 0; + + // Parse Escher stream + while ($this->_pos < $this->_dataSize) { + + // offset: 2; size: 2: Record Type + $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); + + switch ($fbt) { + case self::DGGCONTAINER: $this->_readDggContainer(); break; + case self::DGG: $this->_readDgg(); break; + case self::BSTORECONTAINER: $this->_readBstoreContainer(); break; + case self::BSE: $this->_readBSE(); break; + case self::BLIPJPEG: $this->_readBlipJPEG(); break; + case self::BLIPPNG: $this->_readBlipPNG(); break; + case self::OPT: $this->_readOPT(); break; + case self::TERTIARYOPT: $this->_readTertiaryOPT(); break; + case self::SPLITMENUCOLORS: $this->_readSplitMenuColors(); break; + case self::DGCONTAINER: $this->_readDgContainer(); break; + case self::DG: $this->_readDg(); break; + case self::SPGRCONTAINER: $this->_readSpgrContainer(); break; + case self::SPCONTAINER: $this->_readSpContainer(); break; + case self::SPGR: $this->_readSpgr(); break; + case self::SP: $this->_readSp(); break; + case self::CLIENTTEXTBOX: $this->_readClientTextbox(); break; + case self::CLIENTANCHOR: $this->_readClientAnchor(); break; + case self::CLIENTDATA: $this->_readClientData(); break; + default: $this->_readDefault(); break; + } + } + + return $this->_object; + } + + /** + * Read a generic record + */ + private function _readDefault() + { + // offset 0; size: 2; recVer and recInstance + $verInstance = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos); + + // offset: 2; size: 2: Record Type + $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); + + // bit: 0-3; mask: 0x000F; recVer + $recVer = (0x000F & $verInstance) >> 0; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read DggContainer record (Drawing Group Container) + */ + private function _readDggContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); + $this->_object->setDggContainer($dggContainer); + $reader = new PHPExcel_Reader_Excel5_Escher($dggContainer); + $reader->load($recordData); + } + + /** + * Read Dgg record (Drawing Group) + */ + private function _readDgg() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read BstoreContainer record (Blip Store Container) + */ + private function _readBstoreContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); + $this->_object->setBstoreContainer($bstoreContainer); + $reader = new PHPExcel_Reader_Excel5_Escher($bstoreContainer); + $reader->load($recordData); + } + + /** + * Read BSE record + */ + private function _readBSE() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // add BSE to BstoreContainer + $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); + $this->_object->addBSE($BSE); + + $BSE->setBLIPType($recInstance); + + // offset: 0; size: 1; btWin32 (MSOBLIPTYPE) + $btWin32 = ord($recordData[0]); - // offset: 1; size: 1; btWin32 (MSOBLIPTYPE) - $btMacOS = ord($recordData[1]); + // offset: 1; size: 1; btWin32 (MSOBLIPTYPE) + $btMacOS = ord($recordData[1]); - // offset: 2; size: 16; MD4 digest - $rgbUid = substr($recordData, 2, 16); + // offset: 2; size: 16; MD4 digest + $rgbUid = substr($recordData, 2, 16); - // offset: 18; size: 2; tag - $tag = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 18); + // offset: 18; size: 2; tag + $tag = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 18); - // offset: 20; size: 4; size of BLIP in bytes - $size = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 20); + // offset: 20; size: 4; size of BLIP in bytes + $size = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 20); - // offset: 24; size: 4; number of references to this BLIP - $cRef = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 24); + // offset: 24; size: 4; number of references to this BLIP + $cRef = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 24); - // offset: 28; size: 4; MSOFO file offset - $foDelay = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 28); + // offset: 28; size: 4; MSOFO file offset + $foDelay = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 28); - // offset: 32; size: 1; unused1 - $unused1 = ord($recordData{32}); + // offset: 32; size: 1; unused1 + $unused1 = ord($recordData{32}); - // offset: 33; size: 1; size of nameData in bytes (including null terminator) - $cbName = ord($recordData{33}); + // offset: 33; size: 1; size of nameData in bytes (including null terminator) + $cbName = ord($recordData{33}); - // offset: 34; size: 1; unused2 - $unused2 = ord($recordData{34}); + // offset: 34; size: 1; unused2 + $unused2 = ord($recordData{34}); - // offset: 35; size: 1; unused3 - $unused3 = ord($recordData{35}); + // offset: 35; size: 1; unused3 + $unused3 = ord($recordData{35}); - // offset: 36; size: $cbName; nameData - $nameData = substr($recordData, 36, $cbName); + // offset: 36; size: $cbName; nameData + $nameData = substr($recordData, 36, $cbName); - // offset: 36 + $cbName, size: var; the BLIP data - $blipData = substr($recordData, 36 + $cbName); + // offset: 36 + $cbName, size: var; the BLIP data + $blipData = substr($recordData, 36 + $cbName); - // record is a container, read contents - $reader = new PHPExcel_Reader_Excel5_Escher($BSE); - $reader->load($blipData); - } + // record is a container, read contents + $reader = new PHPExcel_Reader_Excel5_Escher($BSE); + $reader->load($blipData); + } - /** - * Read BlipJPEG record. Holds raw JPEG image data - */ - private function _readBlipJPEG() - { - // offset: 0; size: 2; recVer and recInstance + /** + * Read BlipJPEG record. Holds raw JPEG image data + */ + private function _readBlipJPEG() + { + // offset: 0; size: 2; recVer and recInstance - // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); - // move stream pointer to next record - $this->_pos += 8 + $length; + // move stream pointer to next record + $this->_pos += 8 + $length; - $pos = 0; + $pos = 0; - // offset: 0; size: 16; rgbUid1 (MD4 digest of) - $rgbUid1 = substr($recordData, 0, 16); - $pos += 16; + // offset: 0; size: 16; rgbUid1 (MD4 digest of) + $rgbUid1 = substr($recordData, 0, 16); + $pos += 16; - // offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 - if (in_array($recInstance, array(0x046B, 0x06E3))) { - $rgbUid2 = substr($recordData, 16, 16); - $pos += 16; - } + // offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 + if (in_array($recInstance, array(0x046B, 0x06E3))) { + $rgbUid2 = substr($recordData, 16, 16); + $pos += 16; + } - // offset: var; size: 1; tag - $tag = ord($recordData{$pos}); - $pos += 1; + // offset: var; size: 1; tag + $tag = ord($recordData{$pos}); + $pos += 1; - // offset: var; size: var; the raw image data - $data = substr($recordData, $pos); + // offset: var; size: var; the raw image data + $data = substr($recordData, $pos); - $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); - $blip->setData($data); + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($data); - $this->_object->setBlip($blip); - } + $this->_object->setBlip($blip); + } - /** - * Read BlipPNG record. Holds raw PNG image data - */ - private function _readBlipPNG() - { - // offset: 0; size: 2; recVer and recInstance + /** + * Read BlipPNG record. Holds raw PNG image data + */ + private function _readBlipPNG() + { + // offset: 0; size: 2; recVer and recInstance - // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); - // move stream pointer to next record - $this->_pos += 8 + $length; + // move stream pointer to next record + $this->_pos += 8 + $length; - $pos = 0; + $pos = 0; - // offset: 0; size: 16; rgbUid1 (MD4 digest of) - $rgbUid1 = substr($recordData, 0, 16); - $pos += 16; + // offset: 0; size: 16; rgbUid1 (MD4 digest of) + $rgbUid1 = substr($recordData, 0, 16); + $pos += 16; - // offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 - if ($recInstance == 0x06E1) { - $rgbUid2 = substr($recordData, 16, 16); - $pos += 16; - } - - // offset: var; size: 1; tag - $tag = ord($recordData{$pos}); - $pos += 1; + // offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 + if ($recInstance == 0x06E1) { + $rgbUid2 = substr($recordData, 16, 16); + $pos += 16; + } + + // offset: var; size: 1; tag + $tag = ord($recordData{$pos}); + $pos += 1; - // offset: var; size: var; the raw image data - $data = substr($recordData, $pos); + // offset: var; size: var; the raw image data + $data = substr($recordData, $pos); - $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); - $blip->setData($data); - - $this->_object->setBlip($blip); - } - - /** - * Read OPT record. This record may occur within DggContainer record or SpContainer - */ - private function _readOPT() - { - // offset: 0; size: 2; recVer and recInstance - - // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; - - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - - $this->_readOfficeArtRGFOPTE($recordData, $recInstance); - } - - /** - * Read TertiaryOPT record - */ - private function _readTertiaryOPT() - { - // offset: 0; size: 2; recVer and recInstance - - // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; - - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - } - - /** - * Read SplitMenuColors record - */ - private function _readSplitMenuColors() - { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - } - - /** - * Read DgContainer record (Drawing Container) - */ - private function _readDgContainer() - { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - - // record is a container, read contents - $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); - $this->_object->setDgContainer($dgContainer); - $reader = new PHPExcel_Reader_Excel5_Escher($dgContainer); - $escher = $reader->load($recordData); - } - - /** - * Read Dg record (Drawing) - */ - private function _readDg() - { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - } - - /** - * Read SpgrContainer record (Shape Group Container) - */ - private function _readSpgrContainer() - { - // context is either context DgContainer or SpgrContainer - - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - - // record is a container, read contents - $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); - - if ($this->_object instanceof PHPExcel_Shared_Escher_DgContainer) { - // DgContainer - $this->_object->setSpgrContainer($spgrContainer); - } else { - // SpgrContainer - $this->_object->addChild($spgrContainer); - } - - $reader = new PHPExcel_Reader_Excel5_Escher($spgrContainer); - $escher = $reader->load($recordData); - } - - /** - * Read SpContainer record (Shape Container) - */ - private function _readSpContainer() - { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // add spContainer to spgrContainer - $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); - $this->_object->addChild($spContainer); - - // move stream pointer to next record - $this->_pos += 8 + $length; - - // record is a container, read contents - $reader = new PHPExcel_Reader_Excel5_Escher($spContainer); - $escher = $reader->load($recordData); - } - - /** - * Read Spgr record (Shape Group) - */ - private function _readSpgr() - { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - } - - /** - * Read Sp record (Shape) - */ - private function _readSp() - { - // offset: 0; size: 2; recVer and recInstance - - // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; - - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - } - - /** - * Read ClientTextbox record - */ - private function _readClientTextbox() - { - // offset: 0; size: 2; recVer and recInstance - - // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; - - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - } - - /** - * Read ClientAnchor record. This record holds information about where the shape is anchored in worksheet - */ - private function _readClientAnchor() - { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); - - // move stream pointer to next record - $this->_pos += 8 + $length; - - // offset: 2; size: 2; upper-left corner column index (0-based) - $c1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 2); - - // offset: 4; size: 2; upper-left corner horizontal offset in 1/1024 of column width - $startOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 4); - - // offset: 6; size: 2; upper-left corner row index (0-based) - $r1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 6); - - // offset: 8; size: 2; upper-left corner vertical offset in 1/256 of row height - $startOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 8); - - // offset: 10; size: 2; bottom-right corner column index (0-based) - $c2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 10); - - // offset: 12; size: 2; bottom-right corner horizontal offset in 1/1024 of column width - $endOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 12); - - // offset: 14; size: 2; bottom-right corner row index (0-based) - $r2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 14); - - // offset: 16; size: 2; bottom-right corner vertical offset in 1/256 of row height - $endOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 16); - - // set the start coordinates - $this->_object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1)); - - // set the start offsetX - $this->_object->setStartOffsetX($startOffsetX); + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($data); + + $this->_object->setBlip($blip); + } + + /** + * Read OPT record. This record may occur within DggContainer record or SpContainer + */ + private function _readOPT() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + $this->_readOfficeArtRGFOPTE($recordData, $recInstance); + } + + /** + * Read TertiaryOPT record + */ + private function _readTertiaryOPT() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read SplitMenuColors record + */ + private function _readSplitMenuColors() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read DgContainer record (Drawing Container) + */ + private function _readDgContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); + $this->_object->setDgContainer($dgContainer); + $reader = new PHPExcel_Reader_Excel5_Escher($dgContainer); + $escher = $reader->load($recordData); + } + + /** + * Read Dg record (Drawing) + */ + private function _readDg() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read SpgrContainer record (Shape Group Container) + */ + private function _readSpgrContainer() + { + // context is either context DgContainer or SpgrContainer + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); + + if ($this->_object instanceof PHPExcel_Shared_Escher_DgContainer) { + // DgContainer + $this->_object->setSpgrContainer($spgrContainer); + } else { + // SpgrContainer + $this->_object->addChild($spgrContainer); + } + + $reader = new PHPExcel_Reader_Excel5_Escher($spgrContainer); + $escher = $reader->load($recordData); + } + + /** + * Read SpContainer record (Shape Container) + */ + private function _readSpContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // add spContainer to spgrContainer + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + $this->_object->addChild($spContainer); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $reader = new PHPExcel_Reader_Excel5_Escher($spContainer); + $escher = $reader->load($recordData); + } + + /** + * Read Spgr record (Shape Group) + */ + private function _readSpgr() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read Sp record (Shape) + */ + private function _readSp() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read ClientTextbox record + */ + private function _readClientTextbox() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read ClientAnchor record. This record holds information about where the shape is anchored in worksheet + */ + private function _readClientAnchor() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // offset: 2; size: 2; upper-left corner column index (0-based) + $c1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 2); + + // offset: 4; size: 2; upper-left corner horizontal offset in 1/1024 of column width + $startOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 4); + + // offset: 6; size: 2; upper-left corner row index (0-based) + $r1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 6); + + // offset: 8; size: 2; upper-left corner vertical offset in 1/256 of row height + $startOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 8); + + // offset: 10; size: 2; bottom-right corner column index (0-based) + $c2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 10); + + // offset: 12; size: 2; bottom-right corner horizontal offset in 1/1024 of column width + $endOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 12); + + // offset: 14; size: 2; bottom-right corner row index (0-based) + $r2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 14); + + // offset: 16; size: 2; bottom-right corner vertical offset in 1/256 of row height + $endOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 16); + + // set the start coordinates + $this->_object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1)); + + // set the start offsetX + $this->_object->setStartOffsetX($startOffsetX); - // set the start offsetY - $this->_object->setStartOffsetY($startOffsetY); + // set the start offsetY + $this->_object->setStartOffsetY($startOffsetY); - // set the end coordinates - $this->_object->setEndCoordinates(PHPExcel_Cell::stringFromColumnIndex($c2) . ($r2 + 1)); - - // set the end offsetX - $this->_object->setEndOffsetX($endOffsetX); - - // set the end offsetY - $this->_object->setEndOffsetY($endOffsetY); - } + // set the end coordinates + $this->_object->setEndCoordinates(PHPExcel_Cell::stringFromColumnIndex($c2) . ($r2 + 1)); + + // set the end offsetX + $this->_object->setEndOffsetX($endOffsetX); + + // set the end offsetY + $this->_object->setEndOffsetY($endOffsetY); + } - /** - * Read ClientData record - */ - private function _readClientData() - { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + /** + * Read ClientData record + */ + private function _readClientData() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); - // move stream pointer to next record - $this->_pos += 8 + $length; - } + // move stream pointer to next record + $this->_pos += 8 + $length; + } - /** - * Read OfficeArtRGFOPTE table of property-value pairs - * - * @param string $data Binary data - * @param int $n Number of properties - */ - private function _readOfficeArtRGFOPTE($data, $n) { + /** + * Read OfficeArtRGFOPTE table of property-value pairs + * + * @param string $data Binary data + * @param int $n Number of properties + */ + private function _readOfficeArtRGFOPTE($data, $n) { - $splicedComplexData = substr($data, 6 * $n); + $splicedComplexData = substr($data, 6 * $n); - // loop through property-value pairs - for ($i = 0; $i < $n; ++$i) { - // read 6 bytes at a time - $fopte = substr($data, 6 * $i, 6); + // loop through property-value pairs + for ($i = 0; $i < $n; ++$i) { + // read 6 bytes at a time + $fopte = substr($data, 6 * $i, 6); - // offset: 0; size: 2; opid - $opid = PHPExcel_Reader_Excel5::_GetInt2d($fopte, 0); + // offset: 0; size: 2; opid + $opid = PHPExcel_Reader_Excel5::_GetInt2d($fopte, 0); - // bit: 0-13; mask: 0x3FFF; opid.opid - $opidOpid = (0x3FFF & $opid) >> 0; + // bit: 0-13; mask: 0x3FFF; opid.opid + $opidOpid = (0x3FFF & $opid) >> 0; - // bit: 14; mask 0x4000; 1 = value in op field is BLIP identifier - $opidFBid = (0x4000 & $opid) >> 14; + // bit: 14; mask 0x4000; 1 = value in op field is BLIP identifier + $opidFBid = (0x4000 & $opid) >> 14; - // bit: 15; mask 0x8000; 1 = this is a complex property, op field specifies size of complex data - $opidFComplex = (0x8000 & $opid) >> 15; + // bit: 15; mask 0x8000; 1 = this is a complex property, op field specifies size of complex data + $opidFComplex = (0x8000 & $opid) >> 15; - // offset: 2; size: 4; the value for this property - $op = PHPExcel_Reader_Excel5::_GetInt4d($fopte, 2); + // offset: 2; size: 4; the value for this property + $op = PHPExcel_Reader_Excel5::_GetInt4d($fopte, 2); - if ($opidFComplex) { - $complexData = substr($splicedComplexData, 0, $op); - $splicedComplexData = substr($splicedComplexData, $op); + if ($opidFComplex) { + $complexData = substr($splicedComplexData, 0, $op); + $splicedComplexData = substr($splicedComplexData, $op); - // we store string value with complex data - $value = $complexData; - } else { - // we store integer value - $value = $op; - } + // we store string value with complex data + $value = $complexData; + } else { + // we store integer value + $value = $op; + } - $this->_object->setOPT($opidOpid, $value); - } - } + $this->_object->setOPT($opidOpid, $value); + } + } } diff --git a/Classes/PHPExcel/Reader/Excel5/RC4.php b/Classes/PHPExcel/Reader/Excel5/RC4.php index 4f23c7bd7..9130b45a4 100644 --- a/Classes/PHPExcel/Reader/Excel5/RC4.php +++ b/Classes/PHPExcel/Reader/Excel5/RC4.php @@ -21,68 +21,68 @@ * @category PHPExcel * @package PHPExcel_Reader_Excel5 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ /** * PHPExcel_Reader_Excel5_RC4 * - * @category PHPExcel - * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Reader_Excel5_RC4 { - // Context - var $s = array(); - var $i = 0; - var $j = 0; + // Context + var $s = array(); + var $i = 0; + var $j = 0; - /** - * RC4 stream decryption/encryption constrcutor - * - * @param string $key Encryption key/passphrase - */ - public function __construct($key) - { - $len = strlen($key); + /** + * RC4 stream decryption/encryption constrcutor + * + * @param string $key Encryption key/passphrase + */ + public function __construct($key) + { + $len = strlen($key); - for ($this->i = 0; $this->i < 256; $this->i++) { - $this->s[$this->i] = $this->i; - } + for ($this->i = 0; $this->i < 256; $this->i++) { + $this->s[$this->i] = $this->i; + } - $this->j = 0; - for ($this->i = 0; $this->i < 256; $this->i++) { - $this->j = ($this->j + $this->s[$this->i] + ord($key[$this->i % $len])) % 256; - $t = $this->s[$this->i]; - $this->s[$this->i] = $this->s[$this->j]; - $this->s[$this->j] = $t; - } - $this->i = $this->j = 0; - } + $this->j = 0; + for ($this->i = 0; $this->i < 256; $this->i++) { + $this->j = ($this->j + $this->s[$this->i] + ord($key[$this->i % $len])) % 256; + $t = $this->s[$this->i]; + $this->s[$this->i] = $this->s[$this->j]; + $this->s[$this->j] = $t; + } + $this->i = $this->j = 0; + } - /** - * Symmetric decryption/encryption function - * - * @param string $data Data to encrypt/decrypt - * - * @return string - */ - public function RC4($data) - { - $len = strlen($data); - for ($c = 0; $c < $len; $c++) { - $this->i = ($this->i + 1) % 256; - $this->j = ($this->j + $this->s[$this->i]) % 256; - $t = $this->s[$this->i]; - $this->s[$this->i] = $this->s[$this->j]; - $this->s[$this->j] = $t; + /** + * Symmetric decryption/encryption function + * + * @param string $data Data to encrypt/decrypt + * + * @return string + */ + public function RC4($data) + { + $len = strlen($data); + for ($c = 0; $c < $len; $c++) { + $this->i = ($this->i + 1) % 256; + $this->j = ($this->j + $this->s[$this->i]) % 256; + $t = $this->s[$this->i]; + $this->s[$this->i] = $this->s[$this->j]; + $this->s[$this->j] = $t; - $t = ($this->s[$this->i] + $this->s[$this->j]) % 256; + $t = ($this->s[$this->i] + $this->s[$this->j]) % 256; - $data[$c] = chr(ord($data[$c]) ^ $this->s[$t]); - } - return $data; - } + $data[$c] = chr(ord($data[$c]) ^ $this->s[$t]); + } + return $data; + } } diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index ebda1b243..5a6c043c2 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,72 +35,72 @@ */ class PHPExcel_Shared_CodePage { - /** - * Convert Microsoft Code Page Identifier to Code Page Name which iconv - * and mbstring understands - * - * @param integer $codePage Microsoft Code Page Indentifier - * @return string Code Page Name - * @throws PHPExcel_Exception - */ - public static function NumberToName($codePage = 1252) - { - switch ($codePage) { - case 367: return 'ASCII'; break; // ASCII - case 437: return 'CP437'; break; // OEM US - case 720: throw new PHPExcel_Exception('Code page 720 not supported.'); - break; // OEM Arabic - case 737: return 'CP737'; break; // OEM Greek - case 775: return 'CP775'; break; // OEM Baltic - case 850: return 'CP850'; break; // OEM Latin I - case 852: return 'CP852'; break; // OEM Latin II (Central European) - case 855: return 'CP855'; break; // OEM Cyrillic - case 857: return 'CP857'; break; // OEM Turkish - case 858: return 'CP858'; break; // OEM Multilingual Latin I with Euro - case 860: return 'CP860'; break; // OEM Portugese - case 861: return 'CP861'; break; // OEM Icelandic - case 862: return 'CP862'; break; // OEM Hebrew - case 863: return 'CP863'; break; // OEM Canadian (French) - case 864: return 'CP864'; break; // OEM Arabic - case 865: return 'CP865'; break; // OEM Nordic - case 866: return 'CP866'; break; // OEM Cyrillic (Russian) - case 869: return 'CP869'; break; // OEM Greek (Modern) - case 874: return 'CP874'; break; // ANSI Thai - case 932: return 'CP932'; break; // ANSI Japanese Shift-JIS - case 936: return 'CP936'; break; // ANSI Chinese Simplified GBK - case 949: return 'CP949'; break; // ANSI Korean (Wansung) - case 950: return 'CP950'; break; // ANSI Chinese Traditional BIG5 - case 1200: return 'UTF-16LE'; break; // UTF-16 (BIFF8) - case 1250: return 'CP1250'; break; // ANSI Latin II (Central European) - case 1251: return 'CP1251'; break; // ANSI Cyrillic - case 0: // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program - case 1252: return 'CP1252'; break; // ANSI Latin I (BIFF4-BIFF7) - case 1253: return 'CP1253'; break; // ANSI Greek - case 1254: return 'CP1254'; break; // ANSI Turkish - case 1255: return 'CP1255'; break; // ANSI Hebrew - case 1256: return 'CP1256'; break; // ANSI Arabic - case 1257: return 'CP1257'; break; // ANSI Baltic - case 1258: return 'CP1258'; break; // ANSI Vietnamese - case 1361: return 'CP1361'; break; // ANSI Korean (Johab) - case 10000: return 'MAC'; break; // Apple Roman - case 10001: return 'CP932'; break; // Macintosh Japanese - case 10002: return 'CP950'; break; // Macintosh Chinese Traditional - case 10003: return 'CP1361'; break; // Macintosh Korean - case 10006: return 'MACGREEK'; break; // Macintosh Greek - case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic - case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) - case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe - case 10079: return 'MACICELAND'; break; // Macintosh Icelandic - case 10081: return 'MACTURKISH'; break; // Macintosh Turkish - case 21010: return 'UTF-16LE'; break; // UTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE - case 32768: return 'MAC'; break; // Apple Roman - case 32769: throw new PHPExcel_Exception('Code page 32769 not supported.'); - break; // ANSI Latin I (BIFF2-BIFF3) - case 65000: return 'UTF-7'; break; // Unicode (UTF-7) - case 65001: return 'UTF-8'; break; // Unicode (UTF-8) - } + /** + * Convert Microsoft Code Page Identifier to Code Page Name which iconv + * and mbstring understands + * + * @param integer $codePage Microsoft Code Page Indentifier + * @return string Code Page Name + * @throws PHPExcel_Exception + */ + public static function NumberToName($codePage = 1252) + { + switch ($codePage) { + case 367: return 'ASCII'; break; // ASCII + case 437: return 'CP437'; break; // OEM US + case 720: throw new PHPExcel_Exception('Code page 720 not supported.'); + break; // OEM Arabic + case 737: return 'CP737'; break; // OEM Greek + case 775: return 'CP775'; break; // OEM Baltic + case 850: return 'CP850'; break; // OEM Latin I + case 852: return 'CP852'; break; // OEM Latin II (Central European) + case 855: return 'CP855'; break; // OEM Cyrillic + case 857: return 'CP857'; break; // OEM Turkish + case 858: return 'CP858'; break; // OEM Multilingual Latin I with Euro + case 860: return 'CP860'; break; // OEM Portugese + case 861: return 'CP861'; break; // OEM Icelandic + case 862: return 'CP862'; break; // OEM Hebrew + case 863: return 'CP863'; break; // OEM Canadian (French) + case 864: return 'CP864'; break; // OEM Arabic + case 865: return 'CP865'; break; // OEM Nordic + case 866: return 'CP866'; break; // OEM Cyrillic (Russian) + case 869: return 'CP869'; break; // OEM Greek (Modern) + case 874: return 'CP874'; break; // ANSI Thai + case 932: return 'CP932'; break; // ANSI Japanese Shift-JIS + case 936: return 'CP936'; break; // ANSI Chinese Simplified GBK + case 949: return 'CP949'; break; // ANSI Korean (Wansung) + case 950: return 'CP950'; break; // ANSI Chinese Traditional BIG5 + case 1200: return 'UTF-16LE'; break; // UTF-16 (BIFF8) + case 1250: return 'CP1250'; break; // ANSI Latin II (Central European) + case 1251: return 'CP1251'; break; // ANSI Cyrillic + case 0: // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program + case 1252: return 'CP1252'; break; // ANSI Latin I (BIFF4-BIFF7) + case 1253: return 'CP1253'; break; // ANSI Greek + case 1254: return 'CP1254'; break; // ANSI Turkish + case 1255: return 'CP1255'; break; // ANSI Hebrew + case 1256: return 'CP1256'; break; // ANSI Arabic + case 1257: return 'CP1257'; break; // ANSI Baltic + case 1258: return 'CP1258'; break; // ANSI Vietnamese + case 1361: return 'CP1361'; break; // ANSI Korean (Johab) + case 10000: return 'MAC'; break; // Apple Roman + case 10001: return 'CP932'; break; // Macintosh Japanese + case 10002: return 'CP950'; break; // Macintosh Chinese Traditional + case 10003: return 'CP1361'; break; // Macintosh Korean + case 10006: return 'MACGREEK'; break; // Macintosh Greek + case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic + case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) + case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe + case 10079: return 'MACICELAND'; break; // Macintosh Icelandic + case 10081: return 'MACTURKISH'; break; // Macintosh Turkish + case 21010: return 'UTF-16LE'; break; // UTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE + case 32768: return 'MAC'; break; // Apple Roman + case 32769: throw new PHPExcel_Exception('Code page 32769 not supported.'); + break; // ANSI Latin I (BIFF2-BIFF3) + case 65000: return 'UTF-7'; break; // Unicode (UTF-7) + case 65001: return 'UTF-8'; break; // Unicode (UTF-8) + } - throw new PHPExcel_Exception('Unknown codepage: ' . $codePage); - } + throw new PHPExcel_Exception('Unknown codepage: ' . $codePage); + } } diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index c3fe23001..75260c957 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -20,10 +20,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category PHPExcel - * @package PHPExcel_Shared + * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ @@ -31,345 +31,345 @@ * PHPExcel_Shared_Date * * @category PHPExcel - * @package PHPExcel_Shared + * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_Date { - /** constants */ - const CALENDAR_WINDOWS_1900 = 1900; // Base date of 1st Jan 1900 = 1.0 - const CALENDAR_MAC_1904 = 1904; // Base date of 2nd Jan 1904 = 1.0 - - /* - * Names of the months of the year, indexed by shortname - * Planned usage for locale settings - * - * @public - * @var string[] - */ - public static $_monthNames = array( 'Jan' => 'January', - 'Feb' => 'February', - 'Mar' => 'March', - 'Apr' => 'April', - 'May' => 'May', - 'Jun' => 'June', - 'Jul' => 'July', - 'Aug' => 'August', - 'Sep' => 'September', - 'Oct' => 'October', - 'Nov' => 'November', - 'Dec' => 'December', - ); - - /* - * Names of the months of the year, indexed by shortname - * Planned usage for locale settings - * - * @public - * @var string[] - */ - public static $_numberSuffixes = array( 'st', - 'nd', - 'rd', - 'th', - ); - - /* - * Base calendar year to use for calculations - * - * @private - * @var int - */ - protected static $_excelBaseDate = self::CALENDAR_WINDOWS_1900; - - /** - * Set the Excel calendar (Windows 1900 or Mac 1904) - * - * @param integer $baseDate Excel base date (1900 or 1904) - * @return boolean Success or failure - */ - public static function setExcelCalendar($baseDate) { - if (($baseDate == self::CALENDAR_WINDOWS_1900) || - ($baseDate == self::CALENDAR_MAC_1904)) { - self::$_excelBaseDate = $baseDate; - return TRUE; - } - return FALSE; - } // function setExcelCalendar() - - - /** - * Return the Excel calendar (Windows 1900 or Mac 1904) - * - * @return integer Excel base date (1900 or 1904) - */ - public static function getExcelCalendar() { - return self::$_excelBaseDate; - } // function getExcelCalendar() - - - /** - * Convert a date from Excel to PHP - * - * @param long $dateValue Excel date/time value - * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as - * a UST timestamp, or adjusted to UST - * @param string $timezone The timezone for finding the adjustment from UST - * @return long PHP serialized date/time - */ - public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { - if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { - $my_excelBaseDate = 25569; - // Adjust for the spurious 29-Feb-1900 (Day 60) - if ($dateValue < 60) { - --$my_excelBaseDate; - } - } else { - $my_excelBaseDate = 24107; - } - - // Perform conversion - if ($dateValue >= 1) { - $utcDays = $dateValue - $my_excelBaseDate; - $returnValue = round($utcDays * 86400); - if (($returnValue <= PHP_INT_MAX) && ($returnValue >= -PHP_INT_MAX)) { - $returnValue = (integer) $returnValue; - } - } else { - $hours = round($dateValue * 24); - $mins = round($dateValue * 1440) - round($hours * 60); - $secs = round($dateValue * 86400) - round($hours * 3600) - round($mins * 60); - $returnValue = (integer) gmmktime($hours, $mins, $secs); - } - - $timezoneAdjustment = ($adjustToTimezone) ? - PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone, $returnValue) : - 0; - - // Return - return $returnValue + $timezoneAdjustment; - } // function ExcelToPHP() - - - /** - * Convert a date from Excel to a PHP Date/Time object - * - * @param integer $dateValue Excel date/time value - * @return DateTime PHP date/time object - */ - public static function ExcelToPHPObject($dateValue = 0) { - $dateTime = self::ExcelToPHP($dateValue); - $days = floor($dateTime / 86400); - $time = round((($dateTime / 86400) - $days) * 86400); - $hours = round($time / 3600); - $minutes = round($time / 60) - ($hours * 60); - $seconds = round($time) - ($hours * 3600) - ($minutes * 60); - - $dateObj = date_create('1-Jan-1970+'.$days.' days'); - $dateObj->setTime($hours,$minutes,$seconds); - - return $dateObj; - } // function ExcelToPHPObject() - - - /** - * Convert a date from PHP to Excel - * - * @param mixed $dateValue PHP serialized date/time or date object - * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as - * a UST timestamp, or adjusted to UST - * @param string $timezone The timezone for finding the adjustment from UST - * @return mixed Excel date/time value - * or boolean FALSE on failure - */ - public static function PHPToExcel($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { - $saveTimeZone = date_default_timezone_get(); - date_default_timezone_set('UTC'); - $retValue = FALSE; - if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { - $retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), - $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s') - ); - } elseif (is_numeric($dateValue)) { - $retValue = self::FormattedPHPToExcel( date('Y',$dateValue), date('m',$dateValue), date('d',$dateValue), - date('H',$dateValue), date('i',$dateValue), date('s',$dateValue) - ); - } - date_default_timezone_set($saveTimeZone); - - return $retValue; - } // function PHPToExcel() - - - /** - * FormattedPHPToExcel - * - * @param long $year - * @param long $month - * @param long $day - * @param long $hours - * @param long $minutes - * @param long $seconds - * @return long Excel date/time value - */ - public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minutes=0, $seconds=0) { - if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { - // - // Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel - // This affects every date following 28th February 1900 - // - $excel1900isLeapYear = TRUE; - if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = FALSE; } - $my_excelBaseDate = 2415020; - } else { - $my_excelBaseDate = 2416481; - $excel1900isLeapYear = FALSE; - } - - // Julian base date Adjustment - if ($month > 2) { - $month -= 3; - } else { - $month += 9; - --$year; - } - - // Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0) - $century = substr($year,0,2); - $decade = substr($year,2,2); - $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $my_excelBaseDate + $excel1900isLeapYear; - - $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; - - return (float) $excelDate + $excelTime; - } // function FormattedPHPToExcel() - - - /** - * Is a given cell a date/time? - * - * @param PHPExcel_Cell $pCell - * @return boolean - */ - public static function isDateTime(PHPExcel_Cell $pCell) { - return self::isDateTimeFormat( - $pCell->getWorksheet()->getStyle( - $pCell->getCoordinate() - )->getNumberFormat() - ); - } // function isDateTime() - - - /** - * Is a given number format a date/time? - * - * @param PHPExcel_Style_NumberFormat $pFormat - * @return boolean - */ - public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) { - return self::isDateTimeFormatCode($pFormat->getFormatCode()); - } // function isDateTimeFormat() - - - private static $possibleDateFormatCharacters = 'eymdHs'; - - /** - * Is a given number format code a date/time? - * - * @param string $pFormatCode - * @return boolean - */ - public static function isDateTimeFormatCode($pFormatCode = '') { - if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) - // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) - return FALSE; + /** constants */ + const CALENDAR_WINDOWS_1900 = 1900; // Base date of 1st Jan 1900 = 1.0 + const CALENDAR_MAC_1904 = 1904; // Base date of 2nd Jan 1904 = 1.0 + + /* + * Names of the months of the year, indexed by shortname + * Planned usage for locale settings + * + * @public + * @var string[] + */ + public static $_monthNames = array( 'Jan' => 'January', + 'Feb' => 'February', + 'Mar' => 'March', + 'Apr' => 'April', + 'May' => 'May', + 'Jun' => 'June', + 'Jul' => 'July', + 'Aug' => 'August', + 'Sep' => 'September', + 'Oct' => 'October', + 'Nov' => 'November', + 'Dec' => 'December', + ); + + /* + * Names of the months of the year, indexed by shortname + * Planned usage for locale settings + * + * @public + * @var string[] + */ + public static $_numberSuffixes = array( 'st', + 'nd', + 'rd', + 'th', + ); + + /* + * Base calendar year to use for calculations + * + * @private + * @var int + */ + protected static $_excelBaseDate = self::CALENDAR_WINDOWS_1900; + + /** + * Set the Excel calendar (Windows 1900 or Mac 1904) + * + * @param integer $baseDate Excel base date (1900 or 1904) + * @return boolean Success or failure + */ + public static function setExcelCalendar($baseDate) { + if (($baseDate == self::CALENDAR_WINDOWS_1900) || + ($baseDate == self::CALENDAR_MAC_1904)) { + self::$_excelBaseDate = $baseDate; + return TRUE; + } + return FALSE; + } // function setExcelCalendar() + + + /** + * Return the Excel calendar (Windows 1900 or Mac 1904) + * + * @return integer Excel base date (1900 or 1904) + */ + public static function getExcelCalendar() { + return self::$_excelBaseDate; + } // function getExcelCalendar() + + + /** + * Convert a date from Excel to PHP + * + * @param long $dateValue Excel date/time value + * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as + * a UST timestamp, or adjusted to UST + * @param string $timezone The timezone for finding the adjustment from UST + * @return long PHP serialized date/time + */ + public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { + if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { + $my_excelBaseDate = 25569; + // Adjust for the spurious 29-Feb-1900 (Day 60) + if ($dateValue < 60) { + --$my_excelBaseDate; + } + } else { + $my_excelBaseDate = 24107; + } + + // Perform conversion + if ($dateValue >= 1) { + $utcDays = $dateValue - $my_excelBaseDate; + $returnValue = round($utcDays * 86400); + if (($returnValue <= PHP_INT_MAX) && ($returnValue >= -PHP_INT_MAX)) { + $returnValue = (integer) $returnValue; + } + } else { + $hours = round($dateValue * 24); + $mins = round($dateValue * 1440) - round($hours * 60); + $secs = round($dateValue * 86400) - round($hours * 3600) - round($mins * 60); + $returnValue = (integer) gmmktime($hours, $mins, $secs); + } + + $timezoneAdjustment = ($adjustToTimezone) ? + PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone, $returnValue) : + 0; + + // Return + return $returnValue + $timezoneAdjustment; + } // function ExcelToPHP() + + + /** + * Convert a date from Excel to a PHP Date/Time object + * + * @param integer $dateValue Excel date/time value + * @return DateTime PHP date/time object + */ + public static function ExcelToPHPObject($dateValue = 0) { + $dateTime = self::ExcelToPHP($dateValue); + $days = floor($dateTime / 86400); + $time = round((($dateTime / 86400) - $days) * 86400); + $hours = round($time / 3600); + $minutes = round($time / 60) - ($hours * 60); + $seconds = round($time) - ($hours * 3600) - ($minutes * 60); + + $dateObj = date_create('1-Jan-1970+'.$days.' days'); + $dateObj->setTime($hours,$minutes,$seconds); + + return $dateObj; + } // function ExcelToPHPObject() + + + /** + * Convert a date from PHP to Excel + * + * @param mixed $dateValue PHP serialized date/time or date object + * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as + * a UST timestamp, or adjusted to UST + * @param string $timezone The timezone for finding the adjustment from UST + * @return mixed Excel date/time value + * or boolean FALSE on failure + */ + public static function PHPToExcel($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { + $saveTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $retValue = FALSE; + if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { + $retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), + $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s') + ); + } elseif (is_numeric($dateValue)) { + $retValue = self::FormattedPHPToExcel( date('Y',$dateValue), date('m',$dateValue), date('d',$dateValue), + date('H',$dateValue), date('i',$dateValue), date('s',$dateValue) + ); + } + date_default_timezone_set($saveTimeZone); + + return $retValue; + } // function PHPToExcel() + + + /** + * FormattedPHPToExcel + * + * @param long $year + * @param long $month + * @param long $day + * @param long $hours + * @param long $minutes + * @param long $seconds + * @return long Excel date/time value + */ + public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minutes=0, $seconds=0) { + if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { + // + // Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel + // This affects every date following 28th February 1900 + // + $excel1900isLeapYear = TRUE; + if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = FALSE; } + $my_excelBaseDate = 2415020; + } else { + $my_excelBaseDate = 2416481; + $excel1900isLeapYear = FALSE; + } + + // Julian base date Adjustment + if ($month > 2) { + $month -= 3; + } else { + $month += 9; + --$year; + } + + // Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0) + $century = substr($year,0,2); + $decade = substr($year,2,2); + $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $my_excelBaseDate + $excel1900isLeapYear; + + $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; + + return (float) $excelDate + $excelTime; + } // function FormattedPHPToExcel() + + + /** + * Is a given cell a date/time? + * + * @param PHPExcel_Cell $pCell + * @return boolean + */ + public static function isDateTime(PHPExcel_Cell $pCell) { + return self::isDateTimeFormat( + $pCell->getWorksheet()->getStyle( + $pCell->getCoordinate() + )->getNumberFormat() + ); + } // function isDateTime() + + + /** + * Is a given number format a date/time? + * + * @param PHPExcel_Style_NumberFormat $pFormat + * @return boolean + */ + public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) { + return self::isDateTimeFormatCode($pFormat->getFormatCode()); + } // function isDateTimeFormat() + + + private static $possibleDateFormatCharacters = 'eymdHs'; + + /** + * Is a given number format code a date/time? + * + * @param string $pFormatCode + * @return boolean + */ + public static function isDateTimeFormatCode($pFormatCode = '') { + if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) + // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) + return FALSE; if (preg_match('/[0#]E[+-]0/i', $pFormatCode)) - // Scientific format - return FALSE; - // Switch on formatcode - switch ($pFormatCode) { - // Explicitly defined date formats - case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYMINUS: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMMINUS: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_MYMINUS: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME1: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME2: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME5: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME6: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME7: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME8: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX14: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22: - return TRUE; - } - - // Typically number, currency or accounting (or occasionally fraction) formats - if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) { - return FALSE; - } - // Try checking for any of the date formatting characters that don't appear within square braces - if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) { - // We might also have a format mask containing quoted strings... - // we don't want to test for any of our characters within the quoted blocks - if (strpos($pFormatCode,'"') !== FALSE) { - $segMatcher = FALSE; - foreach(explode('"',$pFormatCode) as $subVal) { - // Only test in alternate array entries (the non-quoted blocks) - if (($segMatcher = !$segMatcher) && - (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$subVal))) { - return TRUE; - } - } - return FALSE; - } - return TRUE; - } - - // No date... - return FALSE; - } // function isDateTimeFormatCode() - - - /** - * Convert a date/time string to Excel time - * - * @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10' - * @return float|FALSE Excel date/time serial value - */ - public static function stringToExcel($dateValue = '') { - if (strlen($dateValue) < 2) - return FALSE; - if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) - return FALSE; - - $dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue); - - if ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) { - return FALSE; - } else { - if (strpos($dateValue, ':') !== FALSE) { - $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue); - if ($timeValue === PHPExcel_Calculation_Functions::VALUE()) { - return FALSE; - } - $dateValueNew += $timeValue; - } - return $dateValueNew; - } - - - } + // Scientific format + return FALSE; + // Switch on formatcode + switch ($pFormatCode) { + // Explicitly defined date formats + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_MYMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME1: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME2: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME5: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME6: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME7: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME8: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX14: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22: + return TRUE; + } + + // Typically number, currency or accounting (or occasionally fraction) formats + if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) { + return FALSE; + } + // Try checking for any of the date formatting characters that don't appear within square braces + if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) { + // We might also have a format mask containing quoted strings... + // we don't want to test for any of our characters within the quoted blocks + if (strpos($pFormatCode,'"') !== FALSE) { + $segMatcher = FALSE; + foreach(explode('"',$pFormatCode) as $subVal) { + // Only test in alternate array entries (the non-quoted blocks) + if (($segMatcher = !$segMatcher) && + (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$subVal))) { + return TRUE; + } + } + return FALSE; + } + return TRUE; + } + + // No date... + return FALSE; + } // function isDateTimeFormatCode() + + + /** + * Convert a date/time string to Excel time + * + * @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10' + * @return float|FALSE Excel date/time serial value + */ + public static function stringToExcel($dateValue = '') { + if (strlen($dateValue) < 2) + return FALSE; + if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) + return FALSE; + + $dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue); + + if ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) { + return FALSE; + } else { + if (strpos($dateValue, ':') !== FALSE) { + $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue); + if ($timeValue === PHPExcel_Calculation_Functions::VALUE()) { + return FALSE; + } + $dateValueNew += $timeValue; + } + return $dateValueNew; + } + + + } public static function monthStringToNumber($month) { $monthIndex = 1; @@ -383,11 +383,11 @@ public static function monthStringToNumber($month) { } public static function dayStringToNumber($day) { - $strippedDayValue = (str_replace(self::$_numberSuffixes,'',$day)); - if (is_numeric($strippedDayValue)) { - return $strippedDayValue; - } - return $day; + $strippedDayValue = (str_replace(self::$_numberSuffixes,'',$day)); + if (is_numeric($strippedDayValue)) { + return $strippedDayValue; + } + return $day; } } diff --git a/Classes/PHPExcel/Shared/Drawing.php b/Classes/PHPExcel/Shared/Drawing.php index aeae3bd3d..311d9be49 100644 --- a/Classes/PHPExcel/Shared/Drawing.php +++ b/Classes/PHPExcel/Shared/Drawing.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,149 +35,149 @@ */ class PHPExcel_Shared_Drawing { - /** - * Convert pixels to EMU - * - * @param int $pValue Value in pixels - * @return int Value in EMU - */ - public static function pixelsToEMU($pValue = 0) { - return round($pValue * 9525); - } - - /** - * Convert EMU to pixels - * - * @param int $pValue Value in EMU - * @return int Value in pixels - */ - public static function EMUToPixels($pValue = 0) { - if ($pValue != 0) { - return round($pValue / 9525); - } else { - return 0; - } - } - - /** - * Convert pixels to column width. Exact algorithm not known. - * By inspection of a real Excel file using Calibri 11, one finds 1000px ~ 142.85546875 - * This gives a conversion factor of 7. Also, we assume that pixels and font size are proportional. - * - * @param int $pValue Value in pixels - * @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook - * @return int Value in cell dimension - */ - public static function pixelsToCellDimension($pValue = 0, PHPExcel_Style_Font $pDefaultFont) { - // Font name and size - $name = $pDefaultFont->getName(); - $size = $pDefaultFont->getSize(); - - if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) { - // Exact width can be determined - $colWidth = $pValue - * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width'] - / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px']; - } else { - // We don't have data for this particular font and size, use approximation by - // extrapolating from Calibri 11 - $colWidth = $pValue * 11 - * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] - / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] / $size; - } - - return $colWidth; - } - - /** - * Convert column width from (intrinsic) Excel units to pixels - * - * @param float $pValue Value in cell dimension - * @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook - * @return int Value in pixels - */ - public static function cellDimensionToPixels($pValue = 0, PHPExcel_Style_Font $pDefaultFont) { - // Font name and size - $name = $pDefaultFont->getName(); - $size = $pDefaultFont->getSize(); - - if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) { - // Exact width can be determined - $colWidth = $pValue - * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px'] - / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width']; - - } else { - // We don't have data for this particular font and size, use approximation by - // extrapolating from Calibri 11 - $colWidth = $pValue * $size - * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] - / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] / 11; - } - - // Round pixels to closest integer - $colWidth = (int) round($colWidth); - - return $colWidth; - } - - /** - * Convert pixels to points - * - * @param int $pValue Value in pixels - * @return int Value in points - */ - public static function pixelsToPoints($pValue = 0) { - return $pValue * 0.67777777; - } - - /** - * Convert points to pixels - * - * @param int $pValue Value in points - * @return int Value in pixels - */ - public static function pointsToPixels($pValue = 0) { - if ($pValue != 0) { - return (int) ceil($pValue * 1.333333333); - } else { - return 0; - } - } - - /** - * Convert degrees to angle - * - * @param int $pValue Degrees - * @return int Angle - */ - public static function degreesToAngle($pValue = 0) { - return (int)round($pValue * 60000); - } - - /** - * Convert angle to degrees - * - * @param int $pValue Angle - * @return int Degrees - */ - public static function angleToDegrees($pValue = 0) { - if ($pValue != 0) { - return round($pValue / 60000); - } else { - return 0; - } - } - - /** - * Create a new image from file. By alexander at alexauto dot nl - * - * @link http://www.php.net/manual/en/function.imagecreatefromwbmp.php#86214 - * @param string $filename Path to Windows DIB (BMP) image - * @return resource - */ - public static function imagecreatefrombmp($p_sFile) - { + /** + * Convert pixels to EMU + * + * @param int $pValue Value in pixels + * @return int Value in EMU + */ + public static function pixelsToEMU($pValue = 0) { + return round($pValue * 9525); + } + + /** + * Convert EMU to pixels + * + * @param int $pValue Value in EMU + * @return int Value in pixels + */ + public static function EMUToPixels($pValue = 0) { + if ($pValue != 0) { + return round($pValue / 9525); + } else { + return 0; + } + } + + /** + * Convert pixels to column width. Exact algorithm not known. + * By inspection of a real Excel file using Calibri 11, one finds 1000px ~ 142.85546875 + * This gives a conversion factor of 7. Also, we assume that pixels and font size are proportional. + * + * @param int $pValue Value in pixels + * @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook + * @return int Value in cell dimension + */ + public static function pixelsToCellDimension($pValue = 0, PHPExcel_Style_Font $pDefaultFont) { + // Font name and size + $name = $pDefaultFont->getName(); + $size = $pDefaultFont->getSize(); + + if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) { + // Exact width can be determined + $colWidth = $pValue + * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width'] + / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px']; + } else { + // We don't have data for this particular font and size, use approximation by + // extrapolating from Calibri 11 + $colWidth = $pValue * 11 + * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] + / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] / $size; + } + + return $colWidth; + } + + /** + * Convert column width from (intrinsic) Excel units to pixels + * + * @param float $pValue Value in cell dimension + * @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook + * @return int Value in pixels + */ + public static function cellDimensionToPixels($pValue = 0, PHPExcel_Style_Font $pDefaultFont) { + // Font name and size + $name = $pDefaultFont->getName(); + $size = $pDefaultFont->getSize(); + + if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) { + // Exact width can be determined + $colWidth = $pValue + * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px'] + / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width']; + + } else { + // We don't have data for this particular font and size, use approximation by + // extrapolating from Calibri 11 + $colWidth = $pValue * $size + * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] + / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] / 11; + } + + // Round pixels to closest integer + $colWidth = (int) round($colWidth); + + return $colWidth; + } + + /** + * Convert pixels to points + * + * @param int $pValue Value in pixels + * @return int Value in points + */ + public static function pixelsToPoints($pValue = 0) { + return $pValue * 0.67777777; + } + + /** + * Convert points to pixels + * + * @param int $pValue Value in points + * @return int Value in pixels + */ + public static function pointsToPixels($pValue = 0) { + if ($pValue != 0) { + return (int) ceil($pValue * 1.333333333); + } else { + return 0; + } + } + + /** + * Convert degrees to angle + * + * @param int $pValue Degrees + * @return int Angle + */ + public static function degreesToAngle($pValue = 0) { + return (int)round($pValue * 60000); + } + + /** + * Convert angle to degrees + * + * @param int $pValue Angle + * @return int Degrees + */ + public static function angleToDegrees($pValue = 0) { + if ($pValue != 0) { + return round($pValue / 60000); + } else { + return 0; + } + } + + /** + * Create a new image from file. By alexander at alexauto dot nl + * + * @link http://www.php.net/manual/en/function.imagecreatefromwbmp.php#86214 + * @param string $filename Path to Windows DIB (BMP) image + * @return resource + */ + public static function imagecreatefrombmp($p_sFile) + { // Load the image into a string $file = fopen($p_sFile,"rb"); $read = fread($file,10); @@ -267,6 +267,6 @@ public static function imagecreatefrombmp($p_sFile) // Return image-object return $image; - } + } } diff --git a/Classes/PHPExcel/Shared/Escher.php b/Classes/PHPExcel/Shared/Escher.php index 88cb1c6fd..67b346ee3 100644 --- a/Classes/PHPExcel/Shared/Escher.php +++ b/Classes/PHPExcel/Shared/Escher.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Escher * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,58 +34,58 @@ */ class PHPExcel_Shared_Escher { - /** - * Drawing Group Container - * - * @var PHPExcel_Shared_Escher_DggContainer - */ - private $_dggContainer; + /** + * Drawing Group Container + * + * @var PHPExcel_Shared_Escher_DggContainer + */ + private $_dggContainer; - /** - * Drawing Container - * - * @var PHPExcel_Shared_Escher_DgContainer - */ - private $_dgContainer; + /** + * Drawing Container + * + * @var PHPExcel_Shared_Escher_DgContainer + */ + private $_dgContainer; - /** - * Get Drawing Group Container - * - * @return PHPExcel_Shared_Escher_DgContainer - */ - public function getDggContainer() - { - return $this->_dggContainer; - } + /** + * Get Drawing Group Container + * + * @return PHPExcel_Shared_Escher_DgContainer + */ + public function getDggContainer() + { + return $this->_dggContainer; + } - /** - * Set Drawing Group Container - * - * @param PHPExcel_Shared_Escher_DggContainer $dggContainer - */ - public function setDggContainer($dggContainer) - { - return $this->_dggContainer = $dggContainer; - } + /** + * Set Drawing Group Container + * + * @param PHPExcel_Shared_Escher_DggContainer $dggContainer + */ + public function setDggContainer($dggContainer) + { + return $this->_dggContainer = $dggContainer; + } - /** - * Get Drawing Container - * - * @return PHPExcel_Shared_Escher_DgContainer - */ - public function getDgContainer() - { - return $this->_dgContainer; - } + /** + * Get Drawing Container + * + * @return PHPExcel_Shared_Escher_DgContainer + */ + public function getDgContainer() + { + return $this->_dgContainer; + } - /** - * Set Drawing Container - * - * @param PHPExcel_Shared_Escher_DgContainer $dgContainer - */ - public function setDgContainer($dgContainer) - { - return $this->_dgContainer = $dgContainer; - } + /** + * Set Drawing Container + * + * @param PHPExcel_Shared_Escher_DgContainer $dgContainer + */ + public function setDgContainer($dgContainer) + { + return $this->_dgContainer = $dgContainer; + } } diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer.php index b7c9fd9e8..ef855d753 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Escher * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,50 +34,50 @@ */ class PHPExcel_Shared_Escher_DgContainer { - /** - * Drawing index, 1-based. - * - * @var int - */ - private $_dgId; + /** + * Drawing index, 1-based. + * + * @var int + */ + private $_dgId; - /** - * Last shape index in this drawing - * - * @var int - */ - private $_lastSpId; + /** + * Last shape index in this drawing + * + * @var int + */ + private $_lastSpId; - private $_spgrContainer = null; + private $_spgrContainer = null; - public function getDgId() - { - return $this->_dgId; - } + public function getDgId() + { + return $this->_dgId; + } - public function setDgId($value) - { - $this->_dgId = $value; - } + public function setDgId($value) + { + $this->_dgId = $value; + } - public function getLastSpId() - { - return $this->_lastSpId; - } + public function getLastSpId() + { + return $this->_lastSpId; + } - public function setLastSpId($value) - { - $this->_lastSpId = $value; - } + public function setLastSpId($value) + { + $this->_lastSpId = $value; + } - public function getSpgrContainer() - { - return $this->_spgrContainer; - } + public function getSpgrContainer() + { + return $this->_spgrContainer; + } - public function setSpgrContainer($spgrContainer) - { - return $this->_spgrContainer = $spgrContainer; - } + public function setSpgrContainer($spgrContainer) + { + return $this->_spgrContainer = $spgrContainer; + } } diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php index c60c641cd..efa1683f3 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Escher * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,76 +34,76 @@ */ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer { - /** - * Parent Shape Group Container - * - * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer - */ - private $_parent; + /** + * Parent Shape Group Container + * + * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer + */ + private $_parent; - /** - * Shape Container collection - * - * @var array - */ - private $_children = array(); + /** + * Shape Container collection + * + * @var array + */ + private $_children = array(); - /** - * Set parent Shape Group Container - * - * @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent - */ - public function setParent($parent) - { - $this->_parent = $parent; - } + /** + * Set parent Shape Group Container + * + * @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } - /** - * Get the parent Shape Group Container if any - * - * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer|null - */ - public function getParent() - { - return $this->_parent; - } + /** + * Get the parent Shape Group Container if any + * + * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer|null + */ + public function getParent() + { + return $this->_parent; + } - /** - * Add a child. This will be either spgrContainer or spContainer - * - * @param mixed $child - */ - public function addChild($child) - { - $this->_children[] = $child; - $child->setParent($this); - } + /** + * Add a child. This will be either spgrContainer or spContainer + * + * @param mixed $child + */ + public function addChild($child) + { + $this->_children[] = $child; + $child->setParent($this); + } - /** - * Get collection of Shape Containers - */ - public function getChildren() - { - return $this->_children; - } + /** + * Get collection of Shape Containers + */ + public function getChildren() + { + return $this->_children; + } - /** - * Recursively get all spContainers within this spgrContainer - * - * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer[] - */ - public function getAllSpContainers() - { - $allSpContainers = array(); + /** + * Recursively get all spContainers within this spgrContainer + * + * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer[] + */ + public function getAllSpContainers() + { + $allSpContainers = array(); - foreach ($this->_children as $child) { - if ($child instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) { - $allSpContainers = array_merge($allSpContainers, $child->getAllSpContainers()); - } else { - $allSpContainers[] = $child; - } - } + foreach ($this->_children as $child) { + if ($child instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) { + $allSpContainers = array_merge($allSpContainers, $child->getAllSpContainers()); + } else { + $allSpContainers[] = $child; + } + } - return $allSpContainers; - } + return $allSpContainers; + } } diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php index 97792af55..97136ee05 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Escher * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,362 +34,362 @@ */ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer { - /** - * Parent Shape Group Container - * - * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer - */ - private $_parent; - - /** - * Is this a group shape? - * - * @var boolean - */ - private $_spgr = false; - - /** - * Shape type - * - * @var int - */ - private $_spType; - - /** - * Shape flag - * - * @var int - */ - private $_spFlag; - - /** - * Shape index (usually group shape has index 0, and the rest: 1,2,3...) - * - * @var boolean - */ - private $_spId; - - /** - * Array of options - * - * @var array - */ - private $_OPT; - - /** - * Cell coordinates of upper-left corner of shape, e.g. 'A1' - * - * @var string - */ - private $_startCoordinates; - - /** - * Horizontal offset of upper-left corner of shape measured in 1/1024 of column width - * - * @var int - */ - private $_startOffsetX; - - /** - * Vertical offset of upper-left corner of shape measured in 1/256 of row height - * - * @var int - */ - private $_startOffsetY; - - /** - * Cell coordinates of bottom-right corner of shape, e.g. 'B2' - * - * @var string - */ - private $_endCoordinates; - - /** - * Horizontal offset of bottom-right corner of shape measured in 1/1024 of column width - * - * @var int - */ - private $_endOffsetX; - - /** - * Vertical offset of bottom-right corner of shape measured in 1/256 of row height - * - * @var int - */ - private $_endOffsetY; - - /** - * Set parent Shape Group Container - * - * @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent - */ - public function setParent($parent) - { - $this->_parent = $parent; - } - - /** - * Get the parent Shape Group Container - * - * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer - */ - public function getParent() - { - return $this->_parent; - } - - /** - * Set whether this is a group shape - * - * @param boolean $value - */ - public function setSpgr($value = false) - { - $this->_spgr = $value; - } - - /** - * Get whether this is a group shape - * - * @return boolean - */ - public function getSpgr() - { - return $this->_spgr; - } - - /** - * Set the shape type - * - * @param int $value - */ - public function setSpType($value) - { - $this->_spType = $value; - } - - /** - * Get the shape type - * - * @return int - */ - public function getSpType() - { - return $this->_spType; - } - - /** - * Set the shape flag - * - * @param int $value - */ - public function setSpFlag($value) - { - $this->_spFlag = $value; - } - - /** - * Get the shape flag - * - * @return int - */ - public function getSpFlag() - { - return $this->_spFlag; - } - - /** - * Set the shape index - * - * @param int $value - */ - public function setSpId($value) - { - $this->_spId = $value; - } - - /** - * Get the shape index - * - * @return int - */ - public function getSpId() - { - return $this->_spId; - } - - /** - * Set an option for the Shape Group Container - * - * @param int $property The number specifies the option - * @param mixed $value - */ - public function setOPT($property, $value) - { - $this->_OPT[$property] = $value; - } - - /** - * Get an option for the Shape Group Container - * - * @param int $property The number specifies the option - * @return mixed - */ - public function getOPT($property) - { - if (isset($this->_OPT[$property])) { - return $this->_OPT[$property]; - } - return null; - } - - /** - * Get the collection of options - * - * @return array - */ - public function getOPTCollection() - { - return $this->_OPT; - } - - /** - * Set cell coordinates of upper-left corner of shape - * - * @param string $value - */ - public function setStartCoordinates($value = 'A1') - { - $this->_startCoordinates = $value; - } - - /** - * Get cell coordinates of upper-left corner of shape - * - * @return string - */ - public function getStartCoordinates() - { - return $this->_startCoordinates; - } - - /** - * Set offset in x-direction of upper-left corner of shape measured in 1/1024 of column width - * - * @param int $startOffsetX - */ - public function setStartOffsetX($startOffsetX = 0) - { - $this->_startOffsetX = $startOffsetX; - } - - /** - * Get offset in x-direction of upper-left corner of shape measured in 1/1024 of column width - * - * @return int - */ - public function getStartOffsetX() - { - return $this->_startOffsetX; - } - - /** - * Set offset in y-direction of upper-left corner of shape measured in 1/256 of row height - * - * @param int $startOffsetY - */ - public function setStartOffsetY($startOffsetY = 0) - { - $this->_startOffsetY = $startOffsetY; - } - - /** - * Get offset in y-direction of upper-left corner of shape measured in 1/256 of row height - * - * @return int - */ - public function getStartOffsetY() - { - return $this->_startOffsetY; - } - - /** - * Set cell coordinates of bottom-right corner of shape - * - * @param string $value - */ - public function setEndCoordinates($value = 'A1') - { - $this->_endCoordinates = $value; - } - - /** - * Get cell coordinates of bottom-right corner of shape - * - * @return string - */ - public function getEndCoordinates() - { - return $this->_endCoordinates; - } - - /** - * Set offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width - * - * @param int $startOffsetX - */ - public function setEndOffsetX($endOffsetX = 0) - { - $this->_endOffsetX = $endOffsetX; - } - - /** - * Get offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width - * - * @return int - */ - public function getEndOffsetX() - { - return $this->_endOffsetX; - } - - /** - * Set offset in y-direction of bottom-right corner of shape measured in 1/256 of row height - * - * @param int $endOffsetY - */ - public function setEndOffsetY($endOffsetY = 0) - { - $this->_endOffsetY = $endOffsetY; - } - - /** - * Get offset in y-direction of bottom-right corner of shape measured in 1/256 of row height - * - * @return int - */ - public function getEndOffsetY() - { - return $this->_endOffsetY; - } - - /** - * Get the nesting level of this spContainer. This is the number of spgrContainers between this spContainer and - * the dgContainer. A value of 1 = immediately within first spgrContainer - * Higher nesting level occurs if and only if spContainer is part of a shape group - * - * @return int Nesting level - */ - public function getNestingLevel() - { - $nestingLevel = 0; - - $parent = $this->getParent(); - while ($parent instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) { - ++$nestingLevel; - $parent = $parent->getParent(); - } - - return $nestingLevel; - } + /** + * Parent Shape Group Container + * + * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer + */ + private $_parent; + + /** + * Is this a group shape? + * + * @var boolean + */ + private $_spgr = false; + + /** + * Shape type + * + * @var int + */ + private $_spType; + + /** + * Shape flag + * + * @var int + */ + private $_spFlag; + + /** + * Shape index (usually group shape has index 0, and the rest: 1,2,3...) + * + * @var boolean + */ + private $_spId; + + /** + * Array of options + * + * @var array + */ + private $_OPT; + + /** + * Cell coordinates of upper-left corner of shape, e.g. 'A1' + * + * @var string + */ + private $_startCoordinates; + + /** + * Horizontal offset of upper-left corner of shape measured in 1/1024 of column width + * + * @var int + */ + private $_startOffsetX; + + /** + * Vertical offset of upper-left corner of shape measured in 1/256 of row height + * + * @var int + */ + private $_startOffsetY; + + /** + * Cell coordinates of bottom-right corner of shape, e.g. 'B2' + * + * @var string + */ + private $_endCoordinates; + + /** + * Horizontal offset of bottom-right corner of shape measured in 1/1024 of column width + * + * @var int + */ + private $_endOffsetX; + + /** + * Vertical offset of bottom-right corner of shape measured in 1/256 of row height + * + * @var int + */ + private $_endOffsetY; + + /** + * Set parent Shape Group Container + * + * @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } + + /** + * Get the parent Shape Group Container + * + * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer + */ + public function getParent() + { + return $this->_parent; + } + + /** + * Set whether this is a group shape + * + * @param boolean $value + */ + public function setSpgr($value = false) + { + $this->_spgr = $value; + } + + /** + * Get whether this is a group shape + * + * @return boolean + */ + public function getSpgr() + { + return $this->_spgr; + } + + /** + * Set the shape type + * + * @param int $value + */ + public function setSpType($value) + { + $this->_spType = $value; + } + + /** + * Get the shape type + * + * @return int + */ + public function getSpType() + { + return $this->_spType; + } + + /** + * Set the shape flag + * + * @param int $value + */ + public function setSpFlag($value) + { + $this->_spFlag = $value; + } + + /** + * Get the shape flag + * + * @return int + */ + public function getSpFlag() + { + return $this->_spFlag; + } + + /** + * Set the shape index + * + * @param int $value + */ + public function setSpId($value) + { + $this->_spId = $value; + } + + /** + * Get the shape index + * + * @return int + */ + public function getSpId() + { + return $this->_spId; + } + + /** + * Set an option for the Shape Group Container + * + * @param int $property The number specifies the option + * @param mixed $value + */ + public function setOPT($property, $value) + { + $this->_OPT[$property] = $value; + } + + /** + * Get an option for the Shape Group Container + * + * @param int $property The number specifies the option + * @return mixed + */ + public function getOPT($property) + { + if (isset($this->_OPT[$property])) { + return $this->_OPT[$property]; + } + return null; + } + + /** + * Get the collection of options + * + * @return array + */ + public function getOPTCollection() + { + return $this->_OPT; + } + + /** + * Set cell coordinates of upper-left corner of shape + * + * @param string $value + */ + public function setStartCoordinates($value = 'A1') + { + $this->_startCoordinates = $value; + } + + /** + * Get cell coordinates of upper-left corner of shape + * + * @return string + */ + public function getStartCoordinates() + { + return $this->_startCoordinates; + } + + /** + * Set offset in x-direction of upper-left corner of shape measured in 1/1024 of column width + * + * @param int $startOffsetX + */ + public function setStartOffsetX($startOffsetX = 0) + { + $this->_startOffsetX = $startOffsetX; + } + + /** + * Get offset in x-direction of upper-left corner of shape measured in 1/1024 of column width + * + * @return int + */ + public function getStartOffsetX() + { + return $this->_startOffsetX; + } + + /** + * Set offset in y-direction of upper-left corner of shape measured in 1/256 of row height + * + * @param int $startOffsetY + */ + public function setStartOffsetY($startOffsetY = 0) + { + $this->_startOffsetY = $startOffsetY; + } + + /** + * Get offset in y-direction of upper-left corner of shape measured in 1/256 of row height + * + * @return int + */ + public function getStartOffsetY() + { + return $this->_startOffsetY; + } + + /** + * Set cell coordinates of bottom-right corner of shape + * + * @param string $value + */ + public function setEndCoordinates($value = 'A1') + { + $this->_endCoordinates = $value; + } + + /** + * Get cell coordinates of bottom-right corner of shape + * + * @return string + */ + public function getEndCoordinates() + { + return $this->_endCoordinates; + } + + /** + * Set offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width + * + * @param int $startOffsetX + */ + public function setEndOffsetX($endOffsetX = 0) + { + $this->_endOffsetX = $endOffsetX; + } + + /** + * Get offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width + * + * @return int + */ + public function getEndOffsetX() + { + return $this->_endOffsetX; + } + + /** + * Set offset in y-direction of bottom-right corner of shape measured in 1/256 of row height + * + * @param int $endOffsetY + */ + public function setEndOffsetY($endOffsetY = 0) + { + $this->_endOffsetY = $endOffsetY; + } + + /** + * Get offset in y-direction of bottom-right corner of shape measured in 1/256 of row height + * + * @return int + */ + public function getEndOffsetY() + { + return $this->_endOffsetY; + } + + /** + * Get the nesting level of this spContainer. This is the number of spgrContainers between this spContainer and + * the dgContainer. A value of 1 = immediately within first spgrContainer + * Higher nesting level occurs if and only if spContainer is part of a shape group + * + * @return int Nesting level + */ + public function getNestingLevel() + { + $nestingLevel = 0; + + $parent = $this->getParent(); + while ($parent instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) { + ++$nestingLevel; + $parent = $parent->getParent(); + } + + return $nestingLevel; + } } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer.php index b5dd3eecf..dae6a5a42 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Escher * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,170 +34,170 @@ */ class PHPExcel_Shared_Escher_DggContainer { - /** - * Maximum shape index of all shapes in all drawings increased by one - * - * @var int - */ - private $_spIdMax; - - /** - * Total number of drawings saved - * - * @var int - */ - private $_cDgSaved; - - /** - * Total number of shapes saved (including group shapes) - * - * @var int - */ - private $_cSpSaved; - - /** - * BLIP Store Container - * - * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer - */ - private $_bstoreContainer; - - /** - * Array of options for the drawing group - * - * @var array - */ - private $_OPT = array(); - - /** - * Array of identifier clusters containg information about the maximum shape identifiers - * - * @var array - */ - private $_IDCLs = array(); - - /** - * Get maximum shape index of all shapes in all drawings (plus one) - * - * @return int - */ - public function getSpIdMax() - { - return $this->_spIdMax; - } - - /** - * Set maximum shape index of all shapes in all drawings (plus one) - * - * @param int - */ - public function setSpIdMax($value) - { - $this->_spIdMax = $value; - } - - /** - * Get total number of drawings saved - * - * @return int - */ - public function getCDgSaved() - { - return $this->_cDgSaved; - } - - /** - * Set total number of drawings saved - * - * @param int - */ - public function setCDgSaved($value) - { - $this->_cDgSaved = $value; - } - - /** - * Get total number of shapes saved (including group shapes) - * - * @return int - */ - public function getCSpSaved() - { - return $this->_cSpSaved; - } - - /** - * Set total number of shapes saved (including group shapes) - * - * @param int - */ - public function setCSpSaved($value) - { - $this->_cSpSaved = $value; - } - - /** - * Get BLIP Store Container - * - * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer - */ - public function getBstoreContainer() - { - return $this->_bstoreContainer; - } - - /** - * Set BLIP Store Container - * - * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $bstoreContainer - */ - public function setBstoreContainer($bstoreContainer) - { - $this->_bstoreContainer = $bstoreContainer; - } - - /** - * Set an option for the drawing group - * - * @param int $property The number specifies the option - * @param mixed $value - */ - public function setOPT($property, $value) - { - $this->_OPT[$property] = $value; - } - - /** - * Get an option for the drawing group - * - * @param int $property The number specifies the option - * @return mixed - */ - public function getOPT($property) - { - if (isset($this->_OPT[$property])) { - return $this->_OPT[$property]; - } - return null; - } - - /** - * Get identifier clusters - * - * @return array - */ - public function getIDCLs() - { - return $this->_IDCLs; - } - - /** - * Set identifier clusters. array(<drawingId> => <max shape id>, ...) - * - * @param array $pValue - */ - public function setIDCLs($pValue) - { - $this->_IDCLs = $pValue; - } + /** + * Maximum shape index of all shapes in all drawings increased by one + * + * @var int + */ + private $_spIdMax; + + /** + * Total number of drawings saved + * + * @var int + */ + private $_cDgSaved; + + /** + * Total number of shapes saved (including group shapes) + * + * @var int + */ + private $_cSpSaved; + + /** + * BLIP Store Container + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer + */ + private $_bstoreContainer; + + /** + * Array of options for the drawing group + * + * @var array + */ + private $_OPT = array(); + + /** + * Array of identifier clusters containg information about the maximum shape identifiers + * + * @var array + */ + private $_IDCLs = array(); + + /** + * Get maximum shape index of all shapes in all drawings (plus one) + * + * @return int + */ + public function getSpIdMax() + { + return $this->_spIdMax; + } + + /** + * Set maximum shape index of all shapes in all drawings (plus one) + * + * @param int + */ + public function setSpIdMax($value) + { + $this->_spIdMax = $value; + } + + /** + * Get total number of drawings saved + * + * @return int + */ + public function getCDgSaved() + { + return $this->_cDgSaved; + } + + /** + * Set total number of drawings saved + * + * @param int + */ + public function setCDgSaved($value) + { + $this->_cDgSaved = $value; + } + + /** + * Get total number of shapes saved (including group shapes) + * + * @return int + */ + public function getCSpSaved() + { + return $this->_cSpSaved; + } + + /** + * Set total number of shapes saved (including group shapes) + * + * @param int + */ + public function setCSpSaved($value) + { + $this->_cSpSaved = $value; + } + + /** + * Get BLIP Store Container + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer + */ + public function getBstoreContainer() + { + return $this->_bstoreContainer; + } + + /** + * Set BLIP Store Container + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $bstoreContainer + */ + public function setBstoreContainer($bstoreContainer) + { + $this->_bstoreContainer = $bstoreContainer; + } + + /** + * Set an option for the drawing group + * + * @param int $property The number specifies the option + * @param mixed $value + */ + public function setOPT($property, $value) + { + $this->_OPT[$property] = $value; + } + + /** + * Get an option for the drawing group + * + * @param int $property The number specifies the option + * @return mixed + */ + public function getOPT($property) + { + if (isset($this->_OPT[$property])) { + return $this->_OPT[$property]; + } + return null; + } + + /** + * Get identifier clusters + * + * @return array + */ + public function getIDCLs() + { + return $this->_IDCLs; + } + + /** + * Set identifier clusters. array(<drawingId> => <max shape id>, ...) + * + * @param array $pValue + */ + public function setIDCLs($pValue) + { + $this->_IDCLs = $pValue; + } } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php index 468ca2465..390f09b68 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Escher * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,32 +34,32 @@ */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer { - /** - * BLIP Store Entries. Each of them holds one BLIP (Big Large Image or Picture) - * - * @var array - */ - private $_BSECollection = array(); + /** + * BLIP Store Entries. Each of them holds one BLIP (Big Large Image or Picture) + * + * @var array + */ + private $_BSECollection = array(); - /** - * Add a BLIP Store Entry - * - * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $BSE - */ - public function addBSE($BSE) - { - $this->_BSECollection[] = $BSE; - $BSE->setParent($this); - } + /** + * Add a BLIP Store Entry + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $BSE + */ + public function addBSE($BSE) + { + $this->_BSECollection[] = $BSE; + $BSE->setParent($this); + } - /** - * Get the collection of BLIP Store Entries - * - * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE[] - */ - public function getBSECollection() - { - return $this->_BSECollection; - } + /** + * Get the collection of BLIP Store Entries + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE[] + */ + public function getBSECollection() + { + return $this->_BSECollection; + } } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php index 0b1239de4..0fac1b8e5 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Escher * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,87 +34,87 @@ */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE { - const BLIPTYPE_ERROR = 0x00; - const BLIPTYPE_UNKNOWN = 0x01; - const BLIPTYPE_EMF = 0x02; - const BLIPTYPE_WMF = 0x03; - const BLIPTYPE_PICT = 0x04; - const BLIPTYPE_JPEG = 0x05; - const BLIPTYPE_PNG = 0x06; - const BLIPTYPE_DIB = 0x07; - const BLIPTYPE_TIFF = 0x11; - const BLIPTYPE_CMYKJPEG = 0x12; + const BLIPTYPE_ERROR = 0x00; + const BLIPTYPE_UNKNOWN = 0x01; + const BLIPTYPE_EMF = 0x02; + const BLIPTYPE_WMF = 0x03; + const BLIPTYPE_PICT = 0x04; + const BLIPTYPE_JPEG = 0x05; + const BLIPTYPE_PNG = 0x06; + const BLIPTYPE_DIB = 0x07; + const BLIPTYPE_TIFF = 0x11; + const BLIPTYPE_CMYKJPEG = 0x12; - /** - * The parent BLIP Store Entry Container - * - * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer - */ - private $_parent; + /** + * The parent BLIP Store Entry Container + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer + */ + private $_parent; - /** - * The BLIP (Big Large Image or Picture) - * - * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip - */ - private $_blip; + /** + * The BLIP (Big Large Image or Picture) + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip + */ + private $_blip; - /** - * The BLIP type - * - * @var int - */ - private $_blipType; + /** + * The BLIP type + * + * @var int + */ + private $_blipType; - /** - * Set parent BLIP Store Entry Container - * - * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $parent - */ - public function setParent($parent) - { - $this->_parent = $parent; - } + /** + * Set parent BLIP Store Entry Container + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } - /** - * Get the BLIP - * - * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip - */ - public function getBlip() - { - return $this->_blip; - } + /** + * Get the BLIP + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip + */ + public function getBlip() + { + return $this->_blip; + } - /** - * Set the BLIP - * - * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip $blip - */ - public function setBlip($blip) - { - $this->_blip = $blip; - $blip->setParent($this); - } + /** + * Set the BLIP + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip $blip + */ + public function setBlip($blip) + { + $this->_blip = $blip; + $blip->setParent($this); + } - /** - * Get the BLIP type - * - * @return int - */ - public function getBlipType() - { - return $this->_blipType; - } + /** + * Get the BLIP type + * + * @return int + */ + public function getBlipType() + { + return $this->_blipType; + } - /** - * Set the BLIP type - * - * @param int - */ - public function setBlipType($blipType) - { - $this->_blipType = $blipType; - } + /** + * Set the BLIP type + * + * @param int + */ + public function setBlipType($blipType) + { + $this->_blipType = $blipType; + } } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php index 80e83bc36..4fd743f58 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Escher * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,58 +34,58 @@ */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip { - /** - * The parent BSE - * - * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE - */ - private $_parent; + /** + * The parent BSE + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE + */ + private $_parent; - /** - * Raw image data - * - * @var string - */ - private $_data; + /** + * Raw image data + * + * @var string + */ + private $_data; - /** - * Get the raw image data - * - * @return string - */ - public function getData() - { - return $this->_data; - } + /** + * Get the raw image data + * + * @return string + */ + public function getData() + { + return $this->_data; + } - /** - * Set the raw image data - * - * @param string - */ - public function setData($data) - { - $this->_data = $data; - } + /** + * Set the raw image data + * + * @param string + */ + public function setData($data) + { + $this->_data = $data; + } - /** - * Set parent BSE - * - * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent - */ - public function setParent($parent) - { - $this->_parent = $parent; - } + /** + * Set parent BSE + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } - /** - * Get parent BSE - * - * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent - */ - public function getParent() - { - return $this->_parent; - } + /** + * Get parent BSE + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent + */ + public function getParent() + { + return $this->_parent; + } } diff --git a/Classes/PHPExcel/Shared/Excel5.php b/Classes/PHPExcel/Shared/Excel5.php index 5564c6b7d..115cc3a41 100644 --- a/Classes/PHPExcel/Shared/Excel5.php +++ b/Classes/PHPExcel/Shared/Excel5.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,284 +34,284 @@ */ class PHPExcel_Shared_Excel5 { - /** - * Get the width of a column in pixels. We use the relationship y = ceil(7x) where - * x is the width in intrinsic Excel units (measuring width in number of normal characters) - * This holds for Arial 10 - * - * @param PHPExcel_Worksheet $sheet The sheet - * @param string $col The column - * @return integer The width in pixels - */ - public static function sizeCol($sheet, $col = 'A') - { - // default font of the workbook - $font = $sheet->getParent()->getDefaultStyle()->getFont(); - - $columnDimensions = $sheet->getColumnDimensions(); - - // first find the true column width in pixels (uncollapsed and unhidden) - if ( isset($columnDimensions[$col]) and $columnDimensions[$col]->getWidth() != -1 ) { - - // then we have column dimension with explicit width - $columnDimension = $columnDimensions[$col]; - $width = $columnDimension->getWidth(); - $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); - - } else if ($sheet->getDefaultColumnDimension()->getWidth() != -1) { - - // then we have default column dimension with explicit width - $defaultColumnDimension = $sheet->getDefaultColumnDimension(); - $width = $defaultColumnDimension->getWidth(); - $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); - - } else { - - // we don't even have any default column dimension. Width depends on default font - $pixelWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($font, true); - } - - // now find the effective column width in pixels - if (isset($columnDimensions[$col]) and !$columnDimensions[$col]->getVisible()) { - $effectivePixelWidth = 0; - } else { - $effectivePixelWidth = $pixelWidth; - } - - return $effectivePixelWidth; - } - - /** - * Convert the height of a cell from user's units to pixels. By interpolation - * the relationship is: y = 4/3x. If the height hasn't been set by the user we - * use the default value. If the row is hidden we use a value of zero. - * - * @param PHPExcel_Worksheet $sheet The sheet - * @param integer $row The row index (1-based) - * @return integer The width in pixels - */ - public static function sizeRow($sheet, $row = 1) - { - // default font of the workbook - $font = $sheet->getParent()->getDefaultStyle()->getFont(); - - $rowDimensions = $sheet->getRowDimensions(); - - // first find the true row height in pixels (uncollapsed and unhidden) - if ( isset($rowDimensions[$row]) and $rowDimensions[$row]->getRowHeight() != -1) { - - // then we have a row dimension - $rowDimension = $rowDimensions[$row]; - $rowHeight = $rowDimension->getRowHeight(); - $pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10 - - } else if ($sheet->getDefaultRowDimension()->getRowHeight() != -1) { - - // then we have a default row dimension with explicit height - $defaultRowDimension = $sheet->getDefaultRowDimension(); - $rowHeight = $defaultRowDimension->getRowHeight(); - $pixelRowHeight = PHPExcel_Shared_Drawing::pointsToPixels($rowHeight); - - } else { - - // we don't even have any default row dimension. Height depends on default font - $pointRowHeight = PHPExcel_Shared_Font::getDefaultRowHeightByFont($font); - $pixelRowHeight = PHPExcel_Shared_Font::fontSizeToPixels($pointRowHeight); - - } - - // now find the effective row height in pixels - if ( isset($rowDimensions[$row]) and !$rowDimensions[$row]->getVisible() ) { - $effectivePixelRowHeight = 0; - } else { - $effectivePixelRowHeight = $pixelRowHeight; - } - - return $effectivePixelRowHeight; - } - - /** - * Get the horizontal distance in pixels between two anchors - * The distanceX is found as sum of all the spanning columns widths minus correction for the two offsets - * - * @param PHPExcel_Worksheet $sheet - * @param string $startColumn - * @param integer $startOffsetX Offset within start cell measured in 1/1024 of the cell width - * @param string $endColumn - * @param integer $endOffsetX Offset within end cell measured in 1/1024 of the cell width - * @return integer Horizontal measured in pixels - */ - public static function getDistanceX(PHPExcel_Worksheet $sheet, $startColumn = 'A', $startOffsetX = 0, $endColumn = 'A', $endOffsetX = 0) - { - $distanceX = 0; - - // add the widths of the spanning columns - $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; // 1-based - $endColumnIndex = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; // 1-based - for ($i = $startColumnIndex; $i <= $endColumnIndex; ++$i) { - $distanceX += self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($i)); - } - - // correct for offsetX in startcell - $distanceX -= (int) floor(self::sizeCol($sheet, $startColumn) * $startOffsetX / 1024); - - // correct for offsetX in endcell - $distanceX -= (int) floor(self::sizeCol($sheet, $endColumn) * (1 - $endOffsetX / 1024)); - - return $distanceX; - } - - /** - * Get the vertical distance in pixels between two anchors - * The distanceY is found as sum of all the spanning rows minus two offsets - * - * @param PHPExcel_Worksheet $sheet - * @param integer $startRow (1-based) - * @param integer $startOffsetY Offset within start cell measured in 1/256 of the cell height - * @param integer $endRow (1-based) - * @param integer $endOffsetY Offset within end cell measured in 1/256 of the cell height - * @return integer Vertical distance measured in pixels - */ - public static function getDistanceY(PHPExcel_Worksheet $sheet, $startRow = 1, $startOffsetY = 0, $endRow = 1, $endOffsetY = 0) - { - $distanceY = 0; - - // add the widths of the spanning rows - for ($row = $startRow; $row <= $endRow; ++$row) { - $distanceY += self::sizeRow($sheet, $row); - } - - // correct for offsetX in startcell - $distanceY -= (int) floor(self::sizeRow($sheet, $startRow) * $startOffsetY / 256); - - // correct for offsetX in endcell - $distanceY -= (int) floor(self::sizeRow($sheet, $endRow) * (1 - $endOffsetY / 256)); - - return $distanceY; - } - - /** - * Convert 1-cell anchor coordinates to 2-cell anchor coordinates - * This function is ported from PEAR Spreadsheet_Writer_Excel with small modifications - * - * Calculate the vertices that define the position of the image as required by - * the OBJ record. - * - * +------------+------------+ - * | A | B | - * +-----+------------+------------+ - * | |(x1,y1) | | - * | 1 |(A1)._______|______ | - * | | | | | - * | | | | | - * +-----+----| BITMAP |-----+ - * | | | | | - * | 2 | |______________. | - * | | | (B2)| - * | | | (x2,y2)| - * +---- +------------+------------+ - * - * Example of a bitmap that covers some of the area from cell A1 to cell B2. - * - * Based on the width and height of the bitmap we need to calculate 8 vars: - * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. - * The width and height of the cells are also variable and have to be taken into - * account. - * The values of $col_start and $row_start are passed in from the calling - * function. The values of $col_end and $row_end are calculated by subtracting - * the width and height of the bitmap from the width and height of the - * underlying cells. - * The vertices are expressed as a percentage of the underlying cell width as - * follows (rhs values are in pixels): - * - * x1 = X / W *1024 - * y1 = Y / H *256 - * x2 = (X-1) / W *1024 - * y2 = (Y-1) / H *256 - * - * Where: X is distance from the left side of the underlying cell - * Y is distance from the top of the underlying cell - * W is the width of the cell - * H is the height of the cell - * - * @param PHPExcel_Worksheet $sheet - * @param string $coordinates E.g. 'A1' - * @param integer $offsetX Horizontal offset in pixels - * @param integer $offsetY Vertical offset in pixels - * @param integer $width Width in pixels - * @param integer $height Height in pixels - * @return array - */ - public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height) - { - list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinates); - $col_start = PHPExcel_Cell::columnIndexFromString($column) - 1; - $row_start = $row - 1; - - $x1 = $offsetX; - $y1 = $offsetY; - - // Initialise end cell to the same as the start cell - $col_end = $col_start; // Col containing lower right corner of object - $row_end = $row_start; // Row containing bottom right corner of object - - // Zero the specified offset if greater than the cell dimensions - if ($x1 >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { - $x1 = 0; - } - if ($y1 >= self::sizeRow($sheet, $row_start + 1)) { - $y1 = 0; - } - - $width = $width + $x1 -1; - $height = $height + $y1 -1; - - // Subtract the underlying cell widths to find the end cell of the image - while ($width >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { - $width -= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); - ++$col_end; - } - - // Subtract the underlying cell heights to find the end cell of the image - while ($height >= self::sizeRow($sheet, $row_end + 1)) { - $height -= self::sizeRow($sheet, $row_end + 1); - ++$row_end; - } - - // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell - // with zero height or width. - if (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { - return; - } - if (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { - return; - } - if (self::sizeRow($sheet, $row_start + 1) == 0) { - return; - } - if (self::sizeRow($sheet, $row_end + 1) == 0) { - return; - } - - // Convert the pixel values to the percentage value expected by Excel - $x1 = $x1 / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; - $y1 = $y1 / self::sizeRow($sheet, $row_start + 1) * 256; - $x2 = ($width + 1) / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object - $y2 = ($height + 1) / self::sizeRow($sheet, $row_end + 1) * 256; // Distance to bottom of object - - $startCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_start) . ($row_start + 1); - $endCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_end) . ($row_end + 1); - - $twoAnchor = array( - 'startCoordinates' => $startCoordinates, - 'startOffsetX' => $x1, - 'startOffsetY' => $y1, - 'endCoordinates' => $endCoordinates, - 'endOffsetX' => $x2, - 'endOffsetY' => $y2, - ); - - return $twoAnchor; - } + /** + * Get the width of a column in pixels. We use the relationship y = ceil(7x) where + * x is the width in intrinsic Excel units (measuring width in number of normal characters) + * This holds for Arial 10 + * + * @param PHPExcel_Worksheet $sheet The sheet + * @param string $col The column + * @return integer The width in pixels + */ + public static function sizeCol($sheet, $col = 'A') + { + // default font of the workbook + $font = $sheet->getParent()->getDefaultStyle()->getFont(); + + $columnDimensions = $sheet->getColumnDimensions(); + + // first find the true column width in pixels (uncollapsed and unhidden) + if ( isset($columnDimensions[$col]) and $columnDimensions[$col]->getWidth() != -1 ) { + + // then we have column dimension with explicit width + $columnDimension = $columnDimensions[$col]; + $width = $columnDimension->getWidth(); + $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); + + } else if ($sheet->getDefaultColumnDimension()->getWidth() != -1) { + + // then we have default column dimension with explicit width + $defaultColumnDimension = $sheet->getDefaultColumnDimension(); + $width = $defaultColumnDimension->getWidth(); + $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); + + } else { + + // we don't even have any default column dimension. Width depends on default font + $pixelWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($font, true); + } + + // now find the effective column width in pixels + if (isset($columnDimensions[$col]) and !$columnDimensions[$col]->getVisible()) { + $effectivePixelWidth = 0; + } else { + $effectivePixelWidth = $pixelWidth; + } + + return $effectivePixelWidth; + } + + /** + * Convert the height of a cell from user's units to pixels. By interpolation + * the relationship is: y = 4/3x. If the height hasn't been set by the user we + * use the default value. If the row is hidden we use a value of zero. + * + * @param PHPExcel_Worksheet $sheet The sheet + * @param integer $row The row index (1-based) + * @return integer The width in pixels + */ + public static function sizeRow($sheet, $row = 1) + { + // default font of the workbook + $font = $sheet->getParent()->getDefaultStyle()->getFont(); + + $rowDimensions = $sheet->getRowDimensions(); + + // first find the true row height in pixels (uncollapsed and unhidden) + if ( isset($rowDimensions[$row]) and $rowDimensions[$row]->getRowHeight() != -1) { + + // then we have a row dimension + $rowDimension = $rowDimensions[$row]; + $rowHeight = $rowDimension->getRowHeight(); + $pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10 + + } else if ($sheet->getDefaultRowDimension()->getRowHeight() != -1) { + + // then we have a default row dimension with explicit height + $defaultRowDimension = $sheet->getDefaultRowDimension(); + $rowHeight = $defaultRowDimension->getRowHeight(); + $pixelRowHeight = PHPExcel_Shared_Drawing::pointsToPixels($rowHeight); + + } else { + + // we don't even have any default row dimension. Height depends on default font + $pointRowHeight = PHPExcel_Shared_Font::getDefaultRowHeightByFont($font); + $pixelRowHeight = PHPExcel_Shared_Font::fontSizeToPixels($pointRowHeight); + + } + + // now find the effective row height in pixels + if ( isset($rowDimensions[$row]) and !$rowDimensions[$row]->getVisible() ) { + $effectivePixelRowHeight = 0; + } else { + $effectivePixelRowHeight = $pixelRowHeight; + } + + return $effectivePixelRowHeight; + } + + /** + * Get the horizontal distance in pixels between two anchors + * The distanceX is found as sum of all the spanning columns widths minus correction for the two offsets + * + * @param PHPExcel_Worksheet $sheet + * @param string $startColumn + * @param integer $startOffsetX Offset within start cell measured in 1/1024 of the cell width + * @param string $endColumn + * @param integer $endOffsetX Offset within end cell measured in 1/1024 of the cell width + * @return integer Horizontal measured in pixels + */ + public static function getDistanceX(PHPExcel_Worksheet $sheet, $startColumn = 'A', $startOffsetX = 0, $endColumn = 'A', $endOffsetX = 0) + { + $distanceX = 0; + + // add the widths of the spanning columns + $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; // 1-based + $endColumnIndex = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; // 1-based + for ($i = $startColumnIndex; $i <= $endColumnIndex; ++$i) { + $distanceX += self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($i)); + } + + // correct for offsetX in startcell + $distanceX -= (int) floor(self::sizeCol($sheet, $startColumn) * $startOffsetX / 1024); + + // correct for offsetX in endcell + $distanceX -= (int) floor(self::sizeCol($sheet, $endColumn) * (1 - $endOffsetX / 1024)); + + return $distanceX; + } + + /** + * Get the vertical distance in pixels between two anchors + * The distanceY is found as sum of all the spanning rows minus two offsets + * + * @param PHPExcel_Worksheet $sheet + * @param integer $startRow (1-based) + * @param integer $startOffsetY Offset within start cell measured in 1/256 of the cell height + * @param integer $endRow (1-based) + * @param integer $endOffsetY Offset within end cell measured in 1/256 of the cell height + * @return integer Vertical distance measured in pixels + */ + public static function getDistanceY(PHPExcel_Worksheet $sheet, $startRow = 1, $startOffsetY = 0, $endRow = 1, $endOffsetY = 0) + { + $distanceY = 0; + + // add the widths of the spanning rows + for ($row = $startRow; $row <= $endRow; ++$row) { + $distanceY += self::sizeRow($sheet, $row); + } + + // correct for offsetX in startcell + $distanceY -= (int) floor(self::sizeRow($sheet, $startRow) * $startOffsetY / 256); + + // correct for offsetX in endcell + $distanceY -= (int) floor(self::sizeRow($sheet, $endRow) * (1 - $endOffsetY / 256)); + + return $distanceY; + } + + /** + * Convert 1-cell anchor coordinates to 2-cell anchor coordinates + * This function is ported from PEAR Spreadsheet_Writer_Excel with small modifications + * + * Calculate the vertices that define the position of the image as required by + * the OBJ record. + * + * +------------+------------+ + * | A | B | + * +-----+------------+------------+ + * | |(x1,y1) | | + * | 1 |(A1)._______|______ | + * | | | | | + * | | | | | + * +-----+----| BITMAP |-----+ + * | | | | | + * | 2 | |______________. | + * | | | (B2)| + * | | | (x2,y2)| + * +---- +------------+------------+ + * + * Example of a bitmap that covers some of the area from cell A1 to cell B2. + * + * Based on the width and height of the bitmap we need to calculate 8 vars: + * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. + * The width and height of the cells are also variable and have to be taken into + * account. + * The values of $col_start and $row_start are passed in from the calling + * function. The values of $col_end and $row_end are calculated by subtracting + * the width and height of the bitmap from the width and height of the + * underlying cells. + * The vertices are expressed as a percentage of the underlying cell width as + * follows (rhs values are in pixels): + * + * x1 = X / W *1024 + * y1 = Y / H *256 + * x2 = (X-1) / W *1024 + * y2 = (Y-1) / H *256 + * + * Where: X is distance from the left side of the underlying cell + * Y is distance from the top of the underlying cell + * W is the width of the cell + * H is the height of the cell + * + * @param PHPExcel_Worksheet $sheet + * @param string $coordinates E.g. 'A1' + * @param integer $offsetX Horizontal offset in pixels + * @param integer $offsetY Vertical offset in pixels + * @param integer $width Width in pixels + * @param integer $height Height in pixels + * @return array + */ + public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height) + { + list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinates); + $col_start = PHPExcel_Cell::columnIndexFromString($column) - 1; + $row_start = $row - 1; + + $x1 = $offsetX; + $y1 = $offsetY; + + // Initialise end cell to the same as the start cell + $col_end = $col_start; // Col containing lower right corner of object + $row_end = $row_start; // Row containing bottom right corner of object + + // Zero the specified offset if greater than the cell dimensions + if ($x1 >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { + $x1 = 0; + } + if ($y1 >= self::sizeRow($sheet, $row_start + 1)) { + $y1 = 0; + } + + $width = $width + $x1 -1; + $height = $height + $y1 -1; + + // Subtract the underlying cell widths to find the end cell of the image + while ($width >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { + $width -= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); + ++$col_end; + } + + // Subtract the underlying cell heights to find the end cell of the image + while ($height >= self::sizeRow($sheet, $row_end + 1)) { + $height -= self::sizeRow($sheet, $row_end + 1); + ++$row_end; + } + + // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell + // with zero height or width. + if (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { + return; + } + if (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { + return; + } + if (self::sizeRow($sheet, $row_start + 1) == 0) { + return; + } + if (self::sizeRow($sheet, $row_end + 1) == 0) { + return; + } + + // Convert the pixel values to the percentage value expected by Excel + $x1 = $x1 / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; + $y1 = $y1 / self::sizeRow($sheet, $row_start + 1) * 256; + $x2 = ($width + 1) / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object + $y2 = ($height + 1) / self::sizeRow($sheet, $row_end + 1) * 256; // Distance to bottom of object + + $startCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_start) . ($row_start + 1); + $endCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_end) . ($row_end + 1); + + $twoAnchor = array( + 'startCoordinates' => $startCoordinates, + 'startOffsetX' => $x1, + 'startOffsetY' => $y1, + 'endCoordinates' => $endCoordinates, + 'endOffsetX' => $x2, + 'endOffsetY' => $y2, + ); + + return $twoAnchor; + } } diff --git a/Classes/PHPExcel/Shared/File.php b/Classes/PHPExcel/Shared/File.php index 8dfb66e2f..8c3012d3c 100644 --- a/Classes/PHPExcel/Shared/File.php +++ b/Classes/PHPExcel/Shared/File.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,144 +35,144 @@ */ class PHPExcel_Shared_File { - /* - * Use Temp or File Upload Temp for temporary files - * - * @protected - * @var boolean - */ - protected static $_useUploadTempDirectory = FALSE; - - - /** - * Set the flag indicating whether the File Upload Temp directory should be used for temporary files - * - * @param boolean $useUploadTempDir Use File Upload Temporary directory (true or false) - */ - public static function setUseUploadTempDirectory($useUploadTempDir = FALSE) { - self::$_useUploadTempDirectory = (boolean) $useUploadTempDir; - } // function setUseUploadTempDirectory() - - - /** - * Get the flag indicating whether the File Upload Temp directory should be used for temporary files - * - * @return boolean Use File Upload Temporary directory (true or false) - */ - public static function getUseUploadTempDirectory() { - return self::$_useUploadTempDirectory; - } // function getUseUploadTempDirectory() - - - /** - * Verify if a file exists - * - * @param string $pFilename Filename - * @return bool - */ - public static function file_exists($pFilename) { - // Sick construction, but it seems that - // file_exists returns strange values when - // doing the original file_exists on ZIP archives... - if ( strtolower(substr($pFilename, 0, 3)) == 'zip' ) { - // Open ZIP file and verify if the file exists - $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); - $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1); - - $zip = new ZipArchive(); - if ($zip->open($zipFile) === true) { - $returnValue = ($zip->getFromName($archiveFile) !== false); - $zip->close(); - return $returnValue; - } else { - return false; - } - } else { - // Regular file_exists - return file_exists($pFilename); - } - } - - /** - * Returns canonicalized absolute pathname, also for ZIP archives - * - * @param string $pFilename - * @return string - */ - public static function realpath($pFilename) { - // Returnvalue - $returnValue = ''; - - // Try using realpath() - if (file_exists($pFilename)) { - $returnValue = realpath($pFilename); - } - - // Found something? - if ($returnValue == '' || ($returnValue === NULL)) { - $pathArray = explode('/' , $pFilename); - while(in_array('..', $pathArray) && $pathArray[0] != '..') { - for ($i = 0; $i < count($pathArray); ++$i) { - if ($pathArray[$i] == '..' && $i > 0) { - unset($pathArray[$i]); - unset($pathArray[$i - 1]); - break; - } - } - } - $returnValue = implode('/', $pathArray); - } - - // Return - return $returnValue; - } - - /** - * Get the systems temporary directory. - * - * @return string - */ - public static function sys_get_temp_dir() - { - if (self::$_useUploadTempDirectory) { - // use upload-directory when defined to allow running on environments having very restricted - // open_basedir configs - if (ini_get('upload_tmp_dir') !== FALSE) { - if ($temp = ini_get('upload_tmp_dir')) { - if (file_exists($temp)) - return realpath($temp); - } - } - } - - // sys_get_temp_dir is only available since PHP 5.2.1 - // http://php.net/manual/en/function.sys-get-temp-dir.php#94119 - if ( !function_exists('sys_get_temp_dir')) { - if ($temp = getenv('TMP') ) { - if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } - } - if ($temp = getenv('TEMP') ) { - if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } - } - if ($temp = getenv('TMPDIR') ) { - if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } - } - - // trick for creating a file in system's temporary dir - // without knowing the path of the system's temporary dir - $temp = tempnam(__FILE__, ''); - if (file_exists($temp)) { - unlink($temp); - return realpath(dirname($temp)); - } - - return null; - } - - // use ordinary built-in PHP function - // There should be no problem with the 5.2.4 Suhosin realpath() bug, because this line should only - // be called if we're running 5.2.1 or earlier - return realpath(sys_get_temp_dir()); - } + /* + * Use Temp or File Upload Temp for temporary files + * + * @protected + * @var boolean + */ + protected static $_useUploadTempDirectory = FALSE; + + + /** + * Set the flag indicating whether the File Upload Temp directory should be used for temporary files + * + * @param boolean $useUploadTempDir Use File Upload Temporary directory (true or false) + */ + public static function setUseUploadTempDirectory($useUploadTempDir = FALSE) { + self::$_useUploadTempDirectory = (boolean) $useUploadTempDir; + } // function setUseUploadTempDirectory() + + + /** + * Get the flag indicating whether the File Upload Temp directory should be used for temporary files + * + * @return boolean Use File Upload Temporary directory (true or false) + */ + public static function getUseUploadTempDirectory() { + return self::$_useUploadTempDirectory; + } // function getUseUploadTempDirectory() + + + /** + * Verify if a file exists + * + * @param string $pFilename Filename + * @return bool + */ + public static function file_exists($pFilename) { + // Sick construction, but it seems that + // file_exists returns strange values when + // doing the original file_exists on ZIP archives... + if ( strtolower(substr($pFilename, 0, 3)) == 'zip' ) { + // Open ZIP file and verify if the file exists + $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); + $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1); + + $zip = new ZipArchive(); + if ($zip->open($zipFile) === true) { + $returnValue = ($zip->getFromName($archiveFile) !== false); + $zip->close(); + return $returnValue; + } else { + return false; + } + } else { + // Regular file_exists + return file_exists($pFilename); + } + } + + /** + * Returns canonicalized absolute pathname, also for ZIP archives + * + * @param string $pFilename + * @return string + */ + public static function realpath($pFilename) { + // Returnvalue + $returnValue = ''; + + // Try using realpath() + if (file_exists($pFilename)) { + $returnValue = realpath($pFilename); + } + + // Found something? + if ($returnValue == '' || ($returnValue === NULL)) { + $pathArray = explode('/' , $pFilename); + while(in_array('..', $pathArray) && $pathArray[0] != '..') { + for ($i = 0; $i < count($pathArray); ++$i) { + if ($pathArray[$i] == '..' && $i > 0) { + unset($pathArray[$i]); + unset($pathArray[$i - 1]); + break; + } + } + } + $returnValue = implode('/', $pathArray); + } + + // Return + return $returnValue; + } + + /** + * Get the systems temporary directory. + * + * @return string + */ + public static function sys_get_temp_dir() + { + if (self::$_useUploadTempDirectory) { + // use upload-directory when defined to allow running on environments having very restricted + // open_basedir configs + if (ini_get('upload_tmp_dir') !== FALSE) { + if ($temp = ini_get('upload_tmp_dir')) { + if (file_exists($temp)) + return realpath($temp); + } + } + } + + // sys_get_temp_dir is only available since PHP 5.2.1 + // http://php.net/manual/en/function.sys-get-temp-dir.php#94119 + if ( !function_exists('sys_get_temp_dir')) { + if ($temp = getenv('TMP') ) { + if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + } + if ($temp = getenv('TEMP') ) { + if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + } + if ($temp = getenv('TMPDIR') ) { + if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + } + + // trick for creating a file in system's temporary dir + // without knowing the path of the system's temporary dir + $temp = tempnam(__FILE__, ''); + if (file_exists($temp)) { + unlink($temp); + return realpath(dirname($temp)); + } + + return null; + } + + // use ordinary built-in PHP function + // There should be no problem with the 5.2.4 Suhosin realpath() bug, because this line should only + // be called if we're running 5.2.1 or earlier + return realpath(sys_get_temp_dir()); + } } diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php index a59aa504a..43451cb9f 100644 --- a/Classes/PHPExcel/Shared/Font.php +++ b/Classes/PHPExcel/Shared/Font.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,237 +35,237 @@ */ class PHPExcel_Shared_Font { - /* Methods for resolving autosize value */ - const AUTOSIZE_METHOD_APPROX = 'approx'; - const AUTOSIZE_METHOD_EXACT = 'exact'; - - private static $_autoSizeMethods = array( - self::AUTOSIZE_METHOD_APPROX, - self::AUTOSIZE_METHOD_EXACT, - ); - - /** Character set codes used by BIFF5-8 in Font records */ - const CHARSET_ANSI_LATIN = 0x00; - const CHARSET_SYSTEM_DEFAULT = 0x01; - const CHARSET_SYMBOL = 0x02; - const CHARSET_APPLE_ROMAN = 0x4D; - const CHARSET_ANSI_JAPANESE_SHIFTJIS = 0x80; - const CHARSET_ANSI_KOREAN_HANGUL = 0x81; - const CHARSET_ANSI_KOREAN_JOHAB = 0x82; - const CHARSET_ANSI_CHINESE_SIMIPLIFIED = 0x86; // gb2312 - const CHARSET_ANSI_CHINESE_TRADITIONAL = 0x88; // big5 - const CHARSET_ANSI_GREEK = 0xA1; - const CHARSET_ANSI_TURKISH = 0xA2; - const CHARSET_ANSI_VIETNAMESE = 0xA3; - const CHARSET_ANSI_HEBREW = 0xB1; - const CHARSET_ANSI_ARABIC = 0xB2; - const CHARSET_ANSI_BALTIC = 0xBA; - const CHARSET_ANSI_CYRILLIC = 0xCC; - const CHARSET_ANSI_THAI = 0xDD; - const CHARSET_ANSI_LATIN_II = 0xEE; - const CHARSET_OEM_LATIN_I = 0xFF; - - // XXX: Constants created! - /** Font filenames */ - const ARIAL = 'arial.ttf'; - const ARIAL_BOLD = 'arialbd.ttf'; - const ARIAL_ITALIC = 'ariali.ttf'; - const ARIAL_BOLD_ITALIC = 'arialbi.ttf'; - - const CALIBRI = 'CALIBRI.TTF'; - const CALIBRI_BOLD = 'CALIBRIB.TTF'; - const CALIBRI_ITALIC = 'CALIBRII.TTF'; - const CALIBRI_BOLD_ITALIC = 'CALIBRIZ.TTF'; - - const COMIC_SANS_MS = 'comic.ttf'; - const COMIC_SANS_MS_BOLD = 'comicbd.ttf'; - - const COURIER_NEW = 'cour.ttf'; - const COURIER_NEW_BOLD = 'courbd.ttf'; - const COURIER_NEW_ITALIC = 'couri.ttf'; - const COURIER_NEW_BOLD_ITALIC = 'courbi.ttf'; - - const GEORGIA = 'georgia.ttf'; - const GEORGIA_BOLD = 'georgiab.ttf'; - const GEORGIA_ITALIC = 'georgiai.ttf'; - const GEORGIA_BOLD_ITALIC = 'georgiaz.ttf'; - - const IMPACT = 'impact.ttf'; - - const LIBERATION_SANS = 'LiberationSans-Regular.ttf'; - const LIBERATION_SANS_BOLD = 'LiberationSans-Bold.ttf'; - const LIBERATION_SANS_ITALIC = 'LiberationSans-Italic.ttf'; - const LIBERATION_SANS_BOLD_ITALIC = 'LiberationSans-BoldItalic.ttf'; - - const LUCIDA_CONSOLE = 'lucon.ttf'; - const LUCIDA_SANS_UNICODE = 'l_10646.ttf'; - - const MICROSOFT_SANS_SERIF = 'micross.ttf'; - - const PALATINO_LINOTYPE = 'pala.ttf'; - const PALATINO_LINOTYPE_BOLD = 'palab.ttf'; - const PALATINO_LINOTYPE_ITALIC = 'palai.ttf'; - const PALATINO_LINOTYPE_BOLD_ITALIC = 'palabi.ttf'; - - const SYMBOL = 'symbol.ttf'; - - const TAHOMA = 'tahoma.ttf'; - const TAHOMA_BOLD = 'tahomabd.ttf'; - - const TIMES_NEW_ROMAN = 'times.ttf'; - const TIMES_NEW_ROMAN_BOLD = 'timesbd.ttf'; - const TIMES_NEW_ROMAN_ITALIC = 'timesi.ttf'; - const TIMES_NEW_ROMAN_BOLD_ITALIC = 'timesbi.ttf'; - - const TREBUCHET_MS = 'trebuc.ttf'; - const TREBUCHET_MS_BOLD = 'trebucbd.ttf'; - const TREBUCHET_MS_ITALIC = 'trebucit.ttf'; - const TREBUCHET_MS_BOLD_ITALIC = 'trebucbi.ttf'; - - const VERDANA = 'verdana.ttf'; - const VERDANA_BOLD = 'verdanab.ttf'; - const VERDANA_ITALIC = 'verdanai.ttf'; - const VERDANA_BOLD_ITALIC = 'verdanaz.ttf'; - - /** - * AutoSize method - * - * @var string - */ - private static $autoSizeMethod = self::AUTOSIZE_METHOD_APPROX; - - /** - * Path to folder containing TrueType font .ttf files - * - * @var string - */ - private static $trueTypeFontPath = null; - - /** - * How wide is a default column for a given default font and size? - * Empirical data found by inspecting real Excel files and reading off the pixel width - * in Microsoft Office Excel 2007. - * - * @var array - */ - public static $defaultColumnWidths = array( - 'Arial' => array( - 1 => array('px' => 24, 'width' => 12.00000000), - 2 => array('px' => 24, 'width' => 12.00000000), - 3 => array('px' => 32, 'width' => 10.66406250), - 4 => array('px' => 32, 'width' => 10.66406250), - 5 => array('px' => 40, 'width' => 10.00000000), - 6 => array('px' => 48, 'width' => 9.59765625), - 7 => array('px' => 48, 'width' => 9.59765625), - 8 => array('px' => 56, 'width' => 9.33203125), - 9 => array('px' => 64, 'width' => 9.14062500), - 10 => array('px' => 64, 'width' => 9.14062500), - ), - 'Calibri' => array( - 1 => array('px' => 24, 'width' => 12.00000000), - 2 => array('px' => 24, 'width' => 12.00000000), - 3 => array('px' => 32, 'width' => 10.66406250), - 4 => array('px' => 32, 'width' => 10.66406250), - 5 => array('px' => 40, 'width' => 10.00000000), - 6 => array('px' => 48, 'width' => 9.59765625), - 7 => array('px' => 48, 'width' => 9.59765625), - 8 => array('px' => 56, 'width' => 9.33203125), - 9 => array('px' => 56, 'width' => 9.33203125), - 10 => array('px' => 64, 'width' => 9.14062500), - 11 => array('px' => 64, 'width' => 9.14062500), - ), - 'Verdana' => array( - 1 => array('px' => 24, 'width' => 12.00000000), - 2 => array('px' => 24, 'width' => 12.00000000), - 3 => array('px' => 32, 'width' => 10.66406250), - 4 => array('px' => 32, 'width' => 10.66406250), - 5 => array('px' => 40, 'width' => 10.00000000), - 6 => array('px' => 48, 'width' => 9.59765625), - 7 => array('px' => 48, 'width' => 9.59765625), - 8 => array('px' => 64, 'width' => 9.14062500), - 9 => array('px' => 72, 'width' => 9.00000000), - 10 => array('px' => 72, 'width' => 9.00000000), - ), - ); - - /** - * Set autoSize method - * - * @param string $pValue - * @return boolean Success or failure - */ - public static function setAutoSizeMethod($pValue = self::AUTOSIZE_METHOD_APPROX) - { - if (!in_array($pValue,self::$_autoSizeMethods)) { - return FALSE; - } - self::$autoSizeMethod = $pValue; - - return TRUE; - } - - /** - * Get autoSize method - * - * @return string - */ - public static function getAutoSizeMethod() - { - return self::$autoSizeMethod; - } - - /** - * Set the path to the folder containing .ttf files. There should be a trailing slash. - * Typical locations on variout some platforms: - * <ul> - * <li>C:/Windows/Fonts/</li> - * <li>/usr/share/fonts/truetype/</li> - * <li>~/.fonts/</li> - * </ul> - * - * @param string $pValue - */ - public static function setTrueTypeFontPath($pValue = '') - { - self::$trueTypeFontPath = $pValue; - } - - /** - * Get the path to the folder containing .ttf files. - * - * @return string - */ - public static function getTrueTypeFontPath() - { - return self::$trueTypeFontPath; - } + /* Methods for resolving autosize value */ + const AUTOSIZE_METHOD_APPROX = 'approx'; + const AUTOSIZE_METHOD_EXACT = 'exact'; + + private static $_autoSizeMethods = array( + self::AUTOSIZE_METHOD_APPROX, + self::AUTOSIZE_METHOD_EXACT, + ); + + /** Character set codes used by BIFF5-8 in Font records */ + const CHARSET_ANSI_LATIN = 0x00; + const CHARSET_SYSTEM_DEFAULT = 0x01; + const CHARSET_SYMBOL = 0x02; + const CHARSET_APPLE_ROMAN = 0x4D; + const CHARSET_ANSI_JAPANESE_SHIFTJIS = 0x80; + const CHARSET_ANSI_KOREAN_HANGUL = 0x81; + const CHARSET_ANSI_KOREAN_JOHAB = 0x82; + const CHARSET_ANSI_CHINESE_SIMIPLIFIED = 0x86; // gb2312 + const CHARSET_ANSI_CHINESE_TRADITIONAL = 0x88; // big5 + const CHARSET_ANSI_GREEK = 0xA1; + const CHARSET_ANSI_TURKISH = 0xA2; + const CHARSET_ANSI_VIETNAMESE = 0xA3; + const CHARSET_ANSI_HEBREW = 0xB1; + const CHARSET_ANSI_ARABIC = 0xB2; + const CHARSET_ANSI_BALTIC = 0xBA; + const CHARSET_ANSI_CYRILLIC = 0xCC; + const CHARSET_ANSI_THAI = 0xDD; + const CHARSET_ANSI_LATIN_II = 0xEE; + const CHARSET_OEM_LATIN_I = 0xFF; + + // XXX: Constants created! + /** Font filenames */ + const ARIAL = 'arial.ttf'; + const ARIAL_BOLD = 'arialbd.ttf'; + const ARIAL_ITALIC = 'ariali.ttf'; + const ARIAL_BOLD_ITALIC = 'arialbi.ttf'; + + const CALIBRI = 'CALIBRI.TTF'; + const CALIBRI_BOLD = 'CALIBRIB.TTF'; + const CALIBRI_ITALIC = 'CALIBRII.TTF'; + const CALIBRI_BOLD_ITALIC = 'CALIBRIZ.TTF'; + + const COMIC_SANS_MS = 'comic.ttf'; + const COMIC_SANS_MS_BOLD = 'comicbd.ttf'; + + const COURIER_NEW = 'cour.ttf'; + const COURIER_NEW_BOLD = 'courbd.ttf'; + const COURIER_NEW_ITALIC = 'couri.ttf'; + const COURIER_NEW_BOLD_ITALIC = 'courbi.ttf'; + + const GEORGIA = 'georgia.ttf'; + const GEORGIA_BOLD = 'georgiab.ttf'; + const GEORGIA_ITALIC = 'georgiai.ttf'; + const GEORGIA_BOLD_ITALIC = 'georgiaz.ttf'; + + const IMPACT = 'impact.ttf'; + + const LIBERATION_SANS = 'LiberationSans-Regular.ttf'; + const LIBERATION_SANS_BOLD = 'LiberationSans-Bold.ttf'; + const LIBERATION_SANS_ITALIC = 'LiberationSans-Italic.ttf'; + const LIBERATION_SANS_BOLD_ITALIC = 'LiberationSans-BoldItalic.ttf'; + + const LUCIDA_CONSOLE = 'lucon.ttf'; + const LUCIDA_SANS_UNICODE = 'l_10646.ttf'; + + const MICROSOFT_SANS_SERIF = 'micross.ttf'; + + const PALATINO_LINOTYPE = 'pala.ttf'; + const PALATINO_LINOTYPE_BOLD = 'palab.ttf'; + const PALATINO_LINOTYPE_ITALIC = 'palai.ttf'; + const PALATINO_LINOTYPE_BOLD_ITALIC = 'palabi.ttf'; + + const SYMBOL = 'symbol.ttf'; + + const TAHOMA = 'tahoma.ttf'; + const TAHOMA_BOLD = 'tahomabd.ttf'; + + const TIMES_NEW_ROMAN = 'times.ttf'; + const TIMES_NEW_ROMAN_BOLD = 'timesbd.ttf'; + const TIMES_NEW_ROMAN_ITALIC = 'timesi.ttf'; + const TIMES_NEW_ROMAN_BOLD_ITALIC = 'timesbi.ttf'; + + const TREBUCHET_MS = 'trebuc.ttf'; + const TREBUCHET_MS_BOLD = 'trebucbd.ttf'; + const TREBUCHET_MS_ITALIC = 'trebucit.ttf'; + const TREBUCHET_MS_BOLD_ITALIC = 'trebucbi.ttf'; + + const VERDANA = 'verdana.ttf'; + const VERDANA_BOLD = 'verdanab.ttf'; + const VERDANA_ITALIC = 'verdanai.ttf'; + const VERDANA_BOLD_ITALIC = 'verdanaz.ttf'; /** - * Calculate an (approximate) OpenXML column width, based on font size and text contained - * - * @param PHPExcel_Style_Font $font Font object - * @param PHPExcel_RichText|string $cellText Text to calculate width - * @param integer $rotation Rotation angle - * @param PHPExcel_Style_Font|NULL $defaultFont Font object - * @return integer Column width - */ - public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText = '', $rotation = 0, PHPExcel_Style_Font $defaultFont = null) { - // If it is rich text, use plain text - if ($cellText instanceof PHPExcel_RichText) { - $cellText = $cellText->getPlainText(); - } - - // Special case if there are one or more newline characters ("\n") - if (strpos($cellText, "\n") !== false) { - $lineTexts = explode("\n", $cellText); - $lineWidths = array(); - foreach ($lineTexts as $lineText) { - $lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont); - } - return max($lineWidths); // width of longest line in cell - } - - // Try to get the exact text width in pixels + * AutoSize method + * + * @var string + */ + private static $autoSizeMethod = self::AUTOSIZE_METHOD_APPROX; + + /** + * Path to folder containing TrueType font .ttf files + * + * @var string + */ + private static $trueTypeFontPath = null; + + /** + * How wide is a default column for a given default font and size? + * Empirical data found by inspecting real Excel files and reading off the pixel width + * in Microsoft Office Excel 2007. + * + * @var array + */ + public static $defaultColumnWidths = array( + 'Arial' => array( + 1 => array('px' => 24, 'width' => 12.00000000), + 2 => array('px' => 24, 'width' => 12.00000000), + 3 => array('px' => 32, 'width' => 10.66406250), + 4 => array('px' => 32, 'width' => 10.66406250), + 5 => array('px' => 40, 'width' => 10.00000000), + 6 => array('px' => 48, 'width' => 9.59765625), + 7 => array('px' => 48, 'width' => 9.59765625), + 8 => array('px' => 56, 'width' => 9.33203125), + 9 => array('px' => 64, 'width' => 9.14062500), + 10 => array('px' => 64, 'width' => 9.14062500), + ), + 'Calibri' => array( + 1 => array('px' => 24, 'width' => 12.00000000), + 2 => array('px' => 24, 'width' => 12.00000000), + 3 => array('px' => 32, 'width' => 10.66406250), + 4 => array('px' => 32, 'width' => 10.66406250), + 5 => array('px' => 40, 'width' => 10.00000000), + 6 => array('px' => 48, 'width' => 9.59765625), + 7 => array('px' => 48, 'width' => 9.59765625), + 8 => array('px' => 56, 'width' => 9.33203125), + 9 => array('px' => 56, 'width' => 9.33203125), + 10 => array('px' => 64, 'width' => 9.14062500), + 11 => array('px' => 64, 'width' => 9.14062500), + ), + 'Verdana' => array( + 1 => array('px' => 24, 'width' => 12.00000000), + 2 => array('px' => 24, 'width' => 12.00000000), + 3 => array('px' => 32, 'width' => 10.66406250), + 4 => array('px' => 32, 'width' => 10.66406250), + 5 => array('px' => 40, 'width' => 10.00000000), + 6 => array('px' => 48, 'width' => 9.59765625), + 7 => array('px' => 48, 'width' => 9.59765625), + 8 => array('px' => 64, 'width' => 9.14062500), + 9 => array('px' => 72, 'width' => 9.00000000), + 10 => array('px' => 72, 'width' => 9.00000000), + ), + ); + + /** + * Set autoSize method + * + * @param string $pValue + * @return boolean Success or failure + */ + public static function setAutoSizeMethod($pValue = self::AUTOSIZE_METHOD_APPROX) + { + if (!in_array($pValue,self::$_autoSizeMethods)) { + return FALSE; + } + self::$autoSizeMethod = $pValue; + + return TRUE; + } + + /** + * Get autoSize method + * + * @return string + */ + public static function getAutoSizeMethod() + { + return self::$autoSizeMethod; + } + + /** + * Set the path to the folder containing .ttf files. There should be a trailing slash. + * Typical locations on variout some platforms: + * <ul> + * <li>C:/Windows/Fonts/</li> + * <li>/usr/share/fonts/truetype/</li> + * <li>~/.fonts/</li> + * </ul> + * + * @param string $pValue + */ + public static function setTrueTypeFontPath($pValue = '') + { + self::$trueTypeFontPath = $pValue; + } + + /** + * Get the path to the folder containing .ttf files. + * + * @return string + */ + public static function getTrueTypeFontPath() + { + return self::$trueTypeFontPath; + } + + /** + * Calculate an (approximate) OpenXML column width, based on font size and text contained + * + * @param PHPExcel_Style_Font $font Font object + * @param PHPExcel_RichText|string $cellText Text to calculate width + * @param integer $rotation Rotation angle + * @param PHPExcel_Style_Font|NULL $defaultFont Font object + * @return integer Column width + */ + public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText = '', $rotation = 0, PHPExcel_Style_Font $defaultFont = null) { + // If it is rich text, use plain text + if ($cellText instanceof PHPExcel_RichText) { + $cellText = $cellText->getPlainText(); + } + + // Special case if there are one or more newline characters ("\n") + if (strpos($cellText, "\n") !== false) { + $lineTexts = explode("\n", $cellText); + $lineWidths = array(); + foreach ($lineTexts as $lineText) { + $lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont); + } + return max($lineWidths); // width of longest line in cell + } + + // Try to get the exact text width in pixels $approximate = self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX; if (!$approximate) { $columnWidthAdjust = ceil(self::getTextWidthPixelsExact('n', $font, 0) * 1.07); @@ -280,494 +280,494 @@ public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText if ($approximate) { $columnWidthAdjust = self::getTextWidthPixelsApprox('n', $font, 0); - // Width of text in pixels excl. padding, approximation - // and addition because Excel adds some padding, just use approx width of 'n' glyph - $columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation) + $columnWidthAdjust; + // Width of text in pixels excl. padding, approximation + // and addition because Excel adds some padding, just use approx width of 'n' glyph + $columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation) + $columnWidthAdjust; } - // Convert from pixel width to column width - $columnWidth = PHPExcel_Shared_Drawing::pixelsToCellDimension($columnWidth, $defaultFont); - - // Return - return round($columnWidth, 6); - } - - /** - * Get GD text width in pixels for a string of text in a certain font at a certain rotation angle - * - * @param string $text - * @param PHPExcel_Style_Font - * @param int $rotation - * @return int - * @throws PHPExcel_Exception - */ - public static function getTextWidthPixelsExact($text, PHPExcel_Style_Font $font, $rotation = 0) { - if (!function_exists('imagettfbbox')) { - throw new PHPExcel_Exception('GD library needs to be enabled'); - } - - // font size should really be supplied in pixels in GD2, - // but since GD2 seems to assume 72dpi, pixels and points are the same - $fontFile = self::getTrueTypeFontFileFromFont($font); - $textBox = imagettfbbox($font->getSize(), $rotation, $fontFile, $text); - - // Get corners positions - $lowerLeftCornerX = $textBox[0]; -// $lowerLeftCornerY = $textBox[1]; - $lowerRightCornerX = $textBox[2]; -// $lowerRightCornerY = $textBox[3]; - $upperRightCornerX = $textBox[4]; -// $upperRightCornerY = $textBox[5]; - $upperLeftCornerX = $textBox[6]; -// $upperLeftCornerY = $textBox[7]; - - // Consider the rotation when calculating the width - $textWidth = max($lowerRightCornerX - $upperLeftCornerX, $upperRightCornerX - $lowerLeftCornerX); - - return $textWidth; - } - - /** - * Get approximate width in pixels for a string of text in a certain font at a certain rotation angle - * - * @param string $columnText - * @param PHPExcel_Style_Font $font - * @param int $rotation - * @return int Text width in pixels (no padding added) - */ - public static function getTextWidthPixelsApprox($columnText, PHPExcel_Style_Font $font = null, $rotation = 0) - { - $fontName = $font->getName(); - $fontSize = $font->getSize(); - - // Calculate column width in pixels. We assume fixed glyph width. Result varies with font name and size. - switch ($fontName) { - case 'Calibri': - // value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font. - $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); - $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size - break; - - case 'Arial': - // value 7 was found via interpolation by inspecting real Excel files with Arial 10 font. -// $columnWidth = (int) (7 * PHPExcel_Shared_String::CountCharacters($columnText)); + // Convert from pixel width to column width + $columnWidth = PHPExcel_Shared_Drawing::pixelsToCellDimension($columnWidth, $defaultFont); + + // Return + return round($columnWidth, 6); + } + + /** + * Get GD text width in pixels for a string of text in a certain font at a certain rotation angle + * + * @param string $text + * @param PHPExcel_Style_Font + * @param int $rotation + * @return int + * @throws PHPExcel_Exception + */ + public static function getTextWidthPixelsExact($text, PHPExcel_Style_Font $font, $rotation = 0) { + if (!function_exists('imagettfbbox')) { + throw new PHPExcel_Exception('GD library needs to be enabled'); + } + + // font size should really be supplied in pixels in GD2, + // but since GD2 seems to assume 72dpi, pixels and points are the same + $fontFile = self::getTrueTypeFontFileFromFont($font); + $textBox = imagettfbbox($font->getSize(), $rotation, $fontFile, $text); + + // Get corners positions + $lowerLeftCornerX = $textBox[0]; +// $lowerLeftCornerY = $textBox[1]; + $lowerRightCornerX = $textBox[2]; +// $lowerRightCornerY = $textBox[3]; + $upperRightCornerX = $textBox[4]; +// $upperRightCornerY = $textBox[5]; + $upperLeftCornerX = $textBox[6]; +// $upperLeftCornerY = $textBox[7]; + + // Consider the rotation when calculating the width + $textWidth = max($lowerRightCornerX - $upperLeftCornerX, $upperRightCornerX - $lowerLeftCornerX); + + return $textWidth; + } + + /** + * Get approximate width in pixels for a string of text in a certain font at a certain rotation angle + * + * @param string $columnText + * @param PHPExcel_Style_Font $font + * @param int $rotation + * @return int Text width in pixels (no padding added) + */ + public static function getTextWidthPixelsApprox($columnText, PHPExcel_Style_Font $font = null, $rotation = 0) + { + $fontName = $font->getName(); + $fontSize = $font->getSize(); + + // Calculate column width in pixels. We assume fixed glyph width. Result varies with font name and size. + switch ($fontName) { + case 'Calibri': + // value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font. + $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size + break; + + case 'Arial': + // value 7 was found via interpolation by inspecting real Excel files with Arial 10 font. +// $columnWidth = (int) (7 * PHPExcel_Shared_String::CountCharacters($columnText)); // value 8 was set because of experience in different exports at Arial 10 font. - $columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText)); - $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size + $columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size + break; + + case 'Verdana': + // value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font. + $columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size + break; + + default: + // just assume Calibri + $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size + break; + } + + // Calculate approximate rotated column width + if ($rotation !== 0) { + if ($rotation == -165) { + // stacked text + $columnWidth = 4; // approximation + } else { + // rotated text + $columnWidth = $columnWidth * cos(deg2rad($rotation)) + + $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation + } + } + + // pixel width is an integer + return (int) $columnWidth; + } + + /** + * Calculate an (approximate) pixel size, based on a font points size + * + * @param int $fontSizeInPoints Font size (in points) + * @return int Font size (in pixels) + */ + public static function fontSizeToPixels($fontSizeInPoints = 11) { + return (int) ((4 / 3) * $fontSizeInPoints); + } + + /** + * Calculate an (approximate) pixel size, based on inch size + * + * @param int $sizeInInch Font size (in inch) + * @return int Size (in pixels) + */ + public static function inchSizeToPixels($sizeInInch = 1) { + return ($sizeInInch * 96); + } + + /** + * Calculate an (approximate) pixel size, based on centimeter size + * + * @param int $sizeInCm Font size (in centimeters) + * @return int Size (in pixels) + */ + public static function centimeterSizeToPixels($sizeInCm = 1) { + return ($sizeInCm * 37.795275591); + } + + /** + * Returns the font path given the font + * + * @param PHPExcel_Style_Font + * @return string Path to TrueType font file + */ + public static function getTrueTypeFontFileFromFont($font) { + if (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath)) { + throw new PHPExcel_Exception('Valid directory to TrueType Font files not specified'); + } + + $name = $font->getName(); + $bold = $font->getBold(); + $italic = $font->getItalic(); + + // Check if we can map font to true type font file + switch ($name) { + case 'Arial': + $fontFile = ( + $bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD) + : ($italic ? self::ARIAL_ITALIC : self::ARIAL) + ); + break; + + case 'Calibri': + $fontFile = ( + $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD) + : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI) + ); + break; + + case 'Courier New': + $fontFile = ( + $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD) + : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW) + ); + break; + + case 'Comic Sans MS': + $fontFile = ( + $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS + ); + break; + + case 'Georgia': + $fontFile = ( + $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD) + : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA) + ); + break; + + case 'Impact': + $fontFile = self::IMPACT; + break; + + case 'Liberation Sans': + $fontFile = ( + $bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD) + : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS) + ); + break; + + case 'Lucida Console': + $fontFile = self::LUCIDA_CONSOLE; + break; + + case 'Lucida Sans Unicode': + $fontFile = self::LUCIDA_SANS_UNICODE; + break; + + case 'Microsoft Sans Serif': + $fontFile = self::MICROSOFT_SANS_SERIF; + break; + + case 'Palatino Linotype': + $fontFile = ( + $bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD) + : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE) + ); + break; + + case 'Symbol': + $fontFile = self::SYMBOL; + break; + + case 'Tahoma': + $fontFile = ( + $bold ? self::TAHOMA_BOLD : self::TAHOMA + ); + break; + + case 'Times New Roman': + $fontFile = ( + $bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD) + : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN) + ); + break; + + case 'Trebuchet MS': + $fontFile = ( + $bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD) + : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS) + ); break; - case 'Verdana': - // value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font. - $columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText)); - $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size - break; - - default: - // just assume Calibri - $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); - $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size - break; - } - - // Calculate approximate rotated column width - if ($rotation !== 0) { - if ($rotation == -165) { - // stacked text - $columnWidth = 4; // approximation - } else { - // rotated text - $columnWidth = $columnWidth * cos(deg2rad($rotation)) - + $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation - } - } - - // pixel width is an integer - return (int) $columnWidth; - } - - /** - * Calculate an (approximate) pixel size, based on a font points size - * - * @param int $fontSizeInPoints Font size (in points) - * @return int Font size (in pixels) - */ - public static function fontSizeToPixels($fontSizeInPoints = 11) { - return (int) ((4 / 3) * $fontSizeInPoints); - } - - /** - * Calculate an (approximate) pixel size, based on inch size - * - * @param int $sizeInInch Font size (in inch) - * @return int Size (in pixels) - */ - public static function inchSizeToPixels($sizeInInch = 1) { - return ($sizeInInch * 96); - } - - /** - * Calculate an (approximate) pixel size, based on centimeter size - * - * @param int $sizeInCm Font size (in centimeters) - * @return int Size (in pixels) - */ - public static function centimeterSizeToPixels($sizeInCm = 1) { - return ($sizeInCm * 37.795275591); - } - - /** - * Returns the font path given the font - * - * @param PHPExcel_Style_Font - * @return string Path to TrueType font file - */ - public static function getTrueTypeFontFileFromFont($font) { - if (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath)) { - throw new PHPExcel_Exception('Valid directory to TrueType Font files not specified'); - } - - $name = $font->getName(); - $bold = $font->getBold(); - $italic = $font->getItalic(); - - // Check if we can map font to true type font file - switch ($name) { - case 'Arial': - $fontFile = ( - $bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD) - : ($italic ? self::ARIAL_ITALIC : self::ARIAL) - ); - break; - - case 'Calibri': - $fontFile = ( - $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD) - : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI) - ); - break; - - case 'Courier New': - $fontFile = ( - $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD) - : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW) - ); - break; - - case 'Comic Sans MS': - $fontFile = ( - $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS - ); - break; - - case 'Georgia': - $fontFile = ( - $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD) - : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA) - ); - break; - - case 'Impact': - $fontFile = self::IMPACT; - break; - - case 'Liberation Sans': - $fontFile = ( - $bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD) - : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS) - ); - break; - - case 'Lucida Console': - $fontFile = self::LUCIDA_CONSOLE; - break; - - case 'Lucida Sans Unicode': - $fontFile = self::LUCIDA_SANS_UNICODE; - break; - - case 'Microsoft Sans Serif': - $fontFile = self::MICROSOFT_SANS_SERIF; - break; - - case 'Palatino Linotype': - $fontFile = ( - $bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD) - : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE) - ); - break; - - case 'Symbol': - $fontFile = self::SYMBOL; - break; - - case 'Tahoma': - $fontFile = ( - $bold ? self::TAHOMA_BOLD : self::TAHOMA - ); - break; - - case 'Times New Roman': - $fontFile = ( - $bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD) - : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN) - ); - break; - - case 'Trebuchet MS': - $fontFile = ( - $bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD) - : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS) - ); - break; - - case 'Verdana': - $fontFile = ( - $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD) - : ($italic ? self::VERDANA_ITALIC : self::VERDANA) - ); - break; - - default: - throw new PHPExcel_Exception('Unknown font name "'. $name .'". Cannot map to TrueType font file'); - break; - } - - $fontFile = self::$trueTypeFontPath . $fontFile; - - // Check if file actually exists - if (!file_exists($fontFile)) { - throw New PHPExcel_Exception('TrueType Font file not found'); - } - - return $fontFile; - } - - /** - * Returns the associated charset for the font name. - * - * @param string $name Font name - * @return int Character set code - */ - public static function getCharsetFromFontName($name) - { - switch ($name) { - // Add more cases. Check FONT records in real Excel files. - case 'EucrosiaUPC': return self::CHARSET_ANSI_THAI; - case 'Wingdings': return self::CHARSET_SYMBOL; - case 'Wingdings 2': return self::CHARSET_SYMBOL; - case 'Wingdings 3': return self::CHARSET_SYMBOL; - default: return self::CHARSET_ANSI_LATIN; - } - } - - /** - * Get the effective column width for columns without a column dimension or column with width -1 - * For example, for Calibri 11 this is 9.140625 (64 px) - * - * @param PHPExcel_Style_Font $font The workbooks default font - * @param boolean $pPixels true = return column width in pixels, false = return in OOXML units - * @return mixed Column width - */ - public static function getDefaultColumnWidthByFont(PHPExcel_Style_Font $font, $pPixels = false) - { - if (isset(self::$defaultColumnWidths[$font->getName()][$font->getSize()])) { - // Exact width can be determined - $columnWidth = $pPixels ? - self::$defaultColumnWidths[$font->getName()][$font->getSize()]['px'] - : self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width']; - - } else { - // We don't have data for this particular font and size, use approximation by - // extrapolating from Calibri 11 - $columnWidth = $pPixels ? - self::$defaultColumnWidths['Calibri'][11]['px'] - : self::$defaultColumnWidths['Calibri'][11]['width']; - $columnWidth = $columnWidth * $font->getSize() / 11; - - // Round pixels to closest integer - if ($pPixels) { - $columnWidth = (int) round($columnWidth); - } - } - - return $columnWidth; - } - - /** - * Get the effective row height for rows without a row dimension or rows with height -1 - * For example, for Calibri 11 this is 15 points - * - * @param PHPExcel_Style_Font $font The workbooks default font - * @return float Row height in points - */ - public static function getDefaultRowHeightByFont(PHPExcel_Style_Font $font) - { - switch ($font->getName()) { - case 'Arial': - switch ($font->getSize()) { - case 10: - // inspection of Arial 10 workbook says 12.75pt ~17px - $rowHeight = 12.75; - break; - - case 9: - // inspection of Arial 9 workbook says 12.00pt ~16px - $rowHeight = 12; - break; - - case 8: - // inspection of Arial 8 workbook says 11.25pt ~15px - $rowHeight = 11.25; - break; - - case 7: - // inspection of Arial 7 workbook says 9.00pt ~12px - $rowHeight = 9; - break; - - case 6: - case 5: - // inspection of Arial 5,6 workbook says 8.25pt ~11px - $rowHeight = 8.25; - break; - - case 4: - // inspection of Arial 4 workbook says 6.75pt ~9px - $rowHeight = 6.75; - break; - - case 3: - // inspection of Arial 3 workbook says 6.00pt ~8px - $rowHeight = 6; - break; - - case 2: - case 1: - // inspection of Arial 1,2 workbook says 5.25pt ~7px - $rowHeight = 5.25; - break; - - default: - // use Arial 10 workbook as an approximation, extrapolation - $rowHeight = 12.75 * $font->getSize() / 10; - break; - } - break; - - case 'Calibri': - switch ($font->getSize()) { - case 11: - // inspection of Calibri 11 workbook says 15.00pt ~20px - $rowHeight = 15; - break; - - case 10: - // inspection of Calibri 10 workbook says 12.75pt ~17px - $rowHeight = 12.75; - break; - - case 9: - // inspection of Calibri 9 workbook says 12.00pt ~16px - $rowHeight = 12; - break; - - case 8: - // inspection of Calibri 8 workbook says 11.25pt ~15px - $rowHeight = 11.25; - break; - - case 7: - // inspection of Calibri 7 workbook says 9.00pt ~12px - $rowHeight = 9; - break; - - case 6: - case 5: - // inspection of Calibri 5,6 workbook says 8.25pt ~11px - $rowHeight = 8.25; - break; - - case 4: - // inspection of Calibri 4 workbook says 6.75pt ~9px - $rowHeight = 6.75; - break; - - case 3: - // inspection of Calibri 3 workbook says 6.00pt ~8px - $rowHeight = 6.00; - break; - - case 2: - case 1: - // inspection of Calibri 1,2 workbook says 5.25pt ~7px - $rowHeight = 5.25; - break; - - default: - // use Calibri 11 workbook as an approximation, extrapolation - $rowHeight = 15 * $font->getSize() / 11; - break; - } - break; - - case 'Verdana': - switch ($font->getSize()) { - case 10: - // inspection of Verdana 10 workbook says 12.75pt ~17px - $rowHeight = 12.75; - break; - - case 9: - // inspection of Verdana 9 workbook says 11.25pt ~15px - $rowHeight = 11.25; - break; - - case 8: - // inspection of Verdana 8 workbook says 10.50pt ~14px - $rowHeight = 10.50; - break; - - case 7: - // inspection of Verdana 7 workbook says 9.00pt ~12px - $rowHeight = 9.00; - break; - - case 6: - case 5: - // inspection of Verdana 5,6 workbook says 8.25pt ~11px - $rowHeight = 8.25; - break; - - case 4: - // inspection of Verdana 4 workbook says 6.75pt ~9px - $rowHeight = 6.75; - break; - - case 3: - // inspection of Verdana 3 workbook says 6.00pt ~8px - $rowHeight = 6; - break; - - case 2: - case 1: - // inspection of Verdana 1,2 workbook says 5.25pt ~7px - $rowHeight = 5.25; - break; - - default: - // use Verdana 10 workbook as an approximation, extrapolation - $rowHeight = 12.75 * $font->getSize() / 10; - break; - } - break; - - default: - // just use Calibri as an approximation - $rowHeight = 15 * $font->getSize() / 11; - break; - } - - return $rowHeight; - } + case 'Verdana': + $fontFile = ( + $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD) + : ($italic ? self::VERDANA_ITALIC : self::VERDANA) + ); + break; + + default: + throw new PHPExcel_Exception('Unknown font name "'. $name .'". Cannot map to TrueType font file'); + break; + } + + $fontFile = self::$trueTypeFontPath . $fontFile; + + // Check if file actually exists + if (!file_exists($fontFile)) { + throw New PHPExcel_Exception('TrueType Font file not found'); + } + + return $fontFile; + } + + /** + * Returns the associated charset for the font name. + * + * @param string $name Font name + * @return int Character set code + */ + public static function getCharsetFromFontName($name) + { + switch ($name) { + // Add more cases. Check FONT records in real Excel files. + case 'EucrosiaUPC': return self::CHARSET_ANSI_THAI; + case 'Wingdings': return self::CHARSET_SYMBOL; + case 'Wingdings 2': return self::CHARSET_SYMBOL; + case 'Wingdings 3': return self::CHARSET_SYMBOL; + default: return self::CHARSET_ANSI_LATIN; + } + } + + /** + * Get the effective column width for columns without a column dimension or column with width -1 + * For example, for Calibri 11 this is 9.140625 (64 px) + * + * @param PHPExcel_Style_Font $font The workbooks default font + * @param boolean $pPixels true = return column width in pixels, false = return in OOXML units + * @return mixed Column width + */ + public static function getDefaultColumnWidthByFont(PHPExcel_Style_Font $font, $pPixels = false) + { + if (isset(self::$defaultColumnWidths[$font->getName()][$font->getSize()])) { + // Exact width can be determined + $columnWidth = $pPixels ? + self::$defaultColumnWidths[$font->getName()][$font->getSize()]['px'] + : self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width']; + + } else { + // We don't have data for this particular font and size, use approximation by + // extrapolating from Calibri 11 + $columnWidth = $pPixels ? + self::$defaultColumnWidths['Calibri'][11]['px'] + : self::$defaultColumnWidths['Calibri'][11]['width']; + $columnWidth = $columnWidth * $font->getSize() / 11; + + // Round pixels to closest integer + if ($pPixels) { + $columnWidth = (int) round($columnWidth); + } + } + + return $columnWidth; + } + + /** + * Get the effective row height for rows without a row dimension or rows with height -1 + * For example, for Calibri 11 this is 15 points + * + * @param PHPExcel_Style_Font $font The workbooks default font + * @return float Row height in points + */ + public static function getDefaultRowHeightByFont(PHPExcel_Style_Font $font) + { + switch ($font->getName()) { + case 'Arial': + switch ($font->getSize()) { + case 10: + // inspection of Arial 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; + + case 9: + // inspection of Arial 9 workbook says 12.00pt ~16px + $rowHeight = 12; + break; + + case 8: + // inspection of Arial 8 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; + + case 7: + // inspection of Arial 7 workbook says 9.00pt ~12px + $rowHeight = 9; + break; + + case 6: + case 5: + // inspection of Arial 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; + + case 4: + // inspection of Arial 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; + + case 3: + // inspection of Arial 3 workbook says 6.00pt ~8px + $rowHeight = 6; + break; + + case 2: + case 1: + // inspection of Arial 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; + + default: + // use Arial 10 workbook as an approximation, extrapolation + $rowHeight = 12.75 * $font->getSize() / 10; + break; + } + break; + + case 'Calibri': + switch ($font->getSize()) { + case 11: + // inspection of Calibri 11 workbook says 15.00pt ~20px + $rowHeight = 15; + break; + + case 10: + // inspection of Calibri 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; + + case 9: + // inspection of Calibri 9 workbook says 12.00pt ~16px + $rowHeight = 12; + break; + + case 8: + // inspection of Calibri 8 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; + + case 7: + // inspection of Calibri 7 workbook says 9.00pt ~12px + $rowHeight = 9; + break; + + case 6: + case 5: + // inspection of Calibri 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; + + case 4: + // inspection of Calibri 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; + + case 3: + // inspection of Calibri 3 workbook says 6.00pt ~8px + $rowHeight = 6.00; + break; + + case 2: + case 1: + // inspection of Calibri 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; + + default: + // use Calibri 11 workbook as an approximation, extrapolation + $rowHeight = 15 * $font->getSize() / 11; + break; + } + break; + + case 'Verdana': + switch ($font->getSize()) { + case 10: + // inspection of Verdana 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; + + case 9: + // inspection of Verdana 9 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; + + case 8: + // inspection of Verdana 8 workbook says 10.50pt ~14px + $rowHeight = 10.50; + break; + + case 7: + // inspection of Verdana 7 workbook says 9.00pt ~12px + $rowHeight = 9.00; + break; + + case 6: + case 5: + // inspection of Verdana 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; + + case 4: + // inspection of Verdana 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; + + case 3: + // inspection of Verdana 3 workbook says 6.00pt ~8px + $rowHeight = 6; + break; + + case 2: + case 1: + // inspection of Verdana 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; + + default: + // use Verdana 10 workbook as an approximation, extrapolation + $rowHeight = 12.75 * $font->getSize() / 10; + break; + } + break; + + default: + // just use Calibri as an approximation + $rowHeight = 15 * $font->getSize() / 11; + break; + } + + return $rowHeight; + } } diff --git a/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php b/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php index cfbaa53bc..31a0b648e 100644 --- a/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php @@ -1,149 +1,149 @@ <?php /** - * @package JAMA + * @package JAMA * - * Cholesky decomposition class + * Cholesky decomposition class * - * For a symmetric, positive definite matrix A, the Cholesky decomposition - * is an lower triangular matrix L so that A = L*L'. + * For a symmetric, positive definite matrix A, the Cholesky decomposition + * is an lower triangular matrix L so that A = L*L'. * - * If the matrix is not symmetric or positive definite, the constructor - * returns a partial decomposition and sets an internal flag that may - * be queried by the isSPD() method. + * If the matrix is not symmetric or positive definite, the constructor + * returns a partial decomposition and sets an internal flag that may + * be queried by the isSPD() method. * - * @author Paul Meagher - * @author Michael Bommarito - * @version 1.2 + * @author Paul Meagher + * @author Michael Bommarito + * @version 1.2 */ class CholeskyDecomposition { - /** - * Decomposition storage - * @var array - * @access private - */ - private $L = array(); - - /** - * Matrix row and column dimension - * @var int - * @access private - */ - private $m; - - /** - * Symmetric positive definite flag - * @var boolean - * @access private - */ - private $isspd = true; - - - /** - * CholeskyDecomposition - * - * Class constructor - decomposes symmetric positive definite matrix - * @param mixed Matrix square symmetric positive definite matrix - */ - public function __construct($A = null) { - if ($A instanceof Matrix) { - $this->L = $A->getArray(); - $this->m = $A->getRowDimension(); - - for($i = 0; $i < $this->m; ++$i) { - for($j = $i; $j < $this->m; ++$j) { - for($sum = $this->L[$i][$j], $k = $i - 1; $k >= 0; --$k) { - $sum -= $this->L[$i][$k] * $this->L[$j][$k]; - } - if ($i == $j) { - if ($sum >= 0) { - $this->L[$i][$i] = sqrt($sum); - } else { - $this->isspd = false; - } - } else { - if ($this->L[$i][$i] != 0) { - $this->L[$j][$i] = $sum / $this->L[$i][$i]; - } - } - } - - for ($k = $i+1; $k < $this->m; ++$k) { - $this->L[$i][$k] = 0.0; - } - } - } else { - throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); - } - } // function __construct() - - - /** - * Is the matrix symmetric and positive definite? - * - * @return boolean - */ - public function isSPD() { - return $this->isspd; - } // function isSPD() - - - /** - * getL - * - * Return triangular factor. - * @return Matrix Lower triangular matrix - */ - public function getL() { - return new Matrix($this->L); - } // function getL() - - - /** - * Solve A*X = B - * - * @param $B Row-equal matrix - * @return Matrix L * L' * X = B - */ - public function solve($B = null) { - if ($B instanceof Matrix) { - if ($B->getRowDimension() == $this->m) { - if ($this->isspd) { - $X = $B->getArrayCopy(); - $nx = $B->getColumnDimension(); - - for ($k = 0; $k < $this->m; ++$k) { - for ($i = $k + 1; $i < $this->m; ++$i) { - for ($j = 0; $j < $nx; ++$j) { - $X[$i][$j] -= $X[$k][$j] * $this->L[$i][$k]; - } - } - for ($j = 0; $j < $nx; ++$j) { - $X[$k][$j] /= $this->L[$k][$k]; - } - } - - for ($k = $this->m - 1; $k >= 0; --$k) { - for ($j = 0; $j < $nx; ++$j) { - $X[$k][$j] /= $this->L[$k][$k]; - } - for ($i = 0; $i < $k; ++$i) { - for ($j = 0; $j < $nx; ++$j) { - $X[$i][$j] -= $X[$k][$j] * $this->L[$k][$i]; - } - } - } - - return new Matrix($X, $this->m, $nx); - } else { - throw new PHPExcel_Calculation_Exception(JAMAError(MatrixSPDException)); - } - } else { - throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionException)); - } - } else { - throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); - } - } // function solve() - -} // class CholeskyDecomposition + /** + * Decomposition storage + * @var array + * @access private + */ + private $L = array(); + + /** + * Matrix row and column dimension + * @var int + * @access private + */ + private $m; + + /** + * Symmetric positive definite flag + * @var boolean + * @access private + */ + private $isspd = true; + + + /** + * CholeskyDecomposition + * + * Class constructor - decomposes symmetric positive definite matrix + * @param mixed Matrix square symmetric positive definite matrix + */ + public function __construct($A = null) { + if ($A instanceof Matrix) { + $this->L = $A->getArray(); + $this->m = $A->getRowDimension(); + + for($i = 0; $i < $this->m; ++$i) { + for($j = $i; $j < $this->m; ++$j) { + for($sum = $this->L[$i][$j], $k = $i - 1; $k >= 0; --$k) { + $sum -= $this->L[$i][$k] * $this->L[$j][$k]; + } + if ($i == $j) { + if ($sum >= 0) { + $this->L[$i][$i] = sqrt($sum); + } else { + $this->isspd = false; + } + } else { + if ($this->L[$i][$i] != 0) { + $this->L[$j][$i] = $sum / $this->L[$i][$i]; + } + } + } + + for ($k = $i+1; $k < $this->m; ++$k) { + $this->L[$i][$k] = 0.0; + } + } + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + } + } // function __construct() + + + /** + * Is the matrix symmetric and positive definite? + * + * @return boolean + */ + public function isSPD() { + return $this->isspd; + } // function isSPD() + + + /** + * getL + * + * Return triangular factor. + * @return Matrix Lower triangular matrix + */ + public function getL() { + return new Matrix($this->L); + } // function getL() + + + /** + * Solve A*X = B + * + * @param $B Row-equal matrix + * @return Matrix L * L' * X = B + */ + public function solve($B = null) { + if ($B instanceof Matrix) { + if ($B->getRowDimension() == $this->m) { + if ($this->isspd) { + $X = $B->getArrayCopy(); + $nx = $B->getColumnDimension(); + + for ($k = 0; $k < $this->m; ++$k) { + for ($i = $k + 1; $i < $this->m; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X[$i][$j] -= $X[$k][$j] * $this->L[$i][$k]; + } + } + for ($j = 0; $j < $nx; ++$j) { + $X[$k][$j] /= $this->L[$k][$k]; + } + } + + for ($k = $this->m - 1; $k >= 0; --$k) { + for ($j = 0; $j < $nx; ++$j) { + $X[$k][$j] /= $this->L[$k][$k]; + } + for ($i = 0; $i < $k; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X[$i][$j] -= $X[$k][$j] * $this->L[$k][$i]; + } + } + } + + return new Matrix($X, $this->m, $nx); + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixSPDException)); + } + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionException)); + } + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + } + } // function solve() + +} // class CholeskyDecomposition diff --git a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php index 2a696d00f..386d6c13a 100644 --- a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php @@ -1,862 +1,862 @@ <?php /** - * @package JAMA + * @package JAMA * - * Class to obtain eigenvalues and eigenvectors of a real matrix. + * Class to obtain eigenvalues and eigenvectors of a real matrix. * - * If A is symmetric, then A = V*D*V' where the eigenvalue matrix D - * is diagonal and the eigenvector matrix V is orthogonal (i.e. - * A = V.times(D.times(V.transpose())) and V.times(V.transpose()) - * equals the identity matrix). + * If A is symmetric, then A = V*D*V' where the eigenvalue matrix D + * is diagonal and the eigenvector matrix V is orthogonal (i.e. + * A = V.times(D.times(V.transpose())) and V.times(V.transpose()) + * equals the identity matrix). * - * If A is not symmetric, then the eigenvalue matrix D is block diagonal - * with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues, - * lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda]. The - * columns of V represent the eigenvectors in the sense that A*V = V*D, - * i.e. A.times(V) equals V.times(D). The matrix V may be badly - * conditioned, or even singular, so the validity of the equation - * A = V*D*inverse(V) depends upon V.cond(). + * If A is not symmetric, then the eigenvalue matrix D is block diagonal + * with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues, + * lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda]. The + * columns of V represent the eigenvectors in the sense that A*V = V*D, + * i.e. A.times(V) equals V.times(D). The matrix V may be badly + * conditioned, or even singular, so the validity of the equation + * A = V*D*inverse(V) depends upon V.cond(). * - * @author Paul Meagher - * @license PHP v3.0 - * @version 1.1 + * @author Paul Meagher + * @license PHP v3.0 + * @version 1.1 */ class EigenvalueDecomposition { - /** - * Row and column dimension (square matrix). - * @var int - */ - private $n; - - /** - * Internal symmetry flag. - * @var int - */ - private $issymmetric; - - /** - * Arrays for internal storage of eigenvalues. - * @var array - */ - private $d = array(); - private $e = array(); - - /** - * Array for internal storage of eigenvectors. - * @var array - */ - private $V = array(); - - /** - * Array for internal storage of nonsymmetric Hessenberg form. - * @var array - */ - private $H = array(); - - /** - * Working storage for nonsymmetric algorithm. - * @var array - */ - private $ort; - - /** - * Used for complex scalar division. - * @var float - */ - private $cdivr; - private $cdivi; - - - /** - * Symmetric Householder reduction to tridiagonal form. - * - * @access private - */ - private function tred2 () { - // This is derived from the Algol procedures tred2 by - // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for - // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding - // Fortran subroutine in EISPACK. - $this->d = $this->V[$this->n-1]; - // Householder reduction to tridiagonal form. - for ($i = $this->n-1; $i > 0; --$i) { - $i_ = $i -1; - // Scale to avoid under/overflow. - $h = $scale = 0.0; - $scale += array_sum(array_map(abs, $this->d)); - if ($scale == 0.0) { - $this->e[$i] = $this->d[$i_]; - $this->d = array_slice($this->V[$i_], 0, $i_); - for ($j = 0; $j < $i; ++$j) { - $this->V[$j][$i] = $this->V[$i][$j] = 0.0; - } - } else { - // Generate Householder vector. - for ($k = 0; $k < $i; ++$k) { - $this->d[$k] /= $scale; - $h += pow($this->d[$k], 2); - } - $f = $this->d[$i_]; - $g = sqrt($h); - if ($f > 0) { - $g = -$g; - } - $this->e[$i] = $scale * $g; - $h = $h - $f * $g; - $this->d[$i_] = $f - $g; - for ($j = 0; $j < $i; ++$j) { - $this->e[$j] = 0.0; - } - // Apply similarity transformation to remaining columns. - for ($j = 0; $j < $i; ++$j) { - $f = $this->d[$j]; - $this->V[$j][$i] = $f; - $g = $this->e[$j] + $this->V[$j][$j] * $f; - for ($k = $j+1; $k <= $i_; ++$k) { - $g += $this->V[$k][$j] * $this->d[$k]; - $this->e[$k] += $this->V[$k][$j] * $f; - } - $this->e[$j] = $g; - } - $f = 0.0; - for ($j = 0; $j < $i; ++$j) { - $this->e[$j] /= $h; - $f += $this->e[$j] * $this->d[$j]; - } - $hh = $f / (2 * $h); - for ($j=0; $j < $i; ++$j) { - $this->e[$j] -= $hh * $this->d[$j]; - } - for ($j = 0; $j < $i; ++$j) { - $f = $this->d[$j]; - $g = $this->e[$j]; - for ($k = $j; $k <= $i_; ++$k) { - $this->V[$k][$j] -= ($f * $this->e[$k] + $g * $this->d[$k]); - } - $this->d[$j] = $this->V[$i-1][$j]; - $this->V[$i][$j] = 0.0; - } - } - $this->d[$i] = $h; - } - - // Accumulate transformations. - for ($i = 0; $i < $this->n-1; ++$i) { - $this->V[$this->n-1][$i] = $this->V[$i][$i]; - $this->V[$i][$i] = 1.0; - $h = $this->d[$i+1]; - if ($h != 0.0) { - for ($k = 0; $k <= $i; ++$k) { - $this->d[$k] = $this->V[$k][$i+1] / $h; - } - for ($j = 0; $j <= $i; ++$j) { - $g = 0.0; - for ($k = 0; $k <= $i; ++$k) { - $g += $this->V[$k][$i+1] * $this->V[$k][$j]; - } - for ($k = 0; $k <= $i; ++$k) { - $this->V[$k][$j] -= $g * $this->d[$k]; - } - } - } - for ($k = 0; $k <= $i; ++$k) { - $this->V[$k][$i+1] = 0.0; - } - } - - $this->d = $this->V[$this->n-1]; - $this->V[$this->n-1] = array_fill(0, $j, 0.0); - $this->V[$this->n-1][$this->n-1] = 1.0; - $this->e[0] = 0.0; - } - - - /** - * Symmetric tridiagonal QL algorithm. - * - * This is derived from the Algol procedures tql2, by - * Bowdler, Martin, Reinsch, and Wilkinson, Handbook for - * Auto. Comp., Vol.ii-Linear Algebra, and the corresponding - * Fortran subroutine in EISPACK. - * - * @access private - */ - private function tql2() { - for ($i = 1; $i < $this->n; ++$i) { - $this->e[$i-1] = $this->e[$i]; - } - $this->e[$this->n-1] = 0.0; - $f = 0.0; - $tst1 = 0.0; - $eps = pow(2.0,-52.0); - - for ($l = 0; $l < $this->n; ++$l) { - // Find small subdiagonal element - $tst1 = max($tst1, abs($this->d[$l]) + abs($this->e[$l])); - $m = $l; - while ($m < $this->n) { - if (abs($this->e[$m]) <= $eps * $tst1) - break; - ++$m; - } - // If m == l, $this->d[l] is an eigenvalue, - // otherwise, iterate. - if ($m > $l) { - $iter = 0; - do { - // Could check iteration count here. - $iter += 1; - // Compute implicit shift - $g = $this->d[$l]; - $p = ($this->d[$l+1] - $g) / (2.0 * $this->e[$l]); - $r = hypo($p, 1.0); - if ($p < 0) - $r *= -1; - $this->d[$l] = $this->e[$l] / ($p + $r); - $this->d[$l+1] = $this->e[$l] * ($p + $r); - $dl1 = $this->d[$l+1]; - $h = $g - $this->d[$l]; - for ($i = $l + 2; $i < $this->n; ++$i) - $this->d[$i] -= $h; - $f += $h; - // Implicit QL transformation. - $p = $this->d[$m]; - $c = 1.0; - $c2 = $c3 = $c; - $el1 = $this->e[$l + 1]; - $s = $s2 = 0.0; - for ($i = $m-1; $i >= $l; --$i) { - $c3 = $c2; - $c2 = $c; - $s2 = $s; - $g = $c * $this->e[$i]; - $h = $c * $p; - $r = hypo($p, $this->e[$i]); - $this->e[$i+1] = $s * $r; - $s = $this->e[$i] / $r; - $c = $p / $r; - $p = $c * $this->d[$i] - $s * $g; - $this->d[$i+1] = $h + $s * ($c * $g + $s * $this->d[$i]); - // Accumulate transformation. - for ($k = 0; $k < $this->n; ++$k) { - $h = $this->V[$k][$i+1]; - $this->V[$k][$i+1] = $s * $this->V[$k][$i] + $c * $h; - $this->V[$k][$i] = $c * $this->V[$k][$i] - $s * $h; - } - } - $p = -$s * $s2 * $c3 * $el1 * $this->e[$l] / $dl1; - $this->e[$l] = $s * $p; - $this->d[$l] = $c * $p; - // Check for convergence. - } while (abs($this->e[$l]) > $eps * $tst1); - } - $this->d[$l] = $this->d[$l] + $f; - $this->e[$l] = 0.0; - } - - // Sort eigenvalues and corresponding vectors. - for ($i = 0; $i < $this->n - 1; ++$i) { - $k = $i; - $p = $this->d[$i]; - for ($j = $i+1; $j < $this->n; ++$j) { - if ($this->d[$j] < $p) { - $k = $j; - $p = $this->d[$j]; - } - } - if ($k != $i) { - $this->d[$k] = $this->d[$i]; - $this->d[$i] = $p; - for ($j = 0; $j < $this->n; ++$j) { - $p = $this->V[$j][$i]; - $this->V[$j][$i] = $this->V[$j][$k]; - $this->V[$j][$k] = $p; - } - } - } - } - - - /** - * Nonsymmetric reduction to Hessenberg form. - * - * This is derived from the Algol procedures orthes and ortran, - * by Martin and Wilkinson, Handbook for Auto. Comp., - * Vol.ii-Linear Algebra, and the corresponding - * Fortran subroutines in EISPACK. - * - * @access private - */ - private function orthes () { - $low = 0; - $high = $this->n-1; - - for ($m = $low+1; $m <= $high-1; ++$m) { - // Scale column. - $scale = 0.0; - for ($i = $m; $i <= $high; ++$i) { - $scale = $scale + abs($this->H[$i][$m-1]); - } - if ($scale != 0.0) { - // Compute Householder transformation. - $h = 0.0; - for ($i = $high; $i >= $m; --$i) { - $this->ort[$i] = $this->H[$i][$m-1] / $scale; - $h += $this->ort[$i] * $this->ort[$i]; - } - $g = sqrt($h); - if ($this->ort[$m] > 0) { - $g *= -1; - } - $h -= $this->ort[$m] * $g; - $this->ort[$m] -= $g; - // Apply Householder similarity transformation - // H = (I -u * u' / h) * H * (I -u * u') / h) - for ($j = $m; $j < $this->n; ++$j) { - $f = 0.0; - for ($i = $high; $i >= $m; --$i) { - $f += $this->ort[$i] * $this->H[$i][$j]; - } - $f /= $h; - for ($i = $m; $i <= $high; ++$i) { - $this->H[$i][$j] -= $f * $this->ort[$i]; - } - } - for ($i = 0; $i <= $high; ++$i) { - $f = 0.0; - for ($j = $high; $j >= $m; --$j) { - $f += $this->ort[$j] * $this->H[$i][$j]; - } - $f = $f / $h; - for ($j = $m; $j <= $high; ++$j) { - $this->H[$i][$j] -= $f * $this->ort[$j]; - } - } - $this->ort[$m] = $scale * $this->ort[$m]; - $this->H[$m][$m-1] = $scale * $g; - } - } - - // Accumulate transformations (Algol's ortran). - for ($i = 0; $i < $this->n; ++$i) { - for ($j = 0; $j < $this->n; ++$j) { - $this->V[$i][$j] = ($i == $j ? 1.0 : 0.0); - } - } - for ($m = $high-1; $m >= $low+1; --$m) { - if ($this->H[$m][$m-1] != 0.0) { - for ($i = $m+1; $i <= $high; ++$i) { - $this->ort[$i] = $this->H[$i][$m-1]; - } - for ($j = $m; $j <= $high; ++$j) { - $g = 0.0; - for ($i = $m; $i <= $high; ++$i) { - $g += $this->ort[$i] * $this->V[$i][$j]; - } - // Double division avoids possible underflow - $g = ($g / $this->ort[$m]) / $this->H[$m][$m-1]; - for ($i = $m; $i <= $high; ++$i) { - $this->V[$i][$j] += $g * $this->ort[$i]; - } - } - } - } - } - - - /** - * Performs complex division. - * - * @access private - */ - private function cdiv($xr, $xi, $yr, $yi) { - if (abs($yr) > abs($yi)) { - $r = $yi / $yr; - $d = $yr + $r * $yi; - $this->cdivr = ($xr + $r * $xi) / $d; - $this->cdivi = ($xi - $r * $xr) / $d; - } else { - $r = $yr / $yi; - $d = $yi + $r * $yr; - $this->cdivr = ($r * $xr + $xi) / $d; - $this->cdivi = ($r * $xi - $xr) / $d; - } - } - - - /** - * Nonsymmetric reduction from Hessenberg to real Schur form. - * - * Code is derived from the Algol procedure hqr2, - * by Martin and Wilkinson, Handbook for Auto. Comp., - * Vol.ii-Linear Algebra, and the corresponding - * Fortran subroutine in EISPACK. - * - * @access private - */ - private function hqr2 () { - // Initialize - $nn = $this->n; - $n = $nn - 1; - $low = 0; - $high = $nn - 1; - $eps = pow(2.0, -52.0); - $exshift = 0.0; - $p = $q = $r = $s = $z = 0; - // Store roots isolated by balanc and compute matrix norm - $norm = 0.0; - - for ($i = 0; $i < $nn; ++$i) { - if (($i < $low) OR ($i > $high)) { - $this->d[$i] = $this->H[$i][$i]; - $this->e[$i] = 0.0; - } - for ($j = max($i-1, 0); $j < $nn; ++$j) { - $norm = $norm + abs($this->H[$i][$j]); - } - } - - // Outer loop over eigenvalue index - $iter = 0; - while ($n >= $low) { - // Look for single small sub-diagonal element - $l = $n; - while ($l > $low) { - $s = abs($this->H[$l-1][$l-1]) + abs($this->H[$l][$l]); - if ($s == 0.0) { - $s = $norm; - } - if (abs($this->H[$l][$l-1]) < $eps * $s) { - break; - } - --$l; - } - // Check for convergence - // One root found - if ($l == $n) { - $this->H[$n][$n] = $this->H[$n][$n] + $exshift; - $this->d[$n] = $this->H[$n][$n]; - $this->e[$n] = 0.0; - --$n; - $iter = 0; - // Two roots found - } else if ($l == $n-1) { - $w = $this->H[$n][$n-1] * $this->H[$n-1][$n]; - $p = ($this->H[$n-1][$n-1] - $this->H[$n][$n]) / 2.0; - $q = $p * $p + $w; - $z = sqrt(abs($q)); - $this->H[$n][$n] = $this->H[$n][$n] + $exshift; - $this->H[$n-1][$n-1] = $this->H[$n-1][$n-1] + $exshift; - $x = $this->H[$n][$n]; - // Real pair - if ($q >= 0) { - if ($p >= 0) { - $z = $p + $z; - } else { - $z = $p - $z; - } - $this->d[$n-1] = $x + $z; - $this->d[$n] = $this->d[$n-1]; - if ($z != 0.0) { - $this->d[$n] = $x - $w / $z; - } - $this->e[$n-1] = 0.0; - $this->e[$n] = 0.0; - $x = $this->H[$n][$n-1]; - $s = abs($x) + abs($z); - $p = $x / $s; - $q = $z / $s; - $r = sqrt($p * $p + $q * $q); - $p = $p / $r; - $q = $q / $r; - // Row modification - for ($j = $n-1; $j < $nn; ++$j) { - $z = $this->H[$n-1][$j]; - $this->H[$n-1][$j] = $q * $z + $p * $this->H[$n][$j]; - $this->H[$n][$j] = $q * $this->H[$n][$j] - $p * $z; - } - // Column modification - for ($i = 0; $i <= n; ++$i) { - $z = $this->H[$i][$n-1]; - $this->H[$i][$n-1] = $q * $z + $p * $this->H[$i][$n]; - $this->H[$i][$n] = $q * $this->H[$i][$n] - $p * $z; - } - // Accumulate transformations - for ($i = $low; $i <= $high; ++$i) { - $z = $this->V[$i][$n-1]; - $this->V[$i][$n-1] = $q * $z + $p * $this->V[$i][$n]; - $this->V[$i][$n] = $q * $this->V[$i][$n] - $p * $z; - } - // Complex pair - } else { - $this->d[$n-1] = $x + $p; - $this->d[$n] = $x + $p; - $this->e[$n-1] = $z; - $this->e[$n] = -$z; - } - $n = $n - 2; - $iter = 0; - // No convergence yet - } else { - // Form shift - $x = $this->H[$n][$n]; - $y = 0.0; - $w = 0.0; - if ($l < $n) { - $y = $this->H[$n-1][$n-1]; - $w = $this->H[$n][$n-1] * $this->H[$n-1][$n]; - } - // Wilkinson's original ad hoc shift - if ($iter == 10) { - $exshift += $x; - for ($i = $low; $i <= $n; ++$i) { - $this->H[$i][$i] -= $x; - } - $s = abs($this->H[$n][$n-1]) + abs($this->H[$n-1][$n-2]); - $x = $y = 0.75 * $s; - $w = -0.4375 * $s * $s; - } - // MATLAB's new ad hoc shift - if ($iter == 30) { - $s = ($y - $x) / 2.0; - $s = $s * $s + $w; - if ($s > 0) { - $s = sqrt($s); - if ($y < $x) { - $s = -$s; - } - $s = $x - $w / (($y - $x) / 2.0 + $s); - for ($i = $low; $i <= $n; ++$i) { - $this->H[$i][$i] -= $s; - } - $exshift += $s; - $x = $y = $w = 0.964; - } - } - // Could check iteration count here. - $iter = $iter + 1; - // Look for two consecutive small sub-diagonal elements - $m = $n - 2; - while ($m >= $l) { - $z = $this->H[$m][$m]; - $r = $x - $z; - $s = $y - $z; - $p = ($r * $s - $w) / $this->H[$m+1][$m] + $this->H[$m][$m+1]; - $q = $this->H[$m+1][$m+1] - $z - $r - $s; - $r = $this->H[$m+2][$m+1]; - $s = abs($p) + abs($q) + abs($r); - $p = $p / $s; - $q = $q / $s; - $r = $r / $s; - if ($m == $l) { - break; - } - if (abs($this->H[$m][$m-1]) * (abs($q) + abs($r)) < - $eps * (abs($p) * (abs($this->H[$m-1][$m-1]) + abs($z) + abs($this->H[$m+1][$m+1])))) { - break; - } - --$m; - } - for ($i = $m + 2; $i <= $n; ++$i) { - $this->H[$i][$i-2] = 0.0; - if ($i > $m+2) { - $this->H[$i][$i-3] = 0.0; - } - } - // Double QR step involving rows l:n and columns m:n - for ($k = $m; $k <= $n-1; ++$k) { - $notlast = ($k != $n-1); - if ($k != $m) { - $p = $this->H[$k][$k-1]; - $q = $this->H[$k+1][$k-1]; - $r = ($notlast ? $this->H[$k+2][$k-1] : 0.0); - $x = abs($p) + abs($q) + abs($r); - if ($x != 0.0) { - $p = $p / $x; - $q = $q / $x; - $r = $r / $x; - } - } - if ($x == 0.0) { - break; - } - $s = sqrt($p * $p + $q * $q + $r * $r); - if ($p < 0) { - $s = -$s; - } - if ($s != 0) { - if ($k != $m) { - $this->H[$k][$k-1] = -$s * $x; - } elseif ($l != $m) { - $this->H[$k][$k-1] = -$this->H[$k][$k-1]; - } - $p = $p + $s; - $x = $p / $s; - $y = $q / $s; - $z = $r / $s; - $q = $q / $p; - $r = $r / $p; - // Row modification - for ($j = $k; $j < $nn; ++$j) { - $p = $this->H[$k][$j] + $q * $this->H[$k+1][$j]; - if ($notlast) { - $p = $p + $r * $this->H[$k+2][$j]; - $this->H[$k+2][$j] = $this->H[$k+2][$j] - $p * $z; - } - $this->H[$k][$j] = $this->H[$k][$j] - $p * $x; - $this->H[$k+1][$j] = $this->H[$k+1][$j] - $p * $y; - } - // Column modification - for ($i = 0; $i <= min($n, $k+3); ++$i) { - $p = $x * $this->H[$i][$k] + $y * $this->H[$i][$k+1]; - if ($notlast) { - $p = $p + $z * $this->H[$i][$k+2]; - $this->H[$i][$k+2] = $this->H[$i][$k+2] - $p * $r; - } - $this->H[$i][$k] = $this->H[$i][$k] - $p; - $this->H[$i][$k+1] = $this->H[$i][$k+1] - $p * $q; - } - // Accumulate transformations - for ($i = $low; $i <= $high; ++$i) { - $p = $x * $this->V[$i][$k] + $y * $this->V[$i][$k+1]; - if ($notlast) { - $p = $p + $z * $this->V[$i][$k+2]; - $this->V[$i][$k+2] = $this->V[$i][$k+2] - $p * $r; - } - $this->V[$i][$k] = $this->V[$i][$k] - $p; - $this->V[$i][$k+1] = $this->V[$i][$k+1] - $p * $q; - } - } // ($s != 0) - } // k loop - } // check convergence - } // while ($n >= $low) - - // Backsubstitute to find vectors of upper triangular form - if ($norm == 0.0) { - return; - } - - for ($n = $nn-1; $n >= 0; --$n) { - $p = $this->d[$n]; - $q = $this->e[$n]; - // Real vector - if ($q == 0) { - $l = $n; - $this->H[$n][$n] = 1.0; - for ($i = $n-1; $i >= 0; --$i) { - $w = $this->H[$i][$i] - $p; - $r = 0.0; - for ($j = $l; $j <= $n; ++$j) { - $r = $r + $this->H[$i][$j] * $this->H[$j][$n]; - } - if ($this->e[$i] < 0.0) { - $z = $w; - $s = $r; - } else { - $l = $i; - if ($this->e[$i] == 0.0) { - if ($w != 0.0) { - $this->H[$i][$n] = -$r / $w; - } else { - $this->H[$i][$n] = -$r / ($eps * $norm); - } - // Solve real equations - } else { - $x = $this->H[$i][$i+1]; - $y = $this->H[$i+1][$i]; - $q = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i]; - $t = ($x * $s - $z * $r) / $q; - $this->H[$i][$n] = $t; - if (abs($x) > abs($z)) { - $this->H[$i+1][$n] = (-$r - $w * $t) / $x; - } else { - $this->H[$i+1][$n] = (-$s - $y * $t) / $z; - } - } - // Overflow control - $t = abs($this->H[$i][$n]); - if (($eps * $t) * $t > 1) { - for ($j = $i; $j <= $n; ++$j) { - $this->H[$j][$n] = $this->H[$j][$n] / $t; - } - } - } - } - // Complex vector - } else if ($q < 0) { - $l = $n-1; - // Last vector component imaginary so matrix is triangular - if (abs($this->H[$n][$n-1]) > abs($this->H[$n-1][$n])) { - $this->H[$n-1][$n-1] = $q / $this->H[$n][$n-1]; - $this->H[$n-1][$n] = -($this->H[$n][$n] - $p) / $this->H[$n][$n-1]; - } else { - $this->cdiv(0.0, -$this->H[$n-1][$n], $this->H[$n-1][$n-1] - $p, $q); - $this->H[$n-1][$n-1] = $this->cdivr; - $this->H[$n-1][$n] = $this->cdivi; - } - $this->H[$n][$n-1] = 0.0; - $this->H[$n][$n] = 1.0; - for ($i = $n-2; $i >= 0; --$i) { - // double ra,sa,vr,vi; - $ra = 0.0; - $sa = 0.0; - for ($j = $l; $j <= $n; ++$j) { - $ra = $ra + $this->H[$i][$j] * $this->H[$j][$n-1]; - $sa = $sa + $this->H[$i][$j] * $this->H[$j][$n]; - } - $w = $this->H[$i][$i] - $p; - if ($this->e[$i] < 0.0) { - $z = $w; - $r = $ra; - $s = $sa; - } else { - $l = $i; - if ($this->e[$i] == 0) { - $this->cdiv(-$ra, -$sa, $w, $q); - $this->H[$i][$n-1] = $this->cdivr; - $this->H[$i][$n] = $this->cdivi; - } else { - // Solve complex equations - $x = $this->H[$i][$i+1]; - $y = $this->H[$i+1][$i]; - $vr = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i] - $q * $q; - $vi = ($this->d[$i] - $p) * 2.0 * $q; - if ($vr == 0.0 & $vi == 0.0) { - $vr = $eps * $norm * (abs($w) + abs($q) + abs($x) + abs($y) + abs($z)); - } - $this->cdiv($x * $r - $z * $ra + $q * $sa, $x * $s - $z * $sa - $q * $ra, $vr, $vi); - $this->H[$i][$n-1] = $this->cdivr; - $this->H[$i][$n] = $this->cdivi; - if (abs($x) > (abs($z) + abs($q))) { - $this->H[$i+1][$n-1] = (-$ra - $w * $this->H[$i][$n-1] + $q * $this->H[$i][$n]) / $x; - $this->H[$i+1][$n] = (-$sa - $w * $this->H[$i][$n] - $q * $this->H[$i][$n-1]) / $x; - } else { - $this->cdiv(-$r - $y * $this->H[$i][$n-1], -$s - $y * $this->H[$i][$n], $z, $q); - $this->H[$i+1][$n-1] = $this->cdivr; - $this->H[$i+1][$n] = $this->cdivi; - } - } - // Overflow control - $t = max(abs($this->H[$i][$n-1]),abs($this->H[$i][$n])); - if (($eps * $t) * $t > 1) { - for ($j = $i; $j <= $n; ++$j) { - $this->H[$j][$n-1] = $this->H[$j][$n-1] / $t; - $this->H[$j][$n] = $this->H[$j][$n] / $t; - } - } - } // end else - } // end for - } // end else for complex case - } // end for - - // Vectors of isolated roots - for ($i = 0; $i < $nn; ++$i) { - if ($i < $low | $i > $high) { - for ($j = $i; $j < $nn; ++$j) { - $this->V[$i][$j] = $this->H[$i][$j]; - } - } - } - - // Back transformation to get eigenvectors of original matrix - for ($j = $nn-1; $j >= $low; --$j) { - for ($i = $low; $i <= $high; ++$i) { - $z = 0.0; - for ($k = $low; $k <= min($j,$high); ++$k) { - $z = $z + $this->V[$i][$k] * $this->H[$k][$j]; - } - $this->V[$i][$j] = $z; - } - } - } // end hqr2 - - - /** - * Constructor: Check for symmetry, then construct the eigenvalue decomposition - * - * @access public - * @param A Square matrix - * @return Structure to access D and V. - */ - public function __construct($Arg) { - $this->A = $Arg->getArray(); - $this->n = $Arg->getColumnDimension(); - - $issymmetric = true; - for ($j = 0; ($j < $this->n) & $issymmetric; ++$j) { - for ($i = 0; ($i < $this->n) & $issymmetric; ++$i) { - $issymmetric = ($this->A[$i][$j] == $this->A[$j][$i]); - } - } - - if ($issymmetric) { - $this->V = $this->A; - // Tridiagonalize. - $this->tred2(); - // Diagonalize. - $this->tql2(); - } else { - $this->H = $this->A; - $this->ort = array(); - // Reduce to Hessenberg form. - $this->orthes(); - // Reduce Hessenberg to real Schur form. - $this->hqr2(); - } - } - - - /** - * Return the eigenvector matrix - * - * @access public - * @return V - */ - public function getV() { - return new Matrix($this->V, $this->n, $this->n); - } - - - /** - * Return the real parts of the eigenvalues - * - * @access public - * @return real(diag(D)) - */ - public function getRealEigenvalues() { - return $this->d; - } - - - /** - * Return the imaginary parts of the eigenvalues - * - * @access public - * @return imag(diag(D)) - */ - public function getImagEigenvalues() { - return $this->e; - } - - - /** - * Return the block diagonal eigenvalue matrix - * - * @access public - * @return D - */ - public function getD() { - for ($i = 0; $i < $this->n; ++$i) { - $D[$i] = array_fill(0, $this->n, 0.0); - $D[$i][$i] = $this->d[$i]; - if ($this->e[$i] == 0) { - continue; - } - $o = ($this->e[$i] > 0) ? $i + 1 : $i - 1; - $D[$i][$o] = $this->e[$i]; - } - return new Matrix($D); - } - -} // class EigenvalueDecomposition + /** + * Row and column dimension (square matrix). + * @var int + */ + private $n; + + /** + * Internal symmetry flag. + * @var int + */ + private $issymmetric; + + /** + * Arrays for internal storage of eigenvalues. + * @var array + */ + private $d = array(); + private $e = array(); + + /** + * Array for internal storage of eigenvectors. + * @var array + */ + private $V = array(); + + /** + * Array for internal storage of nonsymmetric Hessenberg form. + * @var array + */ + private $H = array(); + + /** + * Working storage for nonsymmetric algorithm. + * @var array + */ + private $ort; + + /** + * Used for complex scalar division. + * @var float + */ + private $cdivr; + private $cdivi; + + + /** + * Symmetric Householder reduction to tridiagonal form. + * + * @access private + */ + private function tred2 () { + // This is derived from the Algol procedures tred2 by + // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for + // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding + // Fortran subroutine in EISPACK. + $this->d = $this->V[$this->n-1]; + // Householder reduction to tridiagonal form. + for ($i = $this->n-1; $i > 0; --$i) { + $i_ = $i -1; + // Scale to avoid under/overflow. + $h = $scale = 0.0; + $scale += array_sum(array_map(abs, $this->d)); + if ($scale == 0.0) { + $this->e[$i] = $this->d[$i_]; + $this->d = array_slice($this->V[$i_], 0, $i_); + for ($j = 0; $j < $i; ++$j) { + $this->V[$j][$i] = $this->V[$i][$j] = 0.0; + } + } else { + // Generate Householder vector. + for ($k = 0; $k < $i; ++$k) { + $this->d[$k] /= $scale; + $h += pow($this->d[$k], 2); + } + $f = $this->d[$i_]; + $g = sqrt($h); + if ($f > 0) { + $g = -$g; + } + $this->e[$i] = $scale * $g; + $h = $h - $f * $g; + $this->d[$i_] = $f - $g; + for ($j = 0; $j < $i; ++$j) { + $this->e[$j] = 0.0; + } + // Apply similarity transformation to remaining columns. + for ($j = 0; $j < $i; ++$j) { + $f = $this->d[$j]; + $this->V[$j][$i] = $f; + $g = $this->e[$j] + $this->V[$j][$j] * $f; + for ($k = $j+1; $k <= $i_; ++$k) { + $g += $this->V[$k][$j] * $this->d[$k]; + $this->e[$k] += $this->V[$k][$j] * $f; + } + $this->e[$j] = $g; + } + $f = 0.0; + for ($j = 0; $j < $i; ++$j) { + $this->e[$j] /= $h; + $f += $this->e[$j] * $this->d[$j]; + } + $hh = $f / (2 * $h); + for ($j=0; $j < $i; ++$j) { + $this->e[$j] -= $hh * $this->d[$j]; + } + for ($j = 0; $j < $i; ++$j) { + $f = $this->d[$j]; + $g = $this->e[$j]; + for ($k = $j; $k <= $i_; ++$k) { + $this->V[$k][$j] -= ($f * $this->e[$k] + $g * $this->d[$k]); + } + $this->d[$j] = $this->V[$i-1][$j]; + $this->V[$i][$j] = 0.0; + } + } + $this->d[$i] = $h; + } + + // Accumulate transformations. + for ($i = 0; $i < $this->n-1; ++$i) { + $this->V[$this->n-1][$i] = $this->V[$i][$i]; + $this->V[$i][$i] = 1.0; + $h = $this->d[$i+1]; + if ($h != 0.0) { + for ($k = 0; $k <= $i; ++$k) { + $this->d[$k] = $this->V[$k][$i+1] / $h; + } + for ($j = 0; $j <= $i; ++$j) { + $g = 0.0; + for ($k = 0; $k <= $i; ++$k) { + $g += $this->V[$k][$i+1] * $this->V[$k][$j]; + } + for ($k = 0; $k <= $i; ++$k) { + $this->V[$k][$j] -= $g * $this->d[$k]; + } + } + } + for ($k = 0; $k <= $i; ++$k) { + $this->V[$k][$i+1] = 0.0; + } + } + + $this->d = $this->V[$this->n-1]; + $this->V[$this->n-1] = array_fill(0, $j, 0.0); + $this->V[$this->n-1][$this->n-1] = 1.0; + $this->e[0] = 0.0; + } + + + /** + * Symmetric tridiagonal QL algorithm. + * + * This is derived from the Algol procedures tql2, by + * Bowdler, Martin, Reinsch, and Wilkinson, Handbook for + * Auto. Comp., Vol.ii-Linear Algebra, and the corresponding + * Fortran subroutine in EISPACK. + * + * @access private + */ + private function tql2() { + for ($i = 1; $i < $this->n; ++$i) { + $this->e[$i-1] = $this->e[$i]; + } + $this->e[$this->n-1] = 0.0; + $f = 0.0; + $tst1 = 0.0; + $eps = pow(2.0,-52.0); + + for ($l = 0; $l < $this->n; ++$l) { + // Find small subdiagonal element + $tst1 = max($tst1, abs($this->d[$l]) + abs($this->e[$l])); + $m = $l; + while ($m < $this->n) { + if (abs($this->e[$m]) <= $eps * $tst1) + break; + ++$m; + } + // If m == l, $this->d[l] is an eigenvalue, + // otherwise, iterate. + if ($m > $l) { + $iter = 0; + do { + // Could check iteration count here. + $iter += 1; + // Compute implicit shift + $g = $this->d[$l]; + $p = ($this->d[$l+1] - $g) / (2.0 * $this->e[$l]); + $r = hypo($p, 1.0); + if ($p < 0) + $r *= -1; + $this->d[$l] = $this->e[$l] / ($p + $r); + $this->d[$l+1] = $this->e[$l] * ($p + $r); + $dl1 = $this->d[$l+1]; + $h = $g - $this->d[$l]; + for ($i = $l + 2; $i < $this->n; ++$i) + $this->d[$i] -= $h; + $f += $h; + // Implicit QL transformation. + $p = $this->d[$m]; + $c = 1.0; + $c2 = $c3 = $c; + $el1 = $this->e[$l + 1]; + $s = $s2 = 0.0; + for ($i = $m-1; $i >= $l; --$i) { + $c3 = $c2; + $c2 = $c; + $s2 = $s; + $g = $c * $this->e[$i]; + $h = $c * $p; + $r = hypo($p, $this->e[$i]); + $this->e[$i+1] = $s * $r; + $s = $this->e[$i] / $r; + $c = $p / $r; + $p = $c * $this->d[$i] - $s * $g; + $this->d[$i+1] = $h + $s * ($c * $g + $s * $this->d[$i]); + // Accumulate transformation. + for ($k = 0; $k < $this->n; ++$k) { + $h = $this->V[$k][$i+1]; + $this->V[$k][$i+1] = $s * $this->V[$k][$i] + $c * $h; + $this->V[$k][$i] = $c * $this->V[$k][$i] - $s * $h; + } + } + $p = -$s * $s2 * $c3 * $el1 * $this->e[$l] / $dl1; + $this->e[$l] = $s * $p; + $this->d[$l] = $c * $p; + // Check for convergence. + } while (abs($this->e[$l]) > $eps * $tst1); + } + $this->d[$l] = $this->d[$l] + $f; + $this->e[$l] = 0.0; + } + + // Sort eigenvalues and corresponding vectors. + for ($i = 0; $i < $this->n - 1; ++$i) { + $k = $i; + $p = $this->d[$i]; + for ($j = $i+1; $j < $this->n; ++$j) { + if ($this->d[$j] < $p) { + $k = $j; + $p = $this->d[$j]; + } + } + if ($k != $i) { + $this->d[$k] = $this->d[$i]; + $this->d[$i] = $p; + for ($j = 0; $j < $this->n; ++$j) { + $p = $this->V[$j][$i]; + $this->V[$j][$i] = $this->V[$j][$k]; + $this->V[$j][$k] = $p; + } + } + } + } + + + /** + * Nonsymmetric reduction to Hessenberg form. + * + * This is derived from the Algol procedures orthes and ortran, + * by Martin and Wilkinson, Handbook for Auto. Comp., + * Vol.ii-Linear Algebra, and the corresponding + * Fortran subroutines in EISPACK. + * + * @access private + */ + private function orthes () { + $low = 0; + $high = $this->n-1; + + for ($m = $low+1; $m <= $high-1; ++$m) { + // Scale column. + $scale = 0.0; + for ($i = $m; $i <= $high; ++$i) { + $scale = $scale + abs($this->H[$i][$m-1]); + } + if ($scale != 0.0) { + // Compute Householder transformation. + $h = 0.0; + for ($i = $high; $i >= $m; --$i) { + $this->ort[$i] = $this->H[$i][$m-1] / $scale; + $h += $this->ort[$i] * $this->ort[$i]; + } + $g = sqrt($h); + if ($this->ort[$m] > 0) { + $g *= -1; + } + $h -= $this->ort[$m] * $g; + $this->ort[$m] -= $g; + // Apply Householder similarity transformation + // H = (I -u * u' / h) * H * (I -u * u') / h) + for ($j = $m; $j < $this->n; ++$j) { + $f = 0.0; + for ($i = $high; $i >= $m; --$i) { + $f += $this->ort[$i] * $this->H[$i][$j]; + } + $f /= $h; + for ($i = $m; $i <= $high; ++$i) { + $this->H[$i][$j] -= $f * $this->ort[$i]; + } + } + for ($i = 0; $i <= $high; ++$i) { + $f = 0.0; + for ($j = $high; $j >= $m; --$j) { + $f += $this->ort[$j] * $this->H[$i][$j]; + } + $f = $f / $h; + for ($j = $m; $j <= $high; ++$j) { + $this->H[$i][$j] -= $f * $this->ort[$j]; + } + } + $this->ort[$m] = $scale * $this->ort[$m]; + $this->H[$m][$m-1] = $scale * $g; + } + } + + // Accumulate transformations (Algol's ortran). + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + $this->V[$i][$j] = ($i == $j ? 1.0 : 0.0); + } + } + for ($m = $high-1; $m >= $low+1; --$m) { + if ($this->H[$m][$m-1] != 0.0) { + for ($i = $m+1; $i <= $high; ++$i) { + $this->ort[$i] = $this->H[$i][$m-1]; + } + for ($j = $m; $j <= $high; ++$j) { + $g = 0.0; + for ($i = $m; $i <= $high; ++$i) { + $g += $this->ort[$i] * $this->V[$i][$j]; + } + // Double division avoids possible underflow + $g = ($g / $this->ort[$m]) / $this->H[$m][$m-1]; + for ($i = $m; $i <= $high; ++$i) { + $this->V[$i][$j] += $g * $this->ort[$i]; + } + } + } + } + } + + + /** + * Performs complex division. + * + * @access private + */ + private function cdiv($xr, $xi, $yr, $yi) { + if (abs($yr) > abs($yi)) { + $r = $yi / $yr; + $d = $yr + $r * $yi; + $this->cdivr = ($xr + $r * $xi) / $d; + $this->cdivi = ($xi - $r * $xr) / $d; + } else { + $r = $yr / $yi; + $d = $yi + $r * $yr; + $this->cdivr = ($r * $xr + $xi) / $d; + $this->cdivi = ($r * $xi - $xr) / $d; + } + } + + + /** + * Nonsymmetric reduction from Hessenberg to real Schur form. + * + * Code is derived from the Algol procedure hqr2, + * by Martin and Wilkinson, Handbook for Auto. Comp., + * Vol.ii-Linear Algebra, and the corresponding + * Fortran subroutine in EISPACK. + * + * @access private + */ + private function hqr2 () { + // Initialize + $nn = $this->n; + $n = $nn - 1; + $low = 0; + $high = $nn - 1; + $eps = pow(2.0, -52.0); + $exshift = 0.0; + $p = $q = $r = $s = $z = 0; + // Store roots isolated by balanc and compute matrix norm + $norm = 0.0; + + for ($i = 0; $i < $nn; ++$i) { + if (($i < $low) OR ($i > $high)) { + $this->d[$i] = $this->H[$i][$i]; + $this->e[$i] = 0.0; + } + for ($j = max($i-1, 0); $j < $nn; ++$j) { + $norm = $norm + abs($this->H[$i][$j]); + } + } + + // Outer loop over eigenvalue index + $iter = 0; + while ($n >= $low) { + // Look for single small sub-diagonal element + $l = $n; + while ($l > $low) { + $s = abs($this->H[$l-1][$l-1]) + abs($this->H[$l][$l]); + if ($s == 0.0) { + $s = $norm; + } + if (abs($this->H[$l][$l-1]) < $eps * $s) { + break; + } + --$l; + } + // Check for convergence + // One root found + if ($l == $n) { + $this->H[$n][$n] = $this->H[$n][$n] + $exshift; + $this->d[$n] = $this->H[$n][$n]; + $this->e[$n] = 0.0; + --$n; + $iter = 0; + // Two roots found + } else if ($l == $n-1) { + $w = $this->H[$n][$n-1] * $this->H[$n-1][$n]; + $p = ($this->H[$n-1][$n-1] - $this->H[$n][$n]) / 2.0; + $q = $p * $p + $w; + $z = sqrt(abs($q)); + $this->H[$n][$n] = $this->H[$n][$n] + $exshift; + $this->H[$n-1][$n-1] = $this->H[$n-1][$n-1] + $exshift; + $x = $this->H[$n][$n]; + // Real pair + if ($q >= 0) { + if ($p >= 0) { + $z = $p + $z; + } else { + $z = $p - $z; + } + $this->d[$n-1] = $x + $z; + $this->d[$n] = $this->d[$n-1]; + if ($z != 0.0) { + $this->d[$n] = $x - $w / $z; + } + $this->e[$n-1] = 0.0; + $this->e[$n] = 0.0; + $x = $this->H[$n][$n-1]; + $s = abs($x) + abs($z); + $p = $x / $s; + $q = $z / $s; + $r = sqrt($p * $p + $q * $q); + $p = $p / $r; + $q = $q / $r; + // Row modification + for ($j = $n-1; $j < $nn; ++$j) { + $z = $this->H[$n-1][$j]; + $this->H[$n-1][$j] = $q * $z + $p * $this->H[$n][$j]; + $this->H[$n][$j] = $q * $this->H[$n][$j] - $p * $z; + } + // Column modification + for ($i = 0; $i <= n; ++$i) { + $z = $this->H[$i][$n-1]; + $this->H[$i][$n-1] = $q * $z + $p * $this->H[$i][$n]; + $this->H[$i][$n] = $q * $this->H[$i][$n] - $p * $z; + } + // Accumulate transformations + for ($i = $low; $i <= $high; ++$i) { + $z = $this->V[$i][$n-1]; + $this->V[$i][$n-1] = $q * $z + $p * $this->V[$i][$n]; + $this->V[$i][$n] = $q * $this->V[$i][$n] - $p * $z; + } + // Complex pair + } else { + $this->d[$n-1] = $x + $p; + $this->d[$n] = $x + $p; + $this->e[$n-1] = $z; + $this->e[$n] = -$z; + } + $n = $n - 2; + $iter = 0; + // No convergence yet + } else { + // Form shift + $x = $this->H[$n][$n]; + $y = 0.0; + $w = 0.0; + if ($l < $n) { + $y = $this->H[$n-1][$n-1]; + $w = $this->H[$n][$n-1] * $this->H[$n-1][$n]; + } + // Wilkinson's original ad hoc shift + if ($iter == 10) { + $exshift += $x; + for ($i = $low; $i <= $n; ++$i) { + $this->H[$i][$i] -= $x; + } + $s = abs($this->H[$n][$n-1]) + abs($this->H[$n-1][$n-2]); + $x = $y = 0.75 * $s; + $w = -0.4375 * $s * $s; + } + // MATLAB's new ad hoc shift + if ($iter == 30) { + $s = ($y - $x) / 2.0; + $s = $s * $s + $w; + if ($s > 0) { + $s = sqrt($s); + if ($y < $x) { + $s = -$s; + } + $s = $x - $w / (($y - $x) / 2.0 + $s); + for ($i = $low; $i <= $n; ++$i) { + $this->H[$i][$i] -= $s; + } + $exshift += $s; + $x = $y = $w = 0.964; + } + } + // Could check iteration count here. + $iter = $iter + 1; + // Look for two consecutive small sub-diagonal elements + $m = $n - 2; + while ($m >= $l) { + $z = $this->H[$m][$m]; + $r = $x - $z; + $s = $y - $z; + $p = ($r * $s - $w) / $this->H[$m+1][$m] + $this->H[$m][$m+1]; + $q = $this->H[$m+1][$m+1] - $z - $r - $s; + $r = $this->H[$m+2][$m+1]; + $s = abs($p) + abs($q) + abs($r); + $p = $p / $s; + $q = $q / $s; + $r = $r / $s; + if ($m == $l) { + break; + } + if (abs($this->H[$m][$m-1]) * (abs($q) + abs($r)) < + $eps * (abs($p) * (abs($this->H[$m-1][$m-1]) + abs($z) + abs($this->H[$m+1][$m+1])))) { + break; + } + --$m; + } + for ($i = $m + 2; $i <= $n; ++$i) { + $this->H[$i][$i-2] = 0.0; + if ($i > $m+2) { + $this->H[$i][$i-3] = 0.0; + } + } + // Double QR step involving rows l:n and columns m:n + for ($k = $m; $k <= $n-1; ++$k) { + $notlast = ($k != $n-1); + if ($k != $m) { + $p = $this->H[$k][$k-1]; + $q = $this->H[$k+1][$k-1]; + $r = ($notlast ? $this->H[$k+2][$k-1] : 0.0); + $x = abs($p) + abs($q) + abs($r); + if ($x != 0.0) { + $p = $p / $x; + $q = $q / $x; + $r = $r / $x; + } + } + if ($x == 0.0) { + break; + } + $s = sqrt($p * $p + $q * $q + $r * $r); + if ($p < 0) { + $s = -$s; + } + if ($s != 0) { + if ($k != $m) { + $this->H[$k][$k-1] = -$s * $x; + } elseif ($l != $m) { + $this->H[$k][$k-1] = -$this->H[$k][$k-1]; + } + $p = $p + $s; + $x = $p / $s; + $y = $q / $s; + $z = $r / $s; + $q = $q / $p; + $r = $r / $p; + // Row modification + for ($j = $k; $j < $nn; ++$j) { + $p = $this->H[$k][$j] + $q * $this->H[$k+1][$j]; + if ($notlast) { + $p = $p + $r * $this->H[$k+2][$j]; + $this->H[$k+2][$j] = $this->H[$k+2][$j] - $p * $z; + } + $this->H[$k][$j] = $this->H[$k][$j] - $p * $x; + $this->H[$k+1][$j] = $this->H[$k+1][$j] - $p * $y; + } + // Column modification + for ($i = 0; $i <= min($n, $k+3); ++$i) { + $p = $x * $this->H[$i][$k] + $y * $this->H[$i][$k+1]; + if ($notlast) { + $p = $p + $z * $this->H[$i][$k+2]; + $this->H[$i][$k+2] = $this->H[$i][$k+2] - $p * $r; + } + $this->H[$i][$k] = $this->H[$i][$k] - $p; + $this->H[$i][$k+1] = $this->H[$i][$k+1] - $p * $q; + } + // Accumulate transformations + for ($i = $low; $i <= $high; ++$i) { + $p = $x * $this->V[$i][$k] + $y * $this->V[$i][$k+1]; + if ($notlast) { + $p = $p + $z * $this->V[$i][$k+2]; + $this->V[$i][$k+2] = $this->V[$i][$k+2] - $p * $r; + } + $this->V[$i][$k] = $this->V[$i][$k] - $p; + $this->V[$i][$k+1] = $this->V[$i][$k+1] - $p * $q; + } + } // ($s != 0) + } // k loop + } // check convergence + } // while ($n >= $low) + + // Backsubstitute to find vectors of upper triangular form + if ($norm == 0.0) { + return; + } + + for ($n = $nn-1; $n >= 0; --$n) { + $p = $this->d[$n]; + $q = $this->e[$n]; + // Real vector + if ($q == 0) { + $l = $n; + $this->H[$n][$n] = 1.0; + for ($i = $n-1; $i >= 0; --$i) { + $w = $this->H[$i][$i] - $p; + $r = 0.0; + for ($j = $l; $j <= $n; ++$j) { + $r = $r + $this->H[$i][$j] * $this->H[$j][$n]; + } + if ($this->e[$i] < 0.0) { + $z = $w; + $s = $r; + } else { + $l = $i; + if ($this->e[$i] == 0.0) { + if ($w != 0.0) { + $this->H[$i][$n] = -$r / $w; + } else { + $this->H[$i][$n] = -$r / ($eps * $norm); + } + // Solve real equations + } else { + $x = $this->H[$i][$i+1]; + $y = $this->H[$i+1][$i]; + $q = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i]; + $t = ($x * $s - $z * $r) / $q; + $this->H[$i][$n] = $t; + if (abs($x) > abs($z)) { + $this->H[$i+1][$n] = (-$r - $w * $t) / $x; + } else { + $this->H[$i+1][$n] = (-$s - $y * $t) / $z; + } + } + // Overflow control + $t = abs($this->H[$i][$n]); + if (($eps * $t) * $t > 1) { + for ($j = $i; $j <= $n; ++$j) { + $this->H[$j][$n] = $this->H[$j][$n] / $t; + } + } + } + } + // Complex vector + } else if ($q < 0) { + $l = $n-1; + // Last vector component imaginary so matrix is triangular + if (abs($this->H[$n][$n-1]) > abs($this->H[$n-1][$n])) { + $this->H[$n-1][$n-1] = $q / $this->H[$n][$n-1]; + $this->H[$n-1][$n] = -($this->H[$n][$n] - $p) / $this->H[$n][$n-1]; + } else { + $this->cdiv(0.0, -$this->H[$n-1][$n], $this->H[$n-1][$n-1] - $p, $q); + $this->H[$n-1][$n-1] = $this->cdivr; + $this->H[$n-1][$n] = $this->cdivi; + } + $this->H[$n][$n-1] = 0.0; + $this->H[$n][$n] = 1.0; + for ($i = $n-2; $i >= 0; --$i) { + // double ra,sa,vr,vi; + $ra = 0.0; + $sa = 0.0; + for ($j = $l; $j <= $n; ++$j) { + $ra = $ra + $this->H[$i][$j] * $this->H[$j][$n-1]; + $sa = $sa + $this->H[$i][$j] * $this->H[$j][$n]; + } + $w = $this->H[$i][$i] - $p; + if ($this->e[$i] < 0.0) { + $z = $w; + $r = $ra; + $s = $sa; + } else { + $l = $i; + if ($this->e[$i] == 0) { + $this->cdiv(-$ra, -$sa, $w, $q); + $this->H[$i][$n-1] = $this->cdivr; + $this->H[$i][$n] = $this->cdivi; + } else { + // Solve complex equations + $x = $this->H[$i][$i+1]; + $y = $this->H[$i+1][$i]; + $vr = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i] - $q * $q; + $vi = ($this->d[$i] - $p) * 2.0 * $q; + if ($vr == 0.0 & $vi == 0.0) { + $vr = $eps * $norm * (abs($w) + abs($q) + abs($x) + abs($y) + abs($z)); + } + $this->cdiv($x * $r - $z * $ra + $q * $sa, $x * $s - $z * $sa - $q * $ra, $vr, $vi); + $this->H[$i][$n-1] = $this->cdivr; + $this->H[$i][$n] = $this->cdivi; + if (abs($x) > (abs($z) + abs($q))) { + $this->H[$i+1][$n-1] = (-$ra - $w * $this->H[$i][$n-1] + $q * $this->H[$i][$n]) / $x; + $this->H[$i+1][$n] = (-$sa - $w * $this->H[$i][$n] - $q * $this->H[$i][$n-1]) / $x; + } else { + $this->cdiv(-$r - $y * $this->H[$i][$n-1], -$s - $y * $this->H[$i][$n], $z, $q); + $this->H[$i+1][$n-1] = $this->cdivr; + $this->H[$i+1][$n] = $this->cdivi; + } + } + // Overflow control + $t = max(abs($this->H[$i][$n-1]),abs($this->H[$i][$n])); + if (($eps * $t) * $t > 1) { + for ($j = $i; $j <= $n; ++$j) { + $this->H[$j][$n-1] = $this->H[$j][$n-1] / $t; + $this->H[$j][$n] = $this->H[$j][$n] / $t; + } + } + } // end else + } // end for + } // end else for complex case + } // end for + + // Vectors of isolated roots + for ($i = 0; $i < $nn; ++$i) { + if ($i < $low | $i > $high) { + for ($j = $i; $j < $nn; ++$j) { + $this->V[$i][$j] = $this->H[$i][$j]; + } + } + } + + // Back transformation to get eigenvectors of original matrix + for ($j = $nn-1; $j >= $low; --$j) { + for ($i = $low; $i <= $high; ++$i) { + $z = 0.0; + for ($k = $low; $k <= min($j,$high); ++$k) { + $z = $z + $this->V[$i][$k] * $this->H[$k][$j]; + } + $this->V[$i][$j] = $z; + } + } + } // end hqr2 + + + /** + * Constructor: Check for symmetry, then construct the eigenvalue decomposition + * + * @access public + * @param A Square matrix + * @return Structure to access D and V. + */ + public function __construct($Arg) { + $this->A = $Arg->getArray(); + $this->n = $Arg->getColumnDimension(); + + $issymmetric = true; + for ($j = 0; ($j < $this->n) & $issymmetric; ++$j) { + for ($i = 0; ($i < $this->n) & $issymmetric; ++$i) { + $issymmetric = ($this->A[$i][$j] == $this->A[$j][$i]); + } + } + + if ($issymmetric) { + $this->V = $this->A; + // Tridiagonalize. + $this->tred2(); + // Diagonalize. + $this->tql2(); + } else { + $this->H = $this->A; + $this->ort = array(); + // Reduce to Hessenberg form. + $this->orthes(); + // Reduce Hessenberg to real Schur form. + $this->hqr2(); + } + } + + + /** + * Return the eigenvector matrix + * + * @access public + * @return V + */ + public function getV() { + return new Matrix($this->V, $this->n, $this->n); + } + + + /** + * Return the real parts of the eigenvalues + * + * @access public + * @return real(diag(D)) + */ + public function getRealEigenvalues() { + return $this->d; + } + + + /** + * Return the imaginary parts of the eigenvalues + * + * @access public + * @return imag(diag(D)) + */ + public function getImagEigenvalues() { + return $this->e; + } + + + /** + * Return the block diagonal eigenvalue matrix + * + * @access public + * @return D + */ + public function getD() { + for ($i = 0; $i < $this->n; ++$i) { + $D[$i] = array_fill(0, $this->n, 0.0); + $D[$i][$i] = $this->d[$i]; + if ($this->e[$i] == 0) { + continue; + } + $o = ($this->e[$i] > 0) ? $i + 1 : $i - 1; + $D[$i][$o] = $this->e[$i]; + } + return new Matrix($D); + } + +} // class EigenvalueDecomposition diff --git a/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php b/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php index 08e500cf7..a4b226653 100644 --- a/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php @@ -1,258 +1,258 @@ <?php /** - * @package JAMA + * @package JAMA * - * For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n - * unit lower triangular matrix L, an n-by-n upper triangular matrix U, - * and a permutation vector piv of length m so that A(piv,:) = L*U. - * If m < n, then L is m-by-m and U is m-by-n. + * For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n + * unit lower triangular matrix L, an n-by-n upper triangular matrix U, + * and a permutation vector piv of length m so that A(piv,:) = L*U. + * If m < n, then L is m-by-m and U is m-by-n. * - * The LU decompostion with pivoting always exists, even if the matrix is - * singular, so the constructor will never fail. The primary use of the - * LU decomposition is in the solution of square systems of simultaneous - * linear equations. This will fail if isNonsingular() returns false. + * The LU decompostion with pivoting always exists, even if the matrix is + * singular, so the constructor will never fail. The primary use of the + * LU decomposition is in the solution of square systems of simultaneous + * linear equations. This will fail if isNonsingular() returns false. * - * @author Paul Meagher - * @author Bartosz Matosiuk - * @author Michael Bommarito - * @version 1.1 - * @license PHP v3.0 + * @author Paul Meagher + * @author Bartosz Matosiuk + * @author Michael Bommarito + * @version 1.1 + * @license PHP v3.0 */ class PHPExcel_Shared_JAMA_LUDecomposition { - const MatrixSingularException = "Can only perform operation on singular matrix."; - const MatrixSquareException = "Mismatched Row dimension"; + const MatrixSingularException = "Can only perform operation on singular matrix."; + const MatrixSquareException = "Mismatched Row dimension"; - /** - * Decomposition storage - * @var array - */ - private $LU = array(); + /** + * Decomposition storage + * @var array + */ + private $LU = array(); - /** - * Row dimension. - * @var int - */ - private $m; + /** + * Row dimension. + * @var int + */ + private $m; - /** - * Column dimension. - * @var int - */ - private $n; + /** + * Column dimension. + * @var int + */ + private $n; - /** - * Pivot sign. - * @var int - */ - private $pivsign; + /** + * Pivot sign. + * @var int + */ + private $pivsign; - /** - * Internal storage of pivot vector. - * @var array - */ - private $piv = array(); + /** + * Internal storage of pivot vector. + * @var array + */ + private $piv = array(); - /** - * LU Decomposition constructor. - * - * @param $A Rectangular matrix - * @return Structure to access L, U and piv. - */ - public function __construct($A) { - if ($A instanceof PHPExcel_Shared_JAMA_Matrix) { - // Use a "left-looking", dot-product, Crout/Doolittle algorithm. - $this->LU = $A->getArray(); - $this->m = $A->getRowDimension(); - $this->n = $A->getColumnDimension(); - for ($i = 0; $i < $this->m; ++$i) { - $this->piv[$i] = $i; - } - $this->pivsign = 1; - $LUrowi = $LUcolj = array(); + /** + * LU Decomposition constructor. + * + * @param $A Rectangular matrix + * @return Structure to access L, U and piv. + */ + public function __construct($A) { + if ($A instanceof PHPExcel_Shared_JAMA_Matrix) { + // Use a "left-looking", dot-product, Crout/Doolittle algorithm. + $this->LU = $A->getArray(); + $this->m = $A->getRowDimension(); + $this->n = $A->getColumnDimension(); + for ($i = 0; $i < $this->m; ++$i) { + $this->piv[$i] = $i; + } + $this->pivsign = 1; + $LUrowi = $LUcolj = array(); - // Outer loop. - for ($j = 0; $j < $this->n; ++$j) { - // Make a copy of the j-th column to localize references. - for ($i = 0; $i < $this->m; ++$i) { - $LUcolj[$i] = &$this->LU[$i][$j]; - } - // Apply previous transformations. - for ($i = 0; $i < $this->m; ++$i) { - $LUrowi = $this->LU[$i]; - // Most of the time is spent in the following dot product. - $kmax = min($i,$j); - $s = 0.0; - for ($k = 0; $k < $kmax; ++$k) { - $s += $LUrowi[$k] * $LUcolj[$k]; - } - $LUrowi[$j] = $LUcolj[$i] -= $s; - } - // Find pivot and exchange if necessary. - $p = $j; - for ($i = $j+1; $i < $this->m; ++$i) { - if (abs($LUcolj[$i]) > abs($LUcolj[$p])) { - $p = $i; - } - } - if ($p != $j) { - for ($k = 0; $k < $this->n; ++$k) { - $t = $this->LU[$p][$k]; - $this->LU[$p][$k] = $this->LU[$j][$k]; - $this->LU[$j][$k] = $t; - } - $k = $this->piv[$p]; - $this->piv[$p] = $this->piv[$j]; - $this->piv[$j] = $k; - $this->pivsign = $this->pivsign * -1; - } - // Compute multipliers. - if (($j < $this->m) && ($this->LU[$j][$j] != 0.0)) { - for ($i = $j+1; $i < $this->m; ++$i) { - $this->LU[$i][$j] /= $this->LU[$j][$j]; - } - } - } - } else { - throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException); - } - } // function __construct() + // Outer loop. + for ($j = 0; $j < $this->n; ++$j) { + // Make a copy of the j-th column to localize references. + for ($i = 0; $i < $this->m; ++$i) { + $LUcolj[$i] = &$this->LU[$i][$j]; + } + // Apply previous transformations. + for ($i = 0; $i < $this->m; ++$i) { + $LUrowi = $this->LU[$i]; + // Most of the time is spent in the following dot product. + $kmax = min($i,$j); + $s = 0.0; + for ($k = 0; $k < $kmax; ++$k) { + $s += $LUrowi[$k] * $LUcolj[$k]; + } + $LUrowi[$j] = $LUcolj[$i] -= $s; + } + // Find pivot and exchange if necessary. + $p = $j; + for ($i = $j+1; $i < $this->m; ++$i) { + if (abs($LUcolj[$i]) > abs($LUcolj[$p])) { + $p = $i; + } + } + if ($p != $j) { + for ($k = 0; $k < $this->n; ++$k) { + $t = $this->LU[$p][$k]; + $this->LU[$p][$k] = $this->LU[$j][$k]; + $this->LU[$j][$k] = $t; + } + $k = $this->piv[$p]; + $this->piv[$p] = $this->piv[$j]; + $this->piv[$j] = $k; + $this->pivsign = $this->pivsign * -1; + } + // Compute multipliers. + if (($j < $this->m) && ($this->LU[$j][$j] != 0.0)) { + for ($i = $j+1; $i < $this->m; ++$i) { + $this->LU[$i][$j] /= $this->LU[$j][$j]; + } + } + } + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException); + } + } // function __construct() - /** - * Get lower triangular factor. - * - * @return array Lower triangular factor - */ - public function getL() { - for ($i = 0; $i < $this->m; ++$i) { - for ($j = 0; $j < $this->n; ++$j) { - if ($i > $j) { - $L[$i][$j] = $this->LU[$i][$j]; - } elseif ($i == $j) { - $L[$i][$j] = 1.0; - } else { - $L[$i][$j] = 0.0; - } - } - } - return new PHPExcel_Shared_JAMA_Matrix($L); - } // function getL() + /** + * Get lower triangular factor. + * + * @return array Lower triangular factor + */ + public function getL() { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i > $j) { + $L[$i][$j] = $this->LU[$i][$j]; + } elseif ($i == $j) { + $L[$i][$j] = 1.0; + } else { + $L[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($L); + } // function getL() - /** - * Get upper triangular factor. - * - * @return array Upper triangular factor - */ - public function getU() { - for ($i = 0; $i < $this->n; ++$i) { - for ($j = 0; $j < $this->n; ++$j) { - if ($i <= $j) { - $U[$i][$j] = $this->LU[$i][$j]; - } else { - $U[$i][$j] = 0.0; - } - } - } - return new PHPExcel_Shared_JAMA_Matrix($U); - } // function getU() + /** + * Get upper triangular factor. + * + * @return array Upper triangular factor + */ + public function getU() { + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i <= $j) { + $U[$i][$j] = $this->LU[$i][$j]; + } else { + $U[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($U); + } // function getU() - /** - * Return pivot permutation vector. - * - * @return array Pivot vector - */ - public function getPivot() { - return $this->piv; - } // function getPivot() + /** + * Return pivot permutation vector. + * + * @return array Pivot vector + */ + public function getPivot() { + return $this->piv; + } // function getPivot() - /** - * Alias for getPivot - * - * @see getPivot - */ - public function getDoublePivot() { - return $this->getPivot(); - } // function getDoublePivot() + /** + * Alias for getPivot + * + * @see getPivot + */ + public function getDoublePivot() { + return $this->getPivot(); + } // function getDoublePivot() - /** - * Is the matrix nonsingular? - * - * @return true if U, and hence A, is nonsingular. - */ - public function isNonsingular() { - for ($j = 0; $j < $this->n; ++$j) { - if ($this->LU[$j][$j] == 0) { - return false; - } - } - return true; - } // function isNonsingular() + /** + * Is the matrix nonsingular? + * + * @return true if U, and hence A, is nonsingular. + */ + public function isNonsingular() { + for ($j = 0; $j < $this->n; ++$j) { + if ($this->LU[$j][$j] == 0) { + return false; + } + } + return true; + } // function isNonsingular() - /** - * Count determinants - * - * @return array d matrix deterninat - */ - public function det() { - if ($this->m == $this->n) { - $d = $this->pivsign; - for ($j = 0; $j < $this->n; ++$j) { - $d *= $this->LU[$j][$j]; - } - return $d; - } else { - throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); - } - } // function det() + /** + * Count determinants + * + * @return array d matrix deterninat + */ + public function det() { + if ($this->m == $this->n) { + $d = $this->pivsign; + for ($j = 0; $j < $this->n; ++$j) { + $d *= $this->LU[$j][$j]; + } + return $d; + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); + } + } // function det() - /** - * Solve A*X = B - * - * @param $B A Matrix with as many rows as A and any number of columns. - * @return X so that L*U*X = B(piv,:) - * @PHPExcel_Calculation_Exception IllegalArgumentException Matrix row dimensions must agree. - * @PHPExcel_Calculation_Exception RuntimeException Matrix is singular. - */ - public function solve($B) { - if ($B->getRowDimension() == $this->m) { - if ($this->isNonsingular()) { - // Copy right hand side with pivoting - $nx = $B->getColumnDimension(); - $X = $B->getMatrix($this->piv, 0, $nx-1); - // Solve L*Y = B(piv,:) - for ($k = 0; $k < $this->n; ++$k) { - for ($i = $k+1; $i < $this->n; ++$i) { - for ($j = 0; $j < $nx; ++$j) { - $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k]; - } - } - } - // Solve U*X = Y; - for ($k = $this->n-1; $k >= 0; --$k) { - for ($j = 0; $j < $nx; ++$j) { - $X->A[$k][$j] /= $this->LU[$k][$k]; - } - for ($i = 0; $i < $k; ++$i) { - for ($j = 0; $j < $nx; ++$j) { - $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k]; - } - } - } - return $X; - } else { - throw new PHPExcel_Calculation_Exception(self::MatrixSingularException); - } - } else { - throw new PHPExcel_Calculation_Exception(self::MatrixSquareException); - } - } // function solve() + /** + * Solve A*X = B + * + * @param $B A Matrix with as many rows as A and any number of columns. + * @return X so that L*U*X = B(piv,:) + * @PHPExcel_Calculation_Exception IllegalArgumentException Matrix row dimensions must agree. + * @PHPExcel_Calculation_Exception RuntimeException Matrix is singular. + */ + public function solve($B) { + if ($B->getRowDimension() == $this->m) { + if ($this->isNonsingular()) { + // Copy right hand side with pivoting + $nx = $B->getColumnDimension(); + $X = $B->getMatrix($this->piv, 0, $nx-1); + // Solve L*Y = B(piv,:) + for ($k = 0; $k < $this->n; ++$k) { + for ($i = $k+1; $i < $this->n; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k]; + } + } + } + // Solve U*X = Y; + for ($k = $this->n-1; $k >= 0; --$k) { + for ($j = 0; $j < $nx; ++$j) { + $X->A[$k][$j] /= $this->LU[$k][$k]; + } + for ($i = 0; $i < $k; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k]; + } + } + } + return $X; + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixSingularException); + } + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixSquareException); + } + } // function solve() -} // class PHPExcel_Shared_JAMA_LUDecomposition +} // class PHPExcel_Shared_JAMA_LUDecomposition diff --git a/Classes/PHPExcel/Shared/JAMA/Matrix.php b/Classes/PHPExcel/Shared/JAMA/Matrix.php index 1e7c334ac..8d5e39d86 100644 --- a/Classes/PHPExcel/Shared/JAMA/Matrix.php +++ b/Classes/PHPExcel/Shared/JAMA/Matrix.php @@ -5,1053 +5,1053 @@ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } /* - * Matrix class + * Matrix class * - * @author Paul Meagher - * @author Michael Bommarito - * @author Lukasz Karapuda - * @author Bartek Matosiuk - * @version 1.8 - * @license PHP v3.0 - * @see http://math.nist.gov/javanumerics/jama/ + * @author Paul Meagher + * @author Michael Bommarito + * @author Lukasz Karapuda + * @author Bartek Matosiuk + * @version 1.8 + * @license PHP v3.0 + * @see http://math.nist.gov/javanumerics/jama/ */ class PHPExcel_Shared_JAMA_Matrix { - const PolymorphicArgumentException = "Invalid argument pattern for polymorphic function."; - const ArgumentTypeException = "Invalid argument type."; - const ArgumentBoundsException = "Invalid argument range."; - const MatrixDimensionException = "Matrix dimensions are not equal."; - const ArrayLengthException = "Array length must be a multiple of m."; - - /** - * Matrix storage - * - * @var array - * @access public - */ - public $A = array(); - - /** - * Matrix row dimension - * - * @var int - * @access private - */ - private $m; - - /** - * Matrix column dimension - * - * @var int - * @access private - */ - private $n; - - - /** - * Polymorphic constructor - * - * As PHP has no support for polymorphic constructors, we hack our own sort of polymorphism using func_num_args, func_get_arg, and gettype. In essence, we're just implementing a simple RTTI filter and calling the appropriate constructor. - */ - public function __construct() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - //Rectangular matrix - m x n initialized from 2D array - case 'array': - $this->m = count($args[0]); - $this->n = count($args[0][0]); - $this->A = $args[0]; - break; - //Square matrix - n x n - case 'integer': - $this->m = $args[0]; - $this->n = $args[0]; - $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); - break; - //Rectangular matrix - m x n - case 'integer,integer': - $this->m = $args[0]; - $this->n = $args[1]; - $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); - break; - //Rectangular matrix - m x n initialized from packed array - case 'array,integer': - $this->m = $args[1]; - if ($this->m != 0) { - $this->n = count($args[0]) / $this->m; - } else { - $this->n = 0; - } - if (($this->m * $this->n) == count($args[0])) { - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $this->A[$i][$j] = $args[0][$i + $j * $this->m]; - } - } - } else { - throw new PHPExcel_Calculation_Exception(self::ArrayLengthException); - } - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function __construct() - - - /** - * getArray - * - * @return array Matrix array - */ - public function getArray() { - return $this->A; - } // function getArray() - - - /** - * getRowDimension - * - * @return int Row dimension - */ - public function getRowDimension() { - return $this->m; - } // function getRowDimension() - - - /** - * getColumnDimension - * - * @return int Column dimension - */ - public function getColumnDimension() { - return $this->n; - } // function getColumnDimension() - - - /** - * get - * - * Get the i,j-th element of the matrix. - * @param int $i Row position - * @param int $j Column position - * @return mixed Element (int/float/double) - */ - public function get($i = null, $j = null) { - return $this->A[$i][$j]; - } // function get() - - - /** - * getMatrix - * - * Get a submatrix - * @param int $i0 Initial row index - * @param int $iF Final row index - * @param int $j0 Initial column index - * @param int $jF Final column index - * @return Matrix Submatrix - */ - public function getMatrix() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - //A($i0...; $j0...) - case 'integer,integer': - list($i0, $j0) = $args; - if ($i0 >= 0) { $m = $this->m - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if ($j0 >= 0) { $n = $this->n - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = $i0; $i < $this->m; ++$i) { - for($j = $j0; $j < $this->n; ++$j) { - $R->set($i, $j, $this->A[$i][$j]); - } - } - return $R; - break; - //A($i0...$iF; $j0...$jF) - case 'integer,integer,integer,integer': - list($i0, $iF, $j0, $jF) = $args; - if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1); - for($i = $i0; $i <= $iF; ++$i) { - for($j = $j0; $j <= $jF; ++$j) { - $R->set($i - $i0, $j - $j0, $this->A[$i][$j]); - } - } - return $R; - break; - //$R = array of row indices; $C = array of column indices - case 'array,array': - list($RL, $CL) = $args; - if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = 0; $i < $m; ++$i) { - for($j = 0; $j < $n; ++$j) { - $R->set($i - $i0, $j - $j0, $this->A[$RL[$i]][$CL[$j]]); - } - } - return $R; - break; - //$RL = array of row indices; $CL = array of column indices - case 'array,array': - list($RL, $CL) = $args; - if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = 0; $i < $m; ++$i) { - for($j = 0; $j < $n; ++$j) { - $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]); - } - } - return $R; - break; - //A($i0...$iF); $CL = array of column indices - case 'integer,integer,array': - list($i0, $iF, $CL) = $args; - if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = $i0; $i < $iF; ++$i) { - for($j = 0; $j < $n; ++$j) { - $R->set($i - $i0, $j, $this->A[$RL[$i]][$j]); - } - } - return $R; - break; - //$RL = array of row indices - case 'array,integer,integer': - list($RL, $j0, $jF) = $args; - if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n+1); - for($i = 0; $i < $m; ++$i) { - for($j = $j0; $j <= $jF; ++$j) { - $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]); - } - } - return $R; - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function getMatrix() - - - /** - * checkMatrixDimensions - * - * Is matrix B the same size? - * @param Matrix $B Matrix B - * @return boolean - */ - public function checkMatrixDimensions($B = null) { - if ($B instanceof PHPExcel_Shared_JAMA_Matrix) { - if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) { - return true; - } else { - throw new PHPExcel_Calculation_Exception(self::MatrixDimensionException); - } - } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); - } - } // function checkMatrixDimensions() - - - - /** - * set - * - * Set the i,j-th element of the matrix. - * @param int $i Row position - * @param int $j Column position - * @param mixed $c Int/float/double value - * @return mixed Element (int/float/double) - */ - public function set($i = null, $j = null, $c = null) { - // Optimized set version just has this - $this->A[$i][$j] = $c; - } // function set() - - - /** - * identity - * - * Generate an identity matrix. - * @param int $m Row dimension - * @param int $n Column dimension - * @return Matrix Identity matrix - */ - public function identity($m = null, $n = null) { - return $this->diagonal($m, $n, 1); - } // function identity() - - - /** - * diagonal - * - * Generate a diagonal matrix - * @param int $m Row dimension - * @param int $n Column dimension - * @param mixed $c Diagonal value - * @return Matrix Diagonal matrix - */ - public function diagonal($m = null, $n = null, $c = 1) { - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = 0; $i < $m; ++$i) { - $R->set($i, $i, $c); - } - return $R; - } // function diagonal() - - - /** - * getMatrixByRow - * - * Get a submatrix by row index/range - * @param int $i0 Initial row index - * @param int $iF Final row index - * @return Matrix Submatrix - */ - public function getMatrixByRow($i0 = null, $iF = null) { - if (is_int($i0)) { - if (is_int($iF)) { - return $this->getMatrix($i0, 0, $iF + 1, $this->n); - } else { - return $this->getMatrix($i0, 0, $i0 + 1, $this->n); - } - } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); - } - } // function getMatrixByRow() - - - /** - * getMatrixByCol - * - * Get a submatrix by column index/range - * @param int $i0 Initial column index - * @param int $iF Final column index - * @return Matrix Submatrix - */ - public function getMatrixByCol($j0 = null, $jF = null) { - if (is_int($j0)) { - if (is_int($jF)) { - return $this->getMatrix(0, $j0, $this->m, $jF + 1); - } else { - return $this->getMatrix(0, $j0, $this->m, $j0 + 1); - } - } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); - } - } // function getMatrixByCol() - - - /** - * transpose - * - * Tranpose matrix - * @return Matrix Transposed matrix - */ - public function transpose() { - $R = new PHPExcel_Shared_JAMA_Matrix($this->n, $this->m); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $R->set($j, $i, $this->A[$i][$j]); - } - } - return $R; - } // function transpose() - - - /** - * trace - * - * Sum of diagonal elements - * @return float Sum of diagonal elements - */ - public function trace() { - $s = 0; - $n = min($this->m, $this->n); - for($i = 0; $i < $n; ++$i) { - $s += $this->A[$i][$i]; - } - return $s; - } // function trace() - - - /** - * uminus - * - * Unary minus matrix -A - * @return Matrix Unary minus matrix - */ - public function uminus() { - } // function uminus() - - - /** - * plus - * - * A + B - * @param mixed $B Matrix/Array - * @return Matrix Sum - */ - public function plus() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]); - } - } - return $M; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function plus() - - - /** - * plusEquals - * - * A = A + B - * @param mixed $B Matrix/Array - * @return Matrix Sum - */ - public function plusEquals() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $validValues = True; - $value = $M->get($i, $j); - if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"'); - $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); - } - if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value,'"'); - $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); - } - if ($validValues) { - $this->A[$i][$j] += $value; - } else { - $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); - } - } - } - return $this; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function plusEquals() - - - /** - * minus - * - * A - B - * @param mixed $B Matrix/Array - * @return Matrix Sum - */ - public function minus() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $M->set($i, $j, $M->get($i, $j) - $this->A[$i][$j]); - } - } - return $M; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function minus() - - - /** - * minusEquals - * - * A = A - B - * @param mixed $B Matrix/Array - * @return Matrix Sum - */ - public function minusEquals() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $validValues = True; - $value = $M->get($i, $j); - if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"'); - $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); - } - if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value,'"'); - $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); - } - if ($validValues) { - $this->A[$i][$j] -= $value; - } else { - $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); - } - } - } - return $this; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function minusEquals() - - - /** - * arrayTimes - * - * Element-by-element multiplication - * Cij = Aij * Bij - * @param mixed $B Matrix/Array - * @return Matrix Matrix Cij - */ - public function arrayTimes() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $M->set($i, $j, $M->get($i, $j) * $this->A[$i][$j]); - } - } - return $M; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function arrayTimes() - - - /** - * arrayTimesEquals - * - * Element-by-element multiplication - * Aij = Aij * Bij - * @param mixed $B Matrix/Array - * @return Matrix Matrix Aij - */ - public function arrayTimesEquals() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $validValues = True; - $value = $M->get($i, $j); - if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"'); - $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); - } - if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value,'"'); - $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); - } - if ($validValues) { - $this->A[$i][$j] *= $value; - } else { - $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); - } - } - } - return $this; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function arrayTimesEquals() - - - /** - * arrayRightDivide - * - * Element-by-element right division - * A / B - * @param Matrix $B Matrix B - * @return Matrix Division result - */ - public function arrayRightDivide() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $validValues = True; - $value = $M->get($i, $j); - if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"'); - $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); - } - if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value,'"'); - $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); - } - if ($validValues) { - if ($value == 0) { - // Trap for Divide by Zero error - $M->set($i, $j, '#DIV/0!'); - } else { - $M->set($i, $j, $this->A[$i][$j] / $value); - } - } else { - $M->set($i, $j, PHPExcel_Calculation_Functions::NaN()); - } - } - } - return $M; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function arrayRightDivide() - - - /** - * arrayRightDivideEquals - * - * Element-by-element right division - * Aij = Aij / Bij - * @param mixed $B Matrix/Array - * @return Matrix Matrix Aij - */ - public function arrayRightDivideEquals() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $this->A[$i][$j] = $this->A[$i][$j] / $M->get($i, $j); - } - } - return $M; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function arrayRightDivideEquals() - - - /** - * arrayLeftDivide - * - * Element-by-element Left division - * A / B - * @param Matrix $B Matrix B - * @return Matrix Division result - */ - public function arrayLeftDivide() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $M->set($i, $j, $M->get($i, $j) / $this->A[$i][$j]); - } - } - return $M; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function arrayLeftDivide() - - - /** - * arrayLeftDivideEquals - * - * Element-by-element Left division - * Aij = Aij / Bij - * @param mixed $B Matrix/Array - * @return Matrix Matrix Aij - */ - public function arrayLeftDivideEquals() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $this->A[$i][$j] = $M->get($i, $j) / $this->A[$i][$j]; - } - } - return $M; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function arrayLeftDivideEquals() - - - /** - * times - * - * Matrix multiplication - * @param mixed $n Matrix/Array/Scalar - * @return Matrix Product - */ - public function times() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $B = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - if ($this->n == $B->m) { - $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); - for($j = 0; $j < $B->n; ++$j) { - for ($k = 0; $k < $this->n; ++$k) { - $Bcolj[$k] = $B->A[$k][$j]; - } - for($i = 0; $i < $this->m; ++$i) { - $Arowi = $this->A[$i]; - $s = 0; - for($k = 0; $k < $this->n; ++$k) { - $s += $Arowi[$k] * $Bcolj[$k]; - } - $C->A[$i][$j] = $s; - } - } - return $C; - } else { - throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); - } - break; - case 'array': - $B = new PHPExcel_Shared_JAMA_Matrix($args[0]); - if ($this->n == $B->m) { - $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { - $s = "0"; - for($k = 0; $k < $C->n; ++$k) { - $s += $this->A[$i][$k] * $B->A[$k][$j]; - } - $C->A[$i][$j] = $s; - } - } - return $C; - } else { - throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); - } - return $M; - break; - case 'integer': - $C = new PHPExcel_Shared_JAMA_Matrix($this->A); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { - $C->A[$i][$j] *= $args[0]; - } - } - return $C; - break; - case 'double': - $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $this->n); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { - $C->A[$i][$j] = $args[0] * $this->A[$i][$j]; - } - } - return $C; - break; - case 'float': - $C = new PHPExcel_Shared_JAMA_Matrix($this->A); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { - $C->A[$i][$j] *= $args[0]; - } - } - return $C; - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function times() - - - /** - * power - * - * A = A ^ B - * @param mixed $B Matrix/Array - * @return Matrix Sum - */ - public function power() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $validValues = True; - $value = $M->get($i, $j); - if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"'); - $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); - } - if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value,'"'); - $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); - } - if ($validValues) { - $this->A[$i][$j] = pow($this->A[$i][$j],$value); - } else { - $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); - } - } - } - return $this; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function power() - - - /** - * concat - * - * A = A & B - * @param mixed $B Matrix/Array - * @return Matrix Sum - */ - public function concat() { - if (func_num_args() > 0) { - $args = func_get_args(); - $match = implode(",", array_map('gettype', $args)); - - switch($match) { - case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; - default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; - } - $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"').trim($M->get($i, $j),'"'); - } - } - return $this; - } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - } - } // function concat() - - - /** - * Solve A*X = B. - * - * @param Matrix $B Right hand side - * @return Matrix ... Solution if A is square, least squares solution otherwise - */ - public function solve($B) { - if ($this->m == $this->n) { - $LU = new PHPExcel_Shared_JAMA_LUDecomposition($this); - return $LU->solve($B); - } else { - $QR = new PHPExcel_Shared_JAMA_QRDecomposition($this); - return $QR->solve($B); - } - } // function solve() - - - /** - * Matrix inverse or pseudoinverse. - * - * @return Matrix ... Inverse(A) if A is square, pseudoinverse otherwise. - */ - public function inverse() { - return $this->solve($this->identity($this->m, $this->m)); - } // function inverse() - - - /** - * det - * - * Calculate determinant - * @return float Determinant - */ - public function det() { - $L = new PHPExcel_Shared_JAMA_LUDecomposition($this); - return $L->det(); - } // function det() -} // class PHPExcel_Shared_JAMA_Matrix + const PolymorphicArgumentException = "Invalid argument pattern for polymorphic function."; + const ArgumentTypeException = "Invalid argument type."; + const ArgumentBoundsException = "Invalid argument range."; + const MatrixDimensionException = "Matrix dimensions are not equal."; + const ArrayLengthException = "Array length must be a multiple of m."; + + /** + * Matrix storage + * + * @var array + * @access public + */ + public $A = array(); + + /** + * Matrix row dimension + * + * @var int + * @access private + */ + private $m; + + /** + * Matrix column dimension + * + * @var int + * @access private + */ + private $n; + + + /** + * Polymorphic constructor + * + * As PHP has no support for polymorphic constructors, we hack our own sort of polymorphism using func_num_args, func_get_arg, and gettype. In essence, we're just implementing a simple RTTI filter and calling the appropriate constructor. + */ + public function __construct() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + //Rectangular matrix - m x n initialized from 2D array + case 'array': + $this->m = count($args[0]); + $this->n = count($args[0][0]); + $this->A = $args[0]; + break; + //Square matrix - n x n + case 'integer': + $this->m = $args[0]; + $this->n = $args[0]; + $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); + break; + //Rectangular matrix - m x n + case 'integer,integer': + $this->m = $args[0]; + $this->n = $args[1]; + $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); + break; + //Rectangular matrix - m x n initialized from packed array + case 'array,integer': + $this->m = $args[1]; + if ($this->m != 0) { + $this->n = count($args[0]) / $this->m; + } else { + $this->n = 0; + } + if (($this->m * $this->n) == count($args[0])) { + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = $args[0][$i + $j * $this->m]; + } + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArrayLengthException); + } + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function __construct() + + + /** + * getArray + * + * @return array Matrix array + */ + public function getArray() { + return $this->A; + } // function getArray() + + + /** + * getRowDimension + * + * @return int Row dimension + */ + public function getRowDimension() { + return $this->m; + } // function getRowDimension() + + + /** + * getColumnDimension + * + * @return int Column dimension + */ + public function getColumnDimension() { + return $this->n; + } // function getColumnDimension() + + + /** + * get + * + * Get the i,j-th element of the matrix. + * @param int $i Row position + * @param int $j Column position + * @return mixed Element (int/float/double) + */ + public function get($i = null, $j = null) { + return $this->A[$i][$j]; + } // function get() + + + /** + * getMatrix + * + * Get a submatrix + * @param int $i0 Initial row index + * @param int $iF Final row index + * @param int $j0 Initial column index + * @param int $jF Final column index + * @return Matrix Submatrix + */ + public function getMatrix() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + //A($i0...; $j0...) + case 'integer,integer': + list($i0, $j0) = $args; + if ($i0 >= 0) { $m = $this->m - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if ($j0 >= 0) { $n = $this->n - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = $i0; $i < $this->m; ++$i) { + for($j = $j0; $j < $this->n; ++$j) { + $R->set($i, $j, $this->A[$i][$j]); + } + } + return $R; + break; + //A($i0...$iF; $j0...$jF) + case 'integer,integer,integer,integer': + list($i0, $iF, $j0, $jF) = $args; + if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1); + for($i = $i0; $i <= $iF; ++$i) { + for($j = $j0; $j <= $jF; ++$j) { + $R->set($i - $i0, $j - $j0, $this->A[$i][$j]); + } + } + return $R; + break; + //$R = array of row indices; $C = array of column indices + case 'array,array': + list($RL, $CL) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i - $i0, $j - $j0, $this->A[$RL[$i]][$CL[$j]]); + } + } + return $R; + break; + //$RL = array of row indices; $CL = array of column indices + case 'array,array': + list($RL, $CL) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]); + } + } + return $R; + break; + //A($i0...$iF); $CL = array of column indices + case 'integer,integer,array': + list($i0, $iF, $CL) = $args; + if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = $i0; $i < $iF; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i - $i0, $j, $this->A[$RL[$i]][$j]); + } + } + return $R; + break; + //$RL = array of row indices + case 'array,integer,integer': + list($RL, $j0, $jF) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n+1); + for($i = 0; $i < $m; ++$i) { + for($j = $j0; $j <= $jF; ++$j) { + $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]); + } + } + return $R; + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function getMatrix() + + + /** + * checkMatrixDimensions + * + * Is matrix B the same size? + * @param Matrix $B Matrix B + * @return boolean + */ + public function checkMatrixDimensions($B = null) { + if ($B instanceof PHPExcel_Shared_JAMA_Matrix) { + if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) { + return true; + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixDimensionException); + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + } // function checkMatrixDimensions() + + + + /** + * set + * + * Set the i,j-th element of the matrix. + * @param int $i Row position + * @param int $j Column position + * @param mixed $c Int/float/double value + * @return mixed Element (int/float/double) + */ + public function set($i = null, $j = null, $c = null) { + // Optimized set version just has this + $this->A[$i][$j] = $c; + } // function set() + + + /** + * identity + * + * Generate an identity matrix. + * @param int $m Row dimension + * @param int $n Column dimension + * @return Matrix Identity matrix + */ + public function identity($m = null, $n = null) { + return $this->diagonal($m, $n, 1); + } // function identity() + + + /** + * diagonal + * + * Generate a diagonal matrix + * @param int $m Row dimension + * @param int $n Column dimension + * @param mixed $c Diagonal value + * @return Matrix Diagonal matrix + */ + public function diagonal($m = null, $n = null, $c = 1) { + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + $R->set($i, $i, $c); + } + return $R; + } // function diagonal() + + + /** + * getMatrixByRow + * + * Get a submatrix by row index/range + * @param int $i0 Initial row index + * @param int $iF Final row index + * @return Matrix Submatrix + */ + public function getMatrixByRow($i0 = null, $iF = null) { + if (is_int($i0)) { + if (is_int($iF)) { + return $this->getMatrix($i0, 0, $iF + 1, $this->n); + } else { + return $this->getMatrix($i0, 0, $i0 + 1, $this->n); + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + } // function getMatrixByRow() + + + /** + * getMatrixByCol + * + * Get a submatrix by column index/range + * @param int $i0 Initial column index + * @param int $iF Final column index + * @return Matrix Submatrix + */ + public function getMatrixByCol($j0 = null, $jF = null) { + if (is_int($j0)) { + if (is_int($jF)) { + return $this->getMatrix(0, $j0, $this->m, $jF + 1); + } else { + return $this->getMatrix(0, $j0, $this->m, $j0 + 1); + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + } // function getMatrixByCol() + + + /** + * transpose + * + * Tranpose matrix + * @return Matrix Transposed matrix + */ + public function transpose() { + $R = new PHPExcel_Shared_JAMA_Matrix($this->n, $this->m); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $R->set($j, $i, $this->A[$i][$j]); + } + } + return $R; + } // function transpose() + + + /** + * trace + * + * Sum of diagonal elements + * @return float Sum of diagonal elements + */ + public function trace() { + $s = 0; + $n = min($this->m, $this->n); + for($i = 0; $i < $n; ++$i) { + $s += $this->A[$i][$i]; + } + return $s; + } // function trace() + + + /** + * uminus + * + * Unary minus matrix -A + * @return Matrix Unary minus matrix + */ + public function uminus() { + } // function uminus() + + + /** + * plus + * + * A + B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function plus() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function plus() + + + /** + * plusEquals + * + * A = A + B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function plusEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] += $value; + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function plusEquals() + + + /** + * minus + * + * A - B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function minus() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) - $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function minus() + + + /** + * minusEquals + * + * A = A - B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function minusEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] -= $value; + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function minusEquals() + + + /** + * arrayTimes + * + * Element-by-element multiplication + * Cij = Aij * Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Cij + */ + public function arrayTimes() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) * $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayTimes() + + + /** + * arrayTimesEquals + * + * Element-by-element multiplication + * Aij = Aij * Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Aij + */ + public function arrayTimesEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] *= $value; + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayTimesEquals() + + + /** + * arrayRightDivide + * + * Element-by-element right division + * A / B + * @param Matrix $B Matrix B + * @return Matrix Division result + */ + public function arrayRightDivide() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + if ($value == 0) { + // Trap for Divide by Zero error + $M->set($i, $j, '#DIV/0!'); + } else { + $M->set($i, $j, $this->A[$i][$j] / $value); + } + } else { + $M->set($i, $j, PHPExcel_Calculation_Functions::NaN()); + } + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayRightDivide() + + + /** + * arrayRightDivideEquals + * + * Element-by-element right division + * Aij = Aij / Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Aij + */ + public function arrayRightDivideEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = $this->A[$i][$j] / $M->get($i, $j); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayRightDivideEquals() + + + /** + * arrayLeftDivide + * + * Element-by-element Left division + * A / B + * @param Matrix $B Matrix B + * @return Matrix Division result + */ + public function arrayLeftDivide() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) / $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayLeftDivide() + + + /** + * arrayLeftDivideEquals + * + * Element-by-element Left division + * Aij = Aij / Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Aij + */ + public function arrayLeftDivideEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = $M->get($i, $j) / $this->A[$i][$j]; + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayLeftDivideEquals() + + + /** + * times + * + * Matrix multiplication + * @param mixed $n Matrix/Array/Scalar + * @return Matrix Product + */ + public function times() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $B = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + if ($this->n == $B->m) { + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); + for($j = 0; $j < $B->n; ++$j) { + for ($k = 0; $k < $this->n; ++$k) { + $Bcolj[$k] = $B->A[$k][$j]; + } + for($i = 0; $i < $this->m; ++$i) { + $Arowi = $this->A[$i]; + $s = 0; + for($k = 0; $k < $this->n; ++$k) { + $s += $Arowi[$k] * $Bcolj[$k]; + } + $C->A[$i][$j] = $s; + } + } + return $C; + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); + } + break; + case 'array': + $B = new PHPExcel_Shared_JAMA_Matrix($args[0]); + if ($this->n == $B->m) { + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $s = "0"; + for($k = 0; $k < $C->n; ++$k) { + $s += $this->A[$i][$k] * $B->A[$k][$j]; + } + $C->A[$i][$j] = $s; + } + } + return $C; + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); + } + return $M; + break; + case 'integer': + $C = new PHPExcel_Shared_JAMA_Matrix($this->A); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] *= $args[0]; + } + } + return $C; + break; + case 'double': + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $this->n); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] = $args[0] * $this->A[$i][$j]; + } + } + return $C; + break; + case 'float': + $C = new PHPExcel_Shared_JAMA_Matrix($this->A); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] *= $args[0]; + } + } + return $C; + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function times() + + + /** + * power + * + * A = A ^ B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function power() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] = pow($this->A[$i][$j],$value); + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function power() + + + /** + * concat + * + * A = A & B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function concat() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"').trim($M->get($i, $j),'"'); + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function concat() + + + /** + * Solve A*X = B. + * + * @param Matrix $B Right hand side + * @return Matrix ... Solution if A is square, least squares solution otherwise + */ + public function solve($B) { + if ($this->m == $this->n) { + $LU = new PHPExcel_Shared_JAMA_LUDecomposition($this); + return $LU->solve($B); + } else { + $QR = new PHPExcel_Shared_JAMA_QRDecomposition($this); + return $QR->solve($B); + } + } // function solve() + + + /** + * Matrix inverse or pseudoinverse. + * + * @return Matrix ... Inverse(A) if A is square, pseudoinverse otherwise. + */ + public function inverse() { + return $this->solve($this->identity($this->m, $this->m)); + } // function inverse() + + + /** + * det + * + * Calculate determinant + * @return float Determinant + */ + public function det() { + $L = new PHPExcel_Shared_JAMA_LUDecomposition($this); + return $L->det(); + } // function det() +} // class PHPExcel_Shared_JAMA_Matrix diff --git a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php index 753846298..17c443573 100644 --- a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php @@ -1,234 +1,234 @@ <?php /** - * @package JAMA + * @package JAMA * - * For an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n - * orthogonal matrix Q and an n-by-n upper triangular matrix R so that - * A = Q*R. + * For an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n + * orthogonal matrix Q and an n-by-n upper triangular matrix R so that + * A = Q*R. * - * The QR decompostion always exists, even if the matrix does not have - * full rank, so the constructor will never fail. The primary use of the - * QR decomposition is in the least squares solution of nonsquare systems - * of simultaneous linear equations. This will fail if isFullRank() - * returns false. + * The QR decompostion always exists, even if the matrix does not have + * full rank, so the constructor will never fail. The primary use of the + * QR decomposition is in the least squares solution of nonsquare systems + * of simultaneous linear equations. This will fail if isFullRank() + * returns false. * - * @author Paul Meagher - * @license PHP v3.0 - * @version 1.1 + * @author Paul Meagher + * @license PHP v3.0 + * @version 1.1 */ class PHPExcel_Shared_JAMA_QRDecomposition { - const MatrixRankException = "Can only perform operation on full-rank matrix."; - - /** - * Array for internal storage of decomposition. - * @var array - */ - private $QR = array(); - - /** - * Row dimension. - * @var integer - */ - private $m; - - /** - * Column dimension. - * @var integer - */ - private $n; - - /** - * Array for internal storage of diagonal of R. - * @var array - */ - private $Rdiag = array(); - - - /** - * QR Decomposition computed by Householder reflections. - * - * @param matrix $A Rectangular matrix - * @return Structure to access R and the Householder vectors and compute Q. - */ - public function __construct($A) { - if($A instanceof PHPExcel_Shared_JAMA_Matrix) { - // Initialize. - $this->QR = $A->getArrayCopy(); - $this->m = $A->getRowDimension(); - $this->n = $A->getColumnDimension(); - // Main loop. - for ($k = 0; $k < $this->n; ++$k) { - // Compute 2-norm of k-th column without under/overflow. - $nrm = 0.0; - for ($i = $k; $i < $this->m; ++$i) { - $nrm = hypo($nrm, $this->QR[$i][$k]); - } - if ($nrm != 0.0) { - // Form k-th Householder vector. - if ($this->QR[$k][$k] < 0) { - $nrm = -$nrm; - } - for ($i = $k; $i < $this->m; ++$i) { - $this->QR[$i][$k] /= $nrm; - } - $this->QR[$k][$k] += 1.0; - // Apply transformation to remaining columns. - for ($j = $k+1; $j < $this->n; ++$j) { - $s = 0.0; - for ($i = $k; $i < $this->m; ++$i) { - $s += $this->QR[$i][$k] * $this->QR[$i][$j]; - } - $s = -$s/$this->QR[$k][$k]; - for ($i = $k; $i < $this->m; ++$i) { - $this->QR[$i][$j] += $s * $this->QR[$i][$k]; - } - } - } - $this->Rdiag[$k] = -$nrm; - } - } else { - throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException); - } - } // function __construct() - - - /** - * Is the matrix full rank? - * - * @return boolean true if R, and hence A, has full rank, else false. - */ - public function isFullRank() { - for ($j = 0; $j < $this->n; ++$j) { - if ($this->Rdiag[$j] == 0) { - return false; - } - } - return true; - } // function isFullRank() - - - /** - * Return the Householder vectors - * - * @return Matrix Lower trapezoidal matrix whose columns define the reflections - */ - public function getH() { - for ($i = 0; $i < $this->m; ++$i) { - for ($j = 0; $j < $this->n; ++$j) { - if ($i >= $j) { - $H[$i][$j] = $this->QR[$i][$j]; - } else { - $H[$i][$j] = 0.0; - } - } - } - return new PHPExcel_Shared_JAMA_Matrix($H); - } // function getH() - - - /** - * Return the upper triangular factor - * - * @return Matrix upper triangular factor - */ - public function getR() { - for ($i = 0; $i < $this->n; ++$i) { - for ($j = 0; $j < $this->n; ++$j) { - if ($i < $j) { - $R[$i][$j] = $this->QR[$i][$j]; - } elseif ($i == $j) { - $R[$i][$j] = $this->Rdiag[$i]; - } else { - $R[$i][$j] = 0.0; - } - } - } - return new PHPExcel_Shared_JAMA_Matrix($R); - } // function getR() - - - /** - * Generate and return the (economy-sized) orthogonal factor - * - * @return Matrix orthogonal factor - */ - public function getQ() { - for ($k = $this->n-1; $k >= 0; --$k) { - for ($i = 0; $i < $this->m; ++$i) { - $Q[$i][$k] = 0.0; - } - $Q[$k][$k] = 1.0; - for ($j = $k; $j < $this->n; ++$j) { - if ($this->QR[$k][$k] != 0) { - $s = 0.0; - for ($i = $k; $i < $this->m; ++$i) { - $s += $this->QR[$i][$k] * $Q[$i][$j]; - } - $s = -$s/$this->QR[$k][$k]; - for ($i = $k; $i < $this->m; ++$i) { - $Q[$i][$j] += $s * $this->QR[$i][$k]; - } - } - } - } - /* - for($i = 0; $i < count($Q); ++$i) { - for($j = 0; $j < count($Q); ++$j) { - if(! isset($Q[$i][$j]) ) { - $Q[$i][$j] = 0; - } - } - } - */ - return new PHPExcel_Shared_JAMA_Matrix($Q); - } // function getQ() - - - /** - * Least squares solution of A*X = B - * - * @param Matrix $B A Matrix with as many rows as A and any number of columns. - * @return Matrix Matrix that minimizes the two norm of Q*R*X-B. - */ - public function solve($B) { - if ($B->getRowDimension() == $this->m) { - if ($this->isFullRank()) { - // Copy right hand side - $nx = $B->getColumnDimension(); - $X = $B->getArrayCopy(); - // Compute Y = transpose(Q)*B - for ($k = 0; $k < $this->n; ++$k) { - for ($j = 0; $j < $nx; ++$j) { - $s = 0.0; - for ($i = $k; $i < $this->m; ++$i) { - $s += $this->QR[$i][$k] * $X[$i][$j]; - } - $s = -$s/$this->QR[$k][$k]; - for ($i = $k; $i < $this->m; ++$i) { - $X[$i][$j] += $s * $this->QR[$i][$k]; - } - } - } - // Solve R*X = Y; - for ($k = $this->n-1; $k >= 0; --$k) { - for ($j = 0; $j < $nx; ++$j) { - $X[$k][$j] /= $this->Rdiag[$k]; - } - for ($i = 0; $i < $k; ++$i) { - for ($j = 0; $j < $nx; ++$j) { - $X[$i][$j] -= $X[$k][$j]* $this->QR[$i][$k]; - } - } - } - $X = new PHPExcel_Shared_JAMA_Matrix($X); - return ($X->getMatrix(0, $this->n-1, 0, $nx)); - } else { - throw new PHPExcel_Calculation_Exception(self::MatrixRankException); - } - } else { - throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); - } - } // function solve() - -} // PHPExcel_Shared_JAMA_class QRDecomposition + const MatrixRankException = "Can only perform operation on full-rank matrix."; + + /** + * Array for internal storage of decomposition. + * @var array + */ + private $QR = array(); + + /** + * Row dimension. + * @var integer + */ + private $m; + + /** + * Column dimension. + * @var integer + */ + private $n; + + /** + * Array for internal storage of diagonal of R. + * @var array + */ + private $Rdiag = array(); + + + /** + * QR Decomposition computed by Householder reflections. + * + * @param matrix $A Rectangular matrix + * @return Structure to access R and the Householder vectors and compute Q. + */ + public function __construct($A) { + if($A instanceof PHPExcel_Shared_JAMA_Matrix) { + // Initialize. + $this->QR = $A->getArrayCopy(); + $this->m = $A->getRowDimension(); + $this->n = $A->getColumnDimension(); + // Main loop. + for ($k = 0; $k < $this->n; ++$k) { + // Compute 2-norm of k-th column without under/overflow. + $nrm = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $nrm = hypo($nrm, $this->QR[$i][$k]); + } + if ($nrm != 0.0) { + // Form k-th Householder vector. + if ($this->QR[$k][$k] < 0) { + $nrm = -$nrm; + } + for ($i = $k; $i < $this->m; ++$i) { + $this->QR[$i][$k] /= $nrm; + } + $this->QR[$k][$k] += 1.0; + // Apply transformation to remaining columns. + for ($j = $k+1; $j < $this->n; ++$j) { + $s = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $s += $this->QR[$i][$k] * $this->QR[$i][$j]; + } + $s = -$s/$this->QR[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $this->QR[$i][$j] += $s * $this->QR[$i][$k]; + } + } + } + $this->Rdiag[$k] = -$nrm; + } + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException); + } + } // function __construct() + + + /** + * Is the matrix full rank? + * + * @return boolean true if R, and hence A, has full rank, else false. + */ + public function isFullRank() { + for ($j = 0; $j < $this->n; ++$j) { + if ($this->Rdiag[$j] == 0) { + return false; + } + } + return true; + } // function isFullRank() + + + /** + * Return the Householder vectors + * + * @return Matrix Lower trapezoidal matrix whose columns define the reflections + */ + public function getH() { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i >= $j) { + $H[$i][$j] = $this->QR[$i][$j]; + } else { + $H[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($H); + } // function getH() + + + /** + * Return the upper triangular factor + * + * @return Matrix upper triangular factor + */ + public function getR() { + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i < $j) { + $R[$i][$j] = $this->QR[$i][$j]; + } elseif ($i == $j) { + $R[$i][$j] = $this->Rdiag[$i]; + } else { + $R[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($R); + } // function getR() + + + /** + * Generate and return the (economy-sized) orthogonal factor + * + * @return Matrix orthogonal factor + */ + public function getQ() { + for ($k = $this->n-1; $k >= 0; --$k) { + for ($i = 0; $i < $this->m; ++$i) { + $Q[$i][$k] = 0.0; + } + $Q[$k][$k] = 1.0; + for ($j = $k; $j < $this->n; ++$j) { + if ($this->QR[$k][$k] != 0) { + $s = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $s += $this->QR[$i][$k] * $Q[$i][$j]; + } + $s = -$s/$this->QR[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $Q[$i][$j] += $s * $this->QR[$i][$k]; + } + } + } + } + /* + for($i = 0; $i < count($Q); ++$i) { + for($j = 0; $j < count($Q); ++$j) { + if(! isset($Q[$i][$j]) ) { + $Q[$i][$j] = 0; + } + } + } + */ + return new PHPExcel_Shared_JAMA_Matrix($Q); + } // function getQ() + + + /** + * Least squares solution of A*X = B + * + * @param Matrix $B A Matrix with as many rows as A and any number of columns. + * @return Matrix Matrix that minimizes the two norm of Q*R*X-B. + */ + public function solve($B) { + if ($B->getRowDimension() == $this->m) { + if ($this->isFullRank()) { + // Copy right hand side + $nx = $B->getColumnDimension(); + $X = $B->getArrayCopy(); + // Compute Y = transpose(Q)*B + for ($k = 0; $k < $this->n; ++$k) { + for ($j = 0; $j < $nx; ++$j) { + $s = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $s += $this->QR[$i][$k] * $X[$i][$j]; + } + $s = -$s/$this->QR[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $X[$i][$j] += $s * $this->QR[$i][$k]; + } + } + } + // Solve R*X = Y; + for ($k = $this->n-1; $k >= 0; --$k) { + for ($j = 0; $j < $nx; ++$j) { + $X[$k][$j] /= $this->Rdiag[$k]; + } + for ($i = 0; $i < $k; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X[$i][$j] -= $X[$k][$j]* $this->QR[$i][$k]; + } + } + } + $X = new PHPExcel_Shared_JAMA_Matrix($X); + return ($X->getMatrix(0, $this->n-1, 0, $nx)); + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixRankException); + } + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); + } + } // function solve() + +} // PHPExcel_Shared_JAMA_class QRDecomposition diff --git a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php index a4b096c59..76c4786cc 100644 --- a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php @@ -1,526 +1,526 @@ <?php /** - * @package JAMA + * @package JAMA * - * For an m-by-n matrix A with m >= n, the singular value decomposition is - * an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and - * an n-by-n orthogonal matrix V so that A = U*S*V'. + * For an m-by-n matrix A with m >= n, the singular value decomposition is + * an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and + * an n-by-n orthogonal matrix V so that A = U*S*V'. * - * The singular values, sigma[$k] = S[$k][$k], are ordered so that - * sigma[0] >= sigma[1] >= ... >= sigma[n-1]. + * The singular values, sigma[$k] = S[$k][$k], are ordered so that + * sigma[0] >= sigma[1] >= ... >= sigma[n-1]. * - * The singular value decompostion always exists, so the constructor will - * never fail. The matrix condition number and the effective numerical - * rank can be computed from this decomposition. + * The singular value decompostion always exists, so the constructor will + * never fail. The matrix condition number and the effective numerical + * rank can be computed from this decomposition. * - * @author Paul Meagher - * @license PHP v3.0 - * @version 1.1 + * @author Paul Meagher + * @license PHP v3.0 + * @version 1.1 */ class SingularValueDecomposition { - /** - * Internal storage of U. - * @var array - */ - private $U = array(); - - /** - * Internal storage of V. - * @var array - */ - private $V = array(); - - /** - * Internal storage of singular values. - * @var array - */ - private $s = array(); - - /** - * Row dimension. - * @var int - */ - private $m; - - /** - * Column dimension. - * @var int - */ - private $n; - - - /** - * Construct the singular value decomposition - * - * Derived from LINPACK code. - * - * @param $A Rectangular matrix - * @return Structure to access U, S and V. - */ - public function __construct($Arg) { - - // Initialize. - $A = $Arg->getArrayCopy(); - $this->m = $Arg->getRowDimension(); - $this->n = $Arg->getColumnDimension(); - $nu = min($this->m, $this->n); - $e = array(); - $work = array(); - $wantu = true; - $wantv = true; - $nct = min($this->m - 1, $this->n); - $nrt = max(0, min($this->n - 2, $this->m)); - - // Reduce A to bidiagonal form, storing the diagonal elements - // in s and the super-diagonal elements in e. - for ($k = 0; $k < max($nct,$nrt); ++$k) { - - if ($k < $nct) { - // Compute the transformation for the k-th column and - // place the k-th diagonal in s[$k]. - // Compute 2-norm of k-th column without under/overflow. - $this->s[$k] = 0; - for ($i = $k; $i < $this->m; ++$i) { - $this->s[$k] = hypo($this->s[$k], $A[$i][$k]); - } - if ($this->s[$k] != 0.0) { - if ($A[$k][$k] < 0.0) { - $this->s[$k] = -$this->s[$k]; - } - for ($i = $k; $i < $this->m; ++$i) { - $A[$i][$k] /= $this->s[$k]; - } - $A[$k][$k] += 1.0; - } - $this->s[$k] = -$this->s[$k]; - } - - for ($j = $k + 1; $j < $this->n; ++$j) { - if (($k < $nct) & ($this->s[$k] != 0.0)) { - // Apply the transformation. - $t = 0; - for ($i = $k; $i < $this->m; ++$i) { - $t += $A[$i][$k] * $A[$i][$j]; - } - $t = -$t / $A[$k][$k]; - for ($i = $k; $i < $this->m; ++$i) { - $A[$i][$j] += $t * $A[$i][$k]; - } - // Place the k-th row of A into e for the - // subsequent calculation of the row transformation. - $e[$j] = $A[$k][$j]; - } - } - - if ($wantu AND ($k < $nct)) { - // Place the transformation in U for subsequent back - // multiplication. - for ($i = $k; $i < $this->m; ++$i) { - $this->U[$i][$k] = $A[$i][$k]; - } - } - - if ($k < $nrt) { - // Compute the k-th row transformation and place the - // k-th super-diagonal in e[$k]. - // Compute 2-norm without under/overflow. - $e[$k] = 0; - for ($i = $k + 1; $i < $this->n; ++$i) { - $e[$k] = hypo($e[$k], $e[$i]); - } - if ($e[$k] != 0.0) { - if ($e[$k+1] < 0.0) { - $e[$k] = -$e[$k]; - } - for ($i = $k + 1; $i < $this->n; ++$i) { - $e[$i] /= $e[$k]; - } - $e[$k+1] += 1.0; - } - $e[$k] = -$e[$k]; - if (($k+1 < $this->m) AND ($e[$k] != 0.0)) { - // Apply the transformation. - for ($i = $k+1; $i < $this->m; ++$i) { - $work[$i] = 0.0; - } - for ($j = $k+1; $j < $this->n; ++$j) { - for ($i = $k+1; $i < $this->m; ++$i) { - $work[$i] += $e[$j] * $A[$i][$j]; - } - } - for ($j = $k + 1; $j < $this->n; ++$j) { - $t = -$e[$j] / $e[$k+1]; - for ($i = $k + 1; $i < $this->m; ++$i) { - $A[$i][$j] += $t * $work[$i]; - } - } - } - if ($wantv) { - // Place the transformation in V for subsequent - // back multiplication. - for ($i = $k + 1; $i < $this->n; ++$i) { - $this->V[$i][$k] = $e[$i]; - } - } - } - } - - // Set up the final bidiagonal matrix or order p. - $p = min($this->n, $this->m + 1); - if ($nct < $this->n) { - $this->s[$nct] = $A[$nct][$nct]; - } - if ($this->m < $p) { - $this->s[$p-1] = 0.0; - } - if ($nrt + 1 < $p) { - $e[$nrt] = $A[$nrt][$p-1]; - } - $e[$p-1] = 0.0; - // If required, generate U. - if ($wantu) { - for ($j = $nct; $j < $nu; ++$j) { - for ($i = 0; $i < $this->m; ++$i) { - $this->U[$i][$j] = 0.0; - } - $this->U[$j][$j] = 1.0; - } - for ($k = $nct - 1; $k >= 0; --$k) { - if ($this->s[$k] != 0.0) { - for ($j = $k + 1; $j < $nu; ++$j) { - $t = 0; - for ($i = $k; $i < $this->m; ++$i) { - $t += $this->U[$i][$k] * $this->U[$i][$j]; - } - $t = -$t / $this->U[$k][$k]; - for ($i = $k; $i < $this->m; ++$i) { - $this->U[$i][$j] += $t * $this->U[$i][$k]; - } - } - for ($i = $k; $i < $this->m; ++$i ) { - $this->U[$i][$k] = -$this->U[$i][$k]; - } - $this->U[$k][$k] = 1.0 + $this->U[$k][$k]; - for ($i = 0; $i < $k - 1; ++$i) { - $this->U[$i][$k] = 0.0; - } - } else { - for ($i = 0; $i < $this->m; ++$i) { - $this->U[$i][$k] = 0.0; - } - $this->U[$k][$k] = 1.0; - } - } - } - - // If required, generate V. - if ($wantv) { - for ($k = $this->n - 1; $k >= 0; --$k) { - if (($k < $nrt) AND ($e[$k] != 0.0)) { - for ($j = $k + 1; $j < $nu; ++$j) { - $t = 0; - for ($i = $k + 1; $i < $this->n; ++$i) { - $t += $this->V[$i][$k]* $this->V[$i][$j]; - } - $t = -$t / $this->V[$k+1][$k]; - for ($i = $k + 1; $i < $this->n; ++$i) { - $this->V[$i][$j] += $t * $this->V[$i][$k]; - } - } - } - for ($i = 0; $i < $this->n; ++$i) { - $this->V[$i][$k] = 0.0; - } - $this->V[$k][$k] = 1.0; - } - } - - // Main iteration loop for the singular values. - $pp = $p - 1; - $iter = 0; - $eps = pow(2.0, -52.0); - - while ($p > 0) { - // Here is where a test for too many iterations would go. - // This section of the program inspects for negligible - // elements in the s and e arrays. On completion the - // variables kase and k are set as follows: - // kase = 1 if s(p) and e[k-1] are negligible and k<p - // kase = 2 if s(k) is negligible and k<p - // kase = 3 if e[k-1] is negligible, k<p, and - // s(k), ..., s(p) are not negligible (qr step). - // kase = 4 if e(p-1) is negligible (convergence). - for ($k = $p - 2; $k >= -1; --$k) { - if ($k == -1) { - break; - } - if (abs($e[$k]) <= $eps * (abs($this->s[$k]) + abs($this->s[$k+1]))) { - $e[$k] = 0.0; - break; - } - } - if ($k == $p - 2) { - $kase = 4; - } else { - for ($ks = $p - 1; $ks >= $k; --$ks) { - if ($ks == $k) { - break; - } - $t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks-1]) : 0.); - if (abs($this->s[$ks]) <= $eps * $t) { - $this->s[$ks] = 0.0; - break; - } - } - if ($ks == $k) { - $kase = 3; - } else if ($ks == $p-1) { - $kase = 1; - } else { - $kase = 2; - $k = $ks; - } - } - ++$k; - - // Perform the task indicated by kase. - switch ($kase) { - // Deflate negligible s(p). - case 1: - $f = $e[$p-2]; - $e[$p-2] = 0.0; - for ($j = $p - 2; $j >= $k; --$j) { - $t = hypo($this->s[$j],$f); - $cs = $this->s[$j] / $t; - $sn = $f / $t; - $this->s[$j] = $t; - if ($j != $k) { - $f = -$sn * $e[$j-1]; - $e[$j-1] = $cs * $e[$j-1]; - } - if ($wantv) { - for ($i = 0; $i < $this->n; ++$i) { - $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p-1]; - $this->V[$i][$p-1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p-1]; - $this->V[$i][$j] = $t; - } - } - } - break; - // Split at negligible s(k). - case 2: - $f = $e[$k-1]; - $e[$k-1] = 0.0; - for ($j = $k; $j < $p; ++$j) { - $t = hypo($this->s[$j], $f); - $cs = $this->s[$j] / $t; - $sn = $f / $t; - $this->s[$j] = $t; - $f = -$sn * $e[$j]; - $e[$j] = $cs * $e[$j]; - if ($wantu) { - for ($i = 0; $i < $this->m; ++$i) { - $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k-1]; - $this->U[$i][$k-1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k-1]; - $this->U[$i][$j] = $t; - } - } - } - break; - // Perform one qr step. - case 3: - // Calculate the shift. - $scale = max(max(max(max( - abs($this->s[$p-1]),abs($this->s[$p-2])),abs($e[$p-2])), - abs($this->s[$k])), abs($e[$k])); - $sp = $this->s[$p-1] / $scale; - $spm1 = $this->s[$p-2] / $scale; - $epm1 = $e[$p-2] / $scale; - $sk = $this->s[$k] / $scale; - $ek = $e[$k] / $scale; - $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0; - $c = ($sp * $epm1) * ($sp * $epm1); - $shift = 0.0; - if (($b != 0.0) || ($c != 0.0)) { - $shift = sqrt($b * $b + $c); - if ($b < 0.0) { - $shift = -$shift; - } - $shift = $c / ($b + $shift); - } - $f = ($sk + $sp) * ($sk - $sp) + $shift; - $g = $sk * $ek; - // Chase zeros. - for ($j = $k; $j < $p-1; ++$j) { - $t = hypo($f,$g); - $cs = $f/$t; - $sn = $g/$t; - if ($j != $k) { - $e[$j-1] = $t; - } - $f = $cs * $this->s[$j] + $sn * $e[$j]; - $e[$j] = $cs * $e[$j] - $sn * $this->s[$j]; - $g = $sn * $this->s[$j+1]; - $this->s[$j+1] = $cs * $this->s[$j+1]; - if ($wantv) { - for ($i = 0; $i < $this->n; ++$i) { - $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j+1]; - $this->V[$i][$j+1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j+1]; - $this->V[$i][$j] = $t; - } - } - $t = hypo($f,$g); - $cs = $f/$t; - $sn = $g/$t; - $this->s[$j] = $t; - $f = $cs * $e[$j] + $sn * $this->s[$j+1]; - $this->s[$j+1] = -$sn * $e[$j] + $cs * $this->s[$j+1]; - $g = $sn * $e[$j+1]; - $e[$j+1] = $cs * $e[$j+1]; - if ($wantu && ($j < $this->m - 1)) { - for ($i = 0; $i < $this->m; ++$i) { - $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j+1]; - $this->U[$i][$j+1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j+1]; - $this->U[$i][$j] = $t; - } - } - } - $e[$p-2] = $f; - $iter = $iter + 1; - break; - // Convergence. - case 4: - // Make the singular values positive. - if ($this->s[$k] <= 0.0) { - $this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0); - if ($wantv) { - for ($i = 0; $i <= $pp; ++$i) { - $this->V[$i][$k] = -$this->V[$i][$k]; - } - } - } - // Order the singular values. - while ($k < $pp) { - if ($this->s[$k] >= $this->s[$k+1]) { - break; - } - $t = $this->s[$k]; - $this->s[$k] = $this->s[$k+1]; - $this->s[$k+1] = $t; - if ($wantv AND ($k < $this->n - 1)) { - for ($i = 0; $i < $this->n; ++$i) { - $t = $this->V[$i][$k+1]; - $this->V[$i][$k+1] = $this->V[$i][$k]; - $this->V[$i][$k] = $t; - } - } - if ($wantu AND ($k < $this->m-1)) { - for ($i = 0; $i < $this->m; ++$i) { - $t = $this->U[$i][$k+1]; - $this->U[$i][$k+1] = $this->U[$i][$k]; - $this->U[$i][$k] = $t; - } - } - ++$k; - } - $iter = 0; - --$p; - break; - } // end switch - } // end while - - } // end constructor - - - /** - * Return the left singular vectors - * - * @access public - * @return U - */ - public function getU() { - return new Matrix($this->U, $this->m, min($this->m + 1, $this->n)); - } - - - /** - * Return the right singular vectors - * - * @access public - * @return V - */ - public function getV() { - return new Matrix($this->V); - } - - - /** - * Return the one-dimensional array of singular values - * - * @access public - * @return diagonal of S. - */ - public function getSingularValues() { - return $this->s; - } - - - /** - * Return the diagonal matrix of singular values - * - * @access public - * @return S - */ - public function getS() { - for ($i = 0; $i < $this->n; ++$i) { - for ($j = 0; $j < $this->n; ++$j) { - $S[$i][$j] = 0.0; - } - $S[$i][$i] = $this->s[$i]; - } - return new Matrix($S); - } - - - /** - * Two norm - * - * @access public - * @return max(S) - */ - public function norm2() { - return $this->s[0]; - } - - - /** - * Two norm condition number - * - * @access public - * @return max(S)/min(S) - */ - public function cond() { - return $this->s[0] / $this->s[min($this->m, $this->n) - 1]; - } - - - /** - * Effective numerical matrix rank - * - * @access public - * @return Number of nonnegligible singular values. - */ - public function rank() { - $eps = pow(2.0, -52.0); - $tol = max($this->m, $this->n) * $this->s[0] * $eps; - $r = 0; - for ($i = 0; $i < count($this->s); ++$i) { - if ($this->s[$i] > $tol) { - ++$r; - } - } - return $r; - } - -} // class SingularValueDecomposition + /** + * Internal storage of U. + * @var array + */ + private $U = array(); + + /** + * Internal storage of V. + * @var array + */ + private $V = array(); + + /** + * Internal storage of singular values. + * @var array + */ + private $s = array(); + + /** + * Row dimension. + * @var int + */ + private $m; + + /** + * Column dimension. + * @var int + */ + private $n; + + + /** + * Construct the singular value decomposition + * + * Derived from LINPACK code. + * + * @param $A Rectangular matrix + * @return Structure to access U, S and V. + */ + public function __construct($Arg) { + + // Initialize. + $A = $Arg->getArrayCopy(); + $this->m = $Arg->getRowDimension(); + $this->n = $Arg->getColumnDimension(); + $nu = min($this->m, $this->n); + $e = array(); + $work = array(); + $wantu = true; + $wantv = true; + $nct = min($this->m - 1, $this->n); + $nrt = max(0, min($this->n - 2, $this->m)); + + // Reduce A to bidiagonal form, storing the diagonal elements + // in s and the super-diagonal elements in e. + for ($k = 0; $k < max($nct,$nrt); ++$k) { + + if ($k < $nct) { + // Compute the transformation for the k-th column and + // place the k-th diagonal in s[$k]. + // Compute 2-norm of k-th column without under/overflow. + $this->s[$k] = 0; + for ($i = $k; $i < $this->m; ++$i) { + $this->s[$k] = hypo($this->s[$k], $A[$i][$k]); + } + if ($this->s[$k] != 0.0) { + if ($A[$k][$k] < 0.0) { + $this->s[$k] = -$this->s[$k]; + } + for ($i = $k; $i < $this->m; ++$i) { + $A[$i][$k] /= $this->s[$k]; + } + $A[$k][$k] += 1.0; + } + $this->s[$k] = -$this->s[$k]; + } + + for ($j = $k + 1; $j < $this->n; ++$j) { + if (($k < $nct) & ($this->s[$k] != 0.0)) { + // Apply the transformation. + $t = 0; + for ($i = $k; $i < $this->m; ++$i) { + $t += $A[$i][$k] * $A[$i][$j]; + } + $t = -$t / $A[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $A[$i][$j] += $t * $A[$i][$k]; + } + // Place the k-th row of A into e for the + // subsequent calculation of the row transformation. + $e[$j] = $A[$k][$j]; + } + } + + if ($wantu AND ($k < $nct)) { + // Place the transformation in U for subsequent back + // multiplication. + for ($i = $k; $i < $this->m; ++$i) { + $this->U[$i][$k] = $A[$i][$k]; + } + } + + if ($k < $nrt) { + // Compute the k-th row transformation and place the + // k-th super-diagonal in e[$k]. + // Compute 2-norm without under/overflow. + $e[$k] = 0; + for ($i = $k + 1; $i < $this->n; ++$i) { + $e[$k] = hypo($e[$k], $e[$i]); + } + if ($e[$k] != 0.0) { + if ($e[$k+1] < 0.0) { + $e[$k] = -$e[$k]; + } + for ($i = $k + 1; $i < $this->n; ++$i) { + $e[$i] /= $e[$k]; + } + $e[$k+1] += 1.0; + } + $e[$k] = -$e[$k]; + if (($k+1 < $this->m) AND ($e[$k] != 0.0)) { + // Apply the transformation. + for ($i = $k+1; $i < $this->m; ++$i) { + $work[$i] = 0.0; + } + for ($j = $k+1; $j < $this->n; ++$j) { + for ($i = $k+1; $i < $this->m; ++$i) { + $work[$i] += $e[$j] * $A[$i][$j]; + } + } + for ($j = $k + 1; $j < $this->n; ++$j) { + $t = -$e[$j] / $e[$k+1]; + for ($i = $k + 1; $i < $this->m; ++$i) { + $A[$i][$j] += $t * $work[$i]; + } + } + } + if ($wantv) { + // Place the transformation in V for subsequent + // back multiplication. + for ($i = $k + 1; $i < $this->n; ++$i) { + $this->V[$i][$k] = $e[$i]; + } + } + } + } + + // Set up the final bidiagonal matrix or order p. + $p = min($this->n, $this->m + 1); + if ($nct < $this->n) { + $this->s[$nct] = $A[$nct][$nct]; + } + if ($this->m < $p) { + $this->s[$p-1] = 0.0; + } + if ($nrt + 1 < $p) { + $e[$nrt] = $A[$nrt][$p-1]; + } + $e[$p-1] = 0.0; + // If required, generate U. + if ($wantu) { + for ($j = $nct; $j < $nu; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + $this->U[$i][$j] = 0.0; + } + $this->U[$j][$j] = 1.0; + } + for ($k = $nct - 1; $k >= 0; --$k) { + if ($this->s[$k] != 0.0) { + for ($j = $k + 1; $j < $nu; ++$j) { + $t = 0; + for ($i = $k; $i < $this->m; ++$i) { + $t += $this->U[$i][$k] * $this->U[$i][$j]; + } + $t = -$t / $this->U[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $this->U[$i][$j] += $t * $this->U[$i][$k]; + } + } + for ($i = $k; $i < $this->m; ++$i ) { + $this->U[$i][$k] = -$this->U[$i][$k]; + } + $this->U[$k][$k] = 1.0 + $this->U[$k][$k]; + for ($i = 0; $i < $k - 1; ++$i) { + $this->U[$i][$k] = 0.0; + } + } else { + for ($i = 0; $i < $this->m; ++$i) { + $this->U[$i][$k] = 0.0; + } + $this->U[$k][$k] = 1.0; + } + } + } + + // If required, generate V. + if ($wantv) { + for ($k = $this->n - 1; $k >= 0; --$k) { + if (($k < $nrt) AND ($e[$k] != 0.0)) { + for ($j = $k + 1; $j < $nu; ++$j) { + $t = 0; + for ($i = $k + 1; $i < $this->n; ++$i) { + $t += $this->V[$i][$k]* $this->V[$i][$j]; + } + $t = -$t / $this->V[$k+1][$k]; + for ($i = $k + 1; $i < $this->n; ++$i) { + $this->V[$i][$j] += $t * $this->V[$i][$k]; + } + } + } + for ($i = 0; $i < $this->n; ++$i) { + $this->V[$i][$k] = 0.0; + } + $this->V[$k][$k] = 1.0; + } + } + + // Main iteration loop for the singular values. + $pp = $p - 1; + $iter = 0; + $eps = pow(2.0, -52.0); + + while ($p > 0) { + // Here is where a test for too many iterations would go. + // This section of the program inspects for negligible + // elements in the s and e arrays. On completion the + // variables kase and k are set as follows: + // kase = 1 if s(p) and e[k-1] are negligible and k<p + // kase = 2 if s(k) is negligible and k<p + // kase = 3 if e[k-1] is negligible, k<p, and + // s(k), ..., s(p) are not negligible (qr step). + // kase = 4 if e(p-1) is negligible (convergence). + for ($k = $p - 2; $k >= -1; --$k) { + if ($k == -1) { + break; + } + if (abs($e[$k]) <= $eps * (abs($this->s[$k]) + abs($this->s[$k+1]))) { + $e[$k] = 0.0; + break; + } + } + if ($k == $p - 2) { + $kase = 4; + } else { + for ($ks = $p - 1; $ks >= $k; --$ks) { + if ($ks == $k) { + break; + } + $t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks-1]) : 0.); + if (abs($this->s[$ks]) <= $eps * $t) { + $this->s[$ks] = 0.0; + break; + } + } + if ($ks == $k) { + $kase = 3; + } else if ($ks == $p-1) { + $kase = 1; + } else { + $kase = 2; + $k = $ks; + } + } + ++$k; + + // Perform the task indicated by kase. + switch ($kase) { + // Deflate negligible s(p). + case 1: + $f = $e[$p-2]; + $e[$p-2] = 0.0; + for ($j = $p - 2; $j >= $k; --$j) { + $t = hypo($this->s[$j],$f); + $cs = $this->s[$j] / $t; + $sn = $f / $t; + $this->s[$j] = $t; + if ($j != $k) { + $f = -$sn * $e[$j-1]; + $e[$j-1] = $cs * $e[$j-1]; + } + if ($wantv) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p-1]; + $this->V[$i][$p-1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p-1]; + $this->V[$i][$j] = $t; + } + } + } + break; + // Split at negligible s(k). + case 2: + $f = $e[$k-1]; + $e[$k-1] = 0.0; + for ($j = $k; $j < $p; ++$j) { + $t = hypo($this->s[$j], $f); + $cs = $this->s[$j] / $t; + $sn = $f / $t; + $this->s[$j] = $t; + $f = -$sn * $e[$j]; + $e[$j] = $cs * $e[$j]; + if ($wantu) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k-1]; + $this->U[$i][$k-1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k-1]; + $this->U[$i][$j] = $t; + } + } + } + break; + // Perform one qr step. + case 3: + // Calculate the shift. + $scale = max(max(max(max( + abs($this->s[$p-1]),abs($this->s[$p-2])),abs($e[$p-2])), + abs($this->s[$k])), abs($e[$k])); + $sp = $this->s[$p-1] / $scale; + $spm1 = $this->s[$p-2] / $scale; + $epm1 = $e[$p-2] / $scale; + $sk = $this->s[$k] / $scale; + $ek = $e[$k] / $scale; + $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0; + $c = ($sp * $epm1) * ($sp * $epm1); + $shift = 0.0; + if (($b != 0.0) || ($c != 0.0)) { + $shift = sqrt($b * $b + $c); + if ($b < 0.0) { + $shift = -$shift; + } + $shift = $c / ($b + $shift); + } + $f = ($sk + $sp) * ($sk - $sp) + $shift; + $g = $sk * $ek; + // Chase zeros. + for ($j = $k; $j < $p-1; ++$j) { + $t = hypo($f,$g); + $cs = $f/$t; + $sn = $g/$t; + if ($j != $k) { + $e[$j-1] = $t; + } + $f = $cs * $this->s[$j] + $sn * $e[$j]; + $e[$j] = $cs * $e[$j] - $sn * $this->s[$j]; + $g = $sn * $this->s[$j+1]; + $this->s[$j+1] = $cs * $this->s[$j+1]; + if ($wantv) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j+1]; + $this->V[$i][$j+1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j+1]; + $this->V[$i][$j] = $t; + } + } + $t = hypo($f,$g); + $cs = $f/$t; + $sn = $g/$t; + $this->s[$j] = $t; + $f = $cs * $e[$j] + $sn * $this->s[$j+1]; + $this->s[$j+1] = -$sn * $e[$j] + $cs * $this->s[$j+1]; + $g = $sn * $e[$j+1]; + $e[$j+1] = $cs * $e[$j+1]; + if ($wantu && ($j < $this->m - 1)) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j+1]; + $this->U[$i][$j+1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j+1]; + $this->U[$i][$j] = $t; + } + } + } + $e[$p-2] = $f; + $iter = $iter + 1; + break; + // Convergence. + case 4: + // Make the singular values positive. + if ($this->s[$k] <= 0.0) { + $this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0); + if ($wantv) { + for ($i = 0; $i <= $pp; ++$i) { + $this->V[$i][$k] = -$this->V[$i][$k]; + } + } + } + // Order the singular values. + while ($k < $pp) { + if ($this->s[$k] >= $this->s[$k+1]) { + break; + } + $t = $this->s[$k]; + $this->s[$k] = $this->s[$k+1]; + $this->s[$k+1] = $t; + if ($wantv AND ($k < $this->n - 1)) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $this->V[$i][$k+1]; + $this->V[$i][$k+1] = $this->V[$i][$k]; + $this->V[$i][$k] = $t; + } + } + if ($wantu AND ($k < $this->m-1)) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $this->U[$i][$k+1]; + $this->U[$i][$k+1] = $this->U[$i][$k]; + $this->U[$i][$k] = $t; + } + } + ++$k; + } + $iter = 0; + --$p; + break; + } // end switch + } // end while + + } // end constructor + + + /** + * Return the left singular vectors + * + * @access public + * @return U + */ + public function getU() { + return new Matrix($this->U, $this->m, min($this->m + 1, $this->n)); + } + + + /** + * Return the right singular vectors + * + * @access public + * @return V + */ + public function getV() { + return new Matrix($this->V); + } + + + /** + * Return the one-dimensional array of singular values + * + * @access public + * @return diagonal of S. + */ + public function getSingularValues() { + return $this->s; + } + + + /** + * Return the diagonal matrix of singular values + * + * @access public + * @return S + */ + public function getS() { + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + $S[$i][$j] = 0.0; + } + $S[$i][$i] = $this->s[$i]; + } + return new Matrix($S); + } + + + /** + * Two norm + * + * @access public + * @return max(S) + */ + public function norm2() { + return $this->s[0]; + } + + + /** + * Two norm condition number + * + * @access public + * @return max(S)/min(S) + */ + public function cond() { + return $this->s[0] / $this->s[min($this->m, $this->n) - 1]; + } + + + /** + * Effective numerical matrix rank + * + * @access public + * @return Number of nonnegligible singular values. + */ + public function rank() { + $eps = pow(2.0, -52.0); + $tol = max($this->m, $this->n) * $this->s[0] * $eps; + $r = 0; + for ($i = 0; $i < count($this->s); ++$i) { + if ($this->s[$i] > $tol) { + ++$r; + } + } + return $r; + } + +} // class SingularValueDecomposition diff --git a/Classes/PHPExcel/Shared/JAMA/utils/Error.php b/Classes/PHPExcel/Shared/JAMA/utils/Error.php index e73252b3d..ff51ccc5b 100644 --- a/Classes/PHPExcel/Shared/JAMA/utils/Error.php +++ b/Classes/PHPExcel/Shared/JAMA/utils/Error.php @@ -1,10 +1,10 @@ <?php /** - * @package JAMA + * @package JAMA * - * Error handling - * @author Michael Bommarito - * @version 01292005 + * Error handling + * @author Michael Bommarito + * @version 01292005 */ //Language constant @@ -64,19 +64,19 @@ $error['EN'][RowLengthException] = "All rows must have the same length."; /** - * Custom error handler - * @param int $num Error number + * Custom error handler + * @param int $num Error number */ function JAMAError($errorNumber = null) { - global $error; - - if (isset($errorNumber)) { - if (isset($error[JAMALANG][$errorNumber])) { - return $error[JAMALANG][$errorNumber]; - } else { - return $error['EN'][$errorNumber]; - } - } else { - return ("Invalid argument to JAMAError()"); - } + global $error; + + if (isset($errorNumber)) { + if (isset($error[JAMALANG][$errorNumber])) { + return $error[JAMALANG][$errorNumber]; + } else { + return $error['EN'][$errorNumber]; + } + } else { + return ("Invalid argument to JAMAError()"); + } } diff --git a/Classes/PHPExcel/Shared/JAMA/utils/Maths.php b/Classes/PHPExcel/Shared/JAMA/utils/Maths.php index aa09a8bbb..922784c5c 100644 --- a/Classes/PHPExcel/Shared/JAMA/utils/Maths.php +++ b/Classes/PHPExcel/Shared/JAMA/utils/Maths.php @@ -1,43 +1,43 @@ <?php /** - * @package JAMA + * @package JAMA * - * Pythagorean Theorem: + * Pythagorean Theorem: * - * a = 3 - * b = 4 - * r = sqrt(square(a) + square(b)) - * r = 5 + * a = 3 + * b = 4 + * r = sqrt(square(a) + square(b)) + * r = 5 * - * r = sqrt(a^2 + b^2) without under/overflow. + * r = sqrt(a^2 + b^2) without under/overflow. */ function hypo($a, $b) { - if (abs($a) > abs($b)) { - $r = $b / $a; - $r = abs($a) * sqrt(1 + $r * $r); - } elseif ($b != 0) { - $r = $a / $b; - $r = abs($b) * sqrt(1 + $r * $r); - } else { - $r = 0.0; - } - return $r; -} // function hypo() + if (abs($a) > abs($b)) { + $r = $b / $a; + $r = abs($a) * sqrt(1 + $r * $r); + } elseif ($b != 0) { + $r = $a / $b; + $r = abs($b) * sqrt(1 + $r * $r); + } else { + $r = 0.0; + } + return $r; +} // function hypo() /** - * Mike Bommarito's version. - * Compute n-dimensional hyotheneuse. + * Mike Bommarito's version. + * Compute n-dimensional hyotheneuse. * function hypot() { - $s = 0; - foreach (func_get_args() as $d) { - if (is_numeric($d)) { - $s += pow($d, 2); - } else { - throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); - } - } - return sqrt($s); + $s = 0; + foreach (func_get_args() as $d) { + if (is_numeric($d)) { + $s += pow($d, 2); + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + } + } + return sqrt($s); } */ diff --git a/Classes/PHPExcel/Shared/OLE.php b/Classes/PHPExcel/Shared/OLE.php index 9796282a8..f11490696 100644 --- a/Classes/PHPExcel/Shared/OLE.php +++ b/Classes/PHPExcel/Shared/OLE.php @@ -37,495 +37,495 @@ */ class PHPExcel_Shared_OLE { - const OLE_PPS_TYPE_ROOT = 5; - const OLE_PPS_TYPE_DIR = 1; - const OLE_PPS_TYPE_FILE = 2; - const OLE_DATA_SIZE_SMALL = 0x1000; - const OLE_LONG_INT_SIZE = 4; - const OLE_PPS_SIZE = 0x80; - - /** - * The file handle for reading an OLE container - * @var resource - */ - public $_file_handle; - - /** - * Array of PPS's found on the OLE container - * @var array - */ - public $_list = array(); - - /** - * Root directory of OLE container - * @var OLE_PPS_Root - */ - public $root; - - /** - * Big Block Allocation Table - * @var array (blockId => nextBlockId) - */ - public $bbat; - - /** - * Short Block Allocation Table - * @var array (blockId => nextBlockId) - */ - public $sbat; - - /** - * Size of big blocks. This is usually 512. - * @var int number of octets per block. - */ - public $bigBlockSize; - - /** - * Size of small blocks. This is usually 64. - * @var int number of octets per block - */ - public $smallBlockSize; - - /** - * Reads an OLE container from the contents of the file given. - * - * @acces public - * @param string $file - * @return mixed true on success, PEAR_Error on failure - */ - public function read($file) - { - $fh = fopen($file, "r"); - if (!$fh) { - throw new PHPExcel_Reader_Exception("Can't open file $file"); - } - $this->_file_handle = $fh; - - $signature = fread($fh, 8); - if ("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) { - throw new PHPExcel_Reader_Exception("File doesn't seem to be an OLE container."); - } - fseek($fh, 28); - if (fread($fh, 2) != "\xFE\xFF") { - // This shouldn't be a problem in practice - throw new PHPExcel_Reader_Exception("Only Little-Endian encoding is supported."); - } - // Size of blocks and short blocks in bytes - $this->bigBlockSize = pow(2, self::_readInt2($fh)); - $this->smallBlockSize = pow(2, self::_readInt2($fh)); - - // Skip UID, revision number and version number - fseek($fh, 44); - // Number of blocks in Big Block Allocation Table - $bbatBlockCount = self::_readInt4($fh); - - // Root chain 1st block - $directoryFirstBlockId = self::_readInt4($fh); - - // Skip unused bytes - fseek($fh, 56); - // Streams shorter than this are stored using small blocks - $this->bigBlockThreshold = self::_readInt4($fh); - // Block id of first sector in Short Block Allocation Table - $sbatFirstBlockId = self::_readInt4($fh); - // Number of blocks in Short Block Allocation Table - $sbbatBlockCount = self::_readInt4($fh); - // Block id of first sector in Master Block Allocation Table - $mbatFirstBlockId = self::_readInt4($fh); - // Number of blocks in Master Block Allocation Table - $mbbatBlockCount = self::_readInt4($fh); - $this->bbat = array(); - - // Remaining 4 * 109 bytes of current block is beginning of Master - // Block Allocation Table - $mbatBlocks = array(); - for ($i = 0; $i < 109; ++$i) { - $mbatBlocks[] = self::_readInt4($fh); - } - - // Read rest of Master Block Allocation Table (if any is left) - $pos = $this->_getBlockOffset($mbatFirstBlockId); - for ($i = 0; $i < $mbbatBlockCount; ++$i) { - fseek($fh, $pos); - for ($j = 0; $j < $this->bigBlockSize / 4 - 1; ++$j) { - $mbatBlocks[] = self::_readInt4($fh); - } - // Last block id in each block points to next block - $pos = $this->_getBlockOffset(self::_readInt4($fh)); - } - - // Read Big Block Allocation Table according to chain specified by - // $mbatBlocks - for ($i = 0; $i < $bbatBlockCount; ++$i) { - $pos = $this->_getBlockOffset($mbatBlocks[$i]); - fseek($fh, $pos); - for ($j = 0 ; $j < $this->bigBlockSize / 4; ++$j) { - $this->bbat[] = self::_readInt4($fh); - } - } - - // Read short block allocation table (SBAT) - $this->sbat = array(); - $shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4; - $sbatFh = $this->getStream($sbatFirstBlockId); - for ($blockId = 0; $blockId < $shortBlockCount; ++$blockId) { - $this->sbat[$blockId] = self::_readInt4($sbatFh); - } - fclose($sbatFh); - - $this->_readPpsWks($directoryFirstBlockId); - - return true; - } - - /** - * @param int block id - * @param int byte offset from beginning of file - * @access public - */ - public function _getBlockOffset($blockId) - { - return 512 + $blockId * $this->bigBlockSize; - } - - /** - * Returns a stream for use with fread() etc. External callers should - * use PHPExcel_Shared_OLE_PPS_File::getStream(). - * @param int|PPS block id or PPS - * @return resource read-only stream - */ - public function getStream($blockIdOrPps) - { - static $isRegistered = false; - if (!$isRegistered) { - stream_wrapper_register('ole-chainedblockstream', - 'PHPExcel_Shared_OLE_ChainedBlockStream'); - $isRegistered = true; - } - - // Store current instance in global array, so that it can be accessed - // in OLE_ChainedBlockStream::stream_open(). - // Object is removed from self::$instances in OLE_Stream::close(). - $GLOBALS['_OLE_INSTANCES'][] = $this; - $instanceId = end(array_keys($GLOBALS['_OLE_INSTANCES'])); - - $path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId; - if ($blockIdOrPps instanceof PHPExcel_Shared_OLE_PPS) { - $path .= '&blockId=' . $blockIdOrPps->_StartBlock; - $path .= '&size=' . $blockIdOrPps->Size; - } else { - $path .= '&blockId=' . $blockIdOrPps; - } - return fopen($path, 'r'); - } - - /** - * Reads a signed char. - * @param resource file handle - * @return int - * @access public - */ - private static function _readInt1($fh) - { - list(, $tmp) = unpack("c", fread($fh, 1)); - return $tmp; - } - - /** - * Reads an unsigned short (2 octets). - * @param resource file handle - * @return int - * @access public - */ - private static function _readInt2($fh) - { - list(, $tmp) = unpack("v", fread($fh, 2)); - return $tmp; - } - - /** - * Reads an unsigned long (4 octets). - * @param resource file handle - * @return int - * @access public - */ - private static function _readInt4($fh) - { - list(, $tmp) = unpack("V", fread($fh, 4)); - return $tmp; - } - - /** - * Gets information about all PPS's on the OLE container from the PPS WK's - * creates an OLE_PPS object for each one. - * - * @access public - * @param integer the block id of the first block - * @return mixed true on success, PEAR_Error on failure - */ - public function _readPpsWks($blockId) - { - $fh = $this->getStream($blockId); - for ($pos = 0; ; $pos += 128) { - fseek($fh, $pos, SEEK_SET); - $nameUtf16 = fread($fh, 64); - $nameLength = self::_readInt2($fh); - $nameUtf16 = substr($nameUtf16, 0, $nameLength - 2); - // Simple conversion from UTF-16LE to ISO-8859-1 - $name = str_replace("\x00", "", $nameUtf16); - $type = self::_readInt1($fh); - switch ($type) { - case self::OLE_PPS_TYPE_ROOT: - $pps = new PHPExcel_Shared_OLE_PPS_Root(null, null, array()); - $this->root = $pps; - break; - case self::OLE_PPS_TYPE_DIR: - $pps = new PHPExcel_Shared_OLE_PPS(null, null, null, null, null, - null, null, null, null, array()); - break; - case self::OLE_PPS_TYPE_FILE: - $pps = new PHPExcel_Shared_OLE_PPS_File($name); - break; - default: - continue; - } - fseek($fh, 1, SEEK_CUR); - $pps->Type = $type; - $pps->Name = $name; - $pps->PrevPps = self::_readInt4($fh); - $pps->NextPps = self::_readInt4($fh); - $pps->DirPps = self::_readInt4($fh); - fseek($fh, 20, SEEK_CUR); - $pps->Time1st = self::OLE2LocalDate(fread($fh, 8)); - $pps->Time2nd = self::OLE2LocalDate(fread($fh, 8)); - $pps->_StartBlock = self::_readInt4($fh); - $pps->Size = self::_readInt4($fh); - $pps->No = count($this->_list); - $this->_list[] = $pps; - - // check if the PPS tree (starting from root) is complete - if (isset($this->root) && - $this->_ppsTreeComplete($this->root->No)) { - - break; - } - } - fclose($fh); - - // Initialize $pps->children on directories - foreach ($this->_list as $pps) { - if ($pps->Type == self::OLE_PPS_TYPE_DIR || $pps->Type == self::OLE_PPS_TYPE_ROOT) { - $nos = array($pps->DirPps); - $pps->children = array(); - while ($nos) { - $no = array_pop($nos); - if ($no != -1) { - $childPps = $this->_list[$no]; - $nos[] = $childPps->PrevPps; - $nos[] = $childPps->NextPps; - $pps->children[] = $childPps; - } - } - } - } - - return true; - } - - /** - * It checks whether the PPS tree is complete (all PPS's read) - * starting with the given PPS (not necessarily root) - * - * @access public - * @param integer $index The index of the PPS from which we are checking - * @return boolean Whether the PPS tree for the given PPS is complete - */ - public function _ppsTreeComplete($index) - { - return isset($this->_list[$index]) && - ($pps = $this->_list[$index]) && - ($pps->PrevPps == -1 || - $this->_ppsTreeComplete($pps->PrevPps)) && - ($pps->NextPps == -1 || - $this->_ppsTreeComplete($pps->NextPps)) && - ($pps->DirPps == -1 || - $this->_ppsTreeComplete($pps->DirPps)); - } - - /** - * Checks whether a PPS is a File PPS or not. - * If there is no PPS for the index given, it will return false. - * - * @access public - * @param integer $index The index for the PPS - * @return bool true if it's a File PPS, false otherwise - */ - public function isFile($index) - { - if (isset($this->_list[$index])) { - return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_FILE); - } - return false; - } - - /** - * Checks whether a PPS is a Root PPS or not. - * If there is no PPS for the index given, it will return false. - * - * @access public - * @param integer $index The index for the PPS. - * @return bool true if it's a Root PPS, false otherwise - */ - public function isRoot($index) - { - if (isset($this->_list[$index])) { - return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_ROOT); - } - return false; - } - - /** - * Gives the total number of PPS's found in the OLE container. - * - * @access public - * @return integer The total number of PPS's found in the OLE container - */ - public function ppsTotal() - { - return count($this->_list); - } - - /** - * Gets data from a PPS - * If there is no PPS for the index given, it will return an empty string. - * - * @access public - * @param integer $index The index for the PPS - * @param integer $position The position from which to start reading - * (relative to the PPS) - * @param integer $length The amount of bytes to read (at most) - * @return string The binary string containing the data requested - * @see OLE_PPS_File::getStream() - */ - public function getData($index, $position, $length) - { - // if position is not valid return empty string - if (!isset($this->_list[$index]) || ($position >= $this->_list[$index]->Size) || ($position < 0)) { - return ''; - } - $fh = $this->getStream($this->_list[$index]); - $data = stream_get_contents($fh, $length, $position); - fclose($fh); - return $data; - } - - /** - * Gets the data length from a PPS - * If there is no PPS for the index given, it will return 0. - * - * @access public - * @param integer $index The index for the PPS - * @return integer The amount of bytes in data the PPS has - */ - public function getDataLength($index) - { - if (isset($this->_list[$index])) { - return $this->_list[$index]->Size; - } - return 0; - } - - /** - * Utility function to transform ASCII text to Unicode - * - * @access public - * @static - * @param string $ascii The ASCII string to transform - * @return string The string in Unicode - */ - public static function Asc2Ucs($ascii) - { - $rawname = ''; - for ($i = 0; $i < strlen($ascii); ++$i) { - $rawname .= $ascii{$i} . "\x00"; - } - return $rawname; - } - - /** - * Utility function - * Returns a string for the OLE container with the date given - * - * @access public - * @static - * @param integer $date A timestamp - * @return string The string for the OLE container - */ - public static function LocalDate2OLE($date = null) - { - if (!isset($date)) { - return "\x00\x00\x00\x00\x00\x00\x00\x00"; - } - - // factor used for separating numbers into 4 bytes parts - $factor = pow(2, 32); - - // days from 1-1-1601 until the beggining of UNIX era - $days = 134774; - // calculate seconds - $big_date = $days*24*3600 + gmmktime(date("H",$date),date("i",$date),date("s",$date), - date("m",$date),date("d",$date),date("Y",$date)); - // multiply just to make MS happy - $big_date *= 10000000; - - $high_part = floor($big_date / $factor); - // lower 4 bytes - $low_part = floor((($big_date / $factor) - $high_part) * $factor); - - // Make HEX string - $res = ''; - - for ($i = 0; $i < 4; ++$i) { - $hex = $low_part % 0x100; - $res .= pack('c', $hex); - $low_part /= 0x100; - } - for ($i = 0; $i < 4; ++$i) { - $hex = $high_part % 0x100; - $res .= pack('c', $hex); - $high_part /= 0x100; - } - return $res; - } - - /** - * Returns a timestamp from an OLE container's date - * - * @access public - * @static - * @param integer $string A binary string with the encoded date - * @return string The timestamp corresponding to the string - */ - public static function OLE2LocalDate($string) - { - if (strlen($string) != 8) { - return new PEAR_Error("Expecting 8 byte string"); - } - - // factor used for separating numbers into 4 bytes parts - $factor = pow(2,32); - list(, $high_part) = unpack('V', substr($string, 4, 4)); - list(, $low_part) = unpack('V', substr($string, 0, 4)); - - $big_date = ($high_part * $factor) + $low_part; - // translate to seconds - $big_date /= 10000000; - - // days from 1-1-1601 until the beggining of UNIX era - $days = 134774; - - // translate to seconds from beggining of UNIX era - $big_date -= $days * 24 * 3600; - return floor($big_date); - } + const OLE_PPS_TYPE_ROOT = 5; + const OLE_PPS_TYPE_DIR = 1; + const OLE_PPS_TYPE_FILE = 2; + const OLE_DATA_SIZE_SMALL = 0x1000; + const OLE_LONG_INT_SIZE = 4; + const OLE_PPS_SIZE = 0x80; + + /** + * The file handle for reading an OLE container + * @var resource + */ + public $_file_handle; + + /** + * Array of PPS's found on the OLE container + * @var array + */ + public $_list = array(); + + /** + * Root directory of OLE container + * @var OLE_PPS_Root + */ + public $root; + + /** + * Big Block Allocation Table + * @var array (blockId => nextBlockId) + */ + public $bbat; + + /** + * Short Block Allocation Table + * @var array (blockId => nextBlockId) + */ + public $sbat; + + /** + * Size of big blocks. This is usually 512. + * @var int number of octets per block. + */ + public $bigBlockSize; + + /** + * Size of small blocks. This is usually 64. + * @var int number of octets per block + */ + public $smallBlockSize; + + /** + * Reads an OLE container from the contents of the file given. + * + * @acces public + * @param string $file + * @return mixed true on success, PEAR_Error on failure + */ + public function read($file) + { + $fh = fopen($file, "r"); + if (!$fh) { + throw new PHPExcel_Reader_Exception("Can't open file $file"); + } + $this->_file_handle = $fh; + + $signature = fread($fh, 8); + if ("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) { + throw new PHPExcel_Reader_Exception("File doesn't seem to be an OLE container."); + } + fseek($fh, 28); + if (fread($fh, 2) != "\xFE\xFF") { + // This shouldn't be a problem in practice + throw new PHPExcel_Reader_Exception("Only Little-Endian encoding is supported."); + } + // Size of blocks and short blocks in bytes + $this->bigBlockSize = pow(2, self::_readInt2($fh)); + $this->smallBlockSize = pow(2, self::_readInt2($fh)); + + // Skip UID, revision number and version number + fseek($fh, 44); + // Number of blocks in Big Block Allocation Table + $bbatBlockCount = self::_readInt4($fh); + + // Root chain 1st block + $directoryFirstBlockId = self::_readInt4($fh); + + // Skip unused bytes + fseek($fh, 56); + // Streams shorter than this are stored using small blocks + $this->bigBlockThreshold = self::_readInt4($fh); + // Block id of first sector in Short Block Allocation Table + $sbatFirstBlockId = self::_readInt4($fh); + // Number of blocks in Short Block Allocation Table + $sbbatBlockCount = self::_readInt4($fh); + // Block id of first sector in Master Block Allocation Table + $mbatFirstBlockId = self::_readInt4($fh); + // Number of blocks in Master Block Allocation Table + $mbbatBlockCount = self::_readInt4($fh); + $this->bbat = array(); + + // Remaining 4 * 109 bytes of current block is beginning of Master + // Block Allocation Table + $mbatBlocks = array(); + for ($i = 0; $i < 109; ++$i) { + $mbatBlocks[] = self::_readInt4($fh); + } + + // Read rest of Master Block Allocation Table (if any is left) + $pos = $this->_getBlockOffset($mbatFirstBlockId); + for ($i = 0; $i < $mbbatBlockCount; ++$i) { + fseek($fh, $pos); + for ($j = 0; $j < $this->bigBlockSize / 4 - 1; ++$j) { + $mbatBlocks[] = self::_readInt4($fh); + } + // Last block id in each block points to next block + $pos = $this->_getBlockOffset(self::_readInt4($fh)); + } + + // Read Big Block Allocation Table according to chain specified by + // $mbatBlocks + for ($i = 0; $i < $bbatBlockCount; ++$i) { + $pos = $this->_getBlockOffset($mbatBlocks[$i]); + fseek($fh, $pos); + for ($j = 0 ; $j < $this->bigBlockSize / 4; ++$j) { + $this->bbat[] = self::_readInt4($fh); + } + } + + // Read short block allocation table (SBAT) + $this->sbat = array(); + $shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4; + $sbatFh = $this->getStream($sbatFirstBlockId); + for ($blockId = 0; $blockId < $shortBlockCount; ++$blockId) { + $this->sbat[$blockId] = self::_readInt4($sbatFh); + } + fclose($sbatFh); + + $this->_readPpsWks($directoryFirstBlockId); + + return true; + } + + /** + * @param int block id + * @param int byte offset from beginning of file + * @access public + */ + public function _getBlockOffset($blockId) + { + return 512 + $blockId * $this->bigBlockSize; + } + + /** + * Returns a stream for use with fread() etc. External callers should + * use PHPExcel_Shared_OLE_PPS_File::getStream(). + * @param int|PPS block id or PPS + * @return resource read-only stream + */ + public function getStream($blockIdOrPps) + { + static $isRegistered = false; + if (!$isRegistered) { + stream_wrapper_register('ole-chainedblockstream', + 'PHPExcel_Shared_OLE_ChainedBlockStream'); + $isRegistered = true; + } + + // Store current instance in global array, so that it can be accessed + // in OLE_ChainedBlockStream::stream_open(). + // Object is removed from self::$instances in OLE_Stream::close(). + $GLOBALS['_OLE_INSTANCES'][] = $this; + $instanceId = end(array_keys($GLOBALS['_OLE_INSTANCES'])); + + $path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId; + if ($blockIdOrPps instanceof PHPExcel_Shared_OLE_PPS) { + $path .= '&blockId=' . $blockIdOrPps->_StartBlock; + $path .= '&size=' . $blockIdOrPps->Size; + } else { + $path .= '&blockId=' . $blockIdOrPps; + } + return fopen($path, 'r'); + } + + /** + * Reads a signed char. + * @param resource file handle + * @return int + * @access public + */ + private static function _readInt1($fh) + { + list(, $tmp) = unpack("c", fread($fh, 1)); + return $tmp; + } + + /** + * Reads an unsigned short (2 octets). + * @param resource file handle + * @return int + * @access public + */ + private static function _readInt2($fh) + { + list(, $tmp) = unpack("v", fread($fh, 2)); + return $tmp; + } + + /** + * Reads an unsigned long (4 octets). + * @param resource file handle + * @return int + * @access public + */ + private static function _readInt4($fh) + { + list(, $tmp) = unpack("V", fread($fh, 4)); + return $tmp; + } + + /** + * Gets information about all PPS's on the OLE container from the PPS WK's + * creates an OLE_PPS object for each one. + * + * @access public + * @param integer the block id of the first block + * @return mixed true on success, PEAR_Error on failure + */ + public function _readPpsWks($blockId) + { + $fh = $this->getStream($blockId); + for ($pos = 0; ; $pos += 128) { + fseek($fh, $pos, SEEK_SET); + $nameUtf16 = fread($fh, 64); + $nameLength = self::_readInt2($fh); + $nameUtf16 = substr($nameUtf16, 0, $nameLength - 2); + // Simple conversion from UTF-16LE to ISO-8859-1 + $name = str_replace("\x00", "", $nameUtf16); + $type = self::_readInt1($fh); + switch ($type) { + case self::OLE_PPS_TYPE_ROOT: + $pps = new PHPExcel_Shared_OLE_PPS_Root(null, null, array()); + $this->root = $pps; + break; + case self::OLE_PPS_TYPE_DIR: + $pps = new PHPExcel_Shared_OLE_PPS(null, null, null, null, null, + null, null, null, null, array()); + break; + case self::OLE_PPS_TYPE_FILE: + $pps = new PHPExcel_Shared_OLE_PPS_File($name); + break; + default: + continue; + } + fseek($fh, 1, SEEK_CUR); + $pps->Type = $type; + $pps->Name = $name; + $pps->PrevPps = self::_readInt4($fh); + $pps->NextPps = self::_readInt4($fh); + $pps->DirPps = self::_readInt4($fh); + fseek($fh, 20, SEEK_CUR); + $pps->Time1st = self::OLE2LocalDate(fread($fh, 8)); + $pps->Time2nd = self::OLE2LocalDate(fread($fh, 8)); + $pps->_StartBlock = self::_readInt4($fh); + $pps->Size = self::_readInt4($fh); + $pps->No = count($this->_list); + $this->_list[] = $pps; + + // check if the PPS tree (starting from root) is complete + if (isset($this->root) && + $this->_ppsTreeComplete($this->root->No)) { + + break; + } + } + fclose($fh); + + // Initialize $pps->children on directories + foreach ($this->_list as $pps) { + if ($pps->Type == self::OLE_PPS_TYPE_DIR || $pps->Type == self::OLE_PPS_TYPE_ROOT) { + $nos = array($pps->DirPps); + $pps->children = array(); + while ($nos) { + $no = array_pop($nos); + if ($no != -1) { + $childPps = $this->_list[$no]; + $nos[] = $childPps->PrevPps; + $nos[] = $childPps->NextPps; + $pps->children[] = $childPps; + } + } + } + } + + return true; + } + + /** + * It checks whether the PPS tree is complete (all PPS's read) + * starting with the given PPS (not necessarily root) + * + * @access public + * @param integer $index The index of the PPS from which we are checking + * @return boolean Whether the PPS tree for the given PPS is complete + */ + public function _ppsTreeComplete($index) + { + return isset($this->_list[$index]) && + ($pps = $this->_list[$index]) && + ($pps->PrevPps == -1 || + $this->_ppsTreeComplete($pps->PrevPps)) && + ($pps->NextPps == -1 || + $this->_ppsTreeComplete($pps->NextPps)) && + ($pps->DirPps == -1 || + $this->_ppsTreeComplete($pps->DirPps)); + } + + /** + * Checks whether a PPS is a File PPS or not. + * If there is no PPS for the index given, it will return false. + * + * @access public + * @param integer $index The index for the PPS + * @return bool true if it's a File PPS, false otherwise + */ + public function isFile($index) + { + if (isset($this->_list[$index])) { + return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_FILE); + } + return false; + } + + /** + * Checks whether a PPS is a Root PPS or not. + * If there is no PPS for the index given, it will return false. + * + * @access public + * @param integer $index The index for the PPS. + * @return bool true if it's a Root PPS, false otherwise + */ + public function isRoot($index) + { + if (isset($this->_list[$index])) { + return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_ROOT); + } + return false; + } + + /** + * Gives the total number of PPS's found in the OLE container. + * + * @access public + * @return integer The total number of PPS's found in the OLE container + */ + public function ppsTotal() + { + return count($this->_list); + } + + /** + * Gets data from a PPS + * If there is no PPS for the index given, it will return an empty string. + * + * @access public + * @param integer $index The index for the PPS + * @param integer $position The position from which to start reading + * (relative to the PPS) + * @param integer $length The amount of bytes to read (at most) + * @return string The binary string containing the data requested + * @see OLE_PPS_File::getStream() + */ + public function getData($index, $position, $length) + { + // if position is not valid return empty string + if (!isset($this->_list[$index]) || ($position >= $this->_list[$index]->Size) || ($position < 0)) { + return ''; + } + $fh = $this->getStream($this->_list[$index]); + $data = stream_get_contents($fh, $length, $position); + fclose($fh); + return $data; + } + + /** + * Gets the data length from a PPS + * If there is no PPS for the index given, it will return 0. + * + * @access public + * @param integer $index The index for the PPS + * @return integer The amount of bytes in data the PPS has + */ + public function getDataLength($index) + { + if (isset($this->_list[$index])) { + return $this->_list[$index]->Size; + } + return 0; + } + + /** + * Utility function to transform ASCII text to Unicode + * + * @access public + * @static + * @param string $ascii The ASCII string to transform + * @return string The string in Unicode + */ + public static function Asc2Ucs($ascii) + { + $rawname = ''; + for ($i = 0; $i < strlen($ascii); ++$i) { + $rawname .= $ascii{$i} . "\x00"; + } + return $rawname; + } + + /** + * Utility function + * Returns a string for the OLE container with the date given + * + * @access public + * @static + * @param integer $date A timestamp + * @return string The string for the OLE container + */ + public static function LocalDate2OLE($date = null) + { + if (!isset($date)) { + return "\x00\x00\x00\x00\x00\x00\x00\x00"; + } + + // factor used for separating numbers into 4 bytes parts + $factor = pow(2, 32); + + // days from 1-1-1601 until the beggining of UNIX era + $days = 134774; + // calculate seconds + $big_date = $days*24*3600 + gmmktime(date("H",$date),date("i",$date),date("s",$date), + date("m",$date),date("d",$date),date("Y",$date)); + // multiply just to make MS happy + $big_date *= 10000000; + + $high_part = floor($big_date / $factor); + // lower 4 bytes + $low_part = floor((($big_date / $factor) - $high_part) * $factor); + + // Make HEX string + $res = ''; + + for ($i = 0; $i < 4; ++$i) { + $hex = $low_part % 0x100; + $res .= pack('c', $hex); + $low_part /= 0x100; + } + for ($i = 0; $i < 4; ++$i) { + $hex = $high_part % 0x100; + $res .= pack('c', $hex); + $high_part /= 0x100; + } + return $res; + } + + /** + * Returns a timestamp from an OLE container's date + * + * @access public + * @static + * @param integer $string A binary string with the encoded date + * @return string The timestamp corresponding to the string + */ + public static function OLE2LocalDate($string) + { + if (strlen($string) != 8) { + return new PEAR_Error("Expecting 8 byte string"); + } + + // factor used for separating numbers into 4 bytes parts + $factor = pow(2,32); + list(, $high_part) = unpack('V', substr($string, 4, 4)); + list(, $low_part) = unpack('V', substr($string, 0, 4)); + + $big_date = ($high_part * $factor) + $low_part; + // translate to seconds + $big_date /= 10000000; + + // days from 1-1-1601 until the beggining of UNIX era + $days = 134774; + + // translate to seconds from beggining of UNIX era + $big_date -= $days * 24 * 3600; + return floor($big_date); + } } diff --git a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php index 03a9e48f1..10f3f4b41 100644 --- a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php +++ b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_OLE * @copyright Copyright (c) 2006 - 2007 Christian Schmidt - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -37,186 +37,186 @@ */ class PHPExcel_Shared_OLE_ChainedBlockStream { - /** - * The OLE container of the file that is being read. - * @var OLE - */ - public $ole; - - /** - * Parameters specified by fopen(). - * @var array - */ - public $params; - - /** - * The binary data of the file. - * @var string - */ - public $data; - - /** - * The file pointer. - * @var int byte offset - */ - public $pos; - - /** - * Implements support for fopen(). - * For creating streams using this wrapper, use OLE_PPS_File::getStream(). - * - * @param string $path resource name including scheme, e.g. - * ole-chainedblockstream://oleInstanceId=1 - * @param string $mode only "r" is supported - * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH - * @param string &$openedPath absolute path of the opened stream (out parameter) - * @return bool true on success - */ - public function stream_open($path, $mode, $options, &$openedPath) - { - if ($mode != 'r') { - if ($options & STREAM_REPORT_ERRORS) { - trigger_error('Only reading is supported', E_USER_WARNING); - } - return false; - } - - // 25 is length of "ole-chainedblockstream://" - parse_str(substr($path, 25), $this->params); - if (!isset($this->params['oleInstanceId'], - $this->params['blockId'], - $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) { - - if ($options & STREAM_REPORT_ERRORS) { - trigger_error('OLE stream not found', E_USER_WARNING); - } - return false; - } - $this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']]; - - $blockId = $this->params['blockId']; - $this->data = ''; - if (isset($this->params['size']) && - $this->params['size'] < $this->ole->bigBlockThreshold && - $blockId != $this->ole->root->_StartBlock) { - - // Block id refers to small blocks - $rootPos = $this->ole->_getBlockOffset($this->ole->root->_StartBlock); - while ($blockId != -2) { - $pos = $rootPos + $blockId * $this->ole->bigBlockSize; - $blockId = $this->ole->sbat[$blockId]; - fseek($this->ole->_file_handle, $pos); - $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize); - } - } else { - // Block id refers to big blocks - while ($blockId != -2) { - $pos = $this->ole->_getBlockOffset($blockId); - fseek($this->ole->_file_handle, $pos); - $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize); - $blockId = $this->ole->bbat[$blockId]; - } - } - if (isset($this->params['size'])) { - $this->data = substr($this->data, 0, $this->params['size']); - } - - if ($options & STREAM_USE_PATH) { - $openedPath = $path; - } - - return true; - } - - /** - * Implements support for fclose(). - * - */ - public function stream_close() - { - $this->ole = null; - unset($GLOBALS['_OLE_INSTANCES']); - } - - /** - * Implements support for fread(), fgets() etc. - * - * @param int $count maximum number of bytes to read - * @return string - */ - public function stream_read($count) - { - if ($this->stream_eof()) { - return false; - } - $s = substr($this->data, $this->pos, $count); - $this->pos += $count; - return $s; - } - - /** - * Implements support for feof(). - * - * @return bool TRUE if the file pointer is at EOF; otherwise FALSE - */ - public function stream_eof() - { - return $this->pos >= strlen($this->data); - } - - /** - * Returns the position of the file pointer, i.e. its offset into the file - * stream. Implements support for ftell(). - * - * @return int - */ - public function stream_tell() - { - return $this->pos; - } - - /** - * Implements support for fseek(). - * - * @param int $offset byte offset - * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END - * @return bool - */ - public function stream_seek($offset, $whence) - { - if ($whence == SEEK_SET && $offset >= 0) { - $this->pos = $offset; - } elseif ($whence == SEEK_CUR && -$offset <= $this->pos) { - $this->pos += $offset; - } elseif ($whence == SEEK_END && -$offset <= sizeof($this->data)) { - $this->pos = strlen($this->data) + $offset; - } else { - return false; - } - return true; - } - - /** - * Implements support for fstat(). Currently the only supported field is - * "size". - * @return array - */ - public function stream_stat() - { - return array( - 'size' => strlen($this->data), - ); - } - - // Methods used by stream_wrapper_register() that are not implemented: - // bool stream_flush ( void ) - // int stream_write ( string data ) - // bool rename ( string path_from, string path_to ) - // bool mkdir ( string path, int mode, int options ) - // bool rmdir ( string path, int options ) - // bool dir_opendir ( string path, int options ) - // array url_stat ( string path, int flags ) - // string dir_readdir ( void ) - // bool dir_rewinddir ( void ) - // bool dir_closedir ( void ) + /** + * The OLE container of the file that is being read. + * @var OLE + */ + public $ole; + + /** + * Parameters specified by fopen(). + * @var array + */ + public $params; + + /** + * The binary data of the file. + * @var string + */ + public $data; + + /** + * The file pointer. + * @var int byte offset + */ + public $pos; + + /** + * Implements support for fopen(). + * For creating streams using this wrapper, use OLE_PPS_File::getStream(). + * + * @param string $path resource name including scheme, e.g. + * ole-chainedblockstream://oleInstanceId=1 + * @param string $mode only "r" is supported + * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH + * @param string &$openedPath absolute path of the opened stream (out parameter) + * @return bool true on success + */ + public function stream_open($path, $mode, $options, &$openedPath) + { + if ($mode != 'r') { + if ($options & STREAM_REPORT_ERRORS) { + trigger_error('Only reading is supported', E_USER_WARNING); + } + return false; + } + + // 25 is length of "ole-chainedblockstream://" + parse_str(substr($path, 25), $this->params); + if (!isset($this->params['oleInstanceId'], + $this->params['blockId'], + $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) { + + if ($options & STREAM_REPORT_ERRORS) { + trigger_error('OLE stream not found', E_USER_WARNING); + } + return false; + } + $this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']]; + + $blockId = $this->params['blockId']; + $this->data = ''; + if (isset($this->params['size']) && + $this->params['size'] < $this->ole->bigBlockThreshold && + $blockId != $this->ole->root->_StartBlock) { + + // Block id refers to small blocks + $rootPos = $this->ole->_getBlockOffset($this->ole->root->_StartBlock); + while ($blockId != -2) { + $pos = $rootPos + $blockId * $this->ole->bigBlockSize; + $blockId = $this->ole->sbat[$blockId]; + fseek($this->ole->_file_handle, $pos); + $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize); + } + } else { + // Block id refers to big blocks + while ($blockId != -2) { + $pos = $this->ole->_getBlockOffset($blockId); + fseek($this->ole->_file_handle, $pos); + $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize); + $blockId = $this->ole->bbat[$blockId]; + } + } + if (isset($this->params['size'])) { + $this->data = substr($this->data, 0, $this->params['size']); + } + + if ($options & STREAM_USE_PATH) { + $openedPath = $path; + } + + return true; + } + + /** + * Implements support for fclose(). + * + */ + public function stream_close() + { + $this->ole = null; + unset($GLOBALS['_OLE_INSTANCES']); + } + + /** + * Implements support for fread(), fgets() etc. + * + * @param int $count maximum number of bytes to read + * @return string + */ + public function stream_read($count) + { + if ($this->stream_eof()) { + return false; + } + $s = substr($this->data, $this->pos, $count); + $this->pos += $count; + return $s; + } + + /** + * Implements support for feof(). + * + * @return bool TRUE if the file pointer is at EOF; otherwise FALSE + */ + public function stream_eof() + { + return $this->pos >= strlen($this->data); + } + + /** + * Returns the position of the file pointer, i.e. its offset into the file + * stream. Implements support for ftell(). + * + * @return int + */ + public function stream_tell() + { + return $this->pos; + } + + /** + * Implements support for fseek(). + * + * @param int $offset byte offset + * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END + * @return bool + */ + public function stream_seek($offset, $whence) + { + if ($whence == SEEK_SET && $offset >= 0) { + $this->pos = $offset; + } elseif ($whence == SEEK_CUR && -$offset <= $this->pos) { + $this->pos += $offset; + } elseif ($whence == SEEK_END && -$offset <= sizeof($this->data)) { + $this->pos = strlen($this->data) + $offset; + } else { + return false; + } + return true; + } + + /** + * Implements support for fstat(). Currently the only supported field is + * "size". + * @return array + */ + public function stream_stat() + { + return array( + 'size' => strlen($this->data), + ); + } + + // Methods used by stream_wrapper_register() that are not implemented: + // bool stream_flush ( void ) + // int stream_write ( string data ) + // bool rename ( string path_from, string path_to ) + // bool mkdir ( string path, int mode, int options ) + // bool rmdir ( string path, int options ) + // bool dir_opendir ( string path, int options ) + // array url_stat ( string path, int flags ) + // string dir_readdir ( void ) + // bool dir_rewinddir ( void ) + // bool dir_closedir ( void ) } diff --git a/Classes/PHPExcel/Shared/OLE/PPS.php b/Classes/PHPExcel/Shared/OLE/PPS.php index 4db0ae4e2..80875f90d 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS.php +++ b/Classes/PHPExcel/Shared/OLE/PPS.php @@ -29,202 +29,202 @@ */ class PHPExcel_Shared_OLE_PPS { - /** - * The PPS index - * @var integer - */ - public $No; - - /** - * The PPS name (in Unicode) - * @var string - */ - public $Name; - - /** - * The PPS type. Dir, Root or File - * @var integer - */ - public $Type; - - /** - * The index of the previous PPS - * @var integer - */ - public $PrevPps; - - /** - * The index of the next PPS - * @var integer - */ - public $NextPps; - - /** - * The index of it's first child if this is a Dir or Root PPS - * @var integer - */ - public $DirPps; - - /** - * A timestamp - * @var integer - */ - public $Time1st; - - /** - * A timestamp - * @var integer - */ - public $Time2nd; - - /** - * Starting block (small or big) for this PPS's data inside the container - * @var integer - */ - public $_StartBlock; - - /** - * The size of the PPS's data (in bytes) - * @var integer - */ - public $Size; - - /** - * The PPS's data (only used if it's not using a temporary file) - * @var string - */ - public $_data; - - /** - * Array of child PPS's (only used by Root and Dir PPS's) - * @var array - */ - public $children = array(); - - /** - * Pointer to OLE container - * @var OLE - */ - public $ole; - - /** - * The constructor - * - * @access public - * @param integer $No The PPS index - * @param string $name The PPS name - * @param integer $type The PPS type. Dir, Root or File - * @param integer $prev The index of the previous PPS - * @param integer $next The index of the next PPS - * @param integer $dir The index of it's first child if this is a Dir or Root PPS - * @param integer $time_1st A timestamp - * @param integer $time_2nd A timestamp - * @param string $data The (usually binary) source data of the PPS - * @param array $children Array containing children PPS for this PPS - */ - public function __construct($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children) - { - $this->No = $No; - $this->Name = $name; - $this->Type = $type; - $this->PrevPps = $prev; - $this->NextPps = $next; - $this->DirPps = $dir; - $this->Time1st = $time_1st; - $this->Time2nd = $time_2nd; - $this->_data = $data; - $this->children = $children; - if ($data != '') { - $this->Size = strlen($data); - } else { - $this->Size = 0; - } - } - - /** - * Returns the amount of data saved for this PPS - * - * @access public - * @return integer The amount of data (in bytes) - */ - public function _DataLen() - { - if (!isset($this->_data)) { - return 0; - } - //if (isset($this->_PPS_FILE)) { - // fseek($this->_PPS_FILE, 0); - // $stats = fstat($this->_PPS_FILE); - // return $stats[7]; - //} else { - return strlen($this->_data); - //} - } - - /** - * Returns a string with the PPS's WK (What is a WK?) - * - * @access public - * @return string The binary string - */ - public function _getPpsWk() - { - $ret = str_pad($this->Name,64,"\x00"); - - $ret .= pack("v", strlen($this->Name) + 2) // 66 - . pack("c", $this->Type) // 67 - . pack("c", 0x00) //UK // 68 - . pack("V", $this->PrevPps) //Prev // 72 - . pack("V", $this->NextPps) //Next // 76 - . pack("V", $this->DirPps) //Dir // 80 - . "\x00\x09\x02\x00" // 84 - . "\x00\x00\x00\x00" // 88 - . "\xc0\x00\x00\x00" // 92 - . "\x00\x00\x00\x46" // 96 // Seems to be ok only for Root - . "\x00\x00\x00\x00" // 100 - . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time1st) // 108 - . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time2nd) // 116 - . pack("V", isset($this->_StartBlock)? - $this->_StartBlock:0) // 120 - . pack("V", $this->Size) // 124 - . pack("V", 0); // 128 - return $ret; - } - - /** - * Updates index and pointers to previous, next and children PPS's for this - * PPS. I don't think it'll work with Dir PPS's. - * - * @access public - * @param array &$raList Reference to the array of PPS's for the whole OLE - * container - * @return integer The index for this PPS - */ - public static function _savePpsSetPnt(&$raList, $to_save, $depth = 0) - { - if ( !is_array($to_save) || (empty($to_save)) ) { - return 0xFFFFFFFF; - } elseif( count($to_save) == 1 ) { - $cnt = count($raList); - // If the first entry, it's the root... Don't clone it! - $raList[$cnt] = ( $depth == 0 ) ? $to_save[0] : clone $to_save[0]; - $raList[$cnt]->No = $cnt; - $raList[$cnt]->PrevPps = 0xFFFFFFFF; - $raList[$cnt]->NextPps = 0xFFFFFFFF; - $raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++); - } else { - $iPos = floor(count($to_save) / 2); - $aPrev = array_slice($to_save, 0, $iPos); - $aNext = array_slice($to_save, $iPos + 1); - $cnt = count($raList); - // If the first entry, it's the root... Don't clone it! - $raList[$cnt] = ( $depth == 0 ) ? $to_save[$iPos] : clone $to_save[$iPos]; - $raList[$cnt]->No = $cnt; - $raList[$cnt]->PrevPps = self::_savePpsSetPnt($raList, $aPrev, $depth++); - $raList[$cnt]->NextPps = self::_savePpsSetPnt($raList, $aNext, $depth++); - $raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++); - - } - return $cnt; - } + /** + * The PPS index + * @var integer + */ + public $No; + + /** + * The PPS name (in Unicode) + * @var string + */ + public $Name; + + /** + * The PPS type. Dir, Root or File + * @var integer + */ + public $Type; + + /** + * The index of the previous PPS + * @var integer + */ + public $PrevPps; + + /** + * The index of the next PPS + * @var integer + */ + public $NextPps; + + /** + * The index of it's first child if this is a Dir or Root PPS + * @var integer + */ + public $DirPps; + + /** + * A timestamp + * @var integer + */ + public $Time1st; + + /** + * A timestamp + * @var integer + */ + public $Time2nd; + + /** + * Starting block (small or big) for this PPS's data inside the container + * @var integer + */ + public $_StartBlock; + + /** + * The size of the PPS's data (in bytes) + * @var integer + */ + public $Size; + + /** + * The PPS's data (only used if it's not using a temporary file) + * @var string + */ + public $_data; + + /** + * Array of child PPS's (only used by Root and Dir PPS's) + * @var array + */ + public $children = array(); + + /** + * Pointer to OLE container + * @var OLE + */ + public $ole; + + /** + * The constructor + * + * @access public + * @param integer $No The PPS index + * @param string $name The PPS name + * @param integer $type The PPS type. Dir, Root or File + * @param integer $prev The index of the previous PPS + * @param integer $next The index of the next PPS + * @param integer $dir The index of it's first child if this is a Dir or Root PPS + * @param integer $time_1st A timestamp + * @param integer $time_2nd A timestamp + * @param string $data The (usually binary) source data of the PPS + * @param array $children Array containing children PPS for this PPS + */ + public function __construct($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children) + { + $this->No = $No; + $this->Name = $name; + $this->Type = $type; + $this->PrevPps = $prev; + $this->NextPps = $next; + $this->DirPps = $dir; + $this->Time1st = $time_1st; + $this->Time2nd = $time_2nd; + $this->_data = $data; + $this->children = $children; + if ($data != '') { + $this->Size = strlen($data); + } else { + $this->Size = 0; + } + } + + /** + * Returns the amount of data saved for this PPS + * + * @access public + * @return integer The amount of data (in bytes) + */ + public function _DataLen() + { + if (!isset($this->_data)) { + return 0; + } + //if (isset($this->_PPS_FILE)) { + // fseek($this->_PPS_FILE, 0); + // $stats = fstat($this->_PPS_FILE); + // return $stats[7]; + //} else { + return strlen($this->_data); + //} + } + + /** + * Returns a string with the PPS's WK (What is a WK?) + * + * @access public + * @return string The binary string + */ + public function _getPpsWk() + { + $ret = str_pad($this->Name,64,"\x00"); + + $ret .= pack("v", strlen($this->Name) + 2) // 66 + . pack("c", $this->Type) // 67 + . pack("c", 0x00) //UK // 68 + . pack("V", $this->PrevPps) //Prev // 72 + . pack("V", $this->NextPps) //Next // 76 + . pack("V", $this->DirPps) //Dir // 80 + . "\x00\x09\x02\x00" // 84 + . "\x00\x00\x00\x00" // 88 + . "\xc0\x00\x00\x00" // 92 + . "\x00\x00\x00\x46" // 96 // Seems to be ok only for Root + . "\x00\x00\x00\x00" // 100 + . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time1st) // 108 + . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time2nd) // 116 + . pack("V", isset($this->_StartBlock)? + $this->_StartBlock:0) // 120 + . pack("V", $this->Size) // 124 + . pack("V", 0); // 128 + return $ret; + } + + /** + * Updates index and pointers to previous, next and children PPS's for this + * PPS. I don't think it'll work with Dir PPS's. + * + * @access public + * @param array &$raList Reference to the array of PPS's for the whole OLE + * container + * @return integer The index for this PPS + */ + public static function _savePpsSetPnt(&$raList, $to_save, $depth = 0) + { + if ( !is_array($to_save) || (empty($to_save)) ) { + return 0xFFFFFFFF; + } elseif( count($to_save) == 1 ) { + $cnt = count($raList); + // If the first entry, it's the root... Don't clone it! + $raList[$cnt] = ( $depth == 0 ) ? $to_save[0] : clone $to_save[0]; + $raList[$cnt]->No = $cnt; + $raList[$cnt]->PrevPps = 0xFFFFFFFF; + $raList[$cnt]->NextPps = 0xFFFFFFFF; + $raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++); + } else { + $iPos = floor(count($to_save) / 2); + $aPrev = array_slice($to_save, 0, $iPos); + $aNext = array_slice($to_save, $iPos + 1); + $cnt = count($raList); + // If the first entry, it's the root... Don't clone it! + $raList[$cnt] = ( $depth == 0 ) ? $to_save[$iPos] : clone $to_save[$iPos]; + $raList[$cnt]->No = $cnt; + $raList[$cnt]->PrevPps = self::_savePpsSetPnt($raList, $aPrev, $depth++); + $raList[$cnt]->NextPps = self::_savePpsSetPnt($raList, $aNext, $depth++); + $raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++); + + } + return $cnt; + } } diff --git a/Classes/PHPExcel/Shared/OLE/PPS/File.php b/Classes/PHPExcel/Shared/OLE/PPS/File.php index f061f568c..f0be587a3 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/File.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/File.php @@ -28,57 +28,57 @@ * @package PHPExcel_Shared_OLE */ class PHPExcel_Shared_OLE_PPS_File extends PHPExcel_Shared_OLE_PPS - { - /** - * The constructor - * - * @access public - * @param string $name The name of the file (in Unicode) - * @see OLE::Asc2Ucs() - */ - public function __construct($name) - { - parent::__construct( - null, - $name, - PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE, - null, - null, - null, - null, - null, - '', - array()); - } + { + /** + * The constructor + * + * @access public + * @param string $name The name of the file (in Unicode) + * @see OLE::Asc2Ucs() + */ + public function __construct($name) + { + parent::__construct( + null, + $name, + PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE, + null, + null, + null, + null, + null, + '', + array()); + } - /** - * Initialization method. Has to be called right after OLE_PPS_File(). - * - * @access public - * @return mixed true on success - */ - public function init() - { - return true; - } + /** + * Initialization method. Has to be called right after OLE_PPS_File(). + * + * @access public + * @return mixed true on success + */ + public function init() + { + return true; + } - /** - * Append data to PPS - * - * @access public - * @param string $data The data to append - */ - public function append($data) - { - $this->_data .= $data; - } + /** + * Append data to PPS + * + * @access public + * @param string $data The data to append + */ + public function append($data) + { + $this->_data .= $data; + } - /** - * Returns a stream for reading this file using fread() etc. - * @return resource a read-only stream - */ - public function getStream() - { - $this->ole->getStream($this); - } + /** + * Returns a stream for reading this file using fread() etc. + * @return resource a read-only stream + */ + public function getStream() + { + $this->ole->getStream($this); + } } diff --git a/Classes/PHPExcel/Shared/OLE/PPS/Root.php b/Classes/PHPExcel/Shared/OLE/PPS/Root.php index eb929d205..cbf01105d 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/Root.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/Root.php @@ -28,440 +28,440 @@ * @package PHPExcel_Shared_OLE */ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS - { + { - /** - * Directory for temporary files - * @var string - */ - protected $_tmp_dir = NULL; + /** + * Directory for temporary files + * @var string + */ + protected $_tmp_dir = NULL; - /** - * @param integer $time_1st A timestamp - * @param integer $time_2nd A timestamp - */ - public function __construct($time_1st, $time_2nd, $raChild) - { - $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + /** + * @param integer $time_1st A timestamp + * @param integer $time_2nd A timestamp + */ + public function __construct($time_1st, $time_2nd, $raChild) + { + $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); - parent::__construct( - null, - PHPExcel_Shared_OLE::Asc2Ucs('Root Entry'), - PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT, - null, - null, - null, - $time_1st, - $time_2nd, - null, - $raChild); - } + parent::__construct( + null, + PHPExcel_Shared_OLE::Asc2Ucs('Root Entry'), + PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT, + null, + null, + null, + $time_1st, + $time_2nd, + null, + $raChild); + } - /** - * Method for saving the whole OLE container (including files). - * In fact, if called with an empty argument (or '-'), it saves to a - * temporary file and then outputs it's contents to stdout. - * If a resource pointer to a stream created by fopen() is passed - * it will be used, but you have to close such stream by yourself. - * - * @param string|resource $filename The name of the file or stream where to save the OLE container. - * @access public - * @return mixed true on success - */ - public function save($filename) - { - // Initial Setting for saving - $this->_BIG_BLOCK_SIZE = pow(2, - ((isset($this->_BIG_BLOCK_SIZE))? self::_adjust2($this->_BIG_BLOCK_SIZE) : 9)); - $this->_SMALL_BLOCK_SIZE= pow(2, - ((isset($this->_SMALL_BLOCK_SIZE))? self::_adjust2($this->_SMALL_BLOCK_SIZE): 6)); + /** + * Method for saving the whole OLE container (including files). + * In fact, if called with an empty argument (or '-'), it saves to a + * temporary file and then outputs it's contents to stdout. + * If a resource pointer to a stream created by fopen() is passed + * it will be used, but you have to close such stream by yourself. + * + * @param string|resource $filename The name of the file or stream where to save the OLE container. + * @access public + * @return mixed true on success + */ + public function save($filename) + { + // Initial Setting for saving + $this->_BIG_BLOCK_SIZE = pow(2, + ((isset($this->_BIG_BLOCK_SIZE))? self::_adjust2($this->_BIG_BLOCK_SIZE) : 9)); + $this->_SMALL_BLOCK_SIZE= pow(2, + ((isset($this->_SMALL_BLOCK_SIZE))? self::_adjust2($this->_SMALL_BLOCK_SIZE): 6)); - if (is_resource($filename)) { - $this->_FILEH_ = $filename; - } else if ($filename == '-' || $filename == '') { - if ($this->_tmp_dir === NULL) - $this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir(); - $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root"); - $this->_FILEH_ = fopen($this->_tmp_filename,"w+b"); - if ($this->_FILEH_ == false) { - throw new PHPExcel_Writer_Exception("Can't create temporary file."); - } - } else { - $this->_FILEH_ = fopen($filename, "wb"); - } - if ($this->_FILEH_ == false) { - throw new PHPExcel_Writer_Exception("Can't open $filename. It may be in use or protected."); - } - // Make an array of PPS's (for Save) - $aList = array(); - PHPExcel_Shared_OLE_PPS::_savePpsSetPnt($aList, array($this)); - // calculate values for header - list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo); - // Save Header - $this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt); + if (is_resource($filename)) { + $this->_FILEH_ = $filename; + } else if ($filename == '-' || $filename == '') { + if ($this->_tmp_dir === NULL) + $this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir(); + $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root"); + $this->_FILEH_ = fopen($this->_tmp_filename,"w+b"); + if ($this->_FILEH_ == false) { + throw new PHPExcel_Writer_Exception("Can't create temporary file."); + } + } else { + $this->_FILEH_ = fopen($filename, "wb"); + } + if ($this->_FILEH_ == false) { + throw new PHPExcel_Writer_Exception("Can't open $filename. It may be in use or protected."); + } + // Make an array of PPS's (for Save) + $aList = array(); + PHPExcel_Shared_OLE_PPS::_savePpsSetPnt($aList, array($this)); + // calculate values for header + list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo); + // Save Header + $this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt); - // Make Small Data string (write SBD) - $this->_data = $this->_makeSmallData($aList); + // Make Small Data string (write SBD) + $this->_data = $this->_makeSmallData($aList); - // Write BB - $this->_saveBigData($iSBDcnt, $aList); - // Write PPS - $this->_savePps($aList); - // Write Big Block Depot and BDList and Adding Header informations - $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt); + // Write BB + $this->_saveBigData($iSBDcnt, $aList); + // Write PPS + $this->_savePps($aList); + // Write Big Block Depot and BDList and Adding Header informations + $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt); - if (!is_resource($filename)) { - fclose($this->_FILEH_); - } + if (!is_resource($filename)) { + fclose($this->_FILEH_); + } - return true; - } + return true; + } - /** - * Calculate some numbers - * - * @access public - * @param array $raList Reference to an array of PPS's - * @return array The array of numbers - */ - public function _calcSize(&$raList) - { - // Calculate Basic Setting - list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0); - $iSmallLen = 0; - $iSBcnt = 0; - $iCount = count($raList); - for ($i = 0; $i < $iCount; ++$i) { - if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) { - $raList[$i]->Size = $raList[$i]->_DataLen(); - if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) { - $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE) - + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0); - } else { - $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) + - (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0)); - } - } - } - $iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE; - $iSlCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE); - $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0); - $iBBcnt += (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) + - (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0)); - $iCnt = count($raList); - $iBdCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE; - $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0)); + /** + * Calculate some numbers + * + * @access public + * @param array $raList Reference to an array of PPS's + * @return array The array of numbers + */ + public function _calcSize(&$raList) + { + // Calculate Basic Setting + list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0); + $iSmallLen = 0; + $iSBcnt = 0; + $iCount = count($raList); + for ($i = 0; $i < $iCount; ++$i) { + if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) { + $raList[$i]->Size = $raList[$i]->_DataLen(); + if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) { + $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0); + } else { + $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0)); + } + } + } + $iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE; + $iSlCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE); + $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0); + $iBBcnt += (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) + + (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0)); + $iCnt = count($raList); + $iBdCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE; + $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0)); - return array($iSBDcnt, $iBBcnt, $iPPScnt); - } + return array($iSBDcnt, $iBBcnt, $iPPScnt); + } - /** - * Helper function for caculating a magic value for block sizes - * - * @access public - * @param integer $i2 The argument - * @see save() - * @return integer - */ - private static function _adjust2($i2) - { - $iWk = log($i2)/log(2); - return ($iWk > floor($iWk))? floor($iWk)+1:$iWk; - } + /** + * Helper function for caculating a magic value for block sizes + * + * @access public + * @param integer $i2 The argument + * @see save() + * @return integer + */ + private static function _adjust2($i2) + { + $iWk = log($i2)/log(2); + return ($iWk > floor($iWk))? floor($iWk)+1:$iWk; + } - /** - * Save OLE header - * - * @access public - * @param integer $iSBDcnt - * @param integer $iBBcnt - * @param integer $iPPScnt - */ - public function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt) - { - $FILE = $this->_FILEH_; + /** + * Save OLE header + * + * @access public + * @param integer $iSBDcnt + * @param integer $iBBcnt + * @param integer $iPPScnt + */ + public function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt) + { + $FILE = $this->_FILEH_; - // Calculate Basic Setting - $iBlCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; - $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + // Calculate Basic Setting + $iBlCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; - $iBdExL = 0; - $iAll = $iBBcnt + $iPPScnt + $iSBDcnt; - $iAllW = $iAll; - $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0); - $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0); + $iBdExL = 0; + $iAll = $iBBcnt + $iPPScnt + $iSBDcnt; + $iAllW = $iAll; + $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0); + $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0); - // Calculate BD count - if ($iBdCnt > $i1stBdL) { - while (1) { - ++$iBdExL; - ++$iAllW; - $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0); - $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0); - if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) { - break; - } - } - } + // Calculate BD count + if ($iBdCnt > $i1stBdL) { + while (1) { + ++$iBdExL; + ++$iAllW; + $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0); + $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0); + if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) { + break; + } + } + } - // Save Header - fwrite($FILE, - "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" - . "\x00\x00\x00\x00" - . "\x00\x00\x00\x00" - . "\x00\x00\x00\x00" - . "\x00\x00\x00\x00" - . pack("v", 0x3b) - . pack("v", 0x03) - . pack("v", -2) - . pack("v", 9) - . pack("v", 6) - . pack("v", 0) - . "\x00\x00\x00\x00" - . "\x00\x00\x00\x00" - . pack("V", $iBdCnt) - . pack("V", $iBBcnt+$iSBDcnt) //ROOT START - . pack("V", 0) - . pack("V", 0x1000) - . pack("V", $iSBDcnt ? 0 : -2) //Small Block Depot - . pack("V", $iSBDcnt) - ); - // Extra BDList Start, Count - if ($iBdCnt < $i1stBdL) { - fwrite($FILE, - pack("V", -2) // Extra BDList Start - . pack("V", 0) // Extra BDList Count - ); - } else { - fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL)); - } + // Save Header + fwrite($FILE, + "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . pack("v", 0x3b) + . pack("v", 0x03) + . pack("v", -2) + . pack("v", 9) + . pack("v", 6) + . pack("v", 0) + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . pack("V", $iBdCnt) + . pack("V", $iBBcnt+$iSBDcnt) //ROOT START + . pack("V", 0) + . pack("V", 0x1000) + . pack("V", $iSBDcnt ? 0 : -2) //Small Block Depot + . pack("V", $iSBDcnt) + ); + // Extra BDList Start, Count + if ($iBdCnt < $i1stBdL) { + fwrite($FILE, + pack("V", -2) // Extra BDList Start + . pack("V", 0) // Extra BDList Count + ); + } else { + fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL)); + } - // BDList - for ($i = 0; $i < $i1stBdL && $i < $iBdCnt; ++$i) { - fwrite($FILE, pack("V", $iAll+$i)); - } - if ($i < $i1stBdL) { - $jB = $i1stBdL - $i; - for ($j = 0; $j < $jB; ++$j) { - fwrite($FILE, (pack("V", -1))); - } - } - } + // BDList + for ($i = 0; $i < $i1stBdL && $i < $iBdCnt; ++$i) { + fwrite($FILE, pack("V", $iAll+$i)); + } + if ($i < $i1stBdL) { + $jB = $i1stBdL - $i; + for ($j = 0; $j < $jB; ++$j) { + fwrite($FILE, (pack("V", -1))); + } + } + } - /** - * Saving big data (PPS's with data bigger than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) - * - * @access public - * @param integer $iStBlk - * @param array &$raList Reference to array of PPS's - */ - public function _saveBigData($iStBlk, &$raList) - { - $FILE = $this->_FILEH_; + /** + * Saving big data (PPS's with data bigger than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) + * + * @access public + * @param integer $iStBlk + * @param array &$raList Reference to array of PPS's + */ + public function _saveBigData($iStBlk, &$raList) + { + $FILE = $this->_FILEH_; - // cycle through PPS's - $iCount = count($raList); - for ($i = 0; $i < $iCount; ++$i) { - if ($raList[$i]->Type != PHPExcel_Shared_OLE::OLE_PPS_TYPE_DIR) { - $raList[$i]->Size = $raList[$i]->_DataLen(); - if (($raList[$i]->Size >= PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) || - (($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data))) - { - // Write Data - //if (isset($raList[$i]->_PPS_FILE)) { - // $iLen = 0; - // fseek($raList[$i]->_PPS_FILE, 0); // To The Top - // while($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { - // $iLen += strlen($sBuff); - // fwrite($FILE, $sBuff); - // } - //} else { - fwrite($FILE, $raList[$i]->_data); - //} + // cycle through PPS's + $iCount = count($raList); + for ($i = 0; $i < $iCount; ++$i) { + if ($raList[$i]->Type != PHPExcel_Shared_OLE::OLE_PPS_TYPE_DIR) { + $raList[$i]->Size = $raList[$i]->_DataLen(); + if (($raList[$i]->Size >= PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) || + (($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data))) + { + // Write Data + //if (isset($raList[$i]->_PPS_FILE)) { + // $iLen = 0; + // fseek($raList[$i]->_PPS_FILE, 0); // To The Top + // while($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { + // $iLen += strlen($sBuff); + // fwrite($FILE, $sBuff); + // } + //} else { + fwrite($FILE, $raList[$i]->_data); + //} - if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE) { - fwrite($FILE, str_repeat("\x00", $this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE))); - } - // Set For PPS - $raList[$i]->_StartBlock = $iStBlk; - $iStBlk += - (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) + - (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0)); - } - // Close file for each PPS, and unlink it - //if (isset($raList[$i]->_PPS_FILE)) { - // fclose($raList[$i]->_PPS_FILE); - // $raList[$i]->_PPS_FILE = null; - // unlink($raList[$i]->_tmp_filename); - //} - } - } - } + if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE) { + fwrite($FILE, str_repeat("\x00", $this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE))); + } + // Set For PPS + $raList[$i]->_StartBlock = $iStBlk; + $iStBlk += + (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0)); + } + // Close file for each PPS, and unlink it + //if (isset($raList[$i]->_PPS_FILE)) { + // fclose($raList[$i]->_PPS_FILE); + // $raList[$i]->_PPS_FILE = null; + // unlink($raList[$i]->_tmp_filename); + //} + } + } + } - /** - * get small data (PPS's with data smaller than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) - * - * @access public - * @param array &$raList Reference to array of PPS's - */ - public function _makeSmallData(&$raList) - { - $sRes = ''; - $FILE = $this->_FILEH_; - $iSmBlk = 0; + /** + * get small data (PPS's with data smaller than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) + * + * @access public + * @param array &$raList Reference to array of PPS's + */ + public function _makeSmallData(&$raList) + { + $sRes = ''; + $FILE = $this->_FILEH_; + $iSmBlk = 0; - $iCount = count($raList); - for ($i = 0; $i < $iCount; ++$i) { - // Make SBD, small data string - if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) { - if ($raList[$i]->Size <= 0) { - continue; - } - if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) { - $iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE) - + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0); - // Add to SBD - $jB = $iSmbCnt - 1; - for ($j = 0; $j < $jB; ++$j) { - fwrite($FILE, pack("V", $j+$iSmBlk+1)); - } - fwrite($FILE, pack("V", -2)); + $iCount = count($raList); + for ($i = 0; $i < $iCount; ++$i) { + // Make SBD, small data string + if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) { + if ($raList[$i]->Size <= 0) { + continue; + } + if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) { + $iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0); + // Add to SBD + $jB = $iSmbCnt - 1; + for ($j = 0; $j < $jB; ++$j) { + fwrite($FILE, pack("V", $j+$iSmBlk+1)); + } + fwrite($FILE, pack("V", -2)); - //// Add to Data String(this will be written for RootEntry) - //if ($raList[$i]->_PPS_FILE) { - // fseek($raList[$i]->_PPS_FILE, 0); // To The Top - // while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { - // $sRes .= $sBuff; - // } - //} else { - $sRes .= $raList[$i]->_data; - //} - if ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) { - $sRes .= str_repeat("\x00",$this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); - } - // Set for PPS - $raList[$i]->_StartBlock = $iSmBlk; - $iSmBlk += $iSmbCnt; - } - } - } - $iSbCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE); - if ($iSmBlk % $iSbCnt) { - $iB = $iSbCnt - ($iSmBlk % $iSbCnt); - for ($i = 0; $i < $iB; ++$i) { - fwrite($FILE, pack("V", -1)); - } - } - return $sRes; - } + //// Add to Data String(this will be written for RootEntry) + //if ($raList[$i]->_PPS_FILE) { + // fseek($raList[$i]->_PPS_FILE, 0); // To The Top + // while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { + // $sRes .= $sBuff; + // } + //} else { + $sRes .= $raList[$i]->_data; + //} + if ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) { + $sRes .= str_repeat("\x00",$this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); + } + // Set for PPS + $raList[$i]->_StartBlock = $iSmBlk; + $iSmBlk += $iSmbCnt; + } + } + } + $iSbCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE); + if ($iSmBlk % $iSbCnt) { + $iB = $iSbCnt - ($iSmBlk % $iSbCnt); + for ($i = 0; $i < $iB; ++$i) { + fwrite($FILE, pack("V", -1)); + } + } + return $sRes; + } - /** - * Saves all the PPS's WKs - * - * @access public - * @param array $raList Reference to an array with all PPS's - */ - public function _savePps(&$raList) - { - // Save each PPS WK - $iC = count($raList); - for ($i = 0; $i < $iC; ++$i) { - fwrite($this->_FILEH_, $raList[$i]->_getPpsWk()); - } - // Adjust for Block - $iCnt = count($raList); - $iBCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE; - if ($iCnt % $iBCnt) { - fwrite($this->_FILEH_, str_repeat("\x00",($iBCnt - ($iCnt % $iBCnt)) * PHPExcel_Shared_OLE::OLE_PPS_SIZE)); - } - } + /** + * Saves all the PPS's WKs + * + * @access public + * @param array $raList Reference to an array with all PPS's + */ + public function _savePps(&$raList) + { + // Save each PPS WK + $iC = count($raList); + for ($i = 0; $i < $iC; ++$i) { + fwrite($this->_FILEH_, $raList[$i]->_getPpsWk()); + } + // Adjust for Block + $iCnt = count($raList); + $iBCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE; + if ($iCnt % $iBCnt) { + fwrite($this->_FILEH_, str_repeat("\x00",($iBCnt - ($iCnt % $iBCnt)) * PHPExcel_Shared_OLE::OLE_PPS_SIZE)); + } + } - /** - * Saving Big Block Depot - * - * @access public - * @param integer $iSbdSize - * @param integer $iBsize - * @param integer $iPpsCnt - */ - public function _saveBbd($iSbdSize, $iBsize, $iPpsCnt) - { - $FILE = $this->_FILEH_; - // Calculate Basic Setting - $iBbCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; - $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + /** + * Saving Big Block Depot + * + * @access public + * @param integer $iSbdSize + * @param integer $iBsize + * @param integer $iPpsCnt + */ + public function _saveBbd($iSbdSize, $iBsize, $iPpsCnt) + { + $FILE = $this->_FILEH_; + // Calculate Basic Setting + $iBbCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; - $iBdExL = 0; - $iAll = $iBsize + $iPpsCnt + $iSbdSize; - $iAllW = $iAll; - $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0); - $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); - // Calculate BD count - if ($iBdCnt >$i1stBdL) { - while (1) { - ++$iBdExL; - ++$iAllW; - $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0); - $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); - if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) { - break; - } - } - } + $iBdExL = 0; + $iAll = $iBsize + $iPpsCnt + $iSbdSize; + $iAllW = $iAll; + $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0); + $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); + // Calculate BD count + if ($iBdCnt >$i1stBdL) { + while (1) { + ++$iBdExL; + ++$iAllW; + $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0); + $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); + if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) { + break; + } + } + } - // Making BD - // Set for SBD - if ($iSbdSize > 0) { - for ($i = 0; $i < ($iSbdSize - 1); ++$i) { - fwrite($FILE, pack("V", $i+1)); - } - fwrite($FILE, pack("V", -2)); - } - // Set for B - for ($i = 0; $i < ($iBsize - 1); ++$i) { - fwrite($FILE, pack("V", $i+$iSbdSize+1)); - } - fwrite($FILE, pack("V", -2)); + // Making BD + // Set for SBD + if ($iSbdSize > 0) { + for ($i = 0; $i < ($iSbdSize - 1); ++$i) { + fwrite($FILE, pack("V", $i+1)); + } + fwrite($FILE, pack("V", -2)); + } + // Set for B + for ($i = 0; $i < ($iBsize - 1); ++$i) { + fwrite($FILE, pack("V", $i+$iSbdSize+1)); + } + fwrite($FILE, pack("V", -2)); - // Set for PPS - for ($i = 0; $i < ($iPpsCnt - 1); ++$i) { - fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1)); - } - fwrite($FILE, pack("V", -2)); - // Set for BBD itself ( 0xFFFFFFFD : BBD) - for ($i = 0; $i < $iBdCnt; ++$i) { - fwrite($FILE, pack("V", 0xFFFFFFFD)); - } - // Set for ExtraBDList - for ($i = 0; $i < $iBdExL; ++$i) { - fwrite($FILE, pack("V", 0xFFFFFFFC)); - } - // Adjust for Block - if (($iAllW + $iBdCnt) % $iBbCnt) { - $iBlock = ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); - for ($i = 0; $i < $iBlock; ++$i) { - fwrite($FILE, pack("V", -1)); - } - } - // Extra BDList - if ($iBdCnt > $i1stBdL) { - $iN=0; - $iNb=0; - for ($i = $i1stBdL;$i < $iBdCnt; $i++, ++$iN) { - if ($iN >= ($iBbCnt - 1)) { - $iN = 0; - ++$iNb; - fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb)); - } - fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i)); - } - if (($iBdCnt-$i1stBdL) % ($iBbCnt-1)) { - $iB = ($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1)); - for ($i = 0; $i < $iB; ++$i) { - fwrite($FILE, pack("V", -1)); - } - } - fwrite($FILE, pack("V", -2)); - } - } + // Set for PPS + for ($i = 0; $i < ($iPpsCnt - 1); ++$i) { + fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1)); + } + fwrite($FILE, pack("V", -2)); + // Set for BBD itself ( 0xFFFFFFFD : BBD) + for ($i = 0; $i < $iBdCnt; ++$i) { + fwrite($FILE, pack("V", 0xFFFFFFFD)); + } + // Set for ExtraBDList + for ($i = 0; $i < $iBdExL; ++$i) { + fwrite($FILE, pack("V", 0xFFFFFFFC)); + } + // Adjust for Block + if (($iAllW + $iBdCnt) % $iBbCnt) { + $iBlock = ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); + for ($i = 0; $i < $iBlock; ++$i) { + fwrite($FILE, pack("V", -1)); + } + } + // Extra BDList + if ($iBdCnt > $i1stBdL) { + $iN=0; + $iNb=0; + for ($i = $i1stBdL;$i < $iBdCnt; $i++, ++$iN) { + if ($iN >= ($iBbCnt - 1)) { + $iN = 0; + ++$iNb; + fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb)); + } + fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i)); + } + if (($iBdCnt-$i1stBdL) % ($iBbCnt-1)) { + $iB = ($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1)); + for ($i = 0; $i < $iB; ++$i) { + fwrite($FILE, pack("V", -1)); + } + } + fwrite($FILE, pack("V", -2)); + } + } } diff --git a/Classes/PHPExcel/Shared/OLERead.php b/Classes/PHPExcel/Shared/OLERead.php index b50fd0554..9a8729f12 100644 --- a/Classes/PHPExcel/Shared/OLERead.php +++ b/Classes/PHPExcel/Shared/OLERead.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -29,289 +29,289 @@ define('IDENTIFIER_OLE', pack('CCCCCCCC', 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1)); class PHPExcel_Shared_OLERead { - private $data = ''; + private $data = ''; - // OLE identifier - const IDENTIFIER_OLE = IDENTIFIER_OLE; + // OLE identifier + const IDENTIFIER_OLE = IDENTIFIER_OLE; - // Size of a sector = 512 bytes - const BIG_BLOCK_SIZE = 0x200; + // Size of a sector = 512 bytes + const BIG_BLOCK_SIZE = 0x200; - // Size of a short sector = 64 bytes - const SMALL_BLOCK_SIZE = 0x40; + // Size of a short sector = 64 bytes + const SMALL_BLOCK_SIZE = 0x40; - // Size of a directory entry always = 128 bytes - const PROPERTY_STORAGE_BLOCK_SIZE = 0x80; + // Size of a directory entry always = 128 bytes + const PROPERTY_STORAGE_BLOCK_SIZE = 0x80; - // Minimum size of a standard stream = 4096 bytes, streams smaller than this are stored as short streams - const SMALL_BLOCK_THRESHOLD = 0x1000; + // Minimum size of a standard stream = 4096 bytes, streams smaller than this are stored as short streams + const SMALL_BLOCK_THRESHOLD = 0x1000; - // header offsets - const NUM_BIG_BLOCK_DEPOT_BLOCKS_POS = 0x2c; - const ROOT_START_BLOCK_POS = 0x30; - const SMALL_BLOCK_DEPOT_BLOCK_POS = 0x3c; - const EXTENSION_BLOCK_POS = 0x44; - const NUM_EXTENSION_BLOCK_POS = 0x48; - const BIG_BLOCK_DEPOT_BLOCKS_POS = 0x4c; + // header offsets + const NUM_BIG_BLOCK_DEPOT_BLOCKS_POS = 0x2c; + const ROOT_START_BLOCK_POS = 0x30; + const SMALL_BLOCK_DEPOT_BLOCK_POS = 0x3c; + const EXTENSION_BLOCK_POS = 0x44; + const NUM_EXTENSION_BLOCK_POS = 0x48; + const BIG_BLOCK_DEPOT_BLOCKS_POS = 0x4c; - // property storage offsets (directory offsets) - const SIZE_OF_NAME_POS = 0x40; - const TYPE_POS = 0x42; - const START_BLOCK_POS = 0x74; - const SIZE_POS = 0x78; + // property storage offsets (directory offsets) + const SIZE_OF_NAME_POS = 0x40; + const TYPE_POS = 0x42; + const START_BLOCK_POS = 0x74; + const SIZE_POS = 0x78; - public $wrkbook = null; - public $summaryInformation = null; - public $documentSummaryInformation = null; + public $wrkbook = null; + public $summaryInformation = null; + public $documentSummaryInformation = null; - /** - * Read the file - * - * @param $sFileName string Filename - * @throws PHPExcel_Reader_Exception - */ - public function read($sFileName) - { - // Check if file exists and is readable - if(!is_readable($sFileName)) { - throw new PHPExcel_Reader_Exception("Could not open " . $sFileName . " for reading! File does not exist, or it is not readable."); - } + /** + * Read the file + * + * @param $sFileName string Filename + * @throws PHPExcel_Reader_Exception + */ + public function read($sFileName) + { + // Check if file exists and is readable + if(!is_readable($sFileName)) { + throw new PHPExcel_Reader_Exception("Could not open " . $sFileName . " for reading! File does not exist, or it is not readable."); + } - // Get the file identifier - // Don't bother reading the whole file until we know it's a valid OLE file - $this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8); + // Get the file identifier + // Don't bother reading the whole file until we know it's a valid OLE file + $this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8); - // Check OLE identifier - if ($this->data != self::IDENTIFIER_OLE) { - throw new PHPExcel_Reader_Exception('The filename ' . $sFileName . ' is not recognised as an OLE file'); - } + // Check OLE identifier + if ($this->data != self::IDENTIFIER_OLE) { + throw new PHPExcel_Reader_Exception('The filename ' . $sFileName . ' is not recognised as an OLE file'); + } - // Get the file data - $this->data = file_get_contents($sFileName); + // Get the file data + $this->data = file_get_contents($sFileName); - // Total number of sectors used for the SAT - $this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); + // Total number of sectors used for the SAT + $this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); - // SecID of the first sector of the directory stream - $this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS); + // SecID of the first sector of the directory stream + $this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS); - // SecID of the first sector of the SSAT (or -2 if not extant) - $this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS); + // SecID of the first sector of the SSAT (or -2 if not extant) + $this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS); - // SecID of the first sector of the MSAT (or -2 if no additional sectors are used) - $this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS); + // SecID of the first sector of the MSAT (or -2 if no additional sectors are used) + $this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS); - // Total number of sectors used by MSAT - $this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS); + // Total number of sectors used by MSAT + $this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS); - $bigBlockDepotBlocks = array(); - $pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS; + $bigBlockDepotBlocks = array(); + $pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS; - $bbdBlocks = $this->numBigBlockDepotBlocks; + $bbdBlocks = $this->numBigBlockDepotBlocks; - if ($this->numExtensionBlocks != 0) { - $bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS)/4; - } + if ($this->numExtensionBlocks != 0) { + $bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS)/4; + } - for ($i = 0; $i < $bbdBlocks; ++$i) { - $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos); - $pos += 4; - } - - for ($j = 0; $j < $this->numExtensionBlocks; ++$j) { - $pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE; - $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1); - - for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) { - $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos); - $pos += 4; - } - - $bbdBlocks += $blocksToRead; - if ($bbdBlocks < $this->numBigBlockDepotBlocks) { - $this->extensionBlock = self::_GetInt4d($this->data, $pos); - } - } - - $pos = 0; - $this->bigBlockChain = ''; - $bbs = self::BIG_BLOCK_SIZE / 4; - for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) { - $pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE; - - $this->bigBlockChain .= substr($this->data, $pos, 4*$bbs); - $pos += 4*$bbs; - } - - $pos = 0; - $sbdBlock = $this->sbdStartBlock; - $this->smallBlockChain = ''; - while ($sbdBlock != -2) { - $pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE; - - $this->smallBlockChain .= substr($this->data, $pos, 4*$bbs); - $pos += 4*$bbs; - - $sbdBlock = self::_GetInt4d($this->bigBlockChain, $sbdBlock*4); - } - - // read the directory stream - $block = $this->rootStartBlock; - $this->entry = $this->_readData($block); - - $this->_readPropertySets(); - } - - /** - * Extract binary stream data - * - * @return string - */ - public function getStream($stream) - { - if ($stream === NULL) { - return null; - } - - $streamData = ''; - - if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) { - $rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']); - - $block = $this->props[$stream]['startBlock']; - - while ($block != -2) { - $pos = $block * self::SMALL_BLOCK_SIZE; - $streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE); - - $block = self::_GetInt4d($this->smallBlockChain, $block*4); - } - - return $streamData; - } else { - $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE; - if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) { - ++$numBlocks; - } - - if ($numBlocks == 0) return ''; - - $block = $this->props[$stream]['startBlock']; - - while ($block != -2) { - $pos = ($block + 1) * self::BIG_BLOCK_SIZE; - $streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); - $block = self::_GetInt4d($this->bigBlockChain, $block*4); - } - - return $streamData; - } - } - - /** - * Read a standard stream (by joining sectors using information from SAT) - * - * @param int $bl Sector ID where the stream starts - * @return string Data for standard stream - */ - private function _readData($bl) - { - $block = $bl; - $data = ''; - - while ($block != -2) { - $pos = ($block + 1) * self::BIG_BLOCK_SIZE; - $data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); - $block = self::_GetInt4d($this->bigBlockChain, $block*4); - } - return $data; - } - - /** - * Read entries in the directory stream. - */ - private function _readPropertySets() { - $offset = 0; - - // loop through entires, each entry is 128 bytes - $entryLen = strlen($this->entry); - while ($offset < $entryLen) { - // entry data (128 bytes) - $d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE); - - // size in bytes of name - $nameSize = ord($d[self::SIZE_OF_NAME_POS]) | (ord($d[self::SIZE_OF_NAME_POS+1]) << 8); - - // type of entry - $type = ord($d[self::TYPE_POS]); - - // sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook) - // sectorID of first sector of the short-stream container stream, if this entry is root entry - $startBlock = self::_GetInt4d($d, self::START_BLOCK_POS); - - $size = self::_GetInt4d($d, self::SIZE_POS); - - $name = str_replace("\x00", "", substr($d,0,$nameSize)); - - - $this->props[] = array ( - 'name' => $name, - 'type' => $type, - 'startBlock' => $startBlock, - 'size' => $size); - - // tmp helper to simplify checks - $upName = strtoupper($name); - - // Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook) - if (($upName === 'WORKBOOK') || ($upName === 'BOOK')) { - $this->wrkbook = count($this->props) - 1; - } - else if ( $upName === 'ROOT ENTRY' || $upName === 'R') { - // Root entry - $this->rootentry = count($this->props) - 1; - } - - // Summary information - if ($name == chr(5) . 'SummaryInformation') { -// echo 'Summary Information<br />'; - $this->summaryInformation = count($this->props) - 1; - } - - // Additional Document Summary information - if ($name == chr(5) . 'DocumentSummaryInformation') { -// echo 'Document Summary Information<br />'; - $this->documentSummaryInformation = count($this->props) - 1; - } - - $offset += self::PROPERTY_STORAGE_BLOCK_SIZE; - } - - } - - /** - * Read 4 bytes of data at specified position - * - * @param string $data - * @param int $pos - * @return int - */ - private static function _GetInt4d($data, $pos) - { - // FIX: represent numbers correctly on 64-bit system - // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 - // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems - $_or_24 = ord($data[$pos + 3]); - if ($_or_24 >= 128) { - // negative number - $_ord_24 = -abs((256 - $_or_24) << 24); - } else { - $_ord_24 = ($_or_24 & 127) << 24; - } - return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24; - } + for ($i = 0; $i < $bbdBlocks; ++$i) { + $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos); + $pos += 4; + } + + for ($j = 0; $j < $this->numExtensionBlocks; ++$j) { + $pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE; + $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1); + + for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) { + $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos); + $pos += 4; + } + + $bbdBlocks += $blocksToRead; + if ($bbdBlocks < $this->numBigBlockDepotBlocks) { + $this->extensionBlock = self::_GetInt4d($this->data, $pos); + } + } + + $pos = 0; + $this->bigBlockChain = ''; + $bbs = self::BIG_BLOCK_SIZE / 4; + for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) { + $pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE; + + $this->bigBlockChain .= substr($this->data, $pos, 4*$bbs); + $pos += 4*$bbs; + } + + $pos = 0; + $sbdBlock = $this->sbdStartBlock; + $this->smallBlockChain = ''; + while ($sbdBlock != -2) { + $pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE; + + $this->smallBlockChain .= substr($this->data, $pos, 4*$bbs); + $pos += 4*$bbs; + + $sbdBlock = self::_GetInt4d($this->bigBlockChain, $sbdBlock*4); + } + + // read the directory stream + $block = $this->rootStartBlock; + $this->entry = $this->_readData($block); + + $this->_readPropertySets(); + } + + /** + * Extract binary stream data + * + * @return string + */ + public function getStream($stream) + { + if ($stream === NULL) { + return null; + } + + $streamData = ''; + + if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) { + $rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']); + + $block = $this->props[$stream]['startBlock']; + + while ($block != -2) { + $pos = $block * self::SMALL_BLOCK_SIZE; + $streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE); + + $block = self::_GetInt4d($this->smallBlockChain, $block*4); + } + + return $streamData; + } else { + $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE; + if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) { + ++$numBlocks; + } + + if ($numBlocks == 0) return ''; + + $block = $this->props[$stream]['startBlock']; + + while ($block != -2) { + $pos = ($block + 1) * self::BIG_BLOCK_SIZE; + $streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); + $block = self::_GetInt4d($this->bigBlockChain, $block*4); + } + + return $streamData; + } + } + + /** + * Read a standard stream (by joining sectors using information from SAT) + * + * @param int $bl Sector ID where the stream starts + * @return string Data for standard stream + */ + private function _readData($bl) + { + $block = $bl; + $data = ''; + + while ($block != -2) { + $pos = ($block + 1) * self::BIG_BLOCK_SIZE; + $data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); + $block = self::_GetInt4d($this->bigBlockChain, $block*4); + } + return $data; + } + + /** + * Read entries in the directory stream. + */ + private function _readPropertySets() { + $offset = 0; + + // loop through entires, each entry is 128 bytes + $entryLen = strlen($this->entry); + while ($offset < $entryLen) { + // entry data (128 bytes) + $d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE); + + // size in bytes of name + $nameSize = ord($d[self::SIZE_OF_NAME_POS]) | (ord($d[self::SIZE_OF_NAME_POS+1]) << 8); + + // type of entry + $type = ord($d[self::TYPE_POS]); + + // sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook) + // sectorID of first sector of the short-stream container stream, if this entry is root entry + $startBlock = self::_GetInt4d($d, self::START_BLOCK_POS); + + $size = self::_GetInt4d($d, self::SIZE_POS); + + $name = str_replace("\x00", "", substr($d,0,$nameSize)); + + + $this->props[] = array ( + 'name' => $name, + 'type' => $type, + 'startBlock' => $startBlock, + 'size' => $size); + + // tmp helper to simplify checks + $upName = strtoupper($name); + + // Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook) + if (($upName === 'WORKBOOK') || ($upName === 'BOOK')) { + $this->wrkbook = count($this->props) - 1; + } + else if ( $upName === 'ROOT ENTRY' || $upName === 'R') { + // Root entry + $this->rootentry = count($this->props) - 1; + } + + // Summary information + if ($name == chr(5) . 'SummaryInformation') { +// echo 'Summary Information<br />'; + $this->summaryInformation = count($this->props) - 1; + } + + // Additional Document Summary information + if ($name == chr(5) . 'DocumentSummaryInformation') { +// echo 'Document Summary Information<br />'; + $this->documentSummaryInformation = count($this->props) - 1; + } + + $offset += self::PROPERTY_STORAGE_BLOCK_SIZE; + } + + } + + /** + * Read 4 bytes of data at specified position + * + * @param string $data + * @param int $pos + * @return int + */ + private static function _GetInt4d($data, $pos) + { + // FIX: represent numbers correctly on 64-bit system + // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 + // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems + $_or_24 = ord($data[$pos + 3]); + if ($_or_24 >= 128) { + // negative number + $_ord_24 = -abs((256 - $_or_24) << 24); + } else { + $_ord_24 = ($_or_24 & 127) << 24; + } + return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24; + } } diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index 5b81e6790..cafc4fa0c 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -327,7 +327,7 @@ function create($p_filelist) } else if ($v_size > 2) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Invalid number / type of arguments"); + "Invalid number / type of arguments"); return 0; } } @@ -388,7 +388,7 @@ function create($p_filelist) ,PCLZIP_ATT_FILE_MTIME => 'optional' ,PCLZIP_ATT_FILE_CONTENT => 'optional' ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); + ); foreach ($v_att_list as $v_entry) { $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], @@ -492,7 +492,7 @@ function add($p_filelist) PCLZIP_OPT_TEMP_FILE_ON => 'optional', PCLZIP_OPT_TEMP_FILE_OFF => 'optional' //, PCLZIP_OPT_CRYPT => 'optional' - )); + )); if ($v_result != 1) { return 0; } @@ -571,7 +571,7 @@ function add($p_filelist) ,PCLZIP_ATT_FILE_MTIME => 'optional' ,PCLZIP_ATT_FILE_CONTENT => 'optional' ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); + ); foreach ($v_att_list as $v_entry) { $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], @@ -751,7 +751,7 @@ function extract() PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', PCLZIP_OPT_TEMP_FILE_ON => 'optional', PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); + )); if ($v_result != 1) { return 0; } @@ -805,7 +805,7 @@ function extract() // ----- Call the extracting fct $p_list = array(); $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, - $v_remove_all_path, $v_options); + $v_remove_all_path, $v_options); if ($v_result < 1) { unset($p_list); return(0); @@ -907,7 +907,7 @@ function extractByIndex($p_index) PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', PCLZIP_OPT_TEMP_FILE_ON => 'optional', PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); + )); if ($v_result != 1) { return 0; } @@ -1374,7 +1374,7 @@ function privCheckFormat($p_level=0) { $v_result = true; - // ----- Reset the file system cache + // ----- Reset the file system cache clearstatcache(); // ----- Reset the error handler @@ -1596,9 +1596,9 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, - "Missing parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); + "Missing parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); // ----- Return return PclZip::errorCode(); @@ -1611,9 +1611,9 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, - "Wrong parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); + "Wrong parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); // ----- Return return PclZip::errorCode(); @@ -1779,8 +1779,8 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request default : // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Unknown parameter '" - .$p_options_list[$i]."'"); + "Unknown parameter '" + .$p_options_list[$i]."'"); // ----- Return return PclZip::errorCode(); @@ -1954,7 +1954,7 @@ function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requ default : // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Unknown parameter '".$v_key."'"); + "Unknown parameter '".$v_key."'"); // ----- Return return PclZip::errorCode(); @@ -3033,12 +3033,12 @@ function privWriteFileHeader(&$p_header) // ----- Packed data $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, - $p_header['version_extracted'], $p_header['flag'], + $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], - $p_header['size'], + $p_header['size'], strlen($p_header['stored_filename']), - $p_header['extra_len']); + $p_header['extra_len']); // ----- Write the first 148 bytes of the header in the archive fputs($this->zip_fd, $v_binary_data, 30); @@ -3080,14 +3080,14 @@ function privWriteCentralFileHeader(&$p_header) // ----- Packed data $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, - $p_header['version'], $p_header['version_extracted'], + $p_header['version'], $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], - $v_mtime, $v_mdate, $p_header['crc'], + $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), - $p_header['extra_len'], $p_header['comment_len'], + $p_header['extra_len'], $p_header['comment_len'], $p_header['disk'], $p_header['internal'], - $p_header['external'], $p_header['offset']); + $p_header['external'], $p_header['offset']); // ----- Write the 42 bytes of the header in the zip file fputs($this->zip_fd, $v_binary_data, 46); @@ -3123,8 +3123,8 @@ function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) // ----- Packed data $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, - $p_nb_entries, $p_size, - $p_offset, strlen($p_comment)); + $p_nb_entries, $p_size, + $p_offset, strlen($p_comment)); // ----- Write the 22 bytes of the header in the zip file fputs($this->zip_fd, $v_binary_data, 22); @@ -3281,9 +3281,9 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all // ----- Check the path if ( ($p_path == "") - || ( (substr($p_path, 0, 1) != "/") - && (substr($p_path, 0, 3) != "../") - && (substr($p_path,1,2)!=":/"))) + || ( (substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") + && (substr($p_path,1,2)!=":/"))) $p_path = "./".$p_path; // ----- Reduce the path last (and duplicated) '/' @@ -3433,50 +3433,50 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all $v_extract = true; } - // ----- Check compression method - if ( ($v_extract) - && ( ($v_header['compression'] != 8) - && ($v_header['compression'] != 0))) { + // ----- Check compression method + if ( ($v_extract) + && ( ($v_header['compression'] != 8) + && ($v_header['compression'] != 0))) { $v_header['status'] = 'unsupported_compression'; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { $this->privSwapBackMagicQuotes(); PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, - "Filename '".$v_header['stored_filename']."' is " - ."compressed by an unsupported compression " - ."method (".$v_header['compression'].") "); + "Filename '".$v_header['stored_filename']."' is " + ."compressed by an unsupported compression " + ."method (".$v_header['compression'].") "); return PclZip::errorCode(); - } - } - - // ----- Check encrypted files - if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + } + } + + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { $v_header['status'] = 'unsupported_encryption'; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { $this->privSwapBackMagicQuotes(); PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, - "Unsupported encryption for " - ." filename '".$v_header['stored_filename'] - ."'"); + "Unsupported encryption for " + ." filename '".$v_header['stored_filename'] + ."'"); return PclZip::errorCode(); - } + } } // ----- Look for real extraction if (($v_extract) && ($v_header['status'] != 'ok')) { $v_result = $this->privConvertHeader2FileInfo($v_header, - $p_file_list[$v_nb_extracted++]); + $p_file_list[$v_nb_extracted++]); if ($v_result != 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); @@ -3537,12 +3537,12 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all // ----- Look for user callback abort if ($v_result1 == 2) { - break; + break; } } // ----- Look for extraction in standard output elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) - && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { // ----- Extracting the file in standard output $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); if ($v_result1 < 1) { @@ -3560,16 +3560,16 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all // ----- Look for user callback abort if ($v_result1 == 2) { - break; + break; } } // ----- Look for normal extraction else { // ----- Extracting the file $v_result1 = $this->privExtractFile($v_header, - $p_path, $p_remove_path, - $p_remove_all_path, - $p_options); + $p_path, $p_remove_path, + $p_remove_all_path, + $p_options); if ($v_result1 < 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); @@ -3588,7 +3588,7 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all // ----- Look for user callback abort if ($v_result1 == 2) { - break; + break; } } } @@ -3679,8 +3679,8 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, if ($v_inclusion == 0) { PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, - "Filename '".$p_entry['filename']."' is " - ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + "Filename '".$p_entry['filename']."' is " + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); return PclZip::errorCode(); } @@ -3708,7 +3708,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, if ($v_result == 2) { // ----- This status is internal and will be changed in 'skipped' $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; + $v_result = PCLZIP_ERR_USER_ABORTED; } // ----- Update the informations @@ -3735,14 +3735,14 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, - "Filename '".$p_entry['filename']."' is " - ."already used by an existing directory"); + "Filename '".$p_entry['filename']."' is " + ."already used by an existing directory"); return PclZip::errorCode(); - } + } } // ----- Look if file is write protected else if (!is_writeable($p_entry['filename'])) @@ -3755,14 +3755,14 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Filename '".$p_entry['filename']."' exists " - ."and is write protected"); + "Filename '".$p_entry['filename']."' exists " + ."and is write protected"); return PclZip::errorCode(); - } + } } // ----- Look if the extracted file is older @@ -3770,24 +3770,24 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, { // ----- Change the file status if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) - && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { - } - else { + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + } + else { $p_entry['status'] = "newer_exist"; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Newer version of '".$p_entry['filename']."' exists " - ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + "Newer version of '".$p_entry['filename']."' exists " + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); return PclZip::errorCode(); - } - } + } + } } else { } @@ -3823,7 +3823,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, // ----- Look for not compressed file if ($p_entry['compression'] == 0) { - // ----- Opening destination file + // ----- Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { @@ -3928,11 +3928,11 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, } } - // ----- Change abort status - if ($p_entry['status'] == "aborted") { + // ----- Change abort status + if ($p_entry['status'] == "aborted") { $p_entry['status'] = "skipped"; - } - + } + // ----- Look for post-extract callback elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { @@ -3948,7 +3948,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, // ----- Look for abort result if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; + $v_result = PCLZIP_ERR_USER_ABORTED; } } @@ -4076,7 +4076,7 @@ function privExtractFileInOutput(&$p_entry, &$p_options) if ($v_result == 2) { // ----- This status is internal and will be changed in 'skipped' $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; + $v_result = PCLZIP_ERR_USER_ABORTED; } // ----- Update the informations @@ -4117,10 +4117,10 @@ function privExtractFileInOutput(&$p_entry, &$p_options) } } - // ----- Change abort status - if ($p_entry['status'] == "aborted") { + // ----- Change abort status + if ($p_entry['status'] == "aborted") { $p_entry['status'] = "skipped"; - } + } // ----- Look for post-extract callback elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { @@ -4137,7 +4137,7 @@ function privExtractFileInOutput(&$p_entry, &$p_options) // ----- Look for abort result if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; + $v_result = PCLZIP_ERR_USER_ABORTED; } } @@ -4191,7 +4191,7 @@ function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) if ($v_result == 2) { // ----- This status is internal and will be changed in 'skipped' $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; + $v_result = PCLZIP_ERR_USER_ABORTED; } // ----- Update the informations @@ -4231,11 +4231,11 @@ function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) } - // ----- Change abort status - if ($p_entry['status'] == "aborted") { + // ----- Change abort status + if ($p_entry['status'] == "aborted") { $p_entry['status'] = "skipped"; - } - + } + // ----- Look for post-extract callback elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { @@ -4259,7 +4259,7 @@ function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) // ----- Look for abort result if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; + $v_result = PCLZIP_ERR_USER_ABORTED; } } @@ -4489,27 +4489,27 @@ function privCheckFileHeaders(&$p_local_header, &$p_central_header) { $v_result=1; - // ----- Check the static values - // TBC - if ($p_local_header['filename'] != $p_central_header['filename']) { - } - if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { - } - if ($p_local_header['flag'] != $p_central_header['flag']) { - } - if ($p_local_header['compression'] != $p_central_header['compression']) { - } - if ($p_local_header['mtime'] != $p_central_header['mtime']) { - } - if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { - } + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + } - // ----- Look for flag bit 3 - if (($p_local_header['flag'] & 8) == 8) { + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { $p_local_header['size'] = $p_central_header['size']; $p_local_header['compressed_size'] = $p_central_header['compressed_size']; $p_local_header['crc'] = $p_central_header['crc']; - } + } // ----- Return return $v_result; @@ -4635,19 +4635,19 @@ function privReadEndCentralDir(&$p_central_dir) // ----- Check the global size if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { - // ----- Removed in release 2.2 see readme file - // The check of the file size is a little too strict. - // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. - // While decrypted, zip has training 0 bytes - if (0) { + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, - 'The central dir is not at the end of the archive.' - .' Some trailing bytes exists after the archive.'); + 'The central dir is not at the end of the archive.' + .' Some trailing bytes exists after the archive.'); // ----- Return return PclZip::errorCode(); - } + } } // ----- Get comment @@ -4809,7 +4809,7 @@ function privDeleteByRule(&$p_result_list, &$p_options) } } else { - $v_found = true; + $v_found = true; } // ----- Look for deletion @@ -4872,7 +4872,7 @@ function privDeleteByRule(&$p_result_list, &$p_options) // ----- Check that local file header is same as central file header if ($this->privCheckFileHeaders($v_local_header, - $v_header_list[$i]) != 1) { + $v_header_list[$i]) != 1) { // TBC } unset($v_local_header); @@ -5330,22 +5330,22 @@ function privDisableMagicQuotes() // ----- Look if function exists if ( (!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { + || (!function_exists("set_magic_quotes_runtime"))) { return $v_result; - } + } // ----- Look if already done if ($this->magic_quotes_status != -1) { return $v_result; - } + } - // ----- Get and memorize the magic_quote value - $this->magic_quotes_status = @get_magic_quotes_runtime(); + // ----- Get and memorize the magic_quote value + $this->magic_quotes_status = @get_magic_quotes_runtime(); - // ----- Disable magic_quotes - if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime(0); - } + // ----- Disable magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime(0); + } // ----- Return return $v_result; @@ -5364,19 +5364,19 @@ function privSwapBackMagicQuotes() // ----- Look if function exists if ( (!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { + || (!function_exists("set_magic_quotes_runtime"))) { return $v_result; - } + } // ----- Look if something to do if ($this->magic_quotes_status != -1) { return $v_result; - } + } - // ----- Swap back magic_quotes - if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime($this->magic_quotes_status); - } + // ----- Swap back magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime($this->magic_quotes_status); + } // ----- Return return $v_result; @@ -5411,37 +5411,37 @@ function PclZipUtilPathReduction($p_dir) // Should be the first $i=0, but no check is done } else if ($v_list[$i] == "..") { - $v_skip++; + $v_skip++; } else if ($v_list[$i] == "") { - // ----- First '/' i.e. root slash - if ($i == 0) { + // ----- First '/' i.e. root slash + if ($i == 0) { $v_result = "/".$v_result; - if ($v_skip > 0) { - // ----- It is an invalid path, so the path is not modified - // TBC - $v_result = $p_dir; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; $v_skip = 0; - } - } - // ----- Last '/' i.e. indicates a directory - else if ($i == (sizeof($v_list)-1)) { + } + } + // ----- Last '/' i.e. indicates a directory + else if ($i == (sizeof($v_list)-1)) { $v_result = $v_list[$i]; - } - // ----- Double '/' inside the path - else { + } + // ----- Double '/' inside the path + else { // ----- Ignore only the double '//' in path, // but not the first and last '/' - } + } } else { - // ----- Look for item to skip - if ($v_skip > 0) { - $v_skip--; - } - else { + // ----- Look for item to skip + if ($v_skip > 0) { + $v_skip--; + } + else { $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); - } + } } } @@ -5648,13 +5648,13 @@ function PclZipUtilOptionText($p_option) $v_list = get_defined_constants(); for (reset($v_list); $v_key = key($v_list); next($v_list)) { - $v_prefix = substr($v_key, 0, 10); - if (( ($v_prefix == 'PCLZIP_OPT') + $v_prefix = substr($v_key, 0, 10); + if (( ($v_prefix == 'PCLZIP_OPT') || ($v_prefix == 'PCLZIP_CB_') || ($v_prefix == 'PCLZIP_ATT')) - && ($v_list[$v_key] == $p_option)) { + && ($v_list[$v_key] == $p_option)) { return $v_key; - } + } } $v_result = 'Unknown'; diff --git a/Classes/PHPExcel/Shared/PasswordHasher.php b/Classes/PHPExcel/Shared/PasswordHasher.php index db0707f2b..92c8b3f91 100644 --- a/Classes/PHPExcel/Shared/PasswordHasher.php +++ b/Classes/PHPExcel/Shared/PasswordHasher.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,32 +35,32 @@ */ class PHPExcel_Shared_PasswordHasher { - /** - * Create a password hash from a given string. - * - * This method is based on the algorithm provided by - * Daniel Rentz of OpenOffice and the PEAR package - * Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>. - * - * @param string $pPassword Password to hash - * @return string Hashed password - */ - public static function hashPassword($pPassword = '') { - $password = 0x0000; - $charPos = 1; // char position + /** + * Create a password hash from a given string. + * + * This method is based on the algorithm provided by + * Daniel Rentz of OpenOffice and the PEAR package + * Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>. + * + * @param string $pPassword Password to hash + * @return string Hashed password + */ + public static function hashPassword($pPassword = '') { + $password = 0x0000; + $charPos = 1; // char position // split the plain text password in its component characters $chars = preg_split('//', $pPassword, -1, PREG_SPLIT_NO_EMPTY); foreach ($chars as $char) { - $value = ord($char) << $charPos++; // shifted ASCII value - $rotated_bits = $value >> 15; // rotated bits beyond bit 15 - $value &= 0x7fff; // first 15 bits - $password ^= ($value | $rotated_bits); + $value = ord($char) << $charPos++; // shifted ASCII value + $rotated_bits = $value >> 15; // rotated bits beyond bit 15 + $value &= 0x7fff; // first 15 bits + $password ^= ($value | $rotated_bits); } $password ^= strlen($pPassword); $password ^= 0xCE4B; return(strtoupper(dechex($password))); - } + } } diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 7c6978846..3d584c4c8 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,596 +35,596 @@ */ class PHPExcel_Shared_String { - /** Constants */ - /** Regular Expressions */ - // Fraction - const STRING_REGEXP_FRACTION = '(-?)(\d+)\s+(\d+\/\d+)'; - - - /** - * Control characters array - * - * @var string[] - */ - private static $_controlCharacters = array(); - - /** - * SYLK Characters array - * - * $var array - */ - private static $_SYLKCharacters = array(); - - /** - * Decimal separator - * - * @var string - */ - private static $_decimalSeparator; - - /** - * Thousands separator - * - * @var string - */ - private static $_thousandsSeparator; - - /** - * Currency code - * - * @var string - */ - private static $_currencyCode; - - /** - * Is mbstring extension avalable? - * - * @var boolean - */ - private static $_isMbstringEnabled; - - /** - * Is iconv extension avalable? - * - * @var boolean - */ - private static $_isIconvEnabled; - - /** - * Build control characters array - */ - private static function _buildControlCharacters() { - for ($i = 0; $i <= 31; ++$i) { - if ($i != 9 && $i != 10 && $i != 13) { - $find = '_x' . sprintf('%04s' , strtoupper(dechex($i))) . '_'; - $replace = chr($i); - self::$_controlCharacters[$find] = $replace; - } - } - } - - /** - * Build SYLK characters array - */ - private static function _buildSYLKCharacters() - { - self::$_SYLKCharacters = array( - "\x1B 0" => chr(0), - "\x1B 1" => chr(1), - "\x1B 2" => chr(2), - "\x1B 3" => chr(3), - "\x1B 4" => chr(4), - "\x1B 5" => chr(5), - "\x1B 6" => chr(6), - "\x1B 7" => chr(7), - "\x1B 8" => chr(8), - "\x1B 9" => chr(9), - "\x1B :" => chr(10), - "\x1B ;" => chr(11), - "\x1B <" => chr(12), - "\x1B :" => chr(13), - "\x1B >" => chr(14), - "\x1B ?" => chr(15), - "\x1B!0" => chr(16), - "\x1B!1" => chr(17), - "\x1B!2" => chr(18), - "\x1B!3" => chr(19), - "\x1B!4" => chr(20), - "\x1B!5" => chr(21), - "\x1B!6" => chr(22), - "\x1B!7" => chr(23), - "\x1B!8" => chr(24), - "\x1B!9" => chr(25), - "\x1B!:" => chr(26), - "\x1B!;" => chr(27), - "\x1B!<" => chr(28), - "\x1B!=" => chr(29), - "\x1B!>" => chr(30), - "\x1B!?" => chr(31), - "\x1B'?" => chr(127), - "\x1B(0" => '€', // 128 in CP1252 - "\x1B(2" => '‚', // 130 in CP1252 - "\x1B(3" => 'ƒ', // 131 in CP1252 - "\x1B(4" => '„', // 132 in CP1252 - "\x1B(5" => '…', // 133 in CP1252 - "\x1B(6" => '†', // 134 in CP1252 - "\x1B(7" => '‡', // 135 in CP1252 - "\x1B(8" => 'ˆ', // 136 in CP1252 - "\x1B(9" => '‰', // 137 in CP1252 - "\x1B(:" => 'Š', // 138 in CP1252 - "\x1B(;" => '‹', // 139 in CP1252 - "\x1BNj" => 'Œ', // 140 in CP1252 - "\x1B(>" => 'Ž', // 142 in CP1252 - "\x1B)1" => '‘', // 145 in CP1252 - "\x1B)2" => '’', // 146 in CP1252 - "\x1B)3" => '“', // 147 in CP1252 - "\x1B)4" => '”', // 148 in CP1252 - "\x1B)5" => '•', // 149 in CP1252 - "\x1B)6" => '–', // 150 in CP1252 - "\x1B)7" => '—', // 151 in CP1252 - "\x1B)8" => '˜', // 152 in CP1252 - "\x1B)9" => '™', // 153 in CP1252 - "\x1B):" => 'š', // 154 in CP1252 - "\x1B);" => '›', // 155 in CP1252 - "\x1BNz" => 'œ', // 156 in CP1252 - "\x1B)>" => 'ž', // 158 in CP1252 - "\x1B)?" => 'Ÿ', // 159 in CP1252 - "\x1B*0" => ' ', // 160 in CP1252 - "\x1BN!" => '¡', // 161 in CP1252 - "\x1BN\"" => '¢', // 162 in CP1252 - "\x1BN#" => '£', // 163 in CP1252 - "\x1BN(" => '¤', // 164 in CP1252 - "\x1BN%" => '¥', // 165 in CP1252 - "\x1B*6" => '¦', // 166 in CP1252 - "\x1BN'" => '§', // 167 in CP1252 - "\x1BNH " => '¨', // 168 in CP1252 - "\x1BNS" => '©', // 169 in CP1252 - "\x1BNc" => 'ª', // 170 in CP1252 - "\x1BN+" => '«', // 171 in CP1252 - "\x1B*<" => '¬', // 172 in CP1252 - "\x1B*=" => '­', // 173 in CP1252 - "\x1BNR" => '®', // 174 in CP1252 - "\x1B*?" => '¯', // 175 in CP1252 - "\x1BN0" => '°', // 176 in CP1252 - "\x1BN1" => '±', // 177 in CP1252 - "\x1BN2" => '²', // 178 in CP1252 - "\x1BN3" => '³', // 179 in CP1252 - "\x1BNB " => '´', // 180 in CP1252 - "\x1BN5" => 'µ', // 181 in CP1252 - "\x1BN6" => '¶', // 182 in CP1252 - "\x1BN7" => '·', // 183 in CP1252 - "\x1B+8" => '¸', // 184 in CP1252 - "\x1BNQ" => '¹', // 185 in CP1252 - "\x1BNk" => 'º', // 186 in CP1252 - "\x1BN;" => '»', // 187 in CP1252 - "\x1BN<" => '¼', // 188 in CP1252 - "\x1BN=" => '½', // 189 in CP1252 - "\x1BN>" => '¾', // 190 in CP1252 - "\x1BN?" => '¿', // 191 in CP1252 - "\x1BNAA" => 'À', // 192 in CP1252 - "\x1BNBA" => 'Á', // 193 in CP1252 - "\x1BNCA" => 'Â', // 194 in CP1252 - "\x1BNDA" => 'Ã', // 195 in CP1252 - "\x1BNHA" => 'Ä', // 196 in CP1252 - "\x1BNJA" => 'Å', // 197 in CP1252 - "\x1BNa" => 'Æ', // 198 in CP1252 - "\x1BNKC" => 'Ç', // 199 in CP1252 - "\x1BNAE" => 'È', // 200 in CP1252 - "\x1BNBE" => 'É', // 201 in CP1252 - "\x1BNCE" => 'Ê', // 202 in CP1252 - "\x1BNHE" => 'Ë', // 203 in CP1252 - "\x1BNAI" => 'Ì', // 204 in CP1252 - "\x1BNBI" => 'Í', // 205 in CP1252 - "\x1BNCI" => 'Î', // 206 in CP1252 - "\x1BNHI" => 'Ï', // 207 in CP1252 - "\x1BNb" => 'Ð', // 208 in CP1252 - "\x1BNDN" => 'Ñ', // 209 in CP1252 - "\x1BNAO" => 'Ò', // 210 in CP1252 - "\x1BNBO" => 'Ó', // 211 in CP1252 - "\x1BNCO" => 'Ô', // 212 in CP1252 - "\x1BNDO" => 'Õ', // 213 in CP1252 - "\x1BNHO" => 'Ö', // 214 in CP1252 - "\x1B-7" => '×', // 215 in CP1252 - "\x1BNi" => 'Ø', // 216 in CP1252 - "\x1BNAU" => 'Ù', // 217 in CP1252 - "\x1BNBU" => 'Ú', // 218 in CP1252 - "\x1BNCU" => 'Û', // 219 in CP1252 - "\x1BNHU" => 'Ü', // 220 in CP1252 - "\x1B-=" => 'Ý', // 221 in CP1252 - "\x1BNl" => 'Þ', // 222 in CP1252 - "\x1BN{" => 'ß', // 223 in CP1252 - "\x1BNAa" => 'à', // 224 in CP1252 - "\x1BNBa" => 'á', // 225 in CP1252 - "\x1BNCa" => 'â', // 226 in CP1252 - "\x1BNDa" => 'ã', // 227 in CP1252 - "\x1BNHa" => 'ä', // 228 in CP1252 - "\x1BNJa" => 'å', // 229 in CP1252 - "\x1BNq" => 'æ', // 230 in CP1252 - "\x1BNKc" => 'ç', // 231 in CP1252 - "\x1BNAe" => 'è', // 232 in CP1252 - "\x1BNBe" => 'é', // 233 in CP1252 - "\x1BNCe" => 'ê', // 234 in CP1252 - "\x1BNHe" => 'ë', // 235 in CP1252 - "\x1BNAi" => 'ì', // 236 in CP1252 - "\x1BNBi" => 'í', // 237 in CP1252 - "\x1BNCi" => 'î', // 238 in CP1252 - "\x1BNHi" => 'ï', // 239 in CP1252 - "\x1BNs" => 'ð', // 240 in CP1252 - "\x1BNDn" => 'ñ', // 241 in CP1252 - "\x1BNAo" => 'ò', // 242 in CP1252 - "\x1BNBo" => 'ó', // 243 in CP1252 - "\x1BNCo" => 'ô', // 244 in CP1252 - "\x1BNDo" => 'õ', // 245 in CP1252 - "\x1BNHo" => 'ö', // 246 in CP1252 - "\x1B/7" => '÷', // 247 in CP1252 - "\x1BNy" => 'ø', // 248 in CP1252 - "\x1BNAu" => 'ù', // 249 in CP1252 - "\x1BNBu" => 'ú', // 250 in CP1252 - "\x1BNCu" => 'û', // 251 in CP1252 - "\x1BNHu" => 'ü', // 252 in CP1252 - "\x1B/=" => 'ý', // 253 in CP1252 - "\x1BN|" => 'þ', // 254 in CP1252 - "\x1BNHy" => 'ÿ', // 255 in CP1252 - ); - } - - /** - * Get whether mbstring extension is available - * - * @return boolean - */ - public static function getIsMbstringEnabled() - { - if (isset(self::$_isMbstringEnabled)) { - return self::$_isMbstringEnabled; - } - - self::$_isMbstringEnabled = function_exists('mb_convert_encoding') ? - true : false; - - return self::$_isMbstringEnabled; - } - - /** - * Get whether iconv extension is available - * - * @return boolean - */ - public static function getIsIconvEnabled() - { - if (isset(self::$_isIconvEnabled)) { - return self::$_isIconvEnabled; - } - - // Fail if iconv doesn't exist - if (!function_exists('iconv')) { - self::$_isIconvEnabled = false; - return false; - } - - // Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false, - if (!@iconv('UTF-8', 'UTF-16LE', 'x')) { - self::$_isIconvEnabled = false; - return false; - } - - // Sometimes iconv_substr('A', 0, 1, 'UTF-8') just returns false in PHP 5.2.0 - // we cannot use iconv in that case either (http://bugs.php.net/bug.php?id=37773) - if (!@iconv_substr('A', 0, 1, 'UTF-8')) { - self::$_isIconvEnabled = false; - return false; - } - - // CUSTOM: IBM AIX iconv() does not work - if ( defined('PHP_OS') && @stristr(PHP_OS, 'AIX') - && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) - && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0) ) - { - self::$_isIconvEnabled = false; - return false; - } - - // If we reach here no problems were detected with iconv - self::$_isIconvEnabled = true; - return true; - } - - public static function buildCharacterSets() { - if(empty(self::$_controlCharacters)) { - self::_buildControlCharacters(); - } - if(empty(self::$_SYLKCharacters)) { - self::_buildSYLKCharacters(); - } - } - - /** - * Convert from OpenXML escaped control character to PHP control character - * - * Excel 2007 team: - * ---------------- - * That's correct, control characters are stored directly in the shared-strings table. - * We do encode characters that cannot be represented in XML using the following escape sequence: - * _xHHHH_ where H represents a hexadecimal character in the character's value... - * So you could end up with something like _x0008_ in a string (either in a cell value (<v>) - * element or in the shared string <t> element. - * - * @param string $value Value to unescape - * @return string - */ - public static function ControlCharacterOOXML2PHP($value = '') { - return str_replace( array_keys(self::$_controlCharacters), array_values(self::$_controlCharacters), $value ); - } - - /** - * Convert from PHP control character to OpenXML escaped control character - * - * Excel 2007 team: - * ---------------- - * That's correct, control characters are stored directly in the shared-strings table. - * We do encode characters that cannot be represented in XML using the following escape sequence: - * _xHHHH_ where H represents a hexadecimal character in the character's value... - * So you could end up with something like _x0008_ in a string (either in a cell value (<v>) - * element or in the shared string <t> element. - * - * @param string $value Value to escape - * @return string - */ - public static function ControlCharacterPHP2OOXML($value = '') { - return str_replace( array_values(self::$_controlCharacters), array_keys(self::$_controlCharacters), $value ); - } - - /** - * Try to sanitize UTF8, stripping invalid byte sequences. Not perfect. Does not surrogate characters. - * - * @param string $value - * @return string - */ - public static function SanitizeUTF8($value) - { - if (self::getIsIconvEnabled()) { - $value = @iconv('UTF-8', 'UTF-8', $value); - return $value; - } - - if (self::getIsMbstringEnabled()) { - $value = mb_convert_encoding($value, 'UTF-8', 'UTF-8'); - return $value; - } - - // else, no conversion - return $value; - } - - /** - * Check if a string contains UTF8 data - * - * @param string $value - * @return boolean - */ - public static function IsUTF8($value = '') { - return $value === '' || preg_match('/^./su', $value) === 1; - } - - /** - * Formats a numeric value as a string for output in various output writers forcing - * point as decimal separator in case locale is other than English. - * - * @param mixed $value - * @return string - */ - public static function FormatNumber($value) { - if (is_float($value)) { - return str_replace(',', '.', $value); - } - return (string) $value; - } - - /** - * Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length) - * Writes the string using uncompressed notation, no rich text, no Asian phonetics - * If mbstring extension is not available, ASCII is assumed, and compressed notation is used - * although this will give wrong results for non-ASCII strings - * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 - * - * @param string $value UTF-8 encoded string - * @param mixed[] $arrcRuns Details of rich text runs in $value - * @return string - */ - public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = array()) - { - // character count - $ln = self::CountCharacters($value, 'UTF-8'); - // option flags - if(empty($arrcRuns)){ - $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? - 0x0001 : 0x0000; - $data = pack('CC', $ln, $opt); - // characters - $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); - } - else { - $data = pack('vC', $ln, 0x09); - $data .= pack('v', count($arrcRuns)); - // characters - $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); - foreach ($arrcRuns as $cRun){ - $data .= pack('v', $cRun['strlen']); - $data .= pack('v', $cRun['fontidx']); - } - } - return $data; - } - - /** - * Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length) - * Writes the string using uncompressed notation, no rich text, no Asian phonetics - * If mbstring extension is not available, ASCII is assumed, and compressed notation is used - * although this will give wrong results for non-ASCII strings - * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 - * - * @param string $value UTF-8 encoded string - * @return string - */ - public static function UTF8toBIFF8UnicodeLong($value) - { - // character count - $ln = self::CountCharacters($value, 'UTF-8'); - - // option flags - $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? - 0x0001 : 0x0000; - - // characters - $chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); - - $data = pack('vC', $ln, $opt) . $chars; - return $data; - } - - /** - * Convert string from one encoding to another. First try mbstring, then iconv, finally strlen - * - * @param string $value - * @param string $to Encoding to convert to, e.g. 'UTF-8' - * @param string $from Encoding to convert from, e.g. 'UTF-16LE' - * @return string - */ - public static function ConvertEncoding($value, $to, $from) - { - if (self::getIsIconvEnabled()) { - return iconv($from, $to, $value); - } - - if (self::getIsMbstringEnabled()) { - return mb_convert_encoding($value, $to, $from); - } - - if($from == 'UTF-16LE'){ - return self::utf16_decode($value, false); - }else if($from == 'UTF-16BE'){ - return self::utf16_decode($value); - } - // else, no conversion - return $value; - } - - /** - * Decode UTF-16 encoded strings. - * - * Can handle both BOM'ed data and un-BOM'ed data. - * Assumes Big-Endian byte order if no BOM is available. - * This function was taken from http://php.net/manual/en/function.utf8-decode.php - * and $bom_be parameter added. - * - * @param string $str UTF-16 encoded data to decode. - * @return string UTF-8 / ISO encoded data. - * @access public - * @version 0.2 / 2010-05-13 - * @author Rasmus Andersson {@link http://rasmusandersson.se/} - * @author vadik56 - */ - public static function utf16_decode($str, $bom_be = TRUE) { - if( strlen($str) < 2 ) return $str; - $c0 = ord($str{0}); - $c1 = ord($str{1}); - if( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); } - elseif( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; } - $len = strlen($str); - $newstr = ''; - for($i=0;$i<$len;$i+=2) { - if( $bom_be ) { $val = ord($str{$i}) << 4; $val += ord($str{$i+1}); } - else { $val = ord($str{$i+1}) << 4; $val += ord($str{$i}); } - $newstr .= ($val == 0x228) ? "\n" : chr($val); - } - return $newstr; - } - - /** - * Get character count. First try mbstring, then iconv, finally strlen - * - * @param string $value - * @param string $enc Encoding - * @return int Character count - */ - public static function CountCharacters($value, $enc = 'UTF-8') - { - if (self::getIsMbstringEnabled()) { - return mb_strlen($value, $enc); - } - - if (self::getIsIconvEnabled()) { - return iconv_strlen($value, $enc); - } - - // else strlen - return strlen($value); - } - - /** - * Get a substring of a UTF-8 encoded string. First try mbstring, then iconv, finally strlen - * - * @param string $pValue UTF-8 encoded string - * @param int $pStart Start offset - * @param int $pLength Maximum number of characters in substring - * @return string - */ - public static function Substring($pValue = '', $pStart = 0, $pLength = 0) - { - if (self::getIsMbstringEnabled()) { - return mb_substr($pValue, $pStart, $pLength, 'UTF-8'); - } - - if (self::getIsIconvEnabled()) { - return iconv_substr($pValue, $pStart, $pLength, 'UTF-8'); - } - - // else substr - return substr($pValue, $pStart, $pLength); - } - - /** - * Convert a UTF-8 encoded string to upper case - * - * @param string $pValue UTF-8 encoded string - * @return string - */ - public static function StrToUpper($pValue = '') - { - if (function_exists('mb_convert_case')) { - return mb_convert_case($pValue, MB_CASE_UPPER, "UTF-8"); - } - return strtoupper($pValue); - } - - /** - * Convert a UTF-8 encoded string to lower case - * - * @param string $pValue UTF-8 encoded string - * @return string - */ - public static function StrToLower($pValue = '') - { - if (function_exists('mb_convert_case')) { - return mb_convert_case($pValue, MB_CASE_LOWER, "UTF-8"); - } - return strtolower($pValue); - } - - /** - * Convert a UTF-8 encoded string to title/proper case - * (uppercase every first character in each word, lower case all other characters) - * - * @param string $pValue UTF-8 encoded string - * @return string - */ - public static function StrToTitle($pValue = '') - { - if (function_exists('mb_convert_case')) { - return mb_convert_case($pValue, MB_CASE_TITLE, "UTF-8"); - } - return ucwords($pValue); - } + /** Constants */ + /** Regular Expressions */ + // Fraction + const STRING_REGEXP_FRACTION = '(-?)(\d+)\s+(\d+\/\d+)'; + + + /** + * Control characters array + * + * @var string[] + */ + private static $_controlCharacters = array(); + + /** + * SYLK Characters array + * + * $var array + */ + private static $_SYLKCharacters = array(); + + /** + * Decimal separator + * + * @var string + */ + private static $_decimalSeparator; + + /** + * Thousands separator + * + * @var string + */ + private static $_thousandsSeparator; + + /** + * Currency code + * + * @var string + */ + private static $_currencyCode; + + /** + * Is mbstring extension avalable? + * + * @var boolean + */ + private static $_isMbstringEnabled; + + /** + * Is iconv extension avalable? + * + * @var boolean + */ + private static $_isIconvEnabled; + + /** + * Build control characters array + */ + private static function _buildControlCharacters() { + for ($i = 0; $i <= 31; ++$i) { + if ($i != 9 && $i != 10 && $i != 13) { + $find = '_x' . sprintf('%04s' , strtoupper(dechex($i))) . '_'; + $replace = chr($i); + self::$_controlCharacters[$find] = $replace; + } + } + } + + /** + * Build SYLK characters array + */ + private static function _buildSYLKCharacters() + { + self::$_SYLKCharacters = array( + "\x1B 0" => chr(0), + "\x1B 1" => chr(1), + "\x1B 2" => chr(2), + "\x1B 3" => chr(3), + "\x1B 4" => chr(4), + "\x1B 5" => chr(5), + "\x1B 6" => chr(6), + "\x1B 7" => chr(7), + "\x1B 8" => chr(8), + "\x1B 9" => chr(9), + "\x1B :" => chr(10), + "\x1B ;" => chr(11), + "\x1B <" => chr(12), + "\x1B :" => chr(13), + "\x1B >" => chr(14), + "\x1B ?" => chr(15), + "\x1B!0" => chr(16), + "\x1B!1" => chr(17), + "\x1B!2" => chr(18), + "\x1B!3" => chr(19), + "\x1B!4" => chr(20), + "\x1B!5" => chr(21), + "\x1B!6" => chr(22), + "\x1B!7" => chr(23), + "\x1B!8" => chr(24), + "\x1B!9" => chr(25), + "\x1B!:" => chr(26), + "\x1B!;" => chr(27), + "\x1B!<" => chr(28), + "\x1B!=" => chr(29), + "\x1B!>" => chr(30), + "\x1B!?" => chr(31), + "\x1B'?" => chr(127), + "\x1B(0" => '€', // 128 in CP1252 + "\x1B(2" => '‚', // 130 in CP1252 + "\x1B(3" => 'ƒ', // 131 in CP1252 + "\x1B(4" => '„', // 132 in CP1252 + "\x1B(5" => '…', // 133 in CP1252 + "\x1B(6" => '†', // 134 in CP1252 + "\x1B(7" => '‡', // 135 in CP1252 + "\x1B(8" => 'ˆ', // 136 in CP1252 + "\x1B(9" => '‰', // 137 in CP1252 + "\x1B(:" => 'Š', // 138 in CP1252 + "\x1B(;" => '‹', // 139 in CP1252 + "\x1BNj" => 'Œ', // 140 in CP1252 + "\x1B(>" => 'Ž', // 142 in CP1252 + "\x1B)1" => '‘', // 145 in CP1252 + "\x1B)2" => '’', // 146 in CP1252 + "\x1B)3" => '“', // 147 in CP1252 + "\x1B)4" => '”', // 148 in CP1252 + "\x1B)5" => '•', // 149 in CP1252 + "\x1B)6" => '–', // 150 in CP1252 + "\x1B)7" => '—', // 151 in CP1252 + "\x1B)8" => '˜', // 152 in CP1252 + "\x1B)9" => '™', // 153 in CP1252 + "\x1B):" => 'š', // 154 in CP1252 + "\x1B);" => '›', // 155 in CP1252 + "\x1BNz" => 'œ', // 156 in CP1252 + "\x1B)>" => 'ž', // 158 in CP1252 + "\x1B)?" => 'Ÿ', // 159 in CP1252 + "\x1B*0" => ' ', // 160 in CP1252 + "\x1BN!" => '¡', // 161 in CP1252 + "\x1BN\"" => '¢', // 162 in CP1252 + "\x1BN#" => '£', // 163 in CP1252 + "\x1BN(" => '¤', // 164 in CP1252 + "\x1BN%" => '¥', // 165 in CP1252 + "\x1B*6" => '¦', // 166 in CP1252 + "\x1BN'" => '§', // 167 in CP1252 + "\x1BNH " => '¨', // 168 in CP1252 + "\x1BNS" => '©', // 169 in CP1252 + "\x1BNc" => 'ª', // 170 in CP1252 + "\x1BN+" => '«', // 171 in CP1252 + "\x1B*<" => '¬', // 172 in CP1252 + "\x1B*=" => '­', // 173 in CP1252 + "\x1BNR" => '®', // 174 in CP1252 + "\x1B*?" => '¯', // 175 in CP1252 + "\x1BN0" => '°', // 176 in CP1252 + "\x1BN1" => '±', // 177 in CP1252 + "\x1BN2" => '²', // 178 in CP1252 + "\x1BN3" => '³', // 179 in CP1252 + "\x1BNB " => '´', // 180 in CP1252 + "\x1BN5" => 'µ', // 181 in CP1252 + "\x1BN6" => '¶', // 182 in CP1252 + "\x1BN7" => '·', // 183 in CP1252 + "\x1B+8" => '¸', // 184 in CP1252 + "\x1BNQ" => '¹', // 185 in CP1252 + "\x1BNk" => 'º', // 186 in CP1252 + "\x1BN;" => '»', // 187 in CP1252 + "\x1BN<" => '¼', // 188 in CP1252 + "\x1BN=" => '½', // 189 in CP1252 + "\x1BN>" => '¾', // 190 in CP1252 + "\x1BN?" => '¿', // 191 in CP1252 + "\x1BNAA" => 'À', // 192 in CP1252 + "\x1BNBA" => 'Á', // 193 in CP1252 + "\x1BNCA" => 'Â', // 194 in CP1252 + "\x1BNDA" => 'Ã', // 195 in CP1252 + "\x1BNHA" => 'Ä', // 196 in CP1252 + "\x1BNJA" => 'Å', // 197 in CP1252 + "\x1BNa" => 'Æ', // 198 in CP1252 + "\x1BNKC" => 'Ç', // 199 in CP1252 + "\x1BNAE" => 'È', // 200 in CP1252 + "\x1BNBE" => 'É', // 201 in CP1252 + "\x1BNCE" => 'Ê', // 202 in CP1252 + "\x1BNHE" => 'Ë', // 203 in CP1252 + "\x1BNAI" => 'Ì', // 204 in CP1252 + "\x1BNBI" => 'Í', // 205 in CP1252 + "\x1BNCI" => 'Î', // 206 in CP1252 + "\x1BNHI" => 'Ï', // 207 in CP1252 + "\x1BNb" => 'Ð', // 208 in CP1252 + "\x1BNDN" => 'Ñ', // 209 in CP1252 + "\x1BNAO" => 'Ò', // 210 in CP1252 + "\x1BNBO" => 'Ó', // 211 in CP1252 + "\x1BNCO" => 'Ô', // 212 in CP1252 + "\x1BNDO" => 'Õ', // 213 in CP1252 + "\x1BNHO" => 'Ö', // 214 in CP1252 + "\x1B-7" => '×', // 215 in CP1252 + "\x1BNi" => 'Ø', // 216 in CP1252 + "\x1BNAU" => 'Ù', // 217 in CP1252 + "\x1BNBU" => 'Ú', // 218 in CP1252 + "\x1BNCU" => 'Û', // 219 in CP1252 + "\x1BNHU" => 'Ü', // 220 in CP1252 + "\x1B-=" => 'Ý', // 221 in CP1252 + "\x1BNl" => 'Þ', // 222 in CP1252 + "\x1BN{" => 'ß', // 223 in CP1252 + "\x1BNAa" => 'à', // 224 in CP1252 + "\x1BNBa" => 'á', // 225 in CP1252 + "\x1BNCa" => 'â', // 226 in CP1252 + "\x1BNDa" => 'ã', // 227 in CP1252 + "\x1BNHa" => 'ä', // 228 in CP1252 + "\x1BNJa" => 'å', // 229 in CP1252 + "\x1BNq" => 'æ', // 230 in CP1252 + "\x1BNKc" => 'ç', // 231 in CP1252 + "\x1BNAe" => 'è', // 232 in CP1252 + "\x1BNBe" => 'é', // 233 in CP1252 + "\x1BNCe" => 'ê', // 234 in CP1252 + "\x1BNHe" => 'ë', // 235 in CP1252 + "\x1BNAi" => 'ì', // 236 in CP1252 + "\x1BNBi" => 'í', // 237 in CP1252 + "\x1BNCi" => 'î', // 238 in CP1252 + "\x1BNHi" => 'ï', // 239 in CP1252 + "\x1BNs" => 'ð', // 240 in CP1252 + "\x1BNDn" => 'ñ', // 241 in CP1252 + "\x1BNAo" => 'ò', // 242 in CP1252 + "\x1BNBo" => 'ó', // 243 in CP1252 + "\x1BNCo" => 'ô', // 244 in CP1252 + "\x1BNDo" => 'õ', // 245 in CP1252 + "\x1BNHo" => 'ö', // 246 in CP1252 + "\x1B/7" => '÷', // 247 in CP1252 + "\x1BNy" => 'ø', // 248 in CP1252 + "\x1BNAu" => 'ù', // 249 in CP1252 + "\x1BNBu" => 'ú', // 250 in CP1252 + "\x1BNCu" => 'û', // 251 in CP1252 + "\x1BNHu" => 'ü', // 252 in CP1252 + "\x1B/=" => 'ý', // 253 in CP1252 + "\x1BN|" => 'þ', // 254 in CP1252 + "\x1BNHy" => 'ÿ', // 255 in CP1252 + ); + } + + /** + * Get whether mbstring extension is available + * + * @return boolean + */ + public static function getIsMbstringEnabled() + { + if (isset(self::$_isMbstringEnabled)) { + return self::$_isMbstringEnabled; + } + + self::$_isMbstringEnabled = function_exists('mb_convert_encoding') ? + true : false; + + return self::$_isMbstringEnabled; + } + + /** + * Get whether iconv extension is available + * + * @return boolean + */ + public static function getIsIconvEnabled() + { + if (isset(self::$_isIconvEnabled)) { + return self::$_isIconvEnabled; + } + + // Fail if iconv doesn't exist + if (!function_exists('iconv')) { + self::$_isIconvEnabled = false; + return false; + } + + // Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false, + if (!@iconv('UTF-8', 'UTF-16LE', 'x')) { + self::$_isIconvEnabled = false; + return false; + } + + // Sometimes iconv_substr('A', 0, 1, 'UTF-8') just returns false in PHP 5.2.0 + // we cannot use iconv in that case either (http://bugs.php.net/bug.php?id=37773) + if (!@iconv_substr('A', 0, 1, 'UTF-8')) { + self::$_isIconvEnabled = false; + return false; + } + + // CUSTOM: IBM AIX iconv() does not work + if ( defined('PHP_OS') && @stristr(PHP_OS, 'AIX') + && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) + && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0) ) + { + self::$_isIconvEnabled = false; + return false; + } + + // If we reach here no problems were detected with iconv + self::$_isIconvEnabled = true; + return true; + } + + public static function buildCharacterSets() { + if(empty(self::$_controlCharacters)) { + self::_buildControlCharacters(); + } + if(empty(self::$_SYLKCharacters)) { + self::_buildSYLKCharacters(); + } + } + + /** + * Convert from OpenXML escaped control character to PHP control character + * + * Excel 2007 team: + * ---------------- + * That's correct, control characters are stored directly in the shared-strings table. + * We do encode characters that cannot be represented in XML using the following escape sequence: + * _xHHHH_ where H represents a hexadecimal character in the character's value... + * So you could end up with something like _x0008_ in a string (either in a cell value (<v>) + * element or in the shared string <t> element. + * + * @param string $value Value to unescape + * @return string + */ + public static function ControlCharacterOOXML2PHP($value = '') { + return str_replace( array_keys(self::$_controlCharacters), array_values(self::$_controlCharacters), $value ); + } + + /** + * Convert from PHP control character to OpenXML escaped control character + * + * Excel 2007 team: + * ---------------- + * That's correct, control characters are stored directly in the shared-strings table. + * We do encode characters that cannot be represented in XML using the following escape sequence: + * _xHHHH_ where H represents a hexadecimal character in the character's value... + * So you could end up with something like _x0008_ in a string (either in a cell value (<v>) + * element or in the shared string <t> element. + * + * @param string $value Value to escape + * @return string + */ + public static function ControlCharacterPHP2OOXML($value = '') { + return str_replace( array_values(self::$_controlCharacters), array_keys(self::$_controlCharacters), $value ); + } + + /** + * Try to sanitize UTF8, stripping invalid byte sequences. Not perfect. Does not surrogate characters. + * + * @param string $value + * @return string + */ + public static function SanitizeUTF8($value) + { + if (self::getIsIconvEnabled()) { + $value = @iconv('UTF-8', 'UTF-8', $value); + return $value; + } + + if (self::getIsMbstringEnabled()) { + $value = mb_convert_encoding($value, 'UTF-8', 'UTF-8'); + return $value; + } + + // else, no conversion + return $value; + } + + /** + * Check if a string contains UTF8 data + * + * @param string $value + * @return boolean + */ + public static function IsUTF8($value = '') { + return $value === '' || preg_match('/^./su', $value) === 1; + } + + /** + * Formats a numeric value as a string for output in various output writers forcing + * point as decimal separator in case locale is other than English. + * + * @param mixed $value + * @return string + */ + public static function FormatNumber($value) { + if (is_float($value)) { + return str_replace(',', '.', $value); + } + return (string) $value; + } + + /** + * Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length) + * Writes the string using uncompressed notation, no rich text, no Asian phonetics + * If mbstring extension is not available, ASCII is assumed, and compressed notation is used + * although this will give wrong results for non-ASCII strings + * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 + * + * @param string $value UTF-8 encoded string + * @param mixed[] $arrcRuns Details of rich text runs in $value + * @return string + */ + public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = array()) + { + // character count + $ln = self::CountCharacters($value, 'UTF-8'); + // option flags + if(empty($arrcRuns)){ + $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? + 0x0001 : 0x0000; + $data = pack('CC', $ln, $opt); + // characters + $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + } + else { + $data = pack('vC', $ln, 0x09); + $data .= pack('v', count($arrcRuns)); + // characters + $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + foreach ($arrcRuns as $cRun){ + $data .= pack('v', $cRun['strlen']); + $data .= pack('v', $cRun['fontidx']); + } + } + return $data; + } + + /** + * Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length) + * Writes the string using uncompressed notation, no rich text, no Asian phonetics + * If mbstring extension is not available, ASCII is assumed, and compressed notation is used + * although this will give wrong results for non-ASCII strings + * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 + * + * @param string $value UTF-8 encoded string + * @return string + */ + public static function UTF8toBIFF8UnicodeLong($value) + { + // character count + $ln = self::CountCharacters($value, 'UTF-8'); + + // option flags + $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? + 0x0001 : 0x0000; + + // characters + $chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + + $data = pack('vC', $ln, $opt) . $chars; + return $data; + } + + /** + * Convert string from one encoding to another. First try mbstring, then iconv, finally strlen + * + * @param string $value + * @param string $to Encoding to convert to, e.g. 'UTF-8' + * @param string $from Encoding to convert from, e.g. 'UTF-16LE' + * @return string + */ + public static function ConvertEncoding($value, $to, $from) + { + if (self::getIsIconvEnabled()) { + return iconv($from, $to, $value); + } + + if (self::getIsMbstringEnabled()) { + return mb_convert_encoding($value, $to, $from); + } + + if($from == 'UTF-16LE'){ + return self::utf16_decode($value, false); + }else if($from == 'UTF-16BE'){ + return self::utf16_decode($value); + } + // else, no conversion + return $value; + } + + /** + * Decode UTF-16 encoded strings. + * + * Can handle both BOM'ed data and un-BOM'ed data. + * Assumes Big-Endian byte order if no BOM is available. + * This function was taken from http://php.net/manual/en/function.utf8-decode.php + * and $bom_be parameter added. + * + * @param string $str UTF-16 encoded data to decode. + * @return string UTF-8 / ISO encoded data. + * @access public + * @version 0.2 / 2010-05-13 + * @author Rasmus Andersson {@link http://rasmusandersson.se/} + * @author vadik56 + */ + public static function utf16_decode($str, $bom_be = TRUE) { + if( strlen($str) < 2 ) return $str; + $c0 = ord($str{0}); + $c1 = ord($str{1}); + if( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); } + elseif( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; } + $len = strlen($str); + $newstr = ''; + for($i=0;$i<$len;$i+=2) { + if( $bom_be ) { $val = ord($str{$i}) << 4; $val += ord($str{$i+1}); } + else { $val = ord($str{$i+1}) << 4; $val += ord($str{$i}); } + $newstr .= ($val == 0x228) ? "\n" : chr($val); + } + return $newstr; + } + + /** + * Get character count. First try mbstring, then iconv, finally strlen + * + * @param string $value + * @param string $enc Encoding + * @return int Character count + */ + public static function CountCharacters($value, $enc = 'UTF-8') + { + if (self::getIsMbstringEnabled()) { + return mb_strlen($value, $enc); + } + + if (self::getIsIconvEnabled()) { + return iconv_strlen($value, $enc); + } + + // else strlen + return strlen($value); + } + + /** + * Get a substring of a UTF-8 encoded string. First try mbstring, then iconv, finally strlen + * + * @param string $pValue UTF-8 encoded string + * @param int $pStart Start offset + * @param int $pLength Maximum number of characters in substring + * @return string + */ + public static function Substring($pValue = '', $pStart = 0, $pLength = 0) + { + if (self::getIsMbstringEnabled()) { + return mb_substr($pValue, $pStart, $pLength, 'UTF-8'); + } + + if (self::getIsIconvEnabled()) { + return iconv_substr($pValue, $pStart, $pLength, 'UTF-8'); + } + + // else substr + return substr($pValue, $pStart, $pLength); + } + + /** + * Convert a UTF-8 encoded string to upper case + * + * @param string $pValue UTF-8 encoded string + * @return string + */ + public static function StrToUpper($pValue = '') + { + if (function_exists('mb_convert_case')) { + return mb_convert_case($pValue, MB_CASE_UPPER, "UTF-8"); + } + return strtoupper($pValue); + } + + /** + * Convert a UTF-8 encoded string to lower case + * + * @param string $pValue UTF-8 encoded string + * @return string + */ + public static function StrToLower($pValue = '') + { + if (function_exists('mb_convert_case')) { + return mb_convert_case($pValue, MB_CASE_LOWER, "UTF-8"); + } + return strtolower($pValue); + } + + /** + * Convert a UTF-8 encoded string to title/proper case + * (uppercase every first character in each word, lower case all other characters) + * + * @param string $pValue UTF-8 encoded string + * @return string + */ + public static function StrToTitle($pValue = '') + { + if (function_exists('mb_convert_case')) { + return mb_convert_case($pValue, MB_CASE_TITLE, "UTF-8"); + } + return ucwords($pValue); + } public static function mb_is_upper($char) { @@ -638,15 +638,15 @@ public static function mb_str_split($string) return preg_split('/(?<!^)(?!$)/u', $string ); } - /** - * Reverse the case of a string, so that all uppercase characters become lowercase + /** + * Reverse the case of a string, so that all uppercase characters become lowercase * and all lowercase characters become uppercase - * - * @param string $pValue UTF-8 encoded string - * @return string - */ - public static function StrCaseReverse($pValue = '') - { + * + * @param string $pValue UTF-8 encoded string + * @return string + */ + public static function StrCaseReverse($pValue = '') + { if (self::getIsMbstringEnabled()) { $characters = self::mb_str_split($pValue); foreach($characters as &$character) { @@ -657,155 +657,155 @@ public static function StrCaseReverse($pValue = '') } } return implode('', $characters); - } - return strtolower($pValue) ^ strtoupper($pValue) ^ $pValue; - } - - /** - * Identify whether a string contains a fractional numeric value, - * and convert it to a numeric if it is - * - * @param string &$operand string value to test - * @return boolean - */ - public static function convertToNumberIfFraction(&$operand) { - if (preg_match('/^'.self::STRING_REGEXP_FRACTION.'$/i', $operand, $match)) { - $sign = ($match[1] == '-') ? '-' : '+'; - $fractionFormula = '='.$sign.$match[2].$sign.$match[3]; - $operand = PHPExcel_Calculation::getInstance()->_calculateFormulaValue($fractionFormula); - return true; - } - return false; - } // function convertToNumberIfFraction() - - /** - * Get the decimal separator. If it has not yet been set explicitly, try to obtain number - * formatting information from locale. - * - * @return string - */ - public static function getDecimalSeparator() - { - if (!isset(self::$_decimalSeparator)) { - $localeconv = localeconv(); - self::$_decimalSeparator = ($localeconv['decimal_point'] != '') - ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point']; - - if (self::$_decimalSeparator == '') { - // Default to . - self::$_decimalSeparator = '.'; - } - } - return self::$_decimalSeparator; - } - - /** - * Set the decimal separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString() - * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF - * - * @param string $pValue Character for decimal separator - */ - public static function setDecimalSeparator($pValue = '.') - { - self::$_decimalSeparator = $pValue; - } - - /** - * Get the thousands separator. If it has not yet been set explicitly, try to obtain number - * formatting information from locale. - * - * @return string - */ - public static function getThousandsSeparator() - { - if (!isset(self::$_thousandsSeparator)) { - $localeconv = localeconv(); - self::$_thousandsSeparator = ($localeconv['thousands_sep'] != '') - ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep']; - - if (self::$_thousandsSeparator == '') { - // Default to . - self::$_thousandsSeparator = ','; - } - } - return self::$_thousandsSeparator; - } - - /** - * Set the thousands separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString() - * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF - * - * @param string $pValue Character for thousands separator - */ - public static function setThousandsSeparator($pValue = ',') - { - self::$_thousandsSeparator = $pValue; - } - - /** - * Get the currency code. If it has not yet been set explicitly, try to obtain the - * symbol information from locale. - * - * @return string - */ - public static function getCurrencyCode() - { - if (!isset(self::$_currencyCode)) { - $localeconv = localeconv(); - self::$_currencyCode = ($localeconv['currency_symbol'] != '') - ? $localeconv['currency_symbol'] : $localeconv['int_curr_symbol']; - - if (self::$_currencyCode == '') { - // Default to $ - self::$_currencyCode = '$'; - } - } - return self::$_currencyCode; - } - - /** - * Set the currency code. Only used by PHPExcel_Style_NumberFormat::toFormattedString() - * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF - * - * @param string $pValue Character for currency code - */ - public static function setCurrencyCode($pValue = '$') - { - self::$_currencyCode = $pValue; - } - - /** - * Convert SYLK encoded string to UTF-8 - * - * @param string $pValue - * @return string UTF-8 encoded string - */ - public static function SYLKtoUTF8($pValue = '') - { - // If there is no escape character in the string there is nothing to do - if (strpos($pValue, '') === false) { - return $pValue; - } - - foreach (self::$_SYLKCharacters as $k => $v) { - $pValue = str_replace($k, $v, $pValue); - } - - return $pValue; - } - - /** - * Retrieve any leading numeric part of a string, or return the full string if no leading numeric - * (handles basic integer or float, but not exponent or non decimal) - * - * @param string $value - * @return mixed string or only the leading numeric part of the string - */ - public static function testStringAsNumeric($value) - { - if (is_numeric($value)) - return $value; - $v = floatval($value); - return (is_numeric(substr($value, 0, strlen($v)))) ? $v : $value; - } + } + return strtolower($pValue) ^ strtoupper($pValue) ^ $pValue; + } + + /** + * Identify whether a string contains a fractional numeric value, + * and convert it to a numeric if it is + * + * @param string &$operand string value to test + * @return boolean + */ + public static function convertToNumberIfFraction(&$operand) { + if (preg_match('/^'.self::STRING_REGEXP_FRACTION.'$/i', $operand, $match)) { + $sign = ($match[1] == '-') ? '-' : '+'; + $fractionFormula = '='.$sign.$match[2].$sign.$match[3]; + $operand = PHPExcel_Calculation::getInstance()->_calculateFormulaValue($fractionFormula); + return true; + } + return false; + } // function convertToNumberIfFraction() + + /** + * Get the decimal separator. If it has not yet been set explicitly, try to obtain number + * formatting information from locale. + * + * @return string + */ + public static function getDecimalSeparator() + { + if (!isset(self::$_decimalSeparator)) { + $localeconv = localeconv(); + self::$_decimalSeparator = ($localeconv['decimal_point'] != '') + ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point']; + + if (self::$_decimalSeparator == '') { + // Default to . + self::$_decimalSeparator = '.'; + } + } + return self::$_decimalSeparator; + } + + /** + * Set the decimal separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString() + * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF + * + * @param string $pValue Character for decimal separator + */ + public static function setDecimalSeparator($pValue = '.') + { + self::$_decimalSeparator = $pValue; + } + + /** + * Get the thousands separator. If it has not yet been set explicitly, try to obtain number + * formatting information from locale. + * + * @return string + */ + public static function getThousandsSeparator() + { + if (!isset(self::$_thousandsSeparator)) { + $localeconv = localeconv(); + self::$_thousandsSeparator = ($localeconv['thousands_sep'] != '') + ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep']; + + if (self::$_thousandsSeparator == '') { + // Default to . + self::$_thousandsSeparator = ','; + } + } + return self::$_thousandsSeparator; + } + + /** + * Set the thousands separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString() + * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF + * + * @param string $pValue Character for thousands separator + */ + public static function setThousandsSeparator($pValue = ',') + { + self::$_thousandsSeparator = $pValue; + } + + /** + * Get the currency code. If it has not yet been set explicitly, try to obtain the + * symbol information from locale. + * + * @return string + */ + public static function getCurrencyCode() + { + if (!isset(self::$_currencyCode)) { + $localeconv = localeconv(); + self::$_currencyCode = ($localeconv['currency_symbol'] != '') + ? $localeconv['currency_symbol'] : $localeconv['int_curr_symbol']; + + if (self::$_currencyCode == '') { + // Default to $ + self::$_currencyCode = '$'; + } + } + return self::$_currencyCode; + } + + /** + * Set the currency code. Only used by PHPExcel_Style_NumberFormat::toFormattedString() + * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF + * + * @param string $pValue Character for currency code + */ + public static function setCurrencyCode($pValue = '$') + { + self::$_currencyCode = $pValue; + } + + /** + * Convert SYLK encoded string to UTF-8 + * + * @param string $pValue + * @return string UTF-8 encoded string + */ + public static function SYLKtoUTF8($pValue = '') + { + // If there is no escape character in the string there is nothing to do + if (strpos($pValue, '') === false) { + return $pValue; + } + + foreach (self::$_SYLKCharacters as $k => $v) { + $pValue = str_replace($k, $v, $pValue); + } + + return $pValue; + } + + /** + * Retrieve any leading numeric part of a string, or return the full string if no leading numeric + * (handles basic integer or float, but not exponent or non decimal) + * + * @param string $value + * @return mixed string or only the leading numeric part of the string + */ + public static function testStringAsNumeric($value) + { + if (is_numeric($value)) + return $value; + $v = floatval($value); + return (is_numeric(substr($value, 0, strlen($v)))) ? $v : $value; + } } diff --git a/Classes/PHPExcel/Shared/TimeZone.php b/Classes/PHPExcel/Shared/TimeZone.php index 3aa1884e3..8e417326b 100644 --- a/Classes/PHPExcel/Shared/TimeZone.php +++ b/Classes/PHPExcel/Shared/TimeZone.php @@ -20,10 +20,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category PHPExcel - * @package PHPExcel_Shared + * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ @@ -31,110 +31,109 @@ * PHPExcel_Shared_TimeZone * * @category PHPExcel - * @package PHPExcel_Shared + * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_TimeZone { - /* - * Default Timezone used for date/time conversions - * - * @private - * @var string - */ - protected static $_timezone = 'UTC'; + /* + * Default Timezone used for date/time conversions + * + * @private + * @var string + */ + protected static $_timezone = 'UTC'; - /** - * Validate a Timezone name - * - * @param string $timezone Time zone (e.g. 'Europe/London') - * @return boolean Success or failure - */ - public static function _validateTimeZone($timezone) { - if (in_array($timezone, DateTimeZone::listIdentifiers())) { - return TRUE; - } - return FALSE; - } + /** + * Validate a Timezone name + * + * @param string $timezone Time zone (e.g. 'Europe/London') + * @return boolean Success or failure + */ + public static function _validateTimeZone($timezone) { + if (in_array($timezone, DateTimeZone::listIdentifiers())) { + return true; + } + return false; + } - /** - * Set the Default Timezone used for date/time conversions - * - * @param string $timezone Time zone (e.g. 'Europe/London') - * @return boolean Success or failure - */ - public static function setTimeZone($timezone) { - if (self::_validateTimezone($timezone)) { - self::$_timezone = $timezone; - return TRUE; - } - return FALSE; - } // function setTimezone() + /** + * Set the Default Timezone used for date/time conversions + * + * @param string $timezone Time zone (e.g. 'Europe/London') + * @return boolean Success or failure + */ + public static function setTimeZone($timezone) { + if (self::_validateTimezone($timezone)) { + self::$_timezone = $timezone; + return true; + } + return false; + } // function setTimezone() - /** - * Return the Default Timezone used for date/time conversions - * - * @return string Timezone (e.g. 'Europe/London') - */ - public static function getTimeZone() { - return self::$_timezone; - } // function getTimezone() + /** + * Return the Default Timezone used for date/time conversions + * + * @return string Timezone (e.g. 'Europe/London') + */ + public static function getTimeZone() { + return self::$_timezone; + } // function getTimezone() - /** - * Return the Timezone transition for the specified timezone and timestamp - * - * @param DateTimeZone $objTimezone The timezone for finding the transitions - * @param integer $timestamp PHP date/time value for finding the current transition - * @return array The current transition details - */ - private static function _getTimezoneTransitions($objTimezone, $timestamp) { - $allTransitions = $objTimezone->getTransitions(); - $transitions = array(); - foreach($allTransitions as $key => $transition) { - if ($transition['ts'] > $timestamp) { - $transitions[] = ($key > 0) ? $allTransitions[$key - 1] : $transition; - break; - } - if (empty($transitions)) { - $transitions[] = end($allTransitions); - } - } + /** + * Return the Timezone transition for the specified timezone and timestamp + * + * @param DateTimeZone $objTimezone The timezone for finding the transitions + * @param integer $timestamp PHP date/time value for finding the current transition + * @return array The current transition details + */ + private static function _getTimezoneTransitions($objTimezone, $timestamp) { + $allTransitions = $objTimezone->getTransitions(); + $transitions = array(); + foreach ($allTransitions as $key => $transition) { + if ($transition['ts'] > $timestamp) { + $transitions[] = ($key > 0) ? $allTransitions[$key - 1] : $transition; + break; + } + if (empty($transitions)) { + $transitions[] = end($allTransitions); + } + } - return $transitions; - } + return $transitions; + } - /** - * Return the Timezone offset used for date/time conversions to/from UST - * This requires both the timezone and the calculated date/time to allow for local DST - * - * @param string $timezone The timezone for finding the adjustment to UST - * @param integer $timestamp PHP date/time value - * @return integer Number of seconds for timezone adjustment - * @throws PHPExcel_Exception - */ - public static function getTimeZoneAdjustment($timezone, $timestamp) { - if ($timezone !== NULL) { - if (!self::_validateTimezone($timezone)) { - throw new PHPExcel_Exception("Invalid timezone " . $timezone); - } - } else { - $timezone = self::$_timezone; - } + /** + * Return the Timezone offset used for date/time conversions to/from UST + * This requires both the timezone and the calculated date/time to allow for local DST + * + * @param string $timezone The timezone for finding the adjustment to UST + * @param integer $timestamp PHP date/time value + * @return integer Number of seconds for timezone adjustment + * @throws PHPExcel_Exception + */ + public static function getTimeZoneAdjustment($timezone, $timestamp) { + if ($timezone !== null) { + if (!self::_validateTimezone($timezone)) { + throw new PHPExcel_Exception("Invalid timezone " . $timezone); + } + } else { + $timezone = self::$_timezone; + } - if ($timezone == 'UST') { - return 0; - } + if ($timezone == 'UST') { + return 0; + } - $objTimezone = new DateTimeZone($timezone); - if (version_compare(PHP_VERSION, '5.3.0') >= 0) { - $transitions = $objTimezone->getTransitions($timestamp,$timestamp); - } else { - $transitions = self::_getTimezoneTransitions($objTimezone, $timestamp); - } - - return (count($transitions) > 0) ? $transitions[0]['offset'] : 0; - } + $objTimezone = new DateTimeZone($timezone); + if (version_compare(PHP_VERSION, '5.3.0') >= 0) { + $transitions = $objTimezone->getTransitions($timestamp,$timestamp); + } else { + $transitions = self::_getTimezoneTransitions($objTimezone, $timestamp); + } + return (count($transitions) > 0) ? $transitions[0]['offset'] : 0; + } } diff --git a/Classes/PHPExcel/Shared/XMLWriter.php b/Classes/PHPExcel/Shared/XMLWriter.php index 8ec38e223..a17c112b8 100644 --- a/Classes/PHPExcel/Shared/XMLWriter.php +++ b/Classes/PHPExcel/Shared/XMLWriter.php @@ -19,10 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category PHPExcel - * @package PHPExcel_Shared + * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ if (!defined('DATE_W3C')) { @@ -38,90 +38,90 @@ * PHPExcel_Shared_XMLWriter * * @category PHPExcel - * @package PHPExcel_Shared + * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_XMLWriter extends XMLWriter { - /** Temporary storage method */ - const STORAGE_MEMORY = 1; - const STORAGE_DISK = 2; + /** Temporary storage method */ + const STORAGE_MEMORY = 1; + const STORAGE_DISK = 2; - /** - * Temporary filename - * - * @var string - */ - private $_tempFileName = ''; + /** + * Temporary filename + * + * @var string + */ + private $_tempFileName = ''; - /** - * Create a new PHPExcel_Shared_XMLWriter instance - * - * @param int $pTemporaryStorage Temporary storage location - * @param string $pTemporaryStorageFolder Temporary storage folder - */ - public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = NULL) { - // Open temporary storage - if ($pTemporaryStorage == self::STORAGE_MEMORY) { - $this->openMemory(); - } else { - // Create temporary filename - if ($pTemporaryStorageFolder === NULL) - $pTemporaryStorageFolder = PHPExcel_Shared_File::sys_get_temp_dir(); - $this->_tempFileName = @tempnam($pTemporaryStorageFolder, 'xml'); + /** + * Create a new PHPExcel_Shared_XMLWriter instance + * + * @param int $pTemporaryStorage Temporary storage location + * @param string $pTemporaryStorageFolder Temporary storage folder + */ + public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = NULL) { + // Open temporary storage + if ($pTemporaryStorage == self::STORAGE_MEMORY) { + $this->openMemory(); + } else { + // Create temporary filename + if ($pTemporaryStorageFolder === NULL) + $pTemporaryStorageFolder = PHPExcel_Shared_File::sys_get_temp_dir(); + $this->_tempFileName = @tempnam($pTemporaryStorageFolder, 'xml'); - // Open storage - if ($this->openUri($this->_tempFileName) === false) { - // Fallback to memory... - $this->openMemory(); - } - } + // Open storage + if ($this->openUri($this->_tempFileName) === false) { + // Fallback to memory... + $this->openMemory(); + } + } - // Set default values - if (DEBUGMODE_ENABLED) { - $this->setIndent(true); - } - } + // Set default values + if (DEBUGMODE_ENABLED) { + $this->setIndent(true); + } + } - /** - * Destructor - */ - public function __destruct() { - // Unlink temporary files - if ($this->_tempFileName != '') { - @unlink($this->_tempFileName); - } - } + /** + * Destructor + */ + public function __destruct() { + // Unlink temporary files + if ($this->_tempFileName != '') { + @unlink($this->_tempFileName); + } + } - /** - * Get written data - * - * @return $data - */ - public function getData() { - if ($this->_tempFileName == '') { - return $this->outputMemory(true); - } else { - $this->flush(); - return file_get_contents($this->_tempFileName); - } - } + /** + * Get written data + * + * @return $data + */ + public function getData() { + if ($this->_tempFileName == '') { + return $this->outputMemory(true); + } else { + $this->flush(); + return file_get_contents($this->_tempFileName); + } + } - /** - * Fallback method for writeRaw, introduced in PHP 5.2 - * - * @param string $text - * @return string - */ - public function writeRawData($text) - { - if (is_array($text)) { - $text = implode("\n",$text); - } + /** + * Fallback method for writeRaw, introduced in PHP 5.2 + * + * @param string $text + * @return string + */ + public function writeRawData($text) + { + if (is_array($text)) { + $text = implode("\n",$text); + } - if (method_exists($this, 'writeRaw')) { - return $this->writeRaw(htmlspecialchars($text)); - } + if (method_exists($this, 'writeRaw')) { + return $this->writeRaw(htmlspecialchars($text)); + } - return $this->text($text); - } + return $this->text($text); + } } diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index 4af9c3d13..6a1dcc647 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -21,12 +21,12 @@ * @category PHPExcel * @package PHPExcel_Shared_ZipArchive * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ if (!defined('PCLZIP_TEMPORARY_DIR')) { - define('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir() . DIRECTORY_SEPARATOR); + define('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir() . DIRECTORY_SEPARATOR); } require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/PCLZip/pclzip.lib.php'; @@ -41,75 +41,72 @@ class PHPExcel_Shared_ZipArchive { - /** constants */ - const OVERWRITE = 'OVERWRITE'; - const CREATE = 'CREATE'; + /** constants */ + const OVERWRITE = 'OVERWRITE'; + const CREATE = 'CREATE'; - /** - * Temporary storage directory - * - * @var string - */ - private $_tempDir; + /** + * Temporary storage directory + * + * @var string + */ + private $_tempDir; - /** - * Zip Archive Stream Handle - * - * @var string - */ - private $_zip; + /** + * Zip Archive Stream Handle + * + * @var string + */ + private $_zip; /** - * Open a new zip archive - * - * @param string $fileName Filename for the zip archive - * @return boolean + * Open a new zip archive + * + * @param string $fileName Filename for the zip archive + * @return boolean */ - public function open($fileName) - { - $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + public function open($fileName) + { + $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); - $this->_zip = new PclZip($fileName); + $this->_zip = new PclZip($fileName); - return true; - } + return true; + } /** - * Close this zip archive - * + * Close this zip archive + * */ - public function close() - { - } + public function close() + { + } /** - * Add a new file to the zip archive from a string of raw data. - * - * @param string $localname Directory/Name of the file to add to the zip archive - * @param string $contents String of data to add to the zip archive + * Add a new file to the zip archive from a string of raw data. + * + * @param string $localname Directory/Name of the file to add to the zip archive + * @param string $contents String of data to add to the zip archive */ - public function addFromString($localname, $contents) - { - $filenameParts = pathinfo($localname); + public function addFromString($localname, $contents) + { + $filenameParts = pathinfo($localname); - $handle = fopen($this->_tempDir.'/'.$filenameParts["basename"], "wb"); - fwrite($handle, $contents); - fclose($handle); + $handle = fopen($this->_tempDir.'/'.$filenameParts["basename"], "wb"); + fwrite($handle, $contents); + fclose($handle); - $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], - PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, - PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"] - ); - if ($res == 0) { - throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->_zip->errorInfo(true)); - } + $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"]); + if ($res == 0) { + throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->_zip->errorInfo(true)); + } - unlink($this->_tempDir.'/'.$filenameParts["basename"]); - } + unlink($this->_tempDir.'/'.$filenameParts["basename"]); + } /** * Find if given fileName exist in archive (Emulate ZipArchive locateName()) @@ -138,7 +135,7 @@ public function locateName($fileName) * @param string $fileName Filename for the file in zip archive * @return string $contents File string contents */ - public function getFromName($fileName) + public function getFromName($fileName) { $list = $this->_zip->listContent(); $listCount = count($list); @@ -158,7 +155,7 @@ public function getFromName($fileName) $filename = substr($fileName, 1); $list_index = -1; for ($i = 0; $i < $listCount; ++$i) { - if (strtolower($list[$i]["filename"]) == strtolower($fileName) || + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { $list_index = $i; break; diff --git a/Classes/PHPExcel/Shared/ZipStreamWrapper.php b/Classes/PHPExcel/Shared/ZipStreamWrapper.php index a5ceb1e4d..30b57be54 100644 --- a/Classes/PHPExcel/Shared/ZipStreamWrapper.php +++ b/Classes/PHPExcel/Shared/ZipStreamWrapper.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -34,11 +34,11 @@ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Shared_ZipStreamWrapper { - /** - * Internal ZipAcrhive - * - * @var ZipAcrhive - */ + /** + * Internal ZipAcrhive + * + * @var ZipAcrhive + */ private $_archive; /** @@ -66,18 +66,18 @@ class PHPExcel_Shared_ZipStreamWrapper { * Register wrapper */ public static function register() { - @stream_wrapper_unregister("zip"); - @stream_wrapper_register("zip", __CLASS__); + @stream_wrapper_unregister("zip"); + @stream_wrapper_register("zip", __CLASS__); } /** - * Implements support for fopen(). - * - * @param string $path resource name including scheme, e.g. - * @param string $mode only "r" is supported - * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH - * @param string &$openedPath absolute path of the opened stream (out parameter) - * @return bool true on success + * Implements support for fopen(). + * + * @param string $path resource name including scheme, e.g. + * @param string $mode only "r" is supported + * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH + * @param string &$openedPath absolute path of the opened stream (out parameter) + * @return bool true on success */ public function stream_open($path, $mode, $options, &$opened_path) { // Check for mode @@ -85,9 +85,9 @@ public function stream_open($path, $mode, $options, &$opened_path) { throw new PHPExcel_Reader_Exception('Mode ' . $mode . ' is not supported. Only read mode is supported.'); } - $pos = strrpos($path, '#'); - $url['host'] = substr($path, 6, $pos - 6); // 6: strlen('zip://') - $url['fragment'] = substr($path, $pos + 1); + $pos = strrpos($path, '#'); + $url['host'] = substr($path, 6, $pos - 6); // 6: strlen('zip://') + $url['fragment'] = substr($path, $pos + 1); // Open archive $this->_archive = new ZipArchive(); @@ -101,37 +101,37 @@ public function stream_open($path, $mode, $options, &$opened_path) { } /** - * Implements support for fstat(). - * - * @return boolean + * Implements support for fstat(). + * + * @return boolean */ public function statName() { return $this->_fileNameInArchive; } /** - * Implements support for fstat(). - * - * @return boolean + * Implements support for fstat(). + * + * @return boolean */ public function url_stat() { return $this->statName( $this->_fileNameInArchive ); } /** - * Implements support for fstat(). - * - * @return boolean + * Implements support for fstat(). + * + * @return boolean */ public function stream_stat() { return $this->_archive->statName( $this->_fileNameInArchive ); } /** - * Implements support for fread(), fgets() etc. - * - * @param int $count maximum number of bytes to read - * @return string + * Implements support for fread(), fgets() etc. + * + * @param int $count maximum number of bytes to read + * @return string */ function stream_read($count) { $ret = substr($this->_data, $this->_position, $count); @@ -140,10 +140,10 @@ function stream_read($count) { } /** - * Returns the position of the file pointer, i.e. its offset into the file - * stream. Implements support for ftell(). - * - * @return int + * Returns the position of the file pointer, i.e. its offset into the file + * stream. Implements support for ftell(). + * + * @return int */ public function stream_tell() { return $this->_position; @@ -151,8 +151,8 @@ public function stream_tell() { /** * EOF stream - * - * @return bool + * + * @return bool */ public function stream_eof() { return $this->_position >= strlen($this->_data); @@ -160,10 +160,10 @@ public function stream_eof() { /** * Seek stream - * - * @param int $offset byte offset - * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END - * @return bool + * + * @param int $offset byte offset + * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END + * @return bool */ public function stream_seek($offset, $whence) { switch ($whence) { diff --git a/Classes/PHPExcel/Shared/trend/bestFitClass.php b/Classes/PHPExcel/Shared/trend/bestFitClass.php index b797d664f..665e22589 100644 --- a/Classes/PHPExcel/Shared/trend/bestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/bestFitClass.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Trend * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,398 +35,398 @@ */ class PHPExcel_Best_Fit { - /** - * Indicator flag for a calculation error - * - * @var boolean - **/ - protected $_error = False; + /** + * Indicator flag for a calculation error + * + * @var boolean + **/ + protected $_error = False; - /** - * Algorithm type to use for best-fit - * - * @var string - **/ - protected $_bestFitType = 'undetermined'; + /** + * Algorithm type to use for best-fit + * + * @var string + **/ + protected $_bestFitType = 'undetermined'; - /** - * Number of entries in the sets of x- and y-value arrays - * - * @var int - **/ - protected $_valueCount = 0; + /** + * Number of entries in the sets of x- and y-value arrays + * + * @var int + **/ + protected $_valueCount = 0; - /** - * X-value dataseries of values - * - * @var float[] - **/ - protected $_xValues = array(); + /** + * X-value dataseries of values + * + * @var float[] + **/ + protected $_xValues = array(); - /** - * Y-value dataseries of values - * - * @var float[] - **/ - protected $_yValues = array(); + /** + * Y-value dataseries of values + * + * @var float[] + **/ + protected $_yValues = array(); - /** - * Flag indicating whether values should be adjusted to Y=0 - * - * @var boolean - **/ - protected $_adjustToZero = False; - - /** - * Y-value series of best-fit values - * - * @var float[] - **/ - protected $_yBestFitValues = array(); - - protected $_goodnessOfFit = 1; - - protected $_stdevOfResiduals = 0; - - protected $_covariance = 0; - - protected $_correlation = 0; - - protected $_SSRegression = 0; - - protected $_SSResiduals = 0; - - protected $_DFResiduals = 0; - - protected $_F = 0; - - protected $_slope = 0; - - protected $_slopeSE = 0; - - protected $_intersect = 0; - - protected $_intersectSE = 0; - - protected $_Xoffset = 0; - - protected $_Yoffset = 0; - - - public function getError() { - return $this->_error; - } // function getBestFitType() - - - public function getBestFitType() { - return $this->_bestFitType; - } // function getBestFitType() - - - /** - * Return the Y-Value for a specified value of X - * - * @param float $xValue X-Value - * @return float Y-Value - */ - public function getValueOfYForX($xValue) { - return False; - } // function getValueOfYForX() - - - /** - * Return the X-Value for a specified value of Y - * - * @param float $yValue Y-Value - * @return float X-Value - */ - public function getValueOfXForY($yValue) { - return False; - } // function getValueOfXForY() - - - /** - * Return the original set of X-Values - * - * @return float[] X-Values - */ - public function getXValues() { - return $this->_xValues; - } // function getValueOfXForY() - - - /** - * Return the Equation of the best-fit line - * - * @param int $dp Number of places of decimal precision to display - * @return string - */ - public function getEquation($dp=0) { - return False; - } // function getEquation() - - - /** - * Return the Slope of the line - * - * @param int $dp Number of places of decimal precision to display - * @return string - */ - public function getSlope($dp=0) { - if ($dp != 0) { - return round($this->_slope,$dp); - } - return $this->_slope; - } // function getSlope() - - - /** - * Return the standard error of the Slope - * - * @param int $dp Number of places of decimal precision to display - * @return string - */ - public function getSlopeSE($dp=0) { - if ($dp != 0) { - return round($this->_slopeSE,$dp); - } - return $this->_slopeSE; - } // function getSlopeSE() - - - /** - * Return the Value of X where it intersects Y = 0 - * - * @param int $dp Number of places of decimal precision to display - * @return string - */ - public function getIntersect($dp=0) { - if ($dp != 0) { - return round($this->_intersect,$dp); - } - return $this->_intersect; - } // function getIntersect() - - - /** - * Return the standard error of the Intersect - * - * @param int $dp Number of places of decimal precision to display - * @return string - */ - public function getIntersectSE($dp=0) { - if ($dp != 0) { - return round($this->_intersectSE,$dp); - } - return $this->_intersectSE; - } // function getIntersectSE() - - - /** - * Return the goodness of fit for this regression - * - * @param int $dp Number of places of decimal precision to return - * @return float - */ - public function getGoodnessOfFit($dp=0) { - if ($dp != 0) { - return round($this->_goodnessOfFit,$dp); - } - return $this->_goodnessOfFit; - } // function getGoodnessOfFit() - - - public function getGoodnessOfFitPercent($dp=0) { - if ($dp != 0) { - return round($this->_goodnessOfFit * 100,$dp); - } - return $this->_goodnessOfFit * 100; - } // function getGoodnessOfFitPercent() - - - /** - * Return the standard deviation of the residuals for this regression - * - * @param int $dp Number of places of decimal precision to return - * @return float - */ - public function getStdevOfResiduals($dp=0) { - if ($dp != 0) { - return round($this->_stdevOfResiduals,$dp); - } - return $this->_stdevOfResiduals; - } // function getStdevOfResiduals() - - - public function getSSRegression($dp=0) { - if ($dp != 0) { - return round($this->_SSRegression,$dp); - } - return $this->_SSRegression; - } // function getSSRegression() - - - public function getSSResiduals($dp=0) { - if ($dp != 0) { - return round($this->_SSResiduals,$dp); - } - return $this->_SSResiduals; - } // function getSSResiduals() - - - public function getDFResiduals($dp=0) { - if ($dp != 0) { - return round($this->_DFResiduals,$dp); - } - return $this->_DFResiduals; - } // function getDFResiduals() - - - public function getF($dp=0) { - if ($dp != 0) { - return round($this->_F,$dp); - } - return $this->_F; - } // function getF() - - - public function getCovariance($dp=0) { - if ($dp != 0) { - return round($this->_covariance,$dp); - } - return $this->_covariance; - } // function getCovariance() - - - public function getCorrelation($dp=0) { - if ($dp != 0) { - return round($this->_correlation,$dp); - } - return $this->_correlation; - } // function getCorrelation() - - - public function getYBestFitValues() { - return $this->_yBestFitValues; - } // function getYBestFitValues() - - - protected function _calculateGoodnessOfFit($sumX,$sumY,$sumX2,$sumY2,$sumXY,$meanX,$meanY, $const) { - $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0; - foreach($this->_xValues as $xKey => $xValue) { - $bestFitY = $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); - - $SSres += ($this->_yValues[$xKey] - $bestFitY) * ($this->_yValues[$xKey] - $bestFitY); - if ($const) { - $SStot += ($this->_yValues[$xKey] - $meanY) * ($this->_yValues[$xKey] - $meanY); - } else { - $SStot += $this->_yValues[$xKey] * $this->_yValues[$xKey]; - } - $SScov += ($this->_xValues[$xKey] - $meanX) * ($this->_yValues[$xKey] - $meanY); - if ($const) { - $SSsex += ($this->_xValues[$xKey] - $meanX) * ($this->_xValues[$xKey] - $meanX); - } else { - $SSsex += $this->_xValues[$xKey] * $this->_xValues[$xKey]; - } - } - - $this->_SSResiduals = $SSres; - $this->_DFResiduals = $this->_valueCount - 1 - $const; - - if ($this->_DFResiduals == 0.0) { - $this->_stdevOfResiduals = 0.0; - } else { - $this->_stdevOfResiduals = sqrt($SSres / $this->_DFResiduals); - } - if (($SStot == 0.0) || ($SSres == $SStot)) { - $this->_goodnessOfFit = 1; - } else { - $this->_goodnessOfFit = 1 - ($SSres / $SStot); - } - - $this->_SSRegression = $this->_goodnessOfFit * $SStot; - $this->_covariance = $SScov / $this->_valueCount; - $this->_correlation = ($this->_valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->_valueCount * $sumX2 - pow($sumX,2)) * ($this->_valueCount * $sumY2 - pow($sumY,2))); - $this->_slopeSE = $this->_stdevOfResiduals / sqrt($SSsex); - $this->_intersectSE = $this->_stdevOfResiduals * sqrt(1 / ($this->_valueCount - ($sumX * $sumX) / $sumX2)); - if ($this->_SSResiduals != 0.0) { - if ($this->_DFResiduals == 0.0) { - $this->_F = 0.0; - } else { - $this->_F = $this->_SSRegression / ($this->_SSResiduals / $this->_DFResiduals); - } - } else { - if ($this->_DFResiduals == 0.0) { - $this->_F = 0.0; - } else { - $this->_F = $this->_SSRegression / $this->_DFResiduals; - } - } - } // function _calculateGoodnessOfFit() - - - protected function _leastSquareFit($yValues, $xValues, $const) { - // calculate sums - $x_sum = array_sum($xValues); - $y_sum = array_sum($yValues); - $meanX = $x_sum / $this->_valueCount; - $meanY = $y_sum / $this->_valueCount; - $mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0; - for($i = 0; $i < $this->_valueCount; ++$i) { - $xy_sum += $xValues[$i] * $yValues[$i]; - $xx_sum += $xValues[$i] * $xValues[$i]; - $yy_sum += $yValues[$i] * $yValues[$i]; - - if ($const) { - $mBase += ($xValues[$i] - $meanX) * ($yValues[$i] - $meanY); - $mDivisor += ($xValues[$i] - $meanX) * ($xValues[$i] - $meanX); - } else { - $mBase += $xValues[$i] * $yValues[$i]; - $mDivisor += $xValues[$i] * $xValues[$i]; - } - } - - // calculate slope -// $this->_slope = (($this->_valueCount * $xy_sum) - ($x_sum * $y_sum)) / (($this->_valueCount * $xx_sum) - ($x_sum * $x_sum)); - $this->_slope = $mBase / $mDivisor; - - // calculate intersect -// $this->_intersect = ($y_sum - ($this->_slope * $x_sum)) / $this->_valueCount; - if ($const) { - $this->_intersect = $meanY - ($this->_slope * $meanX); - } else { - $this->_intersect = 0; - } - - $this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum,$meanX,$meanY,$const); - } // function _leastSquareFit() - - - /** - * Define the regression - * - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - function __construct($yValues, $xValues=array(), $const=True) { - // Calculate number of points - $nY = count($yValues); - $nX = count($xValues); - - // Define X Values if necessary - if ($nX == 0) { - $xValues = range(1,$nY); - $nX = $nY; - } elseif ($nY != $nX) { - // Ensure both arrays of points are the same size - $this->_error = True; - return False; - } - - $this->_valueCount = $nY; - $this->_xValues = $xValues; - $this->_yValues = $yValues; - } // function __construct() - -} // class bestFit + /** + * Flag indicating whether values should be adjusted to Y=0 + * + * @var boolean + **/ + protected $_adjustToZero = False; + + /** + * Y-value series of best-fit values + * + * @var float[] + **/ + protected $_yBestFitValues = array(); + + protected $_goodnessOfFit = 1; + + protected $_stdevOfResiduals = 0; + + protected $_covariance = 0; + + protected $_correlation = 0; + + protected $_SSRegression = 0; + + protected $_SSResiduals = 0; + + protected $_DFResiduals = 0; + + protected $_F = 0; + + protected $_slope = 0; + + protected $_slopeSE = 0; + + protected $_intersect = 0; + + protected $_intersectSE = 0; + + protected $_Xoffset = 0; + + protected $_Yoffset = 0; + + + public function getError() { + return $this->_error; + } // function getBestFitType() + + + public function getBestFitType() { + return $this->_bestFitType; + } // function getBestFitType() + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + */ + public function getValueOfYForX($xValue) { + return False; + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + */ + public function getValueOfXForY($yValue) { + return False; + } // function getValueOfXForY() + + + /** + * Return the original set of X-Values + * + * @return float[] X-Values + */ + public function getXValues() { + return $this->_xValues; + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getEquation($dp=0) { + return False; + } // function getEquation() + + + /** + * Return the Slope of the line + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getSlope($dp=0) { + if ($dp != 0) { + return round($this->_slope,$dp); + } + return $this->_slope; + } // function getSlope() + + + /** + * Return the standard error of the Slope + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getSlopeSE($dp=0) { + if ($dp != 0) { + return round($this->_slopeSE,$dp); + } + return $this->_slopeSE; + } // function getSlopeSE() + + + /** + * Return the Value of X where it intersects Y = 0 + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getIntersect($dp=0) { + if ($dp != 0) { + return round($this->_intersect,$dp); + } + return $this->_intersect; + } // function getIntersect() + + + /** + * Return the standard error of the Intersect + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getIntersectSE($dp=0) { + if ($dp != 0) { + return round($this->_intersectSE,$dp); + } + return $this->_intersectSE; + } // function getIntersectSE() + + + /** + * Return the goodness of fit for this regression + * + * @param int $dp Number of places of decimal precision to return + * @return float + */ + public function getGoodnessOfFit($dp=0) { + if ($dp != 0) { + return round($this->_goodnessOfFit,$dp); + } + return $this->_goodnessOfFit; + } // function getGoodnessOfFit() + + + public function getGoodnessOfFitPercent($dp=0) { + if ($dp != 0) { + return round($this->_goodnessOfFit * 100,$dp); + } + return $this->_goodnessOfFit * 100; + } // function getGoodnessOfFitPercent() + + + /** + * Return the standard deviation of the residuals for this regression + * + * @param int $dp Number of places of decimal precision to return + * @return float + */ + public function getStdevOfResiduals($dp=0) { + if ($dp != 0) { + return round($this->_stdevOfResiduals,$dp); + } + return $this->_stdevOfResiduals; + } // function getStdevOfResiduals() + + + public function getSSRegression($dp=0) { + if ($dp != 0) { + return round($this->_SSRegression,$dp); + } + return $this->_SSRegression; + } // function getSSRegression() + + + public function getSSResiduals($dp=0) { + if ($dp != 0) { + return round($this->_SSResiduals,$dp); + } + return $this->_SSResiduals; + } // function getSSResiduals() + + + public function getDFResiduals($dp=0) { + if ($dp != 0) { + return round($this->_DFResiduals,$dp); + } + return $this->_DFResiduals; + } // function getDFResiduals() + + + public function getF($dp=0) { + if ($dp != 0) { + return round($this->_F,$dp); + } + return $this->_F; + } // function getF() + + + public function getCovariance($dp=0) { + if ($dp != 0) { + return round($this->_covariance,$dp); + } + return $this->_covariance; + } // function getCovariance() + + + public function getCorrelation($dp=0) { + if ($dp != 0) { + return round($this->_correlation,$dp); + } + return $this->_correlation; + } // function getCorrelation() + + + public function getYBestFitValues() { + return $this->_yBestFitValues; + } // function getYBestFitValues() + + + protected function _calculateGoodnessOfFit($sumX,$sumY,$sumX2,$sumY2,$sumXY,$meanX,$meanY, $const) { + $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0; + foreach($this->_xValues as $xKey => $xValue) { + $bestFitY = $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); + + $SSres += ($this->_yValues[$xKey] - $bestFitY) * ($this->_yValues[$xKey] - $bestFitY); + if ($const) { + $SStot += ($this->_yValues[$xKey] - $meanY) * ($this->_yValues[$xKey] - $meanY); + } else { + $SStot += $this->_yValues[$xKey] * $this->_yValues[$xKey]; + } + $SScov += ($this->_xValues[$xKey] - $meanX) * ($this->_yValues[$xKey] - $meanY); + if ($const) { + $SSsex += ($this->_xValues[$xKey] - $meanX) * ($this->_xValues[$xKey] - $meanX); + } else { + $SSsex += $this->_xValues[$xKey] * $this->_xValues[$xKey]; + } + } + + $this->_SSResiduals = $SSres; + $this->_DFResiduals = $this->_valueCount - 1 - $const; + + if ($this->_DFResiduals == 0.0) { + $this->_stdevOfResiduals = 0.0; + } else { + $this->_stdevOfResiduals = sqrt($SSres / $this->_DFResiduals); + } + if (($SStot == 0.0) || ($SSres == $SStot)) { + $this->_goodnessOfFit = 1; + } else { + $this->_goodnessOfFit = 1 - ($SSres / $SStot); + } + + $this->_SSRegression = $this->_goodnessOfFit * $SStot; + $this->_covariance = $SScov / $this->_valueCount; + $this->_correlation = ($this->_valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->_valueCount * $sumX2 - pow($sumX,2)) * ($this->_valueCount * $sumY2 - pow($sumY,2))); + $this->_slopeSE = $this->_stdevOfResiduals / sqrt($SSsex); + $this->_intersectSE = $this->_stdevOfResiduals * sqrt(1 / ($this->_valueCount - ($sumX * $sumX) / $sumX2)); + if ($this->_SSResiduals != 0.0) { + if ($this->_DFResiduals == 0.0) { + $this->_F = 0.0; + } else { + $this->_F = $this->_SSRegression / ($this->_SSResiduals / $this->_DFResiduals); + } + } else { + if ($this->_DFResiduals == 0.0) { + $this->_F = 0.0; + } else { + $this->_F = $this->_SSRegression / $this->_DFResiduals; + } + } + } // function _calculateGoodnessOfFit() + + + protected function _leastSquareFit($yValues, $xValues, $const) { + // calculate sums + $x_sum = array_sum($xValues); + $y_sum = array_sum($yValues); + $meanX = $x_sum / $this->_valueCount; + $meanY = $y_sum / $this->_valueCount; + $mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0; + for($i = 0; $i < $this->_valueCount; ++$i) { + $xy_sum += $xValues[$i] * $yValues[$i]; + $xx_sum += $xValues[$i] * $xValues[$i]; + $yy_sum += $yValues[$i] * $yValues[$i]; + + if ($const) { + $mBase += ($xValues[$i] - $meanX) * ($yValues[$i] - $meanY); + $mDivisor += ($xValues[$i] - $meanX) * ($xValues[$i] - $meanX); + } else { + $mBase += $xValues[$i] * $yValues[$i]; + $mDivisor += $xValues[$i] * $xValues[$i]; + } + } + + // calculate slope +// $this->_slope = (($this->_valueCount * $xy_sum) - ($x_sum * $y_sum)) / (($this->_valueCount * $xx_sum) - ($x_sum * $x_sum)); + $this->_slope = $mBase / $mDivisor; + + // calculate intersect +// $this->_intersect = ($y_sum - ($this->_slope * $x_sum)) / $this->_valueCount; + if ($const) { + $this->_intersect = $meanY - ($this->_slope * $meanX); + } else { + $this->_intersect = 0; + } + + $this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum,$meanX,$meanY,$const); + } // function _leastSquareFit() + + + /** + * Define the regression + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + // Calculate number of points + $nY = count($yValues); + $nX = count($xValues); + + // Define X Values if necessary + if ($nX == 0) { + $xValues = range(1,$nY); + $nX = $nY; + } elseif ($nY != $nX) { + // Ensure both arrays of points are the same size + $this->_error = True; + return False; + } + + $this->_valueCount = $nY; + $this->_xValues = $xValues; + $this->_yValues = $yValues; + } // function __construct() + +} // class bestFit diff --git a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php index 541e22919..6a92297ff 100644 --- a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Trend * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -38,111 +38,111 @@ */ class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit { - /** - * Algorithm type to use for best-fit - * (Name of this trend class) - * - * @var string - **/ - protected $_bestFitType = 'exponential'; - - - /** - * Return the Y-Value for a specified value of X - * - * @param float $xValue X-Value - * @return float Y-Value - **/ - public function getValueOfYForX($xValue) { - return $this->getIntersect() * pow($this->getSlope(),($xValue - $this->_Xoffset)); - } // function getValueOfYForX() - - - /** - * Return the X-Value for a specified value of Y - * - * @param float $yValue Y-Value - * @return float X-Value - **/ - public function getValueOfXForY($yValue) { - return log(($yValue + $this->_Yoffset) / $this->getIntersect()) / log($this->getSlope()); - } // function getValueOfXForY() - - - /** - * Return the Equation of the best-fit line - * - * @param int $dp Number of places of decimal precision to display - * @return string - **/ - public function getEquation($dp=0) { - $slope = $this->getSlope($dp); - $intersect = $this->getIntersect($dp); - - return 'Y = '.$intersect.' * '.$slope.'^X'; - } // function getEquation() - - - /** - * Return the Slope of the line - * - * @param int $dp Number of places of decimal precision to display - * @return string - **/ - public function getSlope($dp=0) { - if ($dp != 0) { - return round(exp($this->_slope),$dp); - } - return exp($this->_slope); - } // function getSlope() - - - /** - * Return the Value of X where it intersects Y = 0 - * - * @param int $dp Number of places of decimal precision to display - * @return string - **/ - public function getIntersect($dp=0) { - if ($dp != 0) { - return round(exp($this->_intersect),$dp); - } - return exp($this->_intersect); - } // function getIntersect() - - - /** - * Execute the regression and calculate the goodness of fit for a set of X and Y data values - * - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - private function _exponential_regression($yValues, $xValues, $const) { - foreach($yValues as &$value) { - if ($value < 0.0) { - $value = 0 - log(abs($value)); - } elseif ($value > 0.0) { - $value = log($value); - } - } - unset($value); - - $this->_leastSquareFit($yValues, $xValues, $const); - } // function _exponential_regression() - - - /** - * Define the regression and calculate the goodness of fit for a set of X and Y data values - * - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - function __construct($yValues, $xValues=array(), $const=True) { - if (parent::__construct($yValues, $xValues) !== False) { - $this->_exponential_regression($yValues, $xValues, $const); - } - } // function __construct() - -} // class exponentialBestFit \ No newline at end of file + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'exponential'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() * pow($this->getSlope(),($xValue - $this->_Xoffset)); + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return log(($yValue + $this->_Yoffset) / $this->getIntersect()) / log($this->getSlope()); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' * '.$slope.'^X'; + } // function getEquation() + + + /** + * Return the Slope of the line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getSlope($dp=0) { + if ($dp != 0) { + return round(exp($this->_slope),$dp); + } + return exp($this->_slope); + } // function getSlope() + + + /** + * Return the Value of X where it intersects Y = 0 + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getIntersect($dp=0) { + if ($dp != 0) { + return round(exp($this->_intersect),$dp); + } + return exp($this->_intersect); + } // function getIntersect() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _exponential_regression($yValues, $xValues, $const) { + foreach($yValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + + $this->_leastSquareFit($yValues, $xValues, $const); + } // function _exponential_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_exponential_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class exponentialBestFit \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php index c6575a4b0..b60d5e779 100644 --- a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Trend * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -38,74 +38,74 @@ */ class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit { - /** - * Algorithm type to use for best-fit - * (Name of this trend class) - * - * @var string - **/ - protected $_bestFitType = 'linear'; - - - /** - * Return the Y-Value for a specified value of X - * - * @param float $xValue X-Value - * @return float Y-Value - **/ - public function getValueOfYForX($xValue) { - return $this->getIntersect() + $this->getSlope() * $xValue; - } // function getValueOfYForX() - - - /** - * Return the X-Value for a specified value of Y - * - * @param float $yValue Y-Value - * @return float X-Value - **/ - public function getValueOfXForY($yValue) { - return ($yValue - $this->getIntersect()) / $this->getSlope(); - } // function getValueOfXForY() - - - /** - * Return the Equation of the best-fit line - * - * @param int $dp Number of places of decimal precision to display - * @return string - **/ - public function getEquation($dp=0) { - $slope = $this->getSlope($dp); - $intersect = $this->getIntersect($dp); - - return 'Y = '.$intersect.' + '.$slope.' * X'; - } // function getEquation() - - - /** - * Execute the regression and calculate the goodness of fit for a set of X and Y data values - * - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - private function _linear_regression($yValues, $xValues, $const) { - $this->_leastSquareFit($yValues, $xValues,$const); - } // function _linear_regression() - - - /** - * Define the regression and calculate the goodness of fit for a set of X and Y data values - * - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - function __construct($yValues, $xValues=array(), $const=True) { - if (parent::__construct($yValues, $xValues) !== False) { - $this->_linear_regression($yValues, $xValues, $const); - } - } // function __construct() - -} // class linearBestFit \ No newline at end of file + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'linear'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() + $this->getSlope() * $xValue; + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return ($yValue - $this->getIntersect()) / $this->getSlope(); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' + '.$slope.' * X'; + } // function getEquation() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _linear_regression($yValues, $xValues, $const) { + $this->_leastSquareFit($yValues, $xValues,$const); + } // function _linear_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_linear_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class linearBestFit \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php index 77e9ad29d..c15446666 100644 --- a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Trend * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -38,83 +38,83 @@ */ class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit { - /** - * Algorithm type to use for best-fit - * (Name of this trend class) - * - * @var string - **/ - protected $_bestFitType = 'logarithmic'; - - - /** - * Return the Y-Value for a specified value of X - * - * @param float $xValue X-Value - * @return float Y-Value - **/ - public function getValueOfYForX($xValue) { - return $this->getIntersect() + $this->getSlope() * log($xValue - $this->_Xoffset); - } // function getValueOfYForX() - - - /** - * Return the X-Value for a specified value of Y - * - * @param float $yValue Y-Value - * @return float X-Value - **/ - public function getValueOfXForY($yValue) { - return exp(($yValue - $this->getIntersect()) / $this->getSlope()); - } // function getValueOfXForY() - - - /** - * Return the Equation of the best-fit line - * - * @param int $dp Number of places of decimal precision to display - * @return string - **/ - public function getEquation($dp=0) { - $slope = $this->getSlope($dp); - $intersect = $this->getIntersect($dp); - - return 'Y = '.$intersect.' + '.$slope.' * log(X)'; - } // function getEquation() - - - /** - * Execute the regression and calculate the goodness of fit for a set of X and Y data values - * - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - private function _logarithmic_regression($yValues, $xValues, $const) { - foreach($xValues as &$value) { - if ($value < 0.0) { - $value = 0 - log(abs($value)); - } elseif ($value > 0.0) { - $value = log($value); - } - } - unset($value); - - $this->_leastSquareFit($yValues, $xValues, $const); - } // function _logarithmic_regression() - - - /** - * Define the regression and calculate the goodness of fit for a set of X and Y data values - * - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - function __construct($yValues, $xValues=array(), $const=True) { - if (parent::__construct($yValues, $xValues) !== False) { - $this->_logarithmic_regression($yValues, $xValues, $const); - } - } // function __construct() - -} // class logarithmicBestFit \ No newline at end of file + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'logarithmic'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() + $this->getSlope() * log($xValue - $this->_Xoffset); + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return exp(($yValue - $this->getIntersect()) / $this->getSlope()); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' + '.$slope.' * log(X)'; + } // function getEquation() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _logarithmic_regression($yValues, $xValues, $const) { + foreach($xValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + + $this->_leastSquareFit($yValues, $xValues, $const); + } // function _logarithmic_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_logarithmic_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class logarithmicBestFit \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php index 5c9fec419..b43abe768 100644 --- a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Trend * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -39,186 +39,186 @@ */ class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit { - /** - * Algorithm type to use for best-fit - * (Name of this trend class) - * - * @var string - **/ - protected $_bestFitType = 'polynomial'; - - /** - * Polynomial order - * - * @protected - * @var int - **/ - protected $_order = 0; - - - /** - * Return the order of this polynomial - * - * @return int - **/ - public function getOrder() { - return $this->_order; - } // function getOrder() - - - /** - * Return the Y-Value for a specified value of X - * - * @param float $xValue X-Value - * @return float Y-Value - **/ - public function getValueOfYForX($xValue) { - $retVal = $this->getIntersect(); - $slope = $this->getSlope(); - foreach($slope as $key => $value) { - if ($value != 0.0) { - $retVal += $value * pow($xValue, $key + 1); - } - } - return $retVal; - } // function getValueOfYForX() - - - /** - * Return the X-Value for a specified value of Y - * - * @param float $yValue Y-Value - * @return float X-Value - **/ - public function getValueOfXForY($yValue) { - return ($yValue - $this->getIntersect()) / $this->getSlope(); - } // function getValueOfXForY() - - - /** - * Return the Equation of the best-fit line - * - * @param int $dp Number of places of decimal precision to display - * @return string - **/ - public function getEquation($dp=0) { - $slope = $this->getSlope($dp); - $intersect = $this->getIntersect($dp); - - $equation = 'Y = '.$intersect; - foreach($slope as $key => $value) { - if ($value != 0.0) { - $equation .= ' + '.$value.' * X'; - if ($key > 0) { - $equation .= '^'.($key + 1); - } - } - } - return $equation; - } // function getEquation() - - - /** - * Return the Slope of the line - * - * @param int $dp Number of places of decimal precision to display - * @return string - **/ - public function getSlope($dp=0) { - if ($dp != 0) { - $coefficients = array(); - foreach($this->_slope as $coefficient) { - $coefficients[] = round($coefficient,$dp); - } - return $coefficients; - } - return $this->_slope; - } // function getSlope() - - - public function getCoefficients($dp=0) { - return array_merge(array($this->getIntersect($dp)),$this->getSlope($dp)); - } // function getCoefficients() - - - /** - * Execute the regression and calculate the goodness of fit for a set of X and Y data values - * - * @param int $order Order of Polynomial for this regression - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - private function _polynomial_regression($order, $yValues, $xValues, $const) { - // calculate sums - $x_sum = array_sum($xValues); - $y_sum = array_sum($yValues); - $xx_sum = $xy_sum = 0; - for($i = 0; $i < $this->_valueCount; ++$i) { - $xy_sum += $xValues[$i] * $yValues[$i]; - $xx_sum += $xValues[$i] * $xValues[$i]; - $yy_sum += $yValues[$i] * $yValues[$i]; - } - /* - * This routine uses logic from the PHP port of polyfit version 0.1 - * written by Michael Bommarito and Paul Meagher - * - * The function fits a polynomial function of order $order through - * a series of x-y data points using least squares. - * - */ - for ($i = 0; $i < $this->_valueCount; ++$i) { - for ($j = 0; $j <= $order; ++$j) { - $A[$i][$j] = pow($xValues[$i], $j); - } - } - for ($i=0; $i < $this->_valueCount; ++$i) { - $B[$i] = array($yValues[$i]); - } - $matrixA = new Matrix($A); - $matrixB = new Matrix($B); - $C = $matrixA->solve($matrixB); - - $coefficients = array(); - for($i = 0; $i < $C->m; ++$i) { - $r = $C->get($i, 0); - if (abs($r) <= pow(10, -9)) { - $r = 0; - } - $coefficients[] = $r; - } - - $this->_intersect = array_shift($coefficients); - $this->_slope = $coefficients; - - $this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum); - foreach($this->_xValues as $xKey => $xValue) { - $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); - } - } // function _polynomial_regression() - - - /** - * Define the regression and calculate the goodness of fit for a set of X and Y data values - * - * @param int $order Order of Polynomial for this regression - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - function __construct($order, $yValues, $xValues=array(), $const=True) { - if (parent::__construct($yValues, $xValues) !== False) { - if ($order < $this->_valueCount) { - $this->_bestFitType .= '_'.$order; - $this->_order = $order; - $this->_polynomial_regression($order, $yValues, $xValues, $const); - if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) { - $this->_error = True; - } - } else { - $this->_error = True; - } - } - } // function __construct() - -} // class polynomialBestFit \ No newline at end of file + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'polynomial'; + + /** + * Polynomial order + * + * @protected + * @var int + **/ + protected $_order = 0; + + + /** + * Return the order of this polynomial + * + * @return int + **/ + public function getOrder() { + return $this->_order; + } // function getOrder() + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + $retVal = $this->getIntersect(); + $slope = $this->getSlope(); + foreach($slope as $key => $value) { + if ($value != 0.0) { + $retVal += $value * pow($xValue, $key + 1); + } + } + return $retVal; + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return ($yValue - $this->getIntersect()) / $this->getSlope(); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + $equation = 'Y = '.$intersect; + foreach($slope as $key => $value) { + if ($value != 0.0) { + $equation .= ' + '.$value.' * X'; + if ($key > 0) { + $equation .= '^'.($key + 1); + } + } + } + return $equation; + } // function getEquation() + + + /** + * Return the Slope of the line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getSlope($dp=0) { + if ($dp != 0) { + $coefficients = array(); + foreach($this->_slope as $coefficient) { + $coefficients[] = round($coefficient,$dp); + } + return $coefficients; + } + return $this->_slope; + } // function getSlope() + + + public function getCoefficients($dp=0) { + return array_merge(array($this->getIntersect($dp)),$this->getSlope($dp)); + } // function getCoefficients() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param int $order Order of Polynomial for this regression + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _polynomial_regression($order, $yValues, $xValues, $const) { + // calculate sums + $x_sum = array_sum($xValues); + $y_sum = array_sum($yValues); + $xx_sum = $xy_sum = 0; + for($i = 0; $i < $this->_valueCount; ++$i) { + $xy_sum += $xValues[$i] * $yValues[$i]; + $xx_sum += $xValues[$i] * $xValues[$i]; + $yy_sum += $yValues[$i] * $yValues[$i]; + } + /* + * This routine uses logic from the PHP port of polyfit version 0.1 + * written by Michael Bommarito and Paul Meagher + * + * The function fits a polynomial function of order $order through + * a series of x-y data points using least squares. + * + */ + for ($i = 0; $i < $this->_valueCount; ++$i) { + for ($j = 0; $j <= $order; ++$j) { + $A[$i][$j] = pow($xValues[$i], $j); + } + } + for ($i=0; $i < $this->_valueCount; ++$i) { + $B[$i] = array($yValues[$i]); + } + $matrixA = new Matrix($A); + $matrixB = new Matrix($B); + $C = $matrixA->solve($matrixB); + + $coefficients = array(); + for($i = 0; $i < $C->m; ++$i) { + $r = $C->get($i, 0); + if (abs($r) <= pow(10, -9)) { + $r = 0; + } + $coefficients[] = $r; + } + + $this->_intersect = array_shift($coefficients); + $this->_slope = $coefficients; + + $this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum); + foreach($this->_xValues as $xKey => $xValue) { + $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); + } + } // function _polynomial_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param int $order Order of Polynomial for this regression + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($order, $yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + if ($order < $this->_valueCount) { + $this->_bestFitType .= '_'.$order; + $this->_order = $order; + $this->_polynomial_regression($order, $yValues, $xValues, $const); + if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) { + $this->_error = True; + } + } else { + $this->_error = True; + } + } + } // function __construct() + +} // class polynomialBestFit \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php index 5da232d7c..e4b229bd9 100644 --- a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Trend * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -38,105 +38,105 @@ */ class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit { - /** - * Algorithm type to use for best-fit - * (Name of this trend class) - * - * @var string - **/ - protected $_bestFitType = 'power'; - - - /** - * Return the Y-Value for a specified value of X - * - * @param float $xValue X-Value - * @return float Y-Value - **/ - public function getValueOfYForX($xValue) { - return $this->getIntersect() * pow(($xValue - $this->_Xoffset),$this->getSlope()); - } // function getValueOfYForX() - - - /** - * Return the X-Value for a specified value of Y - * - * @param float $yValue Y-Value - * @return float X-Value - **/ - public function getValueOfXForY($yValue) { - return pow((($yValue + $this->_Yoffset) / $this->getIntersect()),(1 / $this->getSlope())); - } // function getValueOfXForY() - - - /** - * Return the Equation of the best-fit line - * - * @param int $dp Number of places of decimal precision to display - * @return string - **/ - public function getEquation($dp=0) { - $slope = $this->getSlope($dp); - $intersect = $this->getIntersect($dp); - - return 'Y = '.$intersect.' * X^'.$slope; - } // function getEquation() - - - /** - * Return the Value of X where it intersects Y = 0 - * - * @param int $dp Number of places of decimal precision to display - * @return string - **/ - public function getIntersect($dp=0) { - if ($dp != 0) { - return round(exp($this->_intersect),$dp); - } - return exp($this->_intersect); - } // function getIntersect() - - - /** - * Execute the regression and calculate the goodness of fit for a set of X and Y data values - * - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - private function _power_regression($yValues, $xValues, $const) { - foreach($xValues as &$value) { - if ($value < 0.0) { - $value = 0 - log(abs($value)); - } elseif ($value > 0.0) { - $value = log($value); - } - } - unset($value); - foreach($yValues as &$value) { - if ($value < 0.0) { - $value = 0 - log(abs($value)); - } elseif ($value > 0.0) { - $value = log($value); - } - } - unset($value); - - $this->_leastSquareFit($yValues, $xValues, $const); - } // function _power_regression() - - - /** - * Define the regression and calculate the goodness of fit for a set of X and Y data values - * - * @param float[] $yValues The set of Y-values for this regression - * @param float[] $xValues The set of X-values for this regression - * @param boolean $const - */ - function __construct($yValues, $xValues=array(), $const=True) { - if (parent::__construct($yValues, $xValues) !== False) { - $this->_power_regression($yValues, $xValues, $const); - } - } // function __construct() - -} // class powerBestFit \ No newline at end of file + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'power'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() * pow(($xValue - $this->_Xoffset),$this->getSlope()); + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return pow((($yValue + $this->_Yoffset) / $this->getIntersect()),(1 / $this->getSlope())); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' * X^'.$slope; + } // function getEquation() + + + /** + * Return the Value of X where it intersects Y = 0 + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getIntersect($dp=0) { + if ($dp != 0) { + return round(exp($this->_intersect),$dp); + } + return exp($this->_intersect); + } // function getIntersect() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _power_regression($yValues, $xValues, $const) { + foreach($xValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + foreach($yValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + + $this->_leastSquareFit($yValues, $xValues, $const); + } // function _power_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_power_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class powerBestFit \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/trend/trendClass.php b/Classes/PHPExcel/Shared/trend/trendClass.php index 4ccb517d4..cbd5101b0 100644 --- a/Classes/PHPExcel/Shared/trend/trendClass.php +++ b/Classes/PHPExcel/Shared/trend/trendClass.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Shared_Trend * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -42,115 +42,115 @@ */ class trendClass { - const TREND_LINEAR = 'Linear'; - const TREND_LOGARITHMIC = 'Logarithmic'; - const TREND_EXPONENTIAL = 'Exponential'; - const TREND_POWER = 'Power'; - const TREND_POLYNOMIAL_2 = 'Polynomial_2'; - const TREND_POLYNOMIAL_3 = 'Polynomial_3'; - const TREND_POLYNOMIAL_4 = 'Polynomial_4'; - const TREND_POLYNOMIAL_5 = 'Polynomial_5'; - const TREND_POLYNOMIAL_6 = 'Polynomial_6'; - const TREND_BEST_FIT = 'Bestfit'; - const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials'; + const TREND_LINEAR = 'Linear'; + const TREND_LOGARITHMIC = 'Logarithmic'; + const TREND_EXPONENTIAL = 'Exponential'; + const TREND_POWER = 'Power'; + const TREND_POLYNOMIAL_2 = 'Polynomial_2'; + const TREND_POLYNOMIAL_3 = 'Polynomial_3'; + const TREND_POLYNOMIAL_4 = 'Polynomial_4'; + const TREND_POLYNOMIAL_5 = 'Polynomial_5'; + const TREND_POLYNOMIAL_6 = 'Polynomial_6'; + const TREND_BEST_FIT = 'Bestfit'; + const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials'; - /** - * Names of the best-fit trend analysis methods - * - * @var string[] - **/ - private static $_trendTypes = array( self::TREND_LINEAR, - self::TREND_LOGARITHMIC, - self::TREND_EXPONENTIAL, - self::TREND_POWER - ); - /** - * Names of the best-fit trend polynomial orders - * - * @var string[] - **/ - private static $_trendTypePolyOrders = array( self::TREND_POLYNOMIAL_2, - self::TREND_POLYNOMIAL_3, - self::TREND_POLYNOMIAL_4, - self::TREND_POLYNOMIAL_5, - self::TREND_POLYNOMIAL_6 - ); + /** + * Names of the best-fit trend analysis methods + * + * @var string[] + **/ + private static $_trendTypes = array( self::TREND_LINEAR, + self::TREND_LOGARITHMIC, + self::TREND_EXPONENTIAL, + self::TREND_POWER + ); + /** + * Names of the best-fit trend polynomial orders + * + * @var string[] + **/ + private static $_trendTypePolyOrders = array( self::TREND_POLYNOMIAL_2, + self::TREND_POLYNOMIAL_3, + self::TREND_POLYNOMIAL_4, + self::TREND_POLYNOMIAL_5, + self::TREND_POLYNOMIAL_6 + ); - /** - * Cached results for each method when trying to identify which provides the best fit - * - * @var PHPExcel_Best_Fit[] - **/ - private static $_trendCache = array(); + /** + * Cached results for each method when trying to identify which provides the best fit + * + * @var PHPExcel_Best_Fit[] + **/ + private static $_trendCache = array(); - public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xValues=array(), $const=True) { - // Calculate number of points in each dataset - $nY = count($yValues); - $nX = count($xValues); + public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xValues=array(), $const=True) { + // Calculate number of points in each dataset + $nY = count($yValues); + $nX = count($xValues); - // Define X Values if necessary - if ($nX == 0) { - $xValues = range(1,$nY); - $nX = $nY; - } elseif ($nY != $nX) { - // Ensure both arrays of points are the same size - trigger_error("trend(): Number of elements in coordinate arrays do not match.", E_USER_ERROR); - } + // Define X Values if necessary + if ($nX == 0) { + $xValues = range(1,$nY); + $nX = $nY; + } elseif ($nY != $nX) { + // Ensure both arrays of points are the same size + trigger_error("trend(): Number of elements in coordinate arrays do not match.", E_USER_ERROR); + } - $key = md5($trendType.$const.serialize($yValues).serialize($xValues)); - // Determine which trend method has been requested - switch ($trendType) { - // Instantiate and return the class for the requested trend method - case self::TREND_LINEAR : - case self::TREND_LOGARITHMIC : - case self::TREND_EXPONENTIAL : - case self::TREND_POWER : - if (!isset(self::$_trendCache[$key])) { - $className = 'PHPExcel_'.$trendType.'_Best_Fit'; - self::$_trendCache[$key] = new $className($yValues,$xValues,$const); - } - return self::$_trendCache[$key]; - break; - case self::TREND_POLYNOMIAL_2 : - case self::TREND_POLYNOMIAL_3 : - case self::TREND_POLYNOMIAL_4 : - case self::TREND_POLYNOMIAL_5 : - case self::TREND_POLYNOMIAL_6 : - if (!isset(self::$_trendCache[$key])) { - $order = substr($trendType,-1); - self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const); - } - return self::$_trendCache[$key]; - break; - case self::TREND_BEST_FIT : - case self::TREND_BEST_FIT_NO_POLY : - // If the request is to determine the best fit regression, then we test each trend line in turn - // Start by generating an instance of each available trend method - foreach(self::$_trendTypes as $trendMethod) { - $className = 'PHPExcel_'.$trendMethod.'BestFit'; - $bestFit[$trendMethod] = new $className($yValues,$xValues,$const); - $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); - } - if ($trendType != self::TREND_BEST_FIT_NO_POLY) { - foreach(self::$_trendTypePolyOrders as $trendMethod) { - $order = substr($trendMethod,-1); - $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const); - if ($bestFit[$trendMethod]->getError()) { - unset($bestFit[$trendMethod]); - } else { - $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); - } - } - } - // Determine which of our trend lines is the best fit, and then we return the instance of that trend class - arsort($bestFitValue); - $bestFitType = key($bestFitValue); - return $bestFit[$bestFitType]; - break; - default : - return false; - } - } // function calculate() + $key = md5($trendType.$const.serialize($yValues).serialize($xValues)); + // Determine which trend method has been requested + switch ($trendType) { + // Instantiate and return the class for the requested trend method + case self::TREND_LINEAR : + case self::TREND_LOGARITHMIC : + case self::TREND_EXPONENTIAL : + case self::TREND_POWER : + if (!isset(self::$_trendCache[$key])) { + $className = 'PHPExcel_'.$trendType.'_Best_Fit'; + self::$_trendCache[$key] = new $className($yValues,$xValues,$const); + } + return self::$_trendCache[$key]; + break; + case self::TREND_POLYNOMIAL_2 : + case self::TREND_POLYNOMIAL_3 : + case self::TREND_POLYNOMIAL_4 : + case self::TREND_POLYNOMIAL_5 : + case self::TREND_POLYNOMIAL_6 : + if (!isset(self::$_trendCache[$key])) { + $order = substr($trendType,-1); + self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const); + } + return self::$_trendCache[$key]; + break; + case self::TREND_BEST_FIT : + case self::TREND_BEST_FIT_NO_POLY : + // If the request is to determine the best fit regression, then we test each trend line in turn + // Start by generating an instance of each available trend method + foreach(self::$_trendTypes as $trendMethod) { + $className = 'PHPExcel_'.$trendMethod.'BestFit'; + $bestFit[$trendMethod] = new $className($yValues,$xValues,$const); + $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); + } + if ($trendType != self::TREND_BEST_FIT_NO_POLY) { + foreach(self::$_trendTypePolyOrders as $trendMethod) { + $order = substr($trendMethod,-1); + $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const); + if ($bestFit[$trendMethod]->getError()) { + unset($bestFit[$trendMethod]); + } else { + $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); + } + } + } + // Determine which of our trend lines is the best fit, and then we return the instance of that trend class + arsort($bestFitValue); + $bestFitType = key($bestFitValue); + return $bestFit[$bestFitType]; + break; + default : + return false; + } + } // function calculate() -} // class trendClass \ No newline at end of file +} // class trendClass \ No newline at end of file diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index 77ad376ac..92868a4da 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,828 +35,828 @@ */ class PHPExcel_Worksheet_AutoFilter { - /** - * Autofilter Worksheet - * - * @var PHPExcel_Worksheet - */ - private $_workSheet = NULL; + /** + * Autofilter Worksheet + * + * @var PHPExcel_Worksheet + */ + private $_workSheet = NULL; - /** - * Autofilter Range - * - * @var string - */ - private $_range = ''; + /** + * Autofilter Range + * + * @var string + */ + private $_range = ''; - /** - * Autofilter Column Ruleset - * - * @var array of PHPExcel_Worksheet_AutoFilter_Column - */ - private $_columns = array(); + /** + * Autofilter Column Ruleset + * + * @var array of PHPExcel_Worksheet_AutoFilter_Column + */ + private $_columns = array(); /** * Create a new PHPExcel_Worksheet_AutoFilter - * - * @param string $pRange Cell range (i.e. A1:E10) - * @param PHPExcel_Worksheet $pSheet + * + * @param string $pRange Cell range (i.e. A1:E10) + * @param PHPExcel_Worksheet $pSheet */ public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = NULL) { - $this->_range = $pRange; - $this->_workSheet = $pSheet; + $this->_range = $pRange; + $this->_workSheet = $pSheet; + } + + /** + * Get AutoFilter Parent Worksheet + * + * @return PHPExcel_Worksheet + */ + public function getParent() { + return $this->_workSheet; + } + + /** + * Set AutoFilter Parent Worksheet + * + * @param PHPExcel_Worksheet $pSheet + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setParent(PHPExcel_Worksheet $pSheet = NULL) { + $this->_workSheet = $pSheet; + + return $this; + } + + /** + * Get AutoFilter Range + * + * @return string + */ + public function getRange() { + return $this->_range; + } + + /** + * Set AutoFilter Range + * + * @param string $pRange Cell range (i.e. A1:E10) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setRange($pRange = '') { + // Uppercase coordinate + $cellAddress = explode('!',strtoupper($pRange)); + if (count($cellAddress) > 1) { + list($worksheet,$pRange) = $cellAddress; + } + + if (strpos($pRange,':') !== FALSE) { + $this->_range = $pRange; + } elseif(empty($pRange)) { + $this->_range = ''; + } else { + throw new PHPExcel_Exception('Autofilter must be set on a range of cells.'); + } + + if (empty($pRange)) { + // Discard all column rules + $this->_columns = array(); + } else { + // Discard any column rules that are no longer valid within this range + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + foreach($this->_columns as $key => $value) { + $colIndex = PHPExcel_Cell::columnIndexFromString($key); + if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) { + unset($this->_columns[$key]); + } + } + } + + return $this; + } + + /** + * Get all AutoFilter Columns + * + * @throws PHPExcel_Exception + * @return array of PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumns() { + return $this->_columns; + } + + /** + * Validate that the specified column is in the AutoFilter range + * + * @param string $column Column name (e.g. A) + * @throws PHPExcel_Exception + * @return integer The column offset within the autofilter range + */ + public function testColumnInRange($column) { + if (empty($this->_range)) { + throw new PHPExcel_Exception("No autofilter range is defined."); + } + + $columnIndex = PHPExcel_Cell::columnIndexFromString($column); + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) { + throw new PHPExcel_Exception("Column is outside of current autofilter range."); + } + + return $columnIndex - $rangeStart[0]; + } + + /** + * Get a specified AutoFilter Column Offset within the defined AutoFilter range + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return integer The offset of the specified column within the autofilter range + */ + public function getColumnOffset($pColumn) { + return $this->testColumnInRange($pColumn); + } + + /** + * Get a specified AutoFilter Column + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumn($pColumn) { + $this->testColumnInRange($pColumn); + + if (!isset($this->_columns[$pColumn])) { + $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + } + + return $this->_columns[$pColumn]; + } + + /** + * Get a specified AutoFilter Column by it's offset + * + * @param integer $pColumnOffset Column offset within range (starting from 0) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumnByOffset($pColumnOffset = 0) { + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + $pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1); + + return $this->getColumn($pColumn); + } + + /** + * Set AutoFilter + * + * @param PHPExcel_Worksheet_AutoFilter_Column|string $pColumn + * A simple string containing a Column ID like 'A' is permitted + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setColumn($pColumn) + { + if ((is_string($pColumn)) && (!empty($pColumn))) { + $column = $pColumn; + } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { + $column = $pColumn->getColumnIndex(); + } else { + throw new PHPExcel_Exception("Column is not within the autofilter range."); + } + $this->testColumnInRange($column); + + if (is_string($pColumn)) { + $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { + $pColumn->setParent($this); + $this->_columns[$column] = $pColumn; + } + ksort($this->_columns); + + return $this; + } + + /** + * Clear a specified AutoFilter Column + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function clearColumn($pColumn) { + $this->testColumnInRange($pColumn); + + if (isset($this->_columns[$pColumn])) { + unset($this->_columns[$pColumn]); + } + + return $this; } - /** - * Get AutoFilter Parent Worksheet - * - * @return PHPExcel_Worksheet - */ - public function getParent() { - return $this->_workSheet; - } - - /** - * Set AutoFilter Parent Worksheet - * - * @param PHPExcel_Worksheet $pSheet - * @return PHPExcel_Worksheet_AutoFilter - */ - public function setParent(PHPExcel_Worksheet $pSheet = NULL) { - $this->_workSheet = $pSheet; - - return $this; - } - - /** - * Get AutoFilter Range - * - * @return string - */ - public function getRange() { - return $this->_range; - } - - /** - * Set AutoFilter Range - * - * @param string $pRange Cell range (i.e. A1:E10) - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter - */ - public function setRange($pRange = '') { - // Uppercase coordinate - $cellAddress = explode('!',strtoupper($pRange)); - if (count($cellAddress) > 1) { - list($worksheet,$pRange) = $cellAddress; - } - - if (strpos($pRange,':') !== FALSE) { - $this->_range = $pRange; - } elseif(empty($pRange)) { - $this->_range = ''; - } else { - throw new PHPExcel_Exception('Autofilter must be set on a range of cells.'); - } - - if (empty($pRange)) { - // Discard all column rules - $this->_columns = array(); - } else { - // Discard any column rules that are no longer valid within this range - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); - foreach($this->_columns as $key => $value) { - $colIndex = PHPExcel_Cell::columnIndexFromString($key); - if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) { - unset($this->_columns[$key]); - } - } - } - - return $this; - } - - /** - * Get all AutoFilter Columns - * - * @throws PHPExcel_Exception - * @return array of PHPExcel_Worksheet_AutoFilter_Column - */ - public function getColumns() { - return $this->_columns; - } - - /** - * Validate that the specified column is in the AutoFilter range - * - * @param string $column Column name (e.g. A) - * @throws PHPExcel_Exception - * @return integer The column offset within the autofilter range - */ - public function testColumnInRange($column) { - if (empty($this->_range)) { - throw new PHPExcel_Exception("No autofilter range is defined."); - } - - $columnIndex = PHPExcel_Cell::columnIndexFromString($column); - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); - if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) { - throw new PHPExcel_Exception("Column is outside of current autofilter range."); - } - - return $columnIndex - $rangeStart[0]; - } - - /** - * Get a specified AutoFilter Column Offset within the defined AutoFilter range - * - * @param string $pColumn Column name (e.g. A) - * @throws PHPExcel_Exception - * @return integer The offset of the specified column within the autofilter range - */ - public function getColumnOffset($pColumn) { - return $this->testColumnInRange($pColumn); - } - - /** - * Get a specified AutoFilter Column - * - * @param string $pColumn Column name (e.g. A) - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function getColumn($pColumn) { - $this->testColumnInRange($pColumn); - - if (!isset($this->_columns[$pColumn])) { - $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); - } - - return $this->_columns[$pColumn]; - } - - /** - * Get a specified AutoFilter Column by it's offset - * - * @param integer $pColumnOffset Column offset within range (starting from 0) - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function getColumnByOffset($pColumnOffset = 0) { - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); - $pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1); - - return $this->getColumn($pColumn); - } - - /** - * Set AutoFilter - * - * @param PHPExcel_Worksheet_AutoFilter_Column|string $pColumn - * A simple string containing a Column ID like 'A' is permitted - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter - */ - public function setColumn($pColumn) - { - if ((is_string($pColumn)) && (!empty($pColumn))) { - $column = $pColumn; - } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { - $column = $pColumn->getColumnIndex(); - } else { - throw new PHPExcel_Exception("Column is not within the autofilter range."); - } - $this->testColumnInRange($column); - - if (is_string($pColumn)) { - $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); - } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { - $pColumn->setParent($this); - $this->_columns[$column] = $pColumn; - } - ksort($this->_columns); - - return $this; - } - - /** - * Clear a specified AutoFilter Column - * - * @param string $pColumn Column name (e.g. A) - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter - */ - public function clearColumn($pColumn) { - $this->testColumnInRange($pColumn); - - if (isset($this->_columns[$pColumn])) { - unset($this->_columns[$pColumn]); - } - - return $this; - } - - /** - * Shift an AutoFilter Column Rule to a different column - * - * Note: This method bypasses validation of the destination column to ensure it is within this AutoFilter range. - * Nor does it verify whether any column rule already exists at $toColumn, but will simply overrideany existing value. - * Use with caution. - * - * @param string $fromColumn Column name (e.g. A) - * @param string $toColumn Column name (e.g. B) - * @return PHPExcel_Worksheet_AutoFilter - */ - public function shiftColumn($fromColumn=NULL,$toColumn=NULL) { - $fromColumn = strtoupper($fromColumn); - $toColumn = strtoupper($toColumn); - - if (($fromColumn !== NULL) && (isset($this->_columns[$fromColumn])) && ($toColumn !== NULL)) { - $this->_columns[$fromColumn]->setParent(); - $this->_columns[$fromColumn]->setColumnIndex($toColumn); - $this->_columns[$toColumn] = $this->_columns[$fromColumn]; - $this->_columns[$toColumn]->setParent($this); - unset($this->_columns[$fromColumn]); - - ksort($this->_columns); - } - - return $this; - } - - - /** - * Test if cell value is in the defined set of values - * - * @param mixed $cellValue - * @param mixed[] $dataSet - * @return boolean - */ - private static function _filterTestInSimpleDataSet($cellValue,$dataSet) - { - $dataSetValues = $dataSet['filterValues']; - $blanks = $dataSet['blanks']; - if (($cellValue == '') || ($cellValue === NULL)) { - return $blanks; - } - return in_array($cellValue,$dataSetValues); - } - - /** - * Test if cell value is in the defined set of Excel date values - * - * @param mixed $cellValue - * @param mixed[] $dataSet - * @return boolean - */ - private static function _filterTestInDateGroupSet($cellValue,$dataSet) - { - $dateSet = $dataSet['filterValues']; - $blanks = $dataSet['blanks']; - if (($cellValue == '') || ($cellValue === NULL)) { - return $blanks; - } - - if (is_numeric($cellValue)) { - $dateValue = PHPExcel_Shared_Date::ExcelToPHP($cellValue); - if ($cellValue < 1) { - // Just the time part - $dtVal = date('His',$dateValue); - $dateSet = $dateSet['time']; - } elseif($cellValue == floor($cellValue)) { - // Just the date part - $dtVal = date('Ymd',$dateValue); - $dateSet = $dateSet['date']; - } else { - // date and time parts - $dtVal = date('YmdHis',$dateValue); - $dateSet = $dateSet['dateTime']; - } - foreach($dateSet as $dateValue) { - // Use of substr to extract value at the appropriate group level - if (substr($dtVal,0,strlen($dateValue)) == $dateValue) - return TRUE; - } - } - - return FALSE; - } - - /** - * Test if cell value is within a set of values defined by a ruleset - * - * @param mixed $cellValue - * @param mixed[] $ruleSet - * @return boolean - */ - private static function _filterTestInCustomDataSet($cellValue, $ruleSet) - { - $dataSet = $ruleSet['filterRules']; - $join = $ruleSet['join']; - $customRuleForBlanks = isset($ruleSet['customRuleForBlanks']) ? $ruleSet['customRuleForBlanks'] : FALSE; - - if (!$customRuleForBlanks) { - // Blank cells are always ignored, so return a FALSE - if (($cellValue == '') || ($cellValue === NULL)) { - return FALSE; - } - } - $returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); - foreach($dataSet as $rule) { - if (is_numeric($rule['value'])) { - // Numeric values are tested using the appropriate operator - switch ($rule['operator']) { - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : - $retVal = ($cellValue == $rule['value']); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : - $retVal = ($cellValue != $rule['value']); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN : - $retVal = ($cellValue > $rule['value']); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL : - $retVal = ($cellValue >= $rule['value']); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN : - $retVal = ($cellValue < $rule['value']); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL : - $retVal = ($cellValue <= $rule['value']); - break; - } - } elseif($rule['value'] == '') { - switch ($rule['operator']) { - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : - $retVal = (($cellValue == '') || ($cellValue === NULL)); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : - $retVal = (($cellValue != '') && ($cellValue !== NULL)); - break; - default : - $retVal = TRUE; - break; - } - } else { - // String values are always tested for equality, factoring in for wildcards (hence a regexp test) - $retVal = preg_match('/^'.$rule['value'].'$/i',$cellValue); - } - // If there are multiple conditions, then we need to test both using the appropriate join operator - switch ($join) { - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR : - $returnVal = $returnVal || $retVal; - // Break as soon as we have a TRUE match for OR joins, - // to avoid unnecessary additional code execution - if ($returnVal) - return $returnVal; - break; - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND : - $returnVal = $returnVal && $retVal; - break; - } - } - - return $returnVal; - } - - /** - * Test if cell date value is matches a set of values defined by a set of months - * - * @param mixed $cellValue - * @param mixed[] $monthSet - * @return boolean - */ - private static function _filterTestInPeriodDateSet($cellValue, $monthSet) - { - // Blank cells are always ignored, so return a FALSE - if (($cellValue == '') || ($cellValue === NULL)) { - return FALSE; - } - - if (is_numeric($cellValue)) { - $dateValue = date('m',PHPExcel_Shared_Date::ExcelToPHP($cellValue)); - if (in_array($dateValue,$monthSet)) { - return TRUE; - } - } - - return FALSE; - } - - /** - * Search/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching - * - * @var array - */ - private static $_fromReplace = array('\*', '\?', '~~', '~.*', '~.?'); - private static $_toReplace = array('.*', '.', '~', '\*', '\?'); - - - /** - * Convert a dynamic rule daterange to a custom filter range expression for ease of calculation - * - * @param string $dynamicRuleType - * @param PHPExcel_Worksheet_AutoFilter_Column &$filterColumn - * @return mixed[] - */ - private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) - { - $rDateType = PHPExcel_Calculation_Functions::getReturnDateType(); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $val = $maxVal = NULL; - - $ruleValues = array(); - $baseDate = PHPExcel_Calculation_DateTime::DATENOW(); - // Calculate start/end dates for the required date range based on current date - switch ($dynamicRuleType) { - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : - $baseDate = strtotime('-7 days',$baseDate); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : - $baseDate = strtotime('-7 days',$baseDate); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : - $baseDate = strtotime('-1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : - $baseDate = strtotime('+1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : - $baseDate = strtotime('-3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : - $baseDate = strtotime('+3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : - $baseDate = strtotime('-1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : - $baseDate = strtotime('+1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); - break; - } - - switch ($dynamicRuleType) { - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : - $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); - $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE : - $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : - $maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,31,12,date('Y',$baseDate))); - ++$maxVal; - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : - $thisMonth = date('m',$baseDate); - $thisQuarter = floor(--$thisMonth / 3); - $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),(1+$thisQuarter)*3,date('Y',$baseDate))); - ++$maxVal; - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1+$thisQuarter*3,date('Y',$baseDate))); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : - $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),date('m',$baseDate),date('Y',$baseDate))); - ++$maxVal; - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : - $dayOfWeek = date('w',$baseDate); - $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate) - $dayOfWeek; - $maxVal = $val + 7; - break; - } - - switch ($dynamicRuleType) { - // Adjust Today dates for Yesterday and Tomorrow - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : - --$maxVal; - --$val; - break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : - ++$maxVal; - ++$val; - break; - } - - // Set the filter column rule attributes ready for writing - $filterColumn->setAttributes(array( 'val' => $val, - 'maxVal' => $maxVal - ) - ); - - // Set the rules for identifying rows for hide/show - $ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, - 'value' => $val - ); - $ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, - 'value' => $maxVal - ); - PHPExcel_Calculation_Functions::setReturnDateType($rDateType); - - return array( - 'method' => '_filterTestInCustomDataSet', - 'arguments' => array( 'filterRules' => $ruleValues, - 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND - ) - ); - } - - private function _calculateTopTenValue($columnID,$startRow,$endRow,$ruleType,$ruleValue) { - $range = $columnID.$startRow.':'.$columnID.$endRow; - $dataValues = PHPExcel_Calculation_Functions::flattenArray( - $this->_workSheet->rangeToArray($range,NULL,TRUE,FALSE) - ); - - $dataValues = array_filter($dataValues); - if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) { - rsort($dataValues); - } else { - sort($dataValues); - } - - return array_pop(array_slice($dataValues,0,$ruleValue)); - } - - /** - * Apply the AutoFilter rules to the AutoFilter Range - * - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter - */ - public function showHideRows() - { - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); - - // The heading row should always be visible -// echo 'AutoFilter Heading Row ',$rangeStart[1],' is always SHOWN',PHP_EOL; - $this->_workSheet->getRowDimension($rangeStart[1])->setVisible(TRUE); - - $columnFilterTests = array(); - foreach($this->_columns as $columnID => $filterColumn) { - $rules = $filterColumn->getRules(); - switch ($filterColumn->getFilterType()) { - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER : - $ruleValues = array(); - // Build a list of the filter value selections - foreach($rules as $rule) { - $ruleType = $rule->getRuleType(); - $ruleValues[] = $rule->getValue(); - } - // Test if we want to include blanks in our filter criteria - $blanks = FALSE; - $ruleDataSet = array_filter($ruleValues); - if (count($ruleValues) != count($ruleDataSet)) - $blanks = TRUE; - if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) { - // Filter on absolute values - $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInSimpleDataSet', - 'arguments' => array( 'filterValues' => $ruleDataSet, - 'blanks' => $blanks - ) - ); - } else { - // Filter on date group values - $arguments = array( + /** + * Shift an AutoFilter Column Rule to a different column + * + * Note: This method bypasses validation of the destination column to ensure it is within this AutoFilter range. + * Nor does it verify whether any column rule already exists at $toColumn, but will simply overrideany existing value. + * Use with caution. + * + * @param string $fromColumn Column name (e.g. A) + * @param string $toColumn Column name (e.g. B) + * @return PHPExcel_Worksheet_AutoFilter + */ + public function shiftColumn($fromColumn=NULL,$toColumn=NULL) { + $fromColumn = strtoupper($fromColumn); + $toColumn = strtoupper($toColumn); + + if (($fromColumn !== NULL) && (isset($this->_columns[$fromColumn])) && ($toColumn !== NULL)) { + $this->_columns[$fromColumn]->setParent(); + $this->_columns[$fromColumn]->setColumnIndex($toColumn); + $this->_columns[$toColumn] = $this->_columns[$fromColumn]; + $this->_columns[$toColumn]->setParent($this); + unset($this->_columns[$fromColumn]); + + ksort($this->_columns); + } + + return $this; + } + + + /** + * Test if cell value is in the defined set of values + * + * @param mixed $cellValue + * @param mixed[] $dataSet + * @return boolean + */ + private static function _filterTestInSimpleDataSet($cellValue,$dataSet) + { + $dataSetValues = $dataSet['filterValues']; + $blanks = $dataSet['blanks']; + if (($cellValue == '') || ($cellValue === NULL)) { + return $blanks; + } + return in_array($cellValue,$dataSetValues); + } + + /** + * Test if cell value is in the defined set of Excel date values + * + * @param mixed $cellValue + * @param mixed[] $dataSet + * @return boolean + */ + private static function _filterTestInDateGroupSet($cellValue,$dataSet) + { + $dateSet = $dataSet['filterValues']; + $blanks = $dataSet['blanks']; + if (($cellValue == '') || ($cellValue === NULL)) { + return $blanks; + } + + if (is_numeric($cellValue)) { + $dateValue = PHPExcel_Shared_Date::ExcelToPHP($cellValue); + if ($cellValue < 1) { + // Just the time part + $dtVal = date('His',$dateValue); + $dateSet = $dateSet['time']; + } elseif($cellValue == floor($cellValue)) { + // Just the date part + $dtVal = date('Ymd',$dateValue); + $dateSet = $dateSet['date']; + } else { + // date and time parts + $dtVal = date('YmdHis',$dateValue); + $dateSet = $dateSet['dateTime']; + } + foreach($dateSet as $dateValue) { + // Use of substr to extract value at the appropriate group level + if (substr($dtVal,0,strlen($dateValue)) == $dateValue) + return TRUE; + } + } + + return FALSE; + } + + /** + * Test if cell value is within a set of values defined by a ruleset + * + * @param mixed $cellValue + * @param mixed[] $ruleSet + * @return boolean + */ + private static function _filterTestInCustomDataSet($cellValue, $ruleSet) + { + $dataSet = $ruleSet['filterRules']; + $join = $ruleSet['join']; + $customRuleForBlanks = isset($ruleSet['customRuleForBlanks']) ? $ruleSet['customRuleForBlanks'] : FALSE; + + if (!$customRuleForBlanks) { + // Blank cells are always ignored, so return a FALSE + if (($cellValue == '') || ($cellValue === NULL)) { + return FALSE; + } + } + $returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); + foreach($dataSet as $rule) { + if (is_numeric($rule['value'])) { + // Numeric values are tested using the appropriate operator + switch ($rule['operator']) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : + $retVal = ($cellValue == $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : + $retVal = ($cellValue != $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN : + $retVal = ($cellValue > $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL : + $retVal = ($cellValue >= $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN : + $retVal = ($cellValue < $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL : + $retVal = ($cellValue <= $rule['value']); + break; + } + } elseif($rule['value'] == '') { + switch ($rule['operator']) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : + $retVal = (($cellValue == '') || ($cellValue === NULL)); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : + $retVal = (($cellValue != '') && ($cellValue !== NULL)); + break; + default : + $retVal = TRUE; + break; + } + } else { + // String values are always tested for equality, factoring in for wildcards (hence a regexp test) + $retVal = preg_match('/^'.$rule['value'].'$/i',$cellValue); + } + // If there are multiple conditions, then we need to test both using the appropriate join operator + switch ($join) { + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR : + $returnVal = $returnVal || $retVal; + // Break as soon as we have a TRUE match for OR joins, + // to avoid unnecessary additional code execution + if ($returnVal) + return $returnVal; + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND : + $returnVal = $returnVal && $retVal; + break; + } + } + + return $returnVal; + } + + /** + * Test if cell date value is matches a set of values defined by a set of months + * + * @param mixed $cellValue + * @param mixed[] $monthSet + * @return boolean + */ + private static function _filterTestInPeriodDateSet($cellValue, $monthSet) + { + // Blank cells are always ignored, so return a FALSE + if (($cellValue == '') || ($cellValue === NULL)) { + return FALSE; + } + + if (is_numeric($cellValue)) { + $dateValue = date('m',PHPExcel_Shared_Date::ExcelToPHP($cellValue)); + if (in_array($dateValue,$monthSet)) { + return TRUE; + } + } + + return FALSE; + } + + /** + * Search/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching + * + * @var array + */ + private static $_fromReplace = array('\*', '\?', '~~', '~.*', '~.?'); + private static $_toReplace = array('.*', '.', '~', '\*', '\?'); + + + /** + * Convert a dynamic rule daterange to a custom filter range expression for ease of calculation + * + * @param string $dynamicRuleType + * @param PHPExcel_Worksheet_AutoFilter_Column &$filterColumn + * @return mixed[] + */ + private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) + { + $rDateType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $val = $maxVal = NULL; + + $ruleValues = array(); + $baseDate = PHPExcel_Calculation_DateTime::DATENOW(); + // Calculate start/end dates for the required date range based on current date + switch ($dynamicRuleType) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : + $baseDate = strtotime('-7 days',$baseDate); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : + $baseDate = strtotime('-7 days',$baseDate); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : + $baseDate = strtotime('-1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : + $baseDate = strtotime('+1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : + $baseDate = strtotime('-3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : + $baseDate = strtotime('+3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : + $baseDate = strtotime('-1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : + $baseDate = strtotime('+1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + } + + switch ($dynamicRuleType) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); + $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE : + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : + $maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,31,12,date('Y',$baseDate))); + ++$maxVal; + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : + $thisMonth = date('m',$baseDate); + $thisQuarter = floor(--$thisMonth / 3); + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),(1+$thisQuarter)*3,date('Y',$baseDate))); + ++$maxVal; + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1+$thisQuarter*3,date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),date('m',$baseDate),date('Y',$baseDate))); + ++$maxVal; + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : + $dayOfWeek = date('w',$baseDate); + $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate) - $dayOfWeek; + $maxVal = $val + 7; + break; + } + + switch ($dynamicRuleType) { + // Adjust Today dates for Yesterday and Tomorrow + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : + --$maxVal; + --$val; + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : + ++$maxVal; + ++$val; + break; + } + + // Set the filter column rule attributes ready for writing + $filterColumn->setAttributes(array( 'val' => $val, + 'maxVal' => $maxVal + ) + ); + + // Set the rules for identifying rows for hide/show + $ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, + 'value' => $val + ); + $ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, + 'value' => $maxVal + ); + PHPExcel_Calculation_Functions::setReturnDateType($rDateType); + + return array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND + ) + ); + } + + private function _calculateTopTenValue($columnID,$startRow,$endRow,$ruleType,$ruleValue) { + $range = $columnID.$startRow.':'.$columnID.$endRow; + $dataValues = PHPExcel_Calculation_Functions::flattenArray( + $this->_workSheet->rangeToArray($range,NULL,TRUE,FALSE) + ); + + $dataValues = array_filter($dataValues); + if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) { + rsort($dataValues); + } else { + sort($dataValues); + } + + return array_pop(array_slice($dataValues,0,$ruleValue)); + } + + /** + * Apply the AutoFilter rules to the AutoFilter Range + * + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function showHideRows() + { + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + + // The heading row should always be visible +// echo 'AutoFilter Heading Row ',$rangeStart[1],' is always SHOWN',PHP_EOL; + $this->_workSheet->getRowDimension($rangeStart[1])->setVisible(TRUE); + + $columnFilterTests = array(); + foreach($this->_columns as $columnID => $filterColumn) { + $rules = $filterColumn->getRules(); + switch ($filterColumn->getFilterType()) { + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER : + $ruleValues = array(); + // Build a list of the filter value selections + foreach($rules as $rule) { + $ruleType = $rule->getRuleType(); + $ruleValues[] = $rule->getValue(); + } + // Test if we want to include blanks in our filter criteria + $blanks = FALSE; + $ruleDataSet = array_filter($ruleValues); + if (count($ruleValues) != count($ruleDataSet)) + $blanks = TRUE; + if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) { + // Filter on absolute values + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInSimpleDataSet', + 'arguments' => array( 'filterValues' => $ruleDataSet, + 'blanks' => $blanks + ) + ); + } else { + // Filter on date group values + $arguments = array( 'date' => array(), 'time' => array(), 'dateTime' => array(), ); - foreach($ruleDataSet as $ruleValue) { - $date = $time = ''; - if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')) - $date .= sprintf('%04d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]); - if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')) - $date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]); - if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')) - $date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]); - if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')) - $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]); - if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')) - $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]); - if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')) - $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]); - $dateTime = $date . $time; - $arguments['date'][] = $date; - $arguments['time'][] = $time; - $arguments['dateTime'][] = $dateTime; - } - // Remove empty elements - $arguments['date'] = array_filter($arguments['date']); - $arguments['time'] = array_filter($arguments['time']); - $arguments['dateTime'] = array_filter($arguments['dateTime']); - $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInDateGroupSet', - 'arguments' => array( 'filterValues' => $arguments, - 'blanks' => $blanks - ) - ); - } - break; - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER : - $customRuleForBlanks = FALSE; - $ruleValues = array(); - // Build a list of the filter value selections - foreach($rules as $rule) { - $ruleType = $rule->getRuleType(); - $ruleValue = $rule->getValue(); - if (!is_numeric($ruleValue)) { - // Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards - $ruleValue = preg_quote($ruleValue); - $ruleValue = str_replace(self::$_fromReplace,self::$_toReplace,$ruleValue); - if (trim($ruleValue) == '') { - $customRuleForBlanks = TRUE; - $ruleValue = trim($ruleValue); - } - } - $ruleValues[] = array( 'operator' => $rule->getOperator(), - 'value' => $ruleValue - ); - } - $join = $filterColumn->getJoin(); - $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInCustomDataSet', - 'arguments' => array( 'filterRules' => $ruleValues, - 'join' => $join, - 'customRuleForBlanks' => $customRuleForBlanks - ) - ); - break; - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER : - $ruleValues = array(); - foreach($rules as $rule) { - // We should only ever have one Dynamic Filter Rule anyway - $dynamicRuleType = $rule->getGrouping(); - if (($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) || - ($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE)) { - // Number (Average) based - // Calculate the average - $averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')'; - $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,NULL,$this->_workSheet->getCell('A1')); - // Set above/below rule based on greaterThan or LessTan - $operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) - ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN - : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN; - $ruleValues[] = array( 'operator' => $operator, - 'value' => $average - ); - $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInCustomDataSet', - 'arguments' => array( 'filterRules' => $ruleValues, - 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR - ) - ); - } else { - // Date based - if ($dynamicRuleType{0} == 'M' || $dynamicRuleType{0} == 'Q') { - // Month or Quarter - sscanf($dynamicRuleType,'%[A-Z]%d', $periodType, $period); - if ($periodType == 'M') { - $ruleValues = array($period); - } else { - --$period; - $periodEnd = (1+$period)*3; - $periodStart = 1+$period*3; - $ruleValues = range($periodStart,periodEnd); - } - $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInPeriodDateSet', - 'arguments' => $ruleValues - ); - $filterColumn->setAttributes(array()); - } else { - // Date Range - $columnFilterTests[$columnID] = $this->_dynamicFilterDateRange($dynamicRuleType, $filterColumn); - break; - } - } - } - break; - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER : - $ruleValues = array(); - $dataRowCount = $rangeEnd[1] - $rangeStart[1]; - foreach($rules as $rule) { - // We should only ever have one Dynamic Filter Rule anyway - $toptenRuleType = $rule->getGrouping(); - $ruleValue = $rule->getValue(); - $ruleOperator = $rule->getOperator(); - } - if ($ruleOperator === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) { - $ruleValue = floor($ruleValue * ($dataRowCount / 100)); - } - if ($ruleValue < 1) $ruleValue = 1; - if ($ruleValue > 500) $ruleValue = 500; - - $maxVal = $this->_calculateTopTenValue($columnID,$rangeStart[1]+1,$rangeEnd[1],$toptenRuleType,$ruleValue); - - $operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) - ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL - : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL; - $ruleValues[] = array( 'operator' => $operator, - 'value' => $maxVal - ); - $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInCustomDataSet', - 'arguments' => array( 'filterRules' => $ruleValues, - 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR - ) - ); - $filterColumn->setAttributes( - array('maxVal' => $maxVal) - ); - break; - } - } - -// echo 'Column Filter Test CRITERIA',PHP_EOL; -// var_dump($columnFilterTests); + foreach($ruleDataSet as $ruleValue) { + $date = $time = ''; + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')) + $date .= sprintf('%04d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')) + $date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')) + $date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')) + $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')) + $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')) + $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]); + $dateTime = $date . $time; + $arguments['date'][] = $date; + $arguments['time'][] = $time; + $arguments['dateTime'][] = $dateTime; + } + // Remove empty elements + $arguments['date'] = array_filter($arguments['date']); + $arguments['time'] = array_filter($arguments['time']); + $arguments['dateTime'] = array_filter($arguments['dateTime']); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInDateGroupSet', + 'arguments' => array( 'filterValues' => $arguments, + 'blanks' => $blanks + ) + ); + } + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER : + $customRuleForBlanks = FALSE; + $ruleValues = array(); + // Build a list of the filter value selections + foreach($rules as $rule) { + $ruleType = $rule->getRuleType(); + $ruleValue = $rule->getValue(); + if (!is_numeric($ruleValue)) { + // Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards + $ruleValue = preg_quote($ruleValue); + $ruleValue = str_replace(self::$_fromReplace,self::$_toReplace,$ruleValue); + if (trim($ruleValue) == '') { + $customRuleForBlanks = TRUE; + $ruleValue = trim($ruleValue); + } + } + $ruleValues[] = array( 'operator' => $rule->getOperator(), + 'value' => $ruleValue + ); + } + $join = $filterColumn->getJoin(); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => $join, + 'customRuleForBlanks' => $customRuleForBlanks + ) + ); + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER : + $ruleValues = array(); + foreach($rules as $rule) { + // We should only ever have one Dynamic Filter Rule anyway + $dynamicRuleType = $rule->getGrouping(); + if (($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) || + ($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE)) { + // Number (Average) based + // Calculate the average + $averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')'; + $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,NULL,$this->_workSheet->getCell('A1')); + // Set above/below rule based on greaterThan or LessTan + $operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN; + $ruleValues[] = array( 'operator' => $operator, + 'value' => $average + ); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR + ) + ); + } else { + // Date based + if ($dynamicRuleType{0} == 'M' || $dynamicRuleType{0} == 'Q') { + // Month or Quarter + sscanf($dynamicRuleType,'%[A-Z]%d', $periodType, $period); + if ($periodType == 'M') { + $ruleValues = array($period); + } else { + --$period; + $periodEnd = (1+$period)*3; + $periodStart = 1+$period*3; + $ruleValues = range($periodStart,periodEnd); + } + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInPeriodDateSet', + 'arguments' => $ruleValues + ); + $filterColumn->setAttributes(array()); + } else { + // Date Range + $columnFilterTests[$columnID] = $this->_dynamicFilterDateRange($dynamicRuleType, $filterColumn); + break; + } + } + } + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER : + $ruleValues = array(); + $dataRowCount = $rangeEnd[1] - $rangeStart[1]; + foreach($rules as $rule) { + // We should only ever have one Dynamic Filter Rule anyway + $toptenRuleType = $rule->getGrouping(); + $ruleValue = $rule->getValue(); + $ruleOperator = $rule->getOperator(); + } + if ($ruleOperator === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) { + $ruleValue = floor($ruleValue * ($dataRowCount / 100)); + } + if ($ruleValue < 1) $ruleValue = 1; + if ($ruleValue > 500) $ruleValue = 500; + + $maxVal = $this->_calculateTopTenValue($columnID,$rangeStart[1]+1,$rangeEnd[1],$toptenRuleType,$ruleValue); + + $operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL; + $ruleValues[] = array( 'operator' => $operator, + 'value' => $maxVal + ); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR + ) + ); + $filterColumn->setAttributes( + array('maxVal' => $maxVal) + ); + break; + } + } + +// echo 'Column Filter Test CRITERIA',PHP_EOL; +// var_dump($columnFilterTests); // - // Execute the column tests for each row in the autoFilter range to determine show/hide, - for ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) { -// echo 'Testing Row = ',$row,PHP_EOL; - $result = TRUE; - foreach($columnFilterTests as $columnID => $columnFilterTest) { -// echo 'Testing cell ',$columnID.$row,PHP_EOL; - $cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue(); -// echo 'Value is ',$cellValue,PHP_EOL; - // Execute the filter test - $result = $result && - call_user_func_array( - array('PHPExcel_Worksheet_AutoFilter',$columnFilterTest['method']), - array( - $cellValue, - $columnFilterTest['arguments'] - ) - ); -// echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL; - // If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests - if (!$result) - break; - } - // Set show/hide for the row based on the result of the autoFilter result -// echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL; - $this->_workSheet->getRowDimension($row)->setVisible($result); - } - - return $this; - } - - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - if ($key == '_workSheet') { - // Detach from worksheet - $this->{$key} = NULL; - } else { - $this->{$key} = clone $value; - } - } elseif ((is_array($value)) && ($key == '_columns')) { - // The columns array of PHPExcel_Worksheet_AutoFilter objects - $this->{$key} = array(); - foreach ($value as $k => $v) { - $this->{$key}[$k] = clone $v; - // attach the new cloned Column to this new cloned Autofilter object - $this->{$key}[$k]->setParent($this); - } - } else { - $this->{$key} = $value; - } - } - } - - /** - * toString method replicates previous behavior by returning the range if object is - * referenced as a property of its parent. - */ - public function __toString() { - return (string) $this->_range; - } + // Execute the column tests for each row in the autoFilter range to determine show/hide, + for ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) { +// echo 'Testing Row = ',$row,PHP_EOL; + $result = TRUE; + foreach($columnFilterTests as $columnID => $columnFilterTest) { +// echo 'Testing cell ',$columnID.$row,PHP_EOL; + $cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue(); +// echo 'Value is ',$cellValue,PHP_EOL; + // Execute the filter test + $result = $result && + call_user_func_array( + array('PHPExcel_Worksheet_AutoFilter',$columnFilterTest['method']), + array( + $cellValue, + $columnFilterTest['arguments'] + ) + ); +// echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL; + // If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests + if (!$result) + break; + } + // Set show/hide for the row based on the result of the autoFilter result +// echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL; + $this->_workSheet->getRowDimension($row)->setVisible($result); + } + + return $this; + } + + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + if ($key == '_workSheet') { + // Detach from worksheet + $this->{$key} = NULL; + } else { + $this->{$key} = clone $value; + } + } elseif ((is_array($value)) && ($key == '_columns')) { + // The columns array of PHPExcel_Worksheet_AutoFilter objects + $this->{$key} = array(); + foreach ($value as $k => $v) { + $this->{$key}[$k] = clone $v; + // attach the new cloned Column to this new cloned Autofilter object + $this->{$key}[$k]->setParent($this); + } + } else { + $this->{$key} = $value; + } + } + } + + /** + * toString method replicates previous behavior by returning the range if object is + * referenced as a property of its parent. + */ + public function __toString() { + return (string) $this->_range; + } } diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php index e2ea1bb3e..577f8db50 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php @@ -18,377 +18,377 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** * PHPExcel_Worksheet_AutoFilter_Column * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_AutoFilter_Column { - const AUTOFILTER_FILTERTYPE_FILTER = 'filters'; - const AUTOFILTER_FILTERTYPE_CUSTOMFILTER = 'customFilters'; - // Supports no more than 2 rules, with an And/Or join criteria - // if more than 1 rule is defined - const AUTOFILTER_FILTERTYPE_DYNAMICFILTER = 'dynamicFilter'; - // Even though the filter rule is constant, the filtered data can vary - // e.g. filtered by date = TODAY - const AUTOFILTER_FILTERTYPE_TOPTENFILTER = 'top10'; - - /** - * Types of autofilter rules - * - * @var string[] - */ - private static $_filterTypes = array( - // Currently we're not handling - // colorFilter - // extLst - // iconFilter - self::AUTOFILTER_FILTERTYPE_FILTER, - self::AUTOFILTER_FILTERTYPE_CUSTOMFILTER, - self::AUTOFILTER_FILTERTYPE_DYNAMICFILTER, - self::AUTOFILTER_FILTERTYPE_TOPTENFILTER, - ); - - /* Multiple Rule Connections */ - const AUTOFILTER_COLUMN_JOIN_AND = 'and'; - const AUTOFILTER_COLUMN_JOIN_OR = 'or'; - - /** - * Join options for autofilter rules - * - * @var string[] - */ - private static $_ruleJoins = array( - self::AUTOFILTER_COLUMN_JOIN_AND, - self::AUTOFILTER_COLUMN_JOIN_OR, - ); - - /** - * Autofilter - * - * @var PHPExcel_Worksheet_AutoFilter - */ - private $_parent = NULL; - - - /** - * Autofilter Column Index - * - * @var string - */ - private $_columnIndex = ''; - - - /** - * Autofilter Column Filter Type - * - * @var string - */ - private $_filterType = self::AUTOFILTER_FILTERTYPE_FILTER; - - - /** - * Autofilter Multiple Rules And/Or - * - * @var string - */ - private $_join = self::AUTOFILTER_COLUMN_JOIN_OR; - - - /** - * Autofilter Column Rules - * - * @var array of PHPExcel_Worksheet_AutoFilter_Column_Rule - */ - private $_ruleset = array(); - - - /** - * Autofilter Column Dynamic Attributes - * - * @var array of mixed - */ - private $_attributes = array(); - - - /** - * Create a new PHPExcel_Worksheet_AutoFilter_Column - * - * @param string $pColumn Column (e.g. A) - * @param PHPExcel_Worksheet_AutoFilter $pParent Autofilter for this column - */ - public function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = NULL) - { - $this->_columnIndex = $pColumn; - $this->_parent = $pParent; - } - - /** - * Get AutoFilter Column Index - * - * @return string - */ - public function getColumnIndex() { - return $this->_columnIndex; - } - - /** - * Set AutoFilter Column Index - * - * @param string $pColumn Column (e.g. A) - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function setColumnIndex($pColumn) { - // Uppercase coordinate - $pColumn = strtoupper($pColumn); - if ($this->_parent !== NULL) { - $this->_parent->testColumnInRange($pColumn); - } - - $this->_columnIndex = $pColumn; - - return $this; - } - - /** - * Get this Column's AutoFilter Parent - * - * @return PHPExcel_Worksheet_AutoFilter - */ - public function getParent() { - return $this->_parent; - } - - /** - * Set this Column's AutoFilter Parent - * - * @param PHPExcel_Worksheet_AutoFilter - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = NULL) { - $this->_parent = $pParent; - - return $this; - } - - /** - * Get AutoFilter Type - * - * @return string - */ - public function getFilterType() { - return $this->_filterType; - } - - /** - * Set AutoFilter Type - * - * @param string $pFilterType - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER) { - if (!in_array($pFilterType,self::$_filterTypes)) { - throw new PHPExcel_Exception('Invalid filter type for column AutoFilter.'); - } - - $this->_filterType = $pFilterType; - - return $this; - } - - /** - * Get AutoFilter Multiple Rules And/Or Join - * - * @return string - */ - public function getJoin() { - return $this->_join; - } - - /** - * Set AutoFilter Multiple Rules And/Or - * - * @param string $pJoin And/Or - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR) { - // Lowercase And/Or - $pJoin = strtolower($pJoin); - if (!in_array($pJoin,self::$_ruleJoins)) { - throw new PHPExcel_Exception('Invalid rule connection for column AutoFilter.'); - } - - $this->_join = $pJoin; - - return $this; - } - - /** - * Set AutoFilter Attributes - * - * @param string[] $pAttributes - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function setAttributes($pAttributes = array()) { - $this->_attributes = $pAttributes; - - return $this; - } - - /** - * Set An AutoFilter Attribute - * - * @param string $pName Attribute Name - * @param string $pValue Attribute Value - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function setAttribute($pName, $pValue) { - $this->_attributes[$pName] = $pValue; - - return $this; - } - - /** - * Get AutoFilter Column Attributes - * - * @return string - */ - public function getAttributes() { - return $this->_attributes; - } - - /** - * Get specific AutoFilter Column Attribute - * - * @param string $pName Attribute Name - * @return string - */ - public function getAttribute($pName) { - if (isset($this->_attributes[$pName])) - return $this->_attributes[$pName]; - return NULL; - } - - /** - * Get all AutoFilter Column Rules - * - * @throws PHPExcel_Exception - * @return array of PHPExcel_Worksheet_AutoFilter_Column_Rule - */ - public function getRules() { - return $this->_ruleset; - } - - /** - * Get a specified AutoFilter Column Rule - * - * @param integer $pIndex Rule index in the ruleset array - * @return PHPExcel_Worksheet_AutoFilter_Column_Rule - */ - public function getRule($pIndex) { - if (!isset($this->_ruleset[$pIndex])) { - $this->_ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); - } - return $this->_ruleset[$pIndex]; - } - - /** - * Create a new AutoFilter Column Rule in the ruleset - * - * @return PHPExcel_Worksheet_AutoFilter_Column_Rule - */ - public function createRule() { - $this->_ruleset[] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); - - return end($this->_ruleset); - } - - /** - * Add a new AutoFilter Column Rule to the ruleset - * - * @param PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule - * @param boolean $returnRule Flag indicating whether the rule object or the column object should be returned - * @return PHPExcel_Worksheet_AutoFilter_Column|PHPExcel_Worksheet_AutoFilter_Column_Rule - */ - public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $returnRule=TRUE) { - $pRule->setParent($this); - $this->_ruleset[] = $pRule; - - return ($returnRule) ? $pRule : $this; - } - - /** - * Delete a specified AutoFilter Column Rule - * If the number of rules is reduced to 1, then we reset And/Or logic to Or - * - * @param integer $pIndex Rule index in the ruleset array - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function deleteRule($pIndex) { - if (isset($this->_ruleset[$pIndex])) { - unset($this->_ruleset[$pIndex]); - // If we've just deleted down to a single rule, then reset And/Or joining to Or - if (count($this->_ruleset) <= 1) { - $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); - } - } - - return $this; - } - - /** - * Delete all AutoFilter Column Rules - * - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function clearRules() { - $this->_ruleset = array(); - $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); - - return $this; - } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - if ($key == '_parent') { - // Detach from autofilter parent - $this->$key = NULL; - } else { - $this->$key = clone $value; - } - } elseif ((is_array($value)) && ($key == '_ruleset')) { - // The columns array of PHPExcel_Worksheet_AutoFilter objects - $this->$key = array(); - foreach ($value as $k => $v) { - $this->$key[$k] = clone $v; - // attach the new cloned Rule to this new cloned Autofilter Cloned object - $this->$key[$k]->setParent($this); - } - } else { - $this->$key = $value; - } - } - } + const AUTOFILTER_FILTERTYPE_FILTER = 'filters'; + const AUTOFILTER_FILTERTYPE_CUSTOMFILTER = 'customFilters'; + // Supports no more than 2 rules, with an And/Or join criteria + // if more than 1 rule is defined + const AUTOFILTER_FILTERTYPE_DYNAMICFILTER = 'dynamicFilter'; + // Even though the filter rule is constant, the filtered data can vary + // e.g. filtered by date = TODAY + const AUTOFILTER_FILTERTYPE_TOPTENFILTER = 'top10'; + + /** + * Types of autofilter rules + * + * @var string[] + */ + private static $_filterTypes = array( + // Currently we're not handling + // colorFilter + // extLst + // iconFilter + self::AUTOFILTER_FILTERTYPE_FILTER, + self::AUTOFILTER_FILTERTYPE_CUSTOMFILTER, + self::AUTOFILTER_FILTERTYPE_DYNAMICFILTER, + self::AUTOFILTER_FILTERTYPE_TOPTENFILTER, + ); + + /* Multiple Rule Connections */ + const AUTOFILTER_COLUMN_JOIN_AND = 'and'; + const AUTOFILTER_COLUMN_JOIN_OR = 'or'; + + /** + * Join options for autofilter rules + * + * @var string[] + */ + private static $_ruleJoins = array( + self::AUTOFILTER_COLUMN_JOIN_AND, + self::AUTOFILTER_COLUMN_JOIN_OR, + ); + + /** + * Autofilter + * + * @var PHPExcel_Worksheet_AutoFilter + */ + private $_parent = NULL; + + + /** + * Autofilter Column Index + * + * @var string + */ + private $_columnIndex = ''; + + + /** + * Autofilter Column Filter Type + * + * @var string + */ + private $_filterType = self::AUTOFILTER_FILTERTYPE_FILTER; + + + /** + * Autofilter Multiple Rules And/Or + * + * @var string + */ + private $_join = self::AUTOFILTER_COLUMN_JOIN_OR; + + + /** + * Autofilter Column Rules + * + * @var array of PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + private $_ruleset = array(); + + + /** + * Autofilter Column Dynamic Attributes + * + * @var array of mixed + */ + private $_attributes = array(); + + + /** + * Create a new PHPExcel_Worksheet_AutoFilter_Column + * + * @param string $pColumn Column (e.g. A) + * @param PHPExcel_Worksheet_AutoFilter $pParent Autofilter for this column + */ + public function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = NULL) + { + $this->_columnIndex = $pColumn; + $this->_parent = $pParent; + } + + /** + * Get AutoFilter Column Index + * + * @return string + */ + public function getColumnIndex() { + return $this->_columnIndex; + } + + /** + * Set AutoFilter Column Index + * + * @param string $pColumn Column (e.g. A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setColumnIndex($pColumn) { + // Uppercase coordinate + $pColumn = strtoupper($pColumn); + if ($this->_parent !== NULL) { + $this->_parent->testColumnInRange($pColumn); + } + + $this->_columnIndex = $pColumn; + + return $this; + } + + /** + * Get this Column's AutoFilter Parent + * + * @return PHPExcel_Worksheet_AutoFilter + */ + public function getParent() { + return $this->_parent; + } + + /** + * Set this Column's AutoFilter Parent + * + * @param PHPExcel_Worksheet_AutoFilter + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = NULL) { + $this->_parent = $pParent; + + return $this; + } + + /** + * Get AutoFilter Type + * + * @return string + */ + public function getFilterType() { + return $this->_filterType; + } + + /** + * Set AutoFilter Type + * + * @param string $pFilterType + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER) { + if (!in_array($pFilterType,self::$_filterTypes)) { + throw new PHPExcel_Exception('Invalid filter type for column AutoFilter.'); + } + + $this->_filterType = $pFilterType; + + return $this; + } + + /** + * Get AutoFilter Multiple Rules And/Or Join + * + * @return string + */ + public function getJoin() { + return $this->_join; + } + + /** + * Set AutoFilter Multiple Rules And/Or + * + * @param string $pJoin And/Or + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR) { + // Lowercase And/Or + $pJoin = strtolower($pJoin); + if (!in_array($pJoin,self::$_ruleJoins)) { + throw new PHPExcel_Exception('Invalid rule connection for column AutoFilter.'); + } + + $this->_join = $pJoin; + + return $this; + } + + /** + * Set AutoFilter Attributes + * + * @param string[] $pAttributes + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setAttributes($pAttributes = array()) { + $this->_attributes = $pAttributes; + + return $this; + } + + /** + * Set An AutoFilter Attribute + * + * @param string $pName Attribute Name + * @param string $pValue Attribute Value + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setAttribute($pName, $pValue) { + $this->_attributes[$pName] = $pValue; + + return $this; + } + + /** + * Get AutoFilter Column Attributes + * + * @return string + */ + public function getAttributes() { + return $this->_attributes; + } + + /** + * Get specific AutoFilter Column Attribute + * + * @param string $pName Attribute Name + * @return string + */ + public function getAttribute($pName) { + if (isset($this->_attributes[$pName])) + return $this->_attributes[$pName]; + return NULL; + } + + /** + * Get all AutoFilter Column Rules + * + * @throws PHPExcel_Exception + * @return array of PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function getRules() { + return $this->_ruleset; + } + + /** + * Get a specified AutoFilter Column Rule + * + * @param integer $pIndex Rule index in the ruleset array + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function getRule($pIndex) { + if (!isset($this->_ruleset[$pIndex])) { + $this->_ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); + } + return $this->_ruleset[$pIndex]; + } + + /** + * Create a new AutoFilter Column Rule in the ruleset + * + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function createRule() { + $this->_ruleset[] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); + + return end($this->_ruleset); + } + + /** + * Add a new AutoFilter Column Rule to the ruleset + * + * @param PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule + * @param boolean $returnRule Flag indicating whether the rule object or the column object should be returned + * @return PHPExcel_Worksheet_AutoFilter_Column|PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $returnRule=TRUE) { + $pRule->setParent($this); + $this->_ruleset[] = $pRule; + + return ($returnRule) ? $pRule : $this; + } + + /** + * Delete a specified AutoFilter Column Rule + * If the number of rules is reduced to 1, then we reset And/Or logic to Or + * + * @param integer $pIndex Rule index in the ruleset array + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function deleteRule($pIndex) { + if (isset($this->_ruleset[$pIndex])) { + unset($this->_ruleset[$pIndex]); + // If we've just deleted down to a single rule, then reset And/Or joining to Or + if (count($this->_ruleset) <= 1) { + $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); + } + } + + return $this; + } + + /** + * Delete all AutoFilter Column Rules + * + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function clearRules() { + $this->_ruleset = array(); + $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); + + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + if ($key == '_parent') { + // Detach from autofilter parent + $this->$key = NULL; + } else { + $this->$key = clone $value; + } + } elseif ((is_array($value)) && ($key == '_ruleset')) { + // The columns array of PHPExcel_Worksheet_AutoFilter objects + $this->$key = array(); + foreach ($value as $k => $v) { + $this->$key[$k] = clone $v; + // attach the new cloned Rule to this new cloned Autofilter Cloned object + $this->$key[$k]->setParent($this); + } + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php index eb9f71ff4..98c4630c0 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -18,447 +18,447 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** * PHPExcel_Worksheet_AutoFilter_Column_Rule * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_AutoFilter_Column_Rule { - const AUTOFILTER_RULETYPE_FILTER = 'filter'; - const AUTOFILTER_RULETYPE_DATEGROUP = 'dateGroupItem'; - const AUTOFILTER_RULETYPE_CUSTOMFILTER = 'customFilter'; - const AUTOFILTER_RULETYPE_DYNAMICFILTER = 'dynamicFilter'; - const AUTOFILTER_RULETYPE_TOPTENFILTER = 'top10Filter'; - - private static $_ruleTypes = array( - // Currently we're not handling - // colorFilter - // extLst - // iconFilter - self::AUTOFILTER_RULETYPE_FILTER, - self::AUTOFILTER_RULETYPE_DATEGROUP, - self::AUTOFILTER_RULETYPE_CUSTOMFILTER, - self::AUTOFILTER_RULETYPE_DYNAMICFILTER, - self::AUTOFILTER_RULETYPE_TOPTENFILTER, - ); - - const AUTOFILTER_RULETYPE_DATEGROUP_YEAR = 'year'; - const AUTOFILTER_RULETYPE_DATEGROUP_MONTH = 'month'; - const AUTOFILTER_RULETYPE_DATEGROUP_DAY = 'day'; - const AUTOFILTER_RULETYPE_DATEGROUP_HOUR = 'hour'; - const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE = 'minute'; - const AUTOFILTER_RULETYPE_DATEGROUP_SECOND = 'second'; - - private static $_dateTimeGroups = array( - self::AUTOFILTER_RULETYPE_DATEGROUP_YEAR, - self::AUTOFILTER_RULETYPE_DATEGROUP_MONTH, - self::AUTOFILTER_RULETYPE_DATEGROUP_DAY, - self::AUTOFILTER_RULETYPE_DATEGROUP_HOUR, - self::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE, - self::AUTOFILTER_RULETYPE_DATEGROUP_SECOND, - ); - - const AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY = 'yesterday'; - const AUTOFILTER_RULETYPE_DYNAMIC_TODAY = 'today'; - const AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW = 'tomorrow'; - const AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE = 'yearToDate'; - const AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR = 'thisYear'; - const AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER = 'thisQuarter'; - const AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH = 'thisMonth'; - const AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK = 'thisWeek'; - const AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR = 'lastYear'; - const AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER = 'lastQuarter'; - const AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH = 'lastMonth'; - const AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK = 'lastWeek'; - const AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR = 'nextYear'; - const AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER = 'nextQuarter'; - const AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH = 'nextMonth'; - const AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK = 'nextWeek'; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1 = 'M1'; - const AUTOFILTER_RULETYPE_DYNAMIC_JANUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2 = 'M2'; - const AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3 = 'M3'; - const AUTOFILTER_RULETYPE_DYNAMIC_MARCH = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4 = 'M4'; - const AUTOFILTER_RULETYPE_DYNAMIC_APRIL = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5 = 'M5'; - const AUTOFILTER_RULETYPE_DYNAMIC_MAY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6 = 'M6'; - const AUTOFILTER_RULETYPE_DYNAMIC_JUNE = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7 = 'M7'; - const AUTOFILTER_RULETYPE_DYNAMIC_JULY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8 = 'M8'; - const AUTOFILTER_RULETYPE_DYNAMIC_AUGUST = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9 = 'M9'; - const AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10 = 'M10'; - const AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11 = 'M11'; - const AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12 = 'M12'; - const AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12; - const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1 = 'Q1'; - const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2 = 'Q2'; - const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3 = 'Q3'; - const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4 = 'Q4'; - const AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE = 'aboveAverage'; - const AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE = 'belowAverage'; - - private static $_dynamicTypes = array( - self::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY, - self::AUTOFILTER_RULETYPE_DYNAMIC_TODAY, - self::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW, - self::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE, - self::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR, - self::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER, - self::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH, - self::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK, - self::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR, - self::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER, - self::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH, - self::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK, - self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR, - self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER, - self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH, - self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11, - self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12, - self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1, - self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2, - self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3, - self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4, - self::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE, - self::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE, - ); - - /* - * The only valid filter rule operators for filter and customFilter types are: - * <xsd:enumeration value="equal"/> - * <xsd:enumeration value="lessThan"/> - * <xsd:enumeration value="lessThanOrEqual"/> - * <xsd:enumeration value="notEqual"/> - * <xsd:enumeration value="greaterThanOrEqual"/> - * <xsd:enumeration value="greaterThan"/> - */ - const AUTOFILTER_COLUMN_RULE_EQUAL = 'equal'; - const AUTOFILTER_COLUMN_RULE_NOTEQUAL = 'notEqual'; - const AUTOFILTER_COLUMN_RULE_GREATERTHAN = 'greaterThan'; - const AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL = 'greaterThanOrEqual'; - const AUTOFILTER_COLUMN_RULE_LESSTHAN = 'lessThan'; - const AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL = 'lessThanOrEqual'; - - private static $_operators = array( - self::AUTOFILTER_COLUMN_RULE_EQUAL, - self::AUTOFILTER_COLUMN_RULE_NOTEQUAL, - self::AUTOFILTER_COLUMN_RULE_GREATERTHAN, - self::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, - self::AUTOFILTER_COLUMN_RULE_LESSTHAN, - self::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL, - ); - - const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE = 'byValue'; - const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT = 'byPercent'; - - private static $_topTenValue = array( - self::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, - self::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, - ); - - const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP = 'top'; - const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM = 'bottom'; - - private static $_topTenType = array( - self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, - self::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM, - ); - - - /* Rule Operators (Numeric, Boolean etc) */ -// const AUTOFILTER_COLUMN_RULE_BETWEEN = 'between'; // greaterThanOrEqual 1 && lessThanOrEqual 2 - /* Rule Operators (Numeric Special) which are translated to standard numeric operators with calculated values */ -// const AUTOFILTER_COLUMN_RULE_TOPTEN = 'topTen'; // greaterThan calculated value -// const AUTOFILTER_COLUMN_RULE_TOPTENPERCENT = 'topTenPercent'; // greaterThan calculated value -// const AUTOFILTER_COLUMN_RULE_ABOVEAVERAGE = 'aboveAverage'; // Value is calculated as the average -// const AUTOFILTER_COLUMN_RULE_BELOWAVERAGE = 'belowAverage'; // Value is calculated as the average - /* Rule Operators (String) which are set as wild-carded values */ -// const AUTOFILTER_COLUMN_RULE_BEGINSWITH = 'beginsWith'; // A* -// const AUTOFILTER_COLUMN_RULE_ENDSWITH = 'endsWith'; // *Z -// const AUTOFILTER_COLUMN_RULE_CONTAINS = 'contains'; // *B* -// const AUTOFILTER_COLUMN_RULE_DOESNTCONTAIN = 'notEqual'; // notEqual *B* - /* Rule Operators (Date Special) which are translated to standard numeric operators with calculated values */ -// const AUTOFILTER_COLUMN_RULE_BEFORE = 'lessThan'; -// const AUTOFILTER_COLUMN_RULE_AFTER = 'greaterThan'; -// const AUTOFILTER_COLUMN_RULE_YESTERDAY = 'yesterday'; -// const AUTOFILTER_COLUMN_RULE_TODAY = 'today'; -// const AUTOFILTER_COLUMN_RULE_TOMORROW = 'tomorrow'; -// const AUTOFILTER_COLUMN_RULE_LASTWEEK = 'lastWeek'; -// const AUTOFILTER_COLUMN_RULE_THISWEEK = 'thisWeek'; -// const AUTOFILTER_COLUMN_RULE_NEXTWEEK = 'nextWeek'; -// const AUTOFILTER_COLUMN_RULE_LASTMONTH = 'lastMonth'; -// const AUTOFILTER_COLUMN_RULE_THISMONTH = 'thisMonth'; -// const AUTOFILTER_COLUMN_RULE_NEXTMONTH = 'nextMonth'; -// const AUTOFILTER_COLUMN_RULE_LASTQUARTER = 'lastQuarter'; -// const AUTOFILTER_COLUMN_RULE_THISQUARTER = 'thisQuarter'; -// const AUTOFILTER_COLUMN_RULE_NEXTQUARTER = 'nextQuarter'; -// const AUTOFILTER_COLUMN_RULE_LASTYEAR = 'lastYear'; -// const AUTOFILTER_COLUMN_RULE_THISYEAR = 'thisYear'; -// const AUTOFILTER_COLUMN_RULE_NEXTYEAR = 'nextYear'; -// const AUTOFILTER_COLUMN_RULE_YEARTODATE = 'yearToDate'; // <dynamicFilter val="40909" type="yearToDate" maxVal="41113"/> -// const AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH = 'allDatesInMonth'; // <dynamicFilter type="M2"/> for Month/February -// const AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER = 'allDatesInQuarter'; // <dynamicFilter type="Q2"/> for Quarter 2 - - /** - * Autofilter Column - * - * @var PHPExcel_Worksheet_AutoFilter_Column - */ - private $_parent = NULL; - - - /** - * Autofilter Rule Type - * - * @var string - */ - private $_ruleType = self::AUTOFILTER_RULETYPE_FILTER; - - - /** - * Autofilter Rule Value - * - * @var string - */ - private $_value = ''; - - /** - * Autofilter Rule Operator - * - * @var string - */ - private $_operator = self::AUTOFILTER_COLUMN_RULE_EQUAL; - - /** - * DateTimeGrouping Group Value - * - * @var string - */ - private $_grouping = ''; - - - /** - * Create a new PHPExcel_Worksheet_AutoFilter_Column_Rule - * - * @param PHPExcel_Worksheet_AutoFilter_Column $pParent - */ - public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) - { - $this->_parent = $pParent; - } - - /** - * Get AutoFilter Rule Type - * - * @return string - */ - public function getRuleType() { - return $this->_ruleType; - } - - /** - * Set AutoFilter Rule Type - * - * @param string $pRuleType - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) { - if (!in_array($pRuleType,self::$_ruleTypes)) { - throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); - } - - $this->_ruleType = $pRuleType; - - return $this; - } - - /** - * Get AutoFilter Rule Value - * - * @return string - */ - public function getValue() { - return $this->_value; - } - - /** - * Set AutoFilter Rule Value - * - * @param string|string[] $pValue - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column_Rule - */ - public function setValue($pValue = '') { - if (is_array($pValue)) { - $grouping = -1; - foreach($pValue as $key => $value) { - // Validate array entries - if (!in_array($key,self::$_dateTimeGroups)) { - // Remove any invalid entries from the value array - unset($pValue[$key]); - } else { - // Work out what the dateTime grouping will be - $grouping = max($grouping,array_search($key,self::$_dateTimeGroups)); - } - } - if (count($pValue) == 0) { - throw new PHPExcel_Exception('Invalid rule value for column AutoFilter Rule.'); - } - // Set the dateTime grouping that we've anticipated - $this->setGrouping(self::$_dateTimeGroups[$grouping]); - } - $this->_value = $pValue; - - return $this; - } - - /** - * Get AutoFilter Rule Operator - * - * @return string - */ - public function getOperator() { - return $this->_operator; - } - - /** - * Set AutoFilter Rule Operator - * - * @param string $pOperator - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column_Rule - */ - public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) { - if (empty($pOperator)) - $pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL; - if ((!in_array($pOperator,self::$_operators)) && - (!in_array($pOperator,self::$_topTenValue))) { - throw new PHPExcel_Exception('Invalid operator for column AutoFilter Rule.'); - } - $this->_operator = $pOperator; - - return $this; - } - - /** - * Get AutoFilter Rule Grouping - * - * @return string - */ - public function getGrouping() { - return $this->_grouping; - } - - /** - * Set AutoFilter Rule Grouping - * - * @param string $pGrouping - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column_Rule - */ - public function setGrouping($pGrouping = NULL) { - if (($pGrouping !== NULL) && - (!in_array($pGrouping,self::$_dateTimeGroups)) && - (!in_array($pGrouping,self::$_dynamicTypes)) && - (!in_array($pGrouping,self::$_topTenType))) { - throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); - } - - $this->_grouping = $pGrouping; - - return $this; - } - - /** - * Set AutoFilter Rule - * - * @param string $pOperator - * @param string|string[] $pValue - * @param string $pGrouping - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_AutoFilter_Column_Rule - */ - public function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue = '', $pGrouping = NULL) { - $this->setOperator($pOperator); - $this->setValue($pValue); - // Only set grouping if it's been passed in as a user-supplied argument, - // otherwise we're calculating it when we setValue() and don't want to overwrite that - // If the user supplies an argumnet for grouping, then on their own head be it - if ($pGrouping !== NULL) - $this->setGrouping($pGrouping); - - return $this; - } - - /** - * Get this Rule's AutoFilter Column Parent - * - * @return PHPExcel_Worksheet_AutoFilter_Column - */ - public function getParent() { - return $this->_parent; - } - - /** - * Set this Rule's AutoFilter Column Parent - * - * @param PHPExcel_Worksheet_AutoFilter_Column - * @return PHPExcel_Worksheet_AutoFilter_Column_Rule - */ - public function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) { - $this->_parent = $pParent; - - return $this; - } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - if ($key == '_parent') { - // Detach from autofilter column parent - $this->$key = NULL; - } else { - $this->$key = clone $value; - } - } else { - $this->$key = $value; - } - } - } + const AUTOFILTER_RULETYPE_FILTER = 'filter'; + const AUTOFILTER_RULETYPE_DATEGROUP = 'dateGroupItem'; + const AUTOFILTER_RULETYPE_CUSTOMFILTER = 'customFilter'; + const AUTOFILTER_RULETYPE_DYNAMICFILTER = 'dynamicFilter'; + const AUTOFILTER_RULETYPE_TOPTENFILTER = 'top10Filter'; + + private static $_ruleTypes = array( + // Currently we're not handling + // colorFilter + // extLst + // iconFilter + self::AUTOFILTER_RULETYPE_FILTER, + self::AUTOFILTER_RULETYPE_DATEGROUP, + self::AUTOFILTER_RULETYPE_CUSTOMFILTER, + self::AUTOFILTER_RULETYPE_DYNAMICFILTER, + self::AUTOFILTER_RULETYPE_TOPTENFILTER, + ); + + const AUTOFILTER_RULETYPE_DATEGROUP_YEAR = 'year'; + const AUTOFILTER_RULETYPE_DATEGROUP_MONTH = 'month'; + const AUTOFILTER_RULETYPE_DATEGROUP_DAY = 'day'; + const AUTOFILTER_RULETYPE_DATEGROUP_HOUR = 'hour'; + const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE = 'minute'; + const AUTOFILTER_RULETYPE_DATEGROUP_SECOND = 'second'; + + private static $_dateTimeGroups = array( + self::AUTOFILTER_RULETYPE_DATEGROUP_YEAR, + self::AUTOFILTER_RULETYPE_DATEGROUP_MONTH, + self::AUTOFILTER_RULETYPE_DATEGROUP_DAY, + self::AUTOFILTER_RULETYPE_DATEGROUP_HOUR, + self::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE, + self::AUTOFILTER_RULETYPE_DATEGROUP_SECOND, + ); + + const AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY = 'yesterday'; + const AUTOFILTER_RULETYPE_DYNAMIC_TODAY = 'today'; + const AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW = 'tomorrow'; + const AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE = 'yearToDate'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR = 'thisYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER = 'thisQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH = 'thisMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK = 'thisWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR = 'lastYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER = 'lastQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH = 'lastMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK = 'lastWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR = 'nextYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER = 'nextQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH = 'nextMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK = 'nextWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1 = 'M1'; + const AUTOFILTER_RULETYPE_DYNAMIC_JANUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2 = 'M2'; + const AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3 = 'M3'; + const AUTOFILTER_RULETYPE_DYNAMIC_MARCH = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4 = 'M4'; + const AUTOFILTER_RULETYPE_DYNAMIC_APRIL = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5 = 'M5'; + const AUTOFILTER_RULETYPE_DYNAMIC_MAY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6 = 'M6'; + const AUTOFILTER_RULETYPE_DYNAMIC_JUNE = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7 = 'M7'; + const AUTOFILTER_RULETYPE_DYNAMIC_JULY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8 = 'M8'; + const AUTOFILTER_RULETYPE_DYNAMIC_AUGUST = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9 = 'M9'; + const AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10 = 'M10'; + const AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11 = 'M11'; + const AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12 = 'M12'; + const AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1 = 'Q1'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2 = 'Q2'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3 = 'Q3'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4 = 'Q4'; + const AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE = 'aboveAverage'; + const AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE = 'belowAverage'; + + private static $_dynamicTypes = array( + self::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY, + self::AUTOFILTER_RULETYPE_DYNAMIC_TODAY, + self::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW, + self::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4, + self::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE, + self::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE, + ); + + /* + * The only valid filter rule operators for filter and customFilter types are: + * <xsd:enumeration value="equal"/> + * <xsd:enumeration value="lessThan"/> + * <xsd:enumeration value="lessThanOrEqual"/> + * <xsd:enumeration value="notEqual"/> + * <xsd:enumeration value="greaterThanOrEqual"/> + * <xsd:enumeration value="greaterThan"/> + */ + const AUTOFILTER_COLUMN_RULE_EQUAL = 'equal'; + const AUTOFILTER_COLUMN_RULE_NOTEQUAL = 'notEqual'; + const AUTOFILTER_COLUMN_RULE_GREATERTHAN = 'greaterThan'; + const AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL = 'greaterThanOrEqual'; + const AUTOFILTER_COLUMN_RULE_LESSTHAN = 'lessThan'; + const AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL = 'lessThanOrEqual'; + + private static $_operators = array( + self::AUTOFILTER_COLUMN_RULE_EQUAL, + self::AUTOFILTER_COLUMN_RULE_NOTEQUAL, + self::AUTOFILTER_COLUMN_RULE_GREATERTHAN, + self::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, + self::AUTOFILTER_COLUMN_RULE_LESSTHAN, + self::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL, + ); + + const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE = 'byValue'; + const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT = 'byPercent'; + + private static $_topTenValue = array( + self::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, + self::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, + ); + + const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP = 'top'; + const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM = 'bottom'; + + private static $_topTenType = array( + self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, + self::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM, + ); + + + /* Rule Operators (Numeric, Boolean etc) */ +// const AUTOFILTER_COLUMN_RULE_BETWEEN = 'between'; // greaterThanOrEqual 1 && lessThanOrEqual 2 + /* Rule Operators (Numeric Special) which are translated to standard numeric operators with calculated values */ +// const AUTOFILTER_COLUMN_RULE_TOPTEN = 'topTen'; // greaterThan calculated value +// const AUTOFILTER_COLUMN_RULE_TOPTENPERCENT = 'topTenPercent'; // greaterThan calculated value +// const AUTOFILTER_COLUMN_RULE_ABOVEAVERAGE = 'aboveAverage'; // Value is calculated as the average +// const AUTOFILTER_COLUMN_RULE_BELOWAVERAGE = 'belowAverage'; // Value is calculated as the average + /* Rule Operators (String) which are set as wild-carded values */ +// const AUTOFILTER_COLUMN_RULE_BEGINSWITH = 'beginsWith'; // A* +// const AUTOFILTER_COLUMN_RULE_ENDSWITH = 'endsWith'; // *Z +// const AUTOFILTER_COLUMN_RULE_CONTAINS = 'contains'; // *B* +// const AUTOFILTER_COLUMN_RULE_DOESNTCONTAIN = 'notEqual'; // notEqual *B* + /* Rule Operators (Date Special) which are translated to standard numeric operators with calculated values */ +// const AUTOFILTER_COLUMN_RULE_BEFORE = 'lessThan'; +// const AUTOFILTER_COLUMN_RULE_AFTER = 'greaterThan'; +// const AUTOFILTER_COLUMN_RULE_YESTERDAY = 'yesterday'; +// const AUTOFILTER_COLUMN_RULE_TODAY = 'today'; +// const AUTOFILTER_COLUMN_RULE_TOMORROW = 'tomorrow'; +// const AUTOFILTER_COLUMN_RULE_LASTWEEK = 'lastWeek'; +// const AUTOFILTER_COLUMN_RULE_THISWEEK = 'thisWeek'; +// const AUTOFILTER_COLUMN_RULE_NEXTWEEK = 'nextWeek'; +// const AUTOFILTER_COLUMN_RULE_LASTMONTH = 'lastMonth'; +// const AUTOFILTER_COLUMN_RULE_THISMONTH = 'thisMonth'; +// const AUTOFILTER_COLUMN_RULE_NEXTMONTH = 'nextMonth'; +// const AUTOFILTER_COLUMN_RULE_LASTQUARTER = 'lastQuarter'; +// const AUTOFILTER_COLUMN_RULE_THISQUARTER = 'thisQuarter'; +// const AUTOFILTER_COLUMN_RULE_NEXTQUARTER = 'nextQuarter'; +// const AUTOFILTER_COLUMN_RULE_LASTYEAR = 'lastYear'; +// const AUTOFILTER_COLUMN_RULE_THISYEAR = 'thisYear'; +// const AUTOFILTER_COLUMN_RULE_NEXTYEAR = 'nextYear'; +// const AUTOFILTER_COLUMN_RULE_YEARTODATE = 'yearToDate'; // <dynamicFilter val="40909" type="yearToDate" maxVal="41113"/> +// const AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH = 'allDatesInMonth'; // <dynamicFilter type="M2"/> for Month/February +// const AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER = 'allDatesInQuarter'; // <dynamicFilter type="Q2"/> for Quarter 2 + + /** + * Autofilter Column + * + * @var PHPExcel_Worksheet_AutoFilter_Column + */ + private $_parent = NULL; + + + /** + * Autofilter Rule Type + * + * @var string + */ + private $_ruleType = self::AUTOFILTER_RULETYPE_FILTER; + + + /** + * Autofilter Rule Value + * + * @var string + */ + private $_value = ''; + + /** + * Autofilter Rule Operator + * + * @var string + */ + private $_operator = self::AUTOFILTER_COLUMN_RULE_EQUAL; + + /** + * DateTimeGrouping Group Value + * + * @var string + */ + private $_grouping = ''; + + + /** + * Create a new PHPExcel_Worksheet_AutoFilter_Column_Rule + * + * @param PHPExcel_Worksheet_AutoFilter_Column $pParent + */ + public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) + { + $this->_parent = $pParent; + } + + /** + * Get AutoFilter Rule Type + * + * @return string + */ + public function getRuleType() { + return $this->_ruleType; + } + + /** + * Set AutoFilter Rule Type + * + * @param string $pRuleType + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) { + if (!in_array($pRuleType,self::$_ruleTypes)) { + throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); + } + + $this->_ruleType = $pRuleType; + + return $this; + } + + /** + * Get AutoFilter Rule Value + * + * @return string + */ + public function getValue() { + return $this->_value; + } + + /** + * Set AutoFilter Rule Value + * + * @param string|string[] $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setValue($pValue = '') { + if (is_array($pValue)) { + $grouping = -1; + foreach($pValue as $key => $value) { + // Validate array entries + if (!in_array($key,self::$_dateTimeGroups)) { + // Remove any invalid entries from the value array + unset($pValue[$key]); + } else { + // Work out what the dateTime grouping will be + $grouping = max($grouping,array_search($key,self::$_dateTimeGroups)); + } + } + if (count($pValue) == 0) { + throw new PHPExcel_Exception('Invalid rule value for column AutoFilter Rule.'); + } + // Set the dateTime grouping that we've anticipated + $this->setGrouping(self::$_dateTimeGroups[$grouping]); + } + $this->_value = $pValue; + + return $this; + } + + /** + * Get AutoFilter Rule Operator + * + * @return string + */ + public function getOperator() { + return $this->_operator; + } + + /** + * Set AutoFilter Rule Operator + * + * @param string $pOperator + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) { + if (empty($pOperator)) + $pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL; + if ((!in_array($pOperator,self::$_operators)) && + (!in_array($pOperator,self::$_topTenValue))) { + throw new PHPExcel_Exception('Invalid operator for column AutoFilter Rule.'); + } + $this->_operator = $pOperator; + + return $this; + } + + /** + * Get AutoFilter Rule Grouping + * + * @return string + */ + public function getGrouping() { + return $this->_grouping; + } + + /** + * Set AutoFilter Rule Grouping + * + * @param string $pGrouping + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setGrouping($pGrouping = NULL) { + if (($pGrouping !== NULL) && + (!in_array($pGrouping,self::$_dateTimeGroups)) && + (!in_array($pGrouping,self::$_dynamicTypes)) && + (!in_array($pGrouping,self::$_topTenType))) { + throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); + } + + $this->_grouping = $pGrouping; + + return $this; + } + + /** + * Set AutoFilter Rule + * + * @param string $pOperator + * @param string|string[] $pValue + * @param string $pGrouping + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue = '', $pGrouping = NULL) { + $this->setOperator($pOperator); + $this->setValue($pValue); + // Only set grouping if it's been passed in as a user-supplied argument, + // otherwise we're calculating it when we setValue() and don't want to overwrite that + // If the user supplies an argumnet for grouping, then on their own head be it + if ($pGrouping !== NULL) + $this->setGrouping($pGrouping); + + return $this; + } + + /** + * Get this Rule's AutoFilter Column Parent + * + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getParent() { + return $this->_parent; + } + + /** + * Set this Rule's AutoFilter Column Parent + * + * @param PHPExcel_Worksheet_AutoFilter_Column + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) { + $this->_parent = $pParent; + + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + if ($key == '_parent') { + // Detach from autofilter column parent + $this->$key = NULL; + } else { + $this->$key = clone $value; + } + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/BaseDrawing.php b/Classes/PHPExcel/Worksheet/BaseDrawing.php index e1d4715bd..d22c6b4b3 100644 --- a/Classes/PHPExcel/Worksheet/BaseDrawing.php +++ b/Classes/PHPExcel/Worksheet/BaseDrawing.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,118 +35,118 @@ */ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { - /** - * Image counter - * - * @var int - */ - private static $_imageCounter = 0; - - /** - * Image index - * - * @var int - */ - private $_imageIndex = 0; - - /** - * Name - * - * @var string - */ - protected $_name; - - /** - * Description - * - * @var string - */ - protected $_description; - - /** - * Worksheet - * - * @var PHPExcel_Worksheet - */ - protected $_worksheet; - - /** - * Coordinates - * - * @var string - */ - protected $_coordinates; - - /** - * Offset X - * - * @var int - */ - protected $_offsetX; - - /** - * Offset Y - * - * @var int - */ - protected $_offsetY; - - /** - * Width - * - * @var int - */ - protected $_width; - - /** - * Height - * - * @var int - */ - protected $_height; - - /** - * Proportional resize - * - * @var boolean - */ - protected $_resizeProportional; - - /** - * Rotation - * - * @var int - */ - protected $_rotation; - - /** - * Shadow - * - * @var PHPExcel_Worksheet_Drawing_Shadow - */ - protected $_shadow; + /** + * Image counter + * + * @var int + */ + private static $_imageCounter = 0; + + /** + * Image index + * + * @var int + */ + private $_imageIndex = 0; + + /** + * Name + * + * @var string + */ + protected $_name; + + /** + * Description + * + * @var string + */ + protected $_description; + + /** + * Worksheet + * + * @var PHPExcel_Worksheet + */ + protected $_worksheet; + + /** + * Coordinates + * + * @var string + */ + protected $_coordinates; + + /** + * Offset X + * + * @var int + */ + protected $_offsetX; + + /** + * Offset Y + * + * @var int + */ + protected $_offsetY; + + /** + * Width + * + * @var int + */ + protected $_width; + + /** + * Height + * + * @var int + */ + protected $_height; + + /** + * Proportional resize + * + * @var boolean + */ + protected $_resizeProportional; + + /** + * Rotation + * + * @var int + */ + protected $_rotation; + + /** + * Shadow + * + * @var PHPExcel_Worksheet_Drawing_Shadow + */ + protected $_shadow; /** * Create a new PHPExcel_Worksheet_BaseDrawing */ public function __construct() { - // Initialise values - $this->_name = ''; - $this->_description = ''; - $this->_worksheet = null; - $this->_coordinates = 'A1'; - $this->_offsetX = 0; - $this->_offsetY = 0; - $this->_width = 0; - $this->_height = 0; - $this->_resizeProportional = true; - $this->_rotation = 0; - $this->_shadow = new PHPExcel_Worksheet_Drawing_Shadow(); - - // Set image index - self::$_imageCounter++; - $this->_imageIndex = self::$_imageCounter; + // Initialise values + $this->_name = ''; + $this->_description = ''; + $this->_worksheet = null; + $this->_coordinates = 'A1'; + $this->_offsetX = 0; + $this->_offsetY = 0; + $this->_width = 0; + $this->_height = 0; + $this->_resizeProportional = true; + $this->_rotation = 0; + $this->_shadow = new PHPExcel_Worksheet_Drawing_Shadow(); + + // Set image index + self::$_imageCounter++; + $this->_imageIndex = self::$_imageCounter; } /** @@ -155,7 +155,7 @@ public function __construct() * @return int */ public function getImageIndex() { - return $this->_imageIndex; + return $this->_imageIndex; } /** @@ -164,7 +164,7 @@ public function getImageIndex() { * @return string */ public function getName() { - return $this->_name; + return $this->_name; } /** @@ -174,8 +174,8 @@ public function getName() { * @return PHPExcel_Worksheet_BaseDrawing */ public function setName($pValue = '') { - $this->_name = $pValue; - return $this; + $this->_name = $pValue; + return $this; } /** @@ -184,7 +184,7 @@ public function setName($pValue = '') { * @return string */ public function getDescription() { - return $this->_description; + return $this->_description; } /** @@ -194,8 +194,8 @@ public function getDescription() { * @return PHPExcel_Worksheet_BaseDrawing */ public function setDescription($pValue = '') { - $this->_description = $pValue; - return $this; + $this->_description = $pValue; + return $this; } /** @@ -204,43 +204,43 @@ public function setDescription($pValue = '') { * @return PHPExcel_Worksheet */ public function getWorksheet() { - return $this->_worksheet; + return $this->_worksheet; } /** * Set Worksheet * - * @param PHPExcel_Worksheet $pValue - * @param bool $pOverrideOld If a Worksheet has already been assigned, overwrite it and remove image from old Worksheet? - * @throws PHPExcel_Exception + * @param PHPExcel_Worksheet $pValue + * @param bool $pOverrideOld If a Worksheet has already been assigned, overwrite it and remove image from old Worksheet? + * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_BaseDrawing */ public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = false) { - if (is_null($this->_worksheet)) { - // Add drawing to PHPExcel_Worksheet - $this->_worksheet = $pValue; - $this->_worksheet->getCell($this->_coordinates); - $this->_worksheet->getDrawingCollection()->append($this); - } else { - if ($pOverrideOld) { - // Remove drawing from old PHPExcel_Worksheet - $iterator = $this->_worksheet->getDrawingCollection()->getIterator(); - - while ($iterator->valid()) { - if ($iterator->current()->getHashCode() == $this->getHashCode()) { - $this->_worksheet->getDrawingCollection()->offsetUnset( $iterator->key() ); - $this->_worksheet = null; - break; - } - } - - // Set new PHPExcel_Worksheet - $this->setWorksheet($pValue); - } else { - throw new PHPExcel_Exception("A PHPExcel_Worksheet has already been assigned. Drawings can only exist on one PHPExcel_Worksheet."); - } - } - return $this; + if (is_null($this->_worksheet)) { + // Add drawing to PHPExcel_Worksheet + $this->_worksheet = $pValue; + $this->_worksheet->getCell($this->_coordinates); + $this->_worksheet->getDrawingCollection()->append($this); + } else { + if ($pOverrideOld) { + // Remove drawing from old PHPExcel_Worksheet + $iterator = $this->_worksheet->getDrawingCollection()->getIterator(); + + while ($iterator->valid()) { + if ($iterator->current()->getHashCode() == $this->getHashCode()) { + $this->_worksheet->getDrawingCollection()->offsetUnset( $iterator->key() ); + $this->_worksheet = null; + break; + } + } + + // Set new PHPExcel_Worksheet + $this->setWorksheet($pValue); + } else { + throw new PHPExcel_Exception("A PHPExcel_Worksheet has already been assigned. Drawings can only exist on one PHPExcel_Worksheet."); + } + } + return $this; } /** @@ -249,7 +249,7 @@ public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = * @return string */ public function getCoordinates() { - return $this->_coordinates; + return $this->_coordinates; } /** @@ -259,8 +259,8 @@ public function getCoordinates() { * @return PHPExcel_Worksheet_BaseDrawing */ public function setCoordinates($pValue = 'A1') { - $this->_coordinates = $pValue; - return $this; + $this->_coordinates = $pValue; + return $this; } /** @@ -269,7 +269,7 @@ public function setCoordinates($pValue = 'A1') { * @return int */ public function getOffsetX() { - return $this->_offsetX; + return $this->_offsetX; } /** @@ -279,8 +279,8 @@ public function getOffsetX() { * @return PHPExcel_Worksheet_BaseDrawing */ public function setOffsetX($pValue = 0) { - $this->_offsetX = $pValue; - return $this; + $this->_offsetX = $pValue; + return $this; } /** @@ -289,7 +289,7 @@ public function setOffsetX($pValue = 0) { * @return int */ public function getOffsetY() { - return $this->_offsetY; + return $this->_offsetY; } /** @@ -299,8 +299,8 @@ public function getOffsetY() { * @return PHPExcel_Worksheet_BaseDrawing */ public function setOffsetY($pValue = 0) { - $this->_offsetY = $pValue; - return $this; + $this->_offsetY = $pValue; + return $this; } /** @@ -309,7 +309,7 @@ public function setOffsetY($pValue = 0) { * @return int */ public function getWidth() { - return $this->_width; + return $this->_width; } /** @@ -319,16 +319,16 @@ public function getWidth() { * @return PHPExcel_Worksheet_BaseDrawing */ public function setWidth($pValue = 0) { - // Resize proportional? - if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_height / ($this->_width != 0 ? $this->_width : 1); - $this->_height = round($ratio * $pValue); - } + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_height / ($this->_width != 0 ? $this->_width : 1); + $this->_height = round($ratio * $pValue); + } - // Set width - $this->_width = $pValue; + // Set width + $this->_width = $pValue; - return $this; + return $this; } /** @@ -337,7 +337,7 @@ public function setWidth($pValue = 0) { * @return int */ public function getHeight() { - return $this->_height; + return $this->_height; } /** @@ -347,49 +347,49 @@ public function getHeight() { * @return PHPExcel_Worksheet_BaseDrawing */ public function setHeight($pValue = 0) { - // Resize proportional? - if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_width / ($this->_height != 0 ? $this->_height : 1); - $this->_width = round($ratio * $pValue); - } + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_width / ($this->_height != 0 ? $this->_height : 1); + $this->_width = round($ratio * $pValue); + } - // Set height - $this->_height = $pValue; + // Set height + $this->_height = $pValue; - return $this; + return $this; } /** * Set width and height with proportional resize - * Example: - * <code> - * $objDrawing->setResizeProportional(true); - * $objDrawing->setWidthAndHeight(160,120); - * </code> - * + * Example: + * <code> + * $objDrawing->setResizeProportional(true); + * $objDrawing->setWidthAndHeight(160,120); + * </code> + * * @author Vincent@luo MSN:kele_100@hotmail.com * @param int $width * @param int $height * @return PHPExcel_Worksheet_BaseDrawing */ - public function setWidthAndHeight($width = 0, $height = 0) { - $xratio = $width / ($this->_width != 0 ? $this->_width : 1); - $yratio = $height / ($this->_height != 0 ? $this->_height : 1); - if ($this->_resizeProportional && !($width == 0 || $height == 0)) { - if (($xratio * $this->_height) < $height) { - $this->_height = ceil($xratio * $this->_height); - $this->_width = $width; - } else { - $this->_width = ceil($yratio * $this->_width); - $this->_height = $height; - } - } else { + public function setWidthAndHeight($width = 0, $height = 0) { + $xratio = $width / ($this->_width != 0 ? $this->_width : 1); + $yratio = $height / ($this->_height != 0 ? $this->_height : 1); + if ($this->_resizeProportional && !($width == 0 || $height == 0)) { + if (($xratio * $this->_height) < $height) { + $this->_height = ceil($xratio * $this->_height); + $this->_width = $width; + } else { + $this->_width = ceil($yratio * $this->_width); + $this->_height = $height; + } + } else { $this->_width = $width; $this->_height = $height; } - return $this; - } + return $this; + } /** * Get ResizeProportional @@ -397,7 +397,7 @@ public function setWidthAndHeight($width = 0, $height = 0) { * @return boolean */ public function getResizeProportional() { - return $this->_resizeProportional; + return $this->_resizeProportional; } /** @@ -407,8 +407,8 @@ public function getResizeProportional() { * @return PHPExcel_Worksheet_BaseDrawing */ public function setResizeProportional($pValue = true) { - $this->_resizeProportional = $pValue; - return $this; + $this->_resizeProportional = $pValue; + return $this; } /** @@ -417,7 +417,7 @@ public function setResizeProportional($pValue = true) { * @return int */ public function getRotation() { - return $this->_rotation; + return $this->_rotation; } /** @@ -427,8 +427,8 @@ public function getRotation() { * @return PHPExcel_Worksheet_BaseDrawing */ public function setRotation($pValue = 0) { - $this->_rotation = $pValue; - return $this; + $this->_rotation = $pValue; + return $this; } /** @@ -437,53 +437,53 @@ public function setRotation($pValue = 0) { * @return PHPExcel_Worksheet_Drawing_Shadow */ public function getShadow() { - return $this->_shadow; + return $this->_shadow; } /** * Set Shadow * - * @param PHPExcel_Worksheet_Drawing_Shadow $pValue - * @throws PHPExcel_Exception + * @param PHPExcel_Worksheet_Drawing_Shadow $pValue + * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_BaseDrawing */ public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) { - $this->_shadow = $pValue; - return $this; + $this->_shadow = $pValue; + return $this; } - /** - * Get hash code - * - * @return string Hash code - */ - public function getHashCode() { - return md5( - $this->_name - . $this->_description - . $this->_worksheet->getHashCode() - . $this->_coordinates - . $this->_offsetX - . $this->_offsetY - . $this->_width - . $this->_height - . $this->_rotation - . $this->_shadow->getHashCode() - . __CLASS__ - ); + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_name + . $this->_description + . $this->_worksheet->getHashCode() + . $this->_coordinates + . $this->_offsetX + . $this->_offsetY + . $this->_width + . $this->_height + . $this->_rotation + . $this->_shadow->getHashCode() + . __CLASS__ + ); } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/ColumnDimension.php b/Classes/PHPExcel/Worksheet/ColumnDimension.php index 956ffdce9..05be76fac 100644 --- a/Classes/PHPExcel/Worksheet/ColumnDimension.php +++ b/Classes/PHPExcel/Worksheet/ColumnDimension.php @@ -22,7 +22,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ class PHPExcel_Worksheet_ColumnDimension diff --git a/Classes/PHPExcel/Worksheet/Drawing.php b/Classes/PHPExcel/Worksheet/Drawing.php index d58fcebd8..7f9dfd55d 100644 --- a/Classes/PHPExcel/Worksheet/Drawing.php +++ b/Classes/PHPExcel/Worksheet/Drawing.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet_Drawing * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,23 +35,23 @@ */ class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { - /** - * Path - * - * @var string - */ - private $_path; + /** + * Path + * + * @var string + */ + private $_path; /** * Create a new PHPExcel_Worksheet_Drawing */ public function __construct() { - // Initialise values - $this->_path = ''; + // Initialise values + $this->_path = ''; - // Initialize parent - parent::__construct(); + // Initialize parent + parent::__construct(); } /** @@ -60,7 +60,7 @@ public function __construct() * @return string */ public function getFilename() { - return basename($this->_path); + return basename($this->_path); } /** @@ -69,9 +69,9 @@ public function getFilename() { * @return string */ public function getIndexedFilename() { - $fileName = $this->getFilename(); - $fileName = str_replace(' ', '_', $fileName); - return str_replace('.' . $this->getExtension(), '', $fileName) . $this->getImageIndex() . '.' . $this->getExtension(); + $fileName = $this->getFilename(); + $fileName = str_replace(' ', '_', $fileName); + return str_replace('.' . $this->getExtension(), '', $fileName) . $this->getImageIndex() . '.' . $this->getExtension(); } /** @@ -80,8 +80,8 @@ public function getIndexedFilename() { * @return string */ public function getExtension() { - $exploded = explode(".", basename($this->_path)); - return $exploded[count($exploded) - 1]; + $exploded = explode(".", basename($this->_path)); + return $exploded[count($exploded) - 1]; } /** @@ -90,59 +90,59 @@ public function getExtension() { * @return string */ public function getPath() { - return $this->_path; + return $this->_path; } /** * Set Path * - * @param string $pValue File path - * @param boolean $pVerifyFile Verify file - * @throws PHPExcel_Exception + * @param string $pValue File path + * @param boolean $pVerifyFile Verify file + * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_Drawing */ public function setPath($pValue = '', $pVerifyFile = true) { - if ($pVerifyFile) { - if (file_exists($pValue)) { - $this->_path = $pValue; + if ($pVerifyFile) { + if (file_exists($pValue)) { + $this->_path = $pValue; - if ($this->_width == 0 && $this->_height == 0) { - // Get width/height - list($this->_width, $this->_height) = getimagesize($pValue); - } - } else { - throw new PHPExcel_Exception("File $pValue not found!"); - } - } else { - $this->_path = $pValue; - } - return $this; + if ($this->_width == 0 && $this->_height == 0) { + // Get width/height + list($this->_width, $this->_height) = getimagesize($pValue); + } + } else { + throw new PHPExcel_Exception("File $pValue not found!"); + } + } else { + $this->_path = $pValue; + } + return $this; } - /** - * Get hash code - * - * @return string Hash code - */ - public function getHashCode() { - return md5( - $this->_path - . parent::getHashCode() - . __CLASS__ - ); + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_path + . parent::getHashCode() + . __CLASS__ + ); } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php index cc6289a00..8776745f0 100644 --- a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php +++ b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet_Drawing * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,82 +35,82 @@ */ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable { - /* Shadow alignment */ - const SHADOW_BOTTOM = 'b'; - const SHADOW_BOTTOM_LEFT = 'bl'; - const SHADOW_BOTTOM_RIGHT = 'br'; - const SHADOW_CENTER = 'ctr'; - const SHADOW_LEFT = 'l'; - const SHADOW_TOP = 't'; - const SHADOW_TOP_LEFT = 'tl'; - const SHADOW_TOP_RIGHT = 'tr'; + /* Shadow alignment */ + const SHADOW_BOTTOM = 'b'; + const SHADOW_BOTTOM_LEFT = 'bl'; + const SHADOW_BOTTOM_RIGHT = 'br'; + const SHADOW_CENTER = 'ctr'; + const SHADOW_LEFT = 'l'; + const SHADOW_TOP = 't'; + const SHADOW_TOP_LEFT = 'tl'; + const SHADOW_TOP_RIGHT = 'tr'; - /** - * Visible - * - * @var boolean - */ - private $_visible; + /** + * Visible + * + * @var boolean + */ + private $_visible; - /** - * Blur radius - * - * Defaults to 6 - * - * @var int - */ - private $_blurRadius; + /** + * Blur radius + * + * Defaults to 6 + * + * @var int + */ + private $_blurRadius; - /** - * Shadow distance - * - * Defaults to 2 - * - * @var int - */ - private $_distance; + /** + * Shadow distance + * + * Defaults to 2 + * + * @var int + */ + private $_distance; - /** - * Shadow direction (in degrees) - * - * @var int - */ - private $_direction; + /** + * Shadow direction (in degrees) + * + * @var int + */ + private $_direction; - /** - * Shadow alignment - * - * @var int - */ - private $_alignment; + /** + * Shadow alignment + * + * @var int + */ + private $_alignment; - /** - * Color - * - * @var PHPExcel_Style_Color - */ - private $_color; + /** + * Color + * + * @var PHPExcel_Style_Color + */ + private $_color; - /** - * Alpha - * - * @var int - */ - private $_alpha; + /** + * Alpha + * + * @var int + */ + private $_alpha; /** * Create a new PHPExcel_Worksheet_Drawing_Shadow */ public function __construct() { - // Initialise values - $this->_visible = false; - $this->_blurRadius = 6; - $this->_distance = 2; - $this->_direction = 0; - $this->_alignment = PHPExcel_Worksheet_Drawing_Shadow::SHADOW_BOTTOM_RIGHT; - $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK); - $this->_alpha = 50; + // Initialise values + $this->_visible = false; + $this->_blurRadius = 6; + $this->_distance = 2; + $this->_direction = 0; + $this->_alignment = PHPExcel_Worksheet_Drawing_Shadow::SHADOW_BOTTOM_RIGHT; + $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK); + $this->_alpha = 50; } /** @@ -119,7 +119,7 @@ public function __construct() * @return boolean */ public function getVisible() { - return $this->_visible; + return $this->_visible; } /** @@ -129,8 +129,8 @@ public function getVisible() { * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setVisible($pValue = false) { - $this->_visible = $pValue; - return $this; + $this->_visible = $pValue; + return $this; } /** @@ -139,7 +139,7 @@ public function setVisible($pValue = false) { * @return int */ public function getBlurRadius() { - return $this->_blurRadius; + return $this->_blurRadius; } /** @@ -149,8 +149,8 @@ public function getBlurRadius() { * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setBlurRadius($pValue = 6) { - $this->_blurRadius = $pValue; - return $this; + $this->_blurRadius = $pValue; + return $this; } /** @@ -159,7 +159,7 @@ public function setBlurRadius($pValue = 6) { * @return int */ public function getDistance() { - return $this->_distance; + return $this->_distance; } /** @@ -169,8 +169,8 @@ public function getDistance() { * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setDistance($pValue = 2) { - $this->_distance = $pValue; - return $this; + $this->_distance = $pValue; + return $this; } /** @@ -179,7 +179,7 @@ public function setDistance($pValue = 2) { * @return int */ public function getDirection() { - return $this->_direction; + return $this->_direction; } /** @@ -189,8 +189,8 @@ public function getDirection() { * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setDirection($pValue = 0) { - $this->_direction = $pValue; - return $this; + $this->_direction = $pValue; + return $this; } /** @@ -199,7 +199,7 @@ public function setDirection($pValue = 0) { * @return int */ public function getAlignment() { - return $this->_alignment; + return $this->_alignment; } /** @@ -209,8 +209,8 @@ public function getAlignment() { * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setAlignment($pValue = 0) { - $this->_alignment = $pValue; - return $this; + $this->_alignment = $pValue; + return $this; } /** @@ -219,19 +219,19 @@ public function setAlignment($pValue = 0) { * @return PHPExcel_Style_Color */ public function getColor() { - return $this->_color; + return $this->_color; } /** * Set Color * - * @param PHPExcel_Style_Color $pValue - * @throws PHPExcel_Exception + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setColor(PHPExcel_Style_Color $pValue = null) { - $this->_color = $pValue; - return $this; + $this->_color = $pValue; + return $this; } /** @@ -240,7 +240,7 @@ public function setColor(PHPExcel_Style_Color $pValue = null) { * @return int */ public function getAlpha() { - return $this->_alpha; + return $this->_alpha; } /** @@ -250,39 +250,39 @@ public function getAlpha() { * @return PHPExcel_Worksheet_Drawing_Shadow */ public function setAlpha($pValue = 0) { - $this->_alpha = $pValue; - return $this; + $this->_alpha = $pValue; + return $this; } - /** - * Get hash code - * - * @return string Hash code - */ - public function getHashCode() { - return md5( - ($this->_visible ? 't' : 'f') - . $this->_blurRadius - . $this->_distance - . $this->_direction - . $this->_alignment - . $this->_color->getHashCode() - . $this->_alpha - . __CLASS__ - ); + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + ($this->_visible ? 't' : 'f') + . $this->_blurRadius + . $this->_distance + . $this->_direction + . $this->_alignment + . $this->_color->getHashCode() + . $this->_alpha + . __CLASS__ + ); } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/HeaderFooter.php b/Classes/PHPExcel/Worksheet/HeaderFooter.php index 6620682f3..3d2271aba 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooter.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooter.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -37,7 +37,7 @@ * * Example: This example shows the text "Center Bold Header" on the first line (center section), and the date on * the second line (center section). - * &CCenter &"-,Bold"Bold&"-,Regular"Header_x000A_&D + * &CCenter &"-,Bold"Bold&"-,Regular"Header_x000A_&D * * General Rules: * There is no required order in which these codes must appear. @@ -95,90 +95,90 @@ */ class PHPExcel_Worksheet_HeaderFooter { - /* Header/footer image location */ - const IMAGE_HEADER_LEFT = 'LH'; - const IMAGE_HEADER_CENTER = 'CH'; - const IMAGE_HEADER_RIGHT = 'RH'; - const IMAGE_FOOTER_LEFT = 'LF'; - const IMAGE_FOOTER_CENTER = 'CF'; - const IMAGE_FOOTER_RIGHT = 'RF'; - - /** - * OddHeader - * - * @var string - */ - private $_oddHeader = ''; - - /** - * OddFooter - * - * @var string - */ - private $_oddFooter = ''; - - /** - * EvenHeader - * - * @var string - */ - private $_evenHeader = ''; - - /** - * EvenFooter - * - * @var string - */ - private $_evenFooter = ''; - - /** - * FirstHeader - * - * @var string - */ - private $_firstHeader = ''; - - /** - * FirstFooter - * - * @var string - */ - private $_firstFooter = ''; - - /** - * Different header for Odd/Even, defaults to false - * - * @var boolean - */ - private $_differentOddEven = false; - - /** - * Different header for first page, defaults to false - * - * @var boolean - */ - private $_differentFirst = false; - - /** - * Scale with document, defaults to true - * - * @var boolean - */ - private $_scaleWithDocument = true; - - /** - * Align with margins, defaults to true - * - * @var boolean - */ - private $_alignWithMargins = true; - - /** - * Header/footer images - * - * @var PHPExcel_Worksheet_HeaderFooterDrawing[] - */ - private $_headerFooterImages = array(); + /* Header/footer image location */ + const IMAGE_HEADER_LEFT = 'LH'; + const IMAGE_HEADER_CENTER = 'CH'; + const IMAGE_HEADER_RIGHT = 'RH'; + const IMAGE_FOOTER_LEFT = 'LF'; + const IMAGE_FOOTER_CENTER = 'CF'; + const IMAGE_FOOTER_RIGHT = 'RF'; + + /** + * OddHeader + * + * @var string + */ + private $_oddHeader = ''; + + /** + * OddFooter + * + * @var string + */ + private $_oddFooter = ''; + + /** + * EvenHeader + * + * @var string + */ + private $_evenHeader = ''; + + /** + * EvenFooter + * + * @var string + */ + private $_evenFooter = ''; + + /** + * FirstHeader + * + * @var string + */ + private $_firstHeader = ''; + + /** + * FirstFooter + * + * @var string + */ + private $_firstFooter = ''; + + /** + * Different header for Odd/Even, defaults to false + * + * @var boolean + */ + private $_differentOddEven = false; + + /** + * Different header for first page, defaults to false + * + * @var boolean + */ + private $_differentFirst = false; + + /** + * Scale with document, defaults to true + * + * @var boolean + */ + private $_scaleWithDocument = true; + + /** + * Align with margins, defaults to true + * + * @var boolean + */ + private $_alignWithMargins = true; + + /** + * Header/footer images + * + * @var PHPExcel_Worksheet_HeaderFooterDrawing[] + */ + private $_headerFooterImages = array(); /** * Create a new PHPExcel_Worksheet_HeaderFooter @@ -193,7 +193,7 @@ public function __construct() * @return string */ public function getOddHeader() { - return $this->_oddHeader; + return $this->_oddHeader; } /** @@ -203,8 +203,8 @@ public function getOddHeader() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setOddHeader($pValue) { - $this->_oddHeader = $pValue; - return $this; + $this->_oddHeader = $pValue; + return $this; } /** @@ -213,7 +213,7 @@ public function setOddHeader($pValue) { * @return string */ public function getOddFooter() { - return $this->_oddFooter; + return $this->_oddFooter; } /** @@ -223,8 +223,8 @@ public function getOddFooter() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setOddFooter($pValue) { - $this->_oddFooter = $pValue; - return $this; + $this->_oddFooter = $pValue; + return $this; } /** @@ -233,7 +233,7 @@ public function setOddFooter($pValue) { * @return string */ public function getEvenHeader() { - return $this->_evenHeader; + return $this->_evenHeader; } /** @@ -243,8 +243,8 @@ public function getEvenHeader() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setEvenHeader($pValue) { - $this->_evenHeader = $pValue; - return $this; + $this->_evenHeader = $pValue; + return $this; } /** @@ -253,7 +253,7 @@ public function setEvenHeader($pValue) { * @return string */ public function getEvenFooter() { - return $this->_evenFooter; + return $this->_evenFooter; } /** @@ -263,8 +263,8 @@ public function getEvenFooter() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setEvenFooter($pValue) { - $this->_evenFooter = $pValue; - return $this; + $this->_evenFooter = $pValue; + return $this; } /** @@ -273,7 +273,7 @@ public function setEvenFooter($pValue) { * @return string */ public function getFirstHeader() { - return $this->_firstHeader; + return $this->_firstHeader; } /** @@ -283,8 +283,8 @@ public function getFirstHeader() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setFirstHeader($pValue) { - $this->_firstHeader = $pValue; - return $this; + $this->_firstHeader = $pValue; + return $this; } /** @@ -293,7 +293,7 @@ public function setFirstHeader($pValue) { * @return string */ public function getFirstFooter() { - return $this->_firstFooter; + return $this->_firstFooter; } /** @@ -303,8 +303,8 @@ public function getFirstFooter() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setFirstFooter($pValue) { - $this->_firstFooter = $pValue; - return $this; + $this->_firstFooter = $pValue; + return $this; } /** @@ -313,7 +313,7 @@ public function setFirstFooter($pValue) { * @return boolean */ public function getDifferentOddEven() { - return $this->_differentOddEven; + return $this->_differentOddEven; } /** @@ -323,8 +323,8 @@ public function getDifferentOddEven() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setDifferentOddEven($pValue = false) { - $this->_differentOddEven = $pValue; - return $this; + $this->_differentOddEven = $pValue; + return $this; } /** @@ -333,7 +333,7 @@ public function setDifferentOddEven($pValue = false) { * @return boolean */ public function getDifferentFirst() { - return $this->_differentFirst; + return $this->_differentFirst; } /** @@ -343,8 +343,8 @@ public function getDifferentFirst() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setDifferentFirst($pValue = false) { - $this->_differentFirst = $pValue; - return $this; + $this->_differentFirst = $pValue; + return $this; } /** @@ -353,7 +353,7 @@ public function setDifferentFirst($pValue = false) { * @return boolean */ public function getScaleWithDocument() { - return $this->_scaleWithDocument; + return $this->_scaleWithDocument; } /** @@ -363,8 +363,8 @@ public function getScaleWithDocument() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setScaleWithDocument($pValue = true) { - $this->_scaleWithDocument = $pValue; - return $this; + $this->_scaleWithDocument = $pValue; + return $this; } /** @@ -373,7 +373,7 @@ public function setScaleWithDocument($pValue = true) { * @return boolean */ public function getAlignWithMargins() { - return $this->_alignWithMargins; + return $this->_alignWithMargins; } /** @@ -383,8 +383,8 @@ public function getAlignWithMargins() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setAlignWithMargins($pValue = true) { - $this->_alignWithMargins = $pValue; - return $this; + $this->_alignWithMargins = $pValue; + return $this; } /** @@ -396,8 +396,8 @@ public function setAlignWithMargins($pValue = true) { * @return PHPExcel_Worksheet_HeaderFooter */ public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $location = self::IMAGE_HEADER_LEFT) { - $this->_headerFooterImages[$location] = $image; - return $this; + $this->_headerFooterImages[$location] = $image; + return $this; } /** @@ -408,10 +408,10 @@ public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $ * @return PHPExcel_Worksheet_HeaderFooter */ public function removeImage($location = self::IMAGE_HEADER_LEFT) { - if (isset($this->_headerFooterImages[$location])) { - unset($this->_headerFooterImages[$location]); - } - return $this; + if (isset($this->_headerFooterImages[$location])) { + unset($this->_headerFooterImages[$location]); + } + return $this; } /** @@ -422,12 +422,12 @@ public function removeImage($location = self::IMAGE_HEADER_LEFT) { * @return PHPExcel_Worksheet_HeaderFooter */ public function setImages($images) { - if (!is_array($images)) { - throw new PHPExcel_Exception('Invalid parameter!'); - } + if (!is_array($images)) { + throw new PHPExcel_Exception('Invalid parameter!'); + } - $this->_headerFooterImages = $images; - return $this; + $this->_headerFooterImages = $images; + return $this; } /** @@ -436,30 +436,30 @@ public function setImages($images) { * @return PHPExcel_Worksheet_HeaderFooterDrawing[] */ public function getImages() { - // Sort array - $images = array(); - if (isset($this->_headerFooterImages[self::IMAGE_HEADER_LEFT])) $images[self::IMAGE_HEADER_LEFT] = $this->_headerFooterImages[self::IMAGE_HEADER_LEFT]; - if (isset($this->_headerFooterImages[self::IMAGE_HEADER_CENTER])) $images[self::IMAGE_HEADER_CENTER] = $this->_headerFooterImages[self::IMAGE_HEADER_CENTER]; - if (isset($this->_headerFooterImages[self::IMAGE_HEADER_RIGHT])) $images[self::IMAGE_HEADER_RIGHT] = $this->_headerFooterImages[self::IMAGE_HEADER_RIGHT]; - if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_LEFT])) $images[self::IMAGE_FOOTER_LEFT] = $this->_headerFooterImages[self::IMAGE_FOOTER_LEFT]; - if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_CENTER])) $images[self::IMAGE_FOOTER_CENTER] = $this->_headerFooterImages[self::IMAGE_FOOTER_CENTER]; - if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT])) $images[self::IMAGE_FOOTER_RIGHT] = $this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT]; - $this->_headerFooterImages = $images; - - return $this->_headerFooterImages; + // Sort array + $images = array(); + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_LEFT])) $images[self::IMAGE_HEADER_LEFT] = $this->_headerFooterImages[self::IMAGE_HEADER_LEFT]; + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_CENTER])) $images[self::IMAGE_HEADER_CENTER] = $this->_headerFooterImages[self::IMAGE_HEADER_CENTER]; + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_RIGHT])) $images[self::IMAGE_HEADER_RIGHT] = $this->_headerFooterImages[self::IMAGE_HEADER_RIGHT]; + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_LEFT])) $images[self::IMAGE_FOOTER_LEFT] = $this->_headerFooterImages[self::IMAGE_FOOTER_LEFT]; + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_CENTER])) $images[self::IMAGE_FOOTER_CENTER] = $this->_headerFooterImages[self::IMAGE_FOOTER_CENTER]; + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT])) $images[self::IMAGE_FOOTER_RIGHT] = $this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT]; + $this->_headerFooterImages = $images; + + return $this->_headerFooterImages; } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php index 99085b73f..6468d4f3b 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,68 +35,68 @@ */ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing implements PHPExcel_IComparable { - /** - * Path - * - * @var string - */ - private $_path; - - /** - * Name - * - * @var string - */ - protected $_name; - - /** - * Offset X - * - * @var int - */ - protected $_offsetX; - - /** - * Offset Y - * - * @var int - */ - protected $_offsetY; - - /** - * Width - * - * @var int - */ - protected $_width; - - /** - * Height - * - * @var int - */ - protected $_height; - - /** - * Proportional resize - * - * @var boolean - */ - protected $_resizeProportional; + /** + * Path + * + * @var string + */ + private $_path; + + /** + * Name + * + * @var string + */ + protected $_name; + + /** + * Offset X + * + * @var int + */ + protected $_offsetX; + + /** + * Offset Y + * + * @var int + */ + protected $_offsetY; + + /** + * Width + * + * @var int + */ + protected $_width; + + /** + * Height + * + * @var int + */ + protected $_height; + + /** + * Proportional resize + * + * @var boolean + */ + protected $_resizeProportional; /** * Create a new PHPExcel_Worksheet_HeaderFooterDrawing */ public function __construct() { - // Initialise values - $this->_path = ''; - $this->_name = ''; - $this->_offsetX = 0; - $this->_offsetY = 0; - $this->_width = 0; - $this->_height = 0; - $this->_resizeProportional = true; + // Initialise values + $this->_path = ''; + $this->_name = ''; + $this->_offsetX = 0; + $this->_offsetY = 0; + $this->_width = 0; + $this->_height = 0; + $this->_resizeProportional = true; } /** @@ -105,7 +105,7 @@ public function __construct() * @return string */ public function getName() { - return $this->_name; + return $this->_name; } /** @@ -115,8 +115,8 @@ public function getName() { * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setName($pValue = '') { - $this->_name = $pValue; - return $this; + $this->_name = $pValue; + return $this; } /** @@ -125,7 +125,7 @@ public function setName($pValue = '') { * @return int */ public function getOffsetX() { - return $this->_offsetX; + return $this->_offsetX; } /** @@ -135,8 +135,8 @@ public function getOffsetX() { * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setOffsetX($pValue = 0) { - $this->_offsetX = $pValue; - return $this; + $this->_offsetX = $pValue; + return $this; } /** @@ -145,7 +145,7 @@ public function setOffsetX($pValue = 0) { * @return int */ public function getOffsetY() { - return $this->_offsetY; + return $this->_offsetY; } /** @@ -155,8 +155,8 @@ public function getOffsetY() { * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setOffsetY($pValue = 0) { - $this->_offsetY = $pValue; - return $this; + $this->_offsetY = $pValue; + return $this; } /** @@ -165,7 +165,7 @@ public function setOffsetY($pValue = 0) { * @return int */ public function getWidth() { - return $this->_width; + return $this->_width; } /** @@ -175,16 +175,16 @@ public function getWidth() { * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setWidth($pValue = 0) { - // Resize proportional? - if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_width / $this->_height; - $this->_height = round($ratio * $pValue); - } + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_width / $this->_height; + $this->_height = round($ratio * $pValue); + } - // Set width - $this->_width = $pValue; + // Set width + $this->_width = $pValue; - return $this; + return $this; } /** @@ -193,7 +193,7 @@ public function setWidth($pValue = 0) { * @return int */ public function getHeight() { - return $this->_height; + return $this->_height; } /** @@ -203,45 +203,45 @@ public function getHeight() { * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setHeight($pValue = 0) { - // Resize proportional? - if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_width / $this->_height; - $this->_width = round($ratio * $pValue); - } + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_width / $this->_height; + $this->_width = round($ratio * $pValue); + } - // Set height - $this->_height = $pValue; + // Set height + $this->_height = $pValue; - return $this; + return $this; } /** * Set width and height with proportional resize - * Example: - * <code> + * Example: + * <code> * $objDrawing->setResizeProportional(true); * $objDrawing->setWidthAndHeight(160,120); - * </code> - * + * </code> + * * @author Vincent@luo MSN:kele_100@hotmail.com * @param int $width * @param int $height * @return PHPExcel_Worksheet_HeaderFooterDrawing */ - public function setWidthAndHeight($width = 0, $height = 0) { - $xratio = $width / $this->_width; - $yratio = $height / $this->_height; - if ($this->_resizeProportional && !($width == 0 || $height == 0)) { - if (($xratio * $this->_height) < $height) { - $this->_height = ceil($xratio * $this->_height); - $this->_width = $width; - } else { - $this->_width = ceil($yratio * $this->_width); - $this->_height = $height; - } - } - return $this; - } + public function setWidthAndHeight($width = 0, $height = 0) { + $xratio = $width / $this->_width; + $yratio = $height / $this->_height; + if ($this->_resizeProportional && !($width == 0 || $height == 0)) { + if (($xratio * $this->_height) < $height) { + $this->_height = ceil($xratio * $this->_height); + $this->_width = $width; + } else { + $this->_width = ceil($yratio * $this->_width); + $this->_height = $height; + } + } + return $this; + } /** * Get ResizeProportional @@ -249,7 +249,7 @@ public function setWidthAndHeight($width = 0, $height = 0) { * @return boolean */ public function getResizeProportional() { - return $this->_resizeProportional; + return $this->_resizeProportional; } /** @@ -259,8 +259,8 @@ public function getResizeProportional() { * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setResizeProportional($pValue = true) { - $this->_resizeProportional = $pValue; - return $this; + $this->_resizeProportional = $pValue; + return $this; } /** @@ -269,7 +269,7 @@ public function setResizeProportional($pValue = true) { * @return string */ public function getFilename() { - return basename($this->_path); + return basename($this->_path); } /** @@ -288,63 +288,63 @@ public function getExtension() { * @return string */ public function getPath() { - return $this->_path; + return $this->_path; } /** * Set Path * - * @param string $pValue File path - * @param boolean $pVerifyFile Verify file - * @throws PHPExcel_Exception + * @param string $pValue File path + * @param boolean $pVerifyFile Verify file + * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_HeaderFooterDrawing */ public function setPath($pValue = '', $pVerifyFile = true) { - if ($pVerifyFile) { - if (file_exists($pValue)) { - $this->_path = $pValue; - - if ($this->_width == 0 && $this->_height == 0) { - // Get width/height - list($this->_width, $this->_height) = getimagesize($pValue); - } - } else { - throw new PHPExcel_Exception("File $pValue not found!"); - } - } else { - $this->_path = $pValue; - } - return $this; + if ($pVerifyFile) { + if (file_exists($pValue)) { + $this->_path = $pValue; + + if ($this->_width == 0 && $this->_height == 0) { + // Get width/height + list($this->_width, $this->_height) = getimagesize($pValue); + } + } else { + throw new PHPExcel_Exception("File $pValue not found!"); + } + } else { + $this->_path = $pValue; + } + return $this; } - /** - * Get hash code - * - * @return string Hash code - */ - public function getHashCode() { - return md5( - $this->_path - . $this->_name - . $this->_offsetX - . $this->_offsetY - . $this->_width - . $this->_height - . __CLASS__ - ); + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_path + . $this->_name + . $this->_offsetX + . $this->_offsetY + . $this->_width + . $this->_height + . __CLASS__ + ); } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/MemoryDrawing.php b/Classes/PHPExcel/Worksheet/MemoryDrawing.php index b6c71af99..86fc681ed 100644 --- a/Classes/PHPExcel/Worksheet/MemoryDrawing.php +++ b/Classes/PHPExcel/Worksheet/MemoryDrawing.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,59 +35,59 @@ */ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { - /* Rendering functions */ - const RENDERING_DEFAULT = 'imagepng'; - const RENDERING_PNG = 'imagepng'; - const RENDERING_GIF = 'imagegif'; - const RENDERING_JPEG = 'imagejpeg'; - - /* MIME types */ - const MIMETYPE_DEFAULT = 'image/png'; - const MIMETYPE_PNG = 'image/png'; - const MIMETYPE_GIF = 'image/gif'; - const MIMETYPE_JPEG = 'image/jpeg'; - - /** - * Image resource - * - * @var resource - */ - private $_imageResource; - - /** - * Rendering function - * - * @var string - */ - private $_renderingFunction; - - /** - * Mime type - * - * @var string - */ - private $_mimeType; - - /** - * Unique name - * - * @var string - */ - private $_uniqueName; + /* Rendering functions */ + const RENDERING_DEFAULT = 'imagepng'; + const RENDERING_PNG = 'imagepng'; + const RENDERING_GIF = 'imagegif'; + const RENDERING_JPEG = 'imagejpeg'; + + /* MIME types */ + const MIMETYPE_DEFAULT = 'image/png'; + const MIMETYPE_PNG = 'image/png'; + const MIMETYPE_GIF = 'image/gif'; + const MIMETYPE_JPEG = 'image/jpeg'; + + /** + * Image resource + * + * @var resource + */ + private $_imageResource; + + /** + * Rendering function + * + * @var string + */ + private $_renderingFunction; + + /** + * Mime type + * + * @var string + */ + private $_mimeType; + + /** + * Unique name + * + * @var string + */ + private $_uniqueName; /** * Create a new PHPExcel_Worksheet_MemoryDrawing */ public function __construct() { - // Initialise values - $this->_imageResource = null; - $this->_renderingFunction = self::RENDERING_DEFAULT; - $this->_mimeType = self::MIMETYPE_DEFAULT; - $this->_uniqueName = md5(rand(0, 9999). time() . rand(0, 9999)); - - // Initialize parent - parent::__construct(); + // Initialise values + $this->_imageResource = null; + $this->_renderingFunction = self::RENDERING_DEFAULT; + $this->_mimeType = self::MIMETYPE_DEFAULT; + $this->_uniqueName = md5(rand(0, 9999). time() . rand(0, 9999)); + + // Initialize parent + parent::__construct(); } /** @@ -96,24 +96,24 @@ public function __construct() * @return resource */ public function getImageResource() { - return $this->_imageResource; + return $this->_imageResource; } /** * Set image resource * - * @param $value resource + * @param $value resource * @return PHPExcel_Worksheet_MemoryDrawing */ public function setImageResource($value = null) { - $this->_imageResource = $value; - - if (!is_null($this->_imageResource)) { - // Get width/height - $this->_width = imagesx($this->_imageResource); - $this->_height = imagesy($this->_imageResource); - } - return $this; + $this->_imageResource = $value; + + if (!is_null($this->_imageResource)) { + // Get width/height + $this->_width = imagesx($this->_imageResource); + $this->_height = imagesy($this->_imageResource); + } + return $this; } /** @@ -122,7 +122,7 @@ public function setImageResource($value = null) { * @return string */ public function getRenderingFunction() { - return $this->_renderingFunction; + return $this->_renderingFunction; } /** @@ -132,8 +132,8 @@ public function getRenderingFunction() { * @return PHPExcel_Worksheet_MemoryDrawing */ public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT) { - $this->_renderingFunction = $value; - return $this; + $this->_renderingFunction = $value; + return $this; } /** @@ -142,7 +142,7 @@ public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing:: * @return string */ public function getMimeType() { - return $this->_mimeType; + return $this->_mimeType; } /** @@ -152,8 +152,8 @@ public function getMimeType() { * @return PHPExcel_Worksheet_MemoryDrawing */ public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT) { - $this->_mimeType = $value; - return $this; + $this->_mimeType = $value; + return $this; } /** @@ -162,39 +162,39 @@ public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_ * @return string */ public function getIndexedFilename() { - $extension = strtolower($this->getMimeType()); - $extension = explode('/', $extension); - $extension = $extension[1]; + $extension = strtolower($this->getMimeType()); + $extension = explode('/', $extension); + $extension = $extension[1]; - return $this->_uniqueName . $this->getImageIndex() . '.' . $extension; + return $this->_uniqueName . $this->getImageIndex() . '.' . $extension; } - /** - * Get hash code - * - * @return string Hash code - */ - public function getHashCode() { - return md5( - $this->_renderingFunction - . $this->_mimeType - . $this->_uniqueName - . parent::getHashCode() - . __CLASS__ - ); + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_renderingFunction + . $this->_mimeType + . $this->_uniqueName + . parent::getHashCode() + . __CLASS__ + ); } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/PageMargins.php b/Classes/PHPExcel/Worksheet/PageMargins.php index 3b83afb53..38cbce6e6 100644 --- a/Classes/PHPExcel/Worksheet/PageMargins.php +++ b/Classes/PHPExcel/Worksheet/PageMargins.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,47 +35,47 @@ */ class PHPExcel_Worksheet_PageMargins { - /** - * Left - * - * @var double - */ - private $_left = 0.7; - - /** - * Right - * - * @var double - */ - private $_right = 0.7; - - /** - * Top - * - * @var double - */ - private $_top = 0.75; - - /** - * Bottom - * - * @var double - */ - private $_bottom = 0.75; - - /** - * Header - * - * @var double - */ - private $_header = 0.3; - - /** - * Footer - * - * @var double - */ - private $_footer = 0.3; + /** + * Left + * + * @var double + */ + private $_left = 0.7; + + /** + * Right + * + * @var double + */ + private $_right = 0.7; + + /** + * Top + * + * @var double + */ + private $_top = 0.75; + + /** + * Bottom + * + * @var double + */ + private $_bottom = 0.75; + + /** + * Header + * + * @var double + */ + private $_header = 0.3; + + /** + * Footer + * + * @var double + */ + private $_footer = 0.3; /** * Create a new PHPExcel_Worksheet_PageMargins @@ -90,7 +90,7 @@ public function __construct() * @return double */ public function getLeft() { - return $this->_left; + return $this->_left; } /** @@ -100,8 +100,8 @@ public function getLeft() { * @return PHPExcel_Worksheet_PageMargins */ public function setLeft($pValue) { - $this->_left = $pValue; - return $this; + $this->_left = $pValue; + return $this; } /** @@ -110,7 +110,7 @@ public function setLeft($pValue) { * @return double */ public function getRight() { - return $this->_right; + return $this->_right; } /** @@ -120,8 +120,8 @@ public function getRight() { * @return PHPExcel_Worksheet_PageMargins */ public function setRight($pValue) { - $this->_right = $pValue; - return $this; + $this->_right = $pValue; + return $this; } /** @@ -130,7 +130,7 @@ public function setRight($pValue) { * @return double */ public function getTop() { - return $this->_top; + return $this->_top; } /** @@ -140,8 +140,8 @@ public function getTop() { * @return PHPExcel_Worksheet_PageMargins */ public function setTop($pValue) { - $this->_top = $pValue; - return $this; + $this->_top = $pValue; + return $this; } /** @@ -150,7 +150,7 @@ public function setTop($pValue) { * @return double */ public function getBottom() { - return $this->_bottom; + return $this->_bottom; } /** @@ -160,8 +160,8 @@ public function getBottom() { * @return PHPExcel_Worksheet_PageMargins */ public function setBottom($pValue) { - $this->_bottom = $pValue; - return $this; + $this->_bottom = $pValue; + return $this; } /** @@ -170,7 +170,7 @@ public function setBottom($pValue) { * @return double */ public function getHeader() { - return $this->_header; + return $this->_header; } /** @@ -180,8 +180,8 @@ public function getHeader() { * @return PHPExcel_Worksheet_PageMargins */ public function setHeader($pValue) { - $this->_header = $pValue; - return $this; + $this->_header = $pValue; + return $this; } /** @@ -190,7 +190,7 @@ public function setHeader($pValue) { * @return double */ public function getFooter() { - return $this->_footer; + return $this->_footer; } /** @@ -200,21 +200,21 @@ public function getFooter() { * @return PHPExcel_Worksheet_PageMargins */ public function setFooter($pValue) { - $this->_footer = $pValue; - return $this; + $this->_footer = $pValue; + return $this; } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/PageSetup.php b/Classes/PHPExcel/Worksheet/PageSetup.php index 86af283d4..2070cf901 100644 --- a/Classes/PHPExcel/Worksheet/PageSetup.php +++ b/Classes/PHPExcel/Worksheet/PageSetup.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -106,173 +106,173 @@ */ class PHPExcel_Worksheet_PageSetup { - /* Paper size */ - const PAPERSIZE_LETTER = 1; - const PAPERSIZE_LETTER_SMALL = 2; - const PAPERSIZE_TABLOID = 3; - const PAPERSIZE_LEDGER = 4; - const PAPERSIZE_LEGAL = 5; - const PAPERSIZE_STATEMENT = 6; - const PAPERSIZE_EXECUTIVE = 7; - const PAPERSIZE_A3 = 8; - const PAPERSIZE_A4 = 9; - const PAPERSIZE_A4_SMALL = 10; - const PAPERSIZE_A5 = 11; - const PAPERSIZE_B4 = 12; - const PAPERSIZE_B5 = 13; - const PAPERSIZE_FOLIO = 14; - const PAPERSIZE_QUARTO = 15; - const PAPERSIZE_STANDARD_1 = 16; - const PAPERSIZE_STANDARD_2 = 17; - const PAPERSIZE_NOTE = 18; - const PAPERSIZE_NO9_ENVELOPE = 19; - const PAPERSIZE_NO10_ENVELOPE = 20; - const PAPERSIZE_NO11_ENVELOPE = 21; - const PAPERSIZE_NO12_ENVELOPE = 22; - const PAPERSIZE_NO14_ENVELOPE = 23; - const PAPERSIZE_C = 24; - const PAPERSIZE_D = 25; - const PAPERSIZE_E = 26; - const PAPERSIZE_DL_ENVELOPE = 27; - const PAPERSIZE_C5_ENVELOPE = 28; - const PAPERSIZE_C3_ENVELOPE = 29; - const PAPERSIZE_C4_ENVELOPE = 30; - const PAPERSIZE_C6_ENVELOPE = 31; - const PAPERSIZE_C65_ENVELOPE = 32; - const PAPERSIZE_B4_ENVELOPE = 33; - const PAPERSIZE_B5_ENVELOPE = 34; - const PAPERSIZE_B6_ENVELOPE = 35; - const PAPERSIZE_ITALY_ENVELOPE = 36; - const PAPERSIZE_MONARCH_ENVELOPE = 37; - const PAPERSIZE_6_3_4_ENVELOPE = 38; - const PAPERSIZE_US_STANDARD_FANFOLD = 39; - const PAPERSIZE_GERMAN_STANDARD_FANFOLD = 40; - const PAPERSIZE_GERMAN_LEGAL_FANFOLD = 41; - const PAPERSIZE_ISO_B4 = 42; - const PAPERSIZE_JAPANESE_DOUBLE_POSTCARD = 43; - const PAPERSIZE_STANDARD_PAPER_1 = 44; - const PAPERSIZE_STANDARD_PAPER_2 = 45; - const PAPERSIZE_STANDARD_PAPER_3 = 46; - const PAPERSIZE_INVITE_ENVELOPE = 47; - const PAPERSIZE_LETTER_EXTRA_PAPER = 48; - const PAPERSIZE_LEGAL_EXTRA_PAPER = 49; - const PAPERSIZE_TABLOID_EXTRA_PAPER = 50; - const PAPERSIZE_A4_EXTRA_PAPER = 51; - const PAPERSIZE_LETTER_TRANSVERSE_PAPER = 52; - const PAPERSIZE_A4_TRANSVERSE_PAPER = 53; - const PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER = 54; - const PAPERSIZE_SUPERA_SUPERA_A4_PAPER = 55; - const PAPERSIZE_SUPERB_SUPERB_A3_PAPER = 56; - const PAPERSIZE_LETTER_PLUS_PAPER = 57; - const PAPERSIZE_A4_PLUS_PAPER = 58; - const PAPERSIZE_A5_TRANSVERSE_PAPER = 59; - const PAPERSIZE_JIS_B5_TRANSVERSE_PAPER = 60; - const PAPERSIZE_A3_EXTRA_PAPER = 61; - const PAPERSIZE_A5_EXTRA_PAPER = 62; - const PAPERSIZE_ISO_B5_EXTRA_PAPER = 63; - const PAPERSIZE_A2_PAPER = 64; - const PAPERSIZE_A3_TRANSVERSE_PAPER = 65; - const PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER = 66; - - /* Page orientation */ - const ORIENTATION_DEFAULT = 'default'; - const ORIENTATION_LANDSCAPE = 'landscape'; - const ORIENTATION_PORTRAIT = 'portrait'; - - /* Print Range Set Method */ - const SETPRINTRANGE_OVERWRITE = 'O'; - const SETPRINTRANGE_INSERT = 'I'; - - - /** - * Paper size - * - * @var int - */ - private $_paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER; - - /** - * Orientation - * - * @var string - */ - private $_orientation = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT; - - /** - * Scale (Print Scale) - * - * Print scaling. Valid values range from 10 to 400 - * This setting is overridden when fitToWidth and/or fitToHeight are in use - * - * @var int? - */ - private $_scale = 100; - - /** - * Fit To Page - * Whether scale or fitToWith / fitToHeight applies - * - * @var boolean - */ - private $_fitToPage = FALSE; - - /** - * Fit To Height - * Number of vertical pages to fit on - * - * @var int? - */ - private $_fitToHeight = 1; - - /** - * Fit To Width - * Number of horizontal pages to fit on - * - * @var int? - */ - private $_fitToWidth = 1; - - /** - * Columns to repeat at left - * - * @var array Containing start column and end column, empty array if option unset - */ - private $_columnsToRepeatAtLeft = array('', ''); - - /** - * Rows to repeat at top - * - * @var array Containing start row number and end row number, empty array if option unset - */ - private $_rowsToRepeatAtTop = array(0, 0); - - /** - * Center page horizontally - * - * @var boolean - */ - private $_horizontalCentered = FALSE; - - /** - * Center page vertically - * - * @var boolean - */ - private $_verticalCentered = FALSE; - - /** - * Print area - * - * @var string - */ - private $_printArea = NULL; - - /** - * First page number - * - * @var int - */ - private $_firstPageNumber = NULL; + /* Paper size */ + const PAPERSIZE_LETTER = 1; + const PAPERSIZE_LETTER_SMALL = 2; + const PAPERSIZE_TABLOID = 3; + const PAPERSIZE_LEDGER = 4; + const PAPERSIZE_LEGAL = 5; + const PAPERSIZE_STATEMENT = 6; + const PAPERSIZE_EXECUTIVE = 7; + const PAPERSIZE_A3 = 8; + const PAPERSIZE_A4 = 9; + const PAPERSIZE_A4_SMALL = 10; + const PAPERSIZE_A5 = 11; + const PAPERSIZE_B4 = 12; + const PAPERSIZE_B5 = 13; + const PAPERSIZE_FOLIO = 14; + const PAPERSIZE_QUARTO = 15; + const PAPERSIZE_STANDARD_1 = 16; + const PAPERSIZE_STANDARD_2 = 17; + const PAPERSIZE_NOTE = 18; + const PAPERSIZE_NO9_ENVELOPE = 19; + const PAPERSIZE_NO10_ENVELOPE = 20; + const PAPERSIZE_NO11_ENVELOPE = 21; + const PAPERSIZE_NO12_ENVELOPE = 22; + const PAPERSIZE_NO14_ENVELOPE = 23; + const PAPERSIZE_C = 24; + const PAPERSIZE_D = 25; + const PAPERSIZE_E = 26; + const PAPERSIZE_DL_ENVELOPE = 27; + const PAPERSIZE_C5_ENVELOPE = 28; + const PAPERSIZE_C3_ENVELOPE = 29; + const PAPERSIZE_C4_ENVELOPE = 30; + const PAPERSIZE_C6_ENVELOPE = 31; + const PAPERSIZE_C65_ENVELOPE = 32; + const PAPERSIZE_B4_ENVELOPE = 33; + const PAPERSIZE_B5_ENVELOPE = 34; + const PAPERSIZE_B6_ENVELOPE = 35; + const PAPERSIZE_ITALY_ENVELOPE = 36; + const PAPERSIZE_MONARCH_ENVELOPE = 37; + const PAPERSIZE_6_3_4_ENVELOPE = 38; + const PAPERSIZE_US_STANDARD_FANFOLD = 39; + const PAPERSIZE_GERMAN_STANDARD_FANFOLD = 40; + const PAPERSIZE_GERMAN_LEGAL_FANFOLD = 41; + const PAPERSIZE_ISO_B4 = 42; + const PAPERSIZE_JAPANESE_DOUBLE_POSTCARD = 43; + const PAPERSIZE_STANDARD_PAPER_1 = 44; + const PAPERSIZE_STANDARD_PAPER_2 = 45; + const PAPERSIZE_STANDARD_PAPER_3 = 46; + const PAPERSIZE_INVITE_ENVELOPE = 47; + const PAPERSIZE_LETTER_EXTRA_PAPER = 48; + const PAPERSIZE_LEGAL_EXTRA_PAPER = 49; + const PAPERSIZE_TABLOID_EXTRA_PAPER = 50; + const PAPERSIZE_A4_EXTRA_PAPER = 51; + const PAPERSIZE_LETTER_TRANSVERSE_PAPER = 52; + const PAPERSIZE_A4_TRANSVERSE_PAPER = 53; + const PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER = 54; + const PAPERSIZE_SUPERA_SUPERA_A4_PAPER = 55; + const PAPERSIZE_SUPERB_SUPERB_A3_PAPER = 56; + const PAPERSIZE_LETTER_PLUS_PAPER = 57; + const PAPERSIZE_A4_PLUS_PAPER = 58; + const PAPERSIZE_A5_TRANSVERSE_PAPER = 59; + const PAPERSIZE_JIS_B5_TRANSVERSE_PAPER = 60; + const PAPERSIZE_A3_EXTRA_PAPER = 61; + const PAPERSIZE_A5_EXTRA_PAPER = 62; + const PAPERSIZE_ISO_B5_EXTRA_PAPER = 63; + const PAPERSIZE_A2_PAPER = 64; + const PAPERSIZE_A3_TRANSVERSE_PAPER = 65; + const PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER = 66; + + /* Page orientation */ + const ORIENTATION_DEFAULT = 'default'; + const ORIENTATION_LANDSCAPE = 'landscape'; + const ORIENTATION_PORTRAIT = 'portrait'; + + /* Print Range Set Method */ + const SETPRINTRANGE_OVERWRITE = 'O'; + const SETPRINTRANGE_INSERT = 'I'; + + + /** + * Paper size + * + * @var int + */ + private $_paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER; + + /** + * Orientation + * + * @var string + */ + private $_orientation = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT; + + /** + * Scale (Print Scale) + * + * Print scaling. Valid values range from 10 to 400 + * This setting is overridden when fitToWidth and/or fitToHeight are in use + * + * @var int? + */ + private $_scale = 100; + + /** + * Fit To Page + * Whether scale or fitToWith / fitToHeight applies + * + * @var boolean + */ + private $_fitToPage = FALSE; + + /** + * Fit To Height + * Number of vertical pages to fit on + * + * @var int? + */ + private $_fitToHeight = 1; + + /** + * Fit To Width + * Number of horizontal pages to fit on + * + * @var int? + */ + private $_fitToWidth = 1; + + /** + * Columns to repeat at left + * + * @var array Containing start column and end column, empty array if option unset + */ + private $_columnsToRepeatAtLeft = array('', ''); + + /** + * Rows to repeat at top + * + * @var array Containing start row number and end row number, empty array if option unset + */ + private $_rowsToRepeatAtTop = array(0, 0); + + /** + * Center page horizontally + * + * @var boolean + */ + private $_horizontalCentered = FALSE; + + /** + * Center page vertically + * + * @var boolean + */ + private $_verticalCentered = FALSE; + + /** + * Print area + * + * @var string + */ + private $_printArea = NULL; + + /** + * First page number + * + * @var int + */ + private $_firstPageNumber = NULL; /** * Create a new PHPExcel_Worksheet_PageSetup @@ -287,7 +287,7 @@ public function __construct() * @return int */ public function getPaperSize() { - return $this->_paperSize; + return $this->_paperSize; } /** @@ -297,8 +297,8 @@ public function getPaperSize() { * @return PHPExcel_Worksheet_PageSetup */ public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) { - $this->_paperSize = $pValue; - return $this; + $this->_paperSize = $pValue; + return $this; } /** @@ -307,7 +307,7 @@ public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_L * @return string */ public function getOrientation() { - return $this->_orientation; + return $this->_orientation; } /** @@ -317,449 +317,449 @@ public function getOrientation() { * @return PHPExcel_Worksheet_PageSetup */ public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) { - $this->_orientation = $pValue; - return $this; - } - - /** - * Get Scale - * - * @return int? - */ - public function getScale() { - return $this->_scale; - } - - /** - * Set Scale - * - * Print scaling. Valid values range from 10 to 400 - * This setting is overridden when fitToWidth and/or fitToHeight are in use - * - * @param int? $pValue - * @param boolean $pUpdate Update fitToPage so scaling applies rather than fitToHeight / fitToWidth - * @return PHPExcel_Worksheet_PageSetup - * @throws PHPExcel_Exception - */ - public function setScale($pValue = 100, $pUpdate = true) { - // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, - // but it is apparently still able to handle any scale >= 0, where 0 results in 100 - if (($pValue >= 0) || is_null($pValue)) { - $this->_scale = $pValue; - if ($pUpdate) { - $this->_fitToPage = false; - } - } else { - throw new PHPExcel_Exception("Scale must not be negative"); - } - return $this; - } - - /** - * Get Fit To Page - * - * @return boolean - */ - public function getFitToPage() { - return $this->_fitToPage; - } - - /** - * Set Fit To Page - * - * @param boolean $pValue - * @return PHPExcel_Worksheet_PageSetup - */ - public function setFitToPage($pValue = TRUE) { - $this->_fitToPage = $pValue; - return $this; - } - - /** - * Get Fit To Height - * - * @return int? - */ - public function getFitToHeight() { - return $this->_fitToHeight; - } - - /** - * Set Fit To Height - * - * @param int? $pValue - * @param boolean $pUpdate Update fitToPage so it applies rather than scaling - * @return PHPExcel_Worksheet_PageSetup - */ - public function setFitToHeight($pValue = 1, $pUpdate = TRUE) { - $this->_fitToHeight = $pValue; - if ($pUpdate) { - $this->_fitToPage = TRUE; - } - return $this; - } - - /** - * Get Fit To Width - * - * @return int? - */ - public function getFitToWidth() { - return $this->_fitToWidth; - } - - /** - * Set Fit To Width - * - * @param int? $pValue - * @param boolean $pUpdate Update fitToPage so it applies rather than scaling - * @return PHPExcel_Worksheet_PageSetup - */ - public function setFitToWidth($pValue = 1, $pUpdate = TRUE) { - $this->_fitToWidth = $pValue; - if ($pUpdate) { - $this->_fitToPage = TRUE; - } - return $this; - } - - /** - * Is Columns to repeat at left set? - * - * @return boolean - */ - public function isColumnsToRepeatAtLeftSet() { - if (is_array($this->_columnsToRepeatAtLeft)) { - if ($this->_columnsToRepeatAtLeft[0] != '' && $this->_columnsToRepeatAtLeft[1] != '') { - return true; - } - } - - return false; - } - - /** - * Get Columns to repeat at left - * - * @return array Containing start column and end column, empty array if option unset - */ - public function getColumnsToRepeatAtLeft() { - return $this->_columnsToRepeatAtLeft; - } - - /** - * Set Columns to repeat at left - * - * @param array $pValue Containing start column and end column, empty array if option unset - * @return PHPExcel_Worksheet_PageSetup - */ - public function setColumnsToRepeatAtLeft($pValue = null) { - if (is_array($pValue)) { - $this->_columnsToRepeatAtLeft = $pValue; - } - return $this; - } - - /** - * Set Columns to repeat at left by start and end - * - * @param string $pStart - * @param string $pEnd - * @return PHPExcel_Worksheet_PageSetup - */ - public function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A') { - $this->_columnsToRepeatAtLeft = array($pStart, $pEnd); - return $this; - } - - /** - * Is Rows to repeat at top set? - * - * @return boolean - */ - public function isRowsToRepeatAtTopSet() { - if (is_array($this->_rowsToRepeatAtTop)) { - if ($this->_rowsToRepeatAtTop[0] != 0 && $this->_rowsToRepeatAtTop[1] != 0) { - return true; - } - } - - return false; - } - - /** - * Get Rows to repeat at top - * - * @return array Containing start column and end column, empty array if option unset - */ - public function getRowsToRepeatAtTop() { - return $this->_rowsToRepeatAtTop; - } - - /** - * Set Rows to repeat at top - * - * @param array $pValue Containing start column and end column, empty array if option unset - * @return PHPExcel_Worksheet_PageSetup - */ - public function setRowsToRepeatAtTop($pValue = null) { - if (is_array($pValue)) { - $this->_rowsToRepeatAtTop = $pValue; - } - return $this; - } - - /** - * Set Rows to repeat at top by start and end - * - * @param int $pStart - * @param int $pEnd - * @return PHPExcel_Worksheet_PageSetup - */ - public function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1) { - $this->_rowsToRepeatAtTop = array($pStart, $pEnd); - return $this; - } - - /** - * Get center page horizontally - * - * @return bool - */ - public function getHorizontalCentered() { - return $this->_horizontalCentered; - } - - /** - * Set center page horizontally - * - * @param bool $value - * @return PHPExcel_Worksheet_PageSetup - */ - public function setHorizontalCentered($value = false) { - $this->_horizontalCentered = $value; - return $this; - } - - /** - * Get center page vertically - * - * @return bool - */ - public function getVerticalCentered() { - return $this->_verticalCentered; - } - - /** - * Set center page vertically - * - * @param bool $value - * @return PHPExcel_Worksheet_PageSetup - */ - public function setVerticalCentered($value = false) { - $this->_verticalCentered = $value; - return $this; - } - - /** - * Get print area - * - * @param int $index Identifier for a specific print area range if several ranges have been set - * Default behaviour, or a index value of 0, will return all ranges as a comma-separated string - * Otherwise, the specific range identified by the value of $index will be returned - * Print areas are numbered from 1 - * @throws PHPExcel_Exception - * @return string - */ - public function getPrintArea($index = 0) { - if ($index == 0) { - return $this->_printArea; - } - $printAreas = explode(',',$this->_printArea); - if (isset($printAreas[$index-1])) { - return $printAreas[$index-1]; - } - throw new PHPExcel_Exception("Requested Print Area does not exist"); - } - - /** - * Is print area set? - * - * @param int $index Identifier for a specific print area range if several ranges have been set - * Default behaviour, or an index value of 0, will identify whether any print range is set - * Otherwise, existence of the range identified by the value of $index will be returned - * Print areas are numbered from 1 - * @return boolean - */ - public function isPrintAreaSet($index = 0) { - if ($index == 0) { - return !is_null($this->_printArea); - } - $printAreas = explode(',',$this->_printArea); - return isset($printAreas[$index-1]); - } - - /** - * Clear a print area - * - * @param int $index Identifier for a specific print area range if several ranges have been set - * Default behaviour, or an index value of 0, will clear all print ranges that are set - * Otherwise, the range identified by the value of $index will be removed from the series - * Print areas are numbered from 1 - * @return PHPExcel_Worksheet_PageSetup - */ - public function clearPrintArea($index = 0) { - if ($index == 0) { - $this->_printArea = NULL; - } else { - $printAreas = explode(',',$this->_printArea); - if (isset($printAreas[$index-1])) { - unset($printAreas[$index-1]); - $this->_printArea = implode(',',$printAreas); - } - } - - return $this; - } - - /** - * Set print area. e.g. 'A1:D10' or 'A1:D10,G5:M20' - * - * @param string $value - * @param int $index Identifier for a specific print area range allowing several ranges to be set - * When the method is "O"verwrite, then a positive integer index will overwrite that indexed - * entry in the print areas list; a negative index value will identify which entry to - * overwrite working bacward through the print area to the list, with the last entry as -1. - * Specifying an index value of 0, will overwrite <b>all</b> existing print ranges. - * When the method is "I"nsert, then a positive index will insert after that indexed entry in - * the print areas list, while a negative index will insert before the indexed entry. - * Specifying an index value of 0, will always append the new print range at the end of the - * list. - * Print areas are numbered from 1 - * @param string $method Determines the method used when setting multiple print areas - * Default behaviour, or the "O" method, overwrites existing print area - * The "I" method, inserts the new print area before any specified index, or at the end of the list - * @return PHPExcel_Worksheet_PageSetup - * @throws PHPExcel_Exception - */ - public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) { - if (strpos($value,'!') !== false) { - throw new PHPExcel_Exception('Cell coordinate must not specify a worksheet.'); - } elseif (strpos($value,':') === false) { - throw new PHPExcel_Exception('Cell coordinate must be a range of cells.'); - } elseif (strpos($value,'$') !== false) { - throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); - } - $value = strtoupper($value); - - if ($method == self::SETPRINTRANGE_OVERWRITE) { - if ($index == 0) { - $this->_printArea = $value; - } else { - $printAreas = explode(',',$this->_printArea); - if($index < 0) { - $index = count($printAreas) - abs($index) + 1; - } - if (($index <= 0) || ($index > count($printAreas))) { - throw new PHPExcel_Exception('Invalid index for setting print range.'); - } - $printAreas[$index-1] = $value; - $this->_printArea = implode(',',$printAreas); - } - } elseif($method == self::SETPRINTRANGE_INSERT) { - if ($index == 0) { - $this->_printArea .= ($this->_printArea == '') ? $value : ','.$value; - } else { - $printAreas = explode(',',$this->_printArea); - if($index < 0) { - $index = abs($index) - 1; - } - if ($index > count($printAreas)) { - throw new PHPExcel_Exception('Invalid index for setting print range.'); - } - $printAreas = array_merge(array_slice($printAreas,0,$index),array($value),array_slice($printAreas,$index)); - $this->_printArea = implode(',',$printAreas); - } - } else { - throw new PHPExcel_Exception('Invalid method for setting print range.'); - } - - return $this; - } - - /** - * Add a new print area (e.g. 'A1:D10' or 'A1:D10,G5:M20') to the list of print areas - * - * @param string $value - * @param int $index Identifier for a specific print area range allowing several ranges to be set - * A positive index will insert after that indexed entry in the print areas list, while a - * negative index will insert before the indexed entry. - * Specifying an index value of 0, will always append the new print range at the end of the - * list. - * Print areas are numbered from 1 - * @return PHPExcel_Worksheet_PageSetup - * @throws PHPExcel_Exception - */ - public function addPrintArea($value, $index = -1) { - return $this->setPrintArea($value, $index, self::SETPRINTRANGE_INSERT); - } - - /** - * Set print area - * - * @param int $column1 Column 1 - * @param int $row1 Row 1 - * @param int $column2 Column 2 - * @param int $row2 Row 2 - * @param int $index Identifier for a specific print area range allowing several ranges to be set - * When the method is "O"verwrite, then a positive integer index will overwrite that indexed - * entry in the print areas list; a negative index value will identify which entry to - * overwrite working bacward through the print area to the list, with the last entry as -1. - * Specifying an index value of 0, will overwrite <b>all</b> existing print ranges. - * When the method is "I"nsert, then a positive index will insert after that indexed entry in - * the print areas list, while a negative index will insert before the indexed entry. - * Specifying an index value of 0, will always append the new print range at the end of the - * list. - * Print areas are numbered from 1 - * @param string $method Determines the method used when setting multiple print areas - * Default behaviour, or the "O" method, overwrites existing print area - * The "I" method, inserts the new print area before any specified index, or at the end of the list - * @return PHPExcel_Worksheet_PageSetup - * @throws PHPExcel_Exception - */ + $this->_orientation = $pValue; + return $this; + } + + /** + * Get Scale + * + * @return int? + */ + public function getScale() { + return $this->_scale; + } + + /** + * Set Scale + * + * Print scaling. Valid values range from 10 to 400 + * This setting is overridden when fitToWidth and/or fitToHeight are in use + * + * @param int? $pValue + * @param boolean $pUpdate Update fitToPage so scaling applies rather than fitToHeight / fitToWidth + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function setScale($pValue = 100, $pUpdate = true) { + // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, + // but it is apparently still able to handle any scale >= 0, where 0 results in 100 + if (($pValue >= 0) || is_null($pValue)) { + $this->_scale = $pValue; + if ($pUpdate) { + $this->_fitToPage = false; + } + } else { + throw new PHPExcel_Exception("Scale must not be negative"); + } + return $this; + } + + /** + * Get Fit To Page + * + * @return boolean + */ + public function getFitToPage() { + return $this->_fitToPage; + } + + /** + * Set Fit To Page + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_PageSetup + */ + public function setFitToPage($pValue = TRUE) { + $this->_fitToPage = $pValue; + return $this; + } + + /** + * Get Fit To Height + * + * @return int? + */ + public function getFitToHeight() { + return $this->_fitToHeight; + } + + /** + * Set Fit To Height + * + * @param int? $pValue + * @param boolean $pUpdate Update fitToPage so it applies rather than scaling + * @return PHPExcel_Worksheet_PageSetup + */ + public function setFitToHeight($pValue = 1, $pUpdate = TRUE) { + $this->_fitToHeight = $pValue; + if ($pUpdate) { + $this->_fitToPage = TRUE; + } + return $this; + } + + /** + * Get Fit To Width + * + * @return int? + */ + public function getFitToWidth() { + return $this->_fitToWidth; + } + + /** + * Set Fit To Width + * + * @param int? $pValue + * @param boolean $pUpdate Update fitToPage so it applies rather than scaling + * @return PHPExcel_Worksheet_PageSetup + */ + public function setFitToWidth($pValue = 1, $pUpdate = TRUE) { + $this->_fitToWidth = $pValue; + if ($pUpdate) { + $this->_fitToPage = TRUE; + } + return $this; + } + + /** + * Is Columns to repeat at left set? + * + * @return boolean + */ + public function isColumnsToRepeatAtLeftSet() { + if (is_array($this->_columnsToRepeatAtLeft)) { + if ($this->_columnsToRepeatAtLeft[0] != '' && $this->_columnsToRepeatAtLeft[1] != '') { + return true; + } + } + + return false; + } + + /** + * Get Columns to repeat at left + * + * @return array Containing start column and end column, empty array if option unset + */ + public function getColumnsToRepeatAtLeft() { + return $this->_columnsToRepeatAtLeft; + } + + /** + * Set Columns to repeat at left + * + * @param array $pValue Containing start column and end column, empty array if option unset + * @return PHPExcel_Worksheet_PageSetup + */ + public function setColumnsToRepeatAtLeft($pValue = null) { + if (is_array($pValue)) { + $this->_columnsToRepeatAtLeft = $pValue; + } + return $this; + } + + /** + * Set Columns to repeat at left by start and end + * + * @param string $pStart + * @param string $pEnd + * @return PHPExcel_Worksheet_PageSetup + */ + public function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A') { + $this->_columnsToRepeatAtLeft = array($pStart, $pEnd); + return $this; + } + + /** + * Is Rows to repeat at top set? + * + * @return boolean + */ + public function isRowsToRepeatAtTopSet() { + if (is_array($this->_rowsToRepeatAtTop)) { + if ($this->_rowsToRepeatAtTop[0] != 0 && $this->_rowsToRepeatAtTop[1] != 0) { + return true; + } + } + + return false; + } + + /** + * Get Rows to repeat at top + * + * @return array Containing start column and end column, empty array if option unset + */ + public function getRowsToRepeatAtTop() { + return $this->_rowsToRepeatAtTop; + } + + /** + * Set Rows to repeat at top + * + * @param array $pValue Containing start column and end column, empty array if option unset + * @return PHPExcel_Worksheet_PageSetup + */ + public function setRowsToRepeatAtTop($pValue = null) { + if (is_array($pValue)) { + $this->_rowsToRepeatAtTop = $pValue; + } + return $this; + } + + /** + * Set Rows to repeat at top by start and end + * + * @param int $pStart + * @param int $pEnd + * @return PHPExcel_Worksheet_PageSetup + */ + public function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1) { + $this->_rowsToRepeatAtTop = array($pStart, $pEnd); + return $this; + } + + /** + * Get center page horizontally + * + * @return bool + */ + public function getHorizontalCentered() { + return $this->_horizontalCentered; + } + + /** + * Set center page horizontally + * + * @param bool $value + * @return PHPExcel_Worksheet_PageSetup + */ + public function setHorizontalCentered($value = false) { + $this->_horizontalCentered = $value; + return $this; + } + + /** + * Get center page vertically + * + * @return bool + */ + public function getVerticalCentered() { + return $this->_verticalCentered; + } + + /** + * Set center page vertically + * + * @param bool $value + * @return PHPExcel_Worksheet_PageSetup + */ + public function setVerticalCentered($value = false) { + $this->_verticalCentered = $value; + return $this; + } + + /** + * Get print area + * + * @param int $index Identifier for a specific print area range if several ranges have been set + * Default behaviour, or a index value of 0, will return all ranges as a comma-separated string + * Otherwise, the specific range identified by the value of $index will be returned + * Print areas are numbered from 1 + * @throws PHPExcel_Exception + * @return string + */ + public function getPrintArea($index = 0) { + if ($index == 0) { + return $this->_printArea; + } + $printAreas = explode(',',$this->_printArea); + if (isset($printAreas[$index-1])) { + return $printAreas[$index-1]; + } + throw new PHPExcel_Exception("Requested Print Area does not exist"); + } + + /** + * Is print area set? + * + * @param int $index Identifier for a specific print area range if several ranges have been set + * Default behaviour, or an index value of 0, will identify whether any print range is set + * Otherwise, existence of the range identified by the value of $index will be returned + * Print areas are numbered from 1 + * @return boolean + */ + public function isPrintAreaSet($index = 0) { + if ($index == 0) { + return !is_null($this->_printArea); + } + $printAreas = explode(',',$this->_printArea); + return isset($printAreas[$index-1]); + } + + /** + * Clear a print area + * + * @param int $index Identifier for a specific print area range if several ranges have been set + * Default behaviour, or an index value of 0, will clear all print ranges that are set + * Otherwise, the range identified by the value of $index will be removed from the series + * Print areas are numbered from 1 + * @return PHPExcel_Worksheet_PageSetup + */ + public function clearPrintArea($index = 0) { + if ($index == 0) { + $this->_printArea = NULL; + } else { + $printAreas = explode(',',$this->_printArea); + if (isset($printAreas[$index-1])) { + unset($printAreas[$index-1]); + $this->_printArea = implode(',',$printAreas); + } + } + + return $this; + } + + /** + * Set print area. e.g. 'A1:D10' or 'A1:D10,G5:M20' + * + * @param string $value + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * When the method is "O"verwrite, then a positive integer index will overwrite that indexed + * entry in the print areas list; a negative index value will identify which entry to + * overwrite working bacward through the print area to the list, with the last entry as -1. + * Specifying an index value of 0, will overwrite <b>all</b> existing print ranges. + * When the method is "I"nsert, then a positive index will insert after that indexed entry in + * the print areas list, while a negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @param string $method Determines the method used when setting multiple print areas + * Default behaviour, or the "O" method, overwrites existing print area + * The "I" method, inserts the new print area before any specified index, or at the end of the list + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) { + if (strpos($value,'!') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not specify a worksheet.'); + } elseif (strpos($value,':') === false) { + throw new PHPExcel_Exception('Cell coordinate must be a range of cells.'); + } elseif (strpos($value,'$') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); + } + $value = strtoupper($value); + + if ($method == self::SETPRINTRANGE_OVERWRITE) { + if ($index == 0) { + $this->_printArea = $value; + } else { + $printAreas = explode(',',$this->_printArea); + if($index < 0) { + $index = count($printAreas) - abs($index) + 1; + } + if (($index <= 0) || ($index > count($printAreas))) { + throw new PHPExcel_Exception('Invalid index for setting print range.'); + } + $printAreas[$index-1] = $value; + $this->_printArea = implode(',',$printAreas); + } + } elseif($method == self::SETPRINTRANGE_INSERT) { + if ($index == 0) { + $this->_printArea .= ($this->_printArea == '') ? $value : ','.$value; + } else { + $printAreas = explode(',',$this->_printArea); + if($index < 0) { + $index = abs($index) - 1; + } + if ($index > count($printAreas)) { + throw new PHPExcel_Exception('Invalid index for setting print range.'); + } + $printAreas = array_merge(array_slice($printAreas,0,$index),array($value),array_slice($printAreas,$index)); + $this->_printArea = implode(',',$printAreas); + } + } else { + throw new PHPExcel_Exception('Invalid method for setting print range.'); + } + + return $this; + } + + /** + * Add a new print area (e.g. 'A1:D10' or 'A1:D10,G5:M20') to the list of print areas + * + * @param string $value + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * A positive index will insert after that indexed entry in the print areas list, while a + * negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function addPrintArea($value, $index = -1) { + return $this->setPrintArea($value, $index, self::SETPRINTRANGE_INSERT); + } + + /** + * Set print area + * + * @param int $column1 Column 1 + * @param int $row1 Row 1 + * @param int $column2 Column 2 + * @param int $row2 Row 2 + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * When the method is "O"verwrite, then a positive integer index will overwrite that indexed + * entry in the print areas list; a negative index value will identify which entry to + * overwrite working bacward through the print area to the list, with the last entry as -1. + * Specifying an index value of 0, will overwrite <b>all</b> existing print ranges. + * When the method is "I"nsert, then a positive index will insert after that indexed entry in + * the print areas list, while a negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @param string $method Determines the method used when setting multiple print areas + * Default behaviour, or the "O" method, overwrites existing print area + * The "I" method, inserts the new print area before any specified index, or at the end of the list + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ public function setPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) { - return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, $method); - } - - /** - * Add a new print area to the list of print areas - * - * @param int $column1 Start Column for the print area - * @param int $row1 Start Row for the print area - * @param int $column2 End Column for the print area - * @param int $row2 End Row for the print area - * @param int $index Identifier for a specific print area range allowing several ranges to be set - * A positive index will insert after that indexed entry in the print areas list, while a - * negative index will insert before the indexed entry. - * Specifying an index value of 0, will always append the new print range at the end of the - * list. - * Print areas are numbered from 1 - * @return PHPExcel_Worksheet_PageSetup - * @throws PHPExcel_Exception - */ + return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, $method); + } + + /** + * Add a new print area to the list of print areas + * + * @param int $column1 Start Column for the print area + * @param int $row1 Start Row for the print area + * @param int $column2 End Column for the print area + * @param int $row2 End Row for the print area + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * A positive index will insert after that indexed entry in the print areas list, while a + * negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ public function addPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = -1) { - return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, self::SETPRINTRANGE_INSERT); - } - - /** - * Get first page number - * - * @return int - */ + return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, self::SETPRINTRANGE_INSERT); + } + + /** + * Get first page number + * + * @return int + */ public function getFirstPageNumber() { - return $this->_firstPageNumber; + return $this->_firstPageNumber; } /** @@ -769,8 +769,8 @@ public function getFirstPageNumber() { * @return PHPExcel_Worksheet_HeaderFooter */ public function setFirstPageNumber($value = null) { - $this->_firstPageNumber = $value; - return $this; + $this->_firstPageNumber = $value; + return $this; } /** @@ -779,20 +779,20 @@ public function setFirstPageNumber($value = null) { * @return PHPExcel_Worksheet_HeaderFooter */ public function resetFirstPageNumber() { - return $this->setFirstPageNumber(null); - } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + return $this->setFirstPageNumber(null); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/Protection.php b/Classes/PHPExcel/Worksheet/Protection.php index 1290a9143..af3419889 100644 --- a/Classes/PHPExcel/Worksheet/Protection.php +++ b/Classes/PHPExcel/Worksheet/Protection.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -35,124 +35,124 @@ */ class PHPExcel_Worksheet_Protection { - /** - * Sheet - * - * @var boolean - */ - private $_sheet = false; - - /** - * Objects - * - * @var boolean - */ - private $_objects = false; - - /** - * Scenarios - * - * @var boolean - */ - private $_scenarios = false; - - /** - * Format cells - * - * @var boolean - */ - private $_formatCells = false; - - /** - * Format columns - * - * @var boolean - */ - private $_formatColumns = false; - - /** - * Format rows - * - * @var boolean - */ - private $_formatRows = false; - - /** - * Insert columns - * - * @var boolean - */ - private $_insertColumns = false; - - /** - * Insert rows - * - * @var boolean - */ - private $_insertRows = false; - - /** - * Insert hyperlinks - * - * @var boolean - */ - private $_insertHyperlinks = false; - - /** - * Delete columns - * - * @var boolean - */ - private $_deleteColumns = false; - - /** - * Delete rows - * - * @var boolean - */ - private $_deleteRows = false; - - /** - * Select locked cells - * - * @var boolean - */ - private $_selectLockedCells = false; - - /** - * Sort - * - * @var boolean - */ - private $_sort = false; - - /** - * AutoFilter - * - * @var boolean - */ - private $_autoFilter = false; - - /** - * Pivot tables - * - * @var boolean - */ - private $_pivotTables = false; - - /** - * Select unlocked cells - * - * @var boolean - */ - private $_selectUnlockedCells = false; - - /** - * Password - * - * @var string - */ - private $_password = ''; + /** + * Sheet + * + * @var boolean + */ + private $_sheet = false; + + /** + * Objects + * + * @var boolean + */ + private $_objects = false; + + /** + * Scenarios + * + * @var boolean + */ + private $_scenarios = false; + + /** + * Format cells + * + * @var boolean + */ + private $_formatCells = false; + + /** + * Format columns + * + * @var boolean + */ + private $_formatColumns = false; + + /** + * Format rows + * + * @var boolean + */ + private $_formatRows = false; + + /** + * Insert columns + * + * @var boolean + */ + private $_insertColumns = false; + + /** + * Insert rows + * + * @var boolean + */ + private $_insertRows = false; + + /** + * Insert hyperlinks + * + * @var boolean + */ + private $_insertHyperlinks = false; + + /** + * Delete columns + * + * @var boolean + */ + private $_deleteColumns = false; + + /** + * Delete rows + * + * @var boolean + */ + private $_deleteRows = false; + + /** + * Select locked cells + * + * @var boolean + */ + private $_selectLockedCells = false; + + /** + * Sort + * + * @var boolean + */ + private $_sort = false; + + /** + * AutoFilter + * + * @var boolean + */ + private $_autoFilter = false; + + /** + * Pivot tables + * + * @var boolean + */ + private $_pivotTables = false; + + /** + * Select unlocked cells + * + * @var boolean + */ + private $_selectUnlockedCells = false; + + /** + * Password + * + * @var string + */ + private $_password = ''; /** * Create a new PHPExcel_Worksheet_Protection @@ -167,22 +167,22 @@ public function __construct() * @return boolean */ function isProtectionEnabled() { - return $this->_sheet || - $this->_objects || - $this->_scenarios || - $this->_formatCells || - $this->_formatColumns || - $this->_formatRows || - $this->_insertColumns || - $this->_insertRows || - $this->_insertHyperlinks || - $this->_deleteColumns || - $this->_deleteRows || - $this->_selectLockedCells || - $this->_sort || - $this->_autoFilter || - $this->_pivotTables || - $this->_selectUnlockedCells; + return $this->_sheet || + $this->_objects || + $this->_scenarios || + $this->_formatCells || + $this->_formatColumns || + $this->_formatRows || + $this->_insertColumns || + $this->_insertRows || + $this->_insertHyperlinks || + $this->_deleteColumns || + $this->_deleteRows || + $this->_selectLockedCells || + $this->_sort || + $this->_autoFilter || + $this->_pivotTables || + $this->_selectUnlockedCells; } /** @@ -191,7 +191,7 @@ function isProtectionEnabled() { * @return boolean */ function getSheet() { - return $this->_sheet; + return $this->_sheet; } /** @@ -201,8 +201,8 @@ function getSheet() { * @return PHPExcel_Worksheet_Protection */ function setSheet($pValue = false) { - $this->_sheet = $pValue; - return $this; + $this->_sheet = $pValue; + return $this; } /** @@ -211,7 +211,7 @@ function setSheet($pValue = false) { * @return boolean */ function getObjects() { - return $this->_objects; + return $this->_objects; } /** @@ -221,8 +221,8 @@ function getObjects() { * @return PHPExcel_Worksheet_Protection */ function setObjects($pValue = false) { - $this->_objects = $pValue; - return $this; + $this->_objects = $pValue; + return $this; } /** @@ -231,7 +231,7 @@ function setObjects($pValue = false) { * @return boolean */ function getScenarios() { - return $this->_scenarios; + return $this->_scenarios; } /** @@ -241,8 +241,8 @@ function getScenarios() { * @return PHPExcel_Worksheet_Protection */ function setScenarios($pValue = false) { - $this->_scenarios = $pValue; - return $this; + $this->_scenarios = $pValue; + return $this; } /** @@ -251,7 +251,7 @@ function setScenarios($pValue = false) { * @return boolean */ function getFormatCells() { - return $this->_formatCells; + return $this->_formatCells; } /** @@ -261,8 +261,8 @@ function getFormatCells() { * @return PHPExcel_Worksheet_Protection */ function setFormatCells($pValue = false) { - $this->_formatCells = $pValue; - return $this; + $this->_formatCells = $pValue; + return $this; } /** @@ -271,7 +271,7 @@ function setFormatCells($pValue = false) { * @return boolean */ function getFormatColumns() { - return $this->_formatColumns; + return $this->_formatColumns; } /** @@ -281,8 +281,8 @@ function getFormatColumns() { * @return PHPExcel_Worksheet_Protection */ function setFormatColumns($pValue = false) { - $this->_formatColumns = $pValue; - return $this; + $this->_formatColumns = $pValue; + return $this; } /** @@ -291,7 +291,7 @@ function setFormatColumns($pValue = false) { * @return boolean */ function getFormatRows() { - return $this->_formatRows; + return $this->_formatRows; } /** @@ -301,8 +301,8 @@ function getFormatRows() { * @return PHPExcel_Worksheet_Protection */ function setFormatRows($pValue = false) { - $this->_formatRows = $pValue; - return $this; + $this->_formatRows = $pValue; + return $this; } /** @@ -311,7 +311,7 @@ function setFormatRows($pValue = false) { * @return boolean */ function getInsertColumns() { - return $this->_insertColumns; + return $this->_insertColumns; } /** @@ -321,8 +321,8 @@ function getInsertColumns() { * @return PHPExcel_Worksheet_Protection */ function setInsertColumns($pValue = false) { - $this->_insertColumns = $pValue; - return $this; + $this->_insertColumns = $pValue; + return $this; } /** @@ -331,7 +331,7 @@ function setInsertColumns($pValue = false) { * @return boolean */ function getInsertRows() { - return $this->_insertRows; + return $this->_insertRows; } /** @@ -341,8 +341,8 @@ function getInsertRows() { * @return PHPExcel_Worksheet_Protection */ function setInsertRows($pValue = false) { - $this->_insertRows = $pValue; - return $this; + $this->_insertRows = $pValue; + return $this; } /** @@ -351,7 +351,7 @@ function setInsertRows($pValue = false) { * @return boolean */ function getInsertHyperlinks() { - return $this->_insertHyperlinks; + return $this->_insertHyperlinks; } /** @@ -361,8 +361,8 @@ function getInsertHyperlinks() { * @return PHPExcel_Worksheet_Protection */ function setInsertHyperlinks($pValue = false) { - $this->_insertHyperlinks = $pValue; - return $this; + $this->_insertHyperlinks = $pValue; + return $this; } /** @@ -371,7 +371,7 @@ function setInsertHyperlinks($pValue = false) { * @return boolean */ function getDeleteColumns() { - return $this->_deleteColumns; + return $this->_deleteColumns; } /** @@ -381,8 +381,8 @@ function getDeleteColumns() { * @return PHPExcel_Worksheet_Protection */ function setDeleteColumns($pValue = false) { - $this->_deleteColumns = $pValue; - return $this; + $this->_deleteColumns = $pValue; + return $this; } /** @@ -391,7 +391,7 @@ function setDeleteColumns($pValue = false) { * @return boolean */ function getDeleteRows() { - return $this->_deleteRows; + return $this->_deleteRows; } /** @@ -401,8 +401,8 @@ function getDeleteRows() { * @return PHPExcel_Worksheet_Protection */ function setDeleteRows($pValue = false) { - $this->_deleteRows = $pValue; - return $this; + $this->_deleteRows = $pValue; + return $this; } /** @@ -411,7 +411,7 @@ function setDeleteRows($pValue = false) { * @return boolean */ function getSelectLockedCells() { - return $this->_selectLockedCells; + return $this->_selectLockedCells; } /** @@ -421,8 +421,8 @@ function getSelectLockedCells() { * @return PHPExcel_Worksheet_Protection */ function setSelectLockedCells($pValue = false) { - $this->_selectLockedCells = $pValue; - return $this; + $this->_selectLockedCells = $pValue; + return $this; } /** @@ -431,7 +431,7 @@ function setSelectLockedCells($pValue = false) { * @return boolean */ function getSort() { - return $this->_sort; + return $this->_sort; } /** @@ -441,8 +441,8 @@ function getSort() { * @return PHPExcel_Worksheet_Protection */ function setSort($pValue = false) { - $this->_sort = $pValue; - return $this; + $this->_sort = $pValue; + return $this; } /** @@ -451,7 +451,7 @@ function setSort($pValue = false) { * @return boolean */ function getAutoFilter() { - return $this->_autoFilter; + return $this->_autoFilter; } /** @@ -461,8 +461,8 @@ function getAutoFilter() { * @return PHPExcel_Worksheet_Protection */ function setAutoFilter($pValue = false) { - $this->_autoFilter = $pValue; - return $this; + $this->_autoFilter = $pValue; + return $this; } /** @@ -471,7 +471,7 @@ function setAutoFilter($pValue = false) { * @return boolean */ function getPivotTables() { - return $this->_pivotTables; + return $this->_pivotTables; } /** @@ -481,8 +481,8 @@ function getPivotTables() { * @return PHPExcel_Worksheet_Protection */ function setPivotTables($pValue = false) { - $this->_pivotTables = $pValue; - return $this; + $this->_pivotTables = $pValue; + return $this; } /** @@ -491,7 +491,7 @@ function setPivotTables($pValue = false) { * @return boolean */ function getSelectUnlockedCells() { - return $this->_selectUnlockedCells; + return $this->_selectUnlockedCells; } /** @@ -501,8 +501,8 @@ function getSelectUnlockedCells() { * @return PHPExcel_Worksheet_Protection */ function setSelectUnlockedCells($pValue = false) { - $this->_selectUnlockedCells = $pValue; - return $this; + $this->_selectUnlockedCells = $pValue; + return $this; } /** @@ -511,35 +511,35 @@ function setSelectUnlockedCells($pValue = false) { * @return string */ function getPassword() { - return $this->_password; + return $this->_password; } /** * Set Password * - * @param string $pValue - * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @param string $pValue + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true * @return PHPExcel_Worksheet_Protection */ function setPassword($pValue = '', $pAlreadyHashed = false) { - if (!$pAlreadyHashed) { - $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); - } - $this->_password = $pValue; - return $this; - } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + if (!$pAlreadyHashed) { + $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); + } + $this->_password = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Worksheet/SheetView.php b/Classes/PHPExcel/Worksheet/SheetView.php index 2396ddaa3..f2448e2bc 100644 --- a/Classes/PHPExcel/Worksheet/SheetView.php +++ b/Classes/PHPExcel/Worksheet/SheetView.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Worksheet * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -36,43 +36,43 @@ class PHPExcel_Worksheet_SheetView { - /* Sheet View types */ - const SHEETVIEW_NORMAL = 'normal'; - const SHEETVIEW_PAGE_LAYOUT = 'pageLayout'; - const SHEETVIEW_PAGE_BREAK_PREVIEW = 'pageBreakPreview'; - - private static $_sheetViewTypes = array( - self::SHEETVIEW_NORMAL, - self::SHEETVIEW_PAGE_LAYOUT, - self::SHEETVIEW_PAGE_BREAK_PREVIEW, - ); - - /** - * ZoomScale - * - * Valid values range from 10 to 400. - * - * @var int - */ - private $_zoomScale = 100; - - /** - * ZoomScaleNormal - * - * Valid values range from 10 to 400. - * - * @var int - */ - private $_zoomScaleNormal = 100; - - /** - * View - * - * Valid values range from 10 to 400. - * - * @var string - */ - private $_sheetviewType = self::SHEETVIEW_NORMAL; + /* Sheet View types */ + const SHEETVIEW_NORMAL = 'normal'; + const SHEETVIEW_PAGE_LAYOUT = 'pageLayout'; + const SHEETVIEW_PAGE_BREAK_PREVIEW = 'pageBreakPreview'; + + private static $_sheetViewTypes = array( + self::SHEETVIEW_NORMAL, + self::SHEETVIEW_PAGE_LAYOUT, + self::SHEETVIEW_PAGE_BREAK_PREVIEW, + ); + + /** + * ZoomScale + * + * Valid values range from 10 to 400. + * + * @var int + */ + private $_zoomScale = 100; + + /** + * ZoomScaleNormal + * + * Valid values range from 10 to 400. + * + * @var int + */ + private $_zoomScaleNormal = 100; + + /** + * View + * + * Valid values range from 10 to 400. + * + * @var string + */ + private $_sheetviewType = self::SHEETVIEW_NORMAL; /** * Create a new PHPExcel_Worksheet_SheetView @@ -81,108 +81,108 @@ public function __construct() { } - /** - * Get ZoomScale - * - * @return int - */ - public function getZoomScale() { - return $this->_zoomScale; - } - - /** - * Set ZoomScale - * - * Valid values range from 10 to 400. - * - * @param int $pValue - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_SheetView - */ - public function setZoomScale($pValue = 100) { - // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, - // but it is apparently still able to handle any scale >= 1 - if (($pValue >= 1) || is_null($pValue)) { - $this->_zoomScale = $pValue; - } else { - throw new PHPExcel_Exception("Scale must be greater than or equal to 1."); - } - return $this; - } - - /** - * Get ZoomScaleNormal - * - * @return int - */ - public function getZoomScaleNormal() { - return $this->_zoomScaleNormal; - } - - /** - * Set ZoomScale - * - * Valid values range from 10 to 400. - * - * @param int $pValue - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_SheetView - */ - public function setZoomScaleNormal($pValue = 100) { - if (($pValue >= 1) || is_null($pValue)) { - $this->_zoomScaleNormal = $pValue; - } else { - throw new PHPExcel_Exception("Scale must be greater than or equal to 1."); - } - return $this; - } - - /** - * Get View - * - * @return string - */ - public function getView() { - return $this->_sheetviewType; - } - - /** - * Set View - * - * Valid values are - * 'normal' self::SHEETVIEW_NORMAL - * 'pageLayout' self::SHEETVIEW_PAGE_LAYOUT - * 'pageBreakPreview' self::SHEETVIEW_PAGE_BREAK_PREVIEW - * - * @param string $pValue - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_SheetView - */ - public function setView($pValue = NULL) { - // MS Excel 2007 allows setting the view to 'normal', 'pageLayout' or 'pageBreakPreview' - // via the user interface - if ($pValue === NULL) - $pValue = self::SHEETVIEW_NORMAL; - if (in_array($pValue, self::$_sheetViewTypes)) { - $this->_sheetviewType = $pValue; - } else { - throw new PHPExcel_Exception("Invalid sheetview layout type."); - } - - return $this; - } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } + /** + * Get ZoomScale + * + * @return int + */ + public function getZoomScale() { + return $this->_zoomScale; + } + + /** + * Set ZoomScale + * + * Valid values range from 10 to 400. + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_SheetView + */ + public function setZoomScale($pValue = 100) { + // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, + // but it is apparently still able to handle any scale >= 1 + if (($pValue >= 1) || is_null($pValue)) { + $this->_zoomScale = $pValue; + } else { + throw new PHPExcel_Exception("Scale must be greater than or equal to 1."); + } + return $this; + } + + /** + * Get ZoomScaleNormal + * + * @return int + */ + public function getZoomScaleNormal() { + return $this->_zoomScaleNormal; + } + + /** + * Set ZoomScale + * + * Valid values range from 10 to 400. + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_SheetView + */ + public function setZoomScaleNormal($pValue = 100) { + if (($pValue >= 1) || is_null($pValue)) { + $this->_zoomScaleNormal = $pValue; + } else { + throw new PHPExcel_Exception("Scale must be greater than or equal to 1."); + } + return $this; + } + + /** + * Get View + * + * @return string + */ + public function getView() { + return $this->_sheetviewType; + } + + /** + * Set View + * + * Valid values are + * 'normal' self::SHEETVIEW_NORMAL + * 'pageLayout' self::SHEETVIEW_PAGE_LAYOUT + * 'pageBreakPreview' self::SHEETVIEW_PAGE_BREAK_PREVIEW + * + * @param string $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_SheetView + */ + public function setView($pValue = NULL) { + // MS Excel 2007 allows setting the view to 'normal', 'pageLayout' or 'pageBreakPreview' + // via the user interface + if ($pValue === NULL) + $pValue = self::SHEETVIEW_NORMAL; + if (in_array($pValue, self::$_sheetViewTypes)) { + $this->_sheetviewType = $pValue; + } else { + throw new PHPExcel_Exception("Invalid sheetview layout type."); + } + + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php index 1ade577e5..a25ecd6a6 100644 --- a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php +++ b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php b/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php index c85e36a02..f1e98a16e 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_OpenDocument * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/Classes/PHPExcel/Writer/OpenDocument/Content.php b/Classes/PHPExcel/Writer/OpenDocument/Content.php index 1f6ddc4d2..2e1986a7b 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Content.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Content.php @@ -21,7 +21,7 @@ * @category PHPExcel * @package PHPExcel_Writer_OpenDocument * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ diff --git a/composer.json b/composer.json index da7faa0eb..a280b88e3 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "ext-xmlwriter": "*" }, "require-dev": { - "squizlabs/php_codesniffer": "1.*" + "squizlabs/php_codesniffer": "2.*" }, "recommend": { "ext-zip": "*", From 95b3fb024af4781bf0c5b2be8bc5d1fc95484cdb Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Tue, 12 May 2015 12:43:52 +0200 Subject: [PATCH 353/467] Validation PSR-2 : Fixes --- Classes/PHPExcel/Writer/Excel5/Xf.php | 69 +++++++++++++---------- Classes/PHPExcel/Writer/HTML.php | 81 +++++++++++++-------------- Classes/PHPExcel/Writer/IWriter.php | 1 - 3 files changed, 79 insertions(+), 72 deletions(-) diff --git a/Classes/PHPExcel/Writer/Excel5/Xf.php b/Classes/PHPExcel/Writer/Excel5/Xf.php index 7347aabb7..6d953f816 100644 --- a/Classes/PHPExcel/Writer/Excel5/Xf.php +++ b/Classes/PHPExcel/Writer/Excel5/Xf.php @@ -166,7 +166,7 @@ public function __construct(PHPExcel_Style $style = null) * * @return string The XF record */ - function writeXf() + public function writeXf() { // Set the type of the XF record and some of the attributes. if ($this->_isStyleXf) { @@ -249,18 +249,14 @@ function writeXf() $border2 |= self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21; $border2 |= self::_mapFillType($this->_style->getFill()->getFillType()) << 26; - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); //BIFF8 options: identation, shrinkToFit and text direction $biff8_options = $this->_style->getAlignment()->getIndent(); $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4; $data = pack("vvvC", $ifnt, $ifmt, $style, $align); - $data .= pack("CCC" - , self::_mapTextRotation($this->_style->getAlignment()->getTextRotation()) - , $biff8_options - , $used_attrib - ); + $data .= pack("CCC", self::_mapTextRotation($this->_style->getAlignment()->getTextRotation()), $biff8_options, $used_attrib); $data .= pack("VVv", $border1, $border2, $icv); return($header . $data); @@ -282,7 +278,7 @@ public function setIsStyleXf($value) * @access public * @param int $colorIndex Color index */ - function setBottomColor($colorIndex) + public function setBottomColor($colorIndex) { $this->_bottom_color = $colorIndex; } @@ -293,7 +289,7 @@ function setBottomColor($colorIndex) * @access public * @param int $colorIndex Color index */ - function setTopColor($colorIndex) + public function setTopColor($colorIndex) { $this->_top_color = $colorIndex; } @@ -304,7 +300,7 @@ function setTopColor($colorIndex) * @access public * @param int $colorIndex Color index */ - function setLeftColor($colorIndex) + public function setLeftColor($colorIndex) { $this->_left_color = $colorIndex; } @@ -315,7 +311,7 @@ function setLeftColor($colorIndex) * @access public * @param int $colorIndex Color index */ - function setRightColor($colorIndex) + public function setRightColor($colorIndex) { $this->_right_color = $colorIndex; } @@ -326,7 +322,7 @@ function setRightColor($colorIndex) * @access public * @param int $colorIndex Color index */ - function setDiagColor($colorIndex) + public function setDiagColor($colorIndex) { $this->_diag_color = $colorIndex; } @@ -338,7 +334,7 @@ function setDiagColor($colorIndex) * @access public * @param int $colorIndex Color index */ - function setFgColor($colorIndex) + public function setFgColor($colorIndex) { $this->_fg_color = $colorIndex; } @@ -349,7 +345,7 @@ function setFgColor($colorIndex) * @access public * @param int $colorIndex Color index */ - function setBgColor($colorIndex) + public function setBgColor($colorIndex) { $this->_bg_color = $colorIndex; } @@ -361,7 +357,7 @@ function setBgColor($colorIndex) * @access public * @param integer $numberFormatIndex Index to format record */ - function setNumberFormatIndex($numberFormatIndex) + public function setNumberFormatIndex($numberFormatIndex) { $this->_numberFormatIndex = $numberFormatIndex; } @@ -403,9 +399,11 @@ public function setFontIndex($value) * @param string $borderStyle * @return int */ - private static function _mapBorderStyle($borderStyle) { - if (isset(self::$_mapBorderStyle[$borderStyle])) + private static function _mapBorderStyle($borderStyle) + { + if (isset(self::$_mapBorderStyle[$borderStyle])) { return self::$_mapBorderStyle[$borderStyle]; + } return 0x00; } @@ -442,9 +440,11 @@ private static function _mapBorderStyle($borderStyle) { * @param string $fillType * @return int */ - private static function _mapFillType($fillType) { - if (isset(self::$_mapFillType[$fillType])) + private static function _mapFillType($fillType) + { + if (isset(self::$_mapFillType[$fillType])) { return self::$_mapFillType[$fillType]; + } return 0x00; } @@ -469,8 +469,9 @@ private static function _mapFillType($fillType) { */ private function _mapHAlign($hAlign) { - if (isset(self::$_mapHAlign[$hAlign])) + if (isset(self::$_mapHAlign[$hAlign])) { return self::$_mapHAlign[$hAlign]; + } return 0; } @@ -491,8 +492,9 @@ private function _mapHAlign($hAlign) * @return int */ private static function _mapVAlign($vAlign) { - if (isset(self::$_mapVAlign[$vAlign])) + if (isset(self::$_mapVAlign[$vAlign])) { return self::$_mapVAlign[$vAlign]; + } return 2; } @@ -522,10 +524,14 @@ private static function _mapTextRotation($textRotation) { */ private static function _mapLocked($locked) { switch ($locked) { - case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 1; - case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; - case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; - default: return 1; + case PHPExcel_Style_Protection::PROTECTION_INHERIT: + return 1; + case PHPExcel_Style_Protection::PROTECTION_PROTECTED: + return 1; + case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: + return 0; + default: + return 1; } } @@ -537,11 +543,14 @@ private static function _mapLocked($locked) { */ private static function _mapHidden($hidden) { switch ($hidden) { - case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 0; - case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; - case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; - default: return 0; + case PHPExcel_Style_Protection::PROTECTION_INHERIT: + return 0; + case PHPExcel_Style_Protection::PROTECTION_PROTECTED: + return 1; + case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: + return 0; + default: + return 0; } } - } diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 99a68630a..4821cf06a 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -944,7 +944,7 @@ private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) $css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical()); if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) { $css['text-align'] = $textAlign; - if (in_array($textAlign,array('left','right'))) { + if (in_array($textAlign,array('left', 'right'))) { $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px'; } } @@ -1015,7 +1015,7 @@ private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) { // Create CSS // $css = $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); - // Create CSS - add !important to non-none border styles for merged cells + // Create CSS - add !important to non-none border styles for merged cells $borderStyle = $this->_mapBorderStyle($pStyle->getBorderStyle()); $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); @@ -1265,10 +1265,9 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow } // General horizontal alignment: Actual horizontal alignment depends on dataType - $sharedStyle = $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() ); + $sharedStyle = $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex()); if ($sharedStyle->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL - && isset($this->_cssStyles['.' . $cell->getDataType()]['text-align'])) - { + && isset($this->_cssStyles['.' . $cell->getDataType()]['text-align'])) { $cssClass['text-align'] = $this->_cssStyles['.' . $cell->getDataType()]['text-align']; } } @@ -1303,39 +1302,39 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow if ($writeCell) { // Column start $html .= ' <' . $cellType; - if (!$this->_useInlineCss) { - $html .= ' class="' . $cssClass . '"'; - } else { - //** Necessary redundant code for the sake of PHPExcel_Writer_PDF ** - // We must explicitly write the width of the <td> element because TCPDF - // does not recognize e.g. <col style="width:42pt"> - $width = 0; - $i = $colNum - 1; - $e = $colNum + $colSpan - 1; - while ($i++ < $e) { - if (isset($this->_columnWidths[$sheetIndex][$i])) { - $width += $this->_columnWidths[$sheetIndex][$i]; - } - } - $cssClass['width'] = $width . 'pt'; - - // We must also explicitly write the height of the <td> element because TCPDF - // does not recognize e.g. <tr style="height:50pt"> - if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) { - $height = $this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height']; - $cssClass['height'] = $height; + if (!$this->_useInlineCss) { + $html .= ' class="' . $cssClass . '"'; + } else { + //** Necessary redundant code for the sake of PHPExcel_Writer_PDF ** + // We must explicitly write the width of the <td> element because TCPDF + // does not recognize e.g. <col style="width:42pt"> + $width = 0; + $i = $colNum - 1; + $e = $colNum + $colSpan - 1; + while ($i++ < $e) { + if (isset($this->_columnWidths[$sheetIndex][$i])) { + $width += $this->_columnWidths[$sheetIndex][$i]; } - //** end of redundant code ** - - $html .= ' style="' . $this->_assembleCSS($cssClass) . '"'; } - if ($colSpan > 1) { - $html .= ' colspan="' . $colSpan . '"'; - } - if ($rowSpan > 1) { - $html .= ' rowspan="' . $rowSpan . '"'; + $cssClass['width'] = $width . 'pt'; + + // We must also explicitly write the height of the <td> element because TCPDF + // does not recognize e.g. <tr style="height:50pt"> + if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) { + $height = $this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height']; + $cssClass['height'] = $height; } - $html .= '>'; + //** end of redundant code ** + + $html .= ' style="' . $this->_assembleCSS($cssClass) . '"'; + } + if ($colSpan > 1) { + $html .= ' colspan="' . $colSpan . '"'; + } + if ($rowSpan > 1) { + $html .= ' rowspan="' . $rowSpan . '"'; + } + $html .= '>'; // Image? $html .= $this->_writeImageInCell($pSheet, $coordinate); @@ -1510,13 +1509,13 @@ private function _calculateSpans() // loop through the individual cells in the individual merge $r = $fr - 1; - while($r++ < $lr) { + while ($r++ < $lr) { // also, flag this row as a HTML row that is candidate to be omitted $candidateSpannedRow[$r] = $r; $c = $fc - 1; - while($c++ < $lc) { - if ( !($c == $fc && $r == $fr) ) { + while ($c++ < $lc) { + if (!($c == $fc && $r == $fr)) { // not the upper-left cell (should not be written in HTML) $this->_isSpannedCell[$sheetIndex][$r][$c] = array( 'baseCell' => array($fr, $fc), @@ -1546,15 +1545,15 @@ private function _calculateSpans() } // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1 - if ( isset($this->_isSpannedRow[$sheetIndex]) ) { + if (isset($this->_isSpannedRow[$sheetIndex])) { foreach ($this->_isSpannedRow[$sheetIndex] as $rowIndex) { $adjustedBaseCells = array(); $c = -1; $e = $countColumns - 1; - while($c++ < $e) { + while ($c++ < $e) { $baseCell = $this->_isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell']; - if ( !in_array($baseCell, $adjustedBaseCells) ) { + if (!in_array($baseCell, $adjustedBaseCells)) { // subtract rowspan by 1 --$this->_isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan']; $adjustedBaseCells[] = $baseCell; diff --git a/Classes/PHPExcel/Writer/IWriter.php b/Classes/PHPExcel/Writer/IWriter.php index fd993db64..c7cfe7405 100644 --- a/Classes/PHPExcel/Writer/IWriter.php +++ b/Classes/PHPExcel/Writer/IWriter.php @@ -34,5 +34,4 @@ interface PHPExcel_Writer_IWriter * @throws PHPExcel_Writer_Exception */ public function save($pFilename = null); - } From 661ff77749c0dd4327952c28333d61f157db725b Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Tue, 12 May 2015 13:17:41 +0200 Subject: [PATCH 354/467] Validation PSR-2 : Fixes --- Classes/PHPExcel/Chart/DataSeries.php | 84 +- Classes/PHPExcel/Chart/Layout.php | 143 +- Classes/PHPExcel/Chart/PlotArea.php | 26 +- Classes/PHPExcel/Chart/Properties.php | 654 ++++---- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 1495 ++++++++++++------ 5 files changed, 1538 insertions(+), 864 deletions(-) diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index 711f16cee..c5ddc0955 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -166,7 +166,8 @@ public function __construct($plotType = null, $plotGrouping = null, $plotOrder = * * @return string */ - public function getPlotType() { + public function getPlotType() + { return $this->_plotType; } @@ -176,7 +177,8 @@ public function getPlotType() { * @param string $plotType * @return PHPExcel_Chart_DataSeries */ - public function setPlotType($plotType = '') { + public function setPlotType($plotType = '') + { $this->_plotType = $plotType; return $this; } @@ -186,7 +188,8 @@ public function setPlotType($plotType = '') { * * @return string */ - public function getPlotGrouping() { + public function getPlotGrouping() + { return $this->_plotGrouping; } @@ -196,7 +199,8 @@ public function getPlotGrouping() { * @param string $groupingType * @return PHPExcel_Chart_DataSeries */ - public function setPlotGrouping($groupingType = null) { + public function setPlotGrouping($groupingType = null) + { $this->_plotGrouping = $groupingType; return $this; } @@ -206,7 +210,8 @@ public function setPlotGrouping($groupingType = null) { * * @return string */ - public function getPlotDirection() { + public function getPlotDirection() + { return $this->_plotDirection; } @@ -216,7 +221,8 @@ public function getPlotDirection() { * @param string $plotDirection * @return PHPExcel_Chart_DataSeries */ - public function setPlotDirection($plotDirection = null) { + public function setPlotDirection($plotDirection = null) + { $this->_plotDirection = $plotDirection; return $this; } @@ -226,7 +232,8 @@ public function setPlotDirection($plotDirection = null) { * * @return string */ - public function getPlotOrder() { + public function getPlotOrder() + { return $this->_plotOrder; } @@ -235,7 +242,8 @@ public function getPlotOrder() { * * @return array of PHPExcel_Chart_DataSeriesValues */ - public function getPlotLabels() { + public function getPlotLabels() + { return $this->_plotLabel; } @@ -244,11 +252,12 @@ public function getPlotLabels() { * * @return PHPExcel_Chart_DataSeriesValues */ - public function getPlotLabelByIndex($index) { + public function getPlotLabelByIndex($index) + { $keys = array_keys($this->_plotLabel); - if (in_array($index,$keys)) { + if (in_array($index, $keys)) { return $this->_plotLabel[$index]; - } elseif(isset($keys[$index])) { + } elseif (isset($keys[$index])) { return $this->_plotLabel[$keys[$index]]; } return false; @@ -259,7 +268,8 @@ public function getPlotLabelByIndex($index) { * * @return array of PHPExcel_Chart_DataSeriesValues */ - public function getPlotCategories() { + public function getPlotCategories() + { return $this->_plotCategory; } @@ -268,11 +278,12 @@ public function getPlotCategories() { * * @return PHPExcel_Chart_DataSeriesValues */ - public function getPlotCategoryByIndex($index) { + public function getPlotCategoryByIndex($index) + { $keys = array_keys($this->_plotCategory); - if (in_array($index,$keys)) { + if (in_array($index, $keys)) { return $this->_plotCategory[$index]; - } elseif(isset($keys[$index])) { + } elseif (isset($keys[$index])) { return $this->_plotCategory[$keys[$index]]; } return false; @@ -283,7 +294,8 @@ public function getPlotCategoryByIndex($index) { * * @return string */ - public function getPlotStyle() { + public function getPlotStyle() + { return $this->_plotStyle; } @@ -293,7 +305,8 @@ public function getPlotStyle() { * @param string $plotStyle * @return PHPExcel_Chart_DataSeries */ - public function setPlotStyle($plotStyle = null) { + public function setPlotStyle($plotStyle = null) + { $this->_plotStyle = $plotStyle; return $this; } @@ -303,7 +316,8 @@ public function setPlotStyle($plotStyle = null) { * * @return array of PHPExcel_Chart_DataSeriesValues */ - public function getPlotValues() { + public function getPlotValues() + { return $this->_plotValues; } @@ -312,11 +326,12 @@ public function getPlotValues() { * * @return PHPExcel_Chart_DataSeriesValues */ - public function getPlotValuesByIndex($index) { + public function getPlotValuesByIndex($index) + { $keys = array_keys($this->_plotValues); - if (in_array($index,$keys)) { + if (in_array($index, $keys)) { return $this->_plotValues[$index]; - } elseif(isset($keys[$index])) { + } elseif (isset($keys[$index])) { return $this->_plotValues[$keys[$index]]; } return false; @@ -327,7 +342,8 @@ public function getPlotValuesByIndex($index) { * * @return integer */ - public function getPlotSeriesCount() { + public function getPlotSeriesCount() + { return count($this->_plotValues); } @@ -336,7 +352,8 @@ public function getPlotSeriesCount() { * * @return boolean */ - public function getSmoothLine() { + public function getSmoothLine() + { return $this->_smoothLine; } @@ -346,23 +363,28 @@ public function getSmoothLine() { * @param boolean $smoothLine * @return PHPExcel_Chart_DataSeries */ - public function setSmoothLine($smoothLine = TRUE) { + public function setSmoothLine($smoothLine = true) + { $this->_smoothLine = $smoothLine; return $this; } - public function refresh(PHPExcel_Worksheet $worksheet) { + public function refresh(PHPExcel_Worksheet $worksheet) + { foreach($this->_plotValues as $plotValues) { - if ($plotValues !== NULL) - $plotValues->refresh($worksheet, TRUE); + if ($plotValues !== null) { + $plotValues->refresh($worksheet, true); + } } foreach($this->_plotLabel as $plotValues) { - if ($plotValues !== NULL) - $plotValues->refresh($worksheet, TRUE); + if ($plotValues !== null) { + $plotValues->refresh($worksheet, true); + } } foreach($this->_plotCategory as $plotValues) { - if ($plotValues !== NULL) - $plotValues->refresh($worksheet, FALSE); + if ($plotValues !== null) { + $plotValues->refresh($worksheet, false); + } } } diff --git a/Classes/PHPExcel/Chart/Layout.php b/Classes/PHPExcel/Chart/Layout.php index d524e224f..53a447c95 100644 --- a/Classes/PHPExcel/Chart/Layout.php +++ b/Classes/PHPExcel/Chart/Layout.php @@ -40,49 +40,49 @@ class PHPExcel_Chart_Layout * * @var string */ - private $_layoutTarget = NULL; + private $_layoutTarget = null; /** * X Mode * * @var string */ - private $_xMode = NULL; + private $_xMode = null; /** * Y Mode * * @var string */ - private $_yMode = NULL; + private $_yMode = null; /** * X-Position * * @var float */ - private $_xPos = NULL; + private $_xPos = null; /** * Y-Position * * @var float */ - private $_yPos = NULL; + private $_yPos = null; /** * width * * @var float */ - private $_width = NULL; + private $_width = null; /** * height * * @var float */ - private $_height = NULL; + private $_height = null; /** * show legend key @@ -90,7 +90,7 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showLegendKey = NULL; + private $_showLegendKey = null; /** * show value @@ -98,7 +98,7 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showVal = NULL; + private $_showVal = null; /** * show category name @@ -106,7 +106,7 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showCatName = NULL; + private $_showCatName = null; /** * show data series name @@ -114,7 +114,7 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showSerName = NULL; + private $_showSerName = null; /** * show percentage @@ -122,14 +122,14 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showPercent = NULL; + private $_showPercent = null; /** * show bubble size * * @var boolean */ - private $_showBubbleSize = NULL; + private $_showBubbleSize = null; /** * show leader lines @@ -137,21 +137,35 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showLeaderLines = NULL; + private $_showLeaderLines = null; /** * Create a new PHPExcel_Chart_Layout */ - public function __construct($layout=array()) + public function __construct($layout = array()) { - if (isset($layout['layoutTarget'])) { $this->_layoutTarget = $layout['layoutTarget']; } - if (isset($layout['xMode'])) { $this->_xMode = $layout['xMode']; } - if (isset($layout['yMode'])) { $this->_yMode = $layout['yMode']; } - if (isset($layout['x'])) { $this->_xPos = (float) $layout['x']; } - if (isset($layout['y'])) { $this->_yPos = (float) $layout['y']; } - if (isset($layout['w'])) { $this->_width = (float) $layout['w']; } - if (isset($layout['h'])) { $this->_height = (float) $layout['h']; } + if (isset($layout['layoutTarget'])) { + $this->_layoutTarget = $layout['layoutTarget']; + } + if (isset($layout['xMode'])) { + $this->_xMode = $layout['xMode']; + } + if (isset($layout['yMode'])) { + $this->_yMode = $layout['yMode']; + } + if (isset($layout['x'])) { + $this->_xPos = (float) $layout['x']; + } + if (isset($layout['y'])) { + $this->_yPos = (float) $layout['y']; + } + if (isset($layout['w'])) { + $this->_width = (float) $layout['w']; + } + if (isset($layout['h'])) { + $this->_height = (float) $layout['h']; + } } /** @@ -159,7 +173,8 @@ public function __construct($layout=array()) * * @return string */ - public function getLayoutTarget() { + public function getLayoutTarget() + { return $this->_layoutTarget; } @@ -169,7 +184,8 @@ public function getLayoutTarget() { * @param Layout Target $value * @return PHPExcel_Chart_Layout */ - public function setLayoutTarget($value) { + public function setLayoutTarget($value) + { $this->_layoutTarget = $value; return $this; } @@ -179,7 +195,8 @@ public function setLayoutTarget($value) { * * @return string */ - public function getXMode() { + public function getXMode() + { return $this->_xMode; } @@ -189,7 +206,8 @@ public function getXMode() { * @param X-Mode $value * @return PHPExcel_Chart_Layout */ - public function setXMode($value) { + public function setXMode($value) + { $this->_xMode = $value; return $this; } @@ -199,7 +217,8 @@ public function setXMode($value) { * * @return string */ - public function getYMode() { + public function getYMode() + { return $this->_yMode; } @@ -209,7 +228,8 @@ public function getYMode() { * @param Y-Mode $value * @return PHPExcel_Chart_Layout */ - public function setYMode($value) { + public function setYMode($value) + { $this->_yMode = $value; return $this; } @@ -219,7 +239,8 @@ public function setYMode($value) { * * @return number */ - public function getXPosition() { + public function getXPosition() + { return $this->_xPos; } @@ -229,7 +250,8 @@ public function getXPosition() { * @param X-Position $value * @return PHPExcel_Chart_Layout */ - public function setXPosition($value) { + public function setXPosition($value) + { $this->_xPos = $value; return $this; } @@ -239,7 +261,8 @@ public function setXPosition($value) { * * @return number */ - public function getYPosition() { + public function getYPosition() + { return $this->_yPos; } @@ -249,7 +272,8 @@ public function getYPosition() { * @param Y-Position $value * @return PHPExcel_Chart_Layout */ - public function setYPosition($value) { + public function setYPosition($value) + { $this->_yPos = $value; return $this; } @@ -259,7 +283,8 @@ public function setYPosition($value) { * * @return number */ - public function getWidth() { + public function getWidth() + { return $this->_width; } @@ -269,7 +294,8 @@ public function getWidth() { * @param Width $value * @return PHPExcel_Chart_Layout */ - public function setWidth($value) { + public function setWidth($value) + { $this->_width = $value; return $this; } @@ -279,7 +305,8 @@ public function setWidth($value) { * * @return number */ - public function getHeight() { + public function getHeight() + { return $this->_height; } @@ -289,7 +316,8 @@ public function getHeight() { * @param Height $value * @return PHPExcel_Chart_Layout */ - public function setHeight($value) { + public function setHeight($value) + { $this->_height = $value; return $this; } @@ -300,7 +328,8 @@ public function setHeight($value) { * * @return boolean */ - public function getShowLegendKey() { + public function getShowLegendKey() + { return $this->_showLegendKey; } @@ -311,7 +340,8 @@ public function getShowLegendKey() { * @param boolean $value Show legend key * @return PHPExcel_Chart_Layout */ - public function setShowLegendKey($value) { + public function setShowLegendKey($value) + { $this->_showLegendKey = $value; return $this; } @@ -321,7 +351,8 @@ public function setShowLegendKey($value) { * * @return boolean */ - public function getShowVal() { + public function getShowVal() + { return $this->_showVal; } @@ -332,7 +363,8 @@ public function getShowVal() { * @param boolean $value Show val * @return PHPExcel_Chart_Layout */ - public function setShowVal($value) { + public function setShowVal($value) + { $this->_showVal = $value; return $this; } @@ -342,7 +374,8 @@ public function setShowVal($value) { * * @return boolean */ - public function getShowCatName() { + public function getShowCatName() + { return $this->_showCatName; } @@ -353,7 +386,8 @@ public function getShowCatName() { * @param boolean $value Show cat name * @return PHPExcel_Chart_Layout */ - public function setShowCatName($value) { + public function setShowCatName($value) + { $this->_showCatName = $value; return $this; } @@ -363,7 +397,8 @@ public function setShowCatName($value) { * * @return boolean */ - public function getShowSerName() { + public function getShowSerName() + { return $this->_showSerName; } @@ -374,7 +409,8 @@ public function getShowSerName() { * @param boolean $value Show series name * @return PHPExcel_Chart_Layout */ - public function setShowSerName($value) { + public function setShowSerName($value) + { $this->_showSerName = $value; return $this; } @@ -384,7 +420,8 @@ public function setShowSerName($value) { * * @return boolean */ - public function getShowPercent() { + public function getShowPercent() + { return $this->_showPercent; } @@ -395,7 +432,8 @@ public function getShowPercent() { * @param boolean $value Show percentage * @return PHPExcel_Chart_Layout */ - public function setShowPercent($value) { + public function setShowPercent($value) + { $this->_showPercent = $value; return $this; } @@ -405,7 +443,8 @@ public function setShowPercent($value) { * * @return boolean */ - public function getShowBubbleSize() { + public function getShowBubbleSize() + { return $this->_showBubbleSize; } @@ -416,7 +455,8 @@ public function getShowBubbleSize() { * @param boolean $value Show bubble size * @return PHPExcel_Chart_Layout */ - public function setShowBubbleSize($value) { + public function setShowBubbleSize($value) + { $this->_showBubbleSize = $value; return $this; } @@ -426,7 +466,8 @@ public function setShowBubbleSize($value) { * * @return boolean */ - public function getShowLeaderLines() { + public function getShowLeaderLines() + { return $this->_showLeaderLines; } @@ -437,9 +478,9 @@ public function getShowLeaderLines() { * @param boolean $value Show leader lines * @return PHPExcel_Chart_Layout */ - public function setShowLeaderLines($value) { + public function setShowLeaderLines($value) + { $this->_showLeaderLines = $value; return $this; } - } diff --git a/Classes/PHPExcel/Chart/PlotArea.php b/Classes/PHPExcel/Chart/PlotArea.php index 657fe9813..c2ff157e9 100644 --- a/Classes/PHPExcel/Chart/PlotArea.php +++ b/Classes/PHPExcel/Chart/PlotArea.php @@ -55,7 +55,8 @@ public function __construct(PHPExcel_Chart_Layout $layout = null, $plotSeries = * * @return PHPExcel_Chart_Layout */ - public function getLayout() { + public function getLayout() + { return $this->_layout; } @@ -64,7 +65,8 @@ public function getLayout() { * * @return array of PHPExcel_Chart_DataSeries */ - public function getPlotGroupCount() { + public function getPlotGroupCount() + { return count($this->_plotSeries); } @@ -73,9 +75,10 @@ public function getPlotGroupCount() { * * @return integer */ - public function getPlotSeriesCount() { + public function getPlotSeriesCount() + { $seriesCount = 0; - foreach($this->_plotSeries as $plot) { + foreach ($this->_plotSeries as $plot) { $seriesCount += $plot->getPlotSeriesCount(); } return $seriesCount; @@ -86,7 +89,8 @@ public function getPlotSeriesCount() { * * @return array of PHPExcel_Chart_DataSeries */ - public function getPlotGroup() { + public function getPlotGroup() + { return $this->_plotSeries; } @@ -95,7 +99,8 @@ public function getPlotGroup() { * * @return PHPExcel_Chart_DataSeries */ - public function getPlotGroupByIndex($index) { + public function getPlotGroupByIndex($index) + { return $this->_plotSeries[$index]; } @@ -105,16 +110,17 @@ public function getPlotGroupByIndex($index) { * @param [PHPExcel_Chart_DataSeries] * @return PHPExcel_Chart_PlotArea */ - public function setPlotSeries($plotSeries = array()) { + public function setPlotSeries($plotSeries = array()) + { $this->_plotSeries = $plotSeries; return $this; } - public function refresh(PHPExcel_Worksheet $worksheet) { - foreach($this->_plotSeries as $plotSeries) { + public function refresh(PHPExcel_Worksheet $worksheet) + { + foreach ($this->_plotSeries as $plotSeries) { $plotSeries->refresh($worksheet); } } - } diff --git a/Classes/PHPExcel/Chart/Properties.php b/Classes/PHPExcel/Chart/Properties.php index e0bbb56ae..3181f6546 100644 --- a/Classes/PHPExcel/Chart/Properties.php +++ b/Classes/PHPExcel/Chart/Properties.php @@ -8,353 +8,353 @@ abstract class PHPExcel_Chart_Properties { + const + EXCEL_COLOR_TYPE_STANDARD = 'prstClr', + EXCEL_COLOR_TYPE_SCHEME = 'schemeClr', + EXCEL_COLOR_TYPE_ARGB = 'srgbClr'; - const - EXCEL_COLOR_TYPE_STANDARD = 'prstClr', - EXCEL_COLOR_TYPE_SCHEME = 'schemeClr', - EXCEL_COLOR_TYPE_ARGB = 'srgbClr'; + const + AXIS_LABELS_LOW = 'low', + AXIS_LABELS_HIGH = 'high', + AXIS_LABELS_NEXT_TO = 'nextTo', + AXIS_LABELS_NONE = 'none'; - const - AXIS_LABELS_LOW = 'low', - AXIS_LABELS_HIGH = 'high', - AXIS_LABELS_NEXT_TO = 'nextTo', - AXIS_LABELS_NONE = 'none'; + const + TICK_MARK_NONE = 'none', + TICK_MARK_INSIDE = 'in', + TICK_MARK_OUTSIDE = 'out', + TICK_MARK_CROSS = 'cross'; - const - TICK_MARK_NONE = 'none', - TICK_MARK_INSIDE = 'in', - TICK_MARK_OUTSIDE = 'out', - TICK_MARK_CROSS = 'cross'; + const + HORIZONTAL_CROSSES_AUTOZERO = 'autoZero', + HORIZONTAL_CROSSES_MAXIMUM = 'max'; - const - HORIZONTAL_CROSSES_AUTOZERO = 'autoZero', - HORIZONTAL_CROSSES_MAXIMUM = 'max'; + const + FORMAT_CODE_GENERAL = 'General', + FORMAT_CODE_NUMBER = '#,##0.00', + FORMAT_CODE_CURRENCY = '$#,##0.00', + FORMAT_CODE_ACCOUNTING = '_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)', + FORMAT_CODE_DATE = 'm/d/yyyy', + FORMAT_CODE_TIME = '[$-F400]h:mm:ss AM/PM', + FORMAT_CODE_PERCENTAGE = '0.00%', + FORMAT_CODE_FRACTION = '# ?/?', + FORMAT_CODE_SCIENTIFIC = '0.00E+00', + FORMAT_CODE_TEXT = '@', + FORMAT_CODE_SPECIAL = '00000'; - const - FORMAT_CODE_GENERAL = 'General', - FORMAT_CODE_NUMBER = '#,##0.00', - FORMAT_CODE_CURRENCY = '$#,##0.00', - FORMAT_CODE_ACCOUNTING = '_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)', - FORMAT_CODE_DATE = 'm/d/yyyy', - FORMAT_CODE_TIME = '[$-F400]h:mm:ss AM/PM', - FORMAT_CODE_PERCENTAGE = '0.00%', - FORMAT_CODE_FRACTION = '# ?/?', - FORMAT_CODE_SCIENTIFIC = '0.00E+00', - FORMAT_CODE_TEXT = '@', - FORMAT_CODE_SPECIAL = '00000'; + const + ORIENTATION_NORMAL = 'minMax', + ORIENTATION_REVERSED = 'maxMin'; - const - ORIENTATION_NORMAL = 'minMax', - ORIENTATION_REVERSED = 'maxMin'; + const + LINE_STYLE_COMPOUND_SIMPLE = 'sng', + LINE_STYLE_COMPOUND_DOUBLE = 'dbl', + LINE_STYLE_COMPOUND_THICKTHIN = 'thickThin', + LINE_STYLE_COMPOUND_THINTHICK = 'thinThick', + LINE_STYLE_COMPOUND_TRIPLE = 'tri', - const - LINE_STYLE_COMPOUND_SIMPLE = 'sng', - LINE_STYLE_COMPOUND_DOUBLE = 'dbl', - LINE_STYLE_COMPOUND_THICKTHIN = 'thickThin', - LINE_STYLE_COMPOUND_THINTHICK = 'thinThick', - LINE_STYLE_COMPOUND_TRIPLE = 'tri', + LINE_STYLE_DASH_SOLID = 'solid', + LINE_STYLE_DASH_ROUND_DOT = 'sysDot', + LINE_STYLE_DASH_SQUERE_DOT = 'sysDash', + LINE_STYPE_DASH_DASH = 'dash', + LINE_STYLE_DASH_DASH_DOT = 'dashDot', + LINE_STYLE_DASH_LONG_DASH = 'lgDash', + LINE_STYLE_DASH_LONG_DASH_DOT = 'lgDashDot', + LINE_STYLE_DASH_LONG_DASH_DOT_DOT = 'lgDashDotDot', - LINE_STYLE_DASH_SOLID = 'solid', - LINE_STYLE_DASH_ROUND_DOT = 'sysDot', - LINE_STYLE_DASH_SQUERE_DOT = 'sysDash', - LINE_STYPE_DASH_DASH = 'dash', - LINE_STYLE_DASH_DASH_DOT = 'dashDot', - LINE_STYLE_DASH_LONG_DASH = 'lgDash', - LINE_STYLE_DASH_LONG_DASH_DOT = 'lgDashDot', - LINE_STYLE_DASH_LONG_DASH_DOT_DOT = 'lgDashDotDot', + LINE_STYLE_CAP_SQUARE = 'sq', + LINE_STYLE_CAP_ROUND = 'rnd', + LINE_STYLE_CAP_FLAT = 'flat', - LINE_STYLE_CAP_SQUARE = 'sq', - LINE_STYLE_CAP_ROUND = 'rnd', - LINE_STYLE_CAP_FLAT = 'flat', + LINE_STYLE_JOIN_ROUND = 'bevel', + LINE_STYLE_JOIN_MITER = 'miter', + LINE_STYLE_JOIN_BEVEL = 'bevel', - LINE_STYLE_JOIN_ROUND = 'bevel', - LINE_STYLE_JOIN_MITER = 'miter', - LINE_STYLE_JOIN_BEVEL = 'bevel', + LINE_STYLE_ARROW_TYPE_NOARROW = NULL, + LINE_STYLE_ARROW_TYPE_ARROW = 'triangle', + LINE_STYLE_ARROW_TYPE_OPEN = 'arrow', + LINE_STYLE_ARROW_TYPE_STEALTH = 'stealth', + LINE_STYLE_ARROW_TYPE_DIAMOND = 'diamond', + LINE_STYLE_ARROW_TYPE_OVAL = 'oval', - LINE_STYLE_ARROW_TYPE_NOARROW = NULL, - LINE_STYLE_ARROW_TYPE_ARROW = 'triangle', - LINE_STYLE_ARROW_TYPE_OPEN = 'arrow', - LINE_STYLE_ARROW_TYPE_STEALTH = 'stealth', - LINE_STYLE_ARROW_TYPE_DIAMOND = 'diamond', - LINE_STYLE_ARROW_TYPE_OVAL = 'oval', + LINE_STYLE_ARROW_SIZE_1 = 1, + LINE_STYLE_ARROW_SIZE_2 = 2, + LINE_STYLE_ARROW_SIZE_3 = 3, + LINE_STYLE_ARROW_SIZE_4 = 4, + LINE_STYLE_ARROW_SIZE_5 = 5, + LINE_STYLE_ARROW_SIZE_6 = 6, + LINE_STYLE_ARROW_SIZE_7 = 7, + LINE_STYLE_ARROW_SIZE_8 = 8, + LINE_STYLE_ARROW_SIZE_9 = 9; - LINE_STYLE_ARROW_SIZE_1 = 1, - LINE_STYLE_ARROW_SIZE_2 = 2, - LINE_STYLE_ARROW_SIZE_3 = 3, - LINE_STYLE_ARROW_SIZE_4 = 4, - LINE_STYLE_ARROW_SIZE_5 = 5, - LINE_STYLE_ARROW_SIZE_6 = 6, - LINE_STYLE_ARROW_SIZE_7 = 7, - LINE_STYLE_ARROW_SIZE_8 = 8, - LINE_STYLE_ARROW_SIZE_9 = 9; + const + SHADOW_PRESETS_NOSHADOW = NULL, + SHADOW_PRESETS_OUTER_BOTTTOM_RIGHT = 1, + SHADOW_PRESETS_OUTER_BOTTOM = 2, + SHADOW_PRESETS_OUTER_BOTTOM_LEFT = 3, + SHADOW_PRESETS_OUTER_RIGHT = 4, + SHADOW_PRESETS_OUTER_CENTER = 5, + SHADOW_PRESETS_OUTER_LEFT = 6, + SHADOW_PRESETS_OUTER_TOP_RIGHT = 7, + SHADOW_PRESETS_OUTER_TOP = 8, + SHADOW_PRESETS_OUTER_TOP_LEFT = 9, + SHADOW_PRESETS_INNER_BOTTTOM_RIGHT = 10, + SHADOW_PRESETS_INNER_BOTTOM = 11, + SHADOW_PRESETS_INNER_BOTTOM_LEFT = 12, + SHADOW_PRESETS_INNER_RIGHT = 13, + SHADOW_PRESETS_INNER_CENTER = 14, + SHADOW_PRESETS_INNER_LEFT = 15, + SHADOW_PRESETS_INNER_TOP_RIGHT = 16, + SHADOW_PRESETS_INNER_TOP = 17, + SHADOW_PRESETS_INNER_TOP_LEFT = 18, + SHADOW_PRESETS_PERSPECTIVE_BELOW = 19, + SHADOW_PRESETS_PERSPECTIVE_UPPER_RIGHT = 20, + SHADOW_PRESETS_PERSPECTIVE_UPPER_LEFT = 21, + SHADOW_PRESETS_PERSPECTIVE_LOWER_RIGHT = 22, + SHADOW_PRESETS_PERSPECTIVE_LOWER_LEFT = 23; - const - SHADOW_PRESETS_NOSHADOW = NULL, - SHADOW_PRESETS_OUTER_BOTTTOM_RIGHT = 1, - SHADOW_PRESETS_OUTER_BOTTOM = 2, - SHADOW_PRESETS_OUTER_BOTTOM_LEFT = 3, - SHADOW_PRESETS_OUTER_RIGHT = 4, - SHADOW_PRESETS_OUTER_CENTER = 5, - SHADOW_PRESETS_OUTER_LEFT = 6, - SHADOW_PRESETS_OUTER_TOP_RIGHT = 7, - SHADOW_PRESETS_OUTER_TOP = 8, - SHADOW_PRESETS_OUTER_TOP_LEFT = 9, - SHADOW_PRESETS_INNER_BOTTTOM_RIGHT = 10, - SHADOW_PRESETS_INNER_BOTTOM = 11, - SHADOW_PRESETS_INNER_BOTTOM_LEFT = 12, - SHADOW_PRESETS_INNER_RIGHT = 13, - SHADOW_PRESETS_INNER_CENTER = 14, - SHADOW_PRESETS_INNER_LEFT = 15, - SHADOW_PRESETS_INNER_TOP_RIGHT = 16, - SHADOW_PRESETS_INNER_TOP = 17, - SHADOW_PRESETS_INNER_TOP_LEFT = 18, - SHADOW_PRESETS_PERSPECTIVE_BELOW = 19, - SHADOW_PRESETS_PERSPECTIVE_UPPER_RIGHT = 20, - SHADOW_PRESETS_PERSPECTIVE_UPPER_LEFT = 21, - SHADOW_PRESETS_PERSPECTIVE_LOWER_RIGHT = 22, - SHADOW_PRESETS_PERSPECTIVE_LOWER_LEFT = 23; - - protected function getExcelPointsWidth($width) { - return $width * 12700; - } - - protected function getExcelPointsAngle($angle) { - return $angle * 60000; - } - - protected function getTrueAlpha($alpha) { - return (string) 100 - $alpha . '000'; - } + protected function getExcelPointsWidth($width) + { + return $width * 12700; + } - protected function setColorProperties($color, $alpha, $type) { - return array( - 'type' => (string) $type, - 'value' => (string) $color, - 'alpha' => (string) $this->getTrueAlpha($alpha) - ); - } + protected function getExcelPointsAngle($angle) + { + return $angle * 60000; + } - protected function getLineStyleArrowSize($array_selector, $array_kay_selector) { - $sizes = array( - 1 => array('w' => 'sm', 'len' => 'sm'), - 2 => array('w' => 'sm', 'len' => 'med'), - 3 => array('w' => 'sm', 'len' => 'lg'), - 4 => array('w' => 'med', 'len' => 'sm'), - 5 => array('w' => 'med', 'len' => 'med'), - 6 => array('w' => 'med', 'len' => 'lg'), - 7 => array('w' => 'lg', 'len' => 'sm'), - 8 => array('w' => 'lg', 'len' => 'med'), - 9 => array('w' => 'lg', 'len' => 'lg') - ); + protected function getTrueAlpha($alpha) + { + return (string) 100 - $alpha . '000'; + } - return $sizes[$array_selector][$array_kay_selector]; - } + protected function setColorProperties($color, $alpha, $type) + { + return array( + 'type' => (string) $type, + 'value' => (string) $color, + 'alpha' => (string) $this->getTrueAlpha($alpha) + ); + } - protected function getShadowPresetsMap($shadow_presets_option) { - $presets_options = array( - //OUTER - 1 => array( - 'effect' => 'outerShdw', - 'blur' => '50800', - 'distance' => '38100', - 'direction' => '2700000', - 'algn' => 'tl', - 'rotWithShape' => '0' - ), - 2 => array( - 'effect' => 'outerShdw', - 'blur' => '50800', - 'distance' => '38100', - 'direction' => '5400000', - 'algn' => 't', - 'rotWithShape' => '0' - ), - 3 => array( - 'effect' => 'outerShdw', - 'blur' => '50800', - 'distance' => '38100', - 'direction' => '8100000', - 'algn' => 'tr', - 'rotWithShape' => '0' - ), - 4 => array( - 'effect' => 'outerShdw', - 'blur' => '50800', - 'distance' => '38100', - 'algn' => 'l', - 'rotWithShape' => '0' - ), - 5 => array( - 'effect' => 'outerShdw', - 'size' => array( - 'sx' => '102000', - 'sy' => '102000' - ) - , - 'blur' => '63500', - 'distance' => '38100', - 'algn' => 'ctr', - 'rotWithShape' => '0' - ), - 6 => array( - 'effect' => 'outerShdw', - 'blur' => '50800', - 'distance' => '38100', - 'direction' => '10800000', - 'algn' => 'r', - 'rotWithShape' => '0' - ), - 7 => array( - 'effect' => 'outerShdw', - 'blur' => '50800', - 'distance' => '38100', - 'direction' => '18900000', - 'algn' => 'bl', - 'rotWithShape' => '0' - ), - 8 => array( - 'effect' => 'outerShdw', - 'blur' => '50800', - 'distance' => '38100', - 'direction' => '16200000', - 'rotWithShape' => '0' - ), - 9 => array( - 'effect' => 'outerShdw', - 'blur' => '50800', - 'distance' => '38100', - 'direction' => '13500000', - 'algn' => 'br', - 'rotWithShape' => '0' - ), - //INNER - 10 => array( - 'effect' => 'innerShdw', - 'blur' => '63500', - 'distance' => '50800', - 'direction' => '2700000', - ), - 11 => array( - 'effect' => 'innerShdw', - 'blur' => '63500', - 'distance' => '50800', - 'direction' => '5400000', - ), - 12 => array( - 'effect' => 'innerShdw', - 'blur' => '63500', - 'distance' => '50800', - 'direction' => '8100000', - ), - 13 => array( - 'effect' => 'innerShdw', - 'blur' => '63500', - 'distance' => '50800', - ), - 14 => array( - 'effect' => 'innerShdw', - 'blur' => '114300', - ), - 15 => array( - 'effect' => 'innerShdw', - 'blur' => '63500', - 'distance' => '50800', - 'direction' => '10800000', - ), - 16 => array( - 'effect' => 'innerShdw', - 'blur' => '63500', - 'distance' => '50800', - 'direction' => '18900000', - ), - 17 => array( - 'effect' => 'innerShdw', - 'blur' => '63500', - 'distance' => '50800', - 'direction' => '16200000', - ), - 18 => array( - 'effect' => 'innerShdw', - 'blur' => '63500', - 'distance' => '50800', - 'direction' => '13500000', - ), - //perspective - 19 => array( - 'effect' => 'outerShdw', - 'blur' => '152400', - 'distance' => '317500', - 'size' => array( - 'sx' => '90000', - 'sy' => '-19000', - ), - 'direction' => '5400000', - 'rotWithShape' => '0', - ), - 20 => array( - 'effect' => 'outerShdw', - 'blur' => '76200', - 'direction' => '18900000', - 'size' => array( - 'sy' => '23000', - 'kx' => '-1200000', - ), - 'algn' => 'bl', - 'rotWithShape' => '0', - ), - 21 => array( - 'effect' => 'outerShdw', - 'blur' => '76200', - 'direction' => '13500000', - 'size' => array( - 'sy' => '23000', - 'kx' => '1200000', - ), - 'algn' => 'br', - 'rotWithShape' => '0', - ), - 22 => array( - 'effect' => 'outerShdw', - 'blur' => '76200', - 'distance' => '12700', - 'direction' => '2700000', - 'size' => array( - 'sy' => '-23000', - 'kx' => '-800400', - ), - 'algn' => 'bl', - 'rotWithShape' => '0', - ), - 23 => array( - 'effect' => 'outerShdw', - 'blur' => '76200', - 'distance' => '12700', - 'direction' => '8100000', - 'size' => array( - 'sy' => '-23000', - 'kx' => '800400', - ), - 'algn' => 'br', - 'rotWithShape' => '0', - ), - ); + protected function getLineStyleArrowSize($array_selector, $array_kay_selector) { + $sizes = array( + 1 => array('w' => 'sm', 'len' => 'sm'), + 2 => array('w' => 'sm', 'len' => 'med'), + 3 => array('w' => 'sm', 'len' => 'lg'), + 4 => array('w' => 'med', 'len' => 'sm'), + 5 => array('w' => 'med', 'len' => 'med'), + 6 => array('w' => 'med', 'len' => 'lg'), + 7 => array('w' => 'lg', 'len' => 'sm'), + 8 => array('w' => 'lg', 'len' => 'med'), + 9 => array('w' => 'lg', 'len' => 'lg') + ); - return $presets_options[$shadow_presets_option]; - } + return $sizes[$array_selector][$array_kay_selector]; + } - protected function getArrayElementsValue($properties, $elements) { - $reference = & $properties; - if (!is_array($elements)) { - return $reference[$elements]; - } else { - foreach ($elements as $keys) { - $reference = & $reference[$keys]; - } + protected function getShadowPresetsMap($shadow_presets_option) { + $presets_options = array( + //OUTER + 1 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '2700000', + 'algn' => 'tl', + 'rotWithShape' => '0' + ), + 2 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '5400000', + 'algn' => 't', + 'rotWithShape' => '0' + ), + 3 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '8100000', + 'algn' => 'tr', + 'rotWithShape' => '0' + ), + 4 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'algn' => 'l', + 'rotWithShape' => '0' + ), + 5 => array( + 'effect' => 'outerShdw', + 'size' => array( + 'sx' => '102000', + 'sy' => '102000' + ) + , + 'blur' => '63500', + 'distance' => '38100', + 'algn' => 'ctr', + 'rotWithShape' => '0' + ), + 6 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '10800000', + 'algn' => 'r', + 'rotWithShape' => '0' + ), + 7 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '18900000', + 'algn' => 'bl', + 'rotWithShape' => '0' + ), + 8 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '16200000', + 'rotWithShape' => '0' + ), + 9 => array( + 'effect' => 'outerShdw', + 'blur' => '50800', + 'distance' => '38100', + 'direction' => '13500000', + 'algn' => 'br', + 'rotWithShape' => '0' + ), + //INNER + 10 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '2700000', + ), + 11 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '5400000', + ), + 12 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '8100000', + ), + 13 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + ), + 14 => array( + 'effect' => 'innerShdw', + 'blur' => '114300', + ), + 15 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '10800000', + ), + 16 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '18900000', + ), + 17 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '16200000', + ), + 18 => array( + 'effect' => 'innerShdw', + 'blur' => '63500', + 'distance' => '50800', + 'direction' => '13500000', + ), + //perspective + 19 => array( + 'effect' => 'outerShdw', + 'blur' => '152400', + 'distance' => '317500', + 'size' => array( + 'sx' => '90000', + 'sy' => '-19000', + ), + 'direction' => '5400000', + 'rotWithShape' => '0', + ), + 20 => array( + 'effect' => 'outerShdw', + 'blur' => '76200', + 'direction' => '18900000', + 'size' => array( + 'sy' => '23000', + 'kx' => '-1200000', + ), + 'algn' => 'bl', + 'rotWithShape' => '0', + ), + 21 => array( + 'effect' => 'outerShdw', + 'blur' => '76200', + 'direction' => '13500000', + 'size' => array( + 'sy' => '23000', + 'kx' => '1200000', + ), + 'algn' => 'br', + 'rotWithShape' => '0', + ), + 22 => array( + 'effect' => 'outerShdw', + 'blur' => '76200', + 'distance' => '12700', + 'direction' => '2700000', + 'size' => array( + 'sy' => '-23000', + 'kx' => '-800400', + ), + 'algn' => 'bl', + 'rotWithShape' => '0', + ), + 23 => array( + 'effect' => 'outerShdw', + 'blur' => '76200', + 'distance' => '12700', + 'direction' => '8100000', + 'size' => array( + 'sy' => '-23000', + 'kx' => '800400', + ), + 'algn' => 'br', + 'rotWithShape' => '0', + ), + ); - return $reference; + return $presets_options[$shadow_presets_option]; } - return $this; - } - + protected function getArrayElementsValue($properties, $elements) { + $reference = & $properties; + if (!is_array($elements)) { + return $reference[$elements]; + } else { + foreach ($elements as $keys) { + $reference = & $reference[$keys]; + } + return $reference; + } + return $this; + } } \ No newline at end of file diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index f869abde7..a06d489ab 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -211,8 +211,7 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter * @param string $phpSheet The worksheet to write * @param PHPExcel_Worksheet $phpSheet */ - public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, - $parser, $preCalculateFormulas, $phpSheet) + public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, $parser, $preCalculateFormulas, $phpSheet) { // It needs to call its parent's constructor explicitly parent::__construct(); @@ -261,7 +260,9 @@ public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, $this->_lastColumnIndex = PHPExcel_Cell::columnIndexFromString($maxC); // if ($this->_firstColumnIndex > 255) $this->_firstColumnIndex = 255; - if ($this->_lastColumnIndex > 255) $this->_lastColumnIndex = 255; + if ($this->_lastColumnIndex > 255) { + $this->_lastColumnIndex = 255; + } $this->_countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection()); } @@ -273,7 +274,7 @@ public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, * @access public * @see PHPExcel_Writer_Excel5_Workbook::storeWorkbook() */ - function close() + public function close() { $_phpSheet = $this->_phpSheet; @@ -402,7 +403,7 @@ function close() // Row dimensions foreach ($_phpSheet->getRowDimensions() as $rowDimension) { $xfIndex = $rowDimension->getXfIndex() + 15; // there are 15 cellXfs - $this->_writeRow( $rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel() ); + $this->_writeRow($rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel()); } // Write Cells @@ -500,11 +501,11 @@ function close() $url = $hyperlink->getUrl(); - if ( strpos($url, 'sheet://') !== false ) { + if (strpos($url, 'sheet://') !== false) { // internal to current workbook $url = str_replace('sheet://', 'internal:', $url); - } else if ( preg_match('/^(http:|https:|ftp:|mailto:)/', $url) ) { + } else if (preg_match('/^(http:|https:|ftp:|mailto:)/', $url)) { // URL // $url = $url; @@ -524,7 +525,7 @@ function close() $this->_writeRangeProtection(); $arrConditionalStyles = $_phpSheet->getConditionalStylesCollection(); - if(!empty($arrConditionalStyles)){ + if (!empty($arrConditionalStyles)) { $arrConditional = array(); // @todo CFRule & CFHeader // Write CFHEADER record @@ -532,9 +533,9 @@ function close() // Write ConditionalFormattingTable records foreach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) { foreach ($conditionalStyles as $conditional) { - if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION - || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ - if(!in_array($conditional->getHashCode(), $arrConditional)){ + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS) { + if (!in_array($conditional->getHashCode(), $arrConditional)) { $arrConditional[] = $conditional->getHashCode(); // Write CFRULE record $this->_writeCFRule($conditional); @@ -586,7 +587,7 @@ private function _writeBIFF8CellRangeAddressFixed($range = 'A1') * * @return string The data */ - function getData() + public function getData() { $buffer = 4096; @@ -606,7 +607,7 @@ function getData() * @access public * @param integer $print Whether to print the headers or not. Defaults to 1 (print). */ - function printRowColHeaders($print = 1) + public function printRowColHeaders($print = 1) { $this->_print_headers = $print; } @@ -620,7 +621,7 @@ function printRowColHeaders($print = 1) * @param bool $symbols_right * @param bool $auto_style */ - function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false) + public function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false) { $this->_outline_on = $visible; $this->_outline_below = $symbols_below; @@ -652,9 +653,9 @@ private function _writeNumber($row, $col, $num, $xfIndex) $record = 0x0203; // Record identifier $length = 0x000E; // Number of bytes to follow - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $xfIndex); - $xl_double = pack("d", $num); + $xl_double = pack("d", $num); if (self::getByteOrder()) { // if it's Big Endian $xl_double = strrev($xl_double); } @@ -685,7 +686,8 @@ private function _writeString($row, $col, $str, $xfIndex) * @param mixed $xfIndex The XF format index for the cell * @param array $arrcRun Index to Font record and characters beginning */ - private function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun){ + private function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun) + { $record = 0x00FD; // Record identifier $length = 0x000A; // Bytes to follow $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($str, $arrcRun); @@ -696,7 +698,7 @@ private function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun){ } $this->_str_total++; - $header = pack('vv', $record, $length); + $header = pack('vv', $record, $length); $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); $this->_append($header.$data); } @@ -731,7 +733,7 @@ private function _writeLabel($row, $col, $str, $xfIndex) $str_error = -3; } - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvv", $row, $col, $xfIndex, $strlen); $this->_append($header . $data . $str); return($str_error); @@ -765,7 +767,7 @@ private function _writeLabelSst($row, $col, $str, $xfIndex) } $this->_str_total++; - $header = pack('vv', $record, $length); + $header = pack('vv', $record, $length); $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); $this->_append($header.$data); } @@ -786,14 +788,14 @@ private function _writeNote($row, $col, $note) // Length for this record is no more than 2048 + 6 $length = 0x0006 + min($note_length, 2048); - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $note_length); $this->_append($header . $data . substr($note, 0, 2048)); for ($i = $max_length; $i < $note_length; $i += $max_length) { $chunk = substr($note, $i, $max_length); $length = 0x0006 + strlen($chunk); - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvv", -1, 0, strlen($chunk)); $this->_append($header.$data.$chunk); } @@ -816,12 +818,12 @@ private function _writeNote($row, $col, $note) * @param integer $col Zero indexed column * @param mixed $xfIndex The XF format index */ - function _writeBlank($row, $col, $xfIndex) + public function _writeBlank($row, $col, $xfIndex) { $record = 0x0201; // Record identifier $length = 0x0006; // Number of bytes to follow - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $xfIndex); $this->_append($header . $data); return 0; @@ -841,7 +843,7 @@ private function _writeBoolErr($row, $col, $value, $isError, $xfIndex) $record = 0x0205; $length = 8; - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvCC", $row, $col, $xfIndex, $value, $isError); $this->_append($header . $data); return 0; @@ -920,7 +922,7 @@ private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) $formlen = strlen($formula); // Length of the binary string $length = 0x16 + $formlen; // Length of the record data - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $xfIndex) . $num @@ -997,7 +999,7 @@ private function _writeUrl($row, $col, $url) * @param string $url URL string * @return integer */ - function _writeUrlRange($row1, $col1, $row2, $col2, $url) + public function _writeUrlRange($row1, $col1, $row2, $col2, $url) { // Check for internal/external sheet links or default to web link if (preg_match('[^internal:]', $url)) { @@ -1023,7 +1025,7 @@ function _writeUrlRange($row1, $col1, $row2, $col2, $url) * @param string $url URL string * @return integer */ - function _writeUrlWeb($row1, $col1, $row2, $col2, $url) + public function _writeUrlWeb($row1, $col1, $row2, $col2, $url) { $record = 0x01B8; // Record identifier $length = 0x00000; // Bytes to follow @@ -1046,7 +1048,7 @@ function _writeUrlWeb($row1, $col1, $row2, $col2, $url) $length = 0x34 + strlen($url); // Pack the header data - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvv", $row1, $row2, $col1, $col2); // Write the packed data @@ -1068,7 +1070,7 @@ function _writeUrlWeb($row1, $col1, $row2, $col2, $url) * @param string $url URL string * @return integer */ - function _writeUrlInternal($row1, $col1, $row2, $col2, $url) + public function _writeUrlInternal($row1, $col1, $row2, $col2, $url) { $record = 0x01B8; // Record identifier $length = 0x00000; // Bytes to follow @@ -1095,7 +1097,7 @@ function _writeUrlInternal($row1, $col1, $row2, $col2, $url) $length = 0x24 + strlen($url); // Pack the header data - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvv", $row1, $row2, $col1, $col2); // Write the packed data @@ -1121,7 +1123,7 @@ function _writeUrlInternal($row1, $col1, $row2, $col2, $url) * @param string $url URL string * @return integer */ - function _writeUrlExternal($row1, $col1, $row2, $col2, $url) + public function _writeUrlExternal($row1, $col1, $row2, $col2, $url) { // Network drives are different. We will handle them separately // MS/Novell network drives and shares start with \\ @@ -1143,7 +1145,7 @@ function _writeUrlExternal($row1, $col1, $row2, $col2, $url) // otherwise, absolute $absolute = 0x00; // relative path - if ( preg_match('/^[A-Z]:/', $url) ) { + if (preg_match('/^[A-Z]:/', $url)) { $absolute = 0x02; // absolute path on Windows, e.g. C:\... } $link_type = 0x01 | $absolute; @@ -1179,7 +1181,7 @@ function _writeUrlExternal($row1, $col1, $row2, $col2, $url) $unknown1 = pack("H*",'D0C9EA79F9BACE118C8200AA004BA90B02000000' ); $unknown2 = pack("H*",'0303000000000000C000000000000046' ); $unknown3 = pack("H*",'FFFFADDE000000000000000000000000000000000000000'); - $unknown4 = pack("v", 0x03 ); + $unknown4 = pack("v", 0x03 ); // Pack the main data stream $data = pack("vvvv", $row1, $row2, $col1, $col2) . @@ -1228,7 +1230,7 @@ private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) $grbit = 0x0000; // Option flags $ixfe = $xfIndex; - if ( $height < 0 ){ + if ($height < 0 ) { $height = null; } @@ -1257,7 +1259,7 @@ private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) } $grbit |= 0x0100; - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, $irwMac,$reserved, $grbit, $ixfe); $this->_append($header.$data); @@ -1271,13 +1273,7 @@ private function _writeDimensions() $record = 0x0200; // Record identifier $length = 0x000E; - $data = pack('VVvvv' - , $this->_firstRowIndex - , $this->_lastRowIndex + 1 - , $this->_firstColumnIndex - , $this->_lastColumnIndex + 1 - , 0x0000 // reserved - ); + $data = pack('VVvvv', $this->_firstRowIndex, $this->_lastRowIndex + 1, $this->_firstColumnIndex, $this->_lastColumnIndex + 1, 0x0000 // reserved); $header = pack("vv", $record, $length); $this->_append($header.$data); @@ -1324,7 +1320,7 @@ private function _writeWindow2() $grbit |= $fPaged << 10; $grbit |= $fPageBreakPreview << 11; - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvv", $grbit, $rwTop, $colLeft); // FIXME !!! @@ -1355,7 +1351,7 @@ private function _writeDefaultRowHeight() $length = 0x0004; // Number of bytes to follow $header = pack("vv", $record, $length); - $data = pack("vv", 1, $defaultRowHeight); + $data = pack("vv", 1, $defaultRowHeight); $this->_append($header . $data); } @@ -1427,7 +1423,7 @@ private function _writeColinfo($col_array) $level = max(0, min($level, 7)); $grbit |= $level << 8; - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvvvv", $colFirst, $colLast, $coldx, $ixfe, $grbit, $reserved); $this->_append($header.$data); @@ -1459,10 +1455,10 @@ private function _writeSelection() // make sure we are not out of bounds $colFirst = min($colFirst, 255); - $colLast = min($colLast, 255); + $colLast = min($colLast, 255); $rwFirst = min($rwFirst, 65535); - $rwLast = min($rwLast, 65535); + $rwLast = min($rwLast, 65535); $record = 0x001D; // Record identifier $length = 0x000F; // Number of bytes to follow @@ -1489,11 +1485,8 @@ private function _writeSelection() list($colFirst, $colLast) = array($colLast, $colFirst); } - $header = pack("vv", $record, $length); - $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct, - $irefAct, $cref, - $rwFirst, $rwLast, - $colFirst, $colLast); + $header = pack("vv", $record, $length); + $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct, $irefAct, $cref, $rwFirst, $rwLast, $colFirst, $colLast); $this->_append($header . $data); } @@ -1688,7 +1681,7 @@ private function _writeExterncount($count) $length = 0x0002; // Number of bytes to follow $header = pack("vv", $record, $length); - $data = pack("v", $count); + $data = pack("v", $count); $this->_append($header . $data); } @@ -1718,7 +1711,7 @@ private function _writeExternsheet($sheetname) $rgch = 0x03; // Reference to a sheet in the current workbook } - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("CC", $cch, $rgch); $this->_append($header . $data . $sheetname); } @@ -1801,7 +1794,7 @@ private function _writePanes() $this->_active_pane = $pnnAct; // Used in _writeSelection - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); $this->_append($header . $data); } @@ -1935,7 +1928,7 @@ private function _writeHcenter() $fHCenter = $this->_phpSheet->getPageSetup()->getHorizontalCentered() ? 1 : 0; // Horizontal centering $header = pack("vv", $record, $length); - $data = pack("v", $fHCenter); + $data = pack("v", $fHCenter); $this->_append($header.$data); } @@ -1951,7 +1944,7 @@ private function _writeVcenter() $fVCenter = $this->_phpSheet->getPageSetup()->getVerticalCentered() ? 1 : 0; // Horizontal centering $header = pack("vv", $record, $length); - $data = pack("v", $fVCenter); + $data = pack("v", $fVCenter); $this->_append($header . $data); } @@ -1965,8 +1958,8 @@ private function _writeMarginLeft() $margin = $this->_phpSheet->getPageMargins()->getLeft(); // Margin in inches - $header = pack("vv", $record, $length); - $data = pack("d", $margin); + $header = pack("vv", $record, $length); + $data = pack("d", $margin); if (self::getByteOrder()) { // if it's Big Endian $data = strrev($data); } @@ -1984,8 +1977,8 @@ private function _writeMarginRight() $margin = $this->_phpSheet->getPageMargins()->getRight(); // Margin in inches - $header = pack("vv", $record, $length); - $data = pack("d", $margin); + $header = pack("vv", $record, $length); + $data = pack("d", $margin); if (self::getByteOrder()) { // if it's Big Endian $data = strrev($data); } @@ -2003,8 +1996,8 @@ private function _writeMarginTop() $margin = $this->_phpSheet->getPageMargins()->getTop(); // Margin in inches - $header = pack("vv", $record, $length); - $data = pack("d", $margin); + $header = pack("vv", $record, $length); + $data = pack("d", $margin); if (self::getByteOrder()) { // if it's Big Endian $data = strrev($data); } @@ -2022,8 +2015,8 @@ private function _writeMarginBottom() $margin = $this->_phpSheet->getPageMargins()->getBottom(); // Margin in inches - $header = pack("vv", $record, $length); - $data = pack("d", $margin); + $header = pack("vv", $record, $length); + $data = pack("d", $margin); if (self::getByteOrder()) { // if it's Big Endian $data = strrev($data); } @@ -2073,15 +2066,16 @@ private function _writeGridset() $fGridSet = !$this->_phpSheet->getPrintGridlines(); // Boolean flag - $header = pack("vv", $record, $length); - $data = pack("v", $fGridSet); + $header = pack("vv", $record, $length); + $data = pack("v", $fGridSet); $this->_append($header . $data); } /** * Write the AUTOFILTERINFO BIFF record. This is used to configure the number of autofilter select used in the sheet. */ - private function _writeAutoFilterInfo(){ + private function _writeAutoFilterInfo() + { $record = 0x009D; // Record identifier $length = 0x0002; // Bytes to follow @@ -2089,7 +2083,7 @@ private function _writeAutoFilterInfo(){ $iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0]; $header = pack("vv", $record, $length); - $data = pack("v", $iNumFilters); + $data = pack("v", $iNumFilters); $this->_append($header . $data); } @@ -2134,7 +2128,7 @@ private function _writeGuts() ++$col_level; } - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvv", $dxRwGut, $dxColGut, $maxRowOutlineLevel, $col_level); $this->_append($header.$data); @@ -2172,7 +2166,7 @@ private function _writeWsbool() } $header = pack("vv", $record, $length); - $data = pack("v", $grbit); + $data = pack("v", $grbit); $this->_append($header . $data); } @@ -2195,12 +2189,10 @@ private function _writeBreaks() // Add to list of vertical breaks $vbreaks[] = PHPExcel_Cell::columnIndexFromString($coordinates[0]) - 1; break; - case PHPExcel_Worksheet::BREAK_ROW: // Add to list of horizontal breaks $hbreaks[] = $coordinates[1]; break; - case PHPExcel_Worksheet::BREAK_NONE: default: // Nothing to do @@ -2222,7 +2214,7 @@ private function _writeBreaks() $length = 2 + 6 * $cbrk; // Bytes to follow $header = pack("vv", $record, $length); - $data = pack("v", $cbrk); + $data = pack("v", $cbrk); // Append each page break foreach ($hbreaks as $hbreak) { @@ -2249,8 +2241,8 @@ private function _writeBreaks() $cbrk = count($vbreaks); // Number of page breaks $length = 2 + 6 * $cbrk; // Bytes to follow - $header = pack("vv", $record, $length); - $data = pack("v", $cbrk); + $header = pack("vv", $record, $length); + $data = pack("v", $cbrk); // Append each page break foreach ($vbreaks as $vbreak) { @@ -2277,7 +2269,7 @@ private function _writeProtect() $fLock = 1; // Worksheet is protected $header = pack("vv", $record, $length); - $data = pack("v", $fLock); + $data = pack("v", $fLock); $this->_append($header.$data); } @@ -2346,7 +2338,7 @@ private function _writePassword() $wPassword = hexdec($this->_phpSheet->getProtection()->getPassword()); // Encoded password $header = pack("vv", $record, $length); - $data = pack("v", $wPassword); + $data = pack("v", $wPassword); $this->_append($header . $data); } @@ -2363,7 +2355,7 @@ private function _writePassword() * @param float $scale_x The horizontal scale * @param float $scale_y The vertical scale */ - function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) + public function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) { $bitmap_array = (is_resource($bitmap) ? $this->_processBitmapGd($bitmap) : $this->_processBitmap($bitmap)); list($width, $height, $size, $data) = $bitmap_array; //$this->_processBitmap($bitmap); @@ -2437,7 +2429,7 @@ function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_ * @param integer $width Width of image frame * @param integer $height Height of image frame */ - function _positionImage($col_start, $row_start, $x1, $y1, $width, $height) + public function _positionImage($col_start, $row_start, $x1, $y1, $width, $height) { // Initialise end cell to the same as the start cell $col_end = $col_start; // Col containing lower right corner of object @@ -2580,12 +2572,13 @@ private function _writeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB) * @param resource $image The image to process * @return array Array with data and properties of the bitmap */ - function _processBitmapGd($image) { + public function _processBitmapGd($image) + { $width = imagesx($image); $height = imagesy($image); $data = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); - for ($j=$height; $j--; ) { + for ($j=$height; $j--;) { for ($i=0; $i < $width; ++$i) { $color = imagecolorsforindex($image, imagecolorat($image, $i, $j)); foreach (array("red", "green", "blue") as $key) { @@ -2610,7 +2603,7 @@ function _processBitmapGd($image) { * @param string $bitmap The bitmap to process * @return array Array with data and properties of the bitmap */ - function _processBitmap($bitmap) + public function _processBitmap($bitmap) { // Open file. $bmp_fd = @fopen($bitmap,"rb"); @@ -2760,7 +2753,7 @@ private function _writeMsoDrawing() $objData = ''; // ftCmo - if($spTypes[$i] == 0x00C9){ + if ($spTypes[$i] == 0x00C9) { // Add ftCmo (common object data) subobject $objData .= pack('vvvvvVVV' @@ -2848,23 +2841,45 @@ private function _writeDataValidity() // data type $type = $dataValidation->getType(); switch ($type) { - case PHPExcel_Cell_DataValidation::TYPE_NONE: $type = 0x00; break; - case PHPExcel_Cell_DataValidation::TYPE_WHOLE: $type = 0x01; break; - case PHPExcel_Cell_DataValidation::TYPE_DECIMAL: $type = 0x02; break; - case PHPExcel_Cell_DataValidation::TYPE_LIST: $type = 0x03; break; - case PHPExcel_Cell_DataValidation::TYPE_DATE: $type = 0x04; break; - case PHPExcel_Cell_DataValidation::TYPE_TIME: $type = 0x05; break; - case PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH: $type = 0x06; break; - case PHPExcel_Cell_DataValidation::TYPE_CUSTOM: $type = 0x07; break; + case PHPExcel_Cell_DataValidation::TYPE_NONE: + $type = 0x00; + break; + case PHPExcel_Cell_DataValidation::TYPE_WHOLE: + $type = 0x01; + break; + case PHPExcel_Cell_DataValidation::TYPE_DECIMAL: + $type = 0x02; + break; + case PHPExcel_Cell_DataValidation::TYPE_LIST: + $type = 0x03; + break; + case PHPExcel_Cell_DataValidation::TYPE_DATE: + $type = 0x04; + break; + case PHPExcel_Cell_DataValidation::TYPE_TIME: + $type = 0x05; + break; + case PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH: + $type = 0x06; + break; + case PHPExcel_Cell_DataValidation::TYPE_CUSTOM: + $type = 0x07; + break; } $options |= $type << 0; // error style $errorStyle = $dataValidation->getType(); switch ($errorStyle) { - case PHPExcel_Cell_DataValidation::STYLE_STOP: $errorStyle = 0x00; break; - case PHPExcel_Cell_DataValidation::STYLE_WARNING: $errorStyle = 0x01; break; - case PHPExcel_Cell_DataValidation::STYLE_INFORMATION: $errorStyle = 0x02; break; + case PHPExcel_Cell_DataValidation::STYLE_STOP: + $errorStyle = 0x00; + break; + case PHPExcel_Cell_DataValidation::STYLE_WARNING: + $errorStyle = 0x01; + break; + case PHPExcel_Cell_DataValidation::STYLE_INFORMATION: + $errorStyle = 0x02; + break; } $options |= $errorStyle << 4; @@ -2888,14 +2903,30 @@ private function _writeDataValidity() // condition operator $operator = $dataValidation->getOperator(); switch ($operator) { - case PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN: $operator = 0x00 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN: $operator = 0x01 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_EQUAL: $operator = 0x02 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL: $operator = 0x03 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN: $operator = 0x04 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN: $operator = 0x05 ; break; - case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL: $operator = 0x06; break; - case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL: $operator = 0x07 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN: + $operator = 0x00; + break; + case PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN: + $operator = 0x01; + break; + case PHPExcel_Cell_DataValidation::OPERATOR_EQUAL: + $operator = 0x02; + break; + case PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL: + $operator = 0x03; + break; + case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN: + $operator = 0x04; + break; + case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN: + $operator = 0x05; + break; + case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL: + $operator = 0x06; + break; + case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL: + $operator = 0x07; + break; } $options |= $operator << 20; @@ -2973,15 +3004,23 @@ private function _writeDataValidity() * @param string $errorCode * @return int */ - private static function _mapErrorCode($errorCode) { + private static function _mapErrorCode($errorCode) + { switch ($errorCode) { - case '#NULL!': return 0x00; - case '#DIV/0!': return 0x07; - case '#VALUE!': return 0x0F; - case '#REF!': return 0x17; - case '#NAME?': return 0x1D; - case '#NUM!': return 0x24; - case '#N/A': return 0x2A; + case '#NULL!': + return 0x00; + case '#DIV/0!': + return 0x07; + case '#VALUE!': + return 0x0F; + case '#REF!': + return 0x17; + case '#NAME?': + return 0x1D; + case '#NUM!': + return 0x24; + case '#N/A': + return 0x2A; } return 0; @@ -2990,7 +3029,8 @@ private static function _mapErrorCode($errorCode) { /** * Write PLV Record */ - private function _writePageLayoutView(){ + private function _writePageLayoutView() + { $record = 0x088B; // Record identifier $length = 0x0010; // Bytes to follow @@ -3000,7 +3040,7 @@ private function _writePageLayoutView(){ $wScalvePLV = $this->_phpSheet->getSheetView()->getZoomScale(); // 2 // The options flags that comprise $grbit - if($this->_phpSheet->getSheetView()->getView() == PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT){ + if ($this->_phpSheet->getSheetView()->getView() == PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { $fPageLayoutView = 1; } else { $fPageLayoutView = 0; @@ -3021,18 +3061,19 @@ private function _writePageLayoutView(){ * Write CFRule Record * @param PHPExcel_Style_Conditional $conditional */ - private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ + private function _writeCFRule(PHPExcel_Style_Conditional $conditional) + { $record = 0x01B1; // Record identifier // $type : Type of the CF // $operatorType : Comparison operator - if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION){ + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { $type = 0x02; $operatorType = 0x00; - } else if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS) { $type = 0x01; - switch ($conditional->getOperatorType()){ + switch ($conditional->getOperatorType()) { case PHPExcel_Style_Conditional::OPERATOR_NONE: $operatorType = 0x00; break; @@ -3065,12 +3106,12 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ // $szValue2 : size of the formula data for second value or formula $arrConditions = $conditional->getConditions(); $numConditions = sizeof($arrConditions); - if($numConditions == 1){ + if ($numConditions == 1) { $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); $szValue2 = 0x0000; $operand1 = pack('Cv', 0x1E, $arrConditions[0]); $operand2 = null; - } else if($numConditions == 2 && ($conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BETWEEN)){ + } else if ($numConditions == 2 && ($conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BETWEEN)) { $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); $szValue2 = ($arrConditions[1] <= 65535 ? 3 : 0x0000); $operand1 = pack('Cv', 0x1E, $arrConditions[0]); @@ -3090,7 +3131,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ $bTxRotation = ($conditional->getStyle()->getAlignment()->getTextRotation() == null ? 1 : 0); $bIndent = ($conditional->getStyle()->getAlignment()->getIndent() == 0 ? 1 : 0); $bShrinkToFit = ($conditional->getStyle()->getAlignment()->getShrinkToFit() == false ? 1 : 0); - if($bAlignHz == 0 || $bAlignVt == 0 || $bAlignWrapTx == 0 || $bTxRotation == 0 || $bIndent == 0 || $bShrinkToFit == 0){ + if ($bAlignHz == 0 || $bAlignVt == 0 || $bAlignWrapTx == 0 || $bTxRotation == 0 || $bIndent == 0 || $bShrinkToFit == 0) { $bFormatAlign = 1; } else { $bFormatAlign = 0; @@ -3098,7 +3139,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ // Protection $bProtLocked = ($conditional->getStyle()->getProtection()->getLocked() == null ? 1 : 0); $bProtHidden = ($conditional->getStyle()->getProtection()->getHidden() == null ? 1 : 0); - if($bProtLocked == 0 || $bProtHidden == 0){ + if ($bProtLocked == 0 || $bProtHidden == 0) { $bFormatProt = 1; } else { $bFormatProt = 0; @@ -3112,7 +3153,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ && $conditional->getStyle()->getBorders()->getTop()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); $bBorderBottom = ($conditional->getStyle()->getBorders()->getBottom()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK && $conditional->getStyle()->getBorders()->getBottom()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); - if($bBorderLeft == 0 || $bBorderRight == 0 || $bBorderTop == 0 || $bBorderBottom == 0){ + if ($bBorderLeft == 0 || $bBorderRight == 0 || $bBorderTop == 0 || $bBorderBottom == 0) { $bFormatBorder = 1; } else { $bFormatBorder = 0; @@ -3121,13 +3162,13 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ $bFillStyle = ($conditional->getStyle()->getFill()->getFillType() == null ? 0 : 1); $bFillColor = ($conditional->getStyle()->getFill()->getStartColor()->getARGB() == null ? 0 : 1); $bFillColorBg = ($conditional->getStyle()->getFill()->getEndColor()->getARGB() == null ? 0 : 1); - if($bFillStyle == 0 || $bFillColor == 0 || $bFillColorBg == 0){ + if ($bFillStyle == 0 || $bFillColor == 0 || $bFillColorBg == 0) { $bFormatFill = 1; } else { $bFormatFill = 0; } // Font - if($conditional->getStyle()->getFont()->getName() != null + if ($conditional->getStyle()->getFont()->getName() != null || $conditional->getStyle()->getFont()->getSize() != null || $conditional->getStyle()->getFont()->getBold() != null || $conditional->getStyle()->getFont()->getItalic() != null @@ -3135,7 +3176,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ || $conditional->getStyle()->getFont()->getSubScript() != null || $conditional->getStyle()->getFont()->getUnderline() != null || $conditional->getStyle()->getFont()->getStrikethrough() != null - || $conditional->getStyle()->getFont()->getColor()->getARGB() != null){ + || $conditional->getStyle()->getFont()->getColor()->getARGB() != null) { $bFormatFont = 1; } else { $bFormatFont = 0; @@ -3169,7 +3210,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ $flags |= (1 == 1 ? 0x00380000 : 0); // Font $flags |= (1 == $bFormatFont ? 0x04000000 : 0); - // Alignment : + // Alignment: $flags |= (1 == $bFormatAlign ? 0x08000000 : 0); // Border $flags |= (1 == $bFormatBorder ? 0x10000000 : 0); @@ -3181,16 +3222,16 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ $flags |= (1 == 0 ? 0x80000000 : 0); // Data Blocks - if($bFormatFont == 1){ + if ($bFormatFont == 1) { // Font Name - if($conditional->getStyle()->getFont()->getName() == null){ + if ($conditional->getStyle()->getFont()->getName() == null) { $dataBlockFont = pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); $dataBlockFont .= pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); } else { $dataBlockFont = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($conditional->getStyle()->getFont()->getName()); } // Font Size - if($conditional->getStyle()->getFont()->getSize() == null){ + if ($conditional->getStyle()->getFont()->getSize() == null) { $dataBlockFont .= pack('V', 20 * 11); } else { $dataBlockFont .= pack('V', 20 * $conditional->getStyle()->getFont()->getSize()); @@ -3198,16 +3239,16 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ // Font Options $dataBlockFont .= pack('V', 0); // Font weight - if($conditional->getStyle()->getFont()->getBold() == true){ + if ($conditional->getStyle()->getFont()->getBold() == true) { $dataBlockFont .= pack('v', 0x02BC); } else { $dataBlockFont .= pack('v', 0x0190); } // Escapement type - if($conditional->getStyle()->getFont()->getSubScript() == true){ + if ($conditional->getStyle()->getFont()->getSubScript() == true) { $dataBlockFont .= pack('v', 0x02); $fontEscapement = 0; - } else if($conditional->getStyle()->getFont()->getSuperScript() == true){ + } else if ($conditional->getStyle()->getFont()->getSuperScript() == true) { $dataBlockFont .= pack('v', 0x01); $fontEscapement = 0; } else { @@ -3215,75 +3256,206 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ $fontEscapement = 1; } // Underline type - switch ($conditional->getStyle()->getFont()->getUnderline()){ - case PHPExcel_Style_Font::UNDERLINE_NONE : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 0; break; - case PHPExcel_Style_Font::UNDERLINE_DOUBLE : $dataBlockFont .= pack('C', 0x02); $fontUnderline = 0; break; - case PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING : $dataBlockFont .= pack('C', 0x22); $fontUnderline = 0; break; - case PHPExcel_Style_Font::UNDERLINE_SINGLE : $dataBlockFont .= pack('C', 0x01); $fontUnderline = 0; break; - case PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING : $dataBlockFont .= pack('C', 0x21); $fontUnderline = 0; break; - default : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 1; break; + switch ($conditional->getStyle()->getFont()->getUnderline()) { + case PHPExcel_Style_Font::UNDERLINE_NONE: + $dataBlockFont .= pack('C', 0x00); + $fontUnderline = 0; + break; + case PHPExcel_Style_Font::UNDERLINE_DOUBLE: + $dataBlockFont .= pack('C', 0x02); + $fontUnderline = 0; + break; + case PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING: + $dataBlockFont .= pack('C', 0x22); + $fontUnderline = 0; + break; + case PHPExcel_Style_Font::UNDERLINE_SINGLE: + $dataBlockFont .= pack('C', 0x01); + $fontUnderline = 0; + break; + case PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING: + $dataBlockFont .= pack('C', 0x21); + $fontUnderline = 0; + break; + default: $dataBlockFont .= pack('C', 0x00); + $fontUnderline = 1; + break; } // Not used (3) $dataBlockFont .= pack('vC', 0x0000, 0x00); // Font color index switch ($conditional->getStyle()->getFont()->getColor()->getRGB()) { - case '000000': $colorIdx = 0x08; break; - case 'FFFFFF': $colorIdx = 0x09; break; - case 'FF0000': $colorIdx = 0x0A; break; - case '00FF00': $colorIdx = 0x0B; break; - case '0000FF': $colorIdx = 0x0C; break; - case 'FFFF00': $colorIdx = 0x0D; break; - case 'FF00FF': $colorIdx = 0x0E; break; - case '00FFFF': $colorIdx = 0x0F; break; - case '800000': $colorIdx = 0x10; break; - case '008000': $colorIdx = 0x11; break; - case '000080': $colorIdx = 0x12; break; - case '808000': $colorIdx = 0x13; break; - case '800080': $colorIdx = 0x14; break; - case '008080': $colorIdx = 0x15; break; - case 'C0C0C0': $colorIdx = 0x16; break; - case '808080': $colorIdx = 0x17; break; - case '9999FF': $colorIdx = 0x18; break; - case '993366': $colorIdx = 0x19; break; - case 'FFFFCC': $colorIdx = 0x1A; break; - case 'CCFFFF': $colorIdx = 0x1B; break; - case '660066': $colorIdx = 0x1C; break; - case 'FF8080': $colorIdx = 0x1D; break; - case '0066CC': $colorIdx = 0x1E; break; - case 'CCCCFF': $colorIdx = 0x1F; break; - case '000080': $colorIdx = 0x20; break; - case 'FF00FF': $colorIdx = 0x21; break; - case 'FFFF00': $colorIdx = 0x22; break; - case '00FFFF': $colorIdx = 0x23; break; - case '800080': $colorIdx = 0x24; break; - case '800000': $colorIdx = 0x25; break; - case '008080': $colorIdx = 0x26; break; - case '0000FF': $colorIdx = 0x27; break; - case '00CCFF': $colorIdx = 0x28; break; - case 'CCFFFF': $colorIdx = 0x29; break; - case 'CCFFCC': $colorIdx = 0x2A; break; - case 'FFFF99': $colorIdx = 0x2B; break; - case '99CCFF': $colorIdx = 0x2C; break; - case 'FF99CC': $colorIdx = 0x2D; break; - case 'CC99FF': $colorIdx = 0x2E; break; - case 'FFCC99': $colorIdx = 0x2F; break; - case '3366FF': $colorIdx = 0x30; break; - case '33CCCC': $colorIdx = 0x31; break; - case '99CC00': $colorIdx = 0x32; break; - case 'FFCC00': $colorIdx = 0x33; break; - case 'FF9900': $colorIdx = 0x34; break; - case 'FF6600': $colorIdx = 0x35; break; - case '666699': $colorIdx = 0x36; break; - case '969696': $colorIdx = 0x37; break; - case '003366': $colorIdx = 0x38; break; - case '339966': $colorIdx = 0x39; break; - case '003300': $colorIdx = 0x3A; break; - case '333300': $colorIdx = 0x3B; break; - case '993300': $colorIdx = 0x3C; break; - case '993366': $colorIdx = 0x3D; break; - case '333399': $colorIdx = 0x3E; break; - case '333333': $colorIdx = 0x3F; break; - default: $colorIdx = 0x00; break; + case '000000': + $colorIdx = 0x08; + break; + case 'FFFFFF': + $colorIdx = 0x09; + break; + case 'FF0000': + $colorIdx = 0x0A; + break; + case '00FF00': + $colorIdx = 0x0B; + break; + case '0000FF': + $colorIdx = 0x0C; + break; + case 'FFFF00': + $colorIdx = 0x0D; + break; + case 'FF00FF': + $colorIdx = 0x0E; + break; + case '00FFFF': + $colorIdx = 0x0F; + break; + case '800000': + $colorIdx = 0x10; + break; + case '008000': + $colorIdx = 0x11; + break; + case '000080': + $colorIdx = 0x12; + break; + case '808000': + $colorIdx = 0x13; + break; + case '800080': + $colorIdx = 0x14; + break; + case '008080': + $colorIdx = 0x15; + break; + case 'C0C0C0': + $colorIdx = 0x16; + break; + case '808080': + $colorIdx = 0x17; + break; + case '9999FF': + $colorIdx = 0x18; + break; + case '993366': + $colorIdx = 0x19; + break; + case 'FFFFCC': + $colorIdx = 0x1A; + break; + case 'CCFFFF': + $colorIdx = 0x1B; + break; + case '660066': + $colorIdx = 0x1C; + break; + case 'FF8080': + $colorIdx = 0x1D; + break; + case '0066CC': + $colorIdx = 0x1E; + break; + case 'CCCCFF': + $colorIdx = 0x1F; + break; + case '000080': + $colorIdx = 0x20; + break; + case 'FF00FF': + $colorIdx = 0x21; + break; + case 'FFFF00': + $colorIdx = 0x22; + break; + case '00FFFF': + $colorIdx = 0x23; + break; + case '800080': + $colorIdx = 0x24; + break; + case '800000': + $colorIdx = 0x25; + break; + case '008080': + $colorIdx = 0x26; + break; + case '0000FF': + $colorIdx = 0x27; + break; + case '00CCFF': + $colorIdx = 0x28; + break; + case 'CCFFFF': + $colorIdx = 0x29; + break; + case 'CCFFCC': + $colorIdx = 0x2A; + break; + case 'FFFF99': + $colorIdx = 0x2B; + break; + case '99CCFF': + $colorIdx = 0x2C; + break; + case 'FF99CC': + $colorIdx = 0x2D; + break; + case 'CC99FF': + $colorIdx = 0x2E; + break; + case 'FFCC99': + $colorIdx = 0x2F; + break; + case '3366FF': + $colorIdx = 0x30; + break; + case '33CCCC': + $colorIdx = 0x31; + break; + case '99CC00': + $colorIdx = 0x32; + break; + case 'FFCC00': + $colorIdx = 0x33; + break; + case 'FF9900': + $colorIdx = 0x34; + break; + case 'FF6600': + $colorIdx = 0x35; + break; + case '666699': + $colorIdx = 0x36; + break; + case '969696': + $colorIdx = 0x37; + break; + case '003366': + $colorIdx = 0x38; + break; + case '339966': + $colorIdx = 0x39; + break; + case '003300': + $colorIdx = 0x3A; + break; + case '333300': + $colorIdx = 0x3B; + break; + case '993300': + $colorIdx = 0x3C; + break; + case '993366': + $colorIdx = 0x3D; + break; + case '333399': + $colorIdx = 0x3E; + break; + case '333333': + $colorIdx = 0x3F; + break; + default: + $colorIdx = 0x00; + break; } $dataBlockFont .= pack('V', $colorIdx); // Not used (4) @@ -3310,27 +3482,47 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ // Always $dataBlockFont .= pack('v', 0x0001); } - if($bFormatAlign == 1){ + if ($bFormatAlign == 1) { $blockAlign = 0; // Alignment and text break - switch ($conditional->getStyle()->getAlignment()->getHorizontal()){ - case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL : $blockAlign = 0; break; - case PHPExcel_Style_Alignment::HORIZONTAL_LEFT : $blockAlign = 1; break; - case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT : $blockAlign = 3; break; - case PHPExcel_Style_Alignment::HORIZONTAL_CENTER : $blockAlign = 2; break; - case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS : $blockAlign = 6; break; - case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY : $blockAlign = 5; break; + switch ($conditional->getStyle()->getAlignment()->getHorizontal()) { + case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL: + $blockAlign = 0; + break; + case PHPExcel_Style_Alignment::HORIZONTAL_LEFT: + $blockAlign = 1; + break; + case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: + $blockAlign = 3; + break; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER: + $blockAlign = 2; + break; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS: + $blockAlign = 6; + break; + case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY: + $blockAlign = 5; + break; } - if($conditional->getStyle()->getAlignment()->getWrapText() == true){ + if ($conditional->getStyle()->getAlignment()->getWrapText() == true) { $blockAlign |= 1 << 3; } else { $blockAlign |= 0 << 3; } - switch ($conditional->getStyle()->getAlignment()->getVertical()){ - case PHPExcel_Style_Alignment::VERTICAL_BOTTOM : $blockAlign = 2 << 4; break; - case PHPExcel_Style_Alignment::VERTICAL_TOP : $blockAlign = 0 << 4; break; - case PHPExcel_Style_Alignment::VERTICAL_CENTER : $blockAlign = 1 << 4; break; - case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY : $blockAlign = 3 << 4; break; + switch ($conditional->getStyle()->getAlignment()->getVertical()) { + case PHPExcel_Style_Alignment::VERTICAL_BOTTOM: + $blockAlign = 2 << 4; + break; + case PHPExcel_Style_Alignment::VERTICAL_TOP: + $blockAlign = 0 << 4; + break; + case PHPExcel_Style_Alignment::VERTICAL_CENTER: + $blockAlign = 1 << 4; + break; + case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY: + $blockAlign = 3 << 4; + break; } $blockAlign |= 0 << 7; @@ -3339,7 +3531,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ // Indentation $blockIndent = $conditional->getStyle()->getAlignment()->getIndent(); - if($conditional->getStyle()->getAlignment()->getShrinkToFit() == true){ + if ($conditional->getStyle()->getAlignment()->getShrinkToFit() == true) { $blockIndent |= 1 << 4; } else { $blockIndent |= 0 << 4; @@ -3351,71 +3543,183 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ $dataBlockAlign = pack('CCvvv', $blockAlign, $blockRotation, $blockIndent, $blockIndentRelative, 0x0000); } - if($bFormatBorder == 1){ + if ($bFormatBorder == 1) { $blockLineStyle = 0; - switch ($conditional->getStyle()->getBorders()->getLeft()->getBorderStyle()){ - case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00; break; - case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01; break; - case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02; break; - case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03; break; - case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04; break; - case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05; break; - case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06; break; - case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08; break; - case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A; break; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C; break; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D; break; + switch ($conditional->getStyle()->getBorders()->getLeft()->getBorderStyle()) { + case PHPExcel_Style_Border::BORDER_NONE: + $blockLineStyle |= 0x00; + break; + case PHPExcel_Style_Border::BORDER_THIN: + $blockLineStyle |= 0x01; + break; + case PHPExcel_Style_Border::BORDER_MEDIUM: + $blockLineStyle |= 0x02; + break; + case PHPExcel_Style_Border::BORDER_DASHED: + $blockLineStyle |= 0x03; + break; + case PHPExcel_Style_Border::BORDER_DOTTED: + $blockLineStyle |= 0x04; + break; + case PHPExcel_Style_Border::BORDER_THICK: + $blockLineStyle |= 0x05; + break; + case PHPExcel_Style_Border::BORDER_DOUBLE: + $blockLineStyle |= 0x06; + break; + case PHPExcel_Style_Border::BORDER_HAIR: + $blockLineStyle |= 0x07; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: + $blockLineStyle |= 0x08; + break; + case PHPExcel_Style_Border::BORDER_DASHDOT: + $blockLineStyle |= 0x09; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: + $blockLineStyle |= 0x0A; + break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT: + $blockLineStyle |= 0x0B; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: + $blockLineStyle |= 0x0C; + break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: + $blockLineStyle |= 0x0D; + break; } - switch ($conditional->getStyle()->getBorders()->getRight()->getBorderStyle()){ - case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 4; break; - case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 4; break; - case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 4; break; - case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 4; break; - case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 4; break; - case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 4; break; - case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 4; break; - case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 4; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 4; break; - case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 4; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 4; break; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 4; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 4; break; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 4; break; + switch ($conditional->getStyle()->getBorders()->getRight()->getBorderStyle()) { + case PHPExcel_Style_Border::BORDER_NONE: + $blockLineStyle |= 0x00 << 4; + break; + case PHPExcel_Style_Border::BORDER_THIN: + $blockLineStyle |= 0x01 << 4; + break; + case PHPExcel_Style_Border::BORDER_MEDIUM: + $blockLineStyle |= 0x02 << 4; + break; + case PHPExcel_Style_Border::BORDER_DASHED: + $blockLineStyle |= 0x03 << 4; + break; + case PHPExcel_Style_Border::BORDER_DOTTED: + $blockLineStyle |= 0x04 << 4; + break; + case PHPExcel_Style_Border::BORDER_THICK: + $blockLineStyle |= 0x05 << 4; + break; + case PHPExcel_Style_Border::BORDER_DOUBLE: + $blockLineStyle |= 0x06 << 4; + break; + case PHPExcel_Style_Border::BORDER_HAIR: + $blockLineStyle |= 0x07 << 4; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: + $blockLineStyle |= 0x08 << 4; + break; + case PHPExcel_Style_Border::BORDER_DASHDOT: + $blockLineStyle |= 0x09 << 4; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: + $blockLineStyle |= 0x0A << 4; + break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT: + $blockLineStyle |= 0x0B << 4; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: + $blockLineStyle |= 0x0C << 4; + break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: + $blockLineStyle |= 0x0D << 4; + break; } - switch ($conditional->getStyle()->getBorders()->getTop()->getBorderStyle()){ - case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 8; break; - case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 8; break; - case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 8; break; - case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 8; break; - case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 8; break; - case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 8; break; - case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 8; break; - case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 8; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 8; break; - case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 8; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 8; break; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 8; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 8; break; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 8; break; + switch ($conditional->getStyle()->getBorders()->getTop()->getBorderStyle()) { + case PHPExcel_Style_Border::BORDER_NONE: + $blockLineStyle |= 0x00 << 8; + break; + case PHPExcel_Style_Border::BORDER_THIN: + $blockLineStyle |= 0x01 << 8; + break; + case PHPExcel_Style_Border::BORDER_MEDIUM: + $blockLineStyle |= 0x02 << 8; + break; + case PHPExcel_Style_Border::BORDER_DASHED: + $blockLineStyle |= 0x03 << 8; + break; + case PHPExcel_Style_Border::BORDER_DOTTED: + $blockLineStyle |= 0x04 << 8; + break; + case PHPExcel_Style_Border::BORDER_THICK: + $blockLineStyle |= 0x05 << 8; + break; + case PHPExcel_Style_Border::BORDER_DOUBLE: + $blockLineStyle |= 0x06 << 8; + break; + case PHPExcel_Style_Border::BORDER_HAIR: + $blockLineStyle |= 0x07 << 8; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: + $blockLineStyle |= 0x08 << 8; + break; + case PHPExcel_Style_Border::BORDER_DASHDOT: + $blockLineStyle |= 0x09 << 8; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: + $blockLineStyle |= 0x0A << 8; + break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT: + $blockLineStyle |= 0x0B << 8; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: + $blockLineStyle |= 0x0C << 8; + break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: + $blockLineStyle |= 0x0D << 8; + break; } - switch ($conditional->getStyle()->getBorders()->getBottom()->getBorderStyle()){ - case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 12; break; - case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 12; break; - case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 12; break; - case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 12; break; - case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 12; break; - case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 12; break; - case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 12; break; - case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 12; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 12; break; - case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 12; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 12; break; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 12; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 12; break; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 12; break; + switch ($conditional->getStyle()->getBorders()->getBottom()->getBorderStyle()) { + case PHPExcel_Style_Border::BORDER_NONE: + $blockLineStyle |= 0x00 << 12; + break; + case PHPExcel_Style_Border::BORDER_THIN: + $blockLineStyle |= 0x01 << 12; + break; + case PHPExcel_Style_Border::BORDER_MEDIUM: + $blockLineStyle |= 0x02 << 12; + break; + case PHPExcel_Style_Border::BORDER_DASHED: + $blockLineStyle |= 0x03 << 12; + break; + case PHPExcel_Style_Border::BORDER_DOTTED: + $blockLineStyle |= 0x04 << 12; + break; + case PHPExcel_Style_Border::BORDER_THICK: + $blockLineStyle |= 0x05 << 12; + break; + case PHPExcel_Style_Border::BORDER_DOUBLE: + $blockLineStyle |= 0x06 << 12; + break; + case PHPExcel_Style_Border::BORDER_HAIR: + $blockLineStyle |= 0x07 << 12; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: + $blockLineStyle |= 0x08 << 12; + break; + case PHPExcel_Style_Border::BORDER_DASHDOT: + $blockLineStyle |= 0x09 << 12; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: + $blockLineStyle |= 0x0A << 12; + break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT: + $blockLineStyle |= 0x0B << 12; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: + $blockLineStyle |= 0x0C << 12; + break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: + $blockLineStyle |= 0x0D << 12; + break; } //@todo _writeCFRule() => $blockLineStyle => Index Color for left line //@todo _writeCFRule() => $blockLineStyle => Index Color for right line @@ -3425,204 +3729,504 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ //@todo _writeCFRule() => $blockColor => Index Color for top line //@todo _writeCFRule() => $blockColor => Index Color for bottom line //@todo _writeCFRule() => $blockColor => Index Color for diagonal line - switch ($conditional->getStyle()->getBorders()->getDiagonal()->getBorderStyle()){ - case PHPExcel_Style_Border::BORDER_NONE : $blockColor |= 0x00 << 21; break; - case PHPExcel_Style_Border::BORDER_THIN : $blockColor |= 0x01 << 21; break; - case PHPExcel_Style_Border::BORDER_MEDIUM : $blockColor |= 0x02 << 21; break; - case PHPExcel_Style_Border::BORDER_DASHED : $blockColor |= 0x03 << 21; break; - case PHPExcel_Style_Border::BORDER_DOTTED : $blockColor |= 0x04 << 21; break; - case PHPExcel_Style_Border::BORDER_THICK : $blockColor |= 0x05 << 21; break; - case PHPExcel_Style_Border::BORDER_DOUBLE : $blockColor |= 0x06 << 21; break; - case PHPExcel_Style_Border::BORDER_HAIR : $blockColor |= 0x07 << 21; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockColor |= 0x08 << 21; break; - case PHPExcel_Style_Border::BORDER_DASHDOT : $blockColor |= 0x09 << 21; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockColor |= 0x0A << 21; break; - case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockColor |= 0x0B << 21; break; - case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockColor |= 0x0C << 21; break; - case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockColor |= 0x0D << 21; break; + switch ($conditional->getStyle()->getBorders()->getDiagonal()->getBorderStyle()) { + case PHPExcel_Style_Border::BORDER_NONE: + $blockColor |= 0x00 << 21; + break; + case PHPExcel_Style_Border::BORDER_THIN: + $blockColor |= 0x01 << 21; + break; + case PHPExcel_Style_Border::BORDER_MEDIUM: + $blockColor |= 0x02 << 21; + break; + case PHPExcel_Style_Border::BORDER_DASHED: + $blockColor |= 0x03 << 21; + break; + case PHPExcel_Style_Border::BORDER_DOTTED: + $blockColor |= 0x04 << 21; + break; + case PHPExcel_Style_Border::BORDER_THICK: + $blockColor |= 0x05 << 21; + break; + case PHPExcel_Style_Border::BORDER_DOUBLE: + $blockColor |= 0x06 << 21; + break; + case PHPExcel_Style_Border::BORDER_HAIR: + $blockColor |= 0x07 << 21; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: + $blockColor |= 0x08 << 21; + break; + case PHPExcel_Style_Border::BORDER_DASHDOT: + $blockColor |= 0x09 << 21; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: + $blockColor |= 0x0A << 21; + break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT: + $blockColor |= 0x0B << 21; + break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: + $blockColor |= 0x0C << 21; + break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: + $blockColor |= 0x0D << 21; + break; } $dataBlockBorder = pack('vv', $blockLineStyle, $blockColor); } - if($bFormatFill == 1){ + if ($bFormatFill == 1) { // Fill Patern Style $blockFillPatternStyle = 0; - switch ($conditional->getStyle()->getFill()->getFillType()){ - case PHPExcel_Style_Fill::FILL_NONE : $blockFillPatternStyle = 0x00; break; - case PHPExcel_Style_Fill::FILL_SOLID : $blockFillPatternStyle = 0x01; break; - case PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY : $blockFillPatternStyle = 0x02; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY : $blockFillPatternStyle = 0x03; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY : $blockFillPatternStyle = 0x04; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL : $blockFillPatternStyle = 0x05; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL : $blockFillPatternStyle = 0x06; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN : $blockFillPatternStyle = 0x07; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKUP : $blockFillPatternStyle = 0x08; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID : $blockFillPatternStyle = 0x09; break; - case PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS : $blockFillPatternStyle = 0x0A; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL : $blockFillPatternStyle = 0x0B; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL : $blockFillPatternStyle = 0x0C; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN : $blockFillPatternStyle = 0x0D; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP : $blockFillPatternStyle = 0x0E; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID : $blockFillPatternStyle = 0x0F; break; - case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS : $blockFillPatternStyle = 0x10; break; - case PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 : $blockFillPatternStyle = 0x11; break; - case PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 : $blockFillPatternStyle = 0x12; break; - case PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR : $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 - case PHPExcel_Style_Fill::FILL_GRADIENT_PATH : $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 - default : $blockFillPatternStyle = 0x00; break; + switch ($conditional->getStyle()->getFill()->getFillType()) { + case PHPExcel_Style_Fill::FILL_NONE: + $blockFillPatternStyle = 0x00; + break; + case PHPExcel_Style_Fill::FILL_SOLID: + $blockFillPatternStyle = 0x01; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY: + $blockFillPatternStyle = 0x02; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY: + $blockFillPatternStyle = 0x03; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY: + $blockFillPatternStyle = 0x04; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL: + $blockFillPatternStyle = 0x05; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL: + $blockFillPatternStyle = 0x06; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN: + $blockFillPatternStyle = 0x07; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKUP: + $blockFillPatternStyle = 0x08; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID: + $blockFillPatternStyle = 0x09; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS: + $blockFillPatternStyle = 0x0A; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL: + $blockFillPatternStyle = 0x0B; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL: + $blockFillPatternStyle = 0x0C; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN: + $blockFillPatternStyle = 0x0D; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP: + $blockFillPatternStyle = 0x0E; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID: + $blockFillPatternStyle = 0x0F; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS: + $blockFillPatternStyle = 0x10; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_GRAY125: + $blockFillPatternStyle = 0x11; + break; + case PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625: + $blockFillPatternStyle = 0x12; + break; + case PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR: + $blockFillPatternStyle = 0x00; + break; // does not exist in BIFF8 + case PHPExcel_Style_Fill::FILL_GRADIENT_PATH: + $blockFillPatternStyle = 0x00; + break; // does not exist in BIFF8 + default: + $blockFillPatternStyle = 0x00; + break; } // Color switch ($conditional->getStyle()->getFill()->getStartColor()->getRGB()) { - case '000000': $colorIdxBg = 0x08; break; - case 'FFFFFF': $colorIdxBg = 0x09; break; - case 'FF0000': $colorIdxBg = 0x0A; break; - case '00FF00': $colorIdxBg = 0x0B; break; - case '0000FF': $colorIdxBg = 0x0C; break; - case 'FFFF00': $colorIdxBg = 0x0D; break; - case 'FF00FF': $colorIdxBg = 0x0E; break; - case '00FFFF': $colorIdxBg = 0x0F; break; - case '800000': $colorIdxBg = 0x10; break; - case '008000': $colorIdxBg = 0x11; break; - case '000080': $colorIdxBg = 0x12; break; - case '808000': $colorIdxBg = 0x13; break; - case '800080': $colorIdxBg = 0x14; break; - case '008080': $colorIdxBg = 0x15; break; - case 'C0C0C0': $colorIdxBg = 0x16; break; - case '808080': $colorIdxBg = 0x17; break; - case '9999FF': $colorIdxBg = 0x18; break; - case '993366': $colorIdxBg = 0x19; break; - case 'FFFFCC': $colorIdxBg = 0x1A; break; - case 'CCFFFF': $colorIdxBg = 0x1B; break; - case '660066': $colorIdxBg = 0x1C; break; - case 'FF8080': $colorIdxBg = 0x1D; break; - case '0066CC': $colorIdxBg = 0x1E; break; - case 'CCCCFF': $colorIdxBg = 0x1F; break; - case '000080': $colorIdxBg = 0x20; break; - case 'FF00FF': $colorIdxBg = 0x21; break; - case 'FFFF00': $colorIdxBg = 0x22; break; - case '00FFFF': $colorIdxBg = 0x23; break; - case '800080': $colorIdxBg = 0x24; break; - case '800000': $colorIdxBg = 0x25; break; - case '008080': $colorIdxBg = 0x26; break; - case '0000FF': $colorIdxBg = 0x27; break; - case '00CCFF': $colorIdxBg = 0x28; break; - case 'CCFFFF': $colorIdxBg = 0x29; break; - case 'CCFFCC': $colorIdxBg = 0x2A; break; - case 'FFFF99': $colorIdxBg = 0x2B; break; - case '99CCFF': $colorIdxBg = 0x2C; break; - case 'FF99CC': $colorIdxBg = 0x2D; break; - case 'CC99FF': $colorIdxBg = 0x2E; break; - case 'FFCC99': $colorIdxBg = 0x2F; break; - case '3366FF': $colorIdxBg = 0x30; break; - case '33CCCC': $colorIdxBg = 0x31; break; - case '99CC00': $colorIdxBg = 0x32; break; - case 'FFCC00': $colorIdxBg = 0x33; break; - case 'FF9900': $colorIdxBg = 0x34; break; - case 'FF6600': $colorIdxBg = 0x35; break; - case '666699': $colorIdxBg = 0x36; break; - case '969696': $colorIdxBg = 0x37; break; - case '003366': $colorIdxBg = 0x38; break; - case '339966': $colorIdxBg = 0x39; break; - case '003300': $colorIdxBg = 0x3A; break; - case '333300': $colorIdxBg = 0x3B; break; - case '993300': $colorIdxBg = 0x3C; break; - case '993366': $colorIdxBg = 0x3D; break; - case '333399': $colorIdxBg = 0x3E; break; - case '333333': $colorIdxBg = 0x3F; break; - default: $colorIdxBg = 0x41; break; + case '000000': + $colorIdxBg = 0x08; + break; + case 'FFFFFF': + $colorIdxBg = 0x09; + break; + case 'FF0000': + $colorIdxBg = 0x0A; + break; + case '00FF00': + $colorIdxBg = 0x0B; + break; + case '0000FF': + $colorIdxBg = 0x0C; + break; + case 'FFFF00': + $colorIdxBg = 0x0D; + break; + case 'FF00FF': + $colorIdxBg = 0x0E; + break; + case '00FFFF': + $colorIdxBg = 0x0F; + break; + case '800000': + $colorIdxBg = 0x10; + break; + case '008000': + $colorIdxBg = 0x11; + break; + case '000080': + $colorIdxBg = 0x12; + break; + case '808000': + $colorIdxBg = 0x13; + break; + case '800080': + $colorIdxBg = 0x14; + break; + case '008080': + $colorIdxBg = 0x15; + break; + case 'C0C0C0': + $colorIdxBg = 0x16; + break; + case '808080': + $colorIdxBg = 0x17; + break; + case '9999FF': + $colorIdxBg = 0x18; + break; + case '993366': + $colorIdxBg = 0x19; + break; + case 'FFFFCC': + $colorIdxBg = 0x1A; + break; + case 'CCFFFF': + $colorIdxBg = 0x1B; + break; + case '660066': + $colorIdxBg = 0x1C; + break; + case 'FF8080': + $colorIdxBg = 0x1D; + break; + case '0066CC': + $colorIdxBg = 0x1E; + break; + case 'CCCCFF': + $colorIdxBg = 0x1F; + break; + case '000080': + $colorIdxBg = 0x20; + break; + case 'FF00FF': + $colorIdxBg = 0x21; + break; + case 'FFFF00': + $colorIdxBg = 0x22; + break; + case '00FFFF': + $colorIdxBg = 0x23; + break; + case '800080': + $colorIdxBg = 0x24; + break; + case '800000': + $colorIdxBg = 0x25; + break; + case '008080': + $colorIdxBg = 0x26; + break; + case '0000FF': + $colorIdxBg = 0x27; + break; + case '00CCFF': + $colorIdxBg = 0x28; + break; + case 'CCFFFF': + $colorIdxBg = 0x29; + break; + case 'CCFFCC': + $colorIdxBg = 0x2A; + break; + case 'FFFF99': + $colorIdxBg = 0x2B; + break; + case '99CCFF': + $colorIdxBg = 0x2C; + break; + case 'FF99CC': + $colorIdxBg = 0x2D; + break; + case 'CC99FF': + $colorIdxBg = 0x2E; + break; + case 'FFCC99': + $colorIdxBg = 0x2F; + break; + case '3366FF': + $colorIdxBg = 0x30; + break; + case '33CCCC': + $colorIdxBg = 0x31; + break; + case '99CC00': + $colorIdxBg = 0x32; + break; + case 'FFCC00': + $colorIdxBg = 0x33; + break; + case 'FF9900': + $colorIdxBg = 0x34; + break; + case 'FF6600': + $colorIdxBg = 0x35; + break; + case '666699': + $colorIdxBg = 0x36; + break; + case '969696': + $colorIdxBg = 0x37; + break; + case '003366': + $colorIdxBg = 0x38; + break; + case '339966': + $colorIdxBg = 0x39; + break; + case '003300': + $colorIdxBg = 0x3A; + break; + case '333300': + $colorIdxBg = 0x3B; + break; + case '993300': + $colorIdxBg = 0x3C; + break; + case '993366': + $colorIdxBg = 0x3D; + break; + case '333399': + $colorIdxBg = 0x3E; + break; + case '333333': + $colorIdxBg = 0x3F; + break; + default: + $colorIdxBg = 0x41; + break; } // Fg Color switch ($conditional->getStyle()->getFill()->getEndColor()->getRGB()) { - case '000000': $colorIdxFg = 0x08; break; - case 'FFFFFF': $colorIdxFg = 0x09; break; - case 'FF0000': $colorIdxFg = 0x0A; break; - case '00FF00': $colorIdxFg = 0x0B; break; - case '0000FF': $colorIdxFg = 0x0C; break; - case 'FFFF00': $colorIdxFg = 0x0D; break; - case 'FF00FF': $colorIdxFg = 0x0E; break; - case '00FFFF': $colorIdxFg = 0x0F; break; - case '800000': $colorIdxFg = 0x10; break; - case '008000': $colorIdxFg = 0x11; break; - case '000080': $colorIdxFg = 0x12; break; - case '808000': $colorIdxFg = 0x13; break; - case '800080': $colorIdxFg = 0x14; break; - case '008080': $colorIdxFg = 0x15; break; - case 'C0C0C0': $colorIdxFg = 0x16; break; - case '808080': $colorIdxFg = 0x17; break; - case '9999FF': $colorIdxFg = 0x18; break; - case '993366': $colorIdxFg = 0x19; break; - case 'FFFFCC': $colorIdxFg = 0x1A; break; - case 'CCFFFF': $colorIdxFg = 0x1B; break; - case '660066': $colorIdxFg = 0x1C; break; - case 'FF8080': $colorIdxFg = 0x1D; break; - case '0066CC': $colorIdxFg = 0x1E; break; - case 'CCCCFF': $colorIdxFg = 0x1F; break; - case '000080': $colorIdxFg = 0x20; break; - case 'FF00FF': $colorIdxFg = 0x21; break; - case 'FFFF00': $colorIdxFg = 0x22; break; - case '00FFFF': $colorIdxFg = 0x23; break; - case '800080': $colorIdxFg = 0x24; break; - case '800000': $colorIdxFg = 0x25; break; - case '008080': $colorIdxFg = 0x26; break; - case '0000FF': $colorIdxFg = 0x27; break; - case '00CCFF': $colorIdxFg = 0x28; break; - case 'CCFFFF': $colorIdxFg = 0x29; break; - case 'CCFFCC': $colorIdxFg = 0x2A; break; - case 'FFFF99': $colorIdxFg = 0x2B; break; - case '99CCFF': $colorIdxFg = 0x2C; break; - case 'FF99CC': $colorIdxFg = 0x2D; break; - case 'CC99FF': $colorIdxFg = 0x2E; break; - case 'FFCC99': $colorIdxFg = 0x2F; break; - case '3366FF': $colorIdxFg = 0x30; break; - case '33CCCC': $colorIdxFg = 0x31; break; - case '99CC00': $colorIdxFg = 0x32; break; - case 'FFCC00': $colorIdxFg = 0x33; break; - case 'FF9900': $colorIdxFg = 0x34; break; - case 'FF6600': $colorIdxFg = 0x35; break; - case '666699': $colorIdxFg = 0x36; break; - case '969696': $colorIdxFg = 0x37; break; - case '003366': $colorIdxFg = 0x38; break; - case '339966': $colorIdxFg = 0x39; break; - case '003300': $colorIdxFg = 0x3A; break; - case '333300': $colorIdxFg = 0x3B; break; - case '993300': $colorIdxFg = 0x3C; break; - case '993366': $colorIdxFg = 0x3D; break; - case '333399': $colorIdxFg = 0x3E; break; - case '333333': $colorIdxFg = 0x3F; break; - default: $colorIdxFg = 0x40; break; + case '000000': + $colorIdxFg = 0x08; + break; + case 'FFFFFF': + $colorIdxFg = 0x09; + break; + case 'FF0000': + $colorIdxFg = 0x0A; + break; + case '00FF00': + $colorIdxFg = 0x0B; + break; + case '0000FF': + $colorIdxFg = 0x0C; + break; + case 'FFFF00': + $colorIdxFg = 0x0D; + break; + case 'FF00FF': + $colorIdxFg = 0x0E; + break; + case '00FFFF': + $colorIdxFg = 0x0F; + break; + case '800000': + $colorIdxFg = 0x10; + break; + case '008000': + $colorIdxFg = 0x11; + break; + case '000080': + $colorIdxFg = 0x12; + break; + case '808000': + $colorIdxFg = 0x13; + break; + case '800080': + $colorIdxFg = 0x14; + break; + case '008080': + $colorIdxFg = 0x15; + break; + case 'C0C0C0': + $colorIdxFg = 0x16; + break; + case '808080': + $colorIdxFg = 0x17; + break; + case '9999FF': + $colorIdxFg = 0x18; + break; + case '993366': + $colorIdxFg = 0x19; + break; + case 'FFFFCC': + $colorIdxFg = 0x1A; + break; + case 'CCFFFF': + $colorIdxFg = 0x1B; + break; + case '660066': + $colorIdxFg = 0x1C; + break; + case 'FF8080': + $colorIdxFg = 0x1D; + break; + case '0066CC': + $colorIdxFg = 0x1E; + break; + case 'CCCCFF': + $colorIdxFg = 0x1F; + break; + case '000080': + $colorIdxFg = 0x20; + break; + case 'FF00FF': + $colorIdxFg = 0x21; + break; + case 'FFFF00': + $colorIdxFg = 0x22; + break; + case '00FFFF': + $colorIdxFg = 0x23; + break; + case '800080': + $colorIdxFg = 0x24; + break; + case '800000': + $colorIdxFg = 0x25; + break; + case '008080': + $colorIdxFg = 0x26; + break; + case '0000FF': + $colorIdxFg = 0x27; + break; + case '00CCFF': + $colorIdxFg = 0x28; + break; + case 'CCFFFF': + $colorIdxFg = 0x29; + break; + case 'CCFFCC': + $colorIdxFg = 0x2A; + break; + case 'FFFF99': + $colorIdxFg = 0x2B; + break; + case '99CCFF': + $colorIdxFg = 0x2C; + break; + case 'FF99CC': + $colorIdxFg = 0x2D; + break; + case 'CC99FF': + $colorIdxFg = 0x2E; + break; + case 'FFCC99': + $colorIdxFg = 0x2F; + break; + case '3366FF': + $colorIdxFg = 0x30; + break; + case '33CCCC': + $colorIdxFg = 0x31; + break; + case '99CC00': + $colorIdxFg = 0x32; + break; + case 'FFCC00': + $colorIdxFg = 0x33; + break; + case 'FF9900': + $colorIdxFg = 0x34; + break; + case 'FF6600': + $colorIdxFg = 0x35; + break; + case '666699': + $colorIdxFg = 0x36; + break; + case '969696': + $colorIdxFg = 0x37; + break; + case '003366': + $colorIdxFg = 0x38; + break; + case '339966': + $colorIdxFg = 0x39; + break; + case '003300': + $colorIdxFg = 0x3A; + break; + case '333300': + $colorIdxFg = 0x3B; + break; + case '993300': + $colorIdxFg = 0x3C; + break; + case '993366': + $colorIdxFg = 0x3D; + break; + case '333399': + $colorIdxFg = 0x3E; + break; + case '333333': + $colorIdxFg = 0x3F; + break; + default: + $colorIdxFg = 0x40; + break; } $dataBlockFill = pack('v', $blockFillPatternStyle); $dataBlockFill .= pack('v', $colorIdxFg | ($colorIdxBg << 7)); } - if($bFormatProt == 1){ + if ($bFormatProt == 1) { $dataBlockProtection = 0; - if($conditional->getStyle()->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){ + if ($conditional->getStyle()->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED) { $dataBlockProtection = 1; } - if($conditional->getStyle()->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){ + if ($conditional->getStyle()->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED) { $dataBlockProtection = 1 << 1; } } $data = pack('CCvvVv', $type, $operatorType, $szValue1, $szValue2, $flags, 0x0000); - if($bFormatFont == 1){ // Block Formatting : OK + if ($bFormatFont == 1) { // Block Formatting : OK $data .= $dataBlockFont; } - if($bFormatAlign == 1){ + if ($bFormatAlign == 1) { $data .= $dataBlockAlign; } - if($bFormatBorder == 1){ + if ($bFormatBorder == 1) { $data .= $dataBlockBorder; } - if($bFormatFill == 1){ // Block Formatting : OK + if ($bFormatFill == 1) { // Block Formatting : OK $data .= $dataBlockFill; } - if($bFormatProt == 1){ + if ($bFormatProt == 1) { $data .= $dataBlockProtection; } - if(!is_null($operand1)){ + if (!is_null($operand1)) { $data .= $operand1; } - if(!is_null($operand2)){ + if (!is_null($operand2)) { $data .= $operand2; } $header = pack('vv', $record, strlen($data)); @@ -3632,7 +4236,8 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ /** * Write CFHeader record */ - private function _writeCFHeader(){ + private function _writeCFHeader() + { $record = 0x01B0; // Record identifier $length = 0x0016; // Bytes to follow @@ -3643,26 +4248,26 @@ private function _writeCFHeader(){ $arrConditional = array(); foreach ($this->_phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { foreach ($conditionalStyles as $conditional) { - if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION - || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ - if(!in_array($conditional->getHashCode(), $arrConditional)){ + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS) { + if (!in_array($conditional->getHashCode(), $arrConditional)) { $arrConditional[] = $conditional->getHashCode(); } // Cells $arrCoord = PHPExcel_Cell::coordinateFromString($cellCoordinate); - if(!is_numeric($arrCoord[0])){ + if (!is_numeric($arrCoord[0])) { $arrCoord[0] = PHPExcel_Cell::columnIndexFromString($arrCoord[0]); } - if(is_null($numColumnMin) || ($numColumnMin > $arrCoord[0])){ + if (is_null($numColumnMin) || ($numColumnMin > $arrCoord[0])) { $numColumnMin = $arrCoord[0]; } - if(is_null($numColumnMax) || ($numColumnMax < $arrCoord[0])){ + if (is_null($numColumnMax) || ($numColumnMax < $arrCoord[0])) { $numColumnMax = $arrCoord[0]; } - if(is_null($numRowMin) || ($numRowMin > $arrCoord[1])){ + if (is_null($numRowMin) || ($numRowMin > $arrCoord[1])) { $numRowMin = $arrCoord[1]; } - if(is_null($numRowMax) || ($numRowMax < $arrCoord[1])){ + if (is_null($numRowMax) || ($numRowMax < $arrCoord[1])) { $numRowMax = $arrCoord[1]; } } From d019ce5956c653d4911eb68b679a42f61b7546c4 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Tue, 12 May 2015 13:30:05 +0200 Subject: [PATCH 355/467] PSR-2 : Improve Travis CI Report --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9c5e11a95..63dbdfc8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ before_script: script: ## PHP_CodeSniffer - - ./vendor/bin/phpcs Classes/ unitTests/ --standard=PSR2 -n --ignore=Classes/PHPExcel/Shared/PCLZip + - ./vendor/bin/phpcs --report-summary --report-full Classes/ unitTests/ --standard=PSR2 -n ## PHPUnit - phpunit -c ./unitTests/ From 6850d8a29d2038fb34d3062db64b8a8e82e03468 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Tue, 12 May 2015 13:36:33 +0200 Subject: [PATCH 356/467] PSR-2 : Improve Travis CI Report --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 63dbdfc8c..cfb8941d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ before_script: script: ## PHP_CodeSniffer - - ./vendor/bin/phpcs --report-summary --report-full Classes/ unitTests/ --standard=PSR2 -n + - ./vendor/bin/phpcs --report-width=auto --report-summary --report-full Classes/ unitTests/ --standard=PSR2 -n ## PHPUnit - phpunit -c ./unitTests/ From 2896d62e08c926fced1fc2cd34ed984a97628010 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Tue, 12 May 2015 13:45:25 +0200 Subject: [PATCH 357/467] PSR-2 : Improve Travis CI Report --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cfb8941d0..fc2b5f248 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ before_script: script: ## PHP_CodeSniffer - - ./vendor/bin/phpcs --report-width=auto --report-summary --report-full Classes/ unitTests/ --standard=PSR2 -n + - ./vendor/bin/phpcs --report-width=200 --report-summary --report-full Classes/ unitTests/ --standard=PSR2 -n ## PHPUnit - phpunit -c ./unitTests/ From 5bb747f8cc08bcfcbe0942d1942b11cf3f202507 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Tue, 12 May 2015 14:01:22 +0200 Subject: [PATCH 358/467] PSR-2 : Fixes --- Classes/PHPExcel/Cell/AdvancedValueBinder.php | 14 ++-- Classes/PHPExcel/Cell/DataValidation.php | 3 +- Classes/PHPExcel/Chart/Axis.php | 36 ++++++----- Classes/PHPExcel/IComparable.php | 1 - Classes/PHPExcel/Writer/Excel5/Worksheet.php | 64 ++++++++----------- Classes/PHPExcel/Writer/Excel5/Xf.php | 12 ++-- Classes/PHPExcel/Writer/HTML.php | 2 +- 7 files changed, 66 insertions(+), 66 deletions(-) diff --git a/Classes/PHPExcel/Cell/AdvancedValueBinder.php b/Classes/PHPExcel/Cell/AdvancedValueBinder.php index ee2de791d..061d04eb5 100644 --- a/Classes/PHPExcel/Cell/AdvancedValueBinder.php +++ b/Classes/PHPExcel/Cell/AdvancedValueBinder.php @@ -113,9 +113,9 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) if (preg_match('/^'.preg_quote($currencyCode).' *(\d{1,3}('.preg_quote($thousandsSeparator).'\d{3})*|(\d+))('.preg_quote($decimalSeparator).'\d{2})?$/', $value)) { // Convert value to number $value = (float) trim(str_replace(array($currencyCode, $thousandsSeparator, $decimalSeparator), array('', '', '.'), $value)); - $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode( str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE) ); @@ -123,9 +123,9 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) } elseif (preg_match('/^\$ *(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/', $value)) { // Convert value to number $value = (float) trim(str_replace(array('$',','), '', $value)); - $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE); return true; } @@ -137,7 +137,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) $days = $h / 24 + $m / 1440; $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3); return true; } @@ -150,7 +150,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) // Convert value to number $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); // Set style - $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4); return true; } @@ -165,7 +165,7 @@ public function bindValue(PHPExcel_Cell $cell, $value = null) } else { $formatCode = 'yyyy-mm-dd'; } - $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + $cell->getWorksheet()->getStyle($cell->getCoordinate()) ->getNumberFormat()->setFormatCode($formatCode); return true; } diff --git a/Classes/PHPExcel/Cell/DataValidation.php b/Classes/PHPExcel/Cell/DataValidation.php index a9963b084..9883633e6 100644 --- a/Classes/PHPExcel/Cell/DataValidation.php +++ b/Classes/PHPExcel/Cell/DataValidation.php @@ -191,7 +191,8 @@ public function setFormula1($value = '') * * @return string */ - public function getFormula2() { + public function getFormula2() + { return $this->formula2; } diff --git a/Classes/PHPExcel/Chart/Axis.php b/Classes/PHPExcel/Chart/Axis.php index 65abf9caf..8b5d1d54d 100644 --- a/Classes/PHPExcel/Chart/Axis.php +++ b/Classes/PHPExcel/Chart/Axis.php @@ -176,9 +176,7 @@ public function getAxisNumberSourceLinked() * @param string $minor_unit * */ - public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = null, $horizontal_crosses = null, - $axis_orientation = null, $major_tmt = null, $minor_tmt = null, $minimum = null, $maximum = null, $major_unit = null, - $minor_unit = null) + public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = null, $horizontal_crosses = null, $axis_orientation = null, $major_tmt = null, $minor_tmt = null, $minimum = null, $maximum = null, $major_unit = null, $minor_unit = null) { $this->_axis_options['axis_labels'] = (string) $axis_labels; ($horizontal_crosses_value !== null) @@ -201,7 +199,8 @@ public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value * * @return string */ - public function getAxisOptionsProperty($property) { + public function getAxisOptionsProperty($property) + { return $this->_axis_options[$property]; } @@ -211,7 +210,8 @@ public function getAxisOptionsProperty($property) { * @param string $orientation * */ - public function setAxisOrientation($orientation) { + public function setAxisOrientation($orientation) + { $this->orientation = (string) $orientation; } @@ -223,7 +223,8 @@ public function setAxisOrientation($orientation) { * @param string $type * */ - public function setFillParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) { + public function setFillParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) + { $this->_fill_properties = $this->setColorProperties($color, $alpha, $type); } @@ -235,7 +236,8 @@ public function setFillParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_ * @param string $type * */ - public function setLineParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) { + public function setLineParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) + { $this->_line_properties = $this->setColorProperties($color, $alpha, $type); } @@ -246,7 +248,8 @@ public function setLineParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_ * * @return string */ - public function getFillProperty($property) { + public function getFillProperty($property) + { return $this->_fill_properties[$property]; } @@ -257,7 +260,8 @@ public function getFillProperty($property) { * * @return string */ - public function getLineProperty($property) { + public function getLineProperty($property) + { return $this->_line_properties[$property]; } @@ -276,10 +280,7 @@ public function getLineProperty($property) { * */ - public function setLineStyleProperties($line_width = null, $compound_type = null, - $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, - $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) { - + public function setLineStyleProperties($line_width = null, $compound_type = null, $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) { (!is_null($line_width)) ? $this->_line_style_properties['width'] = $this->getExcelPointsWidth((float) $line_width) : null; (!is_null($compound_type)) ? $this->_line_style_properties['compound'] = (string) $compound_type : null; @@ -304,7 +305,8 @@ public function setLineStyleProperties($line_width = null, $compound_type = null * @return string */ - public function getLineStyleProperty($elements) { + public function getLineStyleProperty($elements) + { return $this->getArrayElementsValue($this->_line_style_properties, $elements); } @@ -316,7 +318,8 @@ public function getLineStyleProperty($elements) { * @return string */ - public function getLineStyleArrowWidth($arrow) { + public function getLineStyleArrowWidth($arrow) + { return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'w'); } @@ -328,7 +331,8 @@ public function getLineStyleArrowWidth($arrow) { * @return string */ - public function getLineStyleArrowLength($arrow) { + public function getLineStyleArrowLength($arrow) + { return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'len'); } diff --git a/Classes/PHPExcel/IComparable.php b/Classes/PHPExcel/IComparable.php index 62a06aea9..6dc36a948 100644 --- a/Classes/PHPExcel/IComparable.php +++ b/Classes/PHPExcel/IComparable.php @@ -31,5 +31,4 @@ interface PHPExcel_IComparable * @return string Hash code */ public function getHashCode(); - } diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index a06d489ab..d0ad7585d 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -432,8 +432,7 @@ public function close() // FONT Index if ($element instanceof PHPExcel_RichText_Run) { $str_fontidx = $this->_fntHashIndex[$element->getFont()->getHashCode()]; - } - else { + } else { $str_fontidx = 0; } $arrcRun[] = array('strlen' => $str_pos, 'fontidx' => $str_fontidx); @@ -573,12 +572,7 @@ private function _writeBIFF8CellRangeAddressFixed($range = 'A1') $firstCellCoordinates = PHPExcel_Cell::coordinateFromString($firstCell); // e.g. array(0, 1) $lastCellCoordinates = PHPExcel_Cell::coordinateFromString($lastCell); // e.g. array(1, 6) - return(pack('vvvv', - $firstCellCoordinates[1] - 1, - $lastCellCoordinates[1] - 1, - PHPExcel_Cell::columnIndexFromString($firstCellCoordinates[0]) - 1, - PHPExcel_Cell::columnIndexFromString($lastCellCoordinates[0]) - 1 - )); + return pack('vvvv', $firstCellCoordinates[1] - 1, $lastCellCoordinates[1] - 1, PHPExcel_Cell::columnIndexFromString($firstCellCoordinates[0]) - 1, PHPExcel_Cell::columnIndexFromString($lastCellCoordinates[0]) - 1); } /** @@ -632,7 +626,7 @@ public function setOutline($visible = true, $symbols_below = true, $symbols_righ if ($this->_outline_on) { $this->_outline_on = 1; } - } + } /** * Write a double to the specified row and column (zero indexed). @@ -907,7 +901,7 @@ private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) // Strip the '=' or '@' sign at the beginning of the formula string if ($formula{0} == '=') { - $formula = substr($formula,1); + $formula = substr($formula, 1); } else { // Error handling $this->_writeString($row, $col, 'Unrecognised character for formula'); @@ -922,7 +916,7 @@ private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) $formlen = strlen($formula); // Length of the binary string $length = 0x16 + $formlen; // Length of the record data - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $xfIndex) . $num @@ -1048,7 +1042,7 @@ public function _writeUrlWeb($row1, $col1, $row2, $col2, $url) $length = 0x34 + strlen($url); // Pack the header data - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvv", $row1, $row2, $col1, $col2); // Write the packed data @@ -1097,7 +1091,7 @@ public function _writeUrlInternal($row1, $col1, $row2, $col2, $url) $length = 0x24 + strlen($url); // Pack the header data - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvv", $row1, $row2, $col1, $col2); // Write the packed data @@ -1173,15 +1167,15 @@ public function _writeUrlExternal($row1, $col1, $row2, $col2, $url) $dir_long = $dir_long . "\0"; // Pack the lengths of the dir strings - $dir_short_len = pack("V", strlen($dir_short) ); - $dir_long_len = pack("V", strlen($dir_long) ); - $stream_len = pack("V", 0);//strlen($dir_long) + 0x06); + $dir_short_len = pack("V", strlen($dir_short)); + $dir_long_len = pack("V", strlen($dir_long)); + $stream_len = pack("V", 0); //strlen($dir_long) + 0x06); // Pack the undocumented parts of the hyperlink stream - $unknown1 = pack("H*",'D0C9EA79F9BACE118C8200AA004BA90B02000000' ); - $unknown2 = pack("H*",'0303000000000000C000000000000046' ); - $unknown3 = pack("H*",'FFFFADDE000000000000000000000000000000000000000'); - $unknown4 = pack("v", 0x03 ); + $unknown1 = pack("H*", 'D0C9EA79F9BACE118C8200AA004BA90B02000000'); + $unknown2 = pack("H*", '0303000000000000C000000000000046'); + $unknown3 = pack("H*", 'FFFFADDE000000000000000000000000000000000000000'); + $unknown4 = pack("v", 0x03); // Pack the main data stream $data = pack("vvvv", $row1, $row2, $col1, $col2) . @@ -1230,7 +1224,7 @@ private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) $grbit = 0x0000; // Option flags $ixfe = $xfIndex; - if ($height < 0 ) { + if ($height < 0) { $height = null; } @@ -1259,9 +1253,8 @@ private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) } $grbit |= 0x0100; - $header = pack("vv", $record, $length); - $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, - $irwMac,$reserved, $grbit, $ixfe); + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, $irwMac,$reserved, $grbit, $ixfe); $this->_append($header.$data); } @@ -1325,7 +1318,7 @@ private function _writeWindow2() // FIXME !!! $rgbHdr = 0x0040; // Row/column heading and gridline color index - $zoom_factor_page_break = ($fPageBreakPreview? $this->_phpSheet->getSheetView()->getZoomScale() : 0x0000); + $zoom_factor_page_break = ($fPageBreakPreview ? $this->_phpSheet->getSheetView()->getZoomScale() : 0x0000); $zoom_factor_normal = $this->_phpSheet->getSheetView()->getZoomScaleNormal(); $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000); @@ -1423,9 +1416,8 @@ private function _writeColinfo($col_array) $level = max(0, min($level, 7)); $grbit |= $level << 8; - $header = pack("vv", $record, $length); - $data = pack("vvvvvv", $colFirst, $colLast, $coldx, - $ixfe, $grbit, $reserved); + $header = pack("vv", $record, $length); + $data = pack("vvvvvv", $colFirst, $colLast, $coldx, $ixfe, $grbit, $reserved); $this->_append($header.$data); } @@ -1554,14 +1546,14 @@ private function _writeSheetLayout() } $recordData = pack( - 'vvVVVvv' - , 0x0862 - , 0x0000 // unused - , 0x00000000 // unused - , 0x00000000 // unused - , 0x00000014 // size of record data - , $this->_colors[$this->_phpSheet->getTabColor()->getRGB()] // color index - , 0x0000 // unused + 'vvVVVvv', + 0x0862, + 0x0000, // unused + 0x00000000, // unused + 0x00000000, // unused + 0x00000014, // size of record data + $this->_colors[$this->_phpSheet->getTabColor()->getRGB()], // color index + 0x0000 // unused ); $length = strlen($recordData); diff --git a/Classes/PHPExcel/Writer/Excel5/Xf.php b/Classes/PHPExcel/Writer/Excel5/Xf.php index 6d953f816..dc185f00c 100644 --- a/Classes/PHPExcel/Writer/Excel5/Xf.php +++ b/Classes/PHPExcel/Writer/Excel5/Xf.php @@ -491,7 +491,8 @@ private function _mapHAlign($hAlign) * @param string $vAlign * @return int */ - private static function _mapVAlign($vAlign) { + private static function _mapVAlign($vAlign) + { if (isset(self::$_mapVAlign[$vAlign])) { return self::$_mapVAlign[$vAlign]; } @@ -504,7 +505,8 @@ private static function _mapVAlign($vAlign) { * @param int $textRotation * @return int */ - private static function _mapTextRotation($textRotation) { + private static function _mapTextRotation($textRotation) + { if ($textRotation >= 0) { return $textRotation; } @@ -522,7 +524,8 @@ private static function _mapTextRotation($textRotation) { * @param string * @return int */ - private static function _mapLocked($locked) { + private static function _mapLocked($locked) + { switch ($locked) { case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 1; @@ -541,7 +544,8 @@ private static function _mapLocked($locked) { * @param string * @return int */ - private static function _mapHidden($hidden) { + private static function _mapHidden($hidden) + { switch ($hidden) { case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 0; diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 4821cf06a..eecc6ec69 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -944,7 +944,7 @@ private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) $css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical()); if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) { $css['text-align'] = $textAlign; - if (in_array($textAlign,array('left', 'right'))) { + if (in_array($textAlign, array('left', 'right'))) { $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px'; } } From f37630e938da2f1dbe9f16a20fdfbf701403812b Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Tue, 12 May 2015 17:57:29 +0200 Subject: [PATCH 359/467] PSR-2 : Fixes --- .../PHPExcel/Writer/Excel2007/WriterPart.php | 10 +- Classes/PHPExcel/Writer/Excel5.php | 168 +++-- Classes/PHPExcel/Writer/Excel5/BIFFwriter.php | 13 +- Classes/PHPExcel/Writer/Excel5/Escher.php | 633 +++++++++--------- Classes/PHPExcel/Writer/Excel5/Font.php | 38 +- Classes/PHPExcel/Writer/Excel5/Parser.php | 168 +++-- Classes/PHPExcel/Writer/Excel5/Workbook.php | 90 +-- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 119 ++-- 8 files changed, 599 insertions(+), 640 deletions(-) diff --git a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php index a25ecd6a6..b32f1ad41 100644 --- a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php +++ b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php @@ -48,7 +48,8 @@ abstract class PHPExcel_Writer_Excel2007_WriterPart * @param PHPExcel_Writer_IWriter $pWriter * @throws PHPExcel_Writer_Exception */ - public function setParentWriter(PHPExcel_Writer_IWriter $pWriter = null) { + public function setParentWriter(PHPExcel_Writer_IWriter $pWriter = null) + { $this->_parentWriter = $pWriter; } @@ -58,7 +59,8 @@ public function setParentWriter(PHPExcel_Writer_IWriter $pWriter = null) { * @return PHPExcel_Writer_IWriter * @throws PHPExcel_Writer_Exception */ - public function getParentWriter() { + public function getParentWriter() + { if (!is_null($this->_parentWriter)) { return $this->_parentWriter; } else { @@ -72,10 +74,10 @@ public function getParentWriter() { * @param PHPExcel_Writer_IWriter $pWriter * @throws PHPExcel_Writer_Exception */ - public function __construct(PHPExcel_Writer_IWriter $pWriter = null) { + public function __construct(PHPExcel_Writer_IWriter $pWriter = null) + { if (!is_null($pWriter)) { $this->_parentWriter = $pWriter; } } - } diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index 63a4ca721..d2502aa02 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -95,7 +95,8 @@ class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExce * * @param PHPExcel $phpExcel PHPExcel object */ - public function __construct(PHPExcel $phpExcel) { + public function __construct(PHPExcel $phpExcel) + { $this->_phpExcel = $phpExcel; $this->_parser = new PHPExcel_Writer_Excel5_Parser(); @@ -107,13 +108,14 @@ public function __construct(PHPExcel $phpExcel) { * @param string $pFilename * @throws PHPExcel_Writer_Exception */ - public function save($pFilename = null) { + public function save($pFilename = null) + { // garbage collect $this->_phpExcel->garbageCollect(); $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(false); $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); @@ -121,18 +123,12 @@ public function save($pFilename = null) { $this->_colors = array(); // Initialise workbook writer - $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel, - $this->_str_total, $this->_str_unique, $this->_str_table, - $this->_colors, $this->_parser); + $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel, $this->_str_total, $this->_str_unique, $this->_str_table, $this->_colors, $this->_parser); // Initialise worksheet writers $countSheets = $this->_phpExcel->getSheetCount(); for ($i = 0; $i < $countSheets; ++$i) { - $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->_str_total, $this->_str_unique, - $this->_str_table, $this->_colors, - $this->_parser, - $this->_preCalculateFormulas, - $this->_phpExcel->getSheet($i)); + $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->_str_total, $this->_str_unique, $this->_str_table, $this->_colors, $this->_parser, $this->_preCalculateFormulas, $this->_phpExcel->getSheet($i)); } // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook. @@ -190,26 +186,26 @@ public function save($pFilename = null) { $this->_documentSummaryInformation = $this->_writeDocumentSummaryInformation(); // initialize OLE Document Summary Information - if(isset($this->_documentSummaryInformation) && !empty($this->_documentSummaryInformation)){ + if (isset($this->_documentSummaryInformation) && !empty($this->_documentSummaryInformation)) { $OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation')); $OLE_DocumentSummaryInformation->append($this->_documentSummaryInformation); } $this->_summaryInformation = $this->_writeSummaryInformation(); // initialize OLE Summary Information - if(isset($this->_summaryInformation) && !empty($this->_summaryInformation)){ - $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation')); - $OLE_SummaryInformation->append($this->_summaryInformation); + if (isset($this->_summaryInformation) && !empty($this->_summaryInformation)) { + $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation')); + $OLE_SummaryInformation->append($this->_summaryInformation); } // define OLE Parts $arrRootData = array($OLE); // initialize OLE Properties file - if(isset($OLE_SummaryInformation)){ + if (isset($OLE_SummaryInformation)) { $arrRootData[] = $OLE_SummaryInformation; } // initialize OLE Extended Properties file - if(isset($OLE_DocumentSummaryInformation)){ + if (isset($OLE_DocumentSummaryInformation)) { $arrRootData[] = $OLE_DocumentSummaryInformation; } @@ -229,7 +225,8 @@ public function save($pFilename = null) { * @throws PHPExcel_Writer_Exception when directory does not exist * @return PHPExcel_Writer_Excel5 */ - public function setTempDir($pValue = '') { + public function setTempDir($pValue = '') + { return $this; } @@ -330,13 +327,13 @@ private function _buildWorksheetEschers() } // AutoFilters - if(!empty($filterRange)){ + if (!empty($filterRange)) { $rangeBounds = PHPExcel_Cell::rangeBoundaries($filterRange); $iNumColStart = $rangeBounds[0][0]; $iNumColEnd = $rangeBounds[1][0]; $iInc = $iNumColStart; - while($iInc <= $iNumColEnd){ + while($iInc <= $iNumColEnd) { ++$countShapes[$sheetIndex]; // create an Drawing Object for the dropdown @@ -444,8 +441,7 @@ private function _buildWorkbookEscher() ++$sheetCountShapes; ++$totalCountShapes; - $spId = $sheetCountShapes - | ($this->_phpExcel->getIndex($sheet) + 1) << 10; + $spId = $sheetCountShapes | ($this->_phpExcel->getIndex($sheet) + 1) << 10; $spIdMax = max($spId, $spIdMax); } } @@ -463,41 +459,35 @@ private function _buildWorkbookEscher() foreach ($this->_phpExcel->getAllsheets() as $sheet) { foreach ($sheet->getDrawingCollection() as $drawing) { if ($drawing instanceof PHPExcel_Worksheet_Drawing) { - $filename = $drawing->getPath(); list($imagesx, $imagesy, $imageFormat) = getimagesize($filename); switch ($imageFormat) { - - case 1: // GIF, not supported by BIFF8, we convert to PNG - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; - ob_start(); - imagepng(imagecreatefromgif($filename)); - $blipData = ob_get_contents(); - ob_end_clean(); - break; - - case 2: // JPEG - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; - $blipData = file_get_contents($filename); - break; - - case 3: // PNG - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; - $blipData = file_get_contents($filename); - break; - - case 6: // Windows DIB (BMP), we convert to PNG - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; - ob_start(); - imagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename)); - $blipData = ob_get_contents(); - ob_end_clean(); - break; - - default: continue 2; - + case 1: // GIF, not supported by BIFF8, we convert to PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + ob_start(); + imagepng(imagecreatefromgif ($filename)); + $blipData = ob_get_contents(); + ob_end_clean(); + break; + case 2: // JPEG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; + $blipData = file_get_contents($filename); + break; + case 3: // PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + $blipData = file_get_contents($filename); + break; + case 6: // Windows DIB (BMP), we convert to PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + ob_start(); + imagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename)); + $blipData = ob_get_contents(); + ob_end_clean(); + break; + default: + continue 2; } $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); @@ -508,23 +498,18 @@ private function _buildWorkbookEscher() $BSE->setBlip($blip); $bstoreContainer->addBSE($BSE); - } else if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { - switch ($drawing->getRenderingFunction()) { - - case PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG: - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; - $renderingFunction = 'imagejpeg'; - break; - - case PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF: - case PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG: - case PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT: - $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; - $renderingFunction = 'imagepng'; - break; - + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG: + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; + $renderingFunction = 'imagejpeg'; + break; + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF: + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG: + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT: + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + $renderingFunction = 'imagepng'; + break; } ob_start(); @@ -552,8 +537,8 @@ private function _buildWorkbookEscher() * Build the OLE Part for DocumentSummary Information * @return string */ - private function _writeDocumentSummaryInformation(){ - + private function _writeDocumentSummaryInformation() + { // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) $data = pack('v', 0xFFFE); // offset: 2; size: 2; @@ -586,7 +571,7 @@ private function _writeDocumentSummaryInformation(){ $dataSection_NumProps++; // GKPIDDSI_CATEGORY : Category - if($this->_phpExcel->getProperties()->getCategory()){ + if ($this->_phpExcel->getProperties()->getCategory()) { $dataProp = $this->_phpExcel->getProperties()->getCategory(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), 'offset' => array('pack' => 'V'), @@ -682,7 +667,7 @@ private function _writeDocumentSummaryInformation(){ // 4 Property count // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; - foreach ($dataSection as $dataProp){ + foreach ($dataSection as $dataProp) { // Summary $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); // Offset @@ -690,25 +675,25 @@ private function _writeDocumentSummaryInformation(){ // DataType $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); // Data - if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer + if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; } - elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer + elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; } - elseif($dataProp['type']['data'] == 0x0B){ // Boolean - if($dataProp['data']['data'] == false){ + elseif ($dataProp['type']['data'] == 0x0B) { // Boolean + if ($dataProp['data']['data'] == false) { $dataSection_Content .= pack('V', 0x0000); } else { $dataSection_Content .= pack('V', 0x0001); } $dataSection_Content_Offset += 4 + 4; } - elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length + elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length // Null-terminated string $dataProp['data']['data'] .= chr(0); $dataProp['data']['length'] += 1; @@ -721,7 +706,7 @@ private function _writeDocumentSummaryInformation(){ $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); } - elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + 8; @@ -753,7 +738,8 @@ private function _writeDocumentSummaryInformation(){ * Build the OLE Part for Summary Information * @return string */ - private function _writeSummaryInformation(){ + private function _writeSummaryInformation() + { // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) $data = pack('v', 0xFFFE); // offset: 2; size: 2; @@ -786,7 +772,7 @@ private function _writeSummaryInformation(){ $dataSection_NumProps++; // Title - if($this->_phpExcel->getProperties()->getTitle()){ + if ($this->_phpExcel->getProperties()->getTitle()) { $dataProp = $this->_phpExcel->getProperties()->getTitle(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), 'offset' => array('pack' => 'V'), @@ -795,7 +781,7 @@ private function _writeSummaryInformation(){ $dataSection_NumProps++; } // Subject - if($this->_phpExcel->getProperties()->getSubject()){ + if ($this->_phpExcel->getProperties()->getSubject()) { $dataProp = $this->_phpExcel->getProperties()->getSubject(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03), 'offset' => array('pack' => 'V'), @@ -804,7 +790,7 @@ private function _writeSummaryInformation(){ $dataSection_NumProps++; } // Author (Creator) - if($this->_phpExcel->getProperties()->getCreator()){ + if ($this->_phpExcel->getProperties()->getCreator()) { $dataProp = $this->_phpExcel->getProperties()->getCreator(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04), 'offset' => array('pack' => 'V'), @@ -813,7 +799,7 @@ private function _writeSummaryInformation(){ $dataSection_NumProps++; } // Keywords - if($this->_phpExcel->getProperties()->getKeywords()){ + if ($this->_phpExcel->getProperties()->getKeywords()) { $dataProp = $this->_phpExcel->getProperties()->getKeywords(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05), 'offset' => array('pack' => 'V'), @@ -822,7 +808,7 @@ private function _writeSummaryInformation(){ $dataSection_NumProps++; } // Comments (Description) - if($this->_phpExcel->getProperties()->getDescription()){ + if ($this->_phpExcel->getProperties()->getDescription()) { $dataProp = $this->_phpExcel->getProperties()->getDescription(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06), 'offset' => array('pack' => 'V'), @@ -831,7 +817,7 @@ private function _writeSummaryInformation(){ $dataSection_NumProps++; } // Last Saved By (LastModifiedBy) - if($this->_phpExcel->getProperties()->getLastModifiedBy()){ + if ($this->_phpExcel->getProperties()->getLastModifiedBy()) { $dataProp = $this->_phpExcel->getProperties()->getLastModifiedBy(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08), 'offset' => array('pack' => 'V'), @@ -840,7 +826,7 @@ private function _writeSummaryInformation(){ $dataSection_NumProps++; } // Created Date/Time - if($this->_phpExcel->getProperties()->getCreated()){ + if ($this->_phpExcel->getProperties()->getCreated()) { $dataProp = $this->_phpExcel->getProperties()->getCreated(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), 'offset' => array('pack' => 'V'), @@ -849,7 +835,7 @@ private function _writeSummaryInformation(){ $dataSection_NumProps++; } // Modified Date/Time - if($this->_phpExcel->getProperties()->getModified()){ + if ($this->_phpExcel->getProperties()->getModified()) { $dataProp = $this->_phpExcel->getProperties()->getModified(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), 'offset' => array('pack' => 'V'), @@ -869,7 +855,7 @@ private function _writeSummaryInformation(){ // 4 Property count // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; - foreach ($dataSection as $dataProp){ + foreach ($dataSection as $dataProp) { // Summary $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); // Offset @@ -877,17 +863,17 @@ private function _writeSummaryInformation(){ // DataType $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); // Data - if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer + if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; } - elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer + elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; } - elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length + elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length // Null-terminated string $dataProp['data']['data'] .= chr(0); $dataProp['data']['length'] += 1; @@ -900,7 +886,7 @@ private function _writeSummaryInformation(){ $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); } - elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + 8; diff --git a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php index de0624888..05ae77fff 100644 --- a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php +++ b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php @@ -118,7 +118,7 @@ public static function getByteOrder() $number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F); if ($number == $teststr) { $byte_order = 0; // Little Endian - } elseif ($number == strrev($teststr)){ + } elseif ($number == strrev($teststr)) { $byte_order = 1; // Big Endian } else { // Give up. I'll fix this in a later version. @@ -136,7 +136,7 @@ public static function getByteOrder() * @param string $data binary data to append * @access private */ - function _append($data) + private function _append($data) { if (strlen($data) - 4 > $this->_limit) { $data = $this->_addContinue($data); @@ -169,7 +169,7 @@ public function writeData($data) * 0x0010 Worksheet. * @access private */ - function _storeBof($type) + private function _storeBof($type) { $record = 0x0809; // Record identifier (BIFF5-BIFF8) $length = 0x0010; @@ -182,7 +182,7 @@ function _storeBof($type) $version = 0x0600; // BIFF8 - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvv", $version, $type, $build, $year); $this->_append($header . $data . $unknown); } @@ -192,7 +192,7 @@ function _storeBof($type) * * @access private */ - function _storeEof() + private function _storeEof() { $record = 0x000A; // Record identifier $length = 0x0000; // Number of bytes to follow @@ -226,7 +226,7 @@ public function writeEof() * @return string A very convenient string of continue blocks * @access private */ - function _addContinue($data) + private function _addContinue($data) { $limit = $this->_limit; $record = 0x003C; // Record identifier @@ -251,5 +251,4 @@ function _addContinue($data) return $tmp; } - } diff --git a/Classes/PHPExcel/Writer/Excel5/Escher.php b/Classes/PHPExcel/Writer/Excel5/Escher.php index 9b8ae8714..62e62f224 100644 --- a/Classes/PHPExcel/Writer/Excel5/Escher.php +++ b/Classes/PHPExcel/Writer/Excel5/Escher.php @@ -78,199 +78,135 @@ public function close() $this->_data = ''; switch (get_class($this->_object)) { - - case 'PHPExcel_Shared_Escher': - if ($dggContainer = $this->_object->getDggContainer()) { - $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer); - $this->_data = $writer->close(); - } else if ($dgContainer = $this->_object->getDgContainer()) { - $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer); - $this->_data = $writer->close(); - $this->_spOffsets = $writer->getSpOffsets(); - $this->_spTypes = $writer->getSpTypes(); - } - break; - - case 'PHPExcel_Shared_Escher_DggContainer': - // this is a container record - - // initialize - $innerData = ''; - - // write the dgg - $recVer = 0x0; - $recInstance = 0x0000; - $recType = 0xF006; - - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; - - // dgg data - $dggData = - pack('VVVV' - , $this->_object->getSpIdMax() // maximum shape identifier increased by one - , $this->_object->getCDgSaved() + 1 // number of file identifier clusters increased by one - , $this->_object->getCSpSaved() - , $this->_object->getCDgSaved() // count total number of drawings saved - ); - - // add file identifier clusters (one per drawing) - $IDCLs = $this->_object->getIDCLs(); - - foreach ($IDCLs as $dgId => $maxReducedSpId) { - $dggData .= pack('VV', $dgId, $maxReducedSpId + 1); - } - - $header = pack('vvV', $recVerInstance, $recType, strlen($dggData)); - $innerData .= $header . $dggData; - - // write the bstoreContainer - if ($bstoreContainer = $this->_object->getBstoreContainer()) { - $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer); - $innerData .= $writer->close(); - } - - // write the record - $recVer = 0xF; - $recInstance = 0x0000; - $recType = 0xF000; - $length = strlen($innerData); - - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; - - $header = pack('vvV', $recVerInstance, $recType, $length); - - $this->_data = $header . $innerData; - break; - - case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer': - // this is a container record - - // initialize - $innerData = ''; - - // treat the inner data - if ($BSECollection = $this->_object->getBSECollection()) { - foreach ($BSECollection as $BSE) { - $writer = new PHPExcel_Writer_Excel5_Escher($BSE); - $innerData .= $writer->close(); + case 'PHPExcel_Shared_Escher': + if ($dggContainer = $this->_object->getDggContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer); + $this->_data = $writer->close(); + } else if ($dgContainer = $this->_object->getDgContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer); + $this->_data = $writer->close(); + $this->_spOffsets = $writer->getSpOffsets(); + $this->_spTypes = $writer->getSpTypes(); } - } - - // write the record - $recVer = 0xF; - $recInstance = count($this->_object->getBSECollection()); - $recType = 0xF001; - $length = strlen($innerData); - - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; - - $header = pack('vvV', $recVerInstance, $recType, $length); - - $this->_data = $header . $innerData; - break; - - case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE': - // this is a semi-container record - - // initialize - $innerData = ''; - - // here we treat the inner data - if ($blip = $this->_object->getBlip()) { - $writer = new PHPExcel_Writer_Excel5_Escher($blip); - $innerData .= $writer->close(); - } + break; + case 'PHPExcel_Shared_Escher_DggContainer': + // this is a container record - // initialize - $data = ''; + // initialize + $innerData = ''; - $btWin32 = $this->_object->getBlipType(); - $btMacOS = $this->_object->getBlipType(); - $data .= pack('CC', $btWin32, $btMacOS); + // write the dgg + $recVer = 0x0; + $recInstance = 0x0000; + $recType = 0xF006; - $rgbUid = pack('VVVV', 0,0,0,0); // todo - $data .= $rgbUid; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $tag = 0; - $size = strlen($innerData); - $cRef = 1; - $foDelay = 0; //todo - $unused1 = 0x0; - $cbName = 0x0; - $unused2 = 0x0; - $unused3 = 0x0; - $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3); + // dgg data + $dggData = + pack('VVVV', + $this->_object->getSpIdMax(), // maximum shape identifier increased by one + $this->_object->getCDgSaved() + 1, // number of file identifier clusters increased by one + $this->_object->getCSpSaved(), + $this->_object->getCDgSaved() // count total number of drawings saved + ); - $data .= $innerData; + // add file identifier clusters (one per drawing) + $IDCLs = $this->_object->getIDCLs(); - // write the record - $recVer = 0x2; - $recInstance = $this->_object->getBlipType(); - $recType = 0xF007; - $length = strlen($data); + foreach ($IDCLs as $dgId => $maxReducedSpId) { + $dggData .= pack('VV', $dgId, $maxReducedSpId + 1); + } - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $header = pack('vvV', $recVerInstance, $recType, strlen($dggData)); + $innerData .= $header . $dggData; - $header = pack('vvV', $recVerInstance, $recType, $length); + // write the bstoreContainer + if ($bstoreContainer = $this->_object->getBstoreContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer); + $innerData .= $writer->close(); + } - $this->_data = $header; + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF000; + $length = strlen($innerData); - $this->_data .= $data; - break; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip': - // this is an atom record + $header = pack('vvV', $recVerInstance, $recType, $length); - // write the record - switch ($this->_object->getParent()->getBlipType()) { + $this->_data = $header . $innerData; + break; + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer': + // this is a container record - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: // initialize $innerData = ''; - $rgbUid1 = pack('VVVV', 0,0,0,0); // todo - $innerData .= $rgbUid1; - - $tag = 0xFF; // todo - $innerData .= pack('C', $tag); - - $innerData .= $this->_object->getData(); + // treat the inner data + if ($BSECollection = $this->_object->getBSECollection()) { + foreach ($BSECollection as $BSE) { + $writer = new PHPExcel_Writer_Excel5_Escher($BSE); + $innerData .= $writer->close(); + } + } - $recVer = 0x0; - $recInstance = 0x46A; - $recType = 0xF01D; + // write the record + $recVer = 0xF; + $recInstance = count($this->_object->getBSECollection()); + $recType = 0xF001; $length = strlen($innerData); $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header; - - $this->_data .= $innerData; + $this->_data = $header . $innerData; break; + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE': + // this is a semi-container record - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: // initialize $innerData = ''; - $rgbUid1 = pack('VVVV', 0,0,0,0); // todo - $innerData .= $rgbUid1; + // here we treat the inner data + if ($blip = $this->_object->getBlip()) { + $writer = new PHPExcel_Writer_Excel5_Escher($blip); + $innerData .= $writer->close(); + } + + // initialize + $data = ''; - $tag = 0xFF; // todo - $innerData .= pack('C', $tag); + $btWin32 = $this->_object->getBlipType(); + $btMacOS = $this->_object->getBlipType(); + $data .= pack('CC', $btWin32, $btMacOS); - $innerData .= $this->_object->getData(); + $rgbUid = pack('VVVV', 0,0,0,0); // todo + $data .= $rgbUid; - $recVer = 0x0; - $recInstance = 0x6E0; - $recType = 0xF01E; - $length = strlen($innerData); + $tag = 0; + $size = strlen($innerData); + $cRef = 1; + $foDelay = 0; //todo + $unused1 = 0x0; + $cbName = 0x0; + $unused2 = 0x0; + $unused3 = 0x0; + $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3); + + $data .= $innerData; + + // write the record + $recVer = 0x2; + $recInstance = $this->_object->getBlipType(); + $recType = 0xF007; + $length = strlen($data); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; @@ -279,235 +215,286 @@ public function close() $this->_data = $header; - $this->_data .= $innerData; + $this->_data .= $data; break; + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip': + // this is an atom record - } - break; + // write the record + switch ($this->_object->getParent()->getBlipType()) { + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: + // initialize + $innerData = ''; - case 'PHPExcel_Shared_Escher_DgContainer': - // this is a container record + $rgbUid1 = pack('VVVV', 0,0,0,0); // todo + $innerData .= $rgbUid1; - // initialize - $innerData = ''; + $tag = 0xFF; // todo + $innerData .= pack('C', $tag); - // write the dg - $recVer = 0x0; - $recInstance = $this->_object->getDgId(); - $recType = 0xF008; - $length = 8; + $innerData .= $this->_object->getData(); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVer = 0x0; + $recInstance = 0x46A; + $recType = 0xF01D; + $length = strlen($innerData); - $header = pack('vvV', $recVerInstance, $recType, $length); + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - // number of shapes in this drawing (including group shape) - $countShapes = count($this->_object->getSpgrContainer()->getChildren()); - $innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId()); - //$innerData .= $header . pack('VV', 0, 0); + $header = pack('vvV', $recVerInstance, $recType, $length); - // write the spgrContainer - if ($spgrContainer = $this->_object->getSpgrContainer()) { - $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer); - $innerData .= $writer->close(); + $this->_data = $header; - // get the shape offsets relative to the spgrContainer record - $spOffsets = $writer->getSpOffsets(); - $spTypes = $writer->getSpTypes(); - - // save the shape offsets relative to dgContainer - foreach ($spOffsets as & $spOffset) { - $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes) - } + $this->_data .= $innerData; + break; - $this->_spOffsets = $spOffsets; - $this->_spTypes = $spTypes; - } + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: + // initialize + $innerData = ''; - // write the record - $recVer = 0xF; - $recInstance = 0x0000; - $recType = 0xF002; - $length = strlen($innerData); + $rgbUid1 = pack('VVVV', 0,0,0,0); // todo + $innerData .= $rgbUid1; - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $tag = 0xFF; // todo + $innerData .= pack('C', $tag); - $header = pack('vvV', $recVerInstance, $recType, $length); + $innerData .= $this->_object->getData(); - $this->_data = $header . $innerData; - break; + $recVer = 0x0; + $recInstance = 0x6E0; + $recType = 0xF01E; + $length = strlen($innerData); - case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer': - // this is a container record + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - // initialize - $innerData = ''; + $header = pack('vvV', $recVerInstance, $recType, $length); - // initialize spape offsets - $totalSize = 8; - $spOffsets = array(); - $spTypes = array(); + $this->_data = $header; - // treat the inner data - foreach ($this->_object->getChildren() as $spContainer) { - $writer = new PHPExcel_Writer_Excel5_Escher($spContainer); - $spData = $writer->close(); - $innerData .= $spData; + $this->_data .= $innerData; + break; + } + break; + case 'PHPExcel_Shared_Escher_DgContainer': + // this is a container record - // save the shape offsets (where new shape records begin) - $totalSize += strlen($spData); - $spOffsets[] = $totalSize; - - $spTypes = array_merge($spTypes, $writer->getSpTypes()); - } + // initialize + $innerData = ''; - // write the record - $recVer = 0xF; - $recInstance = 0x0000; - $recType = 0xF003; - $length = strlen($innerData); + // write the dg + $recVer = 0x0; + $recInstance = $this->_object->getDgId(); + $recType = 0xF008; + $length = 8; - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - $header = pack('vvV', $recVerInstance, $recType, $length); + $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header . $innerData; - $this->_spOffsets = $spOffsets; - $this->_spTypes = $spTypes; - break; + // number of shapes in this drawing (including group shape) + $countShapes = count($this->_object->getSpgrContainer()->getChildren()); + $innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId()); + //$innerData .= $header . pack('VV', 0, 0); - case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer': - // initialize - $data = ''; + // write the spgrContainer + if ($spgrContainer = $this->_object->getSpgrContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer); + $innerData .= $writer->close(); - // build the data + // get the shape offsets relative to the spgrContainer record + $spOffsets = $writer->getSpOffsets(); + $spTypes = $writer->getSpTypes(); + + // save the shape offsets relative to dgContainer + foreach ($spOffsets as & $spOffset) { + $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes) + } + + $this->_spOffsets = $spOffsets; + $this->_spTypes = $spTypes; + } - // write group shape record, if necessary? - if ($this->_object->getSpgr()) { - $recVer = 0x1; + // write the record + $recVer = 0xF; $recInstance = 0x0000; - $recType = 0xF009; - $length = 0x00000010; + $recType = 0xF002; + $length = strlen($innerData); $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . pack('VVVV', 0,0,0,0); - } - $this->_spTypes[] = ($this->_object->getSpType()); + $this->_data = $header . $innerData; + break; + case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer': + // this is a container record + + // initialize + $innerData = ''; + + // initialize spape offsets + $totalSize = 8; + $spOffsets = array(); + $spTypes = array(); + + // treat the inner data + foreach ($this->_object->getChildren() as $spContainer) { + $writer = new PHPExcel_Writer_Excel5_Escher($spContainer); + $spData = $writer->close(); + $innerData .= $spData; + + // save the shape offsets (where new shape records begin) + $totalSize += strlen($spData); + $spOffsets[] = $totalSize; + + $spTypes = array_merge($spTypes, $writer->getSpTypes()); + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF003; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - // write the shape record - $recVer = 0x2; - $recInstance = $this->_object->getSpType(); // shape type - $recType = 0xF00A; - $length = 0x00000008; + $header = pack('vvV', $recVerInstance, $recType, $length); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $this->_data = $header . $innerData; + $this->_spOffsets = $spOffsets; + $this->_spTypes = $spTypes; + break; + case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer': + // initialize + $data = ''; - $header = pack('vvV', $recVerInstance, $recType, $length); + // build the data - $data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x0005 : 0x0A00); + // write group shape record, if necessary? + if ($this->_object->getSpgr()) { + $recVer = 0x1; + $recInstance = 0x0000; + $recType = 0xF009; + $length = 0x00000010; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - // the options - if ($this->_object->getOPTCollection()) { - $optData = ''; + $header = pack('vvV', $recVerInstance, $recType, $length); - $recVer = 0x3; - $recInstance = count($this->_object->getOPTCollection()); - $recType = 0xF00B; - foreach ($this->_object->getOPTCollection() as $property => $value) { - $optData .= pack('vV', $property, $value); + $data .= $header . pack('VVVV', 0,0,0,0); } - $length = strlen($optData); + $this->_spTypes[] = ($this->_object->getSpType()); + + // write the shape record + $recVer = 0x2; + $recInstance = $this->_object->getSpType(); // shape type + $recType = 0xF00A; + $length = 0x00000008; $recVerInstance = $recVer; $recVerInstance |= $recInstance << 4; $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . $optData; - } - // the client anchor - if ($this->_object->getStartCoordinates()) { - $clientAnchorData = ''; + $data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x0005 : 0x0A00); - $recVer = 0x0; - $recInstance = 0x0; - $recType = 0xF010; - // start coordinates - list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates()); - $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1; - $r1 = $row - 1; + // the options + if ($this->_object->getOPTCollection()) { + $optData = ''; - // start offsetX - $startOffsetX = $this->_object->getStartOffsetX(); + $recVer = 0x3; + $recInstance = count($this->_object->getOPTCollection()); + $recType = 0xF00B; + foreach ($this->_object->getOPTCollection() as $property => $value) { + $optData .= pack('vV', $property, $value); + } + $length = strlen($optData); - // start offsetY - $startOffsetY = $this->_object->getStartOffsetY(); + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; - // end coordinates - list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates()); - $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1; - $r2 = $row - 1; + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $optData; + } - // end offsetX - $endOffsetX = $this->_object->getEndOffsetX(); + // the client anchor + if ($this->_object->getStartCoordinates()) { + $clientAnchorData = ''; - // end offsetY - $endOffsetY = $this->_object->getEndOffsetY(); + $recVer = 0x0; + $recInstance = 0x0; + $recType = 0xF010; - $clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(), - $c1, $startOffsetX, $r1, $startOffsetY, - $c2, $endOffsetX, $r2, $endOffsetY); - - $length = strlen($clientAnchorData); + // start coordinates + list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates()); + $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1; + $r1 = $row - 1; - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + // start offsetX + $startOffsetX = $this->_object->getStartOffsetX(); - $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . $clientAnchorData; - } + // start offsetY + $startOffsetY = $this->_object->getStartOffsetY(); - // the client data, just empty for now - if (!$this->_object->getSpgr()) { - $clientDataData = ''; + // end coordinates + list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates()); + $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1; + $r2 = $row - 1; - $recVer = 0x0; - $recInstance = 0x0; - $recType = 0xF011; + // end offsetX + $endOffsetX = $this->_object->getEndOffsetX(); - $length = strlen($clientDataData); + // end offsetY + $endOffsetY = $this->_object->getEndOffsetY(); - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(), $c1, $startOffsetX, $r1, $startOffsetY, $c2, $endOffsetX, $r2, $endOffsetY); + + $length = strlen($clientAnchorData); - $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . $clientDataData; - } + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $clientAnchorData; + } - // write the record - $recVer = 0xF; - $recInstance = 0x0000; - $recType = 0xF004; - $length = strlen($data); + // the client data, just empty for now + if (!$this->_object->getSpgr()) { + $clientDataData = ''; - $recVerInstance = $recVer; - $recVerInstance |= $recInstance << 4; + $recVer = 0x0; + $recInstance = 0x0; + $recType = 0xF011; - $header = pack('vvV', $recVerInstance, $recType, $length); + $length = strlen($clientDataData); - $this->_data = $header . $data; - break; + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $clientDataData; + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF004; + $length = strlen($data); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $data; + break; } return $this->_data; @@ -532,6 +519,4 @@ public function getSpTypes() { return $this->_spTypes; } - - } diff --git a/Classes/PHPExcel/Writer/Excel5/Font.php b/Classes/PHPExcel/Writer/Excel5/Font.php index d4543db19..a95e64555 100644 --- a/Classes/PHPExcel/Writer/Excel5/Font.php +++ b/Classes/PHPExcel/Writer/Excel5/Font.php @@ -107,12 +107,17 @@ public function writeFont() $grbit |= 0x20; } - $data = pack("vvvvvCCCC", - $this->_font->getSize() * 20, // Fontsize (in twips) + $data = pack( + "vvvvvCCCC", + // Fontsize (in twips) + $this->_font->getSize() * 20, $grbit, - $icv, // Colour - self::_mapBold($this->_font->getBold()), // Font weight - $sss, // Superscript/Subscript + // Colour + $icv, + // Font weight + self::_mapBold($this->_font->getBold()), + // Superscript/Subscript + $sss, self::_mapUnderline($this->_font->getUnderline()), $bFamily, $bCharSet, @@ -132,7 +137,8 @@ public function writeFont() * @param boolean $bold * @return int */ - private static function _mapBold($bold) { + private static function _mapBold($bold) + { if ($bold) { return 0x2BC; // 700 = Bold font weight } @@ -144,22 +150,24 @@ private static function _mapBold($bold) { * @static array of int * */ - private static $_mapUnderline = array( PHPExcel_Style_Font::UNDERLINE_NONE => 0x00, - PHPExcel_Style_Font::UNDERLINE_SINGLE => 0x01, - PHPExcel_Style_Font::UNDERLINE_DOUBLE => 0x02, - PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING => 0x21, - PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING => 0x22, - ); + private static $_mapUnderline = array( + PHPExcel_Style_Font::UNDERLINE_NONE => 0x00, + PHPExcel_Style_Font::UNDERLINE_SINGLE => 0x01, + PHPExcel_Style_Font::UNDERLINE_DOUBLE => 0x02, + PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING => 0x21, + PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING => 0x22, + ); /** * Map underline * * @param string * @return int */ - private static function _mapUnderline($underline) { - if (isset(self::$_mapUnderline[$underline])) + private static function _mapUnderline($underline) + { + if (isset(self::$_mapUnderline[$underline])) { return self::$_mapUnderline[$underline]; + } return 0x00; } - } diff --git a/Classes/PHPExcel/Writer/Excel5/Parser.php b/Classes/PHPExcel/Writer/Excel5/Parser.php index c9b0bef7a..6a5e3e083 100644 --- a/Classes/PHPExcel/Writer/Excel5/Parser.php +++ b/Classes/PHPExcel/Writer/Excel5/Parser.php @@ -136,7 +136,7 @@ public function __construct() * * @access private */ - function _initializeHashes() + private function _initializeHashes() { // The Excel ptg indices $this->ptg = array( @@ -512,7 +512,7 @@ function _initializeHashes() * @param mixed $token The token to convert. * @return mixed the converted token on success */ - function _convert($token) + private function _convert($token) { if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token)) { return $this->_convertString($token); @@ -521,15 +521,15 @@ function _convert($token) return $this->_convertNumber($token); // match references like A1 or $A$1 - } elseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/',$token)) { + } elseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/', $token)) { return $this->_convertRef2d($token); // match external references like Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1 - } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u",$token)) { + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u", $token)) { return $this->_convertRef3d($token); // match external references like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1 - } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u",$token)) { + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u", $token)) { return $this->_convertRef3d($token); // match ranges like A1:B2 or $A$1:$B$2 @@ -537,11 +537,11 @@ function _convert($token) return $this->_convertRange2d($token); // match external ranges like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 - } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u",$token)) { + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u", $token)) { return $this->_convertRange3d($token); // match external ranges like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 - } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u",$token)) { + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u", $token)) { return $this->_convertRange3d($token); // operators (including parentheses) @@ -553,9 +553,9 @@ function _convert($token) return $this->_convertError($token); // commented so argument number can be processed correctly. See toReversePolish(). - /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/",$token)) + /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/", $token)) { - return($this->_convertFunction($token,$this->_func_args)); + return($this->_convertFunction($token, $this->_func_args)); }*/ // if it's an argument, ignore the token (the argument remains) @@ -573,7 +573,7 @@ function _convert($token) * @access private * @param mixed $num an integer or double for conversion to its ptg value */ - function _convertNumber($num) + private function _convertNumber($num) { // Integer in the range 0..2**16-1 if ((preg_match("/^\d+$/", $num)) and ($num <= 65535)) { @@ -593,7 +593,7 @@ function _convertNumber($num) * @param string $string A string for conversion to its ptg value. * @return mixed the converted token on success */ - function _convertString($string) + private function _convertString($string) { // chop away beggining and ending quotes $string = substr($string, 1, strlen($string) - 2); @@ -613,16 +613,16 @@ function _convertString($string) * @param integer $num_args The number of arguments the function receives. * @return string The packed ptg for the function */ - function _convertFunction($token, $num_args) + private function _convertFunction($token, $num_args) { $args = $this->_functions[$token][1]; // $volatile = $this->_functions[$token][3]; - // Fixed number of args eg. TIME($i,$j,$k). + // Fixed number of args eg. TIME($i, $j, $k). if ($args >= 0) { return pack("Cv", $this->ptg['ptgFuncV'], $this->_functions[$token][0]); } - // Variable number of args eg. SUM($i,$j,$k, ..). + // Variable number of args eg. SUM($i, $j, $k, ..). if ($args == -1) { return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0]); } @@ -635,7 +635,7 @@ function _convertFunction($token, $num_args) * @param string $range An Excel range in the A1:A2 * @param int $class */ - function _convertRange2d($range, $class=0) + private function _convertRange2d($range, $class = 0) { // TODO: possible class value 0,1,2 check Formula.pm @@ -673,7 +673,7 @@ function _convertRange2d($range, $class=0) * @param string $token An Excel range in the Sheet1!A1:A2 format. * @return mixed The packed ptgArea3d token on success. */ - function _convertRange3d($token) + private function _convertRange3d($token) { // $class = 0; // formulas like Sheet1!$A$1:$A$2 in list type data validation need this class (0x3B) @@ -715,7 +715,7 @@ function _convertRange3d($token) * @param string $cell An Excel cell reference * @return string The cell in packed() format with the corresponding ptg */ - function _convertRef2d($cell) + private function _convertRef2d($cell) { // $class = 2; // as far as I know, this is magick. @@ -745,7 +745,7 @@ function _convertRef2d($cell) * @param string $cell An Excel cell reference * @return mixed The packed ptgRef3d token on success. */ - function _convertRef3d($cell) + private function _convertRef3d($cell) { // $class = 2; // as far as I know, this is magick. @@ -779,16 +779,23 @@ function _convertRef3d($cell) * @param string $errorCode The error code for conversion to its ptg value * @return string The error code ptgErr */ - function _convertError($errorCode) + private function _convertError($errorCode) { switch ($errorCode) { - case '#NULL!': return pack("C", 0x00); - case '#DIV/0!': return pack("C", 0x07); - case '#VALUE!': return pack("C", 0x0F); - case '#REF!': return pack("C", 0x17); - case '#NAME?': return pack("C", 0x1D); - case '#NUM!': return pack("C", 0x24); - case '#N/A': return pack("C", 0x2A); + case '#NULL!': + return pack("C", 0x00); + case '#DIV/0!': + return pack("C", 0x07); + case '#VALUE!': + return pack("C", 0x0F); + case '#REF!': + return pack("C", 0x17); + case '#NAME?': + return pack("C", 0x1D); + case '#NUM!': + return pack("C", 0x24); + case '#N/A': + return pack("C", 0x2A); } return pack("C", 0xFF); } @@ -801,7 +808,7 @@ function _convertError($errorCode) * @param string $ext_ref The name of the external reference * @return string The reference index in packed() format */ - function _packExtRef($ext_ref) + private function _packExtRef($ext_ref) { $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. @@ -846,7 +853,7 @@ function _packExtRef($ext_ref) * @param string $ext_ref The name of the external reference * @return mixed The reference index in packed() format on success */ - function _getRefIndex($ext_ref) + private function _getRefIndex($ext_ref) { $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. @@ -906,7 +913,7 @@ function _getRefIndex($ext_ref) * @param string $sheet_name Sheet name * @return integer The sheet index, -1 if the sheet was not found */ - function _getSheetIndex($sheet_name) + private function _getSheetIndex($sheet_name) { if (!isset($this->_ext_sheets[$sheet_name])) { return -1; @@ -925,7 +932,7 @@ function _getSheetIndex($sheet_name) * @param string $name The name of the worksheet being added * @param integer $index The index of the worksheet being added */ - function setExtSheet($name, $index) + public function setExtSheet($name, $index) { $this->_ext_sheets[$name] = $index; } @@ -937,7 +944,7 @@ function setExtSheet($name, $index) * @param string $cell The Excel cell reference to be packed * @return array Array containing the row and column in packed() format */ - function _cellToPackedRowcol($cell) + private function _cellToPackedRowcol($cell) { $cell = strtoupper($cell); list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell); @@ -966,7 +973,7 @@ function _cellToPackedRowcol($cell) * @param string $range The Excel range to be packed * @return array Array containing (row1,col1,row2,col2) in packed() format */ - function _rangeToPackedRange($range) + private function _rangeToPackedRange($range) { preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match); // return absolute rows if there is a $ in the ref @@ -1007,9 +1014,9 @@ function _rangeToPackedRange($range) * @param string $cell The Excel cell reference in A1 format. * @return array */ - function _cellToRowcol($cell) + private function _cellToRowcol($cell) { - preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/',$cell,$match); + preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/', $cell, $match); // return absolute column if there is a $ in the ref $col_rel = empty($match[1]) ? 1 : 0; $col_ref = $match[2]; @@ -1037,7 +1044,7 @@ function _cellToRowcol($cell) * * @access private */ - function _advance() + private function _advance() { $i = $this->_current_char; $formula_length = strlen($this->_formula); @@ -1088,7 +1095,7 @@ function _advance() * @param mixed $token The token to check. * @return mixed The checked token or false on failure */ - function _match($token) + private function _match($token) { switch($token) { case "+": @@ -1123,65 +1130,55 @@ function _match($token) break; default: // if it's a reference A1 or $A$1 or $A1 or A$1 - if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$token) and - !preg_match("/[0-9]/",$this->_lookahead) and + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $token) and + !preg_match("/[0-9]/", $this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.') and - ($this->_lookahead != '!')) - { + ($this->_lookahead != '!')) { return $token; } // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$token) and - !preg_match("/[0-9]/",$this->_lookahead) and - ($this->_lookahead != ':') and ($this->_lookahead != '.')) - { + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and + !preg_match("/[0-9]/", $this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.')) { return $token; } // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$token) and - !preg_match("/[0-9]/",$this->_lookahead) and - ($this->_lookahead != ':') and ($this->_lookahead != '.')) - { + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and + !preg_match("/[0-9]/", $this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.')) { return $token; } // if it's a range A1:A2 or $A$1:$A$2 elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) and - !preg_match("/[0-9]/",$this->_lookahead)) - { + !preg_match("/[0-9]/", $this->_lookahead)) { return $token; } // If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$token) and - !preg_match("/[0-9]/",$this->_lookahead)) - { + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and + !preg_match("/[0-9]/", $this->_lookahead)) { return $token; } // If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$token) and - !preg_match("/[0-9]/",$this->_lookahead)) - { + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and + !preg_match("/[0-9]/", $this->_lookahead)) { return $token; } // If it's a number (check that it's not a sheet name or range) elseif (is_numeric($token) and (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and - ($this->_lookahead != '!') and ($this->_lookahead != ':')) - { + ($this->_lookahead != '!') and ($this->_lookahead != ':')) { return $token; } // If it's a string (of maximum 255 characters) - elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/",$token) and $this->_lookahead != '"' and (substr_count($token, '"')%2 == 0)) - { + elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token) and $this->_lookahead != '"' and (substr_count($token, '"')%2 == 0)) { return $token; } // If it's an error code - elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') - { + elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { return $token; } // if it's a function call - elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$token) and ($this->_lookahead == "(")) - { + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $token) and ($this->_lookahead == "(")) { return $token; } // It's an argument of some description (e.g. a named range), @@ -1201,7 +1198,7 @@ function _match($token) * sign (=). * @return mixed true on success */ - function parse($formula) + public function parse($formula) { $this->_current_char = 0; $this->_formula = $formula; @@ -1218,7 +1215,7 @@ function parse($formula) * @access private * @return mixed The parsed ptg'd tree on success */ - function _condition() + private function _condition() { $result = $this->_expression(); if ($this->_current_token == "<") { @@ -1264,7 +1261,7 @@ function _condition() * @access private * @return mixed The parsed ptg'd tree on success */ - function _expression() + private function _expression() { // If it's a string return a string node if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $this->_current_token)) { @@ -1323,7 +1320,7 @@ function _expression() * @see _fact() * @return array The parsed ptg'd tree */ - function _parenthesizedExpression() + private function _parenthesizedExpression() { $result = $this->_createTree('ptgParen', $this->_expression(), ''); return $result; @@ -1336,7 +1333,7 @@ function _parenthesizedExpression() * @access private * @return mixed The parsed ptg'd tree on success */ - function _term() + private function _term() { $result = $this->_fact(); while (($this->_current_token == "*") or @@ -1366,7 +1363,7 @@ function _term() * @access private * @return mixed The parsed ptg'd tree on success */ - function _fact() + private function _fact() { if ($this->_current_token == "(") { $this->_advance(); // eat the "(" @@ -1378,29 +1375,29 @@ function _fact() return $result; } // if it's a reference - if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$this->_current_token)) + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $this->_current_token)) { $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; } // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$this->_current_token)) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) { $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; } // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$this->_current_token)) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) { $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; } // if it's a range A1:B2 or $A$1:$B$2 - elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/',$this->_current_token) or - preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/',$this->_current_token)) + elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->_current_token) or + preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->_current_token)) { // must be an error? $result = $this->_createTree($this->_current_token, '', ''); @@ -1408,7 +1405,7 @@ function _fact() return $result; } // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$this->_current_token)) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) { // must be an error? //$result = $this->_current_token; @@ -1417,7 +1414,7 @@ function _fact() return $result; } // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$this->_current_token)) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) { // must be an error? //$result = $this->_current_token; @@ -1438,7 +1435,7 @@ function _fact() return $result; } // if it's a function call - elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$this->_current_token)) + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $this->_current_token)) { $result = $this->_func(); return $result; @@ -1455,7 +1452,7 @@ function _fact() * @access private * @return mixed The parsed ptg'd tree on success */ - function _func() + private function _func() { $num_args = 0; // number of arguments received $function = strtoupper($this->_current_token); @@ -1485,7 +1482,7 @@ function _func() throw new PHPExcel_Writer_Exception("Function $function() doesn't exist"); } $args = $this->_functions[$function][1]; - // If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid. + // If fixed number of args eg. TIME($i, $j, $k). Check that the number of args is valid. if (($args >= 0) and ($args != $num_args)) { throw new PHPExcel_Writer_Exception("Incorrect number of arguments in function $function() "); } @@ -1505,7 +1502,7 @@ function _func() * @param mixed $right The right array (sub-tree) or a final node. * @return array A tree */ - function _createTree($value, $left, $right) + private function _createTree($value, $left, $right) { return array('value' => $value, 'left' => $left, 'right' => $right); } @@ -1537,7 +1534,7 @@ function _createTree($value, $left, $right) * @param array $tree The optional tree to convert. * @return string The tree in reverse polish notation */ - function toReversePolish($tree = array()) + public function toReversePolish($tree = array()) { $polish = ""; // the string we are going to return if (empty($tree)) { // If it's the first call use _parse_tree @@ -1559,9 +1556,9 @@ function toReversePolish($tree = array()) $polish .= $converted_tree; } // if it's a function convert it here (so we can set it's arguments) - if (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/",$tree['value']) and - !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/',$tree['value']) and - !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/",$tree['value']) and + if (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/", $tree['value']) and + !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/', $tree['value']) and + !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/", $tree['value']) and !is_numeric($tree['value']) and !isset($this->ptg[$tree['value']])) { @@ -1579,5 +1576,4 @@ function toReversePolish($tree = array()) $polish .= $converted_tree; return $polish; } - } diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index f5a47a431..24c5ccccd 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -200,9 +200,7 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter * @param array &$colors Colour Table * @param mixed $parser The formula parser created for the Workbook */ - public function __construct(PHPExcel $phpExcel = null, - &$str_total, &$str_unique, &$str_table, &$colors, - $parser ) + public function __construct(PHPExcel $phpExcel = null, &$str_total, &$str_unique, &$str_table, &$colors, $parser) { // It needs to call its parent's constructor explicitly parent::__construct(); @@ -303,7 +301,7 @@ public function addXfWriter($style, $isStyleXf = false) public function _addFont(PHPExcel_Style_Font $font) { $fontHashCode = $font->getHashCode(); - if(isset($this->_addedFonts[$fontHashCode])){ + if (isset($this->_addedFonts[$fontHashCode])) { $fontIndex = $this->_addedFonts[$fontHashCode]; } else { $countFonts = count($this->_fontWriters); @@ -324,7 +322,8 @@ public function _addFont(PHPExcel_Style_Font $font) * @param string $rgb E.g. 'FF00AA' * @return int Color index */ - private function _addColor($rgb) { + private function _addColor($rgb) + { if (!isset($this->_colors[$rgb])) { if (count($this->_colors) < 57) { // then we add a custom color altering the palette @@ -354,7 +353,7 @@ private function _addColor($rgb) { * * @access private */ - function _setPaletteXl97() + private function _setPaletteXl97() { $this->_palette = array( 0x08 => array(0x00, 0x00, 0x00, 0x00), @@ -477,7 +476,7 @@ public function writeWorkbook($pWorksheetSizes = null) * * @access private */ - function _calcSheetOffsets() + private function _calcSheetOffsets() { $boundsheet_length = 10; // fixed length for a BOUNDSHEET record @@ -583,7 +582,7 @@ private function _writeNames() $print_rowmax, $print_colmin, $print_colmax - ); + ); } } @@ -608,11 +607,10 @@ private function _writeNames() $rowmax, $colmin, $colmax - ); + ); // (exclusive) either repeatColumns or repeatRows } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { - // Columns to repeat if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); @@ -640,7 +638,7 @@ private function _writeNames() $rowmax, $colmin, $colmax - ); + ); } } } @@ -658,7 +656,6 @@ private function _writeAllDefinedNamesBiff8() // Loop named ranges $namedRanges = $this->_phpExcel->getNamedRanges(); foreach ($namedRanges as $namedRange) { - // Create absolute coordinate $range = PHPExcel_Cell::splitRange($namedRange->getRange()); for ($i = 0; $i < count($range); $i++) { @@ -688,7 +685,7 @@ private function _writeAllDefinedNamesBiff8() } $chunk .= $this->writeData($this->_writeDefinedNameBiff8($namedRange->getName(), $formulaData, $scope, false)); - } catch(PHPExcel_Exception $e) { + } catch (PHPExcel_Exception $e) { // do nothing } } @@ -721,7 +718,6 @@ private function _writeAllDefinedNamesBiff8() // (exclusive) either repeatColumns or repeatRows } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { - // Columns to repeat if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); @@ -785,7 +781,7 @@ private function _writeAllDefinedNamesBiff8() for ($i = 0; $i < $total_worksheets; ++$i) { $sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter(); $autoFilterRange = $sheetAutoFilter->getRange(); - if(!empty($autoFilterRange)) { + if (!empty($autoFilterRange)) { $rangeBounds = PHPExcel_Cell::rangeBoundaries($autoFilterRange); //Autofilter built in name @@ -842,19 +838,21 @@ private function _writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $i * @param boolean $isHidden * @return string Complete binary record data * */ - private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){ + private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false) + { $record = 0x0018; // option flags $options = ($isHidden ? 0x21 : 0x00); $extra = pack('Cvvvvv', - 0x3B, - $sheetIndex - 1, - $rangeBounds[0][1] - 1, - $rangeBounds[1][1] - 1, - $rangeBounds[0][0] - 1, - $rangeBounds[1][0] - 1); + 0x3B, + $sheetIndex - 1, + $rangeBounds[0][1] - 1, + $rangeBounds[1][1] - 1, + $rangeBounds[0][0] - 1, + $rangeBounds[1][0] - 1 + ); // size of the formula (in bytes) $sz = strlen($extra); @@ -879,7 +877,7 @@ private function _writeCodepage() $cv = $this->_codepage; // The code page $header = pack('vv', $record, $length); - $data = pack('v', $cv); + $data = pack('v', $cv); $this->_append($header . $data); } @@ -909,10 +907,7 @@ private function _writeWindow1() $itabCur = $this->_phpExcel->getActiveSheetIndex(); // Active worksheet $header = pack("vv", $record, $length); - $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, - $grbit, - $itabCur, $itabFirst, - $ctabsel, $wTabRatio); + $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, $grbit, $itabCur, $itabFirst, $ctabsel, $wTabRatio); $this->_append($header . $data); } @@ -929,10 +924,18 @@ private function _writeBoundsheet($sheet, $offset) // sheet state switch ($sheet->getSheetState()) { - case PHPExcel_Worksheet::SHEETSTATE_VISIBLE: $ss = 0x00; break; - case PHPExcel_Worksheet::SHEETSTATE_HIDDEN: $ss = 0x01; break; - case PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN: $ss = 0x02; break; - default: $ss = 0x00; break; + case PHPExcel_Worksheet::SHEETSTATE_VISIBLE: + $ss = 0x00; + break; + case PHPExcel_Worksheet::SHEETSTATE_HIDDEN: + $ss = 0x01; + break; + case PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN: + $ss = 0x02; + break; + default: + $ss = 0x00; + break; } // sheet type @@ -944,7 +947,7 @@ private function _writeBoundsheet($sheet, $offset) $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheetname); $length = strlen($data); - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $this->_append($header . $data); } @@ -973,7 +976,7 @@ private function _writeExternsheetBiff8() $length = 2 + 6 * $total_references; // Number of bytes to follow $supbook_index = 0; // FIXME: only using internal SUPBOOK record - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack('v', $total_references); for ($i = 0; $i < $total_references; ++$i) { $data .= $this->_parser->_references[$i]; @@ -993,7 +996,7 @@ private function _writeStyle() $BuiltIn = 0x00; // Built-in style $iLevel = 0xff; // Outline style level - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vCC", $ixfe, $BuiltIn, $iLevel); $this->_append($header . $data); } @@ -1051,7 +1054,7 @@ private function _writeExterncount($cxals) $length = 0x0002; // Number of bytes to follow $header = pack("vv", $record, $length); - $data = pack("v", $cxals); + $data = pack("v", $cxals); $this->_append($header . $data); } @@ -1072,7 +1075,7 @@ private function _writeExternsheet($sheetname) $cch = strlen($sheetname); // Length of sheet name $rgch = 0x03; // Filename encoding - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("CC", $cch, $rgch); $this->_append($header . $data . $sheetname); } @@ -1177,7 +1180,7 @@ private function _writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colma $unknown07 = 0x1087; $unknown08 = 0x8008; - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("v", $grbit); $data .= pack("C", $chKey); $data .= pack("C", $cch); @@ -1232,7 +1235,7 @@ private function _writeCountry() $record = 0x008C; // Record identifier $length = 4; // Number of bytes to follow - $header = pack('vv', $record, $length); + $header = pack('vv', $record, $length); /* using the same country code always for simplicity */ $data = pack('vv', $this->_country_code, $this->_country_code); //$this->_append($header . $data); @@ -1249,7 +1252,7 @@ private function _writeRecalcId() $record = 0x01C1; // Record identifier $length = 8; // Number of bytes to follow - $header = pack('vv', $record, $length); + $header = pack('vv', $record, $length); // by inspection of real Excel files, MS Office Excel 2007 writes this $data = pack('VV', 0x000001C1, 0x00001E667); @@ -1276,7 +1279,7 @@ private function _writePalette() } } - $header = pack("vvv", $record, $length, $ccv); + $header = pack("vvv", $record, $length, $ccv); $this->_append($header . $data); } @@ -1307,7 +1310,6 @@ private function _writeSharedStringsTable() // loop through all (unique) strings in shared strings table foreach (array_keys($this->_str_table) as $string) { - // here $string is a BIFF8 encoded string // length = character count @@ -1320,7 +1322,6 @@ private function _writeSharedStringsTable() $finished = false; while ($finished === false) { - // normally, there will be only one cycle, but if string cannot immediately be written as is // there will be need for more than one cylcle, if string longer than one record data block, there // may be need for even more cycles @@ -1369,7 +1370,7 @@ private function _writeSharedStringsTable() $effective_space_remaining = $space_remaining; // for uncompressed strings, sometimes effective space remaining is reduced by 1 - if ( $encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1 ) { + if ($encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1) { --$effective_space_remaining; } @@ -1419,10 +1420,9 @@ private function _writeMsoDrawingGroup() $record = 0x00EB; $length = strlen($data); - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); return $this->writeData($header . $data); - } else { return ''; } diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index d0ad7585d..6ea6ca59b 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -1254,7 +1254,7 @@ private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) $grbit |= 0x0100; $header = pack("vv", $record, $length); - $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, $irwMac,$reserved, $grbit, $ixfe); + $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, $irwMac, $reserved, $grbit, $ixfe); $this->_append($header.$data); } @@ -1313,7 +1313,7 @@ private function _writeWindow2() $grbit |= $fPaged << 10; $grbit |= $fPageBreakPreview << 11; - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvv", $grbit, $rwTop, $colLeft); // FIXME !!! @@ -1590,15 +1590,15 @@ private function _writeSheetProtection() // record data $recordData = pack( - 'vVVCVVvv' - , 0x0867 // repeated record identifier - , 0x0000 // not used - , 0x0000 // not used - , 0x00 // not used - , 0x01000200 // unknown data - , 0xFFFFFFFF // unknown data - , $options // options - , 0x0000 // not used + 'vVVCVVvv', + 0x0867, // repeated record identifier + 0x0000, // not used + 0x0000, // not used + 0x00, // not used + 0x01000200, // unknown data + 0xFFFFFFFF, // unknown data + $options, // options + 0x0000 // not used ); $length = strlen($recordData); @@ -1786,8 +1786,8 @@ private function _writePanes() $this->_active_pane = $pnnAct; // Used in _writeSelection - $header = pack("vv", $record, $length); - $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); + $header = pack("vv", $record, $length); + $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); $this->_append($header . $data); } @@ -1846,14 +1846,7 @@ private function _writeSetup() } $header = pack("vv", $record, $length); - $data1 = pack("vvvvvvvv", $iPaperSize, - $iScale, - $iPageStart, - $iFitWidth, - $iFitHeight, - $grbit, - $iRes, - $iVRes); + $data1 = pack("vvvvvvvv", $iPaperSize, $iScale, $iPageStart, $iFitWidth, $iFitHeight, $grbit, $iRes, $iVRes); $data2 = $numHdr.$numFtr; $data3 = pack("v", $iCopies); $this->_append($header . $data1 . $data2 . $data3); @@ -2086,7 +2079,7 @@ private function _writeAutoFilterInfo() * * @see _writeWsbool() */ - private function _writeGuts() + private function _writeGuts() { $record = 0x0080; // Record identifier $length = 0x0008; // Bytes to follow @@ -2194,7 +2187,6 @@ private function _writeBreaks() //horizontal page breaks if (!empty($hbreaks)) { - // Sort and filter array of page breaks sort($hbreaks, SORT_NUMERIC); if ($hbreaks[0] == 0) { // don't use first break if it's 0 @@ -2218,7 +2210,6 @@ private function _writeBreaks() // vertical page breaks if (!empty($vbreaks)) { - // 1000 vertical pagebreaks appears to be an internal Excel 5 limit. // It is slightly higher in Excel 97/200, approx. 1026 $vbreaks = array_slice($vbreaks, 0, 1000); @@ -2472,10 +2463,7 @@ public function _positionImage($col_start, $row_start, $x1, $y1, $width, $height $x2 = $width / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object $y2 = $height / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) * 256; // Distance to bottom of object - $this->_writeObjPicture($col_start, $x1, - $row_start, $y1, - $col_end, $x2, - $row_end, $y2); + $this->_writeObjPicture($col_start, $x1, $row_start, $y1, $col_end, $x2, $row_end, $y2); } /** @@ -2491,7 +2479,7 @@ public function _positionImage($col_start, $row_start, $x1, $y1, $width, $height * @param integer $rwB Row containing bottom right corner of object * @param integer $dyB Distance from bottom of cell */ - private function _writeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB) + private function _writeObjPicture($colL, $dxL, $rwT, $dyT, $colR, $dxR, $rwB, $dyB) { $record = 0x005d; // Record identifier $length = 0x003c; // Bytes to follow @@ -2598,7 +2586,7 @@ public function _processBitmapGd($image) public function _processBitmap($bitmap) { // Open file. - $bmp_fd = @fopen($bitmap,"rb"); + $bmp_fd = @fopen($bitmap, "rb"); if (!$bmp_fd) { throw new PHPExcel_Writer_Exception("Couldn't import $bitmap"); } @@ -2748,15 +2736,15 @@ private function _writeMsoDrawing() if ($spTypes[$i] == 0x00C9) { // Add ftCmo (common object data) subobject $objData .= - pack('vvvvvVVV' - , 0x0015 // 0x0015 = ftCmo - , 0x0012 // length of ftCmo data - , 0x0014 // object type, 0x0014 = filter - , $i // object id number, Excel seems to use 1-based index, local for the sheet - , 0x2101 // option flags, 0x2001 is what OpenOffice.org uses - , 0 // reserved - , 0 // reserved - , 0 // reserved + pack('vvvvvVVV', + 0x0015, // 0x0015 = ftCmo + 0x0012, // length of ftCmo data + 0x0014, // object type, 0x0014 = filter + $i, // object id number, Excel seems to use 1-based index, local for the sheet + 0x2101, // option flags, 0x2001 is what OpenOffice.org uses + 0, // reserved + 0, // reserved + 0 // reserved ); // Add ftSbs Scroll bar subobject @@ -2765,27 +2753,26 @@ private function _writeMsoDrawing() // Add ftLbsData (List box data) subobject $objData .= pack('vv', 0x0013, 0x1FEE); $objData .= pack('H*', '00000000010001030000020008005700'); - } - else { + } else { // Add ftCmo (common object data) subobject $objData .= - pack('vvvvvVVV' - , 0x0015 // 0x0015 = ftCmo - , 0x0012 // length of ftCmo data - , 0x0008 // object type, 0x0008 = picture - , $i // object id number, Excel seems to use 1-based index, local for the sheet - , 0x6011 // option flags, 0x6011 is what OpenOffice.org uses - , 0 // reserved - , 0 // reserved - , 0 // reserved + pack('vvvvvVVV', + 0x0015, // 0x0015 = ftCmo + 0x0012, // length of ftCmo data + 0x0008, // object type, 0x0008 = picture + $i, // object id number, Excel seems to use 1-based index, local for the sheet + 0x6011, // option flags, 0x6011 is what OpenOffice.org uses + 0, // reserved + 0, // reserved + 0 // reserved ); } // ftEnd $objData .= - pack('vv' - , 0x0000 // 0x0000 = ftEnd - , 0x0000 // length of ftEnd data + pack('vv', + 0x0000, // 0x0000 = ftEnd + 0x0000 // length of ftEnd data ); $length = strlen($objData); @@ -2805,19 +2792,17 @@ private function _writeDataValidity() // Write data validations? if (!empty($dataValidationCollection)) { - // DATAVALIDATIONS record $record = 0x01B2; // Record identifier - $length = 0x0012; // Bytes to follow + $length = 0x0012; // Bytes to follow $grbit = 0x0000; // Prompt box at cell, no cached validity data at DV records - $horPos = 0x00000000; // Horizontal position of prompt box, if fixed position - $verPos = 0x00000000; // Vertical position of prompt box, if fixed position + $horPos = 0x00000000; // Horizontal position of prompt box, if fixed position + $verPos = 0x00000000; // Vertical position of prompt box, if fixed position $objId = 0xFFFFFFFF; // Object identifier of drop down arrow object, or -1 if not visible - $header = pack('vv', $record, $length); - $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId, - count($dataValidationCollection)); + $header = pack('vv', $record, $length); + $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId, count($dataValidationCollection)); $this->_append($header.$data); // DATAVALIDATION records @@ -2877,7 +2862,7 @@ private function _writeDataValidity() // explicit formula? if ($type == 0x03 && preg_match('/^\".*\"$/', $dataValidation->getFormula1())) { - $options |= 0x01 << 7; + $options |= 0x01 << 7; } // empty cells allowed @@ -2953,8 +2938,7 @@ private function _writeDataValidity() $this->_parser->parse($formula1); $formula1 = $this->_parser->toReversePolish(); $sz1 = strlen($formula1); - - } catch(PHPExcel_Exception $e) { + } catch (PHPExcel_Exception $e) { $sz1 = 0; $formula1 = ''; } @@ -2970,8 +2954,7 @@ private function _writeDataValidity() $this->_parser->parse($formula2); $formula2 = $this->_parser->toReversePolish(); $sz2 = strlen($formula2); - - } catch(PHPExcel_Exception $e) { + } catch (PHPExcel_Exception $e) { $sz2 = 0; $formula2 = ''; } @@ -2983,7 +2966,7 @@ private function _writeDataValidity() $data .= $this->_writeBIFF8CellRangeAddressFixed($cellCoordinate); $length = strlen($data); - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $this->_append($header . $data); } @@ -3484,7 +3467,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional) case PHPExcel_Style_Alignment::HORIZONTAL_LEFT: $blockAlign = 1; break; - case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: + case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: $blockAlign = 3; break; case PHPExcel_Style_Alignment::HORIZONTAL_CENTER: @@ -4275,4 +4258,4 @@ private function _writeCFHeader() $data .= $cellRange; $this->_append($header . $data); } -} \ No newline at end of file +} From f7296f58b4607c158b3c5358db246d4fe5064aaa Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 13 May 2015 00:40:55 +0100 Subject: [PATCH 360/467] More PSR-2 goodness.... getting there slowly --- Classes/PHPExcel/Calculation.php | 7681 +++++++++--------- Classes/PHPExcel/Shared/CodePage.php | 147 +- Classes/PHPExcel/Shared/Date.php | 715 +- Classes/PHPExcel/Shared/ZipArchive.php | 128 +- Classes/PHPExcel/Shared/ZipStreamWrapper.php | 92 +- 5 files changed, 4370 insertions(+), 4393 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 6f0f3a896..b054fe2ac 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -21,3932 +21,3931 @@ * @category PHPExcel * @package PHPExcel_Calculation * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } if (!defined('CALCULATION_REGEXP_CELLREF')) { - // Test for support of \P (multibyte options) in PCRE - if(defined('PREG_BAD_UTF8_ERROR')) { - // Cell reference (cell or range of cells, with or without a sheet reference) - define('CALCULATION_REGEXP_CELLREF','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})'); - // Named Range of cells - define('CALCULATION_REGEXP_NAMEDRANGE','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)'); - } else { - // Cell reference (cell or range of cells, with or without a sheet reference) - define('CALCULATION_REGEXP_CELLREF','(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)'); - // Named Range of cells - define('CALCULATION_REGEXP_NAMEDRANGE','(((\w*)|(\'.*\')|(\".*\"))!)?([_A-Z][_A-Z0-9\.]*)'); - } + // Test for support of \P (multibyte options) in PCRE + if(defined('PREG_BAD_UTF8_ERROR')) { + // Cell reference (cell or range of cells, with or without a sheet reference) + define('CALCULATION_REGEXP_CELLREF','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})'); + // Named Range of cells + define('CALCULATION_REGEXP_NAMEDRANGE','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)'); + } else { + // Cell reference (cell or range of cells, with or without a sheet reference) + define('CALCULATION_REGEXP_CELLREF','(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)'); + // Named Range of cells + define('CALCULATION_REGEXP_NAMEDRANGE','(((\w*)|(\'.*\')|(\".*\"))!)?([_A-Z][_A-Z0-9\.]*)'); + } } /** * PHPExcel_Calculation (Multiton) * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Calculation { - /** Constants */ - /** Regular Expressions */ - // Numeric operand - const CALCULATION_REGEXP_NUMBER = '[-+]?\d*\.?\d+(e[-+]?\d+)?'; - // String operand - const CALCULATION_REGEXP_STRING = '"(?:[^"]|"")*"'; - // Opening bracket - const CALCULATION_REGEXP_OPENBRACE = '\('; - // Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it) - const CALCULATION_REGEXP_FUNCTION = '@?([A-Z][A-Z0-9\.]*)[\s]*\('; - // Cell reference (cell or range of cells, with or without a sheet reference) - const CALCULATION_REGEXP_CELLREF = CALCULATION_REGEXP_CELLREF; - // Named Range of cells - const CALCULATION_REGEXP_NAMEDRANGE = CALCULATION_REGEXP_NAMEDRANGE; - // Error - const CALCULATION_REGEXP_ERROR = '\#[A-Z][A-Z0_\/]*[!\?]?'; - - - /** constants */ - const RETURN_ARRAY_AS_ERROR = 'error'; - const RETURN_ARRAY_AS_VALUE = 'value'; - const RETURN_ARRAY_AS_ARRAY = 'array'; - - private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; - - - /** - * Instance of this class - * - * @access private - * @var PHPExcel_Calculation - */ - private static $_instance; - - - /** - * Instance of the workbook this Calculation Engine is using - * - * @access private - * @var PHPExcel - */ + /** Constants */ + /** Regular Expressions */ + // Numeric operand + const CALCULATION_REGEXP_NUMBER = '[-+]?\d*\.?\d+(e[-+]?\d+)?'; + // String operand + const CALCULATION_REGEXP_STRING = '"(?:[^"]|"")*"'; + // Opening bracket + const CALCULATION_REGEXP_OPENBRACE = '\('; + // Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it) + const CALCULATION_REGEXP_FUNCTION = '@?([A-Z][A-Z0-9\.]*)[\s]*\('; + // Cell reference (cell or range of cells, with or without a sheet reference) + const CALCULATION_REGEXP_CELLREF = CALCULATION_REGEXP_CELLREF; + // Named Range of cells + const CALCULATION_REGEXP_NAMEDRANGE = CALCULATION_REGEXP_NAMEDRANGE; + // Error + const CALCULATION_REGEXP_ERROR = '\#[A-Z][A-Z0_\/]*[!\?]?'; + + + /** constants */ + const RETURN_ARRAY_AS_ERROR = 'error'; + const RETURN_ARRAY_AS_VALUE = 'value'; + const RETURN_ARRAY_AS_ARRAY = 'array'; + + private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; + + + /** + * Instance of this class + * + * @access private + * @var 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 for individual workbooks - * - * @access private - * @var PHPExcel_Calculation[] - */ + /** + * List of instances of the calculation engine that we've instantiated for individual workbooks + * + * @access private + * @var PHPExcel_Calculation[] + */ private static $_workbookSets; - /** - * Calculation cache - * - * @access private - * @var array - */ - private $_calculationCache = array (); - - - /** - * Calculation cache enabled - * - * @access private - * @var boolean - */ - private $_calculationCacheEnabled = TRUE; - - - /** - * List of operators that can be used within formulae - * The true/false value indicates whether it is a binary operator or a unary operator - * - * @access private - * @var array - */ - private static $_operators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, - '^' => TRUE, '&' => TRUE, '%' => FALSE, '~' => FALSE, - '>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, - '<=' => TRUE, '<>' => TRUE, '|' => TRUE, ':' => TRUE - ); - - - /** - * List of binary operators (those that expect two operands) - * - * @access private - * @var array - */ - private static $_binaryOperators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, - '^' => TRUE, '&' => TRUE, '>' => TRUE, '<' => TRUE, - '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE, - '|' => TRUE, ':' => TRUE - ); - - /** - * The debug log generated by the calculation engine - * - * @access private - * @var PHPExcel_CalcEngine_Logger - * - */ - private $debugLog; - - /** - * Flag to determine how formula errors should be handled - * If true, then a user error will be triggered - * If false, then an exception will be thrown - * - * @access public - * @var boolean - * - */ - public $suppressFormulaErrors = FALSE; - - /** - * Error message for any error that was raised/thrown by the calculation engine - * - * @access public - * @var string - * - */ - public $formulaError = NULL; - - /** - * An array of the nested cell references accessed by the calculation engine, used for the debug log - * - * @access private - * @var array of string - * - */ - private $_cyclicReferenceStack; - - private $_cellStack = array(); - - /** - * Current iteration counter for cyclic formulae - * If the value is 0 (or less) then cyclic formulae will throw an exception, - * otherwise they will iterate to the limit defined here before returning a result - * - * @var integer - * - */ - private $_cyclicFormulaCount = 1; - - private $_cyclicFormulaCell = ''; - - /** - * Number of iterations for cyclic formulae - * - * @var integer - * - */ - public $cyclicFormulaCount = 1; - - /** - * Precision used for calculations - * - * @var integer - * - */ - private $_savedPrecision = 14; - - - /** - * The current locale setting - * - * @var string - * - */ - private static $_localeLanguage = 'en_us'; // US English (default locale) - - /** - * List of available locale settings - * Note that this is read for the locale subdirectory only when requested - * - * @var string[] - * - */ - private static $_validLocaleLanguages = array( 'en' // English (default language) - ); - /** - * Locale-specific argument separator for function arguments - * - * @var string - * - */ - private static $_localeArgumentSeparator = ','; - private static $_localeFunctions = array(); - - /** - * Locale-specific translations for Excel constants (True, False and Null) - * - * @var string[] - * - */ - public static $_localeBoolean = array( 'TRUE' => 'TRUE', - 'FALSE' => 'FALSE', - 'NULL' => 'NULL' - ); - - - /** - * Excel constant string translations to their PHP equivalents - * Constant conversion from text name/value to actual (datatyped) value - * - * @var string[] - * - */ - private static $_ExcelConstants = array('TRUE' => TRUE, - 'FALSE' => FALSE, - 'NULL' => NULL - ); - - // PHPExcel functions - private static $_PHPExcelFunctions = array( // PHPExcel functions - 'ABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'abs', - 'argumentCount' => '1' - ), - 'ACCRINT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', - 'argumentCount' => '4-7' - ), - 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', - 'argumentCount' => '3-5' - ), - 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'acos', - 'argumentCount' => '1' - ), - 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'acosh', - 'argumentCount' => '1' - ), - 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', - 'argumentCount' => '2-5' - ), - 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', - 'argumentCount' => '6,7' - ), - 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', - 'argumentCount' => '6,7' - ), - 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', - 'argumentCount' => '1+' - ), - 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'asin', - 'argumentCount' => '1' - ), - 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'asinh', - 'argumentCount' => '1' - ), - 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'atan', - 'argumentCount' => '1' - ), - 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', - 'argumentCount' => '2' - ), - 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'atanh', - 'argumentCount' => '1' - ), - 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', - 'argumentCount' => '1+' - ), - 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', - 'argumentCount' => '1+' - ), - 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', - 'argumentCount' => '1+' - ), - 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', - 'argumentCount' => '2,3' - ), - 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3+' - ), - 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', - 'argumentCount' => '2' - ), - 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', - 'argumentCount' => '2' - ), - 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', - 'argumentCount' => '2' - ), - 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', - 'argumentCount' => '2' - ), - 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', - 'argumentCount' => '3-5' - ), - 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', - 'argumentCount' => '3-5' - ), - 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', - 'argumentCount' => '1' - ), - 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', - 'argumentCount' => '1,2' - ), - 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', - 'argumentCount' => '1,2' - ), - 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', - 'argumentCount' => '4' - ), - 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', - 'argumentCount' => '2' - ), - 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1,2' - ), - 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', - 'argumentCount' => '1' - ), - 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', - 'argumentCount' => '2' - ), - 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', - 'argumentCount' => '2' - ), - 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', - 'argumentCount' => '2+' - ), - 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', - 'argumentCount' => '1' - ), - 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', - 'argumentCount' => '1' - ), - 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', - 'argumentCount' => '-1', - 'passByReference' => array(TRUE) - ), - 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', - 'argumentCount' => '1' - ), - 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', - 'argumentCount' => '2' - ), - 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', - 'argumentCount' => '2,3' - ), - 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', - 'argumentCount' => '1+' - ), - 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', - 'argumentCount' => '3' - ), - 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', - 'argumentCount' => '3' - ), - 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', - 'argumentCount' => '2' - ), - 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'cos', - 'argumentCount' => '1' - ), - 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'cosh', - 'argumentCount' => '1' - ), - 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', - 'argumentCount' => '1+' - ), - 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', - 'argumentCount' => '1+' - ), - 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', - 'argumentCount' => '1' - ), - 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', - 'argumentCount' => '2' - ), - 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', - 'argumentCount' => '3,4' - ), - 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', - 'argumentCount' => '3,4' - ), - 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', - 'argumentCount' => '3,4' - ), - 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', - 'argumentCount' => '3,4' - ), - 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', - 'argumentCount' => '3,4' - ), - 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', - 'argumentCount' => '3,4' - ), - 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', - 'argumentCount' => '2' - ), - 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', - 'argumentCount' => '3' - ), - 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', - 'argumentCount' => '6' - ), - 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', - 'argumentCount' => '6' - ), - 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', - 'argumentCount' => '3' - ), - 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', - 'argumentCount' => '2,3' - ), - 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', - 'argumentCount' => '1' - ), - 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', - 'argumentCount' => '3' - ), - 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', - 'argumentCount' => '1' - ), - 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', - 'argumentCount' => '2,3' - ), - 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DB', - 'argumentCount' => '4,5' - ), - 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', - 'argumentCount' => '3' - ), - 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', - 'argumentCount' => '3' - ), - 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', - 'argumentCount' => '4,5' - ), - 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', - 'argumentCount' => '1,2' - ), - 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', - 'argumentCount' => '1,2' - ), - 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', - 'argumentCount' => '1,2' - ), - 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'rad2deg', - 'argumentCount' => '1' - ), - 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', - 'argumentCount' => '1,2' - ), - 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', - 'argumentCount' => '1+' - ), - 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DGET', - 'argumentCount' => '3' - ), - 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', - 'argumentCount' => '4,5' - ), - 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', - 'argumentCount' => '3' - ), - 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', - 'argumentCount' => '3' - ), - 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', - 'argumentCount' => '1,2' - ), - 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', - 'argumentCount' => '2' - ), - 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', - 'argumentCount' => '2' - ), - 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', - 'argumentCount' => '3' - ), - 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', - 'argumentCount' => '3' - ), - 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', - 'argumentCount' => '3' - ), - 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', - 'argumentCount' => '3' - ), - 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5,6' - ), - 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', - 'argumentCount' => '3' - ), - 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', - 'argumentCount' => '3' - ), - 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', - 'argumentCount' => '2' - ), - 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', - 'argumentCount' => '2' - ), - 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', - 'argumentCount' => '2' - ), - 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', - 'argumentCount' => '1,2' - ), - 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', - 'argumentCount' => '1' - ), - 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', - 'argumentCount' => '1' - ), - 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', - 'argumentCount' => '1' - ), - 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'exp', - 'argumentCount' => '1' - ), - 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', - 'argumentCount' => '3' - ), - 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', - 'argumentCount' => '1' - ), - 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', - 'argumentCount' => '1' - ), - 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', - 'argumentCount' => '0' - ), - 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3' - ), - 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', - 'argumentCount' => '2,3' - ), - 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', - 'argumentCount' => '2,3' - ), - 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3' - ), - 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', - 'argumentCount' => '1' - ), - 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', - 'argumentCount' => '1' - ), - 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', - 'argumentCount' => '1-3' - ), - 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', - 'argumentCount' => '2' - ), - 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', - 'argumentCount' => '3' - ), - 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::FV', - 'argumentCount' => '3-5' - ), - 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', - 'argumentCount' => '2' - ), - 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', - 'argumentCount' => '4' - ), - 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', - 'argumentCount' => '3' - ), - 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', - 'argumentCount' => '1' - ), - 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', - 'argumentCount' => '1+' - ), - 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', - 'argumentCount' => '1+' - ), - 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', - 'argumentCount' => '1,2' - ), - 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2+' - ), - 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', - 'argumentCount' => '1-4' - ), - 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', - 'argumentCount' => '1+' - ), - 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', - 'argumentCount' => '1,2' - ), - 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', - 'argumentCount' => '1' - ), - 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', - 'argumentCount' => '1,2' - ), - 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', - 'argumentCount' => '3,4' - ), - 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', - 'argumentCount' => '1' - ), - 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', - 'argumentCount' => '1,2', - 'passCellReference'=> TRUE - ), - 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', - 'argumentCount' => '4' - ), - 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', - 'argumentCount' => '1-3' - ), - 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', - 'argumentCount' => '2' - ), - 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', - 'argumentCount' => '1' - ), - 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', - 'argumentCount' => '1' - ), - 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', - 'argumentCount' => '1' - ), - 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', - 'argumentCount' => '1' - ), - 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', - 'argumentCount' => '1' - ), - 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', - 'argumentCount' => '2' - ), - 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', - 'argumentCount' => '1' - ), - 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', - 'argumentCount' => '1' - ), - 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', - 'argumentCount' => '1' - ), - 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', - 'argumentCount' => '1' - ), - 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', - 'argumentCount' => '2' - ), - 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', - 'argumentCount' => '1+' - ), - 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', - 'argumentCount' => '1' - ), - 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', - 'argumentCount' => '1' - ), - 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', - 'argumentCount' => '1' - ), - 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', - 'argumentCount' => '2' - ), - 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', - 'argumentCount' => '1+' - ), - 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', - 'argumentCount' => '1-4' - ), - 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', - 'argumentCount' => '1,2', - 'passCellReference'=> TRUE - ), - 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', - 'argumentCount' => '1' - ), - 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', - 'argumentCount' => '2' - ), - 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', - 'argumentCount' => '4,5' - ), - 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', - 'argumentCount' => '4-6' - ), - 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', - 'argumentCount' => '1,2' - ), - 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', - 'argumentCount' => '1' - ), - 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', - 'argumentCount' => '1' - ), - 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', - 'argumentCount' => '1' - ), - 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', - 'argumentCount' => '1' - ), - 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', - 'argumentCount' => '1' - ), - 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', - 'argumentCount' => '1' - ), - 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', - 'argumentCount' => '1' - ), - 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', - 'argumentCount' => '1' - ), - 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', - 'argumentCount' => '1' - ), - 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', - 'argumentCount' => '4' - ), - 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', - 'argumentCount' => '1' - ), - 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', - 'argumentCount' => '1+' - ), - 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', - 'argumentCount' => '2' - ), - 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', - 'argumentCount' => '1+' - ), - 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', - 'argumentCount' => '1,2' - ), - 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', - 'argumentCount' => '1,2' - ), - 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', - 'argumentCount' => '1' - ), - 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', - 'argumentCount' => '1' - ), - 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', - 'argumentCount' => '1-4' - ), - 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'log', - 'argumentCount' => '1' - ), - 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', - 'argumentCount' => '1,2' - ), - 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'log10', - 'argumentCount' => '1' - ), - 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', - 'argumentCount' => '1-4' - ), - 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', - 'argumentCount' => '3' - ), - 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', - 'argumentCount' => '3' - ), - 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', - 'argumentCount' => '2,3' - ), - 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', - 'argumentCount' => '1' - ), - 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', - 'argumentCount' => '2,3' - ), - 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', - 'argumentCount' => '1+' - ), - 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', - 'argumentCount' => '1+' - ), - 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', - 'argumentCount' => '2+' - ), - 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', - 'argumentCount' => '1' - ), - 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5,6' - ), - 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', - 'argumentCount' => '1+' - ), - 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2+' - ), - 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::MID', - 'argumentCount' => '3' - ), - 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::MID', - 'argumentCount' => '3' - ), - 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', - 'argumentCount' => '1+' - ), - 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', - 'argumentCount' => '1+' - ), - 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', - 'argumentCount' => '2+' - ), - 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', - 'argumentCount' => '1' - ), - 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', - 'argumentCount' => '1' - ), - 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', - 'argumentCount' => '3' - ), - 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', - 'argumentCount' => '2' - ), - 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', - 'argumentCount' => '2' - ), - 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', - 'argumentCount' => '1+' - ), - 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', - 'argumentCount' => '1' - ), - 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', - 'argumentCount' => '2' - ), - 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', - 'argumentCount' => '1+' - ), - 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::N', - 'argumentCount' => '1' - ), - 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::NA', - 'argumentCount' => '0' - ), - 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', - 'argumentCount' => '3' - ), - 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', - 'argumentCount' => '2+' - ), - 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', - 'argumentCount' => '2' - ), - 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', - 'argumentCount' => '4' - ), - 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', - 'argumentCount' => '3' - ), - 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', - 'argumentCount' => '1' - ), - 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', - 'argumentCount' => '1' - ), - 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', - 'argumentCount' => '1' - ), - 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', - 'argumentCount' => '0' - ), - 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', - 'argumentCount' => '3-5' - ), - 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', - 'argumentCount' => '2+' - ), - 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', - 'argumentCount' => '1,2' - ), - 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', - 'argumentCount' => '1' - ), - 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', - 'argumentCount' => '1,2' - ), - 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', - 'argumentCount' => '1' - ), - 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '8,9' - ), - 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '8,9' - ), - 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '7,8' - ), - 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '7,8' - ), - 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', - 'argumentCount' => '3,5', - 'passCellReference'=> TRUE, - 'passByReference' => array(TRUE) - ), - 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', - 'argumentCount' => '1+' - ), - 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', - 'argumentCount' => '2' - ), - 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', - 'argumentCount' => '2' - ), - 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', - 'argumentCount' => '2,3' - ), - 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', - 'argumentCount' => '2' - ), - 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'pi', - 'argumentCount' => '0' - ), - 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', - 'argumentCount' => '3-5' - ), - 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', - 'argumentCount' => '3' - ), - 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', - 'argumentCount' => '2' - ), - 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', - 'argumentCount' => '4-6' - ), - 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', - 'argumentCount' => '6,7' - ), - 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', - 'argumentCount' => '4,5' - ), - 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', - 'argumentCount' => '5,6' - ), - 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3,4' - ), - 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', - 'argumentCount' => '1+' - ), - 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', - 'argumentCount' => '1' - ), - 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PV', - 'argumentCount' => '3-5' - ), - 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', - 'argumentCount' => '2' - ), - 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', - 'argumentCount' => '2' - ), - 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'deg2rad', - 'argumentCount' => '1' - ), - 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', - 'argumentCount' => '0' - ), - 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', - 'argumentCount' => '2' - ), - 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', - 'argumentCount' => '2,3' - ), - 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', - 'argumentCount' => '3-6' - ), - 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', - 'argumentCount' => '4-5' - ), - 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', - 'argumentCount' => '4' - ), - 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', - 'argumentCount' => '4' - ), - 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'str_repeat', - 'argumentCount' => '2' - ), - 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', - 'argumentCount' => '1,2' - ), - 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', - 'argumentCount' => '1,2' - ), - 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', - 'argumentCount' => '1,2' - ), - 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'round', - 'argumentCount' => '2' - ), - 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', - 'argumentCount' => '2' - ), - 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', - 'argumentCount' => '2' - ), - 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', - 'argumentCount' => '-1', - 'passByReference' => array(TRUE) - ), - 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', - 'argumentCount' => '1' - ), - 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', - 'argumentCount' => '2' - ), - 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1+' - ), - 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', - 'argumentCount' => '2,3' - ), - 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', - 'argumentCount' => '2,3' - ), - 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', - 'argumentCount' => '1' - ), - 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', - 'argumentCount' => '4' - ), - 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', - 'argumentCount' => '1' - ), - 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sin', - 'argumentCount' => '1' - ), - 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sinh', - 'argumentCount' => '1' - ), - 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', - 'argumentCount' => '1+' - ), - 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', - 'argumentCount' => '3' - ), - 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', - 'argumentCount' => '2' - ), - 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', - 'argumentCount' => '2' - ), - 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sqrt', - 'argumentCount' => '1' - ), - 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', - 'argumentCount' => '1' - ), - 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', - 'argumentCount' => '3' - ), - 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', - 'argumentCount' => '1+' - ), - 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', - 'argumentCount' => '1+' - ), - 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', - 'argumentCount' => '1+' - ), - 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', - 'argumentCount' => '1+' - ), - 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', - 'argumentCount' => '2' - ), - 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', - 'argumentCount' => '3,4' - ), - 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', - 'argumentCount' => '2+' - ), - 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', - 'argumentCount' => '1+' - ), - 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', - 'argumentCount' => '2,3' - ), - 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', - 'argumentCount' => '1+' - ), - 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', - 'argumentCount' => '1+' - ), - 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', - 'argumentCount' => '2' - ), - 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', - 'argumentCount' => '2' - ), - 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', - 'argumentCount' => '2' - ), - 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', - 'argumentCount' => '4' - ), - 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', - 'argumentCount' => '1' - ), - 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'tan', - 'argumentCount' => '1' - ), - 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'tanh', - 'argumentCount' => '1' - ), - 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', - 'argumentCount' => '3' - ), - 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', - 'argumentCount' => '3' - ), - 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', - 'argumentCount' => '3' - ), - 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', - 'argumentCount' => '3' - ), - 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', - 'argumentCount' => '2' - ), - 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', - 'argumentCount' => '3' - ), - 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', - 'argumentCount' => '1' - ), - 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', - 'argumentCount' => '2' - ), - 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', - 'argumentCount' => '0' - ), - 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', - 'argumentCount' => '1' - ), - 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', - 'argumentCount' => '1-4' - ), - 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', - 'argumentCount' => '1' - ), - 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', - 'argumentCount' => '2' - ), - 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', - 'argumentCount' => '0' - ), - 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', - 'argumentCount' => '1,2' - ), - 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '4' - ), - 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', - 'argumentCount' => '1' - ), - 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', - 'argumentCount' => '1' - ), - 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', - 'argumentCount' => '1' - ), - 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', - 'argumentCount' => '1+' - ), - 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', - 'argumentCount' => '1+' - ), - 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', - 'argumentCount' => '1+' - ), - 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', - 'argumentCount' => '1+' - ), - 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5-7' - ), - 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', - 'argumentCount' => '0' - ), - 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', - 'argumentCount' => '3,4' - ), - 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', - 'argumentCount' => '1,2' - ), - 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', - 'argumentCount' => '1,2' - ), - 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', - 'argumentCount' => '4' - ), - 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', - 'argumentCount' => '2+' - ), - 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', - 'argumentCount' => '2,3' - ), - 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', - 'argumentCount' => '3' - ), - 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', - 'argumentCount' => '1' - ), - 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', - 'argumentCount' => '2,3' - ), - 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '6,7' - ), - 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', - 'argumentCount' => '4,5' - ), - 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', - 'argumentCount' => '5,6' - ), - 'ZTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', - 'argumentCount' => '2-3' - ) - ); - - - // Internal functions used for special control purposes - private static $_controlFunctions = array( - 'MKMATRIX' => array('argumentCount' => '*', - 'functionCall' => 'self::_mkMatrix' - ) - ); - - - - - private function __construct(PHPExcel $workbook = NULL) { - $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; - $this->_savedPrecision = ini_get('precision'); - if ($this->_savedPrecision < $setPrecision) { - ini_set('precision',$setPrecision); - } - $this->delta = 1 * pow(10, -$setPrecision); - - if ($workbook !== NULL) { - self::$_workbookSets[$workbook->getID()] = $this; - } - - $this->_workbook = $workbook; - $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); - $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack); - } // function __construct() - - - public function __destruct() { - if ($this->_savedPrecision != ini_get('precision')) { - ini_set('precision',$this->_savedPrecision); - } - } - - private static function _loadLocales() { - $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/'; - foreach (glob($localeFileDirectory.'/*',GLOB_ONLYDIR) as $filename) { - $filename = substr($filename,strlen($localeFileDirectory)+1); - if ($filename != 'en') { - self::$_validLocaleLanguages[] = $filename; - } - } - } - - /** - * Get an instance of this class - * - * @access public - * @param PHPExcel $workbook Injected workbook for working with a PHPExcel object, - * or NULL to create a standalone claculation engine - * @return PHPExcel_Calculation - */ - 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(); - } - - return self::$_instance; - } // function getInstance() - - /** - * Unset an instance of this class - * - * @access public - * @param PHPExcel $workbook Injected workbook identifying the instance to unset - */ - public static function unsetInstance(PHPExcel $workbook = NULL) { - if ($workbook !== NULL) { - if (isset(self::$_workbookSets[$workbook->getID()])) { - unset(self::$_workbookSets[$workbook->getID()]); - } - } + /** + * Calculation cache + * + * @access private + * @var array + */ + private $_calculationCache = array (); + + + /** + * Calculation cache enabled + * + * @access private + * @var boolean + */ + private $_calculationCacheEnabled = TRUE; + + + /** + * List of operators that can be used within formulae + * The true/false value indicates whether it is a binary operator or a unary operator + * + * @access private + * @var array + */ + private static $_operators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, + '^' => TRUE, '&' => TRUE, '%' => FALSE, '~' => FALSE, + '>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, + '<=' => TRUE, '<>' => TRUE, '|' => TRUE, ':' => TRUE + ); + + + /** + * List of binary operators (those that expect two operands) + * + * @access private + * @var array + */ + private static $_binaryOperators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, + '^' => TRUE, '&' => TRUE, '>' => TRUE, '<' => TRUE, + '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE, + '|' => TRUE, ':' => TRUE + ); + + /** + * The debug log generated by the calculation engine + * + * @access private + * @var PHPExcel_CalcEngine_Logger + * + */ + private $debugLog; + + /** + * Flag to determine how formula errors should be handled + * If true, then a user error will be triggered + * If false, then an exception will be thrown + * + * @access public + * @var boolean + * + */ + public $suppressFormulaErrors = FALSE; + + /** + * Error message for any error that was raised/thrown by the calculation engine + * + * @access public + * @var string + * + */ + public $formulaError = NULL; + + /** + * An array of the nested cell references accessed by the calculation engine, used for the debug log + * + * @access private + * @var array of string + * + */ + private $_cyclicReferenceStack; + + private $_cellStack = array(); + + /** + * Current iteration counter for cyclic formulae + * If the value is 0 (or less) then cyclic formulae will throw an exception, + * otherwise they will iterate to the limit defined here before returning a result + * + * @var integer + * + */ + private $_cyclicFormulaCount = 1; + + private $_cyclicFormulaCell = ''; + + /** + * Number of iterations for cyclic formulae + * + * @var integer + * + */ + public $cyclicFormulaCount = 1; + + /** + * Precision used for calculations + * + * @var integer + * + */ + private $_savedPrecision = 14; + + + /** + * The current locale setting + * + * @var string + * + */ + private static $_localeLanguage = 'en_us'; // US English (default locale) + + /** + * List of available locale settings + * Note that this is read for the locale subdirectory only when requested + * + * @var string[] + * + */ + private static $_validLocaleLanguages = array( 'en' // English (default language) + ); + /** + * Locale-specific argument separator for function arguments + * + * @var string + * + */ + private static $_localeArgumentSeparator = ','; + private static $_localeFunctions = array(); + + /** + * Locale-specific translations for Excel constants (True, False and Null) + * + * @var string[] + * + */ + public static $_localeBoolean = array( 'TRUE' => 'TRUE', + 'FALSE' => 'FALSE', + 'NULL' => 'NULL' + ); + + + /** + * Excel constant string translations to their PHP equivalents + * Constant conversion from text name/value to actual (datatyped) value + * + * @var string[] + * + */ + private static $_ExcelConstants = array('TRUE' => TRUE, + 'FALSE' => FALSE, + 'NULL' => NULL + ); + + // PHPExcel functions + private static $_PHPExcelFunctions = array( // PHPExcel functions + 'ABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'abs', + 'argumentCount' => '1' + ), + 'ACCRINT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', + 'argumentCount' => '4-7' + ), + 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', + 'argumentCount' => '3-5' + ), + 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acos', + 'argumentCount' => '1' + ), + 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acosh', + 'argumentCount' => '1' + ), + 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', + 'argumentCount' => '2-5' + ), + 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', + 'argumentCount' => '6,7' + ), + 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', + 'argumentCount' => '6,7' + ), + 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', + 'argumentCount' => '1+' + ), + 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asin', + 'argumentCount' => '1' + ), + 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asinh', + 'argumentCount' => '1' + ), + 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atan', + 'argumentCount' => '1' + ), + 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', + 'argumentCount' => '2' + ), + 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atanh', + 'argumentCount' => '1' + ), + 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', + 'argumentCount' => '1+' + ), + 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', + 'argumentCount' => '1+' + ), + 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', + 'argumentCount' => '1+' + ), + 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', + 'argumentCount' => '2,3' + ), + 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3+' + ), + 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', + 'argumentCount' => '2' + ), + 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', + 'argumentCount' => '2' + ), + 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', + 'argumentCount' => '2' + ), + 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', + 'argumentCount' => '2' + ), + 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', + 'argumentCount' => '3-5' + ), + 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', + 'argumentCount' => '3-5' + ), + 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', + 'argumentCount' => '1' + ), + 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', + 'argumentCount' => '1,2' + ), + 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', + 'argumentCount' => '1,2' + ), + 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', + 'argumentCount' => '4' + ), + 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', + 'argumentCount' => '2' + ), + 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1,2' + ), + 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', + 'argumentCount' => '1' + ), + 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', + 'argumentCount' => '2' + ), + 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', + 'argumentCount' => '2' + ), + 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', + 'argumentCount' => '2+' + ), + 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', + 'argumentCount' => '1' + ), + 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', + 'argumentCount' => '1' + ), + 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', + 'argumentCount' => '-1', + 'passByReference' => array(TRUE) + ), + 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', + 'argumentCount' => '1' + ), + 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', + 'argumentCount' => '2' + ), + 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', + 'argumentCount' => '2,3' + ), + 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', + 'argumentCount' => '1+' + ), + 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', + 'argumentCount' => '3' + ), + 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', + 'argumentCount' => '3' + ), + 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cos', + 'argumentCount' => '1' + ), + 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cosh', + 'argumentCount' => '1' + ), + 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', + 'argumentCount' => '1+' + ), + 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', + 'argumentCount' => '1+' + ), + 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', + 'argumentCount' => '1' + ), + 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', + 'argumentCount' => '2' + ), + 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', + 'argumentCount' => '3,4' + ), + 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', + 'argumentCount' => '3,4' + ), + 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', + 'argumentCount' => '3,4' + ), + 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', + 'argumentCount' => '3,4' + ), + 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', + 'argumentCount' => '3,4' + ), + 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', + 'argumentCount' => '3,4' + ), + 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', + 'argumentCount' => '2' + ), + 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', + 'argumentCount' => '3' + ), + 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', + 'argumentCount' => '6' + ), + 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', + 'argumentCount' => '6' + ), + 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', + 'argumentCount' => '3' + ), + 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', + 'argumentCount' => '2,3' + ), + 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', + 'argumentCount' => '1' + ), + 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', + 'argumentCount' => '3' + ), + 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', + 'argumentCount' => '1' + ), + 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', + 'argumentCount' => '2,3' + ), + 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DB', + 'argumentCount' => '4,5' + ), + 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', + 'argumentCount' => '3' + ), + 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', + 'argumentCount' => '3' + ), + 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', + 'argumentCount' => '4,5' + ), + 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', + 'argumentCount' => '1,2' + ), + 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', + 'argumentCount' => '1,2' + ), + 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', + 'argumentCount' => '1,2' + ), + 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'rad2deg', + 'argumentCount' => '1' + ), + 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', + 'argumentCount' => '1,2' + ), + 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', + 'argumentCount' => '1+' + ), + 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DGET', + 'argumentCount' => '3' + ), + 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', + 'argumentCount' => '4,5' + ), + 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', + 'argumentCount' => '3' + ), + 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', + 'argumentCount' => '3' + ), + 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', + 'argumentCount' => '1,2' + ), + 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', + 'argumentCount' => '2' + ), + 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', + 'argumentCount' => '2' + ), + 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', + 'argumentCount' => '3' + ), + 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', + 'argumentCount' => '3' + ), + 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', + 'argumentCount' => '3' + ), + 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', + 'argumentCount' => '3' + ), + 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', + 'argumentCount' => '3' + ), + 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', + 'argumentCount' => '3' + ), + 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', + 'argumentCount' => '2' + ), + 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', + 'argumentCount' => '2' + ), + 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', + 'argumentCount' => '2' + ), + 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', + 'argumentCount' => '1,2' + ), + 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', + 'argumentCount' => '1' + ), + 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', + 'argumentCount' => '1' + ), + 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', + 'argumentCount' => '1' + ), + 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'exp', + 'argumentCount' => '1' + ), + 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', + 'argumentCount' => '3' + ), + 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', + 'argumentCount' => '1' + ), + 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', + 'argumentCount' => '1' + ), + 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', + 'argumentCount' => '0' + ), + 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', + 'argumentCount' => '1' + ), + 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', + 'argumentCount' => '1' + ), + 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', + 'argumentCount' => '1-3' + ), + 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', + 'argumentCount' => '2' + ), + 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', + 'argumentCount' => '3' + ), + 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FV', + 'argumentCount' => '3-5' + ), + 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', + 'argumentCount' => '2' + ), + 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', + 'argumentCount' => '4' + ), + 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', + 'argumentCount' => '3' + ), + 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', + 'argumentCount' => '1' + ), + 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', + 'argumentCount' => '1+' + ), + 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', + 'argumentCount' => '1+' + ), + 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', + 'argumentCount' => '1,2' + ), + 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', + 'argumentCount' => '1-4' + ), + 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', + 'argumentCount' => '1+' + ), + 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', + 'argumentCount' => '1,2' + ), + 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', + 'argumentCount' => '1' + ), + 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', + 'argumentCount' => '1,2' + ), + 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', + 'argumentCount' => '3,4' + ), + 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', + 'argumentCount' => '1' + ), + 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', + 'argumentCount' => '1,2', + 'passCellReference'=> TRUE + ), + 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', + 'argumentCount' => '4' + ), + 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', + 'argumentCount' => '1-3' + ), + 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', + 'argumentCount' => '2' + ), + 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', + 'argumentCount' => '1' + ), + 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', + 'argumentCount' => '1' + ), + 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', + 'argumentCount' => '1' + ), + 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', + 'argumentCount' => '1' + ), + 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', + 'argumentCount' => '1' + ), + 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', + 'argumentCount' => '2' + ), + 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', + 'argumentCount' => '1' + ), + 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', + 'argumentCount' => '1' + ), + 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', + 'argumentCount' => '1' + ), + 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', + 'argumentCount' => '1' + ), + 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', + 'argumentCount' => '2' + ), + 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', + 'argumentCount' => '1+' + ), + 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', + 'argumentCount' => '1' + ), + 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', + 'argumentCount' => '1' + ), + 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', + 'argumentCount' => '1' + ), + 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', + 'argumentCount' => '2' + ), + 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', + 'argumentCount' => '1+' + ), + 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', + 'argumentCount' => '1-4' + ), + 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', + 'argumentCount' => '1,2', + 'passCellReference'=> TRUE + ), + 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', + 'argumentCount' => '1' + ), + 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', + 'argumentCount' => '2' + ), + 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', + 'argumentCount' => '4,5' + ), + 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', + 'argumentCount' => '4-6' + ), + 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', + 'argumentCount' => '1,2' + ), + 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', + 'argumentCount' => '1' + ), + 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', + 'argumentCount' => '1' + ), + 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', + 'argumentCount' => '1' + ), + 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', + 'argumentCount' => '1' + ), + 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', + 'argumentCount' => '1' + ), + 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', + 'argumentCount' => '1' + ), + 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', + 'argumentCount' => '1' + ), + 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', + 'argumentCount' => '1' + ), + 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', + 'argumentCount' => '1' + ), + 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', + 'argumentCount' => '4' + ), + 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', + 'argumentCount' => '1' + ), + 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', + 'argumentCount' => '1+' + ), + 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', + 'argumentCount' => '2' + ), + 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', + 'argumentCount' => '1+' + ), + 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', + 'argumentCount' => '1-4' + ), + 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log', + 'argumentCount' => '1' + ), + 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', + 'argumentCount' => '1,2' + ), + 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log10', + 'argumentCount' => '1' + ), + 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', + 'argumentCount' => '1-4' + ), + 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', + 'argumentCount' => '3' + ), + 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', + 'argumentCount' => '3' + ), + 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', + 'argumentCount' => '2,3' + ), + 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', + 'argumentCount' => '1' + ), + 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', + 'argumentCount' => '2,3' + ), + 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', + 'argumentCount' => '1+' + ), + 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', + 'argumentCount' => '1+' + ), + 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', + 'argumentCount' => '2+' + ), + 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', + 'argumentCount' => '1' + ), + 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', + 'argumentCount' => '1+' + ), + 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', + 'argumentCount' => '1+' + ), + 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', + 'argumentCount' => '1+' + ), + 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', + 'argumentCount' => '2+' + ), + 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', + 'argumentCount' => '1' + ), + 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', + 'argumentCount' => '1' + ), + 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', + 'argumentCount' => '3' + ), + 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', + 'argumentCount' => '2' + ), + 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', + 'argumentCount' => '2' + ), + 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', + 'argumentCount' => '1+' + ), + 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', + 'argumentCount' => '1' + ), + 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', + 'argumentCount' => '2' + ), + 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', + 'argumentCount' => '1+' + ), + 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::N', + 'argumentCount' => '1' + ), + 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::NA', + 'argumentCount' => '0' + ), + 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', + 'argumentCount' => '3' + ), + 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', + 'argumentCount' => '2+' + ), + 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', + 'argumentCount' => '2' + ), + 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', + 'argumentCount' => '4' + ), + 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', + 'argumentCount' => '3' + ), + 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', + 'argumentCount' => '1' + ), + 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', + 'argumentCount' => '1' + ), + 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', + 'argumentCount' => '1' + ), + 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', + 'argumentCount' => '0' + ), + 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', + 'argumentCount' => '3-5' + ), + 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', + 'argumentCount' => '2+' + ), + 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', + 'argumentCount' => '1,2' + ), + 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', + 'argumentCount' => '1' + ), + 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', + 'argumentCount' => '1,2' + ), + 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', + 'argumentCount' => '1' + ), + 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', + 'argumentCount' => '3,5', + 'passCellReference'=> TRUE, + 'passByReference' => array(TRUE) + ), + 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', + 'argumentCount' => '1+' + ), + 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', + 'argumentCount' => '2' + ), + 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', + 'argumentCount' => '2,3' + ), + 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', + 'argumentCount' => '2' + ), + 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'pi', + 'argumentCount' => '0' + ), + 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', + 'argumentCount' => '3-5' + ), + 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', + 'argumentCount' => '3' + ), + 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', + 'argumentCount' => '2' + ), + 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', + 'argumentCount' => '4-6' + ), + 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', + 'argumentCount' => '6,7' + ), + 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', + 'argumentCount' => '4,5' + ), + 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', + 'argumentCount' => '5,6' + ), + 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3,4' + ), + 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', + 'argumentCount' => '1+' + ), + 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', + 'argumentCount' => '1' + ), + 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PV', + 'argumentCount' => '3-5' + ), + 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', + 'argumentCount' => '2' + ), + 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', + 'argumentCount' => '2' + ), + 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'deg2rad', + 'argumentCount' => '1' + ), + 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '0' + ), + 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '2' + ), + 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', + 'argumentCount' => '2,3' + ), + 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', + 'argumentCount' => '3-6' + ), + 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', + 'argumentCount' => '4-5' + ), + 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'str_repeat', + 'argumentCount' => '2' + ), + 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', + 'argumentCount' => '1,2' + ), + 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'round', + 'argumentCount' => '2' + ), + 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', + 'argumentCount' => '2' + ), + 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', + 'argumentCount' => '2' + ), + 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', + 'argumentCount' => '-1', + 'passByReference' => array(TRUE) + ), + 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', + 'argumentCount' => '1' + ), + 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', + 'argumentCount' => '2' + ), + 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1+' + ), + 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', + 'argumentCount' => '1' + ), + 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', + 'argumentCount' => '4' + ), + 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', + 'argumentCount' => '1' + ), + 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sin', + 'argumentCount' => '1' + ), + 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sinh', + 'argumentCount' => '1' + ), + 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', + 'argumentCount' => '1+' + ), + 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', + 'argumentCount' => '3' + ), + 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', + 'argumentCount' => '2' + ), + 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', + 'argumentCount' => '2' + ), + 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sqrt', + 'argumentCount' => '1' + ), + 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', + 'argumentCount' => '1' + ), + 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', + 'argumentCount' => '3' + ), + 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', + 'argumentCount' => '1+' + ), + 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', + 'argumentCount' => '1+' + ), + 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', + 'argumentCount' => '1+' + ), + 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', + 'argumentCount' => '1+' + ), + 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', + 'argumentCount' => '2' + ), + 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', + 'argumentCount' => '3,4' + ), + 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', + 'argumentCount' => '2+' + ), + 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', + 'argumentCount' => '1+' + ), + 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', + 'argumentCount' => '2,3' + ), + 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', + 'argumentCount' => '1+' + ), + 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', + 'argumentCount' => '1+' + ), + 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', + 'argumentCount' => '2' + ), + 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', + 'argumentCount' => '2' + ), + 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', + 'argumentCount' => '2' + ), + 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', + 'argumentCount' => '4' + ), + 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', + 'argumentCount' => '1' + ), + 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tan', + 'argumentCount' => '1' + ), + 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tanh', + 'argumentCount' => '1' + ), + 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', + 'argumentCount' => '3' + ), + 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', + 'argumentCount' => '3' + ), + 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', + 'argumentCount' => '3' + ), + 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', + 'argumentCount' => '3' + ), + 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', + 'argumentCount' => '2' + ), + 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', + 'argumentCount' => '3' + ), + 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', + 'argumentCount' => '1' + ), + 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', + 'argumentCount' => '2' + ), + 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', + 'argumentCount' => '0' + ), + 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', + 'argumentCount' => '1' + ), + 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', + 'argumentCount' => '1-4' + ), + 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', + 'argumentCount' => '1' + ), + 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', + 'argumentCount' => '2' + ), + 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', + 'argumentCount' => '0' + ), + 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', + 'argumentCount' => '1,2' + ), + 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '4' + ), + 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', + 'argumentCount' => '1' + ), + 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', + 'argumentCount' => '1' + ), + 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', + 'argumentCount' => '1' + ), + 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', + 'argumentCount' => '1+' + ), + 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', + 'argumentCount' => '1+' + ), + 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', + 'argumentCount' => '1+' + ), + 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', + 'argumentCount' => '1+' + ), + 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5-7' + ), + 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', + 'argumentCount' => '0' + ), + 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', + 'argumentCount' => '3,4' + ), + 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', + 'argumentCount' => '1,2' + ), + 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', + 'argumentCount' => '1,2' + ), + 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', + 'argumentCount' => '4' + ), + 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', + 'argumentCount' => '2+' + ), + 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', + 'argumentCount' => '2,3' + ), + 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', + 'argumentCount' => '3' + ), + 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', + 'argumentCount' => '1' + ), + 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', + 'argumentCount' => '2,3' + ), + 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '6,7' + ), + 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', + 'argumentCount' => '4,5' + ), + 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', + 'argumentCount' => '5,6' + ), + 'ZTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', + 'argumentCount' => '2-3' + ) + ); + + + // Internal functions used for special control purposes + private static $_controlFunctions = array( + 'MKMATRIX' => array('argumentCount' => '*', + 'functionCall' => 'self::_mkMatrix' + ) + ); + + + + + private function __construct(PHPExcel $workbook = NULL) { + $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; + $this->_savedPrecision = ini_get('precision'); + if ($this->_savedPrecision < $setPrecision) { + ini_set('precision',$setPrecision); + } + $this->delta = 1 * pow(10, -$setPrecision); + + if ($workbook !== NULL) { + self::$_workbookSets[$workbook->getID()] = $this; + } + + $this->_workbook = $workbook; + $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); + $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack); + } // function __construct() + + + public function __destruct() { + if ($this->_savedPrecision != ini_get('precision')) { + ini_set('precision',$this->_savedPrecision); + } + } + + private static function _loadLocales() { + $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/'; + foreach (glob($localeFileDirectory.'/*',GLOB_ONLYDIR) as $filename) { + $filename = substr($filename,strlen($localeFileDirectory)+1); + if ($filename != 'en') { + self::$_validLocaleLanguages[] = $filename; + } + } + } + + /** + * Get an instance of this class + * + * @access public + * @param PHPExcel $workbook Injected workbook for working with a PHPExcel object, + * or NULL to create a standalone claculation engine + * @return PHPExcel_Calculation + */ + 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(); + } + + return self::$_instance; + } // function getInstance() + + /** + * Unset an instance of this class + * + * @access public + * @param PHPExcel $workbook Injected workbook identifying the instance to unset + */ + 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 + * but only if a PHPExcel_Calculation instance exists + * + * @access public + * @return null + */ + public function flushInstance() { + $this->clearCalculationCache(); + } // function flushInstance() + + + /** + * Get the debuglog for this claculation engine instance + * + * @access public + * @return PHPExcel_CalcEngine_Logger + */ + public function getDebugLog() { + return $this->_debugLog; } - /** - * Flush the calculation cache for any existing instance of this class - * but only if a PHPExcel_Calculation instance exists - * - * @access public - * @return null - */ - public function flushInstance() { - $this->clearCalculationCache(); - } // function flushInstance() - - - /** - * Get the debuglog for this claculation engine instance - * - * @access public - * @return PHPExcel_CalcEngine_Logger - */ - public function getDebugLog() { - return $this->_debugLog; - } - - /** - * __clone implementation. Cloning should not be allowed in a Singleton! - * - * @access public - * @throws PHPExcel_Calculation_Exception - */ - public final function __clone() { - throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!'); - } // function __clone() - - - /** - * Return the locale-specific translation of TRUE - * - * @access public - * @return string locale-specific translation of TRUE - */ - public static function getTRUE() { - return self::$_localeBoolean['TRUE']; - } - - /** - * Return the locale-specific translation of FALSE - * - * @access public - * @return string locale-specific translation of FALSE - */ - public static function getFALSE() { - return self::$_localeBoolean['FALSE']; - } - - /** - * Set the Array Return Type (Array or Value of first element in the array) - * - * @access public - * @param string $returnType Array return type - * @return boolean Success or failure - */ - public static function setArrayReturnType($returnType) { - if (($returnType == self::RETURN_ARRAY_AS_VALUE) || - ($returnType == self::RETURN_ARRAY_AS_ERROR) || - ($returnType == self::RETURN_ARRAY_AS_ARRAY)) { - self::$returnArrayAsType = $returnType; - return TRUE; - } - return FALSE; - } // function setArrayReturnType() - - - /** - * Return the Array Return Type (Array or Value of first element in the array) - * - * @access public - * @return string $returnType Array return type - */ - public static function getArrayReturnType() { - return self::$returnArrayAsType; - } // function getArrayReturnType() - - - /** - * Is calculation caching enabled? - * - * @access public - * @return boolean - */ - public function getCalculationCacheEnabled() { - return $this->_calculationCacheEnabled; - } // function getCalculationCacheEnabled() - - /** - * Enable/disable calculation cache - * - * @access public - * @param boolean $pValue - */ - public function setCalculationCacheEnabled($pValue = TRUE) { - $this->_calculationCacheEnabled = $pValue; - $this->clearCalculationCache(); - } // function setCalculationCacheEnabled() - - - /** - * Enable calculation cache - */ - public function enableCalculationCache() { - $this->setCalculationCacheEnabled(TRUE); - } // function enableCalculationCache() - - - /** - * Disable calculation cache - */ - public function disableCalculationCache() { - $this->setCalculationCacheEnabled(FALSE); - } // function disableCalculationCache() - - - /** - * Clear calculation cache - */ - public function clearCalculationCache() { - $this->_calculationCache = array(); - } // function clearCalculationCache() - - /** - * Clear calculation cache for a specified worksheet - * - * @param string $worksheetName - */ - public function clearCalculationCacheForWorksheet($worksheetName) { - if (isset($this->_calculationCache[$worksheetName])) { - unset($this->_calculationCache[$worksheetName]); - } - } // function clearCalculationCacheForWorksheet() - - /** - * Rename calculation cache for a specified worksheet - * - * @param string $fromWorksheetName - * @param string $toWorksheetName - */ - public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) { - if (isset($this->_calculationCache[$fromWorksheetName])) { - $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName]; - unset($this->_calculationCache[$fromWorksheetName]); - } - } // function renameCalculationCacheForWorksheet() - - - /** - * Get the currently defined locale code - * - * @return string - */ - public function getLocale() { - return self::$_localeLanguage; - } // function getLocale() - - - /** - * Set the locale code - * - * @param string $locale The locale to use for formula translation - * @return boolean - */ - public function setLocale($locale = 'en_us') { - // Identify our locale and language - $language = $locale = strtolower($locale); - if (strpos($locale,'_') !== FALSE) { - list($language) = explode('_',$locale); - } - - if (count(self::$_validLocaleLanguages) == 1) - self::_loadLocales(); - - // Test whether we have any language data for this language (any locale) - if (in_array($language,self::$_validLocaleLanguages)) { - // initialise language/locale settings - self::$_localeFunctions = array(); - self::$_localeArgumentSeparator = ','; - self::$_localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL'); - // Default is English, if user isn't requesting english, then read the necessary data from the locale files - if ($locale != 'en_us') { - // Search for a file with a list of function names for locale - $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions'; - if (!file_exists($functionNamesFile)) { - // If there isn't a locale specific function file, look for a language specific function file - $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions'; - if (!file_exists($functionNamesFile)) { - return FALSE; - } - } - // Retrieve the list of locale or language specific function names - $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); - foreach ($localeFunctions as $localeFunction) { - list($localeFunction) = explode('##',$localeFunction); // Strip out comments - if (strpos($localeFunction,'=') !== FALSE) { - list($fName,$lfName) = explode('=',$localeFunction); - $fName = trim($fName); - $lfName = trim($lfName); - if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { - self::$_localeFunctions[$fName] = $lfName; - } - } - } - // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions - if (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; } - if (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; } - - $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config'; - if (!file_exists($configFile)) { - $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config'; - } - if (file_exists($configFile)) { - $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); - foreach ($localeSettings as $localeSetting) { - list($localeSetting) = explode('##',$localeSetting); // Strip out comments - if (strpos($localeSetting,'=') !== FALSE) { - list($settingName,$settingValue) = explode('=',$localeSetting); - $settingName = strtoupper(trim($settingName)); - switch ($settingName) { - case 'ARGUMENTSEPARATOR' : - self::$_localeArgumentSeparator = trim($settingValue); - break; - } - } - } - } - } - - self::$functionReplaceFromExcel = self::$functionReplaceToExcel = - self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL; - self::$_localeLanguage = $locale; - return TRUE; - } - return FALSE; - } // function setLocale() - - - - public static function _translateSeparator($fromSeparator,$toSeparator,$formula,&$inBraces) { - $strlen = mb_strlen($formula); - for ($i = 0; $i < $strlen; ++$i) { - $chr = mb_substr($formula,$i,1); - switch ($chr) { - case '{' : $inBraces = TRUE; - break; - case '}' : $inBraces = FALSE; - break; - case $fromSeparator : - if (!$inBraces) { - $formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1); - } - } - } - return $formula; - } - - private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) { - // Convert any Excel function names to the required language - if (self::$_localeLanguage !== 'en_us') { - $inBraces = FALSE; - // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators - if (strpos($formula,'"') !== FALSE) { - // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded - // the formula - $temp = explode('"',$formula); - $i = FALSE; - foreach($temp as &$value) { - // Only count/replace in alternating array entries - if ($i = !$i) { - $value = preg_replace($from,$to,$value); - $value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces); - } - } - unset($value); - // Then rebuild the formula string - $formula = implode('"',$temp); - } else { - // If there's no quoted strings, then we do a simple count/replace - $formula = preg_replace($from,$to,$formula); - $formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces); - } - } - - return $formula; - } - - private static $functionReplaceFromExcel = NULL; - private static $functionReplaceToLocale = NULL; - - public function _translateFormulaToLocale($formula) { - if (self::$functionReplaceFromExcel === NULL) { - self::$functionReplaceFromExcel = array(); - foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { - self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui'; - } - foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { - self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; - } - - } - - if (self::$functionReplaceToLocale === NULL) { - self::$functionReplaceToLocale = array(); - foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { - self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2'; - } - foreach(array_values(self::$_localeBoolean) as $localeBoolean) { - self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2'; - } - } - - return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator); - } // function _translateFormulaToLocale() - - - private static $functionReplaceFromLocale = NULL; - private static $functionReplaceToExcel = NULL; - - public function _translateFormulaToEnglish($formula) { - if (self::$functionReplaceFromLocale === NULL) { - self::$functionReplaceFromLocale = array(); - foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { - self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui'; - } - foreach(array_values(self::$_localeBoolean) as $excelBoolean) { - self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; - } - } - - if (self::$functionReplaceToExcel === NULL) { - self::$functionReplaceToExcel = array(); - foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { - self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2'; - } - foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { - self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2'; - } - } - - return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,','); - } // function _translateFormulaToEnglish() - - - public static function _localeFunc($function) { - if (self::$_localeLanguage !== 'en_us') { - $functionName = trim($function,'('); - if (isset(self::$_localeFunctions[$functionName])) { - $brace = ($functionName != $function); - $function = self::$_localeFunctions[$functionName]; - if ($brace) { $function .= '('; } - } - } - return $function; - } - - - - - /** - * Wrap string values in quotes - * - * @param mixed $value - * @return mixed - */ - public static function _wrapResult($value) { - if (is_string($value)) { - // Error values cannot be "wrapped" - if (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) { - // Return Excel errors "as is" - return $value; - } - // Return strings wrapped in quotes - return '"'.$value.'"'; - // Convert numeric errors to NaN error - } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { - return PHPExcel_Calculation_Functions::NaN(); - } - - return $value; - } // function _wrapResult() - - - /** - * Remove quotes used as a wrapper to identify string values - * - * @param mixed $value - * @return mixed - */ - public static function _unwrapResult($value) { - if (is_string($value)) { - if ((isset($value{0})) && ($value{0} == '"') && (substr($value,-1) == '"')) { - return substr($value,1,-1); - } - // Convert numeric errors to NaN error - } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { - return PHPExcel_Calculation_Functions::NaN(); - } - return $value; - } // function _unwrapResult() - - - - - /** - * Calculate cell value (using formula from a cell ID) - * Retained for backward compatibility - * - * @access public - * @param PHPExcel_Cell $pCell Cell to calculate - * @return mixed - * @throws PHPExcel_Calculation_Exception - */ - public function calculate(PHPExcel_Cell $pCell = NULL) { - try { - return $this->calculateCellValue($pCell); - } catch (PHPExcel_Exception $e) { - throw new PHPExcel_Calculation_Exception($e->getMessage()); - } - } // function calculate() - - - /** - * Calculate the value of a cell formula - * - * @access public - * @param PHPExcel_Cell $pCell Cell to calculate - * @param Boolean $resetLog Flag indicating whether the debug log should be reset or not - * @return mixed - * @throws PHPExcel_Calculation_Exception - */ - public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) { - if ($pCell === NULL) { - return NULL; - } - - $returnArrayAsType = self::$returnArrayAsType; - if ($resetLog) { - // Initialise the logging settings if requested - $this->formulaError = null; - $this->_debugLog->clearLog(); - $this->_cyclicReferenceStack->clear(); - $this->_cyclicFormulaCount = 1; - - self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; - } - - // Execute the calculation for the cell formula + /** + * __clone implementation. Cloning should not be allowed in a Singleton! + * + * @access public + * @throws PHPExcel_Calculation_Exception + */ + public final function __clone() { + throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!'); + } // function __clone() + + + /** + * Return the locale-specific translation of TRUE + * + * @access public + * @return string locale-specific translation of TRUE + */ + public static function getTRUE() { + return self::$_localeBoolean['TRUE']; + } + + /** + * Return the locale-specific translation of FALSE + * + * @access public + * @return string locale-specific translation of FALSE + */ + public static function getFALSE() { + return self::$_localeBoolean['FALSE']; + } + + /** + * Set the Array Return Type (Array or Value of first element in the array) + * + * @access public + * @param string $returnType Array return type + * @return boolean Success or failure + */ + public static function setArrayReturnType($returnType) { + if (($returnType == self::RETURN_ARRAY_AS_VALUE) || + ($returnType == self::RETURN_ARRAY_AS_ERROR) || + ($returnType == self::RETURN_ARRAY_AS_ARRAY)) { + self::$returnArrayAsType = $returnType; + return TRUE; + } + return FALSE; + } // function setArrayReturnType() + + + /** + * Return the Array Return Type (Array or Value of first element in the array) + * + * @access public + * @return string $returnType Array return type + */ + public static function getArrayReturnType() { + return self::$returnArrayAsType; + } // function getArrayReturnType() + + + /** + * Is calculation caching enabled? + * + * @access public + * @return boolean + */ + public function getCalculationCacheEnabled() { + return $this->_calculationCacheEnabled; + } // function getCalculationCacheEnabled() + + /** + * Enable/disable calculation cache + * + * @access public + * @param boolean $pValue + */ + public function setCalculationCacheEnabled($pValue = TRUE) { + $this->_calculationCacheEnabled = $pValue; + $this->clearCalculationCache(); + } // function setCalculationCacheEnabled() + + + /** + * Enable calculation cache + */ + public function enableCalculationCache() { + $this->setCalculationCacheEnabled(TRUE); + } // function enableCalculationCache() + + + /** + * Disable calculation cache + */ + public function disableCalculationCache() { + $this->setCalculationCacheEnabled(FALSE); + } // function disableCalculationCache() + + + /** + * Clear calculation cache + */ + public function clearCalculationCache() { + $this->_calculationCache = array(); + } // function clearCalculationCache() + + /** + * Clear calculation cache for a specified worksheet + * + * @param string $worksheetName + */ + public function clearCalculationCacheForWorksheet($worksheetName) { + if (isset($this->_calculationCache[$worksheetName])) { + unset($this->_calculationCache[$worksheetName]); + } + } // function clearCalculationCacheForWorksheet() + + /** + * Rename calculation cache for a specified worksheet + * + * @param string $fromWorksheetName + * @param string $toWorksheetName + */ + public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) { + if (isset($this->_calculationCache[$fromWorksheetName])) { + $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName]; + unset($this->_calculationCache[$fromWorksheetName]); + } + } // function renameCalculationCacheForWorksheet() + + + /** + * Get the currently defined locale code + * + * @return string + */ + public function getLocale() { + return self::$_localeLanguage; + } // function getLocale() + + + /** + * Set the locale code + * + * @param string $locale The locale to use for formula translation + * @return boolean + */ + public function setLocale($locale = 'en_us') { + // Identify our locale and language + $language = $locale = strtolower($locale); + if (strpos($locale,'_') !== FALSE) { + list($language) = explode('_',$locale); + } + + if (count(self::$_validLocaleLanguages) == 1) + self::_loadLocales(); + + // Test whether we have any language data for this language (any locale) + if (in_array($language,self::$_validLocaleLanguages)) { + // initialise language/locale settings + self::$_localeFunctions = array(); + self::$_localeArgumentSeparator = ','; + self::$_localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL'); + // Default is English, if user isn't requesting english, then read the necessary data from the locale files + if ($locale != 'en_us') { + // Search for a file with a list of function names for locale + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions'; + if (!file_exists($functionNamesFile)) { + // If there isn't a locale specific function file, look for a language specific function file + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions'; + if (!file_exists($functionNamesFile)) { + return FALSE; + } + } + // Retrieve the list of locale or language specific function names + $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($localeFunctions as $localeFunction) { + list($localeFunction) = explode('##',$localeFunction); // Strip out comments + if (strpos($localeFunction,'=') !== FALSE) { + list($fName,$lfName) = explode('=',$localeFunction); + $fName = trim($fName); + $lfName = trim($lfName); + if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { + self::$_localeFunctions[$fName] = $lfName; + } + } + } + // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions + if (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; } + if (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; } + + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config'; + if (!file_exists($configFile)) { + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config'; + } + if (file_exists($configFile)) { + $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($localeSettings as $localeSetting) { + list($localeSetting) = explode('##',$localeSetting); // Strip out comments + if (strpos($localeSetting,'=') !== FALSE) { + list($settingName,$settingValue) = explode('=',$localeSetting); + $settingName = strtoupper(trim($settingName)); + switch ($settingName) { + case 'ARGUMENTSEPARATOR' : + self::$_localeArgumentSeparator = trim($settingValue); + break; + } + } + } + } + } + + self::$functionReplaceFromExcel = self::$functionReplaceToExcel = + self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL; + self::$_localeLanguage = $locale; + return TRUE; + } + return FALSE; + } // function setLocale() + + + + public static function _translateSeparator($fromSeparator,$toSeparator,$formula,&$inBraces) { + $strlen = mb_strlen($formula); + for ($i = 0; $i < $strlen; ++$i) { + $chr = mb_substr($formula,$i,1); + switch ($chr) { + case '{' : $inBraces = TRUE; + break; + case '}' : $inBraces = FALSE; + break; + case $fromSeparator : + if (!$inBraces) { + $formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1); + } + } + } + return $formula; + } + + private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) { + // Convert any Excel function names to the required language + if (self::$_localeLanguage !== 'en_us') { + $inBraces = FALSE; + // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators + if (strpos($formula,'"') !== FALSE) { + // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded + // the formula + $temp = explode('"',$formula); + $i = FALSE; + foreach($temp as &$value) { + // Only count/replace in alternating array entries + if ($i = !$i) { + $value = preg_replace($from,$to,$value); + $value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces); + } + } + unset($value); + // Then rebuild the formula string + $formula = implode('"',$temp); + } else { + // If there's no quoted strings, then we do a simple count/replace + $formula = preg_replace($from,$to,$formula); + $formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces); + } + } + + return $formula; + } + + private static $functionReplaceFromExcel = NULL; + private static $functionReplaceToLocale = NULL; + + public function _translateFormulaToLocale($formula) { + if (self::$functionReplaceFromExcel === NULL) { + self::$functionReplaceFromExcel = array(); + foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui'; + } + foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; + } + + } + + if (self::$functionReplaceToLocale === NULL) { + self::$functionReplaceToLocale = array(); + foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2'; + } + foreach(array_values(self::$_localeBoolean) as $localeBoolean) { + self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2'; + } + } + + return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator); + } // function _translateFormulaToLocale() + + + private static $functionReplaceFromLocale = NULL; + private static $functionReplaceToExcel = NULL; + + public function _translateFormulaToEnglish($formula) { + if (self::$functionReplaceFromLocale === NULL) { + self::$functionReplaceFromLocale = array(); + foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui'; + } + foreach(array_values(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; + } + } + + if (self::$functionReplaceToExcel === NULL) { + self::$functionReplaceToExcel = array(); + foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2'; + } + foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2'; + } + } + + return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,','); + } // function _translateFormulaToEnglish() + + + public static function _localeFunc($function) { + if (self::$_localeLanguage !== 'en_us') { + $functionName = trim($function,'('); + if (isset(self::$_localeFunctions[$functionName])) { + $brace = ($functionName != $function); + $function = self::$_localeFunctions[$functionName]; + if ($brace) { $function .= '('; } + } + } + return $function; + } + + + + + /** + * Wrap string values in quotes + * + * @param mixed $value + * @return mixed + */ + public static function _wrapResult($value) { + if (is_string($value)) { + // Error values cannot be "wrapped" + if (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) { + // Return Excel errors "as is" + return $value; + } + // Return strings wrapped in quotes + return '"'.$value.'"'; + // Convert numeric errors to NaN error + } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return $value; + } // function _wrapResult() + + + /** + * Remove quotes used as a wrapper to identify string values + * + * @param mixed $value + * @return mixed + */ + public static function _unwrapResult($value) { + if (is_string($value)) { + if ((isset($value{0})) && ($value{0} == '"') && (substr($value,-1) == '"')) { + return substr($value,1,-1); + } + // Convert numeric errors to NaN error + } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $value; + } // function _unwrapResult() + + + + + /** + * Calculate cell value (using formula from a cell ID) + * Retained for backward compatibility + * + * @access public + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculate(PHPExcel_Cell $pCell = NULL) { + try { + return $this->calculateCellValue($pCell); + } catch (PHPExcel_Exception $e) { + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + } // function calculate() + + + /** + * Calculate the value of a cell formula + * + * @access public + * @param PHPExcel_Cell $pCell Cell to calculate + * @param Boolean $resetLog Flag indicating whether the debug log should be reset or not + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) { + if ($pCell === NULL) { + return NULL; + } + + $returnArrayAsType = self::$returnArrayAsType; + if ($resetLog) { + // Initialise the logging settings if requested + $this->formulaError = null; + $this->_debugLog->clearLog(); + $this->_cyclicReferenceStack->clear(); + $this->_cyclicFormulaCount = 1; + + self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; + } + + // Execute the calculation for the cell formula $this->_cellStack[] = array( 'sheet' => $pCell->getWorksheet()->getTitle(), 'cell' => $pCell->getCoordinate(), ); - try { - $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); + try { + $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); $cellAddress = array_pop($this->_cellStack); $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); - } catch (PHPExcel_Exception $e) { + } catch (PHPExcel_Exception $e) { $cellAddress = array_pop($this->_cellStack); $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); - throw new PHPExcel_Calculation_Exception($e->getMessage()); - } - - if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { - self::$returnArrayAsType = $returnArrayAsType; - $testResult = PHPExcel_Calculation_Functions::flattenArray($result); - if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) { - return PHPExcel_Calculation_Functions::VALUE(); - } - // If there's only a single cell in the array, then we allow it - if (count($testResult) != 1) { - // If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it - $r = array_keys($result); - $r = array_shift($r); - if (!is_numeric($r)) { return PHPExcel_Calculation_Functions::VALUE(); } - if (is_array($result[$r])) { - $c = array_keys($result[$r]); - $c = array_shift($c); - if (!is_numeric($c)) { - return PHPExcel_Calculation_Functions::VALUE(); - } - } - } - $result = array_shift($testResult); - } - self::$returnArrayAsType = $returnArrayAsType; - - - if ($result === NULL) { - return 0; - } elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) { - return PHPExcel_Calculation_Functions::NaN(); - } - return $result; - } // function calculateCellValue( - - - /** - * Validate and parse a formula string - * - * @param string $formula Formula to parse - * @return array - * @throws PHPExcel_Calculation_Exception - */ - public function parseFormula($formula) { - // Basic validation that this is indeed a formula - // We return an empty array if not - $formula = trim($formula); - if ((!isset($formula{0})) || ($formula{0} != '=')) return array(); - $formula = ltrim(substr($formula,1)); - if (!isset($formula{0})) return array(); - - // Parse the formula and return the token stack - return $this->_parseFormula($formula); - } // function parseFormula() - - - /** - * Calculate the value of a formula - * - * @param string $formula Formula to parse - * @param string $cellID Address of the cell to calculate - * @param PHPExcel_Cell $pCell Cell to calculate - * @return mixed - * @throws PHPExcel_Calculation_Exception - */ - public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) { - // Initialise the logging settings - $this->formulaError = null; - $this->_debugLog->clearLog(); - $this->_cyclicReferenceStack->clear(); - - // Disable calculation cacheing because it only applies to cell calculations, not straight formulae - // But don't actually flush any cache - $resetCache = $this->getCalculationCacheEnabled(); - $this->_calculationCacheEnabled = FALSE; - // Execute the calculation - try { - $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); - } catch (PHPExcel_Exception $e) { - throw new PHPExcel_Calculation_Exception($e->getMessage()); - } - - // Reset calculation cacheing to its previous state - $this->_calculationCacheEnabled = $resetCache; - - return $result; - } // function calculateFormula() + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + + if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { + self::$returnArrayAsType = $returnArrayAsType; + $testResult = PHPExcel_Calculation_Functions::flattenArray($result); + if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) { + return PHPExcel_Calculation_Functions::VALUE(); + } + // If there's only a single cell in the array, then we allow it + if (count($testResult) != 1) { + // If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it + $r = array_keys($result); + $r = array_shift($r); + if (!is_numeric($r)) { return PHPExcel_Calculation_Functions::VALUE(); } + if (is_array($result[$r])) { + $c = array_keys($result[$r]); + $c = array_shift($c); + if (!is_numeric($c)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + } + $result = array_shift($testResult); + } + self::$returnArrayAsType = $returnArrayAsType; + + + if ($result === NULL) { + return 0; + } elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $result; + } // function calculateCellValue( + + + /** + * Validate and parse a formula string + * + * @param string $formula Formula to parse + * @return array + * @throws PHPExcel_Calculation_Exception + */ + public function parseFormula($formula) { + // Basic validation that this is indeed a formula + // We return an empty array if not + $formula = trim($formula); + if ((!isset($formula{0})) || ($formula{0} != '=')) return array(); + $formula = ltrim(substr($formula,1)); + if (!isset($formula{0})) return array(); + + // Parse the formula and return the token stack + return $this->_parseFormula($formula); + } // function parseFormula() + + + /** + * Calculate the value of a formula + * + * @param string $formula Formula to parse + * @param string $cellID Address of the cell to calculate + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) { + // Initialise the logging settings + $this->formulaError = null; + $this->_debugLog->clearLog(); + $this->_cyclicReferenceStack->clear(); + + // Disable calculation cacheing because it only applies to cell calculations, not straight formulae + // But don't actually flush any cache + $resetCache = $this->getCalculationCacheEnabled(); + $this->_calculationCacheEnabled = FALSE; + // Execute the calculation + try { + $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); + } catch (PHPExcel_Exception $e) { + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + + // Reset calculation cacheing to its previous state + $this->_calculationCacheEnabled = $resetCache; + + return $result; + } // function calculateFormula() public function getValueFromCache($cellReference, &$cellValue) { - // Is calculation cacheing enabled? - // Is the value present in calculation 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[$cellReference]; - return TRUE; - } - return FALSE; + // Is calculation cacheing enabled? + // Is the value present in calculation 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[$cellReference]; + return TRUE; + } + return FALSE; } public function saveValueToCache($cellReference, $cellValue) { - if ($this->_calculationCacheEnabled) { - $this->_calculationCache[$cellReference] = $cellValue; - } - } - - /** - * Parse a cell formula and calculate its value - * - * @param string $formula The formula to parse and calculate - * @param string $cellID The ID (e.g. A3) of the cell that we are calculating - * @param PHPExcel_Cell $pCell Cell to calculate - * @return mixed - * @throws PHPExcel_Calculation_Exception - */ - public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) { - $cellValue = null; - - // Basic validation that this is indeed a formula - // We simply return the cell value if not - $formula = trim($formula); - if ($formula{0} != '=') return self::_wrapResult($formula); - $formula = ltrim(substr($formula, 1)); - if (!isset($formula{0})) return self::_wrapResult($formula); - - $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; - $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; + if ($this->_calculationCacheEnabled) { + $this->_calculationCache[$cellReference] = $cellValue; + } + } + + /** + * Parse a cell formula and calculate its value + * + * @param string $formula The formula to parse and calculate + * @param string $cellID The ID (e.g. A3) of the cell that we are calculating + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) { + $cellValue = null; + + // Basic validation that this is indeed a formula + // We simply return the cell value if not + $formula = trim($formula); + if ($formula{0} != '=') return self::_wrapResult($formula); + $formula = ltrim(substr($formula, 1)); + if (!isset($formula{0})) return self::_wrapResult($formula); + + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; $wsCellReference = $wsTitle . '!' . $cellID; - if (($cellID !== NULL) && ($this->getValueFromCache($wsCellReference, $cellValue))) { - return $cellValue; - } + if (($cellID !== NULL) && ($this->getValueFromCache($wsCellReference, $cellValue))) { + return $cellValue; + } - if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsCellReference))) { + if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsCellReference))) { if ($this->cyclicFormulaCount <= 0) { $this->_cyclicFormulaCell = ''; - return $this->_raiseFormulaError('Cyclic Reference in Formula'); - } elseif ($this->_cyclicFormulaCell === $wsCellReference) { - ++$this->_cyclicFormulaCount; - if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { + return $this->_raiseFormulaError('Cyclic Reference in Formula'); + } elseif ($this->_cyclicFormulaCell === $wsCellReference) { + ++$this->_cyclicFormulaCount; + if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { $this->_cyclicFormulaCell = ''; - return $cellValue; - } - } elseif ($this->_cyclicFormulaCell == '') { - if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { - return $cellValue; - } - $this->_cyclicFormulaCell = $wsCellReference; - } - } - - // Parse the formula onto the token stack and calculate the value - $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($wsCellReference, $cellValue); - } - - // Return the calculated value - return $cellValue; - } // function _calculateFormulaValue() - - - /** - * Ensure that paired matrix operands are both matrices and of the same size - * - * @param mixed &$operand1 First matrix operand - * @param mixed &$operand2 Second matrix operand - * @param integer $resize Flag indicating whether the matrices should be resized to match - * and (if so), whether the smaller dimension should grow or the - * larger should shrink. - * 0 = no resize - * 1 = shrink to fit - * 2 = extend to fit - */ - private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) { - // Examine each of the two operands, and turn them into an array if they aren't one already - // Note that this function should only be called if one or both of the operand is already an array - if (!is_array($operand1)) { - list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2); - $operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1)); - $resize = 0; - } elseif (!is_array($operand2)) { - list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1); - $operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2)); - $resize = 0; - } - - list($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1); - list($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2); - if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { - $resize = 1; - } - - if ($resize == 2) { - // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger - self::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); - } elseif ($resize == 1) { - // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller - self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); - } - return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); - } // function _checkMatrixOperands() - - - /** - * Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0 - * - * @param mixed &$matrix matrix operand - * @return array An array comprising the number of rows, and number of columns - */ - public static function _getMatrixDimensions(&$matrix) { - $matrixRows = count($matrix); - $matrixColumns = 0; - foreach($matrix as $rowKey => $rowValue) { - $matrixColumns = max(count($rowValue),$matrixColumns); - if (!is_array($rowValue)) { - $matrix[$rowKey] = array($rowValue); - } else { - $matrix[$rowKey] = array_values($rowValue); - } - } - $matrix = array_values($matrix); - return array($matrixRows,$matrixColumns); - } // function _getMatrixDimensions() - - - /** - * Ensure that paired matrix operands are both matrices of the same size - * - * @param mixed &$matrix1 First matrix operand - * @param mixed &$matrix2 Second matrix operand - * @param integer $matrix1Rows Row size of first matrix operand - * @param integer $matrix1Columns Column size of first matrix operand - * @param integer $matrix2Rows Row size of second matrix operand - * @param integer $matrix2Columns Column size of second matrix operand - */ - private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { - if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { - if ($matrix2Rows < $matrix1Rows) { - for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { - unset($matrix1[$i]); - } - } - if ($matrix2Columns < $matrix1Columns) { - for ($i = 0; $i < $matrix1Rows; ++$i) { - for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { - unset($matrix1[$i][$j]); - } - } - } - } - - if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { - if ($matrix1Rows < $matrix2Rows) { - for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) { - unset($matrix2[$i]); - } - } - if ($matrix1Columns < $matrix2Columns) { - for ($i = 0; $i < $matrix2Rows; ++$i) { - for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { - unset($matrix2[$i][$j]); - } - } - } - } - } // function _resizeMatricesShrink() - - - /** - * Ensure that paired matrix operands are both matrices of the same size - * - * @param mixed &$matrix1 First matrix operand - * @param mixed &$matrix2 Second matrix operand - * @param integer $matrix1Rows Row size of first matrix operand - * @param integer $matrix1Columns Column size of first matrix operand - * @param integer $matrix2Rows Row size of second matrix operand - * @param integer $matrix2Columns Column size of second matrix operand - */ - private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { - if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { - if ($matrix2Columns < $matrix1Columns) { - for ($i = 0; $i < $matrix2Rows; ++$i) { - $x = $matrix2[$i][$matrix2Columns-1]; - for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { - $matrix2[$i][$j] = $x; - } - } - } - if ($matrix2Rows < $matrix1Rows) { - $x = $matrix2[$matrix2Rows-1]; - for ($i = 0; $i < $matrix1Rows; ++$i) { - $matrix2[$i] = $x; - } - } - } - - if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { - if ($matrix1Columns < $matrix2Columns) { - for ($i = 0; $i < $matrix1Rows; ++$i) { - $x = $matrix1[$i][$matrix1Columns-1]; - for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { - $matrix1[$i][$j] = $x; - } - } - } - if ($matrix1Rows < $matrix2Rows) { - $x = $matrix1[$matrix1Rows-1]; - for ($i = 0; $i < $matrix2Rows; ++$i) { - $matrix1[$i] = $x; - } - } - } - } // function _resizeMatricesExtend() - - - /** - * Format details of an operand for display in the log (based on operand type) - * - * @param mixed $value First matrix operand - * @return mixed - */ - private function _showValue($value) { - if ($this->_debugLog->getWriteDebugLog()) { - $testArray = PHPExcel_Calculation_Functions::flattenArray($value); - if (count($testArray) == 1) { - $value = array_pop($testArray); - } - - if (is_array($value)) { - $returnMatrix = array(); - $pad = $rpad = ', '; - foreach($value as $row) { - if (is_array($row)) { - $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row)); - $rpad = '; '; - } else { - $returnMatrix[] = $this->_showValue($row); - } - } - return '{ '.implode($rpad,$returnMatrix).' }'; - } elseif(is_string($value) && (trim($value,'"') == $value)) { - return '"'.$value.'"'; - } elseif(is_bool($value)) { - return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; - } - } - return PHPExcel_Calculation_Functions::flattenSingleValue($value); - } // function _showValue() - - - /** - * Format type and details of an operand for display in the log (based on operand type) - * - * @param mixed $value First matrix operand - * @return mixed - */ - private function _showTypeDetails($value) { - if ($this->_debugLog->getWriteDebugLog()) { - $testArray = PHPExcel_Calculation_Functions::flattenArray($value); - if (count($testArray) == 1) { - $value = array_pop($testArray); - } - - if ($value === NULL) { - return 'a NULL value'; - } elseif (is_float($value)) { - $typeString = 'a floating point number'; - } elseif(is_int($value)) { - $typeString = 'an integer number'; - } elseif(is_bool($value)) { - $typeString = 'a boolean'; - } elseif(is_array($value)) { - $typeString = 'a matrix'; - } else { - if ($value == '') { - return 'an empty string'; - } elseif ($value{0} == '#') { - return 'a '.$value.' error'; - } else { - $typeString = 'a string'; - } - } - return $typeString.' with a value of '.$this->_showValue($value); - } - } // function _showTypeDetails() - - - private function _convertMatrixReferences($formula) { - static $matrixReplaceFrom = array('{',';','}'); - static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))'); - - // Convert any Excel matrix references to the MKMATRIX() function - if (strpos($formula,'{') !== FALSE) { - // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators - if (strpos($formula,'"') !== FALSE) { - // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded - // the formula - $temp = explode('"',$formula); - // Open and Closed counts used for trapping mismatched braces in the formula - $openCount = $closeCount = 0; - $i = FALSE; - foreach($temp as &$value) { - // Only count/replace in alternating array entries - if ($i = !$i) { - $openCount += substr_count($value,'{'); - $closeCount += substr_count($value,'}'); - $value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value); - } - } - unset($value); - // Then rebuild the formula string - $formula = implode('"',$temp); - } else { - // If there's no quoted strings, then we do a simple count/replace - $openCount = substr_count($formula,'{'); - $closeCount = substr_count($formula,'}'); - $formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula); - } - // Trap for mismatched braces and trigger an appropriate error - if ($openCount < $closeCount) { - if ($openCount > 0) { - return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '}'"); - } else { - return $this->_raiseFormulaError("Formula Error: Unexpected '}' encountered"); - } - } elseif ($openCount > $closeCount) { - if ($closeCount > 0) { - return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '{'"); - } else { - return $this->_raiseFormulaError("Formula Error: Unexpected '{' encountered"); - } - } - } - - return $formula; - } // function _convertMatrixReferences() - - - private static function _mkMatrix() { - return func_get_args(); - } // function _mkMatrix() - - - // Binary Operators - // These operators always work on two values - // Array key is the operator, the value indicates whether this is a left or right associative operator - private static $_operatorAssociativity = array( - '^' => 0, // Exponentiation - '*' => 0, '/' => 0, // Multiplication and Division - '+' => 0, '-' => 0, // Addition and Subtraction - '&' => 0, // Concatenation - '|' => 0, ':' => 0, // Intersect and Range - '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison - ); - - // Comparison (Boolean) Operators - // These operators work on two values, but always return a boolean result - private static $_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE); - - // Operator Precedence - // This list includes all valid operators, whether binary (including boolean) or unary (such as %) - // Array key is the operator, the value is its precedence - private static $_operatorPrecedence = array( - ':' => 8, // Range - '|' => 7, // Intersect - '~' => 6, // Negation - '%' => 5, // Percentage - '^' => 4, // Exponentiation - '*' => 3, '/' => 3, // Multiplication and Division - '+' => 2, '-' => 2, // Addition and Subtraction - '&' => 1, // Concatenation - '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison - ); - - // Convert infix to postfix notation - private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { - if (($formula = $this->_convertMatrixReferences(trim($formula))) === FALSE) { - return FALSE; - } - - // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), - // so we store the parent worksheet so that we can re-attach it when necessary - $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; - - $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION. - '|'.self::CALCULATION_REGEXP_CELLREF. - '|'.self::CALCULATION_REGEXP_NUMBER. - '|'.self::CALCULATION_REGEXP_STRING. - '|'.self::CALCULATION_REGEXP_OPENBRACE. - '|'.self::CALCULATION_REGEXP_NAMEDRANGE. - '|'.self::CALCULATION_REGEXP_ERROR. - ')/si'; - - // Start with initialisation - $index = 0; - $stack = new PHPExcel_Calculation_Token_Stack; - $output = array(); - $expectingOperator = FALSE; // We use this test in syntax-checking the expression to determine when a - // - is a negation or + is a positive operator rather than an operation - $expectingOperand = FALSE; // We use this test in syntax-checking the expression to determine whether an operand - // should be null in a function call - // The guts of the lexical parser - // Loop through the formula extracting each operator and operand in turn - while(TRUE) { + return $cellValue; + } + } elseif ($this->_cyclicFormulaCell == '') { + if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { + return $cellValue; + } + $this->_cyclicFormulaCell = $wsCellReference; + } + } + + // Parse the formula onto the token stack and calculate the value + $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($wsCellReference, $cellValue); + } + + // Return the calculated value + return $cellValue; + } // function _calculateFormulaValue() + + + /** + * Ensure that paired matrix operands are both matrices and of the same size + * + * @param mixed &$operand1 First matrix operand + * @param mixed &$operand2 Second matrix operand + * @param integer $resize Flag indicating whether the matrices should be resized to match + * and (if so), whether the smaller dimension should grow or the + * larger should shrink. + * 0 = no resize + * 1 = shrink to fit + * 2 = extend to fit + */ + private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) { + // Examine each of the two operands, and turn them into an array if they aren't one already + // Note that this function should only be called if one or both of the operand is already an array + if (!is_array($operand1)) { + list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2); + $operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1)); + $resize = 0; + } elseif (!is_array($operand2)) { + list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1); + $operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2)); + $resize = 0; + } + + list($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1); + list($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2); + if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { + $resize = 1; + } + + if ($resize == 2) { + // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger + self::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } elseif ($resize == 1) { + // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller + self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } + return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } // function _checkMatrixOperands() + + + /** + * Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0 + * + * @param mixed &$matrix matrix operand + * @return array An array comprising the number of rows, and number of columns + */ + public static function _getMatrixDimensions(&$matrix) { + $matrixRows = count($matrix); + $matrixColumns = 0; + foreach($matrix as $rowKey => $rowValue) { + $matrixColumns = max(count($rowValue),$matrixColumns); + if (!is_array($rowValue)) { + $matrix[$rowKey] = array($rowValue); + } else { + $matrix[$rowKey] = array_values($rowValue); + } + } + $matrix = array_values($matrix); + return array($matrixRows,$matrixColumns); + } // function _getMatrixDimensions() + + + /** + * Ensure that paired matrix operands are both matrices of the same size + * + * @param mixed &$matrix1 First matrix operand + * @param mixed &$matrix2 Second matrix operand + * @param integer $matrix1Rows Row size of first matrix operand + * @param integer $matrix1Columns Column size of first matrix operand + * @param integer $matrix2Rows Row size of second matrix operand + * @param integer $matrix2Columns Column size of second matrix operand + */ + private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { + if ($matrix2Rows < $matrix1Rows) { + for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { + unset($matrix1[$i]); + } + } + if ($matrix2Columns < $matrix1Columns) { + for ($i = 0; $i < $matrix1Rows; ++$i) { + for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { + unset($matrix1[$i][$j]); + } + } + } + } + + if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { + if ($matrix1Rows < $matrix2Rows) { + for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) { + unset($matrix2[$i]); + } + } + if ($matrix1Columns < $matrix2Columns) { + for ($i = 0; $i < $matrix2Rows; ++$i) { + for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { + unset($matrix2[$i][$j]); + } + } + } + } + } // function _resizeMatricesShrink() + + + /** + * Ensure that paired matrix operands are both matrices of the same size + * + * @param mixed &$matrix1 First matrix operand + * @param mixed &$matrix2 Second matrix operand + * @param integer $matrix1Rows Row size of first matrix operand + * @param integer $matrix1Columns Column size of first matrix operand + * @param integer $matrix2Rows Row size of second matrix operand + * @param integer $matrix2Columns Column size of second matrix operand + */ + private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { + if ($matrix2Columns < $matrix1Columns) { + for ($i = 0; $i < $matrix2Rows; ++$i) { + $x = $matrix2[$i][$matrix2Columns-1]; + for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { + $matrix2[$i][$j] = $x; + } + } + } + if ($matrix2Rows < $matrix1Rows) { + $x = $matrix2[$matrix2Rows-1]; + for ($i = 0; $i < $matrix1Rows; ++$i) { + $matrix2[$i] = $x; + } + } + } + + if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { + if ($matrix1Columns < $matrix2Columns) { + for ($i = 0; $i < $matrix1Rows; ++$i) { + $x = $matrix1[$i][$matrix1Columns-1]; + for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { + $matrix1[$i][$j] = $x; + } + } + } + if ($matrix1Rows < $matrix2Rows) { + $x = $matrix1[$matrix1Rows-1]; + for ($i = 0; $i < $matrix2Rows; ++$i) { + $matrix1[$i] = $x; + } + } + } + } // function _resizeMatricesExtend() + + + /** + * Format details of an operand for display in the log (based on operand type) + * + * @param mixed $value First matrix operand + * @return mixed + */ + private function _showValue($value) { + if ($this->_debugLog->getWriteDebugLog()) { + $testArray = PHPExcel_Calculation_Functions::flattenArray($value); + if (count($testArray) == 1) { + $value = array_pop($testArray); + } + + if (is_array($value)) { + $returnMatrix = array(); + $pad = $rpad = ', '; + foreach($value as $row) { + if (is_array($row)) { + $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row)); + $rpad = '; '; + } else { + $returnMatrix[] = $this->_showValue($row); + } + } + return '{ '.implode($rpad,$returnMatrix).' }'; + } elseif(is_string($value) && (trim($value,'"') == $value)) { + return '"'.$value.'"'; + } elseif(is_bool($value)) { + return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + } + return PHPExcel_Calculation_Functions::flattenSingleValue($value); + } // function _showValue() + + + /** + * Format type and details of an operand for display in the log (based on operand type) + * + * @param mixed $value First matrix operand + * @return mixed + */ + private function _showTypeDetails($value) { + if ($this->_debugLog->getWriteDebugLog()) { + $testArray = PHPExcel_Calculation_Functions::flattenArray($value); + if (count($testArray) == 1) { + $value = array_pop($testArray); + } + + if ($value === NULL) { + return 'a NULL value'; + } elseif (is_float($value)) { + $typeString = 'a floating point number'; + } elseif(is_int($value)) { + $typeString = 'an integer number'; + } elseif(is_bool($value)) { + $typeString = 'a boolean'; + } elseif(is_array($value)) { + $typeString = 'a matrix'; + } else { + if ($value == '') { + return 'an empty string'; + } elseif ($value{0} == '#') { + return 'a '.$value.' error'; + } else { + $typeString = 'a string'; + } + } + return $typeString.' with a value of '.$this->_showValue($value); + } + } // function _showTypeDetails() + + + private function _convertMatrixReferences($formula) { + static $matrixReplaceFrom = array('{',';','}'); + static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))'); + + // Convert any Excel matrix references to the MKMATRIX() function + if (strpos($formula,'{') !== FALSE) { + // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators + if (strpos($formula,'"') !== FALSE) { + // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded + // the formula + $temp = explode('"',$formula); + // Open and Closed counts used for trapping mismatched braces in the formula + $openCount = $closeCount = 0; + $i = FALSE; + foreach($temp as &$value) { + // Only count/replace in alternating array entries + if ($i = !$i) { + $openCount += substr_count($value,'{'); + $closeCount += substr_count($value,'}'); + $value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value); + } + } + unset($value); + // Then rebuild the formula string + $formula = implode('"',$temp); + } else { + // If there's no quoted strings, then we do a simple count/replace + $openCount = substr_count($formula,'{'); + $closeCount = substr_count($formula,'}'); + $formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula); + } + // Trap for mismatched braces and trigger an appropriate error + if ($openCount < $closeCount) { + if ($openCount > 0) { + return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '}'"); + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected '}' encountered"); + } + } elseif ($openCount > $closeCount) { + if ($closeCount > 0) { + return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '{'"); + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected '{' encountered"); + } + } + } + + return $formula; + } // function _convertMatrixReferences() + + + private static function _mkMatrix() { + return func_get_args(); + } // function _mkMatrix() + + + // Binary Operators + // These operators always work on two values + // Array key is the operator, the value indicates whether this is a left or right associative operator + private static $_operatorAssociativity = array( + '^' => 0, // Exponentiation + '*' => 0, '/' => 0, // Multiplication and Division + '+' => 0, '-' => 0, // Addition and Subtraction + '&' => 0, // Concatenation + '|' => 0, ':' => 0, // Intersect and Range + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison + ); + + // Comparison (Boolean) Operators + // These operators work on two values, but always return a boolean result + private static $_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE); + + // Operator Precedence + // This list includes all valid operators, whether binary (including boolean) or unary (such as %) + // Array key is the operator, the value is its precedence + private static $_operatorPrecedence = array( + ':' => 8, // Range + '|' => 7, // Intersect + '~' => 6, // Negation + '%' => 5, // Percentage + '^' => 4, // Exponentiation + '*' => 3, '/' => 3, // Multiplication and Division + '+' => 2, '-' => 2, // Addition and Subtraction + '&' => 1, // Concatenation + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison + ); + + // Convert infix to postfix notation + private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { + if (($formula = $this->_convertMatrixReferences(trim($formula))) === FALSE) { + return FALSE; + } + + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), + // so we store the parent worksheet so that we can re-attach it when necessary + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + + $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION. + '|'.self::CALCULATION_REGEXP_CELLREF. + '|'.self::CALCULATION_REGEXP_NUMBER. + '|'.self::CALCULATION_REGEXP_STRING. + '|'.self::CALCULATION_REGEXP_OPENBRACE. + '|'.self::CALCULATION_REGEXP_NAMEDRANGE. + '|'.self::CALCULATION_REGEXP_ERROR. + ')/si'; + + // Start with initialisation + $index = 0; + $stack = new PHPExcel_Calculation_Token_Stack; + $output = array(); + $expectingOperator = FALSE; // We use this test in syntax-checking the expression to determine when a + // - is a negation or + is a positive operator rather than an operation + $expectingOperand = FALSE; // We use this test in syntax-checking the expression to determine whether an operand + // should be null in a function call + // The guts of the lexical parser + // Loop through the formula extracting each operator and operand in turn + while(TRUE) { //echo 'Assessing Expression '.substr($formula, $index),PHP_EOL; - $opCharacter = $formula{$index}; // Get the first character of the value at the current index position + $opCharacter = $formula{$index}; // Get the first character of the value at the current index position //echo 'Initial character of expression block is '.$opCharacter,PHP_EOL; - if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) { - $opCharacter .= $formula{++$index}; + if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) { + $opCharacter .= $formula{++$index}; //echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL; - } + } - // Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand - $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match); + // Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand + $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match); //echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').PHP_EOL; //var_dump($match); - if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus? + if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus? //echo 'Element is a Negation operator',PHP_EOL; - $stack->push('Unary Operator','~'); // Put a negation on the stack - ++$index; // and drop the negation symbol - } elseif ($opCharacter == '%' && $expectingOperator) { + $stack->push('Unary Operator','~'); // Put a negation on the stack + ++$index; // and drop the negation symbol + } elseif ($opCharacter == '%' && $expectingOperator) { //echo 'Element is a Percentage operator',PHP_EOL; - $stack->push('Unary Operator','%'); // Put a percentage on the stack - ++$index; - } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded? + $stack->push('Unary Operator','%'); // Put a percentage on the stack + ++$index; + } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded? //echo 'Element is a Positive number, not Plus operator',PHP_EOL; - ++$index; // Drop the redundant plus symbol - } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal - return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression + ++$index; // Drop the redundant plus symbol + } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal + return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression - } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? + } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? //echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL; - while($stack->count() > 0 && - ($o2 = $stack->last()) && - isset(self::$_operators[$o2['value']]) && - @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { - $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output - } - $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack - ++$index; - $expectingOperator = FALSE; - - } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis? + while($stack->count() > 0 && + ($o2 = $stack->last()) && + isset(self::$_operators[$o2['value']]) && + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { + $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output + } + $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack + ++$index; + $expectingOperator = FALSE; + + } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis? //echo 'Element is a Closing bracket',PHP_EOL; - $expectingOperand = FALSE; - while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( - if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"'); - else $output[] = $o2; - } - $d = $stack->last(2); - if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function? - $functionName = $matches[1]; // Get the function name + $expectingOperand = FALSE; + while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( + if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"'); + else $output[] = $o2; + } + $d = $stack->last(2); + if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function? + $functionName = $matches[1]; // Get the function name //echo 'Closed Function is '.$functionName,PHP_EOL; - $d = $stack->pop(); - $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack) + $d = $stack->pop(); + $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack) //if ($argumentCount == 0) { -// echo 'With no arguments',PHP_EOL; +// echo 'With no arguments',PHP_EOL; //} elseif ($argumentCount == 1) { -// echo 'With 1 argument',PHP_EOL; +// echo 'With 1 argument',PHP_EOL; //} else { -// echo 'With '.$argumentCount.' arguments',PHP_EOL; +// echo 'With '.$argumentCount.' arguments',PHP_EOL; //} - $output[] = $d; // Dump the argument count on the output - $output[] = $stack->pop(); // Pop the function and push onto the output - if (isset(self::$_controlFunctions[$functionName])) { + $output[] = $d; // Dump the argument count on the output + $output[] = $stack->pop(); // Pop the function and push onto the output + if (isset(self::$_controlFunctions[$functionName])) { //echo 'Built-in function '.$functionName,PHP_EOL; - $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount']; - $functionCall = self::$_controlFunctions[$functionName]['functionCall']; - } elseif (isset(self::$_PHPExcelFunctions[$functionName])) { + $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount']; + $functionCall = self::$_controlFunctions[$functionName]['functionCall']; + } elseif (isset(self::$_PHPExcelFunctions[$functionName])) { //echo 'PHPExcel function '.$functionName,PHP_EOL; - $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount']; - $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; - } else { // did we somehow push a non-function on the stack? this should never happen - return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack"); - } - // Check the argument count - $argumentCountError = FALSE; - if (is_numeric($expectedArgumentCount)) { - if ($expectedArgumentCount < 0) { + $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount']; + $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; + } else { // did we somehow push a non-function on the stack? this should never happen + return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack"); + } + // Check the argument count + $argumentCountError = FALSE; + if (is_numeric($expectedArgumentCount)) { + if ($expectedArgumentCount < 0) { //echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount),PHP_EOL; - if ($argumentCount > abs($expectedArgumentCount)) { - $argumentCountError = TRUE; - $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount); - } - } else { + if ($argumentCount > abs($expectedArgumentCount)) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount); + } + } else { //echo '$expectedArgumentCount is numeric '.$expectedArgumentCount,PHP_EOL; - if ($argumentCount != $expectedArgumentCount) { - $argumentCountError = TRUE; - $expectedArgumentCountString = $expectedArgumentCount; - } - } - } elseif ($expectedArgumentCount != '*') { - $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch); + if ($argumentCount != $expectedArgumentCount) { + $argumentCountError = TRUE; + $expectedArgumentCountString = $expectedArgumentCount; + } + } + } elseif ($expectedArgumentCount != '*') { + $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch); //print_r($argMatch); //echo PHP_EOL; - switch ($argMatch[2]) { - case '+' : - if ($argumentCount < $argMatch[1]) { - $argumentCountError = TRUE; - $expectedArgumentCountString = $argMatch[1].' or more '; - } - break; - case '-' : - if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) { - $argumentCountError = TRUE; - $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3]; - } - break; - case ',' : - if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) { - $argumentCountError = TRUE; - $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3]; - } - break; - } - } - if ($argumentCountError) { - return $this->_raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected"); - } - } - ++$index; - - } elseif ($opCharacter == ',') { // Is this the separator for function arguments? + switch ($argMatch[2]) { + case '+' : + if ($argumentCount < $argMatch[1]) { + $argumentCountError = TRUE; + $expectedArgumentCountString = $argMatch[1].' or more '; + } + break; + case '-' : + if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3]; + } + break; + case ',' : + if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3]; + } + break; + } + } + if ($argumentCountError) { + return $this->_raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected"); + } + } + ++$index; + + } elseif ($opCharacter == ',') { // Is this the separator for function arguments? //echo 'Element is a Function argument separator',PHP_EOL; - while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( - if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,"); - else $output[] = $o2; // pop the argument expression stuff and push onto the output - } - // If we've a comma when we're expecting an operand, then what we actually have is a null operand; - // so push a null onto the stack - if (($expectingOperand) || (!$expectingOperator)) { - $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); - } - // make sure there was a function - $d = $stack->last(2); - if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) - return $this->_raiseFormulaError("Formula Error: Unexpected ,"); - $d = $stack->pop(); - $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count - $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again - $expectingOperator = FALSE; - $expectingOperand = TRUE; - ++$index; - - } elseif ($opCharacter == '(' && !$expectingOperator) { -// echo 'Element is an Opening Bracket<br />'; - $stack->push('Brace', '('); - ++$index; - - } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number? - $expectingOperator = TRUE; - $expectingOperand = FALSE; - $val = $match[1]; - $length = strlen($val); -// echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />'; - - if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { - $val = preg_replace('/\s/u','',$val); -// echo 'Element '.$val.' is a Function<br />'; - if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function - $stack->push('Function', strtoupper($val)); - $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch); - if ($ax) { - $stack->push('Operand Count for Function '.strtoupper($val).')', 0); - $expectingOperator = TRUE; - } else { - $stack->push('Operand Count for Function '.strtoupper($val).')', 1); - $expectingOperator = FALSE; - } - $stack->push('Brace', '('); - } else { // it's a var w/ implicit multiplication - $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL); - } - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) { -// echo 'Element '.$val.' is a Cell reference<br />'; - // Watch for this case-change when modifying to allow cell references in different worksheets... - // Should only be applied to the actual cell column, not the worksheet name - - // If the last entry on the stack was a : operator, then we have a cell range reference - $testPrevOp = $stack->last(1); - if ($testPrevOp['value'] == ':') { - // If we have a worksheet reference, then we're playing with a 3D reference - if ($matches[2] == '') { - // Otherwise, we 'inherit' the worksheet reference from the start cell reference - // The start of the cell range reference should be the last entry in $output - $startCellRef = $output[count($output)-1]['value']; - preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches); - if ($startMatches[2] > '') { - $val = $startMatches[2].'!'.$val; - } - } else { - return $this->_raiseFormulaError("3D Range references are not yet supported"); - } - } - - $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val); -// $expectingOperator = FALSE; - } else { // it's a variable, constant, string, number or boolean -// echo 'Element is a Variable, Constant, String, Number or Boolean<br />'; - // If the last entry on the stack was a : operator, then we may have a row or column range reference - $testPrevOp = $stack->last(1); - if ($testPrevOp['value'] == ':') { - $startRowColRef = $output[count($output)-1]['value']; - $rangeWS1 = ''; - if (strpos('!',$startRowColRef) !== FALSE) { - list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef); - } - if ($rangeWS1 != '') $rangeWS1 .= '!'; - $rangeWS2 = $rangeWS1; - if (strpos('!',$val) !== FALSE) { - list($rangeWS2,$val) = explode('!',$val); - } - if ($rangeWS2 != '') $rangeWS2 .= '!'; - if ((is_integer($startRowColRef)) && (ctype_digit($val)) && - ($startRowColRef <= 1048576) && ($val <= 1048576)) { - // Row range - $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007 - $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef; - $val = $rangeWS2.$endRowColRef.$val; - } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) && - (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) { - // Column range - $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007 - $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1'; - $val = $rangeWS2.$val.$endRowColRef; - } - } - - $localeConstant = FALSE; - if ($opCharacter == '"') { -// echo 'Element is a String<br />'; - // UnEscape any quotes within the string - $val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val))); - } elseif (is_numeric($val)) { -// echo 'Element is a Number<br />'; - if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { -// echo 'Casting '.$val.' to float<br />'; - $val = (float) $val; - } else { -// echo 'Casting '.$val.' to integer<br />'; - $val = (integer) $val; - } - } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) { - $excelConstant = trim(strtoupper($val)); -// echo 'Element '.$excelConstant.' is an Excel Constant<br />'; - $val = self::$_ExcelConstants[$excelConstant]; - } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) { -// echo 'Element '.$localeConstant.' is an Excel Constant<br />'; - $val = self::$_ExcelConstants[$localeConstant]; - } - $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL); - if ($localeConstant) { $details['localeValue'] = $localeConstant; } - $output[] = $details; - } - $index += $length; - - } elseif ($opCharacter == '$') { // absolute row or column range - ++$index; - } elseif ($opCharacter == ')') { // miscellaneous error checking - if ($expectingOperand) { - $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); - $expectingOperand = FALSE; - $expectingOperator = TRUE; - } else { - return $this->_raiseFormulaError("Formula Error: Unexpected ')'"); - } - } elseif (isset(self::$_operators[$opCharacter]) && !$expectingOperator) { - return $this->_raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'"); - } else { // I don't even want to know what you did to get here - return $this->_raiseFormulaError("Formula Error: An unexpected error occured"); - } - // Test for end of formula string - if ($index == strlen($formula)) { - // Did we end with an operator?. - // Only valid for the % unary operator - if ((isset(self::$_operators[$opCharacter])) && ($opCharacter != '%')) { - return $this->_raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands"); - } else { - break; - } - } - // Ignore white space - while (($formula{$index} == "\n") || ($formula{$index} == "\r")) { - ++$index; - } - if ($formula{$index} == ' ') { - while ($formula{$index} == ' ') { - ++$index; - } - // If we're expecting an operator, but only have a space between the previous and next operands (and both are - // Cell References) then we have an INTERSECTION operator -// echo 'Possible Intersect Operator<br />'; - if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) && - ($output[count($output)-1]['type'] == 'Cell Reference')) { -// echo 'Element is an Intersect Operator<br />'; - while($stack->count() > 0 && - ($o2 = $stack->last()) && - isset(self::$_operators[$o2['value']]) && - @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { - $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output - } - $stack->push('Binary Operator','|'); // Put an Intersect Operator on the stack - $expectingOperator = FALSE; - } - } - } - - while (($op = $stack->pop()) !== NULL) { // pop everything off the stack and push onto output - if ((is_array($op) && $op['value'] == '(') || ($op === '(')) - return $this->_raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced - $output[] = $op; - } - return $output; - } // function _parseFormula() - - - private static function _dataTestReference(&$operandData) - { - $operand = $operandData['value']; - if (($operandData['reference'] === NULL) && (is_array($operand))) { - $rKeys = array_keys($operand); - $rowKey = array_shift($rKeys); - $cKeys = array_keys(array_keys($operand[$rowKey])); - $colKey = array_shift($cKeys); - if (ctype_upper($colKey)) { - $operandData['reference'] = $colKey.$rowKey; - } - } - return $operand; - } - - // evaluate postfix notation - private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) { - if ($tokens == FALSE) return FALSE; - - // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection), - // so we store the parent cell collection so that we can re-attach it when necessary - $pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; - $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null; - $stack = new PHPExcel_Calculation_Token_Stack; - - // Loop through each token in turn - foreach ($tokens as $tokenData) { -// print_r($tokenData); -// echo '<br />'; - $token = $tokenData['value']; -// echo '<b>Token is '.$token.'</b><br />'; - // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack - if (isset(self::$_binaryOperators[$token])) { -// echo 'Token is a binary operator<br />'; - // We must have two operands, error if we don't - if (($operand2Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); - if (($operand1Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); - - $operand1 = self::_dataTestReference($operand1Data); - $operand2 = self::_dataTestReference($operand2Data); - - // Log what we're doing - if ($token == ':') { - $this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); - } else { - $this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); - } - - // Process the operation in the appropriate manner - switch ($token) { - // Comparison (Boolean) Operators - case '>' : // Greater than - case '<' : // Less than - case '>=' : // Greater than or Equal to - case '<=' : // Less than or Equal to - case '=' : // Equality - case '<>' : // Inequality - $this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack); - break; - // Binary Operators - case ':' : // Range - $sheet1 = $sheet2 = ''; - if (strpos($operand1Data['reference'],'!') !== FALSE) { - list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']); - } else { - $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : ''; - } - if (strpos($operand2Data['reference'],'!') !== FALSE) { - list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']); - } else { - $sheet2 = $sheet1; - } - if ($sheet1 == $sheet2) { - if ($operand1Data['reference'] === NULL) { - if ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) { - $operand1Data['reference'] = $pCell->getColumn().$operand1Data['value']; - } elseif (trim($operand1Data['reference']) == '') { - $operand1Data['reference'] = $pCell->getCoordinate(); - } else { - $operand1Data['reference'] = $operand1Data['value'].$pCell->getRow(); - } - } - if ($operand2Data['reference'] === NULL) { - if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) { - $operand2Data['reference'] = $pCell->getColumn().$operand2Data['value']; - } elseif (trim($operand2Data['reference']) == '') { - $operand2Data['reference'] = $pCell->getCoordinate(); - } else { - $operand2Data['reference'] = $operand2Data['value'].$pCell->getRow(); - } - } - - $oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference'])); - $oCol = $oRow = array(); - foreach($oData as $oDatum) { - $oCR = PHPExcel_Cell::coordinateFromString($oDatum); - $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1; - $oRow[] = $oCR[1]; - } - $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); - if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE); - } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); - } - $stack->push('Cell Reference',$cellValue,$cellRef); - } else { - $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL); - } - - break; - case '+' : // Addition - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack); - break; - case '-' : // Subtraction - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack); - break; - case '*' : // Multiplication - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack); - break; - case '/' : // Division - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack); - break; - case '^' : // Exponential - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack); - break; - case '&' : // Concatenation - // If either of the operands is a matrix, we need to treat them both as matrices - // (converting the other operand to a matrix if need be); then perform the required - // matrix operation - if (is_bool($operand1)) { - $operand1 = ($operand1) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; - } - if (is_bool($operand2)) { - $operand2 = ($operand2) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; - } - if ((is_array($operand1)) || (is_array($operand2))) { - // Ensure that both operands are arrays/matrices - self::_checkMatrixOperands($operand1,$operand2,2); - try { - // Convert operand 1 from a PHP array to a matrix - $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); - // Perform the required operation against the operand 1 matrix, passing in operand 2 - $matrixResult = $matrix->concat($operand2); - $result = $matrixResult->getArray(); - } catch (PHPExcel_Exception $ex) { - $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); - $result = '#VALUE!'; - } - } else { - $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"'; - } - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - $stack->push('Value',$result); - break; - case '|' : // Intersect - $rowIntersect = array_intersect_key($operand1,$operand2); - $cellIntersect = $oCol = $oRow = array(); - foreach(array_keys($rowIntersect) as $row) { - $oRow[] = $row; - foreach($rowIntersect[$row] as $col => $data) { - $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1; - $cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]); - } - } - $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); - $stack->push('Value',$cellIntersect,$cellRef); - break; - } - - // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on - } elseif (($token === '~') || ($token === '%')) { -// echo 'Token is a unary operator<br />'; - if (($arg = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); - $arg = $arg['value']; - if ($token === '~') { -// echo 'Token is a negation operator<br />'; - $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg)); - $multiplier = -1; - } else { -// echo 'Token is a percentile operator<br />'; - $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg)); - $multiplier = 0.01; - } - if (is_array($arg)) { - self::_checkMatrixOperands($arg,$multiplier,2); - try { - $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg); - $matrixResult = $matrix1->arrayTimesEquals($multiplier); - $result = $matrixResult->getArray(); - } catch (PHPExcel_Exception $ex) { - $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); - $result = '#VALUE!'; - } - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - $stack->push('Value',$result); - } else { - $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack); - } - - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { - $cellRef = NULL; -// echo 'Element '.$token.' is a Cell reference<br />'; - if (isset($matches[8])) { -// echo 'Reference is a Range of cells<br />'; - if ($pCell === NULL) { -// We can't access the range, so return a REF error - $cellValue = PHPExcel_Calculation_Functions::REF(); - } else { - $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10]; - if ($matches[2] > '') { - $matches[2] = trim($matches[2],"\"'"); - if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { - // It's a Reference to an external workbook (not currently supported) - return $this->_raiseFormulaError('Unable to access External Workbook'); - } - $matches[2] = trim($matches[2],"\"'"); -// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; - $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); - if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); - } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); - } - $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); -// $cellRef = $matches[2].'!'.$cellRef; - } else { -// echo '$cellRef='.$cellRef.' in current worksheet<br />'; - $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet'); - if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); - } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); - } - $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); - } - } - } else { -// echo 'Reference is a single Cell<br />'; - if ($pCell === NULL) { -// We can't access the cell, so return a REF error - $cellValue = PHPExcel_Calculation_Functions::REF(); - } else { - $cellRef = $matches[6].$matches[7]; - if ($matches[2] > '') { - $matches[2] = trim($matches[2],"\"'"); - if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { - // It's a Reference to an external workbook (not currently supported) - return $this->_raiseFormulaError('Unable to access External Workbook'); - } -// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; - $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); - if ($pCellParent !== NULL) { - $cellSheet = $this->_workbook->getSheetByName($matches[2]); - if ($cellSheet && $cellSheet->cellExists($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); - $pCell->attach($pCellParent); - } else { - $cellValue = NULL; - } - } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); - } - $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); -// $cellRef = $matches[2].'!'.$cellRef; - } else { -// echo '$cellRef='.$cellRef.' in current worksheet<br />'; - $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet'); - if ($pCellParent->isDataSet($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); - $pCell->attach($pCellParent); - } else { - $cellValue = NULL; - } - $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); - } - } - } - $stack->push('Value',$cellValue,$cellRef); - - // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) { -// echo 'Token is a function<br />'; - $functionName = $matches[1]; - $argCount = $stack->pop(); - $argCount = $argCount['value']; - if ($functionName != 'MKMATRIX') { - $this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); - } - if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function - if (isset(self::$_PHPExcelFunctions[$functionName])) { - $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; - $passByReference = isset(self::$_PHPExcelFunctions[$functionName]['passByReference']); - $passCellReference = isset(self::$_PHPExcelFunctions[$functionName]['passCellReference']); - } elseif (isset(self::$_controlFunctions[$functionName])) { - $functionCall = self::$_controlFunctions[$functionName]['functionCall']; - $passByReference = isset(self::$_controlFunctions[$functionName]['passByReference']); - $passCellReference = isset(self::$_controlFunctions[$functionName]['passCellReference']); - } - // get the arguments for this function -// echo 'Function '.$functionName.' expects '.$argCount.' arguments<br />'; - $args = $argArrayVals = array(); - for ($i = 0; $i < $argCount; ++$i) { - $arg = $stack->pop(); - $a = $argCount - $i - 1; - if (($passByReference) && - (isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) && - (self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) { - if ($arg['reference'] === NULL) { - $args[] = $cellID; - if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($cellID); } - } else { - $args[] = $arg['reference']; - if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['reference']); } - } - } else { - $args[] = self::_unwrapResult($arg['value']); - if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['value']); } - } - } - // Reverse the order of the arguments - krsort($args); - if (($passByReference) && ($argCount == 0)) { - $args[] = $cellID; - $argArrayVals[] = $this->_showValue($cellID); - } -// echo 'Arguments are: '; -// print_r($args); -// echo '<br />'; - if ($functionName != 'MKMATRIX') { - if ($this->_debugLog->getWriteDebugLog()) { - krsort($argArrayVals); - $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); - } - } - // Process each argument in turn, building the return value as an array -// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) { -// $operand1 = $args[1]; -// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1)); -// $result = array(); -// $row = 0; -// foreach($operand1 as $args) { -// if (is_array($args)) { -// foreach($args as $arg) { -// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); -// $r = call_user_func_array($functionCall,$arg); -// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); -// $result[$row][] = $r; -// } -// ++$row; -// } else { -// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); -// $r = call_user_func_array($functionCall,$args); -// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); -// $result[] = $r; -// } -// } -// } else { - // Process the argument with the appropriate function call - if ($passCellReference) { - $args[] = $pCell; - } - if (strpos($functionCall,'::') !== FALSE) { - $result = call_user_func_array(explode('::',$functionCall),$args); - } else { - foreach($args as &$arg) { - $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg); - } - unset($arg); - $result = call_user_func_array($functionCall,$args); - } -// } - if ($functionName != 'MKMATRIX') { - $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); - } - $stack->push('Value',self::_wrapResult($result)); - } - - } else { - // if the token is a number, boolean, string or an Excel error, push it onto the stack - if (isset(self::$_ExcelConstants[strtoupper($token)])) { - $excelConstant = strtoupper($token); -// echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />'; - $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]); - $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); - } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { -// echo 'Token is a number, boolean, string, null or an Excel error<br />'; - $stack->push('Value',$token); - // if the token is a named range, push the named range name onto the stack - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) { -// echo 'Token is a named range<br />'; - $namedRange = $matches[6]; -// echo 'Named Range is '.$namedRange.'<br />'; - $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange); - $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE); - $pCell->attach($pCellParent); - $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); - $stack->push('Named Range',$cellValue,$namedRange); - } else { - return $this->_raiseFormulaError("undefined variable '$token'"); - } - } - } - // when we're out of tokens, the stack should have a single element, the final result - if ($stack->count() != 1) return $this->_raiseFormulaError("internal error"); - $output = $stack->pop(); - $output = $output['value']; - -// if ((is_array($output)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { -// return array_shift(PHPExcel_Calculation_Functions::flattenArray($output)); -// } - return $output; - } // function _processTokenStack() - - - private function _validateBinaryOperand($cellID, &$operand, &$stack) { - if (is_array($operand)) { - if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { - do { - $operand = array_pop($operand); - } while (is_array($operand)); - } - } - // Numbers, matrices and booleans can pass straight through, as they're already valid - if (is_string($operand)) { - // We only need special validations for the operand if it is a string - // Start by stripping off the quotation marks we use to identify true excel string values internally - if ($operand > '' && $operand{0} == '"') { $operand = self::_unwrapResult($operand); } - // If the string is a numeric value, we treat it as a numeric, so no further testing - if (!is_numeric($operand)) { - // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations - if ($operand > '' && $operand{0} == '#') { - $stack->push('Value', $operand); - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand)); - return FALSE; - } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { - // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations - $stack->push('Value', '#VALUE!'); - $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); - return FALSE; - } - } - } - - // return a true if the value of the operand is one that we can use in normal binary operations - return TRUE; - } // function _validateBinaryOperand() - - - private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) { - // If we're dealing with matrix operations, we want a matrix result - if ((is_array($operand1)) || (is_array($operand2))) { - $result = array(); - if ((is_array($operand1)) && (!is_array($operand2))) { - foreach($operand1 as $x => $operandData) { - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); - $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack); - $r = $stack->pop(); - $result[$x] = $r['value']; - } - } elseif ((!is_array($operand1)) && (is_array($operand2))) { - foreach($operand2 as $x => $operandData) { - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); - $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack); - $r = $stack->pop(); - $result[$x] = $r['value']; - } - } else { - if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } - foreach($operand1 as $x => $operandData) { - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); - $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); - $r = $stack->pop(); - $result[$x] = $r['value']; - } - } - // Log the result details - $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); - // And push the result onto the stack - $stack->push('Array',$result); - return TRUE; - } - - // Simple validate the two operands if they are string values - if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); } - if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); } - - // Use case insensitive comparaison if not OpenOffice mode - if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) - { - if (is_string($operand1)) { - $operand1 = strtoupper($operand1); - } - - if (is_string($operand2)) { - $operand2 = strtoupper($operand2); - } - } - - $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE; - - // execute the necessary operation - switch ($operation) { - // Greater than - case '>': - if ($useLowercaseFirstComparison) { - $result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0; - } else { - $result = ($operand1 > $operand2); - } - break; - // Less than - case '<': - if ($useLowercaseFirstComparison) { - $result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0; - } else { - $result = ($operand1 < $operand2); - } - break; - // Equality - case '=': + while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( + if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + else $output[] = $o2; // pop the argument expression stuff and push onto the output + } + // If we've a comma when we're expecting an operand, then what we actually have is a null operand; + // so push a null onto the stack + if (($expectingOperand) || (!$expectingOperator)) { + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); + } + // make sure there was a function + $d = $stack->last(2); + if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) + return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + $d = $stack->pop(); + $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count + $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again + $expectingOperator = FALSE; + $expectingOperand = TRUE; + ++$index; + + } elseif ($opCharacter == '(' && !$expectingOperator) { +// echo 'Element is an Opening Bracket<br />'; + $stack->push('Brace', '('); + ++$index; + + } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number? + $expectingOperator = TRUE; + $expectingOperand = FALSE; + $val = $match[1]; + $length = strlen($val); +// echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />'; + + if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { + $val = preg_replace('/\s/u','',$val); +// echo 'Element '.$val.' is a Function<br />'; + if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function + $stack->push('Function', strtoupper($val)); + $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch); + if ($ax) { + $stack->push('Operand Count for Function '.strtoupper($val).')', 0); + $expectingOperator = TRUE; + } else { + $stack->push('Operand Count for Function '.strtoupper($val).')', 1); + $expectingOperator = FALSE; + } + $stack->push('Brace', '('); + } else { // it's a var w/ implicit multiplication + $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL); + } + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) { +// echo 'Element '.$val.' is a Cell reference<br />'; + // Watch for this case-change when modifying to allow cell references in different worksheets... + // Should only be applied to the actual cell column, not the worksheet name + + // If the last entry on the stack was a : operator, then we have a cell range reference + $testPrevOp = $stack->last(1); + if ($testPrevOp['value'] == ':') { + // If we have a worksheet reference, then we're playing with a 3D reference + if ($matches[2] == '') { + // Otherwise, we 'inherit' the worksheet reference from the start cell reference + // The start of the cell range reference should be the last entry in $output + $startCellRef = $output[count($output)-1]['value']; + preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches); + if ($startMatches[2] > '') { + $val = $startMatches[2].'!'.$val; + } + } else { + return $this->_raiseFormulaError("3D Range references are not yet supported"); + } + } + + $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val); +// $expectingOperator = FALSE; + } else { // it's a variable, constant, string, number or boolean +// echo 'Element is a Variable, Constant, String, Number or Boolean<br />'; + // If the last entry on the stack was a : operator, then we may have a row or column range reference + $testPrevOp = $stack->last(1); + if ($testPrevOp['value'] == ':') { + $startRowColRef = $output[count($output)-1]['value']; + $rangeWS1 = ''; + if (strpos('!',$startRowColRef) !== FALSE) { + list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef); + } + if ($rangeWS1 != '') $rangeWS1 .= '!'; + $rangeWS2 = $rangeWS1; + if (strpos('!',$val) !== FALSE) { + list($rangeWS2,$val) = explode('!',$val); + } + if ($rangeWS2 != '') $rangeWS2 .= '!'; + if ((is_integer($startRowColRef)) && (ctype_digit($val)) && + ($startRowColRef <= 1048576) && ($val <= 1048576)) { + // Row range + $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007 + $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef; + $val = $rangeWS2.$endRowColRef.$val; + } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) && + (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) { + // Column range + $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007 + $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1'; + $val = $rangeWS2.$val.$endRowColRef; + } + } + + $localeConstant = FALSE; + if ($opCharacter == '"') { +// echo 'Element is a String<br />'; + // UnEscape any quotes within the string + $val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val))); + } elseif (is_numeric($val)) { +// echo 'Element is a Number<br />'; + if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { +// echo 'Casting '.$val.' to float<br />'; + $val = (float) $val; + } else { +// echo 'Casting '.$val.' to integer<br />'; + $val = (integer) $val; + } + } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) { + $excelConstant = trim(strtoupper($val)); +// echo 'Element '.$excelConstant.' is an Excel Constant<br />'; + $val = self::$_ExcelConstants[$excelConstant]; + } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) { +// echo 'Element '.$localeConstant.' is an Excel Constant<br />'; + $val = self::$_ExcelConstants[$localeConstant]; + } + $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL); + if ($localeConstant) { $details['localeValue'] = $localeConstant; } + $output[] = $details; + } + $index += $length; + + } elseif ($opCharacter == '$') { // absolute row or column range + ++$index; + } elseif ($opCharacter == ')') { // miscellaneous error checking + if ($expectingOperand) { + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); + $expectingOperand = FALSE; + $expectingOperator = TRUE; + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected ')'"); + } + } elseif (isset(self::$_operators[$opCharacter]) && !$expectingOperator) { + return $this->_raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'"); + } else { // I don't even want to know what you did to get here + return $this->_raiseFormulaError("Formula Error: An unexpected error occured"); + } + // Test for end of formula string + if ($index == strlen($formula)) { + // Did we end with an operator?. + // Only valid for the % unary operator + if ((isset(self::$_operators[$opCharacter])) && ($opCharacter != '%')) { + return $this->_raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands"); + } else { + break; + } + } + // Ignore white space + while (($formula{$index} == "\n") || ($formula{$index} == "\r")) { + ++$index; + } + if ($formula{$index} == ' ') { + while ($formula{$index} == ' ') { + ++$index; + } + // If we're expecting an operator, but only have a space between the previous and next operands (and both are + // Cell References) then we have an INTERSECTION operator +// echo 'Possible Intersect Operator<br />'; + if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) && + ($output[count($output)-1]['type'] == 'Cell Reference')) { +// echo 'Element is an Intersect Operator<br />'; + while($stack->count() > 0 && + ($o2 = $stack->last()) && + isset(self::$_operators[$o2['value']]) && + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { + $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output + } + $stack->push('Binary Operator','|'); // Put an Intersect Operator on the stack + $expectingOperator = FALSE; + } + } + } + + while (($op = $stack->pop()) !== NULL) { // pop everything off the stack and push onto output + if ((is_array($op) && $op['value'] == '(') || ($op === '(')) + return $this->_raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced + $output[] = $op; + } + return $output; + } // function _parseFormula() + + + private static function _dataTestReference(&$operandData) + { + $operand = $operandData['value']; + if (($operandData['reference'] === NULL) && (is_array($operand))) { + $rKeys = array_keys($operand); + $rowKey = array_shift($rKeys); + $cKeys = array_keys(array_keys($operand[$rowKey])); + $colKey = array_shift($cKeys); + if (ctype_upper($colKey)) { + $operandData['reference'] = $colKey.$rowKey; + } + } + return $operand; + } + + // evaluate postfix notation + private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) { + if ($tokens == FALSE) return FALSE; + + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection), + // so we store the parent cell collection so that we can re-attach it when necessary + $pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null; + $stack = new PHPExcel_Calculation_Token_Stack; + + // Loop through each token in turn + foreach ($tokens as $tokenData) { +// print_r($tokenData); +// echo '<br />'; + $token = $tokenData['value']; +// echo '<b>Token is '.$token.'</b><br />'; + // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack + if (isset(self::$_binaryOperators[$token])) { +// echo 'Token is a binary operator<br />'; + // We must have two operands, error if we don't + if (($operand2Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + if (($operand1Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + + $operand1 = self::_dataTestReference($operand1Data); + $operand2 = self::_dataTestReference($operand2Data); + + // Log what we're doing + if ($token == ':') { + $this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); + } else { + $this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); + } + + // Process the operation in the appropriate manner + switch ($token) { + // Comparison (Boolean) Operators + case '>' : // Greater than + case '<' : // Less than + case '>=' : // Greater than or Equal to + case '<=' : // Less than or Equal to + case '=' : // Equality + case '<>' : // Inequality + $this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack); + break; + // Binary Operators + case ':' : // Range + $sheet1 = $sheet2 = ''; + if (strpos($operand1Data['reference'],'!') !== FALSE) { + list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']); + } else { + $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : ''; + } + if (strpos($operand2Data['reference'],'!') !== FALSE) { + list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']); + } else { + $sheet2 = $sheet1; + } + if ($sheet1 == $sheet2) { + if ($operand1Data['reference'] === NULL) { + if ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) { + $operand1Data['reference'] = $pCell->getColumn().$operand1Data['value']; + } elseif (trim($operand1Data['reference']) == '') { + $operand1Data['reference'] = $pCell->getCoordinate(); + } else { + $operand1Data['reference'] = $operand1Data['value'].$pCell->getRow(); + } + } + if ($operand2Data['reference'] === NULL) { + if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) { + $operand2Data['reference'] = $pCell->getColumn().$operand2Data['value']; + } elseif (trim($operand2Data['reference']) == '') { + $operand2Data['reference'] = $pCell->getCoordinate(); + } else { + $operand2Data['reference'] = $operand2Data['value'].$pCell->getRow(); + } + } + + $oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference'])); + $oCol = $oRow = array(); + foreach($oData as $oDatum) { + $oCR = PHPExcel_Cell::coordinateFromString($oDatum); + $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1; + $oRow[] = $oCR[1]; + } + $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $stack->push('Cell Reference',$cellValue,$cellRef); + } else { + $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL); + } + + break; + case '+' : // Addition + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack); + break; + case '-' : // Subtraction + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack); + break; + case '*' : // Multiplication + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack); + break; + case '/' : // Division + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack); + break; + case '^' : // Exponential + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack); + break; + case '&' : // Concatenation + // If either of the operands is a matrix, we need to treat them both as matrices + // (converting the other operand to a matrix if need be); then perform the required + // matrix operation + if (is_bool($operand1)) { + $operand1 = ($operand1) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + if (is_bool($operand2)) { + $operand2 = ($operand2) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + if ((is_array($operand1)) || (is_array($operand2))) { + // Ensure that both operands are arrays/matrices + self::_checkMatrixOperands($operand1,$operand2,2); + try { + // Convert operand 1 from a PHP array to a matrix + $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); + // Perform the required operation against the operand 1 matrix, passing in operand 2 + $matrixResult = $matrix->concat($operand2); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + } else { + $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"'; + } + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $stack->push('Value',$result); + break; + case '|' : // Intersect + $rowIntersect = array_intersect_key($operand1,$operand2); + $cellIntersect = $oCol = $oRow = array(); + foreach(array_keys($rowIntersect) as $row) { + $oRow[] = $row; + foreach($rowIntersect[$row] as $col => $data) { + $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1; + $cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]); + } + } + $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); + $stack->push('Value',$cellIntersect,$cellRef); + break; + } + + // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on + } elseif (($token === '~') || ($token === '%')) { +// echo 'Token is a unary operator<br />'; + if (($arg = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + $arg = $arg['value']; + if ($token === '~') { +// echo 'Token is a negation operator<br />'; + $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg)); + $multiplier = -1; + } else { +// echo 'Token is a percentile operator<br />'; + $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg)); + $multiplier = 0.01; + } + if (is_array($arg)) { + self::_checkMatrixOperands($arg,$multiplier,2); + try { + $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg); + $matrixResult = $matrix1->arrayTimesEquals($multiplier); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $stack->push('Value',$result); + } else { + $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack); + } + + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { + $cellRef = NULL; +// echo 'Element '.$token.' is a Cell reference<br />'; + if (isset($matches[8])) { +// echo 'Reference is a Range of cells<br />'; + if ($pCell === NULL) { +// We can't access the range, so return a REF error + $cellValue = PHPExcel_Calculation_Functions::REF(); + } else { + $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10]; + if ($matches[2] > '') { + $matches[2] = trim($matches[2],"\"'"); + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { + // It's a Reference to an external workbook (not currently supported) + return $this->_raiseFormulaError('Unable to access External Workbook'); + } + $matches[2] = trim($matches[2],"\"'"); +// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); +// $cellRef = $matches[2].'!'.$cellRef; + } else { +// echo '$cellRef='.$cellRef.' in current worksheet<br />'; + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet'); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + } + } + } else { +// echo 'Reference is a single Cell<br />'; + if ($pCell === NULL) { +// We can't access the cell, so return a REF error + $cellValue = PHPExcel_Calculation_Functions::REF(); + } else { + $cellRef = $matches[6].$matches[7]; + if ($matches[2] > '') { + $matches[2] = trim($matches[2],"\"'"); + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { + // It's a Reference to an external workbook (not currently supported) + return $this->_raiseFormulaError('Unable to access External Workbook'); + } +// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); + if ($pCellParent !== NULL) { + $cellSheet = $this->_workbook->getSheetByName($matches[2]); + if ($cellSheet && $cellSheet->cellExists($cellRef)) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); + $pCell->attach($pCellParent); + } else { + $cellValue = NULL; + } + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); +// $cellRef = $matches[2].'!'.$cellRef; + } else { +// echo '$cellRef='.$cellRef.' in current worksheet<br />'; + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet'); + if ($pCellParent->isDataSet($cellRef)) { + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); + $pCell->attach($pCellParent); + } else { + $cellValue = NULL; + } + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + } + } + } + $stack->push('Value',$cellValue,$cellRef); + + // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) { +// echo 'Token is a function<br />'; + $functionName = $matches[1]; + $argCount = $stack->pop(); + $argCount = $argCount['value']; + if ($functionName != 'MKMATRIX') { + $this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); + } + if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function + if (isset(self::$_PHPExcelFunctions[$functionName])) { + $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; + $passByReference = isset(self::$_PHPExcelFunctions[$functionName]['passByReference']); + $passCellReference = isset(self::$_PHPExcelFunctions[$functionName]['passCellReference']); + } elseif (isset(self::$_controlFunctions[$functionName])) { + $functionCall = self::$_controlFunctions[$functionName]['functionCall']; + $passByReference = isset(self::$_controlFunctions[$functionName]['passByReference']); + $passCellReference = isset(self::$_controlFunctions[$functionName]['passCellReference']); + } + // get the arguments for this function +// echo 'Function '.$functionName.' expects '.$argCount.' arguments<br />'; + $args = $argArrayVals = array(); + for ($i = 0; $i < $argCount; ++$i) { + $arg = $stack->pop(); + $a = $argCount - $i - 1; + if (($passByReference) && + (isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) && + (self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) { + if ($arg['reference'] === NULL) { + $args[] = $cellID; + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($cellID); } + } else { + $args[] = $arg['reference']; + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['reference']); } + } + } else { + $args[] = self::_unwrapResult($arg['value']); + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['value']); } + } + } + // Reverse the order of the arguments + krsort($args); + if (($passByReference) && ($argCount == 0)) { + $args[] = $cellID; + $argArrayVals[] = $this->_showValue($cellID); + } +// echo 'Arguments are: '; +// print_r($args); +// echo '<br />'; + if ($functionName != 'MKMATRIX') { + if ($this->_debugLog->getWriteDebugLog()) { + krsort($argArrayVals); + $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); + } + } + // Process each argument in turn, building the return value as an array +// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) { +// $operand1 = $args[1]; +// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1)); +// $result = array(); +// $row = 0; +// foreach($operand1 as $args) { +// if (is_array($args)) { +// foreach($args as $arg) { +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); +// $r = call_user_func_array($functionCall,$arg); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $result[$row][] = $r; +// } +// ++$row; +// } else { +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); +// $r = call_user_func_array($functionCall,$args); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $result[] = $r; +// } +// } +// } else { + // Process the argument with the appropriate function call + if ($passCellReference) { + $args[] = $pCell; + } + if (strpos($functionCall,'::') !== FALSE) { + $result = call_user_func_array(explode('::',$functionCall),$args); + } else { + foreach($args as &$arg) { + $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg); + } + unset($arg); + $result = call_user_func_array($functionCall,$args); + } +// } + if ($functionName != 'MKMATRIX') { + $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); + } + $stack->push('Value',self::_wrapResult($result)); + } + + } else { + // if the token is a number, boolean, string or an Excel error, push it onto the stack + if (isset(self::$_ExcelConstants[strtoupper($token)])) { + $excelConstant = strtoupper($token); +// echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />'; + $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]); + $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); + } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { +// echo 'Token is a number, boolean, string, null or an Excel error<br />'; + $stack->push('Value',$token); + // if the token is a named range, push the named range name onto the stack + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) { +// echo 'Token is a named range<br />'; + $namedRange = $matches[6]; +// echo 'Named Range is '.$namedRange.'<br />'; + $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange); + $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE); + $pCell->attach($pCellParent); + $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); + $stack->push('Named Range',$cellValue,$namedRange); + } else { + return $this->_raiseFormulaError("undefined variable '$token'"); + } + } + } + // when we're out of tokens, the stack should have a single element, the final result + if ($stack->count() != 1) return $this->_raiseFormulaError("internal error"); + $output = $stack->pop(); + $output = $output['value']; + +// if ((is_array($output)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { +// return array_shift(PHPExcel_Calculation_Functions::flattenArray($output)); +// } + return $output; + } // function _processTokenStack() + + + private function _validateBinaryOperand($cellID, &$operand, &$stack) { + if (is_array($operand)) { + if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { + do { + $operand = array_pop($operand); + } while (is_array($operand)); + } + } + // Numbers, matrices and booleans can pass straight through, as they're already valid + if (is_string($operand)) { + // We only need special validations for the operand if it is a string + // Start by stripping off the quotation marks we use to identify true excel string values internally + if ($operand > '' && $operand{0} == '"') { $operand = self::_unwrapResult($operand); } + // If the string is a numeric value, we treat it as a numeric, so no further testing + if (!is_numeric($operand)) { + // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations + if ($operand > '' && $operand{0} == '#') { + $stack->push('Value', $operand); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand)); + return FALSE; + } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { + // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations + $stack->push('Value', '#VALUE!'); + $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); + return FALSE; + } + } + } + + // return a true if the value of the operand is one that we can use in normal binary operations + return TRUE; + } // function _validateBinaryOperand() + + + private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) { + // If we're dealing with matrix operations, we want a matrix result + if ((is_array($operand1)) || (is_array($operand2))) { + $result = array(); + if ((is_array($operand1)) && (!is_array($operand2))) { + foreach($operand1 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } elseif ((!is_array($operand1)) && (is_array($operand2))) { + foreach($operand2 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); + $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } else { + if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } + foreach($operand1 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } + // Log the result details + $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Array',$result); + return TRUE; + } + + // Simple validate the two operands if they are string values + if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); } + if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); } + + // Use case insensitive comparaison if not OpenOffice mode + if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) + { + if (is_string($operand1)) { + $operand1 = strtoupper($operand1); + } + + if (is_string($operand2)) { + $operand2 = strtoupper($operand2); + } + } + + $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE; + + // execute the necessary operation + switch ($operation) { + // Greater than + case '>': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0; + } else { + $result = ($operand1 > $operand2); + } + break; + // Less than + case '<': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0; + } else { + $result = ($operand1 < $operand2); + } + break; + // Equality + case '=': if (is_numeric($operand1) && is_numeric($operand2)) { $result = (abs($operand1 - $operand2) < $this->delta); } else { $result = strcmp($operand1, $operand2) == 0; } - break; - // Greater than or equal - case '>=': + break; + // Greater than or equal + case '>=': if (is_numeric($operand1) && is_numeric($operand2)) { $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 > $operand2)); - } elseif ($useLowercaseFirstComparison) { - $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0; - } else { - $result = strcmp($operand1, $operand2) >= 0; - } - break; - // Less than or equal - case '<=': + } elseif ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0; + } else { + $result = strcmp($operand1, $operand2) >= 0; + } + break; + // Less than or equal + case '<=': if (is_numeric($operand1) && is_numeric($operand2)) { $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 < $operand2)); } elseif ($useLowercaseFirstComparison) { - $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0; - } else { - $result = strcmp($operand1, $operand2) <= 0; - } - break; - // Inequality - case '<>': + $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0; + } else { + $result = strcmp($operand1, $operand2) <= 0; + } + break; + // Inequality + case '<>': if (is_numeric($operand1) && is_numeric($operand2)) { $result = (abs($operand1 - $operand2) > 1E-14); } else { $result = strcmp($operand1, $operand2) != 0; } - break; - } - - // Log the result details - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - // And push the result onto the stack - $stack->push('Value',$result); - return true; - } - - /** - * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters - * @param string $str1 First string value for the comparison - * @param string $str2 Second string value for the comparison - * @return integer - */ - private function strcmpLowercaseFirst($str1, $str2) - { + break; + } + + // Log the result details + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Value',$result); + return true; + } + + /** + * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters + * @param string $str1 First string value for the comparison + * @param string $str2 Second string value for the comparison + * @return integer + */ + private function strcmpLowercaseFirst($str1, $str2) + { $inversedStr1 = PHPExcel_Shared_String::StrCaseReverse($str1); $inversedStr2 = PHPExcel_Shared_String::StrCaseReverse($str2); - return strcmp($inversedStr1, $inversedStr2); - } - - private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { - // Validate the two operands - if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; - if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; - - // If either of the operands is a matrix, we need to treat them both as matrices - // (converting the other operand to a matrix if need be); then perform the required - // matrix operation - if ((is_array($operand1)) || (is_array($operand2))) { - // Ensure that both operands are arrays/matrices of the same size - self::_checkMatrixOperands($operand1, $operand2, 2); - - try { - // Convert operand 1 from a PHP array to a matrix - $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); - // Perform the required operation against the operand 1 matrix, passing in operand 2 - $matrixResult = $matrix->$matrixFunction($operand2); - $result = $matrixResult->getArray(); - } catch (PHPExcel_Exception $ex) { - $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); - $result = '#VALUE!'; - } - } else { - if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) && - ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || - (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) { - $result = PHPExcel_Calculation_Functions::VALUE(); - } else { - // If we're dealing with non-matrix operations, execute the necessary operation - switch ($operation) { - // Addition - case '+': - $result = $operand1 + $operand2; - break; - // Subtraction - case '-': - $result = $operand1 - $operand2; - break; - // Multiplication - case '*': - $result = $operand1 * $operand2; - break; - // Division - case '/': - if ($operand2 == 0) { - // Trap for Divide by Zero error - $stack->push('Value','#DIV/0!'); - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); - return FALSE; - } else { - $result = $operand1 / $operand2; - } - break; - // Power - case '^': - $result = pow($operand1, $operand2); - break; - } - } - } - - // Log the result details - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - // And push the result onto the stack - $stack->push('Value',$result); - return TRUE; - } // function _executeNumericBinaryOperation() - - - // trigger an error, but nicely, if need be - protected function _raiseFormulaError($errorMessage) { - $this->formulaError = $errorMessage; - $this->_cyclicReferenceStack->clear(); - if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); - trigger_error($errorMessage, E_USER_ERROR); - } // function _raiseFormulaError() - - - /** - * Extract range values - * - * @param string &$pRange String based range representation - * @param PHPExcel_Worksheet $pSheet Worksheet - * @param boolean $resetLog Flag indicating whether calculation log should be reset or not - * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. - * @throws PHPExcel_Calculation_Exception - */ - public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { - // Return value - $returnValue = array (); - -// echo 'extractCellRange('.$pRange.')',PHP_EOL; - if ($pSheet !== NULL) { - $pSheetName = $pSheet->getTitle(); -// echo 'Passed sheet name is '.$pSheetName.PHP_EOL; -// echo 'Range reference is '.$pRange.PHP_EOL; - if (strpos ($pRange, '!') !== false) { -// echo '$pRange reference includes sheet reference',PHP_EOL; - list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); -// echo 'New sheet name is '.$pSheetName,PHP_EOL; -// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; - $pSheet = $this->_workbook->getSheetByName($pSheetName); - } - - // Extract range - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); - $pRange = $pSheetName.'!'.$pRange; - if (!isset($aReferences[1])) { - // Single cell in range - sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow); - $cellValue = NULL; - if ($pSheet->cellExists($aReferences[0])) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } else { - // Extract cell data for all cells in the range - foreach ($aReferences as $reference) { - // Extract range - sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow); - $cellValue = NULL; - if ($pSheet->cellExists($reference)) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } - } - } - - // Return - return $returnValue; - } // function extractCellRange() - - - /** - * Extract range values - * - * @param string &$pRange String based range representation - * @param PHPExcel_Worksheet $pSheet Worksheet - * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. - * @param boolean $resetLog Flag indicating whether calculation log should be reset or not - * @throws PHPExcel_Calculation_Exception - */ - public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { - // Return value - $returnValue = array (); - -// echo 'extractNamedRange('.$pRange.')<br />'; - if ($pSheet !== NULL) { - $pSheetName = $pSheet->getTitle(); -// echo 'Current sheet name is '.$pSheetName.'<br />'; -// echo 'Range reference is '.$pRange.'<br />'; - if (strpos ($pRange, '!') !== false) { -// echo '$pRange reference includes sheet reference',PHP_EOL; - list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); -// echo 'New sheet name is '.$pSheetName,PHP_EOL; -// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; - $pSheet = $this->_workbook->getSheetByName($pSheetName); - } - - // Named range? - $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet); - if ($namedRange !== NULL) { - $pSheet = $namedRange->getWorksheet(); -// echo 'Named Range '.$pRange.' ('; - $pRange = $namedRange->getRange(); - $splitRange = PHPExcel_Cell::splitRange($pRange); - // Convert row and column references - if (ctype_alpha($splitRange[0][0])) { - $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow(); - } elseif(ctype_digit($splitRange[0][0])) { - $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1]; - } -// echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />'; - -// if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) { -// if (!$namedRange->getLocalOnly()) { -// $pSheet = $namedRange->getWorksheet(); -// } else { -// return $returnValue; -// } -// } - } else { - return PHPExcel_Calculation_Functions::REF(); - } - - // Extract range - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); -// var_dump($aReferences); - if (!isset($aReferences[1])) { - // Single cell (or single column or row) in range - list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); - $cellValue = NULL; - if ($pSheet->cellExists($aReferences[0])) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } else { - // Extract cell data for all cells in the range - foreach ($aReferences as $reference) { - // Extract range - list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference); -// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />'; - $cellValue = NULL; - if ($pSheet->cellExists($reference)) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } - } -// print_r($returnValue); -// echo '<br />'; - } - - // Return - return $returnValue; - } // function extractNamedRange() - - - /** - * Is a specific function implemented? - * - * @param string $pFunction Function Name - * @return boolean - */ - public function isImplemented($pFunction = '') { - $pFunction = strtoupper ($pFunction); - if (isset(self::$_PHPExcelFunctions[$pFunction])) { - return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); - } else { - return FALSE; - } - } // function isImplemented() - - - /** - * Get a list of all implemented functions as an array of function objects - * - * @return array of PHPExcel_Calculation_Function - */ - public function listFunctions() { - // Return value - $returnValue = array(); - // Loop functions - foreach(self::$_PHPExcelFunctions as $functionName => $function) { - if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { - $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'], - $functionName, - $function['functionCall'] - ); - } - } - - // Return - return $returnValue; - } // function listFunctions() - - - /** - * Get a list of all Excel function names - * - * @return array - */ - public function listAllFunctionNames() { - return array_keys(self::$_PHPExcelFunctions); - } // function listAllFunctionNames() - - /** - * Get a list of implemented Excel function names - * - * @return array - */ - public function listFunctionNames() { - // Return value - $returnValue = array(); - // Loop functions - foreach(self::$_PHPExcelFunctions as $functionName => $function) { - if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { - $returnValue[] = $functionName; - } - } - - // Return - return $returnValue; - } // function listFunctionNames() - -} // class PHPExcel_Calculation + return strcmp($inversedStr1, $inversedStr2); + } + private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { + // Validate the two operands + if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; + if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; + + // If either of the operands is a matrix, we need to treat them both as matrices + // (converting the other operand to a matrix if need be); then perform the required + // matrix operation + if ((is_array($operand1)) || (is_array($operand2))) { + // Ensure that both operands are arrays/matrices of the same size + self::_checkMatrixOperands($operand1, $operand2, 2); + + try { + // Convert operand 1 from a PHP array to a matrix + $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); + // Perform the required operation against the operand 1 matrix, passing in operand 2 + $matrixResult = $matrix->$matrixFunction($operand2); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + } else { + if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) && + ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || + (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) { + $result = PHPExcel_Calculation_Functions::VALUE(); + } else { + // If we're dealing with non-matrix operations, execute the necessary operation + switch ($operation) { + // Addition + case '+': + $result = $operand1 + $operand2; + break; + // Subtraction + case '-': + $result = $operand1 - $operand2; + break; + // Multiplication + case '*': + $result = $operand1 * $operand2; + break; + // Division + case '/': + if ($operand2 == 0) { + // Trap for Divide by Zero error + $stack->push('Value','#DIV/0!'); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); + return FALSE; + } else { + $result = $operand1 / $operand2; + } + break; + // Power + case '^': + $result = pow($operand1, $operand2); + break; + } + } + } + + // Log the result details + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Value',$result); + return TRUE; + } // function _executeNumericBinaryOperation() + + + // trigger an error, but nicely, if need be + protected function _raiseFormulaError($errorMessage) { + $this->formulaError = $errorMessage; + $this->_cyclicReferenceStack->clear(); + if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); + trigger_error($errorMessage, E_USER_ERROR); + } // function _raiseFormulaError() + + + /** + * Extract range values + * + * @param string &$pRange String based range representation + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not + * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @throws PHPExcel_Calculation_Exception + */ + public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { + // Return value + $returnValue = array (); + +// echo 'extractCellRange('.$pRange.')',PHP_EOL; + if ($pSheet !== NULL) { + $pSheetName = $pSheet->getTitle(); +// echo 'Passed sheet name is '.$pSheetName.PHP_EOL; +// echo 'Range reference is '.$pRange.PHP_EOL; + if (strpos ($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference',PHP_EOL; + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName,PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + $pSheet = $this->_workbook->getSheetByName($pSheetName); + } + + // Extract range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); + $pRange = $pSheetName.'!'.$pRange; + if (!isset($aReferences[1])) { + // Single cell in range + sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow); + $cellValue = NULL; + if ($pSheet->cellExists($aReferences[0])) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } else { + // Extract cell data for all cells in the range + foreach ($aReferences as $reference) { + // Extract range + sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow); + $cellValue = NULL; + if ($pSheet->cellExists($reference)) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } + } + } + + // Return + return $returnValue; + } // function extractCellRange() + + + /** + * Extract range values + * + * @param string &$pRange String based range representation + * @param PHPExcel_Worksheet $pSheet Worksheet + * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not + * @throws PHPExcel_Calculation_Exception + */ + public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { + // Return value + $returnValue = array (); + +// echo 'extractNamedRange('.$pRange.')<br />'; + if ($pSheet !== NULL) { + $pSheetName = $pSheet->getTitle(); +// echo 'Current sheet name is '.$pSheetName.'<br />'; +// echo 'Range reference is '.$pRange.'<br />'; + if (strpos ($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference',PHP_EOL; + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName,PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + $pSheet = $this->_workbook->getSheetByName($pSheetName); + } + + // Named range? + $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet); + if ($namedRange !== NULL) { + $pSheet = $namedRange->getWorksheet(); +// echo 'Named Range '.$pRange.' ('; + $pRange = $namedRange->getRange(); + $splitRange = PHPExcel_Cell::splitRange($pRange); + // Convert row and column references + if (ctype_alpha($splitRange[0][0])) { + $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow(); + } elseif(ctype_digit($splitRange[0][0])) { + $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1]; + } +// echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />'; + +// if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) { +// if (!$namedRange->getLocalOnly()) { +// $pSheet = $namedRange->getWorksheet(); +// } else { +// return $returnValue; +// } +// } + } else { + return PHPExcel_Calculation_Functions::REF(); + } + + // Extract range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); +// var_dump($aReferences); + if (!isset($aReferences[1])) { + // Single cell (or single column or row) in range + list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); + $cellValue = NULL; + if ($pSheet->cellExists($aReferences[0])) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } else { + // Extract cell data for all cells in the range + foreach ($aReferences as $reference) { + // Extract range + list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference); +// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />'; + $cellValue = NULL; + if ($pSheet->cellExists($reference)) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } + } +// print_r($returnValue); +// echo '<br />'; + } + + // Return + return $returnValue; + } // function extractNamedRange() + + + /** + * Is a specific function implemented? + * + * @param string $pFunction Function Name + * @return boolean + */ + public function isImplemented($pFunction = '') { + $pFunction = strtoupper ($pFunction); + if (isset(self::$_PHPExcelFunctions[$pFunction])) { + return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); + } else { + return FALSE; + } + } // function isImplemented() + + + /** + * Get a list of all implemented functions as an array of function objects + * + * @return array of PHPExcel_Calculation_Function + */ + public function listFunctions() { + // Return value + $returnValue = array(); + // Loop functions + foreach(self::$_PHPExcelFunctions as $functionName => $function) { + if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { + $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'], + $functionName, + $function['functionCall'] + ); + } + } + + // Return + return $returnValue; + } // function listFunctions() + + + /** + * Get a list of all Excel function names + * + * @return array + */ + public function listAllFunctionNames() { + return array_keys(self::$_PHPExcelFunctions); + } // function listAllFunctionNames() + + /** + * Get a list of implemented Excel function names + * + * @return array + */ + public function listFunctionNames() { + // Return value + $returnValue = array(); + // Loop functions + foreach(self::$_PHPExcelFunctions as $functionName => $function) { + if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { + $returnValue[] = $functionName; + } + } + + // Return + return $returnValue; + } // function listFunctionNames() + +} // class PHPExcel_Calculation diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index ebda1b243..2d7432ea5 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_CodePage * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,86 +22,76 @@ * @category PHPExcel * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Shared_CodePage - * - * @category PHPExcel - * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_CodePage { - /** - * Convert Microsoft Code Page Identifier to Code Page Name which iconv - * and mbstring understands - * - * @param integer $codePage Microsoft Code Page Indentifier - * @return string Code Page Name - * @throws PHPExcel_Exception - */ - public static function NumberToName($codePage = 1252) - { - switch ($codePage) { - case 367: return 'ASCII'; break; // ASCII - case 437: return 'CP437'; break; // OEM US - case 720: throw new PHPExcel_Exception('Code page 720 not supported.'); - break; // OEM Arabic - case 737: return 'CP737'; break; // OEM Greek - case 775: return 'CP775'; break; // OEM Baltic - case 850: return 'CP850'; break; // OEM Latin I - case 852: return 'CP852'; break; // OEM Latin II (Central European) - case 855: return 'CP855'; break; // OEM Cyrillic - case 857: return 'CP857'; break; // OEM Turkish - case 858: return 'CP858'; break; // OEM Multilingual Latin I with Euro - case 860: return 'CP860'; break; // OEM Portugese - case 861: return 'CP861'; break; // OEM Icelandic - case 862: return 'CP862'; break; // OEM Hebrew - case 863: return 'CP863'; break; // OEM Canadian (French) - case 864: return 'CP864'; break; // OEM Arabic - case 865: return 'CP865'; break; // OEM Nordic - case 866: return 'CP866'; break; // OEM Cyrillic (Russian) - case 869: return 'CP869'; break; // OEM Greek (Modern) - case 874: return 'CP874'; break; // ANSI Thai - case 932: return 'CP932'; break; // ANSI Japanese Shift-JIS - case 936: return 'CP936'; break; // ANSI Chinese Simplified GBK - case 949: return 'CP949'; break; // ANSI Korean (Wansung) - case 950: return 'CP950'; break; // ANSI Chinese Traditional BIG5 - case 1200: return 'UTF-16LE'; break; // UTF-16 (BIFF8) - case 1250: return 'CP1250'; break; // ANSI Latin II (Central European) - case 1251: return 'CP1251'; break; // ANSI Cyrillic - case 0: // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program - case 1252: return 'CP1252'; break; // ANSI Latin I (BIFF4-BIFF7) - case 1253: return 'CP1253'; break; // ANSI Greek - case 1254: return 'CP1254'; break; // ANSI Turkish - case 1255: return 'CP1255'; break; // ANSI Hebrew - case 1256: return 'CP1256'; break; // ANSI Arabic - case 1257: return 'CP1257'; break; // ANSI Baltic - case 1258: return 'CP1258'; break; // ANSI Vietnamese - case 1361: return 'CP1361'; break; // ANSI Korean (Johab) - case 10000: return 'MAC'; break; // Apple Roman - case 10001: return 'CP932'; break; // Macintosh Japanese - case 10002: return 'CP950'; break; // Macintosh Chinese Traditional - case 10003: return 'CP1361'; break; // Macintosh Korean - case 10006: return 'MACGREEK'; break; // Macintosh Greek - case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic - case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) - case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe - case 10079: return 'MACICELAND'; break; // Macintosh Icelandic - case 10081: return 'MACTURKISH'; break; // Macintosh Turkish - case 21010: return 'UTF-16LE'; break; // UTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE - case 32768: return 'MAC'; break; // Apple Roman - case 32769: throw new PHPExcel_Exception('Code page 32769 not supported.'); - break; // ANSI Latin I (BIFF2-BIFF3) - case 65000: return 'UTF-7'; break; // Unicode (UTF-7) - case 65001: return 'UTF-8'; break; // Unicode (UTF-8) - } - - throw new PHPExcel_Exception('Unknown codepage: ' . $codePage); - } + /** + * Convert Microsoft Code Page Identifier to Code Page Name which iconv + * and mbstring understands + * + * @param integer $codePage Microsoft Code Page Indentifier + * @return string Code Page Name + * @throws PHPExcel_Exception + */ + public static function NumberToName($codePage = 1252) + { + switch ($codePage) { + case 367: return 'ASCII'; break; // ASCII + case 437: return 'CP437'; break; // OEM US + case 720: throw new PHPExcel_Exception('Code page 720 not supported.'); + break; // OEM Arabic + case 737: return 'CP737'; break; // OEM Greek + case 775: return 'CP775'; break; // OEM Baltic + case 850: return 'CP850'; break; // OEM Latin I + case 852: return 'CP852'; break; // OEM Latin II (Central European) + case 855: return 'CP855'; break; // OEM Cyrillic + case 857: return 'CP857'; break; // OEM Turkish + case 858: return 'CP858'; break; // OEM Multilingual Latin I with Euro + case 860: return 'CP860'; break; // OEM Portugese + case 861: return 'CP861'; break; // OEM Icelandic + case 862: return 'CP862'; break; // OEM Hebrew + case 863: return 'CP863'; break; // OEM Canadian (French) + case 864: return 'CP864'; break; // OEM Arabic + case 865: return 'CP865'; break; // OEM Nordic + case 866: return 'CP866'; break; // OEM Cyrillic (Russian) + case 869: return 'CP869'; break; // OEM Greek (Modern) + case 874: return 'CP874'; break; // ANSI Thai + case 932: return 'CP932'; break; // ANSI Japanese Shift-JIS + case 936: return 'CP936'; break; // ANSI Chinese Simplified GBK + case 949: return 'CP949'; break; // ANSI Korean (Wansung) + case 950: return 'CP950'; break; // ANSI Chinese Traditional BIG5 + case 1200: return 'UTF-16LE'; break; // UTF-16 (BIFF8) + case 1250: return 'CP1250'; break; // ANSI Latin II (Central European) + case 1251: return 'CP1251'; break; // ANSI Cyrillic + case 0: // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program + case 1252: return 'CP1252'; break; // ANSI Latin I (BIFF4-BIFF7) + case 1253: return 'CP1253'; break; // ANSI Greek + case 1254: return 'CP1254'; break; // ANSI Turkish + case 1255: return 'CP1255'; break; // ANSI Hebrew + case 1256: return 'CP1256'; break; // ANSI Arabic + case 1257: return 'CP1257'; break; // ANSI Baltic + case 1258: return 'CP1258'; break; // ANSI Vietnamese + case 1361: return 'CP1361'; break; // ANSI Korean (Johab) + case 10000: return 'MAC'; break; // Apple Roman + case 10001: return 'CP932'; break; // Macintosh Japanese + case 10002: return 'CP950'; break; // Macintosh Chinese Traditional + case 10003: return 'CP1361'; break; // Macintosh Korean + case 10006: return 'MACGREEK'; break; // Macintosh Greek + case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic + case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) + case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe + case 10079: return 'MACICELAND'; break; // Macintosh Icelandic + case 10081: return 'MACTURKISH'; break; // Macintosh Turkish + case 21010: return 'UTF-16LE'; break; // UTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE + case 32768: return 'MAC'; break; // Apple Roman + case 32769: throw new PHPExcel_Exception('Code page 32769 not supported.'); + break; // ANSI Latin I (BIFF2-BIFF3) + case 65000: return 'UTF-7'; break; // Unicode (UTF-7) + case 65001: return 'UTF-8'; break; // Unicode (UTF-8) + } + throw new PHPExcel_Exception('Unknown codepage: ' . $codePage); + } } diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index c3fe23001..d0393a411 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -1,7 +1,7 @@ <?php /** - * PHPExcel + * PHPExcel_Shared_Date * * Copyright (c) 2006 - 2015 PHPExcel * @@ -20,360 +20,363 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category PHPExcel - * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_Shared_Date - * - * @category PHPExcel - * @package PHPExcel_Shared + * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ class PHPExcel_Shared_Date { - /** constants */ - const CALENDAR_WINDOWS_1900 = 1900; // Base date of 1st Jan 1900 = 1.0 - const CALENDAR_MAC_1904 = 1904; // Base date of 2nd Jan 1904 = 1.0 - - /* - * Names of the months of the year, indexed by shortname - * Planned usage for locale settings - * - * @public - * @var string[] - */ - public static $_monthNames = array( 'Jan' => 'January', - 'Feb' => 'February', - 'Mar' => 'March', - 'Apr' => 'April', - 'May' => 'May', - 'Jun' => 'June', - 'Jul' => 'July', - 'Aug' => 'August', - 'Sep' => 'September', - 'Oct' => 'October', - 'Nov' => 'November', - 'Dec' => 'December', - ); - - /* - * Names of the months of the year, indexed by shortname - * Planned usage for locale settings - * - * @public - * @var string[] - */ - public static $_numberSuffixes = array( 'st', - 'nd', - 'rd', - 'th', - ); - - /* - * Base calendar year to use for calculations - * - * @private - * @var int - */ - protected static $_excelBaseDate = self::CALENDAR_WINDOWS_1900; - - /** - * Set the Excel calendar (Windows 1900 or Mac 1904) - * - * @param integer $baseDate Excel base date (1900 or 1904) - * @return boolean Success or failure - */ - public static function setExcelCalendar($baseDate) { - if (($baseDate == self::CALENDAR_WINDOWS_1900) || - ($baseDate == self::CALENDAR_MAC_1904)) { - self::$_excelBaseDate = $baseDate; - return TRUE; - } - return FALSE; - } // function setExcelCalendar() - - - /** - * Return the Excel calendar (Windows 1900 or Mac 1904) - * - * @return integer Excel base date (1900 or 1904) - */ - public static function getExcelCalendar() { - return self::$_excelBaseDate; - } // function getExcelCalendar() - - - /** - * Convert a date from Excel to PHP - * - * @param long $dateValue Excel date/time value - * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as - * a UST timestamp, or adjusted to UST - * @param string $timezone The timezone for finding the adjustment from UST - * @return long PHP serialized date/time - */ - public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { - if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { - $my_excelBaseDate = 25569; - // Adjust for the spurious 29-Feb-1900 (Day 60) - if ($dateValue < 60) { - --$my_excelBaseDate; - } - } else { - $my_excelBaseDate = 24107; - } - - // Perform conversion - if ($dateValue >= 1) { - $utcDays = $dateValue - $my_excelBaseDate; - $returnValue = round($utcDays * 86400); - if (($returnValue <= PHP_INT_MAX) && ($returnValue >= -PHP_INT_MAX)) { - $returnValue = (integer) $returnValue; - } - } else { - $hours = round($dateValue * 24); - $mins = round($dateValue * 1440) - round($hours * 60); - $secs = round($dateValue * 86400) - round($hours * 3600) - round($mins * 60); - $returnValue = (integer) gmmktime($hours, $mins, $secs); - } - - $timezoneAdjustment = ($adjustToTimezone) ? - PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone, $returnValue) : - 0; - - // Return - return $returnValue + $timezoneAdjustment; - } // function ExcelToPHP() - - - /** - * Convert a date from Excel to a PHP Date/Time object - * - * @param integer $dateValue Excel date/time value - * @return DateTime PHP date/time object - */ - public static function ExcelToPHPObject($dateValue = 0) { - $dateTime = self::ExcelToPHP($dateValue); - $days = floor($dateTime / 86400); - $time = round((($dateTime / 86400) - $days) * 86400); - $hours = round($time / 3600); - $minutes = round($time / 60) - ($hours * 60); - $seconds = round($time) - ($hours * 3600) - ($minutes * 60); - - $dateObj = date_create('1-Jan-1970+'.$days.' days'); - $dateObj->setTime($hours,$minutes,$seconds); - - return $dateObj; - } // function ExcelToPHPObject() - - - /** - * Convert a date from PHP to Excel - * - * @param mixed $dateValue PHP serialized date/time or date object - * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as - * a UST timestamp, or adjusted to UST - * @param string $timezone The timezone for finding the adjustment from UST - * @return mixed Excel date/time value - * or boolean FALSE on failure - */ - public static function PHPToExcel($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { - $saveTimeZone = date_default_timezone_get(); - date_default_timezone_set('UTC'); - $retValue = FALSE; - if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { - $retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), - $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s') - ); - } elseif (is_numeric($dateValue)) { - $retValue = self::FormattedPHPToExcel( date('Y',$dateValue), date('m',$dateValue), date('d',$dateValue), - date('H',$dateValue), date('i',$dateValue), date('s',$dateValue) - ); - } - date_default_timezone_set($saveTimeZone); - - return $retValue; - } // function PHPToExcel() - - - /** - * FormattedPHPToExcel - * - * @param long $year - * @param long $month - * @param long $day - * @param long $hours - * @param long $minutes - * @param long $seconds - * @return long Excel date/time value - */ - public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minutes=0, $seconds=0) { - if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { - // - // Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel - // This affects every date following 28th February 1900 - // - $excel1900isLeapYear = TRUE; - if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = FALSE; } - $my_excelBaseDate = 2415020; - } else { - $my_excelBaseDate = 2416481; - $excel1900isLeapYear = FALSE; - } - - // Julian base date Adjustment - if ($month > 2) { - $month -= 3; - } else { - $month += 9; - --$year; - } - - // Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0) - $century = substr($year,0,2); - $decade = substr($year,2,2); - $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $my_excelBaseDate + $excel1900isLeapYear; - - $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; - - return (float) $excelDate + $excelTime; - } // function FormattedPHPToExcel() - - - /** - * Is a given cell a date/time? - * - * @param PHPExcel_Cell $pCell - * @return boolean - */ - public static function isDateTime(PHPExcel_Cell $pCell) { - return self::isDateTimeFormat( - $pCell->getWorksheet()->getStyle( - $pCell->getCoordinate() - )->getNumberFormat() - ); - } // function isDateTime() - - - /** - * Is a given number format a date/time? - * - * @param PHPExcel_Style_NumberFormat $pFormat - * @return boolean - */ - public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) { - return self::isDateTimeFormatCode($pFormat->getFormatCode()); - } // function isDateTimeFormat() - - - private static $possibleDateFormatCharacters = 'eymdHs'; - - /** - * Is a given number format code a date/time? - * - * @param string $pFormatCode - * @return boolean - */ - public static function isDateTimeFormatCode($pFormatCode = '') { - if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) - // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) - return FALSE; + /** constants */ + const CALENDAR_WINDOWS_1900 = 1900; // Base date of 1st Jan 1900 = 1.0 + const CALENDAR_MAC_1904 = 1904; // Base date of 2nd Jan 1904 = 1.0 + + /* + * Names of the months of the year, indexed by shortname + * Planned usage for locale settings + * + * @public + * @var string[] + */ + public static $monthNames = array( + 'Jan' => 'January', + 'Feb' => 'February', + 'Mar' => 'March', + 'Apr' => 'April', + 'May' => 'May', + 'Jun' => 'June', + 'Jul' => 'July', + 'Aug' => 'August', + 'Sep' => 'September', + 'Oct' => 'October', + 'Nov' => 'November', + 'Dec' => 'December', + ); + + /* + * Names of the months of the year, indexed by shortname + * Planned usage for locale settings + * + * @public + * @var string[] + */ + public static $numberSuffixes = array( + 'st', + 'nd', + 'rd', + 'th', + ); + + /* + * Base calendar year to use for calculations + * + * @private + * @var int + */ + protected static $excelBaseDate = self::CALENDAR_WINDOWS_1900; + + /** + * Set the Excel calendar (Windows 1900 or Mac 1904) + * + * @param integer $baseDate Excel base date (1900 or 1904) + * @return boolean Success or failure + */ + public static function setExcelCalendar($baseDate) + { + if (($baseDate == self::CALENDAR_WINDOWS_1900) || + ($baseDate == self::CALENDAR_MAC_1904)) { + self::$excelBaseDate = $baseDate; + return true; + } + return false; + } + + + /** + * Return the Excel calendar (Windows 1900 or Mac 1904) + * + * @return integer Excel base date (1900 or 1904) + */ + public static function getExcelCalendar() + { + return self::$excelBaseDate; + } + + + /** + * Convert a date from Excel to PHP + * + * @param long $dateValue Excel date/time value + * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as + * a UST timestamp, or adjusted to UST + * @param string $timezone The timezone for finding the adjustment from UST + * @return long PHP serialized date/time + */ + public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = false, $timezone = null) + { + if (self::$excelBaseDate == self::CALENDAR_WINDOWS_1900) { + $myexcelBaseDate = 25569; + // Adjust for the spurious 29-Feb-1900 (Day 60) + if ($dateValue < 60) { + --$myexcelBaseDate; + } + } else { + $myexcelBaseDate = 24107; + } + + // Perform conversion + if ($dateValue >= 1) { + $utcDays = $dateValue - $myexcelBaseDate; + $returnValue = round($utcDays * 86400); + if (($returnValue <= PHP_INT_MAX) && ($returnValue >= -PHP_INT_MAX)) { + $returnValue = (integer) $returnValue; + } + } else { + $hours = round($dateValue * 24); + $mins = round($dateValue * 1440) - round($hours * 60); + $secs = round($dateValue * 86400) - round($hours * 3600) - round($mins * 60); + $returnValue = (integer) gmmktime($hours, $mins, $secs); + } + + $timezoneAdjustment = ($adjustToTimezone) ? + PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone, $returnValue) : + 0; + + return $returnValue + $timezoneAdjustment; + } + + + /** + * Convert a date from Excel to a PHP Date/Time object + * + * @param integer $dateValue Excel date/time value + * @return DateTime PHP date/time object + */ + public static function ExcelToPHPObject($dateValue = 0) + { + $dateTime = self::ExcelToPHP($dateValue); + $days = floor($dateTime / 86400); + $time = round((($dateTime / 86400) - $days) * 86400); + $hours = round($time / 3600); + $minutes = round($time / 60) - ($hours * 60); + $seconds = round($time) - ($hours * 3600) - ($minutes * 60); + + $dateObj = date_create('1-Jan-1970+'.$days.' days'); + $dateObj->setTime($hours,$minutes,$seconds); + + return $dateObj; + } + + + /** + * Convert a date from PHP to Excel + * + * @param mixed $dateValue PHP serialized date/time or date object + * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as + * a UST timestamp, or adjusted to UST + * @param string $timezone The timezone for finding the adjustment from UST + * @return mixed Excel date/time value + * or boolean FALSE on failure + */ + public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $timezone = null) + { + $saveTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $retValue = false; + if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { + $retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), + $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s') + ); + } elseif (is_numeric($dateValue)) { + $retValue = self::FormattedPHPToExcel( date('Y',$dateValue), date('m',$dateValue), date('d',$dateValue), + date('H',$dateValue), date('i',$dateValue), date('s',$dateValue) + ); + } + date_default_timezone_set($saveTimeZone); + + return $retValue; + } + + + /** + * FormattedPHPToExcel + * + * @param long $year + * @param long $month + * @param long $day + * @param long $hours + * @param long $minutes + * @param long $seconds + * @return long Excel date/time value + */ + public static function FormattedPHPToExcel($year, $month, $day, $hours = 0, $minutes = 0, $seconds = 0) + { + if (self::$excelBaseDate == self::CALENDAR_WINDOWS_1900) { + // + // Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel + // This affects every date following 28th February 1900 + // + $excel1900isLeapYear = true; + if (($year == 1900) && ($month <= 2)) { + $excel1900isLeapYear = false; + } + $myexcelBaseDate = 2415020; + } else { + $myexcelBaseDate = 2416481; + $excel1900isLeapYear = false; + } + + // Julian base date Adjustment + if ($month > 2) { + $month -= 3; + } else { + $month += 9; + --$year; + } + + // Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0) + $century = substr($year,0,2); + $decade = substr($year,2,2); + $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $myexcelBaseDate + $excel1900isLeapYear; + + $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; + + return (float) $excelDate + $excelTime; + } + + + /** + * Is a given cell a date/time? + * + * @param PHPExcel_Cell $pCell + * @return boolean + */ + public static function isDateTime(PHPExcel_Cell $pCell) + { + return self::isDateTimeFormat( + $pCell->getWorksheet()->getStyle( + $pCell->getCoordinate() + )->getNumberFormat() + ); + } + + + /** + * Is a given number format a date/time? + * + * @param PHPExcel_Style_NumberFormat $pFormat + * @return boolean + */ + public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) + { + return self::isDateTimeFormatCode($pFormat->getFormatCode()); + } + + + private static $possibleDateFormatCharacters = 'eymdHs'; + + /** + * Is a given number format code a date/time? + * + * @param string $pFormatCode + * @return boolean + */ + public static function isDateTimeFormatCode($pFormatCode = '') + { + if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) + // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) + return false; if (preg_match('/[0#]E[+-]0/i', $pFormatCode)) - // Scientific format - return FALSE; - // Switch on formatcode - switch ($pFormatCode) { - // Explicitly defined date formats - case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYMINUS: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMMINUS: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_MYMINUS: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME1: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME2: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME5: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME6: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME7: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME8: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX14: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17: - case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22: - return TRUE; - } - - // Typically number, currency or accounting (or occasionally fraction) formats - if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) { - return FALSE; - } - // Try checking for any of the date formatting characters that don't appear within square braces - if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) { - // We might also have a format mask containing quoted strings... - // we don't want to test for any of our characters within the quoted blocks - if (strpos($pFormatCode,'"') !== FALSE) { - $segMatcher = FALSE; - foreach(explode('"',$pFormatCode) as $subVal) { - // Only test in alternate array entries (the non-quoted blocks) - if (($segMatcher = !$segMatcher) && - (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$subVal))) { - return TRUE; - } - } - return FALSE; - } - return TRUE; - } - - // No date... - return FALSE; - } // function isDateTimeFormatCode() - - - /** - * Convert a date/time string to Excel time - * - * @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10' - * @return float|FALSE Excel date/time serial value - */ - public static function stringToExcel($dateValue = '') { - if (strlen($dateValue) < 2) - return FALSE; - if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) - return FALSE; - - $dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue); - - if ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) { - return FALSE; - } else { - if (strpos($dateValue, ':') !== FALSE) { - $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue); - if ($timeValue === PHPExcel_Calculation_Functions::VALUE()) { - return FALSE; - } - $dateValueNew += $timeValue; - } - return $dateValueNew; - } - - - } - - public static function monthStringToNumber($month) { + // Scientific format + return false; + // Switch on formatcode + switch ($pFormatCode) { + // Explicitly defined date formats + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_MYMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME1: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME2: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME5: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME6: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME7: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME8: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX14: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22: + return true; + } + + // Typically number, currency or accounting (or occasionally fraction) formats + if ((substr($pFormatCode, 0, 1) == '_') || (substr($pFormatCode, 0, 2) == '0 ')) { + return false; + } + // Try checking for any of the date formatting characters that don't appear within square braces + if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i', $pFormatCode)) { + // We might also have a format mask containing quoted strings... + // we don't want to test for any of our characters within the quoted blocks + if (strpos($pFormatCode, '"') !== false) { + $segMatcher = false; + foreach(explode('"', $pFormatCode) as $subVal) { + // Only test in alternate array entries (the non-quoted blocks) + if (($segMatcher = !$segMatcher) && + (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i', $subVal))) { + return true; + } + } + return false; + } + return true; + } + + // No date... + return false; + } + + + /** + * Convert a date/time string to Excel time + * + * @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10' + * @return float|FALSE Excel date/time serial value + */ + public static function stringToExcel($dateValue = '') + { + if (strlen($dateValue) < 2) + return false; + if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) + return false; + + $dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue); + + if ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) { + return false; + } + + if (strpos($dateValue, ':') !== false) { + $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue); + if ($timeValue === PHPExcel_Calculation_Functions::VALUE()) { + return false; + } + $dateValueNew += $timeValue; + } + return $dateValueNew; + } + + public static function monthStringToNumber($month) + { $monthIndex = 1; - foreach(self::$_monthNames as $shortMonthName => $longMonthName) { + foreach(self::$monthNames as $shortMonthName => $longMonthName) { if (($month === $longMonthName) || ($month === $shortMonthName)) { return $monthIndex; } @@ -382,12 +385,12 @@ public static function monthStringToNumber($month) { return $month; } - public static function dayStringToNumber($day) { - $strippedDayValue = (str_replace(self::$_numberSuffixes,'',$day)); - if (is_numeric($strippedDayValue)) { - return $strippedDayValue; - } - return $day; + public static function dayStringToNumber($day) + { + $strippedDayValue = (str_replace(self::$numberSuffixes, '', $day)); + if (is_numeric($strippedDayValue)) { + return $strippedDayValue; + } + return $day; } - } diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index 4af9c3d13..0bb333e63 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -1,6 +1,12 @@ <?php + +if (!defined('PCLZIP_TEMPORARY_DIR')) { + define('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir() . DIRECTORY_SEPARATOR); +} +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/PCLZip/pclzip.lib.php'; + /** - * PHPExcel + * PHPExcel_Shared_ZipArchive * * Copyright (c) 2006 - 2015 PHPExcel * @@ -21,95 +27,81 @@ * @category PHPExcel * @package PHPExcel_Shared_ZipArchive * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -if (!defined('PCLZIP_TEMPORARY_DIR')) { - define('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir() . DIRECTORY_SEPARATOR); -} -require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/PCLZip/pclzip.lib.php'; - - -/** - * PHPExcel_Shared_ZipArchive - * - * @category PHPExcel - * @package PHPExcel_Shared_ZipArchive - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_ZipArchive { - /** constants */ - const OVERWRITE = 'OVERWRITE'; - const CREATE = 'CREATE'; + /** constants */ + const OVERWRITE = 'OVERWRITE'; + const CREATE = 'CREATE'; - /** - * Temporary storage directory - * - * @var string - */ - private $_tempDir; + /** + * Temporary storage directory + * + * @var string + */ + private $_tempDir; - /** - * Zip Archive Stream Handle - * - * @var string - */ - private $_zip; + /** + * Zip Archive Stream Handle + * + * @var string + */ + private $_zip; /** - * Open a new zip archive - * - * @param string $fileName Filename for the zip archive - * @return boolean + * Open a new zip archive + * + * @param string $fileName Filename for the zip archive + * @return boolean */ - public function open($fileName) - { - $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + public function open($fileName) + { + $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); - $this->_zip = new PclZip($fileName); + $this->_zip = new PclZip($fileName); - return true; - } + return true; + } /** - * Close this zip archive - * + * Close this zip archive + * */ - public function close() - { - } + public function close() + { + } /** - * Add a new file to the zip archive from a string of raw data. - * - * @param string $localname Directory/Name of the file to add to the zip archive - * @param string $contents String of data to add to the zip archive + * Add a new file to the zip archive from a string of raw data. + * + * @param string $localname Directory/Name of the file to add to the zip archive + * @param string $contents String of data to add to the zip archive */ - public function addFromString($localname, $contents) - { - $filenameParts = pathinfo($localname); - - $handle = fopen($this->_tempDir.'/'.$filenameParts["basename"], "wb"); - fwrite($handle, $contents); - fclose($handle); - - $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], - PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, - PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"] - ); - if ($res == 0) { - throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->_zip->errorInfo(true)); - } - - unlink($this->_tempDir.'/'.$filenameParts["basename"]); - } + public function addFromString($localname, $contents) + { + $filenameParts = pathinfo($localname); + + $handle = fopen($this->_tempDir.'/'.$filenameParts["basename"], "wb"); + fwrite($handle, $contents); + fclose($handle); + + $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], + PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, + PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"] + ); + if ($res == 0) { + throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->_zip->errorInfo(true)); + } + + unlink($this->_tempDir.'/'.$filenameParts["basename"]); + } /** * Find if given fileName exist in archive (Emulate ZipArchive locateName()) diff --git a/Classes/PHPExcel/Shared/ZipStreamWrapper.php b/Classes/PHPExcel/Shared/ZipStreamWrapper.php index a5ceb1e4d..358611765 100644 --- a/Classes/PHPExcel/Shared/ZipStreamWrapper.php +++ b/Classes/PHPExcel/Shared/ZipStreamWrapper.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_ZipStreamWrapper * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,21 +25,12 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Shared_ZipStreamWrapper - * - * @category PHPExcel - * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_ZipStreamWrapper { - /** - * Internal ZipAcrhive - * - * @var ZipAcrhive - */ + /** + * Internal ZipAcrhive + * + * @var ZipAcrhive + */ private $_archive; /** @@ -66,18 +58,18 @@ class PHPExcel_Shared_ZipStreamWrapper { * Register wrapper */ public static function register() { - @stream_wrapper_unregister("zip"); - @stream_wrapper_register("zip", __CLASS__); + @stream_wrapper_unregister("zip"); + @stream_wrapper_register("zip", __CLASS__); } /** - * Implements support for fopen(). - * - * @param string $path resource name including scheme, e.g. - * @param string $mode only "r" is supported - * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH - * @param string &$openedPath absolute path of the opened stream (out parameter) - * @return bool true on success + * Implements support for fopen(). + * + * @param string $path resource name including scheme, e.g. + * @param string $mode only "r" is supported + * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH + * @param string &$openedPath absolute path of the opened stream (out parameter) + * @return bool true on success */ public function stream_open($path, $mode, $options, &$opened_path) { // Check for mode @@ -85,9 +77,9 @@ public function stream_open($path, $mode, $options, &$opened_path) { throw new PHPExcel_Reader_Exception('Mode ' . $mode . ' is not supported. Only read mode is supported.'); } - $pos = strrpos($path, '#'); - $url['host'] = substr($path, 6, $pos - 6); // 6: strlen('zip://') - $url['fragment'] = substr($path, $pos + 1); + $pos = strrpos($path, '#'); + $url['host'] = substr($path, 6, $pos - 6); // 6: strlen('zip://') + $url['fragment'] = substr($path, $pos + 1); // Open archive $this->_archive = new ZipArchive(); @@ -101,37 +93,37 @@ public function stream_open($path, $mode, $options, &$opened_path) { } /** - * Implements support for fstat(). - * - * @return boolean + * Implements support for fstat(). + * + * @return boolean */ public function statName() { return $this->_fileNameInArchive; } /** - * Implements support for fstat(). - * - * @return boolean + * Implements support for fstat(). + * + * @return boolean */ public function url_stat() { return $this->statName( $this->_fileNameInArchive ); } /** - * Implements support for fstat(). - * - * @return boolean + * Implements support for fstat(). + * + * @return boolean */ public function stream_stat() { return $this->_archive->statName( $this->_fileNameInArchive ); } /** - * Implements support for fread(), fgets() etc. - * - * @param int $count maximum number of bytes to read - * @return string + * Implements support for fread(), fgets() etc. + * + * @param int $count maximum number of bytes to read + * @return string */ function stream_read($count) { $ret = substr($this->_data, $this->_position, $count); @@ -140,10 +132,10 @@ function stream_read($count) { } /** - * Returns the position of the file pointer, i.e. its offset into the file - * stream. Implements support for ftell(). - * - * @return int + * Returns the position of the file pointer, i.e. its offset into the file + * stream. Implements support for ftell(). + * + * @return int */ public function stream_tell() { return $this->_position; @@ -151,8 +143,8 @@ public function stream_tell() { /** * EOF stream - * - * @return bool + * + * @return bool */ public function stream_eof() { return $this->_position >= strlen($this->_data); @@ -160,10 +152,10 @@ public function stream_eof() { /** * Seek stream - * - * @param int $offset byte offset - * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END - * @return bool + * + * @param int $offset byte offset + * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END + * @return bool */ public function stream_seek($offset, $whence) { switch ($whence) { From 4a977f184896255e7492ec79788adf5c4f947a0f Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 13 May 2015 01:29:12 +0100 Subject: [PATCH 361/467] Fixed merge errors --- Classes/PHPExcel/Calculation.php | 295 ------------------ Classes/PHPExcel/Shared/Date.php | 209 ------------- Classes/PHPExcel/Shared/ZipArchive.php | 26 -- Classes/PHPExcel/Writer/Excel5/BIFFwriter.php | 8 +- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 2 +- 5 files changed, 5 insertions(+), 535 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 8ef43ab34..b054fe2ac 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -3657,301 +3657,6 @@ private function strcmpLowercaseFirst($str1, $str2) return strcmp($inversedStr1, $inversedStr2); } -<<<<<<< HEAD -======= - - private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { - // Validate the two operands - if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; - if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; - - // If either of the operands is a matrix, we need to treat them both as matrices - // (converting the other operand to a matrix if need be); then perform the required - // matrix operation - if ((is_array($operand1)) || (is_array($operand2))) { - // Ensure that both operands are arrays/matrices of the same size - self::_checkMatrixOperands($operand1, $operand2, 2); - - try { - // Convert operand 1 from a PHP array to a matrix - $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); - // Perform the required operation against the operand 1 matrix, passing in operand 2 - $matrixResult = $matrix->$matrixFunction($operand2); - $result = $matrixResult->getArray(); - } catch (PHPExcel_Exception $ex) { - $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); - $result = '#VALUE!'; - } - } else { - if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) && - ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || - (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) { - $result = PHPExcel_Calculation_Functions::VALUE(); - } else { - // If we're dealing with non-matrix operations, execute the necessary operation - switch ($operation) { - // Addition - case '+': - $result = $operand1 + $operand2; - break; - // Subtraction - case '-': - $result = $operand1 - $operand2; - break; - // Multiplication - case '*': - $result = $operand1 * $operand2; - break; - // Division - case '/': - if ($operand2 == 0) { - // Trap for Divide by Zero error - $stack->push('Value','#DIV/0!'); - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); - return FALSE; - } else { - $result = $operand1 / $operand2; - } - break; - // Power - case '^': - $result = pow($operand1, $operand2); - break; - } - } - } - - // Log the result details - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - // And push the result onto the stack - $stack->push('Value',$result); - return TRUE; - } // function _executeNumericBinaryOperation() - - - // trigger an error, but nicely, if need be - protected function _raiseFormulaError($errorMessage) { - $this->formulaError = $errorMessage; - $this->_cyclicReferenceStack->clear(); - if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); - trigger_error($errorMessage, E_USER_ERROR); - } // function _raiseFormulaError() - - - /** - * Extract range values - * - * @param string &$pRange String based range representation - * @param PHPExcel_Worksheet $pSheet Worksheet - * @param boolean $resetLog Flag indicating whether calculation log should be reset or not - * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. - * @throws PHPExcel_Calculation_Exception - */ - public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { - // Return value - $returnValue = array (); - -// echo 'extractCellRange('.$pRange.')',PHP_EOL; - if ($pSheet !== NULL) { - $pSheetName = $pSheet->getTitle(); -// echo 'Passed sheet name is '.$pSheetName.PHP_EOL; -// echo 'Range reference is '.$pRange.PHP_EOL; - if (strpos ($pRange, '!') !== false) { -// echo '$pRange reference includes sheet reference',PHP_EOL; - list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); -// echo 'New sheet name is '.$pSheetName,PHP_EOL; -// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; - $pSheet = $this->_workbook->getSheetByName($pSheetName); - } - - // Extract range - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); - $pRange = $pSheetName.'!'.$pRange; - if (!isset($aReferences[1])) { - // Single cell in range - sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow); - $cellValue = NULL; - if ($pSheet->cellExists($aReferences[0])) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } else { - // Extract cell data for all cells in the range - foreach ($aReferences as $reference) { - // Extract range - sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow); - $cellValue = NULL; - if ($pSheet->cellExists($reference)) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } - } - } - - // Return - return $returnValue; - } // function extractCellRange() - - - /** - * Extract range values - * - * @param string &$pRange String based range representation - * @param PHPExcel_Worksheet $pSheet Worksheet - * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. - * @param boolean $resetLog Flag indicating whether calculation log should be reset or not - * @throws PHPExcel_Calculation_Exception - */ - public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { - // Return value - $returnValue = array (); - -// echo 'extractNamedRange('.$pRange.')<br />'; - if ($pSheet !== NULL) { - $pSheetName = $pSheet->getTitle(); -// echo 'Current sheet name is '.$pSheetName.'<br />'; -// echo 'Range reference is '.$pRange.'<br />'; - if (strpos ($pRange, '!') !== false) { -// echo '$pRange reference includes sheet reference',PHP_EOL; - list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); -// echo 'New sheet name is '.$pSheetName,PHP_EOL; -// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; - $pSheet = $this->_workbook->getSheetByName($pSheetName); - } - - // Named range? - $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet); - if ($namedRange !== NULL) { - $pSheet = $namedRange->getWorksheet(); -// echo 'Named Range '.$pRange.' ('; - $pRange = $namedRange->getRange(); - $splitRange = PHPExcel_Cell::splitRange($pRange); - // Convert row and column references - if (ctype_alpha($splitRange[0][0])) { - $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow(); - } elseif(ctype_digit($splitRange[0][0])) { - $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1]; - } -// echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />'; - -// if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) { -// if (!$namedRange->getLocalOnly()) { -// $pSheet = $namedRange->getWorksheet(); -// } else { -// return $returnValue; -// } -// } - } else { - return PHPExcel_Calculation_Functions::REF(); - } - - // Extract range - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); -// var_dump($aReferences); - if (!isset($aReferences[1])) { - // Single cell (or single column or row) in range - list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); - $cellValue = NULL; - if ($pSheet->cellExists($aReferences[0])) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } else { - // Extract cell data for all cells in the range - foreach ($aReferences as $reference) { - // Extract range - list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference); -// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />'; - $cellValue = NULL; - if ($pSheet->cellExists($reference)) { - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); - } else { - $returnValue[$currentRow][$currentCol] = NULL; - } - } - } -// print_r($returnValue); -// echo '<br />'; - } - - // Return - return $returnValue; - } // function extractNamedRange() - - - /** - * Is a specific function implemented? - * - * @param string $pFunction Function Name - * @return boolean - */ - public function isImplemented($pFunction = '') { - $pFunction = strtoupper ($pFunction); - if (isset(self::$_PHPExcelFunctions[$pFunction])) { - return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); - } else { - return FALSE; - } - } // function isImplemented() - - - /** - * Get a list of all implemented functions as an array of function objects - * - * @return array of PHPExcel_Calculation_Function - */ - public function listFunctions() { - // Return value - $returnValue = array(); - // Loop functions - foreach(self::$_PHPExcelFunctions as $functionName => $function) { - if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { - $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'], - $functionName, - $function['functionCall'] - ); - } - } - - // Return - return $returnValue; - } // function listFunctions() - - - /** - * Get a list of all Excel function names - * - * @return array - */ - public function listAllFunctionNames() { - return array_keys(self::$_PHPExcelFunctions); - } // function listAllFunctionNames() - - /** - * Get a list of implemented Excel function names - * - * @return array - */ - public function listFunctionNames() { - // Return value - $returnValue = array(); - // Loop functions - foreach(self::$_PHPExcelFunctions as $functionName => $function) { - if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { - $returnValue[] = $functionName; - } - } - - // Return - return $returnValue; - } // function listFunctionNames() - -} // class PHPExcel_Calculation ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { // Validate the two operands diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index e6ea4a82e..d0393a411 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -21,20 +21,6 @@ * * @category PHPExcel * @package PHPExcel_Shared -<<<<<<< HEAD -======= - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_Shared_Date - * - * @category PHPExcel - * @package PHPExcel_Shared ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## @@ -52,7 +38,6 @@ class PHPExcel_Shared_Date * @public * @var string[] */ -<<<<<<< HEAD public static $monthNames = array( 'Jan' => 'January', 'Feb' => 'February', @@ -67,21 +52,6 @@ class PHPExcel_Shared_Date 'Nov' => 'November', 'Dec' => 'December', ); -======= - public static $_monthNames = array( 'Jan' => 'January', - 'Feb' => 'February', - 'Mar' => 'March', - 'Apr' => 'April', - 'May' => 'May', - 'Jun' => 'June', - 'Jul' => 'July', - 'Aug' => 'August', - 'Sep' => 'September', - 'Oct' => 'October', - 'Nov' => 'November', - 'Dec' => 'December', - ); ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /* * Names of the months of the year, indexed by shortname @@ -90,20 +60,12 @@ class PHPExcel_Shared_Date * @public * @var string[] */ -<<<<<<< HEAD public static $numberSuffixes = array( 'st', 'nd', 'rd', 'th', ); -======= - public static $_numberSuffixes = array( 'st', - 'nd', - 'rd', - 'th', - ); ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /* * Base calendar year to use for calculations @@ -111,11 +73,7 @@ class PHPExcel_Shared_Date * @private * @var int */ -<<<<<<< HEAD protected static $excelBaseDate = self::CALENDAR_WINDOWS_1900; -======= - protected static $_excelBaseDate = self::CALENDAR_WINDOWS_1900; ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /** * Set the Excel calendar (Windows 1900 or Mac 1904) @@ -123,7 +81,6 @@ class PHPExcel_Shared_Date * @param integer $baseDate Excel base date (1900 or 1904) * @return boolean Success or failure */ -<<<<<<< HEAD public static function setExcelCalendar($baseDate) { if (($baseDate == self::CALENDAR_WINDOWS_1900) || @@ -133,16 +90,6 @@ public static function setExcelCalendar($baseDate) } return false; } -======= - public static function setExcelCalendar($baseDate) { - if (($baseDate == self::CALENDAR_WINDOWS_1900) || - ($baseDate == self::CALENDAR_MAC_1904)) { - self::$_excelBaseDate = $baseDate; - return TRUE; - } - return FALSE; - } // function setExcelCalendar() ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /** @@ -150,16 +97,10 @@ public static function setExcelCalendar($baseDate) { * * @return integer Excel base date (1900 or 1904) */ -<<<<<<< HEAD public static function getExcelCalendar() { return self::$excelBaseDate; } -======= - public static function getExcelCalendar() { - return self::$_excelBaseDate; - } // function getExcelCalendar() ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /** @@ -171,7 +112,6 @@ public static function getExcelCalendar() { * @param string $timezone The timezone for finding the adjustment from UST * @return long PHP serialized date/time */ -<<<<<<< HEAD public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = false, $timezone = null) { if (self::$excelBaseDate == self::CALENDAR_WINDOWS_1900) { @@ -182,26 +122,11 @@ public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = false, $ti } } else { $myexcelBaseDate = 24107; -======= - public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { - if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { - $my_excelBaseDate = 25569; - // Adjust for the spurious 29-Feb-1900 (Day 60) - if ($dateValue < 60) { - --$my_excelBaseDate; - } - } else { - $my_excelBaseDate = 24107; ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b } // Perform conversion if ($dateValue >= 1) { -<<<<<<< HEAD $utcDays = $dateValue - $myexcelBaseDate; -======= - $utcDays = $dateValue - $my_excelBaseDate; ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b $returnValue = round($utcDays * 86400); if (($returnValue <= PHP_INT_MAX) && ($returnValue >= -PHP_INT_MAX)) { $returnValue = (integer) $returnValue; @@ -217,14 +142,8 @@ public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $ti PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone, $returnValue) : 0; -<<<<<<< HEAD return $returnValue + $timezoneAdjustment; } -======= - // Return - return $returnValue + $timezoneAdjustment; - } // function ExcelToPHP() ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /** @@ -233,12 +152,8 @@ public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $ti * @param integer $dateValue Excel date/time value * @return DateTime PHP date/time object */ -<<<<<<< HEAD public static function ExcelToPHPObject($dateValue = 0) { -======= - public static function ExcelToPHPObject($dateValue = 0) { ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b $dateTime = self::ExcelToPHP($dateValue); $days = floor($dateTime / 86400); $time = round((($dateTime / 86400) - $days) * 86400); @@ -250,11 +165,7 @@ public static function ExcelToPHPObject($dateValue = 0) { $dateObj->setTime($hours,$minutes,$seconds); return $dateObj; -<<<<<<< HEAD } -======= - } // function ExcelToPHPObject() ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /** @@ -267,18 +178,11 @@ public static function ExcelToPHPObject($dateValue = 0) { * @return mixed Excel date/time value * or boolean FALSE on failure */ -<<<<<<< HEAD public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $timezone = null) { $saveTimeZone = date_default_timezone_get(); date_default_timezone_set('UTC'); $retValue = false; -======= - public static function PHPToExcel($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { - $saveTimeZone = date_default_timezone_get(); - date_default_timezone_set('UTC'); - $retValue = FALSE; ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { $retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s') @@ -291,11 +195,7 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = FALSE, $ti date_default_timezone_set($saveTimeZone); return $retValue; -<<<<<<< HEAD } -======= - } // function PHPToExcel() ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /** @@ -309,19 +209,13 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = FALSE, $ti * @param long $seconds * @return long Excel date/time value */ -<<<<<<< HEAD public static function FormattedPHPToExcel($year, $month, $day, $hours = 0, $minutes = 0, $seconds = 0) { if (self::$excelBaseDate == self::CALENDAR_WINDOWS_1900) { -======= - public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minutes=0, $seconds=0) { - if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b // // Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel // This affects every date following 28th February 1900 // -<<<<<<< HEAD $excel1900isLeapYear = true; if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = false; @@ -330,14 +224,6 @@ public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minut } else { $myexcelBaseDate = 2416481; $excel1900isLeapYear = false; -======= - $excel1900isLeapYear = TRUE; - if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = FALSE; } - $my_excelBaseDate = 2415020; - } else { - $my_excelBaseDate = 2416481; - $excel1900isLeapYear = FALSE; ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b } // Julian base date Adjustment @@ -351,20 +237,12 @@ public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minut // Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0) $century = substr($year,0,2); $decade = substr($year,2,2); -<<<<<<< HEAD $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $myexcelBaseDate + $excel1900isLeapYear; -======= - $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $my_excelBaseDate + $excel1900isLeapYear; ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; return (float) $excelDate + $excelTime; -<<<<<<< HEAD } -======= - } // function FormattedPHPToExcel() ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /** @@ -373,22 +251,14 @@ public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minut * @param PHPExcel_Cell $pCell * @return boolean */ -<<<<<<< HEAD public static function isDateTime(PHPExcel_Cell $pCell) { -======= - public static function isDateTime(PHPExcel_Cell $pCell) { ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b return self::isDateTimeFormat( $pCell->getWorksheet()->getStyle( $pCell->getCoordinate() )->getNumberFormat() ); -<<<<<<< HEAD } -======= - } // function isDateTime() ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /** @@ -397,16 +267,10 @@ public static function isDateTime(PHPExcel_Cell $pCell) { * @param PHPExcel_Style_NumberFormat $pFormat * @return boolean */ -<<<<<<< HEAD public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) { return self::isDateTimeFormatCode($pFormat->getFormatCode()); } -======= - public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) { - return self::isDateTimeFormatCode($pFormat->getFormatCode()); - } // function isDateTimeFormat() ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b private static $possibleDateFormatCharacters = 'eymdHs'; @@ -417,7 +281,6 @@ public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) { * @param string $pFormatCode * @return boolean */ -<<<<<<< HEAD public static function isDateTimeFormatCode($pFormatCode = '') { if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) @@ -426,15 +289,6 @@ public static function isDateTimeFormatCode($pFormatCode = '') if (preg_match('/[0#]E[+-]0/i', $pFormatCode)) // Scientific format return false; -======= - public static function isDateTimeFormatCode($pFormatCode = '') { - if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) - // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) - return FALSE; - if (preg_match('/[0#]E[+-]0/i', $pFormatCode)) - // Scientific format - return FALSE; ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b // Switch on formatcode switch ($pFormatCode) { // Explicitly defined date formats @@ -460,7 +314,6 @@ public static function isDateTimeFormatCode($pFormatCode = '') { case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16: case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17: case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22: -<<<<<<< HEAD return true; } @@ -489,36 +342,6 @@ public static function isDateTimeFormatCode($pFormatCode = '') { // No date... return false; } -======= - return TRUE; - } - - // Typically number, currency or accounting (or occasionally fraction) formats - if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) { - return FALSE; - } - // Try checking for any of the date formatting characters that don't appear within square braces - if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) { - // We might also have a format mask containing quoted strings... - // we don't want to test for any of our characters within the quoted blocks - if (strpos($pFormatCode,'"') !== FALSE) { - $segMatcher = FALSE; - foreach(explode('"',$pFormatCode) as $subVal) { - // Only test in alternate array entries (the non-quoted blocks) - if (($segMatcher = !$segMatcher) && - (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$subVal))) { - return TRUE; - } - } - return FALSE; - } - return TRUE; - } - - // No date... - return FALSE; - } // function isDateTimeFormatCode() ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /** @@ -527,25 +350,16 @@ public static function isDateTimeFormatCode($pFormatCode = '') { * @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10' * @return float|FALSE Excel date/time serial value */ -<<<<<<< HEAD public static function stringToExcel($dateValue = '') { if (strlen($dateValue) < 2) return false; if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) return false; -======= - public static function stringToExcel($dateValue = '') { - if (strlen($dateValue) < 2) - return FALSE; - if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) - return FALSE; ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b $dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue); if ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) { -<<<<<<< HEAD return false; } @@ -561,24 +375,6 @@ public static function stringToExcel($dateValue = '') { public static function monthStringToNumber($month) { -======= - return FALSE; - } else { - if (strpos($dateValue, ':') !== FALSE) { - $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue); - if ($timeValue === PHPExcel_Calculation_Functions::VALUE()) { - return FALSE; - } - $dateValueNew += $timeValue; - } - return $dateValueNew; - } - - - } - - public static function monthStringToNumber($month) { ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b $monthIndex = 1; foreach(self::$monthNames as $shortMonthName => $longMonthName) { if (($month === $longMonthName) || ($month === $shortMonthName)) { @@ -589,14 +385,9 @@ public static function monthStringToNumber($month) { return $month; } -<<<<<<< HEAD public static function dayStringToNumber($day) { $strippedDayValue = (str_replace(self::$numberSuffixes, '', $day)); -======= - public static function dayStringToNumber($day) { - $strippedDayValue = (str_replace(self::$_numberSuffixes,'',$day)); ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b if (is_numeric($strippedDayValue)) { return $strippedDayValue; } diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index b06bcd623..5fe682973 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -30,34 +30,12 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ -<<<<<<< HEAD -======= - -if (!defined('PCLZIP_TEMPORARY_DIR')) { - define('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir() . DIRECTORY_SEPARATOR); -} -require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/PCLZip/pclzip.lib.php'; - - -/** - * PHPExcel_Shared_ZipArchive - * - * @category PHPExcel - * @package PHPExcel_Shared_ZipArchive - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b class PHPExcel_Shared_ZipArchive { /** constants */ -<<<<<<< HEAD const OVERWRITE = 'OVERWRITE'; const CREATE = 'CREATE'; -======= - const OVERWRITE = 'OVERWRITE'; - const CREATE = 'CREATE'; ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b /** @@ -114,14 +92,10 @@ public function addFromString($localname, $contents) fwrite($handle, $contents); fclose($handle); -<<<<<<< HEAD $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"] ); -======= - $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"]); ->>>>>>> f37630e938da2f1dbe9f16a20fdfbf701403812b if ($res == 0) { throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->_zip->errorInfo(true)); } diff --git a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php index 05ae77fff..62ab5839a 100644 --- a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php +++ b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php @@ -136,7 +136,7 @@ public static function getByteOrder() * @param string $data binary data to append * @access private */ - private function _append($data) + public function _append($data) { if (strlen($data) - 4 > $this->_limit) { $data = $this->_addContinue($data); @@ -169,7 +169,7 @@ public function writeData($data) * 0x0010 Worksheet. * @access private */ - private function _storeBof($type) + public function _storeBof($type) { $record = 0x0809; // Record identifier (BIFF5-BIFF8) $length = 0x0010; @@ -192,7 +192,7 @@ private function _storeBof($type) * * @access private */ - private function _storeEof() + public function _storeEof() { $record = 0x000A; // Record identifier $length = 0x0000; // Number of bytes to follow @@ -226,7 +226,7 @@ public function writeEof() * @return string A very convenient string of continue blocks * @access private */ - private function _addContinue($data) + public function _addContinue($data) { $limit = $this->_limit; $record = 0x003C; // Record identifier diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index 6ea6ca59b..aa4cfbb59 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -1266,7 +1266,7 @@ private function _writeDimensions() $record = 0x0200; // Record identifier $length = 0x000E; - $data = pack('VVvvv', $this->_firstRowIndex, $this->_lastRowIndex + 1, $this->_firstColumnIndex, $this->_lastColumnIndex + 1, 0x0000 // reserved); + $data = pack('VVvvv', $this->_firstRowIndex, $this->_lastRowIndex + 1, $this->_firstColumnIndex, $this->_lastColumnIndex + 1, 0x0000); // reserved $header = pack("vv", $record, $length); $this->_append($header.$data); From e0182578965990b807512545f1fe61e052c18935 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Wed, 13 May 2015 08:02:03 +0200 Subject: [PATCH 362/467] PSR2 : Improve Travis Test --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5c9631565..284b516be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ before_script: script: ## PHP_CodeSniffer - - ./vendor/bin/phpcs Classes/ unitTests/ --standard=PSR2 -n --ignore=Classes/PHPExcel/Shared/PCLZip + - ./vendor/bin/phpcs --report-width=200 --report-summary --report-full Classes/ unitTests/ --standard=PSR2 -n ## PHPUnit - phpunit -c ./unitTests/ From d85222b45adb1d8f297748f0d86458c18889e067 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Wed, 13 May 2015 08:02:23 +0200 Subject: [PATCH 363/467] PSR2 : Improve Travis Test --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5c9631565..284b516be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ before_script: script: ## PHP_CodeSniffer - - ./vendor/bin/phpcs Classes/ unitTests/ --standard=PSR2 -n --ignore=Classes/PHPExcel/Shared/PCLZip + - ./vendor/bin/phpcs --report-width=200 --report-summary --report-full Classes/ unitTests/ --standard=PSR2 -n ## PHPUnit - phpunit -c ./unitTests/ From 06c1ea78dee0a6feb05d377b7296e232fe9e6587 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 13 May 2015 08:32:01 +0100 Subject: [PATCH 364/467] PSR-2 goodness --- Classes/PHPExcel/Writer/OpenDocument/Content.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Classes/PHPExcel/Writer/OpenDocument/Content.php b/Classes/PHPExcel/Writer/OpenDocument/Content.php index 2e1986a7b..a34b1670c 100644 --- a/Classes/PHPExcel/Writer/OpenDocument/Content.php +++ b/Classes/PHPExcel/Writer/OpenDocument/Content.php @@ -105,7 +105,7 @@ public function write(PHPExcel $pPHPExcel = null) $objWriter->startElement('office:body'); $objWriter->startElement('office:spreadsheet'); $objWriter->writeElement('table:calculation-settings'); - $this->_writeSheets($objWriter); + $this->writeSheets($objWriter); $objWriter->writeElement('table:named-expressions'); $objWriter->endElement(); $objWriter->endElement(); @@ -119,7 +119,7 @@ public function write(PHPExcel $pPHPExcel = null) * * @param PHPExcel_Shared_XMLWriter $objWriter */ - private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter) + private function writeSheets(PHPExcel_Shared_XMLWriter $objWriter) { $pPHPExcel = $this->getParentWriter()->getPHPExcel(); /* @var $pPHPExcel PHPExcel */ @@ -132,7 +132,7 @@ private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter) $objWriter->startElement('table:table-column'); $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX); $objWriter->endElement(); - $this->_writeRows($objWriter, $pPHPExcel->getSheet($i)); + $this->writeRows($objWriter, $pPHPExcel->getSheet($i)); $objWriter->endElement(); } } @@ -143,7 +143,7 @@ private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter) * @param PHPExcel_Shared_XMLWriter $objWriter * @param PHPExcel_Worksheet $sheet */ - private function _writeRows(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet $sheet) + private function writeRows(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet $sheet) { $number_rows_repeated = self::NUMBER_ROWS_REPEATED_MAX; $span_row = 0; @@ -164,7 +164,7 @@ private function _writeRows(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Works $span_row = 0; } $objWriter->startElement('table:table-row'); - $this->_writeCells($objWriter, $row); + $this->writeCells($objWriter, $row); $objWriter->endElement(); } else { $span_row++; @@ -180,7 +180,7 @@ private function _writeRows(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Works * @param PHPExcel_Worksheet_Row $row * @throws PHPExcel_Writer_Exception */ - private function _writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet_Row $row) + private function writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet_Row $row) { $number_cols_repeated = self::NUMBER_COLS_REPEATED_MAX; $prev_column = -1; @@ -189,7 +189,7 @@ private function _writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Work $cell = $cells->current(); $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1; - $this->_writeCellSpan($objWriter, $column, $prev_column); + $this->writeCellSpan($objWriter, $column, $prev_column); $objWriter->startElement('table:table-cell'); switch ($cell->getDataType()) { @@ -258,7 +258,7 @@ private function _writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Work * @param integer $curColumn * @param integer $prevColumn */ - private function _writeCellSpan(PHPExcel_Shared_XMLWriter $objWriter, $curColumn, $prevColumn) + private function writeCellSpan(PHPExcel_Shared_XMLWriter $objWriter, $curColumn, $prevColumn) { $diff = $curColumn - $prevColumn - 1; if (1 === $diff) { From 2881bca443861dbc252676dec67d5e4748ddb81a Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Wed, 13 May 2015 12:27:01 +0200 Subject: [PATCH 365/467] PSR-2 : Fixes --- Classes/PHPExcel/Calculation.php | 248 +- Classes/PHPExcel/Calculation/DateTime.php | 2 +- Classes/PHPExcel/Calculation/Engineering.php | 4 +- Classes/PHPExcel/Calculation/MathTrig.php | 2 +- Classes/PHPExcel/Calculation/Statistical.php | 2 +- Classes/PHPExcel/Cell.php | 2 +- Classes/PHPExcel/Chart.php | 155 +- Classes/PHPExcel/Chart/DataSeries.php | 6 +- Classes/PHPExcel/Chart/DataSeriesValues.php | 18 +- Classes/PHPExcel/Chart/Renderer/jpgraph.php | 98 +- Classes/PHPExcel/DocumentProperties.php | 4 +- Classes/PHPExcel/Helper/HTML.php | 4 +- Classes/PHPExcel/IOFactory.php | 2 +- Classes/PHPExcel/NamedRange.php | 2 +- Classes/PHPExcel/Reader/CSV.php | 2 +- Classes/PHPExcel/Reader/Excel2003XML.php | 122 +- Classes/PHPExcel/Reader/Excel2007.php | 56 +- Classes/PHPExcel/Reader/Excel2007/Chart.php | 110 +- Classes/PHPExcel/Reader/Excel2007/Theme.php | 2 +- Classes/PHPExcel/Reader/Excel5.php | 66 +- Classes/PHPExcel/Reader/Gnumeric.php | 68 +- Classes/PHPExcel/Reader/OOCalc.php | 58 +- Classes/PHPExcel/Reader/SYLK.php | 36 +- Classes/PHPExcel/ReferenceHelper.php | 44 +- Classes/PHPExcel/Shared/Date.php | 10 +- Classes/PHPExcel/Shared/Drawing.php | 10 +- Classes/PHPExcel/Shared/File.php | 2 +- .../Shared/JAMA/EigenvalueDecomposition.php | 2 +- .../PHPExcel/Shared/JAMA/LUDecomposition.php | 2 +- Classes/PHPExcel/Shared/JAMA/Matrix.php | 32 +- .../PHPExcel/Shared/JAMA/QRDecomposition.php | 4 +- .../JAMA/SingularValueDecomposition.php | 8 +- Classes/PHPExcel/Shared/OLE.php | 4 +- Classes/PHPExcel/Shared/OLE/PPS.php | 2 +- Classes/PHPExcel/Shared/OLE/PPS/Root.php | 4 +- Classes/PHPExcel/Shared/OLERead.php | 4 +- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 8 +- Classes/PHPExcel/Shared/String.php | 27 +- Classes/PHPExcel/Shared/TimeZone.php | 2 +- Classes/PHPExcel/Shared/XMLWriter.php | 2 +- .../PHPExcel/Shared/trend/bestFitClass.php | 34 +- .../Shared/trend/exponentialBestFitClass.php | 6 +- .../Shared/trend/linearBestFitClass.php | 2 +- .../Shared/trend/logarithmicBestFitClass.php | 2 +- .../Shared/trend/polynomialBestFitClass.php | 14 +- .../Shared/trend/powerBestFitClass.php | 8 +- Classes/PHPExcel/Shared/trend/trendClass.php | 14 +- Classes/PHPExcel/Worksheet.php | 30 +- Classes/PHPExcel/Worksheet/AutoFilter.php | 128 +- .../Worksheet/AutoFilter/Column/Rule.php | 2 +- Classes/PHPExcel/Worksheet/PageSetup.php | 24 +- Classes/PHPExcel/Writer/CSV.php | 46 +- Classes/PHPExcel/Writer/Excel2007.php | 131 +- Classes/PHPExcel/Writer/Excel2007/Chart.php | 2598 ++++++++--------- .../PHPExcel/Writer/Excel2007/Comments.php | 4 +- .../Writer/Excel2007/ContentTypes.php | 110 +- .../PHPExcel/Writer/Excel2007/DocProps.php | 237 +- Classes/PHPExcel/Writer/Excel2007/Drawing.php | 4 +- Classes/PHPExcel/Writer/Excel2007/Rels.php | 16 +- .../PHPExcel/Writer/Excel2007/RelsRibbon.php | 8 +- Classes/PHPExcel/Writer/Excel2007/RelsVBA.php | 4 +- .../PHPExcel/Writer/Excel2007/StringTable.php | 4 +- Classes/PHPExcel/Writer/Excel2007/Style.php | 617 ++-- Classes/PHPExcel/Writer/Excel2007/Theme.php | 156 +- .../PHPExcel/Writer/Excel2007/Workbook.php | 106 +- .../PHPExcel/Writer/Excel2007/Worksheet.php | 24 +- Classes/PHPExcel/Writer/Excel5.php | 29 +- Classes/PHPExcel/Writer/Excel5/Parser.php | 6 +- Classes/PHPExcel/Writer/Excel5/Workbook.php | 2 +- 69 files changed, 2733 insertions(+), 2869 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index b054fe2ac..114d8291e 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -38,7 +38,7 @@ if (!defined('CALCULATION_REGEXP_CELLREF')) { // Test for support of \P (multibyte options) in PCRE - if(defined('PREG_BAD_UTF8_ERROR')) { + if (defined('PREG_BAD_UTF8_ERROR')) { // Cell reference (cell or range of cells, with or without a sheet reference) define('CALCULATION_REGEXP_CELLREF','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})'); // Named Range of cells @@ -1724,7 +1724,7 @@ private function __construct(PHPExcel $workbook = NULL) { $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; $this->_savedPrecision = ini_get('precision'); if ($this->_savedPrecision < $setPrecision) { - ini_set('precision',$setPrecision); + ini_set('precision', $setPrecision); } $this->delta = 1 * pow(10, -$setPrecision); @@ -1740,7 +1740,7 @@ private function __construct(PHPExcel $workbook = NULL) { public function __destruct() { if ($this->_savedPrecision != ini_get('precision')) { - ini_set('precision',$this->_savedPrecision); + ini_set('precision', $this->_savedPrecision); } } @@ -1963,7 +1963,7 @@ public function setLocale($locale = 'en_us') { // Identify our locale and language $language = $locale = strtolower($locale); if (strpos($locale,'_') !== FALSE) { - list($language) = explode('_',$locale); + list($language) = explode('_', $locale); } if (count(self::$_validLocaleLanguages) == 1) @@ -1978,7 +1978,7 @@ public function setLocale($locale = 'en_us') { // Default is English, if user isn't requesting english, then read the necessary data from the locale files if ($locale != 'en_us') { // Search for a file with a list of function names for locale - $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions'; + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR, $locale).DIRECTORY_SEPARATOR.'functions'; if (!file_exists($functionNamesFile)) { // If there isn't a locale specific function file, look for a language specific function file $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions'; @@ -1989,9 +1989,9 @@ public function setLocale($locale = 'en_us') { // Retrieve the list of locale or language specific function names $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($localeFunctions as $localeFunction) { - list($localeFunction) = explode('##',$localeFunction); // Strip out comments + list($localeFunction) = explode('##', $localeFunction); // Strip out comments if (strpos($localeFunction,'=') !== FALSE) { - list($fName,$lfName) = explode('=',$localeFunction); + list($fName, $lfName) = explode('=', $localeFunction); $fName = trim($fName); $lfName = trim($lfName); if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { @@ -2003,16 +2003,16 @@ public function setLocale($locale = 'en_us') { if (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; } if (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; } - $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config'; + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR, $locale).DIRECTORY_SEPARATOR.'config'; if (!file_exists($configFile)) { $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config'; } if (file_exists($configFile)) { $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($localeSettings as $localeSetting) { - list($localeSetting) = explode('##',$localeSetting); // Strip out comments + list($localeSetting) = explode('##', $localeSetting); // Strip out comments if (strpos($localeSetting,'=') !== FALSE) { - list($settingName,$settingValue) = explode('=',$localeSetting); + list($settingName, $settingValue) = explode('=', $localeSetting); $settingName = strtoupper(trim($settingName)); switch ($settingName) { case 'ARGUMENTSEPARATOR' : @@ -2034,10 +2034,10 @@ public function setLocale($locale = 'en_us') { - public static function _translateSeparator($fromSeparator,$toSeparator,$formula,&$inBraces) { + public static function _translateSeparator($fromSeparator, $toSeparator, $formula,&$inBraces) { $strlen = mb_strlen($formula); for ($i = 0; $i < $strlen; ++$i) { - $chr = mb_substr($formula,$i,1); + $chr = mb_substr($formula, $i,1); switch ($chr) { case '{' : $inBraces = TRUE; break; @@ -2045,14 +2045,14 @@ public static function _translateSeparator($fromSeparator,$toSeparator,$formula, break; case $fromSeparator : if (!$inBraces) { - $formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1); + $formula = mb_substr($formula,0, $i).$toSeparator.mb_substr($formula, $i+1); } } } return $formula; } - private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) { + private static function _translateFormula($from, $to, $formula, $fromSeparator, $toSeparator) { // Convert any Excel function names to the required language if (self::$_localeLanguage !== 'en_us') { $inBraces = FALSE; @@ -2060,22 +2060,22 @@ private static function _translateFormula($from,$to,$formula,$fromSeparator,$toS if (strpos($formula,'"') !== FALSE) { // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded // the formula - $temp = explode('"',$formula); + $temp = explode('"', $formula); $i = FALSE; - foreach($temp as &$value) { + foreach ($temp as &$value) { // Only count/replace in alternating array entries if ($i = !$i) { - $value = preg_replace($from,$to,$value); - $value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces); + $value = preg_replace($from, $to, $value); + $value = self::_translateSeparator($fromSeparator, $toSeparator, $value, $inBraces); } } unset($value); // Then rebuild the formula string - $formula = implode('"',$temp); + $formula = implode('"', $temp); } else { // If there's no quoted strings, then we do a simple count/replace - $formula = preg_replace($from,$to,$formula); - $formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces); + $formula = preg_replace($from, $to, $formula); + $formula = self::_translateSeparator($fromSeparator, $toSeparator, $formula, $inBraces); } } @@ -2088,10 +2088,10 @@ private static function _translateFormula($from,$to,$formula,$fromSeparator,$toS public function _translateFormulaToLocale($formula) { if (self::$functionReplaceFromExcel === NULL) { self::$functionReplaceFromExcel = array(); - foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + foreach (array_keys(self::$_localeFunctions) as $excelFunctionName) { self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui'; } - foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + foreach (array_keys(self::$_localeBoolean) as $excelBoolean) { self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; } @@ -2099,15 +2099,15 @@ public function _translateFormulaToLocale($formula) { if (self::$functionReplaceToLocale === NULL) { self::$functionReplaceToLocale = array(); - foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + foreach (array_values(self::$_localeFunctions) as $localeFunctionName) { self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2'; } - foreach(array_values(self::$_localeBoolean) as $localeBoolean) { + foreach (array_values(self::$_localeBoolean) as $localeBoolean) { self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2'; } } - return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator); + return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale, $formula,',',self::$_localeArgumentSeparator); } // function _translateFormulaToLocale() @@ -2117,25 +2117,25 @@ public function _translateFormulaToLocale($formula) { public function _translateFormulaToEnglish($formula) { if (self::$functionReplaceFromLocale === NULL) { self::$functionReplaceFromLocale = array(); - foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + foreach (array_values(self::$_localeFunctions) as $localeFunctionName) { self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui'; } - foreach(array_values(self::$_localeBoolean) as $excelBoolean) { + foreach (array_values(self::$_localeBoolean) as $excelBoolean) { self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; } } if (self::$functionReplaceToExcel === NULL) { self::$functionReplaceToExcel = array(); - foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + foreach (array_keys(self::$_localeFunctions) as $excelFunctionName) { self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2'; } - foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + foreach (array_keys(self::$_localeBoolean) as $excelBoolean) { self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2'; } } - return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,','); + return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel, $formula,self::$_localeArgumentSeparator,','); } // function _translateFormulaToEnglish() @@ -2170,7 +2170,7 @@ public static function _wrapResult($value) { // Return strings wrapped in quotes return '"'.$value.'"'; // Convert numeric errors to NaN error - } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + } else if ((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { return PHPExcel_Calculation_Functions::NaN(); } @@ -2190,7 +2190,7 @@ public static function _unwrapResult($value) { return substr($value,1,-1); } // Convert numeric errors to NaN error - } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + } else if ((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { return PHPExcel_Calculation_Functions::NaN(); } return $value; @@ -2284,7 +2284,7 @@ public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE if ($result === NULL) { return 0; - } elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) { + } elseif ((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) { return PHPExcel_Calculation_Functions::NaN(); } return $result; @@ -2435,33 +2435,33 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC * 1 = shrink to fit * 2 = extend to fit */ - private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) { + private static function _checkMatrixOperands(&$operand1,&$operand2, $resize = 1) { // Examine each of the two operands, and turn them into an array if they aren't one already // Note that this function should only be called if one or both of the operand is already an array if (!is_array($operand1)) { - list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2); - $operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1)); + list($matrixRows, $matrixColumns) = self::_getMatrixDimensions($operand2); + $operand1 = array_fill(0, $matrixRows,array_fill(0, $matrixColumns, $operand1)); $resize = 0; } elseif (!is_array($operand2)) { - list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1); - $operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2)); + list($matrixRows, $matrixColumns) = self::_getMatrixDimensions($operand1); + $operand2 = array_fill(0, $matrixRows,array_fill(0, $matrixColumns, $operand2)); $resize = 0; } - list($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1); - list($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2); + list($matrix1Rows, $matrix1Columns) = self::_getMatrixDimensions($operand1); + list($matrix2Rows, $matrix2Columns) = self::_getMatrixDimensions($operand2); if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { $resize = 1; } if ($resize == 2) { // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger - self::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + self::_resizeMatricesExtend($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); } elseif ($resize == 1) { // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller - self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + self::_resizeMatricesShrink($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); } - return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + return array( $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); } // function _checkMatrixOperands() @@ -2474,8 +2474,8 @@ private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) public static function _getMatrixDimensions(&$matrix) { $matrixRows = count($matrix); $matrixColumns = 0; - foreach($matrix as $rowKey => $rowValue) { - $matrixColumns = max(count($rowValue),$matrixColumns); + foreach ($matrix as $rowKey => $rowValue) { + $matrixColumns = max(count($rowValue), $matrixColumns); if (!is_array($rowValue)) { $matrix[$rowKey] = array($rowValue); } else { @@ -2483,7 +2483,7 @@ public static function _getMatrixDimensions(&$matrix) { } } $matrix = array_values($matrix); - return array($matrixRows,$matrixColumns); + return array($matrixRows, $matrixColumns); } // function _getMatrixDimensions() @@ -2497,7 +2497,7 @@ public static function _getMatrixDimensions(&$matrix) { * @param integer $matrix2Rows Row size of second matrix operand * @param integer $matrix2Columns Column size of second matrix operand */ - private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + private static function _resizeMatricesShrink(&$matrix1,&$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns) { if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { if ($matrix2Rows < $matrix1Rows) { for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { @@ -2540,7 +2540,7 @@ private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$ * @param integer $matrix2Rows Row size of second matrix operand * @param integer $matrix2Columns Column size of second matrix operand */ - private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + private static function _resizeMatricesExtend(&$matrix1,&$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns) { if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { if ($matrix2Columns < $matrix1Columns) { for ($i = 0; $i < $matrix2Rows; ++$i) { @@ -2593,18 +2593,18 @@ private function _showValue($value) { if (is_array($value)) { $returnMatrix = array(); $pad = $rpad = ', '; - foreach($value as $row) { + foreach ($value as $row) { if (is_array($row)) { - $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row)); + $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'), $row)); $rpad = '; '; } else { $returnMatrix[] = $this->_showValue($row); } } - return '{ '.implode($rpad,$returnMatrix).' }'; - } elseif(is_string($value) && (trim($value,'"') == $value)) { + return '{ '.implode($rpad, $returnMatrix).' }'; + } elseif (is_string($value) && (trim($value,'"') == $value)) { return '"'.$value.'"'; - } elseif(is_bool($value)) { + } elseif (is_bool($value)) { return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; } } @@ -2629,11 +2629,11 @@ private function _showTypeDetails($value) { return 'a NULL value'; } elseif (is_float($value)) { $typeString = 'a floating point number'; - } elseif(is_int($value)) { + } elseif (is_int($value)) { $typeString = 'an integer number'; - } elseif(is_bool($value)) { + } elseif (is_bool($value)) { $typeString = 'a boolean'; - } elseif(is_array($value)) { + } elseif (is_array($value)) { $typeString = 'a matrix'; } else { if ($value == '') { @@ -2659,26 +2659,26 @@ private function _convertMatrixReferences($formula) { if (strpos($formula,'"') !== FALSE) { // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded // the formula - $temp = explode('"',$formula); + $temp = explode('"', $formula); // Open and Closed counts used for trapping mismatched braces in the formula $openCount = $closeCount = 0; $i = FALSE; - foreach($temp as &$value) { + foreach ($temp as &$value) { // Only count/replace in alternating array entries if ($i = !$i) { $openCount += substr_count($value,'{'); $closeCount += substr_count($value,'}'); - $value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value); + $value = str_replace($matrixReplaceFrom, $matrixReplaceTo, $value); } } unset($value); // Then rebuild the formula string - $formula = implode('"',$temp); + $formula = implode('"', $temp); } else { // If there's no quoted strings, then we do a simple count/replace $openCount = substr_count($formula,'{'); $closeCount = substr_count($formula,'}'); - $formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula); + $formula = str_replace($matrixReplaceFrom, $matrixReplaceTo, $formula); } // Trap for mismatched braces and trigger an appropriate error if ($openCount < $closeCount) { @@ -2765,7 +2765,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { // should be null in a function call // The guts of the lexical parser // Loop through the formula extracting each operator and operand in turn - while(TRUE) { + while (TRUE) { //echo 'Assessing Expression '.substr($formula, $index),PHP_EOL; $opCharacter = $formula{$index}; // Get the first character of the value at the current index position //echo 'Initial character of expression block is '.$opCharacter,PHP_EOL; @@ -2795,13 +2795,13 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? //echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL; - while($stack->count() > 0 && + while ($stack->count() > 0 && ($o2 = $stack->last()) && isset(self::$_operators[$o2['value']]) && @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } - $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack + $stack->push('Binary Operator', $opCharacter); // Finally put our current operator onto the stack ++$index; $expectingOperator = FALSE; @@ -2855,7 +2855,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { } } } elseif ($expectedArgumentCount != '*') { - $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch); + $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/', $expectedArgumentCount, $argMatch); //print_r($argMatch); //echo PHP_EOL; switch ($argMatch[2]) { @@ -2901,7 +2901,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) return $this->_raiseFormulaError("Formula Error: Unexpected ,"); $d = $stack->pop(); - $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count + $stack->push($d['type'],++$d['value'], $d['reference']); // increment the argument count $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again $expectingOperator = FALSE; $expectingOperand = TRUE; @@ -2920,7 +2920,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { // echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />'; if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { - $val = preg_replace('/\s/u','',$val); + $val = preg_replace('/\s/u','', $val); // echo 'Element '.$val.' is a Function<br />'; if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function $stack->push('Function', strtoupper($val)); @@ -2967,13 +2967,13 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { if ($testPrevOp['value'] == ':') { $startRowColRef = $output[count($output)-1]['value']; $rangeWS1 = ''; - if (strpos('!',$startRowColRef) !== FALSE) { - list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef); + if (strpos('!', $startRowColRef) !== FALSE) { + list($rangeWS1, $startRowColRef) = explode('!', $startRowColRef); } if ($rangeWS1 != '') $rangeWS1 .= '!'; $rangeWS2 = $rangeWS1; - if (strpos('!',$val) !== FALSE) { - list($rangeWS2,$val) = explode('!',$val); + if (strpos('!', $val) !== FALSE) { + list($rangeWS2, $val) = explode('!', $val); } if ($rangeWS2 != '') $rangeWS2 .= '!'; if ((is_integer($startRowColRef)) && (ctype_digit($val)) && @@ -3058,7 +3058,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) && ($output[count($output)-1]['type'] == 'Cell Reference')) { // echo 'Element is an Intersect Operator<br />'; - while($stack->count() > 0 && + while ($stack->count() > 0 && ($o2 = $stack->last()) && isset(self::$_operators[$o2['value']]) && @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { @@ -3136,18 +3136,18 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel case '<=' : // Less than or Equal to case '=' : // Equality case '<>' : // Inequality - $this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack); + $this->_executeBinaryComparisonOperation($cellID, $operand1, $operand2, $token, $stack); break; // Binary Operators case ':' : // Range $sheet1 = $sheet2 = ''; if (strpos($operand1Data['reference'],'!') !== FALSE) { - list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']); + list($sheet1, $operand1Data['reference']) = explode('!', $operand1Data['reference']); } else { $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : ''; } if (strpos($operand2Data['reference'],'!') !== FALSE) { - list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']); + list($sheet2, $operand2Data['reference']) = explode('!', $operand2Data['reference']); } else { $sheet2 = $sheet1; } @@ -3171,9 +3171,9 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } } - $oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference'])); + $oData = array_merge(explode(':', $operand1Data['reference']),explode(':', $operand2Data['reference'])); $oCol = $oRow = array(); - foreach($oData as $oDatum) { + foreach ($oData as $oDatum) { $oCR = PHPExcel_Cell::coordinateFromString($oDatum); $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1; $oRow[] = $oCR[1]; @@ -3184,26 +3184,26 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } - $stack->push('Cell Reference',$cellValue,$cellRef); + $stack->push('Cell Reference', $cellValue, $cellRef); } else { $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL); } break; case '+' : // Addition - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack); + $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token,'plusEquals', $stack); break; case '-' : // Subtraction - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack); + $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token,'minusEquals', $stack); break; case '*' : // Multiplication - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack); + $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token,'arrayTimesEquals', $stack); break; case '/' : // Division - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack); + $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token,'arrayRightDivide', $stack); break; case '^' : // Exponential - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack); + $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token,'power', $stack); break; case '&' : // Concatenation // If either of the operands is a matrix, we need to treat them both as matrices @@ -3217,7 +3217,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } if ((is_array($operand1)) || (is_array($operand2))) { // Ensure that both operands are arrays/matrices - self::_checkMatrixOperands($operand1,$operand2,2); + self::_checkMatrixOperands($operand1, $operand2,2); try { // Convert operand 1 from a PHP array to a matrix $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); @@ -3232,21 +3232,21 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"'; } $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - $stack->push('Value',$result); + $stack->push('Value', $result); break; case '|' : // Intersect - $rowIntersect = array_intersect_key($operand1,$operand2); + $rowIntersect = array_intersect_key($operand1, $operand2); $cellIntersect = $oCol = $oRow = array(); - foreach(array_keys($rowIntersect) as $row) { + foreach (array_keys($rowIntersect) as $row) { $oRow[] = $row; - foreach($rowIntersect[$row] as $col => $data) { + foreach ($rowIntersect[$row] as $col => $data) { $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1; - $cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]); + $cellIntersect[$row] = array_intersect_key($operand1[$row], $operand2[$row]); } } $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); - $stack->push('Value',$cellIntersect,$cellRef); + $stack->push('Value', $cellIntersect, $cellRef); break; } @@ -3265,7 +3265,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $multiplier = 0.01; } if (is_array($arg)) { - self::_checkMatrixOperands($arg,$multiplier,2); + self::_checkMatrixOperands($arg, $multiplier,2); try { $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg); $matrixResult = $matrix1->arrayTimesEquals($multiplier); @@ -3275,9 +3275,9 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $result = '#VALUE!'; } $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - $stack->push('Value',$result); + $stack->push('Value', $result); } else { - $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack); + $this->_executeNumericBinaryOperation($cellID, $multiplier, $arg,'*','arrayTimesEquals', $stack); } } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { @@ -3358,7 +3358,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } } } - $stack->push('Value',$cellValue,$cellRef); + $stack->push('Value', $cellValue, $cellRef); // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) { @@ -3421,18 +3421,18 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1)); // $result = array(); // $row = 0; -// foreach($operand1 as $args) { +// foreach ($operand1 as $args) { // if (is_array($args)) { -// foreach($args as $arg) { +// foreach ($args as $arg) { // $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); -// $r = call_user_func_array($functionCall,$arg); +// $r = call_user_func_array($functionCall, $arg); // $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); // $result[$row][] = $r; // } // ++$row; // } else { // $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); -// $r = call_user_func_array($functionCall,$args); +// $r = call_user_func_array($functionCall, $args); // $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); // $result[] = $r; // } @@ -3443,13 +3443,13 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $args[] = $pCell; } if (strpos($functionCall,'::') !== FALSE) { - $result = call_user_func_array(explode('::',$functionCall),$args); + $result = call_user_func_array(explode('::', $functionCall), $args); } else { - foreach($args as &$arg) { + foreach ($args as &$arg) { $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg); } unset($arg); - $result = call_user_func_array($functionCall,$args); + $result = call_user_func_array($functionCall, $args); } // } if ($functionName != 'MKMATRIX') { @@ -3467,7 +3467,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { // echo 'Token is a number, boolean, string, null or an Excel error<br />'; - $stack->push('Value',$token); + $stack->push('Value', $token); // if the token is a named range, push the named range name onto the stack } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) { // echo 'Token is a named range<br />'; @@ -3477,7 +3477,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE); $pCell->attach($pCellParent); $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); - $stack->push('Named Range',$cellValue,$namedRange); + $stack->push('Named Range', $cellValue, $namedRange); } else { return $this->_raiseFormulaError("undefined variable '$token'"); } @@ -3534,24 +3534,24 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 if ((is_array($operand1)) || (is_array($operand2))) { $result = array(); if ((is_array($operand1)) && (!is_array($operand2))) { - foreach($operand1 as $x => $operandData) { + foreach ($operand1 as $x => $operandData) { $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); - $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack); + $this->_executeBinaryComparisonOperation($cellID, $operandData, $operand2, $operation, $stack); $r = $stack->pop(); $result[$x] = $r['value']; } } elseif ((!is_array($operand1)) && (is_array($operand2))) { - foreach($operand2 as $x => $operandData) { + foreach ($operand2 as $x => $operandData) { $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); - $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack); + $this->_executeBinaryComparisonOperation($cellID, $operand1, $operandData, $operation, $stack); $r = $stack->pop(); $result[$x] = $r['value']; } } else { - if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } - foreach($operand1 as $x => $operandData) { + if (!$recursingArrays) { self::_checkMatrixOperands($operand1, $operand2,2); } + foreach ($operand1 as $x => $operandData) { $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); - $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); + $this->_executeBinaryComparisonOperation($cellID, $operandData, $operand2[$x], $operation, $stack,TRUE); $r = $stack->pop(); $result[$x] = $r['value']; } @@ -3559,7 +3559,7 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 // Log the result details $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack - $stack->push('Array',$result); + $stack->push('Array', $result); return TRUE; } @@ -3640,7 +3640,7 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 // Log the result details $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack - $stack->push('Value',$result); + $stack->push('Value', $result); return true; } @@ -3658,10 +3658,10 @@ private function strcmpLowercaseFirst($str1, $str2) return strcmp($inversedStr1, $inversedStr2); } - private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { + private function _executeNumericBinaryOperation($cellID, $operand1, $operand2, $operation, $matrixFunction,&$stack) { // Validate the two operands - if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; - if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; + if (!$this->_validateBinaryOperand($cellID, $operand1, $stack)) return FALSE; + if (!$this->_validateBinaryOperand($cellID, $operand2, $stack)) return FALSE; // If either of the operands is a matrix, we need to treat them both as matrices // (converting the other operand to a matrix if need be); then perform the required @@ -3722,7 +3722,7 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope // Log the result details $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack - $stack->push('Value',$result); + $stack->push('Value', $result); return TRUE; } // function _executeNumericBinaryOperation() @@ -3756,7 +3756,7 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = N // echo 'Range reference is '.$pRange.PHP_EOL; if (strpos ($pRange, '!') !== false) { // echo '$pRange reference includes sheet reference',PHP_EOL; - list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); + list($pSheetName, $pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); // echo 'New sheet name is '.$pSheetName,PHP_EOL; // echo 'Adjusted Range reference is '.$pRange,PHP_EOL; $pSheet = $this->_workbook->getSheetByName($pSheetName); @@ -3814,7 +3814,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = // echo 'Range reference is '.$pRange.'<br />'; if (strpos ($pRange, '!') !== false) { // echo '$pRange reference includes sheet reference',PHP_EOL; - list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); + list($pSheetName, $pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); // echo 'New sheet name is '.$pSheetName,PHP_EOL; // echo 'Adjusted Range reference is '.$pRange,PHP_EOL; $pSheet = $this->_workbook->getSheetByName($pSheetName); @@ -3830,7 +3830,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = // Convert row and column references if (ctype_alpha($splitRange[0][0])) { $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow(); - } elseif(ctype_digit($splitRange[0][0])) { + } elseif (ctype_digit($splitRange[0][0])) { $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1]; } // echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />'; @@ -3851,7 +3851,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = // var_dump($aReferences); if (!isset($aReferences[1])) { // Single cell (or single column or row) in range - list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); + list($currentCol, $currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); $cellValue = NULL; if ($pSheet->cellExists($aReferences[0])) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); @@ -3862,7 +3862,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = // Extract cell data for all cells in the range foreach ($aReferences as $reference) { // Extract range - list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference); + list($currentCol, $currentRow) = PHPExcel_Cell::coordinateFromString($reference); // echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />'; $cellValue = NULL; if ($pSheet->cellExists($reference)) { @@ -3906,7 +3906,7 @@ public function listFunctions() { // Return value $returnValue = array(); // Loop functions - foreach(self::$_PHPExcelFunctions as $functionName => $function) { + foreach (self::$_PHPExcelFunctions as $functionName => $function) { if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'], $functionName, @@ -3938,7 +3938,7 @@ public function listFunctionNames() { // Return value $returnValue = array(); // Loop functions - foreach(self::$_PHPExcelFunctions as $functionName => $function) { + foreach (self::$_PHPExcelFunctions as $functionName => $function) { if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { $returnValue[] = $functionName; } diff --git a/Classes/PHPExcel/Calculation/DateTime.php b/Classes/PHPExcel/Calculation/DateTime.php index 359f6ef5c..72f4c7a23 100644 --- a/Classes/PHPExcel/Calculation/DateTime.php +++ b/Classes/PHPExcel/Calculation/DateTime.php @@ -847,7 +847,7 @@ public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) } if (((is_numeric($method)) && (!is_string($method))) || ($method == '')) { - switch($method) { + switch ($method) { case 0: return self::DAYS360($startDate, $endDate) / 360; case 1: diff --git a/Classes/PHPExcel/Calculation/Engineering.php b/Classes/PHPExcel/Calculation/Engineering.php index 8c027d12b..75e278474 100644 --- a/Classes/PHPExcel/Calculation/Engineering.php +++ b/Classes/PHPExcel/Calculation/Engineering.php @@ -1019,7 +1019,7 @@ public static function BESSELK($x, $ord) return PHPExcel_Calculation_Functions::NaN(); } - switch(floor($ord)) { + switch (floor($ord)) { case 0: return self::besselK0($x); case 1: @@ -1103,7 +1103,7 @@ public static function BESSELY($x, $ord) return PHPExcel_Calculation_Functions::NaN(); } - switch(floor($ord)) { + switch (floor($ord)) { case 0: return self::besselY0($x); case 1: diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index d062d032f..9d5a439e6 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -1120,7 +1120,7 @@ public static function SUBTOTAL() $subtotal = array_shift($aArgs); if ((is_numeric($subtotal)) && (!is_string($subtotal))) { - switch($subtotal) { + switch ($subtotal) { case 1: return PHPExcel_Calculation_Statistical::AVERAGE($aArgs); case 2: diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php index 11e54a5e4..cd43dd6c7 100644 --- a/Classes/PHPExcel/Calculation/Statistical.php +++ b/Classes/PHPExcel/Calculation/Statistical.php @@ -3452,7 +3452,7 @@ public static function TREND($yValues, $xValues = array(), $newValues = array(), * of a data set. * * Excel Function: - * TRIMEAN(value1[,value2[, ...]],$discard) + * TRIMEAN(value1[,value2[, ...]], $discard) * * @access public * @category Statistical Functions diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 4ca7e5321..a60298ee3 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -584,7 +584,7 @@ public function isInRange($pRange = 'A1:A1') public static function coordinateFromString($pCoordinateString = 'A1') { if (preg_match("/^([$]?[A-Z]{1,3})([$]?\d{1,7})$/", $pCoordinateString, $matches)) { - return array($matches[1],$matches[2]); + return array($matches[1], $matches[2]); } elseif ((strpos($pCoordinateString,':') !== false) || (strpos($pCoordinateString,',') !== false)) { throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); } elseif ($pCoordinateString == '') { diff --git a/Classes/PHPExcel/Chart.php b/Classes/PHPExcel/Chart.php index c8d96529a..326eac547 100644 --- a/Classes/PHPExcel/Chart.php +++ b/Classes/PHPExcel/Chart.php @@ -90,33 +90,33 @@ class PHPExcel_Chart */ private $_displayBlanksAs = '0'; - /** - * Chart Asix Y as - * - * @var PHPExcel_Chart_Axis - */ - private $_yAxis = null; - - /** - * Chart Asix X as - * - * @var PHPExcel_Chart_Axis - */ - private $_xAxis = null; - - /** - * Chart Major Gridlines as - * - * @var PHPExcel_Chart_GridLines - */ - private $_majorGridlines = null; - - /** - * Chart Minor Gridlines as - * - * @var PHPExcel_Chart_GridLines - */ - private $_minorGridlines = null; + /** + * Chart Asix Y as + * + * @var PHPExcel_Chart_Axis + */ + private $_yAxis = null; + + /** + * Chart Asix X as + * + * @var PHPExcel_Chart_Axis + */ + private $_xAxis = null; + + /** + * Chart Major Gridlines as + * + * @var PHPExcel_Chart_GridLines + */ + private $_majorGridlines = null; + + /** + * Chart Minor Gridlines as + * + * @var PHPExcel_Chart_GridLines + */ + private $_minorGridlines = null; /** * Top-Left Cell Position @@ -304,7 +304,8 @@ public function getYAxisLabel() * @param PHPExcel_Chart_Title $label * @return PHPExcel_Chart */ - public function setYAxisLabel(PHPExcel_Chart_Title $label) { + public function setYAxisLabel(PHPExcel_Chart_Title $label) + { $this->_yAxisLabel = $label; return $this; @@ -365,62 +366,62 @@ public function setDisplayBlanksAs($displayBlanksAs = '0') } - /** - * Get yAxis - * - * @return PHPExcel_Chart_Axis - */ - public function getChartAxisY() - { - if ($this->_yAxis !== null) { - return $this->_yAxis; + /** + * Get yAxis + * + * @return PHPExcel_Chart_Axis + */ + public function getChartAxisY() + { + if ($this->_yAxis !== null) { + return $this->_yAxis; + } + + return new PHPExcel_Chart_Axis(); } - return new PHPExcel_Chart_Axis(); - } + /** + * Get xAxis + * + * @return PHPExcel_Chart_Axis + */ + public function getChartAxisX() + { + if ($this->_xAxis !== null) { + return $this->_xAxis; + } - /** - * Get xAxis - * - * @return PHPExcel_Chart_Axis - */ - public function getChartAxisX() - { - if ($this->_xAxis !== null) { - return $this->_xAxis; + return new PHPExcel_Chart_Axis(); } - return new PHPExcel_Chart_Axis(); - } + /** + * Get Major Gridlines + * + * @return PHPExcel_Chart_GridLines + */ + public function getMajorGridlines() + { + if ($this->_majorGridlines !== null) { + return $this->_majorGridlines; + } - /** - * Get Major Gridlines - * - * @return PHPExcel_Chart_GridLines - */ - public function getMajorGridlines() - { - if ($this->_majorGridlines !== null) { - return $this->_majorGridlines; + return new PHPExcel_Chart_GridLines(); } - return new PHPExcel_Chart_GridLines(); - } + /** + * Get Minor Gridlines + * + * @return PHPExcel_Chart_GridLines + */ + public function getMinorGridlines() + { + if ($this->_minorGridlines !== null) { + return $this->_minorGridlines; + } - /** - * Get Minor Gridlines - * - * @return PHPExcel_Chart_GridLines - */ - public function getMinorGridlines() - { - if ($this->_minorGridlines !== null) { - return $this->_minorGridlines; + return new PHPExcel_Chart_GridLines(); } - return new PHPExcel_Chart_GridLines(); - } - /** * Set the Top Left position for the chart @@ -430,7 +431,7 @@ public function getMinorGridlines() * @param integer $yOffset * @return PHPExcel_Chart */ - public function setTopLeftPosition($cell, $xOffset=null, $yOffset=null) + public function setTopLeftPosition($cell, $xOffset = null, $yOffset = null) { $this->_topLeftCellRef = $cell; if (!is_null($xOffset)) { @@ -662,9 +663,9 @@ public function render($outputDestination = null) $this->refresh(); $libraryPath = PHPExcel_Settings::getChartRendererPath(); - $includePath = str_replace('\\','/',get_include_path()); - $rendererPath = str_replace('\\','/',$libraryPath); - if (strpos($rendererPath,$includePath) === false) { + $includePath = str_replace('\\', '/', get_include_path()); + $rendererPath = str_replace('\\', '/', $libraryPath); + if (strpos($rendererPath, $includePath) === false) { set_include_path(get_include_path() . PATH_SEPARATOR . $libraryPath); } diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index c5ddc0955..5ded0d875 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -371,17 +371,17 @@ public function setSmoothLine($smoothLine = true) public function refresh(PHPExcel_Worksheet $worksheet) { - foreach($this->_plotValues as $plotValues) { + foreach ($this->_plotValues as $plotValues) { if ($plotValues !== null) { $plotValues->refresh($worksheet, true); } } - foreach($this->_plotLabel as $plotValues) { + foreach ($this->_plotLabel as $plotValues) { if ($plotValues !== null) { $plotValues->refresh($worksheet, true); } } - foreach($this->_plotCategory as $plotValues) { + foreach ($this->_plotCategory as $plotValues) { if ($plotValues !== null) { $plotValues->refresh($worksheet, false); } diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index a14b47a18..01f0010eb 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -215,7 +215,7 @@ public function isMultiLevelSeries() { */ public function multiLevelCount() { $levelCount = 0; - foreach($this->_dataValues as $dataValueSet) { + foreach ($this->_dataValues as $dataValueSet) { $levelCount = max($levelCount,count($dataValueSet)); } return $levelCount; @@ -281,31 +281,31 @@ public function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) { ); if ($flatten) { $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); - foreach($this->_dataValues as &$dataValue) { + foreach ($this->_dataValues as &$dataValue) { if ((!empty($dataValue)) && ($dataValue[0] == '#')) { $dataValue = 0.0; } } unset($dataValue); } else { - $cellRange = explode('!',$this->_dataSource); + $cellRange = explode('!', $this->_dataSource); if (count($cellRange) > 1) { - list(,$cellRange) = $cellRange; + list(, $cellRange) = $cellRange; } - $dimensions = PHPExcel_Cell::rangeDimension(str_replace('$','',$cellRange)); + $dimensions = PHPExcel_Cell::rangeDimension(str_replace('$','', $cellRange)); if (($dimensions[0] == 1) || ($dimensions[1] == 1)) { $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); } else { $newArray = array_values(array_shift($newDataValues)); - foreach($newArray as $i => $newDataSet) { + foreach ($newArray as $i => $newDataSet) { $newArray[$i] = array($newDataSet); } - foreach($newDataValues as $newDataSet) { + foreach ($newDataValues as $newDataSet) { $i = 0; - foreach($newDataSet as $newDataVal) { - array_unshift($newArray[$i++],$newDataVal); + foreach ($newDataSet as $newDataVal) { + array_unshift($newArray[$i++], $newDataVal); } } $this->_dataValues = $newArray; diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index 5994db37b..2b49e651a 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -71,7 +71,7 @@ class PHPExcel_Chart_Renderer_jpgraph private static $_plotMark = 0; - private function _formatPointMarker($seriesPlot,$markerID) { + private function _formatPointMarker($seriesPlot, $markerID) { $plotMarkKeys = array_keys(self::$_markSet); if (is_null($markerID)) { // Use default plot marker (next marker in the series) @@ -106,18 +106,18 @@ private function _formatDataSetLabels($groupID, $datasetLabels, $labelCount, $ro } $testCurrentIndex = 0; - foreach($datasetLabels as $i => $datasetLabel) { + foreach ($datasetLabels as $i => $datasetLabel) { if (is_array($datasetLabel)) { if ($rotation == 'bar') { - $datasetLabels[$i] = implode(" ",$datasetLabel); + $datasetLabels[$i] = implode(" ", $datasetLabel); } else { $datasetLabel = array_reverse($datasetLabel); - $datasetLabels[$i] = implode("\n",$datasetLabel); + $datasetLabels[$i] = implode("\n", $datasetLabel); } } else { // Format labels according to any formatting code if (!is_null($datasetLabelFormatCode)) { - $datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel,$datasetLabelFormatCode); + $datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel, $datasetLabelFormatCode); } } ++$testCurrentIndex; @@ -127,14 +127,14 @@ private function _formatDataSetLabels($groupID, $datasetLabels, $labelCount, $ro } // function _formatDataSetLabels() - private function _percentageSumCalculation($groupID,$seriesCount) { + private function _percentageSumCalculation($groupID, $seriesCount) { // Adjust our values to a percentage value across all series in the group for($i = 0; $i < $seriesCount; ++$i) { if ($i == 0) { $sumValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); } else { $nextValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - foreach($nextValues as $k => $value) { + foreach ($nextValues as $k => $value) { if (isset($sumValues[$k])) { $sumValues[$k] += $value; } else { @@ -148,8 +148,8 @@ private function _percentageSumCalculation($groupID,$seriesCount) { } // function _percentageSumCalculation() - private function _percentageAdjustValues($dataValues,$sumValues) { - foreach($dataValues as $k => $dataValue) { + private function _percentageAdjustValues($dataValues, $sumValues) { + foreach ($dataValues as $k => $dataValue) { $dataValues[$k] = $dataValue / $sumValues[$k] * 100; } @@ -165,7 +165,7 @@ private function _getCaption($captionElement) { // If we do, it could be a plain string or an array if (is_array($caption)) { // Implode an array to a plain string - $caption = implode('',$caption); + $caption = implode('', $caption); } } return $caption; @@ -276,7 +276,7 @@ private function _renderPlotLine($groupID, $filled = false, $combination = false $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); $seriesPlots = array(); if ($grouping == 'percentStacked') { - $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount); + $sumValues = $this->_percentageSumCalculation($groupID, $seriesCount); } // Loop through each data series in turn @@ -285,13 +285,13 @@ private function _renderPlotLine($groupID, $filled = false, $combination = false $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); if ($grouping == 'percentStacked') { - $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues); + $dataValues = $this->_percentageAdjustValues($dataValues, $sumValues); } // Fill in any missing values in the $dataValues array $testCurrentIndex = 0; - foreach($dataValues as $k => $dataValue) { - while($k != $testCurrentIndex) { + foreach ($dataValues as $k => $dataValue) { + while ($k != $testCurrentIndex) { $dataValues[$testCurrentIndex] = null; ++$testCurrentIndex; } @@ -309,7 +309,7 @@ private function _renderPlotLine($groupID, $filled = false, $combination = false $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); } else { // Set the appropriate plot marker - $this->_formatPointMarker($seriesPlot,$marker); + $this->_formatPointMarker($seriesPlot, $marker); } $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); $seriesPlot->SetLegend($dataLabel); @@ -352,20 +352,20 @@ private function _renderPlotBar($groupID, $dimensions = '2d') { $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); $seriesPlots = array(); if ($grouping == 'percentStacked') { - $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount); + $sumValues = $this->_percentageSumCalculation($groupID, $seriesCount); } // Loop through each data series in turn for($j = 0; $j < $seriesCount; ++$j) { $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); if ($grouping == 'percentStacked') { - $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues); + $dataValues = $this->_percentageAdjustValues($dataValues, $sumValues); } // Fill in any missing values in the $dataValues array $testCurrentIndex = 0; - foreach($dataValues as $k => $dataValue) { - while($k != $testCurrentIndex) { + foreach ($dataValues as $k => $dataValue) { + while ($k != $testCurrentIndex) { $dataValues[$testCurrentIndex] = null; ++$testCurrentIndex; } @@ -411,7 +411,7 @@ private function _renderPlotBar($groupID, $dimensions = '2d') { } // function _renderPlotBar() - private function _renderPlotScatter($groupID,$bubble) { + private function _renderPlotScatter($groupID, $bubble) { $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); $scatterStyle = $bubbleSize = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); @@ -423,18 +423,18 @@ private function _renderPlotScatter($groupID,$bubble) { $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - foreach($dataValuesY as $k => $dataValueY) { + foreach ($dataValuesY as $k => $dataValueY) { $dataValuesY[$k] = $k; } - $seriesPlot = new ScatterPlot($dataValuesX,$dataValuesY); + $seriesPlot = new ScatterPlot($dataValuesX, $dataValuesY); if ($scatterStyle == 'lineMarker') { $seriesPlot->SetLinkPoints(); $seriesPlot->link->SetColor(self::$_colourSet[self::$_plotColour]); } elseif ($scatterStyle == 'smoothMarker') { - $spline = new Spline($dataValuesY,$dataValuesX); - list($splineDataY,$splineDataX) = $spline->Get(count($dataValuesX) * self::$_width / 20); - $lplot = new LinePlot($splineDataX,$splineDataY); + $spline = new Spline($dataValuesY, $dataValuesX); + list($splineDataY, $splineDataX) = $spline->Get(count($dataValuesX) * self::$_width / 20); + $lplot = new LinePlot($splineDataX, $splineDataY); $lplot->SetColor(self::$_colourSet[self::$_plotColour]); $this->_graph->Add($lplot); @@ -446,7 +446,7 @@ private function _renderPlotScatter($groupID,$bubble) { $seriesPlot->mark->SetSize($bubbleSize); } else { $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - $this->_formatPointMarker($seriesPlot,$marker); + $this->_formatPointMarker($seriesPlot, $marker); } $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); $seriesPlot->SetLegend($dataLabel); @@ -469,7 +469,7 @@ private function _renderPlotRadar($groupID) { $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); $dataValues = array(); - foreach($dataValuesY as $k => $dataValueY) { + foreach ($dataValuesY as $k => $dataValueY) { $dataValues[$k] = implode(' ',array_reverse($dataValueY)); } $tmp = array_shift($dataValues); @@ -486,7 +486,7 @@ private function _renderPlotRadar($groupID) { if ($radarStyle == 'filled') { $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour]); } - $this->_formatPointMarker($seriesPlot,$marker); + $this->_formatPointMarker($seriesPlot, $marker); $seriesPlot->SetLegend($dataLabel); $this->_graph->Add($seriesPlot); @@ -520,13 +520,13 @@ private function _renderPlotStock($groupID) { $dataValues = array(); // Loop through each data series in turn and build the plot arrays - foreach($plotOrder as $i => $v) { + foreach ($plotOrder as $i => $v) { $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); - foreach($dataValuesX as $j => $dataValueX) { + foreach ($dataValuesX as $j => $dataValueX) { $dataValues[$plotOrder[$i]][$j] = $dataValueX; } } - if(empty($dataValues)) { + if (empty($dataValues)) { return; } @@ -559,7 +559,7 @@ private function _renderAreaChart($groupCount, $dimensions = '2d') { $this->_renderCartesianPlotArea(); for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotLine($i,True,False,$dimensions); + $this->_renderPlotLine($i,True,False, $dimensions); } } // function _renderAreaChart() @@ -570,7 +570,7 @@ private function _renderLineChart($groupCount, $dimensions = '2d') { $this->_renderCartesianPlotArea(); for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotLine($i,False,False,$dimensions); + $this->_renderPlotLine($i,False,False, $dimensions); } } // function _renderLineChart() @@ -581,7 +581,7 @@ private function _renderBarChart($groupCount, $dimensions = '2d') { $this->_renderCartesianPlotArea(); for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotBar($i,$dimensions); + $this->_renderPlotBar($i, $dimensions); } } // function _renderBarChart() @@ -640,8 +640,8 @@ private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = Fa // Fill in any missing values in the $dataValues array $testCurrentIndex = 0; - foreach($dataValues as $k => $dataValue) { - while($k != $testCurrentIndex) { + foreach ($dataValues as $k => $dataValue) { + while ($k != $testCurrentIndex) { $dataValues[$testCurrentIndex] = null; ++$testCurrentIndex; } @@ -707,7 +707,7 @@ private function _renderStockChart($groupCount) { } // function _renderStockChart() - private function _renderContourChart($groupCount,$dimensions) { + private function _renderContourChart($groupCount, $dimensions) { require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_contour.php'); $this->_renderCartesianPlotArea('intint'); @@ -718,7 +718,7 @@ private function _renderContourChart($groupCount,$dimensions) { } // function _renderContourChart() - private function _renderCombinationChart($groupCount,$dimensions,$outputDestination) { + private function _renderCombinationChart($groupCount, $dimensions, $outputDestination) { require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); @@ -734,17 +734,17 @@ private function _renderCombinationChart($groupCount,$dimensions,$outputDestinat case 'area3DChart' : $dimensions = '3d'; case 'areaChart' : - $this->_renderPlotLine($i,True,True,$dimensions); + $this->_renderPlotLine($i,True,True, $dimensions); break; case 'bar3DChart' : $dimensions = '3d'; case 'barChart' : - $this->_renderPlotBar($i,$dimensions); + $this->_renderPlotBar($i, $dimensions); break; case 'line3DChart' : $dimensions = '3d'; case 'lineChart' : - $this->_renderPlotLine($i,False,True,$dimensions); + $this->_renderPlotLine($i,False,True, $dimensions); break; case 'scatterChart' : $this->_renderPlotScatter($i,false); @@ -785,7 +785,7 @@ public function render($outputDestination) { echo 'Chart is not yet implemented<br />'; return false; } else { - return $this->_renderCombinationChart($groupCount,$dimensions,$outputDestination); + return $this->_renderCombinationChart($groupCount, $dimensions, $outputDestination); } } @@ -793,27 +793,27 @@ public function render($outputDestination) { case 'area3DChart' : $dimensions = '3d'; case 'areaChart' : - $this->_renderAreaChart($groupCount,$dimensions); + $this->_renderAreaChart($groupCount, $dimensions); break; case 'bar3DChart' : $dimensions = '3d'; case 'barChart' : - $this->_renderBarChart($groupCount,$dimensions); + $this->_renderBarChart($groupCount, $dimensions); break; case 'line3DChart' : $dimensions = '3d'; case 'lineChart' : - $this->_renderLineChart($groupCount,$dimensions); + $this->_renderLineChart($groupCount, $dimensions); break; case 'pie3DChart' : $dimensions = '3d'; case 'pieChart' : - $this->_renderPieChart($groupCount,$dimensions,False,False); + $this->_renderPieChart($groupCount, $dimensions,False,False); break; case 'doughnut3DChart' : $dimensions = '3d'; case 'doughnutChart' : - $this->_renderPieChart($groupCount,$dimensions,True,True); + $this->_renderPieChart($groupCount, $dimensions,True,True); break; case 'scatterChart' : $this->_renderScatterChart($groupCount); @@ -827,10 +827,10 @@ public function render($outputDestination) { case 'surface3DChart' : $dimensions = '3d'; case 'surfaceChart' : - $this->_renderContourChart($groupCount,$dimensions); + $this->_renderContourChart($groupCount, $dimensions); break; case 'stockChart' : - $this->_renderStockChart($groupCount,$dimensions); + $this->_renderStockChart($groupCount, $dimensions); break; default : echo $chartType.' is not yet implemented<br />'; diff --git a/Classes/PHPExcel/DocumentProperties.php b/Classes/PHPExcel/DocumentProperties.php index d872142cd..535c0c6dd 100644 --- a/Classes/PHPExcel/DocumentProperties.php +++ b/Classes/PHPExcel/DocumentProperties.php @@ -466,7 +466,7 @@ public function setCustomProperty($propertyName, $propertyValue = '', $propertyT $propertyType = self::PROPERTY_TYPE_STRING; } elseif (is_float($propertyValue)) { $propertyType = self::PROPERTY_TYPE_FLOAT; - } elseif(is_int($propertyValue)) { + } elseif (is_int($propertyValue)) { $propertyType = self::PROPERTY_TYPE_INTEGER; } elseif (is_bool($propertyValue)) { $propertyType = self::PROPERTY_TYPE_BOOLEAN; @@ -497,7 +497,7 @@ public function __clone() } } - public static function convertProperty($propertyValue,$propertyType) + public static function convertProperty($propertyValue, $propertyType) { switch ($propertyType) { case 'empty': // Empty diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index d0c9a44d6..86cbe31f4 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -637,7 +637,7 @@ protected function buildTextRun() { protected function rgbToColour($rgb) { preg_match_all('/\d+/', $rgb, $values); - foreach($values[0] as &$value) { + foreach ($values[0] as &$value) { $value = str_pad(dechex($value), 2, '0', STR_PAD_LEFT); } return implode($values[0]); @@ -655,7 +655,7 @@ protected function startFontTag($tag) { if ($attributeName == 'color') { if (preg_match('/rgb\s*\(/', $attributeValue)) { $this->$attributeName = $this->rgbToColour($attributeValue); - } elseif(strpos(trim($attributeValue), '#') === 0) { + } elseif (strpos(trim($attributeValue), '#') === 0) { $this->$attributeName = ltrim($attributeValue, '#'); } else { $this->$attributeName = $this->colourNameLookup($attributeValue); diff --git a/Classes/PHPExcel/IOFactory.php b/Classes/PHPExcel/IOFactory.php index 3ad0aa6c7..5b9c63530 100644 --- a/Classes/PHPExcel/IOFactory.php +++ b/Classes/PHPExcel/IOFactory.php @@ -203,7 +203,7 @@ public static function identify($pFilename) { $reader = self::createReaderForFile($pFilename); $className = get_class($reader); - $classType = explode('_',$className); + $classType = explode('_', $className); unset($reader); return array_pop($classType); } diff --git a/Classes/PHPExcel/NamedRange.php b/Classes/PHPExcel/NamedRange.php index 164246fe9..6d1d73f9b 100644 --- a/Classes/PHPExcel/NamedRange.php +++ b/Classes/PHPExcel/NamedRange.php @@ -110,7 +110,7 @@ public function setName($value = null) { // Re-attach if ($this->_worksheet !== NULL) { - $this->_worksheet->getParent()->removeNamedRange($this->_name,$this->_worksheet); + $this->_worksheet->getParent()->removeNamedRange($this->_name, $this->_worksheet); } $this->_name = $value; diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index e92c93eb2..d4fefd581 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -266,7 +266,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Loop through each line of the file in turn while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { $columnLetter = 'A'; - foreach($rowData as $rowDatum) { + foreach ($rowData as $rowDatum) { if ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) { // Unescape enclosures $rowDatum = str_replace($escapeEnclosures, $this->_enclosure, $rowDatum); diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index 3b62b7515..4f1058144 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -101,7 +101,7 @@ public function canRead($pFilename) fclose($fileHandle); $valid = true; - foreach($signature as $match) { + foreach ($signature as $match) { // every part of the signature must be present if (strpos($data, $match) === false) { $valid = false; @@ -110,10 +110,10 @@ public function canRead($pFilename) } // Retrieve charset encoding - if(preg_match('/<?xml.*encoding=[\'"](.*?)[\'"].*?>/um',$data,$matches)) { + if (preg_match('/<?xml.*encoding=[\'"](.*?)[\'"].*?>/um', $data, $matches)) { $this->_charSet = strtoupper($matches[1]); } -// echo 'Character Set is ',$this->_charSet,'<br />'; +// echo 'Character Set is ', $this->_charSet,'<br />'; return $valid; } @@ -141,9 +141,9 @@ public function listWorksheetNames($pFilename) $namespaces = $xml->getNamespaces(true); $xml_ss = $xml->children($namespaces['ss']); - foreach($xml_ss->Worksheet as $worksheet) { + foreach ($xml_ss->Worksheet as $worksheet) { $worksheet_ss = $worksheet->attributes($namespaces['ss']); - $worksheetNames[] = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet); + $worksheetNames[] = self::_convertStringEncoding((string) $worksheet_ss['Name'], $this->_charSet); } return $worksheetNames; @@ -170,7 +170,7 @@ public function listWorksheetInfo($pFilename) $worksheetID = 1; $xml_ss = $xml->children($namespaces['ss']); - foreach($xml_ss->Worksheet as $worksheet) { + foreach ($xml_ss->Worksheet as $worksheet) { $worksheet_ss = $worksheet->attributes($namespaces['ss']); $tmpInfo = array(); @@ -189,11 +189,11 @@ public function listWorksheetInfo($pFilename) if (isset($worksheet->Table->Row)) { $rowIndex = 0; - foreach($worksheet->Table->Row as $rowData) { + foreach ($worksheet->Table->Row as $rowData) { $columnIndex = 0; $rowHasData = false; - foreach($rowData->Cell as $cell) { + foreach ($rowData->Cell as $cell) { if (isset($cell->Data)) { $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); $rowHasData = true; @@ -241,7 +241,7 @@ public function load($pFilename) protected static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { $styleAttributeValue = strtolower($styleAttributeValue); - foreach($styleList as $style) { + foreach ($styleList as $style) { if ($styleAttributeValue == strtolower($style)) { $styleAttributeValue = $style; return true; @@ -336,52 +336,52 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $docProps = $objPHPExcel->getProperties(); if (isset($xml->DocumentProperties[0])) { - foreach($xml->DocumentProperties[0] as $propertyName => $propertyValue) { + foreach ($xml->DocumentProperties[0] as $propertyName => $propertyValue) { switch ($propertyName) { case 'Title' : - $docProps->setTitle(self::_convertStringEncoding($propertyValue,$this->_charSet)); + $docProps->setTitle(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; case 'Subject' : - $docProps->setSubject(self::_convertStringEncoding($propertyValue,$this->_charSet)); + $docProps->setSubject(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; case 'Author' : - $docProps->setCreator(self::_convertStringEncoding($propertyValue,$this->_charSet)); + $docProps->setCreator(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; case 'Created' : $creationDate = strtotime($propertyValue); $docProps->setCreated($creationDate); break; case 'LastAuthor' : - $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue,$this->_charSet)); + $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; case 'LastSaved' : $lastSaveDate = strtotime($propertyValue); $docProps->setModified($lastSaveDate); break; case 'Company' : - $docProps->setCompany(self::_convertStringEncoding($propertyValue,$this->_charSet)); + $docProps->setCompany(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; case 'Category' : - $docProps->setCategory(self::_convertStringEncoding($propertyValue,$this->_charSet)); + $docProps->setCategory(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; case 'Manager' : - $docProps->setManager(self::_convertStringEncoding($propertyValue,$this->_charSet)); + $docProps->setManager(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; case 'Keywords' : - $docProps->setKeywords(self::_convertStringEncoding($propertyValue,$this->_charSet)); + $docProps->setKeywords(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; case 'Description' : - $docProps->setDescription(self::_convertStringEncoding($propertyValue,$this->_charSet)); + $docProps->setDescription(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; } } } if (isset($xml->CustomDocumentProperties)) { - foreach($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { + foreach ($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { $propertyAttributes = $propertyValue->attributes($namespaces['dt']); - $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/','PHPExcel_Reader_Excel2003XML::_hex2str',$propertyName); + $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/','PHPExcel_Reader_Excel2003XML::_hex2str', $propertyName); $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN; - switch((string) $propertyAttributes) { + switch ((string) $propertyAttributes) { case 'string' : $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; $propertyValue = trim($propertyValue); @@ -403,11 +403,11 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $propertyValue = strtotime(trim($propertyValue)); break; } - $docProps->setCustomProperty($propertyName,$propertyValue,$propertyType); + $docProps->setCustomProperty($propertyName, $propertyValue, $propertyType); } } - foreach($xml->Styles[0] as $style) { + foreach ($xml->Styles[0] as $style) { $style_ss = $style->attributes($namespaces['ss']); $styleID = (string) $style_ss['ID']; // echo 'Style ID = '.$styleID.'<br />'; @@ -421,17 +421,17 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo $styleType.'<br />'; switch ($styleType) { case 'Alignment' : - foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { + foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; $styleAttributeValue = (string) $styleAttributeValue; switch ($styleAttributeKey) { case 'Vertical' : - if (self::identifyFixedStyleValue($verticalAlignmentStyles,$styleAttributeValue)) { + if (self::identifyFixedStyleValue($verticalAlignmentStyles, $styleAttributeValue)) { $this->_styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; } break; case 'Horizontal' : - if (self::identifyFixedStyleValue($horizontalAlignmentStyles,$styleAttributeValue)) { + if (self::identifyFixedStyleValue($horizontalAlignmentStyles, $styleAttributeValue)) { $this->_styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; } break; @@ -442,10 +442,10 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } break; case 'Borders' : - foreach($styleData->Border as $borderStyle) { + foreach ($styleData->Border as $borderStyle) { $borderAttributes = $borderStyle->attributes($namespaces['ss']); $thisBorder = array(); - foreach($borderAttributes as $borderStyleKey => $borderStyleValue) { + foreach ($borderAttributes as $borderStyleKey => $borderStyleValue) { // echo $borderStyleKey.' = '.$borderStyleValue.'<br />'; switch ($borderStyleKey) { case 'LineStyle' : @@ -472,7 +472,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } break; case 'Font' : - foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { + foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; $styleAttributeValue = (string) $styleAttributeValue; switch ($styleAttributeKey) { @@ -492,7 +492,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $this->_styles[$styleID]['font']['italic'] = true; break; case 'Underline' : - if (self::identifyFixedStyleValue($underlineStyles,$styleAttributeValue)) { + if (self::identifyFixedStyleValue($underlineStyles, $styleAttributeValue)) { $this->_styles[$styleID]['font']['underline'] = $styleAttributeValue; } break; @@ -500,7 +500,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } break; case 'Interior' : - foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { + foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; switch ($styleAttributeKey) { case 'Color' : @@ -510,9 +510,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } break; case 'NumberFormat' : - foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { + foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; - $styleAttributeValue = str_replace($fromFormats,$toFormats,$styleAttributeValue); + $styleAttributeValue = str_replace($fromFormats, $toFormats, $styleAttributeValue); switch ($styleAttributeValue) { case 'Short Date' : $styleAttributeValue = 'dd/mm/yyyy'; @@ -524,7 +524,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } break; case 'Protection' : - foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { + foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; } break; @@ -538,7 +538,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $worksheetID = 0; $xml_ss = $xml->children($namespaces['ss']); - foreach($xml_ss->Worksheet as $worksheet) { + foreach ($xml_ss->Worksheet as $worksheet) { $worksheet_ss = $worksheet->attributes($namespaces['ss']); if ((isset($this->_loadSheetsOnly)) && (isset($worksheet_ss['Name'])) && @@ -546,13 +546,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) continue; } -// echo '<h3>Worksheet: ',$worksheet_ss['Name'],'<h3>'; +// echo '<h3>Worksheet: ', $worksheet_ss['Name'],'<h3>'; // // Create new Worksheet $objPHPExcel->createSheet(); $objPHPExcel->setActiveSheetIndex($worksheetID); if (isset($worksheet_ss['Name'])) { - $worksheetName = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet); + $worksheetName = self::_convertStringEncoding((string) $worksheet_ss['Name'], $this->_charSet); // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in // formula cells... during the load, all formulae should be correct, and we're simply bringing // the worksheet name in line with the formula, not the reverse @@ -561,7 +561,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $columnID = 'A'; if (isset($worksheet->Table->Column)) { - foreach($worksheet->Table->Column as $columnData) { + foreach ($worksheet->Table->Column as $columnData) { $columnData_ss = $columnData->attributes($namespaces['ss']); if (isset($columnData_ss['Index'])) { $columnID = PHPExcel_Cell::stringFromColumnIndex($columnData_ss['Index']-1); @@ -578,7 +578,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $rowID = 1; if (isset($worksheet->Table->Row)) { $additionalMergedCells = 0; - foreach($worksheet->Table->Row as $rowData) { + foreach ($worksheet->Table->Row as $rowData) { $rowHasData = false; $row_ss = $rowData->attributes($namespaces['ss']); if (isset($row_ss['Index'])) { @@ -587,7 +587,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo '<b>Row '.$rowID.'</b><br />'; $columnID = 'A'; - foreach($rowData->Cell as $cell) { + foreach ($rowData->Cell as $cell) { $cell_ss = $cell->attributes($namespaces['ss']); if (isset($cell_ss['Index'])) { @@ -643,7 +643,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) const TYPE_ERROR = 'e'; */ case 'String' : - $cellValue = self::_convertStringEncoding($cellValue,$this->_charSet); + $cellValue = self::_convertStringEncoding($cellValue, $this->_charSet); $type = PHPExcel_Cell_DataType::TYPE_STRING; break; case 'Number' : @@ -673,31 +673,31 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $columnNumber = PHPExcel_Cell::columnIndexFromString($columnID); if (substr($cellDataFormula,0,3) == 'of:') { $cellDataFormula = substr($cellDataFormula,3); -// echo 'Before: ',$cellDataFormula,'<br />'; - $temp = explode('"',$cellDataFormula); +// echo 'Before: ', $cellDataFormula,'<br />'; + $temp = explode('"', $cellDataFormula); $key = false; - foreach($temp as &$value) { + foreach ($temp as &$value) { // Only replace in alternate array entries (i.e. non-quoted blocks) if ($key = !$key) { - $value = str_replace(array('[.','.',']'),'',$value); + $value = str_replace(array('[.','.',']'),'', $value); } } } else { // Convert R1C1 style references to A1 style references (but only when not quoted) -// echo 'Before: ',$cellDataFormula,'<br />'; - $temp = explode('"',$cellDataFormula); +// echo 'Before: ', $cellDataFormula,'<br />'; + $temp = explode('"', $cellDataFormula); $key = false; - foreach($temp as &$value) { + foreach ($temp as &$value) { // Only replace in alternate array entries (i.e. non-quoted blocks) if ($key = !$key) { - preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way // through the formula from left to right. Reversing means that we work right to left.through // the formula $cellReferences = array_reverse($cellReferences); // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, // then modify the formula to use that new reference - foreach($cellReferences as $cellReference) { + foreach ($cellReferences as $cellReference) { $rowReference = $cellReference[2][0]; // Empty R reference is the current row if ($rowReference == '') $rowReference = $rowID; @@ -709,20 +709,20 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Bracketed C references are relative to the current column if ($columnReference{0} == '[') $columnReference = $columnNumber + trim($columnReference,'[]'); $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; - $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0])); + $value = substr_replace($value, $A1CellReference, $cellReference[0][1],strlen($cellReference[0][0])); } } } } unset($value); // Then rebuild the formula string - $cellDataFormula = implode('"',$temp); -// echo 'After: ',$cellDataFormula,'<br />'; + $cellDataFormula = implode('"', $temp); +// echo 'After: ', $cellDataFormula,'<br />'; } // echo 'Cell '.$columnID.$rowID.' is a '.$type.' with a value of '.(($hasCalculatedValue) ? $cellDataFormula : $cellValue).'<br />'; // - $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $cellValue),$type); + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $cellValue), $type); if ($hasCalculatedValue) { // echo 'Formula result is '.$cellValue.'<br />'; $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($cellValue); @@ -736,15 +736,15 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $author = 'unknown'; if (isset($commentAttributes->Author)) { $author = (string)$commentAttributes->Author; -// echo 'Author: ',$author,'<br />'; +// echo 'Author: ', $author,'<br />'; } $node = $cell->Comment->Data->asXML(); // $annotation = str_replace('html:','',substr($node,49,-10)); // echo $annotation,'<br />'; $annotation = strip_tags($node); -// echo 'Annotation: ',$annotation,'<br />'; +// echo 'Annotation: ', $annotation,'<br />'; $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) - ->setAuthor(self::_convertStringEncoding($author ,$this->_charSet)) + ->setAuthor(self::_convertStringEncoding($author , $this->_charSet)) ->setText($this->_parseRichText($annotation) ); } @@ -790,9 +790,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } - protected static function _convertStringEncoding($string,$charset) { + protected static function _convertStringEncoding($string, $charset) { if ($charset != 'UTF-8') { - return PHPExcel_Shared_String::ConvertEncoding($string,'UTF-8',$charset); + return PHPExcel_Shared_String::ConvertEncoding($string,'UTF-8', $charset); } return $string; } @@ -801,7 +801,7 @@ protected static function _convertStringEncoding($string,$charset) { protected function _parseRichText($is = '') { $value = new PHPExcel_RichText(); - $value->createText(self::_convertStringEncoding($is,$this->_charSet)); + $value->createText(self::_convertStringEncoding($is, $this->_charSet)); return $value; } diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 101424ea5..9e62a852e 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -217,13 +217,13 @@ public function listWorksheetInfo($pFilename) if ($xml->name == 'row' && $xml->nodeType == XMLReader::ELEMENT) { $row = $xml->getAttribute('r'); $tmpInfo['totalRows'] = $row; - $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells); $currCells = 0; } elseif ($xml->name == 'c' && $xml->nodeType == XMLReader::ELEMENT) { $currCells++; } } - $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells); $xml->close(); $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; @@ -267,7 +267,7 @@ private static function _castToString($c) { } // function _castToString() - private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) { + private function _castToFormula($c, $r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas, $castBaseType) { // echo 'Formula', PHP_EOL; // echo '$c->f is ', $c->f, PHP_EOL; $cellDataType = 'f'; @@ -381,7 +381,7 @@ public function load($pFilename) $themeColours = array(); foreach ($colourScheme as $k => $xmlColour) { - $themePos = array_search($k,$themeOrderArray); + $themePos = array_search($k, $themeOrderArray); if ($themePos === false) { $themePos = $themeOrderAdditional++; } @@ -393,7 +393,7 @@ public function load($pFilename) $themeColours[$themePos] = $xmlColourData['val']; } } - self::$_theme = new PHPExcel_Reader_Excel2007_Theme($themeName,$colourSchemeName,$themeColours); + self::$_theme = new PHPExcel_Reader_Excel2007_Theme($themeName, $colourSchemeName, $themeColours); } break; } @@ -443,9 +443,9 @@ public function load($pFilename) $cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); $attributeType = $cellDataOfficeChildren->getName(); $attributeValue = (string) $cellDataOfficeChildren->{$attributeType}; - $attributeValue = PHPExcel_DocumentProperties::convertProperty($attributeValue,$attributeType); + $attributeValue = PHPExcel_DocumentProperties::convertProperty($attributeValue, $attributeType); $attributeType = PHPExcel_DocumentProperties::convertPropertyType($attributeType); - $docProps->setCustomProperty($propertyName,$attributeValue,$attributeType); + $docProps->setCustomProperty($propertyName, $attributeValue, $attributeType); } } } @@ -453,7 +453,7 @@ public function load($pFilename) //Ribbon case "http://schemas.microsoft.com/office/2006/relationships/ui/extensibility": $customUI = $rel['Target']; - if(!is_null($customUI)){ + if (!is_null($customUI)) { $this->_readRibbon($excel, $customUI, $zip); } break; @@ -478,7 +478,7 @@ public function load($pFilename) $worksheets = array(); $macros = $customUI = NULL; foreach ($relsWorkbook->Relationship as $ele) { - switch($ele['Type']){ + switch ($ele['Type']) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": $worksheets[(string) $ele["Id"]] = $ele["Target"]; break; @@ -489,14 +489,14 @@ public function load($pFilename) } } - if(!is_null($macros)){ + if (!is_null($macros)) { $macrosCode = $this->_getFromZipArchive($zip, 'xl/vbaProject.bin');//vbaProject.bin always in 'xl' dir and always named vbaProject.bin - if($macrosCode !== false){ + if ($macrosCode !== false) { $excel->setMacrosCode($macrosCode); $excel->setHasMacros(true); //short-circuit : not reading vbaProject.bin.rel to get Signature =>allways vbaProjectSignature.bin in 'xl' dir $Certificate = $this->_getFromZipArchive($zip, 'xl/vbaProjectSignature.bin'); - if($Certificate !== false) + if ($Certificate !== false) $excel->setMacrosCertificate($Certificate); } } @@ -865,7 +865,7 @@ public function load($pFilename) $value = self::_castToBool($c); } else { // Formula - $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToBool'); + $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas,'_castToBool'); if (isset($c->f['t'])) { $att = array(); $att = $c->f; @@ -885,7 +885,7 @@ public function load($pFilename) $value = self::_castToError($c); } else { // Formula - $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToError'); + $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas,'_castToError'); // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; } @@ -899,7 +899,7 @@ public function load($pFilename) } else { // echo 'Treat as Formula', PHP_EOL; // Formula - $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToString'); + $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas,'_castToString'); // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; } @@ -1207,8 +1207,8 @@ public function load($pFilename) foreach ($xmlSheet->dataValidations->dataValidation as $dataValidation) { // Uppercase coordinate $range = strtoupper($dataValidation["sqref"]); - $rangeSet = explode(' ',$range); - foreach($rangeSet as $range) { + $rangeSet = explode(' ', $range); + foreach ($rangeSet as $range) { $stRange = $docSheet->shrinkRangeToFit($range); // Extract all cell references in $range @@ -1307,7 +1307,7 @@ public function load($pFilename) // Loop through contents foreach ($commentsFile->commentList->comment as $comment) { - if(!empty($comment['authorId'])) + if (!empty($comment['authorId'])) $docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] ); $docSheet->getComment( (string)$comment['ref'] )->setText( $this->_parseRichText($comment->text) ); } @@ -1526,7 +1526,7 @@ public function load($pFilename) $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); } $objDrawing->setWorksheet($docSheet); - } elseif(($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { + } elseif (($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { $fromCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1); $fromOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff); $fromOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff); @@ -1561,7 +1561,7 @@ public function load($pFilename) $extractedRange = (string)$definedName; $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); if (($spos = strpos($extractedRange,'!')) !== false) { - $extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos)); + $extractedRange = substr($extractedRange,0, $spos).str_replace('$', '', substr($extractedRange, $spos)); } else { $extractedRange = str_replace('$', '', $extractedRange); } @@ -1611,7 +1611,7 @@ public function load($pFilename) case '_xlnm.Print_Area': $rangeSets = explode(',', $extractedRange); // FIXME: what if sheetname contains comma? $newRangeSets = array(); - foreach($rangeSets as $rangeSet) { + foreach ($rangeSets as $rangeSet) { $range = explode('!', $rangeSet); // FIXME: what if sheetname contains exclamation mark? $rangeSet = isset($range[1]) ? $range[1] : $range[0]; if (strpos($rangeSet, ':') === FALSE) { @@ -1619,7 +1619,7 @@ public function load($pFilename) } $newRangeSets[] = str_replace('$', '', $rangeSet); } - $docSheet->getPageSetup()->setPrintArea(implode(',',$newRangeSets)); + $docSheet->getPageSetup()->setPrintArea(implode(',', $newRangeSets)); break; default: @@ -1640,7 +1640,7 @@ public function load($pFilename) $extractedRange = (string)$definedName; $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); if (($spos = strpos($extractedRange,'!')) !== false) { - $extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos)); + $extractedRange = substr($extractedRange,0, $spos).str_replace('$', '', substr($extractedRange, $spos)); } else { $extractedRange = str_replace('$', '', $extractedRange); } @@ -1731,12 +1731,12 @@ public function load($pFilename) $chartElements = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $chartEntryRef)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef,'.xml')); -// echo 'Chart ',$chartEntryRef,'<br />'; +// echo 'Chart ', $chartEntryRef,'<br />'; // var_dump($charts[$chartEntryRef]); // if (isset($charts[$chartEntryRef])) { $chartPositionRef = $charts[$chartEntryRef]['sheet'].'!'.$charts[$chartEntryRef]['id']; -// echo 'Position Ref ',$chartPositionRef,'<br />'; +// echo 'Position Ref ', $chartPositionRef,'<br />'; if (isset($chartDetails[$chartPositionRef])) { // var_dump($chartDetails[$chartPositionRef]); @@ -1767,7 +1767,7 @@ private static function _readColor($color, $background=FALSE) { if (isset($color["rgb"])) { return (string)$color["rgb"]; } else if (isset($color["indexed"])) { - return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB(); + return PHPExcel_Style_Color::indexedColor($color["indexed"]-7, $background)->getARGB(); } else if (isset($color["theme"])) { if (self::$_theme !== NULL) { $returnColour = self::$_theme->getColourByIndex((int)$color["theme"]); @@ -1832,7 +1832,7 @@ private static function _readStyle($docStyle, $style) { if (isset($style->fill)) { if ($style->fill->gradientFill) { $gradientFill = $style->fill->gradientFill[0]; - if(!empty($gradientFill["type"])) { + if (!empty($gradientFill["type"])) { $docStyle->getFill()->setFillType((string) $gradientFill["type"]); } $docStyle->getFill()->setRotation(floatval($gradientFill["degree"])); @@ -1934,7 +1934,7 @@ private function _parseRichText($is = null) { if (isset($is->t)) { $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $is->t ) ); } else { - if(is_object($is->r)) { + if (is_object($is->r)) { foreach ($is->r as $run) { if (!isset($run->rPr)) { $objText = $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index 7226d4a4c..80ac44700 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Chart.php +++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php @@ -51,95 +51,95 @@ private static function _getAttribute($component, $name, $format) { } // function _getAttribute() - private static function _readColor($color,$background=false) { + private static function _readColor($color, $background=false) { if (isset($color["rgb"])) { return (string)$color["rgb"]; } else if (isset($color["indexed"])) { - return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB(); + return PHPExcel_Style_Color::indexedColor($color["indexed"]-7, $background)->getARGB(); } } - public static function readChart($chartElements,$chartName) { + public static function readChart($chartElements, $chartName) { $namespacesChartMeta = $chartElements->getNamespaces(true); $chartElementsC = $chartElements->children($namespacesChartMeta['c']); $XaxisLabel = $YaxisLabel = $legend = $title = NULL; $dispBlanksAs = $plotVisOnly = NULL; - foreach($chartElementsC as $chartElementKey => $chartElement) { + foreach ($chartElementsC as $chartElementKey => $chartElement) { switch ($chartElementKey) { case "chart": - foreach($chartElement as $chartDetailsKey => $chartDetails) { + foreach ($chartElement as $chartDetailsKey => $chartDetails) { $chartDetailsC = $chartDetails->children($namespacesChartMeta['c']); switch ($chartDetailsKey) { case "plotArea": $plotAreaLayout = $XaxisLable = $YaxisLable = null; $plotSeries = $plotAttributes = array(); - foreach($chartDetails as $chartDetailKey => $chartDetail) { + foreach ($chartDetails as $chartDetailKey => $chartDetail) { switch ($chartDetailKey) { case "layout": - $plotAreaLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'plotArea'); + $plotAreaLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta,'plotArea'); break; case "catAx": if (isset($chartDetail->title)) { - $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); } break; case "dateAx": if (isset($chartDetail->title)) { - $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); } break; case "valAx": if (isset($chartDetail->title)) { - $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); } break; case "barChart": case "bar3DChart": $barDirection = self::_getAttribute($chartDetail->barDir, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotDirection($barDirection); $plotSeries[] = $plotSer; $plotAttributes = self::_readChartAttributes($chartDetail); break; case "lineChart": case "line3DChart": - $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotAttributes = self::_readChartAttributes($chartDetail); break; case "areaChart": case "area3DChart": - $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotAttributes = self::_readChartAttributes($chartDetail); break; case "doughnutChart": case "pieChart": case "pie3DChart": $explosion = isset($chartDetail->ser->explosion); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotStyle($explosion); $plotSeries[] = $plotSer; $plotAttributes = self::_readChartAttributes($chartDetail); break; case "scatterChart": $scatterStyle = self::_getAttribute($chartDetail->scatterStyle, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotStyle($scatterStyle); $plotSeries[] = $plotSer; $plotAttributes = self::_readChartAttributes($chartDetail); break; case "bubbleChart": $bubbleScale = self::_getAttribute($chartDetail->bubbleScale, 'val', 'integer'); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotStyle($bubbleScale); $plotSeries[] = $plotSer; $plotAttributes = self::_readChartAttributes($chartDetail); break; case "radarChart": $radarStyle = self::_getAttribute($chartDetail->radarStyle, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotStyle($radarStyle); $plotSeries[] = $plotSer; $plotAttributes = self::_readChartAttributes($chartDetail); @@ -147,13 +147,13 @@ public static function readChart($chartElements,$chartName) { case "surfaceChart": case "surface3DChart": $wireFrame = self::_getAttribute($chartDetail->wireframe, 'val', 'boolean'); - $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotStyle($wireFrame); $plotSeries[] = $plotSer; $plotAttributes = self::_readChartAttributes($chartDetail); break; case "stockChart": - $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotAttributes = self::_readChartAttributes($plotAreaLayout); break; } @@ -161,8 +161,8 @@ public static function readChart($chartElements,$chartName) { if ($plotAreaLayout == NULL) { $plotAreaLayout = new PHPExcel_Chart_Layout(); } - $plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout,$plotSeries); - self::_setChartAttributes($plotAreaLayout,$plotAttributes); + $plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout, $plotSeries); + self::_setChartAttributes($plotAreaLayout, $plotAttributes); break; case "plotVisOnly": $plotVisOnly = self::_getAttribute($chartDetails, 'val', 'string'); @@ -171,13 +171,13 @@ public static function readChart($chartElements,$chartName) { $dispBlanksAs = self::_getAttribute($chartDetails, 'val', 'string'); break; case "title": - $title = self::_chartTitle($chartDetails,$namespacesChartMeta,'title'); + $title = self::_chartTitle($chartDetails, $namespacesChartMeta,'title'); break; case "legend": $legendPos = 'r'; $legendLayout = null; $legendOverlay = false; - foreach($chartDetails as $chartDetailKey => $chartDetail) { + foreach ($chartDetails as $chartDetailKey => $chartDetail) { switch ($chartDetailKey) { case "legendPos": $legendPos = self::_getAttribute($chartDetail, 'val', 'string'); @@ -186,7 +186,7 @@ public static function readChart($chartElements,$chartName) { $legendOverlay = self::_getAttribute($chartDetail, 'val', 'boolean'); break; case "layout": - $legendLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'legend'); + $legendLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta,'legend'); break; } } @@ -196,20 +196,20 @@ public static function readChart($chartElements,$chartName) { } } } - $chart = new PHPExcel_Chart($chartName,$title,$legend,$plotArea,$plotVisOnly,$dispBlanksAs,$XaxisLabel,$YaxisLabel); + $chart = new PHPExcel_Chart($chartName, $title, $legend, $plotArea, $plotVisOnly, $dispBlanksAs, $XaxisLabel, $YaxisLabel); return $chart; } // function readChart() - private static function _chartTitle($titleDetails,$namespacesChartMeta,$type) { + private static function _chartTitle($titleDetails, $namespacesChartMeta, $type) { $caption = array(); $titleLayout = null; - foreach($titleDetails as $titleDetailKey => $chartDetail) { + foreach ($titleDetails as $titleDetailKey => $chartDetail) { switch ($titleDetailKey) { case "tx": $titleDetails = $chartDetail->rich->children($namespacesChartMeta['a']); - foreach($titleDetails as $titleKey => $titleDetail) { + foreach ($titleDetails as $titleKey => $titleDetail) { switch ($titleKey) { case "p": $titleDetailPart = $titleDetail->children($namespacesChartMeta['a']); @@ -218,7 +218,7 @@ private static function _chartTitle($titleDetails,$namespacesChartMeta,$type) { } break; case "layout": - $titleLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta); + $titleLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta); break; } } @@ -227,7 +227,7 @@ private static function _chartTitle($titleDetails,$namespacesChartMeta,$type) { } // function _chartTitle() - private static function _chartLayoutDetails($chartDetail,$namespacesChartMeta) { + private static function _chartLayoutDetails($chartDetail, $namespacesChartMeta) { if (!isset($chartDetail->manualLayout)) { return null; } @@ -236,7 +236,7 @@ private static function _chartLayoutDetails($chartDetail,$namespacesChartMeta) { return null; } $layout = array(); - foreach($details as $detailKey => $detail) { + foreach ($details as $detailKey => $detail) { // echo $detailKey,' => ',self::_getAttribute($detail, 'val', 'string'),PHP_EOL; $layout[$detailKey] = self::_getAttribute($detail, 'val', 'string'); } @@ -244,20 +244,20 @@ private static function _chartLayoutDetails($chartDetail,$namespacesChartMeta) { } // function _chartLayoutDetails() - private static function _chartDataSeries($chartDetail,$namespacesChartMeta,$plotType) { + private static function _chartDataSeries($chartDetail, $namespacesChartMeta, $plotType) { $multiSeriesType = NULL; $smoothLine = false; $seriesLabel = $seriesCategory = $seriesValues = $plotOrder = array(); $seriesDetailSet = $chartDetail->children($namespacesChartMeta['c']); - foreach($seriesDetailSet as $seriesDetailKey => $seriesDetails) { + foreach ($seriesDetailSet as $seriesDetailKey => $seriesDetails) { switch ($seriesDetailKey) { case "grouping": $multiSeriesType = self::_getAttribute($chartDetail->grouping, 'val', 'string'); break; case "ser": $marker = NULL; - foreach($seriesDetails as $seriesKey => $seriesDetail) { + foreach ($seriesDetails as $seriesKey => $seriesDetail) { switch ($seriesKey) { case "idx": $seriesIndex = self::_getAttribute($seriesDetail, 'val', 'integer'); @@ -267,7 +267,7 @@ private static function _chartDataSeries($chartDetail,$namespacesChartMeta,$plot $plotOrder[$seriesIndex] = $seriesOrder; break; case "tx": - $seriesLabel[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta); + $seriesLabel[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta); break; case "marker": $marker = self::_getAttribute($seriesDetail->symbol, 'val', 'string'); @@ -276,22 +276,22 @@ private static function _chartDataSeries($chartDetail,$namespacesChartMeta,$plot $smoothLine = self::_getAttribute($seriesDetail, 'val', 'boolean'); break; case "cat": - $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta); + $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta); break; case "val": - $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); break; case "xVal": - $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); break; case "yVal": - $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); break; } } } } - return new PHPExcel_Chart_DataSeries($plotType,$multiSeriesType,$plotOrder,$seriesLabel,$seriesCategory,$seriesValues,$smoothLine); + return new PHPExcel_Chart_DataSeries($plotType, $multiSeriesType, $plotOrder, $seriesLabel, $seriesCategory, $seriesValues, $smoothLine); } // function _chartDataSeries() @@ -300,35 +300,35 @@ private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChart $seriesSource = (string) $seriesDetail->strRef->f; $seriesData = self::_chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']),'s'); - return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } elseif (isset($seriesDetail->numRef)) { $seriesSource = (string) $seriesDetail->numRef->f; $seriesData = self::_chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c'])); - return new PHPExcel_Chart_DataSeriesValues('Number',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + return new PHPExcel_Chart_DataSeriesValues('Number', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } elseif (isset($seriesDetail->multiLvlStrRef)) { $seriesSource = (string) $seriesDetail->multiLvlStrRef->f; $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']),'s'); $seriesData['pointCount'] = count($seriesData['dataValues']); - return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } elseif (isset($seriesDetail->multiLvlNumRef)) { $seriesSource = (string) $seriesDetail->multiLvlNumRef->f; $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']),'s'); $seriesData['pointCount'] = count($seriesData['dataValues']); - return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } return null; } // function _chartDataSeriesValueSet() - private static function _chartDataSeriesValues($seriesValueSet,$dataType='n') { + private static function _chartDataSeriesValues($seriesValueSet, $dataType='n') { $seriesVal = array(); $formatCode = ''; $pointCount = 0; - foreach($seriesValueSet as $seriesValueIdx => $seriesValue) { + foreach ($seriesValueSet as $seriesValueIdx => $seriesValue) { switch ($seriesValueIdx) { case 'ptCount': $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); @@ -358,13 +358,13 @@ private static function _chartDataSeriesValues($seriesValueSet,$dataType='n') { } // function _chartDataSeriesValues() - private static function _chartDataSeriesValuesMultiLevel($seriesValueSet,$dataType='n') { + private static function _chartDataSeriesValuesMultiLevel($seriesValueSet, $dataType='n') { $seriesVal = array(); $formatCode = ''; $pointCount = 0; - foreach($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) { - foreach($seriesLevel as $seriesValueIdx => $seriesValue) { + foreach ($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) { + foreach ($seriesLevel as $seriesValueIdx => $seriesValue) { switch ($seriesValueIdx) { case 'ptCount': $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); @@ -393,7 +393,7 @@ private static function _chartDataSeriesValuesMultiLevel($seriesValueSet,$dataTy private static function _parseRichText($titleDetailPart = null) { $value = new PHPExcel_RichText(); - foreach($titleDetailPart as $titleDetailElementKey => $titleDetailElement) { + foreach ($titleDetailPart as $titleDetailElementKey => $titleDetailElement) { if (isset($titleDetailElement->t)) { $objText = $value->createTextRun( (string) $titleDetailElement->t ); } @@ -426,7 +426,7 @@ private static function _parseRichText($titleDetailPart = null) { if (!is_null($baseline)) { if ($baseline > 0) { $objText->getFont()->setSuperScript(true); - } elseif($baseline < 0) { + } elseif ($baseline < 0) { $objText->getFont()->setSubScript(true); } } @@ -435,7 +435,7 @@ private static function _parseRichText($titleDetailPart = null) { if (!is_null($underscore)) { if ($underscore == 'sng') { $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); - } elseif($underscore == 'dbl') { + } elseif ($underscore == 'dbl') { $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); } else { $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_NONE); @@ -485,10 +485,10 @@ private static function _readChartAttributes($chartDetail) { return $plotAttributes; } - private static function _setChartAttributes($plotArea,$plotAttributes) + private static function _setChartAttributes($plotArea, $plotAttributes) { - foreach($plotAttributes as $plotAttributeKey => $plotAttributeValue) { - switch($plotAttributeKey) { + foreach ($plotAttributes as $plotAttributeKey => $plotAttributeValue) { + switch ($plotAttributeKey) { case 'showLegendKey' : $plotArea->setShowLegendKey($plotAttributeValue); break; diff --git a/Classes/PHPExcel/Reader/Excel2007/Theme.php b/Classes/PHPExcel/Reader/Excel2007/Theme.php index 5d3c1c9b6..2501c8141 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Theme.php +++ b/Classes/PHPExcel/Reader/Excel2007/Theme.php @@ -69,7 +69,7 @@ class PHPExcel_Reader_Excel2007_Theme * Create a new PHPExcel_Theme * */ - public function __construct($themeName,$colourSchemeName,$colourMap) + public function __construct($themeName, $colourSchemeName, $colourMap) { // Initialise values $this->_themeName = $themeName; diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index b12bf3efb..9b27b965d 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -676,7 +676,7 @@ public function load($pFilename) if (!$this->_readDataOnly) { foreach ($this->_objFonts as $objFont) { if (isset($objFont->colorIndex)) { - $color = self::_readColor($objFont->colorIndex,$this->_palette,$this->_version); + $color = self::_readColor($objFont->colorIndex, $this->_palette, $this->_version); $objFont->getColor()->setRGB($color['rgb']); } } @@ -686,12 +686,12 @@ public function load($pFilename) $fill = $objStyle->getFill(); if (isset($fill->startcolorIndex)) { - $startColor = self::_readColor($fill->startcolorIndex,$this->_palette,$this->_version); + $startColor = self::_readColor($fill->startcolorIndex, $this->_palette, $this->_version); $fill->getStartColor()->setRGB($startColor['rgb']); } if (isset($fill->endcolorIndex)) { - $endColor = self::_readColor($fill->endcolorIndex,$this->_palette,$this->_version); + $endColor = self::_readColor($fill->endcolorIndex, $this->_palette, $this->_version); $fill->getEndColor()->setRGB($endColor['rgb']); } @@ -703,27 +703,27 @@ public function load($pFilename) $diagonal = $objStyle->getBorders()->getDiagonal(); if (isset($top->colorIndex)) { - $borderTopColor = self::_readColor($top->colorIndex,$this->_palette,$this->_version); + $borderTopColor = self::_readColor($top->colorIndex, $this->_palette, $this->_version); $top->getColor()->setRGB($borderTopColor['rgb']); } if (isset($right->colorIndex)) { - $borderRightColor = self::_readColor($right->colorIndex,$this->_palette,$this->_version); + $borderRightColor = self::_readColor($right->colorIndex, $this->_palette, $this->_version); $right->getColor()->setRGB($borderRightColor['rgb']); } if (isset($bottom->colorIndex)) { - $borderBottomColor = self::_readColor($bottom->colorIndex,$this->_palette,$this->_version); + $borderBottomColor = self::_readColor($bottom->colorIndex, $this->_palette, $this->_version); $bottom->getColor()->setRGB($borderBottomColor['rgb']); } if (isset($left->colorIndex)) { - $borderLeftColor = self::_readColor($left->colorIndex,$this->_palette,$this->_version); + $borderLeftColor = self::_readColor($left->colorIndex, $this->_palette, $this->_version); $left->getColor()->setRGB($borderLeftColor['rgb']); } if (isset($diagonal->colorIndex)) { - $borderDiagonalColor = self::_readColor($diagonal->colorIndex,$this->_palette,$this->_version); + $borderDiagonalColor = self::_readColor($diagonal->colorIndex, $this->_palette, $this->_version); $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']); } } @@ -863,7 +863,7 @@ public function load($pFilename) // treat OBJ records foreach ($this->_objs as $n => $obj) { -// echo '<hr /><b>Object</b> reference is ',$n,'<br />'; +// echo '<hr /><b>Object</b> reference is ', $n,'<br />'; // var_dump($obj); // echo '<br />'; @@ -896,7 +896,7 @@ public function load($pFilename) case 0x19: // Note // echo 'Cell Annotation Object<br />'; -// echo 'Object ID is ',$obj['idObjID'],'<br />'; +// echo 'Object ID is ', $obj['idObjID'],'<br />'; // if (isset($this->_cellNotes[$obj['idObjID']])) { $cellNote = $this->_cellNotes[$obj['idObjID']]; @@ -969,7 +969,7 @@ public function load($pFilename) } if (!empty($this->_cellNotes)) { - foreach($this->_cellNotes as $note => $noteDetails) { + foreach ($this->_cellNotes as $note => $noteDetails) { if (!isset($noteDetails['objTextData'])) { if (isset($this->_textObjects[$note])) { $textObject = $this->_textObjects[$note]; @@ -978,10 +978,10 @@ public function load($pFilename) $noteDetails['objTextData']['text'] = ''; } } -// echo '<b>Cell annotation ',$note,'</b><br />'; +// echo '<b>Cell annotation ', $note,'</b><br />'; // var_dump($noteDetails); // echo '<br />'; - $cellAddress = str_replace('$','',$noteDetails['cellRef']); + $cellAddress = str_replace('$','', $noteDetails['cellRef']); $this->_phpSheet->getComment( $cellAddress ) ->setAuthor( $noteDetails['author'] ) ->setText($this->_parseRichText($noteDetails['objTextData']['text']) ); @@ -1353,21 +1353,21 @@ private function _readDocumentSummaryInformation() // offset: 8; size: 16 // offset: 24; size: 4; section count $secCount = self::_GetInt4d($this->_documentSummaryInformation, 24); -// echo '$secCount = ',$secCount,'<br />'; +// echo '$secCount = ', $secCount,'<br />'; // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae // offset: 44; size: 4; first section offset $secOffset = self::_GetInt4d($this->_documentSummaryInformation, 44); -// echo '$secOffset = ',$secOffset,'<br />'; +// echo '$secOffset = ', $secOffset,'<br />'; // section header // offset: $secOffset; size: 4; section length $secLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset); -// echo '$secLength = ',$secLength,'<br />'; +// echo '$secLength = ', $secLength,'<br />'; // offset: $secOffset+4; size: 4; property count $countProperties = self::_GetInt4d($this->_documentSummaryInformation, $secOffset+4); -// echo '$countProperties = ',$countProperties,'<br />'; +// echo '$countProperties = ', $countProperties,'<br />'; // initialize code page (used to resolve string values) $codePage = 'CP1252'; @@ -1375,17 +1375,17 @@ private function _readDocumentSummaryInformation() // offset: ($secOffset+8); size: var // loop through property decarations and properties for ($i = 0; $i < $countProperties; ++$i) { -// echo 'Property ',$i,'<br />'; +// echo 'Property ', $i,'<br />'; // offset: ($secOffset+8) + (8 * $i); size: 4; property ID $id = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+8) + (8 * $i)); -// echo 'ID is ',$id,'<br />'; +// echo 'ID is ', $id,'<br />'; // Use value of property id as appropriate // offset: 60 + 8 * $i; size: 4; offset from beginning of section (48) $offset = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+12) + (8 * $i)); $type = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + $offset); -// echo 'Type is ',$type,', '; +// echo 'Type is ', $type,', '; // initialize property value $value = null; @@ -1531,9 +1531,9 @@ private function _readNote() $noteObjID = self::_GetInt2d($recordData, 6); $noteAuthor = self::_readUnicodeStringLong(substr($recordData, 8)); $noteAuthor = $noteAuthor['value']; -// echo 'Note Address=',$cellAddress,'<br />'; -// echo 'Note Object ID=',$noteObjID,'<br />'; -// echo 'Note Author=',$noteAuthor,'<hr />'; +// echo 'Note Address=', $cellAddress,'<br />'; +// echo 'Note Object ID=', $noteObjID,'<br />'; +// echo 'Note Author=', $noteAuthor,'<hr />'; // $this->_cellNotes[$noteObjID] = array('cellRef' => $cellAddress, 'objectID' => $noteObjID, @@ -1549,13 +1549,13 @@ private function _readNote() $extension = true; $cellAddress = array_pop(array_keys($this->_phpSheet->getComments())); } -// echo 'Note Address=',$cellAddress,'<br />'; +// echo 'Note Address=', $cellAddress,'<br />'; - $cellAddress = str_replace('$','',$cellAddress); + $cellAddress = str_replace('$','', $cellAddress); $noteLength = self::_GetInt2d($recordData, 4); $noteText = trim(substr($recordData, 6)); -// echo 'Note Length=',$noteLength,'<br />'; -// echo 'Note Text=',$noteText,'<br />'; +// echo 'Note Length=', $noteLength,'<br />'; +// echo 'Note Text=', $noteText,'<br />'; if ($extension) { // Concatenate this extension with the currently set comment for the cell @@ -1601,8 +1601,8 @@ private function _readTextObject() $text = $this->_getSplicedRecordData(); $this->_textObjects[$this->textObjRef] = array( - 'text' => substr($text["recordData"],$text["spliceOffsets"][0]+1,$cchText), - 'format' => substr($text["recordData"],$text["spliceOffsets"][1],$cbRuns), + 'text' => substr($text["recordData"], $text["spliceOffsets"][0]+1, $cchText), + 'format' => substr($text["recordData"], $text["spliceOffsets"][1], $cbRuns), 'alignment' => $grbitOpts, 'rotation' => $rot ); @@ -4294,7 +4294,7 @@ private function _readWindow2() /** * Read PLV Record(Created by Excel2007 or upper) */ - private function _readPageLayoutView(){ + private function _readPageLayoutView() { $length = self::_GetInt2d($this->_data, $this->_pos + 2); $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); @@ -4564,7 +4564,7 @@ private function _readHyperLink() $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); $nullOffset = strpos($url, 0x00); if ($nullOffset) - $url = substr($url,0,$nullOffset); + $url = substr($url,0, $nullOffset); $url .= $hasText ? '#' : ''; $offset += $us; break; @@ -4858,7 +4858,7 @@ private function _readSheetLayout() case 0x14: // offset: 16; size: 2; color index for sheet tab $colorIndex = self::_GetInt2d($recordData, 16); - $color = self::_readColor($colorIndex,$this->_palette,$this->_version); + $color = self::_readColor($colorIndex, $this->_palette, $this->_version); $this->_phpSheet->getTabColor()->setRGB($color['rgb']); break; @@ -6807,7 +6807,7 @@ public static function _GetInt4d($data, $pos) * @param array $palette Color palette * @return array RGB color value, example: array('rgb' => 'FF0000') */ - private static function _readColor($color,$palette,$version) + private static function _readColor($color, $palette, $version) { if ($color <= 0x07 || $color >= 0x40) { // special built-in color diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index 1f7072f7e..72a6755f0 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -257,13 +257,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $officeDocXML = $officeXML->{'document-meta'}; $officeDocMetaXML = $officeDocXML->meta; - foreach($officeDocMetaXML as $officePropertyData) { + foreach ($officeDocMetaXML as $officePropertyData) { $officePropertyDC = array(); if (isset($namespacesMeta['dc'])) { $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); } - foreach($officePropertyDC as $propertyName => $propertyValue) { + foreach ($officePropertyDC as $propertyName => $propertyValue) { $propertyValue = (string) $propertyValue; switch ($propertyName) { case 'title' : @@ -290,7 +290,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if (isset($namespacesMeta['meta'])) { $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); } - foreach($officePropertyMeta as $propertyName => $propertyValue) { + foreach ($officePropertyMeta as $propertyName => $propertyValue) { $attributes = $propertyValue->attributes($namespacesMeta['meta']); $propertyValue = (string) $propertyValue; switch ($propertyName) { @@ -307,7 +307,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $docProps->setModified($creationDate); break; case 'user-defined' : - list(,$attrName) = explode(':',$attributes['name']); + list(, $attrName) = explode(':', $attributes['name']); switch ($attrName) { case 'publisher' : $docProps->setCompany(trim($propertyValue)); @@ -324,7 +324,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } } elseif (isset($gnmXML->Summary)) { - foreach($gnmXML->Summary->Item as $summaryItem) { + foreach ($gnmXML->Summary->Item as $summaryItem) { $propertyName = $summaryItem->name; $propertyValue = $summaryItem->{'val-string'}; switch ($propertyName) { @@ -355,9 +355,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } $worksheetID = 0; - foreach($gnmXML->Sheets->Sheet as $sheet) { + foreach ($gnmXML->Sheets->Sheet as $sheet) { $worksheetName = (string) $sheet->Name; -// echo '<b>Worksheet: ',$worksheetName,'</b><br />'; +// echo '<b>Worksheet: ', $worksheetName,'</b><br />'; if ((isset($this->_loadSheetsOnly)) && (!in_array($worksheetName, $this->_loadSheetsOnly))) { continue; } @@ -374,15 +374,15 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if ((!$this->_readDataOnly) && (isset($sheet->PrintInformation))) { if (isset($sheet->PrintInformation->Margins)) { - foreach($sheet->PrintInformation->Margins->children('gnm',TRUE) as $key => $margin) { + foreach ($sheet->PrintInformation->Margins->children('gnm',TRUE) as $key => $margin) { $marginAttributes = $margin->attributes(); $marginSize = 72 / 100; // Default - switch($marginAttributes['PrefUnit']) { + switch ($marginAttributes['PrefUnit']) { case 'mm' : $marginSize = intval($marginAttributes['Points']) / 100; break; } - switch($key) { + switch ($key) { case 'top' : $objPHPExcel->getActiveSheet()->getPageMargins()->setTop($marginSize); break; @@ -406,7 +406,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } - foreach($sheet->Cells->Cell as $cell) { + foreach ($sheet->Cells->Cell as $cell) { $cellAttributes = $cell->attributes(); $row = (int) $cellAttributes->Row + 1; $column = (int) $cellAttributes->Col; @@ -425,9 +425,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $ValueType = $cellAttributes->ValueType; $ExprID = (string) $cellAttributes->ExprID; -// echo 'Cell ',$column,$row,'<br />'; -// echo 'Type is ',$ValueType,'<br />'; -// echo 'Value is ',$cell,'<br />'; +// echo 'Cell ', $column, $row,'<br />'; +// echo 'Type is ', $ValueType,'<br />'; +// echo 'Value is ', $cell,'<br />'; $type = PHPExcel_Cell_DataType::TYPE_FORMULA; if ($ExprID > '') { if (((string) $cell) > '') { @@ -436,7 +436,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) 'row' => $cellAttributes->Row, 'formula' => (string) $cell ); -// echo 'NEW EXPRESSION ',$ExprID,'<br />'; +// echo 'NEW EXPRESSION ', $ExprID,'<br />'; } else { $expression = $this->_expressions[$ExprID]; @@ -446,12 +446,12 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $cellAttributes->Row - $expression['row'], $worksheetName ); -// echo 'SHARED EXPRESSION ',$ExprID,'<br />'; -// echo 'New Value is ',$cell,'<br />'; +// echo 'SHARED EXPRESSION ', $ExprID,'<br />'; +// echo 'New Value is ', $cell,'<br />'; } $type = PHPExcel_Cell_DataType::TYPE_FORMULA; } else { - switch($ValueType) { + switch ($ValueType) { case '10' : // NULL $type = PHPExcel_Cell_DataType::TYPE_NULL; break; @@ -474,11 +474,11 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) case '80' : // Array } } - $objPHPExcel->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell,$type); + $objPHPExcel->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell, $type); } if ((!$this->_readDataOnly) && (isset($sheet->Objects))) { - foreach($sheet->Objects->children('gnm',TRUE) as $key => $comment) { + foreach ($sheet->Objects->children('gnm',TRUE) as $key => $comment) { $commentAttributes = $comment->attributes(); // Only comment objects are handled at the moment if ($commentAttributes->Text) { @@ -488,9 +488,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } } -// echo '$maxCol=',$maxCol,'; $maxRow=',$maxRow,'<br />'; +// echo '$maxCol=', $maxCol,'; $maxRow=', $maxRow,'<br />'; // - foreach($sheet->Styles->StyleRegion as $styleRegion) { + foreach ($sheet->Styles->StyleRegion as $styleRegion) { $styleAttributes = $styleRegion->attributes(); if (($styleAttributes['startRow'] <= $maxRow) && ($styleAttributes['startCol'] <= $maxCol)) { @@ -516,7 +516,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $styleArray['numberformat']['code'] = (string) $styleAttributes['Format']; // If _readDataOnly is false, we set all formatting information if (!$this->_readDataOnly) { - switch($styleAttributes['HAlign']) { + switch ($styleAttributes['HAlign']) { case '1' : $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; break; @@ -538,7 +538,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) break; } - switch($styleAttributes['VAlign']) { + switch ($styleAttributes['VAlign']) { case '1' : $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_TOP; break; @@ -565,7 +565,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $styleArray['fill']['color']['rgb'] = $styleArray['fill']['startcolor']['rgb'] = $RGB; $RGB2 = self::_parseGnumericColour($styleAttributes["PatternColor"]); $styleArray['fill']['endcolor']['rgb'] = $RGB2; - switch($shade) { + switch ($shade) { case '1' : $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_SOLID; break; @@ -637,7 +637,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $styleArray['font']['bold'] = ($fontAttributes['Bold'] == '1') ? True : False; $styleArray['font']['italic'] = ($fontAttributes['Italic'] == '1') ? True : False; $styleArray['font']['strike'] = ($fontAttributes['StrikeThrough'] == '1') ? True : False; - switch($fontAttributes['Underline']) { + switch ($fontAttributes['Underline']) { case '1' : $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLE; break; @@ -654,7 +654,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_NONE; break; } - switch($fontAttributes['Script']) { + switch ($fontAttributes['Script']) { case '1' : $styleArray['font']['superScript'] = True; break; @@ -704,7 +704,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $columnAttributes = $sheet->Cols->attributes(); $defaultWidth = $columnAttributes['DefaultSizePts'] / 5.4; $c = 0; - foreach($sheet->Cols->ColInfo as $columnOverride) { + foreach ($sheet->Cols->ColInfo as $columnOverride) { $columnAttributes = $columnOverride->attributes(); $column = $columnAttributes['No']; $columnWidth = $columnAttributes['Unit'] / 5.4; @@ -734,7 +734,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $defaultHeight = $rowAttributes['DefaultSizePts']; $r = 0; - foreach($sheet->Rows->RowInfo as $rowOverride) { + foreach ($sheet->Rows->RowInfo as $rowOverride) { $rowAttributes = $rowOverride->attributes(); $row = $rowAttributes['No']; $rowHeight = $rowAttributes['Unit']; @@ -760,7 +760,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Handle Merged Cells in this worksheet if (isset($sheet->MergedRegions)) { - foreach($sheet->MergedRegions->Merge as $mergeCells) { + foreach ($sheet->MergedRegions->Merge as $mergeCells) { if (strpos($mergeCells,':') !== FALSE) { $objPHPExcel->getActiveSheet()->mergeCells($mergeCells); } @@ -772,14 +772,14 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Loop through definedNames (global named ranges) if (isset($gnmXML->Names)) { - foreach($gnmXML->Names->Name as $namedRange) { + foreach ($gnmXML->Names->Name as $namedRange) { $name = (string) $namedRange->name; $range = (string) $namedRange->value; if (stripos($range, '#REF!') !== false) { continue; } - $range = explode('!',$range); + $range = explode('!', $range); $range[0] = trim($range[0],"'");; if ($worksheet = $objPHPExcel->getSheetByName($range[0])) { $extractedRange = str_replace('$', '', $range[1]); @@ -861,12 +861,12 @@ private function _parseRichText($is = '') { private static function _parseGnumericColour($gnmColour) { - list($gnmR,$gnmG,$gnmB) = explode(':',$gnmColour); + list($gnmR, $gnmG, $gnmB) = explode(':', $gnmColour); $gnmR = substr(str_pad($gnmR,4,'0',STR_PAD_RIGHT),0,2); $gnmG = substr(str_pad($gnmG,4,'0',STR_PAD_RIGHT),0,2); $gnmB = substr(str_pad($gnmB,4,'0',STR_PAD_RIGHT),0,2); $RGB = $gnmR.$gnmG.$gnmB; -// echo 'Excel Colour: ',$RGB,'<br />'; +// echo 'Excel Colour: ', $RGB,'<br />'; return $RGB; } diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 663bc813a..c212e9bcc 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -89,12 +89,12 @@ public function canRead($pFilename) $stat = $zip->statName('mimetype'); if ($stat && ($stat['size'] <= 255)) { $mimeType = $zip->getFromName($stat['name']); - } elseif($stat = $zip->statName('META-INF/manifest.xml')) { + } elseif ($stat = $zip->statName('META-INF/manifest.xml')) { $xml = simplexml_load_string($this->securityScan($zip->getFromName('META-INF/manifest.xml')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $namespacesContent = $xml->getNamespaces(true); if (isset($namespacesContent['manifest'])) { $manifest = $xml->children($namespacesContent['manifest']); - foreach($manifest as $manifestDataSet) { + foreach ($manifest as $manifestDataSet) { $manifestAttributes = $manifestDataSet->attributes($namespacesContent['manifest']); if ($manifestAttributes->{'full-path'} == '/') { $mimeType = (string) $manifestAttributes->{'media-type'}; @@ -222,7 +222,7 @@ public function listWorksheetInfo($pFilename) $rowspan = $xml->getAttribute('table:number-rows-repeated'); $rowspan = empty($rowspan) ? 1 : $rowspan; $tmpInfo['totalRows'] += $rowspan; - $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells); $currCells = 0; // Step into the row $xml->read(); @@ -243,14 +243,14 @@ public function listWorksheetInfo($pFilename) } } while ($xml->name != 'table:table'); - $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells); $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); $worksheetInfo[] = $tmpInfo; } } -// foreach($workbookData->table as $worksheetDataSet) { +// foreach ($workbookData->table as $worksheetDataSet) { // $worksheetData = $worksheetDataSet->children($namespacesContent['table']); // $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']); // @@ -309,7 +309,7 @@ public function load($pFilename) private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { $styleAttributeValue = strtolower($styleAttributeValue); - foreach($styleList as $style) { + foreach ($styleList as $style) { if ($styleAttributeValue == strtolower($style)) { $styleAttributeValue = $style; return true; @@ -353,12 +353,12 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $docProps = $objPHPExcel->getProperties(); $officeProperty = $xml->children($namespacesMeta['office']); - foreach($officeProperty as $officePropertyData) { + foreach ($officeProperty as $officePropertyData) { $officePropertyDC = array(); if (isset($namespacesMeta['dc'])) { $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); } - foreach($officePropertyDC as $propertyName => $propertyValue) { + foreach ($officePropertyDC as $propertyName => $propertyValue) { $propertyValue = (string) $propertyValue; switch ($propertyName) { case 'title' : @@ -385,7 +385,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if (isset($namespacesMeta['dc'])) { $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); } - foreach($officePropertyMeta as $propertyName => $propertyValue) { + foreach ($officePropertyMeta as $propertyName => $propertyValue) { $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']); $propertyValue = (string) $propertyValue; switch ($propertyName) { @@ -404,7 +404,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($propertyValueAttributes as $key => $value) { if ($key == 'name') { $propertyValueName = (string) $value; - } elseif($key == 'value-type') { + } elseif ($key == 'value-type') { switch ($value) { case 'date' : $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date'); @@ -423,7 +423,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } } - $docProps->setCustomProperty($propertyValueName,$propertyValue,$propertyValueType); + $docProps->setCustomProperty($propertyValueName, $propertyValue, $propertyValueType); break; } } @@ -438,10 +438,10 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo '</pre><hr />'; $workbook = $xml->children($namespacesContent['office']); - foreach($workbook->body->spreadsheet as $workbookData) { + foreach ($workbook->body->spreadsheet as $workbookData) { $workbookData = $workbookData->children($namespacesContent['table']); $worksheetID = 0; - foreach($workbookData->table as $worksheetDataSet) { + foreach ($workbookData->table as $worksheetDataSet) { $worksheetData = $worksheetDataSet->children($namespacesContent['table']); // print_r($worksheetData); // echo '<br />'; @@ -466,7 +466,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } $rowID = 1; - foreach($worksheetData as $key => $rowData) { + foreach ($worksheetData as $key => $rowData) { // echo '<b>'.$key.'</b><br />'; switch ($key) { case 'table-header-rows': @@ -479,7 +479,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? $rowDataTableAttributes['number-rows-repeated'] : 1; $columnID = 'A'; - foreach($rowData as $key => $cellData) { + foreach ($rowData as $key => $cellData) { if ($this->getReadFilter() !== NULL) { if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { continue; @@ -514,16 +514,16 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo 'Cell has comment<br />'; $annotationText = $cellDataOffice->annotation->children($namespacesContent['text']); $textArray = array(); - foreach($annotationText as $t) { + foreach ($annotationText as $t) { if (isset($t->span)) { - foreach($t->span as $text) { + foreach ($t->span as $text) { $textArray[] = (string)$text; } } else { $textArray[] = (string) $t; } } - $text = implode("\n",$textArray); + $text = implode("\n", $textArray); // echo $text,'<br />'; $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) // ->setAuthor( $author ) @@ -596,8 +596,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; $dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT); $dateObj->setTimeZone($timezoneObj); - list($year,$month,$day,$hour,$minute,$second) = explode(' ',$dateObj->format('Y m d H i s')); - $dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year,$month,$day,$hour,$minute,$second); + list($year, $month, $day, $hour, $minute, $second) = explode(' ', $dateObj->format('Y m d H i s')); + $dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year, $month, $day, $hour, $minute, $second); if ($dataValue != floor($dataValue)) { $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; } else { @@ -623,21 +623,21 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $type = PHPExcel_Cell_DataType::TYPE_FORMULA; // echo 'Formula: ', $cellDataFormula, PHP_EOL; $cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1); - $temp = explode('"',$cellDataFormula); + $temp = explode('"', $cellDataFormula); $tKey = false; - foreach($temp as &$value) { + foreach ($temp as &$value) { // Only replace in alternate array entries (i.e. non-quoted blocks) if ($tKey = !$tKey) { - $value = preg_replace('/\[([^\.]+)\.([^\.]+):\.([^\.]+)\]/Ui','$1!$2:$3',$value); // Cell range reference in another sheet - $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/Ui','$1!$2',$value); // Cell reference in another sheet - $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/Ui','$1:$2',$value); // Cell range reference - $value = preg_replace('/\[\.([^\.]+)\]/Ui','$1',$value); // Simple cell reference - $value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces); + $value = preg_replace('/\[([^\.]+)\.([^\.]+):\.([^\.]+)\]/Ui','$1!$2:$3', $value); // Cell range reference in another sheet + $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/Ui','$1!$2', $value); // Cell reference in another sheet + $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/Ui','$1:$2', $value); // Cell range reference + $value = preg_replace('/\[\.([^\.]+)\]/Ui','$1', $value); // Simple cell reference + $value = PHPExcel_Calculation::_translateSeparator(';',',', $value, $inBraces); } } unset($value); // Then rebuild the formula string - $cellDataFormula = implode('"',$temp); + $cellDataFormula = implode('"', $temp); // echo 'Adjusted Formula: ', $cellDataFormula, PHP_EOL; } @@ -651,7 +651,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if ($type !== PHPExcel_Cell_DataType::TYPE_NULL) { for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) { $rID = $rowID + $rowAdjust; - $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type); + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue), $type); if ($hasCalculatedValue) { // echo 'Forumla result is '.$dataValue.'<br />'; $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue); diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index 1eee8666b..85569d9a3 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -167,8 +167,8 @@ public function listWorksheetInfo($pFilename) $dataType = array_shift($rowData); if ($dataType == 'C') { // Read cell value data - foreach($rowData as $rowDatum) { - switch($rowDatum{0}) { + foreach ($rowData as $rowDatum) { + switch ($rowDatum{0}) { case 'C' : case 'X' : $columnIndex = substr($rowDatum,1) - 1; @@ -256,9 +256,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Read shared styles if ($dataType == 'P') { $formatArray = array(); - foreach($rowData as $rowDatum) { - switch($rowDatum{0}) { - case 'P' : $formatArray['numberformat']['code'] = str_replace($fromFormats,$toFormats,substr($rowDatum,1)); + foreach ($rowData as $rowDatum) { + switch ($rowDatum{0}) { + case 'P' : $formatArray['numberformat']['code'] = str_replace($fromFormats, $toFormats,substr($rowDatum,1)); break; case 'E' : case 'F' : $formatArray['font']['name'] = substr($rowDatum,1); @@ -290,8 +290,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } elseif ($dataType == 'C') { $hasCalculatedValue = false; $cellData = $cellDataFormula = ''; - foreach($rowData as $rowDatum) { - switch($rowDatum{0}) { + foreach ($rowData as $rowDatum) { + switch ($rowDatum{0}) { case 'C' : case 'X' : $column = substr($rowDatum,1); break; @@ -302,19 +302,19 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) break; case 'E' : $cellDataFormula = '='.substr($rowDatum,1); // Convert R1C1 style references to A1 style references (but only when not quoted) - $temp = explode('"',$cellDataFormula); + $temp = explode('"', $cellDataFormula); $key = false; - foreach($temp as &$value) { + foreach ($temp as &$value) { // Only count/replace in alternate array entries if ($key = !$key) { - preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way // through the formula from left to right. Reversing means that we work right to left.through // the formula $cellReferences = array_reverse($cellReferences); // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, // then modify the formula to use that new reference - foreach($cellReferences as $cellReference) { + foreach ($cellReferences as $cellReference) { $rowReference = $cellReference[2][0]; // Empty R reference is the current row if ($rowReference == '') $rowReference = $row; @@ -327,13 +327,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if ($columnReference{0} == '[') $columnReference = $column + trim($columnReference,'[]'); $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; - $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0])); + $value = substr_replace($value, $A1CellReference, $cellReference[0][1],strlen($cellReference[0][0])); } } } unset($value); // Then rebuild the formula string - $cellDataFormula = implode('"',$temp); + $cellDataFormula = implode('"', $temp); $hasCalculatedValue = true; break; } @@ -351,8 +351,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } elseif ($dataType == 'F') { $formatStyle = $columnWidth = $styleSettings = ''; $styleData = array(); - foreach($rowData as $rowDatum) { - switch($rowDatum{0}) { + foreach ($rowData as $rowDatum) { + switch ($rowDatum{0}) { case 'C' : case 'X' : $column = substr($rowDatum,1); break; @@ -361,7 +361,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) break; case 'P' : $formatStyle = $rowDatum; break; - case 'W' : list($startCol,$endCol,$columnWidth) = explode(' ',substr($rowDatum,1)); + case 'W' : list($startCol, $endCol, $columnWidth) = explode(' ',substr($rowDatum,1)); break; case 'S' : $styleSettings = substr($rowDatum,1); for ($i=0;$i<strlen($styleSettings);++$i) { @@ -407,8 +407,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } } else { - foreach($rowData as $rowDatum) { - switch($rowDatum{0}) { + foreach ($rowData as $rowDatum) { + switch ($rowDatum{0}) { case 'C' : case 'X' : $column = substr($rowDatum,1); break; diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 9144c01d2..5854629f6 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -416,7 +416,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } // Loop through cells, bottom-up, and change cell coordinates - if($remove) { + if ($remove) { // It's faster to reverse and pop than to use unshift, especially with large cell collections $aCellCollection = array_reverse($aCellCollection); } @@ -548,7 +548,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P if (count($autoFilterColumns) > 0) { sscanf($pBefore,'%[A-Z]%d', $column, $row); $columnIndex = PHPExcel_Cell::columnIndexFromString($column); - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($autoFilterRange); + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($autoFilterRange); if ($columnIndex <= $rangeEnd[0]) { if ($pNumCols < 0) { // If we're actually deleting any columns that fall within the autofilter range, @@ -556,7 +556,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P $deleteColumn = $columnIndex + $pNumCols - 1; $deleteCount = abs($pNumCols); for ($i = 1; $i <= $deleteCount; ++$i) { - if (in_array(PHPExcel_Cell::stringFromColumnIndex($deleteColumn),$autoFilterColumns)) { + if (in_array(PHPExcel_Cell::stringFromColumnIndex($deleteColumn), $autoFilterColumns)) { $autoFilter->clearColumn(PHPExcel_Cell::stringFromColumnIndex($deleteColumn)); } ++$deleteColumn; @@ -586,7 +586,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P $toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1); $endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]); do { - $autoFilter->shiftColumn($startColID,$toColID); + $autoFilter->shiftColumn($startColID, $toColID); ++$startColID; ++$toColID; } while ($startColID != $endColID); @@ -644,9 +644,9 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P */ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, $sheetName = '') { // Update cell references in the formula - $formulaBlocks = explode('"',$pFormula); + $formulaBlocks = explode('"', $pFormula); $i = false; - foreach($formulaBlocks as &$formulaBlock) { + foreach ($formulaBlocks as &$formulaBlock) { // Ignore blocks that were enclosed in quotes (alternating entries in the $formulaBlocks array after the explode) if ($i = !$i) { $adjustCount = 0; @@ -654,11 +654,11 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo // Search for row ranges (e.g. 'Sheet1'!3:5 or 3:5) with or without $ absolutes (e.g. $3:5) $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_ROWRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); if ($matchCount > 0) { - foreach($matches as $match) { + foreach ($matches as $match) { $fromString = ($match[2] > '') ? $match[2].'!' : ''; $fromString .= $match[3].':'.$match[4]; - $modified3 = substr($this->updateCellReference('$A'.$match[3],$pBefore,$pNumCols,$pNumRows),2); - $modified4 = substr($this->updateCellReference('$A'.$match[4],$pBefore,$pNumCols,$pNumRows),2); + $modified3 = substr($this->updateCellReference('$A'.$match[3], $pBefore, $pNumCols, $pNumRows),2); + $modified4 = substr($this->updateCellReference('$A'.$match[4], $pBefore, $pNumCols, $pNumRows),2); if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { @@ -679,11 +679,11 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo // Search for column ranges (e.g. 'Sheet1'!C:E or C:E) with or without $ absolutes (e.g. $C:E) $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_COLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); if ($matchCount > 0) { - foreach($matches as $match) { + foreach ($matches as $match) { $fromString = ($match[2] > '') ? $match[2].'!' : ''; $fromString .= $match[3].':'.$match[4]; - $modified3 = substr($this->updateCellReference($match[3].'$1',$pBefore,$pNumCols,$pNumRows),0,-2); - $modified4 = substr($this->updateCellReference($match[4].'$1',$pBefore,$pNumCols,$pNumRows),0,-2); + $modified3 = substr($this->updateCellReference($match[3].'$1', $pBefore, $pNumCols, $pNumRows),0,-2); + $modified4 = substr($this->updateCellReference($match[4].'$1', $pBefore, $pNumCols, $pNumRows),0,-2); if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { @@ -704,17 +704,17 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo // Search for cell ranges (e.g. 'Sheet1'!A3:C5 or A3:C5) with or without $ absolutes (e.g. $A1:C$5) $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); if ($matchCount > 0) { - foreach($matches as $match) { + foreach ($matches as $match) { $fromString = ($match[2] > '') ? $match[2].'!' : ''; $fromString .= $match[3].':'.$match[4]; - $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); - $modified4 = $this->updateCellReference($match[4],$pBefore,$pNumCols,$pNumRows); + $modified3 = $this->updateCellReference($match[3], $pBefore, $pNumCols, $pNumRows); + $modified4 = $this->updateCellReference($match[4], $pBefore, $pNumCols, $pNumRows); if ($match[3].$match[4] !== $modified3.$modified4) { if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { $toString = ($match[2] > '') ? $match[2].'!' : ''; $toString .= $modified3.':'.$modified4; - list($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]); + list($column, $row) = PHPExcel_Cell::coordinateFromString($match[3]); // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; $row = trim($row,'$') + 10000000; @@ -731,16 +731,16 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLREF.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); if ($matchCount > 0) { - foreach($matches as $match) { + foreach ($matches as $match) { $fromString = ($match[2] > '') ? $match[2].'!' : ''; $fromString .= $match[3]; - $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); + $modified3 = $this->updateCellReference($match[3], $pBefore, $pNumCols, $pNumRows); if ($match[3] !== $modified3) { if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { $toString = ($match[2] > '') ? $match[2].'!' : ''; $toString .= $modified3; - list($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]); + list($column, $row) = PHPExcel_Cell::coordinateFromString($match[3]); // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; $row = trim($row,'$') + 10000000; @@ -761,14 +761,14 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo ksort($cellTokens); ksort($newCellTokens); } // Update cell references in the formula - $formulaBlock = str_replace('\\','',preg_replace($cellTokens,$newCellTokens,$formulaBlock)); + $formulaBlock = str_replace('\\','',preg_replace($cellTokens, $newCellTokens, $formulaBlock)); } } } unset($formulaBlock); // Then rebuild the formula string - return implode('"',$formulaBlocks); + return implode('"', $formulaBlocks); } /** @@ -846,7 +846,7 @@ private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumC if (ctype_alpha($range[$i][$j])) { $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference($range[$i][$j].'1', $pBefore, $pNumCols, $pNumRows)); $range[$i][$j] = $r[0]; - } elseif(ctype_digit($range[$i][$j])) { + } elseif (ctype_digit($range[$i][$j])) { $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference('A'.$range[$i][$j], $pBefore, $pNumCols, $pNumRows)); $range[$i][$j] = $r[1]; } else { diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index d0393a411..09026f83d 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -162,7 +162,7 @@ public static function ExcelToPHPObject($dateValue = 0) $seconds = round($time) - ($hours * 3600) - ($minutes * 60); $dateObj = date_create('1-Jan-1970+'.$days.' days'); - $dateObj->setTime($hours,$minutes,$seconds); + $dateObj->setTime($hours, $minutes, $seconds); return $dateObj; } @@ -188,8 +188,8 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $ti $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s') ); } elseif (is_numeric($dateValue)) { - $retValue = self::FormattedPHPToExcel( date('Y',$dateValue), date('m',$dateValue), date('d',$dateValue), - date('H',$dateValue), date('i',$dateValue), date('s',$dateValue) + $retValue = self::FormattedPHPToExcel( date('Y', $dateValue), date('m', $dateValue), date('d', $dateValue), + date('H', $dateValue), date('i', $dateValue), date('s', $dateValue) ); } date_default_timezone_set($saveTimeZone); @@ -327,7 +327,7 @@ public static function isDateTimeFormatCode($pFormatCode = '') // we don't want to test for any of our characters within the quoted blocks if (strpos($pFormatCode, '"') !== false) { $segMatcher = false; - foreach(explode('"', $pFormatCode) as $subVal) { + foreach (explode('"', $pFormatCode) as $subVal) { // Only test in alternate array entries (the non-quoted blocks) if (($segMatcher = !$segMatcher) && (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i', $subVal))) { @@ -376,7 +376,7 @@ public static function stringToExcel($dateValue = '') public static function monthStringToNumber($month) { $monthIndex = 1; - foreach(self::$monthNames as $shortMonthName => $longMonthName) { + foreach (self::$monthNames as $shortMonthName => $longMonthName) { if (($month === $longMonthName) || ($month === $shortMonthName)) { return $monthIndex; } diff --git a/Classes/PHPExcel/Shared/Drawing.php b/Classes/PHPExcel/Shared/Drawing.php index 311d9be49..90d0911be 100644 --- a/Classes/PHPExcel/Shared/Drawing.php +++ b/Classes/PHPExcel/Shared/Drawing.php @@ -181,10 +181,10 @@ public static function imagecreatefrombmp($p_sFile) // Load the image into a string $file = fopen($p_sFile,"rb"); $read = fread($file,10); - while(!feof($file)&&($read<>"")) + while (!feof($file)&&($read<>"")) $read .= fread($file,1024); - $temp = unpack("H*",$read); + $temp = unpack("H*", $read); $hex = $temp[1]; $header = substr($hex,0,108); @@ -210,7 +210,7 @@ public static function imagecreatefrombmp($p_sFile) $y = 1; // Create newimage - $image = imagecreatetruecolor($width,$height); + $image = imagecreatetruecolor($width, $height); // Grab the body from the image $body = substr($hex,108); @@ -255,8 +255,8 @@ public static function imagecreatefrombmp($p_sFile) $b = hexdec($body[$i_pos].$body[$i_pos+1]); // Calculate and draw the pixel - $color = imagecolorallocate($image,$r,$g,$b); - imagesetpixel($image,$x,$height-$y,$color); + $color = imagecolorallocate($image, $r, $g, $b); + imagesetpixel($image, $x, $height-$y, $color); // Raise the horizontal position $x++; diff --git a/Classes/PHPExcel/Shared/File.php b/Classes/PHPExcel/Shared/File.php index 8c3012d3c..f1de32427 100644 --- a/Classes/PHPExcel/Shared/File.php +++ b/Classes/PHPExcel/Shared/File.php @@ -111,7 +111,7 @@ public static function realpath($pFilename) { // Found something? if ($returnValue == '' || ($returnValue === NULL)) { $pathArray = explode('/' , $pFilename); - while(in_array('..', $pathArray) && $pathArray[0] != '..') { + while (in_array('..', $pathArray) && $pathArray[0] != '..') { for ($i = 0; $i < count($pathArray); ++$i) { if ($pathArray[$i] == '..' && $i > 0) { unset($pathArray[$i]); diff --git a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php index 386d6c13a..2f9a9ab6f 100644 --- a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php @@ -763,7 +763,7 @@ private function hqr2 () { for ($j = $nn-1; $j >= $low; --$j) { for ($i = $low; $i <= $high; ++$i) { $z = 0.0; - for ($k = $low; $k <= min($j,$high); ++$k) { + for ($k = $low; $k <= min($j, $high); ++$k) { $z = $z + $this->V[$i][$k] * $this->H[$k][$j]; } $this->V[$i][$j] = $z; diff --git a/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php b/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php index a4b226653..bffda2aa2 100644 --- a/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php @@ -82,7 +82,7 @@ public function __construct($A) { for ($i = 0; $i < $this->m; ++$i) { $LUrowi = $this->LU[$i]; // Most of the time is spent in the following dot product. - $kmax = min($i,$j); + $kmax = min($i, $j); $s = 0.0; for ($k = 0; $k < $kmax; ++$k) { $s += $LUrowi[$k] * $LUcolj[$k]; diff --git a/Classes/PHPExcel/Shared/JAMA/Matrix.php b/Classes/PHPExcel/Shared/JAMA/Matrix.php index 8d5e39d86..2ab40f221 100644 --- a/Classes/PHPExcel/Shared/JAMA/Matrix.php +++ b/Classes/PHPExcel/Shared/JAMA/Matrix.php @@ -68,7 +68,7 @@ public function __construct() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { //Rectangular matrix - m x n initialized from 2D array case 'array': $this->m = count($args[0]); @@ -173,7 +173,7 @@ public function getMatrix() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { //A($i0...; $j0...) case 'integer,integer': list($i0, $j0) = $args; @@ -426,7 +426,7 @@ public function plus() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -462,7 +462,7 @@ public function plusEquals() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -512,7 +512,7 @@ public function minus() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -548,7 +548,7 @@ public function minusEquals() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -599,7 +599,7 @@ public function arrayTimes() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -636,7 +636,7 @@ public function arrayTimesEquals() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -687,7 +687,7 @@ public function arrayRightDivide() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -743,7 +743,7 @@ public function arrayRightDivideEquals() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -780,7 +780,7 @@ public function arrayLeftDivide() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -817,7 +817,7 @@ public function arrayLeftDivideEquals() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -853,7 +853,7 @@ public function times() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $B = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } if ($this->n == $B->m) { @@ -944,7 +944,7 @@ public function power() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } break; @@ -969,7 +969,7 @@ public function power() { $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); } if ($validValues) { - $this->A[$i][$j] = pow($this->A[$i][$j],$value); + $this->A[$i][$j] = pow($this->A[$i][$j], $value); } else { $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); } @@ -994,7 +994,7 @@ public function concat() { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); - switch($match) { + switch ($match) { case 'object': if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } case 'array': diff --git a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php index 17c443573..fa832cafa 100644 --- a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php @@ -52,7 +52,7 @@ class PHPExcel_Shared_JAMA_QRDecomposition { * @return Structure to access R and the Householder vectors and compute Q. */ public function __construct($A) { - if($A instanceof PHPExcel_Shared_JAMA_Matrix) { + if ($A instanceof PHPExcel_Shared_JAMA_Matrix) { // Initialize. $this->QR = $A->getArrayCopy(); $this->m = $A->getRowDimension(); @@ -175,7 +175,7 @@ public function getQ() { /* for($i = 0; $i < count($Q); ++$i) { for($j = 0; $j < count($Q); ++$j) { - if(! isset($Q[$i][$j]) ) { + if (! isset($Q[$i][$j]) ) { $Q[$i][$j] = 0; } } diff --git a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php index 76c4786cc..f20668acd 100644 --- a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php @@ -74,7 +74,7 @@ public function __construct($Arg) { // Reduce A to bidiagonal form, storing the diagonal elements // in s and the super-diagonal elements in e. - for ($k = 0; $k < max($nct,$nrt); ++$k) { + for ($k = 0; $k < max($nct, $nrt); ++$k) { if ($k < $nct) { // Compute the transformation for the k-th column and @@ -291,7 +291,7 @@ public function __construct($Arg) { $f = $e[$p-2]; $e[$p-2] = 0.0; for ($j = $p - 2; $j >= $k; --$j) { - $t = hypo($this->s[$j],$f); + $t = hypo($this->s[$j], $f); $cs = $this->s[$j] / $t; $sn = $f / $t; $this->s[$j] = $t; @@ -353,7 +353,7 @@ public function __construct($Arg) { $g = $sk * $ek; // Chase zeros. for ($j = $k; $j < $p-1; ++$j) { - $t = hypo($f,$g); + $t = hypo($f, $g); $cs = $f/$t; $sn = $g/$t; if ($j != $k) { @@ -370,7 +370,7 @@ public function __construct($Arg) { $this->V[$i][$j] = $t; } } - $t = hypo($f,$g); + $t = hypo($f, $g); $cs = $f/$t; $sn = $g/$t; $this->s[$j] = $t; diff --git a/Classes/PHPExcel/Shared/OLE.php b/Classes/PHPExcel/Shared/OLE.php index f11490696..581e96bb8 100644 --- a/Classes/PHPExcel/Shared/OLE.php +++ b/Classes/PHPExcel/Shared/OLE.php @@ -473,8 +473,8 @@ public static function LocalDate2OLE($date = null) // days from 1-1-1601 until the beggining of UNIX era $days = 134774; // calculate seconds - $big_date = $days*24*3600 + gmmktime(date("H",$date),date("i",$date),date("s",$date), - date("m",$date),date("d",$date),date("Y",$date)); + $big_date = $days*24*3600 + gmmktime(date("H", $date),date("i", $date),date("s", $date), + date("m", $date),date("d", $date),date("Y", $date)); // multiply just to make MS happy $big_date *= 10000000; diff --git a/Classes/PHPExcel/Shared/OLE/PPS.php b/Classes/PHPExcel/Shared/OLE/PPS.php index 80875f90d..6699f4382 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS.php +++ b/Classes/PHPExcel/Shared/OLE/PPS.php @@ -204,7 +204,7 @@ public static function _savePpsSetPnt(&$raList, $to_save, $depth = 0) { if ( !is_array($to_save) || (empty($to_save)) ) { return 0xFFFFFFFF; - } elseif( count($to_save) == 1 ) { + } elseif ( count($to_save) == 1 ) { $cnt = count($raList); // If the first entry, it's the root... Don't clone it! $raList[$cnt] = ( $depth == 0 ) ? $to_save[0] : clone $to_save[0]; diff --git a/Classes/PHPExcel/Shared/OLE/PPS/Root.php b/Classes/PHPExcel/Shared/OLE/PPS/Root.php index cbf01105d..7e50dadf2 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/Root.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/Root.php @@ -271,7 +271,7 @@ public function _saveBigData($iStBlk, &$raList) //if (isset($raList[$i]->_PPS_FILE)) { // $iLen = 0; // fseek($raList[$i]->_PPS_FILE, 0); // To The Top - // while($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { + // while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { // $iLen += strlen($sBuff); // fwrite($FILE, $sBuff); // } @@ -337,7 +337,7 @@ public function _makeSmallData(&$raList) $sRes .= $raList[$i]->_data; //} if ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) { - $sRes .= str_repeat("\x00",$this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); + $sRes .= str_repeat("\x00", $this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); } // Set for PPS $raList[$i]->_StartBlock = $iSmBlk; diff --git a/Classes/PHPExcel/Shared/OLERead.php b/Classes/PHPExcel/Shared/OLERead.php index 9a8729f12..143e22d3d 100644 --- a/Classes/PHPExcel/Shared/OLERead.php +++ b/Classes/PHPExcel/Shared/OLERead.php @@ -76,7 +76,7 @@ class PHPExcel_Shared_OLERead { public function read($sFileName) { // Check if file exists and is readable - if(!is_readable($sFileName)) { + if (!is_readable($sFileName)) { throw new PHPExcel_Reader_Exception("Could not open " . $sFileName . " for reading! File does not exist, or it is not readable."); } @@ -254,7 +254,7 @@ private function _readPropertySets() { $size = self::_GetInt4d($d, self::SIZE_POS); - $name = str_replace("\x00", "", substr($d,0,$nameSize)); + $name = str_replace("\x00", "", substr($d,0, $nameSize)); $this->props[] = array ( diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index cafc4fa0c..36cc902ba 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -1837,13 +1837,13 @@ function privOptionDefaultThreshold(&$p_options) $v_memory_limit = trim($v_memory_limit); $last = strtolower(substr($v_memory_limit, -1)); - if($last == 'g') + if ($last == 'g') //$v_memory_limit = $v_memory_limit*1024*1024*1024; $v_memory_limit = $v_memory_limit*1073741824; - if($last == 'm') + if ($last == 'm') //$v_memory_limit = $v_memory_limit*1024*1024; $v_memory_limit = $v_memory_limit*1048576; - if($last == 'k') + if ($last == 'k') $v_memory_limit = $v_memory_limit*1024; $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); @@ -2412,7 +2412,7 @@ function privAddList($p_filedescr_list, &$p_result_list, &$p_options) $v_offset = @ftell($this->zip_fd); // ----- Create the Central Dir files header - for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++) + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) { // ----- Create the file header if ($v_header_list[$i]['status'] == 'ok') { diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 3d584c4c8..513a1755a 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -330,10 +330,10 @@ public static function getIsIconvEnabled() } public static function buildCharacterSets() { - if(empty(self::$_controlCharacters)) { + if (empty(self::$_controlCharacters)) { self::_buildControlCharacters(); } - if(empty(self::$_SYLKCharacters)) { + if (empty(self::$_SYLKCharacters)) { self::_buildSYLKCharacters(); } } @@ -436,19 +436,18 @@ public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = array()) // character count $ln = self::CountCharacters($value, 'UTF-8'); // option flags - if(empty($arrcRuns)){ + if (empty($arrcRuns)) { $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? 0x0001 : 0x0000; $data = pack('CC', $ln, $opt); // characters $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); - } - else { + } else { $data = pack('vC', $ln, 0x09); $data .= pack('v', count($arrcRuns)); // characters $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); - foreach ($arrcRuns as $cRun){ + foreach ($arrcRuns as $cRun) { $data .= pack('v', $cRun['strlen']); $data .= pack('v', $cRun['fontidx']); } @@ -500,9 +499,9 @@ public static function ConvertEncoding($value, $to, $from) return mb_convert_encoding($value, $to, $from); } - if($from == 'UTF-16LE'){ + if ($from == 'UTF-16LE') { return self::utf16_decode($value, false); - }else if($from == 'UTF-16BE'){ + } else if ($from == 'UTF-16BE') { return self::utf16_decode($value); } // else, no conversion @@ -525,15 +524,15 @@ public static function ConvertEncoding($value, $to, $from) * @author vadik56 */ public static function utf16_decode($str, $bom_be = TRUE) { - if( strlen($str) < 2 ) return $str; + if ( strlen($str) < 2 ) return $str; $c0 = ord($str{0}); $c1 = ord($str{1}); - if( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); } - elseif( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; } + if ( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); } + elseif ( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; } $len = strlen($str); $newstr = ''; for($i=0;$i<$len;$i+=2) { - if( $bom_be ) { $val = ord($str{$i}) << 4; $val += ord($str{$i+1}); } + if ( $bom_be ) { $val = ord($str{$i}) << 4; $val += ord($str{$i+1}); } else { $val = ord($str{$i+1}) << 4; $val += ord($str{$i}); } $newstr .= ($val == 0x228) ? "\n" : chr($val); } @@ -649,8 +648,8 @@ public static function StrCaseReverse($pValue = '') { if (self::getIsMbstringEnabled()) { $characters = self::mb_str_split($pValue); - foreach($characters as &$character) { - if(self::mb_is_upper($character)) { + foreach ($characters as &$character) { + if (self::mb_is_upper($character)) { $character = mb_strtolower($character, 'UTF-8'); } else { $character = mb_strtoupper($character, 'UTF-8'); diff --git a/Classes/PHPExcel/Shared/TimeZone.php b/Classes/PHPExcel/Shared/TimeZone.php index 8e417326b..0b92fd830 100644 --- a/Classes/PHPExcel/Shared/TimeZone.php +++ b/Classes/PHPExcel/Shared/TimeZone.php @@ -129,7 +129,7 @@ public static function getTimeZoneAdjustment($timezone, $timestamp) { $objTimezone = new DateTimeZone($timezone); if (version_compare(PHP_VERSION, '5.3.0') >= 0) { - $transitions = $objTimezone->getTransitions($timestamp,$timestamp); + $transitions = $objTimezone->getTransitions($timestamp, $timestamp); } else { $transitions = self::_getTimezoneTransitions($objTimezone, $timestamp); } diff --git a/Classes/PHPExcel/Shared/XMLWriter.php b/Classes/PHPExcel/Shared/XMLWriter.php index a17c112b8..63d2f4007 100644 --- a/Classes/PHPExcel/Shared/XMLWriter.php +++ b/Classes/PHPExcel/Shared/XMLWriter.php @@ -115,7 +115,7 @@ public function getData() { public function writeRawData($text) { if (is_array($text)) { - $text = implode("\n",$text); + $text = implode("\n", $text); } if (method_exists($this, 'writeRaw')) { diff --git a/Classes/PHPExcel/Shared/trend/bestFitClass.php b/Classes/PHPExcel/Shared/trend/bestFitClass.php index 665e22589..c508fbd49 100644 --- a/Classes/PHPExcel/Shared/trend/bestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/bestFitClass.php @@ -174,7 +174,7 @@ public function getEquation($dp=0) { */ public function getSlope($dp=0) { if ($dp != 0) { - return round($this->_slope,$dp); + return round($this->_slope, $dp); } return $this->_slope; } // function getSlope() @@ -188,7 +188,7 @@ public function getSlope($dp=0) { */ public function getSlopeSE($dp=0) { if ($dp != 0) { - return round($this->_slopeSE,$dp); + return round($this->_slopeSE, $dp); } return $this->_slopeSE; } // function getSlopeSE() @@ -202,7 +202,7 @@ public function getSlopeSE($dp=0) { */ public function getIntersect($dp=0) { if ($dp != 0) { - return round($this->_intersect,$dp); + return round($this->_intersect, $dp); } return $this->_intersect; } // function getIntersect() @@ -216,7 +216,7 @@ public function getIntersect($dp=0) { */ public function getIntersectSE($dp=0) { if ($dp != 0) { - return round($this->_intersectSE,$dp); + return round($this->_intersectSE, $dp); } return $this->_intersectSE; } // function getIntersectSE() @@ -230,7 +230,7 @@ public function getIntersectSE($dp=0) { */ public function getGoodnessOfFit($dp=0) { if ($dp != 0) { - return round($this->_goodnessOfFit,$dp); + return round($this->_goodnessOfFit, $dp); } return $this->_goodnessOfFit; } // function getGoodnessOfFit() @@ -238,7 +238,7 @@ public function getGoodnessOfFit($dp=0) { public function getGoodnessOfFitPercent($dp=0) { if ($dp != 0) { - return round($this->_goodnessOfFit * 100,$dp); + return round($this->_goodnessOfFit * 100, $dp); } return $this->_goodnessOfFit * 100; } // function getGoodnessOfFitPercent() @@ -252,7 +252,7 @@ public function getGoodnessOfFitPercent($dp=0) { */ public function getStdevOfResiduals($dp=0) { if ($dp != 0) { - return round($this->_stdevOfResiduals,$dp); + return round($this->_stdevOfResiduals, $dp); } return $this->_stdevOfResiduals; } // function getStdevOfResiduals() @@ -260,7 +260,7 @@ public function getStdevOfResiduals($dp=0) { public function getSSRegression($dp=0) { if ($dp != 0) { - return round($this->_SSRegression,$dp); + return round($this->_SSRegression, $dp); } return $this->_SSRegression; } // function getSSRegression() @@ -268,7 +268,7 @@ public function getSSRegression($dp=0) { public function getSSResiduals($dp=0) { if ($dp != 0) { - return round($this->_SSResiduals,$dp); + return round($this->_SSResiduals, $dp); } return $this->_SSResiduals; } // function getSSResiduals() @@ -276,7 +276,7 @@ public function getSSResiduals($dp=0) { public function getDFResiduals($dp=0) { if ($dp != 0) { - return round($this->_DFResiduals,$dp); + return round($this->_DFResiduals, $dp); } return $this->_DFResiduals; } // function getDFResiduals() @@ -284,7 +284,7 @@ public function getDFResiduals($dp=0) { public function getF($dp=0) { if ($dp != 0) { - return round($this->_F,$dp); + return round($this->_F, $dp); } return $this->_F; } // function getF() @@ -292,7 +292,7 @@ public function getF($dp=0) { public function getCovariance($dp=0) { if ($dp != 0) { - return round($this->_covariance,$dp); + return round($this->_covariance, $dp); } return $this->_covariance; } // function getCovariance() @@ -300,7 +300,7 @@ public function getCovariance($dp=0) { public function getCorrelation($dp=0) { if ($dp != 0) { - return round($this->_correlation,$dp); + return round($this->_correlation, $dp); } return $this->_correlation; } // function getCorrelation() @@ -311,9 +311,9 @@ public function getYBestFitValues() { } // function getYBestFitValues() - protected function _calculateGoodnessOfFit($sumX,$sumY,$sumX2,$sumY2,$sumXY,$meanX,$meanY, $const) { + protected function _calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const) { $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0; - foreach($this->_xValues as $xKey => $xValue) { + foreach ($this->_xValues as $xKey => $xValue) { $bestFitY = $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); $SSres += ($this->_yValues[$xKey] - $bestFitY) * ($this->_yValues[$xKey] - $bestFitY); @@ -398,7 +398,7 @@ protected function _leastSquareFit($yValues, $xValues, $const) { $this->_intersect = 0; } - $this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum,$meanX,$meanY,$const); + $this->_calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, $meanX, $meanY, $const); } // function _leastSquareFit() @@ -416,7 +416,7 @@ function __construct($yValues, $xValues=array(), $const=True) { // Define X Values if necessary if ($nX == 0) { - $xValues = range(1,$nY); + $xValues = range(1, $nY); $nX = $nY; } elseif ($nY != $nX) { // Ensure both arrays of points are the same size diff --git a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php index 6a92297ff..54243081b 100644 --- a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php @@ -91,7 +91,7 @@ public function getEquation($dp=0) { **/ public function getSlope($dp=0) { if ($dp != 0) { - return round(exp($this->_slope),$dp); + return round(exp($this->_slope), $dp); } return exp($this->_slope); } // function getSlope() @@ -105,7 +105,7 @@ public function getSlope($dp=0) { **/ public function getIntersect($dp=0) { if ($dp != 0) { - return round(exp($this->_intersect),$dp); + return round(exp($this->_intersect), $dp); } return exp($this->_intersect); } // function getIntersect() @@ -119,7 +119,7 @@ public function getIntersect($dp=0) { * @param boolean $const */ private function _exponential_regression($yValues, $xValues, $const) { - foreach($yValues as &$value) { + foreach ($yValues as &$value) { if ($value < 0.0) { $value = 0 - log(abs($value)); } elseif ($value > 0.0) { diff --git a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php index b60d5e779..a18d42a9e 100644 --- a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php @@ -91,7 +91,7 @@ public function getEquation($dp=0) { * @param boolean $const */ private function _linear_regression($yValues, $xValues, $const) { - $this->_leastSquareFit($yValues, $xValues,$const); + $this->_leastSquareFit($yValues, $xValues, $const); } // function _linear_regression() diff --git a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php index c15446666..b0db33e3e 100644 --- a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php @@ -91,7 +91,7 @@ public function getEquation($dp=0) { * @param boolean $const */ private function _logarithmic_regression($yValues, $xValues, $const) { - foreach($xValues as &$value) { + foreach ($xValues as &$value) { if ($value < 0.0) { $value = 0 - log(abs($value)); } elseif ($value > 0.0) { diff --git a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php index b43abe768..bd4484336 100644 --- a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php @@ -75,7 +75,7 @@ public function getOrder() { public function getValueOfYForX($xValue) { $retVal = $this->getIntersect(); $slope = $this->getSlope(); - foreach($slope as $key => $value) { + foreach ($slope as $key => $value) { if ($value != 0.0) { $retVal += $value * pow($xValue, $key + 1); } @@ -106,7 +106,7 @@ public function getEquation($dp=0) { $intersect = $this->getIntersect($dp); $equation = 'Y = '.$intersect; - foreach($slope as $key => $value) { + foreach ($slope as $key => $value) { if ($value != 0.0) { $equation .= ' + '.$value.' * X'; if ($key > 0) { @@ -127,8 +127,8 @@ public function getEquation($dp=0) { public function getSlope($dp=0) { if ($dp != 0) { $coefficients = array(); - foreach($this->_slope as $coefficient) { - $coefficients[] = round($coefficient,$dp); + foreach ($this->_slope as $coefficient) { + $coefficients[] = round($coefficient, $dp); } return $coefficients; } @@ -137,7 +137,7 @@ public function getSlope($dp=0) { public function getCoefficients($dp=0) { - return array_merge(array($this->getIntersect($dp)),$this->getSlope($dp)); + return array_merge(array($this->getIntersect($dp)), $this->getSlope($dp)); } // function getCoefficients() @@ -191,8 +191,8 @@ private function _polynomial_regression($order, $yValues, $xValues, $const) { $this->_intersect = array_shift($coefficients); $this->_slope = $coefficients; - $this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum); - foreach($this->_xValues as $xKey => $xValue) { + $this->_calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum); + foreach ($this->_xValues as $xKey => $xValue) { $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); } } // function _polynomial_regression() diff --git a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php index e4b229bd9..4f2a07352 100644 --- a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php @@ -54,7 +54,7 @@ class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit * @return float Y-Value **/ public function getValueOfYForX($xValue) { - return $this->getIntersect() * pow(($xValue - $this->_Xoffset),$this->getSlope()); + return $this->getIntersect() * pow(($xValue - $this->_Xoffset), $this->getSlope()); } // function getValueOfYForX() @@ -91,7 +91,7 @@ public function getEquation($dp=0) { **/ public function getIntersect($dp=0) { if ($dp != 0) { - return round(exp($this->_intersect),$dp); + return round(exp($this->_intersect), $dp); } return exp($this->_intersect); } // function getIntersect() @@ -105,7 +105,7 @@ public function getIntersect($dp=0) { * @param boolean $const */ private function _power_regression($yValues, $xValues, $const) { - foreach($xValues as &$value) { + foreach ($xValues as &$value) { if ($value < 0.0) { $value = 0 - log(abs($value)); } elseif ($value > 0.0) { @@ -113,7 +113,7 @@ private function _power_regression($yValues, $xValues, $const) { } } unset($value); - foreach($yValues as &$value) { + foreach ($yValues as &$value) { if ($value < 0.0) { $value = 0 - log(abs($value)); } elseif ($value > 0.0) { diff --git a/Classes/PHPExcel/Shared/trend/trendClass.php b/Classes/PHPExcel/Shared/trend/trendClass.php index cbd5101b0..6d16c7ead 100644 --- a/Classes/PHPExcel/Shared/trend/trendClass.php +++ b/Classes/PHPExcel/Shared/trend/trendClass.php @@ -91,7 +91,7 @@ public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xVa // Define X Values if necessary if ($nX == 0) { - $xValues = range(1,$nY); + $xValues = range(1, $nY); $nX = $nY; } elseif ($nY != $nX) { // Ensure both arrays of points are the same size @@ -108,7 +108,7 @@ public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xVa case self::TREND_POWER : if (!isset(self::$_trendCache[$key])) { $className = 'PHPExcel_'.$trendType.'_Best_Fit'; - self::$_trendCache[$key] = new $className($yValues,$xValues,$const); + self::$_trendCache[$key] = new $className($yValues, $xValues, $const); } return self::$_trendCache[$key]; break; @@ -119,7 +119,7 @@ public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xVa case self::TREND_POLYNOMIAL_6 : if (!isset(self::$_trendCache[$key])) { $order = substr($trendType,-1); - self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const); + self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order, $yValues, $xValues, $const); } return self::$_trendCache[$key]; break; @@ -127,15 +127,15 @@ public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xVa case self::TREND_BEST_FIT_NO_POLY : // If the request is to determine the best fit regression, then we test each trend line in turn // Start by generating an instance of each available trend method - foreach(self::$_trendTypes as $trendMethod) { + foreach (self::$_trendTypes as $trendMethod) { $className = 'PHPExcel_'.$trendMethod.'BestFit'; - $bestFit[$trendMethod] = new $className($yValues,$xValues,$const); + $bestFit[$trendMethod] = new $className($yValues, $xValues, $const); $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); } if ($trendType != self::TREND_BEST_FIT_NO_POLY) { - foreach(self::$_trendTypePolyOrders as $trendMethod) { + foreach (self::$_trendTypePolyOrders as $trendMethod) { $order = substr($trendMethod,-1); - $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const); + $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order, $yValues, $xValues, $const); if ($bestFit[$trendMethod]->getError()) { unset($bestFit[$trendMethod]); } else { diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 8d380848f..8e2a7d951 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -378,7 +378,7 @@ public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') * */ public function disconnectCells() { - if ( $this->_cellCollection !== NULL){ + if ( $this->_cellCollection !== NULL) { $this->_cellCollection->unsetWorksheetCells(); $this->_cellCollection = NULL; } @@ -620,7 +620,7 @@ public function getChartByIndex($index = null) public function getChartNames() { $chartNames = array(); - foreach($this->_chartCollection as $chart) { + foreach ($this->_chartCollection as $chart) { $chartNames[] = $chart->getName(); } return $chartNames; @@ -639,7 +639,7 @@ public function getChartByName($chartName = '') if ($chartCount == 0) { return false; } - foreach($this->_chartCollection as $index => $chart) { + foreach ($this->_chartCollection as $index => $chart) { if ($chart->getName() == $chartName) { return $this->_chartCollection[$index]; } @@ -858,7 +858,7 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t } $altTitle = $pValue . ' ' . $i; - return $this->setTitle($altTitle,$updateFormulaCellReferences); + return $this->setTitle($altTitle, $updateFormulaCellReferences); } } @@ -1314,7 +1314,7 @@ public function getRowDimension($pRow = 1, $create = TRUE) return NULL; $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow); - $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow); + $this->_cachedHighestRow = max($this->_cachedHighestRow, $pRow); } return $this->_rowDimensions[$pRow]; } @@ -1571,7 +1571,7 @@ public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') */ public function duplicateConditionalStyle(array $pCellStyle = null, $pRange = '') { - foreach($pCellStyle as $cellStyle) { + foreach ($pCellStyle as $cellStyle) { if (!($cellStyle instanceof PHPExcel_Style_Conditional)) { throw new PHPExcel_Exception('Style is not a conditional style'); } @@ -1899,7 +1899,7 @@ public function setAutoFilter($pValue) if (is_string($pValue)) { $this->_autoFilter->setRange($pValue); - } elseif(is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) { + } elseif (is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) { $this->_autoFilter = $pValue; } return $this; @@ -2406,7 +2406,7 @@ public function fromArray($source = null, $nullValue = null, $startCell = 'A1', // Loop through $source foreach ($source as $rowData) { $currentColumn = $startColumn; - foreach($rowData as $cellValue) { + foreach ($rowData as $cellValue) { if ($strictNullComparison) { if ($cellValue !== $nullValue) { // Set cell value @@ -2600,7 +2600,7 @@ public function garbageCollect() { // Loop through row dimensions foreach ($this->_rowDimensions as $dimension) { - $highestRow = max($highestRow,$dimension->getRowIndex()); + $highestRow = max($highestRow, $dimension->getRowIndex()); } // Cache values @@ -2779,7 +2779,7 @@ public function shrinkRangeToFit($range) { $maxRow = $this->getHighestRow(); $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol); - $rangeBlocks = explode(' ',$range); + $rangeBlocks = explode(' ', $range); foreach ($rangeBlocks as &$rangeSet) { $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($rangeSet); @@ -2790,7 +2790,7 @@ public function shrinkRangeToFit($range) { $rangeSet = $rangeBoundaries[0][0].$rangeBoundaries[0][1].':'.$rangeBoundaries[1][0].$rangeBoundaries[1][1]; } unset($rangeSet); - $stRange = implode(' ',$rangeBlocks); + $stRange = implode(' ', $rangeBlocks); return $stRange; } @@ -2876,7 +2876,7 @@ public function __clone() { * @return objWorksheet * @throws PHPExcel_Exception */ - public function setCodeName($pValue=null){ + public function setCodeName($pValue=null) { // Is this a 'rename' or not? if ($this->getCodeName() == $pValue) { return $this; @@ -2912,7 +2912,7 @@ public function setCodeName($pValue=null){ $pValue = $pValue . '_' . $i;// ok, we have a valid name //codeName is'nt used in formula : no need to call for an update - //return $this->setTitle($altTitle,$updateFormulaCellReferences); + //return $this->setTitle($altTitle, $updateFormulaCellReferences); } } @@ -2924,14 +2924,14 @@ public function setCodeName($pValue=null){ * * @return null|string */ - public function getCodeName(){ + public function getCodeName() { return $this->_codeName; } /** * Sheet has a code name ? * @return boolean */ - public function hasCodeName(){ + public function hasCodeName() { return !(is_null($this->_codeName)); } } diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index 92868a4da..325c906d6 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -112,12 +112,12 @@ public function setRange($pRange = '') { // Uppercase coordinate $cellAddress = explode('!',strtoupper($pRange)); if (count($cellAddress) > 1) { - list($worksheet,$pRange) = $cellAddress; + list($worksheet, $pRange) = $cellAddress; } if (strpos($pRange,':') !== FALSE) { $this->_range = $pRange; - } elseif(empty($pRange)) { + } elseif (empty($pRange)) { $this->_range = ''; } else { throw new PHPExcel_Exception('Autofilter must be set on a range of cells.'); @@ -128,8 +128,8 @@ public function setRange($pRange = '') { $this->_columns = array(); } else { // Discard any column rules that are no longer valid within this range - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); - foreach($this->_columns as $key => $value) { + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + foreach ($this->_columns as $key => $value) { $colIndex = PHPExcel_Cell::columnIndexFromString($key); if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) { unset($this->_columns[$key]); @@ -163,7 +163,7 @@ public function testColumnInRange($column) { } $columnIndex = PHPExcel_Cell::columnIndexFromString($column); - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) { throw new PHPExcel_Exception("Column is outside of current autofilter range."); } @@ -207,7 +207,7 @@ public function getColumn($pColumn) { * @return PHPExcel_Worksheet_AutoFilter_Column */ public function getColumnByOffset($pColumnOffset = 0) { - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); $pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1); return $this->getColumn($pColumn); @@ -225,7 +225,7 @@ public function setColumn($pColumn) { if ((is_string($pColumn)) && (!empty($pColumn))) { $column = $pColumn; - } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { + } elseif (is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { $column = $pColumn->getColumnIndex(); } else { throw new PHPExcel_Exception("Column is not within the autofilter range."); @@ -234,7 +234,7 @@ public function setColumn($pColumn) if (is_string($pColumn)) { $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); - } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { + } elseif (is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { $pColumn->setParent($this); $this->_columns[$column] = $pColumn; } @@ -271,7 +271,7 @@ public function clearColumn($pColumn) { * @param string $toColumn Column name (e.g. B) * @return PHPExcel_Worksheet_AutoFilter */ - public function shiftColumn($fromColumn=NULL,$toColumn=NULL) { + public function shiftColumn($fromColumn=NULL, $toColumn=NULL) { $fromColumn = strtoupper($fromColumn); $toColumn = strtoupper($toColumn); @@ -296,14 +296,14 @@ public function shiftColumn($fromColumn=NULL,$toColumn=NULL) { * @param mixed[] $dataSet * @return boolean */ - private static function _filterTestInSimpleDataSet($cellValue,$dataSet) + private static function _filterTestInSimpleDataSet($cellValue, $dataSet) { $dataSetValues = $dataSet['filterValues']; $blanks = $dataSet['blanks']; if (($cellValue == '') || ($cellValue === NULL)) { return $blanks; } - return in_array($cellValue,$dataSetValues); + return in_array($cellValue, $dataSetValues); } /** @@ -313,7 +313,7 @@ private static function _filterTestInSimpleDataSet($cellValue,$dataSet) * @param mixed[] $dataSet * @return boolean */ - private static function _filterTestInDateGroupSet($cellValue,$dataSet) + private static function _filterTestInDateGroupSet($cellValue, $dataSet) { $dateSet = $dataSet['filterValues']; $blanks = $dataSet['blanks']; @@ -325,18 +325,18 @@ private static function _filterTestInDateGroupSet($cellValue,$dataSet) $dateValue = PHPExcel_Shared_Date::ExcelToPHP($cellValue); if ($cellValue < 1) { // Just the time part - $dtVal = date('His',$dateValue); + $dtVal = date('His', $dateValue); $dateSet = $dateSet['time']; - } elseif($cellValue == floor($cellValue)) { + } elseif ($cellValue == floor($cellValue)) { // Just the date part - $dtVal = date('Ymd',$dateValue); + $dtVal = date('Ymd', $dateValue); $dateSet = $dateSet['date']; } else { // date and time parts - $dtVal = date('YmdHis',$dateValue); + $dtVal = date('YmdHis', $dateValue); $dateSet = $dateSet['dateTime']; } - foreach($dateSet as $dateValue) { + foreach ($dateSet as $dateValue) { // Use of substr to extract value at the appropriate group level if (substr($dtVal,0,strlen($dateValue)) == $dateValue) return TRUE; @@ -366,7 +366,7 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) } } $returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); - foreach($dataSet as $rule) { + foreach ($dataSet as $rule) { if (is_numeric($rule['value'])) { // Numeric values are tested using the appropriate operator switch ($rule['operator']) { @@ -389,7 +389,7 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) $retVal = ($cellValue <= $rule['value']); break; } - } elseif($rule['value'] == '') { + } elseif ($rule['value'] == '') { switch ($rule['operator']) { case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : $retVal = (($cellValue == '') || ($cellValue === NULL)); @@ -403,7 +403,7 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) } } else { // String values are always tested for equality, factoring in for wildcards (hence a regexp test) - $retVal = preg_match('/^'.$rule['value'].'$/i',$cellValue); + $retVal = preg_match('/^'.$rule['value'].'$/i', $cellValue); } // If there are multiple conditions, then we need to test both using the appropriate join operator switch ($join) { @@ -439,7 +439,7 @@ private static function _filterTestInPeriodDateSet($cellValue, $monthSet) if (is_numeric($cellValue)) { $dateValue = date('m',PHPExcel_Shared_Date::ExcelToPHP($cellValue)); - if (in_array($dateValue,$monthSet)) { + if (in_array($dateValue, $monthSet)) { return TRUE; } } @@ -474,28 +474,28 @@ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) // Calculate start/end dates for the required date range based on current date switch ($dynamicRuleType) { case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : - $baseDate = strtotime('-7 days',$baseDate); + $baseDate = strtotime('-7 days', $baseDate); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : - $baseDate = strtotime('-7 days',$baseDate); + $baseDate = strtotime('-7 days', $baseDate); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : - $baseDate = strtotime('-1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + $baseDate = strtotime('-1 month',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : - $baseDate = strtotime('+1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + $baseDate = strtotime('+1 month',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : - $baseDate = strtotime('-3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + $baseDate = strtotime('-3 month',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : - $baseDate = strtotime('+3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + $baseDate = strtotime('+3 month',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : - $baseDate = strtotime('-1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + $baseDate = strtotime('-1 year',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : - $baseDate = strtotime('+1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + $baseDate = strtotime('+1 year',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); break; } @@ -503,40 +503,40 @@ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : - $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day', $baseDate)); $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE : - $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day', $baseDate)); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : - $maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,31,12,date('Y',$baseDate))); + $maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,31,12,date('Y', $baseDate))); ++$maxVal; - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : - $thisMonth = date('m',$baseDate); + $thisMonth = date('m', $baseDate); $thisQuarter = floor(--$thisMonth / 3); - $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),(1+$thisQuarter)*3,date('Y',$baseDate))); + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t', $baseDate),(1+$thisQuarter)*3,date('Y', $baseDate))); ++$maxVal; - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1+$thisQuarter*3,date('Y',$baseDate))); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1+$thisQuarter*3,date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : - $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),date('m',$baseDate),date('Y',$baseDate))); + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t', $baseDate),date('m', $baseDate),date('Y', $baseDate))); ++$maxVal; - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : - $dayOfWeek = date('w',$baseDate); + $dayOfWeek = date('w', $baseDate); $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate) - $dayOfWeek; $maxVal = $val + 7; break; @@ -577,7 +577,7 @@ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) ); } - private function _calculateTopTenValue($columnID,$startRow,$endRow,$ruleType,$ruleValue) { + private function _calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, $ruleValue) { $range = $columnID.$startRow.':'.$columnID.$endRow; $dataValues = PHPExcel_Calculation_Functions::flattenArray( $this->_workSheet->rangeToArray($range,NULL,TRUE,FALSE) @@ -590,7 +590,7 @@ private function _calculateTopTenValue($columnID,$startRow,$endRow,$ruleType,$ru sort($dataValues); } - return array_pop(array_slice($dataValues,0,$ruleValue)); + return array_pop(array_slice($dataValues,0, $ruleValue)); } /** @@ -601,20 +601,20 @@ private function _calculateTopTenValue($columnID,$startRow,$endRow,$ruleType,$ru */ public function showHideRows() { - list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); // The heading row should always be visible -// echo 'AutoFilter Heading Row ',$rangeStart[1],' is always SHOWN',PHP_EOL; +// echo 'AutoFilter Heading Row ', $rangeStart[1],' is always SHOWN',PHP_EOL; $this->_workSheet->getRowDimension($rangeStart[1])->setVisible(TRUE); $columnFilterTests = array(); - foreach($this->_columns as $columnID => $filterColumn) { + foreach ($this->_columns as $columnID => $filterColumn) { $rules = $filterColumn->getRules(); switch ($filterColumn->getFilterType()) { case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER : $ruleValues = array(); // Build a list of the filter value selections - foreach($rules as $rule) { + foreach ($rules as $rule) { $ruleType = $rule->getRuleType(); $ruleValues[] = $rule->getValue(); } @@ -638,26 +638,26 @@ public function showHideRows() 'time' => array(), 'dateTime' => array(), ); - foreach($ruleDataSet as $ruleValue) { + foreach ($ruleDataSet as $ruleValue) { $date = $time = ''; if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) && ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')) - $date .= sprintf('%04d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]); + $date .= sprintf('%04d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]); if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) && ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')) - $date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]); + $date .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]); if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) && ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')) - $date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]); + $date .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]); if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) && ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')) - $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]); + $time .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]); if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) && ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')) - $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]); + $time .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]); if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) && ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')) - $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]); + $time .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]); $dateTime = $date . $time; $arguments['date'][] = $date; $arguments['time'][] = $time; @@ -679,13 +679,13 @@ public function showHideRows() $customRuleForBlanks = FALSE; $ruleValues = array(); // Build a list of the filter value selections - foreach($rules as $rule) { + foreach ($rules as $rule) { $ruleType = $rule->getRuleType(); $ruleValue = $rule->getValue(); if (!is_numeric($ruleValue)) { // Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards $ruleValue = preg_quote($ruleValue); - $ruleValue = str_replace(self::$_fromReplace,self::$_toReplace,$ruleValue); + $ruleValue = str_replace(self::$_fromReplace,self::$_toReplace, $ruleValue); if (trim($ruleValue) == '') { $customRuleForBlanks = TRUE; $ruleValue = trim($ruleValue); @@ -706,7 +706,7 @@ public function showHideRows() break; case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER : $ruleValues = array(); - foreach($rules as $rule) { + foreach ($rules as $rule) { // We should only ever have one Dynamic Filter Rule anyway $dynamicRuleType = $rule->getGrouping(); if (($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) || @@ -714,7 +714,7 @@ public function showHideRows() // Number (Average) based // Calculate the average $averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')'; - $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,NULL,$this->_workSheet->getCell('A1')); + $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,NULL, $this->_workSheet->getCell('A1')); // Set above/below rule based on greaterThan or LessTan $operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN @@ -757,7 +757,7 @@ public function showHideRows() case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER : $ruleValues = array(); $dataRowCount = $rangeEnd[1] - $rangeStart[1]; - foreach($rules as $rule) { + foreach ($rules as $rule) { // We should only ever have one Dynamic Filter Rule anyway $toptenRuleType = $rule->getGrouping(); $ruleValue = $rule->getValue(); @@ -769,7 +769,7 @@ public function showHideRows() if ($ruleValue < 1) $ruleValue = 1; if ($ruleValue > 500) $ruleValue = 500; - $maxVal = $this->_calculateTopTenValue($columnID,$rangeStart[1]+1,$rangeEnd[1],$toptenRuleType,$ruleValue); + $maxVal = $this->_calculateTopTenValue($columnID, $rangeStart[1]+1, $rangeEnd[1], $toptenRuleType, $ruleValue); $operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL @@ -795,16 +795,16 @@ public function showHideRows() // // Execute the column tests for each row in the autoFilter range to determine show/hide, for ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) { -// echo 'Testing Row = ',$row,PHP_EOL; +// echo 'Testing Row = ', $row,PHP_EOL; $result = TRUE; - foreach($columnFilterTests as $columnID => $columnFilterTest) { -// echo 'Testing cell ',$columnID.$row,PHP_EOL; + foreach ($columnFilterTests as $columnID => $columnFilterTest) { +// echo 'Testing cell ', $columnID.$row,PHP_EOL; $cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue(); -// echo 'Value is ',$cellValue,PHP_EOL; +// echo 'Value is ', $cellValue,PHP_EOL; // Execute the filter test $result = $result && call_user_func_array( - array('PHPExcel_Worksheet_AutoFilter',$columnFilterTest['method']), + array('PHPExcel_Worksheet_AutoFilter', $columnFilterTest['method']), array( $cellValue, $columnFilterTest['arguments'] diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php index 98c4630c0..ecf93fa22 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -322,7 +322,7 @@ public function getValue() { public function setValue($pValue = '') { if (is_array($pValue)) { $grouping = -1; - foreach($pValue as $key => $value) { + foreach ($pValue as $key => $value) { // Validate array entries if (!in_array($key,self::$_dateTimeGroups)) { // Remove any invalid entries from the value array diff --git a/Classes/PHPExcel/Worksheet/PageSetup.php b/Classes/PHPExcel/Worksheet/PageSetup.php index 2070cf901..6a98d47b1 100644 --- a/Classes/PHPExcel/Worksheet/PageSetup.php +++ b/Classes/PHPExcel/Worksheet/PageSetup.php @@ -575,7 +575,7 @@ public function getPrintArea($index = 0) { if ($index == 0) { return $this->_printArea; } - $printAreas = explode(',',$this->_printArea); + $printAreas = explode(',', $this->_printArea); if (isset($printAreas[$index-1])) { return $printAreas[$index-1]; } @@ -595,7 +595,7 @@ public function isPrintAreaSet($index = 0) { if ($index == 0) { return !is_null($this->_printArea); } - $printAreas = explode(',',$this->_printArea); + $printAreas = explode(',', $this->_printArea); return isset($printAreas[$index-1]); } @@ -612,10 +612,10 @@ public function clearPrintArea($index = 0) { if ($index == 0) { $this->_printArea = NULL; } else { - $printAreas = explode(',',$this->_printArea); + $printAreas = explode(',', $this->_printArea); if (isset($printAreas[$index-1])) { unset($printAreas[$index-1]); - $this->_printArea = implode(',',$printAreas); + $this->_printArea = implode(',', $printAreas); } } @@ -656,29 +656,29 @@ public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_O if ($index == 0) { $this->_printArea = $value; } else { - $printAreas = explode(',',$this->_printArea); - if($index < 0) { + $printAreas = explode(',', $this->_printArea); + if ($index < 0) { $index = count($printAreas) - abs($index) + 1; } if (($index <= 0) || ($index > count($printAreas))) { throw new PHPExcel_Exception('Invalid index for setting print range.'); } $printAreas[$index-1] = $value; - $this->_printArea = implode(',',$printAreas); + $this->_printArea = implode(',', $printAreas); } - } elseif($method == self::SETPRINTRANGE_INSERT) { + } elseif ($method == self::SETPRINTRANGE_INSERT) { if ($index == 0) { $this->_printArea .= ($this->_printArea == '') ? $value : ','.$value; } else { - $printAreas = explode(',',$this->_printArea); - if($index < 0) { + $printAreas = explode(',', $this->_printArea); + if ($index < 0) { $index = abs($index) - 1; } if ($index > count($printAreas)) { throw new PHPExcel_Exception('Invalid index for setting print range.'); } - $printAreas = array_merge(array_slice($printAreas,0,$index),array($value),array_slice($printAreas,$index)); - $this->_printArea = implode(',',$printAreas); + $printAreas = array_merge(array_slice($printAreas,0, $index),array($value),array_slice($printAreas, $index)); + $this->_printArea = implode(',', $printAreas); } } else { throw new PHPExcel_Exception('Invalid method for setting print range.'); diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php index 74cbc1a16..1540a22b0 100644 --- a/Classes/PHPExcel/Writer/CSV.php +++ b/Classes/PHPExcel/Writer/CSV.php @@ -98,7 +98,7 @@ public function save($pFilename = null) $sheet = $this->_phpExcel->getSheet($this->_sheetIndex); $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(false); $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); @@ -124,9 +124,9 @@ public function save($pFilename = null) $maxRow = $sheet->getHighestDataRow(); // Write rows to file - for($row = 1; $row <= $maxRow; ++$row) { + for ($row = 1; $row <= $maxRow; ++$row) { // Convert the row to an array... - $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row,'', $this->_preCalculateFormulas); + $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row, '', $this->_preCalculateFormulas); // ... and write to the file $this->_writeLine($fileHandle, $cellsArray[0]); } @@ -143,7 +143,8 @@ public function save($pFilename = null) * * @return string */ - public function getDelimiter() { + public function getDelimiter() + { return $this->_delimiter; } @@ -153,7 +154,8 @@ public function getDelimiter() { * @param string $pValue Delimiter, defaults to , * @return PHPExcel_Writer_CSV */ - public function setDelimiter($pValue = ',') { + public function setDelimiter($pValue = ',') + { $this->_delimiter = $pValue; return $this; } @@ -163,7 +165,8 @@ public function setDelimiter($pValue = ',') { * * @return string */ - public function getEnclosure() { + public function getEnclosure() + { return $this->_enclosure; } @@ -173,7 +176,8 @@ public function getEnclosure() { * @param string $pValue Enclosure, defaults to " * @return PHPExcel_Writer_CSV */ - public function setEnclosure($pValue = '"') { + public function setEnclosure($pValue = '"') + { if ($pValue == '') { $pValue = null; } @@ -186,7 +190,8 @@ public function setEnclosure($pValue = '"') { * * @return string */ - public function getLineEnding() { + public function getLineEnding() + { return $this->_lineEnding; } @@ -196,7 +201,8 @@ public function getLineEnding() { * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) * @return PHPExcel_Writer_CSV */ - public function setLineEnding($pValue = PHP_EOL) { + public function setLineEnding($pValue = PHP_EOL) + { $this->_lineEnding = $pValue; return $this; } @@ -206,7 +212,8 @@ public function setLineEnding($pValue = PHP_EOL) { * * @return boolean */ - public function getUseBOM() { + public function getUseBOM() + { return $this->_useBOM; } @@ -216,7 +223,8 @@ public function getUseBOM() { * @param boolean $pValue Use UTF-8 byte-order mark? Defaults to false * @return PHPExcel_Writer_CSV */ - public function setUseBOM($pValue = false) { + public function setUseBOM($pValue = false) + { $this->_useBOM = $pValue; return $this; } @@ -226,7 +234,8 @@ public function setUseBOM($pValue = false) { * * @return boolean */ - public function getExcelCompatibility() { + public function getExcelCompatibility() + { return $this->_excelCompatibility; } @@ -237,7 +246,8 @@ public function getExcelCompatibility() { * Note that this overrides other settings such as useBOM, enclosure and delimiter * @return PHPExcel_Writer_CSV */ - public function setExcelCompatibility($pValue = false) { + public function setExcelCompatibility($pValue = false) + { $this->_excelCompatibility = $pValue; return $this; } @@ -247,7 +257,8 @@ public function setExcelCompatibility($pValue = false) { * * @return int */ - public function getSheetIndex() { + public function getSheetIndex() + { return $this->_sheetIndex; } @@ -257,7 +268,8 @@ public function getSheetIndex() { * @param int $pValue Sheet index * @return PHPExcel_Writer_CSV */ - public function setSheetIndex($pValue = 0) { + public function setSheetIndex($pValue = 0) + { $this->_sheetIndex = $pValue; return $this; } @@ -269,7 +281,8 @@ public function setSheetIndex($pValue = 0) { * @param array $pValues Array containing values in a row * @throws PHPExcel_Writer_Exception */ - private function _writeLine($pFileHandle = null, $pValues = null) { + private function _writeLine($pFileHandle = null, $pValues = null) + { if (is_array($pValues)) { // No leading delimiter $writeDelimiter = false; @@ -301,5 +314,4 @@ private function _writeLine($pFileHandle = null, $pValues = null) { throw new PHPExcel_Writer_Exception("Invalid data row passed to CSV writer."); } } - } diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index 6a2be44c5..756bf4dcc 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -125,18 +125,18 @@ public function __construct(PHPExcel $pPHPExcel = null) // Assign PHPExcel $this->setPHPExcel($pPHPExcel); - $writerPartsArray = array( 'stringtable' => 'PHPExcel_Writer_Excel2007_StringTable', - 'contenttypes' => 'PHPExcel_Writer_Excel2007_ContentTypes', - 'docprops' => 'PHPExcel_Writer_Excel2007_DocProps', - 'rels' => 'PHPExcel_Writer_Excel2007_Rels', - 'theme' => 'PHPExcel_Writer_Excel2007_Theme', - 'style' => 'PHPExcel_Writer_Excel2007_Style', - 'workbook' => 'PHPExcel_Writer_Excel2007_Workbook', - 'worksheet' => 'PHPExcel_Writer_Excel2007_Worksheet', - 'drawing' => 'PHPExcel_Writer_Excel2007_Drawing', - 'comments' => 'PHPExcel_Writer_Excel2007_Comments', - 'chart' => 'PHPExcel_Writer_Excel2007_Chart', - 'relsvba' => 'PHPExcel_Writer_Excel2007_RelsVBA', + $writerPartsArray = array( 'stringtable' => 'PHPExcel_Writer_Excel2007_StringTable', + 'contenttypes' => 'PHPExcel_Writer_Excel2007_ContentTypes', + 'docprops' => 'PHPExcel_Writer_Excel2007_DocProps', + 'rels' => 'PHPExcel_Writer_Excel2007_Rels', + 'theme' => 'PHPExcel_Writer_Excel2007_Theme', + 'style' => 'PHPExcel_Writer_Excel2007_Style', + 'workbook' => 'PHPExcel_Writer_Excel2007_Workbook', + 'worksheet' => 'PHPExcel_Writer_Excel2007_Worksheet', + 'drawing' => 'PHPExcel_Writer_Excel2007_Drawing', + 'comments' => 'PHPExcel_Writer_Excel2007_Comments', + 'chart' => 'PHPExcel_Writer_Excel2007_Chart', + 'relsvba' => 'PHPExcel_Writer_Excel2007_RelsVBA', 'relsribbonobjects' => 'PHPExcel_Writer_Excel2007_RelsRibbon' ); @@ -163,7 +163,8 @@ public function __construct(PHPExcel $pPHPExcel = null) * @param string $pPartName Writer part name * @return PHPExcel_Writer_Excel2007_WriterPart */ - public function getWriterPart($pPartName = '') { + public function getWriterPart($pPartName = '') + { if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) { return $this->_writerParts[strtolower($pPartName)]; } else { @@ -179,7 +180,7 @@ public function getWriterPart($pPartName = '') { */ public function save($pFilename = null) { - if ($this->_spreadSheet !== NULL) { + if ($this->_spreadSheet !== null) { // garbage collect $this->_spreadSheet->garbageCollect(); @@ -193,7 +194,7 @@ public function save($pFilename = null) } $saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(FALSE); + PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(false); $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); @@ -204,15 +205,15 @@ public function save($pFilename = null) } // Create styles dictionaries - $this->_styleHashTable->addFromSource( $this->getWriterPart('Style')->allStyles($this->_spreadSheet) ); - $this->_stylesConditionalHashTable->addFromSource( $this->getWriterPart('Style')->allConditionalStyles($this->_spreadSheet) ); - $this->_fillHashTable->addFromSource( $this->getWriterPart('Style')->allFills($this->_spreadSheet) ); - $this->_fontHashTable->addFromSource( $this->getWriterPart('Style')->allFonts($this->_spreadSheet) ); - $this->_bordersHashTable->addFromSource( $this->getWriterPart('Style')->allBorders($this->_spreadSheet) ); - $this->_numFmtHashTable->addFromSource( $this->getWriterPart('Style')->allNumberFormats($this->_spreadSheet) ); + $this->_styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->_spreadSheet)); + $this->_stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->_spreadSheet)); + $this->_fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->_spreadSheet)); + $this->_fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->_spreadSheet)); + $this->_bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->_spreadSheet)); + $this->_numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->_spreadSheet)); // Create drawing dictionary - $this->_drawingHashTable->addFromSource( $this->getWriterPart('Drawing')->allDrawings($this->_spreadSheet) ); + $this->_drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->_spreadSheet)); // Create new ZIP file and open it for writing $zipClass = PHPExcel_Settings::getZipClass(); @@ -235,60 +236,58 @@ public function save($pFilename = null) } // Add [Content_Types].xml to ZIP file - $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->_includeCharts)); + $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->_includeCharts)); //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) - if($this->_spreadSheet->hasMacros()){ + if ($this->_spreadSheet->hasMacros()) { $macrosCode=$this->_spreadSheet->getMacrosCode(); - if(!is_null($macrosCode)){// we have the code ? + if (!is_null($macrosCode)) {// we have the code ? $objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin - if($this->_spreadSheet->hasMacrosCertificate()){//signed macros ? + if ($this->_spreadSheet->hasMacrosCertificate()) {//signed macros ? // Yes : add the certificate file and the related rels file $objZip->addFromString('xl/vbaProjectSignature.bin', $this->_spreadSheet->getMacrosCertificate()); - $objZip->addFromString('xl/_rels/vbaProject.bin.rels', - $this->getWriterPart('RelsVBA')->writeVBARelationships($this->_spreadSheet)); + $objZip->addFromString('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->_spreadSheet)); } } } //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) - if($this->_spreadSheet->hasRibbon()){ + if ($this->_spreadSheet->hasRibbon()) { $tmpRibbonTarget=$this->_spreadSheet->getRibbonXMLData('target'); $objZip->addFromString($tmpRibbonTarget, $this->_spreadSheet->getRibbonXMLData('data')); - if($this->_spreadSheet->hasRibbonBinObjects()){ + if ($this->_spreadSheet->hasRibbonBinObjects()) { $tmpRootPath=dirname($tmpRibbonTarget).'/'; $ribbonBinObjects=$this->_spreadSheet->getRibbonBinObjects('data');//the files to write - foreach($ribbonBinObjects as $aPath=>$aContent){ + foreach ($ribbonBinObjects as $aPath=>$aContent) { $objZip->addFromString($tmpRootPath.$aPath, $aContent); } //the rels for files - $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', - $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->_spreadSheet)); + $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->_spreadSheet)); } } // Add relationships to ZIP file - $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->_spreadSheet)); - $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->_spreadSheet)); + $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->_spreadSheet)); + $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->_spreadSheet)); // Add document properties to ZIP file - $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->_spreadSheet)); - $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->_spreadSheet)); + $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->_spreadSheet)); + $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->_spreadSheet)); $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->_spreadSheet); - if ($customPropertiesPart !== NULL) { - $objZip->addFromString('docProps/custom.xml', $customPropertiesPart); + if ($customPropertiesPart !== null) { + $objZip->addFromString('docProps/custom.xml', $customPropertiesPart); } // Add theme to ZIP file - $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->_spreadSheet)); + $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->_spreadSheet)); // Add string table to ZIP file - $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->_stringTable)); + $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->_stringTable)); // Add styles to ZIP file - $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->_spreadSheet)); + $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->_spreadSheet)); // Add workbook to ZIP file - $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->_spreadSheet, $this->_preCalculateFormulas)); + $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->_spreadSheet, $this->_preCalculateFormulas)); $chartCount = 0; // Add worksheets @@ -297,7 +296,7 @@ public function save($pFilename = null) if ($this->_includeCharts) { $charts = $this->_spreadSheet->getSheet($i)->getChartCollection(); if (count($charts) > 0) { - foreach($charts as $chart) { + foreach ($charts as $chart) { $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart)); $chartCount++; } @@ -308,9 +307,8 @@ public function save($pFilename = null) $chartRef1 = $chartRef2 = 0; // Add worksheet relationships (drawings, ...) for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { - // Add relationships - $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->_spreadSheet->getSheet($i), ($i + 1), $this->_includeCharts)); + $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->_spreadSheet->getSheet($i), ($i + 1), $this->_includeCharts)); $drawings = $this->_spreadSheet->getSheet($i)->getDrawingCollection(); $drawingCount = count($drawings); @@ -321,10 +319,10 @@ public function save($pFilename = null) // Add drawing and image relationship parts if (($drawingCount > 0) || ($chartCount > 0)) { // Drawing relationships - $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->_spreadSheet->getSheet($i),$chartRef1, $this->_includeCharts)); + $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->_spreadSheet->getSheet($i), $chartRef1, $this->_includeCharts)); // Drawings - $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->_spreadSheet->getSheet($i),$chartRef2,$this->_includeCharts)); + $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->_spreadSheet->getSheet($i), $chartRef2, $this->_includeCharts)); } // Add comment relationship parts @@ -409,7 +407,8 @@ public function save($pFilename = null) * @return PHPExcel * @throws PHPExcel_Writer_Exception */ - public function getPHPExcel() { + public function getPHPExcel() + { if ($this->_spreadSheet !== null) { return $this->_spreadSheet; } else { @@ -424,7 +423,8 @@ public function getPHPExcel() { * @throws PHPExcel_Writer_Exception * @return PHPExcel_Writer_Excel2007 */ - public function setPHPExcel(PHPExcel $pPHPExcel = null) { + public function setPHPExcel(PHPExcel $pPHPExcel = null) + { $this->_spreadSheet = $pPHPExcel; return $this; } @@ -434,7 +434,8 @@ public function setPHPExcel(PHPExcel $pPHPExcel = null) { * * @return string[] */ - public function getStringTable() { + public function getStringTable() + { return $this->_stringTable; } @@ -443,7 +444,8 @@ public function getStringTable() { * * @return PHPExcel_HashTable */ - public function getStyleHashTable() { + public function getStyleHashTable() + { return $this->_styleHashTable; } @@ -452,7 +454,8 @@ public function getStyleHashTable() { * * @return PHPExcel_HashTable */ - public function getStylesConditionalHashTable() { + public function getStylesConditionalHashTable() + { return $this->_stylesConditionalHashTable; } @@ -461,7 +464,8 @@ public function getStylesConditionalHashTable() { * * @return PHPExcel_HashTable */ - public function getFillHashTable() { + public function getFillHashTable() + { return $this->_fillHashTable; } @@ -470,7 +474,8 @@ public function getFillHashTable() { * * @return PHPExcel_HashTable */ - public function getFontHashTable() { + public function getFontHashTable() + { return $this->_fontHashTable; } @@ -479,7 +484,8 @@ public function getFontHashTable() { * * @return PHPExcel_HashTable */ - public function getBordersHashTable() { + public function getBordersHashTable() + { return $this->_bordersHashTable; } @@ -488,7 +494,8 @@ public function getBordersHashTable() { * * @return PHPExcel_HashTable */ - public function getNumFmtHashTable() { + public function getNumFmtHashTable() + { return $this->_numFmtHashTable; } @@ -497,7 +504,8 @@ public function getNumFmtHashTable() { * * @return PHPExcel_HashTable */ - public function getDrawingHashTable() { + public function getDrawingHashTable() + { return $this->_drawingHashTable; } @@ -506,7 +514,8 @@ public function getDrawingHashTable() { * * @return boolean */ - public function getOffice2003Compatibility() { + public function getOffice2003Compatibility() + { return $this->_office2003compatibility; } @@ -516,9 +525,9 @@ public function getOffice2003Compatibility() { * @param boolean $pValue Office2003 compatibility? * @return PHPExcel_Writer_Excel2007 */ - public function setOffice2003Compatibility($pValue = false) { + public function setOffice2003Compatibility($pValue = false) + { $this->_office2003compatibility = $pValue; return $this; } - } diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index a610a13ed..93cff286b 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -32,1575 +32,1473 @@ * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ -class PHPExcel_Writer_Excel2007_Chart extends - PHPExcel_Writer_Excel2007_WriterPart { - - /** - * Write charts to XML format - * - * @param PHPExcel_Chart $pChart - * - * @return string XML Output - * @throws PHPExcel_Writer_Exception - */ - public function writeChart(PHPExcel_Chart $pChart = NULL) { - // Create XML writer - $objWriter = NULL; - if ($this->getParentWriter() - ->getUseDiskCaching() - ) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter() - ->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - // Ensure that data series values are up-to-date before we save - $pChart->refresh(); - - // XML header - $objWriter->startDocument('1.0', 'UTF-8', 'yes'); - - // c:chartSpace - $objWriter->startElement('c:chartSpace'); - $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); - $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); - $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - - $objWriter->startElement('c:date1904'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - $objWriter->startElement('c:lang'); - $objWriter->writeAttribute('val', "en-GB"); - $objWriter->endElement(); - $objWriter->startElement('c:roundedCorners'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $this->_writeAlternateContent($objWriter); - - $objWriter->startElement('c:chart'); - - $this->_writeTitle($pChart->getTitle(), $objWriter); - - $objWriter->startElement('c:autoTitleDeleted'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $this->_writePlotArea( - $pChart->getPlotArea(), - $pChart->getXAxisLabel(), - $pChart->getYAxisLabel(), - $objWriter, - $pChart->getWorksheet(), - $pChart->getChartAxisX(), - $pChart->getChartAxisY(), - $pChart->getMajorGridlines(), - $pChart->getMinorGridlines() - ); - - $this->_writeLegend($pChart->getLegend(), $objWriter); - - $objWriter->startElement('c:plotVisOnly'); - $objWriter->writeAttribute('val', 1); - $objWriter->endElement(); - - $objWriter->startElement('c:dispBlanksAs'); - $objWriter->writeAttribute('val', "gap"); - $objWriter->endElement(); - - $objWriter->startElement('c:showDLblsOverMax'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $objWriter->endElement(); - - $this->_writePrintSettings($objWriter); - - $objWriter->endElement(); - - // Return - return $objWriter->getData(); - } - - /** - * Write Chart Title - * - * @param PHPExcel_Chart_Title $title - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * - * @throws PHPExcel_Writer_Exception - */ - private function _writeTitle(PHPExcel_Chart_Title $title = NULL, $objWriter) { - if (is_null($title)) { - return; - } +class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPart { + /** + * Write charts to XML format + * + * @param PHPExcel_Chart $pChart + * + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeChart(PHPExcel_Chart $pChart = null) { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + // Ensure that data series values are up-to-date before we save + $pChart->refresh(); - $objWriter->startElement('c:title'); - $objWriter->startElement('c:tx'); - $objWriter->startElement('c:rich'); + // XML header + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); - $objWriter->startElement('a:bodyPr'); - $objWriter->endElement(); + // c:chartSpace + $objWriter->startElement('c:chartSpace'); + $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - $objWriter->startElement('a:lstStyle'); - $objWriter->endElement(); + $objWriter->startElement('c:date1904'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + $objWriter->startElement('c:lang'); + $objWriter->writeAttribute('val', "en-GB"); + $objWriter->endElement(); + $objWriter->startElement('c:roundedCorners'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); - $objWriter->startElement('a:p'); + $this->_writeAlternateContent($objWriter); - $caption = $title->getCaption(); - if ((is_array($caption)) && (count($caption) > 0)) { - $caption = $caption[0]; - } - $this->getParentWriter() - ->getWriterPart('stringtable') - ->writeRichTextForCharts($objWriter, $caption, 'a'); - - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - - $layout = $title->getLayout(); - $this->_writeLayout($layout, $objWriter); - - $objWriter->startElement('c:overlay'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write Chart Legend - * - * @param PHPExcel_Chart_Legend $legend - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * - * @throws PHPExcel_Writer_Exception - */ - private function _writeLegend(PHPExcel_Chart_Legend $legend = NULL, $objWriter) { - if (is_null($legend)) { - return; - } + $objWriter->startElement('c:chart'); - $objWriter->startElement('c:legend'); - - $objWriter->startElement('c:legendPos'); - $objWriter->writeAttribute('val', $legend->getPosition()); - $objWriter->endElement(); - - $layout = $legend->getLayout(); - $this->_writeLayout($layout, $objWriter); - - $objWriter->startElement('c:overlay'); - $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0'); - $objWriter->endElement(); - - $objWriter->startElement('c:txPr'); - $objWriter->startElement('a:bodyPr'); - $objWriter->endElement(); - - $objWriter->startElement('a:lstStyle'); - $objWriter->endElement(); - - $objWriter->startElement('a:p'); - $objWriter->startElement('a:pPr'); - $objWriter->writeAttribute('rtl', 0); - - $objWriter->startElement('a:defRPr'); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('a:endParaRPr'); - $objWriter->writeAttribute('lang', "en-US"); - $objWriter->endElement(); - - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write Chart Plot Area - * - * @param PHPExcel_Chart_PlotArea $plotArea - * @param PHPExcel_Chart_Title $xAxisLabel - * @param PHPExcel_Chart_Title $yAxisLabel - * @param PHPExcel_Chart_Axis $xAxis - * @param PHPExcel_Chart_Axis $yAxis - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * - * @throws PHPExcel_Writer_Exception - */ - private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, - PHPExcel_Chart_Title $xAxisLabel = NULL, - PHPExcel_Chart_Title $yAxisLabel = NULL, - $objWriter, - PHPExcel_Worksheet $pSheet, - PHPExcel_Chart_Axis $xAxis, - PHPExcel_Chart_Axis $yAxis, - PHPExcel_Chart_GridLines $majorGridlines, - PHPExcel_Chart_GridLines $minorGridlines - ) { - if (is_null($plotArea)) { - return; - } + $this->_writeTitle($pChart->getTitle(), $objWriter); - $id1 = $id2 = 0; - $this->_seriesIndex = 0; - $objWriter->startElement('c:plotArea'); + $objWriter->startElement('c:autoTitleDeleted'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); - $layout = $plotArea->getLayout(); + $this->_writePlotArea($pChart->getPlotArea(), $pChart->getXAxisLabel(), $pChart->getYAxisLabel(), $objWriter, $pChart->getWorksheet(), $pChart->getChartAxisX(), $pChart->getChartAxisY(), $pChart->getMajorGridlines(), $pChart->getMinorGridlines()); - $this->_writeLayout($layout, $objWriter); + $this->_writeLegend($pChart->getLegend(), $objWriter); - $chartTypes = self::_getChartType($plotArea); - $catIsMultiLevelSeries = $valIsMultiLevelSeries = FALSE; - $plotGroupingType = ''; - foreach ($chartTypes as $chartType) { - $objWriter->startElement('c:' . $chartType); + $objWriter->startElement('c:plotVisOnly'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); - $groupCount = $plotArea->getPlotGroupCount(); - for ($i = 0; $i < $groupCount; ++$i) { - $plotGroup = $plotArea->getPlotGroupByIndex($i); - $groupType = $plotGroup->getPlotType(); - if ($groupType == $chartType) { + $objWriter->startElement('c:dispBlanksAs'); + $objWriter->writeAttribute('val', "gap"); + $objWriter->endElement(); - $plotStyle = $plotGroup->getPlotStyle(); - if ($groupType === PHPExcel_Chart_DataSeries::TYPE_RADARCHART) { - $objWriter->startElement('c:radarStyle'); - $objWriter->writeAttribute('val', $plotStyle); - $objWriter->endElement(); - } elseif ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) { - $objWriter->startElement('c:scatterStyle'); - $objWriter->writeAttribute('val', $plotStyle); - $objWriter->endElement(); - } + $objWriter->startElement('c:showDLblsOverMax'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); - $this->_writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet); - } - } + $objWriter->endElement(); - $this->_writeDataLbls($objWriter, $layout); + $this->_writePrintSettings($objWriter); - if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) { - // Line only, Line3D can't be smoothed + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } - $objWriter->startElement('c:smooth'); - $objWriter->writeAttribute('val', (integer) $plotGroup->getSmoothLine()); + /** + * Write Chart Title + * + * @param PHPExcel_Chart_Title $title + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) { + if (is_null($title)) { + return; + } + + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); + + $objWriter->startElement('a:bodyPr'); $objWriter->endElement(); - } elseif (($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || - ($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) - ) { - $objWriter->startElement('c:gapWidth'); - $objWriter->writeAttribute('val', 150); + $objWriter->startElement('a:lstStyle'); $objWriter->endElement(); - if ($plotGroupingType == 'percentStacked' || - $plotGroupingType == 'stacked' - ) { + $objWriter->startElement('a:p'); - $objWriter->startElement('c:overlap'); - $objWriter->writeAttribute('val', 100); - $objWriter->endElement(); + $caption = $title->getCaption(); + if ((is_array($caption)) && (count($caption) > 0)) { + $caption = $caption[0]; } - } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a'); - $objWriter->startElement('c:bubbleScale'); - $objWriter->writeAttribute('val', 25); + $objWriter->endElement(); + $objWriter->endElement(); $objWriter->endElement(); - $objWriter->startElement('c:showNegBubbles'); + $this->_writeLayout($title->getLayout(), $objWriter); + + $objWriter->startElement('c:overlay'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); - } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { - $objWriter->startElement('c:hiLowLines'); $objWriter->endElement(); + } - $objWriter->startElement('c:upDownBars'); + /** + * Write Chart Legend + * + * @param PHPExcel_Chart_Legend $legend + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) { + if (is_null($legend)) { + return; + } + + $objWriter->startElement('c:legend'); - $objWriter->startElement('c:gapWidth'); - $objWriter->writeAttribute('val', 300); + $objWriter->startElement('c:legendPos'); + $objWriter->writeAttribute('val', $legend->getPosition()); $objWriter->endElement(); - $objWriter->startElement('c:upBars'); + $this->_writeLayout($legend->getLayout(), $objWriter); + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0'); $objWriter->endElement(); - $objWriter->startElement('c:downBars'); + $objWriter->startElement('c:txPr'); + $objWriter->startElement('a:bodyPr'); $objWriter->endElement(); + $objWriter->startElement('a:lstStyle'); $objWriter->endElement(); - } - // Generate 2 unique numbers to use for axId values - // $id1 = $id2 = rand(10000000,99999999); - // do { - // $id2 = rand(10000000,99999999); - // } while ($id1 == $id2); - $id1 = '75091328'; - $id2 = '75089408'; + $objWriter->startElement('a:p'); + $objWriter->startElement('a:pPr'); + $objWriter->writeAttribute('rtl', 0); - if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && - ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && - ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) - ) { + $objWriter->startElement('a:defRPr'); + $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->startElement('c:axId'); - $objWriter->writeAttribute('val', $id1); + $objWriter->startElement('a:endParaRPr'); + $objWriter->writeAttribute('lang', "en-US"); $objWriter->endElement(); - $objWriter->startElement('c:axId'); - $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); - } else { - $objWriter->startElement('c:firstSliceAng'); - $objWriter->writeAttribute('val', 0); $objWriter->endElement(); - if ($chartType === PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) { + $objWriter->endElement(); + } - $objWriter->startElement('c:holeSize'); - $objWriter->writeAttribute('val', 50); - $objWriter->endElement(); + /** + * Write Chart Plot Area + * + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $xAxisLabel + * @param PHPExcel_Chart_Title $yAxisLabel + * @param PHPExcel_Chart_Axis $xAxis + * @param PHPExcel_Chart_Axis $yAxis + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, $objWriter, PHPExcel_Worksheet $pSheet, PHPExcel_Chart_Axis $xAxis, PHPExcel_Chart_Axis $yAxis, PHPExcel_Chart_GridLines $majorGridlines, PHPExcel_Chart_GridLines $minorGridlines ) + { + if (is_null($plotArea)) { + return; } - } - $objWriter->endElement(); - } + $id1 = $id2 = 0; + $this->_seriesIndex = 0; + $objWriter->startElement('c:plotArea'); - if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && - ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && - ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) - ) { + $layout = $plotArea->getLayout(); - if ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $this->_writeValAx($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); - } else { - $this->_writeCatAx($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis); - } + $this->_writeLayout($layout, $objWriter); - $this->_writeValAx($objWriter, $plotArea, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); - } + $chartTypes = self::_getChartType($plotArea); + $catIsMultiLevelSeries = $valIsMultiLevelSeries = false; + $plotGroupingType = ''; + foreach ($chartTypes as $chartType) { + $objWriter->startElement('c:' . $chartType); + + $groupCount = $plotArea->getPlotGroupCount(); + for ($i = 0; $i < $groupCount; ++$i) { + $plotGroup = $plotArea->getPlotGroupByIndex($i); + $groupType = $plotGroup->getPlotType(); + if ($groupType == $chartType) { + $plotStyle = $plotGroup->getPlotStyle(); + if ($groupType === PHPExcel_Chart_DataSeries::TYPE_RADARCHART) { + $objWriter->startElement('c:radarStyle'); + $objWriter->writeAttribute('val', $plotStyle); + $objWriter->endElement(); + } elseif ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) { + $objWriter->startElement('c:scatterStyle'); + $objWriter->writeAttribute('val', $plotStyle); + $objWriter->endElement(); + } + + $this->_writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet); + } + } - $objWriter->endElement(); - } - - /** - * Write Data Labels - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Chart_Layout $chartLayout Chart layout - * - * @throws PHPExcel_Writer_Exception - */ - private function _writeDataLbls($objWriter, $chartLayout) { - $objWriter->startElement('c:dLbls'); - - $objWriter->startElement('c:showLegendKey'); - $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey(); - $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1)); - $objWriter->endElement(); - - $objWriter->startElement('c:showVal'); - $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal(); - $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1)); - $objWriter->endElement(); - - $objWriter->startElement('c:showCatName'); - $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName(); - $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1)); - $objWriter->endElement(); - - $objWriter->startElement('c:showSerName'); - $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName(); - $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1)); - $objWriter->endElement(); - - $objWriter->startElement('c:showPercent'); - $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent(); - $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1)); - $objWriter->endElement(); - - $objWriter->startElement('c:showBubbleSize'); - $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize(); - $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1)); - $objWriter->endElement(); - - $objWriter->startElement('c:showLeaderLines'); - $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines(); - $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1)); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write Category Axis - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Chart_PlotArea $plotArea - * @param PHPExcel_Chart_Title $xAxisLabel - * @param string $groupType Chart type - * @param string $id1 - * @param string $id2 - * @param boolean $isMultiLevelSeries - * - * @throws PHPExcel_Writer_Exception - */ - private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis) { - $objWriter->startElement('c:catAx'); - - if ($id1 > 0) { - $objWriter->startElement('c:axId'); - $objWriter->writeAttribute('val', $id1); - $objWriter->endElement(); - } + $this->_writeDataLbls($objWriter, $layout); + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) { + // Line only, Line3D can't be smoothed + + $objWriter->startElement('c:smooth'); + $objWriter->writeAttribute('val', (integer) $plotGroup->getSmoothLine()); + $objWriter->endElement(); + } elseif (($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) ||($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) { + $objWriter->startElement('c:gapWidth'); + $objWriter->writeAttribute('val', 150); + $objWriter->endElement(); + + if ($plotGroupingType == 'percentStacked' || $plotGroupingType == 'stacked') { + $objWriter->startElement('c:overlap'); + $objWriter->writeAttribute('val', 100); + $objWriter->endElement(); + } + } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $objWriter->startElement('c:bubbleScale'); + $objWriter->writeAttribute('val', 25); + $objWriter->endElement(); + + $objWriter->startElement('c:showNegBubbles'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { + $objWriter->startElement('c:hiLowLines'); + $objWriter->endElement(); + + $objWriter->startElement('c:upDownBars'); + + $objWriter->startElement('c:gapWidth'); + $objWriter->writeAttribute('val', 300); + $objWriter->endElement(); + + $objWriter->startElement('c:upBars'); + $objWriter->endElement(); + + $objWriter->startElement('c:downBars'); + $objWriter->endElement(); + + $objWriter->endElement(); + } - $objWriter->startElement('c:scaling'); - $objWriter->startElement('c:orientation'); - $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('orientation')); - $objWriter->endElement(); - $objWriter->endElement(); + // Generate 2 unique numbers to use for axId values + // $id1 = $id2 = rand(10000000,99999999); + // do { + // $id2 = rand(10000000,99999999); + // } while ($id1 == $id2); + $id1 = '75091328'; + $id2 = '75089408'; + + if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id1); + $objWriter->endElement(); + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + } else { + $objWriter->startElement('c:firstSliceAng'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) { + $objWriter->startElement('c:holeSize'); + $objWriter->writeAttribute('val', 50); + $objWriter->endElement(); + } + } - $objWriter->startElement('c:delete'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); + $objWriter->endElement(); + } - $objWriter->startElement('c:axPos'); - $objWriter->writeAttribute('val', "b"); - $objWriter->endElement(); + if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $this->_writeValAx($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); + } else { + $this->_writeCatAx($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis); + } - if (!is_null($xAxisLabel)) { - $objWriter->startElement('c:title'); - $objWriter->startElement('c:tx'); - $objWriter->startElement('c:rich'); + $this->_writeValAx($objWriter, $plotArea, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); + } - $objWriter->startElement('a:bodyPr'); - $objWriter->endElement(); + $objWriter->endElement(); + } - $objWriter->startElement('a:lstStyle'); - $objWriter->endElement(); + /** + * Write Data Labels + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_Layout $chartLayout Chart layout + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeDataLbls($objWriter, $chartLayout) { + $objWriter->startElement('c:dLbls'); + + $objWriter->startElement('c:showLegendKey'); + $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey(); + $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1)); + $objWriter->endElement(); - $objWriter->startElement('a:p'); - $objWriter->startElement('a:r'); + $objWriter->startElement('c:showVal'); + $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal(); + $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1)); + $objWriter->endElement(); - $caption = $xAxisLabel->getCaption(); - if (is_array($caption)) { - $caption = $caption[0]; - } - $objWriter->startElement('a:t'); - // $objWriter->writeAttribute('xml:space', 'preserve'); - $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption)); - $objWriter->endElement(); + $objWriter->startElement('c:showCatName'); + $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName(); + $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1)); + $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->startElement('c:showSerName'); + $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName(); + $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1)); + $objWriter->endElement(); - $layout = $xAxisLabel->getLayout(); - $this->_writeLayout($layout, $objWriter); + $objWriter->startElement('c:showPercent'); + $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent(); + $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1)); + $objWriter->endElement(); - $objWriter->startElement('c:overlay'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); + $objWriter->startElement('c:showBubbleSize'); + $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize(); + $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1)); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->startElement('c:showLeaderLines'); + $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines(); + $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1)); + $objWriter->endElement(); + $objWriter->endElement(); } - $objWriter->startElement('c:numFmt'); - $objWriter->writeAttribute('formatCode', $yAxis->getAxisNumberFormat()); - $objWriter->writeAttribute('sourceLinked', $yAxis->getAxisNumberSourceLinked()); - $objWriter->endElement(); + /** + * Write Category Axis + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $xAxisLabel + * @param string $groupType Chart type + * @param string $id1 + * @param string $id2 + * @param boolean $isMultiLevelSeries + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis) { + $objWriter->startElement('c:catAx'); + + if ($id1 > 0) { + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id1); + $objWriter->endElement(); + } - $objWriter->startElement('c:majorTickMark'); - $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('major_tick_mark')); - $objWriter->endElement(); + $objWriter->startElement('c:scaling'); + $objWriter->startElement('c:orientation'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('orientation')); + $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->startElement('c:minorTickMark'); - $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minor_tick_mark')); - $objWriter->endElement(); + $objWriter->startElement('c:delete'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); - $objWriter->startElement('c:tickLblPos'); - $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('axis_labels')); - $objWriter->endElement(); + $objWriter->startElement('c:axPos'); + $objWriter->writeAttribute('val', "b"); + $objWriter->endElement(); - if ($id2 > 0) { - $objWriter->startElement('c:crossAx'); - $objWriter->writeAttribute('val', $id2); - $objWriter->endElement(); + if (!is_null($xAxisLabel)) { + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); - $objWriter->startElement('c:crosses'); - $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('horizontal_crosses')); - $objWriter->endElement(); - } + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); - $objWriter->startElement('c:auto'); - $objWriter->writeAttribute('val', 1); - $objWriter->endElement(); + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); - $objWriter->startElement('c:lblAlgn'); - $objWriter->writeAttribute('val', "ctr"); - $objWriter->endElement(); + $objWriter->startElement('a:p'); + $objWriter->startElement('a:r'); - $objWriter->startElement('c:lblOffset'); - $objWriter->writeAttribute('val', 100); - $objWriter->endElement(); + $caption = $xAxisLabel->getCaption(); + if (is_array($caption)) { + $caption = $caption[0]; + } + $objWriter->startElement('a:t'); + // $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption)); + $objWriter->endElement(); - if ($isMultiLevelSeries) { - $objWriter->startElement('c:noMultiLvlLbl'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - } - $objWriter->endElement(); - } - - /** - * Write Value Axis - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Chart_PlotArea $plotArea - * @param PHPExcel_Chart_Title $yAxisLabel - * @param string $groupType Chart type - * @param string $id1 - * @param string $id2 - * @param boolean $isMultiLevelSeries - * - * @throws PHPExcel_Writer_Exception - */ - private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines) { - $objWriter->startElement('c:valAx'); - - if ($id2 > 0) { - $objWriter->startElement('c:axId'); - $objWriter->writeAttribute('val', $id2); - $objWriter->endElement(); - } + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->startElement('c:scaling'); - $objWriter->startElement('c:orientation'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation')); + $layout = $xAxisLabel->getLayout(); + $this->_writeLayout($layout, $objWriter); - if (!is_null($xAxis->getAxisOptionsProperty('maximum'))) { - $objWriter->startElement('c:max'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('maximum')); - $objWriter->endElement(); - } + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); - if (!is_null($xAxis->getAxisOptionsProperty('minimum'))) { - $objWriter->startElement('c:min'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minimum')); - $objWriter->endElement(); - } + $objWriter->endElement(); + } - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('c:delete'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - - $objWriter->startElement('c:axPos'); - $objWriter->writeAttribute('val', "l"); - $objWriter->endElement(); - - $objWriter->startElement('c:majorGridlines'); - $objWriter->startElement('c:spPr'); - - if (!is_null($majorGridlines->getLineColorProperty('value'))) { - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', $majorGridlines->getLineStyleProperty('width')); - $objWriter->startElement('a:solidFill'); - $objWriter->startElement("a:{$majorGridlines->getLineColorProperty('type')}"); - $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('value')); - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('alpha')); - $objWriter->endElement(); //end alpha - $objWriter->endElement(); //end srgbClr - $objWriter->endElement(); //end solidFill - - $objWriter->startElement('a:prstDash'); - $objWriter->writeAttribute('val', $majorGridlines->getLineStyleProperty('dash')); - $objWriter->endElement(); - - if ($majorGridlines->getLineStyleProperty('join') == 'miter') { - $objWriter->startElement('a:miter'); - $objWriter->writeAttribute('lim', '800000'); - $objWriter->endElement(); - } else { - $objWriter->startElement('a:bevel'); - $objWriter->endElement(); - } - - if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) { - $objWriter->startElement('a:headEnd'); - $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type'))); - $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('head', 'w')); - $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('head', 'len')); - $objWriter->endElement(); - } - - if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) { - $objWriter->startElement('a:tailEnd'); - $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type'))); - $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('end', 'w')); - $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('end', 'len')); - $objWriter->endElement(); - } - $objWriter->endElement(); //end ln - } - $objWriter->startElement('a:effectLst'); - - if (!is_null($majorGridlines->getGlowSize())) { - $objWriter->startElement('a:glow'); - $objWriter->writeAttribute('rad', $majorGridlines->getGlowSize()); - $objWriter->startElement("a:{$majorGridlines->getGlowColor('type')}"); - $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('value')); - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('alpha')); - $objWriter->endElement(); //end alpha - $objWriter->endElement(); //end schemeClr - $objWriter->endElement(); //end glow - } + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', $yAxis->getAxisNumberFormat()); + $objWriter->writeAttribute('sourceLinked', $yAxis->getAxisNumberSourceLinked()); + $objWriter->endElement(); - if (!is_null($majorGridlines->getShadowProperty('presets'))) { - $objWriter->startElement("a:{$majorGridlines->getShadowProperty('effect')}"); - if (!is_null($majorGridlines->getShadowProperty('blur'))) { - $objWriter->writeAttribute('blurRad', $majorGridlines->getShadowProperty('blur')); - } - if (!is_null($majorGridlines->getShadowProperty('distance'))) { - $objWriter->writeAttribute('dist', $majorGridlines->getShadowProperty('distance')); - } - if (!is_null($majorGridlines->getShadowProperty('direction'))) { - $objWriter->writeAttribute('dir', $majorGridlines->getShadowProperty('direction')); - } - if (!is_null($majorGridlines->getShadowProperty('algn'))) { - $objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn')); - } - if (!is_null($majorGridlines->getShadowProperty(array('size', 'sx')))) { - $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(array('size', 'sx'))); - } - if (!is_null($majorGridlines->getShadowProperty(array('size', 'sy')))) { - $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(array('size', 'sy'))); - } - if (!is_null($majorGridlines->getShadowProperty(array('size', 'kx')))) { - $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(array('size', 'kx'))); - } - if (!is_null($majorGridlines->getShadowProperty('rotWithShape'))) { - $objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape')); - } - $objWriter->startElement("a:{$majorGridlines->getShadowProperty(array('color', 'type'))}"); - $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'value'))); - - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'alpha'))); - $objWriter->endElement(); //end alpha - - $objWriter->endElement(); //end color:type - $objWriter->endElement(); //end shadow - } + $objWriter->startElement('c:majorTickMark'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('major_tick_mark')); + $objWriter->endElement(); - if (!is_null($majorGridlines->getSoftEdgesSize())) { - $objWriter->startElement('a:softEdge'); - $objWriter->writeAttribute('rad', $majorGridlines->getSoftEdgesSize()); - $objWriter->endElement(); //end softEdge - } + $objWriter->startElement('c:minorTickMark'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minor_tick_mark')); + $objWriter->endElement(); - $objWriter->endElement(); //end effectLst - $objWriter->endElement(); //end spPr - $objWriter->endElement(); //end majorGridLines + $objWriter->startElement('c:tickLblPos'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('axis_labels')); + $objWriter->endElement(); - if ($minorGridlines->getObjectState()) { - $objWriter->startElement('c:minorGridlines'); - $objWriter->startElement('c:spPr'); + if ($id2 > 0) { + $objWriter->startElement('c:crossAx'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); - if (!is_null($minorGridlines->getLineColorProperty('value'))) { - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', $minorGridlines->getLineStyleProperty('width')); - $objWriter->startElement('a:solidFill'); - $objWriter->startElement("a:{$minorGridlines->getLineColorProperty('type')}"); - $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('value')); - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('alpha')); - $objWriter->endElement(); //end alpha - $objWriter->endElement(); //end srgbClr - $objWriter->endElement(); //end solidFill + $objWriter->startElement('c:crosses'); + $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('horizontal_crosses')); + $objWriter->endElement(); + } - $objWriter->startElement('a:prstDash'); - $objWriter->writeAttribute('val', $minorGridlines->getLineStyleProperty('dash')); + $objWriter->startElement('c:auto'); + $objWriter->writeAttribute('val', 1); $objWriter->endElement(); - if ($minorGridlines->getLineStyleProperty('join') == 'miter') { - $objWriter->startElement('a:miter'); - $objWriter->writeAttribute('lim', '800000'); - $objWriter->endElement(); - } else { - $objWriter->startElement('a:bevel'); - $objWriter->endElement(); - } + $objWriter->startElement('c:lblAlgn'); + $objWriter->writeAttribute('val', "ctr"); + $objWriter->endElement(); - if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) { - $objWriter->startElement('a:headEnd'); - $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type'))); - $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('head', 'w')); - $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('head', 'len')); - $objWriter->endElement(); - } + $objWriter->startElement('c:lblOffset'); + $objWriter->writeAttribute('val', 100); + $objWriter->endElement(); - if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) { - $objWriter->startElement('a:tailEnd'); - $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type'))); - $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('end', 'w')); - $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('end', 'len')); - $objWriter->endElement(); - } - $objWriter->endElement(); //end ln - } - - $objWriter->startElement('a:effectLst'); - - if (!is_null($minorGridlines->getGlowSize())) { - $objWriter->startElement('a:glow'); - $objWriter->writeAttribute('rad', $minorGridlines->getGlowSize()); - $objWriter->startElement("a:{$minorGridlines->getGlowColor('type')}"); - $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('value')); - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('alpha')); - $objWriter->endElement(); //end alpha - $objWriter->endElement(); //end schemeClr - $objWriter->endElement(); //end glow - } - - if (!is_null($minorGridlines->getShadowProperty('presets'))) { - $objWriter->startElement("a:{$minorGridlines->getShadowProperty('effect')}"); - if (!is_null($minorGridlines->getShadowProperty('blur'))) { - $objWriter->writeAttribute('blurRad', $minorGridlines->getShadowProperty('blur')); - } - if (!is_null($minorGridlines->getShadowProperty('distance'))) { - $objWriter->writeAttribute('dist', $minorGridlines->getShadowProperty('distance')); - } - if (!is_null($minorGridlines->getShadowProperty('direction'))) { - $objWriter->writeAttribute('dir', $minorGridlines->getShadowProperty('direction')); - } - if (!is_null($minorGridlines->getShadowProperty('algn'))) { - $objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn')); - } - if (!is_null($minorGridlines->getShadowProperty(array('size', 'sx')))) { - $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(array('size', 'sx'))); + if ($isMultiLevelSeries) { + $objWriter->startElement('c:noMultiLvlLbl'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); } - if (!is_null($minorGridlines->getShadowProperty(array('size', 'sy')))) { - $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(array('size', 'sy'))); + $objWriter->endElement(); + } + + /** + * Write Value Axis + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $yAxisLabel + * @param string $groupType Chart type + * @param string $id1 + * @param string $id2 + * @param boolean $isMultiLevelSeries + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines) { + $objWriter->startElement('c:valAx'); + + if ($id2 > 0) { + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); } - if (!is_null($minorGridlines->getShadowProperty(array('size', 'kx')))) { - $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(array('size', 'kx'))); + + $objWriter->startElement('c:scaling'); + $objWriter->startElement('c:orientation'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation')); + + if (!is_null($xAxis->getAxisOptionsProperty('maximum'))) { + $objWriter->startElement('c:max'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('maximum')); + $objWriter->endElement(); } - if (!is_null($minorGridlines->getShadowProperty('rotWithShape'))) { - $objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape')); + + if (!is_null($xAxis->getAxisOptionsProperty('minimum'))) { + $objWriter->startElement('c:min'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minimum')); + $objWriter->endElement(); } - $objWriter->startElement("a:{$minorGridlines->getShadowProperty(array('color', 'type'))}"); - $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'value'))); - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'alpha'))); - $objWriter->endElement(); //end alpha - $objWriter->endElement(); //end color:type - $objWriter->endElement(); //end shadow - } - - if (!is_null($minorGridlines->getSoftEdgesSize())) { - $objWriter->startElement('a:softEdge'); - $objWriter->writeAttribute('rad', $minorGridlines->getSoftEdgesSize()); - $objWriter->endElement(); //end softEdge - } - - $objWriter->endElement(); //end effectLst - $objWriter->endElement(); //end spPr - $objWriter->endElement(); //end minorGridLines - } - if (!is_null($yAxisLabel)) { + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('c:delete'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); - $objWriter->startElement('c:title'); - $objWriter->startElement('c:tx'); - $objWriter->startElement('c:rich'); + $objWriter->startElement('c:axPos'); + $objWriter->writeAttribute('val', "l"); + $objWriter->endElement(); - $objWriter->startElement('a:bodyPr'); - $objWriter->endElement(); + $objWriter->startElement('c:majorGridlines'); + $objWriter->startElement('c:spPr'); - $objWriter->startElement('a:lstStyle'); - $objWriter->endElement(); + if (!is_null($majorGridlines->getLineColorProperty('value'))) { + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', $majorGridlines->getLineStyleProperty('width')); + $objWriter->startElement('a:solidFill'); + $objWriter->startElement("a:{$majorGridlines->getLineColorProperty('type')}"); + $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('alpha')); + $objWriter->endElement(); //end alpha + $objWriter->endElement(); //end srgbClr + $objWriter->endElement(); //end solidFill + + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', $majorGridlines->getLineStyleProperty('dash')); + $objWriter->endElement(); + + if ($majorGridlines->getLineStyleProperty('join') == 'miter') { + $objWriter->startElement('a:miter'); + $objWriter->writeAttribute('lim', '800000'); + $objWriter->endElement(); + } else { + $objWriter->startElement('a:bevel'); + $objWriter->endElement(); + } - $objWriter->startElement('a:p'); - $objWriter->startElement('a:r'); + if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) { + $objWriter->startElement('a:headEnd'); + $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type'))); + $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('head', 'w')); + $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('head', 'len')); + $objWriter->endElement(); + } - $caption = $yAxisLabel->getCaption(); - if (is_array($caption)) { - $caption = $caption[0]; - } + if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) { + $objWriter->startElement('a:tailEnd'); + $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type'))); + $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('end', 'w')); + $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('end', 'len')); + $objWriter->endElement(); + } + $objWriter->endElement(); //end ln + } + $objWriter->startElement('a:effectLst'); + + if (!is_null($majorGridlines->getGlowSize())) { + $objWriter->startElement('a:glow'); + $objWriter->writeAttribute('rad', $majorGridlines->getGlowSize()); + $objWriter->startElement("a:{$majorGridlines->getGlowColor('type')}"); + $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('alpha')); + $objWriter->endElement(); //end alpha + $objWriter->endElement(); //end schemeClr + $objWriter->endElement(); //end glow + } - $objWriter->startElement('a:t'); - // $objWriter->writeAttribute('xml:space', 'preserve'); - $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption)); - $objWriter->endElement(); + if (!is_null($majorGridlines->getShadowProperty('presets'))) { + $objWriter->startElement("a:{$majorGridlines->getShadowProperty('effect')}"); + if (!is_null($majorGridlines->getShadowProperty('blur'))) { + $objWriter->writeAttribute('blurRad', $majorGridlines->getShadowProperty('blur')); + } + if (!is_null($majorGridlines->getShadowProperty('distance'))) { + $objWriter->writeAttribute('dist', $majorGridlines->getShadowProperty('distance')); + } + if (!is_null($majorGridlines->getShadowProperty('direction'))) { + $objWriter->writeAttribute('dir', $majorGridlines->getShadowProperty('direction')); + } + if (!is_null($majorGridlines->getShadowProperty('algn'))) { + $objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn')); + } + if (!is_null($majorGridlines->getShadowProperty(array('size', 'sx')))) { + $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(array('size', 'sx'))); + } + if (!is_null($majorGridlines->getShadowProperty(array('size', 'sy')))) { + $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(array('size', 'sy'))); + } + if (!is_null($majorGridlines->getShadowProperty(array('size', 'kx')))) { + $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(array('size', 'kx'))); + } + if (!is_null($majorGridlines->getShadowProperty('rotWithShape'))) { + $objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape')); + } + $objWriter->startElement("a:{$majorGridlines->getShadowProperty(array('color', 'type'))}"); + $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'value'))); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'alpha'))); + $objWriter->endElement(); //end alpha - if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $layout = $yAxisLabel->getLayout(); - $this->_writeLayout($layout, $objWriter); - } + $objWriter->endElement(); //end color:type + $objWriter->endElement(); //end shadow + } - $objWriter->startElement('c:overlay'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); + if (!is_null($majorGridlines->getSoftEdgesSize())) { + $objWriter->startElement('a:softEdge'); + $objWriter->writeAttribute('rad', $majorGridlines->getSoftEdgesSize()); + $objWriter->endElement(); //end softEdge + } - $objWriter->endElement(); - } + $objWriter->endElement(); //end effectLst + $objWriter->endElement(); //end spPr + $objWriter->endElement(); //end majorGridLines + + if ($minorGridlines->getObjectState()) { + $objWriter->startElement('c:minorGridlines'); + $objWriter->startElement('c:spPr'); + + if (!is_null($minorGridlines->getLineColorProperty('value'))) { + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', $minorGridlines->getLineStyleProperty('width')); + $objWriter->startElement('a:solidFill'); + $objWriter->startElement("a:{$minorGridlines->getLineColorProperty('type')}"); + $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('alpha')); + $objWriter->endElement(); //end alpha + $objWriter->endElement(); //end srgbClr + $objWriter->endElement(); //end solidFill + + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', $minorGridlines->getLineStyleProperty('dash')); + $objWriter->endElement(); + + if ($minorGridlines->getLineStyleProperty('join') == 'miter') { + $objWriter->startElement('a:miter'); + $objWriter->writeAttribute('lim', '800000'); + $objWriter->endElement(); + } else { + $objWriter->startElement('a:bevel'); + $objWriter->endElement(); + } + + if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) { + $objWriter->startElement('a:headEnd'); + $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type'))); + $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('head', 'w')); + $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('head', 'len')); + $objWriter->endElement(); + } + + if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) { + $objWriter->startElement('a:tailEnd'); + $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type'))); + $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('end', 'w')); + $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('end', 'len')); + $objWriter->endElement(); + } + $objWriter->endElement(); //end ln + } - $objWriter->startElement('c:numFmt'); - $objWriter->writeAttribute('formatCode', $xAxis->getAxisNumberFormat()); - $objWriter->writeAttribute('sourceLinked', $xAxis->getAxisNumberSourceLinked()); - $objWriter->endElement(); - - $objWriter->startElement('c:majorTickMark'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_tick_mark')); - $objWriter->endElement(); - - $objWriter->startElement('c:minorTickMark'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_tick_mark')); - $objWriter->endElement(); - - $objWriter->startElement('c:tickLblPos'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('axis_labels')); - $objWriter->endElement(); - - $objWriter->startElement('c:spPr'); - - if (!is_null($xAxis->getFillProperty('value'))) { - $objWriter->startElement('a:solidFill'); - $objWriter->startElement("a:" . $xAxis->getFillProperty('type')); - $objWriter->writeAttribute('val', $xAxis->getFillProperty('value')); - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $xAxis->getFillProperty('alpha')); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - } + $objWriter->startElement('a:effectLst'); + + if (!is_null($minorGridlines->getGlowSize())) { + $objWriter->startElement('a:glow'); + $objWriter->writeAttribute('rad', $minorGridlines->getGlowSize()); + $objWriter->startElement("a:{$minorGridlines->getGlowColor('type')}"); + $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('alpha')); + $objWriter->endElement(); //end alpha + $objWriter->endElement(); //end schemeClr + $objWriter->endElement(); //end glow + } - $objWriter->startElement('a:ln'); - - $objWriter->writeAttribute('w', $xAxis->getLineStyleProperty('width')); - $objWriter->writeAttribute('cap', $xAxis->getLineStyleProperty('cap')); - $objWriter->writeAttribute('cmpd', $xAxis->getLineStyleProperty('compound')); - - if (!is_null($xAxis->getLineProperty('value'))) { - $objWriter->startElement('a:solidFill'); - $objWriter->startElement("a:" . $xAxis->getLineProperty('type')); - $objWriter->writeAttribute('val', $xAxis->getLineProperty('value')); - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $xAxis->getLineProperty('alpha')); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - } + if (!is_null($minorGridlines->getShadowProperty('presets'))) { + $objWriter->startElement("a:{$minorGridlines->getShadowProperty('effect')}"); + if (!is_null($minorGridlines->getShadowProperty('blur'))) { + $objWriter->writeAttribute('blurRad', $minorGridlines->getShadowProperty('blur')); + } + if (!is_null($minorGridlines->getShadowProperty('distance'))) { + $objWriter->writeAttribute('dist', $minorGridlines->getShadowProperty('distance')); + } + if (!is_null($minorGridlines->getShadowProperty('direction'))) { + $objWriter->writeAttribute('dir', $minorGridlines->getShadowProperty('direction')); + } + if (!is_null($minorGridlines->getShadowProperty('algn'))) { + $objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn')); + } + if (!is_null($minorGridlines->getShadowProperty(array('size', 'sx')))) { + $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(array('size', 'sx'))); + } + if (!is_null($minorGridlines->getShadowProperty(array('size', 'sy')))) { + $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(array('size', 'sy'))); + } + if (!is_null($minorGridlines->getShadowProperty(array('size', 'kx')))) { + $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(array('size', 'kx'))); + } + if (!is_null($minorGridlines->getShadowProperty('rotWithShape'))) { + $objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape')); + } + $objWriter->startElement("a:{$minorGridlines->getShadowProperty(array('color', 'type'))}"); + $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'value'))); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'alpha'))); + $objWriter->endElement(); //end alpha + $objWriter->endElement(); //end color:type + $objWriter->endElement(); //end shadow + } - $objWriter->startElement('a:prstDash'); - $objWriter->writeAttribute('val', $xAxis->getLineStyleProperty('dash')); - $objWriter->endElement(); - - if ($xAxis->getLineStyleProperty('join') == 'miter') { - $objWriter->startElement('a:miter'); - $objWriter->writeAttribute('lim', '800000'); - $objWriter->endElement(); - } else { - $objWriter->startElement('a:bevel'); - $objWriter->endElement(); - } + if (!is_null($minorGridlines->getSoftEdgesSize())) { + $objWriter->startElement('a:softEdge'); + $objWriter->writeAttribute('rad', $minorGridlines->getSoftEdgesSize()); + $objWriter->endElement(); //end softEdge + } - if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'head', 'type')))) { - $objWriter->startElement('a:headEnd'); - $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'head', 'type'))); - $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('head')); - $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('head')); - $objWriter->endElement(); - } + $objWriter->endElement(); //end effectLst + $objWriter->endElement(); //end spPr + $objWriter->endElement(); //end minorGridLines + } - if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'end', 'type')))) { - $objWriter->startElement('a:tailEnd'); - $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'end', 'type'))); - $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('end')); - $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('end')); - $objWriter->endElement(); - } + if (!is_null($yAxisLabel)) { + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); - $objWriter->endElement(); + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); - $objWriter->startElement('a:effectLst'); + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); - if (!is_null($xAxis->getGlowProperty('size'))) { - $objWriter->startElement('a:glow'); - $objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size')); - $objWriter->startElement("a:{$xAxis->getGlowProperty(array('color','type'))}"); - $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','value'))); - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','alpha'))); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - } + $objWriter->startElement('a:p'); + $objWriter->startElement('a:r'); - if (!is_null($xAxis->getShadowProperty('presets'))) { - $objWriter->startElement("a:{$xAxis->getShadowProperty('effect')}"); - - if (!is_null($xAxis->getShadowProperty('blur'))) { - $objWriter->writeAttribute('blurRad', $xAxis->getShadowProperty('blur')); - } - if (!is_null($xAxis->getShadowProperty('distance'))) { - $objWriter->writeAttribute('dist', $xAxis->getShadowProperty('distance')); - } - if (!is_null($xAxis->getShadowProperty('direction'))) { - $objWriter->writeAttribute('dir', $xAxis->getShadowProperty('direction')); - } - if (!is_null($xAxis->getShadowProperty('algn'))) { - $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn')); - } - if (!is_null($xAxis->getShadowProperty(array('size','sx')))) { - $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(array('size','sx'))); - } - if (!is_null($xAxis->getShadowProperty(array('size','sy')))) { - $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(array('size','sy'))); - } - if (!is_null($xAxis->getShadowProperty(array('size','kx')))) { - $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(array('size','kx'))); - } - if (!is_null($xAxis->getShadowProperty('rotWithShape'))) { - $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape')); - } - - $objWriter->startElement("a:{$xAxis->getShadowProperty(array('color','type'))}"); - $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','value'))); - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','alpha'))); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->endElement(); - } + $caption = $yAxisLabel->getCaption(); + if (is_array($caption)) { + $caption = $caption[0]; + } - if (!is_null($xAxis->getSoftEdgesSize())) { - $objWriter->startElement('a:softEdge'); - $objWriter->writeAttribute('rad', $xAxis->getSoftEdgesSize()); - $objWriter->endElement(); - } + $objWriter->startElement('a:t'); + // $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption)); + $objWriter->endElement(); - $objWriter->endElement(); //effectList - $objWriter->endElement(); //end spPr + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); - if ($id1 > 0) { - $objWriter->startElement('c:crossAx'); - $objWriter->writeAttribute('val', $id2); - $objWriter->endElement(); + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $layout = $yAxisLabel->getLayout(); + $this->_writeLayout($layout, $objWriter); + } - if (!is_null($xAxis->getAxisOptionsProperty('horizontal_crosses_value'))) { - $objWriter->startElement('c:crossesAt'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses_value')); - $objWriter->endElement(); - } else { - $objWriter->startElement('c:crosses'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses')); - $objWriter->endElement(); - } + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); - $objWriter->startElement('c:crossBetween'); - $objWriter->writeAttribute('val', "midCat"); - $objWriter->endElement(); + $objWriter->endElement(); + } - if (!is_null($xAxis->getAxisOptionsProperty('major_unit'))) { - $objWriter->startElement('c:majorUnit'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_unit')); + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', $xAxis->getAxisNumberFormat()); + $objWriter->writeAttribute('sourceLinked', $xAxis->getAxisNumberSourceLinked()); $objWriter->endElement(); - } - if (!is_null($xAxis->getAxisOptionsProperty('minor_unit'))) { - $objWriter->startElement('c:minorUnit'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_unit')); + $objWriter->startElement('c:majorTickMark'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_tick_mark')); $objWriter->endElement(); - } - } + $objWriter->startElement('c:minorTickMark'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_tick_mark')); + $objWriter->endElement(); - if ($isMultiLevelSeries) { - if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $objWriter->startElement('c:noMultiLvlLbl'); - $objWriter->writeAttribute('val', 0); + $objWriter->startElement('c:tickLblPos'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('axis_labels')); $objWriter->endElement(); - } - } - $objWriter->endElement(); - - } - - /** - * Get the data series type(s) for a chart plot series - * - * @param PHPExcel_Chart_PlotArea $plotArea - * - * @return string|array - * @throws PHPExcel_Writer_Exception - */ - private - static function _getChartType($plotArea) { - $groupCount = $plotArea->getPlotGroupCount(); - - if ($groupCount == 1) { - $chartType = array( - $plotArea->getPlotGroupByIndex(0) - ->getPlotType() - ); - } else { - $chartTypes = array(); - for ($i = 0; $i < $groupCount; ++$i) { - $chartTypes[] = $plotArea->getPlotGroupByIndex($i) - ->getPlotType(); - } - $chartType = array_unique($chartTypes); - if (count($chartTypes) == 0) { - throw new PHPExcel_Writer_Exception('Chart is not yet implemented'); - } - } + $objWriter->startElement('c:spPr'); - return $chartType; - } - - /** - * Write Plot Group (series of related plots) - * - * @param PHPExcel_Chart_DataSeries $plotGroup - * @param string $groupType Type of plot for dataseries - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param boolean &$catIsMultiLevelSeries Is category a multi-series category - * @param boolean &$valIsMultiLevelSeries Is value set a multi-series set - * @param string &$plotGroupingType Type of grouping for multi-series values - * @param PHPExcel_Worksheet $pSheet - * - * @throws PHPExcel_Writer_Exception - */ - private function _writePlotGroup($plotGroup, - $groupType, - $objWriter, - &$catIsMultiLevelSeries, - &$valIsMultiLevelSeries, - &$plotGroupingType, - PHPExcel_Worksheet $pSheet - ) { - if (is_null($plotGroup)) { - return; - } + if (!is_null($xAxis->getFillProperty('value'))) { + $objWriter->startElement('a:solidFill'); + $objWriter->startElement("a:" . $xAxis->getFillProperty('type')); + $objWriter->writeAttribute('val', $xAxis->getFillProperty('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $xAxis->getFillProperty('alpha')); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + } - if (($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) - ) { - $objWriter->startElement('c:barDir'); - $objWriter->writeAttribute('val', $plotGroup->getPlotDirection()); - $objWriter->endElement(); - } + $objWriter->startElement('a:ln'); - if (!is_null($plotGroup->getPlotGrouping())) { - $plotGroupingType = $plotGroup->getPlotGrouping(); - $objWriter->startElement('c:grouping'); - $objWriter->writeAttribute('val', $plotGroupingType); - $objWriter->endElement(); - } + $objWriter->writeAttribute('w', $xAxis->getLineStyleProperty('width')); + $objWriter->writeAttribute('cap', $xAxis->getLineStyleProperty('cap')); + $objWriter->writeAttribute('cmpd', $xAxis->getLineStyleProperty('compound')); - // Get these details before the loop, because we can use the count to check for varyColors - $plotSeriesOrder = $plotGroup->getPlotOrder(); - $plotSeriesCount = count($plotSeriesOrder); - - if (($groupType !== PHPExcel_Chart_DataSeries::TYPE_RADARCHART) && - ($groupType !== PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) - ) { - - if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_LINECHART) { - if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) || - ($plotSeriesCount > 1) - ) { - $objWriter->startElement('c:varyColors'); - $objWriter->writeAttribute('val', 1); - $objWriter->endElement(); - } else { - $objWriter->startElement('c:varyColors'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); + if (!is_null($xAxis->getLineProperty('value'))) { + $objWriter->startElement('a:solidFill'); + $objWriter->startElement("a:" . $xAxis->getLineProperty('type')); + $objWriter->writeAttribute('val', $xAxis->getLineProperty('value')); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $xAxis->getLineProperty('alpha')); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); } - } - } - foreach ($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) { - $objWriter->startElement('c:ser'); + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', $xAxis->getLineStyleProperty('dash')); + $objWriter->endElement(); - $objWriter->startElement('c:idx'); - $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesIdx); - $objWriter->endElement(); + if ($xAxis->getLineStyleProperty('join') == 'miter') { + $objWriter->startElement('a:miter'); + $objWriter->writeAttribute('lim', '800000'); + $objWriter->endElement(); + } else { + $objWriter->startElement('a:bevel'); + $objWriter->endElement(); + } - $objWriter->startElement('c:order'); - $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesRef); - $objWriter->endElement(); + if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'head', 'type')))) { + $objWriter->startElement('a:headEnd'); + $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'head', 'type'))); + $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('head')); + $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('head')); + $objWriter->endElement(); + } - if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) - ) { + if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'end', 'type')))) { + $objWriter->startElement('a:tailEnd'); + $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'end', 'type'))); + $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('end')); + $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('end')); + $objWriter->endElement(); + } - $objWriter->startElement('c:dPt'); - $objWriter->startElement('c:idx'); - $objWriter->writeAttribute('val', 3); $objWriter->endElement(); - $objWriter->startElement('c:bubble3D'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); + $objWriter->startElement('a:effectLst'); - $objWriter->startElement('c:spPr'); - $objWriter->startElement('a:solidFill'); - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', 'FF9900'); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - $objWriter->endElement(); - } + if (!is_null($xAxis->getGlowProperty('size'))) { + $objWriter->startElement('a:glow'); + $objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size')); + $objWriter->startElement("a:{$xAxis->getGlowProperty(array('color','type'))}"); + $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','value'))); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','alpha'))); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + } - // Labels - $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef); - if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) { - $objWriter->startElement('c:tx'); - $objWriter->startElement('c:strRef'); - $this->_writePlotSeriesLabel($plotSeriesLabel, $objWriter); - $objWriter->endElement(); - $objWriter->endElement(); - } + if (!is_null($xAxis->getShadowProperty('presets'))) { + $objWriter->startElement("a:{$xAxis->getShadowProperty('effect')}"); - // Formatting for the points - if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) - ) { - $objWriter->startElement('c:spPr'); - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', 12700); - if ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { - $objWriter->startElement('a:noFill'); - $objWriter->endElement(); - } - $objWriter->endElement(); - $objWriter->endElement(); - } + if (!is_null($xAxis->getShadowProperty('blur'))) { + $objWriter->writeAttribute('blurRad', $xAxis->getShadowProperty('blur')); + } + if (!is_null($xAxis->getShadowProperty('distance'))) { + $objWriter->writeAttribute('dist', $xAxis->getShadowProperty('distance')); + } + if (!is_null($xAxis->getShadowProperty('direction'))) { + $objWriter->writeAttribute('dir', $xAxis->getShadowProperty('direction')); + } + if (!is_null($xAxis->getShadowProperty('algn'))) { + $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn')); + } + if (!is_null($xAxis->getShadowProperty(array('size','sx')))) { + $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(array('size','sx'))); + } + if (!is_null($xAxis->getShadowProperty(array('size','sy')))) { + $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(array('size','sy'))); + } + if (!is_null($xAxis->getShadowProperty(array('size','kx')))) { + $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(array('size','kx'))); + } + if (!is_null($xAxis->getShadowProperty('rotWithShape'))) { + $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape')); + } - $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef); - if ($plotSeriesValues) { - $plotSeriesMarker = $plotSeriesValues->getPointMarker(); - if ($plotSeriesMarker) { - $objWriter->startElement('c:marker'); - $objWriter->startElement('c:symbol'); - $objWriter->writeAttribute('val', $plotSeriesMarker); - $objWriter->endElement(); + $objWriter->startElement("a:{$xAxis->getShadowProperty(array('color','type'))}"); + $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','value'))); + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','alpha'))); + $objWriter->endElement(); + $objWriter->endElement(); - if ($plotSeriesMarker !== 'none') { - $objWriter->startElement('c:size'); - $objWriter->writeAttribute('val', 3); $objWriter->endElement(); - } + } - $objWriter->endElement(); + if (!is_null($xAxis->getSoftEdgesSize())) { + $objWriter->startElement('a:softEdge'); + $objWriter->writeAttribute('rad', $xAxis->getSoftEdgesSize()); + $objWriter->endElement(); } - } - if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || - ($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) || - ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) - ) { + $objWriter->endElement(); //effectList + $objWriter->endElement(); //end spPr - $objWriter->startElement('c:invertIfNegative'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - } + if ($id1 > 0) { + $objWriter->startElement('c:crossAx'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); - // Category Labels - $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef); - if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) { - $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); + if (!is_null($xAxis->getAxisOptionsProperty('horizontal_crosses_value'))) { + $objWriter->startElement('c:crossesAt'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses_value')); + $objWriter->endElement(); + } else { + $objWriter->startElement('c:crosses'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses')); + $objWriter->endElement(); + } - if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || - ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) - ) { + $objWriter->startElement('c:crossBetween'); + $objWriter->writeAttribute('val', "midCat"); + $objWriter->endElement(); - if (!is_null($plotGroup->getPlotStyle())) { - $plotStyle = $plotGroup->getPlotStyle(); - if ($plotStyle) { - $objWriter->startElement('c:explosion'); - $objWriter->writeAttribute('val', 25); - $objWriter->endElement(); + if (!is_null($xAxis->getAxisOptionsProperty('major_unit'))) { + $objWriter->startElement('c:majorUnit'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_unit')); + $objWriter->endElement(); + } + + if (!is_null($xAxis->getAxisOptionsProperty('minor_unit'))) { + $objWriter->startElement('c:minorUnit'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_unit')); + $objWriter->endElement(); } - } } - if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || - ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) - ) { - $objWriter->startElement('c:xVal'); - } else { - $objWriter->startElement('c:cat'); + if ($isMultiLevelSeries) { + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $objWriter->startElement('c:noMultiLvlLbl'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } } - $this->_writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet); $objWriter->endElement(); - } - - // Values - if ($plotSeriesValues) { - $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries(); + } - if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || - ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) - ) { - $objWriter->startElement('c:yVal'); + /** + * Get the data series type(s) for a chart plot series + * + * @param PHPExcel_Chart_PlotArea $plotArea + * + * @return string|array + * @throws PHPExcel_Writer_Exception + */ + private static function _getChartType($plotArea) { + $groupCount = $plotArea->getPlotGroupCount(); + + if ($groupCount == 1) { + $chartType = array($plotArea->getPlotGroupByIndex(0)->getPlotType()); } else { - $objWriter->startElement('c:val'); + $chartTypes = array(); + for ($i = 0; $i < $groupCount; ++$i) { + $chartTypes[] = $plotArea->getPlotGroupByIndex($i)->getPlotType(); + } + $chartType = array_unique($chartTypes); + if (count($chartTypes) == 0) { + throw new PHPExcel_Writer_Exception('Chart is not yet implemented'); + } } - $this->_writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet); - $objWriter->endElement(); - } + return $chartType; + } - if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $this->_writeBubbles($plotSeriesValues, $objWriter, $pSheet); - } + /** + * Write Plot Group (series of related plots) + * + * @param PHPExcel_Chart_DataSeries $plotGroup + * @param string $groupType Type of plot for dataseries + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param boolean &$catIsMultiLevelSeries Is category a multi-series category + * @param boolean &$valIsMultiLevelSeries Is value set a multi-series set + * @param string &$plotGroupingType Type of grouping for multi-series values + * @param PHPExcel_Worksheet $pSheet + * + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType, PHPExcel_Worksheet $pSheet ) { + if (is_null($plotGroup)) { + return; + } - $objWriter->endElement(); + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) { + $objWriter->startElement('c:barDir'); + $objWriter->writeAttribute('val', $plotGroup->getPlotDirection()); + $objWriter->endElement(); + } - } + if (!is_null($plotGroup->getPlotGrouping())) { + $plotGroupingType = $plotGroup->getPlotGrouping(); + $objWriter->startElement('c:grouping'); + $objWriter->writeAttribute('val', $plotGroupingType); + $objWriter->endElement(); + } - $this->_seriesIndex += $plotSeriesIdx + 1; - } - - /** - * Write Plot Series Label - * - * @param PHPExcel_Chart_DataSeriesValues $plotSeriesLabel - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * - * @throws PHPExcel_Writer_Exception - */ - private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) { - if (is_null($plotSeriesLabel)) { - return; - } + // Get these details before the loop, because we can use the count to check for varyColors + $plotSeriesOrder = $plotGroup->getPlotOrder(); + $plotSeriesCount = count($plotSeriesOrder); + + if (($groupType !== PHPExcel_Chart_DataSeries::TYPE_RADARCHART) && ($groupType !== PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_LINECHART) { + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) || ($plotSeriesCount > 1)) { + $objWriter->startElement('c:varyColors'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); + } else { + $objWriter->startElement('c:varyColors'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + } + } - $objWriter->startElement('c:f'); - $objWriter->writeRawData($plotSeriesLabel->getDataSource()); - $objWriter->endElement(); + foreach ($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) { + $objWriter->startElement('c:ser'); - $objWriter->startElement('c:strCache'); - $objWriter->startElement('c:ptCount'); - $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount()); - $objWriter->endElement(); + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesIdx); + $objWriter->endElement(); - foreach ($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) { - $objWriter->startElement('c:pt'); - $objWriter->writeAttribute('idx', $plotLabelKey); + $objWriter->startElement('c:order'); + $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesRef); + $objWriter->endElement(); - $objWriter->startElement('c:v'); - $objWriter->writeRawData($plotLabelValue); - $objWriter->endElement(); - $objWriter->endElement(); - } - $objWriter->endElement(); - - } - - /** - * Write Plot Series Values - * - * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param string $groupType Type of plot for dataseries - * @param string $dataType Datatype of series values - * @param PHPExcel_Worksheet $pSheet - * - * @throws PHPExcel_Writer_Exception - */ - private function _writePlotSeriesValues($plotSeriesValues, - $objWriter, - $groupType, - $dataType = 'str', - PHPExcel_Worksheet $pSheet - ) { - if (is_null($plotSeriesValues)) { - return; - } + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + $objWriter->startElement('c:dPt'); + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', 3); + $objWriter->endElement(); + + $objWriter->startElement('c:bubble3D'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->startElement('c:spPr'); + $objWriter->startElement('a:solidFill'); + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FF9900'); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + } + + // Labels + $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef); + if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) { + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:strRef'); + $this->_writePlotSeriesLabel($plotSeriesLabel, $objWriter); + $objWriter->endElement(); + $objWriter->endElement(); + } + + // Formatting for the points + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { + $objWriter->startElement('c:spPr'); + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', 12700); + if ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { + $objWriter->startElement('a:noFill'); + $objWriter->endElement(); + } + $objWriter->endElement(); + $objWriter->endElement(); + } + + $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef); + if ($plotSeriesValues) { + $plotSeriesMarker = $plotSeriesValues->getPointMarker(); + if ($plotSeriesMarker) { + $objWriter->startElement('c:marker'); + $objWriter->startElement('c:symbol'); + $objWriter->writeAttribute('val', $plotSeriesMarker); + $objWriter->endElement(); + + if ($plotSeriesMarker !== 'none') { + $objWriter->startElement('c:size'); + $objWriter->writeAttribute('val', 3); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART)) { + $objWriter->startElement('c:invertIfNegative'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } - if ($plotSeriesValues->isMultiLevelSeries()) { - $levelCount = $plotSeriesValues->multiLevelCount(); + // Category Labels + $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef); + if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) { + $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); + + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + if (!is_null($plotGroup->getPlotStyle())) { + $plotStyle = $plotGroup->getPlotStyle(); + if ($plotStyle) { + $objWriter->startElement('c:explosion'); + $objWriter->writeAttribute('val', 25); + $objWriter->endElement(); + } + } + } + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) { + $objWriter->startElement('c:xVal'); + } else { + $objWriter->startElement('c:cat'); + } + + $this->_writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet); + $objWriter->endElement(); + } + + // Values + if ($plotSeriesValues) { + $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries(); - $objWriter->startElement('c:multiLvlStrRef'); + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) { + $objWriter->startElement('c:yVal'); + } else { + $objWriter->startElement('c:val'); + } - $objWriter->startElement('c:f'); - $objWriter->writeRawData($plotSeriesValues->getDataSource()); - $objWriter->endElement(); + $this->_writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet); + $objWriter->endElement(); + } - $objWriter->startElement('c:multiLvlStrCache'); + if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $this->_writeBubbles($plotSeriesValues, $objWriter, $pSheet); + } - $objWriter->startElement('c:ptCount'); - $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); - $objWriter->endElement(); + $objWriter->endElement(); + } - for ($level = 0; $level < $levelCount; ++$level) { - $objWriter->startElement('c:lvl'); + $this->_seriesIndex += $plotSeriesIdx + 1; + } + + /** + * Write Plot Series Label + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesLabel + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) { + if (is_null($plotSeriesLabel)) { + return; + } + + $objWriter->startElement('c:f'); + $objWriter->writeRawData($plotSeriesLabel->getDataSource()); + $objWriter->endElement(); - foreach ($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) { - if (isset($plotSeriesValue[$level])) { + $objWriter->startElement('c:strCache'); + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount()); + $objWriter->endElement(); + + foreach ($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) { $objWriter->startElement('c:pt'); - $objWriter->writeAttribute('idx', $plotSeriesKey); + $objWriter->writeAttribute('idx', $plotLabelKey); $objWriter->startElement('c:v'); - $objWriter->writeRawData($plotSeriesValue[$level]); + $objWriter->writeRawData($plotLabelValue); $objWriter->endElement(); $objWriter->endElement(); - } } - $objWriter->endElement(); - } + } - $objWriter->endElement(); + /** + * Write Plot Series Values + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $groupType Type of plot for dataseries + * @param string $dataType Datatype of series values + * @param PHPExcel_Worksheet $pSheet + * + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, $dataType = 'str', PHPExcel_Worksheet $pSheet) { + if (is_null($plotSeriesValues)) { + return; + } - $objWriter->endElement(); - } else { - $objWriter->startElement('c:' . $dataType . 'Ref'); + if ($plotSeriesValues->isMultiLevelSeries()) { + $levelCount = $plotSeriesValues->multiLevelCount(); - $objWriter->startElement('c:f'); - $objWriter->writeRawData($plotSeriesValues->getDataSource()); - $objWriter->endElement(); + $objWriter->startElement('c:multiLvlStrRef'); - $objWriter->startElement('c:' . $dataType . 'Cache'); + $objWriter->startElement('c:f'); + $objWriter->writeRawData($plotSeriesValues->getDataSource()); + $objWriter->endElement(); - if (($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART) && - ($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && - ($groupType != PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) - ) { + $objWriter->startElement('c:multiLvlStrCache'); - if (($plotSeriesValues->getFormatCode() !== NULL) && - ($plotSeriesValues->getFormatCode() !== '') - ) { - $objWriter->startElement('c:formatCode'); - $objWriter->writeRawData($plotSeriesValues->getFormatCode()); - $objWriter->endElement(); - } - } + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); + $objWriter->endElement(); - $objWriter->startElement('c:ptCount'); - $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); - $objWriter->endElement(); + for ($level = 0; $level < $levelCount; ++$level) { + $objWriter->startElement('c:lvl'); - $dataValues = $plotSeriesValues->getDataValues(); - if (!empty($dataValues)) { - if (is_array($dataValues)) { - foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { - $objWriter->startElement('c:pt'); - $objWriter->writeAttribute('idx', $plotSeriesKey); + foreach ($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) { + if (isset($plotSeriesValue[$level])) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData($plotSeriesValue[$level]); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } - $objWriter->startElement('c:v'); - $objWriter->writeRawData($plotSeriesValue); $objWriter->endElement(); + $objWriter->endElement(); - } - } - } + } else { + $objWriter->startElement('c:' . $dataType . 'Ref'); - $objWriter->endElement(); + $objWriter->startElement('c:f'); + $objWriter->writeRawData($plotSeriesValues->getDataSource()); + $objWriter->endElement(); - $objWriter->endElement(); - } - } - - /** - * Write Bubble Chart Details - * - * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * - * @throws PHPExcel_Writer_Exception - */ - private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) { - if (is_null($plotSeriesValues)) { - return; - } + $objWriter->startElement('c:' . $dataType . 'Cache'); + + if (($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART) && ($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($groupType != PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + if (($plotSeriesValues->getFormatCode() !== null) && ($plotSeriesValues->getFormatCode() !== '')) { + $objWriter->startElement('c:formatCode'); + $objWriter->writeRawData($plotSeriesValues->getFormatCode()); + $objWriter->endElement(); + } + } - $objWriter->startElement('c:bubbleSize'); - $objWriter->startElement('c:numLit'); - - $objWriter->startElement('c:formatCode'); - $objWriter->writeRawData('General'); - $objWriter->endElement(); - - $objWriter->startElement('c:ptCount'); - $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); - $objWriter->endElement(); - - $dataValues = $plotSeriesValues->getDataValues(); - if (!empty($dataValues)) { - if (is_array($dataValues)) { - foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { - $objWriter->startElement('c:pt'); - $objWriter->writeAttribute('idx', $plotSeriesKey); - $objWriter->startElement('c:v'); - $objWriter->writeRawData(1); - $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); + $objWriter->endElement(); + + $dataValues = $plotSeriesValues->getDataValues(); + if (!empty($dataValues)) { + if (is_array($dataValues)) { + foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData($plotSeriesValue); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); } - } } - $objWriter->endElement(); - $objWriter->endElement(); + /** + * Write Bubble Chart Details + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) { + if (is_null($plotSeriesValues)) { + return; + } - $objWriter->startElement('c:bubble3D'); - $objWriter->writeAttribute('val', 0); - $objWriter->endElement(); - } + $objWriter->startElement('c:bubbleSize'); + $objWriter->startElement('c:numLit'); - /** - * Write Layout - * - * @param PHPExcel_Chart_Layout $layout - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * - * @throws PHPExcel_Writer_Exception - */ - private function _writeLayout(PHPExcel_Chart_Layout $layout = NULL, $objWriter) { - $objWriter->startElement('c:layout'); + $objWriter->startElement('c:formatCode'); + $objWriter->writeRawData('General'); + $objWriter->endElement(); + + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount()); + $objWriter->endElement(); - if (!is_null($layout)) { - $objWriter->startElement('c:manualLayout'); + $dataValues = $plotSeriesValues->getDataValues(); + if (!empty($dataValues)) { + if (is_array($dataValues)) { + foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey); + $objWriter->startElement('c:v'); + $objWriter->writeRawData(1); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + } - $layoutTarget = $layout->getLayoutTarget(); - if (!is_null($layoutTarget)) { - $objWriter->startElement('c:layoutTarget'); - $objWriter->writeAttribute('val', $layoutTarget); $objWriter->endElement(); - } + $objWriter->endElement(); - $xMode = $layout->getXMode(); - if (!is_null($xMode)) { - $objWriter->startElement('c:xMode'); - $objWriter->writeAttribute('val', $xMode); + $objWriter->startElement('c:bubble3D'); + $objWriter->writeAttribute('val', 0); $objWriter->endElement(); - } + } + + /** + * Write Layout + * + * @param PHPExcel_Chart_Layout $layout + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeLayout(PHPExcel_Chart_Layout $layout = null, $objWriter) { + $objWriter->startElement('c:layout'); + + if (!is_null($layout)) { + $objWriter->startElement('c:manualLayout'); + + $layoutTarget = $layout->getLayoutTarget(); + if (!is_null($layoutTarget)) { + $objWriter->startElement('c:layoutTarget'); + $objWriter->writeAttribute('val', $layoutTarget); + $objWriter->endElement(); + } + + $xMode = $layout->getXMode(); + if (!is_null($xMode)) { + $objWriter->startElement('c:xMode'); + $objWriter->writeAttribute('val', $xMode); + $objWriter->endElement(); + } + + $yMode = $layout->getYMode(); + if (!is_null($yMode)) { + $objWriter->startElement('c:yMode'); + $objWriter->writeAttribute('val', $yMode); + $objWriter->endElement(); + } + + $x = $layout->getXPosition(); + if (!is_null($x)) { + $objWriter->startElement('c:x'); + $objWriter->writeAttribute('val', $x); + $objWriter->endElement(); + } + + $y = $layout->getYPosition(); + if (!is_null($y)) { + $objWriter->startElement('c:y'); + $objWriter->writeAttribute('val', $y); + $objWriter->endElement(); + } + + $w = $layout->getWidth(); + if (!is_null($w)) { + $objWriter->startElement('c:w'); + $objWriter->writeAttribute('val', $w); + $objWriter->endElement(); + } + + $h = $layout->getHeight(); + if (!is_null($h)) { + $objWriter->startElement('c:h'); + $objWriter->writeAttribute('val', $h); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } - $yMode = $layout->getYMode(); - if (!is_null($yMode)) { - $objWriter->startElement('c:yMode'); - $objWriter->writeAttribute('val', $yMode); $objWriter->endElement(); - } + } - $x = $layout->getXPosition(); - if (!is_null($x)) { - $objWriter->startElement('c:x'); - $objWriter->writeAttribute('val', $x); + /** + * Write Alternate Content block + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writeAlternateContent($objWriter) { + $objWriter->startElement('mc:AlternateContent'); + $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); + + $objWriter->startElement('mc:Choice'); + $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart'); + $objWriter->writeAttribute('Requires', 'c14'); + + $objWriter->startElement('c14:style'); + $objWriter->writeAttribute('val', '102'); + $objWriter->endElement(); $objWriter->endElement(); - } - $y = $layout->getYPosition(); - if (!is_null($y)) { - $objWriter->startElement('c:y'); - $objWriter->writeAttribute('val', $y); + $objWriter->startElement('mc:Fallback'); + $objWriter->startElement('c:style'); + $objWriter->writeAttribute('val', '2'); + $objWriter->endElement(); $objWriter->endElement(); - } - $w = $layout->getWidth(); - if (!is_null($w)) { - $objWriter->startElement('c:w'); - $objWriter->writeAttribute('val', $w); $objWriter->endElement(); - } + } - $h = $layout->getHeight(); - if (!is_null($h)) { - $objWriter->startElement('c:h'); - $objWriter->writeAttribute('val', $h); + /** + * Write Printer Settings + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * + * @throws PHPExcel_Writer_Exception + */ + private function _writePrintSettings($objWriter) { + $objWriter->startElement('c:printSettings'); + + $objWriter->startElement('c:headerFooter'); $objWriter->endElement(); - } - $objWriter->endElement(); - } + $objWriter->startElement('c:pageMargins'); + $objWriter->writeAttribute('footer', 0.3); + $objWriter->writeAttribute('header', 0.3); + $objWriter->writeAttribute('r', 0.7); + $objWriter->writeAttribute('l', 0.7); + $objWriter->writeAttribute('t', 0.75); + $objWriter->writeAttribute('b', 0.75); + $objWriter->endElement(); - $objWriter->endElement(); - } - - /** - * Write Alternate Content block - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * - * @throws PHPExcel_Writer_Exception - */ - private function _writeAlternateContent($objWriter) { - $objWriter->startElement('mc:AlternateContent'); - $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); - - $objWriter->startElement('mc:Choice'); - $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart'); - $objWriter->writeAttribute('Requires', 'c14'); - - $objWriter->startElement('c14:style'); - $objWriter->writeAttribute('val', '102'); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->startElement('mc:Fallback'); - $objWriter->startElement('c:style'); - $objWriter->writeAttribute('val', '2'); - $objWriter->endElement(); - $objWriter->endElement(); - - $objWriter->endElement(); - } - - /** - * Write Printer Settings - * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * - * @throws PHPExcel_Writer_Exception - */ - private function _writePrintSettings($objWriter) { - $objWriter->startElement('c:printSettings'); - - $objWriter->startElement('c:headerFooter'); - $objWriter->endElement(); - - $objWriter->startElement('c:pageMargins'); - $objWriter->writeAttribute('footer', 0.3); - $objWriter->writeAttribute('header', 0.3); - $objWriter->writeAttribute('r', 0.7); - $objWriter->writeAttribute('l', 0.7); - $objWriter->writeAttribute('t', 0.75); - $objWriter->writeAttribute('b', 0.75); - $objWriter->endElement(); - - $objWriter->startElement('c:pageSetup'); - $objWriter->writeAttribute('orientation', "portrait"); - $objWriter->endElement(); - - $objWriter->endElement(); - } + $objWriter->startElement('c:pageSetup'); + $objWriter->writeAttribute('orientation', "portrait"); + $objWriter->endElement(); + $objWriter->endElement(); + } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Comments.php b/Classes/PHPExcel/Writer/Excel2007/Comments.php index 177e0faeb..61ba4ad0b 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Comments.php +++ b/Classes/PHPExcel/Writer/Excel2007/Comments.php @@ -53,7 +53,7 @@ public function writeComments(PHPExcel_Worksheet $pWorksheet = null) } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Comments cache $comments = $pWorksheet->getComments(); @@ -133,7 +133,7 @@ public function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null) } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Comments cache $comments = $pWorksheet->getComments(); diff --git a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php index 56ebf0bb3..2ecf93200 100644 --- a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php +++ b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -43,7 +43,7 @@ class PHPExcel_Writer_Excel2007_ContentTypes extends PHPExcel_Writer_Excel2007_W * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = FALSE) + public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = false) { // Create XML writer $objWriter = null; @@ -54,87 +54,59 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = F } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Types $objWriter->startElement('Types'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types'); // Theme - $this->_writeOverrideContentType( - $objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml' - ); + $this->_writeOverrideContentType($objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml'); // Styles - $this->_writeOverrideContentType( - $objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml' - ); + $this->_writeOverrideContentType($objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'); // Rels - $this->_writeDefaultContentType( - $objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml' - ); + $this->_writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml'); // XML - $this->_writeDefaultContentType( - $objWriter, 'xml', 'application/xml' - ); + $this->_writeDefaultContentType($objWriter, 'xml', 'application/xml'); // VML - $this->_writeDefaultContentType( - $objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing' - ); + $this->_writeDefaultContentType($objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'); // Workbook - if($pPHPExcel->hasMacros()){ //Macros in workbook ? + if ($pPHPExcel->hasMacros()) { //Macros in workbook ? // Yes : not standard content but "macroEnabled" - $this->_writeOverrideContentType( - $objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml' - ); + $this->_writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml'); //... and define a new type for the VBA project - $this->_writeDefaultContentType( - $objWriter, 'bin', 'application/vnd.ms-office.vbaProject' - ); - if($pPHPExcel->hasMacrosCertificate()){// signed macros ? + $this->_writeDefaultContentType($objWriter, 'bin', 'application/vnd.ms-office.vbaProject'); + if ($pPHPExcel->hasMacrosCertificate()) {// signed macros ? // Yes : add needed information - $this->_writeOverrideContentType( - $objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature' - ); + $this->_writeOverrideContentType($objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature'); } - }else{// no macros in workbook, so standard type - $this->_writeOverrideContentType( - $objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml' - ); + } else {// no macros in workbook, so standard type + $this->_writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'); } // DocProps - $this->_writeOverrideContentType( - $objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml' - ); + $this->_writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml'); - $this->_writeOverrideContentType( - $objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml' - ); + $this->_writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml'); $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); if (!empty($customPropertyList)) { - $this->_writeOverrideContentType( - $objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml' - ); + $this->_writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml'); } // Worksheets $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { - $this->_writeOverrideContentType( - $objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml' - ); + $this->_writeOverrideContentType($objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'); } // Shared strings - $this->_writeOverrideContentType( - $objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml' - ); + $this->_writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'); // Add worksheet relationship content types $chart = 1; @@ -145,17 +117,13 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = F // We need a drawing relationship for the worksheet if we have either drawings or charts if (($drawingCount > 0) || ($chartCount > 0)) { - $this->_writeOverrideContentType( - $objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml' - ); + $this->_writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml'); } // If we have charts, then we need a chart relationship for every individual chart if ($chartCount > 0) { for ($c = 0; $c < $chartCount; ++$c) { - $this->_writeOverrideContentType( - $objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml' - ); + $this->_writeOverrideContentType($objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); } } } @@ -163,9 +131,7 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = F // Comments for ($i = 0; $i < $sheetCount; ++$i) { if (count($pPHPExcel->getSheet($i)->getComments()) > 0) { - $this->_writeOverrideContentType( - $objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml' - ); + $this->_writeOverrideContentType($objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'); } } @@ -188,33 +154,27 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = F } if (!isset( $aMediaContentTypes[$extension]) ) { - $aMediaContentTypes[$extension] = $mimeType; + $aMediaContentTypes[$extension] = $mimeType; - $this->_writeDefaultContentType( - $objWriter, $extension, $mimeType - ); + $this->_writeDefaultContentType($objWriter, $extension, $mimeType); } } - if($pPHPExcel->hasRibbonBinObjects()){//Some additional objects in the ribbon ? + if ($pPHPExcel->hasRibbonBinObjects()) {//Some additional objects in the ribbon ? //we need to write "Extension" but not already write for media content $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); - foreach($tabRibbonTypes as $aRibbonType){ + foreach ($tabRibbonTypes as $aRibbonType) { $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor - $this->_writeDefaultContentType( - $objWriter, $aRibbonType, $mimeType - ); - } + $this->_writeDefaultContentType($objWriter, $aRibbonType, $mimeType); + } } $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) { foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) { - if (!isset( $aMediaContentTypes[strtolower($image->getExtension())]) ) { - $aMediaContentTypes[strtolower($image->getExtension())] = $this->_getImageMimeType( $image->getPath() ); + if (!isset( $aMediaContentTypes[strtolower($image->getExtension())])) { + $aMediaContentTypes[strtolower($image->getExtension())] = $this->_getImageMimeType($image->getPath()); - $this->_writeDefaultContentType( - $objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())] - ); + $this->_writeDefaultContentType($objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())]); } } } @@ -256,8 +216,8 @@ private function _writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = if ($pPartname != '' && $pContentType != '') { // Write content type $objWriter->startElement('Default'); - $objWriter->writeAttribute('Extension', $pPartname); - $objWriter->writeAttribute('ContentType', $pContentType); + $objWriter->writeAttribute('Extension', $pPartname); + $objWriter->writeAttribute('ContentType', $pContentType); $objWriter->endElement(); } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); @@ -277,8 +237,8 @@ private function _writeOverrideContentType(PHPExcel_Shared_XMLWriter $objWriter if ($pPartname != '' && $pContentType != '') { // Write content type $objWriter->startElement('Override'); - $objWriter->writeAttribute('PartName', $pPartname); - $objWriter->writeAttribute('ContentType', $pContentType); + $objWriter->writeAttribute('PartName', $pPartname); + $objWriter->writeAttribute('ContentType', $pContentType); $objWriter->endElement(); } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); diff --git a/Classes/PHPExcel/Writer/Excel2007/DocProps.php b/Classes/PHPExcel/Writer/Excel2007/DocProps.php index a65d39ac4..4573cc028 100644 --- a/Classes/PHPExcel/Writer/Excel2007/DocProps.php +++ b/Classes/PHPExcel/Writer/Excel2007/DocProps.php @@ -35,7 +35,7 @@ */ class PHPExcel_Writer_Excel2007_DocProps extends PHPExcel_Writer_Excel2007_WriterPart { -/** + /** * Write docProps/app.xml to XML format * * @param PHPExcel $pPHPExcel @@ -53,78 +53,78 @@ public function writeDocPropsApp(PHPExcel $pPHPExcel = null) } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Properties $objWriter->startElement('Properties'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties'); - $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties'); + $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); - // Application - $objWriter->writeElement('Application', 'Microsoft Excel'); + // Application + $objWriter->writeElement('Application', 'Microsoft Excel'); - // DocSecurity - $objWriter->writeElement('DocSecurity', '0'); + // DocSecurity + $objWriter->writeElement('DocSecurity', '0'); - // ScaleCrop - $objWriter->writeElement('ScaleCrop', 'false'); + // ScaleCrop + $objWriter->writeElement('ScaleCrop', 'false'); - // HeadingPairs - $objWriter->startElement('HeadingPairs'); + // HeadingPairs + $objWriter->startElement('HeadingPairs'); - // Vector - $objWriter->startElement('vt:vector'); - $objWriter->writeAttribute('size', '2'); - $objWriter->writeAttribute('baseType', 'variant'); + // Vector + $objWriter->startElement('vt:vector'); + $objWriter->writeAttribute('size', '2'); + $objWriter->writeAttribute('baseType', 'variant'); - // Variant - $objWriter->startElement('vt:variant'); - $objWriter->writeElement('vt:lpstr', 'Worksheets'); - $objWriter->endElement(); + // Variant + $objWriter->startElement('vt:variant'); + $objWriter->writeElement('vt:lpstr', 'Worksheets'); + $objWriter->endElement(); - // Variant - $objWriter->startElement('vt:variant'); - $objWriter->writeElement('vt:i4', $pPHPExcel->getSheetCount()); - $objWriter->endElement(); + // Variant + $objWriter->startElement('vt:variant'); + $objWriter->writeElement('vt:i4', $pPHPExcel->getSheetCount()); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // TitlesOfParts - $objWriter->startElement('TitlesOfParts'); + // TitlesOfParts + $objWriter->startElement('TitlesOfParts'); - // Vector - $objWriter->startElement('vt:vector'); - $objWriter->writeAttribute('size', $pPHPExcel->getSheetCount()); - $objWriter->writeAttribute('baseType', 'lpstr'); + // Vector + $objWriter->startElement('vt:vector'); + $objWriter->writeAttribute('size', $pPHPExcel->getSheetCount()); + $objWriter->writeAttribute('baseType', 'lpstr'); - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - $objWriter->writeElement('vt:lpstr', $pPHPExcel->getSheet($i)->getTitle()); - } + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $objWriter->writeElement('vt:lpstr', $pPHPExcel->getSheet($i)->getTitle()); + } - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // Company - $objWriter->writeElement('Company', $pPHPExcel->getProperties()->getCompany()); + // Company + $objWriter->writeElement('Company', $pPHPExcel->getProperties()->getCompany()); - // Company - $objWriter->writeElement('Manager', $pPHPExcel->getProperties()->getManager()); + // Company + $objWriter->writeElement('Manager', $pPHPExcel->getProperties()->getManager()); - // LinksUpToDate - $objWriter->writeElement('LinksUpToDate', 'false'); + // LinksUpToDate + $objWriter->writeElement('LinksUpToDate', 'false'); - // SharedDoc - $objWriter->writeElement('SharedDoc', 'false'); + // SharedDoc + $objWriter->writeElement('SharedDoc', 'false'); - // HyperlinksChanged - $objWriter->writeElement('HyperlinksChanged', 'false'); + // HyperlinksChanged + $objWriter->writeElement('HyperlinksChanged', 'false'); - // AppVersion - $objWriter->writeElement('AppVersion', '12.0000'); + // AppVersion + $objWriter->writeElement('AppVersion', '12.0000'); $objWriter->endElement(); @@ -150,48 +150,48 @@ public function writeDocPropsCore(PHPExcel $pPHPExcel = null) } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // cp:coreProperties $objWriter->startElement('cp:coreProperties'); - $objWriter->writeAttribute('xmlns:cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties'); - $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); - $objWriter->writeAttribute('xmlns:dcterms', 'http://purl.org/dc/terms/'); - $objWriter->writeAttribute('xmlns:dcmitype', 'http://purl.org/dc/dcmitype/'); - $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); - - // dc:creator - $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); - - // cp:lastModifiedBy - $objWriter->writeElement('cp:lastModifiedBy', $pPHPExcel->getProperties()->getLastModifiedBy()); - - // dcterms:created - $objWriter->startElement('dcterms:created'); - $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); - $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); - $objWriter->endElement(); + $objWriter->writeAttribute('xmlns:cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties'); + $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); + $objWriter->writeAttribute('xmlns:dcterms', 'http://purl.org/dc/terms/'); + $objWriter->writeAttribute('xmlns:dcmitype', 'http://purl.org/dc/dcmitype/'); + $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + + // dc:creator + $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); + + // cp:lastModifiedBy + $objWriter->writeElement('cp:lastModifiedBy', $pPHPExcel->getProperties()->getLastModifiedBy()); + + // dcterms:created + $objWriter->startElement('dcterms:created'); + $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); + $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); + $objWriter->endElement(); - // dcterms:modified - $objWriter->startElement('dcterms:modified'); - $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); - $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getModified())); - $objWriter->endElement(); + // dcterms:modified + $objWriter->startElement('dcterms:modified'); + $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); + $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getModified())); + $objWriter->endElement(); - // dc:title - $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); + // dc:title + $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); - // dc:description - $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); + // dc:description + $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); - // dc:subject - $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); + // dc:subject + $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); - // cp:keywords - $objWriter->writeElement('cp:keywords', $pPHPExcel->getProperties()->getKeywords()); + // cp:keywords + $objWriter->writeElement('cp:keywords', $pPHPExcel->getProperties()->getKeywords()); - // cp:category - $objWriter->writeElement('cp:category', $pPHPExcel->getProperties()->getCategory()); + // cp:category + $objWriter->writeElement('cp:category', $pPHPExcel->getProperties()->getCategory()); $objWriter->endElement(); @@ -222,51 +222,50 @@ public function writeDocPropsCustom(PHPExcel $pPHPExcel = null) } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // cp:coreProperties $objWriter->startElement('Properties'); - $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties'); - $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); - - - foreach($customPropertyList as $key => $customProperty) { - $propertyValue = $pPHPExcel->getProperties()->getCustomPropertyValue($customProperty); - $propertyType = $pPHPExcel->getProperties()->getCustomPropertyType($customProperty); - - $objWriter->startElement('property'); - $objWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'); - $objWriter->writeAttribute('pid', $key+2); - $objWriter->writeAttribute('name', $customProperty); - - switch($propertyType) { - case 'i' : - $objWriter->writeElement('vt:i4', $propertyValue); - break; - case 'f' : - $objWriter->writeElement('vt:r8', $propertyValue); - break; - case 'b' : - $objWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false'); - break; - case 'd' : - $objWriter->startElement('vt:filetime'); - $objWriter->writeRawData(date(DATE_W3C, $propertyValue)); - $objWriter->endElement(); - break; - default : - $objWriter->writeElement('vt:lpwstr', $propertyValue); - break; - } - - $objWriter->endElement(); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties'); + $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + + + foreach ($customPropertyList as $key => $customProperty) { + $propertyValue = $pPHPExcel->getProperties()->getCustomPropertyValue($customProperty); + $propertyType = $pPHPExcel->getProperties()->getCustomPropertyType($customProperty); + + $objWriter->startElement('property'); + $objWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'); + $objWriter->writeAttribute('pid', $key+2); + $objWriter->writeAttribute('name', $customProperty); + + switch ($propertyType) { + case 'i' : + $objWriter->writeElement('vt:i4', $propertyValue); + break; + case 'f' : + $objWriter->writeElement('vt:r8', $propertyValue); + break; + case 'b' : + $objWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false'); + break; + case 'd' : + $objWriter->startElement('vt:filetime'); + $objWriter->writeRawData(date(DATE_W3C, $propertyValue)); + $objWriter->endElement(); + break; + default : + $objWriter->writeElement('vt:lpwstr', $propertyValue); + break; } + $objWriter->endElement(); + } + $objWriter->endElement(); // Return return $objWriter->getData(); } - } diff --git a/Classes/PHPExcel/Writer/Excel2007/Drawing.php b/Classes/PHPExcel/Writer/Excel2007/Drawing.php index 4810542de..3d44ed350 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Drawing.php +++ b/Classes/PHPExcel/Writer/Excel2007/Drawing.php @@ -55,7 +55,7 @@ public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // xdr:wsDr $objWriter->startElement('xdr:wsDr'); @@ -397,7 +397,7 @@ public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Header/footer images $images = $pWorksheet->getHeaderFooter()->getImages(); diff --git a/Classes/PHPExcel/Writer/Excel2007/Rels.php b/Classes/PHPExcel/Writer/Excel2007/Rels.php index 912d23f2b..c08fe6209 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Rels.php +++ b/Classes/PHPExcel/Writer/Excel2007/Rels.php @@ -53,7 +53,7 @@ public function writeRelationships(PHPExcel $pPHPExcel = null) } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); @@ -95,7 +95,7 @@ public function writeRelationships(PHPExcel $pPHPExcel = null) 'xl/workbook.xml' ); // a custom UI in workbook ? - if($pPHPExcel->hasRibbon()){ + if ($pPHPExcel->hasRibbon()) { $this->_writeRelationShip( $objWriter, 5, @@ -128,7 +128,7 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); @@ -170,7 +170,7 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) } // Relationships for vbaProject if needed // id : just after the last sheet - if($pPHPExcel->hasMacros()){ + if ($pPHPExcel->hasMacros()) { $this->_writeRelationShip( $objWriter, ($i + 1 + 3), @@ -210,7 +210,7 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); @@ -238,7 +238,7 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul // $charts = $pWorksheet->getChartCollection(); // echo 'Chart Rels: ' , count($charts) , '<br />'; // if (count($charts) > 0) { -// foreach($charts as $chart) { +// foreach ($charts as $chart) { // $this->_writeRelationship( // $objWriter, // ++$d, @@ -319,7 +319,7 @@ public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); @@ -383,7 +383,7 @@ public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorks } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php index 555a8fc26..2c1945565 100644 --- a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php +++ b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php @@ -42,7 +42,7 @@ class PHPExcel_Writer_Excel2007_RelsRibbon extends PHPExcel_Writer_Excel2007_Wri * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeRibbonRelationships(PHPExcel $pPHPExcel = null){ + public function writeRibbonRelationships(PHPExcel $pPHPExcel = null) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { @@ -52,14 +52,14 @@ public function writeRibbonRelationships(PHPExcel $pPHPExcel = null){ } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); $localRels=$pPHPExcel->getRibbonBinObjects('names'); - if(is_array($localRels)){ - foreach($localRels as $aId=>$aTarget){ + if (is_array($localRels)) { + foreach ($localRels as $aId=>$aTarget) { $objWriter->startElement('Relationship'); $objWriter->writeAttribute('Id', $aId); $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php index 992d0e422..676c57584 100644 --- a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php +++ b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php @@ -42,7 +42,7 @@ class PHPExcel_Writer_Excel2007_RelsVBA extends PHPExcel_Writer_Excel2007_Writer * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeVBARelationships(PHPExcel $pPHPExcel = null){ + public function writeVBARelationships(PHPExcel $pPHPExcel = null) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { @@ -52,7 +52,7 @@ public function writeVBARelationships(PHPExcel $pPHPExcel = null){ } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Relationships $objWriter->startElement('Relationships'); diff --git a/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Classes/PHPExcel/Writer/Excel2007/StringTable.php index dbadb88bd..361caa635 100644 --- a/Classes/PHPExcel/Writer/Excel2007/StringTable.php +++ b/Classes/PHPExcel/Writer/Excel2007/StringTable.php @@ -104,7 +104,7 @@ public function writeStringTable($pStringTable = null) } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // String table $objWriter->startElement('sst'); @@ -254,7 +254,7 @@ public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = nu $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); // Underline $underlineType = $element->getFont()->getUnderline(); - switch($underlineType) { + switch ($underlineType) { case 'single' : $underlineType = 'sng'; break; diff --git a/Classes/PHPExcel/Writer/Excel2007/Style.php b/Classes/PHPExcel/Writer/Excel2007/Style.php index 527984b9b..dcdf82817 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Style.php +++ b/Classes/PHPExcel/Writer/Excel2007/Style.php @@ -53,111 +53,111 @@ public function writeStyles(PHPExcel $pPHPExcel = null) } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // styleSheet $objWriter->startElement('styleSheet'); $objWriter->writeAttribute('xml:space', 'preserve'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); - // numFmts - $objWriter->startElement('numFmts'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count()); + // numFmts + $objWriter->startElement('numFmts'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count()); - // numFmt - for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) { - $this->_writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i); - } + // numFmt + for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) { + $this->_writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i); + } - $objWriter->endElement(); + $objWriter->endElement(); - // fonts - $objWriter->startElement('fonts'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count()); + // fonts + $objWriter->startElement('fonts'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count()); - // font - for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) { - $this->_writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i)); - } + // font + for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) { + $this->_writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i)); + } - $objWriter->endElement(); + $objWriter->endElement(); - // fills - $objWriter->startElement('fills'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count()); + // fills + $objWriter->startElement('fills'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count()); - // fill - for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) { - $this->_writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i)); - } + // fill + for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) { + $this->_writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i)); + } - $objWriter->endElement(); + $objWriter->endElement(); - // borders - $objWriter->startElement('borders'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count()); + // borders + $objWriter->startElement('borders'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count()); - // border - for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) { - $this->_writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i)); - } + // border + for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) { + $this->_writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i)); + } - $objWriter->endElement(); + $objWriter->endElement(); - // cellStyleXfs - $objWriter->startElement('cellStyleXfs'); - $objWriter->writeAttribute('count', 1); + // cellStyleXfs + $objWriter->startElement('cellStyleXfs'); + $objWriter->writeAttribute('count', 1); - // xf - $objWriter->startElement('xf'); - $objWriter->writeAttribute('numFmtId', 0); - $objWriter->writeAttribute('fontId', 0); - $objWriter->writeAttribute('fillId', 0); - $objWriter->writeAttribute('borderId', 0); - $objWriter->endElement(); + // xf + $objWriter->startElement('xf'); + $objWriter->writeAttribute('numFmtId', 0); + $objWriter->writeAttribute('fontId', 0); + $objWriter->writeAttribute('fillId', 0); + $objWriter->writeAttribute('borderId', 0); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // cellXfs - $objWriter->startElement('cellXfs'); - $objWriter->writeAttribute('count', count($pPHPExcel->getCellXfCollection())); + // cellXfs + $objWriter->startElement('cellXfs'); + $objWriter->writeAttribute('count', count($pPHPExcel->getCellXfCollection())); - // xf - foreach ($pPHPExcel->getCellXfCollection() as $cellXf) { - $this->_writeCellStyleXf($objWriter, $cellXf, $pPHPExcel); - } + // xf + foreach ($pPHPExcel->getCellXfCollection() as $cellXf) { + $this->_writeCellStyleXf($objWriter, $cellXf, $pPHPExcel); + } - $objWriter->endElement(); + $objWriter->endElement(); - // cellStyles - $objWriter->startElement('cellStyles'); - $objWriter->writeAttribute('count', 1); + // cellStyles + $objWriter->startElement('cellStyles'); + $objWriter->writeAttribute('count', 1); - // cellStyle - $objWriter->startElement('cellStyle'); - $objWriter->writeAttribute('name', 'Normal'); - $objWriter->writeAttribute('xfId', 0); - $objWriter->writeAttribute('builtinId', 0); - $objWriter->endElement(); + // cellStyle + $objWriter->startElement('cellStyle'); + $objWriter->writeAttribute('name', 'Normal'); + $objWriter->writeAttribute('xfId', 0); + $objWriter->writeAttribute('builtinId', 0); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // dxfs - $objWriter->startElement('dxfs'); - $objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count()); + // dxfs + $objWriter->startElement('dxfs'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count()); - // dxf - for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) { - $this->_writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle()); - } + // dxf + for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) { + $this->_writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle()); + } - $objWriter->endElement(); + $objWriter->endElement(); - // tableStyles - $objWriter->startElement('tableStyles'); - $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9'); - $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1'); - $objWriter->endElement(); + // tableStyles + $objWriter->startElement('tableStyles'); + $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9'); + $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1'); + $objWriter->endElement(); $objWriter->endElement(); @@ -179,7 +179,7 @@ private function _writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce $pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_PATH) { // Gradient fill $this->_writeGradientFill($objWriter, $pFill); - } elseif($pFill->getFillType() !== NULL) { + } elseif ($pFill->getFillType() !== null) { // Pattern fill $this->_writePatternFill($objWriter, $pFill); } @@ -197,34 +197,34 @@ private function _writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, // fill $objWriter->startElement('fill'); - // gradientFill - $objWriter->startElement('gradientFill'); - $objWriter->writeAttribute('type', $pFill->getFillType()); - $objWriter->writeAttribute('degree', $pFill->getRotation()); + // gradientFill + $objWriter->startElement('gradientFill'); + $objWriter->writeAttribute('type', $pFill->getFillType()); + $objWriter->writeAttribute('degree', $pFill->getRotation()); - // stop - $objWriter->startElement('stop'); - $objWriter->writeAttribute('position', '0'); + // stop + $objWriter->startElement('stop'); + $objWriter->writeAttribute('position', '0'); - // color - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); - $objWriter->endElement(); + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // stop - $objWriter->startElement('stop'); - $objWriter->writeAttribute('position', '1'); + // stop + $objWriter->startElement('stop'); + $objWriter->writeAttribute('position', '1'); - // color - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); - $objWriter->endElement(); + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); $objWriter->endElement(); } @@ -241,28 +241,28 @@ private function _writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, // fill $objWriter->startElement('fill'); - // patternFill - $objWriter->startElement('patternFill'); - $objWriter->writeAttribute('patternType', $pFill->getFillType()); + // patternFill + $objWriter->startElement('patternFill'); + $objWriter->writeAttribute('patternType', $pFill->getFillType()); - if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { - // fgColor - if ($pFill->getStartColor()->getARGB()) { - $objWriter->startElement('fgColor'); - $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); - $objWriter->endElement(); - } - } - if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { - // bgColor - if ($pFill->getEndColor()->getARGB()) { - $objWriter->startElement('bgColor'); - $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); - $objWriter->endElement(); - } - } + if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { + // fgColor + if ($pFill->getStartColor()->getARGB()) { + $objWriter->startElement('fgColor'); + $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); + $objWriter->endElement(); + } + } + if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { + // bgColor + if ($pFill->getEndColor()->getARGB()) { + $objWriter->startElement('bgColor'); + $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); + $objWriter->endElement(); + } + } - $objWriter->endElement(); + $objWriter->endElement(); $objWriter->endElement(); } @@ -278,71 +278,71 @@ private function _writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce { // font $objWriter->startElement('font'); - // Weird! The order of these elements actually makes a difference when opening Excel2007 - // files in Excel2003 with the compatibility pack. It's not documented behaviour, - // and makes for a real WTF! - - // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does - // for conditional formatting). Otherwise it will apparently not be picked up in conditional - // formatting style dialog - if ($pFont->getBold() !== NULL) { - $objWriter->startElement('b'); - $objWriter->writeAttribute('val', $pFont->getBold() ? '1' : '0'); - $objWriter->endElement(); - } + // Weird! The order of these elements actually makes a difference when opening Excel2007 + // files in Excel2003 with the compatibility pack. It's not documented behaviour, + // and makes for a real WTF! + + // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does + // for conditional formatting). Otherwise it will apparently not be picked up in conditional + // formatting style dialog + if ($pFont->getBold() !== null) { + $objWriter->startElement('b'); + $objWriter->writeAttribute('val', $pFont->getBold() ? '1' : '0'); + $objWriter->endElement(); + } - // Italic - if ($pFont->getItalic() !== NULL) { - $objWriter->startElement('i'); - $objWriter->writeAttribute('val', $pFont->getItalic() ? '1' : '0'); - $objWriter->endElement(); - } + // Italic + if ($pFont->getItalic() !== null) { + $objWriter->startElement('i'); + $objWriter->writeAttribute('val', $pFont->getItalic() ? '1' : '0'); + $objWriter->endElement(); + } - // Strikethrough - if ($pFont->getStrikethrough() !== NULL) { - $objWriter->startElement('strike'); - $objWriter->writeAttribute('val', $pFont->getStrikethrough() ? '1' : '0'); - $objWriter->endElement(); - } + // Strikethrough + if ($pFont->getStrikethrough() !== null) { + $objWriter->startElement('strike'); + $objWriter->writeAttribute('val', $pFont->getStrikethrough() ? '1' : '0'); + $objWriter->endElement(); + } - // Underline - if ($pFont->getUnderline() !== NULL) { - $objWriter->startElement('u'); - $objWriter->writeAttribute('val', $pFont->getUnderline()); - $objWriter->endElement(); - } + // Underline + if ($pFont->getUnderline() !== null) { + $objWriter->startElement('u'); + $objWriter->writeAttribute('val', $pFont->getUnderline()); + $objWriter->endElement(); + } - // Superscript / subscript - if ($pFont->getSuperScript() === TRUE || $pFont->getSubScript() === TRUE) { - $objWriter->startElement('vertAlign'); - if ($pFont->getSuperScript() === TRUE) { - $objWriter->writeAttribute('val', 'superscript'); - } else if ($pFont->getSubScript() === TRUE) { - $objWriter->writeAttribute('val', 'subscript'); - } - $objWriter->endElement(); + // Superscript / subscript + if ($pFont->getSuperScript() === true || $pFont->getSubScript() === true) { + $objWriter->startElement('vertAlign'); + if ($pFont->getSuperScript() === true) { + $objWriter->writeAttribute('val', 'superscript'); + } else if ($pFont->getSubScript() === true) { + $objWriter->writeAttribute('val', 'subscript'); } + $objWriter->endElement(); + } - // Size - if ($pFont->getSize() !== NULL) { - $objWriter->startElement('sz'); - $objWriter->writeAttribute('val', $pFont->getSize()); - $objWriter->endElement(); - } + // Size + if ($pFont->getSize() !== null) { + $objWriter->startElement('sz'); + $objWriter->writeAttribute('val', $pFont->getSize()); + $objWriter->endElement(); + } - // Foreground color - if ($pFont->getColor()->getARGB() !== NULL) { - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $pFont->getColor()->getARGB()); - $objWriter->endElement(); - } + // Foreground color + if ($pFont->getColor()->getARGB() !== null) { + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFont->getColor()->getARGB()); + $objWriter->endElement(); + } - // Name - if ($pFont->getName() !== NULL) { - $objWriter->startElement('name'); - $objWriter->writeAttribute('val', $pFont->getName()); - $objWriter->endElement(); - } + // Name + if ($pFont->getName() !== null) { + $objWriter->startElement('name'); + $objWriter->writeAttribute('val', $pFont->getName()); + $objWriter->endElement(); + } $objWriter->endElement(); } @@ -358,28 +358,28 @@ private function _writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx { // Write border $objWriter->startElement('border'); - // Diagonal? - switch ($pBorders->getDiagonalDirection()) { - case PHPExcel_Style_Borders::DIAGONAL_UP: - $objWriter->writeAttribute('diagonalUp', 'true'); - $objWriter->writeAttribute('diagonalDown', 'false'); - break; - case PHPExcel_Style_Borders::DIAGONAL_DOWN: - $objWriter->writeAttribute('diagonalUp', 'false'); - $objWriter->writeAttribute('diagonalDown', 'true'); - break; - case PHPExcel_Style_Borders::DIAGONAL_BOTH: - $objWriter->writeAttribute('diagonalUp', 'true'); - $objWriter->writeAttribute('diagonalDown', 'true'); - break; - } + // Diagonal? + switch ($pBorders->getDiagonalDirection()) { + case PHPExcel_Style_Borders::DIAGONAL_UP: + $objWriter->writeAttribute('diagonalUp', 'true'); + $objWriter->writeAttribute('diagonalDown', 'false'); + break; + case PHPExcel_Style_Borders::DIAGONAL_DOWN: + $objWriter->writeAttribute('diagonalUp', 'false'); + $objWriter->writeAttribute('diagonalDown', 'true'); + break; + case PHPExcel_Style_Borders::DIAGONAL_BOTH: + $objWriter->writeAttribute('diagonalUp', 'true'); + $objWriter->writeAttribute('diagonalDown', 'true'); + break; + } - // BorderPr - $this->_writeBorderPr($objWriter, 'left', $pBorders->getLeft()); - $this->_writeBorderPr($objWriter, 'right', $pBorders->getRight()); - $this->_writeBorderPr($objWriter, 'top', $pBorders->getTop()); - $this->_writeBorderPr($objWriter, 'bottom', $pBorders->getBottom()); - $this->_writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal()); + // BorderPr + $this->_writeBorderPr($objWriter, 'left', $pBorders->getLeft()); + $this->_writeBorderPr($objWriter, 'right', $pBorders->getRight()); + $this->_writeBorderPr($objWriter, 'top', $pBorders->getTop()); + $this->_writeBorderPr($objWriter, 'bottom', $pBorders->getBottom()); + $this->_writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal()); $objWriter->endElement(); } @@ -395,66 +395,66 @@ private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, { // xf $objWriter->startElement('xf'); - $objWriter->writeAttribute('xfId', 0); - $objWriter->writeAttribute('fontId', (int)$this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode())); - if ($pStyle->getQuotePrefix()) { - $objWriter->writeAttribute('quotePrefix', 1); - } + $objWriter->writeAttribute('xfId', 0); + $objWriter->writeAttribute('fontId', (int)$this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode())); + if ($pStyle->getQuotePrefix()) { + $objWriter->writeAttribute('quotePrefix', 1); + } - if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) { - $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164) ); - } else { - $objWriter->writeAttribute('numFmtId', (int)$pStyle->getNumberFormat()->getBuiltInFormatCode()); - } + if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) { + $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164) ); + } else { + $objWriter->writeAttribute('numFmtId', (int)$pStyle->getNumberFormat()->getBuiltInFormatCode()); + } - $objWriter->writeAttribute('fillId', (int)$this->getParentWriter()->getFillHashTable()->getIndexForHashCode($pStyle->getFill()->getHashCode())); - $objWriter->writeAttribute('borderId', (int)$this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($pStyle->getBorders()->getHashCode())); - - // Apply styles? - $objWriter->writeAttribute('applyFont', ($pPHPExcel->getDefaultStyle()->getFont()->getHashCode() != $pStyle->getFont()->getHashCode()) ? '1' : '0'); - $objWriter->writeAttribute('applyNumberFormat', ($pPHPExcel->getDefaultStyle()->getNumberFormat()->getHashCode() != $pStyle->getNumberFormat()->getHashCode()) ? '1' : '0'); - $objWriter->writeAttribute('applyFill', ($pPHPExcel->getDefaultStyle()->getFill()->getHashCode() != $pStyle->getFill()->getHashCode()) ? '1' : '0'); - $objWriter->writeAttribute('applyBorder', ($pPHPExcel->getDefaultStyle()->getBorders()->getHashCode() != $pStyle->getBorders()->getHashCode()) ? '1' : '0'); - $objWriter->writeAttribute('applyAlignment', ($pPHPExcel->getDefaultStyle()->getAlignment()->getHashCode() != $pStyle->getAlignment()->getHashCode()) ? '1' : '0'); - if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { - $objWriter->writeAttribute('applyProtection', 'true'); - } + $objWriter->writeAttribute('fillId', (int)$this->getParentWriter()->getFillHashTable()->getIndexForHashCode($pStyle->getFill()->getHashCode())); + $objWriter->writeAttribute('borderId', (int)$this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($pStyle->getBorders()->getHashCode())); + + // Apply styles? + $objWriter->writeAttribute('applyFont', ($pPHPExcel->getDefaultStyle()->getFont()->getHashCode() != $pStyle->getFont()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyNumberFormat', ($pPHPExcel->getDefaultStyle()->getNumberFormat()->getHashCode() != $pStyle->getNumberFormat()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyFill', ($pPHPExcel->getDefaultStyle()->getFill()->getHashCode() != $pStyle->getFill()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyBorder', ($pPHPExcel->getDefaultStyle()->getBorders()->getHashCode() != $pStyle->getBorders()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyAlignment', ($pPHPExcel->getDefaultStyle()->getAlignment()->getHashCode() != $pStyle->getAlignment()->getHashCode()) ? '1' : '0'); + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('applyProtection', 'true'); + } - // alignment - $objWriter->startElement('alignment'); - $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); - $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); + // alignment + $objWriter->startElement('alignment'); + $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); + $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); - $textRotation = 0; - if ($pStyle->getAlignment()->getTextRotation() >= 0) { - $textRotation = $pStyle->getAlignment()->getTextRotation(); - } else if ($pStyle->getAlignment()->getTextRotation() < 0) { - $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); - } - $objWriter->writeAttribute('textRotation', $textRotation); + $textRotation = 0; + if ($pStyle->getAlignment()->getTextRotation() >= 0) { + $textRotation = $pStyle->getAlignment()->getTextRotation(); + } else if ($pStyle->getAlignment()->getTextRotation() < 0) { + $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); + } + $objWriter->writeAttribute('textRotation', $textRotation); - $objWriter->writeAttribute('wrapText', ($pStyle->getAlignment()->getWrapText() ? 'true' : 'false')); - $objWriter->writeAttribute('shrinkToFit', ($pStyle->getAlignment()->getShrinkToFit() ? 'true' : 'false')); + $objWriter->writeAttribute('wrapText', ($pStyle->getAlignment()->getWrapText() ? 'true' : 'false')); + $objWriter->writeAttribute('shrinkToFit', ($pStyle->getAlignment()->getShrinkToFit() ? 'true' : 'false')); - if ($pStyle->getAlignment()->getIndent() > 0) { - $objWriter->writeAttribute('indent', $pStyle->getAlignment()->getIndent()); - } - if ($pStyle->getAlignment()->getReadorder() > 0) { - $objWriter->writeAttribute('readingOrder', $pStyle->getAlignment()->getReadorder()); - } - $objWriter->endElement(); + if ($pStyle->getAlignment()->getIndent() > 0) { + $objWriter->writeAttribute('indent', $pStyle->getAlignment()->getIndent()); + } + if ($pStyle->getAlignment()->getReadorder() > 0) { + $objWriter->writeAttribute('readingOrder', $pStyle->getAlignment()->getReadorder()); + } + $objWriter->endElement(); - // protection - if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { - $objWriter->startElement('protection'); - if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { - $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); - } - if ($pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { - $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); - } - $objWriter->endElement(); + // protection + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->startElement('protection'); + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + if ($pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); } + $objWriter->endElement(); + } $objWriter->endElement(); } @@ -471,55 +471,54 @@ private function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, // dxf $objWriter->startElement('dxf'); - // font - $this->_writeFont($objWriter, $pStyle->getFont()); + // font + $this->_writeFont($objWriter, $pStyle->getFont()); - // numFmt - $this->_writeNumFmt($objWriter, $pStyle->getNumberFormat()); + // numFmt + $this->_writeNumFmt($objWriter, $pStyle->getNumberFormat()); - // fill - $this->_writeFill($objWriter, $pStyle->getFill()); + // fill + $this->_writeFill($objWriter, $pStyle->getFill()); - // alignment - $objWriter->startElement('alignment'); - if ($pStyle->getAlignment()->getHorizontal() !== NULL) { - $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); - } - if ($pStyle->getAlignment()->getVertical() !== NULL) { - $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); - } + // alignment + $objWriter->startElement('alignment'); + if ($pStyle->getAlignment()->getHorizontal() !== null) { + $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); + } + if ($pStyle->getAlignment()->getVertical() !== null) { + $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); + } - if ($pStyle->getAlignment()->getTextRotation() !== NULL) { - $textRotation = 0; - if ($pStyle->getAlignment()->getTextRotation() >= 0) { - $textRotation = $pStyle->getAlignment()->getTextRotation(); - } else if ($pStyle->getAlignment()->getTextRotation() < 0) { - $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); - } - $objWriter->writeAttribute('textRotation', $textRotation); - } - $objWriter->endElement(); + if ($pStyle->getAlignment()->getTextRotation() !== null) { + $textRotation = 0; + if ($pStyle->getAlignment()->getTextRotation() >= 0) { + $textRotation = $pStyle->getAlignment()->getTextRotation(); + } else if ($pStyle->getAlignment()->getTextRotation() < 0) { + $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); + } + $objWriter->writeAttribute('textRotation', $textRotation); + } + $objWriter->endElement(); - // border - $this->_writeBorder($objWriter, $pStyle->getBorders()); - - // protection - if (($pStyle->getProtection()->getLocked() !== NULL) || - ($pStyle->getProtection()->getHidden() !== NULL)) { - if ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT || - $pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT) { - $objWriter->startElement('protection'); - if (($pStyle->getProtection()->getLocked() !== NULL) && - ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { - $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); - } - if (($pStyle->getProtection()->getHidden() !== NULL) && - ($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { - $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); - } - $objWriter->endElement(); - } + // border + $this->_writeBorder($objWriter, $pStyle->getBorders()); + + // protection + if (($pStyle->getProtection()->getLocked() !== null) || ($pStyle->getProtection()->getHidden() !== null)) { + if ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT || + $pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->startElement('protection'); + if (($pStyle->getProtection()->getLocked() !== null) && + ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { + $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + if (($pStyle->getProtection()->getHidden() !== null) && + ($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { + $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + $objWriter->endElement(); } + } $objWriter->endElement(); } @@ -537,12 +536,12 @@ private function _writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pN // Write BorderPr if ($pBorder->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) { $objWriter->startElement($pName); - $objWriter->writeAttribute('style', $pBorder->getBorderStyle()); + $objWriter->writeAttribute('style', $pBorder->getBorderStyle()); - // color - $objWriter->startElement('color'); - $objWriter->writeAttribute('rgb', $pBorder->getColor()->getARGB()); - $objWriter->endElement(); + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pBorder->getColor()->getARGB()); + $objWriter->endElement(); $objWriter->endElement(); } @@ -562,10 +561,10 @@ private function _writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx $formatCode = $pNumberFormat->getFormatCode(); // numFmt - if ($formatCode !== NULL) { + if ($formatCode !== null) { $objWriter->startElement('numFmt'); - $objWriter->writeAttribute('numFmtId', ($pId + 164)); - $objWriter->writeAttribute('formatCode', $formatCode); + $objWriter->writeAttribute('numFmtId', ($pId + 164)); + $objWriter->writeAttribute('formatCode', $formatCode); $objWriter->endElement(); } } @@ -579,9 +578,7 @@ private function _writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx */ public function allStyles(PHPExcel $pPHPExcel = null) { - $aStyles = $pPHPExcel->getCellXfCollection(); - - return $aStyles; + return $pPHPExcel->getCellXfCollection(); } /** @@ -594,7 +591,7 @@ public function allStyles(PHPExcel $pPHPExcel = null) public function allConditionalStyles(PHPExcel $pPHPExcel = null) { // Get an array of all styles - $aStyles = array(); + $aStyles = array(); $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { @@ -618,7 +615,7 @@ public function allConditionalStyles(PHPExcel $pPHPExcel = null) public function allFills(PHPExcel $pPHPExcel = null) { // Get an array of unique fills - $aFills = array(); + $aFills = array(); // Two first fills are predefined $fill0 = new PHPExcel_Style_Fill(); @@ -629,7 +626,7 @@ public function allFills(PHPExcel $pPHPExcel = null) $fill1->setFillType(PHPExcel_Style_Fill::FILL_PATTERN_GRAY125); $aFills[] = $fill1; // The remaining fills - $aStyles = $this->allStyles($pPHPExcel); + $aStyles = $this->allStyles($pPHPExcel); foreach ($aStyles as $style) { if (!array_key_exists($style->getFill()->getHashCode(), $aFills)) { $aFills[ $style->getFill()->getHashCode() ] = $style->getFill(); @@ -649,8 +646,8 @@ public function allFills(PHPExcel $pPHPExcel = null) public function allFonts(PHPExcel $pPHPExcel = null) { // Get an array of unique fonts - $aFonts = array(); - $aStyles = $this->allStyles($pPHPExcel); + $aFonts = array(); + $aStyles = $this->allStyles($pPHPExcel); foreach ($aStyles as $style) { if (!array_key_exists($style->getFont()->getHashCode(), $aFonts)) { @@ -671,8 +668,8 @@ public function allFonts(PHPExcel $pPHPExcel = null) public function allBorders(PHPExcel $pPHPExcel = null) { // Get an array of unique borders - $aBorders = array(); - $aStyles = $this->allStyles($pPHPExcel); + $aBorders = array(); + $aStyles = $this->allStyles($pPHPExcel); foreach ($aStyles as $style) { if (!array_key_exists($style->getBorders()->getHashCode(), $aBorders)) { @@ -693,8 +690,8 @@ public function allBorders(PHPExcel $pPHPExcel = null) public function allNumberFormats(PHPExcel $pPHPExcel = null) { // Get an array of unique number formats - $aNumFmts = array(); - $aStyles = $this->allStyles($pPHPExcel); + $aNumFmts = array(); + $aStyles = $this->allStyles($pPHPExcel); foreach ($aStyles as $style) { if ($style->getNumberFormat()->getBuiltInFormatCode() === false && !array_key_exists($style->getNumberFormat()->getHashCode(), $aNumFmts)) { diff --git a/Classes/PHPExcel/Writer/Excel2007/Theme.php b/Classes/PHPExcel/Writer/Excel2007/Theme.php index 281cd5fef..279ecff93 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Theme.php +++ b/Classes/PHPExcel/Writer/Excel2007/Theme.php @@ -41,37 +41,37 @@ class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPa * */ private static $_majorFonts = array( - 'Jpan' => 'MS Pゴシック', - 'Hang' => '맑은 고딕', - 'Hans' => '宋体', - 'Hant' => '新細明體', - 'Arab' => 'Times New Roman', - 'Hebr' => 'Times New Roman', - 'Thai' => 'Tahoma', - 'Ethi' => 'Nyala', - 'Beng' => 'Vrinda', - 'Gujr' => 'Shruti', - 'Khmr' => 'MoolBoran', - 'Knda' => 'Tunga', - 'Guru' => 'Raavi', - 'Cans' => 'Euphemia', - 'Cher' => 'Plantagenet Cherokee', - 'Yiii' => 'Microsoft Yi Baiti', - 'Tibt' => 'Microsoft Himalaya', - 'Thaa' => 'MV Boli', - 'Deva' => 'Mangal', - 'Telu' => 'Gautami', - 'Taml' => 'Latha', - 'Syrc' => 'Estrangelo Edessa', - 'Orya' => 'Kalinga', - 'Mlym' => 'Kartika', - 'Laoo' => 'DokChampa', - 'Sinh' => 'Iskoola Pota', - 'Mong' => 'Mongolian Baiti', - 'Viet' => 'Times New Roman', - 'Uigh' => 'Microsoft Uighur', - 'Geor' => 'Sylfaen', - ); + 'Jpan' => 'MS Pゴシック', + 'Hang' => '맑은 고딕', + 'Hans' => '宋体', + 'Hant' => '新細明體', + 'Arab' => 'Times New Roman', + 'Hebr' => 'Times New Roman', + 'Thai' => 'Tahoma', + 'Ethi' => 'Nyala', + 'Beng' => 'Vrinda', + 'Gujr' => 'Shruti', + 'Khmr' => 'MoolBoran', + 'Knda' => 'Tunga', + 'Guru' => 'Raavi', + 'Cans' => 'Euphemia', + 'Cher' => 'Plantagenet Cherokee', + 'Yiii' => 'Microsoft Yi Baiti', + 'Tibt' => 'Microsoft Himalaya', + 'Thaa' => 'MV Boli', + 'Deva' => 'Mangal', + 'Telu' => 'Gautami', + 'Taml' => 'Latha', + 'Syrc' => 'Estrangelo Edessa', + 'Orya' => 'Kalinga', + 'Mlym' => 'Kartika', + 'Laoo' => 'DokChampa', + 'Sinh' => 'Iskoola Pota', + 'Mong' => 'Mongolian Baiti', + 'Viet' => 'Times New Roman', + 'Uigh' => 'Microsoft Uighur', + 'Geor' => 'Sylfaen', + ); /** * Map of Minor fonts to write @@ -79,55 +79,55 @@ class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPa * */ private static $_minorFonts = array( - 'Jpan' => 'MS Pゴシック', - 'Hang' => '맑은 고딕', - 'Hans' => '宋体', - 'Hant' => '新細明體', - 'Arab' => 'Arial', - 'Hebr' => 'Arial', - 'Thai' => 'Tahoma', - 'Ethi' => 'Nyala', - 'Beng' => 'Vrinda', - 'Gujr' => 'Shruti', - 'Khmr' => 'DaunPenh', - 'Knda' => 'Tunga', - 'Guru' => 'Raavi', - 'Cans' => 'Euphemia', - 'Cher' => 'Plantagenet Cherokee', - 'Yiii' => 'Microsoft Yi Baiti', - 'Tibt' => 'Microsoft Himalaya', - 'Thaa' => 'MV Boli', - 'Deva' => 'Mangal', - 'Telu' => 'Gautami', - 'Taml' => 'Latha', - 'Syrc' => 'Estrangelo Edessa', - 'Orya' => 'Kalinga', - 'Mlym' => 'Kartika', - 'Laoo' => 'DokChampa', - 'Sinh' => 'Iskoola Pota', - 'Mong' => 'Mongolian Baiti', - 'Viet' => 'Arial', - 'Uigh' => 'Microsoft Uighur', - 'Geor' => 'Sylfaen', - ); + 'Jpan' => 'MS Pゴシック', + 'Hang' => '맑은 고딕', + 'Hans' => '宋体', + 'Hant' => '新細明體', + 'Arab' => 'Arial', + 'Hebr' => 'Arial', + 'Thai' => 'Tahoma', + 'Ethi' => 'Nyala', + 'Beng' => 'Vrinda', + 'Gujr' => 'Shruti', + 'Khmr' => 'DaunPenh', + 'Knda' => 'Tunga', + 'Guru' => 'Raavi', + 'Cans' => 'Euphemia', + 'Cher' => 'Plantagenet Cherokee', + 'Yiii' => 'Microsoft Yi Baiti', + 'Tibt' => 'Microsoft Himalaya', + 'Thaa' => 'MV Boli', + 'Deva' => 'Mangal', + 'Telu' => 'Gautami', + 'Taml' => 'Latha', + 'Syrc' => 'Estrangelo Edessa', + 'Orya' => 'Kalinga', + 'Mlym' => 'Kartika', + 'Laoo' => 'DokChampa', + 'Sinh' => 'Iskoola Pota', + 'Mong' => 'Mongolian Baiti', + 'Viet' => 'Arial', + 'Uigh' => 'Microsoft Uighur', + 'Geor' => 'Sylfaen', + ); /** * Map of core colours * @static array of string * */ - private static $_colourScheme = array( - 'dk2' => '1F497D', - 'lt2' => 'EEECE1', - 'accent1' => '4F81BD', - 'accent2' => 'C0504D', - 'accent3' => '9BBB59', - 'accent4' => '8064A2', - 'accent5' => '4BACC6', - 'accent6' => 'F79646', - 'hlink' => '0000FF', - 'folHlink' => '800080', - ); + private static $_colourScheme = array( + 'dk2' => '1F497D', + 'lt2' => 'EEECE1', + 'accent1' => '4F81BD', + 'accent2' => 'C0504D', + 'accent3' => '9BBB59', + 'accent4' => '8064A2', + 'accent5' => '4BACC6', + 'accent6' => 'F79646', + 'hlink' => '0000FF', + 'folHlink' => '800080', + ); /** * Write theme to XML format @@ -147,7 +147,7 @@ public function writeTheme(PHPExcel $pPHPExcel = null) } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // a:theme $objWriter->startElement('a:theme'); @@ -839,13 +839,12 @@ private function _writeFonts($objWriter, $latinFont, $fontSet) $objWriter->writeAttribute('typeface', ''); $objWriter->endElement(); - foreach($fontSet as $fontScript => $typeface) { + foreach ($fontSet as $fontScript => $typeface) { $objWriter->startElement('a:font'); $objWriter->writeAttribute('script', $fontScript); $objWriter->writeAttribute('typeface', $typeface); $objWriter->endElement(); } - } /** @@ -857,7 +856,7 @@ private function _writeFonts($objWriter, $latinFont, $fontSet) */ private function _writeColourScheme($objWriter) { - foreach(self::$_colourScheme as $colourName => $colourValue) { + foreach (self::$_colourScheme as $colourName => $colourValue) { $objWriter->startElement('a:'.$colourName); $objWriter->startElement('a:srgbClr'); @@ -866,6 +865,5 @@ private function _writeColourScheme($objWriter) $objWriter->endElement(); } - } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Workbook.php b/Classes/PHPExcel/Writer/Excel2007/Workbook.php index 4753d8107..1162501f7 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel2007/Workbook.php @@ -43,7 +43,7 @@ class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_Write * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = FALSE) + public function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = false) { // Create XML writer $objWriter = null; @@ -54,7 +54,7 @@ public function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = FALS } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // workbook $objWriter->startElement('workbook'); @@ -62,28 +62,28 @@ public function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = FALS $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - // fileVersion - $this->_writeFileVersion($objWriter); + // fileVersion + $this->_writeFileVersion($objWriter); - // workbookPr - $this->_writeWorkbookPr($objWriter); + // workbookPr + $this->_writeWorkbookPr($objWriter); - // workbookProtection - $this->_writeWorkbookProtection($objWriter, $pPHPExcel); + // workbookProtection + $this->_writeWorkbookProtection($objWriter, $pPHPExcel); - // bookViews - if ($this->getParentWriter()->getOffice2003Compatibility() === false) { - $this->_writeBookViews($objWriter, $pPHPExcel); - } + // bookViews + if ($this->getParentWriter()->getOffice2003Compatibility() === false) { + $this->_writeBookViews($objWriter, $pPHPExcel); + } - // sheets - $this->_writeSheets($objWriter, $pPHPExcel); + // sheets + $this->_writeSheets($objWriter, $pPHPExcel); - // definedNames - $this->_writeDefinedNames($objWriter, $pPHPExcel); + // definedNames + $this->_writeDefinedNames($objWriter, $pPHPExcel); - // calcPr - $this->_writeCalcPr($objWriter,$recalcRequired); + // calcPr + $this->_writeCalcPr($objWriter, $recalcRequired); $objWriter->endElement(); @@ -138,20 +138,20 @@ private function _writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PH // bookViews $objWriter->startElement('bookViews'); - // workbookView - $objWriter->startElement('workbookView'); + // workbookView + $objWriter->startElement('workbookView'); - $objWriter->writeAttribute('activeTab', $pPHPExcel->getActiveSheetIndex()); - $objWriter->writeAttribute('autoFilterDateGrouping', '1'); - $objWriter->writeAttribute('firstSheet', '0'); - $objWriter->writeAttribute('minimized', '0'); - $objWriter->writeAttribute('showHorizontalScroll', '1'); - $objWriter->writeAttribute('showSheetTabs', '1'); - $objWriter->writeAttribute('showVerticalScroll', '1'); - $objWriter->writeAttribute('tabRatio', '600'); - $objWriter->writeAttribute('visibility', 'visible'); + $objWriter->writeAttribute('activeTab', $pPHPExcel->getActiveSheetIndex()); + $objWriter->writeAttribute('autoFilterDateGrouping', '1'); + $objWriter->writeAttribute('firstSheet', '0'); + $objWriter->writeAttribute('minimized', '0'); + $objWriter->writeAttribute('showHorizontalScroll', '1'); + $objWriter->writeAttribute('showSheetTabs', '1'); + $objWriter->writeAttribute('showVerticalScroll', '1'); + $objWriter->writeAttribute('tabRatio', '600'); + $objWriter->writeAttribute('visibility', 'visible'); - $objWriter->endElement(); + $objWriter->endElement(); $objWriter->endElement(); } @@ -167,16 +167,16 @@ private function _writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = { if ($pPHPExcel->getSecurity()->isSecurityEnabled()) { $objWriter->startElement('workbookProtection'); - $objWriter->writeAttribute('lockRevision', ($pPHPExcel->getSecurity()->getLockRevision() ? 'true' : 'false')); - $objWriter->writeAttribute('lockStructure', ($pPHPExcel->getSecurity()->getLockStructure() ? 'true' : 'false')); - $objWriter->writeAttribute('lockWindows', ($pPHPExcel->getSecurity()->getLockWindows() ? 'true' : 'false')); + $objWriter->writeAttribute('lockRevision', ($pPHPExcel->getSecurity()->getLockRevision() ? 'true' : 'false')); + $objWriter->writeAttribute('lockStructure', ($pPHPExcel->getSecurity()->getLockStructure() ? 'true' : 'false')); + $objWriter->writeAttribute('lockWindows', ($pPHPExcel->getSecurity()->getLockWindows() ? 'true' : 'false')); if ($pPHPExcel->getSecurity()->getRevisionsPassword() != '') { - $objWriter->writeAttribute('revisionsPassword', $pPHPExcel->getSecurity()->getRevisionsPassword()); + $objWriter->writeAttribute('revisionsPassword', $pPHPExcel->getSecurity()->getRevisionsPassword()); } if ($pPHPExcel->getSecurity()->getWorkbookPassword() != '') { - $objWriter->writeAttribute('workbookPassword', $pPHPExcel->getSecurity()->getWorkbookPassword()); + $objWriter->writeAttribute('workbookPassword', $pPHPExcel->getSecurity()->getWorkbookPassword()); } $objWriter->endElement(); @@ -190,18 +190,18 @@ private function _writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing * @throws PHPExcel_Writer_Exception */ - private function _writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = TRUE) + private function _writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = true) { $objWriter->startElement('calcPr'); // Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc // If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit // because the file has changed - $objWriter->writeAttribute('calcId', '999999'); - $objWriter->writeAttribute('calcMode', 'auto'); + $objWriter->writeAttribute('calcId', '999999'); + $objWriter->writeAttribute('calcMode', 'auto'); // fullCalcOnLoad isn't needed if we've recalculating for the save - $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0); - $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1); + $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0); + $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1); $objWriter->endElement(); } @@ -247,12 +247,12 @@ private function _writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pShee if ($pSheetname != '') { // Write sheet $objWriter->startElement('sheet'); - $objWriter->writeAttribute('name', $pSheetname); - $objWriter->writeAttribute('sheetId', $pSheetId); + $objWriter->writeAttribute('name', $pSheetname); + $objWriter->writeAttribute('sheetId', $pSheetId); if ($sheetState != 'visible' && $sheetState != '') { $objWriter->writeAttribute('state', $sheetState); } - $objWriter->writeAttribute('r:id', 'rId' . $pRelId); + $objWriter->writeAttribute('r:id', 'rId' . $pRelId); $objWriter->endElement(); } else { throw new PHPExcel_Writer_Exception("Invalid parameters passed."); @@ -320,9 +320,9 @@ private function _writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWr { // definedName for named range $objWriter->startElement('definedName'); - $objWriter->writeAttribute('name', $pNamedRange->getName()); + $objWriter->writeAttribute('name', $pNamedRange->getName()); if ($pNamedRange->getLocalOnly()) { - $objWriter->writeAttribute('localSheetId', $pNamedRange->getScope()->getParent()->getIndex($pNamedRange->getScope())); + $objWriter->writeAttribute('localSheetId', $pNamedRange->getScope()->getParent()->getIndex($pNamedRange->getScope())); } // Create absolute coordinate and write as raw text @@ -354,16 +354,16 @@ private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWr $autoFilterRange = $pSheet->getAutoFilter()->getRange(); if (!empty($autoFilterRange)) { $objWriter->startElement('definedName'); - $objWriter->writeAttribute('name', '_xlnm._FilterDatabase'); - $objWriter->writeAttribute('localSheetId', $pSheetId); - $objWriter->writeAttribute('hidden', '1'); + $objWriter->writeAttribute('name', '_xlnm._FilterDatabase'); + $objWriter->writeAttribute('localSheetId', $pSheetId); + $objWriter->writeAttribute('hidden', '1'); // Create absolute coordinate and write as raw text $range = PHPExcel_Cell::splitRange($autoFilterRange); $range = $range[0]; // Strip any worksheet ref so we can make the cell ref absolute if (strpos($range[0],'!') !== false) { - list($ws,$range[0]) = explode('!',$range[0]); + list($ws, $range[0]) = explode('!', $range[0]); } $range[0] = PHPExcel_Cell::absoluteCoordinate($range[0]); @@ -389,8 +389,8 @@ private function _writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objW // definedName for PrintTitles if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { $objWriter->startElement('definedName'); - $objWriter->writeAttribute('name', '_xlnm.Print_Titles'); - $objWriter->writeAttribute('localSheetId', $pSheetId); + $objWriter->writeAttribute('name', '_xlnm.Print_Titles'); + $objWriter->writeAttribute('localSheetId', $pSheetId); // Setting string $settingString = ''; @@ -432,8 +432,8 @@ private function _writeDefinedNameForPrintArea(PHPExcel_Shared_XMLWriter $objWri // definedName for PrintArea if ($pSheet->getPageSetup()->isPrintAreaSet()) { $objWriter->startElement('definedName'); - $objWriter->writeAttribute('name', '_xlnm.Print_Area'); - $objWriter->writeAttribute('localSheetId', $pSheetId); + $objWriter->writeAttribute('name', '_xlnm.Print_Area'); + $objWriter->writeAttribute('localSheetId', $pSheetId); // Setting string $settingString = ''; diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index e0ef6f533..899a54bf2 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -56,7 +56,7 @@ public function writeWorksheet($pSheet = null, $pStringTable = null, $includeCha } // XML header - $objWriter->startDocument('1.0','UTF-8','yes'); + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // Worksheet $objWriter->startElement('worksheet'); @@ -148,8 +148,8 @@ private function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPE // sheetPr $objWriter->startElement('sheetPr'); //$objWriter->writeAttribute('codeName', $pSheet->getTitle()); - if($pSheet->getParent()->hasMacros()){//if the workbook have macros, we need to have codeName for the sheet - if($pSheet->hasCodeName()==false){ + if ($pSheet->getParent()->hasMacros()) {//if the workbook have macros, we need to have codeName for the sheet + if ($pSheet->hasCodeName()==false) { $pSheet->setCodeName($pSheet->getTitle()); } $objWriter->writeAttribute('codeName', $pSheet->getCodeName()); @@ -758,15 +758,15 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P $range = $range[0]; // Strip any worksheet ref if (strpos($range[0],'!') !== false) { - list($ws,$range[0]) = explode('!',$range[0]); + list($ws, $range[0]) = explode('!', $range[0]); } $range = implode(':', $range); - $objWriter->writeAttribute('ref', str_replace('$','',$range)); + $objWriter->writeAttribute('ref', str_replace('$','', $range)); $columns = $pSheet->getAutoFilter()->getColumns(); if (count($columns > 0)) { - foreach($columns as $columnID => $column) { + foreach ($columns as $columnID => $column) { $rules = $column->getRules(); if (count($rules > 0)) { $objWriter->startElement('filterColumn'); @@ -783,7 +783,7 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P ($rule->getValue() === '')) { // Filter rule for Blanks $objWriter->writeAttribute('blank', 1); - } elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { + } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { // Dynamic Filter Rule $objWriter->writeAttribute('type', $rule->getGrouping()); $val = $column->getAttribute('val'); @@ -794,7 +794,7 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P if ($maxVal !== NULL) { $objWriter->writeAttribute('maxVal', $maxVal); } - } elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { + } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { // Top 10 Filter Rule $objWriter->writeAttribute('val', $rule->getValue()); $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); @@ -808,7 +808,7 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P } if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { // Date Group filters - foreach($rule->getValue() as $key => $value) { + foreach ($rule->getValue() as $key => $value) { if ($value > '') $objWriter->writeAttribute($key, $value); } $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); @@ -979,7 +979,7 @@ private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PH } $currentRow = 0; - while($currentRow++ < $highestRow) { + while ($currentRow++ < $highestRow) { // Get row dimension $rowDimension = $pSheet->getRowDimension($currentRow); @@ -1026,7 +1026,7 @@ private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PH // Write cells if (isset($cellsByRow[$currentRow])) { - foreach($cellsByRow[$currentRow] as $cellAddress) { + foreach ($cellsByRow[$currentRow] as $cellAddress) { // Write cell $this->_writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable); } @@ -1115,7 +1115,7 @@ private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce break; case 'f': // Formula $attributes = $pCell->getFormulaAttributes(); - if($attributes['t'] == 'array') { + if ($attributes['t'] == 'array') { $objWriter->startElement('f'); $objWriter->writeAttribute('t', 'array'); $objWriter->writeAttribute('ref', $pCellAddress); diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index d2502aa02..c9e643756 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -333,7 +333,7 @@ private function _buildWorksheetEschers() $iNumColEnd = $rangeBounds[1][0]; $iInc = $iNumColStart; - while($iInc <= $iNumColEnd) { + while ($iInc <= $iNumColEnd) { ++$countShapes[$sheetIndex]; // create an Drawing Object for the dropdown @@ -679,21 +679,18 @@ private function _writeDocumentSummaryInformation() $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; - } - elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer + } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; - } - elseif ($dataProp['type']['data'] == 0x0B) { // Boolean + } elseif ($dataProp['type']['data'] == 0x0B) { // Boolean if ($dataProp['data']['data'] == false) { $dataSection_Content .= pack('V', 0x0000); } else { $dataSection_Content .= pack('V', 0x0001); } $dataSection_Content_Offset += 4 + 4; - } - elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length + } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length // Null-terminated string $dataProp['data']['data'] .= chr(0); $dataProp['data']['length'] += 1; @@ -705,13 +702,11 @@ private function _writeDocumentSummaryInformation() $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); - } - elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + } elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + 8; - } - else { + } else { // Data Type Not Used at the moment $dataSection_Content .= $dataProp['data']['data']; @@ -867,13 +862,11 @@ private function _writeSummaryInformation() $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; - } - elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer + } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer $dataSection_Content .= pack('V', $dataProp['data']['data']); $dataSection_Content_Offset += 4 + 4; - } - elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length + } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length // Null-terminated string $dataProp['data']['data'] .= chr(0); $dataProp['data']['length'] += 1; @@ -885,13 +878,11 @@ private function _writeSummaryInformation() $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); - } - elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + } elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) $dataSection_Content .= $dataProp['data']['data']; $dataSection_Content_Offset += 4 + 8; - } - else { + } else { // Data Type Not Used at the moment } } diff --git a/Classes/PHPExcel/Writer/Excel5/Parser.php b/Classes/PHPExcel/Writer/Excel5/Parser.php index 6a5e3e083..8cf86ca8b 100644 --- a/Classes/PHPExcel/Writer/Excel5/Parser.php +++ b/Classes/PHPExcel/Writer/Excel5/Parser.php @@ -1097,7 +1097,7 @@ private function _advance() */ private function _match($token) { - switch($token) { + switch ($token) { case "+": case "-": case "*": @@ -1183,7 +1183,7 @@ private function _match($token) } // It's an argument of some description (e.g. a named range), // precise nature yet to be determined - elseif(substr($token,-1) == ')') { + elseif (substr($token,-1) == ')') { return $token; } return ''; @@ -1425,7 +1425,7 @@ private function _fact() // If it's a number or a percent elseif (is_numeric($this->_current_token)) { - if($this->_lookahead == '%'){ + if ($this->_lookahead == '%') { $result = $this->_createTree('ptgPercent', $this->_current_token, ''); $this->_advance(); // Skip the percentage operator once we've pre-built that tree } else { diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index 24c5ccccd..298cb2c11 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -1275,7 +1275,7 @@ private function _writePalette() // Pack the RGB data foreach ($aref as $color) { foreach ($color as $byte) { - $data .= pack("C",$byte); + $data .= pack("C", $byte); } } From 7d086fdbeedd50558f27be78b3a890fde198cdfb Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Wed, 13 May 2015 13:15:55 +0200 Subject: [PATCH 366/467] PSR-2 : Fixes --- Classes/PHPExcel/Writer/Excel2007/Rels.php | 350 ++++---- .../PHPExcel/Writer/Excel2007/RelsRibbon.php | 9 +- Classes/PHPExcel/Writer/Excel2007/RelsVBA.php | 4 +- .../PHPExcel/Writer/Excel2007/StringTable.php | 218 ++--- Classes/PHPExcel/Writer/Excel2007/Style.php | 18 +- Classes/PHPExcel/Writer/Excel2007/Theme.php | 850 +++++++++--------- .../PHPExcel/Writer/Excel2007/Workbook.php | 2 +- .../PHPExcel/Writer/Excel2007/Worksheet.php | 517 ++++++----- Classes/PHPExcel/Writer/Excel5.php | 2 +- Classes/PHPExcel/Writer/Excel5/Escher.php | 11 +- Classes/PHPExcel/Writer/Excel5/Parser.php | 104 +-- Classes/PHPExcel/Writer/Excel5/Workbook.php | 5 +- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 11 +- 13 files changed, 1039 insertions(+), 1062 deletions(-) diff --git a/Classes/PHPExcel/Writer/Excel2007/Rels.php b/Classes/PHPExcel/Writer/Excel2007/Rels.php index c08fe6209..5e8abe696 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Rels.php +++ b/Classes/PHPExcel/Writer/Excel2007/Rels.php @@ -59,50 +59,50 @@ public function writeRelationships(PHPExcel $pPHPExcel = null) $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); - if (!empty($customPropertyList)) { - // Relationship docProps/app.xml - $this->_writeRelationship( - $objWriter, - 4, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties', - 'docProps/custom.xml' - ); - - } - + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (!empty($customPropertyList)) { // Relationship docProps/app.xml $this->_writeRelationship( $objWriter, - 3, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties', - 'docProps/app.xml' + 4, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties', + 'docProps/custom.xml' ); - // Relationship docProps/core.xml - $this->_writeRelationship( - $objWriter, - 2, - 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', - 'docProps/core.xml' - ); + } - // Relationship xl/workbook.xml - $this->_writeRelationship( + // Relationship docProps/app.xml + $this->_writeRelationship( + $objWriter, + 3, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties', + 'docProps/app.xml' + ); + + // Relationship docProps/core.xml + $this->_writeRelationship( + $objWriter, + 2, + 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', + 'docProps/core.xml' + ); + + // Relationship xl/workbook.xml + $this->_writeRelationship( + $objWriter, + 1, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', + 'xl/workbook.xml' + ); + // a custom UI in workbook ? + if ($pPHPExcel->hasRibbon()) { + $this->_writeRelationShip( $objWriter, - 1, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', - 'xl/workbook.xml' + 5, + 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', + $pPHPExcel->getRibbonXMLData('target') ); - // a custom UI in workbook ? - if ($pPHPExcel->hasRibbon()) { - $this->_writeRelationShip( - $objWriter, - 5, - 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', - $pPHPExcel->getRibbonXMLData('target') - ); - } + } $objWriter->endElement(); @@ -134,51 +134,51 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - // Relationship styles.xml - $this->_writeRelationship( - $objWriter, - 1, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles', - 'styles.xml' - ); - - // Relationship theme/theme1.xml + // Relationship styles.xml + $this->_writeRelationship( + $objWriter, + 1, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles', + 'styles.xml' + ); + + // Relationship theme/theme1.xml + $this->_writeRelationship( + $objWriter, + 2, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', + 'theme/theme1.xml' + ); + + // Relationship sharedStrings.xml + $this->_writeRelationship( + $objWriter, + 3, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', + 'sharedStrings.xml' + ); + + // Relationships with sheets + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { $this->_writeRelationship( $objWriter, - 2, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', - 'theme/theme1.xml' + ($i + 1 + 3), + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', + 'worksheets/sheet' . ($i + 1) . '.xml' ); - - // Relationship sharedStrings.xml - $this->_writeRelationship( + } + // Relationships for vbaProject if needed + // id : just after the last sheet + if ($pPHPExcel->hasMacros()) { + $this->_writeRelationShip( $objWriter, - 3, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', - 'sharedStrings.xml' + ($i + 1 + 3), + 'http://schemas.microsoft.com/office/2006/relationships/vbaProject', + 'vbaProject.bin' ); - - // Relationships with sheets - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - $this->_writeRelationship( - $objWriter, - ($i + 1 + 3), - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', - 'worksheets/sheet' . ($i + 1) . '.xml' - ); - } - // Relationships for vbaProject if needed - // id : just after the last sheet - if ($pPHPExcel->hasMacros()) { - $this->_writeRelationShip( - $objWriter, - ($i + 1 + 3), - 'http://schemas.microsoft.com/office/2006/relationships/vbaProject', - 'vbaProject.bin' - ); - ++$i;//increment i if needed for an another relation - } + ++$i;//increment i if needed for an another relation + } $objWriter->endElement(); @@ -199,7 +199,7 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = null, $pWorksheetId = 1, $includeCharts = FALSE) + public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = null, $pWorksheetId = 1, $includeCharts = false) { // Create XML writer $objWriter = null; @@ -216,24 +216,24 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - // Write drawing relationships? - $d = 0; - if ($includeCharts) { - $charts = $pWorksheet->getChartCollection(); - } else { - $charts = array(); - } - if (($pWorksheet->getDrawingCollection()->count() > 0) || - (count($charts) > 0)) { - $this->_writeRelationship( - $objWriter, - ++$d, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', - '../drawings/drawing' . $pWorksheetId . '.xml' - ); - } + // Write drawing relationships? + $d = 0; + if ($includeCharts) { + $charts = $pWorksheet->getChartCollection(); + } else { + $charts = array(); + } + if (($pWorksheet->getDrawingCollection()->count() > 0) || + (count($charts) > 0)) { + $this->_writeRelationship( + $objWriter, + ++$d, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', + '../drawings/drawing' . $pWorksheetId . '.xml' + ); + } - // Write chart relationships? + // Write chart relationships? // $chartCount = 0; // $charts = $pWorksheet->getChartCollection(); // echo 'Chart Rels: ' , count($charts) , '<br />'; @@ -248,50 +248,50 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul // } // } // - // Write hyperlink relationships? - $i = 1; - foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) { - if (!$hyperlink->isInternal()) { - $this->_writeRelationship( - $objWriter, - '_hyperlink_' . $i, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', - $hyperlink->getUrl(), - 'External' - ); - - ++$i; - } - } - - // Write comments relationship? - $i = 1; - if (count($pWorksheet->getComments()) > 0) { + // Write hyperlink relationships? + $i = 1; + foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) { + if (!$hyperlink->isInternal()) { $this->_writeRelationship( $objWriter, - '_comments_vml' . $i, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', - '../drawings/vmlDrawing' . $pWorksheetId . '.vml' + '_hyperlink_' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', + $hyperlink->getUrl(), + 'External' ); - $this->_writeRelationship( - $objWriter, - '_comments' . $i, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', - '../comments' . $pWorksheetId . '.xml' - ); + ++$i; } + } - // Write header/footer relationship? - $i = 1; - if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) { - $this->_writeRelationship( - $objWriter, - '_headerfooter_vml' . $i, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', - '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml' - ); - } + // Write comments relationship? + $i = 1; + if (count($pWorksheet->getComments()) > 0) { + $this->_writeRelationship( + $objWriter, + '_comments_vml' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', + '../drawings/vmlDrawing' . $pWorksheetId . '.vml' + ); + + $this->_writeRelationship( + $objWriter, + '_comments' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', + '../comments' . $pWorksheetId . '.xml' + ); + } + + // Write header/footer relationship? + $i = 1; + if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) { + $this->_writeRelationship( + $objWriter, + '_headerfooter_vml' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', + '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml' + ); + } $objWriter->endElement(); @@ -308,7 +308,7 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE) + public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = false) { // Create XML writer $objWriter = null; @@ -325,39 +325,39 @@ public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - // Loop through images and write relationships - $i = 1; - $iterator = $pWorksheet->getDrawingCollection()->getIterator(); - while ($iterator->valid()) { - if ($iterator->current() instanceof PHPExcel_Worksheet_Drawing - || $iterator->current() instanceof PHPExcel_Worksheet_MemoryDrawing) { - // Write relationship for image drawing + // Loop through images and write relationships + $i = 1; + $iterator = $pWorksheet->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + if ($iterator->current() instanceof PHPExcel_Worksheet_Drawing + || $iterator->current() instanceof PHPExcel_Worksheet_MemoryDrawing) { + // Write relationship for image drawing + $this->_writeRelationship( + $objWriter, + $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', + '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename()) + ); + } + + $iterator->next(); + ++$i; + } + + if ($includeCharts) { + // Loop through charts and write relationships + $chartCount = $pWorksheet->getChartCount(); + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { $this->_writeRelationship( $objWriter, - $i, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', - '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename()) + $i++, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', + '../charts/chart' . ++$chartRef . '.xml' ); } - - $iterator->next(); - ++$i; - } - - if ($includeCharts) { - // Loop through charts and write relationships - $chartCount = $pWorksheet->getChartCount(); - if ($chartCount > 0) { - for ($c = 0; $c < $chartCount; ++$c) { - $this->_writeRelationship( - $objWriter, - $i++, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', - '../charts/chart' . ++$chartRef . '.xml' - ); - } - } } + } $objWriter->endElement(); @@ -389,16 +389,16 @@ public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorks $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - // Loop through images and write relationships - foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) { - // Write relationship for image drawing - $this->_writeRelationship( - $objWriter, - $key, - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', - '../media/' . $value->getIndexedFilename() - ); - } + // Loop through images and write relationships + foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) { + // Write relationship for image drawing + $this->_writeRelationship( + $objWriter, + $key, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', + '../media/' . $value->getIndexedFilename() + ); + } $objWriter->endElement(); @@ -421,12 +421,12 @@ private function _writeRelationship(PHPExcel_Shared_XMLWriter $objWriter = null, if ($pType != '' && $pTarget != '') { // Write relationship $objWriter->startElement('Relationship'); - $objWriter->writeAttribute('Id', 'rId' . $pId); - $objWriter->writeAttribute('Type', $pType); - $objWriter->writeAttribute('Target', $pTarget); + $objWriter->writeAttribute('Id', 'rId' . $pId); + $objWriter->writeAttribute('Type', $pType); + $objWriter->writeAttribute('Target', $pTarget); if ($pTargetMode != '') { - $objWriter->writeAttribute('TargetMode', $pTargetMode); + $objWriter->writeAttribute('TargetMode', $pTargetMode); } $objWriter->endElement(); diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php index 2c1945565..0ab653574 100644 --- a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php +++ b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php @@ -42,7 +42,8 @@ class PHPExcel_Writer_Excel2007_RelsRibbon extends PHPExcel_Writer_Excel2007_Wri * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeRibbonRelationships(PHPExcel $pPHPExcel = null) { + public function writeRibbonRelationships(PHPExcel $pPHPExcel = null) + { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { @@ -57,9 +58,9 @@ public function writeRibbonRelationships(PHPExcel $pPHPExcel = null) { // Relationships $objWriter->startElement('Relationships'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); - $localRels=$pPHPExcel->getRibbonBinObjects('names'); + $localRels = $pPHPExcel->getRibbonBinObjects('names'); if (is_array($localRels)) { - foreach ($localRels as $aId=>$aTarget) { + foreach ($localRels as $aId => $aTarget) { $objWriter->startElement('Relationship'); $objWriter->writeAttribute('Id', $aId); $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); @@ -71,7 +72,5 @@ public function writeRibbonRelationships(PHPExcel $pPHPExcel = null) { // Return return $objWriter->getData(); - } - } diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php index 676c57584..b8e3ed4f6 100644 --- a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php +++ b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php @@ -42,7 +42,8 @@ class PHPExcel_Writer_Excel2007_RelsVBA extends PHPExcel_Writer_Excel2007_Writer * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeVBARelationships(PHPExcel $pPHPExcel = null) { + public function writeVBARelationships(PHPExcel $pPHPExcel = null) + { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { @@ -68,5 +69,4 @@ public function writeVBARelationships(PHPExcel $pPHPExcel = null) { return $objWriter->getData(); } - } diff --git a/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Classes/PHPExcel/Writer/Excel2007/StringTable.php index 361caa635..f2e8a12e6 100644 --- a/Classes/PHPExcel/Writer/Excel2007/StringTable.php +++ b/Classes/PHPExcel/Writer/Excel2007/StringTable.php @@ -45,14 +45,14 @@ class PHPExcel_Writer_Excel2007_StringTable extends PHPExcel_Writer_Excel2007_Wr */ public function createStringTable($pSheet = null, $pExistingTable = null) { - if ($pSheet !== NULL) { + if ($pSheet !== null) { // Create string lookup table $aStringTable = array(); $cellCollection = null; $aFlippedStringTable = null; // For faster lookup // Is an existing table given? - if (($pExistingTable !== NULL) && is_array($pExistingTable)) { + if (($pExistingTable !== null) && is_array($pExistingTable)) { $aStringTable = $pExistingTable; } @@ -64,14 +64,14 @@ public function createStringTable($pSheet = null, $pExistingTable = null) $cell = $pSheet->getCell($cellID); $cellValue = $cell->getValue(); if (!is_object($cellValue) && - ($cellValue !== NULL) && + ($cellValue !== null) && $cellValue !== '' && !isset($aFlippedStringTable[$cellValue]) && ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING2 || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_NULL)) { $aStringTable[] = $cellValue; $aFlippedStringTable[$cellValue] = true; } elseif ($cellValue instanceof PHPExcel_RichText && - ($cellValue !== NULL) && + ($cellValue !== null) && !isset($aFlippedStringTable[$cellValue->getHashCode()])) { $aStringTable[] = $cellValue; $aFlippedStringTable[$cellValue->getHashCode()] = true; @@ -94,7 +94,7 @@ public function createStringTable($pSheet = null, $pExistingTable = null) */ public function writeStringTable($pStringTable = null) { - if ($pStringTable !== NULL) { + if ($pStringTable !== null) { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { @@ -111,25 +111,25 @@ public function writeStringTable($pStringTable = null) $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); $objWriter->writeAttribute('uniqueCount', count($pStringTable)); - // Loop through string table - foreach ($pStringTable as $textElement) { - $objWriter->startElement('si'); - - if (! $textElement instanceof PHPExcel_RichText) { - $textToWrite = PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $textElement ); - $objWriter->startElement('t'); - if ($textToWrite !== trim($textToWrite)) { - $objWriter->writeAttribute('xml:space', 'preserve'); - } - $objWriter->writeRawData($textToWrite); - $objWriter->endElement(); - } else if ($textElement instanceof PHPExcel_RichText) { - $this->writeRichText($objWriter, $textElement); - } + // Loop through string table + foreach ($pStringTable as $textElement) { + $objWriter->startElement('si'); + if (! $textElement instanceof PHPExcel_RichText) { + $textToWrite = PHPExcel_Shared_String::ControlCharacterPHP2OOXML($textElement); + $objWriter->startElement('t'); + if ($textToWrite !== trim($textToWrite)) { + $objWriter->writeAttribute('xml:space', 'preserve'); + } + $objWriter->writeRawData($textToWrite); $objWriter->endElement(); + } else if ($textElement instanceof PHPExcel_RichText) { + $this->writeRichText($objWriter, $textElement); } + $objWriter->endElement(); + } + $objWriter->endElement(); // Return @@ -147,76 +147,78 @@ public function writeStringTable($pStringTable = null) * @param string $prefix Optional Namespace prefix * @throws PHPExcel_Writer_Exception */ - public function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_RichText $pRichText = null, $prefix=NULL) + public function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_RichText $pRichText = null, $prefix = null) { - if ($prefix !== NULL) + if ($prefix !== null) { $prefix .= ':'; + } + // Loop through rich text elements $elements = $pRichText->getRichTextElements(); foreach ($elements as $element) { // r $objWriter->startElement($prefix.'r'); + // rPr + if ($element instanceof PHPExcel_RichText_Run) { // rPr - if ($element instanceof PHPExcel_RichText_Run) { - // rPr - $objWriter->startElement($prefix.'rPr'); - - // rFont - $objWriter->startElement($prefix.'rFont'); - $objWriter->writeAttribute('val', $element->getFont()->getName()); - $objWriter->endElement(); - - // Bold - $objWriter->startElement($prefix.'b'); - $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false')); - $objWriter->endElement(); - - // Italic - $objWriter->startElement($prefix.'i'); - $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false')); - $objWriter->endElement(); - - // Superscript / subscript - if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { - $objWriter->startElement($prefix.'vertAlign'); - if ($element->getFont()->getSuperScript()) { - $objWriter->writeAttribute('val', 'superscript'); - } else if ($element->getFont()->getSubScript()) { - $objWriter->writeAttribute('val', 'subscript'); - } - $objWriter->endElement(); - } - - // Strikethrough - $objWriter->startElement($prefix.'strike'); - $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false')); - $objWriter->endElement(); - - // Color - $objWriter->startElement($prefix.'color'); - $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); - $objWriter->endElement(); - - // Size - $objWriter->startElement($prefix.'sz'); - $objWriter->writeAttribute('val', $element->getFont()->getSize()); - $objWriter->endElement(); - - // Underline - $objWriter->startElement($prefix.'u'); - $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); - $objWriter->endElement(); + $objWriter->startElement($prefix.'rPr'); + + // rFont + $objWriter->startElement($prefix.'rFont'); + $objWriter->writeAttribute('val', $element->getFont()->getName()); + $objWriter->endElement(); + + // Bold + $objWriter->startElement($prefix.'b'); + $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false')); + $objWriter->endElement(); + + // Italic + $objWriter->startElement($prefix.'i'); + $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false')); + $objWriter->endElement(); + // Superscript / subscript + if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { + $objWriter->startElement($prefix.'vertAlign'); + if ($element->getFont()->getSuperScript()) { + $objWriter->writeAttribute('val', 'superscript'); + } else if ($element->getFont()->getSubScript()) { + $objWriter->writeAttribute('val', 'subscript'); + } $objWriter->endElement(); } - // t - $objWriter->startElement($prefix.'t'); - $objWriter->writeAttribute('xml:space', 'preserve'); - $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); + // Strikethrough + $objWriter->startElement($prefix.'strike'); + $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false')); + $objWriter->endElement(); + + // Color + $objWriter->startElement($prefix.'color'); + $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); + $objWriter->endElement(); + + // Size + $objWriter->startElement($prefix.'sz'); + $objWriter->writeAttribute('val', $element->getFont()->getSize()); + $objWriter->endElement(); + + // Underline + $objWriter->startElement($prefix.'u'); + $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); $objWriter->endElement(); + $objWriter->endElement(); + } + + // t + $objWriter->startElement($prefix.'t'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($element->getText())); + $objWriter->endElement(); + $objWriter->endElement(); } } @@ -229,7 +231,7 @@ public function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx * @param string $prefix Optional Namespace prefix * @throws PHPExcel_Writer_Exception */ - public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = null, $pRichText = null, $prefix=NULL) + public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = null, $pRichText = null, $prefix = null) { if (!$pRichText instanceof PHPExcel_RichText) { $textRun = $pRichText; @@ -237,41 +239,43 @@ public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = nu $pRichText->createTextRun($textRun); } - if ($prefix !== NULL) + if ($prefix !== null) { $prefix .= ':'; + } + // Loop through rich text elements $elements = $pRichText->getRichTextElements(); foreach ($elements as $element) { // r $objWriter->startElement($prefix.'r'); - // rPr - $objWriter->startElement($prefix.'rPr'); - - // Bold - $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0)); - // Italic - $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); - // Underline - $underlineType = $element->getFont()->getUnderline(); - switch ($underlineType) { - case 'single' : - $underlineType = 'sng'; - break; - case 'double' : - $underlineType = 'dbl'; - break; - } - $objWriter->writeAttribute('u', $underlineType); - // Strikethrough - $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike')); + // rPr + $objWriter->startElement($prefix.'rPr'); + + // Bold + $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0)); + // Italic + $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); + // Underline + $underlineType = $element->getFont()->getUnderline(); + switch ($underlineType) { + case 'single' : + $underlineType = 'sng'; + break; + case 'double' : + $underlineType = 'dbl'; + break; + } + $objWriter->writeAttribute('u', $underlineType); + // Strikethrough + $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike')); - // rFont - $objWriter->startElement($prefix.'latin'); - $objWriter->writeAttribute('typeface', $element->getFont()->getName()); - $objWriter->endElement(); + // rFont + $objWriter->startElement($prefix.'latin'); + $objWriter->writeAttribute('typeface', $element->getFont()->getName()); + $objWriter->endElement(); - // Superscript / subscript + // Superscript / subscript // if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { // $objWriter->startElement($prefix.'vertAlign'); // if ($element->getFont()->getSuperScript()) { @@ -282,13 +286,13 @@ public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = nu // $objWriter->endElement(); // } // - $objWriter->endElement(); + $objWriter->endElement(); - // t - $objWriter->startElement($prefix.'t'); + // t + $objWriter->startElement($prefix.'t'); // $objWriter->writeAttribute('xml:space', 'preserve'); // Excel2010 accepts, Excel2007 complains - $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); - $objWriter->endElement(); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($element->getText())); + $objWriter->endElement(); $objWriter->endElement(); } diff --git a/Classes/PHPExcel/Writer/Excel2007/Style.php b/Classes/PHPExcel/Writer/Excel2007/Style.php index dcdf82817..d6cf85384 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Style.php +++ b/Classes/PHPExcel/Writer/Excel2007/Style.php @@ -402,7 +402,7 @@ private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, } if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) { - $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164) ); + $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164)); } else { $objWriter->writeAttribute('numFmtId', (int)$pStyle->getNumberFormat()->getBuiltInFormatCode()); } @@ -508,14 +508,14 @@ private function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, if ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT) { $objWriter->startElement('protection'); - if (($pStyle->getProtection()->getLocked() !== null) && - ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { - $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); - } - if (($pStyle->getProtection()->getHidden() !== null) && - ($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { - $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); - } + if (($pStyle->getProtection()->getLocked() !== null) && + ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { + $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + if (($pStyle->getProtection()->getHidden() !== null) && + ($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { + $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } $objWriter->endElement(); } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Theme.php b/Classes/PHPExcel/Writer/Excel2007/Theme.php index 279ecff93..7253afe48 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Theme.php +++ b/Classes/PHPExcel/Writer/Excel2007/Theme.php @@ -138,372 +138,370 @@ class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPa */ public function writeTheme(PHPExcel $pPHPExcel = null) { - // Create XML writer - $objWriter = null; - if ($this->getParentWriter()->getUseDiskCaching()) { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); - } else { - $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); - } - - // XML header - $objWriter->startDocument('1.0', 'UTF-8', 'yes'); - - // a:theme - $objWriter->startElement('a:theme'); - $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); - $objWriter->writeAttribute('name', 'Office Theme'); - - // a:themeElements - $objWriter->startElement('a:themeElements'); - - // a:clrScheme - $objWriter->startElement('a:clrScheme'); - $objWriter->writeAttribute('name', 'Office'); - - // a:dk1 - $objWriter->startElement('a:dk1'); - - // a:sysClr - $objWriter->startElement('a:sysClr'); - $objWriter->writeAttribute('val', 'windowText'); - $objWriter->writeAttribute('lastClr', '000000'); - $objWriter->endElement(); + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } - $objWriter->endElement(); + // XML header + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); - // a:lt1 - $objWriter->startElement('a:lt1'); + // a:theme + $objWriter->startElement('a:theme'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + $objWriter->writeAttribute('name', 'Office Theme'); - // a:sysClr - $objWriter->startElement('a:sysClr'); - $objWriter->writeAttribute('val', 'window'); - $objWriter->writeAttribute('lastClr', 'FFFFFF'); - $objWriter->endElement(); + // a:themeElements + $objWriter->startElement('a:themeElements'); - $objWriter->endElement(); + // a:clrScheme + $objWriter->startElement('a:clrScheme'); + $objWriter->writeAttribute('name', 'Office'); - // a:dk2 - $this->_writeColourScheme($objWriter); + // a:dk1 + $objWriter->startElement('a:dk1'); + + // a:sysClr + $objWriter->startElement('a:sysClr'); + $objWriter->writeAttribute('val', 'windowText'); + $objWriter->writeAttribute('lastClr', '000000'); + $objWriter->endElement(); $objWriter->endElement(); - // a:fontScheme - $objWriter->startElement('a:fontScheme'); - $objWriter->writeAttribute('name', 'Office'); + // a:lt1 + $objWriter->startElement('a:lt1'); - // a:majorFont - $objWriter->startElement('a:majorFont'); - $this->_writeFonts($objWriter, 'Cambria', self::$_majorFonts); + // a:sysClr + $objWriter->startElement('a:sysClr'); + $objWriter->writeAttribute('val', 'window'); + $objWriter->writeAttribute('lastClr', 'FFFFFF'); $objWriter->endElement(); - // a:minorFont - $objWriter->startElement('a:minorFont'); - $this->_writeFonts($objWriter, 'Calibri', self::$_minorFonts); - $objWriter->endElement(); + $objWriter->endElement(); + // a:dk2 + $this->_writeColourScheme($objWriter); + + $objWriter->endElement(); + + // a:fontScheme + $objWriter->startElement('a:fontScheme'); + $objWriter->writeAttribute('name', 'Office'); + + // a:majorFont + $objWriter->startElement('a:majorFont'); + $this->_writeFonts($objWriter, 'Cambria', self::$_majorFonts); $objWriter->endElement(); - // a:fmtScheme - $objWriter->startElement('a:fmtScheme'); - $objWriter->writeAttribute('name', 'Office'); + // a:minorFont + $objWriter->startElement('a:minorFont'); + $this->_writeFonts($objWriter, 'Calibri', self::$_minorFonts); + $objWriter->endElement(); - // a:fillStyleLst - $objWriter->startElement('a:fillStyleLst'); + $objWriter->endElement(); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:fmtScheme + $objWriter->startElement('a:fmtScheme'); + $objWriter->writeAttribute('name', 'Office'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); - $objWriter->endElement(); + // a:fillStyleLst + $objWriter->startElement('a:fillStyleLst'); + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); $objWriter->endElement(); - // a:gradFill - $objWriter->startElement('a:gradFill'); - $objWriter->writeAttribute('rotWithShape', '1'); + $objWriter->endElement(); - // a:gsLst - $objWriter->startElement('a:gsLst'); + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '0'); + // a:gsLst + $objWriter->startElement('a:gsLst'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '50000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '300000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '50000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); $objWriter->endElement(); $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '35000'); + $objWriter->endElement(); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '35000'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '37000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '300000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '37000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); $objWriter->endElement(); $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '100000'); + $objWriter->endElement(); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '15000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '350000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '15000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); - // a:lin - $objWriter->startElement('a:lin'); - $objWriter->writeAttribute('ang', '16200000'); - $objWriter->writeAttribute('scaled', '1'); - $objWriter->endElement(); + $objWriter->endElement(); + // a:lin + $objWriter->startElement('a:lin'); + $objWriter->writeAttribute('ang', '16200000'); + $objWriter->writeAttribute('scaled', '1'); $objWriter->endElement(); - // a:gradFill - $objWriter->startElement('a:gradFill'); - $objWriter->writeAttribute('rotWithShape', '1'); + $objWriter->endElement(); - // a:gsLst - $objWriter->startElement('a:gsLst'); + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '0'); + // a:gsLst + $objWriter->startElement('a:gsLst'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '51000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '130000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '51000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '130000'); $objWriter->endElement(); $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '80000'); + $objWriter->endElement(); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '80000'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '93000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '130000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '93000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '130000'); $objWriter->endElement(); $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '100000'); + $objWriter->endElement(); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '94000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '135000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '94000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '135000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); - // a:lin - $objWriter->startElement('a:lin'); - $objWriter->writeAttribute('ang', '16200000'); - $objWriter->writeAttribute('scaled', '0'); - $objWriter->endElement(); + $objWriter->endElement(); + // a:lin + $objWriter->startElement('a:lin'); + $objWriter->writeAttribute('ang', '16200000'); + $objWriter->writeAttribute('scaled', '0'); $objWriter->endElement(); $objWriter->endElement(); - // a:lnStyleLst - $objWriter->startElement('a:lnStyleLst'); + $objWriter->endElement(); - // a:ln - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', '9525'); - $objWriter->writeAttribute('cap', 'flat'); - $objWriter->writeAttribute('cmpd', 'sng'); - $objWriter->writeAttribute('algn', 'ctr'); + // a:lnStyleLst + $objWriter->startElement('a:lnStyleLst'); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '9525'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:solidFill + $objWriter->startElement('a:solidFill'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '95000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '105000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '95000'); + $objWriter->endElement(); - $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '105000'); + $objWriter->endElement(); $objWriter->endElement(); - // a:prstDash - $objWriter->startElement('a:prstDash'); - $objWriter->writeAttribute('val', 'solid'); - $objWriter->endElement(); + $objWriter->endElement(); + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); $objWriter->endElement(); - // a:ln - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', '25400'); - $objWriter->writeAttribute('cap', 'flat'); - $objWriter->writeAttribute('cmpd', 'sng'); - $objWriter->writeAttribute('algn', 'ctr'); + $objWriter->endElement(); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '25400'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); - $objWriter->endElement(); + // a:solidFill + $objWriter->startElement('a:solidFill'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); $objWriter->endElement(); - // a:prstDash - $objWriter->startElement('a:prstDash'); - $objWriter->writeAttribute('val', 'solid'); - $objWriter->endElement(); + $objWriter->endElement(); + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); $objWriter->endElement(); - // a:ln - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', '38100'); - $objWriter->writeAttribute('cap', 'flat'); - $objWriter->writeAttribute('cmpd', 'sng'); - $objWriter->writeAttribute('algn', 'ctr'); + $objWriter->endElement(); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '38100'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); - $objWriter->endElement(); + // a:solidFill + $objWriter->startElement('a:solidFill'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); $objWriter->endElement(); - // a:prstDash - $objWriter->startElement('a:prstDash'); - $objWriter->writeAttribute('val', 'solid'); - $objWriter->endElement(); + $objWriter->endElement(); + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); $objWriter->endElement(); $objWriter->endElement(); + $objWriter->endElement(); - // a:effectStyleLst - $objWriter->startElement('a:effectStyleLst'); - // a:effectStyle - $objWriter->startElement('a:effectStyle'); + // a:effectStyleLst + $objWriter->startElement('a:effectStyleLst'); - // a:effectLst - $objWriter->startElement('a:effectLst'); + // a:effectStyle + $objWriter->startElement('a:effectStyle'); - // a:outerShdw - $objWriter->startElement('a:outerShdw'); - $objWriter->writeAttribute('blurRad', '40000'); - $objWriter->writeAttribute('dist', '20000'); - $objWriter->writeAttribute('dir', '5400000'); - $objWriter->writeAttribute('rotWithShape', '0'); + // a:effectLst + $objWriter->startElement('a:effectLst'); - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', '000000'); + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '20000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); - // a:alpha - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', '38000'); - $objWriter->endElement(); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '38000'); $objWriter->endElement(); $objWriter->endElement(); @@ -512,28 +510,28 @@ public function writeTheme(PHPExcel $pPHPExcel = null) $objWriter->endElement(); - // a:effectStyle - $objWriter->startElement('a:effectStyle'); + $objWriter->endElement(); - // a:effectLst - $objWriter->startElement('a:effectLst'); + // a:effectStyle + $objWriter->startElement('a:effectStyle'); - // a:outerShdw - $objWriter->startElement('a:outerShdw'); - $objWriter->writeAttribute('blurRad', '40000'); - $objWriter->writeAttribute('dist', '23000'); - $objWriter->writeAttribute('dir', '5400000'); - $objWriter->writeAttribute('rotWithShape', '0'); + // a:effectLst + $objWriter->startElement('a:effectLst'); - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', '000000'); + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '23000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); - // a:alpha - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', '35000'); - $objWriter->endElement(); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '35000'); $objWriter->endElement(); $objWriter->endElement(); @@ -542,255 +540,255 @@ public function writeTheme(PHPExcel $pPHPExcel = null) $objWriter->endElement(); - // a:effectStyle - $objWriter->startElement('a:effectStyle'); + $objWriter->endElement(); - // a:effectLst - $objWriter->startElement('a:effectLst'); + // a:effectStyle + $objWriter->startElement('a:effectStyle'); - // a:outerShdw - $objWriter->startElement('a:outerShdw'); - $objWriter->writeAttribute('blurRad', '40000'); - $objWriter->writeAttribute('dist', '23000'); - $objWriter->writeAttribute('dir', '5400000'); - $objWriter->writeAttribute('rotWithShape', '0'); + // a:effectLst + $objWriter->startElement('a:effectLst'); - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', '000000'); + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '23000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); - // a:alpha - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', '35000'); - $objWriter->endElement(); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '35000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); - // a:scene3d - $objWriter->startElement('a:scene3d'); + $objWriter->endElement(); - // a:camera - $objWriter->startElement('a:camera'); - $objWriter->writeAttribute('prst', 'orthographicFront'); + // a:scene3d + $objWriter->startElement('a:scene3d'); - // a:rot - $objWriter->startElement('a:rot'); - $objWriter->writeAttribute('lat', '0'); - $objWriter->writeAttribute('lon', '0'); - $objWriter->writeAttribute('rev', '0'); - $objWriter->endElement(); + // a:camera + $objWriter->startElement('a:camera'); + $objWriter->writeAttribute('prst', 'orthographicFront'); + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '0'); $objWriter->endElement(); - // a:lightRig - $objWriter->startElement('a:lightRig'); - $objWriter->writeAttribute('rig', 'threePt'); - $objWriter->writeAttribute('dir', 't'); + $objWriter->endElement(); - // a:rot - $objWriter->startElement('a:rot'); - $objWriter->writeAttribute('lat', '0'); - $objWriter->writeAttribute('lon', '0'); - $objWriter->writeAttribute('rev', '1200000'); - $objWriter->endElement(); + // a:lightRig + $objWriter->startElement('a:lightRig'); + $objWriter->writeAttribute('rig', 'threePt'); + $objWriter->writeAttribute('dir', 't'); + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '1200000'); $objWriter->endElement(); $objWriter->endElement(); - // a:sp3d - $objWriter->startElement('a:sp3d'); + $objWriter->endElement(); - // a:bevelT - $objWriter->startElement('a:bevelT'); - $objWriter->writeAttribute('w', '63500'); - $objWriter->writeAttribute('h', '25400'); - $objWriter->endElement(); + // a:sp3d + $objWriter->startElement('a:sp3d'); + // a:bevelT + $objWriter->startElement('a:bevelT'); + $objWriter->writeAttribute('w', '63500'); + $objWriter->writeAttribute('h', '25400'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); - // a:bgFillStyleLst - $objWriter->startElement('a:bgFillStyleLst'); + $objWriter->endElement(); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:bgFillStyleLst + $objWriter->startElement('a:bgFillStyleLst'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); - $objWriter->endElement(); + // a:solidFill + $objWriter->startElement('a:solidFill'); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); $objWriter->endElement(); - // a:gradFill - $objWriter->startElement('a:gradFill'); - $objWriter->writeAttribute('rotWithShape', '1'); + $objWriter->endElement(); - // a:gsLst - $objWriter->startElement('a:gsLst'); + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '0'); + // a:gsLst + $objWriter->startElement('a:gsLst'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '40000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '350000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '40000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); $objWriter->endElement(); $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '40000'); + $objWriter->endElement(); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '40000'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '45000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '99000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '45000'); + $objWriter->endElement(); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '350000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '99000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); $objWriter->endElement(); $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '100000'); + $objWriter->endElement(); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '20000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '255000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '20000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '255000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); - // a:path - $objWriter->startElement('a:path'); - $objWriter->writeAttribute('path', 'circle'); + $objWriter->endElement(); - // a:fillToRect - $objWriter->startElement('a:fillToRect'); - $objWriter->writeAttribute('l', '50000'); - $objWriter->writeAttribute('t', '-80000'); - $objWriter->writeAttribute('r', '50000'); - $objWriter->writeAttribute('b', '180000'); - $objWriter->endElement(); + // a:path + $objWriter->startElement('a:path'); + $objWriter->writeAttribute('path', 'circle'); + // a:fillToRect + $objWriter->startElement('a:fillToRect'); + $objWriter->writeAttribute('l', '50000'); + $objWriter->writeAttribute('t', '-80000'); + $objWriter->writeAttribute('r', '50000'); + $objWriter->writeAttribute('b', '180000'); $objWriter->endElement(); $objWriter->endElement(); - // a:gradFill - $objWriter->startElement('a:gradFill'); - $objWriter->writeAttribute('rotWithShape', '1'); + $objWriter->endElement(); - // a:gsLst - $objWriter->startElement('a:gsLst'); + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '0'); + // a:gsLst + $objWriter->startElement('a:gsLst'); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); - // a:tint - $objWriter->startElement('a:tint'); - $objWriter->writeAttribute('val', '80000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '300000'); - $objWriter->endElement(); + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '80000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); $objWriter->endElement(); $objWriter->endElement(); - // a:gs - $objWriter->startElement('a:gs'); - $objWriter->writeAttribute('pos', '100000'); + $objWriter->endElement(); - // a:schemeClr - $objWriter->startElement('a:schemeClr'); - $objWriter->writeAttribute('val', 'phClr'); + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); - // a:shade - $objWriter->startElement('a:shade'); - $objWriter->writeAttribute('val', '30000'); - $objWriter->endElement(); + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); - // a:satMod - $objWriter->startElement('a:satMod'); - $objWriter->writeAttribute('val', '200000'); - $objWriter->endElement(); + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '30000'); + $objWriter->endElement(); + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '200000'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); - // a:path - $objWriter->startElement('a:path'); - $objWriter->writeAttribute('path', 'circle'); + $objWriter->endElement(); - // a:fillToRect - $objWriter->startElement('a:fillToRect'); - $objWriter->writeAttribute('l', '50000'); - $objWriter->writeAttribute('t', '50000'); - $objWriter->writeAttribute('r', '50000'); - $objWriter->writeAttribute('b', '50000'); - $objWriter->endElement(); + // a:path + $objWriter->startElement('a:path'); + $objWriter->writeAttribute('path', 'circle'); + // a:fillToRect + $objWriter->startElement('a:fillToRect'); + $objWriter->writeAttribute('l', '50000'); + $objWriter->writeAttribute('t', '50000'); + $objWriter->writeAttribute('r', '50000'); + $objWriter->writeAttribute('b', '50000'); $objWriter->endElement(); $objWriter->endElement(); @@ -801,16 +799,18 @@ public function writeTheme(PHPExcel $pPHPExcel = null) $objWriter->endElement(); - // a:objectDefaults - $objWriter->writeElement('a:objectDefaults', null); + $objWriter->endElement(); - // a:extraClrSchemeLst - $objWriter->writeElement('a:extraClrSchemeLst', null); + // a:objectDefaults + $objWriter->writeElement('a:objectDefaults', null); - $objWriter->endElement(); + // a:extraClrSchemeLst + $objWriter->writeElement('a:extraClrSchemeLst', null); + + $objWriter->endElement(); - // Return - return $objWriter->getData(); + // Return + return $objWriter->getData(); } /** diff --git a/Classes/PHPExcel/Writer/Excel2007/Workbook.php b/Classes/PHPExcel/Writer/Excel2007/Workbook.php index 1162501f7..40c1cf4f7 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel2007/Workbook.php @@ -362,7 +362,7 @@ private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWr $range = PHPExcel_Cell::splitRange($autoFilterRange); $range = $range[0]; // Strip any worksheet ref so we can make the cell ref absolute - if (strpos($range[0],'!') !== false) { + if (strpos($range[0], '!') !== false) { list($ws, $range[0]) = explode('!', $range[0]); } diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index 899a54bf2..b1e7c1bd6 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -44,7 +44,7 @@ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_Writ * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeWorksheet($pSheet = null, $pStringTable = null, $includeCharts = FALSE) + public function writeWorksheet($pSheet = null, $pStringTable = null, $includeCharts = false) { if (!is_null($pSheet)) { // Create XML writer @@ -152,33 +152,33 @@ private function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPE if ($pSheet->hasCodeName()==false) { $pSheet->setCodeName($pSheet->getTitle()); } - $objWriter->writeAttribute('codeName', $pSheet->getCodeName()); + $objWriter->writeAttribute('codeName', $pSheet->getCodeName()); + } + $autoFilterRange = $pSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + $objWriter->writeAttribute('filterMode', 1); + $pSheet->getAutoFilter()->showHideRows(); } - $autoFilterRange = $pSheet->getAutoFilter()->getRange(); - if (!empty($autoFilterRange)) { - $objWriter->writeAttribute('filterMode', 1); - $pSheet->getAutoFilter()->showHideRows(); - } - - // tabColor - if ($pSheet->isTabColorSet()) { - $objWriter->startElement('tabColor'); - $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB()); - $objWriter->endElement(); - } - // outlinePr - $objWriter->startElement('outlinePr'); - $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0')); - $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0')); + // tabColor + if ($pSheet->isTabColorSet()) { + $objWriter->startElement('tabColor'); + $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB()); $objWriter->endElement(); + } - // pageSetUpPr - if ($pSheet->getPageSetup()->getFitToPage()) { - $objWriter->startElement('pageSetUpPr'); - $objWriter->writeAttribute('fitToPage', '1'); - $objWriter->endElement(); - } + // outlinePr + $objWriter->startElement('outlinePr'); + $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0')); + $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0')); + $objWriter->endElement(); + + // pageSetUpPr + if ($pSheet->getPageSetup()->getFitToPage()) { + $objWriter->startElement('pageSetUpPr'); + $objWriter->writeAttribute('fitToPage', '1'); + $objWriter->endElement(); + } $objWriter->endElement(); } @@ -205,28 +205,28 @@ private function _writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PH * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = NULL, PHPExcel_Worksheet $pSheet = NULL) + private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // sheetViews $objWriter->startElement('sheetViews'); // Sheet selected? $sheetSelected = false; - if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex()) + if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex()) { $sheetSelected = true; - + } // sheetView $objWriter->startElement('sheetView'); - $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0'); - $objWriter->writeAttribute('workbookViewId', '0'); + $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0'); + $objWriter->writeAttribute('workbookViewId', '0'); // Zoom scales if ($pSheet->getSheetView()->getZoomScale() != 100) { - $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale()); + $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale()); } if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) { - $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal()); + $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal()); } // View Layout Type @@ -236,9 +236,9 @@ private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = NULL, P // Gridlines if ($pSheet->getShowGridlines()) { - $objWriter->writeAttribute('showGridLines', 'true'); + $objWriter->writeAttribute('showGridLines', 'true'); } else { - $objWriter->writeAttribute('showGridLines', 'false'); + $objWriter->writeAttribute('showGridLines', 'false'); } // Row and column headers @@ -250,7 +250,7 @@ private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = NULL, P // Right-to-left if ($pSheet->getRightToLeft()) { - $objWriter->writeAttribute('rightToLeft', 'true'); + $objWriter->writeAttribute('rightToLeft', 'true'); } $activeCell = $pSheet->getActiveCell(); @@ -270,20 +270,24 @@ private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = NULL, P $pane = 'topRight'; $objWriter->startElement('pane'); if ($xSplit > 1) - $objWriter->writeAttribute('xSplit', $xSplit - 1); + $objWriter->writeAttribute('xSplit', $xSplit - 1); if ($ySplit > 1) { - $objWriter->writeAttribute('ySplit', $ySplit - 1); + $objWriter->writeAttribute('ySplit', $ySplit - 1); $pane = ($xSplit > 1) ? 'bottomRight' : 'bottomLeft'; } - $objWriter->writeAttribute('topLeftCell', $topLeftCell); - $objWriter->writeAttribute('activePane', $pane); - $objWriter->writeAttribute('state', 'frozen'); + $objWriter->writeAttribute('topLeftCell', $topLeftCell); + $objWriter->writeAttribute('activePane', $pane); + $objWriter->writeAttribute('state', 'frozen'); $objWriter->endElement(); if (($xSplit > 1) && ($ySplit > 1)) { // Write additional selections if more than two panes (ie both an X and a Y split) - $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'topRight'); $objWriter->endElement(); - $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'bottomLeft'); $objWriter->endElement(); + $objWriter->startElement('selection'); + $objWriter->writeAttribute('pane', 'topRight'); + $objWriter->endElement(); + $objWriter->startElement('selection'); + $objWriter->writeAttribute('pane', 'bottomLeft'); + $objWriter->endElement(); } } @@ -317,42 +321,42 @@ private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null // sheetFormatPr $objWriter->startElement('sheetFormatPr'); - // Default row height - if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) { - $objWriter->writeAttribute('customHeight', 'true'); - $objWriter->writeAttribute('defaultRowHeight', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultRowDimension()->getRowHeight())); - } else { - $objWriter->writeAttribute('defaultRowHeight', '14.4'); - } + // Default row height + if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) { + $objWriter->writeAttribute('customHeight', 'true'); + $objWriter->writeAttribute('defaultRowHeight', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultRowDimension()->getRowHeight())); + } else { + $objWriter->writeAttribute('defaultRowHeight', '14.4'); + } - // Set Zero Height row - if ((string)$pSheet->getDefaultRowDimension()->getZeroHeight() == '1' || - strtolower((string)$pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true' ) { - $objWriter->writeAttribute('zeroHeight', '1'); - } + // Set Zero Height row + if ((string)$pSheet->getDefaultRowDimension()->getZeroHeight() == '1' || + strtolower((string)$pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true') { + $objWriter->writeAttribute('zeroHeight', '1'); + } - // Default column width - if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) { - $objWriter->writeAttribute('defaultColWidth', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultColumnDimension()->getWidth())); - } + // Default column width + if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) { + $objWriter->writeAttribute('defaultColWidth', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultColumnDimension()->getWidth())); + } - // Outline level - row - $outlineLevelRow = 0; - foreach ($pSheet->getRowDimensions() as $dimension) { - if ($dimension->getOutlineLevel() > $outlineLevelRow) { - $outlineLevelRow = $dimension->getOutlineLevel(); - } + // Outline level - row + $outlineLevelRow = 0; + foreach ($pSheet->getRowDimensions() as $dimension) { + if ($dimension->getOutlineLevel() > $outlineLevelRow) { + $outlineLevelRow = $dimension->getOutlineLevel(); } - $objWriter->writeAttribute('outlineLevelRow', (int)$outlineLevelRow); + } + $objWriter->writeAttribute('outlineLevelRow', (int)$outlineLevelRow); - // Outline level - column - $outlineLevelCol = 0; - foreach ($pSheet->getColumnDimensions() as $dimension) { - if ($dimension->getOutlineLevel() > $outlineLevelCol) { - $outlineLevelCol = $dimension->getOutlineLevel(); - } + // Outline level - column + $outlineLevelCol = 0; + foreach ($pSheet->getColumnDimensions() as $dimension) { + if ($dimension->getOutlineLevel() > $outlineLevelCol) { + $outlineLevelCol = $dimension->getOutlineLevel(); } - $objWriter->writeAttribute('outlineLevelCol', (int)$outlineLevelCol); + } + $objWriter->writeAttribute('outlineLevelCol', (int)$outlineLevelCol); $objWriter->endElement(); } @@ -360,8 +364,8 @@ private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null /** * Write Cols * - * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * @param PHPExcel_Worksheet $pSheet Worksheet + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ private function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) @@ -370,54 +374,54 @@ private function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce if (count($pSheet->getColumnDimensions()) > 0) { $objWriter->startElement('cols'); - $pSheet->calculateColumnWidths(); - - // Loop through column dimensions - foreach ($pSheet->getColumnDimensions() as $colDimension) { - // col - $objWriter->startElement('col'); - $objWriter->writeAttribute('min', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); - $objWriter->writeAttribute('max', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); - - if ($colDimension->getWidth() < 0) { - // No width set, apply default of 10 - $objWriter->writeAttribute('width', '9.10'); - } else { - // Width set - $objWriter->writeAttribute('width', PHPExcel_Shared_String::FormatNumber($colDimension->getWidth())); - } + $pSheet->calculateColumnWidths(); - // Column visibility - if ($colDimension->getVisible() == false) { - $objWriter->writeAttribute('hidden', 'true'); - } + // Loop through column dimensions + foreach ($pSheet->getColumnDimensions() as $colDimension) { + // col + $objWriter->startElement('col'); + $objWriter->writeAttribute('min', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); + $objWriter->writeAttribute('max', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); - // Auto size? - if ($colDimension->getAutoSize()) { - $objWriter->writeAttribute('bestFit', 'true'); - } + if ($colDimension->getWidth() < 0) { + // No width set, apply default of 10 + $objWriter->writeAttribute('width', '9.10'); + } else { + // Width set + $objWriter->writeAttribute('width', PHPExcel_Shared_String::FormatNumber($colDimension->getWidth())); + } - // Custom width? - if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) { - $objWriter->writeAttribute('customWidth', 'true'); - } + // Column visibility + if ($colDimension->getVisible() == false) { + $objWriter->writeAttribute('hidden', 'true'); + } - // Collapsed - if ($colDimension->getCollapsed() == true) { - $objWriter->writeAttribute('collapsed', 'true'); - } + // Auto size? + if ($colDimension->getAutoSize()) { + $objWriter->writeAttribute('bestFit', 'true'); + } - // Outline level - if ($colDimension->getOutlineLevel() > 0) { - $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel()); - } + // Custom width? + if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) { + $objWriter->writeAttribute('customWidth', 'true'); + } - // Style - $objWriter->writeAttribute('style', $colDimension->getXfIndex()); + // Collapsed + if ($colDimension->getCollapsed() == true) { + $objWriter->writeAttribute('collapsed', 'true'); + } - $objWriter->endElement(); + // Outline level + if ($colDimension->getOutlineLevel() > 0) { + $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel()); } + // Style + $objWriter->writeAttribute('style', $colDimension->getXfIndex()); + + $objWriter->endElement(); + } + $objWriter->endElement(); } } @@ -435,25 +439,25 @@ private function _writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = nu $objWriter->startElement('sheetProtection'); if ($pSheet->getProtection()->getPassword() != '') { - $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword()); + $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword()); } - $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false')); - $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false')); - $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false')); - $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false')); - $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false')); - $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false')); - $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false')); - $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false')); - $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false')); - $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false')); - $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false')); - $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false')); - $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false')); - $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false')); - $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false')); - $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false')); + $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false')); + $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false')); + $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false')); + $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false')); + $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false')); + $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false')); + $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false')); + $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false')); + $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false')); + $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false')); + $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false')); + $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false')); + $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false')); $objWriter->endElement(); } @@ -473,54 +477,54 @@ private function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWrite foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { foreach ($conditionalStyles as $conditional) { // WHY was this again? - // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() ) == '') { + // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) == '') { // continue; // } if ($conditional->getConditionType() != PHPExcel_Style_Conditional::CONDITION_NONE) { // conditionalFormatting $objWriter->startElement('conditionalFormatting'); - $objWriter->writeAttribute('sqref', $cellCoordinate); + $objWriter->writeAttribute('sqref', $cellCoordinate); // cfRule $objWriter->startElement('cfRule'); - $objWriter->writeAttribute('type', $conditional->getConditionType()); - $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() )); - $objWriter->writeAttribute('priority', $id++); + $objWriter->writeAttribute('type', $conditional->getConditionType()); + $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode())); + $objWriter->writeAttribute('priority', $id++); if (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT) && $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) { - $objWriter->writeAttribute('operator', $conditional->getOperatorType()); + $objWriter->writeAttribute('operator', $conditional->getOperatorType()); } if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && !is_null($conditional->getText())) { - $objWriter->writeAttribute('text', $conditional->getText()); + $objWriter->writeAttribute('text', $conditional->getText()); } if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))'); + $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))'); } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); + $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); + $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))'); + $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))'); } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { foreach ($conditional->getConditions() as $formula) { // Formula - $objWriter->writeElement('formula', $formula); + $objWriter->writeElement('formula', $formula); } } @@ -564,10 +568,10 @@ private function _writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = nu $objWriter->writeAttribute('operator', $dv->getOperator()); } - $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0')); - $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0')); - $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0')); - $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0')); + $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0')); + $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0')); + $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0')); + $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0')); if ($dv->getErrorTitle() !== '') { $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle()); @@ -622,10 +626,10 @@ private function _writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, P $objWriter->writeAttribute('ref', $coordinate); if (!$hyperlink->isInternal()) { - $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId); + $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId); ++$relationId; } else { - $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl())); + $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl())); } if ($hyperlink->getTooltip() != '') { @@ -656,8 +660,8 @@ private function _writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = nu foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) { // protectedRange $objWriter->startElement('protectedRange'); - $objWriter->writeAttribute('name', 'p' . md5($protectedCell)); - $objWriter->writeAttribute('sqref', $protectedCell); + $objWriter->writeAttribute('name', 'p' . md5($protectedCell)); + $objWriter->writeAttribute('sqref', $protectedCell); if (!empty($passwordHash)) { $objWriter->writeAttribute('password', $passwordHash); } @@ -705,8 +709,8 @@ private function _writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, // printOptions $objWriter->startElement('printOptions'); - $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true': 'false')); - $objWriter->writeAttribute('gridLinesSet', 'true'); + $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true': 'false')); + $objWriter->writeAttribute('gridLinesSet', 'true'); if ($pSheet->getPageSetup()->getHorizontalCentered()) { $objWriter->writeAttribute('horizontalCentered', 'true'); @@ -730,12 +734,12 @@ private function _writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, { // pageMargins $objWriter->startElement('pageMargins'); - $objWriter->writeAttribute('left', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft())); - $objWriter->writeAttribute('right', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight())); - $objWriter->writeAttribute('top', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop())); - $objWriter->writeAttribute('bottom', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom())); - $objWriter->writeAttribute('header', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getHeader())); - $objWriter->writeAttribute('footer', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getFooter())); + $objWriter->writeAttribute('left', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft())); + $objWriter->writeAttribute('right', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight())); + $objWriter->writeAttribute('top', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop())); + $objWriter->writeAttribute('bottom', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom())); + $objWriter->writeAttribute('header', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getHeader())); + $objWriter->writeAttribute('footer', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getFooter())); $objWriter->endElement(); } @@ -762,7 +766,7 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P } $range = implode(':', $range); - $objWriter->writeAttribute('ref', str_replace('$','', $range)); + $objWriter->writeAttribute('ref', str_replace('$','', $range)); $columns = $pSheet->getAutoFilter()->getColumns(); if (count($columns > 0)) { @@ -770,11 +774,11 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P $rules = $column->getRules(); if (count($rules > 0)) { $objWriter->startElement('filterColumn'); - $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID)); + $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID)); - $objWriter->startElement( $column->getFilterType()); + $objWriter->startElement($column->getFilterType()); if ($column->getJoin() == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND) { - $objWriter->writeAttribute('and', 1); + $objWriter->writeAttribute('and', 1); } foreach ($rules as $rule) { @@ -787,33 +791,33 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P // Dynamic Filter Rule $objWriter->writeAttribute('type', $rule->getGrouping()); $val = $column->getAttribute('val'); - if ($val !== NULL) { + if ($val !== null) { $objWriter->writeAttribute('val', $val); } $maxVal = $column->getAttribute('maxVal'); - if ($maxVal !== NULL) { + if ($maxVal !== null) { $objWriter->writeAttribute('maxVal', $maxVal); } } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { // Top 10 Filter Rule - $objWriter->writeAttribute('val', $rule->getValue()); - $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); - $objWriter->writeAttribute('top', (($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0')); + $objWriter->writeAttribute('val', $rule->getValue()); + $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); + $objWriter->writeAttribute('top', (($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0')); } else { // Filter, DateGroupItem or CustomFilter $objWriter->startElement($rule->getRuleType()); if ($rule->getOperator() !== PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) { - $objWriter->writeAttribute('operator', $rule->getOperator()); + $objWriter->writeAttribute('operator', $rule->getOperator()); } if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { // Date Group filters foreach ($rule->getValue() as $key => $value) { - if ($value > '') $objWriter->writeAttribute($key, $value); + if ($value > '') $objWriter->writeAttribute($key, $value); } - $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); + $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); } else { - $objWriter->writeAttribute('val', $rule->getValue()); + $objWriter->writeAttribute('val', $rule->getValue()); } $objWriter->endElement(); @@ -842,24 +846,24 @@ private function _writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PH { // pageSetup $objWriter->startElement('pageSetup'); - $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize()); - $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation()); + $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize()); + $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation()); if (!is_null($pSheet->getPageSetup()->getScale())) { - $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale()); + $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale()); } if (!is_null($pSheet->getPageSetup()->getFitToHeight())) { - $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight()); + $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight()); } else { - $objWriter->writeAttribute('fitToHeight', '0'); + $objWriter->writeAttribute('fitToHeight', '0'); } if (!is_null($pSheet->getPageSetup()->getFitToWidth())) { - $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth()); + $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth()); } else { - $objWriter->writeAttribute('fitToWidth', '0'); + $objWriter->writeAttribute('fitToWidth', '0'); } if (!is_null($pSheet->getPageSetup()->getFirstPageNumber())) { - $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber()); + $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber()); $objWriter->writeAttribute('useFirstPageNumber', '1'); } @@ -877,17 +881,17 @@ private function _writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, { // headerFooter $objWriter->startElement('headerFooter'); - $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false')); - $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false')); - $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false')); - $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false')); - - $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader()); - $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter()); - $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader()); - $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter()); - $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader()); - $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter()); + $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false')); + $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false')); + $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false')); + $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false')); + + $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader()); + $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter()); + $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader()); + $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter()); + $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader()); + $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter()); $objWriter->endElement(); } @@ -914,15 +918,15 @@ private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx // rowBreaks if (!empty($aRowBreaks)) { $objWriter->startElement('rowBreaks'); - $objWriter->writeAttribute('count', count($aRowBreaks)); - $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks)); + $objWriter->writeAttribute('count', count($aRowBreaks)); + $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks)); foreach ($aRowBreaks as $cell) { $coords = PHPExcel_Cell::coordinateFromString($cell); $objWriter->startElement('brk'); - $objWriter->writeAttribute('id', $coords[1]); - $objWriter->writeAttribute('man', '1'); + $objWriter->writeAttribute('id', $coords[1]); + $objWriter->writeAttribute('man', '1'); $objWriter->endElement(); } @@ -932,15 +936,15 @@ private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx // Second, write column breaks if (!empty($aColumnBreaks)) { $objWriter->startElement('colBreaks'); - $objWriter->writeAttribute('count', count($aColumnBreaks)); - $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks)); + $objWriter->writeAttribute('count', count($aColumnBreaks)); + $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks)); foreach ($aColumnBreaks as $cell) { $coords = PHPExcel_Cell::coordinateFromString($cell); $objWriter->startElement('brk'); - $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1); - $objWriter->writeAttribute('man', '1'); + $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1); + $objWriter->writeAttribute('man', '1'); $objWriter->endElement(); } @@ -965,77 +969,72 @@ private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PH // sheetData $objWriter->startElement('sheetData'); - // Get column count - $colCount = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()); + // Get column count + $colCount = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()); - // Highest row number - $highestRow = $pSheet->getHighestRow(); + // Highest row number + $highestRow = $pSheet->getHighestRow(); - // Loop through cells - $cellsByRow = array(); - foreach ($pSheet->getCellCollection() as $cellID) { - $cellAddress = PHPExcel_Cell::coordinateFromString($cellID); - $cellsByRow[$cellAddress[1]][] = $cellID; - } + // Loop through cells + $cellsByRow = array(); + foreach ($pSheet->getCellCollection() as $cellID) { + $cellAddress = PHPExcel_Cell::coordinateFromString($cellID); + $cellsByRow[$cellAddress[1]][] = $cellID; + } - $currentRow = 0; - while ($currentRow++ < $highestRow) { - // Get row dimension - $rowDimension = $pSheet->getRowDimension($currentRow); - - // Write current row? - $writeCurrentRow = isset($cellsByRow[$currentRow]) || - $rowDimension->getRowHeight() >= 0 || - $rowDimension->getVisible() == false || - $rowDimension->getCollapsed() == true || - $rowDimension->getOutlineLevel() > 0 || - $rowDimension->getXfIndex() !== null; - - if ($writeCurrentRow) { - // Start a new row - $objWriter->startElement('row'); - $objWriter->writeAttribute('r', $currentRow); - $objWriter->writeAttribute('spans', '1:' . $colCount); - - // Row dimensions - if ($rowDimension->getRowHeight() >= 0) { - $objWriter->writeAttribute('customHeight', '1'); - $objWriter->writeAttribute('ht', PHPExcel_Shared_String::FormatNumber($rowDimension->getRowHeight())); - } + $currentRow = 0; + while ($currentRow++ < $highestRow) { + // Get row dimension + $rowDimension = $pSheet->getRowDimension($currentRow); - // Row visibility - if ($rowDimension->getVisible() == false) { - $objWriter->writeAttribute('hidden', 'true'); - } + // Write current row? + $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() == false || $rowDimension->getCollapsed() == true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null; - // Collapsed - if ($rowDimension->getCollapsed() == true) { - $objWriter->writeAttribute('collapsed', 'true'); - } + if ($writeCurrentRow) { + // Start a new row + $objWriter->startElement('row'); + $objWriter->writeAttribute('r', $currentRow); + $objWriter->writeAttribute('spans', '1:' . $colCount); - // Outline level - if ($rowDimension->getOutlineLevel() > 0) { - $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel()); - } + // Row dimensions + if ($rowDimension->getRowHeight() >= 0) { + $objWriter->writeAttribute('customHeight', '1'); + $objWriter->writeAttribute('ht', PHPExcel_Shared_String::FormatNumber($rowDimension->getRowHeight())); + } - // Style - if ($rowDimension->getXfIndex() !== null) { - $objWriter->writeAttribute('s', $rowDimension->getXfIndex()); - $objWriter->writeAttribute('customFormat', '1'); - } + // Row visibility + if ($rowDimension->getVisible() == false) { + $objWriter->writeAttribute('hidden', 'true'); + } - // Write cells - if (isset($cellsByRow[$currentRow])) { - foreach ($cellsByRow[$currentRow] as $cellAddress) { - // Write cell - $this->_writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable); - } - } + // Collapsed + if ($rowDimension->getCollapsed() == true) { + $objWriter->writeAttribute('collapsed', 'true'); + } - // End row - $objWriter->endElement(); + // Outline level + if ($rowDimension->getOutlineLevel() > 0) { + $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel()); } + + // Style + if ($rowDimension->getXfIndex() !== null) { + $objWriter->writeAttribute('s', $rowDimension->getXfIndex()); + $objWriter->writeAttribute('customFormat', '1'); + } + + // Write cells + if (isset($cellsByRow[$currentRow])) { + foreach ($cellsByRow[$currentRow] as $cellAddress) { + // Write cell + $this->_writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable); + } + } + + // End row + $objWriter->endElement(); } + } $objWriter->endElement(); } else { @@ -1095,7 +1094,7 @@ private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce switch (strtolower($mappedType)) { case 'inlinestr': // Inline string if (! $cellValue instanceof PHPExcel_RichText) { - $objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML( htmlspecialchars($cellValue) ) ); + $objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML(htmlspecialchars($cellValue))); } else if ($cellValue instanceof PHPExcel_RichText) { $objWriter->startElement('is'); $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue); @@ -1172,7 +1171,7 @@ private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce * @param boolean $includeCharts Flag indicating if we should include drawing details for charts * @throws PHPExcel_Writer_Exception */ - private function _writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = FALSE) + private function _writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = false) { $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0; // If sheet contains drawings, add the relationships diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index c9e643756..024e7708a 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -467,7 +467,7 @@ private function _buildWorkbookEscher() case 1: // GIF, not supported by BIFF8, we convert to PNG $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; ob_start(); - imagepng(imagecreatefromgif ($filename)); + imagepng(imagecreatefromgif($filename)); $blipData = ob_get_contents(); ob_end_clean(); break; diff --git a/Classes/PHPExcel/Writer/Excel5/Escher.php b/Classes/PHPExcel/Writer/Excel5/Escher.php index 62e62f224..fc0f10a75 100644 --- a/Classes/PHPExcel/Writer/Excel5/Escher.php +++ b/Classes/PHPExcel/Writer/Excel5/Escher.php @@ -105,7 +105,8 @@ public function close() // dgg data $dggData = - pack('VVVV', + pack( + 'VVVV', $this->_object->getSpIdMax(), // maximum shape identifier increased by one $this->_object->getCDgSaved() + 1, // number of file identifier clusters increased by one $this->_object->getCSpSaved(), @@ -187,7 +188,7 @@ public function close() $btMacOS = $this->_object->getBlipType(); $data .= pack('CC', $btWin32, $btMacOS); - $rgbUid = pack('VVVV', 0,0,0,0); // todo + $rgbUid = pack('VVVV', 0, 0, 0, 0); // todo $data .= $rgbUid; $tag = 0; @@ -226,7 +227,7 @@ public function close() // initialize $innerData = ''; - $rgbUid1 = pack('VVVV', 0,0,0,0); // todo + $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo $innerData .= $rgbUid1; $tag = 0xFF; // todo @@ -253,7 +254,7 @@ public function close() // initialize $innerData = ''; - $rgbUid1 = pack('VVVV', 0,0,0,0); // todo + $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo $innerData .= $rgbUid1; $tag = 0xFF; // todo @@ -387,7 +388,7 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . pack('VVVV', 0,0,0,0); + $data .= $header . pack('VVVV', 0, 0, 0, 0); } $this->_spTypes[] = ($this->_object->getSpType()); diff --git a/Classes/PHPExcel/Writer/Excel5/Parser.php b/Classes/PHPExcel/Writer/Excel5/Parser.php index 8cf86ca8b..56449fcff 100644 --- a/Classes/PHPExcel/Writer/Excel5/Parser.php +++ b/Classes/PHPExcel/Writer/Excel5/Parser.php @@ -1130,60 +1130,39 @@ private function _match($token) break; default: // if it's a reference A1 or $A$1 or $A1 or A$1 - if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $token) and - !preg_match("/[0-9]/", $this->_lookahead) and - ($this->_lookahead != ':') and ($this->_lookahead != '.') and - ($this->_lookahead != '!')) { + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $token) and !preg_match("/[0-9]/", $this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.') and ($this->_lookahead != '!')) { return $token; - } - // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and - !preg_match("/[0-9]/", $this->_lookahead) and - ($this->_lookahead != ':') and ($this->_lookahead != '.')) { + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.')) { + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) return $token; } - // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and - !preg_match("/[0-9]/", $this->_lookahead) and - ($this->_lookahead != ':') and ($this->_lookahead != '.')) { + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.')) { + // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) return $token; - } - // if it's a range A1:A2 or $A$1:$A$2 - elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) and - !preg_match("/[0-9]/", $this->_lookahead)) { + } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) && !preg_match("/[0-9]/", $this->_lookahead)) { + // if it's a range A1:A2 or $A$1:$A$2 return $token; - } - // If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and - !preg_match("/[0-9]/", $this->_lookahead)) { + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead)) { + // If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 return $token; - } - // If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and - !preg_match("/[0-9]/", $this->_lookahead)) { + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead)) { + // If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 return $token; - } - // If it's a number (check that it's not a sheet name or range) - elseif (is_numeric($token) and - (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and - ($this->_lookahead != '!') and ($this->_lookahead != ':')) { + } elseif (is_numeric($token) and (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and ($this->_lookahead != '!') and ($this->_lookahead != ':')) { + // If it's a number (check that it's not a sheet name or range) return $token; - } - // If it's a string (of maximum 255 characters) - elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token) and $this->_lookahead != '"' and (substr_count($token, '"')%2 == 0)) { + } elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token) and $this->_lookahead != '"' and (substr_count($token, '"')%2 == 0)) { + // If it's a string (of maximum 255 characters) return $token; - } - // If it's an error code - elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { + } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { + // If it's an error code return $token; - } - // if it's a function call - elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $token) and ($this->_lookahead == "(")) { + } elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $token) and ($this->_lookahead == "(")) { + // if it's a function call return $token; - } - // It's an argument of some description (e.g. a named range), - // precise nature yet to be determined - elseif (substr($token,-1) == ')') { + } elseif (substr($token, -1) == ')') { + // It's an argument of some description (e.g. a named range), + // precise nature yet to be determined return $token; } return ''; @@ -1266,7 +1245,10 @@ private function _expression() // If it's a string return a string node if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $this->_current_token)) { $tmp = str_replace('""', '"', $this->_current_token); - if (($tmp == '"') || ($tmp == '')) $tmp = '""'; // Trap for "" that has been used for an empty string + if (($tmp == '"') || ($tmp == '')) { + // Trap for "" that has been used for an empty string + $tmp = '""'; + } $result = $this->_createTree($tmp, '', ''); $this->_advance(); return $result; @@ -1375,38 +1357,33 @@ private function _fact() return $result; } // if it's a reference - if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $this->_current_token)) - { + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $this->_current_token)) { $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; } // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) - { + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) { $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; } // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) - { + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) { $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; } // if it's a range A1:B2 or $A$1:$B$2 elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->_current_token) or - preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->_current_token)) - { + preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->_current_token)) { // must be an error? $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; } // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) - { + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) { // must be an error? //$result = $this->_current_token; $result = $this->_createTree($this->_current_token, '', ''); @@ -1414,8 +1391,7 @@ private function _fact() return $result; } // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) - { + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) { // must be an error? //$result = $this->_current_token; $result = $this->_createTree($this->_current_token, '', ''); @@ -1423,8 +1399,7 @@ private function _fact() return $result; } // If it's a number or a percent - elseif (is_numeric($this->_current_token)) - { + elseif (is_numeric($this->_current_token)) { if ($this->_lookahead == '%') { $result = $this->_createTree('ptgPercent', $this->_current_token, ''); $this->_advance(); // Skip the percentage operator once we've pre-built that tree @@ -1435,8 +1410,7 @@ private function _fact() return $result; } // if it's a function call - elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $this->_current_token)) - { + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $this->_current_token)) { $result = $this->_func(); return $result; } @@ -1462,13 +1436,10 @@ private function _func() while ($this->_current_token != ')') { /**/ if ($num_args > 0) { - if ($this->_current_token == "," or - $this->_current_token == ";") - { + if ($this->_current_token == "," || $this->_current_token == ";") { $this->_advance(); // eat the "," or ";" } else { - throw new PHPExcel_Writer_Exception("Syntax error: comma expected in ". - "function $function, arg #{$num_args}"); + throw new PHPExcel_Writer_Exception("Syntax error: comma expected in function $function, arg #{$num_args}"); } $result2 = $this->_condition(); $result = $this->_createTree('arg', $result, $result2); @@ -1560,8 +1531,7 @@ public function toReversePolish($tree = array()) !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/', $tree['value']) and !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/", $tree['value']) and !is_numeric($tree['value']) and - !isset($this->ptg[$tree['value']])) - { + !isset($this->ptg[$tree['value']])) { // left subtree for a function is always an array. if ($tree['left'] != '') { $left_tree = $this->toReversePolish($tree['left']); diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index 298cb2c11..cd6bbd737 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -845,7 +845,8 @@ private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isH // option flags $options = ($isHidden ? 0x21 : 0x00); - $extra = pack('Cvvvvv', + $extra = pack( + 'Cvvvvv', 0x3B, $sheetIndex - 1, $rangeBounds[0][1] - 1, @@ -906,7 +907,7 @@ private function _writeWindow1() $itabFirst = 0; // 1st displayed worksheet $itabCur = $this->_phpExcel->getActiveSheetIndex(); // Active worksheet - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, $grbit, $itabCur, $itabFirst, $ctabsel, $wTabRatio); $this->_append($header . $data); } diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index aa4cfbb59..11e0e862a 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -1590,7 +1590,7 @@ private function _writeSheetProtection() // record data $recordData = pack( - 'vVVCVVvv', + 'vVVCVVvv', 0x0867, // repeated record identifier 0x0000, // not used 0x0000, // not used @@ -2736,7 +2736,8 @@ private function _writeMsoDrawing() if ($spTypes[$i] == 0x00C9) { // Add ftCmo (common object data) subobject $objData .= - pack('vvvvvVVV', + pack( + 'vvvvvVVV', 0x0015, // 0x0015 = ftCmo 0x0012, // length of ftCmo data 0x0014, // object type, 0x0014 = filter @@ -2756,7 +2757,8 @@ private function _writeMsoDrawing() } else { // Add ftCmo (common object data) subobject $objData .= - pack('vvvvvVVV', + pack( + 'vvvvvVVV', 0x0015, // 0x0015 = ftCmo 0x0012, // length of ftCmo data 0x0008, // object type, 0x0008 = picture @@ -2770,7 +2772,8 @@ private function _writeMsoDrawing() // ftEnd $objData .= - pack('vv', + pack( + 'vv', 0x0000, // 0x0000 = ftEnd 0x0000 // length of ftEnd data ); From 141a61a908aef70d48a36fabdc07b50d055c1ec7 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Wed, 13 May 2015 13:36:53 +0200 Subject: [PATCH 367/467] PSR-2 : Fixes --- .../PHPExcel/Worksheet/AutoFilter/Column.php | 71 +++++++++----- .../Worksheet/AutoFilter/Column/Rule.php | 68 ++++++++------ Classes/PHPExcel/Worksheet/BaseDrawing.php | 94 +++++++++++-------- .../Worksheet/HeaderFooterDrawing.php | 69 +++++++++----- Classes/PHPExcel/Worksheet/MemoryDrawing.php | 32 ++++--- Classes/PHPExcel/Worksheet/PageMargins.php | 39 +++++--- Classes/PHPExcel/Worksheet/SheetView.php | 27 ++++-- 7 files changed, 246 insertions(+), 154 deletions(-) diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php index 577f8db50..9f705cabc 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php @@ -79,7 +79,7 @@ class PHPExcel_Worksheet_AutoFilter_Column * * @var PHPExcel_Worksheet_AutoFilter */ - private $_parent = NULL; + private $_parent = null; /** @@ -128,7 +128,7 @@ class PHPExcel_Worksheet_AutoFilter_Column * @param string $pColumn Column (e.g. A) * @param PHPExcel_Worksheet_AutoFilter $pParent Autofilter for this column */ - public function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = NULL) + public function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = null) { $this->_columnIndex = $pColumn; $this->_parent = $pParent; @@ -139,7 +139,8 @@ public function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = N * * @return string */ - public function getColumnIndex() { + public function getColumnIndex() + { return $this->_columnIndex; } @@ -150,10 +151,11 @@ public function getColumnIndex() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function setColumnIndex($pColumn) { + public function setColumnIndex($pColumn) + { // Uppercase coordinate $pColumn = strtoupper($pColumn); - if ($this->_parent !== NULL) { + if ($this->_parent !== null) { $this->_parent->testColumnInRange($pColumn); } @@ -167,7 +169,8 @@ public function setColumnIndex($pColumn) { * * @return PHPExcel_Worksheet_AutoFilter */ - public function getParent() { + public function getParent() + { return $this->_parent; } @@ -177,7 +180,8 @@ public function getParent() { * @param PHPExcel_Worksheet_AutoFilter * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = NULL) { + public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = null) + { $this->_parent = $pParent; return $this; @@ -188,7 +192,8 @@ public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = NULL) { * * @return string */ - public function getFilterType() { + public function getFilterType() + { return $this->_filterType; } @@ -199,8 +204,9 @@ public function getFilterType() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER) { - if (!in_array($pFilterType,self::$_filterTypes)) { + public function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER) + { + if (!in_array($pFilterType, self::$_filterTypes)) { throw new PHPExcel_Exception('Invalid filter type for column AutoFilter.'); } @@ -225,10 +231,11 @@ public function getJoin() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR) { + public function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR) + { // Lowercase And/Or $pJoin = strtolower($pJoin); - if (!in_array($pJoin,self::$_ruleJoins)) { + if (!in_array($pJoin, self::$_ruleJoins)) { throw new PHPExcel_Exception('Invalid rule connection for column AutoFilter.'); } @@ -244,7 +251,8 @@ public function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function setAttributes($pAttributes = array()) { + public function setAttributes($pAttributes = array()) + { $this->_attributes = $pAttributes; return $this; @@ -258,7 +266,8 @@ public function setAttributes($pAttributes = array()) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function setAttribute($pName, $pValue) { + public function setAttribute($pName, $pValue) + { $this->_attributes[$pName] = $pValue; return $this; @@ -269,7 +278,8 @@ public function setAttribute($pName, $pValue) { * * @return string */ - public function getAttributes() { + public function getAttributes() + { return $this->_attributes; } @@ -279,10 +289,12 @@ public function getAttributes() { * @param string $pName Attribute Name * @return string */ - public function getAttribute($pName) { - if (isset($this->_attributes[$pName])) + public function getAttribute($pName) + { + if (isset($this->_attributes[$pName])) { return $this->_attributes[$pName]; - return NULL; + } + return null; } /** @@ -291,7 +303,8 @@ public function getAttribute($pName) { * @throws PHPExcel_Exception * @return array of PHPExcel_Worksheet_AutoFilter_Column_Rule */ - public function getRules() { + public function getRules() + { return $this->_ruleset; } @@ -301,7 +314,8 @@ public function getRules() { * @param integer $pIndex Rule index in the ruleset array * @return PHPExcel_Worksheet_AutoFilter_Column_Rule */ - public function getRule($pIndex) { + public function getRule($pIndex) + { if (!isset($this->_ruleset[$pIndex])) { $this->_ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); } @@ -313,7 +327,8 @@ public function getRule($pIndex) { * * @return PHPExcel_Worksheet_AutoFilter_Column_Rule */ - public function createRule() { + public function createRule() + { $this->_ruleset[] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); return end($this->_ruleset); @@ -326,7 +341,8 @@ public function createRule() { * @param boolean $returnRule Flag indicating whether the rule object or the column object should be returned * @return PHPExcel_Worksheet_AutoFilter_Column|PHPExcel_Worksheet_AutoFilter_Column_Rule */ - public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $returnRule=TRUE) { + public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $returnRule = true) + { $pRule->setParent($this); $this->_ruleset[] = $pRule; @@ -340,7 +356,8 @@ public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $retur * @param integer $pIndex Rule index in the ruleset array * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function deleteRule($pIndex) { + public function deleteRule($pIndex) + { if (isset($this->_ruleset[$pIndex])) { unset($this->_ruleset[$pIndex]); // If we've just deleted down to a single rule, then reset And/Or joining to Or @@ -357,7 +374,8 @@ public function deleteRule($pIndex) { * * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function clearRules() { + public function clearRules() + { $this->_ruleset = array(); $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); @@ -367,13 +385,14 @@ public function clearRules() { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { if ($key == '_parent') { // Detach from autofilter parent - $this->$key = NULL; + $this->$key = null; } else { $this->$key = clone $value; } diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php index ecf93fa22..e31c9cfca 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -234,7 +234,7 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule * * @var PHPExcel_Worksheet_AutoFilter_Column */ - private $_parent = NULL; + private $_parent = null; /** @@ -272,7 +272,7 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule * * @param PHPExcel_Worksheet_AutoFilter_Column $pParent */ - public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) + public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = null) { $this->_parent = $pParent; } @@ -282,7 +282,8 @@ public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL * * @return string */ - public function getRuleType() { + public function getRuleType() + { return $this->_ruleType; } @@ -293,8 +294,9 @@ public function getRuleType() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) { - if (!in_array($pRuleType,self::$_ruleTypes)) { + public function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) + { + if (!in_array($pRuleType, self::$_ruleTypes)) { throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); } @@ -308,7 +310,8 @@ public function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) { * * @return string */ - public function getValue() { + public function getValue() + { return $this->_value; } @@ -319,17 +322,18 @@ public function getValue() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column_Rule */ - public function setValue($pValue = '') { + public function setValue($pValue = '') + { if (is_array($pValue)) { $grouping = -1; foreach ($pValue as $key => $value) { // Validate array entries - if (!in_array($key,self::$_dateTimeGroups)) { + if (!in_array($key, self::$_dateTimeGroups)) { // Remove any invalid entries from the value array unset($pValue[$key]); } else { // Work out what the dateTime grouping will be - $grouping = max($grouping,array_search($key,self::$_dateTimeGroups)); + $grouping = max($grouping, array_search($key,self::$_dateTimeGroups)); } } if (count($pValue) == 0) { @@ -348,7 +352,8 @@ public function setValue($pValue = '') { * * @return string */ - public function getOperator() { + public function getOperator() + { return $this->_operator; } @@ -359,11 +364,13 @@ public function getOperator() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column_Rule */ - public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) { - if (empty($pOperator)) + public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) + { + if (empty($pOperator)) { $pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL; - if ((!in_array($pOperator,self::$_operators)) && - (!in_array($pOperator,self::$_topTenValue))) { + } + if ((!in_array($pOperator, self::$_operators)) && + (!in_array($pOperator, self::$_topTenValue))) { throw new PHPExcel_Exception('Invalid operator for column AutoFilter Rule.'); } $this->_operator = $pOperator; @@ -376,7 +383,8 @@ public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) { * * @return string */ - public function getGrouping() { + public function getGrouping() + { return $this->_grouping; } @@ -387,14 +395,14 @@ public function getGrouping() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column_Rule */ - public function setGrouping($pGrouping = NULL) { - if (($pGrouping !== NULL) && - (!in_array($pGrouping,self::$_dateTimeGroups)) && - (!in_array($pGrouping,self::$_dynamicTypes)) && - (!in_array($pGrouping,self::$_topTenType))) { + public function setGrouping($pGrouping = null) + { + if (($pGrouping !== null) && + (!in_array($pGrouping, self::$_dateTimeGroups)) && + (!in_array($pGrouping, self::$_dynamicTypes)) && + (!in_array($pGrouping, self::$_topTenType))) { throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); } - $this->_grouping = $pGrouping; return $this; @@ -409,14 +417,16 @@ public function setGrouping($pGrouping = NULL) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column_Rule */ - public function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue = '', $pGrouping = NULL) { + public function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue = '', $pGrouping = null) + { $this->setOperator($pOperator); $this->setValue($pValue); // Only set grouping if it's been passed in as a user-supplied argument, // otherwise we're calculating it when we setValue() and don't want to overwrite that // If the user supplies an argumnet for grouping, then on their own head be it - if ($pGrouping !== NULL) + if ($pGrouping !== null) { $this->setGrouping($pGrouping); + } return $this; } @@ -426,7 +436,8 @@ public function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue * * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function getParent() { + public function getParent() + { return $this->_parent; } @@ -436,7 +447,8 @@ public function getParent() { * @param PHPExcel_Worksheet_AutoFilter_Column * @return PHPExcel_Worksheet_AutoFilter_Column_Rule */ - public function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) { + public function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = null) + { $this->_parent = $pParent; return $this; @@ -445,13 +457,14 @@ public function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { if ($key == '_parent') { // Detach from autofilter column parent - $this->$key = NULL; + $this->$key = null; } else { $this->$key = clone $value; } @@ -460,5 +473,4 @@ public function __clone() { } } } - } diff --git a/Classes/PHPExcel/Worksheet/BaseDrawing.php b/Classes/PHPExcel/Worksheet/BaseDrawing.php index d22c6b4b3..9ae35adc2 100644 --- a/Classes/PHPExcel/Worksheet/BaseDrawing.php +++ b/Classes/PHPExcel/Worksheet/BaseDrawing.php @@ -154,7 +154,8 @@ public function __construct() * * @return int */ - public function getImageIndex() { + public function getImageIndex() + { return $this->_imageIndex; } @@ -163,7 +164,8 @@ public function getImageIndex() { * * @return string */ - public function getName() { + public function getName() + { return $this->_name; } @@ -173,7 +175,8 @@ public function getName() { * @param string $pValue * @return PHPExcel_Worksheet_BaseDrawing */ - public function setName($pValue = '') { + public function setName($pValue = '') + { $this->_name = $pValue; return $this; } @@ -183,7 +186,8 @@ public function setName($pValue = '') { * * @return string */ - public function getDescription() { + public function getDescription() + { return $this->_description; } @@ -193,7 +197,8 @@ public function getDescription() { * @param string $pValue * @return PHPExcel_Worksheet_BaseDrawing */ - public function setDescription($pValue = '') { + public function setDescription($pValue = '') + { $this->_description = $pValue; return $this; } @@ -203,7 +208,8 @@ public function setDescription($pValue = '') { * * @return PHPExcel_Worksheet */ - public function getWorksheet() { + public function getWorksheet() + { return $this->_worksheet; } @@ -215,7 +221,8 @@ public function getWorksheet() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_BaseDrawing */ - public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = false) { + public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = false) + { if (is_null($this->_worksheet)) { // Add drawing to PHPExcel_Worksheet $this->_worksheet = $pValue; @@ -228,7 +235,7 @@ public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = while ($iterator->valid()) { if ($iterator->current()->getHashCode() == $this->getHashCode()) { - $this->_worksheet->getDrawingCollection()->offsetUnset( $iterator->key() ); + $this->_worksheet->getDrawingCollection()->offsetUnset($iterator->key()); $this->_worksheet = null; break; } @@ -248,7 +255,8 @@ public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = * * @return string */ - public function getCoordinates() { + public function getCoordinates() + { return $this->_coordinates; } @@ -258,7 +266,8 @@ public function getCoordinates() { * @param string $pValue * @return PHPExcel_Worksheet_BaseDrawing */ - public function setCoordinates($pValue = 'A1') { + public function setCoordinates($pValue = 'A1') + { $this->_coordinates = $pValue; return $this; } @@ -268,7 +277,8 @@ public function setCoordinates($pValue = 'A1') { * * @return int */ - public function getOffsetX() { + public function getOffsetX() + { return $this->_offsetX; } @@ -278,7 +288,8 @@ public function getOffsetX() { * @param int $pValue * @return PHPExcel_Worksheet_BaseDrawing */ - public function setOffsetX($pValue = 0) { + public function setOffsetX($pValue = 0) + { $this->_offsetX = $pValue; return $this; } @@ -288,7 +299,8 @@ public function setOffsetX($pValue = 0) { * * @return int */ - public function getOffsetY() { + public function getOffsetY() + { return $this->_offsetY; } @@ -298,7 +310,8 @@ public function getOffsetY() { * @param int $pValue * @return PHPExcel_Worksheet_BaseDrawing */ - public function setOffsetY($pValue = 0) { + public function setOffsetY($pValue = 0) + { $this->_offsetY = $pValue; return $this; } @@ -308,7 +321,8 @@ public function setOffsetY($pValue = 0) { * * @return int */ - public function getWidth() { + public function getWidth() + { return $this->_width; } @@ -318,7 +332,8 @@ public function getWidth() { * @param int $pValue * @return PHPExcel_Worksheet_BaseDrawing */ - public function setWidth($pValue = 0) { + public function setWidth($pValue = 0) + { // Resize proportional? if ($this->_resizeProportional && $pValue != 0) { $ratio = $this->_height / ($this->_width != 0 ? $this->_width : 1); @@ -336,7 +351,8 @@ public function setWidth($pValue = 0) { * * @return int */ - public function getHeight() { + public function getHeight() + { return $this->_height; } @@ -346,7 +362,8 @@ public function getHeight() { * @param int $pValue * @return PHPExcel_Worksheet_BaseDrawing */ - public function setHeight($pValue = 0) { + public function setHeight($pValue = 0) + { // Resize proportional? if ($this->_resizeProportional && $pValue != 0) { $ratio = $this->_width / ($this->_height != 0 ? $this->_height : 1); @@ -372,7 +389,8 @@ public function setHeight($pValue = 0) { * @param int $height * @return PHPExcel_Worksheet_BaseDrawing */ - public function setWidthAndHeight($width = 0, $height = 0) { + public function setWidthAndHeight($width = 0, $height = 0) + { $xratio = $width / ($this->_width != 0 ? $this->_width : 1); $yratio = $height / ($this->_height != 0 ? $this->_height : 1); if ($this->_resizeProportional && !($width == 0 || $height == 0)) { @@ -396,7 +414,8 @@ public function setWidthAndHeight($width = 0, $height = 0) { * * @return boolean */ - public function getResizeProportional() { + public function getResizeProportional() + { return $this->_resizeProportional; } @@ -406,7 +425,8 @@ public function getResizeProportional() { * @param boolean $pValue * @return PHPExcel_Worksheet_BaseDrawing */ - public function setResizeProportional($pValue = true) { + public function setResizeProportional($pValue = true) + { $this->_resizeProportional = $pValue; return $this; } @@ -416,7 +436,8 @@ public function setResizeProportional($pValue = true) { * * @return int */ - public function getRotation() { + public function getRotation() + { return $this->_rotation; } @@ -426,7 +447,8 @@ public function getRotation() { * @param int $pValue * @return PHPExcel_Worksheet_BaseDrawing */ - public function setRotation($pValue = 0) { + public function setRotation($pValue = 0) + { $this->_rotation = $pValue; return $this; } @@ -436,7 +458,8 @@ public function setRotation($pValue = 0) { * * @return PHPExcel_Worksheet_Drawing_Shadow */ - public function getShadow() { + public function getShadow() + { return $this->_shadow; } @@ -447,7 +470,8 @@ public function getShadow() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_BaseDrawing */ - public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) { + public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) + { $this->_shadow = $pValue; return $this; } @@ -457,26 +481,16 @@ public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) { * * @return string Hash code */ - public function getHashCode() { - return md5( - $this->_name - . $this->_description - . $this->_worksheet->getHashCode() - . $this->_coordinates - . $this->_offsetX - . $this->_offsetY - . $this->_width - . $this->_height - . $this->_rotation - . $this->_shadow->getHashCode() - . __CLASS__ - ); + public function getHashCode() + { + return md5($this->_name.$this->_description.$this->_worksheet->getHashCode().$this->_coordinates.$this->_offsetX.$this->_offsetY.$this->_width.$this->_height.$this->_rotation.$this->_shadow->getHashCode().__CLASS__); } /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php index 6468d4f3b..6c1fa1f22 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php @@ -92,11 +92,11 @@ public function __construct() // Initialise values $this->_path = ''; $this->_name = ''; - $this->_offsetX = 0; - $this->_offsetY = 0; - $this->_width = 0; - $this->_height = 0; - $this->_resizeProportional = true; + $this->_offsetX = 0; + $this->_offsetY = 0; + $this->_width = 0; + $this->_height = 0; + $this->_resizeProportional = true; } /** @@ -104,7 +104,8 @@ public function __construct() * * @return string */ - public function getName() { + public function getName() + { return $this->_name; } @@ -114,7 +115,8 @@ public function getName() { * @param string $pValue * @return PHPExcel_Worksheet_HeaderFooterDrawing */ - public function setName($pValue = '') { + public function setName($pValue = '') + { $this->_name = $pValue; return $this; } @@ -124,7 +126,8 @@ public function setName($pValue = '') { * * @return int */ - public function getOffsetX() { + public function getOffsetX() + { return $this->_offsetX; } @@ -134,7 +137,8 @@ public function getOffsetX() { * @param int $pValue * @return PHPExcel_Worksheet_HeaderFooterDrawing */ - public function setOffsetX($pValue = 0) { + public function setOffsetX($pValue = 0) + { $this->_offsetX = $pValue; return $this; } @@ -144,7 +148,8 @@ public function setOffsetX($pValue = 0) { * * @return int */ - public function getOffsetY() { + public function getOffsetY() + { return $this->_offsetY; } @@ -154,7 +159,8 @@ public function getOffsetY() { * @param int $pValue * @return PHPExcel_Worksheet_HeaderFooterDrawing */ - public function setOffsetY($pValue = 0) { + public function setOffsetY($pValue = 0) + { $this->_offsetY = $pValue; return $this; } @@ -164,7 +170,8 @@ public function setOffsetY($pValue = 0) { * * @return int */ - public function getWidth() { + public function getWidth() + { return $this->_width; } @@ -174,7 +181,8 @@ public function getWidth() { * @param int $pValue * @return PHPExcel_Worksheet_HeaderFooterDrawing */ - public function setWidth($pValue = 0) { + public function setWidth($pValue = 0) + { // Resize proportional? if ($this->_resizeProportional && $pValue != 0) { $ratio = $this->_width / $this->_height; @@ -192,7 +200,8 @@ public function setWidth($pValue = 0) { * * @return int */ - public function getHeight() { + public function getHeight() + { return $this->_height; } @@ -202,7 +211,8 @@ public function getHeight() { * @param int $pValue * @return PHPExcel_Worksheet_HeaderFooterDrawing */ - public function setHeight($pValue = 0) { + public function setHeight($pValue = 0) + { // Resize proportional? if ($this->_resizeProportional && $pValue != 0) { $ratio = $this->_width / $this->_height; @@ -228,7 +238,8 @@ public function setHeight($pValue = 0) { * @param int $height * @return PHPExcel_Worksheet_HeaderFooterDrawing */ - public function setWidthAndHeight($width = 0, $height = 0) { + public function setWidthAndHeight($width = 0, $height = 0) + { $xratio = $width / $this->_width; $yratio = $height / $this->_height; if ($this->_resizeProportional && !($width == 0 || $height == 0)) { @@ -248,7 +259,8 @@ public function setWidthAndHeight($width = 0, $height = 0) { * * @return boolean */ - public function getResizeProportional() { + public function getResizeProportional() + { return $this->_resizeProportional; } @@ -258,7 +270,8 @@ public function getResizeProportional() { * @param boolean $pValue * @return PHPExcel_Worksheet_HeaderFooterDrawing */ - public function setResizeProportional($pValue = true) { + public function setResizeProportional($pValue = true) + { $this->_resizeProportional = $pValue; return $this; } @@ -268,7 +281,8 @@ public function setResizeProportional($pValue = true) { * * @return string */ - public function getFilename() { + public function getFilename() + { return basename($this->_path); } @@ -277,7 +291,8 @@ public function getFilename() { * * @return string */ - public function getExtension() { + public function getExtension() + { $parts = explode(".", basename($this->_path)); return end($parts); } @@ -287,7 +302,8 @@ public function getExtension() { * * @return string */ - public function getPath() { + public function getPath() + { return $this->_path; } @@ -299,7 +315,8 @@ public function getPath() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_HeaderFooterDrawing */ - public function setPath($pValue = '', $pVerifyFile = true) { + public function setPath($pValue = '', $pVerifyFile = true) + { if ($pVerifyFile) { if (file_exists($pValue)) { $this->_path = $pValue; @@ -322,9 +339,10 @@ public function setPath($pValue = '', $pVerifyFile = true) { * * @return string Hash code */ - public function getHashCode() { + public function getHashCode() + { return md5( - $this->_path + $this->_path . $this->_name . $this->_offsetX . $this->_offsetY @@ -337,7 +355,8 @@ public function getHashCode() { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/Worksheet/MemoryDrawing.php b/Classes/PHPExcel/Worksheet/MemoryDrawing.php index 86fc681ed..1f19b4d0a 100644 --- a/Classes/PHPExcel/Worksheet/MemoryDrawing.php +++ b/Classes/PHPExcel/Worksheet/MemoryDrawing.php @@ -81,10 +81,10 @@ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing im public function __construct() { // Initialise values - $this->_imageResource = null; - $this->_renderingFunction = self::RENDERING_DEFAULT; + $this->_imageResource = null; + $this->_renderingFunction = self::RENDERING_DEFAULT; $this->_mimeType = self::MIMETYPE_DEFAULT; - $this->_uniqueName = md5(rand(0, 9999). time() . rand(0, 9999)); + $this->_uniqueName = md5(rand(0, 9999). time() . rand(0, 9999)); // Initialize parent parent::__construct(); @@ -95,7 +95,8 @@ public function __construct() * * @return resource */ - public function getImageResource() { + public function getImageResource() + { return $this->_imageResource; } @@ -105,7 +106,8 @@ public function getImageResource() { * @param $value resource * @return PHPExcel_Worksheet_MemoryDrawing */ - public function setImageResource($value = null) { + public function setImageResource($value = null) + { $this->_imageResource = $value; if (!is_null($this->_imageResource)) { @@ -121,7 +123,8 @@ public function setImageResource($value = null) { * * @return string */ - public function getRenderingFunction() { + public function getRenderingFunction() + { return $this->_renderingFunction; } @@ -131,7 +134,8 @@ public function getRenderingFunction() { * @param string $value * @return PHPExcel_Worksheet_MemoryDrawing */ - public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT) { + public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT) + { $this->_renderingFunction = $value; return $this; } @@ -141,7 +145,8 @@ public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing:: * * @return string */ - public function getMimeType() { + public function getMimeType() + { return $this->_mimeType; } @@ -151,7 +156,8 @@ public function getMimeType() { * @param string $value * @return PHPExcel_Worksheet_MemoryDrawing */ - public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT) { + public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT) + { $this->_mimeType = $value; return $this; } @@ -161,7 +167,8 @@ public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_ * * @return string */ - public function getIndexedFilename() { + public function getIndexedFilename() + { $extension = strtolower($this->getMimeType()); $extension = explode('/', $extension); $extension = $extension[1]; @@ -174,9 +181,10 @@ public function getIndexedFilename() { * * @return string Hash code */ - public function getHashCode() { + public function getHashCode() + { return md5( - $this->_renderingFunction + $this->_renderingFunction . $this->_mimeType . $this->_uniqueName . parent::getHashCode() diff --git a/Classes/PHPExcel/Worksheet/PageMargins.php b/Classes/PHPExcel/Worksheet/PageMargins.php index 38cbce6e6..afc269fd7 100644 --- a/Classes/PHPExcel/Worksheet/PageMargins.php +++ b/Classes/PHPExcel/Worksheet/PageMargins.php @@ -89,7 +89,8 @@ public function __construct() * * @return double */ - public function getLeft() { + public function getLeft() + { return $this->_left; } @@ -99,7 +100,8 @@ public function getLeft() { * @param double $pValue * @return PHPExcel_Worksheet_PageMargins */ - public function setLeft($pValue) { + public function setLeft($pValue) + { $this->_left = $pValue; return $this; } @@ -109,7 +111,8 @@ public function setLeft($pValue) { * * @return double */ - public function getRight() { + public function getRight() + { return $this->_right; } @@ -119,7 +122,8 @@ public function getRight() { * @param double $pValue * @return PHPExcel_Worksheet_PageMargins */ - public function setRight($pValue) { + public function setRight($pValue) + { $this->_right = $pValue; return $this; } @@ -129,7 +133,8 @@ public function setRight($pValue) { * * @return double */ - public function getTop() { + public function getTop() + { return $this->_top; } @@ -139,7 +144,8 @@ public function getTop() { * @param double $pValue * @return PHPExcel_Worksheet_PageMargins */ - public function setTop($pValue) { + public function setTop($pValue) + { $this->_top = $pValue; return $this; } @@ -149,7 +155,8 @@ public function setTop($pValue) { * * @return double */ - public function getBottom() { + public function getBottom() + { return $this->_bottom; } @@ -159,7 +166,8 @@ public function getBottom() { * @param double $pValue * @return PHPExcel_Worksheet_PageMargins */ - public function setBottom($pValue) { + public function setBottom($pValue) + { $this->_bottom = $pValue; return $this; } @@ -169,7 +177,8 @@ public function setBottom($pValue) { * * @return double */ - public function getHeader() { + public function getHeader() + { return $this->_header; } @@ -179,7 +188,8 @@ public function getHeader() { * @param double $pValue * @return PHPExcel_Worksheet_PageMargins */ - public function setHeader($pValue) { + public function setHeader($pValue) + { $this->_header = $pValue; return $this; } @@ -189,7 +199,8 @@ public function setHeader($pValue) { * * @return double */ - public function getFooter() { + public function getFooter() + { return $this->_footer; } @@ -199,7 +210,8 @@ public function getFooter() { * @param double $pValue * @return PHPExcel_Worksheet_PageMargins */ - public function setFooter($pValue) { + public function setFooter($pValue) + { $this->_footer = $pValue; return $this; } @@ -207,7 +219,8 @@ public function setFooter($pValue) { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/Worksheet/SheetView.php b/Classes/PHPExcel/Worksheet/SheetView.php index f2448e2bc..e0ea61483 100644 --- a/Classes/PHPExcel/Worksheet/SheetView.php +++ b/Classes/PHPExcel/Worksheet/SheetView.php @@ -86,7 +86,8 @@ public function __construct() * * @return int */ - public function getZoomScale() { + public function getZoomScale() + { return $this->_zoomScale; } @@ -99,7 +100,8 @@ public function getZoomScale() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_SheetView */ - public function setZoomScale($pValue = 100) { + public function setZoomScale($pValue = 100) + { // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, // but it is apparently still able to handle any scale >= 1 if (($pValue >= 1) || is_null($pValue)) { @@ -115,7 +117,8 @@ public function setZoomScale($pValue = 100) { * * @return int */ - public function getZoomScaleNormal() { + public function getZoomScaleNormal() + { return $this->_zoomScaleNormal; } @@ -128,7 +131,8 @@ public function getZoomScaleNormal() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_SheetView */ - public function setZoomScaleNormal($pValue = 100) { + public function setZoomScaleNormal($pValue = 100) + { if (($pValue >= 1) || is_null($pValue)) { $this->_zoomScaleNormal = $pValue; } else { @@ -142,7 +146,8 @@ public function setZoomScaleNormal($pValue = 100) { * * @return string */ - public function getView() { + public function getView() + { return $this->_sheetviewType; } @@ -158,11 +163,12 @@ public function getView() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_SheetView */ - public function setView($pValue = NULL) { - // MS Excel 2007 allows setting the view to 'normal', 'pageLayout' or 'pageBreakPreview' - // via the user interface - if ($pValue === NULL) + public function setView($pValue = null) + { + // MS Excel 2007 allows setting the view to 'normal', 'pageLayout' or 'pageBreakPreview' via the user interface + if ($pValue === null) { $pValue = self::SHEETVIEW_NORMAL; + } if (in_array($pValue, self::$_sheetViewTypes)) { $this->_sheetviewType = $pValue; } else { @@ -175,7 +181,8 @@ public function setView($pValue = NULL) { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { From feac76dadf99c4e9c8e39e3c7c3cb663b6bf9914 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 13 May 2015 17:00:22 +0100 Subject: [PATCH 368/467] We changed the coding standard to PSR-2, and wow! What happened next was awesome --- Classes/PHPExcel/Calculation.php | 1195 +++++++++++++------------ Classes/PHPExcel/Cell.php | 4 +- Classes/PHPExcel/Chart/Axis.php | 551 ++++++------ Classes/PHPExcel/Chart/DataSeries.php | 7 +- 4 files changed, 915 insertions(+), 842 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index b054fe2ac..63a2ace4c 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -1,30 +1,4 @@ <?php -/** - * PHPExcel - * - * Copyright (c) 2006 - 2015 PHPExcel - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - /** PHPExcel root directory */ if (!defined('PHPEXCEL_ROOT')) { @@ -35,32 +9,48 @@ require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); } - if (!defined('CALCULATION_REGEXP_CELLREF')) { // Test for support of \P (multibyte options) in PCRE - if(defined('PREG_BAD_UTF8_ERROR')) { + if (defined('PREG_BAD_UTF8_ERROR')) { // Cell reference (cell or range of cells, with or without a sheet reference) - define('CALCULATION_REGEXP_CELLREF','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})'); + define('CALCULATION_REGEXP_CELLREF', '((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})'); // Named Range of cells - define('CALCULATION_REGEXP_NAMEDRANGE','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)'); + define('CALCULATION_REGEXP_NAMEDRANGE', '((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)'); } else { // Cell reference (cell or range of cells, with or without a sheet reference) - define('CALCULATION_REGEXP_CELLREF','(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)'); + define('CALCULATION_REGEXP_CELLREF', '(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)'); // Named Range of cells - define('CALCULATION_REGEXP_NAMEDRANGE','(((\w*)|(\'.*\')|(\".*\"))!)?([_A-Z][_A-Z0-9\.]*)'); + define('CALCULATION_REGEXP_NAMEDRANGE', '(((\w*)|(\'.*\')|(\".*\"))!)?([_A-Z][_A-Z0-9\.]*)'); } } - /** * PHPExcel_Calculation (Multiton) * - * @category PHPExcel - * @package PHPExcel_Calculation - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * Copyright (c) 2006 - 2015 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## */ -class PHPExcel_Calculation { - +class PHPExcel_Calculation +{ /** Constants */ /** Regular Expressions */ // Numeric operand @@ -84,7 +74,7 @@ class PHPExcel_Calculation { const RETURN_ARRAY_AS_VALUE = 'value'; const RETURN_ARRAY_AS_ARRAY = 'array'; - private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; + private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; /** @@ -127,7 +117,7 @@ class PHPExcel_Calculation { * @access private * @var boolean */ - private $_calculationCacheEnabled = TRUE; + private $_calculationCacheEnabled = true; /** @@ -137,12 +127,12 @@ class PHPExcel_Calculation { * @access private * @var array */ - private static $_operators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, - '^' => TRUE, '&' => TRUE, '%' => FALSE, '~' => FALSE, - '>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, - '<=' => TRUE, '<>' => TRUE, '|' => TRUE, ':' => TRUE - ); - + private static $_operators = array( + '+' => true, '-' => true, '*' => true, '/' => true, + '^' => true, '&' => true, '%' => false, '~' => false, + '>' => true, '<' => true, '=' => true, '>=' => true, + '<=' => true, '<>' => true, '|' => true, ':' => true + ); /** * List of binary operators (those that expect two operands) @@ -150,11 +140,12 @@ class PHPExcel_Calculation { * @access private * @var array */ - private static $_binaryOperators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, - '^' => TRUE, '&' => TRUE, '>' => TRUE, '<' => TRUE, - '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE, - '|' => TRUE, ':' => TRUE - ); + private static $_binaryOperators = array( + '+' => true, '-' => true, '*' => true, '/' => true, + '^' => true, '&' => true, '>' => true, '<' => true, + '=' => true, '>=' => true, '<=' => true, '<>' => true, + '|' => true, ':' => true + ); /** * The debug log generated by the calculation engine @@ -174,7 +165,7 @@ class PHPExcel_Calculation { * @var boolean * */ - public $suppressFormulaErrors = FALSE; + public $suppressFormulaErrors = false; /** * Error message for any error that was raised/thrown by the calculation engine @@ -183,7 +174,7 @@ class PHPExcel_Calculation { * @var string * */ - public $formulaError = NULL; + public $formulaError = null; /** * An array of the nested cell references accessed by the calculation engine, used for the debug log @@ -240,8 +231,10 @@ class PHPExcel_Calculation { * @var string[] * */ - private static $_validLocaleLanguages = array( 'en' // English (default language) - ); + private static $_validLocaleLanguages = array( + 'en' // English (default language) + ); + /** * Locale-specific argument separator for function arguments * @@ -257,11 +250,11 @@ class PHPExcel_Calculation { * @var string[] * */ - public static $_localeBoolean = array( 'TRUE' => 'TRUE', - 'FALSE' => 'FALSE', - 'NULL' => 'NULL' - ); - + public static $_localeBoolean = array( + 'TRUE' => 'TRUE', + 'FALSE' => 'FALSE', + 'NULL' => 'NULL' + ); /** * Excel constant string translations to their PHP equivalents @@ -270,10 +263,11 @@ class PHPExcel_Calculation { * @var string[] * */ - private static $_ExcelConstants = array('TRUE' => TRUE, - 'FALSE' => FALSE, - 'NULL' => NULL - ); + private static $_ExcelConstants = array( + 'TRUE' => true, + 'FALSE' => false, + 'NULL' => null + ); // PHPExcel functions private static $_PHPExcelFunctions = array( // PHPExcel functions @@ -444,7 +438,7 @@ class PHPExcel_Calculation { 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', 'argumentCount' => '-1', - 'passByReference' => array(TRUE) + 'passByReference' => array(true) ), 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', @@ -853,7 +847,7 @@ class PHPExcel_Calculation { 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', 'argumentCount' => '1,2', - 'passCellReference'=> TRUE + 'passCellReference'=> true ), 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', @@ -942,7 +936,7 @@ class PHPExcel_Calculation { 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', 'argumentCount' => '1,2', - 'passCellReference'=> TRUE + 'passCellReference'=> true ), 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', @@ -1259,8 +1253,8 @@ class PHPExcel_Calculation { 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', 'argumentCount' => '3,5', - 'passCellReference'=> TRUE, - 'passByReference' => array(TRUE) + 'passCellReference'=> true, + 'passByReference' => array(true) ), 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', @@ -1405,7 +1399,7 @@ class PHPExcel_Calculation { 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', 'argumentCount' => '-1', - 'passByReference' => array(TRUE) + 'passByReference' => array(true) ), 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', @@ -1712,42 +1706,44 @@ class PHPExcel_Calculation { // Internal functions used for special control purposes private static $_controlFunctions = array( - 'MKMATRIX' => array('argumentCount' => '*', - 'functionCall' => 'self::_mkMatrix' - ) - ); - - + 'MKMATRIX' => array( + 'argumentCount' => '*', + 'functionCall' => 'self::_mkMatrix' + ) + ); - private function __construct(PHPExcel $workbook = NULL) { + private function __construct(PHPExcel $workbook = null) + { $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; $this->_savedPrecision = ini_get('precision'); if ($this->_savedPrecision < $setPrecision) { - ini_set('precision',$setPrecision); + ini_set('precision', $setPrecision); } $this->delta = 1 * pow(10, -$setPrecision); - if ($workbook !== NULL) { + if ($workbook !== null) { self::$_workbookSets[$workbook->getID()] = $this; } $this->_workbook = $workbook; $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack); - } // function __construct() + } - public function __destruct() { + public function __destruct() + { if ($this->_savedPrecision != ini_get('precision')) { - ini_set('precision',$this->_savedPrecision); + ini_set('precision', $this->_savedPrecision); } } - private static function _loadLocales() { + private static function _loadLocales() + { $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/'; - foreach (glob($localeFileDirectory.'/*',GLOB_ONLYDIR) as $filename) { - $filename = substr($filename,strlen($localeFileDirectory)+1); + foreach (glob($localeFileDirectory.'/*', GLOB_ONLYDIR) as $filename) { + $filename = substr($filename, strlen($localeFileDirectory)+1); if ($filename != 'en') { self::$_validLocaleLanguages[] = $filename; } @@ -1762,20 +1758,21 @@ private static function _loadLocales() { * or NULL to create a standalone claculation engine * @return PHPExcel_Calculation */ - public static function getInstance(PHPExcel $workbook = NULL) { - if ($workbook !== NULL) { + 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(); } return self::$_instance; - } // function getInstance() + } /** * Unset an instance of this class @@ -1783,8 +1780,9 @@ public static function getInstance(PHPExcel $workbook = NULL) { * @access public * @param PHPExcel $workbook Injected workbook identifying the instance to unset */ - public static function unsetInstance(PHPExcel $workbook = NULL) { - if ($workbook !== NULL) { + public static function unsetInstance(PHPExcel $workbook = null) + { + if ($workbook !== null) { if (isset(self::$_workbookSets[$workbook->getID()])) { unset(self::$_workbookSets[$workbook->getID()]); } @@ -1798,9 +1796,10 @@ public static function unsetInstance(PHPExcel $workbook = NULL) { * @access public * @return null */ - public function flushInstance() { + public function flushInstance() + { $this->clearCalculationCache(); - } // function flushInstance() + } /** @@ -1809,7 +1808,8 @@ public function flushInstance() { * @access public * @return PHPExcel_CalcEngine_Logger */ - public function getDebugLog() { + public function getDebugLog() + { return $this->_debugLog; } @@ -1819,9 +1819,10 @@ public function getDebugLog() { * @access public * @throws PHPExcel_Calculation_Exception */ - public final function __clone() { - throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!'); - } // function __clone() + final public function __clone() + { + throw new PHPExcel_Calculation_Exception('Cloning the calculation engine is not allowed!'); + } /** @@ -1830,7 +1831,8 @@ public final function __clone() { * @access public * @return string locale-specific translation of TRUE */ - public static function getTRUE() { + public static function getTRUE() + { return self::$_localeBoolean['TRUE']; } @@ -1840,7 +1842,8 @@ public static function getTRUE() { * @access public * @return string locale-specific translation of FALSE */ - public static function getFALSE() { + public static function getFALSE() + { return self::$_localeBoolean['FALSE']; } @@ -1851,15 +1854,16 @@ public static function getFALSE() { * @param string $returnType Array return type * @return boolean Success or failure */ - public static function setArrayReturnType($returnType) { + public static function setArrayReturnType($returnType) + { if (($returnType == self::RETURN_ARRAY_AS_VALUE) || ($returnType == self::RETURN_ARRAY_AS_ERROR) || ($returnType == self::RETURN_ARRAY_AS_ARRAY)) { self::$returnArrayAsType = $returnType; - return TRUE; + return true; } - return FALSE; - } // function setArrayReturnType() + return false; + } /** @@ -1868,9 +1872,10 @@ public static function setArrayReturnType($returnType) { * @access public * @return string $returnType Array return type */ - public static function getArrayReturnType() { + public static function getArrayReturnType() + { return self::$returnArrayAsType; - } // function getArrayReturnType() + } /** @@ -1879,9 +1884,10 @@ public static function getArrayReturnType() { * @access public * @return boolean */ - public function getCalculationCacheEnabled() { + public function getCalculationCacheEnabled() + { return $this->_calculationCacheEnabled; - } // function getCalculationCacheEnabled() + } /** * Enable/disable calculation cache @@ -1889,45 +1895,50 @@ public function getCalculationCacheEnabled() { * @access public * @param boolean $pValue */ - public function setCalculationCacheEnabled($pValue = TRUE) { + public function setCalculationCacheEnabled($pValue = true) + { $this->_calculationCacheEnabled = $pValue; $this->clearCalculationCache(); - } // function setCalculationCacheEnabled() + } /** * Enable calculation cache */ - public function enableCalculationCache() { - $this->setCalculationCacheEnabled(TRUE); - } // function enableCalculationCache() + public function enableCalculationCache() + { + $this->setCalculationCacheEnabled(true); + } /** * Disable calculation cache */ - public function disableCalculationCache() { - $this->setCalculationCacheEnabled(FALSE); - } // function disableCalculationCache() + public function disableCalculationCache() + { + $this->setCalculationCacheEnabled(false); + } /** * Clear calculation cache */ - public function clearCalculationCache() { + public function clearCalculationCache() + { $this->_calculationCache = array(); - } // function clearCalculationCache() + } /** * Clear calculation cache for a specified worksheet * * @param string $worksheetName */ - public function clearCalculationCacheForWorksheet($worksheetName) { + public function clearCalculationCacheForWorksheet($worksheetName) + { if (isset($this->_calculationCache[$worksheetName])) { unset($this->_calculationCache[$worksheetName]); } - } // function clearCalculationCacheForWorksheet() + } /** * Rename calculation cache for a specified worksheet @@ -1935,12 +1946,13 @@ public function clearCalculationCacheForWorksheet($worksheetName) { * @param string $fromWorksheetName * @param string $toWorksheetName */ - public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) { + public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) + { if (isset($this->_calculationCache[$fromWorksheetName])) { $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName]; unset($this->_calculationCache[$fromWorksheetName]); } - } // function renameCalculationCacheForWorksheet() + } /** @@ -1948,9 +1960,10 @@ public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksh * * @return string */ - public function getLocale() { + public function getLocale() + { return self::$_localeLanguage; - } // function getLocale() + } /** @@ -1959,18 +1972,19 @@ public function getLocale() { * @param string $locale The locale to use for formula translation * @return boolean */ - public function setLocale($locale = 'en_us') { + public function setLocale($locale = 'en_us') + { // Identify our locale and language $language = $locale = strtolower($locale); - if (strpos($locale,'_') !== FALSE) { - list($language) = explode('_',$locale); + if (strpos($locale, '_') !== false) { + list($language) = explode('_', $locale); } - if (count(self::$_validLocaleLanguages) == 1) + if (count(self::$_validLocaleLanguages) == 1) { self::_loadLocales(); - + } // Test whether we have any language data for this language (any locale) - if (in_array($language,self::$_validLocaleLanguages)) { + if (in_array($language, self::$_validLocaleLanguages)) { // initialise language/locale settings self::$_localeFunctions = array(); self::$_localeArgumentSeparator = ','; @@ -1978,20 +1992,20 @@ public function setLocale($locale = 'en_us') { // Default is English, if user isn't requesting english, then read the necessary data from the locale files if ($locale != 'en_us') { // Search for a file with a list of function names for locale - $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions'; + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $locale).DIRECTORY_SEPARATOR.'functions'; if (!file_exists($functionNamesFile)) { // If there isn't a locale specific function file, look for a language specific function file $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions'; if (!file_exists($functionNamesFile)) { - return FALSE; + return false; } } // Retrieve the list of locale or language specific function names - $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + $localeFunctions = file($functionNamesFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($localeFunctions as $localeFunction) { - list($localeFunction) = explode('##',$localeFunction); // Strip out comments - if (strpos($localeFunction,'=') !== FALSE) { - list($fName,$lfName) = explode('=',$localeFunction); + list($localeFunction) = explode('##', $localeFunction); // Strip out comments + if (strpos($localeFunction, '=') !== false) { + list($fName, $lfName) = explode('=', $localeFunction); $fName = trim($fName); $lfName = trim($lfName); if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { @@ -2000,22 +2014,26 @@ public function setLocale($locale = 'en_us') { } } // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions - if (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; } - if (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; } + if (isset(self::$_localeFunctions['TRUE'])) { + self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; + } + if (isset(self::$_localeFunctions['FALSE'])) { + self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; + } - $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config'; + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $locale).DIRECTORY_SEPARATOR.'config'; if (!file_exists($configFile)) { $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config'; } if (file_exists($configFile)) { - $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + $localeSettings = file($configFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($localeSettings as $localeSetting) { - list($localeSetting) = explode('##',$localeSetting); // Strip out comments - if (strpos($localeSetting,'=') !== FALSE) { - list($settingName,$settingValue) = explode('=',$localeSetting); + list($localeSetting) = explode('##', $localeSetting); // Strip out comments + if (strpos($localeSetting, '=') !== false) { + list($settingName, $settingValue) = explode('=', $localeSetting); $settingName = strtoupper(trim($settingName)); switch ($settingName) { - case 'ARGUMENTSEPARATOR' : + case 'ARGUMENTSEPARATOR': self::$_localeArgumentSeparator = trim($settingValue); break; } @@ -2025,127 +2043,136 @@ public function setLocale($locale = 'en_us') { } self::$functionReplaceFromExcel = self::$functionReplaceToExcel = - self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL; + self::$functionReplaceFromLocale = self::$functionReplaceToLocale = null; self::$_localeLanguage = $locale; - return TRUE; + return true; } - return FALSE; - } // function setLocale() + return false; + } - public static function _translateSeparator($fromSeparator,$toSeparator,$formula,&$inBraces) { + public static function _translateSeparator($fromSeparator, $toSeparator, $formula, &$inBraces) + { $strlen = mb_strlen($formula); for ($i = 0; $i < $strlen; ++$i) { - $chr = mb_substr($formula,$i,1); + $chr = mb_substr($formula, $i, 1); switch ($chr) { - case '{' : $inBraces = TRUE; - break; - case '}' : $inBraces = FALSE; - break; - case $fromSeparator : - if (!$inBraces) { - $formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1); - } + case '{': + $inBraces = true; + break; + case '}': + $inBraces = false; + break; + case $fromSeparator: + if (!$inBraces) { + $formula = mb_substr($formula, 0, $i).$toSeparator.mb_substr($formula, $i+1); + } } } return $formula; } - private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) { + private static function _translateFormula($from, $to, $formula, $fromSeparator, $toSeparator) + { // Convert any Excel function names to the required language if (self::$_localeLanguage !== 'en_us') { - $inBraces = FALSE; + $inBraces = false; // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators - if (strpos($formula,'"') !== FALSE) { + if (strpos($formula, '"') !== false) { // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded // the formula - $temp = explode('"',$formula); - $i = FALSE; - foreach($temp as &$value) { + $temp = explode('"', $formula); + $i = false; + foreach ($temp as &$value) { // Only count/replace in alternating array entries if ($i = !$i) { - $value = preg_replace($from,$to,$value); - $value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces); + $value = preg_replace($from, $to, $value); + $value = self::_translateSeparator($fromSeparator, $toSeparator, $value, $inBraces); } } unset($value); // Then rebuild the formula string - $formula = implode('"',$temp); + $formula = implode('"', $temp); } else { // If there's no quoted strings, then we do a simple count/replace - $formula = preg_replace($from,$to,$formula); - $formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces); + $formula = preg_replace($from, $to, $formula); + $formula = self::_translateSeparator($fromSeparator, $toSeparator, $formula, $inBraces); } } return $formula; } - private static $functionReplaceFromExcel = NULL; - private static $functionReplaceToLocale = NULL; + private static $functionReplaceFromExcel = null; + private static $functionReplaceToLocale = null; - public function _translateFormulaToLocale($formula) { - if (self::$functionReplaceFromExcel === NULL) { + public function _translateFormulaToLocale($formula) + { + if (self::$functionReplaceFromExcel === null) { self::$functionReplaceFromExcel = array(); - foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + foreach (array_keys(self::$_localeFunctions) as $excelFunctionName) { self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui'; } - foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + foreach (array_keys(self::$_localeBoolean) as $excelBoolean) { self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; } } - if (self::$functionReplaceToLocale === NULL) { + if (self::$functionReplaceToLocale === null) { self::$functionReplaceToLocale = array(); - foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + foreach (array_values(self::$_localeFunctions) as $localeFunctionName) { self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2'; } - foreach(array_values(self::$_localeBoolean) as $localeBoolean) { + foreach (array_values(self::$_localeBoolean) as $localeBoolean) { self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2'; } } - return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator); - } // function _translateFormulaToLocale() + return self::_translateFormula(self::$functionReplaceFromExcel, self::$functionReplaceToLocale, $formula, ',', self::$_localeArgumentSeparator); + } - private static $functionReplaceFromLocale = NULL; - private static $functionReplaceToExcel = NULL; + private static $functionReplaceFromLocale = null; + private static $functionReplaceToExcel = null; - public function _translateFormulaToEnglish($formula) { - if (self::$functionReplaceFromLocale === NULL) { + public function _translateFormulaToEnglish($formula) + { + if (self::$functionReplaceFromLocale === null) { self::$functionReplaceFromLocale = array(); - foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + foreach (array_values(self::$_localeFunctions) as $localeFunctionName) { self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui'; } - foreach(array_values(self::$_localeBoolean) as $excelBoolean) { + foreach (array_values(self::$_localeBoolean) as $excelBoolean) { self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; } } - if (self::$functionReplaceToExcel === NULL) { + if (self::$functionReplaceToExcel === null) { self::$functionReplaceToExcel = array(); - foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + foreach (array_keys(self::$_localeFunctions) as $excelFunctionName) { self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2'; } - foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + foreach (array_keys(self::$_localeBoolean) as $excelBoolean) { self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2'; } } - return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,','); - } // function _translateFormulaToEnglish() + return self::_translateFormula(self::$functionReplaceFromLocale, self::$functionReplaceToExcel, $formula, self::$_localeArgumentSeparator, ','); + } - public static function _localeFunc($function) { + public static function _localeFunc($function) + { if (self::$_localeLanguage !== 'en_us') { - $functionName = trim($function,'('); + $functionName = trim($function, '('); if (isset(self::$_localeFunctions[$functionName])) { $brace = ($functionName != $function); $function = self::$_localeFunctions[$functionName]; - if ($brace) { $function .= '('; } + if ($brace) { + $function .= '('; + } } } return $function; @@ -2160,7 +2187,8 @@ public static function _localeFunc($function) { * @param mixed $value * @return mixed */ - public static function _wrapResult($value) { + public static function _wrapResult($value) + { if (is_string($value)) { // Error values cannot be "wrapped" if (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) { @@ -2170,12 +2198,12 @@ public static function _wrapResult($value) { // Return strings wrapped in quotes return '"'.$value.'"'; // Convert numeric errors to NaN error - } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + } elseif ((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { return PHPExcel_Calculation_Functions::NaN(); } return $value; - } // function _wrapResult() + } /** @@ -2184,17 +2212,18 @@ public static function _wrapResult($value) { * @param mixed $value * @return mixed */ - public static function _unwrapResult($value) { + public static function _unwrapResult($value) + { if (is_string($value)) { - if ((isset($value{0})) && ($value{0} == '"') && (substr($value,-1) == '"')) { - return substr($value,1,-1); + if ((isset($value{0})) && ($value{0} == '"') && (substr($value, -1) == '"')) { + return substr($value, 1, -1); } // Convert numeric errors to NaN error - } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + } elseif ((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { return PHPExcel_Calculation_Functions::NaN(); } return $value; - } // function _unwrapResult() + } @@ -2208,13 +2237,14 @@ public static function _unwrapResult($value) { * @return mixed * @throws PHPExcel_Calculation_Exception */ - public function calculate(PHPExcel_Cell $pCell = NULL) { + public function calculate(PHPExcel_Cell $pCell = null) + { try { return $this->calculateCellValue($pCell); } catch (PHPExcel_Exception $e) { throw new PHPExcel_Calculation_Exception($e->getMessage()); } - } // function calculate() + } /** @@ -2226,9 +2256,10 @@ public function calculate(PHPExcel_Cell $pCell = NULL) { * @return mixed * @throws PHPExcel_Calculation_Exception */ - public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) { - if ($pCell === NULL) { - return NULL; + public function calculateCellValue(PHPExcel_Cell $pCell = null, $resetLog = true) + { + if ($pCell === null) { + return null; } $returnArrayAsType = self::$returnArrayAsType; @@ -2268,7 +2299,9 @@ public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE // If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it $r = array_keys($result); $r = array_shift($r); - if (!is_numeric($r)) { return PHPExcel_Calculation_Functions::VALUE(); } + if (!is_numeric($r)) { + return PHPExcel_Calculation_Functions::VALUE(); + } if (is_array($result[$r])) { $c = array_keys($result[$r]); $c = array_shift($c); @@ -2282,13 +2315,13 @@ public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE self::$returnArrayAsType = $returnArrayAsType; - if ($result === NULL) { + if ($result === null) { return 0; - } elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) { + } elseif ((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) { return PHPExcel_Calculation_Functions::NaN(); } return $result; - } // function calculateCellValue( + } /** @@ -2298,17 +2331,22 @@ public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE * @return array * @throws PHPExcel_Calculation_Exception */ - public function parseFormula($formula) { + public function parseFormula($formula) + { // Basic validation that this is indeed a formula // We return an empty array if not $formula = trim($formula); - if ((!isset($formula{0})) || ($formula{0} != '=')) return array(); - $formula = ltrim(substr($formula,1)); - if (!isset($formula{0})) return array(); + if ((!isset($formula{0})) || ($formula{0} != '=')) { + return array(); + } + $formula = ltrim(substr($formula, 1)); + if (!isset($formula{0})) { + return array(); + } // Parse the formula and return the token stack return $this->_parseFormula($formula); - } // function parseFormula() + } /** @@ -2320,7 +2358,8 @@ public function parseFormula($formula) { * @return mixed * @throws PHPExcel_Calculation_Exception */ - public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) { + public function calculateFormula($formula, $cellID = null, PHPExcel_Cell $pCell = null) + { // Initialise the logging settings $this->formulaError = null; $this->_debugLog->clearLog(); @@ -2329,7 +2368,7 @@ public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = // Disable calculation cacheing because it only applies to cell calculations, not straight formulae // But don't actually flush any cache $resetCache = $this->getCalculationCacheEnabled(); - $this->_calculationCacheEnabled = FALSE; + $this->_calculationCacheEnabled = false; // Execute the calculation try { $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); @@ -2341,10 +2380,11 @@ public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = $this->_calculationCacheEnabled = $resetCache; return $result; - } // function calculateFormula() + } - public function getValueFromCache($cellReference, &$cellValue) { + public function getValueFromCache($cellReference, &$cellValue) + { // Is calculation cacheing enabled? // Is the value present in calculation cache? $this->_debugLog->writeDebugLog('Testing cache value for cell ', $cellReference); @@ -2352,12 +2392,13 @@ public function getValueFromCache($cellReference, &$cellValue) { $this->_debugLog->writeDebugLog('Retrieving value for cell ', $cellReference, ' from cache'); // Return the cached result $cellValue = $this->_calculationCache[$cellReference]; - return TRUE; + return true; } - return FALSE; + return false; } - public function saveValueToCache($cellReference, $cellValue) { + public function saveValueToCache($cellReference, $cellValue) + { if ($this->_calculationCacheEnabled) { $this->_calculationCache[$cellReference] = $cellValue; } @@ -2372,21 +2413,26 @@ public function saveValueToCache($cellReference, $cellValue) { * @return mixed * @throws PHPExcel_Calculation_Exception */ - public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) { + public function _calculateFormulaValue($formula, $cellID = null, PHPExcel_Cell $pCell = null) + { $cellValue = null; // Basic validation that this is indeed a formula // We simply return the cell value if not $formula = trim($formula); - if ($formula{0} != '=') return self::_wrapResult($formula); + if ($formula{0} != '=') { + return self::_wrapResult($formula); + } $formula = ltrim(substr($formula, 1)); - if (!isset($formula{0})) return self::_wrapResult($formula); + if (!isset($formula{0})) { + return self::_wrapResult($formula); + } - $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; - $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; + $pCellParent = ($pCell !== null) ? $pCell->getWorksheet() : null; + $wsTitle = ($pCellParent !== null) ? $pCellParent->getTitle() : "\x00Wrk"; $wsCellReference = $wsTitle . '!' . $cellID; - if (($cellID !== NULL) && ($this->getValueFromCache($wsCellReference, $cellValue))) { + if (($cellID !== null) && ($this->getValueFromCache($wsCellReference, $cellValue))) { return $cellValue; } @@ -2414,13 +2460,13 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC $this->_cyclicReferenceStack->pop(); // Save to calculation cache - if ($cellID !== NULL) { + if ($cellID !== null) { $this->saveValueToCache($wsCellReference, $cellValue); } // Return the calculated value return $cellValue; - } // function _calculateFormulaValue() + } /** @@ -2435,34 +2481,35 @@ public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pC * 1 = shrink to fit * 2 = extend to fit */ - private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) { + private static function _checkMatrixOperands(&$operand1, &$operand2, $resize = 1) + { // Examine each of the two operands, and turn them into an array if they aren't one already // Note that this function should only be called if one or both of the operand is already an array if (!is_array($operand1)) { - list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2); - $operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1)); + list($matrixRows, $matrixColumns) = self::_getMatrixDimensions($operand2); + $operand1 = array_fill(0, $matrixRows, array_fill(0, $matrixColumns, $operand1)); $resize = 0; } elseif (!is_array($operand2)) { - list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1); - $operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2)); + list($matrixRows, $matrixColumns) = self::_getMatrixDimensions($operand1); + $operand2 = array_fill(0, $matrixRows, array_fill(0, $matrixColumns, $operand2)); $resize = 0; } - list($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1); - list($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2); + list($matrix1Rows, $matrix1Columns) = self::_getMatrixDimensions($operand1); + list($matrix2Rows, $matrix2Columns) = self::_getMatrixDimensions($operand2); if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { $resize = 1; } if ($resize == 2) { // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger - self::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + self::_resizeMatricesExtend($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); } elseif ($resize == 1) { // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller - self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + self::_resizeMatricesShrink($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); } - return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); - } // function _checkMatrixOperands() + return array( $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); + } /** @@ -2471,11 +2518,12 @@ private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) * @param mixed &$matrix matrix operand * @return array An array comprising the number of rows, and number of columns */ - public static function _getMatrixDimensions(&$matrix) { + public static function _getMatrixDimensions(&$matrix) + { $matrixRows = count($matrix); $matrixColumns = 0; - foreach($matrix as $rowKey => $rowValue) { - $matrixColumns = max(count($rowValue),$matrixColumns); + foreach ($matrix as $rowKey => $rowValue) { + $matrixColumns = max(count($rowValue), $matrixColumns); if (!is_array($rowValue)) { $matrix[$rowKey] = array($rowValue); } else { @@ -2483,8 +2531,8 @@ public static function _getMatrixDimensions(&$matrix) { } } $matrix = array_values($matrix); - return array($matrixRows,$matrixColumns); - } // function _getMatrixDimensions() + return array($matrixRows, $matrixColumns); + } /** @@ -2497,7 +2545,8 @@ public static function _getMatrixDimensions(&$matrix) { * @param integer $matrix2Rows Row size of second matrix operand * @param integer $matrix2Columns Column size of second matrix operand */ - private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + private static function _resizeMatricesShrink(&$matrix1, &$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns) + { if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { if ($matrix2Rows < $matrix1Rows) { for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { @@ -2527,7 +2576,7 @@ private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$ } } } - } // function _resizeMatricesShrink() + } /** @@ -2540,7 +2589,8 @@ private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$ * @param integer $matrix2Rows Row size of second matrix operand * @param integer $matrix2Columns Column size of second matrix operand */ - private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + private static function _resizeMatricesExtend(&$matrix1, &$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns) + { if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { if ($matrix2Columns < $matrix1Columns) { for ($i = 0; $i < $matrix2Rows; ++$i) { @@ -2574,7 +2624,7 @@ private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$ } } } - } // function _resizeMatricesExtend() + } /** @@ -2583,7 +2633,8 @@ private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$ * @param mixed $value First matrix operand * @return mixed */ - private function _showValue($value) { + private function _showValue($value) + { if ($this->_debugLog->getWriteDebugLog()) { $testArray = PHPExcel_Calculation_Functions::flattenArray($value); if (count($testArray) == 1) { @@ -2593,23 +2644,23 @@ private function _showValue($value) { if (is_array($value)) { $returnMatrix = array(); $pad = $rpad = ', '; - foreach($value as $row) { + foreach ($value as $row) { if (is_array($row)) { - $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row)); + $returnMatrix[] = implode($pad, array_map(array($this, '_showValue'), $row)); $rpad = '; '; } else { $returnMatrix[] = $this->_showValue($row); } } - return '{ '.implode($rpad,$returnMatrix).' }'; - } elseif(is_string($value) && (trim($value,'"') == $value)) { + return '{ '.implode($rpad, $returnMatrix).' }'; + } elseif (is_string($value) && (trim($value, '"') == $value)) { return '"'.$value.'"'; - } elseif(is_bool($value)) { + } elseif (is_bool($value)) { return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; } } return PHPExcel_Calculation_Functions::flattenSingleValue($value); - } // function _showValue() + } /** @@ -2618,22 +2669,23 @@ private function _showValue($value) { * @param mixed $value First matrix operand * @return mixed */ - private function _showTypeDetails($value) { + private function _showTypeDetails($value) + { if ($this->_debugLog->getWriteDebugLog()) { $testArray = PHPExcel_Calculation_Functions::flattenArray($value); if (count($testArray) == 1) { $value = array_pop($testArray); } - if ($value === NULL) { + if ($value === null) { return 'a NULL value'; } elseif (is_float($value)) { $typeString = 'a floating point number'; - } elseif(is_int($value)) { + } elseif (is_int($value)) { $typeString = 'an integer number'; - } elseif(is_bool($value)) { + } elseif (is_bool($value)) { $typeString = 'a boolean'; - } elseif(is_array($value)) { + } elseif (is_array($value)) { $typeString = 'a matrix'; } else { if ($value == '') { @@ -2646,39 +2698,40 @@ private function _showTypeDetails($value) { } return $typeString.' with a value of '.$this->_showValue($value); } - } // function _showTypeDetails() + } - private function _convertMatrixReferences($formula) { - static $matrixReplaceFrom = array('{',';','}'); - static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))'); + private function _convertMatrixReferences($formula) + { + static $matrixReplaceFrom = array('{', ';', '}'); + static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(', '),MKMATRIX(', '))'); // Convert any Excel matrix references to the MKMATRIX() function - if (strpos($formula,'{') !== FALSE) { + if (strpos($formula, '{') !== false) { // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators - if (strpos($formula,'"') !== FALSE) { + if (strpos($formula, '"') !== false) { // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded // the formula - $temp = explode('"',$formula); + $temp = explode('"', $formula); // Open and Closed counts used for trapping mismatched braces in the formula $openCount = $closeCount = 0; - $i = FALSE; - foreach($temp as &$value) { + $i = false; + foreach ($temp as &$value) { // Only count/replace in alternating array entries if ($i = !$i) { - $openCount += substr_count($value,'{'); - $closeCount += substr_count($value,'}'); - $value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value); + $openCount += substr_count($value, '{'); + $closeCount += substr_count($value, '}'); + $value = str_replace($matrixReplaceFrom, $matrixReplaceTo, $value); } } unset($value); // Then rebuild the formula string - $formula = implode('"',$temp); + $formula = implode('"', $temp); } else { // If there's no quoted strings, then we do a simple count/replace - $openCount = substr_count($formula,'{'); - $closeCount = substr_count($formula,'}'); - $formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula); + $openCount = substr_count($formula, '{'); + $closeCount = substr_count($formula, '}'); + $formula = str_replace($matrixReplaceFrom, $matrixReplaceTo, $formula); } // Trap for mismatched braces and trigger an appropriate error if ($openCount < $closeCount) { @@ -2697,12 +2750,13 @@ private function _convertMatrixReferences($formula) { } return $formula; - } // function _convertMatrixReferences() + } - private static function _mkMatrix() { + private static function _mkMatrix() + { return func_get_args(); - } // function _mkMatrix() + } // Binary Operators @@ -2719,7 +2773,7 @@ private static function _mkMatrix() { // Comparison (Boolean) Operators // These operators work on two values, but always return a boolean result - private static $_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE); + private static $_comparisonOperators = array('>' => true, '<' => true, '=' => true, '>=' => true, '<=' => true, '<>' => true); // Operator Precedence // This list includes all valid operators, whether binary (including boolean) or unary (such as %) @@ -2737,14 +2791,15 @@ private static function _mkMatrix() { ); // Convert infix to postfix notation - private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { - if (($formula = $this->_convertMatrixReferences(trim($formula))) === FALSE) { - return FALSE; + private function _parseFormula($formula, PHPExcel_Cell $pCell = null) + { + if (($formula = $this->_convertMatrixReferences(trim($formula))) === false) { + return false; } // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), // so we store the parent worksheet so that we can re-attach it when necessary - $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + $pCellParent = ($pCell !== null) ? $pCell->getWorksheet() : null; $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION. '|'.self::CALCULATION_REGEXP_CELLREF. @@ -2759,16 +2814,16 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { $index = 0; $stack = new PHPExcel_Calculation_Token_Stack; $output = array(); - $expectingOperator = FALSE; // We use this test in syntax-checking the expression to determine when a + $expectingOperator = false; // We use this test in syntax-checking the expression to determine when a // - is a negation or + is a positive operator rather than an operation - $expectingOperand = FALSE; // We use this test in syntax-checking the expression to determine whether an operand + $expectingOperand = false; // We use this test in syntax-checking the expression to determine whether an operand // should be null in a function call // The guts of the lexical parser // Loop through the formula extracting each operator and operand in turn - while(TRUE) { -//echo 'Assessing Expression '.substr($formula, $index),PHP_EOL; + while (true) { +//echo 'Assessing Expression '.substr($formula, $index), PHP_EOL; $opCharacter = $formula{$index}; // Get the first character of the value at the current index position -//echo 'Initial character of expression block is '.$opCharacter,PHP_EOL; +//echo 'Initial character of expression block is '.$opCharacter, PHP_EOL; if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) { $opCharacter .= $formula{++$index}; //echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL; @@ -2780,100 +2835,103 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { //var_dump($match); if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus? -//echo 'Element is a Negation operator',PHP_EOL; - $stack->push('Unary Operator','~'); // Put a negation on the stack +//echo 'Element is a Negation operator', PHP_EOL; + $stack->push('Unary Operator', '~'); // Put a negation on the stack ++$index; // and drop the negation symbol } elseif ($opCharacter == '%' && $expectingOperator) { -//echo 'Element is a Percentage operator',PHP_EOL; - $stack->push('Unary Operator','%'); // Put a percentage on the stack +//echo 'Element is a Percentage operator', PHP_EOL; + $stack->push('Unary Operator', '%'); // Put a percentage on the stack ++$index; } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded? -//echo 'Element is a Positive number, not Plus operator',PHP_EOL; +//echo 'Element is a Positive number, not Plus operator', PHP_EOL; ++$index; // Drop the redundant plus symbol } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? -//echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL; - while($stack->count() > 0 && +//echo 'Element with value '.$opCharacter.' is an Operator', PHP_EOL; + while ($stack->count() > 0 && ($o2 = $stack->last()) && isset(self::$_operators[$o2['value']]) && @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } - $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack + $stack->push('Binary Operator', $opCharacter); // Finally put our current operator onto the stack ++$index; - $expectingOperator = FALSE; + $expectingOperator = false; } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis? -//echo 'Element is a Closing bracket',PHP_EOL; - $expectingOperand = FALSE; +//echo 'Element is a Closing bracket', PHP_EOL; + $expectingOperand = false; while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( - if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"'); - else $output[] = $o2; + if ($o2 === null) { + return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"'); + } else { + $output[] = $o2; + } } $d = $stack->last(2); if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function? $functionName = $matches[1]; // Get the function name -//echo 'Closed Function is '.$functionName,PHP_EOL; +//echo 'Closed Function is '.$functionName, PHP_EOL; $d = $stack->pop(); $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack) //if ($argumentCount == 0) { -// echo 'With no arguments',PHP_EOL; +// echo 'With no arguments', PHP_EOL; //} elseif ($argumentCount == 1) { -// echo 'With 1 argument',PHP_EOL; +// echo 'With 1 argument', PHP_EOL; //} else { -// echo 'With '.$argumentCount.' arguments',PHP_EOL; +// echo 'With '.$argumentCount.' arguments', PHP_EOL; //} $output[] = $d; // Dump the argument count on the output $output[] = $stack->pop(); // Pop the function and push onto the output if (isset(self::$_controlFunctions[$functionName])) { -//echo 'Built-in function '.$functionName,PHP_EOL; +//echo 'Built-in function '.$functionName, PHP_EOL; $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount']; $functionCall = self::$_controlFunctions[$functionName]['functionCall']; } elseif (isset(self::$_PHPExcelFunctions[$functionName])) { -//echo 'PHPExcel function '.$functionName,PHP_EOL; +//echo 'PHPExcel function '.$functionName, PHP_EOL; $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount']; $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; } else { // did we somehow push a non-function on the stack? this should never happen return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack"); } // Check the argument count - $argumentCountError = FALSE; + $argumentCountError = false; if (is_numeric($expectedArgumentCount)) { if ($expectedArgumentCount < 0) { -//echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount),PHP_EOL; +//echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount), PHP_EOL; if ($argumentCount > abs($expectedArgumentCount)) { - $argumentCountError = TRUE; + $argumentCountError = true; $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount); } } else { -//echo '$expectedArgumentCount is numeric '.$expectedArgumentCount,PHP_EOL; +//echo '$expectedArgumentCount is numeric '.$expectedArgumentCount, PHP_EOL; if ($argumentCount != $expectedArgumentCount) { - $argumentCountError = TRUE; + $argumentCountError = true; $expectedArgumentCountString = $expectedArgumentCount; } } } elseif ($expectedArgumentCount != '*') { - $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch); + $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/', $expectedArgumentCount, $argMatch); //print_r($argMatch); //echo PHP_EOL; switch ($argMatch[2]) { - case '+' : + case '+': if ($argumentCount < $argMatch[1]) { - $argumentCountError = TRUE; + $argumentCountError = true; $expectedArgumentCountString = $argMatch[1].' or more '; } break; - case '-' : + case '-': if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) { - $argumentCountError = TRUE; + $argumentCountError = true; $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3]; } break; - case ',' : + case ',': if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) { - $argumentCountError = TRUE; + $argumentCountError = true; $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3]; } break; @@ -2886,25 +2944,29 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { ++$index; } elseif ($opCharacter == ',') { // Is this the separator for function arguments? -//echo 'Element is a Function argument separator',PHP_EOL; +//echo 'Element is a Function argument separator', PHP_EOL; while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( - if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,"); - else $output[] = $o2; // pop the argument expression stuff and push onto the output + if ($o2 === null) { + return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + } else { + $output[] = $o2; // pop the argument expression stuff and push onto the output + } } // If we've a comma when we're expecting an operand, then what we actually have is a null operand; // so push a null onto the stack if (($expectingOperand) || (!$expectingOperator)) { - $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => null); } // make sure there was a function $d = $stack->last(2); - if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) + if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + } $d = $stack->pop(); - $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count + $stack->push($d['type'], ++$d['value'], $d['reference']); // increment the argument count $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again - $expectingOperator = FALSE; - $expectingOperand = TRUE; + $expectingOperator = false; + $expectingOperand = true; ++$index; } elseif ($opCharacter == '(' && !$expectingOperator) { @@ -2913,28 +2975,28 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { ++$index; } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number? - $expectingOperator = TRUE; - $expectingOperand = FALSE; + $expectingOperator = true; + $expectingOperand = false; $val = $match[1]; $length = strlen($val); // echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />'; if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { - $val = preg_replace('/\s/u','',$val); + $val = preg_replace('/\s/u', '', $val); // echo 'Element '.$val.' is a Function<br />'; if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function $stack->push('Function', strtoupper($val)); $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch); if ($ax) { $stack->push('Operand Count for Function '.strtoupper($val).')', 0); - $expectingOperator = TRUE; + $expectingOperator = true; } else { $stack->push('Operand Count for Function '.strtoupper($val).')', 1); - $expectingOperator = FALSE; + $expectingOperator = false; } $stack->push('Brace', '('); } else { // it's a var w/ implicit multiplication - $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL); + $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => null); } } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) { // echo 'Element '.$val.' is a Cell reference<br />'; @@ -2967,38 +3029,42 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { if ($testPrevOp['value'] == ':') { $startRowColRef = $output[count($output)-1]['value']; $rangeWS1 = ''; - if (strpos('!',$startRowColRef) !== FALSE) { - list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef); + if (strpos('!', $startRowColRef) !== false) { + list($rangeWS1, $startRowColRef) = explode('!', $startRowColRef); + } + if ($rangeWS1 != '') { + $rangeWS1 .= '!'; } - if ($rangeWS1 != '') $rangeWS1 .= '!'; $rangeWS2 = $rangeWS1; - if (strpos('!',$val) !== FALSE) { - list($rangeWS2,$val) = explode('!',$val); + if (strpos('!', $val) !== false) { + list($rangeWS2, $val) = explode('!', $val); + } + if ($rangeWS2 != '') { + $rangeWS2 .= '!'; } - if ($rangeWS2 != '') $rangeWS2 .= '!'; if ((is_integer($startRowColRef)) && (ctype_digit($val)) && ($startRowColRef <= 1048576) && ($val <= 1048576)) { // Row range - $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007 + $endRowColRef = ($pCellParent !== null) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007 $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef; $val = $rangeWS2.$endRowColRef.$val; } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) && (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) { // Column range - $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007 + $endRowColRef = ($pCellParent !== null) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007 $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1'; $val = $rangeWS2.$val.$endRowColRef; } } - $localeConstant = FALSE; + $localeConstant = false; if ($opCharacter == '"') { // echo 'Element is a String<br />'; // UnEscape any quotes within the string - $val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val))); + $val = self::_wrapResult(str_replace('""', '"', self::_unwrapResult($val))); } elseif (is_numeric($val)) { // echo 'Element is a Number<br />'; - if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { + if ((strpos($val, '.') !== false) || (stripos($val, 'e') !== false) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { // echo 'Casting '.$val.' to float<br />'; $val = (float) $val; } else { @@ -3009,12 +3075,14 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { $excelConstant = trim(strtoupper($val)); // echo 'Element '.$excelConstant.' is an Excel Constant<br />'; $val = self::$_ExcelConstants[$excelConstant]; - } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) { + } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== false) { // echo 'Element '.$localeConstant.' is an Excel Constant<br />'; $val = self::$_ExcelConstants[$localeConstant]; } - $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL); - if ($localeConstant) { $details['localeValue'] = $localeConstant; } + $details = array('type' => 'Value', 'value' => $val, 'reference' => null); + if ($localeConstant) { + $details['localeValue'] = $localeConstant; + } $output[] = $details; } $index += $length; @@ -3023,9 +3091,9 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { ++$index; } elseif ($opCharacter == ')') { // miscellaneous error checking if ($expectingOperand) { - $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); - $expectingOperand = FALSE; - $expectingOperator = TRUE; + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => null); + $expectingOperand = false; + $expectingOperator = true; } else { return $this->_raiseFormulaError("Formula Error: Unexpected ')'"); } @@ -3058,31 +3126,32 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) && ($output[count($output)-1]['type'] == 'Cell Reference')) { // echo 'Element is an Intersect Operator<br />'; - while($stack->count() > 0 && + while ($stack->count() > 0 && ($o2 = $stack->last()) && isset(self::$_operators[$o2['value']]) && @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } - $stack->push('Binary Operator','|'); // Put an Intersect Operator on the stack - $expectingOperator = FALSE; + $stack->push('Binary Operator', '|'); // Put an Intersect Operator on the stack + $expectingOperator = false; } } } - while (($op = $stack->pop()) !== NULL) { // pop everything off the stack and push onto output - if ((is_array($op) && $op['value'] == '(') || ($op === '(')) + while (($op = $stack->pop()) !== null) { // pop everything off the stack and push onto output + if ((is_array($op) && $op['value'] == '(') || ($op === '(')) { return $this->_raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced + } $output[] = $op; } return $output; - } // function _parseFormula() + } private static function _dataTestReference(&$operandData) { $operand = $operandData['value']; - if (($operandData['reference'] === NULL) && (is_array($operand))) { + if (($operandData['reference'] === null) && (is_array($operand))) { $rKeys = array_keys($operand); $rowKey = array_shift($rKeys); $cKeys = array_keys(array_keys($operand[$rowKey])); @@ -3095,13 +3164,16 @@ private static function _dataTestReference(&$operandData) } // evaluate postfix notation - private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) { - if ($tokens == FALSE) return FALSE; + private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCell = null) + { + if ($tokens == false) { + return false; + } // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection), // so we store the parent cell collection so that we can re-attach it when necessary - $pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; - $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null; + $pCellWorksheet = ($pCell !== null) ? $pCell->getWorksheet() : null; + $pCellParent = ($pCell !== null) ? $pCell->getParent() : null; $stack = new PHPExcel_Calculation_Token_Stack; // Loop through each token in turn @@ -3114,8 +3186,12 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel if (isset(self::$_binaryOperators[$token])) { // echo 'Token is a binary operator<br />'; // We must have two operands, error if we don't - if (($operand2Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); - if (($operand1Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + if (($operand2Data = $stack->pop()) === null) { + return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + } + if (($operand1Data = $stack->pop()) === null) { + return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + } $operand1 = self::_dataTestReference($operand1Data); $operand2 = self::_dataTestReference($operand2Data); @@ -3130,29 +3206,29 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // Process the operation in the appropriate manner switch ($token) { // Comparison (Boolean) Operators - case '>' : // Greater than - case '<' : // Less than - case '>=' : // Greater than or Equal to - case '<=' : // Less than or Equal to - case '=' : // Equality - case '<>' : // Inequality - $this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack); + case '>': // Greater than + case '<': // Less than + case '>=': // Greater than or Equal to + case '<=': // Less than or Equal to + case '=': // Equality + case '<>': // Inequality + $this->_executeBinaryComparisonOperation($cellID, $operand1, $operand2, $token, $stack); break; // Binary Operators - case ':' : // Range + case ':': // Range $sheet1 = $sheet2 = ''; - if (strpos($operand1Data['reference'],'!') !== FALSE) { - list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']); + if (strpos($operand1Data['reference'], '!') !== false) { + list($sheet1, $operand1Data['reference']) = explode('!', $operand1Data['reference']); } else { - $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : ''; + $sheet1 = ($pCellParent !== null) ? $pCellWorksheet->getTitle() : ''; } - if (strpos($operand2Data['reference'],'!') !== FALSE) { - list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']); + if (strpos($operand2Data['reference'], '!') !== false) { + list($sheet2, $operand2Data['reference']) = explode('!', $operand2Data['reference']); } else { $sheet2 = $sheet1; } if ($sheet1 == $sheet2) { - if ($operand1Data['reference'] === NULL) { + if ($operand1Data['reference'] === null) { if ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) { $operand1Data['reference'] = $pCell->getColumn().$operand1Data['value']; } elseif (trim($operand1Data['reference']) == '') { @@ -3161,7 +3237,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $operand1Data['reference'] = $operand1Data['value'].$pCell->getRow(); } } - if ($operand2Data['reference'] === NULL) { + if ($operand2Data['reference'] === null) { if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) { $operand2Data['reference'] = $pCell->getColumn().$operand2Data['value']; } elseif (trim($operand2Data['reference']) == '') { @@ -3171,41 +3247,40 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } } - $oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference'])); + $oData = array_merge(explode(':', $operand1Data['reference']), explode(':', $operand2Data['reference'])); $oCol = $oRow = array(); - foreach($oData as $oDatum) { + foreach ($oData as $oDatum) { $oCR = PHPExcel_Cell::coordinateFromString($oDatum); $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1; $oRow[] = $oCR[1]; } $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); - if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE); + if ($pCellParent !== null) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), false); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } - $stack->push('Cell Reference',$cellValue,$cellRef); + $stack->push('Cell Reference', $cellValue, $cellRef); } else { - $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL); + $stack->push('Error', PHPExcel_Calculation_Functions::REF(), null); } - break; - case '+' : // Addition - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack); + case '+': // Addition + $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'plusEquals', $stack); break; - case '-' : // Subtraction - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack); + case '-': // Subtraction + $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'minusEquals', $stack); break; - case '*' : // Multiplication - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack); + case '*': // Multiplication + $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'arrayTimesEquals', $stack); break; - case '/' : // Division - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack); + case '/': // Division + $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'arrayRightDivide', $stack); break; - case '^' : // Exponential - $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack); + case '^': // Exponential + $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'power', $stack); break; - case '&' : // Concatenation + case '&': // Concatenation // If either of the operands is a matrix, we need to treat them both as matrices // (converting the other operand to a matrix if need be); then perform the required // matrix operation @@ -3217,7 +3292,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } if ((is_array($operand1)) || (is_array($operand2))) { // Ensure that both operands are arrays/matrices - self::_checkMatrixOperands($operand1,$operand2,2); + self::_checkMatrixOperands($operand1, $operand2, 2); try { // Convert operand 1 from a PHP array to a matrix $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); @@ -3229,31 +3304,33 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $result = '#VALUE!'; } } else { - $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"'; + $result = '"'.str_replace('""', '"', self::_unwrapResult($operand1, '"').self::_unwrapResult($operand2, '"')).'"'; } $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - $stack->push('Value',$result); + $stack->push('Value', $result); break; - case '|' : // Intersect - $rowIntersect = array_intersect_key($operand1,$operand2); + case '|': // Intersect + $rowIntersect = array_intersect_key($operand1, $operand2); $cellIntersect = $oCol = $oRow = array(); - foreach(array_keys($rowIntersect) as $row) { + foreach (array_keys($rowIntersect) as $row) { $oRow[] = $row; - foreach($rowIntersect[$row] as $col => $data) { + foreach ($rowIntersect[$row] as $col => $data) { $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1; - $cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]); + $cellIntersect[$row] = array_intersect_key($operand1[$row], $operand2[$row]); } } $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); - $stack->push('Value',$cellIntersect,$cellRef); + $stack->push('Value', $cellIntersect, $cellRef); break; } // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on } elseif (($token === '~') || ($token === '%')) { // echo 'Token is a unary operator<br />'; - if (($arg = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + if (($arg = $stack->pop()) === null) { + return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + } $arg = $arg['value']; if ($token === '~') { // echo 'Token is a negation operator<br />'; @@ -3265,7 +3342,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $multiplier = 0.01; } if (is_array($arg)) { - self::_checkMatrixOperands($arg,$multiplier,2); + self::_checkMatrixOperands($arg, $multiplier, 2); try { $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg); $matrixResult = $matrix1->arrayTimesEquals($multiplier); @@ -3275,32 +3352,32 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel $result = '#VALUE!'; } $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); - $stack->push('Value',$result); + $stack->push('Value', $result); } else { - $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack); + $this->_executeNumericBinaryOperation($cellID, $multiplier, $arg, '*', 'arrayTimesEquals', $stack); } } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { - $cellRef = NULL; + $cellRef = null; // echo 'Element '.$token.' is a Cell reference<br />'; if (isset($matches[8])) { // echo 'Reference is a Range of cells<br />'; - if ($pCell === NULL) { + if ($pCell === null) { // We can't access the range, so return a REF error $cellValue = PHPExcel_Calculation_Functions::REF(); } else { $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10]; if ($matches[2] > '') { - $matches[2] = trim($matches[2],"\"'"); - if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { + $matches[2] = trim($matches[2], "\"'"); + if ((strpos($matches[2], '[') !== false) || (strpos($matches[2], ']') !== false)) { // It's a Reference to an external workbook (not currently supported) return $this->_raiseFormulaError('Unable to access External Workbook'); } - $matches[2] = trim($matches[2],"\"'"); + $matches[2] = trim($matches[2], "\"'"); // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); - if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); + if ($pCellParent !== null) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), false); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } @@ -3309,8 +3386,8 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } else { // echo '$cellRef='.$cellRef.' in current worksheet<br />'; $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet'); - if ($pCellParent !== NULL) { - $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); + if ($pCellParent !== null) { + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, false); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } @@ -3319,26 +3396,26 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel } } else { // echo 'Reference is a single Cell<br />'; - if ($pCell === NULL) { + if ($pCell === null) { // We can't access the cell, so return a REF error $cellValue = PHPExcel_Calculation_Functions::REF(); } else { $cellRef = $matches[6].$matches[7]; if ($matches[2] > '') { - $matches[2] = trim($matches[2],"\"'"); - if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { + $matches[2] = trim($matches[2], "\"'"); + if ((strpos($matches[2], '[') !== false) || (strpos($matches[2], ']') !== false)) { // It's a Reference to an external workbook (not currently supported) return $this->_raiseFormulaError('Unable to access External Workbook'); } // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); - if ($pCellParent !== NULL) { + if ($pCellParent !== null) { $cellSheet = $this->_workbook->getSheetByName($matches[2]); if ($cellSheet && $cellSheet->cellExists($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), false); $pCell->attach($pCellParent); } else { - $cellValue = NULL; + $cellValue = null; } } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); @@ -3349,16 +3426,16 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // echo '$cellRef='.$cellRef.' in current worksheet<br />'; $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet'); if ($pCellParent->isDataSet($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, false); $pCell->attach($pCellParent); } else { - $cellValue = NULL; + $cellValue = null; } $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); } } } - $stack->push('Value',$cellValue,$cellRef); + $stack->push('Value', $cellValue, $cellRef); // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) { @@ -3388,16 +3465,22 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel if (($passByReference) && (isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) && (self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) { - if ($arg['reference'] === NULL) { + if ($arg['reference'] === null) { $args[] = $cellID; - if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($cellID); } + if ($functionName != 'MKMATRIX') { + $argArrayVals[] = $this->_showValue($cellID); + } } else { $args[] = $arg['reference']; - if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['reference']); } + if ($functionName != 'MKMATRIX') { + $argArrayVals[] = $this->_showValue($arg['reference']); + } } } else { $args[] = self::_unwrapResult($arg['value']); - if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['value']); } + if ($functionName != 'MKMATRIX') { + $argArrayVals[] = $this->_showValue($arg['value']); + } } } // Reverse the order of the arguments @@ -3412,7 +3495,7 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel if ($functionName != 'MKMATRIX') { if ($this->_debugLog->getWriteDebugLog()) { krsort($argArrayVals); - $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); + $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ', PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); } } // Process each argument in turn, building the return value as an array @@ -3425,37 +3508,36 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // if (is_array($args)) { // foreach($args as $arg) { // $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); -// $r = call_user_func_array($functionCall,$arg); +// $r = call_user_func_array($functionCall, $arg); // $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); // $result[$row][] = $r; // } // ++$row; // } else { // $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); -// $r = call_user_func_array($functionCall,$args); +// $r = call_user_func_array($functionCall, $args); // $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); // $result[] = $r; // } // } // } else { // Process the argument with the appropriate function call - if ($passCellReference) { - $args[] = $pCell; - } - if (strpos($functionCall,'::') !== FALSE) { - $result = call_user_func_array(explode('::',$functionCall),$args); - } else { - foreach($args as &$arg) { - $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg); - } - unset($arg); - $result = call_user_func_array($functionCall,$args); + if ($passCellReference) { + $args[] = $pCell; + } + if (strpos($functionCall, '::') !== false) { + $result = call_user_func_array(explode('::', $functionCall), $args); + } else { + foreach ($args as &$arg) { + $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg); } -// } + unset($arg); + $result = call_user_func_array($functionCall, $args); + } if ($functionName != 'MKMATRIX') { $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); } - $stack->push('Value',self::_wrapResult($result)); + $stack->push('Value', self::_wrapResult($result)); } } else { @@ -3463,28 +3545,30 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel if (isset(self::$_ExcelConstants[strtoupper($token)])) { $excelConstant = strtoupper($token); // echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />'; - $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]); + $stack->push('Constant Value', self::$_ExcelConstants[$excelConstant]); $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); - } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { + } elseif ((is_numeric($token)) || ($token === null) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { // echo 'Token is a number, boolean, string, null or an Excel error<br />'; - $stack->push('Value',$token); + $stack->push('Value', $token); // if the token is a named range, push the named range name onto the stack } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) { // echo 'Token is a named range<br />'; $namedRange = $matches[6]; // echo 'Named Range is '.$namedRange.'<br />'; $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange); - $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE); + $cellValue = $this->extractNamedRange($namedRange, ((null !== $pCell) ? $pCellWorksheet : null), false); $pCell->attach($pCellParent); $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); - $stack->push('Named Range',$cellValue,$namedRange); + $stack->push('Named Range', $cellValue, $namedRange); } else { return $this->_raiseFormulaError("undefined variable '$token'"); } } } // when we're out of tokens, the stack should have a single element, the final result - if ($stack->count() != 1) return $this->_raiseFormulaError("internal error"); + if ($stack->count() != 1) { + return $this->_raiseFormulaError("internal error"); + } $output = $stack->pop(); $output = $output['value']; @@ -3492,10 +3576,11 @@ private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCel // return array_shift(PHPExcel_Calculation_Functions::flattenArray($output)); // } return $output; - } // function _processTokenStack() + } - private function _validateBinaryOperand($cellID, &$operand, &$stack) { + private function _validateBinaryOperand($cellID, &$operand, &$stack) + { if (is_array($operand)) { if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { do { @@ -3507,51 +3592,56 @@ private function _validateBinaryOperand($cellID, &$operand, &$stack) { if (is_string($operand)) { // We only need special validations for the operand if it is a string // Start by stripping off the quotation marks we use to identify true excel string values internally - if ($operand > '' && $operand{0} == '"') { $operand = self::_unwrapResult($operand); } + if ($operand > '' && $operand{0} == '"') { + $operand = self::_unwrapResult($operand); + } // If the string is a numeric value, we treat it as a numeric, so no further testing if (!is_numeric($operand)) { // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations if ($operand > '' && $operand{0} == '#') { $stack->push('Value', $operand); $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand)); - return FALSE; + return false; } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations $stack->push('Value', '#VALUE!'); $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); - return FALSE; + return false; } } } // return a true if the value of the operand is one that we can use in normal binary operations - return TRUE; - } // function _validateBinaryOperand() + return true; + } - private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) { + private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays = false) + { // If we're dealing with matrix operations, we want a matrix result if ((is_array($operand1)) || (is_array($operand2))) { $result = array(); if ((is_array($operand1)) && (!is_array($operand2))) { - foreach($operand1 as $x => $operandData) { + foreach ($operand1 as $x => $operandData) { $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); - $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack); + $this->_executeBinaryComparisonOperation($cellID, $operandData, $operand2, $operation, $stack); $r = $stack->pop(); $result[$x] = $r['value']; } } elseif ((!is_array($operand1)) && (is_array($operand2))) { - foreach($operand2 as $x => $operandData) { + foreach ($operand2 as $x => $operandData) { $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); - $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack); + $this->_executeBinaryComparisonOperation($cellID, $operand1, $operandData, $operation, $stack); $r = $stack->pop(); $result[$x] = $r['value']; } } else { - if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } - foreach($operand1 as $x => $operandData) { + if (!$recursingArrays) { + self::_checkMatrixOperands($operand1, $operand2, 2); + } + foreach ($operand1 as $x => $operandData) { $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); - $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); + $this->_executeBinaryComparisonOperation($cellID, $operandData, $operand2[$x], $operation, $stack, true); $r = $stack->pop(); $result[$x] = $r['value']; } @@ -3559,21 +3649,23 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 // Log the result details $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack - $stack->push('Array',$result); - return TRUE; + $stack->push('Array', $result); + return true; } // Simple validate the two operands if they are string values - if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); } - if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); } + if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { + $operand1 = self::_unwrapResult($operand1); + } + if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { + $operand2 = self::_unwrapResult($operand2); + } // Use case insensitive comparaison if not OpenOffice mode - if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) - { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { if (is_string($operand1)) { $operand1 = strtoupper($operand1); } - if (is_string($operand2)) { $operand2 = strtoupper($operand2); } @@ -3640,7 +3732,7 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 // Log the result details $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack - $stack->push('Value',$result); + $stack->push('Value', $result); return true; } @@ -3658,10 +3750,15 @@ private function strcmpLowercaseFirst($str1, $str2) return strcmp($inversedStr1, $inversedStr2); } - private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { + private function _executeNumericBinaryOperation($cellID, $operand1, $operand2, $operation, $matrixFunction, &$stack) + { // Validate the two operands - if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; - if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; + if (!$this->_validateBinaryOperand($cellID, $operand1, $stack)) { + return false; + } + if (!$this->_validateBinaryOperand($cellID, $operand2, $stack)) { + return false; + } // If either of the operands is a matrix, we need to treat them both as matrices // (converting the other operand to a matrix if need be); then perform the required @@ -3682,7 +3779,7 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope } } else { if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) && - ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || + ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) { $result = PHPExcel_Calculation_Functions::VALUE(); } else { @@ -3704,9 +3801,9 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope case '/': if ($operand2 == 0) { // Trap for Divide by Zero error - $stack->push('Value','#DIV/0!'); + $stack->push('Value', '#DIV/0!'); $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); - return FALSE; + return false; } else { $result = $operand1 / $operand2; } @@ -3722,18 +3819,21 @@ private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$ope // Log the result details $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); // And push the result onto the stack - $stack->push('Value',$result); - return TRUE; - } // function _executeNumericBinaryOperation() + $stack->push('Value', $result); + return true; + } // trigger an error, but nicely, if need be - protected function _raiseFormulaError($errorMessage) { + protected function _raiseFormulaError($errorMessage) + { $this->formulaError = $errorMessage; $this->_cyclicReferenceStack->clear(); - if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); + if (!$this->suppressFormulaErrors) { + throw new PHPExcel_Calculation_Exception($errorMessage); + } trigger_error($errorMessage, E_USER_ERROR); - } // function _raiseFormulaError() + } /** @@ -3745,20 +3845,21 @@ protected function _raiseFormulaError($errorMessage) { * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. * @throws PHPExcel_Calculation_Exception */ - public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { + public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = null, $resetLog = true) + { // Return value $returnValue = array (); -// echo 'extractCellRange('.$pRange.')',PHP_EOL; - if ($pSheet !== NULL) { +// echo 'extractCellRange('.$pRange.')', PHP_EOL; + if ($pSheet !== null) { $pSheetName = $pSheet->getTitle(); // echo 'Passed sheet name is '.$pSheetName.PHP_EOL; // echo 'Range reference is '.$pRange.PHP_EOL; - if (strpos ($pRange, '!') !== false) { -// echo '$pRange reference includes sheet reference',PHP_EOL; - list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); -// echo 'New sheet name is '.$pSheetName,PHP_EOL; -// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + if (strpos($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference', PHP_EOL; + list($pSheetName, $pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName, PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange, PHP_EOL; $pSheet = $this->_workbook->getSheetByName($pSheetName); } @@ -3767,31 +3868,30 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = N $pRange = $pSheetName.'!'.$pRange; if (!isset($aReferences[1])) { // Single cell in range - sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow); - $cellValue = NULL; + sscanf($aReferences[0], '%[A-Z]%d', $currentCol, $currentRow); + $cellValue = null; if ($pSheet->cellExists($aReferences[0])) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); } else { - $returnValue[$currentRow][$currentCol] = NULL; + $returnValue[$currentRow][$currentCol] = null; } } else { // Extract cell data for all cells in the range foreach ($aReferences as $reference) { // Extract range - sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow); - $cellValue = NULL; + sscanf($reference, '%[A-Z]%d', $currentCol, $currentRow); + $cellValue = null; if ($pSheet->cellExists($reference)) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); } else { - $returnValue[$currentRow][$currentCol] = NULL; + $returnValue[$currentRow][$currentCol] = null; } } } } - // Return return $returnValue; - } // function extractCellRange() + } /** @@ -3803,26 +3903,27 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = N * @param boolean $resetLog Flag indicating whether calculation log should be reset or not * @throws PHPExcel_Calculation_Exception */ - public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { + public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = null, $resetLog = true) + { // Return value $returnValue = array (); // echo 'extractNamedRange('.$pRange.')<br />'; - if ($pSheet !== NULL) { + if ($pSheet !== null) { $pSheetName = $pSheet->getTitle(); // echo 'Current sheet name is '.$pSheetName.'<br />'; // echo 'Range reference is '.$pRange.'<br />'; - if (strpos ($pRange, '!') !== false) { -// echo '$pRange reference includes sheet reference',PHP_EOL; - list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); -// echo 'New sheet name is '.$pSheetName,PHP_EOL; -// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + if (strpos($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference', PHP_EOL; + list($pSheetName, $pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName, PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange, PHP_EOL; $pSheet = $this->_workbook->getSheetByName($pSheetName); } // Named range? $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet); - if ($namedRange !== NULL) { + if ($namedRange !== null) { $pSheet = $namedRange->getWorksheet(); // echo 'Named Range '.$pRange.' ('; $pRange = $namedRange->getRange(); @@ -3830,7 +3931,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = // Convert row and column references if (ctype_alpha($splitRange[0][0])) { $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow(); - } elseif(ctype_digit($splitRange[0][0])) { + } elseif (ctype_digit($splitRange[0][0])) { $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1]; } // echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />'; @@ -3851,24 +3952,24 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = // var_dump($aReferences); if (!isset($aReferences[1])) { // Single cell (or single column or row) in range - list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); - $cellValue = NULL; + list($currentCol, $currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); + $cellValue = null; if ($pSheet->cellExists($aReferences[0])) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); } else { - $returnValue[$currentRow][$currentCol] = NULL; + $returnValue[$currentRow][$currentCol] = null; } } else { // Extract cell data for all cells in the range foreach ($aReferences as $reference) { // Extract range - list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference); + list($currentCol, $currentRow) = PHPExcel_Cell::coordinateFromString($reference); // echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />'; - $cellValue = NULL; + $cellValue = null; if ($pSheet->cellExists($reference)) { $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); } else { - $returnValue[$currentRow][$currentCol] = NULL; + $returnValue[$currentRow][$currentCol] = null; } } } @@ -3876,9 +3977,8 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = // echo '<br />'; } - // Return return $returnValue; - } // function extractNamedRange() + } /** @@ -3887,14 +3987,15 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = * @param string $pFunction Function Name * @return boolean */ - public function isImplemented($pFunction = '') { - $pFunction = strtoupper ($pFunction); + public function isImplemented($pFunction = '') + { + $pFunction = strtoupper($pFunction); if (isset(self::$_PHPExcelFunctions[$pFunction])) { return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); } else { - return FALSE; + return false; } - } // function isImplemented() + } /** @@ -3902,22 +4003,22 @@ public function isImplemented($pFunction = '') { * * @return array of PHPExcel_Calculation_Function */ - public function listFunctions() { - // Return value + public function listFunctions() + { $returnValue = array(); - // Loop functions - foreach(self::$_PHPExcelFunctions as $functionName => $function) { + + foreach (self::$_PHPExcelFunctions as $functionName => $function) { if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { - $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'], - $functionName, - $function['functionCall'] - ); + $returnValue[$functionName] = new PHPExcel_Calculation_Function( + $function['category'], + $functionName, + $function['functionCall'] + ); } } - // Return return $returnValue; - } // function listFunctions() + } /** @@ -3925,27 +4026,25 @@ public function listFunctions() { * * @return array */ - public function listAllFunctionNames() { + public function listAllFunctionNames() + { return array_keys(self::$_PHPExcelFunctions); - } // function listAllFunctionNames() + } /** * Get a list of implemented Excel function names * * @return array */ - public function listFunctionNames() { - // Return value + public function listFunctionNames() + { $returnValue = array(); - // Loop functions - foreach(self::$_PHPExcelFunctions as $functionName => $function) { + foreach (self::$_PHPExcelFunctions as $functionName => $function) { if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { $returnValue[] = $functionName; } } - // Return return $returnValue; - } // function listFunctionNames() - -} // class PHPExcel_Calculation + } +} diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 4ca7e5321..5250cba55 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -585,7 +585,7 @@ public static function coordinateFromString($pCoordinateString = 'A1') { if (preg_match("/^([$]?[A-Z]{1,3})([$]?\d{1,7})$/", $pCoordinateString, $matches)) { return array($matches[1],$matches[2]); - } elseif ((strpos($pCoordinateString,':') !== false) || (strpos($pCoordinateString,',') !== false)) { + } elseif ((strpos($pCoordinateString, ':') !== false) || (strpos($pCoordinateString, ',') !== false)) { throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); } elseif ($pCoordinateString == '') { throw new PHPExcel_Exception('Cell coordinate can not be zero-length string'); @@ -868,7 +868,7 @@ public static function extractAllCellReferencesInRange($pRange = 'A1') $cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange))); foreach ($cellBlocks as $cellBlock) { // Single cell? - if (strpos($cellBlock,':') === false && strpos($cellBlock,',') === false) { + if (strpos($cellBlock, ':') === false && strpos($cellBlock, ',') === false) { $returnValue[] = $cellBlock; continue; } diff --git a/Classes/PHPExcel/Chart/Axis.php b/Classes/PHPExcel/Chart/Axis.php index 8b5d1d54d..b032bf4b7 100644 --- a/Classes/PHPExcel/Chart/Axis.php +++ b/Classes/PHPExcel/Chart/Axis.php @@ -179,8 +179,7 @@ public function getAxisNumberSourceLinked() public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = null, $horizontal_crosses = null, $axis_orientation = null, $major_tmt = null, $minor_tmt = null, $minimum = null, $maximum = null, $major_unit = null, $minor_unit = null) { $this->_axis_options['axis_labels'] = (string) $axis_labels; - ($horizontal_crosses_value !== null) - ? $this->_axis_options['horizontal_crosses_value'] = (string) $horizontal_crosses_value : null; + ($horizontal_crosses_value !== null) ? $this->_axis_options['horizontal_crosses_value'] = (string) $horizontal_crosses_value : null; ($horizontal_crosses !== null) ? $this->_axis_options['horizontal_crosses'] = (string) $horizontal_crosses : null; ($axis_orientation !== null) ? $this->_axis_options['orientation'] = (string) $axis_orientation : null; ($major_tmt !== null) ? $this->_axis_options['major_tick_mark'] = (string) $major_tmt : null; @@ -265,306 +264,282 @@ public function getLineProperty($property) return $this->_line_properties[$property]; } - /** - * Set Line Style Properties - * - * @param float $line_width - * @param string $compound_type - * @param string $dash_type - * @param string $cap_type - * @param string $join_type - * @param string $head_arrow_type - * @param string $head_arrow_size - * @param string $end_arrow_type - * @param string $end_arrow_size - * - */ - - public function setLineStyleProperties($line_width = null, $compound_type = null, $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) { - (!is_null($line_width)) ? $this->_line_style_properties['width'] = $this->getExcelPointsWidth((float) $line_width) - : null; - (!is_null($compound_type)) ? $this->_line_style_properties['compound'] = (string) $compound_type : null; - (!is_null($dash_type)) ? $this->_line_style_properties['dash'] = (string) $dash_type : null; - (!is_null($cap_type)) ? $this->_line_style_properties['cap'] = (string) $cap_type : null; - (!is_null($join_type)) ? $this->_line_style_properties['join'] = (string) $join_type : null; - (!is_null($head_arrow_type)) ? $this->_line_style_properties['arrow']['head']['type'] = (string) $head_arrow_type - : null; - (!is_null($head_arrow_size)) ? $this->_line_style_properties['arrow']['head']['size'] = (string) $head_arrow_size - : null; - (!is_null($end_arrow_type)) ? $this->_line_style_properties['arrow']['end']['type'] = (string) $end_arrow_type - : null; - (!is_null($end_arrow_size)) ? $this->_line_style_properties['arrow']['end']['size'] = (string) $end_arrow_size - : null; - } - - /** - * Get Line Style Property - * - * @param array|string $elements - * - * @return string - */ - - public function getLineStyleProperty($elements) - { - return $this->getArrayElementsValue($this->_line_style_properties, $elements); - } - - /** - * Get Line Style Arrow Excel Width - * - * @param string $arrow - * - * @return string - */ - - public function getLineStyleArrowWidth($arrow) - { - return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'w'); - } - - /** - * Get Line Style Arrow Excel Length - * - * @param string $arrow - * - * @return string - */ - - public function getLineStyleArrowLength($arrow) - { - return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'len'); - } - - /** - * Set Shadow Properties - * - * @param int $shadow_presets - * @param string $sh_color_value - * @param string $sh_color_type - * @param string $sh_color_alpha - * @param float $sh_blur - * @param int $sh_angle - * @param float $sh_distance - * - */ - - public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_color_type = null, $sh_color_alpha = null, $sh_blur = null, $sh_angle = null, $sh_distance = null) { - $this - ->_setShadowPresetsProperties((int) $sh_presets) - ->_setShadowColor( - is_null($sh_color_value) ? $this->_shadow_properties['color']['value'] : $sh_color_value - , is_null($sh_color_alpha) ? (int) $this->_shadow_properties['color']['alpha'] : $sh_color_alpha - , is_null($sh_color_type) ? $this->_shadow_properties['color']['type'] : $sh_color_type) - ->_setShadowBlur($sh_blur) - ->_setShadowAngle($sh_angle) - ->_setShadowDistance($sh_distance); - } - - /** - * Set Shadow Color - * - * @param int $shadow_presets - * - * @return PHPExcel_Chart_Axis - */ - - private function _setShadowPresetsProperties($shadow_presets) { - $this->_shadow_properties['presets'] = $shadow_presets; - $this->_setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); - - return $this; - } - - /** - * Set Shadow Properties from Maped Values - * - * @param array $properties_map - * @param * $reference - * - * @return PHPExcel_Chart_Axis - */ - - private function _setShadowProperiesMapValues(array $properties_map, &$reference = null) { - $base_reference = $reference; - foreach ($properties_map as $property_key => $property_val) { - if (is_array($property_val)) { - if ($reference === null) { - $reference = & $this->_shadow_properties[$property_key]; - } else { - $reference = & $reference[$property_key]; + /** + * Set Line Style Properties + * + * @param float $line_width + * @param string $compound_type + * @param string $dash_type + * @param string $cap_type + * @param string $join_type + * @param string $head_arrow_type + * @param string $head_arrow_size + * @param string $end_arrow_type + * @param string $end_arrow_size + * + */ + public function setLineStyleProperties($line_width = null, $compound_type = null, $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) { + (!is_null($line_width)) ? $this->_line_style_properties['width'] = $this->getExcelPointsWidth((float) $line_width) : null; + (!is_null($compound_type)) ? $this->_line_style_properties['compound'] = (string) $compound_type : null; + (!is_null($dash_type)) ? $this->_line_style_properties['dash'] = (string) $dash_type : null; + (!is_null($cap_type)) ? $this->_line_style_properties['cap'] = (string) $cap_type : null; + (!is_null($join_type)) ? $this->_line_style_properties['join'] = (string) $join_type : null; + (!is_null($head_arrow_type)) ? $this->_line_style_properties['arrow']['head']['type'] = (string) $head_arrow_type : null; + (!is_null($head_arrow_size)) ? $this->_line_style_properties['arrow']['head']['size'] = (string) $head_arrow_size : null; + (!is_null($end_arrow_type)) ? $this->_line_style_properties['arrow']['end']['type'] = (string) $end_arrow_type : null; + (!is_null($end_arrow_size)) ? $this->_line_style_properties['arrow']['end']['size'] = (string) $end_arrow_size : null; + } + + /** + * Get Line Style Property + * + * @param array|string $elements + * + * @return string + */ + public function getLineStyleProperty($elements) + { + return $this->getArrayElementsValue($this->_line_style_properties, $elements); + } + + /** + * Get Line Style Arrow Excel Width + * + * @param string $arrow + * + * @return string + */ + public function getLineStyleArrowWidth($arrow) + { + return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'w'); + } + + /** + * Get Line Style Arrow Excel Length + * + * @param string $arrow + * + * @return string + */ + public function getLineStyleArrowLength($arrow) + { + return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'len'); + } + + /** + * Set Shadow Properties + * + * @param int $shadow_presets + * @param string $sh_color_value + * @param string $sh_color_type + * @param string $sh_color_alpha + * @param float $sh_blur + * @param int $sh_angle + * @param float $sh_distance + * + */ + public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_color_type = null, $sh_color_alpha = null, $sh_blur = null, $sh_angle = null, $sh_distance = null) { + $this->_setShadowPresetsProperties((int) $sh_presets) + ->_setShadowColor( + is_null($sh_color_value) ? $this->_shadow_properties['color']['value'] : $sh_color_value + , is_null($sh_color_alpha) ? (int) $this->_shadow_properties['color']['alpha'] : $sh_color_alpha + , is_null($sh_color_type) ? $this->_shadow_properties['color']['type'] : $sh_color_type) + ->_setShadowBlur($sh_blur) + ->_setShadowAngle($sh_angle) + ->_setShadowDistance($sh_distance); + } + + /** + * Set Shadow Color + * + * @param int $shadow_presets + * + * @return PHPExcel_Chart_Axis + */ + private function _setShadowPresetsProperties($shadow_presets) { + $this->_shadow_properties['presets'] = $shadow_presets; + $this->_setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); + + return $this; + } + + /** + * Set Shadow Properties from Maped Values + * + * @param array $properties_map + * @param * $reference + * + * @return PHPExcel_Chart_Axis + */ + private function _setShadowProperiesMapValues(array $properties_map, &$reference = null) { + $base_reference = $reference; + foreach ($properties_map as $property_key => $property_val) { + if (is_array($property_val)) { + if ($reference === null) { + $reference = & $this->_shadow_properties[$property_key]; + } else { + $reference = & $reference[$property_key]; + } + $this->_setShadowProperiesMapValues($property_val, $reference); + } else { + if ($base_reference === null) { + $this->_shadow_properties[$property_key] = $property_val; + } else { + $reference[$property_key] = $property_val; + } + } + } + + return $this; + } + + /** + * Set Shadow Color + * + * @param string $color + * @param int $alpha + * @param string $type + * + * @return PHPExcel_Chart_Axis + */ + private function _setShadowColor($color, $alpha, $type) { + $this->_shadow_properties['color'] = $this->setColorProperties($color, $alpha, $type); + + return $this; + } + + /** + * Set Shadow Blur + * + * @param float $blur + * + * @return PHPExcel_Chart_Axis + */ + private function _setShadowBlur($blur) { + if ($blur !== null) { + $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur); } - $this->_setShadowProperiesMapValues($property_val, $reference); - } else { - if ($base_reference === null) { - $this->_shadow_properties[$property_key] = $property_val; - } else { - $reference[$property_key] = $property_val; + + return $this; + } + + /** + * Set Shadow Angle + * + * @param int $angle + * + * @return PHPExcel_Chart_Axis + */ + private function _setShadowAngle($angle) { + if ($angle !== null) { + $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle); } - } + + return $this; } - return $this; - } - - /** - * Set Shadow Color - * - * @param string $color - * @param int $alpha - * @param string $type - * - * @return PHPExcel_Chart_Axis - */ - - private function _setShadowColor($color, $alpha, $type) { - $this->_shadow_properties['color'] = $this->setColorProperties($color, $alpha, $type); - - return $this; - } - - /** - * Set Shadow Blur - * - * @param float $blur - * - * @return PHPExcel_Chart_Axis - */ - - private function _setShadowBlur($blur) { - if ($blur !== null) { - $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur); + /** + * Set Shadow Distance + * + * @param float $distance + * + * @return PHPExcel_Chart_Axis + */ + private function _setShadowDistance($distance) { + if ($distance !== null) { + $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance); + } + + return $this; } - return $this; - } + /** + * Get Glow Property + * + * @param float $size + * @param string $color_value + * @param int $color_alpha + * @param string $color_type + */ + public function getShadowProperty($elements) { + return $this->getArrayElementsValue($this->_shadow_properties, $elements); + } - /** - * Set Shadow Angle - * - * @param int $angle - * - * @return PHPExcel_Chart_Axis - */ + /** + * Set Glow Properties + * + * @param float $size + * @param string $color_value + * @param int $color_alpha + * @param string $color_type + */ + public function setGlowProperties($size, $color_value = null, $color_alpha = null, $color_type = null) { + $this->_setGlowSize($size) + ->_setGlowColor( + is_null($color_value) ? $this->_glow_properties['color']['value'] : $color_value + , is_null($color_alpha) ? (int) $this->_glow_properties['color']['alpha'] : $color_alpha + , is_null($color_type) ? $this->_glow_properties['color']['type'] : $color_type + ); + } - private function _setShadowAngle($angle) { - if ($angle !== null) { - $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle); + /** + * Get Glow Property + * + * @param array|string $property + * + * @return string + */ + public function getGlowProperty($property) { + return $this->getArrayElementsValue($this->_glow_properties, $property); } - return $this; - } + /** + * Set Glow Color + * + * @param float $size + * + * @return PHPExcel_Chart_Axis + */ + private function _setGlowSize($size) { + if (!is_null($size)) { + $this->_glow_properties['size'] = $this->getExcelPointsWidth($size); + } + + return $this; + } - /** - * Set Shadow Distance - * - * @param float $distance - * - * @return PHPExcel_Chart_Axis - */ + /** + * Set Glow Color + * + * @param string $color + * @param int $alpha + * @param string $type + * + * @return PHPExcel_Chart_Axis + */ + private function _setGlowColor($color, $alpha, $type) { + $this->_glow_properties['color'] = $this->setColorProperties($color, $alpha, $type); - private function _setShadowDistance($distance) { - if ($distance !== null) { - $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance); + return $this; } - return $this; - } - - /** - * Get Glow Property - * - * @param float $size - * @param string $color_value - * @param int $color_alpha - * @param string $color_type - */ - - public function getShadowProperty($elements) { - return $this->getArrayElementsValue($this->_shadow_properties, $elements); - } - - /** - * Set Glow Properties - * - * @param float $size - * @param string $color_value - * @param int $color_alpha - * @param string $color_type - */ - - public function setGlowProperties($size, $color_value = null, $color_alpha = null, $color_type = null) { - $this - ->_setGlowSize($size) - ->_setGlowColor( - is_null($color_value) ? $this->_glow_properties['color']['value'] : $color_value - , is_null($color_alpha) ? (int) $this->_glow_properties['color']['alpha'] : $color_alpha - , is_null($color_type) ? $this->_glow_properties['color']['type'] : $color_type); - } - - /** - * Get Glow Property - * - * @param array|string $property - * - * @return string - */ - - public function getGlowProperty($property) { - return $this->getArrayElementsValue($this->_glow_properties, $property); - } - - /** - * Set Glow Color - * - * @param float $size - * - * @return PHPExcel_Chart_Axis - */ - - private function _setGlowSize($size) { - if (!is_null($size)) { - $this->_glow_properties['size'] = $this->getExcelPointsWidth($size); + /** + * Set Soft Edges Size + * + * @param float $size + */ + public function setSoftEdges($size) { + if (!is_null($size)) { + $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size); + } } - return $this; - } - - /** - * Set Glow Color - * - * @param string $color - * @param int $alpha - * @param string $type - * - * @return PHPExcel_Chart_Axis - */ - - private function _setGlowColor($color, $alpha, $type) { - $this->_glow_properties['color'] = $this->setColorProperties($color, $alpha, $type); - - return $this; - } - - /** - * Set Soft Edges Size - * - * @param float $size - */ - - public function setSoftEdges($size) { - if (!is_null($size)) { - $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size); + /** + * Get Soft Edges Size + * + * @return string + */ + public function getSoftEdgesSize() { + return $this->_soft_edges['size']; } - } - - /** - * Get Soft Edges Size - * - * @return string - */ - - public function getSoftEdgesSize() { - return $this->_soft_edges['size']; - } -} \ No newline at end of file +} diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index c5ddc0955..617c8a917 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -371,21 +371,20 @@ public function setSmoothLine($smoothLine = true) public function refresh(PHPExcel_Worksheet $worksheet) { - foreach($this->_plotValues as $plotValues) { + foreach ($this->_plotValues as $plotValues) { if ($plotValues !== null) { $plotValues->refresh($worksheet, true); } } - foreach($this->_plotLabel as $plotValues) { + foreach ($this->_plotLabel as $plotValues) { if ($plotValues !== null) { $plotValues->refresh($worksheet, true); } } - foreach($this->_plotCategory as $plotValues) { + foreach ($this->_plotCategory as $plotValues) { if ($plotValues !== null) { $plotValues->refresh($worksheet, false); } } } - } From 66169af8981470be7f9f484811aef839265ad924 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 14 May 2015 23:50:28 +0100 Subject: [PATCH 369/467] PSR-2 coding standards for the charting --- Classes/PHPExcel/Chart/DataSeriesValues.php | 58 +- Classes/PHPExcel/Chart/GridLines.php | 631 ++++++++++---------- 2 files changed, 364 insertions(+), 325 deletions(-) diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index 01f0010eb..df88d6222 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -96,7 +96,8 @@ public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSourc * * @return string */ - public function getDataType() { + public function getDataType() + { return $this->_dataType; } @@ -111,7 +112,8 @@ public function getDataType() { * Normally used for chart data values * @return PHPExcel_Chart_DataSeriesValues */ - public function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) { + public function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) + { if (!in_array($dataType, self::$_dataTypeValues)) { throw new PHPExcel_Chart_Exception('Invalid datatype for chart data series values'); } @@ -125,7 +127,8 @@ public function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) { * * @return string */ - public function getDataSource() { + public function getDataSource() + { return $this->_dataSource; } @@ -135,7 +138,8 @@ public function getDataSource() { * @param string $dataSource * @return PHPExcel_Chart_DataSeriesValues */ - public function setDataSource($dataSource = null, $refreshDataValues = true) { + public function setDataSource($dataSource = null, $refreshDataValues = true) + { $this->_dataSource = $dataSource; if ($refreshDataValues) { @@ -150,7 +154,8 @@ public function setDataSource($dataSource = null, $refreshDataValues = true) { * * @return string */ - public function getPointMarker() { + public function getPointMarker() + { return $this->_marker; } @@ -160,7 +165,8 @@ public function getPointMarker() { * @param string $marker * @return PHPExcel_Chart_DataSeriesValues */ - public function setPointMarker($marker = null) { + public function setPointMarker($marker = null) + { $this->_marker = $marker; return $this; @@ -171,7 +177,8 @@ public function setPointMarker($marker = null) { * * @return string */ - public function getFormatCode() { + public function getFormatCode() + { return $this->_formatCode; } @@ -181,7 +188,8 @@ public function getFormatCode() { * @param string $formatCode * @return PHPExcel_Chart_DataSeriesValues */ - public function setFormatCode($formatCode = null) { + public function setFormatCode($formatCode = null) + { $this->_formatCode = $formatCode; return $this; @@ -192,7 +200,8 @@ public function setFormatCode($formatCode = null) { * * @return integer */ - public function getPointCount() { + public function getPointCount() + { return $this->_pointCount; } @@ -201,7 +210,8 @@ public function getPointCount() { * * @return boolean */ - public function isMultiLevelSeries() { + public function isMultiLevelSeries() + { if (count($this->_dataValues) > 0) { return is_array($this->_dataValues[0]); } @@ -213,7 +223,8 @@ public function isMultiLevelSeries() { * * @return boolean */ - public function multiLevelCount() { + public function multiLevelCount() + { $levelCount = 0; foreach ($this->_dataValues as $dataValueSet) { $levelCount = max($levelCount,count($dataValueSet)); @@ -226,7 +237,8 @@ public function multiLevelCount() { * * @return array of mixed */ - public function getDataValues() { + public function getDataValues() + { return $this->_dataValues; } @@ -235,7 +247,8 @@ public function getDataValues() { * * @return mixed */ - public function getDataValue() { + public function getDataValue() + { $count = count($this->_dataValues); if ($count == 0) { return null; @@ -254,7 +267,8 @@ public function getDataValue() { * FALSE - don't change the value of _dataSource * @return PHPExcel_Chart_DataSeriesValues */ - public function setDataValues($dataValues = array(), $refreshDataSource = TRUE) { + public function setDataValues($dataValues = array(), $refreshDataSource = true) + { $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($dataValues); $this->_pointCount = count($dataValues); @@ -265,17 +279,19 @@ public function setDataValues($dataValues = array(), $refreshDataSource = TRUE) return $this; } - private function _stripNulls($var) { - return $var !== NULL; + private function _stripNulls($var) + { + return $var !== null; } - public function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) { - if ($this->_dataSource !== NULL) { + public function refresh(PHPExcel_Worksheet $worksheet, $flatten = true) + { + if ($this->_dataSource !== null) { $calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent()); $newDataValues = PHPExcel_Calculation::_unwrapResult( $calcEngine->_calculateFormulaValue( '='.$this->_dataSource, - NULL, + null, $worksheet->getCell('A1') ) ); @@ -293,7 +309,7 @@ public function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) { list(, $cellRange) = $cellRange; } - $dimensions = PHPExcel_Cell::rangeDimension(str_replace('$','', $cellRange)); + $dimensions = PHPExcel_Cell::rangeDimension(str_replace('$', '', $cellRange)); if (($dimensions[0] == 1) || ($dimensions[1] == 1)) { $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); } else { @@ -313,7 +329,5 @@ public function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) { } $this->_pointCount = count($this->_dataValues); } - } - } diff --git a/Classes/PHPExcel/Chart/GridLines.php b/Classes/PHPExcel/Chart/GridLines.php index 72cb8e4ed..69d8ed54c 100644 --- a/Classes/PHPExcel/Chart/GridLines.php +++ b/Classes/PHPExcel/Chart/GridLines.php @@ -7,8 +7,8 @@ * Time: 2:36 PM */ -class PHPExcel_Chart_GridLines extends - PHPExcel_Chart_Properties { +class PHPExcel_Chart_GridLines extends PHPExcel_Chart_Properties +{ /** * Properties of Class: @@ -20,333 +20,351 @@ class PHPExcel_Chart_GridLines extends * */ - private - $_object_state = FALSE, - $_line_properties = array( - 'color' => array( - 'type' => self::EXCEL_COLOR_TYPE_STANDARD, - 'value' => NULL, - 'alpha' => 0 - ), - 'style' => array( - 'width' => '9525', - 'compound' => self::LINE_STYLE_COMPOUND_SIMPLE, - 'dash' => self::LINE_STYLE_DASH_SOLID, - 'cap' => self::LINE_STYLE_CAP_FLAT, - 'join' => self::LINE_STYLE_JOIN_BEVEL, - 'arrow' => array( - 'head' => array( - 'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, - 'size' => self::LINE_STYLE_ARROW_SIZE_5 - ), - 'end' => array( - 'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, - 'size' => self::LINE_STYLE_ARROW_SIZE_8 - ), - ) - ) - ), - $_shadow_properties = array( - 'presets' => self::SHADOW_PRESETS_NOSHADOW, - 'effect' => NULL, - 'color' => array( - 'type' => self::EXCEL_COLOR_TYPE_STANDARD, - 'value' => 'black', - 'alpha' => 85, - ), - 'size' => array( - 'sx' => NULL, - 'sy' => NULL, - 'kx' => NULL - ), - 'blur' => NULL, - 'direction' => NULL, - 'distance' => NULL, - 'algn' => NULL, - 'rotWithShape' => NULL - ), - $_glow_properties = array( - 'size' => NULL, - 'color' => array( - 'type' => self::EXCEL_COLOR_TYPE_STANDARD, - 'value' => 'black', - 'alpha' => 40 - ) - ), - $_soft_edges = array( - 'size' => NULL - ); + private $_object_state = false; + + private $_line_properties = array( + 'color' => array( + 'type' => self::EXCEL_COLOR_TYPE_STANDARD, + 'value' => null, + 'alpha' => 0 + ), + 'style' => array( + 'width' => '9525', + 'compound' => self::LINE_STYLE_COMPOUND_SIMPLE, + 'dash' => self::LINE_STYLE_DASH_SOLID, + 'cap' => self::LINE_STYLE_CAP_FLAT, + 'join' => self::LINE_STYLE_JOIN_BEVEL, + 'arrow' => array( + 'head' => array( + 'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, + 'size' => self::LINE_STYLE_ARROW_SIZE_5 + ), + 'end' => array( + 'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, + 'size' => self::LINE_STYLE_ARROW_SIZE_8 + ), + ) + ) + ); + + private $_shadow_properties = array( + 'presets' => self::SHADOW_PRESETS_NOSHADOW, + 'effect' => null, + 'color' => array( + 'type' => self::EXCEL_COLOR_TYPE_STANDARD, + 'value' => 'black', + 'alpha' => 85, + ), + 'size' => array( + 'sx' => null, + 'sy' => null, + 'kx' => null + ), + 'blur' => null, + 'direction' => null, + 'distance' => null, + 'algn' => null, + 'rotWithShape' => null + ); + + private $_glow_properties = array( + 'size' => null, + 'color' => array( + 'type' => self::EXCEL_COLOR_TYPE_STANDARD, + 'value' => 'black', + 'alpha' => 40 + ) + ); + + private $_soft_edges = array( + 'size' => null + ); - /** - * Get Object State - * - * @return bool - */ + /** + * Get Object State + * + * @return bool + */ - public function getObjectState() { - return $this->_object_state; - } + public function getObjectState() + { + return $this->_object_state; + } - /** - * Change Object State to True - * - * @return PHPExcel_Chart_GridLines - */ + /** + * Change Object State to True + * + * @return PHPExcel_Chart_GridLines + */ - private function _activateObject() { - $this->_object_state = TRUE; + private function _activateObject() + { + $this->_object_state = true; - return $this; - } + return $this; + } - /** - * Set Line Color Properties - * - * @param string $value - * @param int $alpha - * @param string $type - */ + /** + * Set Line Color Properties + * + * @param string $value + * @param int $alpha + * @param string $type + */ - public function setLineColorProperties($value, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_STANDARD) { - $this - ->_activateObject() - ->_line_properties['color'] = $this->setColorProperties( - $value, - $alpha, - $type); - } + public function setLineColorProperties($value, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_STANDARD) + { + $this + ->_activateObject() + ->_line_properties['color'] = $this->setColorProperties( + $value, + $alpha, + $type); + } - /** - * Set Line Color Properties - * - * @param float $line_width - * @param string $compound_type - * @param string $dash_type - * @param string $cap_type - * @param string $join_type - * @param string $head_arrow_type - * @param string $head_arrow_size - * @param string $end_arrow_type - * @param string $end_arrow_size - */ + /** + * Set Line Color Properties + * + * @param float $line_width + * @param string $compound_type + * @param string $dash_type + * @param string $cap_type + * @param string $join_type + * @param string $head_arrow_type + * @param string $head_arrow_size + * @param string $end_arrow_type + * @param string $end_arrow_size + */ - public function setLineStyleProperties($line_width = NULL, $compound_type = NULL, $dash_type = NULL, $cap_type = NULL, $join_type = NULL, $head_arrow_type = NULL, $head_arrow_size = NULL, $end_arrow_type = NULL, $end_arrow_size = NULL) { - $this->_activateObject(); - (!is_null($line_width)) - ? $this->_line_properties['style']['width'] = $this->getExcelPointsWidth((float) $line_width) - : NULL; - (!is_null($compound_type)) - ? $this->_line_properties['style']['compound'] = (string) $compound_type - : NULL; - (!is_null($dash_type)) - ? $this->_line_properties['style']['dash'] = (string) $dash_type - : NULL; - (!is_null($cap_type)) - ? $this->_line_properties['style']['cap'] = (string) $cap_type - : NULL; - (!is_null($join_type)) - ? $this->_line_properties['style']['join'] = (string) $join_type - : NULL; - (!is_null($head_arrow_type)) - ? $this->_line_properties['style']['arrow']['head']['type'] = (string) $head_arrow_type - : NULL; - (!is_null($head_arrow_size)) - ? $this->_line_properties['style']['arrow']['head']['size'] = (string) $head_arrow_size - : NULL; - (!is_null($end_arrow_type)) - ? $this->_line_properties['style']['arrow']['end']['type'] = (string) $end_arrow_type - : NULL; - (!is_null($end_arrow_size)) - ? $this->_line_properties['style']['arrow']['end']['size'] = (string) $end_arrow_size - : NULL; - } + public function setLineStyleProperties($line_width = null, $compound_type = null, $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) + { + $this->_activateObject(); + (!is_null($line_width)) + ? $this->_line_properties['style']['width'] = $this->getExcelPointsWidth((float) $line_width) + : null; + (!is_null($compound_type)) + ? $this->_line_properties['style']['compound'] = (string) $compound_type + : null; + (!is_null($dash_type)) + ? $this->_line_properties['style']['dash'] = (string) $dash_type + : null; + (!is_null($cap_type)) + ? $this->_line_properties['style']['cap'] = (string) $cap_type + : null; + (!is_null($join_type)) + ? $this->_line_properties['style']['join'] = (string) $join_type + : null; + (!is_null($head_arrow_type)) + ? $this->_line_properties['style']['arrow']['head']['type'] = (string) $head_arrow_type + : null; + (!is_null($head_arrow_size)) + ? $this->_line_properties['style']['arrow']['head']['size'] = (string) $head_arrow_size + : null; + (!is_null($end_arrow_type)) + ? $this->_line_properties['style']['arrow']['end']['type'] = (string) $end_arrow_type + : null; + (!is_null($end_arrow_size)) + ? $this->_line_properties['style']['arrow']['end']['size'] = (string) $end_arrow_size + : null; + } - /** - * Get Line Color Property - * - * @param string $parameter - * - * @return string - */ + /** + * Get Line Color Property + * + * @param string $parameter + * + * @return string + */ - public function getLineColorProperty($parameter) { - return $this->_line_properties['color'][$parameter]; - } + public function getLineColorProperty($parameter) + { + return $this->_line_properties['color'][$parameter]; + } - /** - * Get Line Style Property - * - * @param array|string $elements - * - * @return string - */ + /** + * Get Line Style Property + * + * @param array|string $elements + * + * @return string + */ - public function getLineStyleProperty($elements) { - return $this->getArrayElementsValue($this->_line_properties['style'], $elements); - } + public function getLineStyleProperty($elements) + { + return $this->getArrayElementsValue($this->_line_properties['style'], $elements); + } - /** - * Set Glow Properties - * - * @param float $size - * @param string $color_value - * @param int $color_alpha - * @param string $color_type - * - */ + /** + * Set Glow Properties + * + * @param float $size + * @param string $color_value + * @param int $color_alpha + * @param string $color_type + * + */ - public function setGlowProperties($size, $color_value = NULL, $color_alpha = NULL, $color_type = NULL) { - $this - ->_activateObject() - ->_setGlowSize($size) - ->_setGlowColor($color_value, $color_alpha, $color_type); - } + public function setGlowProperties($size, $color_value = null, $color_alpha = null, $color_type = null) + { + $this + ->_activateObject() + ->_setGlowSize($size) + ->_setGlowColor($color_value, $color_alpha, $color_type); + } - /** - * Get Glow Color Property - * - * @param string $property - * - * @return string - */ + /** + * Get Glow Color Property + * + * @param string $property + * + * @return string + */ - public function getGlowColor($property) { - return $this->_glow_properties['color'][$property]; - } + public function getGlowColor($property) + { + return $this->_glow_properties['color'][$property]; + } - /** - * Get Glow Size - * - * @return string - */ + /** + * Get Glow Size + * + * @return string + */ - public function getGlowSize() { - return $this->_glow_properties['size']; - } + public function getGlowSize() + { + return $this->_glow_properties['size']; + } - /** - * Set Glow Size - * - * @param float $size - * - * @return PHPExcel_Chart_GridLines - */ + /** + * Set Glow Size + * + * @param float $size + * + * @return PHPExcel_Chart_GridLines + */ - private function _setGlowSize($size) { - $this->_glow_properties['size'] = $this->getExcelPointsWidth((float) $size); + private function _setGlowSize($size) + { + $this->_glow_properties['size'] = $this->getExcelPointsWidth((float) $size); - return $this; - } + return $this; + } - /** - * Set Glow Color - * - * @param string $color - * @param int $alpha - * @param string $type - * - * @return PHPExcel_Chart_GridLines - */ + /** + * Set Glow Color + * + * @param string $color + * @param int $alpha + * @param string $type + * + * @return PHPExcel_Chart_GridLines + */ - private function _setGlowColor($color, $alpha, $type) { - if (!is_null($color)) { - $this->_glow_properties['color']['value'] = (string) $color; - } - if (!is_null($alpha)) { - $this->_glow_properties['color']['alpha'] = $this->getTrueAlpha((int) $alpha); - } - if (!is_null($type)) { - $this->_glow_properties['color']['type'] = (string) $type; - } + private function _setGlowColor($color, $alpha, $type) + { + if (!is_null($color)) { + $this->_glow_properties['color']['value'] = (string) $color; + } + if (!is_null($alpha)) { + $this->_glow_properties['color']['alpha'] = $this->getTrueAlpha((int) $alpha); + } + if (!is_null($type)) { + $this->_glow_properties['color']['type'] = (string) $type; + } - return $this; - } + return $this; + } - /** - * Get Line Style Arrow Parameters - * - * @param string $arrow_selector - * @param string $property_selector - * - * @return string - */ + /** + * Get Line Style Arrow Parameters + * + * @param string $arrow_selector + * @param string $property_selector + * + * @return string + */ - public function getLineStyleArrowParameters($arrow_selector, $property_selector) { - return $this->getLineStyleArrowSize($this->_line_properties['style']['arrow'][$arrow_selector]['size'], $property_selector); - } + public function getLineStyleArrowParameters($arrow_selector, $property_selector) + { + return $this->getLineStyleArrowSize($this->_line_properties['style']['arrow'][$arrow_selector]['size'], $property_selector); + } - /** - * Set Shadow Properties - * - * @param int $sh_presets - * @param string $sh_color_value - * @param string $sh_color_type - * @param int $sh_color_alpha - * @param string $sh_blur - * @param int $sh_angle - * @param float $sh_distance - * - */ + /** + * Set Shadow Properties + * + * @param int $sh_presets + * @param string $sh_color_value + * @param string $sh_color_type + * @param int $sh_color_alpha + * @param string $sh_blur + * @param int $sh_angle + * @param float $sh_distance + * + */ - public function setShadowProperties($sh_presets, $sh_color_value = NULL, $sh_color_type = NULL, $sh_color_alpha = NULL, $sh_blur = NULL, $sh_angle = NULL, $sh_distance = NULL) { - $this - ->_activateObject() - ->_setShadowPresetsProperties((int) $sh_presets) - ->_setShadowColor( - is_null($sh_color_value) ? $this->_shadow_properties['color']['value'] : $sh_color_value - , is_null($sh_color_alpha) ? (int) $this->_shadow_properties['color']['alpha'] - : $this->getTrueAlpha($sh_color_alpha) - , is_null($sh_color_type) ? $this->_shadow_properties['color']['type'] : $sh_color_type) - ->_setShadowBlur($sh_blur) - ->_setShadowAngle($sh_angle) - ->_setShadowDistance($sh_distance); - } + public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_color_type = null, $sh_color_alpha = null, $sh_blur = null, $sh_angle = null, $sh_distance = null) + { + $this + ->_activateObject() + ->_setShadowPresetsProperties((int) $sh_presets) + ->_setShadowColor( + is_null($sh_color_value) ? $this->_shadow_properties['color']['value'] : $sh_color_value + , is_null($sh_color_alpha) ? (int) $this->_shadow_properties['color']['alpha'] + : $this->getTrueAlpha($sh_color_alpha) + , is_null($sh_color_type) ? $this->_shadow_properties['color']['type'] : $sh_color_type) + ->_setShadowBlur($sh_blur) + ->_setShadowAngle($sh_angle) + ->_setShadowDistance($sh_distance); + } - /** - * Set Shadow Presets Properties - * - * @param int $shadow_presets - * - * @return PHPExcel_Chart_GridLines - */ + /** + * Set Shadow Presets Properties + * + * @param int $shadow_presets + * + * @return PHPExcel_Chart_GridLines + */ - private function _setShadowPresetsProperties($shadow_presets) { - $this->_shadow_properties['presets'] = $shadow_presets; - $this->_setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); + private function _setShadowPresetsProperties($shadow_presets) + { + $this->_shadow_properties['presets'] = $shadow_presets; + $this->_setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); - return $this; - } + return $this; + } - /** - * Set Shadow Properties Values - * - * @param array $properties_map - * @param * $reference - * - * @return PHPExcel_Chart_GridLines - */ + /** + * Set Shadow Properties Values + * + * @param array $properties_map + * @param * $reference + * + * @return PHPExcel_Chart_GridLines + */ - private function _setShadowProperiesMapValues(array $properties_map, &$reference = NULL) { - $base_reference = $reference; - foreach ($properties_map as $property_key => $property_val) { - if (is_array($property_val)) { - if ($reference === NULL) { - $reference = & $this->_shadow_properties[$property_key]; - } else { - $reference = & $reference[$property_key]; + private function _setShadowProperiesMapValues(array $properties_map, &$reference = null) + { + $base_reference = $reference; + foreach ($properties_map as $property_key => $property_val) { + if (is_array($property_val)) { + if ($reference === null) { + $reference = & $this->_shadow_properties[$property_key]; + } else { + $reference = & $reference[$property_key]; + } + $this->_setShadowProperiesMapValues($property_val, $reference); + } else { + if ($base_reference === null) { + $this->_shadow_properties[$property_key] = $property_val; + } else { + $reference[$property_key] = $property_val; + } + } } - $this->_setShadowProperiesMapValues($property_val, $reference); - } else { - if ($base_reference === NULL) { - $this->_shadow_properties[$property_key] = $property_val; - } else { - $reference[$property_key] = $property_val; - } - } - } - return $this; - } + return $this; + } /** * Set Shadow Color @@ -356,7 +374,8 @@ private function _setShadowProperiesMapValues(array $properties_map, &$reference * @param string $type * @return PHPExcel_Chart_GridLines */ - private function _setShadowColor($color, $alpha, $type) { + private function _setShadowColor($color, $alpha, $type) + { if (!is_null($color)) { $this->_shadow_properties['color']['value'] = (string) $color; } @@ -377,8 +396,9 @@ private function _setShadowColor($color, $alpha, $type) { * * @return PHPExcel_Chart_GridLines */ - private function _setShadowBlur($blur) { - if ($blur !== NULL) { + private function _setShadowBlur($blur) + { + if ($blur !== null) { $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur); } @@ -392,8 +412,9 @@ private function _setShadowBlur($blur) { * @return PHPExcel_Chart_GridLines */ - private function _setShadowAngle($angle) { - if ($angle !== NULL) { + private function _setShadowAngle($angle) + { + if ($angle !== null) { $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle); } @@ -406,8 +427,9 @@ private function _setShadowAngle($angle) { * @param float $distance * @return PHPExcel_Chart_GridLines */ - private function _setShadowDistance($distance) { - if ($distance !== NULL) { + private function _setShadowDistance($distance) + { + if ($distance !== null) { $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance); } @@ -421,7 +443,8 @@ private function _setShadowDistance($distance) { * @param array $elements * @return string */ - public function getShadowProperty($elements) { + public function getShadowProperty($elements) + { return $this->getArrayElementsValue($this->_shadow_properties, $elements); } @@ -430,7 +453,8 @@ public function getShadowProperty($elements) { * * @param float $size */ - public function setSoftEdgesSize($size) { + public function setSoftEdgesSize($size) + { if (!is_null($size)) { $this->_activateObject(); $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size); @@ -442,7 +466,8 @@ public function setSoftEdgesSize($size) { * * @return string */ - public function getSoftEdgesSize() { + public function getSoftEdgesSize() + { return $this->_soft_edges['size']; } } \ No newline at end of file From e18ba38f16c020fd69bb6b01b5ec9e4aaf3f5b4f Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Fri, 15 May 2015 09:11:18 +0100 Subject: [PATCH 370/467] More psr-2 for charts --- Classes/PHPExcel/Chart/Axis.php | 182 ++++++----- Classes/PHPExcel/Chart/DataSeries.php | 90 +++--- Classes/PHPExcel/Chart/DataSeriesValues.php | 86 +++--- Classes/PHPExcel/Chart/GridLines.php | 137 ++++----- Classes/PHPExcel/Chart/Layout.php | 98 +++--- Classes/PHPExcel/Chart/Legend.php | 82 ++--- Classes/PHPExcel/Chart/PlotArea.php | 22 +- Classes/PHPExcel/Chart/Properties.php | 23 +- Classes/PHPExcel/Chart/Renderer/jpgraph.php | 325 ++++++++++---------- Classes/PHPExcel/Chart/Title.php | 36 +-- 10 files changed, 545 insertions(+), 536 deletions(-) diff --git a/Classes/PHPExcel/Chart/Axis.php b/Classes/PHPExcel/Chart/Axis.php index b032bf4b7..9aeafc6a4 100644 --- a/Classes/PHPExcel/Chart/Axis.php +++ b/Classes/PHPExcel/Chart/Axis.php @@ -14,7 +14,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties * * @var array of mixed */ - private $_axis_number = array( + private $axisNumber = array( 'format' => self::FORMAT_CODE_GENERAL, 'source_linked' => 1 ); @@ -24,7 +24,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties * * @var array of mixed */ - private $_axis_options = array( + private $axisOptions = array( 'minimum' => null, 'maximum' => null, 'major_unit' => null, @@ -42,7 +42,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties * * @var array of mixed */ - private $_fill_properties = array( + private $fillProperties = array( 'type' => self::EXCEL_COLOR_TYPE_ARGB, 'value' => null, 'alpha' => 0 @@ -53,7 +53,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties * * @var array of mixed */ - private $_line_properties = array( + private $lineProperties = array( 'type' => self::EXCEL_COLOR_TYPE_ARGB, 'value' => null, 'alpha' => 0 @@ -64,7 +64,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties * * @var array of mixed */ - private $_line_style_properties = array( + private $lineStyleProperties = array( 'width' => '9525', 'compound' => self::LINE_STYLE_COMPOUND_SIMPLE, 'dash' => self::LINE_STYLE_DASH_SOLID, @@ -87,7 +87,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties * * @var array of mixed */ - private $_shadow_properties = array( + private $shadowProperties = array( 'presets' => self::SHADOW_PRESETS_NOSHADOW, 'effect' => null, 'color' => array( @@ -112,7 +112,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties * * @var array of mixed */ - private $_glow_properties = array( + private $glowProperties = array( 'size' => null, 'color' => array( 'type' => self::EXCEL_COLOR_TYPE_STANDARD, @@ -126,7 +126,7 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties * * @var array of mixed */ - private $_soft_edges = array( + private $softEdges = array( 'size' => null ); @@ -137,8 +137,8 @@ class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties */ public function setAxisNumberProperties($format_code) { - $this->_axis_number['format'] = (string) $format_code; - $this->_axis_number['source_linked'] = 0; + $this->axisNumber['format'] = (string) $format_code; + $this->axisNumber['source_linked'] = 0; } /** @@ -148,7 +148,7 @@ public function setAxisNumberProperties($format_code) */ public function getAxisNumberFormat() { - return $this->_axis_number['format']; + return $this->axisNumber['format']; } /** @@ -158,7 +158,7 @@ public function getAxisNumberFormat() */ public function getAxisNumberSourceLinked() { - return (string) $this->_axis_number['source_linked']; + return (string) $this->axisNumber['source_linked']; } /** @@ -178,17 +178,17 @@ public function getAxisNumberSourceLinked() */ public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = null, $horizontal_crosses = null, $axis_orientation = null, $major_tmt = null, $minor_tmt = null, $minimum = null, $maximum = null, $major_unit = null, $minor_unit = null) { - $this->_axis_options['axis_labels'] = (string) $axis_labels; - ($horizontal_crosses_value !== null) ? $this->_axis_options['horizontal_crosses_value'] = (string) $horizontal_crosses_value : null; - ($horizontal_crosses !== null) ? $this->_axis_options['horizontal_crosses'] = (string) $horizontal_crosses : null; - ($axis_orientation !== null) ? $this->_axis_options['orientation'] = (string) $axis_orientation : null; - ($major_tmt !== null) ? $this->_axis_options['major_tick_mark'] = (string) $major_tmt : null; - ($minor_tmt !== null) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : null; - ($minor_tmt !== null) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : null; - ($minimum !== null) ? $this->_axis_options['minimum'] = (string) $minimum : null; - ($maximum !== null) ? $this->_axis_options['maximum'] = (string) $maximum : null; - ($major_unit !== null) ? $this->_axis_options['major_unit'] = (string) $major_unit : null; - ($minor_unit !== null) ? $this->_axis_options['minor_unit'] = (string) $minor_unit : null; + $this->axisOptions['axis_labels'] = (string) $axis_labels; + ($horizontal_crosses_value !== null) ? $this->axisOptions['horizontal_crosses_value'] = (string) $horizontal_crosses_value : null; + ($horizontal_crosses !== null) ? $this->axisOptions['horizontal_crosses'] = (string) $horizontal_crosses : null; + ($axis_orientation !== null) ? $this->axisOptions['orientation'] = (string) $axis_orientation : null; + ($major_tmt !== null) ? $this->axisOptions['major_tick_mark'] = (string) $major_tmt : null; + ($minor_tmt !== null) ? $this->axisOptions['minor_tick_mark'] = (string) $minor_tmt : null; + ($minor_tmt !== null) ? $this->axisOptions['minor_tick_mark'] = (string) $minor_tmt : null; + ($minimum !== null) ? $this->axisOptions['minimum'] = (string) $minimum : null; + ($maximum !== null) ? $this->axisOptions['maximum'] = (string) $maximum : null; + ($major_unit !== null) ? $this->axisOptions['major_unit'] = (string) $major_unit : null; + ($minor_unit !== null) ? $this->axisOptions['minor_unit'] = (string) $minor_unit : null; } /** @@ -200,7 +200,7 @@ public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value */ public function getAxisOptionsProperty($property) { - return $this->_axis_options[$property]; + return $this->axisOptions[$property]; } /** @@ -224,7 +224,7 @@ public function setAxisOrientation($orientation) */ public function setFillParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) { - $this->_fill_properties = $this->setColorProperties($color, $alpha, $type); + $this->fillProperties = $this->setColorProperties($color, $alpha, $type); } /** @@ -237,7 +237,7 @@ public function setFillParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_ */ public function setLineParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) { - $this->_line_properties = $this->setColorProperties($color, $alpha, $type); + $this->lineProperties = $this->setColorProperties($color, $alpha, $type); } /** @@ -249,7 +249,7 @@ public function setLineParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_ */ public function getFillProperty($property) { - return $this->_fill_properties[$property]; + return $this->fillProperties[$property]; } /** @@ -261,7 +261,7 @@ public function getFillProperty($property) */ public function getLineProperty($property) { - return $this->_line_properties[$property]; + return $this->lineProperties[$property]; } /** @@ -278,16 +278,17 @@ public function getLineProperty($property) * @param string $end_arrow_size * */ - public function setLineStyleProperties($line_width = null, $compound_type = null, $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) { - (!is_null($line_width)) ? $this->_line_style_properties['width'] = $this->getExcelPointsWidth((float) $line_width) : null; - (!is_null($compound_type)) ? $this->_line_style_properties['compound'] = (string) $compound_type : null; - (!is_null($dash_type)) ? $this->_line_style_properties['dash'] = (string) $dash_type : null; - (!is_null($cap_type)) ? $this->_line_style_properties['cap'] = (string) $cap_type : null; - (!is_null($join_type)) ? $this->_line_style_properties['join'] = (string) $join_type : null; - (!is_null($head_arrow_type)) ? $this->_line_style_properties['arrow']['head']['type'] = (string) $head_arrow_type : null; - (!is_null($head_arrow_size)) ? $this->_line_style_properties['arrow']['head']['size'] = (string) $head_arrow_size : null; - (!is_null($end_arrow_type)) ? $this->_line_style_properties['arrow']['end']['type'] = (string) $end_arrow_type : null; - (!is_null($end_arrow_size)) ? $this->_line_style_properties['arrow']['end']['size'] = (string) $end_arrow_size : null; + public function setLineStyleProperties($line_width = null, $compound_type = null, $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) + { + (!is_null($line_width)) ? $this->lineStyleProperties['width'] = $this->getExcelPointsWidth((float) $line_width) : null; + (!is_null($compound_type)) ? $this->lineStyleProperties['compound'] = (string) $compound_type : null; + (!is_null($dash_type)) ? $this->lineStyleProperties['dash'] = (string) $dash_type : null; + (!is_null($cap_type)) ? $this->lineStyleProperties['cap'] = (string) $cap_type : null; + (!is_null($join_type)) ? $this->lineStyleProperties['join'] = (string) $join_type : null; + (!is_null($head_arrow_type)) ? $this->lineStyleProperties['arrow']['head']['type'] = (string) $head_arrow_type : null; + (!is_null($head_arrow_size)) ? $this->lineStyleProperties['arrow']['head']['size'] = (string) $head_arrow_size : null; + (!is_null($end_arrow_type)) ? $this->lineStyleProperties['arrow']['end']['type'] = (string) $end_arrow_type : null; + (!is_null($end_arrow_size)) ? $this->lineStyleProperties['arrow']['end']['size'] = (string) $end_arrow_size : null; } /** @@ -299,7 +300,7 @@ public function setLineStyleProperties($line_width = null, $compound_type = null */ public function getLineStyleProperty($elements) { - return $this->getArrayElementsValue($this->_line_style_properties, $elements); + return $this->getArrayElementsValue($this->lineStyleProperties, $elements); } /** @@ -311,7 +312,7 @@ public function getLineStyleProperty($elements) */ public function getLineStyleArrowWidth($arrow) { - return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'w'); + return $this->getLineStyleArrowSize($this->lineStyleProperties['arrow'][$arrow]['size'], 'w'); } /** @@ -323,7 +324,7 @@ public function getLineStyleArrowWidth($arrow) */ public function getLineStyleArrowLength($arrow) { - return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'len'); + return $this->getLineStyleArrowSize($this->lineStyleProperties['arrow'][$arrow]['size'], 'len'); } /** @@ -338,15 +339,17 @@ public function getLineStyleArrowLength($arrow) * @param float $sh_distance * */ - public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_color_type = null, $sh_color_alpha = null, $sh_blur = null, $sh_angle = null, $sh_distance = null) { - $this->_setShadowPresetsProperties((int) $sh_presets) - ->_setShadowColor( - is_null($sh_color_value) ? $this->_shadow_properties['color']['value'] : $sh_color_value - , is_null($sh_color_alpha) ? (int) $this->_shadow_properties['color']['alpha'] : $sh_color_alpha - , is_null($sh_color_type) ? $this->_shadow_properties['color']['type'] : $sh_color_type) - ->_setShadowBlur($sh_blur) - ->_setShadowAngle($sh_angle) - ->_setShadowDistance($sh_distance); + public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_color_type = null, $sh_color_alpha = null, $sh_blur = null, $sh_angle = null, $sh_distance = null) + { + $this->setShadowPresetsProperties((int) $sh_presets) + ->setShadowColor( + is_null($sh_color_value) ? $this->shadowProperties['color']['value'] : $sh_color_value, + is_null($sh_color_alpha) ? (int) $this->shadowProperties['color']['alpha'] : $sh_color_alpha, + is_null($sh_color_type) ? $this->shadowProperties['color']['type'] : $sh_color_type + ) + ->setShadowBlur($sh_blur) + ->setShadowAngle($sh_angle) + ->setShadowDistance($sh_distance); } /** @@ -356,9 +359,10 @@ public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_col * * @return PHPExcel_Chart_Axis */ - private function _setShadowPresetsProperties($shadow_presets) { - $this->_shadow_properties['presets'] = $shadow_presets; - $this->_setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); + private function setShadowPresetsProperties($shadow_presets) + { + $this->shadowProperties['presets'] = $shadow_presets; + $this->setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); return $this; } @@ -371,19 +375,20 @@ private function _setShadowPresetsProperties($shadow_presets) { * * @return PHPExcel_Chart_Axis */ - private function _setShadowProperiesMapValues(array $properties_map, &$reference = null) { + private function setShadowProperiesMapValues(array $properties_map, &$reference = null) + { $base_reference = $reference; foreach ($properties_map as $property_key => $property_val) { if (is_array($property_val)) { if ($reference === null) { - $reference = & $this->_shadow_properties[$property_key]; + $reference = & $this->shadowProperties[$property_key]; } else { $reference = & $reference[$property_key]; } - $this->_setShadowProperiesMapValues($property_val, $reference); + $this->setShadowProperiesMapValues($property_val, $reference); } else { if ($base_reference === null) { - $this->_shadow_properties[$property_key] = $property_val; + $this->shadowProperties[$property_key] = $property_val; } else { $reference[$property_key] = $property_val; } @@ -402,8 +407,9 @@ private function _setShadowProperiesMapValues(array $properties_map, &$reference * * @return PHPExcel_Chart_Axis */ - private function _setShadowColor($color, $alpha, $type) { - $this->_shadow_properties['color'] = $this->setColorProperties($color, $alpha, $type); + private function setShadowColor($color, $alpha, $type) + { + $this->shadowProperties['color'] = $this->setColorProperties($color, $alpha, $type); return $this; } @@ -415,9 +421,10 @@ private function _setShadowColor($color, $alpha, $type) { * * @return PHPExcel_Chart_Axis */ - private function _setShadowBlur($blur) { + private function setShadowBlur($blur) + { if ($blur !== null) { - $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur); + $this->shadowProperties['blur'] = (string) $this->getExcelPointsWidth($blur); } return $this; @@ -430,9 +437,10 @@ private function _setShadowBlur($blur) { * * @return PHPExcel_Chart_Axis */ - private function _setShadowAngle($angle) { + private function setShadowAngle($angle) + { if ($angle !== null) { - $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle); + $this->shadowProperties['direction'] = (string) $this->getExcelPointsAngle($angle); } return $this; @@ -445,9 +453,10 @@ private function _setShadowAngle($angle) { * * @return PHPExcel_Chart_Axis */ - private function _setShadowDistance($distance) { + private function setShadowDistance($distance) + { if ($distance !== null) { - $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance); + $this->shadowProperties['distance'] = (string) $this->getExcelPointsWidth($distance); } return $this; @@ -461,8 +470,9 @@ private function _setShadowDistance($distance) { * @param int $color_alpha * @param string $color_type */ - public function getShadowProperty($elements) { - return $this->getArrayElementsValue($this->_shadow_properties, $elements); + public function getShadowProperty($elements) + { + return $this->getArrayElementsValue($this->shadowProperties, $elements); } /** @@ -473,12 +483,13 @@ public function getShadowProperty($elements) { * @param int $color_alpha * @param string $color_type */ - public function setGlowProperties($size, $color_value = null, $color_alpha = null, $color_type = null) { - $this->_setGlowSize($size) - ->_setGlowColor( - is_null($color_value) ? $this->_glow_properties['color']['value'] : $color_value - , is_null($color_alpha) ? (int) $this->_glow_properties['color']['alpha'] : $color_alpha - , is_null($color_type) ? $this->_glow_properties['color']['type'] : $color_type + public function setGlowProperties($size, $color_value = null, $color_alpha = null, $color_type = null) + { + $this->setGlowSize($size) + ->setGlowColor( + is_null($color_value) ? $this->glowProperties['color']['value'] : $color_value, + is_null($color_alpha) ? (int) $this->glowProperties['color']['alpha'] : $color_alpha, + is_null($color_type) ? $this->glowProperties['color']['type'] : $color_type ); } @@ -489,8 +500,9 @@ public function setGlowProperties($size, $color_value = null, $color_alpha = nul * * @return string */ - public function getGlowProperty($property) { - return $this->getArrayElementsValue($this->_glow_properties, $property); + public function getGlowProperty($property) + { + return $this->getArrayElementsValue($this->glowProperties, $property); } /** @@ -500,9 +512,10 @@ public function getGlowProperty($property) { * * @return PHPExcel_Chart_Axis */ - private function _setGlowSize($size) { + private function setGlowSize($size) + { if (!is_null($size)) { - $this->_glow_properties['size'] = $this->getExcelPointsWidth($size); + $this->glowProperties['size'] = $this->getExcelPointsWidth($size); } return $this; @@ -517,8 +530,9 @@ private function _setGlowSize($size) { * * @return PHPExcel_Chart_Axis */ - private function _setGlowColor($color, $alpha, $type) { - $this->_glow_properties['color'] = $this->setColorProperties($color, $alpha, $type); + private function setGlowColor($color, $alpha, $type) + { + $this->glowProperties['color'] = $this->setColorProperties($color, $alpha, $type); return $this; } @@ -528,9 +542,10 @@ private function _setGlowColor($color, $alpha, $type) { * * @param float $size */ - public function setSoftEdges($size) { + public function setSoftEdges($size) + { if (!is_null($size)) { - $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size); + $softEdges['size'] = (string) $this->getExcelPointsWidth($size); } } @@ -539,7 +554,8 @@ public function setSoftEdges($size) { * * @return string */ - public function getSoftEdgesSize() { - return $this->_soft_edges['size']; + public function getSoftEdgesSize() + { + return $this->softEdges['size']; } } diff --git a/Classes/PHPExcel/Chart/DataSeries.php b/Classes/PHPExcel/Chart/DataSeries.php index 617c8a917..9ecd543a8 100644 --- a/Classes/PHPExcel/Chart/DataSeries.php +++ b/Classes/PHPExcel/Chart/DataSeries.php @@ -75,90 +75,90 @@ class PHPExcel_Chart_DataSeries * * @var string */ - private $_plotType = null; + private $plotType; /** * Plot Grouping Type * * @var boolean */ - private $_plotGrouping = null; + private $plotGrouping; /** * Plot Direction * * @var boolean */ - private $_plotDirection = null; + private $plotDirection; /** * Plot Style * * @var string */ - private $_plotStyle = null; + private $plotStyle; /** * Order of plots in Series * * @var array of integer */ - private $_plotOrder = array(); + private $plotOrder = array(); /** * Plot Label * * @var array of PHPExcel_Chart_DataSeriesValues */ - private $_plotLabel = array(); + private $plotLabel = array(); /** * Plot Category * * @var array of PHPExcel_Chart_DataSeriesValues */ - private $_plotCategory = array(); + private $plotCategory = array(); /** * Smooth Line * * @var string */ - private $_smoothLine = null; + private $smoothLine; /** * Plot Values * * @var array of PHPExcel_Chart_DataSeriesValues */ - private $_plotValues = array(); + private $plotValues = array(); /** * Create a new PHPExcel_Chart_DataSeries */ public function __construct($plotType = null, $plotGrouping = null, $plotOrder = array(), $plotLabel = array(), $plotCategory = array(), $plotValues = array(), $plotDirection = null, $smoothLine = null, $plotStyle = null) { - $this->_plotType = $plotType; - $this->_plotGrouping = $plotGrouping; - $this->_plotOrder = $plotOrder; + $this->plotType = $plotType; + $this->plotGrouping = $plotGrouping; + $this->plotOrder = $plotOrder; $keys = array_keys($plotValues); - $this->_plotValues = $plotValues; + $this->plotValues = $plotValues; if ((count($plotLabel) == 0) || (is_null($plotLabel[$keys[0]]))) { $plotLabel[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); } - $this->_plotLabel = $plotLabel; + $this->plotLabel = $plotLabel; if ((count($plotCategory) == 0) || (is_null($plotCategory[$keys[0]]))) { $plotCategory[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); } - $this->_plotCategory = $plotCategory; - $this->_smoothLine = $smoothLine; - $this->_plotStyle = $plotStyle; + $this->plotCategory = $plotCategory; + $this->smoothLine = $smoothLine; + $this->plotStyle = $plotStyle; if (is_null($plotDirection)) { $plotDirection = self::DIRECTION_COL; } - $this->_plotDirection = $plotDirection; + $this->plotDirection = $plotDirection; } /** @@ -168,7 +168,7 @@ public function __construct($plotType = null, $plotGrouping = null, $plotOrder = */ public function getPlotType() { - return $this->_plotType; + return $this->plotType; } /** @@ -179,7 +179,7 @@ public function getPlotType() */ public function setPlotType($plotType = '') { - $this->_plotType = $plotType; + $this->plotType = $plotType; return $this; } @@ -190,7 +190,7 @@ public function setPlotType($plotType = '') */ public function getPlotGrouping() { - return $this->_plotGrouping; + return $this->plotGrouping; } /** @@ -201,7 +201,7 @@ public function getPlotGrouping() */ public function setPlotGrouping($groupingType = null) { - $this->_plotGrouping = $groupingType; + $this->plotGrouping = $groupingType; return $this; } @@ -212,7 +212,7 @@ public function setPlotGrouping($groupingType = null) */ public function getPlotDirection() { - return $this->_plotDirection; + return $this->plotDirection; } /** @@ -223,7 +223,7 @@ public function getPlotDirection() */ public function setPlotDirection($plotDirection = null) { - $this->_plotDirection = $plotDirection; + $this->plotDirection = $plotDirection; return $this; } @@ -234,7 +234,7 @@ public function setPlotDirection($plotDirection = null) */ public function getPlotOrder() { - return $this->_plotOrder; + return $this->plotOrder; } /** @@ -244,7 +244,7 @@ public function getPlotOrder() */ public function getPlotLabels() { - return $this->_plotLabel; + return $this->plotLabel; } /** @@ -254,11 +254,11 @@ public function getPlotLabels() */ public function getPlotLabelByIndex($index) { - $keys = array_keys($this->_plotLabel); + $keys = array_keys($this->plotLabel); if (in_array($index, $keys)) { - return $this->_plotLabel[$index]; + return $this->plotLabel[$index]; } elseif (isset($keys[$index])) { - return $this->_plotLabel[$keys[$index]]; + return $this->plotLabel[$keys[$index]]; } return false; } @@ -270,7 +270,7 @@ public function getPlotLabelByIndex($index) */ public function getPlotCategories() { - return $this->_plotCategory; + return $this->plotCategory; } /** @@ -280,11 +280,11 @@ public function getPlotCategories() */ public function getPlotCategoryByIndex($index) { - $keys = array_keys($this->_plotCategory); + $keys = array_keys($this->plotCategory); if (in_array($index, $keys)) { - return $this->_plotCategory[$index]; + return $this->plotCategory[$index]; } elseif (isset($keys[$index])) { - return $this->_plotCategory[$keys[$index]]; + return $this->plotCategory[$keys[$index]]; } return false; } @@ -296,7 +296,7 @@ public function getPlotCategoryByIndex($index) */ public function getPlotStyle() { - return $this->_plotStyle; + return $this->plotStyle; } /** @@ -307,7 +307,7 @@ public function getPlotStyle() */ public function setPlotStyle($plotStyle = null) { - $this->_plotStyle = $plotStyle; + $this->plotStyle = $plotStyle; return $this; } @@ -318,7 +318,7 @@ public function setPlotStyle($plotStyle = null) */ public function getPlotValues() { - return $this->_plotValues; + return $this->plotValues; } /** @@ -328,11 +328,11 @@ public function getPlotValues() */ public function getPlotValuesByIndex($index) { - $keys = array_keys($this->_plotValues); + $keys = array_keys($this->plotValues); if (in_array($index, $keys)) { - return $this->_plotValues[$index]; + return $this->plotValues[$index]; } elseif (isset($keys[$index])) { - return $this->_plotValues[$keys[$index]]; + return $this->plotValues[$keys[$index]]; } return false; } @@ -344,7 +344,7 @@ public function getPlotValuesByIndex($index) */ public function getPlotSeriesCount() { - return count($this->_plotValues); + return count($this->plotValues); } /** @@ -354,7 +354,7 @@ public function getPlotSeriesCount() */ public function getSmoothLine() { - return $this->_smoothLine; + return $this->smoothLine; } /** @@ -365,23 +365,23 @@ public function getSmoothLine() */ public function setSmoothLine($smoothLine = true) { - $this->_smoothLine = $smoothLine; + $this->smoothLine = $smoothLine; return $this; } public function refresh(PHPExcel_Worksheet $worksheet) { - foreach ($this->_plotValues as $plotValues) { + foreach ($this->plotValues as $plotValues) { if ($plotValues !== null) { $plotValues->refresh($worksheet, true); } } - foreach ($this->_plotLabel as $plotValues) { + foreach ($this->plotLabel as $plotValues) { if ($plotValues !== null) { $plotValues->refresh($worksheet, true); } } - foreach ($this->_plotCategory as $plotValues) { + foreach ($this->plotCategory as $plotValues) { if ($plotValues !== null) { $plotValues->refresh($worksheet, false); } diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index df88d6222..23d185deb 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -31,7 +31,7 @@ class PHPExcel_Chart_DataSeriesValues const DATASERIES_TYPE_STRING = 'String'; const DATASERIES_TYPE_NUMBER = 'Number'; - private static $_dataTypeValues = array( + private static $dataTypeValues = array( self::DATASERIES_TYPE_STRING, self::DATASERIES_TYPE_NUMBER, ); @@ -41,42 +41,42 @@ class PHPExcel_Chart_DataSeriesValues * * @var string */ - private $_dataType = null; + private $dataType; /** * Series Data Source * * @var string */ - private $_dataSource = null; + private $dataSource; /** * Format Code * * @var string */ - private $_formatCode = null; + private $formatCode; /** * Series Point Marker * * @var string */ - private $_marker = null; + private $pointMarker; /** * Point Count (The number of datapoints in the dataseries) * * @var integer */ - private $_pointCount = 0; + private $pointCount = 0; /** * Data Values * * @var array of mixed */ - private $_dataValues = array(); + private $dataValues = array(); /** * Create a new PHPExcel_Chart_DataSeriesValues object @@ -84,11 +84,11 @@ class PHPExcel_Chart_DataSeriesValues public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSource = null, $formatCode = null, $pointCount = 0, $dataValues = array(), $marker = null) { $this->setDataType($dataType); - $this->_dataSource = $dataSource; - $this->_formatCode = $formatCode; - $this->_pointCount = $pointCount; - $this->_dataValues = $dataValues; - $this->_marker = $marker; + $this->dataSource = $dataSource; + $this->formatCode = $formatCode; + $this->pointCount = $pointCount; + $this->dataValues = $dataValues; + $this->pointMarker = $marker; } /** @@ -98,7 +98,7 @@ public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSourc */ public function getDataType() { - return $this->_dataType; + return $this->dataType; } /** @@ -114,10 +114,10 @@ public function getDataType() */ public function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) { - if (!in_array($dataType, self::$_dataTypeValues)) { + if (!in_array($dataType, self::$dataTypeValues)) { throw new PHPExcel_Chart_Exception('Invalid datatype for chart data series values'); } - $this->_dataType = $dataType; + $this->dataType = $dataType; return $this; } @@ -129,7 +129,7 @@ public function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) */ public function getDataSource() { - return $this->_dataSource; + return $this->dataSource; } /** @@ -140,7 +140,7 @@ public function getDataSource() */ public function setDataSource($dataSource = null, $refreshDataValues = true) { - $this->_dataSource = $dataSource; + $this->dataSource = $dataSource; if ($refreshDataValues) { // TO DO @@ -156,7 +156,7 @@ public function setDataSource($dataSource = null, $refreshDataValues = true) */ public function getPointMarker() { - return $this->_marker; + return $this->pointMarker; } /** @@ -167,7 +167,7 @@ public function getPointMarker() */ public function setPointMarker($marker = null) { - $this->_marker = $marker; + $this->pointMarker = $marker; return $this; } @@ -179,7 +179,7 @@ public function setPointMarker($marker = null) */ public function getFormatCode() { - return $this->_formatCode; + return $this->formatCode; } /** @@ -190,7 +190,7 @@ public function getFormatCode() */ public function setFormatCode($formatCode = null) { - $this->_formatCode = $formatCode; + $this->formatCode = $formatCode; return $this; } @@ -202,7 +202,7 @@ public function setFormatCode($formatCode = null) */ public function getPointCount() { - return $this->_pointCount; + return $this->pointCount; } /** @@ -212,8 +212,8 @@ public function getPointCount() */ public function isMultiLevelSeries() { - if (count($this->_dataValues) > 0) { - return is_array($this->_dataValues[0]); + if (count($this->dataValues) > 0) { + return is_array($this->dataValues[0]); } return null; } @@ -226,8 +226,8 @@ public function isMultiLevelSeries() public function multiLevelCount() { $levelCount = 0; - foreach ($this->_dataValues as $dataValueSet) { - $levelCount = max($levelCount,count($dataValueSet)); + foreach ($this->dataValues as $dataValueSet) { + $levelCount = max($levelCount, count($dataValueSet)); } return $levelCount; } @@ -239,7 +239,7 @@ public function multiLevelCount() */ public function getDataValues() { - return $this->_dataValues; + return $this->dataValues; } /** @@ -249,13 +249,13 @@ public function getDataValues() */ public function getDataValue() { - $count = count($this->_dataValues); + $count = count($this->dataValues); if ($count == 0) { return null; } elseif ($count == 1) { - return $this->_dataValues[0]; + return $this->dataValues[0]; } - return $this->_dataValues; + return $this->dataValues; } /** @@ -263,14 +263,14 @@ public function getDataValue() * * @param array $dataValues * @param boolean $refreshDataSource - * TRUE - refresh the value of _dataSource based on the values of $dataValues - * FALSE - don't change the value of _dataSource + * TRUE - refresh the value of dataSource based on the values of $dataValues + * FALSE - don't change the value of dataSource * @return PHPExcel_Chart_DataSeriesValues */ public function setDataValues($dataValues = array(), $refreshDataSource = true) { - $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($dataValues); - $this->_pointCount = count($dataValues); + $this->dataValues = PHPExcel_Calculation_Functions::flattenArray($dataValues); + $this->pointCount = count($dataValues); if ($refreshDataSource) { // TO DO @@ -279,39 +279,39 @@ public function setDataValues($dataValues = array(), $refreshDataSource = true) return $this; } - private function _stripNulls($var) + private function stripNulls($var) { return $var !== null; } public function refresh(PHPExcel_Worksheet $worksheet, $flatten = true) { - if ($this->_dataSource !== null) { + if ($this->dataSource !== null) { $calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent()); $newDataValues = PHPExcel_Calculation::_unwrapResult( $calcEngine->_calculateFormulaValue( - '='.$this->_dataSource, + '='.$this->dataSource, null, $worksheet->getCell('A1') ) ); if ($flatten) { - $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); - foreach ($this->_dataValues as &$dataValue) { + $this->dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); + foreach ($this->dataValues as &$dataValue) { if ((!empty($dataValue)) && ($dataValue[0] == '#')) { $dataValue = 0.0; } } unset($dataValue); } else { - $cellRange = explode('!', $this->_dataSource); + $cellRange = explode('!', $this->dataSource); if (count($cellRange) > 1) { list(, $cellRange) = $cellRange; } $dimensions = PHPExcel_Cell::rangeDimension(str_replace('$', '', $cellRange)); if (($dimensions[0] == 1) || ($dimensions[1] == 1)) { - $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); + $this->dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); } else { $newArray = array_values(array_shift($newDataValues)); foreach ($newArray as $i => $newDataSet) { @@ -324,10 +324,10 @@ public function refresh(PHPExcel_Worksheet $worksheet, $flatten = true) array_unshift($newArray[$i++], $newDataVal); } } - $this->_dataValues = $newArray; + $this->dataValues = $newArray; } } - $this->_pointCount = count($this->_dataValues); + $this->pointCount = count($this->dataValues); } } } diff --git a/Classes/PHPExcel/Chart/GridLines.php b/Classes/PHPExcel/Chart/GridLines.php index 69d8ed54c..898012ebd 100644 --- a/Classes/PHPExcel/Chart/GridLines.php +++ b/Classes/PHPExcel/Chart/GridLines.php @@ -20,9 +20,9 @@ class PHPExcel_Chart_GridLines extends PHPExcel_Chart_Properties * */ - private $_object_state = false; + private $objectState = false; - private $_line_properties = array( + private $lineProperties = array( 'color' => array( 'type' => self::EXCEL_COLOR_TYPE_STANDARD, 'value' => null, @@ -47,7 +47,7 @@ class PHPExcel_Chart_GridLines extends PHPExcel_Chart_Properties ) ); - private $_shadow_properties = array( + private $shadowProperties = array( 'presets' => self::SHADOW_PRESETS_NOSHADOW, 'effect' => null, 'color' => array( @@ -67,7 +67,7 @@ class PHPExcel_Chart_GridLines extends PHPExcel_Chart_Properties 'rotWithShape' => null ); - private $_glow_properties = array( + private $glowProperties = array( 'size' => null, 'color' => array( 'type' => self::EXCEL_COLOR_TYPE_STANDARD, @@ -76,7 +76,7 @@ class PHPExcel_Chart_GridLines extends PHPExcel_Chart_Properties ) ); - private $_soft_edges = array( + private $softEdges = array( 'size' => null ); @@ -88,7 +88,7 @@ class PHPExcel_Chart_GridLines extends PHPExcel_Chart_Properties public function getObjectState() { - return $this->_object_state; + return $this->objectState; } /** @@ -97,9 +97,9 @@ public function getObjectState() * @return PHPExcel_Chart_GridLines */ - private function _activateObject() + private function activateObject() { - $this->_object_state = true; + $this->objectState = true; return $this; } @@ -114,12 +114,12 @@ private function _activateObject() public function setLineColorProperties($value, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_STANDARD) { - $this - ->_activateObject() - ->_line_properties['color'] = $this->setColorProperties( + $this->activateObject() + ->lineProperties['color'] = $this->setColorProperties( $value, $alpha, - $type); + $type + ); } /** @@ -138,33 +138,33 @@ public function setLineColorProperties($value, $alpha = 0, $type = self::EXCEL_C public function setLineStyleProperties($line_width = null, $compound_type = null, $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) { - $this->_activateObject(); + $this->activateObject(); (!is_null($line_width)) - ? $this->_line_properties['style']['width'] = $this->getExcelPointsWidth((float) $line_width) + ? $this->lineProperties['style']['width'] = $this->getExcelPointsWidth((float) $line_width) : null; (!is_null($compound_type)) - ? $this->_line_properties['style']['compound'] = (string) $compound_type + ? $this->lineProperties['style']['compound'] = (string) $compound_type : null; (!is_null($dash_type)) - ? $this->_line_properties['style']['dash'] = (string) $dash_type + ? $this->lineProperties['style']['dash'] = (string) $dash_type : null; (!is_null($cap_type)) - ? $this->_line_properties['style']['cap'] = (string) $cap_type + ? $this->lineProperties['style']['cap'] = (string) $cap_type : null; (!is_null($join_type)) - ? $this->_line_properties['style']['join'] = (string) $join_type + ? $this->lineProperties['style']['join'] = (string) $join_type : null; (!is_null($head_arrow_type)) - ? $this->_line_properties['style']['arrow']['head']['type'] = (string) $head_arrow_type + ? $this->lineProperties['style']['arrow']['head']['type'] = (string) $head_arrow_type : null; (!is_null($head_arrow_size)) - ? $this->_line_properties['style']['arrow']['head']['size'] = (string) $head_arrow_size + ? $this->lineProperties['style']['arrow']['head']['size'] = (string) $head_arrow_size : null; (!is_null($end_arrow_type)) - ? $this->_line_properties['style']['arrow']['end']['type'] = (string) $end_arrow_type + ? $this->lineProperties['style']['arrow']['end']['type'] = (string) $end_arrow_type : null; (!is_null($end_arrow_size)) - ? $this->_line_properties['style']['arrow']['end']['size'] = (string) $end_arrow_size + ? $this->lineProperties['style']['arrow']['end']['size'] = (string) $end_arrow_size : null; } @@ -178,7 +178,7 @@ public function setLineStyleProperties($line_width = null, $compound_type = null public function getLineColorProperty($parameter) { - return $this->_line_properties['color'][$parameter]; + return $this->lineProperties['color'][$parameter]; } /** @@ -191,7 +191,7 @@ public function getLineColorProperty($parameter) public function getLineStyleProperty($elements) { - return $this->getArrayElementsValue($this->_line_properties['style'], $elements); + return $this->getArrayElementsValue($this->lineProperties['style'], $elements); } /** @@ -207,9 +207,9 @@ public function getLineStyleProperty($elements) public function setGlowProperties($size, $color_value = null, $color_alpha = null, $color_type = null) { $this - ->_activateObject() - ->_setGlowSize($size) - ->_setGlowColor($color_value, $color_alpha, $color_type); + ->activateObject() + ->setGlowSize($size) + ->setGlowColor($color_value, $color_alpha, $color_type); } /** @@ -222,7 +222,7 @@ public function setGlowProperties($size, $color_value = null, $color_alpha = nul public function getGlowColor($property) { - return $this->_glow_properties['color'][$property]; + return $this->glowProperties['color'][$property]; } /** @@ -233,7 +233,7 @@ public function getGlowColor($property) public function getGlowSize() { - return $this->_glow_properties['size']; + return $this->glowProperties['size']; } /** @@ -244,9 +244,9 @@ public function getGlowSize() * @return PHPExcel_Chart_GridLines */ - private function _setGlowSize($size) + private function setGlowSize($size) { - $this->_glow_properties['size'] = $this->getExcelPointsWidth((float) $size); + $this->glowProperties['size'] = $this->getExcelPointsWidth((float) $size); return $this; } @@ -261,16 +261,16 @@ private function _setGlowSize($size) * @return PHPExcel_Chart_GridLines */ - private function _setGlowColor($color, $alpha, $type) + private function setGlowColor($color, $alpha, $type) { if (!is_null($color)) { - $this->_glow_properties['color']['value'] = (string) $color; + $this->glowProperties['color']['value'] = (string) $color; } if (!is_null($alpha)) { - $this->_glow_properties['color']['alpha'] = $this->getTrueAlpha((int) $alpha); + $this->glowProperties['color']['alpha'] = $this->getTrueAlpha((int) $alpha); } if (!is_null($type)) { - $this->_glow_properties['color']['type'] = (string) $type; + $this->glowProperties['color']['type'] = (string) $type; } return $this; @@ -287,7 +287,7 @@ private function _setGlowColor($color, $alpha, $type) public function getLineStyleArrowParameters($arrow_selector, $property_selector) { - return $this->getLineStyleArrowSize($this->_line_properties['style']['arrow'][$arrow_selector]['size'], $property_selector); + return $this->getLineStyleArrowSize($this->lineProperties['style']['arrow'][$arrow_selector]['size'], $property_selector); } /** @@ -305,17 +305,16 @@ public function getLineStyleArrowParameters($arrow_selector, $property_selector) public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_color_type = null, $sh_color_alpha = null, $sh_blur = null, $sh_angle = null, $sh_distance = null) { - $this - ->_activateObject() - ->_setShadowPresetsProperties((int) $sh_presets) - ->_setShadowColor( - is_null($sh_color_value) ? $this->_shadow_properties['color']['value'] : $sh_color_value - , is_null($sh_color_alpha) ? (int) $this->_shadow_properties['color']['alpha'] - : $this->getTrueAlpha($sh_color_alpha) - , is_null($sh_color_type) ? $this->_shadow_properties['color']['type'] : $sh_color_type) - ->_setShadowBlur($sh_blur) - ->_setShadowAngle($sh_angle) - ->_setShadowDistance($sh_distance); + $this->activateObject() + ->setShadowPresetsProperties((int) $sh_presets) + ->setShadowColor( + is_null($sh_color_value) ? $this->shadowProperties['color']['value'] : $sh_color_value, + is_null($sh_color_alpha) ? (int) $this->shadowProperties['color']['alpha'] : $this->getTrueAlpha($sh_color_alpha), + is_null($sh_color_type) ? $this->shadowProperties['color']['type'] : $sh_color_type + ) + ->setShadowBlur($sh_blur) + ->setShadowAngle($sh_angle) + ->setShadowDistance($sh_distance); } /** @@ -326,10 +325,10 @@ public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_col * @return PHPExcel_Chart_GridLines */ - private function _setShadowPresetsProperties($shadow_presets) + private function setShadowPresetsProperties($shadow_presets) { - $this->_shadow_properties['presets'] = $shadow_presets; - $this->_setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); + $this->shadowProperties['presets'] = $shadow_presets; + $this->setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); return $this; } @@ -343,20 +342,20 @@ private function _setShadowPresetsProperties($shadow_presets) * @return PHPExcel_Chart_GridLines */ - private function _setShadowProperiesMapValues(array $properties_map, &$reference = null) + private function setShadowProperiesMapValues(array $properties_map, &$reference = null) { $base_reference = $reference; foreach ($properties_map as $property_key => $property_val) { if (is_array($property_val)) { if ($reference === null) { - $reference = & $this->_shadow_properties[$property_key]; + $reference = & $this->shadowProperties[$property_key]; } else { $reference = & $reference[$property_key]; } - $this->_setShadowProperiesMapValues($property_val, $reference); + $this->setShadowProperiesMapValues($property_val, $reference); } else { if ($base_reference === null) { - $this->_shadow_properties[$property_key] = $property_val; + $this->shadowProperties[$property_key] = $property_val; } else { $reference[$property_key] = $property_val; } @@ -374,16 +373,16 @@ private function _setShadowProperiesMapValues(array $properties_map, &$reference * @param string $type * @return PHPExcel_Chart_GridLines */ - private function _setShadowColor($color, $alpha, $type) + private function setShadowColor($color, $alpha, $type) { if (!is_null($color)) { - $this->_shadow_properties['color']['value'] = (string) $color; + $this->shadowProperties['color']['value'] = (string) $color; } if (!is_null($alpha)) { - $this->_shadow_properties['color']['alpha'] = $this->getTrueAlpha((int) $alpha); + $this->shadowProperties['color']['alpha'] = $this->getTrueAlpha((int) $alpha); } if (!is_null($type)) { - $this->_shadow_properties['color']['type'] = (string) $type; + $this->shadowProperties['color']['type'] = (string) $type; } return $this; @@ -396,10 +395,10 @@ private function _setShadowColor($color, $alpha, $type) * * @return PHPExcel_Chart_GridLines */ - private function _setShadowBlur($blur) + private function setShadowBlur($blur) { if ($blur !== null) { - $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur); + $this->shadowProperties['blur'] = (string) $this->getExcelPointsWidth($blur); } return $this; @@ -412,10 +411,10 @@ private function _setShadowBlur($blur) * @return PHPExcel_Chart_GridLines */ - private function _setShadowAngle($angle) + private function setShadowAngle($angle) { if ($angle !== null) { - $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle); + $this->shadowProperties['direction'] = (string) $this->getExcelPointsAngle($angle); } return $this; @@ -427,10 +426,10 @@ private function _setShadowAngle($angle) * @param float $distance * @return PHPExcel_Chart_GridLines */ - private function _setShadowDistance($distance) + private function setShadowDistance($distance) { if ($distance !== null) { - $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance); + $this->shadowProperties['distance'] = (string) $this->getExcelPointsWidth($distance); } return $this; @@ -445,7 +444,7 @@ private function _setShadowDistance($distance) */ public function getShadowProperty($elements) { - return $this->getArrayElementsValue($this->_shadow_properties, $elements); + return $this->getArrayElementsValue($this->shadowProperties, $elements); } /** @@ -456,8 +455,8 @@ public function getShadowProperty($elements) public function setSoftEdgesSize($size) { if (!is_null($size)) { - $this->_activateObject(); - $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size); + $this->activateObject(); + $softEdges['size'] = (string) $this->getExcelPointsWidth($size); } } @@ -468,6 +467,6 @@ public function setSoftEdgesSize($size) */ public function getSoftEdgesSize() { - return $this->_soft_edges['size']; + return $this->softEdges['size']; } -} \ No newline at end of file +} diff --git a/Classes/PHPExcel/Chart/Layout.php b/Classes/PHPExcel/Chart/Layout.php index 53a447c95..7fef07410 100644 --- a/Classes/PHPExcel/Chart/Layout.php +++ b/Classes/PHPExcel/Chart/Layout.php @@ -40,49 +40,49 @@ class PHPExcel_Chart_Layout * * @var string */ - private $_layoutTarget = null; + private $layoutTarget; /** * X Mode * * @var string */ - private $_xMode = null; + private $xMode; /** * Y Mode * * @var string */ - private $_yMode = null; + private $yMode; /** * X-Position * * @var float */ - private $_xPos = null; + private $xPos; /** * Y-Position * * @var float */ - private $_yPos = null; + private $yPos; /** * width * * @var float */ - private $_width = null; + private $width; /** * height * * @var float */ - private $_height = null; + private $height; /** * show legend key @@ -90,7 +90,7 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showLegendKey = null; + private $showLegendKey; /** * show value @@ -98,7 +98,7 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showVal = null; + private $showVal; /** * show category name @@ -106,7 +106,7 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showCatName = null; + private $showCatName; /** * show data series name @@ -114,7 +114,7 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showSerName = null; + private $showSerName; /** * show percentage @@ -122,14 +122,14 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showPercent = null; + private $showPercent; /** * show bubble size * * @var boolean */ - private $_showBubbleSize = null; + private $showBubbleSize; /** * show leader lines @@ -137,7 +137,7 @@ class PHPExcel_Chart_Layout * * @var boolean */ - private $_showLeaderLines = null; + private $showLeaderLines; /** @@ -146,25 +146,25 @@ class PHPExcel_Chart_Layout public function __construct($layout = array()) { if (isset($layout['layoutTarget'])) { - $this->_layoutTarget = $layout['layoutTarget']; + $this->layoutTarget = $layout['layoutTarget']; } if (isset($layout['xMode'])) { - $this->_xMode = $layout['xMode']; + $this->xMode = $layout['xMode']; } if (isset($layout['yMode'])) { - $this->_yMode = $layout['yMode']; + $this->yMode = $layout['yMode']; } if (isset($layout['x'])) { - $this->_xPos = (float) $layout['x']; + $this->xPos = (float) $layout['x']; } if (isset($layout['y'])) { - $this->_yPos = (float) $layout['y']; + $this->yPos = (float) $layout['y']; } if (isset($layout['w'])) { - $this->_width = (float) $layout['w']; + $this->width = (float) $layout['w']; } if (isset($layout['h'])) { - $this->_height = (float) $layout['h']; + $this->height = (float) $layout['h']; } } @@ -175,7 +175,7 @@ public function __construct($layout = array()) */ public function getLayoutTarget() { - return $this->_layoutTarget; + return $this->layoutTarget; } /** @@ -186,7 +186,7 @@ public function getLayoutTarget() */ public function setLayoutTarget($value) { - $this->_layoutTarget = $value; + $this->layoutTarget = $value; return $this; } @@ -197,7 +197,7 @@ public function setLayoutTarget($value) */ public function getXMode() { - return $this->_xMode; + return $this->xMode; } /** @@ -208,7 +208,7 @@ public function getXMode() */ public function setXMode($value) { - $this->_xMode = $value; + $this->xMode = $value; return $this; } @@ -219,7 +219,7 @@ public function setXMode($value) */ public function getYMode() { - return $this->_yMode; + return $this->yMode; } /** @@ -230,7 +230,7 @@ public function getYMode() */ public function setYMode($value) { - $this->_yMode = $value; + $this->yMode = $value; return $this; } @@ -241,7 +241,7 @@ public function setYMode($value) */ public function getXPosition() { - return $this->_xPos; + return $this->xPos; } /** @@ -252,7 +252,7 @@ public function getXPosition() */ public function setXPosition($value) { - $this->_xPos = $value; + $this->xPos = $value; return $this; } @@ -263,7 +263,7 @@ public function setXPosition($value) */ public function getYPosition() { - return $this->_yPos; + return $this->yPos; } /** @@ -274,7 +274,7 @@ public function getYPosition() */ public function setYPosition($value) { - $this->_yPos = $value; + $this->yPos = $value; return $this; } @@ -285,7 +285,7 @@ public function setYPosition($value) */ public function getWidth() { - return $this->_width; + return $this->width; } /** @@ -296,7 +296,7 @@ public function getWidth() */ public function setWidth($value) { - $this->_width = $value; + $this->width = $value; return $this; } @@ -307,7 +307,7 @@ public function setWidth($value) */ public function getHeight() { - return $this->_height; + return $this->height; } /** @@ -318,7 +318,7 @@ public function getHeight() */ public function setHeight($value) { - $this->_height = $value; + $this->height = $value; return $this; } @@ -330,7 +330,7 @@ public function setHeight($value) */ public function getShowLegendKey() { - return $this->_showLegendKey; + return $this->showLegendKey; } /** @@ -342,7 +342,7 @@ public function getShowLegendKey() */ public function setShowLegendKey($value) { - $this->_showLegendKey = $value; + $this->showLegendKey = $value; return $this; } @@ -353,7 +353,7 @@ public function setShowLegendKey($value) */ public function getShowVal() { - return $this->_showVal; + return $this->showVal; } /** @@ -365,7 +365,7 @@ public function getShowVal() */ public function setShowVal($value) { - $this->_showVal = $value; + $this->showVal = $value; return $this; } @@ -376,7 +376,7 @@ public function setShowVal($value) */ public function getShowCatName() { - return $this->_showCatName; + return $this->showCatName; } /** @@ -388,7 +388,7 @@ public function getShowCatName() */ public function setShowCatName($value) { - $this->_showCatName = $value; + $this->showCatName = $value; return $this; } @@ -399,7 +399,7 @@ public function setShowCatName($value) */ public function getShowSerName() { - return $this->_showSerName; + return $this->showSerName; } /** @@ -411,7 +411,7 @@ public function getShowSerName() */ public function setShowSerName($value) { - $this->_showSerName = $value; + $this->showSerName = $value; return $this; } @@ -422,7 +422,7 @@ public function setShowSerName($value) */ public function getShowPercent() { - return $this->_showPercent; + return $this->showPercent; } /** @@ -434,7 +434,7 @@ public function getShowPercent() */ public function setShowPercent($value) { - $this->_showPercent = $value; + $this->showPercent = $value; return $this; } @@ -445,7 +445,7 @@ public function setShowPercent($value) */ public function getShowBubbleSize() { - return $this->_showBubbleSize; + return $this->showBubbleSize; } /** @@ -457,7 +457,7 @@ public function getShowBubbleSize() */ public function setShowBubbleSize($value) { - $this->_showBubbleSize = $value; + $this->showBubbleSize = $value; return $this; } @@ -468,7 +468,7 @@ public function setShowBubbleSize($value) */ public function getShowLeaderLines() { - return $this->_showLeaderLines; + return $this->showLeaderLines; } /** @@ -480,7 +480,7 @@ public function getShowLeaderLines() */ public function setShowLeaderLines($value) { - $this->_showLeaderLines = $value; + $this->showLeaderLines = $value; return $this; } } diff --git a/Classes/PHPExcel/Chart/Legend.php b/Classes/PHPExcel/Chart/Legend.php index c44003bd0..60f47c803 100644 --- a/Classes/PHPExcel/Chart/Legend.php +++ b/Classes/PHPExcel/Chart/Legend.php @@ -28,26 +28,26 @@ class PHPExcel_Chart_Legend { /** Legend positions */ - const xlLegendPositionBottom = -4107; // Below the chart. - const xlLegendPositionCorner = 2; // In the upper right-hand corner of the chart border. - const xlLegendPositionCustom = -4161; // A custom position. - const xlLegendPositionLeft = -4131; // Left of the chart. - const xlLegendPositionRight = -4152; // Right of the chart. - const xlLegendPositionTop = -4160; // Above the chart. + const xlLegendPositionBottom = -4107; // Below the chart. + const xlLegendPositionCorner = 2; // In the upper right-hand corner of the chart border. + const xlLegendPositionCustom = -4161; // A custom position. + const xlLegendPositionLeft = -4131; // Left of the chart. + const xlLegendPositionRight = -4152; // Right of the chart. + const xlLegendPositionTop = -4160; // Above the chart. const POSITION_RIGHT = 'r'; - const POSITION_LEFT = 'l'; - const POSITION_BOTTOM = 'b'; - const POSITION_TOP = 't'; - const POSITION_TOPRIGHT = 'tr'; + const POSITION_LEFT = 'l'; + const POSITION_BOTTOM = 'b'; + const POSITION_TOP = 't'; + const POSITION_TOPRIGHT = 'tr'; private static $_positionXLref = array( - self::xlLegendPositionBottom => self::POSITION_BOTTOM, - self::xlLegendPositionCorner => self::POSITION_TOPRIGHT, - self::xlLegendPositionCustom => '??', - self::xlLegendPositionLeft => self::POSITION_LEFT, - self::xlLegendPositionRight => self::POSITION_RIGHT, - self::xlLegendPositionTop => self::POSITION_TOP + self::xlLegendPositionBottom => self::POSITION_BOTTOM, + self::xlLegendPositionCorner => self::POSITION_TOPRIGHT, + self::xlLegendPositionCustom => '??', + self::xlLegendPositionLeft => self::POSITION_LEFT, + self::xlLegendPositionRight => self::POSITION_RIGHT, + self::xlLegendPositionTop => self::POSITION_TOP ); /** @@ -55,30 +55,30 @@ class PHPExcel_Chart_Legend * * @var string */ - private $_position = self::POSITION_RIGHT; + private $position = self::POSITION_RIGHT; /** * Allow overlay of other elements? * * @var boolean */ - private $_overlay = TRUE; + private $overlay = true; /** * Legend Layout * * @var PHPExcel_Chart_Layout */ - private $_layout = NULL; + private $layout = null; /** * Create a new PHPExcel_Chart_Legend */ - public function __construct($position = self::POSITION_RIGHT, PHPExcel_Chart_Layout $layout = NULL, $overlay = FALSE) + public function __construct($position = self::POSITION_RIGHT, PHPExcel_Chart_Layout $layout = null, $overlay = false) { $this->setPosition($position); - $this->_layout = $layout; + $this->layout = $layout; $this->setOverlay($overlay); } @@ -87,8 +87,9 @@ public function __construct($position = self::POSITION_RIGHT, PHPExcel_Chart_Lay * * @return string */ - public function getPosition() { - return $this->_position; + public function getPosition() + { + return $this->position; } /** @@ -96,12 +97,13 @@ public function getPosition() { * * @param string $position */ - public function setPosition($position = self::POSITION_RIGHT) { - if (!in_array($position,self::$_positionXLref)) { + public function setPosition($position = self::POSITION_RIGHT) + { + if (!in_array($position, self::$_positionXLref)) { return false; } - $this->_position = $position; + $this->position = $position; return true; } @@ -110,8 +112,9 @@ public function setPosition($position = self::POSITION_RIGHT) { * * @return number */ - public function getPositionXL() { - return array_search($this->_position,self::$_positionXLref); + public function getPositionXL() + { + return array_search($this->position, self::$_positionXLref); } /** @@ -119,12 +122,13 @@ public function getPositionXL() { * * @param number $positionXL */ - public function setPositionXL($positionXL = self::xlLegendPositionRight) { - if (!array_key_exists($positionXL,self::$_positionXLref)) { + public function setPositionXL($positionXL = self::xlLegendPositionRight) + { + if (!array_key_exists($positionXL, self::$_positionXLref)) { return false; } - $this->_position = self::$_positionXLref[$positionXL]; + $this->position = self::$_positionXLref[$positionXL]; return true; } @@ -133,8 +137,9 @@ public function setPositionXL($positionXL = self::xlLegendPositionRight) { * * @return boolean */ - public function getOverlay() { - return $this->_overlay; + public function getOverlay() + { + return $this->overlay; } /** @@ -143,12 +148,13 @@ public function getOverlay() { * @param boolean $overlay * @return boolean */ - public function setOverlay($overlay = FALSE) { + public function setOverlay($overlay = false) + { if (!is_bool($overlay)) { return false; } - $this->_overlay = $overlay; + $this->overlay = $overlay; return true; } @@ -157,8 +163,8 @@ public function setOverlay($overlay = FALSE) { * * @return PHPExcel_Chart_Layout */ - public function getLayout() { - return $this->_layout; + public function getLayout() + { + return $this->layout; } - } diff --git a/Classes/PHPExcel/Chart/PlotArea.php b/Classes/PHPExcel/Chart/PlotArea.php index c2ff157e9..551cc517b 100644 --- a/Classes/PHPExcel/Chart/PlotArea.php +++ b/Classes/PHPExcel/Chart/PlotArea.php @@ -32,22 +32,22 @@ class PHPExcel_Chart_PlotArea * * @var PHPExcel_Chart_Layout */ - private $_layout = null; + private $layout = null; /** * Plot Series * * @var array of PHPExcel_Chart_DataSeries */ - private $_plotSeries = array(); + private $plotSeries = array(); /** * Create a new PHPExcel_Chart_PlotArea */ public function __construct(PHPExcel_Chart_Layout $layout = null, $plotSeries = array()) { - $this->_layout = $layout; - $this->_plotSeries = $plotSeries; + $this->layout = $layout; + $this->plotSeries = $plotSeries; } /** @@ -57,7 +57,7 @@ public function __construct(PHPExcel_Chart_Layout $layout = null, $plotSeries = */ public function getLayout() { - return $this->_layout; + return $this->layout; } /** @@ -67,7 +67,7 @@ public function getLayout() */ public function getPlotGroupCount() { - return count($this->_plotSeries); + return count($this->plotSeries); } /** @@ -78,7 +78,7 @@ public function getPlotGroupCount() public function getPlotSeriesCount() { $seriesCount = 0; - foreach ($this->_plotSeries as $plot) { + foreach ($this->plotSeries as $plot) { $seriesCount += $plot->getPlotSeriesCount(); } return $seriesCount; @@ -91,7 +91,7 @@ public function getPlotSeriesCount() */ public function getPlotGroup() { - return $this->_plotSeries; + return $this->plotSeries; } /** @@ -101,7 +101,7 @@ public function getPlotGroup() */ public function getPlotGroupByIndex($index) { - return $this->_plotSeries[$index]; + return $this->plotSeries[$index]; } /** @@ -112,14 +112,14 @@ public function getPlotGroupByIndex($index) */ public function setPlotSeries($plotSeries = array()) { - $this->_plotSeries = $plotSeries; + $this->plotSeries = $plotSeries; return $this; } public function refresh(PHPExcel_Worksheet $worksheet) { - foreach ($this->_plotSeries as $plotSeries) { + foreach ($this->plotSeries as $plotSeries) { $plotSeries->refresh($worksheet); } } diff --git a/Classes/PHPExcel/Chart/Properties.php b/Classes/PHPExcel/Chart/Properties.php index 3181f6546..9bb6e9337 100644 --- a/Classes/PHPExcel/Chart/Properties.php +++ b/Classes/PHPExcel/Chart/Properties.php @@ -70,7 +70,7 @@ abstract class PHPExcel_Chart_Properties LINE_STYLE_JOIN_MITER = 'miter', LINE_STYLE_JOIN_BEVEL = 'bevel', - LINE_STYLE_ARROW_TYPE_NOARROW = NULL, + LINE_STYLE_ARROW_TYPE_NOARROW = null, LINE_STYLE_ARROW_TYPE_ARROW = 'triangle', LINE_STYLE_ARROW_TYPE_OPEN = 'arrow', LINE_STYLE_ARROW_TYPE_STEALTH = 'stealth', @@ -88,7 +88,7 @@ abstract class PHPExcel_Chart_Properties LINE_STYLE_ARROW_SIZE_9 = 9; const - SHADOW_PRESETS_NOSHADOW = NULL, + SHADOW_PRESETS_NOSHADOW = null, SHADOW_PRESETS_OUTER_BOTTTOM_RIGHT = 1, SHADOW_PRESETS_OUTER_BOTTOM = 2, SHADOW_PRESETS_OUTER_BOTTOM_LEFT = 3, @@ -113,19 +113,19 @@ abstract class PHPExcel_Chart_Properties SHADOW_PRESETS_PERSPECTIVE_LOWER_RIGHT = 22, SHADOW_PRESETS_PERSPECTIVE_LOWER_LEFT = 23; - protected function getExcelPointsWidth($width) + protected function getExcelPointsWidth($width) { - return $width * 12700; + return $width * 12700; } protected function getExcelPointsAngle($angle) { - return $angle * 60000; + return $angle * 60000; } protected function getTrueAlpha($alpha) { - return (string) 100 - $alpha . '000'; + return (string) 100 - $alpha . '000'; } protected function setColorProperties($color, $alpha, $type) @@ -137,7 +137,8 @@ protected function setColorProperties($color, $alpha, $type) ); } - protected function getLineStyleArrowSize($array_selector, $array_kay_selector) { + protected function getLineStyleArrowSize($array_selector, $array_kay_selector) + { $sizes = array( 1 => array('w' => 'sm', 'len' => 'sm'), 2 => array('w' => 'sm', 'len' => 'med'), @@ -153,7 +154,8 @@ protected function getLineStyleArrowSize($array_selector, $array_kay_selector) { return $sizes[$array_selector][$array_kay_selector]; } - protected function getShadowPresetsMap($shadow_presets_option) { + protected function getShadowPresetsMap($shadow_presets_option) + { $presets_options = array( //OUTER 1 => array( @@ -345,7 +347,8 @@ protected function getShadowPresetsMap($shadow_presets_option) { return $presets_options[$shadow_presets_option]; } - protected function getArrayElementsValue($properties, $elements) { + protected function getArrayElementsValue($properties, $elements) + { $reference = & $properties; if (!is_array($elements)) { return $reference[$elements]; @@ -357,4 +360,4 @@ protected function getArrayElementsValue($properties, $elements) { } return $this; } -} \ No newline at end of file +} diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index 2b49e651a..a62f0b799 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -1,7 +1,9 @@ <?php +require_once(PHPExcel_Settings::getChartRendererPath().'/jpgraph.php'); + /** - * PHPExcel + * PHPExcel_Chart_Renderer_jpgraph * * Copyright (c) 2006 - 2015 PHPExcel * @@ -25,81 +27,71 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -require_once(PHPExcel_Settings::getChartRendererPath().'/jpgraph.php'); - - -/** - * PHPExcel_Chart_Renderer_jpgraph - * - * @category PHPExcel - * @package PHPExcel_Chart_Renderer - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Chart_Renderer_jpgraph { - private static $_width = 640; + private static $width = 640; - private static $_height = 480; + private static $height = 480; - private static $_colourSet = array( 'mediumpurple1', 'palegreen3', 'gold1', 'cadetblue1', - 'darkmagenta', 'coral', 'dodgerblue3', 'eggplant', - 'mediumblue', 'magenta', 'sandybrown', 'cyan', - 'firebrick1', 'forestgreen', 'deeppink4', 'darkolivegreen', - 'goldenrod2' - ); + private static $colourSet = array( + 'mediumpurple1', 'palegreen3', 'gold1', 'cadetblue1', + 'darkmagenta', 'coral', 'dodgerblue3', 'eggplant', + 'mediumblue', 'magenta', 'sandybrown', 'cyan', + 'firebrick1', 'forestgreen', 'deeppink4', 'darkolivegreen', + 'goldenrod2' + ); - private static $_markSet = array( 'diamond' => MARK_DIAMOND, - 'square' => MARK_SQUARE, - 'triangle' => MARK_UTRIANGLE, - 'x' => MARK_X, - 'star' => MARK_STAR, - 'dot' => MARK_FILLEDCIRCLE, - 'dash' => MARK_DTRIANGLE, - 'circle' => MARK_CIRCLE, - 'plus' => MARK_CROSS - ); + private static $markSet = array( + 'diamond' => MARK_DIAMOND, + 'square' => MARK_SQUARE, + 'triangle' => MARK_UTRIANGLE, + 'x' => MARK_X, + 'star' => MARK_STAR, + 'dot' => MARK_FILLEDCIRCLE, + 'dash' => MARK_DTRIANGLE, + 'circle' => MARK_CIRCLE, + 'plus' => MARK_CROSS + ); - private $_chart = null; + private $chart; - private $_graph = null; + private $graph; - private static $_plotColour = 0; + private static $_plotColour = 0; - private static $_plotMark = 0; + private static $_plotMark = 0; - private function _formatPointMarker($seriesPlot, $markerID) { - $plotMarkKeys = array_keys(self::$_markSet); + private function formatPointMarker($seriesPlot, $markerID) { + $plotMarkKeys = array_keys(self::$markSet); if (is_null($markerID)) { // Use default plot marker (next marker in the series) - self::$_plotMark %= count(self::$_markSet); - $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]); + self::$_plotMark %= count(self::$markSet); + $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$_plotMark++]]); } elseif ($markerID !== 'none') { // Use specified plot marker (if it exists) - if (isset(self::$_markSet[$markerID])) { - $seriesPlot->mark->SetType(self::$_markSet[$markerID]); + if (isset(self::$markSet[$markerID])) { + $seriesPlot->mark->SetType(self::$markSet[$markerID]); } else { // If the specified plot marker doesn't exist, use default plot marker (next marker in the series) - self::$_plotMark %= count(self::$_markSet); - $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]); + self::$_plotMark %= count(self::$markSet); + $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$_plotMark++]]); } } else { // Hide plot marker $seriesPlot->mark->Hide(); } - $seriesPlot->mark->SetColor(self::$_colourSet[self::$_plotColour]); - $seriesPlot->mark->SetFillColor(self::$_colourSet[self::$_plotColour]); - $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + $seriesPlot->mark->SetColor(self::$colourSet[self::$_plotColour]); + $seriesPlot->mark->SetFillColor(self::$colourSet[self::$_plotColour]); + $seriesPlot->SetColor(self::$colourSet[self::$_plotColour++]); return $seriesPlot; - } // function _formatPointMarker() + } - private function _formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') { - $datasetLabelFormatCode = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); + private function formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') { + $datasetLabelFormatCode = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); if (!is_null($datasetLabelFormatCode)) { // Retrieve any label formatting code $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); @@ -124,16 +116,16 @@ private function _formatDataSetLabels($groupID, $datasetLabels, $labelCount, $ro } return $datasetLabels; - } // function _formatDataSetLabels() + } private function _percentageSumCalculation($groupID, $seriesCount) { // Adjust our values to a percentage value across all series in the group for($i = 0; $i < $seriesCount; ++$i) { if ($i == 0) { - $sumValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $sumValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); } else { - $nextValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $nextValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); foreach ($nextValues as $k => $value) { if (isset($sumValues[$k])) { $sumValues[$k] += $value; @@ -173,75 +165,75 @@ private function _getCaption($captionElement) { private function _renderTitle() { - $title = $this->_getCaption($this->_chart->getTitle()); + $title = $this->_getCaption($this->chart->getTitle()); if (!is_null($title)) { - $this->_graph->title->Set($title); + $this->graph->title->Set($title); } } // function _renderTitle() private function _renderLegend() { - $legend = $this->_chart->getLegend(); + $legend = $this->chart->getLegend(); if (!is_null($legend)) { $legendPosition = $legend->getPosition(); $legendOverlay = $legend->getOverlay(); switch ($legendPosition) { case 'r' : - $this->_graph->legend->SetPos(0.01,0.5,'right','center'); // right - $this->_graph->legend->SetColumns(1); + $this->graph->legend->SetPos(0.01,0.5,'right','center'); // right + $this->graph->legend->SetColumns(1); break; case 'l' : - $this->_graph->legend->SetPos(0.01,0.5,'left','center'); // left - $this->_graph->legend->SetColumns(1); + $this->graph->legend->SetPos(0.01,0.5,'left','center'); // left + $this->graph->legend->SetColumns(1); break; case 't' : - $this->_graph->legend->SetPos(0.5,0.01,'center','top'); // top + $this->graph->legend->SetPos(0.5,0.01,'center','top'); // top break; case 'b' : - $this->_graph->legend->SetPos(0.5,0.99,'center','bottom'); // bottom + $this->graph->legend->SetPos(0.5,0.99,'center','bottom'); // bottom break; default : - $this->_graph->legend->SetPos(0.01,0.01,'right','top'); // top-right - $this->_graph->legend->SetColumns(1); + $this->graph->legend->SetPos(0.01,0.01,'right','top'); // top-right + $this->graph->legend->SetColumns(1); break; } } else { - $this->_graph->legend->Hide(); + $this->graph->legend->Hide(); } } // function _renderLegend() private function _renderCartesianPlotArea($type='textlin') { - $this->_graph = new Graph(self::$_width,self::$_height); - $this->_graph->SetScale($type); + $this->graph = new Graph(self::$width,self::$height); + $this->graph->SetScale($type); $this->_renderTitle(); // Rotate for bar rather than column chart - $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); + $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); $reverse = ($rotation == 'bar') ? true : false; - $xAxisLabel = $this->_chart->getXAxisLabel(); + $xAxisLabel = $this->chart->getXAxisLabel(); if (!is_null($xAxisLabel)) { $title = $this->_getCaption($xAxisLabel); if (!is_null($title)) { - $this->_graph->xaxis->SetTitle($title,'center'); - $this->_graph->xaxis->title->SetMargin(35); + $this->graph->xaxis->SetTitle($title,'center'); + $this->graph->xaxis->title->SetMargin(35); if ($reverse) { - $this->_graph->xaxis->title->SetAngle(90); - $this->_graph->xaxis->title->SetMargin(90); + $this->graph->xaxis->title->SetAngle(90); + $this->graph->xaxis->title->SetMargin(90); } } } - $yAxisLabel = $this->_chart->getYAxisLabel(); + $yAxisLabel = $this->chart->getYAxisLabel(); if (!is_null($yAxisLabel)) { $title = $this->_getCaption($yAxisLabel); if (!is_null($title)) { - $this->_graph->yaxis->SetTitle($title,'center'); + $this->graph->yaxis->SetTitle($title,'center'); if ($reverse) { - $this->_graph->yaxis->title->SetAngle(0); - $this->_graph->yaxis->title->SetMargin(-55); + $this->graph->yaxis->title->SetAngle(0); + $this->graph->yaxis->title->SetMargin(-55); } } } @@ -249,31 +241,31 @@ private function _renderCartesianPlotArea($type='textlin') { private function _renderPiePlotArea($doughnut = False) { - $this->_graph = new PieGraph(self::$_width,self::$_height); + $this->graph = new PieGraph(self::$width,self::$height); $this->_renderTitle(); } // function _renderPiePlotArea() private function _renderRadarPlotArea() { - $this->_graph = new RadarGraph(self::$_width,self::$_height); - $this->_graph->SetScale('lin'); + $this->graph = new RadarGraph(self::$width,self::$height); + $this->graph->SetScale('lin'); $this->_renderTitle(); } // function _renderRadarPlotArea() private function _renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') { - $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); if ($labelCount > 0) { - $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); - $this->_graph->xaxis->SetTickLabels($datasetLabels); + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->graph->xaxis->SetTickLabels($datasetLabels); } - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); $seriesPlots = array(); if ($grouping == 'percentStacked') { $sumValues = $this->_percentageSumCalculation($groupID, $seriesCount); @@ -281,8 +273,8 @@ private function _renderPlotLine($groupID, $filled = false, $combination = false // Loop through each data series in turn for($i = 0; $i < $seriesCount; ++$i) { - $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); if ($grouping == 'percentStacked') { $dataValues = $this->_percentageAdjustValues($dataValues, $sumValues); @@ -306,12 +298,12 @@ private function _renderPlotLine($groupID, $filled = false, $combination = false if ($filled) { $seriesPlot->SetFilled(true); $seriesPlot->SetColor('black'); - $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); + $seriesPlot->SetFillColor(self::$colourSet[self::$_plotColour++]); } else { // Set the appropriate plot marker - $this->_formatPointMarker($seriesPlot, $marker); + $this->formatPointMarker($seriesPlot, $marker); } - $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); $seriesPlot->SetLegend($dataLabel); $seriesPlots[] = $seriesPlot; @@ -322,34 +314,34 @@ private function _renderPlotLine($groupID, $filled = false, $combination = false } else { $groupPlot = new AccLinePlot($seriesPlots); } - $this->_graph->Add($groupPlot); + $this->graph->Add($groupPlot); } // function _renderPlotLine() private function _renderPlotBar($groupID, $dimensions = '2d') { - $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); + $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); // Rotate for bar rather than column chart if (($groupID == 0) && ($rotation == 'bar')) { - $this->_graph->Set90AndMargin(); + $this->graph->Set90AndMargin(); } - $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); if ($labelCount > 0) { - $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); // Rotate for bar rather than column chart if ($rotation == 'bar') { $datasetLabels = array_reverse($datasetLabels); - $this->_graph->yaxis->SetPos('max'); - $this->_graph->yaxis->SetLabelAlign('center','top'); - $this->_graph->yaxis->SetLabelSide(SIDE_RIGHT); + $this->graph->yaxis->SetPos('max'); + $this->graph->yaxis->SetLabelAlign('center','top'); + $this->graph->yaxis->SetLabelSide(SIDE_RIGHT); } - $this->_graph->xaxis->SetTickLabels($datasetLabels); + $this->graph->xaxis->SetTickLabels($datasetLabels); } - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); $seriesPlots = array(); if ($grouping == 'percentStacked') { $sumValues = $this->_percentageSumCalculation($groupID, $seriesCount); @@ -357,7 +349,7 @@ private function _renderPlotBar($groupID, $dimensions = '2d') { // Loop through each data series in turn for($j = 0; $j < $seriesCount; ++$j) { - $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); if ($grouping == 'percentStacked') { $dataValues = $this->_percentageAdjustValues($dataValues, $sumValues); } @@ -378,14 +370,14 @@ private function _renderPlotBar($groupID, $dimensions = '2d') { } $seriesPlot = new BarPlot($dataValues); $seriesPlot->SetColor('black'); - $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); + $seriesPlot->SetFillColor(self::$colourSet[self::$_plotColour++]); if ($dimensions == '3d') { $seriesPlot->SetShadow(); } - if (!$this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { + if (!$this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { $dataLabel = ''; } else { - $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); } $seriesPlot->SetLegend($dataLabel); @@ -407,21 +399,21 @@ private function _renderPlotBar($groupID, $dimensions = '2d') { } } - $this->_graph->Add($groupPlot); + $this->graph->Add($groupPlot); } // function _renderPlotBar() private function _renderPlotScatter($groupID, $bubble) { - $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - $scatterStyle = $bubbleSize = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $scatterStyle = $bubbleSize = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); $seriesPlots = array(); // Loop through each data series in turn for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); foreach ($dataValuesY as $k => $dataValueY) { $dataValuesY[$k] = $k; @@ -430,43 +422,43 @@ private function _renderPlotScatter($groupID, $bubble) { $seriesPlot = new ScatterPlot($dataValuesX, $dataValuesY); if ($scatterStyle == 'lineMarker') { $seriesPlot->SetLinkPoints(); - $seriesPlot->link->SetColor(self::$_colourSet[self::$_plotColour]); + $seriesPlot->link->SetColor(self::$colourSet[self::$_plotColour]); } elseif ($scatterStyle == 'smoothMarker') { $spline = new Spline($dataValuesY, $dataValuesX); - list($splineDataY, $splineDataX) = $spline->Get(count($dataValuesX) * self::$_width / 20); + list($splineDataY, $splineDataX) = $spline->Get(count($dataValuesX) * self::$width / 20); $lplot = new LinePlot($splineDataX, $splineDataY); - $lplot->SetColor(self::$_colourSet[self::$_plotColour]); + $lplot->SetColor(self::$colourSet[self::$_plotColour]); - $this->_graph->Add($lplot); + $this->graph->Add($lplot); } if ($bubble) { - $this->_formatPointMarker($seriesPlot,'dot'); + $this->formatPointMarker($seriesPlot,'dot'); $seriesPlot->mark->SetColor('black'); $seriesPlot->mark->SetSize($bubbleSize); } else { - $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - $this->_formatPointMarker($seriesPlot, $marker); + $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + $this->formatPointMarker($seriesPlot, $marker); } - $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); $seriesPlot->SetLegend($dataLabel); - $this->_graph->Add($seriesPlot); + $this->graph->Add($seriesPlot); } } // function _renderPlotScatter() private function _renderPlotRadar($groupID) { - $radarStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + $radarStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); $seriesPlots = array(); // Loop through each data series in turn for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); $dataValues = array(); foreach ($dataValuesY as $k => $dataValueY) { @@ -477,51 +469,51 @@ private function _renderPlotRadar($groupID) { $tmp = array_shift($dataValuesX); $dataValuesX[] = $tmp; - $this->_graph->SetTitles(array_reverse($dataValues)); + $this->graph->SetTitles(array_reverse($dataValues)); $seriesPlot = new RadarPlot(array_reverse($dataValuesX)); - $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); - $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetColor(self::$colourSet[self::$_plotColour++]); if ($radarStyle == 'filled') { - $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour]); + $seriesPlot->SetFillColor(self::$colourSet[self::$_plotColour]); } - $this->_formatPointMarker($seriesPlot, $marker); + $this->formatPointMarker($seriesPlot, $marker); $seriesPlot->SetLegend($dataLabel); - $this->_graph->Add($seriesPlot); + $this->graph->Add($seriesPlot); } } // function _renderPlotRadar() private function _renderPlotContour($groupID) { - $contourStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + $contourStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); $seriesPlots = array(); $dataValues = array(); // Loop through each data series in turn for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); $dataValues[$i] = $dataValuesX; } $seriesPlot = new ContourPlot($dataValues); - $this->_graph->Add($seriesPlot); + $this->graph->Add($seriesPlot); } // function _renderPlotContour() private function _renderPlotStock($groupID) { - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $plotOrder = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $plotOrder = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); $dataValues = array(); // Loop through each data series in turn and build the plot arrays foreach ($plotOrder as $i => $v) { - $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); foreach ($dataValuesX as $j => $dataValueX) { $dataValues[$plotOrder[$i]][$j] = $dataValueX; } @@ -539,17 +531,17 @@ private function _renderPlotStock($groupID) { } // Set the x-axis labels - $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); if ($labelCount > 0) { - $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); - $this->_graph->xaxis->SetTickLabels($datasetLabels); + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->graph->xaxis->SetTickLabels($datasetLabels); } $seriesPlot = new StockPlot($dataValuesPlot); $seriesPlot->SetWidth(20); - $this->_graph->Add($seriesPlot); + $this->graph->Add($seriesPlot); } // function _renderPlotStock() @@ -620,23 +612,23 @@ private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = Fa $iLimit = ($multiplePlots) ? $groupCount : 1; for($groupID = 0; $groupID < $iLimit; ++$groupID) { - $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - $exploded = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $exploded = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); if ($groupID == 0) { - $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); if ($labelCount > 0) { - $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); } } - $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); $seriesPlots = array(); // For pie charts, we only display the first series: doughnut charts generally display all series $jLimit = ($multiplePlots) ? $seriesCount : 1; // Loop through each data series in turn for($j = 0; $j < $jLimit; ++$j) { - $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); // Fill in any missing values in the $dataValues array $testCurrentIndex = 0; @@ -666,7 +658,7 @@ private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = Fa $seriesPlot->SetMidColor('white'); } - $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + $seriesPlot->SetColor(self::$colourSet[self::$_plotColour++]); if (count($datasetLabels) > 0) $seriesPlot->SetLabels(array_fill(0,count($datasetLabels),'')); if ($dimensions != '3d') { @@ -679,7 +671,7 @@ private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = Fa $seriesPlot->SetLegends($datasetLabels); } - $this->_graph->Add($seriesPlot); + $this->graph->Add($seriesPlot); } } } // function _renderPieChart() @@ -729,7 +721,7 @@ private function _renderCombinationChart($groupCount, $dimensions, $outputDestin for($i = 0; $i < $groupCount; ++$i) { $dimensions = null; - $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); switch ($chartType) { case 'area3DChart' : $dimensions = '3d'; @@ -753,14 +745,14 @@ private function _renderCombinationChart($groupCount, $dimensions, $outputDestin $this->_renderPlotScatter($i,true); break; default : - $this->_graph = null; + $this->graph = null; return false; } } $this->_renderLegend(); - $this->_graph->Stroke($outputDestination); + $this->graph->Stroke($outputDestination); return true; } // function _renderCombinationChart() @@ -768,15 +760,15 @@ private function _renderCombinationChart($groupCount, $dimensions, $outputDestin public function render($outputDestination) { self::$_plotColour = 0; - $groupCount = $this->_chart->getPlotArea()->getPlotGroupCount(); + $groupCount = $this->chart->getPlotArea()->getPlotGroupCount(); $dimensions = null; if ($groupCount == 1) { - $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); + $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); } else { $chartTypes = array(); for($i = 0; $i < $groupCount; ++$i) { - $chartTypes[] = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + $chartTypes[] = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); } $chartTypes = array_unique($chartTypes); if (count($chartTypes) == 1) { @@ -838,9 +830,9 @@ public function render($outputDestination) { } $this->_renderLegend(); - $this->_graph->Stroke($outputDestination); + $this->graph->Stroke($outputDestination); return true; - } // function render() + } /** @@ -848,8 +840,7 @@ public function render($outputDestination) { */ public function __construct(PHPExcel_Chart $chart) { - $this->_graph = null; - $this->_chart = $chart; - } // function __construct() - -} // PHPExcel_Chart_Renderer_jpgraph + $this->graph = null; + $this->chart = $chart; + } +} diff --git a/Classes/PHPExcel/Chart/Title.php b/Classes/PHPExcel/Chart/Title.php index c68a0b91a..d8dc14f2b 100644 --- a/Classes/PHPExcel/Chart/Title.php +++ b/Classes/PHPExcel/Chart/Title.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Chart_Title * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Chart_Title - * - * @category PHPExcel - * @package PHPExcel_Chart - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Chart_Title { @@ -41,22 +33,22 @@ class PHPExcel_Chart_Title * * @var string */ - private $_caption = null; + private $caption = null; /** * Title Layout * * @var PHPExcel_Chart_Layout */ - private $_layout = null; + private $layout = null; /** * Create a new PHPExcel_Chart_Title */ public function __construct($caption = null, PHPExcel_Chart_Layout $layout = null) { - $this->_caption = $caption; - $this->_layout = $layout; + $this->caption = $caption; + $this->layout = $layout; } /** @@ -64,8 +56,9 @@ public function __construct($caption = null, PHPExcel_Chart_Layout $layout = nul * * @return string */ - public function getCaption() { - return $this->_caption; + public function getCaption() + { + return $this->caption; } /** @@ -74,8 +67,9 @@ public function getCaption() { * @param string $caption * @return PHPExcel_Chart_Title */ - public function setCaption($caption = null) { - $this->_caption = $caption; + public function setCaption($caption = null) + { + $this->caption = $caption; return $this; } @@ -85,8 +79,8 @@ public function setCaption($caption = null) { * * @return PHPExcel_Chart_Layout */ - public function getLayout() { - return $this->_layout; + public function getLayout() + { + return $this->layout; } - } From 96f3d0e6eeba904ed643dc6c798cda6f96831d8f Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Fri, 15 May 2015 12:55:10 +0200 Subject: [PATCH 371/467] PSR-2 : Fixes --- Classes/PHPExcel/Comment.php | 69 +- Classes/PHPExcel/Exception.php | 6 +- Classes/PHPExcel/HashTable.php | 2 +- Classes/PHPExcel/IOFactory.php | 10 +- Classes/PHPExcel/NamedRange.php | 48 +- Classes/PHPExcel/ReferenceHelper.php | 121 +- Classes/PHPExcel/Shared/Drawing.php | 120 +- Classes/PHPExcel/Shared/Escher.php | 1 - Classes/PHPExcel/Shared/File.php | 42 +- Classes/PHPExcel/Shared/OLE.php | 41 +- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 10075 ++++++++-------- Classes/PHPExcel/Shared/ZipStreamWrapper.php | 40 +- Classes/PHPExcel/Style.php | 3 +- .../PHPExcel/Writer/Excel2007/DocProps.php | 10 +- Classes/PHPExcel/Writer/Excel2007/Drawing.php | 517 +- .../PHPExcel/Writer/Excel2007/StringTable.php | 7 +- .../PHPExcel/Writer/Excel2007/Worksheet.php | 406 +- Classes/PHPExcel/Writer/Excel5/Parser.php | 44 +- 18 files changed, 5719 insertions(+), 5843 deletions(-) diff --git a/Classes/PHPExcel/Comment.php b/Classes/PHPExcel/Comment.php index bdadfbf5f..0546f4aee 100644 --- a/Classes/PHPExcel/Comment.php +++ b/Classes/PHPExcel/Comment.php @@ -98,10 +98,10 @@ class PHPExcel_Comment implements PHPExcel_IComparable public function __construct() { // Initialise variables - $this->_author = 'Author'; + $this->_author = 'Author'; $this->_text = new PHPExcel_RichText(); - $this->_fillColor = new PHPExcel_Style_Color('FFFFFFE1'); - $this->_alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + $this->_fillColor = new PHPExcel_Style_Color('FFFFFFE1'); + $this->_alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; } /** @@ -109,7 +109,8 @@ public function __construct() * * @return string */ - public function getAuthor() { + public function getAuthor() + { return $this->_author; } @@ -119,7 +120,8 @@ public function getAuthor() { * @param string $pValue * @return PHPExcel_Comment */ - public function setAuthor($pValue = '') { + public function setAuthor($pValue = '') + { $this->_author = $pValue; return $this; } @@ -129,7 +131,8 @@ public function setAuthor($pValue = '') { * * @return PHPExcel_RichText */ - public function getText() { + public function getText() + { return $this->_text; } @@ -139,7 +142,8 @@ public function getText() { * @param PHPExcel_RichText $pValue * @return PHPExcel_Comment */ - public function setText(PHPExcel_RichText $pValue) { + public function setText(PHPExcel_RichText $pValue) + { $this->_text = $pValue; return $this; } @@ -149,7 +153,8 @@ public function setText(PHPExcel_RichText $pValue) { * * @return string */ - public function getWidth() { + public function getWidth() + { return $this->_width; } @@ -159,7 +164,8 @@ public function getWidth() { * @param string $value * @return PHPExcel_Comment */ - public function setWidth($value = '96pt') { + public function setWidth($value = '96pt') + { $this->_width = $value; return $this; } @@ -169,7 +175,8 @@ public function setWidth($value = '96pt') { * * @return string */ - public function getHeight() { + public function getHeight() + { return $this->_height; } @@ -179,7 +186,8 @@ public function getHeight() { * @param string $value * @return PHPExcel_Comment */ - public function setHeight($value = '55.5pt') { + public function setHeight($value = '55.5pt') + { $this->_height = $value; return $this; } @@ -189,7 +197,8 @@ public function setHeight($value = '55.5pt') { * * @return string */ - public function getMarginLeft() { + public function getMarginLeft() + { return $this->_marginLeft; } @@ -199,7 +208,8 @@ public function getMarginLeft() { * @param string $value * @return PHPExcel_Comment */ - public function setMarginLeft($value = '59.25pt') { + public function setMarginLeft($value = '59.25pt') + { $this->_marginLeft = $value; return $this; } @@ -209,7 +219,8 @@ public function setMarginLeft($value = '59.25pt') { * * @return string */ - public function getMarginTop() { + public function getMarginTop() + { return $this->_marginTop; } @@ -219,7 +230,8 @@ public function getMarginTop() { * @param string $value * @return PHPExcel_Comment */ - public function setMarginTop($value = '1.5pt') { + public function setMarginTop($value = '1.5pt') + { $this->_marginTop = $value; return $this; } @@ -229,7 +241,8 @@ public function setMarginTop($value = '1.5pt') { * * @return boolean */ - public function getVisible() { + public function getVisible() + { return $this->_visible; } @@ -239,7 +252,8 @@ public function getVisible() { * @param boolean $value * @return PHPExcel_Comment */ - public function setVisible($value = false) { + public function setVisible($value = false) + { $this->_visible = $value; return $this; } @@ -249,7 +263,8 @@ public function setVisible($value = false) { * * @return PHPExcel_Style_Color */ - public function getFillColor() { + public function getFillColor() + { return $this->_fillColor; } @@ -259,7 +274,8 @@ public function getFillColor() { * @param string $pValue * @return PHPExcel_Comment */ - public function setAlignment($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) { + public function setAlignment($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) + { $this->_alignment = $pValue; return $this; } @@ -269,7 +285,8 @@ public function setAlignment($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENE * * @return string */ - public function getAlignment() { + public function getAlignment() + { return $this->_alignment; } @@ -278,9 +295,10 @@ public function getAlignment() { * * @return string Hash code */ - public function getHashCode() { + public function getHashCode() + { return md5( - $this->_author + $this->_author . $this->_text->getHashCode() . $this->_width . $this->_height @@ -296,7 +314,8 @@ public function getHashCode() { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { @@ -312,8 +331,8 @@ public function __clone() { * * @return string */ - public function __toString() { + public function __toString() + { return $this->_text->getPlainText(); } - } diff --git a/Classes/PHPExcel/Exception.php b/Classes/PHPExcel/Exception.php index c2694adde..b27750ea2 100644 --- a/Classes/PHPExcel/Exception.php +++ b/Classes/PHPExcel/Exception.php @@ -33,7 +33,8 @@ * @package PHPExcel * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ -class PHPExcel_Exception extends Exception { +class PHPExcel_Exception extends Exception +{ /** * Error handler callback * @@ -43,7 +44,8 @@ class PHPExcel_Exception extends Exception { * @param mixed $line * @param mixed $context */ - public static function errorHandlerCallback($code, $string, $file, $line, $context) { + public static function errorHandlerCallback($code, $string, $file, $line, $context) + { $e = new self($string, $code); $e->line = $line; $e->file = $file; diff --git a/Classes/PHPExcel/HashTable.php b/Classes/PHPExcel/HashTable.php index 8ec020ba5..6fca1431f 100644 --- a/Classes/PHPExcel/HashTable.php +++ b/Classes/PHPExcel/HashTable.php @@ -157,7 +157,7 @@ public function getIndexForHashCode($pHashCode = '') public function getByIndex($pIndex = 0) { if (isset($this->_keyMap[$pIndex])) { - return $this->getByHashCode( $this->_keyMap[$pIndex] ); + return $this->getByHashCode($this->_keyMap[$pIndex]); } return null; diff --git a/Classes/PHPExcel/IOFactory.php b/Classes/PHPExcel/IOFactory.php index 5b9c63530..8b063cd70 100644 --- a/Classes/PHPExcel/IOFactory.php +++ b/Classes/PHPExcel/IOFactory.php @@ -69,7 +69,9 @@ class PHPExcel_IOFactory /** * Private constructor for PHPExcel_IOFactory */ - private function __construct() { } + private function __construct() + { + } /** * Get search locations @@ -135,7 +137,7 @@ public static function createWriter(PHPExcel $phpExcel, $writerType = '') $className = str_replace('{0}', $writerType, $searchLocation['class']); $instance = new $className($phpExcel); - if ($instance !== NULL) { + if ($instance !== null) { return $instance; } } @@ -165,7 +167,7 @@ public static function createReader($readerType = '') $className = str_replace('{0}', $readerType, $searchLocation['class']); $instance = new $className(); - if ($instance !== NULL) { + if ($instance !== null) { return $instance; } } @@ -222,7 +224,7 @@ public static function createReaderForFile($pFilename) // First, lucky guess by inspecting file extension $pathinfo = pathinfo($pFilename); - $extensionType = NULL; + $extensionType = null; if (isset($pathinfo['extension'])) { switch (strtolower($pathinfo['extension'])) { case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet diff --git a/Classes/PHPExcel/NamedRange.php b/Classes/PHPExcel/NamedRange.php index 6d1d73f9b..318bcf3b5 100644 --- a/Classes/PHPExcel/NamedRange.php +++ b/Classes/PHPExcel/NamedRange.php @@ -75,7 +75,7 @@ class PHPExcel_NamedRange public function __construct($pName = null, PHPExcel_Worksheet $pWorksheet, $pRange = 'A1', $pLocalOnly = false, $pScope = null) { // Validate data - if (($pName === NULL) || ($pWorksheet === NULL) || ($pRange === NULL)) { + if (($pName === null) || ($pWorksheet === null) || ($pRange === null)) { throw new PHPExcel_Exception('Parameters can not be null.'); } @@ -93,7 +93,8 @@ public function __construct($pName = null, PHPExcel_Worksheet $pWorksheet, $pRan * * @return string */ - public function getName() { + public function getName() + { return $this->_name; } @@ -103,18 +104,19 @@ public function getName() { * @param string $value * @return PHPExcel_NamedRange */ - public function setName($value = null) { - if ($value !== NULL) { + public function setName($value = null) + { + if ($value !== null) { // Old title $oldTitle = $this->_name; // Re-attach - if ($this->_worksheet !== NULL) { + if ($this->_worksheet !== null) { $this->_worksheet->getParent()->removeNamedRange($this->_name, $this->_worksheet); } $this->_name = $value; - if ($this->_worksheet !== NULL) { + if ($this->_worksheet !== null) { $this->_worksheet->getParent()->addNamedRange($this); } @@ -130,7 +132,8 @@ public function setName($value = null) { * * @return PHPExcel_Worksheet */ - public function getWorksheet() { + public function getWorksheet() + { return $this->_worksheet; } @@ -140,8 +143,9 @@ public function getWorksheet() { * @param PHPExcel_Worksheet $value * @return PHPExcel_NamedRange */ - public function setWorksheet(PHPExcel_Worksheet $value = null) { - if ($value !== NULL) { + public function setWorksheet(PHPExcel_Worksheet $value = null) + { + if ($value !== null) { $this->_worksheet = $value; } return $this; @@ -152,7 +156,8 @@ public function setWorksheet(PHPExcel_Worksheet $value = null) { * * @return string */ - public function getRange() { + public function getRange() + { return $this->_range; } @@ -162,8 +167,9 @@ public function getRange() { * @param string $value * @return PHPExcel_NamedRange */ - public function setRange($value = null) { - if ($value !== NULL) { + public function setRange($value = null) + { + if ($value !== null) { $this->_range = $value; } return $this; @@ -174,7 +180,8 @@ public function setRange($value = null) { * * @return bool */ - public function getLocalOnly() { + public function getLocalOnly() + { return $this->_localOnly; } @@ -184,7 +191,8 @@ public function getLocalOnly() { * @param bool $value * @return PHPExcel_NamedRange */ - public function setLocalOnly($value = false) { + public function setLocalOnly($value = false) + { $this->_localOnly = $value; $this->_scope = $value ? $this->_worksheet : null; return $this; @@ -195,7 +203,8 @@ public function setLocalOnly($value = false) { * * @return PHPExcel_Worksheet|null */ - public function getScope() { + public function getScope() + { return $this->_scope; } @@ -205,7 +214,8 @@ public function getScope() { * @param PHPExcel_Worksheet|null $value * @return PHPExcel_NamedRange */ - public function setScope(PHPExcel_Worksheet $value = null) { + public function setScope(PHPExcel_Worksheet $value = null) + { $this->_scope = $value; $this->_localOnly = ($value == null) ? false : true; return $this; @@ -218,14 +228,16 @@ public function setScope(PHPExcel_Worksheet $value = null) { * @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope * @return PHPExcel_NamedRange */ - public static function resolveRange($pNamedRange = '', PHPExcel_Worksheet $pSheet) { + public static function resolveRange($pNamedRange = '', PHPExcel_Worksheet $pSheet) + { return $pSheet->getParent()->getNamedRange($pNamedRange, $pSheet); } /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 5854629f6..90c782f89 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -46,8 +46,9 @@ class PHPExcel_ReferenceHelper * * @return PHPExcel_ReferenceHelper */ - public static function getInstance() { - if (!isset(self::$_instance) || (self::$_instance === NULL)) { + public static function getInstance() + { + if (!isset(self::$_instance) || (self::$_instance === null)) { self::$_instance = new PHPExcel_ReferenceHelper(); } @@ -57,7 +58,8 @@ public static function getInstance() { /** * Create a new PHPExcel_ReferenceHelper */ - protected function __construct() { + protected function __construct() + { } /** @@ -68,7 +70,8 @@ protected function __construct() { * @param string $b Second column to test (e.g. 'Z') * @return integer */ - public static function columnSort($a, $b) { + public static function columnSort($a, $b) + { return strcasecmp(strlen($a) . $a, strlen($b) . $b); } @@ -80,7 +83,8 @@ public static function columnSort($a, $b) { * @param string $b Second column to test (e.g. 'Z') * @return integer */ - public static function columnReverseSort($a, $b) { + public static function columnReverseSort($a, $b) + { return 1 - strcasecmp(strlen($a) . $a, strlen($b) . $b); } @@ -92,9 +96,10 @@ public static function columnReverseSort($a, $b) { * @param string $b Second cell to test (e.g. 'Z1') * @return integer */ - public static function cellSort($a, $b) { - sscanf($a,'%[A-Z]%d', $ac, $ar); - sscanf($b,'%[A-Z]%d', $bc, $br); + public static function cellSort($a, $b) + { + sscanf($a, '%[A-Z]%d', $ac, $ar); + sscanf($b, '%[A-Z]%d', $bc, $br); if ($ar == $br) { return strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); @@ -110,9 +115,10 @@ public static function cellSort($a, $b) { * @param string $b Second cell to test (e.g. 'Z1') * @return integer */ - public static function cellReverseSort($a, $b) { - sscanf($a,'%[A-Z]%d', $ac, $ar); - sscanf($b,'%[A-Z]%d', $bc, $br); + public static function cellReverseSort($a, $b) + { + sscanf($a, '%[A-Z]%d', $ac, $ar); + sscanf($b, '%[A-Z]%d', $bc, $br); if ($ar == $br) { return 1 - strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); @@ -130,20 +136,21 @@ public static function cellReverseSort($a, $b) { * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) * @return boolean */ - private static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols) { + private static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols) + { list($cellColumn, $cellRow) = PHPExcel_Cell::coordinateFromString($cellAddress); $cellColumnIndex = PHPExcel_Cell::columnIndexFromString($cellColumn); // Is cell within the range of rows/columns if we're deleting if ($pNumRows < 0 && ($cellRow >= ($beforeRow + $pNumRows)) && ($cellRow < $beforeRow)) { - return TRUE; + return true; } elseif ($pNumCols < 0 && ($cellColumnIndex >= ($beforeColumnIndex + $pNumCols)) && ($cellColumnIndex < $beforeColumnIndex)) { - return TRUE; + return true; } - return FALSE; + return false; } /** @@ -198,7 +205,7 @@ protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumC foreach ($aComments as $key => &$value) { // Any comments inside a deleted range will be ignored if (!self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { - // Otherwise build a new array of comments indexed by the adjusted cell reference + // Otherwise build a new array of comments indexed by the adjusted cell reference $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); $aNewComments[$newReference] = $value; } @@ -220,15 +227,13 @@ protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumC protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); + ($pNumCols > 0 || $pNumRows > 0) ? uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); foreach ($aHyperlinkCollection as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { - $pSheet->setHyperlink( $newReference, $value ); - $pSheet->setHyperlink( $key, null ); + $pSheet->setHyperlink($newReference, $value); + $pSheet->setHyperlink($key, null); } } } @@ -246,14 +251,13 @@ protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNu protected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aDataValidationCollection = $pSheet->getDataValidationCollection(); - ($pNumCols > 0 || $pNumRows > 0) ? - uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : - uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); + ($pNumCols > 0 || $pNumRows > 0) ? uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); + foreach ($aDataValidationCollection as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { - $pSheet->setDataValidation( $newReference, $value ); - $pSheet->setDataValidation( $key, null ); + $pSheet->setDataValidation($newReference, $value); + $pSheet->setDataValidation($key, null); } } } @@ -298,8 +302,8 @@ protected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, foreach ($aProtectedCells as $key => $value) { $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); if ($key != $newReference) { - $pSheet->protectCells( $newReference, $value, true ); - $pSheet->unprotectCells( $key ); + $pSheet->protectCells($newReference, $value, true); + $pSheet->unprotectCells($key); } } } @@ -372,7 +376,7 @@ protected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $ * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing * @throws PHPExcel_Exception */ - public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, PHPExcel_Worksheet $pSheet = NULL) + public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, PHPExcel_Worksheet $pSheet = null) { $remove = ($pNumCols < 0 || $pNumRows < 0); $aCellCollection = $pSheet->getCellCollection(); @@ -442,8 +446,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P if ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) { // Formula should be adjusted $pSheet->getCell($newCoordinates) - ->setValue($this->updateFormulaReferences($cell->getValue(), - $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); + ->setValue($this->updateFormulaReferences($cell->getValue(), $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); } else { // Formula should not be adjusted $pSheet->getCell($newCoordinates)->setValue($cell->getValue()); @@ -451,14 +454,12 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P // Clear the original cell $pSheet->getCellCacheController()->deleteCacheData($cellID); - } else { /* We don't need to update styles for rows/columns before our insertion position, but we do still need to adjust any formulae in those cells */ if ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) { // Formula should be adjusted - $cell->setValue($this->updateFormulaReferences($cell->getValue(), - $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); + $cell->setValue($this->updateFormulaReferences($cell->getValue(), $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); } } @@ -472,7 +473,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) { // Style - $coordinate = PHPExcel_Cell::stringFromColumnIndex( $beforeColumnIndex - 2 ) . $i; + $coordinate = PHPExcel_Cell::stringFromColumnIndex($beforeColumnIndex - 2) . $i; if ($pSheet->cellExists($coordinate)) { $xfIndex = $pSheet->getCell($coordinate)->getXfIndex(); $conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ? @@ -594,17 +595,17 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } } } - $pSheet->setAutoFilter( $this->updateCellReference($autoFilterRange, $pBefore, $pNumCols, $pNumRows) ); + $pSheet->setAutoFilter($this->updateCellReference($autoFilterRange, $pBefore, $pNumCols, $pNumRows)); } // Update worksheet: freeze pane if ($pSheet->getFreezePane() != '') { - $pSheet->freezePane( $this->updateCellReference($pSheet->getFreezePane(), $pBefore, $pNumCols, $pNumRows) ); + $pSheet->freezePane($this->updateCellReference($pSheet->getFreezePane(), $pBefore, $pNumCols, $pNumRows)); } // Page setup if ($pSheet->getPageSetup()->isPrintAreaSet()) { - $pSheet->getPageSetup()->setPrintArea( $this->updateCellReference($pSheet->getPageSetup()->getPrintArea(), $pBefore, $pNumCols, $pNumRows) ); + $pSheet->getPageSetup()->setPrintArea($this->updateCellReference($pSheet->getPageSetup()->getPrintArea(), $pBefore, $pNumCols, $pNumRows)); } // Update worksheet: drawings @@ -620,9 +621,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P if (count($pSheet->getParent()->getNamedRanges()) > 0) { foreach ($pSheet->getParent()->getNamedRanges() as $namedRange) { if ($namedRange->getWorksheet()->getHashCode() == $pSheet->getHashCode()) { - $namedRange->setRange( - $this->updateCellReference($namedRange->getRange(), $pBefore, $pNumCols, $pNumRows) - ); + $namedRange->setRange($this->updateCellReference($namedRange->getRange(), $pBefore, $pNumCols, $pNumRows)); } } } @@ -642,7 +641,8 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P * @return string Updated formula * @throws PHPExcel_Exception */ - public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, $sheetName = '') { + public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, $sheetName = '') + { // Update cell references in the formula $formulaBlocks = explode('"', $pFormula); $i = false; @@ -657,8 +657,8 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo foreach ($matches as $match) { $fromString = ($match[2] > '') ? $match[2].'!' : ''; $fromString .= $match[3].':'.$match[4]; - $modified3 = substr($this->updateCellReference('$A'.$match[3], $pBefore, $pNumCols, $pNumRows),2); - $modified4 = substr($this->updateCellReference('$A'.$match[4], $pBefore, $pNumCols, $pNumRows),2); + $modified3 = substr($this->updateCellReference('$A'.$match[3], $pBefore, $pNumCols, $pNumRows), 2); + $modified4 = substr($this->updateCellReference('$A'.$match[4], $pBefore, $pNumCols, $pNumRows), 2); if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { @@ -682,8 +682,8 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo foreach ($matches as $match) { $fromString = ($match[2] > '') ? $match[2].'!' : ''; $fromString .= $match[3].':'.$match[4]; - $modified3 = substr($this->updateCellReference($match[3].'$1', $pBefore, $pNumCols, $pNumRows),0,-2); - $modified4 = substr($this->updateCellReference($match[4].'$1', $pBefore, $pNumCols, $pNumRows),0,-2); + $modified3 = substr($this->updateCellReference($match[3].'$1', $pBefore, $pNumCols, $pNumRows), 0, -2); + $modified4 = substr($this->updateCellReference($match[4].'$1', $pBefore, $pNumCols, $pNumRows), 0, -2); if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { @@ -781,7 +781,8 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo * @return string Updated cell range * @throws PHPExcel_Exception */ - public function updateCellReference($pCellRange = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + public function updateCellReference($pCellRange = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) + { // Is it in another worksheet? Will not have to update anything. if (strpos($pCellRange, "!") !== false) { return $pCellRange; @@ -805,7 +806,8 @@ public function updateCellReference($pCellRange = 'A1', $pBefore = 'A1', $pNumCo * @param string $oldName Old name (name to replace) * @param string $newName New name */ - public function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName = '') { + public function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName = '') + { if ($oldName == '') { return; } @@ -813,7 +815,7 @@ public function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName foreach ($pPhpExcel->getWorksheetIterator() as $sheet) { foreach ($sheet->getCellCollection(false) as $cellID) { $cell = $sheet->getCell($cellID); - if (($cell !== NULL) && ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA)) { + if (($cell !== null) && ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA)) { $formula = $cell->getValue(); if (strpos($formula, $oldName) !== false) { $formula = str_replace("'" . $oldName . "'!", "'" . $newName . "'!", $formula); @@ -835,7 +837,8 @@ public function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName * @return string Updated cell range * @throws PHPExcel_Exception */ - private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) + { if (strpos($pCellRange,':') !== false || strpos($pCellRange, ',') !== false) { // Update range $range = PHPExcel_Cell::splitRange($pCellRange); @@ -872,23 +875,22 @@ private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumC * @return string Updated cell reference * @throws PHPExcel_Exception */ - private function _updateSingleCellReference($pCellReference = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + private function _updateSingleCellReference($pCellReference = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) + { if (strpos($pCellReference, ':') === false && strpos($pCellReference, ',') === false) { // Get coordinates of $pBefore - list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString( $pBefore ); + list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString($pBefore); // Get coordinates of $pCellReference - list($newColumn, $newRow) = PHPExcel_Cell::coordinateFromString( $pCellReference ); + list($newColumn, $newRow) = PHPExcel_Cell::coordinateFromString($pCellReference); // Verify which parts should be updated - $updateColumn = (($newColumn{0} != '$') && ($beforeColumn{0} != '$') && - PHPExcel_Cell::columnIndexFromString($newColumn) >= PHPExcel_Cell::columnIndexFromString($beforeColumn)); - $updateRow = (($newRow{0} != '$') && ($beforeRow{0} != '$') && - $newRow >= $beforeRow); + $updateColumn = (($newColumn{0} != '$') && ($beforeColumn{0} != '$') && (PHPExcel_Cell::columnIndexFromString($newColumn) >= PHPExcel_Cell::columnIndexFromString($beforeColumn))); + $updateRow = (($newRow{0} != '$') && ($beforeRow{0} != '$') && $newRow >= $beforeRow); // Create new column reference if ($updateColumn) { - $newColumn = PHPExcel_Cell::stringFromColumnIndex( PHPExcel_Cell::columnIndexFromString($newColumn) - 1 + $pNumCols ); + $newColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($newColumn) - 1 + $pNumCols); } // Create new row reference @@ -908,7 +910,8 @@ private function _updateSingleCellReference($pCellReference = 'A1', $pBefore = ' * * @throws PHPExcel_Exception */ - public final function __clone() { + final public function __clone() + { throw new PHPExcel_Exception("Cloning a Singleton is not allowed!"); } } diff --git a/Classes/PHPExcel/Shared/Drawing.php b/Classes/PHPExcel/Shared/Drawing.php index 90d0911be..4125815d4 100644 --- a/Classes/PHPExcel/Shared/Drawing.php +++ b/Classes/PHPExcel/Shared/Drawing.php @@ -41,7 +41,8 @@ class PHPExcel_Shared_Drawing * @param int $pValue Value in pixels * @return int Value in EMU */ - public static function pixelsToEMU($pValue = 0) { + public static function pixelsToEMU($pValue = 0) + { return round($pValue * 9525); } @@ -51,7 +52,8 @@ public static function pixelsToEMU($pValue = 0) { * @param int $pValue Value in EMU * @return int Value in pixels */ - public static function EMUToPixels($pValue = 0) { + public static function EMUToPixels($pValue = 0) + { if ($pValue != 0) { return round($pValue / 9525); } else { @@ -68,22 +70,19 @@ public static function EMUToPixels($pValue = 0) { * @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook * @return int Value in cell dimension */ - public static function pixelsToCellDimension($pValue = 0, PHPExcel_Style_Font $pDefaultFont) { + public static function pixelsToCellDimension($pValue = 0, PHPExcel_Style_Font $pDefaultFont) + { // Font name and size $name = $pDefaultFont->getName(); $size = $pDefaultFont->getSize(); if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) { // Exact width can be determined - $colWidth = $pValue - * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width'] - / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px']; + $colWidth = $pValue * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width'] / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px']; } else { // We don't have data for this particular font and size, use approximation by // extrapolating from Calibri 11 - $colWidth = $pValue * 11 - * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] - / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] / $size; + $colWidth = $pValue * 11 * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] / $size; } return $colWidth; @@ -96,23 +95,19 @@ public static function pixelsToCellDimension($pValue = 0, PHPExcel_Style_Font $p * @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook * @return int Value in pixels */ - public static function cellDimensionToPixels($pValue = 0, PHPExcel_Style_Font $pDefaultFont) { + public static function cellDimensionToPixels($pValue = 0, PHPExcel_Style_Font $pDefaultFont) + { // Font name and size $name = $pDefaultFont->getName(); $size = $pDefaultFont->getSize(); if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) { // Exact width can be determined - $colWidth = $pValue - * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px'] - / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width']; - + $colWidth = $pValue * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px'] / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width']; } else { // We don't have data for this particular font and size, use approximation by // extrapolating from Calibri 11 - $colWidth = $pValue * $size - * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] - / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] / 11; + $colWidth = $pValue * $size * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] / 11; } // Round pixels to closest integer @@ -127,7 +122,8 @@ public static function cellDimensionToPixels($pValue = 0, PHPExcel_Style_Font $p * @param int $pValue Value in pixels * @return int Value in points */ - public static function pixelsToPoints($pValue = 0) { + public static function pixelsToPoints($pValue = 0) + { return $pValue * 0.67777777; } @@ -137,7 +133,8 @@ public static function pixelsToPoints($pValue = 0) { * @param int $pValue Value in points * @return int Value in pixels */ - public static function pointsToPixels($pValue = 0) { + public static function pointsToPixels($pValue = 0) + { if ($pValue != 0) { return (int) ceil($pValue * 1.333333333); } else { @@ -151,7 +148,8 @@ public static function pointsToPixels($pValue = 0) { * @param int $pValue Degrees * @return int Angle */ - public static function degreesToAngle($pValue = 0) { + public static function degreesToAngle($pValue = 0) + { return (int)round($pValue * 60000); } @@ -161,7 +159,8 @@ public static function degreesToAngle($pValue = 0) { * @param int $pValue Angle * @return int Degrees */ - public static function angleToDegrees($pValue = 0) { + public static function angleToDegrees($pValue = 0) + { if ($pValue != 0) { return round($pValue / 60000); } else { @@ -179,94 +178,93 @@ public static function angleToDegrees($pValue = 0) { public static function imagecreatefrombmp($p_sFile) { // Load the image into a string - $file = fopen($p_sFile,"rb"); - $read = fread($file,10); - while (!feof($file)&&($read<>"")) - $read .= fread($file,1024); + $file = fopen($p_sFile, "rb"); + $read = fread($file, 10); + while (!feof($file) && ($read<>"")) { + $read .= fread($file, 1024); + } - $temp = unpack("H*", $read); - $hex = $temp[1]; - $header = substr($hex,0,108); + $temp = unpack("H*", $read); + $hex = $temp[1]; + $header = substr($hex, 0, 108); // Process the header // Structure: http://www.fastgraph.com/help/bmp_header_format.html - if (substr($header,0,4)=="424d") - { + if (substr($header, 0, 4)=="424d") { // Cut it in parts of 2 bytes - $header_parts = str_split($header,2); + $header_parts = str_split($header, 2); // Get the width 4 bytes - $width = hexdec($header_parts[19].$header_parts[18]); + $width = hexdec($header_parts[19].$header_parts[18]); // Get the height 4 bytes - $height = hexdec($header_parts[23].$header_parts[22]); + $height = hexdec($header_parts[23].$header_parts[22]); // Unset the header params unset($header_parts); } // Define starting X and Y - $x = 0; - $y = 1; + $x = 0; + $y = 1; // Create newimage - $image = imagecreatetruecolor($width, $height); + $image = imagecreatetruecolor($width, $height); // Grab the body from the image - $body = substr($hex,108); + $body = substr($hex, 108); // Calculate if padding at the end-line is needed // Divided by two to keep overview. // 1 byte = 2 HEX-chars - $body_size = (strlen($body)/2); - $header_size = ($width*$height); + $body_size = (strlen($body)/2); + $header_size = ($width*$height); // Use end-line padding? Only when needed - $usePadding = ($body_size>($header_size*3)+4); + $usePadding = ($body_size>($header_size*3)+4); // Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption // Calculate the next DWORD-position in the body - for ($i=0;$i<$body_size;$i+=3) - { + for ($i = 0 ; $i < $body_size ; $i += 3) { // Calculate line-ending and padding - if ($x>=$width) - { - // If padding needed, ignore image-padding - // Shift i to the ending of the current 32-bit-block - if ($usePadding) - $i += $width%4; + if ($x >= $width) { + // If padding needed, ignore image-padding + // Shift i to the ending of the current 32-bit-block + if ($usePadding) { + $i += $width%4; + } // Reset horizontal position - $x = 0; + $x = 0; // Raise the height-position (bottom-up) $y++; // Reached the image-height? Break the for-loop - if ($y>$height) + if ($y > $height) { break; + } } - // Calculation of the RGB-pixel (defined as BGR in image-data) - // Define $i_pos as absolute position in the body - $i_pos = $i*2; - $r = hexdec($body[$i_pos+4].$body[$i_pos+5]); - $g = hexdec($body[$i_pos+2].$body[$i_pos+3]); - $b = hexdec($body[$i_pos].$body[$i_pos+1]); + // Calculation of the RGB-pixel (defined as BGR in image-data) + // Define $i_pos as absolute position in the body + $i_pos = $i * 2; + $r = hexdec($body[$i_pos+4].$body[$i_pos+5]); + $g = hexdec($body[$i_pos+2].$body[$i_pos+3]); + $b = hexdec($body[$i_pos].$body[$i_pos+1]); - // Calculate and draw the pixel - $color = imagecolorallocate($image, $r, $g, $b); + // Calculate and draw the pixel + $color = imagecolorallocate($image, $r, $g, $b); imagesetpixel($image, $x, $height-$y, $color); - // Raise the horizontal position + // Raise the horizontal position $x++; } - // Unset the body / free the memory + // Unset the body / free the memory unset($body); // Return image-object return $image; } - } diff --git a/Classes/PHPExcel/Shared/Escher.php b/Classes/PHPExcel/Shared/Escher.php index 67b346ee3..948d409b6 100644 --- a/Classes/PHPExcel/Shared/Escher.php +++ b/Classes/PHPExcel/Shared/Escher.php @@ -87,5 +87,4 @@ public function setDgContainer($dgContainer) { return $this->_dgContainer = $dgContainer; } - } diff --git a/Classes/PHPExcel/Shared/File.php b/Classes/PHPExcel/Shared/File.php index f1de32427..e2af00ee2 100644 --- a/Classes/PHPExcel/Shared/File.php +++ b/Classes/PHPExcel/Shared/File.php @@ -41,7 +41,7 @@ class PHPExcel_Shared_File * @protected * @var boolean */ - protected static $_useUploadTempDirectory = FALSE; + protected static $_useUploadTempDirectory = false; /** @@ -49,9 +49,10 @@ class PHPExcel_Shared_File * * @param boolean $useUploadTempDir Use File Upload Temporary directory (true or false) */ - public static function setUseUploadTempDirectory($useUploadTempDir = FALSE) { + public static function setUseUploadTempDirectory($useUploadTempDir = false) + { self::$_useUploadTempDirectory = (boolean) $useUploadTempDir; - } // function setUseUploadTempDirectory() + } /** @@ -59,9 +60,10 @@ public static function setUseUploadTempDirectory($useUploadTempDir = FALSE) { * * @return boolean Use File Upload Temporary directory (true or false) */ - public static function getUseUploadTempDirectory() { + public static function getUseUploadTempDirectory() + { return self::$_useUploadTempDirectory; - } // function getUseUploadTempDirectory() + } /** @@ -70,11 +72,12 @@ public static function getUseUploadTempDirectory() { * @param string $pFilename Filename * @return bool */ - public static function file_exists($pFilename) { + public static function file_exists($pFilename) + { // Sick construction, but it seems that // file_exists returns strange values when // doing the original file_exists on ZIP archives... - if ( strtolower(substr($pFilename, 0, 3)) == 'zip' ) { + if (strtolower(substr($pFilename, 0, 3)) == 'zip') { // Open ZIP file and verify if the file exists $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1); @@ -99,7 +102,8 @@ public static function file_exists($pFilename) { * @param string $pFilename * @return string */ - public static function realpath($pFilename) { + public static function realpath($pFilename) + { // Returnvalue $returnValue = ''; @@ -109,8 +113,8 @@ public static function realpath($pFilename) { } // Found something? - if ($returnValue == '' || ($returnValue === NULL)) { - $pathArray = explode('/' , $pFilename); + if ($returnValue == '' || ($returnValue === null)) { + $pathArray = explode('/', $pFilename); while (in_array('..', $pathArray) && $pathArray[0] != '..') { for ($i = 0; $i < count($pathArray); ++$i) { if ($pathArray[$i] == '..' && $i > 0) { @@ -137,10 +141,11 @@ public static function sys_get_temp_dir() if (self::$_useUploadTempDirectory) { // use upload-directory when defined to allow running on environments having very restricted // open_basedir configs - if (ini_get('upload_tmp_dir') !== FALSE) { + if (ini_get('upload_tmp_dir') !== false) { if ($temp = ini_get('upload_tmp_dir')) { - if (file_exists($temp)) + if (file_exists($temp)) { return realpath($temp); + } } } } @@ -149,13 +154,19 @@ public static function sys_get_temp_dir() // http://php.net/manual/en/function.sys-get-temp-dir.php#94119 if ( !function_exists('sys_get_temp_dir')) { if ($temp = getenv('TMP') ) { - if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + if ((!empty($temp)) && (file_exists($temp))) { + return realpath($temp); + } } if ($temp = getenv('TEMP') ) { - if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + if ((!empty($temp)) && (file_exists($temp))) { + return realpath($temp); + } } if ($temp = getenv('TMPDIR') ) { - if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + if ((!empty($temp)) && (file_exists($temp))) { + return realpath($temp); + } } // trick for creating a file in system's temporary dir @@ -174,5 +185,4 @@ public static function sys_get_temp_dir() // be called if we're running 5.2.1 or earlier return realpath(sys_get_temp_dir()); } - } diff --git a/Classes/PHPExcel/Shared/OLE.php b/Classes/PHPExcel/Shared/OLE.php index 581e96bb8..42a3c529f 100644 --- a/Classes/PHPExcel/Shared/OLE.php +++ b/Classes/PHPExcel/Shared/OLE.php @@ -159,7 +159,7 @@ public function read($file) for ($i = 0; $i < $bbatBlockCount; ++$i) { $pos = $this->_getBlockOffset($mbatBlocks[$i]); fseek($fh, $pos); - for ($j = 0 ; $j < $this->bigBlockSize / 4; ++$j) { + for ($j = 0; $j < $this->bigBlockSize / 4; ++$j) { $this->bbat[] = self::_readInt4($fh); } } @@ -198,8 +198,7 @@ public function getStream($blockIdOrPps) { static $isRegistered = false; if (!$isRegistered) { - stream_wrapper_register('ole-chainedblockstream', - 'PHPExcel_Shared_OLE_ChainedBlockStream'); + stream_wrapper_register('ole-chainedblockstream', 'PHPExcel_Shared_OLE_ChainedBlockStream'); $isRegistered = true; } @@ -266,7 +265,7 @@ private static function _readInt4($fh) public function _readPpsWks($blockId) { $fh = $this->getStream($blockId); - for ($pos = 0; ; $pos += 128) { + for ($pos = 0;; $pos += 128) { fseek($fh, $pos, SEEK_SET); $nameUtf16 = fread($fh, 64); $nameLength = self::_readInt2($fh); @@ -275,19 +274,18 @@ public function _readPpsWks($blockId) $name = str_replace("\x00", "", $nameUtf16); $type = self::_readInt1($fh); switch ($type) { - case self::OLE_PPS_TYPE_ROOT: - $pps = new PHPExcel_Shared_OLE_PPS_Root(null, null, array()); - $this->root = $pps; - break; - case self::OLE_PPS_TYPE_DIR: - $pps = new PHPExcel_Shared_OLE_PPS(null, null, null, null, null, - null, null, null, null, array()); - break; - case self::OLE_PPS_TYPE_FILE: - $pps = new PHPExcel_Shared_OLE_PPS_File($name); - break; - default: - continue; + case self::OLE_PPS_TYPE_ROOT: + $pps = new PHPExcel_Shared_OLE_PPS_Root(null, null, array()); + $this->root = $pps; + break; + case self::OLE_PPS_TYPE_DIR: + $pps = new PHPExcel_Shared_OLE_PPS(null, null, null, null, null, null, null, null, null, array()); + break; + case self::OLE_PPS_TYPE_FILE: + $pps = new PHPExcel_Shared_OLE_PPS_File($name); + break; + default: + continue; } fseek($fh, 1, SEEK_CUR); $pps->Type = $type; @@ -304,9 +302,7 @@ public function _readPpsWks($blockId) $this->_list[] = $pps; // check if the PPS tree (starting from root) is complete - if (isset($this->root) && - $this->_ppsTreeComplete($this->root->No)) { - + if (isset($this->root) && $this->_ppsTreeComplete($this->root->No)) { break; } } @@ -473,8 +469,7 @@ public static function LocalDate2OLE($date = null) // days from 1-1-1601 until the beggining of UNIX era $days = 134774; // calculate seconds - $big_date = $days*24*3600 + gmmktime(date("H", $date),date("i", $date),date("s", $date), - date("m", $date),date("d", $date),date("Y", $date)); + $big_date = $days*24*3600 + gmmktime(date("H", $date), date("i", $date), date("s", $date), date("m", $date), date("d", $date), date("Y", $date)); // multiply just to make MS happy $big_date *= 10000000; @@ -513,7 +508,7 @@ public static function OLE2LocalDate($string) } // factor used for separating numbers into 4 bytes parts - $factor = pow(2,32); + $factor = pow(2, 32); list(, $high_part) = unpack('V', substr($string, 4, 4)); list(, $low_part) = unpack('V', substr($string, 0, 4)); diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index 36cc902ba..effb8dd76 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -25,170 +25,170 @@ // $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $ // -------------------------------------------------------------------------------- - // ----- Constants - if (!defined('PCLZIP_READ_BLOCK_SIZE')) { - define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); - } - - // ----- File list separator - // In version 1.x of PclZip, the separator for file list is a space - // (which is not a very smart choice, specifically for windows paths !). - // A better separator should be a comma (,). This constant gives you the - // abilty to change that. - // However notice that changing this value, may have impact on existing - // scripts, using space separated filenames. - // Recommanded values for compatibility with older versions : - //define( 'PCLZIP_SEPARATOR', ' ' ); - // Recommanded values for smart separation of filenames. - if (!defined('PCLZIP_SEPARATOR')) { - define( 'PCLZIP_SEPARATOR', ',' ); - } - - // ----- Error configuration - // 0 : PclZip Class integrated error handling - // 1 : PclError external library error handling. By enabling this - // you must ensure that you have included PclError library. - // [2,...] : reserved for futur use - if (!defined('PCLZIP_ERROR_EXTERNAL')) { - define( 'PCLZIP_ERROR_EXTERNAL', 0 ); - } - - // ----- Optional static temporary directory - // By default temporary files are generated in the script current - // path. - // If defined : - // - MUST BE terminated by a '/'. - // - MUST be a valid, already created directory - // Samples : - // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); - // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); - if (!defined('PCLZIP_TEMPORARY_DIR')) { - define( 'PCLZIP_TEMPORARY_DIR', '' ); - } - - // ----- Optional threshold ratio for use of temporary files - // Pclzip sense the size of the file to add/extract and decide to - // use or not temporary file. The algorythm is looking for - // memory_limit of PHP and apply a ratio. - // threshold = memory_limit * ratio. - // Recommended values are under 0.5. Default 0.47. - // Samples : - // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 ); - if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { - define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 ); - } +// ----- Constants +if (!defined('PCLZIP_READ_BLOCK_SIZE')) { + define('PCLZIP_READ_BLOCK_SIZE', 2048); +} + +// ----- File list separator +// In version 1.x of PclZip, the separator for file list is a space +// (which is not a very smart choice, specifically for windows paths !). +// A better separator should be a comma (,). This constant gives you the +// abilty to change that. +// However notice that changing this value, may have impact on existing +// scripts, using space separated filenames. +// Recommanded values for compatibility with older versions : +//define('PCLZIP_SEPARATOR', ' '); +// Recommanded values for smart separation of filenames. +if (!defined('PCLZIP_SEPARATOR')) { + define('PCLZIP_SEPARATOR', ','); +} + +// ----- Error configuration +// 0 : PclZip Class integrated error handling +// 1 : PclError external library error handling. By enabling this +// you must ensure that you have included PclError library. +// [2,...] : reserved for futur use +if (!defined('PCLZIP_ERROR_EXTERNAL')) { + define('PCLZIP_ERROR_EXTERNAL', 0); +} + +// ----- Optional static temporary directory +// By default temporary files are generated in the script current +// path. +// If defined : +// - MUST BE terminated by a '/'. +// - MUST be a valid, already created directory +// Samples : +// define('PCLZIP_TEMPORARY_DIR', '/temp/'); +// define('PCLZIP_TEMPORARY_DIR', 'C:/Temp/'); +if (!defined('PCLZIP_TEMPORARY_DIR')) { + define('PCLZIP_TEMPORARY_DIR', ''); +} + +// ----- Optional threshold ratio for use of temporary files +// Pclzip sense the size of the file to add/extract and decide to +// use or not temporary file. The algorythm is looking for +// memory_limit of PHP and apply a ratio. +// threshold = memory_limit * ratio. +// Recommended values are under 0.5. Default 0.47. +// Samples : +// define('PCLZIP_TEMPORARY_FILE_RATIO', 0.5); +if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { + define('PCLZIP_TEMPORARY_FILE_RATIO', 0.47); +} // -------------------------------------------------------------------------------- // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** // -------------------------------------------------------------------------------- - // ----- Global variables - $g_pclzip_version = "2.8.2"; - - // ----- Error codes - // -1 : Unable to open file in binary write mode - // -2 : Unable to open file in binary read mode - // -3 : Invalid parameters - // -4 : File does not exist - // -5 : Filename is too long (max. 255) - // -6 : Not a valid zip file - // -7 : Invalid extracted file size - // -8 : Unable to create directory - // -9 : Invalid archive extension - // -10 : Invalid archive format - // -11 : Unable to delete file (unlink) - // -12 : Unable to rename file (rename) - // -13 : Invalid header checksum - // -14 : Invalid archive size - define( 'PCLZIP_ERR_USER_ABORTED', 2 ); - define( 'PCLZIP_ERR_NO_ERROR', 0 ); - define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); - define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); - define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); - define( 'PCLZIP_ERR_MISSING_FILE', -4 ); - define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); - define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); - define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); - define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); - define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); - define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); - define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); - define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); - define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); - define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); - define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); - define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); - define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); - define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); - define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); - define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); - define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); - - // ----- Options values - define( 'PCLZIP_OPT_PATH', 77001 ); - define( 'PCLZIP_OPT_ADD_PATH', 77002 ); - define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); - define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); - define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); - define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); - define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); - define( 'PCLZIP_OPT_BY_NAME', 77008 ); - define( 'PCLZIP_OPT_BY_INDEX', 77009 ); - define( 'PCLZIP_OPT_BY_EREG', 77010 ); - define( 'PCLZIP_OPT_BY_PREG', 77011 ); - define( 'PCLZIP_OPT_COMMENT', 77012 ); - define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); - define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); - define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); - define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); - define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); - // Having big trouble with crypt. Need to multiply 2 long int - // which is not correctly supported by PHP ... - //define( 'PCLZIP_OPT_CRYPT', 77018 ); - define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); - define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 ); - define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias - define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 ); - define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias - define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 ); - define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias - - // ----- File description attributes - define( 'PCLZIP_ATT_FILE_NAME', 79001 ); - define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); - define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); - define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); - define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); - define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); - - // ----- Call backs values - define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); - define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); - define( 'PCLZIP_CB_PRE_ADD', 78003 ); - define( 'PCLZIP_CB_POST_ADD', 78004 ); - /* For futur use - define( 'PCLZIP_CB_PRE_LIST', 78005 ); - define( 'PCLZIP_CB_POST_LIST', 78006 ); - define( 'PCLZIP_CB_PRE_DELETE', 78007 ); - define( 'PCLZIP_CB_POST_DELETE', 78008 ); - */ +// ----- Global variables +$g_pclzip_version = "2.8.2"; + +// ----- Error codes +// -1 : Unable to open file in binary write mode +// -2 : Unable to open file in binary read mode +// -3 : Invalid parameters +// -4 : File does not exist +// -5 : Filename is too long (max. 255) +// -6 : Not a valid zip file +// -7 : Invalid extracted file size +// -8 : Unable to create directory +// -9 : Invalid archive extension +// -10 : Invalid archive format +// -11 : Unable to delete file (unlink) +// -12 : Unable to rename file (rename) +// -13 : Invalid header checksum +// -14 : Invalid archive size +define('PCLZIP_ERR_USER_ABORTED', 2); +define('PCLZIP_ERR_NO_ERROR', 0); +define('PCLZIP_ERR_WRITE_OPEN_FAIL', -1); +define('PCLZIP_ERR_READ_OPEN_FAIL', -2); +define('PCLZIP_ERR_INVALID_PARAMETER', -3); +define('PCLZIP_ERR_MISSING_FILE', -4); +define('PCLZIP_ERR_FILENAME_TOO_LONG', -5); +define('PCLZIP_ERR_INVALID_ZIP', -6); +define('PCLZIP_ERR_BAD_EXTRACTED_FILE', -7); +define('PCLZIP_ERR_DIR_CREATE_FAIL', -8); +define('PCLZIP_ERR_BAD_EXTENSION', -9); +define('PCLZIP_ERR_BAD_FORMAT', -10); +define('PCLZIP_ERR_DELETE_FILE_FAIL', -11); +define('PCLZIP_ERR_RENAME_FILE_FAIL', -12); +define('PCLZIP_ERR_BAD_CHECKSUM', -13); +define('PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14); +define('PCLZIP_ERR_MISSING_OPTION_VALUE', -15); +define('PCLZIP_ERR_INVALID_OPTION_VALUE', -16); +define('PCLZIP_ERR_ALREADY_A_DIRECTORY', -17); +define('PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18); +define('PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19); +define('PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20); +define('PCLZIP_ERR_DIRECTORY_RESTRICTION', -21); + +// ----- Options values +define('PCLZIP_OPT_PATH', 77001); +define('PCLZIP_OPT_ADD_PATH', 77002); +define('PCLZIP_OPT_REMOVE_PATH', 77003); +define('PCLZIP_OPT_REMOVE_ALL_PATH', 77004); +define('PCLZIP_OPT_SET_CHMOD', 77005); +define('PCLZIP_OPT_EXTRACT_AS_STRING', 77006); +define('PCLZIP_OPT_NO_COMPRESSION', 77007); +define('PCLZIP_OPT_BY_NAME', 77008); +define('PCLZIP_OPT_BY_INDEX', 77009); +define('PCLZIP_OPT_BY_EREG', 77010); +define('PCLZIP_OPT_BY_PREG', 77011); +define('PCLZIP_OPT_COMMENT', 77012); +define('PCLZIP_OPT_ADD_COMMENT', 77013); +define('PCLZIP_OPT_PREPEND_COMMENT', 77014); +define('PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015); +define('PCLZIP_OPT_REPLACE_NEWER', 77016); +define('PCLZIP_OPT_STOP_ON_ERROR', 77017); +// Having big trouble with crypt. Need to multiply 2 long int +// which is not correctly supported by PHP ... +//define('PCLZIP_OPT_CRYPT', 77018); +define('PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019); +define('PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020); +define('PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020); // alias +define('PCLZIP_OPT_TEMP_FILE_ON', 77021); +define('PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021); // alias +define('PCLZIP_OPT_TEMP_FILE_OFF', 77022); +define('PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022); // alias + +// ----- File description attributes +define('PCLZIP_ATT_FILE_NAME', 79001); +define('PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002); +define('PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003); +define('PCLZIP_ATT_FILE_MTIME', 79004); +define('PCLZIP_ATT_FILE_CONTENT', 79005); +define('PCLZIP_ATT_FILE_COMMENT', 79006); + +// ----- Call backs values +define('PCLZIP_CB_PRE_EXTRACT', 78001); +define('PCLZIP_CB_POST_EXTRACT', 78002); +define('PCLZIP_CB_PRE_ADD', 78003); +define('PCLZIP_CB_POST_ADD', 78004); +/* For futur use +define('PCLZIP_CB_PRE_LIST', 78005); +define('PCLZIP_CB_POST_LIST', 78006); +define('PCLZIP_CB_PRE_DELETE', 78007); +define('PCLZIP_CB_POST_DELETE', 78008); +*/ - // -------------------------------------------------------------------------------- - // Class : PclZip - // Description : - // PclZip is the class that represent a Zip archive. - // The public methods allow the manipulation of the archive. - // Attributes : - // Attributes must not be accessed directly. - // Methods : - // PclZip() : Object creator - // create() : Creates the Zip archive - // listContent() : List the content of the Zip archive - // extract() : Extract the content of the archive - // properties() : List the properties of the archive - // -------------------------------------------------------------------------------- - class PclZip - { +// -------------------------------------------------------------------------------- +// Class : PclZip +// Description : +// PclZip is the class that represent a Zip archive. +// The public methods allow the manipulation of the archive. +// Attributes : +// Attributes must not be accessed directly. +// Methods : +// PclZip() : Object creator +// create() : Creates the Zip archive +// listContent() : List the content of the Zip archive +// extract() : Extract the content of the archive +// properties() : List the properties of the archive +// -------------------------------------------------------------------------------- +class PclZip +{ // ----- Filename of the zip file var $zipname = ''; @@ -198,5016 +198,4595 @@ class PclZip // ----- Internal error handling var $error_code = 1; var $error_string = ''; - + // ----- Current status of the magic_quotes_runtime // This value store the php configuration for magic_quotes // The class can then disable the magic_quotes and reset it after var $magic_quotes_status; - // -------------------------------------------------------------------------------- - // Function : PclZip() - // Description : - // Creates a PclZip object and set the name of the associated Zip archive - // filename. - // Note that no real action is taken, if the archive does not exist it is not - // created. Use create() for that. - // -------------------------------------------------------------------------------- - function PclZip($p_zipname) - { - - // ----- Tests the zlib - if (!function_exists('gzopen')) + // -------------------------------------------------------------------------------- + // Function : PclZip() + // Description : + // Creates a PclZip object and set the name of the associated Zip archive + // filename. + // Note that no real action is taken, if the archive does not exist it is not + // created. Use create() for that. + // -------------------------------------------------------------------------------- + function PclZip($p_zipname) { - die('Abort '.basename(__FILE__).' : Missing zlib extensions'); - } - - // ----- Set the attributes - $this->zipname = $p_zipname; - $this->zip_fd = 0; - $this->magic_quotes_status = -1; - - // ----- Return - return; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // create($p_filelist, $p_add_dir="", $p_remove_dir="") - // create($p_filelist, $p_option, $p_option_value, ...) - // Description : - // This method supports two different synopsis. The first one is historical. - // This method creates a Zip Archive. The Zip file is created in the - // filesystem. The files and directories indicated in $p_filelist - // are added in the archive. See the parameters description for the - // supported format of $p_filelist. - // When a directory is in the list, the directory and its content is added - // in the archive. - // In this synopsis, the function takes an optional variable list of - // options. See bellow the supported options. - // Parameters : - // $p_filelist : An array containing file or directory names, or - // a string containing one filename or one directory name, or - // a string containing a list of filenames and/or directory - // names separated by spaces. - // $p_add_dir : A path to add before the real path of the archived file, - // in order to have it memorized in the archive. - // $p_remove_dir : A path to remove from the real path of the file to archive, - // in order to have a shorter path memorized in the archive. - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir - // is removed first, before $p_add_dir is added. - // Options : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_COMMENT : - // PCLZIP_CB_PRE_ADD : - // PCLZIP_CB_POST_ADD : - // Return Values : - // 0 on failure, - // The list of the added files, with a status of the add action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function create($p_filelist) - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Set default values - $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove from the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - //, PCLZIP_OPT_CRYPT => 'optional' - )); - if ($v_result != 1) { - return 0; + // ----- Tests the zlib + if (!function_exists('gzopen')) { + die('Abort '.basename(__FILE__).' : Missing zlib extensions'); } - } - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { + // ----- Set the attributes + $this->zipname = $p_zipname; + $this->zip_fd = 0; + $this->magic_quotes_status = -1; - // ----- Get the first argument - $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + // ----- Return + return; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // create($p_filelist, $p_add_dir="", $p_remove_dir="") + // create($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two different synopsis. The first one is historical. + // This method creates a Zip Archive. The Zip file is created in the + // filesystem. The files and directories indicated in $p_filelist + // are added in the archive. See the parameters description for the + // supported format of $p_filelist. + // When a directory is in the list, the directory and its content is added + // in the archive. + // In this synopsis, the function takes an optional variable list of + // options. See bellow the supported options. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function create($p_filelist) { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove from the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array( + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + ))); + if ($v_result != 1) { + return 0; + } + } else { + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } else if ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + return 0; + } + } + } - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } else { + // ----- The list is a list of string names + $v_string_list = $p_filelist; + } + } else if (is_string($p_filelist)) { + // ----- Look if the $p_filelist is a string + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } else { + // ----- Invalid variable type for $p_filelist + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + return 0; } - else if ($v_size > 2) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Invalid number / type of arguments"); - return 0; + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + } } - } - } - - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Init - $v_string_list = array(); - $v_att_list = array(); - $v_filedescr_list = array(); - $p_result_list = array(); - - // ----- Look if the $p_filelist is really an array - if (is_array($p_filelist)) { - - // ----- Look if the first element is also an array - // This will mean that this is a file description entry - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; - } - - // ----- The list is a list of string names - else { - $v_string_list = $p_filelist; - } - } - - // ----- Look if the $p_filelist is a string - else if (is_string($p_filelist)) { - // ----- Create a list from the string - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); - } - // ----- Invalid variable type for $p_filelist - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); - return 0; - } - - // ----- Reformat the string list - if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - if ($v_string != '') { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + // ----- For each file in the list check the attributes + $v_supported_attributes = array( + PCLZIP_ATT_FILE_NAME => 'mandatory', + PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional', + PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional', + PCLZIP_ATT_FILE_MTIME => 'optional', + PCLZIP_ATT_FILE_CONTENT => 'optional', + PCLZIP_ATT_FILE_COMMENT => 'optional', + )); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes); + if ($v_result != 1) { + return 0; + } } - else { + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; } - } - } - - // ----- For each file in the list check the attributes - $v_supported_attributes - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' - ,PCLZIP_ATT_FILE_MTIME => 'optional' - ,PCLZIP_ATT_FILE_CONTENT => 'optional' - ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); - foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, - $v_filedescr_list[], - $v_options, - $v_supported_attributes); - if ($v_result != 1) { - return 0; - } - } - - // ----- Expand the filelist (expand directories) - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); - if ($v_result != 1) { - return 0; - } - - // ----- Call the create fct - $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); - if ($v_result != 1) { - return 0; - } - // ----- Return - return $p_result_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // add($p_filelist, $p_add_dir="", $p_remove_dir="") - // add($p_filelist, $p_option, $p_option_value, ...) - // Description : - // This method supports two synopsis. The first one is historical. - // This methods add the list of files in an existing archive. - // If a file with the same name already exists, it is added at the end of the - // archive, the first one is still present. - // If the archive does not exist, it is created. - // Parameters : - // $p_filelist : An array containing file or directory names, or - // a string containing one filename or one directory name, or - // a string containing a list of filenames and/or directory - // names separated by spaces. - // $p_add_dir : A path to add before the real path of the archived file, - // in order to have it memorized in the archive. - // $p_remove_dir : A path to remove from the real path of the file to archive, - // in order to have a shorter path memorized in the archive. - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir - // is removed first, before $p_add_dir is added. - // Options : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_COMMENT : - // PCLZIP_OPT_ADD_COMMENT : - // PCLZIP_OPT_PREPEND_COMMENT : - // PCLZIP_CB_PRE_ADD : - // PCLZIP_CB_POST_ADD : - // Return Values : - // 0 on failure, - // The list of the added files, with a status of the add action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function add($p_filelist) - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Set default values - $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove form the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_ADD_COMMENT => 'optional', - PCLZIP_OPT_PREPEND_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - //, PCLZIP_OPT_CRYPT => 'optional' - )); + // ----- Call the create fct + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); if ($v_result != 1) { - return 0; + return 0; } - } - - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { - // ----- Get the first argument - $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; - - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // add($p_filelist, $p_add_dir="", $p_remove_dir="") + // add($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two synopsis. The first one is historical. + // This methods add the list of files in an existing archive. + // If a file with the same name already exists, it is added at the end of the + // archive, the first one is still present. + // If the archive does not exist, it is created. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_OPT_ADD_COMMENT : + // PCLZIP_OPT_PREPEND_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function add($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array( + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + ))); + if ($v_result != 1) { + return 0; + } + } else { + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the method. + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + // ----- Return + return 0; + } + } } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Return - return 0; + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } else { + // ----- The list is a list of string names + $v_string_list = $p_filelist; + } + } else if (is_string($p_filelist)) { + // ----- Look if the $p_filelist is a string + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } else { + // ----- Invalid variable type for $p_filelist + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); + return 0; } - } - } - - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Init - $v_string_list = array(); - $v_att_list = array(); - $v_filedescr_list = array(); - $p_result_list = array(); - - // ----- Look if the $p_filelist is really an array - if (is_array($p_filelist)) { - - // ----- Look if the first element is also an array - // This will mean that this is a file description entry - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; - } - - // ----- The list is a list of string names - else { - $v_string_list = $p_filelist; - } - } - - // ----- Look if the $p_filelist is a string - else if (is_string($p_filelist)) { - // ----- Create a list from the string - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); - } - - // ----- Invalid variable type for $p_filelist - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); - return 0; - } - - // ----- Reformat the string list - if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; - } - } - - // ----- For each file in the list check the attributes - $v_supported_attributes - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' - ,PCLZIP_ATT_FILE_MTIME => 'optional' - ,PCLZIP_ATT_FILE_CONTENT => 'optional' - ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); - foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, - $v_filedescr_list[], - $v_options, - $v_supported_attributes); - if ($v_result != 1) { - return 0; - } - } - - // ----- Expand the filelist (expand directories) - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); - if ($v_result != 1) { - return 0; - } - - // ----- Call the create fct - $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); - if ($v_result != 1) { - return 0; - } - - // ----- Return - return $p_result_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : listContent() - // Description : - // This public method, gives the list of the files and directories, with their - // properties. - // The properties of each entries in the list are (used also in other functions) : - // filename : Name of the file. For a create or add action it is the filename - // given by the user. For an extract function it is the filename - // of the extracted file. - // stored_filename : Name of the file / directory stored in the archive. - // size : Size of the stored file. - // compressed_size : Size of the file's data compressed in the archive - // (without the headers overhead) - // mtime : Last known modification date of the file (UNIX timestamp) - // comment : Comment associated with the file - // folder : true | false - // index : index of the file in the archive - // status : status of the action (depending of the action) : - // Values are : - // ok : OK ! - // filtered : the file / dir is not extracted (filtered by user) - // already_a_directory : the file can not be extracted because a - // directory with the same name already exists - // write_protected : the file can not be extracted because a file - // with the same name already exists and is - // write protected - // newer_exist : the file was not extracted because a newer file exists - // path_creation_fail : the file is not extracted because the folder - // does not exist and can not be created - // write_error : the file was not extracted because there was a - // error while writing the file - // read_error : the file was not extracted because there was a error - // while reading the file - // invalid_header : the file was not extracted because of an archive - // format error (bad file header) - // Note that each time a method can continue operating when there - // is an action error on a file, the error is only logged in the file status. - // Return Values : - // 0 on an unrecoverable failure, - // The list of the files in the archive. - // -------------------------------------------------------------------------------- - function listContent() - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } - - // ----- Call the extracting fct - $p_list = array(); - if (($v_result = $this->privList($p_list)) != 1) - { - unset($p_list); - return(0); - } - - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // extract($p_path="./", $p_remove_path="") - // extract([$p_option, $p_option_value, ...]) - // Description : - // This method supports two synopsis. The first one is historical. - // This method extract all the files / directories from the archive to the - // folder indicated in $p_path. - // If you want to ignore the 'root' part of path of the memorized files - // you can indicate this in the optional $p_remove_path parameter. - // By default, if a newer file with the same name already exists, the - // file is not extracted. - // - // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions - // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append - // at the end of the path value of PCLZIP_OPT_PATH. - // Parameters : - // $p_path : Path where the files and directories are to be extracted - // $p_remove_path : First part ('root' part) of the memorized path - // (if any similar) to remove while extracting. - // Options : - // PCLZIP_OPT_PATH : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_CB_PRE_EXTRACT : - // PCLZIP_CB_POST_EXTRACT : - // Return Values : - // 0 or a negative value on failure, - // The list of the extracted files, with a status of the action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function extract() - { - $v_result=1; - // ----- Reset the error handler - $this->privErrorReset(); + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + } - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } + // ----- For each file in the list check the attributes + $v_supported_attributes = array( + PCLZIP_ATT_FILE_NAME => 'mandatory', + PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional', + PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional', + PCLZIP_ATT_FILE_MTIME => 'optional', + PCLZIP_ATT_FILE_CONTENT => 'optional', + PCLZIP_ATT_FILE_COMMENT => 'optional', + )); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } - // ----- Set default values - $v_options = array(); -// $v_path = "./"; - $v_path = ''; - $v_remove_path = ""; - $v_remove_all_path = false; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Default values for option - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; - - // ----- Look for arguments - if ($v_size > 0) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional' - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); if ($v_result != 1) { - return 0; + return 0; } - // ----- Set the arguments - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - // ----- Check for '/' in last path char - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; - } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + // ----- Call the create fct + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; } - } - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : listContent() + // Description : + // This public method, gives the list of the files and directories, with their + // properties. + // The properties of each entries in the list are (used also in other functions) : + // filename : Name of the file. For a create or add action it is the filename + // given by the user. For an extract function it is the filename + // of the extracted file. + // stored_filename : Name of the file / directory stored in the archive. + // size : Size of the stored file. + // compressed_size : Size of the file's data compressed in the archive + // (without the headers overhead) + // mtime : Last known modification date of the file (UNIX timestamp) + // comment : Comment associated with the file + // folder : true | false + // index : index of the file in the archive + // status : status of the action (depending of the action) : + // Values are : + // ok : OK ! + // filtered : the file / dir is not extracted (filtered by user) + // already_a_directory : the file can not be extracted because a + // directory with the same name already exists + // write_protected : the file can not be extracted because a file + // with the same name already exists and is + // write protected + // newer_exist : the file was not extracted because a newer file exists + // path_creation_fail : the file is not extracted because the folder + // does not exist and can not be created + // write_error : the file was not extracted because there was a + // error while writing the file + // read_error : the file was not extracted because there was a error + // while reading the file + // invalid_header : the file was not extracted because of an archive + // format error (bad file header) + // Note that each time a method can continue operating when there + // is an action error on a file, the error is only logged in the file status. + // Return Values : + // 0 on an unrecoverable failure, + // The list of the files in the archive. + // -------------------------------------------------------------------------------- + function listContent() + { + $v_result=1; - // ----- Get the first argument - $v_path = $v_arg_list[0]; + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Return - return 0; + // ----- Call the extracting fct + $p_list = array(); + if (($v_result = $this->privList($p_list)) != 1) { + unset($p_list); + return(0); } - } - } - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Trace + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // extract($p_path="./", $p_remove_path="") + // extract([$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method extract all the files / directories from the archive to the + // folder indicated in $p_path. + // If you want to ignore the 'root' part of path of the memorized files + // you can indicate this in the optional $p_remove_path parameter. + // By default, if a newer file with the same name already exists, the + // file is not extracted. + // + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append + // at the end of the path value of PCLZIP_OPT_PATH. + // Parameters : + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 or a negative value on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function extract() + { + $v_result=1; - // ----- Call the extracting fct - $p_list = array(); - $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, - $v_remove_all_path, $v_options); - if ($v_result < 1) { - unset($p_list); - return(0); - } + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - - // -------------------------------------------------------------------------------- - // Function : - // extractByIndex($p_index, $p_path="./", $p_remove_path="") - // extractByIndex($p_index, [$p_option, $p_option_value, ...]) - // Description : - // This method supports two synopsis. The first one is historical. - // This method is doing a partial extract of the archive. - // The extracted files or folders are identified by their index in the - // archive (from 0 to n). - // Note that if the index identify a folder, only the folder entry is - // extracted, not all the files included in the archive. - // Parameters : - // $p_index : A single index (integer) or a string of indexes of files to - // extract. The form of the string is "0,4-6,8-12" with only numbers - // and '-' for range or ',' to separate ranges. No spaces or ';' - // are allowed. - // $p_path : Path where the files and directories are to be extracted - // $p_remove_path : First part ('root' part) of the memorized path - // (if any similar) to remove while extracting. - // Options : - // PCLZIP_OPT_PATH : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and - // not as files. - // The resulting content is in a new field 'content' in the file - // structure. - // This option must be used alone (any other options are ignored). - // PCLZIP_CB_PRE_EXTRACT : - // PCLZIP_CB_POST_EXTRACT : - // Return Values : - // 0 on failure, - // The list of the extracted files, with a status of the action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - //function extractByIndex($p_index, options...) - function extractByIndex($p_index) - { - $v_result=1; + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } - // ----- Reset the error handler - $this->privErrorReset(); + // ----- Set default values + $v_options = array(); + // $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array( + PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional', + PCLZIP_OPT_STOP_ON_ERROR => 'optional', + PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + ))); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } else { + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the method. + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + // ----- Return + return 0; + } + } + } - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); - // ----- Set default values - $v_options = array(); -// $v_path = "./"; - $v_path = ''; - $v_remove_path = ""; - $v_remove_all_path = false; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Default values for option - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove form the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional' - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; - } + // ----- Trace - // ----- Set the arguments - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - // ----- Check for '/' in last path char - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; - } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + // ----- Call the extracting fct + $p_list = array(); + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, + $v_remove_all_path, $v_options); + if ($v_result < 1) { + unset($p_list); + return(0); } - if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; - } - else { - } - } - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : + // extractByIndex($p_index, $p_path="./", $p_remove_path="") + // extractByIndex($p_index, [$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method is doing a partial extract of the archive. + // The extracted files or folders are identified by their index in the + // archive (from 0 to n). + // Note that if the index identify a folder, only the folder entry is + // extracted, not all the files included in the archive. + // Parameters : + // $p_index : A single index (integer) or a string of indexes of files to + // extract. The form of the string is "0,4-6,8-12" with only numbers + // and '-' for range or ',' to separate ranges. No spaces or ';' + // are allowed. + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and + // not as files. + // The resulting content is in a new field 'content' in the file + // structure. + // This option must be used alone (any other options are ignored). + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + //function extractByIndex($p_index, options...) + function extractByIndex($p_index) + { + $v_result=1; - // ----- Get the first argument - $v_path = $v_arg_list[0]; + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Return - return 0; + // ----- Set default values + $v_options = array(); + // $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array( + PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional', + PCLZIP_OPT_STOP_ON_ERROR => 'optional', + PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + ))); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; + } + } else { + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the method. + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } } - } - } - // ----- Trace + // ----- Trace - // ----- Trick - // Here I want to reuse extractByRule(), so I need to parse the $p_index - // with privParseOptions() - $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); - $v_options_trick = array(); - $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, - array (PCLZIP_OPT_BY_INDEX => 'optional' )); - if ($v_result != 1) { - return 0; - } - $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + // ----- Trick + // Here I want to reuse extractByRule(), so I need to parse the $p_index + // with privParseOptions() + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); + $v_options_trick = array(); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, + array (PCLZIP_OPT_BY_INDEX => 'optional')); + if ($v_result != 1) { + return 0; + } + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); - // ----- Call the extracting fct - if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { - return(0); - } + // ----- Call the extracting fct + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + return(0); + } - // ----- Return - return $p_list; + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // delete([$p_option, $p_option_value, ...]) + // Description : + // This method removes files from the archive. + // If no parameters are given, then all the archive is emptied. + // Parameters : + // None or optional arguments. + // Options : + // PCLZIP_OPT_BY_INDEX : + // PCLZIP_OPT_BY_NAME : + // PCLZIP_OPT_BY_EREG : + // PCLZIP_OPT_BY_PREG : + // Return Values : + // 0 on failure, + // The list of the files which are still present in the archive. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function delete() +{ +$v_result=1; + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Check archive +if (!$this->privCheckFormat()) { + return(0); +} + +// ----- Set default values +$v_options = array(); + +// ----- Look for variable options arguments +$v_size = func_num_args(); + +// ----- Look for arguments +if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional')); + if ($v_result != 1) { + return 0; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // delete([$p_option, $p_option_value, ...]) - // Description : - // This method removes files from the archive. - // If no parameters are given, then all the archive is emptied. - // Parameters : - // None or optional arguments. - // Options : - // PCLZIP_OPT_BY_INDEX : - // PCLZIP_OPT_BY_NAME : - // PCLZIP_OPT_BY_EREG : - // PCLZIP_OPT_BY_PREG : - // Return Values : - // 0 on failure, - // The list of the files which are still present in the archive. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function delete() - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } +} - // ----- Set default values - $v_options = array(); +// ----- Magic quotes trick +$this->privDisableMagicQuotes(); - // ----- Look for variable options arguments - $v_size = func_num_args(); +// ----- Call the delete fct +$v_list = array(); +if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); + return(0); +} - // ----- Look for arguments - if ($v_size > 0) { - // ----- Get the arguments - $v_arg_list = func_get_args(); +// ----- Magic quotes trick +$this->privSwapBackMagicQuotes(); - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional' )); - if ($v_result != 1) { - return 0; - } - } +// ----- Return +return $v_list; +} +// -------------------------------------------------------------------------------- - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); +// -------------------------------------------------------------------------------- +// Function : deleteByIndex() +// Description : +// ***** Deprecated ***** +// delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. +// -------------------------------------------------------------------------------- +function deleteByIndex($p_index) +{ - // ----- Call the delete fct - $v_list = array(); - if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { - $this->privSwapBackMagicQuotes(); - unset($v_list); - return(0); - } +$p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); +// ----- Return +return $p_list; +} +// -------------------------------------------------------------------------------- - // ----- Return - return $v_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : deleteByIndex() - // Description : - // ***** Deprecated ***** - // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. - // -------------------------------------------------------------------------------- - function deleteByIndex($p_index) +// -------------------------------------------------------------------------------- +// Function : properties() +// Description : +// This method gives the properties of the archive. +// The properties are : +// nb : Number of files in the archive +// comment : Comment associated with the archive file +// status : not_exist, ok +// Parameters : +// None +// Return Values : +// 0 on failure, +// An array with the archive properties. +// -------------------------------------------------------------------------------- +function properties() +{ + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Magic quotes trick +$this->privDisableMagicQuotes(); + +// ----- Check archive +if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + return(0); +} + +// ----- Default properties +$v_prop = array(); +$v_prop['comment'] = ''; +$v_prop['nb'] = 0; +$v_prop['status'] = 'not_exist'; + +// ----- Look if file exists +if (@is_file($this->zipname)) +{ + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) { + $this->privSwapBackMagicQuotes(); - $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); // ----- Return - return $p_list; + return 0; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : properties() - // Description : - // This method gives the properties of the archive. - // The properties are : - // nb : Number of files in the archive - // comment : Comment associated with the archive file - // status : not_exist, ok - // Parameters : - // None - // Return Values : - // 0 on failure, - // An array with the archive properties. - // -------------------------------------------------------------------------------- - function properties() + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privSwapBackMagicQuotes(); + return 0; + } - // ----- Reset the error handler - $this->privErrorReset(); + // ----- Close the zip file + $this->privCloseFd(); - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; +} - // ----- Check archive - if (!$this->privCheckFormat()) { - $this->privSwapBackMagicQuotes(); - return(0); - } +// ----- Magic quotes trick +$this->privSwapBackMagicQuotes(); - // ----- Default properties - $v_prop = array(); - $v_prop['comment'] = ''; - $v_prop['nb'] = 0; - $v_prop['status'] = 'not_exist'; +// ----- Return +return $v_prop; +} +// -------------------------------------------------------------------------------- - // ----- Look if file exists - if (@is_file($this->zipname)) - { - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) - { - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); +// -------------------------------------------------------------------------------- +// Function : duplicate() +// Description : +// This method creates an archive by copying the content of an other one. If +// the archive already exist, it is replaced by the new one without any warning. +// Parameters : +// $p_archive : The filename of a valid archive, or +// a valid PclZip object. +// Return Values : +// 1 on success. +// 0 or a negative value on error (error code). +// -------------------------------------------------------------------------------- +function duplicate($p_archive) +{ +$v_result = 1; + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Look if the $p_archive is a PclZip object +if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) +{ + + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); +} + +// ----- Look if the $p_archive is a string (so a filename) +else if (is_string($p_archive)) +{ + + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } + else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } +} + +// ----- Invalid variable +else +{ + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Return - return 0; - } +// -------------------------------------------------------------------------------- +// Function : merge() +// Description : +// This method merge the $p_archive_to_add archive at the end of the current +// one ($this). +// If the archive ($this) does not exist, the merge becomes a duplicate. +// If the $p_archive_to_add archive does not exist, the merge is a success. +// Parameters : +// $p_archive_to_add : It can be directly the filename of a valid zip archive, +// or a PclZip object archive. +// Return Values : +// 1 on success, +// 0 or negative values on error (see below). +// -------------------------------------------------------------------------------- +function merge($p_archive_to_add) +{ +$v_result = 1; + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Check archive +if (!$this->privCheckFormat()) { + return(0); +} + +// ----- Look if the $p_archive_to_add is a PclZip object +if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) +{ + + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); +} + +// ----- Look if the $p_archive_to_add is a string (so a filename) +else if (is_string($p_archive_to_add)) +{ + + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); +} + +// ----- Invalid variable +else +{ + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privSwapBackMagicQuotes(); - return 0; - } - // ----- Close the zip file - $this->privCloseFd(); - // ----- Set the user attributes - $v_prop['comment'] = $v_central_dir['comment']; - $v_prop['nb'] = $v_central_dir['entries']; - $v_prop['status'] = 'ok'; - } +// -------------------------------------------------------------------------------- +// Function : errorCode() +// Description : +// Parameters : +// -------------------------------------------------------------------------------- +function errorCode() +{ +if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorCode()); +} +else { + return($this->error_code); +} +} +// -------------------------------------------------------------------------------- - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); +// -------------------------------------------------------------------------------- +// Function : errorName() +// Description : +// Parameters : +// -------------------------------------------------------------------------------- +function errorName($p_with_code=false) +{ +$v_name = array (PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' + ) ); + +if (isset($v_name[$this->error_code])) { + $v_value = $v_name[$this->error_code]; +} +else { + $v_value = 'NoName'; +} + +if ($p_with_code) { + return($v_value.' ('.$this->error_code.')'); +} +else { + return($v_value); +} +} +// -------------------------------------------------------------------------------- - // ----- Return - return $v_prop; +// -------------------------------------------------------------------------------- +// Function : errorInfo() +// Description : +// Parameters : +// -------------------------------------------------------------------------------- +function errorInfo($p_full=false) +{ +if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorString()); +} +else { + if ($p_full) { + return($this->errorName(true)." : ".$this->error_string); } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : duplicate() - // Description : - // This method creates an archive by copying the content of an other one. If - // the archive already exist, it is replaced by the new one without any warning. - // Parameters : - // $p_archive : The filename of a valid archive, or - // a valid PclZip object. - // Return Values : - // 1 on success. - // 0 or a negative value on error (error code). - // -------------------------------------------------------------------------------- - function duplicate($p_archive) - { - $v_result = 1; + else { + return($this->error_string." [code ".$this->error_code."]"); + } +} +} +// -------------------------------------------------------------------------------- - // ----- Reset the error handler - $this->privErrorReset(); - // ----- Look if the $p_archive is a PclZip object - if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) - { +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** +// ***** ***** +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** +// -------------------------------------------------------------------------------- - // ----- Duplicate the archive - $v_result = $this->privDuplicate($p_archive->zipname); - } - - // ----- Look if the $p_archive is a string (so a filename) - else if (is_string($p_archive)) - { - - // ----- Check that $p_archive is a valid zip file - // TBC : Should also check the archive format - if (!is_file($p_archive)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); - $v_result = PCLZIP_ERR_MISSING_FILE; - } - else { - // ----- Duplicate the archive - $v_result = $this->privDuplicate($p_archive); - } - } - - // ----- Invalid variable - else - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : merge() - // Description : - // This method merge the $p_archive_to_add archive at the end of the current - // one ($this). - // If the archive ($this) does not exist, the merge becomes a duplicate. - // If the $p_archive_to_add archive does not exist, the merge is a success. - // Parameters : - // $p_archive_to_add : It can be directly the filename of a valid zip archive, - // or a PclZip object archive. - // Return Values : - // 1 on success, - // 0 or negative values on error (see below). - // -------------------------------------------------------------------------------- - function merge($p_archive_to_add) - { - $v_result = 1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } - - // ----- Look if the $p_archive_to_add is a PclZip object - if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) - { - - // ----- Merge the archive - $v_result = $this->privMerge($p_archive_to_add); - } - - // ----- Look if the $p_archive_to_add is a string (so a filename) - else if (is_string($p_archive_to_add)) - { - - // ----- Create a temporary archive - $v_object_archive = new PclZip($p_archive_to_add); - - // ----- Merge the archive - $v_result = $this->privMerge($v_object_archive); - } - - // ----- Invalid variable - else - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - - - // -------------------------------------------------------------------------------- - // Function : errorCode() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function errorCode() - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorCode()); - } - else { - return($this->error_code); - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : errorName() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function errorName($p_with_code=false) - { - $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', - PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', - PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', - PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', - PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', - PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', - PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', - PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', - PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', - PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', - PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', - PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', - PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', - PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', - PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', - PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', - PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', - PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', - PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' - ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' - ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' - ); - - if (isset($v_name[$this->error_code])) { - $v_value = $v_name[$this->error_code]; - } - else { - $v_value = 'NoName'; - } - - if ($p_with_code) { - return($v_value.' ('.$this->error_code.')'); - } - else { - return($v_value); - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : errorInfo() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function errorInfo($p_full=false) - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorString()); - } - else { - if ($p_full) { - return($this->errorName(true)." : ".$this->error_string); - } - else { - return($this->error_string." [code ".$this->error_code."]"); - } - } - } - // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- -// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** -// ***** ***** -// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** +// Function : privCheckFormat() +// Description : +// This method check that the archive exists and is a valid zip archive. +// Several level of check exists. (futur) +// Parameters : +// $p_level : Level of check. Default 0. +// 0 : Check the first bytes (magic codes) (default value)) +// 1 : 0 + Check the central directory (futur) +// 2 : 1 + Check each file header (futur) +// Return Values : +// true on success, +// false on error, the error code is set. +// -------------------------------------------------------------------------------- +function privCheckFormat($p_level=0) +{ +$v_result = true; + +// ----- Reset the file system cache +clearstatcache(); + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Look if the file exits +if (!is_file($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); + return(false); +} + +// ----- Check that the file is readeable +if (!is_readable($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); + return(false); +} + +// ----- Check the magic code +// TBC + +// ----- Check the central header +// TBC + +// ----- Check each file header +// TBC + +// ----- Return +return $v_result; +} // -------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------- +// Function : privParseOptions() +// Description : +// This internal methods reads the variable list of arguments ($p_options_list, +// $p_size) and generate an array with the options and values ($v_result_list). +// $v_requested_options contains the options that can be present and those that +// must be present. +// $v_requested_options is an array, with the option value as key, and 'optional', +// or 'mandatory' as value. +// Parameters : +// See above. +// Return Values : +// 1 on success. +// 0 on failure. +// -------------------------------------------------------------------------------- +function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) +{ +$v_result=1; +// ----- Read the options +$i=0; +while ($i<$p_size) { - // -------------------------------------------------------------------------------- - // Function : privCheckFormat() - // Description : - // This method check that the archive exists and is a valid zip archive. - // Several level of check exists. (futur) - // Parameters : - // $p_level : Level of check. Default 0. - // 0 : Check the first bytes (magic codes) (default value)) - // 1 : 0 + Check the central directory (futur) - // 2 : 1 + Check each file header (futur) - // Return Values : - // true on success, - // false on error, the error code is set. - // -------------------------------------------------------------------------------- - function privCheckFormat($p_level=0) - { - $v_result = true; - - // ----- Reset the file system cache - clearstatcache(); - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Look if the file exits - if (!is_file($this->zipname)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); - return(false); - } - - // ----- Check that the file is readeable - if (!is_readable($this->zipname)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); - return(false); - } - - // ----- Check the magic code - // TBC - - // ----- Check the central header - // TBC - - // ----- Check each file header - // TBC - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privParseOptions() - // Description : - // This internal methods reads the variable list of arguments ($p_options_list, - // $p_size) and generate an array with the options and values ($v_result_list). - // $v_requested_options contains the options that can be present and those that - // must be present. - // $v_requested_options is an array, with the option value as key, and 'optional', - // or 'mandatory' as value. - // Parameters : - // See above. - // Return Values : - // 1 on success. - // 0 on failure. - // -------------------------------------------------------------------------------- - function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) - { - $v_result=1; - - // ----- Read the options - $i=0; - while ($i<$p_size) { - - // ----- Check if the option is supported - if (!isset($v_requested_options[$p_options_list[$i]])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for next option - switch ($p_options_list[$i]) { - // ----- Look for options that request a path value - case PCLZIP_OPT_PATH : - case PCLZIP_OPT_REMOVE_PATH : - case PCLZIP_OPT_ADD_PATH : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); - $i++; - break; - - case PCLZIP_OPT_TEMP_FILE_THRESHOLD : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } - - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); - return PclZip::errorCode(); - } - - // ----- Check the value - $v_value = $p_options_list[$i+1]; - if ((!is_integer($v_value)) || ($v_value<0)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } - - // ----- Get the value (and convert it in bytes) - $v_result_list[$p_options_list[$i]] = $v_value*1048576; - $i++; - break; - - case PCLZIP_OPT_TEMP_FILE_ON : - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); - return PclZip::errorCode(); - } - - $v_result_list[$p_options_list[$i]] = true; - break; - - case PCLZIP_OPT_TEMP_FILE_OFF : - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); - return PclZip::errorCode(); - } - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); - return PclZip::errorCode(); - } - - $v_result_list[$p_options_list[$i]] = true; - break; - - case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - if ( is_string($p_options_list[$i+1]) - && ($p_options_list[$i+1] != '')) { - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); - $i++; - } - else { - } - break; - - // ----- Look for options that request an array of string for value - case PCLZIP_OPT_BY_NAME : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; - } - else if (is_array($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that request an EREG or PREG expression - case PCLZIP_OPT_BY_EREG : - // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG - // to PCLZIP_OPT_BY_PREG - $p_options_list[$i] = PCLZIP_OPT_BY_PREG; - case PCLZIP_OPT_BY_PREG : - //case PCLZIP_OPT_CRYPT : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that takes a string - case PCLZIP_OPT_COMMENT : - case PCLZIP_OPT_ADD_COMMENT : - case PCLZIP_OPT_PREPEND_COMMENT : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, - "Missing parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, - "Wrong parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); - - // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that request an array of index - case PCLZIP_OPT_BY_INDEX : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_work_list = array(); - if (is_string($p_options_list[$i+1])) { - - // ----- Remove spaces - $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); - - // ----- Parse items - $v_work_list = explode(",", $p_options_list[$i+1]); - } - else if (is_integer($p_options_list[$i+1])) { - $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; - } - else if (is_array($p_options_list[$i+1])) { - $v_work_list = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Reduce the index list - // each index item in the list must be a couple with a start and - // an end value : [0,3], [5-5], [8-10], ... - // ----- Check the format of each item - $v_sort_flag=false; - $v_sort_value=0; - for ($j=0; $j<sizeof($v_work_list); $j++) { - // ----- Explode the item - $v_item_list = explode("-", $v_work_list[$j]); - $v_size_item_list = sizeof($v_item_list); - - // ----- TBC : Here we might check that each item is a - // real integer ... - - // ----- Look for single value - if ($v_size_item_list == 1) { - // ----- Set the option value - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; - } - elseif ($v_size_item_list == 2) { - // ----- Set the option value - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - - // ----- Look for list sort - if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { - $v_sort_flag=true; - - // ----- TBC : An automatic sort should be writen ... - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; - } - - // ----- Sort the items - if ($v_sort_flag) { - // TBC : To Be Completed - } - - // ----- Next option - $i++; - break; - - // ----- Look for options that request no value - case PCLZIP_OPT_REMOVE_ALL_PATH : - case PCLZIP_OPT_EXTRACT_AS_STRING : - case PCLZIP_OPT_NO_COMPRESSION : - case PCLZIP_OPT_EXTRACT_IN_OUTPUT : - case PCLZIP_OPT_REPLACE_NEWER : - case PCLZIP_OPT_STOP_ON_ERROR : - $v_result_list[$p_options_list[$i]] = true; - break; - - // ----- Look for options that request an octal value - case PCLZIP_OPT_SET_CHMOD : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - $i++; - break; - - // ----- Look for options that request a call-back - case PCLZIP_CB_PRE_EXTRACT : - case PCLZIP_CB_POST_EXTRACT : - case PCLZIP_CB_PRE_ADD : - case PCLZIP_CB_POST_ADD : - /* for futur use - case PCLZIP_CB_PRE_DELETE : - case PCLZIP_CB_POST_DELETE : - case PCLZIP_CB_PRE_LIST : - case PCLZIP_CB_POST_LIST : - */ - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_function_name = $p_options_list[$i+1]; - - // ----- Check that the value is a valid existing function - if (!function_exists($v_function_name)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Set the attribute - $v_result_list[$p_options_list[$i]] = $v_function_name; - $i++; - break; - - default : - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Unknown parameter '" - .$p_options_list[$i]."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Next options - $i++; - } - - // ----- Look for mandatory options - if ($v_requested_options !== false) { - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { - // ----- Look for mandatory option - if ($v_requested_options[$key] == 'mandatory') { - // ----- Look if present - if (!isset($v_result_list[$key])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); - - // ----- Return - return PclZip::errorCode(); - } - } - } - } - - // ----- Look for default values - if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { - - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privOptionDefaultThreshold() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privOptionDefaultThreshold(&$p_options) - { - $v_result=1; - - if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { - return $v_result; - } - - // ----- Get 'memory_limit' configuration value - $v_memory_limit = ini_get('memory_limit'); - $v_memory_limit = trim($v_memory_limit); - $last = strtolower(substr($v_memory_limit, -1)); - - if ($last == 'g') - //$v_memory_limit = $v_memory_limit*1024*1024*1024; - $v_memory_limit = $v_memory_limit*1073741824; - if ($last == 'm') - //$v_memory_limit = $v_memory_limit*1024*1024; - $v_memory_limit = $v_memory_limit*1048576; - if ($last == 'k') - $v_memory_limit = $v_memory_limit*1024; - - $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); - - - // ----- Sanity check : No threshold if value lower than 1M - if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { - unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privFileDescrParseAtt() - // Description : - // Parameters : - // Return Values : - // 1 on success. - // 0 on failure. - // -------------------------------------------------------------------------------- - function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) - { - $v_result=1; - - // ----- For each file in the list check the attributes - foreach ($p_file_list as $v_key => $v_value) { - - // ----- Check if the option is supported - if (!isset($v_requested_options[$v_key])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for attribute - switch ($v_key) { - case PCLZIP_ATT_FILE_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); - - if ($p_filedescr['filename'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - break; - - case PCLZIP_ATT_FILE_NEW_SHORT_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); - - if ($p_filedescr['new_short_name'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - break; - - case PCLZIP_ATT_FILE_NEW_FULL_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); - - if ($p_filedescr['new_full_name'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - break; - - // ----- Look for options that takes a string - case PCLZIP_ATT_FILE_COMMENT : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['comment'] = $v_value; - break; - - case PCLZIP_ATT_FILE_MTIME : - if (!is_integer($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['mtime'] = $v_value; - break; - - case PCLZIP_ATT_FILE_CONTENT : - $p_filedescr['content'] = $v_value; - break; - - default : - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Unknown parameter '".$v_key."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for mandatory options - if ($v_requested_options !== false) { - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { - // ----- Look for mandatory option - if ($v_requested_options[$key] == 'mandatory') { - // ----- Look if present - if (!isset($p_file_list[$key])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); - return PclZip::errorCode(); - } - } - } - } - - // end foreach - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privFileDescrExpand() - // Description : - // This method look for each item of the list to see if its a file, a folder - // or a string to be added as file. For any other type of files (link, other) - // just ignore the item. - // Then prepare the information that will be stored for that file. - // When its a folder, expand the folder with all the files that are in that - // folder (recursively). - // Parameters : - // Return Values : - // 1 on success. - // 0 on failure. - // -------------------------------------------------------------------------------- - function privFileDescrExpand(&$p_filedescr_list, &$p_options) - { - $v_result=1; - - // ----- Create a result list - $v_result_list = array(); - - // ----- Look each entry - for ($i=0; $i<sizeof($p_filedescr_list); $i++) { - - // ----- Get filedescr - $v_descr = $p_filedescr_list[$i]; - - // ----- Reduce the filename - $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); - $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); - - // ----- Look for real file or folder - if (file_exists($v_descr['filename'])) { - if (@is_file($v_descr['filename'])) { - $v_descr['type'] = 'file'; - } - else if (@is_dir($v_descr['filename'])) { - $v_descr['type'] = 'folder'; - } - else if (@is_link($v_descr['filename'])) { - // skip - continue; - } - else { - // skip - continue; - } - } - - // ----- Look for string added as file - else if (isset($v_descr['content'])) { - $v_descr['type'] = 'virtual_file'; - } - - // ----- Missing file - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Calculate the stored filename - $this->privCalculateStoredFilename($v_descr, $p_options); - - // ----- Add the descriptor in result list - $v_result_list[sizeof($v_result_list)] = $v_descr; - - // ----- Look for folder - if ($v_descr['type'] == 'folder') { - // ----- List of items in folder - $v_dirlist_descr = array(); - $v_dirlist_nb = 0; - if ($v_folder_handler = @opendir($v_descr['filename'])) { - while (($v_item_handler = @readdir($v_folder_handler)) !== false) { - - // ----- Skip '.' and '..' - if (($v_item_handler == '.') || ($v_item_handler == '..')) { - continue; - } - - // ----- Compose the full filename - $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; - - // ----- Look for different stored filename - // Because the name of the folder was changed, the name of the - // files/sub-folders also change - if (($v_descr['stored_filename'] != $v_descr['filename']) - && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { - if ($v_descr['stored_filename'] != '') { - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; - } - else { - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; - } - } - - $v_dirlist_nb++; - } - - @closedir($v_folder_handler); - } - else { - // TBC : unable to open folder in read mode - } - - // ----- Expand each element of the list - if ($v_dirlist_nb != 0) { - // ----- Expand - if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { - return $v_result; - } - - // ----- Concat the resulting list - $v_result_list = array_merge($v_result_list, $v_dirlist_descr); - } - else { - } - - // ----- Free local array - unset($v_dirlist_descr); - } - } - - // ----- Get the result list - $p_filedescr_list = $v_result_list; - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCreate() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privCreate($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - $v_list_detail = array(); - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Open the file in write mode - if (($v_result = $this->privOpenFd('wb')) != 1) - { - // ----- Return - return $v_result; - } - - // ----- Add the list of files - $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); - - // ----- Close - $this->privCloseFd(); - - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAdd() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privAdd($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - $v_list_detail = array(); - - // ----- Look if the archive exists or is empty - if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) - { - - // ----- Do a create - $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); - - // ----- Return - return $v_result; - } - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Open the zip file - if (($v_result=$this->privOpenFd('rb')) != 1) - { - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } - - // ----- Go to beginning of File - @rewind($this->zip_fd); - - // ----- Creates a temporay file - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - - // ----- Open the temporary file in write mode - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) - { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Copy the files from the archive to the temporary file - // TBC : Here I should better append the file and go back to erase the central dir - $v_size = $v_central_dir['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Swap the file descriptor - // Here is a trick : I swap the temporary fd with the zip fd, in order to use - // the following methods on the temporary fil and not the real archive - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - - // ----- Add the files - $v_header_list = array(); - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) - { - fclose($v_zip_temp_fd); - $this->privCloseFd(); - @unlink($v_zip_temp_name); - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - - // ----- Store the offset of the central dir - $v_offset = @ftell($this->zip_fd); - - // ----- Copy the block of file headers from the old archive - $v_size = $v_central_dir['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_zip_temp_fd, $v_read_size); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Create the Central Dir files header - for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) - { - // ----- Create the file header - if ($v_header_list[$i]['status'] == 'ok') { - if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { - fclose($v_zip_temp_fd); - $this->privCloseFd(); - @unlink($v_zip_temp_name); - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - $v_count++; - } - - // ----- Transform the header to a 'usable' info - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } - - // ----- Zip file comment - $v_comment = $v_central_dir['comment']; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } - if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { - $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; - } - if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; - } - - // ----- Calculate the size of the central header - $v_size = @ftell($this->zip_fd)-$v_offset; - - // ----- Create the central dir footer - if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) - { - // ----- Reset the file list - unset($v_header_list); - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - - // ----- Swap back the file descriptor - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - - // ----- Close - $this->privCloseFd(); - - // ----- Close the temporary file - @fclose($v_zip_temp_fd); - - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Delete the zip file - // TBC : I should test the result ... - @unlink($this->zipname); - - // ----- Rename the temporary file - // TBC : I should test the result ... - //@rename($v_zip_temp_name, $this->zipname); - PclZipUtilRename($v_zip_temp_name, $this->zipname); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privOpenFd() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privOpenFd($p_mode) - { - $v_result=1; - - // ----- Look if already open - if ($this->zip_fd != 0) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCloseFd() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privCloseFd() - { - $v_result=1; - - if ($this->zip_fd != 0) - @fclose($this->zip_fd); - $this->zip_fd = 0; - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddList() - // Description : - // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is - // different from the real path of the file. This is usefull if you want to have PclTar - // running in any directory, and memorize relative path from an other directory. - // Parameters : - // $p_list : An array containing the file or directory names to add in the tar - // $p_result_list : list of added files with their properties (specially the status field) - // $p_add_dir : Path to add in the filename path archived - // $p_remove_dir : Path to remove in the filename path archived - // Return Values : - // -------------------------------------------------------------------------------- -// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) - function privAddList($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - - // ----- Add the files - $v_header_list = array(); - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) - { - // ----- Return - return $v_result; - } - - // ----- Store the offset of the central dir - $v_offset = @ftell($this->zip_fd); - - // ----- Create the Central Dir files header - for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) - { - // ----- Create the file header - if ($v_header_list[$i]['status'] == 'ok') { - if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { - // ----- Return - return $v_result; - } - $v_count++; - } - - // ----- Transform the header to a 'usable' info - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } - - // ----- Zip file comment - $v_comment = ''; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } - - // ----- Calculate the size of the central header - $v_size = @ftell($this->zip_fd)-$v_offset; - - // ----- Create the central dir footer - if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) - { - // ----- Reset the file list - unset($v_header_list); - - // ----- Return - return $v_result; - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddFileList() - // Description : - // Parameters : - // $p_filedescr_list : An array containing the file description - // or directory names to add in the zip - // $p_result_list : list of added files with their properties (specially the status field) - // Return Values : - // -------------------------------------------------------------------------------- - function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - $v_header = array(); - - // ----- Recuperate the current number of elt in list - $v_nb = sizeof($p_result_list); - - // ----- Loop on the files - for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { - // ----- Format the filename - $p_filedescr_list[$j]['filename'] - = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); - - - // ----- Skip empty file names - // TBC : Can this be possible ? not checked in DescrParseAtt ? - if ($p_filedescr_list[$j]['filename'] == "") { - continue; - } - - // ----- Check the filename - if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') - && (!file_exists($p_filedescr_list[$j]['filename']))) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); - return PclZip::errorCode(); - } - - // ----- Look if it is a file or a dir with no all path remove option - // or a dir with all its path removed -// if ( (is_file($p_filedescr_list[$j]['filename'])) -// || ( is_dir($p_filedescr_list[$j]['filename']) - if ( ($p_filedescr_list[$j]['type'] == 'file') - || ($p_filedescr_list[$j]['type'] == 'virtual_file') - || ( ($p_filedescr_list[$j]['type'] == 'folder') - && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) - || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) - ) { - - // ----- Add the file - $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, - $p_options); - if ($v_result != 1) { - return $v_result; - } - - // ----- Store the file infos - $p_result_list[$v_nb++] = $v_header; - } - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddFile() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privAddFile($p_filedescr, &$p_header, &$p_options) - { - $v_result=1; - - // ----- Working variable - $p_filename = $p_filedescr['filename']; - - // TBC : Already done in the fileAtt check ... ? - if ($p_filename == "") { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for a stored different filename - /* TBC : Removed - if (isset($p_filedescr['stored_filename'])) { - $v_stored_filename = $p_filedescr['stored_filename']; - } - else { - $v_stored_filename = $p_filedescr['stored_filename']; - } - */ - - // ----- Set the file properties - clearstatcache(); - $p_header['version'] = 20; - $p_header['version_extracted'] = 10; - $p_header['flag'] = 0; - $p_header['compression'] = 0; - $p_header['crc'] = 0; - $p_header['compressed_size'] = 0; - $p_header['filename_len'] = strlen($p_filename); - $p_header['extra_len'] = 0; - $p_header['disk'] = 0; - $p_header['internal'] = 0; - $p_header['offset'] = 0; - $p_header['filename'] = $p_filename; -// TBC : Removed $p_header['stored_filename'] = $v_stored_filename; - $p_header['stored_filename'] = $p_filedescr['stored_filename']; - $p_header['extra'] = ''; - $p_header['status'] = 'ok'; - $p_header['index'] = -1; - - // ----- Look for regular file - if ($p_filedescr['type']=='file') { - $p_header['external'] = 0x00000000; - $p_header['size'] = filesize($p_filename); - } - - // ----- Look for regular folder - else if ($p_filedescr['type']=='folder') { - $p_header['external'] = 0x00000010; - $p_header['mtime'] = filemtime($p_filename); - $p_header['size'] = filesize($p_filename); - } - - // ----- Look for virtual file - else if ($p_filedescr['type'] == 'virtual_file') { - $p_header['external'] = 0x00000000; - $p_header['size'] = strlen($p_filedescr['content']); - } - - - // ----- Look for filetime - if (isset($p_filedescr['mtime'])) { - $p_header['mtime'] = $p_filedescr['mtime']; - } - else if ($p_filedescr['type'] == 'virtual_file') { - $p_header['mtime'] = time(); - } - else { - $p_header['mtime'] = filemtime($p_filename); - } - - // ------ Look for file comment - if (isset($p_filedescr['comment'])) { - $p_header['comment_len'] = strlen($p_filedescr['comment']); - $p_header['comment'] = $p_filedescr['comment']; - } - else { - $p_header['comment_len'] = 0; - $p_header['comment'] = ''; - } - - // ----- Look for pre-add callback - if (isset($p_options[PCLZIP_CB_PRE_ADD])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_header, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_header['status'] = "skipped"; - $v_result = 1; - } - - // ----- Update the informations - // Only some fields can be modified - if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { - $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); - } - } - - // ----- Look for empty stored filename - if ($p_header['stored_filename'] == "") { - $p_header['status'] = "filtered"; - } - - // ----- Check the path length - if (strlen($p_header['stored_filename']) > 0xFF) { - $p_header['status'] = 'filename_too_long'; - } - - // ----- Look if no error, or file not skipped - if ($p_header['status'] == 'ok') { - - // ----- Look for a file - if ($p_filedescr['type'] == 'file') { - // ----- Look for using temporary file to zip - if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { - $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); - if ($v_result < PCLZIP_ERR_NO_ERROR) { - return $v_result; - } - } - - // ----- Use "in memory" zip algo - else { - - // ----- Open the source file - if (($v_file = @fopen($p_filename, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); - return PclZip::errorCode(); - } - - // ----- Read the file content - $v_content = @fread($v_file, $p_header['size']); - - // ----- Close the file - @fclose($v_file); - - // ----- Calculate the CRC - $p_header['crc'] = @crc32($v_content); - - // ----- Look for no compression - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { - // ----- Set header parameters - $p_header['compressed_size'] = $p_header['size']; - $p_header['compression'] = 0; - } - - // ----- Look for normal compression - else { - // ----- Compress the content - $v_content = @gzdeflate($v_content); - - // ----- Set header parameters - $p_header['compressed_size'] = strlen($v_content); - $p_header['compression'] = 8; - } - - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - @fclose($v_file); - return $v_result; - } - - // ----- Write the compressed (or not) content - @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); - - } - - } - - // ----- Look for a virtual file (a file from string) - else if ($p_filedescr['type'] == 'virtual_file') { - - $v_content = $p_filedescr['content']; - - // ----- Calculate the CRC - $p_header['crc'] = @crc32($v_content); - - // ----- Look for no compression - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { - // ----- Set header parameters - $p_header['compressed_size'] = $p_header['size']; - $p_header['compression'] = 0; - } - - // ----- Look for normal compression - else { - // ----- Compress the content - $v_content = @gzdeflate($v_content); - - // ----- Set header parameters - $p_header['compressed_size'] = strlen($v_content); - $p_header['compression'] = 8; - } - - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - @fclose($v_file); - return $v_result; - } - - // ----- Write the compressed (or not) content - @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); - } - - // ----- Look for a directory - else if ($p_filedescr['type'] == 'folder') { - // ----- Look for directory last '/' - if (@substr($p_header['stored_filename'], -1) != '/') { - $p_header['stored_filename'] .= '/'; - } - - // ----- Set the file properties - $p_header['size'] = 0; - //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked - $p_header['external'] = 0x00000010; // Value for a folder : to be checked - - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) - { - return $v_result; - } - } - } - - // ----- Look for post-add callback - if (isset($p_options[PCLZIP_CB_POST_ADD])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_header, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); - if ($v_result == 0) { - // ----- Ignored - $v_result = 1; - } - - // ----- Update the informations - // Nothing can be modified - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddFileUsingTempFile() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) - { - $v_result=PCLZIP_ERR_NO_ERROR; - - // ----- Working variable - $p_filename = $p_filedescr['filename']; - - - // ----- Open the source file - if (($v_file = @fopen($p_filename, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); - return PclZip::errorCode(); - } - - // ----- Creates a compressed temporary file - $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; - if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { - fclose($v_file); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); - return PclZip::errorCode(); - } - - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = filesize($p_filename); - while ($v_size != 0) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_file, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @gzputs($v_file_compressed, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Close the file - @fclose($v_file); - @gzclose($v_file_compressed); - - // ----- Check the minimum file size - if (filesize($v_gzip_temp_name) < 18) { - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); - return PclZip::errorCode(); - } - - // ----- Extract the compressed attributes - if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); - } - - // ----- Read the gzip file header - $v_binary_data = @fread($v_file_compressed, 10); - $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); - - // ----- Check some parameters - $v_data_header['os'] = bin2hex($v_data_header['os']); - - // ----- Read the gzip file footer - @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); - $v_binary_data = @fread($v_file_compressed, 8); - $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); - - // ----- Set the attributes - $p_header['compression'] = ord($v_data_header['cm']); - //$p_header['mtime'] = $v_data_header['mtime']; - $p_header['crc'] = $v_data_footer['crc']; - $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; - - // ----- Close the file - @fclose($v_file_compressed); - - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - return $v_result; - } - - // ----- Add the compressed data - if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) - { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); - } - - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - fseek($v_file_compressed, 10); - $v_size = $p_header['compressed_size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_file_compressed, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Close the file - @fclose($v_file_compressed); - - // ----- Unlink the temporary file - @unlink($v_gzip_temp_name); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCalculateStoredFilename() - // Description : - // Based on file descriptor properties and global options, this method - // calculate the filename that will be stored in the archive. - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privCalculateStoredFilename(&$p_filedescr, &$p_options) - { - $v_result=1; - - // ----- Working variables - $p_filename = $p_filedescr['filename']; - if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { - $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; - } - else { - $p_add_dir = ''; - } - if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { - $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; - } - else { - $p_remove_dir = ''; - } - if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - else { - $p_remove_all_dir = 0; - } - - - // ----- Look for full name change - if (isset($p_filedescr['new_full_name'])) { - // ----- Remove drive letter if any - $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); - } - - // ----- Look for path and/or short name change - else { - - // ----- Look for short name change - // Its when we cahnge just the filename but not the path - if (isset($p_filedescr['new_short_name'])) { - $v_path_info = pathinfo($p_filename); - $v_dir = ''; - if ($v_path_info['dirname'] != '') { - $v_dir = $v_path_info['dirname'].'/'; - } - $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; - } - else { - // ----- Calculate the stored filename - $v_stored_filename = $p_filename; - } - - // ----- Look for all path to remove - if ($p_remove_all_dir) { - $v_stored_filename = basename($p_filename); - } - // ----- Look for partial path remove - else if ($p_remove_dir != "") { - if (substr($p_remove_dir, -1) != '/') - $p_remove_dir .= "/"; - - if ( (substr($p_filename, 0, 2) == "./") - || (substr($p_remove_dir, 0, 2) == "./")) { - - if ( (substr($p_filename, 0, 2) == "./") - && (substr($p_remove_dir, 0, 2) != "./")) { - $p_remove_dir = "./".$p_remove_dir; - } - if ( (substr($p_filename, 0, 2) != "./") - && (substr($p_remove_dir, 0, 2) == "./")) { - $p_remove_dir = substr($p_remove_dir, 2); - } - } - - $v_compare = PclZipUtilPathInclusion($p_remove_dir, - $v_stored_filename); - if ($v_compare > 0) { - if ($v_compare == 2) { - $v_stored_filename = ""; - } - else { - $v_stored_filename = substr($v_stored_filename, - strlen($p_remove_dir)); - } - } - } - - // ----- Remove drive letter if any - $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); - - // ----- Look for path to add - if ($p_add_dir != "") { - if (substr($p_add_dir, -1) == "/") - $v_stored_filename = $p_add_dir.$v_stored_filename; - else - $v_stored_filename = $p_add_dir."/".$v_stored_filename; - } - } - - // ----- Filename (reduce the path of stored name) - $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); - $p_filedescr['stored_filename'] = $v_stored_filename; - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privWriteFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privWriteFileHeader(&$p_header) - { - $v_result=1; - - // ----- Store the offset position of the file - $p_header['offset'] = ftell($this->zip_fd); - - // ----- Transform UNIX mtime to DOS format mdate/mtime - $v_date = getdate($p_header['mtime']); - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; - - // ----- Packed data - $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, - $p_header['version_extracted'], $p_header['flag'], - $p_header['compression'], $v_mtime, $v_mdate, - $p_header['crc'], $p_header['compressed_size'], - $p_header['size'], - strlen($p_header['stored_filename']), - $p_header['extra_len']); - - // ----- Write the first 148 bytes of the header in the archive - fputs($this->zip_fd, $v_binary_data, 30); - - // ----- Write the variable fields - if (strlen($p_header['stored_filename']) != 0) - { - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); - } - if ($p_header['extra_len'] != 0) - { - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privWriteCentralFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privWriteCentralFileHeader(&$p_header) - { - $v_result=1; - - // TBC - //for(reset($p_header); $key = key($p_header); next($p_header)) { - //} - - // ----- Transform UNIX mtime to DOS format mdate/mtime - $v_date = getdate($p_header['mtime']); - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; - - - // ----- Packed data - $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, - $p_header['version'], $p_header['version_extracted'], - $p_header['flag'], $p_header['compression'], - $v_mtime, $v_mdate, $p_header['crc'], - $p_header['compressed_size'], $p_header['size'], - strlen($p_header['stored_filename']), - $p_header['extra_len'], $p_header['comment_len'], - $p_header['disk'], $p_header['internal'], - $p_header['external'], $p_header['offset']); - - // ----- Write the 42 bytes of the header in the zip file - fputs($this->zip_fd, $v_binary_data, 46); - - // ----- Write the variable fields - if (strlen($p_header['stored_filename']) != 0) - { - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); - } - if ($p_header['extra_len'] != 0) - { - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); - } - if ($p_header['comment_len'] != 0) - { - fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privWriteCentralHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) - { - $v_result=1; - - // ----- Packed data - $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, - $p_nb_entries, $p_size, - $p_offset, strlen($p_comment)); - - // ----- Write the 22 bytes of the header in the zip file - fputs($this->zip_fd, $v_binary_data, 22); - - // ----- Write the variable fields - if (strlen($p_comment) != 0) - { - fputs($this->zip_fd, $p_comment, strlen($p_comment)); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privList() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privList(&$p_list) - { - $v_result=1; - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) - { - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privSwapBackMagicQuotes(); - return $v_result; - } - - // ----- Go to beginning of Central Dir - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_central_dir['offset'])) - { - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read each entry - for ($i=0; $i<$v_central_dir['entries']; $i++) - { - // ----- Read the file header - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) - { - $this->privSwapBackMagicQuotes(); - return $v_result; - } - $v_header['index'] = $i; - - // ----- Get the only interesting attributes - $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); - unset($v_header); - } - - // ----- Close the zip file - $this->privCloseFd(); - - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privConvertHeader2FileInfo() - // Description : - // This function takes the file informations from the central directory - // entries and extract the interesting parameters that will be given back. - // The resulting file infos are set in the array $p_info - // $p_info['filename'] : Filename with full path. Given by user (add), - // extracted in the filesystem (extract). - // $p_info['stored_filename'] : Stored filename in the archive. - // $p_info['size'] = Size of the file. - // $p_info['compressed_size'] = Compressed size of the file. - // $p_info['mtime'] = Last modification date of the file. - // $p_info['comment'] = Comment associated with the file. - // $p_info['folder'] = true/false : indicates if the entry is a folder or not. - // $p_info['status'] = status of the action on the file. - // $p_info['crc'] = CRC of the file content. - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privConvertHeader2FileInfo($p_header, &$p_info) - { - $v_result=1; - - // ----- Get the interesting attributes - $v_temp_path = PclZipUtilPathReduction($p_header['filename']); - $p_info['filename'] = $v_temp_path; - $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); - $p_info['stored_filename'] = $v_temp_path; - $p_info['size'] = $p_header['size']; - $p_info['compressed_size'] = $p_header['compressed_size']; - $p_info['mtime'] = $p_header['mtime']; - $p_info['comment'] = $p_header['comment']; - $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); - $p_info['index'] = $p_header['index']; - $p_info['status'] = $p_header['status']; - $p_info['crc'] = $p_header['crc']; - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractByRule() - // Description : - // Extract a file or directory depending of rules (by index, by name, ...) - // Parameters : - // $p_file_list : An array where will be placed the properties of each - // extracted file - // $p_path : Path to add while writing the extracted files - // $p_remove_path : Path to remove (from the file memorized path) while writing the - // extracted files. If the path does not match the file path, - // the file is extracted with its memorized path. - // $p_remove_path does not apply to 'list' mode. - // $p_path and $p_remove_path are commulative. - // Return Values : - // 1 on success,0 or less on error (see error code list) - // -------------------------------------------------------------------------------- - function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) - { - $v_result=1; - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Check the path - if ( ($p_path == "") - || ( (substr($p_path, 0, 1) != "/") - && (substr($p_path, 0, 3) != "../") - && (substr($p_path,1,2)!=":/"))) - $p_path = "./".$p_path; - - // ----- Reduce the path last (and duplicated) '/' - if (($p_path != "./") && ($p_path != "/")) - { - // ----- Look for the path end '/' - while (substr($p_path, -1) == "/") - { - $p_path = substr($p_path, 0, strlen($p_path)-1); - } - } - - // ----- Look for path to remove format (should end by /) - if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) - { - $p_remove_path .= '/'; - } - $p_remove_path_size = strlen($p_remove_path); - - // ----- Open the zip file - if (($v_result = $this->privOpenFd('rb')) != 1) - { - $this->privSwapBackMagicQuotes(); - return $v_result; - } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - return $v_result; - } - - // ----- Start at beginning of Central Dir - $v_pos_entry = $v_central_dir['offset']; - - // ----- Read each entry - $j_start = 0; - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) - { + // ----- Check if the option is supported + if (!isset($v_requested_options[$p_options_list[$i]])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); - // ----- Read next Central dir entry - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_pos_entry)) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Return + return PclZip::errorCode(); + } + // ----- Look for next option + switch ($p_options_list[$i]) { + // ----- Look for options that request a path value + case PCLZIP_OPT_PATH : + case PCLZIP_OPT_REMOVE_PATH : + case PCLZIP_OPT_ADD_PATH : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } - // ----- Read the file header - $v_header = array(); - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Get the value + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false); + $i++; + break; - return $v_result; + case PCLZIP_OPT_TEMP_FILE_THRESHOLD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + // ----- Check the value + $v_value = $p_options_list[$i+1]; + if ((!is_integer($v_value)) || ($v_value<0)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); } - // ----- Store the index - $v_header['index'] = $i; - - // ----- Store the file position - $v_pos_entry = ftell($this->zip_fd); + // ----- Get the value (and convert it in bytes) + $v_result_list[$p_options_list[$i]] = $v_value*1048576; + $i++; + break; - // ----- Look for the specific extract rules - $v_extract = false; + case PCLZIP_OPT_TEMP_FILE_ON : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; - // ----- Look for extract by name rule - if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + case PCLZIP_OPT_TEMP_FILE_OFF : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); + return PclZip::errorCode(); + } + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; - // ----- Look if the filename is in the list - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - // ----- Look for a directory - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + // ----- Return + return PclZip::errorCode(); + } - // ----- Look if the directory is in the filename path - if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) - && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_extract = true; - } - } - // ----- Look for a filename - elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { - $v_extract = true; - } - } + // ----- Get the value + if (is_string($p_options_list[$i+1]) + && ($p_options_list[$i+1] != '')) { + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false); + $i++; + } + else { } + break; - // ----- Look for extract by ereg rule - // ereg() is deprecated with PHP 5.3 - /* - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + // ----- Look for options that request an array of string for value + case PCLZIP_OPT_BY_NAME : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { - $v_extract = true; - } + // ----- Return + return PclZip::errorCode(); } - */ - // ----- Look for extract by preg rule - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { - $v_extract = true; - } + // ----- Return + return PclZip::errorCode(); } + $i++; + break; + + // ----- Look for options that request an EREG or PREG expression + case PCLZIP_OPT_BY_EREG : + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG + // to PCLZIP_OPT_BY_PREG + $p_options_list[$i] = PCLZIP_OPT_BY_PREG; + case PCLZIP_OPT_BY_PREG : + //case PCLZIP_OPT_CRYPT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - // ----- Look for extract by index rule - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - - // ----- Look if the index is in the list - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { + // ----- Return + return PclZip::errorCode(); + } - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_extract = true; - } - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; - } + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; - } - } + // ----- Return + return PclZip::errorCode(); } + $i++; + break; + + // ----- Look for options that takes a string + case PCLZIP_OPT_COMMENT : + case PCLZIP_OPT_ADD_COMMENT : + case PCLZIP_OPT_PREPEND_COMMENT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, + "Missing parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); - // ----- Look for no rule, which means extract all the archive - else { - $v_extract = true; + // ----- Return + return PclZip::errorCode(); } - // ----- Check compression method - if ( ($v_extract) - && ( ($v_header['compression'] != 8) - && ($v_header['compression'] != 0))) { - $v_header['status'] = 'unsupported_compression'; + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, + "Wrong parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, - "Filename '".$v_header['stored_filename']."' is " - ."compressed by an unsupported compression " - ."method (".$v_header['compression'].") "); + // ----- Look for options that request an array of index + case PCLZIP_OPT_BY_INDEX : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } + // ----- Return + return PclZip::errorCode(); } - - // ----- Check encrypted files - if (($v_extract) && (($v_header['flag'] & 1) == 1)) { - $v_header['status'] = 'unsupported_encryption'; - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Get the value + $v_work_list = array(); + if (is_string($p_options_list[$i+1])) { - $this->privSwapBackMagicQuotes(); + // ----- Remove spaces + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, - "Unsupported encryption for " - ." filename '".$v_header['stored_filename'] - ."'"); + // ----- Parse items + $v_work_list = explode(",", $p_options_list[$i+1]); + } + else if (is_integer($p_options_list[$i+1])) { + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_work_list = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); + // ----- Return + return PclZip::errorCode(); + } + + // ----- Reduce the index list + // each index item in the list must be a couple with a start and + // an end value : [0,3], [5-5], [8-10], ... + // ----- Check the format of each item + $v_sort_flag=false; + $v_sort_value=0; + for ($j=0; $j<sizeof($v_work_list); $j++) { + // ----- Explode the item + $v_item_list = explode("-", $v_work_list[$j]); + $v_size_item_list = sizeof($v_item_list); + + // ----- TBC : Here we might check that each item is a + // real integer ... + + // ----- Look for single value + if ($v_size_item_list == 1) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; } - } + elseif ($v_size_item_list == 2) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - // ----- Look for real extraction - if (($v_extract) && ($v_header['status'] != 'ok')) { - $v_result = $this->privConvertHeader2FileInfo($v_header, - $p_file_list[$v_nb_extracted++]); - if ($v_result != 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; + // ----- Return + return PclZip::errorCode(); } - $v_extract = false; - } - - // ----- Look for real extraction - if ($v_extract) - { - // ----- Go to the file position - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_header['offset'])) - { - // ----- Close the zip file - $this->privCloseFd(); + // ----- Look for list sort + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { + $v_sort_flag=true; - $this->privSwapBackMagicQuotes(); + // ----- TBC : An automatic sort should be writen ... + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Return + return PclZip::errorCode(); + } + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; + } + + // ----- Sort the items + if ($v_sort_flag) { + // TBC : To Be Completed + } - // ----- Return - return PclZip::errorCode(); - } + // ----- Next option + $i++; + break; + + // ----- Look for options that request no value + case PCLZIP_OPT_REMOVE_ALL_PATH : + case PCLZIP_OPT_EXTRACT_AS_STRING : + case PCLZIP_OPT_NO_COMPRESSION : + case PCLZIP_OPT_EXTRACT_IN_OUTPUT : + case PCLZIP_OPT_REPLACE_NEWER : + case PCLZIP_OPT_STOP_ON_ERROR : + $v_result_list[$p_options_list[$i]] = true; + break; + + // ----- Look for options that request an octal value + case PCLZIP_OPT_SET_CHMOD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - // ----- Look for extraction as string - if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { + // ----- Return + return PclZip::errorCode(); + } - $v_string = ''; + // ----- Get the value + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + $i++; + break; + + // ----- Look for options that request a call-back + case PCLZIP_CB_PRE_EXTRACT : + case PCLZIP_CB_POST_EXTRACT : + case PCLZIP_CB_PRE_ADD : + case PCLZIP_CB_POST_ADD : + /* for futur use + case PCLZIP_CB_PRE_DELETE : + case PCLZIP_CB_POST_DELETE : + case PCLZIP_CB_PRE_LIST : + case PCLZIP_CB_POST_LIST : + */ + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - // ----- Extracting the file - $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } + // ----- Return + return PclZip::errorCode(); + } - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Get the value + $v_function_name = $p_options_list[$i+1]; - return $v_result; - } + // ----- Check that the value is a valid existing function + if (!function_exists($v_function_name)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VA )); + if ($v_result != 1) { + return 0; + } + } - // ----- Set the file content - $p_file_list[$v_nb_extracted]['content'] = $v_string; + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { - // ----- Next extracted file - $v_nb_extracted++; - - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } - } - // ----- Look for extraction in standard output - elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) - && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { - // ----- Extracting the file in standard output - $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Invalid number / type of arguments"); + return 0; + } + } +} - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } - } - // ----- Look for normal extraction - else { - // ----- Extracting the file - $v_result1 = $this->privExtractFile($v_header, - $p_path, $p_remove_path, - $p_remove_all_path, - $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } +// ----- Look for default option values +$this->privOptionDefaultThreshold($v_options); - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); +// ----- Init +$v_string_list = array(); +$v_att_list = array(); +$v_filedescr_list = array(); +$p_result_list = array(); - return $v_result; - } +// ----- Look if the $p_filelist is really an array +if (is_array($p_filelist)) { - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } - } - } + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } +} + +// ----- Look if the $p_filelist is a string +else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); +} + +// ----- Invalid variable type for $p_filelist +else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + return 0; +} + +// ----- Reformat the string list +if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + else { } - - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFile() - // Description : - // Parameters : - // Return Values : - // - // 1 : ... ? - // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback - // -------------------------------------------------------------------------------- - function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) - { - $v_result=1; +} + +// ----- For each file in the list check the attributes +$v_supported_attributes += array (PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); +foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } +} + +// ----- Expand the filelist (expand directories) +$v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); +if ($v_result != 1) { + return 0; +} + +// ----- Call the create fct +$v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); +if ($v_result != 1) { + return 0; +} + +// ----- Return +return $p_result_list; +} +// -------------------------------------------------------------------------------- - // ----- Read the file header - if (($v_result = $this->privReadFileHeader($v_header)) != 1) - { - // ----- Return - return $v_result; +// -------------------------------------------------------------------------------- +// Function : +// add($p_filelist, $p_add_dir="", $p_remove_dir="") +// add($p_filelist, $p_option, $p_option_value, ...) +// Description : +// This method supports two synopsis. The first one is historical. +// This methods add the list of files in an existing archive. +// If a file with the same name already exists, it is added at the end of the +// archive, the first one is still present. +// If the archive does not exist, it is created. +// Parameters : +// $p_filelist : An array containing file or directory names, or +// a string containing one filename or one directory name, or +// a string containing a list of filenames and/or directory +// names separated by spaces. +// $p_add_dir : A path to add before the real path of the archived file, +// in order to have it memorized in the archive. +// $p_remove_dir : A path to remove from the real path of the file to archive, +// in order to have a shorter path memorized in the archive. +// When $p_add_dir and $p_remove_dir are set, $p_remove_dir +// is removed first, before $p_add_dir is added. +// Options : +// PCLZIP_OPT_ADD_PATH : +// PCLZIP_OPT_REMOVE_PATH : +// PCLZIP_OPT_REMOVE_ALL_PATH : +// PCLZIP_OPT_COMMENT : +// PCLZIP_OPT_ADD_COMMENT : +// PCLZIP_OPT_PREPEND_COMMENT : +// PCLZIP_CB_PRE_ADD : +// PCLZIP_CB_POST_ADD : +// Return Values : +// 0 on failure, +// The list of the added files, with a status of the add action. +// (see PclZip::listContent() for list entry format) +// -------------------------------------------------------------------------------- +function add($p_filelist) +{ +$v_result=1; + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Set default values +$v_options = array(); +$v_options[PCLZIP_OPT_NO_COMPRESSION] = false; + +// ----- Look for variable options arguments +$v_size = func_num_args(); + +// ----- Look for arguments +if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; } + } + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { - // ----- Check that the file header is coherent with $p_entry info - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Look for all path to remove - if ($p_remove_all_path == true) { - // ----- Look for folder entry that not need to be extracted - if (($p_entry['external']&0x00000010)==0x00000010) { + // ----- Return + return 0; + } + } +} - $p_entry['status'] = "filtered"; +// ----- Look for default option values +$this->privOptionDefaultThreshold($v_options); - return $v_result; - } +// ----- Init +$v_string_list = array(); +$v_att_list = array(); +$v_filedescr_list = array(); +$p_result_list = array(); - // ----- Get the basename of the path - $p_entry['filename'] = basename($p_entry['filename']); - } +// ----- Look if the $p_filelist is really an array +if (is_array($p_filelist)) { - // ----- Look for path to remove - else if ($p_remove_path != "") - { - if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) - { + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } +} + +// ----- Look if the $p_filelist is a string +else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); +} + +// ----- Invalid variable type for $p_filelist +else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); + return 0; +} + +// ----- Reformat the string list +if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } +} + +// ----- For each file in the list check the attributes +$v_supported_attributes += array (PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); +foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } +} + +// ----- Expand the filelist (expand directories) +$v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); +if ($v_result != 1) { + return 0; +} + +// ----- Call the create fct +$v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); +if ($v_result != 1) { + return 0; +} + +// ----- Return +return $p_result_list; +} +// -------------------------------------------------------------------------------- - // ----- Change the file status - $p_entry['status'] = "filtered"; +// -------------------------------------------------------------------------------- +// Function : listContent() +// Description : +// This public method, gives the list of the files and directories, with their +// properties. +// The properties of each entries in the list are (used also in other functions) : +// filename : Name of the file. For a create or add action it is the filename +// given by the user. For an extract function it is the filename +// of the extracted file. +// stored_filename : Name of the file / directory stored in the archive. +// size : Size of the stored file. +// compressed_size : Size of the file's data compressed in the archive +// (without the headers overhead) +// mtime : Last known modification date of the file (UNIX timestamp) +// comment : Comment associated with the file +// folder : true | false +// index : index of the file in the archive +// status : status of the action (depending of the action) : +// Values are : +// ok : OK ! +// filtered : the file / dir is not extracted (filtered by user) +// already_a_directory : the file can not be extracted because a +// directory with the same name already exists +// write_protected : the file can not be extracted because a file +// with the same name already exists and is +// write protected +// newer_exist : the file was not extracted because a newer file exists +// path_creation_fail : the file is not extracted because the folder +// does not exist and can not be created +// write_error : the file was not extracted because there was a +// error while writing the file +// read_error : the file was not extracted because there was a error +// while reading the file +// invalid_header : the file was not extracted because of an archive +// format error (bad file header) +// Note that each time a method can continue operating when there +// is an action error on a file, the error is only logged in the file status. +// Return Values : +// 0 on an unrecoverable failure, +// The list of the files in the archive. +// -------------------------------------------------------------------------------- +function listContent() +{ +$v_result=1; + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Check archive +if (!$this->privCheckFormat()) { + return(0); +} + +// ----- Call the extracting fct +$p_list = array(); +if (($v_result = $this->privList($p_list)) != 1) +{ + unset($p_list); + return(0); +} + +// ----- Return +return $p_list; +} +// -------------------------------------------------------------------------------- - // ----- Return - return $v_result; - } +// -------------------------------------------------------------------------------- +// Function : +// extract($p_path="./", $p_remove_path="") +// extract([$p_option, $p_option_value, ...]) +// Description : +// This method supports two synopsis. The first one is historical. +// This method extract all the files / directories from the archive to the +// folder indicated in $p_path. +// If you want to ignore the 'root' part of path of the memorized files +// you can indicate this in the optional $p_remove_path parameter. +// By default, if a newer file with the same name already exists, the +// file is not extracted. +// +// If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions +// are used, the path indicated in PCLZIP_OPT_ADD_PATH is append +// at the end of the path value of PCLZIP_OPT_PATH. +// Parameters : +// $p_path : Path where the files and directories are to be extracted +// $p_remove_path : First part ('root' part) of the memorized path +// (if any similar) to remove while extracting. +// Options : +// PCLZIP_OPT_PATH : +// PCLZIP_OPT_ADD_PATH : +// PCLZIP_OPT_REMOVE_PATH : +// PCLZIP_OPT_REMOVE_ALL_PATH : +// PCLZIP_CB_PRE_EXTRACT : +// PCLZIP_CB_POST_EXTRACT : +// Return Values : +// 0 or a negative value on failure, +// The list of the extracted files, with a status of the action. +// (see PclZip::listContent() for list entry format) +// -------------------------------------------------------------------------------- +function extract() +{ +$v_result=1; - $p_remove_path_size = strlen($p_remove_path); - if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) - { +// ----- Reset the error handler +$this->privErrorReset(); - // ----- Remove the path - $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); +// ----- Check archive +if (!$this->privCheckFormat()) { + return(0); +} - } +// ----- Set default values +$v_options = array(); +// $v_path = "./"; +$v_path = ''; +$v_remove_path = ""; +$v_remove_all_path = false; + +// ----- Look for variable options arguments +$v_size = func_num_args(); + +// ----- Default values for option +$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; + +// ----- Look for arguments +if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; } - // ----- Add the path - if ($p_path != '') { - $p_entry['filename'] = $p_path."/".$p_entry['filename']; + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; } - - // ----- Check a base_dir_restriction - if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { - $v_inclusion - = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], - $p_entry['filename']); - if ($v_inclusion == 0) { + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } - PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, - "Filename '".$p_entry['filename']."' is " - ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { - return PclZip::errorCode(); - } + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Look for pre-extract callback - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + // ----- Return + return 0; + } + } +} - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); +// ----- Look for default option values +$this->privOptionDefaultThreshold($v_options); - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } - - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } +// ----- Trace - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; - } +// ----- Call the extracting fct +$p_list = array(); +$v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, + $v_remove_all_path, $v_options); +if ($v_result < 1) { + unset($p_list); + return(0); +} +// ----- Return +return $p_list; +} +// -------------------------------------------------------------------------------- - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { - // ----- Look for specific actions while the file exist - if (file_exists($p_entry['filename'])) - { +// -------------------------------------------------------------------------------- +// Function : +// extractByIndex($p_index, $p_path="./", $p_remove_path="") +// extractByIndex($p_index, [$p_option, $p_option_value, ...]) +// Description : +// This method supports two synopsis. The first one is historical. +// This method is doing a partial extract of the archive. +// The extracted files or folders are identified by their index in the +// archive (from 0 to n). +// Note that if the index identify a folder, only the folder entry is +// extracted, not all the files included in the archive. +// Parameters : +// $p_index : A single index (integer) or a string of indexes of files to +// extract. The form of the string is "0,4-6,8-12" with only numbers +// and '-' for range or ',' to separate ranges. No spaces or ';' +// are allowed. +// $p_path : Path where the files and directories are to be extracted +// $p_remove_path : First part ('root' part) of the memorized path +// (if any similar) to remove while extracting. +// Options : +// PCLZIP_OPT_PATH : +// PCLZIP_OPT_ADD_PATH : +// PCLZIP_OPT_REMOVE_PATH : +// PCLZIP_OPT_REMOVE_ALL_PATH : +// PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and +// not as files. +// The resulting content is in a new field 'content' in the file +// structure. +// This option must be used alone (any other options are ignored). +// PCLZIP_CB_PRE_EXTRACT : +// PCLZIP_CB_POST_EXTRACT : +// Return Values : +// 0 on failure, +// The list of the extracted files, with a status of the action. +// (see PclZip::listContent() for list entry format) +// -------------------------------------------------------------------------------- +//function extractByIndex($p_index, options...) +function extractByIndex($p_index) +{ +$v_result=1; - // ----- Look if file is a directory - if (is_dir($p_entry['filename'])) - { +// ----- Reset the error handler +$this->privErrorReset(); - // ----- Change the file status - $p_entry['status'] = "already_a_directory"; - - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { +// ----- Check archive +if (!$this->privCheckFormat()) { + return(0); +} - PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, - "Filename '".$p_entry['filename']."' is " - ."already used by an existing directory"); +// ----- Set default values +$v_options = array(); +// $v_path = "./"; +$v_path = ''; +$v_remove_path = ""; +$v_remove_all_path = false; + +// ----- Look for variable options arguments +$v_size = func_num_args(); + +// ----- Default values for option +$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; + +// ----- Look for arguments +if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } - return PclZip::errorCode(); - } + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; } - // ----- Look if file is write protected - else if (!is_writeable($p_entry['filename'])) - { + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; + } + else { + } + } - // ----- Change the file status - $p_entry['status'] = "write_protected"; + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else ){ - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Get the first argument + $v_path = $v_arg_list[0]; - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Filename '".$p_entry['filename']."' exists " - ."and is write protected"); + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - return PclZip::errorCode(); - } - } + // ----- Return + return 0; + } + } +} + +// ----- Trace + +// ----- Trick +// Here I want to reuse extractByRule(), so I need to parse the $p_index +// with privParseOptions() +$v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); +$v_options_trick = array(); +$v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, + array (PCLZIP_OPT_BY_INDEX => 'optional')); +if ($v_result != 1) { + return 0; +} +$v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + +// ----- Look for default option values +$this->privOptionDefaultThreshold($v_options); + +// ----- Call the extracting fct +if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + return(0); +} + +// ----- Return +return $p_list; +} +// -------------------------------------------------------------------------------- - // ----- Look if the extracted file is older - else if (filemtime($p_entry['filename']) > $p_entry['mtime']) - { - // ----- Change the file status - if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) - && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { - } - else { - $p_entry['status'] = "newer_exist"; +// -------------------------------------------------------------------------------- +// Function : +// delete([$p_option, $p_option_value, ...]) +// Description : +// This method removes files from the archive. +// If no parameters are given, then all the archive is emptied. +// Parameters : +// None or optional arguments. +// Options : +// PCLZIP_OPT_BY_INDEX : +// PCLZIP_OPT_BY_NAME : +// PCLZIP_OPT_BY_EREG : +// PCLZIP_OPT_BY_PREG : +// Return Values : +// 0 on failure, +// The list of the files which are still present in the archive. +// (see PclZip::listContent() for list entry format) +// -------------------------------------------------------------------------------- +function delete() +{ +$v_result=1; + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Check archive +if (!$this->privCheckFormat()) { + return(0); +} + +// ----- Set default values +$v_options = array(); + +// ----- Look for variable options arguments +$v_size = func_num_args(); + +// ----- Look for arguments +if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional')); + if ($v_result != 1) { + return 0; + } +} - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { +// ----- Magic quotes trick +$this->privDisableMagicQuotes(); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Newer version of '".$p_entry['filename']."' exists " - ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); +// ----- Call the delete fct +$v_list = array(); +if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); + return(0); +} - return PclZip::errorCode(); - } - } - } - else { - } - } +// ----- Magic quotes trick +$this->privSwapBackMagicQuotes(); - // ----- Check the directory availability and create it if necessary - else { - if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) - $v_dir_to_check = $p_entry['filename']; - else if (!strstr($p_entry['filename'], "/")) - $v_dir_to_check = ""; - else - $v_dir_to_check = dirname($p_entry['filename']); - - if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { - - // ----- Change the file status - $p_entry['status'] = "path_creation_fail"; - - // ----- Return - //return $v_result; - $v_result = 1; - } - } - } +// ----- Return +return $v_list; +} +// -------------------------------------------------------------------------------- - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { +// -------------------------------------------------------------------------------- +// Function : deleteByIndex() +// Description : +// ***** Deprecated ***** +// delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. +// -------------------------------------------------------------------------------- +function deleteByIndex($p_index) +{ - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) - { - // ----- Look for not compressed file - if ($p_entry['compression'] == 0) { +$p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) - { +// ----- Return +return $p_list; +} +// -------------------------------------------------------------------------------- - // ----- Change the file status - $p_entry['status'] = "write_error"; +// -------------------------------------------------------------------------------- +// Function : properties() +// Description : +// This method gives the properties of the archive. +// The properties are : +// nb : Number of files in the archive +// comment : Comment associated with the archive file +// status : not_exist, ok +// Parameters : +// None +// Return Values : +// 0 on failure, +// An array with the archive properties. +// -------------------------------------------------------------------------------- +function properties() +{ + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Magic quotes trick +$this->privDisableMagicQuotes(); + +// ----- Check archive +if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + return(0); +} + +// ----- Default properties +$v_prop = array(); +$v_prop['comment'] = ''; +$v_prop['nb'] = 0; +$v_prop['status'] = 'not_exist'; + +// ----- Look if file exists +if (@is_file($this->zipname)) +{ + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - // ----- Return - return $v_result; - } + // ----- Return + return 0; + } + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return 0; + } - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = $p_entry['compressed_size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - /* Try to speed up the code - $v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_binary_data, $v_read_size); - */ - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Close the zip file + $this->privCloseFd(); - // ----- Closing the destination file - fclose($v_dest_file); + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; +} - // ----- Change the file mtime - touch($p_entry['filename'], $p_entry['mtime']); - +// ----- Magic quotes trick +$this->privSwapBackMagicQuotes(); - } - else { - // ----- TBC - // Need to be finished - if (($p_entry['flag'] & 1) == 1) { - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); - return PclZip::errorCode(); - } +// ----- Return +return $v_prop; +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : duplicate() +// Description : +// This method creates an archive by copying the content of an other one. If +// the archive already exist, it is replaced by the new one without any warning. +// Parameters : +// $p_archive : The filename of a valid archive, or +// a valid PclZip object. +// Return Values : +// 1 on success. +// 0 or a negative value on error (error code). +// -------------------------------------------------------------------------------- +function duplicate($p_archive) +{ +$v_result = 1; + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Look if the $p_archive is a PclZip object +if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) +{ + + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); +} + +// ----- Look if the $p_archive is a string (so a filename) +else if (is_string($p_archive)) +{ + + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } + else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } +} + +// ----- Invalid variable +else +{ + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------- +// Function : merge() +// Description : +// This method merge the $p_archive_to_add archive at the end of the current +// one ($this). +// If the archive ($this) does not exist, the merge becomes a duplicate. +// If the $p_archive_to_add archive does not exist, the merge is a success. +// Parameters : +// $p_archive_to_add : It can be directly the filename of a valid zip archive, +// or a PclZip object archive. +// Return Values : +// 1 on success, +// 0 or negative values on error (see below). +// -------------------------------------------------------------------------------- +function merge($p_archive_to_add) +{ +$v_result = 1; + +// ----- Reset the error handler +$this->privErrorReset(); + +// ----- Check archive +if (!$this->privCheckFormat()) { + return(0); +} + +// ----- Look if the $p_archive_to_add is a PclZip object +if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) +{ + + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); +} + +// ----- Look if the $p_archive_to_add is a string (so a filename) +else if (is_string($p_archive_to_add)) +{ + + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); +} + +// ----- Invalid variable +else +{ + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Look for using temporary file to unzip - if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { - $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); - if ($v_result < PCLZIP_ERR_NO_ERROR) { - return $v_result; - } - } - - // ----- Look for extract in memory - else { - - // ----- Read the compressed file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - $v_file_content = @gzinflate($v_buffer); - unset($v_buffer); - if ($v_file_content === FALSE) { - - // ----- Change the file status - // TBC - $p_entry['status'] = "error"; - - return $v_result; - } - - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - - // ----- Change the file status - $p_entry['status'] = "write_error"; - - return $v_result; - } - - // ----- Write the uncompressed data - @fwrite($v_dest_file, $v_file_content, $p_entry['size']); - unset($v_file_content); - - // ----- Closing the destination file - @fclose($v_dest_file); - - } - // ----- Change the file mtime - @touch($p_entry['filename'], $p_entry['mtime']); - } +// -------------------------------------------------------------------------------- +// Function : errorCode() +// Description : +// Parameters : +// -------------------------------------------------------------------------------- +function errorCode() +{ +if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorCode()); +} +else { + return($this->error_code); +} +} +// -------------------------------------------------------------------------------- - // ----- Look for chmod option - if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { +// -------------------------------------------------------------------------------- +// Function : errorName() +// Description : +// Parameters : +// -------------------------------------------------------------------------------- +function errorName($p_with_code=false) +{ +$v_name = array (PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' + ) == 0) +{ + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); +} + +// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks +fseek($v_file_compressed, 10); +$v_size = $p_header['compressed_size']; +while ($v_size != 0) +{ + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file_compressed, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; +} + +// ----- Close the file +@fclose($v_file_compressed); + +// ----- Unlink the temporary file +@unlink($v_gzip_temp_name); + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Change the mode of the file - @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); - } +// -------------------------------------------------------------------------------- +// Function : privCalculateStoredFilename() +// Description : +// Based on file descriptor properties and global options, this method +// calculate the filename that will be stored in the archive. +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privCalculateStoredFilename(&$p_filedescr, &$p_options) +{ +$v_result=1; + +// ----- Working variables +$p_filename = $p_filedescr['filename']; +if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; +} +else { + $p_add_dir = ''; +} +if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; +} +else { + $p_remove_dir = ''; +} +if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; +} +else { + $p_remove_all_dir = 0; +} + + +// ----- Look for full name change +if (isset($p_filedescr['new_full_name'])) { + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); +} + +// ----- Look for path and/or short name change +else { + + // ----- Look for short name change + // Its when we cahnge just the filename but not the path + if (isset($p_filedescr['new_short_name'])) { + $v_path_info = pathinfo($p_filename); + $v_dir = ''; + if ($v_path_info['dirname'] != '') { + $v_dir = $v_path_info['dirname'].'/'; + } + $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; + } + else { + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + } + + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + } + // ----- Look for partial path remove + else if ($p_remove_dir != "") { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + if ((substr($p_filename, 0, 2) == "./") + || (substr($p_remove_dir, 0, 2) == "./")) { + + if ((substr($p_filename, 0, 2) == "./") + && (substr($p_remove_dir, 0, 2) != "./")) { + $p_remove_dir = "./".$p_remove_dir; + } + if ((substr($p_filename, 0, 2) != "./") + && (substr($p_remove_dir, 0, 2) == "./")) { + $p_remove_dir = substr($p_remove_dir, 2); } } - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; + $v_compare = PclZipUtilPathInclusion($p_remove_dir, + $v_stored_filename); + if ($v_compare > 0) { + if ($v_compare == 2) { + $v_stored_filename = ""; } - - // ----- Look for post-extract callback - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + else { + $v_stored_filename = substr($v_stored_filename, + strlen($p_remove_dir)); + } + } + } + + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); + + // ----- Look for path to add + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } +} - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); +// ----- Filename (reduce the path of stored name) +$v_stored_filename = PclZipUtilPathReduction($v_stored_filename); +$p_filedescr['stored_filename'] = $v_stored_filename; - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; - } - } +// -------------------------------------------------------------------------------- +// Function : privWriteFileHeader() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privWriteFileHeader(&$p_header) +{ +$v_result=1; + +// ----- Store the offset position of the file +$p_header['offset'] = ftell($this->zip_fd); + +// ----- Transform UNIX mtime to DOS format mdate/mtime +$v_date = getdate($p_header['mtime']); +$v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; +$v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + +// ----- Packed data +$v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, + $p_header['version_extracted'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], + $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len']); + +// ----- Write the first 148 bytes of the header in the archive +fputs($this->zip_fd, $v_binary_data, 30); + +// ----- Write the variable fields +if (strlen($p_header['stored_filename']) != 0) +{ + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); +} +if ($p_header['extra_len'] != 0) +{ + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Return +// -------------------------------------------------------------------------------- +// Function : privWriteCentralFileHeader() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privWriteCentralFileHeader(&$p_header) +{ +$v_result=1; + +// TBC +//for(reset($p_header); $key = key($p_header); next($p_header)) { +//} + +// ----- Transform UNIX mtime to DOS format mdate/mtime +$v_date = getdate($p_header['mtime']); +$v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; +$v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + +// ----- Packed data +$v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, + $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], + $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], + $p_header['external'], $p_header['offset']); + +// ----- Write the 42 bytes of the header in the zip file +fputs($this->zip_fd, $v_binary_data, 46); + +// ----- Write the variable fields +if (strlen($p_header['stored_filename']) != 0) +{ + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); +} +if ($p_header['extra_len'] != 0) +{ + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); +} +if ($p_header['comment_len'] != 0) +{ + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : privWriteCentralHeader() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) +{ +$v_result=1; + +// ----- Packed data +$v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, + $p_nb_entries, $p_size, + $p_offset, strlen($p_comment)); + +// ----- Write the 22 bytes of the header in the zip file +fputs($this->zip_fd, $v_binary_data, 22); + +// ----- Write the variable fields +if (strlen($p_comment) != 0) +{ + fputs($this->zip_fd, $p_comment, strlen($p_comment)); +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : privList() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privList(&$p_list) +{ +$v_result=1; + +// ----- Magic quotes trick +$this->privDisableMagicQuotes(); + +// ----- Open the zip file +if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) +{ + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + return PclZip::errorCode(); +} + +// ----- Read the central directory informations +$v_central_dir = array(); +if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) +{ + $this->privSwapBackMagicQuotes(); + return $v_result; +} + +// ----- Go to beginning of Central Dir +@rewind($this->zip_fd); +if (@fseek($this->zip_fd, $v_central_dir['offset'])) +{ + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); +} + +// ----- Read each entry +for ($i=0; $i<$v_central_dir['entries']; $i++) +{ + // ----- Read the file header + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + $this->privSwapBackMagicQuotes(); return $v_result; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFileUsingTempFile() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privExtractFileUsingTempFile(&$p_entry, &$p_options) - { - $v_result=1; - - // ----- Creates a temporary file - $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; - if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { - fclose($v_file); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); - return PclZip::errorCode(); - } + $v_header['index'] = $i; + // ----- Get the only interesting attributes + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); +} - // ----- Write gz file format header - $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); - @fwrite($v_dest_file, $v_binary_data, 10); +// ----- Close the zip file +$this->privCloseFd(); - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = $p_entry['compressed_size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } +// ----- Magic quotes trick +$this->privSwapBackMagicQuotes(); - // ----- Write gz file format footer - $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); - @fwrite($v_dest_file, $v_binary_data, 8); +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Close the temporary file - @fclose($v_dest_file); +// -------------------------------------------------------------------------------- +// Function : privConvertHeader2FileInfo() +// Description : +// This function takes the file informations from the central directory +// entries and extract the interesting parameters that will be given back. +// The resulting file infos are set in the array $p_info +// $p_info['filename'] : Filename with full path. Given by user (add), +// extracted in the filesystem (extract). +// $p_info['stored_filename'] : Stored filename in the archive. +// $p_info['size'] = Size of the file. +// $p_info['compressed_size'] = Compressed size of the file. +// $p_info['mtime'] = Last modification date of the file. +// $p_info['comment'] = Comment associated with the file. +// $p_info['folder'] = true/false : indicates if the entry is a folder or not. +// $p_info['status'] = status of the action on the file. +// $p_info['crc'] = CRC of the file content. +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privConvertHeader2FileInfo($p_header, &$p_info) +{ +$v_result=1; + +// ----- Get the interesting attributes +$v_temp_path = PclZipUtilPathReduction($p_header['filename']); +$p_info['filename'] = $v_temp_path; +$v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); +$p_info['stored_filename'] = $v_temp_path; +$p_info['size'] = $p_header['size']; +$p_info['compressed_size'] = $p_header['compressed_size']; +$p_info['mtime'] = $p_header['mtime']; +$p_info['comment'] = $p_header['comment']; +$p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); +$p_info['index'] = $p_header['index']; +$p_info['status'] = $p_header['status']; +$p_info['crc'] = $p_header['crc']; + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - $p_entry['status'] = "write_error"; - return $v_result; - } +// -------------------------------------------------------------------------------- +// Function : privExtractByRule() +// Description : +// Extract a file or directory depending of rules (by index, by name, ...) +// Parameters : +// $p_file_list : An array where will be placed the properties of each +// extracted file +// $p_path : Path to add while writing the extracted files +// $p_remove_path : Path to remove (from the file memorized path) while writing the +// extracted files. If the path does not match the file path, +// the file is extracted with its memorized path. +// $p_remove_path does not apply to 'list' mode. +// $p_path and $p_remove_path are commulative. +// Return Values : +// 1 on success,0 or less on error (see error code list) +// -------------------------------------------------------------------------------- +function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) +{ +$v_result=1; + +// ----- Magic quotes trick +$this->privDisableMagicQuotes(); + +// ----- Check the path +if (($p_path == "") + || ((substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") + && (substr($p_path,1,2)!=":/"))) + $p_path = "./".$p_path; + +// ----- Reduce the path last (and duplicated) '/' +if (($p_path != "./") && ($p_path != "/")) +{ + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") + { + $p_path = substr($p_path, 0, strlen($p_path)-1); + } +} + +// ----- Look for path to remove format (should end by /) +if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) +{ + $p_remove_path .= '/'; +} +$p_remove_path_size = strlen($p_remove_path); + +// ----- Open the zip file +if (($v_result = $this->privOpenFd('rb')) != 1) +{ + $this->privSwapBackMagicQuotes(); + return $v_result; +} + +// ----- Read the central directory informations +$v_central_dir = array(); +if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) +{ + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; +} + +// ----- Start at beginning of Central Dir +$v_pos_entry = $v_central_dir['offset']; + +// ----- Read each entry +$j_start = 0; +for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) +{ + + // ----- Read next Central dir entry + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - // ----- Open the temporary gz file - if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { - @fclose($v_dest_file); - $p_entry['status'] = "read_error"; - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); - } + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Return + return PclZip::errorCode(); + } - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = $p_entry['size']; - while ($v_size != 0) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($v_src_file, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - @fclose($v_dest_file); - @gzclose($v_src_file); + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - // ----- Delete the temporary file - @unlink($v_gzip_temp_name); - - // ----- Return return $v_result; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFileInOutput() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privExtractFileInOutput(&$p_entry, &$p_options) - { - $v_result=1; - // ----- Read the file header - if (($v_result = $this->privReadFileHeader($v_header)) != 1) { - return $v_result; - } + // ----- Store the index + $v_header['index'] = $i; + // ----- Store the file position + $v_pos_entry = ftell($this->zip_fd); - // ----- Check that the file header is coherent with $p_entry info - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC - } + // ----- Look for the specific extract rules + $v_extract = false; - // ----- Look for pre-extract callback - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + // ----- Look for extract by name rule + if ((isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + + // ----- Look if the directory is in the filename path + if ((strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_extract = true; + } + } + // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_extract = true; + } } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ((isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; } + } + */ - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; - } + // ----- Look for extract by preg rule + else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { - // ----- Trace + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { + // ----- Look for extract by index rule + else if ((isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { + + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) { - // ----- Look for not compressed file - if ($p_entry['compressed_size'] == $p_entry['size']) { + // ----- Look for no rule, which means extract all the archive + else { + $v_extract = true; + } - // ----- Read the file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + // ----- Check compression method + if (($v_extract) + && (($v_header['compression'] != 8) + && ($v_header['compression'] != 0))) { + $v_header['status'] = 'unsupported_compression'; - // ----- Send the file to the output - echo $v_buffer; - unset($v_buffer); - } - else { + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - // ----- Read the compressed file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + $this->privSwapBackMagicQuotes(); - // ----- Decompress the file - $v_file_content = gzinflate($v_buffer); - unset($v_buffer); + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, + "Filename '".$v_header['stored_filename']."' is " + ."compressed by an unsupported compression " + ."method (".$v_header['compression'].") "); - // ----- Send the file to the output - echo $v_file_content; - unset($v_file_content); - } + return PclZip::errorCode(); } - } + } + + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + $v_header['status'] = 'unsupported_encryption'; - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; - } + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - // ----- Look for post-extract callback - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + $this->privSwapBackMagicQuotes(); - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, + "Unsupported encryption for " + ." filename '".$v_header['stored_filename'] + ."'"); - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + return PclZip::errorCode(); + } +} - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; + // ----- Look for real extraction + if (($v_extract) && ($v_header['status'] != 'ok')) { + $v_result = $this->privConvertHeader2FileInfo($v_header, + $p_file_list[$v_nb_extracted++]); + if ($v_result != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; } - } - return $v_result; + $v_extract = false; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFileAsString() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) + + // ----- Look for real extraction + if ($v_extract) { - $v_result=1; - // ----- Read the file header - $v_header = array(); - if (($v_result = $this->privReadFileHeader($v_header)) != 1) + // ----- Go to the file position + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header['offset'])) { - // ----- Return - return $v_result; - } + // ----- Close the zip file + $this->privCloseFd(); + + $this->privSwapBackMagicQuotes(); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - // ----- Check that the file header is coherent with $p_entry info - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC + // ----- Return + return PclZip::errorCode(); } - // ----- Look for pre-extract callback - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + // ----- Look for extraction as string + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + $v_string = ''; - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } - - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; + // ----- Extracting the file + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; } - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; - } + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) { - // ----- Look for not compressed file - // if ($p_entry['compressed_size'] == $p_entry['size']) - if ($p_entry['compression'] == 0) { - - // ----- Reading the file - $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); - } - else { - - // ----- Reading the file - $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - if (($p_string = @gzinflate($v_data)) === FALSE) { - // TBC - } - } - - // ----- Trace - } - else { - // TBC : error : can not extract a folder in a string - } + // ----- Next extracted file + $v_nb_extracted++; + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } } - - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; + // ----- Look for extraction in standard output + elseif ((isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Extracting the file in standard output + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; } - - // ----- Look for post-extract callback - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Swap the content to header - $v_local_header['content'] = $p_string; - $p_string = ''; - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - // ----- Swap back the content to header - $p_string = $v_local_header['content']; - unset($v_local_header['content']); + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; } } + // ----- Look for normal extraction + else { + // ----- Extracting the file + $v_result1 = $this->privExtractFile($v_header, + $p_path, $p_remove_path, + $p_remove_all_path, + $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privReadFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privReadFileHeader(&$p_header) - { - $v_result=1; - - // ----- Read the 4 bytes signature - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = unpack('Vid', $v_binary_data); - - // ----- Check signature - if ($v_data['id'] != 0x04034b50) - { + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + return $v_result; + } - // ----- Return - return PclZip::errorCode(); + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } } + } +} - // ----- Read the first 42 bytes of the header - $v_binary_data = fread($this->zip_fd, 26); - - // ----- Look for invalid block size - if (strlen($v_binary_data) != 26) - { - $p_header['filename'] = ""; - $p_header['status'] = "invalid_header"; - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); +// ----- Close the zip file +$this->privCloseFd(); +$this->privSwapBackMagicQuotes(); - // ----- Return - return PclZip::errorCode(); - } +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Extract the values - $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); +// -------------------------------------------------------------------------------- +// Function : privExtractFile() +// Description : +// Parameters : +// Return Values : +// +// 1 : ... ? +// PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback +// -------------------------------------------------------------------------------- +function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) +{ +$v_result=1; - // ----- Get filename - $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); +// ----- Read the file header +if (($v_result = $this->privReadFileHeader($v_header)) != 1) +{ + // ----- Return + return $v_result; +} - // ----- Get extra_fields - if ($v_data['extra_len'] != 0) { - $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); - } - else { - $p_header['extra'] = ''; - } - // ----- Extract properties - $p_header['version_extracted'] = $v_data['version']; - $p_header['compression'] = $v_data['compression']; - $p_header['size'] = $v_data['size']; - $p_header['compressed_size'] = $v_data['compressed_size']; - $p_header['crc'] = $v_data['crc']; - $p_header['flag'] = $v_data['flag']; - $p_header['filename_len'] = $v_data['filename_len']; - - // ----- Recuperate date in UNIX format - $p_header['mdate'] = $v_data['mdate']; - $p_header['mtime'] = $v_data['mtime']; - if ($p_header['mdate'] && $p_header['mtime']) - { - // ----- Extract time - $v_hour = ($p_header['mtime'] & 0xF800) >> 11; - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; - $v_seconde = ($p_header['mtime'] & 0x001F)*2; +// ----- Check that the file header is coherent with $p_entry info +if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC +} - // ----- Extract date - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; - $v_month = ($p_header['mdate'] & 0x01E0) >> 5; - $v_day = $p_header['mdate'] & 0x001F; +// ----- Look for all path to remove +if ($p_remove_all_path == true) { + // ----- Look for folder entry that not need to be extracted + if (($p_entry['external']&0x00000010)==0x00000010) { - // ----- Get UNIX date format - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + $p_entry['status'] = "filtered"; - } - else - { - $p_header['mtime'] = time(); + return $v_result; } - // TBC - //for(reset($v_data); $key = key($v_data); next($v_data)) { - //} + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); +} - // ----- Set the stored filename - $p_header['stored_filename'] = $p_header['filename']; +// ----- Look for path to remove +else if ($p_remove_path != "") +{ + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) + { - // ----- Set the status field - $p_header['status'] = "ok"; + // ----- Change the file status + $p_entry['status'] = "filtered"; // ----- Return return $v_result; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privReadCentralFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privReadCentralFileHeader(&$p_header) - { - $v_result=1; - // ----- Read the 4 bytes signature - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = unpack('Vid', $v_binary_data); + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + { - // ----- Check signature - if ($v_data['id'] != 0x02014b50) - { + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + } +} - // ----- Return - return PclZip::errorCode(); - } +// ----- Add the path +if ($p_path != '') { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; +} - // ----- Read the first 42 bytes of the header - $v_binary_data = fread($this->zip_fd, 42); +// ----- Check a base_dir_restriction +if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { + $v_inclusion + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], + $p_entry['filename']); + if ($v_inclusion == 0) { - // ----- Look for invalid block size - if (strlen($v_binary_data) != 42) - { - $p_header['filename'] = ""; - $p_header['status'] = "invalid_header"; + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, + "Filename '".$p_entry['filename']."' is " + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + return PclZip::errorCode(); + } +} - // ----- Return - return PclZip::errorCode(); - } +// ----- Look for pre-extract callback +if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - // ----- Extract the values - $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - // ----- Get filename - if ($p_header['filename_len'] != 0) - $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); - else - $p_header['filename'] = ''; + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } - // ----- Get extra - if ($p_header['extra_len'] != 0) - $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); - else - $p_header['extra'] = ''; + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; +} - // ----- Get comment - if ($p_header['comment_len'] != 0) - $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); - else - $p_header['comment'] = ''; - // ----- Extract properties +// ----- Look if extraction should be done +if ($p_entry['status'] == 'ok') { - // ----- Recuperate date in UNIX format - //if ($p_header['mdate'] && $p_header['mtime']) - // TBC : bug : this was ignoring time with 0/0/0 - if (1) - { - // ----- Extract time - $v_hour = ($p_header['mtime'] & 0xF800) >> 11; - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; - $v_seconde = ($p_header['mtime'] & 0x001F)*2; +// ----- Look for specific actions while the file exist +if (file_exists($p_entry['filename'])) +{ - // ----- Extract date - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; - $v_month = ($p_header['mdate'] & 0x01E0) >> 5; - $v_day = $p_header['mdate'] & 0x001F; + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) + { - // ----- Get UNIX date format - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - } - else - { - $p_header['mtime'] = time(); - } + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, + "Filename '".$p_entry['filename']."' is " + ."already used by an existing directory"); - // ----- Set the stored filename - $p_header['stored_filename'] = $p_header['filename']; + return PclZip::errorCode(); + } + } + // ----- Look if file is write protected + else if (!is_writeable($p_entry['filename'])) + { - // ----- Set default status to ok - $p_header['status'] = 'ok'; + // ----- Change the file status + $p_entry['status'] = "write_protected"; - // ----- Look if it is a directory - if (substr($p_header['filename'], -1) == '/') { - //$p_header['external'] = 0x41FF0010; - $p_header['external'] = 0x00000010; - } + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Filename '".$p_entry['filename']."' exists " + ."and is write protected"); - // ----- Return - return $v_result; + return PclZip::errorCode(); + } } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCheckFileHeaders() - // Description : - // Parameters : - // Return Values : - // 1 on success, - // 0 on error; - // -------------------------------------------------------------------------------- - function privCheckFileHeaders(&$p_local_header, &$p_central_header) + + // ----- Look if the extracted file is older + else if (filemtime($p_entry['filename']) > $p_entry['mtime']) { - $v_result=1; + // ----- Change the file status + if ((isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + } + else { + $p_entry['status'] = "newer_exist"; - // ----- Check the static values - // TBC - if ($p_local_header['filename'] != $p_central_header['filename']) { - } - if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { - } - if ($p_local_header['flag'] != $p_central_header['flag']) { - } - if ($p_local_header['compression'] != $p_central_header['compression']) { - } - if ($p_local_header['mtime'] != $p_central_header['mtime']) { - } - if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { - } - - // ----- Look for flag bit 3 - if (($p_local_header['flag'] & 8) == 8) { - $p_local_header['size'] = $p_central_header['size']; - $p_local_header['compressed_size'] = $p_central_header['compressed_size']; - $p_local_header['crc'] = $p_central_header['crc']; - } + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - // ----- Return - return $v_result; + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Newer version of '".$p_entry['filename']."' exists " + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + + return PclZip::errorCode(); + } + } } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privReadEndCentralDir() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privReadEndCentralDir(&$p_central_dir) - { - $v_result=1; + else { + } +} - // ----- Go to the end of the zip file - $v_size = filesize($this->zipname); - @fseek($this->zip_fd, $v_size); - if (@ftell($this->zip_fd) != $v_size) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); +// ----- Check the directory availability and create it if necessary +else { + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + else if (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); + + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; // ----- Return - return PclZip::errorCode(); + //return $v_result; + $v_result = 1; } + } +} + +// ----- Look if extraction should be done +if ($p_entry['status'] == 'ok') { - // ----- First try : look if this is an archive with no commentaries (most of the time) - // in this case the end of central dir is at 22 bytes of the file end - $v_found = 0; - if ($v_size > 26) { - @fseek($this->zip_fd, $v_size-22); - if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file + if ($p_entry['compression'] == 0) { + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Change the file status + $p_entry['status'] = "write_error"; // ----- Return - return PclZip::errorCode(); + return $v_result; } - // ----- Read for bytes - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = @unpack('Vid', $v_binary_data); - // ----- Check signature - if ($v_data['id'] == 0x06054b50) { - $v_found = 1; + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + /* Try to speed up the code + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + */ + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; } - $v_pos = ftell($this->zip_fd); - } + // ----- Closing the destination file + fclose($v_dest_file); - // ----- Go back to the maximum possible size of the Central Dir End Record - if (!$v_found) { - $v_maximum_size = 65557; // 0xFFFF + 22; - if ($v_maximum_size > $v_size) - $v_maximum_size = $v_size; - @fseek($this->zip_fd, $v_size-$v_maximum_size); - if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + - // ----- Return + } + else { + // ----- TBC + // Need to be finished + if (($p_entry['flag'] & 1) == 1) { + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); return PclZip::errorCode(); } - // ----- Read byte per byte in order to find the signature - $v_pos = ftell($this->zip_fd); - $v_bytes = 0x00000000; - while ($v_pos < $v_size) - { - // ----- Read a byte - $v_byte = @fread($this->zip_fd, 1); - - // ----- Add the byte - //$v_bytes = ($v_bytes << 8) | Ord($v_byte); - // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number - // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. - $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); - - // ----- Compare the bytes - if ($v_bytes == 0x504b0506) - { - $v_pos++; - break; - } - $v_pos++; + // ----- Look for using temporary file to unzip + if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])))) { + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } } + + // ----- Look for extract in memory + else { - // ----- Look if not found end of central dir - if ($v_pos == $v_size) - { + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = @gzinflate($v_buffer); + unset($v_buffer); + if ($v_file_content === false) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); + // ----- Change the file status + // TBC + $p_entry['status'] = "error"; + + return $v_result; + } + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - // ----- Return - return PclZip::errorCode(); + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + } + + // ----- Change the file mtime + @touch($p_entry['filename'], $p_entry['mtime']); } - // ----- Read the first 18 bytes of the header - $v_binary_data = fread($this->zip_fd, 18); + // ----- Look for chmod option + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { - // ----- Look for invalid block size - if (strlen($v_binary_data) != 18) - { + // ----- Change the mode of the file + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + } - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + } +} - // ----- Return - return PclZip::errorCode(); - } + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } - // ----- Extract the values - $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); +// ----- Look for post-extract callback +elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - // ----- Check the global size - if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - // ----- Removed in release 2.2 see readme file - // The check of the file size is a little too strict. - // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. - // While decrypted, zip has training 0 bytes - if (0) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, - 'The central dir is not at the end of the archive.' - .' Some trailing bytes exists after the archive.'); + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - // ----- Return - return PclZip::errorCode(); - } - } + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } +} - // ----- Get comment - if ($v_data['comment_size'] != 0) { - $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); - } - else - $p_central_dir['comment'] = ''; +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : privExtractFileUsingTempFile() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privExtractFileUsingTempFile(&$p_entry, &$p_options) +{ +$v_result=1; + +// ----- Creates a temporary file +$v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; +if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); +} + + +// ----- Write gz file format header +$v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); +@fwrite($v_dest_file, $v_binary_data, 10); + +// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks +$v_size = $p_entry['compressed_size']; +while ($v_size != 0) +{ + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; +} + +// ----- Write gz file format footer +$v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); +@fwrite($v_dest_file, $v_binary_data, 8); + +// ----- Close the temporary file +@fclose($v_dest_file); + +// ----- Opening destination file +if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + $p_entry['status'] = "write_error"; + return $v_result; +} + +// ----- Open the temporary gz file +if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { + @fclose($v_dest_file); + $p_entry['status'] = "read_error"; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); +} + + +// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks +$v_size = $p_entry['size']; +while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($v_src_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; +} +@fclose($v_dest_file); +@gzclose($v_src_file); + +// ----- Delete the temporary file +@unlink($v_gzip_temp_name); + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : privExtractFileInOutput() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privExtractFileInOutput(&$p_entry, &$p_options) +{ +$v_result=1; + +// ----- Read the file header +if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + return $v_result; +} + + +// ----- Check that the file header is coherent with $p_entry info +if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC +} + +// ----- Look for pre-extract callback +if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; +} + +// ----- Trace - $p_central_dir['entries'] = $v_data['entries']; - $p_central_dir['disk_entries'] = $v_data['disk_entries']; - $p_central_dir['offset'] = $v_data['offset']; - $p_central_dir['size'] = $v_data['size']; - $p_central_dir['disk'] = $v_data['disk']; - $p_central_dir['disk_start'] = $v_data['disk_start']; +// ----- Look if extraction should be done +if ($p_entry['status'] == 'ok') { - // TBC - //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { - //} + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) { - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDeleteByRule() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privDeleteByRule(&$p_result_list, &$p_options) - { - $v_result=1; - $v_list_detail = array(); + // ----- Read the file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - // ----- Open the zip file - if (($v_result=$this->privOpenFd('rb')) != 1) - { - // ----- Return - return $v_result; + // ----- Send the file to the output + echo $v_buffer; + unset($v_buffer); } + else { - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); - return $v_result; + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); + + // ----- Send the file to the output + echo $v_file_content; + unset($v_file_content); } + } +} - // ----- Go to beginning of File - @rewind($this->zip_fd); +// ----- Change abort status +if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; +} - // ----- Scan all the files - // ----- Start at beginning of Central Dir - $v_pos_entry = $v_central_dir['offset']; - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_pos_entry)) - { - // ----- Close the zip file - $this->privCloseFd(); +// ----- Look for post-extract callback +elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - // ----- Return - return PclZip::errorCode(); - } + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - // ----- Read each entry - $v_header_list = array(); - $j_start = 0; - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) - { + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } +} - // ----- Read the file header - $v_header_list[$v_nb_extracted] = array(); - if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); +return $v_result; +} +// -------------------------------------------------------------------------------- - return $v_result; - } +// -------------------------------------------------------------------------------- +// Function : privExtractFileAsString() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) +{ +$v_result=1; +// ----- Read the file header +$v_header = array(); +if (($v_result = $this->privReadFileHeader($v_header)) != 1) +{ + // ----- Return + return $v_result; +} - // ----- Store the index - $v_header_list[$v_nb_extracted]['index'] = $i; - // ----- Look for the specific extract rules - $v_found = false; +// ----- Check that the file header is coherent with $p_entry info +if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC +} - // ----- Look for extract by name rule - if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { +// ----- Look for pre-extract callback +if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - // ----- Look if the filename is in the list - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - // ----- Look for a directory - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } - // ----- Look if the directory is in the filename path - if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) - && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_found = true; - } - elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ - && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_found = true; - } - } - // ----- Look for a filename - elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { - $v_found = true; - } - } - } + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; +} - // ----- Look for extract by ereg rule - // ereg() is deprecated with PHP 5.3 - /* - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { - $v_found = true; - } - } - */ +// ----- Look if extraction should be done +if ($p_entry['status'] == 'ok') { - // ----- Look for extract by preg rule - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file +// if ($p_entry['compressed_size'] == $p_entry['size']) + if ($p_entry['compression'] == 0) { - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { - $v_found = true; - } + // ----- Reading the file + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + } + else { + + // ----- Reading the file + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + if (($p_string = @gzinflate($v_data)) === false) { + // TBC } + } - // ----- Look for extract by index rule - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + // ----- Trace + } + else { + // TBC : error : can not extract a folder in a string + } + +} - // ----- Look if the index is in the list - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_found = true; - } - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; - } +// ----- Look for post-extract callback +elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; - } - } - } - else { - $v_found = true; - } + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Swap the content to header + $v_local_header['content'] = $p_string; + $p_string = ''; - // ----- Look for deletion - if ($v_found) - { - unset($v_header_list[$v_nb_extracted]); - } - else - { - $v_nb_extracted++; - } - } + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - // ----- Look if something need to be deleted - if ($v_nb_extracted > 0) { + // ----- Swap back the content to header + $p_string = $v_local_header['content']; + unset($v_local_header['content']); - // ----- Creates a temporay file - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } +} - // ----- Creates a temporary zip archive - $v_temp_zip = new PclZip($v_zip_temp_name); +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Open the temporary zip file in write mode - if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { - $this->privCloseFd(); +// -------------------------------------------------------------------------------- +// Function : privReadFileHeader() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privReadFileHeader(&$p_header) +{ +$v_result=1; + +// ----- Read the 4 bytes signature +$v_binary_data = @fread($this->zip_fd, 4); +$v_data = unpack('Vid', $v_binary_data); + +// ----- Check signature +if ($v_data['id'] != 0x04034b50) +{ + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); +} + +// ----- Read the first 42 bytes of the header +$v_binary_data = fread($this->zip_fd, 26); + +// ----- Look for invalid block size +if (strlen($v_binary_data) != 26) +{ + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); +} + +// ----- Extract the values +$v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + +// ----- Get filename +$p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); + +// ----- Get extra_fields +if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); +} +else { + $p_header['extra'] = ''; +} + +// ----- Extract properties +$p_header['version_extracted'] = $v_data['version']; +$p_header['compression'] = $v_data['compression']; +$p_header['size'] = $v_data['size']; +$p_header['compressed_size'] = $v_data['compressed_size']; +$p_header['crc'] = $v_data['crc']; +$p_header['flag'] = $v_data['flag']; +$p_header['filename_len'] = $v_data['filename_len']; + +// ----- Recuperate date in UNIX format +$p_header['mdate'] = $v_data['mdate']; +$p_header['mtime'] = $v_data['mtime']; +if ($p_header['mdate'] && $p_header['mtime']) +{ + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + +} +else +{ + $p_header['mtime'] = time(); +} + +// TBC +//for(reset($v_data); $key = key($v_data); next($v_data)) { +//} + +// ----- Set the stored filename +$p_header['stored_filename'] = $p_header['filename']; + +// ----- Set the status field +$p_header['status'] = "ok"; + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Return - return $v_result; - } +// -------------------------------------------------------------------------------- +// Function : privReadCentralFileHeader() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privReadCentralFileHeader(&$p_header) +{ +$v_result=1; + +// ----- Read the 4 bytes signature +$v_binary_data = @fread($this->zip_fd, 4); +$v_data = unpack('Vid', $v_binary_data); + +// ----- Check signature +if ($v_data['id'] != 0x02014b50) +{ + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); +} + +// ----- Read the first 42 bytes of the header +$v_binary_data = fread($this->zip_fd, 42); + +// ----- Look for invalid block size +if (strlen($v_binary_data) != 42) +{ + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); +} + +// ----- Extract the values +$p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); + +// ----- Get filename +if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); +else + $p_header['filename'] = ''; + +// ----- Get extra +if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); +else + $p_header['extra'] = ''; + +// ----- Get comment +if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); +else + $p_header['comment'] = ''; + +// ----- Extract properties + +// ----- Recuperate date in UNIX format +//if ($p_header['mdate'] && $p_header['mtime']) +// TBC : bug : this was ignoring time with 0/0/0 +if (1) +{ + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + +} +else +{ + $p_header['mtime'] = time(); +} + +// ----- Set the stored filename +$p_header['stored_filename'] = $p_header['filename']; + +// ----- Set default status to ok +$p_header['status'] = 'ok'; + +// ----- Look if it is a directory +if (substr($p_header['filename'], -1) == '/') { + //$p_header['external'] = 0x41FF0010; + $p_header['external'] = 0x00000010; +} + + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Look which file need to be kept - for ($i=0; $i<sizeof($v_header_list); $i++) { +// -------------------------------------------------------------------------------- +// Function : privCheckFileHeaders() +// Description : +// Parameters : +// Return Values : +// 1 on success, +// 0 on error; +// -------------------------------------------------------------------------------- +function privCheckFileHeaders(&$p_local_header, &$p_central_header) +{ +$v_result=1; - // ----- Calculate the position of the header - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + } - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { + $p_local_header['size'] = $p_central_header['size']; + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + $p_local_header['crc'] = $p_central_header['crc']; + } - // ----- Return - return PclZip::errorCode(); - } +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Read the file header - $v_local_header = array(); - if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); +// -------------------------------------------------------------------------------- +// Function : privReadEndCentralDir() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privReadEndCentralDir(&$p_central_dir) +{ +$v_result=1; + +// ----- Go to the end of the zip file +$v_size = filesize($this->zipname); +@fseek($this->zip_fd, $v_size); +if (@ftell($this->zip_fd) != $v_size) +{ + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); +} + +// ----- First try : look if this is an archive with no commentaries (most of the time) +// in this case the end of central dir is at 22 bytes of the file end +$v_found = 0; +if ($v_size > 26) { + @fseek($this->zip_fd, $v_size-22); + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); - // ----- Return - return $v_result; - } - - // ----- Check that local file header is same as central file header - if ($this->privCheckFileHeaders($v_local_header, - $v_header_list[$i]) != 1) { - // TBC - } - unset($v_local_header); + // ----- Return + return PclZip::errorCode(); + } - // ----- Write the file header - if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Read for bytes + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = @unpack('Vid', $v_binary_data); - // ----- Return - return $v_result; - } + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } - // ----- Read/write the data block - if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + $v_pos = ftell($this->zip_fd); +} - // ----- Return - return $v_result; - } - } +// ----- Go back to the maximum possible size of the Central Dir End Record +if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); - // ----- Store the offset of the central dir - $v_offset = @ftell($v_temp_zip->zip_fd); + // ----- Return + return PclZip::errorCode(); + } - // ----- Re-Create the Central Dir files header - for ($i=0; $i<sizeof($v_header_list); $i++) { - // ----- Create the file header - if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) + { + // ----- Read a byte + $v_byte = @fread($this->zip_fd, 1); - // ----- Return - return $v_result; - } + // ----- Add the byte + //$v_bytes = ($v_bytes << 8) | Ord($v_byte); + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. + $v_bytes = (($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); - // ----- Transform the header to a 'usable' info - $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) + { + $v_pos++; + break; + } + $v_pos++; + } - // ----- Zip file comment - $v_comment = ''; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } + // ----- Look if not found end of central dir + if ($v_pos == $v_size) + { - // ----- Calculate the size of the central header - $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); - // ----- Create the central dir footer - if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { - // ----- Reset the file list - unset($v_header_list); - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Return + return PclZip::errorCode(); + } +} - // ----- Return - return $v_result; - } +// ----- Read the first 18 bytes of the header +$v_binary_data = fread($this->zip_fd, 18); - // ----- Close - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); +// ----- Look for invalid block size +if (strlen($v_binary_data) != 18) +{ - // ----- Delete the zip file - // TBC : I should test the result ... - @unlink($this->zipname); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); - // ----- Rename the temporary file - // TBC : I should test the result ... - //@rename($v_zip_temp_name, $this->zipname); - PclZipUtilRename($v_zip_temp_name, $this->zipname); - - // ----- Destroy the temporary archive - unset($v_temp_zip); - } - - // ----- Remove every files : reset the file - else if ($v_central_dir['entries'] != 0) { - $this->privCloseFd(); + // ----- Return + return PclZip::errorCode(); +} - if (($v_result = $this->privOpenFd('wb')) != 1) { - return $v_result; - } +// ----- Extract the values +$v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); - if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { - return $v_result; - } +// ----- Check the global size +if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { - $this->privCloseFd(); - } + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, + 'The central dir is not at the end of the archive.' + .' Some trailing bytes exists after the archive.'); - // ----- Return - return $v_result; + // ----- Return + return PclZip::errorCode(); } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDirCheck() - // Description : - // Check if a directory exists, if not it creates it and all the parents directory - // which may be useful. - // Parameters : - // $p_dir : Directory path to check. - // Return Values : - // 1 : OK - // -1 : Unable to create directory - // -------------------------------------------------------------------------------- - function privDirCheck($p_dir, $p_is_dir=false) +} + +// ----- Get comment +if ($v_data['comment_size'] != 0) { + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); +} +else + $p_central_dir['comment'] = ''; + +$p_central_dir['entries'] = $v_data['entries']; +$p_central_dir['disk_entries'] = $v_data['disk_entries']; +$p_central_dir['offset'] = $v_data['offset']; +$p_central_dir['size'] = $v_data['size']; +$p_central_dir['disk'] = $v_data['disk']; +$p_central_dir['disk_start'] = $v_data['disk_start']; + +// TBC +//for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { +//} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : privDeleteByRule() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privDeleteByRule(&$p_result_list, &$p_options) +{ +$v_result=1; +$v_list_detail = array(); + +// ----- Open the zip file +if (($v_result=$this->privOpenFd('rb')) != 1) +{ + // ----- Return + return $v_result; +} + +// ----- Read the central directory informations +$v_central_dir = array(); +if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) +{ + $this->privCloseFd(); + return $v_result; +} + +// ----- Go to beginning of File +@rewind($this->zip_fd); + +// ----- Scan all the files +// ----- Start at beginning of Central Dir +$v_pos_entry = $v_central_dir['offset']; +@rewind($this->zip_fd); +if (@fseek($this->zip_fd, $v_pos_entry)) +{ + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); +} + +// ----- Read each entry +$v_header_list = array(); +$j_start = 0; +for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) +{ + + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) { - $v_result = 1; + // ----- Close the zip file + $this->privCloseFd(); + return $v_result; + } - // ----- Remove the final '/' - if (($p_is_dir) && (substr($p_dir, -1)=='/')) - { - $p_dir = substr($p_dir, 0, strlen($p_dir)-1); - } - // ----- Check the directory availability - if ((is_dir($p_dir)) || ($p_dir == "")) - { - return 1; - } + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; - // ----- Extract parent directory - $p_parent_dir = dirname($p_dir); + // ----- Look for the specific extract rules + $v_found = false; - // ----- Just a check - if ($p_parent_dir != $p_dir) - { - // ----- Look for parent directory - if ($p_parent_dir != "") - { - if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) - { - return $v_result; - } - } - } + // ----- Look for extract by name rule + if ((isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { - // ----- Create the directory - if (!@mkdir($p_dir, 0777)) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { - // ----- Return - return PclZip::errorCode(); - } + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { - // ----- Return - return $v_result; + // ----- Look if the directory is in the filename path + if ((strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + elseif ((($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_found = true; + } + } } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privMerge() - // Description : - // If $p_archive_to_add does not exist, the function exit with a success result. - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privMerge(&$p_archive_to_add) - { - $v_result=1; - // ----- Look if the archive_to_add exists - if (!is_file($p_archive_to_add->zipname)) - { + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ((isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - // ----- Nothing to merge, so merge is a success - $v_result = 1; + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + */ - // ----- Return - return $v_result; - } + // ----- Look for extract by preg rule + else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { - // ----- Look if the archive exists - if (!is_file($this->zipname)) - { + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } - // ----- Do a duplicate - $v_result = $this->privDuplicate($p_archive_to_add->zipname); + // ----- Look for extract by index rule + else if ((isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - // ----- Return - return $v_result; - } + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { - // ----- Open the zip file - if (($v_result=$this->privOpenFd('rb')) != 1) - { - // ----- Return - return $v_result; - } + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); - return $v_result; - } + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + else { + $v_found = true; + } - // ----- Go to beginning of File - @rewind($this->zip_fd); + // ----- Look for deletion + if ($v_found) + { + unset($v_header_list[$v_nb_extracted]); + } + else + { + $v_nb_extracted++; + } +} - // ----- Open the archive_to_add file - if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) - { - $this->privCloseFd(); +// ----- Look if something need to be deleted +if ($v_nb_extracted > 0) { - // ----- Return - return $v_result; - } + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - // ----- Read the central directory informations - $v_central_dir_to_add = array(); - if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); + // ----- Creates a temporary zip archive + $v_temp_zip = new PclZip($v_zip_temp_name); - return $v_result; + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { + $this->privCloseFd(); + + // ----- Return + return $v_result; } - // ----- Go to beginning of File - @rewind($p_archive_to_add->zip_fd); + // ----- Look which file need to be kept + for ($i=0; $i<sizeof($v_header_list); $i++) { - // ----- Creates a temporay file - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + // ----- Calculate the position of the header + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); - // ----- Open the temporary file in write mode - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_local_header = array(); + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + // ----- Return + return $v_result; + } + + // ----- Check that local file header is same as central file header + if ($this->privCheckFileHeaders($v_local_header, + $v_header_list[$i]) != 1) { + // TBC + } + unset($v_local_header); - // ----- Return - return PclZip::errorCode(); - } + // ----- Write the file header + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); - // ----- Copy the files from the archive to the temporary file - // TBC : Here I should better append the file and go back to erase the central dir - $v_size = $v_central_dir['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Return + return $v_result; + } - // ----- Copy the files from the archive_to_add into the temporary file - $v_size = $v_central_dir_to_add['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; + // ----- Read/write the data block + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } } // ----- Store the offset of the central dir - $v_offset = @ftell($v_zip_temp_fd); + $v_offset = @ftell($v_temp_zip->zip_fd); - // ----- Copy the block of file headers from the old archive - $v_size = $v_central_dir['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Re-Create the Central Dir files header + for ($i=0; $i<sizeof($v_header_list); $i++) { + // ----- Create the file header + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); - // ----- Copy the block of file headers from the archive_to_add - $v_size = $v_central_dir_to_add['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; + // ----- Return + return $v_result; + } + + // ----- Transform the header to a 'usable' info + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); } - // ----- Merge the file comments - $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; - // ----- Calculate the size of the (new) central header - $v_size = @ftell($v_zip_temp_fd)-$v_offset; + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } - // ----- Swap the file descriptor - // Here is a trick : I swap the temporary fd with the zip fd, in order to use - // the following methods on the temporary fil and not the real archive fd - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; // ----- Create the central dir footer - if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); - @fclose($v_zip_temp_fd); - $this->zip_fd = null; - - // ----- Reset the file list - unset($v_header_list); + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); - // ----- Return - return $v_result; + // ----- Return + return $v_result; } - // ----- Swap back the file descriptor - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - // ----- Close + $v_temp_zip->privCloseFd(); $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); - - // ----- Close the temporary file - @fclose($v_zip_temp_fd); // ----- Delete the zip file // TBC : I should test the result ... @@ -5218,474 +4797,738 @@ function privMerge(&$p_archive_to_add) //@rename($v_zip_temp_name, $this->zipname); PclZipUtilRename($v_zip_temp_name, $this->zipname); - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDuplicate() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privDuplicate($p_archive_filename) - { - $v_result=1; - - // ----- Look if the $p_archive_filename exists - if (!is_file($p_archive_filename)) - { + // ----- Destroy the temporary archive + unset($v_temp_zip); +} - // ----- Nothing to duplicate, so duplicate is a success. - $v_result = 1; +// ----- Remove every files : reset the file +else if ($v_central_dir['entries'] != 0) { + $this->privCloseFd(); - // ----- Return + if (($v_result = $this->privOpenFd('wb')) != 1) { return $v_result; } - // ----- Open the zip file - if (($v_result=$this->privOpenFd('wb')) != 1) - { - // ----- Return + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { return $v_result; } - // ----- Open the temporary file in write mode - if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) - { - $this->privCloseFd(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Copy the files from the archive to the temporary file - // TBC : Here I should better append the file and go back to erase the central dir - $v_size = filesize($p_archive_filename); - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($v_zip_temp_fd, $v_read_size); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Close $this->privCloseFd(); +} - // ----- Close the temporary file - @fclose($v_zip_temp_fd); +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privErrorLog() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privErrorLog($p_error_code=0, $p_error_string='') - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - PclError($p_error_code, $p_error_string); - } - else { - $this->error_code = $p_error_code; - $this->error_string = $p_error_string; - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privErrorReset() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privErrorReset() +// -------------------------------------------------------------------------------- +// Function : privDirCheck() +// Description : +// Check if a directory exists, if not it creates it and all the parents directory +// which may be useful. +// Parameters : +// $p_dir : Directory path to check. +// Return Values : +// 1 : OK +// -1 : Unable to create directory +// -------------------------------------------------------------------------------- +function privDirCheck($p_dir, $p_is_dir=false) +{ +$v_result = 1; + + +// ----- Remove the final '/' +if (($p_is_dir) && (substr($p_dir, -1)=='/')) +{ + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); +} + +// ----- Check the directory availability +if ((is_dir($p_dir)) || ($p_dir == "")) +{ + return 1; +} + +// ----- Extract parent directory +$p_parent_dir = dirname($p_dir); + +// ----- Just a check +if ($p_parent_dir != $p_dir) +{ + // ----- Look for parent directory + if ($p_parent_dir != "") { - if (PCLZIP_ERROR_EXTERNAL == 1) { - PclErrorReset(); - } - else { - $this->error_code = 0; - $this->error_string = ''; + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) + { + return $v_result; } } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDisableMagicQuotes() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privDisableMagicQuotes() - { - $v_result=1; +} - // ----- Look if function exists - if ( (!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { - return $v_result; - } +// ----- Create the directory +if (!@mkdir($p_dir, 0777)) +{ + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); - // ----- Look if already done - if ($this->magic_quotes_status != -1) { - return $v_result; - } + // ----- Return + return PclZip::errorCode(); +} - // ----- Get and memorize the magic_quote value - $this->magic_quotes_status = @get_magic_quotes_runtime(); +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Disable magic_quotes - if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime(0); - } +// -------------------------------------------------------------------------------- +// Function : privMerge() +// Description : +// If $p_archive_to_add does not exist, the function exit with a success result. +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privMerge(&$p_archive_to_add) +{ +$v_result=1; + +// ----- Look if the archive_to_add exists +if (!is_file($p_archive_to_add->zipname)) +{ + + // ----- Nothing to merge, so merge is a success + $v_result = 1; + + // ----- Return + return $v_result; +} + +// ----- Look if the archive exists +if (!is_file($this->zipname)) +{ + + // ----- Do a duplicate + $v_result = $this->privDuplicate($p_archive_to_add->zipname); + + // ----- Return + return $v_result; +} + +// ----- Open the zip file +if (($v_result=$this->privOpenFd('rb')) != 1) +{ + // ----- Return + return $v_result; +} + +// ----- Read the central directory informations +$v_central_dir = array(); +if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) +{ + $this->privCloseFd(); + return $v_result; +} + +// ----- Go to beginning of File +@rewind($this->zip_fd); + +// ----- Open the archive_to_add file +if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) +{ + $this->privCloseFd(); + + // ----- Return + return $v_result; +} + +// ----- Read the central directory informations +$v_central_dir_to_add = array(); +if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) +{ + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + return $v_result; +} + +// ----- Go to beginning of File +@rewind($p_archive_to_add->zip_fd); + +// ----- Creates a temporay file +$v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + +// ----- Open the temporary file in write mode +if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) +{ + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); +} + +// ----- Copy the files from the archive to the temporary file +// TBC : Here I should better append the file and go back to erase the central dir +$v_size = $v_central_dir['offset']; +while ($v_size != 0) +{ + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; +} + +// ----- Copy the files from the archive_to_add into the temporary file +$v_size = $v_central_dir_to_add['offset']; +while ($v_size != 0) +{ + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; +} + +// ----- Store the offset of the central dir +$v_offset = @ftell($v_zip_temp_fd); + +// ----- Copy the block of file headers from the old archive +$v_size = $v_central_dir['size']; +while ($v_size != 0) +{ + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; +} + +// ----- Copy the block of file headers from the archive_to_add +$v_size = $v_central_dir_to_add['size']; +while ($v_size != 0) +{ + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; +} + +// ----- Merge the file comments +$v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; + +// ----- Calculate the size of the (new) central header +$v_size = @ftell($v_zip_temp_fd)-$v_offset; + +// ----- Swap the file descriptor +// Here is a trick : I swap the temporary fd with the zip fd, in order to use +// the following methods on the temporary fil and not the real archive fd +$v_swap = $this->zip_fd; +$this->zip_fd = $v_zip_temp_fd; +$v_zip_temp_fd = $v_swap; + +// ----- Create the central dir footer +if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) +{ + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + @fclose($v_zip_temp_fd); + $this->zip_fd = null; + + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; +} + +// ----- Swap back the file descriptor +$v_swap = $this->zip_fd; +$this->zip_fd = $v_zip_temp_fd; +$v_zip_temp_fd = $v_swap; + +// ----- Close +$this->privCloseFd(); +$p_archive_to_add->privCloseFd(); + +// ----- Close the temporary file +@fclose($v_zip_temp_fd); + +// ----- Delete the zip file +// TBC : I should test the result ... +@unlink($this->zipname); + +// ----- Rename the temporary file +// TBC : I should test the result ... +//@rename($v_zip_temp_name, $this->zipname); +PclZipUtilRename($v_zip_temp_name, $this->zipname); + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privSwapBackMagicQuotes() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privSwapBackMagicQuotes() - { - $v_result=1; +// -------------------------------------------------------------------------------- +// Function : privDuplicate() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privDuplicate($p_archive_filename) +{ +$v_result=1; + +// ----- Look if the $p_archive_filename exists +if (!is_file($p_archive_filename)) +{ + + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; + + // ----- Return + return $v_result; +} + +// ----- Open the zip file +if (($v_result=$this->privOpenFd('wb')) != 1) +{ + // ----- Return + return $v_result; +} + +// ----- Open the temporary file in write mode +if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) +{ + $this->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); +} + +// ----- Copy the files from the archive to the temporary file +// TBC : Here I should better append the file and go back to erase the central dir +$v_size = filesize($p_archive_filename); +while ($v_size != 0) +{ + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; +} + +// ----- Close +$this->privCloseFd(); + +// ----- Close the temporary file +@fclose($v_zip_temp_fd); + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Look if function exists - if ( (!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { - return $v_result; - } +// -------------------------------------------------------------------------------- +// Function : privErrorLog() +// Description : +// Parameters : +// -------------------------------------------------------------------------------- +function privErrorLog($p_error_code=0, $p_error_string='') +{ +if (PCLZIP_ERROR_EXTERNAL == 1) { + PclError($p_error_code, $p_error_string); +} +else { + $this->error_code = $p_error_code; + $this->error_string = $p_error_string; +} +} +// -------------------------------------------------------------------------------- - // ----- Look if something to do - if ($this->magic_quotes_status != -1) { - return $v_result; - } +// -------------------------------------------------------------------------------- +// Function : privErrorReset() +// Description : +// Parameters : +// -------------------------------------------------------------------------------- +function privErrorReset() +{ +if (PCLZIP_ERROR_EXTERNAL == 1) { + PclErrorReset(); +} +else { + $this->error_code = 0; + $this->error_string = ''; +} +} +// -------------------------------------------------------------------------------- - // ----- Swap back magic_quotes - if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime($this->magic_quotes_status); - } +// -------------------------------------------------------------------------------- +// Function : privDisableMagicQuotes() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privDisableMagicQuotes() +{ +$v_result=1; + +// ----- Look if function exists +if ((!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; +} + +// ----- Look if already done +if ($this->magic_quotes_status != -1) { + return $v_result; +} + +// ----- Get and memorize the magic_quote value +$this->magic_quotes_status = @get_magic_quotes_runtime(); + +// ----- Disable magic_quotes +if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime(0); +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------- +// Function : privSwapBackMagicQuotes() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function privSwapBackMagicQuotes() +{ +$v_result=1; + +// ----- Look if function exists +if ((!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; +} + +// ----- Look if something to do +if ($this->magic_quotes_status != -1) { + return $v_result; +} + +// ----- Swap back magic_quotes +if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime($this->magic_quotes_status); +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - } - // End of class - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilPathReduction() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function PclZipUtilPathReduction($p_dir) - { - $v_result = ""; - - // ----- Look for not empty path - if ($p_dir != "") { - // ----- Explode path by directory names - $v_list = explode("/", $p_dir); - - // ----- Study directories from last to first - $v_skip = 0; - for ($i=sizeof($v_list)-1; $i>=0; $i--) { - // ----- Look for current path - if ($v_list[$i] == ".") { - // ----- Ignore this directory - // Should be the first $i=0, but no check is done - } - else if ($v_list[$i] == "..") { - $v_skip++; - } - else if ($v_list[$i] == "") { - // ----- First '/' i.e. root slash - if ($i == 0) { - $v_result = "/".$v_result; - if ($v_skip > 0) { - // ----- It is an invalid path, so the path is not modified - // TBC - $v_result = $p_dir; - $v_skip = 0; - } - } - // ----- Last '/' i.e. indicates a directory - else if ($i == (sizeof($v_list)-1)) { - $v_result = $v_list[$i]; - } - // ----- Double '/' inside the path - else { - // ----- Ignore only the double '//' in path, - // but not the first and last '/' - } - } - else { - // ----- Look for item to skip - if ($v_skip > 0) { - $v_skip--; - } - else { - $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); - } +} +// End of class +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilPathReduction() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function PclZipUtilPathReduction($p_dir) +{ +$v_result = ""; + +// ----- Look for not empty path +if ($p_dir != "") { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + $v_skip = 0; + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") { + $v_skip++; + } + else if ($v_list[$i] == "") { + // ----- First '/' i.e. root slash + if ($i == 0) { + $v_result = "/".$v_result; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; + $v_skip = 0; } } - - // ----- Look for skip + // ----- Last '/' i.e. indicates a directory + else if ($i == (sizeof($v_list)-1)) { + $v_result = $v_list[$i]; + } + // ----- Double '/' inside the path + else { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + } + else { + // ----- Look for item to skip if ($v_skip > 0) { - while ($v_skip > 0) { - $v_result = '../'.$v_result; - $v_skip--; - } + $v_skip--; + } + else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); } } - - // ----- Return - return $v_result; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilPathInclusion() - // Description : - // This function indicates if the path $p_path is under the $p_dir tree. Or, - // said in an other way, if the file or sub-dir $p_path is inside the dir - // $p_dir. - // The function indicates also if the path is exactly the same as the dir. - // This function supports path with duplicated '/' like '//', but does not - // support '.' or '..' statements. - // Parameters : - // Return Values : - // 0 if $p_path is not inside directory $p_dir - // 1 if $p_path is inside directory $p_dir - // 2 if $p_path is exactly the same as $p_dir - // -------------------------------------------------------------------------------- - function PclZipUtilPathInclusion($p_dir, $p_path) - { - $v_result = 1; - - // ----- Look for path beginning by ./ - if ( ($p_dir == '.') - || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { - $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); - } - if ( ($p_path == '.') - || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { - $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); + + // ----- Look for skip + if ($v_skip > 0) { + while ($v_skip > 0) { + $v_result = '../'.$v_result; + $v_skip--; } + } +} - // ----- Explode dir and path by directory separator - $v_list_dir = explode("/", $p_dir); - $v_list_dir_size = sizeof($v_list_dir); - $v_list_path = explode("/", $p_path); - $v_list_path_size = sizeof($v_list_path); +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Study directories paths - $i = 0; - $j = 0; - while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { +// -------------------------------------------------------------------------------- +// Function : PclZipUtilPathInclusion() +// Description : +// This function indicates if the path $p_path is under the $p_dir tree. Or, +// said in an other way, if the file or sub-dir $p_path is inside the dir +// $p_dir. +// The function indicates also if the path is exactly the same as the dir. +// This function supports path with duplicated '/' like '//', but does not +// support '.' or '..' statements. +// Parameters : +// Return Values : +// 0 if $p_path is not inside directory $p_dir +// 1 if $p_path is inside directory $p_dir +// 2 if $p_path is exactly the same as $p_dir +// -------------------------------------------------------------------------------- +function PclZipUtilPathInclusion($p_dir, $p_path) +{ +$v_result = 1; + +// ----- Look for path beginning by ./ +if (($p_dir == '.') + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { + $p_dir = PclZipUtilTranslateWinPath(getcwd(), false).'/'.substr($p_dir, 1); +} +if (($p_path == '.') + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { + $p_path = PclZipUtilTranslateWinPath(getcwd(), false).'/'.substr($p_path, 1); +} + +// ----- Explode dir and path by directory separator +$v_list_dir = explode("/", $p_dir); +$v_list_dir_size = sizeof($v_list_dir); +$v_list_path = explode("/", $p_path); +$v_list_path_size = sizeof($v_list_path); + +// ----- Study directories paths +$i = 0; +$j = 0; +while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } - // ----- Look for empty dir (path reduction) - if ($v_list_dir[$i] == '') { - $i++; - continue; - } - if ($v_list_path[$j] == '') { - $j++; - continue; - } + // ----- Compare the items + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ($v_list_path[$j] != '')) { + $v_result = 0; + } - // ----- Compare the items - if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { - $v_result = 0; - } + // ----- Next items + $i++; + $j++; +} - // ----- Next items - $i++; - $j++; - } +// ----- Look if everything seems to be the same +if ($v_result) { + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; - // ----- Look if everything seems to be the same - if ($v_result) { - // ----- Skip all the empty items - while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; - while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } + else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } +} - if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { - // ----- There are exactly the same - $v_result = 2; - } - else if ($i < $v_list_dir_size) { - // ----- The path is shorter than the dir - $v_result = 0; - } - } +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Return - return $v_result; +// -------------------------------------------------------------------------------- +// Function : PclZipUtilCopyBlock() +// Description : +// Parameters : +// $p_mode : read/write compression mode +// 0 : src & dest normal +// 1 : src gzip, dest normal +// 2 : src normal, dest gzip +// 3 : src & dest gzip +// Return Values : +// -------------------------------------------------------------------------------- +function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) +{ +$v_result = 1; + +if ($p_mode==0) +{ + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilCopyBlock() - // Description : - // Parameters : - // $p_mode : read/write compression mode - // 0 : src & dest normal - // 1 : src gzip, dest normal - // 2 : src normal, dest gzip - // 3 : src & dest gzip - // Return Values : - // -------------------------------------------------------------------------------- - function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) +} +else if ($p_mode==1) +{ + while ($p_size != 0) { - $v_result = 1; - - if ($p_mode==0) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_src, $v_read_size); - @fwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - else if ($p_mode==1) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($p_src, $v_read_size); - @fwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - else if ($p_mode==2) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_src, $v_read_size); - @gzwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - else if ($p_mode==3) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($p_src, $v_read_size); - @gzwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - - // ----- Return - return $v_result; + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilRename() - // Description : - // This function tries to do a simple rename() function. If it fails, it - // tries to copy the $p_src file in a new $p_dest file and then unlink the - // first one. - // Parameters : - // $p_src : Old filename - // $p_dest : New filename - // Return Values : - // 1 on success, 0 on failure. - // -------------------------------------------------------------------------------- - function PclZipUtilRename($p_src, $p_dest) +} +else if ($p_mode==2) +{ + while ($p_size != 0) { - $v_result = 1; + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } +} +else if ($p_mode==3) +{ + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- - // ----- Try to rename the files - if (!@rename($p_src, $p_dest)) { +// -------------------------------------------------------------------------------- +// Function : PclZipUtilRename() +// Description : +// This function tries to do a simple rename() function. If it fails, it +// tries to copy the $p_src file in a new $p_dest file and then unlink the +// first one. +// Parameters : +// $p_src : Old filename +// $p_dest : New filename +// Return Values : +// 1 on success, 0 on failure. +// -------------------------------------------------------------------------------- +function PclZipUtilRename($p_src, $p_dest) +{ +$v_result = 1; - // ----- Try to copy & unlink the src - if (!@copy($p_src, $p_dest)) { - $v_result = 0; - } - else if (!@unlink($p_src)) { - $v_result = 0; - } - } +// ----- Try to rename the files +if (!@rename($p_src, $p_dest)) { - // ----- Return - return $v_result; + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilOptionText() - // Description : - // Translate option value in text. Mainly for debug purpose. - // Parameters : - // $p_option : the option value. - // Return Values : - // The option text value. - // -------------------------------------------------------------------------------- - function PclZipUtilOptionText($p_option) - { - - $v_list = get_defined_constants(); - for (reset($v_list); $v_key = key($v_list); next($v_list)) { - $v_prefix = substr($v_key, 0, 10); - if (( ($v_prefix == 'PCLZIP_OPT') - || ($v_prefix == 'PCLZIP_CB_') - || ($v_prefix == 'PCLZIP_ATT')) - && ($v_list[$v_key] == $p_option)) { - return $v_key; - } + else if (!@unlink($p_src)) { + $v_result = 0; + } +} + +// ----- Return +return $v_result; +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilOptionText() +// Description : +// Translate option value in text. Mainly for debug purpose. +// Parameters : +// $p_option : the option value. +// Return Values : +// The option text value. +// -------------------------------------------------------------------------------- +function PclZipUtilOptionText($p_option) +{ + +$v_list = get_defined_constants(); +for (reset($v_list); $v_key = key($v_list); next($v_list)) { + $v_prefix = substr($v_key, 0, 10); + if ((($v_prefix == 'PCLZIP_OPT') + || ($v_prefix == 'PCLZIP_CB_') + || ($v_prefix == 'PCLZIP_ATT')) + && ($v_list[$v_key] == $p_option)) { + return $v_key; } - - $v_result = 'Unknown'; +} - return $v_result; +$v_result = 'Unknown'; + +return $v_result; +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilTranslateWinPath() +// Description : +// Translate windows path by replacing '\' by '/' and optionally removing +// drive letter. +// Parameters : +// $p_path : path to translate. +// $p_remove_disk_letter : true | false +// Return Values : +// The path translated. +// -------------------------------------------------------------------------------- +function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) +{ +if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilTranslateWinPath() - // Description : - // Translate windows path by replacing '\' by '/' and optionally removing - // drive letter. - // Parameters : - // $p_path : path to translate. - // $p_remove_disk_letter : true | false - // Return Values : - // The path translated. - // -------------------------------------------------------------------------------- - function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) - { - if (stristr(php_uname(), 'windows')) { - // ----- Look for potential disk letter - if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { - $p_path = substr($p_path, $v_position+1); - } - // ----- Change potential windows directory separator - if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { - $p_path = strtr($p_path, '\\', '/'); - } - } - return $p_path; + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); } - // -------------------------------------------------------------------------------- +} +return $p_path; +} +// -------------------------------------------------------------------------------- \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/ZipStreamWrapper.php b/Classes/PHPExcel/Shared/ZipStreamWrapper.php index de31e247a..254849dfa 100644 --- a/Classes/PHPExcel/Shared/ZipStreamWrapper.php +++ b/Classes/PHPExcel/Shared/ZipStreamWrapper.php @@ -57,9 +57,10 @@ class PHPExcel_Shared_ZipStreamWrapper { /** * Register wrapper */ - public static function register() { - @stream_wrapper_unregister("zip"); - @stream_wrapper_register("zip", __CLASS__); + public static function register() + { + @stream_wrapper_unregister('zip'); + @stream_wrapper_register('zip', __CLASS__); } /** @@ -71,7 +72,8 @@ public static function register() { * @param string &$openedPath absolute path of the opened stream (out parameter) * @return bool true on success */ - public function stream_open($path, $mode, $options, &$opened_path) { + public function stream_open($path, $mode, $options, &$opened_path) + { // Check for mode if ($mode{0} != 'r') { throw new PHPExcel_Reader_Exception('Mode ' . $mode . ' is not supported. Only read mode is supported.'); @@ -87,7 +89,7 @@ public function stream_open($path, $mode, $options, &$opened_path) { $this->_fileNameInArchive = $url['fragment']; $this->_position = 0; - $this->_data = $this->_archive->getFromName( $this->_fileNameInArchive ); + $this->_data = $this->_archive->getFromName($this->_fileNameInArchive); return true; } @@ -97,7 +99,8 @@ public function stream_open($path, $mode, $options, &$opened_path) { * * @return boolean */ - public function statName() { + public function statName() + { return $this->_fileNameInArchive; } @@ -106,8 +109,9 @@ public function statName() { * * @return boolean */ - public function url_stat() { - return $this->statName( $this->_fileNameInArchive ); + public function url_stat() + { + return $this->statName($this->_fileNameInArchive); } /** @@ -115,8 +119,9 @@ public function url_stat() { * * @return boolean */ - public function stream_stat() { - return $this->_archive->statName( $this->_fileNameInArchive ); + public function stream_stat() + { + return $this->_archive->statName($this->_fileNameInArchive); } /** @@ -125,7 +130,8 @@ public function stream_stat() { * @param int $count maximum number of bytes to read * @return string */ - function stream_read($count) { + function stream_read($count) + { $ret = substr($this->_data, $this->_position, $count); $this->_position += strlen($ret); return $ret; @@ -137,7 +143,8 @@ function stream_read($count) { * * @return int */ - public function stream_tell() { + public function stream_tell() + { return $this->_position; } @@ -146,7 +153,8 @@ public function stream_tell() { * * @return bool */ - public function stream_eof() { + public function stream_eof() + { return $this->_position >= strlen($this->_data); } @@ -157,7 +165,8 @@ public function stream_eof() { * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END * @return bool */ - public function stream_seek($offset, $whence) { + public function stream_seek($offset, $whence) + { switch ($whence) { case SEEK_SET: if ($offset < strlen($this->_data) && $offset >= 0) { @@ -167,7 +176,6 @@ public function stream_seek($offset, $whence) { return false; } break; - case SEEK_CUR: if ($offset >= 0) { $this->_position += $offset; @@ -176,7 +184,6 @@ public function stream_seek($offset, $whence) { return false; } break; - case SEEK_END: if (strlen($this->_data) + $offset >= 0) { $this->_position = strlen($this->_data) + $offset; @@ -185,7 +192,6 @@ public function stream_seek($offset, $whence) { return false; } break; - default: return false; } diff --git a/Classes/PHPExcel/Style.php b/Classes/PHPExcel/Style.php index 33ad3caa4..20f7236e7 100644 --- a/Classes/PHPExcel/Style.php +++ b/Classes/PHPExcel/Style.php @@ -210,7 +210,6 @@ public function applyFromArray($pStyles = null, $pAdvanced = true) { if (is_array($pStyles)) { if ($this->isSupervisor) { - $pRange = $this->getSelectedCells(); // Uppercase coordinate @@ -322,7 +321,7 @@ public function applyFromArray($pStyles = null, $pAdvanced = true) unset($regionStyles['borders']['inside']); // what are the inner edges of the region when looking at the selection - $innerEdges = array_diff( array('top', 'right', 'bottom', 'left'), $edges ); + $innerEdges = array_diff(array('top', 'right', 'bottom', 'left'), $edges); // inner edges that are not touching the region should take the 'inside' border properties if they have been set foreach ($innerEdges as $innerEdge) { diff --git a/Classes/PHPExcel/Writer/Excel2007/DocProps.php b/Classes/PHPExcel/Writer/Excel2007/DocProps.php index 4573cc028..6ef50d3bf 100644 --- a/Classes/PHPExcel/Writer/Excel2007/DocProps.php +++ b/Classes/PHPExcel/Writer/Excel2007/DocProps.php @@ -240,21 +240,21 @@ public function writeDocPropsCustom(PHPExcel $pPHPExcel = null) $objWriter->writeAttribute('name', $customProperty); switch ($propertyType) { - case 'i' : + case 'i': $objWriter->writeElement('vt:i4', $propertyValue); break; - case 'f' : + case 'f': $objWriter->writeElement('vt:r8', $propertyValue); break; - case 'b' : + case 'b': $objWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false'); break; - case 'd' : + case 'd': $objWriter->startElement('vt:filetime'); $objWriter->writeRawData(date(DATE_W3C, $propertyValue)); $objWriter->endElement(); break; - default : + default: $objWriter->writeElement('vt:lpwstr', $propertyValue); break; } diff --git a/Classes/PHPExcel/Writer/Excel2007/Drawing.php b/Classes/PHPExcel/Writer/Excel2007/Drawing.php index 3d44ed350..794d6a4bb 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Drawing.php +++ b/Classes/PHPExcel/Writer/Excel2007/Drawing.php @@ -44,7 +44,7 @@ class PHPExcel_Writer_Excel2007_Drawing extends PHPExcel_Writer_Excel2007_Writer * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE) + public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = false) { // Create XML writer $objWriter = null; @@ -62,26 +62,25 @@ public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing'); $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); - // Loop through images and write drawings - $i = 1; - $iterator = $pWorksheet->getDrawingCollection()->getIterator(); - while ($iterator->valid()) { - $this->_writeDrawing($objWriter, $iterator->current(), $i); + // Loop through images and write drawings + $i = 1; + $iterator = $pWorksheet->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + $this->_writeDrawing($objWriter, $iterator->current(), $i); - $iterator->next(); - ++$i; - } + $iterator->next(); + ++$i; + } - if ($includeCharts) { - $chartCount = $pWorksheet->getChartCount(); - // Loop through charts and write the chart position - if ($chartCount > 0) { - for ($c = 0; $c < $chartCount; ++$c) { - $this->_writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i); - } + if ($includeCharts) { + $chartCount = $pWorksheet->getChartCount(); + // Loop through charts and write the chart position + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i); } } - + } $objWriter->endElement(); @@ -174,81 +173,81 @@ public function _writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx if ($pRelationId >= 0) { // xdr:oneCellAnchor $objWriter->startElement('xdr:oneCellAnchor'); - // Image location - $aCoordinates = PHPExcel_Cell::coordinateFromString($pDrawing->getCoordinates()); - $aCoordinates[0] = PHPExcel_Cell::columnIndexFromString($aCoordinates[0]); - - // xdr:from - $objWriter->startElement('xdr:from'); - $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1); - $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX())); - $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1); - $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY())); - $objWriter->endElement(); + // Image location + $aCoordinates = PHPExcel_Cell::coordinateFromString($pDrawing->getCoordinates()); + $aCoordinates[0] = PHPExcel_Cell::columnIndexFromString($aCoordinates[0]); - // xdr:ext - $objWriter->startElement('xdr:ext'); - $objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth())); - $objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight())); - $objWriter->endElement(); + // xdr:from + $objWriter->startElement('xdr:from'); + $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1); + $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX())); + $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1); + $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY())); + $objWriter->endElement(); - // xdr:pic - $objWriter->startElement('xdr:pic'); + // xdr:ext + $objWriter->startElement('xdr:ext'); + $objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth())); + $objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight())); + $objWriter->endElement(); - // xdr:nvPicPr - $objWriter->startElement('xdr:nvPicPr'); + // xdr:pic + $objWriter->startElement('xdr:pic'); - // xdr:cNvPr - $objWriter->startElement('xdr:cNvPr'); - $objWriter->writeAttribute('id', $pRelationId); - $objWriter->writeAttribute('name', $pDrawing->getName()); - $objWriter->writeAttribute('descr', $pDrawing->getDescription()); - $objWriter->endElement(); + // xdr:nvPicPr + $objWriter->startElement('xdr:nvPicPr'); - // xdr:cNvPicPr - $objWriter->startElement('xdr:cNvPicPr'); + // xdr:cNvPr + $objWriter->startElement('xdr:cNvPr'); + $objWriter->writeAttribute('id', $pRelationId); + $objWriter->writeAttribute('name', $pDrawing->getName()); + $objWriter->writeAttribute('descr', $pDrawing->getDescription()); + $objWriter->endElement(); - // a:picLocks - $objWriter->startElement('a:picLocks'); - $objWriter->writeAttribute('noChangeAspect', '1'); - $objWriter->endElement(); + // xdr:cNvPicPr + $objWriter->startElement('xdr:cNvPicPr'); - $objWriter->endElement(); + // a:picLocks + $objWriter->startElement('a:picLocks'); + $objWriter->writeAttribute('noChangeAspect', '1'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // xdr:blipFill - $objWriter->startElement('xdr:blipFill'); + $objWriter->endElement(); - // a:blip - $objWriter->startElement('a:blip'); - $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); - $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId); - $objWriter->endElement(); + // xdr:blipFill + $objWriter->startElement('xdr:blipFill'); - // a:stretch - $objWriter->startElement('a:stretch'); - $objWriter->writeElement('a:fillRect', null); - $objWriter->endElement(); + // a:blip + $objWriter->startElement('a:blip'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId); + $objWriter->endElement(); - $objWriter->endElement(); + // a:stretch + $objWriter->startElement('a:stretch'); + $objWriter->writeElement('a:fillRect', null); + $objWriter->endElement(); - // xdr:spPr - $objWriter->startElement('xdr:spPr'); + $objWriter->endElement(); - // a:xfrm - $objWriter->startElement('a:xfrm'); - $objWriter->writeAttribute('rot', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getRotation())); - $objWriter->endElement(); + // xdr:spPr + $objWriter->startElement('xdr:spPr'); + + // a:xfrm + $objWriter->startElement('a:xfrm'); + $objWriter->writeAttribute('rot', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getRotation())); + $objWriter->endElement(); - // a:prstGeom - $objWriter->startElement('a:prstGeom'); - $objWriter->writeAttribute('prst', 'rect'); + // a:prstGeom + $objWriter->startElement('a:prstGeom'); + $objWriter->writeAttribute('prst', 'rect'); - // a:avLst - $objWriter->writeElement('a:avLst', null); + // a:avLst + $objWriter->writeElement('a:avLst', null); - $objWriter->endElement(); + $objWriter->endElement(); // // a:solidFill // $objWriter->startElement('a:solidFill'); @@ -268,110 +267,110 @@ public function _writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx // $objWriter->endElement(); /* - // a:ln - $objWriter->startElement('a:ln'); - $objWriter->writeAttribute('w', '88900'); - $objWriter->writeAttribute('cap', 'sq'); + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '88900'); + $objWriter->writeAttribute('cap', 'sq'); - // a:solidFill - $objWriter->startElement('a:solidFill'); + // a:solidFill + $objWriter->startElement('a:solidFill'); - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', 'FFFFFF'); - $objWriter->endElement(); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FFFFFF'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // a:miter - $objWriter->startElement('a:miter'); - $objWriter->writeAttribute('lim', '800000'); - $objWriter->endElement(); + // a:miter + $objWriter->startElement('a:miter'); + $objWriter->writeAttribute('lim', '800000'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); */ - if ($pDrawing->getShadow()->getVisible()) { - // a:effectLst - $objWriter->startElement('a:effectLst'); - - // a:outerShdw - $objWriter->startElement('a:outerShdw'); - $objWriter->writeAttribute('blurRad', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius())); - $objWriter->writeAttribute('dist', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance())); - $objWriter->writeAttribute('dir', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getShadow()->getDirection())); - $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment()); - $objWriter->writeAttribute('rotWithShape', '0'); - - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB()); - - // a:alpha - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000); - $objWriter->endElement(); + if ($pDrawing->getShadow()->getVisible()) { + // a:effectLst + $objWriter->startElement('a:effectLst'); + + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius())); + $objWriter->writeAttribute('dist', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance())); + $objWriter->writeAttribute('dir', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getShadow()->getDirection())); + $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment()); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB()); + + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); - } + $objWriter->endElement(); + } /* - // a:scene3d - $objWriter->startElement('a:scene3d'); + // a:scene3d + $objWriter->startElement('a:scene3d'); - // a:camera - $objWriter->startElement('a:camera'); - $objWriter->writeAttribute('prst', 'orthographicFront'); - $objWriter->endElement(); + // a:camera + $objWriter->startElement('a:camera'); + $objWriter->writeAttribute('prst', 'orthographicFront'); + $objWriter->endElement(); - // a:lightRig - $objWriter->startElement('a:lightRig'); - $objWriter->writeAttribute('rig', 'twoPt'); - $objWriter->writeAttribute('dir', 't'); + // a:lightRig + $objWriter->startElement('a:lightRig'); + $objWriter->writeAttribute('rig', 'twoPt'); + $objWriter->writeAttribute('dir', 't'); - // a:rot - $objWriter->startElement('a:rot'); - $objWriter->writeAttribute('lat', '0'); - $objWriter->writeAttribute('lon', '0'); - $objWriter->writeAttribute('rev', '0'); - $objWriter->endElement(); + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '0'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); */ /* - // a:sp3d - $objWriter->startElement('a:sp3d'); - - // a:bevelT - $objWriter->startElement('a:bevelT'); - $objWriter->writeAttribute('w', '25400'); - $objWriter->writeAttribute('h', '19050'); - $objWriter->endElement(); + // a:sp3d + $objWriter->startElement('a:sp3d'); - // a:contourClr - $objWriter->startElement('a:contourClr'); - - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', 'FFFFFF'); - $objWriter->endElement(); + // a:bevelT + $objWriter->startElement('a:bevelT'); + $objWriter->writeAttribute('w', '25400'); + $objWriter->writeAttribute('h', '19050'); + $objWriter->endElement(); - $objWriter->endElement(); + // a:contourClr + $objWriter->startElement('a:contourClr'); + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FFFFFF'); $objWriter->endElement(); -*/ + $objWriter->endElement(); $objWriter->endElement(); +*/ + $objWriter->endElement(); - // xdr:clientData - $objWriter->writeElement('xdr:clientData', null); + $objWriter->endElement(); + + // xdr:clientData + $objWriter->writeElement('xdr:clientData', null); $objWriter->endElement(); } else { @@ -399,8 +398,8 @@ public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); - // Header/footer images - $images = $pWorksheet->getHeaderFooter()->getImages(); + // Header/footer images + $images = $pWorksheet->getHeaderFooter()->getImages(); // xml $objWriter->startElement('xml'); @@ -408,117 +407,117 @@ public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); - // o:shapelayout - $objWriter->startElement('o:shapelayout'); - $objWriter->writeAttribute('v:ext', 'edit'); + // o:shapelayout + $objWriter->startElement('o:shapelayout'); + $objWriter->writeAttribute('v:ext', 'edit'); - // o:idmap - $objWriter->startElement('o:idmap'); - $objWriter->writeAttribute('v:ext', 'edit'); - $objWriter->writeAttribute('data', '1'); - $objWriter->endElement(); + // o:idmap + $objWriter->startElement('o:idmap'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('data', '1'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // v:shapetype - $objWriter->startElement('v:shapetype'); - $objWriter->writeAttribute('id', '_x0000_t75'); - $objWriter->writeAttribute('coordsize', '21600,21600'); - $objWriter->writeAttribute('o:spt', '75'); - $objWriter->writeAttribute('o:preferrelative', 't'); - $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe'); - $objWriter->writeAttribute('filled', 'f'); - $objWriter->writeAttribute('stroked', 'f'); - - // v:stroke - $objWriter->startElement('v:stroke'); - $objWriter->writeAttribute('joinstyle', 'miter'); - $objWriter->endElement(); + // v:shapetype + $objWriter->startElement('v:shapetype'); + $objWriter->writeAttribute('id', '_x0000_t75'); + $objWriter->writeAttribute('coordsize', '21600,21600'); + $objWriter->writeAttribute('o:spt', '75'); + $objWriter->writeAttribute('o:preferrelative', 't'); + $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe'); + $objWriter->writeAttribute('filled', 'f'); + $objWriter->writeAttribute('stroked', 'f'); + + // v:stroke + $objWriter->startElement('v:stroke'); + $objWriter->writeAttribute('joinstyle', 'miter'); + $objWriter->endElement(); - // v:formulas - $objWriter->startElement('v:formulas'); + // v:formulas + $objWriter->startElement('v:formulas'); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'sum @0 1 0'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @0 1 0'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'sum 0 0 @1'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum 0 0 @1'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @2 1 2'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @2 1 2'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'sum @0 0 1'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @0 0 1'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @6 1 2'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @6 1 2'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'sum @8 21600 0'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @8 21600 0'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight'); + $objWriter->endElement(); - // v:f - $objWriter->startElement('v:f'); - $objWriter->writeAttribute('eqn', 'sum @10 21600 0'); - $objWriter->endElement(); + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @10 21600 0'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // v:path - $objWriter->startElement('v:path'); - $objWriter->writeAttribute('o:extrusionok', 'f'); - $objWriter->writeAttribute('gradientshapeok', 't'); - $objWriter->writeAttribute('o:connecttype', 'rect'); - $objWriter->endElement(); + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('o:extrusionok', 'f'); + $objWriter->writeAttribute('gradientshapeok', 't'); + $objWriter->writeAttribute('o:connecttype', 'rect'); + $objWriter->endElement(); - // o:lock - $objWriter->startElement('o:lock'); - $objWriter->writeAttribute('v:ext', 'edit'); - $objWriter->writeAttribute('aspectratio', 't'); - $objWriter->endElement(); + // o:lock + $objWriter->startElement('o:lock'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('aspectratio', 't'); + $objWriter->endElement(); - $objWriter->endElement(); + $objWriter->endElement(); - // Loop through images - foreach ($images as $key => $value) { - $this->_writeVMLHeaderFooterImage($objWriter, $key, $value); - } + // Loop through images + foreach ($images as $key => $value) { + $this->_writeVMLHeaderFooterImage($objWriter, $key, $value); + } $objWriter->endElement(); @@ -548,22 +547,22 @@ public function _writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter // v:shape $objWriter->startElement('v:shape'); - $objWriter->writeAttribute('id', $pReference); - $objWriter->writeAttribute('o:spid', '_x0000_s' . $id); - $objWriter->writeAttribute('type', '#_x0000_t75'); - $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1"); - - // v:imagedata - $objWriter->startElement('v:imagedata'); - $objWriter->writeAttribute('o:relid', 'rId' . $pReference); - $objWriter->writeAttribute('o:title', $pImage->getName()); - $objWriter->endElement(); + $objWriter->writeAttribute('id', $pReference); + $objWriter->writeAttribute('o:spid', '_x0000_s' . $id); + $objWriter->writeAttribute('type', '#_x0000_t75'); + $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1"); + + // v:imagedata + $objWriter->startElement('v:imagedata'); + $objWriter->writeAttribute('o:relid', 'rId' . $pReference); + $objWriter->writeAttribute('o:title', $pImage->getName()); + $objWriter->endElement(); - // o:lock - $objWriter->startElement('o:lock'); - $objWriter->writeAttribute('v:ext', 'edit'); - $objWriter->writeAttribute('rotation', 't'); - $objWriter->endElement(); + // o:lock + $objWriter->startElement('o:lock'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('rotation', 't'); + $objWriter->endElement(); $objWriter->endElement(); } diff --git a/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Classes/PHPExcel/Writer/Excel2007/StringTable.php index f2e8a12e6..4a28f13e9 100644 --- a/Classes/PHPExcel/Writer/Excel2007/StringTable.php +++ b/Classes/PHPExcel/Writer/Excel2007/StringTable.php @@ -259,10 +259,10 @@ public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = nu // Underline $underlineType = $element->getFont()->getUnderline(); switch ($underlineType) { - case 'single' : + case 'single': $underlineType = 'sng'; break; - case 'double' : + case 'double': $underlineType = 'dbl'; break; } @@ -304,7 +304,8 @@ public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = nu * @param array $stringTable Stringtable * @return array */ - public function flipStringTable($stringTable = array()) { + public function flipStringTable($stringTable = array()) + { // Return value $returnValue = array(); diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index b1e7c1bd6..176e44b13 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -210,102 +210,103 @@ private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, P // sheetViews $objWriter->startElement('sheetViews'); - // Sheet selected? - $sheetSelected = false; - if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex()) { - $sheetSelected = true; - } + // Sheet selected? + $sheetSelected = false; + if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex()) { + $sheetSelected = true; + } - // sheetView - $objWriter->startElement('sheetView'); - $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0'); - $objWriter->writeAttribute('workbookViewId', '0'); + // sheetView + $objWriter->startElement('sheetView'); + $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0'); + $objWriter->writeAttribute('workbookViewId', '0'); - // Zoom scales - if ($pSheet->getSheetView()->getZoomScale() != 100) { - $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale()); - } - if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) { - $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal()); - } + // Zoom scales + if ($pSheet->getSheetView()->getZoomScale() != 100) { + $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale()); + } + if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) { + $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal()); + } - // View Layout Type - if ($pSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL) { - $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView()); - } + // View Layout Type + if ($pSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL) { + $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView()); + } - // Gridlines - if ($pSheet->getShowGridlines()) { - $objWriter->writeAttribute('showGridLines', 'true'); - } else { - $objWriter->writeAttribute('showGridLines', 'false'); - } + // Gridlines + if ($pSheet->getShowGridlines()) { + $objWriter->writeAttribute('showGridLines', 'true'); + } else { + $objWriter->writeAttribute('showGridLines', 'false'); + } - // Row and column headers - if ($pSheet->getShowRowColHeaders()) { - $objWriter->writeAttribute('showRowColHeaders', '1'); - } else { - $objWriter->writeAttribute('showRowColHeaders', '0'); - } + // Row and column headers + if ($pSheet->getShowRowColHeaders()) { + $objWriter->writeAttribute('showRowColHeaders', '1'); + } else { + $objWriter->writeAttribute('showRowColHeaders', '0'); + } - // Right-to-left - if ($pSheet->getRightToLeft()) { - $objWriter->writeAttribute('rightToLeft', 'true'); - } + // Right-to-left + if ($pSheet->getRightToLeft()) { + $objWriter->writeAttribute('rightToLeft', 'true'); + } - $activeCell = $pSheet->getActiveCell(); - - // Pane - $pane = ''; - $topLeftCell = $pSheet->getFreezePane(); - if (($topLeftCell != '') && ($topLeftCell != 'A1')) { - $activeCell = $topLeftCell; - // Calculate freeze coordinates - $xSplit = $ySplit = 0; - - list($xSplit, $ySplit) = PHPExcel_Cell::coordinateFromString($topLeftCell); - $xSplit = PHPExcel_Cell::columnIndexFromString($xSplit); - - // pane - $pane = 'topRight'; - $objWriter->startElement('pane'); - if ($xSplit > 1) - $objWriter->writeAttribute('xSplit', $xSplit - 1); - if ($ySplit > 1) { - $objWriter->writeAttribute('ySplit', $ySplit - 1); - $pane = ($xSplit > 1) ? 'bottomRight' : 'bottomLeft'; - } - $objWriter->writeAttribute('topLeftCell', $topLeftCell); - $objWriter->writeAttribute('activePane', $pane); - $objWriter->writeAttribute('state', 'frozen'); - $objWriter->endElement(); + $activeCell = $pSheet->getActiveCell(); - if (($xSplit > 1) && ($ySplit > 1)) { - // Write additional selections if more than two panes (ie both an X and a Y split) - $objWriter->startElement('selection'); - $objWriter->writeAttribute('pane', 'topRight'); - $objWriter->endElement(); - $objWriter->startElement('selection'); - $objWriter->writeAttribute('pane', 'bottomLeft'); - $objWriter->endElement(); - } - } + // Pane + $pane = ''; + $topLeftCell = $pSheet->getFreezePane(); + if (($topLeftCell != '') && ($topLeftCell != 'A1')) { + $activeCell = $topLeftCell; + // Calculate freeze coordinates + $xSplit = $ySplit = 0; - // Selection -// if ($pane != '') { - // Only need to write selection element if we have a split pane - // We cheat a little by over-riding the active cell selection, setting it to the split cell - $objWriter->startElement('selection'); - if ($pane != '') { - $objWriter->writeAttribute('pane', $pane); - } - $objWriter->writeAttribute('activeCell', $activeCell); - $objWriter->writeAttribute('sqref', $activeCell); - $objWriter->endElement(); -// } + list($xSplit, $ySplit) = PHPExcel_Cell::coordinateFromString($topLeftCell); + $xSplit = PHPExcel_Cell::columnIndexFromString($xSplit); + // pane + $pane = 'topRight'; + $objWriter->startElement('pane'); + if ($xSplit > 1) { + $objWriter->writeAttribute('xSplit', $xSplit - 1); + } + if ($ySplit > 1) { + $objWriter->writeAttribute('ySplit', $ySplit - 1); + $pane = ($xSplit > 1) ? 'bottomRight' : 'bottomLeft'; + } + $objWriter->writeAttribute('topLeftCell', $topLeftCell); + $objWriter->writeAttribute('activePane', $pane); + $objWriter->writeAttribute('state', 'frozen'); $objWriter->endElement(); + if (($xSplit > 1) && ($ySplit > 1)) { + // Write additional selections if more than two panes (ie both an X and a Y split) + $objWriter->startElement('selection'); + $objWriter->writeAttribute('pane', 'topRight'); + $objWriter->endElement(); + $objWriter->startElement('selection'); + $objWriter->writeAttribute('pane', 'bottomLeft'); + $objWriter->endElement(); + } + } + + // Selection +// if ($pane != '') { + // Only need to write selection element if we have a split pane + // We cheat a little by over-riding the active cell selection, setting it to the split cell + $objWriter->startElement('selection'); + if ($pane != '') { + $objWriter->writeAttribute('pane', $pane); + } + $objWriter->writeAttribute('activeCell', $activeCell); + $objWriter->writeAttribute('sqref', $activeCell); + $objWriter->endElement(); +// } + + $objWriter->endElement(); + $objWriter->endElement(); } @@ -371,7 +372,7 @@ private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null private function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // cols - if (count($pSheet->getColumnDimensions()) > 0) { + if (count($pSheet->getColumnDimensions()) > 0) { $objWriter->startElement('cols'); $pSheet->calculateColumnWidths(); @@ -485,50 +486,48 @@ private function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWrite $objWriter->startElement('conditionalFormatting'); $objWriter->writeAttribute('sqref', $cellCoordinate); - // cfRule - $objWriter->startElement('cfRule'); - $objWriter->writeAttribute('type', $conditional->getConditionType()); - $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode())); - $objWriter->writeAttribute('priority', $id++); - - if (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS - || - $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT) - && $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) { - $objWriter->writeAttribute('operator', $conditional->getOperatorType()); - } + // cfRule + $objWriter->startElement('cfRule'); + $objWriter->writeAttribute('type', $conditional->getConditionType()); + $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode())); + $objWriter->writeAttribute('priority', $id++); - if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - && !is_null($conditional->getText())) { - $objWriter->writeAttribute('text', $conditional->getText()); - } + if (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT) + && $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) { + $objWriter->writeAttribute('operator', $conditional->getOperatorType()); + } - if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT - && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH - && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH - && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS - && !is_null($conditional->getText())) { - $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS - || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT - || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { - foreach ($conditional->getConditions() as $formula) { - // Formula - $objWriter->writeElement('formula', $formula); - } + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && !is_null($conditional->getText())) { + $objWriter->writeAttribute('text', $conditional->getText()); + } + + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { + foreach ($conditional->getConditions() as $formula) { + // Formula + $objWriter->writeElement('formula', $formula); } + } - $objWriter->endElement(); + $objWriter->endElement(); $objWriter->endElement(); } @@ -656,17 +655,17 @@ private function _writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = nu // protectedRanges $objWriter->startElement('protectedRanges'); - // Loop protectedRanges - foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) { - // protectedRange - $objWriter->startElement('protectedRange'); - $objWriter->writeAttribute('name', 'p' . md5($protectedCell)); - $objWriter->writeAttribute('sqref', $protectedCell); - if (!empty($passwordHash)) { - $objWriter->writeAttribute('password', $passwordHash); - } - $objWriter->endElement(); + // Loop protectedRanges + foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) { + // protectedRange + $objWriter->startElement('protectedRange'); + $objWriter->writeAttribute('name', 'p' . md5($protectedCell)); + $objWriter->writeAttribute('sqref', $protectedCell); + if (!empty($passwordHash)) { + $objWriter->writeAttribute('password', $passwordHash); } + $objWriter->endElement(); + } $objWriter->endElement(); } @@ -685,13 +684,13 @@ private function _writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, P // mergeCells $objWriter->startElement('mergeCells'); - // Loop mergeCells - foreach ($pSheet->getMergeCells() as $mergeCell) { - // mergeCell - $objWriter->startElement('mergeCell'); - $objWriter->writeAttribute('ref', $mergeCell); - $objWriter->endElement(); - } + // Loop mergeCells + foreach ($pSheet->getMergeCells() as $mergeCell) { + // mergeCell + $objWriter->startElement('mergeCell'); + $objWriter->writeAttribute('ref', $mergeCell); + $objWriter->endElement(); + } $objWriter->endElement(); } @@ -766,71 +765,70 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P } $range = implode(':', $range); - $objWriter->writeAttribute('ref', str_replace('$','', $range)); + $objWriter->writeAttribute('ref', str_replace('$', '', $range)); $columns = $pSheet->getAutoFilter()->getColumns(); if (count($columns > 0)) { foreach ($columns as $columnID => $column) { $rules = $column->getRules(); - if (count($rules > 0)) { + if (count($rules) > 0) { $objWriter->startElement('filterColumn'); - $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID)); + $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID)); + + $objWriter->startElement($column->getFilterType()); + if ($column->getJoin() == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND) { + $objWriter->writeAttribute('and', 1); + } - $objWriter->startElement($column->getFilterType()); - if ($column->getJoin() == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND) { - $objWriter->writeAttribute('and', 1); + foreach ($rules as $rule) { + if (($column->getFilterType() === PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) && + ($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) && + ($rule->getValue() === '')) { + // Filter rule for Blanks + $objWriter->writeAttribute('blank', 1); + } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { + // Dynamic Filter Rule + $objWriter->writeAttribute('type', $rule->getGrouping()); + $val = $column->getAttribute('val'); + if ($val !== null) { + $objWriter->writeAttribute('val', $val); } + $maxVal = $column->getAttribute('maxVal'); + if ($maxVal !== null) { + $objWriter->writeAttribute('maxVal', $maxVal); + } + } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { + // Top 10 Filter Rule + $objWriter->writeAttribute('val', $rule->getValue()); + $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); + $objWriter->writeAttribute('top', (($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0')); + } else { + // Filter, DateGroupItem or CustomFilter + $objWriter->startElement($rule->getRuleType()); - foreach ($rules as $rule) { - if (($column->getFilterType() === PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) && - ($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) && - ($rule->getValue() === '')) { - // Filter rule for Blanks - $objWriter->writeAttribute('blank', 1); - } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { - // Dynamic Filter Rule - $objWriter->writeAttribute('type', $rule->getGrouping()); - $val = $column->getAttribute('val'); - if ($val !== null) { - $objWriter->writeAttribute('val', $val); - } - $maxVal = $column->getAttribute('maxVal'); - if ($maxVal !== null) { - $objWriter->writeAttribute('maxVal', $maxVal); - } - } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { - // Top 10 Filter Rule - $objWriter->writeAttribute('val', $rule->getValue()); - $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); - $objWriter->writeAttribute('top', (($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0')); - } else { - // Filter, DateGroupItem or CustomFilter - $objWriter->startElement($rule->getRuleType()); - - if ($rule->getOperator() !== PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) { - $objWriter->writeAttribute('operator', $rule->getOperator()); - } - if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { - // Date Group filters - foreach ($rule->getValue() as $key => $value) { - if ($value > '') $objWriter->writeAttribute($key, $value); - } - $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); - } else { - $objWriter->writeAttribute('val', $rule->getValue()); - } - - $objWriter->endElement(); + if ($rule->getOperator() !== PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) { + $objWriter->writeAttribute('operator', $rule->getOperator()); + } + if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { + // Date Group filters + foreach ($rule->getValue() as $key => $value) { + if ($value > '') $objWriter->writeAttribute($key, $value); } + $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); + } else { + $objWriter->writeAttribute('val', $rule->getValue()); } - $objWriter->endElement(); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); $objWriter->endElement(); } } } - $objWriter->endElement(); } } @@ -921,14 +919,14 @@ private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx $objWriter->writeAttribute('count', count($aRowBreaks)); $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks)); - foreach ($aRowBreaks as $cell) { - $coords = PHPExcel_Cell::coordinateFromString($cell); + foreach ($aRowBreaks as $cell) { + $coords = PHPExcel_Cell::coordinateFromString($cell); - $objWriter->startElement('brk'); - $objWriter->writeAttribute('id', $coords[1]); - $objWriter->writeAttribute('man', '1'); - $objWriter->endElement(); - } + $objWriter->startElement('brk'); + $objWriter->writeAttribute('id', $coords[1]); + $objWriter->writeAttribute('man', '1'); + $objWriter->endElement(); + } $objWriter->endElement(); } @@ -939,14 +937,14 @@ private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx $objWriter->writeAttribute('count', count($aColumnBreaks)); $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks)); - foreach ($aColumnBreaks as $cell) { - $coords = PHPExcel_Cell::coordinateFromString($cell); + foreach ($aColumnBreaks as $cell) { + $coords = PHPExcel_Cell::coordinateFromString($cell); - $objWriter->startElement('brk'); - $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1); - $objWriter->writeAttribute('man', '1'); - $objWriter->endElement(); - } + $objWriter->startElement('brk'); + $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1); + $objWriter->writeAttribute('man', '1'); + $objWriter->endElement(); + } $objWriter->endElement(); } diff --git a/Classes/PHPExcel/Writer/Excel5/Parser.php b/Classes/PHPExcel/Writer/Excel5/Parser.php index 56449fcff..05ea60ef7 100644 --- a/Classes/PHPExcel/Writer/Excel5/Parser.php +++ b/Classes/PHPExcel/Writer/Excel5/Parser.php @@ -1135,8 +1135,7 @@ private function _match($token) } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.')) { // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) return $token; - } - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.')) { + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.')) { // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) return $token; } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) && !preg_match("/[0-9]/", $this->_lookahead)) { @@ -1253,7 +1252,7 @@ private function _expression() $this->_advance(); return $result; // If it's an error code - } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $this->_current_token) or $this->_current_token == '#N/A'){ + } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $this->_current_token) or $this->_current_token == '#N/A') { $result = $this->_createTree($this->_current_token, 'ptgErr', ''); $this->_advance(); return $result; @@ -1361,45 +1360,39 @@ private function _fact() $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; - } - // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) { + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) { + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; - } - // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) { + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) { + // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; - } - // if it's a range A1:B2 or $A$1:$B$2 - elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->_current_token) or + } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->_current_token) or preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->_current_token)) { + // if it's a range A1:B2 or $A$1:$B$2 // must be an error? $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; - } - // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2) - elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) { + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) { + // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2) // must be an error? //$result = $this->_current_token; $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; - } - // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2) - elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) { + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) { + // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2) // must be an error? //$result = $this->_current_token; $result = $this->_createTree($this->_current_token, '', ''); $this->_advance(); return $result; - } - // If it's a number or a percent - elseif (is_numeric($this->_current_token)) { + } elseif (is_numeric($this->_current_token)) { + // If it's a number or a percent if ($this->_lookahead == '%') { $result = $this->_createTree('ptgPercent', $this->_current_token, ''); $this->_advance(); // Skip the percentage operator once we've pre-built that tree @@ -1408,15 +1401,12 @@ private function _fact() } $this->_advance(); return $result; - } - // if it's a function call - elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $this->_current_token)) { + } elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $this->_current_token)) { + // if it's a function call $result = $this->_func(); return $result; } - throw new PHPExcel_Writer_Exception("Syntax error: ".$this->_current_token. - ", lookahead: ".$this->_lookahead. - ", current char: ".$this->_current_char); + throw new PHPExcel_Writer_Exception("Syntax error: ".$this->_current_token.", lookahead: ".$this->_lookahead.", current char: ".$this->_current_char); } /** From 5508013569b122c71dce94bf2cab7add370bbd46 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Fri, 15 May 2015 13:17:40 +0200 Subject: [PATCH 372/467] PSR-2 : Fixes --- Classes/PHPExcel/Worksheet/PageSetup.php | 149 ++++++------- Classes/PHPExcel/Worksheet/Protection.php | 110 ++++++---- Classes/PHPExcel/Writer/Abstract.php | 20 +- Classes/PHPExcel/Writer/Excel2007.php | 4 +- Classes/PHPExcel/Writer/Excel2007/Chart.php | 49 +++-- .../PHPExcel/Writer/Excel2007/Comments.php | 110 +++++----- .../Writer/Excel2007/ContentTypes.php | 197 +++++++++--------- .../PHPExcel/Writer/Excel2007/Worksheet.php | 28 +-- 8 files changed, 364 insertions(+), 303 deletions(-) diff --git a/Classes/PHPExcel/Worksheet/PageSetup.php b/Classes/PHPExcel/Worksheet/PageSetup.php index 6a98d47b1..e5fe06ac6 100644 --- a/Classes/PHPExcel/Worksheet/PageSetup.php +++ b/Classes/PHPExcel/Worksheet/PageSetup.php @@ -107,81 +107,81 @@ class PHPExcel_Worksheet_PageSetup { /* Paper size */ - const PAPERSIZE_LETTER = 1; + const PAPERSIZE_LETTER = 1; const PAPERSIZE_LETTER_SMALL = 2; - const PAPERSIZE_TABLOID = 3; - const PAPERSIZE_LEDGER = 4; - const PAPERSIZE_LEGAL = 5; - const PAPERSIZE_STATEMENT = 6; - const PAPERSIZE_EXECUTIVE = 7; - const PAPERSIZE_A3 = 8; - const PAPERSIZE_A4 = 9; + const PAPERSIZE_TABLOID = 3; + const PAPERSIZE_LEDGER = 4; + const PAPERSIZE_LEGAL = 5; + const PAPERSIZE_STATEMENT = 6; + const PAPERSIZE_EXECUTIVE = 7; + const PAPERSIZE_A3 = 8; + const PAPERSIZE_A4 = 9; const PAPERSIZE_A4_SMALL = 10; - const PAPERSIZE_A5 = 11; - const PAPERSIZE_B4 = 12; - const PAPERSIZE_B5 = 13; - const PAPERSIZE_FOLIO = 14; - const PAPERSIZE_QUARTO = 15; - const PAPERSIZE_STANDARD_1 = 16; - const PAPERSIZE_STANDARD_2 = 17; + const PAPERSIZE_A5 = 11; + const PAPERSIZE_B4 = 12; + const PAPERSIZE_B5 = 13; + const PAPERSIZE_FOLIO = 14; + const PAPERSIZE_QUARTO = 15; + const PAPERSIZE_STANDARD_1 = 16; + const PAPERSIZE_STANDARD_2 = 17; const PAPERSIZE_NOTE = 18; const PAPERSIZE_NO9_ENVELOPE = 19; - const PAPERSIZE_NO10_ENVELOPE = 20; - const PAPERSIZE_NO11_ENVELOPE = 21; - const PAPERSIZE_NO12_ENVELOPE = 22; - const PAPERSIZE_NO14_ENVELOPE = 23; - const PAPERSIZE_C = 24; - const PAPERSIZE_D = 25; - const PAPERSIZE_E = 26; - const PAPERSIZE_DL_ENVELOPE = 27; - const PAPERSIZE_C5_ENVELOPE = 28; - const PAPERSIZE_C3_ENVELOPE = 29; - const PAPERSIZE_C4_ENVELOPE = 30; - const PAPERSIZE_C6_ENVELOPE = 31; + const PAPERSIZE_NO10_ENVELOPE = 20; + const PAPERSIZE_NO11_ENVELOPE = 21; + const PAPERSIZE_NO12_ENVELOPE = 22; + const PAPERSIZE_NO14_ENVELOPE = 23; + const PAPERSIZE_C = 24; + const PAPERSIZE_D = 25; + const PAPERSIZE_E = 26; + const PAPERSIZE_DL_ENVELOPE = 27; + const PAPERSIZE_C5_ENVELOPE = 28; + const PAPERSIZE_C3_ENVELOPE = 29; + const PAPERSIZE_C4_ENVELOPE = 30; + const PAPERSIZE_C6_ENVELOPE = 31; const PAPERSIZE_C65_ENVELOPE = 32; - const PAPERSIZE_B4_ENVELOPE = 33; - const PAPERSIZE_B5_ENVELOPE = 34; - const PAPERSIZE_B6_ENVELOPE = 35; - const PAPERSIZE_ITALY_ENVELOPE = 36; + const PAPERSIZE_B4_ENVELOPE = 33; + const PAPERSIZE_B5_ENVELOPE = 34; + const PAPERSIZE_B6_ENVELOPE = 35; + const PAPERSIZE_ITALY_ENVELOPE = 36; const PAPERSIZE_MONARCH_ENVELOPE = 37; - const PAPERSIZE_6_3_4_ENVELOPE = 38; - const PAPERSIZE_US_STANDARD_FANFOLD = 39; - const PAPERSIZE_GERMAN_STANDARD_FANFOLD = 40; + const PAPERSIZE_6_3_4_ENVELOPE = 38; + const PAPERSIZE_US_STANDARD_FANFOLD = 39; + const PAPERSIZE_GERMAN_STANDARD_FANFOLD = 40; const PAPERSIZE_GERMAN_LEGAL_FANFOLD = 41; - const PAPERSIZE_ISO_B4 = 42; + const PAPERSIZE_ISO_B4 = 42; const PAPERSIZE_JAPANESE_DOUBLE_POSTCARD = 43; const PAPERSIZE_STANDARD_PAPER_1 = 44; const PAPERSIZE_STANDARD_PAPER_2 = 45; const PAPERSIZE_STANDARD_PAPER_3 = 46; - const PAPERSIZE_INVITE_ENVELOPE = 47; - const PAPERSIZE_LETTER_EXTRA_PAPER = 48; - const PAPERSIZE_LEGAL_EXTRA_PAPER = 49; - const PAPERSIZE_TABLOID_EXTRA_PAPER = 50; - const PAPERSIZE_A4_EXTRA_PAPER = 51; - const PAPERSIZE_LETTER_TRANSVERSE_PAPER = 52; - const PAPERSIZE_A4_TRANSVERSE_PAPER = 53; - const PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER = 54; - const PAPERSIZE_SUPERA_SUPERA_A4_PAPER = 55; - const PAPERSIZE_SUPERB_SUPERB_A3_PAPER = 56; - const PAPERSIZE_LETTER_PLUS_PAPER = 57; - const PAPERSIZE_A4_PLUS_PAPER = 58; - const PAPERSIZE_A5_TRANSVERSE_PAPER = 59; - const PAPERSIZE_JIS_B5_TRANSVERSE_PAPER = 60; - const PAPERSIZE_A3_EXTRA_PAPER = 61; - const PAPERSIZE_A5_EXTRA_PAPER = 62; - const PAPERSIZE_ISO_B5_EXTRA_PAPER = 63; + const PAPERSIZE_INVITE_ENVELOPE = 47; + const PAPERSIZE_LETTER_EXTRA_PAPER = 48; + const PAPERSIZE_LEGAL_EXTRA_PAPER = 49; + const PAPERSIZE_TABLOID_EXTRA_PAPER = 50; + const PAPERSIZE_A4_EXTRA_PAPER = 51; + const PAPERSIZE_LETTER_TRANSVERSE_PAPER = 52; + const PAPERSIZE_A4_TRANSVERSE_PAPER = 53; + const PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER = 54; + const PAPERSIZE_SUPERA_SUPERA_A4_PAPER = 55; + const PAPERSIZE_SUPERB_SUPERB_A3_PAPER = 56; + const PAPERSIZE_LETTER_PLUS_PAPER = 57; + const PAPERSIZE_A4_PLUS_PAPER = 58; + const PAPERSIZE_A5_TRANSVERSE_PAPER = 59; + const PAPERSIZE_JIS_B5_TRANSVERSE_PAPER = 60; + const PAPERSIZE_A3_EXTRA_PAPER = 61; + const PAPERSIZE_A5_EXTRA_PAPER = 62; + const PAPERSIZE_ISO_B5_EXTRA_PAPER = 63; const PAPERSIZE_A2_PAPER = 64; - const PAPERSIZE_A3_TRANSVERSE_PAPER = 65; - const PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER = 66; + const PAPERSIZE_A3_TRANSVERSE_PAPER = 65; + const PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER = 66; /* Page orientation */ - const ORIENTATION_DEFAULT = 'default'; - const ORIENTATION_LANDSCAPE = 'landscape'; - const ORIENTATION_PORTRAIT = 'portrait'; + const ORIENTATION_DEFAULT = 'default'; + const ORIENTATION_LANDSCAPE = 'landscape'; + const ORIENTATION_PORTRAIT = 'portrait'; /* Print Range Set Method */ - const SETPRINTRANGE_OVERWRITE = 'O'; - const SETPRINTRANGE_INSERT = 'I'; + const SETPRINTRANGE_OVERWRITE = 'O'; + const SETPRINTRANGE_INSERT = 'I'; /** @@ -189,14 +189,14 @@ class PHPExcel_Worksheet_PageSetup * * @var int */ - private $_paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER; + private $_paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER; /** * Orientation * * @var string */ - private $_orientation = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT; + private $_orientation = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT; /** * Scale (Print Scale) @@ -206,7 +206,7 @@ class PHPExcel_Worksheet_PageSetup * * @var int? */ - private $_scale = 100; + private $_scale = 100; /** * Fit To Page @@ -214,7 +214,7 @@ class PHPExcel_Worksheet_PageSetup * * @var boolean */ - private $_fitToPage = FALSE; + private $_fitToPage = false; /** * Fit To Height @@ -251,28 +251,28 @@ class PHPExcel_Worksheet_PageSetup * * @var boolean */ - private $_horizontalCentered = FALSE; + private $_horizontalCentered = false; /** * Center page vertically * * @var boolean */ - private $_verticalCentered = FALSE; + private $_verticalCentered = false; /** * Print area * * @var string */ - private $_printArea = NULL; + private $_printArea = null; /** * First page number * * @var int */ - private $_firstPageNumber = NULL; + private $_firstPageNumber = null; /** * Create a new PHPExcel_Worksheet_PageSetup @@ -286,7 +286,8 @@ public function __construct() * * @return int */ - public function getPaperSize() { + public function getPaperSize() + { return $this->_paperSize; } @@ -370,7 +371,7 @@ public function getFitToPage() { * @param boolean $pValue * @return PHPExcel_Worksheet_PageSetup */ - public function setFitToPage($pValue = TRUE) { + public function setFitToPage($pValue = true) { $this->_fitToPage = $pValue; return $this; } @@ -391,10 +392,10 @@ public function getFitToHeight() { * @param boolean $pUpdate Update fitToPage so it applies rather than scaling * @return PHPExcel_Worksheet_PageSetup */ - public function setFitToHeight($pValue = 1, $pUpdate = TRUE) { + public function setFitToHeight($pValue = 1, $pUpdate = true) { $this->_fitToHeight = $pValue; if ($pUpdate) { - $this->_fitToPage = TRUE; + $this->_fitToPage = true; } return $this; } @@ -415,10 +416,10 @@ public function getFitToWidth() { * @param boolean $pUpdate Update fitToPage so it applies rather than scaling * @return PHPExcel_Worksheet_PageSetup */ - public function setFitToWidth($pValue = 1, $pUpdate = TRUE) { + public function setFitToWidth($pValue = 1, $pUpdate = true) { $this->_fitToWidth = $pValue; if ($pUpdate) { - $this->_fitToPage = TRUE; + $this->_fitToPage = true; } return $this; } @@ -610,7 +611,7 @@ public function isPrintAreaSet($index = 0) { */ public function clearPrintArea($index = 0) { if ($index == 0) { - $this->_printArea = NULL; + $this->_printArea = null; } else { $printAreas = explode(',', $this->_printArea); if (isset($printAreas[$index-1])) { diff --git a/Classes/PHPExcel/Worksheet/Protection.php b/Classes/PHPExcel/Worksheet/Protection.php index af3419889..d6ab223a0 100644 --- a/Classes/PHPExcel/Worksheet/Protection.php +++ b/Classes/PHPExcel/Worksheet/Protection.php @@ -166,8 +166,9 @@ public function __construct() * * @return boolean */ - function isProtectionEnabled() { - return $this->_sheet || + function isProtectionEnabled() + { + return $this->_sheet || $this->_objects || $this->_scenarios || $this->_formatCells || @@ -190,7 +191,8 @@ function isProtectionEnabled() { * * @return boolean */ - function getSheet() { + function getSheet() + { return $this->_sheet; } @@ -200,7 +202,8 @@ function getSheet() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setSheet($pValue = false) { + function setSheet($pValue = false) + { $this->_sheet = $pValue; return $this; } @@ -210,7 +213,8 @@ function setSheet($pValue = false) { * * @return boolean */ - function getObjects() { + function getObjects() + { return $this->_objects; } @@ -220,7 +224,8 @@ function getObjects() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setObjects($pValue = false) { + function setObjects($pValue = false) + { $this->_objects = $pValue; return $this; } @@ -230,7 +235,8 @@ function setObjects($pValue = false) { * * @return boolean */ - function getScenarios() { + function getScenarios() + { return $this->_scenarios; } @@ -240,7 +246,8 @@ function getScenarios() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setScenarios($pValue = false) { + function setScenarios($pValue = false) + { $this->_scenarios = $pValue; return $this; } @@ -250,7 +257,8 @@ function setScenarios($pValue = false) { * * @return boolean */ - function getFormatCells() { + function getFormatCells() + { return $this->_formatCells; } @@ -260,7 +268,8 @@ function getFormatCells() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setFormatCells($pValue = false) { + function setFormatCells($pValue = false) + { $this->_formatCells = $pValue; return $this; } @@ -270,7 +279,8 @@ function setFormatCells($pValue = false) { * * @return boolean */ - function getFormatColumns() { + function getFormatColumns() + { return $this->_formatColumns; } @@ -280,7 +290,8 @@ function getFormatColumns() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setFormatColumns($pValue = false) { + function setFormatColumns($pValue = false) + { $this->_formatColumns = $pValue; return $this; } @@ -290,7 +301,8 @@ function setFormatColumns($pValue = false) { * * @return boolean */ - function getFormatRows() { + function getFormatRows() + { return $this->_formatRows; } @@ -300,7 +312,8 @@ function getFormatRows() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setFormatRows($pValue = false) { + function setFormatRows($pValue = false) + { $this->_formatRows = $pValue; return $this; } @@ -310,7 +323,8 @@ function setFormatRows($pValue = false) { * * @return boolean */ - function getInsertColumns() { + function getInsertColumns() + { return $this->_insertColumns; } @@ -320,7 +334,8 @@ function getInsertColumns() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setInsertColumns($pValue = false) { + function setInsertColumns($pValue = false) + { $this->_insertColumns = $pValue; return $this; } @@ -330,7 +345,8 @@ function setInsertColumns($pValue = false) { * * @return boolean */ - function getInsertRows() { + function getInsertRows() + { return $this->_insertRows; } @@ -340,7 +356,8 @@ function getInsertRows() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setInsertRows($pValue = false) { + function setInsertRows($pValue = false) + { $this->_insertRows = $pValue; return $this; } @@ -350,7 +367,8 @@ function setInsertRows($pValue = false) { * * @return boolean */ - function getInsertHyperlinks() { + function getInsertHyperlinks() + { return $this->_insertHyperlinks; } @@ -360,7 +378,8 @@ function getInsertHyperlinks() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setInsertHyperlinks($pValue = false) { + function setInsertHyperlinks($pValue = false) + { $this->_insertHyperlinks = $pValue; return $this; } @@ -370,7 +389,8 @@ function setInsertHyperlinks($pValue = false) { * * @return boolean */ - function getDeleteColumns() { + function getDeleteColumns() + { return $this->_deleteColumns; } @@ -380,7 +400,8 @@ function getDeleteColumns() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setDeleteColumns($pValue = false) { + function setDeleteColumns($pValue = false) + { $this->_deleteColumns = $pValue; return $this; } @@ -390,7 +411,8 @@ function setDeleteColumns($pValue = false) { * * @return boolean */ - function getDeleteRows() { + function getDeleteRows() + { return $this->_deleteRows; } @@ -400,7 +422,8 @@ function getDeleteRows() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setDeleteRows($pValue = false) { + function setDeleteRows($pValue = false) + { $this->_deleteRows = $pValue; return $this; } @@ -410,7 +433,8 @@ function setDeleteRows($pValue = false) { * * @return boolean */ - function getSelectLockedCells() { + function getSelectLockedCells() + { return $this->_selectLockedCells; } @@ -420,7 +444,8 @@ function getSelectLockedCells() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setSelectLockedCells($pValue = false) { + function setSelectLockedCells($pValue = false) + { $this->_selectLockedCells = $pValue; return $this; } @@ -430,7 +455,8 @@ function setSelectLockedCells($pValue = false) { * * @return boolean */ - function getSort() { + function getSort() + { return $this->_sort; } @@ -440,7 +466,8 @@ function getSort() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setSort($pValue = false) { + function setSort($pValue = false) + { $this->_sort = $pValue; return $this; } @@ -450,7 +477,8 @@ function setSort($pValue = false) { * * @return boolean */ - function getAutoFilter() { + function getAutoFilter() + { return $this->_autoFilter; } @@ -460,7 +488,8 @@ function getAutoFilter() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setAutoFilter($pValue = false) { + function setAutoFilter($pValue = false) + { $this->_autoFilter = $pValue; return $this; } @@ -470,7 +499,8 @@ function setAutoFilter($pValue = false) { * * @return boolean */ - function getPivotTables() { + function getPivotTables() + { return $this->_pivotTables; } @@ -480,7 +510,8 @@ function getPivotTables() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setPivotTables($pValue = false) { + function setPivotTables($pValue = false) + { $this->_pivotTables = $pValue; return $this; } @@ -490,7 +521,8 @@ function setPivotTables($pValue = false) { * * @return boolean */ - function getSelectUnlockedCells() { + function getSelectUnlockedCells() + { return $this->_selectUnlockedCells; } @@ -500,7 +532,8 @@ function getSelectUnlockedCells() { * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setSelectUnlockedCells($pValue = false) { + function setSelectUnlockedCells($pValue = false) + { $this->_selectUnlockedCells = $pValue; return $this; } @@ -510,7 +543,8 @@ function setSelectUnlockedCells($pValue = false) { * * @return string */ - function getPassword() { + function getPassword() + { return $this->_password; } @@ -521,7 +555,8 @@ function getPassword() { * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true * @return PHPExcel_Worksheet_Protection */ - function setPassword($pValue = '', $pAlreadyHashed = false) { + function setPassword($pValue = '', $pAlreadyHashed = false) + { if (!$pAlreadyHashed) { $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); } @@ -532,7 +567,8 @@ function setPassword($pValue = '', $pAlreadyHashed = false) { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/Writer/Abstract.php b/Classes/PHPExcel/Writer/Abstract.php index 911dc5dda..a0f141002 100644 --- a/Classes/PHPExcel/Writer/Abstract.php +++ b/Classes/PHPExcel/Writer/Abstract.php @@ -65,7 +65,8 @@ abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter * * @return boolean */ - public function getIncludeCharts() { + public function getIncludeCharts() + { return $this->_includeCharts; } @@ -93,7 +94,8 @@ public function setIncludeCharts($pValue = false) * * @return boolean */ - public function getPreCalculateFormulas() { + public function getPreCalculateFormulas() + { return $this->_preCalculateFormulas; } @@ -105,7 +107,8 @@ public function getPreCalculateFormulas() { * @param boolean $pValue Pre-Calculate Formulas? * @return PHPExcel_Writer_IWriter */ - public function setPreCalculateFormulas($pValue = TRUE) { + public function setPreCalculateFormulas($pValue = true) + { $this->_preCalculateFormulas = (boolean) $pValue; return $this; } @@ -115,7 +118,8 @@ public function setPreCalculateFormulas($pValue = TRUE) { * * @return boolean */ - public function getUseDiskCaching() { + public function getUseDiskCaching() + { return $this->_useDiskCaching; } @@ -127,10 +131,11 @@ public function getUseDiskCaching() { * @throws PHPExcel_Writer_Exception when directory does not exist * @return PHPExcel_Writer_Excel2007 */ - public function setUseDiskCaching($pValue = FALSE, $pDirectory = NULL) { + public function setUseDiskCaching($pValue = false, $pDirectory = null) + { $this->_useDiskCaching = $pValue; - if ($pDirectory !== NULL) { + if ($pDirectory !== null) { if (is_dir($pDirectory)) { $this->_diskCachingDirectory = $pDirectory; } else { @@ -145,7 +150,8 @@ public function setUseDiskCaching($pValue = FALSE, $pDirectory = NULL) { * * @return string */ - public function getDiskCachingDirectory() { + public function getDiskCachingDirectory() + { return $this->_diskCachingDirectory; } } diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index 756bf4dcc..e7f26ff58 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -257,7 +257,7 @@ public function save($pFilename = null) if ($this->_spreadSheet->hasRibbonBinObjects()) { $tmpRootPath=dirname($tmpRibbonTarget).'/'; $ribbonBinObjects=$this->_spreadSheet->getRibbonBinObjects('data');//the files to write - foreach ($ribbonBinObjects as $aPath=>$aContent) { + foreach ($ribbonBinObjects as $aPath => $aContent) { $objZip->addFromString($tmpRootPath.$aPath, $aContent); } //the rels for files @@ -494,7 +494,7 @@ public function getBordersHashTable() * * @return PHPExcel_HashTable */ - public function getNumFmtHashTable() + public function getNumFmtHashTable() { return $this->_numFmtHashTable; } diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 93cff286b..6aefa80a1 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -32,7 +32,8 @@ * @package PHPExcel_Writer_Excel2007 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ -class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPart { +class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPart +{ /** * Write charts to XML format * @@ -41,7 +42,8 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeChart(PHPExcel_Chart $pChart = null) { + public function writeChart(PHPExcel_Chart $pChart = null) + { // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { @@ -115,7 +117,8 @@ public function writeChart(PHPExcel_Chart $pChart = null) { * * @throws PHPExcel_Writer_Exception */ - private function _writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) { + private function _writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) + { if (is_null($title)) { return; } @@ -159,7 +162,8 @@ private function _writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) { * * @throws PHPExcel_Writer_Exception */ - private function _writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) { + private function _writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) + { if (is_null($legend)) { return; } @@ -210,10 +214,10 @@ private function _writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) * @param PHPExcel_Chart_Axis $xAxis * @param PHPExcel_Chart_Axis $yAxis * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer - * + * * @throws PHPExcel_Writer_Exception */ - private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, $objWriter, PHPExcel_Worksheet $pSheet, PHPExcel_Chart_Axis $xAxis, PHPExcel_Chart_Axis $yAxis, PHPExcel_Chart_GridLines $majorGridlines, PHPExcel_Chart_GridLines $minorGridlines ) + private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, $objWriter, PHPExcel_Worksheet $pSheet, PHPExcel_Chart_Axis $xAxis, PHPExcel_Chart_Axis $yAxis, PHPExcel_Chart_GridLines $majorGridlines, PHPExcel_Chart_GridLines $minorGridlines) { if (is_null($plotArea)) { return; @@ -349,7 +353,8 @@ private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Char * * @throws PHPExcel_Writer_Exception */ - private function _writeDataLbls($objWriter, $chartLayout) { + private function _writeDataLbls($objWriter, $chartLayout) + { $objWriter->startElement('c:dLbls'); $objWriter->startElement('c:showLegendKey'); @@ -403,7 +408,8 @@ private function _writeDataLbls($objWriter, $chartLayout) { * * @throws PHPExcel_Writer_Exception */ - private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis) { + private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis) + { $objWriter->startElement('c:catAx'); if ($id1 > 0) { @@ -524,7 +530,8 @@ private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAx * * @throws PHPExcel_Writer_Exception */ - private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines) { + private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines) + { $objWriter->startElement('c:valAx'); if ($id2 > 0) { @@ -1004,7 +1011,8 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx * @return string|array * @throws PHPExcel_Writer_Exception */ - private static function _getChartType($plotArea) { + private static function _getChartType($plotArea) + { $groupCount = $plotArea->getPlotGroupCount(); if ($groupCount == 1) { @@ -1036,7 +1044,8 @@ private static function _getChartType($plotArea) { * * @throws PHPExcel_Writer_Exception */ - private function _writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType, PHPExcel_Worksheet $pSheet ) { + private function _writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType, PHPExcel_Worksheet $pSheet) + { if (is_null($plotGroup)) { return; } @@ -1209,7 +1218,8 @@ private function _writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMult * * @throws PHPExcel_Writer_Exception */ - private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) { + private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) + { if (is_null($plotSeriesLabel)) { return; } @@ -1246,7 +1256,8 @@ private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) { * * @throws PHPExcel_Writer_Exception */ - private function _writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, $dataType = 'str', PHPExcel_Worksheet $pSheet) { + private function _writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, $dataType = 'str', PHPExcel_Worksheet $pSheet) + { if (is_null($plotSeriesValues)) { return; } @@ -1337,7 +1348,8 @@ private function _writePlotSeriesValues($plotSeriesValues, $objWriter, $groupTyp * * @throws PHPExcel_Writer_Exception */ - private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) { + private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) + { if (is_null($plotSeriesValues)) { return; } @@ -1383,7 +1395,8 @@ private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet * * @throws PHPExcel_Writer_Exception */ - private function _writeLayout(PHPExcel_Chart_Layout $layout = null, $objWriter) { + private function _writeLayout(PHPExcel_Chart_Layout $layout = null, $objWriter) + { $objWriter->startElement('c:layout'); if (!is_null($layout)) { @@ -1451,7 +1464,8 @@ private function _writeLayout(PHPExcel_Chart_Layout $layout = null, $objWriter) * * @throws PHPExcel_Writer_Exception */ - private function _writeAlternateContent($objWriter) { + private function _writeAlternateContent($objWriter) + { $objWriter->startElement('mc:AlternateContent'); $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); @@ -1480,7 +1494,8 @@ private function _writeAlternateContent($objWriter) { * * @throws PHPExcel_Writer_Exception */ - private function _writePrintSettings($objWriter) { + private function _writePrintSettings($objWriter) + { $objWriter->startElement('c:printSettings'); $objWriter->startElement('c:headerFooter'); diff --git a/Classes/PHPExcel/Writer/Excel2007/Comments.php b/Classes/PHPExcel/Writer/Excel2007/Comments.php index 61ba4ad0b..95336e863 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Comments.php +++ b/Classes/PHPExcel/Writer/Excel2007/Comments.php @@ -71,19 +71,19 @@ public function writeComments(PHPExcel_Worksheet $pWorksheet = null) $objWriter->startElement('comments'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); - // Loop through authors - $objWriter->startElement('authors'); - foreach ($authors as $author => $index) { - $objWriter->writeElement('author', $author); - } - $objWriter->endElement(); + // Loop through authors + $objWriter->startElement('authors'); + foreach ($authors as $author => $index) { + $objWriter->writeElement('author', $author); + } + $objWriter->endElement(); - // Loop through comments - $objWriter->startElement('commentList'); - foreach ($comments as $key => $value) { - $this->_writeComment($objWriter, $key, $value, $authors); - } - $objWriter->endElement(); + // Loop through comments + $objWriter->startElement('commentList'); + foreach ($comments as $key => $value) { + $this->_writeComment($objWriter, $key, $value, $authors); + } + $objWriter->endElement(); $objWriter->endElement(); @@ -104,13 +104,13 @@ public function _writeComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCel { // comment $objWriter->startElement('comment'); - $objWriter->writeAttribute('ref', $pCellReference); - $objWriter->writeAttribute('authorId', $pAuthors[$pComment->getAuthor()]); + $objWriter->writeAttribute('ref', $pCellReference); + $objWriter->writeAttribute('authorId', $pAuthors[$pComment->getAuthor()]); - // text - $objWriter->startElement('text'); - $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText()); - $objWriter->endElement(); + // text + $objWriter->startElement('text'); + $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText()); + $objWriter->endElement(); $objWriter->endElement(); } @@ -144,42 +144,42 @@ public function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null) $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); - // o:shapelayout - $objWriter->startElement('o:shapelayout'); - $objWriter->writeAttribute('v:ext', 'edit'); - - // o:idmap - $objWriter->startElement('o:idmap'); - $objWriter->writeAttribute('v:ext', 'edit'); - $objWriter->writeAttribute('data', '1'); - $objWriter->endElement(); + // o:shapelayout + $objWriter->startElement('o:shapelayout'); + $objWriter->writeAttribute('v:ext', 'edit'); + // o:idmap + $objWriter->startElement('o:idmap'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('data', '1'); $objWriter->endElement(); - // v:shapetype - $objWriter->startElement('v:shapetype'); - $objWriter->writeAttribute('id', '_x0000_t202'); - $objWriter->writeAttribute('coordsize', '21600,21600'); - $objWriter->writeAttribute('o:spt', '202'); - $objWriter->writeAttribute('path', 'm,l,21600r21600,l21600,xe'); + $objWriter->endElement(); - // v:stroke - $objWriter->startElement('v:stroke'); - $objWriter->writeAttribute('joinstyle', 'miter'); - $objWriter->endElement(); + // v:shapetype + $objWriter->startElement('v:shapetype'); + $objWriter->writeAttribute('id', '_x0000_t202'); + $objWriter->writeAttribute('coordsize', '21600,21600'); + $objWriter->writeAttribute('o:spt', '202'); + $objWriter->writeAttribute('path', 'm,l,21600r21600,l21600,xe'); - // v:path - $objWriter->startElement('v:path'); - $objWriter->writeAttribute('gradientshapeok', 't'); - $objWriter->writeAttribute('o:connecttype', 'rect'); - $objWriter->endElement(); + // v:stroke + $objWriter->startElement('v:stroke'); + $objWriter->writeAttribute('joinstyle', 'miter'); + $objWriter->endElement(); + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('gradientshapeok', 't'); + $objWriter->writeAttribute('o:connecttype', 'rect'); $objWriter->endElement(); - // Loop through comments - foreach ($comments as $key => $value) { - $this->_writeVMLComment($objWriter, $key, $value); - } + $objWriter->endElement(); + + // Loop through comments + foreach ($comments as $key => $value) { + $this->_writeVMLComment($objWriter, $key, $value); + } $objWriter->endElement(); @@ -205,22 +205,22 @@ public function _writeVMLComment(PHPExcel_Shared_XMLWriter $objWriter = null, $p // v:shape $objWriter->startElement('v:shape'); - $objWriter->writeAttribute('id', '_x0000_s' . $id); - $objWriter->writeAttribute('type', '#_x0000_t202'); - $objWriter->writeAttribute('style', 'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden')); - $objWriter->writeAttribute('fillcolor', '#' . $pComment->getFillColor()->getRGB()); - $objWriter->writeAttribute('o:insetmode', 'auto'); + $objWriter->writeAttribute('id', '_x0000_s' . $id); + $objWriter->writeAttribute('type', '#_x0000_t202'); + $objWriter->writeAttribute('style', 'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden')); + $objWriter->writeAttribute('fillcolor', '#' . $pComment->getFillColor()->getRGB()); + $objWriter->writeAttribute('o:insetmode', 'auto'); // v:fill $objWriter->startElement('v:fill'); - $objWriter->writeAttribute('color2', '#' . $pComment->getFillColor()->getRGB()); + $objWriter->writeAttribute('color2', '#' . $pComment->getFillColor()->getRGB()); $objWriter->endElement(); // v:shadow $objWriter->startElement('v:shadow'); - $objWriter->writeAttribute('on', 't'); - $objWriter->writeAttribute('color', 'black'); - $objWriter->writeAttribute('obscured', 't'); + $objWriter->writeAttribute('on', 't'); + $objWriter->writeAttribute('color', 'black'); + $objWriter->writeAttribute('obscured', 't'); $objWriter->endElement(); // v:path diff --git a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php index 2ecf93200..ef5721339 100644 --- a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php +++ b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -60,125 +60,126 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f $objWriter->startElement('Types'); $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types'); - // Theme - $this->_writeOverrideContentType($objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml'); - - // Styles - $this->_writeOverrideContentType($objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'); - - // Rels - $this->_writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml'); - - // XML - $this->_writeDefaultContentType($objWriter, 'xml', 'application/xml'); - - // VML - $this->_writeDefaultContentType($objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'); - - // Workbook - if ($pPHPExcel->hasMacros()) { //Macros in workbook ? - // Yes : not standard content but "macroEnabled" - $this->_writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml'); - //... and define a new type for the VBA project - $this->_writeDefaultContentType($objWriter, 'bin', 'application/vnd.ms-office.vbaProject'); - if ($pPHPExcel->hasMacrosCertificate()) {// signed macros ? - // Yes : add needed information - $this->_writeOverrideContentType($objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature'); - } - } else {// no macros in workbook, so standard type - $this->_writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'); + // Theme + $this->_writeOverrideContentType($objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml'); + + // Styles + $this->_writeOverrideContentType($objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'); + + // Rels + $this->_writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml'); + + // XML + $this->_writeDefaultContentType($objWriter, 'xml', 'application/xml'); + + // VML + $this->_writeDefaultContentType($objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'); + + // Workbook + if ($pPHPExcel->hasMacros()) { //Macros in workbook ? + // Yes : not standard content but "macroEnabled" + $this->_writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml'); + //... and define a new type for the VBA project + $this->_writeDefaultContentType($objWriter, 'bin', 'application/vnd.ms-office.vbaProject'); + if ($pPHPExcel->hasMacrosCertificate()) {// signed macros ? + // Yes : add needed information + $this->_writeOverrideContentType($objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature'); } + } else {// no macros in workbook, so standard type + $this->_writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'); + } - // DocProps - $this->_writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml'); + // DocProps + $this->_writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml'); - $this->_writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml'); + $this->_writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml'); - $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); - if (!empty($customPropertyList)) { - $this->_writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml'); - } + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (!empty($customPropertyList)) { + $this->_writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml'); + } - // Worksheets - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - $this->_writeOverrideContentType($objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'); - } + // Worksheets + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $this->_writeOverrideContentType($objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'); + } - // Shared strings - $this->_writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'); + // Shared strings + $this->_writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'); - // Add worksheet relationship content types - $chart = 1; - for ($i = 0; $i < $sheetCount; ++$i) { - $drawings = $pPHPExcel->getSheet($i)->getDrawingCollection(); - $drawingCount = count($drawings); - $chartCount = ($includeCharts) ? $pPHPExcel->getSheet($i)->getChartCount() : 0; + // Add worksheet relationship content types + $chart = 1; + for ($i = 0; $i < $sheetCount; ++$i) { + $drawings = $pPHPExcel->getSheet($i)->getDrawingCollection(); + $drawingCount = count($drawings); + $chartCount = ($includeCharts) ? $pPHPExcel->getSheet($i)->getChartCount() : 0; - // We need a drawing relationship for the worksheet if we have either drawings or charts - if (($drawingCount > 0) || ($chartCount > 0)) { - $this->_writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml'); - } + // We need a drawing relationship for the worksheet if we have either drawings or charts + if (($drawingCount > 0) || ($chartCount > 0)) { + $this->_writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml'); + } - // If we have charts, then we need a chart relationship for every individual chart - if ($chartCount > 0) { - for ($c = 0; $c < $chartCount; ++$c) { - $this->_writeOverrideContentType($objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); - } + // If we have charts, then we need a chart relationship for every individual chart + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeOverrideContentType($objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); } } + } - // Comments - for ($i = 0; $i < $sheetCount; ++$i) { - if (count($pPHPExcel->getSheet($i)->getComments()) > 0) { - $this->_writeOverrideContentType($objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'); - } + // Comments + for ($i = 0; $i < $sheetCount; ++$i) { + if (count($pPHPExcel->getSheet($i)->getComments()) > 0) { + $this->_writeOverrideContentType($objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'); } + } - // Add media content-types - $aMediaContentTypes = array(); - $mediaCount = $this->getParentWriter()->getDrawingHashTable()->count(); - for ($i = 0; $i < $mediaCount; ++$i) { - $extension = ''; - $mimeType = ''; - - if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { - $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); - $mimeType = $this->_getImageMimeType( $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath() ); - } else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { - $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); - $extension = explode('/', $extension); - $extension = $extension[1]; - - $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType(); - } + // Add media content-types + $aMediaContentTypes = array(); + $mediaCount = $this->getParentWriter()->getDrawingHashTable()->count(); + for ($i = 0; $i < $mediaCount; ++$i) { + $extension = ''; + $mimeType = ''; + + if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { + $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); + $mimeType = $this->_getImageMimeType( $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath()); + } else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { + $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); + $extension = explode('/', $extension); + $extension = $extension[1]; + + $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType(); + } - if (!isset( $aMediaContentTypes[$extension]) ) { - $aMediaContentTypes[$extension] = $mimeType; + if (!isset( $aMediaContentTypes[$extension])) { + $aMediaContentTypes[$extension] = $mimeType; - $this->_writeDefaultContentType($objWriter, $extension, $mimeType); - } + $this->_writeDefaultContentType($objWriter, $extension, $mimeType); } - if ($pPHPExcel->hasRibbonBinObjects()) {//Some additional objects in the ribbon ? - //we need to write "Extension" but not already write for media content - $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); - foreach ($tabRibbonTypes as $aRibbonType) { - $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor - $this->_writeDefaultContentType($objWriter, $aRibbonType, $mimeType); - } + } + if ($pPHPExcel->hasRibbonBinObjects()) { + // Some additional objects in the ribbon ? + // we need to write "Extension" but not already write for media content + $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); + foreach ($tabRibbonTypes as $aRibbonType) { + $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor + $this->_writeDefaultContentType($objWriter, $aRibbonType, $mimeType); } - $sheetCount = $pPHPExcel->getSheetCount(); - for ($i = 0; $i < $sheetCount; ++$i) { - if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) { - foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) { - if (!isset( $aMediaContentTypes[strtolower($image->getExtension())])) { - $aMediaContentTypes[strtolower($image->getExtension())] = $this->_getImageMimeType($image->getPath()); - - $this->_writeDefaultContentType($objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())]); - } + } + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) { + foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) { + if (!isset( $aMediaContentTypes[strtolower($image->getExtension())])) { + $aMediaContentTypes[strtolower($image->getExtension())] = $this->_getImageMimeType($image->getPath()); + + $this->_writeDefaultContentType($objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())]); } } } + } $objWriter->endElement(); diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index 176e44b13..cb153f8ae 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -231,7 +231,7 @@ private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, P // View Layout Type if ($pSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL) { - $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView()); + $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView()); } // Gridlines @@ -294,15 +294,15 @@ private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, P // Selection // if ($pane != '') { - // Only need to write selection element if we have a split pane - // We cheat a little by over-riding the active cell selection, setting it to the split cell - $objWriter->startElement('selection'); - if ($pane != '') { - $objWriter->writeAttribute('pane', $pane); - } - $objWriter->writeAttribute('activeCell', $activeCell); - $objWriter->writeAttribute('sqref', $activeCell); - $objWriter->endElement(); + // Only need to write selection element if we have a split pane + // We cheat a little by over-riding the active cell selection, setting it to the split cell + $objWriter->startElement('selection'); + if ($pane != '') { + $objWriter->writeAttribute('pane', $pane); + } + $objWriter->writeAttribute('activeCell', $activeCell); + $objWriter->writeAttribute('sqref', $activeCell); + $objWriter->endElement(); // } $objWriter->endElement(); @@ -760,7 +760,7 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P $range = PHPExcel_Cell::splitRange($autoFilterRange); $range = $range[0]; // Strip any worksheet ref - if (strpos($range[0],'!') !== false) { + if (strpos($range[0], '!') !== false) { list($ws, $range[0]) = explode('!', $range[0]); } $range = implode(':', $range); @@ -785,7 +785,7 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P ($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) && ($rule->getValue() === '')) { // Filter rule for Blanks - $objWriter->writeAttribute('blank', 1); + $objWriter->writeAttribute('blank', 1); } elseif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { // Dynamic Filter Rule $objWriter->writeAttribute('type', $rule->getGrouping()); @@ -812,7 +812,9 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { // Date Group filters foreach ($rule->getValue() as $key => $value) { - if ($value > '') $objWriter->writeAttribute($key, $value); + if ($value > '') { + $objWriter->writeAttribute($key, $value); + } } $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); } else { From 121eccd4c8a5b8f43dfc62a2ad7d4200eec0a445 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Fri, 15 May 2015 13:36:15 +0200 Subject: [PATCH 373/467] PSR-2 : Fixes --- Classes/PHPExcel/Worksheet/AutoFilter.php | 194 ++++++++---------- .../PHPExcel/Worksheet/AutoFilter/Column.php | 4 +- .../Worksheet/AutoFilter/Column/Rule.php | 2 +- .../PHPExcel/Worksheet/ColumnDimension.php | 1 - Classes/PHPExcel/Worksheet/Drawing.php | 23 ++- Classes/PHPExcel/Worksheet/Drawing/Shadow.php | 64 +++--- Classes/PHPExcel/Worksheet/HeaderFooter.php | 99 ++++++--- Classes/PHPExcel/Worksheet/MemoryDrawing.php | 3 +- Classes/PHPExcel/Worksheet/PageSetup.php | 101 +++++---- Classes/PHPExcel/Writer/Excel2007/Chart.php | 2 +- .../Writer/Excel2007/ContentTypes.php | 2 +- 11 files changed, 283 insertions(+), 212 deletions(-) diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index 325c906d6..36407e6e5 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -40,7 +40,7 @@ class PHPExcel_Worksheet_AutoFilter * * @var PHPExcel_Worksheet */ - private $_workSheet = NULL; + private $_workSheet = null; /** @@ -65,7 +65,7 @@ class PHPExcel_Worksheet_AutoFilter * @param string $pRange Cell range (i.e. A1:E10) * @param PHPExcel_Worksheet $pSheet */ - public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = NULL) + public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = null) { $this->_range = $pRange; $this->_workSheet = $pSheet; @@ -76,7 +76,8 @@ public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = NULL) * * @return PHPExcel_Worksheet */ - public function getParent() { + public function getParent() + { return $this->_workSheet; } @@ -86,7 +87,8 @@ public function getParent() { * @param PHPExcel_Worksheet $pSheet * @return PHPExcel_Worksheet_AutoFilter */ - public function setParent(PHPExcel_Worksheet $pSheet = NULL) { + public function setParent(PHPExcel_Worksheet $pSheet = null) + { $this->_workSheet = $pSheet; return $this; @@ -97,7 +99,8 @@ public function setParent(PHPExcel_Worksheet $pSheet = NULL) { * * @return string */ - public function getRange() { + public function getRange() + { return $this->_range; } @@ -108,14 +111,15 @@ public function getRange() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter */ - public function setRange($pRange = '') { + public function setRange($pRange = '') + { // Uppercase coordinate $cellAddress = explode('!',strtoupper($pRange)); if (count($cellAddress) > 1) { list($worksheet, $pRange) = $cellAddress; } - if (strpos($pRange,':') !== FALSE) { + if (strpos($pRange, ':') !== false) { $this->_range = $pRange; } elseif (empty($pRange)) { $this->_range = ''; @@ -146,7 +150,8 @@ public function setRange($pRange = '') { * @throws PHPExcel_Exception * @return array of PHPExcel_Worksheet_AutoFilter_Column */ - public function getColumns() { + public function getColumns() + { return $this->_columns; } @@ -157,7 +162,8 @@ public function getColumns() { * @throws PHPExcel_Exception * @return integer The column offset within the autofilter range */ - public function testColumnInRange($column) { + public function testColumnInRange($column) + { if (empty($this->_range)) { throw new PHPExcel_Exception("No autofilter range is defined."); } @@ -178,7 +184,8 @@ public function testColumnInRange($column) { * @throws PHPExcel_Exception * @return integer The offset of the specified column within the autofilter range */ - public function getColumnOffset($pColumn) { + public function getColumnOffset($pColumn) + { return $this->testColumnInRange($pColumn); } @@ -189,7 +196,8 @@ public function getColumnOffset($pColumn) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function getColumn($pColumn) { + public function getColumn($pColumn) + { $this->testColumnInRange($pColumn); if (!isset($this->_columns[$pColumn])) { @@ -206,7 +214,8 @@ public function getColumn($pColumn) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter_Column */ - public function getColumnByOffset($pColumnOffset = 0) { + public function getColumnByOffset($pColumnOffset = 0) + { list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); $pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1); @@ -250,7 +259,8 @@ public function setColumn($pColumn) * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_AutoFilter */ - public function clearColumn($pColumn) { + public function clearColumn($pColumn) + { $this->testColumnInRange($pColumn); if (isset($this->_columns[$pColumn])) { @@ -271,11 +281,12 @@ public function clearColumn($pColumn) { * @param string $toColumn Column name (e.g. B) * @return PHPExcel_Worksheet_AutoFilter */ - public function shiftColumn($fromColumn=NULL, $toColumn=NULL) { + public function shiftColumn($fromColumn = null, $toColumn = null) + { $fromColumn = strtoupper($fromColumn); $toColumn = strtoupper($toColumn); - if (($fromColumn !== NULL) && (isset($this->_columns[$fromColumn])) && ($toColumn !== NULL)) { + if (($fromColumn !== null) && (isset($this->_columns[$fromColumn])) && ($toColumn !== null)) { $this->_columns[$fromColumn]->setParent(); $this->_columns[$fromColumn]->setColumnIndex($toColumn); $this->_columns[$toColumn] = $this->_columns[$fromColumn]; @@ -300,7 +311,7 @@ private static function _filterTestInSimpleDataSet($cellValue, $dataSet) { $dataSetValues = $dataSet['filterValues']; $blanks = $dataSet['blanks']; - if (($cellValue == '') || ($cellValue === NULL)) { + if (($cellValue == '') || ($cellValue === null)) { return $blanks; } return in_array($cellValue, $dataSetValues); @@ -317,7 +328,7 @@ private static function _filterTestInDateGroupSet($cellValue, $dataSet) { $dateSet = $dataSet['filterValues']; $blanks = $dataSet['blanks']; - if (($cellValue == '') || ($cellValue === NULL)) { + if (($cellValue == '') || ($cellValue === null)) { return $blanks; } @@ -338,12 +349,12 @@ private static function _filterTestInDateGroupSet($cellValue, $dataSet) } foreach ($dateSet as $dateValue) { // Use of substr to extract value at the appropriate group level - if (substr($dtVal,0,strlen($dateValue)) == $dateValue) - return TRUE; + if (substr($dtVal,0,strlen($dateValue)) == $dateValue) { + return true; + } } } - - return FALSE; + return false; } /** @@ -357,12 +368,12 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) { $dataSet = $ruleSet['filterRules']; $join = $ruleSet['join']; - $customRuleForBlanks = isset($ruleSet['customRuleForBlanks']) ? $ruleSet['customRuleForBlanks'] : FALSE; + $customRuleForBlanks = isset($ruleSet['customRuleForBlanks']) ? $ruleSet['customRuleForBlanks'] : false; if (!$customRuleForBlanks) { // Blank cells are always ignored, so return a FALSE - if (($cellValue == '') || ($cellValue === NULL)) { - return FALSE; + if (($cellValue == '') || ($cellValue === null)) { + return false; } } $returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); @@ -392,13 +403,13 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) } elseif ($rule['value'] == '') { switch ($rule['operator']) { case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : - $retVal = (($cellValue == '') || ($cellValue === NULL)); + $retVal = (($cellValue == '') || ($cellValue === null)); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : - $retVal = (($cellValue != '') && ($cellValue !== NULL)); + $retVal = (($cellValue != '') && ($cellValue !== null)); break; default : - $retVal = TRUE; + $retVal = true; break; } } else { @@ -411,8 +422,9 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) $returnVal = $returnVal || $retVal; // Break as soon as we have a TRUE match for OR joins, // to avoid unnecessary additional code execution - if ($returnVal) + if ($returnVal) { return $returnVal; + } break; case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND : $returnVal = $returnVal && $retVal; @@ -433,18 +445,18 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) private static function _filterTestInPeriodDateSet($cellValue, $monthSet) { // Blank cells are always ignored, so return a FALSE - if (($cellValue == '') || ($cellValue === NULL)) { - return FALSE; + if (($cellValue == '') || ($cellValue === null)) { + return false; } if (is_numeric($cellValue)) { $dateValue = date('m',PHPExcel_Shared_Date::ExcelToPHP($cellValue)); if (in_array($dateValue, $monthSet)) { - return TRUE; + return true; } } - return FALSE; + return false; } /** @@ -467,7 +479,7 @@ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) { $rDateType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $val = $maxVal = NULL; + $val = $maxVal = null; $ruleValues = array(); $baseDate = PHPExcel_Calculation_DateTime::DATENOW(); @@ -480,22 +492,22 @@ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) $baseDate = strtotime('-7 days', $baseDate); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : - $baseDate = strtotime('-1 month',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); + $baseDate = strtotime('-1 month',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : - $baseDate = strtotime('+1 month',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); + $baseDate = strtotime('+1 month',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : - $baseDate = strtotime('-3 month',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); + $baseDate = strtotime('-3 month',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : - $baseDate = strtotime('+3 month',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); + $baseDate = strtotime('+3 month',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : - $baseDate = strtotime('-1 year',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); + $baseDate = strtotime('-1 year',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : - $baseDate = strtotime('+1 year',gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); + $baseDate = strtotime('+1 year',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; } @@ -508,30 +520,30 @@ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE : $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day', $baseDate)); - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y', $baseDate))); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1, date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : - $maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,31,12,date('Y', $baseDate))); + $maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 31, 12, date('Y', $baseDate))); ++$maxVal; - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y', $baseDate))); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1, date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : $thisMonth = date('m', $baseDate); $thisQuarter = floor(--$thisMonth / 3); - $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t', $baseDate),(1+$thisQuarter)*3,date('Y', $baseDate))); + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0, 0, 0, date('t', $baseDate), (1+$thisQuarter)*3, date('Y', $baseDate))); ++$maxVal; - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1+$thisQuarter*3,date('Y', $baseDate))); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1+$thisQuarter*3, date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : - $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t', $baseDate),date('m', $baseDate),date('Y', $baseDate))); + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0, 0, 0, date('t', $baseDate), date('m', $baseDate), date('Y', $baseDate))); ++$maxVal; - $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,date('m', $baseDate),date('Y', $baseDate))); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK : case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : @@ -555,33 +567,20 @@ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) } // Set the filter column rule attributes ready for writing - $filterColumn->setAttributes(array( 'val' => $val, - 'maxVal' => $maxVal - ) - ); + $filterColumn->setAttributes(array('val' => $val, 'maxVal' => $maxVal)); // Set the rules for identifying rows for hide/show - $ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, - 'value' => $val - ); - $ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, - 'value' => $maxVal - ); + $ruleValues[] = array('operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, 'value' => $val); + $ruleValues[] = array('operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, 'value' => $maxVal); PHPExcel_Calculation_Functions::setReturnDateType($rDateType); - return array( - 'method' => '_filterTestInCustomDataSet', - 'arguments' => array( 'filterRules' => $ruleValues, - 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND - ) - ); + return array('method' => '_filterTestInCustomDataSet', 'arguments' => array('filterRules' => $ruleValues, 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND)); } - private function _calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, $ruleValue) { + private function _calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, $ruleValue) + { $range = $columnID.$startRow.':'.$columnID.$endRow; - $dataValues = PHPExcel_Calculation_Functions::flattenArray( - $this->_workSheet->rangeToArray($range,NULL,TRUE,FALSE) - ); + $dataValues = PHPExcel_Calculation_Functions::flattenArray($this->_workSheet->rangeToArray($range, null, true, false)); $dataValues = array_filter($dataValues); if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) { @@ -605,7 +604,7 @@ public function showHideRows() // The heading row should always be visible // echo 'AutoFilter Heading Row ', $rangeStart[1],' is always SHOWN',PHP_EOL; - $this->_workSheet->getRowDimension($rangeStart[1])->setVisible(TRUE); + $this->_workSheet->getRowDimension($rangeStart[1])->setVisible(true); $columnFilterTests = array(); foreach ($this->_columns as $columnID => $filterColumn) { @@ -619,17 +618,15 @@ public function showHideRows() $ruleValues[] = $rule->getValue(); } // Test if we want to include blanks in our filter criteria - $blanks = FALSE; + $blanks = false; $ruleDataSet = array_filter($ruleValues); if (count($ruleValues) != count($ruleDataSet)) - $blanks = TRUE; + $blanks = true; if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) { // Filter on absolute values $columnFilterTests[$columnID] = array( 'method' => '_filterTestInSimpleDataSet', - 'arguments' => array( 'filterValues' => $ruleDataSet, - 'blanks' => $blanks - ) + 'arguments' => array('filterValues' => $ruleDataSet, 'blanks' => $blanks) ); } else { // Filter on date group values @@ -669,14 +666,12 @@ public function showHideRows() $arguments['dateTime'] = array_filter($arguments['dateTime']); $columnFilterTests[$columnID] = array( 'method' => '_filterTestInDateGroupSet', - 'arguments' => array( 'filterValues' => $arguments, - 'blanks' => $blanks - ) + 'arguments' => array('filterValues' => $arguments, 'blanks' => $blanks) ); } break; case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER : - $customRuleForBlanks = FALSE; + $customRuleForBlanks = false; $ruleValues = array(); // Build a list of the filter value selections foreach ($rules as $rule) { @@ -687,21 +682,16 @@ public function showHideRows() $ruleValue = preg_quote($ruleValue); $ruleValue = str_replace(self::$_fromReplace,self::$_toReplace, $ruleValue); if (trim($ruleValue) == '') { - $customRuleForBlanks = TRUE; + $customRuleForBlanks = true; $ruleValue = trim($ruleValue); } } - $ruleValues[] = array( 'operator' => $rule->getOperator(), - 'value' => $ruleValue - ); + $ruleValues[] = array('operator' => $rule->getOperator(), 'value' => $ruleValue); } $join = $filterColumn->getJoin(); $columnFilterTests[$columnID] = array( 'method' => '_filterTestInCustomDataSet', - 'arguments' => array( 'filterRules' => $ruleValues, - 'join' => $join, - 'customRuleForBlanks' => $customRuleForBlanks - ) + 'arguments' => array('filterRules' => $ruleValues, 'join' => $join, 'customRuleForBlanks' => $customRuleForBlanks) ); break; case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER : @@ -714,19 +704,17 @@ public function showHideRows() // Number (Average) based // Calculate the average $averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')'; - $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,NULL, $this->_workSheet->getCell('A1')); + $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,null, $this->_workSheet->getCell('A1')); // Set above/below rule based on greaterThan or LessTan $operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN; - $ruleValues[] = array( 'operator' => $operator, + $ruleValues[] = array('operator' => $operator, 'value' => $average ); $columnFilterTests[$columnID] = array( 'method' => '_filterTestInCustomDataSet', - 'arguments' => array( 'filterRules' => $ruleValues, - 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR - ) + 'arguments' => array('filterRules' => $ruleValues, 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR) ); } else { // Date based @@ -774,18 +762,12 @@ public function showHideRows() $operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL; - $ruleValues[] = array( 'operator' => $operator, - 'value' => $maxVal - ); + $ruleValues[] = array('operator' => $operator, 'value' => $maxVal); $columnFilterTests[$columnID] = array( 'method' => '_filterTestInCustomDataSet', - 'arguments' => array( 'filterRules' => $ruleValues, - 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR - ) - ); - $filterColumn->setAttributes( - array('maxVal' => $maxVal) + 'arguments' => array('filterRules' => $ruleValues, 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR) ); + $filterColumn->setAttributes(array('maxVal' => $maxVal)); break; } } @@ -796,7 +778,7 @@ public function showHideRows() // Execute the column tests for each row in the autoFilter range to determine show/hide, for ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) { // echo 'Testing Row = ', $row,PHP_EOL; - $result = TRUE; + $result = true; foreach ($columnFilterTests as $columnID => $columnFilterTest) { // echo 'Testing cell ', $columnID.$row,PHP_EOL; $cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue(); @@ -805,15 +787,13 @@ public function showHideRows() $result = $result && call_user_func_array( array('PHPExcel_Worksheet_AutoFilter', $columnFilterTest['method']), - array( - $cellValue, - $columnFilterTest['arguments'] - ) + array($cellValue, $columnFilterTest['arguments']) ); // echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL; // If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests - if (!$result) + if (!$result) { break; + } } // Set show/hide for the row based on the result of the autoFilter result // echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL; @@ -827,13 +807,14 @@ public function showHideRows() /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { if ($key == '_workSheet') { // Detach from worksheet - $this->{$key} = NULL; + $this->{$key} = null; } else { $this->{$key} = clone $value; } @@ -858,5 +839,4 @@ public function __clone() { public function __toString() { return (string) $this->_range; } - } diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php index 9f705cabc..e30cb3cdf 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php @@ -220,7 +220,8 @@ public function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER) * * @return string */ - public function getJoin() { + public function getJoin() + { return $this->_join; } @@ -409,5 +410,4 @@ public function __clone() } } } - } diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php index e31c9cfca..2250bcde8 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -333,7 +333,7 @@ public function setValue($pValue = '') unset($pValue[$key]); } else { // Work out what the dateTime grouping will be - $grouping = max($grouping, array_search($key,self::$_dateTimeGroups)); + $grouping = max($grouping, array_search($key, self::$_dateTimeGroups)); } } if (count($pValue) == 0) { diff --git a/Classes/PHPExcel/Worksheet/ColumnDimension.php b/Classes/PHPExcel/Worksheet/ColumnDimension.php index 05be76fac..fe007c819 100644 --- a/Classes/PHPExcel/Worksheet/ColumnDimension.php +++ b/Classes/PHPExcel/Worksheet/ColumnDimension.php @@ -267,5 +267,4 @@ public function __clone() } } } - } diff --git a/Classes/PHPExcel/Worksheet/Drawing.php b/Classes/PHPExcel/Worksheet/Drawing.php index 7f9dfd55d..983bda48e 100644 --- a/Classes/PHPExcel/Worksheet/Drawing.php +++ b/Classes/PHPExcel/Worksheet/Drawing.php @@ -59,7 +59,8 @@ public function __construct() * * @return string */ - public function getFilename() { + public function getFilename() + { return basename($this->_path); } @@ -68,7 +69,8 @@ public function getFilename() { * * @return string */ - public function getIndexedFilename() { + public function getIndexedFilename() + { $fileName = $this->getFilename(); $fileName = str_replace(' ', '_', $fileName); return str_replace('.' . $this->getExtension(), '', $fileName) . $this->getImageIndex() . '.' . $this->getExtension(); @@ -79,7 +81,8 @@ public function getIndexedFilename() { * * @return string */ - public function getExtension() { + public function getExtension() + { $exploded = explode(".", basename($this->_path)); return $exploded[count($exploded) - 1]; } @@ -89,7 +92,8 @@ public function getExtension() { * * @return string */ - public function getPath() { + public function getPath() + { return $this->_path; } @@ -101,7 +105,8 @@ public function getPath() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_Drawing */ - public function setPath($pValue = '', $pVerifyFile = true) { + public function setPath($pValue = '', $pVerifyFile = true) + { if ($pVerifyFile) { if (file_exists($pValue)) { $this->_path = $pValue; @@ -124,9 +129,10 @@ public function setPath($pValue = '', $pVerifyFile = true) { * * @return string Hash code */ - public function getHashCode() { + public function getHashCode() + { return md5( - $this->_path + $this->_path . parent::getHashCode() . __CLASS__ ); @@ -135,7 +141,8 @@ public function getHashCode() { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php index 8776745f0..9806bb903 100644 --- a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php +++ b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php @@ -104,13 +104,13 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable public function __construct() { // Initialise values - $this->_visible = false; - $this->_blurRadius = 6; - $this->_distance = 2; - $this->_direction = 0; - $this->_alignment = PHPExcel_Worksheet_Drawing_Shadow::SHADOW_BOTTOM_RIGHT; - $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK); - $this->_alpha = 50; + $this->_visible = false; + $this->_blurRadius = 6; + $this->_distance = 2; + $this->_direction = 0; + $this->_alignment = PHPExcel_Worksheet_Drawing_Shadow::SHADOW_BOTTOM_RIGHT; + $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK); + $this->_alpha = 50; } /** @@ -118,7 +118,8 @@ public function __construct() * * @return boolean */ - public function getVisible() { + public function getVisible() + { return $this->_visible; } @@ -128,7 +129,8 @@ public function getVisible() { * @param boolean $pValue * @return PHPExcel_Worksheet_Drawing_Shadow */ - public function setVisible($pValue = false) { + public function setVisible($pValue = false) + { $this->_visible = $pValue; return $this; } @@ -138,7 +140,8 @@ public function setVisible($pValue = false) { * * @return int */ - public function getBlurRadius() { + public function getBlurRadius() + { return $this->_blurRadius; } @@ -148,7 +151,8 @@ public function getBlurRadius() { * @param int $pValue * @return PHPExcel_Worksheet_Drawing_Shadow */ - public function setBlurRadius($pValue = 6) { + public function setBlurRadius($pValue = 6) + { $this->_blurRadius = $pValue; return $this; } @@ -158,7 +162,8 @@ public function setBlurRadius($pValue = 6) { * * @return int */ - public function getDistance() { + public function getDistance() + { return $this->_distance; } @@ -168,7 +173,8 @@ public function getDistance() { * @param int $pValue * @return PHPExcel_Worksheet_Drawing_Shadow */ - public function setDistance($pValue = 2) { + public function setDistance($pValue = 2) + { $this->_distance = $pValue; return $this; } @@ -178,7 +184,8 @@ public function setDistance($pValue = 2) { * * @return int */ - public function getDirection() { + public function getDirection() + { return $this->_direction; } @@ -188,7 +195,8 @@ public function getDirection() { * @param int $pValue * @return PHPExcel_Worksheet_Drawing_Shadow */ - public function setDirection($pValue = 0) { + public function setDirection($pValue = 0) + { $this->_direction = $pValue; return $this; } @@ -198,7 +206,8 @@ public function setDirection($pValue = 0) { * * @return int */ - public function getAlignment() { + public function getAlignment() + { return $this->_alignment; } @@ -208,7 +217,8 @@ public function getAlignment() { * @param int $pValue * @return PHPExcel_Worksheet_Drawing_Shadow */ - public function setAlignment($pValue = 0) { + public function setAlignment($pValue = 0) + { $this->_alignment = $pValue; return $this; } @@ -218,7 +228,8 @@ public function setAlignment($pValue = 0) { * * @return PHPExcel_Style_Color */ - public function getColor() { + public function getColor() + { return $this->_color; } @@ -229,7 +240,8 @@ public function getColor() { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_Drawing_Shadow */ - public function setColor(PHPExcel_Style_Color $pValue = null) { + public function setColor(PHPExcel_Style_Color $pValue = null) + { $this->_color = $pValue; return $this; } @@ -239,7 +251,8 @@ public function setColor(PHPExcel_Style_Color $pValue = null) { * * @return int */ - public function getAlpha() { + public function getAlpha() + { return $this->_alpha; } @@ -249,7 +262,8 @@ public function getAlpha() { * @param int $pValue * @return PHPExcel_Worksheet_Drawing_Shadow */ - public function setAlpha($pValue = 0) { + public function setAlpha($pValue = 0) + { $this->_alpha = $pValue; return $this; } @@ -259,9 +273,10 @@ public function setAlpha($pValue = 0) { * * @return string Hash code */ - public function getHashCode() { + public function getHashCode() + { return md5( - ($this->_visible ? 't' : 'f') + ($this->_visible ? 't' : 'f') . $this->_blurRadius . $this->_distance . $this->_direction @@ -275,7 +290,8 @@ public function getHashCode() { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/Worksheet/HeaderFooter.php b/Classes/PHPExcel/Worksheet/HeaderFooter.php index 3d2271aba..f4ba2a422 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooter.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooter.php @@ -192,7 +192,8 @@ public function __construct() * * @return string */ - public function getOddHeader() { + public function getOddHeader() + { return $this->_oddHeader; } @@ -202,7 +203,8 @@ public function getOddHeader() { * @param string $pValue * @return PHPExcel_Worksheet_HeaderFooter */ - public function setOddHeader($pValue) { + public function setOddHeader($pValue) + { $this->_oddHeader = $pValue; return $this; } @@ -212,7 +214,8 @@ public function setOddHeader($pValue) { * * @return string */ - public function getOddFooter() { + public function getOddFooter() + { return $this->_oddFooter; } @@ -222,7 +225,8 @@ public function getOddFooter() { * @param string $pValue * @return PHPExcel_Worksheet_HeaderFooter */ - public function setOddFooter($pValue) { + public function setOddFooter($pValue) + { $this->_oddFooter = $pValue; return $this; } @@ -232,7 +236,8 @@ public function setOddFooter($pValue) { * * @return string */ - public function getEvenHeader() { + public function getEvenHeader() + return $this->_evenHeader; } @@ -242,7 +247,8 @@ public function getEvenHeader() { * @param string $pValue * @return PHPExcel_Worksheet_HeaderFooter */ - public function setEvenHeader($pValue) { + public function setEvenHeader($pValue) + { $this->_evenHeader = $pValue; return $this; } @@ -252,7 +258,8 @@ public function setEvenHeader($pValue) { * * @return string */ - public function getEvenFooter() { + public function getEvenFooter() + { return $this->_evenFooter; } @@ -262,7 +269,8 @@ public function getEvenFooter() { * @param string $pValue * @return PHPExcel_Worksheet_HeaderFooter */ - public function setEvenFooter($pValue) { + public function setEvenFooter($pValue) + { $this->_evenFooter = $pValue; return $this; } @@ -272,7 +280,8 @@ public function setEvenFooter($pValue) { * * @return string */ - public function getFirstHeader() { + public function getFirstHeader() + { return $this->_firstHeader; } @@ -282,7 +291,8 @@ public function getFirstHeader() { * @param string $pValue * @return PHPExcel_Worksheet_HeaderFooter */ - public function setFirstHeader($pValue) { + public function setFirstHeader($pValue) + { $this->_firstHeader = $pValue; return $this; } @@ -292,7 +302,8 @@ public function setFirstHeader($pValue) { * * @return string */ - public function getFirstFooter() { + public function getFirstFooter() + { return $this->_firstFooter; } @@ -302,7 +313,8 @@ public function getFirstFooter() { * @param string $pValue * @return PHPExcel_Worksheet_HeaderFooter */ - public function setFirstFooter($pValue) { + public function setFirstFooter($pValue) + { $this->_firstFooter = $pValue; return $this; } @@ -312,7 +324,8 @@ public function setFirstFooter($pValue) { * * @return boolean */ - public function getDifferentOddEven() { + public function getDifferentOddEven() + { return $this->_differentOddEven; } @@ -322,7 +335,8 @@ public function getDifferentOddEven() { * @param boolean $pValue * @return PHPExcel_Worksheet_HeaderFooter */ - public function setDifferentOddEven($pValue = false) { + public function setDifferentOddEven($pValue = false) + { $this->_differentOddEven = $pValue; return $this; } @@ -332,7 +346,8 @@ public function setDifferentOddEven($pValue = false) { * * @return boolean */ - public function getDifferentFirst() { + public function getDifferentFirst() + { return $this->_differentFirst; } @@ -342,7 +357,8 @@ public function getDifferentFirst() { * @param boolean $pValue * @return PHPExcel_Worksheet_HeaderFooter */ - public function setDifferentFirst($pValue = false) { + public function setDifferentFirst($pValue = false) + { $this->_differentFirst = $pValue; return $this; } @@ -352,7 +368,8 @@ public function setDifferentFirst($pValue = false) { * * @return boolean */ - public function getScaleWithDocument() { + public function getScaleWithDocument() + { return $this->_scaleWithDocument; } @@ -362,7 +379,8 @@ public function getScaleWithDocument() { * @param boolean $pValue * @return PHPExcel_Worksheet_HeaderFooter */ - public function setScaleWithDocument($pValue = true) { + public function setScaleWithDocument($pValue = true) + { $this->_scaleWithDocument = $pValue; return $this; } @@ -372,7 +390,8 @@ public function setScaleWithDocument($pValue = true) { * * @return boolean */ - public function getAlignWithMargins() { + public function getAlignWithMargins() + { return $this->_alignWithMargins; } @@ -382,7 +401,8 @@ public function getAlignWithMargins() { * @param boolean $pValue * @return PHPExcel_Worksheet_HeaderFooter */ - public function setAlignWithMargins($pValue = true) { + public function setAlignWithMargins($pValue = true) + { $this->_alignWithMargins = $pValue; return $this; } @@ -395,7 +415,8 @@ public function setAlignWithMargins($pValue = true) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_HeaderFooter */ - public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $location = self::IMAGE_HEADER_LEFT) { + public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $location = self::IMAGE_HEADER_LEFT) + { $this->_headerFooterImages[$location] = $image; return $this; } @@ -407,7 +428,8 @@ public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $ * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_HeaderFooter */ - public function removeImage($location = self::IMAGE_HEADER_LEFT) { + public function removeImage($location = self::IMAGE_HEADER_LEFT) + { if (isset($this->_headerFooterImages[$location])) { unset($this->_headerFooterImages[$location]); } @@ -421,7 +443,8 @@ public function removeImage($location = self::IMAGE_HEADER_LEFT) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet_HeaderFooter */ - public function setImages($images) { + public function setImages($images) + { if (!is_array($images)) { throw new PHPExcel_Exception('Invalid parameter!'); } @@ -435,15 +458,28 @@ public function setImages($images) { * * @return PHPExcel_Worksheet_HeaderFooterDrawing[] */ - public function getImages() { + public function getImages() + { // Sort array $images = array(); - if (isset($this->_headerFooterImages[self::IMAGE_HEADER_LEFT])) $images[self::IMAGE_HEADER_LEFT] = $this->_headerFooterImages[self::IMAGE_HEADER_LEFT]; - if (isset($this->_headerFooterImages[self::IMAGE_HEADER_CENTER])) $images[self::IMAGE_HEADER_CENTER] = $this->_headerFooterImages[self::IMAGE_HEADER_CENTER]; - if (isset($this->_headerFooterImages[self::IMAGE_HEADER_RIGHT])) $images[self::IMAGE_HEADER_RIGHT] = $this->_headerFooterImages[self::IMAGE_HEADER_RIGHT]; - if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_LEFT])) $images[self::IMAGE_FOOTER_LEFT] = $this->_headerFooterImages[self::IMAGE_FOOTER_LEFT]; - if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_CENTER])) $images[self::IMAGE_FOOTER_CENTER] = $this->_headerFooterImages[self::IMAGE_FOOTER_CENTER]; - if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT])) $images[self::IMAGE_FOOTER_RIGHT] = $this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT]; + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_LEFT])) { + $images[self::IMAGE_HEADER_LEFT] = $this->_headerFooterImages[self::IMAGE_HEADER_LEFT]; + } + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_CENTER])) { + $images[self::IMAGE_HEADER_CENTER] = $this->_headerFooterImages[self::IMAGE_HEADER_CENTER]; + } + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_RIGHT])) { + $images[self::IMAGE_HEADER_RIGHT] = $this->_headerFooterImages[self::IMAGE_HEADER_RIGHT]; + } + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_LEFT])) { + $images[self::IMAGE_FOOTER_LEFT] = $this->_headerFooterImages[self::IMAGE_FOOTER_LEFT]; + } + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_CENTER])) { + $images[self::IMAGE_FOOTER_CENTER] = $this->_headerFooterImages[self::IMAGE_FOOTER_CENTER]; + } + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT])) { + $images[self::IMAGE_FOOTER_RIGHT] = $this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT]; + } $this->_headerFooterImages = $images; return $this->_headerFooterImages; @@ -452,7 +488,8 @@ public function getImages() { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/Worksheet/MemoryDrawing.php b/Classes/PHPExcel/Worksheet/MemoryDrawing.php index 1f19b4d0a..04f8d1102 100644 --- a/Classes/PHPExcel/Worksheet/MemoryDrawing.php +++ b/Classes/PHPExcel/Worksheet/MemoryDrawing.php @@ -195,7 +195,8 @@ public function getHashCode() /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/Worksheet/PageSetup.php b/Classes/PHPExcel/Worksheet/PageSetup.php index e5fe06ac6..71649fce6 100644 --- a/Classes/PHPExcel/Worksheet/PageSetup.php +++ b/Classes/PHPExcel/Worksheet/PageSetup.php @@ -297,7 +297,8 @@ public function getPaperSize() * @param int $pValue * @return PHPExcel_Worksheet_PageSetup */ - public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) { + public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) + { $this->_paperSize = $pValue; return $this; } @@ -307,7 +308,8 @@ public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_L * * @return string */ - public function getOrientation() { + public function getOrientation() + { return $this->_orientation; } @@ -317,7 +319,8 @@ public function getOrientation() { * @param string $pValue * @return PHPExcel_Worksheet_PageSetup */ - public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) { + public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) + { $this->_orientation = $pValue; return $this; } @@ -327,7 +330,8 @@ public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATI * * @return int? */ - public function getScale() { + public function getScale() + { return $this->_scale; } @@ -342,7 +346,8 @@ public function getScale() { * @return PHPExcel_Worksheet_PageSetup * @throws PHPExcel_Exception */ - public function setScale($pValue = 100, $pUpdate = true) { + public function setScale($pValue = 100, $pUpdate = true) + { // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, // but it is apparently still able to handle any scale >= 0, where 0 results in 100 if (($pValue >= 0) || is_null($pValue)) { @@ -371,7 +376,8 @@ public function getFitToPage() { * @param boolean $pValue * @return PHPExcel_Worksheet_PageSetup */ - public function setFitToPage($pValue = true) { + public function setFitToPage($pValue = true) + { $this->_fitToPage = $pValue; return $this; } @@ -381,7 +387,8 @@ public function setFitToPage($pValue = true) { * * @return int? */ - public function getFitToHeight() { + public function getFitToHeight() + { return $this->_fitToHeight; } @@ -392,7 +399,8 @@ public function getFitToHeight() { * @param boolean $pUpdate Update fitToPage so it applies rather than scaling * @return PHPExcel_Worksheet_PageSetup */ - public function setFitToHeight($pValue = 1, $pUpdate = true) { + public function setFitToHeight($pValue = 1, $pUpdate = true) + { $this->_fitToHeight = $pValue; if ($pUpdate) { $this->_fitToPage = true; @@ -405,7 +413,8 @@ public function setFitToHeight($pValue = 1, $pUpdate = true) { * * @return int? */ - public function getFitToWidth() { + public function getFitToWidth() + { return $this->_fitToWidth; } @@ -416,7 +425,8 @@ public function getFitToWidth() { * @param boolean $pUpdate Update fitToPage so it applies rather than scaling * @return PHPExcel_Worksheet_PageSetup */ - public function setFitToWidth($pValue = 1, $pUpdate = true) { + public function setFitToWidth($pValue = 1, $pUpdate = true) + { $this->_fitToWidth = $pValue; if ($pUpdate) { $this->_fitToPage = true; @@ -429,7 +439,8 @@ public function setFitToWidth($pValue = 1, $pUpdate = true) { * * @return boolean */ - public function isColumnsToRepeatAtLeftSet() { + public function isColumnsToRepeatAtLeftSet() + { if (is_array($this->_columnsToRepeatAtLeft)) { if ($this->_columnsToRepeatAtLeft[0] != '' && $this->_columnsToRepeatAtLeft[1] != '') { return true; @@ -444,7 +455,8 @@ public function isColumnsToRepeatAtLeftSet() { * * @return array Containing start column and end column, empty array if option unset */ - public function getColumnsToRepeatAtLeft() { + public function getColumnsToRepeatAtLeft() + { return $this->_columnsToRepeatAtLeft; } @@ -454,7 +466,8 @@ public function getColumnsToRepeatAtLeft() { * @param array $pValue Containing start column and end column, empty array if option unset * @return PHPExcel_Worksheet_PageSetup */ - public function setColumnsToRepeatAtLeft($pValue = null) { + public function setColumnsToRepeatAtLeft($pValue = null) + { if (is_array($pValue)) { $this->_columnsToRepeatAtLeft = $pValue; } @@ -468,7 +481,8 @@ public function setColumnsToRepeatAtLeft($pValue = null) { * @param string $pEnd * @return PHPExcel_Worksheet_PageSetup */ - public function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A') { + public function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A') + { $this->_columnsToRepeatAtLeft = array($pStart, $pEnd); return $this; } @@ -478,7 +492,8 @@ public function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A' * * @return boolean */ - public function isRowsToRepeatAtTopSet() { + public function isRowsToRepeatAtTopSet() + { if (is_array($this->_rowsToRepeatAtTop)) { if ($this->_rowsToRepeatAtTop[0] != 0 && $this->_rowsToRepeatAtTop[1] != 0) { return true; @@ -493,7 +508,8 @@ public function isRowsToRepeatAtTopSet() { * * @return array Containing start column and end column, empty array if option unset */ - public function getRowsToRepeatAtTop() { + public function getRowsToRepeatAtTop() + { return $this->_rowsToRepeatAtTop; } @@ -503,7 +519,8 @@ public function getRowsToRepeatAtTop() { * @param array $pValue Containing start column and end column, empty array if option unset * @return PHPExcel_Worksheet_PageSetup */ - public function setRowsToRepeatAtTop($pValue = null) { + public function setRowsToRepeatAtTop($pValue = null) + { if (is_array($pValue)) { $this->_rowsToRepeatAtTop = $pValue; } @@ -517,7 +534,8 @@ public function setRowsToRepeatAtTop($pValue = null) { * @param int $pEnd * @return PHPExcel_Worksheet_PageSetup */ - public function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1) { + public function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1) + { $this->_rowsToRepeatAtTop = array($pStart, $pEnd); return $this; } @@ -527,7 +545,8 @@ public function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1) { * * @return bool */ - public function getHorizontalCentered() { + public function getHorizontalCentered() + { return $this->_horizontalCentered; } @@ -537,7 +556,8 @@ public function getHorizontalCentered() { * @param bool $value * @return PHPExcel_Worksheet_PageSetup */ - public function setHorizontalCentered($value = false) { + public function setHorizontalCentered($value = false) + { $this->_horizontalCentered = $value; return $this; } @@ -547,7 +567,8 @@ public function setHorizontalCentered($value = false) { * * @return bool */ - public function getVerticalCentered() { + public function getVerticalCentered() + { return $this->_verticalCentered; } @@ -557,7 +578,8 @@ public function getVerticalCentered() { * @param bool $value * @return PHPExcel_Worksheet_PageSetup */ - public function setVerticalCentered($value = false) { + public function setVerticalCentered($value = false) + { $this->_verticalCentered = $value; return $this; } @@ -572,7 +594,8 @@ public function setVerticalCentered($value = false) { * @throws PHPExcel_Exception * @return string */ - public function getPrintArea($index = 0) { + public function getPrintArea($index = 0) + { if ($index == 0) { return $this->_printArea; } @@ -592,7 +615,8 @@ public function getPrintArea($index = 0) { * Print areas are numbered from 1 * @return boolean */ - public function isPrintAreaSet($index = 0) { + public function isPrintAreaSet($index = 0) + { if ($index == 0) { return !is_null($this->_printArea); } @@ -609,7 +633,8 @@ public function isPrintAreaSet($index = 0) { * Print areas are numbered from 1 * @return PHPExcel_Worksheet_PageSetup */ - public function clearPrintArea($index = 0) { + public function clearPrintArea($index = 0) + { if ($index == 0) { $this->_printArea = null; } else { @@ -643,12 +668,13 @@ public function clearPrintArea($index = 0) { * @return PHPExcel_Worksheet_PageSetup * @throws PHPExcel_Exception */ - public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) { - if (strpos($value,'!') !== false) { + public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) + { + if (strpos($value, '!') !== false) { throw new PHPExcel_Exception('Cell coordinate must not specify a worksheet.'); - } elseif (strpos($value,':') === false) { + } elseif (strpos($value, ':') === false) { throw new PHPExcel_Exception('Cell coordinate must be a range of cells.'); - } elseif (strpos($value,'$') !== false) { + } elseif (strpos($value, '$') !== false) { throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); } $value = strtoupper($value); @@ -678,7 +704,7 @@ public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_O if ($index > count($printAreas)) { throw new PHPExcel_Exception('Invalid index for setting print range.'); } - $printAreas = array_merge(array_slice($printAreas,0, $index),array($value),array_slice($printAreas, $index)); + $printAreas = array_merge(array_slice($printAreas, 0, $index), array($value), array_slice($printAreas, $index)); $this->_printArea = implode(',', $printAreas); } } else { @@ -701,7 +727,8 @@ public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_O * @return PHPExcel_Worksheet_PageSetup * @throws PHPExcel_Exception */ - public function addPrintArea($value, $index = -1) { + public function addPrintArea($value, $index = -1) + { return $this->setPrintArea($value, $index, self::SETPRINTRANGE_INSERT); } @@ -759,7 +786,8 @@ public function addPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $in * * @return int */ - public function getFirstPageNumber() { + public function getFirstPageNumber() + { return $this->_firstPageNumber; } @@ -769,7 +797,8 @@ public function getFirstPageNumber() { * @param int $value * @return PHPExcel_Worksheet_HeaderFooter */ - public function setFirstPageNumber($value = null) { + public function setFirstPageNumber($value = null) + { $this->_firstPageNumber = $value; return $this; } @@ -779,14 +808,16 @@ public function setFirstPageNumber($value = null) { * * @return PHPExcel_Worksheet_HeaderFooter */ - public function resetFirstPageNumber() { + public function resetFirstPageNumber() + { return $this->setFirstPageNumber(null); } /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 6aefa80a1..8afa52f2e 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -405,7 +405,7 @@ private function _writeDataLbls($objWriter, $chartLayout) * @param string $id1 * @param string $id2 * @param boolean $isMultiLevelSeries - * + * * @throws PHPExcel_Writer_Exception */ private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis) diff --git a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php index ef5721339..4f0b1eba3 100644 --- a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php +++ b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -144,7 +144,7 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); - $mimeType = $this->_getImageMimeType( $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath()); + $mimeType = $this->_getImageMimeType($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath()); } else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); $extension = explode('/', $extension); From 4c8dd00dffd2f6e55ab9bff54219158844902874 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Fri, 15 May 2015 23:41:50 +0100 Subject: [PATCH 374/467] More psr-2 goodness --- Classes/PHPExcel/Calculation.php | 324 +- Classes/PHPExcel/Calculation/Token/Stack.php | 2 +- Classes/PHPExcel/Cell.php | 118 +- Classes/PHPExcel/Chart/Renderer/jpgraph.php | 1720 +-- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 10020 ++++++++-------- Classes/PHPExcel/Worksheet/HeaderFooter.php | 4 +- 6 files changed, 6187 insertions(+), 6001 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 63a2ace4c..6a21bcacb 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -83,7 +83,7 @@ class PHPExcel_Calculation * @access private * @var PHPExcel_Calculation */ - private static $_instance; + private static $instance; /** @@ -92,7 +92,7 @@ class PHPExcel_Calculation * @access private * @var PHPExcel */ - private $_workbook; + private $workbook; /** * List of instances of the calculation engine that we've instantiated for individual workbooks @@ -100,7 +100,7 @@ class PHPExcel_Calculation * @access private * @var PHPExcel_Calculation[] */ - private static $_workbookSets; + private static $workbookSets; /** * Calculation cache @@ -108,7 +108,7 @@ class PHPExcel_Calculation * @access private * @var array */ - private $_calculationCache = array (); + private $calculationCache = array (); /** @@ -117,7 +117,7 @@ class PHPExcel_Calculation * @access private * @var boolean */ - private $_calculationCacheEnabled = true; + private $calculationCacheEnabled = true; /** @@ -127,7 +127,7 @@ class PHPExcel_Calculation * @access private * @var array */ - private static $_operators = array( + private static $operators = array( '+' => true, '-' => true, '*' => true, '/' => true, '^' => true, '&' => true, '%' => false, '~' => false, '>' => true, '<' => true, '=' => true, '>=' => true, @@ -140,7 +140,7 @@ class PHPExcel_Calculation * @access private * @var array */ - private static $_binaryOperators = array( + private static $binaryOperators = array( '+' => true, '-' => true, '*' => true, '/' => true, '^' => true, '&' => true, '>' => true, '<' => true, '=' => true, '>=' => true, '<=' => true, '<>' => true, @@ -183,9 +183,9 @@ class PHPExcel_Calculation * @var array of string * */ - private $_cyclicReferenceStack; + private $cyclicReferenceStack; - private $_cellStack = array(); + private $cellStack = array(); /** * Current iteration counter for cyclic formulae @@ -195,9 +195,9 @@ class PHPExcel_Calculation * @var integer * */ - private $_cyclicFormulaCount = 1; + private $cyclicFormulaCounter = 1; - private $_cyclicFormulaCell = ''; + private $cyclicFormulaCell = ''; /** * Number of iterations for cyclic formulae @@ -213,7 +213,7 @@ class PHPExcel_Calculation * @var integer * */ - private $_savedPrecision = 14; + private $savedPrecision = 14; /** @@ -222,7 +222,7 @@ class PHPExcel_Calculation * @var string * */ - private static $_localeLanguage = 'en_us'; // US English (default locale) + private static $localeLanguage = 'en_us'; // US English (default locale) /** * List of available locale settings @@ -231,7 +231,7 @@ class PHPExcel_Calculation * @var string[] * */ - private static $_validLocaleLanguages = array( + private static $validLocaleLanguages = array( 'en' // English (default language) ); @@ -241,8 +241,8 @@ class PHPExcel_Calculation * @var string * */ - private static $_localeArgumentSeparator = ','; - private static $_localeFunctions = array(); + private static $localeArgumentSeparator = ','; + private static $localeFunctions = array(); /** * Locale-specific translations for Excel constants (True, False and Null) @@ -250,10 +250,10 @@ class PHPExcel_Calculation * @var string[] * */ - public static $_localeBoolean = array( - 'TRUE' => 'TRUE', - 'FALSE' => 'FALSE', - 'NULL' => 'NULL' + public static $localeBoolean = array( + 'TRUE' => 'TRUE', + 'FALSE' => 'FALSE', + 'NULL' => 'NULL' ); /** @@ -263,14 +263,14 @@ class PHPExcel_Calculation * @var string[] * */ - private static $_ExcelConstants = array( - 'TRUE' => true, - 'FALSE' => false, - 'NULL' => null + private static $excelConstants = array( + 'TRUE' => true, + 'FALSE' => false, + 'NULL' => null ); // PHPExcel functions - private static $_PHPExcelFunctions = array( // PHPExcel functions + private static $PHPExcelFunctions = array( // PHPExcel functions 'ABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, 'functionCall' => 'abs', 'argumentCount' => '1' @@ -1705,7 +1705,7 @@ class PHPExcel_Calculation // Internal functions used for special control purposes - private static $_controlFunctions = array( + private static $controlFunctions = array( 'MKMATRIX' => array( 'argumentCount' => '*', 'functionCall' => 'self::_mkMatrix' @@ -1716,26 +1716,26 @@ class PHPExcel_Calculation private function __construct(PHPExcel $workbook = null) { $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; - $this->_savedPrecision = ini_get('precision'); - if ($this->_savedPrecision < $setPrecision) { + $this->savedPrecision = ini_get('precision'); + if ($this->savedPrecision < $setPrecision) { ini_set('precision', $setPrecision); } $this->delta = 1 * pow(10, -$setPrecision); if ($workbook !== null) { - self::$_workbookSets[$workbook->getID()] = $this; + self::$workbookSets[$workbook->getID()] = $this; } - $this->_workbook = $workbook; - $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); - $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack); + $this->workbook = $workbook; + $this->cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); + $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->cyclicReferenceStack); } public function __destruct() { - if ($this->_savedPrecision != ini_get('precision')) { - ini_set('precision', $this->_savedPrecision); + if ($this->savedPrecision != ini_get('precision')) { + ini_set('precision', $this->savedPrecision); } } @@ -1745,7 +1745,7 @@ private static function _loadLocales() foreach (glob($localeFileDirectory.'/*', GLOB_ONLYDIR) as $filename) { $filename = substr($filename, strlen($localeFileDirectory)+1); if ($filename != 'en') { - self::$_validLocaleLanguages[] = $filename; + self::$validLocaleLanguages[] = $filename; } } } @@ -1761,17 +1761,17 @@ private static function _loadLocales() public static function getInstance(PHPExcel $workbook = null) { if ($workbook !== null) { - if (isset(self::$_workbookSets[$workbook->getID()])) { - return self::$_workbookSets[$workbook->getID()]; + 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(); + if (!isset(self::$instance) || (self::$instance === null)) { + self::$instance = new PHPExcel_Calculation(); } - return self::$_instance; + return self::$instance; } /** @@ -1783,8 +1783,8 @@ public static function getInstance(PHPExcel $workbook = null) public static function unsetInstance(PHPExcel $workbook = null) { if ($workbook !== null) { - if (isset(self::$_workbookSets[$workbook->getID()])) { - unset(self::$_workbookSets[$workbook->getID()]); + if (isset(self::$workbookSets[$workbook->getID()])) { + unset(self::$workbookSets[$workbook->getID()]); } } } @@ -1833,7 +1833,7 @@ final public function __clone() */ public static function getTRUE() { - return self::$_localeBoolean['TRUE']; + return self::$localeBoolean['TRUE']; } /** @@ -1844,7 +1844,7 @@ public static function getTRUE() */ public static function getFALSE() { - return self::$_localeBoolean['FALSE']; + return self::$localeBoolean['FALSE']; } /** @@ -1886,7 +1886,7 @@ public static function getArrayReturnType() */ public function getCalculationCacheEnabled() { - return $this->_calculationCacheEnabled; + return $this->calculationCacheEnabled; } /** @@ -1897,7 +1897,7 @@ public function getCalculationCacheEnabled() */ public function setCalculationCacheEnabled($pValue = true) { - $this->_calculationCacheEnabled = $pValue; + $this->calculationCacheEnabled = $pValue; $this->clearCalculationCache(); } @@ -1925,7 +1925,7 @@ public function disableCalculationCache() */ public function clearCalculationCache() { - $this->_calculationCache = array(); + $this->calculationCache = array(); } /** @@ -1935,8 +1935,8 @@ public function clearCalculationCache() */ public function clearCalculationCacheForWorksheet($worksheetName) { - if (isset($this->_calculationCache[$worksheetName])) { - unset($this->_calculationCache[$worksheetName]); + if (isset($this->calculationCache[$worksheetName])) { + unset($this->calculationCache[$worksheetName]); } } @@ -1948,9 +1948,9 @@ public function clearCalculationCacheForWorksheet($worksheetName) */ public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) { - if (isset($this->_calculationCache[$fromWorksheetName])) { - $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName]; - unset($this->_calculationCache[$fromWorksheetName]); + if (isset($this->calculationCache[$fromWorksheetName])) { + $this->calculationCache[$toWorksheetName] = &$this->calculationCache[$fromWorksheetName]; + unset($this->calculationCache[$fromWorksheetName]); } } @@ -1962,7 +1962,7 @@ public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksh */ public function getLocale() { - return self::$_localeLanguage; + return self::$localeLanguage; } @@ -1980,15 +1980,15 @@ public function setLocale($locale = 'en_us') list($language) = explode('_', $locale); } - if (count(self::$_validLocaleLanguages) == 1) { + if (count(self::$validLocaleLanguages) == 1) { self::_loadLocales(); } // Test whether we have any language data for this language (any locale) - if (in_array($language, self::$_validLocaleLanguages)) { + if (in_array($language, self::$validLocaleLanguages)) { // initialise language/locale settings - self::$_localeFunctions = array(); - self::$_localeArgumentSeparator = ','; - self::$_localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL'); + self::$localeFunctions = array(); + self::$localeArgumentSeparator = ','; + self::$localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL'); // Default is English, if user isn't requesting english, then read the necessary data from the locale files if ($locale != 'en_us') { // Search for a file with a list of function names for locale @@ -2008,17 +2008,17 @@ public function setLocale($locale = 'en_us') list($fName, $lfName) = explode('=', $localeFunction); $fName = trim($fName); $lfName = trim($lfName); - if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { - self::$_localeFunctions[$fName] = $lfName; + if ((isset(self::$PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { + self::$localeFunctions[$fName] = $lfName; } } } // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions - if (isset(self::$_localeFunctions['TRUE'])) { - self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; + if (isset(self::$localeFunctions['TRUE'])) { + self::$localeBoolean['TRUE'] = self::$localeFunctions['TRUE']; } - if (isset(self::$_localeFunctions['FALSE'])) { - self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; + if (isset(self::$localeFunctions['FALSE'])) { + self::$localeBoolean['FALSE'] = self::$localeFunctions['FALSE']; } $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $locale).DIRECTORY_SEPARATOR.'config'; @@ -2034,7 +2034,7 @@ public function setLocale($locale = 'en_us') $settingName = strtoupper(trim($settingName)); switch ($settingName) { case 'ARGUMENTSEPARATOR': - self::$_localeArgumentSeparator = trim($settingValue); + self::$localeArgumentSeparator = trim($settingValue); break; } } @@ -2044,7 +2044,7 @@ public function setLocale($locale = 'en_us') self::$functionReplaceFromExcel = self::$functionReplaceToExcel = self::$functionReplaceFromLocale = self::$functionReplaceToLocale = null; - self::$_localeLanguage = $locale; + self::$localeLanguage = $locale; return true; } return false; @@ -2076,7 +2076,7 @@ public static function _translateSeparator($fromSeparator, $toSeparator, $formul private static function _translateFormula($from, $to, $formula, $fromSeparator, $toSeparator) { // Convert any Excel function names to the required language - if (self::$_localeLanguage !== 'en_us') { + if (self::$localeLanguage !== 'en_us') { $inBraces = false; // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators if (strpos($formula, '"') !== false) { @@ -2111,10 +2111,10 @@ public function _translateFormulaToLocale($formula) { if (self::$functionReplaceFromExcel === null) { self::$functionReplaceFromExcel = array(); - foreach (array_keys(self::$_localeFunctions) as $excelFunctionName) { + foreach (array_keys(self::$localeFunctions) as $excelFunctionName) { self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui'; } - foreach (array_keys(self::$_localeBoolean) as $excelBoolean) { + foreach (array_keys(self::$localeBoolean) as $excelBoolean) { self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; } @@ -2122,15 +2122,15 @@ public function _translateFormulaToLocale($formula) if (self::$functionReplaceToLocale === null) { self::$functionReplaceToLocale = array(); - foreach (array_values(self::$_localeFunctions) as $localeFunctionName) { + foreach (array_values(self::$localeFunctions) as $localeFunctionName) { self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2'; } - foreach (array_values(self::$_localeBoolean) as $localeBoolean) { + foreach (array_values(self::$localeBoolean) as $localeBoolean) { self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2'; } } - return self::_translateFormula(self::$functionReplaceFromExcel, self::$functionReplaceToLocale, $formula, ',', self::$_localeArgumentSeparator); + return self::_translateFormula(self::$functionReplaceFromExcel, self::$functionReplaceToLocale, $formula, ',', self::$localeArgumentSeparator); } @@ -2141,35 +2141,35 @@ public function _translateFormulaToEnglish($formula) { if (self::$functionReplaceFromLocale === null) { self::$functionReplaceFromLocale = array(); - foreach (array_values(self::$_localeFunctions) as $localeFunctionName) { + foreach (array_values(self::$localeFunctions) as $localeFunctionName) { self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui'; } - foreach (array_values(self::$_localeBoolean) as $excelBoolean) { + foreach (array_values(self::$localeBoolean) as $excelBoolean) { self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; } } if (self::$functionReplaceToExcel === null) { self::$functionReplaceToExcel = array(); - foreach (array_keys(self::$_localeFunctions) as $excelFunctionName) { + foreach (array_keys(self::$localeFunctions) as $excelFunctionName) { self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2'; } - foreach (array_keys(self::$_localeBoolean) as $excelBoolean) { + foreach (array_keys(self::$localeBoolean) as $excelBoolean) { self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2'; } } - return self::_translateFormula(self::$functionReplaceFromLocale, self::$functionReplaceToExcel, $formula, self::$_localeArgumentSeparator, ','); + return self::_translateFormula(self::$functionReplaceFromLocale, self::$functionReplaceToExcel, $formula, self::$localeArgumentSeparator, ','); } - public static function _localeFunc($function) + public static function localeFunc($function) { - if (self::$_localeLanguage !== 'en_us') { + if (self::$localeLanguage !== 'en_us') { $functionName = trim($function, '('); - if (isset(self::$_localeFunctions[$functionName])) { + if (isset(self::$localeFunctions[$functionName])) { $brace = ($functionName != $function); - $function = self::$_localeFunctions[$functionName]; + $function = self::$localeFunctions[$functionName]; if ($brace) { $function .= '('; } @@ -2267,24 +2267,24 @@ public function calculateCellValue(PHPExcel_Cell $pCell = null, $resetLog = true // Initialise the logging settings if requested $this->formulaError = null; $this->_debugLog->clearLog(); - $this->_cyclicReferenceStack->clear(); - $this->_cyclicFormulaCount = 1; + $this->cyclicReferenceStack->clear(); + $this->cyclicFormulaCounter = 1; self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; } // Execute the calculation for the cell formula - $this->_cellStack[] = array( + $this->cellStack[] = array( 'sheet' => $pCell->getWorksheet()->getTitle(), 'cell' => $pCell->getCoordinate(), ); try { $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); - $cellAddress = array_pop($this->_cellStack); - $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); + $cellAddress = array_pop($this->cellStack); + $this->workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); } catch (PHPExcel_Exception $e) { - $cellAddress = array_pop($this->_cellStack); - $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); + $cellAddress = array_pop($this->cellStack); + $this->workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); throw new PHPExcel_Calculation_Exception($e->getMessage()); } @@ -2363,12 +2363,12 @@ public function calculateFormula($formula, $cellID = null, PHPExcel_Cell $pCell // Initialise the logging settings $this->formulaError = null; $this->_debugLog->clearLog(); - $this->_cyclicReferenceStack->clear(); + $this->cyclicReferenceStack->clear(); // Disable calculation cacheing because it only applies to cell calculations, not straight formulae // But don't actually flush any cache $resetCache = $this->getCalculationCacheEnabled(); - $this->_calculationCacheEnabled = false; + $this->calculationCacheEnabled = false; // Execute the calculation try { $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); @@ -2377,7 +2377,7 @@ public function calculateFormula($formula, $cellID = null, PHPExcel_Cell $pCell } // Reset calculation cacheing to its previous state - $this->_calculationCacheEnabled = $resetCache; + $this->calculationCacheEnabled = $resetCache; return $result; } @@ -2388,10 +2388,10 @@ public function getValueFromCache($cellReference, &$cellValue) // Is calculation cacheing enabled? // Is the value present in calculation cache? $this->_debugLog->writeDebugLog('Testing cache value for cell ', $cellReference); - if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$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[$cellReference]; + $cellValue = $this->calculationCache[$cellReference]; return true; } return false; @@ -2399,8 +2399,8 @@ public function getValueFromCache($cellReference, &$cellValue) public function saveValueToCache($cellReference, $cellValue) { - if ($this->_calculationCacheEnabled) { - $this->_calculationCache[$cellReference] = $cellValue; + if ($this->calculationCacheEnabled) { + $this->calculationCache[$cellReference] = $cellValue; } } @@ -2436,28 +2436,28 @@ public function _calculateFormulaValue($formula, $cellID = null, PHPExcel_Cell $ return $cellValue; } - if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsCellReference))) { + if (($wsTitle{0} !== "\x00") && ($this->cyclicReferenceStack->onStack($wsCellReference))) { if ($this->cyclicFormulaCount <= 0) { - $this->_cyclicFormulaCell = ''; + $this->cyclicFormulaCell = ''; return $this->_raiseFormulaError('Cyclic Reference in Formula'); - } elseif ($this->_cyclicFormulaCell === $wsCellReference) { - ++$this->_cyclicFormulaCount; - if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { - $this->_cyclicFormulaCell = ''; + } elseif ($this->cyclicFormulaCell === $wsCellReference) { + ++$this->cyclicFormulaCounter; + if ($this->cyclicFormulaCounter >= $this->cyclicFormulaCount) { + $this->cyclicFormulaCell = ''; return $cellValue; } - } elseif ($this->_cyclicFormulaCell == '') { - if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { + } elseif ($this->cyclicFormulaCell == '') { + if ($this->cyclicFormulaCounter >= $this->cyclicFormulaCount) { return $cellValue; } - $this->_cyclicFormulaCell = $wsCellReference; + $this->cyclicFormulaCell = $wsCellReference; } } // Parse the formula onto the token stack and calculate the value - $this->_cyclicReferenceStack->push($wsCellReference); + $this->cyclicReferenceStack->push($wsCellReference); $cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell); - $this->_cyclicReferenceStack->pop(); + $this->cyclicReferenceStack->pop(); // Save to calculation cache if ($cellID !== null) { @@ -2656,7 +2656,7 @@ private function _showValue($value) } elseif (is_string($value) && (trim($value, '"') == $value)) { return '"'.$value.'"'; } elseif (is_bool($value)) { - return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + return ($value) ? self::$localeBoolean['TRUE'] : self::$localeBoolean['FALSE']; } } return PHPExcel_Calculation_Functions::flattenSingleValue($value); @@ -2848,11 +2848,11 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression - } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? + } elseif ((isset(self::$operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? //echo 'Element with value '.$opCharacter.' is an Operator', PHP_EOL; while ($stack->count() > 0 && ($o2 = $stack->last()) && - isset(self::$_operators[$o2['value']]) && + isset(self::$operators[$o2['value']]) && @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } @@ -2885,14 +2885,14 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) //} $output[] = $d; // Dump the argument count on the output $output[] = $stack->pop(); // Pop the function and push onto the output - if (isset(self::$_controlFunctions[$functionName])) { + if (isset(self::$controlFunctions[$functionName])) { //echo 'Built-in function '.$functionName, PHP_EOL; - $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount']; - $functionCall = self::$_controlFunctions[$functionName]['functionCall']; - } elseif (isset(self::$_PHPExcelFunctions[$functionName])) { + $expectedArgumentCount = self::$controlFunctions[$functionName]['argumentCount']; + $functionCall = self::$controlFunctions[$functionName]['functionCall']; + } elseif (isset(self::$PHPExcelFunctions[$functionName])) { //echo 'PHPExcel function '.$functionName, PHP_EOL; - $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount']; - $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; + $expectedArgumentCount = self::$PHPExcelFunctions[$functionName]['argumentCount']; + $functionCall = self::$PHPExcelFunctions[$functionName]['functionCall']; } else { // did we somehow push a non-function on the stack? this should never happen return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack"); } @@ -2955,7 +2955,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) // If we've a comma when we're expecting an operand, then what we actually have is a null operand; // so push a null onto the stack if (($expectingOperand) || (!$expectingOperator)) { - $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => null); + $output[] = array('type' => 'NULL Value', 'value' => self::$excelConstants['NULL'], 'reference' => null); } // make sure there was a function $d = $stack->last(2); @@ -2984,7 +2984,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { $val = preg_replace('/\s/u', '', $val); // echo 'Element '.$val.' is a Function<br />'; - if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function + if (isset(self::$PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$controlFunctions[strtoupper($matches[1])])) { // it's a function $stack->push('Function', strtoupper($val)); $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch); if ($ax) { @@ -3071,13 +3071,13 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) // echo 'Casting '.$val.' to integer<br />'; $val = (integer) $val; } - } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) { + } elseif (isset(self::$excelConstants[trim(strtoupper($val))])) { $excelConstant = trim(strtoupper($val)); // echo 'Element '.$excelConstant.' is an Excel Constant<br />'; - $val = self::$_ExcelConstants[$excelConstant]; - } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== false) { + $val = self::$excelConstants[$excelConstant]; + } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$localeBoolean)) !== false) { // echo 'Element '.$localeConstant.' is an Excel Constant<br />'; - $val = self::$_ExcelConstants[$localeConstant]; + $val = self::$excelConstants[$localeConstant]; } $details = array('type' => 'Value', 'value' => $val, 'reference' => null); if ($localeConstant) { @@ -3091,13 +3091,13 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) ++$index; } elseif ($opCharacter == ')') { // miscellaneous error checking if ($expectingOperand) { - $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => null); + $output[] = array('type' => 'NULL Value', 'value' => self::$excelConstants['NULL'], 'reference' => null); $expectingOperand = false; $expectingOperator = true; } else { return $this->_raiseFormulaError("Formula Error: Unexpected ')'"); } - } elseif (isset(self::$_operators[$opCharacter]) && !$expectingOperator) { + } elseif (isset(self::$operators[$opCharacter]) && !$expectingOperator) { return $this->_raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'"); } else { // I don't even want to know what you did to get here return $this->_raiseFormulaError("Formula Error: An unexpected error occured"); @@ -3106,7 +3106,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) if ($index == strlen($formula)) { // Did we end with an operator?. // Only valid for the % unary operator - if ((isset(self::$_operators[$opCharacter])) && ($opCharacter != '%')) { + if ((isset(self::$operators[$opCharacter])) && ($opCharacter != '%')) { return $this->_raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands"); } else { break; @@ -3128,7 +3128,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) // echo 'Element is an Intersect Operator<br />'; while ($stack->count() > 0 && ($o2 = $stack->last()) && - isset(self::$_operators[$o2['value']]) && + isset(self::$operators[$o2['value']]) && @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } @@ -3183,7 +3183,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $token = $tokenData['value']; // echo '<b>Token is '.$token.'</b><br />'; // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack - if (isset(self::$_binaryOperators[$token])) { + if (isset(self::$binaryOperators[$token])) { // echo 'Token is a binary operator<br />'; // We must have two operands, error if we don't if (($operand2Data = $stack->pop()) === null) { @@ -3256,7 +3256,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); if ($pCellParent !== null) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), false); + $cellValue = $this->extractCellRange($cellRef, $this->workbook->getSheetByName($sheet1), false); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } @@ -3285,10 +3285,10 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // (converting the other operand to a matrix if need be); then perform the required // matrix operation if (is_bool($operand1)) { - $operand1 = ($operand1) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + $operand1 = ($operand1) ? self::$localeBoolean['TRUE'] : self::$localeBoolean['FALSE']; } if (is_bool($operand2)) { - $operand2 = ($operand2) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + $operand2 = ($operand2) ? self::$localeBoolean['TRUE'] : self::$localeBoolean['FALSE']; } if ((is_array($operand1)) || (is_array($operand2))) { // Ensure that both operands are arrays/matrices @@ -3377,7 +3377,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== null) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), false); + $cellValue = $this->extractCellRange($cellRef, $this->workbook->getSheetByName($matches[2]), false); } else { return $this->_raiseFormulaError('Unable to access Cell Reference'); } @@ -3410,9 +3410,9 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); if ($pCellParent !== null) { - $cellSheet = $this->_workbook->getSheetByName($matches[2]); + $cellSheet = $this->workbook->getSheetByName($matches[2]); if ($cellSheet && $cellSheet->cellExists($cellRef)) { - $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), false); + $cellValue = $this->extractCellRange($cellRef, $this->workbook->getSheetByName($matches[2]), false); $pCell->attach($pCellParent); } else { $cellValue = null; @@ -3444,17 +3444,17 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $argCount = $stack->pop(); $argCount = $argCount['value']; if ($functionName != 'MKMATRIX') { - $this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); - } - if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function - if (isset(self::$_PHPExcelFunctions[$functionName])) { - $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; - $passByReference = isset(self::$_PHPExcelFunctions[$functionName]['passByReference']); - $passCellReference = isset(self::$_PHPExcelFunctions[$functionName]['passCellReference']); - } elseif (isset(self::$_controlFunctions[$functionName])) { - $functionCall = self::$_controlFunctions[$functionName]['functionCall']; - $passByReference = isset(self::$_controlFunctions[$functionName]['passByReference']); - $passCellReference = isset(self::$_controlFunctions[$functionName]['passCellReference']); + $this->_debugLog->writeDebugLog('Evaluating Function ', self::localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); + } + if ((isset(self::$PHPExcelFunctions[$functionName])) || (isset(self::$controlFunctions[$functionName]))) { // function + if (isset(self::$PHPExcelFunctions[$functionName])) { + $functionCall = self::$PHPExcelFunctions[$functionName]['functionCall']; + $passByReference = isset(self::$PHPExcelFunctions[$functionName]['passByReference']); + $passCellReference = isset(self::$PHPExcelFunctions[$functionName]['passCellReference']); + } elseif (isset(self::$controlFunctions[$functionName])) { + $functionCall = self::$controlFunctions[$functionName]['functionCall']; + $passByReference = isset(self::$controlFunctions[$functionName]['passByReference']); + $passCellReference = isset(self::$controlFunctions[$functionName]['passCellReference']); } // get the arguments for this function // echo 'Function '.$functionName.' expects '.$argCount.' arguments<br />'; @@ -3463,8 +3463,8 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $arg = $stack->pop(); $a = $argCount - $i - 1; if (($passByReference) && - (isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) && - (self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) { + (isset(self::$PHPExcelFunctions[$functionName]['passByReference'][$a])) && + (self::$PHPExcelFunctions[$functionName]['passByReference'][$a])) { if ($arg['reference'] === null) { $args[] = $cellID; if ($functionName != 'MKMATRIX') { @@ -3495,7 +3495,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel if ($functionName != 'MKMATRIX') { if ($this->_debugLog->getWriteDebugLog()) { krsort($argArrayVals); - $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ', PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); + $this->_debugLog->writeDebugLog('Evaluating ', self::localeFunc($functionName), '( ', implode(self::$localeArgumentSeparator.' ', PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); } } // Process each argument in turn, building the return value as an array @@ -3507,16 +3507,16 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // foreach($operand1 as $args) { // if (is_array($args)) { // foreach($args as $arg) { -// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); +// $this->_debugLog->writeDebugLog('Evaluating ', self::localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); // $r = call_user_func_array($functionCall, $arg); -// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); // $result[$row][] = $r; // } // ++$row; // } else { -// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); +// $this->_debugLog->writeDebugLog('Evaluating ', self::localeFunc($functionName), '( ', $this->_showValue($args), ' )'); // $r = call_user_func_array($functionCall, $args); -// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); // $result[] = $r; // } // } @@ -3535,18 +3535,18 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $result = call_user_func_array($functionCall, $args); } if ($functionName != 'MKMATRIX') { - $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); } $stack->push('Value', self::_wrapResult($result)); } } else { // if the token is a number, boolean, string or an Excel error, push it onto the stack - if (isset(self::$_ExcelConstants[strtoupper($token)])) { + if (isset(self::$excelConstants[strtoupper($token)])) { $excelConstant = strtoupper($token); // echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />'; - $stack->push('Constant Value', self::$_ExcelConstants[$excelConstant]); - $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); + $stack->push('Constant Value', self::$excelConstants[$excelConstant]); + $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$excelConstants[$excelConstant])); } elseif ((is_numeric($token)) || ($token === null) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { // echo 'Token is a number, boolean, string, null or an Excel error<br />'; $stack->push('Value', $token); @@ -3828,7 +3828,7 @@ private function _executeNumericBinaryOperation($cellID, $operand1, $operand2, $ protected function _raiseFormulaError($errorMessage) { $this->formulaError = $errorMessage; - $this->_cyclicReferenceStack->clear(); + $this->cyclicReferenceStack->clear(); if (!$this->suppressFormulaErrors) { throw new PHPExcel_Calculation_Exception($errorMessage); } @@ -3860,7 +3860,7 @@ public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = n list($pSheetName, $pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); // echo 'New sheet name is '.$pSheetName, PHP_EOL; // echo 'Adjusted Range reference is '.$pRange, PHP_EOL; - $pSheet = $this->_workbook->getSheetByName($pSheetName); + $pSheet = $this->workbook->getSheetByName($pSheetName); } // Extract range @@ -3918,7 +3918,7 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = list($pSheetName, $pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); // echo 'New sheet name is '.$pSheetName, PHP_EOL; // echo 'Adjusted Range reference is '.$pRange, PHP_EOL; - $pSheet = $this->_workbook->getSheetByName($pSheetName); + $pSheet = $this->workbook->getSheetByName($pSheetName); } // Named range? @@ -3990,8 +3990,8 @@ public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = public function isImplemented($pFunction = '') { $pFunction = strtoupper($pFunction); - if (isset(self::$_PHPExcelFunctions[$pFunction])) { - return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); + if (isset(self::$PHPExcelFunctions[$pFunction])) { + return (self::$PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); } else { return false; } @@ -4007,7 +4007,7 @@ public function listFunctions() { $returnValue = array(); - foreach (self::$_PHPExcelFunctions as $functionName => $function) { + foreach (self::$PHPExcelFunctions as $functionName => $function) { if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { $returnValue[$functionName] = new PHPExcel_Calculation_Function( $function['category'], @@ -4028,7 +4028,7 @@ public function listFunctions() */ public function listAllFunctionNames() { - return array_keys(self::$_PHPExcelFunctions); + return array_keys(self::$PHPExcelFunctions); } /** @@ -4039,7 +4039,7 @@ public function listAllFunctionNames() public function listFunctionNames() { $returnValue = array(); - foreach (self::$_PHPExcelFunctions as $functionName => $function) { + foreach (self::$PHPExcelFunctions as $functionName => $function) { if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { $returnValue[] = $functionName; } diff --git a/Classes/PHPExcel/Calculation/Token/Stack.php b/Classes/PHPExcel/Calculation/Token/Stack.php index 13f446ab9..02ed5aaf0 100644 --- a/Classes/PHPExcel/Calculation/Token/Stack.php +++ b/Classes/PHPExcel/Calculation/Token/Stack.php @@ -66,7 +66,7 @@ public function push($type, $value, $reference = null) 'reference' => $reference ); if ($type == 'Function') { - $localeFunction = PHPExcel_Calculation::_localeFunc($value); + $localeFunction = PHPExcel_Calculation::localeFunc($value); if ($localeFunction != $value) { $this->stack[($this->count - 1)]['localeValue'] = $localeFunction; } diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 5250cba55..8bc5dac93 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -40,14 +40,14 @@ class PHPExcel_Cell * * @var PHPExcel_Cell_IValueBinder */ - private static $_valueBinder; + private static $valueBinder; /** * Value of the cell * * @var mixed */ - private $_value; + private $value; /** * Calculated value of the cell (used for caching) @@ -59,34 +59,34 @@ class PHPExcel_Cell * * @var mixed */ - private $_calculatedValue; + private $calculatedValue; /** * Type of the cell data * * @var string */ - private $_dataType; + private $dataType; /** * Parent worksheet * * @var PHPExcel_CachedObjectStorage_CacheBase */ - private $_parent; + private $parent; /** * Index to cellXf * * @var int */ - private $_xfIndex = 0; + private $xfIndex = 0; /** * Attributes of the formula * */ - private $_formulaAttributes; + private $formulaAttributes; /** @@ -96,19 +96,19 @@ class PHPExcel_Cell **/ public function notifyCacheController() { - $this->_parent->updateCacheData($this); + $this->parent->updateCacheData($this); return $this; } public function detach() { - $this->_parent = null; + $this->parent = null; } public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) { - $this->_parent = $parent; + $this->parent = $parent; } @@ -123,17 +123,17 @@ public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) public function __construct($pValue = null, $pDataType = null, PHPExcel_Worksheet $pSheet = null) { // Initialise cell value - $this->_value = $pValue; + $this->value = $pValue; // Set worksheet cache - $this->_parent = $pSheet->getCellCacheController(); + $this->parent = $pSheet->getCellCacheController(); // Set datatype? if ($pDataType !== null) { if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) { $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; } - $this->_dataType = $pDataType; + $this->dataType = $pDataType; } elseif (!self::getValueBinder()->bindValue($this, $pValue)) { throw new PHPExcel_Exception("Value could not be bound to cell."); } @@ -146,7 +146,7 @@ public function __construct($pValue = null, $pDataType = null, PHPExcel_Workshee */ public function getColumn() { - return $this->_parent->getCurrentColumn(); + return $this->parent->getCurrentColumn(); } /** @@ -156,7 +156,7 @@ public function getColumn() */ public function getRow() { - return $this->_parent->getCurrentRow(); + return $this->parent->getCurrentRow(); } /** @@ -166,7 +166,7 @@ public function getRow() */ public function getCoordinate() { - return $this->_parent->getCurrentAddress(); + return $this->parent->getCurrentAddress(); } /** @@ -176,7 +176,7 @@ public function getCoordinate() */ public function getValue() { - return $this->_value; + return $this->value; } /** @@ -223,7 +223,7 @@ public function setValueExplicit($pValue = null, $pDataType = PHPExcel_Cell_Data // set the value according to data type switch ($pDataType) { case PHPExcel_Cell_DataType::TYPE_NULL: - $this->_value = $pValue; + $this->value = $pValue; break; case PHPExcel_Cell_DataType::TYPE_STRING2: $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; @@ -231,19 +231,19 @@ public function setValueExplicit($pValue = null, $pDataType = PHPExcel_Cell_Data // Synonym for string case PHPExcel_Cell_DataType::TYPE_INLINE: // Rich text - $this->_value = PHPExcel_Cell_DataType::checkString($pValue); + $this->value = PHPExcel_Cell_DataType::checkString($pValue); break; case PHPExcel_Cell_DataType::TYPE_NUMERIC: - $this->_value = (float) $pValue; + $this->value = (float) $pValue; break; case PHPExcel_Cell_DataType::TYPE_FORMULA: - $this->_value = (string) $pValue; + $this->value = (string) $pValue; break; case PHPExcel_Cell_DataType::TYPE_BOOL: - $this->_value = (bool) $pValue; + $this->value = (bool) $pValue; break; case PHPExcel_Cell_DataType::TYPE_ERROR: - $this->_value = PHPExcel_Cell_DataType::checkErrorCode($pValue); + $this->value = PHPExcel_Cell_DataType::checkErrorCode($pValue); break; default: throw new PHPExcel_Exception('Invalid datatype: ' . $pDataType); @@ -251,7 +251,7 @@ public function setValueExplicit($pValue = null, $pDataType = PHPExcel_Cell_Data } // set the datatype - $this->_dataType = $pDataType; + $this->dataType = $pDataType; return $this->notifyCacheController(); } @@ -267,8 +267,8 @@ public function setValueExplicit($pValue = null, $pDataType = PHPExcel_Cell_Data */ public function getCalculatedValue($resetLog = true) { -//echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().PHP_EOL; - if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { +//echo 'Cell '.$this->getCoordinate().' value is a '.$this->dataType.' with a value of '.$this->getValue().PHP_EOL; + if ($this->dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { try { //echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value'.PHP_EOL; $result = PHPExcel_Calculation::getInstance( @@ -282,9 +282,9 @@ public function getCalculatedValue($resetLog = true) } } } catch (PHPExcel_Exception $ex) { - if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== null)) { -//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; - return $this->_calculatedValue; // Fallback for calculations referencing external files. + if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) { +//echo 'Returning fallback value of '.$this->calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; + return $this->calculatedValue; // Fallback for calculations referencing external files. } //echo 'Calculation Exception: '.$ex->getMessage().PHP_EOL; $result = '#N/A'; @@ -294,17 +294,17 @@ public function getCalculatedValue($resetLog = true) } if ($result === '#Not Yet Implemented') { -//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; - return $this->_calculatedValue; // Fallback if calculation engine does not support the formula. +//echo 'Returning fallback value of '.$this->calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; + return $this->calculatedValue; // Fallback if calculation engine does not support the formula. } //echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL; return $result; - } elseif ($this->_value instanceof PHPExcel_RichText) { -// echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->_value.'<br />'; - return $this->_value->getPlainText(); + } elseif ($this->value instanceof PHPExcel_RichText) { +// echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->value.'<br />'; + return $this->value->getPlainText(); } -// echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'<br />'; - return $this->_value; +// echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->value.'<br />'; + return $this->value; } /** @@ -316,7 +316,7 @@ public function getCalculatedValue($resetLog = true) public function setCalculatedValue($pValue = null) { if ($pValue !== null) { - $this->_calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue; + $this->calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue; } return $this->notifyCacheController(); @@ -334,7 +334,7 @@ public function setCalculatedValue($pValue = null) */ public function getOldCalculatedValue() { - return $this->_calculatedValue; + return $this->calculatedValue; } /** @@ -344,7 +344,7 @@ public function getOldCalculatedValue() */ public function getDataType() { - return $this->_dataType; + return $this->dataType; } /** @@ -358,7 +358,7 @@ public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING) if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) { $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; } - $this->_dataType = $pDataType; + $this->dataType = $pDataType; return $this->notifyCacheController(); } @@ -370,7 +370,7 @@ public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING) */ public function isFormula() { - return $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA; + return $this->dataType == PHPExcel_Cell_DataType::TYPE_FORMULA; } /** @@ -381,7 +381,7 @@ public function isFormula() */ public function hasDataValidation() { - if (!isset($this->_parent)) { + if (!isset($this->parent)) { throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet'); } @@ -396,7 +396,7 @@ public function hasDataValidation() */ public function getDataValidation() { - if (!isset($this->_parent)) { + if (!isset($this->parent)) { throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet'); } @@ -412,7 +412,7 @@ public function getDataValidation() */ public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = null) { - if (!isset($this->_parent)) { + if (!isset($this->parent)) { throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet'); } @@ -429,7 +429,7 @@ public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation */ public function hasHyperlink() { - if (!isset($this->_parent)) { + if (!isset($this->parent)) { throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); } @@ -444,7 +444,7 @@ public function hasHyperlink() */ public function getHyperlink() { - if (!isset($this->_parent)) { + if (!isset($this->parent)) { throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); } @@ -460,7 +460,7 @@ public function getHyperlink() */ public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = null) { - if (!isset($this->_parent)) { + if (!isset($this->parent)) { throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); } @@ -476,7 +476,7 @@ public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = null) */ public function getParent() { - return $this->_parent; + return $this->parent; } /** @@ -486,7 +486,7 @@ public function getParent() */ public function getWorksheet() { - return $this->_parent->getParent(); + return $this->parent->getParent(); } /** @@ -549,7 +549,7 @@ public function getStyle() */ public function rebindParent(PHPExcel_Worksheet $parent) { - $this->_parent = $parent->getCellCacheController(); + $this->parent = $parent->getCellCacheController(); return $this->notifyCacheController(); } @@ -943,11 +943,11 @@ public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b) */ public static function getValueBinder() { - if (self::$_valueBinder === null) { - self::$_valueBinder = new PHPExcel_Cell_DefaultValueBinder(); + if (self::$valueBinder === null) { + self::$valueBinder = new PHPExcel_Cell_DefaultValueBinder(); } - return self::$_valueBinder; + return self::$valueBinder; } /** @@ -962,7 +962,7 @@ public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = null) throw new PHPExcel_Exception("A PHPExcel_Cell_IValueBinder is required for PHPExcel to function correctly."); } - self::$_valueBinder = $binder; + self::$valueBinder = $binder; } /** @@ -972,7 +972,7 @@ public function __clone() { $vars = get_object_vars($this); foreach ($vars as $key => $value) { - if ((is_object($value)) && ($key != '_parent')) { + if ((is_object($value)) && ($key != 'parent')) { $this->$key = clone $value; } else { $this->$key = $value; @@ -987,7 +987,7 @@ public function __clone() */ public function getXfIndex() { - return $this->_xfIndex; + return $this->xfIndex; } /** @@ -998,7 +998,7 @@ public function getXfIndex() */ public function setXfIndex($pValue = 0) { - $this->_xfIndex = $pValue; + $this->xfIndex = $pValue; return $this->notifyCacheController(); } @@ -1008,7 +1008,7 @@ public function setXfIndex($pValue = 0) */ public function setFormulaAttributes($pAttributes) { - $this->_formulaAttributes = $pAttributes; + $this->formulaAttributes = $pAttributes; return $this; } @@ -1017,7 +1017,7 @@ public function setFormulaAttributes($pAttributes) */ public function getFormulaAttributes() { - return $this->_formulaAttributes; + return $this->formulaAttributes; } /** diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index a62f0b799..b95f3b28f 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -1,846 +1,874 @@ -<?php - -require_once(PHPExcel_Settings::getChartRendererPath().'/jpgraph.php'); - -/** - * PHPExcel_Chart_Renderer_jpgraph - * - * Copyright (c) 2006 - 2015 PHPExcel - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * @category PHPExcel - * @package PHPExcel_Chart_Renderer - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ -class PHPExcel_Chart_Renderer_jpgraph -{ - private static $width = 640; - - private static $height = 480; - - private static $colourSet = array( - 'mediumpurple1', 'palegreen3', 'gold1', 'cadetblue1', - 'darkmagenta', 'coral', 'dodgerblue3', 'eggplant', - 'mediumblue', 'magenta', 'sandybrown', 'cyan', - 'firebrick1', 'forestgreen', 'deeppink4', 'darkolivegreen', - 'goldenrod2' - ); - - private static $markSet = array( - 'diamond' => MARK_DIAMOND, - 'square' => MARK_SQUARE, - 'triangle' => MARK_UTRIANGLE, - 'x' => MARK_X, - 'star' => MARK_STAR, - 'dot' => MARK_FILLEDCIRCLE, - 'dash' => MARK_DTRIANGLE, - 'circle' => MARK_CIRCLE, - 'plus' => MARK_CROSS - ); - - - private $chart; - - private $graph; - - private static $_plotColour = 0; - - private static $_plotMark = 0; - - - private function formatPointMarker($seriesPlot, $markerID) { - $plotMarkKeys = array_keys(self::$markSet); - if (is_null($markerID)) { - // Use default plot marker (next marker in the series) - self::$_plotMark %= count(self::$markSet); - $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$_plotMark++]]); - } elseif ($markerID !== 'none') { - // Use specified plot marker (if it exists) - if (isset(self::$markSet[$markerID])) { - $seriesPlot->mark->SetType(self::$markSet[$markerID]); - } else { - // If the specified plot marker doesn't exist, use default plot marker (next marker in the series) - self::$_plotMark %= count(self::$markSet); - $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$_plotMark++]]); - } - } else { - // Hide plot marker - $seriesPlot->mark->Hide(); - } - $seriesPlot->mark->SetColor(self::$colourSet[self::$_plotColour]); - $seriesPlot->mark->SetFillColor(self::$colourSet[self::$_plotColour]); - $seriesPlot->SetColor(self::$colourSet[self::$_plotColour++]); - - return $seriesPlot; - } - - - private function formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') { - $datasetLabelFormatCode = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); - if (!is_null($datasetLabelFormatCode)) { - // Retrieve any label formatting code - $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); - } - - $testCurrentIndex = 0; - foreach ($datasetLabels as $i => $datasetLabel) { - if (is_array($datasetLabel)) { - if ($rotation == 'bar') { - $datasetLabels[$i] = implode(" ", $datasetLabel); - } else { - $datasetLabel = array_reverse($datasetLabel); - $datasetLabels[$i] = implode("\n", $datasetLabel); - } - } else { - // Format labels according to any formatting code - if (!is_null($datasetLabelFormatCode)) { - $datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel, $datasetLabelFormatCode); - } - } - ++$testCurrentIndex; - } - - return $datasetLabels; - } - - - private function _percentageSumCalculation($groupID, $seriesCount) { - // Adjust our values to a percentage value across all series in the group - for($i = 0; $i < $seriesCount; ++$i) { - if ($i == 0) { - $sumValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - } else { - $nextValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - foreach ($nextValues as $k => $value) { - if (isset($sumValues[$k])) { - $sumValues[$k] += $value; - } else { - $sumValues[$k] = $value; - } - } - } - } - - return $sumValues; - } // function _percentageSumCalculation() - - - private function _percentageAdjustValues($dataValues, $sumValues) { - foreach ($dataValues as $k => $dataValue) { - $dataValues[$k] = $dataValue / $sumValues[$k] * 100; - } - - return $dataValues; - } // function _percentageAdjustValues() - - - private function _getCaption($captionElement) { - // Read any caption - $caption = (!is_null($captionElement)) ? $captionElement->getCaption() : NULL; - // Test if we have a title caption to display - if (!is_null($caption)) { - // If we do, it could be a plain string or an array - if (is_array($caption)) { - // Implode an array to a plain string - $caption = implode('', $caption); - } - } - return $caption; - } // function _getCaption() - - - private function _renderTitle() { - $title = $this->_getCaption($this->chart->getTitle()); - if (!is_null($title)) { - $this->graph->title->Set($title); - } - } // function _renderTitle() - - - private function _renderLegend() { - $legend = $this->chart->getLegend(); - if (!is_null($legend)) { - $legendPosition = $legend->getPosition(); - $legendOverlay = $legend->getOverlay(); - switch ($legendPosition) { - case 'r' : - $this->graph->legend->SetPos(0.01,0.5,'right','center'); // right - $this->graph->legend->SetColumns(1); - break; - case 'l' : - $this->graph->legend->SetPos(0.01,0.5,'left','center'); // left - $this->graph->legend->SetColumns(1); - break; - case 't' : - $this->graph->legend->SetPos(0.5,0.01,'center','top'); // top - break; - case 'b' : - $this->graph->legend->SetPos(0.5,0.99,'center','bottom'); // bottom - break; - default : - $this->graph->legend->SetPos(0.01,0.01,'right','top'); // top-right - $this->graph->legend->SetColumns(1); - break; - } - } else { - $this->graph->legend->Hide(); - } - } // function _renderLegend() - - - private function _renderCartesianPlotArea($type='textlin') { - $this->graph = new Graph(self::$width,self::$height); - $this->graph->SetScale($type); - - $this->_renderTitle(); - - // Rotate for bar rather than column chart - $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); - $reverse = ($rotation == 'bar') ? true : false; - - $xAxisLabel = $this->chart->getXAxisLabel(); - if (!is_null($xAxisLabel)) { - $title = $this->_getCaption($xAxisLabel); - if (!is_null($title)) { - $this->graph->xaxis->SetTitle($title,'center'); - $this->graph->xaxis->title->SetMargin(35); - if ($reverse) { - $this->graph->xaxis->title->SetAngle(90); - $this->graph->xaxis->title->SetMargin(90); - } - } - } - - $yAxisLabel = $this->chart->getYAxisLabel(); - if (!is_null($yAxisLabel)) { - $title = $this->_getCaption($yAxisLabel); - if (!is_null($title)) { - $this->graph->yaxis->SetTitle($title,'center'); - if ($reverse) { - $this->graph->yaxis->title->SetAngle(0); - $this->graph->yaxis->title->SetMargin(-55); - } - } - } - } // function _renderCartesianPlotArea() - - - private function _renderPiePlotArea($doughnut = False) { - $this->graph = new PieGraph(self::$width,self::$height); - - $this->_renderTitle(); - } // function _renderPiePlotArea() - - - private function _renderRadarPlotArea() { - $this->graph = new RadarGraph(self::$width,self::$height); - $this->graph->SetScale('lin'); - - $this->_renderTitle(); - } // function _renderRadarPlotArea() - - - private function _renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') { - $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - - $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); - if ($labelCount > 0) { - $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); - $this->graph->xaxis->SetTickLabels($datasetLabels); - } - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - if ($grouping == 'percentStacked') { - $sumValues = $this->_percentageSumCalculation($groupID, $seriesCount); - } - - // Loop through each data series in turn - for($i = 0; $i < $seriesCount; ++$i) { - $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - - if ($grouping == 'percentStacked') { - $dataValues = $this->_percentageAdjustValues($dataValues, $sumValues); - } - - // Fill in any missing values in the $dataValues array - $testCurrentIndex = 0; - foreach ($dataValues as $k => $dataValue) { - while ($k != $testCurrentIndex) { - $dataValues[$testCurrentIndex] = null; - ++$testCurrentIndex; - } - ++$testCurrentIndex; - } - - $seriesPlot = new LinePlot($dataValues); - if ($combination) { - $seriesPlot->SetBarCenter(); - } - - if ($filled) { - $seriesPlot->SetFilled(true); - $seriesPlot->SetColor('black'); - $seriesPlot->SetFillColor(self::$colourSet[self::$_plotColour++]); - } else { - // Set the appropriate plot marker - $this->formatPointMarker($seriesPlot, $marker); - } - $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); - $seriesPlot->SetLegend($dataLabel); - - $seriesPlots[] = $seriesPlot; - } - - if ($grouping == 'standard') { - $groupPlot = $seriesPlots; - } else { - $groupPlot = new AccLinePlot($seriesPlots); - } - $this->graph->Add($groupPlot); - } // function _renderPlotLine() - - - private function _renderPlotBar($groupID, $dimensions = '2d') { - $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); - // Rotate for bar rather than column chart - if (($groupID == 0) && ($rotation == 'bar')) { - $this->graph->Set90AndMargin(); - } - $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - - $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); - if ($labelCount > 0) { - $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); - // Rotate for bar rather than column chart - if ($rotation == 'bar') { - $datasetLabels = array_reverse($datasetLabels); - $this->graph->yaxis->SetPos('max'); - $this->graph->yaxis->SetLabelAlign('center','top'); - $this->graph->yaxis->SetLabelSide(SIDE_RIGHT); - } - $this->graph->xaxis->SetTickLabels($datasetLabels); - } - - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - if ($grouping == 'percentStacked') { - $sumValues = $this->_percentageSumCalculation($groupID, $seriesCount); - } - - // Loop through each data series in turn - for($j = 0; $j < $seriesCount; ++$j) { - $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); - if ($grouping == 'percentStacked') { - $dataValues = $this->_percentageAdjustValues($dataValues, $sumValues); - } - - // Fill in any missing values in the $dataValues array - $testCurrentIndex = 0; - foreach ($dataValues as $k => $dataValue) { - while ($k != $testCurrentIndex) { - $dataValues[$testCurrentIndex] = null; - ++$testCurrentIndex; - } - ++$testCurrentIndex; - } - - // Reverse the $dataValues order for bar rather than column chart - if ($rotation == 'bar') { - $dataValues = array_reverse($dataValues); - } - $seriesPlot = new BarPlot($dataValues); - $seriesPlot->SetColor('black'); - $seriesPlot->SetFillColor(self::$colourSet[self::$_plotColour++]); - if ($dimensions == '3d') { - $seriesPlot->SetShadow(); - } - if (!$this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { - $dataLabel = ''; - } else { - $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); - } - $seriesPlot->SetLegend($dataLabel); - - $seriesPlots[] = $seriesPlot; - } - // Reverse the plot order for bar rather than column chart - if (($rotation == 'bar') && (!($grouping == 'percentStacked'))) { - $seriesPlots = array_reverse($seriesPlots); - } - - if ($grouping == 'clustered') { - $groupPlot = new GroupBarPlot($seriesPlots); - } elseif ($grouping == 'standard') { - $groupPlot = new GroupBarPlot($seriesPlots); - } else { - $groupPlot = new AccBarPlot($seriesPlots); - if ($dimensions == '3d') { - $groupPlot->SetShadow(); - } - } - - $this->graph->Add($groupPlot); - } // function _renderPlotBar() - - - private function _renderPlotScatter($groupID, $bubble) { - $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - $scatterStyle = $bubbleSize = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - - // Loop through each data series in turn - for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - - foreach ($dataValuesY as $k => $dataValueY) { - $dataValuesY[$k] = $k; - } - - $seriesPlot = new ScatterPlot($dataValuesX, $dataValuesY); - if ($scatterStyle == 'lineMarker') { - $seriesPlot->SetLinkPoints(); - $seriesPlot->link->SetColor(self::$colourSet[self::$_plotColour]); - } elseif ($scatterStyle == 'smoothMarker') { - $spline = new Spline($dataValuesY, $dataValuesX); - list($splineDataY, $splineDataX) = $spline->Get(count($dataValuesX) * self::$width / 20); - $lplot = new LinePlot($splineDataX, $splineDataY); - $lplot->SetColor(self::$colourSet[self::$_plotColour]); - - $this->graph->Add($lplot); - } - - if ($bubble) { - $this->formatPointMarker($seriesPlot,'dot'); - $seriesPlot->mark->SetColor('black'); - $seriesPlot->mark->SetSize($bubbleSize); - } else { - $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - $this->formatPointMarker($seriesPlot, $marker); - } - $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); - $seriesPlot->SetLegend($dataLabel); - - $this->graph->Add($seriesPlot); - } - } // function _renderPlotScatter() - - - private function _renderPlotRadar($groupID) { - $radarStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - - // Loop through each data series in turn - for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); - - $dataValues = array(); - foreach ($dataValuesY as $k => $dataValueY) { - $dataValues[$k] = implode(' ',array_reverse($dataValueY)); - } - $tmp = array_shift($dataValues); - $dataValues[] = $tmp; - $tmp = array_shift($dataValuesX); - $dataValuesX[] = $tmp; - - $this->graph->SetTitles(array_reverse($dataValues)); - - $seriesPlot = new RadarPlot(array_reverse($dataValuesX)); - - $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); - $seriesPlot->SetColor(self::$colourSet[self::$_plotColour++]); - if ($radarStyle == 'filled') { - $seriesPlot->SetFillColor(self::$colourSet[self::$_plotColour]); - } - $this->formatPointMarker($seriesPlot, $marker); - $seriesPlot->SetLegend($dataLabel); - - $this->graph->Add($seriesPlot); - } - } // function _renderPlotRadar() - - - private function _renderPlotContour($groupID) { - $contourStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - - $dataValues = array(); - // Loop through each data series in turn - for($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); - $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - - $dataValues[$i] = $dataValuesX; - } - $seriesPlot = new ContourPlot($dataValues); - - $this->graph->Add($seriesPlot); - } // function _renderPlotContour() - - - private function _renderPlotStock($groupID) { - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $plotOrder = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); - - $dataValues = array(); - // Loop through each data series in turn and build the plot arrays - foreach ($plotOrder as $i => $v) { - $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); - foreach ($dataValuesX as $j => $dataValueX) { - $dataValues[$plotOrder[$i]][$j] = $dataValueX; - } - } - if (empty($dataValues)) { - return; - } - - $dataValuesPlot = array(); - // Flatten the plot arrays to a single dimensional array to work with jpgraph - for($j = 0; $j < count($dataValues[0]); $j++) { - for($i = 0; $i < $seriesCount; $i++) { - $dataValuesPlot[] = $dataValues[$i][$j]; - } - } - - // Set the x-axis labels - $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); - if ($labelCount > 0) { - $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); - $this->graph->xaxis->SetTickLabels($datasetLabels); - } - - $seriesPlot = new StockPlot($dataValuesPlot); - $seriesPlot->SetWidth(20); - - $this->graph->Add($seriesPlot); - } // function _renderPlotStock() - - - private function _renderAreaChart($groupCount, $dimensions = '2d') { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); - - $this->_renderCartesianPlotArea(); - - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotLine($i,True,False, $dimensions); - } - } // function _renderAreaChart() - - - private function _renderLineChart($groupCount, $dimensions = '2d') { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); - - $this->_renderCartesianPlotArea(); - - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotLine($i,False,False, $dimensions); - } - } // function _renderLineChart() - - - private function _renderBarChart($groupCount, $dimensions = '2d') { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); - - $this->_renderCartesianPlotArea(); - - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotBar($i, $dimensions); - } - } // function _renderBarChart() - - - private function _renderScatterChart($groupCount) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); - - $this->_renderCartesianPlotArea('linlin'); - - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotScatter($i,false); - } - } // function _renderScatterChart() - - - private function _renderBubbleChart($groupCount) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); - - $this->_renderCartesianPlotArea('linlin'); - - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotScatter($i,true); - } - } // function _renderBubbleChart() - - - private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = False, $multiplePlots = False) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie.php'); - if ($dimensions == '3d') { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie3d.php'); - } - - $this->_renderPiePlotArea($doughnut); - - $iLimit = ($multiplePlots) ? $groupCount : 1; - for($groupID = 0; $groupID < $iLimit; ++$groupID) { - $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); - $exploded = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); - if ($groupID == 0) { - $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); - if ($labelCount > 0) { - $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); - $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); - } - } - - $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); - $seriesPlots = array(); - // For pie charts, we only display the first series: doughnut charts generally display all series - $jLimit = ($multiplePlots) ? $seriesCount : 1; - // Loop through each data series in turn - for($j = 0; $j < $jLimit; ++$j) { - $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); - - // Fill in any missing values in the $dataValues array - $testCurrentIndex = 0; - foreach ($dataValues as $k => $dataValue) { - while ($k != $testCurrentIndex) { - $dataValues[$testCurrentIndex] = null; - ++$testCurrentIndex; - } - ++$testCurrentIndex; - } - - if ($dimensions == '3d') { - $seriesPlot = new PiePlot3D($dataValues); - } else { - if ($doughnut) { - $seriesPlot = new PiePlotC($dataValues); - } else { - $seriesPlot = new PiePlot($dataValues); - } - } - - if ($multiplePlots) { - $seriesPlot->SetSize(($jLimit-$j) / ($jLimit * 4)); - } - - if ($doughnut) { - $seriesPlot->SetMidColor('white'); - } - - $seriesPlot->SetColor(self::$colourSet[self::$_plotColour++]); - if (count($datasetLabels) > 0) - $seriesPlot->SetLabels(array_fill(0,count($datasetLabels),'')); - if ($dimensions != '3d') { - $seriesPlot->SetGuideLines(false); - } - if ($j == 0) { - if ($exploded) { - $seriesPlot->ExplodeAll(); - } - $seriesPlot->SetLegends($datasetLabels); - } - - $this->graph->Add($seriesPlot); - } - } - } // function _renderPieChart() - - - private function _renderRadarChart($groupCount) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_radar.php'); - - $this->_renderRadarPlotArea(); - - for($groupID = 0; $groupID < $groupCount; ++$groupID) { - $this->_renderPlotRadar($groupID); - } - } // function _renderRadarChart() - - - private function _renderStockChart($groupCount) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_stock.php'); - - $this->_renderCartesianPlotArea('intint'); - - for($groupID = 0; $groupID < $groupCount; ++$groupID) { - $this->_renderPlotStock($groupID); - } - } // function _renderStockChart() - - - private function _renderContourChart($groupCount, $dimensions) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_contour.php'); - - $this->_renderCartesianPlotArea('intint'); - - for($i = 0; $i < $groupCount; ++$i) { - $this->_renderPlotContour($i); - } - } // function _renderContourChart() - - - private function _renderCombinationChart($groupCount, $dimensions, $outputDestination) { - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); - require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); - - $this->_renderCartesianPlotArea(); - - for($i = 0; $i < $groupCount; ++$i) { - $dimensions = null; - $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); - switch ($chartType) { - case 'area3DChart' : - $dimensions = '3d'; - case 'areaChart' : - $this->_renderPlotLine($i,True,True, $dimensions); - break; - case 'bar3DChart' : - $dimensions = '3d'; - case 'barChart' : - $this->_renderPlotBar($i, $dimensions); - break; - case 'line3DChart' : - $dimensions = '3d'; - case 'lineChart' : - $this->_renderPlotLine($i,False,True, $dimensions); - break; - case 'scatterChart' : - $this->_renderPlotScatter($i,false); - break; - case 'bubbleChart' : - $this->_renderPlotScatter($i,true); - break; - default : - $this->graph = null; - return false; - } - } - - $this->_renderLegend(); - - $this->graph->Stroke($outputDestination); - return true; - } // function _renderCombinationChart() - - - public function render($outputDestination) { - self::$_plotColour = 0; - - $groupCount = $this->chart->getPlotArea()->getPlotGroupCount(); - - $dimensions = null; - if ($groupCount == 1) { - $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); - } else { - $chartTypes = array(); - for($i = 0; $i < $groupCount; ++$i) { - $chartTypes[] = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); - } - $chartTypes = array_unique($chartTypes); - if (count($chartTypes) == 1) { - $chartType = array_pop($chartTypes); - } elseif (count($chartTypes) == 0) { - echo 'Chart is not yet implemented<br />'; - return false; - } else { - return $this->_renderCombinationChart($groupCount, $dimensions, $outputDestination); - } - } - - switch ($chartType) { - case 'area3DChart' : - $dimensions = '3d'; - case 'areaChart' : - $this->_renderAreaChart($groupCount, $dimensions); - break; - case 'bar3DChart' : - $dimensions = '3d'; - case 'barChart' : - $this->_renderBarChart($groupCount, $dimensions); - break; - case 'line3DChart' : - $dimensions = '3d'; - case 'lineChart' : - $this->_renderLineChart($groupCount, $dimensions); - break; - case 'pie3DChart' : - $dimensions = '3d'; - case 'pieChart' : - $this->_renderPieChart($groupCount, $dimensions,False,False); - break; - case 'doughnut3DChart' : - $dimensions = '3d'; - case 'doughnutChart' : - $this->_renderPieChart($groupCount, $dimensions,True,True); - break; - case 'scatterChart' : - $this->_renderScatterChart($groupCount); - break; - case 'bubbleChart' : - $this->_renderBubbleChart($groupCount); - break; - case 'radarChart' : - $this->_renderRadarChart($groupCount); - break; - case 'surface3DChart' : - $dimensions = '3d'; - case 'surfaceChart' : - $this->_renderContourChart($groupCount, $dimensions); - break; - case 'stockChart' : - $this->_renderStockChart($groupCount, $dimensions); - break; - default : - echo $chartType.' is not yet implemented<br />'; - return false; - } - $this->_renderLegend(); - - $this->graph->Stroke($outputDestination); - return true; - } - - - /** - * Create a new PHPExcel_Chart_Renderer_jpgraph - */ - public function __construct(PHPExcel_Chart $chart) - { - $this->graph = null; - $this->chart = $chart; - } -} +<?php + +require_once(PHPExcel_Settings::getChartRendererPath().'/jpgraph.php'); + +/** + * PHPExcel_Chart_Renderer_jpgraph + * + * Copyright (c) 2006 - 2015 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Chart_Renderer + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## + */ +class PHPExcel_Chart_Renderer_jpgraph +{ + private static $width = 640; + + private static $height = 480; + + private static $colourSet = array( + 'mediumpurple1', 'palegreen3', 'gold1', 'cadetblue1', + 'darkmagenta', 'coral', 'dodgerblue3', 'eggplant', + 'mediumblue', 'magenta', 'sandybrown', 'cyan', + 'firebrick1', 'forestgreen', 'deeppink4', 'darkolivegreen', + 'goldenrod2' + ); + + private static $markSet = array( + 'diamond' => MARK_DIAMOND, + 'square' => MARK_SQUARE, + 'triangle' => MARK_UTRIANGLE, + 'x' => MARK_X, + 'star' => MARK_STAR, + 'dot' => MARK_FILLEDCIRCLE, + 'dash' => MARK_DTRIANGLE, + 'circle' => MARK_CIRCLE, + 'plus' => MARK_CROSS + ); + + + private $chart; + + private $graph; + + private static $plotColour = 0; + + private static $plotMark = 0; + + + private function formatPointMarker($seriesPlot, $markerID) + { + $plotMarkKeys = array_keys(self::$markSet); + if (is_null($markerID)) { + // Use default plot marker (next marker in the series) + self::$plotMark %= count(self::$markSet); + $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]); + } elseif ($markerID !== 'none') { + // Use specified plot marker (if it exists) + if (isset(self::$markSet[$markerID])) { + $seriesPlot->mark->SetType(self::$markSet[$markerID]); + } else { + // If the specified plot marker doesn't exist, use default plot marker (next marker in the series) + self::$plotMark %= count(self::$markSet); + $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]); + } + } else { + // Hide plot marker + $seriesPlot->mark->Hide(); + } + $seriesPlot->mark->SetColor(self::$colourSet[self::$plotColour]); + $seriesPlot->mark->SetFillColor(self::$colourSet[self::$plotColour]); + $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); + + return $seriesPlot; + } + + + private function formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') + { + $datasetLabelFormatCode = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); + if (!is_null($datasetLabelFormatCode)) { + // Retrieve any label formatting code + $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); + } + + $testCurrentIndex = 0; + foreach ($datasetLabels as $i => $datasetLabel) { + if (is_array($datasetLabel)) { + if ($rotation == 'bar') { + $datasetLabels[$i] = implode(" ", $datasetLabel); + } else { + $datasetLabel = array_reverse($datasetLabel); + $datasetLabels[$i] = implode("\n", $datasetLabel); + } + } else { + // Format labels according to any formatting code + if (!is_null($datasetLabelFormatCode)) { + $datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel, $datasetLabelFormatCode); + } + } + ++$testCurrentIndex; + } + + return $datasetLabels; + } + + + private function percentageSumCalculation($groupID, $seriesCount) + { + // Adjust our values to a percentage value across all series in the group + for ($i = 0; $i < $seriesCount; ++$i) { + if ($i == 0) { + $sumValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + } else { + $nextValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + foreach ($nextValues as $k => $value) { + if (isset($sumValues[$k])) { + $sumValues[$k] += $value; + } else { + $sumValues[$k] = $value; + } + } + } + } + + return $sumValues; + } + + + private function percentageAdjustValues($dataValues, $sumValues) + { + foreach ($dataValues as $k => $dataValue) { + $dataValues[$k] = $dataValue / $sumValues[$k] * 100; + } + + return $dataValues; + } + + + private function getCaption($captionElement) + { + // Read any caption + $caption = (!is_null($captionElement)) ? $captionElement->getCaption() : null; + // Test if we have a title caption to display + if (!is_null($caption)) { + // If we do, it could be a plain string or an array + if (is_array($caption)) { + // Implode an array to a plain string + $caption = implode('', $caption); + } + } + return $caption; + } + + + private function renderTitle() + { + $title = $this->getCaption($this->chart->getTitle()); + if (!is_null($title)) { + $this->graph->title->Set($title); + } + } + + + private function renderLegend() + { + $legend = $this->chart->getLegend(); + if (!is_null($legend)) { + $legendPosition = $legend->getPosition(); + $legendOverlay = $legend->getOverlay(); + switch ($legendPosition) { + case 'r': + $this->graph->legend->SetPos(0.01, 0.5, 'right', 'center'); // right + $this->graph->legend->SetColumns(1); + break; + case 'l': + $this->graph->legend->SetPos(0.01, 0.5, 'left', 'center'); // left + $this->graph->legend->SetColumns(1); + break; + case 't': + $this->graph->legend->SetPos(0.5, 0.01, 'center', 'top'); // top + break; + case 'b': + $this->graph->legend->SetPos(0.5, 0.99, 'center', 'bottom'); // bottom + break; + default: + $this->graph->legend->SetPos(0.01, 0.01, 'right', 'top'); // top-right + $this->graph->legend->SetColumns(1); + break; + } + } else { + $this->graph->legend->Hide(); + } + } + + + private function renderCartesianPlotArea($type = 'textlin') + { + $this->graph = new Graph(self::$width, self::$height); + $this->graph->SetScale($type); + + $this->renderTitle(); + + // Rotate for bar rather than column chart + $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); + $reverse = ($rotation == 'bar') ? true : false; + + $xAxisLabel = $this->chart->getXAxisLabel(); + if (!is_null($xAxisLabel)) { + $title = $this->getCaption($xAxisLabel); + if (!is_null($title)) { + $this->graph->xaxis->SetTitle($title, 'center'); + $this->graph->xaxis->title->SetMargin(35); + if ($reverse) { + $this->graph->xaxis->title->SetAngle(90); + $this->graph->xaxis->title->SetMargin(90); + } + } + } + + $yAxisLabel = $this->chart->getYAxisLabel(); + if (!is_null($yAxisLabel)) { + $title = $this->getCaption($yAxisLabel); + if (!is_null($title)) { + $this->graph->yaxis->SetTitle($title, 'center'); + if ($reverse) { + $this->graph->yaxis->title->SetAngle(0); + $this->graph->yaxis->title->SetMargin(-55); + } + } + } + } + + + private function renderPiePlotArea($doughnut = false) + { + $this->graph = new PieGraph(self::$width, self::$height); + + $this->renderTitle(); + } + + + private function renderRadarPlotArea() + { + $this->graph = new RadarGraph(self::$width, self::$height); + $this->graph->SetScale('lin'); + + $this->renderTitle(); + } + + + private function renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') + { + $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + + $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->graph->xaxis->SetTickLabels($datasetLabels); + } + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + if ($grouping == 'percentStacked') { + $sumValues = $this->percentageSumCalculation($groupID, $seriesCount); + } + + // Loop through each data series in turn + for ($i = 0; $i < $seriesCount; ++$i) { + $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + + if ($grouping == 'percentStacked') { + $dataValues = $this->percentageAdjustValues($dataValues, $sumValues); + } + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach ($dataValues as $k => $dataValue) { + while ($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + $seriesPlot = new LinePlot($dataValues); + if ($combination) { + $seriesPlot->SetBarCenter(); + } + + if ($filled) { + $seriesPlot->SetFilled(true); + $seriesPlot->SetColor('black'); + $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); + } else { + // Set the appropriate plot marker + $this->formatPointMarker($seriesPlot, $marker); + } + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetLegend($dataLabel); + + $seriesPlots[] = $seriesPlot; + } + + if ($grouping == 'standard') { + $groupPlot = $seriesPlots; + } else { + $groupPlot = new AccLinePlot($seriesPlots); + } + $this->graph->Add($groupPlot); + } + + + private function renderPlotBar($groupID, $dimensions = '2d') + { + $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); + // Rotate for bar rather than column chart + if (($groupID == 0) && ($rotation == 'bar')) { + $this->graph->Set90AndMargin(); + } + $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + + $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); + // Rotate for bar rather than column chart + if ($rotation == 'bar') { + $datasetLabels = array_reverse($datasetLabels); + $this->graph->yaxis->SetPos('max'); + $this->graph->yaxis->SetLabelAlign('center', 'top'); + $this->graph->yaxis->SetLabelSide(SIDE_RIGHT); + } + $this->graph->xaxis->SetTickLabels($datasetLabels); + } + + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + if ($grouping == 'percentStacked') { + $sumValues = $this->percentageSumCalculation($groupID, $seriesCount); + } + + // Loop through each data series in turn + for ($j = 0; $j < $seriesCount; ++$j) { + $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + if ($grouping == 'percentStacked') { + $dataValues = $this->percentageAdjustValues($dataValues, $sumValues); + } + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach ($dataValues as $k => $dataValue) { + while ($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + // Reverse the $dataValues order for bar rather than column chart + if ($rotation == 'bar') { + $dataValues = array_reverse($dataValues); + } + $seriesPlot = new BarPlot($dataValues); + $seriesPlot->SetColor('black'); + $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); + if ($dimensions == '3d') { + $seriesPlot->SetShadow(); + } + if (!$this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { + $dataLabel = ''; + } else { + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); + } + $seriesPlot->SetLegend($dataLabel); + + $seriesPlots[] = $seriesPlot; + } + // Reverse the plot order for bar rather than column chart + if (($rotation == 'bar') && (!($grouping == 'percentStacked'))) { + $seriesPlots = array_reverse($seriesPlots); + } + + if ($grouping == 'clustered') { + $groupPlot = new GroupBarPlot($seriesPlots); + } elseif ($grouping == 'standard') { + $groupPlot = new GroupBarPlot($seriesPlots); + } else { + $groupPlot = new AccBarPlot($seriesPlots); + if ($dimensions == '3d') { + $groupPlot->SetShadow(); + } + } + + $this->graph->Add($groupPlot); + } + + + private function renderPlotScatter($groupID, $bubble) + { + $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $scatterStyle = $bubbleSize = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + // Loop through each data series in turn + for ($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + + foreach ($dataValuesY as $k => $dataValueY) { + $dataValuesY[$k] = $k; + } + + $seriesPlot = new ScatterPlot($dataValuesX, $dataValuesY); + if ($scatterStyle == 'lineMarker') { + $seriesPlot->SetLinkPoints(); + $seriesPlot->link->SetColor(self::$colourSet[self::$plotColour]); + } elseif ($scatterStyle == 'smoothMarker') { + $spline = new Spline($dataValuesY, $dataValuesX); + list($splineDataY, $splineDataX) = $spline->Get(count($dataValuesX) * self::$width / 20); + $lplot = new LinePlot($splineDataX, $splineDataY); + $lplot->SetColor(self::$colourSet[self::$plotColour]); + + $this->graph->Add($lplot); + } + + if ($bubble) { + $this->formatPointMarker($seriesPlot, 'dot'); + $seriesPlot->mark->SetColor('black'); + $seriesPlot->mark->SetSize($bubbleSize); + } else { + $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + $this->formatPointMarker($seriesPlot, $marker); + } + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetLegend($dataLabel); + + $this->graph->Add($seriesPlot); + } + } + + + private function renderPlotRadar($groupID) + { + $radarStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + // Loop through each data series in turn + for ($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + + $dataValues = array(); + foreach ($dataValuesY as $k => $dataValueY) { + $dataValues[$k] = implode(' ', array_reverse($dataValueY)); + } + $tmp = array_shift($dataValues); + $dataValues[] = $tmp; + $tmp = array_shift($dataValuesX); + $dataValuesX[] = $tmp; + + $this->graph->SetTitles(array_reverse($dataValues)); + + $seriesPlot = new RadarPlot(array_reverse($dataValuesX)); + + $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); + if ($radarStyle == 'filled') { + $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour]); + } + $this->formatPointMarker($seriesPlot, $marker); + $seriesPlot->SetLegend($dataLabel); + + $this->graph->Add($seriesPlot); + } + } + + + private function renderPlotContour($groupID) + { + $contourStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + $dataValues = array(); + // Loop through each data series in turn + for ($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + + $dataValues[$i] = $dataValuesX; + } + $seriesPlot = new ContourPlot($dataValues); + + $this->graph->Add($seriesPlot); + } + + + private function renderPlotStock($groupID) + { + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $plotOrder = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); + + $dataValues = array(); + // Loop through each data series in turn and build the plot arrays + foreach ($plotOrder as $i => $v) { + $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); + foreach ($dataValuesX as $j => $dataValueX) { + $dataValues[$plotOrder[$i]][$j] = $dataValueX; + } + } + if (empty($dataValues)) { + return; + } + + $dataValuesPlot = array(); + // Flatten the plot arrays to a single dimensional array to work with jpgraph + for ($j = 0; $j < count($dataValues[0]); ++$j) { + for ($i = 0; $i < $seriesCount; ++$i) { + $dataValuesPlot[] = $dataValues[$i][$j]; + } + } + + // Set the x-axis labels + $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->graph->xaxis->SetTickLabels($datasetLabels); + } + + $seriesPlot = new StockPlot($dataValuesPlot); + $seriesPlot->SetWidth(20); + + $this->graph->Add($seriesPlot); + } + + + private function renderAreaChart($groupCount, $dimensions = '2d') + { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + + $this->renderCartesianPlotArea(); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotLine($i, true, false, $dimensions); + } + } + + + private function renderLineChart($groupCount, $dimensions = '2d') + { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + + $this->renderCartesianPlotArea(); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotLine($i, false, false, $dimensions); + } + } + + + private function renderBarChart($groupCount, $dimensions = '2d') + { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); + + $this->renderCartesianPlotArea(); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotBar($i, $dimensions); + } + } + + + private function renderScatterChart($groupCount) + { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + + $this->renderCartesianPlotArea('linlin'); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotScatter($i, false); + } + } + + + private function renderBubbleChart($groupCount) + { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); + + $this->renderCartesianPlotArea('linlin'); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotScatter($i, true); + } + } + + + private function renderPieChart($groupCount, $dimensions = '2d', $doughnut = false, $multiplePlots = false) + { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie.php'); + if ($dimensions == '3d') { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie3d.php'); + } + + $this->renderPiePlotArea($doughnut); + + $iLimit = ($multiplePlots) ? $groupCount : 1; + for ($groupID = 0; $groupID < $iLimit; ++$groupID) { + $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $exploded = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + if ($groupID == 0) { + $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); + } + } + + $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + // For pie charts, we only display the first series: doughnut charts generally display all series + $jLimit = ($multiplePlots) ? $seriesCount : 1; + // Loop through each data series in turn + for ($j = 0; $j < $jLimit; ++$j) { + $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach ($dataValues as $k => $dataValue) { + while ($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + if ($dimensions == '3d') { + $seriesPlot = new PiePlot3D($dataValues); + } else { + if ($doughnut) { + $seriesPlot = new PiePlotC($dataValues); + } else { + $seriesPlot = new PiePlot($dataValues); + } + } + + if ($multiplePlots) { + $seriesPlot->SetSize(($jLimit-$j) / ($jLimit * 4)); + } + + if ($doughnut) { + $seriesPlot->SetMidColor('white'); + } + + $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); + if (count($datasetLabels) > 0) { + $seriesPlot->SetLabels(array_fill(0, count($datasetLabels), '')); + } + if ($dimensions != '3d') { + $seriesPlot->SetGuideLines(false); + } + if ($j == 0) { + if ($exploded) { + $seriesPlot->ExplodeAll(); + } + $seriesPlot->SetLegends($datasetLabels); + } + + $this->graph->Add($seriesPlot); + } + } + } + + + private function renderRadarChart($groupCount) + { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_radar.php'); + + $this->renderRadarPlotArea(); + + for ($groupID = 0; $groupID < $groupCount; ++$groupID) { + $this->renderPlotRadar($groupID); + } + } + + + private function renderStockChart($groupCount) + { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_stock.php'); + + $this->renderCartesianPlotArea('intint'); + + for ($groupID = 0; $groupID < $groupCount; ++$groupID) { + $this->renderPlotStock($groupID); + } + } + + + private function renderContourChart($groupCount, $dimensions) + { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_contour.php'); + + $this->renderCartesianPlotArea('intint'); + + for ($i = 0; $i < $groupCount; ++$i) { + $this->renderPlotContour($i); + } + } + + + private function renderCombinationChart($groupCount, $dimensions, $outputDestination) + { + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); + require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); + + $this->renderCartesianPlotArea(); + + for ($i = 0; $i < $groupCount; ++$i) { + $dimensions = null; + $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + switch ($chartType) { + case 'area3DChart': + $dimensions = '3d'; + case 'areaChart': + $this->renderPlotLine($i, true, true, $dimensions); + break; + case 'bar3DChart': + $dimensions = '3d'; + case 'barChart': + $this->renderPlotBar($i, $dimensions); + break; + case 'line3DChart': + $dimensions = '3d'; + case 'lineChart': + $this->renderPlotLine($i, false, true, $dimensions); + break; + case 'scatterChart': + $this->renderPlotScatter($i, false); + break; + case 'bubbleChart': + $this->renderPlotScatter($i, true); + break; + default: + $this->graph = null; + return false; + } + } + + $this->renderLegend(); + + $this->graph->Stroke($outputDestination); + return true; + } + + + public function render($outputDestination) + { + self::$plotColour = 0; + + $groupCount = $this->chart->getPlotArea()->getPlotGroupCount(); + + $dimensions = null; + if ($groupCount == 1) { + $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); + } else { + $chartTypes = array(); + for ($i = 0; $i < $groupCount; ++$i) { + $chartTypes[] = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + } + $chartTypes = array_unique($chartTypes); + if (count($chartTypes) == 1) { + $chartType = array_pop($chartTypes); + } elseif (count($chartTypes) == 0) { + echo 'Chart is not yet implemented<br />'; + return false; + } else { + return $this->renderCombinationChart($groupCount, $dimensions, $outputDestination); + } + } + + switch ($chartType) { + case 'area3DChart': + $dimensions = '3d'; + case 'areaChart': + $this->renderAreaChart($groupCount, $dimensions); + break; + case 'bar3DChart': + $dimensions = '3d'; + case 'barChart': + $this->renderBarChart($groupCount, $dimensions); + break; + case 'line3DChart': + $dimensions = '3d'; + case 'lineChart': + $this->renderLineChart($groupCount, $dimensions); + break; + case 'pie3DChart': + $dimensions = '3d'; + case 'pieChart': + $this->renderPieChart($groupCount, $dimensions, false, false); + break; + case 'doughnut3DChart': + $dimensions = '3d'; + case 'doughnutChart': + $this->renderPieChart($groupCount, $dimensions, true, true); + break; + case 'scatterChart': + $this->renderScatterChart($groupCount); + break; + case 'bubbleChart': + $this->renderBubbleChart($groupCount); + break; + case 'radarChart': + $this->renderRadarChart($groupCount); + break; + case 'surface3DChart': + $dimensions = '3d'; + case 'surfaceChart': + $this->renderContourChart($groupCount, $dimensions); + break; + case 'stockChart': + $this->renderStockChart($groupCount, $dimensions); + break; + default: + echo $chartType.' is not yet implemented<br />'; + return false; + } + $this->renderLegend(); + + $this->graph->Stroke($outputDestination); + return true; + } + + + /** + * Create a new PHPExcel_Chart_Renderer_jpgraph + */ + public function __construct(PHPExcel_Chart $chart) + { + $this->graph = null; + $this->chart = $chart; + } +} diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index effb8dd76..0805a03c7 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -25,170 +25,170 @@ // $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $ // -------------------------------------------------------------------------------- -// ----- Constants -if (!defined('PCLZIP_READ_BLOCK_SIZE')) { - define('PCLZIP_READ_BLOCK_SIZE', 2048); -} - -// ----- File list separator -// In version 1.x of PclZip, the separator for file list is a space -// (which is not a very smart choice, specifically for windows paths !). -// A better separator should be a comma (,). This constant gives you the -// abilty to change that. -// However notice that changing this value, may have impact on existing -// scripts, using space separated filenames. -// Recommanded values for compatibility with older versions : -//define('PCLZIP_SEPARATOR', ' '); -// Recommanded values for smart separation of filenames. -if (!defined('PCLZIP_SEPARATOR')) { - define('PCLZIP_SEPARATOR', ','); -} - -// ----- Error configuration -// 0 : PclZip Class integrated error handling -// 1 : PclError external library error handling. By enabling this -// you must ensure that you have included PclError library. -// [2,...] : reserved for futur use -if (!defined('PCLZIP_ERROR_EXTERNAL')) { - define('PCLZIP_ERROR_EXTERNAL', 0); -} - -// ----- Optional static temporary directory -// By default temporary files are generated in the script current -// path. -// If defined : -// - MUST BE terminated by a '/'. -// - MUST be a valid, already created directory -// Samples : -// define('PCLZIP_TEMPORARY_DIR', '/temp/'); -// define('PCLZIP_TEMPORARY_DIR', 'C:/Temp/'); -if (!defined('PCLZIP_TEMPORARY_DIR')) { - define('PCLZIP_TEMPORARY_DIR', ''); -} - -// ----- Optional threshold ratio for use of temporary files -// Pclzip sense the size of the file to add/extract and decide to -// use or not temporary file. The algorythm is looking for -// memory_limit of PHP and apply a ratio. -// threshold = memory_limit * ratio. -// Recommended values are under 0.5. Default 0.47. -// Samples : -// define('PCLZIP_TEMPORARY_FILE_RATIO', 0.5); -if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { - define('PCLZIP_TEMPORARY_FILE_RATIO', 0.47); -} + // ----- Constants + if (!defined('PCLZIP_READ_BLOCK_SIZE')) { + define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); + } + + // ----- File list separator + // In version 1.x of PclZip, the separator for file list is a space + // (which is not a very smart choice, specifically for windows paths !). + // A better separator should be a comma (,). This constant gives you the + // abilty to change that. + // However notice that changing this value, may have impact on existing + // scripts, using space separated filenames. + // Recommanded values for compatibility with older versions : + //define( 'PCLZIP_SEPARATOR', ' ' ); + // Recommanded values for smart separation of filenames. + if (!defined('PCLZIP_SEPARATOR')) { + define( 'PCLZIP_SEPARATOR', ',' ); + } + + // ----- Error configuration + // 0 : PclZip Class integrated error handling + // 1 : PclError external library error handling. By enabling this + // you must ensure that you have included PclError library. + // [2,...] : reserved for futur use + if (!defined('PCLZIP_ERROR_EXTERNAL')) { + define( 'PCLZIP_ERROR_EXTERNAL', 0 ); + } + + // ----- Optional static temporary directory + // By default temporary files are generated in the script current + // path. + // If defined : + // - MUST BE terminated by a '/'. + // - MUST be a valid, already created directory + // Samples : + // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); + // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); + if (!defined('PCLZIP_TEMPORARY_DIR')) { + define( 'PCLZIP_TEMPORARY_DIR', '' ); + } + + // ----- Optional threshold ratio for use of temporary files + // Pclzip sense the size of the file to add/extract and decide to + // use or not temporary file. The algorythm is looking for + // memory_limit of PHP and apply a ratio. + // threshold = memory_limit * ratio. + // Recommended values are under 0.5. Default 0.47. + // Samples : + // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 ); + if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { + define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 ); + } // -------------------------------------------------------------------------------- // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** // -------------------------------------------------------------------------------- -// ----- Global variables -$g_pclzip_version = "2.8.2"; - -// ----- Error codes -// -1 : Unable to open file in binary write mode -// -2 : Unable to open file in binary read mode -// -3 : Invalid parameters -// -4 : File does not exist -// -5 : Filename is too long (max. 255) -// -6 : Not a valid zip file -// -7 : Invalid extracted file size -// -8 : Unable to create directory -// -9 : Invalid archive extension -// -10 : Invalid archive format -// -11 : Unable to delete file (unlink) -// -12 : Unable to rename file (rename) -// -13 : Invalid header checksum -// -14 : Invalid archive size -define('PCLZIP_ERR_USER_ABORTED', 2); -define('PCLZIP_ERR_NO_ERROR', 0); -define('PCLZIP_ERR_WRITE_OPEN_FAIL', -1); -define('PCLZIP_ERR_READ_OPEN_FAIL', -2); -define('PCLZIP_ERR_INVALID_PARAMETER', -3); -define('PCLZIP_ERR_MISSING_FILE', -4); -define('PCLZIP_ERR_FILENAME_TOO_LONG', -5); -define('PCLZIP_ERR_INVALID_ZIP', -6); -define('PCLZIP_ERR_BAD_EXTRACTED_FILE', -7); -define('PCLZIP_ERR_DIR_CREATE_FAIL', -8); -define('PCLZIP_ERR_BAD_EXTENSION', -9); -define('PCLZIP_ERR_BAD_FORMAT', -10); -define('PCLZIP_ERR_DELETE_FILE_FAIL', -11); -define('PCLZIP_ERR_RENAME_FILE_FAIL', -12); -define('PCLZIP_ERR_BAD_CHECKSUM', -13); -define('PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14); -define('PCLZIP_ERR_MISSING_OPTION_VALUE', -15); -define('PCLZIP_ERR_INVALID_OPTION_VALUE', -16); -define('PCLZIP_ERR_ALREADY_A_DIRECTORY', -17); -define('PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18); -define('PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19); -define('PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20); -define('PCLZIP_ERR_DIRECTORY_RESTRICTION', -21); - -// ----- Options values -define('PCLZIP_OPT_PATH', 77001); -define('PCLZIP_OPT_ADD_PATH', 77002); -define('PCLZIP_OPT_REMOVE_PATH', 77003); -define('PCLZIP_OPT_REMOVE_ALL_PATH', 77004); -define('PCLZIP_OPT_SET_CHMOD', 77005); -define('PCLZIP_OPT_EXTRACT_AS_STRING', 77006); -define('PCLZIP_OPT_NO_COMPRESSION', 77007); -define('PCLZIP_OPT_BY_NAME', 77008); -define('PCLZIP_OPT_BY_INDEX', 77009); -define('PCLZIP_OPT_BY_EREG', 77010); -define('PCLZIP_OPT_BY_PREG', 77011); -define('PCLZIP_OPT_COMMENT', 77012); -define('PCLZIP_OPT_ADD_COMMENT', 77013); -define('PCLZIP_OPT_PREPEND_COMMENT', 77014); -define('PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015); -define('PCLZIP_OPT_REPLACE_NEWER', 77016); -define('PCLZIP_OPT_STOP_ON_ERROR', 77017); -// Having big trouble with crypt. Need to multiply 2 long int -// which is not correctly supported by PHP ... -//define('PCLZIP_OPT_CRYPT', 77018); -define('PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019); -define('PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020); -define('PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020); // alias -define('PCLZIP_OPT_TEMP_FILE_ON', 77021); -define('PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021); // alias -define('PCLZIP_OPT_TEMP_FILE_OFF', 77022); -define('PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022); // alias - -// ----- File description attributes -define('PCLZIP_ATT_FILE_NAME', 79001); -define('PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002); -define('PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003); -define('PCLZIP_ATT_FILE_MTIME', 79004); -define('PCLZIP_ATT_FILE_CONTENT', 79005); -define('PCLZIP_ATT_FILE_COMMENT', 79006); - -// ----- Call backs values -define('PCLZIP_CB_PRE_EXTRACT', 78001); -define('PCLZIP_CB_POST_EXTRACT', 78002); -define('PCLZIP_CB_PRE_ADD', 78003); -define('PCLZIP_CB_POST_ADD', 78004); -/* For futur use -define('PCLZIP_CB_PRE_LIST', 78005); -define('PCLZIP_CB_POST_LIST', 78006); -define('PCLZIP_CB_PRE_DELETE', 78007); -define('PCLZIP_CB_POST_DELETE', 78008); -*/ + // ----- Global variables + $g_pclzip_version = "2.8.2"; + + // ----- Error codes + // -1 : Unable to open file in binary write mode + // -2 : Unable to open file in binary read mode + // -3 : Invalid parameters + // -4 : File does not exist + // -5 : Filename is too long (max. 255) + // -6 : Not a valid zip file + // -7 : Invalid extracted file size + // -8 : Unable to create directory + // -9 : Invalid archive extension + // -10 : Invalid archive format + // -11 : Unable to delete file (unlink) + // -12 : Unable to rename file (rename) + // -13 : Invalid header checksum + // -14 : Invalid archive size + define( 'PCLZIP_ERR_USER_ABORTED', 2 ); + define( 'PCLZIP_ERR_NO_ERROR', 0 ); + define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); + define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); + define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); + define( 'PCLZIP_ERR_MISSING_FILE', -4 ); + define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); + define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); + define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); + define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); + define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); + define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); + define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); + define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); + define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); + define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); + define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); + define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); + define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); + define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); + define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); + define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); + define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); + + // ----- Options values + define( 'PCLZIP_OPT_PATH', 77001 ); + define( 'PCLZIP_OPT_ADD_PATH', 77002 ); + define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); + define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); + define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); + define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); + define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); + define( 'PCLZIP_OPT_BY_NAME', 77008 ); + define( 'PCLZIP_OPT_BY_INDEX', 77009 ); + define( 'PCLZIP_OPT_BY_EREG', 77010 ); + define( 'PCLZIP_OPT_BY_PREG', 77011 ); + define( 'PCLZIP_OPT_COMMENT', 77012 ); + define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); + define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); + define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); + define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); + define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); + // Having big trouble with crypt. Need to multiply 2 long int + // which is not correctly supported by PHP ... + //define( 'PCLZIP_OPT_CRYPT', 77018 ); + define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); + define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias + define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias + define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias + + // ----- File description attributes + define( 'PCLZIP_ATT_FILE_NAME', 79001 ); + define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); + define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); + define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); + define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); + define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); + + // ----- Call backs values + define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); + define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); + define( 'PCLZIP_CB_PRE_ADD', 78003 ); + define( 'PCLZIP_CB_POST_ADD', 78004 ); + /* For futur use + define( 'PCLZIP_CB_PRE_LIST', 78005 ); + define( 'PCLZIP_CB_POST_LIST', 78006 ); + define( 'PCLZIP_CB_PRE_DELETE', 78007 ); + define( 'PCLZIP_CB_POST_DELETE', 78008 ); + */ -// -------------------------------------------------------------------------------- -// Class : PclZip -// Description : -// PclZip is the class that represent a Zip archive. -// The public methods allow the manipulation of the archive. -// Attributes : -// Attributes must not be accessed directly. -// Methods : -// PclZip() : Object creator -// create() : Creates the Zip archive -// listContent() : List the content of the Zip archive -// extract() : Extract the content of the archive -// properties() : List the properties of the archive -// -------------------------------------------------------------------------------- -class PclZip -{ + // -------------------------------------------------------------------------------- + // Class : PclZip + // Description : + // PclZip is the class that represent a Zip archive. + // The public methods allow the manipulation of the archive. + // Attributes : + // Attributes must not be accessed directly. + // Methods : + // PclZip() : Object creator + // create() : Creates the Zip archive + // listContent() : List the content of the Zip archive + // extract() : Extract the content of the archive + // properties() : List the properties of the archive + // -------------------------------------------------------------------------------- + class PclZip + { // ----- Filename of the zip file var $zipname = ''; @@ -198,4595 +198,5016 @@ class PclZip // ----- Internal error handling var $error_code = 1; var $error_string = ''; - + // ----- Current status of the magic_quotes_runtime // This value store the php configuration for magic_quotes // The class can then disable the magic_quotes and reset it after var $magic_quotes_status; - // -------------------------------------------------------------------------------- - // Function : PclZip() - // Description : - // Creates a PclZip object and set the name of the associated Zip archive - // filename. - // Note that no real action is taken, if the archive does not exist it is not - // created. Use create() for that. - // -------------------------------------------------------------------------------- - function PclZip($p_zipname) + // -------------------------------------------------------------------------------- + // Function : PclZip() + // Description : + // Creates a PclZip object and set the name of the associated Zip archive + // filename. + // Note that no real action is taken, if the archive does not exist it is not + // created. Use create() for that. + // -------------------------------------------------------------------------------- + function PclZip($p_zipname) + { + + // ----- Tests the zlib + if (!function_exists('gzopen')) { - // ----- Tests the zlib - if (!function_exists('gzopen')) { - die('Abort '.basename(__FILE__).' : Missing zlib extensions'); - } + die('Abort '.basename(__FILE__).' : Missing zlib extensions'); + } - // ----- Set the attributes - $this->zipname = $p_zipname; - $this->zip_fd = 0; - $this->magic_quotes_status = -1; + // ----- Set the attributes + $this->zipname = $p_zipname; + $this->zip_fd = 0; + $this->magic_quotes_status = -1; - // ----- Return - return; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // create($p_filelist, $p_add_dir="", $p_remove_dir="") - // create($p_filelist, $p_option, $p_option_value, ...) - // Description : - // This method supports two different synopsis. The first one is historical. - // This method creates a Zip Archive. The Zip file is created in the - // filesystem. The files and directories indicated in $p_filelist - // are added in the archive. See the parameters description for the - // supported format of $p_filelist. - // When a directory is in the list, the directory and its content is added - // in the archive. - // In this synopsis, the function takes an optional variable list of - // options. See bellow the supported options. - // Parameters : - // $p_filelist : An array containing file or directory names, or - // a string containing one filename or one directory name, or - // a string containing a list of filenames and/or directory - // names separated by spaces. - // $p_add_dir : A path to add before the real path of the archived file, - // in order to have it memorized in the archive. - // $p_remove_dir : A path to remove from the real path of the file to archive, - // in order to have a shorter path memorized in the archive. - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir - // is removed first, before $p_add_dir is added. - // Options : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_COMMENT : - // PCLZIP_CB_PRE_ADD : - // PCLZIP_CB_POST_ADD : - // Return Values : - // 0 on failure, - // The list of the added files, with a status of the add action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function create($p_filelist) { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Set default values - $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = false; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove from the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array( - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - //, PCLZIP_OPT_CRYPT => 'optional' - ))); - if ($v_result != 1) { - return 0; - } - } else { - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - - // ----- Get the first argument - $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; - - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; - } else if ($v_size > 2) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - return 0; - } - } + // ----- Return + return; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // create($p_filelist, $p_add_dir="", $p_remove_dir="") + // create($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two different synopsis. The first one is historical. + // This method creates a Zip Archive. The Zip file is created in the + // filesystem. The files and directories indicated in $p_filelist + // are added in the archive. See the parameters description for the + // supported format of $p_filelist. + // When a directory is in the list, the directory and its content is added + // in the archive. + // In this synopsis, the function takes an optional variable list of + // options. See bellow the supported options. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function create($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove from the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; } + } - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Init - $v_string_list = array(); - $v_att_list = array(); - $v_filedescr_list = array(); - $p_result_list = array(); - - // ----- Look if the $p_filelist is really an array - if (is_array($p_filelist)) { - // ----- Look if the first element is also an array - // This will mean that this is a file description entry - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; - } else { - // ----- The list is a list of string names - $v_string_list = $p_filelist; - } - } else if (is_string($p_filelist)) { - // ----- Look if the $p_filelist is a string - // ----- Create a list from the string - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); - } else { - // ----- Invalid variable type for $p_filelist - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); - return 0; + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; } - // ----- Reformat the string list - if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - if ($v_string != '') { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; - } - } + else if ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Invalid number / type of arguments"); + return 0; } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } - // ----- For each file in the list check the attributes - $v_supported_attributes = array( - PCLZIP_ATT_FILE_NAME => 'mandatory', - PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional', - PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional', - PCLZIP_ATT_FILE_MTIME => 'optional', - PCLZIP_ATT_FILE_CONTENT => 'optional', - PCLZIP_ATT_FILE_COMMENT => 'optional', - )); - foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes); - if ($v_result != 1) { - return 0; - } + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; } - // ----- Expand the filelist (expand directories) - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); - if ($v_result != 1) { - return 0; + else { } + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } - // ----- Call the create fct - $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // add($p_filelist, $p_add_dir="", $p_remove_dir="") + // add($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two synopsis. The first one is historical. + // This methods add the list of files in an existing archive. + // If a file with the same name already exists, it is added at the end of the + // archive, the first one is still present. + // If the archive does not exist, it is created. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_OPT_ADD_COMMENT : + // PCLZIP_OPT_PREPEND_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function add($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); if ($v_result != 1) { - return 0; + return 0; } + } - // ----- Return - return $p_result_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // add($p_filelist, $p_add_dir="", $p_remove_dir="") - // add($p_filelist, $p_option, $p_option_value, ...) - // Description : - // This method supports two synopsis. The first one is historical. - // This methods add the list of files in an existing archive. - // If a file with the same name already exists, it is added at the end of the - // archive, the first one is still present. - // If the archive does not exist, it is created. - // Parameters : - // $p_filelist : An array containing file or directory names, or - // a string containing one filename or one directory name, or - // a string containing a list of filenames and/or directory - // names separated by spaces. - // $p_add_dir : A path to add before the real path of the archived file, - // in order to have it memorized in the archive. - // $p_remove_dir : A path to remove from the real path of the file to archive, - // in order to have a shorter path memorized in the archive. - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir - // is removed first, before $p_add_dir is added. - // Options : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_COMMENT : - // PCLZIP_OPT_ADD_COMMENT : - // PCLZIP_OPT_PREPEND_COMMENT : - // PCLZIP_CB_PRE_ADD : - // PCLZIP_CB_POST_ADD : - // Return Values : - // 0 on failure, - // The list of the added files, with a status of the add action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function add($p_filelist) - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Set default values - $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = false; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove form the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array( - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_ADD_COMMENT => 'optional', - PCLZIP_OPT_PREPEND_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - //, PCLZIP_OPT_CRYPT => 'optional' - ))); - if ($v_result != 1) { - return 0; - } - } else { - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the method. - - // ----- Get the first argument - $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; - - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; - } else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Return - return 0; - } - } - } + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Init - $v_string_list = array(); - $v_att_list = array(); - $v_filedescr_list = array(); - $p_result_list = array(); - - // ----- Look if the $p_filelist is really an array - if (is_array($p_filelist)) { - // ----- Look if the first element is also an array - // This will mean that this is a file description entry - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; - } else { - // ----- The list is a list of string names - $v_string_list = $p_filelist; - } - } else if (is_string($p_filelist)) { - // ----- Look if the $p_filelist is a string - // ----- Create a list from the string - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); - } else { - // ----- Invalid variable type for $p_filelist - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); - return 0; - } + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; - // ----- Reformat the string list - if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; - } + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- For each file in the list check the attributes - $v_supported_attributes = array( - PCLZIP_ATT_FILE_NAME => 'mandatory', - PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional', - PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional', - PCLZIP_ATT_FILE_MTIME => 'optional', - PCLZIP_ATT_FILE_CONTENT => 'optional', - PCLZIP_ATT_FILE_COMMENT => 'optional', - )); - foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes); - if ($v_result != 1) { - return 0; - } + // ----- Return + return 0; } + } + } - // ----- Expand the filelist (expand directories) - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); - if ($v_result != 1) { - return 0; - } + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); - // ----- Call the create fct - $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); - if ($v_result != 1) { - return 0; - } + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } - // ----- Return - return $p_result_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : listContent() - // Description : - // This public method, gives the list of the files and directories, with their - // properties. - // The properties of each entries in the list are (used also in other functions) : - // filename : Name of the file. For a create or add action it is the filename - // given by the user. For an extract function it is the filename - // of the extracted file. - // stored_filename : Name of the file / directory stored in the archive. - // size : Size of the stored file. - // compressed_size : Size of the file's data compressed in the archive - // (without the headers overhead) - // mtime : Last known modification date of the file (UNIX timestamp) - // comment : Comment associated with the file - // folder : true | false - // index : index of the file in the archive - // status : status of the action (depending of the action) : - // Values are : - // ok : OK ! - // filtered : the file / dir is not extracted (filtered by user) - // already_a_directory : the file can not be extracted because a - // directory with the same name already exists - // write_protected : the file can not be extracted because a file - // with the same name already exists and is - // write protected - // newer_exist : the file was not extracted because a newer file exists - // path_creation_fail : the file is not extracted because the folder - // does not exist and can not be created - // write_error : the file was not extracted because there was a - // error while writing the file - // read_error : the file was not extracted because there was a error - // while reading the file - // invalid_header : the file was not extracted because of an archive - // format error (bad file header) - // Note that each time a method can continue operating when there - // is an action error on a file, the error is only logged in the file status. - // Return Values : - // 0 on an unrecoverable failure, - // The list of the files in the archive. - // -------------------------------------------------------------------------------- - function listContent() + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : listContent() + // Description : + // This public method, gives the list of the files and directories, with their + // properties. + // The properties of each entries in the list are (used also in other functions) : + // filename : Name of the file. For a create or add action it is the filename + // given by the user. For an extract function it is the filename + // of the extracted file. + // stored_filename : Name of the file / directory stored in the archive. + // size : Size of the stored file. + // compressed_size : Size of the file's data compressed in the archive + // (without the headers overhead) + // mtime : Last known modification date of the file (UNIX timestamp) + // comment : Comment associated with the file + // folder : true | false + // index : index of the file in the archive + // status : status of the action (depending of the action) : + // Values are : + // ok : OK ! + // filtered : the file / dir is not extracted (filtered by user) + // already_a_directory : the file can not be extracted because a + // directory with the same name already exists + // write_protected : the file can not be extracted because a file + // with the same name already exists and is + // write protected + // newer_exist : the file was not extracted because a newer file exists + // path_creation_fail : the file is not extracted because the folder + // does not exist and can not be created + // write_error : the file was not extracted because there was a + // error while writing the file + // read_error : the file was not extracted because there was a error + // while reading the file + // invalid_header : the file was not extracted because of an archive + // format error (bad file header) + // Note that each time a method can continue operating when there + // is an action error on a file, the error is only logged in the file status. + // Return Values : + // 0 on an unrecoverable failure, + // The list of the files in the archive. + // -------------------------------------------------------------------------------- + function listContent() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Call the extracting fct + $p_list = array(); + if (($v_result = $this->privList($p_list)) != 1) { - $v_result=1; + unset($p_list); + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // extract($p_path="./", $p_remove_path="") + // extract([$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method extract all the files / directories from the archive to the + // folder indicated in $p_path. + // If you want to ignore the 'root' part of path of the memorized files + // you can indicate this in the optional $p_remove_path parameter. + // By default, if a newer file with the same name already exists, the + // file is not extracted. + // + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append + // at the end of the path value of PCLZIP_OPT_PATH. + // Parameters : + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 or a negative value on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function extract() + { + $v_result=1; - // ----- Reset the error handler - $this->privErrorReset(); + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; } - // ----- Call the extracting fct - $p_list = array(); - if (($v_result = $this->privList($p_list)) != 1) { - unset($p_list); - return(0); + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // extract($p_path="./", $p_remove_path="") - // extract([$p_option, $p_option_value, ...]) - // Description : - // This method supports two synopsis. The first one is historical. - // This method extract all the files / directories from the archive to the - // folder indicated in $p_path. - // If you want to ignore the 'root' part of path of the memorized files - // you can indicate this in the optional $p_remove_path parameter. - // By default, if a newer file with the same name already exists, the - // file is not extracted. - // - // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions - // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append - // at the end of the path value of PCLZIP_OPT_PATH. - // Parameters : - // $p_path : Path where the files and directories are to be extracted - // $p_remove_path : First part ('root' part) of the memorized path - // (if any similar) to remove while extracting. - // Options : - // PCLZIP_OPT_PATH : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_CB_PRE_EXTRACT : - // PCLZIP_CB_POST_EXTRACT : - // Return Values : - // 0 or a negative value on failure, - // The list of the extracted files, with a status of the action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function extract() - { - $v_result=1; + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { - // ----- Reset the error handler - $this->privErrorReset(); + // ----- Get the first argument + $v_path = $v_arg_list[0]; - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Set default values - $v_options = array(); - // $v_path = "./"; - $v_path = ''; - $v_remove_path = ""; - $v_remove_all_path = false; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Default values for option - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; - - // ----- Look for arguments - if ($v_size > 0) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array( - PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional', - PCLZIP_OPT_STOP_ON_ERROR => 'optional', - PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - ))); - if ($v_result != 1) { - return 0; - } - - // ----- Set the arguments - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - // ----- Check for '/' in last path char - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; - } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; - } - } else { - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the method. - // ----- Get the first argument - $v_path = $v_arg_list[0]; - - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; - } else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Return - return 0; - } - } + // ----- Return + return 0; } + } + } - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); - // ----- Trace + // ----- Trace - // ----- Call the extracting fct - $p_list = array(); - $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, - $v_remove_all_path, $v_options); - if ($v_result < 1) { - unset($p_list); - return(0); - } + // ----- Call the extracting fct + $p_list = array(); + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, + $v_remove_all_path, $v_options); + if ($v_result < 1) { + unset($p_list); + return(0); + } - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - - // -------------------------------------------------------------------------------- - // Function : - // extractByIndex($p_index, $p_path="./", $p_remove_path="") - // extractByIndex($p_index, [$p_option, $p_option_value, ...]) - // Description : - // This method supports two synopsis. The first one is historical. - // This method is doing a partial extract of the archive. - // The extracted files or folders are identified by their index in the - // archive (from 0 to n). - // Note that if the index identify a folder, only the folder entry is - // extracted, not all the files included in the archive. - // Parameters : - // $p_index : A single index (integer) or a string of indexes of files to - // extract. The form of the string is "0,4-6,8-12" with only numbers - // and '-' for range or ',' to separate ranges. No spaces or ';' - // are allowed. - // $p_path : Path where the files and directories are to be extracted - // $p_remove_path : First part ('root' part) of the memorized path - // (if any similar) to remove while extracting. - // Options : - // PCLZIP_OPT_PATH : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and - // not as files. - // The resulting content is in a new field 'content' in the file - // structure. - // This option must be used alone (any other options are ignored). - // PCLZIP_CB_PRE_EXTRACT : - // PCLZIP_CB_POST_EXTRACT : - // Return Values : - // 0 on failure, - // The list of the extracted files, with a status of the action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - //function extractByIndex($p_index, options...) - function extractByIndex($p_index) - { - $v_result=1; + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : + // extractByIndex($p_index, $p_path="./", $p_remove_path="") + // extractByIndex($p_index, [$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method is doing a partial extract of the archive. + // The extracted files or folders are identified by their index in the + // archive (from 0 to n). + // Note that if the index identify a folder, only the folder entry is + // extracted, not all the files included in the archive. + // Parameters : + // $p_index : A single index (integer) or a string of indexes of files to + // extract. The form of the string is "0,4-6,8-12" with only numbers + // and '-' for range or ',' to separate ranges. No spaces or ';' + // are allowed. + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and + // not as files. + // The resulting content is in a new field 'content' in the file + // structure. + // This option must be used alone (any other options are ignored). + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + //function extractByIndex($p_index, options...) + function extractByIndex($p_index) + { + $v_result=1; - // ----- Reset the error handler - $this->privErrorReset(); + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; } - // ----- Set default values - $v_options = array(); - // $v_path = "./"; - $v_path = ''; - $v_remove_path = ""; - $v_remove_all_path = false; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Default values for option - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove form the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array( - PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional', - PCLZIP_OPT_STOP_ON_ERROR => 'optional', - PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - ))); - if ($v_result != 1) { - return 0; - } - - // ----- Set the arguments - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - // ----- Check for '/' in last path char - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; - } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; - } - if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; - } - } else { - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the method. - - // ----- Get the first argument - $v_path = $v_arg_list[0]; - - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; - } else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - - // ----- Return - return 0; - } - } + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; } + else { + } + } - // ----- Trace + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { - // ----- Trick - // Here I want to reuse extractByRule(), so I need to parse the $p_index - // with privParseOptions() - $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); - $v_options_trick = array(); - $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, - array (PCLZIP_OPT_BY_INDEX => 'optional')); - if ($v_result != 1) { - return 0; - } - $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + // ----- Get the first argument + $v_path = $v_arg_list[0]; - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Call the extracting fct - if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { - return(0); + // ----- Return + return 0; } + } + } - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // delete([$p_option, $p_option_value, ...]) - // Description : - // This method removes files from the archive. - // If no parameters are given, then all the archive is emptied. - // Parameters : - // None or optional arguments. - // Options : - // PCLZIP_OPT_BY_INDEX : - // PCLZIP_OPT_BY_NAME : - // PCLZIP_OPT_BY_EREG : - // PCLZIP_OPT_BY_PREG : - // Return Values : - // 0 on failure, - // The list of the files which are still present in the archive. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function delete() -{ -$v_result=1; - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Check archive -if (!$this->privCheckFormat()) { - return(0); -} - -// ----- Set default values -$v_options = array(); - -// ----- Look for variable options arguments -$v_size = func_num_args(); - -// ----- Look for arguments -if ($v_size > 0) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional')); - if ($v_result != 1) { - return 0; + // ----- Trace + + // ----- Trick + // Here I want to reuse extractByRule(), so I need to parse the $p_index + // with privParseOptions() + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); + $v_options_trick = array(); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, + array (PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; + } + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Call the extracting fct + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + return(0); + } + + // ----- Return + return $p_list; } -} + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // delete([$p_option, $p_option_value, ...]) + // Description : + // This method removes files from the archive. + // If no parameters are given, then all the archive is emptied. + // Parameters : + // None or optional arguments. + // Options : + // PCLZIP_OPT_BY_INDEX : + // PCLZIP_OPT_BY_NAME : + // PCLZIP_OPT_BY_EREG : + // PCLZIP_OPT_BY_PREG : + // Return Values : + // 0 on failure, + // The list of the files which are still present in the archive. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function delete() + { + $v_result=1; -// ----- Magic quotes trick -$this->privDisableMagicQuotes(); + // ----- Reset the error handler + $this->privErrorReset(); -// ----- Call the delete fct -$v_list = array(); -if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { - $this->privSwapBackMagicQuotes(); - unset($v_list); - return(0); -} + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } -// ----- Magic quotes trick -$this->privSwapBackMagicQuotes(); + // ----- Set default values + $v_options = array(); -// ----- Return -return $v_list; -} -// -------------------------------------------------------------------------------- + // ----- Look for variable options arguments + $v_size = func_num_args(); -// -------------------------------------------------------------------------------- -// Function : deleteByIndex() -// Description : -// ***** Deprecated ***** -// delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. -// -------------------------------------------------------------------------------- -function deleteByIndex($p_index) -{ + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; + } + } -$p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); -// ----- Return -return $p_list; -} -// -------------------------------------------------------------------------------- + // ----- Call the delete fct + $v_list = array(); + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); + return(0); + } -// -------------------------------------------------------------------------------- -// Function : properties() -// Description : -// This method gives the properties of the archive. -// The properties are : -// nb : Number of files in the archive -// comment : Comment associated with the archive file -// status : not_exist, ok -// Parameters : -// None -// Return Values : -// 0 on failure, -// An array with the archive properties. -// -------------------------------------------------------------------------------- -function properties() -{ - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Magic quotes trick -$this->privDisableMagicQuotes(); - -// ----- Check archive -if (!$this->privCheckFormat()) { - $this->privSwapBackMagicQuotes(); - return(0); -} - -// ----- Default properties -$v_prop = array(); -$v_prop['comment'] = ''; -$v_prop['nb'] = 0; -$v_prop['status'] = 'not_exist'; - -// ----- Look if file exists -if (@is_file($this->zipname)) -{ - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) - { + // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); // ----- Return - return 0; + return $v_list; } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : deleteByIndex() + // Description : + // ***** Deprecated ***** + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. + // -------------------------------------------------------------------------------- + function deleteByIndex($p_index) { - $this->privSwapBackMagicQuotes(); - return 0; + + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + + // ----- Return + return $p_list; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : properties() + // Description : + // This method gives the properties of the archive. + // The properties are : + // nb : Number of files in the archive + // comment : Comment associated with the archive file + // status : not_exist, ok + // Parameters : + // None + // Return Values : + // 0 on failure, + // An array with the archive properties. + // -------------------------------------------------------------------------------- + function properties() + { - // ----- Close the zip file - $this->privCloseFd(); + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Set the user attributes - $v_prop['comment'] = $v_central_dir['comment']; - $v_prop['nb'] = $v_central_dir['entries']; - $v_prop['status'] = 'ok'; -} + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); -// ----- Magic quotes trick -$this->privSwapBackMagicQuotes(); + // ----- Check archive + if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + return(0); + } -// ----- Return -return $v_prop; -} -// -------------------------------------------------------------------------------- + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; -// -------------------------------------------------------------------------------- -// Function : duplicate() -// Description : -// This method creates an archive by copying the content of an other one. If -// the archive already exist, it is replaced by the new one without any warning. -// Parameters : -// $p_archive : The filename of a valid archive, or -// a valid PclZip object. -// Return Values : -// 1 on success. -// 0 or a negative value on error (error code). -// -------------------------------------------------------------------------------- -function duplicate($p_archive) -{ -$v_result = 1; - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Look if the $p_archive is a PclZip object -if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) -{ - - // ----- Duplicate the archive - $v_result = $this->privDuplicate($p_archive->zipname); -} - -// ----- Look if the $p_archive is a string (so a filename) -else if (is_string($p_archive)) -{ - - // ----- Check that $p_archive is a valid zip file - // TBC : Should also check the archive format - if (!is_file($p_archive)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); - $v_result = PCLZIP_ERR_MISSING_FILE; - } - else { - // ----- Duplicate the archive - $v_result = $this->privDuplicate($p_archive); - } -} - -// ----- Invalid variable -else -{ - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Look if file exists + if (@is_file($this->zipname)) + { + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); -// -------------------------------------------------------------------------------- -// Function : merge() -// Description : -// This method merge the $p_archive_to_add archive at the end of the current -// one ($this). -// If the archive ($this) does not exist, the merge becomes a duplicate. -// If the $p_archive_to_add archive does not exist, the merge is a success. -// Parameters : -// $p_archive_to_add : It can be directly the filename of a valid zip archive, -// or a PclZip object archive. -// Return Values : -// 1 on success, -// 0 or negative values on error (see below). -// -------------------------------------------------------------------------------- -function merge($p_archive_to_add) -{ -$v_result = 1; - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Check archive -if (!$this->privCheckFormat()) { - return(0); -} - -// ----- Look if the $p_archive_to_add is a PclZip object -if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) -{ - - // ----- Merge the archive - $v_result = $this->privMerge($p_archive_to_add); -} - -// ----- Look if the $p_archive_to_add is a string (so a filename) -else if (is_string($p_archive_to_add)) -{ - - // ----- Create a temporary archive - $v_object_archive = new PclZip($p_archive_to_add); - - // ----- Merge the archive - $v_result = $this->privMerge($v_object_archive); -} - -// ----- Invalid variable -else -{ - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Return + return 0; + } + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return 0; + } + // ----- Close the zip file + $this->privCloseFd(); -// -------------------------------------------------------------------------------- -// Function : errorCode() -// Description : -// Parameters : -// -------------------------------------------------------------------------------- -function errorCode() -{ -if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorCode()); -} -else { - return($this->error_code); -} -} -// -------------------------------------------------------------------------------- + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } -// -------------------------------------------------------------------------------- -// Function : errorName() -// Description : -// Parameters : -// -------------------------------------------------------------------------------- -function errorName($p_with_code=false) -{ -$v_name = array (PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', - PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', - PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', - PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', - PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', - PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', - PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', - PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', - PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', - PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', - PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', - PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', - PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', - PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', - PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', - PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', - PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', - PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', - PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' - ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' - ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' - ) ); - -if (isset($v_name[$this->error_code])) { - $v_value = $v_name[$this->error_code]; -} -else { - $v_value = 'NoName'; -} - -if ($p_with_code) { - return($v_value.' ('.$this->error_code.')'); -} -else { - return($v_value); -} -} -// -------------------------------------------------------------------------------- + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); -// -------------------------------------------------------------------------------- -// Function : errorInfo() -// Description : -// Parameters : -// -------------------------------------------------------------------------------- -function errorInfo($p_full=false) -{ -if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorString()); -} -else { - if ($p_full) { - return($this->errorName(true)." : ".$this->error_string); - } - else { - return($this->error_string." [code ".$this->error_code."]"); + // ----- Return + return $v_prop; } -} -} -// -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : duplicate() + // Description : + // This method creates an archive by copying the content of an other one. If + // the archive already exist, it is replaced by the new one without any warning. + // Parameters : + // $p_archive : The filename of a valid archive, or + // a valid PclZip object. + // Return Values : + // 1 on success. + // 0 or a negative value on error (error code). + // -------------------------------------------------------------------------------- + function duplicate($p_archive) + { + $v_result = 1; + // ----- Reset the error handler + $this->privErrorReset(); -// -------------------------------------------------------------------------------- -// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** -// ***** ***** -// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** -// -------------------------------------------------------------------------------- + // ----- Look if the $p_archive is a PclZip object + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) + { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); + } + // ----- Look if the $p_archive is a string (so a filename) + else if (is_string($p_archive)) + { + + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } + else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : merge() + // Description : + // This method merge the $p_archive_to_add archive at the end of the current + // one ($this). + // If the archive ($this) does not exist, the merge becomes a duplicate. + // If the $p_archive_to_add archive does not exist, the merge is a success. + // Parameters : + // $p_archive_to_add : It can be directly the filename of a valid zip archive, + // or a PclZip object archive. + // Return Values : + // 1 on success, + // 0 or negative values on error (see below). + // -------------------------------------------------------------------------------- + function merge($p_archive_to_add) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Look if the $p_archive_to_add is a PclZip object + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) + { + + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); + } + + // ----- Look if the $p_archive_to_add is a string (so a filename) + else if (is_string($p_archive_to_add)) + { + + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : errorCode() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorCode() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorCode()); + } + else { + return($this->error_code); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorName() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorName($p_with_code=false) + { + $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' + ); + + if (isset($v_name[$this->error_code])) { + $v_value = $v_name[$this->error_code]; + } + else { + $v_value = 'NoName'; + } + + if ($p_with_code) { + return($v_value.' ('.$this->error_code.')'); + } + else { + return($v_value); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorInfo() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorInfo($p_full=false) + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorString()); + } + else { + if ($p_full) { + return($this->errorName(true)." : ".$this->error_string); + } + else { + return($this->error_string." [code ".$this->error_code."]"); + } + } + } + // -------------------------------------------------------------------------------- -// -------------------------------------------------------------------------------- -// Function : privCheckFormat() -// Description : -// This method check that the archive exists and is a valid zip archive. -// Several level of check exists. (futur) -// Parameters : -// $p_level : Level of check. Default 0. -// 0 : Check the first bytes (magic codes) (default value)) -// 1 : 0 + Check the central directory (futur) -// 2 : 1 + Check each file header (futur) -// Return Values : -// true on success, -// false on error, the error code is set. -// -------------------------------------------------------------------------------- -function privCheckFormat($p_level=0) -{ -$v_result = true; - -// ----- Reset the file system cache -clearstatcache(); - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Look if the file exits -if (!is_file($this->zipname)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); - return(false); -} - -// ----- Check that the file is readeable -if (!is_readable($this->zipname)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); - return(false); -} - -// ----- Check the magic code -// TBC - -// ----- Check the central header -// TBC - -// ----- Check each file header -// TBC - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- -// Function : privParseOptions() -// Description : -// This internal methods reads the variable list of arguments ($p_options_list, -// $p_size) and generate an array with the options and values ($v_result_list). -// $v_requested_options contains the options that can be present and those that -// must be present. -// $v_requested_options is an array, with the option value as key, and 'optional', -// or 'mandatory' as value. -// Parameters : -// See above. -// Return Values : -// 1 on success. -// 0 on failure. +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** +// ***** ***** +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** // -------------------------------------------------------------------------------- -function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) -{ -$v_result=1; -// ----- Read the options -$i=0; -while ($i<$p_size) { - // ----- Check if the option is supported - if (!isset($v_requested_options[$p_options_list[$i]])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); + + // -------------------------------------------------------------------------------- + // Function : privCheckFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // -------------------------------------------------------------------------------- + function privCheckFormat($p_level=0) + { + $v_result = true; + + // ----- Reset the file system cache + clearstatcache(); + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the file exits + if (!is_file($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); + return(false); + } + + // ----- Check that the file is readeable + if (!is_readable($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); + return(false); + } + + // ----- Check the magic code + // TBC + + // ----- Check the central header + // TBC + + // ----- Check each file header + // TBC + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privParseOptions() + // Description : + // This internal methods reads the variable list of arguments ($p_options_list, + // $p_size) and generate an array with the options and values ($v_result_list). + // $v_requested_options contains the options that can be present and those that + // must be present. + // $v_requested_options is an array, with the option value as key, and 'optional', + // or 'mandatory' as value. + // Parameters : + // See above. + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) + { + $v_result=1; + + // ----- Read the options + $i=0; + while ($i<$p_size) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$p_options_list[$i]])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for next option + switch ($p_options_list[$i]) { + // ----- Look for options that request a path value + case PCLZIP_OPT_PATH : + case PCLZIP_OPT_REMOVE_PATH : + case PCLZIP_OPT_ADD_PATH : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_THRESHOLD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + // ----- Check the value + $v_value = $p_options_list[$i+1]; + if ((!is_integer($v_value)) || ($v_value<0)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Get the value (and convert it in bytes) + $v_result_list[$p_options_list[$i]] = $v_value*1048576; + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_ON : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_TEMP_FILE_OFF : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); + return PclZip::errorCode(); + } + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if ( is_string($p_options_list[$i+1]) + && ($p_options_list[$i+1] != '')) { + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + } + else { + } + break; + + // ----- Look for options that request an array of string for value + case PCLZIP_OPT_BY_NAME : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an EREG or PREG expression + case PCLZIP_OPT_BY_EREG : + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG + // to PCLZIP_OPT_BY_PREG + $p_options_list[$i] = PCLZIP_OPT_BY_PREG; + case PCLZIP_OPT_BY_PREG : + //case PCLZIP_OPT_CRYPT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that takes a string + case PCLZIP_OPT_COMMENT : + case PCLZIP_OPT_ADD_COMMENT : + case PCLZIP_OPT_PREPEND_COMMENT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, + "Missing parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, + "Wrong parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an array of index + case PCLZIP_OPT_BY_INDEX : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_work_list = array(); + if (is_string($p_options_list[$i+1])) { + + // ----- Remove spaces + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); + + // ----- Parse items + $v_work_list = explode(",", $p_options_list[$i+1]); + } + else if (is_integer($p_options_list[$i+1])) { + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_work_list = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Reduce the index list + // each index item in the list must be a couple with a start and + // an end value : [0,3], [5-5], [8-10], ... + // ----- Check the format of each item + $v_sort_flag=false; + $v_sort_value=0; + for ($j=0; $j<sizeof($v_work_list); $j++) { + // ----- Explode the item + $v_item_list = explode("-", $v_work_list[$j]); + $v_size_item_list = sizeof($v_item_list); + + // ----- TBC : Here we might check that each item is a + // real integer ... + + // ----- Look for single value + if ($v_size_item_list == 1) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; + } + elseif ($v_size_item_list == 2) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + + // ----- Look for list sort + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { + $v_sort_flag=true; + + // ----- TBC : An automatic sort should be writen ... + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; + } + + // ----- Sort the items + if ($v_sort_flag) { + // TBC : To Be Completed + } + + // ----- Next option + $i++; + break; + + // ----- Look for options that request no value + case PCLZIP_OPT_REMOVE_ALL_PATH : + case PCLZIP_OPT_EXTRACT_AS_STRING : + case PCLZIP_OPT_NO_COMPRESSION : + case PCLZIP_OPT_EXTRACT_IN_OUTPUT : + case PCLZIP_OPT_REPLACE_NEWER : + case PCLZIP_OPT_STOP_ON_ERROR : + $v_result_list[$p_options_list[$i]] = true; + break; + + // ----- Look for options that request an octal value + case PCLZIP_OPT_SET_CHMOD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + $i++; + break; + + // ----- Look for options that request a call-back + case PCLZIP_CB_PRE_EXTRACT : + case PCLZIP_CB_POST_EXTRACT : + case PCLZIP_CB_PRE_ADD : + case PCLZIP_CB_POST_ADD : + /* for futur use + case PCLZIP_CB_PRE_DELETE : + case PCLZIP_CB_POST_DELETE : + case PCLZIP_CB_PRE_LIST : + case PCLZIP_CB_POST_LIST : + */ + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_function_name = $p_options_list[$i+1]; + + // ----- Check that the value is a valid existing function + if (!function_exists($v_function_name)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Set the attribute + $v_result_list[$p_options_list[$i]] = $v_function_name; + $i++; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '" + .$p_options_list[$i]."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Next options + $i++; + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($v_result_list[$key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + + // ----- Return + return PclZip::errorCode(); + } + } + } + } + + // ----- Look for default values + if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOptionDefaultThreshold() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privOptionDefaultThreshold(&$p_options) + { + $v_result=1; + + if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { + return $v_result; + } + + // ----- Get 'memory_limit' configuration value + $v_memory_limit = ini_get('memory_limit'); + $v_memory_limit = trim($v_memory_limit); + $last = strtolower(substr($v_memory_limit, -1)); + + if ($last == 'g') + //$v_memory_limit = $v_memory_limit*1024*1024*1024; + $v_memory_limit = $v_memory_limit*1073741824; + if ($last == 'm') + //$v_memory_limit = $v_memory_limit*1024*1024; + $v_memory_limit = $v_memory_limit*1048576; + if ($last == 'k') + $v_memory_limit = $v_memory_limit*1024; + + $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); + + + // ----- Sanity check : No threshold if value lower than 1M + if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { + unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrParseAtt() + // Description : + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) + { + $v_result=1; + + // ----- For each file in the list check the attributes + foreach ($p_file_list as $v_key => $v_value) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$v_key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for attribute + switch ($v_key) { + case PCLZIP_ATT_FILE_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['filename'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + break; + + case PCLZIP_ATT_FILE_NEW_SHORT_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_short_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + + case PCLZIP_ATT_FILE_NEW_FULL_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_full_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + + // ----- Look for options that takes a string + case PCLZIP_ATT_FILE_COMMENT : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['comment'] = $v_value; + break; + + case PCLZIP_ATT_FILE_MTIME : + if (!is_integer($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['mtime'] = $v_value; + break; + + case PCLZIP_ATT_FILE_CONTENT : + $p_filedescr['content'] = $v_value; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '".$v_key."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($p_file_list[$key])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + return PclZip::errorCode(); + } + } + } + } + + // end foreach + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrExpand() + // Description : + // This method look for each item of the list to see if its a file, a folder + // or a string to be added as file. For any other type of files (link, other) + // just ignore the item. + // Then prepare the information that will be stored for that file. + // When its a folder, expand the folder with all the files that are in that + // folder (recursively). + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrExpand(&$p_filedescr_list, &$p_options) + { + $v_result=1; + + // ----- Create a result list + $v_result_list = array(); + + // ----- Look each entry + for ($i=0; $i<sizeof($p_filedescr_list); $i++) { + + // ----- Get filedescr + $v_descr = $p_filedescr_list[$i]; + + // ----- Reduce the filename + $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); + $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); + + // ----- Look for real file or folder + if (file_exists($v_descr['filename'])) { + if (@is_file($v_descr['filename'])) { + $v_descr['type'] = 'file'; + } + else if (@is_dir($v_descr['filename'])) { + $v_descr['type'] = 'folder'; + } + else if (@is_link($v_descr['filename'])) { + // skip + continue; + } + else { + // skip + continue; + } + } + + // ----- Look for string added as file + else if (isset($v_descr['content'])) { + $v_descr['type'] = 'virtual_file'; + } + + // ----- Missing file + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Calculate the stored filename + $this->privCalculateStoredFilename($v_descr, $p_options); + + // ----- Add the descriptor in result list + $v_result_list[sizeof($v_result_list)] = $v_descr; + + // ----- Look for folder + if ($v_descr['type'] == 'folder') { + // ----- List of items in folder + $v_dirlist_descr = array(); + $v_dirlist_nb = 0; + if ($v_folder_handler = @opendir($v_descr['filename'])) { + while (($v_item_handler = @readdir($v_folder_handler)) !== false) { + + // ----- Skip '.' and '..' + if (($v_item_handler == '.') || ($v_item_handler == '..')) { + continue; + } + + // ----- Compose the full filename + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; + + // ----- Look for different stored filename + // Because the name of the folder was changed, the name of the + // files/sub-folders also change + if (($v_descr['stored_filename'] != $v_descr['filename']) + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { + if ($v_descr['stored_filename'] != '') { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; + } + else { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; + } + } + + $v_dirlist_nb++; + } + + @closedir($v_folder_handler); + } + else { + // TBC : unable to open folder in read mode + } + + // ----- Expand each element of the list + if ($v_dirlist_nb != 0) { + // ----- Expand + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { + return $v_result; + } + + // ----- Concat the resulting list + $v_result_list = array_merge($v_result_list, $v_dirlist_descr); + } + else { + } + + // ----- Free local array + unset($v_dirlist_descr); + } + } + + // ----- Get the result list + $p_filedescr_list = $v_result_list; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCreate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCreate($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the file in write mode + if (($v_result = $this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Add the list of files + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); + + // ----- Close + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAdd() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAdd($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Look if the archive exists or is empty + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) + { + + // ----- Do a create + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); + + // ----- Return + return $v_result; + } + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) + { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = $v_central_dir['comment']; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOpenFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privOpenFd($p_mode) + { + $v_result=1; + + // ----- Look if already open + if ($this->zip_fd != 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCloseFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privCloseFd() + { + $v_result=1; + + if ($this->zip_fd != 0) + @fclose($this->zip_fd); + $this->zip_fd = 0; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // -------------------------------------------------------------------------------- +// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) + function privAddList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) + { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } // ----- Return - return PclZip::errorCode(); + return $v_result; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileList() + // Description : + // Parameters : + // $p_filedescr_list : An array containing the file description + // or directory names to add in the zip + // $p_result_list : list of added files with their properties (specially the status field) + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_header = array(); - // ----- Look for next option - switch ($p_options_list[$i]) { - // ----- Look for options that request a path value - case PCLZIP_OPT_PATH : - case PCLZIP_OPT_REMOVE_PATH : - case PCLZIP_OPT_ADD_PATH : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false); - $i++; - break; + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); - case PCLZIP_OPT_TEMP_FILE_THRESHOLD : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } + // ----- Loop on the files + for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { + // ----- Format the filename + $p_filedescr_list[$j]['filename'] + = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); - return PclZip::errorCode(); + + // ----- Skip empty file names + // TBC : Can this be possible ? not checked in DescrParseAtt ? + if ($p_filedescr_list[$j]['filename'] == "") { + continue; } - - // ----- Check the value - $v_value = $p_options_list[$i+1]; - if ((!is_integer($v_value)) || ($v_value<0)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Check the filename + if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') + && (!file_exists($p_filedescr_list[$j]['filename']))) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); return PclZip::errorCode(); } - // ----- Get the value (and convert it in bytes) - $v_result_list[$p_options_list[$i]] = $v_value*1048576; - $i++; - break; + // ----- Look if it is a file or a dir with no all path remove option + // or a dir with all its path removed +// if ( (is_file($p_filedescr_list[$j]['filename'])) +// || ( is_dir($p_filedescr_list[$j]['filename']) + if ( ($p_filedescr_list[$j]['type'] == 'file') + || ($p_filedescr_list[$j]['type'] == 'virtual_file') + || ( ($p_filedescr_list[$j]['type'] == 'folder') + && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) + || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) + ) { + + // ----- Add the file + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, + $p_options); + if ($v_result != 1) { + return $v_result; + } - case PCLZIP_OPT_TEMP_FILE_ON : - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); - return PclZip::errorCode(); + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; } - - $v_result_list[$p_options_list[$i]] = true; - break; + } - case PCLZIP_OPT_TEMP_FILE_OFF : - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); - return PclZip::errorCode(); - } - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); - return PclZip::errorCode(); - } - - $v_result_list[$p_options_list[$i]] = true; - break; + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=1; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; - case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // TBC : Already done in the fileAtt check ... ? + if ($p_filename == "") { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); - // ----- Return - return PclZip::errorCode(); - } + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for a stored different filename + /* TBC : Removed + if (isset($p_filedescr['stored_filename'])) { + $v_stored_filename = $p_filedescr['stored_filename']; + } + else { + $v_stored_filename = $p_filedescr['stored_filename']; + } + */ - // ----- Get the value - if (is_string($p_options_list[$i+1]) - && ($p_options_list[$i+1] != '')) { - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false); - $i++; - } - else { - } - break; + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; +// TBC : Removed $p_header['stored_filename'] = $v_stored_filename; + $p_header['stored_filename'] = $p_filedescr['stored_filename']; + $p_header['extra'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; + + // ----- Look for regular file + if ($p_filedescr['type']=='file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for regular folder + else if ($p_filedescr['type']=='folder') { + $p_header['external'] = 0x00000010; + $p_header['mtime'] = filemtime($p_filename); + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for virtual file + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = strlen($p_filedescr['content']); + } + - // ----- Look for options that request an array of string for value - case PCLZIP_OPT_BY_NAME : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Look for filetime + if (isset($p_filedescr['mtime'])) { + $p_header['mtime'] = $p_filedescr['mtime']; + } + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['mtime'] = time(); + } + else { + $p_header['mtime'] = filemtime($p_filename); + } - // ----- Return - return PclZip::errorCode(); - } + // ------ Look for file comment + if (isset($p_filedescr['comment'])) { + $p_header['comment_len'] = strlen($p_filedescr['comment']); + $p_header['comment'] = $p_filedescr['comment']; + } + else { + $p_header['comment_len'] = 0; + $p_header['comment'] = ''; + } - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; - } - else if (is_array($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Look for pre-add callback + if (isset($p_options[PCLZIP_CB_PRE_ADD])) { - // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that request an EREG or PREG expression - case PCLZIP_OPT_BY_EREG : - // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG - // to PCLZIP_OPT_BY_PREG - $p_options_list[$i] = PCLZIP_OPT_BY_PREG; - case PCLZIP_OPT_BY_PREG : - //case PCLZIP_OPT_CRYPT : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); - // ----- Return - return PclZip::errorCode(); + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; } - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + } - // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that takes a string - case PCLZIP_OPT_COMMENT : - case PCLZIP_OPT_ADD_COMMENT : - case PCLZIP_OPT_PREPEND_COMMENT : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, - "Missing parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } + + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; + } - // ----- Return - return PclZip::errorCode(); - } + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { + + // ----- Look for a file + if ($p_filedescr['type'] == 'file') { + // ----- Look for using temporary file to zip + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { + $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } + + // ----- Use "in memory" zip algo + else { - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, - "Wrong parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); + + // ----- Close the file + @fclose($v_file); + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + + } - // ----- Return - return PclZip::errorCode(); } - $i++; - break; - // ----- Look for options that request an array of index - case PCLZIP_OPT_BY_INDEX : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Look for a virtual file (a file from string) + else if ($p_filedescr['type'] == 'virtual_file') { + + $v_content = $p_filedescr['content']; - // ----- Return - return PclZip::errorCode(); + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); } - // ----- Get the value - $v_work_list = array(); - if (is_string($p_options_list[$i+1])) { + // ----- Look for a directory + else if ($p_filedescr['type'] == 'folder') { + // ----- Look for directory last '/' + if (@substr($p_header['stored_filename'], -1) != '/') { + $p_header['stored_filename'] .= '/'; + } - // ----- Remove spaces - $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); + // ----- Set the file properties + $p_header['size'] = 0; + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + $p_header['external'] = 0x00000010; // Value for a folder : to be checked - // ----- Parse items - $v_work_list = explode(",", $p_options_list[$i+1]); + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) + { + return $v_result; + } } - else if (is_integer($p_options_list[$i+1])) { - $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; + } + + // ----- Look for post-add callback + if (isset($p_options[PCLZIP_CB_POST_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; } - else if (is_array($p_options_list[$i+1])) { - $v_work_list = $p_options_list[$i+1]; + + // ----- Update the informations + // Nothing can be modified + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=PCLZIP_ERR_NO_ERROR; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Creates a compressed temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = filesize($p_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @gzputs($v_file_compressed, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file); + @gzclose($v_file_compressed); + + // ----- Check the minimum file size + if (filesize($v_gzip_temp_name) < 18) { + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); + return PclZip::errorCode(); + } + + // ----- Extract the compressed attributes + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the gzip file header + $v_binary_data = @fread($v_file_compressed, 10); + $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); + + // ----- Check some parameters + $v_data_header['os'] = bin2hex($v_data_header['os']); + + // ----- Read the gzip file footer + @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); + $v_binary_data = @fread($v_file_compressed, 8); + $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); + + // ----- Set the attributes + $p_header['compression'] = ord($v_data_header['cm']); + //$p_header['mtime'] = $v_data_header['mtime']; + $p_header['crc'] = $v_data_footer['crc']; + $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + return $v_result; + } + + // ----- Add the compressed data + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) + { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + fseek($v_file_compressed, 10); + $v_size = $p_header['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file_compressed, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Unlink the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCalculateStoredFilename() + // Description : + // Based on file descriptor properties and global options, this method + // calculate the filename that will be stored in the archive. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCalculateStoredFilename(&$p_filedescr, &$p_options) + { + $v_result=1; + + // ----- Working variables + $p_filename = $p_filedescr['filename']; + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; + } + else { + $p_add_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; + } + else { + $p_remove_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + else { + $p_remove_all_dir = 0; + } + + + // ----- Look for full name change + if (isset($p_filedescr['new_full_name'])) { + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); + } + + // ----- Look for path and/or short name change + else { + + // ----- Look for short name change + // Its when we cahnge just the filename but not the path + if (isset($p_filedescr['new_short_name'])) { + $v_path_info = pathinfo($p_filename); + $v_dir = ''; + if ($v_path_info['dirname'] != '') { + $v_dir = $v_path_info['dirname'].'/'; + } + $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; } else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + } - // ----- Return - return PclZip::errorCode(); + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); } - - // ----- Reduce the index list - // each index item in the list must be a couple with a start and - // an end value : [0,3], [5-5], [8-10], ... - // ----- Check the format of each item - $v_sort_flag=false; - $v_sort_value=0; - for ($j=0; $j<sizeof($v_work_list); $j++) { - // ----- Explode the item - $v_item_list = explode("-", $v_work_list[$j]); - $v_size_item_list = sizeof($v_item_list); - - // ----- TBC : Here we might check that each item is a - // real integer ... - - // ----- Look for single value - if ($v_size_item_list == 1) { - // ----- Set the option value - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; + // ----- Look for partial path remove + else if ($p_remove_dir != "") { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + + if ( (substr($p_filename, 0, 2) == "./") + || (substr($p_remove_dir, 0, 2) == "./")) { + + if ( (substr($p_filename, 0, 2) == "./") + && (substr($p_remove_dir, 0, 2) != "./")) { + $p_remove_dir = "./".$p_remove_dir; } - elseif ($v_size_item_list == 2) { - // ----- Set the option value - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; + if ( (substr($p_filename, 0, 2) != "./") + && (substr($p_remove_dir, 0, 2) == "./")) { + $p_remove_dir = substr($p_remove_dir, 2); + } + } + + $v_compare = PclZipUtilPathInclusion($p_remove_dir, + $v_stored_filename); + if ($v_compare > 0) { + if ($v_compare == 2) { + $v_stored_filename = ""; } else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + $v_stored_filename = substr($v_stored_filename, + strlen($p_remove_dir)); + } + } + } + + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); + + // ----- Look for path to add + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } + } + + // ----- Filename (reduce the path of stored name) + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); + $p_filedescr['stored_filename'] = $v_stored_filename; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteFileHeader(&$p_header) + { + $v_result=1; + + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->zip_fd); + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, + $p_header['version_extracted'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], + $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len']); + + // ----- Write the first 148 bytes of the header in the archive + fputs($this->zip_fd, $v_binary_data, 30); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralFileHeader(&$p_header) + { + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, + $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], + $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], + $p_header['external'], $p_header['offset']); + + // ----- Write the 42 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 46); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) + { + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) + { + $v_result=1; - // ----- Return - return PclZip::errorCode(); - } + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, + $p_nb_entries, $p_size, + $p_offset, strlen($p_comment)); + // ----- Write the 22 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 22); - // ----- Look for list sort - if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { - $v_sort_flag=true; + // ----- Write the variable fields + if (strlen($p_comment) != 0) + { + fputs($this->zip_fd, $p_comment, strlen($p_comment)); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privList() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privList(&$p_list) + { + $v_result=1; - // ----- TBC : An automatic sort should be writen ... - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - // ----- Return - return PclZip::errorCode(); - } - $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; - } + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); - // ----- Sort the items - if ($v_sort_flag) { - // TBC : To Be Completed - } + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - // ----- Next option - $i++; - break; - - // ----- Look for options that request no value - case PCLZIP_OPT_REMOVE_ALL_PATH : - case PCLZIP_OPT_EXTRACT_AS_STRING : - case PCLZIP_OPT_NO_COMPRESSION : - case PCLZIP_OPT_EXTRACT_IN_OUTPUT : - case PCLZIP_OPT_REPLACE_NEWER : - case PCLZIP_OPT_STOP_ON_ERROR : - $v_result_list[$p_options_list[$i]] = true; - break; - - // ----- Look for options that request an octal value - case PCLZIP_OPT_SET_CHMOD : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } - // ----- Return - return PclZip::errorCode(); - } + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } - // ----- Get the value - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - $i++; - break; - - // ----- Look for options that request a call-back - case PCLZIP_CB_PRE_EXTRACT : - case PCLZIP_CB_POST_EXTRACT : - case PCLZIP_CB_PRE_ADD : - case PCLZIP_CB_POST_ADD : - /* for futur use - case PCLZIP_CB_PRE_DELETE : - case PCLZIP_CB_POST_DELETE : - case PCLZIP_CB_PRE_LIST : - case PCLZIP_CB_POST_LIST : - */ - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Go to beginning of Central Dir + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_central_dir['offset'])) + { + $this->privSwapBackMagicQuotes(); - // ----- Return - return PclZip::errorCode(); - } + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - // ----- Get the value - $v_function_name = $p_options_list[$i+1]; + // ----- Return + return PclZip::errorCode(); + } - // ----- Check that the value is a valid existing function - if (!function_exists($v_function_name)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VA )); - if ($v_result != 1) { - return 0; + // ----- Read each entry + for ($i=0; $i<$v_central_dir['entries']; $i++) + { + // ----- Read the file header + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + $v_header['index'] = $i; + + // ----- Get the only interesting attributes + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); } - } - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { + // ----- Close the zip file + $this->privCloseFd(); - // ----- Get the first argument - $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; - } - else if ($v_size > 2) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Invalid number / type of arguments"); - return 0; - } + // ----- Return + return $v_result; } -} + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privConvertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // $p_info['crc'] = CRC of the file content. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privConvertHeader2FileInfo($p_header, &$p_info) + { + $v_result=1; + + // ----- Get the interesting attributes + $v_temp_path = PclZipUtilPathReduction($p_header['filename']); + $p_info['filename'] = $v_temp_path; + $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); + $p_info['stored_filename'] = $v_temp_path; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + $p_info['crc'] = $p_header['crc']; -// ----- Look for default option values -$this->privOptionDefaultThreshold($v_options); + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // -------------------------------------------------------------------------------- + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; -// ----- Init -$v_string_list = array(); -$v_att_list = array(); -$v_filedescr_list = array(); -$p_result_list = array(); + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); -// ----- Look if the $p_filelist is really an array -if (is_array($p_filelist)) { + // ----- Check the path + if ( ($p_path == "") + || ( (substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") + && (substr($p_path,1,2)!=":/"))) + $p_path = "./".$p_path; - // ----- Look if the first element is also an array - // This will mean that this is a file description entry - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; - } - - // ----- The list is a list of string names - else { - $v_string_list = $p_filelist; - } -} - -// ----- Look if the $p_filelist is a string -else if (is_string($p_filelist)) { - // ----- Create a list from the string - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); -} - -// ----- Invalid variable type for $p_filelist -else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); - return 0; -} - -// ----- Reformat the string list -if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - if ($v_string != '') { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; - } - else { + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) + { + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") + { + $p_path = substr($p_path, 0, strlen($p_path)-1); + } } - } -} - -// ----- For each file in the list check the attributes -$v_supported_attributes -= array (PCLZIP_ATT_FILE_NAME => 'mandatory' - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' - ,PCLZIP_ATT_FILE_MTIME => 'optional' - ,PCLZIP_ATT_FILE_CONTENT => 'optional' - ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); -foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, - $v_filedescr_list[], - $v_options, - $v_supported_attributes); - if ($v_result != 1) { - return 0; - } -} - -// ----- Expand the filelist (expand directories) -$v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); -if ($v_result != 1) { - return 0; -} - -// ----- Call the create fct -$v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); -if ($v_result != 1) { - return 0; -} - -// ----- Return -return $p_result_list; -} -// -------------------------------------------------------------------------------- -// -------------------------------------------------------------------------------- -// Function : -// add($p_filelist, $p_add_dir="", $p_remove_dir="") -// add($p_filelist, $p_option, $p_option_value, ...) -// Description : -// This method supports two synopsis. The first one is historical. -// This methods add the list of files in an existing archive. -// If a file with the same name already exists, it is added at the end of the -// archive, the first one is still present. -// If the archive does not exist, it is created. -// Parameters : -// $p_filelist : An array containing file or directory names, or -// a string containing one filename or one directory name, or -// a string containing a list of filenames and/or directory -// names separated by spaces. -// $p_add_dir : A path to add before the real path of the archived file, -// in order to have it memorized in the archive. -// $p_remove_dir : A path to remove from the real path of the file to archive, -// in order to have a shorter path memorized in the archive. -// When $p_add_dir and $p_remove_dir are set, $p_remove_dir -// is removed first, before $p_add_dir is added. -// Options : -// PCLZIP_OPT_ADD_PATH : -// PCLZIP_OPT_REMOVE_PATH : -// PCLZIP_OPT_REMOVE_ALL_PATH : -// PCLZIP_OPT_COMMENT : -// PCLZIP_OPT_ADD_COMMENT : -// PCLZIP_OPT_PREPEND_COMMENT : -// PCLZIP_CB_PRE_ADD : -// PCLZIP_CB_POST_ADD : -// Return Values : -// 0 on failure, -// The list of the added files, with a status of the add action. -// (see PclZip::listContent() for list entry format) -// -------------------------------------------------------------------------------- -function add($p_filelist) -{ -$v_result=1; - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Set default values -$v_options = array(); -$v_options[PCLZIP_OPT_NO_COMPRESSION] = false; - -// ----- Look for variable options arguments -$v_size = func_num_args(); - -// ----- Look for arguments -if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove form the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_ADD_COMMENT => 'optional', - PCLZIP_OPT_PREPEND_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - //, PCLZIP_OPT_CRYPT => 'optional' - )); - if ($v_result != 1) { - return 0; + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) + { + $p_remove_path .= '/'; } - } + $p_remove_path_size = strlen($p_remove_path); - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } - // ----- Get the first argument - $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + return $v_result; } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Return - return 0; - } - } -} + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; -// ----- Look for default option values -$this->privOptionDefaultThreshold($v_options); + // ----- Read each entry + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { -// ----- Init -$v_string_list = array(); -$v_att_list = array(); -$v_filedescr_list = array(); -$p_result_list = array(); + // ----- Read next Central dir entry + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); -// ----- Look if the $p_filelist is really an array -if (is_array($p_filelist)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - // ----- Look if the first element is also an array - // This will mean that this is a file description entry - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; - } - - // ----- The list is a list of string names - else { - $v_string_list = $p_filelist; - } -} - -// ----- Look if the $p_filelist is a string -else if (is_string($p_filelist)) { - // ----- Create a list from the string - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); -} - -// ----- Invalid variable type for $p_filelist -else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); - return 0; -} - -// ----- Reformat the string list -if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; - } -} - -// ----- For each file in the list check the attributes -$v_supported_attributes -= array (PCLZIP_ATT_FILE_NAME => 'mandatory' - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' - ,PCLZIP_ATT_FILE_MTIME => 'optional' - ,PCLZIP_ATT_FILE_CONTENT => 'optional' - ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); -foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, - $v_filedescr_list[], - $v_options, - $v_supported_attributes); - if ($v_result != 1) { - return 0; - } -} - -// ----- Expand the filelist (expand directories) -$v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); -if ($v_result != 1) { - return 0; -} - -// ----- Call the create fct -$v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); -if ($v_result != 1) { - return 0; -} - -// ----- Return -return $p_result_list; -} -// -------------------------------------------------------------------------------- + // ----- Return + return PclZip::errorCode(); + } -// -------------------------------------------------------------------------------- -// Function : listContent() -// Description : -// This public method, gives the list of the files and directories, with their -// properties. -// The properties of each entries in the list are (used also in other functions) : -// filename : Name of the file. For a create or add action it is the filename -// given by the user. For an extract function it is the filename -// of the extracted file. -// stored_filename : Name of the file / directory stored in the archive. -// size : Size of the stored file. -// compressed_size : Size of the file's data compressed in the archive -// (without the headers overhead) -// mtime : Last known modification date of the file (UNIX timestamp) -// comment : Comment associated with the file -// folder : true | false -// index : index of the file in the archive -// status : status of the action (depending of the action) : -// Values are : -// ok : OK ! -// filtered : the file / dir is not extracted (filtered by user) -// already_a_directory : the file can not be extracted because a -// directory with the same name already exists -// write_protected : the file can not be extracted because a file -// with the same name already exists and is -// write protected -// newer_exist : the file was not extracted because a newer file exists -// path_creation_fail : the file is not extracted because the folder -// does not exist and can not be created -// write_error : the file was not extracted because there was a -// error while writing the file -// read_error : the file was not extracted because there was a error -// while reading the file -// invalid_header : the file was not extracted because of an archive -// format error (bad file header) -// Note that each time a method can continue operating when there -// is an action error on a file, the error is only logged in the file status. -// Return Values : -// 0 on an unrecoverable failure, -// The list of the files in the archive. -// -------------------------------------------------------------------------------- -function listContent() -{ -$v_result=1; - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Check archive -if (!$this->privCheckFormat()) { - return(0); -} - -// ----- Call the extracting fct -$p_list = array(); -if (($v_result = $this->privList($p_list)) != 1) -{ - unset($p_list); - return(0); -} - -// ----- Return -return $p_list; -} -// -------------------------------------------------------------------------------- + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); -// -------------------------------------------------------------------------------- -// Function : -// extract($p_path="./", $p_remove_path="") -// extract([$p_option, $p_option_value, ...]) -// Description : -// This method supports two synopsis. The first one is historical. -// This method extract all the files / directories from the archive to the -// folder indicated in $p_path. -// If you want to ignore the 'root' part of path of the memorized files -// you can indicate this in the optional $p_remove_path parameter. -// By default, if a newer file with the same name already exists, the -// file is not extracted. -// -// If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions -// are used, the path indicated in PCLZIP_OPT_ADD_PATH is append -// at the end of the path value of PCLZIP_OPT_PATH. -// Parameters : -// $p_path : Path where the files and directories are to be extracted -// $p_remove_path : First part ('root' part) of the memorized path -// (if any similar) to remove while extracting. -// Options : -// PCLZIP_OPT_PATH : -// PCLZIP_OPT_ADD_PATH : -// PCLZIP_OPT_REMOVE_PATH : -// PCLZIP_OPT_REMOVE_ALL_PATH : -// PCLZIP_CB_PRE_EXTRACT : -// PCLZIP_CB_POST_EXTRACT : -// Return Values : -// 0 or a negative value on failure, -// The list of the extracted files, with a status of the action. -// (see PclZip::listContent() for list entry format) -// -------------------------------------------------------------------------------- -function extract() -{ -$v_result=1; + return $v_result; + } -// ----- Reset the error handler -$this->privErrorReset(); + // ----- Store the index + $v_header['index'] = $i; -// ----- Check archive -if (!$this->privCheckFormat()) { - return(0); -} + // ----- Store the file position + $v_pos_entry = ftell($this->zip_fd); -// ----- Set default values -$v_options = array(); -// $v_path = "./"; -$v_path = ''; -$v_remove_path = ""; -$v_remove_all_path = false; - -// ----- Look for variable options arguments -$v_size = func_num_args(); - -// ----- Default values for option -$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; - -// ----- Look for arguments -if ($v_size > 0) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional' - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; - } + // ----- Look for the specific extract rules + $v_extract = false; - // ----- Set the arguments - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - // ----- Check for '/' in last path char - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + + // ----- Look if the directory is in the filename path + if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_extract = true; + } + } + // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_extract = true; + } + } } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; - } - } - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - // ----- Get the first argument - $v_path = $v_arg_list[0]; + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + */ - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; - } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { - // ----- Return - return 0; - } - } -} + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } -// ----- Look for default option values -$this->privOptionDefaultThreshold($v_options); + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { -// ----- Trace + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } -// ----- Call the extracting fct -$p_list = array(); -$v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, - $v_remove_all_path, $v_options); -if ($v_result < 1) { - unset($p_list); - return(0); -} + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } -// ----- Return -return $p_list; -} -// -------------------------------------------------------------------------------- + // ----- Look for no rule, which means extract all the archive + else { + $v_extract = true; + } + // ----- Check compression method + if ( ($v_extract) + && ( ($v_header['compression'] != 8) + && ($v_header['compression'] != 0))) { + $v_header['status'] = 'unsupported_compression'; -// -------------------------------------------------------------------------------- -// Function : -// extractByIndex($p_index, $p_path="./", $p_remove_path="") -// extractByIndex($p_index, [$p_option, $p_option_value, ...]) -// Description : -// This method supports two synopsis. The first one is historical. -// This method is doing a partial extract of the archive. -// The extracted files or folders are identified by their index in the -// archive (from 0 to n). -// Note that if the index identify a folder, only the folder entry is -// extracted, not all the files included in the archive. -// Parameters : -// $p_index : A single index (integer) or a string of indexes of files to -// extract. The form of the string is "0,4-6,8-12" with only numbers -// and '-' for range or ',' to separate ranges. No spaces or ';' -// are allowed. -// $p_path : Path where the files and directories are to be extracted -// $p_remove_path : First part ('root' part) of the memorized path -// (if any similar) to remove while extracting. -// Options : -// PCLZIP_OPT_PATH : -// PCLZIP_OPT_ADD_PATH : -// PCLZIP_OPT_REMOVE_PATH : -// PCLZIP_OPT_REMOVE_ALL_PATH : -// PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and -// not as files. -// The resulting content is in a new field 'content' in the file -// structure. -// This option must be used alone (any other options are ignored). -// PCLZIP_CB_PRE_EXTRACT : -// PCLZIP_CB_POST_EXTRACT : -// Return Values : -// 0 on failure, -// The list of the extracted files, with a status of the action. -// (see PclZip::listContent() for list entry format) -// -------------------------------------------------------------------------------- -//function extractByIndex($p_index, options...) -function extractByIndex($p_index) -{ -$v_result=1; + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, + "Filename '".$v_header['stored_filename']."' is " + ."compressed by an unsupported compression " + ."method (".$v_header['compression'].") "); + + return PclZip::errorCode(); + } + } + + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + $v_header['status'] = 'unsupported_encryption'; -// ----- Reset the error handler -$this->privErrorReset(); + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { -// ----- Check archive -if (!$this->privCheckFormat()) { - return(0); -} + $this->privSwapBackMagicQuotes(); -// ----- Set default values -$v_options = array(); -// $v_path = "./"; -$v_path = ''; -$v_remove_path = ""; -$v_remove_all_path = false; - -// ----- Look for variable options arguments -$v_size = func_num_args(); - -// ----- Default values for option -$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; - -// ----- Look for arguments -if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove form the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional' - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; - } + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, + "Unsupported encryption for " + ." filename '".$v_header['stored_filename'] + ."'"); - // ----- Set the arguments - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + return PclZip::errorCode(); + } } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - // ----- Check for '/' in last path char - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; + + // ----- Look for real extraction + if (($v_extract) && ($v_header['status'] != 'ok')) { + $v_result = $this->privConvertHeader2FileInfo($v_header, + $p_file_list[$v_nb_extracted++]); + if ($v_result != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + $v_extract = false; } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; - } - if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; - } - else { - } - } + + // ----- Look for real extraction + if ($v_extract) + { - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else ){ + // ----- Go to the file position + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header['offset'])) + { + // ----- Close the zip file + $this->privCloseFd(); - // ----- Get the first argument - $v_path = $v_arg_list[0]; + $this->privSwapBackMagicQuotes(); - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; - } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - // ----- Return - return 0; - } - } -} - -// ----- Trace - -// ----- Trick -// Here I want to reuse extractByRule(), so I need to parse the $p_index -// with privParseOptions() -$v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); -$v_options_trick = array(); -$v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, - array (PCLZIP_OPT_BY_INDEX => 'optional')); -if ($v_result != 1) { - return 0; -} -$v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; - -// ----- Look for default option values -$this->privOptionDefaultThreshold($v_options); - -// ----- Call the extracting fct -if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { - return(0); -} - -// ----- Return -return $p_list; -} -// -------------------------------------------------------------------------------- + // ----- Return + return PclZip::errorCode(); + } -// -------------------------------------------------------------------------------- -// Function : -// delete([$p_option, $p_option_value, ...]) -// Description : -// This method removes files from the archive. -// If no parameters are given, then all the archive is emptied. -// Parameters : -// None or optional arguments. -// Options : -// PCLZIP_OPT_BY_INDEX : -// PCLZIP_OPT_BY_NAME : -// PCLZIP_OPT_BY_EREG : -// PCLZIP_OPT_BY_PREG : -// Return Values : -// 0 on failure, -// The list of the files which are still present in the archive. -// (see PclZip::listContent() for list entry format) -// -------------------------------------------------------------------------------- -function delete() -{ -$v_result=1; - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Check archive -if (!$this->privCheckFormat()) { - return(0); -} - -// ----- Set default values -$v_options = array(); - -// ----- Look for variable options arguments -$v_size = func_num_args(); - -// ----- Look for arguments -if ($v_size > 0) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional')); - if ($v_result != 1) { - return 0; - } -} + // ----- Look for extraction as string + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { -// ----- Magic quotes trick -$this->privDisableMagicQuotes(); + $v_string = ''; -// ----- Call the delete fct -$v_list = array(); -if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { - $this->privSwapBackMagicQuotes(); - unset($v_list); - return(0); -} + // ----- Extracting the file + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } -// ----- Magic quotes trick -$this->privSwapBackMagicQuotes(); + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); -// ----- Return -return $v_list; -} -// -------------------------------------------------------------------------------- + return $v_result; + } -// -------------------------------------------------------------------------------- -// Function : deleteByIndex() -// Description : -// ***** Deprecated ***** -// delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. -// -------------------------------------------------------------------------------- -function deleteByIndex($p_index) -{ + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; -$p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + // ----- Next extracted file + $v_nb_extracted++; + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for extraction in standard output + elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Extracting the file in standard output + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } -// ----- Return -return $p_list; -} -// -------------------------------------------------------------------------------- + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } -// -------------------------------------------------------------------------------- -// Function : properties() -// Description : -// This method gives the properties of the archive. -// The properties are : -// nb : Number of files in the archive -// comment : Comment associated with the archive file -// status : not_exist, ok -// Parameters : -// None -// Return Values : -// 0 on failure, -// An array with the archive properties. -// -------------------------------------------------------------------------------- -function properties() -{ - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Magic quotes trick -$this->privDisableMagicQuotes(); - -// ----- Check archive -if (!$this->privCheckFormat()) { - $this->privSwapBackMagicQuotes(); - return(0); -} - -// ----- Default properties -$v_prop = array(); -$v_prop['comment'] = ''; -$v_prop['nb'] = 0; -$v_prop['status'] = 'not_exist'; - -// ----- Look if file exists -if (@is_file($this->zipname)) -{ - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) - { + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for normal extraction + else { + // ----- Extracting the file + $v_result1 = $this->privExtractFile($v_header, + $p_path, $p_remove_path, + $p_remove_all_path, + $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + } + } + + // ----- Close the zip file + $this->privCloseFd(); $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); // ----- Return - return 0; + return $v_result; } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFile() + // Description : + // Parameters : + // Return Values : + // + // 1 : ... ? + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback + // -------------------------------------------------------------------------------- + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) { - $this->privSwapBackMagicQuotes(); - return 0; - } + $v_result=1; - // ----- Close the zip file - $this->privCloseFd(); + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } - // ----- Set the user attributes - $v_prop['comment'] = $v_central_dir['comment']; - $v_prop['nb'] = $v_central_dir['entries']; - $v_prop['status'] = 'ok'; -} -// ----- Magic quotes trick -$this->privSwapBackMagicQuotes(); + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } -// ----- Return -return $v_prop; -} -// -------------------------------------------------------------------------------- + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Look for folder entry that not need to be extracted + if (($p_entry['external']&0x00000010)==0x00000010) { -// -------------------------------------------------------------------------------- -// Function : duplicate() -// Description : -// This method creates an archive by copying the content of an other one. If -// the archive already exist, it is replaced by the new one without any warning. -// Parameters : -// $p_archive : The filename of a valid archive, or -// a valid PclZip object. -// Return Values : -// 1 on success. -// 0 or a negative value on error (error code). -// -------------------------------------------------------------------------------- -function duplicate($p_archive) -{ -$v_result = 1; - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Look if the $p_archive is a PclZip object -if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) -{ - - // ----- Duplicate the archive - $v_result = $this->privDuplicate($p_archive->zipname); -} - -// ----- Look if the $p_archive is a string (so a filename) -else if (is_string($p_archive)) -{ - - // ----- Check that $p_archive is a valid zip file - // TBC : Should also check the archive format - if (!is_file($p_archive)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); - $v_result = PCLZIP_ERR_MISSING_FILE; - } - else { - // ----- Duplicate the archive - $v_result = $this->privDuplicate($p_archive); - } -} - -// ----- Invalid variable -else -{ - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + $p_entry['status'] = "filtered"; -// -------------------------------------------------------------------------------- -// Function : merge() -// Description : -// This method merge the $p_archive_to_add archive at the end of the current -// one ($this). -// If the archive ($this) does not exist, the merge becomes a duplicate. -// If the $p_archive_to_add archive does not exist, the merge is a success. -// Parameters : -// $p_archive_to_add : It can be directly the filename of a valid zip archive, -// or a PclZip object archive. -// Return Values : -// 1 on success, -// 0 or negative values on error (see below). -// -------------------------------------------------------------------------------- -function merge($p_archive_to_add) -{ -$v_result = 1; - -// ----- Reset the error handler -$this->privErrorReset(); - -// ----- Check archive -if (!$this->privCheckFormat()) { - return(0); -} - -// ----- Look if the $p_archive_to_add is a PclZip object -if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) -{ - - // ----- Merge the archive - $v_result = $this->privMerge($p_archive_to_add); -} - -// ----- Look if the $p_archive_to_add is a string (so a filename) -else if (is_string($p_archive_to_add)) -{ - - // ----- Create a temporary archive - $v_object_archive = new PclZip($p_archive_to_add); - - // ----- Merge the archive - $v_result = $this->privMerge($v_object_archive); -} - -// ----- Invalid variable -else -{ - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + return $v_result; + } + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); + } + // ----- Look for path to remove + else if ($p_remove_path != "") + { + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) + { -// -------------------------------------------------------------------------------- -// Function : errorCode() -// Description : -// Parameters : -// -------------------------------------------------------------------------------- -function errorCode() -{ -if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorCode()); -} -else { - return($this->error_code); -} -} -// -------------------------------------------------------------------------------- + // ----- Change the file status + $p_entry['status'] = "filtered"; -// -------------------------------------------------------------------------------- -// Function : errorName() -// Description : -// Parameters : -// -------------------------------------------------------------------------------- -function errorName($p_with_code=false) -{ -$v_name = array (PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', - PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', - PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', - PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', - PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', - PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', - PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', - PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', - PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', - PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', - PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', - PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', - PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', - PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', - PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', - PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', - PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', - PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', - PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' - ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' - ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' - ) == 0) -{ - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); -} - -// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks -fseek($v_file_compressed, 10); -$v_size = $p_header['compressed_size']; -while ($v_size != 0) -{ - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_file_compressed, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; -} - -// ----- Close the file -@fclose($v_file_compressed); - -// ----- Unlink the temporary file -@unlink($v_gzip_temp_name); - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Return + return $v_result; + } -// -------------------------------------------------------------------------------- -// Function : privCalculateStoredFilename() -// Description : -// Based on file descriptor properties and global options, this method -// calculate the filename that will be stored in the archive. -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privCalculateStoredFilename(&$p_filedescr, &$p_options) -{ -$v_result=1; - -// ----- Working variables -$p_filename = $p_filedescr['filename']; -if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { - $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; -} -else { - $p_add_dir = ''; -} -if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { - $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; -} -else { - $p_remove_dir = ''; -} -if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; -} -else { - $p_remove_all_dir = 0; -} - - -// ----- Look for full name change -if (isset($p_filedescr['new_full_name'])) { - // ----- Remove drive letter if any - $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); -} - -// ----- Look for path and/or short name change -else { - - // ----- Look for short name change - // Its when we cahnge just the filename but not the path - if (isset($p_filedescr['new_short_name'])) { - $v_path_info = pathinfo($p_filename); - $v_dir = ''; - if ($v_path_info['dirname'] != '') { - $v_dir = $v_path_info['dirname'].'/'; - } - $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; - } - else { - // ----- Calculate the stored filename - $v_stored_filename = $p_filename; - } + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + { - // ----- Look for all path to remove - if ($p_remove_all_dir) { - $v_stored_filename = basename($p_filename); - } - // ----- Look for partial path remove - else if ($p_remove_dir != "") { - if (substr($p_remove_dir, -1) != '/') - $p_remove_dir .= "/"; + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); - if ((substr($p_filename, 0, 2) == "./") - || (substr($p_remove_dir, 0, 2) == "./")) { - - if ((substr($p_filename, 0, 2) == "./") - && (substr($p_remove_dir, 0, 2) != "./")) { - $p_remove_dir = "./".$p_remove_dir; - } - if ((substr($p_filename, 0, 2) != "./") - && (substr($p_remove_dir, 0, 2) == "./")) { - $p_remove_dir = substr($p_remove_dir, 2); } } - $v_compare = PclZipUtilPathInclusion($p_remove_dir, - $v_stored_filename); - if ($v_compare > 0) { - if ($v_compare == 2) { - $v_stored_filename = ""; - } - else { - $v_stored_filename = substr($v_stored_filename, - strlen($p_remove_dir)); - } + // ----- Add the path + if ($p_path != '') { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; } - } - - // ----- Remove drive letter if any - $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); - - // ----- Look for path to add - if ($p_add_dir != "") { - if (substr($p_add_dir, -1) == "/") - $v_stored_filename = $p_add_dir.$v_stored_filename; - else - $v_stored_filename = $p_add_dir."/".$v_stored_filename; - } -} - -// ----- Filename (reduce the path of stored name) -$v_stored_filename = PclZipUtilPathReduction($v_stored_filename); -$p_filedescr['stored_filename'] = $v_stored_filename; - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + + // ----- Check a base_dir_restriction + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { + $v_inclusion + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], + $p_entry['filename']); + if ($v_inclusion == 0) { -// -------------------------------------------------------------------------------- -// Function : privWriteFileHeader() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privWriteFileHeader(&$p_header) -{ -$v_result=1; - -// ----- Store the offset position of the file -$p_header['offset'] = ftell($this->zip_fd); - -// ----- Transform UNIX mtime to DOS format mdate/mtime -$v_date = getdate($p_header['mtime']); -$v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; -$v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; - -// ----- Packed data -$v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, - $p_header['version_extracted'], $p_header['flag'], - $p_header['compression'], $v_mtime, $v_mdate, - $p_header['crc'], $p_header['compressed_size'], - $p_header['size'], - strlen($p_header['stored_filename']), - $p_header['extra_len']); - -// ----- Write the first 148 bytes of the header in the archive -fputs($this->zip_fd, $v_binary_data, 30); - -// ----- Write the variable fields -if (strlen($p_header['stored_filename']) != 0) -{ - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); -} -if ($p_header['extra_len'] != 0) -{ - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, + "Filename '".$p_entry['filename']."' is " + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); -// -------------------------------------------------------------------------------- -// Function : privWriteCentralFileHeader() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privWriteCentralFileHeader(&$p_header) -{ -$v_result=1; - -// TBC -//for(reset($p_header); $key = key($p_header); next($p_header)) { -//} - -// ----- Transform UNIX mtime to DOS format mdate/mtime -$v_date = getdate($p_header['mtime']); -$v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; -$v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; - - -// ----- Packed data -$v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, - $p_header['version'], $p_header['version_extracted'], - $p_header['flag'], $p_header['compression'], - $v_mtime, $v_mdate, $p_header['crc'], - $p_header['compressed_size'], $p_header['size'], - strlen($p_header['stored_filename']), - $p_header['extra_len'], $p_header['comment_len'], - $p_header['disk'], $p_header['internal'], - $p_header['external'], $p_header['offset']); - -// ----- Write the 42 bytes of the header in the zip file -fputs($this->zip_fd, $v_binary_data, 46); - -// ----- Write the variable fields -if (strlen($p_header['stored_filename']) != 0) -{ - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); -} -if ($p_header['extra_len'] != 0) -{ - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); -} -if ($p_header['comment_len'] != 0) -{ - fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + return PclZip::errorCode(); + } + } -// -------------------------------------------------------------------------------- -// Function : privWriteCentralHeader() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) -{ -$v_result=1; - -// ----- Packed data -$v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, - $p_nb_entries, $p_size, - $p_offset, strlen($p_comment)); - -// ----- Write the 22 bytes of the header in the zip file -fputs($this->zip_fd, $v_binary_data, 22); - -// ----- Write the variable fields -if (strlen($p_comment) != 0) -{ - fputs($this->zip_fd, $p_comment, strlen($p_comment)); -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { -// -------------------------------------------------------------------------------- -// Function : privList() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privList(&$p_list) -{ -$v_result=1; - -// ----- Magic quotes trick -$this->privDisableMagicQuotes(); - -// ----- Open the zip file -if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) -{ - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - - // ----- Return - return PclZip::errorCode(); -} - -// ----- Read the central directory informations -$v_central_dir = array(); -if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) -{ - $this->privSwapBackMagicQuotes(); - return $v_result; -} - -// ----- Go to beginning of Central Dir -@rewind($this->zip_fd); -if (@fseek($this->zip_fd, $v_central_dir['offset'])) -{ - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - - // ----- Return - return PclZip::errorCode(); -} - -// ----- Read each entry -for ($i=0; $i<$v_central_dir['entries']; $i++) -{ - // ----- Read the file header - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) - { - $this->privSwapBackMagicQuotes(); - return $v_result; - } - $v_header['index'] = $i; + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - // ----- Get the only interesting attributes - $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); - unset($v_header); -} + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } -// ----- Close the zip file -$this->privCloseFd(); + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } -// ----- Magic quotes trick -$this->privSwapBackMagicQuotes(); -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { -// -------------------------------------------------------------------------------- -// Function : privConvertHeader2FileInfo() -// Description : -// This function takes the file informations from the central directory -// entries and extract the interesting parameters that will be given back. -// The resulting file infos are set in the array $p_info -// $p_info['filename'] : Filename with full path. Given by user (add), -// extracted in the filesystem (extract). -// $p_info['stored_filename'] : Stored filename in the archive. -// $p_info['size'] = Size of the file. -// $p_info['compressed_size'] = Compressed size of the file. -// $p_info['mtime'] = Last modification date of the file. -// $p_info['comment'] = Comment associated with the file. -// $p_info['folder'] = true/false : indicates if the entry is a folder or not. -// $p_info['status'] = status of the action on the file. -// $p_info['crc'] = CRC of the file content. -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privConvertHeader2FileInfo($p_header, &$p_info) -{ -$v_result=1; - -// ----- Get the interesting attributes -$v_temp_path = PclZipUtilPathReduction($p_header['filename']); -$p_info['filename'] = $v_temp_path; -$v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); -$p_info['stored_filename'] = $v_temp_path; -$p_info['size'] = $p_header['size']; -$p_info['compressed_size'] = $p_header['compressed_size']; -$p_info['mtime'] = $p_header['mtime']; -$p_info['comment'] = $p_header['comment']; -$p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); -$p_info['index'] = $p_header['index']; -$p_info['status'] = $p_header['status']; -$p_info['crc'] = $p_header['crc']; - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) + { -// -------------------------------------------------------------------------------- -// Function : privExtractByRule() -// Description : -// Extract a file or directory depending of rules (by index, by name, ...) -// Parameters : -// $p_file_list : An array where will be placed the properties of each -// extracted file -// $p_path : Path to add while writing the extracted files -// $p_remove_path : Path to remove (from the file memorized path) while writing the -// extracted files. If the path does not match the file path, -// the file is extracted with its memorized path. -// $p_remove_path does not apply to 'list' mode. -// $p_path and $p_remove_path are commulative. -// Return Values : -// 1 on success,0 or less on error (see error code list) -// -------------------------------------------------------------------------------- -function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) -{ -$v_result=1; - -// ----- Magic quotes trick -$this->privDisableMagicQuotes(); - -// ----- Check the path -if (($p_path == "") - || ((substr($p_path, 0, 1) != "/") - && (substr($p_path, 0, 3) != "../") - && (substr($p_path,1,2)!=":/"))) - $p_path = "./".$p_path; - -// ----- Reduce the path last (and duplicated) '/' -if (($p_path != "./") && ($p_path != "/")) -{ - // ----- Look for the path end '/' - while (substr($p_path, -1) == "/") - { - $p_path = substr($p_path, 0, strlen($p_path)-1); - } -} - -// ----- Look for path to remove format (should end by /) -if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) -{ - $p_remove_path .= '/'; -} -$p_remove_path_size = strlen($p_remove_path); - -// ----- Open the zip file -if (($v_result = $this->privOpenFd('rb')) != 1) -{ - $this->privSwapBackMagicQuotes(); - return $v_result; -} - -// ----- Read the central directory informations -$v_central_dir = array(); -if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) -{ - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - return $v_result; -} - -// ----- Start at beginning of Central Dir -$v_pos_entry = $v_central_dir['offset']; - -// ----- Read each entry -$j_start = 0; -for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) -{ - - // ----- Read next Central dir entry - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_pos_entry)) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) + { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - // ----- Return - return PclZip::errorCode(); - } + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, + "Filename '".$p_entry['filename']."' is " + ."already used by an existing directory"); - // ----- Read the file header - $v_header = array(); - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + return PclZip::errorCode(); + } + } + // ----- Look if file is write protected + else if (!is_writeable($p_entry['filename'])) + { - return $v_result; - } + // ----- Change the file status + $p_entry['status'] = "write_protected"; - // ----- Store the index - $v_header['index'] = $i; + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - // ----- Store the file position - $v_pos_entry = ftell($this->zip_fd); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Filename '".$p_entry['filename']."' exists " + ."and is write protected"); - // ----- Look for the specific extract rules - $v_extract = false; + return PclZip::errorCode(); + } + } - // ----- Look for extract by name rule - if ((isset($p_options[PCLZIP_OPT_BY_NAME])) - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + // ----- Look if the extracted file is older + else if (filemtime($p_entry['filename']) > $p_entry['mtime']) + { + // ----- Change the file status + if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + } + else { + $p_entry['status'] = "newer_exist"; - // ----- Look if the filename is in the list - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - // ----- Look for a directory - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Newer version of '".$p_entry['filename']."' exists " + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); - // ----- Look if the directory is in the filename path - if ((strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) - && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_extract = true; + return PclZip::errorCode(); } - } - // ----- Look for a filename - elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { - $v_extract = true; - } + } } - } - - // ----- Look for extract by ereg rule - // ereg() is deprecated with PHP 5.3 - /* - else if ((isset($p_options[PCLZIP_OPT_BY_EREG])) - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + else { + } + } - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { - $v_extract = true; + // ----- Check the directory availability and create it if necessary + else { + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + else if (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); + + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + //return $v_result; + $v_result = 1; + } } - } - */ + } - // ----- Look for extract by preg rule - else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { - $v_extract = true; - } - } + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file + if ($p_entry['compression'] == 0) { - // ----- Look for extract by index rule - else if ((isset($p_options[PCLZIP_OPT_BY_INDEX])) - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - - // ----- Look if the index is in the list - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) + { - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_extract = true; - } - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; + // ----- Change the file status + $p_entry['status'] = "write_error"; + + // ----- Return + return $v_result; } - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + /* Try to speed up the code + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + */ + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; } - } - } - // ----- Look for no rule, which means extract all the archive - else { - $v_extract = true; - } + // ----- Closing the destination file + fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + - // ----- Check compression method - if (($v_extract) - && (($v_header['compression'] != 8) - && ($v_header['compression'] != 0))) { - $v_header['status'] = 'unsupported_compression'; + } + else { + // ----- TBC + // Need to be finished + if (($p_entry['flag'] & 1) == 1) { + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); + return PclZip::errorCode(); + } - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - $this->privSwapBackMagicQuotes(); + // ----- Look for using temporary file to unzip + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, - "Filename '".$v_header['stored_filename']."' is " - ."compressed by an unsupported compression " - ."method (".$v_header['compression'].") "); + // ----- Look for extract in memory + else { - return PclZip::errorCode(); - } - } + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = @gzinflate($v_buffer); + unset($v_buffer); + if ($v_file_content === FALSE) { + + // ----- Change the file status + // TBC + $p_entry['status'] = "error"; + + return $v_result; + } + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } - // ----- Check encrypted files - if (($v_extract) && (($v_header['flag'] & 1) == 1)) { - $v_header['status'] = 'unsupported_encryption'; + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + + } - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Change the file mtime + @touch($p_entry['filename'], $p_entry['mtime']); + } - $this->privSwapBackMagicQuotes(); + // ----- Look for chmod option + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, - "Unsupported encryption for " - ." filename '".$v_header['stored_filename'] - ."'"); + // ----- Change the mode of the file + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + } - return PclZip::errorCode(); } -} + } - // ----- Look for real extraction - if (($v_extract) && ($v_header['status'] != 'ok')) { - $v_result = $this->privConvertHeader2FileInfo($v_header, - $p_file_list[$v_nb_extracted++]); - if ($v_result != 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - $v_extract = false; - } - - // ----- Look for real extraction - if ($v_extract) - { - - // ----- Go to the file position - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_header['offset'])) - { - // ----- Close the zip file - $this->privCloseFd(); + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - $this->privSwapBackMagicQuotes(); + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } - // ----- Return + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileUsingTempFile(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Creates a temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); return PclZip::errorCode(); } - // ----- Look for extraction as string - if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { - $v_string = ''; + // ----- Write gz file format header + $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); + @fwrite($v_dest_file, $v_binary_data, 10); - // ----- Extracting the file - $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Write gz file format footer + $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); + @fwrite($v_dest_file, $v_binary_data, 8); - return $v_result; - } + // ----- Close the temporary file + @fclose($v_dest_file); - // ----- Set the file content - $p_file_list[$v_nb_extracted]['content'] = $v_string; + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + $p_entry['status'] = "write_error"; + return $v_result; + } - // ----- Next extracted file - $v_nb_extracted++; - - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } + // ----- Open the temporary gz file + if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { + @fclose($v_dest_file); + $p_entry['status'] = "read_error"; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($v_src_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + @fclose($v_dest_file); + @gzclose($v_src_file); + + // ----- Delete the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileInOutput() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileInOutput(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + return $v_result; } - // ----- Look for extraction in standard output - elseif ((isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) - && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { - // ----- Extracting the file in standard output - $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC } - // ----- Look for normal extraction - else { - // ----- Extracting the file - $v_result1 = $this->privExtractFile($v_header, - $p_path, $p_remove_path, - $p_remove_all_path, - $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - return $v_result; + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; } - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; } - } - } -} -// ----- Close the zip file -$this->privCloseFd(); -$this->privSwapBackMagicQuotes(); + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Trace -// -------------------------------------------------------------------------------- -// Function : privExtractFile() -// Description : -// Parameters : -// Return Values : -// -// 1 : ... ? -// PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback -// -------------------------------------------------------------------------------- -function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) -{ -$v_result=1; + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { -// ----- Read the file header -if (($v_result = $this->privReadFileHeader($v_header)) != 1) -{ - // ----- Return - return $v_result; -} + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) { + // ----- Read the file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); -// ----- Check that the file header is coherent with $p_entry info -if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC -} + // ----- Send the file to the output + echo $v_buffer; + unset($v_buffer); + } + else { -// ----- Look for all path to remove -if ($p_remove_all_path == true) { - // ----- Look for folder entry that not need to be extracted - if (($p_entry['external']&0x00000010)==0x00000010) { + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); - $p_entry['status'] = "filtered"; + // ----- Send the file to the output + echo $v_file_content; + unset($v_file_content); + } + } + } - return $v_result; + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; } - // ----- Get the basename of the path - $p_entry['filename'] = basename($p_entry['filename']); -} + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { -// ----- Look for path to remove -else if ($p_remove_path != "") -{ - if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) - { + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - // ----- Change the file status - $p_entry['status'] = "filtered"; + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } - // ----- Return return $v_result; } - - $p_remove_path_size = strlen($p_remove_path); - if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileAsString() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) { + $v_result=1; - // ----- Remove the path - $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } - } -} -// ----- Add the path -if ($p_path != '') { - $p_entry['filename'] = $p_path."/".$p_entry['filename']; -} + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } -// ----- Check a base_dir_restriction -if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { - $v_inclusion - = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], - $p_entry['filename']); - if ($v_inclusion == 0) { + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, - "Filename '".$p_entry['filename']."' is " - ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - return PclZip::errorCode(); - } -} + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } -// ----- Look for pre-extract callback -if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + // if ($p_entry['compressed_size'] == $p_entry['size']) + if ($p_entry['compression'] == 0) { - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } + // ----- Reading the file + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + } + else { + + // ----- Reading the file + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + if (($p_string = @gzinflate($v_data)) === FALSE) { + // TBC + } + } + + // ----- Trace + } + else { + // TBC : error : can not extract a folder in a string + } + + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; -} + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Swap the content to header + $v_local_header['content'] = $p_string; + $p_string = ''; + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); -// ----- Look if extraction should be done -if ($p_entry['status'] == 'ok') { + // ----- Swap back the content to header + $p_string = $v_local_header['content']; + unset($v_local_header['content']); -// ----- Look for specific actions while the file exist -if (file_exists($p_entry['filename'])) -{ + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } - // ----- Look if file is a directory - if (is_dir($p_entry['filename'])) + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadFileHeader(&$p_header) { + $v_result=1; - // ----- Change the file status - $p_entry['status'] = "already_a_directory"; - - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); - PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, - "Filename '".$p_entry['filename']."' is " - ."already used by an existing directory"); + // ----- Check signature + if ($v_data['id'] != 0x04034b50) + { - return PclZip::errorCode(); - } - } - // ----- Look if file is write protected - else if (!is_writeable($p_entry['filename'])) - { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); - // ----- Change the file status - $p_entry['status'] = "write_protected"; + // ----- Return + return PclZip::errorCode(); + } - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 26); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Filename '".$p_entry['filename']."' exists " - ."and is write protected"); + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; - return PclZip::errorCode(); - } - } + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); - // ----- Look if the extracted file is older - else if (filemtime($p_entry['filename']) > $p_entry['mtime']) - { - // ----- Change the file status - if ((isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) - && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { - } - else { - $p_entry['status'] = "newer_exist"; + // ----- Return + return PclZip::errorCode(); + } - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Extract the values + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Newer version of '".$p_entry['filename']."' exists " - ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + // ----- Get filename + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); - return PclZip::errorCode(); - } - } - } - else { - } -} + // ----- Get extra_fields + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); + } + else { + $p_header['extra'] = ''; + } -// ----- Check the directory availability and create it if necessary -else { - if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) - $v_dir_to_check = $p_entry['filename']; - else if (!strstr($p_entry['filename'], "/")) - $v_dir_to_check = ""; - else - $v_dir_to_check = dirname($p_entry['filename']); + // ----- Extract properties + $p_header['version_extracted'] = $v_data['version']; + $p_header['compression'] = $v_data['compression']; + $p_header['size'] = $v_data['size']; + $p_header['compressed_size'] = $v_data['compressed_size']; + $p_header['crc'] = $v_data['crc']; + $p_header['flag'] = $v_data['flag']; + $p_header['filename_len'] = $v_data['filename_len']; + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; - if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; - // ----- Change the file status - $p_entry['status'] = "path_creation_fail"; + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); - // ----- Return - //return $v_result; - $v_result = 1; } - } -} + else + { + $p_header['mtime'] = time(); + } + + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + //} -// ----- Look if extraction should be done -if ($p_entry['status'] == 'ok') { + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) + // ----- Set the status field + $p_header['status'] = "ok"; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadCentralFileHeader(&$p_header) { - // ----- Look for not compressed file - if ($p_entry['compression'] == 0) { + $v_result=1; - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) - { + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); - // ----- Change the file status - $p_entry['status'] = "write_error"; + // ----- Check signature + if ($v_data['id'] != 0x02014b50) + { - // ----- Return - return $v_result; - } + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + // ----- Return + return PclZip::errorCode(); + } - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = $p_entry['compressed_size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - /* Try to speed up the code - $v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_binary_data, $v_read_size); - */ - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 42); - // ----- Closing the destination file - fclose($v_dest_file); + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; - // ----- Change the file mtime - touch($p_entry['filename'], $p_entry['mtime']); - + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + // ----- Return + return PclZip::errorCode(); } - else { - // ----- TBC - // Need to be finished - if (($p_entry['flag'] & 1) == 1) { - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); - return PclZip::errorCode(); - } + // ----- Extract the values + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); - // ----- Look for using temporary file to unzip - if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])))) { - $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); - if ($v_result < PCLZIP_ERR_NO_ERROR) { - return $v_result; - } - } - - // ----- Look for extract in memory - else { + // ----- Get filename + if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); + else + $p_header['filename'] = ''; - - // ----- Read the compressed file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - $v_file_content = @gzinflate($v_buffer); - unset($v_buffer); - if ($v_file_content === false) { + // ----- Get extra + if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); + else + $p_header['extra'] = ''; - // ----- Change the file status - // TBC - $p_entry['status'] = "error"; - - return $v_result; - } - - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + // ----- Get comment + if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); + else + $p_header['comment'] = ''; - // ----- Change the file status - $p_entry['status'] = "write_error"; + // ----- Extract properties - return $v_result; - } + // ----- Recuperate date in UNIX format + //if ($p_header['mdate'] && $p_header['mtime']) + // TBC : bug : this was ignoring time with 0/0/0 + if (1) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; - // ----- Write the uncompressed data - @fwrite($v_dest_file, $v_file_content, $p_entry['size']); - unset($v_file_content); + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; - // ----- Closing the destination file - @fclose($v_dest_file); - - } + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); - // ----- Change the file mtime - @touch($p_entry['filename'], $p_entry['mtime']); } + else + { + $p_header['mtime'] = time(); + } + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; - // ----- Look for chmod option - if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { + // ----- Set default status to ok + $p_header['status'] = 'ok'; - // ----- Change the mode of the file - @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + // ----- Look if it is a directory + if (substr($p_header['filename'], -1) == '/') { + //$p_header['external'] = 0x41FF0010; + $p_header['external'] = 0x00000010; } + + // ----- Return + return $v_result; } -} + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCheckFileHeaders() + // Description : + // Parameters : + // Return Values : + // 1 on success, + // 0 on error; + // -------------------------------------------------------------------------------- + function privCheckFileHeaders(&$p_local_header, &$p_central_header) + { + $v_result=1; + + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + } + + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { + $p_local_header['size'] = $p_central_header['size']; + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + $p_local_header['crc'] = $p_central_header['crc']; + } - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadEndCentralDir() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadEndCentralDir(&$p_central_dir) + { + $v_result=1; -// ----- Look for post-extract callback -elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + // ----- Go to the end of the zip file + $v_size = filesize($this->zipname); + @fseek($this->zip_fd, $v_size); + if (@ftell($this->zip_fd) != $v_size) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + // ----- Return + return PclZip::errorCode(); + } - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + // ----- First try : look if this is an archive with no commentaries (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + @fseek($this->zip_fd, $v_size-22); + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; - } -} + // ----- Return + return PclZip::errorCode(); + } -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Read for bytes + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = @unpack('Vid', $v_binary_data); -// -------------------------------------------------------------------------------- -// Function : privExtractFileUsingTempFile() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privExtractFileUsingTempFile(&$p_entry, &$p_options) -{ -$v_result=1; - -// ----- Creates a temporary file -$v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; -if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { - fclose($v_file); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); - return PclZip::errorCode(); -} - - -// ----- Write gz file format header -$v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); -@fwrite($v_dest_file, $v_binary_data, 10); - -// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks -$v_size = $p_entry['compressed_size']; -while ($v_size != 0) -{ - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; -} - -// ----- Write gz file format footer -$v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); -@fwrite($v_dest_file, $v_binary_data, 8); - -// ----- Close the temporary file -@fclose($v_dest_file); - -// ----- Opening destination file -if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - $p_entry['status'] = "write_error"; - return $v_result; -} - -// ----- Open the temporary gz file -if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { - @fclose($v_dest_file); - $p_entry['status'] = "read_error"; - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); -} - - -// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks -$v_size = $p_entry['size']; -while ($v_size != 0) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($v_src_file, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; -} -@fclose($v_dest_file); -@gzclose($v_src_file); - -// ----- Delete the temporary file -@unlink($v_gzip_temp_name); - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } -// -------------------------------------------------------------------------------- -// Function : privExtractFileInOutput() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privExtractFileInOutput(&$p_entry, &$p_options) -{ -$v_result=1; + $v_pos = ftell($this->zip_fd); + } + + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); -// ----- Read the file header -if (($v_result = $this->privReadFileHeader($v_header)) != 1) { - return $v_result; -} + // ----- Return + return PclZip::errorCode(); + } + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) + { + // ----- Read a byte + $v_byte = @fread($this->zip_fd, 1); + + // ----- Add the byte + //$v_bytes = ($v_bytes << 8) | Ord($v_byte); + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. + $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); + + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) + { + $v_pos++; + break; + } -// ----- Check that the file header is coherent with $p_entry info -if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC -} + $v_pos++; + } -// ----- Look for pre-extract callback -if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + // ----- Look if not found end of central dir + if ($v_pos == $v_size) + { - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } + // ----- Return + return PclZip::errorCode(); + } + } - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->zip_fd, 18); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) + { - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; -} + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } -// ----- Trace + // ----- Extract the values + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); -// ----- Look if extraction should be done -if ($p_entry['status'] == 'ok') { + // ----- Check the global size + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) { - // ----- Look for not compressed file - if ($p_entry['compressed_size'] == $p_entry['size']) { + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, + 'The central dir is not at the end of the archive.' + .' Some trailing bytes exists after the archive.'); - // ----- Read the file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + // ----- Return + return PclZip::errorCode(); + } + } - // ----- Send the file to the output - echo $v_buffer; - unset($v_buffer); + // ----- Get comment + if ($v_data['comment_size'] != 0) { + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); } - else { + else + $p_central_dir['comment'] = ''; - // ----- Read the compressed file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - $v_file_content = gzinflate($v_buffer); - unset($v_buffer); + $p_central_dir['entries'] = $v_data['entries']; + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + $p_central_dir['offset'] = $v_data['offset']; + $p_central_dir['size'] = $v_data['size']; + $p_central_dir['disk'] = $v_data['disk']; + $p_central_dir['disk_start'] = $v_data['disk_start']; - // ----- Send the file to the output - echo $v_file_content; - unset($v_file_content); - } - } -} + // TBC + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { + //} -// ----- Change abort status -if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; -} + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDeleteByRule() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDeleteByRule(&$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); -// ----- Look for post-extract callback -elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; + } - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + // ----- Go to beginning of File + @rewind($this->zip_fd); - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; - } -} + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); -// -------------------------------------------------------------------------------- -// Function : privExtractFileAsString() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) -{ -$v_result=1; + // ----- Return + return PclZip::errorCode(); + } -// ----- Read the file header -$v_header = array(); -if (($v_result = $this->privReadFileHeader($v_header)) != 1) -{ - // ----- Return - return $v_result; -} + // ----- Read each entry + $v_header_list = array(); + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); -// ----- Check that the file header is coherent with $p_entry info -if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC -} + return $v_result; + } -// ----- Look for pre-extract callback -if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } - - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } + // ----- Look for the specific extract rules + $v_found = false; - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; -} + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { -// ----- Look if extraction should be done -if ($p_entry['status'] == 'ok') { + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) { - // ----- Look for not compressed file -// if ($p_entry['compressed_size'] == $p_entry['size']) - if ($p_entry['compression'] == 0) { + // ----- Look if the directory is in the filename path + if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_found = true; + } + } + } - // ----- Reading the file - $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); - } - else { + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - // ----- Reading the file - $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - if (($p_string = @gzinflate($v_data)) === false) { - // TBC + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } } - } + */ - // ----- Trace - } - else { - // TBC : error : can not extract a folder in a string - } - -} + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; - } + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } -// ----- Look for post-extract callback -elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Swap the content to header - $v_local_header['content'] = $p_string; - $p_string = ''; + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } - // ----- Swap back the content to header - $p_string = $v_local_header['content']; - unset($v_local_header['content']); + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + else { + $v_found = true; + } - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; - } -} + // ----- Look for deletion + if ($v_found) + { + unset($v_header_list[$v_nb_extracted]); + } + else + { + $v_nb_extracted++; + } + } -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Look if something need to be deleted + if ($v_nb_extracted > 0) { -// -------------------------------------------------------------------------------- -// Function : privReadFileHeader() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privReadFileHeader(&$p_header) -{ -$v_result=1; - -// ----- Read the 4 bytes signature -$v_binary_data = @fread($this->zip_fd, 4); -$v_data = unpack('Vid', $v_binary_data); - -// ----- Check signature -if ($v_data['id'] != 0x04034b50) -{ - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); - - // ----- Return - return PclZip::errorCode(); -} - -// ----- Read the first 42 bytes of the header -$v_binary_data = fread($this->zip_fd, 26); - -// ----- Look for invalid block size -if (strlen($v_binary_data) != 26) -{ - $p_header['filename'] = ""; - $p_header['status'] = "invalid_header"; - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); - - // ----- Return - return PclZip::errorCode(); -} - -// ----- Extract the values -$v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); - -// ----- Get filename -$p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); - -// ----- Get extra_fields -if ($v_data['extra_len'] != 0) { - $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); -} -else { - $p_header['extra'] = ''; -} - -// ----- Extract properties -$p_header['version_extracted'] = $v_data['version']; -$p_header['compression'] = $v_data['compression']; -$p_header['size'] = $v_data['size']; -$p_header['compressed_size'] = $v_data['compressed_size']; -$p_header['crc'] = $v_data['crc']; -$p_header['flag'] = $v_data['flag']; -$p_header['filename_len'] = $v_data['filename_len']; - -// ----- Recuperate date in UNIX format -$p_header['mdate'] = $v_data['mdate']; -$p_header['mtime'] = $v_data['mtime']; -if ($p_header['mdate'] && $p_header['mtime']) -{ - // ----- Extract time - $v_hour = ($p_header['mtime'] & 0xF800) >> 11; - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; - $v_seconde = ($p_header['mtime'] & 0x001F)*2; - - // ----- Extract date - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; - $v_month = ($p_header['mdate'] & 0x01E0) >> 5; - $v_day = $p_header['mdate'] & 0x001F; - - // ----- Get UNIX date format - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); - -} -else -{ - $p_header['mtime'] = time(); -} - -// TBC -//for(reset($v_data); $key = key($v_data); next($v_data)) { -//} - -// ----- Set the stored filename -$p_header['stored_filename'] = $p_header['filename']; - -// ----- Set the status field -$p_header['status'] = "ok"; - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; -// -------------------------------------------------------------------------------- -// Function : privReadCentralFileHeader() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privReadCentralFileHeader(&$p_header) -{ -$v_result=1; - -// ----- Read the 4 bytes signature -$v_binary_data = @fread($this->zip_fd, 4); -$v_data = unpack('Vid', $v_binary_data); - -// ----- Check signature -if ($v_data['id'] != 0x02014b50) -{ - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); - - // ----- Return - return PclZip::errorCode(); -} - -// ----- Read the first 42 bytes of the header -$v_binary_data = fread($this->zip_fd, 42); - -// ----- Look for invalid block size -if (strlen($v_binary_data) != 42) -{ - $p_header['filename'] = ""; - $p_header['status'] = "invalid_header"; - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); - - // ----- Return - return PclZip::errorCode(); -} - -// ----- Extract the values -$p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); - -// ----- Get filename -if ($p_header['filename_len'] != 0) - $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); -else - $p_header['filename'] = ''; - -// ----- Get extra -if ($p_header['extra_len'] != 0) - $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); -else - $p_header['extra'] = ''; - -// ----- Get comment -if ($p_header['comment_len'] != 0) - $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); -else - $p_header['comment'] = ''; - -// ----- Extract properties - -// ----- Recuperate date in UNIX format -//if ($p_header['mdate'] && $p_header['mtime']) -// TBC : bug : this was ignoring time with 0/0/0 -if (1) -{ - // ----- Extract time - $v_hour = ($p_header['mtime'] & 0xF800) >> 11; - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; - $v_seconde = ($p_header['mtime'] & 0x001F)*2; - - // ----- Extract date - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; - $v_month = ($p_header['mdate'] & 0x01E0) >> 5; - $v_day = $p_header['mdate'] & 0x001F; - - // ----- Get UNIX date format - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); - -} -else -{ - $p_header['mtime'] = time(); -} - -// ----- Set the stored filename -$p_header['stored_filename'] = $p_header['filename']; - -// ----- Set default status to ok -$p_header['status'] = 'ok'; - -// ----- Look if it is a directory -if (substr($p_header['filename'], -1) == '/') { - //$p_header['external'] = 0x41FF0010; - $p_header['external'] = 0x00000010; -} - - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Creates a temporary zip archive + $v_temp_zip = new PclZip($v_zip_temp_name); -// -------------------------------------------------------------------------------- -// Function : privCheckFileHeaders() -// Description : -// Parameters : -// Return Values : -// 1 on success, -// 0 on error; -// -------------------------------------------------------------------------------- -function privCheckFileHeaders(&$p_local_header, &$p_central_header) -{ -$v_result=1; + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { + $this->privCloseFd(); - // ----- Check the static values - // TBC - if ($p_local_header['filename'] != $p_central_header['filename']) { - } - if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { - } - if ($p_local_header['flag'] != $p_central_header['flag']) { - } - if ($p_local_header['compression'] != $p_central_header['compression']) { - } - if ($p_local_header['mtime'] != $p_central_header['mtime']) { - } - if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { - } + // ----- Return + return $v_result; + } - // ----- Look for flag bit 3 - if (($p_local_header['flag'] & 8) == 8) { - $p_local_header['size'] = $p_central_header['size']; - $p_local_header['compressed_size'] = $p_central_header['compressed_size']; - $p_local_header['crc'] = $p_central_header['crc']; - } + // ----- Look which file need to be kept + for ($i=0; $i<sizeof($v_header_list); $i++) { -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Calculate the position of the header + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); -// -------------------------------------------------------------------------------- -// Function : privReadEndCentralDir() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privReadEndCentralDir(&$p_central_dir) -{ -$v_result=1; - -// ----- Go to the end of the zip file -$v_size = filesize($this->zipname); -@fseek($this->zip_fd, $v_size); -if (@ftell($this->zip_fd) != $v_size) -{ - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); - - // ----- Return - return PclZip::errorCode(); -} - -// ----- First try : look if this is an archive with no commentaries (most of the time) -// in this case the end of central dir is at 22 bytes of the file end -$v_found = 0; -if ($v_size > 26) { - @fseek($this->zip_fd, $v_size-22); - if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - // ----- Return - return PclZip::errorCode(); - } + // ----- Return + return PclZip::errorCode(); + } - // ----- Read for bytes - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = @unpack('Vid', $v_binary_data); + // ----- Read the file header + $v_local_header = array(); + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); - // ----- Check signature - if ($v_data['id'] == 0x06054b50) { - $v_found = 1; - } + // ----- Return + return $v_result; + } + + // ----- Check that local file header is same as central file header + if ($this->privCheckFileHeaders($v_local_header, + $v_header_list[$i]) != 1) { + // TBC + } + unset($v_local_header); - $v_pos = ftell($this->zip_fd); -} + // ----- Write the file header + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); -// ----- Go back to the maximum possible size of the Central Dir End Record -if (!$v_found) { - $v_maximum_size = 65557; // 0xFFFF + 22; - if ($v_maximum_size > $v_size) - $v_maximum_size = $v_size; - @fseek($this->zip_fd, $v_size-$v_maximum_size); - if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + // ----- Return + return $v_result; + } - // ----- Return - return PclZip::errorCode(); - } + // ----- Read/write the data block + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); - // ----- Read byte per byte in order to find the signature - $v_pos = ftell($this->zip_fd); - $v_bytes = 0x00000000; - while ($v_pos < $v_size) - { - // ----- Read a byte - $v_byte = @fread($this->zip_fd, 1); + // ----- Return + return $v_result; + } + } - // ----- Add the byte - //$v_bytes = ($v_bytes << 8) | Ord($v_byte); - // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number - // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. - $v_bytes = (($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->zip_fd); - // ----- Compare the bytes - if ($v_bytes == 0x504b0506) - { - $v_pos++; - break; - } + // ----- Re-Create the Central Dir files header + for ($i=0; $i<sizeof($v_header_list); $i++) { + // ----- Create the file header + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); - $v_pos++; - } + // ----- Return + return $v_result; + } - // ----- Look if not found end of central dir - if ($v_pos == $v_size) - { + // ----- Transform the header to a 'usable' info + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); - // ----- Return - return PclZip::errorCode(); - } -} + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } -// ----- Read the first 18 bytes of the header -$v_binary_data = fread($this->zip_fd, 18); + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; -// ----- Look for invalid block size -if (strlen($v_binary_data) != 18) -{ + // ----- Create the central dir footer + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + // ----- Return + return $v_result; + } - // ----- Return - return PclZip::errorCode(); -} + // ----- Close + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); -// ----- Extract the values -$v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); -// ----- Check the global size -if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } + + // ----- Remove every files : reset the file + else if ($v_central_dir['entries'] != 0) { + $this->privCloseFd(); - // ----- Removed in release 2.2 see readme file - // The check of the file size is a little too strict. - // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. - // While decrypted, zip has training 0 bytes - if (0) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, - 'The central dir is not at the end of the archive.' - .' Some trailing bytes exists after the archive.'); + if (($v_result = $this->privOpenFd('wb')) != 1) { + return $v_result; + } - // ----- Return - return PclZip::errorCode(); - } -} - -// ----- Get comment -if ($v_data['comment_size'] != 0) { - $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); -} -else - $p_central_dir['comment'] = ''; - -$p_central_dir['entries'] = $v_data['entries']; -$p_central_dir['disk_entries'] = $v_data['disk_entries']; -$p_central_dir['offset'] = $v_data['offset']; -$p_central_dir['size'] = $v_data['size']; -$p_central_dir['disk'] = $v_data['disk']; -$p_central_dir['disk_start'] = $v_data['disk_start']; - -// TBC -//for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { -//} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { + return $v_result; + } -// -------------------------------------------------------------------------------- -// Function : privDeleteByRule() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privDeleteByRule(&$p_result_list, &$p_options) -{ -$v_result=1; -$v_list_detail = array(); - -// ----- Open the zip file -if (($v_result=$this->privOpenFd('rb')) != 1) -{ - // ----- Return - return $v_result; -} - -// ----- Read the central directory informations -$v_central_dir = array(); -if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) -{ - $this->privCloseFd(); - return $v_result; -} - -// ----- Go to beginning of File -@rewind($this->zip_fd); - -// ----- Scan all the files -// ----- Start at beginning of Central Dir -$v_pos_entry = $v_central_dir['offset']; -@rewind($this->zip_fd); -if (@fseek($this->zip_fd, $v_pos_entry)) -{ - // ----- Close the zip file - $this->privCloseFd(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - - // ----- Return - return PclZip::errorCode(); -} - -// ----- Read each entry -$v_header_list = array(); -$j_start = 0; -for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) -{ - - // ----- Read the file header - $v_header_list[$v_nb_extracted] = array(); - if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); + $this->privCloseFd(); + } + // ----- Return return $v_result; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // -------------------------------------------------------------------------------- + function privDirCheck($p_dir, $p_is_dir=false) + { + $v_result = 1; - // ----- Store the index - $v_header_list[$v_nb_extracted]['index'] = $i; - - // ----- Look for the specific extract rules - $v_found = false; - - // ----- Look for extract by name rule - if ((isset($p_options[PCLZIP_OPT_BY_NAME])) - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1)=='/')) + { + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); + } - // ----- Look if the filename is in the list - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) + { + return 1; + } - // ----- Look for a directory - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); - // ----- Look if the directory is in the filename path - if ((strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) - && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_found = true; - } - elseif ((($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ - && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_found = true; - } - } - // ----- Look for a filename - elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { - $v_found = true; - } + // ----- Just a check + if ($p_parent_dir != $p_dir) + { + // ----- Look for parent directory + if ($p_parent_dir != "") + { + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) + { + return $v_result; + } } - } - - // ----- Look for extract by ereg rule - // ereg() is deprecated with PHP 5.3 - /* - else if ((isset($p_options[PCLZIP_OPT_BY_EREG])) - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + } - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { - $v_found = true; - } - } - */ + // ----- Create the directory + if (!@mkdir($p_dir, 0777)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); - // ----- Look for extract by preg rule - else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + // ----- Return + return PclZip::errorCode(); + } - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { - $v_found = true; - } + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privMerge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privMerge(&$p_archive_to_add) + { + $v_result=1; - // ----- Look for extract by index rule - else if ((isset($p_options[PCLZIP_OPT_BY_INDEX])) - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - - // ----- Look if the index is in the list - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { - - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_found = true; - } - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; - } + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->zipname)) + { - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; - } - } - } - else { - $v_found = true; - } + // ----- Nothing to merge, so merge is a success + $v_result = 1; - // ----- Look for deletion - if ($v_found) - { - unset($v_header_list[$v_nb_extracted]); - } - else - { - $v_nb_extracted++; - } -} + // ----- Return + return $v_result; + } -// ----- Look if something need to be deleted -if ($v_nb_extracted > 0) { + // ----- Look if the archive exists + if (!is_file($this->zipname)) + { - // ----- Creates a temporay file - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + // ----- Do a duplicate + $v_result = $this->privDuplicate($p_archive_to_add->zipname); - // ----- Creates a temporary zip archive - $v_temp_zip = new PclZip($v_zip_temp_name); + // ----- Return + return $v_result; + } - // ----- Open the temporary zip file in write mode - if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { - $this->privCloseFd(); + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } - // ----- Return - return $v_result; + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; } - // ----- Look which file need to be kept - for ($i=0; $i<sizeof($v_header_list); $i++) { + // ----- Go to beginning of File + @rewind($this->zip_fd); - // ----- Calculate the position of the header - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Open the archive_to_add file + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) + { + $this->privCloseFd(); - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Return + return $v_result; + } - // ----- Return - return PclZip::errorCode(); - } + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); - // ----- Read the file header - $v_local_header = array(); - if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + return $v_result; + } - // ----- Return - return $v_result; - } - - // ----- Check that local file header is same as central file header - if ($this->privCheckFileHeaders($v_local_header, - $v_header_list[$i]) != 1) { - // TBC - } - unset($v_local_header); + // ----- Go to beginning of File + @rewind($p_archive_to_add->zip_fd); - // ----- Write the file header - if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - // ----- Return - return $v_result; - } + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); - // ----- Read/write the data block - if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); - // ----- Return - return $v_result; - } + // ----- Return + return PclZip::errorCode(); } - // ----- Store the offset of the central dir - $v_offset = @ftell($v_temp_zip->zip_fd); + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - // ----- Re-Create the Central Dir files header - for ($i=0; $i<sizeof($v_header_list); $i++) { - // ----- Create the file header - if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - // ----- Return - return $v_result; - } + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); - // ----- Transform the header to a 'usable' info - $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; } - - // ----- Zip file comment - $v_comment = ''; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; } - // ----- Calculate the size of the central header - $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; + // ----- Merge the file comments + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; + + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd)-$v_offset; + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; // ----- Create the central dir footer - if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { - // ----- Reset the file list - unset($v_header_list); - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($v_zip_temp_name); + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + @fclose($v_zip_temp_fd); + $this->zip_fd = null; - // ----- Return - return $v_result; + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; } + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + // ----- Close - $v_temp_zip->privCloseFd(); $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); // ----- Delete the zip file // TBC : I should test the result ... @@ -4797,738 +5218,475 @@ function privDeleteByRule(&$p_result_list, &$p_options) //@rename($v_zip_temp_name, $this->zipname); PclZipUtilRename($v_zip_temp_name, $this->zipname); - // ----- Destroy the temporary archive - unset($v_temp_zip); -} + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDuplicate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDuplicate($p_archive_filename) + { + $v_result=1; + + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) + { -// ----- Remove every files : reset the file -else if ($v_central_dir['entries'] != 0) { - $this->privCloseFd(); + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; - if (($v_result = $this->privOpenFd('wb')) != 1) { + // ----- Return return $v_result; } - if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { + // ----- Open the zip file + if (($v_result=$this->privOpenFd('wb')) != 1) + { + // ----- Return return $v_result; } + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) + { + $this->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close $this->privCloseFd(); -} -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Close the temporary file + @fclose($v_zip_temp_fd); -// -------------------------------------------------------------------------------- -// Function : privDirCheck() -// Description : -// Check if a directory exists, if not it creates it and all the parents directory -// which may be useful. -// Parameters : -// $p_dir : Directory path to check. -// Return Values : -// 1 : OK -// -1 : Unable to create directory -// -------------------------------------------------------------------------------- -function privDirCheck($p_dir, $p_is_dir=false) -{ -$v_result = 1; - - -// ----- Remove the final '/' -if (($p_is_dir) && (substr($p_dir, -1)=='/')) -{ - $p_dir = substr($p_dir, 0, strlen($p_dir)-1); -} - -// ----- Check the directory availability -if ((is_dir($p_dir)) || ($p_dir == "")) -{ - return 1; -} - -// ----- Extract parent directory -$p_parent_dir = dirname($p_dir); - -// ----- Just a check -if ($p_parent_dir != $p_dir) -{ - // ----- Look for parent directory - if ($p_parent_dir != "") + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorLog() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorLog($p_error_code=0, $p_error_string='') { - if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) - { - return $v_result; + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclError($p_error_code, $p_error_string); + } + else { + $this->error_code = $p_error_code; + $this->error_string = $p_error_string; } } -} - -// ----- Create the directory -if (!@mkdir($p_dir, 0777)) -{ - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorReset() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorReset() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclErrorReset(); + } + else { + $this->error_code = 0; + $this->error_string = ''; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDisableMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDisableMagicQuotes() + { + $v_result=1; - // ----- Return - return PclZip::errorCode(); -} + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Look if already done + if ($this->magic_quotes_status != -1) { + return $v_result; + } -// -------------------------------------------------------------------------------- -// Function : privMerge() -// Description : -// If $p_archive_to_add does not exist, the function exit with a success result. -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privMerge(&$p_archive_to_add) -{ -$v_result=1; - -// ----- Look if the archive_to_add exists -if (!is_file($p_archive_to_add->zipname)) -{ - - // ----- Nothing to merge, so merge is a success - $v_result = 1; - - // ----- Return - return $v_result; -} - -// ----- Look if the archive exists -if (!is_file($this->zipname)) -{ - - // ----- Do a duplicate - $v_result = $this->privDuplicate($p_archive_to_add->zipname); - - // ----- Return - return $v_result; -} - -// ----- Open the zip file -if (($v_result=$this->privOpenFd('rb')) != 1) -{ - // ----- Return - return $v_result; -} - -// ----- Read the central directory informations -$v_central_dir = array(); -if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) -{ - $this->privCloseFd(); - return $v_result; -} - -// ----- Go to beginning of File -@rewind($this->zip_fd); - -// ----- Open the archive_to_add file -if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) -{ - $this->privCloseFd(); - - // ----- Return - return $v_result; -} - -// ----- Read the central directory informations -$v_central_dir_to_add = array(); -if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) -{ - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); - - return $v_result; -} - -// ----- Go to beginning of File -@rewind($p_archive_to_add->zip_fd); - -// ----- Creates a temporay file -$v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - -// ----- Open the temporary file in write mode -if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) -{ - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); - - // ----- Return - return PclZip::errorCode(); -} - -// ----- Copy the files from the archive to the temporary file -// TBC : Here I should better append the file and go back to erase the central dir -$v_size = $v_central_dir['offset']; -while ($v_size != 0) -{ - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; -} - -// ----- Copy the files from the archive_to_add into the temporary file -$v_size = $v_central_dir_to_add['offset']; -while ($v_size != 0) -{ - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; -} - -// ----- Store the offset of the central dir -$v_offset = @ftell($v_zip_temp_fd); - -// ----- Copy the block of file headers from the old archive -$v_size = $v_central_dir['size']; -while ($v_size != 0) -{ - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; -} - -// ----- Copy the block of file headers from the archive_to_add -$v_size = $v_central_dir_to_add['size']; -while ($v_size != 0) -{ - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; -} - -// ----- Merge the file comments -$v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; - -// ----- Calculate the size of the (new) central header -$v_size = @ftell($v_zip_temp_fd)-$v_offset; - -// ----- Swap the file descriptor -// Here is a trick : I swap the temporary fd with the zip fd, in order to use -// the following methods on the temporary fil and not the real archive fd -$v_swap = $this->zip_fd; -$this->zip_fd = $v_zip_temp_fd; -$v_zip_temp_fd = $v_swap; - -// ----- Create the central dir footer -if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) -{ - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); - @fclose($v_zip_temp_fd); - $this->zip_fd = null; - - // ----- Reset the file list - unset($v_header_list); - - // ----- Return - return $v_result; -} - -// ----- Swap back the file descriptor -$v_swap = $this->zip_fd; -$this->zip_fd = $v_zip_temp_fd; -$v_zip_temp_fd = $v_swap; - -// ----- Close -$this->privCloseFd(); -$p_archive_to_add->privCloseFd(); - -// ----- Close the temporary file -@fclose($v_zip_temp_fd); - -// ----- Delete the zip file -// TBC : I should test the result ... -@unlink($this->zipname); - -// ----- Rename the temporary file -// TBC : I should test the result ... -//@rename($v_zip_temp_name, $this->zipname); -PclZipUtilRename($v_zip_temp_name, $this->zipname); - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Get and memorize the magic_quote value + $this->magic_quotes_status = @get_magic_quotes_runtime(); -// -------------------------------------------------------------------------------- -// Function : privDuplicate() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privDuplicate($p_archive_filename) -{ -$v_result=1; - -// ----- Look if the $p_archive_filename exists -if (!is_file($p_archive_filename)) -{ - - // ----- Nothing to duplicate, so duplicate is a success. - $v_result = 1; - - // ----- Return - return $v_result; -} - -// ----- Open the zip file -if (($v_result=$this->privOpenFd('wb')) != 1) -{ - // ----- Return - return $v_result; -} - -// ----- Open the temporary file in write mode -if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) -{ - $this->privCloseFd(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); - - // ----- Return - return PclZip::errorCode(); -} - -// ----- Copy the files from the archive to the temporary file -// TBC : Here I should better append the file and go back to erase the central dir -$v_size = filesize($p_archive_filename); -while ($v_size != 0) -{ - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($v_zip_temp_fd, $v_read_size); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; -} - -// ----- Close -$this->privCloseFd(); - -// ----- Close the temporary file -@fclose($v_zip_temp_fd); - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Disable magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime(0); + } -// -------------------------------------------------------------------------------- -// Function : privErrorLog() -// Description : -// Parameters : -// -------------------------------------------------------------------------------- -function privErrorLog($p_error_code=0, $p_error_string='') -{ -if (PCLZIP_ERROR_EXTERNAL == 1) { - PclError($p_error_code, $p_error_string); -} -else { - $this->error_code = $p_error_code; - $this->error_string = $p_error_string; -} -} -// -------------------------------------------------------------------------------- + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privSwapBackMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privSwapBackMagicQuotes() + { + $v_result=1; -// -------------------------------------------------------------------------------- -// Function : privErrorReset() -// Description : -// Parameters : -// -------------------------------------------------------------------------------- -function privErrorReset() -{ -if (PCLZIP_ERROR_EXTERNAL == 1) { - PclErrorReset(); -} -else { - $this->error_code = 0; - $this->error_string = ''; -} -} -// -------------------------------------------------------------------------------- + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } -// -------------------------------------------------------------------------------- -// Function : privDisableMagicQuotes() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privDisableMagicQuotes() -{ -$v_result=1; - -// ----- Look if function exists -if ((!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { - return $v_result; -} - -// ----- Look if already done -if ($this->magic_quotes_status != -1) { - return $v_result; -} - -// ----- Get and memorize the magic_quote value -$this->magic_quotes_status = @get_magic_quotes_runtime(); - -// ----- Disable magic_quotes -if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime(0); -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Look if something to do + if ($this->magic_quotes_status != -1) { + return $v_result; + } -// -------------------------------------------------------------------------------- -// Function : privSwapBackMagicQuotes() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function privSwapBackMagicQuotes() -{ -$v_result=1; - -// ----- Look if function exists -if ((!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { - return $v_result; -} - -// ----- Look if something to do -if ($this->magic_quotes_status != -1) { - return $v_result; -} - -// ----- Swap back magic_quotes -if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime($this->magic_quotes_status); -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Swap back magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime($this->magic_quotes_status); + } -} -// End of class -// -------------------------------------------------------------------------------- + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- -// -------------------------------------------------------------------------------- -// Function : PclZipUtilPathReduction() -// Description : -// Parameters : -// Return Values : -// -------------------------------------------------------------------------------- -function PclZipUtilPathReduction($p_dir) -{ -$v_result = ""; - -// ----- Look for not empty path -if ($p_dir != "") { - // ----- Explode path by directory names - $v_list = explode("/", $p_dir); - - // ----- Study directories from last to first - $v_skip = 0; - for ($i=sizeof($v_list)-1; $i>=0; $i--) { - // ----- Look for current path - if ($v_list[$i] == ".") { - // ----- Ignore this directory - // Should be the first $i=0, but no check is done - } - else if ($v_list[$i] == "..") { - $v_skip++; - } - else if ($v_list[$i] == "") { - // ----- First '/' i.e. root slash - if ($i == 0) { - $v_result = "/".$v_result; - if ($v_skip > 0) { - // ----- It is an invalid path, so the path is not modified - // TBC - $v_result = $p_dir; - $v_skip = 0; + } + // End of class + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathReduction() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilPathReduction($p_dir) + { + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + $v_skip = 0; + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") { + $v_skip++; + } + else if ($v_list[$i] == "") { + // ----- First '/' i.e. root slash + if ($i == 0) { + $v_result = "/".$v_result; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; + $v_skip = 0; + } + } + // ----- Last '/' i.e. indicates a directory + else if ($i == (sizeof($v_list)-1)) { + $v_result = $v_list[$i]; + } + // ----- Double '/' inside the path + else { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + } + else { + // ----- Look for item to skip + if ($v_skip > 0) { + $v_skip--; + } + else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } } } - // ----- Last '/' i.e. indicates a directory - else if ($i == (sizeof($v_list)-1)) { - $v_result = $v_list[$i]; - } - // ----- Double '/' inside the path - else { - // ----- Ignore only the double '//' in path, - // but not the first and last '/' - } - } - else { - // ----- Look for item to skip + + // ----- Look for skip if ($v_skip > 0) { - $v_skip--; - } - else { - $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + while ($v_skip > 0) { + $v_result = '../'.$v_result; + $v_skip--; + } } } + + // ----- Return + return $v_result; } - - // ----- Look for skip - if ($v_skip > 0) { - while ($v_skip > 0) { - $v_result = '../'.$v_result; - $v_skip--; + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathInclusion() + // Description : + // This function indicates if the path $p_path is under the $p_dir tree. Or, + // said in an other way, if the file or sub-dir $p_path is inside the dir + // $p_dir. + // The function indicates also if the path is exactly the same as the dir. + // This function supports path with duplicated '/' like '//', but does not + // support '.' or '..' statements. + // Parameters : + // Return Values : + // 0 if $p_path is not inside directory $p_dir + // 1 if $p_path is inside directory $p_dir + // 2 if $p_path is exactly the same as $p_dir + // -------------------------------------------------------------------------------- + function PclZipUtilPathInclusion($p_dir, $p_path) + { + $v_result = 1; + + // ----- Look for path beginning by ./ + if ( ($p_dir == '.') + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); + } + if ( ($p_path == '.') + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); } - } -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- -// -------------------------------------------------------------------------------- -// Function : PclZipUtilPathInclusion() -// Description : -// This function indicates if the path $p_path is under the $p_dir tree. Or, -// said in an other way, if the file or sub-dir $p_path is inside the dir -// $p_dir. -// The function indicates also if the path is exactly the same as the dir. -// This function supports path with duplicated '/' like '//', but does not -// support '.' or '..' statements. -// Parameters : -// Return Values : -// 0 if $p_path is not inside directory $p_dir -// 1 if $p_path is inside directory $p_dir -// 2 if $p_path is exactly the same as $p_dir -// -------------------------------------------------------------------------------- -function PclZipUtilPathInclusion($p_dir, $p_path) -{ -$v_result = 1; - -// ----- Look for path beginning by ./ -if (($p_dir == '.') - || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { - $p_dir = PclZipUtilTranslateWinPath(getcwd(), false).'/'.substr($p_dir, 1); -} -if (($p_path == '.') - || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { - $p_path = PclZipUtilTranslateWinPath(getcwd(), false).'/'.substr($p_path, 1); -} - -// ----- Explode dir and path by directory separator -$v_list_dir = explode("/", $p_dir); -$v_list_dir_size = sizeof($v_list_dir); -$v_list_path = explode("/", $p_path); -$v_list_path_size = sizeof($v_list_path); - -// ----- Study directories paths -$i = 0; -$j = 0; -while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { - - // ----- Look for empty dir (path reduction) - if ($v_list_dir[$i] == '') { - $i++; - continue; - } - if ($v_list_path[$j] == '') { - $j++; - continue; - } + // ----- Explode dir and path by directory separator + $v_list_dir = explode("/", $p_dir); + $v_list_dir_size = sizeof($v_list_dir); + $v_list_path = explode("/", $p_path); + $v_list_path_size = sizeof($v_list_path); - // ----- Compare the items - if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ($v_list_path[$j] != '')) { - $v_result = 0; - } + // ----- Study directories paths + $i = 0; + $j = 0; + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { - // ----- Next items - $i++; - $j++; -} + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } -// ----- Look if everything seems to be the same -if ($v_result) { - // ----- Skip all the empty items - while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; - while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + // ----- Compare the items + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { + $v_result = 0; + } - if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { - // ----- There are exactly the same - $v_result = 2; - } - else if ($i < $v_list_dir_size) { - // ----- The path is shorter than the dir - $v_result = 0; - } -} + // ----- Next items + $i++; + $j++; + } -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Look if everything seems to be the same + if ($v_result) { + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; -// -------------------------------------------------------------------------------- -// Function : PclZipUtilCopyBlock() -// Description : -// Parameters : -// $p_mode : read/write compression mode -// 0 : src & dest normal -// 1 : src gzip, dest normal -// 2 : src normal, dest gzip -// 3 : src & dest gzip -// Return Values : -// -------------------------------------------------------------------------------- -function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) -{ -$v_result = 1; + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } + else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } + } -if ($p_mode==0) -{ - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_src, $v_read_size); - @fwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } -} -else if ($p_mode==1) -{ - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($p_src, $v_read_size); - @fwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } -} -else if ($p_mode==2) -{ - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_src, $v_read_size); - @gzwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; + // ----- Return + return $v_result; } -} -else if ($p_mode==3) -{ - while ($p_size != 0) + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilCopyBlock() + // Description : + // Parameters : + // $p_mode : read/write compression mode + // 0 : src & dest normal + // 1 : src gzip, dest normal + // 2 : src normal, dest gzip + // 3 : src & dest gzip + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($p_src, $v_read_size); - @gzwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- - -// -------------------------------------------------------------------------------- -// Function : PclZipUtilRename() -// Description : -// This function tries to do a simple rename() function. If it fails, it -// tries to copy the $p_src file in a new $p_dest file and then unlink the -// first one. -// Parameters : -// $p_src : Old filename -// $p_dest : New filename -// Return Values : -// 1 on success, 0 on failure. -// -------------------------------------------------------------------------------- -function PclZipUtilRename($p_src, $p_dest) -{ -$v_result = 1; + $v_result = 1; -// ----- Try to rename the files -if (!@rename($p_src, $p_dest)) { + if ($p_mode==0) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==1) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==2) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==3) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } - // ----- Try to copy & unlink the src - if (!@copy($p_src, $p_dest)) { - $v_result = 0; - } - else if (!@unlink($p_src)) { - $v_result = 0; + // ----- Return + return $v_result; } -} - -// ----- Return -return $v_result; -} -// -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilRename() + // Description : + // This function tries to do a simple rename() function. If it fails, it + // tries to copy the $p_src file in a new $p_dest file and then unlink the + // first one. + // Parameters : + // $p_src : Old filename + // $p_dest : New filename + // Return Values : + // 1 on success, 0 on failure. + // -------------------------------------------------------------------------------- + function PclZipUtilRename($p_src, $p_dest) + { + $v_result = 1; -// -------------------------------------------------------------------------------- -// Function : PclZipUtilOptionText() -// Description : -// Translate option value in text. Mainly for debug purpose. -// Parameters : -// $p_option : the option value. -// Return Values : -// The option text value. -// -------------------------------------------------------------------------------- -function PclZipUtilOptionText($p_option) -{ + // ----- Try to rename the files + if (!@rename($p_src, $p_dest)) { -$v_list = get_defined_constants(); -for (reset($v_list); $v_key = key($v_list); next($v_list)) { - $v_prefix = substr($v_key, 0, 10); - if ((($v_prefix == 'PCLZIP_OPT') - || ($v_prefix == 'PCLZIP_CB_') - || ($v_prefix == 'PCLZIP_ATT')) - && ($v_list[$v_key] == $p_option)) { - return $v_key; + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; + } + else if (!@unlink($p_src)) { + $v_result = 0; + } } -} -$v_result = 'Unknown'; - -return $v_result; -} -// -------------------------------------------------------------------------------- + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilOptionText() + // Description : + // Translate option value in text. Mainly for debug purpose. + // Parameters : + // $p_option : the option value. + // Return Values : + // The option text value. + // -------------------------------------------------------------------------------- + function PclZipUtilOptionText($p_option) + { + + $v_list = get_defined_constants(); + for (reset($v_list); $v_key = key($v_list); next($v_list)) { + $v_prefix = substr($v_key, 0, 10); + if (( ($v_prefix == 'PCLZIP_OPT') + || ($v_prefix == 'PCLZIP_CB_') + || ($v_prefix == 'PCLZIP_ATT')) + && ($v_list[$v_key] == $p_option)) { + return $v_key; + } + } + + $v_result = 'Unknown'; -// -------------------------------------------------------------------------------- -// Function : PclZipUtilTranslateWinPath() -// Description : -// Translate windows path by replacing '\' by '/' and optionally removing -// drive letter. -// Parameters : -// $p_path : path to translate. -// $p_remove_disk_letter : true | false -// Return Values : -// The path translated. -// -------------------------------------------------------------------------------- -function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) -{ -if (stristr(php_uname(), 'windows')) { - // ----- Look for potential disk letter - if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { - $p_path = substr($p_path, $v_position+1); + return $v_result; } - // ----- Change potential windows directory separator - if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { - $p_path = strtr($p_path, '\\', '/'); + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilTranslateWinPath() + // Description : + // Translate windows path by replacing '\' by '/' and optionally removing + // drive letter. + // Parameters : + // $p_path : path to translate. + // $p_remove_disk_letter : true | false + // Return Values : + // The path translated. + // -------------------------------------------------------------------------------- + function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) + { + if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; } -} -return $p_path; -} -// -------------------------------------------------------------------------------- \ No newline at end of file + // -------------------------------------------------------------------------------- + \ No newline at end of file diff --git a/Classes/PHPExcel/Worksheet/HeaderFooter.php b/Classes/PHPExcel/Worksheet/HeaderFooter.php index f4ba2a422..394baf7c2 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooter.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooter.php @@ -15,7 +15,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software + * License along with this library; if not,241 write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category PHPExcel @@ -237,7 +237,7 @@ public function setOddFooter($pValue) * @return string */ public function getEvenHeader() - + { return $this->_evenHeader; } From 1bf5ea414b1819d24466bcbbc547c9c102220e48 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sat, 16 May 2015 13:04:38 +0200 Subject: [PATCH 375/467] PSR2 Fixes --- Classes/PHPExcel/Chart/Renderer/jpgraph.php | 9 + Classes/PHPExcel/Helper/HTML.php | 81 +++-- Classes/PHPExcel/IOFactory.php | 2 +- Classes/PHPExcel/Reader/Abstract.php | 46 +-- Classes/PHPExcel/Reader/Excel2003XML.php | 353 ++++++++++---------- Classes/PHPExcel/ReferenceHelper.php | 44 ++- Classes/PHPExcel/Worksheet.php | 269 ++++++++------- 7 files changed, 440 insertions(+), 364 deletions(-) diff --git a/Classes/PHPExcel/Chart/Renderer/jpgraph.php b/Classes/PHPExcel/Chart/Renderer/jpgraph.php index b95f3b28f..b3d7396f5 100644 --- a/Classes/PHPExcel/Chart/Renderer/jpgraph.php +++ b/Classes/PHPExcel/Chart/Renderer/jpgraph.php @@ -752,16 +752,19 @@ private function renderCombinationChart($groupCount, $dimensions, $outputDestina switch ($chartType) { case 'area3DChart': $dimensions = '3d'; + // no break case 'areaChart': $this->renderPlotLine($i, true, true, $dimensions); break; case 'bar3DChart': $dimensions = '3d'; + // no break case 'barChart': $this->renderPlotBar($i, $dimensions); break; case 'line3DChart': $dimensions = '3d'; + // no break case 'lineChart': $this->renderPlotLine($i, false, true, $dimensions); break; @@ -812,26 +815,31 @@ public function render($outputDestination) switch ($chartType) { case 'area3DChart': $dimensions = '3d'; + // no break case 'areaChart': $this->renderAreaChart($groupCount, $dimensions); break; case 'bar3DChart': $dimensions = '3d'; + // no break case 'barChart': $this->renderBarChart($groupCount, $dimensions); break; case 'line3DChart': $dimensions = '3d'; + // no break case 'lineChart': $this->renderLineChart($groupCount, $dimensions); break; case 'pie3DChart': $dimensions = '3d'; + // no break case 'pieChart': $this->renderPieChart($groupCount, $dimensions, false, false); break; case 'doughnut3DChart': $dimensions = '3d'; + // no break case 'doughnutChart': $this->renderPieChart($groupCount, $dimensions, true, true); break; @@ -846,6 +854,7 @@ public function render($outputDestination) break; case 'surface3DChart': $dimensions = '3d'; + // no break case 'surfaceChart': $this->renderContourChart($groupCount, $dimensions); break; diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index 86cbe31f4..28bf6b107 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -3,7 +3,7 @@ class PHPExcel_Helper_HTML { protected static $colourMap = array( - 'aliceblue' => 'f0f8ff', + 'aliceblue' => 'f0f8ff', 'antiquewhite' => 'faebd7', 'antiquewhite1' => 'ffefdb', 'antiquewhite2' => 'eedfcc', @@ -573,7 +573,8 @@ class PHPExcel_Helper_HTML protected $richTextObject; - protected function initialise() { + protected function initialise() + { $this->face = $this->size = $this->color = null; $this->bold = $this->italic = $this->underline = $this->superscript = $this->subscript = $this->strikethrough = false; @@ -582,7 +583,8 @@ protected function initialise() { $this->stringData = ''; } - public function toRichTextObject($html) { + public function toRichTextObject($html) + { $this->initialise(); // Create a new DOM object @@ -594,15 +596,17 @@ public function toRichTextObject($html) { // Discard excess white space $dom->preserveWhiteSpace = false; - $this->richTextObject = new PHPExcel_RichText();; + $this->richTextObject = new PHPExcel_RichText(); $this->parseElements($dom); return $this->richTextObject; } - protected function buildTextRun() { + protected function buildTextRun() + { $text = $this->stringData; - if (trim($text) === '') + if (trim($text) === '') { return; + } $richtextRun = $this->richTextObject->createTextRun($this->stringData); if ($this->face) { @@ -612,7 +616,7 @@ protected function buildTextRun() { $richtextRun->getFont()->setSize($this->size); } if ($this->color) { - $richtextRun->getFont()->setColor( new PHPExcel_Style_Color( 'ff' . $this->color ) ); + $richtextRun->getFont()->setColor(new PHPExcel_Style_Color('ff' . $this->color)); } if ($this->bold) { $richtextRun->getFont()->setBold(true); @@ -635,7 +639,8 @@ protected function buildTextRun() { $this->stringData = ''; } - protected function rgbToColour($rgb) { + protected function rgbToColour($rgb) + { preg_match_all('/\d+/', $rgb, $values); foreach ($values[0] as &$value) { $value = str_pad(dechex($value), 2, '0', STR_PAD_LEFT); @@ -643,11 +648,13 @@ protected function rgbToColour($rgb) { return implode($values[0]); } - protected function colourNameLookup($rgb) { + protected function colourNameLookup($rgb) + { return self::$colourMap[$rgb]; } - protected function startFontTag($tag) { + protected function startFontTag($tag) + { foreach ($tag->attributes as $attribute) { $attributeName = strtolower($attribute->name); $attributeValue = $attribute->value; @@ -666,69 +673,85 @@ protected function startFontTag($tag) { } } - protected function endFontTag() { + protected function endFontTag() + { $this->face = $this->size = $this->color = null; } - protected function startBoldTag() { + protected function startBoldTag() + { $this->bold = true; } - protected function endBoldTag() { + protected function endBoldTag() + { $this->bold = false; } - protected function startItalicTag() { + protected function startItalicTag() + { $this->italic = true; } - protected function endItalicTag() { + protected function endItalicTag() + { $this->italic = false; } - protected function startUnderlineTag() { + protected function startUnderlineTag() + { $this->underline = true; } - protected function endUnderlineTag() { + protected function endUnderlineTag() + { $this->underline = false; } - protected function startSubscriptTag() { + protected function startSubscriptTag() + { $this->subscript = true; } - protected function endSubscriptTag() { + protected function endSubscriptTag() + { $this->subscript = false; } - protected function startSuperscriptTag() { + protected function startSuperscriptTag() + { $this->superscript = true; } - protected function endSuperscriptTag() { + protected function endSuperscriptTag() + { $this->superscript = false; } - protected function startStrikethruTag() { + protected function startStrikethruTag() + { $this->strikethrough = true; } - protected function endStrikethruTag() { + protected function endStrikethruTag() + { $this->strikethrough = false; } - protected function breakTag() { + protected function breakTag() + { $this->stringData .= PHP_EOL; } - protected function parseTextNode(DOMText $textNode) { + protected function parseTextNode(DOMText $textNode) + { $domText = preg_replace('/\s+/u', ' ', ltrim($textNode->nodeValue)); $this->stringData .= $domText; $this->buildTextRun(); } - protected function handleCallback($element, $callbackTag, $callbacks) { + protected function handleCallback($element, $callbackTag, $callbacks) + { if (isset($callbacks[$callbackTag])) { $elementHandler = $callbacks[$callbackTag]; if (method_exists($this, $elementHandler)) { @@ -737,7 +760,8 @@ protected function handleCallback($element, $callbackTag, $callbacks) { } } - protected function parseElementNode(DOMElement $element) { + protected function parseElementNode(DOMElement $element) + { $callbackTag = strtolower($element->nodeName); $this->stack[] = $callbackTag; @@ -750,7 +774,8 @@ protected function parseElementNode(DOMElement $element) { $this->handleCallback($element, $callbackTag, $this->endTagCallbacks); } - protected function parseElements(DOMNode $element) { + protected function parseElements(DOMNode $element) + { foreach ($element->childNodes as $child) { if ($child instanceof DOMText) { $this->parseTextNode($child); diff --git a/Classes/PHPExcel/IOFactory.php b/Classes/PHPExcel/IOFactory.php index 8b063cd70..bc1d99e3c 100644 --- a/Classes/PHPExcel/IOFactory.php +++ b/Classes/PHPExcel/IOFactory.php @@ -70,7 +70,7 @@ class PHPExcel_IOFactory * Private constructor for PHPExcel_IOFactory */ private function __construct() - { + { } /** diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php index a0201366c..08f8dbd13 100644 --- a/Classes/PHPExcel/Reader/Abstract.php +++ b/Classes/PHPExcel/Reader/Abstract.php @@ -42,7 +42,7 @@ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader * * @var boolean */ - protected $_readDataOnly = FALSE; + protected $_readDataOnly = false; /** * Read charts that are defined in the workbook? @@ -50,7 +50,7 @@ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader * * @var boolean */ - protected $_includeCharts = FALSE; + protected $_includeCharts = false; /** * Restrict which sheets should be loaded? @@ -58,16 +58,16 @@ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader * * @var array of string */ - protected $_loadSheetsOnly = NULL; + protected $_loadSheetsOnly = null; /** * PHPExcel_Reader_IReadFilter instance * * @var PHPExcel_Reader_IReadFilter */ - protected $_readFilter = NULL; + protected $_readFilter = null; - protected $_fileHandle = NULL; + protected $_fileHandle = null; /** @@ -77,7 +77,8 @@ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader * * @return boolean */ - public function getReadDataOnly() { + public function getReadDataOnly() + { return $this->_readDataOnly; } @@ -90,7 +91,8 @@ public function getReadDataOnly() { * * @return PHPExcel_Reader_IReader */ - public function setReadDataOnly($pValue = FALSE) { + public function setReadDataOnly($pValue = false) + { $this->_readDataOnly = $pValue; return $this; } @@ -103,7 +105,8 @@ public function setReadDataOnly($pValue = FALSE) { * * @return boolean */ - public function getIncludeCharts() { + public function getIncludeCharts() + { return $this->_includeCharts; } @@ -117,7 +120,8 @@ public function getIncludeCharts() { * * @return PHPExcel_Reader_IReader */ - public function setIncludeCharts($pValue = FALSE) { + public function setIncludeCharts($pValue = false) + { $this->_includeCharts = (boolean) $pValue; return $this; } @@ -143,13 +147,13 @@ public function getLoadSheetsOnly() * * @return PHPExcel_Reader_IReader */ - public function setLoadSheetsOnly($value = NULL) + public function setLoadSheetsOnly($value = null) { - if ($value === NULL) + if ($value === null) { return $this->setLoadAllSheets(); + } - $this->_loadSheetsOnly = is_array($value) ? - $value : array($value); + $this->_loadSheetsOnly = is_array($value) ? $value : array($value); return $this; } @@ -161,7 +165,7 @@ public function setLoadSheetsOnly($value = NULL) */ public function setLoadAllSheets() { - $this->_loadSheetsOnly = NULL; + $this->_loadSheetsOnly = null; return $this; } @@ -170,7 +174,8 @@ public function setLoadAllSheets() * * @return PHPExcel_Reader_IReadFilter */ - public function getReadFilter() { + public function getReadFilter() + { return $this->_readFilter; } @@ -180,7 +185,8 @@ public function getReadFilter() { * @param PHPExcel_Reader_IReadFilter $pValue * @return PHPExcel_Reader_IReader */ - public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) { + public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) + { $this->_readFilter = $pValue; return $this; } @@ -201,7 +207,7 @@ protected function _openFile($pFilename) // Open file $this->_fileHandle = fopen($pFilename, 'r'); - if ($this->_fileHandle === FALSE) { + if ($this->_fileHandle === false) { throw new PHPExcel_Reader_Exception("Could not open file " . $pFilename . " for reading."); } } @@ -219,11 +225,11 @@ public function canRead($pFilename) try { $this->_openFile($pFilename); } catch (Exception $e) { - return FALSE; + return false; } $readable = $this->_isValidFormat(); - fclose ($this->_fileHandle); + fclose($this->_fileHandle); return $readable; } @@ -236,7 +242,7 @@ public function canRead($pFilename) public function securityScan($xml) { $pattern = '/\\0?' . implode('\\0?', str_split('<!DOCTYPE')) . '\\0?/'; - if (preg_match($pattern, $xml)) { + if (preg_match($pattern, $xml)) { throw new PHPExcel_Reader_Exception('Detected use of ENTITY in XML, spreadsheet file load() aborted to prevent XXE/XEE attacks'); } return $xml; diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index 4f1058144..e66ee1f1e 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -62,7 +62,8 @@ class PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements P /** * Create a new PHPExcel_Reader_Excel2003XML */ - public function __construct() { + public function __construct() + { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); } @@ -238,8 +239,8 @@ public function load($pFilename) return $this->loadIntoExisting($pFilename, $objPHPExcel); } - - protected static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { + protected static function identifyFixedStyleValue($styleList,&$styleAttributeValue) + { $styleAttributeValue = strtolower($styleAttributeValue); foreach ($styleList as $style) { if ($styleAttributeValue == strtolower($style)) { @@ -250,13 +251,13 @@ protected static function identifyFixedStyleValue($styleList,&$styleAttributeVal return false; } - /** * pixel units to excel width units(units of 1/256th of a character width) * @param pxs * @return */ - protected static function _pixel2WidthUnits($pxs) { + protected static function _pixel2WidthUnits($pxs) + { $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); $widthUnits = 256 * ($pxs / 7); @@ -264,25 +265,24 @@ protected static function _pixel2WidthUnits($pxs) { return $widthUnits; } - /** * excel width units(units of 1/256th of a character width) to pixel units * @param widthUnits * @return */ - protected static function _widthUnits2Pixel($widthUnits) { + protected static function _widthUnits2Pixel($widthUnits) + { $pixels = ($widthUnits / 256) * 7; $offsetWidthUnits = $widthUnits % 256; $pixels += round($offsetWidthUnits / (256 / 7)); return $pixels; } - - protected static function _hex2str($hex) { + protected static function _hex2str($hex) + { return chr(hexdec($hex[1])); } - /** * Loads PHPExcel from file into PHPExcel instance * @@ -293,35 +293,34 @@ protected static function _hex2str($hex) { */ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) { - $fromFormats = array('\-', '\ '); - $toFormats = array('-', ' '); + $fromFormats = array('\-', '\ '); + $toFormats = array('-', ' '); $underlineStyles = array ( - PHPExcel_Style_Font::UNDERLINE_NONE, - PHPExcel_Style_Font::UNDERLINE_DOUBLE, - PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING, - PHPExcel_Style_Font::UNDERLINE_SINGLE, - PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING - ); + PHPExcel_Style_Font::UNDERLINE_NONE, + PHPExcel_Style_Font::UNDERLINE_DOUBLE, + PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING, + PHPExcel_Style_Font::UNDERLINE_SINGLE, + PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING + ); $verticalAlignmentStyles = array ( - PHPExcel_Style_Alignment::VERTICAL_BOTTOM, - PHPExcel_Style_Alignment::VERTICAL_TOP, - PHPExcel_Style_Alignment::VERTICAL_CENTER, - PHPExcel_Style_Alignment::VERTICAL_JUSTIFY - ); + PHPExcel_Style_Alignment::VERTICAL_BOTTOM, + PHPExcel_Style_Alignment::VERTICAL_TOP, + PHPExcel_Style_Alignment::VERTICAL_CENTER, + PHPExcel_Style_Alignment::VERTICAL_JUSTIFY + ); $horizontalAlignmentStyles = array ( - PHPExcel_Style_Alignment::HORIZONTAL_GENERAL, - PHPExcel_Style_Alignment::HORIZONTAL_LEFT, - PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, - PHPExcel_Style_Alignment::HORIZONTAL_CENTER, - PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS, - PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY - ); + PHPExcel_Style_Alignment::HORIZONTAL_GENERAL, + PHPExcel_Style_Alignment::HORIZONTAL_LEFT, + PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS, + PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY + ); $timezoneObj = new DateTimeZone('Europe/London'); $GMT = new DateTimeZone('UTC'); - // Check if file exists if (!file_exists($pFilename)) { throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); @@ -339,40 +338,40 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($xml->DocumentProperties[0] as $propertyName => $propertyValue) { switch ($propertyName) { case 'Title' : - $docProps->setTitle(self::_convertStringEncoding($propertyValue, $this->_charSet)); - break; + $docProps->setTitle(self::_convertStringEncoding($propertyValue, $this->_charSet)); + break; case 'Subject' : - $docProps->setSubject(self::_convertStringEncoding($propertyValue, $this->_charSet)); - break; + $docProps->setSubject(self::_convertStringEncoding($propertyValue, $this->_charSet)); + break; case 'Author' : - $docProps->setCreator(self::_convertStringEncoding($propertyValue, $this->_charSet)); - break; + $docProps->setCreator(self::_convertStringEncoding($propertyValue, $this->_charSet)); + break; case 'Created' : - $creationDate = strtotime($propertyValue); - $docProps->setCreated($creationDate); - break; + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + break; case 'LastAuthor' : - $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue, $this->_charSet)); - break; + $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue, $this->_charSet)); + break; case 'LastSaved' : - $lastSaveDate = strtotime($propertyValue); - $docProps->setModified($lastSaveDate); - break; + $lastSaveDate = strtotime($propertyValue); + $docProps->setModified($lastSaveDate); + break; case 'Company' : - $docProps->setCompany(self::_convertStringEncoding($propertyValue, $this->_charSet)); - break; + $docProps->setCompany(self::_convertStringEncoding($propertyValue, $this->_charSet)); + break; case 'Category' : - $docProps->setCategory(self::_convertStringEncoding($propertyValue, $this->_charSet)); - break; + $docProps->setCategory(self::_convertStringEncoding($propertyValue, $this->_charSet)); + break; case 'Manager' : - $docProps->setManager(self::_convertStringEncoding($propertyValue, $this->_charSet)); - break; + $docProps->setManager(self::_convertStringEncoding($propertyValue, $this->_charSet)); + break; case 'Keywords' : - $docProps->setKeywords(self::_convertStringEncoding($propertyValue, $this->_charSet)); - break; + $docProps->setKeywords(self::_convertStringEncoding($propertyValue, $this->_charSet)); + break; case 'Description' : - $docProps->setDescription(self::_convertStringEncoding($propertyValue, $this->_charSet)); - break; + $docProps->setDescription(self::_convertStringEncoding($propertyValue, $this->_charSet)); + break; } } } @@ -421,113 +420,113 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo $styleType.'<br />'; switch ($styleType) { case 'Alignment' : - foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { + foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; - $styleAttributeValue = (string) $styleAttributeValue; - switch ($styleAttributeKey) { - case 'Vertical' : - if (self::identifyFixedStyleValue($verticalAlignmentStyles, $styleAttributeValue)) { - $this->_styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; - } - break; - case 'Horizontal' : - if (self::identifyFixedStyleValue($horizontalAlignmentStyles, $styleAttributeValue)) { - $this->_styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; - } - break; - case 'WrapText' : - $this->_styles[$styleID]['alignment']['wrap'] = true; - break; - } + $styleAttributeValue = (string) $styleAttributeValue; + switch ($styleAttributeKey) { + case 'Vertical' : + if (self::identifyFixedStyleValue($verticalAlignmentStyles, $styleAttributeValue)) { + $this->_styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; + } + break; + case 'Horizontal' : + if (self::identifyFixedStyleValue($horizontalAlignmentStyles, $styleAttributeValue)) { + $this->_styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; + } + break; + case 'WrapText' : + $this->_styles[$styleID]['alignment']['wrap'] = true; + break; } - break; + } + break; case 'Borders' : - foreach ($styleData->Border as $borderStyle) { - $borderAttributes = $borderStyle->attributes($namespaces['ss']); - $thisBorder = array(); - foreach ($borderAttributes as $borderStyleKey => $borderStyleValue) { + foreach ($styleData->Border as $borderStyle) { + $borderAttributes = $borderStyle->attributes($namespaces['ss']); + $thisBorder = array(); + foreach ($borderAttributes as $borderStyleKey => $borderStyleValue) { // echo $borderStyleKey.' = '.$borderStyleValue.'<br />'; - switch ($borderStyleKey) { - case 'LineStyle' : - $thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; + switch ($borderStyleKey) { + case 'LineStyle' : + $thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; // $thisBorder['style'] = $borderStyleValue; - break; - case 'Weight' : + break; + case 'Weight' : // $thisBorder['style'] = $borderStyleValue; - break; - case 'Position' : - $borderPosition = strtolower($borderStyleValue); - break; - case 'Color' : - $borderColour = substr($borderStyleValue,1); - $thisBorder['color']['rgb'] = $borderColour; - break; - } + break; + case 'Position' : + $borderPosition = strtolower($borderStyleValue); + break; + case 'Color' : + $borderColour = substr($borderStyleValue,1); + $thisBorder['color']['rgb'] = $borderColour; + break; } - if (!empty($thisBorder)) { - if (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) { - $this->_styles[$styleID]['borders'][$borderPosition] = $thisBorder; - } + } + if (!empty($thisBorder)) { + if (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) { + $this->_styles[$styleID]['borders'][$borderPosition] = $thisBorder; } } - break; + } + break; case 'Font' : - foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { + foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; - $styleAttributeValue = (string) $styleAttributeValue; - switch ($styleAttributeKey) { - case 'FontName' : - $this->_styles[$styleID]['font']['name'] = $styleAttributeValue; - break; - case 'Size' : - $this->_styles[$styleID]['font']['size'] = $styleAttributeValue; - break; - case 'Color' : - $this->_styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue,1); - break; - case 'Bold' : - $this->_styles[$styleID]['font']['bold'] = true; - break; - case 'Italic' : - $this->_styles[$styleID]['font']['italic'] = true; - break; - case 'Underline' : - if (self::identifyFixedStyleValue($underlineStyles, $styleAttributeValue)) { - $this->_styles[$styleID]['font']['underline'] = $styleAttributeValue; - } - break; - } + $styleAttributeValue = (string) $styleAttributeValue; + switch ($styleAttributeKey) { + case 'FontName' : + $this->_styles[$styleID]['font']['name'] = $styleAttributeValue; + break; + case 'Size' : + $this->_styles[$styleID]['font']['size'] = $styleAttributeValue; + break; + case 'Color' : + $this->_styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue,1); + break; + case 'Bold' : + $this->_styles[$styleID]['font']['bold'] = true; + break; + case 'Italic' : + $this->_styles[$styleID]['font']['italic'] = true; + break; + case 'Underline' : + if (self::identifyFixedStyleValue($underlineStyles, $styleAttributeValue)) { + $this->_styles[$styleID]['font']['underline'] = $styleAttributeValue; + } + break; } - break; + } + break; case 'Interior' : - foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { + foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; - switch ($styleAttributeKey) { - case 'Color' : - $this->_styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue,1); - break; - } + switch ($styleAttributeKey) { + case 'Color' : + $this->_styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue,1); + break; } - break; + } + break; case 'NumberFormat' : - foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { + foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; - $styleAttributeValue = str_replace($fromFormats, $toFormats, $styleAttributeValue); - switch ($styleAttributeValue) { - case 'Short Date' : - $styleAttributeValue = 'dd/mm/yyyy'; - break; - } - if ($styleAttributeValue > '') { - $this->_styles[$styleID]['numberformat']['code'] = $styleAttributeValue; - } + $styleAttributeValue = str_replace($fromFormats, $toFormats, $styleAttributeValue); + switch ($styleAttributeValue) { + case 'Short Date' : + $styleAttributeValue = 'dd/mm/yyyy'; + break; + } + if ($styleAttributeValue > '') { + $this->_styles[$styleID]['numberformat']['code'] = $styleAttributeValue; } - break; + } + break; case 'Protection' : - foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { + foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; - } - break; + } + break; } } // print_r($this->_styles[$styleID]); @@ -588,14 +587,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $columnID = 'A'; foreach ($rowData->Cell as $cell) { - $cell_ss = $cell->attributes($namespaces['ss']); if (isset($cell_ss['Index'])) { $columnID = PHPExcel_Cell::stringFromColumnIndex($cell_ss['Index']-1); } $cellRange = $columnID.$rowID; - if ($this->getReadFilter() !== NULL) { + if ($this->getReadFilter() !== null) { if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { continue; } @@ -643,27 +641,27 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) const TYPE_ERROR = 'e'; */ case 'String' : - $cellValue = self::_convertStringEncoding($cellValue, $this->_charSet); - $type = PHPExcel_Cell_DataType::TYPE_STRING; - break; + $cellValue = self::_convertStringEncoding($cellValue, $this->_charSet); + $type = PHPExcel_Cell_DataType::TYPE_STRING; + break; case 'Number' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $cellValue = (float) $cellValue; - if (floor($cellValue) == $cellValue) { - $cellValue = (integer) $cellValue; - } - break; + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $cellValue = (float) $cellValue; + if (floor($cellValue) == $cellValue) { + $cellValue = (integer) $cellValue; + } + break; case 'Boolean' : - $type = PHPExcel_Cell_DataType::TYPE_BOOL; - $cellValue = ($cellValue != 0); - break; + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $cellValue = ($cellValue != 0); + break; case 'DateTime' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $cellValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellValue)); - break; + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $cellValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellValue)); + break; case 'Error' : - $type = PHPExcel_Cell_DataType::TYPE_ERROR; - break; + $type = PHPExcel_Cell_DataType::TYPE_ERROR; + break; } } @@ -700,16 +698,24 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($cellReferences as $cellReference) { $rowReference = $cellReference[2][0]; // Empty R reference is the current row - if ($rowReference == '') $rowReference = $rowID; + if ($rowReference == '') { + $rowReference = $rowID; + } // Bracketed R references are relative to the current row - if ($rowReference{0} == '[') $rowReference = $rowID + trim($rowReference,'[]'); + if ($rowReference{0} == '[') { + $rowReference = $rowID + trim($rowReference,'[]'); + } $columnReference = $cellReference[4][0]; // Empty C reference is the current column - if ($columnReference == '') $columnReference = $columnNumber; + if ($columnReference == '') { + $columnReference = $columnNumber; + } // Bracketed C references are relative to the current column - if ($columnReference{0} == '[') $columnReference = $columnNumber + trim($columnReference,'[]'); + if ($columnReference{0} == '[') { + $columnReference = $columnNumber + trim($columnReference,'[]'); + } $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; - $value = substr_replace($value, $A1CellReference, $cellReference[0][1],strlen($cellReference[0][0])); + $value = substr_replace($value, $A1CellReference, $cellReference[0][1],strlen($cellReference[0][0])); } } } @@ -743,9 +749,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo $annotation,'<br />'; $annotation = strip_tags($node); // echo 'Annotation: ', $annotation,'<br />'; - $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) - ->setAuthor(self::_convertStringEncoding($author , $this->_charSet)) - ->setText($this->_parseRichText($annotation) ); + $objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setAuthor(self::_convertStringEncoding($author , $this->_charSet))->setText($this->_parseRichText($annotation) ); } if (($cellIsSet) && (isset($cell_ss['StyleID']))) { @@ -756,7 +760,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // print_r($this->_styles[$style]); // echo '<br />'; if (!$objPHPExcel->getActiveSheet()->cellExists($columnID.$rowID)) { - $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValue(NULL); + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValue(null); } $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->_styles[$style]); } @@ -790,20 +794,21 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } - protected static function _convertStringEncoding($string, $charset) { + protected static function _convertStringEncoding($string, $charset) + { if ($charset != 'UTF-8') { - return PHPExcel_Shared_String::ConvertEncoding($string,'UTF-8', $charset); + return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $charset); } return $string; } - protected function _parseRichText($is = '') { + protected function _parseRichText($is = '') + { $value = new PHPExcel_RichText(); $value->createText(self::_convertStringEncoding($is, $this->_charSet)); return $value; } - } diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 90c782f89..1442425ef 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -28,11 +28,11 @@ class PHPExcel_ReferenceHelper { /** Constants */ - /** Regular Expressions */ - const REFHELPER_REGEXP_CELLREF = '((\w*|\'[^!]*\')!)?(?<![:a-z\$])(\$?[a-z]{1,3}\$?\d+)(?=[^:!\d\'])'; + /** Regular Expressions */ + const REFHELPER_REGEXP_CELLREF = '((\w*|\'[^!]*\')!)?(?<![:a-z\$])(\$?[a-z]{1,3}\$?\d+)(?=[^:!\d\'])'; const REFHELPER_REGEXP_CELLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}\$?\d+):(\$?[a-z]{1,3}\$?\d+)'; - const REFHELPER_REGEXP_ROWRANGE = '((\w*|\'[^!]*\')!)?(\$?\d+):(\$?\d+)'; - const REFHELPER_REGEXP_COLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}):(\$?[a-z]{1,3})'; + const REFHELPER_REGEXP_ROWRANGE = '((\w*|\'[^!]*\')!)?(\$?\d+):(\$?\d+)'; + const REFHELPER_REGEXP_COLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}):(\$?[a-z]{1,3})'; /** * Instance of this class @@ -436,9 +436,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P $newCoordinates = PHPExcel_Cell::stringFromColumnIndex($cellIndex-1 + $pNumCols) . ($cell->getRow() + $pNumRows); // Should the cell be updated? Move value and cellXf index from one cell to another. - if (($cellIndex >= $beforeColumnIndex) && - ($cell->getRow() >= $beforeRow)) { - + if (($cellIndex >= $beforeColumnIndex) && ($cell->getRow() >= $beforeRow)) { // Update cell styles $pSheet->getCell($newCoordinates)->setXfIndex($cell->getXfIndex()); @@ -471,7 +469,6 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P if ($pNumCols > 0 && $beforeColumnIndex - 2 > 0) { for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) { - // Style $coordinate = PHPExcel_Cell::stringFromColumnIndex($beforeColumnIndex - 2) . $i; if ($pSheet->cellExists($coordinate)) { @@ -495,7 +492,6 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P if ($pNumRows > 0 && $beforeRow - 1 > 0) { for ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) { - // Style $coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . ($beforeRow - 1); if ($pSheet->cellExists($coordinate)) { @@ -547,7 +543,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P if ($pNumCols != 0) { $autoFilterColumns = array_keys($autoFilter->getColumns()); if (count($autoFilterColumns) > 0) { - sscanf($pBefore,'%[A-Z]%d', $column, $row); + sscanf($pBefore, '%[A-Z]%d', $column, $row); $columnIndex = PHPExcel_Cell::columnIndexFromString($column); list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($autoFilterRange); if ($columnIndex <= $rangeEnd[0]) { @@ -577,7 +573,7 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P $toColRef = $rangeEnd[0]+$pNumCols; do { - $autoFilter->shiftColumn(PHPExcel_Cell::stringFromColumnIndex($endColRef-1),PHPExcel_Cell::stringFromColumnIndex($toColRef-1)); + $autoFilter->shiftColumn(PHPExcel_Cell::stringFromColumnIndex($endColRef-1), PHPExcel_Cell::stringFromColumnIndex($toColRef-1)); --$endColRef; --$toColRef; } while ($startColRef <= $endColRef); @@ -661,12 +657,12 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo $modified4 = substr($this->updateCellReference('$A'.$match[4], $pBefore, $pNumCols, $pNumRows), 2); if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { - if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + if (($match[2] == '') || (trim($match[2], "'") == $sheetName)) { $toString = ($match[2] > '') ? $match[2].'!' : ''; $toString .= $modified3.':'.$modified4; // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more $column = 100000; - $row = 10000000+trim($match[3],'$'); + $row = 10000000 + trim($match[3],'$'); $cellIndex = $column.$row; $newCellTokens[$cellIndex] = preg_quote($toString); @@ -686,11 +682,11 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo $modified4 = substr($this->updateCellReference($match[4].'$1', $pBefore, $pNumCols, $pNumRows), 0, -2); if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { - if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + if (($match[2] == '') || (trim($match[2], "'") == $sheetName)) { $toString = ($match[2] > '') ? $match[2].'!' : ''; $toString .= $modified3.':'.$modified4; // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more - $column = PHPExcel_Cell::columnIndexFromString(trim($match[3],'$')) + 100000; + $column = PHPExcel_Cell::columnIndexFromString(trim($match[3], '$')) + 100000; $row = 10000000; $cellIndex = $column.$row; @@ -711,13 +707,13 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo $modified4 = $this->updateCellReference($match[4], $pBefore, $pNumCols, $pNumRows); if ($match[3].$match[4] !== $modified3.$modified4) { - if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + if (($match[2] == '') || (trim($match[2], "'") == $sheetName)) { $toString = ($match[2] > '') ? $match[2].'!' : ''; $toString .= $modified3.':'.$modified4; list($column, $row) = PHPExcel_Cell::coordinateFromString($match[3]); // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more - $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; - $row = trim($row,'$') + 10000000; + $column = PHPExcel_Cell::columnIndexFromString(trim($column, '$')) + 100000; + $row = trim($row, '$') + 10000000; $cellIndex = $column.$row; $newCellTokens[$cellIndex] = preg_quote($toString); @@ -737,13 +733,13 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo $modified3 = $this->updateCellReference($match[3], $pBefore, $pNumCols, $pNumRows); if ($match[3] !== $modified3) { - if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + if (($match[2] == '') || (trim($match[2], "'") == $sheetName)) { $toString = ($match[2] > '') ? $match[2].'!' : ''; $toString .= $modified3; list($column, $row) = PHPExcel_Cell::coordinateFromString($match[3]); // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more - $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; - $row = trim($row,'$') + 10000000; + $column = PHPExcel_Cell::columnIndexFromString(trim($column, '$')) + 100000; + $row = trim($row, '$') + 10000000; $cellIndex = $row . $column; $newCellTokens[$cellIndex] = preg_quote($toString); @@ -757,11 +753,11 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo if ($pNumCols > 0 || $pNumRows > 0) { krsort($cellTokens); krsort($newCellTokens); - } else { + } else { ksort($cellTokens); ksort($newCellTokens); } // Update cell references in the formula - $formulaBlock = str_replace('\\','',preg_replace($cellTokens, $newCellTokens, $formulaBlock)); + $formulaBlock = str_replace('\\', '', preg_replace($cellTokens, $newCellTokens, $formulaBlock)); } } } @@ -839,7 +835,7 @@ public function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName */ private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { - if (strpos($pCellRange,':') !== false || strpos($pCellRange, ',') !== false) { + if (strpos($pCellRange, ':') !== false || strpos($pCellRange, ',') !== false) { // Update range $range = PHPExcel_Cell::splitRange($pCellRange); $ic = count($range); diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 8e2a7d951..ebb32ec4f 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -196,7 +196,7 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable * * @var PHPExcel_Worksheet_AutoFilter */ - private $_autoFilter = NULL; + private $_autoFilter = null; /** * Freeze pane @@ -334,7 +334,7 @@ public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') { // Set parent and title $this->_parent = $pParent; - $this->setTitle($pTitle, FALSE); + $this->setTitle($pTitle, false); // setTitle can change $pTitle $this->setCodeName($this->getTitle()); $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE); @@ -363,12 +363,12 @@ public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') $this->_protection = new PHPExcel_Worksheet_Protection(); // Default row dimension - $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(NULL); + $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(null); // Default column dimension - $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(NULL); + $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(null); - $this->_autoFilter = new PHPExcel_Worksheet_AutoFilter(NULL, $this); + $this->_autoFilter = new PHPExcel_Worksheet_AutoFilter(null, $this); } @@ -377,10 +377,11 @@ public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') * typically so that the worksheet object can be unset * */ - public function disconnectCells() { - if ( $this->_cellCollection !== NULL) { + public function disconnectCells() + { + if ($this->_cellCollection !== null) { $this->_cellCollection->unsetWorksheetCells(); - $this->_cellCollection = NULL; + $this->_cellCollection = null; } // detach ourself from the workbook, so that it can then delete this worksheet successfully $this->_parent = null; @@ -390,9 +391,9 @@ public function disconnectCells() { * Code to execute when this worksheet is unset() * */ - function __destruct() { - PHPExcel_Calculation::getInstance($this->_parent) - ->clearCalculationCacheForWorksheet($this->_title); + function __destruct() + { + PHPExcel_Calculation::getInstance($this->_parent)->clearCalculationCacheForWorksheet($this->_title); $this->disconnectCells(); } @@ -402,7 +403,8 @@ function __destruct() { * * @return PHPExcel_CachedObjectStorage_xxx */ - public function getCellCacheController() { + public function getCellCacheController() + { return $this->_cellCollection; } // function getCellCacheController() @@ -431,17 +433,17 @@ private static function _checkSheetCodeName($pValue) throw new PHPExcel_Exception('Sheet code name cannot be empty.'); } // Some of the printable ASCII characters are invalid: * : / \ ? [ ] and first and last characters cannot be a "'" - if ((str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) || - (PHPExcel_Shared_String::Substring($pValue,-1,1)=='\'') || + if ((str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) || + (PHPExcel_Shared_String::Substring($pValue,-1,1)=='\'') || (PHPExcel_Shared_String::Substring($pValue,0,1)=='\'')) { throw new PHPExcel_Exception('Invalid character found in sheet code name'); } - + // Maximum 31 characters allowed for sheet title if ($CharCount > 31) { throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet code name.'); } - + return $pValue; } @@ -479,7 +481,7 @@ public function getCellCollection($pSorted = true) // Re-order cell collection return $this->sortCellCollection(); } - if ($this->_cellCollection !== NULL) { + if ($this->_cellCollection !== null) { return $this->_cellCollection->getCellList(); } return array(); @@ -492,7 +494,7 @@ public function getCellCollection($pSorted = true) */ public function sortCellCollection() { - if ($this->_cellCollection !== NULL) { + if ($this->_cellCollection !== null) { return $this->_cellCollection->getSortedCellList(); } return array(); @@ -725,7 +727,6 @@ public function calculateColumnWidths($calculateMergeCells = false) // There is only something to do if there are some auto-size columns if (!empty($autoSizes)) { - // build list of cells references that participate in a merge $isMergeCell = array(); foreach ($this->getMergeCells() as $cells) { @@ -762,7 +763,9 @@ public function calculateColumnWidths($calculateMergeCells = false) // adjust column widths foreach ($autoSizes as $columnIndex => $width) { - if ($width == -1) $width = $this->getDefaultColumnDimension()->getWidth(); + if ($width == -1) { + $width = $this->getDefaultColumnDimension()->getWidth(); + } $this->getColumnDimension($columnIndex)->setWidth($width); } } @@ -775,7 +778,8 @@ public function calculateColumnWidths($calculateMergeCells = false) * * @return PHPExcel */ - public function getParent() { + public function getParent() + { return $this->_parent; } @@ -785,7 +789,8 @@ public function getParent() { * @param PHPExcel $parent * @return PHPExcel_Worksheet */ - public function rebindParent(PHPExcel $parent) { + public function rebindParent(PHPExcel $parent) + { if ($this->_parent !== null) { $namedRanges = $this->_parent->getNamedRanges(); foreach ($namedRanges as $namedRange) { @@ -841,18 +846,18 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t // Use name, but append with lowest possible integer if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); + $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 29); } $i = 1; while ($this->_parent->sheetNameExists($pValue . ' ' . $i)) { ++$i; if ($i == 10) { if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); + $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 28); } } elseif ($i == 100) { if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); + $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 27); } } } @@ -871,8 +876,9 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t $newTitle = $this->getTitle(); PHPExcel_Calculation::getInstance($this->_parent) ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); - if ($updateFormulaCellReferences) + if ($updateFormulaCellReferences) { PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_parent, $oldTitle, $newTitle); + } } return $this; @@ -883,7 +889,8 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t * * @return string Sheet state (visible, hidden, veryHidden) */ - public function getSheetState() { + public function getSheetState() + { return $this->_sheetState; } @@ -893,7 +900,8 @@ public function getSheetState() { * @param string $value Sheet state (visible, hidden, veryHidden) * @return PHPExcel_Worksheet */ - public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) { + public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) + { $this->_sheetState = $value; return $this; } @@ -1159,7 +1167,7 @@ public function getCell($pCoordinate = 'A1') if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) && (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) { $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); - if ($namedRange !== NULL) { + if ($namedRange !== null) { $pCoordinate = $namedRange->getRange(); return $namedRange->getWorksheet()->getCell($pCoordinate); } @@ -1207,36 +1215,33 @@ private function _createNewCell($pCoordinate) { $cell = $this->_cellCollection->addCacheData( $pCoordinate, - new PHPExcel_Cell( - NULL, - PHPExcel_Cell_DataType::TYPE_NULL, - $this - ) + new PHPExcel_Cell(null, PHPExcel_Cell_DataType::TYPE_NULL, $this) ); $this->_cellCollectionIsSorted = false; // Coordinates $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); - if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) + if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) { $this->_cachedHighestColumn = $aCoordinates[0]; + } $this->_cachedHighestRow = max($this->_cachedHighestRow, $aCoordinates[1]); // Cell needs appropriate xfIndex from dimensions records // but don't create dimension records if they don't already exist - $rowDimension = $this->getRowDimension($aCoordinates[1], FALSE); - $columnDimension = $this->getColumnDimension($aCoordinates[0], FALSE); + $rowDimension = $this->getRowDimension($aCoordinates[1], false); + $columnDimension = $this->getColumnDimension($aCoordinates[0], false); - if ($rowDimension !== NULL && $rowDimension->getXfIndex() > 0) { + if ($rowDimension !== null && $rowDimension->getXfIndex() > 0) { // then there is a row dimension with explicit style, assign it to the cell $cell->setXfIndex($rowDimension->getXfIndex()); - } elseif ($columnDimension !== NULL && $columnDimension->getXfIndex() > 0) { + } elseif ($columnDimension !== null && $columnDimension->getXfIndex() > 0) { // then there is a column dimension, assign it to the cell $cell->setXfIndex($columnDimension->getXfIndex()); } return $cell; } - + /** * Does the cell at a specific coordinate exist? * @@ -1256,7 +1261,7 @@ public function cellExists($pCoordinate = 'A1') if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) && (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) { $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); - if ($namedRange !== NULL) { + if ($namedRange !== null) { $pCoordinate = $namedRange->getRange(); if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) { if (!$namedRange->getLocalOnly()) { @@ -1265,16 +1270,17 @@ public function cellExists($pCoordinate = 'A1') throw new PHPExcel_Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle()); } } + } else { + return false; } - else { return false; } } // Uppercase coordinate $pCoordinate = strtoupper($pCoordinate); - if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { + if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) { throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.'); - } elseif (strpos($pCoordinate,'$') !== false) { + } elseif (strpos($pCoordinate, '$') !== false) { throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); } else { // Coordinates @@ -1303,15 +1309,16 @@ public function cellExistsByColumnAndRow($pColumn = 0, $pRow = 1) * @param int $pRow Numeric index of the row * @return PHPExcel_Worksheet_RowDimension */ - public function getRowDimension($pRow = 1, $create = TRUE) + public function getRowDimension($pRow = 1, $create = true) { // Found $found = null; // Get row dimension if (!isset($this->_rowDimensions[$pRow])) { - if (!$create) - return NULL; + if (!$create) { + return null; + } $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow); $this->_cachedHighestRow = max($this->_cachedHighestRow, $pRow); @@ -1325,19 +1332,21 @@ public function getRowDimension($pRow = 1, $create = TRUE) * @param string $pColumn String index of the column * @return PHPExcel_Worksheet_ColumnDimension */ - public function getColumnDimension($pColumn = 'A', $create = TRUE) + public function getColumnDimension($pColumn = 'A', $create = true) { // Uppercase coordinate $pColumn = strtoupper($pColumn); // Fetch dimensions if (!isset($this->_columnDimensions[$pColumn])) { - if (!$create) - return NULL; + if (!$create) { + return null; + } $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn); - if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) + if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) { $this->_cachedHighestColumn = $pColumn; + } } return $this->_columnDimensions[$pColumn]; } @@ -1488,8 +1497,7 @@ public function setConditionalStyles($pCoordinate = 'A1', $pValue) public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1, $pColumn2 = null, $pRow2 = null) { if (!is_null($pColumn2) && !is_null($pRow2)) { - $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow . ':' . - PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; return $this->getStyle($cellRange); } @@ -1680,7 +1688,7 @@ public function mergeCells($pRange = 'A1:A1') // Uppercase coordinate $pRange = strtoupper($pRange); - if (strpos($pRange,':') !== false) { + if (strpos($pRange, ':') !== false) { $this->_mergeCells[$pRange] = $pRange; // make sure cells are created @@ -1699,7 +1707,6 @@ public function mergeCells($pRange = 'A1:A1') for ($i = 1; $i < $count; $i++) { $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); } - } else { throw new PHPExcel_Exception('Merge must be set on a range of cells.'); } @@ -1735,7 +1742,7 @@ public function unmergeCells($pRange = 'A1:A1') // Uppercase coordinate $pRange = strtoupper($pRange); - if (strpos($pRange,':') !== false) { + if (strpos($pRange, ':') !== false) { if (isset($this->_mergeCells[$pRange])) { unset($this->_mergeCells[$pRange]); } else { @@ -1783,7 +1790,6 @@ public function getMergeCells() public function setMergeCells($pValue = array()) { $this->_mergeCells = $pValue; - return $this; } @@ -1896,7 +1902,6 @@ public function getAutoFilter() public function setAutoFilter($pValue) { $pRange = strtoupper($pValue); - if (is_string($pValue)) { $this->_autoFilter->setRange($pValue); } elseif (is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) { @@ -1931,7 +1936,7 @@ public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 */ public function removeAutoFilter() { - $this->_autoFilter->setRange(NULL); + $this->_autoFilter->setRange(null); return $this; } @@ -1961,8 +1966,7 @@ public function freezePane($pCell = '') { // Uppercase coordinate $pCell = strtoupper($pCell); - - if (strpos($pCell,':') === false && strpos($pCell,',') === false) { + if (strpos($pCell, ':') === false && strpos($pCell, ',') === false) { $this->_freezePane = $pCell; } else { throw new PHPExcel_Exception('Freeze pane can not be set on a range of cells.'); @@ -2001,7 +2005,8 @@ public function unfreezePane() * @throws PHPExcel_Exception * @return PHPExcel_Worksheet */ - public function insertNewRowBefore($pBefore = 1, $pNumRows = 1) { + public function insertNewRowBefore($pBefore = 1, $pNumRows = 1) + { if ($pBefore >= 1) { $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); $objReferenceHelper->insertNewBefore('A' . $pBefore, 0, $pNumRows, $this); @@ -2019,7 +2024,8 @@ public function insertNewRowBefore($pBefore = 1, $pNumRows = 1) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet */ - public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1) { + public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1) + { if (!is_numeric($pBefore)) { $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); $objReferenceHelper->insertNewBefore($pBefore . '1', $pNumCols, 0, $this); @@ -2037,7 +2043,8 @@ public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet */ - public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) { + public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) + { if ($pBefore >= 0) { return $this->insertNewColumnBefore(PHPExcel_Cell::stringFromColumnIndex($pBefore), $pNumCols); } else { @@ -2053,7 +2060,8 @@ public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet */ - public function removeRow($pRow = 1, $pNumRows = 1) { + public function removeRow($pRow = 1, $pNumRows = 1) + { if ($pRow >= 1) { $highestRow = $this->getHighestDataRow(); $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); @@ -2076,7 +2084,8 @@ public function removeRow($pRow = 1, $pNumRows = 1) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet */ - public function removeColumn($pColumn = 'A', $pNumCols = 1) { + public function removeColumn($pColumn = 'A', $pNumCols = 1) + { if (!is_numeric($pColumn)) { $highestColumn = $this->getHighestDataColumn(); $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols); @@ -2100,7 +2109,8 @@ public function removeColumn($pColumn = 'A', $pNumCols = 1) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet */ - public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) { + public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) + { if ($pColumn >= 0) { return $this->removeColumn(PHPExcel_Cell::stringFromColumnIndex($pColumn), $pNumCols); } else { @@ -2113,7 +2123,8 @@ public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) { * * @return boolean */ - public function getShowGridlines() { + public function getShowGridlines() + { return $this->_showGridlines; } @@ -2123,7 +2134,8 @@ public function getShowGridlines() { * @param boolean $pValue Show gridlines (true/false) * @return PHPExcel_Worksheet */ - public function setShowGridlines($pValue = false) { + public function setShowGridlines($pValue = false) + { $this->_showGridlines = $pValue; return $this; } @@ -2133,7 +2145,8 @@ public function setShowGridlines($pValue = false) { * * @return boolean */ - public function getPrintGridlines() { + public function getPrintGridlines() + { return $this->_printGridlines; } @@ -2143,7 +2156,8 @@ public function getPrintGridlines() { * @param boolean $pValue Print gridlines (true/false) * @return PHPExcel_Worksheet */ - public function setPrintGridlines($pValue = false) { + public function setPrintGridlines($pValue = false) + { $this->_printGridlines = $pValue; return $this; } @@ -2153,7 +2167,8 @@ public function setPrintGridlines($pValue = false) { * * @return boolean */ - public function getShowRowColHeaders() { + public function getShowRowColHeaders() + { return $this->_showRowColHeaders; } @@ -2163,7 +2178,8 @@ public function getShowRowColHeaders() { * @param boolean $pValue Show row and column headers (true/false) * @return PHPExcel_Worksheet */ - public function setShowRowColHeaders($pValue = false) { + public function setShowRowColHeaders($pValue = false) + { $this->_showRowColHeaders = $pValue; return $this; } @@ -2173,7 +2189,8 @@ public function setShowRowColHeaders($pValue = false) { * * @return boolean */ - public function getShowSummaryBelow() { + public function getShowSummaryBelow() + { return $this->_showSummaryBelow; } @@ -2183,7 +2200,8 @@ public function getShowSummaryBelow() { * @param boolean $pValue Show summary below (true/false) * @return PHPExcel_Worksheet */ - public function setShowSummaryBelow($pValue = true) { + public function setShowSummaryBelow($pValue = true) + { $this->_showSummaryBelow = $pValue; return $this; } @@ -2193,7 +2211,8 @@ public function setShowSummaryBelow($pValue = true) { * * @return boolean */ - public function getShowSummaryRight() { + public function getShowSummaryRight() + { return $this->_showSummaryRight; } @@ -2203,7 +2222,8 @@ public function getShowSummaryRight() { * @param boolean $pValue Show summary right (true/false) * @return PHPExcel_Worksheet */ - public function setShowSummaryRight($pValue = true) { + public function setShowSummaryRight($pValue = true) + { $this->_showSummaryRight = $pValue; return $this; } @@ -2243,9 +2263,9 @@ public function getComment($pCellCoordinate = 'A1') // Uppercase coordinate $pCellCoordinate = strtoupper($pCellCoordinate); - if (strpos($pCellCoordinate,':') !== false || strpos($pCellCoordinate,',') !== false) { + if (strpos($pCellCoordinate, ':') !== false || strpos($pCellCoordinate, ',') !== false) { throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells.'); - } else if (strpos($pCellCoordinate,'$') !== false) { + } else if (strpos($pCellCoordinate, '$') !== false) { throw new PHPExcel_Exception('Cell coordinate string must not be absolute.'); } else if ($pCellCoordinate == '') { throw new PHPExcel_Exception('Cell coordinate can not be zero-length string.'); @@ -2340,7 +2360,7 @@ public function setSelectedCells($pCoordinate = 'A1') // Convert '1:3' to 'A1:XFD3' $pCoordinate = preg_replace('/^([0-9]+):([0-9]+)$/', 'A${1}:XFD${2}', $pCoordinate); - if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { + if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) { list($first, ) = PHPExcel_Cell::splitRange($pCoordinate); $this->_activeCell = $first[0]; } else { @@ -2368,7 +2388,8 @@ public function setSelectedCellByColumnAndRow($pColumn = 0, $pRow = 1) * * @return boolean */ - public function getRightToLeft() { + public function getRightToLeft() + { return $this->_rightToLeft; } @@ -2378,7 +2399,8 @@ public function getRightToLeft() { * @param boolean $value Right-to-left true/false * @return PHPExcel_Worksheet */ - public function setRightToLeft($value = false) { + public function setRightToLeft($value = false) + { $this->_rightToLeft = $value; return $this; } @@ -2393,7 +2415,8 @@ public function setRightToLeft($value = false) { * @throws PHPExcel_Exception * @return PHPExcel_Worksheet */ - public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false) { + public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false) + { if (is_array($source)) { // Convert a 1-D array to 2-D (for ease of looping) if (!is_array(end($source))) { @@ -2439,7 +2462,8 @@ public function fromArray($source = null, $nullValue = null, $startCell = 'A1', * True - Return rows and columns indexed by their actual row and column IDs * @return array */ - public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) + { // Returnvalue $returnValue = array(); // Identify the range that we need to extract from the worksheet @@ -2511,14 +2535,14 @@ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormul * @return array * @throws PHPExcel_Exception */ - public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) + { $namedRange = PHPExcel_NamedRange::resolveRange($pNamedRange, $this); - if ($namedRange !== NULL) { + if ($namedRange !== null) { $pWorkSheet = $namedRange->getWorksheet(); $pCellRange = $namedRange->getRange(); - return $pWorkSheet->rangeToArray( $pCellRange, - $nullValue, $calculateFormulas, $formatData, $returnCellRef); + return $pWorkSheet->rangeToArray($pCellRange, $nullValue, $calculateFormulas, $formatData, $returnCellRef); } throw new PHPExcel_Exception('Named Range '.$pNamedRange.' does not exist.'); @@ -2535,7 +2559,8 @@ public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calcula * True - Return rows and columns indexed by their actual row and column IDs * @return array */ - public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) + { // Garbage collect... $this->garbageCollect(); @@ -2543,8 +2568,7 @@ public function toArray($nullValue = null, $calculateFormulas = true, $formatDat $maxCol = $this->getHighestColumn(); $maxRow = $this->getHighestRow(); // Return - return $this->rangeToArray( 'A1:'.$maxCol.$maxRow, - $nullValue, $calculateFormulas, $formatData, $returnCellRef); + return $this->rangeToArray('A1:'.$maxCol.$maxRow, $nullValue, $calculateFormulas, $formatData, $returnCellRef); } /** @@ -2555,7 +2579,8 @@ public function toArray($nullValue = null, $calculateFormulas = true, $formatDat * * @return PHPExcel_Worksheet_RowIterator */ - public function getRowIterator($startRow = 1, $endRow = null) { + public function getRowIterator($startRow = 1, $endRow = null) + { return new PHPExcel_Worksheet_RowIterator($this, $startRow, $endRow); } @@ -2567,7 +2592,8 @@ public function getRowIterator($startRow = 1, $endRow = null) { * * @return PHPExcel_Worksheet_ColumnIterator */ - public function getColumnIterator($startColumn = 'A', $endColumn = null) { + public function getColumnIterator($startColumn = 'A', $endColumn = null) + { return new PHPExcel_Worksheet_ColumnIterator($this, $startColumn, $endColumn); } @@ -2576,7 +2602,8 @@ public function getColumnIterator($startColumn = 'A', $endColumn = null) { * * @return PHPExcel_Worksheet */ - public function garbageCollect() { + public function garbageCollect() + { // Flush cache $this->_cellCollection->getCacheData('A1'); // Build a reference table from images @@ -2620,13 +2647,10 @@ public function garbageCollect() { * * @return string Hash code */ - public function getHashCode() { + public function getHashCode() + { if ($this->_dirty) { - $this->_hash = md5( $this->_title . - $this->_autoFilter . - ($this->_protection->isProtectionEnabled() ? 't' : 'f') . - __CLASS__ - ); + $this->_hash = md5($this->_title . $this->_autoFilter . ($this->_protection->isProtectionEnabled() ? 't' : 'f') . __CLASS__); $this->_dirty = false; } return $this->_hash; @@ -2642,17 +2666,15 @@ public function getHashCode() { * @param bool $returnRange Return range? (see example) * @return mixed */ - public static function extractSheetTitle($pRange, $returnRange = false) { + public static function extractSheetTitle($pRange, $returnRange = false) + { // Sheet title included? if (($sep = strpos($pRange, '!')) === false) { return ''; } if ($returnRange) { - return array( - trim(substr($pRange, 0, $sep),"'"), - substr($pRange, $sep + 1) - ); + return array(trim(substr($pRange, 0, $sep),"'"), substr($pRange, $sep + 1)); } return substr($pRange, $sep + 1); @@ -2774,7 +2796,8 @@ public function getDataValidationCollection() * @param string $range * @return string Adjusted range value */ - public function shrinkRangeToFit($range) { + public function shrinkRangeToFit($range) + { $maxCol = $this->getHighestColumn(); $maxRow = $this->getHighestRow(); $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol); @@ -2783,10 +2806,18 @@ public function shrinkRangeToFit($range) { foreach ($rangeBlocks as &$rangeSet) { $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($rangeSet); - if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) { $rangeBoundaries[0][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); } - if ($rangeBoundaries[0][1] > $maxRow) { $rangeBoundaries[0][1] = $maxRow; } - if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) { $rangeBoundaries[1][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); } - if ($rangeBoundaries[1][1] > $maxRow) { $rangeBoundaries[1][1] = $maxRow; } + if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) { + $rangeBoundaries[0][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); + } + if ($rangeBoundaries[0][1] > $maxRow) { + $rangeBoundaries[0][1] = $maxRow; + } + if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) { + $rangeBoundaries[1][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); + } + if ($rangeBoundaries[1][1] > $maxRow) { + $rangeBoundaries[1][1] = $maxRow; + } $rangeSet = $rangeBoundaries[0][0].$rangeBoundaries[0][1].':'.$rangeBoundaries[1][0].$rangeBoundaries[1][1]; } unset($rangeSet); @@ -2802,7 +2833,7 @@ public function shrinkRangeToFit($range) { */ public function getTabColor() { - if ($this->_tabColor === NULL) + if ($this->_tabColor === null) $this->_tabColor = new PHPExcel_Style_Color(); return $this->_tabColor; @@ -2828,7 +2859,7 @@ public function resetTabColor() */ public function isTabColorSet() { - return ($this->_tabColor !== NULL); + return ($this->_tabColor !== null); } /** @@ -2845,7 +2876,8 @@ public function copy() { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { foreach ($this as $key => $val) { if ($key == '_parent') { continue; @@ -2876,7 +2908,8 @@ public function __clone() { * @return objWorksheet * @throws PHPExcel_Exception */ - public function setCodeName($pValue=null) { + public function setCodeName($pValue=null) + { // Is this a 'rename' or not? if ($this->getCodeName() == $pValue) { return $this; @@ -2887,7 +2920,7 @@ public function setCodeName($pValue=null) { self::_checkSheetCodeName($pValue); // We use the same code that setTitle to find a valid codeName else not using a space (Excel don't like) but a '_' - + if ($this->getParent()) { // Is there already such sheet name? if ($this->getParent()->sheetCodeNameExists($pValue)) { @@ -2924,14 +2957,16 @@ public function setCodeName($pValue=null) { * * @return null|string */ - public function getCodeName() { + public function getCodeName() + { return $this->_codeName; } /** * Sheet has a code name ? * @return boolean */ - public function hasCodeName() { + public function hasCodeName() + { return !(is_null($this->_codeName)); } } From f827a25af28e97f5c9b9f5c0312391025d16e99d Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sat, 16 May 2015 19:00:31 +0200 Subject: [PATCH 376/467] PSR2 Fixes --- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 9519 ++++++++--------- Classes/PHPExcel/Shared/PasswordHasher.php | 5 +- Classes/PHPExcel/Shared/String.php | 58 +- Classes/PHPExcel/Shared/TimeZone.php | 15 +- Classes/PHPExcel/Shared/XMLWriter.php | 23 +- Classes/PHPExcel/Shared/ZipArchive.php | 5 +- Classes/PHPExcel/Shared/ZipStreamWrapper.php | 5 +- .../PHPExcel/Shared/trend/bestFitClass.php | 104 +- .../Shared/trend/exponentialBestFitClass.php | 33 +- .../Shared/trend/linearBestFitClass.php | 26 +- .../Shared/trend/logarithmicBestFitClass.php | 27 +- .../Shared/trend/polynomialBestFitClass.php | 29 +- .../Shared/trend/powerBestFitClass.php | 27 +- Classes/PHPExcel/Shared/trend/trendClass.php | 34 +- Classes/PHPExcel/Worksheet.php | 31 +- Classes/PHPExcel/Worksheet/AutoFilter.php | 142 +- Classes/PHPExcel/Worksheet/PageSetup.php | 3 +- 17 files changed, 4828 insertions(+), 5258 deletions(-) diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index 0805a03c7..9fd7b3456 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -7,188 +7,188 @@ // -------------------------------------------------------------------------------- // // Presentation : -// PclZip is a PHP library that manage ZIP archives. -// So far tests show that archives generated by PclZip are readable by -// WinZip application and other tools. +// PclZip is a PHP library that manage ZIP archives. +// So far tests show that archives generated by PclZip are readable by +// WinZip application and other tools. // // Description : -// See readme.txt and http://www.phpconcept.net +// See readme.txt and http://www.phpconcept.net // // Warning : -// This library and the associated files are non commercial, non professional -// work. -// It should not have unexpected results. However if any damage is caused by -// this software the author can not be responsible. -// The use of this software is at the risk of the user. +// This library and the associated files are non commercial, non professional +// work. +// It should not have unexpected results. However if any damage is caused by +// this software the author can not be responsible. +// The use of this software is at the risk of the user. // // -------------------------------------------------------------------------------- // $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $ // -------------------------------------------------------------------------------- - // ----- Constants - if (!defined('PCLZIP_READ_BLOCK_SIZE')) { - define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); - } - - // ----- File list separator - // In version 1.x of PclZip, the separator for file list is a space - // (which is not a very smart choice, specifically for windows paths !). - // A better separator should be a comma (,). This constant gives you the - // abilty to change that. - // However notice that changing this value, may have impact on existing - // scripts, using space separated filenames. - // Recommanded values for compatibility with older versions : - //define( 'PCLZIP_SEPARATOR', ' ' ); - // Recommanded values for smart separation of filenames. - if (!defined('PCLZIP_SEPARATOR')) { +// ----- Constants +if (!defined('PCLZIP_READ_BLOCK_SIZE')) { + define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); +} + +// ----- File list separator +// In version 1.x of PclZip, the separator for file list is a space +// (which is not a very smart choice, specifically for windows paths !). +// A better separator should be a comma (,). This constant gives you the +// abilty to change that. +// However notice that changing this value, may have impact on existing +// scripts, using space separated filenames. +// Recommanded values for compatibility with older versions : +//define( 'PCLZIP_SEPARATOR', ' ' ); +// Recommanded values for smart separation of filenames. +if (!defined('PCLZIP_SEPARATOR')) { define( 'PCLZIP_SEPARATOR', ',' ); - } - - // ----- Error configuration - // 0 : PclZip Class integrated error handling - // 1 : PclError external library error handling. By enabling this - // you must ensure that you have included PclError library. - // [2,...] : reserved for futur use - if (!defined('PCLZIP_ERROR_EXTERNAL')) { +} + +// ----- Error configuration +// 0 : PclZip Class integrated error handling +// 1 : PclError external library error handling. By enabling this +// you must ensure that you have included PclError library. +// [2,...] : reserved for futur use +if (!defined('PCLZIP_ERROR_EXTERNAL')) { define( 'PCLZIP_ERROR_EXTERNAL', 0 ); - } - - // ----- Optional static temporary directory - // By default temporary files are generated in the script current - // path. - // If defined : - // - MUST BE terminated by a '/'. - // - MUST be a valid, already created directory - // Samples : - // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); - // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); - if (!defined('PCLZIP_TEMPORARY_DIR')) { +} + +// ----- Optional static temporary directory +// By default temporary files are generated in the script current +// path. +// If defined : +// - MUST BE terminated by a '/'. +// - MUST be a valid, already created directory +// Samples : +// define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); +// define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); +if (!defined('PCLZIP_TEMPORARY_DIR')) { define( 'PCLZIP_TEMPORARY_DIR', '' ); - } - - // ----- Optional threshold ratio for use of temporary files - // Pclzip sense the size of the file to add/extract and decide to - // use or not temporary file. The algorythm is looking for - // memory_limit of PHP and apply a ratio. - // threshold = memory_limit * ratio. - // Recommended values are under 0.5. Default 0.47. - // Samples : - // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 ); - if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { +} + +// ----- Optional threshold ratio for use of temporary files +// Pclzip sense the size of the file to add/extract and decide to +// use or not temporary file. The algorythm is looking for +// memory_limit of PHP and apply a ratio. +// threshold = memory_limit * ratio. +// Recommended values are under 0.5. Default 0.47. +// Samples : +// define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 ); +if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 ); - } +} // -------------------------------------------------------------------------------- // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** // -------------------------------------------------------------------------------- - // ----- Global variables - $g_pclzip_version = "2.8.2"; - - // ----- Error codes - // -1 : Unable to open file in binary write mode - // -2 : Unable to open file in binary read mode - // -3 : Invalid parameters - // -4 : File does not exist - // -5 : Filename is too long (max. 255) - // -6 : Not a valid zip file - // -7 : Invalid extracted file size - // -8 : Unable to create directory - // -9 : Invalid archive extension - // -10 : Invalid archive format - // -11 : Unable to delete file (unlink) - // -12 : Unable to rename file (rename) - // -13 : Invalid header checksum - // -14 : Invalid archive size - define( 'PCLZIP_ERR_USER_ABORTED', 2 ); - define( 'PCLZIP_ERR_NO_ERROR', 0 ); - define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); - define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); - define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); - define( 'PCLZIP_ERR_MISSING_FILE', -4 ); - define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); - define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); - define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); - define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); - define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); - define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); - define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); - define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); - define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); - define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); - define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); - define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); - define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); - define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); - define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); - define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); - define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); - - // ----- Options values - define( 'PCLZIP_OPT_PATH', 77001 ); - define( 'PCLZIP_OPT_ADD_PATH', 77002 ); - define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); - define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); - define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); - define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); - define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); - define( 'PCLZIP_OPT_BY_NAME', 77008 ); - define( 'PCLZIP_OPT_BY_INDEX', 77009 ); - define( 'PCLZIP_OPT_BY_EREG', 77010 ); - define( 'PCLZIP_OPT_BY_PREG', 77011 ); - define( 'PCLZIP_OPT_COMMENT', 77012 ); - define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); - define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); - define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); - define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); - define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); - // Having big trouble with crypt. Need to multiply 2 long int - // which is not correctly supported by PHP ... - //define( 'PCLZIP_OPT_CRYPT', 77018 ); - define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); - define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 ); - define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias - define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 ); - define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias - define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 ); - define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias - - // ----- File description attributes - define( 'PCLZIP_ATT_FILE_NAME', 79001 ); - define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); - define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); - define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); - define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); - define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); - - // ----- Call backs values - define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); - define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); - define( 'PCLZIP_CB_PRE_ADD', 78003 ); - define( 'PCLZIP_CB_POST_ADD', 78004 ); - /* For futur use - define( 'PCLZIP_CB_PRE_LIST', 78005 ); - define( 'PCLZIP_CB_POST_LIST', 78006 ); - define( 'PCLZIP_CB_PRE_DELETE', 78007 ); - define( 'PCLZIP_CB_POST_DELETE', 78008 ); - */ - - // -------------------------------------------------------------------------------- - // Class : PclZip - // Description : - // PclZip is the class that represent a Zip archive. - // The public methods allow the manipulation of the archive. - // Attributes : - // Attributes must not be accessed directly. - // Methods : - // PclZip() : Object creator - // create() : Creates the Zip archive - // listContent() : List the content of the Zip archive - // extract() : Extract the content of the archive - // properties() : List the properties of the archive - // -------------------------------------------------------------------------------- - class PclZip - { +// ----- Global variables +$g_pclzip_version = "2.8.2"; + +// ----- Error codes +// -1 : Unable to open file in binary write mode +// -2 : Unable to open file in binary read mode +// -3 : Invalid parameters +// -4 : File does not exist +// -5 : Filename is too long (max. 255) +// -6 : Not a valid zip file +// -7 : Invalid extracted file size +// -8 : Unable to create directory +// -9 : Invalid archive extension +// -10 : Invalid archive format +// -11 : Unable to delete file (unlink) +// -12 : Unable to rename file (rename) +// -13 : Invalid header checksum +// -14 : Invalid archive size +define( 'PCLZIP_ERR_USER_ABORTED', 2 ); +define( 'PCLZIP_ERR_NO_ERROR', 0 ); +define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); +define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); +define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); +define( 'PCLZIP_ERR_MISSING_FILE', -4 ); +define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); +define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); +define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); +define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); +define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); +define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); +define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); +define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); +define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); +define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); +define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); +define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); +define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); +define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); +define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); +define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); +define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); + +// ----- Options values +define( 'PCLZIP_OPT_PATH', 77001 ); +define( 'PCLZIP_OPT_ADD_PATH', 77002 ); +define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); +define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); +define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); +define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); +define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); +define( 'PCLZIP_OPT_BY_NAME', 77008 ); +define( 'PCLZIP_OPT_BY_INDEX', 77009 ); +define( 'PCLZIP_OPT_BY_EREG', 77010 ); +define( 'PCLZIP_OPT_BY_PREG', 77011 ); +define( 'PCLZIP_OPT_COMMENT', 77012 ); +define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); +define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); +define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); +define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); +define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); +// Having big trouble with crypt. Need to multiply 2 long int +// which is not correctly supported by PHP ... +//define( 'PCLZIP_OPT_CRYPT', 77018 ); +define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); +define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 ); +define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias +define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 ); +define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias +define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 ); +define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias + +// ----- File description attributes +define( 'PCLZIP_ATT_FILE_NAME', 79001 ); +define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); +define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); +define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); +define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); +define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); + +// ----- Call backs values +define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); +define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); +define( 'PCLZIP_CB_PRE_ADD', 78003 ); +define( 'PCLZIP_CB_POST_ADD', 78004 ); +/* For futur use +define( 'PCLZIP_CB_PRE_LIST', 78005 ); +define( 'PCLZIP_CB_POST_LIST', 78006 ); +define( 'PCLZIP_CB_PRE_DELETE', 78007 ); +define( 'PCLZIP_CB_POST_DELETE', 78008 ); +*/ + +// -------------------------------------------------------------------------------- +// Class : PclZip +// Description : +// PclZip is the class that represent a Zip archive. +// The public methods allow the manipulation of the archive. +// Attributes : +// Attributes must not be accessed directly. +// Methods : +// PclZip() : Object creator +// create() : Creates the Zip archive +// listContent() : List the content of the Zip archive +// extract() : Extract the content of the archive +// properties() : List the properties of the archive +// -------------------------------------------------------------------------------- +class PclZip +{ // ----- Filename of the zip file var $zipname = ''; @@ -198,5294 +198,4842 @@ class PclZip // ----- Internal error handling var $error_code = 1; var $error_string = ''; - + // ----- Current status of the magic_quotes_runtime // This value store the php configuration for magic_quotes // The class can then disable the magic_quotes and reset it after var $magic_quotes_status; - // -------------------------------------------------------------------------------- - // Function : PclZip() - // Description : - // Creates a PclZip object and set the name of the associated Zip archive - // filename. - // Note that no real action is taken, if the archive does not exist it is not - // created. Use create() for that. - // -------------------------------------------------------------------------------- - function PclZip($p_zipname) - { - - // ----- Tests the zlib - if (!function_exists('gzopen')) + // -------------------------------------------------------------------------------- + // Function : PclZip() + // Description : + // Creates a PclZip object and set the name of the associated Zip archive + // filename. + // Note that no real action is taken, if the archive does not exist it is not + // created. Use create() for that. + // -------------------------------------------------------------------------------- + function PclZip($p_zipname) { - die('Abort '.basename(__FILE__).' : Missing zlib extensions'); - } - // ----- Set the attributes - $this->zipname = $p_zipname; - $this->zip_fd = 0; - $this->magic_quotes_status = -1; + // ----- Tests the zlib + if (!function_exists('gzopen')) { + die('Abort '.basename(__FILE__).' : Missing zlib extensions'); + } - // ----- Return - return; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // create($p_filelist, $p_add_dir="", $p_remove_dir="") - // create($p_filelist, $p_option, $p_option_value, ...) - // Description : - // This method supports two different synopsis. The first one is historical. - // This method creates a Zip Archive. The Zip file is created in the - // filesystem. The files and directories indicated in $p_filelist - // are added in the archive. See the parameters description for the - // supported format of $p_filelist. - // When a directory is in the list, the directory and its content is added - // in the archive. - // In this synopsis, the function takes an optional variable list of - // options. See bellow the supported options. - // Parameters : - // $p_filelist : An array containing file or directory names, or - // a string containing one filename or one directory name, or - // a string containing a list of filenames and/or directory - // names separated by spaces. - // $p_add_dir : A path to add before the real path of the archived file, - // in order to have it memorized in the archive. - // $p_remove_dir : A path to remove from the real path of the file to archive, - // in order to have a shorter path memorized in the archive. - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir - // is removed first, before $p_add_dir is added. - // Options : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_COMMENT : - // PCLZIP_CB_PRE_ADD : - // PCLZIP_CB_POST_ADD : - // Return Values : - // 0 on failure, - // The list of the added files, with a status of the add action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function create($p_filelist) - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Set default values - $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove from the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - //, PCLZIP_OPT_CRYPT => 'optional' - )); - if ($v_result != 1) { - return 0; + // ----- Set the attributes + $this->zipname = $p_zipname; + $this->zip_fd = 0; + $this->magic_quotes_status = -1; + + // ----- Return + return; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // create($p_filelist, $p_add_dir="", $p_remove_dir="") + // create($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two different synopsis. The first one is historical. + // This method creates a Zip Archive. The Zip file is created in the + // filesystem. The files and directories indicated in $p_filelist + // are added in the archive. See the parameters description for the + // supported format of $p_filelist. + // When a directory is in the list, the directory and its content is added + // in the archive. + // In this synopsis, the function takes an optional variable list of + // options. See bellow the supported options. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function create($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove from the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array ( + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } else { + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } else if ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Invalid number / type of arguments"); + return 0; + } + } } - } - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } else { + // ----- The list is a list of string names + $v_string_list = $p_filelist; + } + } else if (is_string($p_filelist)) { + // ----- Look if the $p_filelist is a string + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } else { + // ----- Invalid variable type for $p_filelist + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + return 0; + } - // ----- Get the first argument - $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } else { + } + } + } - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + // ----- For each file in the list check the attributes + $v_supported_attributes = array( + PCLZIP_ATT_FILE_NAME => 'mandatory', + PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional', + PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional', + PCLZIP_ATT_FILE_MTIME => 'optional', + PCLZIP_ATT_FILE_CONTENT => 'optional', + PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes); + if ($v_result != 1) { + return 0; + } } - else if ($v_size > 2) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Invalid number / type of arguments"); - return 0; + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; } - } - } - - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Init - $v_string_list = array(); - $v_att_list = array(); - $v_filedescr_list = array(); - $p_result_list = array(); - - // ----- Look if the $p_filelist is really an array - if (is_array($p_filelist)) { - - // ----- Look if the first element is also an array - // This will mean that this is a file description entry - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; - } - - // ----- The list is a list of string names - else { - $v_string_list = $p_filelist; - } - } - // ----- Look if the $p_filelist is a string - else if (is_string($p_filelist)) { - // ----- Create a list from the string - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); - } + // ----- Call the create fct + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } - // ----- Invalid variable type for $p_filelist - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); - return 0; - } - - // ----- Reformat the string list - if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - if ($v_string != '') { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // add($p_filelist, $p_add_dir="", $p_remove_dir="") + // add($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two synopsis. The first one is historical. + // This methods add the list of files in an existing archive. + // If a file with the same name already exists, it is added at the end of the + // archive, the first one is still present. + // If the archive does not exist, it is created. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_OPT_ADD_COMMENT : + // PCLZIP_OPT_PREPEND_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function add($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array ( + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } else { + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } } - else { + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } else { + // ----- The list is a list of string names + $v_string_list = $p_filelist; + } + } else if (is_string($p_filelist)) { + // ----- Look if the $p_filelist is a string + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } else { + // ----- Invalid variable type for $p_filelist + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); + return 0; } - } - } - - // ----- For each file in the list check the attributes - $v_supported_attributes - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' - ,PCLZIP_ATT_FILE_MTIME => 'optional' - ,PCLZIP_ATT_FILE_CONTENT => 'optional' - ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); - foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, - $v_filedescr_list[], - $v_options, - $v_supported_attributes); - if ($v_result != 1) { - return 0; - } - } - // ----- Expand the filelist (expand directories) - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); - if ($v_result != 1) { - return 0; - } + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + } - // ----- Call the create fct - $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); - if ($v_result != 1) { - return 0; - } + // ----- For each file in the list check the attributes + $v_supported_attributes = array( + PCLZIP_ATT_FILE_NAME => 'mandatory', + PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional', + PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional', + PCLZIP_ATT_FILE_MTIME => 'optional', + PCLZIP_ATT_FILE_CONTENT => 'optional', + PCLZIP_ATT_FILE_COMMENT => 'optional', + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } - // ----- Return - return $p_result_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // add($p_filelist, $p_add_dir="", $p_remove_dir="") - // add($p_filelist, $p_option, $p_option_value, ...) - // Description : - // This method supports two synopsis. The first one is historical. - // This methods add the list of files in an existing archive. - // If a file with the same name already exists, it is added at the end of the - // archive, the first one is still present. - // If the archive does not exist, it is created. - // Parameters : - // $p_filelist : An array containing file or directory names, or - // a string containing one filename or one directory name, or - // a string containing a list of filenames and/or directory - // names separated by spaces. - // $p_add_dir : A path to add before the real path of the archived file, - // in order to have it memorized in the archive. - // $p_remove_dir : A path to remove from the real path of the file to archive, - // in order to have a shorter path memorized in the archive. - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir - // is removed first, before $p_add_dir is added. - // Options : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_COMMENT : - // PCLZIP_OPT_ADD_COMMENT : - // PCLZIP_OPT_PREPEND_COMMENT : - // PCLZIP_CB_PRE_ADD : - // PCLZIP_CB_POST_ADD : - // Return Values : - // 0 on failure, - // The list of the added files, with a status of the add action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function add($p_filelist) - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Set default values - $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove form the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_ADD_COMMENT => 'optional', - PCLZIP_OPT_PREPEND_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - //, PCLZIP_OPT_CRYPT => 'optional' - )); + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); if ($v_result != 1) { - return 0; + return 0; } - } - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : listContent() + // Description : + // This public method, gives the list of the files and directories, with their + // properties. + // The properties of each entries in the list are (used also in other functions) : + // filename : Name of the file. For a create or add action it is the filename + // given by the user. For an extract function it is the filename + // of the extracted file. + // stored_filename : Name of the file / directory stored in the archive. + // size : Size of the stored file. + // compressed_size : Size of the file's data compressed in the archive + // (without the headers overhead) + // mtime : Last known modification date of the file (UNIX timestamp) + // comment : Comment associated with the file + // folder : true | false + // index : index of the file in the archive + // status : status of the action (depending of the action) : + // Values are : + // ok : OK ! + // filtered : the file / dir is not extracted (filtered by user) + // already_a_directory : the file can not be extracted because a + // directory with the same name already exists + // write_protected : the file can not be extracted because a file + // with the same name already exists and is + // write protected + // newer_exist : the file was not extracted because a newer file exists + // path_creation_fail : the file is not extracted because the folder + // does not exist and can not be created + // write_error : the file was not extracted because there was a + // error while writing the file + // read_error : the file was not extracted because there was a error + // while reading the file + // invalid_header : the file was not extracted because of an archive + // format error (bad file header) + // Note that each time a method can continue operating when there + // is an action error on a file, the error is only logged in the file status. + // Return Values : + // 0 on an unrecoverable failure, + // The list of the files in the archive. + // -------------------------------------------------------------------------------- + function listContent() + { + $v_result=1; - // ----- Get the first argument - $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Return - return 0; + // ----- Call the extracting fct + $p_list = array(); + if (($v_result = $this->privList($p_list)) != 1) { + unset($p_list); + return(0); } - } - } - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Init - $v_string_list = array(); - $v_att_list = array(); - $v_filedescr_list = array(); - $p_result_list = array(); - - // ----- Look if the $p_filelist is really an array - if (is_array($p_filelist)) { - - // ----- Look if the first element is also an array - // This will mean that this is a file description entry - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; - } - - // ----- The list is a list of string names - else { - $v_string_list = $p_filelist; - } - } + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // extract($p_path="./", $p_remove_path="") + // extract([$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method extract all the files / directories from the archive to the + // folder indicated in $p_path. + // If you want to ignore the 'root' part of path of the memorized files + // you can indicate this in the optional $p_remove_path parameter. + // By default, if a newer file with the same name already exists, the + // file is not extracted. + // + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append + // at the end of the path value of PCLZIP_OPT_PATH. + // Parameters : + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 or a negative value on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function extract() + { + $v_result=1; - // ----- Look if the $p_filelist is a string - else if (is_string($p_filelist)) { - // ----- Create a list from the string - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); - } + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Invalid variable type for $p_filelist - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); - return 0; - } - - // ----- Reformat the string list - if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; - } - } - - // ----- For each file in the list check the attributes - $v_supported_attributes - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' - ,PCLZIP_ATT_FILE_MTIME => 'optional' - ,PCLZIP_ATT_FILE_CONTENT => 'optional' - ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); - foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, - $v_filedescr_list[], - $v_options, - $v_supported_attributes); - if ($v_result != 1) { - return 0; - } - } + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } - // ----- Expand the filelist (expand directories) - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); - if ($v_result != 1) { - return 0; - } + // ----- Set default values + $v_options = array(); + // $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array ( + PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional', + PCLZIP_OPT_STOP_ON_ERROR => 'optional', + PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } else { + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } - // ----- Call the create fct - $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); - if ($v_result != 1) { - return 0; - } + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); - // ----- Return - return $p_result_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : listContent() - // Description : - // This public method, gives the list of the files and directories, with their - // properties. - // The properties of each entries in the list are (used also in other functions) : - // filename : Name of the file. For a create or add action it is the filename - // given by the user. For an extract function it is the filename - // of the extracted file. - // stored_filename : Name of the file / directory stored in the archive. - // size : Size of the stored file. - // compressed_size : Size of the file's data compressed in the archive - // (without the headers overhead) - // mtime : Last known modification date of the file (UNIX timestamp) - // comment : Comment associated with the file - // folder : true | false - // index : index of the file in the archive - // status : status of the action (depending of the action) : - // Values are : - // ok : OK ! - // filtered : the file / dir is not extracted (filtered by user) - // already_a_directory : the file can not be extracted because a - // directory with the same name already exists - // write_protected : the file can not be extracted because a file - // with the same name already exists and is - // write protected - // newer_exist : the file was not extracted because a newer file exists - // path_creation_fail : the file is not extracted because the folder - // does not exist and can not be created - // write_error : the file was not extracted because there was a - // error while writing the file - // read_error : the file was not extracted because there was a error - // while reading the file - // invalid_header : the file was not extracted because of an archive - // format error (bad file header) - // Note that each time a method can continue operating when there - // is an action error on a file, the error is only logged in the file status. - // Return Values : - // 0 on an unrecoverable failure, - // The list of the files in the archive. - // -------------------------------------------------------------------------------- - function listContent() - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } + // ----- Trace + + // ----- Call the extracting fct + $p_list = array(); + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options); + if ($v_result < 1) { + unset($p_list); + return(0); + } - // ----- Call the extracting fct - $p_list = array(); - if (($v_result = $this->privList($p_list)) != 1) + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : + // extractByIndex($p_index, $p_path="./", $p_remove_path="") + // extractByIndex($p_index, [$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method is doing a partial extract of the archive. + // The extracted files or folders are identified by their index in the + // archive (from 0 to n). + // Note that if the index identify a folder, only the folder entry is + // extracted, not all the files included in the archive. + // Parameters : + // $p_index : A single index (integer) or a string of indexes of files to + // extract. The form of the string is "0,4-6,8-12" with only numbers + // and '-' for range or ',' to separate ranges. No spaces or ';' + // are allowed. + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and + // not as files. + // The resulting content is in a new field 'content' in the file + // structure. + // This option must be used alone (any other options are ignored). + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + //function extractByIndex($p_index, options...) + function extractByIndex($p_index) { - unset($p_list); - return(0); - } + $v_result=1; - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // extract($p_path="./", $p_remove_path="") - // extract([$p_option, $p_option_value, ...]) - // Description : - // This method supports two synopsis. The first one is historical. - // This method extract all the files / directories from the archive to the - // folder indicated in $p_path. - // If you want to ignore the 'root' part of path of the memorized files - // you can indicate this in the optional $p_remove_path parameter. - // By default, if a newer file with the same name already exists, the - // file is not extracted. - // - // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions - // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append - // at the end of the path value of PCLZIP_OPT_PATH. - // Parameters : - // $p_path : Path where the files and directories are to be extracted - // $p_remove_path : First part ('root' part) of the memorized path - // (if any similar) to remove while extracting. - // Options : - // PCLZIP_OPT_PATH : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_CB_PRE_EXTRACT : - // PCLZIP_CB_POST_EXTRACT : - // Return Values : - // 0 or a negative value on failure, - // The list of the extracted files, with a status of the action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function extract() - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Set default values - $v_options = array(); -// $v_path = "./"; - $v_path = ''; - $v_remove_path = ""; - $v_remove_all_path = false; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Default values for option - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; - - // ----- Look for arguments - if ($v_size > 0) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional' - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); } - // ----- Set the arguments - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + // ----- Set default values + $v_options = array(); + // $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array( + PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional', + PCLZIP_OPT_STOP_ON_ERROR => 'optional', + PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + } else { + } + } else { + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + + // ----- Trace + + // ----- Trick + // Here I want to reuse extractByRule(), so I need to parse the $p_index + // with privParseOptions() + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); + $v_options_trick = array(); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, array (PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - // ----- Check for '/' in last path char - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; - } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Call the extracting fct + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + return(0); } - } - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // delete([$p_option, $p_option_value, ...]) + // Description : + // This method removes files from the archive. + // If no parameters are given, then all the archive is emptied. + // Parameters : + // None or optional arguments. + // Options : + // PCLZIP_OPT_BY_INDEX : + // PCLZIP_OPT_BY_NAME : + // PCLZIP_OPT_BY_EREG : + // PCLZIP_OPT_BY_PREG : + // Return Values : + // 0 on failure, + // The list of the files which are still present in the archive. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function delete() + { + $v_result=1; - // ----- Get the first argument - $v_path = $v_arg_list[0]; + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - // ----- Return - return 0; + // ----- Set default values + $v_options = array(); + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array ( + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional' + )); + if ($v_result != 1) { + return 0; + } } - } - } - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - // ----- Trace + // ----- Call the delete fct + $v_list = array(); + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); + return(0); + } - // ----- Call the extracting fct - $p_list = array(); - $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, - $v_remove_all_path, $v_options); - if ($v_result < 1) { - unset($p_list); - return(0); - } + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - - // -------------------------------------------------------------------------------- - // Function : - // extractByIndex($p_index, $p_path="./", $p_remove_path="") - // extractByIndex($p_index, [$p_option, $p_option_value, ...]) - // Description : - // This method supports two synopsis. The first one is historical. - // This method is doing a partial extract of the archive. - // The extracted files or folders are identified by their index in the - // archive (from 0 to n). - // Note that if the index identify a folder, only the folder entry is - // extracted, not all the files included in the archive. - // Parameters : - // $p_index : A single index (integer) or a string of indexes of files to - // extract. The form of the string is "0,4-6,8-12" with only numbers - // and '-' for range or ',' to separate ranges. No spaces or ';' - // are allowed. - // $p_path : Path where the files and directories are to be extracted - // $p_remove_path : First part ('root' part) of the memorized path - // (if any similar) to remove while extracting. - // Options : - // PCLZIP_OPT_PATH : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and - // not as files. - // The resulting content is in a new field 'content' in the file - // structure. - // This option must be used alone (any other options are ignored). - // PCLZIP_CB_PRE_EXTRACT : - // PCLZIP_CB_POST_EXTRACT : - // Return Values : - // 0 on failure, - // The list of the extracted files, with a status of the action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - //function extractByIndex($p_index, options...) - function extractByIndex($p_index) - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); + // ----- Return + return $v_list; } + // -------------------------------------------------------------------------------- - // ----- Set default values - $v_options = array(); -// $v_path = "./"; - $v_path = ''; - $v_remove_path = ""; - $v_remove_all_path = false; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Default values for option - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove form the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional' - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; - } + // -------------------------------------------------------------------------------- + // Function : deleteByIndex() + // Description : + // ***** Deprecated ***** + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. + // -------------------------------------------------------------------------------- + function deleteByIndex($p_index) + { - // ----- Set the arguments - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - // ----- Check for '/' in last path char - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; - } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; - } - if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; - } - else { - } - } + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : properties() + // Description : + // This method gives the properties of the archive. + // The properties are : + // nb : Number of files in the archive + // comment : Comment associated with the archive file + // status : not_exist, ok + // Parameters : + // None + // Return Values : + // 0 on failure, + // An array with the archive properties. + // -------------------------------------------------------------------------------- + function properties() + { - // ----- Get the first argument - $v_path = $v_arg_list[0]; + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; - } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - // ----- Return - return 0; + // ----- Check archive + if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + return(0); } - } - } - // ----- Trace - - // ----- Trick - // Here I want to reuse extractByRule(), so I need to parse the $p_index - // with privParseOptions() - $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); - $v_options_trick = array(); - $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, - array (PCLZIP_OPT_BY_INDEX => 'optional' )); - if ($v_result != 1) { - return 0; - } - $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); + // ----- Look if file exists + if (@is_file($this->zipname)) { + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) { + $this->privSwapBackMagicQuotes(); - // ----- Call the extracting fct - if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { - return(0); - } + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // delete([$p_option, $p_option_value, ...]) - // Description : - // This method removes files from the archive. - // If no parameters are given, then all the archive is emptied. - // Parameters : - // None or optional arguments. - // Options : - // PCLZIP_OPT_BY_INDEX : - // PCLZIP_OPT_BY_NAME : - // PCLZIP_OPT_BY_EREG : - // PCLZIP_OPT_BY_PREG : - // Return Values : - // 0 on failure, - // The list of the files which are still present in the archive. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function delete() - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } + // ----- Return + return 0; + } - // ----- Set default values - $v_options = array(); - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Look for arguments - if ($v_size > 0) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional' )); - if ($v_result != 1) { - return 0; - } - } + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privSwapBackMagicQuotes(); + return 0; + } - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); + // ----- Close the zip file + $this->privCloseFd(); - // ----- Call the delete fct - $v_list = array(); - if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { - $this->privSwapBackMagicQuotes(); - unset($v_list); - return(0); - } + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); - // ----- Return - return $v_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : deleteByIndex() - // Description : - // ***** Deprecated ***** - // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. - // -------------------------------------------------------------------------------- - function deleteByIndex($p_index) - { - - $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + // ----- Return + return $v_prop; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : duplicate() + // Description : + // This method creates an archive by copying the content of an other one. If + // the archive already exist, it is replaced by the new one without any warning. + // Parameters : + // $p_archive : The filename of a valid archive, or + // a valid PclZip object. + // Return Values : + // 1 on success. + // 0 or a negative value on error (error code). + // -------------------------------------------------------------------------------- + function duplicate($p_archive) + { + $v_result = 1; - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : properties() - // Description : - // This method gives the properties of the archive. - // The properties are : - // nb : Number of files in the archive - // comment : Comment associated with the archive file - // status : not_exist, ok - // Parameters : - // None - // Return Values : - // 0 on failure, - // An array with the archive properties. - // -------------------------------------------------------------------------------- - function properties() - { - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - $this->privSwapBackMagicQuotes(); - return(0); - } + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Default properties - $v_prop = array(); - $v_prop['comment'] = ''; - $v_prop['nb'] = 0; - $v_prop['status'] = 'not_exist'; + // ----- Look if the $p_archive is a PclZip object + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) { - // ----- Look if file exists - if (@is_file($this->zipname)) - { - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) - { - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); + } else if (is_string($p_archive)) { + // ----- Look if the $p_archive is a string (so a filename) + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } + } else { + // ----- Invalid variable + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } // ----- Return - return 0; - } + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : merge() + // Description : + // This method merge the $p_archive_to_add archive at the end of the current + // one ($this). + // If the archive ($this) does not exist, the merge becomes a duplicate. + // If the $p_archive_to_add archive does not exist, the merge is a success. + // Parameters : + // $p_archive_to_add : It can be directly the filename of a valid zip archive, + // or a PclZip object archive. + // Return Values : + // 1 on success, + // 0 or negative values on error (see below). + // -------------------------------------------------------------------------------- + function merge($p_archive_to_add) + { + $v_result = 1; - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privSwapBackMagicQuotes(); - return 0; - } + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Close the zip file - $this->privCloseFd(); + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } - // ----- Set the user attributes - $v_prop['comment'] = $v_central_dir['comment']; - $v_prop['nb'] = $v_central_dir['entries']; - $v_prop['status'] = 'ok'; - } + // ----- Look if the $p_archive_to_add is a PclZip object + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) { + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); + } else if (is_string($p_archive_to_add)) { + // ----- Look if the $p_archive_to_add is a string (so a filename) + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); + } else { + // ----- Invalid variable + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- - // ----- Return - return $v_prop; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : duplicate() - // Description : - // This method creates an archive by copying the content of an other one. If - // the archive already exist, it is replaced by the new one without any warning. - // Parameters : - // $p_archive : The filename of a valid archive, or - // a valid PclZip object. - // Return Values : - // 1 on success. - // 0 or a negative value on error (error code). - // -------------------------------------------------------------------------------- - function duplicate($p_archive) - { - $v_result = 1; - // ----- Reset the error handler - $this->privErrorReset(); - // ----- Look if the $p_archive is a PclZip object - if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) + // -------------------------------------------------------------------------------- + // Function : errorCode() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorCode() { - - // ----- Duplicate the archive - $v_result = $this->privDuplicate($p_archive->zipname); + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorCode()); + } else { + return($this->error_code); + } } + // -------------------------------------------------------------------------------- - // ----- Look if the $p_archive is a string (so a filename) - else if (is_string($p_archive)) + // -------------------------------------------------------------------------------- + // Function : errorName() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorName($p_with_code=false) { + $v_name = array ( + PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', + PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', + PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION', + ); + + if (isset($v_name[$this->error_code])) { + $v_value = $v_name[$this->error_code]; + } else { + $v_value = 'NoName'; + } - // ----- Check that $p_archive is a valid zip file - // TBC : Should also check the archive format - if (!is_file($p_archive)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); - $v_result = PCLZIP_ERR_MISSING_FILE; - } - else { - // ----- Duplicate the archive - $v_result = $this->privDuplicate($p_archive); - } + if ($p_with_code) { + return($v_value.' ('.$this->error_code.')'); + } else { + return($v_value); + } } + // -------------------------------------------------------------------------------- - // ----- Invalid variable - else + // -------------------------------------------------------------------------------- + // Function : errorInfo() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorInfo($p_full=false) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorString()); + } else { + if ($p_full) { + return($this->errorName(true)." : ".$this->error_string); + } else { + return($this->error_string." [code ".$this->error_code."]"); + } + } } + // -------------------------------------------------------------------------------- - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : merge() - // Description : - // This method merge the $p_archive_to_add archive at the end of the current - // one ($this). - // If the archive ($this) does not exist, the merge becomes a duplicate. - // If the $p_archive_to_add archive does not exist, the merge is a success. - // Parameters : - // $p_archive_to_add : It can be directly the filename of a valid zip archive, - // or a PclZip object archive. - // Return Values : - // 1 on success, - // 0 or negative values on error (see below). - // -------------------------------------------------------------------------------- - function merge($p_archive_to_add) - { - $v_result = 1; - - // ----- Reset the error handler - $this->privErrorReset(); - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } + // -------------------------------------------------------------------------------- + // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** + // ***** ***** + // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** + // -------------------------------------------------------------------------------- - // ----- Look if the $p_archive_to_add is a PclZip object - if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) - { - // ----- Merge the archive - $v_result = $this->privMerge($p_archive_to_add); - } - // ----- Look if the $p_archive_to_add is a string (so a filename) - else if (is_string($p_archive_to_add)) + // -------------------------------------------------------------------------------- + // Function : privCheckFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // -------------------------------------------------------------------------------- + function privCheckFormat($p_level=0) { + $v_result = true; - // ----- Create a temporary archive - $v_object_archive = new PclZip($p_archive_to_add); + // ----- Reset the file system cache + clearstatcache(); - // ----- Merge the archive - $v_result = $this->privMerge($v_object_archive); - } + // ----- Reset the error handler + $this->privErrorReset(); - // ----- Invalid variable - else - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; - } + // ----- Look if the file exits + if (!is_file($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); + return(false); + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- + // ----- Check that the file is readeable + if (!is_readable($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); + return(false); + } + // ----- Check the magic code + // TBC + // ----- Check the central header + // TBC - // -------------------------------------------------------------------------------- - // Function : errorCode() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function errorCode() - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorCode()); - } - else { - return($this->error_code); - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : errorName() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function errorName($p_with_code=false) - { - $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', - PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', - PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', - PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', - PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', - PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', - PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', - PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', - PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', - PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', - PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', - PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', - PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', - PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', - PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', - PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', - PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', - PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', - PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' - ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' - ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' - ); - - if (isset($v_name[$this->error_code])) { - $v_value = $v_name[$this->error_code]; - } - else { - $v_value = 'NoName'; - } + // ----- Check each file header + // TBC - if ($p_with_code) { - return($v_value.' ('.$this->error_code.')'); - } - else { - return($v_value); - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : errorInfo() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function errorInfo($p_full=false) - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorString()); - } - else { - if ($p_full) { - return($this->errorName(true)." : ".$this->error_string); - } - else { - return($this->error_string." [code ".$this->error_code."]"); - } + // ----- Return + return $v_result; } - } - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privParseOptions() + // Description : + // This internal methods reads the variable list of arguments ($p_options_list, + // $p_size) and generate an array with the options and values ($v_result_list). + // $v_requested_options contains the options that can be present and those that + // must be present. + // $v_requested_options is an array, with the option value as key, and 'optional', + // or 'mandatory' as value. + // Parameters : + // See above. + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) + { + $v_result=1; + // ----- Read the options + $i=0; + while ($i<$p_size) { + // ----- Check if the option is supported + if (!isset($v_requested_options[$p_options_list[$i]])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); -// -------------------------------------------------------------------------------- -// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** -// ***** ***** -// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** -// -------------------------------------------------------------------------------- + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for next option + switch ($p_options_list[$i]) { + // ----- Look for options that request a path value + case PCLZIP_OPT_PATH: + case PCLZIP_OPT_REMOVE_PATH: + case PCLZIP_OPT_ADD_PATH: + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_THRESHOLD: + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + // ----- Check the value + $v_value = $p_options_list[$i+1]; + if ((!is_integer($v_value)) || ($v_value<0)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Get the value (and convert it in bytes) + $v_result_list[$p_options_list[$i]] = $v_value*1048576; + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_ON: + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_TEMP_FILE_OFF: + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); + return PclZip::errorCode(); + } + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); + return PclZip::errorCode(); + } + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1]) && ($p_options_list[$i+1] != '')) { + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + } else { + } + break; + + // ----- Look for options that request an array of string for value + case PCLZIP_OPT_BY_NAME : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; + } else if (is_array($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + // ----- Look for options that request an EREG or PREG expression + case PCLZIP_OPT_BY_EREG : + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG + // to PCLZIP_OPT_BY_PREG + $p_options_list[$i] = PCLZIP_OPT_BY_PREG; + case PCLZIP_OPT_BY_PREG : + //case PCLZIP_OPT_CRYPT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that takes a string + case PCLZIP_OPT_COMMENT : + case PCLZIP_OPT_ADD_COMMENT : + case PCLZIP_OPT_PREPEND_COMMENT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" .PclZipUtilOptionText($p_options_list[$i]) ."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an array of index + case PCLZIP_OPT_BY_INDEX : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_work_list = array(); + if (is_string($p_options_list[$i+1])) { + // ----- Remove spaces + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); + + // ----- Parse items + $v_work_list = explode(",", $p_options_list[$i+1]); + } else if (is_integer($p_options_list[$i+1])) { + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; + } else if (is_array($p_options_list[$i+1])) { + $v_work_list = $p_options_list[$i+1]; + } else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Reduce the index list + // each index item in the list must be a couple with a start and + // an end value : [0,3], [5-5], [8-10], ... + // ----- Check the format of each item + $v_sort_flag=false; + $v_sort_value=0; + for ($j=0; $j<sizeof($v_work_list); $j++) { + // ----- Explode the item + $v_item_list = explode("-", $v_work_list[$j]); + $v_size_item_list = sizeof($v_item_list); + + // ----- TBC : Here we might check that each item is a + // real integer ... + + // ----- Look for single value + if ($v_size_item_list == 1) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; + } elseif ($v_size_item_list == 2) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; + } else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + + // ----- Look for list sort + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { + $v_sort_flag=true; + + // ----- TBC : An automatic sort should be writen ... + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; + } + + // ----- Sort the items + if ($v_sort_flag) { + // TBC : To Be Completed + } + // ----- Next option + $i++; + break; + // ----- Look for options that request no value + case PCLZIP_OPT_REMOVE_ALL_PATH: + case PCLZIP_OPT_EXTRACT_AS_STRING: + case PCLZIP_OPT_NO_COMPRESSION: + case PCLZIP_OPT_EXTRACT_IN_OUTPUT: + case PCLZIP_OPT_REPLACE_NEWER: + case PCLZIP_OPT_STOP_ON_ERROR: + $v_result_list[$p_options_list[$i]] = true; + break; + // ----- Look for options that request an octal value + case PCLZIP_OPT_SET_CHMOD: + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } + // ----- Get the value + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + $i++; + break; + + // ----- Look for options that request a call-back + case PCLZIP_CB_PRE_EXTRACT: + case PCLZIP_CB_POST_EXTRACT: + case PCLZIP_CB_PRE_ADD: + case PCLZIP_CB_POST_ADD: + /* for futur use + case PCLZIP_CB_PRE_DELETE : + case PCLZIP_CB_POST_DELETE : + case PCLZIP_CB_PRE_LIST : + case PCLZIP_CB_POST_LIST : + */ + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_function_name = $p_options_list[$i+1]; + + // ----- Check that the value is a valid existing function + if (!function_exists($v_function_name)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } + + // ----- Set the attribute + $v_result_list[$p_options_list[$i]] = $v_function_name; + $i++; + break; + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '" .$p_options_list[$i]."'"); + + // ----- Return + return PclZip::errorCode(); + } + // ----- Next options + $i++; + } + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($v_result_list[$key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + + // ----- Return + return PclZip::errorCode(); + } + } + } + } - // -------------------------------------------------------------------------------- - // Function : privCheckFormat() - // Description : - // This method check that the archive exists and is a valid zip archive. - // Several level of check exists. (futur) - // Parameters : - // $p_level : Level of check. Default 0. - // 0 : Check the first bytes (magic codes) (default value)) - // 1 : 0 + Check the central directory (futur) - // 2 : 1 + Check each file header (futur) - // Return Values : - // true on success, - // false on error, the error code is set. - // -------------------------------------------------------------------------------- - function privCheckFormat($p_level=0) - { - $v_result = true; - - // ----- Reset the file system cache - clearstatcache(); - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Look if the file exits - if (!is_file($this->zipname)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); - return(false); - } + // ----- Look for default values + if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + } - // ----- Check that the file is readeable - if (!is_readable($this->zipname)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); - return(false); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Check the magic code - // TBC + // -------------------------------------------------------------------------------- + // Function : privOptionDefaultThreshold() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privOptionDefaultThreshold(&$p_options) + { + $v_result=1; - // ----- Check the central header - // TBC + if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { + return $v_result; + } - // ----- Check each file header - // TBC + // ----- Get 'memory_limit' configuration value + $v_memory_limit = ini_get('memory_limit'); + $v_memory_limit = trim($v_memory_limit); + $last = strtolower(substr($v_memory_limit, -1)); - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privParseOptions() - // Description : - // This internal methods reads the variable list of arguments ($p_options_list, - // $p_size) and generate an array with the options and values ($v_result_list). - // $v_requested_options contains the options that can be present and those that - // must be present. - // $v_requested_options is an array, with the option value as key, and 'optional', - // or 'mandatory' as value. - // Parameters : - // See above. - // Return Values : - // 1 on success. - // 0 on failure. - // -------------------------------------------------------------------------------- - function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) - { - $v_result=1; - - // ----- Read the options - $i=0; - while ($i<$p_size) { - - // ----- Check if the option is supported - if (!isset($v_requested_options[$p_options_list[$i]])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); + if ($last == 'g') { + //$v_memory_limit = $v_memory_limit*1024*1024*1024; + $v_memory_limit = $v_memory_limit*1073741824; + } + if ($last == 'm') { + //$v_memory_limit = $v_memory_limit*1024*1024; + $v_memory_limit = $v_memory_limit*1048576; + } + if ($last == 'k') { + $v_memory_limit = $v_memory_limit*1024; + } + + $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); + + // ----- Sanity check : No threshold if value lower than 1M + if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { + unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); + } // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for next option - switch ($p_options_list[$i]) { - // ----- Look for options that request a path value - case PCLZIP_OPT_PATH : - case PCLZIP_OPT_REMOVE_PATH : - case PCLZIP_OPT_ADD_PATH : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrParseAtt() + // Description : + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) + { + $v_result=1; - // ----- Return - return PclZip::errorCode(); - } + // ----- For each file in the list check the attributes + foreach ($p_file_list as $v_key => $v_value) { + // ----- Check if the option is supported + if (!isset($v_requested_options[$v_key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); - // ----- Get the value - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); - $i++; - break; + // ----- Return + return PclZip::errorCode(); + } - case PCLZIP_OPT_TEMP_FILE_THRESHOLD : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } - - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); - return PclZip::errorCode(); - } - - // ----- Check the value - $v_value = $p_options_list[$i+1]; - if ((!is_integer($v_value)) || ($v_value<0)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } + // ----- Look for attribute + switch ($v_key) { + case PCLZIP_ATT_FILE_NAME: + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['filename'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + case PCLZIP_ATT_FILE_NEW_SHORT_NAME: + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_short_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + case PCLZIP_ATT_FILE_NEW_FULL_NAME: + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_full_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + // ----- Look for options that takes a string + case PCLZIP_ATT_FILE_COMMENT: + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + $p_filedescr['comment'] = $v_value; + break; + case PCLZIP_ATT_FILE_MTIME: + if (!is_integer($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + $p_filedescr['mtime'] = $v_value; + break; + case PCLZIP_ATT_FILE_CONTENT: + $p_filedescr['content'] = $v_value; + break; + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '".$v_key."'"); + + // ----- Return + return PclZip::errorCode(); + } - // ----- Get the value (and convert it in bytes) - $v_result_list[$p_options_list[$i]] = $v_value*1048576; - $i++; - break; + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key = reset($v_requested_options); $key = key($v_requested_options); $key = next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($p_file_list[$key])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + return PclZip::errorCode(); + } + } + } + } + } - case PCLZIP_OPT_TEMP_FILE_ON : - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); - return PclZip::errorCode(); - } - - $v_result_list[$p_options_list[$i]] = true; - break; - - case PCLZIP_OPT_TEMP_FILE_OFF : - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); - return PclZip::errorCode(); - } - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); - return PclZip::errorCode(); - } - - $v_result_list[$p_options_list[$i]] = true; - break; - - case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrExpand() + // Description : + // This method look for each item of the list to see if its a file, a folder + // or a string to be added as file. For any other type of files (link, other) + // just ignore the item. + // Then prepare the information that will be stored for that file. + // When its a folder, expand the folder with all the files that are in that + // folder (recursively). + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrExpand(&$p_filedescr_list, &$p_options) + { + $v_result=1; + + // ----- Create a result list + $v_result_list = array(); + + // ----- Look each entry + for ($i=0; $i<sizeof($p_filedescr_list); $i++) { + // ----- Get filedescr + $v_descr = $p_filedescr_list[$i]; + + // ----- Reduce the filename + $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); + $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); + + // ----- Look for real file or folder + if (file_exists($v_descr['filename'])) { + if (@is_file($v_descr['filename'])) { + $v_descr['type'] = 'file'; + } else if (@is_dir($v_descr['filename'])) { + $v_descr['type'] = 'folder'; + } else if (@is_link($v_descr['filename'])) { + // skip + continue; + } else { + // skip + continue; + } + } else if (isset($v_descr['content'])) { + // ----- Look for string added as file + $v_descr['type'] = 'virtual_file'; + } else { + // ----- Missing file + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); - // ----- Return - return PclZip::errorCode(); - } + // ----- Return + return PclZip::errorCode(); + } - // ----- Get the value - if ( is_string($p_options_list[$i+1]) - && ($p_options_list[$i+1] != '')) { - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); - $i++; - } - else { - } - break; - - // ----- Look for options that request an array of string for value - case PCLZIP_OPT_BY_NAME : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Calculate the stored filename + $this->privCalculateStoredFilename($v_descr, $p_options); + + // ----- Add the descriptor in result list + $v_result_list[sizeof($v_result_list)] = $v_descr; + + // ----- Look for folder + if ($v_descr['type'] == 'folder') { + // ----- List of items in folder + $v_dirlist_descr = array(); + $v_dirlist_nb = 0; + if ($v_folder_handler = @opendir($v_descr['filename'])) { + while (($v_item_handler = @readdir($v_folder_handler)) !== false) { + // ----- Skip '.' and '..' + if (($v_item_handler == '.') || ($v_item_handler == '..')) { + continue; + } + + // ----- Compose the full filename + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; + + // ----- Look for different stored filename + // Because the name of the folder was changed, the name of the + // files/sub-folders also change + if (($v_descr['stored_filename'] != $v_descr['filename']) + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { + if ($v_descr['stored_filename'] != '') { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; + } else { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; + } + } + $v_dirlist_nb++; + } + + @closedir($v_folder_handler); + } else { + // TBC : unable to open folder in read mode + } + + // ----- Expand each element of the list + if ($v_dirlist_nb != 0) { + // ----- Expand + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { + return $v_result; + } + + // ----- Concat the resulting list + $v_result_list = array_merge($v_result_list, $v_dirlist_descr); + } + + // ----- Free local array + unset($v_dirlist_descr); + } + } - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; - } - else if (is_array($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Get the result list + $p_filedescr_list = $v_result_list; - // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that request an EREG or PREG expression - case PCLZIP_OPT_BY_EREG : - // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG - // to PCLZIP_OPT_BY_PREG - $p_options_list[$i] = PCLZIP_OPT_BY_PREG; - case PCLZIP_OPT_BY_PREG : - //case PCLZIP_OPT_CRYPT : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- - // ----- Return - return PclZip::errorCode(); - } + // -------------------------------------------------------------------------------- + // Function : privCreate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCreate($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + // ----- Open the file in write mode + if (($v_result = $this->privOpenFd('wb')) != 1) { // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that takes a string - case PCLZIP_OPT_COMMENT : - case PCLZIP_OPT_ADD_COMMENT : - case PCLZIP_OPT_PREPEND_COMMENT : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, - "Missing parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); + return $v_result; + } - // ----- Return - return PclZip::errorCode(); - } + // ----- Add the list of files + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, - "Wrong parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); - - // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that request an array of index - case PCLZIP_OPT_BY_INDEX : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_work_list = array(); - if (is_string($p_options_list[$i+1])) { - - // ----- Remove spaces - $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); - - // ----- Parse items - $v_work_list = explode(",", $p_options_list[$i+1]); - } - else if (is_integer($p_options_list[$i+1])) { - $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; - } - else if (is_array($p_options_list[$i+1])) { - $v_work_list = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Close + $this->privCloseFd(); - // ----- Return - return PclZip::errorCode(); - } - - // ----- Reduce the index list - // each index item in the list must be a couple with a start and - // an end value : [0,3], [5-5], [8-10], ... - // ----- Check the format of each item - $v_sort_flag=false; - $v_sort_value=0; - for ($j=0; $j<sizeof($v_work_list); $j++) { - // ----- Explode the item - $v_item_list = explode("-", $v_work_list[$j]); - $v_size_item_list = sizeof($v_item_list); - - // ----- TBC : Here we might check that each item is a - // real integer ... - - // ----- Look for single value - if ($v_size_item_list == 1) { - // ----- Set the option value - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; - } - elseif ($v_size_item_list == 2) { - // ----- Set the option value - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - - // ----- Look for list sort - if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { - $v_sort_flag=true; - - // ----- TBC : An automatic sort should be writen ... - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; - } - - // ----- Sort the items - if ($v_sort_flag) { - // TBC : To Be Completed - } - - // ----- Next option - $i++; - break; - - // ----- Look for options that request no value - case PCLZIP_OPT_REMOVE_ALL_PATH : - case PCLZIP_OPT_EXTRACT_AS_STRING : - case PCLZIP_OPT_NO_COMPRESSION : - case PCLZIP_OPT_EXTRACT_IN_OUTPUT : - case PCLZIP_OPT_REPLACE_NEWER : - case PCLZIP_OPT_STOP_ON_ERROR : - $v_result_list[$p_options_list[$i]] = true; - break; - - // ----- Look for options that request an octal value - case PCLZIP_OPT_SET_CHMOD : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - $i++; - break; - - // ----- Look for options that request a call-back - case PCLZIP_CB_PRE_EXTRACT : - case PCLZIP_CB_POST_EXTRACT : - case PCLZIP_CB_PRE_ADD : - case PCLZIP_CB_POST_ADD : - /* for futur use - case PCLZIP_CB_PRE_DELETE : - case PCLZIP_CB_POST_DELETE : - case PCLZIP_CB_PRE_LIST : - case PCLZIP_CB_POST_LIST : - */ - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- - // ----- Return - return PclZip::errorCode(); - } + // -------------------------------------------------------------------------------- + // Function : privAdd() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAdd($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); - // ----- Get the value - $v_function_name = $p_options_list[$i+1]; + // ----- Look if the archive exists or is empty + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) { - // ----- Check that the value is a valid existing function - if (!function_exists($v_function_name)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Do a create + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); // ----- Return - return PclZip::errorCode(); - } - - // ----- Set the attribute - $v_result_list[$p_options_list[$i]] = $v_function_name; - $i++; - break; - - default : - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Unknown parameter '" - .$p_options_list[$i]."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Next options - $i++; - } + return $v_result; + } + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - // ----- Look for mandatory options - if ($v_requested_options !== false) { - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { - // ----- Look for mandatory option - if ($v_requested_options[$key] == 'mandatory') { - // ----- Look if present - if (!isset($v_result_list[$key])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); // ----- Return - return PclZip::errorCode(); - } + return $v_result; } - } - } - - // ----- Look for default values - if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { - - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privOptionDefaultThreshold() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privOptionDefaultThreshold(&$p_options) - { - $v_result=1; - - if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { - return $v_result; - } - - // ----- Get 'memory_limit' configuration value - $v_memory_limit = ini_get('memory_limit'); - $v_memory_limit = trim($v_memory_limit); - $last = strtolower(substr($v_memory_limit, -1)); - - if ($last == 'g') - //$v_memory_limit = $v_memory_limit*1024*1024*1024; - $v_memory_limit = $v_memory_limit*1073741824; - if ($last == 'm') - //$v_memory_limit = $v_memory_limit*1024*1024; - $v_memory_limit = $v_memory_limit*1048576; - if ($last == 'k') - $v_memory_limit = $v_memory_limit*1024; - - $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); - - - // ----- Sanity check : No threshold if value lower than 1M - if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { - unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privFileDescrParseAtt() - // Description : - // Parameters : - // Return Values : - // 1 on success. - // 0 on failure. - // -------------------------------------------------------------------------------- - function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) - { - $v_result=1; - - // ----- For each file in the list check the attributes - foreach ($p_file_list as $v_key => $v_value) { - - // ----- Check if the option is supported - if (!isset($v_requested_options[$v_key])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for attribute - switch ($v_key) { - case PCLZIP_ATT_FILE_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); - - if ($p_filedescr['filename'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } - break; + // ----- Go to beginning of File + @rewind($this->zip_fd); - case PCLZIP_ATT_FILE_NEW_SHORT_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - if ($p_filedescr['new_short_name'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - break; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); - case PCLZIP_ATT_FILE_NEW_FULL_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + // ----- Return return PclZip::errorCode(); - } + } - $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - if ($p_filedescr['new_full_name'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - break; + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); - // ----- Look for options that takes a string - case PCLZIP_ATT_FILE_COMMENT : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } + // ----- Return + return $v_result; + } - $p_filedescr['comment'] = $v_value; - break; + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); - case PCLZIP_ATT_FILE_MTIME : - if (!is_integer($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['mtime'] = $v_value; - break; - - case PCLZIP_ATT_FILE_CONTENT : - $p_filedescr['content'] = $v_value; - break; - - default : - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Unknown parameter '".$v_key."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for mandatory options - if ($v_requested_options !== false) { - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { - // ----- Look for mandatory option - if ($v_requested_options[$key] == 'mandatory') { - // ----- Look if present - if (!isset($p_file_list[$key])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); - return PclZip::errorCode(); - } - } - } - } - - // end foreach - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privFileDescrExpand() - // Description : - // This method look for each item of the list to see if its a file, a folder - // or a string to be added as file. For any other type of files (link, other) - // just ignore the item. - // Then prepare the information that will be stored for that file. - // When its a folder, expand the folder with all the files that are in that - // folder (recursively). - // Parameters : - // Return Values : - // 1 on success. - // 0 on failure. - // -------------------------------------------------------------------------------- - function privFileDescrExpand(&$p_filedescr_list, &$p_options) - { - $v_result=1; - - // ----- Create a result list - $v_result_list = array(); - - // ----- Look each entry - for ($i=0; $i<sizeof($p_filedescr_list); $i++) { - - // ----- Get filedescr - $v_descr = $p_filedescr_list[$i]; - - // ----- Reduce the filename - $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); - $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); - - // ----- Look for real file or folder - if (file_exists($v_descr['filename'])) { - if (@is_file($v_descr['filename'])) { - $v_descr['type'] = 'file'; - } - else if (@is_dir($v_descr['filename'])) { - $v_descr['type'] = 'folder'; - } - else if (@is_link($v_descr['filename'])) { - // skip - continue; + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; } - else { - // skip - continue; - } - } - - // ----- Look for string added as file - else if (isset($v_descr['content'])) { - $v_descr['type'] = 'virtual_file'; - } - - // ----- Missing file - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); - // ----- Return - return PclZip::errorCode(); - } - - // ----- Calculate the stored filename - $this->privCalculateStoredFilename($v_descr, $p_options); - - // ----- Add the descriptor in result list - $v_result_list[sizeof($v_result_list)] = $v_descr; - - // ----- Look for folder - if ($v_descr['type'] == 'folder') { - // ----- List of items in folder - $v_dirlist_descr = array(); - $v_dirlist_nb = 0; - if ($v_folder_handler = @opendir($v_descr['filename'])) { - while (($v_item_handler = @readdir($v_folder_handler)) !== false) { - - // ----- Skip '.' and '..' - if (($v_item_handler == '.') || ($v_item_handler == '..')) { - continue; - } - - // ----- Compose the full filename - $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; - - // ----- Look for different stored filename - // Because the name of the folder was changed, the name of the - // files/sub-folders also change - if (($v_descr['stored_filename'] != $v_descr['filename']) - && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { - if ($v_descr['stored_filename'] != '') { - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; - } - else { - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; - } + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + $v_count++; } - - $v_dirlist_nb++; - } - - @closedir($v_folder_handler); + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); } - else { - // TBC : unable to open folder in read mode + + // ----- Zip file comment + $v_comment = $v_central_dir['comment']; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; } - - // ----- Expand each element of the list - if ($v_dirlist_nb != 0) { - // ----- Expand - if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { - return $v_result; - } - - // ----- Concat the resulting list - $v_result_list = array_merge($v_result_list, $v_dirlist_descr); + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; } - else { + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; } - - // ----- Free local array - unset($v_dirlist_descr); - } - } - - // ----- Get the result list - $p_filedescr_list = $v_result_list; - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCreate() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privCreate($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - $v_list_detail = array(); - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Open the file in write mode - if (($v_result = $this->privOpenFd('wb')) != 1) - { - // ----- Return - return $v_result; - } + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; - // ----- Add the list of files - $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $this->privSwapBackMagicQuotes(); - // ----- Close - $this->privCloseFd(); + // ----- Return + return $v_result; + } - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAdd() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privAdd($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - $v_list_detail = array(); - - // ----- Look if the archive exists or is empty - if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) - { + // ----- Close + $this->privCloseFd(); - // ----- Do a create - $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); + // ----- Close the temporary file + @fclose($v_zip_temp_fd); - // ----- Return - return $v_result; - } - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); - // ----- Open the zip file - if (($v_result=$this->privOpenFd('rb')) != 1) - { - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); - // ----- Return - return $v_result; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + // -------------------------------------------------------------------------------- + // Function : privOpenFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privOpenFd($p_mode) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } + $v_result=1; - // ----- Go to beginning of File - @rewind($this->zip_fd); + // ----- Look if already open + if ($this->zip_fd != 0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); - // ----- Creates a temporay file - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + // ----- Return + return PclZip::errorCode(); + } - // ----- Open the temporary file in write mode - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) - { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + // ----- Return + return PclZip::errorCode(); + } - // ----- Return - return PclZip::errorCode(); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Copy the files from the archive to the temporary file - // TBC : Here I should better append the file and go back to erase the central dir - $v_size = $v_central_dir['offset']; - while ($v_size != 0) + // -------------------------------------------------------------------------------- + // Function : privCloseFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privCloseFd() { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + $v_result=1; - // ----- Swap the file descriptor - // Here is a trick : I swap the temporary fd with the zip fd, in order to use - // the following methods on the temporary fil and not the real archive - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - - // ----- Add the files - $v_header_list = array(); - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) - { - fclose($v_zip_temp_fd); - $this->privCloseFd(); - @unlink($v_zip_temp_name); - $this->privSwapBackMagicQuotes(); + if ($this->zip_fd != 0) { + @fclose($this->zip_fd); + } + $this->zip_fd = 0; - // ----- Return - return $v_result; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // -------------------------------------------------------------------------------- + // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) + function privAddList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; - // ----- Store the offset of the central dir - $v_offset = @ftell($this->zip_fd); + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) { + // ----- Return + return $v_result; + } - // ----- Copy the block of file headers from the old archive - $v_size = $v_central_dir['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_zip_temp_fd, $v_read_size); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); - // ----- Create the Central Dir files header - for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) - { - // ----- Create the file header - if ($v_header_list[$i]['status'] == 'ok') { - if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { - fclose($v_zip_temp_fd); - $this->privCloseFd(); - @unlink($v_zip_temp_name); - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - $v_count++; - } - - // ----- Transform the header to a 'usable' info - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + // ----- Return + return $v_result; + } + $v_count++; + } - // ----- Zip file comment - $v_comment = $v_central_dir['comment']; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } - if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { - $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; - } - if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; - } + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } - // ----- Calculate the size of the central header - $v_size = @ftell($this->zip_fd)-$v_offset; + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } - // ----- Create the central dir footer - if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) - { - // ----- Reset the file list - unset($v_header_list); - $this->privSwapBackMagicQuotes(); + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; - // ----- Return - return $v_result; - } + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); - // ----- Swap back the file descriptor - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; + // ----- Return + return $v_result; + } - // ----- Close - $this->privCloseFd(); + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileList() + // Description : + // Parameters : + // $p_filedescr_list : An array containing the file description + // or directory names to add in the zip + // $p_result_list : list of added files with their properties (specially the status field) + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_header = array(); - // ----- Close the temporary file - @fclose($v_zip_temp_fd); + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); + // ----- Loop on the files + for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { + // ----- Format the filename + $p_filedescr_list[$j]['filename'] = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); - // ----- Delete the zip file - // TBC : I should test the result ... - @unlink($this->zipname); + // ----- Skip empty file names + // TBC : Can this be possible ? not checked in DescrParseAtt ? + if ($p_filedescr_list[$j]['filename'] == "") { + continue; + } - // ----- Rename the temporary file - // TBC : I should test the result ... - //@rename($v_zip_temp_name, $this->zipname); - PclZipUtilRename($v_zip_temp_name, $this->zipname); + // ----- Check the filename + if (($p_filedescr_list[$j]['type'] != 'virtual_file') && (!file_exists($p_filedescr_list[$j]['filename']))) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); + return PclZip::errorCode(); + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privOpenFd() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privOpenFd($p_mode) - { - $v_result=1; - - // ----- Look if already open - if ($this->zip_fd != 0) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); + // ----- Look if it is a file or a dir with no all path remove option + // or a dir with all its path removed + // if ( (is_file($p_filedescr_list[$j]['filename'])) + // || ( is_dir($p_filedescr_list[$j]['filename']) + if (($p_filedescr_list[$j]['type'] == 'file') || ($p_filedescr_list[$j]['type'] == 'virtual_file') || (($p_filedescr_list[$j]['type'] == 'folder') && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { + // ----- Add the file + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, $p_options); + if ($v_result != 1) { + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + } - // ----- Return - return PclZip::errorCode(); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) + // -------------------------------------------------------------------------------- + // Function : privAddFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFile($p_filedescr, &$p_header, &$p_options) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); + $v_result=1; - // ----- Return - return PclZip::errorCode(); - } + // ----- Working variable + $p_filename = $p_filedescr['filename']; - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCloseFd() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privCloseFd() - { - $v_result=1; - - if ($this->zip_fd != 0) - @fclose($this->zip_fd); - $this->zip_fd = 0; + // TBC : Already done in the fileAtt check ... ? + if ($p_filename == "") { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddList() - // Description : - // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is - // different from the real path of the file. This is usefull if you want to have PclTar - // running in any directory, and memorize relative path from an other directory. - // Parameters : - // $p_list : An array containing the file or directory names to add in the tar - // $p_result_list : list of added files with their properties (specially the status field) - // $p_add_dir : Path to add in the filename path archived - // $p_remove_dir : Path to remove in the filename path archived - // Return Values : - // -------------------------------------------------------------------------------- -// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) - function privAddList($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - - // ----- Add the files - $v_header_list = array(); - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) - { - // ----- Return - return $v_result; - } + // ----- Return + return PclZip::errorCode(); + } - // ----- Store the offset of the central dir - $v_offset = @ftell($this->zip_fd); + // ----- Look for a stored different filename + /* TBC : Removed + if (isset($p_filedescr['stored_filename'])) { + $v_stored_filename = $p_filedescr['stored_filename']; + } + else { + $v_stored_filename = $p_filedescr['stored_filename']; + } + */ - // ----- Create the Central Dir files header - for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) - { - // ----- Create the file header - if ($v_header_list[$i]['status'] == 'ok') { - if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { - // ----- Return - return $v_result; + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; + // TBC : Removed $p_header['stored_filename'] = $v_stored_filename; + $p_header['stored_filename'] = $p_filedescr['stored_filename']; + $p_header['extra'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; + + // ----- Look for regular file + if ($p_filedescr['type']=='file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = filesize($p_filename); + } else if ($p_filedescr['type']=='folder') { + // ----- Look for regular folder + $p_header['external'] = 0x00000010; + $p_header['mtime'] = filemtime($p_filename); + $p_header['size'] = filesize($p_filename); + } else if ($p_filedescr['type'] == 'virtual_file') { + // ----- Look for virtual file + $p_header['external'] = 0x00000000; + $p_header['size'] = strlen($p_filedescr['content']); } - $v_count++; - } - // ----- Transform the header to a 'usable' info - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } + // ----- Look for filetime + if (isset($p_filedescr['mtime'])) { + $p_header['mtime'] = $p_filedescr['mtime']; + } else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['mtime'] = time(); + } else { + $p_header['mtime'] = filemtime($p_filename); + } - // ----- Zip file comment - $v_comment = ''; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } + // ------ Look for file comment + if (isset($p_filedescr['comment'])) { + $p_header['comment_len'] = strlen($p_filedescr['comment']); + $p_header['comment'] = $p_filedescr['comment']; + } else { + $p_header['comment_len'] = 0; + $p_header['comment'] = ''; + } - // ----- Calculate the size of the central header - $v_size = @ftell($this->zip_fd)-$v_offset; + // ----- Look for pre-add callback + if (isset($p_options[PCLZIP_CB_PRE_ADD])) { + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; + } - // ----- Create the central dir footer - if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) - { - // ----- Reset the file list - unset($v_header_list); + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); + } + } - // ----- Return - return $v_result; - } + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddFileList() - // Description : - // Parameters : - // $p_filedescr_list : An array containing the file description - // or directory names to add in the zip - // $p_result_list : list of added files with their properties (specially the status field) - // Return Values : - // -------------------------------------------------------------------------------- - function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - $v_header = array(); - - // ----- Recuperate the current number of elt in list - $v_nb = sizeof($p_result_list); - - // ----- Loop on the files - for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { - // ----- Format the filename - $p_filedescr_list[$j]['filename'] - = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); - - - // ----- Skip empty file names - // TBC : Can this be possible ? not checked in DescrParseAtt ? - if ($p_filedescr_list[$j]['filename'] == "") { - continue; - } - - // ----- Check the filename - if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') - && (!file_exists($p_filedescr_list[$j]['filename']))) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); - return PclZip::errorCode(); - } - - // ----- Look if it is a file or a dir with no all path remove option - // or a dir with all its path removed -// if ( (is_file($p_filedescr_list[$j]['filename'])) -// || ( is_dir($p_filedescr_list[$j]['filename']) - if ( ($p_filedescr_list[$j]['type'] == 'file') - || ($p_filedescr_list[$j]['type'] == 'virtual_file') - || ( ($p_filedescr_list[$j]['type'] == 'folder') - && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) - || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) - ) { - - // ----- Add the file - $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, - $p_options); - if ($v_result != 1) { - return $v_result; + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; } - // ----- Store the file infos - $p_result_list[$v_nb++] = $v_header; - } - } + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { + // ----- Look for a file + if ($p_filedescr['type'] == 'file') { + // ----- Look for using temporary file to zip + if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { + $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } else { + // ----- Use "in memory" zip algo + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); + + // ----- Close the file + @fclose($v_file); + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } else { + // ----- Look for normal compression + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + } + } else if ($p_filedescr['type'] == 'virtual_file') { + // ----- Look for a virtual file (a file from string) + $v_content = $p_filedescr['content']; + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } else { + // ----- Look for normal compression + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + } else if ($p_filedescr['type'] == 'folder') { + // ----- Look for a directory + // ----- Look for directory last '/' + if (@substr($p_header['stored_filename'], -1) != '/') { + $p_header['stored_filename'] .= '/'; + } + + // ----- Set the file properties + $p_header['size'] = 0; + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + $p_header['external'] = 0x00000010; // Value for a folder : to be checked + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + return $v_result; + } + } + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddFile() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privAddFile($p_filedescr, &$p_header, &$p_options) - { - $v_result=1; - - // ----- Working variable - $p_filename = $p_filedescr['filename']; - - // TBC : Already done in the fileAtt check ... ? - if ($p_filename == "") { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for a stored different filename - /* TBC : Removed - if (isset($p_filedescr['stored_filename'])) { - $v_stored_filename = $p_filedescr['stored_filename']; - } - else { - $v_stored_filename = $p_filedescr['stored_filename']; - } - */ - - // ----- Set the file properties - clearstatcache(); - $p_header['version'] = 20; - $p_header['version_extracted'] = 10; - $p_header['flag'] = 0; - $p_header['compression'] = 0; - $p_header['crc'] = 0; - $p_header['compressed_size'] = 0; - $p_header['filename_len'] = strlen($p_filename); - $p_header['extra_len'] = 0; - $p_header['disk'] = 0; - $p_header['internal'] = 0; - $p_header['offset'] = 0; - $p_header['filename'] = $p_filename; -// TBC : Removed $p_header['stored_filename'] = $v_stored_filename; - $p_header['stored_filename'] = $p_filedescr['stored_filename']; - $p_header['extra'] = ''; - $p_header['status'] = 'ok'; - $p_header['index'] = -1; - - // ----- Look for regular file - if ($p_filedescr['type']=='file') { - $p_header['external'] = 0x00000000; - $p_header['size'] = filesize($p_filename); - } - - // ----- Look for regular folder - else if ($p_filedescr['type']=='folder') { - $p_header['external'] = 0x00000010; - $p_header['mtime'] = filemtime($p_filename); - $p_header['size'] = filesize($p_filename); - } - - // ----- Look for virtual file - else if ($p_filedescr['type'] == 'virtual_file') { - $p_header['external'] = 0x00000000; - $p_header['size'] = strlen($p_filedescr['content']); - } - + // ----- Look for post-add callback + if (isset($p_options[PCLZIP_CB_POST_ADD])) { + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; + } - // ----- Look for filetime - if (isset($p_filedescr['mtime'])) { - $p_header['mtime'] = $p_filedescr['mtime']; - } - else if ($p_filedescr['type'] == 'virtual_file') { - $p_header['mtime'] = time(); - } - else { - $p_header['mtime'] = filemtime($p_filename); - } + // ----- Update the informations + // Nothing can be modified + } - // ------ Look for file comment - if (isset($p_filedescr['comment'])) { - $p_header['comment_len'] = strlen($p_filedescr['comment']); - $p_header['comment'] = $p_filedescr['comment']; - } - else { - $p_header['comment_len'] = 0; - $p_header['comment'] = ''; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Look for pre-add callback - if (isset($p_options[PCLZIP_CB_PRE_ADD])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_header, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_header['status'] = "skipped"; - $v_result = 1; - } + // -------------------------------------------------------------------------------- + // Function : privAddFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=PCLZIP_ERR_NO_ERROR; - // ----- Update the informations - // Only some fields can be modified - if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { - $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); - } - } + // ----- Working variable + $p_filename = $p_filedescr['filename']; - // ----- Look for empty stored filename - if ($p_header['stored_filename'] == "") { - $p_header['status'] = "filtered"; - } - - // ----- Check the path length - if (strlen($p_header['stored_filename']) > 0xFF) { - $p_header['status'] = 'filename_too_long'; - } - - // ----- Look if no error, or file not skipped - if ($p_header['status'] == 'ok') { - - // ----- Look for a file - if ($p_filedescr['type'] == 'file') { - // ----- Look for using temporary file to zip - if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { - $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); - if ($v_result < PCLZIP_ERR_NO_ERROR) { - return $v_result; - } - } - - // ----- Use "in memory" zip algo - else { // ----- Open the source file if (($v_file = @fopen($p_filename, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); - return PclZip::errorCode(); + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); } - // ----- Read the file content - $v_content = @fread($v_file, $p_header['size']); + // ----- Creates a compressed temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = filesize($p_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @gzputs($v_file_compressed, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } // ----- Close the file @fclose($v_file); + @gzclose($v_file_compressed); - // ----- Calculate the CRC - $p_header['crc'] = @crc32($v_content); - - // ----- Look for no compression - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { - // ----- Set header parameters - $p_header['compressed_size'] = $p_header['size']; - $p_header['compression'] = 0; - } - - // ----- Look for normal compression - else { - // ----- Compress the content - $v_content = @gzdeflate($v_content); - - // ----- Set header parameters - $p_header['compressed_size'] = strlen($v_content); - $p_header['compression'] = 8; + // ----- Check the minimum file size + if (filesize($v_gzip_temp_name) < 18) { + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); + return PclZip::errorCode(); } - - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - @fclose($v_file); - return $v_result; + + // ----- Extract the compressed attributes + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); } - // ----- Write the compressed (or not) content - @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + // ----- Read the gzip file header + $v_binary_data = @fread($v_file_compressed, 10); + $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); - } + // ----- Check some parameters + $v_data_header['os'] = bin2hex($v_data_header['os']); - } + // ----- Read the gzip file footer + @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); + $v_binary_data = @fread($v_file_compressed, 8); + $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); - // ----- Look for a virtual file (a file from string) - else if ($p_filedescr['type'] == 'virtual_file') { - - $v_content = $p_filedescr['content']; + // ----- Set the attributes + $p_header['compression'] = ord($v_data_header['cm']); + //$p_header['mtime'] = $v_data_header['mtime']; + $p_header['crc'] = $v_data_footer['crc']; + $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; - // ----- Calculate the CRC - $p_header['crc'] = @crc32($v_content); - - // ----- Look for no compression - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { - // ----- Set header parameters - $p_header['compressed_size'] = $p_header['size']; - $p_header['compression'] = 0; - } - - // ----- Look for normal compression - else { - // ----- Compress the content - $v_content = @gzdeflate($v_content); + // ----- Close the file + @fclose($v_file_compressed); - // ----- Set header parameters - $p_header['compressed_size'] = strlen($v_content); - $p_header['compression'] = 8; - } - // ----- Call the header generation if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - @fclose($v_file); - return $v_result; + return $v_result; } - // ----- Write the compressed (or not) content - @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); - } - - // ----- Look for a directory - else if ($p_filedescr['type'] == 'folder') { - // ----- Look for directory last '/' - if (@substr($p_header['stored_filename'], -1) != '/') { - $p_header['stored_filename'] .= '/'; + // ----- Add the compressed data + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); } - // ----- Set the file properties - $p_header['size'] = 0; - //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked - $p_header['external'] = 0x00000010; // Value for a folder : to be checked - - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) - { - return $v_result; + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + fseek($v_file_compressed, 10); + $v_size = $p_header['compressed_size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file_compressed, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; } - } - } - - // ----- Look for post-add callback - if (isset($p_options[PCLZIP_CB_POST_ADD])) { - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_header, $v_local_header); + // ----- Close the file + @fclose($v_file_compressed); - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); - if ($v_result == 0) { - // ----- Ignored - $v_result = 1; - } + // ----- Unlink the temporary file + @unlink($v_gzip_temp_name); - // ----- Update the informations - // Nothing can be modified + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCalculateStoredFilename() + // Description : + // Based on file descriptor properties and global options, this method + // calculate the filename that will be stored in the archive. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCalculateStoredFilename(&$p_filedescr, &$p_options) + { + $v_result=1; + + // ----- Working variables + $p_filename = $p_filedescr['filename']; + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; + } else { + $p_add_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; + } else { + $p_remove_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } else { + $p_remove_all_dir = 0; + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddFileUsingTempFile() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) - { - $v_result=PCLZIP_ERR_NO_ERROR; - - // ----- Working variable - $p_filename = $p_filedescr['filename']; - - - // ----- Open the source file - if (($v_file = @fopen($p_filename, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); - return PclZip::errorCode(); - } + // ----- Look for full name change + if (isset($p_filedescr['new_full_name'])) { + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); + } else { + // ----- Look for path and/or short name change + // ----- Look for short name change + // Its when we cahnge just the filename but not the path + if (isset($p_filedescr['new_short_name'])) { + $v_path_info = pathinfo($p_filename); + $v_dir = ''; + if ($v_path_info['dirname'] != '') { + $v_dir = $v_path_info['dirname'].'/'; + } + $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; + } else { + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + } - // ----- Creates a compressed temporary file - $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; - if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { - fclose($v_file); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); - return PclZip::errorCode(); - } + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + } else if ($p_remove_dir != "") { + // ----- Look for partial path remove + if (substr($p_remove_dir, -1) != '/') { + $p_remove_dir .= "/"; + } + + if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./")) { + if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./")) { + $p_remove_dir = "./".$p_remove_dir; + } + if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./")) { + $p_remove_dir = substr($p_remove_dir, 2); + } + } + + $v_compare = PclZipUtilPathInclusion($p_remove_dir, $v_stored_filename); + if ($v_compare > 0) { + if ($v_compare == 2) { + $v_stored_filename = ""; + } else { + $v_stored_filename = substr($v_stored_filename, strlen($p_remove_dir)); + } + } + } - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = filesize($p_filename); - while ($v_size != 0) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_file, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @gzputs($v_file_compressed, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); - // ----- Close the file - @fclose($v_file); - @gzclose($v_file_compressed); + // ----- Look for path to add + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") { + $v_stored_filename = $p_add_dir.$v_stored_filename; + } else { + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } + } + } - // ----- Check the minimum file size - if (filesize($v_gzip_temp_name) < 18) { - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); - return PclZip::errorCode(); - } + // ----- Filename (reduce the path of stored name) + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); + $p_filedescr['stored_filename'] = $v_stored_filename; - // ----- Extract the compressed attributes - if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Read the gzip file header - $v_binary_data = @fread($v_file_compressed, 10); - $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); + // -------------------------------------------------------------------------------- + // Function : privWriteFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteFileHeader(&$p_header) + { + $v_result=1; - // ----- Check some parameters - $v_data_header['os'] = bin2hex($v_data_header['os']); + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->zip_fd); - // ----- Read the gzip file footer - @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); - $v_binary_data = @fread($v_file_compressed, 8); - $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; - // ----- Set the attributes - $p_header['compression'] = ord($v_data_header['cm']); - //$p_header['mtime'] = $v_data_header['mtime']; - $p_header['crc'] = $v_data_footer['crc']; - $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), $p_header['extra_len']); - // ----- Close the file - @fclose($v_file_compressed); + // ----- Write the first 148 bytes of the header in the archive + fputs($this->zip_fd, $v_binary_data, 30); - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - return $v_result; - } + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } - // ----- Add the compressed data - if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) - { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - fseek($v_file_compressed, 10); - $v_size = $p_header['compressed_size']; - while ($v_size != 0) + // -------------------------------------------------------------------------------- + // Function : privWriteCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralFileHeader(&$p_header) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_file_compressed, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + $v_result=1; - // ----- Close the file - @fclose($v_file_compressed); + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} - // ----- Unlink the temporary file - @unlink($v_gzip_temp_name); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCalculateStoredFilename() - // Description : - // Based on file descriptor properties and global options, this method - // calculate the filename that will be stored in the archive. - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privCalculateStoredFilename(&$p_filedescr, &$p_options) - { - $v_result=1; - - // ----- Working variables - $p_filename = $p_filedescr['filename']; - if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { - $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; - } - else { - $p_add_dir = ''; - } - if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { - $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; - } - else { - $p_remove_dir = ''; - } - if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - else { - $p_remove_all_dir = 0; - } + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; - // ----- Look for full name change - if (isset($p_filedescr['new_full_name'])) { - // ----- Remove drive letter if any - $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); - } - - // ----- Look for path and/or short name change - else { - - // ----- Look for short name change - // Its when we cahnge just the filename but not the path - if (isset($p_filedescr['new_short_name'])) { - $v_path_info = pathinfo($p_filename); - $v_dir = ''; - if ($v_path_info['dirname'] != '') { - $v_dir = $v_path_info['dirname'].'/'; - } - $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; - } - else { - // ----- Calculate the stored filename - $v_stored_filename = $p_filename; - } - - // ----- Look for all path to remove - if ($p_remove_all_dir) { - $v_stored_filename = basename($p_filename); - } - // ----- Look for partial path remove - else if ($p_remove_dir != "") { - if (substr($p_remove_dir, -1) != '/') - $p_remove_dir .= "/"; - - if ( (substr($p_filename, 0, 2) == "./") - || (substr($p_remove_dir, 0, 2) == "./")) { - - if ( (substr($p_filename, 0, 2) == "./") - && (substr($p_remove_dir, 0, 2) != "./")) { - $p_remove_dir = "./".$p_remove_dir; - } - if ( (substr($p_filename, 0, 2) != "./") - && (substr($p_remove_dir, 0, 2) == "./")) { - $p_remove_dir = substr($p_remove_dir, 2); - } - } - - $v_compare = PclZipUtilPathInclusion($p_remove_dir, - $v_stored_filename); - if ($v_compare > 0) { - if ($v_compare == 2) { - $v_stored_filename = ""; - } - else { - $v_stored_filename = substr($v_stored_filename, - strlen($p_remove_dir)); - } - } - } - - // ----- Remove drive letter if any - $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); - - // ----- Look for path to add - if ($p_add_dir != "") { - if (substr($p_add_dir, -1) == "/") - $v_stored_filename = $p_add_dir.$v_stored_filename; - else - $v_stored_filename = $p_add_dir."/".$v_stored_filename; - } - } + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, $p_header['version'], $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), $p_header['extra_len'], $p_header['comment_len'], $p_header['disk'], $p_header['internal'], $p_header['external'], $p_header['offset']); - // ----- Filename (reduce the path of stored name) - $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); - $p_filedescr['stored_filename'] = $v_stored_filename; - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privWriteFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privWriteFileHeader(&$p_header) - { - $v_result=1; - - // ----- Store the offset position of the file - $p_header['offset'] = ftell($this->zip_fd); - - // ----- Transform UNIX mtime to DOS format mdate/mtime - $v_date = getdate($p_header['mtime']); - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; - - // ----- Packed data - $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, - $p_header['version_extracted'], $p_header['flag'], - $p_header['compression'], $v_mtime, $v_mdate, - $p_header['crc'], $p_header['compressed_size'], - $p_header['size'], - strlen($p_header['stored_filename']), - $p_header['extra_len']); - - // ----- Write the first 148 bytes of the header in the archive - fputs($this->zip_fd, $v_binary_data, 30); - - // ----- Write the variable fields - if (strlen($p_header['stored_filename']) != 0) - { - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); - } - if ($p_header['extra_len'] != 0) - { - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); - } + // ----- Write the 42 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 46); - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privWriteCentralFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privWriteCentralFileHeader(&$p_header) - { - $v_result=1; - - // TBC - //for(reset($p_header); $key = key($p_header); next($p_header)) { - //} - - // ----- Transform UNIX mtime to DOS format mdate/mtime - $v_date = getdate($p_header['mtime']); - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; - - - // ----- Packed data - $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, - $p_header['version'], $p_header['version_extracted'], - $p_header['flag'], $p_header['compression'], - $v_mtime, $v_mdate, $p_header['crc'], - $p_header['compressed_size'], $p_header['size'], - strlen($p_header['stored_filename']), - $p_header['extra_len'], $p_header['comment_len'], - $p_header['disk'], $p_header['internal'], - $p_header['external'], $p_header['offset']); - - // ----- Write the 42 bytes of the header in the zip file - fputs($this->zip_fd, $v_binary_data, 46); - - // ----- Write the variable fields - if (strlen($p_header['stored_filename']) != 0) - { - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); - } - if ($p_header['extra_len'] != 0) - { - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); - } - if ($p_header['comment_len'] != 0) - { - fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); - } + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) { + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privWriteCentralHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) - { - $v_result=1; - - // ----- Packed data - $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, - $p_nb_entries, $p_size, - $p_offset, strlen($p_comment)); - - // ----- Write the 22 bytes of the header in the zip file - fputs($this->zip_fd, $v_binary_data, 22); - - // ----- Write the variable fields - if (strlen($p_comment) != 0) - { - fputs($this->zip_fd, $p_comment, strlen($p_comment)); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privList() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privList(&$p_list) - { - $v_result=1; - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + // -------------------------------------------------------------------------------- + // Function : privWriteCentralHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) { - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - - // ----- Return - return PclZip::errorCode(); - } + $v_result = 1; - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privSwapBackMagicQuotes(); - return $v_result; - } + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, $p_nb_entries, $p_size, $p_offset, strlen($p_comment)); - // ----- Go to beginning of Central Dir - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_central_dir['offset'])) - { - $this->privSwapBackMagicQuotes(); + // ----- Write the 22 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 22); - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Write the variable fields + if (strlen($p_comment) != 0) { + fputs($this->zip_fd, $p_comment, strlen($p_comment)); + } - // ----- Return - return PclZip::errorCode(); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Read each entry - for ($i=0; $i<$v_central_dir['entries']; $i++) + // -------------------------------------------------------------------------------- + // Function : privList() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privList(&$p_list) { - // ----- Read the file header - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) - { - $this->privSwapBackMagicQuotes(); - return $v_result; - } - $v_header['index'] = $i; - - // ----- Get the only interesting attributes - $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); - unset($v_header); - } + $v_result = 1; - // ----- Close the zip file - $this->privCloseFd(); + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privConvertHeader2FileInfo() - // Description : - // This function takes the file informations from the central directory - // entries and extract the interesting parameters that will be given back. - // The resulting file infos are set in the array $p_info - // $p_info['filename'] : Filename with full path. Given by user (add), - // extracted in the filesystem (extract). - // $p_info['stored_filename'] : Stored filename in the archive. - // $p_info['size'] = Size of the file. - // $p_info['compressed_size'] = Compressed size of the file. - // $p_info['mtime'] = Last modification date of the file. - // $p_info['comment'] = Comment associated with the file. - // $p_info['folder'] = true/false : indicates if the entry is a folder or not. - // $p_info['status'] = status of the action on the file. - // $p_info['crc'] = CRC of the file content. - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privConvertHeader2FileInfo($p_header, &$p_info) - { - $v_result=1; - - // ----- Get the interesting attributes - $v_temp_path = PclZipUtilPathReduction($p_header['filename']); - $p_info['filename'] = $v_temp_path; - $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); - $p_info['stored_filename'] = $v_temp_path; - $p_info['size'] = $p_header['size']; - $p_info['compressed_size'] = $p_header['compressed_size']; - $p_info['mtime'] = $p_header['mtime']; - $p_info['comment'] = $p_header['comment']; - $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); - $p_info['index'] = $p_header['index']; - $p_info['status'] = $p_header['status']; - $p_info['crc'] = $p_header['crc']; + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractByRule() - // Description : - // Extract a file or directory depending of rules (by index, by name, ...) - // Parameters : - // $p_file_list : An array where will be placed the properties of each - // extracted file - // $p_path : Path to add while writing the extracted files - // $p_remove_path : Path to remove (from the file memorized path) while writing the - // extracted files. If the path does not match the file path, - // the file is extracted with its memorized path. - // $p_remove_path does not apply to 'list' mode. - // $p_path and $p_remove_path are commulative. - // Return Values : - // 1 on success,0 or less on error (see error code list) - // -------------------------------------------------------------------------------- - function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) - { - $v_result=1; - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Check the path - if ( ($p_path == "") - || ( (substr($p_path, 0, 1) != "/") - && (substr($p_path, 0, 3) != "../") - && (substr($p_path,1,2)!=":/"))) - $p_path = "./".$p_path; - - // ----- Reduce the path last (and duplicated) '/' - if (($p_path != "./") && ($p_path != "/")) - { - // ----- Look for the path end '/' - while (substr($p_path, -1) == "/") - { - $p_path = substr($p_path, 0, strlen($p_path)-1); - } - } + // ----- Return + return PclZip::errorCode(); + } - // ----- Look for path to remove format (should end by /) - if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) - { - $p_remove_path .= '/'; - } - $p_remove_path_size = strlen($p_remove_path); + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privSwapBackMagicQuotes(); + return $v_result; + } - // ----- Open the zip file - if (($v_result = $this->privOpenFd('rb')) != 1) - { - $this->privSwapBackMagicQuotes(); - return $v_result; - } + // ----- Go to beginning of Central Dir + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_central_dir['offset'])) { + $this->privSwapBackMagicQuotes(); - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - return $v_result; - } + // ----- Return + return PclZip::errorCode(); + } - // ----- Start at beginning of Central Dir - $v_pos_entry = $v_central_dir['offset']; + // ----- Read each entry + for ($i=0; $i<$v_central_dir['entries']; $i++) { + // ----- Read the file header + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + $v_header['index'] = $i; - // ----- Read each entry - $j_start = 0; - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) - { + // ----- Get the only interesting attributes + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); + } - // ----- Read next Central dir entry - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_pos_entry)) - { // ----- Close the zip file $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - - // ----- Return - return PclZip::errorCode(); - } - // ----- Read the file header - $v_header = array(); - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); + // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); + // ----- Return return $v_result; - } - - // ----- Store the index - $v_header['index'] = $i; - - // ----- Store the file position - $v_pos_entry = ftell($this->zip_fd); - - // ----- Look for the specific extract rules - $v_extract = false; - - // ----- Look for extract by name rule - if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { - - // ----- Look if the filename is in the list - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { - - // ----- Look for a directory - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { - - // ----- Look if the directory is in the filename path - if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) - && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_extract = true; - } - } - // ----- Look for a filename - elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { - $v_extract = true; - } - } - } - - // ----- Look for extract by ereg rule - // ereg() is deprecated with PHP 5.3 - /* - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { - $v_extract = true; - } - } - */ - - // ----- Look for extract by preg rule - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { - - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { - $v_extract = true; - } - } - - // ----- Look for extract by index rule - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - - // ----- Look if the index is in the list - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { - - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_extract = true; - } - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; - } - - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; - } - } - } - - // ----- Look for no rule, which means extract all the archive - else { - $v_extract = true; - } - - // ----- Check compression method - if ( ($v_extract) - && ( ($v_header['compression'] != 8) - && ($v_header['compression'] != 0))) { - $v_header['status'] = 'unsupported_compression'; - - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, - "Filename '".$v_header['stored_filename']."' is " - ."compressed by an unsupported compression " - ."method (".$v_header['compression'].") "); - - return PclZip::errorCode(); - } - } - - // ----- Check encrypted files - if (($v_extract) && (($v_header['flag'] & 1) == 1)) { - $v_header['status'] = 'unsupported_encryption'; - - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, - "Unsupported encryption for " - ." filename '".$v_header['stored_filename'] - ."'"); - - return PclZip::errorCode(); - } } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privConvertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // $p_info['crc'] = CRC of the file content. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privConvertHeader2FileInfo($p_header, &$p_info) + { + $v_result=1; + + // ----- Get the interesting attributes + $v_temp_path = PclZipUtilPathReduction($p_header['filename']); + $p_info['filename'] = $v_temp_path; + $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); + $p_info['stored_filename'] = $v_temp_path; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + $p_info['crc'] = $p_header['crc']; - // ----- Look for real extraction - if (($v_extract) && ($v_header['status'] != 'ok')) { - $v_result = $this->privConvertHeader2FileInfo($v_header, - $p_file_list[$v_nb_extracted++]); - if ($v_result != 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } - - $v_extract = false; - } - - // ----- Look for real extraction - if ($v_extract) - { - - // ----- Go to the file position - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_header['offset'])) - { - // ----- Close the zip file - $this->privCloseFd(); - - $this->privSwapBackMagicQuotes(); + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // -------------------------------------------------------------------------------- + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - // ----- Return - return PclZip::errorCode(); + // ----- Check the path + if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/"))) { + $p_path = "./".$p_path; } - // ----- Look for extraction as string - if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) { + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") { + $p_path = substr($p_path, 0, strlen($p_path)-1); + } + } - $v_string = ''; + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); - // ----- Extracting the file - $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) { $this->privSwapBackMagicQuotes(); - return $v_result1; - } + return $v_result; + } - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) - { + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result; - } - - // ----- Set the file content - $p_file_list[$v_nb_extracted]['content'] = $v_string; - - // ----- Next extracted file - $v_nb_extracted++; - - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } - } - // ----- Look for extraction in standard output - elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) - && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { - // ----- Extracting the file in standard output - $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } + } - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } - } - // ----- Look for normal extraction - else { - // ----- Extracting the file - $v_result1 = $this->privExtractFile($v_header, - $p_path, $p_remove_path, - $p_remove_all_path, - $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } + // ----- Read each entry + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { + // ----- Read next Central dir entry + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - return $v_result; - } + // ----- Return + return PclZip::errorCode(); + } - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } - } - } - } + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + return $v_result; + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFile() - // Description : - // Parameters : - // Return Values : - // - // 1 : ... ? - // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback - // -------------------------------------------------------------------------------- - function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) - { - $v_result=1; - - // ----- Read the file header - if (($v_result = $this->privReadFileHeader($v_header)) != 1) - { - // ----- Return - return $v_result; - } + // ----- Store the index + $v_header['index'] = $i; + + // ----- Store the file position + $v_pos_entry = ftell($this->zip_fd); + + // ----- Look for the specific extract rules + $v_extract = false; + + // ----- Look for extract by name rule + if ((isset($p_options[PCLZIP_OPT_BY_NAME])) && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + // ----- Look if the directory is in the filename path + if ((strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_extract = true; + } + } elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + // ----- Look for a filename + $v_extract = true; + } + } + } + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + */ + else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + // ----- Look for extract by preg rule + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } else if ((isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + // ----- Look for extract by index rule + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } else { + // ----- Look for no rule, which means extract all the archive + $v_extract = true; + } + // ----- Check compression method + if (($v_extract) && (($v_header['compression'] != 8) && ($v_header['compression'] != 0))) { + $v_header['status'] = 'unsupported_compression'; - // ----- Check that the file header is coherent with $p_entry info - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC - } + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { - // ----- Look for all path to remove - if ($p_remove_all_path == true) { - // ----- Look for folder entry that not need to be extracted - if (($p_entry['external']&0x00000010)==0x00000010) { + $this->privSwapBackMagicQuotes(); - $p_entry['status'] = "filtered"; + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, "Filename '".$v_header['stored_filename']."' is compressed by an unsupported compression method (".$v_header['compression'].") "); - return $v_result; - } + return PclZip::errorCode(); + } + } - // ----- Get the basename of the path - $p_entry['filename'] = basename($p_entry['filename']); - } + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + $v_header['status'] = 'unsupported_encryption'; + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { + $this->privSwapBackMagicQuotes(); - // ----- Look for path to remove - else if ($p_remove_path != "") - { - if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) - { + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, "Unsupported encryption for filename '".$v_header['stored_filename']."'"); - // ----- Change the file status - $p_entry['status'] = "filtered"; + return PclZip::errorCode(); + } + } - // ----- Return - return $v_result; - } + // ----- Look for real extraction + if (($v_extract) && ($v_header['status'] != 'ok')) { + $v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++]); + if ($v_result != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } - $p_remove_path_size = strlen($p_remove_path); - if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) - { + $v_extract = false; + } - // ----- Remove the path - $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + // ----- Look for real extraction + if ($v_extract) { + // ----- Go to the file position + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for extraction as string + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { + $v_string = ''; + + // ----- Extracting the file + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; + + // ----- Next extracted file + $v_nb_extracted++; + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for extraction in standard output + elseif ((isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Extracting the file in standard output + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } else { + // ----- Look for normal extraction + // ----- Extracting the file + $v_result1 = $this->privExtractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + } + } - } - } + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - // ----- Add the path - if ($p_path != '') { - $p_entry['filename'] = $p_path."/".$p_entry['filename']; - } - - // ----- Check a base_dir_restriction - if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { - $v_inclusion - = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], - $p_entry['filename']); - if ($v_inclusion == 0) { - - PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, - "Filename '".$p_entry['filename']."' is " - ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); - - return PclZip::errorCode(); - } + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFile() + // Description : + // Parameters : + // Return Values : + // + // 1 : ... ? + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback + // -------------------------------------------------------------------------------- + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; - // ----- Look for pre-extract callback - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } - - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } - - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; - } + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + // ----- Return + return $v_result; + } - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } - // ----- Look for specific actions while the file exist - if (file_exists($p_entry['filename'])) - { + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Look for folder entry that not need to be extracted + if (($p_entry['external']&0x00000010)==0x00000010) { + $p_entry['status'] = "filtered"; - // ----- Look if file is a directory - if (is_dir($p_entry['filename'])) - { + return $v_result; + } - // ----- Change the file status - $p_entry['status'] = "already_a_directory"; - - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); + } else if ($p_remove_path != "") { + // ----- Look for path to remove + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) { + // ----- Change the file status + $p_entry['status'] = "filtered"; - PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, - "Filename '".$p_entry['filename']."' is " - ."already used by an existing directory"); + // ----- Return + return $v_result; + } - return PclZip::errorCode(); + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) { + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); } - } - // ----- Look if file is write protected - else if (!is_writeable($p_entry['filename'])) - { + } - // ----- Change the file status - $p_entry['status'] = "write_protected"; + // ----- Add the path + if ($p_path != '') { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; + } - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Check a base_dir_restriction + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { + $v_inclusion = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], $p_entry['filename']); + if ($v_inclusion == 0) { + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,"Filename '".$p_entry['filename']."' is outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Filename '".$p_entry['filename']."' exists " - ."and is write protected"); + return PclZip::errorCode(); + } + } - return PclZip::errorCode(); + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; } - } - - // ----- Look if the extracted file is older - else if (filemtime($p_entry['filename']) > $p_entry['mtime']) - { - // ----- Change the file status - if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) - && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; } - else { - $p_entry['status'] = "newer_exist"; - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Newer version of '".$p_entry['filename']."' exists " - ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) { + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) { + + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, "Filename '".$p_entry['filename']."' is already used by an existing directory"); + return PclZip::errorCode(); + } + } else if (!is_writeable($p_entry['filename'])) { + // ----- Look if file is write protected + // ----- Change the file status + $p_entry['status'] = "write_protected"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Filename '".$p_entry['filename']."' exists and is write protected"); + return PclZip::errorCode(); + } + } else if (filemtime($p_entry['filename']) > $p_entry['mtime']) { + // ----- Look if the extracted file is older + // ----- Change the file status + if ((isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) && ($p_options[PCLZIP_OPT_REPLACE_NEWER] === true)) { + } else { + $p_entry['status'] = "newer_exist"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Newer version of '".$p_entry['filename']."' exists and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + return PclZip::errorCode(); + } + } + } else { + } + } else { + // ----- Check the directory availability and create it if necessary + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) { + $v_dir_to_check = $p_entry['filename']; + } + else if (!strstr($p_entry['filename'], "/")) { + $v_dir_to_check = ""; + } + else { + $v_dir_to_check = dirname($p_entry['filename']); + } + + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + //return $v_result; + $v_result = 1; + } + } + } - return PclZip::errorCode(); - } + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010) == 0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compression'] == 0) { + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + // ----- Change the file status + $p_entry['status'] = "write_error"; + + // ----- Return + return $v_result; + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + /* Try to speed up the code + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + */ + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Closing the destination file + fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + } else { + // ----- TBC + // Need to be finished + if (($p_entry['flag'] & 1) == 1) { + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); + return PclZip::errorCode(); + } + + // ----- Look for using temporary file to unzip + if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } else { + // ----- Look for extract in memory + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = @gzinflate($v_buffer); + unset($v_buffer); + if ($v_file_content === FALSE) { + + // ----- Change the file status + // TBC + $p_entry['status'] = "error"; + + return $v_result; + } + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + } + + // ----- Change the file mtime + @touch($p_entry['filename'], $p_entry['mtime']); + } + + // ----- Look for chmod option + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { + // ----- Change the mode of the file + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + } } - } - else { - } - } + } - // ----- Check the directory availability and create it if necessary - else { - if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) - $v_dir_to_check = $p_entry['filename']; - else if (!strstr($p_entry['filename'], "/")) - $v_dir_to_check = ""; - else - $v_dir_to_check = dirname($p_entry['filename']); - - if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { - - // ----- Change the file status - $p_entry['status'] = "path_creation_fail"; - - // ----- Return - //return $v_result; - $v_result = 1; - } - } - } + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + // ----- Look for post-extract callback + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) - { - // ----- Look for not compressed file - if ($p_entry['compression'] == 0) { + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) - { + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- - // ----- Change the file status - $p_entry['status'] = "write_error"; + // -------------------------------------------------------------------------------- + // Function : privExtractFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileUsingTempFile(&$p_entry, &$p_options) + { + $v_result=1; - // ----- Return - return $v_result; - } + // ----- Creates a temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + // ----- Write gz file format header + $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); + @fwrite($v_dest_file, $v_binary_data, 10); - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = $p_entry['compressed_size']; - while ($v_size != 0) - { + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($this->zip_fd, $v_read_size); - /* Try to speed up the code - $v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_binary_data, $v_read_size); - */ - @fwrite($v_dest_file, $v_buffer, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); $v_size -= $v_read_size; - } + } - // ----- Closing the destination file - fclose($v_dest_file); + // ----- Write gz file format footer + $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); + @fwrite($v_dest_file, $v_binary_data, 8); - // ----- Change the file mtime - touch($p_entry['filename'], $p_entry['mtime']); - + // ----- Close the temporary file + @fclose($v_dest_file); + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + $p_entry['status'] = "write_error"; + return $v_result; } - else { - // ----- TBC - // Need to be finished - if (($p_entry['flag'] & 1) == 1) { - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); + + // ----- Open the temporary gz file + if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { + @fclose($v_dest_file); + $p_entry['status'] = "read_error"; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); return PclZip::errorCode(); - } + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($v_src_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + @fclose($v_dest_file); + @gzclose($v_src_file); + + // ----- Delete the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileInOutput() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileInOutput(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + return $v_result; + } + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } - // ----- Look for using temporary file to unzip - if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { - $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); - if ($v_result < PCLZIP_ERR_NO_ERROR) { - return $v_result; - } - } - - // ----- Look for extract in memory - else { - - - // ----- Read the compressed file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - $v_file_content = @gzinflate($v_buffer); - unset($v_buffer); - if ($v_file_content === FALSE) { - - // ----- Change the file status - // TBC - $p_entry['status'] = "error"; - - return $v_result; + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; } - - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - - // ----- Change the file status - $p_entry['status'] = "write_error"; - - return $v_result; + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; } - - // ----- Write the uncompressed data - @fwrite($v_dest_file, $v_file_content, $p_entry['size']); - unset($v_file_content); - - // ----- Closing the destination file - @fclose($v_dest_file); - - } - // ----- Change the file mtime - @touch($p_entry['filename'], $p_entry['mtime']); + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; } - // ----- Look for chmod option - if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { + // ----- Trace - // ----- Change the mode of the file - @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); - } + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) { - } - } + // ----- Read the file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; - } - - // ----- Look for post-extract callback - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; - } - } + // ----- Send the file to the output + echo $v_buffer; + unset($v_buffer); + } else { - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFileUsingTempFile() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privExtractFileUsingTempFile(&$p_entry, &$p_options) - { - $v_result=1; - - // ----- Creates a temporary file - $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; - if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { - fclose($v_file); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); - return PclZip::errorCode(); - } + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); - // ----- Write gz file format header - $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); - @fwrite($v_dest_file, $v_binary_data, 10); + // ----- Send the file to the output + echo $v_file_content; + unset($v_file_content); + } + } + } - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = $p_entry['compressed_size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + // ----- Look for post-extract callback - // ----- Write gz file format footer - $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); - @fwrite($v_dest_file, $v_binary_data, 8); + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - // ----- Close the temporary file - @fclose($v_dest_file); + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - $p_entry['status'] = "write_error"; - return $v_result; - } + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } - // ----- Open the temporary gz file - if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { - @fclose($v_dest_file); - $p_entry['status'] = "read_error"; - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); + return $v_result; } + // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // Function : privExtractFileAsString() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) + { + $v_result=1; - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = $p_entry['size']; - while ($v_size != 0) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($v_src_file, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - @fclose($v_dest_file); - @gzclose($v_src_file); - - // ----- Delete the temporary file - @unlink($v_gzip_temp_name); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFileInOutput() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privExtractFileInOutput(&$p_entry, &$p_options) - { - $v_result=1; - - // ----- Read the file header - if (($v_result = $this->privReadFileHeader($v_header)) != 1) { - return $v_result; - } + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + // ----- Return + return $v_result; + } + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } - // ----- Check that the file header is coherent with $p_entry info - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC - } + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } - // ----- Look for pre-extract callback - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } - - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } - - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; - } + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } - // ----- Trace + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + // if ($p_entry['compressed_size'] == $p_entry['size']) + if ($p_entry['compression'] == 0) { + + // ----- Reading the file + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + } else { + + // ----- Reading the file + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + if (($p_string = @gzinflate($v_data)) === FALSE) { + // TBC + } + } + // ----- Trace + } else { + // TBC : error : can not extract a folder in a string + } + } - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) { - // ----- Look for not compressed file - if ($p_entry['compressed_size'] == $p_entry['size']) { + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + // ----- Look for post-extract callback + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - // ----- Read the file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + // ----- Swap the content to header + $v_local_header['content'] = $p_string; + $p_string = ''; - // ----- Send the file to the output - echo $v_buffer; - unset($v_buffer); - } - else { + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - // ----- Read the compressed file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - $v_file_content = gzinflate($v_buffer); - unset($v_buffer); + // ----- Swap back the content to header + $p_string = $v_local_header['content']; + unset($v_local_header['content']); - // ----- Send the file to the output - echo $v_file_content; - unset($v_file_content); + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } } - } - } - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Look for post-extract callback - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + // -------------------------------------------------------------------------------- + // Function : privReadFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadFileHeader(&$p_header) + { + $v_result=1; - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + // ----- Check signature + if ($v_data['id'] != 0x04034b50) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; - } - } + // ----- Return + return PclZip::errorCode(); + } - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFileAsString() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) - { - $v_result=1; - - // ----- Read the file header - $v_header = array(); - if (($v_result = $this->privReadFileHeader($v_header)) != 1) - { - // ----- Return - return $v_result; - } + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 26); + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; - // ----- Check that the file header is coherent with $p_entry info - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC - } + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); - // ----- Look for pre-extract callback - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } - - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } - - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; - } + // ----- Return + return PclZip::errorCode(); + } + // ----- Extract the values + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { + // ----- Get filename + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) { - // ----- Look for not compressed file - // if ($p_entry['compressed_size'] == $p_entry['size']) - if ($p_entry['compression'] == 0) { - - // ----- Reading the file - $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + // ----- Get extra_fields + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); + } else { + $p_header['extra'] = ''; } - else { - - // ----- Reading the file - $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - if (($p_string = @gzinflate($v_data)) === FALSE) { - // TBC - } - } - - // ----- Trace - } - else { - // TBC : error : can not extract a folder in a string - } - - } - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; - } - - // ----- Look for post-extract callback - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Swap the content to header - $v_local_header['content'] = $p_string; - $p_string = ''; - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - - // ----- Swap back the content to header - $p_string = $v_local_header['content']; - unset($v_local_header['content']); - - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; - } - } + // ----- Extract properties + $p_header['version_extracted'] = $v_data['version']; + $p_header['compression'] = $v_data['compression']; + $p_header['size'] = $v_data['size']; + $p_header['compressed_size'] = $v_data['compressed_size']; + $p_header['crc'] = $v_data['crc']; + $p_header['flag'] = $v_data['flag']; + $p_header['filename_len'] = $v_data['filename_len']; + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } else { + $p_header['mtime'] = time(); + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privReadFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privReadFileHeader(&$p_header) - { - $v_result=1; - - // ----- Read the 4 bytes signature - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = unpack('Vid', $v_binary_data); - - // ----- Check signature - if ($v_data['id'] != 0x04034b50) - { + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + //} - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; - // ----- Return - return PclZip::errorCode(); - } + // ----- Set the status field + $p_header['status'] = "ok"; - // ----- Read the first 42 bytes of the header - $v_binary_data = fread($this->zip_fd, 26); + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- - // ----- Look for invalid block size - if (strlen($v_binary_data) != 26) + // -------------------------------------------------------------------------------- + // Function : privReadCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadCentralFileHeader(&$p_header) { - $p_header['filename'] = ""; - $p_header['status'] = "invalid_header"; + $v_result = 1; - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); - // ----- Return - return PclZip::errorCode(); - } + // ----- Check signature + if ($v_data['id'] != 0x02014b50) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); - // ----- Extract the values - $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + // ----- Return + return PclZip::errorCode(); + } - // ----- Get filename - $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 42); - // ----- Get extra_fields - if ($v_data['extra_len'] != 0) { - $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); - } - else { - $p_header['extra'] = ''; - } + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; - // ----- Extract properties - $p_header['version_extracted'] = $v_data['version']; - $p_header['compression'] = $v_data['compression']; - $p_header['size'] = $v_data['size']; - $p_header['compressed_size'] = $v_data['compressed_size']; - $p_header['crc'] = $v_data['crc']; - $p_header['flag'] = $v_data['flag']; - $p_header['filename_len'] = $v_data['filename_len']; - - // ----- Recuperate date in UNIX format - $p_header['mdate'] = $v_data['mdate']; - $p_header['mtime'] = $v_data['mtime']; - if ($p_header['mdate'] && $p_header['mtime']) - { - // ----- Extract time - $v_hour = ($p_header['mtime'] & 0xF800) >> 11; - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; - $v_seconde = ($p_header['mtime'] & 0x001F)*2; + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); - // ----- Extract date - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; - $v_month = ($p_header['mdate'] & 0x01E0) >> 5; - $v_day = $p_header['mdate'] & 0x001F; + // ----- Return + return PclZip::errorCode(); + } - // ----- Get UNIX date format - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + // ----- Extract the values + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); - } - else - { - $p_header['mtime'] = time(); - } + // ----- Get filename + if ($p_header['filename_len'] != 0) { + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); + } else { + $p_header['filename'] = ''; + } - // TBC - //for(reset($v_data); $key = key($v_data); next($v_data)) { - //} + // ----- Get extra + if ($p_header['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); + } else { + $p_header['extra'] = ''; + } - // ----- Set the stored filename - $p_header['stored_filename'] = $p_header['filename']; + // ----- Get comment + if ($p_header['comment_len'] != 0) { + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); + } + else { + $p_header['comment'] = ''; + } - // ----- Set the status field - $p_header['status'] = "ok"; + // ----- Extract properties - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privReadCentralFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privReadCentralFileHeader(&$p_header) - { - $v_result=1; - - // ----- Read the 4 bytes signature - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = unpack('Vid', $v_binary_data); - - // ----- Check signature - if ($v_data['id'] != 0x02014b50) - { + // ----- Recuperate date in UNIX format + //if ($p_header['mdate'] && $p_header['mtime']) + // TBC : bug : this was ignoring time with 0/0/0 + if (1) { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; - // ----- Return - return PclZip::errorCode(); - } + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); - // ----- Read the first 42 bytes of the header - $v_binary_data = fread($this->zip_fd, 42); + } else { + $p_header['mtime'] = time(); + } - // ----- Look for invalid block size - if (strlen($v_binary_data) != 42) - { - $p_header['filename'] = ""; - $p_header['status'] = "invalid_header"; + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + // ----- Set default status to ok + $p_header['status'] = 'ok'; + + // ----- Look if it is a directory + if (substr($p_header['filename'], -1) == '/') { + //$p_header['external'] = 0x41FF0010; + $p_header['external'] = 0x00000010; + } - // ----- Return - return PclZip::errorCode(); - } - // ----- Extract the values - $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); - - // ----- Get filename - if ($p_header['filename_len'] != 0) - $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); - else - $p_header['filename'] = ''; - - // ----- Get extra - if ($p_header['extra_len'] != 0) - $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); - else - $p_header['extra'] = ''; - - // ----- Get comment - if ($p_header['comment_len'] != 0) - $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); - else - $p_header['comment'] = ''; - - // ----- Extract properties - - // ----- Recuperate date in UNIX format - //if ($p_header['mdate'] && $p_header['mtime']) - // TBC : bug : this was ignoring time with 0/0/0 - if (1) + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCheckFileHeaders() + // Description : + // Parameters : + // Return Values : + // 1 on success, + // 0 on error; + // -------------------------------------------------------------------------------- + function privCheckFileHeaders(&$p_local_header, &$p_central_header) { - // ----- Extract time - $v_hour = ($p_header['mtime'] & 0xF800) >> 11; - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; - $v_seconde = ($p_header['mtime'] & 0x001F)*2; + $v_result=1; - // ----- Extract date - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; - $v_month = ($p_header['mdate'] & 0x01E0) >> 5; - $v_day = $p_header['mdate'] & 0x001F; + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + } - // ----- Get UNIX date format - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { + $p_local_header['size'] = $p_central_header['size']; + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + $p_local_header['crc'] = $p_central_header['crc']; + } + // ----- Return + return $v_result; } - else + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadEndCentralDir() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadEndCentralDir(&$p_central_dir) { - $p_header['mtime'] = time(); - } + $v_result=1; + + // ----- Go to the end of the zip file + $v_size = filesize($this->zipname); + @fseek($this->zip_fd, $v_size); + if (@ftell($this->zip_fd) != $v_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); - // ----- Set the stored filename - $p_header['stored_filename'] = $p_header['filename']; + // ----- Return + return PclZip::errorCode(); + } - // ----- Set default status to ok - $p_header['status'] = 'ok'; + // ----- First try : look if this is an archive with no commentaries (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + @fseek($this->zip_fd, $v_size-22); + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); - // ----- Look if it is a directory - if (substr($p_header['filename'], -1) == '/') { - //$p_header['external'] = 0x41FF0010; - $p_header['external'] = 0x00000010; - } + // ----- Return + return PclZip::errorCode(); + } + // ----- Read for bytes + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = @unpack('Vid', $v_binary_data); - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCheckFileHeaders() - // Description : - // Parameters : - // Return Values : - // 1 on success, - // 0 on error; - // -------------------------------------------------------------------------------- - function privCheckFileHeaders(&$p_local_header, &$p_central_header) - { - $v_result=1; - - // ----- Check the static values - // TBC - if ($p_local_header['filename'] != $p_central_header['filename']) { - } - if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { - } - if ($p_local_header['flag'] != $p_central_header['flag']) { - } - if ($p_local_header['compression'] != $p_central_header['compression']) { - } - if ($p_local_header['mtime'] != $p_central_header['mtime']) { - } - if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { - } - - // ----- Look for flag bit 3 - if (($p_local_header['flag'] & 8) == 8) { - $p_local_header['size'] = $p_central_header['size']; - $p_local_header['compressed_size'] = $p_central_header['compressed_size']; - $p_local_header['crc'] = $p_central_header['crc']; - } + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privReadEndCentralDir() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privReadEndCentralDir(&$p_central_dir) - { - $v_result=1; - - // ----- Go to the end of the zip file - $v_size = filesize($this->zipname); - @fseek($this->zip_fd, $v_size); - if (@ftell($this->zip_fd) != $v_size) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); + $v_pos = ftell($this->zip_fd); + } - // ----- Return - return PclZip::errorCode(); - } + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); - // ----- First try : look if this is an archive with no commentaries (most of the time) - // in this case the end of central dir is at 22 bytes of the file end - $v_found = 0; - if ($v_size > 26) { - @fseek($this->zip_fd, $v_size-22); - if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + // ----- Return + return PclZip::errorCode(); + } - // ----- Return - return PclZip::errorCode(); - } + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) { + // ----- Read a byte + $v_byte = @fread($this->zip_fd, 1); + + // ----- Add the byte + //$v_bytes = ($v_bytes << 8) | Ord($v_byte); + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. + $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); + + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) + { + $v_pos++; + break; + } + + $v_pos++; + } - // ----- Read for bytes - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = @unpack('Vid', $v_binary_data); + // ----- Look if not found end of central dir + if ($v_pos == $v_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); - // ----- Check signature - if ($v_data['id'] == 0x06054b50) { - $v_found = 1; - } + // ----- Return + return PclZip::errorCode(); + } + } - $v_pos = ftell($this->zip_fd); - } + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->zip_fd, 18); - // ----- Go back to the maximum possible size of the Central Dir End Record - if (!$v_found) { - $v_maximum_size = 65557; // 0xFFFF + 22; - if ($v_maximum_size > $v_size) - $v_maximum_size = $v_size; - @fseek($this->zip_fd, $v_size-$v_maximum_size); - if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); - // ----- Return - return PclZip::errorCode(); - } + // ----- Return + return PclZip::errorCode(); + } - // ----- Read byte per byte in order to find the signature - $v_pos = ftell($this->zip_fd); - $v_bytes = 0x00000000; - while ($v_pos < $v_size) - { - // ----- Read a byte - $v_byte = @fread($this->zip_fd, 1); + // ----- Extract the values + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); - // ----- Add the byte - //$v_bytes = ($v_bytes << 8) | Ord($v_byte); - // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number - // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. - $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); + // ----- Check the global size + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'The central dir is not at the end of the archive. Some trailing bytes exists after the archive.'); - // ----- Compare the bytes - if ($v_bytes == 0x504b0506) - { - $v_pos++; - break; + // ----- Return + return PclZip::errorCode(); + } } - $v_pos++; - } + // ----- Get comment + if ($v_data['comment_size'] != 0) { + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); + } else { + $p_central_dir['comment'] = ''; + } - // ----- Look if not found end of central dir - if ($v_pos == $v_size) - { + $p_central_dir['entries'] = $v_data['entries']; + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + $p_central_dir['offset'] = $v_data['offset']; + $p_central_dir['size'] = $v_data['size']; + $p_central_dir['disk'] = $v_data['disk']; + $p_central_dir['disk_start'] = $v_data['disk_start']; - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); + // TBC + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { + //} // ----- Return - return PclZip::errorCode(); - } + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Read the first 18 bytes of the header - $v_binary_data = fread($this->zip_fd, 18); - - // ----- Look for invalid block size - if (strlen($v_binary_data) != 18) + // -------------------------------------------------------------------------------- + // Function : privDeleteByRule() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDeleteByRule(&$p_result_list, &$p_options) { + $v_result=1; + $v_list_detail = array(); - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) { + // ----- Return + return $v_result; + } - // ----- Return - return PclZip::errorCode(); - } + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privCloseFd(); + return $v_result; + } - // ----- Extract the values - $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); - - // ----- Check the global size - if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { - - // ----- Removed in release 2.2 see readme file - // The check of the file size is a little too strict. - // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. - // While decrypted, zip has training 0 bytes - if (0) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, - 'The central dir is not at the end of the archive.' - .' Some trailing bytes exists after the archive.'); - - // ----- Return - return PclZip::errorCode(); - } - } + // ----- Go to beginning of File + @rewind($this->zip_fd); - // ----- Get comment - if ($v_data['comment_size'] != 0) { - $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); - } - else - $p_central_dir['comment'] = ''; + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) { + // ----- Close the zip file + $this->privCloseFd(); - $p_central_dir['entries'] = $v_data['entries']; - $p_central_dir['disk_entries'] = $v_data['disk_entries']; - $p_central_dir['offset'] = $v_data['offset']; - $p_central_dir['size'] = $v_data['size']; - $p_central_dir['disk'] = $v_data['disk']; - $p_central_dir['disk_start'] = $v_data['disk_start']; + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - // TBC - //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { - //} + // ----- Return + return PclZip::errorCode(); + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDeleteByRule() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privDeleteByRule(&$p_result_list, &$p_options) - { - $v_result=1; - $v_list_detail = array(); - - // ----- Open the zip file - if (($v_result=$this->privOpenFd('rb')) != 1) - { - // ----- Return - return $v_result; - } + // ----- Read each entry + $v_header_list = array(); + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); - return $v_result; - } + return $v_result; + } - // ----- Go to beginning of File - @rewind($this->zip_fd); - // ----- Scan all the files - // ----- Start at beginning of Central Dir - $v_pos_entry = $v_central_dir['offset']; - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_pos_entry)) - { - // ----- Close the zip file - $this->privCloseFd(); + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; + + // ----- Look for the specific extract rules + $v_found = false; + + // ----- Look for extract by name rule + if ((isset($p_options[PCLZIP_OPT_BY_NAME])) && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + // ----- Look if the directory is in the filename path + if ((strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } elseif ((($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_found = true; + } + } + } + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + */ + else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) + // ----- Look for extract by preg rule + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } else if ((isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + // ----- Look for extract by index rule + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } else { + $v_found = true; + } - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Look for deletion + if ($v_found) { + unset($v_header_list[$v_nb_extracted]); + } else { + $v_nb_extracted++; + } + } - // ----- Return - return PclZip::errorCode(); - } + // ----- Look if something need to be deleted + if ($v_nb_extracted > 0) { + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - // ----- Read each entry - $v_header_list = array(); - $j_start = 0; - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) - { + // ----- Creates a temporary zip archive + $v_temp_zip = new PclZip($v_zip_temp_name); - // ----- Read the file header - $v_header_list[$v_nb_extracted] = array(); - if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { + $this->privCloseFd(); - return $v_result; - } - - - // ----- Store the index - $v_header_list[$v_nb_extracted]['index'] = $i; - - // ----- Look for the specific extract rules - $v_found = false; - - // ----- Look for extract by name rule - if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { - - // ----- Look if the filename is in the list - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { - - // ----- Look for a directory - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { - - // ----- Look if the directory is in the filename path - if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) - && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_found = true; - } - elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ - && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_found = true; - } - } - // ----- Look for a filename - elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { - $v_found = true; - } - } - } - - // ----- Look for extract by ereg rule - // ereg() is deprecated with PHP 5.3 - /* - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { - $v_found = true; - } - } - */ - - // ----- Look for extract by preg rule - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { - - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { - $v_found = true; - } - } - - // ----- Look for extract by index rule - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - - // ----- Look if the index is in the list - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { - - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_found = true; - } - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; - } - - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; - } - } - } - else { - $v_found = true; - } - - // ----- Look for deletion - if ($v_found) - { - unset($v_header_list[$v_nb_extracted]); - } - else - { - $v_nb_extracted++; - } - } + // ----- Return + return $v_result; + } - // ----- Look if something need to be deleted - if ($v_nb_extracted > 0) { + // ----- Look which file need to be kept + for ($i=0; $i<sizeof($v_header_list); $i++) { + // ----- Calculate the position of the header + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_local_header = array(); + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Check that local file header is same as central file header + if ($this->privCheckFileHeaders($v_local_header, $v_header_list[$i]) != 1) { + // TBC + } + unset($v_local_header); + + // ----- Write the file header + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Read/write the data block + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + } - // ----- Creates a temporay file - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->zip_fd); - // ----- Creates a temporary zip archive - $v_temp_zip = new PclZip($v_zip_temp_name); + // ----- Re-Create the Central Dir files header + for ($i=0; $i<sizeof($v_header_list); $i++) { + // ----- Create the file header + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); - // ----- Open the temporary zip file in write mode - if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { - $this->privCloseFd(); + // ----- Return + return $v_result; + } - // ----- Return - return $v_result; - } + // ----- Transform the header to a 'usable' info + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } - // ----- Look which file need to be kept - for ($i=0; $i<sizeof($v_header_list); $i++) { - // ----- Calculate the position of the header - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; - // ----- Return - return PclZip::errorCode(); + // ----- Create the central dir footer + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; } - // ----- Read the file header - $v_local_header = array(); - if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Close + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); - // ----- Return + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } else if ($v_central_dir['entries'] != 0) { + // ----- Remove every files : reset the file + $this->privCloseFd(); + + if (($v_result = $this->privOpenFd('wb')) != 1) { return $v_result; } - - // ----- Check that local file header is same as central file header - if ($this->privCheckFileHeaders($v_local_header, - $v_header_list[$i]) != 1) { - // TBC - } - unset($v_local_header); - - // ----- Write the file header - if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); - // ----- Return + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { return $v_result; } - // ----- Read/write the data block - if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + $this->privCloseFd(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // -------------------------------------------------------------------------------- + function privDirCheck($p_dir, $p_is_dir=false) + { + $v_result = 1; + - // ----- Return - return $v_result; - } + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1)=='/')) { + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); } - // ----- Store the offset of the central dir - $v_offset = @ftell($v_temp_zip->zip_fd); + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) { + return 1; + } - // ----- Re-Create the Central Dir files header - for ($i=0; $i<sizeof($v_header_list); $i++) { - // ----- Create the file header - if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); - // ----- Return - return $v_result; + // ----- Just a check + if ($p_parent_dir != $p_dir) { + // ----- Look for parent directory + if ($p_parent_dir != "") { + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) { + return $v_result; + } } - - // ----- Transform the header to a 'usable' info - $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); } + // ----- Create the directory + if (!@mkdir($p_dir, 0777)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); - // ----- Zip file comment - $v_comment = ''; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + // ----- Return + return PclZip::errorCode(); } - // ----- Calculate the size of the central header - $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- - // ----- Create the central dir footer - if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { - // ----- Reset the file list - unset($v_header_list); - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($v_zip_temp_name); + // -------------------------------------------------------------------------------- + // Function : privMerge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privMerge(&$p_archive_to_add) + { + $v_result=1; + + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->zipname)) { + + // ----- Nothing to merge, so merge is a success + $v_result = 1; // ----- Return return $v_result; } - // ----- Close - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - - // ----- Delete the zip file - // TBC : I should test the result ... - @unlink($this->zipname); + // ----- Look if the archive exists + if (!is_file($this->zipname)) { - // ----- Rename the temporary file - // TBC : I should test the result ... - //@rename($v_zip_temp_name, $this->zipname); - PclZipUtilRename($v_zip_temp_name, $this->zipname); - - // ----- Destroy the temporary archive - unset($v_temp_zip); - } - - // ----- Remove every files : reset the file - else if ($v_central_dir['entries'] != 0) { - $this->privCloseFd(); + // ----- Do a duplicate + $v_result = $this->privDuplicate($p_archive_to_add->zipname); - if (($v_result = $this->privOpenFd('wb')) != 1) { - return $v_result; + // ----- Return + return $v_result; } - if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { - return $v_result; + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) { + // ----- Return + return $v_result; } - $this->privCloseFd(); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDirCheck() - // Description : - // Check if a directory exists, if not it creates it and all the parents directory - // which may be useful. - // Parameters : - // $p_dir : Directory path to check. - // Return Values : - // 1 : OK - // -1 : Unable to create directory - // -------------------------------------------------------------------------------- - function privDirCheck($p_dir, $p_is_dir=false) - { - $v_result = 1; - - - // ----- Remove the final '/' - if (($p_is_dir) && (substr($p_dir, -1)=='/')) - { - $p_dir = substr($p_dir, 0, strlen($p_dir)-1); - } + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privCloseFd(); + return $v_result; + } - // ----- Check the directory availability - if ((is_dir($p_dir)) || ($p_dir == "")) - { - return 1; - } + // ----- Go to beginning of File + @rewind($this->zip_fd); - // ----- Extract parent directory - $p_parent_dir = dirname($p_dir); + // ----- Open the archive_to_add file + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) { + $this->privCloseFd(); - // ----- Just a check - if ($p_parent_dir != $p_dir) - { - // ----- Look for parent directory - if ($p_parent_dir != "") - { - if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) - { - return $v_result; - } - } - } + // ----- Return + return $v_result; + } - // ----- Create the directory - if (!@mkdir($p_dir, 0777)) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); - // ----- Return - return PclZip::errorCode(); - } + return $v_result; + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privMerge() - // Description : - // If $p_archive_to_add does not exist, the function exit with a success result. - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privMerge(&$p_archive_to_add) - { - $v_result=1; - - // ----- Look if the archive_to_add exists - if (!is_file($p_archive_to_add->zipname)) - { + // ----- Go to beginning of File + @rewind($p_archive_to_add->zip_fd); - // ----- Nothing to merge, so merge is a success - $v_result = 1; + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - // ----- Return - return $v_result; - } + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); - // ----- Look if the archive exists - if (!is_file($this->zipname)) - { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); - // ----- Do a duplicate - $v_result = $this->privDuplicate($p_archive_to_add->zipname); + // ----- Return + return PclZip::errorCode(); + } - // ----- Return - return $v_result; - } + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - // ----- Open the zip file - if (($v_result=$this->privOpenFd('rb')) != 1) - { - // ----- Return - return $v_result; - } + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); - return $v_result; - } + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); - // ----- Go to beginning of File - @rewind($this->zip_fd); + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - // ----- Open the archive_to_add file - if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) - { - $this->privCloseFd(); + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - // ----- Return - return $v_result; - } + // ----- Merge the file comments + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; - // ----- Read the central directory informations - $v_central_dir_to_add = array(); - if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd)-$v_offset; - return $v_result; - } + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; - // ----- Go to beginning of File - @rewind($p_archive_to_add->zip_fd); + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + @fclose($v_zip_temp_fd); + $this->zip_fd = null; - // ----- Creates a temporay file - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + // ----- Reset the file list + unset($v_header_list); - // ----- Open the temporary file in write mode - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); + // ----- Return + return $v_result; + } - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; - // ----- Return - return PclZip::errorCode(); - } + // ----- Close + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); - // ----- Copy the files from the archive to the temporary file - // TBC : Here I should better append the file and go back to erase the central dir - $v_size = $v_central_dir['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Close the temporary file + @fclose($v_zip_temp_fd); - // ----- Copy the files from the archive_to_add into the temporary file - $v_size = $v_central_dir_to_add['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); - // ----- Store the offset of the central dir - $v_offset = @ftell($v_zip_temp_fd); + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); - // ----- Copy the block of file headers from the old archive - $v_size = $v_central_dir['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Copy the block of file headers from the archive_to_add - $v_size = $v_central_dir_to_add['size']; - while ($v_size != 0) + // -------------------------------------------------------------------------------- + // Function : privDuplicate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDuplicate($p_archive_filename) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + $v_result=1; - // ----- Merge the file comments - $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) { - // ----- Calculate the size of the (new) central header - $v_size = @ftell($v_zip_temp_fd)-$v_offset; + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; - // ----- Swap the file descriptor - // Here is a trick : I swap the temporary fd with the zip fd, in order to use - // the following methods on the temporary fil and not the real archive fd - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - - // ----- Create the central dir footer - if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); - @fclose($v_zip_temp_fd); - $this->zip_fd = null; - - // ----- Reset the file list - unset($v_header_list); - - // ----- Return - return $v_result; - } + // ----- Return + return $v_result; + } - // ----- Swap back the file descriptor - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; + // ----- Open the zip file + if (($v_result=$this->privOpenFd('wb')) != 1) { + // ----- Return + return $v_result; + } - // ----- Close - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) { + $this->privCloseFd(); - // ----- Close the temporary file - @fclose($v_zip_temp_fd); + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); - // ----- Delete the zip file - // TBC : I should test the result ... - @unlink($this->zipname); + // ----- Return + return PclZip::errorCode(); + } - // ----- Rename the temporary file - // TBC : I should test the result ... - //@rename($v_zip_temp_name, $this->zipname); - PclZipUtilRename($v_zip_temp_name, $this->zipname); + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDuplicate() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privDuplicate($p_archive_filename) - { - $v_result=1; - - // ----- Look if the $p_archive_filename exists - if (!is_file($p_archive_filename)) - { + // ----- Close + $this->privCloseFd(); - // ----- Nothing to duplicate, so duplicate is a success. - $v_result = 1; + // ----- Close the temporary file + @fclose($v_zip_temp_fd); - // ----- Return - return $v_result; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Open the zip file - if (($v_result=$this->privOpenFd('wb')) != 1) + // -------------------------------------------------------------------------------- + // Function : privErrorLog() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorLog($p_error_code=0, $p_error_string='') { - // ----- Return - return $v_result; + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclError($p_error_code, $p_error_string); + } else { + $this->error_code = $p_error_code; + $this->error_string = $p_error_string; + } } + // -------------------------------------------------------------------------------- - // ----- Open the temporary file in write mode - if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) + // -------------------------------------------------------------------------------- + // Function : privErrorReset() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorReset() { - $this->privCloseFd(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); - - // ----- Return - return PclZip::errorCode(); + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclErrorReset(); + } else { + $this->error_code = 0; + $this->error_string = ''; + } } + // -------------------------------------------------------------------------------- - // ----- Copy the files from the archive to the temporary file - // TBC : Here I should better append the file and go back to erase the central dir - $v_size = filesize($p_archive_filename); - while ($v_size != 0) + // -------------------------------------------------------------------------------- + // Function : privDisableMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDisableMagicQuotes() { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($v_zip_temp_fd, $v_read_size); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + $v_result=1; - // ----- Close - $this->privCloseFd(); + // ----- Look if function exists + if ((!function_exists("get_magic_quotes_runtime")) || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } - // ----- Close the temporary file - @fclose($v_zip_temp_fd); + // ----- Look if already done + if ($this->magic_quotes_status != -1) { + return $v_result; + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privErrorLog() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privErrorLog($p_error_code=0, $p_error_string='') - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - PclError($p_error_code, $p_error_string); - } - else { - $this->error_code = $p_error_code; - $this->error_string = $p_error_string; - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privErrorReset() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privErrorReset() - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - PclErrorReset(); - } - else { - $this->error_code = 0; - $this->error_string = ''; - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDisableMagicQuotes() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privDisableMagicQuotes() - { - $v_result=1; - - // ----- Look if function exists - if ( (!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { - return $v_result; - } + // ----- Get and memorize the magic_quote value + $this->magic_quotes_status = @get_magic_quotes_runtime(); + + // ----- Disable magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime(0); + } - // ----- Look if already done - if ($this->magic_quotes_status != -1) { - return $v_result; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - // ----- Get and memorize the magic_quote value - $this->magic_quotes_status = @get_magic_quotes_runtime(); + // -------------------------------------------------------------------------------- + // Function : privSwapBackMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privSwapBackMagicQuotes() + { + $v_result=1; - // ----- Disable magic_quotes - if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime(0); - } + // ----- Look if function exists + if ((!function_exists("get_magic_quotes_runtime")) || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privSwapBackMagicQuotes() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privSwapBackMagicQuotes() - { - $v_result=1; - - // ----- Look if function exists - if ( (!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { - return $v_result; - } + // ----- Look if something to do + if ($this->magic_quotes_status != -1) { + return $v_result; + } - // ----- Look if something to do - if ($this->magic_quotes_status != -1) { - return $v_result; - } + // ----- Swap back magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime($this->magic_quotes_status); + } - // ----- Swap back magic_quotes - if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime($this->magic_quotes_status); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- +} +// End of class +// -------------------------------------------------------------------------------- - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - } - // End of class - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilPathReduction() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function PclZipUtilPathReduction($p_dir) - { +// -------------------------------------------------------------------------------- +// Function : PclZipUtilPathReduction() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function PclZipUtilPathReduction($p_dir) +{ $v_result = ""; // ----- Look for not empty path if ($p_dir != "") { - // ----- Explode path by directory names - $v_list = explode("/", $p_dir); - - // ----- Study directories from last to first - $v_skip = 0; - for ($i=sizeof($v_list)-1; $i>=0; $i--) { - // ----- Look for current path - if ($v_list[$i] == ".") { - // ----- Ignore this directory - // Should be the first $i=0, but no check is done - } - else if ($v_list[$i] == "..") { - $v_skip++; - } - else if ($v_list[$i] == "") { - // ----- First '/' i.e. root slash - if ($i == 0) { - $v_result = "/".$v_result; - if ($v_skip > 0) { - // ----- It is an invalid path, so the path is not modified - // TBC - $v_result = $p_dir; - $v_skip = 0; + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + $v_skip = 0; + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } else if ($v_list[$i] == "..") { + $v_skip++; + } else if ($v_list[$i] == "") { + // ----- First '/' i.e. root slash + if ($i == 0) { + $v_result = "/".$v_result; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; + $v_skip = 0; + } + } else if ($i == (sizeof($v_list)-1)) { + // ----- Last '/' i.e. indicates a directory + $v_result = $v_list[$i]; + } else { + // ----- Double '/' inside the path + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + } else { + // ----- Look for item to skip + if ($v_skip > 0) { + $v_skip--; + } + else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } + } + } + + // ----- Look for skip + if ($v_skip > 0) { + while ($v_skip > 0) { + $v_result = '../'.$v_result; + $v_skip--; } - } - // ----- Last '/' i.e. indicates a directory - else if ($i == (sizeof($v_list)-1)) { - $v_result = $v_list[$i]; - } - // ----- Double '/' inside the path - else { - // ----- Ignore only the double '//' in path, - // but not the first and last '/' - } } - else { - // ----- Look for item to skip - if ($v_skip > 0) { - $v_skip--; - } - else { - $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); - } - } - } - - // ----- Look for skip - if ($v_skip > 0) { - while ($v_skip > 0) { - $v_result = '../'.$v_result; - $v_skip--; - } - } } // ----- Return return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilPathInclusion() - // Description : - // This function indicates if the path $p_path is under the $p_dir tree. Or, - // said in an other way, if the file or sub-dir $p_path is inside the dir - // $p_dir. - // The function indicates also if the path is exactly the same as the dir. - // This function supports path with duplicated '/' like '//', but does not - // support '.' or '..' statements. - // Parameters : - // Return Values : - // 0 if $p_path is not inside directory $p_dir - // 1 if $p_path is inside directory $p_dir - // 2 if $p_path is exactly the same as $p_dir - // -------------------------------------------------------------------------------- - function PclZipUtilPathInclusion($p_dir, $p_path) - { +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilPathInclusion() +// Description : +// This function indicates if the path $p_path is under the $p_dir tree. Or, +// said in an other way, if the file or sub-dir $p_path is inside the dir +// $p_dir. +// The function indicates also if the path is exactly the same as the dir. +// This function supports path with duplicated '/' like '//', but does not +// support '.' or '..' statements. +// Parameters : +// Return Values : +// 0 if $p_path is not inside directory $p_dir +// 1 if $p_path is inside directory $p_dir +// 2 if $p_path is exactly the same as $p_dir +// -------------------------------------------------------------------------------- +function PclZipUtilPathInclusion($p_dir, $p_path) +{ $v_result = 1; - + // ----- Look for path beginning by ./ - if ( ($p_dir == '.') - || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { - $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); + if (($p_dir == '.') || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); } - if ( ($p_path == '.') - || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { - $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); + if (($p_path == '.') || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); } // ----- Explode dir and path by directory separator @@ -5498,195 +5046,176 @@ function PclZipUtilPathInclusion($p_dir, $p_path) $i = 0; $j = 0; while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } + + // ----- Compare the items + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { + $v_result = 0; + } - // ----- Look for empty dir (path reduction) - if ($v_list_dir[$i] == '') { + // ----- Next items $i++; - continue; - } - if ($v_list_path[$j] == '') { $j++; - continue; - } - - // ----- Compare the items - if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { - $v_result = 0; - } - - // ----- Next items - $i++; - $j++; } // ----- Look if everything seems to be the same if ($v_result) { - // ----- Skip all the empty items - while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; - while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; - - if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { - // ----- There are exactly the same - $v_result = 2; - } - else if ($i < $v_list_dir_size) { - // ----- The path is shorter than the dir - $v_result = 0; - } + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } } // ----- Return return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilCopyBlock() - // Description : - // Parameters : - // $p_mode : read/write compression mode - // 0 : src & dest normal - // 1 : src gzip, dest normal - // 2 : src normal, dest gzip - // 3 : src & dest gzip - // Return Values : - // -------------------------------------------------------------------------------- - function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) - { +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilCopyBlock() +// Description : +// Parameters : +// $p_mode : read/write compression mode +// 0 : src & dest normal +// 1 : src gzip, dest normal +// 2 : src normal, dest gzip +// 3 : src & dest gzip +// Return Values : +// -------------------------------------------------------------------------------- +function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) +{ $v_result = 1; - if ($p_mode==0) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_src, $v_read_size); - @fwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - else if ($p_mode==1) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($p_src, $v_read_size); - @fwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - else if ($p_mode==2) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_src, $v_read_size); - @gzwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - else if ($p_mode==3) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($p_src, $v_read_size); - @gzwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } + if ($p_mode==0) { + while ($p_size != 0) { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } else if ($p_mode==1) { + while ($p_size != 0) { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } else if ($p_mode==2) { + while ($p_size != 0) { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } else if ($p_mode==3) { + while ($p_size != 0) { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } } // ----- Return return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilRename() - // Description : - // This function tries to do a simple rename() function. If it fails, it - // tries to copy the $p_src file in a new $p_dest file and then unlink the - // first one. - // Parameters : - // $p_src : Old filename - // $p_dest : New filename - // Return Values : - // 1 on success, 0 on failure. - // -------------------------------------------------------------------------------- - function PclZipUtilRename($p_src, $p_dest) - { +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilRename() +// Description : +// This function tries to do a simple rename() function. If it fails, it +// tries to copy the $p_src file in a new $p_dest file and then unlink the +// first one. +// Parameters : +// $p_src : Old filename +// $p_dest : New filename +// Return Values : +// 1 on success, 0 on failure. +// -------------------------------------------------------------------------------- +function PclZipUtilRename($p_src, $p_dest) +{ $v_result = 1; // ----- Try to rename the files if (!@rename($p_src, $p_dest)) { - - // ----- Try to copy & unlink the src - if (!@copy($p_src, $p_dest)) { - $v_result = 0; - } - else if (!@unlink($p_src)) { - $v_result = 0; - } + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; + } else if (!@unlink($p_src)) { + $v_result = 0; + } } // ----- Return return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilOptionText() - // Description : - // Translate option value in text. Mainly for debug purpose. - // Parameters : - // $p_option : the option value. - // Return Values : - // The option text value. - // -------------------------------------------------------------------------------- - function PclZipUtilOptionText($p_option) - { - +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilOptionText() +// Description : +// Translate option value in text. Mainly for debug purpose. +// Parameters : +// $p_option : the option value. +// Return Values : +// The option text value. +// -------------------------------------------------------------------------------- +function PclZipUtilOptionText($p_option) +{ + $v_list = get_defined_constants(); for (reset($v_list); $v_key = key($v_list); next($v_list)) { $v_prefix = substr($v_key, 0, 10); - if (( ($v_prefix == 'PCLZIP_OPT') - || ($v_prefix == 'PCLZIP_CB_') - || ($v_prefix == 'PCLZIP_ATT')) - && ($v_list[$v_key] == $p_option)) { - return $v_key; + if ((($v_prefix == 'PCLZIP_OPT') || ($v_prefix == 'PCLZIP_CB_') || ($v_prefix == 'PCLZIP_ATT')) && ($v_list[$v_key] == $p_option)) { + return $v_key; } } - + $v_result = 'Unknown'; return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilTranslateWinPath() - // Description : - // Translate windows path by replacing '\' by '/' and optionally removing - // drive letter. - // Parameters : - // $p_path : path to translate. - // $p_remove_disk_letter : true | false - // Return Values : - // The path translated. - // -------------------------------------------------------------------------------- - function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) - { +} +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilTranslateWinPath() +// Description : +// Translate windows path by replacing '\' by '/' and optionally removing +// drive letter. +// Parameters : +// $p_path : path to translate. +// $p_remove_disk_letter : true | false +// Return Values : +// The path translated. +// -------------------------------------------------------------------------------- +function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) +{ if (stristr(php_uname(), 'windows')) { - // ----- Look for potential disk letter - if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { - $p_path = substr($p_path, $v_position+1); - } - // ----- Change potential windows directory separator - if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { - $p_path = strtr($p_path, '\\', '/'); - } + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } } return $p_path; - } - // -------------------------------------------------------------------------------- - \ No newline at end of file +} +// -------------------------------------------------------------------------------- \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/PasswordHasher.php b/Classes/PHPExcel/Shared/PasswordHasher.php index 92c8b3f91..946742bf6 100644 --- a/Classes/PHPExcel/Shared/PasswordHasher.php +++ b/Classes/PHPExcel/Shared/PasswordHasher.php @@ -45,8 +45,9 @@ class PHPExcel_Shared_PasswordHasher * @param string $pPassword Password to hash * @return string Hashed password */ - public static function hashPassword($pPassword = '') { - $password = 0x0000; + public static function hashPassword($pPassword = '') + { + $password = 0x0000; $charPos = 1; // char position // split the plain text password in its component characters diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 513a1755a..563e7f2c1 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -93,10 +93,11 @@ class PHPExcel_Shared_String /** * Build control characters array */ - private static function _buildControlCharacters() { + private static function _buildControlCharacters() + { for ($i = 0; $i <= 31; ++$i) { if ($i != 9 && $i != 10 && $i != 13) { - $find = '_x' . sprintf('%04s' , strtoupper(dechex($i))) . '_'; + $find = '_x' . sprintf('%04s', strtoupper(dechex($i))) . '_'; $replace = chr($i); self::$_controlCharacters[$find] = $replace; } @@ -316,10 +317,7 @@ public static function getIsIconvEnabled() } // CUSTOM: IBM AIX iconv() does not work - if ( defined('PHP_OS') && @stristr(PHP_OS, 'AIX') - && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) - && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0) ) - { + if (defined('PHP_OS') && @stristr(PHP_OS, 'AIX') && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)) { self::$_isIconvEnabled = false; return false; } @@ -329,7 +327,8 @@ public static function getIsIconvEnabled() return true; } - public static function buildCharacterSets() { + public static function buildCharacterSets() + { if (empty(self::$_controlCharacters)) { self::_buildControlCharacters(); } @@ -352,8 +351,9 @@ public static function buildCharacterSets() { * @param string $value Value to unescape * @return string */ - public static function ControlCharacterOOXML2PHP($value = '') { - return str_replace( array_keys(self::$_controlCharacters), array_values(self::$_controlCharacters), $value ); + public static function ControlCharacterOOXML2PHP($value = '') + { + return str_replace(array_keys(self::$_controlCharacters), array_values(self::$_controlCharacters), $value); } /** @@ -370,8 +370,9 @@ public static function ControlCharacterOOXML2PHP($value = '') { * @param string $value Value to escape * @return string */ - public static function ControlCharacterPHP2OOXML($value = '') { - return str_replace( array_values(self::$_controlCharacters), array_keys(self::$_controlCharacters), $value ); + public static function ControlCharacterPHP2OOXML($value = '') + { + return str_replace(array_values(self::$_controlCharacters), array_keys(self::$_controlCharacters), $value); } /** @@ -402,7 +403,8 @@ public static function SanitizeUTF8($value) * @param string $value * @return boolean */ - public static function IsUTF8($value = '') { + public static function IsUTF8($value = '') + { return $value === '' || preg_match('/^./su', $value) === 1; } @@ -413,7 +415,8 @@ public static function IsUTF8($value = '') { * @param mixed $value * @return string */ - public static function FormatNumber($value) { + public static function FormatNumber($value) + { if (is_float($value)) { return str_replace(',', '.', $value); } @@ -524,16 +527,27 @@ public static function ConvertEncoding($value, $to, $from) * @author vadik56 */ public static function utf16_decode($str, $bom_be = TRUE) { - if ( strlen($str) < 2 ) return $str; + if (strlen($str) < 2) { + return $str; + } $c0 = ord($str{0}); $c1 = ord($str{1}); - if ( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); } - elseif ( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; } + if ($c0 == 0xfe && $c1 == 0xff) { + $str = substr($str,2); + } elseif ($c0 == 0xff && $c1 == 0xfe) { + $str = substr($str,2); + $bom_be = false; + } $len = strlen($str); $newstr = ''; for($i=0;$i<$len;$i+=2) { - if ( $bom_be ) { $val = ord($str{$i}) << 4; $val += ord($str{$i+1}); } - else { $val = ord($str{$i+1}) << 4; $val += ord($str{$i}); } + if ($bom_be) { + $val = ord($str{$i}) << 4; + $val += ord($str{$i+1}); + } else { + $val = ord($str{$i+1}) << 4; + $val += ord($str{$i}); + } $newstr .= ($val == 0x228) ? "\n" : chr($val); } return $newstr; @@ -634,7 +648,7 @@ public static function mb_str_split($string) { # Split at all position not after the start: ^ # and not before the end: $ - return preg_split('/(?<!^)(?!$)/u', $string ); + return preg_split('/(?<!^)(?!$)/u', $string); } /** @@ -667,7 +681,8 @@ public static function StrCaseReverse($pValue = '') * @param string &$operand string value to test * @return boolean */ - public static function convertToNumberIfFraction(&$operand) { + public static function convertToNumberIfFraction(&$operand) + { if (preg_match('/^'.self::STRING_REGEXP_FRACTION.'$/i', $operand, $match)) { $sign = ($match[1] == '-') ? '-' : '+'; $fractionFormula = '='.$sign.$match[2].$sign.$match[3]; @@ -802,8 +817,9 @@ public static function SYLKtoUTF8($pValue = '') */ public static function testStringAsNumeric($value) { - if (is_numeric($value)) + if (is_numeric($value)) { return $value; + } $v = floatval($value); return (is_numeric(substr($value, 0, strlen($v)))) ? $v : $value; } diff --git a/Classes/PHPExcel/Shared/TimeZone.php b/Classes/PHPExcel/Shared/TimeZone.php index 0b92fd830..c303eb936 100644 --- a/Classes/PHPExcel/Shared/TimeZone.php +++ b/Classes/PHPExcel/Shared/TimeZone.php @@ -50,7 +50,8 @@ class PHPExcel_Shared_TimeZone * @param string $timezone Time zone (e.g. 'Europe/London') * @return boolean Success or failure */ - public static function _validateTimeZone($timezone) { + public static function _validateTimeZone($timezone) + { if (in_array($timezone, DateTimeZone::listIdentifiers())) { return true; } @@ -63,7 +64,8 @@ public static function _validateTimeZone($timezone) { * @param string $timezone Time zone (e.g. 'Europe/London') * @return boolean Success or failure */ - public static function setTimeZone($timezone) { + public static function setTimeZone($timezone) + { if (self::_validateTimezone($timezone)) { self::$_timezone = $timezone; return true; @@ -77,7 +79,8 @@ public static function setTimeZone($timezone) { * * @return string Timezone (e.g. 'Europe/London') */ - public static function getTimeZone() { + public static function getTimeZone() + { return self::$_timezone; } // function getTimezone() @@ -89,7 +92,8 @@ public static function getTimeZone() { * @param integer $timestamp PHP date/time value for finding the current transition * @return array The current transition details */ - private static function _getTimezoneTransitions($objTimezone, $timestamp) { + private static function _getTimezoneTransitions($objTimezone, $timestamp) + { $allTransitions = $objTimezone->getTransitions(); $transitions = array(); foreach ($allTransitions as $key => $transition) { @@ -114,7 +118,8 @@ private static function _getTimezoneTransitions($objTimezone, $timestamp) { * @return integer Number of seconds for timezone adjustment * @throws PHPExcel_Exception */ - public static function getTimeZoneAdjustment($timezone, $timestamp) { + public static function getTimeZoneAdjustment($timezone, $timestamp) + { if ($timezone !== null) { if (!self::_validateTimezone($timezone)) { throw new PHPExcel_Exception("Invalid timezone " . $timezone); diff --git a/Classes/PHPExcel/Shared/XMLWriter.php b/Classes/PHPExcel/Shared/XMLWriter.php index 63d2f4007..0319f330a 100644 --- a/Classes/PHPExcel/Shared/XMLWriter.php +++ b/Classes/PHPExcel/Shared/XMLWriter.php @@ -26,14 +26,13 @@ */ if (!defined('DATE_W3C')) { - define('DATE_W3C', 'Y-m-d\TH:i:sP'); + define('DATE_W3C', 'Y-m-d\TH:i:sP'); } if (!defined('DEBUGMODE_ENABLED')) { - define('DEBUGMODE_ENABLED', false); + define('DEBUGMODE_ENABLED', false); } - /** * PHPExcel_Shared_XMLWriter * @@ -41,17 +40,18 @@ * @package PHPExcel_Shared * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ -class PHPExcel_Shared_XMLWriter extends XMLWriter { +class PHPExcel_Shared_XMLWriter extends XMLWriter +{ /** Temporary storage method */ const STORAGE_MEMORY = 1; - const STORAGE_DISK = 2; + const STORAGE_DISK = 2; /** * Temporary filename * * @var string */ - private $_tempFileName = ''; + private $_tempFileName = ''; /** * Create a new PHPExcel_Shared_XMLWriter instance @@ -59,14 +59,15 @@ class PHPExcel_Shared_XMLWriter extends XMLWriter { * @param int $pTemporaryStorage Temporary storage location * @param string $pTemporaryStorageFolder Temporary storage folder */ - public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = NULL) { + public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = null) { // Open temporary storage if ($pTemporaryStorage == self::STORAGE_MEMORY) { $this->openMemory(); } else { // Create temporary filename - if ($pTemporaryStorageFolder === NULL) + if ($pTemporaryStorageFolder === null) { $pTemporaryStorageFolder = PHPExcel_Shared_File::sys_get_temp_dir(); + } $this->_tempFileName = @tempnam($pTemporaryStorageFolder, 'xml'); // Open storage @@ -85,7 +86,8 @@ public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTempora /** * Destructor */ - public function __destruct() { + public function __destruct() + { // Unlink temporary files if ($this->_tempFileName != '') { @unlink($this->_tempFileName); @@ -97,7 +99,8 @@ public function __destruct() { * * @return $data */ - public function getData() { + public function getData() + { if ($this->_tempFileName == '') { return $this->outputMemory(true); } else { diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index 5fe682973..f795350a1 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -92,10 +92,7 @@ public function addFromString($localname, $contents) fwrite($handle, $contents); fclose($handle); - $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], - PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, - PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"] - ); + $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"]); if ($res == 0) { throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->_zip->errorInfo(true)); } diff --git a/Classes/PHPExcel/Shared/ZipStreamWrapper.php b/Classes/PHPExcel/Shared/ZipStreamWrapper.php index 254849dfa..c96cffe12 100644 --- a/Classes/PHPExcel/Shared/ZipStreamWrapper.php +++ b/Classes/PHPExcel/Shared/ZipStreamWrapper.php @@ -25,11 +25,12 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ -class PHPExcel_Shared_ZipStreamWrapper { +class PHPExcel_Shared_ZipStreamWrapper +{ /** * Internal ZipAcrhive * - * @var ZipAcrhive + * @var ZipArchive */ private $_archive; diff --git a/Classes/PHPExcel/Shared/trend/bestFitClass.php b/Classes/PHPExcel/Shared/trend/bestFitClass.php index c508fbd49..b30ad7da2 100644 --- a/Classes/PHPExcel/Shared/trend/bestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/bestFitClass.php @@ -25,7 +25,6 @@ * @version ##VERSION##, ##DATE## */ - /** * PHPExcel_Best_Fit * @@ -75,7 +74,7 @@ class PHPExcel_Best_Fit * * @var boolean **/ - protected $_adjustToZero = False; + protected $_adjustToZero = false; /** * Y-value series of best-fit values @@ -113,205 +112,207 @@ class PHPExcel_Best_Fit protected $_Yoffset = 0; - public function getError() { + public function getError() + { return $this->_error; } // function getBestFitType() - public function getBestFitType() { + public function getBestFitType() + { return $this->_bestFitType; } // function getBestFitType() - /** * Return the Y-Value for a specified value of X * * @param float $xValue X-Value * @return float Y-Value */ - public function getValueOfYForX($xValue) { - return False; + public function getValueOfYForX($xValue) + { + return false; } // function getValueOfYForX() - /** * Return the X-Value for a specified value of Y * * @param float $yValue Y-Value * @return float X-Value */ - public function getValueOfXForY($yValue) { - return False; + public function getValueOfXForY($yValue) + { + return false; } // function getValueOfXForY() - /** * Return the original set of X-Values * * @return float[] X-Values */ - public function getXValues() { + public function getXValues() + { return $this->_xValues; } // function getValueOfXForY() - /** * Return the Equation of the best-fit line * * @param int $dp Number of places of decimal precision to display * @return string */ - public function getEquation($dp=0) { + public function getEquation($dp = 0) + { return False; } // function getEquation() - /** * Return the Slope of the line * * @param int $dp Number of places of decimal precision to display * @return string */ - public function getSlope($dp=0) { + public function getSlope($dp = 0) + { if ($dp != 0) { return round($this->_slope, $dp); } return $this->_slope; } // function getSlope() - /** * Return the standard error of the Slope * * @param int $dp Number of places of decimal precision to display * @return string */ - public function getSlopeSE($dp=0) { + public function getSlopeSE($dp = 0) + { if ($dp != 0) { return round($this->_slopeSE, $dp); } return $this->_slopeSE; } // function getSlopeSE() - /** * Return the Value of X where it intersects Y = 0 * * @param int $dp Number of places of decimal precision to display * @return string */ - public function getIntersect($dp=0) { + public function getIntersect($dp=0) + { if ($dp != 0) { return round($this->_intersect, $dp); } return $this->_intersect; } // function getIntersect() - /** * Return the standard error of the Intersect * * @param int $dp Number of places of decimal precision to display * @return string */ - public function getIntersectSE($dp=0) { + public function getIntersectSE($dp = 0) + { if ($dp != 0) { return round($this->_intersectSE, $dp); } return $this->_intersectSE; } // function getIntersectSE() - /** * Return the goodness of fit for this regression * * @param int $dp Number of places of decimal precision to return * @return float */ - public function getGoodnessOfFit($dp=0) { + public function getGoodnessOfFit($dp = 0) + { if ($dp != 0) { return round($this->_goodnessOfFit, $dp); } return $this->_goodnessOfFit; } // function getGoodnessOfFit() - - public function getGoodnessOfFitPercent($dp=0) { + public function getGoodnessOfFitPercent($dp = 0) + { if ($dp != 0) { return round($this->_goodnessOfFit * 100, $dp); } return $this->_goodnessOfFit * 100; } // function getGoodnessOfFitPercent() - /** * Return the standard deviation of the residuals for this regression * * @param int $dp Number of places of decimal precision to return * @return float */ - public function getStdevOfResiduals($dp=0) { + public function getStdevOfResiduals($dp = 0) + { if ($dp != 0) { return round($this->_stdevOfResiduals, $dp); } return $this->_stdevOfResiduals; } // function getStdevOfResiduals() - - public function getSSRegression($dp=0) { + public function getSSRegression($dp = 0) + { if ($dp != 0) { return round($this->_SSRegression, $dp); } return $this->_SSRegression; } // function getSSRegression() - - public function getSSResiduals($dp=0) { + public function getSSResiduals($dp = 0) + { if ($dp != 0) { return round($this->_SSResiduals, $dp); } return $this->_SSResiduals; } // function getSSResiduals() - - public function getDFResiduals($dp=0) { + public function getDFResiduals($dp = 0) + { if ($dp != 0) { return round($this->_DFResiduals, $dp); } return $this->_DFResiduals; } // function getDFResiduals() - - public function getF($dp=0) { + public function getF($dp = 0) + { if ($dp != 0) { return round($this->_F, $dp); } return $this->_F; } // function getF() - - public function getCovariance($dp=0) { + public function getCovariance($dp = 0) + { if ($dp != 0) { return round($this->_covariance, $dp); } return $this->_covariance; } // function getCovariance() - - public function getCorrelation($dp=0) { + public function getCorrelation($dp = 0) + { if ($dp != 0) { return round($this->_correlation, $dp); } return $this->_correlation; } // function getCorrelation() - - public function getYBestFitValues() { + public function getYBestFitValues() + { return $this->_yBestFitValues; } // function getYBestFitValues() - - protected function _calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const) { + protected function _calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const) + { $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0; foreach ($this->_xValues as $xKey => $xValue) { $bestFitY = $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); @@ -364,8 +365,8 @@ protected function _calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, } } // function _calculateGoodnessOfFit() - - protected function _leastSquareFit($yValues, $xValues, $const) { + protected function _leastSquareFit($yValues, $xValues, $const) + { // calculate sums $x_sum = array_sum($xValues); $y_sum = array_sum($yValues); @@ -401,7 +402,6 @@ protected function _leastSquareFit($yValues, $xValues, $const) { $this->_calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, $meanX, $meanY, $const); } // function _leastSquareFit() - /** * Define the regression * @@ -409,7 +409,8 @@ protected function _leastSquareFit($yValues, $xValues, $const) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($yValues, $xValues=array(), $const=True) { + function __construct($yValues, $xValues = array(), $const = true) + { // Calculate number of points $nY = count($yValues); $nX = count($xValues); @@ -420,13 +421,12 @@ function __construct($yValues, $xValues=array(), $const=True) { $nX = $nY; } elseif ($nY != $nX) { // Ensure both arrays of points are the same size - $this->_error = True; - return False; + $this->_error = true; + return false; } $this->_valueCount = $nY; $this->_xValues = $xValues; $this->_yValues = $yValues; } // function __construct() - -} // class bestFit +} diff --git a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php index 54243081b..0aec82fd3 100644 --- a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php @@ -46,71 +46,70 @@ class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit **/ protected $_bestFitType = 'exponential'; - /** * Return the Y-Value for a specified value of X * * @param float $xValue X-Value * @return float Y-Value **/ - public function getValueOfYForX($xValue) { + public function getValueOfYForX($xValue) + { return $this->getIntersect() * pow($this->getSlope(),($xValue - $this->_Xoffset)); } // function getValueOfYForX() - /** * Return the X-Value for a specified value of Y * * @param float $yValue Y-Value * @return float X-Value **/ - public function getValueOfXForY($yValue) { + public function getValueOfXForY($yValue) + { return log(($yValue + $this->_Yoffset) / $this->getIntersect()) / log($this->getSlope()); } // function getValueOfXForY() - /** * Return the Equation of the best-fit line * * @param int $dp Number of places of decimal precision to display * @return string **/ - public function getEquation($dp=0) { + public function getEquation($dp = 0) + { $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); return 'Y = '.$intersect.' * '.$slope.'^X'; } // function getEquation() - /** * Return the Slope of the line * * @param int $dp Number of places of decimal precision to display * @return string **/ - public function getSlope($dp=0) { + public function getSlope($dp = 0) + { if ($dp != 0) { return round(exp($this->_slope), $dp); } return exp($this->_slope); } // function getSlope() - /** * Return the Value of X where it intersects Y = 0 * * @param int $dp Number of places of decimal precision to display * @return string **/ - public function getIntersect($dp=0) { + public function getIntersect($dp = 0) + { if ($dp != 0) { return round(exp($this->_intersect), $dp); } return exp($this->_intersect); } // function getIntersect() - /** * Execute the regression and calculate the goodness of fit for a set of X and Y data values * @@ -118,7 +117,8 @@ public function getIntersect($dp=0) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - private function _exponential_regression($yValues, $xValues, $const) { + private function _exponential_regression($yValues, $xValues, $const) + { foreach ($yValues as &$value) { if ($value < 0.0) { $value = 0 - log(abs($value)); @@ -131,7 +131,6 @@ private function _exponential_regression($yValues, $xValues, $const) { $this->_leastSquareFit($yValues, $xValues, $const); } // function _exponential_regression() - /** * Define the regression and calculate the goodness of fit for a set of X and Y data values * @@ -139,10 +138,10 @@ private function _exponential_regression($yValues, $xValues, $const) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($yValues, $xValues=array(), $const=True) { - if (parent::__construct($yValues, $xValues) !== False) { + function __construct($yValues, $xValues = array(), $const = true) + { + if (parent::__construct($yValues, $xValues) !== false) { $this->_exponential_regression($yValues, $xValues, $const); } } // function __construct() - -} // class exponentialBestFit \ No newline at end of file +} \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php index a18d42a9e..e884073ee 100644 --- a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php @@ -25,10 +25,8 @@ * @version ##VERSION##, ##DATE## */ - require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); - /** * PHPExcel_Linear_Best_Fit * @@ -46,25 +44,25 @@ class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit **/ protected $_bestFitType = 'linear'; - /** * Return the Y-Value for a specified value of X * * @param float $xValue X-Value * @return float Y-Value **/ - public function getValueOfYForX($xValue) { + public function getValueOfYForX($xValue) + { return $this->getIntersect() + $this->getSlope() * $xValue; } // function getValueOfYForX() - /** * Return the X-Value for a specified value of Y * * @param float $yValue Y-Value * @return float X-Value **/ - public function getValueOfXForY($yValue) { + public function getValueOfXForY($yValue) + { return ($yValue - $this->getIntersect()) / $this->getSlope(); } // function getValueOfXForY() @@ -75,14 +73,14 @@ public function getValueOfXForY($yValue) { * @param int $dp Number of places of decimal precision to display * @return string **/ - public function getEquation($dp=0) { + public function getEquation($dp = 0) + { $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); return 'Y = '.$intersect.' + '.$slope.' * X'; } // function getEquation() - /** * Execute the regression and calculate the goodness of fit for a set of X and Y data values * @@ -90,11 +88,11 @@ public function getEquation($dp=0) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - private function _linear_regression($yValues, $xValues, $const) { + private function _linear_regression($yValues, $xValues, $const) + { $this->_leastSquareFit($yValues, $xValues, $const); } // function _linear_regression() - /** * Define the regression and calculate the goodness of fit for a set of X and Y data values * @@ -102,10 +100,10 @@ private function _linear_regression($yValues, $xValues, $const) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($yValues, $xValues=array(), $const=True) { - if (parent::__construct($yValues, $xValues) !== False) { + function __construct($yValues, $xValues = array(), $const = true) + { + if (parent::__construct($yValues, $xValues) !== false) { $this->_linear_regression($yValues, $xValues, $const); } } // function __construct() - -} // class linearBestFit \ No newline at end of file +} \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php index b0db33e3e..35ab8b292 100644 --- a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php @@ -25,10 +25,8 @@ * @version ##VERSION##, ##DATE## */ - require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); - /** * PHPExcel_Logarithmic_Best_Fit * @@ -46,43 +44,42 @@ class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit **/ protected $_bestFitType = 'logarithmic'; - /** * Return the Y-Value for a specified value of X * * @param float $xValue X-Value * @return float Y-Value **/ - public function getValueOfYForX($xValue) { + public function getValueOfYForX($xValue) + { return $this->getIntersect() + $this->getSlope() * log($xValue - $this->_Xoffset); } // function getValueOfYForX() - /** * Return the X-Value for a specified value of Y * * @param float $yValue Y-Value * @return float X-Value **/ - public function getValueOfXForY($yValue) { + public function getValueOfXForY($yValue) + { return exp(($yValue - $this->getIntersect()) / $this->getSlope()); } // function getValueOfXForY() - /** * Return the Equation of the best-fit line * * @param int $dp Number of places of decimal precision to display * @return string **/ - public function getEquation($dp=0) { + public function getEquation($dp = 0) + { $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); return 'Y = '.$intersect.' + '.$slope.' * log(X)'; } // function getEquation() - /** * Execute the regression and calculate the goodness of fit for a set of X and Y data values * @@ -90,7 +87,8 @@ public function getEquation($dp=0) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - private function _logarithmic_regression($yValues, $xValues, $const) { + private function _logarithmic_regression($yValues, $xValues, $const) + { foreach ($xValues as &$value) { if ($value < 0.0) { $value = 0 - log(abs($value)); @@ -103,7 +101,6 @@ private function _logarithmic_regression($yValues, $xValues, $const) { $this->_leastSquareFit($yValues, $xValues, $const); } // function _logarithmic_regression() - /** * Define the regression and calculate the goodness of fit for a set of X and Y data values * @@ -111,10 +108,10 @@ private function _logarithmic_regression($yValues, $xValues, $const) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($yValues, $xValues=array(), $const=True) { - if (parent::__construct($yValues, $xValues) !== False) { + function __construct($yValues, $xValues = array(), $const = true) + { + if (parent::__construct($yValues, $xValues) !== false) { $this->_logarithmic_regression($yValues, $xValues, $const); } } // function __construct() - -} // class logarithmicBestFit \ No newline at end of file +} \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php index bd4484336..7e618ac34 100644 --- a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php @@ -61,7 +61,8 @@ class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit * * @return int **/ - public function getOrder() { + public function getOrder() + { return $this->_order; } // function getOrder() @@ -72,7 +73,8 @@ public function getOrder() { * @param float $xValue X-Value * @return float Y-Value **/ - public function getValueOfYForX($xValue) { + public function getValueOfYForX($xValue) + { $retVal = $this->getIntersect(); $slope = $this->getSlope(); foreach ($slope as $key => $value) { @@ -90,7 +92,8 @@ public function getValueOfYForX($xValue) { * @param float $yValue Y-Value * @return float X-Value **/ - public function getValueOfXForY($yValue) { + public function getValueOfXForY($yValue) + { return ($yValue - $this->getIntersect()) / $this->getSlope(); } // function getValueOfXForY() @@ -101,7 +104,8 @@ public function getValueOfXForY($yValue) { * @param int $dp Number of places of decimal precision to display * @return string **/ - public function getEquation($dp=0) { + public function getEquation($dp = 0) + { $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); @@ -124,7 +128,8 @@ public function getEquation($dp=0) { * @param int $dp Number of places of decimal precision to display * @return string **/ - public function getSlope($dp=0) { + public function getSlope($dp = 0) + { if ($dp != 0) { $coefficients = array(); foreach ($this->_slope as $coefficient) { @@ -136,7 +141,8 @@ public function getSlope($dp=0) { } // function getSlope() - public function getCoefficients($dp=0) { + public function getCoefficients($dp = 0) + { return array_merge(array($this->getIntersect($dp)), $this->getSlope($dp)); } // function getCoefficients() @@ -149,7 +155,8 @@ public function getCoefficients($dp=0) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - private function _polynomial_regression($order, $yValues, $xValues, $const) { + private function _polynomial_regression($order, $yValues, $xValues, $const) + { // calculate sums $x_sum = array_sum($xValues); $y_sum = array_sum($yValues); @@ -206,8 +213,9 @@ private function _polynomial_regression($order, $yValues, $xValues, $const) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($order, $yValues, $xValues=array(), $const=True) { - if (parent::__construct($yValues, $xValues) !== False) { + function __construct($order, $yValues, $xValues = array(), $const = true) + { + if (parent::__construct($yValues, $xValues) !== false) { if ($order < $this->_valueCount) { $this->_bestFitType .= '_'.$order; $this->_order = $order; @@ -220,5 +228,4 @@ function __construct($order, $yValues, $xValues=array(), $const=True) { } } } // function __construct() - -} // class polynomialBestFit \ No newline at end of file +} \ No newline at end of file diff --git a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php index 4f2a07352..b58d8f5d6 100644 --- a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php @@ -53,7 +53,8 @@ class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit * @param float $xValue X-Value * @return float Y-Value **/ - public function getValueOfYForX($xValue) { + public function getValueOfYForX($xValue) + { return $this->getIntersect() * pow(($xValue - $this->_Xoffset), $this->getSlope()); } // function getValueOfYForX() @@ -64,8 +65,9 @@ public function getValueOfYForX($xValue) { * @param float $yValue Y-Value * @return float X-Value **/ - public function getValueOfXForY($yValue) { - return pow((($yValue + $this->_Yoffset) / $this->getIntersect()),(1 / $this->getSlope())); + public function getValueOfXForY($yValue) + { + return pow((($yValue + $this->_Yoffset) / $this->getIntersect()), (1 / $this->getSlope())); } // function getValueOfXForY() @@ -75,7 +77,8 @@ public function getValueOfXForY($yValue) { * @param int $dp Number of places of decimal precision to display * @return string **/ - public function getEquation($dp=0) { + public function getEquation($dp = 0) + { $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); @@ -89,7 +92,8 @@ public function getEquation($dp=0) { * @param int $dp Number of places of decimal precision to display * @return string **/ - public function getIntersect($dp=0) { + public function getIntersect($dp = 0) + { if ($dp != 0) { return round(exp($this->_intersect), $dp); } @@ -104,7 +108,8 @@ public function getIntersect($dp=0) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - private function _power_regression($yValues, $xValues, $const) { + private function _power_regression($yValues, $xValues, $const) + { foreach ($xValues as &$value) { if ($value < 0.0) { $value = 0 - log(abs($value)); @@ -133,10 +138,10 @@ private function _power_regression($yValues, $xValues, $const) { * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($yValues, $xValues=array(), $const=True) { - if (parent::__construct($yValues, $xValues) !== False) { + function __construct($yValues, $xValues = array(), $const = true) + { + if (parent::__construct($yValues, $xValues) !== false) { $this->_power_regression($yValues, $xValues, $const); } - } // function __construct() - -} // class powerBestFit \ No newline at end of file + } +} diff --git a/Classes/PHPExcel/Shared/trend/trendClass.php b/Classes/PHPExcel/Shared/trend/trendClass.php index 6d16c7ead..bb1cd1c54 100644 --- a/Classes/PHPExcel/Shared/trend/trendClass.php +++ b/Classes/PHPExcel/Shared/trend/trendClass.php @@ -84,7 +84,8 @@ class trendClass private static $_trendCache = array(); - public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xValues=array(), $const=True) { + public static function calculate($trendType = self::TREND_BEST_FIT, $yValues, $xValues = array(), $const = true) + { // Calculate number of points in each dataset $nY = count($yValues); $nX = count($xValues); @@ -102,29 +103,29 @@ public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xVa // Determine which trend method has been requested switch ($trendType) { // Instantiate and return the class for the requested trend method - case self::TREND_LINEAR : - case self::TREND_LOGARITHMIC : - case self::TREND_EXPONENTIAL : - case self::TREND_POWER : + case self::TREND_LINEAR: + case self::TREND_LOGARITHMIC: + case self::TREND_EXPONENTIAL: + case self::TREND_POWER: if (!isset(self::$_trendCache[$key])) { $className = 'PHPExcel_'.$trendType.'_Best_Fit'; self::$_trendCache[$key] = new $className($yValues, $xValues, $const); } return self::$_trendCache[$key]; break; - case self::TREND_POLYNOMIAL_2 : - case self::TREND_POLYNOMIAL_3 : - case self::TREND_POLYNOMIAL_4 : - case self::TREND_POLYNOMIAL_5 : - case self::TREND_POLYNOMIAL_6 : + case self::TREND_POLYNOMIAL_2: + case self::TREND_POLYNOMIAL_3: + case self::TREND_POLYNOMIAL_4: + case self::TREND_POLYNOMIAL_5: + case self::TREND_POLYNOMIAL_6: if (!isset(self::$_trendCache[$key])) { - $order = substr($trendType,-1); + $order = substr($trendType, -1); self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order, $yValues, $xValues, $const); } return self::$_trendCache[$key]; break; - case self::TREND_BEST_FIT : - case self::TREND_BEST_FIT_NO_POLY : + case self::TREND_BEST_FIT: + case self::TREND_BEST_FIT_NO_POLY: // If the request is to determine the best fit regression, then we test each trend line in turn // Start by generating an instance of each available trend method foreach (self::$_trendTypes as $trendMethod) { @@ -134,7 +135,7 @@ public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xVa } if ($trendType != self::TREND_BEST_FIT_NO_POLY) { foreach (self::$_trendTypePolyOrders as $trendMethod) { - $order = substr($trendMethod,-1); + $order = substr($trendMethod, -1); $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order, $yValues, $xValues, $const); if ($bestFit[$trendMethod]->getError()) { unset($bestFit[$trendMethod]); @@ -148,9 +149,8 @@ public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xVa $bestFitType = key($bestFitValue); return $bestFit[$bestFitType]; break; - default : + default: return false; } } // function calculate() - -} // class trendClass \ No newline at end of file +} // class trendClass diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index ebb32ec4f..5c6d3ed62 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -434,8 +434,8 @@ private static function _checkSheetCodeName($pValue) } // Some of the printable ASCII characters are invalid: * : / \ ? [ ] and first and last characters cannot be a "'" if ((str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) || - (PHPExcel_Shared_String::Substring($pValue,-1,1)=='\'') || - (PHPExcel_Shared_String::Substring($pValue,0,1)=='\'')) { + (PHPExcel_Shared_String::Substring($pValue, -1, 1)=='\'') || + (PHPExcel_Shared_String::Substring($pValue, 0, 1)=='\'')) { throw new PHPExcel_Exception('Invalid character found in sheet code name'); } @@ -2066,7 +2066,7 @@ public function removeRow($pRow = 1, $pNumRows = 1) $highestRow = $this->getHighestDataRow(); $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this); - for($r = 0; $r < $pNumRows; ++$r) { + for ($r = 0; $r < $pNumRows; ++$r) { $this->getCellCacheController()->removeRow($highestRow); --$highestRow; } @@ -2091,7 +2091,7 @@ public function removeColumn($pColumn = 'A', $pNumCols = 1) $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols); $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this); - for($c = 0; $c < $pNumCols; ++$c) { + for ($c = 0; $c < $pNumCols; ++$c) { $this->getCellCacheController()->removeColumn($highestColumn); $highestColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($highestColumn) - 2); } @@ -2502,9 +2502,7 @@ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormul $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString( $returnValue[$rRef][$cRef], - ($style && $style->getNumberFormat()) ? - $style->getNumberFormat()->getFormatCode() : - PHPExcel_Style_NumberFormat::FORMAT_GENERAL + ($style && $style->getNumberFormat()) ? $style->getNumberFormat()->getFormatCode() : PHPExcel_Style_NumberFormat::FORMAT_GENERAL ); } } else { @@ -2622,7 +2620,7 @@ public function garbageCollect() // Loop through column dimensions foreach ($this->_columnDimensions as $dimension) { - $highestColumn = max($highestColumn,PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex())); + $highestColumn = max($highestColumn, PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex())); } // Loop through row dimensions @@ -2674,7 +2672,7 @@ public static function extractSheetTitle($pRange, $returnRange = false) } if ($returnRange) { - return array(trim(substr($pRange, 0, $sep),"'"), substr($pRange, $sep + 1)); + return array(trim(substr($pRange, 0, $sep), "'"), substr($pRange, $sep + 1)); } return substr($pRange, $sep + 1); @@ -2833,9 +2831,9 @@ public function shrinkRangeToFit($range) */ public function getTabColor() { - if ($this->_tabColor === null) + if ($this->_tabColor === null) { $this->_tabColor = new PHPExcel_Style_Color(); - + } return $this->_tabColor; } @@ -2867,7 +2865,8 @@ public function isTabColorSet() * * @return PHPExcel_Worksheet */ - public function copy() { + public function copy() + { $copied = clone $this; return $copied; @@ -2908,7 +2907,7 @@ public function __clone() * @return objWorksheet * @throws PHPExcel_Exception */ - public function setCodeName($pValue=null) + public function setCodeName($pValue = null) { // Is this a 'rename' or not? if ($this->getCodeName() == $pValue) { @@ -2927,18 +2926,18 @@ public function setCodeName($pValue=null) // Use name, but append with lowest possible integer if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); + $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 29); } $i = 1; while ($this->getParent()->sheetCodeNameExists($pValue . '_' . $i)) { ++$i; if ($i == 10) { if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); + $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 28); } } elseif ($i == 100) { if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { - $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); + $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 27); } } } diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index 36407e6e5..e86f97830 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -114,7 +114,7 @@ public function getRange() public function setRange($pRange = '') { // Uppercase coordinate - $cellAddress = explode('!',strtoupper($pRange)); + $cellAddress = explode('!', strtoupper($pRange)); if (count($cellAddress) > 1) { list($worksheet, $pRange) = $cellAddress; } @@ -349,7 +349,7 @@ private static function _filterTestInDateGroupSet($cellValue, $dataSet) } foreach ($dateSet as $dateValue) { // Use of substr to extract value at the appropriate group level - if (substr($dtVal,0,strlen($dateValue)) == $dateValue) { + if (substr($dtVal, 0, strlen($dateValue)) == $dateValue) { return true; } } @@ -381,34 +381,34 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) if (is_numeric($rule['value'])) { // Numeric values are tested using the appropriate operator switch ($rule['operator']) { - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL: $retVal = ($cellValue == $rule['value']); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL: $retVal = ($cellValue != $rule['value']); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN: $retVal = ($cellValue > $rule['value']); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL: $retVal = ($cellValue >= $rule['value']); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN: $retVal = ($cellValue < $rule['value']); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL: $retVal = ($cellValue <= $rule['value']); break; } } elseif ($rule['value'] == '') { switch ($rule['operator']) { - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL: $retVal = (($cellValue == '') || ($cellValue === null)); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL: $retVal = (($cellValue != '') && ($cellValue !== null)); break; - default : + default: $retVal = true; break; } @@ -418,7 +418,7 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) } // If there are multiple conditions, then we need to test both using the appropriate join operator switch ($join) { - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR : + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR: $returnVal = $returnVal || $retVal; // Break as soon as we have a TRUE match for OR joins, // to avoid unnecessary additional code execution @@ -426,7 +426,7 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) return $returnVal; } break; - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND : + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND: $returnVal = $returnVal && $retVal; break; } @@ -450,7 +450,7 @@ private static function _filterTestInPeriodDateSet($cellValue, $monthSet) } if (is_numeric($cellValue)) { - $dateValue = date('m',PHPExcel_Shared_Date::ExcelToPHP($cellValue)); + $dateValue = date('m', PHPExcel_Shared_Date::ExcelToPHP($cellValue)); if (in_array($dateValue, $monthSet)) { return true; } @@ -485,69 +485,69 @@ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) $baseDate = PHPExcel_Calculation_DateTime::DATENOW(); // Calculate start/end dates for the required date range based on current date switch ($dynamicRuleType) { - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK: $baseDate = strtotime('-7 days', $baseDate); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK: $baseDate = strtotime('-7 days', $baseDate); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : - $baseDate = strtotime('-1 month',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH: + $baseDate = strtotime('-1 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : - $baseDate = strtotime('+1 month',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH: + $baseDate = strtotime('+1 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : - $baseDate = strtotime('-3 month',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER: + $baseDate = strtotime('-3 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : - $baseDate = strtotime('+3 month',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER: + $baseDate = strtotime('+3 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : - $baseDate = strtotime('-1 year',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR: + $baseDate = strtotime('-1 year', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : - $baseDate = strtotime('+1 year',gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR: + $baseDate = strtotime('+1 year', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; } switch ($dynamicRuleType) { - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY: + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY: + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW: $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day', $baseDate)); $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE: $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day', $baseDate)); $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1, date('Y', $baseDate))); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR: + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR: + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR: $maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 31, 12, date('Y', $baseDate))); ++$maxVal; $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1, date('Y', $baseDate))); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER: + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER: + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER: $thisMonth = date('m', $baseDate); $thisQuarter = floor(--$thisMonth / 3); $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0, 0, 0, date('t', $baseDate), (1+$thisQuarter)*3, date('Y', $baseDate))); ++$maxVal; $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1+$thisQuarter*3, date('Y', $baseDate))); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH: + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH: + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH: $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0, 0, 0, date('t', $baseDate), date('m', $baseDate), date('Y', $baseDate))); ++$maxVal; $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate))); break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK: + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK: + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK: $dayOfWeek = date('w', $baseDate); $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate) - $dayOfWeek; $maxVal = $val + 7; @@ -556,11 +556,11 @@ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) switch ($dynamicRuleType) { // Adjust Today dates for Yesterday and Tomorrow - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY: --$maxVal; --$val; break; - case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW: ++$maxVal; ++$val; break; @@ -589,7 +589,7 @@ private function _calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, sort($dataValues); } - return array_pop(array_slice($dataValues,0, $ruleValue)); + return array_pop(array_slice($dataValues, 0, $ruleValue)); } /** @@ -610,7 +610,7 @@ public function showHideRows() foreach ($this->_columns as $columnID => $filterColumn) { $rules = $filterColumn->getRules(); switch ($filterColumn->getFilterType()) { - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER : + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER: $ruleValues = array(); // Build a list of the filter value selections foreach ($rules as $rule) { @@ -620,8 +620,9 @@ public function showHideRows() // Test if we want to include blanks in our filter criteria $blanks = false; $ruleDataSet = array_filter($ruleValues); - if (count($ruleValues) != count($ruleDataSet)) + if (count($ruleValues) != count($ruleDataSet)) { $blanks = true; + } if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) { // Filter on absolute values $columnFilterTests[$columnID] = array( @@ -638,23 +639,29 @@ public function showHideRows() foreach ($ruleDataSet as $ruleValue) { $date = $time = ''; if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')) + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')) { $date .= sprintf('%04d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]); + } if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')) + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')) { $date .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]); + } if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')) + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')) { $date .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]); + } if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')) + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')) { $time .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]); + } if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')) + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')) { $time .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]); + } if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) && - ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')) + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')) { $time .= sprintf('%02d', $ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]); + } $dateTime = $date . $time; $arguments['date'][] = $date; $arguments['time'][] = $time; @@ -670,7 +677,7 @@ public function showHideRows() ); } break; - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER : + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER: $customRuleForBlanks = false; $ruleValues = array(); // Build a list of the filter value selections @@ -680,7 +687,7 @@ public function showHideRows() if (!is_numeric($ruleValue)) { // Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards $ruleValue = preg_quote($ruleValue); - $ruleValue = str_replace(self::$_fromReplace,self::$_toReplace, $ruleValue); + $ruleValue = str_replace(self::$_fromReplace, self::$_toReplace, $ruleValue); if (trim($ruleValue) == '') { $customRuleForBlanks = true; $ruleValue = trim($ruleValue); @@ -694,7 +701,7 @@ public function showHideRows() 'arguments' => array('filterRules' => $ruleValues, 'join' => $join, 'customRuleForBlanks' => $customRuleForBlanks) ); break; - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER : + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER: $ruleValues = array(); foreach ($rules as $rule) { // We should only ever have one Dynamic Filter Rule anyway @@ -704,7 +711,7 @@ public function showHideRows() // Number (Average) based // Calculate the average $averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')'; - $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,null, $this->_workSheet->getCell('A1')); + $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula, null, $this->_workSheet->getCell('A1')); // Set above/below rule based on greaterThan or LessTan $operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN @@ -720,14 +727,14 @@ public function showHideRows() // Date based if ($dynamicRuleType{0} == 'M' || $dynamicRuleType{0} == 'Q') { // Month or Quarter - sscanf($dynamicRuleType,'%[A-Z]%d', $periodType, $period); + sscanf($dynamicRuleType, '%[A-Z]%d', $periodType, $period); if ($periodType == 'M') { $ruleValues = array($period); } else { --$period; $periodEnd = (1+$period)*3; $periodStart = 1+$period*3; - $ruleValues = range($periodStart,periodEnd); + $ruleValues = range($periodStart, $periodEnd); } $columnFilterTests[$columnID] = array( 'method' => '_filterTestInPeriodDateSet', @@ -742,7 +749,7 @@ public function showHideRows() } } break; - case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER : + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER: $ruleValues = array(); $dataRowCount = $rangeEnd[1] - $rangeStart[1]; foreach ($rules as $rule) { @@ -754,8 +761,12 @@ public function showHideRows() if ($ruleOperator === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) { $ruleValue = floor($ruleValue * ($dataRowCount / 100)); } - if ($ruleValue < 1) $ruleValue = 1; - if ($ruleValue > 500) $ruleValue = 500; + if ($ruleValue < 1) { + $ruleValue = 1; + } + if ($ruleValue > 500) { + $ruleValue = 500; + } $maxVal = $this->_calculateTopTenValue($columnID, $rangeStart[1]+1, $rangeEnd[1], $toptenRuleType, $ruleValue); @@ -836,7 +847,8 @@ public function __clone() * toString method replicates previous behavior by returning the range if object is * referenced as a property of its parent. */ - public function __toString() { + public function __toString() + { return (string) $this->_range; } } diff --git a/Classes/PHPExcel/Worksheet/PageSetup.php b/Classes/PHPExcel/Worksheet/PageSetup.php index 71649fce6..1e9df19ef 100644 --- a/Classes/PHPExcel/Worksheet/PageSetup.php +++ b/Classes/PHPExcel/Worksheet/PageSetup.php @@ -366,7 +366,8 @@ public function setScale($pValue = 100, $pUpdate = true) * * @return boolean */ - public function getFitToPage() { + public function getFitToPage() + { return $this->_fitToPage; } From 082fb1b4756f0835d53ce35b519d888a52105442 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sat, 16 May 2015 23:09:31 +0200 Subject: [PATCH 377/467] PSR2 Fixes --- Classes/PHPExcel/Shared/CodePage.php | 201 ++++++++++---- Classes/PHPExcel/Shared/Date.php | 27 +- Classes/PHPExcel/Shared/Drawing.php | 2 +- .../PHPExcel/Shared/Escher/DgContainer.php | 1 - .../Escher/DggContainer/BstoreContainer.php | 1 - .../DggContainer/BstoreContainer/BSE.php | 1 - .../DggContainer/BstoreContainer/BSE/Blip.php | 1 - Classes/PHPExcel/Shared/Excel5.php | 18 +- Classes/PHPExcel/Shared/File.php | 8 +- Classes/PHPExcel/Shared/Font.php | 178 ++++++------- .../Shared/OLE/ChainedBlockStream.php | 10 +- Classes/PHPExcel/Shared/OLE/PPS.php | 6 +- Classes/PHPExcel/Shared/OLE/PPS/File.php | 14 +- Classes/PHPExcel/Shared/OLE/PPS/Root.php | 34 +-- Classes/PHPExcel/Shared/OLERead.php | 58 ++-- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 248 ++++++++---------- Classes/PHPExcel/Shared/String.php | 9 +- Classes/PHPExcel/Shared/XMLWriter.php | 3 +- .../PHPExcel/Shared/trend/bestFitClass.php | 12 +- .../Shared/trend/exponentialBestFitClass.php | 4 +- .../Shared/trend/linearBestFitClass.php | 2 +- .../Shared/trend/logarithmicBestFitClass.php | 2 +- .../Shared/trend/polynomialBestFitClass.php | 10 +- 23 files changed, 429 insertions(+), 421 deletions(-) diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index cdaf30a1e..13c166a3a 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -38,58 +38,155 @@ class PHPExcel_Shared_CodePage public static function NumberToName($codePage = 1252) { switch ($codePage) { - case 367: return 'ASCII'; break; // ASCII - case 437: return 'CP437'; break; // OEM US - case 720: throw new PHPExcel_Exception('Code page 720 not supported.'); - break; // OEM Arabic - case 737: return 'CP737'; break; // OEM Greek - case 775: return 'CP775'; break; // OEM Baltic - case 850: return 'CP850'; break; // OEM Latin I - case 852: return 'CP852'; break; // OEM Latin II (Central European) - case 855: return 'CP855'; break; // OEM Cyrillic - case 857: return 'CP857'; break; // OEM Turkish - case 858: return 'CP858'; break; // OEM Multilingual Latin I with Euro - case 860: return 'CP860'; break; // OEM Portugese - case 861: return 'CP861'; break; // OEM Icelandic - case 862: return 'CP862'; break; // OEM Hebrew - case 863: return 'CP863'; break; // OEM Canadian (French) - case 864: return 'CP864'; break; // OEM Arabic - case 865: return 'CP865'; break; // OEM Nordic - case 866: return 'CP866'; break; // OEM Cyrillic (Russian) - case 869: return 'CP869'; break; // OEM Greek (Modern) - case 874: return 'CP874'; break; // ANSI Thai - case 932: return 'CP932'; break; // ANSI Japanese Shift-JIS - case 936: return 'CP936'; break; // ANSI Chinese Simplified GBK - case 949: return 'CP949'; break; // ANSI Korean (Wansung) - case 950: return 'CP950'; break; // ANSI Chinese Traditional BIG5 - case 1200: return 'UTF-16LE'; break; // UTF-16 (BIFF8) - case 1250: return 'CP1250'; break; // ANSI Latin II (Central European) - case 1251: return 'CP1251'; break; // ANSI Cyrillic - case 0: // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program - case 1252: return 'CP1252'; break; // ANSI Latin I (BIFF4-BIFF7) - case 1253: return 'CP1253'; break; // ANSI Greek - case 1254: return 'CP1254'; break; // ANSI Turkish - case 1255: return 'CP1255'; break; // ANSI Hebrew - case 1256: return 'CP1256'; break; // ANSI Arabic - case 1257: return 'CP1257'; break; // ANSI Baltic - case 1258: return 'CP1258'; break; // ANSI Vietnamese - case 1361: return 'CP1361'; break; // ANSI Korean (Johab) - case 10000: return 'MAC'; break; // Apple Roman - case 10001: return 'CP932'; break; // Macintosh Japanese - case 10002: return 'CP950'; break; // Macintosh Chinese Traditional - case 10003: return 'CP1361'; break; // Macintosh Korean - case 10006: return 'MACGREEK'; break; // Macintosh Greek - case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic - case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) - case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe - case 10079: return 'MACICELAND'; break; // Macintosh Icelandic - case 10081: return 'MACTURKISH'; break; // Macintosh Turkish - case 21010: return 'UTF-16LE'; break; // UTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE - case 32768: return 'MAC'; break; // Apple Roman - case 32769: throw new PHPExcel_Exception('Code page 32769 not supported.'); - break; // ANSI Latin I (BIFF2-BIFF3) - case 65000: return 'UTF-7'; break; // Unicode (UTF-7) - case 65001: return 'UTF-8'; break; // Unicode (UTF-8) + case 367: + return 'ASCII'; + break; // ASCII + case 437: + return 'CP437'; + break; // OEM US + case 720: + throw new PHPExcel_Exception('Code page 720 not supported.'); + break; // OEM Arabic + case 737: + return 'CP737'; + break; // OEM Greek + case 775: + return 'CP775'; + break; // OEM Baltic + case 850: + return 'CP850'; + break; // OEM Latin I + case 852: + return 'CP852'; + break; // OEM Latin II (Central European) + case 855: + return 'CP855'; + break; // OEM Cyrillic + case 857: + return 'CP857'; + break; // OEM Turkish + case 858: + return 'CP858'; + break; // OEM Multilingual Latin I with Euro + case 860: + return 'CP860'; + break; // OEM Portugese + case 861: + return 'CP861'; + break; // OEM Icelandic + case 862: + return 'CP862'; + break; // OEM Hebrew + case 863: + return 'CP863'; + break; // OEM Canadian (French) + case 864: + return 'CP864'; + break; // OEM Arabic + case 865: + return 'CP865'; + break; // OEM Nordic + case 866: + return 'CP866'; + break; // OEM Cyrillic (Russian) + case 869: + return 'CP869'; + break; // OEM Greek (Modern) + case 874: + return 'CP874'; + break; // ANSI Thai + case 932: + return 'CP932'; + break; // ANSI Japanese Shift-JIS + case 936: + return 'CP936'; + break; // ANSI Chinese Simplified GBK + case 949: + return 'CP949'; + break; // ANSI Korean (Wansung) + case 950: + return 'CP950'; + break; // ANSI Chinese Traditional BIG5 + case 1200: + return 'UTF-16LE'; + break; // UTF-16 (BIFF8) + case 1250: + return 'CP1250'; + break; // ANSI Latin II (Central European) + case 1251: + return 'CP1251'; + break; // ANSI Cyrillic + case 0: + // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program + case 1252: + return 'CP1252'; + break; // ANSI Latin I (BIFF4-BIFF7) + case 1253: + return 'CP1253'; + break; // ANSI Greek + case 1254: + return 'CP1254'; + break; // ANSI Turkish + case 1255: + return 'CP1255'; + break; // ANSI Hebrew + case 1256: + return 'CP1256'; + break; // ANSI Arabic + case 1257: + return 'CP1257'; + break; // ANSI Baltic + case 1258: + return 'CP1258'; + break; // ANSI Vietnamese + case 1361: + return 'CP1361'; + break; // ANSI Korean (Johab) + case 10000: + return 'MAC'; + break; // Apple Roman + case 10001: + return 'CP932'; + break; // Macintosh Japanese + case 10002: + return 'CP950'; + break; // Macintosh Chinese Traditional + case 10003: + return 'CP1361'; + break; // Macintosh Korean + case 10006: + return 'MACGREEK'; + break; // Macintosh Greek + case 10007: + return 'MACCYRILLIC'; + break; // Macintosh Cyrillic + case 10008: + return 'CP936'; + break; // Macintosh - Simplified Chinese (GB 2312) + case 10029: + return 'MACCENTRALEUROPE'; + break; // Macintosh Central Europe + case 10079: + return 'MACICELAND'; + break; // Macintosh Icelandic + case 10081: + return 'MACTURKISH'; + break; // Macintosh Turkish + case 21010: + return 'UTF-16LE'; + break; // UTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE + case 32768: + return 'MAC'; + break; // Apple Roman + case 32769: + throw new PHPExcel_Exception('Code page 32769 not supported.'); + break; // ANSI Latin I (BIFF2-BIFF3) + case 65000: + return 'UTF-7'; + break; // Unicode (UTF-7) + case 65001: + return 'UTF-8'; + break; // Unicode (UTF-8) } throw new PHPExcel_Exception('Unknown codepage: ' . $codePage); } diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index 09026f83d..f860b8a46 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -184,13 +184,9 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $ti date_default_timezone_set('UTC'); $retValue = false; if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { - $retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), - $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s') - ); + $retValue = self::FormattedPHPToExcel($dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s')); } elseif (is_numeric($dateValue)) { - $retValue = self::FormattedPHPToExcel( date('Y', $dateValue), date('m', $dateValue), date('d', $dateValue), - date('H', $dateValue), date('i', $dateValue), date('s', $dateValue) - ); + $retValue = self::FormattedPHPToExcel(date('Y', $dateValue), date('m', $dateValue), date('d', $dateValue), date('H', $dateValue), date('i', $dateValue), date('s', $dateValue)); } date_default_timezone_set($saveTimeZone); @@ -235,8 +231,8 @@ public static function FormattedPHPToExcel($year, $month, $day, $hours = 0, $min } // Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0) - $century = substr($year,0,2); - $decade = substr($year,2,2); + $century = substr($year, 0, 2); + $decade = substr($year, 2, 2); $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $myexcelBaseDate + $excel1900isLeapYear; $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; @@ -273,7 +269,7 @@ public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) } - private static $possibleDateFormatCharacters = 'eymdHs'; + private static $possibleDateFormatCharacters = 'eymdHs'; /** * Is a given number format code a date/time? @@ -283,12 +279,15 @@ public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) */ public static function isDateTimeFormatCode($pFormatCode = '') { - if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) + if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) { // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) return false; - if (preg_match('/[0#]E[+-]0/i', $pFormatCode)) + } + if (preg_match('/[0#]E[+-]0/i', $pFormatCode)) { // Scientific format return false; + } + // Switch on formatcode switch ($pFormatCode) { // Explicitly defined date formats @@ -352,10 +351,12 @@ public static function isDateTimeFormatCode($pFormatCode = '') */ public static function stringToExcel($dateValue = '') { - if (strlen($dateValue) < 2) + if (strlen($dateValue) < 2) { return false; - if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) + } + if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) { return false; + } $dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue); diff --git a/Classes/PHPExcel/Shared/Drawing.php b/Classes/PHPExcel/Shared/Drawing.php index 4125815d4..3e027b4ad 100644 --- a/Classes/PHPExcel/Shared/Drawing.php +++ b/Classes/PHPExcel/Shared/Drawing.php @@ -225,7 +225,7 @@ public static function imagecreatefrombmp($p_sFile) // Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption // Calculate the next DWORD-position in the body - for ($i = 0 ; $i < $body_size ; $i += 3) { + for ($i = 0; $i < $body_size; $i += 3) { // Calculate line-ending and padding if ($x >= $width) { // If padding needed, ignore image-padding diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer.php index ef855d753..e4d17bc1b 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer.php @@ -79,5 +79,4 @@ public function setSpgrContainer($spgrContainer) { return $this->_spgrContainer = $spgrContainer; } - } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php index 390f09b68..3f8f81da6 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php @@ -61,5 +61,4 @@ public function getBSECollection() { return $this->_BSECollection; } - } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php index 0fac1b8e5..1b0fbe2ca 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php @@ -116,5 +116,4 @@ public function setBlipType($blipType) { $this->_blipType = $blipType; } - } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php index 4fd743f58..172c03e21 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php @@ -87,5 +87,4 @@ public function getParent() { return $this->_parent; } - } diff --git a/Classes/PHPExcel/Shared/Excel5.php b/Classes/PHPExcel/Shared/Excel5.php index 115cc3a41..819092dd0 100644 --- a/Classes/PHPExcel/Shared/Excel5.php +++ b/Classes/PHPExcel/Shared/Excel5.php @@ -51,22 +51,17 @@ public static function sizeCol($sheet, $col = 'A') $columnDimensions = $sheet->getColumnDimensions(); // first find the true column width in pixels (uncollapsed and unhidden) - if ( isset($columnDimensions[$col]) and $columnDimensions[$col]->getWidth() != -1 ) { - + if (isset($columnDimensions[$col]) and $columnDimensions[$col]->getWidth() != -1) { // then we have column dimension with explicit width $columnDimension = $columnDimensions[$col]; $width = $columnDimension->getWidth(); $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); - } else if ($sheet->getDefaultColumnDimension()->getWidth() != -1) { - // then we have default column dimension with explicit width $defaultColumnDimension = $sheet->getDefaultColumnDimension(); $width = $defaultColumnDimension->getWidth(); $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); - } else { - // we don't even have any default column dimension. Width depends on default font $pixelWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($font, true); } @@ -98,30 +93,24 @@ public static function sizeRow($sheet, $row = 1) $rowDimensions = $sheet->getRowDimensions(); // first find the true row height in pixels (uncollapsed and unhidden) - if ( isset($rowDimensions[$row]) and $rowDimensions[$row]->getRowHeight() != -1) { - + if (isset($rowDimensions[$row]) and $rowDimensions[$row]->getRowHeight() != -1) { // then we have a row dimension $rowDimension = $rowDimensions[$row]; $rowHeight = $rowDimension->getRowHeight(); $pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10 - } else if ($sheet->getDefaultRowDimension()->getRowHeight() != -1) { - // then we have a default row dimension with explicit height $defaultRowDimension = $sheet->getDefaultRowDimension(); $rowHeight = $defaultRowDimension->getRowHeight(); $pixelRowHeight = PHPExcel_Shared_Drawing::pointsToPixels($rowHeight); - } else { - // we don't even have any default row dimension. Height depends on default font $pointRowHeight = PHPExcel_Shared_Font::getDefaultRowHeightByFont($font); $pixelRowHeight = PHPExcel_Shared_Font::fontSizeToPixels($pointRowHeight); - } // now find the effective row height in pixels - if ( isset($rowDimensions[$row]) and !$rowDimensions[$row]->getVisible() ) { + if (isset($rowDimensions[$row]) and !$rowDimensions[$row]->getVisible()) { $effectivePixelRowHeight = 0; } else { $effectivePixelRowHeight = $pixelRowHeight; @@ -313,5 +302,4 @@ public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offs return $twoAnchor; } - } diff --git a/Classes/PHPExcel/Shared/File.php b/Classes/PHPExcel/Shared/File.php index e2af00ee2..6e04857af 100644 --- a/Classes/PHPExcel/Shared/File.php +++ b/Classes/PHPExcel/Shared/File.php @@ -152,18 +152,18 @@ public static function sys_get_temp_dir() // sys_get_temp_dir is only available since PHP 5.2.1 // http://php.net/manual/en/function.sys-get-temp-dir.php#94119 - if ( !function_exists('sys_get_temp_dir')) { - if ($temp = getenv('TMP') ) { + if (!function_exists('sys_get_temp_dir')) { + if ($temp = getenv('TMP')) { if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } } - if ($temp = getenv('TEMP') ) { + if ($temp = getenv('TEMP')) { if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } } - if ($temp = getenv('TMPDIR') ) { + if ($temp = getenv('TMPDIR')) { if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php index 43451cb9f..23d087e7e 100644 --- a/Classes/PHPExcel/Shared/Font.php +++ b/Classes/PHPExcel/Shared/Font.php @@ -37,7 +37,7 @@ class PHPExcel_Shared_Font { /* Methods for resolving autosize value */ const AUTOSIZE_METHOD_APPROX = 'approx'; - const AUTOSIZE_METHOD_EXACT = 'exact'; + const AUTOSIZE_METHOD_EXACT = 'exact'; private static $_autoSizeMethods = array( self::AUTOSIZE_METHOD_APPROX, @@ -48,84 +48,84 @@ class PHPExcel_Shared_Font const CHARSET_ANSI_LATIN = 0x00; const CHARSET_SYSTEM_DEFAULT = 0x01; const CHARSET_SYMBOL = 0x02; - const CHARSET_APPLE_ROMAN = 0x4D; + const CHARSET_APPLE_ROMAN = 0x4D; const CHARSET_ANSI_JAPANESE_SHIFTJIS = 0x80; const CHARSET_ANSI_KOREAN_HANGUL = 0x81; - const CHARSET_ANSI_KOREAN_JOHAB = 0x82; - const CHARSET_ANSI_CHINESE_SIMIPLIFIED = 0x86; // gb2312 - const CHARSET_ANSI_CHINESE_TRADITIONAL = 0x88; // big5 + const CHARSET_ANSI_KOREAN_JOHAB = 0x82; + const CHARSET_ANSI_CHINESE_SIMIPLIFIED = 0x86; // gb2312 + const CHARSET_ANSI_CHINESE_TRADITIONAL = 0x88; // big5 const CHARSET_ANSI_GREEK = 0xA1; - const CHARSET_ANSI_TURKISH = 0xA2; - const CHARSET_ANSI_VIETNAMESE = 0xA3; - const CHARSET_ANSI_HEBREW = 0xB1; - const CHARSET_ANSI_ARABIC = 0xB2; - const CHARSET_ANSI_BALTIC = 0xBA; - const CHARSET_ANSI_CYRILLIC = 0xCC; - const CHARSET_ANSI_THAI = 0xDD; - const CHARSET_ANSI_LATIN_II = 0xEE; - const CHARSET_OEM_LATIN_I = 0xFF; + const CHARSET_ANSI_TURKISH = 0xA2; + const CHARSET_ANSI_VIETNAMESE = 0xA3; + const CHARSET_ANSI_HEBREW = 0xB1; + const CHARSET_ANSI_ARABIC = 0xB2; + const CHARSET_ANSI_BALTIC = 0xBA; + const CHARSET_ANSI_CYRILLIC = 0xCC; + const CHARSET_ANSI_THAI = 0xDD; + const CHARSET_ANSI_LATIN_II = 0xEE; + const CHARSET_OEM_LATIN_I = 0xFF; // XXX: Constants created! /** Font filenames */ - const ARIAL = 'arial.ttf'; + const ARIAL = 'arial.ttf'; const ARIAL_BOLD = 'arialbd.ttf'; - const ARIAL_ITALIC = 'ariali.ttf'; - const ARIAL_BOLD_ITALIC = 'arialbi.ttf'; + const ARIAL_ITALIC = 'ariali.ttf'; + const ARIAL_BOLD_ITALIC = 'arialbi.ttf'; - const CALIBRI = 'CALIBRI.TTF'; - const CALIBRI_BOLD = 'CALIBRIB.TTF'; + const CALIBRI = 'CALIBRI.TTF'; + const CALIBRI_BOLD = 'CALIBRIB.TTF'; const CALIBRI_ITALIC = 'CALIBRII.TTF'; - const CALIBRI_BOLD_ITALIC = 'CALIBRIZ.TTF'; + const CALIBRI_BOLD_ITALIC = 'CALIBRIZ.TTF'; - const COMIC_SANS_MS = 'comic.ttf'; + const COMIC_SANS_MS = 'comic.ttf'; const COMIC_SANS_MS_BOLD = 'comicbd.ttf'; - const COURIER_NEW = 'cour.ttf'; - const COURIER_NEW_BOLD = 'courbd.ttf'; + const COURIER_NEW = 'cour.ttf'; + const COURIER_NEW_BOLD = 'courbd.ttf'; const COURIER_NEW_ITALIC = 'couri.ttf'; - const COURIER_NEW_BOLD_ITALIC = 'courbi.ttf'; + const COURIER_NEW_BOLD_ITALIC = 'courbi.ttf'; - const GEORGIA = 'georgia.ttf'; - const GEORGIA_BOLD = 'georgiab.ttf'; + const GEORGIA = 'georgia.ttf'; + const GEORGIA_BOLD = 'georgiab.ttf'; const GEORGIA_ITALIC = 'georgiai.ttf'; - const GEORGIA_BOLD_ITALIC = 'georgiaz.ttf'; + const GEORGIA_BOLD_ITALIC = 'georgiaz.ttf'; const IMPACT = 'impact.ttf'; - const LIBERATION_SANS = 'LiberationSans-Regular.ttf'; - const LIBERATION_SANS_BOLD = 'LiberationSans-Bold.ttf'; + const LIBERATION_SANS = 'LiberationSans-Regular.ttf'; + const LIBERATION_SANS_BOLD = 'LiberationSans-Bold.ttf'; const LIBERATION_SANS_ITALIC = 'LiberationSans-Italic.ttf'; - const LIBERATION_SANS_BOLD_ITALIC = 'LiberationSans-BoldItalic.ttf'; + const LIBERATION_SANS_BOLD_ITALIC = 'LiberationSans-BoldItalic.ttf'; const LUCIDA_CONSOLE = 'lucon.ttf'; - const LUCIDA_SANS_UNICODE = 'l_10646.ttf'; + const LUCIDA_SANS_UNICODE = 'l_10646.ttf'; - const MICROSOFT_SANS_SERIF = 'micross.ttf'; + const MICROSOFT_SANS_SERIF = 'micross.ttf'; - const PALATINO_LINOTYPE = 'pala.ttf'; + const PALATINO_LINOTYPE = 'pala.ttf'; const PALATINO_LINOTYPE_BOLD = 'palab.ttf'; - const PALATINO_LINOTYPE_ITALIC = 'palai.ttf'; - const PALATINO_LINOTYPE_BOLD_ITALIC = 'palabi.ttf'; + const PALATINO_LINOTYPE_ITALIC = 'palai.ttf'; + const PALATINO_LINOTYPE_BOLD_ITALIC = 'palabi.ttf'; const SYMBOL = 'symbol.ttf'; const TAHOMA = 'tahoma.ttf'; - const TAHOMA_BOLD = 'tahomabd.ttf'; + const TAHOMA_BOLD = 'tahomabd.ttf'; - const TIMES_NEW_ROMAN = 'times.ttf'; - const TIMES_NEW_ROMAN_BOLD = 'timesbd.ttf'; + const TIMES_NEW_ROMAN = 'times.ttf'; + const TIMES_NEW_ROMAN_BOLD = 'timesbd.ttf'; const TIMES_NEW_ROMAN_ITALIC = 'timesi.ttf'; - const TIMES_NEW_ROMAN_BOLD_ITALIC = 'timesbi.ttf'; + const TIMES_NEW_ROMAN_BOLD_ITALIC = 'timesbi.ttf'; - const TREBUCHET_MS = 'trebuc.ttf'; - const TREBUCHET_MS_BOLD = 'trebucbd.ttf'; - const TREBUCHET_MS_ITALIC = 'trebucit.ttf'; - const TREBUCHET_MS_BOLD_ITALIC = 'trebucbi.ttf'; + const TREBUCHET_MS = 'trebuc.ttf'; + const TREBUCHET_MS_BOLD = 'trebucbd.ttf'; + const TREBUCHET_MS_ITALIC = 'trebucit.ttf'; + const TREBUCHET_MS_BOLD_ITALIC = 'trebucbi.ttf'; - const VERDANA = 'verdana.ttf'; - const VERDANA_BOLD = 'verdanab.ttf'; + const VERDANA = 'verdana.ttf'; + const VERDANA_BOLD = 'verdanab.ttf'; const VERDANA_ITALIC = 'verdanai.ttf'; - const VERDANA_BOLD_ITALIC = 'verdanaz.ttf'; + const VERDANA_BOLD_ITALIC = 'verdanaz.ttf'; /** * AutoSize method @@ -196,12 +196,12 @@ class PHPExcel_Shared_Font */ public static function setAutoSizeMethod($pValue = self::AUTOSIZE_METHOD_APPROX) { - if (!in_array($pValue,self::$_autoSizeMethods)) { - return FALSE; + if (!in_array($pValue, self::$_autoSizeMethods)) { + return false; } self::$autoSizeMethod = $pValue; - return TRUE; + return true; } /** @@ -249,7 +249,8 @@ public static function getTrueTypeFontPath() * @param PHPExcel_Style_Font|NULL $defaultFont Font object * @return integer Column width */ - public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText = '', $rotation = 0, PHPExcel_Style_Font $defaultFont = null) { + public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText = '', $rotation = 0, PHPExcel_Style_Font $defaultFont = null) + { // If it is rich text, use plain text if ($cellText instanceof PHPExcel_RichText) { $cellText = $cellText->getPlainText(); @@ -301,7 +302,8 @@ public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText * @return int * @throws PHPExcel_Exception */ - public static function getTextWidthPixelsExact($text, PHPExcel_Style_Font $font, $rotation = 0) { + public static function getTextWidthPixelsExact($text, PHPExcel_Style_Font $font, $rotation = 0) + { if (!function_exists('imagettfbbox')) { throw new PHPExcel_Exception('GD library needs to be enabled'); } @@ -391,7 +393,8 @@ public static function getTextWidthPixelsApprox($columnText, PHPExcel_Style_Font * @param int $fontSizeInPoints Font size (in points) * @return int Font size (in pixels) */ - public static function fontSizeToPixels($fontSizeInPoints = 11) { + public static function fontSizeToPixels($fontSizeInPoints = 11) + { return (int) ((4 / 3) * $fontSizeInPoints); } @@ -401,7 +404,8 @@ public static function fontSizeToPixels($fontSizeInPoints = 11) { * @param int $sizeInInch Font size (in inch) * @return int Size (in pixels) */ - public static function inchSizeToPixels($sizeInInch = 1) { + public static function inchSizeToPixels($sizeInInch = 1) + { return ($sizeInInch * 96); } @@ -411,7 +415,8 @@ public static function inchSizeToPixels($sizeInInch = 1) { * @param int $sizeInCm Font size (in centimeters) * @return int Size (in pixels) */ - public static function centimeterSizeToPixels($sizeInCm = 1) { + public static function centimeterSizeToPixels($sizeInCm = 1) + { return ($sizeInCm * 37.795275591); } @@ -421,14 +426,15 @@ public static function centimeterSizeToPixels($sizeInCm = 1) { * @param PHPExcel_Style_Font * @return string Path to TrueType font file */ - public static function getTrueTypeFontFileFromFont($font) { + public static function getTrueTypeFontFileFromFont($font) + { if (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath)) { throw new PHPExcel_Exception('Valid directory to TrueType Font files not specified'); } $name = $font->getName(); $bold = $font->getBold(); - $italic = $font->getItalic(); + $italic = $font->getItalic(); // Check if we can map font to true type font file switch ($name) { @@ -438,95 +444,79 @@ public static function getTrueTypeFontFileFromFont($font) { : ($italic ? self::ARIAL_ITALIC : self::ARIAL) ); break; - case 'Calibri': $fontFile = ( $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD) : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI) ); break; - case 'Courier New': $fontFile = ( $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD) : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW) ); break; - case 'Comic Sans MS': $fontFile = ( $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS ); break; - case 'Georgia': $fontFile = ( $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD) : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA) ); break; - case 'Impact': $fontFile = self::IMPACT; break; - case 'Liberation Sans': $fontFile = ( $bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD) : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS) ); break; - case 'Lucida Console': $fontFile = self::LUCIDA_CONSOLE; break; - case 'Lucida Sans Unicode': $fontFile = self::LUCIDA_SANS_UNICODE; break; - case 'Microsoft Sans Serif': $fontFile = self::MICROSOFT_SANS_SERIF; break; - case 'Palatino Linotype': $fontFile = ( $bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD) : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE) ); break; - case 'Symbol': $fontFile = self::SYMBOL; break; - case 'Tahoma': $fontFile = ( $bold ? self::TAHOMA_BOLD : self::TAHOMA ); break; - case 'Times New Roman': $fontFile = ( $bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD) : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN) ); break; - case 'Trebuchet MS': $fontFile = ( $bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD) : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS) ); break; - case 'Verdana': $fontFile = ( $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD) : ($italic ? self::VERDANA_ITALIC : self::VERDANA) ); break; - default: throw new PHPExcel_Exception('Unknown font name "'. $name .'". Cannot map to TrueType font file'); break; @@ -536,7 +526,7 @@ public static function getTrueTypeFontFileFromFont($font) { // Check if file actually exists if (!file_exists($fontFile)) { - throw New PHPExcel_Exception('TrueType Font file not found'); + throw new PHPExcel_Exception('TrueType Font file not found'); } return $fontFile; @@ -552,11 +542,16 @@ public static function getCharsetFromFontName($name) { switch ($name) { // Add more cases. Check FONT records in real Excel files. - case 'EucrosiaUPC': return self::CHARSET_ANSI_THAI; - case 'Wingdings': return self::CHARSET_SYMBOL; - case 'Wingdings 2': return self::CHARSET_SYMBOL; - case 'Wingdings 3': return self::CHARSET_SYMBOL; - default: return self::CHARSET_ANSI_LATIN; + case 'EucrosiaUPC': + return self::CHARSET_ANSI_THAI; + case 'Wingdings': + return self::CHARSET_SYMBOL; + case 'Wingdings 2': + return self::CHARSET_SYMBOL; + case 'Wingdings 3': + return self::CHARSET_SYMBOL; + default: + return self::CHARSET_ANSI_LATIN; } } @@ -609,44 +604,36 @@ public static function getDefaultRowHeightByFont(PHPExcel_Style_Font $font) // inspection of Arial 10 workbook says 12.75pt ~17px $rowHeight = 12.75; break; - case 9: // inspection of Arial 9 workbook says 12.00pt ~16px $rowHeight = 12; break; - case 8: // inspection of Arial 8 workbook says 11.25pt ~15px $rowHeight = 11.25; break; - case 7: // inspection of Arial 7 workbook says 9.00pt ~12px $rowHeight = 9; break; - case 6: case 5: // inspection of Arial 5,6 workbook says 8.25pt ~11px $rowHeight = 8.25; break; - case 4: // inspection of Arial 4 workbook says 6.75pt ~9px $rowHeight = 6.75; break; - case 3: // inspection of Arial 3 workbook says 6.00pt ~8px $rowHeight = 6; break; - case 2: case 1: // inspection of Arial 1,2 workbook says 5.25pt ~7px $rowHeight = 5.25; break; - default: // use Arial 10 workbook as an approximation, extrapolation $rowHeight = 12.75 * $font->getSize() / 10; @@ -660,49 +647,40 @@ public static function getDefaultRowHeightByFont(PHPExcel_Style_Font $font) // inspection of Calibri 11 workbook says 15.00pt ~20px $rowHeight = 15; break; - case 10: // inspection of Calibri 10 workbook says 12.75pt ~17px $rowHeight = 12.75; break; - case 9: // inspection of Calibri 9 workbook says 12.00pt ~16px $rowHeight = 12; break; - case 8: // inspection of Calibri 8 workbook says 11.25pt ~15px $rowHeight = 11.25; break; - case 7: // inspection of Calibri 7 workbook says 9.00pt ~12px $rowHeight = 9; break; - case 6: case 5: // inspection of Calibri 5,6 workbook says 8.25pt ~11px $rowHeight = 8.25; break; - case 4: // inspection of Calibri 4 workbook says 6.75pt ~9px $rowHeight = 6.75; break; - case 3: // inspection of Calibri 3 workbook says 6.00pt ~8px $rowHeight = 6.00; break; - case 2: case 1: // inspection of Calibri 1,2 workbook says 5.25pt ~7px $rowHeight = 5.25; break; - default: // use Calibri 11 workbook as an approximation, extrapolation $rowHeight = 15 * $font->getSize() / 11; @@ -716,51 +694,42 @@ public static function getDefaultRowHeightByFont(PHPExcel_Style_Font $font) // inspection of Verdana 10 workbook says 12.75pt ~17px $rowHeight = 12.75; break; - case 9: // inspection of Verdana 9 workbook says 11.25pt ~15px $rowHeight = 11.25; break; - case 8: // inspection of Verdana 8 workbook says 10.50pt ~14px $rowHeight = 10.50; break; - case 7: // inspection of Verdana 7 workbook says 9.00pt ~12px $rowHeight = 9.00; break; - case 6: case 5: // inspection of Verdana 5,6 workbook says 8.25pt ~11px $rowHeight = 8.25; break; - case 4: // inspection of Verdana 4 workbook says 6.75pt ~9px $rowHeight = 6.75; break; - case 3: // inspection of Verdana 3 workbook says 6.00pt ~8px $rowHeight = 6; break; - case 2: case 1: // inspection of Verdana 1,2 workbook says 5.25pt ~7px $rowHeight = 5.25; break; - default: // use Verdana 10 workbook as an approximation, extrapolation $rowHeight = 12.75 * $font->getSize() / 10; break; } break; - default: // just use Calibri as an approximation $rowHeight = 15 * $font->getSize() / 11; @@ -769,5 +738,4 @@ public static function getDefaultRowHeightByFont(PHPExcel_Style_Font $font) return $rowHeight; } - } diff --git a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php index 10f3f4b41..d7d1f051b 100644 --- a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php +++ b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php @@ -83,10 +83,7 @@ public function stream_open($path, $mode, $options, &$openedPath) // 25 is length of "ole-chainedblockstream://" parse_str(substr($path, 25), $this->params); - if (!isset($this->params['oleInstanceId'], - $this->params['blockId'], - $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) { - + if (!isset($this->params['oleInstanceId'], $this->params['blockId'], $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) { if ($options & STREAM_REPORT_ERRORS) { trigger_error('OLE stream not found', E_USER_WARNING); } @@ -96,10 +93,7 @@ public function stream_open($path, $mode, $options, &$openedPath) $blockId = $this->params['blockId']; $this->data = ''; - if (isset($this->params['size']) && - $this->params['size'] < $this->ole->bigBlockThreshold && - $blockId != $this->ole->root->_StartBlock) { - + if (isset($this->params['size']) && $this->params['size'] < $this->ole->bigBlockThreshold && $blockId != $this->ole->root->_StartBlock) { // Block id refers to small blocks $rootPos = $this->ole->_getBlockOffset($this->ole->root->_StartBlock); while ($blockId != -2) { diff --git a/Classes/PHPExcel/Shared/OLE/PPS.php b/Classes/PHPExcel/Shared/OLE/PPS.php index 6699f4382..608a892aa 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS.php +++ b/Classes/PHPExcel/Shared/OLE/PPS.php @@ -169,7 +169,7 @@ public function _DataLen() */ public function _getPpsWk() { - $ret = str_pad($this->Name,64,"\x00"); + $ret = str_pad($this->Name, 64, "\x00"); $ret .= pack("v", strlen($this->Name) + 2) // 66 . pack("c", $this->Type) // 67 @@ -202,9 +202,9 @@ public function _getPpsWk() */ public static function _savePpsSetPnt(&$raList, $to_save, $depth = 0) { - if ( !is_array($to_save) || (empty($to_save)) ) { + if (!is_array($to_save) || (empty($to_save))) { return 0xFFFFFFFF; - } elseif ( count($to_save) == 1 ) { + } elseif (count($to_save) == 1) { $cnt = count($raList); // If the first entry, it's the root... Don't clone it! $raList[$cnt] = ( $depth == 0 ) ? $to_save[0] : clone $to_save[0]; diff --git a/Classes/PHPExcel/Shared/OLE/PPS/File.php b/Classes/PHPExcel/Shared/OLE/PPS/File.php index f0be587a3..1ca337cba 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/File.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/File.php @@ -28,7 +28,7 @@ * @package PHPExcel_Shared_OLE */ class PHPExcel_Shared_OLE_PPS_File extends PHPExcel_Shared_OLE_PPS - { +{ /** * The constructor * @@ -38,17 +38,7 @@ class PHPExcel_Shared_OLE_PPS_File extends PHPExcel_Shared_OLE_PPS */ public function __construct($name) { - parent::__construct( - null, - $name, - PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE, - null, - null, - null, - null, - null, - '', - array()); + parent::__construct(null, $name, PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE, null, null, null, null, null, '', array()); } /** diff --git a/Classes/PHPExcel/Shared/OLE/PPS/Root.php b/Classes/PHPExcel/Shared/OLE/PPS/Root.php index 7e50dadf2..bd2c4cf78 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/Root.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/Root.php @@ -28,13 +28,13 @@ * @package PHPExcel_Shared_OLE */ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS - { +{ /** * Directory for temporary files * @var string */ - protected $_tmp_dir = NULL; + protected $_tmp_dir = null; /** * @param integer $time_1st A timestamp @@ -44,17 +44,7 @@ public function __construct($time_1st, $time_2nd, $raChild) { $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); - parent::__construct( - null, - PHPExcel_Shared_OLE::Asc2Ucs('Root Entry'), - PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT, - null, - null, - null, - $time_1st, - $time_2nd, - null, - $raChild); + parent::__construct(null, PHPExcel_Shared_OLE::Asc2Ucs('Root Entry'), PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT, null, null, null, $time_1st, $time_2nd, null, $raChild); } /** @@ -78,13 +68,13 @@ public function save($filename) if (is_resource($filename)) { $this->_FILEH_ = $filename; - } else if ($filename == '-' || $filename == '') { - if ($this->_tmp_dir === NULL) - $this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir(); - $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root"); - $this->_FILEH_ = fopen($this->_tmp_filename,"w+b"); - if ($this->_FILEH_ == false) { - throw new PHPExcel_Writer_Exception("Can't create temporary file."); + } else if ($filename == '-' || $filename == '') { + if ($this->_tmp_dir === null) + $this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir(); + $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root"); + $this->_FILEH_ = fopen($this->_tmp_filename,"w+b"); + if ($this->_FILEH_ == false) { + throw new PHPExcel_Writer_Exception("Can't create temporary file."); } } else { $this->_FILEH_ = fopen($filename, "wb"); @@ -94,7 +84,7 @@ public function save($filename) } // Make an array of PPS's (for Save) $aList = array(); - PHPExcel_Shared_OLE_PPS::_savePpsSetPnt($aList, array($this)); + PHPExcel_Shared_OLE_PPS::_savePpsSetPnt($aList, array($this)); // calculate values for header list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo); // Save Header @@ -447,7 +437,7 @@ public function _saveBbd($iSbdSize, $iBsize, $iPpsCnt) if ($iBdCnt > $i1stBdL) { $iN=0; $iNb=0; - for ($i = $i1stBdL;$i < $iBdCnt; $i++, ++$iN) { + for ($i = $i1stBdL; $i < $iBdCnt; $i++, ++$iN) { if ($iN >= ($iBbCnt - 1)) { $iN = 0; ++$iNb; diff --git a/Classes/PHPExcel/Shared/OLERead.php b/Classes/PHPExcel/Shared/OLERead.php index 143e22d3d..f43567d74 100644 --- a/Classes/PHPExcel/Shared/OLERead.php +++ b/Classes/PHPExcel/Shared/OLERead.php @@ -32,39 +32,39 @@ class PHPExcel_Shared_OLERead { private $data = ''; // OLE identifier - const IDENTIFIER_OLE = IDENTIFIER_OLE; + const IDENTIFIER_OLE = IDENTIFIER_OLE; // Size of a sector = 512 bytes const BIG_BLOCK_SIZE = 0x200; // Size of a short sector = 64 bytes - const SMALL_BLOCK_SIZE = 0x40; + const SMALL_BLOCK_SIZE = 0x40; // Size of a directory entry always = 128 bytes - const PROPERTY_STORAGE_BLOCK_SIZE = 0x80; + const PROPERTY_STORAGE_BLOCK_SIZE = 0x80; // Minimum size of a standard stream = 4096 bytes, streams smaller than this are stored as short streams - const SMALL_BLOCK_THRESHOLD = 0x1000; + const SMALL_BLOCK_THRESHOLD = 0x1000; // header offsets const NUM_BIG_BLOCK_DEPOT_BLOCKS_POS = 0x2c; - const ROOT_START_BLOCK_POS = 0x30; - const SMALL_BLOCK_DEPOT_BLOCK_POS = 0x3c; - const EXTENSION_BLOCK_POS = 0x44; - const NUM_EXTENSION_BLOCK_POS = 0x48; + const ROOT_START_BLOCK_POS = 0x30; + const SMALL_BLOCK_DEPOT_BLOCK_POS = 0x3c; + const EXTENSION_BLOCK_POS = 0x44; + const NUM_EXTENSION_BLOCK_POS = 0x48; const BIG_BLOCK_DEPOT_BLOCKS_POS = 0x4c; // property storage offsets (directory offsets) - const SIZE_OF_NAME_POS = 0x40; - const TYPE_POS = 0x42; - const START_BLOCK_POS = 0x74; - const SIZE_POS = 0x78; + const SIZE_OF_NAME_POS = 0x40; + const TYPE_POS = 0x42; + const START_BLOCK_POS = 0x74; + const SIZE_POS = 0x78; - public $wrkbook = null; - public $summaryInformation = null; - public $documentSummaryInformation = null; + public $wrkbook = null; + public $summaryInformation = null; + public $documentSummaryInformation = null; /** @@ -82,7 +82,7 @@ public function read($sFileName) // Get the file identifier // Don't bother reading the whole file until we know it's a valid OLE file - $this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8); + $this->data = file_get_contents($sFileName, false, null, 0, 8); // Check OLE identifier if ($this->data != self::IDENTIFIER_OLE) { @@ -172,7 +172,7 @@ public function read($sFileName) */ public function getStream($stream) { - if ($stream === NULL) { + if ($stream === null) { return null; } @@ -197,7 +197,9 @@ public function getStream($stream) ++$numBlocks; } - if ($numBlocks == 0) return ''; + if ($numBlocks == 0) { + return ''; + } $block = $this->props[$stream]['startBlock']; @@ -222,18 +224,19 @@ private function _readData($bl) $block = $bl; $data = ''; - while ($block != -2) { + while ($block != -2) { $pos = ($block + 1) * self::BIG_BLOCK_SIZE; $data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); $block = self::_GetInt4d($this->bigBlockChain, $block*4); } return $data; - } + } /** * Read entries in the directory stream. */ - private function _readPropertySets() { + private function _readPropertySets() + { $offset = 0; // loop through entires, each entry is 128 bytes @@ -254,14 +257,14 @@ private function _readPropertySets() { $size = self::_GetInt4d($d, self::SIZE_POS); - $name = str_replace("\x00", "", substr($d,0, $nameSize)); - + $name = str_replace("\x00", "", substr($d, 0, $nameSize)); - $this->props[] = array ( + $this->props[] = array( 'name' => $name, 'type' => $type, 'startBlock' => $startBlock, - 'size' => $size); + 'size' => $size + ); // tmp helper to simplify checks $upName = strtoupper($name); @@ -269,8 +272,7 @@ private function _readPropertySets() { // Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook) if (($upName === 'WORKBOOK') || ($upName === 'BOOK')) { $this->wrkbook = count($this->props) - 1; - } - else if ( $upName === 'ROOT ENTRY' || $upName === 'R') { + } else if ($upName === 'ROOT ENTRY' || $upName === 'R') { // Root entry $this->rootentry = count($this->props) - 1; } @@ -289,7 +291,6 @@ private function _readPropertySets() { $offset += self::PROPERTY_STORAGE_BLOCK_SIZE; } - } /** @@ -313,5 +314,4 @@ private static function _GetInt4d($data, $pos) } return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24; } - } diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index 9fd7b3456..6ead8e436 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -27,7 +27,7 @@ // ----- Constants if (!defined('PCLZIP_READ_BLOCK_SIZE')) { - define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); + define('PCLZIP_READ_BLOCK_SIZE', 2048); } // ----- File list separator @@ -38,10 +38,10 @@ // However notice that changing this value, may have impact on existing // scripts, using space separated filenames. // Recommanded values for compatibility with older versions : -//define( 'PCLZIP_SEPARATOR', ' ' ); +//define('PCLZIP_SEPARATOR', ' '); // Recommanded values for smart separation of filenames. if (!defined('PCLZIP_SEPARATOR')) { - define( 'PCLZIP_SEPARATOR', ',' ); + define('PCLZIP_SEPARATOR', ','); } // ----- Error configuration @@ -50,7 +50,7 @@ // you must ensure that you have included PclError library. // [2,...] : reserved for futur use if (!defined('PCLZIP_ERROR_EXTERNAL')) { - define( 'PCLZIP_ERROR_EXTERNAL', 0 ); + define('PCLZIP_ERROR_EXTERNAL', 0); } // ----- Optional static temporary directory @@ -60,10 +60,10 @@ // - MUST BE terminated by a '/'. // - MUST be a valid, already created directory // Samples : -// define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); -// define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); +// define('PCLZIP_TEMPORARY_DIR', '/temp/'); +// define('PCLZIP_TEMPORARY_DIR', 'C:/Temp/'); if (!defined('PCLZIP_TEMPORARY_DIR')) { - define( 'PCLZIP_TEMPORARY_DIR', '' ); + define('PCLZIP_TEMPORARY_DIR', ''); } // ----- Optional threshold ratio for use of temporary files @@ -73,9 +73,9 @@ // threshold = memory_limit * ratio. // Recommended values are under 0.5. Default 0.47. // Samples : -// define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 ); +// define('PCLZIP_TEMPORARY_FILE_RATIO', 0.5); if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { - define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 ); + define('PCLZIP_TEMPORARY_FILE_RATIO', 0.47); } // -------------------------------------------------------------------------------- @@ -100,77 +100,77 @@ // -12 : Unable to rename file (rename) // -13 : Invalid header checksum // -14 : Invalid archive size -define( 'PCLZIP_ERR_USER_ABORTED', 2 ); -define( 'PCLZIP_ERR_NO_ERROR', 0 ); -define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); -define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); -define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); -define( 'PCLZIP_ERR_MISSING_FILE', -4 ); -define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); -define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); -define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); -define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); -define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); -define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); -define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); -define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); -define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); -define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); -define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); -define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); -define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); -define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); -define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); -define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); -define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); +define('PCLZIP_ERR_USER_ABORTED', 2); +define('PCLZIP_ERR_NO_ERROR', 0); +define('PCLZIP_ERR_WRITE_OPEN_FAIL', -1); +define('PCLZIP_ERR_READ_OPEN_FAIL', -2); +define('PCLZIP_ERR_INVALID_PARAMETER', -3); +define('PCLZIP_ERR_MISSING_FILE', -4); +define('PCLZIP_ERR_FILENAME_TOO_LONG', -5); +define('PCLZIP_ERR_INVALID_ZIP', -6); +define('PCLZIP_ERR_BAD_EXTRACTED_FILE', -7); +define('PCLZIP_ERR_DIR_CREATE_FAIL', -8); +define('PCLZIP_ERR_BAD_EXTENSION', -9); +define('PCLZIP_ERR_BAD_FORMAT', -10); +define('PCLZIP_ERR_DELETE_FILE_FAIL', -11); +define('PCLZIP_ERR_RENAME_FILE_FAIL', -12); +define('PCLZIP_ERR_BAD_CHECKSUM', -13); +define('PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14); +define('PCLZIP_ERR_MISSING_OPTION_VALUE', -15); +define('PCLZIP_ERR_INVALID_OPTION_VALUE', -16); +define('PCLZIP_ERR_ALREADY_A_DIRECTORY', -17); +define('PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18); +define('PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19); +define('PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20); +define('PCLZIP_ERR_DIRECTORY_RESTRICTION', -21); // ----- Options values -define( 'PCLZIP_OPT_PATH', 77001 ); -define( 'PCLZIP_OPT_ADD_PATH', 77002 ); -define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); -define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); -define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); -define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); -define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); -define( 'PCLZIP_OPT_BY_NAME', 77008 ); -define( 'PCLZIP_OPT_BY_INDEX', 77009 ); -define( 'PCLZIP_OPT_BY_EREG', 77010 ); -define( 'PCLZIP_OPT_BY_PREG', 77011 ); -define( 'PCLZIP_OPT_COMMENT', 77012 ); -define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); -define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); -define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); -define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); -define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); +define('PCLZIP_OPT_PATH', 77001); +define('PCLZIP_OPT_ADD_PATH', 77002); +define('PCLZIP_OPT_REMOVE_PATH', 77003); +define('PCLZIP_OPT_REMOVE_ALL_PATH', 77004); +define('PCLZIP_OPT_SET_CHMOD', 77005); +define('PCLZIP_OPT_EXTRACT_AS_STRING', 77006); +define('PCLZIP_OPT_NO_COMPRESSION', 77007); +define('PCLZIP_OPT_BY_NAME', 77008); +define('PCLZIP_OPT_BY_INDEX', 77009); +define('PCLZIP_OPT_BY_EREG', 77010); +define('PCLZIP_OPT_BY_PREG', 77011); +define('PCLZIP_OPT_COMMENT', 77012); +define('PCLZIP_OPT_ADD_COMMENT', 77013); +define('PCLZIP_OPT_PREPEND_COMMENT', 77014); +define('PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015); +define('PCLZIP_OPT_REPLACE_NEWER', 77016); +define('PCLZIP_OPT_STOP_ON_ERROR', 77017); // Having big trouble with crypt. Need to multiply 2 long int // which is not correctly supported by PHP ... -//define( 'PCLZIP_OPT_CRYPT', 77018 ); -define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); -define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 ); -define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias -define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 ); -define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias -define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 ); -define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias +//define('PCLZIP_OPT_CRYPT', 77018); +define('PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019); +define('PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020); +define('PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020); // alias +define('PCLZIP_OPT_TEMP_FILE_ON', 77021); +define('PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021); // alias +define('PCLZIP_OPT_TEMP_FILE_OFF', 77022); +define('PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022); // alias // ----- File description attributes -define( 'PCLZIP_ATT_FILE_NAME', 79001 ); -define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); -define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); -define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); -define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); -define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); +define('PCLZIP_ATT_FILE_NAME', 79001); +define('PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002); +define('PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003); +define('PCLZIP_ATT_FILE_MTIME', 79004); +define('PCLZIP_ATT_FILE_CONTENT', 79005); +define('PCLZIP_ATT_FILE_COMMENT', 79006); // ----- Call backs values -define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); -define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); -define( 'PCLZIP_CB_PRE_ADD', 78003 ); -define( 'PCLZIP_CB_POST_ADD', 78004 ); +define('PCLZIP_CB_PRE_EXTRACT', 78001); +define('PCLZIP_CB_POST_EXTRACT', 78002); +define('PCLZIP_CB_PRE_ADD', 78003); +define('PCLZIP_CB_POST_ADD', 78004); /* For futur use -define( 'PCLZIP_CB_PRE_LIST', 78005 ); -define( 'PCLZIP_CB_POST_LIST', 78006 ); -define( 'PCLZIP_CB_PRE_DELETE', 78007 ); -define( 'PCLZIP_CB_POST_DELETE', 78008 ); +define('PCLZIP_CB_PRE_LIST', 78005); +define('PCLZIP_CB_POST_LIST', 78006); +define('PCLZIP_CB_PRE_DELETE', 78007); +define('PCLZIP_CB_POST_DELETE', 78008); */ // -------------------------------------------------------------------------------- @@ -276,7 +276,7 @@ function create($p_filelist) // ----- Set default values $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + $v_options[PCLZIP_OPT_NO_COMPRESSION] = false; // ----- Look for variable options arguments $v_size = func_num_args(); @@ -320,8 +320,7 @@ function create($p_filelist) if ($v_size == 2) { $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; } else if ($v_size > 2) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Invalid number / type of arguments"); + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); return 0; } } @@ -443,7 +442,7 @@ function add($p_filelist) // ----- Set default values $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + $v_options[PCLZIP_OPT_NO_COMPRESSION] = false; // ----- Look for variable options arguments $v_size = func_num_args(); @@ -687,7 +686,7 @@ function extract() $v_size = func_num_args(); // ----- Default values for option - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; // ----- Look for arguments if ($v_size > 0) { @@ -838,7 +837,7 @@ function extractByIndex($p_index) $v_size = func_num_args(); // ----- Default values for option - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; // ----- Look for arguments if ($v_size > 1) { @@ -890,7 +889,7 @@ function extractByIndex($p_index) $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; } if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; } else { } } else { @@ -921,7 +920,7 @@ function extractByIndex($p_index) // with privParseOptions() $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); $v_options_trick = array(); - $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, array (PCLZIP_OPT_BY_INDEX => 'optional' )); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, array (PCLZIP_OPT_BY_INDEX => 'optional')); if ($v_result != 1) { return 0; } @@ -1121,7 +1120,6 @@ function duplicate($p_archive) // ----- Look if the $p_archive is a PclZip object if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) { - // ----- Duplicate the archive $v_result = $this->privDuplicate($p_archive->zipname); } else if (is_string($p_archive)) { @@ -1219,9 +1217,9 @@ function errorCode() // Description : // Parameters : // -------------------------------------------------------------------------------- - function errorName($p_with_code=false) + function errorName($p_with_code = false) { - $v_name = array ( + $v_name = array( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', @@ -1264,7 +1262,7 @@ function errorName($p_with_code=false) // Description : // Parameters : // -------------------------------------------------------------------------------- - function errorInfo($p_full=false) + function errorInfo($p_full = false) { if (PCLZIP_ERROR_EXTERNAL == 1) { return(PclErrorString()); @@ -1301,7 +1299,7 @@ function errorInfo($p_full=false) // true on success, // false on error, the error code is set. // -------------------------------------------------------------------------------- - function privCheckFormat($p_level=0) + function privCheckFormat($p_level = 0) { $v_result = true; @@ -1354,7 +1352,7 @@ function privCheckFormat($p_level=0) // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- - function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options = false) { $v_result=1; @@ -1386,7 +1384,7 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request } // ----- Get the value - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false); $i++; break; @@ -1439,7 +1437,7 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request $v_result_list[$p_options_list[$i]] = true; break; - case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION: // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log @@ -1450,14 +1448,13 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request // ----- Get the value if (is_string($p_options_list[$i+1]) && ($p_options_list[$i+1] != '')) { - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false); $i++; } else { } - break; - + break; // ----- Look for options that request an array of string for value - case PCLZIP_OPT_BY_NAME : + case PCLZIP_OPT_BY_NAME: // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log @@ -1480,11 +1477,11 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request $i++; break; // ----- Look for options that request an EREG or PREG expression - case PCLZIP_OPT_BY_EREG : + case PCLZIP_OPT_BY_EREG: // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG // to PCLZIP_OPT_BY_PREG $p_options_list[$i] = PCLZIP_OPT_BY_PREG; - case PCLZIP_OPT_BY_PREG : + case PCLZIP_OPT_BY_PREG: //case PCLZIP_OPT_CRYPT : // ----- Check the number of parameters if (($i+1) >= $p_size) { @@ -1507,9 +1504,9 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request break; // ----- Look for options that takes a string - case PCLZIP_OPT_COMMENT : - case PCLZIP_OPT_ADD_COMMENT : - case PCLZIP_OPT_PREPEND_COMMENT : + case PCLZIP_OPT_COMMENT: + case PCLZIP_OPT_ADD_COMMENT: + case PCLZIP_OPT_PREPEND_COMMENT: // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log @@ -1533,7 +1530,7 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request break; // ----- Look for options that request an array of index - case PCLZIP_OPT_BY_INDEX : + case PCLZIP_OPT_BY_INDEX: // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log @@ -1673,7 +1670,7 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request $v_result_list[$p_options_list[$i]] = $v_function_name; $i++; break; - default : + default: // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '" .$p_options_list[$i]."'"); @@ -1762,7 +1759,7 @@ function privOptionDefaultThreshold(&$p_options) // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- - function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options = false) { $v_result=1; @@ -1836,7 +1833,7 @@ function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requ case PCLZIP_ATT_FILE_CONTENT: $p_filedescr['content'] = $v_value; break; - default : + default: // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '".$v_key."'"); @@ -2030,7 +2027,6 @@ function privAdd($p_filedescr_list, &$p_result_list, &$p_options) // ----- Look if the archive exists or is empty if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) { - // ----- Do a create $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); @@ -2341,8 +2337,8 @@ function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) // ----- Look if it is a file or a dir with no all path remove option // or a dir with all its path removed - // if ( (is_file($p_filedescr_list[$j]['filename'])) - // || ( is_dir($p_filedescr_list[$j]['filename']) + // if ( (is_file($p_filedescr_list[$j]['filename'])) + // || ( is_dir($p_filedescr_list[$j]['filename']) if (($p_filedescr_list[$j]['type'] == 'file') || ($p_filedescr_list[$j]['type'] == 'virtual_file') || (($p_filedescr_list[$j]['type'] == 'folder') && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { // ----- Add the file $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, $p_options); @@ -2484,7 +2480,7 @@ function privAddFile($p_filedescr, &$p_header, &$p_options) // ----- Look for a file if ($p_filedescr['type'] == 'file') { // ----- Look for using temporary file to zip - if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { + if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])))) { $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); if ($v_result < PCLZIP_ERR_NO_ERROR) { return $v_result; @@ -2964,8 +2960,7 @@ function privList(&$p_list) // ----- Read each entry for ($i=0; $i<$v_central_dir['entries']; $i++) { // ----- Read the file header - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) - { + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) { $this->privSwapBackMagicQuotes(); return $v_result; } @@ -3053,7 +3048,7 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all $this->privDisableMagicQuotes(); // ----- Check the path - if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/"))) { + if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path, 1, 2)!=":/"))) { $p_path = "./".$p_path; } @@ -3141,19 +3136,7 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all $v_extract = true; } } - } - // ----- Look for extract by ereg rule - // ereg() is deprecated with PHP 5.3 - /* - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { - $v_extract = true; - } - } - */ - else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + }else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { // ----- Look for extract by preg rule if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { $v_extract = true; @@ -3533,7 +3516,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, } // ----- Look for using temporary file to unzip - if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { + if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])))) { $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); if ($v_result < PCLZIP_ERR_NO_ERROR) { return $v_result; @@ -3546,7 +3529,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, // ----- Decompress the file $v_file_content = @gzinflate($v_buffer); unset($v_buffer); - if ($v_file_content === FALSE) { + if ($v_file_content === false) { // ----- Change the file status // TBC @@ -3856,7 +3839,7 @@ function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); // ----- Decompress the file - if (($p_string = @gzinflate($v_data)) === FALSE) { + if (($p_string = @gzinflate($v_data)) === false) { // TBC } } @@ -4210,7 +4193,7 @@ function privReadEndCentralDir(&$p_central_dir) //$v_bytes = ($v_bytes << 8) | Ord($v_byte); // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. - $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); + $v_bytes = (($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); // ----- Compare the bytes if ($v_bytes == 0x504b0506) @@ -4369,7 +4352,7 @@ function privDeleteByRule(&$p_result_list, &$p_options) // ----- Look for extract by ereg rule // ereg() is deprecated with PHP 5.3 /* - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { @@ -4571,11 +4554,10 @@ function privDeleteByRule(&$p_result_list, &$p_options) // 1 : OK // -1 : Unable to create directory // -------------------------------------------------------------------------------- - function privDirCheck($p_dir, $p_is_dir=false) + function privDirCheck($p_dir, $p_is_dir = false) { $v_result = 1; - // ----- Remove the final '/' if (($p_is_dir) && (substr($p_dir, -1)=='/')) { $p_dir = substr($p_dir, 0, strlen($p_dir)-1); @@ -4849,7 +4831,7 @@ function privDuplicate($p_archive_filename) // Description : // Parameters : // -------------------------------------------------------------------------------- - function privErrorLog($p_error_code=0, $p_error_string='') + function privErrorLog($p_error_code = 0, $p_error_string = '') { if (PCLZIP_ERROR_EXTERNAL == 1) { PclError($p_error_code, $p_error_string); @@ -5030,10 +5012,10 @@ function PclZipUtilPathInclusion($p_dir, $p_path) // ----- Look for path beginning by ./ if (($p_dir == '.') || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { - $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); + $p_dir = PclZipUtilTranslateWinPath(getcwd(), false).'/'.substr($p_dir, 1); } if (($p_path == '.') || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { - $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); + $p_path = PclZipUtilTranslateWinPath(getcwd(), false).'/'.substr($p_path, 1); } // ----- Explode dir and path by directory separator @@ -5057,7 +5039,7 @@ function PclZipUtilPathInclusion($p_dir, $p_path) } // ----- Compare the items - if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ($v_list_path[$j] != '')) { $v_result = 0; } @@ -5097,7 +5079,7 @@ function PclZipUtilPathInclusion($p_dir, $p_path) // 3 : src & dest gzip // Return Values : // -------------------------------------------------------------------------------- -function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) +function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode = 0) { $v_result = 1; @@ -5204,7 +5186,7 @@ function PclZipUtilOptionText($p_option) // Return Values : // The path translated. // -------------------------------------------------------------------------------- -function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) +function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter = true) { if (stristr(php_uname(), 'windows')) { // ----- Look for potential disk letter diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 563e7f2c1..c32a3bb8a 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -526,21 +526,22 @@ public static function ConvertEncoding($value, $to, $from) * @author Rasmus Andersson {@link http://rasmusandersson.se/} * @author vadik56 */ - public static function utf16_decode($str, $bom_be = TRUE) { + public static function utf16_decode($str, $bom_be = true) + { if (strlen($str) < 2) { return $str; } $c0 = ord($str{0}); $c1 = ord($str{1}); if ($c0 == 0xfe && $c1 == 0xff) { - $str = substr($str,2); + $str = substr($str, 2); } elseif ($c0 == 0xff && $c1 == 0xfe) { - $str = substr($str,2); + $str = substr($str, 2); $bom_be = false; } $len = strlen($str); $newstr = ''; - for($i=0;$i<$len;$i+=2) { + for ($i=0; $i<$len; $i+=2) { if ($bom_be) { $val = ord($str{$i}) << 4; $val += ord($str{$i+1}); diff --git a/Classes/PHPExcel/Shared/XMLWriter.php b/Classes/PHPExcel/Shared/XMLWriter.php index 0319f330a..7b3b5a162 100644 --- a/Classes/PHPExcel/Shared/XMLWriter.php +++ b/Classes/PHPExcel/Shared/XMLWriter.php @@ -59,7 +59,8 @@ class PHPExcel_Shared_XMLWriter extends XMLWriter * @param int $pTemporaryStorage Temporary storage location * @param string $pTemporaryStorageFolder Temporary storage folder */ - public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = null) { + public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = null) + { // Open temporary storage if ($pTemporaryStorage == self::STORAGE_MEMORY) { $this->openMemory(); diff --git a/Classes/PHPExcel/Shared/trend/bestFitClass.php b/Classes/PHPExcel/Shared/trend/bestFitClass.php index b30ad7da2..1e547b2fb 100644 --- a/Classes/PHPExcel/Shared/trend/bestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/bestFitClass.php @@ -39,7 +39,7 @@ class PHPExcel_Best_Fit * * @var boolean **/ - protected $_error = False; + protected $_error = false; /** * Algorithm type to use for best-fit @@ -163,7 +163,7 @@ public function getXValues() */ public function getEquation($dp = 0) { - return False; + return false; } // function getEquation() /** @@ -200,7 +200,7 @@ public function getSlopeSE($dp = 0) * @param int $dp Number of places of decimal precision to display * @return string */ - public function getIntersect($dp=0) + public function getIntersect($dp = 0) { if ($dp != 0) { return round($this->_intersect, $dp); @@ -347,7 +347,7 @@ protected function _calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $this->_SSRegression = $this->_goodnessOfFit * $SStot; $this->_covariance = $SScov / $this->_valueCount; - $this->_correlation = ($this->_valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->_valueCount * $sumX2 - pow($sumX,2)) * ($this->_valueCount * $sumY2 - pow($sumY,2))); + $this->_correlation = ($this->_valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->_valueCount * $sumX2 - pow($sumX, 2)) * ($this->_valueCount * $sumY2 - pow($sumY, 2))); $this->_slopeSE = $this->_stdevOfResiduals / sqrt($SSsex); $this->_intersectSE = $this->_stdevOfResiduals * sqrt(1 / ($this->_valueCount - ($sumX * $sumX) / $sumX2)); if ($this->_SSResiduals != 0.0) { @@ -373,7 +373,7 @@ protected function _leastSquareFit($yValues, $xValues, $const) $meanX = $x_sum / $this->_valueCount; $meanY = $y_sum / $this->_valueCount; $mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0; - for($i = 0; $i < $this->_valueCount; ++$i) { + for ($i = 0; $i < $this->_valueCount; ++$i) { $xy_sum += $xValues[$i] * $yValues[$i]; $xx_sum += $xValues[$i] * $xValues[$i]; $yy_sum += $yValues[$i] * $yValues[$i]; @@ -409,7 +409,7 @@ protected function _leastSquareFit($yValues, $xValues, $const) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($yValues, $xValues = array(), $const = true) + public function __construct($yValues, $xValues = array(), $const = true) { // Calculate number of points $nY = count($yValues); diff --git a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php index 0aec82fd3..647bd2dc1 100644 --- a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php @@ -54,7 +54,7 @@ class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit **/ public function getValueOfYForX($xValue) { - return $this->getIntersect() * pow($this->getSlope(),($xValue - $this->_Xoffset)); + return $this->getIntersect() * pow($this->getSlope(), ($xValue - $this->_Xoffset)); } // function getValueOfYForX() /** @@ -144,4 +144,4 @@ function __construct($yValues, $xValues = array(), $const = true) $this->_exponential_regression($yValues, $xValues, $const); } } // function __construct() -} \ No newline at end of file +} diff --git a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php index e884073ee..1689dd60c 100644 --- a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php @@ -106,4 +106,4 @@ function __construct($yValues, $xValues = array(), $const = true) $this->_linear_regression($yValues, $xValues, $const); } } // function __construct() -} \ No newline at end of file +} diff --git a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php index 35ab8b292..fa1a3d268 100644 --- a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php @@ -114,4 +114,4 @@ function __construct($yValues, $xValues = array(), $const = true) $this->_logarithmic_regression($yValues, $xValues, $const); } } // function __construct() -} \ No newline at end of file +} diff --git a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php index 7e618ac34..b571f206f 100644 --- a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php @@ -161,7 +161,7 @@ private function _polynomial_regression($order, $yValues, $xValues, $const) $x_sum = array_sum($xValues); $y_sum = array_sum($yValues); $xx_sum = $xy_sum = 0; - for($i = 0; $i < $this->_valueCount; ++$i) { + for ($i = 0; $i < $this->_valueCount; ++$i) { $xy_sum += $xValues[$i] * $yValues[$i]; $xx_sum += $xValues[$i] * $xValues[$i]; $yy_sum += $yValues[$i] * $yValues[$i]; @@ -187,7 +187,7 @@ private function _polynomial_regression($order, $yValues, $xValues, $const) $C = $matrixA->solve($matrixB); $coefficients = array(); - for($i = 0; $i < $C->m; ++$i) { + for ($i = 0; $i < $C->m; ++$i) { $r = $C->get($i, 0); if (abs($r) <= pow(10, -9)) { $r = 0; @@ -221,11 +221,11 @@ function __construct($order, $yValues, $xValues = array(), $const = true) $this->_order = $order; $this->_polynomial_regression($order, $yValues, $xValues, $const); if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) { - $this->_error = True; + $this->_error = true; } } else { - $this->_error = True; + $this->_error = true; } } } // function __construct() -} \ No newline at end of file +} From 61e81377cbf61d9360d87c2b4c2f3c11eedbb798 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sat, 16 May 2015 23:18:40 +0100 Subject: [PATCH 378/467] Yet more of the psr-2 work --- Classes/PHPExcel/Calculation.php | 2871 ++-- Classes/PHPExcel/Chart/Legend.php | 10 +- Classes/PHPExcel/DocumentProperties.php | 6 +- Classes/PHPExcel/DocumentSecurity.php | 46 +- Classes/PHPExcel/HashTable.php | 2 +- Classes/PHPExcel/Helper/HTML.php | 81 +- .../Shared/OLE/ChainedBlockStream.php | 14 +- Classes/PHPExcel/Shared/OLE/PPS/File.php | 2 +- Classes/PHPExcel/Shared/OLE/PPS/Root.php | 14 +- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 11382 ++++++++-------- 10 files changed, 7225 insertions(+), 7203 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 6a21bcacb..032ccd32c 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -271,1444 +271,1447 @@ class PHPExcel_Calculation // PHPExcel functions private static $PHPExcelFunctions = array( // PHPExcel functions - 'ABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'abs', - 'argumentCount' => '1' - ), - 'ACCRINT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', - 'argumentCount' => '4-7' - ), - 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', - 'argumentCount' => '3-5' - ), - 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'acos', - 'argumentCount' => '1' - ), - 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'acosh', - 'argumentCount' => '1' - ), - 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', - 'argumentCount' => '2-5' - ), - 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', - 'argumentCount' => '6,7' - ), - 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', - 'argumentCount' => '6,7' - ), - 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', - 'argumentCount' => '1+' - ), - 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'asin', - 'argumentCount' => '1' - ), - 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'asinh', - 'argumentCount' => '1' - ), - 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'atan', - 'argumentCount' => '1' - ), - 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', - 'argumentCount' => '2' - ), - 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'atanh', - 'argumentCount' => '1' - ), - 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', - 'argumentCount' => '1+' - ), - 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', - 'argumentCount' => '1+' - ), - 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', - 'argumentCount' => '1+' - ), - 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', - 'argumentCount' => '2,3' - ), - 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3+' - ), - 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', - 'argumentCount' => '2' - ), - 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', - 'argumentCount' => '2' - ), - 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', - 'argumentCount' => '2' - ), - 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', - 'argumentCount' => '2' - ), - 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', - 'argumentCount' => '3-5' - ), - 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', - 'argumentCount' => '3-5' - ), - 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', - 'argumentCount' => '1' - ), - 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', - 'argumentCount' => '1,2' - ), - 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', - 'argumentCount' => '1,2' - ), - 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', - 'argumentCount' => '4' - ), - 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', - 'argumentCount' => '2' - ), - 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1,2' - ), - 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', - 'argumentCount' => '1' - ), - 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', - 'argumentCount' => '2' - ), - 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', - 'argumentCount' => '2' - ), - 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', - 'argumentCount' => '2+' - ), - 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', - 'argumentCount' => '1' - ), - 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', - 'argumentCount' => '1' - ), - 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', - 'argumentCount' => '-1', - 'passByReference' => array(true) - ), - 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', - 'argumentCount' => '1' - ), - 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', - 'argumentCount' => '2' - ), - 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', - 'argumentCount' => '2,3' - ), - 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', - 'argumentCount' => '1+' - ), - 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', - 'argumentCount' => '3' - ), - 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', - 'argumentCount' => '3' - ), - 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', - 'argumentCount' => '2' - ), - 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'cos', - 'argumentCount' => '1' - ), - 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'cosh', - 'argumentCount' => '1' - ), - 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', - 'argumentCount' => '1+' - ), - 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', - 'argumentCount' => '1+' - ), - 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', - 'argumentCount' => '1' - ), - 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', - 'argumentCount' => '2' - ), - 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', - 'argumentCount' => '3,4' - ), - 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', - 'argumentCount' => '3,4' - ), - 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', - 'argumentCount' => '3,4' - ), - 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', - 'argumentCount' => '3,4' - ), - 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', - 'argumentCount' => '3,4' - ), - 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', - 'argumentCount' => '3,4' - ), - 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', - 'argumentCount' => '2' - ), - 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', - 'argumentCount' => '3' - ), - 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', - 'argumentCount' => '6' - ), - 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', - 'argumentCount' => '6' - ), - 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', - 'argumentCount' => '3' - ), - 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', - 'argumentCount' => '2,3' - ), - 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', - 'argumentCount' => '1' - ), - 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', - 'argumentCount' => '3' - ), - 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', - 'argumentCount' => '1' - ), - 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', - 'argumentCount' => '2,3' - ), - 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DB', - 'argumentCount' => '4,5' - ), - 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', - 'argumentCount' => '3' - ), - 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', - 'argumentCount' => '3' - ), - 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', - 'argumentCount' => '4,5' - ), - 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', - 'argumentCount' => '1,2' - ), - 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', - 'argumentCount' => '1,2' - ), - 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', - 'argumentCount' => '1,2' - ), - 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'rad2deg', - 'argumentCount' => '1' - ), - 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', - 'argumentCount' => '1,2' - ), - 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', - 'argumentCount' => '1+' - ), - 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DGET', - 'argumentCount' => '3' - ), - 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', - 'argumentCount' => '4,5' - ), - 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', - 'argumentCount' => '3' - ), - 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', - 'argumentCount' => '3' - ), - 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', - 'argumentCount' => '1,2' - ), - 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', - 'argumentCount' => '2' - ), - 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', - 'argumentCount' => '2' - ), - 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', - 'argumentCount' => '3' - ), - 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', - 'argumentCount' => '3' - ), - 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', - 'argumentCount' => '3' - ), - 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', - 'argumentCount' => '3' - ), - 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5,6' - ), - 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', - 'argumentCount' => '3' - ), - 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', - 'argumentCount' => '3' - ), - 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', - 'argumentCount' => '2' - ), - 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', - 'argumentCount' => '2' - ), - 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', - 'argumentCount' => '2' - ), - 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', - 'argumentCount' => '1,2' - ), - 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', - 'argumentCount' => '1' - ), - 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', - 'argumentCount' => '1' - ), - 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', - 'argumentCount' => '1' - ), - 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'exp', - 'argumentCount' => '1' - ), - 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', - 'argumentCount' => '3' - ), - 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', - 'argumentCount' => '1' - ), - 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', - 'argumentCount' => '1' - ), - 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', - 'argumentCount' => '0' - ), - 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3' - ), - 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', - 'argumentCount' => '2,3' - ), - 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', - 'argumentCount' => '2,3' - ), - 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3' - ), - 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', - 'argumentCount' => '1' - ), - 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', - 'argumentCount' => '1' - ), - 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', - 'argumentCount' => '1-3' - ), - 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', - 'argumentCount' => '2' - ), - 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', - 'argumentCount' => '3' - ), - 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::FV', - 'argumentCount' => '3-5' - ), - 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', - 'argumentCount' => '2' - ), - 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', - 'argumentCount' => '4' - ), - 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', - 'argumentCount' => '3' - ), - 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', - 'argumentCount' => '1' - ), - 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', - 'argumentCount' => '1+' - ), - 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', - 'argumentCount' => '1+' - ), - 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', - 'argumentCount' => '1,2' - ), - 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2+' - ), - 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', - 'argumentCount' => '1-4' - ), - 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', - 'argumentCount' => '1+' - ), - 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', - 'argumentCount' => '1,2' - ), - 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', - 'argumentCount' => '1' - ), - 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', - 'argumentCount' => '1,2' - ), - 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', - 'argumentCount' => '3,4' - ), - 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', - 'argumentCount' => '1' - ), - 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', - 'argumentCount' => '1,2', - 'passCellReference'=> true - ), - 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', - 'argumentCount' => '4' - ), - 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', - 'argumentCount' => '1-3' - ), - 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', - 'argumentCount' => '2' - ), - 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', - 'argumentCount' => '1' - ), - 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', - 'argumentCount' => '1' - ), - 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', - 'argumentCount' => '1' - ), - 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', - 'argumentCount' => '1' - ), - 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', - 'argumentCount' => '1' - ), - 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', - 'argumentCount' => '2' - ), - 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', - 'argumentCount' => '1' - ), - 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', - 'argumentCount' => '1' - ), - 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', - 'argumentCount' => '1' - ), - 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', - 'argumentCount' => '1' - ), - 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', - 'argumentCount' => '2' - ), - 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', - 'argumentCount' => '1+' - ), - 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', - 'argumentCount' => '1' - ), - 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', - 'argumentCount' => '1' - ), - 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', - 'argumentCount' => '1' - ), - 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', - 'argumentCount' => '2' - ), - 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', - 'argumentCount' => '1+' - ), - 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', - 'argumentCount' => '1-4' - ), - 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', - 'argumentCount' => '1,2', - 'passCellReference'=> true - ), - 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', - 'argumentCount' => '1' - ), - 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', - 'argumentCount' => '2' - ), - 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', - 'argumentCount' => '4,5' - ), - 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', - 'argumentCount' => '4-6' - ), - 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', - 'argumentCount' => '1,2' - ), - 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', - 'argumentCount' => '1' - ), - 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', - 'argumentCount' => '1' - ), - 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', - 'argumentCount' => '1' - ), - 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', - 'argumentCount' => '1' - ), - 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', - 'argumentCount' => '1' - ), - 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', - 'argumentCount' => '1' - ), - 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', - 'argumentCount' => '1' - ), - 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', - 'argumentCount' => '1' - ), - 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', - 'argumentCount' => '1' - ), - 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', - 'argumentCount' => '4' - ), - 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', - 'argumentCount' => '1' - ), - 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', - 'argumentCount' => '1+' - ), - 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', - 'argumentCount' => '2' - ), - 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', - 'argumentCount' => '1+' - ), - 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', - 'argumentCount' => '1,2' - ), - 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', - 'argumentCount' => '1,2' - ), - 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', - 'argumentCount' => '1' - ), - 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', - 'argumentCount' => '1' - ), - 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', - 'argumentCount' => '1-4' - ), - 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'log', - 'argumentCount' => '1' - ), - 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', - 'argumentCount' => '1,2' - ), - 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'log10', - 'argumentCount' => '1' - ), - 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', - 'argumentCount' => '1-4' - ), - 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', - 'argumentCount' => '3' - ), - 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', - 'argumentCount' => '3' - ), - 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', - 'argumentCount' => '2,3' - ), - 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', - 'argumentCount' => '1' - ), - 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', - 'argumentCount' => '2,3' - ), - 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', - 'argumentCount' => '1+' - ), - 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', - 'argumentCount' => '1+' - ), - 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', - 'argumentCount' => '2+' - ), - 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', - 'argumentCount' => '1' - ), - 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5,6' - ), - 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', - 'argumentCount' => '1+' - ), - 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2+' - ), - 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::MID', - 'argumentCount' => '3' - ), - 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::MID', - 'argumentCount' => '3' - ), - 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', - 'argumentCount' => '1+' - ), - 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', - 'argumentCount' => '1+' - ), - 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', - 'argumentCount' => '2+' - ), - 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', - 'argumentCount' => '1' - ), - 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', - 'argumentCount' => '1' - ), - 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', - 'argumentCount' => '3' - ), - 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', - 'argumentCount' => '2' - ), - 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', - 'argumentCount' => '2' - ), - 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', - 'argumentCount' => '1+' - ), - 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', - 'argumentCount' => '1' - ), - 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', - 'argumentCount' => '2' - ), - 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', - 'argumentCount' => '1+' - ), - 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::N', - 'argumentCount' => '1' - ), - 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::NA', - 'argumentCount' => '0' - ), - 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', - 'argumentCount' => '3' - ), - 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', - 'argumentCount' => '2+' - ), - 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', - 'argumentCount' => '2' - ), - 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', - 'argumentCount' => '4' - ), - 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', - 'argumentCount' => '3' - ), - 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', - 'argumentCount' => '1' - ), - 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', - 'argumentCount' => '1' - ), - 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', - 'argumentCount' => '1' - ), - 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', - 'argumentCount' => '0' - ), - 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', - 'argumentCount' => '3-5' - ), - 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', - 'argumentCount' => '2+' - ), - 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', - 'argumentCount' => '1,2' - ), - 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', - 'argumentCount' => '1' - ), - 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', - 'argumentCount' => '1,2' - ), - 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', - 'argumentCount' => '1' - ), - 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '8,9' - ), - 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '8,9' - ), - 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '7,8' - ), - 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '7,8' - ), - 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', - 'argumentCount' => '3,5', - 'passCellReference'=> true, - 'passByReference' => array(true) - ), - 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', - 'argumentCount' => '1+' - ), - 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', - 'argumentCount' => '2' - ), - 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', - 'argumentCount' => '2' - ), - 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', - 'argumentCount' => '2,3' - ), - 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', - 'argumentCount' => '2' - ), - 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'pi', - 'argumentCount' => '0' - ), - 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', - 'argumentCount' => '3-5' - ), - 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', - 'argumentCount' => '3' - ), - 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', - 'argumentCount' => '2' - ), - 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', - 'argumentCount' => '4-6' - ), - 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', - 'argumentCount' => '6,7' - ), - 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', - 'argumentCount' => '4,5' - ), - 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', - 'argumentCount' => '5,6' - ), - 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3,4' - ), - 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', - 'argumentCount' => '1+' - ), - 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', - 'argumentCount' => '1' - ), - 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PV', - 'argumentCount' => '3-5' - ), - 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', - 'argumentCount' => '2' - ), - 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', - 'argumentCount' => '2' - ), - 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'deg2rad', - 'argumentCount' => '1' - ), - 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', - 'argumentCount' => '0' - ), - 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', - 'argumentCount' => '2' - ), - 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', - 'argumentCount' => '2,3' - ), - 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', - 'argumentCount' => '3-6' - ), - 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', - 'argumentCount' => '4-5' - ), - 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', - 'argumentCount' => '4' - ), - 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', - 'argumentCount' => '4' - ), - 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'str_repeat', - 'argumentCount' => '2' - ), - 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', - 'argumentCount' => '1,2' - ), - 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', - 'argumentCount' => '1,2' - ), - 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', - 'argumentCount' => '1,2' - ), - 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'round', - 'argumentCount' => '2' - ), - 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', - 'argumentCount' => '2' - ), - 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', - 'argumentCount' => '2' - ), - 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', - 'argumentCount' => '-1', - 'passByReference' => array(true) - ), - 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', - 'argumentCount' => '1' - ), - 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', - 'argumentCount' => '2' - ), - 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1+' - ), - 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', - 'argumentCount' => '2,3' - ), - 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', - 'argumentCount' => '2,3' - ), - 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', - 'argumentCount' => '1' - ), - 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', - 'argumentCount' => '4' - ), - 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', - 'argumentCount' => '1' - ), - 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sin', - 'argumentCount' => '1' - ), - 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sinh', - 'argumentCount' => '1' - ), - 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', - 'argumentCount' => '1+' - ), - 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', - 'argumentCount' => '3' - ), - 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', - 'argumentCount' => '2' - ), - 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', - 'argumentCount' => '2' - ), - 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sqrt', - 'argumentCount' => '1' - ), - 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', - 'argumentCount' => '1' - ), - 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', - 'argumentCount' => '3' - ), - 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', - 'argumentCount' => '1+' - ), - 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', - 'argumentCount' => '1+' - ), - 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', - 'argumentCount' => '1+' - ), - 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', - 'argumentCount' => '1+' - ), - 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', - 'argumentCount' => '2' - ), - 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', - 'argumentCount' => '3,4' - ), - 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', - 'argumentCount' => '2+' - ), - 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', - 'argumentCount' => '1+' - ), - 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', - 'argumentCount' => '2,3' - ), - 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', - 'argumentCount' => '1+' - ), - 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', - 'argumentCount' => '1+' - ), - 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', - 'argumentCount' => '2' - ), - 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', - 'argumentCount' => '2' - ), - 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', - 'argumentCount' => '2' - ), - 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', - 'argumentCount' => '4' - ), - 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', - 'argumentCount' => '1' - ), - 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'tan', - 'argumentCount' => '1' - ), - 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'tanh', - 'argumentCount' => '1' - ), - 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', - 'argumentCount' => '3' - ), - 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', - 'argumentCount' => '3' - ), - 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', - 'argumentCount' => '3' - ), - 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', - 'argumentCount' => '3' - ), - 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', - 'argumentCount' => '2' - ), - 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', - 'argumentCount' => '3' - ), - 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', - 'argumentCount' => '1' - ), - 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', - 'argumentCount' => '2' - ), - 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', - 'argumentCount' => '0' - ), - 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', - 'argumentCount' => '1' - ), - 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', - 'argumentCount' => '1-4' - ), - 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', - 'argumentCount' => '1' - ), - 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', - 'argumentCount' => '2' - ), - 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', - 'argumentCount' => '0' - ), - 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', - 'argumentCount' => '1,2' - ), - 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '4' - ), - 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', - 'argumentCount' => '1' - ), - 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', - 'argumentCount' => '1' - ), - 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', - 'argumentCount' => '1' - ), - 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', - 'argumentCount' => '1+' - ), - 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', - 'argumentCount' => '1+' - ), - 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', - 'argumentCount' => '1+' - ), - 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', - 'argumentCount' => '1+' - ), - 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5-7' - ), - 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', - 'argumentCount' => '0' - ), - 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', - 'argumentCount' => '3,4' - ), - 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', - 'argumentCount' => '1,2' - ), - 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', - 'argumentCount' => '1,2' - ), - 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', - 'argumentCount' => '4' - ), - 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', - 'argumentCount' => '2+' - ), - 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', - 'argumentCount' => '2,3' - ), - 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', - 'argumentCount' => '3' - ), - 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', - 'argumentCount' => '1' - ), - 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', - 'argumentCount' => '2,3' - ), - 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '6,7' - ), - 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', - 'argumentCount' => '4,5' - ), - 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', - 'argumentCount' => '5,6' - ), - 'ZTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', - 'argumentCount' => '2-3' - ) - ); + 'ABS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'abs', + argumentCount' => '1' + ), + 'ACCRINT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', + 'argumentCount' => '4-7' + ), + 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', + 'argumentCount' => '3-5' + ), + 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acos', + 'argumentCount' => '1' + ), + 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acosh', + 'argumentCount' => '1' + ), + 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', + 'argumentCount' => '2-5' + ), + 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', + 'argumentCount' => '6,7' + ), + 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', + 'argumentCount' => '6,7' + ), + 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', + 'argumentCount' => '1+' + ), + 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asin', + 'argumentCount' => '1' + ), + 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asinh', + 'argumentCount' => '1' + ), + 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atan', + 'argumentCount' => '1' + ), + 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', + 'argumentCount' => '2' + ), + 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atanh', + 'argumentCount' => '1' + ), + 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', + 'argumentCount' => '1+' + ), + 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', + 'argumentCount' => '1+' + ), + 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', + 'argumentCount' => '1+' + ), + 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', + 'argumentCount' => '2,3' + ), + 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3+' + ), + 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', + 'argumentCount' => '2' + ), + 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', + 'argumentCount' => '2' + ), + 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', + 'argumentCount' => '2' + ), + 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', + 'argumentCount' => '2' + ), + 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', + 'argumentCount' => '3-5' + ), + 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', + 'argumentCount' => '3-5' + ), + 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', + 'argumentCount' => '1' + ), + 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', + 'argumentCount' => '1,2' + ), + 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', + 'argumentCount' => '1,2' + ), + 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', + 'argumentCount' => '4' + ), + 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', + 'argumentCount' => '2' + ), + 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1,2' + ), + 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', + 'argumentCount' => '1' + ), + 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', + 'argumentCount' => '2' + ), + 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', + 'argumentCount' => '2' + ), + 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', + 'argumentCount' => '2+' + ), + 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', + 'argumentCount' => '1' + ), + 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', + 'argumentCount' => '1' + ), + 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', + 'argumentCount' => '-1', + 'passByReference' => array(true) + ), + 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', + 'argumentCount' => '1' + ), + 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', + 'argumentCount' => '2' + ), + 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', + 'argumentCount' => '2,3' + ), + 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', + 'argumentCount' => '1+' + ), + 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', + 'argumentCount' => '3' + ), + 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', + 'argumentCount' => '3' + ), + 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cos', + 'argumentCount' => '1' + ), + 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cosh', + 'argumentCount' => '1' + ), + 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', + 'argumentCount' => '1+' + ), + 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', + 'argumentCount' => '1+' + ), + 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', + 'argumentCount' => '1' + ), + 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', + 'argumentCount' => '2' + ), + 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', + 'argumentCount' => '3,4' + ), + 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', + 'argumentCount' => '3,4' + ), + 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', + 'argumentCount' => '3,4' + ), + 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', + 'argumentCount' => '3,4' + ), + 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', + 'argumentCount' => '3,4' + ), + 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', + 'argumentCount' => '3,4' + ), + 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', + 'argumentCount' => '2' + ), + 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', + 'argumentCount' => '3' + ), + 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', + 'argumentCount' => '6' + ), + 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', + 'argumentCount' => '6' + ), + 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', + 'argumentCount' => '3' + ), + 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', + 'argumentCount' => '2,3' + ), + 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', + 'argumentCount' => '1' + ), + 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', + 'argumentCount' => '3' + ), + 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', + 'argumentCount' => '1' + ), + 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', + 'argumentCount' => '2,3' + ), + 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DB', + 'argumentCount' => '4,5' + ), + 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', + 'argumentCount' => '3' + ), + 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', + 'argumentCount' => '3' + ), + 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', + 'argumentCount' => '4,5' + ), + 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', + 'argumentCount' => '1,2' + ), + 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', + 'argumentCount' => '1,2' + ), + 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', + 'argumentCount' => '1,2' + ), + 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'rad2deg', + 'argumentCount' => '1' + ), + 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', + 'argumentCount' => '1,2' + ), + 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', + 'argumentCount' => '1+' + ), + 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DGET', + 'argumentCount' => '3' + ), + 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', + 'argumentCount' => '4,5' + ), + 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', + 'argumentCount' => '3' + ), + 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', + 'argumentCount' => '3' + ), + 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', + 'argumentCount' => '1,2' + ), + 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', + 'argumentCount' => '2' + ), + 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', + 'argumentCount' => '2' + ), + 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', + 'argumentCount' => '3' + ), + 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', + 'argumentCount' => '3' + ), + 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', + 'argumentCount' => '3' + ), + 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', + 'argumentCount' => '3' + ), + 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', + 'argumentCount' => '3' + ), + 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', + 'argumentCount' => '3' + ), + 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', + 'argumentCount' => '2' + ), + 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', + 'argumentCount' => '2' + ), + 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', + 'argumentCount' => '2' + ), + 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', + 'argumentCount' => '1,2' + ), + 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', + 'argumentCount' => '1' + ), + 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', + 'argumentCount' => '1' + ), + 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', + 'argumentCount' => '1' + ), + 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'exp', + 'argumentCount' => '1' + ), + 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', + 'argumentCount' => '3' + ), + 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', + 'argumentCount' => '1' + ), + 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', + 'argumentCount' => '1' + ), + 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', + 'argumentCount' => '0' + ), + 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', + 'argumentCount' => '1' + ), + 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', + 'argumentCount' => '1' + ), + 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', + 'argumentCount' => '1-3' + ), + 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', + 'argumentCount' => '2' + ), + 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', + 'argumentCount' => '3' + ), + 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FV', + 'argumentCount' => '3-5' + ), + 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', + 'argumentCount' => '2' + ), + 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', + 'argumentCount' => '4' + ), + 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', + 'argumentCount' => '3' + ), + 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', + 'argumentCount' => '1' + ), + 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', + 'argumentCount' => '1+' + ), + 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', + 'argumentCount' => '1+' + ), + 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', + 'argumentCount' => '1,2' + ), + 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', + 'argumentCount' => '1-4' + ), + 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', + 'argumentCount' => '1+' + ), + 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', + 'argumentCount' => '1,2' + ), + 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', + 'argumentCount' => '1' + ), + 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', + 'argumentCount' => '1,2' + ), + 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', + 'argumentCount' => '3,4' + ), + 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', + 'argumentCount' => '1' + ), + 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', + 'argumentCount' => '1,2', + 'passCellReference'=> true + ), + 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', + 'argumentCount' => '4' + ), + 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', + 'argumentCount' => '1-3' + ), + 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', + 'argumentCount' => '2' + ), + 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', + 'argumentCount' => '1' + ), + 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', + 'argumentCount' => '1' + ), + 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', + 'argumentCount' => '1' + ), + 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', + 'argumentCount' => '1' + ), + 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', + 'argumentCount' => '1' + ), + 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', + 'argumentCount' => '2' + ), + 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', + 'argumentCount' => '1' + ), + 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', + 'argumentCount' => '1' + ), + 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', + 'argumentCount' => '1' + ), + 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', + 'argumentCount' => '1' + ), + 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', + 'argumentCount' => '2' + ), + 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', + 'argumentCount' => '1+' + ), + 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', + 'argumentCount' => '1' + ), + 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', + 'argumentCount' => '1' + ), + 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', + 'argumentCount' => '1' + ), + 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', + 'argumentCount' => '2' + ), + 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', + 'argumentCount' => '1+' + ), + 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', + 'argumentCount' => '1-4' + ), + 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', + 'argumentCount' => '1,2', + 'passCellReference'=> true + ), + 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', + 'argumentCount' => '1' + ), + 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', + 'argumentCount' => '2' + ), + 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', + 'argumentCount' => '4,5' + ), + 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', + 'argumentCount' => '4-6' + ), + 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', + 'argumentCount' => '1,2' + ), + 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', + 'argumentCount' => '1' + ), + 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', + 'argumentCount' => '1' + ), + 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', + 'argumentCount' => '1' + ), + 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', + 'argumentCount' => '1' + ), + 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', + 'argumentCount' => '1' + ), + 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', + 'argumentCount' => '1' + ), + 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', + 'argumentCount' => '1' + ), + 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', + 'argumentCount' => '1' + ), + 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', + 'argumentCount' => '1' + ), + 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', + 'argumentCount' => '4' + ), + 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', + 'argumentCount' => '1' + ), + 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', + 'argumentCount' => '1+' + ), + 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', + 'argumentCount' => '2' + ), + 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', + 'argumentCount' => '1+' + ), + 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', + 'argumentCount' => '1-4' + ), + 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log', + 'argumentCount' => '1' + ), + 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', + 'argumentCount' => '1,2' + ), + 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log10', + 'argumentCount' => '1' + ), + 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', + 'argumentCount' => '1-4' + ), + 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', + 'argumentCount' => '3' + ), + 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', + 'argumentCount' => '3' + ), + 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', + 'argumentCount' => '2,3' + ), + 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', + 'argumentCount' => '1' + ), + 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', + 'argumentCount' => '2,3' + ), + 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', + 'argumentCount' => '1+' + ), + 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', + 'argumentCount' => '1+' + ), + 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', + 'argumentCount' => '2+' + ), + 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', + 'argumentCount' => '1' + ), + 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', + 'argumentCount' => '1+' + ), + 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', + 'argumentCount' => '1+' + ), + 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', + 'argumentCount' => '1+' + ), + 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', + 'argumentCount' => '2+' + ), + 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', + 'argumentCount' => '1' + ), + 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', + 'argumentCount' => '1' + ), + 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', + 'argumentCount' => '3' + ), + 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', + 'argumentCount' => '2' + ), + 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', + 'argumentCount' => '2' + ), + 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', + 'argumentCount' => '1+' + ), + 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', + 'argumentCount' => '1' + ), + 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', + 'argumentCount' => '2' + ), + 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', + 'argumentCount' => '1+' + ), + 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::N', + 'argumentCount' => '1' + ), + 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::NA', + 'argumentCount' => '0' + ), + 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', + 'argumentCount' => '3' + ), + 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', + 'argumentCount' => '2+' + ), + 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', + 'argumentCount' => '2' + ), + 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', + 'argumentCount' => '4' + ), + 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', + 'argumentCount' => '3' + ), + 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', + 'argumentCount' => '1' + ), + 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', + 'argumentCount' => '1' + ), + 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', + 'argumentCount' => '1' + ), + 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', + 'argumentCount' => '0' + ), + 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', + 'argumentCount' => '3-5' + ), + 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', + 'argumentCount' => '2+' + ), + 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', + 'argumentCount' => '1,2' + ), + 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', + 'argumentCount' => '1' + ), + 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', + 'argumentCount' => '1,2' + ), + 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', + 'argumentCount' => '1' + ), + 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', + 'argumentCount' => '3,5', + 'passCellReference'=> true, + 'passByReference' => array(true) + ), + 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', + 'argumentCount' => '1+' + ), + 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', + 'argumentCount' => '2' + ), + 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', + 'argumentCount' => '2,3' + ), + 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', + 'argumentCount' => '2' + ), + 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'pi', + 'argumentCount' => '0' + ), + 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', + 'argumentCount' => '3-5' + ), + 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', + 'argumentCount' => '3' + ), + 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', + 'argumentCount' => '2' + ), + 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', + 'argumentCount' => '4-6' + ), + 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', + 'argumentCount' => '6,7' + ), + 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', + 'argumentCount' => '4,5' + ), + 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', + 'argumentCount' => '5,6' + ), + 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3,4' + ), + 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', + 'argumentCount' => '1+' + ), + 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', + 'argumentCount' => '1' + ), + 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PV', + 'argumentCount' => '3-5' + ), + 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', + 'argumentCount' => '2' + ), + 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', + 'argumentCount' => '2' + ), + 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'deg2rad', + 'argumentCount' => '1' + ), + 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '0' + ), + 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '2' + ), + 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', + 'argumentCount' => '2,3' + ), + 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', + 'argumentCount' => '3-6' + ), + 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', + 'argumentCount' => '4-5' + ), + 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'str_repeat', + 'argumentCount' => '2' + ), + 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', + 'argumentCount' => '1,2' + ), + 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'round', + 'argumentCount' => '2' + ), + 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', + 'argumentCount' => '2' + ), + 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', + 'argumentCount' => '2' + ), + 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', + 'argumentCount' => '-1', + 'passByReference' => array(true) + ), + 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', + 'argumentCount' => '1' + ), + 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', + 'argumentCount' => '2' + ), + 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1+' + ), + 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', + 'argumentCount' => '1' + ), + 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', + 'argumentCount' => '4' + ), + 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', + 'argumentCount' => '1' + ), + 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sin', + 'argumentCount' => '1' + ), + 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sinh', + 'argumentCount' => '1' + ), + 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', + 'argumentCount' => '1+' + ), + 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', + 'argumentCount' => '3' + ), + 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', + 'argumentCount' => '2' + ), + 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', + 'argumentCount' => '2' + ), + 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sqrt', + 'argumentCount' => '1' + ), + 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', + 'argumentCount' => '1' + ), + 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', + 'argumentCount' => '3' + ), + 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', + 'argumentCount' => '1+' + ), + 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', + 'argumentCount' => '1+' + ), + 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', + 'argumentCount' => '1+' + ), + 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', + 'argumentCount' => '1+' + ), + 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', + 'argumentCount' => '2' + ), + 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', + 'argumentCount' => '3,4' + ), + 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', + 'argumentCount' => '2+' + ), + 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', + 'argumentCount' => '1+' + ), + 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', + 'argumentCount' => '2,3' + ), + 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', + 'argumentCount' => '1+' + ), + 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', + 'argumentCount' => '1+' + ), + 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', + 'argumentCount' => '2' + ), + 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', + 'argumentCount' => '2' + ), + 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', + 'argumentCount' => '2' + ), + 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', + 'argumentCount' => '4' + ), + 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', + 'argumentCount' => '1' + ), + 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tan', + 'argumentCount' => '1' + ), + 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tanh', + 'argumentCount' => '1' + ), + 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', + 'argumentCount' => '3' + ), + 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', + 'argumentCount' => '3' + ), + 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', + 'argumentCount' => '3' + ), + 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', + 'argumentCount' => '3' + ), + 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', + 'argumentCount' => '2' + ), + 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', + 'argumentCount' => '3' + ), + 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', + 'argumentCount' => '1' + ), + 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', + 'argumentCount' => '2' + ), + 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', + 'argumentCount' => '0' + ), + 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', + 'argumentCount' => '1' + ), + 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', + 'argumentCount' => '1-4' + ), + 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', + 'argumentCount' => '1' + ), + 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', + 'argumentCount' => '2' + ), + 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', + 'argumentCount' => '0' + ), + 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', + 'argumentCount' => '1,2' + ), + 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '4' + ), + 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', + 'argumentCount' => '1' + ), + 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', + 'argumentCount' => '1' + ), + 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', + 'argumentCount' => '1' + ), + 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', + 'argumentCount' => '1+' + ), + 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', + 'argumentCount' => '1+' + ), + 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', + 'argumentCount' => '1+' + ), + 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', + 'argumentCount' => '1+' + ), + 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5-7' + ), + 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', + 'argumentCount' => '0' + ), + 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', + 'argumentCount' => '3,4' + ), + 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', + 'argumentCount' => '1,2' + ), + 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', + 'argumentCount' => '1,2' + ), + 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', + 'argumentCount' => '4' + ), + 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', + 'argumentCount' => '2+' + ), + 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', + 'argumentCount' => '2,3' + ), + 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', + 'argumentCount' => '3' + ), + 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', + 'argumentCount' => '1' + ), + 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', + 'argumentCount' => '2,3' + ), + 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '6,7' + ), + 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', + 'argumentCount' => '4,5' + ), + 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', + 'argumentCount' => '5,6' + ), + 'ZTEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', + 'argumentCount' => '2-3' + ) + ); // Internal functions used for special control purposes private static $controlFunctions = array( 'MKMATRIX' => array( 'argumentCount' => '*', - 'functionCall' => 'self::_mkMatrix' + 'functionCall' => 'self::_mkMatrix' ) ); @@ -1739,7 +1742,7 @@ public function __destruct() } } - private static function _loadLocales() + private static function loadLocales() { $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/'; foreach (glob($localeFileDirectory.'/*', GLOB_ONLYDIR) as $filename) { @@ -1981,7 +1984,7 @@ public function setLocale($locale = 'en_us') } if (count(self::$validLocaleLanguages) == 1) { - self::_loadLocales(); + self::loadLocales(); } // Test whether we have any language data for this language (any locale) if (in_array($language, self::$validLocaleLanguages)) { diff --git a/Classes/PHPExcel/Chart/Legend.php b/Classes/PHPExcel/Chart/Legend.php index 60f47c803..e850eb594 100644 --- a/Classes/PHPExcel/Chart/Legend.php +++ b/Classes/PHPExcel/Chart/Legend.php @@ -41,7 +41,7 @@ class PHPExcel_Chart_Legend const POSITION_TOP = 't'; const POSITION_TOPRIGHT = 'tr'; - private static $_positionXLref = array( + private static $positionXLref = array( self::xlLegendPositionBottom => self::POSITION_BOTTOM, self::xlLegendPositionCorner => self::POSITION_TOPRIGHT, self::xlLegendPositionCustom => '??', @@ -99,7 +99,7 @@ public function getPosition() */ public function setPosition($position = self::POSITION_RIGHT) { - if (!in_array($position, self::$_positionXLref)) { + if (!in_array($position, self::$positionXLref)) { return false; } @@ -114,7 +114,7 @@ public function setPosition($position = self::POSITION_RIGHT) */ public function getPositionXL() { - return array_search($this->position, self::$_positionXLref); + return array_search($this->position, self::$positionXLref); } /** @@ -124,11 +124,11 @@ public function getPositionXL() */ public function setPositionXL($positionXL = self::xlLegendPositionRight) { - if (!array_key_exists($positionXL, self::$_positionXLref)) { + if (!array_key_exists($positionXL, self::$positionXLref)) { return false; } - $this->position = self::$_positionXLref[$positionXL]; + $this->position = self::$positionXLref[$positionXL]; return true; } diff --git a/Classes/PHPExcel/DocumentProperties.php b/Classes/PHPExcel/DocumentProperties.php index 535c0c6dd..f52059f5f 100644 --- a/Classes/PHPExcel/DocumentProperties.php +++ b/Classes/PHPExcel/DocumentProperties.php @@ -535,7 +535,7 @@ public static function convertProperty($propertyValue, $propertyType) return strtotime($propertyValue); break; case 'bool': // Boolean - return ($propertyValue == 'true') ? True : False; + return ($propertyValue == 'true') ? true : false; break; case 'cy': // Currency case 'error': // Error Status Code @@ -556,7 +556,8 @@ public static function convertProperty($propertyValue, $propertyType) return $propertyValue; } - public static function convertPropertyType($propertyType) { + public static function convertPropertyType($propertyType) + { switch ($propertyType) { case 'i1': // 1-Byte Signed Integer case 'i2': // 2-Byte Signed Integer @@ -607,5 +608,4 @@ public static function convertPropertyType($propertyType) { } return self::PROPERTY_TYPE_UNKNOWN; } - } diff --git a/Classes/PHPExcel/DocumentSecurity.php b/Classes/PHPExcel/DocumentSecurity.php index 0887a2c38..ecea0da1f 100644 --- a/Classes/PHPExcel/DocumentSecurity.php +++ b/Classes/PHPExcel/DocumentSecurity.php @@ -32,35 +32,35 @@ class PHPExcel_DocumentSecurity * * @var boolean */ - private $_lockRevision; + private $lockRevision; /** * LockStructure * * @var boolean */ - private $_lockStructure; + private $lockStructure; /** * LockWindows * * @var boolean */ - private $_lockWindows; + private $lockWindows; /** * RevisionsPassword * * @var string */ - private $_revisionsPassword; + private $revisionsPassword; /** * WorkbookPassword * * @var string */ - private $_workbookPassword; + private $workbookPassword; /** * Create a new PHPExcel_DocumentSecurity @@ -68,11 +68,11 @@ class PHPExcel_DocumentSecurity public function __construct() { // Initialise values - $this->_lockRevision = false; - $this->_lockStructure = false; - $this->_lockWindows = false; - $this->_revisionsPassword = ''; - $this->_workbookPassword = ''; + $this->lockRevision = false; + $this->lockStructure = false; + $this->lockWindows = false; + $this->revisionsPassword = ''; + $this->workbookPassword = ''; } /** @@ -82,9 +82,9 @@ public function __construct() */ public function isSecurityEnabled() { - return $this->_lockRevision || - $this->_lockStructure || - $this->_lockWindows; + return $this->lockRevision || + $this->lockStructure || + $this->lockWindows; } /** @@ -94,7 +94,7 @@ public function isSecurityEnabled() */ public function getLockRevision() { - return $this->_lockRevision; + return $this->lockRevision; } /** @@ -105,7 +105,7 @@ public function getLockRevision() */ public function setLockRevision($pValue = false) { - $this->_lockRevision = $pValue; + $this->lockRevision = $pValue; return $this; } @@ -116,7 +116,7 @@ public function setLockRevision($pValue = false) */ public function getLockStructure() { - return $this->_lockStructure; + return $this->lockStructure; } /** @@ -127,7 +127,7 @@ public function getLockStructure() */ public function setLockStructure($pValue = false) { - $this->_lockStructure = $pValue; + $this->lockStructure = $pValue; return $this; } @@ -138,7 +138,7 @@ public function setLockStructure($pValue = false) */ public function getLockWindows() { - return $this->_lockWindows; + return $this->lockWindows; } /** @@ -149,7 +149,7 @@ public function getLockWindows() */ public function setLockWindows($pValue = false) { - $this->_lockWindows = $pValue; + $this->lockWindows = $pValue; return $this; } @@ -160,7 +160,7 @@ public function setLockWindows($pValue = false) */ public function getRevisionsPassword() { - return $this->_revisionsPassword; + return $this->revisionsPassword; } /** @@ -175,7 +175,7 @@ public function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) if (!$pAlreadyHashed) { $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); } - $this->_revisionsPassword = $pValue; + $this->revisionsPassword = $pValue; return $this; } @@ -186,7 +186,7 @@ public function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) */ public function getWorkbookPassword() { - return $this->_workbookPassword; + return $this->workbookPassword; } /** @@ -201,7 +201,7 @@ public function setWorkbookPassword($pValue = '', $pAlreadyHashed = false) if (!$pAlreadyHashed) { $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); } - $this->_workbookPassword = $pValue; + $this->workbookPassword = $pValue; return $this; } diff --git a/Classes/PHPExcel/HashTable.php b/Classes/PHPExcel/HashTable.php index 6fca1431f..f752a3637 100644 --- a/Classes/PHPExcel/HashTable.php +++ b/Classes/PHPExcel/HashTable.php @@ -66,7 +66,7 @@ public function addFromSource($pSource = null) // Check if an array was passed if ($pSource == null) { return; - } else if (!is_array($pSource)) { + } elseif (!is_array($pSource)) { throw new PHPExcel_Exception('Invalid array parameter passed.'); } diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index 86cbe31f4..28bf6b107 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -3,7 +3,7 @@ class PHPExcel_Helper_HTML { protected static $colourMap = array( - 'aliceblue' => 'f0f8ff', + 'aliceblue' => 'f0f8ff', 'antiquewhite' => 'faebd7', 'antiquewhite1' => 'ffefdb', 'antiquewhite2' => 'eedfcc', @@ -573,7 +573,8 @@ class PHPExcel_Helper_HTML protected $richTextObject; - protected function initialise() { + protected function initialise() + { $this->face = $this->size = $this->color = null; $this->bold = $this->italic = $this->underline = $this->superscript = $this->subscript = $this->strikethrough = false; @@ -582,7 +583,8 @@ protected function initialise() { $this->stringData = ''; } - public function toRichTextObject($html) { + public function toRichTextObject($html) + { $this->initialise(); // Create a new DOM object @@ -594,15 +596,17 @@ public function toRichTextObject($html) { // Discard excess white space $dom->preserveWhiteSpace = false; - $this->richTextObject = new PHPExcel_RichText();; + $this->richTextObject = new PHPExcel_RichText(); $this->parseElements($dom); return $this->richTextObject; } - protected function buildTextRun() { + protected function buildTextRun() + { $text = $this->stringData; - if (trim($text) === '') + if (trim($text) === '') { return; + } $richtextRun = $this->richTextObject->createTextRun($this->stringData); if ($this->face) { @@ -612,7 +616,7 @@ protected function buildTextRun() { $richtextRun->getFont()->setSize($this->size); } if ($this->color) { - $richtextRun->getFont()->setColor( new PHPExcel_Style_Color( 'ff' . $this->color ) ); + $richtextRun->getFont()->setColor(new PHPExcel_Style_Color('ff' . $this->color)); } if ($this->bold) { $richtextRun->getFont()->setBold(true); @@ -635,7 +639,8 @@ protected function buildTextRun() { $this->stringData = ''; } - protected function rgbToColour($rgb) { + protected function rgbToColour($rgb) + { preg_match_all('/\d+/', $rgb, $values); foreach ($values[0] as &$value) { $value = str_pad(dechex($value), 2, '0', STR_PAD_LEFT); @@ -643,11 +648,13 @@ protected function rgbToColour($rgb) { return implode($values[0]); } - protected function colourNameLookup($rgb) { + protected function colourNameLookup($rgb) + { return self::$colourMap[$rgb]; } - protected function startFontTag($tag) { + protected function startFontTag($tag) + { foreach ($tag->attributes as $attribute) { $attributeName = strtolower($attribute->name); $attributeValue = $attribute->value; @@ -666,69 +673,85 @@ protected function startFontTag($tag) { } } - protected function endFontTag() { + protected function endFontTag() + { $this->face = $this->size = $this->color = null; } - protected function startBoldTag() { + protected function startBoldTag() + { $this->bold = true; } - protected function endBoldTag() { + protected function endBoldTag() + { $this->bold = false; } - protected function startItalicTag() { + protected function startItalicTag() + { $this->italic = true; } - protected function endItalicTag() { + protected function endItalicTag() + { $this->italic = false; } - protected function startUnderlineTag() { + protected function startUnderlineTag() + { $this->underline = true; } - protected function endUnderlineTag() { + protected function endUnderlineTag() + { $this->underline = false; } - protected function startSubscriptTag() { + protected function startSubscriptTag() + { $this->subscript = true; } - protected function endSubscriptTag() { + protected function endSubscriptTag() + { $this->subscript = false; } - protected function startSuperscriptTag() { + protected function startSuperscriptTag() + { $this->superscript = true; } - protected function endSuperscriptTag() { + protected function endSuperscriptTag() + { $this->superscript = false; } - protected function startStrikethruTag() { + protected function startStrikethruTag() + { $this->strikethrough = true; } - protected function endStrikethruTag() { + protected function endStrikethruTag() + { $this->strikethrough = false; } - protected function breakTag() { + protected function breakTag() + { $this->stringData .= PHP_EOL; } - protected function parseTextNode(DOMText $textNode) { + protected function parseTextNode(DOMText $textNode) + { $domText = preg_replace('/\s+/u', ' ', ltrim($textNode->nodeValue)); $this->stringData .= $domText; $this->buildTextRun(); } - protected function handleCallback($element, $callbackTag, $callbacks) { + protected function handleCallback($element, $callbackTag, $callbacks) + { if (isset($callbacks[$callbackTag])) { $elementHandler = $callbacks[$callbackTag]; if (method_exists($this, $elementHandler)) { @@ -737,7 +760,8 @@ protected function handleCallback($element, $callbackTag, $callbacks) { } } - protected function parseElementNode(DOMElement $element) { + protected function parseElementNode(DOMElement $element) + { $callbackTag = strtolower($element->nodeName); $this->stack[] = $callbackTag; @@ -750,7 +774,8 @@ protected function parseElementNode(DOMElement $element) { $this->handleCallback($element, $callbackTag, $this->endTagCallbacks); } - protected function parseElements(DOMNode $element) { + protected function parseElements(DOMNode $element) + { foreach ($element->childNodes as $child) { if ($child instanceof DOMText) { $this->parseTextNode($child); diff --git a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php index 10f3f4b41..4d4fa4c25 100644 --- a/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php +++ b/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_OLE_ChainedBlockStream * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,17 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Shared_OLE_ChainedBlockStream - * - * Stream wrapper for reading data stored in an OLE file. Implements methods - * for PHP's stream_wrapper_register(). For creating streams using this - * wrapper, use PHPExcel_Shared_OLE_PPS_File::getStream(). - * - * @category PHPExcel - * @package PHPExcel_Shared_OLE - */ class PHPExcel_Shared_OLE_ChainedBlockStream { /** diff --git a/Classes/PHPExcel/Shared/OLE/PPS/File.php b/Classes/PHPExcel/Shared/OLE/PPS/File.php index f0be587a3..8b562b8c2 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/File.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/File.php @@ -28,7 +28,7 @@ * @package PHPExcel_Shared_OLE */ class PHPExcel_Shared_OLE_PPS_File extends PHPExcel_Shared_OLE_PPS - { +{ /** * The constructor * diff --git a/Classes/PHPExcel/Shared/OLE/PPS/Root.php b/Classes/PHPExcel/Shared/OLE/PPS/Root.php index 7e50dadf2..a2385f39e 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/Root.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/Root.php @@ -28,7 +28,7 @@ * @package PHPExcel_Shared_OLE */ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS - { +{ /** * Directory for temporary files @@ -71,10 +71,14 @@ public function __construct($time_1st, $time_2nd, $raChild) public function save($filename) { // Initial Setting for saving - $this->_BIG_BLOCK_SIZE = pow(2, - ((isset($this->_BIG_BLOCK_SIZE))? self::_adjust2($this->_BIG_BLOCK_SIZE) : 9)); - $this->_SMALL_BLOCK_SIZE= pow(2, - ((isset($this->_SMALL_BLOCK_SIZE))? self::_adjust2($this->_SMALL_BLOCK_SIZE): 6)); + $this->_BIG_BLOCK_SIZE = pow( + 2, + (isset($this->_BIG_BLOCK_SIZE))? self::_adjust2($this->_BIG_BLOCK_SIZE) : 9 + ); + $this->_SMALL_BLOCK_SIZE= pow( + 2, + (isset($this->_SMALL_BLOCK_SIZE))? self::_adjust2($this->_SMALL_BLOCK_SIZE) : 6 + ); if (is_resource($filename)) { $this->_FILEH_ = $filename; diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index 0805a03c7..fd7268d48 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -1,5692 +1,5692 @@ -<?php -// -------------------------------------------------------------------------------- -// PhpConcept Library - Zip Module 2.8.2 -// -------------------------------------------------------------------------------- -// License GNU/LGPL - Vincent Blavet - August 2009 -// http://www.phpconcept.net -// -------------------------------------------------------------------------------- -// -// Presentation : -// PclZip is a PHP library that manage ZIP archives. -// So far tests show that archives generated by PclZip are readable by -// WinZip application and other tools. -// -// Description : -// See readme.txt and http://www.phpconcept.net -// -// Warning : -// This library and the associated files are non commercial, non professional -// work. -// It should not have unexpected results. However if any damage is caused by -// this software the author can not be responsible. -// The use of this software is at the risk of the user. -// -// -------------------------------------------------------------------------------- -// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $ -// -------------------------------------------------------------------------------- - - // ----- Constants - if (!defined('PCLZIP_READ_BLOCK_SIZE')) { - define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); - } - - // ----- File list separator - // In version 1.x of PclZip, the separator for file list is a space - // (which is not a very smart choice, specifically for windows paths !). - // A better separator should be a comma (,). This constant gives you the - // abilty to change that. - // However notice that changing this value, may have impact on existing - // scripts, using space separated filenames. - // Recommanded values for compatibility with older versions : - //define( 'PCLZIP_SEPARATOR', ' ' ); - // Recommanded values for smart separation of filenames. - if (!defined('PCLZIP_SEPARATOR')) { - define( 'PCLZIP_SEPARATOR', ',' ); - } - - // ----- Error configuration - // 0 : PclZip Class integrated error handling - // 1 : PclError external library error handling. By enabling this - // you must ensure that you have included PclError library. - // [2,...] : reserved for futur use - if (!defined('PCLZIP_ERROR_EXTERNAL')) { - define( 'PCLZIP_ERROR_EXTERNAL', 0 ); - } - - // ----- Optional static temporary directory - // By default temporary files are generated in the script current - // path. - // If defined : - // - MUST BE terminated by a '/'. - // - MUST be a valid, already created directory - // Samples : - // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); - // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); - if (!defined('PCLZIP_TEMPORARY_DIR')) { - define( 'PCLZIP_TEMPORARY_DIR', '' ); - } - - // ----- Optional threshold ratio for use of temporary files - // Pclzip sense the size of the file to add/extract and decide to - // use or not temporary file. The algorythm is looking for - // memory_limit of PHP and apply a ratio. - // threshold = memory_limit * ratio. - // Recommended values are under 0.5. Default 0.47. - // Samples : - // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 ); - if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { - define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 ); - } - -// -------------------------------------------------------------------------------- -// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** -// -------------------------------------------------------------------------------- - - // ----- Global variables - $g_pclzip_version = "2.8.2"; - - // ----- Error codes - // -1 : Unable to open file in binary write mode - // -2 : Unable to open file in binary read mode - // -3 : Invalid parameters - // -4 : File does not exist - // -5 : Filename is too long (max. 255) - // -6 : Not a valid zip file - // -7 : Invalid extracted file size - // -8 : Unable to create directory - // -9 : Invalid archive extension - // -10 : Invalid archive format - // -11 : Unable to delete file (unlink) - // -12 : Unable to rename file (rename) - // -13 : Invalid header checksum - // -14 : Invalid archive size - define( 'PCLZIP_ERR_USER_ABORTED', 2 ); - define( 'PCLZIP_ERR_NO_ERROR', 0 ); - define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); - define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); - define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); - define( 'PCLZIP_ERR_MISSING_FILE', -4 ); - define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); - define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); - define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); - define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); - define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); - define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); - define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); - define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); - define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); - define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); - define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); - define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); - define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); - define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); - define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); - define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); - define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); - - // ----- Options values - define( 'PCLZIP_OPT_PATH', 77001 ); - define( 'PCLZIP_OPT_ADD_PATH', 77002 ); - define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); - define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); - define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); - define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); - define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); - define( 'PCLZIP_OPT_BY_NAME', 77008 ); - define( 'PCLZIP_OPT_BY_INDEX', 77009 ); - define( 'PCLZIP_OPT_BY_EREG', 77010 ); - define( 'PCLZIP_OPT_BY_PREG', 77011 ); - define( 'PCLZIP_OPT_COMMENT', 77012 ); - define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); - define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); - define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); - define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); - define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); - // Having big trouble with crypt. Need to multiply 2 long int - // which is not correctly supported by PHP ... - //define( 'PCLZIP_OPT_CRYPT', 77018 ); - define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); - define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 ); - define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias - define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 ); - define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias - define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 ); - define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias - - // ----- File description attributes - define( 'PCLZIP_ATT_FILE_NAME', 79001 ); - define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); - define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); - define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); - define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); - define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); - - // ----- Call backs values - define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); - define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); - define( 'PCLZIP_CB_PRE_ADD', 78003 ); - define( 'PCLZIP_CB_POST_ADD', 78004 ); - /* For futur use - define( 'PCLZIP_CB_PRE_LIST', 78005 ); - define( 'PCLZIP_CB_POST_LIST', 78006 ); - define( 'PCLZIP_CB_PRE_DELETE', 78007 ); - define( 'PCLZIP_CB_POST_DELETE', 78008 ); - */ - - // -------------------------------------------------------------------------------- - // Class : PclZip - // Description : - // PclZip is the class that represent a Zip archive. - // The public methods allow the manipulation of the archive. - // Attributes : - // Attributes must not be accessed directly. - // Methods : - // PclZip() : Object creator - // create() : Creates the Zip archive - // listContent() : List the content of the Zip archive - // extract() : Extract the content of the archive - // properties() : List the properties of the archive - // -------------------------------------------------------------------------------- - class PclZip - { - // ----- Filename of the zip file - var $zipname = ''; - - // ----- File descriptor of the zip file - var $zip_fd = 0; - - // ----- Internal error handling - var $error_code = 1; - var $error_string = ''; - - // ----- Current status of the magic_quotes_runtime - // This value store the php configuration for magic_quotes - // The class can then disable the magic_quotes and reset it after - var $magic_quotes_status; - - // -------------------------------------------------------------------------------- - // Function : PclZip() - // Description : - // Creates a PclZip object and set the name of the associated Zip archive - // filename. - // Note that no real action is taken, if the archive does not exist it is not - // created. Use create() for that. - // -------------------------------------------------------------------------------- - function PclZip($p_zipname) - { - - // ----- Tests the zlib - if (!function_exists('gzopen')) - { - die('Abort '.basename(__FILE__).' : Missing zlib extensions'); - } - - // ----- Set the attributes - $this->zipname = $p_zipname; - $this->zip_fd = 0; - $this->magic_quotes_status = -1; - - // ----- Return - return; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // create($p_filelist, $p_add_dir="", $p_remove_dir="") - // create($p_filelist, $p_option, $p_option_value, ...) - // Description : - // This method supports two different synopsis. The first one is historical. - // This method creates a Zip Archive. The Zip file is created in the - // filesystem. The files and directories indicated in $p_filelist - // are added in the archive. See the parameters description for the - // supported format of $p_filelist. - // When a directory is in the list, the directory and its content is added - // in the archive. - // In this synopsis, the function takes an optional variable list of - // options. See bellow the supported options. - // Parameters : - // $p_filelist : An array containing file or directory names, or - // a string containing one filename or one directory name, or - // a string containing a list of filenames and/or directory - // names separated by spaces. - // $p_add_dir : A path to add before the real path of the archived file, - // in order to have it memorized in the archive. - // $p_remove_dir : A path to remove from the real path of the file to archive, - // in order to have a shorter path memorized in the archive. - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir - // is removed first, before $p_add_dir is added. - // Options : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_COMMENT : - // PCLZIP_CB_PRE_ADD : - // PCLZIP_CB_POST_ADD : - // Return Values : - // 0 on failure, - // The list of the added files, with a status of the add action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function create($p_filelist) - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Set default values - $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove from the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - //, PCLZIP_OPT_CRYPT => 'optional' - )); - if ($v_result != 1) { - return 0; - } - } - - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { - - // ----- Get the first argument - $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; - - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; - } - else if ($v_size > 2) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Invalid number / type of arguments"); - return 0; - } - } - } - - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Init - $v_string_list = array(); - $v_att_list = array(); - $v_filedescr_list = array(); - $p_result_list = array(); - - // ----- Look if the $p_filelist is really an array - if (is_array($p_filelist)) { - - // ----- Look if the first element is also an array - // This will mean that this is a file description entry - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; - } - - // ----- The list is a list of string names - else { - $v_string_list = $p_filelist; - } - } - - // ----- Look if the $p_filelist is a string - else if (is_string($p_filelist)) { - // ----- Create a list from the string - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); - } - - // ----- Invalid variable type for $p_filelist - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); - return 0; - } - - // ----- Reformat the string list - if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - if ($v_string != '') { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; - } - else { - } - } - } - - // ----- For each file in the list check the attributes - $v_supported_attributes - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' - ,PCLZIP_ATT_FILE_MTIME => 'optional' - ,PCLZIP_ATT_FILE_CONTENT => 'optional' - ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); - foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, - $v_filedescr_list[], - $v_options, - $v_supported_attributes); - if ($v_result != 1) { - return 0; - } - } - - // ----- Expand the filelist (expand directories) - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); - if ($v_result != 1) { - return 0; - } - - // ----- Call the create fct - $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); - if ($v_result != 1) { - return 0; - } - - // ----- Return - return $p_result_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // add($p_filelist, $p_add_dir="", $p_remove_dir="") - // add($p_filelist, $p_option, $p_option_value, ...) - // Description : - // This method supports two synopsis. The first one is historical. - // This methods add the list of files in an existing archive. - // If a file with the same name already exists, it is added at the end of the - // archive, the first one is still present. - // If the archive does not exist, it is created. - // Parameters : - // $p_filelist : An array containing file or directory names, or - // a string containing one filename or one directory name, or - // a string containing a list of filenames and/or directory - // names separated by spaces. - // $p_add_dir : A path to add before the real path of the archived file, - // in order to have it memorized in the archive. - // $p_remove_dir : A path to remove from the real path of the file to archive, - // in order to have a shorter path memorized in the archive. - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir - // is removed first, before $p_add_dir is added. - // Options : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_COMMENT : - // PCLZIP_OPT_ADD_COMMENT : - // PCLZIP_OPT_PREPEND_COMMENT : - // PCLZIP_CB_PRE_ADD : - // PCLZIP_CB_POST_ADD : - // Return Values : - // 0 on failure, - // The list of the added files, with a status of the add action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function add($p_filelist) - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Set default values - $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove form the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_ADD_COMMENT => 'optional', - PCLZIP_OPT_PREPEND_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - //, PCLZIP_OPT_CRYPT => 'optional' - )); - if ($v_result != 1) { - return 0; - } - } - - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { - - // ----- Get the first argument - $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; - - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; - } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - - // ----- Return - return 0; - } - } - } - - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Init - $v_string_list = array(); - $v_att_list = array(); - $v_filedescr_list = array(); - $p_result_list = array(); - - // ----- Look if the $p_filelist is really an array - if (is_array($p_filelist)) { - - // ----- Look if the first element is also an array - // This will mean that this is a file description entry - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; - } - - // ----- The list is a list of string names - else { - $v_string_list = $p_filelist; - } - } - - // ----- Look if the $p_filelist is a string - else if (is_string($p_filelist)) { - // ----- Create a list from the string - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); - } - - // ----- Invalid variable type for $p_filelist - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); - return 0; - } - - // ----- Reformat the string list - if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; - } - } - - // ----- For each file in the list check the attributes - $v_supported_attributes - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' - ,PCLZIP_ATT_FILE_MTIME => 'optional' - ,PCLZIP_ATT_FILE_CONTENT => 'optional' - ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); - foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, - $v_filedescr_list[], - $v_options, - $v_supported_attributes); - if ($v_result != 1) { - return 0; - } - } - - // ----- Expand the filelist (expand directories) - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); - if ($v_result != 1) { - return 0; - } - - // ----- Call the create fct - $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); - if ($v_result != 1) { - return 0; - } - - // ----- Return - return $p_result_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : listContent() - // Description : - // This public method, gives the list of the files and directories, with their - // properties. - // The properties of each entries in the list are (used also in other functions) : - // filename : Name of the file. For a create or add action it is the filename - // given by the user. For an extract function it is the filename - // of the extracted file. - // stored_filename : Name of the file / directory stored in the archive. - // size : Size of the stored file. - // compressed_size : Size of the file's data compressed in the archive - // (without the headers overhead) - // mtime : Last known modification date of the file (UNIX timestamp) - // comment : Comment associated with the file - // folder : true | false - // index : index of the file in the archive - // status : status of the action (depending of the action) : - // Values are : - // ok : OK ! - // filtered : the file / dir is not extracted (filtered by user) - // already_a_directory : the file can not be extracted because a - // directory with the same name already exists - // write_protected : the file can not be extracted because a file - // with the same name already exists and is - // write protected - // newer_exist : the file was not extracted because a newer file exists - // path_creation_fail : the file is not extracted because the folder - // does not exist and can not be created - // write_error : the file was not extracted because there was a - // error while writing the file - // read_error : the file was not extracted because there was a error - // while reading the file - // invalid_header : the file was not extracted because of an archive - // format error (bad file header) - // Note that each time a method can continue operating when there - // is an action error on a file, the error is only logged in the file status. - // Return Values : - // 0 on an unrecoverable failure, - // The list of the files in the archive. - // -------------------------------------------------------------------------------- - function listContent() - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } - - // ----- Call the extracting fct - $p_list = array(); - if (($v_result = $this->privList($p_list)) != 1) - { - unset($p_list); - return(0); - } - - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // extract($p_path="./", $p_remove_path="") - // extract([$p_option, $p_option_value, ...]) - // Description : - // This method supports two synopsis. The first one is historical. - // This method extract all the files / directories from the archive to the - // folder indicated in $p_path. - // If you want to ignore the 'root' part of path of the memorized files - // you can indicate this in the optional $p_remove_path parameter. - // By default, if a newer file with the same name already exists, the - // file is not extracted. - // - // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions - // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append - // at the end of the path value of PCLZIP_OPT_PATH. - // Parameters : - // $p_path : Path where the files and directories are to be extracted - // $p_remove_path : First part ('root' part) of the memorized path - // (if any similar) to remove while extracting. - // Options : - // PCLZIP_OPT_PATH : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_CB_PRE_EXTRACT : - // PCLZIP_CB_POST_EXTRACT : - // Return Values : - // 0 or a negative value on failure, - // The list of the extracted files, with a status of the action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function extract() - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } - - // ----- Set default values - $v_options = array(); -// $v_path = "./"; - $v_path = ''; - $v_remove_path = ""; - $v_remove_all_path = false; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Default values for option - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; - - // ----- Look for arguments - if ($v_size > 0) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional' - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; - } - - // ----- Set the arguments - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - // ----- Check for '/' in last path char - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; - } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; - } - } - - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { - - // ----- Get the first argument - $v_path = $v_arg_list[0]; - - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; - } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - - // ----- Return - return 0; - } - } - } - - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Trace - - // ----- Call the extracting fct - $p_list = array(); - $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, - $v_remove_all_path, $v_options); - if ($v_result < 1) { - unset($p_list); - return(0); - } - - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - - // -------------------------------------------------------------------------------- - // Function : - // extractByIndex($p_index, $p_path="./", $p_remove_path="") - // extractByIndex($p_index, [$p_option, $p_option_value, ...]) - // Description : - // This method supports two synopsis. The first one is historical. - // This method is doing a partial extract of the archive. - // The extracted files or folders are identified by their index in the - // archive (from 0 to n). - // Note that if the index identify a folder, only the folder entry is - // extracted, not all the files included in the archive. - // Parameters : - // $p_index : A single index (integer) or a string of indexes of files to - // extract. The form of the string is "0,4-6,8-12" with only numbers - // and '-' for range or ',' to separate ranges. No spaces or ';' - // are allowed. - // $p_path : Path where the files and directories are to be extracted - // $p_remove_path : First part ('root' part) of the memorized path - // (if any similar) to remove while extracting. - // Options : - // PCLZIP_OPT_PATH : - // PCLZIP_OPT_ADD_PATH : - // PCLZIP_OPT_REMOVE_PATH : - // PCLZIP_OPT_REMOVE_ALL_PATH : - // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and - // not as files. - // The resulting content is in a new field 'content' in the file - // structure. - // This option must be used alone (any other options are ignored). - // PCLZIP_CB_PRE_EXTRACT : - // PCLZIP_CB_POST_EXTRACT : - // Return Values : - // 0 on failure, - // The list of the extracted files, with a status of the action. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - //function extractByIndex($p_index, options...) - function extractByIndex($p_index) - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } - - // ----- Set default values - $v_options = array(); -// $v_path = "./"; - $v_path = ''; - $v_remove_path = ""; - $v_remove_all_path = false; - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Default values for option - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; - - // ----- Look for arguments - if ($v_size > 1) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Remove form the options list the first argument - array_shift($v_arg_list); - $v_size--; - - // ----- Look for first arg - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional' - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; - } - - // ----- Set the arguments - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - // ----- Check for '/' in last path char - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; - } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; - } - if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; - } - else { - } - } - - // ----- Look for 2 args - // Here we need to support the first historic synopsis of the - // method. - else { - - // ----- Get the first argument - $v_path = $v_arg_list[0]; - - // ----- Look for the optional second argument - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; - } - else if ($v_size > 2) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - - // ----- Return - return 0; - } - } - } - - // ----- Trace - - // ----- Trick - // Here I want to reuse extractByRule(), so I need to parse the $p_index - // with privParseOptions() - $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); - $v_options_trick = array(); - $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, - array (PCLZIP_OPT_BY_INDEX => 'optional' )); - if ($v_result != 1) { - return 0; - } - $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; - - // ----- Look for default option values - $this->privOptionDefaultThreshold($v_options); - - // ----- Call the extracting fct - if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { - return(0); - } - - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : - // delete([$p_option, $p_option_value, ...]) - // Description : - // This method removes files from the archive. - // If no parameters are given, then all the archive is emptied. - // Parameters : - // None or optional arguments. - // Options : - // PCLZIP_OPT_BY_INDEX : - // PCLZIP_OPT_BY_NAME : - // PCLZIP_OPT_BY_EREG : - // PCLZIP_OPT_BY_PREG : - // Return Values : - // 0 on failure, - // The list of the files which are still present in the archive. - // (see PclZip::listContent() for list entry format) - // -------------------------------------------------------------------------------- - function delete() - { - $v_result=1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } - - // ----- Set default values - $v_options = array(); - - // ----- Look for variable options arguments - $v_size = func_num_args(); - - // ----- Look for arguments - if ($v_size > 0) { - // ----- Get the arguments - $v_arg_list = func_get_args(); - - // ----- Parse the options - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional' )); - if ($v_result != 1) { - return 0; - } - } - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Call the delete fct - $v_list = array(); - if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { - $this->privSwapBackMagicQuotes(); - unset($v_list); - return(0); - } - - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : deleteByIndex() - // Description : - // ***** Deprecated ***** - // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. - // -------------------------------------------------------------------------------- - function deleteByIndex($p_index) - { - - $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); - - // ----- Return - return $p_list; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : properties() - // Description : - // This method gives the properties of the archive. - // The properties are : - // nb : Number of files in the archive - // comment : Comment associated with the archive file - // status : not_exist, ok - // Parameters : - // None - // Return Values : - // 0 on failure, - // An array with the archive properties. - // -------------------------------------------------------------------------------- - function properties() - { - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - $this->privSwapBackMagicQuotes(); - return(0); - } - - // ----- Default properties - $v_prop = array(); - $v_prop['comment'] = ''; - $v_prop['nb'] = 0; - $v_prop['status'] = 'not_exist'; - - // ----- Look if file exists - if (@is_file($this->zipname)) - { - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) - { - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - - // ----- Return - return 0; - } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privSwapBackMagicQuotes(); - return 0; - } - - // ----- Close the zip file - $this->privCloseFd(); - - // ----- Set the user attributes - $v_prop['comment'] = $v_central_dir['comment']; - $v_prop['nb'] = $v_central_dir['entries']; - $v_prop['status'] = 'ok'; - } - - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_prop; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : duplicate() - // Description : - // This method creates an archive by copying the content of an other one. If - // the archive already exist, it is replaced by the new one without any warning. - // Parameters : - // $p_archive : The filename of a valid archive, or - // a valid PclZip object. - // Return Values : - // 1 on success. - // 0 or a negative value on error (error code). - // -------------------------------------------------------------------------------- - function duplicate($p_archive) - { - $v_result = 1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Look if the $p_archive is a PclZip object - if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) - { - - // ----- Duplicate the archive - $v_result = $this->privDuplicate($p_archive->zipname); - } - - // ----- Look if the $p_archive is a string (so a filename) - else if (is_string($p_archive)) - { - - // ----- Check that $p_archive is a valid zip file - // TBC : Should also check the archive format - if (!is_file($p_archive)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); - $v_result = PCLZIP_ERR_MISSING_FILE; - } - else { - // ----- Duplicate the archive - $v_result = $this->privDuplicate($p_archive); - } - } - - // ----- Invalid variable - else - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : merge() - // Description : - // This method merge the $p_archive_to_add archive at the end of the current - // one ($this). - // If the archive ($this) does not exist, the merge becomes a duplicate. - // If the $p_archive_to_add archive does not exist, the merge is a success. - // Parameters : - // $p_archive_to_add : It can be directly the filename of a valid zip archive, - // or a PclZip object archive. - // Return Values : - // 1 on success, - // 0 or negative values on error (see below). - // -------------------------------------------------------------------------------- - function merge($p_archive_to_add) - { - $v_result = 1; - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Check archive - if (!$this->privCheckFormat()) { - return(0); - } - - // ----- Look if the $p_archive_to_add is a PclZip object - if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) - { - - // ----- Merge the archive - $v_result = $this->privMerge($p_archive_to_add); - } - - // ----- Look if the $p_archive_to_add is a string (so a filename) - else if (is_string($p_archive_to_add)) - { - - // ----- Create a temporary archive - $v_object_archive = new PclZip($p_archive_to_add); - - // ----- Merge the archive - $v_result = $this->privMerge($v_object_archive); - } - - // ----- Invalid variable - else - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - - - // -------------------------------------------------------------------------------- - // Function : errorCode() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function errorCode() - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorCode()); - } - else { - return($this->error_code); - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : errorName() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function errorName($p_with_code=false) - { - $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', - PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', - PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', - PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', - PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', - PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', - PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', - PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', - PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', - PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', - PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', - PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', - PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', - PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', - PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', - PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', - PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', - PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', - PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' - ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' - ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' - ); - - if (isset($v_name[$this->error_code])) { - $v_value = $v_name[$this->error_code]; - } - else { - $v_value = 'NoName'; - } - - if ($p_with_code) { - return($v_value.' ('.$this->error_code.')'); - } - else { - return($v_value); - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : errorInfo() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function errorInfo($p_full=false) - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorString()); - } - else { - if ($p_full) { - return($this->errorName(true)." : ".$this->error_string); - } - else { - return($this->error_string." [code ".$this->error_code."]"); - } - } - } - // -------------------------------------------------------------------------------- - - -// -------------------------------------------------------------------------------- -// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** -// ***** ***** -// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** -// -------------------------------------------------------------------------------- - - - - // -------------------------------------------------------------------------------- - // Function : privCheckFormat() - // Description : - // This method check that the archive exists and is a valid zip archive. - // Several level of check exists. (futur) - // Parameters : - // $p_level : Level of check. Default 0. - // 0 : Check the first bytes (magic codes) (default value)) - // 1 : 0 + Check the central directory (futur) - // 2 : 1 + Check each file header (futur) - // Return Values : - // true on success, - // false on error, the error code is set. - // -------------------------------------------------------------------------------- - function privCheckFormat($p_level=0) - { - $v_result = true; - - // ----- Reset the file system cache - clearstatcache(); - - // ----- Reset the error handler - $this->privErrorReset(); - - // ----- Look if the file exits - if (!is_file($this->zipname)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); - return(false); - } - - // ----- Check that the file is readeable - if (!is_readable($this->zipname)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); - return(false); - } - - // ----- Check the magic code - // TBC - - // ----- Check the central header - // TBC - - // ----- Check each file header - // TBC - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privParseOptions() - // Description : - // This internal methods reads the variable list of arguments ($p_options_list, - // $p_size) and generate an array with the options and values ($v_result_list). - // $v_requested_options contains the options that can be present and those that - // must be present. - // $v_requested_options is an array, with the option value as key, and 'optional', - // or 'mandatory' as value. - // Parameters : - // See above. - // Return Values : - // 1 on success. - // 0 on failure. - // -------------------------------------------------------------------------------- - function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) - { - $v_result=1; - - // ----- Read the options - $i=0; - while ($i<$p_size) { - - // ----- Check if the option is supported - if (!isset($v_requested_options[$p_options_list[$i]])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for next option - switch ($p_options_list[$i]) { - // ----- Look for options that request a path value - case PCLZIP_OPT_PATH : - case PCLZIP_OPT_REMOVE_PATH : - case PCLZIP_OPT_ADD_PATH : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); - $i++; - break; - - case PCLZIP_OPT_TEMP_FILE_THRESHOLD : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } - - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); - return PclZip::errorCode(); - } - - // ----- Check the value - $v_value = $p_options_list[$i+1]; - if ((!is_integer($v_value)) || ($v_value<0)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } - - // ----- Get the value (and convert it in bytes) - $v_result_list[$p_options_list[$i]] = $v_value*1048576; - $i++; - break; - - case PCLZIP_OPT_TEMP_FILE_ON : - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); - return PclZip::errorCode(); - } - - $v_result_list[$p_options_list[$i]] = true; - break; - - case PCLZIP_OPT_TEMP_FILE_OFF : - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); - return PclZip::errorCode(); - } - // ----- Check for incompatible options - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); - return PclZip::errorCode(); - } - - $v_result_list[$p_options_list[$i]] = true; - break; - - case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - if ( is_string($p_options_list[$i+1]) - && ($p_options_list[$i+1] != '')) { - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); - $i++; - } - else { - } - break; - - // ----- Look for options that request an array of string for value - case PCLZIP_OPT_BY_NAME : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; - } - else if (is_array($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that request an EREG or PREG expression - case PCLZIP_OPT_BY_EREG : - // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG - // to PCLZIP_OPT_BY_PREG - $p_options_list[$i] = PCLZIP_OPT_BY_PREG; - case PCLZIP_OPT_BY_PREG : - //case PCLZIP_OPT_CRYPT : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that takes a string - case PCLZIP_OPT_COMMENT : - case PCLZIP_OPT_ADD_COMMENT : - case PCLZIP_OPT_PREPEND_COMMENT : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, - "Missing parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, - "Wrong parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); - - // ----- Return - return PclZip::errorCode(); - } - $i++; - break; - - // ----- Look for options that request an array of index - case PCLZIP_OPT_BY_INDEX : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_work_list = array(); - if (is_string($p_options_list[$i+1])) { - - // ----- Remove spaces - $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); - - // ----- Parse items - $v_work_list = explode(",", $p_options_list[$i+1]); - } - else if (is_integer($p_options_list[$i+1])) { - $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; - } - else if (is_array($p_options_list[$i+1])) { - $v_work_list = $p_options_list[$i+1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Reduce the index list - // each index item in the list must be a couple with a start and - // an end value : [0,3], [5-5], [8-10], ... - // ----- Check the format of each item - $v_sort_flag=false; - $v_sort_value=0; - for ($j=0; $j<sizeof($v_work_list); $j++) { - // ----- Explode the item - $v_item_list = explode("-", $v_work_list[$j]); - $v_size_item_list = sizeof($v_item_list); - - // ----- TBC : Here we might check that each item is a - // real integer ... - - // ----- Look for single value - if ($v_size_item_list == 1) { - // ----- Set the option value - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; - } - elseif ($v_size_item_list == 2) { - // ----- Set the option value - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; - } - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - - // ----- Look for list sort - if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { - $v_sort_flag=true; - - // ----- TBC : An automatic sort should be writen ... - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; - } - - // ----- Sort the items - if ($v_sort_flag) { - // TBC : To Be Completed - } - - // ----- Next option - $i++; - break; - - // ----- Look for options that request no value - case PCLZIP_OPT_REMOVE_ALL_PATH : - case PCLZIP_OPT_EXTRACT_AS_STRING : - case PCLZIP_OPT_NO_COMPRESSION : - case PCLZIP_OPT_EXTRACT_IN_OUTPUT : - case PCLZIP_OPT_REPLACE_NEWER : - case PCLZIP_OPT_STOP_ON_ERROR : - $v_result_list[$p_options_list[$i]] = true; - break; - - // ----- Look for options that request an octal value - case PCLZIP_OPT_SET_CHMOD : - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - $i++; - break; - - // ----- Look for options that request a call-back - case PCLZIP_CB_PRE_EXTRACT : - case PCLZIP_CB_POST_EXTRACT : - case PCLZIP_CB_PRE_ADD : - case PCLZIP_CB_POST_ADD : - /* for futur use - case PCLZIP_CB_PRE_DELETE : - case PCLZIP_CB_POST_DELETE : - case PCLZIP_CB_PRE_LIST : - case PCLZIP_CB_POST_LIST : - */ - // ----- Check the number of parameters - if (($i+1) >= $p_size) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Get the value - $v_function_name = $p_options_list[$i+1]; - - // ----- Check that the value is a valid existing function - if (!function_exists($v_function_name)) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Set the attribute - $v_result_list[$p_options_list[$i]] = $v_function_name; - $i++; - break; - - default : - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Unknown parameter '" - .$p_options_list[$i]."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Next options - $i++; - } - - // ----- Look for mandatory options - if ($v_requested_options !== false) { - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { - // ----- Look for mandatory option - if ($v_requested_options[$key] == 'mandatory') { - // ----- Look if present - if (!isset($v_result_list[$key])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); - - // ----- Return - return PclZip::errorCode(); - } - } - } - } - - // ----- Look for default values - if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { - - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privOptionDefaultThreshold() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privOptionDefaultThreshold(&$p_options) - { - $v_result=1; - - if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { - return $v_result; - } - - // ----- Get 'memory_limit' configuration value - $v_memory_limit = ini_get('memory_limit'); - $v_memory_limit = trim($v_memory_limit); - $last = strtolower(substr($v_memory_limit, -1)); - - if ($last == 'g') - //$v_memory_limit = $v_memory_limit*1024*1024*1024; - $v_memory_limit = $v_memory_limit*1073741824; - if ($last == 'm') - //$v_memory_limit = $v_memory_limit*1024*1024; - $v_memory_limit = $v_memory_limit*1048576; - if ($last == 'k') - $v_memory_limit = $v_memory_limit*1024; - - $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); - - - // ----- Sanity check : No threshold if value lower than 1M - if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { - unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privFileDescrParseAtt() - // Description : - // Parameters : - // Return Values : - // 1 on success. - // 0 on failure. - // -------------------------------------------------------------------------------- - function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) - { - $v_result=1; - - // ----- For each file in the list check the attributes - foreach ($p_file_list as $v_key => $v_value) { - - // ----- Check if the option is supported - if (!isset($v_requested_options[$v_key])) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for attribute - switch ($v_key) { - case PCLZIP_ATT_FILE_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); - - if ($p_filedescr['filename'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - break; - - case PCLZIP_ATT_FILE_NEW_SHORT_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); - - if ($p_filedescr['new_short_name'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - break; - - case PCLZIP_ATT_FILE_NEW_FULL_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); - - if ($p_filedescr['new_full_name'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - break; - - // ----- Look for options that takes a string - case PCLZIP_ATT_FILE_COMMENT : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['comment'] = $v_value; - break; - - case PCLZIP_ATT_FILE_MTIME : - if (!is_integer($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - - $p_filedescr['mtime'] = $v_value; - break; - - case PCLZIP_ATT_FILE_CONTENT : - $p_filedescr['content'] = $v_value; - break; - - default : - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Unknown parameter '".$v_key."'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for mandatory options - if ($v_requested_options !== false) { - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { - // ----- Look for mandatory option - if ($v_requested_options[$key] == 'mandatory') { - // ----- Look if present - if (!isset($p_file_list[$key])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); - return PclZip::errorCode(); - } - } - } - } - - // end foreach - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privFileDescrExpand() - // Description : - // This method look for each item of the list to see if its a file, a folder - // or a string to be added as file. For any other type of files (link, other) - // just ignore the item. - // Then prepare the information that will be stored for that file. - // When its a folder, expand the folder with all the files that are in that - // folder (recursively). - // Parameters : - // Return Values : - // 1 on success. - // 0 on failure. - // -------------------------------------------------------------------------------- - function privFileDescrExpand(&$p_filedescr_list, &$p_options) - { - $v_result=1; - - // ----- Create a result list - $v_result_list = array(); - - // ----- Look each entry - for ($i=0; $i<sizeof($p_filedescr_list); $i++) { - - // ----- Get filedescr - $v_descr = $p_filedescr_list[$i]; - - // ----- Reduce the filename - $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); - $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); - - // ----- Look for real file or folder - if (file_exists($v_descr['filename'])) { - if (@is_file($v_descr['filename'])) { - $v_descr['type'] = 'file'; - } - else if (@is_dir($v_descr['filename'])) { - $v_descr['type'] = 'folder'; - } - else if (@is_link($v_descr['filename'])) { - // skip - continue; - } - else { - // skip - continue; - } - } - - // ----- Look for string added as file - else if (isset($v_descr['content'])) { - $v_descr['type'] = 'virtual_file'; - } - - // ----- Missing file - else { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Calculate the stored filename - $this->privCalculateStoredFilename($v_descr, $p_options); - - // ----- Add the descriptor in result list - $v_result_list[sizeof($v_result_list)] = $v_descr; - - // ----- Look for folder - if ($v_descr['type'] == 'folder') { - // ----- List of items in folder - $v_dirlist_descr = array(); - $v_dirlist_nb = 0; - if ($v_folder_handler = @opendir($v_descr['filename'])) { - while (($v_item_handler = @readdir($v_folder_handler)) !== false) { - - // ----- Skip '.' and '..' - if (($v_item_handler == '.') || ($v_item_handler == '..')) { - continue; - } - - // ----- Compose the full filename - $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; - - // ----- Look for different stored filename - // Because the name of the folder was changed, the name of the - // files/sub-folders also change - if (($v_descr['stored_filename'] != $v_descr['filename']) - && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { - if ($v_descr['stored_filename'] != '') { - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; - } - else { - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; - } - } - - $v_dirlist_nb++; - } - - @closedir($v_folder_handler); - } - else { - // TBC : unable to open folder in read mode - } - - // ----- Expand each element of the list - if ($v_dirlist_nb != 0) { - // ----- Expand - if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { - return $v_result; - } - - // ----- Concat the resulting list - $v_result_list = array_merge($v_result_list, $v_dirlist_descr); - } - else { - } - - // ----- Free local array - unset($v_dirlist_descr); - } - } - - // ----- Get the result list - $p_filedescr_list = $v_result_list; - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCreate() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privCreate($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - $v_list_detail = array(); - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Open the file in write mode - if (($v_result = $this->privOpenFd('wb')) != 1) - { - // ----- Return - return $v_result; - } - - // ----- Add the list of files - $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); - - // ----- Close - $this->privCloseFd(); - - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAdd() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privAdd($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - $v_list_detail = array(); - - // ----- Look if the archive exists or is empty - if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) - { - - // ----- Do a create - $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); - - // ----- Return - return $v_result; - } - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Open the zip file - if (($v_result=$this->privOpenFd('rb')) != 1) - { - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } - - // ----- Go to beginning of File - @rewind($this->zip_fd); - - // ----- Creates a temporay file - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - - // ----- Open the temporary file in write mode - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) - { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Copy the files from the archive to the temporary file - // TBC : Here I should better append the file and go back to erase the central dir - $v_size = $v_central_dir['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Swap the file descriptor - // Here is a trick : I swap the temporary fd with the zip fd, in order to use - // the following methods on the temporary fil and not the real archive - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - - // ----- Add the files - $v_header_list = array(); - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) - { - fclose($v_zip_temp_fd); - $this->privCloseFd(); - @unlink($v_zip_temp_name); - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - - // ----- Store the offset of the central dir - $v_offset = @ftell($this->zip_fd); - - // ----- Copy the block of file headers from the old archive - $v_size = $v_central_dir['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_zip_temp_fd, $v_read_size); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Create the Central Dir files header - for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) - { - // ----- Create the file header - if ($v_header_list[$i]['status'] == 'ok') { - if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { - fclose($v_zip_temp_fd); - $this->privCloseFd(); - @unlink($v_zip_temp_name); - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - $v_count++; - } - - // ----- Transform the header to a 'usable' info - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } - - // ----- Zip file comment - $v_comment = $v_central_dir['comment']; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } - if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { - $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; - } - if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; - } - - // ----- Calculate the size of the central header - $v_size = @ftell($this->zip_fd)-$v_offset; - - // ----- Create the central dir footer - if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) - { - // ----- Reset the file list - unset($v_header_list); - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - - // ----- Swap back the file descriptor - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - - // ----- Close - $this->privCloseFd(); - - // ----- Close the temporary file - @fclose($v_zip_temp_fd); - - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Delete the zip file - // TBC : I should test the result ... - @unlink($this->zipname); - - // ----- Rename the temporary file - // TBC : I should test the result ... - //@rename($v_zip_temp_name, $this->zipname); - PclZipUtilRename($v_zip_temp_name, $this->zipname); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privOpenFd() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privOpenFd($p_mode) - { - $v_result=1; - - // ----- Look if already open - if ($this->zip_fd != 0) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCloseFd() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privCloseFd() - { - $v_result=1; - - if ($this->zip_fd != 0) - @fclose($this->zip_fd); - $this->zip_fd = 0; - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddList() - // Description : - // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is - // different from the real path of the file. This is usefull if you want to have PclTar - // running in any directory, and memorize relative path from an other directory. - // Parameters : - // $p_list : An array containing the file or directory names to add in the tar - // $p_result_list : list of added files with their properties (specially the status field) - // $p_add_dir : Path to add in the filename path archived - // $p_remove_dir : Path to remove in the filename path archived - // Return Values : - // -------------------------------------------------------------------------------- -// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) - function privAddList($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - - // ----- Add the files - $v_header_list = array(); - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) - { - // ----- Return - return $v_result; - } - - // ----- Store the offset of the central dir - $v_offset = @ftell($this->zip_fd); - - // ----- Create the Central Dir files header - for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) - { - // ----- Create the file header - if ($v_header_list[$i]['status'] == 'ok') { - if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { - // ----- Return - return $v_result; - } - $v_count++; - } - - // ----- Transform the header to a 'usable' info - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } - - // ----- Zip file comment - $v_comment = ''; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } - - // ----- Calculate the size of the central header - $v_size = @ftell($this->zip_fd)-$v_offset; - - // ----- Create the central dir footer - if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) - { - // ----- Reset the file list - unset($v_header_list); - - // ----- Return - return $v_result; - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddFileList() - // Description : - // Parameters : - // $p_filedescr_list : An array containing the file description - // or directory names to add in the zip - // $p_result_list : list of added files with their properties (specially the status field) - // Return Values : - // -------------------------------------------------------------------------------- - function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) - { - $v_result=1; - $v_header = array(); - - // ----- Recuperate the current number of elt in list - $v_nb = sizeof($p_result_list); - - // ----- Loop on the files - for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { - // ----- Format the filename - $p_filedescr_list[$j]['filename'] - = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); - - - // ----- Skip empty file names - // TBC : Can this be possible ? not checked in DescrParseAtt ? - if ($p_filedescr_list[$j]['filename'] == "") { - continue; - } - - // ----- Check the filename - if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') - && (!file_exists($p_filedescr_list[$j]['filename']))) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); - return PclZip::errorCode(); - } - - // ----- Look if it is a file or a dir with no all path remove option - // or a dir with all its path removed -// if ( (is_file($p_filedescr_list[$j]['filename'])) -// || ( is_dir($p_filedescr_list[$j]['filename']) - if ( ($p_filedescr_list[$j]['type'] == 'file') - || ($p_filedescr_list[$j]['type'] == 'virtual_file') - || ( ($p_filedescr_list[$j]['type'] == 'folder') - && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) - || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) - ) { - - // ----- Add the file - $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, - $p_options); - if ($v_result != 1) { - return $v_result; - } - - // ----- Store the file infos - $p_result_list[$v_nb++] = $v_header; - } - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddFile() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privAddFile($p_filedescr, &$p_header, &$p_options) - { - $v_result=1; - - // ----- Working variable - $p_filename = $p_filedescr['filename']; - - // TBC : Already done in the fileAtt check ... ? - if ($p_filename == "") { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for a stored different filename - /* TBC : Removed - if (isset($p_filedescr['stored_filename'])) { - $v_stored_filename = $p_filedescr['stored_filename']; - } - else { - $v_stored_filename = $p_filedescr['stored_filename']; - } - */ - - // ----- Set the file properties - clearstatcache(); - $p_header['version'] = 20; - $p_header['version_extracted'] = 10; - $p_header['flag'] = 0; - $p_header['compression'] = 0; - $p_header['crc'] = 0; - $p_header['compressed_size'] = 0; - $p_header['filename_len'] = strlen($p_filename); - $p_header['extra_len'] = 0; - $p_header['disk'] = 0; - $p_header['internal'] = 0; - $p_header['offset'] = 0; - $p_header['filename'] = $p_filename; -// TBC : Removed $p_header['stored_filename'] = $v_stored_filename; - $p_header['stored_filename'] = $p_filedescr['stored_filename']; - $p_header['extra'] = ''; - $p_header['status'] = 'ok'; - $p_header['index'] = -1; - - // ----- Look for regular file - if ($p_filedescr['type']=='file') { - $p_header['external'] = 0x00000000; - $p_header['size'] = filesize($p_filename); - } - - // ----- Look for regular folder - else if ($p_filedescr['type']=='folder') { - $p_header['external'] = 0x00000010; - $p_header['mtime'] = filemtime($p_filename); - $p_header['size'] = filesize($p_filename); - } - - // ----- Look for virtual file - else if ($p_filedescr['type'] == 'virtual_file') { - $p_header['external'] = 0x00000000; - $p_header['size'] = strlen($p_filedescr['content']); - } - - - // ----- Look for filetime - if (isset($p_filedescr['mtime'])) { - $p_header['mtime'] = $p_filedescr['mtime']; - } - else if ($p_filedescr['type'] == 'virtual_file') { - $p_header['mtime'] = time(); - } - else { - $p_header['mtime'] = filemtime($p_filename); - } - - // ------ Look for file comment - if (isset($p_filedescr['comment'])) { - $p_header['comment_len'] = strlen($p_filedescr['comment']); - $p_header['comment'] = $p_filedescr['comment']; - } - else { - $p_header['comment_len'] = 0; - $p_header['comment'] = ''; - } - - // ----- Look for pre-add callback - if (isset($p_options[PCLZIP_CB_PRE_ADD])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_header, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_header['status'] = "skipped"; - $v_result = 1; - } - - // ----- Update the informations - // Only some fields can be modified - if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { - $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); - } - } - - // ----- Look for empty stored filename - if ($p_header['stored_filename'] == "") { - $p_header['status'] = "filtered"; - } - - // ----- Check the path length - if (strlen($p_header['stored_filename']) > 0xFF) { - $p_header['status'] = 'filename_too_long'; - } - - // ----- Look if no error, or file not skipped - if ($p_header['status'] == 'ok') { - - // ----- Look for a file - if ($p_filedescr['type'] == 'file') { - // ----- Look for using temporary file to zip - if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { - $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); - if ($v_result < PCLZIP_ERR_NO_ERROR) { - return $v_result; - } - } - - // ----- Use "in memory" zip algo - else { - - // ----- Open the source file - if (($v_file = @fopen($p_filename, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); - return PclZip::errorCode(); - } - - // ----- Read the file content - $v_content = @fread($v_file, $p_header['size']); - - // ----- Close the file - @fclose($v_file); - - // ----- Calculate the CRC - $p_header['crc'] = @crc32($v_content); - - // ----- Look for no compression - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { - // ----- Set header parameters - $p_header['compressed_size'] = $p_header['size']; - $p_header['compression'] = 0; - } - - // ----- Look for normal compression - else { - // ----- Compress the content - $v_content = @gzdeflate($v_content); - - // ----- Set header parameters - $p_header['compressed_size'] = strlen($v_content); - $p_header['compression'] = 8; - } - - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - @fclose($v_file); - return $v_result; - } - - // ----- Write the compressed (or not) content - @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); - - } - - } - - // ----- Look for a virtual file (a file from string) - else if ($p_filedescr['type'] == 'virtual_file') { - - $v_content = $p_filedescr['content']; - - // ----- Calculate the CRC - $p_header['crc'] = @crc32($v_content); - - // ----- Look for no compression - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { - // ----- Set header parameters - $p_header['compressed_size'] = $p_header['size']; - $p_header['compression'] = 0; - } - - // ----- Look for normal compression - else { - // ----- Compress the content - $v_content = @gzdeflate($v_content); - - // ----- Set header parameters - $p_header['compressed_size'] = strlen($v_content); - $p_header['compression'] = 8; - } - - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - @fclose($v_file); - return $v_result; - } - - // ----- Write the compressed (or not) content - @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); - } - - // ----- Look for a directory - else if ($p_filedescr['type'] == 'folder') { - // ----- Look for directory last '/' - if (@substr($p_header['stored_filename'], -1) != '/') { - $p_header['stored_filename'] .= '/'; - } - - // ----- Set the file properties - $p_header['size'] = 0; - //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked - $p_header['external'] = 0x00000010; // Value for a folder : to be checked - - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) - { - return $v_result; - } - } - } - - // ----- Look for post-add callback - if (isset($p_options[PCLZIP_CB_POST_ADD])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_header, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); - if ($v_result == 0) { - // ----- Ignored - $v_result = 1; - } - - // ----- Update the informations - // Nothing can be modified - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privAddFileUsingTempFile() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) - { - $v_result=PCLZIP_ERR_NO_ERROR; - - // ----- Working variable - $p_filename = $p_filedescr['filename']; - - - // ----- Open the source file - if (($v_file = @fopen($p_filename, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); - return PclZip::errorCode(); - } - - // ----- Creates a compressed temporary file - $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; - if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { - fclose($v_file); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); - return PclZip::errorCode(); - } - - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = filesize($p_filename); - while ($v_size != 0) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_file, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @gzputs($v_file_compressed, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Close the file - @fclose($v_file); - @gzclose($v_file_compressed); - - // ----- Check the minimum file size - if (filesize($v_gzip_temp_name) < 18) { - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); - return PclZip::errorCode(); - } - - // ----- Extract the compressed attributes - if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); - } - - // ----- Read the gzip file header - $v_binary_data = @fread($v_file_compressed, 10); - $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); - - // ----- Check some parameters - $v_data_header['os'] = bin2hex($v_data_header['os']); - - // ----- Read the gzip file footer - @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); - $v_binary_data = @fread($v_file_compressed, 8); - $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); - - // ----- Set the attributes - $p_header['compression'] = ord($v_data_header['cm']); - //$p_header['mtime'] = $v_data_header['mtime']; - $p_header['crc'] = $v_data_footer['crc']; - $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; - - // ----- Close the file - @fclose($v_file_compressed); - - // ----- Call the header generation - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - return $v_result; - } - - // ----- Add the compressed data - if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) - { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); - } - - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - fseek($v_file_compressed, 10); - $v_size = $p_header['compressed_size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_file_compressed, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Close the file - @fclose($v_file_compressed); - - // ----- Unlink the temporary file - @unlink($v_gzip_temp_name); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCalculateStoredFilename() - // Description : - // Based on file descriptor properties and global options, this method - // calculate the filename that will be stored in the archive. - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privCalculateStoredFilename(&$p_filedescr, &$p_options) - { - $v_result=1; - - // ----- Working variables - $p_filename = $p_filedescr['filename']; - if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { - $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; - } - else { - $p_add_dir = ''; - } - if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { - $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; - } - else { - $p_remove_dir = ''; - } - if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - else { - $p_remove_all_dir = 0; - } - - - // ----- Look for full name change - if (isset($p_filedescr['new_full_name'])) { - // ----- Remove drive letter if any - $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); - } - - // ----- Look for path and/or short name change - else { - - // ----- Look for short name change - // Its when we cahnge just the filename but not the path - if (isset($p_filedescr['new_short_name'])) { - $v_path_info = pathinfo($p_filename); - $v_dir = ''; - if ($v_path_info['dirname'] != '') { - $v_dir = $v_path_info['dirname'].'/'; - } - $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; - } - else { - // ----- Calculate the stored filename - $v_stored_filename = $p_filename; - } - - // ----- Look for all path to remove - if ($p_remove_all_dir) { - $v_stored_filename = basename($p_filename); - } - // ----- Look for partial path remove - else if ($p_remove_dir != "") { - if (substr($p_remove_dir, -1) != '/') - $p_remove_dir .= "/"; - - if ( (substr($p_filename, 0, 2) == "./") - || (substr($p_remove_dir, 0, 2) == "./")) { - - if ( (substr($p_filename, 0, 2) == "./") - && (substr($p_remove_dir, 0, 2) != "./")) { - $p_remove_dir = "./".$p_remove_dir; - } - if ( (substr($p_filename, 0, 2) != "./") - && (substr($p_remove_dir, 0, 2) == "./")) { - $p_remove_dir = substr($p_remove_dir, 2); - } - } - - $v_compare = PclZipUtilPathInclusion($p_remove_dir, - $v_stored_filename); - if ($v_compare > 0) { - if ($v_compare == 2) { - $v_stored_filename = ""; - } - else { - $v_stored_filename = substr($v_stored_filename, - strlen($p_remove_dir)); - } - } - } - - // ----- Remove drive letter if any - $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); - - // ----- Look for path to add - if ($p_add_dir != "") { - if (substr($p_add_dir, -1) == "/") - $v_stored_filename = $p_add_dir.$v_stored_filename; - else - $v_stored_filename = $p_add_dir."/".$v_stored_filename; - } - } - - // ----- Filename (reduce the path of stored name) - $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); - $p_filedescr['stored_filename'] = $v_stored_filename; - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privWriteFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privWriteFileHeader(&$p_header) - { - $v_result=1; - - // ----- Store the offset position of the file - $p_header['offset'] = ftell($this->zip_fd); - - // ----- Transform UNIX mtime to DOS format mdate/mtime - $v_date = getdate($p_header['mtime']); - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; - - // ----- Packed data - $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, - $p_header['version_extracted'], $p_header['flag'], - $p_header['compression'], $v_mtime, $v_mdate, - $p_header['crc'], $p_header['compressed_size'], - $p_header['size'], - strlen($p_header['stored_filename']), - $p_header['extra_len']); - - // ----- Write the first 148 bytes of the header in the archive - fputs($this->zip_fd, $v_binary_data, 30); - - // ----- Write the variable fields - if (strlen($p_header['stored_filename']) != 0) - { - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); - } - if ($p_header['extra_len'] != 0) - { - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privWriteCentralFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privWriteCentralFileHeader(&$p_header) - { - $v_result=1; - - // TBC - //for(reset($p_header); $key = key($p_header); next($p_header)) { - //} - - // ----- Transform UNIX mtime to DOS format mdate/mtime - $v_date = getdate($p_header['mtime']); - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; - - - // ----- Packed data - $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, - $p_header['version'], $p_header['version_extracted'], - $p_header['flag'], $p_header['compression'], - $v_mtime, $v_mdate, $p_header['crc'], - $p_header['compressed_size'], $p_header['size'], - strlen($p_header['stored_filename']), - $p_header['extra_len'], $p_header['comment_len'], - $p_header['disk'], $p_header['internal'], - $p_header['external'], $p_header['offset']); - - // ----- Write the 42 bytes of the header in the zip file - fputs($this->zip_fd, $v_binary_data, 46); - - // ----- Write the variable fields - if (strlen($p_header['stored_filename']) != 0) - { - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); - } - if ($p_header['extra_len'] != 0) - { - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); - } - if ($p_header['comment_len'] != 0) - { - fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privWriteCentralHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) - { - $v_result=1; - - // ----- Packed data - $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, - $p_nb_entries, $p_size, - $p_offset, strlen($p_comment)); - - // ----- Write the 22 bytes of the header in the zip file - fputs($this->zip_fd, $v_binary_data, 22); - - // ----- Write the variable fields - if (strlen($p_comment) != 0) - { - fputs($this->zip_fd, $p_comment, strlen($p_comment)); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privList() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privList(&$p_list) - { - $v_result=1; - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Open the zip file - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) - { - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privSwapBackMagicQuotes(); - return $v_result; - } - - // ----- Go to beginning of Central Dir - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_central_dir['offset'])) - { - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read each entry - for ($i=0; $i<$v_central_dir['entries']; $i++) - { - // ----- Read the file header - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) - { - $this->privSwapBackMagicQuotes(); - return $v_result; - } - $v_header['index'] = $i; - - // ----- Get the only interesting attributes - $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); - unset($v_header); - } - - // ----- Close the zip file - $this->privCloseFd(); - - // ----- Magic quotes trick - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privConvertHeader2FileInfo() - // Description : - // This function takes the file informations from the central directory - // entries and extract the interesting parameters that will be given back. - // The resulting file infos are set in the array $p_info - // $p_info['filename'] : Filename with full path. Given by user (add), - // extracted in the filesystem (extract). - // $p_info['stored_filename'] : Stored filename in the archive. - // $p_info['size'] = Size of the file. - // $p_info['compressed_size'] = Compressed size of the file. - // $p_info['mtime'] = Last modification date of the file. - // $p_info['comment'] = Comment associated with the file. - // $p_info['folder'] = true/false : indicates if the entry is a folder or not. - // $p_info['status'] = status of the action on the file. - // $p_info['crc'] = CRC of the file content. - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privConvertHeader2FileInfo($p_header, &$p_info) - { - $v_result=1; - - // ----- Get the interesting attributes - $v_temp_path = PclZipUtilPathReduction($p_header['filename']); - $p_info['filename'] = $v_temp_path; - $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); - $p_info['stored_filename'] = $v_temp_path; - $p_info['size'] = $p_header['size']; - $p_info['compressed_size'] = $p_header['compressed_size']; - $p_info['mtime'] = $p_header['mtime']; - $p_info['comment'] = $p_header['comment']; - $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); - $p_info['index'] = $p_header['index']; - $p_info['status'] = $p_header['status']; - $p_info['crc'] = $p_header['crc']; - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractByRule() - // Description : - // Extract a file or directory depending of rules (by index, by name, ...) - // Parameters : - // $p_file_list : An array where will be placed the properties of each - // extracted file - // $p_path : Path to add while writing the extracted files - // $p_remove_path : Path to remove (from the file memorized path) while writing the - // extracted files. If the path does not match the file path, - // the file is extracted with its memorized path. - // $p_remove_path does not apply to 'list' mode. - // $p_path and $p_remove_path are commulative. - // Return Values : - // 1 on success,0 or less on error (see error code list) - // -------------------------------------------------------------------------------- - function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) - { - $v_result=1; - - // ----- Magic quotes trick - $this->privDisableMagicQuotes(); - - // ----- Check the path - if ( ($p_path == "") - || ( (substr($p_path, 0, 1) != "/") - && (substr($p_path, 0, 3) != "../") - && (substr($p_path,1,2)!=":/"))) - $p_path = "./".$p_path; - - // ----- Reduce the path last (and duplicated) '/' - if (($p_path != "./") && ($p_path != "/")) - { - // ----- Look for the path end '/' - while (substr($p_path, -1) == "/") - { - $p_path = substr($p_path, 0, strlen($p_path)-1); - } - } - - // ----- Look for path to remove format (should end by /) - if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) - { - $p_remove_path .= '/'; - } - $p_remove_path_size = strlen($p_remove_path); - - // ----- Open the zip file - if (($v_result = $this->privOpenFd('rb')) != 1) - { - $this->privSwapBackMagicQuotes(); - return $v_result; - } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - return $v_result; - } - - // ----- Start at beginning of Central Dir - $v_pos_entry = $v_central_dir['offset']; - - // ----- Read each entry - $j_start = 0; - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) - { - - // ----- Read next Central dir entry - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_pos_entry)) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read the file header - $v_header = array(); - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - return $v_result; - } - - // ----- Store the index - $v_header['index'] = $i; - - // ----- Store the file position - $v_pos_entry = ftell($this->zip_fd); - - // ----- Look for the specific extract rules - $v_extract = false; - - // ----- Look for extract by name rule - if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { - - // ----- Look if the filename is in the list - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { - - // ----- Look for a directory - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { - - // ----- Look if the directory is in the filename path - if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) - && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_extract = true; - } - } - // ----- Look for a filename - elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { - $v_extract = true; - } - } - } - - // ----- Look for extract by ereg rule - // ereg() is deprecated with PHP 5.3 - /* - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { - $v_extract = true; - } - } - */ - - // ----- Look for extract by preg rule - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { - - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { - $v_extract = true; - } - } - - // ----- Look for extract by index rule - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - - // ----- Look if the index is in the list - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { - - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_extract = true; - } - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; - } - - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; - } - } - } - - // ----- Look for no rule, which means extract all the archive - else { - $v_extract = true; - } - - // ----- Check compression method - if ( ($v_extract) - && ( ($v_header['compression'] != 8) - && ($v_header['compression'] != 0))) { - $v_header['status'] = 'unsupported_compression'; - - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, - "Filename '".$v_header['stored_filename']."' is " - ."compressed by an unsupported compression " - ."method (".$v_header['compression'].") "); - - return PclZip::errorCode(); - } - } - - // ----- Check encrypted files - if (($v_extract) && (($v_header['flag'] & 1) == 1)) { - $v_header['status'] = 'unsupported_encryption'; - - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, - "Unsupported encryption for " - ." filename '".$v_header['stored_filename'] - ."'"); - - return PclZip::errorCode(); - } - } - - // ----- Look for real extraction - if (($v_extract) && ($v_header['status'] != 'ok')) { - $v_result = $this->privConvertHeader2FileInfo($v_header, - $p_file_list[$v_nb_extracted++]); - if ($v_result != 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } - - $v_extract = false; - } - - // ----- Look for real extraction - if ($v_extract) - { - - // ----- Go to the file position - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_header['offset'])) - { - // ----- Close the zip file - $this->privCloseFd(); - - $this->privSwapBackMagicQuotes(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Look for extraction as string - if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { - - $v_string = ''; - - // ----- Extracting the file - $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } - - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - return $v_result; - } - - // ----- Set the file content - $p_file_list[$v_nb_extracted]['content'] = $v_string; - - // ----- Next extracted file - $v_nb_extracted++; - - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } - } - // ----- Look for extraction in standard output - elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) - && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { - // ----- Extracting the file in standard output - $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } - - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } - - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } - } - // ----- Look for normal extraction - else { - // ----- Extracting the file - $v_result1 = $this->privExtractFile($v_header, - $p_path, $p_remove_path, - $p_remove_all_path, - $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } - - // ----- Get the only interesting attributes - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - return $v_result; - } - - // ----- Look for user callback abort - if ($v_result1 == 2) { - break; - } - } - } - } - - // ----- Close the zip file - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFile() - // Description : - // Parameters : - // Return Values : - // - // 1 : ... ? - // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback - // -------------------------------------------------------------------------------- - function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) - { - $v_result=1; - - // ----- Read the file header - if (($v_result = $this->privReadFileHeader($v_header)) != 1) - { - // ----- Return - return $v_result; - } - - - // ----- Check that the file header is coherent with $p_entry info - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC - } - - // ----- Look for all path to remove - if ($p_remove_all_path == true) { - // ----- Look for folder entry that not need to be extracted - if (($p_entry['external']&0x00000010)==0x00000010) { - - $p_entry['status'] = "filtered"; - - return $v_result; - } - - // ----- Get the basename of the path - $p_entry['filename'] = basename($p_entry['filename']); - } - - // ----- Look for path to remove - else if ($p_remove_path != "") - { - if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) - { - - // ----- Change the file status - $p_entry['status'] = "filtered"; - - // ----- Return - return $v_result; - } - - $p_remove_path_size = strlen($p_remove_path); - if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) - { - - // ----- Remove the path - $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); - - } - } - - // ----- Add the path - if ($p_path != '') { - $p_entry['filename'] = $p_path."/".$p_entry['filename']; - } - - // ----- Check a base_dir_restriction - if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { - $v_inclusion - = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], - $p_entry['filename']); - if ($v_inclusion == 0) { - - PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, - "Filename '".$p_entry['filename']."' is " - ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); - - return PclZip::errorCode(); - } - } - - // ----- Look for pre-extract callback - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } - - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } - - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; - } - - - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { - - // ----- Look for specific actions while the file exist - if (file_exists($p_entry['filename'])) - { - - // ----- Look if file is a directory - if (is_dir($p_entry['filename'])) - { - - // ----- Change the file status - $p_entry['status'] = "already_a_directory"; - - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - - PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, - "Filename '".$p_entry['filename']."' is " - ."already used by an existing directory"); - - return PclZip::errorCode(); - } - } - // ----- Look if file is write protected - else if (!is_writeable($p_entry['filename'])) - { - - // ----- Change the file status - $p_entry['status'] = "write_protected"; - - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Filename '".$p_entry['filename']."' exists " - ."and is write protected"); - - return PclZip::errorCode(); - } - } - - // ----- Look if the extracted file is older - else if (filemtime($p_entry['filename']) > $p_entry['mtime']) - { - // ----- Change the file status - if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) - && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { - } - else { - $p_entry['status'] = "newer_exist"; - - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR - // For historical reason first PclZip implementation does not stop - // when this kind of error occurs. - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Newer version of '".$p_entry['filename']."' exists " - ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); - - return PclZip::errorCode(); - } - } - } - else { - } - } - - // ----- Check the directory availability and create it if necessary - else { - if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) - $v_dir_to_check = $p_entry['filename']; - else if (!strstr($p_entry['filename'], "/")) - $v_dir_to_check = ""; - else - $v_dir_to_check = dirname($p_entry['filename']); - - if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { - - // ----- Change the file status - $p_entry['status'] = "path_creation_fail"; - - // ----- Return - //return $v_result; - $v_result = 1; - } - } - } - - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { - - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) - { - // ----- Look for not compressed file - if ($p_entry['compression'] == 0) { - - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) - { - - // ----- Change the file status - $p_entry['status'] = "write_error"; - - // ----- Return - return $v_result; - } - - - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = $p_entry['compressed_size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - /* Try to speed up the code - $v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_binary_data, $v_read_size); - */ - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Closing the destination file - fclose($v_dest_file); - - // ----- Change the file mtime - touch($p_entry['filename'], $p_entry['mtime']); - - - } - else { - // ----- TBC - // Need to be finished - if (($p_entry['flag'] & 1) == 1) { - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); - return PclZip::errorCode(); - } - - - // ----- Look for using temporary file to unzip - if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { - $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); - if ($v_result < PCLZIP_ERR_NO_ERROR) { - return $v_result; - } - } - - // ----- Look for extract in memory - else { - - - // ----- Read the compressed file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - $v_file_content = @gzinflate($v_buffer); - unset($v_buffer); - if ($v_file_content === FALSE) { - - // ----- Change the file status - // TBC - $p_entry['status'] = "error"; - - return $v_result; - } - - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - - // ----- Change the file status - $p_entry['status'] = "write_error"; - - return $v_result; - } - - // ----- Write the uncompressed data - @fwrite($v_dest_file, $v_file_content, $p_entry['size']); - unset($v_file_content); - - // ----- Closing the destination file - @fclose($v_dest_file); - - } - - // ----- Change the file mtime - @touch($p_entry['filename'], $p_entry['mtime']); - } - - // ----- Look for chmod option - if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { - - // ----- Change the mode of the file - @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); - } - - } - } - - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; - } - - // ----- Look for post-extract callback - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; - } - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFileUsingTempFile() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privExtractFileUsingTempFile(&$p_entry, &$p_options) - { - $v_result=1; - - // ----- Creates a temporary file - $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; - if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { - fclose($v_file); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); - return PclZip::errorCode(); - } - - - // ----- Write gz file format header - $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); - @fwrite($v_dest_file, $v_binary_data, 10); - - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = $p_entry['compressed_size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Write gz file format footer - $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); - @fwrite($v_dest_file, $v_binary_data, 8); - - // ----- Close the temporary file - @fclose($v_dest_file); - - // ----- Opening destination file - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - $p_entry['status'] = "write_error"; - return $v_result; - } - - // ----- Open the temporary gz file - if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { - @fclose($v_dest_file); - $p_entry['status'] = "read_error"; - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); - } - - - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks - $v_size = $p_entry['size']; - while ($v_size != 0) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($v_src_file, $v_read_size); - //$v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - @fclose($v_dest_file); - @gzclose($v_src_file); - - // ----- Delete the temporary file - @unlink($v_gzip_temp_name); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFileInOutput() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privExtractFileInOutput(&$p_entry, &$p_options) - { - $v_result=1; - - // ----- Read the file header - if (($v_result = $this->privReadFileHeader($v_header)) != 1) { - return $v_result; - } - - - // ----- Check that the file header is coherent with $p_entry info - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC - } - - // ----- Look for pre-extract callback - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } - - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } - - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; - } - - // ----- Trace - - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { - - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) { - // ----- Look for not compressed file - if ($p_entry['compressed_size'] == $p_entry['size']) { - - // ----- Read the file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Send the file to the output - echo $v_buffer; - unset($v_buffer); - } - else { - - // ----- Read the compressed file in a buffer (one shot) - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - $v_file_content = gzinflate($v_buffer); - unset($v_buffer); - - // ----- Send the file to the output - echo $v_file_content; - unset($v_file_content); - } - } - } - - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; - } - - // ----- Look for post-extract callback - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; - } - } - - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privExtractFileAsString() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) - { - $v_result=1; - - // ----- Read the file header - $v_header = array(); - if (($v_result = $this->privReadFileHeader($v_header)) != 1) - { - // ----- Return - return $v_result; - } - - - // ----- Check that the file header is coherent with $p_entry info - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC - } - - // ----- Look for pre-extract callback - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); - if ($v_result == 0) { - // ----- Change the file status - $p_entry['status'] = "skipped"; - $v_result = 1; - } - - // ----- Look for abort result - if ($v_result == 2) { - // ----- This status is internal and will be changed in 'skipped' - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } - - // ----- Update the informations - // Only some fields can be modified - $p_entry['filename'] = $v_local_header['filename']; - } - - - // ----- Look if extraction should be done - if ($p_entry['status'] == 'ok') { - - // ----- Do the extraction (if not a folder) - if (!(($p_entry['external']&0x00000010)==0x00000010)) { - // ----- Look for not compressed file - // if ($p_entry['compressed_size'] == $p_entry['size']) - if ($p_entry['compression'] == 0) { - - // ----- Reading the file - $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); - } - else { - - // ----- Reading the file - $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); - - // ----- Decompress the file - if (($p_string = @gzinflate($v_data)) === FALSE) { - // TBC - } - } - - // ----- Trace - } - else { - // TBC : error : can not extract a folder in a string - } - - } - - // ----- Change abort status - if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; - } - - // ----- Look for post-extract callback - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - - // ----- Generate a local information - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - // ----- Swap the content to header - $v_local_header['content'] = $p_string; - $p_string = ''; - - // ----- Call the callback - // Here I do not use call_user_func() because I need to send a reference to the - // header. -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - - // ----- Swap back the content to header - $p_string = $v_local_header['content']; - unset($v_local_header['content']); - - // ----- Look for abort result - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; - } - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privReadFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privReadFileHeader(&$p_header) - { - $v_result=1; - - // ----- Read the 4 bytes signature - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = unpack('Vid', $v_binary_data); - - // ----- Check signature - if ($v_data['id'] != 0x04034b50) - { - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read the first 42 bytes of the header - $v_binary_data = fread($this->zip_fd, 26); - - // ----- Look for invalid block size - if (strlen($v_binary_data) != 26) - { - $p_header['filename'] = ""; - $p_header['status'] = "invalid_header"; - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Extract the values - $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); - - // ----- Get filename - $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); - - // ----- Get extra_fields - if ($v_data['extra_len'] != 0) { - $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); - } - else { - $p_header['extra'] = ''; - } - - // ----- Extract properties - $p_header['version_extracted'] = $v_data['version']; - $p_header['compression'] = $v_data['compression']; - $p_header['size'] = $v_data['size']; - $p_header['compressed_size'] = $v_data['compressed_size']; - $p_header['crc'] = $v_data['crc']; - $p_header['flag'] = $v_data['flag']; - $p_header['filename_len'] = $v_data['filename_len']; - - // ----- Recuperate date in UNIX format - $p_header['mdate'] = $v_data['mdate']; - $p_header['mtime'] = $v_data['mtime']; - if ($p_header['mdate'] && $p_header['mtime']) - { - // ----- Extract time - $v_hour = ($p_header['mtime'] & 0xF800) >> 11; - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; - $v_seconde = ($p_header['mtime'] & 0x001F)*2; - - // ----- Extract date - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; - $v_month = ($p_header['mdate'] & 0x01E0) >> 5; - $v_day = $p_header['mdate'] & 0x001F; - - // ----- Get UNIX date format - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); - - } - else - { - $p_header['mtime'] = time(); - } - - // TBC - //for(reset($v_data); $key = key($v_data); next($v_data)) { - //} - - // ----- Set the stored filename - $p_header['stored_filename'] = $p_header['filename']; - - // ----- Set the status field - $p_header['status'] = "ok"; - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privReadCentralFileHeader() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privReadCentralFileHeader(&$p_header) - { - $v_result=1; - - // ----- Read the 4 bytes signature - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = unpack('Vid', $v_binary_data); - - // ----- Check signature - if ($v_data['id'] != 0x02014b50) - { - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read the first 42 bytes of the header - $v_binary_data = fread($this->zip_fd, 42); - - // ----- Look for invalid block size - if (strlen($v_binary_data) != 42) - { - $p_header['filename'] = ""; - $p_header['status'] = "invalid_header"; - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Extract the values - $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); - - // ----- Get filename - if ($p_header['filename_len'] != 0) - $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); - else - $p_header['filename'] = ''; - - // ----- Get extra - if ($p_header['extra_len'] != 0) - $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); - else - $p_header['extra'] = ''; - - // ----- Get comment - if ($p_header['comment_len'] != 0) - $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); - else - $p_header['comment'] = ''; - - // ----- Extract properties - - // ----- Recuperate date in UNIX format - //if ($p_header['mdate'] && $p_header['mtime']) - // TBC : bug : this was ignoring time with 0/0/0 - if (1) - { - // ----- Extract time - $v_hour = ($p_header['mtime'] & 0xF800) >> 11; - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; - $v_seconde = ($p_header['mtime'] & 0x001F)*2; - - // ----- Extract date - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; - $v_month = ($p_header['mdate'] & 0x01E0) >> 5; - $v_day = $p_header['mdate'] & 0x001F; - - // ----- Get UNIX date format - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); - - } - else - { - $p_header['mtime'] = time(); - } - - // ----- Set the stored filename - $p_header['stored_filename'] = $p_header['filename']; - - // ----- Set default status to ok - $p_header['status'] = 'ok'; - - // ----- Look if it is a directory - if (substr($p_header['filename'], -1) == '/') { - //$p_header['external'] = 0x41FF0010; - $p_header['external'] = 0x00000010; - } - - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privCheckFileHeaders() - // Description : - // Parameters : - // Return Values : - // 1 on success, - // 0 on error; - // -------------------------------------------------------------------------------- - function privCheckFileHeaders(&$p_local_header, &$p_central_header) - { - $v_result=1; - - // ----- Check the static values - // TBC - if ($p_local_header['filename'] != $p_central_header['filename']) { - } - if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { - } - if ($p_local_header['flag'] != $p_central_header['flag']) { - } - if ($p_local_header['compression'] != $p_central_header['compression']) { - } - if ($p_local_header['mtime'] != $p_central_header['mtime']) { - } - if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { - } - - // ----- Look for flag bit 3 - if (($p_local_header['flag'] & 8) == 8) { - $p_local_header['size'] = $p_central_header['size']; - $p_local_header['compressed_size'] = $p_central_header['compressed_size']; - $p_local_header['crc'] = $p_central_header['crc']; - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privReadEndCentralDir() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privReadEndCentralDir(&$p_central_dir) - { - $v_result=1; - - // ----- Go to the end of the zip file - $v_size = filesize($this->zipname); - @fseek($this->zip_fd, $v_size); - if (@ftell($this->zip_fd) != $v_size) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- First try : look if this is an archive with no commentaries (most of the time) - // in this case the end of central dir is at 22 bytes of the file end - $v_found = 0; - if ($v_size > 26) { - @fseek($this->zip_fd, $v_size-22); - if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read for bytes - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = @unpack('Vid', $v_binary_data); - - // ----- Check signature - if ($v_data['id'] == 0x06054b50) { - $v_found = 1; - } - - $v_pos = ftell($this->zip_fd); - } - - // ----- Go back to the maximum possible size of the Central Dir End Record - if (!$v_found) { - $v_maximum_size = 65557; // 0xFFFF + 22; - if ($v_maximum_size > $v_size) - $v_maximum_size = $v_size; - @fseek($this->zip_fd, $v_size-$v_maximum_size); - if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read byte per byte in order to find the signature - $v_pos = ftell($this->zip_fd); - $v_bytes = 0x00000000; - while ($v_pos < $v_size) - { - // ----- Read a byte - $v_byte = @fread($this->zip_fd, 1); - - // ----- Add the byte - //$v_bytes = ($v_bytes << 8) | Ord($v_byte); - // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number - // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. - $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); - - // ----- Compare the bytes - if ($v_bytes == 0x504b0506) - { - $v_pos++; - break; - } - - $v_pos++; - } - - // ----- Look if not found end of central dir - if ($v_pos == $v_size) - { - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); - - // ----- Return - return PclZip::errorCode(); - } - } - - // ----- Read the first 18 bytes of the header - $v_binary_data = fread($this->zip_fd, 18); - - // ----- Look for invalid block size - if (strlen($v_binary_data) != 18) - { - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Extract the values - $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); - - // ----- Check the global size - if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { - - // ----- Removed in release 2.2 see readme file - // The check of the file size is a little too strict. - // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. - // While decrypted, zip has training 0 bytes - if (0) { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, - 'The central dir is not at the end of the archive.' - .' Some trailing bytes exists after the archive.'); - - // ----- Return - return PclZip::errorCode(); - } - } - - // ----- Get comment - if ($v_data['comment_size'] != 0) { - $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); - } - else - $p_central_dir['comment'] = ''; - - $p_central_dir['entries'] = $v_data['entries']; - $p_central_dir['disk_entries'] = $v_data['disk_entries']; - $p_central_dir['offset'] = $v_data['offset']; - $p_central_dir['size'] = $v_data['size']; - $p_central_dir['disk'] = $v_data['disk']; - $p_central_dir['disk_start'] = $v_data['disk_start']; - - // TBC - //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { - //} - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDeleteByRule() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privDeleteByRule(&$p_result_list, &$p_options) - { - $v_result=1; - $v_list_detail = array(); - - // ----- Open the zip file - if (($v_result=$this->privOpenFd('rb')) != 1) - { - // ----- Return - return $v_result; - } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); - return $v_result; - } - - // ----- Go to beginning of File - @rewind($this->zip_fd); - - // ----- Scan all the files - // ----- Start at beginning of Central Dir - $v_pos_entry = $v_central_dir['offset']; - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_pos_entry)) - { - // ----- Close the zip file - $this->privCloseFd(); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read each entry - $v_header_list = array(); - $j_start = 0; - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) - { - - // ----- Read the file header - $v_header_list[$v_nb_extracted] = array(); - if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) - { - // ----- Close the zip file - $this->privCloseFd(); - - return $v_result; - } - - - // ----- Store the index - $v_header_list[$v_nb_extracted]['index'] = $i; - - // ----- Look for the specific extract rules - $v_found = false; - - // ----- Look for extract by name rule - if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { - - // ----- Look if the filename is in the list - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { - - // ----- Look for a directory - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { - - // ----- Look if the directory is in the filename path - if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) - && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_found = true; - } - elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ - && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_found = true; - } - } - // ----- Look for a filename - elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { - $v_found = true; - } - } - } - - // ----- Look for extract by ereg rule - // ereg() is deprecated with PHP 5.3 - /* - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { - $v_found = true; - } - } - */ - - // ----- Look for extract by preg rule - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { - - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { - $v_found = true; - } - } - - // ----- Look for extract by index rule - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - - // ----- Look if the index is in the list - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { - - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_found = true; - } - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; - } - - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; - } - } - } - else { - $v_found = true; - } - - // ----- Look for deletion - if ($v_found) - { - unset($v_header_list[$v_nb_extracted]); - } - else - { - $v_nb_extracted++; - } - } - - // ----- Look if something need to be deleted - if ($v_nb_extracted > 0) { - - // ----- Creates a temporay file - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - - // ----- Creates a temporary zip archive - $v_temp_zip = new PclZip($v_zip_temp_name); - - // ----- Open the temporary zip file in write mode - if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { - $this->privCloseFd(); - - // ----- Return - return $v_result; - } - - // ----- Look which file need to be kept - for ($i=0; $i<sizeof($v_header_list); $i++) { - - // ----- Calculate the position of the header - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); - - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Read the file header - $v_local_header = array(); - if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); - - // ----- Return - return $v_result; - } - - // ----- Check that local file header is same as central file header - if ($this->privCheckFileHeaders($v_local_header, - $v_header_list[$i]) != 1) { - // TBC - } - unset($v_local_header); - - // ----- Write the file header - if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); - - // ----- Return - return $v_result; - } - - // ----- Read/write the data block - if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { - // ----- Close the zip file - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); - - // ----- Return - return $v_result; - } - } - - // ----- Store the offset of the central dir - $v_offset = @ftell($v_temp_zip->zip_fd); - - // ----- Re-Create the Central Dir files header - for ($i=0; $i<sizeof($v_header_list); $i++) { - // ----- Create the file header - if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($v_zip_temp_name); - - // ----- Return - return $v_result; - } - - // ----- Transform the header to a 'usable' info - $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } - - - // ----- Zip file comment - $v_comment = ''; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } - - // ----- Calculate the size of the central header - $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; - - // ----- Create the central dir footer - if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { - // ----- Reset the file list - unset($v_header_list); - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($v_zip_temp_name); - - // ----- Return - return $v_result; - } - - // ----- Close - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - - // ----- Delete the zip file - // TBC : I should test the result ... - @unlink($this->zipname); - - // ----- Rename the temporary file - // TBC : I should test the result ... - //@rename($v_zip_temp_name, $this->zipname); - PclZipUtilRename($v_zip_temp_name, $this->zipname); - - // ----- Destroy the temporary archive - unset($v_temp_zip); - } - - // ----- Remove every files : reset the file - else if ($v_central_dir['entries'] != 0) { - $this->privCloseFd(); - - if (($v_result = $this->privOpenFd('wb')) != 1) { - return $v_result; - } - - if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { - return $v_result; - } - - $this->privCloseFd(); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDirCheck() - // Description : - // Check if a directory exists, if not it creates it and all the parents directory - // which may be useful. - // Parameters : - // $p_dir : Directory path to check. - // Return Values : - // 1 : OK - // -1 : Unable to create directory - // -------------------------------------------------------------------------------- - function privDirCheck($p_dir, $p_is_dir=false) - { - $v_result = 1; - - - // ----- Remove the final '/' - if (($p_is_dir) && (substr($p_dir, -1)=='/')) - { - $p_dir = substr($p_dir, 0, strlen($p_dir)-1); - } - - // ----- Check the directory availability - if ((is_dir($p_dir)) || ($p_dir == "")) - { - return 1; - } - - // ----- Extract parent directory - $p_parent_dir = dirname($p_dir); - - // ----- Just a check - if ($p_parent_dir != $p_dir) - { - // ----- Look for parent directory - if ($p_parent_dir != "") - { - if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) - { - return $v_result; - } - } - } - - // ----- Create the directory - if (!@mkdir($p_dir, 0777)) - { - // ----- Error log - PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privMerge() - // Description : - // If $p_archive_to_add does not exist, the function exit with a success result. - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privMerge(&$p_archive_to_add) - { - $v_result=1; - - // ----- Look if the archive_to_add exists - if (!is_file($p_archive_to_add->zipname)) - { - - // ----- Nothing to merge, so merge is a success - $v_result = 1; - - // ----- Return - return $v_result; - } - - // ----- Look if the archive exists - if (!is_file($this->zipname)) - { - - // ----- Do a duplicate - $v_result = $this->privDuplicate($p_archive_to_add->zipname); - - // ----- Return - return $v_result; - } - - // ----- Open the zip file - if (($v_result=$this->privOpenFd('rb')) != 1) - { - // ----- Return - return $v_result; - } - - // ----- Read the central directory informations - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); - return $v_result; - } - - // ----- Go to beginning of File - @rewind($this->zip_fd); - - // ----- Open the archive_to_add file - if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) - { - $this->privCloseFd(); - - // ----- Return - return $v_result; - } - - // ----- Read the central directory informations - $v_central_dir_to_add = array(); - if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); - - return $v_result; - } - - // ----- Go to beginning of File - @rewind($p_archive_to_add->zip_fd); - - // ----- Creates a temporay file - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - - // ----- Open the temporary file in write mode - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Copy the files from the archive to the temporary file - // TBC : Here I should better append the file and go back to erase the central dir - $v_size = $v_central_dir['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Copy the files from the archive_to_add into the temporary file - $v_size = $v_central_dir_to_add['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Store the offset of the central dir - $v_offset = @ftell($v_zip_temp_fd); - - // ----- Copy the block of file headers from the old archive - $v_size = $v_central_dir['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Copy the block of file headers from the archive_to_add - $v_size = $v_central_dir_to_add['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Merge the file comments - $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; - - // ----- Calculate the size of the (new) central header - $v_size = @ftell($v_zip_temp_fd)-$v_offset; - - // ----- Swap the file descriptor - // Here is a trick : I swap the temporary fd with the zip fd, in order to use - // the following methods on the temporary fil and not the real archive fd - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - - // ----- Create the central dir footer - if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); - @fclose($v_zip_temp_fd); - $this->zip_fd = null; - - // ----- Reset the file list - unset($v_header_list); - - // ----- Return - return $v_result; - } - - // ----- Swap back the file descriptor - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - - // ----- Close - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); - - // ----- Close the temporary file - @fclose($v_zip_temp_fd); - - // ----- Delete the zip file - // TBC : I should test the result ... - @unlink($this->zipname); - - // ----- Rename the temporary file - // TBC : I should test the result ... - //@rename($v_zip_temp_name, $this->zipname); - PclZipUtilRename($v_zip_temp_name, $this->zipname); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDuplicate() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privDuplicate($p_archive_filename) - { - $v_result=1; - - // ----- Look if the $p_archive_filename exists - if (!is_file($p_archive_filename)) - { - - // ----- Nothing to duplicate, so duplicate is a success. - $v_result = 1; - - // ----- Return - return $v_result; - } - - // ----- Open the zip file - if (($v_result=$this->privOpenFd('wb')) != 1) - { - // ----- Return - return $v_result; - } - - // ----- Open the temporary file in write mode - if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) - { - $this->privCloseFd(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); - - // ----- Return - return PclZip::errorCode(); - } - - // ----- Copy the files from the archive to the temporary file - // TBC : Here I should better append the file and go back to erase the central dir - $v_size = filesize($p_archive_filename); - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($v_zip_temp_fd, $v_read_size); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - // ----- Close - $this->privCloseFd(); - - // ----- Close the temporary file - @fclose($v_zip_temp_fd); - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privErrorLog() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privErrorLog($p_error_code=0, $p_error_string='') - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - PclError($p_error_code, $p_error_string); - } - else { - $this->error_code = $p_error_code; - $this->error_string = $p_error_string; - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privErrorReset() - // Description : - // Parameters : - // -------------------------------------------------------------------------------- - function privErrorReset() - { - if (PCLZIP_ERROR_EXTERNAL == 1) { - PclErrorReset(); - } - else { - $this->error_code = 0; - $this->error_string = ''; - } - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privDisableMagicQuotes() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privDisableMagicQuotes() - { - $v_result=1; - - // ----- Look if function exists - if ( (!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { - return $v_result; - } - - // ----- Look if already done - if ($this->magic_quotes_status != -1) { - return $v_result; - } - - // ----- Get and memorize the magic_quote value - $this->magic_quotes_status = @get_magic_quotes_runtime(); - - // ----- Disable magic_quotes - if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime(0); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : privSwapBackMagicQuotes() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function privSwapBackMagicQuotes() - { - $v_result=1; - - // ----- Look if function exists - if ( (!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { - return $v_result; - } - - // ----- Look if something to do - if ($this->magic_quotes_status != -1) { - return $v_result; - } - - // ----- Swap back magic_quotes - if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime($this->magic_quotes_status); - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - } - // End of class - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilPathReduction() - // Description : - // Parameters : - // Return Values : - // -------------------------------------------------------------------------------- - function PclZipUtilPathReduction($p_dir) - { - $v_result = ""; - - // ----- Look for not empty path - if ($p_dir != "") { - // ----- Explode path by directory names - $v_list = explode("/", $p_dir); - - // ----- Study directories from last to first - $v_skip = 0; - for ($i=sizeof($v_list)-1; $i>=0; $i--) { - // ----- Look for current path - if ($v_list[$i] == ".") { - // ----- Ignore this directory - // Should be the first $i=0, but no check is done - } - else if ($v_list[$i] == "..") { - $v_skip++; - } - else if ($v_list[$i] == "") { - // ----- First '/' i.e. root slash - if ($i == 0) { - $v_result = "/".$v_result; - if ($v_skip > 0) { - // ----- It is an invalid path, so the path is not modified - // TBC - $v_result = $p_dir; - $v_skip = 0; - } - } - // ----- Last '/' i.e. indicates a directory - else if ($i == (sizeof($v_list)-1)) { - $v_result = $v_list[$i]; - } - // ----- Double '/' inside the path - else { - // ----- Ignore only the double '//' in path, - // but not the first and last '/' - } - } - else { - // ----- Look for item to skip - if ($v_skip > 0) { - $v_skip--; - } - else { - $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); - } - } - } - - // ----- Look for skip - if ($v_skip > 0) { - while ($v_skip > 0) { - $v_result = '../'.$v_result; - $v_skip--; - } - } - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilPathInclusion() - // Description : - // This function indicates if the path $p_path is under the $p_dir tree. Or, - // said in an other way, if the file or sub-dir $p_path is inside the dir - // $p_dir. - // The function indicates also if the path is exactly the same as the dir. - // This function supports path with duplicated '/' like '//', but does not - // support '.' or '..' statements. - // Parameters : - // Return Values : - // 0 if $p_path is not inside directory $p_dir - // 1 if $p_path is inside directory $p_dir - // 2 if $p_path is exactly the same as $p_dir - // -------------------------------------------------------------------------------- - function PclZipUtilPathInclusion($p_dir, $p_path) - { - $v_result = 1; - - // ----- Look for path beginning by ./ - if ( ($p_dir == '.') - || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { - $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); - } - if ( ($p_path == '.') - || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { - $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); - } - - // ----- Explode dir and path by directory separator - $v_list_dir = explode("/", $p_dir); - $v_list_dir_size = sizeof($v_list_dir); - $v_list_path = explode("/", $p_path); - $v_list_path_size = sizeof($v_list_path); - - // ----- Study directories paths - $i = 0; - $j = 0; - while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { - - // ----- Look for empty dir (path reduction) - if ($v_list_dir[$i] == '') { - $i++; - continue; - } - if ($v_list_path[$j] == '') { - $j++; - continue; - } - - // ----- Compare the items - if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { - $v_result = 0; - } - - // ----- Next items - $i++; - $j++; - } - - // ----- Look if everything seems to be the same - if ($v_result) { - // ----- Skip all the empty items - while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; - while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; - - if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { - // ----- There are exactly the same - $v_result = 2; - } - else if ($i < $v_list_dir_size) { - // ----- The path is shorter than the dir - $v_result = 0; - } - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilCopyBlock() - // Description : - // Parameters : - // $p_mode : read/write compression mode - // 0 : src & dest normal - // 1 : src gzip, dest normal - // 2 : src normal, dest gzip - // 3 : src & dest gzip - // Return Values : - // -------------------------------------------------------------------------------- - function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) - { - $v_result = 1; - - if ($p_mode==0) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_src, $v_read_size); - @fwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - else if ($p_mode==1) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($p_src, $v_read_size); - @fwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - else if ($p_mode==2) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_src, $v_read_size); - @gzwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - else if ($p_mode==3) - { - while ($p_size != 0) - { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($p_src, $v_read_size); - @gzwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; - } - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilRename() - // Description : - // This function tries to do a simple rename() function. If it fails, it - // tries to copy the $p_src file in a new $p_dest file and then unlink the - // first one. - // Parameters : - // $p_src : Old filename - // $p_dest : New filename - // Return Values : - // 1 on success, 0 on failure. - // -------------------------------------------------------------------------------- - function PclZipUtilRename($p_src, $p_dest) - { - $v_result = 1; - - // ----- Try to rename the files - if (!@rename($p_src, $p_dest)) { - - // ----- Try to copy & unlink the src - if (!@copy($p_src, $p_dest)) { - $v_result = 0; - } - else if (!@unlink($p_src)) { - $v_result = 0; - } - } - - // ----- Return - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilOptionText() - // Description : - // Translate option value in text. Mainly for debug purpose. - // Parameters : - // $p_option : the option value. - // Return Values : - // The option text value. - // -------------------------------------------------------------------------------- - function PclZipUtilOptionText($p_option) - { - - $v_list = get_defined_constants(); - for (reset($v_list); $v_key = key($v_list); next($v_list)) { - $v_prefix = substr($v_key, 0, 10); - if (( ($v_prefix == 'PCLZIP_OPT') - || ($v_prefix == 'PCLZIP_CB_') - || ($v_prefix == 'PCLZIP_ATT')) - && ($v_list[$v_key] == $p_option)) { - return $v_key; - } - } - - $v_result = 'Unknown'; - - return $v_result; - } - // -------------------------------------------------------------------------------- - - // -------------------------------------------------------------------------------- - // Function : PclZipUtilTranslateWinPath() - // Description : - // Translate windows path by replacing '\' by '/' and optionally removing - // drive letter. - // Parameters : - // $p_path : path to translate. - // $p_remove_disk_letter : true | false - // Return Values : - // The path translated. - // -------------------------------------------------------------------------------- - function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) - { - if (stristr(php_uname(), 'windows')) { - // ----- Look for potential disk letter - if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { - $p_path = substr($p_path, $v_position+1); - } - // ----- Change potential windows directory separator - if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { - $p_path = strtr($p_path, '\\', '/'); - } - } - return $p_path; - } - // -------------------------------------------------------------------------------- +<?php +// -------------------------------------------------------------------------------- +// PhpConcept Library - Zip Module 2.8.2 +// -------------------------------------------------------------------------------- +// License GNU/LGPL - Vincent Blavet - August 2009 +// http://www.phpconcept.net +// -------------------------------------------------------------------------------- +// +// Presentation : +// PclZip is a PHP library that manage ZIP archives. +// So far tests show that archives generated by PclZip are readable by +// WinZip application and other tools. +// +// Description : +// See readme.txt and http://www.phpconcept.net +// +// Warning : +// This library and the associated files are non commercial, non professional +// work. +// It should not have unexpected results. However if any damage is caused by +// this software the author can not be responsible. +// The use of this software is at the risk of the user. +// +// -------------------------------------------------------------------------------- +// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $ +// -------------------------------------------------------------------------------- + +// ----- Constants +if (!defined('PCLZIP_READ_BLOCK_SIZE')) { + define('PCLZIP_READ_BLOCK_SIZE', 2048); +} + +// ----- File list separator +// In version 1.x of PclZip, the separator for file list is a space +// (which is not a very smart choice, specifically for windows paths !). +// A better separator should be a comma (,). This constant gives you the +// abilty to change that. +// However notice that changing this value, may have impact on existing +// scripts, using space separated filenames. +// Recommanded values for compatibility with older versions : +//define('PCLZIP_SEPARATOR', ' '); +// Recommanded values for smart separation of filenames. +if (!defined('PCLZIP_SEPARATOR')) { + define('PCLZIP_SEPARATOR', ','); +} + +// ----- Error configuration +// 0 : PclZip Class integrated error handling +// 1 : PclError external library error handling. By enabling this +// you must ensure that you have included PclError library. +// [2,...] : reserved for futur use +if (!defined('PCLZIP_ERROR_EXTERNAL')) { + define('PCLZIP_ERROR_EXTERNAL', 0); +} + +// ----- Optional static temporary directory +// By default temporary files are generated in the script current +// path. +// If defined : +// - MUST BE terminated by a '/'. +// - MUST be a valid, already created directory +// Samples : +// define('PCLZIP_TEMPORARY_DIR', '/temp/'); +// define('PCLZIP_TEMPORARY_DIR', 'C:/Temp/'); +if (!defined('PCLZIP_TEMPORARY_DIR')) { + define('PCLZIP_TEMPORARY_DIR', ''); +} + +// ----- Optional threshold ratio for use of temporary files +// Pclzip sense the size of the file to add/extract and decide to +// use or not temporary file. The algorythm is looking for +// memory_limit of PHP and apply a ratio. +// threshold = memory_limit * ratio. +// Recommended values are under 0.5. Default 0.47. +// Samples : +// define('PCLZIP_TEMPORARY_FILE_RATIO', 0.5); +if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { + define('PCLZIP_TEMPORARY_FILE_RATIO', 0.47); +} + +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** +// -------------------------------------------------------------------------------- + +// ----- Global variables +$g_pclzip_version = "2.8.2"; + +// ----- Error codes +// -1 : Unable to open file in binary write mode +// -2 : Unable to open file in binary read mode +// -3 : Invalid parameters +// -4 : File does not exist +// -5 : Filename is too long (max. 255) +// -6 : Not a valid zip file +// -7 : Invalid extracted file size +// -8 : Unable to create directory +// -9 : Invalid archive extension +// -10 : Invalid archive format +// -11 : Unable to delete file (unlink) +// -12 : Unable to rename file (rename) +// -13 : Invalid header checksum +// -14 : Invalid archive size +define('PCLZIP_ERR_USER_ABORTED', 2); +define('PCLZIP_ERR_NO_ERROR', 0); +define('PCLZIP_ERR_WRITE_OPEN_FAIL', -1); +define('PCLZIP_ERR_READ_OPEN_FAIL', -2); +define('PCLZIP_ERR_INVALID_PARAMETER', -3); +define('PCLZIP_ERR_MISSING_FILE', -4); +define('PCLZIP_ERR_FILENAME_TOO_LONG', -5); +define('PCLZIP_ERR_INVALID_ZIP', -6); +define('PCLZIP_ERR_BAD_EXTRACTED_FILE', -7); +define('PCLZIP_ERR_DIR_CREATE_FAIL', -8); +define('PCLZIP_ERR_BAD_EXTENSION', -9); +define('PCLZIP_ERR_BAD_FORMAT', -10); +define('PCLZIP_ERR_DELETE_FILE_FAIL', -11); +define('PCLZIP_ERR_RENAME_FILE_FAIL', -12); +define('PCLZIP_ERR_BAD_CHECKSUM', -13); +define('PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14); +define('PCLZIP_ERR_MISSING_OPTION_VALUE', -15); +define('PCLZIP_ERR_INVALID_OPTION_VALUE', -16); +define('PCLZIP_ERR_ALREADY_A_DIRECTORY', -17); +define('PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18); +define('PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19); +define('PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20); +define('PCLZIP_ERR_DIRECTORY_RESTRICTION', -21); + +// ----- Options values +define('PCLZIP_OPT_PATH', 77001); +define('PCLZIP_OPT_ADD_PATH', 77002); +define('PCLZIP_OPT_REMOVE_PATH', 77003); +define('PCLZIP_OPT_REMOVE_ALL_PATH', 77004); +define('PCLZIP_OPT_SET_CHMOD', 77005); +define('PCLZIP_OPT_EXTRACT_AS_STRING', 77006); +define('PCLZIP_OPT_NO_COMPRESSION', 77007); +define('PCLZIP_OPT_BY_NAME', 77008); +define('PCLZIP_OPT_BY_INDEX', 77009); +define('PCLZIP_OPT_BY_EREG', 77010); +define('PCLZIP_OPT_BY_PREG', 77011); +define('PCLZIP_OPT_COMMENT', 77012); +define('PCLZIP_OPT_ADD_COMMENT', 77013); +define('PCLZIP_OPT_PREPEND_COMMENT', 77014); +define('PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015); +define('PCLZIP_OPT_REPLACE_NEWER', 77016); +define('PCLZIP_OPT_STOP_ON_ERROR', 77017); +// Having big trouble with crypt. Need to multiply 2 long int +// which is not correctly supported by PHP ... +//define('PCLZIP_OPT_CRYPT', 77018); +define('PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019); +define('PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020); +define('PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020); // alias +define('PCLZIP_OPT_TEMP_FILE_ON', 77021); +define('PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021); // alias +define('PCLZIP_OPT_TEMP_FILE_OFF', 77022); +define('PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022); // alias + +// ----- File description attributes +define('PCLZIP_ATT_FILE_NAME', 79001); +define('PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002); +define('PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003); +define('PCLZIP_ATT_FILE_MTIME', 79004); +define('PCLZIP_ATT_FILE_CONTENT', 79005); +define('PCLZIP_ATT_FILE_COMMENT', 79006); + +// ----- Call backs values +define('PCLZIP_CB_PRE_EXTRACT', 78001); +define('PCLZIP_CB_POST_EXTRACT', 78002); +define('PCLZIP_CB_PRE_ADD', 78003); +define('PCLZIP_CB_POST_ADD', 78004); +/* For futur use +define('PCLZIP_CB_PRE_LIST', 78005); +define('PCLZIP_CB_POST_LIST', 78006); +define('PCLZIP_CB_PRE_DELETE', 78007); +define('PCLZIP_CB_POST_DELETE', 78008); +*/ + +// -------------------------------------------------------------------------------- +// Class : PclZip +// Description : +// PclZip is the class that represent a Zip archive. +// The public methods allow the manipulation of the archive. +// Attributes : +// Attributes must not be accessed directly. +// Methods : +// PclZip() : Object creator +// create() : Creates the Zip archive +// listContent() : List the content of the Zip archive +// extract() : Extract the content of the archive +// properties() : List the properties of the archive +// -------------------------------------------------------------------------------- +class PclZip +{ + // ----- Filename of the zip file + var $zipname = ''; + + // ----- File descriptor of the zip file + var $zip_fd = 0; + + // ----- Internal error handling + var $error_code = 1; + var $error_string = ''; + + // ----- Current status of the magic_quotes_runtime + // This value store the php configuration for magic_quotes + // The class can then disable the magic_quotes and reset it after + var $magic_quotes_status; + + // -------------------------------------------------------------------------------- + // Function : PclZip() + // Description : + // Creates a PclZip object and set the name of the associated Zip archive + // filename. + // Note that no real action is taken, if the archive does not exist it is not + // created. Use create() for that. + // -------------------------------------------------------------------------------- + function PclZip($p_zipname) + { + + // ----- Tests the zlib + if (!function_exists('gzopen')) { + die('Abort '.basename(__FILE__).' : Missing zlib extensions'); + } + + // ----- Set the attributes + $this->zipname = $p_zipname; + $this->zip_fd = 0; + $this->magic_quotes_status = -1; + + // ----- Return + return; + } + + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // create($p_filelist, $p_add_dir="", $p_remove_dir="") + // create($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two different synopsis. The first one is historical. + // This method creates a Zip Archive. The Zip file is created in the + // filesystem. The files and directories indicated in $p_filelist + // are added in the archive. See the parameters description for the + // supported format of $p_filelist. + // When a directory is in the list, the directory and its content is added + // in the archive. + // In this synopsis, the function takes an optional variable list of + // options. See bellow the supported options. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function create($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove from the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' +)); + if ($v_result != 1) { + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Invalid number / type of arguments"); + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + else { + } + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array (PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' +); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // add($p_filelist, $p_add_dir="", $p_remove_dir="") + // add($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two synopsis. The first one is historical. + // This methods add the list of files in an existing archive. + // If a file with the same name already exists, it is added at the end of the + // archive, the first one is still present. + // If the archive does not exist, it is created. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_OPT_ADD_COMMENT : + // PCLZIP_OPT_PREPEND_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function add($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' +)); + if ($v_result != 1) { + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array (PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' +); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : listContent() + // Description : + // This public method, gives the list of the files and directories, with their + // properties. + // The properties of each entries in the list are (used also in other functions) : + // filename : Name of the file. For a create or add action it is the filename + // given by the user. For an extract function it is the filename + // of the extracted file. + // stored_filename : Name of the file / directory stored in the archive. + // size : Size of the stored file. + // compressed_size : Size of the file's data compressed in the archive + // (without the headers overhead) + // mtime : Last known modification date of the file (UNIX timestamp) + // comment : Comment associated with the file + // folder : true | false + // index : index of the file in the archive + // status : status of the action (depending of the action) : + // Values are : + // ok : OK ! + // filtered : the file / dir is not extracted (filtered by user) + // already_a_directory : the file can not be extracted because a + // directory with the same name already exists + // write_protected : the file can not be extracted because a file + // with the same name already exists and is + // write protected + // newer_exist : the file was not extracted because a newer file exists + // path_creation_fail : the file is not extracted because the folder + // does not exist and can not be created + // write_error : the file was not extracted because there was a + // error while writing the file + // read_error : the file was not extracted because there was a error + // while reading the file + // invalid_header : the file was not extracted because of an archive + // format error (bad file header) + // Note that each time a method can continue operating when there + // is an action error on a file, the error is only logged in the file status. + // Return Values : + // 0 on an unrecoverable failure, + // The list of the files in the archive. + // -------------------------------------------------------------------------------- + function listContent() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Call the extracting fct + $p_list = array(); + if (($v_result = $this->privList($p_list)) != 1) + { + unset($p_list); + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // extract($p_path="./", $p_remove_path="") + // extract([$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method extract all the files / directories from the archive to the + // folder indicated in $p_path. + // If you want to ignore the 'root' part of path of the memorized files + // you can indicate this in the optional $p_remove_path parameter. + // By default, if a newer file with the same name already exists, the + // file is not extracted. + // + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append + // at the end of the path value of PCLZIP_OPT_PATH. + // Parameters : + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 or a negative value on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function extract() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' +)); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Trace + + // ----- Call the extracting fct + $p_list = array(); + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, + $v_remove_all_path, $v_options); + if ($v_result < 1) { + unset($p_list); + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : + // extractByIndex($p_index, $p_path="./", $p_remove_path="") + // extractByIndex($p_index, [$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method is doing a partial extract of the archive. + // The extracted files or folders are identified by their index in the + // archive (from 0 to n). + // Note that if the index identify a folder, only the folder entry is + // extracted, not all the files included in the archive. + // Parameters : + // $p_index : A single index (integer) or a string of indexes of files to + // extract. The form of the string is "0,4-6,8-12" with only numbers + // and '-' for range or ',' to separate ranges. No spaces or ';' + // are allowed. + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and + // not as files. + // The resulting content is in a new field 'content' in the file + // structure. + // This option must be used alone (any other options are ignored). + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + //function extractByIndex($p_index, options...) + function extractByIndex($p_index) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' +)); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + } + else { + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Trace + + // ----- Trick + // Here I want to reuse extractByRule(), so I need to parse the $p_index + // with privParseOptions() + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); + $v_options_trick = array(); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, + array (PCLZIP_OPT_BY_INDEX => 'optional')); + if ($v_result != 1) { + return 0; + } + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Call the extracting fct + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // delete([$p_option, $p_option_value, ...]) + // Description : + // This method removes files from the archive. + // If no parameters are given, then all the archive is emptied. + // Parameters : + // None or optional arguments. + // Options : + // PCLZIP_OPT_BY_INDEX : + // PCLZIP_OPT_BY_NAME : + // PCLZIP_OPT_BY_EREG : + // PCLZIP_OPT_BY_PREG : + // Return Values : + // 0 on failure, + // The list of the files which are still present in the archive. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function delete() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional')); + if ($v_result != 1) { + return 0; + } + } + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Call the delete fct + $v_list = array(); + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); + return(0); + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : deleteByIndex() + // Description : + // ***** Deprecated ***** + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. + // -------------------------------------------------------------------------------- + function deleteByIndex($p_index) + { + + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : properties() + // Description : + // This method gives the properties of the archive. + // The properties are : + // nb : Number of files in the archive + // comment : Comment associated with the archive file + // status : not_exist, ok + // Parameters : + // None + // Return Values : + // 0 on failure, + // An array with the archive properties. + // -------------------------------------------------------------------------------- + function properties() + { + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + return(0); + } + + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; + + // ----- Look if file exists + if (@is_file($this->zipname)) + { + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + return 0; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return 0; + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_prop; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : duplicate() + // Description : + // This method creates an archive by copying the content of an other one. If + // the archive already exist, it is replaced by the new one without any warning. + // Parameters : + // $p_archive : The filename of a valid archive, or + // a valid PclZip object. + // Return Values : + // 1 on success. + // 0 or a negative value on error (error code). + // -------------------------------------------------------------------------------- + function duplicate($p_archive) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the $p_archive is a PclZip object + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) + { + + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); + } + + // ----- Look if the $p_archive is a string (so a filename) + else if (is_string($p_archive)) + { + + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } + else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : merge() + // Description : + // This method merge the $p_archive_to_add archive at the end of the current + // one ($this). + // If the archive ($this) does not exist, the merge becomes a duplicate. + // If the $p_archive_to_add archive does not exist, the merge is a success. + // Parameters : + // $p_archive_to_add : It can be directly the filename of a valid zip archive, + // or a PclZip object archive. + // Return Values : + // 1 on success, + // 0 or negative values on error (see below). + // -------------------------------------------------------------------------------- + function merge($p_archive_to_add) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Look if the $p_archive_to_add is a PclZip object + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) + { + + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); + } + + // ----- Look if the $p_archive_to_add is a string (so a filename) + else if (is_string($p_archive_to_add)) + { + + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : errorCode() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorCode() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorCode()); + } + else { + return($this->error_code); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorName() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorName($p_with_code=false) + { + $v_name = array (PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' +); + + if (isset($v_name[$this->error_code])) { + $v_value = $v_name[$this->error_code]; + } + else { + $v_value = 'NoName'; + } + + if ($p_with_code) { + return($v_value.' ('.$this->error_code.')'); + } + else { + return($v_value); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorInfo() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorInfo($p_full=false) + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorString()); + } + else { + if ($p_full) { + return($this->errorName(true)." : ".$this->error_string); + } + else { + return($this->error_string." [code ".$this->error_code."]"); + } + } + } + // -------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** +// ***** ***** +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** +// -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : privCheckFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // -------------------------------------------------------------------------------- + function privCheckFormat($p_level=0) + { + $v_result = true; + + // ----- Reset the file system cache + clearstatcache(); + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the file exits + if (!is_file($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); + return(false); + } + + // ----- Check that the file is readeable + if (!is_readable($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); + return(false); + } + + // ----- Check the magic code + // TBC + + // ----- Check the central header + // TBC + + // ----- Check each file header + // TBC + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privParseOptions() + // Description : + // This internal methods reads the variable list of arguments ($p_options_list, + // $p_size) and generate an array with the options and values ($v_result_list). + // $v_requested_options contains the options that can be present and those that + // must be present. + // $v_requested_options is an array, with the option value as key, and 'optional', + // or 'mandatory' as value. + // Parameters : + // See above. + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) + { + $v_result=1; + + // ----- Read the options + $i=0; + while ($i<$p_size) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$p_options_list[$i]])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for next option + switch ($p_options_list[$i]) { + // ----- Look for options that request a path value + case PCLZIP_OPT_PATH : + case PCLZIP_OPT_REMOVE_PATH : + case PCLZIP_OPT_ADD_PATH : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_THRESHOLD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + // ----- Check the value + $v_value = $p_options_list[$i+1]; + if ((!is_integer($v_value)) || ($v_value<0)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Get the value (and convert it in bytes) + $v_result_list[$p_options_list[$i]] = $v_value*1048576; + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_ON : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_TEMP_FILE_OFF : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); + return PclZip::errorCode(); + } + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1]) + && ($p_options_list[$i+1] != '')) { + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + } + else { + } + break; + + // ----- Look for options that request an array of string for value + case PCLZIP_OPT_BY_NAME : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an EREG or PREG expression + case PCLZIP_OPT_BY_EREG : + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG + // to PCLZIP_OPT_BY_PREG + $p_options_list[$i] = PCLZIP_OPT_BY_PREG; + case PCLZIP_OPT_BY_PREG : + //case PCLZIP_OPT_CRYPT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that takes a string + case PCLZIP_OPT_COMMENT : + case PCLZIP_OPT_ADD_COMMENT : + case PCLZIP_OPT_PREPEND_COMMENT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, + "Missing parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, + "Wrong parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an array of index + case PCLZIP_OPT_BY_INDEX : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_work_list = array(); + if (is_string($p_options_list[$i+1])) { + + // ----- Remove spaces + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); + + // ----- Parse items + $v_work_list = explode(",", $p_options_list[$i+1]); + } + else if (is_integer($p_options_list[$i+1])) { + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_work_list = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Reduce the index list + // each index item in the list must be a couple with a start and + // an end value : [0,3], [5-5], [8-10], ... + // ----- Check the format of each item + $v_sort_flag=false; + $v_sort_value=0; + for ($j=0; $j<sizeof($v_work_list); $j++) { + // ----- Explode the item + $v_item_list = explode("-", $v_work_list[$j]); + $v_size_item_list = sizeof($v_item_list); + + // ----- TBC : Here we might check that each item is a + // real integer ... + + // ----- Look for single value + if ($v_size_item_list == 1) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; + } + elseif ($v_size_item_list == 2) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + + // ----- Look for list sort + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { + $v_sort_flag=true; + + // ----- TBC : An automatic sort should be writen ... + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; + } + + // ----- Sort the items + if ($v_sort_flag) { + // TBC : To Be Completed + } + + // ----- Next option + $i++; + break; + + // ----- Look for options that request no value + case PCLZIP_OPT_REMOVE_ALL_PATH : + case PCLZIP_OPT_EXTRACT_AS_STRING : + case PCLZIP_OPT_NO_COMPRESSION : + case PCLZIP_OPT_EXTRACT_IN_OUTPUT : + case PCLZIP_OPT_REPLACE_NEWER : + case PCLZIP_OPT_STOP_ON_ERROR : + $v_result_list[$p_options_list[$i]] = true; + break; + + // ----- Look for options that request an octal value + case PCLZIP_OPT_SET_CHMOD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + $i++; + break; + + // ----- Look for options that request a call-back + case PCLZIP_CB_PRE_EXTRACT : + case PCLZIP_CB_POST_EXTRACT : + case PCLZIP_CB_PRE_ADD : + case PCLZIP_CB_POST_ADD : + /* for futur use + case PCLZIP_CB_PRE_DELETE : + case PCLZIP_CB_POST_DELETE : + case PCLZIP_CB_PRE_LIST : + case PCLZIP_CB_POST_LIST : + */ + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_function_name = $p_options_list[$i+1]; + + // ----- Check that the value is a valid existing function + if (!function_exists($v_function_name)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Set the attribute + $v_result_list[$p_options_list[$i]] = $v_function_name; + $i++; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '" + .$p_options_list[$i]."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Next options + $i++; + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($v_result_list[$key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + + // ----- Return + return PclZip::errorCode(); + } + } + } + } + + // ----- Look for default values + if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOptionDefaultThreshold() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privOptionDefaultThreshold(&$p_options) + { + $v_result=1; + + if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { + return $v_result; + } + + // ----- Get 'memory_limit' configuration value + $v_memory_limit = ini_get('memory_limit'); + $v_memory_limit = trim($v_memory_limit); + $last = strtolower(substr($v_memory_limit, -1)); + + if ($last == 'g') + //$v_memory_limit = $v_memory_limit*1024*1024*1024; + $v_memory_limit = $v_memory_limit*1073741824; + if ($last == 'm') + //$v_memory_limit = $v_memory_limit*1024*1024; + $v_memory_limit = $v_memory_limit*1048576; + if ($last == 'k') + $v_memory_limit = $v_memory_limit*1024; + + $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); + + + // ----- Sanity check : No threshold if value lower than 1M + if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { + unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrParseAtt() + // Description : + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) + { + $v_result=1; + + // ----- For each file in the list check the attributes + foreach ($p_file_list as $v_key => $v_value) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$v_key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for attribute + switch ($v_key) { + case PCLZIP_ATT_FILE_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['filename'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + break; + + case PCLZIP_ATT_FILE_NEW_SHORT_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_short_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + + case PCLZIP_ATT_FILE_NEW_FULL_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_full_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + + // ----- Look for options that takes a string + case PCLZIP_ATT_FILE_COMMENT : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['comment'] = $v_value; + break; + + case PCLZIP_ATT_FILE_MTIME : + if (!is_integer($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['mtime'] = $v_value; + break; + + case PCLZIP_ATT_FILE_CONTENT : + $p_filedescr['content'] = $v_value; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '".$v_key."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($p_file_list[$key])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + return PclZip::errorCode(); + } + } + } + } + + // end foreach + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrExpand() + // Description : + // This method look for each item of the list to see if its a file, a folder + // or a string to be added as file. For any other type of files (link, other) + // just ignore the item. + // Then prepare the information that will be stored for that file. + // When its a folder, expand the folder with all the files that are in that + // folder (recursively). + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrExpand(&$p_filedescr_list, &$p_options) + { + $v_result=1; + + // ----- Create a result list + $v_result_list = array(); + + // ----- Look each entry + for ($i=0; $i<sizeof($p_filedescr_list); $i++) { + + // ----- Get filedescr + $v_descr = $p_filedescr_list[$i]; + + // ----- Reduce the filename + $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); + $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); + + // ----- Look for real file or folder + if (file_exists($v_descr['filename'])) { + if (@is_file($v_descr['filename'])) { + $v_descr['type'] = 'file'; + } + else if (@is_dir($v_descr['filename'])) { + $v_descr['type'] = 'folder'; + } + else if (@is_link($v_descr['filename'])) { + // skip + continue; + } + else { + // skip + continue; + } + } + + // ----- Look for string added as file + else if (isset($v_descr['content'])) { + $v_descr['type'] = 'virtual_file'; + } + + // ----- Missing file + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Calculate the stored filename + $this->privCalculateStoredFilename($v_descr, $p_options); + + // ----- Add the descriptor in result list + $v_result_list[sizeof($v_result_list)] = $v_descr; + + // ----- Look for folder + if ($v_descr['type'] == 'folder') { + // ----- List of items in folder + $v_dirlist_descr = array(); + $v_dirlist_nb = 0; + if ($v_folder_handler = @opendir($v_descr['filename'])) { + while (($v_item_handler = @readdir($v_folder_handler)) !== false) { + + // ----- Skip '.' and '..' + if (($v_item_handler == '.') || ($v_item_handler == '..')) { + continue; + } + + // ----- Compose the full filename + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; + + // ----- Look for different stored filename + // Because the name of the folder was changed, the name of the + // files/sub-folders also change + if (($v_descr['stored_filename'] != $v_descr['filename']) + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { + if ($v_descr['stored_filename'] != '') { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; + } + else { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; + } + } + + $v_dirlist_nb++; + } + + @closedir($v_folder_handler); + } + else { + // TBC : unable to open folder in read mode + } + + // ----- Expand each element of the list + if ($v_dirlist_nb != 0) { + // ----- Expand + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { + return $v_result; + } + + // ----- Concat the resulting list + $v_result_list = array_merge($v_result_list, $v_dirlist_descr); + } + else { + } + + // ----- Free local array + unset($v_dirlist_descr); + } + } + + // ----- Get the result list + $p_filedescr_list = $v_result_list; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCreate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCreate($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the file in write mode + if (($v_result = $this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Add the list of files + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); + + // ----- Close + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAdd() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAdd($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Look if the archive exists or is empty + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) + { + + // ----- Do a create + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); + + // ----- Return + return $v_result; + } + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) + { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = $v_central_dir['comment']; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOpenFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privOpenFd($p_mode) + { + $v_result=1; + + // ----- Look if already open + if ($this->zip_fd != 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCloseFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privCloseFd() + { + $v_result=1; + + if ($this->zip_fd != 0) + @fclose($this->zip_fd); + $this->zip_fd = 0; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // -------------------------------------------------------------------------------- +// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) + function privAddList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) + { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileList() + // Description : + // Parameters : + // $p_filedescr_list : An array containing the file description + // or directory names to add in the zip + // $p_result_list : list of added files with their properties (specially the status field) + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_header = array(); + + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); + + // ----- Loop on the files + for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { + // ----- Format the filename + $p_filedescr_list[$j]['filename'] + = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); + + + // ----- Skip empty file names + // TBC : Can this be possible ? not checked in DescrParseAtt ? + if ($p_filedescr_list[$j]['filename'] == "") { + continue; + } + + // ----- Check the filename + if (($p_filedescr_list[$j]['type'] != 'virtual_file') + && (!file_exists($p_filedescr_list[$j]['filename']))) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); + return PclZip::errorCode(); + } + + // ----- Look if it is a file or a dir with no all path remove option + // or a dir with all its path removed +// if ((is_file($p_filedescr_list[$j]['filename'])) +// || (is_dir($p_filedescr_list[$j]['filename']) + if (($p_filedescr_list[$j]['type'] == 'file') + || ($p_filedescr_list[$j]['type'] == 'virtual_file') + || (($p_filedescr_list[$j]['type'] == 'folder') + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) + || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) +) { + + // ----- Add the file + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, + $p_options); + if ($v_result != 1) { + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=1; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + // TBC : Already done in the fileAtt check ... ? + if ($p_filename == "") { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for a stored different filename + /* TBC : Removed + if (isset($p_filedescr['stored_filename'])) { + $v_stored_filename = $p_filedescr['stored_filename']; + } + else { + $v_stored_filename = $p_filedescr['stored_filename']; + } + */ + + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; +// TBC : Removed $p_header['stored_filename'] = $v_stored_filename; + $p_header['stored_filename'] = $p_filedescr['stored_filename']; + $p_header['extra'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; + + // ----- Look for regular file + if ($p_filedescr['type']=='file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for regular folder + else if ($p_filedescr['type']=='folder') { + $p_header['external'] = 0x00000010; + $p_header['mtime'] = filemtime($p_filename); + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for virtual file + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = strlen($p_filedescr['content']); + } + + + // ----- Look for filetime + if (isset($p_filedescr['mtime'])) { + $p_header['mtime'] = $p_filedescr['mtime']; + } + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['mtime'] = time(); + } + else { + $p_header['mtime'] = filemtime($p_filename); + } + + // ------ Look for file comment + if (isset($p_filedescr['comment'])) { + $p_header['comment_len'] = strlen($p_filedescr['comment']); + $p_header['comment'] = $p_filedescr['comment']; + } + else { + $p_header['comment_len'] = 0; + $p_header['comment'] = ''; + } + + // ----- Look for pre-add callback + if (isset($p_options[PCLZIP_CB_PRE_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; + } + + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); + } + } + + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } + + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; + } + + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { + + // ----- Look for a file + if ($p_filedescr['type'] == 'file') { + // ----- Look for using temporary file to zip + if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])))) { + $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } + + // ----- Use "in memory" zip algo + else { + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); + + // ----- Close the file + @fclose($v_file); + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + + } + + } + + // ----- Look for a virtual file (a file from string) + else if ($p_filedescr['type'] == 'virtual_file') { + + $v_content = $p_filedescr['content']; + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + } + + // ----- Look for a directory + else if ($p_filedescr['type'] == 'folder') { + // ----- Look for directory last '/' + if (@substr($p_header['stored_filename'], -1) != '/') { + $p_header['stored_filename'] .= '/'; + } + + // ----- Set the file properties + $p_header['size'] = 0; + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + $p_header['external'] = 0x00000010; // Value for a folder : to be checked + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) + { + return $v_result; + } + } + } + + // ----- Look for post-add callback + if (isset($p_options[PCLZIP_CB_POST_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; + } + + // ----- Update the informations + // Nothing can be modified + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=PCLZIP_ERR_NO_ERROR; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Creates a compressed temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = filesize($p_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @gzputs($v_file_compressed, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file); + @gzclose($v_file_compressed); + + // ----- Check the minimum file size + if (filesize($v_gzip_temp_name) < 18) { + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); + return PclZip::errorCode(); + } + + // ----- Extract the compressed attributes + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the gzip file header + $v_binary_data = @fread($v_file_compressed, 10); + $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); + + // ----- Check some parameters + $v_data_header['os'] = bin2hex($v_data_header['os']); + + // ----- Read the gzip file footer + @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); + $v_binary_data = @fread($v_file_compressed, 8); + $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); + + // ----- Set the attributes + $p_header['compression'] = ord($v_data_header['cm']); + //$p_header['mtime'] = $v_data_header['mtime']; + $p_header['crc'] = $v_data_footer['crc']; + $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + return $v_result; + } + + // ----- Add the compressed data + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) + { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + fseek($v_file_compressed, 10); + $v_size = $p_header['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file_compressed, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Unlink the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCalculateStoredFilename() + // Description : + // Based on file descriptor properties and global options, this method + // calculate the filename that will be stored in the archive. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCalculateStoredFilename(&$p_filedescr, &$p_options) + { + $v_result=1; + + // ----- Working variables + $p_filename = $p_filedescr['filename']; + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; + } + else { + $p_add_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; + } + else { + $p_remove_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + else { + $p_remove_all_dir = 0; + } + + + // ----- Look for full name change + if (isset($p_filedescr['new_full_name'])) { + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); + } + + // ----- Look for path and/or short name change + else { + + // ----- Look for short name change + // Its when we cahnge just the filename but not the path + if (isset($p_filedescr['new_short_name'])) { + $v_path_info = pathinfo($p_filename); + $v_dir = ''; + if ($v_path_info['dirname'] != '') { + $v_dir = $v_path_info['dirname'].'/'; + } + $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; + } + else { + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + } + + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + } + // ----- Look for partial path remove + else if ($p_remove_dir != "") { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + + if ((substr($p_filename, 0, 2) == "./") + || (substr($p_remove_dir, 0, 2) == "./")) { + + if ((substr($p_filename, 0, 2) == "./") + && (substr($p_remove_dir, 0, 2) != "./")) { + $p_remove_dir = "./".$p_remove_dir; + } + if ((substr($p_filename, 0, 2) != "./") + && (substr($p_remove_dir, 0, 2) == "./")) { + $p_remove_dir = substr($p_remove_dir, 2); + } + } + + $v_compare = PclZipUtilPathInclusion($p_remove_dir, + $v_stored_filename); + if ($v_compare > 0) { + if ($v_compare == 2) { + $v_stored_filename = ""; + } + else { + $v_stored_filename = substr($v_stored_filename, + strlen($p_remove_dir)); + } + } + } + + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); + + // ----- Look for path to add + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } + } + + // ----- Filename (reduce the path of stored name) + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); + $p_filedescr['stored_filename'] = $v_stored_filename; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteFileHeader(&$p_header) + { + $v_result=1; + + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->zip_fd); + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, + $p_header['version_extracted'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], + $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len']); + + // ----- Write the first 148 bytes of the header in the archive + fputs($this->zip_fd, $v_binary_data, 30); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralFileHeader(&$p_header) + { + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, + $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], + $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], + $p_header['external'], $p_header['offset']); + + // ----- Write the 42 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 46); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) + { + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) + { + $v_result=1; + + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, + $p_nb_entries, $p_size, + $p_offset, strlen($p_comment)); + + // ----- Write the 22 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 22); + + // ----- Write the variable fields + if (strlen($p_comment) != 0) + { + fputs($this->zip_fd, $p_comment, strlen($p_comment)); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privList() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privList(&$p_list) + { + $v_result=1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of Central Dir + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_central_dir['offset'])) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read each entry + for ($i=0; $i<$v_central_dir['entries']; $i++) + { + // ----- Read the file header + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + $v_header['index'] = $i; + + // ----- Get the only interesting attributes + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privConvertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // $p_info['crc'] = CRC of the file content. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privConvertHeader2FileInfo($p_header, &$p_info) + { + $v_result=1; + + // ----- Get the interesting attributes + $v_temp_path = PclZipUtilPathReduction($p_header['filename']); + $p_info['filename'] = $v_temp_path; + $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); + $p_info['stored_filename'] = $v_temp_path; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + $p_info['crc'] = $p_header['crc']; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // -------------------------------------------------------------------------------- + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check the path + if (($p_path == "") + || ((substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") + && (substr($p_path,1,2)!=":/"))) + $p_path = "./".$p_path; + + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) + { + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") + { + $p_path = substr($p_path, 0, strlen($p_path)-1); + } + } + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) + { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); + + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + + // ----- Read each entry + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + + // ----- Read next Central dir entry + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Store the index + $v_header['index'] = $i; + + // ----- Store the file position + $v_pos_entry = ftell($this->zip_fd); + + // ----- Look for the specific extract rules + $v_extract = false; + + // ----- Look for extract by name rule + if ((isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + + // ----- Look if the directory is in the filename path + if ((strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_extract = true; + } + } + // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_extract = true; + } + } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ((isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + */ + + // ----- Look for extract by preg rule + else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + + // ----- Look for extract by index rule + else if ((isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { + + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + + // ----- Look for no rule, which means extract all the archive + else { + $v_extract = true; + } + + // ----- Check compression method + if (($v_extract) + && (($v_header['compression'] != 8) + && ($v_header['compression'] != 0))) { + $v_header['status'] = 'unsupported_compression'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, + "Filename '".$v_header['stored_filename']."' is " + ."compressed by an unsupported compression " + ."method (".$v_header['compression'].") "); + + return PclZip::errorCode(); + } + } + + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + $v_header['status'] = 'unsupported_encryption'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, + "Unsupported encryption for " + ." filename '".$v_header['stored_filename'] + ."'"); + + return PclZip::errorCode(); + } + } + + // ----- Look for real extraction + if (($v_extract) && ($v_header['status'] != 'ok')) { + $v_result = $this->privConvertHeader2FileInfo($v_header, + $p_file_list[$v_nb_extracted++]); + if ($v_result != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + $v_extract = false; + } + + // ----- Look for real extraction + if ($v_extract) + { + + // ----- Go to the file position + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header['offset'])) + { + // ----- Close the zip file + $this->privCloseFd(); + + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for extraction as string + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { + + $v_string = ''; + + // ----- Extracting the file + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; + + // ----- Next extracted file + $v_nb_extracted++; + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for extraction in standard output + elseif ((isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Extracting the file in standard output + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for normal extraction + else { + // ----- Extracting the file + $v_result1 = $this->privExtractFile($v_header, + $p_path, $p_remove_path, + $p_remove_all_path, + $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + } + } + + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFile() + // Description : + // Parameters : + // Return Values : + // + // 1 : ... ? + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback + // -------------------------------------------------------------------------------- + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Look for folder entry that not need to be extracted + if (($p_entry['external']&0x00000010)==0x00000010) { + + $p_entry['status'] = "filtered"; + + return $v_result; + } + + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); + } + + // ----- Look for path to remove + else if ($p_remove_path != "") + { + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) + { + + // ----- Change the file status + $p_entry['status'] = "filtered"; + + // ----- Return + return $v_result; + } + + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + { + + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + + } + } + + // ----- Add the path + if ($p_path != '') { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; + } + + // ----- Check a base_dir_restriction + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { + $v_inclusion + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], + $p_entry['filename']); + if ($v_inclusion == 0) { + + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, + "Filename '".$p_entry['filename']."' is " + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + + return PclZip::errorCode(); + } + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) + { + + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, + "Filename '".$p_entry['filename']."' is " + ."already used by an existing directory"); + + return PclZip::errorCode(); + } + } + // ----- Look if file is write protected + else if (!is_writeable($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "write_protected"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Filename '".$p_entry['filename']."' exists " + ."and is write protected"); + + return PclZip::errorCode(); + } + } + + // ----- Look if the extracted file is older + else if (filemtime($p_entry['filename']) > $p_entry['mtime']) + { + // ----- Change the file status + if ((isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + } + else { + $p_entry['status'] = "newer_exist"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Newer version of '".$p_entry['filename']."' exists " + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + + return PclZip::errorCode(); + } + } + } + else { + } + } + + // ----- Check the directory availability and create it if necessary + else { + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + else if (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); + + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + //return $v_result; + $v_result = 1; + } + } + } + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file + if ($p_entry['compression'] == 0) { + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) + { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + // ----- Return + return $v_result; + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + /* Try to speed up the code + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + */ + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Closing the destination file + fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + + + } + else { + // ----- TBC + // Need to be finished + if (($p_entry['flag'] & 1) == 1) { + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); + return PclZip::errorCode(); + } + + + // ----- Look for using temporary file to unzip + if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])))) { + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } + + // ----- Look for extract in memory + else { + + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = @gzinflate($v_buffer); + unset($v_buffer); + if ($v_file_content === FALSE) { + + // ----- Change the file status + // TBC + $p_entry['status'] = "error"; + + return $v_result; + } + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + + } + + // ----- Change the file mtime + @touch($p_entry['filename'], $p_entry['mtime']); + } + + // ----- Look for chmod option + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { + + // ----- Change the mode of the file + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + } + + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileUsingTempFile(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Creates a temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + + + // ----- Write gz file format header + $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); + @fwrite($v_dest_file, $v_binary_data, 10); + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Write gz file format footer + $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); + @fwrite($v_dest_file, $v_binary_data, 8); + + // ----- Close the temporary file + @fclose($v_dest_file); + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + $p_entry['status'] = "write_error"; + return $v_result; + } + + // ----- Open the temporary gz file + if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { + @fclose($v_dest_file); + $p_entry['status'] = "read_error"; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($v_src_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + @fclose($v_dest_file); + @gzclose($v_src_file); + + // ----- Delete the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileInOutput() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileInOutput(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + // ----- Trace + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) { + + // ----- Read the file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Send the file to the output + echo $v_buffer; + unset($v_buffer); + } + else { + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); + + // ----- Send the file to the output + echo $v_file_content; + unset($v_file_content); + } + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileAsString() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) + { + $v_result=1; + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + // if ($p_entry['compressed_size'] == $p_entry['size']) + if ($p_entry['compression'] == 0) { + + // ----- Reading the file + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + } + else { + + // ----- Reading the file + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + if (($p_string = @gzinflate($v_data)) === FALSE) { + // TBC + } + } + + // ----- Trace + } + else { + // TBC : error : can not extract a folder in a string + } + + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Swap the content to header + $v_local_header['content'] = $p_string; + $p_string = ''; + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Swap back the content to header + $p_string = $v_local_header['content']; + unset($v_local_header['content']); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x04034b50) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 26); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + + // ----- Get filename + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); + + // ----- Get extra_fields + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); + } + else { + $p_header['extra'] = ''; + } + + // ----- Extract properties + $p_header['version_extracted'] = $v_data['version']; + $p_header['compression'] = $v_data['compression']; + $p_header['size'] = $v_data['size']; + $p_header['compressed_size'] = $v_data['compressed_size']; + $p_header['crc'] = $v_data['crc']; + $p_header['flag'] = $v_data['flag']; + $p_header['filename_len'] = $v_data['filename_len']; + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + //} + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set the status field + $p_header['status'] = "ok"; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadCentralFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x02014b50) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 42); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); + + // ----- Get filename + if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); + else + $p_header['filename'] = ''; + + // ----- Get extra + if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); + else + $p_header['extra'] = ''; + + // ----- Get comment + if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); + else + $p_header['comment'] = ''; + + // ----- Extract properties + + // ----- Recuperate date in UNIX format + //if ($p_header['mdate'] && $p_header['mtime']) + // TBC : bug : this was ignoring time with 0/0/0 + if (1) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set default status to ok + $p_header['status'] = 'ok'; + + // ----- Look if it is a directory + if (substr($p_header['filename'], -1) == '/') { + //$p_header['external'] = 0x41FF0010; + $p_header['external'] = 0x00000010; + } + + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCheckFileHeaders() + // Description : + // Parameters : + // Return Values : + // 1 on success, + // 0 on error; + // -------------------------------------------------------------------------------- + function privCheckFileHeaders(&$p_local_header, &$p_central_header) + { + $v_result=1; + + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + } + + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { + $p_local_header['size'] = $p_central_header['size']; + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + $p_local_header['crc'] = $p_central_header['crc']; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadEndCentralDir() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadEndCentralDir(&$p_central_dir) + { + $v_result=1; + + // ----- Go to the end of the zip file + $v_size = filesize($this->zipname); + @fseek($this->zip_fd, $v_size); + if (@ftell($this->zip_fd) != $v_size) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- First try : look if this is an archive with no commentaries (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + @fseek($this->zip_fd, $v_size-22); + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read for bytes + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = @unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } + + $v_pos = ftell($this->zip_fd); + } + + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) + { + // ----- Read a byte + $v_byte = @fread($this->zip_fd, 1); + + // ----- Add the byte + //$v_bytes = ($v_bytes << 8) | Ord($v_byte); + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. + $v_bytes = (($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); + + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) + { + $v_pos++; + break; + } + + $v_pos++; + } + + // ----- Look if not found end of central dir + if ($v_pos == $v_size) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); + + // ----- Return + return PclZip::errorCode(); + } + } + + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->zip_fd, 18); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); + + // ----- Check the global size + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, + 'The central dir is not at the end of the archive.' + .' Some trailing bytes exists after the archive.'); + + // ----- Return + return PclZip::errorCode(); + } + } + + // ----- Get comment + if ($v_data['comment_size'] != 0) { + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); + } + else + $p_central_dir['comment'] = ''; + + $p_central_dir['entries'] = $v_data['entries']; + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + $p_central_dir['offset'] = $v_data['offset']; + $p_central_dir['size'] = $v_data['size']; + $p_central_dir['disk'] = $v_data['disk']; + $p_central_dir['disk_start'] = $v_data['disk_start']; + + // TBC + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { + //} + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDeleteByRule() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDeleteByRule(&$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read each entry + $v_header_list = array(); + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + + return $v_result; + } + + + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; + + // ----- Look for the specific extract rules + $v_found = false; + + // ----- Look for extract by name rule + if ((isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + + // ----- Look if the directory is in the filename path + if ((strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + elseif ((($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_found = true; + } + } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ((isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + */ + + // ----- Look for extract by preg rule + else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + + // ----- Look for extract by index rule + else if ((isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { + + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + else { + $v_found = true; + } + + // ----- Look for deletion + if ($v_found) + { + unset($v_header_list[$v_nb_extracted]); + } + else + { + $v_nb_extracted++; + } + } + + // ----- Look if something need to be deleted + if ($v_nb_extracted > 0) { + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Creates a temporary zip archive + $v_temp_zip = new PclZip($v_zip_temp_name); + + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { + $this->privCloseFd(); + + // ----- Return + return $v_result; + } + + // ----- Look which file need to be kept + for ($i=0; $i<sizeof($v_header_list); $i++) { + + // ----- Calculate the position of the header + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_local_header = array(); + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Check that local file header is same as central file header + if ($this->privCheckFileHeaders($v_local_header, + $v_header_list[$i]) != 1) { + // TBC + } + unset($v_local_header); + + // ----- Write the file header + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Read/write the data block + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->zip_fd); + + // ----- Re-Create the Central Dir files header + for ($i=0; $i<sizeof($v_header_list); $i++) { + // ----- Create the file header + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Transform the header to a 'usable' info + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Close + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } + + // ----- Remove every files : reset the file + else if ($v_central_dir['entries'] != 0) { + $this->privCloseFd(); + + if (($v_result = $this->privOpenFd('wb')) != 1) { + return $v_result; + } + + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { + return $v_result; + } + + $this->privCloseFd(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // -------------------------------------------------------------------------------- + function privDirCheck($p_dir, $p_is_dir=false) + { + $v_result = 1; + + + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1)=='/')) + { + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); + } + + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) + { + return 1; + } + + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); + + // ----- Just a check + if ($p_parent_dir != $p_dir) + { + // ----- Look for parent directory + if ($p_parent_dir != "") + { + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) + { + return $v_result; + } + } + } + + // ----- Create the directory + if (!@mkdir($p_dir, 0777)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privMerge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privMerge(&$p_archive_to_add) + { + $v_result=1; + + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->zipname)) + { + + // ----- Nothing to merge, so merge is a success + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Look if the archive exists + if (!is_file($this->zipname)) + { + + // ----- Do a duplicate + $v_result = $this->privDuplicate($p_archive_to_add->zipname); + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Open the archive_to_add file + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) + { + $this->privCloseFd(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + return $v_result; + } + + // ----- Go to beginning of File + @rewind($p_archive_to_add->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Merge the file comments + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; + + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd)-$v_offset; + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + @fclose($v_zip_temp_fd); + $this->zip_fd = null; + + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDuplicate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDuplicate($p_archive_filename) + { + $v_result=1; + + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) + { + + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) + { + $this->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorLog() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorLog($p_error_code=0, $p_error_string='') + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclError($p_error_code, $p_error_string); + } + else { + $this->error_code = $p_error_code; + $this->error_string = $p_error_string; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorReset() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorReset() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclErrorReset(); + } + else { + $this->error_code = 0; + $this->error_string = ''; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDisableMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDisableMagicQuotes() + { + $v_result=1; + + // ----- Look if function exists + if ((!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } + + // ----- Look if already done + if ($this->magic_quotes_status != -1) { + return $v_result; + } + + // ----- Get and memorize the magic_quote value + $this->magic_quotes_status = @get_magic_quotes_runtime(); + + // ----- Disable magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime(0); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privSwapBackMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privSwapBackMagicQuotes() + { + $v_result=1; + + // ----- Look if function exists + if ((!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } + + // ----- Look if something to do + if ($this->magic_quotes_status != -1) { + return $v_result; + } + + // ----- Swap back magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime($this->magic_quotes_status); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + } + // End of class + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathReduction() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilPathReduction($p_dir) + { + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + $v_skip = 0; + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") { + $v_skip++; + } + else if ($v_list[$i] == "") { + // ----- First '/' i.e. root slash + if ($i == 0) { + $v_result = "/".$v_result; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; + $v_skip = 0; + } + } + // ----- Last '/' i.e. indicates a directory + else if ($i == (sizeof($v_list)-1)) { + $v_result = $v_list[$i]; + } + // ----- Double '/' inside the path + else { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + } + else { + // ----- Look for item to skip + if ($v_skip > 0) { + $v_skip--; + } + else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } + } + } + + // ----- Look for skip + if ($v_skip > 0) { + while ($v_skip > 0) { + $v_result = '../'.$v_result; + $v_skip--; + } + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathInclusion() + // Description : + // This function indicates if the path $p_path is under the $p_dir tree. Or, + // said in an other way, if the file or sub-dir $p_path is inside the dir + // $p_dir. + // The function indicates also if the path is exactly the same as the dir. + // This function supports path with duplicated '/' like '//', but does not + // support '.' or '..' statements. + // Parameters : + // Return Values : + // 0 if $p_path is not inside directory $p_dir + // 1 if $p_path is inside directory $p_dir + // 2 if $p_path is exactly the same as $p_dir + // -------------------------------------------------------------------------------- + function PclZipUtilPathInclusion($p_dir, $p_path) + { + $v_result = 1; + + // ----- Look for path beginning by ./ + if (($p_dir == '.') + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); + } + if (($p_path == '.') + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); + } + + // ----- Explode dir and path by directory separator + $v_list_dir = explode("/", $p_dir); + $v_list_dir_size = sizeof($v_list_dir); + $v_list_path = explode("/", $p_path); + $v_list_path_size = sizeof($v_list_path); + + // ----- Study directories paths + $i = 0; + $j = 0; + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } + + // ----- Compare the items + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ($v_list_path[$j] != '')) { + $v_result = 0; + } + + // ----- Next items + $i++; + $j++; + } + + // ----- Look if everything seems to be the same + if ($v_result) { + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } + else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilCopyBlock() + // Description : + // Parameters : + // $p_mode : read/write compression mode + // 0 : src & dest normal + // 1 : src gzip, dest normal + // 2 : src normal, dest gzip + // 3 : src & dest gzip + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) + { + $v_result = 1; + + if ($p_mode==0) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==1) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==2) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==3) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilRename() + // Description : + // This function tries to do a simple rename() function. If it fails, it + // tries to copy the $p_src file in a new $p_dest file and then unlink the + // first one. + // Parameters : + // $p_src : Old filename + // $p_dest : New filename + // Return Values : + // 1 on success, 0 on failure. + // -------------------------------------------------------------------------------- + function PclZipUtilRename($p_src, $p_dest) + { + $v_result = 1; + + // ----- Try to rename the files + if (!@rename($p_src, $p_dest)) { + + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; + } + else if (!@unlink($p_src)) { + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilOptionText() + // Description : + // Translate option value in text. Mainly for debug purpose. + // Parameters : + // $p_option : the option value. + // Return Values : + // The option text value. + // -------------------------------------------------------------------------------- + function PclZipUtilOptionText($p_option) + { + + $v_list = get_defined_constants(); + for (reset($v_list); $v_key = key($v_list); next($v_list)) { + $v_prefix = substr($v_key, 0, 10); + if ((($v_prefix == 'PCLZIP_OPT') + || ($v_prefix == 'PCLZIP_CB_') + || ($v_prefix == 'PCLZIP_ATT')) + && ($v_list[$v_key] == $p_option)) { + return $v_key; + } + } + + $v_result = 'Unknown'; + + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilTranslateWinPath() + // Description : + // Translate windows path by replacing '\' by '/' and optionally removing + // drive letter. + // Parameters : + // $p_path : path to translate. + // $p_remove_disk_letter : true | false + // Return Values : + // The path translated. + // -------------------------------------------------------------------------------- + function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) + { + if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; + } + // -------------------------------------------------------------------------------- \ No newline at end of file From 1663ef141cfa3d93c2b91facb8087eaf8cf6d889 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 17 May 2015 00:16:41 +0100 Subject: [PATCH 379/467] More psr-2 changes --- Classes/PHPExcel/Calculation.php | 3298 +++++++++++++++++------------- Classes/PHPExcel/Reader/HTML.php | 105 +- 2 files changed, 1876 insertions(+), 1527 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 032ccd32c..94a0aaf06 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -272,1437 +272,1791 @@ class PHPExcel_Calculation // PHPExcel functions private static $PHPExcelFunctions = array( // PHPExcel functions 'ABS' => array( - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'abs', - argumentCount' => '1' + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'abs', + 'argumentCount' => '1' ), 'ACCRINT' => array( - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', - 'argumentCount' => '4-7' - ), - 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', - 'argumentCount' => '3-5' - ), - 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'acos', - 'argumentCount' => '1' - ), - 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'acosh', - 'argumentCount' => '1' - ), - 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', - 'argumentCount' => '2-5' - ), - 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', - 'argumentCount' => '6,7' - ), - 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', - 'argumentCount' => '6,7' - ), - 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', - 'argumentCount' => '1+' - ), - 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'asin', - 'argumentCount' => '1' - ), - 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'asinh', - 'argumentCount' => '1' - ), - 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'atan', - 'argumentCount' => '1' - ), - 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', - 'argumentCount' => '2' - ), - 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'atanh', - 'argumentCount' => '1' - ), - 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', - 'argumentCount' => '1+' - ), - 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', - 'argumentCount' => '1+' - ), - 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', - 'argumentCount' => '1+' - ), - 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', - 'argumentCount' => '2,3' - ), - 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3+' - ), - 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', - 'argumentCount' => '2' - ), - 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', - 'argumentCount' => '2' - ), - 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', - 'argumentCount' => '2' - ), - 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', - 'argumentCount' => '2' - ), - 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', - 'argumentCount' => '3-5' - ), - 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', - 'argumentCount' => '3-5' - ), - 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', - 'argumentCount' => '1' - ), - 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', - 'argumentCount' => '1,2' - ), - 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', - 'argumentCount' => '1,2' - ), - 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', - 'argumentCount' => '4' - ), - 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', - 'argumentCount' => '2' - ), - 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1,2' - ), - 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', - 'argumentCount' => '1' - ), - 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', - 'argumentCount' => '2' - ), - 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', - 'argumentCount' => '2' - ), - 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', - 'argumentCount' => '2+' - ), - 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', - 'argumentCount' => '1' - ), - 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', - 'argumentCount' => '1' - ), - 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', - 'argumentCount' => '-1', - 'passByReference' => array(true) - ), - 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', - 'argumentCount' => '1' - ), - 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', - 'argumentCount' => '2' - ), - 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', - 'argumentCount' => '2,3' - ), - 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', - 'argumentCount' => '1+' - ), - 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', - 'argumentCount' => '3' - ), - 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', - 'argumentCount' => '3' - ), - 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', - 'argumentCount' => '2' - ), - 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'cos', - 'argumentCount' => '1' - ), - 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'cosh', - 'argumentCount' => '1' - ), - 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', - 'argumentCount' => '1+' - ), - 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', - 'argumentCount' => '1+' - ), - 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', - 'argumentCount' => '1' - ), - 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', - 'argumentCount' => '2' - ), - 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', - 'argumentCount' => '3,4' - ), - 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', - 'argumentCount' => '3,4' - ), - 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', - 'argumentCount' => '3,4' - ), - 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', - 'argumentCount' => '3,4' - ), - 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', - 'argumentCount' => '3,4' - ), - 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', - 'argumentCount' => '3,4' - ), - 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', - 'argumentCount' => '2' - ), - 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', - 'argumentCount' => '3' - ), - 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', - 'argumentCount' => '6' - ), - 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', - 'argumentCount' => '6' - ), - 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', - 'argumentCount' => '3' - ), - 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', - 'argumentCount' => '2,3' - ), - 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', - 'argumentCount' => '1' - ), - 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', - 'argumentCount' => '3' - ), - 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', - 'argumentCount' => '1' - ), - 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', - 'argumentCount' => '2,3' - ), - 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DB', - 'argumentCount' => '4,5' - ), - 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', - 'argumentCount' => '3' - ), - 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', - 'argumentCount' => '3' - ), - 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', - 'argumentCount' => '4,5' - ), - 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', - 'argumentCount' => '1,2' - ), - 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', - 'argumentCount' => '1,2' - ), - 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', - 'argumentCount' => '1,2' - ), - 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'rad2deg', - 'argumentCount' => '1' - ), - 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', - 'argumentCount' => '1,2' - ), - 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', - 'argumentCount' => '1+' - ), - 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DGET', - 'argumentCount' => '3' - ), - 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', - 'argumentCount' => '4,5' - ), - 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', - 'argumentCount' => '3' - ), - 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', - 'argumentCount' => '3' - ), - 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', - 'argumentCount' => '1,2' - ), - 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', - 'argumentCount' => '2' - ), - 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', - 'argumentCount' => '2' - ), - 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', - 'argumentCount' => '3' - ), - 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', - 'argumentCount' => '3' - ), - 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', - 'argumentCount' => '3' - ), - 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', - 'argumentCount' => '3' - ), - 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5,6' - ), - 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', - 'argumentCount' => '3' - ), - 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', - 'argumentCount' => '3' - ), - 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', - 'argumentCount' => '2' - ), - 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', - 'argumentCount' => '2' - ), - 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', - 'argumentCount' => '2' - ), - 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', - 'argumentCount' => '1,2' - ), - 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', - 'argumentCount' => '1' - ), - 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', - 'argumentCount' => '1' - ), - 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', - 'argumentCount' => '1' - ), - 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'exp', - 'argumentCount' => '1' - ), - 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', - 'argumentCount' => '3' - ), - 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', - 'argumentCount' => '1' - ), - 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', - 'argumentCount' => '1' - ), - 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', - 'argumentCount' => '0' - ), - 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3' - ), - 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', - 'argumentCount' => '2,3' - ), - 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', - 'argumentCount' => '2,3' - ), - 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3' - ), - 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', - 'argumentCount' => '1' - ), - 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', - 'argumentCount' => '1' - ), - 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', - 'argumentCount' => '1-3' - ), - 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', - 'argumentCount' => '2' - ), - 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', - 'argumentCount' => '3' - ), - 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::FV', - 'argumentCount' => '3-5' - ), - 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', - 'argumentCount' => '2' - ), - 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', - 'argumentCount' => '4' - ), - 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', - 'argumentCount' => '3' - ), - 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', - 'argumentCount' => '1' - ), - 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', - 'argumentCount' => '1+' - ), - 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', - 'argumentCount' => '1+' - ), - 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', - 'argumentCount' => '1,2' - ), - 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2+' - ), - 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', - 'argumentCount' => '1-4' - ), - 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', - 'argumentCount' => '1+' - ), - 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', - 'argumentCount' => '1,2' - ), - 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', - 'argumentCount' => '1' - ), - 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', - 'argumentCount' => '1,2' - ), - 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', - 'argumentCount' => '3,4' - ), - 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', - 'argumentCount' => '1' - ), - 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', - 'argumentCount' => '1,2', - 'passCellReference'=> true - ), - 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', - 'argumentCount' => '4' - ), - 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', - 'argumentCount' => '1-3' - ), - 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', - 'argumentCount' => '2' - ), - 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', - 'argumentCount' => '1' - ), - 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', - 'argumentCount' => '1' - ), - 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', - 'argumentCount' => '1' - ), - 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', - 'argumentCount' => '1' - ), - 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', - 'argumentCount' => '1' - ), - 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', - 'argumentCount' => '2' - ), - 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', - 'argumentCount' => '1' - ), - 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', - 'argumentCount' => '1' - ), - 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', - 'argumentCount' => '1' - ), - 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', - 'argumentCount' => '1' - ), - 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', - 'argumentCount' => '2' - ), - 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', - 'argumentCount' => '1+' - ), - 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', - 'argumentCount' => '1' - ), - 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', - 'argumentCount' => '1' - ), - 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', - 'argumentCount' => '1' - ), - 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', - 'argumentCount' => '2' - ), - 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', - 'argumentCount' => '1+' - ), - 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', - 'argumentCount' => '1-4' - ), - 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', - 'argumentCount' => '1,2', - 'passCellReference'=> true - ), - 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', - 'argumentCount' => '1' - ), - 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', - 'argumentCount' => '2' - ), - 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', - 'argumentCount' => '4,5' - ), - 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', - 'argumentCount' => '4-6' - ), - 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', - 'argumentCount' => '1,2' - ), - 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', - 'argumentCount' => '1' - ), - 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', - 'argumentCount' => '1' - ), - 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', - 'argumentCount' => '1' - ), - 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', - 'argumentCount' => '1' - ), - 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', - 'argumentCount' => '1' - ), - 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', - 'argumentCount' => '1' - ), - 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', - 'argumentCount' => '1' - ), - 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', - 'argumentCount' => '1' - ), - 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', - 'argumentCount' => '1' - ), - 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', - 'argumentCount' => '4' - ), - 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', - 'argumentCount' => '1' - ), - 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', - 'argumentCount' => '1+' - ), - 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', - 'argumentCount' => '2' - ), - 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', - 'argumentCount' => '1+' - ), - 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', - 'argumentCount' => '1,2' - ), - 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', - 'argumentCount' => '1,2' - ), - 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', - 'argumentCount' => '1' - ), - 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', - 'argumentCount' => '1' - ), - 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', - 'argumentCount' => '1-4' - ), - 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'log', - 'argumentCount' => '1' - ), - 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', - 'argumentCount' => '1,2' - ), - 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'log10', - 'argumentCount' => '1' - ), - 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', - 'argumentCount' => '1-4' - ), - 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', - 'argumentCount' => '3' - ), - 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', - 'argumentCount' => '3' - ), - 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', - 'argumentCount' => '2,3' - ), - 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', - 'argumentCount' => '1' - ), - 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', - 'argumentCount' => '2,3' - ), - 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', - 'argumentCount' => '1+' - ), - 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', - 'argumentCount' => '1+' - ), - 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', - 'argumentCount' => '2+' - ), - 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', - 'argumentCount' => '1' - ), - 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5,6' - ), - 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', - 'argumentCount' => '1+' - ), - 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2+' - ), - 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::MID', - 'argumentCount' => '3' - ), - 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::MID', - 'argumentCount' => '3' - ), - 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', - 'argumentCount' => '1+' - ), - 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', - 'argumentCount' => '1+' - ), - 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', - 'argumentCount' => '2+' - ), - 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', - 'argumentCount' => '1' - ), - 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', - 'argumentCount' => '1' - ), - 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', - 'argumentCount' => '3' - ), - 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', - 'argumentCount' => '2' - ), - 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', - 'argumentCount' => '2' - ), - 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', - 'argumentCount' => '1+' - ), - 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', - 'argumentCount' => '1' - ), - 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', - 'argumentCount' => '2' - ), - 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', - 'argumentCount' => '1+' - ), - 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::N', - 'argumentCount' => '1' - ), - 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::NA', - 'argumentCount' => '0' - ), - 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', - 'argumentCount' => '3' - ), - 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', - 'argumentCount' => '2+' - ), - 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', - 'argumentCount' => '2' - ), - 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', - 'argumentCount' => '4' - ), - 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', - 'argumentCount' => '3' - ), - 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', - 'argumentCount' => '1' - ), - 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', - 'argumentCount' => '1' - ), - 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', - 'argumentCount' => '1' - ), - 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', - 'argumentCount' => '0' - ), - 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', - 'argumentCount' => '3-5' - ), - 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', - 'argumentCount' => '2+' - ), - 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', - 'argumentCount' => '1,2' - ), - 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', - 'argumentCount' => '1' - ), - 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', - 'argumentCount' => '1,2' - ), - 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', - 'argumentCount' => '1' - ), - 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '8,9' - ), - 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '8,9' - ), - 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '7,8' - ), - 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '7,8' - ), - 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', - 'argumentCount' => '3,5', - 'passCellReference'=> true, - 'passByReference' => array(true) - ), - 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', - 'argumentCount' => '1+' - ), - 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', - 'argumentCount' => '2' - ), - 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', - 'argumentCount' => '2' - ), - 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', - 'argumentCount' => '2,3' - ), - 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', - 'argumentCount' => '2' - ), - 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'pi', - 'argumentCount' => '0' - ), - 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', - 'argumentCount' => '3-5' - ), - 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', - 'argumentCount' => '3' - ), - 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', - 'argumentCount' => '2' - ), - 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', - 'argumentCount' => '4-6' - ), - 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', - 'argumentCount' => '6,7' - ), - 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', - 'argumentCount' => '4,5' - ), - 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', - 'argumentCount' => '5,6' - ), - 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3,4' - ), - 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', - 'argumentCount' => '1+' - ), - 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', - 'argumentCount' => '1' - ), - 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PV', - 'argumentCount' => '3-5' - ), - 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', - 'argumentCount' => '2' - ), - 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', - 'argumentCount' => '2' - ), - 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'deg2rad', - 'argumentCount' => '1' - ), - 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', - 'argumentCount' => '0' - ), - 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', - 'argumentCount' => '2' - ), - 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', - 'argumentCount' => '2,3' - ), - 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', - 'argumentCount' => '3-6' - ), - 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', - 'argumentCount' => '4-5' - ), - 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', - 'argumentCount' => '4' - ), - 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', - 'argumentCount' => '4' - ), - 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'str_repeat', - 'argumentCount' => '2' - ), - 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', - 'argumentCount' => '1,2' - ), - 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', - 'argumentCount' => '1,2' - ), - 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', - 'argumentCount' => '1,2' - ), - 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'round', - 'argumentCount' => '2' - ), - 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', - 'argumentCount' => '2' - ), - 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', - 'argumentCount' => '2' - ), - 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', - 'argumentCount' => '-1', - 'passByReference' => array(true) - ), - 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', - 'argumentCount' => '1' - ), - 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', - 'argumentCount' => '2' - ), - 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1+' - ), - 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', - 'argumentCount' => '2,3' - ), - 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', - 'argumentCount' => '2,3' - ), - 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', - 'argumentCount' => '1' - ), - 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', - 'argumentCount' => '4' - ), - 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', - 'argumentCount' => '1' - ), - 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sin', - 'argumentCount' => '1' - ), - 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sinh', - 'argumentCount' => '1' - ), - 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', - 'argumentCount' => '1+' - ), - 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', - 'argumentCount' => '3' - ), - 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', - 'argumentCount' => '2' - ), - 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', - 'argumentCount' => '2' - ), - 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sqrt', - 'argumentCount' => '1' - ), - 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', - 'argumentCount' => '1' - ), - 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', - 'argumentCount' => '3' - ), - 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', - 'argumentCount' => '1+' - ), - 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', - 'argumentCount' => '1+' - ), - 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', - 'argumentCount' => '1+' - ), - 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', - 'argumentCount' => '1+' - ), - 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', - 'argumentCount' => '2' - ), - 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', - 'argumentCount' => '3,4' - ), - 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', - 'argumentCount' => '2+' - ), - 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', - 'argumentCount' => '1+' - ), - 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', - 'argumentCount' => '2,3' - ), - 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', - 'argumentCount' => '1+' - ), - 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', - 'argumentCount' => '1+' - ), - 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', - 'argumentCount' => '2' - ), - 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', - 'argumentCount' => '2' - ), - 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', - 'argumentCount' => '2' - ), - 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', - 'argumentCount' => '4' - ), - 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', - 'argumentCount' => '1' - ), - 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'tan', - 'argumentCount' => '1' - ), - 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'tanh', - 'argumentCount' => '1' - ), - 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', - 'argumentCount' => '3' - ), - 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', - 'argumentCount' => '3' - ), - 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', - 'argumentCount' => '3' - ), - 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', - 'argumentCount' => '3' - ), - 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', - 'argumentCount' => '2' - ), - 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', - 'argumentCount' => '3' - ), - 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', - 'argumentCount' => '1' - ), - 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', - 'argumentCount' => '2' - ), - 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', - 'argumentCount' => '0' - ), - 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', - 'argumentCount' => '1' - ), - 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', - 'argumentCount' => '1-4' - ), - 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', - 'argumentCount' => '1' - ), - 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', - 'argumentCount' => '2' - ), - 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', - 'argumentCount' => '0' - ), - 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', - 'argumentCount' => '1,2' - ), - 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '4' - ), - 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', - 'argumentCount' => '1' - ), - 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', - 'argumentCount' => '1' - ), - 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', - 'argumentCount' => '1' - ), - 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', - 'argumentCount' => '1+' - ), - 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', - 'argumentCount' => '1+' - ), - 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', - 'argumentCount' => '1+' - ), - 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', - 'argumentCount' => '1+' - ), - 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5-7' - ), - 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', - 'argumentCount' => '0' - ), - 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', - 'argumentCount' => '3,4' - ), - 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', - 'argumentCount' => '1,2' - ), - 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', - 'argumentCount' => '1,2' - ), - 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', - 'argumentCount' => '4' - ), - 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', - 'argumentCount' => '2+' - ), - 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', - 'argumentCount' => '2,3' - ), - 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', - 'argumentCount' => '3' - ), - 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', - 'argumentCount' => '1' - ), - 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', - 'argumentCount' => '2,3' - ), - 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '6,7' - ), - 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', - 'argumentCount' => '4,5' - ), - 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', - 'argumentCount' => '5,6' - ), + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', + 'argumentCount' => '4-7' + ), + 'ACCRINTM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', + 'argumentCount' => '3-5' + ), + 'ACOS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acos', + 'argumentCount' => '1' + ), + 'ACOSH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acosh', + 'argumentCount' => '1' + ), + 'ADDRESS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', + 'argumentCount' => '2-5' + ), + 'AMORDEGRC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', + 'argumentCount' => '6,7' + ), + 'AMORLINC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', + 'argumentCount' => '6,7' + ), + 'AND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', + 'argumentCount' => '1+' + ), + 'AREAS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asin', + 'argumentCount' => '1' + ), + 'ASINH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asinh', + 'argumentCount' => '1' + ), + 'ATAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atan', + 'argumentCount' => '1' + ), + 'ATAN2' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', + 'argumentCount' => '2' + ), + 'ATANH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atanh', + 'argumentCount' => '1' + ), + 'AVEDEV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', + 'argumentCount' => '1+' + ), + 'AVERAGE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', + 'argumentCount' => '1+' + ), + 'AVERAGEA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', + 'argumentCount' => '1+' + ), + 'AVERAGEIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', + 'argumentCount' => '2,3' + ), + 'AVERAGEIFS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3+' + ), + 'BAHTTEXT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'BESSELI' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', + 'argumentCount' => '2' + ), + 'BESSELJ' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', + 'argumentCount' => '2' + ), + 'BESSELK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', + 'argumentCount' => '2' + ), + 'BESSELY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', + 'argumentCount' => '2' + ), + 'BETADIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', + 'argumentCount' => '3-5' + ), + 'BETAINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', + 'argumentCount' => '3-5' + ), + 'BIN2DEC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', + 'argumentCount' => '1' + ), + 'BIN2HEX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', + 'argumentCount' => '1,2' + ), + 'BIN2OCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', + 'argumentCount' => '1,2' + ), + 'BINOMDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', + 'argumentCount' => '4' + ), + 'CEILING' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', + 'argumentCount' => '2' + ), + 'CELL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1,2' + ), + 'CHAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', + 'argumentCount' => '1' + ), + 'CHIDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', + 'argumentCount' => '2' + ), + 'CHIINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', + 'argumentCount' => '2' + ), + 'CHITEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'CHOOSE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', + 'argumentCount' => '2+' + ), + 'CLEAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', + 'argumentCount' => '1' + ), + 'CODE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', + 'argumentCount' => '1' + ), + 'COLUMN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', + 'argumentCount' => '-1', + 'passByReference' => array(true) + ), + 'COLUMNS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', + 'argumentCount' => '1' + ), + 'COMBIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', + 'argumentCount' => '2' + ), + 'COMPLEX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', + 'argumentCount' => '2,3' + ), + 'CONCATENATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', + 'argumentCount' => '1+' + ), + 'CONFIDENCE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', + 'argumentCount' => '3' + ), + 'CONVERT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', + 'argumentCount' => '3' + ), + 'CORREL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'COS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cos', + 'argumentCount' => '1' + ), + 'COSH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cosh', + 'argumentCount' => '1' + ), + 'COUNT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', + 'argumentCount' => '1+' + ), + 'COUNTA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', + 'argumentCount' => '1+' + ), + 'COUNTBLANK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', + 'argumentCount' => '1' + ), + 'COUNTIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', + 'argumentCount' => '2' + ), + 'COUNTIFS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'COUPDAYBS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', + 'argumentCount' => '3,4' + ), + 'COUPDAYS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', + 'argumentCount' => '3,4' + ), + 'COUPDAYSNC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', + 'argumentCount' => '3,4' + ), + 'COUPNCD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', + 'argumentCount' => '3,4' + ), + 'COUPNUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', + 'argumentCount' => '3,4' + ), + 'COUPPCD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', + 'argumentCount' => '3,4' + ), + 'COVAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', + 'argumentCount' => '2' + ), + 'CRITBINOM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', + 'argumentCount' => '3' + ), + 'CUBEKPIMEMBER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBERPROPERTY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBERANKEDMEMBER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESET' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESETCOUNT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEVALUE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUMIPMT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', + 'argumentCount' => '6' + ), + 'CUMPRINC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', + 'argumentCount' => '6' + ), + 'DATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', + 'argumentCount' => '3' + ), + 'DATEDIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', + 'argumentCount' => '2,3' + ), + 'DATEVALUE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', + 'argumentCount' => '1' + ), + 'DAVERAGE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', + 'argumentCount' => '3' + ), + 'DAY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', + 'argumentCount' => '1' + ), + 'DAYS360' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', + 'argumentCount' => '2,3' + ), + 'DB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DB', + 'argumentCount' => '4,5' + ), + 'DCOUNT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', + 'argumentCount' => '3' + ), + 'DCOUNTA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', + 'argumentCount' => '3' + ), + 'DDB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', + 'argumentCount' => '4,5' + ), + 'DEC2BIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', + 'argumentCount' => '1,2' + ), + 'DEC2HEX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', + 'argumentCount' => '1,2' + ), + 'DEC2OCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', + 'argumentCount' => '1,2' + ), + 'DEGREES' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'rad2deg', + 'argumentCount' => '1' + ), + 'DELTA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', + 'argumentCount' => '1,2' + ), + 'DEVSQ' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', + 'argumentCount' => '1+' + ), + 'DGET' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DGET', + 'argumentCount' => '3' + ), + 'DISC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', + 'argumentCount' => '4,5' + ), + 'DMAX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', + 'argumentCount' => '3' + ), + 'DMIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', + 'argumentCount' => '3' + ), + 'DOLLAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', + 'argumentCount' => '1,2' + ), + 'DOLLARDE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', + 'argumentCount' => '2' + ), + 'DOLLARFR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', + 'argumentCount' => '2' + ), + 'DPRODUCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', + 'argumentCount' => '3' + ), + 'DSTDEV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', + 'argumentCount' => '3' + ), + 'DSTDEVP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', + 'argumentCount' => '3' + ), + 'DSUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', + 'argumentCount' => '3' + ), + 'DURATION' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + array( + 'onCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'DVAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', + 'argumentCount' => '3' + ), + 'DVARP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', + 'argumentCount' => '3' + ), + 'EDATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', + 'argumentCount' => '2' + ), + 'EFFECT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', + 'argumentCount' => '2' + ), + 'EOMONTH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', + 'argumentCount' => '2' + ), + 'ERF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', + 'argumentCount' => '1,2' + ), + 'ERFC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', + 'argumentCount' => '1' + ), + 'ERROR.TYPE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', + 'argumentCount' => '1' + ), + 'EVEN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', + 'argumentCount' => '1' + ), + 'EXACT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'EXP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'exp', + 'argumentCount' => '1' + ), + 'EXPONDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', + 'argumentCount' => '3' + ), + 'FACT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', + 'argumentCount' => '1' + ), + 'FACTDOUBLE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', + 'argumentCount' => '1' + ), + 'FALSE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', + 'argumentCount' => '0' + ), + 'FDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FIND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINDB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FISHER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', + 'argumentCount' => '1' + ), + 'FISHERINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', + 'argumentCount' => '1' + ), + 'FIXED' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', + 'argumentCount' => '1-3' + ), + 'FLOOR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', + 'argumentCount' => '2' + ), + 'FORECAST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', + 'argumentCount' => '3' + ), + 'FREQUENCY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FTEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FV', + 'argumentCount' => '3-5' + ), + 'FVSCHEDULE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', + 'argumentCount' => '2' + ), + 'GAMMADIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', + 'argumentCount' => '4' + ), + 'GAMMAINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', + 'argumentCount' => '3' + ), + 'GAMMALN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', + 'argumentCount' => '1' + ), + 'GCD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', + 'argumentCount' => '1+' + ), + 'GEOMEAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', + 'argumentCount' => '1+' + ), + 'GESTEP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', + 'argumentCount' => '1,2' + ), + 'GETPIVOTDATA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'GROWTH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', + 'argumentCount' => '1-4' + ), + 'HARMEAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', + 'argumentCount' => '1+' + ), + 'HEX2BIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', + 'argumentCount' => '1,2' + ), + 'HEX2DEC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', + 'argumentCount' => '1' + ), + 'HEX2OCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', + 'argumentCount' => '1,2' + ), + 'HLOOKUP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', + 'argumentCount' => '3,4' + ), + 'HOUR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', + 'argumentCount' => '1' + ), + 'HYPERLINK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', + 'argumentCount' => '1,2', + 'passCellReference'=> true + ), + 'HYPGEOMDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', + 'argumentCount' => '4' + ), + 'IF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', + 'argumentCount' => '1-3' + ), + 'IFERROR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', + 'argumentCount' => '2' + ), + 'IMABS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', + 'argumentCount' => '1' + ), + 'IMAGINARY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', + 'argumentCount' => '1' + ), + 'IMARGUMENT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', + 'argumentCount' => '1' + ), + 'IMCONJUGATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', + 'argumentCount' => '1' + ), + 'IMCOS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', + 'argumentCount' => '1' + ), + 'IMDIV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', + 'argumentCount' => '2' + ), + 'IMEXP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', + 'argumentCount' => '1' + ), + 'IMLN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', + 'argumentCount' => '1' + ), + 'IMLOG10' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', + 'argumentCount' => '1' + ), + 'IMLOG2' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', + 'argumentCount' => '1' + ), + 'IMPOWER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', + 'argumentCount' => '2' + ), + 'IMPRODUCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', + 'argumentCount' => '1+' + ), + 'IMREAL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', + 'argumentCount' => '1' + ), + 'IMSIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', + 'argumentCount' => '1' + ), + 'IMSQRT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', + 'argumentCount' => '1' + ), + 'IMSUB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', + 'argumentCount' => '2' + ), + 'IMSUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', + 'argumentCount' => '1+' + ), + 'INDEX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', + 'argumentCount' => '1-4' + ), + 'INDIRECT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', + 'argumentCount' => '1,2', + 'passCellReference'=> true + ), + 'INFO' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'INT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', + 'argumentCount' => '1' + ), + 'INTERCEPT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', + 'argumentCount' => '2' + ), + 'INTRATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', + 'argumentCount' => '4,5' + ), + 'IPMT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', + 'argumentCount' => '4-6' + ), + 'IRR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', + 'argumentCount' => '1,2' + ), + 'ISBLANK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', + 'argumentCount' => '1' + ), + 'ISERR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', + 'argumentCount' => '1' + ), + 'ISERROR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', + 'argumentCount' => '1' + ), + 'ISEVEN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', + 'argumentCount' => '1' + ), + 'ISLOGICAL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', + 'argumentCount' => '1' + ), + 'ISNA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', + 'argumentCount' => '1' + ), + 'ISNONTEXT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', + 'argumentCount' => '1' + ), + 'ISNUMBER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', + 'argumentCount' => '1' + ), + 'ISODD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', + 'argumentCount' => '1' + ), + 'ISPMT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', + 'argumentCount' => '4' + ), + 'ISREF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ISTEXT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', + 'argumentCount' => '1' + ), + 'JIS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'KURT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', + 'argumentCount' => '1+' + ), + 'LARGE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', + 'argumentCount' => '2' + ), + 'LCM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', + 'argumentCount' => '1+' + ), + 'LEFT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEFTB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LENB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LINEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', + 'argumentCount' => '1-4' + ), + 'LN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log', + 'argumentCount' => '1' + ), + 'LOG' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', + 'argumentCount' => '1,2' + ), + 'LOG10' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log10', + 'argumentCount' => '1' + ), + 'LOGEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', + 'argumentCount' => '1-4' + ), + 'LOGINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', + 'argumentCount' => '3' + ), + 'LOGNORMDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', + 'argumentCount' => '3' + ), + 'LOOKUP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', + 'argumentCount' => '2,3' + ), + 'LOWER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', + 'argumentCount' => '1' + ), + 'MATCH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', + 'argumentCount' => '2,3' + ), + 'MAX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', + 'argumentCount' => '1+' + ), + 'MAXA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', + 'argumentCount' => '1+' + ), + 'MAXIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', + 'argumentCount' => '2+' + ), + 'MDETERM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', + 'argumentCount' => '1' + ), + 'MDURATION' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'MEDIAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', + 'argumentCount' => '1+' + ), + 'MEDIANIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'MID' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIDB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', + 'argumentCount' => '1+' + ), + 'MINA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', + 'argumentCount' => '1+' + ), + 'MINIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', + 'argumentCount' => '2+' + ), + 'MINUTE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', + 'argumentCount' => '1' + ), + 'MINVERSE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', + 'argumentCount' => '1' + ), + 'MIRR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', + 'argumentCount' => '3' + ), + 'MMULT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', + 'argumentCount' => '2' + ), + 'MOD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', + 'argumentCount' => '2' + ), + 'MODE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', + 'argumentCount' => '1+' + ), + 'MONTH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', + 'argumentCount' => '1' + ), + 'MROUND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', + 'argumentCount' => '2' + ), + 'MULTINOMIAL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', + 'argumentCount' => '1+' + ), + 'N' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::N', + 'argumentCount' => '1' + ), + 'NA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::NA', + 'argumentCount' => '0' + ), + 'NEGBINOMDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', + 'argumentCount' => '3' + ), + 'NETWORKDAYS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', + 'argumentCount' => '2+' + ), + 'NOMINAL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', + 'argumentCount' => '2' + ), + 'NORMDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', + 'argumentCount' => '4' + ), + 'NORMINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', + 'argumentCount' => '3' + ), + 'NORMSDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', + 'argumentCount' => '1' + ), + 'NORMSINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', + 'argumentCount' => '1' + ), + 'NOT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', + 'argumentCount' => '1' + ), + 'NOW' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', + 'argumentCount' => '0' + ), + 'NPER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', + 'argumentCount' => '3-5' + ), + 'NPV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', + 'argumentCount' => '2+' + ), + 'OCT2BIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', + 'argumentCount' => '1,2' + ), + 'OCT2DEC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', + 'argumentCount' => '1' + ), + 'OCT2HEX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', + 'argumentCount' => '1,2' + ), + 'ODD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', + 'argumentCount' => '1' + ), + 'ODDFPRICE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDFYIELD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDLPRICE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'ODDLYIELD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'OFFSET' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', + 'argumentCount' => '3,5', + 'passCellReference'=> true, + 'passByReference' => array(true) + ), + 'OR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', + 'argumentCount' => '1+' + ), + 'PEARSON' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'PERCENTILE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', + 'argumentCount' => '2' + ), + 'PERCENTRANK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', + 'argumentCount' => '2,3' + ), + 'PERMUT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', + 'argumentCount' => '2' + ), + 'PHONETIC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'PI' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'pi', + 'argumentCount' => '0' + ), + 'PMT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', + 'argumentCount' => '3-5' + ), + 'POISSON' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', + 'argumentCount' => '3' + ), + 'POWER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', + 'argumentCount' => '2' + ), + 'PPMT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', + 'argumentCount' => '4-6' + ), + 'PRICE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', + 'argumentCount' => '6,7' + ), + 'PRICEDISC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', + 'argumentCount' => '4,5' + ), + 'PRICEMAT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', + 'argumentCount' => '5,6' + ), + 'PROB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3,4' + ), + 'PRODUCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', + 'argumentCount' => '1+' + ), + 'PROPER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', + 'argumentCount' => '1' + ), + 'PV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PV', + 'argumentCount' => '3-5' + ), + 'QUARTILE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', + 'argumentCount' => '2' + ), + 'QUOTIENT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', + 'argumentCount' => '2' + ), + 'RADIANS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'deg2rad', + 'argumentCount' => '1' + ), + 'RAND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '0' + ), + 'RANDBETWEEN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '2' + ), + 'RANK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', + 'argumentCount' => '2,3' + ), + 'RATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', + 'argumentCount' => '3-6' + ), + 'RECEIVED' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', + 'argumentCount' => '4-5' + ), + 'REPLACE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPLACEB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'str_repeat', + 'argumentCount' => '2' + ), + 'RIGHT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'RIGHTB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'ROMAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', + 'argumentCount' => '1,2' + ), + 'ROUND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'round', + 'argumentCount' => '2' + ), + 'ROUNDDOWN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', + 'argumentCount' => '2' + ), + 'ROUNDUP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', + 'argumentCount' => '2' + ), + 'ROW' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', + 'argumentCount' => '-1', + 'passByReference' => array(true) + ), + 'ROWS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', + 'argumentCount' => '1' + ), + 'RSQ' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', + 'argumentCount' => '2' + ), + 'RTD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1+' + ), + 'SEARCH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SEARCHB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SECOND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', + 'argumentCount' => '1' + ), + 'SERIESSUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', + 'argumentCount' => '4' + ), + 'SIGN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', + 'argumentCount' => '1' + ), + 'SIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sin', + 'argumentCount' => '1' + ), + 'SINH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sinh', + 'argumentCount' => '1' + ), + 'SKEW' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', + 'argumentCount' => '1+' + ), + 'SLN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', + 'argumentCount' => '3' + ), + 'SLOPE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', + 'argumentCount' => '2' + ), + 'SMALL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', + 'argumentCount' => '2' + ), + 'SQRT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sqrt', + 'argumentCount' => '1' + ), + 'SQRTPI' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', + 'argumentCount' => '1' + ), + 'STANDARDIZE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', + 'argumentCount' => '3' + ), + 'STDEV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', + 'argumentCount' => '1+' + ), + 'STDEVA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', + 'argumentCount' => '1+' + ), + 'STDEVP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', + 'argumentCount' => '1+' + ), + 'STDEVPA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', + 'argumentCount' => '1+' + ), + 'STEYX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', + 'argumentCount' => '2' + ), + 'SUBSTITUTE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', + 'argumentCount' => '3,4' + ), + 'SUBTOTAL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', + 'argumentCount' => '2+' + ), + 'SUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', + 'argumentCount' => '1+' + ), + 'SUMIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', + 'argumentCount' => '2,3' + ), + 'SUMIFS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'SUMPRODUCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', + 'argumentCount' => '1+' + ), + 'SUMSQ' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', + 'argumentCount' => '1+' + ), + 'SUMX2MY2' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', + 'argumentCount' => '2' + ), + 'SUMX2PY2' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', + 'argumentCount' => '2' + ), + 'SUMXMY2' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', + 'argumentCount' => '2' + ), + 'SYD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', + 'argumentCount' => '4' + ), + 'T' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', + 'argumentCount' => '1' + ), + 'TAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tan', + 'argumentCount' => '1' + ), + 'TANH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tanh', + 'argumentCount' => '1' + ), + 'TBILLEQ' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', + 'argumentCount' => '3' + ), + 'TBILLPRICE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', + 'argumentCount' => '3' + ), + 'TBILLYIELD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', + 'argumentCount' => '3' + ), + 'TDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', + 'argumentCount' => '3' + ), + 'TEXT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', + 'argumentCount' => '2' + ), + 'TIME' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', + 'argumentCount' => '3' + ), + 'TIMEVALUE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', + 'argumentCount' => '1' + ), + 'TINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', + 'argumentCount' => '2' + ), + 'TODAY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', + 'argumentCount' => '0' + ), + 'TRANSPOSE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', + 'argumentCount' => '1' + ), + 'TREND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', + 'argumentCount' => '1-4' + ), + 'TRIM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', + 'argumentCount' => '1' + ), + 'TRIMMEAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', + 'argumentCount' => '2' + ), + 'TRUE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', + 'argumentCount' => '0' + ), + 'TRUNC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', + 'argumentCount' => '1,2' + ), + 'TTEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '4' + ), + 'TYPE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', + 'argumentCount' => '1' + ), + 'UPPER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', + 'argumentCount' => '1' + ), + 'USDOLLAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'VALUE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', + 'argumentCount' => '1' + ), + 'VAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', + 'argumentCount' => '1+' + ), + 'VARA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', + 'argumentCount' => '1+' + ), + 'VARP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', + 'argumentCount' => '1+' + ), + 'VARPA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', + 'argumentCount' => '1+' + ), + 'VDB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5-7' + ), + 'VERSION' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', + 'argumentCount' => '0' + ), + 'VLOOKUP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', + 'argumentCount' => '3,4' + ), + 'WEEKDAY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', + 'argumentCount' => '1,2' + ), + 'WEEKNUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', + 'argumentCount' => '1,2' + ), + 'WEIBULL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', + 'argumentCount' => '4' + ), + 'WORKDAY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', + 'argumentCount' => '2+' + ), + 'XIRR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', + 'argumentCount' => '2,3' + ), + 'XNPV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', + 'argumentCount' => '3' + ), + 'YEAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', + 'argumentCount' => '1' + ), + 'YEARFRAC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', + 'argumentCount' => '2,3' + ), + 'YIELD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '6,7' + ), + 'YIELDDISC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', + 'argumentCount' => '4,5' + ), + 'YIELDMAT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', + 'argumentCount' => '5,6' + ), 'ZTEST' => array( - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', - 'argumentCount' => '2-3' + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', + 'argumentCount' => '2-3' ) ); @@ -2442,7 +2796,7 @@ public function _calculateFormulaValue($formula, $cellID = null, PHPExcel_Cell $ if (($wsTitle{0} !== "\x00") && ($this->cyclicReferenceStack->onStack($wsCellReference))) { if ($this->cyclicFormulaCount <= 0) { $this->cyclicFormulaCell = ''; - return $this->_raiseFormulaError('Cyclic Reference in Formula'); + return $this->raiseFormulaError('Cyclic Reference in Formula'); } elseif ($this->cyclicFormulaCell === $wsCellReference) { ++$this->cyclicFormulaCounter; if ($this->cyclicFormulaCounter >= $this->cyclicFormulaCount) { @@ -2739,15 +3093,15 @@ private function _convertMatrixReferences($formula) // Trap for mismatched braces and trigger an appropriate error if ($openCount < $closeCount) { if ($openCount > 0) { - return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '}'"); + return $this->raiseFormulaError("Formula Error: Mismatched matrix braces '}'"); } else { - return $this->_raiseFormulaError("Formula Error: Unexpected '}' encountered"); + return $this->raiseFormulaError("Formula Error: Unexpected '}' encountered"); } } elseif ($openCount > $closeCount) { if ($closeCount > 0) { - return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '{'"); + return $this->raiseFormulaError("Formula Error: Mismatched matrix braces '{'"); } else { - return $this->_raiseFormulaError("Formula Error: Unexpected '{' encountered"); + return $this->raiseFormulaError("Formula Error: Unexpected '{' encountered"); } } } @@ -2849,7 +3203,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) //echo 'Element is a Positive number, not Plus operator', PHP_EOL; ++$index; // Drop the redundant plus symbol } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal - return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression + return $this->raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression } elseif ((isset(self::$operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? //echo 'Element with value '.$opCharacter.' is an Operator', PHP_EOL; @@ -2868,7 +3222,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) $expectingOperand = false; while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( if ($o2 === null) { - return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"'); + return $this->raiseFormulaError('Formula Error: Unexpected closing brace ")"'); } else { $output[] = $o2; } @@ -2897,7 +3251,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) $expectedArgumentCount = self::$PHPExcelFunctions[$functionName]['argumentCount']; $functionCall = self::$PHPExcelFunctions[$functionName]['functionCall']; } else { // did we somehow push a non-function on the stack? this should never happen - return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack"); + return $this->raiseFormulaError("Formula Error: Internal error, non-function on stack"); } // Check the argument count $argumentCountError = false; @@ -2941,7 +3295,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) } } if ($argumentCountError) { - return $this->_raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected"); + return $this->raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected"); } } ++$index; @@ -2950,7 +3304,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) //echo 'Element is a Function argument separator', PHP_EOL; while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( if ($o2 === null) { - return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + return $this->raiseFormulaError("Formula Error: Unexpected ,"); } else { $output[] = $o2; // pop the argument expression stuff and push onto the output } @@ -2963,7 +3317,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) // make sure there was a function $d = $stack->last(2); if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { - return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + return $this->raiseFormulaError("Formula Error: Unexpected ,"); } $d = $stack->pop(); $stack->push($d['type'], ++$d['value'], $d['reference']); // increment the argument count @@ -3019,7 +3373,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) $val = $startMatches[2].'!'.$val; } } else { - return $this->_raiseFormulaError("3D Range references are not yet supported"); + return $this->raiseFormulaError("3D Range references are not yet supported"); } } @@ -3098,19 +3452,19 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) $expectingOperand = false; $expectingOperator = true; } else { - return $this->_raiseFormulaError("Formula Error: Unexpected ')'"); + return $this->raiseFormulaError("Formula Error: Unexpected ')'"); } } elseif (isset(self::$operators[$opCharacter]) && !$expectingOperator) { - return $this->_raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'"); + return $this->raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'"); } else { // I don't even want to know what you did to get here - return $this->_raiseFormulaError("Formula Error: An unexpected error occured"); + return $this->raiseFormulaError("Formula Error: An unexpected error occured"); } // Test for end of formula string if ($index == strlen($formula)) { // Did we end with an operator?. // Only valid for the % unary operator if ((isset(self::$operators[$opCharacter])) && ($opCharacter != '%')) { - return $this->_raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands"); + return $this->raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands"); } else { break; } @@ -3143,7 +3497,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) while (($op = $stack->pop()) !== null) { // pop everything off the stack and push onto output if ((is_array($op) && $op['value'] == '(') || ($op === '(')) { - return $this->_raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced + return $this->raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced } $output[] = $op; } @@ -3190,10 +3544,10 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // echo 'Token is a binary operator<br />'; // We must have two operands, error if we don't if (($operand2Data = $stack->pop()) === null) { - return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + return $this->raiseFormulaError('Internal error - Operand value missing from stack'); } if (($operand1Data = $stack->pop()) === null) { - return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + return $this->raiseFormulaError('Internal error - Operand value missing from stack'); } $operand1 = self::_dataTestReference($operand1Data); @@ -3215,7 +3569,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel case '<=': // Less than or Equal to case '=': // Equality case '<>': // Inequality - $this->_executeBinaryComparisonOperation($cellID, $operand1, $operand2, $token, $stack); + $this->executeBinaryComparisonOperation($cellID, $operand1, $operand2, $token, $stack); break; // Binary Operators case ':': // Range @@ -3261,7 +3615,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel if ($pCellParent !== null) { $cellValue = $this->extractCellRange($cellRef, $this->workbook->getSheetByName($sheet1), false); } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); + return $this->raiseFormulaError('Unable to access Cell Reference'); } $stack->push('Cell Reference', $cellValue, $cellRef); } else { @@ -3269,19 +3623,19 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } break; case '+': // Addition - $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'plusEquals', $stack); + $this->executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'plusEquals', $stack); break; case '-': // Subtraction - $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'minusEquals', $stack); + $this->executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'minusEquals', $stack); break; case '*': // Multiplication - $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'arrayTimesEquals', $stack); + $this->executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'arrayTimesEquals', $stack); break; case '/': // Division - $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'arrayRightDivide', $stack); + $this->executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'arrayRightDivide', $stack); break; case '^': // Exponential - $this->_executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'power', $stack); + $this->executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'power', $stack); break; case '&': // Concatenation // If either of the operands is a matrix, we need to treat them both as matrices @@ -3332,7 +3686,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } elseif (($token === '~') || ($token === '%')) { // echo 'Token is a unary operator<br />'; if (($arg = $stack->pop()) === null) { - return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + return $this->raiseFormulaError('Internal error - Operand value missing from stack'); } $arg = $arg['value']; if ($token === '~') { @@ -3357,7 +3711,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); $stack->push('Value', $result); } else { - $this->_executeNumericBinaryOperation($cellID, $multiplier, $arg, '*', 'arrayTimesEquals', $stack); + $this->executeNumericBinaryOperation($cellID, $multiplier, $arg, '*', 'arrayTimesEquals', $stack); } } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { @@ -3374,7 +3728,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $matches[2] = trim($matches[2], "\"'"); if ((strpos($matches[2], '[') !== false) || (strpos($matches[2], ']') !== false)) { // It's a Reference to an external workbook (not currently supported) - return $this->_raiseFormulaError('Unable to access External Workbook'); + return $this->raiseFormulaError('Unable to access External Workbook'); } $matches[2] = trim($matches[2], "\"'"); // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; @@ -3382,7 +3736,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel if ($pCellParent !== null) { $cellValue = $this->extractCellRange($cellRef, $this->workbook->getSheetByName($matches[2]), false); } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); + return $this->raiseFormulaError('Unable to access Cell Reference'); } $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); // $cellRef = $matches[2].'!'.$cellRef; @@ -3392,7 +3746,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel if ($pCellParent !== null) { $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, false); } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); + return $this->raiseFormulaError('Unable to access Cell Reference'); } $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); } @@ -3408,7 +3762,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $matches[2] = trim($matches[2], "\"'"); if ((strpos($matches[2], '[') !== false) || (strpos($matches[2], ']') !== false)) { // It's a Reference to an external workbook (not currently supported) - return $this->_raiseFormulaError('Unable to access External Workbook'); + return $this->raiseFormulaError('Unable to access External Workbook'); } // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />'; $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); @@ -3421,7 +3775,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $cellValue = null; } } else { - return $this->_raiseFormulaError('Unable to access Cell Reference'); + return $this->raiseFormulaError('Unable to access Cell Reference'); } $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); // $cellRef = $matches[2].'!'.$cellRef; @@ -3564,13 +3918,13 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); $stack->push('Named Range', $cellValue, $namedRange); } else { - return $this->_raiseFormulaError("undefined variable '$token'"); + return $this->raiseFormulaError("undefined variable '$token'"); } } } // when we're out of tokens, the stack should have a single element, the final result if ($stack->count() != 1) { - return $this->_raiseFormulaError("internal error"); + return $this->raiseFormulaError("internal error"); } $output = $stack->pop(); $output = $output['value']; @@ -3582,7 +3936,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } - private function _validateBinaryOperand($cellID, &$operand, &$stack) + private function validateBinaryOperand($cellID, &$operand, &$stack) { if (is_array($operand)) { if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { @@ -3619,7 +3973,7 @@ private function _validateBinaryOperand($cellID, &$operand, &$stack) } - private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays = false) + private function executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays = false) { // If we're dealing with matrix operations, we want a matrix result if ((is_array($operand1)) || (is_array($operand2))) { @@ -3627,14 +3981,14 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 if ((is_array($operand1)) && (!is_array($operand2))) { foreach ($operand1 as $x => $operandData) { $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); - $this->_executeBinaryComparisonOperation($cellID, $operandData, $operand2, $operation, $stack); + $this->executeBinaryComparisonOperation($cellID, $operandData, $operand2, $operation, $stack); $r = $stack->pop(); $result[$x] = $r['value']; } } elseif ((!is_array($operand1)) && (is_array($operand2))) { foreach ($operand2 as $x => $operandData) { $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); - $this->_executeBinaryComparisonOperation($cellID, $operand1, $operandData, $operation, $stack); + $this->executeBinaryComparisonOperation($cellID, $operand1, $operandData, $operation, $stack); $r = $stack->pop(); $result[$x] = $r['value']; } @@ -3644,7 +3998,7 @@ private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2 } foreach ($operand1 as $x => $operandData) { $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); - $this->_executeBinaryComparisonOperation($cellID, $operandData, $operand2[$x], $operation, $stack, true); + $this->executeBinaryComparisonOperation($cellID, $operandData, $operand2[$x], $operation, $stack, true); $r = $stack->pop(); $result[$x] = $r['value']; } @@ -3753,13 +4107,13 @@ private function strcmpLowercaseFirst($str1, $str2) return strcmp($inversedStr1, $inversedStr2); } - private function _executeNumericBinaryOperation($cellID, $operand1, $operand2, $operation, $matrixFunction, &$stack) + private function executeNumericBinaryOperation($cellID, $operand1, $operand2, $operation, $matrixFunction, &$stack) { // Validate the two operands - if (!$this->_validateBinaryOperand($cellID, $operand1, $stack)) { + if (!$this->validateBinaryOperand($cellID, $operand1, $stack)) { return false; } - if (!$this->_validateBinaryOperand($cellID, $operand2, $stack)) { + if (!$this->validateBinaryOperand($cellID, $operand2, $stack)) { return false; } @@ -3828,7 +4182,7 @@ private function _executeNumericBinaryOperation($cellID, $operand1, $operand2, $ // trigger an error, but nicely, if need be - protected function _raiseFormulaError($errorMessage) + protected function raiseFormulaError($errorMessage) { $this->formulaError = $errorMessage; $this->cyclicReferenceStack->clear(); diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 6b60f3f01..a7272e470 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -1,7 +1,15 @@ <?php +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + /** - * PHPExcel + * PHPExcel_Reader_HTML * * Copyright (c) 2006 - 2015 PHPExcel * @@ -26,21 +34,6 @@ * @version ##VERSION##, ##DATE## */ /** PHPExcel root directory */ -if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); -} - -/** - * PHPExcel_Reader_HTML - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_HTML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { @@ -120,12 +113,12 @@ protected function _isValidFormat() { // Reading 2048 bytes should be enough to validate that the format is HTML $data = fread($this->_fileHandle, 2048); - if ((strpos($data, '<') !== FALSE) && + if ((strpos($data, '<') !== false) && (strlen($data) !== strlen(strip_tags($data)))) { - return TRUE; + return true; } - return FALSE; + return false; } /** @@ -173,8 +166,9 @@ public function getInputEncoding() protected function _setTableStartColumn($column) { - if ($this->_tableLevel == 0) + if ($this->_tableLevel == 0) { $column = 'A'; + } ++$this->_tableLevel; $this->_nestedColumn[$this->_tableLevel] = $column; @@ -235,7 +229,7 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, } switch ($child->nodeName) { - case 'meta' : + case 'meta': foreach ($attributeArray as $attributeName => $attributeValue) { switch ($attributeName) { case 'content': @@ -246,27 +240,29 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, } $this->_processDomElement($child, $sheet, $row, $column, $cellContent); break; - case 'title' : + case 'title': $this->_processDomElement($child, $sheet, $row, $column, $cellContent); $sheet->setTitle($cellContent); $cellContent = ''; break; - case 'span' : - case 'div' : - case 'font' : - case 'i' : - case 'em' : + case 'span': + case 'div': + case 'font': + case 'i': + case 'em': case 'strong': - case 'b' : + case 'b': // echo 'STYLING, SPAN OR DIV<br />'; - if ($cellContent > '') + if ($cellContent > '') { $cellContent .= ' '; + } $this->_processDomElement($child, $sheet, $row, $column, $cellContent); - if ($cellContent > '') + if ($cellContent > '') { $cellContent .= ' '; + } // echo 'END OF STYLING, SPAN OR DIV<br />'; break; - case 'hr' : + case 'hr': $this->_flushCell($sheet, $column, $row, $cellContent); ++$row; if (isset($this->_formats[$child->nodeName])) { @@ -276,7 +272,7 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, $this->_flushCell($sheet, $column, $row, $cellContent); } ++$row; - case 'br' : + case 'br': if ($this->_tableLevel > 0) { // If we're inside a table, replace with a \n $cellContent .= "\n"; @@ -287,7 +283,7 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, } // echo 'HARD LINE BREAK: ' , '<br />'; break; - case 'a' : + case 'a': // echo 'START OF HYPERLINK: ' , '<br />'; foreach ($attributeArray as $attributeName => $attributeValue) { switch ($attributeName) { @@ -304,15 +300,15 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, $this->_processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF HYPERLINK:' , '<br />'; break; - case 'h1' : - case 'h2' : - case 'h3' : - case 'h4' : - case 'h5' : - case 'h6' : - case 'ol' : - case 'ul' : - case 'p' : + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + case 'ol': + case 'ul': + case 'p': if ($this->_tableLevel > 0) { // If we're inside a table, replace with a \n $cellContent .= "\n"; @@ -337,7 +333,7 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, $column = 'A'; } break; - case 'li' : + case 'li': if ($this->_tableLevel > 0) { // If we're inside a table, replace with a \n $cellContent .= "\n"; @@ -356,12 +352,13 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, $column = 'A'; } break; - case 'table' : + case 'table': $this->_flushCell($sheet, $column, $row, $cellContent); $column = $this->_setTableStartColumn($column); // echo 'START OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; - if ($this->_tableLevel > 1) + if ($this->_tableLevel > 1) { --$row; + } $this->_processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; $column = $this->_releaseTableStartColumn(); @@ -371,11 +368,11 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, ++$row; } break; - case 'thead' : - case 'tbody' : + case 'thead': + case 'tbody': $this->_processDomElement($child, $sheet, $row, $column, $cellContent); break; - case 'tr' : + case 'tr': $column = $this->_getTableStartColumn(); $cellContent = ''; // echo 'START OF TABLE ' , $this->_tableLevel , ' ROW<br />'; @@ -383,8 +380,8 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, ++$row; // echo 'END OF TABLE ' , $this->_tableLevel , ' ROW<br />'; break; - case 'th' : - case 'td' : + case 'th': + case 'td': // echo 'START OF TABLE ' , $this->_tableLevel , ' CELL<br />'; $this->_processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF TABLE ' , $this->_tableLevel , ' CELL<br />'; @@ -433,7 +430,7 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, } ++$column; break; - case 'body' : + case 'body': $row = 1; $column = 'A'; $content = ''; @@ -476,7 +473,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $dom = new domDocument; // Reload the HTML file into the DOM object $loaded = $dom->loadHTML($this->securityScanFile($pFilename)); - if ($loaded === FALSE) { + if ($loaded === false) { throw new PHPExcel_Reader_Exception('Failed to load ', $pFilename, ' as a DOM Document'); } @@ -524,11 +521,9 @@ public function setSheetIndex($pValue = 0) public function securityScan($xml) { $pattern = '/\\0?' . implode('\\0?', str_split('<!ENTITY')) . '\\0?/'; - if (preg_match($pattern, $xml)) { + if (preg_match($pattern, $xml)) { throw new PHPExcel_Reader_Exception('Detected use of ENTITY in XML, spreadsheet file load() aborted to prevent XXE/XEE attacks'); } return $xml; } - } - From 9140e3da2e4178bd6015d579ccd7ba6c7f41cbff Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sun, 17 May 2015 11:22:28 +0200 Subject: [PATCH 380/467] PSR2 Fixes --- Classes/PHPExcel/Reader/CSV.php | 36 +- Classes/PHPExcel/Reader/DefaultReadFilter.php | 3 +- Classes/PHPExcel/Reader/Excel2003XML.php | 136 +- Classes/PHPExcel/Reader/Excel2007.php | 443 +- Classes/PHPExcel/Reader/Excel5.php | 4024 ++++++++++------- 5 files changed, 2793 insertions(+), 1849 deletions(-) diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index d4fefd581..c8c5fbb93 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -95,7 +95,8 @@ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_R /** * Create a new PHPExcel_Reader_CSV */ - public function __construct() { + public function __construct() + { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); } @@ -106,7 +107,7 @@ public function __construct() { */ protected function _isValidFormat() { - return TRUE; + return true; } /** @@ -175,7 +176,7 @@ public function listWorksheetInfo($pFilename) // Open file $this->_openFile($pFilename); if (!$this->_isValidFormat()) { - fclose ($this->_fileHandle); + fclose($this->_fileHandle); throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } $fileHandle = $this->_fileHandle; @@ -193,7 +194,7 @@ public function listWorksheetInfo($pFilename) $worksheetInfo[0]['totalColumns'] = 0; // Loop through each line of the file in turn - while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { + while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== false) { $worksheetInfo[0]['totalRows']++; $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1); } @@ -239,7 +240,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Open file $this->_openFile($pFilename); if (!$this->_isValidFormat()) { - fclose ($this->_fileHandle); + fclose($this->_fileHandle); throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } $fileHandle = $this->_fileHandle; @@ -264,7 +265,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } // Loop through each line of the file in turn - while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { + while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== false) { $columnLetter = 'A'; foreach ($rowData as $rowDatum) { if ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) { @@ -302,7 +303,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) * * @return string */ - public function getDelimiter() { + public function getDelimiter() + { return $this->_delimiter; } @@ -312,7 +314,8 @@ public function getDelimiter() { * @param string $pValue Delimiter, defaults to , * @return PHPExcel_Reader_CSV */ - public function setDelimiter($pValue = ',') { + public function setDelimiter($pValue = ',') + { $this->_delimiter = $pValue; return $this; } @@ -322,7 +325,8 @@ public function setDelimiter($pValue = ',') { * * @return string */ - public function getEnclosure() { + public function getEnclosure() + { return $this->_enclosure; } @@ -332,7 +336,8 @@ public function getEnclosure() { * @param string $pValue Enclosure, defaults to " * @return PHPExcel_Reader_CSV */ - public function setEnclosure($pValue = '"') { + public function setEnclosure($pValue = '"') + { if ($pValue == '') { $pValue = '"'; } @@ -345,7 +350,8 @@ public function setEnclosure($pValue = '"') { * * @return integer */ - public function getSheetIndex() { + public function getSheetIndex() + { return $this->_sheetIndex; } @@ -355,7 +361,8 @@ public function getSheetIndex() { * @param integer $pValue Sheet index * @return PHPExcel_Reader_CSV */ - public function setSheetIndex($pValue = 0) { + public function setSheetIndex($pValue = 0) + { $this->_sheetIndex = $pValue; return $this; } @@ -365,7 +372,7 @@ public function setSheetIndex($pValue = 0) { * * @param boolean $contiguous */ - public function setContiguous($contiguous = FALSE) + public function setContiguous($contiguous = false) { $this->_contiguous = (bool) $contiguous; if (!$contiguous) { @@ -380,8 +387,7 @@ public function setContiguous($contiguous = FALSE) * * @return boolean */ - public function getContiguous() { + public function getContiguous(){ return $this->_contiguous; } - } diff --git a/Classes/PHPExcel/Reader/DefaultReadFilter.php b/Classes/PHPExcel/Reader/DefaultReadFilter.php index 7caf26058..2e06dcbd4 100644 --- a/Classes/PHPExcel/Reader/DefaultReadFilter.php +++ b/Classes/PHPExcel/Reader/DefaultReadFilter.php @@ -52,7 +52,8 @@ class PHPExcel_Reader_DefaultReadFilter implements PHPExcel_Reader_IReadFilter * @param $worksheetName Optional worksheet name * @return boolean */ - public function readCell($column, $row, $worksheetName = '') { + public function readCell($column, $row, $worksheetName = '') + { return true; } } diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index e66ee1f1e..29720aa9d 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -239,7 +239,7 @@ public function load($pFilename) return $this->loadIntoExisting($pFilename, $objPHPExcel); } - protected static function identifyFixedStyleValue($styleList,&$styleAttributeValue) + protected static function identifyFixedStyleValue($styleList, &$styleAttributeValue) { $styleAttributeValue = strtolower($styleAttributeValue); foreach ($styleList as $style) { @@ -251,18 +251,18 @@ protected static function identifyFixedStyleValue($styleList,&$styleAttributeVal return false; } - /** - * pixel units to excel width units(units of 1/256th of a character width) - * @param pxs - * @return - */ - protected static function _pixel2WidthUnits($pxs) - { - $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); - - $widthUnits = 256 * ($pxs / 7); - $widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)]; - return $widthUnits; + /** + * pixel units to excel width units(units of 1/256th of a character width) + * @param pxs + * @return + */ + protected static function _pixel2WidthUnits($pxs) + { + $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); + + $widthUnits = 256 * ($pxs / 7); + $widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)]; + return $widthUnits; } /** @@ -337,39 +337,39 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if (isset($xml->DocumentProperties[0])) { foreach ($xml->DocumentProperties[0] as $propertyName => $propertyValue) { switch ($propertyName) { - case 'Title' : + case 'Title': $docProps->setTitle(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; - case 'Subject' : + case 'Subject': $docProps->setSubject(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; - case 'Author' : + case 'Author': $docProps->setCreator(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; - case 'Created' : + case 'Created': $creationDate = strtotime($propertyValue); $docProps->setCreated($creationDate); break; - case 'LastAuthor' : + case 'LastAuthor': $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; - case 'LastSaved' : + case 'LastSaved': $lastSaveDate = strtotime($propertyValue); $docProps->setModified($lastSaveDate); break; - case 'Company' : + case 'Company': $docProps->setCompany(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; - case 'Category' : + case 'Category': $docProps->setCategory(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; - case 'Manager' : + case 'Manager': $docProps->setManager(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; - case 'Keywords' : + case 'Keywords': $docProps->setKeywords(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; - case 'Description' : + case 'Description': $docProps->setDescription(self::_convertStringEncoding($propertyValue, $this->_charSet)); break; } @@ -378,26 +378,26 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if (isset($xml->CustomDocumentProperties)) { foreach ($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { $propertyAttributes = $propertyValue->attributes($namespaces['dt']); - $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/','PHPExcel_Reader_Excel2003XML::_hex2str', $propertyName); + $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/', 'PHPExcel_Reader_Excel2003XML::_hex2str', $propertyName); $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN; switch ((string) $propertyAttributes) { - case 'string' : + case 'string': $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; $propertyValue = trim($propertyValue); break; - case 'boolean' : + case 'boolean': $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; $propertyValue = (bool) $propertyValue; break; - case 'integer' : + case 'integer': $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_INTEGER; $propertyValue = intval($propertyValue); break; - case 'float' : + case 'float': $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; $propertyValue = floatval($propertyValue); break; - case 'dateTime.tz' : + case 'dateTime.tz': $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; $propertyValue = strtotime(trim($propertyValue)); break; @@ -419,46 +419,46 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $styleAttributes = $styleData->attributes($namespaces['ss']); // echo $styleType.'<br />'; switch ($styleType) { - case 'Alignment' : + case 'Alignment': foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; $styleAttributeValue = (string) $styleAttributeValue; switch ($styleAttributeKey) { - case 'Vertical' : + case 'Vertical': if (self::identifyFixedStyleValue($verticalAlignmentStyles, $styleAttributeValue)) { $this->_styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; } break; - case 'Horizontal' : + case 'Horizontal': if (self::identifyFixedStyleValue($horizontalAlignmentStyles, $styleAttributeValue)) { $this->_styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; } break; - case 'WrapText' : + case 'WrapText': $this->_styles[$styleID]['alignment']['wrap'] = true; break; } } break; - case 'Borders' : + case 'Borders': foreach ($styleData->Border as $borderStyle) { $borderAttributes = $borderStyle->attributes($namespaces['ss']); $thisBorder = array(); foreach ($borderAttributes as $borderStyleKey => $borderStyleValue) { // echo $borderStyleKey.' = '.$borderStyleValue.'<br />'; switch ($borderStyleKey) { - case 'LineStyle' : + case 'LineStyle': $thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; // $thisBorder['style'] = $borderStyleValue; break; - case 'Weight' : + case 'Weight': // $thisBorder['style'] = $borderStyleValue; break; - case 'Position' : + case 'Position': $borderPosition = strtolower($borderStyleValue); break; - case 'Color' : - $borderColour = substr($borderStyleValue,1); + case 'Color': + $borderColour = substr($borderStyleValue, 1); $thisBorder['color']['rgb'] = $borderColour; break; } @@ -470,27 +470,27 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } break; - case 'Font' : + case 'Font': foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; $styleAttributeValue = (string) $styleAttributeValue; switch ($styleAttributeKey) { - case 'FontName' : + case 'FontName': $this->_styles[$styleID]['font']['name'] = $styleAttributeValue; break; - case 'Size' : + case 'Size': $this->_styles[$styleID]['font']['size'] = $styleAttributeValue; break; - case 'Color' : - $this->_styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue,1); + case 'Color': + $this->_styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue, 1); break; - case 'Bold' : + case 'Bold': $this->_styles[$styleID]['font']['bold'] = true; break; - case 'Italic' : + case 'Italic': $this->_styles[$styleID]['font']['italic'] = true; break; - case 'Underline' : + case 'Underline': if (self::identifyFixedStyleValue($underlineStyles, $styleAttributeValue)) { $this->_styles[$styleID]['font']['underline'] = $styleAttributeValue; } @@ -498,22 +498,22 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } break; - case 'Interior' : + case 'Interior': foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; switch ($styleAttributeKey) { - case 'Color' : - $this->_styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue,1); + case 'Color': + $this->_styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue, 1); break; } } break; - case 'NumberFormat' : + case 'NumberFormat': foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; $styleAttributeValue = str_replace($fromFormats, $toFormats, $styleAttributeValue); switch ($styleAttributeValue) { - case 'Short Date' : + case 'Short Date': $styleAttributeValue = 'dd/mm/yyyy'; break; } @@ -522,7 +522,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } break; - case 'Protection' : + case 'Protection': foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; } @@ -555,7 +555,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in // formula cells... during the load, all formulae should be correct, and we're simply bringing // the worksheet name in line with the formula, not the reverse - $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + $objPHPExcel->getActiveSheet()->setTitle($worksheetName, false); } $columnID = 'A'; @@ -640,26 +640,26 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) const TYPE_INLINE = 'inlineStr'; const TYPE_ERROR = 'e'; */ - case 'String' : + case 'String': $cellValue = self::_convertStringEncoding($cellValue, $this->_charSet); $type = PHPExcel_Cell_DataType::TYPE_STRING; break; - case 'Number' : + case 'Number': $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; $cellValue = (float) $cellValue; if (floor($cellValue) == $cellValue) { $cellValue = (integer) $cellValue; } break; - case 'Boolean' : + case 'Boolean': $type = PHPExcel_Cell_DataType::TYPE_BOOL; $cellValue = ($cellValue != 0); break; - case 'DateTime' : + case 'DateTime': $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; $cellValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellValue)); break; - case 'Error' : + case 'Error': $type = PHPExcel_Cell_DataType::TYPE_ERROR; break; } @@ -669,15 +669,15 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo 'FORMULA<br />'; $type = PHPExcel_Cell_DataType::TYPE_FORMULA; $columnNumber = PHPExcel_Cell::columnIndexFromString($columnID); - if (substr($cellDataFormula,0,3) == 'of:') { - $cellDataFormula = substr($cellDataFormula,3); + if (substr($cellDataFormula, 0, 3) == 'of:') { + $cellDataFormula = substr($cellDataFormula, 3); // echo 'Before: ', $cellDataFormula,'<br />'; $temp = explode('"', $cellDataFormula); $key = false; foreach ($temp as &$value) { // Only replace in alternate array entries (i.e. non-quoted blocks) if ($key = !$key) { - $value = str_replace(array('[.','.',']'),'', $value); + $value = str_replace(array('[.', '.', ']'), '', $value); } } } else { @@ -688,7 +688,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($temp as &$value) { // Only replace in alternate array entries (i.e. non-quoted blocks) if ($key = !$key) { - preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences, PREG_SET_ORDER + PREG_OFFSET_CAPTURE); // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way // through the formula from left to right. Reversing means that we work right to left.through // the formula @@ -703,7 +703,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } // Bracketed R references are relative to the current row if ($rowReference{0} == '[') { - $rowReference = $rowID + trim($rowReference,'[]'); + $rowReference = $rowID + trim($rowReference, '[]'); } $columnReference = $cellReference[4][0]; // Empty C reference is the current column @@ -712,10 +712,10 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } // Bracketed C references are relative to the current column if ($columnReference{0} == '[') { - $columnReference = $columnNumber + trim($columnReference,'[]'); + $columnReference = $columnNumber + trim($columnReference, '[]'); } $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; - $value = substr_replace($value, $A1CellReference, $cellReference[0][1],strlen($cellReference[0][0])); + $value = substr_replace($value, $A1CellReference, $cellReference[0][1], strlen($cellReference[0][0])); } } } @@ -749,7 +749,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo $annotation,'<br />'; $annotation = strip_tags($node); // echo 'Annotation: ', $annotation,'<br />'; - $objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setAuthor(self::_convertStringEncoding($author , $this->_charSet))->setText($this->_parseRichText($annotation) ); + $objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setAuthor(self::_convertStringEncoding($author, $this->_charSet))->setText($this->_parseRichText($annotation)); } if (($cellIsSet) && (isset($cell_ss['StyleID']))) { diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 9e62a852e..f59d310a7 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -49,25 +49,24 @@ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPE * * @var PHPExcel_ReferenceHelper */ - private $_referenceHelper = NULL; + private $_referenceHelper = null; /** * PHPExcel_Reader_Excel2007_Theme instance * * @var PHPExcel_Reader_Excel2007_Theme */ - private static $_theme = NULL; - + private static $_theme = null; /** * Create a new PHPExcel_Reader_Excel2007 instance */ - public function __construct() { + public function __construct() + { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); } - /** * Can the current PHPExcel_Reader_IReader read the file? * @@ -85,7 +84,7 @@ public function canRead($pFilename) $zipClass = PHPExcel_Settings::getZipClass(); // Check if zip class exists -// if (!class_exists($zipClass, FALSE)) { +// if (!class_exists($zipClass, false)) { // throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); // } @@ -240,39 +239,39 @@ public function listWorksheetInfo($pFilename) return $worksheetInfo; } - - private static function _castToBool($c) { + private static function _castToBool($c) + { // echo 'Initial Cast to Boolean', PHP_EOL; - $value = isset($c->v) ? (string) $c->v : NULL; + $value = isset($c->v) ? (string) $c->v : null; if ($value == '0') { - return FALSE; + return false; } elseif ($value == '1') { - return TRUE; + return true; } else { return (bool)$c->v; } return $value; } // function _castToBool() - - private static function _castToError($c) { + private static function _castToError($c) + { // echo 'Initial Cast to Error', PHP_EOL; - return isset($c->v) ? (string) $c->v : NULL; + return isset($c->v) ? (string) $c->v : null; } // function _castToError() - - private static function _castToString($c) { + private static function _castToString($c) + { // echo 'Initial Cast to String, PHP_EOL; - return isset($c->v) ? (string) $c->v : NULL; + return isset($c->v) ? (string) $c->v : null; } // function _castToString() - - private function _castToFormula($c, $r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas, $castBaseType) { + private function _castToFormula($c, $r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas, $castBaseType) + { // echo 'Formula', PHP_EOL; // echo '$c->f is ', $c->f, PHP_EOL; - $cellDataType = 'f'; - $value = "={$c->f}"; - $calculatedValue = self::$castBaseType($c); + $cellDataType = 'f'; + $value = "={$c->f}"; + $calculatedValue = self::$castBaseType($c); // Shared formula? if (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') { @@ -287,9 +286,7 @@ private function _castToFormula($c, $r,&$cellDataType,&$value,&$calculatedValue, // echo 'SETTING NEW SHARED FORMULA', PHP_EOL; // echo 'Master is ', $r, PHP_EOL; // echo 'Formula is ', $value, PHP_EOL; - $sharedFormulas[$instance] = array( 'master' => $r, - 'formula' => $value - ); + $sharedFormulas[$instance] = array('master' => $r, 'formula' => $value); // echo 'New Shared Formula Array:', PHP_EOL; // print_r($sharedFormulas); } else { @@ -303,11 +300,7 @@ private function _castToFormula($c, $r,&$cellDataType,&$value,&$calculatedValue, $difference[0] = PHPExcel_Cell::columnIndexFromString($current[0]) - PHPExcel_Cell::columnIndexFromString($master[0]); $difference[1] = $current[1] - $master[1]; - $value = $this->_referenceHelper->updateFormulaReferences( $sharedFormulas[$instance]['formula'], - 'A1', - $difference[0], - $difference[1] - ); + $value = $this->_referenceHelper->updateFormulaReferences($sharedFormulas[$instance]['formula'], 'A1', $difference[0], $difference[1]); // echo 'Adjusted Formula is ', $value, PHP_EOL; } } @@ -317,16 +310,14 @@ private function _castToFormula($c, $r,&$cellDataType,&$value,&$calculatedValue, public function _getFromZipArchive($archive, $fileName = '') { // Root-relative paths - if (strpos($fileName, '//') !== false) - { + if (strpos($fileName, '//') !== false) { $fileName = substr($fileName, strpos($fileName, '//') + 1); } $fileName = PHPExcel_Shared_File::realpath($fileName); // Apache POI fixes $contents = $archive->getFromName($fileName); - if ($contents === false) - { + if ($contents === false) { $contents = $archive->getFromName(substr($fileName, 1)); } @@ -366,7 +357,7 @@ public function load($pFilename) foreach ($wbRels->Relationship as $rel) { switch ($rel["Type"]) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme": - $themeOrderArray = array('lt1','dk1','lt2','dk2'); + $themeOrderArray = array('lt1', 'dk1', 'lt2', 'dk2'); $themeOrderAdditional = count($themeOrderArray); $xmlTheme = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "xl/{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); @@ -419,19 +410,19 @@ public function load($pFilename) $docProps->setKeywords((string) self::array_item($xmlCore->xpath("cp:keywords"))); $docProps->setCategory((string) self::array_item($xmlCore->xpath("cp:category"))); } - break; - + break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties": $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { $docProps = $excel->getProperties(); - if (isset($xmlCore->Company)) + if (isset($xmlCore->Company)) { $docProps->setCompany((string) $xmlCore->Company); - if (isset($xmlCore->Manager)) + } + if (isset($xmlCore->Manager)) { $docProps->setManager((string) $xmlCore->Manager); + } } - break; - + break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties": $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { @@ -449,14 +440,14 @@ public function load($pFilename) } } } - break; + break; //Ribbon case "http://schemas.microsoft.com/office/2006/relationships/ui/extensibility": $customUI = $rel['Target']; if (!is_null($customUI)) { $this->_readRibbon($excel, $customUI, $zip); } - break; + break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": $dir = dirname($rel["Target"]); $relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); @@ -468,7 +459,7 @@ public function load($pFilename) if (isset($xmlStrings) && isset($xmlStrings->si)) { foreach ($xmlStrings->si as $val) { if (isset($val->t)) { - $sharedStrings[] = PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $val->t ); + $sharedStrings[] = PHPExcel_Shared_String::ControlCharacterOOXML2PHP((string) $val->t); } elseif (isset($val->r)) { $sharedStrings[] = $this->_parseRichText($val); } @@ -476,7 +467,7 @@ public function load($pFilename) } $worksheets = array(); - $macros = $customUI = NULL; + $macros = $customUI = null; foreach ($relsWorkbook->Relationship as $ele) { switch ($ele['Type']) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": @@ -496,8 +487,9 @@ public function load($pFilename) $excel->setHasMacros(true); //short-circuit : not reading vbaProject.bin.rel to get Signature =>allways vbaProjectSignature.bin in 'xl' dir $Certificate = $this->_getFromZipArchive($zip, 'xl/vbaProjectSignature.bin'); - if ($Certificate !== false) + if ($Certificate !== false) { $excel->setMacrosCertificate($Certificate); + } } } $styles = array(); @@ -508,7 +500,7 @@ public function load($pFilename) if ($xmlStyles && $xmlStyles->numFmts[0]) { $numFmts = $xmlStyles->numFmts[0]; } - if (isset($numFmts) && ($numFmts !== NULL)) { + if (isset($numFmts) && ($numFmts !== null)) { $numFmts->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); } if (!$this->_readDataOnly && $xmlStyles) { @@ -586,7 +578,7 @@ public function load($pFilename) // Conditional Styles if ($xmlStyles->dxfs) { foreach ($xmlStyles->dxfs->dxf as $dxf) { - $style = new PHPExcel_Style(FALSE, TRUE); + $style = new PHPExcel_Style(false, true); self::_readStyle($style, $dxf); $dxfs[] = $style; } @@ -624,7 +616,6 @@ public function load($pFilename) $countSkippedSheets = 0; // keep track of number of skipped sheets $mapSheetId = array(); // mapping of sheet ids from old to new - $charts = $chartDetails = array(); if ($xmlWorkbook->sheets) { @@ -655,37 +646,31 @@ public function load($pFilename) $sharedFormulas = array(); if (isset($eleSheet["state"]) && (string) $eleSheet["state"] != '') { - $docSheet->setSheetState( (string) $eleSheet["state"] ); + $docSheet->setSheetState((string) $eleSheet["state"]); } if (isset($xmlSheet->sheetViews) && isset($xmlSheet->sheetViews->sheetView)) { if (isset($xmlSheet->sheetViews->sheetView['zoomScale'])) { - $docSheet->getSheetView()->setZoomScale( intval($xmlSheet->sheetViews->sheetView['zoomScale']) ); + $docSheet->getSheetView()->setZoomScale(intval($xmlSheet->sheetViews->sheetView['zoomScale'])); } - if (isset($xmlSheet->sheetViews->sheetView['zoomScaleNormal'])) { - $docSheet->getSheetView()->setZoomScaleNormal( intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal']) ); + $docSheet->getSheetView()->setZoomScaleNormal(intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal'])); } - if (isset($xmlSheet->sheetViews->sheetView['view'])) { $docSheet->getSheetView()->setView((string) $xmlSheet->sheetViews->sheetView['view']); } - if (isset($xmlSheet->sheetViews->sheetView['showGridLines'])) { $docSheet->setShowGridLines(self::boolean((string)$xmlSheet->sheetViews->sheetView['showGridLines'])); } - if (isset($xmlSheet->sheetViews->sheetView['showRowColHeaders'])) { $docSheet->setShowRowColHeaders(self::boolean((string)$xmlSheet->sheetViews->sheetView['showRowColHeaders'])); } - if (isset($xmlSheet->sheetViews->sheetView['rightToLeft'])) { $docSheet->setRightToLeft(self::boolean((string)$xmlSheet->sheetViews->sheetView['rightToLeft'])); } - if (isset($xmlSheet->sheetViews->sheetView->pane)) { if (isset($xmlSheet->sheetViews->sheetView->pane['topLeftCell'])) { - $docSheet->freezePane( (string)$xmlSheet->sheetViews->sheetView->pane['topLeftCell'] ); + $docSheet->freezePane((string)$xmlSheet->sheetViews->sheetView->pane['topLeftCell']); } else { $xSplit = 0; $ySplit = 0; @@ -710,12 +695,11 @@ public function load($pFilename) $docSheet->setSelectedCells($sqref); } } - } if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->tabColor)) { if (isset($xmlSheet->sheetPr->tabColor['rgb'])) { - $docSheet->getTabColor()->setARGB( (string)$xmlSheet->sheetPr->tabColor['rgb'] ); + $docSheet->getTabColor()->setARGB((string)$xmlSheet->sheetPr->tabColor['rgb']); } } if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr['codeName'])) { @@ -724,25 +708,25 @@ public function load($pFilename) if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->outlinePr)) { if (isset($xmlSheet->sheetPr->outlinePr['summaryRight']) && !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryRight'])) { - $docSheet->setShowSummaryRight(FALSE); + $docSheet->setShowSummaryRight(false); } else { - $docSheet->setShowSummaryRight(TRUE); + $docSheet->setShowSummaryRight(true); } if (isset($xmlSheet->sheetPr->outlinePr['summaryBelow']) && !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryBelow'])) { - $docSheet->setShowSummaryBelow(FALSE); + $docSheet->setShowSummaryBelow(false); } else { - $docSheet->setShowSummaryBelow(TRUE); + $docSheet->setShowSummaryBelow(true); } } if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->pageSetUpPr)) { if (isset($xmlSheet->sheetPr->pageSetUpPr['fitToPage']) && !self::boolean((string) $xmlSheet->sheetPr->pageSetUpPr['fitToPage'])) { - $docSheet->getPageSetup()->setFitToPage(FALSE); + $docSheet->getPageSetup()->setFitToPage(false); } else { - $docSheet->getPageSetup()->setFitToPage(TRUE); + $docSheet->getPageSetup()->setFitToPage(true); } } @@ -750,10 +734,10 @@ public function load($pFilename) if (isset($xmlSheet->sheetFormatPr['customHeight']) && self::boolean((string) $xmlSheet->sheetFormatPr['customHeight']) && isset($xmlSheet->sheetFormatPr['defaultRowHeight'])) { - $docSheet->getDefaultRowDimension()->setRowHeight( (float)$xmlSheet->sheetFormatPr['defaultRowHeight'] ); + $docSheet->getDefaultRowDimension()->setRowHeight((float)$xmlSheet->sheetFormatPr['defaultRowHeight']); } if (isset($xmlSheet->sheetFormatPr['defaultColWidth'])) { - $docSheet->getDefaultColumnDimension()->setWidth( (float)$xmlSheet->sheetFormatPr['defaultColWidth'] ); + $docSheet->getDefaultColumnDimension()->setWidth((float)$xmlSheet->sheetFormatPr['defaultColWidth']); } if (isset($xmlSheet->sheetFormatPr['zeroHeight']) && ((string)$xmlSheet->sheetFormatPr['zeroHeight'] == '1')) { @@ -768,14 +752,14 @@ public function load($pFilename) $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setXfIndex(intval($col["style"])); } if (self::boolean($col["bestFit"])) { - //$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(TRUE); + //$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(true); } if (self::boolean($col["hidden"])) { - // echo PHPExcel_Cell::stringFromColumnIndex($i),': HIDDEN COLUMN',PHP_EOL; - $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(FALSE); + // echo PHPExcel_Cell::stringFromColumnIndex($i), ': HIDDEN COLUMN',PHP_EOL; + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(false); } if (self::boolean($col["collapsed"])) { - $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setCollapsed(TRUE); + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setCollapsed(true); } if ($col["outlineLevel"] > 0) { $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setOutlineLevel(intval($col["outlineLevel"])); @@ -791,18 +775,16 @@ public function load($pFilename) if (isset($xmlSheet->printOptions) && !$this->_readDataOnly) { if (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) { - $docSheet->setShowGridlines(TRUE); + $docSheet->setShowGridlines(true); } - if (self::boolean((string) $xmlSheet->printOptions['gridLines'])) { - $docSheet->setPrintGridlines(TRUE); + $docSheet->setPrintGridlines(true); } - if (self::boolean((string) $xmlSheet->printOptions['horizontalCentered'])) { - $docSheet->getPageSetup()->setHorizontalCentered(TRUE); + $docSheet->getPageSetup()->setHorizontalCentered(true); } if (self::boolean((string) $xmlSheet->printOptions['verticalCentered'])) { - $docSheet->getPageSetup()->setVerticalCentered(TRUE); + $docSheet->getPageSetup()->setVerticalCentered(true); } } @@ -812,10 +794,10 @@ public function load($pFilename) $docSheet->getRowDimension(intval($row["r"]))->setRowHeight(floatval($row["ht"])); } if (self::boolean($row["hidden"]) && !$this->_readDataOnly) { - $docSheet->getRowDimension(intval($row["r"]))->setVisible(FALSE); + $docSheet->getRowDimension(intval($row["r"]))->setVisible(false); } if (self::boolean($row["collapsed"])) { - $docSheet->getRowDimension(intval($row["r"]))->setCollapsed(TRUE); + $docSheet->getRowDimension(intval($row["r"]))->setCollapsed(true); } if ($row["outlineLevel"] > 0) { $docSheet->getRowDimension(intval($row["r"]))->setOutlineLevel(intval($row["outlineLevel"])); @@ -831,7 +813,7 @@ public function load($pFilename) $calculatedValue = null; // Read cell? - if ($this->getReadFilter() !== NULL) { + if ($this->getReadFilter() !== null) { $coordinates = PHPExcel_Cell::coordinateFromString($r); if (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) { @@ -857,7 +839,6 @@ public function load($pFilename) } else { $value = ''; } - break; case "b": // echo 'Boolean', PHP_EOL; @@ -865,7 +846,7 @@ public function load($pFilename) $value = self::_castToBool($c); } else { // Formula - $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas,'_castToBool'); + $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, '_castToBool'); if (isset($c->f['t'])) { $att = array(); $att = $c->f; @@ -877,7 +858,6 @@ public function load($pFilename) case "inlineStr": // echo 'Inline String', PHP_EOL; $value = $this->_parseRichText($c->is); - break; case "e": // echo 'Error', PHP_EOL; @@ -885,12 +865,10 @@ public function load($pFilename) $value = self::_castToError($c); } else { // Formula - $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas,'_castToError'); + $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, '_castToError'); // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; } - break; - default: // echo 'Default', PHP_EOL; if (!isset($c->f)) { @@ -899,10 +877,9 @@ public function load($pFilename) } else { // echo 'Treat as Formula', PHP_EOL; // Formula - $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas,'_castToString'); + $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, '_castToString'); // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; } - break; } // echo 'Value is ', $value, PHP_EOL; @@ -926,7 +903,7 @@ public function load($pFilename) } else { $cell->setValue($value); } - if ($calculatedValue !== NULL) { + if ($calculatedValue !== null) { $cell->setCalculatedValue($calculatedValue); } @@ -997,7 +974,7 @@ public function load($pFilename) } if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { - $docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection["password"], TRUE); + $docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection["password"], true); if ($xmlSheet->protectedRanges->protectedRange) { foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) { $docSheet->protectCells((string) $protectedRange["sqref"], (string) $protectedRange["password"], true); @@ -1019,7 +996,7 @@ public function load($pFilename) $filters = $filterColumn->filters; if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL + null, // Operator is undefined, but always treated as EQUAL '' ) ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); @@ -1028,7 +1005,7 @@ public function load($pFilename) // Entries can be either filter elements foreach ($filters->filter as $filterRule) { $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL + null, // Operator is undefined, but always treated as EQUAL (string) $filterRule["val"] ) ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); @@ -1036,7 +1013,7 @@ public function load($pFilename) // Or Date Group elements foreach ($filters->dateGroupItem as $dateGroupItem) { $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL + null, // Operator is undefined, but always treated as EQUAL array( 'year' => (string) $dateGroupItem["year"], 'month' => (string) $dateGroupItem["month"], @@ -1073,7 +1050,7 @@ public function load($pFilename) // We should only ever have one dynamic filter foreach ($filterColumn->dynamicFilter as $filterRule) { $column->createRule()->setRule( - NULL, // Operator is undefined, but always treated as EQUAL + null, // Operator is undefined, but always treated as EQUAL (string) $filterRule["val"], (string) $filterRule["type"] ) @@ -1112,7 +1089,7 @@ public function load($pFilename) if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) { foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) { $mergeRef = (string) $mergeCell["ref"]; - if (strpos($mergeRef,':') !== FALSE) { + if (strpos($mergeRef, ':') !== false) { $docSheet->mergeCells((string) $mergeCell["ref"]); } } @@ -1138,13 +1115,13 @@ public function load($pFilename) $docPageSetup->setPaperSize(intval($xmlSheet->pageSetup["paperSize"])); } if (isset($xmlSheet->pageSetup["scale"])) { - $docPageSetup->setScale(intval($xmlSheet->pageSetup["scale"]), FALSE); + $docPageSetup->setScale(intval($xmlSheet->pageSetup["scale"]), false); } if (isset($xmlSheet->pageSetup["fitToHeight"]) && intval($xmlSheet->pageSetup["fitToHeight"]) >= 0) { - $docPageSetup->setFitToHeight(intval($xmlSheet->pageSetup["fitToHeight"]), FALSE); + $docPageSetup->setFitToHeight(intval($xmlSheet->pageSetup["fitToHeight"]), false); } if (isset($xmlSheet->pageSetup["fitToWidth"]) && intval($xmlSheet->pageSetup["fitToWidth"]) >= 0) { - $docPageSetup->setFitToWidth(intval($xmlSheet->pageSetup["fitToWidth"]), FALSE); + $docPageSetup->setFitToWidth(intval($xmlSheet->pageSetup["fitToWidth"]), false); } if (isset($xmlSheet->pageSetup["firstPageNumber"]) && isset($xmlSheet->pageSetup["useFirstPageNumber"]) && self::boolean((string) $xmlSheet->pageSetup["useFirstPageNumber"])) { @@ -1157,27 +1134,27 @@ public function load($pFilename) if (isset($xmlSheet->headerFooter["differentOddEven"]) && self::boolean((string)$xmlSheet->headerFooter["differentOddEven"])) { - $docHeaderFooter->setDifferentOddEven(TRUE); + $docHeaderFooter->setDifferentOddEven(true); } else { - $docHeaderFooter->setDifferentOddEven(FALSE); + $docHeaderFooter->setDifferentOddEven(false); } if (isset($xmlSheet->headerFooter["differentFirst"]) && self::boolean((string)$xmlSheet->headerFooter["differentFirst"])) { - $docHeaderFooter->setDifferentFirst(TRUE); + $docHeaderFooter->setDifferentFirst(true); } else { - $docHeaderFooter->setDifferentFirst(FALSE); + $docHeaderFooter->setDifferentFirst(false); } if (isset($xmlSheet->headerFooter["scaleWithDoc"]) && !self::boolean((string)$xmlSheet->headerFooter["scaleWithDoc"])) { - $docHeaderFooter->setScaleWithDocument(FALSE); + $docHeaderFooter->setScaleWithDocument(false); } else { - $docHeaderFooter->setScaleWithDocument(TRUE); + $docHeaderFooter->setScaleWithDocument(true); } if (isset($xmlSheet->headerFooter["alignWithMargins"]) && !self::boolean((string)$xmlSheet->headerFooter["alignWithMargins"])) { - $docHeaderFooter->setAlignWithMargins(FALSE); + $docHeaderFooter->setAlignWithMargins(false); } else { - $docHeaderFooter->setAlignWithMargins(TRUE); + $docHeaderFooter->setAlignWithMargins(true); } $docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader); @@ -1254,7 +1231,7 @@ public function load($pFilename) $linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'); foreach (PHPExcel_Cell::extractAllCellReferencesInRange($hyperlink['ref']) as $cellReference) { - $cell = $docSheet->getCell( $cellReference ); + $cell = $docSheet->getCell($cellReference); if (isset($linkRel['id'])) { $hyperlinkUrl = $hyperlinks[ (string)$linkRel['id'] ]; if (isset($hyperlink['location'])) { @@ -1262,12 +1239,12 @@ public function load($pFilename) } $cell->getHyperlink()->setUrl($hyperlinkUrl); } elseif (isset($hyperlink['location'])) { - $cell->getHyperlink()->setUrl( 'sheet://' . (string)$hyperlink['location'] ); + $cell->getHyperlink()->setUrl('sheet://' . (string)$hyperlink['location']); } // Tooltip if (isset($hyperlink['tooltip'])) { - $cell->getHyperlink()->setTooltip( (string)$hyperlink['tooltip'] ); + $cell->getHyperlink()->setTooltip((string)$hyperlink['tooltip']); } } } @@ -1308,8 +1285,8 @@ public function load($pFilename) // Loop through contents foreach ($commentsFile->commentList->comment as $comment) { if (!empty($comment['authorId'])) - $docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] ); - $docSheet->getComment( (string)$comment['ref'] )->setText( $this->_parseRichText($comment->text) ); + $docSheet->getComment((string)$comment['ref'])->setAuthor($authors[(string)$comment['authorId']]); + $docSheet->getComment((string)$comment['ref'])->setText($this->_parseRichText($comment->text)); } } @@ -1326,7 +1303,7 @@ public function load($pFilename) if (isset($shape['style'])) { $style = (string)$shape['style']; - $fillColor = strtoupper( substr( (string)$shape['fillcolor'], 1 ) ); + $fillColor = strtoupper(substr((string)$shape['fillcolor'], 1)); $column = null; $row = null; @@ -1334,31 +1311,44 @@ public function load($pFilename) if (is_array($clientData) && !empty($clientData)) { $clientData = $clientData[0]; - if ( isset($clientData['ObjectType']) && (string)$clientData['ObjectType'] == 'Note' ) { + if (isset($clientData['ObjectType']) && (string)$clientData['ObjectType'] == 'Note') { $temp = $clientData->xpath('.//x:Row'); - if (is_array($temp)) $row = $temp[0]; + if (is_array($temp)) { + $row = $temp[0]; + } $temp = $clientData->xpath('.//x:Column'); - if (is_array($temp)) $column = $temp[0]; + if (is_array($temp)) { + $column = $temp[0]; + } } } - if (($column !== NULL) && ($row !== NULL)) { + if (($column !== null) && ($row !== null)) { // Set comment properties $comment = $docSheet->getCommentByColumnAndRow((string) $column, $row + 1); - $comment->getFillColor()->setRGB( $fillColor ); + $comment->getFillColor()->setRGB($fillColor); // Parse style $styleArray = explode(';', str_replace(' ', '', $style)); foreach ($styleArray as $stylePair) { $stylePair = explode(':', $stylePair); - if ($stylePair[0] == 'margin-left') $comment->setMarginLeft($stylePair[1]); - if ($stylePair[0] == 'margin-top') $comment->setMarginTop($stylePair[1]); - if ($stylePair[0] == 'width') $comment->setWidth($stylePair[1]); - if ($stylePair[0] == 'height') $comment->setHeight($stylePair[1]); - if ($stylePair[0] == 'visibility') $comment->setVisible( $stylePair[1] == 'visible' ); - + if ($stylePair[0] == 'margin-left') { + $comment->setMarginLeft($stylePair[1]); + } + if ($stylePair[0] == 'margin-top') { + $comment->setMarginTop($stylePair[1]); + } + if ($stylePair[0] == 'width') { + $comment->setWidth($stylePair[1]); + } + if ($stylePair[0] == 'height') { + $comment->setHeight($stylePair[1]); + } + if ($stylePair[0] == 'visibility') { + $comment->setVisible($stylePair[1] == 'visible'); + } } } } @@ -1400,11 +1390,11 @@ public function load($pFilename) $imageData = $imageData[$idx]; $imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office'); - $style = self::toCSSArray( (string)$shape['style'] ); + $style = self::toCSSArray((string)$shape['style']); $hfImages[ (string)$shape['id'] ] = new PHPExcel_Worksheet_HeaderFooterDrawing(); if (isset($imageData['title'])) { - $hfImages[ (string)$shape['id'] ]->setName( (string)$imageData['title'] ); + $hfImages[ (string)$shape['id'] ]->setName((string)$imageData['title']); } $hfImages[ (string)$shape['id'] ]->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $drawings[(string)$imageData['relid']], false); @@ -1446,9 +1436,10 @@ public function load($pFilename) $images[(string) $ele["Id"]] = self::dir_add($fileDrawing, $ele["Target"]); } elseif ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart") { if ($this->_includeCharts) { - $charts[self::dir_add($fileDrawing, $ele["Target"])] = array('id' => (string) $ele["Id"], - 'sheet' => $docSheet->getTitle() - ); + $charts[self::dir_add($fileDrawing, $ele["Target"])] = array( + 'id' => (string) $ele["Id"], + 'sheet' => $docSheet->getTitle() + ); } } } @@ -1537,19 +1528,18 @@ public function load($pFilename) $chartRef = $graphic->graphicData->children("http://schemas.openxmlformats.org/drawingml/2006/chart")->chart; $thisChart = (string) $chartRef->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"); - $chartDetails[$docSheet->getTitle().'!'.$thisChart] = - array( 'fromCoordinate' => $fromCoordinate, - 'fromOffsetX' => $fromOffsetX, - 'fromOffsetY' => $fromOffsetY, - 'toCoordinate' => $toCoordinate, - 'toOffsetX' => $toOffsetX, - 'toOffsetY' => $toOffsetY, - 'worksheetTitle' => $docSheet->getTitle() - ); + $chartDetails[$docSheet->getTitle().'!'.$thisChart] = array( + 'fromCoordinate' => $fromCoordinate, + 'fromOffsetX' => $fromOffsetX, + 'fromOffsetY' => $fromOffsetY, + 'toCoordinate' => $toCoordinate, + 'toOffsetX' => $toOffsetX, + 'toOffsetY' => $toOffsetY, + 'worksheetTitle' => $docSheet->getTitle() + ); } } } - } } } @@ -1560,14 +1550,14 @@ public function load($pFilename) // Extract range $extractedRange = (string)$definedName; $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); - if (($spos = strpos($extractedRange,'!')) !== false) { + if (($spos = strpos($extractedRange, '!')) !== false) { $extractedRange = substr($extractedRange,0, $spos).str_replace('$', '', substr($extractedRange, $spos)); } else { $extractedRange = str_replace('$', '', $extractedRange); } // Valid range? - if (stripos((string)$definedName, '#REF!') !== FALSE || $extractedRange == '') { + if (stripos((string)$definedName, '#REF!') !== false || $extractedRange == '') { continue; } @@ -1575,7 +1565,6 @@ public function load($pFilename) if ((string)$definedName['localSheetId'] != '' && (string)$definedName['localSheetId'] == $sheetId) { // Switch on type switch ((string)$definedName['name']) { - case '_xlnm._FilterDatabase': if ((string)$definedName['hidden'] !== '1') { $extractedRange = explode(',', $extractedRange); @@ -1587,7 +1576,6 @@ public function load($pFilename) } } break; - case '_xlnm.Print_Titles': // Split $extractedRange $extractedRange = explode(',', $extractedRange); @@ -1607,14 +1595,13 @@ public function load($pFilename) } } break; - case '_xlnm.Print_Area': $rangeSets = explode(',', $extractedRange); // FIXME: what if sheetname contains comma? $newRangeSets = array(); foreach ($rangeSets as $rangeSet) { $range = explode('!', $rangeSet); // FIXME: what if sheetname contains exclamation mark? $rangeSet = isset($range[1]) ? $range[1] : $range[0]; - if (strpos($rangeSet, ':') === FALSE) { + if (strpos($rangeSet, ':') === false) { $rangeSet = $rangeSet . ':' . $rangeSet; } $newRangeSets[] = str_replace('$', '', $rangeSet); @@ -1639,7 +1626,7 @@ public function load($pFilename) // Extract range $extractedRange = (string)$definedName; $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); - if (($spos = strpos($extractedRange,'!')) !== false) { + if (($spos = strpos($extractedRange, '!')) !== false) { $extractedRange = substr($extractedRange,0, $spos).str_replace('$', '', substr($extractedRange, $spos)); } else { $extractedRange = str_replace('$', '', $extractedRange); @@ -1655,12 +1642,10 @@ public function load($pFilename) // Local defined name // Switch on type switch ((string)$definedName['name']) { - case '_xlnm._FilterDatabase': case '_xlnm.Print_Titles': case '_xlnm.Print_Area': break; - default: if ($mapSheetId[(integer) $definedName['localSheetId']] !== null) { $range = explode('!', (string)$definedName); @@ -1670,7 +1655,7 @@ public function load($pFilename) if ($worksheet = $docSheet->getParent()->getSheetByName($range[0])) { $extractedRange = str_replace('$', '', $range[1]); $scope = $docSheet->getParent()->getSheet($mapSheetId[(integer) $definedName['localSheetId']]); - $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $worksheet, $extractedRange, true, $scope) ); + $excel->addNamedRange(new PHPExcel_NamedRange((string)$definedName['name'], $worksheet, $extractedRange, true, $scope)); } } } @@ -1680,9 +1665,9 @@ public function load($pFilename) // "Global" definedNames $locatedSheet = null; $extractedSheetName = ''; - if (strpos( (string)$definedName, '!' ) !== false) { + if (strpos((string)$definedName, '!') !== false) { // Extract sheet name - $extractedSheetName = PHPExcel_Worksheet::extractSheetTitle( (string)$definedName, true ); + $extractedSheetName = PHPExcel_Worksheet::extractSheetTitle((string)$definedName, true); $extractedSheetName = $extractedSheetName[0]; // Locate sheet @@ -1693,8 +1678,8 @@ public function load($pFilename) $extractedRange = isset($range[1]) ? $range[1] : $range[0]; } - if ($locatedSheet !== NULL) { - $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $locatedSheet, $extractedRange, false) ); + if ($locatedSheet !== null) { + $excel->addNamedRange(new PHPExcel_NamedRange((string)$definedName['name'], $locatedSheet, $extractedRange, false)); } } } @@ -1717,39 +1702,31 @@ public function load($pFilename) } break; } - } - if (!$this->_readDataOnly) { $contentTypes = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "[Content_Types].xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); foreach ($contentTypes->Override as $contentType) { switch ($contentType["ContentType"]) { case "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": if ($this->_includeCharts) { - $chartEntryRef = ltrim($contentType['PartName'],'/'); + $chartEntryRef = ltrim($contentType['PartName'], '/'); $chartElements = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $chartEntryRef)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef,'.xml')); + $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef, '.xml')); -// echo 'Chart ', $chartEntryRef,'<br />'; +// echo 'Chart ', $chartEntryRef, '<br />'; // var_dump($charts[$chartEntryRef]); // if (isset($charts[$chartEntryRef])) { $chartPositionRef = $charts[$chartEntryRef]['sheet'].'!'.$charts[$chartEntryRef]['id']; -// echo 'Position Ref ', $chartPositionRef,'<br />'; +// echo 'Position Ref ', $chartPositionRef, '<br />'; if (isset($chartDetails[$chartPositionRef])) { // var_dump($chartDetails[$chartPositionRef]); $excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart); $objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet'])); - $objChart->setTopLeftPosition( $chartDetails[$chartPositionRef]['fromCoordinate'], - $chartDetails[$chartPositionRef]['fromOffsetX'], - $chartDetails[$chartPositionRef]['fromOffsetY'] - ); - $objChart->setBottomRightPosition( $chartDetails[$chartPositionRef]['toCoordinate'], - $chartDetails[$chartPositionRef]['toOffsetX'], - $chartDetails[$chartPositionRef]['toOffsetY'] - ); + $objChart->setTopLeftPosition($chartDetails[$chartPositionRef]['fromCoordinate'], $chartDetails[$chartPositionRef]['fromOffsetX'], $chartDetails[$chartPositionRef]['fromOffsetY']); + $objChart->setBottomRightPosition($chartDetails[$chartPositionRef]['toCoordinate'], $chartDetails[$chartPositionRef]['toOffsetX'], $chartDetails[$chartPositionRef]['toOffsetY']); } } } @@ -1762,14 +1739,14 @@ public function load($pFilename) return $excel; } - - private static function _readColor($color, $background=FALSE) { + private static function _readColor($color, $background = false) + { if (isset($color["rgb"])) { return (string)$color["rgb"]; } else if (isset($color["indexed"])) { return PHPExcel_Style_Color::indexedColor($color["indexed"]-7, $background)->getARGB(); } else if (isset($color["theme"])) { - if (self::$_theme !== NULL) { + if (self::$_theme !== null) { $returnColour = self::$_theme->getColourByIndex((int)$color["theme"]); if (isset($color["tint"])) { $tintAdjust = (float) $color["tint"]; @@ -1785,8 +1762,8 @@ private static function _readColor($color, $background=FALSE) { return 'FF000000'; } - - private static function _readStyle($docStyle, $style) { + private static function _readStyle($docStyle, $style) + { // format code // if (isset($style->numFmt)) { // if (isset($style->numFmt['formatCode'])) { @@ -1837,8 +1814,8 @@ private static function _readStyle($docStyle, $style) { } $docStyle->getFill()->setRotation(floatval($gradientFill["degree"])); $gradientFill->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - $docStyle->getFill()->getStartColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color) ); - $docStyle->getFill()->getEndColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color) ); + $docStyle->getFill()->getStartColor()->setARGB(self::_readColor(self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color)); + $docStyle->getFill()->getEndColor()->setARGB(self::_readColor(self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color)); } elseif ($style->fill->patternFill) { $patternType = (string)$style->fill->patternFill["patternType"] != '' ? (string)$style->fill->patternFill["patternType"] : 'solid'; $docStyle->getFill()->setFillType($patternType); @@ -1888,8 +1865,8 @@ private static function _readStyle($docStyle, $style) { $docStyle->getAlignment()->setTextRotation(intval($textRotation)); $docStyle->getAlignment()->setWrapText(self::boolean((string) $style->alignment["wrapText"])); $docStyle->getAlignment()->setShrinkToFit(self::boolean((string) $style->alignment["shrinkToFit"])); - $docStyle->getAlignment()->setIndent( intval((string)$style->alignment["indent"]) > 0 ? intval((string)$style->alignment["indent"]) : 0 ); - $docStyle->getAlignment()->setReadorder( intval((string)$style->alignment["readingOrder"]) > 0 ? intval((string)$style->alignment["readingOrder"]) : 0 ); + $docStyle->getAlignment()->setIndent(intval((string)$style->alignment["indent"]) > 0 ? intval((string)$style->alignment["indent"]) : 0); + $docStyle->getAlignment()->setReadorder(intval((string)$style->alignment["readingOrder"]) > 0 ? intval((string)$style->alignment["readingOrder"]) : 0); } // protection @@ -1917,8 +1894,8 @@ private static function _readStyle($docStyle, $style) { } } - - private static function _readBorder($docBorder, $eleBorder) { + private static function _readBorder($docBorder, $eleBorder) + { if (isset($eleBorder["style"])) { $docBorder->setBorderStyle((string) $eleBorder["style"]); } @@ -1927,66 +1904,59 @@ private static function _readBorder($docBorder, $eleBorder) { } } - - private function _parseRichText($is = null) { + private function _parseRichText($is = null) + { $value = new PHPExcel_RichText(); if (isset($is->t)) { - $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $is->t ) ); + $value->createText(PHPExcel_Shared_String::ControlCharacterOOXML2PHP((string) $is->t)); } else { if (is_object($is->r)) { - foreach ($is->r as $run) { - if (!isset($run->rPr)) { - $objText = $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); - - } else { - $objText = $value->createTextRun( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); - - if (isset($run->rPr->rFont["val"])) { - $objText->getFont()->setName((string) $run->rPr->rFont["val"]); - } - - if (isset($run->rPr->sz["val"])) { - $objText->getFont()->setSize((string) $run->rPr->sz["val"]); - } + foreach ($is->r as $run) { + if (!isset($run->rPr)) { + $objText = $value->createText(PHPExcel_Shared_String::ControlCharacterOOXML2PHP((string) $run->t)); - if (isset($run->rPr->color)) { - $objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($run->rPr->color) ) ); - } - - if ((isset($run->rPr->b["val"]) && self::boolean((string) $run->rPr->b["val"])) || - (isset($run->rPr->b) && !isset($run->rPr->b["val"]))) { - $objText->getFont()->setBold(TRUE); - } + } else { + $objText = $value->createTextRun(PHPExcel_Shared_String::ControlCharacterOOXML2PHP((string) $run->t)); - if ((isset($run->rPr->i["val"]) && self::boolean((string) $run->rPr->i["val"])) || - (isset($run->rPr->i) && !isset($run->rPr->i["val"]))) { - $objText->getFont()->setItalic(TRUE); - } - - if (isset($run->rPr->vertAlign) && isset($run->rPr->vertAlign["val"])) { - $vertAlign = strtolower((string)$run->rPr->vertAlign["val"]); - if ($vertAlign == 'superscript') { - $objText->getFont()->setSuperScript(TRUE); + if (isset($run->rPr->rFont["val"])) { + $objText->getFont()->setName((string) $run->rPr->rFont["val"]); } - if ($vertAlign == 'subscript') { - $objText->getFont()->setSubScript(TRUE); + if (isset($run->rPr->sz["val"])) { + $objText->getFont()->setSize((string) $run->rPr->sz["val"]); + } + if (isset($run->rPr->color)) { + $objText->getFont()->setColor(new PHPExcel_Style_Color(self::_readColor($run->rPr->color))); + } + if ((isset($run->rPr->b["val"]) && self::boolean((string) $run->rPr->b["val"])) || + (isset($run->rPr->b) && !isset($run->rPr->b["val"]))) { + $objText->getFont()->setBold(true); + } + if ((isset($run->rPr->i["val"]) && self::boolean((string) $run->rPr->i["val"])) || + (isset($run->rPr->i) && !isset($run->rPr->i["val"]))) { + $objText->getFont()->setItalic(true); + } + if (isset($run->rPr->vertAlign) && isset($run->rPr->vertAlign["val"])) { + $vertAlign = strtolower((string)$run->rPr->vertAlign["val"]); + if ($vertAlign == 'superscript') { + $objText->getFont()->setSuperScript(true); + } + if ($vertAlign == 'subscript') { + $objText->getFont()->setSubScript(true); + } + } + if (isset($run->rPr->u) && !isset($run->rPr->u["val"])) { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } else if (isset($run->rPr->u) && isset($run->rPr->u["val"])) { + $objText->getFont()->setUnderline((string)$run->rPr->u["val"]); + } + if ((isset($run->rPr->strike["val"]) && self::boolean((string) $run->rPr->strike["val"])) || + (isset($run->rPr->strike) && !isset($run->rPr->strike["val"]))) { + $objText->getFont()->setStrikethrough(true); } - } - - if (isset($run->rPr->u) && !isset($run->rPr->u["val"])) { - $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); - } else if (isset($run->rPr->u) && isset($run->rPr->u["val"])) { - $objText->getFont()->setUnderline((string)$run->rPr->u["val"]); - } - - if ((isset($run->rPr->strike["val"]) && self::boolean((string) $run->rPr->strike["val"])) || - (isset($run->rPr->strike) && !isset($run->rPr->strike["val"]))) { - $objText->getFont()->setStrikethrough(TRUE); } } } - } } return $value; @@ -2022,25 +1992,26 @@ private function _readRibbon($excel, $customUITarget, $zip) if (count($customUIImagesNames) > 0 && count($customUIImagesBinaries) > 0) { $excel->setRibbonBinObjects($customUIImagesNames, $customUIImagesBinaries); } else { - $excel->setRibbonBinObjects(NULL); + $excel->setRibbonBinObjects(null); } } else { - $excel->setRibbonXMLData(NULL); - $excel->setRibbonBinObjects(NULL); + $excel->setRibbonXMLData(null); + $excel->setRibbonBinObjects(null); } } - private static function array_item($array, $key = 0) { + private static function array_item($array, $key = 0) + { return (isset($array[$key]) ? $array[$key] : null); } - - private static function dir_add($base, $add) { + private static function dir_add($base, $add) + { return preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add"); } - - private static function toCSSArray($style) { + private static function toCSSArray($style) + { $style = str_replace(array("\r","\n"), "", $style); $temp = explode(';', $style); @@ -2070,7 +2041,7 @@ private static function toCSSArray($style) { return $style; } - private static function boolean($value = NULL) + private static function boolean($value = null) { if (is_object($value)) { $value = (string) $value; diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 9b27b965d..15fa11b77 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -78,94 +78,94 @@ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { // ParseXL definitions - const XLS_BIFF8 = 0x0600; - const XLS_BIFF7 = 0x0500; - const XLS_WorkbookGlobals = 0x0005; - const XLS_Worksheet = 0x0010; + const XLS_BIFF8 = 0x0600; + const XLS_BIFF7 = 0x0500; + const XLS_WorkbookGlobals = 0x0005; + const XLS_Worksheet = 0x0010; // record identifiers - const XLS_Type_FORMULA = 0x0006; - const XLS_Type_EOF = 0x000a; - const XLS_Type_PROTECT = 0x0012; + const XLS_Type_FORMULA = 0x0006; + const XLS_Type_EOF = 0x000a; + const XLS_Type_PROTECT = 0x0012; const XLS_Type_OBJECTPROTECT = 0x0063; - const XLS_Type_SCENPROTECT = 0x00dd; - const XLS_Type_PASSWORD = 0x0013; - const XLS_Type_HEADER = 0x0014; - const XLS_Type_FOOTER = 0x0015; - const XLS_Type_EXTERNSHEET = 0x0017; - const XLS_Type_DEFINEDNAME = 0x0018; - const XLS_Type_VERTICALPAGEBREAKS = 0x001a; - const XLS_Type_HORIZONTALPAGEBREAKS = 0x001b; - const XLS_Type_NOTE = 0x001c; + const XLS_Type_SCENPROTECT = 0x00dd; + const XLS_Type_PASSWORD = 0x0013; + const XLS_Type_HEADER = 0x0014; + const XLS_Type_FOOTER = 0x0015; + const XLS_Type_EXTERNSHEET = 0x0017; + const XLS_Type_DEFINEDNAME = 0x0018; + const XLS_Type_VERTICALPAGEBREAKS = 0x001a; + const XLS_Type_HORIZONTALPAGEBREAKS = 0x001b; + const XLS_Type_NOTE = 0x001c; const XLS_Type_SELECTION = 0x001d; - const XLS_Type_DATEMODE = 0x0022; - const XLS_Type_EXTERNNAME = 0x0023; - const XLS_Type_LEFTMARGIN = 0x0026; - const XLS_Type_RIGHTMARGIN = 0x0027; + const XLS_Type_DATEMODE = 0x0022; + const XLS_Type_EXTERNNAME = 0x0023; + const XLS_Type_LEFTMARGIN = 0x0026; + const XLS_Type_RIGHTMARGIN = 0x0027; const XLS_Type_TOPMARGIN = 0x0028; - const XLS_Type_BOTTOMMARGIN = 0x0029; - const XLS_Type_PRINTGRIDLINES = 0x002b; - const XLS_Type_FILEPASS = 0x002f; - const XLS_Type_FONT = 0x0031; - const XLS_Type_CONTINUE = 0x003c; - const XLS_Type_PANE = 0x0041; - const XLS_Type_CODEPAGE = 0x0042; - const XLS_Type_DEFCOLWIDTH = 0x0055; - const XLS_Type_OBJ = 0x005d; - const XLS_Type_COLINFO = 0x007d; - const XLS_Type_IMDATA = 0x007f; - const XLS_Type_SHEETPR = 0x0081; - const XLS_Type_HCENTER = 0x0083; - const XLS_Type_VCENTER = 0x0084; + const XLS_Type_BOTTOMMARGIN = 0x0029; + const XLS_Type_PRINTGRIDLINES = 0x002b; + const XLS_Type_FILEPASS = 0x002f; + const XLS_Type_FONT = 0x0031; + const XLS_Type_CONTINUE = 0x003c; + const XLS_Type_PANE = 0x0041; + const XLS_Type_CODEPAGE = 0x0042; + const XLS_Type_DEFCOLWIDTH = 0x0055; + const XLS_Type_OBJ = 0x005d; + const XLS_Type_COLINFO = 0x007d; + const XLS_Type_IMDATA = 0x007f; + const XLS_Type_SHEETPR = 0x0081; + const XLS_Type_HCENTER = 0x0083; + const XLS_Type_VCENTER = 0x0084; const XLS_Type_SHEET = 0x0085; - const XLS_Type_PALETTE = 0x0092; - const XLS_Type_SCL = 0x00a0; + const XLS_Type_PALETTE = 0x0092; + const XLS_Type_SCL = 0x00a0; const XLS_Type_PAGESETUP = 0x00a1; const XLS_Type_MULRK = 0x00bd; - const XLS_Type_MULBLANK = 0x00be; - const XLS_Type_DBCELL = 0x00d7; - const XLS_Type_XF = 0x00e0; - const XLS_Type_MERGEDCELLS = 0x00e5; - const XLS_Type_MSODRAWINGGROUP = 0x00eb; - const XLS_Type_MSODRAWING = 0x00ec; - const XLS_Type_SST = 0x00fc; - const XLS_Type_LABELSST = 0x00fd; - const XLS_Type_EXTSST = 0x00ff; - const XLS_Type_EXTERNALBOOK = 0x01ae; - const XLS_Type_DATAVALIDATIONS = 0x01b2; - const XLS_Type_TXO = 0x01b6; + const XLS_Type_MULBLANK = 0x00be; + const XLS_Type_DBCELL = 0x00d7; + const XLS_Type_XF = 0x00e0; + const XLS_Type_MERGEDCELLS = 0x00e5; + const XLS_Type_MSODRAWINGGROUP = 0x00eb; + const XLS_Type_MSODRAWING = 0x00ec; + const XLS_Type_SST = 0x00fc; + const XLS_Type_LABELSST = 0x00fd; + const XLS_Type_EXTSST = 0x00ff; + const XLS_Type_EXTERNALBOOK = 0x01ae; + const XLS_Type_DATAVALIDATIONS = 0x01b2; + const XLS_Type_TXO = 0x01b6; const XLS_Type_HYPERLINK = 0x01b8; - const XLS_Type_DATAVALIDATION = 0x01be; + const XLS_Type_DATAVALIDATION = 0x01be; const XLS_Type_DIMENSION = 0x0200; const XLS_Type_BLANK = 0x0201; - const XLS_Type_NUMBER = 0x0203; + const XLS_Type_NUMBER = 0x0203; const XLS_Type_LABEL = 0x0204; - const XLS_Type_BOOLERR = 0x0205; - const XLS_Type_STRING = 0x0207; - const XLS_Type_ROW = 0x0208; + const XLS_Type_BOOLERR = 0x0205; + const XLS_Type_STRING = 0x0207; + const XLS_Type_ROW = 0x0208; const XLS_Type_INDEX = 0x020b; const XLS_Type_ARRAY = 0x0221; const XLS_Type_DEFAULTROWHEIGHT = 0x0225; - const XLS_Type_WINDOW2 = 0x023e; - const XLS_Type_RK = 0x027e; + const XLS_Type_WINDOW2 = 0x023e; + const XLS_Type_RK = 0x027e; const XLS_Type_STYLE = 0x0293; - const XLS_Type_FORMAT = 0x041e; - const XLS_Type_SHAREDFMLA = 0x04bc; - const XLS_Type_BOF = 0x0809; - const XLS_Type_SHEETPROTECTION = 0x0867; - const XLS_Type_RANGEPROTECTION = 0x0868; - const XLS_Type_SHEETLAYOUT = 0x0862; + const XLS_Type_FORMAT = 0x041e; + const XLS_Type_SHAREDFMLA = 0x04bc; + const XLS_Type_BOF = 0x0809; + const XLS_Type_SHEETPROTECTION = 0x0867; + const XLS_Type_RANGEPROTECTION = 0x0868; + const XLS_Type_SHEETLAYOUT = 0x0862; const XLS_Type_XFEXT = 0x087d; - const XLS_Type_PAGELAYOUTVIEW = 0x088b; - const XLS_Type_UNKNOWN = 0xffff; + const XLS_Type_PAGELAYOUTVIEW = 0x088b; + const XLS_Type_UNKNOWN = 0xffff; // Encryption type - const MS_BIFF_CRYPTO_NONE = 0; - const MS_BIFF_CRYPTO_XOR = 1; - const MS_BIFF_CRYPTO_RC4 = 2; + const MS_BIFF_CRYPTO_NONE = 0; + const MS_BIFF_CRYPTO_XOR = 1; + const MS_BIFF_CRYPTO_RC4 = 2; // Size of stream blocks when using RC4 encryption - const REKEY_BLOCK = 0x400; + const REKEY_BLOCK = 0x400; /** * Summary Information stream data. @@ -389,7 +389,7 @@ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExce /** * The type of encryption in use * - * @var int + * @var int */ private $_encryption = 0; @@ -424,11 +424,11 @@ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExce /** * Create a new PHPExcel_Reader_Excel5 instance */ - public function __construct() { + public function __construct() + { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); } - /** * Can the current PHPExcel_Reader_IReader read the file? * @@ -455,7 +455,6 @@ public function canRead($pFilename) } } - /** * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object * @@ -485,10 +484,18 @@ public function listWorksheetNames($pFilename) $code = self::_GetInt2d($this->_data, $this->_pos); switch ($code) { - case self::XLS_Type_BOF: $this->_readBof(); break; - case self::XLS_Type_SHEET: $this->_readSheet(); break; - case self::XLS_Type_EOF: $this->_readDefault(); break 2; - default: $this->_readDefault(); break; + case self::XLS_Type_BOF: + $this->_readBof(); + break; + case self::XLS_Type_SHEET: + $this->_readSheet(); + break; + case self::XLS_Type_EOF: + $this->_readDefault(); + break 2; + default: + $this->_readDefault(); + break; } } @@ -535,10 +542,18 @@ public function listWorksheetInfo($pFilename) $code = self::_GetInt2d($this->_data, $this->_pos); switch ($code) { - case self::XLS_Type_BOF: $this->_readBof(); break; - case self::XLS_Type_SHEET: $this->_readSheet(); break; - case self::XLS_Type_EOF: $this->_readDefault(); break 2; - default: $this->_readDefault(); break; + case self::XLS_Type_BOF: + $this->_readBof(); + break; + case self::XLS_Type_SHEET: + $this->_readSheet(); + break; + case self::XLS_Type_EOF: + $this->_readDefault(); + break 2; + default: + $this->_readDefault(); + break; } } @@ -583,9 +598,15 @@ public function listWorksheetInfo($pFilename) $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); break; - case self::XLS_Type_BOF: $this->_readBof(); break; - case self::XLS_Type_EOF: $this->_readDefault(); break 2; - default: $this->_readDefault(); break; + case self::XLS_Type_BOF: + $this->_readBof(); + break; + case self::XLS_Type_EOF: + $this->_readDefault(); + break 2; + default: + $this->_readDefault(); + break; } } @@ -629,45 +650,83 @@ public function load($pFilename) $this->_dataSize = strlen($this->_data); // initialize - $this->_pos = 0; + $this->_pos = 0; $this->_codepage = 'CP1252'; - $this->_formats = array(); + $this->_formats = array(); $this->_objFonts = array(); - $this->_palette = array(); - $this->_sheets = array(); - $this->_externalBooks = array(); - $this->_ref = array(); - $this->_definedname = array(); - $this->_sst = array(); + $this->_palette = array(); + $this->_sheets = array(); + $this->_externalBooks = array(); + $this->_ref = array(); + $this->_definedname = array(); + $this->_sst = array(); $this->_drawingGroupData = ''; - $this->_xfIndex = ''; - $this->_mapCellXfIndex = array(); - $this->_mapCellStyleXfIndex = array(); + $this->_xfIndex = ''; + $this->_mapCellXfIndex = array(); + $this->_mapCellStyleXfIndex = array(); // Parse Workbook Global Substream while ($this->_pos < $this->_dataSize) { $code = self::_GetInt2d($this->_data, $this->_pos); switch ($code) { - case self::XLS_Type_BOF: $this->_readBof(); break; - case self::XLS_Type_FILEPASS: $this->_readFilepass(); break; - case self::XLS_Type_CODEPAGE: $this->_readCodepage(); break; - case self::XLS_Type_DATEMODE: $this->_readDateMode(); break; - case self::XLS_Type_FONT: $this->_readFont(); break; - case self::XLS_Type_FORMAT: $this->_readFormat(); break; - case self::XLS_Type_XF: $this->_readXf(); break; - case self::XLS_Type_XFEXT: $this->_readXfExt(); break; - case self::XLS_Type_STYLE: $this->_readStyle(); break; - case self::XLS_Type_PALETTE: $this->_readPalette(); break; - case self::XLS_Type_SHEET: $this->_readSheet(); break; - case self::XLS_Type_EXTERNALBOOK: $this->_readExternalBook(); break; - case self::XLS_Type_EXTERNNAME: $this->_readExternName(); break; - case self::XLS_Type_EXTERNSHEET: $this->_readExternSheet(); break; - case self::XLS_Type_DEFINEDNAME: $this->_readDefinedName(); break; - case self::XLS_Type_MSODRAWINGGROUP: $this->_readMsoDrawingGroup(); break; - case self::XLS_Type_SST: $this->_readSst(); break; - case self::XLS_Type_EOF: $this->_readDefault(); break 2; - default: $this->_readDefault(); break; + case self::XLS_Type_BOF: + $this->_readBof(); + break; + case self::XLS_Type_FILEPASS: + $this->_readFilepass(); + break; + case self::XLS_Type_CODEPAGE: + $this->_readCodepage(); + break; + case self::XLS_Type_DATEMODE: + $this->_readDateMode(); + break; + case self::XLS_Type_FONT: + $this->_readFont(); + break; + case self::XLS_Type_FORMAT: + $this->_readFormat(); + break; + case self::XLS_Type_XF: + $this->_readXf(); + break; + case self::XLS_Type_XFEXT: + $this->_readXfExt(); + break; + case self::XLS_Type_STYLE: + $this->_readStyle(); + break; + case self::XLS_Type_PALETTE: + $this->_readPalette(); + break; + case self::XLS_Type_SHEET: + $this->_readSheet(); + break; + case self::XLS_Type_EXTERNALBOOK: + $this->_readExternalBook(); + break; + case self::XLS_Type_EXTERNNAME: + $this->_readExternName(); + break; + case self::XLS_Type_EXTERNSHEET: + $this->_readExternSheet(); + break; + case self::XLS_Type_DEFINEDNAME: + $this->_readDefinedName(); + break; + case self::XLS_Type_MSODRAWINGGROUP: + $this->_readMsoDrawingGroup(); + break; + case self::XLS_Type_SST: + $this->_readSst(); + break; + case self::XLS_Type_EOF: + $this->_readDefault(); + break 2; + default: + $this->_readDefault(); + break; } } @@ -689,7 +748,6 @@ public function load($pFilename) $startColor = self::_readColor($fill->startcolorIndex, $this->_palette, $this->_version); $fill->getStartColor()->setRGB($startColor['rgb']); } - if (isset($fill->endcolorIndex)) { $endColor = self::_readColor($fill->endcolorIndex, $this->_palette, $this->_version); $fill->getEndColor()->setRGB($endColor['rgb']); @@ -706,22 +764,18 @@ public function load($pFilename) $borderTopColor = self::_readColor($top->colorIndex, $this->_palette, $this->_version); $top->getColor()->setRGB($borderTopColor['rgb']); } - if (isset($right->colorIndex)) { $borderRightColor = self::_readColor($right->colorIndex, $this->_palette, $this->_version); $right->getColor()->setRGB($borderRightColor['rgb']); } - if (isset($bottom->colorIndex)) { $borderBottomColor = self::_readColor($bottom->colorIndex, $this->_palette, $this->_version); $bottom->getColor()->setRGB($borderBottomColor['rgb']); } - if (isset($left->colorIndex)) { $borderLeftColor = self::_readColor($left->colorIndex, $this->_palette, $this->_version); $left->getColor()->setRGB($borderLeftColor['rgb']); } - if (isset($diagonal->colorIndex)) { $borderDiagonalColor = self::_readColor($diagonal->colorIndex, $this->_palette, $this->_version); $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']); @@ -742,7 +796,6 @@ public function load($pFilename) // Parse the individual sheets foreach ($this->_sheets as $sheet) { - if ($sheet['sheetType'] != 0x00) { // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module continue; @@ -789,60 +842,166 @@ public function load($pFilename) $code = self::_GetInt2d($this->_data, $this->_pos); switch ($code) { - case self::XLS_Type_BOF: $this->_readBof(); break; - case self::XLS_Type_PRINTGRIDLINES: $this->_readPrintGridlines(); break; - case self::XLS_Type_DEFAULTROWHEIGHT: $this->_readDefaultRowHeight(); break; - case self::XLS_Type_SHEETPR: $this->_readSheetPr(); break; - case self::XLS_Type_HORIZONTALPAGEBREAKS: $this->_readHorizontalPageBreaks(); break; - case self::XLS_Type_VERTICALPAGEBREAKS: $this->_readVerticalPageBreaks(); break; - case self::XLS_Type_HEADER: $this->_readHeader(); break; - case self::XLS_Type_FOOTER: $this->_readFooter(); break; - case self::XLS_Type_HCENTER: $this->_readHcenter(); break; - case self::XLS_Type_VCENTER: $this->_readVcenter(); break; - case self::XLS_Type_LEFTMARGIN: $this->_readLeftMargin(); break; - case self::XLS_Type_RIGHTMARGIN: $this->_readRightMargin(); break; - case self::XLS_Type_TOPMARGIN: $this->_readTopMargin(); break; - case self::XLS_Type_BOTTOMMARGIN: $this->_readBottomMargin(); break; - case self::XLS_Type_PAGESETUP: $this->_readPageSetup(); break; - case self::XLS_Type_PROTECT: $this->_readProtect(); break; - case self::XLS_Type_SCENPROTECT: $this->_readScenProtect(); break; - case self::XLS_Type_OBJECTPROTECT: $this->_readObjectProtect(); break; - case self::XLS_Type_PASSWORD: $this->_readPassword(); break; - case self::XLS_Type_DEFCOLWIDTH: $this->_readDefColWidth(); break; - case self::XLS_Type_COLINFO: $this->_readColInfo(); break; - case self::XLS_Type_DIMENSION: $this->_readDefault(); break; - case self::XLS_Type_ROW: $this->_readRow(); break; - case self::XLS_Type_DBCELL: $this->_readDefault(); break; - case self::XLS_Type_RK: $this->_readRk(); break; - case self::XLS_Type_LABELSST: $this->_readLabelSst(); break; - case self::XLS_Type_MULRK: $this->_readMulRk(); break; - case self::XLS_Type_NUMBER: $this->_readNumber(); break; - case self::XLS_Type_FORMULA: $this->_readFormula(); break; - case self::XLS_Type_SHAREDFMLA: $this->_readSharedFmla(); break; - case self::XLS_Type_BOOLERR: $this->_readBoolErr(); break; - case self::XLS_Type_MULBLANK: $this->_readMulBlank(); break; - case self::XLS_Type_LABEL: $this->_readLabel(); break; - case self::XLS_Type_BLANK: $this->_readBlank(); break; - case self::XLS_Type_MSODRAWING: $this->_readMsoDrawing(); break; - case self::XLS_Type_OBJ: $this->_readObj(); break; - case self::XLS_Type_WINDOW2: $this->_readWindow2(); break; - case self::XLS_Type_PAGELAYOUTVIEW: $this->_readPageLayoutView(); break; - case self::XLS_Type_SCL: $this->_readScl(); break; - case self::XLS_Type_PANE: $this->_readPane(); break; - case self::XLS_Type_SELECTION: $this->_readSelection(); break; - case self::XLS_Type_MERGEDCELLS: $this->_readMergedCells(); break; - case self::XLS_Type_HYPERLINK: $this->_readHyperLink(); break; - case self::XLS_Type_DATAVALIDATIONS: $this->_readDataValidations(); break; - case self::XLS_Type_DATAVALIDATION: $this->_readDataValidation(); break; - case self::XLS_Type_SHEETLAYOUT: $this->_readSheetLayout(); break; - case self::XLS_Type_SHEETPROTECTION: $this->_readSheetProtection(); break; - case self::XLS_Type_RANGEPROTECTION: $this->_readRangeProtection(); break; - case self::XLS_Type_NOTE: $this->_readNote(); break; + case self::XLS_Type_BOF: + $this->_readBof(); + break; + case self::XLS_Type_PRINTGRIDLINES: + $this->_readPrintGridlines(); + break; + case self::XLS_Type_DEFAULTROWHEIGHT: + $this->_readDefaultRowHeight(); + break; + case self::XLS_Type_SHEETPR: + $this->_readSheetPr(); + break; + case self::XLS_Type_HORIZONTALPAGEBREAKS: + $this->_readHorizontalPageBreaks(); + break; + case self::XLS_Type_VERTICALPAGEBREAKS: + $this->_readVerticalPageBreaks(); + break; + case self::XLS_Type_HEADER: + $this->_readHeader(); + break; + case self::XLS_Type_FOOTER: + $this->_readFooter(); + break; + case self::XLS_Type_HCENTER: + $this->_readHcenter(); + break; + case self::XLS_Type_VCENTER: + $this->_readVcenter(); + break; + case self::XLS_Type_LEFTMARGIN: + $this->_readLeftMargin(); + break; + case self::XLS_Type_RIGHTMARGIN: + $this->_readRightMargin(); + break; + case self::XLS_Type_TOPMARGIN: + $this->_readTopMargin(); + break; + case self::XLS_Type_BOTTOMMARGIN: + $this->_readBottomMargin(); + break; + case self::XLS_Type_PAGESETUP: + $this->_readPageSetup(); + break; + case self::XLS_Type_PROTECT: + $this->_readProtect(); + break; + case self::XLS_Type_SCENPROTECT: + $this->_readScenProtect(); + break; + case self::XLS_Type_OBJECTPROTECT: + $this->_readObjectProtect(); + break; + case self::XLS_Type_PASSWORD: + $this->_readPassword(); + break; + case self::XLS_Type_DEFCOLWIDTH: + $this->_readDefColWidth(); + break; + case self::XLS_Type_COLINFO: + $this->_readColInfo(); + break; + case self::XLS_Type_DIMENSION: + $this->_readDefault(); + break; + case self::XLS_Type_ROW: + $this->_readRow(); + break; + case self::XLS_Type_DBCELL: + $this->_readDefault(); + break; + case self::XLS_Type_RK: + $this->_readRk(); + break; + case self::XLS_Type_LABELSST: + $this->_readLabelSst(); + break; + case self::XLS_Type_MULRK: + $this->_readMulRk(); + break; + case self::XLS_Type_NUMBER: + $this->_readNumber(); + break; + case self::XLS_Type_FORMULA: + $this->_readFormula(); + break; + case self::XLS_Type_SHAREDFMLA: + $this->_readSharedFmla(); + break; + case self::XLS_Type_BOOLERR: + $this->_readBoolErr(); + break; + case self::XLS_Type_MULBLANK: + $this->_readMulBlank(); + break; + case self::XLS_Type_LABEL: + $this->_readLabel(); + break; + case self::XLS_Type_BLANK: + $this->_readBlank(); + break; + case self::XLS_Type_MSODRAWING: + $this->_readMsoDrawing(); + break; + case self::XLS_Type_OBJ: + $this->_readObj(); + break; + case self::XLS_Type_WINDOW2: + $this->_readWindow2(); + break; + case self::XLS_Type_PAGELAYOUTVIEW: + $this->_readPageLayoutView(); + break; + case self::XLS_Type_SCL: + $this->_readScl(); + break; + case self::XLS_Type_PANE: + $this->_readPane(); + break; + case self::XLS_Type_SELECTION: + $this->_readSelection(); + break; + case self::XLS_Type_MERGEDCELLS: + $this->_readMergedCells(); + break; + case self::XLS_Type_HYPERLINK: + $this->_readHyperLink(); + break; + case self::XLS_Type_DATAVALIDATIONS: + $this->_readDataValidations(); + break; + case self::XLS_Type_DATAVALIDATION: + $this->_readDataValidation(); + break; + case self::XLS_Type_SHEETLAYOUT: + $this->_readSheetLayout(); + break; + case self::XLS_Type_SHEETPROTECTION: + $this->_readSheetProtection(); + break; + case self::XLS_Type_RANGEPROTECTION: + $this->_readRangeProtection(); + break; + case self::XLS_Type_NOTE: + $this->_readNote(); + break; //case self::XLS_Type_IMDATA: $this->_readImData(); break; - case self::XLS_Type_TXO: $this->_readTextObject(); break; - case self::XLS_Type_CONTINUE: $this->_readContinue(); break; - case self::XLS_Type_EOF: $this->_readDefault(); break 2; - default: $this->_readDefault(); break; + case self::XLS_Type_TXO: + $this->_readTextObject(); + break; + case self::XLS_Type_CONTINUE: + $this->_readContinue(); + break; + case self::XLS_Type_EOF: + $this->_readDefault(); + break 2; + default: + $this->_readDefault(); + break; } } @@ -897,7 +1056,6 @@ public function load($pFilename) // Note // echo 'Cell Annotation Object<br />'; // echo 'Object ID is ', $obj['idObjID'],'<br />'; -// if (isset($this->_cellNotes[$obj['idObjID']])) { $cellNote = $this->_cellNotes[$obj['idObjID']]; @@ -907,11 +1065,9 @@ public function load($pFilename) } } break; - case 0x08: // echo 'Picture Object<br />'; // picture - // get index to BSE entry (1-based) $BSEindex = $spContainer->getOPT(0x0104); $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection(); @@ -936,7 +1092,6 @@ public function load($pFilename) $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG); break; - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG); $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG); @@ -946,13 +1101,10 @@ public function load($pFilename) $drawing->setWorksheet($this->_phpSheet); $drawing->setCoordinates($spContainer->getStartCoordinates()); } - break; - default: // other object type break; - } } } @@ -982,9 +1134,7 @@ public function load($pFilename) // var_dump($noteDetails); // echo '<br />'; $cellAddress = str_replace('$','', $noteDetails['cellRef']); - $this->_phpSheet->getComment( $cellAddress ) - ->setAuthor( $noteDetails['author'] ) - ->setText($this->_parseRichText($noteDetails['objTextData']['text']) ); + $this->_phpSheet->getComment($cellAddress)->setAuthor($noteDetails['author'])->setText($this->_parseRichText($noteDetails['objTextData']['text'])); } } } @@ -993,78 +1143,69 @@ public function load($pFilename) foreach ($this->_definedname as $definedName) { if ($definedName['isBuiltInName']) { switch ($definedName['name']) { - - case pack('C', 0x06): - // print area - // in general, formula looks like this: Foo!$C$7:$J$66,Bar!$A$1:$IV$2 - $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? - - $extractedRanges = array(); - foreach ($ranges as $range) { - // $range should look like one of these - // Foo!$C$7:$J$66 - // Bar!$A$1:$IV$2 - - $explodes = explode('!', $range); // FIXME: what if sheetname contains exclamation mark? - $sheetName = trim($explodes[0], "'"); - - if (count($explodes) == 2) { - if (strpos($explodes[1], ':') === FALSE) { - $explodes[1] = $explodes[1] . ':' . $explodes[1]; + case pack('C', 0x06): + // print area + // in general, formula looks like this: Foo!$C$7:$J$66,Bar!$A$1:$IV$2 + $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? + + $extractedRanges = array(); + foreach ($ranges as $range) { + // $range should look like one of these + // Foo!$C$7:$J$66 + // Bar!$A$1:$IV$2 + $explodes = explode('!', $range); // FIXME: what if sheetname contains exclamation mark? + $sheetName = trim($explodes[0], "'"); + if (count($explodes) == 2) { + if (strpos($explodes[1], ':') === FALSE) { + $explodes[1] = $explodes[1] . ':' . $explodes[1]; + } + $extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66 } - $extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66 } - } - if ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) { - $docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges)); // C7:J66,A1:IV2 - } - break; - - case pack('C', 0x07): - // print titles (repeating rows) - // Assuming BIFF8, there are 3 cases - // 1. repeating rows - // formula looks like this: Sheet!$A$1:$IV$2 - // rows 1-2 repeat - // 2. repeating columns - // formula looks like this: Sheet!$A$1:$B$65536 - // columns A-B repeat - // 3. both repeating rows and repeating columns - // formula looks like this: Sheet!$A$1:$B$65536,Sheet!$A$1:$IV$2 - - $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? - - foreach ($ranges as $range) { - // $range should look like this one of these - // Sheet!$A$1:$B$65536 - // Sheet!$A$1:$IV$2 - - $explodes = explode('!', $range); - - if (count($explodes) == 2) { - if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) { - - $extractedRange = $explodes[1]; - $extractedRange = str_replace('$', '', $extractedRange); - - $coordinateStrings = explode(':', $extractedRange); - if (count($coordinateStrings) == 2) { - list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[0]); - list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[1]); - - if ($firstColumn == 'A' and $lastColumn == 'IV') { - // then we have repeating rows - $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($firstRow, $lastRow)); - } elseif ($firstRow == 1 and $lastRow == 65536) { - // then we have repeating columns - $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($firstColumn, $lastColumn)); + if ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) { + $docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges)); // C7:J66,A1:IV2 + } + break; + case pack('C', 0x07): + // print titles (repeating rows) + // Assuming BIFF8, there are 3 cases + // 1. repeating rows + // formula looks like this: Sheet!$A$1:$IV$2 + // rows 1-2 repeat + // 2. repeating columns + // formula looks like this: Sheet!$A$1:$B$65536 + // columns A-B repeat + // 3. both repeating rows and repeating columns + // formula looks like this: Sheet!$A$1:$B$65536,Sheet!$A$1:$IV$2 + $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? + foreach ($ranges as $range) { + // $range should look like this one of these + // Sheet!$A$1:$B$65536 + // Sheet!$A$1:$IV$2 + $explodes = explode('!', $range); + if (count($explodes) == 2) { + if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) { + + $extractedRange = $explodes[1]; + $extractedRange = str_replace('$', '', $extractedRange); + + $coordinateStrings = explode(':', $extractedRange); + if (count($coordinateStrings) == 2) { + list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[0]); + list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[1]); + + if ($firstColumn == 'A' and $lastColumn == 'IV') { + // then we have repeating rows + $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($firstRow, $lastRow)); + } elseif ($firstRow == 1 and $lastRow == 65536) { + // then we have repeating columns + $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($firstColumn, $lastColumn)); + } } } } } - } - break; - + break; } } else { // Extract range @@ -1078,8 +1219,7 @@ public function load($pFilename) $localOnly = ($definedName['scope'] == 0) ? false : true; - $scope = ($definedName['scope'] == 0) ? - null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']); + $scope = ($definedName['scope'] == 0) ? null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']); $this->_phpExcel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope) ); } @@ -1114,7 +1254,6 @@ private function _readRecordData($data, $pos, $len) $recordData = ''; if ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) { - $oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK); $block = floor($pos / self::REKEY_BLOCK); $endBlock = floor(($pos + $len) / self::REKEY_BLOCK); @@ -1144,7 +1283,6 @@ private function _readRecordData($data, $pos, $len) // Keep track of the position of this decryptor. // We'll try and re-use it later if we can to speed things up $this->_rc4Pos = $pos + $len; - } elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) { throw new PHPExcel_Reader_Exception('XOr encryption not supported'); } @@ -1160,18 +1298,14 @@ private function _loadOLE($pFilename) { // OLE reader $ole = new PHPExcel_Shared_OLERead(); - // get excel data, $res = $ole->read($pFilename); // Get workbook data: workbook stream + sheet streams $this->_data = $ole->getStream($ole->wrkbook); - // Get summary information data $this->_summaryInformation = $ole->getStream($ole->summaryInformation); - // Get additional document summary information data $this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation); - // Get user-defined property data // $this->_userDefinedProperties = $ole->getUserDefinedProperties(); } @@ -1211,7 +1345,6 @@ private function _readSummaryInformation() // offset: ($secOffset+8); size: var // loop through property decarations and properties for ($i = 0; $i < $countProperties; ++$i) { - // offset: ($secOffset+8) + (8 * $i); size: 4; property ID $id = self::_GetInt4d($this->_summaryInformation, ($secOffset+8) + (8 * $i)); @@ -1229,27 +1362,22 @@ private function _readSummaryInformation() case 0x02: // 2 byte signed integer $value = self::_GetInt2d($this->_summaryInformation, $secOffset + 4 + $offset); break; - case 0x03: // 4 byte signed integer $value = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); break; - case 0x13: // 4 byte unsigned integer // not needed yet, fix later if necessary break; - case 0x1E: // null-terminated string prepended by dword string length $byteLength = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); $value = substr($this->_summaryInformation, $secOffset + 8 + $offset, $byteLength); $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); $value = rtrim($value); break; - case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) // PHP-time $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_summaryInformation, $secOffset + 4 + $offset, 8)); break; - case 0x47: // Clipboard format // not needed yet, fix later if necessary break; @@ -1259,79 +1387,60 @@ private function _readSummaryInformation() case 0x01: // Code Page $codePage = PHPExcel_Shared_CodePage::NumberToName($value); break; - case 0x02: // Title $this->_phpExcel->getProperties()->setTitle($value); break; - case 0x03: // Subject $this->_phpExcel->getProperties()->setSubject($value); break; - case 0x04: // Author (Creator) $this->_phpExcel->getProperties()->setCreator($value); break; - case 0x05: // Keywords $this->_phpExcel->getProperties()->setKeywords($value); break; - case 0x06: // Comments (Description) $this->_phpExcel->getProperties()->setDescription($value); break; - case 0x07: // Template // Not supported by PHPExcel break; - case 0x08: // Last Saved By (LastModifiedBy) $this->_phpExcel->getProperties()->setLastModifiedBy($value); break; - case 0x09: // Revision // Not supported by PHPExcel break; - case 0x0A: // Total Editing Time // Not supported by PHPExcel break; - case 0x0B: // Last Printed // Not supported by PHPExcel break; - case 0x0C: // Created Date/Time $this->_phpExcel->getProperties()->setCreated($value); break; - case 0x0D: // Modified Date/Time $this->_phpExcel->getProperties()->setModified($value); break; - case 0x0E: // Number of Pages // Not supported by PHPExcel break; - case 0x0F: // Number of Words // Not supported by PHPExcel break; - case 0x10: // Number of Characters // Not supported by PHPExcel break; - case 0x11: // Thumbnail // Not supported by PHPExcel break; - case 0x12: // Name of creating application // Not supported by PHPExcel break; - case 0x13: // Security // Not supported by PHPExcel break; - } } } @@ -1395,32 +1504,26 @@ private function _readDocumentSummaryInformation() case 0x02: // 2 byte signed integer $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); break; - case 0x03: // 4 byte signed integer $value = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); break; - case 0x0B: // Boolean $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); $value = ($value == 0 ? false : true); break; - case 0x13: // 4 byte unsigned integer // not needed yet, fix later if necessary break; - case 0x1E: // null-terminated string prepended by dword string length $byteLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); $value = substr($this->_documentSummaryInformation, $secOffset + 8 + $offset, $byteLength); $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); $value = rtrim($value); break; - case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) // PHP-Time $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_documentSummaryInformation, $secOffset + 4 + $offset, 8)); break; - case 0x47: // Clipboard format // not needed yet, fix later if necessary break; @@ -1430,67 +1533,51 @@ private function _readDocumentSummaryInformation() case 0x01: // Code Page $codePage = PHPExcel_Shared_CodePage::NumberToName($value); break; - case 0x02: // Category $this->_phpExcel->getProperties()->setCategory($value); break; - case 0x03: // Presentation Target // Not supported by PHPExcel break; - case 0x04: // Bytes // Not supported by PHPExcel break; - case 0x05: // Lines // Not supported by PHPExcel break; - case 0x06: // Paragraphs // Not supported by PHPExcel break; - case 0x07: // Slides // Not supported by PHPExcel break; - case 0x08: // Notes // Not supported by PHPExcel break; - case 0x09: // Hidden Slides // Not supported by PHPExcel break; - case 0x0A: // MM Clips // Not supported by PHPExcel break; - case 0x0B: // Scale Crop // Not supported by PHPExcel break; - case 0x0C: // Heading Pairs // Not supported by PHPExcel break; - case 0x0D: // Titles of Parts // Not supported by PHPExcel break; - case 0x0E: // Manager $this->_phpExcel->getProperties()->setManager($value); break; - case 0x0F: // Company $this->_phpExcel->getProperties()->setCompany($value); break; - case 0x10: // Links up-to-date // Not supported by PHPExcel break; - } } } @@ -1535,10 +1622,11 @@ private function _readNote() // echo 'Note Object ID=', $noteObjID,'<br />'; // echo 'Note Author=', $noteAuthor,'<hr />'; // - $this->_cellNotes[$noteObjID] = array('cellRef' => $cellAddress, - 'objectID' => $noteObjID, - 'author' => $noteAuthor - ); + $this->_cellNotes[$noteObjID] = array( + 'cellRef' => $cellAddress, + 'objectID' => $noteObjID, + 'author' => $noteAuthor + ); } else { $extension = false; if ($cellAddress == '$B$65536') { @@ -1564,9 +1652,8 @@ private function _readNote() $comment->setText($this->_parseRichText($commentText.$noteText) ); } else { // Set comment for the cell - $this->_phpSheet->getComment( $cellAddress ) + $this->_phpSheet->getComment($cellAddress)->setText($this->_parseRichText($noteText)); // ->setAuthor( $author ) - ->setText($this->_parseRichText($noteText) ); } } @@ -1594,18 +1681,18 @@ private function _readTextObject() // cchText: 2 bytes; length of the text (in the first continue record) // cbRuns: 2 bytes; length of the formatting (in the second continue record) // followed by the continuation records containing the actual text and formatting - $grbitOpts = self::_GetInt2d($recordData, 0); + $grbitOpts = self::_GetInt2d($recordData, 0); $rot = self::_GetInt2d($recordData, 2); $cchText = self::_GetInt2d($recordData, 10); - $cbRuns = self::_GetInt2d($recordData, 12); - $text = $this->_getSplicedRecordData(); + $cbRuns = self::_GetInt2d($recordData, 12); + $text = $this->_getSplicedRecordData(); $this->_textObjects[$this->textObjRef] = array( - 'text' => substr($text["recordData"], $text["spliceOffsets"][0]+1, $cchText), - 'format' => substr($text["recordData"], $text["spliceOffsets"][1], $cbRuns), - 'alignment' => $grbitOpts, - 'rotation' => $rot - ); + 'text' => substr($text["recordData"], $text["spliceOffsets"][0]+1, $cchText), + 'format' => substr($text["recordData"], $text["spliceOffsets"][1], $cbRuns), + 'alignment' => $grbitOpts, + 'rotation' => $rot + ); // echo '<b>_readTextObject()</b><br />'; // var_dump($this->_textObjects[$this->textObjRef]); @@ -1635,12 +1722,10 @@ private function _readBof() } $this->_version = $version; break; - case self::XLS_Worksheet: // do not use this version information for anything // it is unreliable (OpenOffice doc, 5.8), use only version information from the global stream break; - default: // substream, e.g. chart // just skip the entire substream @@ -1681,13 +1766,7 @@ private function _readFilepass() // move stream pointer to next record $this->_pos += 4 + $length; - if (!$this->_verifyPassword( - 'VelvetSweatshop', - substr($recordData, 6, 16), - substr($recordData, 22, 16), - substr($recordData, 38, 16), - $this->_md5Ctxt - )) { + if (!$this->_verifyPassword('VelvetSweatshop', substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->_md5Ctxt)) { throw new PHPExcel_Reader_Exception('Decryption password incorrect'); } @@ -1766,11 +1845,9 @@ private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data if ((64 - $offset) < 5) { $tocopy = 64 - $offset; } - for ($i = 0; $i <= $tocopy; $i++) { $pwarray[$offset + $i] = $mdContext1[$keyoffset + $i]; } - $offset += $tocopy; if ($offset == 64) { @@ -2045,13 +2122,11 @@ private function _readXf() $xfTypeProt = self::_GetInt2d($recordData, 4); // bit 0; mask 0x01; 1 = cell is locked $isLocked = (0x01 & $xfTypeProt) >> 0; - $objStyle->getProtection()->setLocked($isLocked ? - PHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + $objStyle->getProtection()->setLocked($isLocked ? PHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); // bit 1; mask 0x02; 1 = Formula is hidden $isHidden = (0x02 & $xfTypeProt) >> 1; - $objStyle->getProtection()->setHidden($isHidden ? - PHPExcel_Style_Protection::PROTECTION_PROTECTED : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + $objStyle->getProtection()->setHidden($isHidden ? PHPExcel_Style_Protection::PROTECTION_PROTECTED : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); // bit 2; mask 0x04; 0 = Cell XF, 1 = Cell Style XF $isCellStyleXf = (0x04 & $xfTypeProt) >> 2; @@ -2111,101 +2186,99 @@ private function _readXf() if ($this->_version == self::XLS_BIFF8) { // offset: 7; size: 1; XF_ROTATION: Text rotation angle - $angle = ord($recordData{7}); - $rotation = 0; - if ($angle <= 90) { - $rotation = $angle; - } else if ($angle <= 180) { - $rotation = 90 - $angle; - } else if ($angle == 255) { - $rotation = -165; - } - $objStyle->getAlignment()->setTextRotation($rotation); + $angle = ord($recordData{7}); + $rotation = 0; + if ($angle <= 90) { + $rotation = $angle; + } else if ($angle <= 180) { + $rotation = 90 - $angle; + } else if ($angle == 255) { + $rotation = -165; + } + $objStyle->getAlignment()->setTextRotation($rotation); // offset: 8; size: 1; Indentation, shrink to cell size, and text direction - // bit: 3-0; mask: 0x0F; indent level - $indent = (0x0F & ord($recordData{8})) >> 0; - $objStyle->getAlignment()->setIndent($indent); - - // bit: 4; mask: 0x10; 1 = shrink content to fit into cell - $shrinkToFit = (0x10 & ord($recordData{8})) >> 4; - switch ($shrinkToFit) { - case 0: - $objStyle->getAlignment()->setShrinkToFit(false); - break; - case 1: - $objStyle->getAlignment()->setShrinkToFit(true); - break; - } + // bit: 3-0; mask: 0x0F; indent level + $indent = (0x0F & ord($recordData{8})) >> 0; + $objStyle->getAlignment()->setIndent($indent); + + // bit: 4; mask: 0x10; 1 = shrink content to fit into cell + $shrinkToFit = (0x10 & ord($recordData{8})) >> 4; + switch ($shrinkToFit) { + case 0: + $objStyle->getAlignment()->setShrinkToFit(false); + break; + case 1: + $objStyle->getAlignment()->setShrinkToFit(true); + break; + } // offset: 9; size: 1; Flags used for attribute groups // offset: 10; size: 4; Cell border lines and background area - // bit: 3-0; mask: 0x0000000F; left style - if ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) { - $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle); - } - // bit: 7-4; mask: 0x000000F0; right style - if ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) { - $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle); - } - // bit: 11-8; mask: 0x00000F00; top style - if ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) { - $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle); - } - // bit: 15-12; mask: 0x0000F000; bottom style - if ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) { - $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle); - } - // bit: 22-16; mask: 0x007F0000; left color - $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16; - - // bit: 29-23; mask: 0x3F800000; right color - $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23; - - // bit: 30; mask: 0x40000000; 1 = diagonal line from top left to right bottom - $diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ? - true : false; - - // bit: 31; mask: 0x80000000; 1 = diagonal line from bottom left to top right - $diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ? - true : false; - - if ($diagonalUp == false && $diagonalDown == false) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); - } elseif ($diagonalUp == true && $diagonalDown == false) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); - } elseif ($diagonalUp == false && $diagonalDown == true) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); - } elseif ($diagonalUp == true && $diagonalDown == true) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); - } + // bit: 3-0; mask: 0x0000000F; left style + if ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) { + $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle); + } + // bit: 7-4; mask: 0x000000F0; right style + if ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) { + $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle); + } + // bit: 11-8; mask: 0x00000F00; top style + if ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) { + $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle); + } + // bit: 15-12; mask: 0x0000F000; bottom style + if ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) { + $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle); + } + // bit: 22-16; mask: 0x007F0000; left color + $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16; + + // bit: 29-23; mask: 0x3F800000; right color + $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23; + + // bit: 30; mask: 0x40000000; 1 = diagonal line from top left to right bottom + $diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ? true : false; + + // bit: 31; mask: 0x80000000; 1 = diagonal line from bottom left to top right + $diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ? true : false; + + if ($diagonalUp == false && $diagonalDown == false) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); + } elseif ($diagonalUp == true && $diagonalDown == false) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); + } elseif ($diagonalUp == false && $diagonalDown == true) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); + } elseif ($diagonalUp == true && $diagonalDown == true) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); + } // offset: 14; size: 4; - // bit: 6-0; mask: 0x0000007F; top color - $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0; + // bit: 6-0; mask: 0x0000007F; top color + $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0; - // bit: 13-7; mask: 0x00003F80; bottom color - $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7; + // bit: 13-7; mask: 0x00003F80; bottom color + $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7; - // bit: 20-14; mask: 0x001FC000; diagonal color - $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14; + // bit: 20-14; mask: 0x001FC000; diagonal color + $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14; - // bit: 24-21; mask: 0x01E00000; diagonal style - if ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) { - $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle); - } + // bit: 24-21; mask: 0x01E00000; diagonal style + if ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) { + $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle); + } - // bit: 31-26; mask: 0xFC000000 fill pattern - if ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) { - $objStyle->getFill()->setFillType($fillType); - } + // bit: 31-26; mask: 0xFC000000 fill pattern + if ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) { + $objStyle->getFill()->setFillType($fillType); + } // offset: 18; size: 2; pattern and background colour - // bit: 6-0; mask: 0x007F; color index for pattern color - $objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0; + // bit: 6-0; mask: 0x007F; color index for pattern color + $objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0; - // bit: 13-7; mask: 0x3F80; color index for pattern background - $objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7; + // bit: 13-7; mask: 0x3F80; color index for pattern background + $objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7; } else { // BIFF5 @@ -2344,7 +2417,6 @@ private function _readXfExt() } } break; - case 5: // fill end color $xclfType = self::_GetInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) @@ -2360,7 +2432,6 @@ private function _readXfExt() } } break; - case 7: // border color top $xclfType = self::_GetInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) @@ -2376,7 +2447,6 @@ private function _readXfExt() } } break; - case 8: // border color bottom $xclfType = self::_GetInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) @@ -2392,7 +2462,6 @@ private function _readXfExt() } } break; - case 9: // border color left $xclfType = self::_GetInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) @@ -2408,7 +2477,6 @@ private function _readXfExt() } } break; - case 10: // border color right $xclfType = self::_GetInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) @@ -2424,7 +2492,6 @@ private function _readXfExt() } } break; - case 11: // border color diagonal $xclfType = self::_GetInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) @@ -2440,7 +2507,6 @@ private function _readXfExt() } } break; - case 13: // font color $xclfType = self::_GetInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) @@ -2494,11 +2560,9 @@ private function _readStyle() case 0x00: // currently, we are not using this for anything break; - default: break; } - } else { // user-defined; not supported by PHPExcel } @@ -2556,10 +2620,18 @@ private function _readSheet() // offset: 4; size: 1; sheet state switch (ord($recordData{4})) { - case 0x00: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; - case 0x01: $sheetState = PHPExcel_Worksheet::SHEETSTATE_HIDDEN; break; - case 0x02: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN; break; - default: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; + case 0x00: + $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; + break; + case 0x01: + $sheetState = PHPExcel_Worksheet::SHEETSTATE_HIDDEN; + break; + case 0x02: + $sheetState = PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN; + break; + default: + $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; + break; } // offset: 5; size: 1; sheet type @@ -2622,7 +2694,6 @@ private function _readExternalBook() 'encodedUrl' => $encodedUrlString['value'], 'externalSheetNames' => $externalSheetNames, ); - } elseif (substr($recordData, 2, 2) == pack('CC', 0x01, 0x04)) { // internal reference // offset: 0; size: 2; number of sheet in this document @@ -2736,8 +2807,8 @@ private function _readDefinedName() // offset: 0; size: 2; option flags $opts = self::_GetInt2d($recordData, 0); - // bit: 5; mask: 0x0020; 0 = user-defined name, 1 = built-in-name - $isBuiltInName = (0x0020 & $opts) >> 5; + // bit: 5; mask: 0x0020; 0 = user-defined name, 1 = built-in-name + $isBuiltInName = (0x0020 & $opts) >> 5; // offset: 2; size: 1; keyboard shortcut @@ -2868,7 +2939,6 @@ private function _readSst() $retstr = substr($recordData, $pos, $len); $pos += $len; - } else { // character array is split between records @@ -2884,7 +2954,6 @@ private function _readSst() // keep reading the characters while ($charsLeft > 0) { - // look up next limit position, in case the string span more than one continue record foreach ($spliceOffsets as $spliceOffset) { if ($pos < $spliceOffset) { @@ -2905,7 +2974,6 @@ private function _readSst() $retstr .= substr($recordData, $pos, $len); $charsLeft -= $len; $isCompressed = true; - } elseif (!$isCompressed && ($option != 0)) { // 1st fragment uncompressed // this fragment uncompressed @@ -2913,7 +2981,6 @@ private function _readSst() $retstr .= substr($recordData, $pos, $len); $charsLeft -= $len / 2; $isCompressed = false; - } elseif (!$isCompressed && ($option == 0)) { // 1st fragment uncompressed // this fragment compressed @@ -2923,7 +2990,6 @@ private function _readSst() } $charsLeft -= $len; $isCompressed = false; - } else { // 1st fragment compressed // this fragment uncompressed @@ -3057,7 +3123,6 @@ private function _readHorizontalPageBreaks() $this->_pos += 4 + $length; if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { - // offset: 0; size: 2; number of the following row index structures $nm = self::_GetInt2d($recordData, 0); @@ -3295,18 +3360,22 @@ private function _readPageSetup() // offset: 10; size: 2; option flags - // bit: 1; mask: 0x0002; 0=landscape, 1=portrait - $isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1; + // bit: 1; mask: 0x0002; 0=landscape, 1=portrait + $isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1; - // bit: 2; mask: 0x0004; 1= paper size, scaling factor, paper orient. not init - // when this bit is set, do not use flags for those properties - $isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2; + // bit: 2; mask: 0x0004; 1= paper size, scaling factor, paper orient. not init + // when this bit is set, do not use flags for those properties + $isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2; if (!$isNotInit) { $this->_phpSheet->getPageSetup()->setPaperSize($paperSize); switch ($isPortrait) { - case 0: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); break; - case 1: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); break; + case 0: + $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); + break; + case 1: + $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); + break; } $this->_phpSheet->getPageSetup()->setScale($scale, false); @@ -3461,15 +3530,14 @@ private function _readColInfo() $xfIndex = self::_GetInt2d($recordData, 6); // offset: 8; size: 2; option flags + // bit: 0; mask: 0x0001; 1= columns are hidden + $isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0; - // bit: 0; mask: 0x0001; 1= columns are hidden - $isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0; + // bit: 10-8; mask: 0x0700; outline level of the columns (0 = no outline) + $level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8; - // bit: 10-8; mask: 0x0700; outline level of the columns (0 = no outline) - $level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8; - - // bit: 12; mask: 0x1000; 1 = collapsed - $isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12; + // bit: 12; mask: 0x1000; 1 = collapsed + $isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12; // offset: 10; size: 2; not used @@ -3584,7 +3652,7 @@ private function _readRk() $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { // offset: 4; size: 2; index to XF record $xfIndex = self::_GetInt2d($recordData, 4); @@ -3629,7 +3697,7 @@ private function _readLabelSst() $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { // offset: 4; size: 2; index to XF record $xfIndex = self::_GetInt2d($recordData, 4); @@ -3716,8 +3784,7 @@ private function _readMulRk() $columnString = PHPExcel_Cell::stringFromColumnIndex($colFirst + $i); // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { // offset: var; size: 2; index to XF record $xfIndex = self::_GetInt2d($recordData, $offset); @@ -3762,7 +3829,7 @@ private function _readNumber() $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { // offset 4; size: 2; index to XF record $xfIndex = self::_GetInt2d($recordData, 4); @@ -3829,8 +3896,7 @@ private function _readFormula() } // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { - + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { if ($isPartOfSharedFormula) { // formula is added to this cell after the sheet has been read $this->_sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell; @@ -3842,10 +3908,7 @@ private function _readFormula() $xfIndex = self::_GetInt2d($recordData, 4); // offset: 6; size: 8; result of the formula - if ( (ord($recordData{6}) == 0) - && (ord($recordData{12}) == 255) - && (ord($recordData{13}) == 255) ) { - + if ((ord($recordData{6}) == 0) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { // String formula. Result follows in appended STRING record $dataType = PHPExcel_Cell_DataType::TYPE_STRING; @@ -3857,7 +3920,6 @@ private function _readFormula() // read STRING record $value = $this->_readString(); - } elseif ((ord($recordData{6}) == 1) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { @@ -3865,7 +3927,6 @@ private function _readFormula() // Boolean formula. Result is in +2; 0=false, 1=true $dataType = PHPExcel_Cell_DataType::TYPE_BOOL; $value = (bool) ord($recordData{8}); - } elseif ((ord($recordData{6}) == 2) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { @@ -3873,7 +3934,6 @@ private function _readFormula() // Error formula. Error code is in +2 $dataType = PHPExcel_Cell_DataType::TYPE_ERROR; $value = self::_mapErrorCode(ord($recordData{8})); - } elseif ((ord($recordData{6}) == 3) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { @@ -3881,13 +3941,10 @@ private function _readFormula() // Formula result is a null string $dataType = PHPExcel_Cell_DataType::TYPE_NULL; $value = ''; - } else { - // forumla result is a number, first 14 bytes like _NUMBER record $dataType = PHPExcel_Cell_DataType::TYPE_NUMERIC; $value = self::_extractNumber(substr($recordData, 6, 8)); - } $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); @@ -3951,7 +4008,6 @@ private function _readSharedFmla() // at this point we only store the shared formula for later use $this->_sharedFormulas[$this->_baseCell] = $formula; - } @@ -4006,7 +4062,7 @@ private function _readBoolErr() $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { // offset: 4; size: 2; index to XF record $xfIndex = self::_GetInt2d($recordData, 4); @@ -4024,7 +4080,6 @@ private function _readBoolErr() // add cell value $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL); break; - case 1: // error type $value = self::_mapErrorCode($boolErr); @@ -4150,7 +4205,7 @@ private function _readBlank() $columnString = PHPExcel_Cell::stringFromColumnIndex($col); // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { // offset: 4; size: 2; XF index $xfIndex = self::_GetInt2d($recordData, 4); @@ -4202,18 +4257,18 @@ private function _readObj() // data: var; subrecord data // for now, we are just interested in the second subrecord containing the object type - $ftCmoType = self::_GetInt2d($recordData, 0); - $cbCmoSize = self::_GetInt2d($recordData, 2); - $otObjType = self::_GetInt2d($recordData, 4); + $ftCmoType = self::_GetInt2d($recordData, 0); + $cbCmoSize = self::_GetInt2d($recordData, 2); + $otObjType = self::_GetInt2d($recordData, 4); $idObjID = self::_GetInt2d($recordData, 6); - $grbitOpts = self::_GetInt2d($recordData, 6); + $grbitOpts = self::_GetInt2d($recordData, 6); $this->_objs[] = array( - 'ftCmoType' => $ftCmoType, - 'cbCmoSize' => $cbCmoSize, - 'otObjType' => $otObjType, - 'idObjID' => $idObjID, - 'grbitOpts' => $grbitOpts + 'ftCmoType' => $ftCmoType, + 'cbCmoSize' => $cbCmoSize, + 'otObjType' => $otObjType, + 'idObjID' => $idObjID, + 'grbitOpts' => $grbitOpts ); $this->textObjRef = $idObjID; @@ -4248,9 +4303,13 @@ private function _readWindow2() // offset: 12; size: 2; cached magnification factor in normal view (in percent); 0 = Default (100%) // offset: 14; size: 4; not used $zoomscaleInPageBreakPreview = self::_GetInt2d($recordData, 10); - if ($zoomscaleInPageBreakPreview === 0) $zoomscaleInPageBreakPreview = 60; + if ($zoomscaleInPageBreakPreview === 0) { + $zoomscaleInPageBreakPreview = 60; + } $zoomscaleInNormalView = self::_GetInt2d($recordData, 12); - if ($zoomscaleInNormalView === 0) $zoomscaleInNormalView = 100; + if ($zoomscaleInNormalView === 0) { + $zoomscaleInNormalView = 100; + } } // bit: 1; mask: 0x0002; 0 = do not show gridlines, 1 = show gridlines @@ -4280,11 +4339,10 @@ private function _readWindow2() if ($this->_phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { //NOTE: this setting is inferior to page layout view(Excel2007-) - $view = $isPageBreakPreview? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW : - PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL; + $view = $isPageBreakPreview ? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW : PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL; $this->_phpSheet->getSheetView()->setView($view); if ($this->_version === self::XLS_BIFF8) { - $zoomScale = $isPageBreakPreview? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView; + $zoomScale = $isPageBreakPreview ? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView; $this->_phpSheet->getSheetView()->setZoomScale($zoomScale); $this->_phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView); } @@ -4433,7 +4491,7 @@ private function _readSelection() private function _includeCellRangeFiltered($cellRangeAddress) { $includeCellRange = true; - if ($this->getReadFilter() !== NULL) { + if ($this->getReadFilter() !== null) { $includeCellRange = false; $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($cellRangeAddress); $rangeBoundaries[1][0]++; @@ -4503,24 +4561,23 @@ private function _readHyperLink() // offset: 24, size: 4; unknown value // offset: 28, size: 4; option flags + // bit: 0; mask: 0x00000001; 0 = no link or extant, 1 = file link or URL + $isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0; - // bit: 0; mask: 0x00000001; 0 = no link or extant, 1 = file link or URL - $isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0; - - // bit: 1; mask: 0x00000002; 0 = relative path, 1 = absolute path or URL - $isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1; + // bit: 1; mask: 0x00000002; 0 = relative path, 1 = absolute path or URL + $isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1; - // bit: 2 (and 4); mask: 0x00000014; 0 = no description - $hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2; + // bit: 2 (and 4); mask: 0x00000014; 0 = no description + $hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2; - // bit: 3; mask: 0x00000008; 0 = no text, 1 = has text - $hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3; + // bit: 3; mask: 0x00000008; 0 = no text, 1 = has text + $hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3; - // bit: 7; mask: 0x00000080; 0 = no target frame, 1 = has target frame - $hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7; + // bit: 7; mask: 0x00000080; 0 = no target frame, 1 = has target frame + $hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7; - // bit: 8; mask: 0x00000100; 0 = file link or URL, 1 = UNC path (inc. server name) - $isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8; + // bit: 8; mask: 0x00000100; 0 = file link or URL, 1 = UNC path (inc. server name) + $isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8; // offset within record data $offset = 32; @@ -4551,94 +4608,87 @@ private function _readHyperLink() } switch ($hyperlinkType) { - case 'URL': - // section 5.58.2: Hyperlink containing a URL - // e.g. http://example.org/index.php - - // offset: var; size: 16; GUID of URL Moniker - $offset += 16; - // offset: var; size: 4; size (in bytes) of character array of the URL including trailing zero word - $us = self::_GetInt4d($recordData, $offset); - $offset += 4; - // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated - $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); - $nullOffset = strpos($url, 0x00); - if ($nullOffset) - $url = substr($url,0, $nullOffset); - $url .= $hasText ? '#' : ''; - $offset += $us; - break; - - case 'local': - // section 5.58.3: Hyperlink to local file - // examples: - // mydoc.txt - // ../../somedoc.xls#Sheet!A1 - - // offset: var; size: 16; GUI of File Moniker - $offset += 16; - - // offset: var; size: 2; directory up-level count. - $upLevelCount = self::_GetInt2d($recordData, $offset); - $offset += 2; - - // offset: var; size: 4; character count of the shortened file path and name, including trailing zero word - $sl = self::_GetInt4d($recordData, $offset); - $offset += 4; - - // offset: var; size: sl; character array of the shortened file path and name in 8.3-DOS-format (compressed Unicode string) - $shortenedFilePath = substr($recordData, $offset, $sl); - $shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true); - $shortenedFilePath = substr($shortenedFilePath, 0, -1); // remove trailing zero - - $offset += $sl; + case 'URL': + // section 5.58.2: Hyperlink containing a URL + // e.g. http://example.org/index.php + + // offset: var; size: 16; GUID of URL Moniker + $offset += 16; + // offset: var; size: 4; size (in bytes) of character array of the URL including trailing zero word + $us = self::_GetInt4d($recordData, $offset); + $offset += 4; + // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated + $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); + $nullOffset = strpos($url, 0x00); + if ($nullOffset) + $url = substr($url,0, $nullOffset); + $url .= $hasText ? '#' : ''; + $offset += $us; + break; + case 'local': + // section 5.58.3: Hyperlink to local file + // examples: + // mydoc.txt + // ../../somedoc.xls#Sheet!A1 - // offset: var; size: 24; unknown sequence - $offset += 24; + // offset: var; size: 16; GUI of File Moniker + $offset += 16; - // extended file path - // offset: var; size: 4; size of the following file link field including string lenth mark - $sz = self::_GetInt4d($recordData, $offset); - $offset += 4; + // offset: var; size: 2; directory up-level count. + $upLevelCount = self::_GetInt2d($recordData, $offset); + $offset += 2; - // only present if $sz > 0 - if ($sz > 0) { - // offset: var; size: 4; size of the character array of the extended file path and name - $xl = self::_GetInt4d($recordData, $offset); + // offset: var; size: 4; character count of the shortened file path and name, including trailing zero word + $sl = self::_GetInt4d($recordData, $offset); $offset += 4; - // offset: var; size 2; unknown - $offset += 2; + // offset: var; size: sl; character array of the shortened file path and name in 8.3-DOS-format (compressed Unicode string) + $shortenedFilePath = substr($recordData, $offset, $sl); + $shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true); + $shortenedFilePath = substr($shortenedFilePath, 0, -1); // remove trailing zero - // offset: var; size $xl; character array of the extended file path and name. - $extendedFilePath = substr($recordData, $offset, $xl); - $extendedFilePath = self::_encodeUTF16($extendedFilePath, false); - $offset += $xl; - } + $offset += $sl; - // construct the path - $url = str_repeat('..\\', $upLevelCount); - $url .= ($sz > 0) ? - $extendedFilePath : $shortenedFilePath; // use extended path if available - $url .= $hasText ? '#' : ''; + // offset: var; size: 24; unknown sequence + $offset += 24; - break; + // extended file path + // offset: var; size: 4; size of the following file link field including string lenth mark + $sz = self::_GetInt4d($recordData, $offset); + $offset += 4; + // only present if $sz > 0 + if ($sz > 0) { + // offset: var; size: 4; size of the character array of the extended file path and name + $xl = self::_GetInt4d($recordData, $offset); + $offset += 4; - case 'UNC': - // section 5.58.4: Hyperlink to a File with UNC (Universal Naming Convention) Path - // todo: implement - return; + // offset: var; size 2; unknown + $offset += 2; - case 'workbook': - // section 5.58.5: Hyperlink to the Current Workbook - // e.g. Sheet2!B1:C2, stored in text mark field - $url = 'sheet://'; - break; + // offset: var; size $xl; character array of the extended file path and name. + $extendedFilePath = substr($recordData, $offset, $xl); + $extendedFilePath = self::_encodeUTF16($extendedFilePath, false); + $offset += $xl; + } - default: - return; + // construct the path + $url = str_repeat('..\\', $upLevelCount); + $url .= ($sz > 0) ? $extendedFilePath : $shortenedFilePath; // use extended path if available + $url .= $hasText ? '#' : ''; + break; + case 'UNC': + // section 5.58.4: Hyperlink to a File with UNC (Universal Naming Convention) Path + // todo: implement + return; + case 'workbook': + // section 5.58.5: Hyperlink to the Current Workbook + // e.g. Sheet2!B1:C2, stored in text mark field + $url = 'sheet://'; + break; + default: + return; } if ($hasText) { @@ -4692,22 +4742,44 @@ private function _readDataValidation() // bit: 0-3; mask: 0x0000000F; type $type = (0x0000000F & $options) >> 0; switch ($type) { - case 0x00: $type = PHPExcel_Cell_DataValidation::TYPE_NONE; break; - case 0x01: $type = PHPExcel_Cell_DataValidation::TYPE_WHOLE; break; - case 0x02: $type = PHPExcel_Cell_DataValidation::TYPE_DECIMAL; break; - case 0x03: $type = PHPExcel_Cell_DataValidation::TYPE_LIST; break; - case 0x04: $type = PHPExcel_Cell_DataValidation::TYPE_DATE; break; - case 0x05: $type = PHPExcel_Cell_DataValidation::TYPE_TIME; break; - case 0x06: $type = PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH; break; - case 0x07: $type = PHPExcel_Cell_DataValidation::TYPE_CUSTOM; break; + case 0x00: + $type = PHPExcel_Cell_DataValidation::TYPE_NONE; + break; + case 0x01: + $type = PHPExcel_Cell_DataValidation::TYPE_WHOLE; + break; + case 0x02: + $type = PHPExcel_Cell_DataValidation::TYPE_DECIMAL; + break; + case 0x03: + $type = PHPExcel_Cell_DataValidation::TYPE_LIST; + break; + case 0x04: + $type = PHPExcel_Cell_DataValidation::TYPE_DATE; + break; + case 0x05: + $type = PHPExcel_Cell_DataValidation::TYPE_TIME; + break; + case 0x06: + $type = PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH; + break; + case 0x07: + $type = PHPExcel_Cell_DataValidation::TYPE_CUSTOM; + break; } // bit: 4-6; mask: 0x00000070; error type $errorStyle = (0x00000070 & $options) >> 4; switch ($errorStyle) { - case 0x00: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; break; - case 0x01: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_WARNING; break; - case 0x02: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_INFORMATION; break; + case 0x00: + $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; + break; + case 0x01: + $errorStyle = PHPExcel_Cell_DataValidation::STYLE_WARNING; + break; + case 0x02: + $errorStyle = PHPExcel_Cell_DataValidation::STYLE_INFORMATION; + break; } // bit: 7; mask: 0x00000080; 1= formula is explicit (only applies to list) @@ -4729,39 +4801,51 @@ private function _readDataValidation() // bit: 20-23; mask: 0x00F00000; condition operator $operator = (0x00F00000 & $options) >> 20; switch ($operator) { - case 0x00: $operator = PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN ; break; - case 0x01: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN ; break; - case 0x02: $operator = PHPExcel_Cell_DataValidation::OPERATOR_EQUAL ; break; - case 0x03: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL ; break; - case 0x04: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN ; break; - case 0x05: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN ; break; - case 0x06: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL; break; - case 0x07: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL ; break; + case 0x00: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN; + break; + case 0x01: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN; + break; + case 0x02: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_EQUAL; + break; + case 0x03: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL; + break; + case 0x04: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN; + break; + case 0x05: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN; + break; + case 0x06: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL; + break; + case 0x07: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL; + break; } // offset: 4; size: var; title of the prompt box $offset = 4; $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $promptTitle = $string['value'] !== chr(0) ? - $string['value'] : ''; + $promptTitle = $string['value'] !== chr(0) ? $string['value'] : ''; $offset += $string['size']; // offset: var; size: var; title of the error box $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $errorTitle = $string['value'] !== chr(0) ? - $string['value'] : ''; + $errorTitle = $string['value'] !== chr(0) ? $string['value'] : ''; $offset += $string['size']; // offset: var; size: var; text of the prompt box $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $prompt = $string['value'] !== chr(0) ? - $string['value'] : ''; + $prompt = $string['value'] !== chr(0) ? $string['value'] : ''; $offset += $string['size']; // offset: var; size: var; text of the error box $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $error = $string['value'] !== chr(0) ? - $string['value'] : ''; + $error = $string['value'] !== chr(0) ? $string['value'] : ''; $offset += $string['size']; // offset: var; size: 2; size of the formula data for the first condition @@ -4827,10 +4911,8 @@ private function _readDataValidation() $objValidation->setFormula2($formula2); } } - } - /** * Read SHEETLAYOUT record. Stores sheet tab color information. */ @@ -4861,7 +4943,6 @@ private function _readSheetLayout() $color = self::_readColor($colorIndex, $this->_palette, $this->_version); $this->_phpSheet->getTabColor()->setRGB($color['rgb']); break; - case 0x28: // TODO: Investigate structure for .xls SHEETLAYOUT record as saved by MS Office Excel 2007 return; @@ -5059,55 +5140,52 @@ private function _readImData() $iData = substr($recordData, 8); switch ($cf) { - case 0x09: // Windows bitmap format - // BITMAPCOREINFO - // 1. BITMAPCOREHEADER - // offset: 0; size: 4; bcSize, Specifies the number of bytes required by the structure - $bcSize = self::_GetInt4d($iData, 0); -// var_dump($bcSize); - - // offset: 4; size: 2; bcWidth, specifies the width of the bitmap, in pixels - $bcWidth = self::_GetInt2d($iData, 4); -// var_dump($bcWidth); - - // offset: 6; size: 2; bcHeight, specifies the height of the bitmap, in pixels. - $bcHeight = self::_GetInt2d($iData, 6); -// var_dump($bcHeight); - $ih = imagecreatetruecolor($bcWidth, $bcHeight); - - // offset: 8; size: 2; bcPlanes, specifies the number of planes for the target device. This value must be 1 - - // offset: 10; size: 2; bcBitCount specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24 - $bcBitCount = self::_GetInt2d($iData, 10); -// var_dump($bcBitCount); - - $rgbString = substr($iData, 12); - $rgbTriples = array(); - while (strlen($rgbString) > 0) { - $rgbTriples[] = unpack('Cb/Cg/Cr', $rgbString); - $rgbString = substr($rgbString, 3); - } - $x = 0; - $y = 0; - foreach ($rgbTriples as $i => $rgbTriple) { - $color = imagecolorallocate($ih, $rgbTriple['r'], $rgbTriple['g'], $rgbTriple['b']); - imagesetpixel($ih, $x, $bcHeight - 1 - $y, $color); - $x = ($x + 1) % $bcWidth; - $y = $y + floor(($x + 1) / $bcWidth); - } - //imagepng($ih, 'image.png'); - - $drawing = new PHPExcel_Worksheet_Drawing(); - $drawing->setPath($filename); - $drawing->setWorksheet($this->_phpSheet); - - break; - - case 0x02: // Windows metafile or Macintosh PICT format - case 0x0e: // native format - default; - break; + case 0x09: // Windows bitmap format + // BITMAPCOREINFO + // 1. BITMAPCOREHEADER + // offset: 0; size: 4; bcSize, Specifies the number of bytes required by the structure + $bcSize = self::_GetInt4d($iData, 0); + // var_dump($bcSize); + + // offset: 4; size: 2; bcWidth, specifies the width of the bitmap, in pixels + $bcWidth = self::_GetInt2d($iData, 4); + // var_dump($bcWidth); + + // offset: 6; size: 2; bcHeight, specifies the height of the bitmap, in pixels. + $bcHeight = self::_GetInt2d($iData, 6); + // var_dump($bcHeight); + $ih = imagecreatetruecolor($bcWidth, $bcHeight); + + // offset: 8; size: 2; bcPlanes, specifies the number of planes for the target device. This value must be 1 + + // offset: 10; size: 2; bcBitCount specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24 + $bcBitCount = self::_GetInt2d($iData, 10); + // var_dump($bcBitCount); + + $rgbString = substr($iData, 12); + $rgbTriples = array(); + while (strlen($rgbString) > 0) { + $rgbTriples[] = unpack('Cb/Cg/Cr', $rgbString); + $rgbString = substr($rgbString, 3); + } + $x = 0; + $y = 0; + foreach ($rgbTriples as $i => $rgbTriple) { + $color = imagecolorallocate($ih, $rgbTriple['r'], $rgbTriple['g'], $rgbTriple['b']); + imagesetpixel($ih, $x, $bcHeight - 1 - $y, $color); + $x = ($x + 1) % $bcWidth; + $y = $y + floor(($x + 1) / $bcWidth); + } + //imagepng($ih, 'image.png'); + $drawing = new PHPExcel_Worksheet_Drawing(); + $drawing->setPath($filename); + $drawing->setWorksheet($this->_phpSheet); + break; + case 0x02: // Windows metafile or Macintosh PICT format + case 0x0e: // native format + default; + break; } // _getSplicedRecordData() takes care of moving current position in data stream @@ -5160,7 +5238,6 @@ private function _readContinue() // move stream pointer to next record $this->_pos += 4 + $length; - } @@ -5193,8 +5270,7 @@ private function _getSplicedRecordData() $this->_pos += 4 + $length; $nextIdentifier = self::_GetInt2d($this->_data, $this->_pos); - } - while ($nextIdentifier == self::XLS_Type_CONTINUE); + } while ($nextIdentifier == self::XLS_Type_CONTINUE); $splicedData = array( 'recordData' => $data, @@ -5236,7 +5312,6 @@ private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') //echo 'the entire additional data: '; //Debug::dump($additionalData); //echo "\n----\n"; - } else { $additionalData = ''; } @@ -5298,132 +5373,132 @@ private function _createFormulaFromTokens($tokens, $additionalData) $space5 = isset($space5) ? $space5 : ''; // carriage returns before closing parenthesis switch ($token['name']) { - case 'tAdd': // addition - case 'tConcat': // addition - case 'tDiv': // division - case 'tEQ': // equality - case 'tGE': // greater than or equal - case 'tGT': // greater than - case 'tIsect': // intersection - case 'tLE': // less than or equal - case 'tList': // less than or equal - case 'tLT': // less than - case 'tMul': // multiplication - case 'tNE': // multiplication - case 'tPower': // power - case 'tRange': // range - case 'tSub': // subtraction - $op2 = array_pop($formulaStrings); - $op1 = array_pop($formulaStrings); - $formulaStrings[] = "$op1$space1$space0{$token['data']}$op2"; - unset($space0, $space1); - break; - case 'tUplus': // unary plus - case 'tUminus': // unary minus - $op = array_pop($formulaStrings); - $formulaStrings[] = "$space1$space0{$token['data']}$op"; - unset($space0, $space1); - break; - case 'tPercent': // percent sign - $op = array_pop($formulaStrings); - $formulaStrings[] = "$op$space1$space0{$token['data']}"; - unset($space0, $space1); - break; - case 'tAttrVolatile': // indicates volatile function - case 'tAttrIf': - case 'tAttrSkip': - case 'tAttrChoose': - // token is only important for Excel formula evaluator - // do nothing - break; - case 'tAttrSpace': // space / carriage return - // space will be used when next token arrives, do not alter formulaString stack - switch ($token['data']['spacetype']) { - case 'type0': - $space0 = str_repeat(' ', $token['data']['spacecount']); + case 'tAdd': // addition + case 'tConcat': // addition + case 'tDiv': // division + case 'tEQ': // equality + case 'tGE': // greater than or equal + case 'tGT': // greater than + case 'tIsect': // intersection + case 'tLE': // less than or equal + case 'tList': // less than or equal + case 'tLT': // less than + case 'tMul': // multiplication + case 'tNE': // multiplication + case 'tPower': // power + case 'tRange': // range + case 'tSub': // subtraction + $op2 = array_pop($formulaStrings); + $op1 = array_pop($formulaStrings); + $formulaStrings[] = "$op1$space1$space0{$token['data']}$op2"; + unset($space0, $space1); break; - case 'type1': - $space1 = str_repeat("\n", $token['data']['spacecount']); + case 'tUplus': // unary plus + case 'tUminus': // unary minus + $op = array_pop($formulaStrings); + $formulaStrings[] = "$space1$space0{$token['data']}$op"; + unset($space0, $space1); break; - case 'type2': - $space2 = str_repeat(' ', $token['data']['spacecount']); + case 'tPercent': // percent sign + $op = array_pop($formulaStrings); + $formulaStrings[] = "$op$space1$space0{$token['data']}"; + unset($space0, $space1); break; - case 'type3': - $space3 = str_repeat("\n", $token['data']['spacecount']); + case 'tAttrVolatile': // indicates volatile function + case 'tAttrIf': + case 'tAttrSkip': + case 'tAttrChoose': + // token is only important for Excel formula evaluator + // do nothing break; - case 'type4': - $space4 = str_repeat(' ', $token['data']['spacecount']); + case 'tAttrSpace': // space / carriage return + // space will be used when next token arrives, do not alter formulaString stack + switch ($token['data']['spacetype']) { + case 'type0': + $space0 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type1': + $space1 = str_repeat("\n", $token['data']['spacecount']); + break; + case 'type2': + $space2 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type3': + $space3 = str_repeat("\n", $token['data']['spacecount']); + break; + case 'type4': + $space4 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type5': + $space5 = str_repeat("\n", $token['data']['spacecount']); + break; + } break; - case 'type5': - $space5 = str_repeat("\n", $token['data']['spacecount']); + case 'tAttrSum': // SUM function with one parameter + $op = array_pop($formulaStrings); + $formulaStrings[] = "{$space1}{$space0}SUM($op)"; + unset($space0, $space1); break; - } - break; - case 'tAttrSum': // SUM function with one parameter - $op = array_pop($formulaStrings); - $formulaStrings[] = "{$space1}{$space0}SUM($op)"; - unset($space0, $space1); - break; - case 'tFunc': // function with fixed number of arguments - case 'tFuncV': // function with variable number of arguments - if ($token['data']['function'] != '') { - // normal function - $ops = array(); // array of operators - for ($i = 0; $i < $token['data']['args']; ++$i) { - $ops[] = array_pop($formulaStrings); + case 'tFunc': // function with fixed number of arguments + case 'tFuncV': // function with variable number of arguments + if ($token['data']['function'] != '') { + // normal function + $ops = array(); // array of operators + for ($i = 0; $i < $token['data']['args']; ++$i) { + $ops[] = array_pop($formulaStrings); + } + $ops = array_reverse($ops); + $formulaStrings[] = "$space1$space0{$token['data']['function']}(" . implode(',', $ops) . ")"; + unset($space0, $space1); + } else { + // add-in function + $ops = array(); // array of operators + for ($i = 0; $i < $token['data']['args'] - 1; ++$i) { + $ops[] = array_pop($formulaStrings); + } + $ops = array_reverse($ops); + $function = array_pop($formulaStrings); + $formulaStrings[] = "$space1$space0$function(" . implode(',', $ops) . ")"; + unset($space0, $space1); } - $ops = array_reverse($ops); - $formulaStrings[] = "$space1$space0{$token['data']['function']}(" . implode(',', $ops) . ")"; + break; + case 'tParen': // parenthesis + $expression = array_pop($formulaStrings); + $formulaStrings[] = "$space3$space2($expression$space5$space4)"; + unset($space2, $space3, $space4, $space5); + break; + case 'tArray': // array constant + $constantArray = self::_readBIFF8ConstantArray($additionalData); + $formulaStrings[] = $space1 . $space0 . $constantArray['value']; + $additionalData = substr($additionalData, $constantArray['size']); // bite of chunk of additional data unset($space0, $space1); - } else { - // add-in function - $ops = array(); // array of operators - for ($i = 0; $i < $token['data']['args'] - 1; ++$i) { - $ops[] = array_pop($formulaStrings); - } - $ops = array_reverse($ops); - $function = array_pop($formulaStrings); - $formulaStrings[] = "$space1$space0$function(" . implode(',', $ops) . ")"; + break; + case 'tMemArea': + // bite off chunk of additional data + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData); + $additionalData = substr($additionalData, $cellRangeAddressList['size']); + $formulaStrings[] = "$space1$space0{$token['data']}"; unset($space0, $space1); - } - break; - case 'tParen': // parenthesis - $expression = array_pop($formulaStrings); - $formulaStrings[] = "$space3$space2($expression$space5$space4)"; - unset($space2, $space3, $space4, $space5); - break; - case 'tArray': // array constant - $constantArray = self::_readBIFF8ConstantArray($additionalData); - $formulaStrings[] = $space1 . $space0 . $constantArray['value']; - $additionalData = substr($additionalData, $constantArray['size']); // bite of chunk of additional data - unset($space0, $space1); - break; - case 'tMemArea': - // bite off chunk of additional data - $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData); - $additionalData = substr($additionalData, $cellRangeAddressList['size']); - $formulaStrings[] = "$space1$space0{$token['data']}"; - unset($space0, $space1); - break; - case 'tArea': // cell range address - case 'tBool': // boolean - case 'tErr': // error code - case 'tInt': // integer - case 'tMemErr': - case 'tMemFunc': - case 'tMissArg': - case 'tName': - case 'tNameX': - case 'tNum': // number - case 'tRef': // single cell reference - case 'tRef3d': // 3d cell reference - case 'tArea3d': // 3d cell range reference - case 'tRefN': - case 'tAreaN': - case 'tStr': // string - $formulaStrings[] = "$space1$space0{$token['data']}"; - unset($space0, $space1); - break; + break; + case 'tArea': // cell range address + case 'tBool': // boolean + case 'tErr': // error code + case 'tInt': // integer + case 'tMemErr': + case 'tMemFunc': + case 'tMissArg': + case 'tName': + case 'tNameX': + case 'tNum': // number + case 'tRef': // single cell reference + case 'tRef3d': // 3d cell reference + case 'tArea3d': // 3d cell range reference + case 'tRefN': + case 'tAreaN': + case 'tStr': // string + $formulaStrings[] = "$space1$space0{$token['data']}"; + unset($space0, $space1); + break; } } $formulaString = $formulaStrings[0]; @@ -5451,546 +5526,1268 @@ private function _getNextToken($formulaData, $baseCell = 'A1') $name = false; // initialize token name switch ($id) { - case 0x03: $name = 'tAdd'; $size = 1; $data = '+'; break; - case 0x04: $name = 'tSub'; $size = 1; $data = '-'; break; - case 0x05: $name = 'tMul'; $size = 1; $data = '*'; break; - case 0x06: $name = 'tDiv'; $size = 1; $data = '/'; break; - case 0x07: $name = 'tPower'; $size = 1; $data = '^'; break; - case 0x08: $name = 'tConcat'; $size = 1; $data = '&'; break; - case 0x09: $name = 'tLT'; $size = 1; $data = '<'; break; - case 0x0A: $name = 'tLE'; $size = 1; $data = '<='; break; - case 0x0B: $name = 'tEQ'; $size = 1; $data = '='; break; - case 0x0C: $name = 'tGE'; $size = 1; $data = '>='; break; - case 0x0D: $name = 'tGT'; $size = 1; $data = '>'; break; - case 0x0E: $name = 'tNE'; $size = 1; $data = '<>'; break; - case 0x0F: $name = 'tIsect'; $size = 1; $data = ' '; break; - case 0x10: $name = 'tList'; $size = 1; $data = ','; break; - case 0x11: $name = 'tRange'; $size = 1; $data = ':'; break; - case 0x12: $name = 'tUplus'; $size = 1; $data = '+'; break; - case 0x13: $name = 'tUminus'; $size = 1; $data = '-'; break; - case 0x14: $name = 'tPercent'; $size = 1; $data = '%'; break; - case 0x15: // parenthesis - $name = 'tParen'; - $size = 1; - $data = null; - break; - case 0x16: // missing argument - $name = 'tMissArg'; - $size = 1; - $data = ''; - break; - case 0x17: // string - $name = 'tStr'; - // offset: 1; size: var; Unicode string, 8-bit string length - $string = self::_readUnicodeStringShort(substr($formulaData, 1)); - $size = 1 + $string['size']; - $data = self::_UTF8toExcelDoubleQuoted($string['value']); - break; - case 0x19: // Special attribute - // offset: 1; size: 1; attribute type flags: - switch (ord($formulaData[1])) { - case 0x01: - $name = 'tAttrVolatile'; - $size = 4; - $data = null; - break; - case 0x02: - $name = 'tAttrIf'; - $size = 4; - $data = null; + case 0x03: + $name = 'tAdd'; + $size = 1; + $data = '+'; break; case 0x04: - $name = 'tAttrChoose'; - // offset: 2; size: 2; number of choices in the CHOOSE function ($nc, number of parameters decreased by 1) - $nc = self::_GetInt2d($formulaData, 2); - // offset: 4; size: 2 * $nc - // offset: 4 + 2 * $nc; size: 2 - $size = 2 * $nc + 6; - $data = null; + $name = 'tSub'; + $size = 1; + $data = '-'; + break; + case 0x05: + $name = 'tMul'; + $size = 1; + $data = '*'; + break; + case 0x06: + $name = 'tDiv'; + $size = 1; + $data = '/'; + break; + case 0x07: + $name = 'tPower'; + $size = 1; + $data = '^'; break; case 0x08: - $name = 'tAttrSkip'; - $size = 4; - $data = null; + $name = 'tConcat'; + $size = 1; + $data = '&'; + break; + case 0x09: + $name = 'tLT'; + $size = 1; + $data = '<'; + break; + case 0x0A: + $name = 'tLE'; + $size = 1; + $data = '<='; + break; + case 0x0B: + $name = 'tEQ'; + $size = 1; + $data = '='; + break; + case 0x0C: + $name = 'tGE'; + $size = 1; + $data = '>='; + break; + case 0x0D: + $name = 'tGT'; + $size = 1; + $data = '>'; + break; + case 0x0E: + $name = 'tNE'; + $size = 1; + $data = '<>'; + break; + case 0x0F: + $name = 'tIsect'; + $size = 1; + $data = ' '; break; case 0x10: - $name = 'tAttrSum'; - $size = 4; + $name = 'tList'; + $size = 1; + $data = ','; + break; + case 0x11: + $name = 'tRange'; + $size = 1; + $data = ':'; + break; + case 0x12: + $name = 'tUplus'; + $size = 1; + $data = '+'; + break; + case 0x13: + $name = 'tUminus'; + $size = 1; + $data = '-'; + break; + case 0x14: + $name = 'tPercent'; + $size = 1; + $data = '%'; + break; + case 0x15: // parenthesis + $name = 'tParen'; + $size = 1; $data = null; break; + case 0x16: // missing argument + $name = 'tMissArg'; + $size = 1; + $data = ''; + break; + case 0x17: // string + $name = 'tStr'; + // offset: 1; size: var; Unicode string, 8-bit string length + $string = self::_readUnicodeStringShort(substr($formulaData, 1)); + $size = 1 + $string['size']; + $data = self::_UTF8toExcelDoubleQuoted($string['value']); + break; + case 0x19: // Special attribute + // offset: 1; size: 1; attribute type flags: + switch (ord($formulaData[1])) { + case 0x01: + $name = 'tAttrVolatile'; + $size = 4; + $data = null; + break; + case 0x02: + $name = 'tAttrIf'; + $size = 4; + $data = null; + break; + case 0x04: + $name = 'tAttrChoose'; + // offset: 2; size: 2; number of choices in the CHOOSE function ($nc, number of parameters decreased by 1) + $nc = self::_GetInt2d($formulaData, 2); + // offset: 4; size: 2 * $nc + // offset: 4 + 2 * $nc; size: 2 + $size = 2 * $nc + 6; + $data = null; + break; + case 0x08: + $name = 'tAttrSkip'; + $size = 4; + $data = null; + break; + case 0x10: + $name = 'tAttrSum'; + $size = 4; + $data = null; + break; + case 0x40: + case 0x41: + $name = 'tAttrSpace'; + $size = 4; + // offset: 2; size: 2; space type and position + switch (ord($formulaData[2])) { + case 0x00: + $spacetype = 'type0'; + break; + case 0x01: + $spacetype = 'type1'; + break; + case 0x02: + $spacetype = 'type2'; + break; + case 0x03: + $spacetype = 'type3'; + break; + case 0x04: + $spacetype = 'type4'; + break; + case 0x05: + $spacetype = 'type5'; + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized space type in tAttrSpace token'); + break; + } + // offset: 3; size: 1; number of inserted spaces/carriage returns + $spacecount = ord($formulaData[3]); + + $data = array('spacetype' => $spacetype, 'spacecount' => $spacecount); + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized attribute flag in tAttr token'); + break; + } + break; + case 0x1C: // error code + // offset: 1; size: 1; error code + $name = 'tErr'; + $size = 2; + $data = self::_mapErrorCode(ord($formulaData[1])); + break; + case 0x1D: // boolean + // offset: 1; size: 1; 0 = false, 1 = true; + $name = 'tBool'; + $size = 2; + $data = ord($formulaData[1]) ? 'TRUE' : 'FALSE'; + break; + case 0x1E: // integer + // offset: 1; size: 2; unsigned 16-bit integer + $name = 'tInt'; + $size = 3; + $data = self::_GetInt2d($formulaData, 1); + break; + case 0x1F: // number + // offset: 1; size: 8; + $name = 'tNum'; + $size = 9; + $data = self::_extractNumber(substr($formulaData, 1)); + $data = str_replace(',', '.', (string)$data); // in case non-English locale + break; + case 0x20: // array constant case 0x40: + case 0x60: + // offset: 1; size: 7; not used + $name = 'tArray'; + $size = 8; + $data = null; + break; + case 0x21: // function with fixed number of arguments case 0x41: - $name = 'tAttrSpace'; + case 0x61: + $name = 'tFunc'; + $size = 3; + // offset: 1; size: 2; index to built-in sheet function + switch (self::_GetInt2d($formulaData, 1)) { + case 2: + $function = 'ISNA'; + $args = 1; + break; + case 3: + $function = 'ISERROR'; + $args = 1; + break; + case 10: + $function = 'NA'; + $args = 0; + break; + case 15: + $function = 'SIN'; + $args = 1; + break; + case 16: + $function = 'COS'; + $args = 1; + break; + case 17: + $function = 'TAN'; + $args = 1; + break; + case 18: + $function = 'ATAN'; + $args = 1; + break; + case 19: + $function = 'PI'; + $args = 0; + break; + case 20: + $function = 'SQRT'; + $args = 1; + break; + case 21: + $function = 'EXP'; + $args = 1; + break; + case 22: + $function = 'LN'; + $args = 1; + break; + case 23: + $function = 'LOG10'; + $args = 1; + break; + case 24: + $function = 'ABS'; + $args = 1; + break; + case 25: + $function = 'INT'; + $args = 1; + break; + case 26: + $function = 'SIGN'; + $args = 1; + break; + case 27: + $function = 'ROUND'; + $args = 2; + break; + case 30: + $function = 'REPT'; + $args = 2; + break; + case 31: + $function = 'MID'; + $args = 3; + break; + case 32: + $function = 'LEN'; + $args = 1; + break; + case 33: + $function = 'VALUE'; + $args = 1; + break; + case 34: + $function = 'TRUE'; + $args = 0; + break; + case 35: + $function = 'FALSE'; + $args = 0; + break; + case 38: + $function = 'NOT'; + $args = 1; + break; + case 39: + $function = 'MOD'; + $args = 2; + break; + case 40: + $function = 'DCOUNT'; + $args = 3; + break; + case 41: + $function = 'DSUM'; + $args = 3; + break; + case 42: + $function = 'DAVERAGE'; + $args = 3; + break; + case 43: + $function = 'DMIN'; + $args = 3; + break; + case 44: + $function = 'DMAX'; + $args = 3; + break; + case 45: + $function = 'DSTDEV'; + $args = 3; + break; + case 48: + $function = 'TEXT'; + $args = 2; + break; + case 61: + $function = 'MIRR'; + $args = 3; + break; + case 63: + $function = 'RAND'; + $args = 0; + break; + case 65: + $function = 'DATE'; + $args = 3; + break; + case 66: + $function = 'TIME'; + $args = 3; + break; + case 67: + $function = 'DAY'; + $args = 1; + break; + case 68: + $function = 'MONTH'; + $args = 1; + break; + case 69: + $function = 'YEAR'; + $args = 1; + break; + case 71: + $function = 'HOUR'; + $args = 1; + break; + case 72: + $function = 'MINUTE'; + $args = 1; + break; + case 73: + $function = 'SECOND'; + $args = 1; + break; + case 74: + $function = 'NOW'; + $args = 0; + break; + case 75: + $function = 'AREAS'; + $args = 1; + break; + case 76: + $function = 'ROWS'; + $args = 1; + break; + case 77: + $function = 'COLUMNS'; + $args = 1; + break; + case 83: + $function = 'TRANSPOSE'; + $args = 1; + break; + case 86: + $function = 'TYPE'; + $args = 1; + break; + case 97: + $function = 'ATAN2'; + $args = 2; + break; + case 98: + $function = 'ASIN'; + $args = 1; + break; + case 99: + $function = 'ACOS'; + $args = 1; + break; + case 105: + $function = 'ISREF'; + $args = 1; + break; + case 111: + $function = 'CHAR'; + $args = 1; + break; + case 112: + $function = 'LOWER'; + $args = 1; + break; + case 113: + $function = 'UPPER'; + $args = 1; + break; + case 114: + $function = 'PROPER'; + $args = 1; + break; + case 117: + $function = 'EXACT'; + $args = 2; + break; + case 118: + $function = 'TRIM'; + $args = 1; + break; + case 119: + $function = 'REPLACE'; + $args = 4; + break; + case 121: + $function = 'CODE'; + $args = 1; + break; + case 126: + $function = 'ISERR'; + $args = 1; + break; + case 127: + $function = 'ISTEXT'; + $args = 1; + break; + case 128: + $function = 'ISNUMBER'; + $args = 1; + break; + case 129: + $function = 'ISBLANK'; + $args = 1; + break; + case 130: + $function = 'T'; + $args = 1; + break; + case 131: + $function = 'N'; + $args = 1; + break; + case 140: + $function = 'DATEVALUE'; + $args = 1; + break; + case 141: + $function = 'TIMEVALUE'; + $args = 1; + break; + case 142: + $function = 'SLN'; + $args = 3; + break; + case 143: + $function = 'SYD'; + $args = 4; + break; + case 162: + $function = 'CLEAN'; + $args = 1; + break; + case 163: + $function = 'MDETERM'; + $args = 1; + break; + case 164: + $function = 'MINVERSE'; + $args = 1; + break; + case 165: + $function = 'MMULT'; + $args = 2; + break; + case 184: + $function = 'FACT'; + $args = 1; + break; + case 189: + $function = 'DPRODUCT'; + $args = 3; + break; + case 190: + $function = 'ISNONTEXT'; + $args = 1; + break; + case 195: + $function = 'DSTDEVP'; + $args = 3; + break; + case 196: + $function = 'DVARP'; + $args = 3; + break; + case 198: + $function = 'ISLOGICAL'; + $args = 1; + break; + case 199: + $function = 'DCOUNTA'; + $args = 3; + break; + case 207: + $function = 'REPLACEB'; + $args = 4; + break; + case 210: + $function = 'MIDB'; + $args = 3; + break; + case 211: + $function = 'LENB'; + $args = 1; + break; + case 212: + $function = 'ROUNDUP'; + $args = 2; + break; + case 213: + $function = 'ROUNDDOWN'; + $args = 2; + break; + case 214: + $function = 'ASC'; + $args = 1; + break; + case 215: + $function = 'DBCS'; + $args = 1; + break; + case 221: + $function = 'TODAY'; + $args = 0; + break; + case 229: + $function = 'SINH'; + $args = 1; + break; + case 230: + $function = 'COSH'; + $args = 1; + break; + case 231: + $function = 'TANH'; + $args = 1; + break; + case 232: + $function = 'ASINH'; + $args = 1; + break; + case 233: + $function = 'ACOSH'; + $args = 1; + break; + case 234: + $function = 'ATANH'; + $args = 1; + break; + case 235: + $function = 'DGET'; + $args = 3; + break; + case 244: + $function = 'INFO'; + $args = 1; + break; + case 252: + $function = 'FREQUENCY'; + $args = 2; + break; + case 261: + $function = 'ERROR.TYPE'; + $args = 1; + break; + case 271: + $function = 'GAMMALN'; + $args = 1; + break; + case 273: + $function = 'BINOMDIST'; + $args = 4; + break; + case 274: + $function = 'CHIDIST'; + $args = 2; + break; + case 275: + $function = 'CHIINV'; + $args = 2; + break; + case 276: + $function = 'COMBIN'; + $args = 2; + break; + case 277: + $function = 'CONFIDENCE'; + $args = 3; + break; + case 278: + $function = 'CRITBINOM'; + $args = 3; + break; + case 279: + $function = 'EVEN'; + $args = 1; + break; + case 280: + $function = 'EXPONDIST'; + $args = 3; + break; + case 281: + $function = 'FDIST'; + $args = 3; + break; + case 282: + $function = 'FINV'; + $args = 3; + break; + case 283: + $function = 'FISHER'; + $args = 1; + break; + case 284: + $function = 'FISHERINV'; + $args = 1; + break; + case 285: + $function = 'FLOOR'; + $args = 2; + break; + case 286: + $function = 'GAMMADIST'; + $args = 4; + break; + case 287: + $function = 'GAMMAINV'; + $args = 3; + break; + case 288: + $function = 'CEILING'; + $args = 2; + break; + case 289: + $function = 'HYPGEOMDIST'; + $args = 4; + break; + case 290: + $function = 'LOGNORMDIST'; + $args = 3; + break; + case 291: + $function = 'LOGINV'; + $args = 3; + break; + case 292: + $function = 'NEGBINOMDIST'; + $args = 3; + break; + case 293: + $function = 'NORMDIST'; + $args = 4; + break; + case 294: + $function = 'NORMSDIST'; + $args = 1; + break; + case 295: + $function = 'NORMINV'; + $args = 3; + break; + case 296: + $function = 'NORMSINV'; + $args = 1; + break; + case 297: + $function = 'STANDARDIZE'; + $args = 3; + break; + case 298: + $function = 'ODD'; + $args = 1; + break; + case 299: + $function = 'PERMUT'; + $args = 2; + break; + case 300: + $function = 'POISSON'; + $args = 3; + break; + case 301: + $function = 'TDIST'; + $args = 3; + break; + case 302: + $function = 'WEIBULL'; + $args = 4; + break; + case 303: + $function = 'SUMXMY2'; + $args = 2; + break; + case 304: + $function = 'SUMX2MY2'; + $args = 2; + break; + case 305: + $function = 'SUMX2PY2'; + $args = 2; + break; + case 306: + $function = 'CHITEST'; + $args = 2; + break; + case 307: + $function = 'CORREL'; + $args = 2; + break; + case 308: + $function = 'COVAR'; + $args = 2; + break; + case 309: + $function = 'FORECAST'; + $args = 3; + break; + case 310: + $function = 'FTEST'; + $args = 2; + break; + case 311: + $function = 'INTERCEPT'; + $args = 2; + break; + case 312: + $function = 'PEARSON'; + $args = 2; + break; + case 313: + $function = 'RSQ'; + $args = 2; + break; + case 314: + $function = 'STEYX'; + $args = 2; + break; + case 315: + $function = 'SLOPE'; + $args = 2; + break; + case 316: + $function = 'TTEST'; + $args = 4; + break; + case 325: + $function = 'LARGE'; + $args = 2; + break; + case 326: + $function = 'SMALL'; + $args = 2; + break; + case 327: + $function = 'QUARTILE'; + $args = 2; + break; + case 328: + $function = 'PERCENTILE'; + $args = 2; + break; + case 331: + $function = 'TRIMMEAN'; + $args = 2; + break; + case 332: + $function = 'TINV'; + $args = 2; + break; + case 337: + $function = 'POWER'; + $args = 2; + break; + case 342: + $function = 'RADIANS'; + $args = 1; + break; + case 343: + $function = 'DEGREES'; + $args = 1; + break; + case 346: + $function = 'COUNTIF'; + $args = 2; + break; + case 347: + $function = 'COUNTBLANK'; + $args = 1; + break; + case 350: + $function = 'ISPMT'; + $args = 4; + break; + case 351: + $function = 'DATEDIF'; + $args = 3; + break; + case 352: + $function = 'DATESTRING'; + $args = 1; + break; + case 353: + $function = 'NUMBERSTRING'; + $args = 2; + break; + case 360: + $function = 'PHONETIC'; + $args = 1; + break; + case 368: + $function = 'BAHTTEXT'; + $args = 1; + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + break; + } + $data = array('function' => $function, 'args' => $args); + break; + case 0x22: // function with variable number of arguments + case 0x42: + case 0x62: + $name = 'tFuncV'; $size = 4; - // offset: 2; size: 2; space type and position - switch (ord($formulaData[2])) { - case 0x00: - $spacetype = 'type0'; - break; - case 0x01: - $spacetype = 'type1'; - break; - case 0x02: - $spacetype = 'type2'; - break; - case 0x03: - $spacetype = 'type3'; - break; - case 0x04: - $spacetype = 'type4'; - break; - case 0x05: - $spacetype = 'type5'; - break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized space type in tAttrSpace token'); - break; + // offset: 1; size: 1; number of arguments + $args = ord($formulaData[1]); + // offset: 2: size: 2; index to built-in sheet function + $index = self::_GetInt2d($formulaData, 2); + switch ($index) { + case 0: + $function = 'COUNT'; + break; + case 1: + $function = 'IF'; + break; + case 4: + $function = 'SUM'; + break; + case 5: + $function = 'AVERAGE'; + break; + case 6: + $function = 'MIN'; + break; + case 7: + $function = 'MAX'; + break; + case 8: + $function = 'ROW'; + break; + case 9: + $function = 'COLUMN'; + break; + case 11: + $function = 'NPV'; + break; + case 12: + $function = 'STDEV'; + break; + case 13: + $function = 'DOLLAR'; + break; + case 14: + $function = 'FIXED'; + break; + case 28: + $function = 'LOOKUP'; + break; + case 29: + $function = 'INDEX'; + break; + case 36: + $function = 'AND'; + break; + case 37: + $function = 'OR'; + break; + case 46: + $function = 'VAR'; + break; + case 49: + $function = 'LINEST'; + break; + case 50: + $function = 'TREND'; + break; + case 51: + $function = 'LOGEST'; + break; + case 52: + $function = 'GROWTH'; + break; + case 56: + $function = 'PV'; + break; + case 57: + $function = 'FV'; + break; + case 58: + $function = 'NPER'; + break; + case 59: + $function = 'PMT'; + break; + case 60: + $function = 'RATE'; + break; + case 62: + $function = 'IRR'; + break; + case 64: + $function = 'MATCH'; + break; + case 70: + $function = 'WEEKDAY'; + break; + case 78: + $function = 'OFFSET'; + break; + case 82: + $function = 'SEARCH'; + break; + case 100: + $function = 'CHOOSE'; + break; + case 101: + $function = 'HLOOKUP'; + break; + case 102: + $function = 'VLOOKUP'; + break; + case 109: + $function = 'LOG'; + break; + case 115: + $function = 'LEFT'; + break; + case 116: + $function = 'RIGHT'; + break; + case 120: + $function = 'SUBSTITUTE'; + break; + case 124: + $function = 'FIND'; + break; + case 125: + $function = 'CELL'; + break; + case 144: + $function = 'DDB'; + break; + case 148: + $function = 'INDIRECT'; + break; + case 167: + $function = 'IPMT'; + break; + case 168: + $function = 'PPMT'; + break; + case 169: + $function = 'COUNTA'; + break; + case 183: + $function = 'PRODUCT'; + break; + case 193: + $function = 'STDEVP'; + break; + case 194: + $function = 'VARP'; + break; + case 197: + $function = 'TRUNC'; + break; + case 204: + $function = 'USDOLLAR'; + break; + case 205: + $function = 'FINDB'; + break; + case 206: + $function = 'SEARCHB'; + break; + case 208: + $function = 'LEFTB'; + break; + case 209: + $function = 'RIGHTB'; + break; + case 216: + $function = 'RANK'; + break; + case 219: + $function = 'ADDRESS'; + break; + case 220: + $function = 'DAYS360'; + break; + case 222: + $function = 'VDB'; + break; + case 227: + $function = 'MEDIAN'; + break; + case 228: + $function = 'SUMPRODUCT'; + break; + case 247: + $function = 'DB'; + break; + case 255: + $function = ''; + break; + case 269: + $function = 'AVEDEV'; + break; + case 270: + $function = 'BETADIST'; + break; + case 272: + $function = 'BETAINV'; + break; + case 317: + $function = 'PROB'; + break; + case 318: + $function = 'DEVSQ'; + break; + case 319: + $function = 'GEOMEAN'; + break; + case 320: + $function = 'HARMEAN'; + break; + case 321: + $function = 'SUMSQ'; + break; + case 322: + $function = 'KURT'; + break; + case 323: + $function = 'SKEW'; + break; + case 324: + $function = 'ZTEST'; + break; + case 329: + $function = 'PERCENTRANK'; + break; + case 330: + $function = 'MODE'; + break; + case 336: + $function = 'CONCATENATE'; + break; + case 344: + $function = 'SUBTOTAL'; + break; + case 345: + $function = 'SUMIF'; + break; + case 354: + $function = 'ROMAN'; + break; + case 358: + $function = 'GETPIVOTDATA'; + break; + case 359: + $function = 'HYPERLINK'; + break; + case 361: + $function = 'AVERAGEA'; + break; + case 362: + $function = 'MAXA'; + break; + case 363: + $function = 'MINA'; + break; + case 364: + $function = 'STDEVPA'; + break; + case 365: + $function = 'VARPA'; + break; + case 366: + $function = 'STDEVA'; + break; + case 367: + $function = 'VARA'; + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + break; } - // offset: 3; size: 1; number of inserted spaces/carriage returns - $spacecount = ord($formulaData[3]); - - $data = array('spacetype' => $spacetype, 'spacecount' => $spacecount); + $data = array('function' => $function, 'args' => $args); break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized attribute flag in tAttr token'); + case 0x23: // index to defined name + case 0x43: + case 0x63: + $name = 'tName'; + $size = 5; + // offset: 1; size: 2; one-based index to definedname record + $definedNameIndex = self::_GetInt2d($formulaData, 1) - 1; + // offset: 2; size: 2; not used + $data = $this->_definedname[$definedNameIndex]['name']; break; - } - break; - case 0x1C: // error code - // offset: 1; size: 1; error code - $name = 'tErr'; - $size = 2; - $data = self::_mapErrorCode(ord($formulaData[1])); - break; - case 0x1D: // boolean - // offset: 1; size: 1; 0 = false, 1 = true; - $name = 'tBool'; - $size = 2; - $data = ord($formulaData[1]) ? 'TRUE' : 'FALSE'; - break; - case 0x1E: // integer - // offset: 1; size: 2; unsigned 16-bit integer - $name = 'tInt'; - $size = 3; - $data = self::_GetInt2d($formulaData, 1); - break; - case 0x1F: // number - // offset: 1; size: 8; - $name = 'tNum'; - $size = 9; - $data = self::_extractNumber(substr($formulaData, 1)); - $data = str_replace(',', '.', (string)$data); // in case non-English locale - break; - case 0x20: // array constant - case 0x40: - case 0x60: - // offset: 1; size: 7; not used - $name = 'tArray'; - $size = 8; - $data = null; - break; - case 0x21: // function with fixed number of arguments - case 0x41: - case 0x61: - $name = 'tFunc'; - $size = 3; - // offset: 1; size: 2; index to built-in sheet function - switch (self::_GetInt2d($formulaData, 1)) { - case 2: $function = 'ISNA'; $args = 1; break; - case 3: $function = 'ISERROR'; $args = 1; break; - case 10: $function = 'NA'; $args = 0; break; - case 15: $function = 'SIN'; $args = 1; break; - case 16: $function = 'COS'; $args = 1; break; - case 17: $function = 'TAN'; $args = 1; break; - case 18: $function = 'ATAN'; $args = 1; break; - case 19: $function = 'PI'; $args = 0; break; - case 20: $function = 'SQRT'; $args = 1; break; - case 21: $function = 'EXP'; $args = 1; break; - case 22: $function = 'LN'; $args = 1; break; - case 23: $function = 'LOG10'; $args = 1; break; - case 24: $function = 'ABS'; $args = 1; break; - case 25: $function = 'INT'; $args = 1; break; - case 26: $function = 'SIGN'; $args = 1; break; - case 27: $function = 'ROUND'; $args = 2; break; - case 30: $function = 'REPT'; $args = 2; break; - case 31: $function = 'MID'; $args = 3; break; - case 32: $function = 'LEN'; $args = 1; break; - case 33: $function = 'VALUE'; $args = 1; break; - case 34: $function = 'TRUE'; $args = 0; break; - case 35: $function = 'FALSE'; $args = 0; break; - case 38: $function = 'NOT'; $args = 1; break; - case 39: $function = 'MOD'; $args = 2; break; - case 40: $function = 'DCOUNT'; $args = 3; break; - case 41: $function = 'DSUM'; $args = 3; break; - case 42: $function = 'DAVERAGE'; $args = 3; break; - case 43: $function = 'DMIN'; $args = 3; break; - case 44: $function = 'DMAX'; $args = 3; break; - case 45: $function = 'DSTDEV'; $args = 3; break; - case 48: $function = 'TEXT'; $args = 2; break; - case 61: $function = 'MIRR'; $args = 3; break; - case 63: $function = 'RAND'; $args = 0; break; - case 65: $function = 'DATE'; $args = 3; break; - case 66: $function = 'TIME'; $args = 3; break; - case 67: $function = 'DAY'; $args = 1; break; - case 68: $function = 'MONTH'; $args = 1; break; - case 69: $function = 'YEAR'; $args = 1; break; - case 71: $function = 'HOUR'; $args = 1; break; - case 72: $function = 'MINUTE'; $args = 1; break; - case 73: $function = 'SECOND'; $args = 1; break; - case 74: $function = 'NOW'; $args = 0; break; - case 75: $function = 'AREAS'; $args = 1; break; - case 76: $function = 'ROWS'; $args = 1; break; - case 77: $function = 'COLUMNS'; $args = 1; break; - case 83: $function = 'TRANSPOSE'; $args = 1; break; - case 86: $function = 'TYPE'; $args = 1; break; - case 97: $function = 'ATAN2'; $args = 2; break; - case 98: $function = 'ASIN'; $args = 1; break; - case 99: $function = 'ACOS'; $args = 1; break; - case 105: $function = 'ISREF'; $args = 1; break; - case 111: $function = 'CHAR'; $args = 1; break; - case 112: $function = 'LOWER'; $args = 1; break; - case 113: $function = 'UPPER'; $args = 1; break; - case 114: $function = 'PROPER'; $args = 1; break; - case 117: $function = 'EXACT'; $args = 2; break; - case 118: $function = 'TRIM'; $args = 1; break; - case 119: $function = 'REPLACE'; $args = 4; break; - case 121: $function = 'CODE'; $args = 1; break; - case 126: $function = 'ISERR'; $args = 1; break; - case 127: $function = 'ISTEXT'; $args = 1; break; - case 128: $function = 'ISNUMBER'; $args = 1; break; - case 129: $function = 'ISBLANK'; $args = 1; break; - case 130: $function = 'T'; $args = 1; break; - case 131: $function = 'N'; $args = 1; break; - case 140: $function = 'DATEVALUE'; $args = 1; break; - case 141: $function = 'TIMEVALUE'; $args = 1; break; - case 142: $function = 'SLN'; $args = 3; break; - case 143: $function = 'SYD'; $args = 4; break; - case 162: $function = 'CLEAN'; $args = 1; break; - case 163: $function = 'MDETERM'; $args = 1; break; - case 164: $function = 'MINVERSE'; $args = 1; break; - case 165: $function = 'MMULT'; $args = 2; break; - case 184: $function = 'FACT'; $args = 1; break; - case 189: $function = 'DPRODUCT'; $args = 3; break; - case 190: $function = 'ISNONTEXT'; $args = 1; break; - case 195: $function = 'DSTDEVP'; $args = 3; break; - case 196: $function = 'DVARP'; $args = 3; break; - case 198: $function = 'ISLOGICAL'; $args = 1; break; - case 199: $function = 'DCOUNTA'; $args = 3; break; - case 207: $function = 'REPLACEB'; $args = 4; break; - case 210: $function = 'MIDB'; $args = 3; break; - case 211: $function = 'LENB'; $args = 1; break; - case 212: $function = 'ROUNDUP'; $args = 2; break; - case 213: $function = 'ROUNDDOWN'; $args = 2; break; - case 214: $function = 'ASC'; $args = 1; break; - case 215: $function = 'DBCS'; $args = 1; break; - case 221: $function = 'TODAY'; $args = 0; break; - case 229: $function = 'SINH'; $args = 1; break; - case 230: $function = 'COSH'; $args = 1; break; - case 231: $function = 'TANH'; $args = 1; break; - case 232: $function = 'ASINH'; $args = 1; break; - case 233: $function = 'ACOSH'; $args = 1; break; - case 234: $function = 'ATANH'; $args = 1; break; - case 235: $function = 'DGET'; $args = 3; break; - case 244: $function = 'INFO'; $args = 1; break; - case 252: $function = 'FREQUENCY'; $args = 2; break; - case 261: $function = 'ERROR.TYPE'; $args = 1; break; - case 271: $function = 'GAMMALN'; $args = 1; break; - case 273: $function = 'BINOMDIST'; $args = 4; break; - case 274: $function = 'CHIDIST'; $args = 2; break; - case 275: $function = 'CHIINV'; $args = 2; break; - case 276: $function = 'COMBIN'; $args = 2; break; - case 277: $function = 'CONFIDENCE'; $args = 3; break; - case 278: $function = 'CRITBINOM'; $args = 3; break; - case 279: $function = 'EVEN'; $args = 1; break; - case 280: $function = 'EXPONDIST'; $args = 3; break; - case 281: $function = 'FDIST'; $args = 3; break; - case 282: $function = 'FINV'; $args = 3; break; - case 283: $function = 'FISHER'; $args = 1; break; - case 284: $function = 'FISHERINV'; $args = 1; break; - case 285: $function = 'FLOOR'; $args = 2; break; - case 286: $function = 'GAMMADIST'; $args = 4; break; - case 287: $function = 'GAMMAINV'; $args = 3; break; - case 288: $function = 'CEILING'; $args = 2; break; - case 289: $function = 'HYPGEOMDIST'; $args = 4; break; - case 290: $function = 'LOGNORMDIST'; $args = 3; break; - case 291: $function = 'LOGINV'; $args = 3; break; - case 292: $function = 'NEGBINOMDIST'; $args = 3; break; - case 293: $function = 'NORMDIST'; $args = 4; break; - case 294: $function = 'NORMSDIST'; $args = 1; break; - case 295: $function = 'NORMINV'; $args = 3; break; - case 296: $function = 'NORMSINV'; $args = 1; break; - case 297: $function = 'STANDARDIZE'; $args = 3; break; - case 298: $function = 'ODD'; $args = 1; break; - case 299: $function = 'PERMUT'; $args = 2; break; - case 300: $function = 'POISSON'; $args = 3; break; - case 301: $function = 'TDIST'; $args = 3; break; - case 302: $function = 'WEIBULL'; $args = 4; break; - case 303: $function = 'SUMXMY2'; $args = 2; break; - case 304: $function = 'SUMX2MY2'; $args = 2; break; - case 305: $function = 'SUMX2PY2'; $args = 2; break; - case 306: $function = 'CHITEST'; $args = 2; break; - case 307: $function = 'CORREL'; $args = 2; break; - case 308: $function = 'COVAR'; $args = 2; break; - case 309: $function = 'FORECAST'; $args = 3; break; - case 310: $function = 'FTEST'; $args = 2; break; - case 311: $function = 'INTERCEPT'; $args = 2; break; - case 312: $function = 'PEARSON'; $args = 2; break; - case 313: $function = 'RSQ'; $args = 2; break; - case 314: $function = 'STEYX'; $args = 2; break; - case 315: $function = 'SLOPE'; $args = 2; break; - case 316: $function = 'TTEST'; $args = 4; break; - case 325: $function = 'LARGE'; $args = 2; break; - case 326: $function = 'SMALL'; $args = 2; break; - case 327: $function = 'QUARTILE'; $args = 2; break; - case 328: $function = 'PERCENTILE'; $args = 2; break; - case 331: $function = 'TRIMMEAN'; $args = 2; break; - case 332: $function = 'TINV'; $args = 2; break; - case 337: $function = 'POWER'; $args = 2; break; - case 342: $function = 'RADIANS'; $args = 1; break; - case 343: $function = 'DEGREES'; $args = 1; break; - case 346: $function = 'COUNTIF'; $args = 2; break; - case 347: $function = 'COUNTBLANK'; $args = 1; break; - case 350: $function = 'ISPMT'; $args = 4; break; - case 351: $function = 'DATEDIF'; $args = 3; break; - case 352: $function = 'DATESTRING'; $args = 1; break; - case 353: $function = 'NUMBERSTRING'; $args = 2; break; - case 360: $function = 'PHONETIC'; $args = 1; break; - case 368: $function = 'BAHTTEXT'; $args = 1; break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + case 0x24: // single cell reference e.g. A5 + case 0x44: + case 0x64: + $name = 'tRef'; + $size = 5; + $data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4)); break; - } - $data = array('function' => $function, 'args' => $args); - break; - case 0x22: // function with variable number of arguments - case 0x42: - case 0x62: - $name = 'tFuncV'; - $size = 4; - // offset: 1; size: 1; number of arguments - $args = ord($formulaData[1]); - // offset: 2: size: 2; index to built-in sheet function - $index = self::_GetInt2d($formulaData, 2); - switch ($index) { - case 0: $function = 'COUNT'; break; - case 1: $function = 'IF'; break; - case 4: $function = 'SUM'; break; - case 5: $function = 'AVERAGE'; break; - case 6: $function = 'MIN'; break; - case 7: $function = 'MAX'; break; - case 8: $function = 'ROW'; break; - case 9: $function = 'COLUMN'; break; - case 11: $function = 'NPV'; break; - case 12: $function = 'STDEV'; break; - case 13: $function = 'DOLLAR'; break; - case 14: $function = 'FIXED'; break; - case 28: $function = 'LOOKUP'; break; - case 29: $function = 'INDEX'; break; - case 36: $function = 'AND'; break; - case 37: $function = 'OR'; break; - case 46: $function = 'VAR'; break; - case 49: $function = 'LINEST'; break; - case 50: $function = 'TREND'; break; - case 51: $function = 'LOGEST'; break; - case 52: $function = 'GROWTH'; break; - case 56: $function = 'PV'; break; - case 57: $function = 'FV'; break; - case 58: $function = 'NPER'; break; - case 59: $function = 'PMT'; break; - case 60: $function = 'RATE'; break; - case 62: $function = 'IRR'; break; - case 64: $function = 'MATCH'; break; - case 70: $function = 'WEEKDAY'; break; - case 78: $function = 'OFFSET'; break; - case 82: $function = 'SEARCH'; break; - case 100: $function = 'CHOOSE'; break; - case 101: $function = 'HLOOKUP'; break; - case 102: $function = 'VLOOKUP'; break; - case 109: $function = 'LOG'; break; - case 115: $function = 'LEFT'; break; - case 116: $function = 'RIGHT'; break; - case 120: $function = 'SUBSTITUTE'; break; - case 124: $function = 'FIND'; break; - case 125: $function = 'CELL'; break; - case 144: $function = 'DDB'; break; - case 148: $function = 'INDIRECT'; break; - case 167: $function = 'IPMT'; break; - case 168: $function = 'PPMT'; break; - case 169: $function = 'COUNTA'; break; - case 183: $function = 'PRODUCT'; break; - case 193: $function = 'STDEVP'; break; - case 194: $function = 'VARP'; break; - case 197: $function = 'TRUNC'; break; - case 204: $function = 'USDOLLAR'; break; - case 205: $function = 'FINDB'; break; - case 206: $function = 'SEARCHB'; break; - case 208: $function = 'LEFTB'; break; - case 209: $function = 'RIGHTB'; break; - case 216: $function = 'RANK'; break; - case 219: $function = 'ADDRESS'; break; - case 220: $function = 'DAYS360'; break; - case 222: $function = 'VDB'; break; - case 227: $function = 'MEDIAN'; break; - case 228: $function = 'SUMPRODUCT'; break; - case 247: $function = 'DB'; break; - case 255: $function = ''; break; - case 269: $function = 'AVEDEV'; break; - case 270: $function = 'BETADIST'; break; - case 272: $function = 'BETAINV'; break; - case 317: $function = 'PROB'; break; - case 318: $function = 'DEVSQ'; break; - case 319: $function = 'GEOMEAN'; break; - case 320: $function = 'HARMEAN'; break; - case 321: $function = 'SUMSQ'; break; - case 322: $function = 'KURT'; break; - case 323: $function = 'SKEW'; break; - case 324: $function = 'ZTEST'; break; - case 329: $function = 'PERCENTRANK'; break; - case 330: $function = 'MODE'; break; - case 336: $function = 'CONCATENATE'; break; - case 344: $function = 'SUBTOTAL'; break; - case 345: $function = 'SUMIF'; break; - case 354: $function = 'ROMAN'; break; - case 358: $function = 'GETPIVOTDATA'; break; - case 359: $function = 'HYPERLINK'; break; - case 361: $function = 'AVERAGEA'; break; - case 362: $function = 'MAXA'; break; - case 363: $function = 'MINA'; break; - case 364: $function = 'STDEVPA'; break; - case 365: $function = 'VARPA'; break; - case 366: $function = 'STDEVA'; break; - case 367: $function = 'VARA'; break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + case 0x25: // cell range reference to cells in the same sheet (2d) + case 0x45: + case 0x65: + $name = 'tArea'; + $size = 9; + $data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8)); break; - } - $data = array('function' => $function, 'args' => $args); - break; - case 0x23: // index to defined name - case 0x43: - case 0x63: - $name = 'tName'; - $size = 5; - // offset: 1; size: 2; one-based index to definedname record - $definedNameIndex = self::_GetInt2d($formulaData, 1) - 1; - // offset: 2; size: 2; not used - $data = $this->_definedname[$definedNameIndex]['name']; - break; - case 0x24: // single cell reference e.g. A5 - case 0x44: - case 0x64: - $name = 'tRef'; - $size = 5; - $data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4)); - break; - case 0x25: // cell range reference to cells in the same sheet (2d) - case 0x45: - case 0x65: - $name = 'tArea'; - $size = 9; - $data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8)); - break; - case 0x26: // Constant reference sub-expression - case 0x46: - case 0x66: - $name = 'tMemArea'; - // offset: 1; size: 4; not used - // offset: 5; size: 2; size of the following subexpression - $subSize = self::_GetInt2d($formulaData, 5); - $size = 7 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); - break; - case 0x27: // Deleted constant reference sub-expression - case 0x47: - case 0x67: - $name = 'tMemErr'; - // offset: 1; size: 4; not used - // offset: 5; size: 2; size of the following subexpression - $subSize = self::_GetInt2d($formulaData, 5); - $size = 7 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); - break; - case 0x29: // Variable reference sub-expression - case 0x49: - case 0x69: - $name = 'tMemFunc'; - // offset: 1; size: 2; size of the following sub-expression - $subSize = self::_GetInt2d($formulaData, 1); - $size = 3 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize)); - break; - - case 0x2C: // Relative 2d cell reference reference, used in shared formulas and some other places - case 0x4C: - case 0x6C: - $name = 'tRefN'; - $size = 5; - $data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell); - break; - - case 0x2D: // Relative 2d range reference - case 0x4D: - case 0x6D: - $name = 'tAreaN'; - $size = 9; - $data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell); - break; - - case 0x39: // External name - case 0x59: - case 0x79: - $name = 'tNameX'; - $size = 7; - // offset: 1; size: 2; index to REF entry in EXTERNSHEET record - // offset: 3; size: 2; one-based index to DEFINEDNAME or EXTERNNAME record - $index = self::_GetInt2d($formulaData, 3); - // assume index is to EXTERNNAME record - $data = $this->_externalNames[$index - 1]['name']; - // offset: 5; size: 2; not used - break; - - case 0x3A: // 3d reference to cell - case 0x5A: - case 0x7A: - $name = 'tRef3d'; - $size = 7; - - try { - // offset: 1; size: 2; index to REF entry - $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); - // offset: 3; size: 4; cell address - $cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4)); - - $data = "$sheetRange!$cellAddress"; - } catch (PHPExcel_Exception $e) { - // deleted sheet reference - $data = '#REF!'; - } + case 0x26: // Constant reference sub-expression + case 0x46: + case 0x66: + $name = 'tMemArea'; + // offset: 1; size: 4; not used + // offset: 5; size: 2; size of the following subexpression + $subSize = self::_GetInt2d($formulaData, 5); + $size = 7 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + break; + case 0x27: // Deleted constant reference sub-expression + case 0x47: + case 0x67: + $name = 'tMemErr'; + // offset: 1; size: 4; not used + // offset: 5; size: 2; size of the following subexpression + $subSize = self::_GetInt2d($formulaData, 5); + $size = 7 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + break; + case 0x29: // Variable reference sub-expression + case 0x49: + case 0x69: + $name = 'tMemFunc'; + // offset: 1; size: 2; size of the following sub-expression + $subSize = self::_GetInt2d($formulaData, 1); + $size = 3 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize)); + break; + case 0x2C: // Relative 2d cell reference reference, used in shared formulas and some other places + case 0x4C: + case 0x6C: + $name = 'tRefN'; + $size = 5; + $data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell); + break; + case 0x2D: // Relative 2d range reference + case 0x4D: + case 0x6D: + $name = 'tAreaN'; + $size = 9; + $data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell); + break; + case 0x39: // External name + case 0x59: + case 0x79: + $name = 'tNameX'; + $size = 7; + // offset: 1; size: 2; index to REF entry in EXTERNSHEET record + // offset: 3; size: 2; one-based index to DEFINEDNAME or EXTERNNAME record + $index = self::_GetInt2d($formulaData, 3); + // assume index is to EXTERNNAME record + $data = $this->_externalNames[$index - 1]['name']; + // offset: 5; size: 2; not used + break; + case 0x3A: // 3d reference to cell + case 0x5A: + case 0x7A: + $name = 'tRef3d'; + $size = 7; - break; - case 0x3B: // 3d reference to cell range - case 0x5B: - case 0x7B: - $name = 'tArea3d'; - $size = 11; + try { + // offset: 1; size: 2; index to REF entry + $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + // offset: 3; size: 4; cell address + $cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4)); - try { - // offset: 1; size: 2; index to REF entry - $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); - // offset: 3; size: 8; cell address - $cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8)); + $data = "$sheetRange!$cellAddress"; + } catch (PHPExcel_Exception $e) { + // deleted sheet reference + $data = '#REF!'; + } + break; + case 0x3B: // 3d reference to cell range + case 0x5B: + case 0x7B: + $name = 'tArea3d'; + $size = 11; - $data = "$sheetRange!$cellRangeAddress"; - } catch (PHPExcel_Exception $e) { - // deleted sheet reference - $data = '#REF!'; - } + try { + // offset: 1; size: 2; index to REF entry + $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + // offset: 3; size: 8; cell address + $cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8)); - break; - // Unknown cases // don't know how to deal with - default: - throw new PHPExcel_Reader_Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula'); - break; + $data = "$sheetRange!$cellRangeAddress"; + } catch (PHPExcel_Exception $e) { + // deleted sheet reference + $data = '#REF!'; + } + break; + // Unknown cases // don't know how to deal with + default: + throw new PHPExcel_Reader_Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula'); + break; } return array( @@ -6015,18 +6812,17 @@ private function _readBIFF8CellAddress($cellAddressStructure) $row = self::_GetInt2d($cellAddressStructure, 0) + 1; // offset: 2; size: 2; index to column or column offset + relative flags + // bit: 7-0; mask 0x00FF; column index + $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2)); - // bit: 7-0; mask 0x00FF; column index - $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2)); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { - $column = '$' . $column; - } - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { - $row = '$' . $row; - } + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + $column = '$' . $column; + } + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + $row = '$' . $row; + } return $column . $row; } @@ -6047,30 +6843,29 @@ private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) - $rowIndex = self::_GetInt2d($cellAddressStructure, 0); - $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + $rowIndex = self::_GetInt2d($cellAddressStructure, 0); + $row = self::_GetInt2d($cellAddressStructure, 0) + 1; // offset: 2; size: 2; index to column or column offset + relative flags + // bit: 7-0; mask 0x00FF; column index + $colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2); - // bit: 7-0; mask 0x00FF; column index - $colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { - $column = PHPExcel_Cell::stringFromColumnIndex($colIndex); - $column = '$' . $column; - } else { - $colIndex = ($colIndex <= 127) ? $colIndex : $colIndex - 256; - $column = PHPExcel_Cell::stringFromColumnIndex($baseCol + $colIndex); - } + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + $column = PHPExcel_Cell::stringFromColumnIndex($colIndex); + $column = '$' . $column; + } else { + $colIndex = ($colIndex <= 127) ? $colIndex : $colIndex - 256; + $column = PHPExcel_Cell::stringFromColumnIndex($baseCol + $colIndex); + } - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { - $row = '$' . $row; - } else { - $rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536; - $row = $baseRow + $rowIndex; - } + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + $row = '$' . $row; + } else { + $rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536; + $row = $baseRow + $rowIndex; + } return $column . $row; } @@ -6359,7 +7154,6 @@ private function _readBIFF5CellRangeAddressList($subData) private function _readSheetRangeByRefIndex($index) { if (isset($this->_ref[$index])) { - $type = $this->_externalBooks[$this->_ref[$index]['externalBookIndex']]['type']; switch ($type) { @@ -6393,7 +7187,6 @@ private function _readSheetRangeByRefIndex($index) return $sheetRange; break; - default: // TODO: external sheet support throw new PHPExcel_Reader_Exception('Excel5 reader only supports internal sheets in fomulas'); @@ -6457,35 +7250,35 @@ private static function _readBIFF8Constant($valueData) $identifier = ord($valueData[0]); switch ($identifier) { - case 0x00: // empty constant (what is this?) - $value = ''; - $size = 9; - break; - case 0x01: // number - // offset: 1; size: 8; IEEE 754 floating-point value - $value = self::_extractNumber(substr($valueData, 1, 8)); - $size = 9; - break; - case 0x02: // string value - // offset: 1; size: var; Unicode string, 16-bit string length - $string = self::_readUnicodeStringLong(substr($valueData, 1)); - $value = '"' . $string['value'] . '"'; - $size = 1 + $string['size']; - break; - case 0x04: // boolean - // offset: 1; size: 1; 0 = FALSE, 1 = TRUE - if (ord($valueData[1])) { - $value = 'TRUE'; - } else { - $value = 'FALSE'; - } - $size = 9; - break; - case 0x10: // error code - // offset: 1; size: 1; error code - $value = self::_mapErrorCode(ord($valueData[1])); - $size = 9; - break; + case 0x00: // empty constant (what is this?) + $value = ''; + $size = 9; + break; + case 0x01: // number + // offset: 1; size: 8; IEEE 754 floating-point value + $value = self::_extractNumber(substr($valueData, 1, 8)); + $size = 9; + break; + case 0x02: // string value + // offset: 1; size: var; Unicode string, 16-bit string length + $string = self::_readUnicodeStringLong(substr($valueData, 1)); + $value = '"' . $string['value'] . '"'; + $size = 1 + $string['size']; + break; + case 0x04: // boolean + // offset: 1; size: 1; 0 = FALSE, 1 = TRUE + if (ord($valueData[1])) { + $value = 'TRUE'; + } else { + $value = 'FALSE'; + } + $size = 9; + break; + case 0x10: // error code + // offset: 1; size: 1; error code + $value = self::_mapErrorCode(ord($valueData[1])); + $size = 9; + break; } return array( 'value' => $value, @@ -6626,15 +7419,14 @@ private static function _readUnicodeString($subData, $characterCount) $value = ''; // offset: 0: size: 1; option flags + // bit: 0; mask: 0x01; character compression (0 = compressed 8-bit, 1 = uncompressed 16-bit) + $isCompressed = !((0x01 & ord($subData[0])) >> 0); - // bit: 0; mask: 0x01; character compression (0 = compressed 8-bit, 1 = uncompressed 16-bit) - $isCompressed = !((0x01 & ord($subData[0])) >> 0); + // bit: 2; mask: 0x04; Asian phonetic settings + $hasAsian = (0x04) & ord($subData[0]) >> 2; - // bit: 2; mask: 0x04; Asian phonetic settings - $hasAsian = (0x04) & ord($subData[0]) >> 2; - - // bit: 3; mask: 0x08; Rich-Text settings - $hasRichText = (0x08) & ord($subData[0]) >> 3; + // bit: 3; mask: 0x08; Rich-Text settings + $hasRichText = (0x08) & ord($subData[0]) >> 3; // offset: 1: size: var; character array // this offset assumes richtext and Asian phonetic settings are off which is generally wrong @@ -6839,21 +7631,36 @@ private static function _readColor($color, $palette, $version) private static function _mapBorderStyle($index) { switch ($index) { - case 0x00: return PHPExcel_Style_Border::BORDER_NONE; - case 0x01: return PHPExcel_Style_Border::BORDER_THIN; - case 0x02: return PHPExcel_Style_Border::BORDER_MEDIUM; - case 0x03: return PHPExcel_Style_Border::BORDER_DASHED; - case 0x04: return PHPExcel_Style_Border::BORDER_DOTTED; - case 0x05: return PHPExcel_Style_Border::BORDER_THICK; - case 0x06: return PHPExcel_Style_Border::BORDER_DOUBLE; - case 0x07: return PHPExcel_Style_Border::BORDER_HAIR; - case 0x08: return PHPExcel_Style_Border::BORDER_MEDIUMDASHED; - case 0x09: return PHPExcel_Style_Border::BORDER_DASHDOT; - case 0x0A: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; - case 0x0B: return PHPExcel_Style_Border::BORDER_DASHDOTDOT; - case 0x0C: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; - case 0x0D: return PHPExcel_Style_Border::BORDER_SLANTDASHDOT; - default: return PHPExcel_Style_Border::BORDER_NONE; + case 0x00: + return PHPExcel_Style_Border::BORDER_NONE; + case 0x01: + return PHPExcel_Style_Border::BORDER_THIN; + case 0x02: + return PHPExcel_Style_Border::BORDER_MEDIUM; + case 0x03: + return PHPExcel_Style_Border::BORDER_DASHED; + case 0x04: + return PHPExcel_Style_Border::BORDER_DOTTED; + case 0x05: + return PHPExcel_Style_Border::BORDER_THICK; + case 0x06: + return PHPExcel_Style_Border::BORDER_DOUBLE; + case 0x07: + return PHPExcel_Style_Border::BORDER_HAIR; + case 0x08: + return PHPExcel_Style_Border::BORDER_MEDIUMDASHED; + case 0x09: + return PHPExcel_Style_Border::BORDER_DASHDOT; + case 0x0A: + return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; + case 0x0B: + return PHPExcel_Style_Border::BORDER_DASHDOTDOT; + case 0x0C: + return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + case 0x0D: + return PHPExcel_Style_Border::BORDER_SLANTDASHDOT; + default: + return PHPExcel_Style_Border::BORDER_NONE; } } @@ -6868,26 +7675,46 @@ private static function _mapBorderStyle($index) private static function _mapFillPattern($index) { switch ($index) { - case 0x00: return PHPExcel_Style_Fill::FILL_NONE; - case 0x01: return PHPExcel_Style_Fill::FILL_SOLID; - case 0x02: return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; - case 0x03: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; - case 0x04: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; - case 0x05: return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; - case 0x06: return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; - case 0x07: return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; - case 0x08: return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; - case 0x09: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; - case 0x0A: return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; - case 0x0B: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; - case 0x0C: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; - case 0x0D: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; - case 0x0E: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; - case 0x0F: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; - case 0x10: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; - case 0x11: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; - case 0x12: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; - default: return PHPExcel_Style_Fill::FILL_NONE; + case 0x00: + return PHPExcel_Style_Fill::FILL_NONE; + case 0x01: + return PHPExcel_Style_Fill::FILL_SOLID; + case 0x02: + return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; + case 0x03: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; + case 0x04: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; + case 0x05: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; + case 0x06: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; + case 0x07: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; + case 0x08: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; + case 0x09: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; + case 0x0A: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; + case 0x0B: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; + case 0x0C: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; + case 0x0D: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; + case 0x0E: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; + case 0x0F: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; + case 0x10: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; + case 0x11: + return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; + case 0x12: + return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; + default: + return PHPExcel_Style_Fill::FILL_NONE; } } @@ -6901,14 +7728,29 @@ private static function _mapFillPattern($index) private static function _mapErrorCode($subData) { switch ($subData) { - case 0x00: return '#NULL!'; break; - case 0x07: return '#DIV/0!'; break; - case 0x0F: return '#VALUE!'; break; - case 0x17: return '#REF!'; break; - case 0x1D: return '#NAME?'; break; - case 0x24: return '#NUM!'; break; - case 0x2A: return '#N/A'; break; - default: return false; + case 0x00: + return '#NULL!'; + break; + case 0x07: + return '#DIV/0!'; + break; + case 0x0F: + return '#VALUE!'; + break; + case 0x17: + return '#REF!'; + break; + case 0x1D: + return '#NAME?'; + break; + case 0x24: + return '#NUM!'; + break; + case 0x2A: + return '#N/A'; + break; + default: + return false; } } @@ -6922,17 +7764,28 @@ private static function _mapErrorCode($subData) private static function _mapBuiltInColor($color) { switch ($color) { - case 0x00: return array('rgb' => '000000'); - case 0x01: return array('rgb' => 'FFFFFF'); - case 0x02: return array('rgb' => 'FF0000'); - case 0x03: return array('rgb' => '00FF00'); - case 0x04: return array('rgb' => '0000FF'); - case 0x05: return array('rgb' => 'FFFF00'); - case 0x06: return array('rgb' => 'FF00FF'); - case 0x07: return array('rgb' => '00FFFF'); - case 0x40: return array('rgb' => '000000'); // system window text color - case 0x41: return array('rgb' => 'FFFFFF'); // system window background color - default: return array('rgb' => '000000'); + case 0x00: + return array('rgb' => '000000'); + case 0x01: + return array('rgb' => 'FFFFFF'); + case 0x02: + return array('rgb' => 'FF0000'); + case 0x03: + return array('rgb' => '00FF00'); + case 0x04: + return array('rgb' => '0000FF'); + case 0x05: + return array('rgb' => 'FFFF00'); + case 0x06: + return array('rgb' => 'FF00FF'); + case 0x07: + return array('rgb' => '00FFFF'); + case 0x40: + return array('rgb' => '000000'); // system window text color + case 0x41: + return array('rgb' => 'FFFFFF'); // system window background color + default: + return array('rgb' => '000000'); } } @@ -6946,63 +7799,120 @@ private static function _mapBuiltInColor($color) private static function _mapColorBIFF5($subData) { switch ($subData) { - case 0x08: return array('rgb' => '000000'); - case 0x09: return array('rgb' => 'FFFFFF'); - case 0x0A: return array('rgb' => 'FF0000'); - case 0x0B: return array('rgb' => '00FF00'); - case 0x0C: return array('rgb' => '0000FF'); - case 0x0D: return array('rgb' => 'FFFF00'); - case 0x0E: return array('rgb' => 'FF00FF'); - case 0x0F: return array('rgb' => '00FFFF'); - case 0x10: return array('rgb' => '800000'); - case 0x11: return array('rgb' => '008000'); - case 0x12: return array('rgb' => '000080'); - case 0x13: return array('rgb' => '808000'); - case 0x14: return array('rgb' => '800080'); - case 0x15: return array('rgb' => '008080'); - case 0x16: return array('rgb' => 'C0C0C0'); - case 0x17: return array('rgb' => '808080'); - case 0x18: return array('rgb' => '8080FF'); - case 0x19: return array('rgb' => '802060'); - case 0x1A: return array('rgb' => 'FFFFC0'); - case 0x1B: return array('rgb' => 'A0E0F0'); - case 0x1C: return array('rgb' => '600080'); - case 0x1D: return array('rgb' => 'FF8080'); - case 0x1E: return array('rgb' => '0080C0'); - case 0x1F: return array('rgb' => 'C0C0FF'); - case 0x20: return array('rgb' => '000080'); - case 0x21: return array('rgb' => 'FF00FF'); - case 0x22: return array('rgb' => 'FFFF00'); - case 0x23: return array('rgb' => '00FFFF'); - case 0x24: return array('rgb' => '800080'); - case 0x25: return array('rgb' => '800000'); - case 0x26: return array('rgb' => '008080'); - case 0x27: return array('rgb' => '0000FF'); - case 0x28: return array('rgb' => '00CFFF'); - case 0x29: return array('rgb' => '69FFFF'); - case 0x2A: return array('rgb' => 'E0FFE0'); - case 0x2B: return array('rgb' => 'FFFF80'); - case 0x2C: return array('rgb' => 'A6CAF0'); - case 0x2D: return array('rgb' => 'DD9CB3'); - case 0x2E: return array('rgb' => 'B38FEE'); - case 0x2F: return array('rgb' => 'E3E3E3'); - case 0x30: return array('rgb' => '2A6FF9'); - case 0x31: return array('rgb' => '3FB8CD'); - case 0x32: return array('rgb' => '488436'); - case 0x33: return array('rgb' => '958C41'); - case 0x34: return array('rgb' => '8E5E42'); - case 0x35: return array('rgb' => 'A0627A'); - case 0x36: return array('rgb' => '624FAC'); - case 0x37: return array('rgb' => '969696'); - case 0x38: return array('rgb' => '1D2FBE'); - case 0x39: return array('rgb' => '286676'); - case 0x3A: return array('rgb' => '004500'); - case 0x3B: return array('rgb' => '453E01'); - case 0x3C: return array('rgb' => '6A2813'); - case 0x3D: return array('rgb' => '85396A'); - case 0x3E: return array('rgb' => '4A3285'); - case 0x3F: return array('rgb' => '424242'); - default: return array('rgb' => '000000'); + case 0x08: + return array('rgb' => '000000'); + case 0x09: + return array('rgb' => 'FFFFFF'); + case 0x0A: + return array('rgb' => 'FF0000'); + case 0x0B: + return array('rgb' => '00FF00'); + case 0x0C: + return array('rgb' => '0000FF'); + case 0x0D: + return array('rgb' => 'FFFF00'); + case 0x0E: + return array('rgb' => 'FF00FF'); + case 0x0F: + return array('rgb' => '00FFFF'); + case 0x10: + return array('rgb' => '800000'); + case 0x11: + return array('rgb' => '008000'); + case 0x12: + return array('rgb' => '000080'); + case 0x13: + return array('rgb' => '808000'); + case 0x14: + return array('rgb' => '800080'); + case 0x15: + return array('rgb' => '008080'); + case 0x16: + return array('rgb' => 'C0C0C0'); + case 0x17: + return array('rgb' => '808080'); + case 0x18: + return array('rgb' => '8080FF'); + case 0x19: + return array('rgb' => '802060'); + case 0x1A: + return array('rgb' => 'FFFFC0'); + case 0x1B: + return array('rgb' => 'A0E0F0'); + case 0x1C: + return array('rgb' => '600080'); + case 0x1D: + return array('rgb' => 'FF8080'); + case 0x1E: + return array('rgb' => '0080C0'); + case 0x1F: + return array('rgb' => 'C0C0FF'); + case 0x20: + return array('rgb' => '000080'); + case 0x21: + return array('rgb' => 'FF00FF'); + case 0x22: + return array('rgb' => 'FFFF00'); + case 0x23: + return array('rgb' => '00FFFF'); + case 0x24: + return array('rgb' => '800080'); + case 0x25: + return array('rgb' => '800000'); + case 0x26: + return array('rgb' => '008080'); + case 0x27: + return array('rgb' => '0000FF'); + case 0x28: + return array('rgb' => '00CFFF'); + case 0x29: + return array('rgb' => '69FFFF'); + case 0x2A: + return array('rgb' => 'E0FFE0'); + case 0x2B: + return array('rgb' => 'FFFF80'); + case 0x2C: + return array('rgb' => 'A6CAF0'); + case 0x2D: + return array('rgb' => 'DD9CB3'); + case 0x2E: + return array('rgb' => 'B38FEE'); + case 0x2F: + return array('rgb' => 'E3E3E3'); + case 0x30: + return array('rgb' => '2A6FF9'); + case 0x31: + return array('rgb' => '3FB8CD'); + case 0x32: + return array('rgb' => '488436'); + case 0x33: + return array('rgb' => '958C41'); + case 0x34: + return array('rgb' => '8E5E42'); + case 0x35: + return array('rgb' => 'A0627A'); + case 0x36: + return array('rgb' => '624FAC'); + case 0x37: + return array('rgb' => '969696'); + case 0x38: + return array('rgb' => '1D2FBE'); + case 0x39: + return array('rgb' => '286676'); + case 0x3A: + return array('rgb' => '004500'); + case 0x3B: + return array('rgb' => '453E01'); + case 0x3C: + return array('rgb' => '6A2813'); + case 0x3D: + return array('rgb' => '85396A'); + case 0x3E: + return array('rgb' => '4A3285'); + case 0x3F: + return array('rgb' => '424242'); + default: + return array('rgb' => '000000'); } } @@ -7016,63 +7926,120 @@ private static function _mapColorBIFF5($subData) private static function _mapColor($subData) { switch ($subData) { - case 0x08: return array('rgb' => '000000'); - case 0x09: return array('rgb' => 'FFFFFF'); - case 0x0A: return array('rgb' => 'FF0000'); - case 0x0B: return array('rgb' => '00FF00'); - case 0x0C: return array('rgb' => '0000FF'); - case 0x0D: return array('rgb' => 'FFFF00'); - case 0x0E: return array('rgb' => 'FF00FF'); - case 0x0F: return array('rgb' => '00FFFF'); - case 0x10: return array('rgb' => '800000'); - case 0x11: return array('rgb' => '008000'); - case 0x12: return array('rgb' => '000080'); - case 0x13: return array('rgb' => '808000'); - case 0x14: return array('rgb' => '800080'); - case 0x15: return array('rgb' => '008080'); - case 0x16: return array('rgb' => 'C0C0C0'); - case 0x17: return array('rgb' => '808080'); - case 0x18: return array('rgb' => '9999FF'); - case 0x19: return array('rgb' => '993366'); - case 0x1A: return array('rgb' => 'FFFFCC'); - case 0x1B: return array('rgb' => 'CCFFFF'); - case 0x1C: return array('rgb' => '660066'); - case 0x1D: return array('rgb' => 'FF8080'); - case 0x1E: return array('rgb' => '0066CC'); - case 0x1F: return array('rgb' => 'CCCCFF'); - case 0x20: return array('rgb' => '000080'); - case 0x21: return array('rgb' => 'FF00FF'); - case 0x22: return array('rgb' => 'FFFF00'); - case 0x23: return array('rgb' => '00FFFF'); - case 0x24: return array('rgb' => '800080'); - case 0x25: return array('rgb' => '800000'); - case 0x26: return array('rgb' => '008080'); - case 0x27: return array('rgb' => '0000FF'); - case 0x28: return array('rgb' => '00CCFF'); - case 0x29: return array('rgb' => 'CCFFFF'); - case 0x2A: return array('rgb' => 'CCFFCC'); - case 0x2B: return array('rgb' => 'FFFF99'); - case 0x2C: return array('rgb' => '99CCFF'); - case 0x2D: return array('rgb' => 'FF99CC'); - case 0x2E: return array('rgb' => 'CC99FF'); - case 0x2F: return array('rgb' => 'FFCC99'); - case 0x30: return array('rgb' => '3366FF'); - case 0x31: return array('rgb' => '33CCCC'); - case 0x32: return array('rgb' => '99CC00'); - case 0x33: return array('rgb' => 'FFCC00'); - case 0x34: return array('rgb' => 'FF9900'); - case 0x35: return array('rgb' => 'FF6600'); - case 0x36: return array('rgb' => '666699'); - case 0x37: return array('rgb' => '969696'); - case 0x38: return array('rgb' => '003366'); - case 0x39: return array('rgb' => '339966'); - case 0x3A: return array('rgb' => '003300'); - case 0x3B: return array('rgb' => '333300'); - case 0x3C: return array('rgb' => '993300'); - case 0x3D: return array('rgb' => '993366'); - case 0x3E: return array('rgb' => '333399'); - case 0x3F: return array('rgb' => '333333'); - default: return array('rgb' => '000000'); + case 0x08: + return array('rgb' => '000000'); + case 0x09: + return array('rgb' => 'FFFFFF'); + case 0x0A: + return array('rgb' => 'FF0000'); + case 0x0B: + return array('rgb' => '00FF00'); + case 0x0C: + return array('rgb' => '0000FF'); + case 0x0D: + return array('rgb' => 'FFFF00'); + case 0x0E: + return array('rgb' => 'FF00FF'); + case 0x0F: + return array('rgb' => '00FFFF'); + case 0x10: + return array('rgb' => '800000'); + case 0x11: + return array('rgb' => '008000'); + case 0x12: + return array('rgb' => '000080'); + case 0x13: + return array('rgb' => '808000'); + case 0x14: + return array('rgb' => '800080'); + case 0x15: + return array('rgb' => '008080'); + case 0x16: + return array('rgb' => 'C0C0C0'); + case 0x17: + return array('rgb' => '808080'); + case 0x18: + return array('rgb' => '9999FF'); + case 0x19: + return array('rgb' => '993366'); + case 0x1A: + return array('rgb' => 'FFFFCC'); + case 0x1B: + return array('rgb' => 'CCFFFF'); + case 0x1C: + return array('rgb' => '660066'); + case 0x1D: + return array('rgb' => 'FF8080'); + case 0x1E: + return array('rgb' => '0066CC'); + case 0x1F: + return array('rgb' => 'CCCCFF'); + case 0x20: + return array('rgb' => '000080'); + case 0x21: + return array('rgb' => 'FF00FF'); + case 0x22: + return array('rgb' => 'FFFF00'); + case 0x23: + return array('rgb' => '00FFFF'); + case 0x24: + return array('rgb' => '800080'); + case 0x25: + return array('rgb' => '800000'); + case 0x26: + return array('rgb' => '008080'); + case 0x27: + return array('rgb' => '0000FF'); + case 0x28: + return array('rgb' => '00CCFF'); + case 0x29: + return array('rgb' => 'CCFFFF'); + case 0x2A: + return array('rgb' => 'CCFFCC'); + case 0x2B: + return array('rgb' => 'FFFF99'); + case 0x2C: + return array('rgb' => '99CCFF'); + case 0x2D: + return array('rgb' => 'FF99CC'); + case 0x2E: + return array('rgb' => 'CC99FF'); + case 0x2F: + return array('rgb' => 'FFCC99'); + case 0x30: + return array('rgb' => '3366FF'); + case 0x31: + return array('rgb' => '33CCCC'); + case 0x32: + return array('rgb' => '99CC00'); + case 0x33: + return array('rgb' => 'FFCC00'); + case 0x34: + return array('rgb' => 'FF9900'); + case 0x35: + return array('rgb' => 'FF6600'); + case 0x36: + return array('rgb' => '666699'); + case 0x37: + return array('rgb' => '969696'); + case 0x38: + return array('rgb' => '003366'); + case 0x39: + return array('rgb' => '339966'); + case 0x3A: + return array('rgb' => '003300'); + case 0x3B: + return array('rgb' => '333300'); + case 0x3C: + return array('rgb' => '993300'); + case 0x3D: + return array('rgb' => '993366'); + case 0x3E: + return array('rgb' => '333399'); + case 0x3F: + return array('rgb' => '333333'); + default: + return array('rgb' => '000000'); } } @@ -7084,5 +8051,4 @@ private function _parseRichText($is = '') { return $value; } - } From f0fdc9430bbcaedbb4d51d436841c14b91e1a791 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 17 May 2015 10:22:51 +0100 Subject: [PATCH 381/467] More PSR-2 work, and eliminate duplicate code in Row/Column dimensions by extension of an abstract Dimension class containing common code/properties --- Classes/PHPExcel/Calculation.php | 3328 +++++++++-------- Classes/PHPExcel/Chart.php | 156 +- Classes/PHPExcel/Comment.php | 82 +- Classes/PHPExcel/DocumentProperties.php | 88 +- Classes/PHPExcel/HashTable.php | 38 +- .../PHPExcel/Worksheet/ColumnDimension.php | 164 +- Classes/PHPExcel/Worksheet/Dimension.php | 178 + Classes/PHPExcel/Worksheet/RowDimension.php | 164 +- Classes/PHPExcel/Worksheet/SheetView.php | 38 +- 9 files changed, 2243 insertions(+), 1993 deletions(-) create mode 100644 Classes/PHPExcel/Worksheet/Dimension.php diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 5a7922175..b94841c82 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -270,1438 +270,1794 @@ class PHPExcel_Calculation ); // PHPExcel functions - private static $PHPExcelFunctions = array( // PHPExcel functions - 'ABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'abs', - 'argumentCount' => '1' - ), - 'ACCRINT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', - 'argumentCount' => '4-7' - ), - 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', - 'argumentCount' => '3-5' - ), - 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'acos', - 'argumentCount' => '1' - ), - 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'acosh', - 'argumentCount' => '1' - ), - 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', - 'argumentCount' => '2-5' - ), - 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', - 'argumentCount' => '6,7' - ), - 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', - 'argumentCount' => '6,7' - ), - 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', - 'argumentCount' => '1+' - ), - 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'asin', - 'argumentCount' => '1' - ), - 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'asinh', - 'argumentCount' => '1' - ), - 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'atan', - 'argumentCount' => '1' - ), - 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', - 'argumentCount' => '2' - ), - 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'atanh', - 'argumentCount' => '1' - ), - 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', - 'argumentCount' => '1+' - ), - 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', - 'argumentCount' => '1+' - ), - 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', - 'argumentCount' => '1+' - ), - 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', - 'argumentCount' => '2,3' - ), - 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3+' - ), - 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', - 'argumentCount' => '2' - ), - 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', - 'argumentCount' => '2' - ), - 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', - 'argumentCount' => '2' - ), - 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', - 'argumentCount' => '2' - ), - 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', - 'argumentCount' => '3-5' - ), - 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', - 'argumentCount' => '3-5' - ), - 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', - 'argumentCount' => '1' - ), - 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', - 'argumentCount' => '1,2' - ), - 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', - 'argumentCount' => '1,2' - ), - 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', - 'argumentCount' => '4' - ), - 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', - 'argumentCount' => '2' - ), - 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1,2' - ), - 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', - 'argumentCount' => '1' - ), - 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', - 'argumentCount' => '2' - ), - 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', - 'argumentCount' => '2' - ), - 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', - 'argumentCount' => '2+' - ), - 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', - 'argumentCount' => '1' - ), - 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', - 'argumentCount' => '1' - ), - 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', - 'argumentCount' => '-1', - 'passByReference' => array(true) - ), - 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', - 'argumentCount' => '1' - ), - 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', - 'argumentCount' => '2' - ), - 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', - 'argumentCount' => '2,3' - ), - 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', - 'argumentCount' => '1+' - ), - 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', - 'argumentCount' => '3' - ), - 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', - 'argumentCount' => '3' - ), - 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', - 'argumentCount' => '2' - ), - 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'cos', - 'argumentCount' => '1' - ), - 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'cosh', - 'argumentCount' => '1' - ), - 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', - 'argumentCount' => '1+' - ), - 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', - 'argumentCount' => '1+' - ), - 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', - 'argumentCount' => '1' - ), - 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', - 'argumentCount' => '2' - ), - 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', - 'argumentCount' => '3,4' - ), - 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', - 'argumentCount' => '3,4' - ), - 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', - 'argumentCount' => '3,4' - ), - 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', - 'argumentCount' => '3,4' - ), - 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', - 'argumentCount' => '3,4' - ), - 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', - 'argumentCount' => '3,4' - ), - 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', - 'argumentCount' => '2' - ), - 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', - 'argumentCount' => '3' - ), - 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', - 'argumentCount' => '6' - ), - 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', - 'argumentCount' => '6' - ), - 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', - 'argumentCount' => '3' - ), - 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', - 'argumentCount' => '2,3' - ), - 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', - 'argumentCount' => '1' - ), - 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', - 'argumentCount' => '3' - ), - 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', - 'argumentCount' => '1' - ), - 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', - 'argumentCount' => '2,3' - ), - 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DB', - 'argumentCount' => '4,5' - ), - 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', - 'argumentCount' => '3' - ), - 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', - 'argumentCount' => '3' - ), - 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', - 'argumentCount' => '4,5' - ), - 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', - 'argumentCount' => '1,2' - ), - 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', - 'argumentCount' => '1,2' - ), - 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', - 'argumentCount' => '1,2' - ), - 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'rad2deg', - 'argumentCount' => '1' - ), - 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', - 'argumentCount' => '1,2' - ), - 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', - 'argumentCount' => '1+' - ), - 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DGET', - 'argumentCount' => '3' - ), - 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', - 'argumentCount' => '4,5' - ), - 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', - 'argumentCount' => '3' - ), - 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', - 'argumentCount' => '3' - ), - 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', - 'argumentCount' => '1,2' - ), - 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', - 'argumentCount' => '2' - ), - 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', - 'argumentCount' => '2' - ), - 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', - 'argumentCount' => '3' - ), - 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', - 'argumentCount' => '3' - ), - 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', - 'argumentCount' => '3' - ), - 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', - 'argumentCount' => '3' - ), - 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5,6' - ), - 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', - 'argumentCount' => '3' - ), - 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, - 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', - 'argumentCount' => '3' - ), - 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', - 'argumentCount' => '2' - ), - 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', - 'argumentCount' => '2' - ), - 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', - 'argumentCount' => '2' - ), - 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', - 'argumentCount' => '1,2' - ), - 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', - 'argumentCount' => '1' - ), - 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', - 'argumentCount' => '1' - ), - 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', - 'argumentCount' => '1' - ), - 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'exp', - 'argumentCount' => '1' - ), - 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', - 'argumentCount' => '3' - ), - 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', - 'argumentCount' => '1' - ), - 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', - 'argumentCount' => '1' - ), - 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', - 'argumentCount' => '0' - ), - 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3' - ), - 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', - 'argumentCount' => '2,3' - ), - 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', - 'argumentCount' => '2,3' - ), - 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3' - ), - 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', - 'argumentCount' => '1' - ), - 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', - 'argumentCount' => '1' - ), - 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', - 'argumentCount' => '1-3' - ), - 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', - 'argumentCount' => '2' - ), - 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', - 'argumentCount' => '3' - ), - 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::FV', - 'argumentCount' => '3-5' - ), - 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', - 'argumentCount' => '2' - ), - 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', - 'argumentCount' => '4' - ), - 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', - 'argumentCount' => '3' - ), - 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', - 'argumentCount' => '1' - ), - 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', - 'argumentCount' => '1+' - ), - 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', - 'argumentCount' => '1+' - ), - 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', - 'argumentCount' => '1,2' - ), - 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2+' - ), - 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', - 'argumentCount' => '1-4' - ), - 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', - 'argumentCount' => '1+' - ), - 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', - 'argumentCount' => '1,2' - ), - 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', - 'argumentCount' => '1' - ), - 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', - 'argumentCount' => '1,2' - ), - 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', - 'argumentCount' => '3,4' - ), - 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', - 'argumentCount' => '1' - ), - 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', - 'argumentCount' => '1,2', - 'passCellReference'=> true - ), - 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', - 'argumentCount' => '4' - ), - 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', - 'argumentCount' => '1-3' - ), - 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', - 'argumentCount' => '2' - ), - 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', - 'argumentCount' => '1' - ), - 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', - 'argumentCount' => '1' - ), - 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', - 'argumentCount' => '1' - ), - 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', - 'argumentCount' => '1' - ), - 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', - 'argumentCount' => '1' - ), - 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', - 'argumentCount' => '2' - ), - 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', - 'argumentCount' => '1' - ), - 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', - 'argumentCount' => '1' - ), - 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', - 'argumentCount' => '1' - ), - 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', - 'argumentCount' => '1' - ), - 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', - 'argumentCount' => '2' - ), - 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', - 'argumentCount' => '1+' - ), - 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', - 'argumentCount' => '1' - ), - 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', - 'argumentCount' => '1' - ), - 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', - 'argumentCount' => '1' - ), - 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', - 'argumentCount' => '2' - ), - 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', - 'argumentCount' => '1+' - ), - 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', - 'argumentCount' => '1-4' - ), - 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', - 'argumentCount' => '1,2', - 'passCellReference'=> true - ), - 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', - 'argumentCount' => '1' - ), - 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', - 'argumentCount' => '2' - ), - 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', - 'argumentCount' => '4,5' - ), - 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', - 'argumentCount' => '4-6' - ), - 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', - 'argumentCount' => '1,2' - ), - 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', - 'argumentCount' => '1' - ), - 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', - 'argumentCount' => '1' - ), - 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', - 'argumentCount' => '1' - ), - 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', - 'argumentCount' => '1' - ), - 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', - 'argumentCount' => '1' - ), - 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', - 'argumentCount' => '1' - ), - 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', - 'argumentCount' => '1' - ), - 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', - 'argumentCount' => '1' - ), - 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', - 'argumentCount' => '1' - ), - 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', - 'argumentCount' => '4' - ), - 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', - 'argumentCount' => '1' - ), - 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', - 'argumentCount' => '1+' - ), - 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', - 'argumentCount' => '2' - ), - 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', - 'argumentCount' => '1+' - ), - 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', - 'argumentCount' => '1,2' - ), - 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', - 'argumentCount' => '1,2' - ), - 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', - 'argumentCount' => '1' - ), - 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', - 'argumentCount' => '1' - ), - 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', - 'argumentCount' => '1-4' - ), - 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'log', - 'argumentCount' => '1' - ), - 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', - 'argumentCount' => '1,2' - ), - 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'log10', - 'argumentCount' => '1' - ), - 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', - 'argumentCount' => '1-4' - ), - 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', - 'argumentCount' => '3' - ), - 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', - 'argumentCount' => '3' - ), - 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', - 'argumentCount' => '2,3' - ), - 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', - 'argumentCount' => '1' - ), - 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', - 'argumentCount' => '2,3' - ), - 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', - 'argumentCount' => '1+' - ), - 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', - 'argumentCount' => '1+' - ), - 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', - 'argumentCount' => '2+' - ), - 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', - 'argumentCount' => '1' - ), - 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5,6' - ), - 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', - 'argumentCount' => '1+' - ), - 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2+' - ), - 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::MID', - 'argumentCount' => '3' - ), - 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::MID', - 'argumentCount' => '3' - ), - 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', - 'argumentCount' => '1+' - ), - 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', - 'argumentCount' => '1+' - ), - 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', - 'argumentCount' => '2+' - ), - 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', - 'argumentCount' => '1' - ), - 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', - 'argumentCount' => '1' - ), - 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', - 'argumentCount' => '3' - ), - 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', - 'argumentCount' => '2' - ), - 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', - 'argumentCount' => '2' - ), - 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', - 'argumentCount' => '1+' - ), - 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', - 'argumentCount' => '1' - ), - 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', - 'argumentCount' => '2' - ), - 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', - 'argumentCount' => '1+' - ), - 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::N', - 'argumentCount' => '1' - ), - 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::NA', - 'argumentCount' => '0' - ), - 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', - 'argumentCount' => '3' - ), - 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', - 'argumentCount' => '2+' - ), - 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', - 'argumentCount' => '2' - ), - 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', - 'argumentCount' => '4' - ), - 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', - 'argumentCount' => '3' - ), - 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', - 'argumentCount' => '1' - ), - 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', - 'argumentCount' => '1' - ), - 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', - 'argumentCount' => '1' - ), - 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', - 'argumentCount' => '0' - ), - 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', - 'argumentCount' => '3-5' - ), - 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', - 'argumentCount' => '2+' - ), - 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', - 'argumentCount' => '1,2' - ), - 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', - 'argumentCount' => '1' - ), - 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', - 'argumentCount' => '1,2' - ), - 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', - 'argumentCount' => '1' - ), - 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '8,9' - ), - 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '8,9' - ), - 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '7,8' - ), - 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '7,8' - ), - 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', - 'argumentCount' => '3,5', - 'passCellReference'=> true, - 'passByReference' => array(true) - ), - 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', - 'argumentCount' => '1+' - ), - 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', - 'argumentCount' => '2' - ), - 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', - 'argumentCount' => '2' - ), - 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', - 'argumentCount' => '2,3' - ), - 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', - 'argumentCount' => '2' - ), - 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1' - ), - 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'pi', - 'argumentCount' => '0' - ), - 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', - 'argumentCount' => '3-5' - ), - 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', - 'argumentCount' => '3' - ), - 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', - 'argumentCount' => '2' - ), - 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', - 'argumentCount' => '4-6' - ), - 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', - 'argumentCount' => '6,7' - ), - 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', - 'argumentCount' => '4,5' - ), - 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', - 'argumentCount' => '5,6' - ), - 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '3,4' - ), - 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', - 'argumentCount' => '1+' - ), - 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', - 'argumentCount' => '1' - ), - 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::PV', - 'argumentCount' => '3-5' - ), - 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', - 'argumentCount' => '2' - ), - 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', - 'argumentCount' => '2' - ), - 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'deg2rad', - 'argumentCount' => '1' - ), - 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', - 'argumentCount' => '0' - ), - 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', - 'argumentCount' => '2' - ), - 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', - 'argumentCount' => '2,3' - ), - 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', - 'argumentCount' => '3-6' - ), - 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', - 'argumentCount' => '4-5' - ), - 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', - 'argumentCount' => '4' - ), - 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', - 'argumentCount' => '4' - ), - 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'str_repeat', - 'argumentCount' => '2' - ), - 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', - 'argumentCount' => '1,2' - ), - 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', - 'argumentCount' => '1,2' - ), - 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', - 'argumentCount' => '1,2' - ), - 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'round', - 'argumentCount' => '2' - ), - 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', - 'argumentCount' => '2' - ), - 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', - 'argumentCount' => '2' - ), - 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', - 'argumentCount' => '-1', - 'passByReference' => array(true) - ), - 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', - 'argumentCount' => '1' - ), - 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', - 'argumentCount' => '2' - ), - 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '1+' - ), - 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', - 'argumentCount' => '2,3' - ), - 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', - 'argumentCount' => '2,3' - ), - 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', - 'argumentCount' => '1' - ), - 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', - 'argumentCount' => '4' - ), - 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', - 'argumentCount' => '1' - ), - 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sin', - 'argumentCount' => '1' - ), - 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sinh', - 'argumentCount' => '1' - ), - 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', - 'argumentCount' => '1+' - ), - 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', - 'argumentCount' => '3' - ), - 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', - 'argumentCount' => '2' - ), - 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', - 'argumentCount' => '2' - ), - 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'sqrt', - 'argumentCount' => '1' - ), - 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', - 'argumentCount' => '1' - ), - 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', - 'argumentCount' => '3' - ), - 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', - 'argumentCount' => '1+' - ), - 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', - 'argumentCount' => '1+' - ), - 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', - 'argumentCount' => '1+' - ), - 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', - 'argumentCount' => '1+' - ), - 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', - 'argumentCount' => '2' - ), - 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', - 'argumentCount' => '3,4' - ), - 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', - 'argumentCount' => '2+' - ), - 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', - 'argumentCount' => '1+' - ), - 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', - 'argumentCount' => '2,3' - ), - 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' - ), - 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', - 'argumentCount' => '1+' - ), - 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', - 'argumentCount' => '1+' - ), - 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', - 'argumentCount' => '2' - ), - 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', - 'argumentCount' => '2' - ), - 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', - 'argumentCount' => '2' - ), - 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', - 'argumentCount' => '4' - ), - 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', - 'argumentCount' => '1' - ), - 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'tan', - 'argumentCount' => '1' - ), - 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'tanh', - 'argumentCount' => '1' - ), - 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', - 'argumentCount' => '3' - ), - 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', - 'argumentCount' => '3' - ), - 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', - 'argumentCount' => '3' - ), - 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', - 'argumentCount' => '3' - ), - 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', - 'argumentCount' => '2' - ), - 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', - 'argumentCount' => '3' - ), - 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', - 'argumentCount' => '1' - ), - 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', - 'argumentCount' => '2' - ), - 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', - 'argumentCount' => '0' - ), - 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', - 'argumentCount' => '1' - ), - 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', - 'argumentCount' => '1-4' - ), - 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', - 'argumentCount' => '1' - ), - 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', - 'argumentCount' => '2' - ), - 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, - 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', - 'argumentCount' => '0' - ), - 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', - 'argumentCount' => '1,2' - ), - 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '4' - ), - 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', - 'argumentCount' => '1' - ), - 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', - 'argumentCount' => '1' - ), - 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '2' - ), - 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', - 'argumentCount' => '1' - ), - 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', - 'argumentCount' => '1+' - ), - 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', - 'argumentCount' => '1+' - ), - 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', - 'argumentCount' => '1+' - ), - 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', - 'argumentCount' => '1+' - ), - 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '5-7' - ), - 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, - 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', - 'argumentCount' => '0' - ), - 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', - 'argumentCount' => '3,4' - ), - 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', - 'argumentCount' => '1,2' - ), - 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', - 'argumentCount' => '1,2' - ), - 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', - 'argumentCount' => '4' - ), - 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', - 'argumentCount' => '2+' - ), - 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', - 'argumentCount' => '2,3' - ), - 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', - 'argumentCount' => '3' - ), - 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', - 'argumentCount' => '1' - ), - 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', - 'argumentCount' => '2,3' - ), - 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '6,7' - ), - 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', - 'argumentCount' => '4,5' - ), - 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', - 'argumentCount' => '5,6' - ), - 'ZTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, - 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', - 'argumentCount' => '2-3' - ) - ); + private static $PHPExcelFunctions = array( + 'ABS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'abs', + 'argumentCount' => '1' + ), + 'ACCRINT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', + 'argumentCount' => '4-7' + ), + 'ACCRINTM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', + 'argumentCount' => '3-5' + ), + 'ACOS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acos', + 'argumentCount' => '1' + ), + 'ACOSH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acosh', + 'argumentCount' => '1' + ), + 'ADDRESS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', + 'argumentCount' => '2-5' + ), + 'AMORDEGRC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', + 'argumentCount' => '6,7' + ), + 'AMORLINC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', + 'argumentCount' => '6,7' + ), + 'AND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', + 'argumentCount' => '1+' + ), + 'AREAS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asin', + 'argumentCount' => '1' + ), + 'ASINH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asinh', + 'argumentCount' => '1' + ), + 'ATAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atan', + 'argumentCount' => '1' + ), + 'ATAN2' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', + 'argumentCount' => '2' + ), + 'ATANH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atanh', + 'argumentCount' => '1' + ), + 'AVEDEV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', + 'argumentCount' => '1+' + ), + 'AVERAGE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', + 'argumentCount' => '1+' + ), + 'AVERAGEA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', + 'argumentCount' => '1+' + ), + 'AVERAGEIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', + 'argumentCount' => '2,3' + ), + 'AVERAGEIFS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3+' + ), + 'BAHTTEXT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'BESSELI' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', + 'argumentCount' => '2' + ), + 'BESSELJ' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', + 'argumentCount' => '2' + ), + 'BESSELK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', + 'argumentCount' => '2' + ), + 'BESSELY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', + 'argumentCount' => '2' + ), + 'BETADIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', + 'argumentCount' => '3-5' + ), + 'BETAINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', + 'argumentCount' => '3-5' + ), + 'BIN2DEC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', + 'argumentCount' => '1' + ), + 'BIN2HEX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', + 'argumentCount' => '1,2' + ), + 'BIN2OCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', + 'argumentCount' => '1,2' + ), + 'BINOMDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', + 'argumentCount' => '4' + ), + 'CEILING' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', + 'argumentCount' => '2' + ), + 'CELL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1,2' + ), + 'CHAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', + 'argumentCount' => '1' + ), + 'CHIDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', + 'argumentCount' => '2' + ), + 'CHIINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', + 'argumentCount' => '2' + ), + 'CHITEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'CHOOSE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', + 'argumentCount' => '2+' + ), + 'CLEAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', + 'argumentCount' => '1' + ), + 'CODE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', + 'argumentCount' => '1' + ), + 'COLUMN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', + 'argumentCount' => '-1', + 'passByReference' => array(true) + ), + 'COLUMNS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', + 'argumentCount' => '1' + ), + 'COMBIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', + 'argumentCount' => '2' + ), + 'COMPLEX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', + 'argumentCount' => '2,3' + ), + 'CONCATENATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', + 'argumentCount' => '1+' + ), + 'CONFIDENCE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', + 'argumentCount' => '3' + ), + 'CONVERT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', + 'argumentCount' => '3' + ), + 'CORREL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'COS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cos', + 'argumentCount' => '1' + ), + 'COSH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cosh', + 'argumentCount' => '1' + ), + 'COUNT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', + 'argumentCount' => '1+' + ), + 'COUNTA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', + 'argumentCount' => '1+' + ), + 'COUNTBLANK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', + 'argumentCount' => '1' + ), + 'COUNTIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', + 'argumentCount' => '2' + ), + 'COUNTIFS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'COUPDAYBS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', + 'argumentCount' => '3,4' + ), + 'COUPDAYS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', + 'argumentCount' => '3,4' + ), + 'COUPDAYSNC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', + 'argumentCount' => '3,4' + ), + 'COUPNCD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', + 'argumentCount' => '3,4' + ), + 'COUPNUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', + 'argumentCount' => '3,4' + ), + 'COUPPCD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', + 'argumentCount' => '3,4' + ), + 'COVAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', + 'argumentCount' => '2' + ), + 'CRITBINOM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', + 'argumentCount' => '3' + ), + 'CUBEKPIMEMBER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBERPROPERTY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBERANKEDMEMBER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESET' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESETCOUNT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEVALUE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUMIPMT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', + 'argumentCount' => '6' + ), + 'CUMPRINC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', + 'argumentCount' => '6' + ), + 'DATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', + 'argumentCount' => '3' + ), + 'DATEDIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', + 'argumentCount' => '2,3' + ), + 'DATEVALUE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', + 'argumentCount' => '1' + ), + 'DAVERAGE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', + 'argumentCount' => '3' + ), + 'DAY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', + 'argumentCount' => '1' + ), + 'DAYS360' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', + 'argumentCount' => '2,3' + ), + 'DB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DB', + 'argumentCount' => '4,5' + ), + 'DCOUNT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', + 'argumentCount' => '3' + ), + 'DCOUNTA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', + 'argumentCount' => '3' + ), + 'DDB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', + 'argumentCount' => '4,5' + ), + 'DEC2BIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', + 'argumentCount' => '1,2' + ), + 'DEC2HEX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', + 'argumentCount' => '1,2' + ), + 'DEC2OCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', + 'argumentCount' => '1,2' + ), + 'DEGREES' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'rad2deg', + 'argumentCount' => '1' + ), + 'DELTA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', + 'argumentCount' => '1,2' + ), + 'DEVSQ' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', + 'argumentCount' => '1+' + ), + 'DGET' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DGET', + 'argumentCount' => '3' + ), + 'DISC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', + 'argumentCount' => '4,5' + ), + 'DMAX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', + 'argumentCount' => '3' + ), + 'DMIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', + 'argumentCount' => '3' + ), + 'DOLLAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', + 'argumentCount' => '1,2' + ), + 'DOLLARDE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', + 'argumentCount' => '2' + ), + 'DOLLARFR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', + 'argumentCount' => '2' + ), + 'DPRODUCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', + 'argumentCount' => '3' + ), + 'DSTDEV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', + 'argumentCount' => '3' + ), + 'DSTDEVP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', + 'argumentCount' => '3' + ), + 'DSUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', + 'argumentCount' => '3' + ), + 'DURATION' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'DVAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', + 'argumentCount' => '3' + ), + 'DVARP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', + 'argumentCount' => '3' + ), + 'EDATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', + 'argumentCount' => '2' + ), + 'EFFECT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', + 'argumentCount' => '2' + ), + 'EOMONTH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', + 'argumentCount' => '2' + ), + 'ERF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', + 'argumentCount' => '1,2' + ), + 'ERFC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', + 'argumentCount' => '1' + ), + 'ERROR.TYPE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', + 'argumentCount' => '1' + ), + 'EVEN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', + 'argumentCount' => '1' + ), + 'EXACT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'EXP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'exp', + 'argumentCount' => '1' + ), + 'EXPONDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', + 'argumentCount' => '3' + ), + 'FACT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', + 'argumentCount' => '1' + ), + 'FACTDOUBLE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', + 'argumentCount' => '1' + ), + 'FALSE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', + 'argumentCount' => '0' + ), + 'FDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FIND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINDB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FISHER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', + 'argumentCount' => '1' + ), + 'FISHERINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', + 'argumentCount' => '1' + ), + 'FIXED' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', + 'argumentCount' => '1-3' + ), + 'FLOOR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', + 'argumentCount' => '2' + ), + 'FORECAST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', + 'argumentCount' => '3' + ), + 'FREQUENCY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FTEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FV', + 'argumentCount' => '3-5' + ), + 'FVSCHEDULE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', + 'argumentCount' => '2' + ), + 'GAMMADIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', + 'argumentCount' => '4' + ), + 'GAMMAINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', + 'argumentCount' => '3' + ), + 'GAMMALN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', + 'argumentCount' => '1' + ), + 'GCD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', + 'argumentCount' => '1+' + ), + 'GEOMEAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', + 'argumentCount' => '1+' + ), + 'GESTEP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', + 'argumentCount' => '1,2' + ), + 'GETPIVOTDATA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'GROWTH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', + 'argumentCount' => '1-4' + ), + 'HARMEAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', + 'argumentCount' => '1+' + ), + 'HEX2BIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', + 'argumentCount' => '1,2' + ), + 'HEX2DEC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', + 'argumentCount' => '1' + ), + 'HEX2OCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', + 'argumentCount' => '1,2' + ), + 'HLOOKUP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', + 'argumentCount' => '3,4' + ), + 'HOUR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', + 'argumentCount' => '1' + ), + 'HYPERLINK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', + 'argumentCount' => '1,2', + 'passCellReference' => true + ), + 'HYPGEOMDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', + 'argumentCount' => '4' + ), + 'IF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', + 'argumentCount' => '1-3' + ), + 'IFERROR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', + 'argumentCount' => '2' + ), + 'IMABS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', + 'argumentCount' => '1' + ), + 'IMAGINARY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', + 'argumentCount' => '1' + ), + 'IMARGUMENT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', + 'argumentCount' => '1' + ), + 'IMCONJUGATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', + 'argumentCount' => '1' + ), + 'IMCOS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', + 'argumentCount' => '1' + ), + 'IMDIV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', + 'argumentCount' => '2' + ), + 'IMEXP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', + 'argumentCount' => '1' + ), + 'IMLN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', + 'argumentCount' => '1' + ), + 'IMLOG10' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', + 'argumentCount' => '1' + ), + 'IMLOG2' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', + 'argumentCount' => '1' + ), + 'IMPOWER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', + 'argumentCount' => '2' + ), + 'IMPRODUCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', + 'argumentCount' => '1+' + ), + 'IMREAL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', + 'argumentCount' => '1' + ), + 'IMSIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', + 'argumentCount' => '1' + ), + 'IMSQRT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', + 'argumentCount' => '1' + ), + 'IMSUB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', + 'argumentCount' => '2' + ), + 'IMSUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', + 'argumentCount' => '1+' + ), + 'INDEX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', + 'argumentCount' => '1-4' + ), + 'INDIRECT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', + 'argumentCount' => '1,2', + 'passCellReference' => true + ), + 'INFO' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'INT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', + 'argumentCount' => '1' + ), + 'INTERCEPT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', + 'argumentCount' => '2' + ), + 'INTRATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', + 'argumentCount' => '4,5' + ), + 'IPMT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', + 'argumentCount' => '4-6' + ), + 'IRR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', + 'argumentCount' => '1,2' + ), + 'ISBLANK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', + 'argumentCount' => '1' + ), + 'ISERR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', + 'argumentCount' => '1' + ), + 'ISERROR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', + 'argumentCount' => '1' + ), + 'ISEVEN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', + 'argumentCount' => '1' + ), + 'ISLOGICAL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', + 'argumentCount' => '1' + ), + 'ISNA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', + 'argumentCount' => '1' + ), + 'ISNONTEXT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', + 'argumentCount' => '1' + ), + 'ISNUMBER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', + 'argumentCount' => '1' + ), + 'ISODD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', + 'argumentCount' => '1' + ), + 'ISPMT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', + 'argumentCount' => '4' + ), + 'ISREF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ISTEXT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', + 'argumentCount' => '1' + ), + 'JIS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'KURT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', + 'argumentCount' => '1+' + ), + 'LARGE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', + 'argumentCount' => '2' + ), + 'LCM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', + 'argumentCount' => '1+' + ), + 'LEFT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEFTB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LENB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LINEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', + 'argumentCount' => '1-4' + ), + 'LN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log', + 'argumentCount' => '1' + ), + 'LOG' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', + 'argumentCount' => '1,2' + ), + 'LOG10' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log10', + 'argumentCount' => '1' + ), + 'LOGEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', + 'argumentCount' => '1-4' + ), + 'LOGINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', + 'argumentCount' => '3' + ), + 'LOGNORMDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', + 'argumentCount' => '3' + ), + 'LOOKUP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', + 'argumentCount' => '2,3' + ), + 'LOWER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', + 'argumentCount' => '1' + ), + 'MATCH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', + 'argumentCount' => '2,3' + ), + 'MAX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', + 'argumentCount' => '1+' + ), + 'MAXA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', + 'argumentCount' => '1+' + ), + 'MAXIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', + 'argumentCount' => '2+' + ), + 'MDETERM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', + 'argumentCount' => '1' + ), + 'MDURATION' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'MEDIAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', + 'argumentCount' => '1+' + ), + 'MEDIANIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'MID' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIDB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', + 'argumentCount' => '1+' + ), + 'MINA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', + 'argumentCount' => '1+' + ), + 'MINIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', + 'argumentCount' => '2+' + ), + 'MINUTE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', + 'argumentCount' => '1' + ), + 'MINVERSE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', + 'argumentCount' => '1' + ), + 'MIRR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', + 'argumentCount' => '3' + ), + 'MMULT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', + 'argumentCount' => '2' + ), + 'MOD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', + 'argumentCount' => '2' + ), + 'MODE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', + 'argumentCount' => '1+' + ), + 'MONTH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', + 'argumentCount' => '1' + ), + 'MROUND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', + 'argumentCount' => '2' + ), + 'MULTINOMIAL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', + 'argumentCount' => '1+' + ), + 'N' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::N', + 'argumentCount' => '1' + ), + 'NA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::NA', + 'argumentCount' => '0' + ), + 'NEGBINOMDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', + 'argumentCount' => '3' + ), + 'NETWORKDAYS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', + 'argumentCount' => '2+' + ), + 'NOMINAL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', + 'argumentCount' => '2' + ), + 'NORMDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', + 'argumentCount' => '4' + ), + 'NORMINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', + 'argumentCount' => '3' + ), + 'NORMSDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', + 'argumentCount' => '1' + ), + 'NORMSINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', + 'argumentCount' => '1' + ), + 'NOT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', + 'argumentCount' => '1' + ), + 'NOW' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', + 'argumentCount' => '0' + ), + 'NPER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', + 'argumentCount' => '3-5' + ), + 'NPV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', + 'argumentCount' => '2+' + ), + 'OCT2BIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', + 'argumentCount' => '1,2' + ), + 'OCT2DEC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', + 'argumentCount' => '1' + ), + 'OCT2HEX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', + 'argumentCount' => '1,2' + ), + 'ODD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', + 'argumentCount' => '1' + ), + 'ODDFPRICE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDFYIELD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDLPRICE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'ODDLYIELD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'OFFSET' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', + 'argumentCount' => '3,5', + 'passCellReference' => true, + 'passByReference' => array(true) + ), + 'OR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', + 'argumentCount' => '1+' + ), + 'PEARSON' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'PERCENTILE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', + 'argumentCount' => '2' + ), + 'PERCENTRANK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', + 'argumentCount' => '2,3' + ), + 'PERMUT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', + 'argumentCount' => '2' + ), + 'PHONETIC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'PI' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'pi', + 'argumentCount' => '0' + ), + 'PMT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', + 'argumentCount' => '3-5' + ), + 'POISSON' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', + 'argumentCount' => '3' + ), + 'POWER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', + 'argumentCount' => '2' + ), + 'PPMT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', + 'argumentCount' => '4-6' + ), + 'PRICE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', + 'argumentCount' => '6,7' + ), + 'PRICEDISC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', + 'argumentCount' => '4,5' + ), + 'PRICEMAT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', + 'argumentCount' => '5,6' + ), + 'PROB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3,4' + ), + 'PRODUCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', + 'argumentCount' => '1+' + ), + 'PROPER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', + 'argumentCount' => '1' + ), + 'PV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PV', + 'argumentCount' => '3-5' + ), + 'QUARTILE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', + 'argumentCount' => '2' + ), + 'QUOTIENT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', + 'argumentCount' => '2' + ), + 'RADIANS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'deg2rad', + 'argumentCount' => '1' + ), + 'RAND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '0' + ), + 'RANDBETWEEN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '2' + ), + 'RANK' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', + 'argumentCount' => '2,3' + ), + 'RATE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', + 'argumentCount' => '3-6' + ), + 'RECEIVED' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', + 'argumentCount' => '4-5' + ), + 'REPLACE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPLACEB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'str_repeat', + 'argumentCount' => '2' + ), + 'RIGHT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'RIGHTB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'ROMAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', + 'argumentCount' => '1,2' + ), + 'ROUND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'round', + 'argumentCount' => '2' + ), + 'ROUNDDOWN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', + 'argumentCount' => '2' + ), + 'ROUNDUP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', + 'argumentCount' => '2' + ), + 'ROW' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', + 'argumentCount' => '-1', + 'passByReference' => array(true) + ), + 'ROWS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', + 'argumentCount' => '1' + ), + 'RSQ' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', + 'argumentCount' => '2' + ), + 'RTD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1+' + ), + 'SEARCH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SEARCHB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SECOND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', + 'argumentCount' => '1' + ), + 'SERIESSUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', + 'argumentCount' => '4' + ), + 'SIGN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', + 'argumentCount' => '1' + ), + 'SIN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sin', + 'argumentCount' => '1' + ), + 'SINH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sinh', + 'argumentCount' => '1' + ), + 'SKEW' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', + 'argumentCount' => '1+' + ), + 'SLN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', + 'argumentCount' => '3' + ), + 'SLOPE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', + 'argumentCount' => '2' + ), + 'SMALL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', + 'argumentCount' => '2' + ), + 'SQRT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sqrt', + 'argumentCount' => '1' + ), + 'SQRTPI' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', + 'argumentCount' => '1' + ), + 'STANDARDIZE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', + 'argumentCount' => '3' + ), + 'STDEV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', + 'argumentCount' => '1+' + ), + 'STDEVA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', + 'argumentCount' => '1+' + ), + 'STDEVP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', + 'argumentCount' => '1+' + ), + 'STDEVPA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', + 'argumentCount' => '1+' + ), + 'STEYX' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', + 'argumentCount' => '2' + ), + 'SUBSTITUTE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', + 'argumentCount' => '3,4' + ), + 'SUBTOTAL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', + 'argumentCount' => '2+' + ), + 'SUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', + 'argumentCount' => '1+' + ), + 'SUMIF' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', + 'argumentCount' => '2,3' + ), + 'SUMIFS' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'SUMPRODUCT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', + 'argumentCount' => '1+' + ), + 'SUMSQ' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', + 'argumentCount' => '1+' + ), + 'SUMX2MY2' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', + 'argumentCount' => '2' + ), + 'SUMX2PY2' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', + 'argumentCount' => '2' + ), + 'SUMXMY2' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', + 'argumentCount' => '2' + ), + 'SYD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', + 'argumentCount' => '4' + ), + 'T' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', + 'argumentCount' => '1' + ), + 'TAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tan', + 'argumentCount' => '1' + ), + 'TANH' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tanh', + 'argumentCount' => '1' + ), + 'TBILLEQ' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', + 'argumentCount' => '3' + ), + 'TBILLPRICE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', + 'argumentCount' => '3' + ), + 'TBILLYIELD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', + 'argumentCount' => '3' + ), + 'TDIST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', + 'argumentCount' => '3' + ), + 'TEXT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', + 'argumentCount' => '2' + ), + 'TIME' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', + 'argumentCount' => '3' + ), + 'TIMEVALUE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', + 'argumentCount' => '1' + ), + 'TINV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', + 'argumentCount' => '2' + ), + 'TODAY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', + 'argumentCount' => '0' + ), + 'TRANSPOSE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', + 'argumentCount' => '1' + ), + 'TREND' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', + 'argumentCount' => '1-4' + ), + 'TRIM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', + 'argumentCount' => '1' + ), + 'TRIMMEAN' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', + 'argumentCount' => '2' + ), + 'TRUE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', + 'argumentCount' => '0' + ), + 'TRUNC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', + 'argumentCount' => '1,2' + ), + 'TTEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '4' + ), + 'TYPE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', + 'argumentCount' => '1' + ), + 'UPPER' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', + 'argumentCount' => '1' + ), + 'USDOLLAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'VALUE' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', + 'argumentCount' => '1' + ), + 'VAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', + 'argumentCount' => '1+' + ), + 'VARA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', + 'argumentCount' => '1+' + ), + 'VARP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', + 'argumentCount' => '1+' + ), + 'VARPA' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', + 'argumentCount' => '1+' + ), + 'VDB' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5-7' + ), + 'VERSION' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', + 'argumentCount' => '0' + ), + 'VLOOKUP' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', + 'argumentCount' => '3,4' + ), + 'WEEKDAY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', + 'argumentCount' => '1,2' + ), + 'WEEKNUM' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', + 'argumentCount' => '1,2' + ), + 'WEIBULL' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', + 'argumentCount' => '4' + ), + 'WORKDAY' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', + 'argumentCount' => '2+' + ), + 'XIRR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', + 'argumentCount' => '2,3' + ), + 'XNPV' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', + 'argumentCount' => '3' + ), + 'YEAR' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', + 'argumentCount' => '1' + ), + 'YEARFRAC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', + 'argumentCount' => '2,3' + ), + 'YIELD' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '6,7' + ), + 'YIELDDISC' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', + 'argumentCount' => '4,5' + ), + 'YIELDMAT' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', + 'argumentCount' => '5,6' + ), + 'ZTEST' => array( + 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', + 'argumentCount' => '2-3' + ) + ); // Internal functions used for special control purposes private static $controlFunctions = array( @@ -2480,7 +2836,7 @@ public function _calculateFormulaValue($formula, $cellID = null, PHPExcel_Cell $ * 1 = shrink to fit * 2 = extend to fit */ - private static function _checkMatrixOperands(&$operand1, &$operand2, $resize = 1) + private static function checkMatrixOperands(&$operand1, &$operand2, $resize = 1) { // Examine each of the two operands, and turn them into an array if they aren't one already // Note that this function should only be called if one or both of the operand is already an array @@ -2502,10 +2858,10 @@ private static function _checkMatrixOperands(&$operand1, &$operand2, $resize = 1 if ($resize == 2) { // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger - self::_resizeMatricesExtend($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); + self::resizeMatricesExtend($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); } elseif ($resize == 1) { // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller - self::_resizeMatricesShrink($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); + self::resizeMatricesShrink($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); } return array( $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns); } @@ -2544,7 +2900,7 @@ public static function _getMatrixDimensions(&$matrix) * @param integer $matrix2Rows Row size of second matrix operand * @param integer $matrix2Columns Column size of second matrix operand */ - private static function _resizeMatricesShrink(&$matrix1, &$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns) + private static function resizeMatricesShrink(&$matrix1, &$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns) { if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { if ($matrix2Rows < $matrix1Rows) { @@ -2588,7 +2944,7 @@ private static function _resizeMatricesShrink(&$matrix1, &$matrix2, $matrix1Rows * @param integer $matrix2Rows Row size of second matrix operand * @param integer $matrix2Columns Column size of second matrix operand */ - private static function _resizeMatricesExtend(&$matrix1, &$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns) + private static function resizeMatricesExtend(&$matrix1, &$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns) { if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { if ($matrix2Columns < $matrix1Columns) { @@ -2632,7 +2988,7 @@ private static function _resizeMatricesExtend(&$matrix1, &$matrix2, $matrix1Rows * @param mixed $value First matrix operand * @return mixed */ - private function _showValue($value) + private function showValue($value) { if ($this->_debugLog->getWriteDebugLog()) { $testArray = PHPExcel_Calculation_Functions::flattenArray($value); @@ -2645,10 +3001,10 @@ private function _showValue($value) $pad = $rpad = ', '; foreach ($value as $row) { if (is_array($row)) { - $returnMatrix[] = implode($pad, array_map(array($this, '_showValue'), $row)); + $returnMatrix[] = implode($pad, array_map(array($this, 'showValue'), $row)); $rpad = '; '; } else { - $returnMatrix[] = $this->_showValue($row); + $returnMatrix[] = $this->showValue($row); } } return '{ '.implode($rpad, $returnMatrix).' }'; @@ -2668,7 +3024,7 @@ private function _showValue($value) * @param mixed $value First matrix operand * @return mixed */ - private function _showTypeDetails($value) + private function showTypeDetails($value) { if ($this->_debugLog->getWriteDebugLog()) { $testArray = PHPExcel_Calculation_Functions::flattenArray($value); @@ -2695,12 +3051,12 @@ private function _showTypeDetails($value) $typeString = 'a string'; } } - return $typeString.' with a value of '.$this->_showValue($value); + return $typeString.' with a value of '.$this->showValue($value); } } - private function _convertMatrixReferences($formula) + private function convertMatrixReferences($formula) { static $matrixReplaceFrom = array('{', ';', '}'); static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(', '),MKMATRIX(', '))'); @@ -2761,7 +3117,7 @@ private static function _mkMatrix() // Binary Operators // These operators always work on two values // Array key is the operator, the value indicates whether this is a left or right associative operator - private static $_operatorAssociativity = array( + private static $operatorAssociativity = array( '^' => 0, // Exponentiation '*' => 0, '/' => 0, // Multiplication and Division '+' => 0, '-' => 0, // Addition and Subtraction @@ -2772,12 +3128,12 @@ private static function _mkMatrix() // Comparison (Boolean) Operators // These operators work on two values, but always return a boolean result - private static $_comparisonOperators = array('>' => true, '<' => true, '=' => true, '>=' => true, '<=' => true, '<>' => true); + private static $comparisonOperators = array('>' => true, '<' => true, '=' => true, '>=' => true, '<=' => true, '<>' => true); // Operator Precedence // This list includes all valid operators, whether binary (including boolean) or unary (such as %) // Array key is the operator, the value is its precedence - private static $_operatorPrecedence = array( + private static $operatorPrecedence = array( ':' => 8, // Range '|' => 7, // Intersect '~' => 6, // Negation @@ -2792,7 +3148,7 @@ private static function _mkMatrix() // Convert infix to postfix notation private function _parseFormula($formula, PHPExcel_Cell $pCell = null) { - if (($formula = $this->_convertMatrixReferences(trim($formula))) === false) { + if (($formula = $this->convertMatrixReferences(trim($formula))) === false) { return false; } @@ -2823,7 +3179,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) //echo 'Assessing Expression '.substr($formula, $index), PHP_EOL; $opCharacter = $formula{$index}; // Get the first character of the value at the current index position //echo 'Initial character of expression block is '.$opCharacter, PHP_EOL; - if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) { + if ((isset(self::$comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$comparisonOperators[$formula{$index+1}]))) { $opCharacter .= $formula{++$index}; //echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL; } @@ -2852,7 +3208,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) while ($stack->count() > 0 && ($o2 = $stack->last()) && isset(self::$operators[$o2['value']]) && - @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { + @(self::$operatorAssociativity[$opCharacter] ? self::$operatorPrecedence[$opCharacter] < self::$operatorPrecedence[$o2['value']] : self::$operatorPrecedence[$opCharacter] <= self::$operatorPrecedence[$o2['value']])) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } $stack->push('Binary Operator', $opCharacter); // Finally put our current operator onto the stack @@ -3128,7 +3484,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) while ($stack->count() > 0 && ($o2 = $stack->last()) && isset(self::$operators[$o2['value']]) && - @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { + @(self::$operatorAssociativity[$opCharacter] ? self::$operatorPrecedence[$opCharacter] < self::$operatorPrecedence[$o2['value']] : self::$operatorPrecedence[$opCharacter] <= self::$operatorPrecedence[$o2['value']])) { $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output } $stack->push('Binary Operator', '|'); // Put an Intersect Operator on the stack @@ -3197,9 +3553,9 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // Log what we're doing if ($token == ':') { - $this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); + $this->_debugLog->writeDebugLog('Evaluating Range ', $this->showValue($operand1Data['reference']), ' ', $token, ' ', $this->showValue($operand2Data['reference'])); } else { - $this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); + $this->_debugLog->writeDebugLog('Evaluating ', $this->showValue($operand1), ' ', $token, ' ', $this->showValue($operand2)); } // Process the operation in the appropriate manner @@ -3291,7 +3647,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } if ((is_array($operand1)) || (is_array($operand2))) { // Ensure that both operands are arrays/matrices - self::_checkMatrixOperands($operand1, $operand2, 2); + self::checkMatrixOperands($operand1, $operand2, 2); try { // Convert operand 1 from a PHP array to a matrix $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); @@ -3305,7 +3661,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } else { $result = '"'.str_replace('""', '"', self::_unwrapResult($operand1, '"').self::_unwrapResult($operand2, '"')).'"'; } - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($result)); $stack->push('Value', $result); break; case '|': // Intersect @@ -3319,7 +3675,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } } $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($cellIntersect)); $stack->push('Value', $cellIntersect, $cellRef); break; } @@ -3333,15 +3689,15 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $arg = $arg['value']; if ($token === '~') { // echo 'Token is a negation operator<br />'; - $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg)); + $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->showValue($arg)); $multiplier = -1; } else { // echo 'Token is a percentile operator<br />'; - $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg)); + $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->showValue($arg)); $multiplier = 0.01; } if (is_array($arg)) { - self::_checkMatrixOperands($arg, $multiplier, 2); + self::checkMatrixOperands($arg, $multiplier, 2); try { $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg); $matrixResult = $matrix1->arrayTimesEquals($multiplier); @@ -3350,7 +3706,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); $result = '#VALUE!'; } - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($result)); $stack->push('Value', $result); } else { $this->executeNumericBinaryOperation($cellID, $multiplier, $arg, '*', 'arrayTimesEquals', $stack); @@ -3380,7 +3736,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } else { return $this->raiseFormulaError('Unable to access Cell Reference'); } - $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->showTypeDetails($cellValue)); // $cellRef = $matches[2].'!'.$cellRef; } else { // echo '$cellRef='.$cellRef.' in current worksheet<br />'; @@ -3390,7 +3746,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } else { return $this->raiseFormulaError('Unable to access Cell Reference'); } - $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->showTypeDetails($cellValue)); } } } else { @@ -3419,7 +3775,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } else { return $this->raiseFormulaError('Unable to access Cell Reference'); } - $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->showTypeDetails($cellValue)); // $cellRef = $matches[2].'!'.$cellRef; } else { // echo '$cellRef='.$cellRef.' in current worksheet<br />'; @@ -3430,7 +3786,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } else { $cellValue = null; } - $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->showTypeDetails($cellValue)); } } } @@ -3467,18 +3823,18 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel if ($arg['reference'] === null) { $args[] = $cellID; if ($functionName != 'MKMATRIX') { - $argArrayVals[] = $this->_showValue($cellID); + $argArrayVals[] = $this->showValue($cellID); } } else { $args[] = $arg['reference']; if ($functionName != 'MKMATRIX') { - $argArrayVals[] = $this->_showValue($arg['reference']); + $argArrayVals[] = $this->showValue($arg['reference']); } } } else { $args[] = self::_unwrapResult($arg['value']); if ($functionName != 'MKMATRIX') { - $argArrayVals[] = $this->_showValue($arg['value']); + $argArrayVals[] = $this->showValue($arg['value']); } } } @@ -3486,7 +3842,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel krsort($args); if (($passByReference) && ($argCount == 0)) { $args[] = $cellID; - $argArrayVals[] = $this->_showValue($cellID); + $argArrayVals[] = $this->showValue($cellID); } // echo 'Arguments are: '; // print_r($args); @@ -3500,22 +3856,22 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel // Process each argument in turn, building the return value as an array // if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) { // $operand1 = $args[1]; -// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1)); +// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->showValue($operand1)); // $result = array(); // $row = 0; // foreach($operand1 as $args) { // if (is_array($args)) { // foreach($args as $arg) { -// $this->_debugLog->writeDebugLog('Evaluating ', self::localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); +// $this->_debugLog->writeDebugLog('Evaluating ', self::localeFunc($functionName), '( ', $this->showValue($arg), ' )'); // $r = call_user_func_array($functionCall, $arg); -// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->showTypeDetails($r)); // $result[$row][] = $r; // } // ++$row; // } else { -// $this->_debugLog->writeDebugLog('Evaluating ', self::localeFunc($functionName), '( ', $this->_showValue($args), ' )'); +// $this->_debugLog->writeDebugLog('Evaluating ', self::localeFunc($functionName), '( ', $this->showValue($args), ' )'); // $r = call_user_func_array($functionCall, $args); -// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->showTypeDetails($r)); // $result[] = $r; // } // } @@ -3534,7 +3890,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $result = call_user_func_array($functionCall, $args); } if ($functionName != 'MKMATRIX') { - $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->showTypeDetails($result)); } $stack->push('Value', self::_wrapResult($result)); } @@ -3545,7 +3901,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $excelConstant = strtoupper($token); // echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />'; $stack->push('Constant Value', self::$excelConstants[$excelConstant]); - $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$excelConstants[$excelConstant])); + $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->showTypeDetails(self::$excelConstants[$excelConstant])); } elseif ((is_numeric($token)) || ($token === null) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { // echo 'Token is a number, boolean, string, null or an Excel error<br />'; $stack->push('Value', $token); @@ -3557,7 +3913,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange); $cellValue = $this->extractNamedRange($namedRange, ((null !== $pCell) ? $pCellWorksheet : null), false); $pCell->attach($pCellParent); - $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); + $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->showTypeDetails($cellValue)); $stack->push('Named Range', $cellValue, $namedRange); } else { return $this->raiseFormulaError("undefined variable '$token'"); @@ -3599,12 +3955,12 @@ private function validateBinaryOperand($cellID, &$operand, &$stack) // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations if ($operand > '' && $operand{0} == '#') { $stack->push('Value', $operand); - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($operand)); return false; } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations $stack->push('Value', '#VALUE!'); - $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); + $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->showTypeDetails('#VALUE!')); return false; } } @@ -3622,31 +3978,31 @@ private function executeBinaryComparisonOperation($cellID, $operand1, $operand2, $result = array(); if ((is_array($operand1)) && (!is_array($operand2))) { foreach ($operand1 as $x => $operandData) { - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operandData), ' ', $operation, ' ', $this->showValue($operand2)); $this->executeBinaryComparisonOperation($cellID, $operandData, $operand2, $operation, $stack); $r = $stack->pop(); $result[$x] = $r['value']; } } elseif ((!is_array($operand1)) && (is_array($operand2))) { foreach ($operand2 as $x => $operandData) { - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operand1), ' ', $operation, ' ', $this->showValue($operandData)); $this->executeBinaryComparisonOperation($cellID, $operand1, $operandData, $operation, $stack); $r = $stack->pop(); $result[$x] = $r['value']; } } else { if (!$recursingArrays) { - self::_checkMatrixOperands($operand1, $operand2, 2); + self::checkMatrixOperands($operand1, $operand2, 2); } foreach ($operand1 as $x => $operandData) { - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operandData), ' ', $operation, ' ', $this->showValue($operand2[$x])); $this->executeBinaryComparisonOperation($cellID, $operandData, $operand2[$x], $operation, $stack, true); $r = $stack->pop(); $result[$x] = $r['value']; } } // Log the result details - $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->showTypeDetails($result)); // And push the result onto the stack $stack->push('Array', $result); return true; @@ -3729,7 +4085,7 @@ private function executeBinaryComparisonOperation($cellID, $operand1, $operand2, } // Log the result details - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($result)); // And push the result onto the stack $stack->push('Value', $result); return true; @@ -3764,7 +4120,7 @@ private function executeNumericBinaryOperation($cellID, $operand1, $operand2, $o // matrix operation if ((is_array($operand1)) || (is_array($operand2))) { // Ensure that both operands are arrays/matrices of the same size - self::_checkMatrixOperands($operand1, $operand2, 2); + self::checkMatrixOperands($operand1, $operand2, 2); try { // Convert operand 1 from a PHP array to a matrix @@ -3801,7 +4157,7 @@ private function executeNumericBinaryOperation($cellID, $operand1, $operand2, $o if ($operand2 == 0) { // Trap for Divide by Zero error $stack->push('Value', '#DIV/0!'); - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails('#DIV/0!')); return false; } else { $result = $operand1 / $operand2; @@ -3816,7 +4172,7 @@ private function executeNumericBinaryOperation($cellID, $operand1, $operand2, $o } // Log the result details - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($result)); // And push the result onto the stack $stack->push('Value', $result); return true; diff --git a/Classes/PHPExcel/Chart.php b/Classes/PHPExcel/Chart.php index 326eac547..0cc22c145 100644 --- a/Classes/PHPExcel/Chart.php +++ b/Classes/PHPExcel/Chart.php @@ -39,91 +39,91 @@ class PHPExcel_Chart * * @var PHPExcel_Worksheet */ - private $_worksheet = null; + private $worksheet; /** * Chart Title * * @var PHPExcel_Chart_Title */ - private $_title = null; + private $title; /** * Chart Legend * * @var PHPExcel_Chart_Legend */ - private $_legend = null; + private $legend; /** * X-Axis Label * * @var PHPExcel_Chart_Title */ - private $_xAxisLabel = null; + private $xAxisLabel; /** * Y-Axis Label * * @var PHPExcel_Chart_Title */ - private $_yAxisLabel = null; + private $yAxisLabel; /** * Chart Plot Area * * @var PHPExcel_Chart_PlotArea */ - private $_plotArea = null; + private $plotArea; /** * Plot Visible Only * * @var boolean */ - private $_plotVisibleOnly = true; + private $plotVisibleOnly = true; /** * Display Blanks as * * @var string */ - private $_displayBlanksAs = '0'; + private $displayBlanksAs = '0'; /** * Chart Asix Y as * * @var PHPExcel_Chart_Axis */ - private $_yAxis = null; + private $yAxis; /** * Chart Asix X as * * @var PHPExcel_Chart_Axis */ - private $_xAxis = null; + private $xAxis; /** * Chart Major Gridlines as * * @var PHPExcel_Chart_GridLines */ - private $_majorGridlines = null; + private $majorGridlines; /** * Chart Minor Gridlines as * * @var PHPExcel_Chart_GridLines */ - private $_minorGridlines = null; + private $minorGridlines; /** * Top-Left Cell Position * * @var string */ - private $_topLeftCellRef = 'A1'; + private $topLeftCellRef = 'A1'; /** @@ -131,7 +131,7 @@ class PHPExcel_Chart * * @var integer */ - private $_topLeftXOffset = 0; + private $topLeftXOffset = 0; /** @@ -139,7 +139,7 @@ class PHPExcel_Chart * * @var integer */ - private $_topLeftYOffset = 0; + private $topLeftYOffset = 0; /** @@ -147,7 +147,7 @@ class PHPExcel_Chart * * @var string */ - private $_bottomRightCellRef = 'A1'; + private $bottomRightCellRef = 'A1'; /** @@ -155,7 +155,7 @@ class PHPExcel_Chart * * @var integer */ - private $_bottomRightXOffset = 10; + private $bottomRightXOffset = 10; /** @@ -163,7 +163,7 @@ class PHPExcel_Chart * * @var integer */ - private $_bottomRightYOffset = 10; + private $bottomRightYOffset = 10; /** @@ -172,17 +172,17 @@ class PHPExcel_Chart public function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_Chart_Legend $legend = null, PHPExcel_Chart_PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = '0', PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, PHPExcel_Chart_Axis $xAxis = null, PHPExcel_Chart_Axis $yAxis = null, PHPExcel_Chart_GridLines $majorGridlines = null, PHPExcel_Chart_GridLines $minorGridlines = null) { $this->_name = $name; - $this->_title = $title; - $this->_legend = $legend; - $this->_xAxisLabel = $xAxisLabel; - $this->_yAxisLabel = $yAxisLabel; - $this->_plotArea = $plotArea; - $this->_plotVisibleOnly = $plotVisibleOnly; - $this->_displayBlanksAs = $displayBlanksAs; - $this->_xAxis = $xAxis; - $this->_yAxis = $yAxis; - $this->_majorGridlines = $majorGridlines; - $this->_minorGridlines = $minorGridlines; + $this->title = $title; + $this->legend = $legend; + $this->xAxisLabel = $xAxisLabel; + $this->yAxisLabel = $yAxisLabel; + $this->plotArea = $plotArea; + $this->plotVisibleOnly = $plotVisibleOnly; + $this->displayBlanksAs = $displayBlanksAs; + $this->xAxis = $xAxis; + $this->yAxis = $yAxis; + $this->majorGridlines = $majorGridlines; + $this->minorGridlines = $minorGridlines; } /** @@ -202,7 +202,7 @@ public function getName() */ public function getWorksheet() { - return $this->_worksheet; + return $this->worksheet; } /** @@ -214,7 +214,7 @@ public function getWorksheet() */ public function setWorksheet(PHPExcel_Worksheet $pValue = null) { - $this->_worksheet = $pValue; + $this->worksheet = $pValue; return $this; } @@ -226,7 +226,7 @@ public function setWorksheet(PHPExcel_Worksheet $pValue = null) */ public function getTitle() { - return $this->_title; + return $this->title; } /** @@ -237,7 +237,7 @@ public function getTitle() */ public function setTitle(PHPExcel_Chart_Title $title) { - $this->_title = $title; + $this->title = $title; return $this; } @@ -249,7 +249,7 @@ public function setTitle(PHPExcel_Chart_Title $title) */ public function getLegend() { - return $this->_legend; + return $this->legend; } /** @@ -260,7 +260,7 @@ public function getLegend() */ public function setLegend(PHPExcel_Chart_Legend $legend) { - $this->_legend = $legend; + $this->legend = $legend; return $this; } @@ -272,7 +272,7 @@ public function setLegend(PHPExcel_Chart_Legend $legend) */ public function getXAxisLabel() { - return $this->_xAxisLabel; + return $this->xAxisLabel; } /** @@ -283,7 +283,7 @@ public function getXAxisLabel() */ public function setXAxisLabel(PHPExcel_Chart_Title $label) { - $this->_xAxisLabel = $label; + $this->xAxisLabel = $label; return $this; } @@ -295,7 +295,7 @@ public function setXAxisLabel(PHPExcel_Chart_Title $label) */ public function getYAxisLabel() { - return $this->_yAxisLabel; + return $this->yAxisLabel; } /** @@ -306,7 +306,7 @@ public function getYAxisLabel() */ public function setYAxisLabel(PHPExcel_Chart_Title $label) { - $this->_yAxisLabel = $label; + $this->yAxisLabel = $label; return $this; } @@ -318,7 +318,7 @@ public function setYAxisLabel(PHPExcel_Chart_Title $label) */ public function getPlotArea() { - return $this->_plotArea; + return $this->plotArea; } /** @@ -328,7 +328,7 @@ public function getPlotArea() */ public function getPlotVisibleOnly() { - return $this->_plotVisibleOnly; + return $this->plotVisibleOnly; } /** @@ -339,7 +339,7 @@ public function getPlotVisibleOnly() */ public function setPlotVisibleOnly($plotVisibleOnly = true) { - $this->_plotVisibleOnly = $plotVisibleOnly; + $this->plotVisibleOnly = $plotVisibleOnly; return $this; } @@ -351,7 +351,7 @@ public function setPlotVisibleOnly($plotVisibleOnly = true) */ public function getDisplayBlanksAs() { - return $this->_displayBlanksAs; + return $this->displayBlanksAs; } /** @@ -362,7 +362,7 @@ public function getDisplayBlanksAs() */ public function setDisplayBlanksAs($displayBlanksAs = '0') { - $this->_displayBlanksAs = $displayBlanksAs; + $this->displayBlanksAs = $displayBlanksAs; } @@ -373,8 +373,8 @@ public function setDisplayBlanksAs($displayBlanksAs = '0') */ public function getChartAxisY() { - if ($this->_yAxis !== null) { - return $this->_yAxis; + if ($this->yAxis !== null) { + return $this->yAxis; } return new PHPExcel_Chart_Axis(); @@ -387,8 +387,8 @@ public function getChartAxisY() */ public function getChartAxisX() { - if ($this->_xAxis !== null) { - return $this->_xAxis; + if ($this->xAxis !== null) { + return $this->xAxis; } return new PHPExcel_Chart_Axis(); @@ -401,8 +401,8 @@ public function getChartAxisX() */ public function getMajorGridlines() { - if ($this->_majorGridlines !== null) { - return $this->_majorGridlines; + if ($this->majorGridlines !== null) { + return $this->majorGridlines; } return new PHPExcel_Chart_GridLines(); @@ -415,8 +415,8 @@ public function getMajorGridlines() */ public function getMinorGridlines() { - if ($this->_minorGridlines !== null) { - return $this->_minorGridlines; + if ($this->minorGridlines !== null) { + return $this->minorGridlines; } return new PHPExcel_Chart_GridLines(); @@ -433,7 +433,7 @@ public function getMinorGridlines() */ public function setTopLeftPosition($cell, $xOffset = null, $yOffset = null) { - $this->_topLeftCellRef = $cell; + $this->topLeftCellRef = $cell; if (!is_null($xOffset)) { $this->setTopLeftXOffset($xOffset); } @@ -452,9 +452,9 @@ public function setTopLeftPosition($cell, $xOffset = null, $yOffset = null) public function getTopLeftPosition() { return array( - 'cell' => $this->_topLeftCellRef, - 'xOffset' => $this->_topLeftXOffset, - 'yOffset' => $this->_topLeftYOffset + 'cell' => $this->topLeftCellRef, + 'xOffset' => $this->topLeftXOffset, + 'yOffset' => $this->topLeftYOffset ); } @@ -465,7 +465,7 @@ public function getTopLeftPosition() */ public function getTopLeftCell() { - return $this->_topLeftCellRef; + return $this->topLeftCellRef; } /** @@ -476,7 +476,7 @@ public function getTopLeftCell() */ public function setTopLeftCell($cell) { - $this->_topLeftCellRef = $cell; + $this->topLeftCellRef = $cell; return $this; } @@ -508,33 +508,33 @@ public function setTopLeftOffset($xOffset = null, $yOffset = null) public function getTopLeftOffset() { return array( - 'X' => $this->_topLeftXOffset, - 'Y' => $this->_topLeftYOffset + 'X' => $this->topLeftXOffset, + 'Y' => $this->topLeftYOffset ); } public function setTopLeftXOffset($xOffset) { - $this->_topLeftXOffset = $xOffset; + $this->topLeftXOffset = $xOffset; return $this; } public function getTopLeftXOffset() { - return $this->_topLeftXOffset; + return $this->topLeftXOffset; } public function setTopLeftYOffset($yOffset) { - $this->_topLeftYOffset = $yOffset; + $this->topLeftYOffset = $yOffset; return $this; } public function getTopLeftYOffset() { - return $this->_topLeftYOffset; + return $this->topLeftYOffset; } /** @@ -547,7 +547,7 @@ public function getTopLeftYOffset() */ public function setBottomRightPosition($cell, $xOffset = null, $yOffset = null) { - $this->_bottomRightCellRef = $cell; + $this->bottomRightCellRef = $cell; if (!is_null($xOffset)) { $this->setBottomRightXOffset($xOffset); } @@ -566,15 +566,15 @@ public function setBottomRightPosition($cell, $xOffset = null, $yOffset = null) public function getBottomRightPosition() { return array( - 'cell' => $this->_bottomRightCellRef, - 'xOffset' => $this->_bottomRightXOffset, - 'yOffset' => $this->_bottomRightYOffset + 'cell' => $this->bottomRightCellRef, + 'xOffset' => $this->bottomRightXOffset, + 'yOffset' => $this->bottomRightYOffset ); } public function setBottomRightCell($cell) { - $this->_bottomRightCellRef = $cell; + $this->bottomRightCellRef = $cell; return $this; } @@ -586,7 +586,7 @@ public function setBottomRightCell($cell) */ public function getBottomRightCell() { - return $this->_bottomRightCellRef; + return $this->bottomRightCellRef; } /** @@ -616,40 +616,40 @@ public function setBottomRightOffset($xOffset = null, $yOffset = null) public function getBottomRightOffset() { return array( - 'X' => $this->_bottomRightXOffset, - 'Y' => $this->_bottomRightYOffset + 'X' => $this->bottomRightXOffset, + 'Y' => $this->bottomRightYOffset ); } public function setBottomRightXOffset($xOffset) { - $this->_bottomRightXOffset = $xOffset; + $this->bottomRightXOffset = $xOffset; return $this; } public function getBottomRightXOffset() { - return $this->_bottomRightXOffset; + return $this->bottomRightXOffset; } public function setBottomRightYOffset($yOffset) { - $this->_bottomRightYOffset = $yOffset; + $this->bottomRightYOffset = $yOffset; return $this; } public function getBottomRightYOffset() { - return $this->_bottomRightYOffset; + return $this->bottomRightYOffset; } public function refresh() { - if ($this->_worksheet !== null) { - $this->_plotArea->refresh($this->_worksheet); + if ($this->worksheet !== null) { + $this->plotArea->refresh($this->worksheet); } } diff --git a/Classes/PHPExcel/Comment.php b/Classes/PHPExcel/Comment.php index 0546f4aee..d55363fd5 100644 --- a/Classes/PHPExcel/Comment.php +++ b/Classes/PHPExcel/Comment.php @@ -32,63 +32,63 @@ class PHPExcel_Comment implements PHPExcel_IComparable * * @var string */ - private $_author; + private $author; /** * Rich text comment * * @var PHPExcel_RichText */ - private $_text; + private $text; /** * Comment width (CSS style, i.e. XXpx or YYpt) * * @var string */ - private $_width = '96pt'; + private $width = '96pt'; /** * Left margin (CSS style, i.e. XXpx or YYpt) * * @var string */ - private $_marginLeft = '59.25pt'; + private $marginLeft = '59.25pt'; /** * Top margin (CSS style, i.e. XXpx or YYpt) * * @var string */ - private $_marginTop = '1.5pt'; + private $marginTop = '1.5pt'; /** * Visible * * @var boolean */ - private $_visible = false; + private $visible = false; /** * Comment height (CSS style, i.e. XXpx or YYpt) * * @var string */ - private $_height = '55.5pt'; + private $height = '55.5pt'; /** * Comment fill color * * @var PHPExcel_Style_Color */ - private $_fillColor; + private $fillColor; /** * Alignment * * @var string */ - private $_alignment; + private $alignment; /** * Create a new PHPExcel_Comment @@ -98,10 +98,10 @@ class PHPExcel_Comment implements PHPExcel_IComparable public function __construct() { // Initialise variables - $this->_author = 'Author'; - $this->_text = new PHPExcel_RichText(); - $this->_fillColor = new PHPExcel_Style_Color('FFFFFFE1'); - $this->_alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + $this->author = 'Author'; + $this->text = new PHPExcel_RichText(); + $this->fillColor = new PHPExcel_Style_Color('FFFFFFE1'); + $this->alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; } /** @@ -111,7 +111,7 @@ public function __construct() */ public function getAuthor() { - return $this->_author; + return $this->author; } /** @@ -122,7 +122,7 @@ public function getAuthor() */ public function setAuthor($pValue = '') { - $this->_author = $pValue; + $this->author = $pValue; return $this; } @@ -133,7 +133,7 @@ public function setAuthor($pValue = '') */ public function getText() { - return $this->_text; + return $this->text; } /** @@ -144,7 +144,7 @@ public function getText() */ public function setText(PHPExcel_RichText $pValue) { - $this->_text = $pValue; + $this->text = $pValue; return $this; } @@ -155,7 +155,7 @@ public function setText(PHPExcel_RichText $pValue) */ public function getWidth() { - return $this->_width; + return $this->width; } /** @@ -166,7 +166,7 @@ public function getWidth() */ public function setWidth($value = '96pt') { - $this->_width = $value; + $this->width = $value; return $this; } @@ -177,7 +177,7 @@ public function setWidth($value = '96pt') */ public function getHeight() { - return $this->_height; + return $this->height; } /** @@ -188,7 +188,7 @@ public function getHeight() */ public function setHeight($value = '55.5pt') { - $this->_height = $value; + $this->height = $value; return $this; } @@ -199,7 +199,7 @@ public function setHeight($value = '55.5pt') */ public function getMarginLeft() { - return $this->_marginLeft; + return $this->marginLeft; } /** @@ -210,7 +210,7 @@ public function getMarginLeft() */ public function setMarginLeft($value = '59.25pt') { - $this->_marginLeft = $value; + $this->marginLeft = $value; return $this; } @@ -221,7 +221,7 @@ public function setMarginLeft($value = '59.25pt') */ public function getMarginTop() { - return $this->_marginTop; + return $this->marginTop; } /** @@ -232,7 +232,7 @@ public function getMarginTop() */ public function setMarginTop($value = '1.5pt') { - $this->_marginTop = $value; + $this->marginTop = $value; return $this; } @@ -243,7 +243,7 @@ public function setMarginTop($value = '1.5pt') */ public function getVisible() { - return $this->_visible; + return $this->visible; } /** @@ -254,7 +254,7 @@ public function getVisible() */ public function setVisible($value = false) { - $this->_visible = $value; + $this->visible = $value; return $this; } @@ -265,7 +265,7 @@ public function setVisible($value = false) */ public function getFillColor() { - return $this->_fillColor; + return $this->fillColor; } /** @@ -276,7 +276,7 @@ public function getFillColor() */ public function setAlignment($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) { - $this->_alignment = $pValue; + $this->alignment = $pValue; return $this; } @@ -287,7 +287,7 @@ public function setAlignment($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENE */ public function getAlignment() { - return $this->_alignment; + return $this->alignment; } /** @@ -298,16 +298,16 @@ public function getAlignment() public function getHashCode() { return md5( - $this->_author - . $this->_text->getHashCode() - . $this->_width - . $this->_height - . $this->_marginLeft - . $this->_marginTop - . ($this->_visible ? 1 : 0) - . $this->_fillColor->getHashCode() - . $this->_alignment - . __CLASS__ + $this->author . + $this->text->getHashCode() . + $this->width . + $this->height . + $this->marginLeft . + $this->marginTop . + ($this->visible ? 1 : 0) . + $this->fillColor->getHashCode() . + $this->alignment . + __CLASS__ ); } @@ -333,6 +333,6 @@ public function __clone() */ public function __toString() { - return $this->_text->getPlainText(); + return $this->text->getPlainText(); } } diff --git a/Classes/PHPExcel/DocumentProperties.php b/Classes/PHPExcel/DocumentProperties.php index f52059f5f..2395ba987 100644 --- a/Classes/PHPExcel/DocumentProperties.php +++ b/Classes/PHPExcel/DocumentProperties.php @@ -40,84 +40,84 @@ class PHPExcel_DocumentProperties * * @var string */ - private $_creator = 'Unknown Creator'; + private $creator = 'Unknown Creator'; /** * LastModifiedBy * * @var string */ - private $_lastModifiedBy; + private $lastModifiedBy; /** * Created * * @var datetime */ - private $_created; + private $created; /** * Modified * * @var datetime */ - private $_modified; + private $modified; /** * Title * * @var string */ - private $_title = 'Untitled Spreadsheet'; + private $title = 'Untitled Spreadsheet'; /** * Description * * @var string */ - private $_description = ''; + private $description = ''; /** * Subject * * @var string */ - private $_subject = ''; + private $subject = ''; /** * Keywords * * @var string */ - private $_keywords = ''; + private $keywords = ''; /** * Category * * @var string */ - private $_category = ''; + private $category = ''; /** * Manager * * @var string */ - private $_manager = ''; + private $manager = ''; /** * Company * * @var string */ - private $_company = 'Microsoft Corporation'; + private $company = 'Microsoft Corporation'; /** * Custom Properties * * @var string */ - private $_customProperties = array(); + private $customProperties = array(); /** @@ -126,9 +126,9 @@ class PHPExcel_DocumentProperties public function __construct() { // Initialise values - $this->_lastModifiedBy = $this->_creator; - $this->_created = time(); - $this->_modified = time(); + $this->lastModifiedBy = $this->creator; + $this->created = time(); + $this->modified = time(); } /** @@ -138,7 +138,7 @@ public function __construct() */ public function getCreator() { - return $this->_creator; + return $this->creator; } /** @@ -149,7 +149,7 @@ public function getCreator() */ public function setCreator($pValue = '') { - $this->_creator = $pValue; + $this->creator = $pValue; return $this; } @@ -160,7 +160,7 @@ public function setCreator($pValue = '') */ public function getLastModifiedBy() { - return $this->_lastModifiedBy; + return $this->lastModifiedBy; } /** @@ -171,7 +171,7 @@ public function getLastModifiedBy() */ public function setLastModifiedBy($pValue = '') { - $this->_lastModifiedBy = $pValue; + $this->lastModifiedBy = $pValue; return $this; } @@ -182,7 +182,7 @@ public function setLastModifiedBy($pValue = '') */ public function getCreated() { - return $this->_created; + return $this->created; } /** @@ -203,7 +203,7 @@ public function setCreated($pValue = null) } } - $this->_created = $pValue; + $this->created = $pValue; return $this; } @@ -214,7 +214,7 @@ public function setCreated($pValue = null) */ public function getModified() { - return $this->_modified; + return $this->modified; } /** @@ -235,7 +235,7 @@ public function setModified($pValue = null) } } - $this->_modified = $pValue; + $this->modified = $pValue; return $this; } @@ -246,7 +246,7 @@ public function setModified($pValue = null) */ public function getTitle() { - return $this->_title; + return $this->title; } /** @@ -257,7 +257,7 @@ public function getTitle() */ public function setTitle($pValue = '') { - $this->_title = $pValue; + $this->title = $pValue; return $this; } @@ -268,7 +268,7 @@ public function setTitle($pValue = '') */ public function getDescription() { - return $this->_description; + return $this->description; } /** @@ -279,7 +279,7 @@ public function getDescription() */ public function setDescription($pValue = '') { - $this->_description = $pValue; + $this->description = $pValue; return $this; } @@ -290,7 +290,7 @@ public function setDescription($pValue = '') */ public function getSubject() { - return $this->_subject; + return $this->subject; } /** @@ -301,7 +301,7 @@ public function getSubject() */ public function setSubject($pValue = '') { - $this->_subject = $pValue; + $this->subject = $pValue; return $this; } @@ -312,7 +312,7 @@ public function setSubject($pValue = '') */ public function getKeywords() { - return $this->_keywords; + return $this->keywords; } /** @@ -323,7 +323,7 @@ public function getKeywords() */ public function setKeywords($pValue = '') { - $this->_keywords = $pValue; + $this->keywords = $pValue; return $this; } @@ -334,7 +334,7 @@ public function setKeywords($pValue = '') */ public function getCategory() { - return $this->_category; + return $this->category; } /** @@ -345,7 +345,7 @@ public function getCategory() */ public function setCategory($pValue = '') { - $this->_category = $pValue; + $this->category = $pValue; return $this; } @@ -356,7 +356,7 @@ public function setCategory($pValue = '') */ public function getCompany() { - return $this->_company; + return $this->company; } /** @@ -367,7 +367,7 @@ public function getCompany() */ public function setCompany($pValue = '') { - $this->_company = $pValue; + $this->company = $pValue; return $this; } @@ -378,7 +378,7 @@ public function setCompany($pValue = '') */ public function getManager() { - return $this->_manager; + return $this->manager; } /** @@ -389,7 +389,7 @@ public function getManager() */ public function setManager($pValue = '') { - $this->_manager = $pValue; + $this->manager = $pValue; return $this; } @@ -400,7 +400,7 @@ public function setManager($pValue = '') */ public function getCustomProperties() { - return array_keys($this->_customProperties); + return array_keys($this->customProperties); } /** @@ -411,7 +411,7 @@ public function getCustomProperties() */ public function isCustomPropertySet($propertyName) { - return isset($this->_customProperties[$propertyName]); + return isset($this->customProperties[$propertyName]); } /** @@ -422,8 +422,8 @@ public function isCustomPropertySet($propertyName) */ public function getCustomPropertyValue($propertyName) { - if (isset($this->_customProperties[$propertyName])) { - return $this->_customProperties[$propertyName]['value']; + if (isset($this->customProperties[$propertyName])) { + return $this->customProperties[$propertyName]['value']; } } @@ -436,8 +436,8 @@ public function getCustomPropertyValue($propertyName) */ public function getCustomPropertyType($propertyName) { - if (isset($this->_customProperties[$propertyName])) { - return $this->_customProperties[$propertyName]['type']; + if (isset($this->customProperties[$propertyName])) { + return $this->customProperties[$propertyName]['type']; } } @@ -475,7 +475,7 @@ public function setCustomProperty($propertyName, $propertyValue = '', $propertyT } } - $this->_customProperties[$propertyName] = array( + $this->customProperties[$propertyName] = array( 'value' => $propertyValue, 'type' => $propertyType ); diff --git a/Classes/PHPExcel/HashTable.php b/Classes/PHPExcel/HashTable.php index f752a3637..c21d18c3a 100644 --- a/Classes/PHPExcel/HashTable.php +++ b/Classes/PHPExcel/HashTable.php @@ -32,14 +32,14 @@ class PHPExcel_HashTable * * @var array */ - public $_items = array(); + protected $items = array(); /** * HashTable key map * * @var array */ - public $_keyMap = array(); + protected $keyMap = array(); /** * Create a new PHPExcel_HashTable @@ -84,9 +84,9 @@ public function addFromSource($pSource = null) public function add(PHPExcel_IComparable $pSource = null) { $hash = $pSource->getHashCode(); - if (!isset($this->_items[$hash])) { - $this->_items[$hash] = $pSource; - $this->_keyMap[count($this->_items) - 1] = $hash; + if (!isset($this->items[$hash])) { + $this->items[$hash] = $pSource; + $this->keyMap[count($this->items) - 1] = $hash; } } @@ -99,20 +99,20 @@ public function add(PHPExcel_IComparable $pSource = null) public function remove(PHPExcel_IComparable $pSource = null) { $hash = $pSource->getHashCode(); - if (isset($this->_items[$hash])) { - unset($this->_items[$hash]); + if (isset($this->items[$hash])) { + unset($this->items[$hash]); $deleteKey = -1; - foreach ($this->_keyMap as $key => $value) { + foreach ($this->keyMap as $key => $value) { if ($deleteKey >= 0) { - $this->_keyMap[$key - 1] = $value; + $this->keyMap[$key - 1] = $value; } if ($value == $hash) { $deleteKey = $key; } } - unset($this->_keyMap[count($this->_keyMap) - 1]); + unset($this->keyMap[count($this->keyMap) - 1]); } } @@ -122,8 +122,8 @@ public function remove(PHPExcel_IComparable $pSource = null) */ public function clear() { - $this->_items = array(); - $this->_keyMap = array(); + $this->items = array(); + $this->keyMap = array(); } /** @@ -133,7 +133,7 @@ public function clear() */ public function count() { - return count($this->_items); + return count($this->items); } /** @@ -144,7 +144,7 @@ public function count() */ public function getIndexForHashCode($pHashCode = '') { - return array_search($pHashCode, $this->_keyMap); + return array_search($pHashCode, $this->keyMap); } /** @@ -156,8 +156,8 @@ public function getIndexForHashCode($pHashCode = '') */ public function getByIndex($pIndex = 0) { - if (isset($this->_keyMap[$pIndex])) { - return $this->getByHashCode($this->_keyMap[$pIndex]); + if (isset($this->keyMap[$pIndex])) { + return $this->getByHashCode($this->keyMap[$pIndex]); } return null; @@ -172,8 +172,8 @@ public function getByIndex($pIndex = 0) */ public function getByHashCode($pHashCode = '') { - if (isset($this->_items[$pHashCode])) { - return $this->_items[$pHashCode]; + if (isset($this->items[$pHashCode])) { + return $this->items[$pHashCode]; } return null; @@ -186,7 +186,7 @@ public function getByHashCode($pHashCode = '') */ public function toArray() { - return $this->_items; + return $this->items; } /** diff --git a/Classes/PHPExcel/Worksheet/ColumnDimension.php b/Classes/PHPExcel/Worksheet/ColumnDimension.php index fe007c819..405b8258e 100644 --- a/Classes/PHPExcel/Worksheet/ColumnDimension.php +++ b/Classes/PHPExcel/Worksheet/ColumnDimension.php @@ -25,14 +25,14 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ -class PHPExcel_Worksheet_ColumnDimension +class PHPExcel_Worksheet_ColumnDimension extends PHPExcel_Worksheet_Dimension { /** * Column index * * @var int */ - private $_columnIndex; + private $columnIndex; /** * Column width @@ -41,42 +41,14 @@ class PHPExcel_Worksheet_ColumnDimension * * @var double */ - private $_width = -1; + private $width = -1; /** * Auto size? * * @var bool */ - private $_autoSize = false; - - /** - * Visible? - * - * @var bool - */ - private $_visible = true; - - /** - * Outline level - * - * @var int - */ - private $_outlineLevel = 0; - - /** - * Collapsed - * - * @var bool - */ - private $_collapsed = false; - - /** - * Index to cellXf - * - * @var int - */ - private $_xfIndex; + private $autoSize = false; /** * Create a new PHPExcel_Worksheet_ColumnDimension @@ -86,10 +58,10 @@ class PHPExcel_Worksheet_ColumnDimension public function __construct($pIndex = 'A') { // Initialise values - $this->_columnIndex = $pIndex; + $this->columnIndex = $pIndex; - // set default index to cellXf - $this->_xfIndex = 0; + // set dimension as unformatted by default + parent::__construct(0); } /** @@ -99,7 +71,7 @@ public function __construct($pIndex = 'A') */ public function getColumnIndex() { - return $this->_columnIndex; + return $this->columnIndex; } /** @@ -110,7 +82,7 @@ public function getColumnIndex() */ public function setColumnIndex($pValue) { - $this->_columnIndex = $pValue; + $this->columnIndex = $pValue; return $this; } @@ -121,7 +93,7 @@ public function setColumnIndex($pValue) */ public function getWidth() { - return $this->_width; + return $this->width; } /** @@ -132,7 +104,7 @@ public function getWidth() */ public function setWidth($pValue = -1) { - $this->_width = $pValue; + $this->width = $pValue; return $this; } @@ -143,7 +115,7 @@ public function setWidth($pValue = -1) */ public function getAutoSize() { - return $this->_autoSize; + return $this->autoSize; } /** @@ -154,117 +126,7 @@ public function getAutoSize() */ public function setAutoSize($pValue = false) { - $this->_autoSize = $pValue; - return $this; - } - - /** - * Get Visible - * - * @return bool - */ - public function getVisible() - { - return $this->_visible; - } - - /** - * Set Visible - * - * @param bool $pValue - * @return PHPExcel_Worksheet_ColumnDimension - */ - public function setVisible($pValue = true) - { - $this->_visible = $pValue; + $this->autoSize = $pValue; return $this; } - - /** - * Get Outline Level - * - * @return int - */ - public function getOutlineLevel() - { - return $this->_outlineLevel; - } - - /** - * Set Outline Level - * - * Value must be between 0 and 7 - * - * @param int $pValue - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_ColumnDimension - */ - public function setOutlineLevel($pValue) - { - if ($pValue < 0 || $pValue > 7) { - throw new PHPExcel_Exception("Outline level must range between 0 and 7."); - } - - $this->_outlineLevel = $pValue; - return $this; - } - - /** - * Get Collapsed - * - * @return bool - */ - public function getCollapsed() - { - return $this->_collapsed; - } - - /** - * Set Collapsed - * - * @param bool $pValue - * @return PHPExcel_Worksheet_ColumnDimension - */ - public function setCollapsed($pValue = true) - { - $this->_collapsed = $pValue; - return $this; - } - - /** - * Get index to cellXf - * - * @return int - */ - public function getXfIndex() - { - return $this->_xfIndex; - } - - /** - * Set index to cellXf - * - * @param int $pValue - * @return PHPExcel_Worksheet_ColumnDimension - */ - public function setXfIndex($pValue = 0) - { - $this->_xfIndex = $pValue; - return $this; - } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() - { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } } diff --git a/Classes/PHPExcel/Worksheet/Dimension.php b/Classes/PHPExcel/Worksheet/Dimension.php new file mode 100644 index 000000000..84f692cb5 --- /dev/null +++ b/Classes/PHPExcel/Worksheet/Dimension.php @@ -0,0 +1,178 @@ +<?php + +/** + * PHPExcel_Worksheet_Dimension + * + * Copyright (c) 2006 - 2015 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## + */ +abstract class PHPExcel_Worksheet_Dimension +{ + /** + * Visible? + * + * @var bool + */ + private $visible = true; + + /** + * Outline level + * + * @var int + */ + private $outlineLevel = 0; + + /** + * Collapsed + * + * @var bool + */ + private $collapsed = false; + + /** + * Index to cellXf. Null value means row has no explicit cellXf format. + * + * @var int|null + */ + private $xfIndex; + + /** + * Create a new PHPExcel_Worksheet_Dimension + * + * @param int $pIndex Numeric row index + */ + public function __construct($initialValue = null) + { + // set dimension as unformatted by default + $this->xfIndex = $initialValue; + } + + /** + * Get Visible + * + * @return bool + */ + public function getVisible() + { + return $this->visible; + } + + /** + * Set Visible + * + * @param bool $pValue + * @return PHPExcel_Worksheet_Dimension + */ + public function setVisible($pValue = true) + { + $this->visible = $pValue; + return $this; + } + + /** + * Get Outline Level + * + * @return int + */ + public function getOutlineLevel() + { + return $this->outlineLevel; + } + + /** + * Set Outline Level + * + * Value must be between 0 and 7 + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_Dimension + */ + public function setOutlineLevel($pValue) + { + if ($pValue < 0 || $pValue > 7) { + throw new PHPExcel_Exception("Outline level must range between 0 and 7."); + } + + $this->outlineLevel = $pValue; + return $this; + } + + /** + * Get Collapsed + * + * @return bool + */ + public function getCollapsed() + { + return $this->collapsed; + } + + /** + * Set Collapsed + * + * @param bool $pValue + * @return PHPExcel_Worksheet_Dimension + */ + public function setCollapsed($pValue = true) + { + $this->collapsed = $pValue; + return $this; + } + + /** + * Get index to cellXf + * + * @return int + */ + public function getXfIndex() + { + return $this->xfIndex; + } + + /** + * Set index to cellXf + * + * @param int $pValue + * @return PHPExcel_Worksheet_Dimension + */ + public function setXfIndex($pValue = 0) + { + $this->xfIndex = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() + { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/Classes/PHPExcel/Worksheet/RowDimension.php b/Classes/PHPExcel/Worksheet/RowDimension.php index 5314f9c19..c1474862c 100644 --- a/Classes/PHPExcel/Worksheet/RowDimension.php +++ b/Classes/PHPExcel/Worksheet/RowDimension.php @@ -25,14 +25,14 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ -class PHPExcel_Worksheet_RowDimension +class PHPExcel_Worksheet_RowDimension extends PHPExcel_Worksheet_Dimension { /** * Row index * * @var int */ - private $_rowIndex; + private $rowIndex; /** * Row height (in pt) @@ -41,42 +41,14 @@ class PHPExcel_Worksheet_RowDimension * * @var double */ - private $_rowHeight = -1; + private $height = -1; /** * ZeroHeight for Row? * * @var bool */ - private $_zeroHeight = false; - - /** - * Visible? - * - * @var bool - */ - private $_visible = true; - - /** - * Outline level - * - * @var int - */ - private $_outlineLevel = 0; - - /** - * Collapsed - * - * @var bool - */ - private $_collapsed = false; - - /** - * Index to cellXf. Null value means row has no explicit cellXf format. - * - * @var int|null - */ - private $_xfIndex; + private $zeroHeight = false; /** * Create a new PHPExcel_Worksheet_RowDimension @@ -86,10 +58,10 @@ class PHPExcel_Worksheet_RowDimension public function __construct($pIndex = 0) { // Initialise values - $this->_rowIndex = $pIndex; + $this->rowIndex = $pIndex; - // set row dimension as unformatted by default - $this->_xfIndex = null; + // set dimension as unformatted by default + parent::__construct(null); } /** @@ -99,7 +71,7 @@ public function __construct($pIndex = 0) */ public function getRowIndex() { - return $this->_rowIndex; + return $this->rowIndex; } /** @@ -110,7 +82,7 @@ public function getRowIndex() */ public function setRowIndex($pValue) { - $this->_rowIndex = $pValue; + $this->rowIndex = $pValue; return $this; } @@ -121,7 +93,7 @@ public function setRowIndex($pValue) */ public function getRowHeight() { - return $this->_rowHeight; + return $this->height; } /** @@ -132,7 +104,7 @@ public function getRowHeight() */ public function setRowHeight($pValue = -1) { - $this->_rowHeight = $pValue; + $this->height = $pValue; return $this; } @@ -143,7 +115,7 @@ public function setRowHeight($pValue = -1) */ public function getZeroHeight() { - return $this->_zeroHeight; + return $this->zeroHeight; } /** @@ -154,117 +126,7 @@ public function getZeroHeight() */ public function setZeroHeight($pValue = false) { - $this->_zeroHeight = $pValue; - return $this; - } - - /** - * Get Visible - * - * @return bool - */ - public function getVisible() - { - return $this->_visible; - } - - /** - * Set Visible - * - * @param bool $pValue - * @return PHPExcel_Worksheet_RowDimension - */ - public function setVisible($pValue = true) - { - $this->_visible = $pValue; - return $this; - } - - /** - * Get Outline Level - * - * @return int - */ - public function getOutlineLevel() - { - return $this->_outlineLevel; - } - - /** - * Set Outline Level - * - * Value must be between 0 and 7 - * - * @param int $pValue - * @throws PHPExcel_Exception - * @return PHPExcel_Worksheet_RowDimension - */ - public function setOutlineLevel($pValue) - { - if ($pValue < 0 || $pValue > 7) { - throw new PHPExcel_Exception("Outline level must range between 0 and 7."); - } - - $this->_outlineLevel = $pValue; + $this->zeroHeight = $pValue; return $this; } - - /** - * Get Collapsed - * - * @return bool - */ - public function getCollapsed() - { - return $this->_collapsed; - } - - /** - * Set Collapsed - * - * @param bool $pValue - * @return PHPExcel_Worksheet_RowDimension - */ - public function setCollapsed($pValue = true) - { - $this->_collapsed = $pValue; - return $this; - } - - /** - * Get index to cellXf - * - * @return int - */ - public function getXfIndex() - { - return $this->_xfIndex; - } - - /** - * Set index to cellXf - * - * @param int $pValue - * @return PHPExcel_Worksheet_RowDimension - */ - public function setXfIndex($pValue = 0) - { - $this->_xfIndex = $pValue; - return $this; - } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() - { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } } diff --git a/Classes/PHPExcel/Worksheet/SheetView.php b/Classes/PHPExcel/Worksheet/SheetView.php index e0ea61483..c7a7d5bf1 100644 --- a/Classes/PHPExcel/Worksheet/SheetView.php +++ b/Classes/PHPExcel/Worksheet/SheetView.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Worksheet_SheetView * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,22 +25,13 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Worksheet_SheetView - * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Worksheet_SheetView { /* Sheet View types */ - const SHEETVIEW_NORMAL = 'normal'; - const SHEETVIEW_PAGE_LAYOUT = 'pageLayout'; - const SHEETVIEW_PAGE_BREAK_PREVIEW = 'pageBreakPreview'; + const SHEETVIEW_NORMAL = 'normal'; + const SHEETVIEW_PAGE_LAYOUT = 'pageLayout'; + const SHEETVIEW_PAGE_BREAK_PREVIEW = 'pageBreakPreview'; private static $_sheetViewTypes = array( self::SHEETVIEW_NORMAL, @@ -54,7 +46,7 @@ class PHPExcel_Worksheet_SheetView * * @var int */ - private $_zoomScale = 100; + private $zoomScale = 100; /** * ZoomScaleNormal @@ -63,7 +55,7 @@ class PHPExcel_Worksheet_SheetView * * @var int */ - private $_zoomScaleNormal = 100; + private $zoomScaleNormal = 100; /** * View @@ -72,7 +64,7 @@ class PHPExcel_Worksheet_SheetView * * @var string */ - private $_sheetviewType = self::SHEETVIEW_NORMAL; + private $sheetviewType = self::SHEETVIEW_NORMAL; /** * Create a new PHPExcel_Worksheet_SheetView @@ -88,7 +80,7 @@ public function __construct() */ public function getZoomScale() { - return $this->_zoomScale; + return $this->zoomScale; } /** @@ -105,7 +97,7 @@ public function setZoomScale($pValue = 100) // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, // but it is apparently still able to handle any scale >= 1 if (($pValue >= 1) || is_null($pValue)) { - $this->_zoomScale = $pValue; + $this->zoomScale = $pValue; } else { throw new PHPExcel_Exception("Scale must be greater than or equal to 1."); } @@ -119,7 +111,7 @@ public function setZoomScale($pValue = 100) */ public function getZoomScaleNormal() { - return $this->_zoomScaleNormal; + return $this->zoomScaleNormal; } /** @@ -134,7 +126,7 @@ public function getZoomScaleNormal() public function setZoomScaleNormal($pValue = 100) { if (($pValue >= 1) || is_null($pValue)) { - $this->_zoomScaleNormal = $pValue; + $this->zoomScaleNormal = $pValue; } else { throw new PHPExcel_Exception("Scale must be greater than or equal to 1."); } @@ -148,7 +140,7 @@ public function setZoomScaleNormal($pValue = 100) */ public function getView() { - return $this->_sheetviewType; + return $this->sheetviewType; } /** @@ -157,7 +149,7 @@ public function getView() * Valid values are * 'normal' self::SHEETVIEW_NORMAL * 'pageLayout' self::SHEETVIEW_PAGE_LAYOUT - * 'pageBreakPreview' self::SHEETVIEW_PAGE_BREAK_PREVIEW + * 'pageBreakPreview' self::SHEETVIEW_PAGE_BREAK_PREVIEW * * @param string $pValue * @throws PHPExcel_Exception @@ -170,7 +162,7 @@ public function setView($pValue = null) $pValue = self::SHEETVIEW_NORMAL; } if (in_array($pValue, self::$_sheetViewTypes)) { - $this->_sheetviewType = $pValue; + $this->sheetviewType = $pValue; } else { throw new PHPExcel_Exception("Invalid sheetview layout type."); } From 6b1764f7718f16683164ec53549a19744edd4965 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sun, 17 May 2015 12:11:56 +0200 Subject: [PATCH 382/467] PSR2 Fixes --- Classes/PHPExcel/Reader/Excel2007.php | 99 ++++----- Classes/PHPExcel/Reader/Excel5/Escher.php | 111 ++++++---- Classes/PHPExcel/Reader/Excel5/MD5.php | 16 +- Classes/PHPExcel/Reader/Excel5/RC4.php | 6 +- Classes/PHPExcel/Reader/SYLK.php | 254 ++++++++++++---------- Classes/PHPExcel/ReferenceHelper.php | 2 +- 6 files changed, 274 insertions(+), 214 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index f59d310a7..caf6c28e6 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -209,7 +209,7 @@ public function listWorksheetInfo($pFilename) $xml = new XMLReader(); $res = $xml->xml($this->securityScanFile('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet"), null, PHPExcel_Settings::getLibXmlLoaderOptions()); - $xml->setParserProperty(2,true); + $xml->setParserProperty(2, true); $currCells = 0; while ($xml->read()) { @@ -265,7 +265,7 @@ private static function _castToString($c) return isset($c->v) ? (string) $c->v : null; } // function _castToString() - private function _castToFormula($c, $r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas, $castBaseType) + private function _castToFormula($c, $r, &$cellDataType, &$value, &$calculatedValue, &$sharedFormulas, $castBaseType) { // echo 'Formula', PHP_EOL; // echo '$c->f is ', $c->f, PHP_EOL; @@ -470,13 +470,13 @@ public function load($pFilename) $macros = $customUI = null; foreach ($relsWorkbook->Relationship as $ele) { switch ($ele['Type']) { - case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": - $worksheets[(string) $ele["Id"]] = $ele["Target"]; - break; - // a vbaProject ? (: some macros) - case "http://schemas.microsoft.com/office/2006/relationships/vbaProject": - $macros = $ele["Target"]; - break; + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": + $worksheets[(string) $ele["Id"]] = $ele["Target"]; + break; + // a vbaProject ? (: some macros) + case "http://schemas.microsoft.com/office/2006/relationships/vbaProject": + $macros = $ele["Target"]; + break; } } @@ -639,7 +639,7 @@ public function load($pFilename) // references in formula cells... during the load, all formulae should be correct, // and we're simply bringing the worksheet name in line with the formula, not the // reverse - $docSheet->setTitle((string) $eleSheet["name"],false); + $docSheet->setTitle((string) $eleSheet["name"], false); $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; $xmlSheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$fileWorksheet")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); @@ -886,9 +886,13 @@ public function load($pFilename) // Check for numeric values if (is_numeric($value) && $cellDataType != 's') { - if ($value == (int)$value) $value = (int)$value; - elseif ($value == (float)$value) $value = (float)$value; - elseif ($value == (double)$value) $value = (double)$value; + if ($value == (int)$value) { + $value = (int)$value; + } elseif ($value == (float)$value) { + $value = (float)$value; + } elseif ($value == (double)$value) { + $value = (double)$value; + } } // Rich text? @@ -921,14 +925,7 @@ public function load($pFilename) if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) { foreach ($xmlSheet->conditionalFormatting as $conditional) { foreach ($conditional->cfRule as $cfRule) { - if ( - ( - (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_NONE || - (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CELLIS || - (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT || - (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_EXPRESSION - ) && isset($dxfs[intval($cfRule["dxfId"])]) - ) { + if (((string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_NONE || (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CELLIS || (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT || (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) && isset($dxfs[intval($cfRule["dxfId"])])) { $conditionals[(string) $conditional["sqref"]][intval($cfRule["priority"])] = $cfRule; } } @@ -996,7 +993,7 @@ public function load($pFilename) $filters = $filterColumn->filters; if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { $column->createRule()->setRule( - null, // Operator is undefined, but always treated as EQUAL + null,// Operator is undefined, but always treated as EQUAL '' ) ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); @@ -1005,7 +1002,7 @@ public function load($pFilename) // Entries can be either filter elements foreach ($filters->filter as $filterRule) { $column->createRule()->setRule( - null, // Operator is undefined, but always treated as EQUAL + null,// Operator is undefined, but always treated as EQUAL (string) $filterRule["val"] ) ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); @@ -1013,7 +1010,7 @@ public function load($pFilename) // Or Date Group elements foreach ($filters->dateGroupItem as $dateGroupItem) { $column->createRule()->setRule( - null, // Operator is undefined, but always treated as EQUAL + null,// Operator is undefined, but always treated as EQUAL array( 'year' => (string) $dateGroupItem["year"], 'month' => (string) $dateGroupItem["month"], @@ -1050,16 +1047,16 @@ public function load($pFilename) // We should only ever have one dynamic filter foreach ($filterColumn->dynamicFilter as $filterRule) { $column->createRule()->setRule( - null, // Operator is undefined, but always treated as EQUAL + null,// Operator is undefined, but always treated as EQUAL (string) $filterRule["val"], (string) $filterRule["type"] ) ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER); if (isset($filterRule["val"])) { - $column->setAttribute('val',(string) $filterRule["val"]); + $column->setAttribute('val', (string) $filterRule["val"]); } if (isset($filterRule["maxVal"])) { - $column->setAttribute('maxVal',(string) $filterRule["maxVal"]); + $column->setAttribute('maxVal', (string) $filterRule["maxVal"]); } } } @@ -1216,7 +1213,7 @@ public function load($pFilename) if (!$this->_readDataOnly) { // Locate hyperlink relations if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") { $hyperlinks[(string)$ele["Id"]] = (string)$ele["Target"]; @@ -1257,7 +1254,7 @@ public function load($pFilename) if (!$this->_readDataOnly) { // Locate comment relations if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") { $comments[(string)$ele["Id"]] = (string)$ele["Target"]; @@ -1284,8 +1281,9 @@ public function load($pFilename) // Loop through contents foreach ($commentsFile->commentList->comment as $comment) { - if (!empty($comment['authorId'])) + if (!empty($comment['authorId'])) { $docSheet->getComment((string)$comment['ref'])->setAuthor($authors[(string)$comment['authorId']]); + } $docSheet->getComment((string)$comment['ref'])->setText($this->_parseRichText($comment->text)); } } @@ -1358,7 +1356,7 @@ public function load($pFilename) // Header/footer images if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) { if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $vmlRelationship = ''; foreach ($relsWorksheet->Relationship as $ele) { @@ -1369,7 +1367,7 @@ public function load($pFilename) if ($vmlRelationship != '') { // Fetch linked images - $relsVML = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsVML = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $drawings = array(); foreach ($relsVML->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { @@ -1417,7 +1415,7 @@ public function load($pFilename) // TODO: Autoshapes from twoCellAnchors! if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $drawings = array(); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing") { @@ -1427,7 +1425,7 @@ public function load($pFilename) if ($xmlSheet->drawing && !$this->_readDataOnly) { foreach ($xmlSheet->drawing as $drawing) { $fileDrawing = $drawings[(string) self::array_item($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; - $relsDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $images = array(); if ($relsDrawing && $relsDrawing->Relationship) { @@ -1481,8 +1479,8 @@ public function load($pFilename) $coordinates = PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1); $offsetX = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff); $offsetY = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff); - $width = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx")); - $height = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy")); + $width = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx")); + $height = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy")); } } } @@ -1518,15 +1516,15 @@ public function load($pFilename) } $objDrawing->setWorksheet($docSheet); } elseif (($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { - $fromCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1); + $fromCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1); $fromOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff); $fromOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff); - $toCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->to->col) . ($twoCellAnchor->to->row + 1); - $toOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->colOff); - $toOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->rowOff); + $toCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->to->col) . ($twoCellAnchor->to->row + 1); + $toOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->colOff); + $toOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->rowOff); $graphic = $twoCellAnchor->graphicFrame->children("http://schemas.openxmlformats.org/drawingml/2006/main")->graphic; - $chartRef = $graphic->graphicData->children("http://schemas.openxmlformats.org/drawingml/2006/chart")->chart; - $thisChart = (string) $chartRef->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + $chartRef = $graphic->graphicData->children("http://schemas.openxmlformats.org/drawingml/2006/chart")->chart; + $thisChart = (string) $chartRef->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"); $chartDetails[$docSheet->getTitle().'!'.$thisChart] = array( 'fromCoordinate' => $fromCoordinate, @@ -1551,7 +1549,7 @@ public function load($pFilename) $extractedRange = (string)$definedName; $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); if (($spos = strpos($extractedRange, '!')) !== false) { - $extractedRange = substr($extractedRange,0, $spos).str_replace('$', '', substr($extractedRange, $spos)); + $extractedRange = substr($extractedRange, 0, $spos).str_replace('$', '', substr($extractedRange, $spos)); } else { $extractedRange = str_replace('$', '', $extractedRange); } @@ -1588,9 +1586,8 @@ public function load($pFilename) // check for repeating columns, e g. 'A:A' or 'A:D' if (preg_match('/!?([A-Z]+)\:([A-Z]+)$/', $range, $matches)) { $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($matches[1], $matches[2])); - } - // check for repeating rows, e.g. '1:1' or '1:5' - elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) { + } elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) { + // check for repeating rows, e.g. '1:1' or '1:5' $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($matches[1], $matches[2])); } } @@ -1627,7 +1624,7 @@ public function load($pFilename) $extractedRange = (string)$definedName; $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); if (($spos = strpos($extractedRange, '!')) !== false) { - $extractedRange = substr($extractedRange,0, $spos).str_replace('$', '', substr($extractedRange, $spos)); + $extractedRange = substr($extractedRange, 0, $spos).str_replace('$', '', substr($extractedRange, $spos)); } else { $extractedRange = str_replace('$', '', $extractedRange); } @@ -1700,7 +1697,7 @@ public function load($pFilename) $excel->setActiveSheetIndex(0); } } - break; + break; } } @@ -1712,7 +1709,7 @@ public function load($pFilename) if ($this->_includeCharts) { $chartEntryRef = ltrim($contentType['PartName'], '/'); $chartElements = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $chartEntryRef)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); - $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef, '.xml')); + $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements, basename($chartEntryRef, '.xml')); // echo 'Chart ', $chartEntryRef, '<br />'; // var_dump($charts[$chartEntryRef]); @@ -1820,12 +1817,12 @@ private static function _readStyle($docStyle, $style) $patternType = (string)$style->fill->patternFill["patternType"] != '' ? (string)$style->fill->patternFill["patternType"] : 'solid'; $docStyle->getFill()->setFillType($patternType); if ($style->fill->patternFill->fgColor) { - $docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor,true)); + $docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor, true)); } else { $docStyle->getFill()->getStartColor()->setARGB('FF000000'); } if ($style->fill->patternFill->bgColor) { - $docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor,true)); + $docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor, true)); } } } diff --git a/Classes/PHPExcel/Reader/Excel5/Escher.php b/Classes/PHPExcel/Reader/Excel5/Escher.php index 9b2338c28..3fd949a08 100644 --- a/Classes/PHPExcel/Reader/Excel5/Escher.php +++ b/Classes/PHPExcel/Reader/Excel5/Escher.php @@ -34,24 +34,24 @@ */ class PHPExcel_Reader_Excel5_Escher { - const DGGCONTAINER = 0xF000; - const BSTORECONTAINER = 0xF001; - const DGCONTAINER = 0xF002; - const SPGRCONTAINER = 0xF003; - const SPCONTAINER = 0xF004; - const DGG = 0xF006; - const BSE = 0xF007; + const DGGCONTAINER = 0xF000; + const BSTORECONTAINER = 0xF001; + const DGCONTAINER = 0xF002; + const SPGRCONTAINER = 0xF003; + const SPCONTAINER = 0xF004; + const DGG = 0xF006; + const BSE = 0xF007; const DG = 0xF008; - const SPGR = 0xF009; + const SPGR = 0xF009; const SP = 0xF00A; - const OPT = 0xF00B; - const CLIENTTEXTBOX = 0xF00D; - const CLIENTANCHOR = 0xF010; + const OPT = 0xF00B; + const CLIENTTEXTBOX = 0xF00D; + const CLIENTANCHOR = 0xF010; const CLIENTDATA = 0xF011; - const BLIPJPEG = 0xF01D; - const BLIPPNG = 0xF01E; - const SPLITMENUCOLORS = 0xF11E; - const TERTIARYOPT = 0xF122; + const BLIPJPEG = 0xF01D; + const BLIPPNG = 0xF01E; + const SPLITMENUCOLORS = 0xF11E; + const TERTIARYOPT = 0xF122; /** * Escher stream data (binary) @@ -112,25 +112,63 @@ public function load($data) $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); switch ($fbt) { - case self::DGGCONTAINER: $this->_readDggContainer(); break; - case self::DGG: $this->_readDgg(); break; - case self::BSTORECONTAINER: $this->_readBstoreContainer(); break; - case self::BSE: $this->_readBSE(); break; - case self::BLIPJPEG: $this->_readBlipJPEG(); break; - case self::BLIPPNG: $this->_readBlipPNG(); break; - case self::OPT: $this->_readOPT(); break; - case self::TERTIARYOPT: $this->_readTertiaryOPT(); break; - case self::SPLITMENUCOLORS: $this->_readSplitMenuColors(); break; - case self::DGCONTAINER: $this->_readDgContainer(); break; - case self::DG: $this->_readDg(); break; - case self::SPGRCONTAINER: $this->_readSpgrContainer(); break; - case self::SPCONTAINER: $this->_readSpContainer(); break; - case self::SPGR: $this->_readSpgr(); break; - case self::SP: $this->_readSp(); break; - case self::CLIENTTEXTBOX: $this->_readClientTextbox(); break; - case self::CLIENTANCHOR: $this->_readClientAnchor(); break; - case self::CLIENTDATA: $this->_readClientData(); break; - default: $this->_readDefault(); break; + case self::DGGCONTAINER: + $this->_readDggContainer(); + break; + case self::DGG: + $this->_readDgg(); + break; + case self::BSTORECONTAINER: + $this->_readBstoreContainer(); + break; + case self::BSE: + $this->_readBSE(); + break; + case self::BLIPJPEG: + $this->_readBlipJPEG(); + break; + case self::BLIPPNG: + $this->_readBlipPNG(); + break; + case self::OPT: + $this->_readOPT(); + break; + case self::TERTIARYOPT: + $this->_readTertiaryOPT(); + break; + case self::SPLITMENUCOLORS: + $this->_readSplitMenuColors(); + break; + case self::DGCONTAINER: + $this->_readDgContainer(); + break; + case self::DG: + $this->_readDg(); + break; + case self::SPGRCONTAINER: + $this->_readSpgrContainer(); + break; + case self::SPCONTAINER: + $this->_readSpContainer(); + break; + case self::SPGR: + $this->_readSpgr(); + break; + case self::SP: + $this->_readSp(); + break; + case self::CLIENTTEXTBOX: + $this->_readClientTextbox(); + break; + case self::CLIENTANCHOR: + $this->_readClientAnchor(); + break; + case self::CLIENTDATA: + $this->_readClientData(); + break; + default: + $this->_readDefault(); + break; } } @@ -598,8 +636,8 @@ private function _readClientData() * @param string $data Binary data * @param int $n Number of properties */ - private function _readOfficeArtRGFOPTE($data, $n) { - + private function _readOfficeArtRGFOPTE($data, $n) + { $splicedComplexData = substr($data, 6 * $n); // loop through property-value pairs @@ -636,5 +674,4 @@ private function _readOfficeArtRGFOPTE($data, $n) { $this->_object->setOPT($opidOpid, $value); } } - } diff --git a/Classes/PHPExcel/Reader/Excel5/MD5.php b/Classes/PHPExcel/Reader/Excel5/MD5.php index 1c9ede02b..3570c52ee 100644 --- a/Classes/PHPExcel/Reader/Excel5/MD5.php +++ b/Classes/PHPExcel/Reader/Excel5/MD5.php @@ -41,7 +41,6 @@ class PHPExcel_Reader_Excel5_MD5 private $c; private $d; - /** * MD5 stream constructor */ @@ -50,7 +49,6 @@ public function __construct() $this->reset(); } - /** * Reset the MD5 stream context */ @@ -62,10 +60,9 @@ public function reset() $this->d = 0x10325476; } - /** * Get MD5 stream context - * + * * @return string */ public function getContext() @@ -82,10 +79,9 @@ public function getContext() return $s; } - /** * Add data to context - * + * * @param string $data Data to add */ public function add($data) @@ -180,31 +176,26 @@ public function add($data) $this->d = ($this->d + $D) & 0xffffffff; } - private static function F($X, $Y, $Z) { return (($X & $Y) | ((~ $X) & $Z)); // X AND Y OR NOT X AND Z } - private static function G($X, $Y, $Z) { return (($X & $Z) | ($Y & (~ $Z))); // X AND Z OR Y AND NOT Z } - private static function H($X, $Y, $Z) { return ($X ^ $Y ^ $Z); // X XOR Y XOR Z } - private static function I($X, $Y, $Z) { return ($Y ^ ($X | (~ $Z))) ; // Y XOR (X OR NOT Z) } - private static function step($func, &$A, $B, $C, $D, $M, $s, $t) { $A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & 0xffffffff; @@ -212,10 +203,9 @@ private static function step($func, &$A, $B, $C, $D, $M, $s, $t) $A = ($B + $A) & 0xffffffff; } - private static function rotate($decimal, $bits) { $binary = str_pad(decbin($decimal), 32, "0", STR_PAD_LEFT); return bindec(substr($binary, $bits).substr($binary, 0, $bits)); } -} \ No newline at end of file +} diff --git a/Classes/PHPExcel/Reader/Excel5/RC4.php b/Classes/PHPExcel/Reader/Excel5/RC4.php index 9130b45a4..394a00aa7 100644 --- a/Classes/PHPExcel/Reader/Excel5/RC4.php +++ b/Classes/PHPExcel/Reader/Excel5/RC4.php @@ -41,7 +41,7 @@ class PHPExcel_Reader_Excel5_RC4 /** * RC4 stream decryption/encryption constrcutor - * + * * @param string $key Encryption key/passphrase */ public function __construct($key) @@ -64,9 +64,9 @@ public function __construct($key) /** * Symmetric decryption/encryption function - * + * * @param string $data Data to encrypt/decrypt - * + * * @return string */ public function RC4($data) diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index 85569d9a3..de712d639 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -92,16 +92,16 @@ protected function _isValidFormat() // Count delimiters in file $delimiterCount = substr_count($data, ';'); if ($delimiterCount < 1) { - return FALSE; + return false; } // Analyze first line looking for ID; signature $lines = explode("\n", $data); if (substr($lines[0],0,4) != 'ID;P') { - return FALSE; + return false; } - return TRUE; + return true; } /** @@ -154,7 +154,7 @@ public function listWorksheetInfo($pFilename) // loop through one row (line) at a time in the file $rowIndex = 0; - while (($rowData = fgets($fileHandle)) !== FALSE) { + while (($rowData = fgets($fileHandle)) !== false) { $columnIndex = 0; // convert SYLK encoded $rowData to UTF-8 @@ -243,7 +243,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $column = $row = ''; // loop through one row (line) at a time in the file - while (($rowData = fgets($fileHandle)) !== FALSE) { + while (($rowData = fgets($fileHandle)) !== false) { // convert SYLK encoded $rowData to UTF-8 $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData); @@ -258,31 +258,41 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $formatArray = array(); foreach ($rowData as $rowDatum) { switch ($rowDatum{0}) { - case 'P' : $formatArray['numberformat']['code'] = str_replace($fromFormats, $toFormats,substr($rowDatum,1)); - break; - case 'E' : - case 'F' : $formatArray['font']['name'] = substr($rowDatum,1); - break; - case 'L' : $formatArray['font']['size'] = substr($rowDatum,1); - break; - case 'S' : $styleSettings = substr($rowDatum,1); - for ($i=0;$i<strlen($styleSettings);++$i) { - switch ($styleSettings{$i}) { - case 'I' : $formatArray['font']['italic'] = true; - break; - case 'D' : $formatArray['font']['bold'] = true; - break; - case 'T' : $formatArray['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'B' : $formatArray['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'L' : $formatArray['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'R' : $formatArray['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - } - } - break; + case 'P': + $formatArray['numberformat']['code'] = str_replace($fromFormats, $toFormats, substr($rowDatum, 1)); + break; + case 'E': + case 'F': + $formatArray['font']['name'] = substr($rowDatum, 1); + break; + case 'L': + $formatArray['font']['size'] = substr($rowDatum, 1); + break; + case 'S': + $styleSettings = substr($rowDatum,1); + for ($i=0;$i<strlen($styleSettings);++$i) { + switch ($styleSettings{$i}) { + case 'I': + $formatArray['font']['italic'] = true; + break; + case 'D': + $formatArray['font']['bold'] = true; + break; + case 'T': + $formatArray['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'B': + $formatArray['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'L': + $formatArray['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'R': + $formatArray['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + } + } + break; } } $this->_formats['P'.$this->_format++] = $formatArray; @@ -292,50 +302,62 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $cellData = $cellDataFormula = ''; foreach ($rowData as $rowDatum) { switch ($rowDatum{0}) { - case 'C' : - case 'X' : $column = substr($rowDatum,1); - break; - case 'R' : - case 'Y' : $row = substr($rowDatum,1); - break; - case 'K' : $cellData = substr($rowDatum,1); - break; - case 'E' : $cellDataFormula = '='.substr($rowDatum,1); - // Convert R1C1 style references to A1 style references (but only when not quoted) - $temp = explode('"', $cellDataFormula); - $key = false; - foreach ($temp as &$value) { - // Only count/replace in alternate array entries - if ($key = !$key) { - preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); - // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way - // through the formula from left to right. Reversing means that we work right to left.through - // the formula - $cellReferences = array_reverse($cellReferences); - // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, - // then modify the formula to use that new reference - foreach ($cellReferences as $cellReference) { - $rowReference = $cellReference[2][0]; - // Empty R reference is the current row - if ($rowReference == '') $rowReference = $row; - // Bracketed R references are relative to the current row - if ($rowReference{0} == '[') $rowReference = $row + trim($rowReference,'[]'); - $columnReference = $cellReference[4][0]; - // Empty C reference is the current column - if ($columnReference == '') $columnReference = $column; - // Bracketed C references are relative to the current column - if ($columnReference{0} == '[') $columnReference = $column + trim($columnReference,'[]'); - $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; - - $value = substr_replace($value, $A1CellReference, $cellReference[0][1],strlen($cellReference[0][0])); - } + case 'C': + case 'X': + $column = substr($rowDatum, 1); + break; + case 'R': + case 'Y': + $row = substr($rowDatum, 1); + break; + case 'K': + $cellData = substr($rowDatum, 1); + break; + case 'E': + $cellDataFormula = '='.substr($rowDatum, 1); + // Convert R1C1 style references to A1 style references (but only when not quoted) + $temp = explode('"', $cellDataFormula); + $key = false; + foreach ($temp as &$value) { + // Only count/replace in alternate array entries + if ($key = !$key) { + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way + // through the formula from left to right. Reversing means that we work right to left.through + // the formula + $cellReferences = array_reverse($cellReferences); + // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, + // then modify the formula to use that new reference + foreach ($cellReferences as $cellReference) { + $rowReference = $cellReference[2][0]; + // Empty R reference is the current row + if ($rowReference == '') { + $rowReference = $row; + } + // Bracketed R references are relative to the current row + if ($rowReference{0} == '[') { + $rowReference = $row + trim($rowReference, '[]'); + } + $columnReference = $cellReference[4][0]; + // Empty C reference is the current column + if ($columnReference == '') { + $columnReference = $column; } + // Bracketed C references are relative to the current column + if ($columnReference{0} == '[') { + $columnReference = $column + trim($columnReference,'[]'); + } + $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; + + $value = substr_replace($value, $A1CellReference, $cellReference[0][1], strlen($cellReference[0][0])); } - unset($value); - // Then rebuild the formula string - $cellDataFormula = implode('"', $temp); - $hasCalculatedValue = true; - break; + } + } + unset($value); + // Then rebuild the formula string + $cellDataFormula = implode('"', $temp); + $hasCalculatedValue = true; + break; } } $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); @@ -353,34 +375,45 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $styleData = array(); foreach ($rowData as $rowDatum) { switch ($rowDatum{0}) { - case 'C' : - case 'X' : $column = substr($rowDatum,1); - break; - case 'R' : - case 'Y' : $row = substr($rowDatum,1); - break; - case 'P' : $formatStyle = $rowDatum; - break; - case 'W' : list($startCol, $endCol, $columnWidth) = explode(' ',substr($rowDatum,1)); - break; - case 'S' : $styleSettings = substr($rowDatum,1); - for ($i=0;$i<strlen($styleSettings);++$i) { - switch ($styleSettings{$i}) { - case 'I' : $styleData['font']['italic'] = true; - break; - case 'D' : $styleData['font']['bold'] = true; - break; - case 'T' : $styleData['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'B' : $styleData['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'L' : $styleData['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - case 'R' : $styleData['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; - break; - } - } - break; + case 'C': + case 'X': + $column = substr($rowDatum, 1); + break; + case 'R': + case 'Y': + $row = substr($rowDatum, 1); + break; + case 'P': + $formatStyle = $rowDatum; + break; + case 'W': + list($startCol, $endCol, $columnWidth) = explode(' ', substr($rowDatum, 1)); + break; + case 'S': + $styleSettings = substr($rowDatum,1); + for ($i=0;$i<strlen($styleSettings);++$i) { + switch ($styleSettings{$i}) { + case 'I': + $styleData['font']['italic'] = true; + break; + case 'D': + $styleData['font']['bold'] = true; + break; + case 'T': + $styleData['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'B': + $styleData['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'L': + $styleData['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'R': + $styleData['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + } + } + break; } } if (($formatStyle > '') && ($column > '') && ($row > '')) { @@ -409,12 +442,14 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } else { foreach ($rowData as $rowDatum) { switch ($rowDatum{0}) { - case 'C' : - case 'X' : $column = substr($rowDatum,1); - break; - case 'R' : - case 'Y' : $row = substr($rowDatum,1); - break; + case 'C': + case 'X': + $column = substr($rowDatum,1); + break; + case 'R': + case 'Y': + $row = substr($rowDatum,1); + break; } } } @@ -432,7 +467,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) * * @return int */ - public function getSheetIndex() { + public function getSheetIndex() + { return $this->_sheetIndex; } @@ -442,9 +478,9 @@ public function getSheetIndex() { * @param int $pValue Sheet index * @return PHPExcel_Reader_SYLK */ - public function setSheetIndex($pValue = 0) { + public function setSheetIndex($pValue = 0) + { $this->_sheetIndex = $pValue; return $this; } - } diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 1442425ef..2964131a3 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -662,7 +662,7 @@ public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCo $toString .= $modified3.':'.$modified4; // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more $column = 100000; - $row = 10000000 + trim($match[3],'$'); + $row = 10000000 + trim($match[3], '$'); $cellIndex = $column.$row; $newCellTokens[$cellIndex] = preg_quote($toString); From 1d842ed2188adc5c332b2db3ae7c20211399c459 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sun, 17 May 2015 14:16:53 +0200 Subject: [PATCH 383/467] PSR2 Fixes --- Classes/PHPExcel/Reader/Excel2003XML.php | 1 - Classes/PHPExcel/Reader/Excel2007.php | 7 +- Classes/PHPExcel/Reader/Excel2007/Chart.php | 293 +++++---- Classes/PHPExcel/Reader/Excel2007/Theme.php | 13 +- Classes/PHPExcel/Reader/Excel5.php | 208 +++--- Classes/PHPExcel/Reader/Excel5/Escher.php | 1 - Classes/PHPExcel/Reader/Gnumeric.php | 329 +++++---- Classes/PHPExcel/Reader/OOCalc.php | 245 ++++--- Classes/PHPExcel/Reader/SYLK.php | 44 +- .../Shared/JAMA/CholeskyDecomposition.php | 29 +- .../Shared/JAMA/EigenvalueDecomposition.php | 60 +- .../PHPExcel/Shared/JAMA/LUDecomposition.php | 39 +- Classes/PHPExcel/Shared/JAMA/Matrix.php | 622 ++++++++++-------- .../PHPExcel/Shared/JAMA/QRDecomposition.php | 28 +- .../JAMA/SingularValueDecomposition.php | 280 ++++---- Classes/PHPExcel/Shared/JAMA/utils/Error.php | 3 +- Classes/PHPExcel/Shared/JAMA/utils/Maths.php | 3 +- Classes/PHPExcel/Shared/OLE/PPS/Root.php | 63 +- Classes/PHPExcel/Shared/OLERead.php | 3 +- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 101 +-- 20 files changed, 1193 insertions(+), 1179 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index 29720aa9d..c5360cfbd 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -58,7 +58,6 @@ class PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements P */ protected $_charSet = 'UTF-8'; - /** * Create a new PHPExcel_Reader_Excel2003XML */ diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index caf6c28e6..6c1ded0d3 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -992,11 +992,8 @@ public function load($pFilename) $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER); $filters = $filterColumn->filters; if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { - $column->createRule()->setRule( - null,// Operator is undefined, but always treated as EQUAL - '' - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + // Operator is undefined, but always treated as EQUAL + $column->createRule()->setRule(null, '')->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); } // Standard filters are always an OR join, so no join rule needs to be set // Entries can be either filter elements diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index 80ac44700..222c54667 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Chart.php +++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php @@ -34,7 +34,8 @@ */ class PHPExcel_Reader_Excel2007_Chart { - private static function _getAttribute($component, $name, $format) { + private static function _getAttribute($component, $name, $format) + { $attributes = $component->attributes(); if (isset($attributes[$name])) { if ($format == 'string') { @@ -51,7 +52,8 @@ private static function _getAttribute($component, $name, $format) { } // function _getAttribute() - private static function _readColor($color, $background=false) { + private static function _readColor($color, $background = false) + { if (isset($color["rgb"])) { return (string)$color["rgb"]; } else if (isset($color["indexed"])) { @@ -59,13 +61,13 @@ private static function _readColor($color, $background=false) { } } - - public static function readChart($chartElements, $chartName) { + public static function readChart($chartElements, $chartName) + { $namespacesChartMeta = $chartElements->getNamespaces(true); $chartElementsC = $chartElements->children($namespacesChartMeta['c']); - $XaxisLabel = $YaxisLabel = $legend = $title = NULL; - $dispBlanksAs = $plotVisOnly = NULL; + $XaxisLabel = $YaxisLabel = $legend = $title = null; + $dispBlanksAs = $plotVisOnly = null; foreach ($chartElementsC as $chartElementKey => $chartElement) { switch ($chartElementKey) { @@ -74,124 +76,124 @@ public static function readChart($chartElements, $chartName) { $chartDetailsC = $chartDetails->children($namespacesChartMeta['c']); switch ($chartDetailsKey) { case "plotArea": - $plotAreaLayout = $XaxisLable = $YaxisLable = null; - $plotSeries = $plotAttributes = array(); - foreach ($chartDetails as $chartDetailKey => $chartDetail) { - switch ($chartDetailKey) { - case "layout": - $plotAreaLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta,'plotArea'); - break; - case "catAx": - if (isset($chartDetail->title)) { - $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); - } - break; - case "dateAx": - if (isset($chartDetail->title)) { - $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); - } - break; - case "valAx": - if (isset($chartDetail->title)) { - $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); - } - break; - case "barChart": - case "bar3DChart": - $barDirection = self::_getAttribute($chartDetail->barDir, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotSer->setPlotDirection($barDirection); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "lineChart": - case "line3DChart": - $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "areaChart": - case "area3DChart": - $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "doughnutChart": - case "pieChart": - case "pie3DChart": - $explosion = isset($chartDetail->ser->explosion); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotSer->setPlotStyle($explosion); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "scatterChart": - $scatterStyle = self::_getAttribute($chartDetail->scatterStyle, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotSer->setPlotStyle($scatterStyle); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "bubbleChart": - $bubbleScale = self::_getAttribute($chartDetail->bubbleScale, 'val', 'integer'); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotSer->setPlotStyle($bubbleScale); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "radarChart": - $radarStyle = self::_getAttribute($chartDetail->radarStyle, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotSer->setPlotStyle($radarStyle); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "surfaceChart": - case "surface3DChart": - $wireFrame = self::_getAttribute($chartDetail->wireframe, 'val', 'boolean'); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotSer->setPlotStyle($wireFrame); - $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); - break; - case "stockChart": - $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotAttributes = self::_readChartAttributes($plotAreaLayout); - break; - } + $plotAreaLayout = $XaxisLable = $YaxisLable = null; + $plotSeries = $plotAttributes = array(); + foreach ($chartDetails as $chartDetailKey => $chartDetail) { + switch ($chartDetailKey) { + case "layout": + $plotAreaLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta,'plotArea'); + break; + case "catAx": + if (isset($chartDetail->title)) { + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); + } + break; + case "dateAx": + if (isset($chartDetail->title)) { + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); + } + break; + case "valAx": + if (isset($chartDetail->title)) { + $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); + } + break; + case "barChart": + case "bar3DChart": + $barDirection = self::_getAttribute($chartDetail->barDir, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotSer->setPlotDirection($barDirection); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "lineChart": + case "line3DChart": + $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "areaChart": + case "area3DChart": + $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "doughnutChart": + case "pieChart": + case "pie3DChart": + $explosion = isset($chartDetail->ser->explosion); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotSer->setPlotStyle($explosion); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "scatterChart": + $scatterStyle = self::_getAttribute($chartDetail->scatterStyle, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotSer->setPlotStyle($scatterStyle); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "bubbleChart": + $bubbleScale = self::_getAttribute($chartDetail->bubbleScale, 'val', 'integer'); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotSer->setPlotStyle($bubbleScale); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "radarChart": + $radarStyle = self::_getAttribute($chartDetail->radarStyle, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotSer->setPlotStyle($radarStyle); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "surfaceChart": + case "surface3DChart": + $wireFrame = self::_getAttribute($chartDetail->wireframe, 'val', 'boolean'); + $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotSer->setPlotStyle($wireFrame); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "stockChart": + $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotAttributes = self::_readChartAttributes($plotAreaLayout); + break; } - if ($plotAreaLayout == NULL) { - $plotAreaLayout = new PHPExcel_Chart_Layout(); - } - $plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout, $plotSeries); - self::_setChartAttributes($plotAreaLayout, $plotAttributes); - break; + } + if ($plotAreaLayout == null) { + $plotAreaLayout = new PHPExcel_Chart_Layout(); + } + $plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout, $plotSeries); + self::_setChartAttributes($plotAreaLayout, $plotAttributes); + break; case "plotVisOnly": - $plotVisOnly = self::_getAttribute($chartDetails, 'val', 'string'); - break; + $plotVisOnly = self::_getAttribute($chartDetails, 'val', 'string'); + break; case "dispBlanksAs": - $dispBlanksAs = self::_getAttribute($chartDetails, 'val', 'string'); - break; + $dispBlanksAs = self::_getAttribute($chartDetails, 'val', 'string'); + break; case "title": - $title = self::_chartTitle($chartDetails, $namespacesChartMeta,'title'); - break; + $title = self::_chartTitle($chartDetails, $namespacesChartMeta,'title'); + break; case "legend": - $legendPos = 'r'; - $legendLayout = null; - $legendOverlay = false; - foreach ($chartDetails as $chartDetailKey => $chartDetail) { - switch ($chartDetailKey) { - case "legendPos": - $legendPos = self::_getAttribute($chartDetail, 'val', 'string'); - break; - case "overlay": - $legendOverlay = self::_getAttribute($chartDetail, 'val', 'boolean'); - break; - case "layout": - $legendLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta,'legend'); - break; - } + $legendPos = 'r'; + $legendLayout = null; + $legendOverlay = false; + foreach ($chartDetails as $chartDetailKey => $chartDetail) { + switch ($chartDetailKey) { + case "legendPos": + $legendPos = self::_getAttribute($chartDetail, 'val', 'string'); + break; + case "overlay": + $legendOverlay = self::_getAttribute($chartDetail, 'val', 'boolean'); + break; + case "layout": + $legendLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta,'legend'); + break; } - $legend = new PHPExcel_Chart_Legend($legendPos, $legendLayout, $legendOverlay); - break; + } + $legend = new PHPExcel_Chart_Legend($legendPos, $legendLayout, $legendOverlay); + break; } } } @@ -201,8 +203,8 @@ public static function readChart($chartElements, $chartName) { return $chart; } // function readChart() - - private static function _chartTitle($titleDetails, $namespacesChartMeta, $type) { + private static function _chartTitle($titleDetails, $namespacesChartMeta, $type) + { $caption = array(); $titleLayout = null; foreach ($titleDetails as $titleDetailKey => $chartDetail) { @@ -226,8 +228,8 @@ private static function _chartTitle($titleDetails, $namespacesChartMeta, $type) return new PHPExcel_Chart_Title($caption, $titleLayout); } // function _chartTitle() - - private static function _chartLayoutDetails($chartDetail, $namespacesChartMeta) { + private static function _chartLayoutDetails($chartDetail, $namespacesChartMeta) + { if (!isset($chartDetail->manualLayout)) { return null; } @@ -243,9 +245,9 @@ private static function _chartLayoutDetails($chartDetail, $namespacesChartMeta) return new PHPExcel_Chart_Layout($layout); } // function _chartLayoutDetails() - - private static function _chartDataSeries($chartDetail, $namespacesChartMeta, $plotType) { - $multiSeriesType = NULL; + private static function _chartDataSeries($chartDetail, $namespacesChartMeta, $plotType) + { + $multiSeriesType = null; $smoothLine = false; $seriesLabel = $seriesCategory = $seriesValues = $plotOrder = array(); @@ -256,7 +258,7 @@ private static function _chartDataSeries($chartDetail, $namespacesChartMeta, $pl $multiSeriesType = self::_getAttribute($chartDetail->grouping, 'val', 'string'); break; case "ser": - $marker = NULL; + $marker = null; foreach ($seriesDetails as $seriesKey => $seriesDetail) { switch ($seriesKey) { case "idx": @@ -294,8 +296,8 @@ private static function _chartDataSeries($chartDetail, $namespacesChartMeta, $pl return new PHPExcel_Chart_DataSeries($plotType, $multiSeriesType, $plotOrder, $seriesLabel, $seriesCategory, $seriesValues, $smoothLine); } // function _chartDataSeries() - - private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null, $smoothLine = false) { + private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null, $smoothLine = false) + { if (isset($seriesDetail->strRef)) { $seriesSource = (string) $seriesDetail->strRef->f; $seriesData = self::_chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']),'s'); @@ -322,8 +324,8 @@ private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChart return null; } // function _chartDataSeriesValueSet() - - private static function _chartDataSeriesValues($seriesValueSet, $dataType='n') { + private static function _chartDataSeriesValues($seriesValueSet, $dataType = 'n') + { $seriesVal = array(); $formatCode = ''; $pointCount = 0; @@ -348,17 +350,18 @@ private static function _chartDataSeriesValues($seriesValueSet, $dataType='n') { } if (empty($seriesVal)) { - $seriesVal = NULL; + $seriesVal = null; } - return array( 'formatCode' => $formatCode, - 'pointCount' => $pointCount, - 'dataValues' => $seriesVal - ); + return array( + 'formatCode' => $formatCode, + 'pointCount' => $pointCount, + 'dataValues' => $seriesVal + ); } // function _chartDataSeriesValues() - - private static function _chartDataSeriesValuesMultiLevel($seriesValueSet, $dataType='n') { + private static function _chartDataSeriesValuesMultiLevel($seriesValueSet, $dataType = 'n') + { $seriesVal = array(); $formatCode = ''; $pointCount = 0; @@ -384,13 +387,15 @@ private static function _chartDataSeriesValuesMultiLevel($seriesValueSet, $dataT } } - return array( 'formatCode' => $formatCode, - 'pointCount' => $pointCount, - 'dataValues' => $seriesVal - ); + return array( + 'formatCode' => $formatCode, + 'pointCount' => $pointCount, + 'dataValues' => $seriesVal + ); } // function _chartDataSeriesValuesMultiLevel() - private static function _parseRichText($titleDetailPart = null) { + private static function _parseRichText($titleDetailPart = null) + { $value = new PHPExcel_RichText(); foreach ($titleDetailPart as $titleDetailElementKey => $titleDetailElement) { @@ -456,7 +461,8 @@ private static function _parseRichText($titleDetailPart = null) { return $value; } - private static function _readChartAttributes($chartDetail) { + private static function _readChartAttributes($chartDetail) + { $plotAttributes = array(); if (isset($chartDetail->dLbls)) { if (isset($chartDetail->dLbls->howLegendKey)) { @@ -513,5 +519,4 @@ private static function _setChartAttributes($plotArea, $plotAttributes) } } } - } diff --git a/Classes/PHPExcel/Reader/Excel2007/Theme.php b/Classes/PHPExcel/Reader/Excel2007/Theme.php index 2501c8141..d5879ad47 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Theme.php +++ b/Classes/PHPExcel/Reader/Excel2007/Theme.php @@ -72,9 +72,9 @@ class PHPExcel_Reader_Excel2007_Theme public function __construct($themeName, $colourSchemeName, $colourMap) { // Initialise values - $this->_themeName = $themeName; + $this->_themeName = $themeName; $this->_colourSchemeName = $colourSchemeName; - $this->_colourMap = $colourMap; + $this->_colourMap = $colourMap; } /** @@ -92,7 +92,8 @@ public function getThemeName() * * @return string */ - public function getColourSchemeName() { + public function getColourSchemeName() + { return $this->_colourSchemeName; } @@ -101,7 +102,8 @@ public function getColourSchemeName() { * * @return string */ - public function getColourByIndex($index=0) { + public function getColourByIndex($index = 0) + { if (isset($this->_colourMap[$index])) { return $this->_colourMap[$index]; } @@ -111,7 +113,8 @@ public function getColourByIndex($index=0) { /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */ - public function __clone() { + public function __clone() + { $vars = get_object_vars($this); foreach ($vars as $key => $value) { if ((is_object($value)) && ($key != '_parent')) { diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 15fa11b77..8b87bf3d7 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -1113,7 +1113,7 @@ public function load($pFilename) if ($this->_version == self::XLS_BIFF8) { foreach ($this->_sharedFormulaParts as $cell => $baseCell) { list($column, $row) = PHPExcel_Cell::coordinateFromString($cell); - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle()) ) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { $formula = $this->_getFormulaFromStructure($this->_sharedFormulas[$baseCell], $cell); $this->_phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); } @@ -1156,7 +1156,7 @@ public function load($pFilename) $explodes = explode('!', $range); // FIXME: what if sheetname contains exclamation mark? $sheetName = trim($explodes[0], "'"); if (count($explodes) == 2) { - if (strpos($explodes[1], ':') === FALSE) { + if (strpos($explodes[1], ':') === false) { $explodes[1] = $explodes[1] . ':' . $explodes[1]; } $extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66 @@ -1221,7 +1221,7 @@ public function load($pFilename) $scope = ($definedName['scope'] == 0) ? null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']); - $this->_phpExcel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope) ); + $this->_phpExcel->addNamedRange(new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope)); } } else { // Named Value @@ -1624,7 +1624,7 @@ private function _readNote() // $this->_cellNotes[$noteObjID] = array( 'cellRef' => $cellAddress, - 'objectID' => $noteObjID, + 'objectID' => $noteObjID, 'author' => $noteAuthor ); } else { @@ -1647,13 +1647,13 @@ private function _readNote() if ($extension) { // Concatenate this extension with the currently set comment for the cell - $comment = $this->_phpSheet->getComment( $cellAddress ); + $comment = $this->_phpSheet->getComment($cellAddress); $commentText = $comment->getText()->getPlainText(); - $comment->setText($this->_parseRichText($commentText.$noteText) ); + $comment->setText($this->_parseRichText($commentText.$noteText)); } else { // Set comment for the cell $this->_phpSheet->getComment($cellAddress)->setText($this->_parseRichText($noteText)); -// ->setAuthor( $author ) +// ->setAuthor($author) } } @@ -2410,7 +2410,7 @@ private function _readXfExt() $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + if (isset($this->_mapCellXfIndex[$ixfe])) { $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); $fill->getStartColor()->setRGB($rgb); unset($fill->startcolorIndex); // normal color index does not apply, discard @@ -2425,7 +2425,7 @@ private function _readXfExt() $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + if (isset($this->_mapCellXfIndex[$ixfe])) { $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); $fill->getEndColor()->setRGB($rgb); unset($fill->endcolorIndex); // normal color index does not apply, discard @@ -2440,7 +2440,7 @@ private function _readXfExt() $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + if (isset($this->_mapCellXfIndex[$ixfe])) { $top = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getTop(); $top->getColor()->setRGB($rgb); unset($top->colorIndex); // normal color index does not apply, discard @@ -2455,7 +2455,7 @@ private function _readXfExt() $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + if (isset($this->_mapCellXfIndex[$ixfe])) { $bottom = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getBottom(); $bottom->getColor()->setRGB($rgb); unset($bottom->colorIndex); // normal color index does not apply, discard @@ -2470,7 +2470,7 @@ private function _readXfExt() $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + if (isset($this->_mapCellXfIndex[$ixfe])) { $left = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getLeft(); $left->getColor()->setRGB($rgb); unset($left->colorIndex); // normal color index does not apply, discard @@ -2485,7 +2485,7 @@ private function _readXfExt() $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + if (isset($this->_mapCellXfIndex[$ixfe])) { $right = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getRight(); $right->getColor()->setRGB($rgb); unset($right->colorIndex); // normal color index does not apply, discard @@ -2500,7 +2500,7 @@ private function _readXfExt() $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + if (isset($this->_mapCellXfIndex[$ixfe])) { $diagonal = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getDiagonal(); $diagonal->getColor()->setRGB($rgb); unset($diagonal->colorIndex); // normal color index does not apply, discard @@ -2515,7 +2515,7 @@ private function _readXfExt() $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + if (isset($this->_mapCellXfIndex[$ixfe])) { $font = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFont(); $font->getColor()->setRGB($rgb); unset($font->colorIndex); // normal color index does not apply, discard @@ -3652,7 +3652,7 @@ private function _readRk() $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { // offset: 4; size: 2; index to XF record $xfIndex = self::_GetInt2d($recordData, 4); @@ -4125,7 +4125,7 @@ private function _readMulBlank() $columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i); // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { $xfIndex = self::_GetInt2d($recordData, 4 + 2 * $i); $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); } @@ -4162,7 +4162,7 @@ private function _readLabel() $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { // offset: 4; size: 2; XF index $xfIndex = self::_GetInt2d($recordData, 4); @@ -4528,7 +4528,7 @@ private function _readMergedCells() if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData); foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) { - if ((strpos($cellRangeAddress,':') !== FALSE) && + if ((strpos($cellRangeAddress,':') !== false) && ($this->_includeCellRangeFiltered($cellRangeAddress))) { $this->_phpSheet->mergeCells($cellRangeAddress); } @@ -5743,203 +5743,203 @@ private function _getNextToken($formulaData, $baseCell = 'A1') $size = 3; // offset: 1; size: 2; index to built-in sheet function switch (self::_GetInt2d($formulaData, 1)) { - case 2: + case 2: $function = 'ISNA'; $args = 1; break; - case 3: + case 3: $function = 'ISERROR'; $args = 1; break; - case 10: + case 10: $function = 'NA'; $args = 0; break; - case 15: + case 15: $function = 'SIN'; $args = 1; break; - case 16: + case 16: $function = 'COS'; $args = 1; break; - case 17: + case 17: $function = 'TAN'; $args = 1; break; - case 18: + case 18: $function = 'ATAN'; $args = 1; break; - case 19: + case 19: $function = 'PI'; $args = 0; break; - case 20: + case 20: $function = 'SQRT'; $args = 1; break; - case 21: + case 21: $function = 'EXP'; $args = 1; break; - case 22: + case 22: $function = 'LN'; $args = 1; break; - case 23: + case 23: $function = 'LOG10'; $args = 1; break; - case 24: + case 24: $function = 'ABS'; $args = 1; break; - case 25: + case 25: $function = 'INT'; $args = 1; break; - case 26: + case 26: $function = 'SIGN'; $args = 1; break; - case 27: + case 27: $function = 'ROUND'; $args = 2; break; - case 30: + case 30: $function = 'REPT'; $args = 2; break; - case 31: + case 31: $function = 'MID'; $args = 3; break; - case 32: + case 32: $function = 'LEN'; $args = 1; break; - case 33: + case 33: $function = 'VALUE'; $args = 1; break; - case 34: + case 34: $function = 'TRUE'; $args = 0; break; - case 35: + case 35: $function = 'FALSE'; $args = 0; break; - case 38: + case 38: $function = 'NOT'; $args = 1; break; - case 39: + case 39: $function = 'MOD'; $args = 2; break; - case 40: + case 40: $function = 'DCOUNT'; $args = 3; break; - case 41: + case 41: $function = 'DSUM'; $args = 3; break; - case 42: + case 42: $function = 'DAVERAGE'; $args = 3; break; - case 43: + case 43: $function = 'DMIN'; $args = 3; break; - case 44: + case 44: $function = 'DMAX'; $args = 3; break; - case 45: + case 45: $function = 'DSTDEV'; $args = 3; break; - case 48: + case 48: $function = 'TEXT'; $args = 2; break; - case 61: + case 61: $function = 'MIRR'; $args = 3; break; - case 63: + case 63: $function = 'RAND'; $args = 0; break; - case 65: + case 65: $function = 'DATE'; $args = 3; break; - case 66: + case 66: $function = 'TIME'; $args = 3; break; - case 67: + case 67: $function = 'DAY'; $args = 1; break; - case 68: + case 68: $function = 'MONTH'; $args = 1; break; - case 69: + case 69: $function = 'YEAR'; $args = 1; break; - case 71: + case 71: $function = 'HOUR'; $args = 1; break; - case 72: + case 72: $function = 'MINUTE'; $args = 1; break; - case 73: + case 73: $function = 'SECOND'; $args = 1; break; - case 74: + case 74: $function = 'NOW'; $args = 0; break; - case 75: + case 75: $function = 'AREAS'; $args = 1; break; - case 76: + case 76: $function = 'ROWS'; $args = 1; break; - case 77: + case 77: $function = 'COLUMNS'; $args = 1; break; - case 83: + case 83: $function = 'TRANSPOSE'; $args = 1; break; - case 86: + case 86: $function = 'TYPE'; $args = 1; break; - case 97: + case 97: $function = 'ATAN2'; $args = 2; break; - case 98: + case 98: $function = 'ASIN'; $args = 1; break; - case 99: + case 99: $function = 'ACOS'; $args = 1; break; @@ -6399,97 +6399,97 @@ private function _getNextToken($formulaData, $baseCell = 'A1') // offset: 2: size: 2; index to built-in sheet function $index = self::_GetInt2d($formulaData, 2); switch ($index) { - case 0: + case 0: $function = 'COUNT'; break; - case 1: + case 1: $function = 'IF'; break; - case 4: + case 4: $function = 'SUM'; break; - case 5: + case 5: $function = 'AVERAGE'; break; - case 6: + case 6: $function = 'MIN'; break; - case 7: + case 7: $function = 'MAX'; break; - case 8: + case 8: $function = 'ROW'; break; - case 9: + case 9: $function = 'COLUMN'; break; - case 11: + case 11: $function = 'NPV'; break; - case 12: + case 12: $function = 'STDEV'; break; - case 13: + case 13: $function = 'DOLLAR'; break; - case 14: + case 14: $function = 'FIXED'; break; - case 28: + case 28: $function = 'LOOKUP'; break; - case 29: + case 29: $function = 'INDEX'; break; - case 36: + case 36: $function = 'AND'; break; - case 37: + case 37: $function = 'OR'; break; - case 46: + case 46: $function = 'VAR'; break; - case 49: + case 49: $function = 'LINEST'; break; - case 50: + case 50: $function = 'TREND'; break; - case 51: + case 51: $function = 'LOGEST'; break; - case 52: + case 52: $function = 'GROWTH'; break; - case 56: + case 56: $function = 'PV'; break; - case 57: + case 57: $function = 'FV'; break; - case 58: + case 58: $function = 'NPER'; break; - case 59: + case 59: $function = 'PMT'; break; - case 60: + case 60: $function = 'RATE'; break; - case 62: + case 62: $function = 'IRR'; break; - case 64: + case 64: $function = 'MATCH'; break; - case 70: + case 70: $function = 'WEEKDAY'; break; - case 78: + case 78: $function = 'OFFSET'; break; - case 82: + case 82: $function = 'SEARCH'; break; case 100: @@ -7468,7 +7468,7 @@ private static function _extractNumber($data) $mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); $mantissalow1 = ($rknumlow & 0x80000000) >> 31; $mantissalow2 = ($rknumlow & 0x7fffffff); - $value = $mantissa / pow( 2 , (20 - $exp)); + $value = $mantissa / pow(2 , (20 - $exp)); if ($mantissalow1 != 0) { $value += 1 / pow (2 , (21 - $exp)); @@ -7496,7 +7496,7 @@ private static function _GetIEEE754($rknum) $sign = ($rknum & 0x80000000) >> 31; $exp = ($rknum & 0x7ff00000) >> 20; $mantissa = (0x100000 | ($rknum & 0x000ffffc)); - $value = $mantissa / pow( 2 , (20- ($exp - 1023))); + $value = $mantissa / pow(2 , (20- ($exp - 1023))); if ($sign) { $value = -1 * $value; } @@ -8043,8 +8043,8 @@ private static function _mapColor($subData) } } - - private function _parseRichText($is = '') { + private function _parseRichText($is = '') + { $value = new PHPExcel_RichText(); $value->createText($is); diff --git a/Classes/PHPExcel/Reader/Excel5/Escher.php b/Classes/PHPExcel/Reader/Excel5/Escher.php index 3fd949a08..f7f45dcdd 100644 --- a/Classes/PHPExcel/Reader/Excel5/Escher.php +++ b/Classes/PHPExcel/Reader/Excel5/Escher.php @@ -107,7 +107,6 @@ public function load($data) // Parse Escher stream while ($this->_pos < $this->_dataSize) { - // offset: 2; size: 2: Record Type $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index 72a6755f0..f67f3231f 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -60,16 +60,15 @@ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPEx private $_referenceHelper = null; - /** * Create a new PHPExcel_Reader_Gnumeric */ - public function __construct() { + public function __construct() + { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); } - /** * Can the current PHPExcel_Reader_IReader read the file? * @@ -101,7 +100,6 @@ public function canRead($pFilename) return true; } - /** * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object * @@ -116,9 +114,7 @@ public function listWorksheetNames($pFilename) } $xml = new XMLReader(); - $xml->xml( - $this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions() - ); + $xml->xml($this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions()); $xml->setParserProperty(2,true); $worksheetNames = array(); @@ -135,7 +131,6 @@ public function listWorksheetNames($pFilename) return $worksheetNames; } - /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) * @@ -150,10 +145,8 @@ public function listWorksheetInfo($pFilename) } $xml = new XMLReader(); - $xml->xml( - $this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions() - ); - $xml->setParserProperty(2,true); + $xml->xml($this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml->setParserProperty(2, true); $worksheetInfo = array(); while ($xml->read()) { @@ -188,8 +181,8 @@ public function listWorksheetInfo($pFilename) return $worksheetInfo; } - - private function _gzfileGetContents($filename) { + private function _gzfileGetContents($filename) + { $file = @gzopen($filename, 'rb'); if ($file !== false) { $data = ''; @@ -201,7 +194,6 @@ private function _gzfileGetContents($filename) { return $data; } - /** * Loads PHPExcel from file * @@ -218,7 +210,6 @@ public function load($pFilename) return $this->loadIntoExisting($pFilename, $objPHPExcel); } - /** * Loads PHPExcel from file into PHPExcel instance * @@ -258,7 +249,6 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $officeDocMetaXML = $officeDocXML->meta; foreach ($officeDocMetaXML as $officePropertyData) { - $officePropertyDC = array(); if (isset($namespacesMeta['dc'])) { $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); @@ -266,24 +256,24 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($officePropertyDC as $propertyName => $propertyValue) { $propertyValue = (string) $propertyValue; switch ($propertyName) { - case 'title' : - $docProps->setTitle(trim($propertyValue)); - break; - case 'subject' : - $docProps->setSubject(trim($propertyValue)); - break; - case 'creator' : - $docProps->setCreator(trim($propertyValue)); - $docProps->setLastModifiedBy(trim($propertyValue)); - break; - case 'date' : - $creationDate = strtotime(trim($propertyValue)); - $docProps->setCreated($creationDate); - $docProps->setModified($creationDate); - break; - case 'description' : - $docProps->setDescription(trim($propertyValue)); - break; + case 'title': + $docProps->setTitle(trim($propertyValue)); + break; + case 'subject': + $docProps->setSubject(trim($propertyValue)); + break; + case 'creator': + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'date': + $creationDate = strtotime(trim($propertyValue)); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'description': + $docProps->setDescription(trim($propertyValue)); + break; } } $officePropertyMeta = array(); @@ -294,32 +284,32 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $attributes = $propertyValue->attributes($namespacesMeta['meta']); $propertyValue = (string) $propertyValue; switch ($propertyName) { - case 'keyword' : - $docProps->setKeywords(trim($propertyValue)); - break; - case 'initial-creator' : - $docProps->setCreator(trim($propertyValue)); - $docProps->setLastModifiedBy(trim($propertyValue)); - break; - case 'creation-date' : - $creationDate = strtotime(trim($propertyValue)); - $docProps->setCreated($creationDate); - $docProps->setModified($creationDate); - break; - case 'user-defined' : - list(, $attrName) = explode(':', $attributes['name']); - switch ($attrName) { - case 'publisher' : - $docProps->setCompany(trim($propertyValue)); - break; - case 'category' : - $docProps->setCategory(trim($propertyValue)); - break; - case 'manager' : - $docProps->setManager(trim($propertyValue)); - break; - } - break; + case 'keyword': + $docProps->setKeywords(trim($propertyValue)); + break; + case 'initial-creator': + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'creation-date': + $creationDate = strtotime(trim($propertyValue)); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'user-defined': + list(, $attrName) = explode(':', $attributes['name']); + switch ($attrName) { + case 'publisher': + $docProps->setCompany(trim($propertyValue)); + break; + case 'category': + $docProps->setCategory(trim($propertyValue)); + break; + case 'manager': + $docProps->setManager(trim($propertyValue)); + break; + } + break; } } } @@ -328,26 +318,26 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $propertyName = $summaryItem->name; $propertyValue = $summaryItem->{'val-string'}; switch ($propertyName) { - case 'title' : + case 'title': $docProps->setTitle(trim($propertyValue)); break; - case 'comments' : + case 'comments': $docProps->setDescription(trim($propertyValue)); break; - case 'keywords' : + case 'keywords': $docProps->setKeywords(trim($propertyValue)); break; - case 'category' : + case 'category': $docProps->setCategory(trim($propertyValue)); break; - case 'manager' : + case 'manager': $docProps->setManager(trim($propertyValue)); break; - case 'author' : + case 'author': $docProps->setCreator(trim($propertyValue)); $docProps->setLastModifiedBy(trim($propertyValue)); break; - case 'company' : + case 'company': $docProps->setCompany(trim($propertyValue)); break; } @@ -370,35 +360,35 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet // name in line with the formula, not the reverse - $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + $objPHPExcel->getActiveSheet()->setTitle($worksheetName, false); if ((!$this->_readDataOnly) && (isset($sheet->PrintInformation))) { if (isset($sheet->PrintInformation->Margins)) { - foreach ($sheet->PrintInformation->Margins->children('gnm',TRUE) as $key => $margin) { + foreach ($sheet->PrintInformation->Margins->children('gnm', true) as $key => $margin) { $marginAttributes = $margin->attributes(); $marginSize = 72 / 100; // Default switch ($marginAttributes['PrefUnit']) { - case 'mm' : + case 'mm': $marginSize = intval($marginAttributes['Points']) / 100; break; } switch ($key) { - case 'top' : + case 'top': $objPHPExcel->getActiveSheet()->getPageMargins()->setTop($marginSize); break; - case 'bottom' : + case 'bottom': $objPHPExcel->getActiveSheet()->getPageMargins()->setBottom($marginSize); break; - case 'left' : + case 'left': $objPHPExcel->getActiveSheet()->getPageMargins()->setLeft($marginSize); break; - case 'right' : + case 'right': $objPHPExcel->getActiveSheet()->getPageMargins()->setRight($marginSize); break; - case 'header' : + case 'header': $objPHPExcel->getActiveSheet()->getPageMargins()->setHeader($marginSize); break; - case 'footer' : + case 'footer': $objPHPExcel->getActiveSheet()->getPageMargins()->setFooter($marginSize); break; } @@ -411,13 +401,17 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $row = (int) $cellAttributes->Row + 1; $column = (int) $cellAttributes->Col; - if ($row > $maxRow) $maxRow = $row; - if ($column > $maxCol) $maxCol = $column; + if ($row > $maxRow) { + $maxRow = $row; + } + if ($column > $maxCol) { + $maxCol = $column; + } $column = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if ($this->getReadFilter() !== NULL) { + if ($this->getReadFilter() !== null) { if (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) { continue; } @@ -431,47 +425,42 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $type = PHPExcel_Cell_DataType::TYPE_FORMULA; if ($ExprID > '') { if (((string) $cell) > '') { - - $this->_expressions[$ExprID] = array( 'column' => $cellAttributes->Col, - 'row' => $cellAttributes->Row, - 'formula' => (string) $cell - ); + $this->_expressions[$ExprID] = array( + 'column' => $cellAttributes->Col, + 'row' => $cellAttributes->Row, + 'formula' => (string) $cell + ); // echo 'NEW EXPRESSION ', $ExprID,'<br />'; } else { $expression = $this->_expressions[$ExprID]; - $cell = $this->_referenceHelper->updateFormulaReferences( $expression['formula'], - 'A1', - $cellAttributes->Col - $expression['column'], - $cellAttributes->Row - $expression['row'], - $worksheetName - ); + $cell = $this->_referenceHelper->updateFormulaReferences($expression['formula'], 'A1', $cellAttributes->Col - $expression['column'], $cellAttributes->Row - $expression['row'], $worksheetName); // echo 'SHARED EXPRESSION ', $ExprID,'<br />'; // echo 'New Value is ', $cell,'<br />'; } $type = PHPExcel_Cell_DataType::TYPE_FORMULA; } else { switch ($ValueType) { - case '10' : // NULL + case '10': // NULL $type = PHPExcel_Cell_DataType::TYPE_NULL; break; - case '20' : // Boolean + case '20': // Boolean $type = PHPExcel_Cell_DataType::TYPE_BOOL; - $cell = ($cell == 'TRUE') ? True : False; + $cell = ($cell == 'TRUE') ? true: false; break; - case '30' : // Integer + case '30': // Integer $cell = intval($cell); - case '40' : // Float + case '40': // Float $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; break; - case '50' : // Error + case '50': // Error $type = PHPExcel_Cell_DataType::TYPE_ERROR; break; - case '60' : // String + case '60': // String $type = PHPExcel_Cell_DataType::TYPE_STRING; break; - case '70' : // Cell Range - case '80' : // Array + case '70': // Cell Range + case '80': // Array } } $objPHPExcel->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell, $type); @@ -482,9 +471,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $commentAttributes = $comment->attributes(); // Only comment objects are handled at the moment if ($commentAttributes->Text) { - $objPHPExcel->getActiveSheet()->getComment( (string)$commentAttributes->ObjectBound ) - ->setAuthor( (string)$commentAttributes->Author ) - ->setText($this->_parseRichText((string)$commentAttributes->Text) ); + $objPHPExcel->getActiveSheet()->getComment((string)$commentAttributes->ObjectBound)->setAuthor((string)$commentAttributes->Author)->setText($this->_parseRichText((string)$commentAttributes->Text)); } } } @@ -517,44 +504,44 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // If _readDataOnly is false, we set all formatting information if (!$this->_readDataOnly) { switch ($styleAttributes['HAlign']) { - case '1' : + case '1': $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; break; - case '2' : + case '2': $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_LEFT; break; - case '4' : + case '4': $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_RIGHT; break; - case '8' : + case '8': $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER; break; - case '16' : - case '64' : + case '16': + case '64': $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS; break; - case '32' : + case '32': $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY; break; } switch ($styleAttributes['VAlign']) { - case '1' : + case '1': $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_TOP; break; - case '2' : + case '2': $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; break; - case '4' : + case '4': $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_CENTER; break; - case '8' : + case '8': $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_JUSTIFY; break; } - $styleArray['alignment']['wrap'] = ($styleAttributes['WrapText'] == '1') ? True : False; - $styleArray['alignment']['shrinkToFit'] = ($styleAttributes['ShrinkToFit'] == '1') ? True : False; + $styleArray['alignment']['wrap'] = ($styleAttributes['WrapText'] == '1') ? true : false; + $styleArray['alignment']['shrinkToFit'] = ($styleAttributes['ShrinkToFit'] == '1') ? true : false; $styleArray['alignment']['indent'] = (intval($styleAttributes["Indent"]) > 0) ? $styleAttributes["indent"] : 0; $RGB = self::_parseGnumericColour($styleAttributes["Fore"]); @@ -566,64 +553,64 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $RGB2 = self::_parseGnumericColour($styleAttributes["PatternColor"]); $styleArray['fill']['endcolor']['rgb'] = $RGB2; switch ($shade) { - case '1' : + case '1': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_SOLID; break; - case '2' : + case '2': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR; break; - case '3' : + case '3': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_PATH; break; - case '4' : + case '4': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; break; - case '5' : + case '5': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; break; - case '6' : + case '6': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; break; - case '7' : + case '7': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; break; - case '8' : + case '8': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; break; - case '9' : + case '9': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; break; - case '10' : + case '10': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; break; - case '11' : + case '11': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; break; - case '12' : + case '12': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; break; - case '13' : + case '13': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; break; - case '14' : + case '14': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; break; - case '15' : + case '15': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; break; - case '16' : + case '16': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; break; - case '17' : + case '17': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; break; - case '18' : + case '18': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; break; - case '19' : + case '19': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; break; - case '20' : + case '20': $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; break; } @@ -634,32 +621,32 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo '<br />'; $styleArray['font']['name'] = (string) $styleRegion->Style->Font; $styleArray['font']['size'] = intval($fontAttributes['Unit']); - $styleArray['font']['bold'] = ($fontAttributes['Bold'] == '1') ? True : False; - $styleArray['font']['italic'] = ($fontAttributes['Italic'] == '1') ? True : False; - $styleArray['font']['strike'] = ($fontAttributes['StrikeThrough'] == '1') ? True : False; + $styleArray['font']['bold'] = ($fontAttributes['Bold'] == '1') ? true : false; + $styleArray['font']['italic'] = ($fontAttributes['Italic'] == '1') ? true : false; + $styleArray['font']['strike'] = ($fontAttributes['StrikeThrough'] == '1') ? true : false; switch ($fontAttributes['Underline']) { - case '1' : + case '1': $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLE; break; - case '2' : + case '2': $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLE; break; - case '3' : + case '3': $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING; break; - case '4' : + case '4': $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING; break; - default : + default: $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_NONE; break; } switch ($fontAttributes['Script']) { - case '1' : - $styleArray['font']['superScript'] = True; + case '1': + $styleArray['font']['superScript'] = true; break; - case '-1' : - $styleArray['font']['subScript'] = True; + case '-1': + $styleArray['font']['subScript'] = true; break; } @@ -761,7 +748,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Handle Merged Cells in this worksheet if (isset($sheet->MergedRegions)) { foreach ($sheet->MergedRegions->Merge as $mergeCells) { - if (strpos($mergeCells,':') !== FALSE) { + if (strpos($mergeCells,':') !== false) { $objPHPExcel->getActiveSheet()->mergeCells($mergeCells); } } @@ -783,17 +770,15 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $range[0] = trim($range[0],"'");; if ($worksheet = $objPHPExcel->getSheetByName($range[0])) { $extractedRange = str_replace('$', '', $range[1]); - $objPHPExcel->addNamedRange( new PHPExcel_NamedRange($name, $worksheet, $extractedRange) ); + $objPHPExcel->addNamedRange(new PHPExcel_NamedRange($name, $worksheet, $extractedRange)); } } } - // Return return $objPHPExcel; } - private static function _parseBorderAttributes($borderAttributes) { $styleArray = array(); @@ -804,54 +789,54 @@ private static function _parseBorderAttributes($borderAttributes) } switch ($borderAttributes["Style"]) { - case '0' : + case '0': $styleArray['style'] = PHPExcel_Style_Border::BORDER_NONE; break; - case '1' : + case '1': $styleArray['style'] = PHPExcel_Style_Border::BORDER_THIN; break; - case '2' : + case '2': $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; break; - case '4' : + case '4': $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHED; break; - case '5' : + case '5': $styleArray['style'] = PHPExcel_Style_Border::BORDER_THICK; break; - case '6' : + case '6': $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOUBLE; break; - case '7' : + case '7': $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOTTED; break; - case '9' : + case '9': $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOT; break; - case '10' : + case '10': $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; break; - case '11' : + case '11': $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOTDOT; break; - case '12' : + case '12': $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; break; - case '13' : + case '13': $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; break; - case '3' : + case '3': $styleArray['style'] = PHPExcel_Style_Border::BORDER_SLANTDASHDOT; break; - case '8' : + case '8': $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHED; break; } return $styleArray; } - - private function _parseRichText($is = '') { + private function _parseRichText($is = '') + { $value = new PHPExcel_RichText(); $value->createText($is); @@ -859,15 +844,13 @@ private function _parseRichText($is = '') { return $value; } - private static function _parseGnumericColour($gnmColour) { list($gnmR, $gnmG, $gnmB) = explode(':', $gnmColour); - $gnmR = substr(str_pad($gnmR,4,'0',STR_PAD_RIGHT),0,2); - $gnmG = substr(str_pad($gnmG,4,'0',STR_PAD_RIGHT),0,2); - $gnmB = substr(str_pad($gnmB,4,'0',STR_PAD_RIGHT),0,2); + $gnmR = substr(str_pad($gnmR, 4, '0', STR_PAD_RIGHT), 0, 2); + $gnmG = substr(str_pad($gnmG, 4, '0', STR_PAD_RIGHT), 0, 2); + $gnmB = substr(str_pad($gnmB, 4, '0', STR_PAD_RIGHT), 0, 2); $RGB = $gnmR.$gnmG.$gnmB; // echo 'Excel Colour: ', $RGB,'<br />'; return $RGB; } - } diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index c212e9bcc..21a35bf72 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -51,7 +51,6 @@ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExce */ private $_styles = array(); - /** * Create a new PHPExcel_Reader_OOCalc */ @@ -59,7 +58,6 @@ public function __construct() { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); } - /** * Can the current PHPExcel_Reader_IReader read the file? * @@ -77,7 +75,7 @@ public function canRead($pFilename) $zipClass = PHPExcel_Settings::getZipClass(); // Check if zip class exists -// if (!class_exists($zipClass, FALSE)) { +// if (!class_exists($zipClass, false)) { // throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); // } @@ -109,7 +107,7 @@ public function canRead($pFilename) return ($mimeType === 'application/vnd.oasis.opendocument.spreadsheet'); } - return FALSE; + return false; } @@ -137,17 +135,18 @@ public function listWorksheetNames($pFilename) $xml = new XMLReader(); $res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions()); - $xml->setParserProperty(2,true); + $xml->setParserProperty(2, true); // Step into the first level of content of the XML $xml->read(); while ($xml->read()) { // Quickly jump through to the office:body node while ($xml->name !== 'office:body') { - if ($xml->isEmptyElement) + if ($xml->isEmptyElement) { $xml->read(); - else + } else { $xml->next(); + } } // Now read each node until we find our first table:table node while ($xml->read()) { @@ -164,7 +163,6 @@ public function listWorksheetNames($pFilename) return $worksheetNames; } - /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) * @@ -189,17 +187,18 @@ public function listWorksheetInfo($pFilename) $xml = new XMLReader(); $res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions()); - $xml->setParserProperty(2,true); + $xml->setParserProperty(2, true); // Step into the first level of content of the XML $xml->read(); while ($xml->read()) { // Quickly jump through to the office:body node while ($xml->name !== 'office:body') { - if ($xml->isEmptyElement) + if ($xml->isEmptyElement) { $xml->read(); - else + } else { $xml->next(); + } } // Now read each node until we find our first table:table node while ($xml->read()) { @@ -289,7 +288,6 @@ public function listWorksheetInfo($pFilename) return $worksheetInfo; } - /** * Loads PHPExcel from file * @@ -306,8 +304,8 @@ public function load($pFilename) return $this->loadIntoExisting($pFilename, $objPHPExcel); } - - private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { + private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) + { $styleAttributeValue = strtolower($styleAttributeValue); foreach ($styleList as $style) { if ($styleAttributeValue == strtolower($style)) { @@ -318,7 +316,6 @@ private static function identifyFixedStyleValue($styleList,&$styleAttributeValue return false; } - /** * Loads PHPExcel from file into PHPExcel instance * @@ -362,23 +359,23 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $propertyValue = (string) $propertyValue; switch ($propertyName) { case 'title' : - $docProps->setTitle($propertyValue); - break; + $docProps->setTitle($propertyValue); + break; case 'subject' : - $docProps->setSubject($propertyValue); - break; + $docProps->setSubject($propertyValue); + break; case 'creator' : - $docProps->setCreator($propertyValue); - $docProps->setLastModifiedBy($propertyValue); - break; + $docProps->setCreator($propertyValue); + $docProps->setLastModifiedBy($propertyValue); + break; case 'date' : - $creationDate = strtotime($propertyValue); - $docProps->setCreated($creationDate); - $docProps->setModified($creationDate); - break; + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; case 'description' : - $docProps->setDescription($propertyValue); - break; + $docProps->setDescription($propertyValue); + break; } } $officePropertyMeta = array(); @@ -390,41 +387,41 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $propertyValue = (string) $propertyValue; switch ($propertyName) { case 'initial-creator' : - $docProps->setCreator($propertyValue); - break; + $docProps->setCreator($propertyValue); + break; case 'keyword' : - $docProps->setKeywords($propertyValue); - break; + $docProps->setKeywords($propertyValue); + break; case 'creation-date' : - $creationDate = strtotime($propertyValue); - $docProps->setCreated($creationDate); - break; + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + break; case 'user-defined' : - $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; - foreach ($propertyValueAttributes as $key => $value) { - if ($key == 'name') { - $propertyValueName = (string) $value; - } elseif ($key == 'value-type') { - switch ($value) { - case 'date' : - $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date'); - $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; - break; - case 'boolean' : - $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'bool'); - $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; - break; - case 'float' : - $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'r4'); - $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; - break; - default : - $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; - } + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; + foreach ($propertyValueAttributes as $key => $value) { + if ($key == 'name') { + $propertyValueName = (string) $value; + } elseif ($key == 'value-type') { + switch ($value) { + case 'date' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue, 'date'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; + break; + case 'boolean' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue, 'bool'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; + break; + case 'float' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue, 'r4'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; + break; + default : + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; } } - $docProps->setCustomProperty($propertyValueName, $propertyValue, $propertyValueType); - break; + } + $docProps->setCustomProperty($propertyValueName, $propertyValue, $propertyValueType); + break; } } } @@ -470,7 +467,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo '<b>'.$key.'</b><br />'; switch ($key) { case 'table-header-rows': - foreach ($rowData as $key=>$cellData) { + foreach ($rowData as $key => $cellData) { $rowData = $cellData; break; } @@ -480,7 +477,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $rowDataTableAttributes['number-rows-repeated'] : 1; $columnID = 'A'; foreach ($rowData as $key => $cellData) { - if ($this->getReadFilter() !== NULL) { + if ($this->getReadFilter() !== null) { if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { continue; } @@ -524,13 +521,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } $text = implode("\n", $textArray); -// echo $text,'<br />'; +// echo $text, '<br />'; $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) // ->setAuthor( $author ) ->setText($this->_parseRichText($text) ); } - if (isset($cellDataText->p)) { + if (isset($cellDataText->p)) { // Consolidate if there are multiple p records (maybe with spans as well) $dataArray = array(); // Text can have multiple text:p and within those, multiple text:span. @@ -554,85 +551,85 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />'; switch ($cellDataOfficeAttributes['value-type']) { case 'string' : - $type = PHPExcel_Cell_DataType::TYPE_STRING; - $dataValue = $allCellDataText; - if (isset($dataValue->a)) { - $dataValue = $dataValue->a; - $cellXLinkAttributes = $dataValue->attributes($namespacesContent['xlink']); - $hyperlink = $cellXLinkAttributes['href']; - } - break; + $type = PHPExcel_Cell_DataType::TYPE_STRING; + $dataValue = $allCellDataText; + if (isset($dataValue->a)) { + $dataValue = $dataValue->a; + $cellXLinkAttributes = $dataValue->attributes($namespacesContent['xlink']); + $hyperlink = $cellXLinkAttributes['href']; + } + break; case 'boolean' : $type = PHPExcel_Cell_DataType::TYPE_BOOL; - $dataValue = ($allCellDataText == 'TRUE') ? True : False; + $dataValue = ($allCellDataText == 'TRUE') ? true : false; break; case 'percentage' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dataValue = (float) $cellDataOfficeAttributes['value']; - if (floor($dataValue) == $dataValue) { - $dataValue = (integer) $dataValue; - } - $formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00; - break; + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + $dataValue = (integer) $dataValue; + } + $formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00; + break; case 'currency' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dataValue = (float) $cellDataOfficeAttributes['value']; - if (floor($dataValue) == $dataValue) { - $dataValue = (integer) $dataValue; - } - $formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE; - break; + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + $dataValue = (integer) $dataValue; + } + $formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE; + break; case 'float' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dataValue = (float) $cellDataOfficeAttributes['value']; - if (floor($dataValue) == $dataValue) { - if ($dataValue == (integer) $dataValue) - $dataValue = (integer) $dataValue; - else - $dataValue = (float) $dataValue; - } - break; + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + if ($dataValue == (integer) $dataValue) + $dataValue = (integer) $dataValue; + else + $dataValue = (float) $dataValue; + } + break; case 'date' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT); - $dateObj->setTimeZone($timezoneObj); - list($year, $month, $day, $hour, $minute, $second) = explode(' ', $dateObj->format('Y m d H i s')); - $dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year, $month, $day, $hour, $minute, $second); - if ($dataValue != floor($dataValue)) { - $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; - } else { - $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15; - } - break; + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT); + $dateObj->setTimeZone($timezoneObj); + list($year, $month, $day, $hour, $minute, $second) = explode(' ', $dateObj->format('Y m d H i s')); + $dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year, $month, $day, $hour, $minute, $second); + if ($dataValue != floor($dataValue)) { + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; + } else { + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15; + } + break; case 'time' : - $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'],'PT%dH%dM%dS')))); - $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; - break; + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'], 'PT%dH%dM%dS')))); + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; + break; } // echo 'Data value is '.$dataValue.'<br />'; -// if ($hyperlink !== NULL) { +// if ($hyperlink !== null) { // echo 'Hyperlink is '.$hyperlink.'<br />'; // } } else { $type = PHPExcel_Cell_DataType::TYPE_NULL; - $dataValue = NULL; + $dataValue = null; } if ($hasCalculatedValue) { $type = PHPExcel_Cell_DataType::TYPE_FORMULA; // echo 'Formula: ', $cellDataFormula, PHP_EOL; - $cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1); + $cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula, ':=')+1); $temp = explode('"', $cellDataFormula); $tKey = false; foreach ($temp as &$value) { // Only replace in alternate array entries (i.e. non-quoted blocks) if ($tKey = !$tKey) { - $value = preg_replace('/\[([^\.]+)\.([^\.]+):\.([^\.]+)\]/Ui','$1!$2:$3', $value); // Cell range reference in another sheet - $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/Ui','$1!$2', $value); // Cell reference in another sheet - $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/Ui','$1:$2', $value); // Cell range reference - $value = preg_replace('/\[\.([^\.]+)\]/Ui','$1', $value); // Simple cell reference - $value = PHPExcel_Calculation::_translateSeparator(';',',', $value, $inBraces); + $value = preg_replace('/\[([^\.]+)\.([^\.]+):\.([^\.]+)\]/Ui', '$1!$2:$3', $value); // Cell range reference in another sheet + $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/Ui', '$1!$2', $value); // Cell reference in another sheet + $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/Ui', '$1:$2', $value); // Cell range reference + $value = preg_replace('/\[\.([^\.]+)\]/Ui', '$1', $value); // Simple cell reference + $value = PHPExcel_Calculation::_translateSeparator(';', ',', $value, $inBraces); } } unset($value); @@ -641,9 +638,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo 'Adjusted Formula: ', $cellDataFormula, PHP_EOL; } - $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? - $cellDataTableAttributes['number-columns-repeated'] : 1; - if ($type !== NULL) { + $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? $cellDataTableAttributes['number-columns-repeated'] : 1; + if ($type !== null) { for ($i = 0; $i < $colRepeats; ++$i) { if ($i > 0) { ++$columnID; @@ -656,12 +652,12 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo 'Forumla result is '.$dataValue.'<br />'; $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue); } - if ($formatting !== NULL) { + if ($formatting !== null) { $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode($formatting); } else { $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL); } - if ($hyperlink !== NULL) { + if ($hyperlink !== null) { $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->getHyperlink()->setUrl($hyperlink); } } @@ -699,13 +695,12 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) return $objPHPExcel; } - - private function _parseRichText($is = '') { + private function _parseRichText($is = '') + { $value = new PHPExcel_RichText(); $value->createText($is); return $value; } - } diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index de712d639..51c80605b 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -75,7 +75,8 @@ class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_ /** * Create a new PHPExcel_Reader_SYLK */ - public function __construct() { + public function __construct() + { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); } @@ -97,7 +98,7 @@ protected function _isValidFormat() // Analyze first line looking for ID; signature $lines = explode("\n", $data); - if (substr($lines[0],0,4) != 'ID;P') { + if (substr($lines[0], 0, 4) != 'ID;P') { return false; } @@ -136,7 +137,7 @@ public function listWorksheetInfo($pFilename) // Open file $this->_openFile($pFilename); if (!$this->_isValidFormat()) { - fclose ($this->_fileHandle); + fclose($this->_fileHandle); throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } $fileHandle = $this->_fileHandle; @@ -162,20 +163,20 @@ public function listWorksheetInfo($pFilename) // explode each row at semicolons while taking into account that literal semicolon (;) // is escaped like this (;;) - $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); + $rowData = explode("\t", str_replace('¤', ';', str_replace(';', "\t", str_replace(';;', '¤', rtrim($rowData))))); $dataType = array_shift($rowData); if ($dataType == 'C') { // Read cell value data foreach ($rowData as $rowDatum) { switch ($rowDatum{0}) { - case 'C' : - case 'X' : - $columnIndex = substr($rowDatum,1) - 1; + case 'C': + case 'X': + $columnIndex = substr($rowDatum, 1) - 1; break; - case 'R' : - case 'Y' : - $rowIndex = substr($rowDatum,1); + case 'R': + case 'Y': + $rowIndex = substr($rowDatum, 1); break; } @@ -223,7 +224,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Open file $this->_openFile($pFilename); if (!$this->_isValidFormat()) { - fclose ($this->_fileHandle); + fclose($this->_fileHandle); throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } $fileHandle = $this->_fileHandle; @@ -233,7 +234,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { $objPHPExcel->createSheet(); } - $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex ); + $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); $fromFormats = array('\-', '\ '); $toFormats = array('-', ' '); @@ -244,13 +245,12 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // loop through one row (line) at a time in the file while (($rowData = fgets($fileHandle)) !== false) { - // convert SYLK encoded $rowData to UTF-8 $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData); // explode each row at semicolons while taking into account that literal semicolon (;) // is escaped like this (;;) - $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); + $rowData = explode("\t", str_replace('¤', ';', str_replace(';', "\t", str_replace(';;', '¤', rtrim($rowData))))); $dataType = array_shift($rowData); // Read shared styles @@ -270,7 +270,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) break; case 'S': $styleSettings = substr($rowDatum,1); - for ($i=0;$i<strlen($styleSettings);++$i) { + for ($i=0; $i<strlen($styleSettings); ++$i) { switch ($styleSettings{$i}) { case 'I': $formatArray['font']['italic'] = true; @@ -305,7 +305,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) case 'C': case 'X': $column = substr($rowDatum, 1); - break; + break; case 'R': case 'Y': $row = substr($rowDatum, 1); @@ -321,7 +321,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($temp as &$value) { // Only count/replace in alternate array entries if ($key = !$key) { - preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences, PREG_SET_ORDER+PREG_OFFSET_CAPTURE); // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way // through the formula from left to right. Reversing means that we work right to left.through // the formula @@ -345,7 +345,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } // Bracketed C references are relative to the current column if ($columnReference{0} == '[') { - $columnReference = $column + trim($columnReference,'[]'); + $columnReference = $column + trim($columnReference, '[]'); } $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; @@ -390,8 +390,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) list($startCol, $endCol, $columnWidth) = explode(' ', substr($rowDatum, 1)); break; case 'S': - $styleSettings = substr($rowDatum,1); - for ($i=0;$i<strlen($styleSettings);++$i) { + $styleSettings = substr($rowDatum, 1); + for ($i=0; $i<strlen($styleSettings); ++$i) { switch ($styleSettings{$i}) { case 'I': $styleData['font']['italic'] = true; @@ -444,11 +444,11 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) switch ($rowDatum{0}) { case 'C': case 'X': - $column = substr($rowDatum,1); + $column = substr($rowDatum, 1); break; case 'R': case 'Y': - $row = substr($rowDatum,1); + $row = substr($rowDatum, 1); break; } } diff --git a/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php b/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php index 31a0b648e..4b73e077a 100644 --- a/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php @@ -15,8 +15,8 @@ * @author Michael Bommarito * @version 1.2 */ -class CholeskyDecomposition { - +class CholeskyDecomposition +{ /** * Decomposition storage * @var array @@ -38,21 +38,21 @@ class CholeskyDecomposition { */ private $isspd = true; - /** * CholeskyDecomposition * * Class constructor - decomposes symmetric positive definite matrix * @param mixed Matrix square symmetric positive definite matrix */ - public function __construct($A = null) { + public function __construct($A = null) + { if ($A instanceof Matrix) { $this->L = $A->getArray(); $this->m = $A->getRowDimension(); - for($i = 0; $i < $this->m; ++$i) { - for($j = $i; $j < $this->m; ++$j) { - for($sum = $this->L[$i][$j], $k = $i - 1; $k >= 0; --$k) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = $i; $j < $this->m; ++$j) { + for ($sum = $this->L[$i][$j], $k = $i - 1; $k >= 0; --$k) { $sum -= $this->L[$i][$k] * $this->L[$j][$k]; } if ($i == $j) { @@ -77,35 +77,35 @@ public function __construct($A = null) { } } // function __construct() - /** * Is the matrix symmetric and positive definite? * * @return boolean */ - public function isSPD() { + public function isSPD() + { return $this->isspd; } // function isSPD() - /** * getL * * Return triangular factor. * @return Matrix Lower triangular matrix */ - public function getL() { + public function getL() + { return new Matrix($this->L); } // function getL() - /** * Solve A*X = B * * @param $B Row-equal matrix * @return Matrix L * L' * X = B */ - public function solve($B = null) { + public function solve($B = null) + { if ($B instanceof Matrix) { if ($B->getRowDimension() == $this->m) { if ($this->isspd) { @@ -145,5 +145,4 @@ public function solve($B = null) { throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); } } // function solve() - -} // class CholeskyDecomposition +} diff --git a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php index 2f9a9ab6f..9a19ba52a 100644 --- a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php @@ -21,8 +21,8 @@ * @license PHP v3.0 * @version 1.1 */ -class EigenvalueDecomposition { - +class EigenvalueDecomposition +{ /** * Row and column dimension (square matrix). * @var int @@ -67,13 +67,13 @@ class EigenvalueDecomposition { private $cdivr; private $cdivi; - /** * Symmetric Householder reduction to tridiagonal form. * * @access private */ - private function tred2 () { + private function tred2 () + { // This is derived from the Algol procedures tred2 by // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding @@ -171,7 +171,6 @@ private function tred2 () { $this->e[0] = 0.0; } - /** * Symmetric tridiagonal QL algorithm. * @@ -182,7 +181,8 @@ private function tred2 () { * * @access private */ - private function tql2() { + private function tql2() + { for ($i = 1; $i < $this->n; ++$i) { $this->e[$i-1] = $this->e[$i]; } @@ -196,8 +196,9 @@ private function tql2() { $tst1 = max($tst1, abs($this->d[$l]) + abs($this->e[$l])); $m = $l; while ($m < $this->n) { - if (abs($this->e[$m]) <= $eps * $tst1) + if (abs($this->e[$m]) <= $eps * $tst1) { break; + } ++$m; } // If m == l, $this->d[l] is an eigenvalue, @@ -211,14 +212,16 @@ private function tql2() { $g = $this->d[$l]; $p = ($this->d[$l+1] - $g) / (2.0 * $this->e[$l]); $r = hypo($p, 1.0); - if ($p < 0) + if ($p < 0) { $r *= -1; + } $this->d[$l] = $this->e[$l] / ($p + $r); $this->d[$l+1] = $this->e[$l] * ($p + $r); $dl1 = $this->d[$l+1]; $h = $g - $this->d[$l]; - for ($i = $l + 2; $i < $this->n; ++$i) + for ($i = $l + 2; $i < $this->n; ++$i) { $this->d[$i] -= $h; + } $f += $h; // Implicit QL transformation. $p = $this->d[$m]; @@ -277,7 +280,6 @@ private function tql2() { } } - /** * Nonsymmetric reduction to Hessenberg form. * @@ -288,7 +290,8 @@ private function tql2() { * * @access private */ - private function orthes () { + private function orthes() + { $low = 0; $high = $this->n-1; @@ -364,13 +367,13 @@ private function orthes () { } } - /** * Performs complex division. * * @access private */ - private function cdiv($xr, $xi, $yr, $yi) { + private function cdiv($xr, $xi, $yr, $yi) + { if (abs($yr) > abs($yi)) { $r = $yi / $yr; $d = $yr + $r * $yi; @@ -384,7 +387,6 @@ private function cdiv($xr, $xi, $yr, $yi) { } } - /** * Nonsymmetric reduction from Hessenberg to real Schur form. * @@ -395,7 +397,8 @@ private function cdiv($xr, $xi, $yr, $yi) { * * @access private */ - private function hqr2 () { + private function hqr2() + { // Initialize $nn = $this->n; $n = $nn - 1; @@ -408,7 +411,7 @@ private function hqr2 () { $norm = 0.0; for ($i = 0; $i < $nn; ++$i) { - if (($i < $low) OR ($i > $high)) { + if (($i < $low) or ($i > $high)) { $this->d[$i] = $this->H[$i][$i]; $this->e[$i] = 0.0; } @@ -477,7 +480,7 @@ private function hqr2 () { $this->H[$n][$j] = $q * $this->H[$n][$j] - $p * $z; } // Column modification - for ($i = 0; $i <= n; ++$i) { + for ($i = 0; $i <= $n; ++$i) { $z = $this->H[$i][$n-1]; $this->H[$i][$n-1] = $q * $z + $p * $this->H[$i][$n]; $this->H[$i][$n] = $q * $this->H[$i][$n] - $p * $z; @@ -771,7 +774,6 @@ private function hqr2 () { } } // end hqr2 - /** * Constructor: Check for symmetry, then construct the eigenvalue decomposition * @@ -779,7 +781,8 @@ private function hqr2 () { * @param A Square matrix * @return Structure to access D and V. */ - public function __construct($Arg) { + public function __construct($Arg) + { $this->A = $Arg->getArray(); $this->n = $Arg->getColumnDimension(); @@ -806,47 +809,47 @@ public function __construct($Arg) { } } - /** * Return the eigenvector matrix * * @access public * @return V */ - public function getV() { + public function getV() + { return new Matrix($this->V, $this->n, $this->n); } - /** * Return the real parts of the eigenvalues * * @access public * @return real(diag(D)) */ - public function getRealEigenvalues() { + public function getRealEigenvalues() + { return $this->d; } - /** * Return the imaginary parts of the eigenvalues * * @access public * @return imag(diag(D)) */ - public function getImagEigenvalues() { + public function getImagEigenvalues() + { return $this->e; } - /** * Return the block diagonal eigenvalue matrix * * @access public * @return D */ - public function getD() { + public function getD() + { for ($i = 0; $i < $this->n; ++$i) { $D[$i] = array_fill(0, $this->n, 0.0); $D[$i][$i] = $this->d[$i]; @@ -858,5 +861,4 @@ public function getD() { } return new Matrix($D); } - -} // class EigenvalueDecomposition +} diff --git a/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php b/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php index bffda2aa2..64290fe7e 100644 --- a/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php @@ -18,8 +18,8 @@ * @version 1.1 * @license PHP v3.0 */ -class PHPExcel_Shared_JAMA_LUDecomposition { - +class PHPExcel_Shared_JAMA_LUDecomposition +{ const MatrixSingularException = "Can only perform operation on singular matrix."; const MatrixSquareException = "Mismatched Row dimension"; @@ -53,14 +53,14 @@ class PHPExcel_Shared_JAMA_LUDecomposition { */ private $piv = array(); - /** * LU Decomposition constructor. * * @param $A Rectangular matrix * @return Structure to access L, U and piv. */ - public function __construct($A) { + public function __construct($A) + { if ($A instanceof PHPExcel_Shared_JAMA_Matrix) { // Use a "left-looking", dot-product, Crout/Doolittle algorithm. $this->LU = $A->getArray(); @@ -119,13 +119,13 @@ public function __construct($A) { } } // function __construct() - /** * Get lower triangular factor. * * @return array Lower triangular factor */ - public function getL() { + public function getL() + { for ($i = 0; $i < $this->m; ++$i) { for ($j = 0; $j < $this->n; ++$j) { if ($i > $j) { @@ -140,13 +140,13 @@ public function getL() { return new PHPExcel_Shared_JAMA_Matrix($L); } // function getL() - /** * Get upper triangular factor. * * @return array Upper triangular factor */ - public function getU() { + public function getU() + { for ($i = 0; $i < $this->n; ++$i) { for ($j = 0; $j < $this->n; ++$j) { if ($i <= $j) { @@ -159,33 +159,33 @@ public function getU() { return new PHPExcel_Shared_JAMA_Matrix($U); } // function getU() - /** * Return pivot permutation vector. * * @return array Pivot vector */ - public function getPivot() { + public function getPivot() + { return $this->piv; } // function getPivot() - /** * Alias for getPivot * * @see getPivot */ - public function getDoublePivot() { + public function getDoublePivot() + { return $this->getPivot(); } // function getDoublePivot() - /** * Is the matrix nonsingular? * * @return true if U, and hence A, is nonsingular. */ - public function isNonsingular() { + public function isNonsingular() + { for ($j = 0; $j < $this->n; ++$j) { if ($this->LU[$j][$j] == 0) { return false; @@ -194,13 +194,13 @@ public function isNonsingular() { return true; } // function isNonsingular() - /** * Count determinants * * @return array d matrix deterninat */ - public function det() { + public function det() + { if ($this->m == $this->n) { $d = $this->pivsign; for ($j = 0; $j < $this->n; ++$j) { @@ -212,7 +212,6 @@ public function det() { } } // function det() - /** * Solve A*X = B * @@ -221,7 +220,8 @@ public function det() { * @PHPExcel_Calculation_Exception IllegalArgumentException Matrix row dimensions must agree. * @PHPExcel_Calculation_Exception RuntimeException Matrix is singular. */ - public function solve($B) { + public function solve($B) + { if ($B->getRowDimension() == $this->m) { if ($this->isNonsingular()) { // Copy right hand side with pivoting @@ -254,5 +254,4 @@ public function solve($B) { throw new PHPExcel_Calculation_Exception(self::MatrixSquareException); } } // function solve() - -} // class PHPExcel_Shared_JAMA_LUDecomposition +} diff --git a/Classes/PHPExcel/Shared/JAMA/Matrix.php b/Classes/PHPExcel/Shared/JAMA/Matrix.php index 2ab40f221..c245cc867 100644 --- a/Classes/PHPExcel/Shared/JAMA/Matrix.php +++ b/Classes/PHPExcel/Shared/JAMA/Matrix.php @@ -24,9 +24,8 @@ * @license PHP v3.0 * @see http://math.nist.gov/javanumerics/jama/ */ -class PHPExcel_Shared_JAMA_Matrix { - - +class PHPExcel_Shared_JAMA_Matrix +{ const PolymorphicArgumentException = "Invalid argument pattern for polymorphic function."; const ArgumentTypeException = "Invalid argument type."; const ArgumentBoundsException = "Invalid argument range."; @@ -57,13 +56,13 @@ class PHPExcel_Shared_JAMA_Matrix { */ private $n; - /** * Polymorphic constructor * * As PHP has no support for polymorphic constructors, we hack our own sort of polymorphism using func_num_args, func_get_arg, and gettype. In essence, we're just implementing a simple RTTI filter and calling the appropriate constructor. */ - public function __construct() { + public function __construct() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); @@ -71,80 +70,79 @@ public function __construct() { switch ($match) { //Rectangular matrix - m x n initialized from 2D array case 'array': - $this->m = count($args[0]); - $this->n = count($args[0][0]); - $this->A = $args[0]; - break; + $this->m = count($args[0]); + $this->n = count($args[0][0]); + $this->A = $args[0]; + break; //Square matrix - n x n case 'integer': - $this->m = $args[0]; - $this->n = $args[0]; - $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); - break; + $this->m = $args[0]; + $this->n = $args[0]; + $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); + break; //Rectangular matrix - m x n case 'integer,integer': - $this->m = $args[0]; - $this->n = $args[1]; - $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); - break; + $this->m = $args[0]; + $this->n = $args[1]; + $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); + break; //Rectangular matrix - m x n initialized from packed array case 'array,integer': - $this->m = $args[1]; - if ($this->m != 0) { - $this->n = count($args[0]) / $this->m; - } else { - $this->n = 0; - } - if (($this->m * $this->n) == count($args[0])) { - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $this->A[$i][$j] = $args[0][$i + $j * $this->m]; - } + $this->m = $args[1]; + if ($this->m != 0) { + $this->n = count($args[0]) / $this->m; + } else { + $this->n = 0; + } + if (($this->m * $this->n) == count($args[0])) { + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = $args[0][$i + $j * $this->m]; } - } else { - throw new PHPExcel_Calculation_Exception(self::ArrayLengthException); } - break; + } else { + throw new PHPExcel_Calculation_Exception(self::ArrayLengthException); + } + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } } // function __construct() - /** * getArray * * @return array Matrix array */ - public function getArray() { + public function getArray() + { return $this->A; } // function getArray() - /** * getRowDimension * * @return int Row dimension */ - public function getRowDimension() { + public function getRowDimension() + { return $this->m; } // function getRowDimension() - /** * getColumnDimension * * @return int Column dimension */ - public function getColumnDimension() { + public function getColumnDimension() + { return $this->n; } // function getColumnDimension() - /** * get * @@ -153,11 +151,11 @@ public function getColumnDimension() { * @param int $j Column position * @return mixed Element (int/float/double) */ - public function get($i = null, $j = null) { + public function get($i = null, $j = null) + { return $this->A[$i][$j]; } // function get() - /** * getMatrix * @@ -168,7 +166,8 @@ public function get($i = null, $j = null) { * @param int $jF Final column index * @return Matrix Submatrix */ - public function getMatrix() { + public function getMatrix() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); @@ -176,92 +175,91 @@ public function getMatrix() { switch ($match) { //A($i0...; $j0...) case 'integer,integer': - list($i0, $j0) = $args; - if ($i0 >= 0) { $m = $this->m - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if ($j0 >= 0) { $n = $this->n - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = $i0; $i < $this->m; ++$i) { - for($j = $j0; $j < $this->n; ++$j) { - $R->set($i, $j, $this->A[$i][$j]); - } + list($i0, $j0) = $args; + if ($i0 >= 0) { $m = $this->m - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if ($j0 >= 0) { $n = $this->n - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = $i0; $i < $this->m; ++$i) { + for($j = $j0; $j < $this->n; ++$j) { + $R->set($i, $j, $this->A[$i][$j]); } - return $R; - break; + } + return $R; + break; //A($i0...$iF; $j0...$jF) case 'integer,integer,integer,integer': - list($i0, $iF, $j0, $jF) = $args; - if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1); - for($i = $i0; $i <= $iF; ++$i) { - for($j = $j0; $j <= $jF; ++$j) { - $R->set($i - $i0, $j - $j0, $this->A[$i][$j]); - } + list($i0, $iF, $j0, $jF) = $args; + if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1); + for($i = $i0; $i <= $iF; ++$i) { + for($j = $j0; $j <= $jF; ++$j) { + $R->set($i - $i0, $j - $j0, $this->A[$i][$j]); } - return $R; - break; + } + return $R; + break; //$R = array of row indices; $C = array of column indices case 'array,array': - list($RL, $CL) = $args; - if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = 0; $i < $m; ++$i) { - for($j = 0; $j < $n; ++$j) { - $R->set($i - $i0, $j - $j0, $this->A[$RL[$i]][$CL[$j]]); - } + list($RL, $CL) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i - $i0, $j - $j0, $this->A[$RL[$i]][$CL[$j]]); } - return $R; - break; + } + return $R; + break; //$RL = array of row indices; $CL = array of column indices case 'array,array': - list($RL, $CL) = $args; - if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = 0; $i < $m; ++$i) { - for($j = 0; $j < $n; ++$j) { - $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]); - } + list($RL, $CL) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]); } - return $R; - break; + } + return $R; + break; //A($i0...$iF); $CL = array of column indices case 'integer,integer,array': - list($i0, $iF, $CL) = $args; - if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = $i0; $i < $iF; ++$i) { - for($j = 0; $j < $n; ++$j) { - $R->set($i - $i0, $j, $this->A[$RL[$i]][$j]); - } + list($i0, $iF, $CL) = $args; + if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = $i0; $i < $iF; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i - $i0, $j, $this->A[$RL[$i]][$j]); } - return $R; - break; + } + return $R; + break; //$RL = array of row indices case 'array,integer,integer': - list($RL, $j0, $jF) = $args; - if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - $R = new PHPExcel_Shared_JAMA_Matrix($m, $n+1); - for($i = 0; $i < $m; ++$i) { - for($j = $j0; $j <= $jF; ++$j) { - $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]); - } + list($RL, $j0, $jF) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n+1); + for($i = 0; $i < $m; ++$i) { + for($j = $j0; $j <= $jF; ++$j) { + $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]); } - return $R; - break; + } + return $R; + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } } // function getMatrix() - /** * checkMatrixDimensions * @@ -269,7 +267,8 @@ public function getMatrix() { * @param Matrix $B Matrix B * @return boolean */ - public function checkMatrixDimensions($B = null) { + public function checkMatrixDimensions($B = null) + { if ($B instanceof PHPExcel_Shared_JAMA_Matrix) { if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) { return true; @@ -281,8 +280,6 @@ public function checkMatrixDimensions($B = null) { } } // function checkMatrixDimensions() - - /** * set * @@ -292,12 +289,12 @@ public function checkMatrixDimensions($B = null) { * @param mixed $c Int/float/double value * @return mixed Element (int/float/double) */ - public function set($i = null, $j = null, $c = null) { + public function set($i = null, $j = null, $c = null) + { // Optimized set version just has this $this->A[$i][$j] = $c; } // function set() - /** * identity * @@ -306,11 +303,11 @@ public function set($i = null, $j = null, $c = null) { * @param int $n Column dimension * @return Matrix Identity matrix */ - public function identity($m = null, $n = null) { + public function identity($m = null, $n = null) + { return $this->diagonal($m, $n, 1); } // function identity() - /** * diagonal * @@ -320,7 +317,8 @@ public function identity($m = null, $n = null) { * @param mixed $c Diagonal value * @return Matrix Diagonal matrix */ - public function diagonal($m = null, $n = null, $c = 1) { + public function diagonal($m = null, $n = null, $c = 1) + { $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); for($i = 0; $i < $m; ++$i) { $R->set($i, $i, $c); @@ -328,7 +326,6 @@ public function diagonal($m = null, $n = null, $c = 1) { return $R; } // function diagonal() - /** * getMatrixByRow * @@ -337,7 +334,8 @@ public function diagonal($m = null, $n = null, $c = 1) { * @param int $iF Final row index * @return Matrix Submatrix */ - public function getMatrixByRow($i0 = null, $iF = null) { + public function getMatrixByRow($i0 = null, $iF = null) + { if (is_int($i0)) { if (is_int($iF)) { return $this->getMatrix($i0, 0, $iF + 1, $this->n); @@ -349,7 +347,6 @@ public function getMatrixByRow($i0 = null, $iF = null) { } } // function getMatrixByRow() - /** * getMatrixByCol * @@ -358,7 +355,8 @@ public function getMatrixByRow($i0 = null, $iF = null) { * @param int $iF Final column index * @return Matrix Submatrix */ - public function getMatrixByCol($j0 = null, $jF = null) { + public function getMatrixByCol($j0 = null, $jF = null) + { if (is_int($j0)) { if (is_int($jF)) { return $this->getMatrix(0, $j0, $this->m, $jF + 1); @@ -370,14 +368,14 @@ public function getMatrixByCol($j0 = null, $jF = null) { } } // function getMatrixByCol() - /** * transpose * * Tranpose matrix * @return Matrix Transposed matrix */ - public function transpose() { + public function transpose() + { $R = new PHPExcel_Shared_JAMA_Matrix($this->n, $this->m); for($i = 0; $i < $this->m; ++$i) { for($j = 0; $j < $this->n; ++$j) { @@ -387,14 +385,14 @@ public function transpose() { return $R; } // function transpose() - /** * trace * * Sum of diagonal elements * @return float Sum of diagonal elements */ - public function trace() { + public function trace() + { $s = 0; $n = min($this->m, $this->n); for($i = 0; $i < $n; ++$i) { @@ -403,17 +401,16 @@ public function trace() { return $s; } // function trace() - /** * uminus * * Unary minus matrix -A * @return Matrix Unary minus matrix */ - public function uminus() { + public function uminus() + { } // function uminus() - /** * plus * @@ -421,21 +418,26 @@ public function uminus() { * @param mixed $B Matrix/Array * @return Matrix Sum */ - public function plus() { + public function plus() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { @@ -449,7 +451,6 @@ public function plus() { } } // function plus() - /** * plusEquals * @@ -457,26 +458,31 @@ public function plus() { * @param mixed $B Matrix/Array * @return Matrix Sum */ - public function plusEquals() { + public function plusEquals() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { for($j = 0; $j < $this->n; ++$j) { - $validValues = True; + $validValues = true; $value = $M->get($i, $j); if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { $this->A[$i][$j] = trim($this->A[$i][$j],'"'); @@ -499,7 +505,6 @@ public function plusEquals() { } } // function plusEquals() - /** * minus * @@ -507,21 +512,26 @@ public function plusEquals() { * @param mixed $B Matrix/Array * @return Matrix Sum */ - public function minus() { + public function minus() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { @@ -535,7 +545,6 @@ public function minus() { } } // function minus() - /** * minusEquals * @@ -543,26 +552,31 @@ public function minus() { * @param mixed $B Matrix/Array * @return Matrix Sum */ - public function minusEquals() { + public function minusEquals() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { for($j = 0; $j < $this->n; ++$j) { - $validValues = True; + $validValues = true; $value = $M->get($i, $j); if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { $this->A[$i][$j] = trim($this->A[$i][$j],'"'); @@ -585,7 +599,6 @@ public function minusEquals() { } } // function minusEquals() - /** * arrayTimes * @@ -594,21 +607,26 @@ public function minusEquals() { * @param mixed $B Matrix/Array * @return Matrix Matrix Cij */ - public function arrayTimes() { + public function arrayTimes() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { @@ -622,7 +640,6 @@ public function arrayTimes() { } } // function arrayTimes() - /** * arrayTimesEquals * @@ -631,26 +648,31 @@ public function arrayTimes() { * @param mixed $B Matrix/Array * @return Matrix Matrix Aij */ - public function arrayTimesEquals() { + public function arrayTimesEquals() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { for($j = 0; $j < $this->n; ++$j) { - $validValues = True; + $validValues = true; $value = $M->get($i, $j); if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { $this->A[$i][$j] = trim($this->A[$i][$j],'"'); @@ -673,7 +695,6 @@ public function arrayTimesEquals() { } } // function arrayTimesEquals() - /** * arrayRightDivide * @@ -682,26 +703,31 @@ public function arrayTimesEquals() { * @param Matrix $B Matrix B * @return Matrix Division result */ - public function arrayRightDivide() { + public function arrayRightDivide() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { for($j = 0; $j < $this->n; ++$j) { - $validValues = True; + $validValues = true; $value = $M->get($i, $j); if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { $this->A[$i][$j] = trim($this->A[$i][$j],'"'); @@ -738,21 +764,26 @@ public function arrayRightDivide() { * @param mixed $B Matrix/Array * @return Matrix Matrix Aij */ - public function arrayRightDivideEquals() { + public function arrayRightDivideEquals() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { @@ -775,21 +806,26 @@ public function arrayRightDivideEquals() { * @param Matrix $B Matrix B * @return Matrix Division result */ - public function arrayLeftDivide() { + public function arrayLeftDivide() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { @@ -812,21 +848,26 @@ public function arrayLeftDivide() { * @param mixed $B Matrix/Array * @return Matrix Matrix Aij */ - public function arrayLeftDivideEquals() { + public function arrayLeftDivideEquals() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { @@ -848,90 +889,94 @@ public function arrayLeftDivideEquals() { * @param mixed $n Matrix/Array/Scalar * @return Matrix Product */ - public function times() { + public function times() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $B = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - if ($this->n == $B->m) { - $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); - for($j = 0; $j < $B->n; ++$j) { - for ($k = 0; $k < $this->n; ++$k) { - $Bcolj[$k] = $B->A[$k][$j]; - } - for($i = 0; $i < $this->m; ++$i) { - $Arowi = $this->A[$i]; - $s = 0; - for($k = 0; $k < $this->n; ++$k) { - $s += $Arowi[$k] * $Bcolj[$k]; - } - $C->A[$i][$j] = $s; - } + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $B = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + if ($this->n == $B->m) { + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); + for($j = 0; $j < $B->n; ++$j) { + for ($k = 0; $k < $this->n; ++$k) { + $Bcolj[$k] = $B->A[$k][$j]; } - return $C; - } else { - throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); - } - break; - case 'array': - $B = new PHPExcel_Shared_JAMA_Matrix($args[0]); - if ($this->n == $B->m) { - $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { - $s = "0"; - for($k = 0; $k < $C->n; ++$k) { - $s += $this->A[$i][$k] * $B->A[$k][$j]; - } - $C->A[$i][$j] = $s; + for($i = 0; $i < $this->m; ++$i) { + $Arowi = $this->A[$i]; + $s = 0; + for($k = 0; $k < $this->n; ++$k) { + $s += $Arowi[$k] * $Bcolj[$k]; } + $C->A[$i][$j] = $s; } - return $C; - } else { - throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); } - return $M; - break; - case 'integer': - $C = new PHPExcel_Shared_JAMA_Matrix($this->A); + return $C; + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); + } + break; + case 'array': + $B = new PHPExcel_Shared_JAMA_Matrix($args[0]); + if ($this->n == $B->m) { + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); for($i = 0; $i < $C->m; ++$i) { for($j = 0; $j < $C->n; ++$j) { - $C->A[$i][$j] *= $args[0]; + $s = "0"; + for($k = 0; $k < $C->n; ++$k) { + $s += $this->A[$i][$k] * $B->A[$k][$j]; + } + $C->A[$i][$j] = $s; } } return $C; - break; + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); + } + return $M; + break; + case 'integer': + $C = new PHPExcel_Shared_JAMA_Matrix($this->A); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] *= $args[0]; + } + } + return $C; + break; case 'double': - $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $this->n); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { - $C->A[$i][$j] = $args[0] * $this->A[$i][$j]; - } + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $this->n); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] = $args[0] * $this->A[$i][$j]; } - return $C; - break; + } + return $C; + break; case 'float': - $C = new PHPExcel_Shared_JAMA_Matrix($this->A); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { - $C->A[$i][$j] *= $args[0]; - } + $C = new PHPExcel_Shared_JAMA_Matrix($this->A); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] *= $args[0]; } - return $C; - break; + } + return $C; + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } } // function times() - /** * power * @@ -939,26 +984,31 @@ public function times() { * @param mixed $B Matrix/Array * @return Matrix Sum */ - public function power() { + public function power() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - break; + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + break; case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { for($j = 0; $j < $this->n; ++$j) { - $validValues = True; + $validValues = true; $value = $M->get($i, $j); if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { $this->A[$i][$j] = trim($this->A[$i][$j],'"'); @@ -981,7 +1031,6 @@ public function power() { } } // function power() - /** * concat * @@ -989,20 +1038,25 @@ public function power() { * @param mixed $B Matrix/Array * @return Matrix Sum */ - public function concat() { + public function concat() + { if (func_num_args() > 0) { $args = func_get_args(); $match = implode(",", array_map('gettype', $args)); switch ($match) { case 'object': - if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { + $M = $args[0]; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } case 'array': - $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); - break; + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); - break; + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; } $this->checkMatrixDimensions($M); for($i = 0; $i < $this->m; ++$i) { @@ -1016,14 +1070,14 @@ public function concat() { } } // function concat() - /** * Solve A*X = B. * * @param Matrix $B Right hand side * @return Matrix ... Solution if A is square, least squares solution otherwise */ - public function solve($B) { + public function solve($B) + { if ($this->m == $this->n) { $LU = new PHPExcel_Shared_JAMA_LUDecomposition($this); return $LU->solve($B); @@ -1033,24 +1087,24 @@ public function solve($B) { } } // function solve() - /** * Matrix inverse or pseudoinverse. * * @return Matrix ... Inverse(A) if A is square, pseudoinverse otherwise. */ - public function inverse() { + public function inverse() + { return $this->solve($this->identity($this->m, $this->m)); } // function inverse() - /** * det * * Calculate determinant * @return float Determinant */ - public function det() { + public function det() + { $L = new PHPExcel_Shared_JAMA_LUDecomposition($this); return $L->det(); } // function det() diff --git a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php index fa832cafa..c76f9235d 100644 --- a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php @@ -16,8 +16,8 @@ * @license PHP v3.0 * @version 1.1 */ -class PHPExcel_Shared_JAMA_QRDecomposition { - +class PHPExcel_Shared_JAMA_QRDecomposition +{ const MatrixRankException = "Can only perform operation on full-rank matrix."; /** @@ -51,7 +51,8 @@ class PHPExcel_Shared_JAMA_QRDecomposition { * @param matrix $A Rectangular matrix * @return Structure to access R and the Householder vectors and compute Q. */ - public function __construct($A) { + public function __construct($A) + { if ($A instanceof PHPExcel_Shared_JAMA_Matrix) { // Initialize. $this->QR = $A->getArrayCopy(); @@ -98,7 +99,8 @@ public function __construct($A) { * * @return boolean true if R, and hence A, has full rank, else false. */ - public function isFullRank() { + public function isFullRank() + { for ($j = 0; $j < $this->n; ++$j) { if ($this->Rdiag[$j] == 0) { return false; @@ -107,13 +109,13 @@ public function isFullRank() { return true; } // function isFullRank() - /** * Return the Householder vectors * * @return Matrix Lower trapezoidal matrix whose columns define the reflections */ - public function getH() { + public function getH() + { for ($i = 0; $i < $this->m; ++$i) { for ($j = 0; $j < $this->n; ++$j) { if ($i >= $j) { @@ -126,13 +128,13 @@ public function getH() { return new PHPExcel_Shared_JAMA_Matrix($H); } // function getH() - /** * Return the upper triangular factor * * @return Matrix upper triangular factor */ - public function getR() { + public function getR() + { for ($i = 0; $i < $this->n; ++$i) { for ($j = 0; $j < $this->n; ++$j) { if ($i < $j) { @@ -147,13 +149,13 @@ public function getR() { return new PHPExcel_Shared_JAMA_Matrix($R); } // function getR() - /** * Generate and return the (economy-sized) orthogonal factor * * @return Matrix orthogonal factor */ - public function getQ() { + public function getQ() + { for ($k = $this->n-1; $k >= 0; --$k) { for ($i = 0; $i < $this->m; ++$i) { $Q[$i][$k] = 0.0; @@ -184,14 +186,14 @@ public function getQ() { return new PHPExcel_Shared_JAMA_Matrix($Q); } // function getQ() - /** * Least squares solution of A*X = B * * @param Matrix $B A Matrix with as many rows as A and any number of columns. * @return Matrix Matrix that minimizes the two norm of Q*R*X-B. */ - public function solve($B) { + public function solve($B) + { if ($B->getRowDimension() == $this->m) { if ($this->isFullRank()) { // Copy right hand side @@ -230,5 +232,5 @@ public function solve($B) { throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); } } // function solve() +} -} // PHPExcel_Shared_JAMA_class QRDecomposition diff --git a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php index f20668acd..3a36f2991 100644 --- a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php @@ -17,8 +17,8 @@ * @license PHP v3.0 * @version 1.1 */ -class SingularValueDecomposition { - +class SingularValueDecomposition +{ /** * Internal storage of U. * @var array @@ -49,7 +49,6 @@ class SingularValueDecomposition { */ private $n; - /** * Construct the singular value decomposition * @@ -58,8 +57,8 @@ class SingularValueDecomposition { * @param $A Rectangular matrix * @return Structure to access U, S and V. */ - public function __construct($Arg) { - + public function __construct($Arg) + { // Initialize. $A = $Arg->getArrayCopy(); $this->m = $Arg->getRowDimension(); @@ -75,7 +74,6 @@ public function __construct($Arg) { // Reduce A to bidiagonal form, storing the diagonal elements // in s and the super-diagonal elements in e. for ($k = 0; $k < max($nct, $nrt); ++$k) { - if ($k < $nct) { // Compute the transformation for the k-th column and // place the k-th diagonal in s[$k]. @@ -113,7 +111,7 @@ public function __construct($Arg) { } } - if ($wantu AND ($k < $nct)) { + if ($wantu and ($k < $nct)) { // Place the transformation in U for subsequent back // multiplication. for ($i = $k; $i < $this->m; ++$i) { @@ -139,7 +137,7 @@ public function __construct($Arg) { $e[$k+1] += 1.0; } $e[$k] = -$e[$k]; - if (($k+1 < $this->m) AND ($e[$k] != 0.0)) { + if (($k+1 < $this->m) and ($e[$k] != 0.0)) { // Apply the transformation. for ($i = $k+1; $i < $this->m; ++$i) { $work[$i] = 0.0; @@ -198,7 +196,7 @@ public function __construct($Arg) { $this->U[$i][$j] += $t * $this->U[$i][$k]; } } - for ($i = $k; $i < $this->m; ++$i ) { + for ($i = $k; $i < $this->m; ++$i) { $this->U[$i][$k] = -$this->U[$i][$k]; } $this->U[$k][$k] = 1.0 + $this->U[$k][$k]; @@ -217,7 +215,7 @@ public function __construct($Arg) { // If required, generate V. if ($wantv) { for ($k = $this->n - 1; $k >= 0; --$k) { - if (($k < $nrt) AND ($e[$k] != 0.0)) { + if (($k < $nrt) and ($e[$k] != 0.0)) { for ($j = $k + 1; $j < $nu; ++$j) { $t = 0; for ($i = $k + 1; $i < $this->n; ++$i) { @@ -288,145 +286,143 @@ public function __construct($Arg) { switch ($kase) { // Deflate negligible s(p). case 1: - $f = $e[$p-2]; - $e[$p-2] = 0.0; - for ($j = $p - 2; $j >= $k; --$j) { - $t = hypo($this->s[$j], $f); - $cs = $this->s[$j] / $t; - $sn = $f / $t; - $this->s[$j] = $t; - if ($j != $k) { - $f = -$sn * $e[$j-1]; - $e[$j-1] = $cs * $e[$j-1]; - } - if ($wantv) { - for ($i = 0; $i < $this->n; ++$i) { - $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p-1]; - $this->V[$i][$p-1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p-1]; - $this->V[$i][$j] = $t; - } + $f = $e[$p-2]; + $e[$p-2] = 0.0; + for ($j = $p - 2; $j >= $k; --$j) { + $t = hypo($this->s[$j], $f); + $cs = $this->s[$j] / $t; + $sn = $f / $t; + $this->s[$j] = $t; + if ($j != $k) { + $f = -$sn * $e[$j-1]; + $e[$j-1] = $cs * $e[$j-1]; + } + if ($wantv) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p-1]; + $this->V[$i][$p-1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p-1]; + $this->V[$i][$j] = $t; } } - break; + } + break; // Split at negligible s(k). case 2: - $f = $e[$k-1]; - $e[$k-1] = 0.0; - for ($j = $k; $j < $p; ++$j) { - $t = hypo($this->s[$j], $f); - $cs = $this->s[$j] / $t; - $sn = $f / $t; - $this->s[$j] = $t; - $f = -$sn * $e[$j]; - $e[$j] = $cs * $e[$j]; - if ($wantu) { - for ($i = 0; $i < $this->m; ++$i) { - $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k-1]; - $this->U[$i][$k-1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k-1]; - $this->U[$i][$j] = $t; - } + $f = $e[$k-1]; + $e[$k-1] = 0.0; + for ($j = $k; $j < $p; ++$j) { + $t = hypo($this->s[$j], $f); + $cs = $this->s[$j] / $t; + $sn = $f / $t; + $this->s[$j] = $t; + $f = -$sn * $e[$j]; + $e[$j] = $cs * $e[$j]; + if ($wantu) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k-1]; + $this->U[$i][$k-1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k-1]; + $this->U[$i][$j] = $t; } } - break; + } + break; // Perform one qr step. case 3: - // Calculate the shift. - $scale = max(max(max(max( - abs($this->s[$p-1]),abs($this->s[$p-2])),abs($e[$p-2])), - abs($this->s[$k])), abs($e[$k])); - $sp = $this->s[$p-1] / $scale; - $spm1 = $this->s[$p-2] / $scale; - $epm1 = $e[$p-2] / $scale; - $sk = $this->s[$k] / $scale; - $ek = $e[$k] / $scale; - $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0; - $c = ($sp * $epm1) * ($sp * $epm1); - $shift = 0.0; - if (($b != 0.0) || ($c != 0.0)) { - $shift = sqrt($b * $b + $c); - if ($b < 0.0) { - $shift = -$shift; - } - $shift = $c / ($b + $shift); + // Calculate the shift. + $scale = max(max(max(max(abs($this->s[$p-1]), abs($this->s[$p-2])), abs($e[$p-2])), abs($this->s[$k])), abs($e[$k])); + $sp = $this->s[$p-1] / $scale; + $spm1 = $this->s[$p-2] / $scale; + $epm1 = $e[$p-2] / $scale; + $sk = $this->s[$k] / $scale; + $ek = $e[$k] / $scale; + $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0; + $c = ($sp * $epm1) * ($sp * $epm1); + $shift = 0.0; + if (($b != 0.0) || ($c != 0.0)) { + $shift = sqrt($b * $b + $c); + if ($b < 0.0) { + $shift = -$shift; } - $f = ($sk + $sp) * ($sk - $sp) + $shift; - $g = $sk * $ek; - // Chase zeros. - for ($j = $k; $j < $p-1; ++$j) { - $t = hypo($f, $g); - $cs = $f/$t; - $sn = $g/$t; - if ($j != $k) { - $e[$j-1] = $t; - } - $f = $cs * $this->s[$j] + $sn * $e[$j]; - $e[$j] = $cs * $e[$j] - $sn * $this->s[$j]; - $g = $sn * $this->s[$j+1]; - $this->s[$j+1] = $cs * $this->s[$j+1]; - if ($wantv) { - for ($i = 0; $i < $this->n; ++$i) { - $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j+1]; - $this->V[$i][$j+1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j+1]; - $this->V[$i][$j] = $t; - } + $shift = $c / ($b + $shift); + } + $f = ($sk + $sp) * ($sk - $sp) + $shift; + $g = $sk * $ek; + // Chase zeros. + for ($j = $k; $j < $p-1; ++$j) { + $t = hypo($f, $g); + $cs = $f/$t; + $sn = $g/$t; + if ($j != $k) { + $e[$j-1] = $t; + } + $f = $cs * $this->s[$j] + $sn * $e[$j]; + $e[$j] = $cs * $e[$j] - $sn * $this->s[$j]; + $g = $sn * $this->s[$j+1]; + $this->s[$j+1] = $cs * $this->s[$j+1]; + if ($wantv) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j+1]; + $this->V[$i][$j+1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j+1]; + $this->V[$i][$j] = $t; } - $t = hypo($f, $g); - $cs = $f/$t; - $sn = $g/$t; - $this->s[$j] = $t; - $f = $cs * $e[$j] + $sn * $this->s[$j+1]; - $this->s[$j+1] = -$sn * $e[$j] + $cs * $this->s[$j+1]; - $g = $sn * $e[$j+1]; - $e[$j+1] = $cs * $e[$j+1]; - if ($wantu && ($j < $this->m - 1)) { - for ($i = 0; $i < $this->m; ++$i) { - $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j+1]; - $this->U[$i][$j+1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j+1]; - $this->U[$i][$j] = $t; - } + } + $t = hypo($f, $g); + $cs = $f/$t; + $sn = $g/$t; + $this->s[$j] = $t; + $f = $cs * $e[$j] + $sn * $this->s[$j+1]; + $this->s[$j+1] = -$sn * $e[$j] + $cs * $this->s[$j+1]; + $g = $sn * $e[$j+1]; + $e[$j+1] = $cs * $e[$j+1]; + if ($wantu && ($j < $this->m - 1)) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j+1]; + $this->U[$i][$j+1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j+1]; + $this->U[$i][$j] = $t; } } - $e[$p-2] = $f; - $iter = $iter + 1; - break; + } + $e[$p-2] = $f; + $iter = $iter + 1; + break; // Convergence. case 4: - // Make the singular values positive. - if ($this->s[$k] <= 0.0) { - $this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0); - if ($wantv) { - for ($i = 0; $i <= $pp; ++$i) { - $this->V[$i][$k] = -$this->V[$i][$k]; - } + // Make the singular values positive. + if ($this->s[$k] <= 0.0) { + $this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0); + if ($wantv) { + for ($i = 0; $i <= $pp; ++$i) { + $this->V[$i][$k] = -$this->V[$i][$k]; } } - // Order the singular values. - while ($k < $pp) { - if ($this->s[$k] >= $this->s[$k+1]) { - break; - } - $t = $this->s[$k]; - $this->s[$k] = $this->s[$k+1]; - $this->s[$k+1] = $t; - if ($wantv AND ($k < $this->n - 1)) { - for ($i = 0; $i < $this->n; ++$i) { - $t = $this->V[$i][$k+1]; - $this->V[$i][$k+1] = $this->V[$i][$k]; - $this->V[$i][$k] = $t; - } + } + // Order the singular values. + while ($k < $pp) { + if ($this->s[$k] >= $this->s[$k+1]) { + break; + } + $t = $this->s[$k]; + $this->s[$k] = $this->s[$k+1]; + $this->s[$k+1] = $t; + if ($wantv and ($k < $this->n - 1)) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $this->V[$i][$k+1]; + $this->V[$i][$k+1] = $this->V[$i][$k]; + $this->V[$i][$k] = $t; } - if ($wantu AND ($k < $this->m-1)) { - for ($i = 0; $i < $this->m; ++$i) { - $t = $this->U[$i][$k+1]; - $this->U[$i][$k+1] = $this->U[$i][$k]; - $this->U[$i][$k] = $t; - } + } + if ($wantu and ($k < $this->m-1)) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $this->U[$i][$k+1]; + $this->U[$i][$k+1] = $this->U[$i][$k]; + $this->U[$i][$k] = $t; } - ++$k; } - $iter = 0; - --$p; - break; + ++$k; + } + $iter = 0; + --$p; + break; } // end switch } // end while @@ -439,7 +435,8 @@ public function __construct($Arg) { * @access public * @return U */ - public function getU() { + public function getU() + { return new Matrix($this->U, $this->m, min($this->m + 1, $this->n)); } @@ -450,7 +447,8 @@ public function getU() { * @access public * @return V */ - public function getV() { + public function getV() + { return new Matrix($this->V); } @@ -461,7 +459,8 @@ public function getV() { * @access public * @return diagonal of S. */ - public function getSingularValues() { + public function getSingularValues() + { return $this->s; } @@ -472,7 +471,8 @@ public function getSingularValues() { * @access public * @return S */ - public function getS() { + public function getS() + { for ($i = 0; $i < $this->n; ++$i) { for ($j = 0; $j < $this->n; ++$j) { $S[$i][$j] = 0.0; @@ -489,7 +489,8 @@ public function getS() { * @access public * @return max(S) */ - public function norm2() { + public function norm2() + { return $this->s[0]; } @@ -500,7 +501,8 @@ public function norm2() { * @access public * @return max(S)/min(S) */ - public function cond() { + public function cond() + { return $this->s[0] / $this->s[min($this->m, $this->n) - 1]; } @@ -511,7 +513,8 @@ public function cond() { * @access public * @return Number of nonnegligible singular values. */ - public function rank() { + public function rank() + { $eps = pow(2.0, -52.0); $tol = max($this->m, $this->n) * $this->s[0] * $eps; $r = 0; @@ -522,5 +525,4 @@ public function rank() { } return $r; } - -} // class SingularValueDecomposition +} diff --git a/Classes/PHPExcel/Shared/JAMA/utils/Error.php b/Classes/PHPExcel/Shared/JAMA/utils/Error.php index ff51ccc5b..155bcba04 100644 --- a/Classes/PHPExcel/Shared/JAMA/utils/Error.php +++ b/Classes/PHPExcel/Shared/JAMA/utils/Error.php @@ -67,7 +67,8 @@ * Custom error handler * @param int $num Error number */ -function JAMAError($errorNumber = null) { +function JAMAError($errorNumber = null) +{ global $error; if (isset($errorNumber)) { diff --git a/Classes/PHPExcel/Shared/JAMA/utils/Maths.php b/Classes/PHPExcel/Shared/JAMA/utils/Maths.php index 922784c5c..6d4db65a1 100644 --- a/Classes/PHPExcel/Shared/JAMA/utils/Maths.php +++ b/Classes/PHPExcel/Shared/JAMA/utils/Maths.php @@ -11,7 +11,8 @@ * * r = sqrt(a^2 + b^2) without under/overflow. */ -function hypo($a, $b) { +function hypo($a, $b) +{ if (abs($a) > abs($b)) { $r = $b / $a; $r = abs($a) * sqrt(1 + $r * $r); diff --git a/Classes/PHPExcel/Shared/OLE/PPS/Root.php b/Classes/PHPExcel/Shared/OLE/PPS/Root.php index b2278c4e7..e2ae53282 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/Root.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/Root.php @@ -73,8 +73,9 @@ public function save($filename) if (is_resource($filename)) { $this->_FILEH_ = $filename; } else if ($filename == '-' || $filename == '') { - if ($this->_tmp_dir === null) + if ($this->_tmp_dir === null) { $this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir(); + } $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root"); $this->_FILEH_ = fopen($this->_tmp_filename,"w+b"); if ($this->_FILEH_ == false) { @@ -105,8 +106,8 @@ public function save($filename) $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt); if (!is_resource($filename)) { - fclose($this->_FILEH_); - } + fclose($this->_FILEH_); + } return true; } @@ -199,33 +200,35 @@ public function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt) } // Save Header - fwrite($FILE, - "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" - . "\x00\x00\x00\x00" - . "\x00\x00\x00\x00" - . "\x00\x00\x00\x00" - . "\x00\x00\x00\x00" - . pack("v", 0x3b) - . pack("v", 0x03) - . pack("v", -2) - . pack("v", 9) - . pack("v", 6) - . pack("v", 0) - . "\x00\x00\x00\x00" - . "\x00\x00\x00\x00" - . pack("V", $iBdCnt) - . pack("V", $iBBcnt+$iSBDcnt) //ROOT START - . pack("V", 0) - . pack("V", 0x1000) - . pack("V", $iSBDcnt ? 0 : -2) //Small Block Depot - . pack("V", $iSBDcnt) + fwrite( + $FILE, + "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . pack("v", 0x3b) + . pack("v", 0x03) + . pack("v", -2) + . pack("v", 9) + . pack("v", 6) + . pack("v", 0) + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . pack("V", $iBdCnt) + . pack("V", $iBBcnt+$iSBDcnt) //ROOT START + . pack("V", 0) + . pack("V", 0x1000) + . pack("V", $iSBDcnt ? 0 : -2) //Small Block Depot + . pack("V", $iSBDcnt) ); // Extra BDList Start, Count if ($iBdCnt < $i1stBdL) { - fwrite($FILE, - pack("V", -2) // Extra BDList Start - . pack("V", 0) // Extra BDList Count - ); + fwrite( + $FILE, + pack("V", -2) // Extra BDList Start + . pack("V", 0)// Extra BDList Count + ); } else { fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL)); } @@ -258,9 +261,7 @@ public function _saveBigData($iStBlk, &$raList) for ($i = 0; $i < $iCount; ++$i) { if ($raList[$i]->Type != PHPExcel_Shared_OLE::OLE_PPS_TYPE_DIR) { $raList[$i]->Size = $raList[$i]->_DataLen(); - if (($raList[$i]->Size >= PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) || - (($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data))) - { + if (($raList[$i]->Size >= PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) || (($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data))) { // Write Data //if (isset($raList[$i]->_PPS_FILE)) { // $iLen = 0; @@ -366,7 +367,7 @@ public function _savePps(&$raList) $iCnt = count($raList); $iBCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE; if ($iCnt % $iBCnt) { - fwrite($this->_FILEH_, str_repeat("\x00",($iBCnt - ($iCnt % $iBCnt)) * PHPExcel_Shared_OLE::OLE_PPS_SIZE)); + fwrite($this->_FILEH_, str_repeat("\x00", ($iBCnt - ($iCnt % $iBCnt)) * PHPExcel_Shared_OLE::OLE_PPS_SIZE)); } } diff --git a/Classes/PHPExcel/Shared/OLERead.php b/Classes/PHPExcel/Shared/OLERead.php index f43567d74..54b0fadd8 100644 --- a/Classes/PHPExcel/Shared/OLERead.php +++ b/Classes/PHPExcel/Shared/OLERead.php @@ -28,7 +28,8 @@ defined('IDENTIFIER_OLE') || define('IDENTIFIER_OLE', pack('CCCCCCCC', 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1)); -class PHPExcel_Shared_OLERead { +class PHPExcel_Shared_OLERead +{ private $data = ''; // OLE identifier diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index d0c772a5c..3b557a060 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -3136,7 +3136,7 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all $v_extract = true; } } - }else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + } else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { // ----- Look for extract by preg rule if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { $v_extract = true; @@ -3167,7 +3167,6 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all // ----- Look for PCLZIP_OPT_STOP_ON_ERROR if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { - $this->privSwapBackMagicQuotes(); PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, "Filename '".$v_header['stored_filename']."' is compressed by an unsupported compression method (".$v_header['compression'].") "); @@ -3249,9 +3248,8 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all if ($v_result1 == 2) { break; } - } - // ----- Look for extraction in standard output - elseif ((isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + } elseif ((isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Look for extraction in standard output // ----- Extracting the file in standard output $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); if ($v_result1 < 1) { @@ -3369,7 +3367,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { $v_inclusion = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], $p_entry['filename']); if ($v_inclusion == 0) { - PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,"Filename '".$p_entry['filename']."' is outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, "Filename '".$p_entry['filename']."' is outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); return PclZip::errorCode(); } @@ -3410,7 +3408,6 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, if (file_exists($p_entry['filename'])) { // ----- Look if file is a directory if (is_dir($p_entry['filename'])) { - // ----- Change the file status $p_entry['status'] = "already_a_directory"; @@ -3444,21 +3441,19 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Newer version of '".$p_entry['filename']."' exists and option PCLZIP_OPT_REPLACE_NEWER is not selected"); - return PclZip::errorCode(); - } + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Newer version of '".$p_entry['filename']."' exists and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + return PclZip::errorCode(); + } } } else { } } else { - // ----- Check the directory availability and create it if necessary + // ----- Check the directory availability and create it if necessary if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) { $v_dir_to_check = $p_entry['filename']; - } - else if (!strstr($p_entry['filename'], "/")) { + } else if (!strstr($p_entry['filename'], "/")) { $v_dir_to_check = ""; - } - else { + } else { $v_dir_to_check = dirname($p_entry['filename']); } @@ -3530,7 +3525,6 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, $v_file_content = @gzinflate($v_buffer); unset($v_buffer); if ($v_file_content === false) { - // ----- Change the file status // TBC $p_entry['status'] = "error"; @@ -3540,7 +3534,6 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, // ----- Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - // ----- Change the file status $p_entry['status'] = "write_error"; @@ -3723,7 +3716,6 @@ function privExtractFileInOutput(&$p_entry, &$p_options) if (!(($p_entry['external']&0x00000010)==0x00000010)) { // ----- Look for not compressed file if ($p_entry['compressed_size'] == $p_entry['size']) { - // ----- Read the file in a buffer (one shot) $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); @@ -3731,7 +3723,6 @@ function privExtractFileInOutput(&$p_entry, &$p_options) echo $v_buffer; unset($v_buffer); } else { - // ----- Read the compressed file in a buffer (one shot) $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); @@ -3791,7 +3782,7 @@ function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) // ----- Check that the file header is coherent with $p_entry info if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - // TBC + // TBC } // ----- Look for pre-extract callback @@ -3830,17 +3821,15 @@ function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) // ----- Look for not compressed file // if ($p_entry['compressed_size'] == $p_entry['size']) if ($p_entry['compression'] == 0) { - // ----- Reading the file $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); } else { - // ----- Reading the file $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); // ----- Decompress the file if (($p_string = @gzinflate($v_data)) === false) { - // TBC + // TBC } } // ----- Trace @@ -4037,8 +4026,7 @@ function privReadCentralFileHeader(&$p_header) // ----- Get comment if ($p_header['comment_len'] != 0) { $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); - } - else { + } else { $p_header['comment'] = ''; } @@ -4112,9 +4100,9 @@ function privCheckFileHeaders(&$p_local_header, &$p_central_header) // ----- Look for flag bit 3 if (($p_local_header['flag'] & 8) == 8) { - $p_local_header['size'] = $p_central_header['size']; - $p_local_header['compressed_size'] = $p_central_header['compressed_size']; - $p_local_header['crc'] = $p_central_header['crc']; + $p_local_header['size'] = $p_central_header['size']; + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + $p_local_header['crc'] = $p_central_header['crc']; } // ----- Return @@ -4171,8 +4159,9 @@ function privReadEndCentralDir(&$p_central_dir) // ----- Go back to the maximum possible size of the Central Dir End Record if (!$v_found) { $v_maximum_size = 65557; // 0xFFFF + 22; - if ($v_maximum_size > $v_size) + if ($v_maximum_size > $v_size) { $v_maximum_size = $v_size; + } @fseek($this->zip_fd, $v_size-$v_maximum_size); if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) { // ----- Error log @@ -4196,8 +4185,7 @@ function privReadEndCentralDir(&$p_central_dir) $v_bytes = (($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); // ----- Compare the bytes - if ($v_bytes == 0x504b0506) - { + if ($v_bytes == 0x504b0506) { $v_pos++; break; } @@ -4342,27 +4330,13 @@ function privDeleteByRule(&$p_result_list, &$p_options) } elseif ((($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { $v_found = true; } - } - // ----- Look for a filename - elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + } elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + // ----- Look for a filename $v_found = true; } } - } - // ----- Look for extract by ereg rule - // ereg() is deprecated with PHP 5.3 - /* - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { - $v_found = true; - } - } - */ - else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) - // ----- Look for extract by preg rule - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + } else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + // ----- Look for extract by preg rule if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { $v_found = true; } @@ -4371,14 +4345,13 @@ function privDeleteByRule(&$p_result_list, &$p_options) // ----- Look if the index is in the list for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_found = true; + $v_found = true; } if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; + $j_start = $j+1; } - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; + break; } } } else { @@ -4608,7 +4581,6 @@ function privMerge(&$p_archive_to_add) // ----- Look if the archive_to_add exists if (!is_file($p_archive_to_add->zipname)) { - // ----- Nothing to merge, so merge is a success $v_result = 1; @@ -4618,7 +4590,6 @@ function privMerge(&$p_archive_to_add) // ----- Look if the archive exists if (!is_file($this->zipname)) { - // ----- Do a duplicate $v_result = $this->privDuplicate($p_archive_to_add->zipname); @@ -4781,7 +4752,6 @@ function privDuplicate($p_archive_filename) // ----- Look if the $p_archive_filename exists if (!is_file($p_archive_filename)) { - // ----- Nothing to duplicate, so duplicate is a success. $v_result = 1; @@ -4970,8 +4940,7 @@ function PclZipUtilPathReduction($p_dir) // ----- Look for item to skip if ($v_skip > 0) { $v_skip--; - } - else { + } else { $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); } } @@ -5051,8 +5020,12 @@ function PclZipUtilPathInclusion($p_dir, $p_path) // ----- Look if everything seems to be the same if ($v_result) { // ----- Skip all the empty items - while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; - while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) { + $j++; + } + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) { + $i++; + } if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { // ----- There are exactly the same @@ -5160,7 +5133,6 @@ function PclZipUtilRename($p_src, $p_dest) // -------------------------------------------------------------------------------- function PclZipUtilOptionText($p_option) { - $v_list = get_defined_constants(); for (reset($v_list); $v_key = key($v_list); next($v_list)) { $v_prefix = substr($v_key, 0, 10); @@ -5191,13 +5163,12 @@ function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter = true) if (stristr(php_uname(), 'windows')) { // ----- Look for potential disk letter if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { - $p_path = substr($p_path, $v_position+1); + $p_path = substr($p_path, $v_position+1); } // ----- Change potential windows directory separator - if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { - $p_path = strtr($p_path, '\\', '/'); + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); } } return $p_path; } -// -------------------------------------------------------------------------------- \ No newline at end of file From 09352e3e80bea9f4792aa2218d4a6599e41db0a0 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sun, 17 May 2015 15:00:02 +0200 Subject: [PATCH 384/467] PSR2 Fixes --- Classes/PHPExcel/Reader/CSV.php | 3 +- Classes/PHPExcel/Reader/Excel2003XML.php | 8 +- Classes/PHPExcel/Reader/Excel2007.php | 13 +- Classes/PHPExcel/Reader/Excel2007/Chart.php | 38 +- Classes/PHPExcel/Reader/Excel5.php | 68 +- Classes/PHPExcel/Reader/Gnumeric.php | 12 +- Classes/PHPExcel/Reader/OOCalc.php | 74 +- Classes/PHPExcel/Reader/SYLK.php | 2 +- .../Shared/JAMA/EigenvalueDecomposition.php | 6 +- Classes/PHPExcel/Shared/JAMA/Matrix.php | 198 +++-- .../PHPExcel/Shared/JAMA/QRDecomposition.php | 1 - .../JAMA/SingularValueDecomposition.php | 2 +- Classes/PHPExcel/Shared/OLE/PPS/Root.php | 4 +- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 1 - .../PHPExcel/Calculation/DateTimeTest.php | 548 ++++++------ .../PHPExcel/Calculation/EngineeringTest.php | 796 +++++++++--------- .../PHPExcel/Calculation/FinancialTest.php | 560 ++++++------ .../PHPExcel/Calculation/FunctionsTest.php | 332 ++++---- .../PHPExcel/Calculation/LogicalTest.php | 102 +-- .../PHPExcel/Calculation/LookupRefTest.php | 38 +- .../PHPExcel/Calculation/MathTrigTest.php | 530 ++++++------ .../PHPExcel/Calculation/TextDataTest.php | 398 ++++----- .../PHPExcel/Cell/AdvancedValueBinderTest.php | 12 +- .../Classes/PHPExcel/Cell/DataTypeTest.php | 16 +- .../PHPExcel/Cell/DefaultValueBinderTest.php | 40 +- .../Classes/PHPExcel/Cell/HyperlinkTest.php | 110 +-- unitTests/Classes/PHPExcel/CellTest.php | 372 ++++---- .../PHPExcel/Chart/DataSeriesValuesTest.php | 80 +- .../Classes/PHPExcel/Chart/LayoutTest.php | 32 +- .../Classes/PHPExcel/Chart/LegendTest.php | 238 +++--- .../PHPExcel/Reader/XEEValidatorTest.php | 30 +- .../Classes/PHPExcel/ReferenceHelperTest.php | 84 +- .../Classes/PHPExcel/Shared/CodePageTest.php | 60 +- .../Classes/PHPExcel/Shared/DateTest.php | 240 +++--- .../Classes/PHPExcel/Shared/FileTest.php | 48 +- .../Classes/PHPExcel/Shared/FontTest.php | 102 +-- .../PHPExcel/Shared/PasswordHasherTest.php | 20 +- .../Classes/PHPExcel/Shared/StringTest.php | 134 +-- .../Classes/PHPExcel/Shared/TimeZoneTest.php | 42 +- .../Classes/PHPExcel/Style/ColorTest.php | 74 +- .../PHPExcel/Style/NumberFormatTest.php | 24 +- .../Worksheet/AutoFilter/Column/RuleTest.php | 174 ++-- .../Worksheet/AutoFilter/ColumnTest.php | 282 +++---- .../PHPExcel/Worksheet/AutoFilterTest.php | 568 ++++++------- .../PHPExcel/Worksheet/CellCollectionTest.php | 44 +- .../Worksheet/ColumnCellIteratorTest.php | 34 +- .../PHPExcel/Worksheet/ColumnIteratorTest.php | 34 +- .../Worksheet/RowCellIteratorTest.php | 34 +- .../PHPExcel/Worksheet/RowIteratorTest.php | 34 +- .../Worksheet/WorksheetColumnTest.php | 30 +- .../PHPExcel/Worksheet/WorksheetRowTest.php | 30 +- unitTests/testDataFileIterator.php | 32 +- 52 files changed, 3417 insertions(+), 3371 deletions(-) diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index c8c5fbb93..c168310e4 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -387,7 +387,8 @@ public function setContiguous($contiguous = false) * * @return boolean */ - public function getContiguous(){ + public function getContiguous() + { return $this->_contiguous; } } diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index c5360cfbd..f27c8c8a1 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -257,11 +257,11 @@ protected static function identifyFixedStyleValue($styleList, &$styleAttributeVa */ protected static function _pixel2WidthUnits($pxs) { - $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); + $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); - $widthUnits = 256 * ($pxs / 7); - $widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)]; - return $widthUnits; + $widthUnits = 256 * ($pxs / 7); + $widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)]; + return $widthUnits; } /** diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 6c1ded0d3..cc2616ae0 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -998,16 +998,14 @@ public function load($pFilename) // Standard filters are always an OR join, so no join rule needs to be set // Entries can be either filter elements foreach ($filters->filter as $filterRule) { - $column->createRule()->setRule( - null,// Operator is undefined, but always treated as EQUAL - (string) $filterRule["val"] - ) - ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + // Operator is undefined, but always treated as EQUAL + $column->createRule()->setRule(null, (string) $filterRule["val"])->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); } // Or Date Group elements foreach ($filters->dateGroupItem as $dateGroupItem) { $column->createRule()->setRule( - null,// Operator is undefined, but always treated as EQUAL + // Operator is undefined, but always treated as EQUAL + null, array( 'year' => (string) $dateGroupItem["year"], 'month' => (string) $dateGroupItem["month"], @@ -1044,7 +1042,8 @@ public function load($pFilename) // We should only ever have one dynamic filter foreach ($filterColumn->dynamicFilter as $filterRule) { $column->createRule()->setRule( - null,// Operator is undefined, but always treated as EQUAL + // Operator is undefined, but always treated as EQUAL + null, (string) $filterRule["val"], (string) $filterRule["type"] ) diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index 222c54667..4569f2679 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Chart.php +++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php @@ -81,21 +81,21 @@ public static function readChart($chartElements, $chartName) foreach ($chartDetails as $chartDetailKey => $chartDetail) { switch ($chartDetailKey) { case "layout": - $plotAreaLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta,'plotArea'); + $plotAreaLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta, 'plotArea'); break; case "catAx": if (isset($chartDetail->title)) { - $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); } break; case "dateAx": if (isset($chartDetail->title)) { - $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); } break; case "valAx": if (isset($chartDetail->title)) { - $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta,'cat'); + $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); } break; case "barChart": @@ -173,7 +173,7 @@ public static function readChart($chartElements, $chartName) $dispBlanksAs = self::_getAttribute($chartDetails, 'val', 'string'); break; case "title": - $title = self::_chartTitle($chartDetails, $namespacesChartMeta,'title'); + $title = self::_chartTitle($chartDetails, $namespacesChartMeta, 'title'); break; case "legend": $legendPos = 'r'; @@ -188,7 +188,7 @@ public static function readChart($chartElements, $chartName) $legendOverlay = self::_getAttribute($chartDetail, 'val', 'boolean'); break; case "layout": - $legendLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta,'legend'); + $legendLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta, 'legend'); break; } } @@ -239,7 +239,7 @@ private static function _chartLayoutDetails($chartDetail, $namespacesChartMeta) } $layout = array(); foreach ($details as $detailKey => $detail) { -// echo $detailKey,' => ',self::_getAttribute($detail, 'val', 'string'),PHP_EOL; +// echo $detailKey, ' => ',self::_getAttribute($detail, 'val', 'string'),PHP_EOL; $layout[$detailKey] = self::_getAttribute($detail, 'val', 'string'); } return new PHPExcel_Chart_Layout($layout); @@ -300,7 +300,7 @@ private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChart { if (isset($seriesDetail->strRef)) { $seriesSource = (string) $seriesDetail->strRef->f; - $seriesData = self::_chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']),'s'); + $seriesData = self::_chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']), 's'); return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } elseif (isset($seriesDetail->numRef)) { @@ -310,13 +310,13 @@ private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChart return new PHPExcel_Chart_DataSeriesValues('Number', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } elseif (isset($seriesDetail->multiLvlStrRef)) { $seriesSource = (string) $seriesDetail->multiLvlStrRef->f; - $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']),'s'); + $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']), 's'); $seriesData['pointCount'] = count($seriesData['dataValues']); return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } elseif (isset($seriesDetail->multiLvlNumRef)) { $seriesSource = (string) $seriesDetail->multiLvlNumRef->f; - $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']),'s'); + $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']), 's'); $seriesData['pointCount'] = count($seriesData['dataValues']); return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); @@ -400,7 +400,7 @@ private static function _parseRichText($titleDetailPart = null) foreach ($titleDetailPart as $titleDetailElementKey => $titleDetailElement) { if (isset($titleDetailElement->t)) { - $objText = $value->createTextRun( (string) $titleDetailElement->t ); + $objText = $value->createTextRun((string) $titleDetailElement->t); } if (isset($titleDetailElement->rPr)) { if (isset($titleDetailElement->rPr->rFont["val"])) { @@ -414,7 +414,7 @@ private static function _parseRichText($titleDetailPart = null) $fontColor = (self::_getAttribute($titleDetailElement->rPr, 'color', 'string')); if (!is_null($fontColor)) { - $objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($fontColor) ) ); + $objText->getFont()->setColor(new PHPExcel_Style_Color(self::_readColor($fontColor))); } $bold = self::_getAttribute($titleDetailElement->rPr, 'b', 'boolean'); @@ -495,25 +495,25 @@ private static function _setChartAttributes($plotArea, $plotAttributes) { foreach ($plotAttributes as $plotAttributeKey => $plotAttributeValue) { switch ($plotAttributeKey) { - case 'showLegendKey' : + case 'showLegendKey': $plotArea->setShowLegendKey($plotAttributeValue); break; - case 'showVal' : + case 'showVal': $plotArea->setShowVal($plotAttributeValue); break; - case 'showCatName' : + case 'showCatName': $plotArea->setShowCatName($plotAttributeValue); break; - case 'showSerName' : + case 'showSerName': $plotArea->setShowSerName($plotAttributeValue); break; - case 'showPercent' : + case 'showPercent': $plotArea->setShowPercent($plotAttributeValue); break; - case 'showBubbleSize' : + case 'showBubbleSize': $plotArea->setShowBubbleSize($plotAttributeValue); break; - case 'showLeaderLines' : + case 'showLeaderLines': $plotArea->setShowLeaderLines($plotAttributeValue); break; } diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 8b87bf3d7..5fd36cce4 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -559,7 +559,6 @@ public function listWorksheetInfo($pFilename) // Parse the individual sheets foreach ($this->_sheets as $sheet) { - if ($sheet['sheetType'] != 0x00) { // 0x00: Worksheet // 0x02: Chart @@ -811,7 +810,7 @@ public function load($pFilename) // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet // name in line with the formula, not the reverse - $this->_phpSheet->setTitle($sheet['name'],false); + $this->_phpSheet->setTitle($sheet['name'], false); $this->_phpSheet->setSheetState($sheet['sheetState']); $this->_pos = $sheet['offset']; @@ -1133,7 +1132,7 @@ public function load($pFilename) // echo '<b>Cell annotation ', $note,'</b><br />'; // var_dump($noteDetails); // echo '<br />'; - $cellAddress = str_replace('$','', $noteDetails['cellRef']); + $cellAddress = str_replace('$', '', $noteDetails['cellRef']); $this->_phpSheet->getComment($cellAddress)->setAuthor($noteDetails['author'])->setText($this->_parseRichText($noteDetails['objTextData']['text'])); } } @@ -1185,7 +1184,6 @@ public function load($pFilename) $explodes = explode('!', $range); if (count($explodes) == 2) { if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) { - $extractedRange = $explodes[1]; $extractedRange = str_replace('$', '', $extractedRange); @@ -1213,7 +1211,7 @@ public function load($pFilename) if (count($explodes) == 2) { if (($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) || - ($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0],"'")))) { + ($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0], "'")))) { $extractedRange = $explodes[1]; $extractedRange = str_replace('$', '', $extractedRange); @@ -1236,11 +1234,11 @@ public function load($pFilename) /** * Read record data from stream, decrypting as required - * + * * @param string $data Data stream to read from * @param int $pos Position to start reading from * @param int $length Record data length - * + * * @return string Record data */ private function _readRecordData($data, $pos, $len) @@ -1639,7 +1637,7 @@ private function _readNote() } // echo 'Note Address=', $cellAddress,'<br />'; - $cellAddress = str_replace('$','', $cellAddress); + $cellAddress = str_replace('$', '', $cellAddress); $noteLength = self::_GetInt2d($recordData, 4); $noteText = trim(substr($recordData, 6)); // echo 'Note Length=', $noteLength,'<br />'; @@ -1748,7 +1746,7 @@ private function _readBof() * * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" - * + * * The decryption functions and objects used from here on in * are based on the source of Spreadsheet-ParseExcel: * http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/ @@ -1778,10 +1776,10 @@ private function _readFilepass() /** * Make an RC4 decryptor for the given block - * + * * @var int $block Block for which to create decrypto * @var string $valContext MD5 context state - * + * * @return PHPExcel_Reader_Excel5_RC4 */ private function _makeKey($block, $valContext) @@ -1809,13 +1807,13 @@ private function _makeKey($block, $valContext) /** * Verify RC4 file password - * + * * @var string $password Password to check * @var string $docid Document id * @var string $salt_data Salt data * @var string $hashedsalt_data Hashed salt data * @var string &$valContext Set to the MD5 context of the value - * + * * @return bool Success */ private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext) @@ -1965,12 +1963,16 @@ private function _readFont() // bit: 0; mask 0x0001; bold (redundant in BIFF5-BIFF8) // bit: 1; mask 0x0002; italic $isItalic = (0x0002 & self::_GetInt2d($recordData, 2)) >> 1; - if ($isItalic) $objFont->setItalic(true); + if ($isItalic) { + $objFont->setItalic(true); + } // bit: 2; mask 0x0004; underlined (redundant in BIFF5-BIFF8) // bit: 3; mask 0x0008; strike $isStrike = (0x0008 & self::_GetInt2d($recordData, 2)) >> 3; - if ($isStrike) $objFont->setStrikethrough(true); + if ($isStrike) { + $objFont->setStrikethrough(true); + } // offset: 4; size: 2; colour index $colorIndex = self::_GetInt2d($recordData, 4); @@ -2557,11 +2559,11 @@ private function _readStyle() $builtInId = ord($recordData{2}); switch ($builtInId) { - case 0x00: - // currently, we are not using this for anything - break; - default: - break; + case 0x00: + // currently, we are not using this for anything + break; + default: + break; } } else { // user-defined; not supported by PHPExcel @@ -2891,7 +2893,6 @@ private function _readSst() // loop through the Unicode strings (16-bit length) for ($i = 0; $i < $nm; ++$i) { - // number of characters in the Unicode string $numChars = self::_GetInt2d($recordData, $pos); $pos += 2; @@ -3923,21 +3924,18 @@ private function _readFormula() } elseif ((ord($recordData{6}) == 1) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { - // Boolean formula. Result is in +2; 0=false, 1=true $dataType = PHPExcel_Cell_DataType::TYPE_BOOL; $value = (bool) ord($recordData{8}); } elseif ((ord($recordData{6}) == 2) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { - // Error formula. Error code is in +2 $dataType = PHPExcel_Cell_DataType::TYPE_ERROR; $value = self::_mapErrorCode(ord($recordData{8})); } elseif ((ord($recordData{6}) == 3) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { - // Formula result is a null string $dataType = PHPExcel_Cell_DataType::TYPE_NULL; $value = ''; @@ -4352,7 +4350,8 @@ private function _readWindow2() /** * Read PLV Record(Created by Excel2007 or upper) */ - private function _readPageLayoutView() { + private function _readPageLayoutView() + { $length = self::_GetInt2d($this->_data, $this->_pos + 2); $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); @@ -4528,7 +4527,7 @@ private function _readMergedCells() if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData); foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) { - if ((strpos($cellRangeAddress,':') !== false) && + if ((strpos($cellRangeAddress, ':') !== false) && ($this->_includeCellRangeFiltered($cellRangeAddress))) { $this->_phpSheet->mergeCells($cellRangeAddress); } @@ -4620,8 +4619,9 @@ private function _readHyperLink() // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); $nullOffset = strpos($url, 0x00); - if ($nullOffset) - $url = substr($url,0, $nullOffset); + if ($nullOffset) { + $url = substr($url, 0, $nullOffset); + } $url .= $hasText ? '#' : ''; $offset += $us; break; @@ -5328,7 +5328,7 @@ private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas * @return string Human readable formula */ - private function _getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1') + private function _getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1') { // start parsing the formula data $tokens = array(); @@ -7468,13 +7468,13 @@ private static function _extractNumber($data) $mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); $mantissalow1 = ($rknumlow & 0x80000000) >> 31; $mantissalow2 = ($rknumlow & 0x7fffffff); - $value = $mantissa / pow(2 , (20 - $exp)); + $value = $mantissa / pow(2, (20 - $exp)); if ($mantissalow1 != 0) { - $value += 1 / pow (2 , (21 - $exp)); + $value += 1 / pow (2, (21 - $exp)); } - $value += $mantissalow2 / pow (2 , (52 - $exp)); + $value += $mantissalow2 / pow (2, (52 - $exp)); if ($sign) { $value *= -1; } @@ -7496,7 +7496,7 @@ private static function _GetIEEE754($rknum) $sign = ($rknum & 0x80000000) >> 31; $exp = ($rknum & 0x7ff00000) >> 20; $mantissa = (0x100000 | ($rknum & 0x000ffffc)); - $value = $mantissa / pow(2 , (20- ($exp - 1023))); + $value = $mantissa / pow(2, (20- ($exp - 1023))); if ($sign) { $value = -1 * $value; } @@ -7520,7 +7520,7 @@ private static function _encodeUTF16($string, $compressed = '') { if ($compressed) { $string = self::_uncompressByteString($string); - } + } return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE'); } diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index f67f3231f..2a187b3ba 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -115,7 +115,7 @@ public function listWorksheetNames($pFilename) $xml = new XMLReader(); $xml->xml($this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions()); - $xml->setParserProperty(2,true); + $xml->setParserProperty(2, true); $worksheetNames = array(); while ($xml->read()) { @@ -467,7 +467,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } if ((!$this->_readDataOnly) && (isset($sheet->Objects))) { - foreach ($sheet->Objects->children('gnm',TRUE) as $key => $comment) { + foreach ($sheet->Objects->children('gnm', true) as $key => $comment) { $commentAttributes = $comment->attributes(); // Only comment objects are handled at the moment if ($commentAttributes->Text) { @@ -481,7 +481,6 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $styleAttributes = $styleRegion->attributes(); if (($styleAttributes['startRow'] <= $maxRow) && ($styleAttributes['startCol'] <= $maxCol)) { - $startColumn = PHPExcel_Cell::stringFromColumnIndex((int) $styleAttributes['startCol']); $startRow = $styleAttributes['startRow'] + 1; @@ -748,7 +747,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Handle Merged Cells in this worksheet if (isset($sheet->MergedRegions)) { foreach ($sheet->MergedRegions->Merge as $mergeCells) { - if (strpos($mergeCells,':') !== false) { + if (strpos($mergeCells, ':') !== false) { $objPHPExcel->getActiveSheet()->mergeCells($mergeCells); } } @@ -767,7 +766,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } $range = explode('!', $range); - $range[0] = trim($range[0],"'");; + $range[0] = trim($range[0], "'"); if ($worksheet = $objPHPExcel->getSheetByName($range[0])) { $extractedRange = str_replace('$', '', $range[1]); $objPHPExcel->addNamedRange(new PHPExcel_NamedRange($name, $worksheet, $extractedRange)); @@ -844,7 +843,8 @@ private function _parseRichText($is = '') return $value; } - private static function _parseGnumericColour($gnmColour) { + private static function _parseGnumericColour($gnmColour) + { list($gnmR, $gnmG, $gnmB) = explode(':', $gnmColour); $gnmR = substr(str_pad($gnmR, 4, '0', STR_PAD_RIGHT), 0, 2); $gnmG = substr(str_pad($gnmG, 4, '0', STR_PAD_RIGHT), 0, 2); diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 21a35bf72..cca5a23b6 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -54,7 +54,8 @@ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExce /** * Create a new PHPExcel_Reader_OOCalc */ - public function __construct() { + public function __construct() + { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); } @@ -304,7 +305,7 @@ public function load($pFilename) return $this->loadIntoExisting($pFilename, $objPHPExcel); } - private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) + private static function identifyFixedStyleValue($styleList, &$styleAttributeValue) { $styleAttributeValue = strtolower($styleAttributeValue); foreach ($styleList as $style) { @@ -358,22 +359,22 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($officePropertyDC as $propertyName => $propertyValue) { $propertyValue = (string) $propertyValue; switch ($propertyName) { - case 'title' : + case 'title': $docProps->setTitle($propertyValue); break; - case 'subject' : + case 'subject': $docProps->setSubject($propertyValue); break; - case 'creator' : + case 'creator': $docProps->setCreator($propertyValue); $docProps->setLastModifiedBy($propertyValue); break; - case 'date' : + case 'date': $creationDate = strtotime($propertyValue); $docProps->setCreated($creationDate); $docProps->setModified($creationDate); break; - case 'description' : + case 'description': $docProps->setDescription($propertyValue); break; } @@ -386,36 +387,36 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']); $propertyValue = (string) $propertyValue; switch ($propertyName) { - case 'initial-creator' : + case 'initial-creator': $docProps->setCreator($propertyValue); break; - case 'keyword' : + case 'keyword': $docProps->setKeywords($propertyValue); break; - case 'creation-date' : + case 'creation-date': $creationDate = strtotime($propertyValue); $docProps->setCreated($creationDate); break; - case 'user-defined' : + case 'user-defined': $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; foreach ($propertyValueAttributes as $key => $value) { if ($key == 'name') { $propertyValueName = (string) $value; } elseif ($key == 'value-type') { switch ($value) { - case 'date' : + case 'date': $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue, 'date'); $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; break; - case 'boolean' : + case 'boolean': $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue, 'bool'); $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; break; - case 'float' : + case 'float': $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue, 'r4'); $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; break; - default : + default: $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; } } @@ -459,7 +460,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in // formula cells... during the load, all formulae should be correct, and we're simply // bringing the worksheet name in line with the formula, not the reverse - $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + $objPHPExcel->getActiveSheet()->setTitle($worksheetName, false); } $rowID = 1; @@ -471,10 +472,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $rowData = $cellData; break; } - case 'table-row' : + case 'table-row': $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); - $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? - $rowDataTableAttributes['number-rows-repeated'] : 1; + $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? $rowDataTableAttributes['number-rows-repeated'] : 1; $columnID = 'A'; foreach ($rowData as $key => $cellData) { if ($this->getReadFilter() !== null) { @@ -484,9 +484,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } // echo '<b>'.$columnID.$rowID.'</b><br />'; - $cellDataText = (isset($namespacesContent['text'])) ? - $cellData->children($namespacesContent['text']) : - ''; + $cellDataText = (isset($namespacesContent['text'])) ? $cellData->children($namespacesContent['text']) : ''; $cellDataOffice = $cellData->children($namespacesContent['office']); $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']); $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']); @@ -522,9 +520,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } $text = implode("\n", $textArray); // echo $text, '<br />'; - $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) + $objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setText($this->_parseRichText($text)); // ->setAuthor( $author ) - ->setText($this->_parseRichText($text) ); } if (isset($cellDataText->p)) { @@ -550,7 +547,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />'; switch ($cellDataOfficeAttributes['value-type']) { - case 'string' : + case 'string': $type = PHPExcel_Cell_DataType::TYPE_STRING; $dataValue = $allCellDataText; if (isset($dataValue->a)) { @@ -559,11 +556,11 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $hyperlink = $cellXLinkAttributes['href']; } break; - case 'boolean' : - $type = PHPExcel_Cell_DataType::TYPE_BOOL; - $dataValue = ($allCellDataText == 'TRUE') ? true : false; - break; - case 'percentage' : + case 'boolean': + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $dataValue = ($allCellDataText == 'TRUE') ? true : false; + break; + case 'percentage': $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; $dataValue = (float) $cellDataOfficeAttributes['value']; if (floor($dataValue) == $dataValue) { @@ -571,7 +568,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } $formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00; break; - case 'currency' : + case 'currency': $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; $dataValue = (float) $cellDataOfficeAttributes['value']; if (floor($dataValue) == $dataValue) { @@ -579,17 +576,18 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } $formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE; break; - case 'float' : + case 'float': $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; $dataValue = (float) $cellDataOfficeAttributes['value']; if (floor($dataValue) == $dataValue) { - if ($dataValue == (integer) $dataValue) + if ($dataValue == (integer) $dataValue) { $dataValue = (integer) $dataValue; - else + } else { $dataValue = (float) $dataValue; + } } break; - case 'date' : + case 'date': $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; $dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT); $dateObj->setTimeZone($timezoneObj); @@ -601,9 +599,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15; } break; - case 'time' : + case 'time': $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'], 'PT%dH%dM%dS')))); + $dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':', sscanf($cellDataOfficeAttributes['time-value'], 'PT%dH%dM%dS')))); $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; break; } @@ -619,7 +617,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if ($hasCalculatedValue) { $type = PHPExcel_Cell_DataType::TYPE_FORMULA; // echo 'Formula: ', $cellDataFormula, PHP_EOL; - $cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula, ':=')+1); + $cellDataFormula = substr($cellDataFormula, strpos($cellDataFormula, ':=')+1); $temp = explode('"', $cellDataFormula); $tKey = false; foreach ($temp as &$value) { diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index 51c80605b..2fc4967f8 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -269,7 +269,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $formatArray['font']['size'] = substr($rowDatum, 1); break; case 'S': - $styleSettings = substr($rowDatum,1); + $styleSettings = substr($rowDatum, 1); for ($i=0; $i<strlen($styleSettings); ++$i) { switch ($styleSettings{$i}) { case 'I': diff --git a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php index 9a19ba52a..b8e42d233 100644 --- a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php @@ -72,7 +72,7 @@ class EigenvalueDecomposition * * @access private */ - private function tred2 () + private function tred2() { // This is derived from the Algol procedures tred2 by // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for @@ -189,7 +189,7 @@ private function tql2() $this->e[$this->n-1] = 0.0; $f = 0.0; $tst1 = 0.0; - $eps = pow(2.0,-52.0); + $eps = pow(2.0, -52.0); for ($l = 0; $l < $this->n; ++$l) { // Find small subdiagonal element @@ -741,7 +741,7 @@ private function hqr2() } } // Overflow control - $t = max(abs($this->H[$i][$n-1]),abs($this->H[$i][$n])); + $t = max(abs($this->H[$i][$n-1]), abs($this->H[$i][$n])); if (($eps * $t) * $t > 1) { for ($j = $i; $j <= $n; ++$j) { $this->H[$j][$n-1] = $this->H[$j][$n-1] / $t; diff --git a/Classes/PHPExcel/Shared/JAMA/Matrix.php b/Classes/PHPExcel/Shared/JAMA/Matrix.php index c245cc867..dfb450fda 100644 --- a/Classes/PHPExcel/Shared/JAMA/Matrix.php +++ b/Classes/PHPExcel/Shared/JAMA/Matrix.php @@ -95,8 +95,8 @@ public function __construct() $this->n = 0; } if (($this->m * $this->n) == count($args[0])) { - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $this->A[$i][$j] = $args[0][$i + $j * $this->m]; } } @@ -176,11 +176,19 @@ public function getMatrix() //A($i0...; $j0...) case 'integer,integer': list($i0, $j0) = $args; - if ($i0 >= 0) { $m = $this->m - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if ($j0 >= 0) { $n = $this->n - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if ($i0 >= 0) { + $m = $this->m - $i0; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } + if ($j0 >= 0) { + $n = $this->n - $j0; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = $i0; $i < $this->m; ++$i) { - for($j = $j0; $j < $this->n; ++$j) { + for ($i = $i0; $i < $this->m; ++$i) { + for ($j = $j0; $j < $this->n; ++$j) { $R->set($i, $j, $this->A[$i][$j]); } } @@ -189,11 +197,15 @@ public function getMatrix() //A($i0...$iF; $j0...$jF) case 'integer,integer,integer,integer': list($i0, $iF, $j0, $jF) = $args; - if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { + $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } + if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { + $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } $R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1); - for($i = $i0; $i <= $iF; ++$i) { - for($j = $j0; $j <= $jF; ++$j) { + for ($i = $i0; $i <= $iF; ++$i) { + for ($j = $j0; $j <= $jF; ++$j) { $R->set($i - $i0, $j - $j0, $this->A[$i][$j]); } } @@ -202,11 +214,19 @@ public function getMatrix() //$R = array of row indices; $C = array of column indices case 'array,array': list($RL, $CL) = $args; - if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($RL) > 0) { + $m = count($RL); + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } + if (count($CL) > 0) { + $n = count($CL); + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = 0; $i < $m; ++$i) { - for($j = 0; $j < $n; ++$j) { + for ($i = 0; $i < $m; ++$i) { + for ($j = 0; $j < $n; ++$j) { $R->set($i - $i0, $j - $j0, $this->A[$RL[$i]][$CL[$j]]); } } @@ -215,11 +235,19 @@ public function getMatrix() //$RL = array of row indices; $CL = array of column indices case 'array,array': list($RL, $CL) = $args; - if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($RL) > 0) { + $m = count($RL); + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } + if (count($CL) > 0) { + $n = count($CL); + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = 0; $i < $m; ++$i) { - for($j = 0; $j < $n; ++$j) { + for ($i = 0; $i < $m; ++$i) { + for ($j = 0; $j < $n; ++$j) { $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]); } } @@ -228,11 +256,19 @@ public function getMatrix() //A($i0...$iF); $CL = array of column indices case 'integer,integer,array': list($i0, $iF, $CL) = $args; - if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { + $m = $iF - $i0; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } + if (count($CL) > 0) { + $n = count($CL); + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = $i0; $i < $iF; ++$i) { - for($j = 0; $j < $n; ++$j) { + for ($i = $i0; $i < $iF; ++$i) { + for ($j = 0; $j < $n; ++$j) { $R->set($i - $i0, $j, $this->A[$RL[$i]][$j]); } } @@ -241,11 +277,19 @@ public function getMatrix() //$RL = array of row indices case 'array,integer,integer': list($RL, $j0, $jF) = $args; - if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } - if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($RL) > 0) { + $m = count($RL); + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } + if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { + $n = $jF - $j0; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + } $R = new PHPExcel_Shared_JAMA_Matrix($m, $n+1); - for($i = 0; $i < $m; ++$i) { - for($j = $j0; $j <= $jF; ++$j) { + for ($i = 0; $i < $m; ++$i) { + for ($j = $j0; $j <= $jF; ++$j) { $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]); } } @@ -320,7 +364,7 @@ public function identity($m = null, $n = null) public function diagonal($m = null, $n = null, $c = 1) { $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); - for($i = 0; $i < $m; ++$i) { + for ($i = 0; $i < $m; ++$i) { $R->set($i, $i, $c); } return $R; @@ -377,8 +421,8 @@ public function getMatrixByCol($j0 = null, $jF = null) public function transpose() { $R = new PHPExcel_Shared_JAMA_Matrix($this->n, $this->m); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $R->set($j, $i, $this->A[$i][$j]); } } @@ -395,7 +439,7 @@ public function trace() { $s = 0; $n = min($this->m, $this->n); - for($i = 0; $i < $n; ++$i) { + for ($i = 0; $i < $n; ++$i) { $s += $this->A[$i][$i]; } return $s; @@ -440,8 +484,8 @@ public function plus() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]); } } @@ -480,16 +524,16 @@ public function plusEquals() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $validValues = true; $value = $M->get($i, $j); if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $this->A[$i][$j] = trim($this->A[$i][$j], '"'); $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); } if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value,'"'); + $value = trim($value, '"'); $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); } if ($validValues) { @@ -534,8 +578,8 @@ public function minus() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $M->set($i, $j, $M->get($i, $j) - $this->A[$i][$j]); } } @@ -574,16 +618,16 @@ public function minusEquals() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $validValues = true; $value = $M->get($i, $j); if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $this->A[$i][$j] = trim($this->A[$i][$j], '"'); $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); } if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value,'"'); + $value = trim($value, '"'); $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); } if ($validValues) { @@ -629,8 +673,8 @@ public function arrayTimes() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $M->set($i, $j, $M->get($i, $j) * $this->A[$i][$j]); } } @@ -670,16 +714,16 @@ public function arrayTimesEquals() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $validValues = true; $value = $M->get($i, $j); if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $this->A[$i][$j] = trim($this->A[$i][$j], '"'); $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); } if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value,'"'); + $value = trim($value, '"'); $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); } if ($validValues) { @@ -725,16 +769,16 @@ public function arrayRightDivide() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $validValues = true; $value = $M->get($i, $j); if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $this->A[$i][$j] = trim($this->A[$i][$j], '"'); $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); } if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value,'"'); + $value = trim($value, '"'); $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); } if ($validValues) { @@ -786,8 +830,8 @@ public function arrayRightDivideEquals() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $this->A[$i][$j] = $this->A[$i][$j] / $M->get($i, $j); } } @@ -828,8 +872,8 @@ public function arrayLeftDivide() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $M->set($i, $j, $M->get($i, $j) / $this->A[$i][$j]); } } @@ -870,8 +914,8 @@ public function arrayLeftDivideEquals() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $this->A[$i][$j] = $M->get($i, $j) / $this->A[$i][$j]; } } @@ -904,14 +948,14 @@ public function times() } if ($this->n == $B->m) { $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); - for($j = 0; $j < $B->n; ++$j) { + for ($j = 0; $j < $B->n; ++$j) { for ($k = 0; $k < $this->n; ++$k) { $Bcolj[$k] = $B->A[$k][$j]; } - for($i = 0; $i < $this->m; ++$i) { + for ($i = 0; $i < $this->m; ++$i) { $Arowi = $this->A[$i]; $s = 0; - for($k = 0; $k < $this->n; ++$k) { + for ($k = 0; $k < $this->n; ++$k) { $s += $Arowi[$k] * $Bcolj[$k]; } $C->A[$i][$j] = $s; @@ -926,10 +970,10 @@ public function times() $B = new PHPExcel_Shared_JAMA_Matrix($args[0]); if ($this->n == $B->m) { $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { + for ($i = 0; $i < $C->m; ++$i) { + for ($j = 0; $j < $C->n; ++$j) { $s = "0"; - for($k = 0; $k < $C->n; ++$k) { + for ($k = 0; $k < $C->n; ++$k) { $s += $this->A[$i][$k] * $B->A[$k][$j]; } $C->A[$i][$j] = $s; @@ -943,8 +987,8 @@ public function times() break; case 'integer': $C = new PHPExcel_Shared_JAMA_Matrix($this->A); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { + for ($i = 0; $i < $C->m; ++$i) { + for ($j = 0; $j < $C->n; ++$j) { $C->A[$i][$j] *= $args[0]; } } @@ -952,8 +996,8 @@ public function times() break; case 'double': $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $this->n); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { + for ($i = 0; $i < $C->m; ++$i) { + for ($j = 0; $j < $C->n; ++$j) { $C->A[$i][$j] = $args[0] * $this->A[$i][$j]; } } @@ -961,8 +1005,8 @@ public function times() break; case 'float': $C = new PHPExcel_Shared_JAMA_Matrix($this->A); - for($i = 0; $i < $C->m; ++$i) { - for($j = 0; $j < $C->n; ++$j) { + for ($i = 0; $i < $C->m; ++$i) { + for ($j = 0; $j < $C->n; ++$j) { $C->A[$i][$j] *= $args[0]; } } @@ -1006,16 +1050,16 @@ public function power() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { $validValues = true; $value = $M->get($i, $j); if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $this->A[$i][$j] = trim($this->A[$i][$j], '"'); $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); } if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { - $value = trim($value,'"'); + $value = trim($value, '"'); $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); } if ($validValues) { @@ -1059,9 +1103,9 @@ public function concat() break; } $this->checkMatrixDimensions($M); - for($i = 0; $i < $this->m; ++$i) { - for($j = 0; $j < $this->n; ++$j) { - $this->A[$i][$j] = trim($this->A[$i][$j],'"').trim($M->get($i, $j),'"'); + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = trim($this->A[$i][$j], '"').trim($M->get($i, $j), '"'); } } return $this; diff --git a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php index c76f9235d..b20e5a073 100644 --- a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php @@ -233,4 +233,3 @@ public function solve($B) } } // function solve() } - diff --git a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php index 3a36f2991..3d6aeb49b 100644 --- a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php @@ -266,7 +266,7 @@ public function __construct($Arg) break; } $t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks-1]) : 0.); - if (abs($this->s[$ks]) <= $eps * $t) { + if (abs($this->s[$ks]) <= $eps * $t) { $this->s[$ks] = 0.0; break; } diff --git a/Classes/PHPExcel/Shared/OLE/PPS/Root.php b/Classes/PHPExcel/Shared/OLE/PPS/Root.php index e2ae53282..a36c4f970 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/Root.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/Root.php @@ -77,7 +77,7 @@ public function save($filename) $this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir(); } $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root"); - $this->_FILEH_ = fopen($this->_tmp_filename,"w+b"); + $this->_FILEH_ = fopen($this->_tmp_filename, "w+b"); if ($this->_FILEH_ == false) { throw new PHPExcel_Writer_Exception("Can't create temporary file."); } @@ -221,7 +221,7 @@ public function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt) . pack("V", 0x1000) . pack("V", $iSBDcnt ? 0 : -2) //Small Block Depot . pack("V", $iSBDcnt) - ); + ); // Extra BDList Start, Count if ($iBdCnt < $i1stBdL) { fwrite( diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index 3b557a060..78bed21f8 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -3458,7 +3458,6 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, } if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { - // ----- Change the file status $p_entry['status'] = "path_creation_fail"; diff --git a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php index d4bdc5abf..50cdec99c 100644 --- a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php @@ -15,452 +15,452 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); - } + } /** * @dataProvider providerDATE */ - public function testDATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testDATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerDATE() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/DATE.data'); - } - - public function testDATEtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::DATE(2012,1,31); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(1327968000, $result, NULL, 1E-8); - } - - public function testDATEtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::DATE(2012,1,31); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + return new testDataFileIterator('rawTestData/Calculation/DateTime/DATE.data'); + } + + public function testDATEtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::DATE(2012,1,31); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(1327968000, $result, null, 1E-8); + } + + public function testDATEtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::DATE(2012,1,31); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type $this->assertTrue(is_a($result,'DateTime')); // ... with the correct value $this->assertEquals($result->format('d-M-Y'),'31-Jan-2012'); - } + } - public function testDATEwith1904Calendar() - { - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); - $result = PHPExcel_Calculation_DateTime::DATE(1918,11,11); - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + public function testDATEwith1904Calendar() + { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + $result = PHPExcel_Calculation_DateTime::DATE(1918,11,11); + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); $this->assertEquals($result,5428); - } + } - public function testDATEwith1904CalendarError() - { - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); - $result = PHPExcel_Calculation_DateTime::DATE(1901,1,31); - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + public function testDATEwith1904CalendarError() + { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + $result = PHPExcel_Calculation_DateTime::DATE(1901,1,31); + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); $this->assertEquals($result,'#NUM!'); - } + } /** * @dataProvider providerDATEVALUE */ - public function testDATEVALUE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEVALUE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testDATEVALUE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEVALUE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerDATEVALUE() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/DATEVALUE.data'); - } - - public function testDATEVALUEtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::DATEVALUE('2012-1-31'); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(1327968000, $result, NULL, 1E-8); - } - - public function testDATEVALUEtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::DATEVALUE('2012-1-31'); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + return new testDataFileIterator('rawTestData/Calculation/DateTime/DATEVALUE.data'); + } + + public function testDATEVALUEtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::DATEVALUE('2012-1-31'); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(1327968000, $result, null, 1E-8); + } + + public function testDATEVALUEtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::DATEVALUE('2012-1-31'); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type $this->assertTrue(is_a($result,'DateTime')); // ... with the correct value $this->assertEquals($result->format('d-M-Y'),'31-Jan-2012'); - } + } /** * @dataProvider providerYEAR */ - public function testYEAR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEAR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testYEAR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEAR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerYEAR() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/YEAR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/YEAR.data'); + } /** * @dataProvider providerMONTH */ - public function testMONTH() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MONTHOFYEAR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testMONTH() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MONTHOFYEAR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerMONTH() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/MONTH.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/MONTH.data'); + } /** * @dataProvider providerWEEKNUM */ - public function testWEEKNUM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WEEKOFYEAR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testWEEKNUM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WEEKOFYEAR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerWEEKNUM() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/WEEKNUM.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/WEEKNUM.data'); + } /** * @dataProvider providerWEEKDAY */ - public function testWEEKDAY() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFWEEK'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testWEEKDAY() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFWEEK'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerWEEKDAY() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/WEEKDAY.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/WEEKDAY.data'); + } /** * @dataProvider providerDAY */ - public function testDAY() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFMONTH'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testDAY() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFMONTH'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerDAY() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/DAY.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/DAY.data'); + } /** * @dataProvider providerTIME */ - public function testTIME() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIME'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testTIME() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIME'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerTIME() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/TIME.data'); - } - - public function testTIMEtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::TIME(7,30,20); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(27020, $result, NULL, 1E-8); - } - - public function testTIMEtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::TIME(7,30,20); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + return new testDataFileIterator('rawTestData/Calculation/DateTime/TIME.data'); + } + + public function testTIMEtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::TIME(7,30,20); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(27020, $result, null, 1E-8); + } + + public function testTIMEtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::TIME(7,30,20); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type $this->assertTrue(is_a($result,'DateTime')); // ... with the correct value $this->assertEquals($result->format('H:i:s'),'07:30:20'); - } + } /** * @dataProvider providerTIMEVALUE */ - public function testTIMEVALUE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIMEVALUE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testTIMEVALUE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIMEVALUE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerTIMEVALUE() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/TIMEVALUE.data'); - } - - public function testTIMEVALUEtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::TIMEVALUE('7:30:20'); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(23420, $result, NULL, 1E-8); - } - - public function testTIMEVALUEtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::TIMEVALUE('7:30:20'); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + return new testDataFileIterator('rawTestData/Calculation/DateTime/TIMEVALUE.data'); + } + + public function testTIMEVALUEtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::TIMEVALUE('7:30:20'); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(23420, $result, null, 1E-8); + } + + public function testTIMEVALUEtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::TIMEVALUE('7:30:20'); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type $this->assertTrue(is_a($result,'DateTime')); // ... with the correct value $this->assertEquals($result->format('H:i:s'),'07:30:20'); - } + } /** * @dataProvider providerHOUR */ - public function testHOUR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','HOUROFDAY'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testHOUR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','HOUROFDAY'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerHOUR() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/HOUR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/HOUR.data'); + } /** * @dataProvider providerMINUTE */ - public function testMINUTE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MINUTEOFHOUR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testMINUTE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MINUTEOFHOUR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerMINUTE() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/MINUTE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/MINUTE.data'); + } /** * @dataProvider providerSECOND */ - public function testSECOND() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','SECONDOFMINUTE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testSECOND() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','SECONDOFMINUTE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerSECOND() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/SECOND.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/SECOND.data'); + } /** * @dataProvider providerNETWORKDAYS */ - public function testNETWORKDAYS() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','NETWORKDAYS'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testNETWORKDAYS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','NETWORKDAYS'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerNETWORKDAYS() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/NETWORKDAYS.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/NETWORKDAYS.data'); + } /** * @dataProvider providerWORKDAY */ - public function testWORKDAY() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WORKDAY'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testWORKDAY() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WORKDAY'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerWORKDAY() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/WORKDAY.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/WORKDAY.data'); + } /** * @dataProvider providerEDATE */ - public function testEDATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EDATE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testEDATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EDATE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerEDATE() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/EDATE.data'); - } - - public function testEDATEtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(1324857600, $result, NULL, 1E-8); - } - - public function testEDATEtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + return new testDataFileIterator('rawTestData/Calculation/DateTime/EDATE.data'); + } + + public function testEDATEtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(1324857600, $result, null, 1E-8); + } + + public function testEDATEtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type $this->assertTrue(is_a($result,'DateTime')); // ... with the correct value $this->assertEquals($result->format('d-M-Y'),'26-Dec-2011'); - } + } /** * @dataProvider providerEOMONTH */ - public function testEOMONTH() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EOMONTH'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testEOMONTH() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EOMONTH'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerEOMONTH() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/EOMONTH.data'); - } - - public function testEOMONTHtoPHP() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); - $this->assertEquals(1325289600, $result, NULL, 1E-8); - } - - public function testEOMONTHtoPHPObject() - { - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1); - PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + return new testDataFileIterator('rawTestData/Calculation/DateTime/EOMONTH.data'); + } + + public function testEOMONTHtoPHP() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + $this->assertEquals(1325289600, $result, null, 1E-8); + } + + public function testEOMONTHtoPHPObject() + { + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); + $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type $this->assertTrue(is_a($result,'DateTime')); // ... with the correct value $this->assertEquals($result->format('d-M-Y'),'31-Dec-2011'); - } + } /** * @dataProvider providerDATEDIF */ - public function testDATEDIF() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEDIF'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testDATEDIF() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEDIF'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerDATEDIF() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/DATEDIF.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/DATEDIF.data'); + } /** * @dataProvider providerDAYS360 */ - public function testDAYS360() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYS360'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testDAYS360() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYS360'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerDAYS360() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/DAYS360.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/DAYS360.data'); + } /** * @dataProvider providerYEARFRAC */ - public function testYEARFRAC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEARFRAC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testYEARFRAC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEARFRAC'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerYEARFRAC() { - return new testDataFileIterator('rawTestData/Calculation/DateTime/YEARFRAC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/DateTime/YEARFRAC.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php b/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php index 1f511ffac..c5a829615 100644 --- a/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php @@ -19,680 +19,680 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); - } + } /** * @dataProvider providerBESSELI */ - public function testBESSELI() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELI'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testBESSELI() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELI'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerBESSELI() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELI.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELI.data'); + } /** * @dataProvider providerBESSELJ */ - public function testBESSELJ() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELJ'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testBESSELJ() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELJ'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerBESSELJ() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELJ.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELJ.data'); + } /** * @dataProvider providerBESSELK */ - public function testBESSELK() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELK'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testBESSELK() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELK'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerBESSELK() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELK.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELK.data'); + } /** * @dataProvider providerBESSELY */ - public function testBESSELY() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELY'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testBESSELY() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELY'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerBESSELY() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELY.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELY.data'); + } /** * @dataProvider providerCOMPLEX */ - public function testCOMPLEX() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','COMPLEX'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testCOMPLEX() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','COMPLEX'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerCOMPLEX() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/COMPLEX.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/COMPLEX.data'); + } /** * @dataProvider providerIMAGINARY */ - public function testIMAGINARY() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMAGINARY'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIMAGINARY() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMAGINARY'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIMAGINARY() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMAGINARY.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMAGINARY.data'); + } /** * @dataProvider providerIMREAL */ - public function testIMREAL() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMREAL'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIMREAL() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMREAL'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIMREAL() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMREAL.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMREAL.data'); + } /** * @dataProvider providerIMABS */ - public function testIMABS() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMABS'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIMABS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMABS'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIMABS() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMABS.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMABS.data'); + } /** * @dataProvider providerIMARGUMENT */ - public function testIMARGUMENT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMARGUMENT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIMARGUMENT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMARGUMENT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIMARGUMENT() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMARGUMENT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMARGUMENT.data'); + } /** * @dataProvider providerIMCONJUGATE */ - public function testIMCONJUGATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCONJUGATE'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMCONJUGATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCONJUGATE'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMCONJUGATE() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMCONJUGATE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMCONJUGATE.data'); + } /** * @dataProvider providerIMCOS */ - public function testIMCOS() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCOS'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMCOS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCOS'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMCOS() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMCOS.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMCOS.data'); + } /** * @dataProvider providerIMDIV */ - public function testIMDIV() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMDIV'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMDIV() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMDIV'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMDIV() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMDIV.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMDIV.data'); + } /** * @dataProvider providerIMEXP */ - public function testIMEXP() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMEXP'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMEXP() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMEXP'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMEXP() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMEXP.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMEXP.data'); + } /** * @dataProvider providerIMLN */ - public function testIMLN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLN'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMLN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLN'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMLN() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLN.data'); + } /** * @dataProvider providerIMLOG2 */ - public function testIMLOG2() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG2'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMLOG2() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG2'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMLOG2() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLOG2.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLOG2.data'); + } /** * @dataProvider providerIMLOG10 */ - public function testIMLOG10() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG10'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMLOG10() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG10'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMLOG10() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLOG10.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMLOG10.data'); + } /** * @dataProvider providerIMPOWER */ - public function testIMPOWER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPOWER'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMPOWER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPOWER'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMPOWER() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMPOWER.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMPOWER.data'); + } /** * @dataProvider providerIMPRODUCT */ - public function testIMPRODUCT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPRODUCT'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMPRODUCT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPRODUCT'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMPRODUCT() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMPRODUCT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMPRODUCT.data'); + } /** * @dataProvider providerIMSIN */ - public function testIMSIN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSIN'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMSIN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSIN'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMSIN() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSIN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSIN.data'); + } /** * @dataProvider providerIMSQRT */ - public function testIMSQRT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSQRT'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMSQRT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSQRT'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMSQRT() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSQRT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSQRT.data'); + } /** * @dataProvider providerIMSUB */ - public function testIMSUB() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUB'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMSUB() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUB'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMSUB() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUB.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUB.data'); + } /** * @dataProvider providerIMSUM */ - public function testIMSUM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'),$args); - $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); - } + public function testIMSUM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'),$args); + $complexAssert = new complexAssert(); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), + $complexAssert->getErrorMessage()); + } public function providerIMSUM() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUM.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUM.data'); + } /** * @dataProvider providerERF */ - public function testERF() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERF'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testERF() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERF'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerERF() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/ERF.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/ERF.data'); + } /** * @dataProvider providerERFC */ - public function testERFC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERFC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testERFC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERFC'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerERFC() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/ERFC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/ERFC.data'); + } /** * @dataProvider providerBIN2DEC */ - public function testBIN2DEC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTODEC'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testBIN2DEC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTODEC'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerBIN2DEC() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2DEC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2DEC.data'); + } /** * @dataProvider providerBIN2HEX */ - public function testBIN2HEX() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOHEX'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testBIN2HEX() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOHEX'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerBIN2HEX() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2HEX.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2HEX.data'); + } /** * @dataProvider providerBIN2OCT */ - public function testBIN2OCT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOOCT'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testBIN2OCT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOOCT'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerBIN2OCT() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2OCT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2OCT.data'); + } /** * @dataProvider providerDEC2BIN */ - public function testDEC2BIN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOBIN'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testDEC2BIN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOBIN'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerDEC2BIN() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2BIN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2BIN.data'); + } /** * @dataProvider providerDEC2HEX */ - public function testDEC2HEX() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOHEX'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testDEC2HEX() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOHEX'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerDEC2HEX() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2HEX.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2HEX.data'); + } /** * @dataProvider providerDEC2OCT */ - public function testDEC2OCT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOOCT'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testDEC2OCT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOOCT'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerDEC2OCT() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2OCT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2OCT.data'); + } /** * @dataProvider providerHEX2BIN */ - public function testHEX2BIN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOBIN'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testHEX2BIN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOBIN'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerHEX2BIN() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2BIN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2BIN.data'); + } /** * @dataProvider providerHEX2DEC */ - public function testHEX2DEC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTODEC'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testHEX2DEC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTODEC'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerHEX2DEC() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2DEC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2DEC.data'); + } /** * @dataProvider providerHEX2OCT */ - public function testHEX2OCT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOOCT'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testHEX2OCT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOOCT'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerHEX2OCT() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2OCT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2OCT.data'); + } /** * @dataProvider providerOCT2BIN */ - public function testOCT2BIN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOBIN'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testOCT2BIN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOBIN'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerOCT2BIN() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2BIN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2BIN.data'); + } /** * @dataProvider providerOCT2DEC */ - public function testOCT2DEC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTODEC'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testOCT2DEC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTODEC'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerOCT2DEC() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2DEC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2DEC.data'); + } /** * @dataProvider providerOCT2HEX */ - public function testOCT2HEX() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOHEX'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testOCT2HEX() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOHEX'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerOCT2HEX() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2HEX.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2HEX.data'); + } /** * @dataProvider providerDELTA */ - public function testDELTA() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DELTA'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testDELTA() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DELTA'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerDELTA() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/DELTA.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/DELTA.data'); + } /** * @dataProvider providerGESTEP */ - public function testGESTEP() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','GESTEP'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testGESTEP() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','GESTEP'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerGESTEP() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/GESTEP.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/GESTEP.data'); + } - public function testGetConversionGroups() - { - $result = PHPExcel_Calculation_Engineering::getConversionGroups(); - $this->assertInternalType('array', $result); - } + public function testGetConversionGroups() + { + $result = PHPExcel_Calculation_Engineering::getConversionGroups(); + $this->assertInternalType('array', $result); + } - public function testGetConversionGroupUnits() - { - $result = PHPExcel_Calculation_Engineering::getConversionGroupUnits(); - $this->assertInternalType('array', $result); - } + public function testGetConversionGroupUnits() + { + $result = PHPExcel_Calculation_Engineering::getConversionGroupUnits(); + $this->assertInternalType('array', $result); + } - public function testGetConversionGroupUnitDetails() - { - $result = PHPExcel_Calculation_Engineering::getConversionGroupUnitDetails(); - $this->assertInternalType('array', $result); - } + public function testGetConversionGroupUnitDetails() + { + $result = PHPExcel_Calculation_Engineering::getConversionGroupUnitDetails(); + $this->assertInternalType('array', $result); + } - public function testGetConversionMultipliers() - { - $result = PHPExcel_Calculation_Engineering::getConversionMultipliers(); - $this->assertInternalType('array', $result); - } + public function testGetConversionMultipliers() + { + $result = PHPExcel_Calculation_Engineering::getConversionMultipliers(); + $this->assertInternalType('array', $result); + } /** * @dataProvider providerCONVERTUOM */ - public function testCONVERTUOM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','CONVERTUOM'),$args); - $this->assertEquals($expectedResult, $result, NULL); - } + public function testCONVERTUOM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','CONVERTUOM'),$args); + $this->assertEquals($expectedResult, $result, null); + } public function providerCONVERTUOM() { - return new testDataFileIterator('rawTestData/Calculation/Engineering/CONVERTUOM.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Engineering/CONVERTUOM.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php b/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php index f5689c950..efaa60e57 100644 --- a/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php @@ -15,502 +15,502 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); - } + } /** * @dataProvider providerACCRINT */ - public function testACCRINT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testACCRINT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerACCRINT() { - return new testDataFileIterator('rawTestData/Calculation/Financial/ACCRINT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/ACCRINT.data'); + } /** * @dataProvider providerACCRINTM */ - public function testACCRINTM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINTM'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testACCRINTM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINTM'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerACCRINTM() { - return new testDataFileIterator('rawTestData/Calculation/Financial/ACCRINTM.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/ACCRINTM.data'); + } /** * @dataProvider providerAMORDEGRC */ - public function testAMORDEGRC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORDEGRC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testAMORDEGRC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORDEGRC'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerAMORDEGRC() { - return new testDataFileIterator('rawTestData/Calculation/Financial/AMORDEGRC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/AMORDEGRC.data'); + } /** * @dataProvider providerAMORLINC */ - public function testAMORLINC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORLINC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testAMORLINC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORLINC'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerAMORLINC() { - return new testDataFileIterator('rawTestData/Calculation/Financial/AMORLINC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/AMORLINC.data'); + } /** * @dataProvider providerCOUPDAYBS */ - public function testCOUPDAYBS() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYBS'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testCOUPDAYBS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYBS'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerCOUPDAYBS() { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYBS.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYBS.data'); + } /** * @dataProvider providerCOUPDAYS */ - public function testCOUPDAYS() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYS'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testCOUPDAYS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYS'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerCOUPDAYS() { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYS.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYS.data'); + } /** * @dataProvider providerCOUPDAYSNC */ - public function testCOUPDAYSNC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYSNC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testCOUPDAYSNC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYSNC'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerCOUPDAYSNC() { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYSNC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYSNC.data'); + } /** * @dataProvider providerCOUPNCD */ - public function testCOUPNCD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNCD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testCOUPNCD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNCD'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerCOUPNCD() { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPNCD.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPNCD.data'); + } /** * @dataProvider providerCOUPNUM */ - public function testCOUPNUM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNUM'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testCOUPNUM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNUM'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerCOUPNUM() { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPNUM.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPNUM.data'); + } /** * @dataProvider providerCOUPPCD */ - public function testCOUPPCD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPPCD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testCOUPPCD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPPCD'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerCOUPPCD() { - return new testDataFileIterator('rawTestData/Calculation/Financial/COUPPCD.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/COUPPCD.data'); + } /** * @dataProvider providerCUMIPMT */ - public function testCUMIPMT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMIPMT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testCUMIPMT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMIPMT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerCUMIPMT() { - return new testDataFileIterator('rawTestData/Calculation/Financial/CUMIPMT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/CUMIPMT.data'); + } /** * @dataProvider providerCUMPRINC */ - public function testCUMPRINC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMPRINC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testCUMPRINC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMPRINC'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerCUMPRINC() { - return new testDataFileIterator('rawTestData/Calculation/Financial/CUMPRINC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/CUMPRINC.data'); + } /** * @dataProvider providerDB */ - public function testDB() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DB'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testDB() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DB'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerDB() { - return new testDataFileIterator('rawTestData/Calculation/Financial/DB.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/DB.data'); + } /** * @dataProvider providerDDB */ - public function testDDB() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DDB'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testDDB() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DDB'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerDDB() { - return new testDataFileIterator('rawTestData/Calculation/Financial/DDB.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/DDB.data'); + } /** * @dataProvider providerDISC */ - public function testDISC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DISC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testDISC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DISC'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerDISC() { - return new testDataFileIterator('rawTestData/Calculation/Financial/DISC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/DISC.data'); + } /** * @dataProvider providerDOLLARDE */ - public function testDOLLARDE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARDE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testDOLLARDE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARDE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerDOLLARDE() { - return new testDataFileIterator('rawTestData/Calculation/Financial/DOLLARDE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/DOLLARDE.data'); + } /** * @dataProvider providerDOLLARFR */ - public function testDOLLARFR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARFR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testDOLLARFR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARFR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerDOLLARFR() { - return new testDataFileIterator('rawTestData/Calculation/Financial/DOLLARFR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/DOLLARFR.data'); + } /** * @dataProvider providerEFFECT */ - public function testEFFECT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','EFFECT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testEFFECT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','EFFECT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerEFFECT() { - return new testDataFileIterator('rawTestData/Calculation/Financial/EFFECT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/EFFECT.data'); + } /** * @dataProvider providerFV */ - public function testFV() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FV'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testFV() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FV'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerFV() { - return new testDataFileIterator('rawTestData/Calculation/Financial/FV.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/FV.data'); + } /** * @dataProvider providerFVSCHEDULE */ - public function testFVSCHEDULE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FVSCHEDULE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testFVSCHEDULE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FVSCHEDULE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerFVSCHEDULE() { - return new testDataFileIterator('rawTestData/Calculation/Financial/FVSCHEDULE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/FVSCHEDULE.data'); + } /** * @dataProvider providerINTRATE */ - public function testINTRATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','INTRATE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testINTRATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','INTRATE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerINTRATE() { - return new testDataFileIterator('rawTestData/Calculation/Financial/INTRATE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/INTRATE.data'); + } /** * @dataProvider providerIPMT */ - public function testIPMT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IPMT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIPMT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IPMT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIPMT() { - return new testDataFileIterator('rawTestData/Calculation/Financial/IPMT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/IPMT.data'); + } /** * @dataProvider providerIRR */ - public function testIRR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IRR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIRR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IRR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIRR() { - return new testDataFileIterator('rawTestData/Calculation/Financial/IRR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/IRR.data'); + } /** * @dataProvider providerISPMT */ - public function testISPMT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ISPMT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testISPMT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ISPMT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerISPMT() { - return new testDataFileIterator('rawTestData/Calculation/Financial/ISPMT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/ISPMT.data'); + } /** * @dataProvider providerMIRR */ - public function testMIRR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','MIRR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testMIRR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','MIRR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerMIRR() { - return new testDataFileIterator('rawTestData/Calculation/Financial/MIRR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/MIRR.data'); + } /** * @dataProvider providerNOMINAL */ - public function testNOMINAL() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NOMINAL'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testNOMINAL() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NOMINAL'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerNOMINAL() { - return new testDataFileIterator('rawTestData/Calculation/Financial/NOMINAL.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/NOMINAL.data'); + } /** * @dataProvider providerNPER */ - public function testNPER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPER'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testNPER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPER'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerNPER() { - return new testDataFileIterator('rawTestData/Calculation/Financial/NPER.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/NPER.data'); + } /** * @dataProvider providerNPV */ - public function testNPV() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPV'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testNPV() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPV'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerNPV() { - return new testDataFileIterator('rawTestData/Calculation/Financial/NPV.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/NPV.data'); + } /** * @dataProvider providerPRICE */ - public function testPRICE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','PRICE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testPRICE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','PRICE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerPRICE() { - return new testDataFileIterator('rawTestData/Calculation/Financial/PRICE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/PRICE.data'); + } /** * @dataProvider providerRATE */ - public function testRATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','RATE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testRATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','RATE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerRATE() { - return new testDataFileIterator('rawTestData/Calculation/Financial/RATE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/RATE.data'); + } /** * @dataProvider providerXIRR */ - public function testXIRR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','XIRR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testXIRR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','XIRR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerXIRR() { - return new testDataFileIterator('rawTestData/Calculation/Financial/XIRR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Financial/XIRR.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php b/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php index 013332940..0e9fb50d7 100644 --- a/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php @@ -15,262 +15,262 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); - } - - public function testDUMMY() - { - $result = PHPExcel_Calculation_Functions::DUMMY(); - $this->assertEquals('#Not Yet Implemented', $result); - } - - public function testDIV0() - { - $result = PHPExcel_Calculation_Functions::DIV0(); - $this->assertEquals('#DIV/0!', $result); - } - - public function testNA() - { - $result = PHPExcel_Calculation_Functions::NA(); - $this->assertEquals('#N/A', $result); - } - - public function testNaN() - { - $result = PHPExcel_Calculation_Functions::NaN(); - $this->assertEquals('#NUM!', $result); - } - - public function testNAME() - { - $result = PHPExcel_Calculation_Functions::NAME(); - $this->assertEquals('#NAME?', $result); - } - - public function testREF() - { - $result = PHPExcel_Calculation_Functions::REF(); - $this->assertEquals('#REF!', $result); - } - - public function testNULL() - { - $result = PHPExcel_Calculation_Functions::NULL(); - $this->assertEquals('#NULL!', $result); - } - - public function testVALUE() - { - $result = PHPExcel_Calculation_Functions::VALUE(); - $this->assertEquals('#VALUE!', $result); - } + } + + public function testDUMMY() + { + $result = PHPExcel_Calculation_Functions::DUMMY(); + $this->assertEquals('#Not Yet Implemented', $result); + } + + public function testDIV0() + { + $result = PHPExcel_Calculation_Functions::DIV0(); + $this->assertEquals('#DIV/0!', $result); + } + + public function testNA() + { + $result = PHPExcel_Calculation_Functions::NA(); + $this->assertEquals('#N/A', $result); + } + + public function testNaN() + { + $result = PHPExcel_Calculation_Functions::NaN(); + $this->assertEquals('#NUM!', $result); + } + + public function testNAME() + { + $result = PHPExcel_Calculation_Functions::NAME(); + $this->assertEquals('#NAME?', $result); + } + + public function testREF() + { + $result = PHPExcel_Calculation_Functions::REF(); + $this->assertEquals('#REF!', $result); + } + + public function testNULL() + { + $result = PHPExcel_Calculation_Functions::null(); + $this->assertEquals('#NULL!', $result); + } + + public function testVALUE() + { + $result = PHPExcel_Calculation_Functions::VALUE(); + $this->assertEquals('#VALUE!', $result); + } /** * @dataProvider providerIS_BLANK */ - public function testIS_BLANK() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_BLANK'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIS_BLANK() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_BLANK'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIS_BLANK() { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_BLANK.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_BLANK.data'); + } /** * @dataProvider providerIS_ERR */ - public function testIS_ERR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIS_ERR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIS_ERR() { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ERR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ERR.data'); + } /** * @dataProvider providerIS_ERROR */ - public function testIS_ERROR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERROR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIS_ERROR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERROR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIS_ERROR() { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ERROR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ERROR.data'); + } /** * @dataProvider providerERROR_TYPE */ - public function testERROR_TYPE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','ERROR_TYPE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testERROR_TYPE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','ERROR_TYPE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerERROR_TYPE() { - return new testDataFileIterator('rawTestData/Calculation/Functions/ERROR_TYPE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/ERROR_TYPE.data'); + } /** * @dataProvider providerIS_LOGICAL */ - public function testIS_LOGICAL() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_LOGICAL'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIS_LOGICAL() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_LOGICAL'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIS_LOGICAL() { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_LOGICAL.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_LOGICAL.data'); + } /** * @dataProvider providerIS_NA */ - public function testIS_NA() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NA'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIS_NA() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NA'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIS_NA() { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NA.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NA.data'); + } /** * @dataProvider providerIS_NUMBER */ - public function testIS_NUMBER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NUMBER'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIS_NUMBER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NUMBER'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIS_NUMBER() { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NUMBER.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NUMBER.data'); + } /** * @dataProvider providerIS_TEXT */ - public function testIS_TEXT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_TEXT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIS_TEXT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_TEXT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIS_TEXT() { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_TEXT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_TEXT.data'); + } /** * @dataProvider providerIS_NONTEXT */ - public function testIS_NONTEXT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NONTEXT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIS_NONTEXT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NONTEXT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIS_NONTEXT() { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NONTEXT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_NONTEXT.data'); + } /** * @dataProvider providerIS_EVEN */ - public function testIS_EVEN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_EVEN'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIS_EVEN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_EVEN'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIS_EVEN() { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_EVEN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_EVEN.data'); + } /** * @dataProvider providerIS_ODD */ - public function testIS_ODD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ODD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testIS_ODD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ODD'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerIS_ODD() { - return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ODD.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/IS_ODD.data'); + } /** * @dataProvider providerTYPE */ - public function testTYPE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','TYPE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testTYPE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','TYPE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerTYPE() { - return new testDataFileIterator('rawTestData/Calculation/Functions/TYPE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/TYPE.data'); + } /** * @dataProvider providerN */ - public function testN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','N'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','N'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerN() { - return new testDataFileIterator('rawTestData/Calculation/Functions/N.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Functions/N.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php b/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php index cc8f8b333..21d497725 100644 --- a/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php @@ -15,98 +15,98 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); - } + } - public function testTRUE() - { - $result = PHPExcel_Calculation_Logical::TRUE(); - $this->assertEquals(TRUE, $result); - } + public function testTRUE() + { + $result = PHPExcel_Calculation_Logical::TRUE(); + $this->assertEquals(true, $result); + } - public function testFALSE() - { - $result = PHPExcel_Calculation_Logical::FALSE(); - $this->assertEquals(FALSE, $result); - } + public function testFALSE() + { + $result = PHPExcel_Calculation_Logical::FALSE(); + $this->assertEquals(false, $result); + } /** * @dataProvider providerAND */ - public function testAND() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_AND'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testAND() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_AND'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerAND() { - return new testDataFileIterator('rawTestData/Calculation/Logical/AND.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Logical/AND.data'); + } /** * @dataProvider providerOR */ - public function testOR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_OR'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testOR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_OR'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerOR() { - return new testDataFileIterator('rawTestData/Calculation/Logical/OR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Logical/OR.data'); + } /** * @dataProvider providerNOT */ public function testNOT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','NOT'),$args); - $this->assertEquals($expectedResult, $result); - } + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','NOT'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerNOT() { - return new testDataFileIterator('rawTestData/Calculation/Logical/NOT.data'); + return new testDataFileIterator('rawTestData/Calculation/Logical/NOT.data'); } /** * @dataProvider providerIF */ public function testIF() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','STATEMENT_IF'),$args); - $this->assertEquals($expectedResult, $result); - } + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','STATEMENT_IF'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerIF() { - return new testDataFileIterator('rawTestData/Calculation/Logical/IF.data'); - } + return new testDataFileIterator('rawTestData/Calculation/Logical/IF.data'); + } /** * @dataProvider providerIFERROR */ public function testIFERROR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','IFERROR'),$args); - $this->assertEquals($expectedResult, $result); - } + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','IFERROR'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerIFERROR() { return new testDataFileIterator('rawTestData/Calculation/Logical/IFERROR.data'); - } + } } diff --git a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php index 6450b0822..ed4d6ee0d 100644 --- a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php @@ -15,38 +15,38 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); - } + } /** * @dataProvider providerHLOOKUP */ - public function testHLOOKUP() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','HLOOKUP'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testHLOOKUP() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','HLOOKUP'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerHLOOKUP() { - return new testDataFileIterator('rawTestData/Calculation/LookupRef/HLOOKUP.data'); - } + return new testDataFileIterator('rawTestData/Calculation/LookupRef/HLOOKUP.data'); + } /** * @dataProvider providerVLOOKUP */ - public function testVLOOKUP() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','VLOOKUP'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testVLOOKUP() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','VLOOKUP'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerVLOOKUP() { - return new testDataFileIterator('rawTestData/Calculation/LookupRef/VLOOKUP.data'); - } + return new testDataFileIterator('rawTestData/Calculation/LookupRef/VLOOKUP.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php index 0059ed08e..9772a7e77 100644 --- a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php @@ -15,472 +15,472 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); - } + } /** * @dataProvider providerATAN2 */ - public function testATAN2() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ATAN2'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testATAN2() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ATAN2'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerATAN2() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/ATAN2.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/ATAN2.data'); + } /** * @dataProvider providerCEILING */ - public function testCEILING() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','CEILING'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testCEILING() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','CEILING'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerCEILING() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/CEILING.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/CEILING.data'); + } /** * @dataProvider providerCOMBIN */ - public function testCOMBIN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','COMBIN'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testCOMBIN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','COMBIN'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerCOMBIN() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/COMBIN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/COMBIN.data'); + } /** * @dataProvider providerEVEN */ - public function testEVEN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','EVEN'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testEVEN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','EVEN'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerEVEN() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/EVEN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/EVEN.data'); + } /** * @dataProvider providerODD */ - public function testODD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ODD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testODD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ODD'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerODD() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/ODD.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/ODD.data'); + } /** * @dataProvider providerFACT */ - public function testFACT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testFACT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerFACT() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/FACT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/FACT.data'); + } /** * @dataProvider providerFACTDOUBLE */ - public function testFACTDOUBLE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACTDOUBLE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testFACTDOUBLE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACTDOUBLE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerFACTDOUBLE() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/FACTDOUBLE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/FACTDOUBLE.data'); + } /** * @dataProvider providerFLOOR */ - public function testFLOOR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FLOOR'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testFLOOR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FLOOR'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerFLOOR() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/FLOOR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/FLOOR.data'); + } /** * @dataProvider providerGCD */ - public function testGCD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','GCD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testGCD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','GCD'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerGCD() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/GCD.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/GCD.data'); + } /** * @dataProvider providerLCM */ - public function testLCM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LCM'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testLCM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LCM'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerLCM() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/LCM.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/LCM.data'); + } /** * @dataProvider providerINT */ - public function testINT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','INT'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testINT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','INT'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerINT() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/INT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/INT.data'); + } /** * @dataProvider providerSIGN */ - public function testSIGN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SIGN'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testSIGN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SIGN'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerSIGN() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/SIGN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/SIGN.data'); + } /** * @dataProvider providerPOWER */ - public function testPOWER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','POWER'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testPOWER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','POWER'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerPOWER() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/POWER.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/POWER.data'); + } /** * @dataProvider providerLOG */ - public function testLOG() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LOG_BASE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testLOG() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LOG_BASE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerLOG() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/LOG.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/LOG.data'); + } /** * @dataProvider providerMOD */ - public function testMOD() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MOD'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testMOD() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MOD'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerMOD() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MOD.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MOD.data'); + } /** * @dataProvider providerMDETERM */ - public function testMDETERM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MDETERM'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testMDETERM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MDETERM'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerMDETERM() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MDETERM.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MDETERM.data'); + } /** * @dataProvider providerMINVERSE */ - public function testMINVERSE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MINVERSE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testMINVERSE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MINVERSE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerMINVERSE() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MINVERSE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MINVERSE.data'); + } /** * @dataProvider providerMMULT */ - public function testMMULT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MMULT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testMMULT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MMULT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerMMULT() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MMULT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MMULT.data'); + } /** * @dataProvider providerMULTINOMIAL */ - public function testMULTINOMIAL() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MULTINOMIAL'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testMULTINOMIAL() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MULTINOMIAL'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerMULTINOMIAL() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MULTINOMIAL.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MULTINOMIAL.data'); + } /** * @dataProvider providerMROUND */ - public function testMROUND() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MROUND'),$args); - PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_ARRAY); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testMROUND() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MROUND'),$args); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_ARRAY); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerMROUND() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/MROUND.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/MROUND.data'); + } /** * @dataProvider providerPRODUCT */ - public function testPRODUCT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','PRODUCT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testPRODUCT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','PRODUCT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerPRODUCT() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/PRODUCT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/PRODUCT.data'); + } /** * @dataProvider providerQUOTIENT */ - public function testQUOTIENT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','QUOTIENT'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testQUOTIENT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','QUOTIENT'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerQUOTIENT() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/QUOTIENT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/QUOTIENT.data'); + } /** * @dataProvider providerROUNDUP */ - public function testROUNDUP() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDUP'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testROUNDUP() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDUP'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerROUNDUP() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROUNDUP.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROUNDUP.data'); + } /** * @dataProvider providerROUNDDOWN */ - public function testROUNDDOWN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDDOWN'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testROUNDDOWN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDDOWN'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerROUNDDOWN() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROUNDDOWN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROUNDDOWN.data'); + } /** * @dataProvider providerSERIESSUM */ - public function testSERIESSUM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SERIESSUM'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testSERIESSUM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SERIESSUM'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerSERIESSUM() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/SERIESSUM.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/SERIESSUM.data'); + } /** * @dataProvider providerSUMSQ */ - public function testSUMSQ() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SUMSQ'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testSUMSQ() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SUMSQ'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerSUMSQ() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/SUMSQ.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/SUMSQ.data'); + } /** * @dataProvider providerTRUNC */ - public function testTRUNC() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','TRUNC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testTRUNC() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','TRUNC'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerTRUNC() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/TRUNC.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/TRUNC.data'); + } /** * @dataProvider providerROMAN */ - public function testROMAN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROMAN'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testROMAN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROMAN'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerROMAN() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROMAN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/MathTrig/ROMAN.data'); + } /** * @dataProvider providerSQRTPI */ - public function testSQRTPI() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SQRTPI'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); - } + public function testSQRTPI() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SQRTPI'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } public function providerSQRTPI() { - return new testDataFileIterator('rawTestData/Calculation/MathTrig/SQRTPI.data'); + return new testDataFileIterator('rawTestData/Calculation/MathTrig/SQRTPI.data'); } /** @@ -491,7 +491,7 @@ public function testSUMIF() $args = func_get_args(); $expectedResult = array_pop($args); $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig', 'SUMIF'), $args); - $this->assertEquals($expectedResult, $result, NULL, 1E-12); + $this->assertEquals($expectedResult, $result, null, 1E-12); } public function providerSUMIF() @@ -555,6 +555,6 @@ public function providerSUMIF() 100 ), ); - } + } } diff --git a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php index 4b1caf517..c7ed3b577 100644 --- a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php @@ -15,351 +15,351 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL); - } + } /** * @dataProvider providerCHAR */ - public function testCHAR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','CHARACTER'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testCHAR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','CHARACTER'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerCHAR() { - return new testDataFileIterator('rawTestData/Calculation/TextData/CHAR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/CHAR.data'); + } /** * @dataProvider providerCODE */ - public function testCODE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','ASCIICODE'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testCODE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','ASCIICODE'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerCODE() { - return new testDataFileIterator('rawTestData/Calculation/TextData/CODE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/CODE.data'); + } /** * @dataProvider providerCONCATENATE */ - public function testCONCATENATE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','CONCATENATE'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testCONCATENATE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','CONCATENATE'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerCONCATENATE() { - return new testDataFileIterator('rawTestData/Calculation/TextData/CONCATENATE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/CONCATENATE.data'); + } /** * @dataProvider providerLEFT */ - public function testLEFT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LEFT'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testLEFT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LEFT'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerLEFT() { - return new testDataFileIterator('rawTestData/Calculation/TextData/LEFT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/LEFT.data'); + } /** * @dataProvider providerMID */ - public function testMID() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','MID'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testMID() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','MID'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerMID() { - return new testDataFileIterator('rawTestData/Calculation/TextData/MID.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/MID.data'); + } /** * @dataProvider providerRIGHT */ - public function testRIGHT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RIGHT'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testRIGHT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RIGHT'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerRIGHT() { - return new testDataFileIterator('rawTestData/Calculation/TextData/RIGHT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/RIGHT.data'); + } /** * @dataProvider providerLOWER */ - public function testLOWER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LOWERCASE'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testLOWER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LOWERCASE'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerLOWER() { - return new testDataFileIterator('rawTestData/Calculation/TextData/LOWER.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/LOWER.data'); + } /** * @dataProvider providerUPPER */ - public function testUPPER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','UPPERCASE'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testUPPER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','UPPERCASE'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerUPPER() { - return new testDataFileIterator('rawTestData/Calculation/TextData/UPPER.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/UPPER.data'); + } /** * @dataProvider providerPROPER */ - public function testPROPER() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','PROPERCASE'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testPROPER() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','PROPERCASE'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerPROPER() { - return new testDataFileIterator('rawTestData/Calculation/TextData/PROPER.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/PROPER.data'); + } /** * @dataProvider providerLEN */ - public function testLEN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','STRINGLENGTH'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testLEN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','STRINGLENGTH'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerLEN() { - return new testDataFileIterator('rawTestData/Calculation/TextData/LEN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/LEN.data'); + } /** * @dataProvider providerSEARCH */ - public function testSEARCH() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHINSENSITIVE'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testSEARCH() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHINSENSITIVE'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerSEARCH() { - return new testDataFileIterator('rawTestData/Calculation/TextData/SEARCH.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/SEARCH.data'); + } /** * @dataProvider providerFIND */ - public function testFIND() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHSENSITIVE'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testFIND() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHSENSITIVE'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerFIND() { - return new testDataFileIterator('rawTestData/Calculation/TextData/FIND.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/FIND.data'); + } /** * @dataProvider providerREPLACE */ - public function testREPLACE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','REPLACE'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testREPLACE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','REPLACE'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerREPLACE() { - return new testDataFileIterator('rawTestData/Calculation/TextData/REPLACE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/REPLACE.data'); + } /** * @dataProvider providerSUBSTITUTE */ - public function testSUBSTITUTE() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SUBSTITUTE'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testSUBSTITUTE() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SUBSTITUTE'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerSUBSTITUTE() { - return new testDataFileIterator('rawTestData/Calculation/TextData/SUBSTITUTE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/SUBSTITUTE.data'); + } /** * @dataProvider providerTRIM */ - public function testTRIM() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMSPACES'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testTRIM() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMSPACES'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerTRIM() { - return new testDataFileIterator('rawTestData/Calculation/TextData/TRIM.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/TRIM.data'); + } /** * @dataProvider providerCLEAN */ - public function testCLEAN() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMNONPRINTABLE'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testCLEAN() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMNONPRINTABLE'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerCLEAN() { - return new testDataFileIterator('rawTestData/Calculation/TextData/CLEAN.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/CLEAN.data'); + } /** * @dataProvider providerDOLLAR */ - public function testDOLLAR() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','DOLLAR'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testDOLLAR() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','DOLLAR'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerDOLLAR() { - return new testDataFileIterator('rawTestData/Calculation/TextData/DOLLAR.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/DOLLAR.data'); + } /** * @dataProvider providerFIXED */ - public function testFIXED() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','FIXEDFORMAT'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testFIXED() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','FIXEDFORMAT'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerFIXED() { - return new testDataFileIterator('rawTestData/Calculation/TextData/FIXED.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/FIXED.data'); + } /** * @dataProvider providerT */ - public function testT() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RETURNSTRING'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testT() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RETURNSTRING'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerT() { - return new testDataFileIterator('rawTestData/Calculation/TextData/T.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/T.data'); + } /** * @dataProvider providerTEXT */ - public function testTEXT() - { - // Enforce decimal and thousands separator values to UK/US, and currency code to USD - call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.'); - call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),','); - call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$'); - - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TEXTFORMAT'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testTEXT() + { + // Enforce decimal and thousands separator values to UK/US, and currency code to USD + call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.'); + call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),','); + call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$'); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TEXTFORMAT'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerTEXT() { - return new testDataFileIterator('rawTestData/Calculation/TextData/TEXT.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/TEXT.data'); + } /** * @dataProvider providerVALUE */ - public function testVALUE() - { - call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.'); - call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),' '); - call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$'); - - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','VALUE'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-8); - } + public function testVALUE() + { + call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.'); + call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),' '); + call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$'); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','VALUE'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-8); + } public function providerVALUE() { - return new testDataFileIterator('rawTestData/Calculation/TextData/VALUE.data'); - } + return new testDataFileIterator('rawTestData/Calculation/TextData/VALUE.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php b/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php index 0a6ca54da..b9b74d2ac 100644 --- a/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php +++ b/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php @@ -36,12 +36,12 @@ public function provider() public function testCurrency($value, $valueBinded, $format, $thousandsSeparator, $decimalSeparator, $currencyCode) { $sheet = $this->getMock( - 'PHPExcel_Worksheet', - array('getStyle', 'getNumberFormat', 'setFormatCode','getCellCacheController') - ); + 'PHPExcel_Worksheet', + array('getStyle', 'getNumberFormat', 'setFormatCode','getCellCacheController') + ); $cache = $this->getMockBuilder('PHPExcel_CachedObjectStorage_Memory') - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $cache->expects($this->any()) ->method('getParent') ->will($this->returnValue($sheet)); @@ -64,7 +64,7 @@ public function testCurrency($value, $valueBinded, $format, $thousandsSeparator, PHPExcel_Shared_String::setDecimalSeparator($decimalSeparator); PHPExcel_Shared_String::setThousandsSeparator($thousandsSeparator); - $cell = new PHPExcel_Cell(NULL, PHPExcel_Cell_DataType::TYPE_STRING, $sheet); + $cell = new PHPExcel_Cell(null, PHPExcel_Cell_DataType::TYPE_STRING, $sheet); $binder = new PHPExcel_Cell_AdvancedValueBinder(); $binder->bindValue($cell, $value); diff --git a/unitTests/Classes/PHPExcel/Cell/DataTypeTest.php b/unitTests/Classes/PHPExcel/Cell/DataTypeTest.php index c17c5d0fc..00d965f13 100644 --- a/unitTests/Classes/PHPExcel/Cell/DataTypeTest.php +++ b/unitTests/Classes/PHPExcel/Cell/DataTypeTest.php @@ -11,14 +11,14 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } - public function testGetErrorCodes() - { - $result = call_user_func(array('PHPExcel_Cell_DataType','getErrorCodes')); - $this->assertInternalType('array', $result); - $this->assertGreaterThan(0, count($result)); - $this->assertArrayHasKey('#NULL!', $result); - } + public function testGetErrorCodes() + { + $result = call_user_func(array('PHPExcel_Cell_DataType','getErrorCodes')); + $this->assertInternalType('array', $result); + $this->assertGreaterThan(0, count($result)); + $this->assertArrayHasKey('#NULL!', $result); + } } diff --git a/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php b/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php index 1c74d96f6..a23261266 100644 --- a/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php +++ b/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php @@ -13,7 +13,7 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } protected function createCellStub() { @@ -32,12 +32,12 @@ protected function createCellStub() * @dataProvider binderProvider */ public function testBindValue($value) - { - $this->createCellStub(); + { + $this->createCellStub(); $binder = new PHPExcel_Cell_DefaultValueBinder(); - $result = $binder->bindValue($this->cellStub, $value); - $this->assertTrue($result); - } + $result = $binder->bindValue($this->cellStub, $value); + $this->assertTrue($result); + } public function binderProvider() { @@ -60,26 +60,26 @@ public function binderProvider() /** * @dataProvider providerDataTypeForValue */ - public function testDataTypeForValue() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell_DefaultValueBinder','dataTypeForValue'), $args); - $this->assertEquals($expectedResult, $result); - } + public function testDataTypeForValue() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell_DefaultValueBinder','dataTypeForValue'), $args); + $this->assertEquals($expectedResult, $result); + } public function providerDataTypeForValue() { - return new testDataFileIterator('rawTestData/Cell/DefaultValueBinder.data'); - } + return new testDataFileIterator('rawTestData/Cell/DefaultValueBinder.data'); + } - public function testDataTypeForRichTextObject() - { + public function testDataTypeForRichTextObject() + { $objRichText = new PHPExcel_RichText(); $objRichText->createText('Hello World'); $expectedResult = PHPExcel_Cell_DataType::TYPE_INLINE; - $result = call_user_func(array('PHPExcel_Cell_DefaultValueBinder','dataTypeForValue'), $objRichText); - $this->assertEquals($expectedResult, $result); - } + $result = call_user_func(array('PHPExcel_Cell_DefaultValueBinder','dataTypeForValue'), $objRichText); + $this->assertEquals($expectedResult, $result); + } } diff --git a/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php b/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php index 54910cfd5..9fbbb5a3b 100644 --- a/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php +++ b/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php @@ -11,78 +11,78 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } - public function testGetUrl() - { - $urlValue = 'http://www.phpexcel.net/'; + public function testGetUrl() + { + $urlValue = 'http://www.phpexcel.net/'; - $testInstance = new PHPExcel_Cell_Hyperlink($urlValue); + $testInstance = new PHPExcel_Cell_Hyperlink($urlValue); - $result = $testInstance->getUrl(); - $this->assertEquals($urlValue,$result); - } + $result = $testInstance->getUrl(); + $this->assertEquals($urlValue,$result); + } - public function testSetUrl() - { - $initialUrlValue = 'http://www.phpexcel.net/'; - $newUrlValue = 'http://github.com/PHPOffice/PHPExcel'; + public function testSetUrl() + { + $initialUrlValue = 'http://www.phpexcel.net/'; + $newUrlValue = 'http://github.com/PHPOffice/PHPExcel'; - $testInstance = new PHPExcel_Cell_Hyperlink($initialUrlValue); - $result = $testInstance->setUrl($newUrlValue); - $this->assertTrue($result instanceof PHPExcel_Cell_Hyperlink); + $testInstance = new PHPExcel_Cell_Hyperlink($initialUrlValue); + $result = $testInstance->setUrl($newUrlValue); + $this->assertTrue($result instanceof PHPExcel_Cell_Hyperlink); - $result = $testInstance->getUrl(); - $this->assertEquals($newUrlValue,$result); - } + $result = $testInstance->getUrl(); + $this->assertEquals($newUrlValue,$result); + } - public function testGetTooltip() - { - $tooltipValue = 'PHPExcel Web Site'; + public function testGetTooltip() + { + $tooltipValue = 'PHPExcel Web Site'; - $testInstance = new PHPExcel_Cell_Hyperlink(NULL, $tooltipValue); + $testInstance = new PHPExcel_Cell_Hyperlink(null, $tooltipValue); - $result = $testInstance->getTooltip(); - $this->assertEquals($tooltipValue,$result); - } + $result = $testInstance->getTooltip(); + $this->assertEquals($tooltipValue,$result); + } - public function testSetTooltip() - { - $initialTooltipValue = 'PHPExcel Web Site'; - $newTooltipValue = 'PHPExcel Repository on Github'; + public function testSetTooltip() + { + $initialTooltipValue = 'PHPExcel Web Site'; + $newTooltipValue = 'PHPExcel Repository on Github'; - $testInstance = new PHPExcel_Cell_Hyperlink(NULL, $initialTooltipValue); - $result = $testInstance->setTooltip($newTooltipValue); - $this->assertTrue($result instanceof PHPExcel_Cell_Hyperlink); + $testInstance = new PHPExcel_Cell_Hyperlink(null, $initialTooltipValue); + $result = $testInstance->setTooltip($newTooltipValue); + $this->assertTrue($result instanceof PHPExcel_Cell_Hyperlink); - $result = $testInstance->getTooltip(); - $this->assertEquals($newTooltipValue,$result); - } + $result = $testInstance->getTooltip(); + $this->assertEquals($newTooltipValue,$result); + } - public function testIsInternal() - { - $initialUrlValue = 'http://www.phpexcel.net/'; - $newUrlValue = 'sheet://Worksheet1!A1'; + public function testIsInternal() + { + $initialUrlValue = 'http://www.phpexcel.net/'; + $newUrlValue = 'sheet://Worksheet1!A1'; - $testInstance = new PHPExcel_Cell_Hyperlink($initialUrlValue); - $result = $testInstance->isInternal(); - $this->assertFalse($result); + $testInstance = new PHPExcel_Cell_Hyperlink($initialUrlValue); + $result = $testInstance->isInternal(); + $this->assertFalse($result); - $testInstance->setUrl($newUrlValue); - $result = $testInstance->isInternal(); - $this->assertTrue($result); - } + $testInstance->setUrl($newUrlValue); + $result = $testInstance->isInternal(); + $this->assertTrue($result); + } - public function testGetHashCode() - { - $urlValue = 'http://www.phpexcel.net/'; - $tooltipValue = 'PHPExcel Web Site'; - $initialExpectedHash = 'd84d713aed1dbbc8a7c5af183d6c7dbb'; + public function testGetHashCode() + { + $urlValue = 'http://www.phpexcel.net/'; + $tooltipValue = 'PHPExcel Web Site'; + $initialExpectedHash = 'd84d713aed1dbbc8a7c5af183d6c7dbb'; - $testInstance = new PHPExcel_Cell_Hyperlink($urlValue, $tooltipValue); + $testInstance = new PHPExcel_Cell_Hyperlink($urlValue, $tooltipValue); - $result = $testInstance->getHashCode(); - $this->assertEquals($initialExpectedHash,$result); - } + $result = $testInstance->getHashCode(); + $this->assertEquals($initialExpectedHash,$result); + } } diff --git a/unitTests/Classes/PHPExcel/CellTest.php b/unitTests/Classes/PHPExcel/CellTest.php index 11df404ce..2d8567e9c 100644 --- a/unitTests/Classes/PHPExcel/CellTest.php +++ b/unitTests/Classes/PHPExcel/CellTest.php @@ -12,284 +12,284 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } /** * @dataProvider providerColumnString */ - public function testColumnIndexFromString() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','columnIndexFromString'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testColumnIndexFromString() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','columnIndexFromString'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerColumnString() { - return new testDataFileIterator('rawTestData/ColumnString.data'); - } + return new testDataFileIterator('rawTestData/ColumnString.data'); + } public function testColumnIndexFromStringTooLong() - { - $cellAddress = 'ABCD'; - try { - $result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'),$cellAddress); - } catch (PHPExcel_Exception $e) { - $this->assertEquals($e->getMessage(), 'Column string index can not be longer than 3 characters'); - return; - } - $this->fail('An expected exception has not been raised.'); - } + { + $cellAddress = 'ABCD'; + try { + $result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Column string index can not be longer than 3 characters'); + return; + } + $this->fail('An expected exception has not been raised.'); + } public function testColumnIndexFromStringTooShort() - { - $cellAddress = ''; - try { - $result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'),$cellAddress); - } catch (PHPExcel_Exception $e) { - $this->assertEquals($e->getMessage(), 'Column string index can not be empty'); - return; - } - $this->fail('An expected exception has not been raised.'); - } + { + $cellAddress = ''; + try { + $result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Column string index can not be empty'); + return; + } + $this->fail('An expected exception has not been raised.'); + } /** * @dataProvider providerColumnIndex */ - public function testStringFromColumnIndex() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','stringFromColumnIndex'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testStringFromColumnIndex() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','stringFromColumnIndex'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerColumnIndex() { - return new testDataFileIterator('rawTestData/ColumnIndex.data'); - } + return new testDataFileIterator('rawTestData/ColumnIndex.data'); + } /** * @dataProvider providerCoordinates */ - public function testCoordinateFromString() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','coordinateFromString'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testCoordinateFromString() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','coordinateFromString'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerCoordinates() { - return new testDataFileIterator('rawTestData/CellCoordinates.data'); - } + return new testDataFileIterator('rawTestData/CellCoordinates.data'); + } public function testCoordinateFromStringWithRangeAddress() - { - $cellAddress = 'A1:AI2012'; - try { - $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); - } catch (PHPExcel_Exception $e) { - $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); - return; - } - $this->fail('An expected exception has not been raised.'); - } + { + $cellAddress = 'A1:AI2012'; + try { + $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); + return; + } + $this->fail('An expected exception has not been raised.'); + } public function testCoordinateFromStringWithEmptyAddress() - { - $cellAddress = ''; - try { - $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); - } catch (PHPExcel_Exception $e) { - $this->assertEquals($e->getMessage(), 'Cell coordinate can not be zero-length string'); - return; - } - $this->fail('An expected exception has not been raised.'); - } + { + $cellAddress = ''; + try { + $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Cell coordinate can not be zero-length string'); + return; + } + $this->fail('An expected exception has not been raised.'); + } public function testCoordinateFromStringWithInvalidAddress() - { - $cellAddress = 'AI'; - try { - $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); - } catch (PHPExcel_Exception $e) { - $this->assertEquals($e->getMessage(), 'Invalid cell coordinate '.$cellAddress); - return; - } - $this->fail('An expected exception has not been raised.'); - } + { + $cellAddress = 'AI'; + try { + $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Invalid cell coordinate '.$cellAddress); + return; + } + $this->fail('An expected exception has not been raised.'); + } /** * @dataProvider providerAbsoluteCoordinates */ - public function testAbsoluteCoordinateFromString() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','absoluteCoordinate'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testAbsoluteCoordinateFromString() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','absoluteCoordinate'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerAbsoluteCoordinates() { - return new testDataFileIterator('rawTestData/CellAbsoluteCoordinate.data'); - } + return new testDataFileIterator('rawTestData/CellAbsoluteCoordinate.data'); + } public function testAbsoluteCoordinateFromStringWithRangeAddress() - { - $cellAddress = 'A1:AI2012'; - try { - $result = call_user_func(array('PHPExcel_Cell','absoluteCoordinate'),$cellAddress); - } catch (PHPExcel_Exception $e) { - $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); - return; - } - $this->fail('An expected exception has not been raised.'); - } + { + $cellAddress = 'A1:AI2012'; + try { + $result = call_user_func(array('PHPExcel_Cell','absoluteCoordinate'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); + return; + } + $this->fail('An expected exception has not been raised.'); + } /** * @dataProvider providerAbsoluteReferences */ - public function testAbsoluteReferenceFromString() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','absoluteReference'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testAbsoluteReferenceFromString() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','absoluteReference'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerAbsoluteReferences() { - return new testDataFileIterator('rawTestData/CellAbsoluteReference.data'); - } + return new testDataFileIterator('rawTestData/CellAbsoluteReference.data'); + } public function testAbsoluteReferenceFromStringWithRangeAddress() - { - $cellAddress = 'A1:AI2012'; - try { - $result = call_user_func(array('PHPExcel_Cell','absoluteReference'),$cellAddress); - } catch (PHPExcel_Exception $e) { - $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); - return; - } - $this->fail('An expected exception has not been raised.'); - } + { + $cellAddress = 'A1:AI2012'; + try { + $result = call_user_func(array('PHPExcel_Cell','absoluteReference'),$cellAddress); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); + return; + } + $this->fail('An expected exception has not been raised.'); + } /** * @dataProvider providerSplitRange */ - public function testSplitRange() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','splitRange'),$args); - foreach($result as $key => $split) { - if (!is_array($expectedResult[$key])) { - $this->assertEquals($expectedResult[$key], $split[0]); - } else { - $this->assertEquals($expectedResult[$key], $split); - } - } - } + public function testSplitRange() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','splitRange'),$args); + foreach ($result as $key => $split) { + if (!is_array($expectedResult[$key])) { + $this->assertEquals($expectedResult[$key], $split[0]); + } else { + $this->assertEquals($expectedResult[$key], $split); + } + } + } public function providerSplitRange() { - return new testDataFileIterator('rawTestData/CellSplitRange.data'); - } + return new testDataFileIterator('rawTestData/CellSplitRange.data'); + } /** * @dataProvider providerBuildRange */ - public function testBuildRange() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','buildRange'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testBuildRange() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','buildRange'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerBuildRange() { - return new testDataFileIterator('rawTestData/CellBuildRange.data'); - } + return new testDataFileIterator('rawTestData/CellBuildRange.data'); + } public function testBuildRangeInvalid() - { - $cellRange = ''; - try { - $result = call_user_func(array('PHPExcel_Cell','buildRange'),$cellRange); - } catch (PHPExcel_Exception $e) { - $this->assertEquals($e->getMessage(), 'Range does not contain any information'); - return; - } - $this->fail('An expected exception has not been raised.'); - } + { + $cellRange = ''; + try { + $result = call_user_func(array('PHPExcel_Cell','buildRange'),$cellRange); + } catch (PHPExcel_Exception $e) { + $this->assertEquals($e->getMessage(), 'Range does not contain any information'); + return; + } + $this->fail('An expected exception has not been raised.'); + } /** * @dataProvider providerRangeBoundaries */ - public function testRangeBoundaries() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','rangeBoundaries'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testRangeBoundaries() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','rangeBoundaries'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerRangeBoundaries() { - return new testDataFileIterator('rawTestData/CellRangeBoundaries.data'); - } + return new testDataFileIterator('rawTestData/CellRangeBoundaries.data'); + } /** * @dataProvider providerRangeDimension */ - public function testRangeDimension() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','rangeDimension'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testRangeDimension() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','rangeDimension'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerRangeDimension() { - return new testDataFileIterator('rawTestData/CellRangeDimension.data'); - } + return new testDataFileIterator('rawTestData/CellRangeDimension.data'); + } /** * @dataProvider providerGetRangeBoundaries */ - public function testGetRangeBoundaries() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','getRangeBoundaries'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testGetRangeBoundaries() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','getRangeBoundaries'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerGetRangeBoundaries() { - return new testDataFileIterator('rawTestData/CellGetRangeBoundaries.data'); - } + return new testDataFileIterator('rawTestData/CellGetRangeBoundaries.data'); + } /** * @dataProvider providerExtractAllCellReferencesInRange */ - public function testExtractAllCellReferencesInRange() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','extractAllCellReferencesInRange'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testExtractAllCellReferencesInRange() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Cell','extractAllCellReferencesInRange'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerExtractAllCellReferencesInRange() { - return new testDataFileIterator('rawTestData/CellExtractAllCellReferencesInRange.data'); - } + return new testDataFileIterator('rawTestData/CellExtractAllCellReferencesInRange.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php b/unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php index 38284de9a..78ca67d71 100644 --- a/unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php +++ b/unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php @@ -11,45 +11,45 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } - - public function testSetDataType() - { - $dataTypeValues = array( - 'Number', - 'String' - ); - - $testInstance = new PHPExcel_Chart_DataSeriesValues; - - foreach($dataTypeValues as $dataTypeValue) { - $result = $testInstance->setDataType($dataTypeValue); - $this->assertTrue($result instanceof PHPExcel_Chart_DataSeriesValues); - } - } - - public function testSetInvalidDataTypeThrowsException() - { - $testInstance = new PHPExcel_Chart_DataSeriesValues; - - try { - $result = $testInstance->setDataType('BOOLEAN'); - } catch (Exception $e) { - $this->assertEquals($e->getMessage(), 'Invalid datatype for chart data series values'); - return; - } - $this->fail('An expected exception has not been raised.'); - } - - public function testGetDataType() - { - $dataTypeValue = 'String'; - - $testInstance = new PHPExcel_Chart_DataSeriesValues; - $setValue = $testInstance->setDataType($dataTypeValue); - - $result = $testInstance->getDataType(); - $this->assertEquals($dataTypeValue,$result); - } + } + + public function testSetDataType() + { + $dataTypeValues = array( + 'Number', + 'String' + ); + + $testInstance = new PHPExcel_Chart_DataSeriesValues; + + foreach ($dataTypeValues as $dataTypeValue) { + $result = $testInstance->setDataType($dataTypeValue); + $this->assertTrue($result instanceof PHPExcel_Chart_DataSeriesValues); + } + } + + public function testSetInvalidDataTypeThrowsException() + { + $testInstance = new PHPExcel_Chart_DataSeriesValues; + + try { + $result = $testInstance->setDataType('BOOLEAN'); + } catch (Exception $e) { + $this->assertEquals($e->getMessage(), 'Invalid datatype for chart data series values'); + return; + } + $this->fail('An expected exception has not been raised.'); + } + + public function testGetDataType() + { + $dataTypeValue = 'String'; + + $testInstance = new PHPExcel_Chart_DataSeriesValues; + $setValue = $testInstance->setDataType($dataTypeValue); + + $result = $testInstance->getDataType(); + $this->assertEquals($dataTypeValue,$result); + } } diff --git a/unitTests/Classes/PHPExcel/Chart/LayoutTest.php b/unitTests/Classes/PHPExcel/Chart/LayoutTest.php index f24e01c31..457b8551c 100644 --- a/unitTests/Classes/PHPExcel/Chart/LayoutTest.php +++ b/unitTests/Classes/PHPExcel/Chart/LayoutTest.php @@ -11,27 +11,27 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } - public function testSetLayoutTarget() - { - $LayoutTargetValue = 'String'; + public function testSetLayoutTarget() + { + $LayoutTargetValue = 'String'; - $testInstance = new PHPExcel_Chart_Layout; + $testInstance = new PHPExcel_Chart_Layout; - $result = $testInstance->setLayoutTarget($LayoutTargetValue); - $this->assertTrue($result instanceof PHPExcel_Chart_Layout); - } + $result = $testInstance->setLayoutTarget($LayoutTargetValue); + $this->assertTrue($result instanceof PHPExcel_Chart_Layout); + } - public function testGetLayoutTarget() - { - $LayoutTargetValue = 'String'; + public function testGetLayoutTarget() + { + $LayoutTargetValue = 'String'; - $testInstance = new PHPExcel_Chart_Layout; - $setValue = $testInstance->setLayoutTarget($LayoutTargetValue); + $testInstance = new PHPExcel_Chart_Layout; + $setValue = $testInstance->setLayoutTarget($LayoutTargetValue); - $result = $testInstance->getLayoutTarget(); - $this->assertEquals($LayoutTargetValue,$result); - } + $result = $testInstance->getLayoutTarget(); + $this->assertEquals($LayoutTargetValue,$result); + } } diff --git a/unitTests/Classes/PHPExcel/Chart/LegendTest.php b/unitTests/Classes/PHPExcel/Chart/LegendTest.php index 4c4f8df81..47af687bd 100644 --- a/unitTests/Classes/PHPExcel/Chart/LegendTest.php +++ b/unitTests/Classes/PHPExcel/Chart/LegendTest.php @@ -11,124 +11,124 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } - - public function testSetPosition() - { - $positionValues = array( - PHPExcel_Chart_Legend::POSITION_RIGHT, - PHPExcel_Chart_Legend::POSITION_LEFT, - PHPExcel_Chart_Legend::POSITION_TOP, - PHPExcel_Chart_Legend::POSITION_BOTTOM, - PHPExcel_Chart_Legend::POSITION_TOPRIGHT, - ); - - $testInstance = new PHPExcel_Chart_Legend; - - foreach($positionValues as $positionValue) { - $result = $testInstance->setPosition($positionValue); - $this->assertTrue($result); - } - } - - public function testSetInvalidPositionReturnsFalse() - { - $testInstance = new PHPExcel_Chart_Legend; - - $result = $testInstance->setPosition('BottomLeft'); - $this->assertFalse($result); - // Ensure that value is unchanged - $result = $testInstance->getPosition(); - $this->assertEquals(PHPExcel_Chart_Legend::POSITION_RIGHT,$result); - } - - public function testGetPosition() - { - $PositionValue = PHPExcel_Chart_Legend::POSITION_BOTTOM; - - $testInstance = new PHPExcel_Chart_Legend; - $setValue = $testInstance->setPosition($PositionValue); - - $result = $testInstance->getPosition(); - $this->assertEquals($PositionValue,$result); - } - - public function testSetPositionXL() - { - $positionValues = array( - PHPExcel_Chart_Legend::xlLegendPositionBottom, - PHPExcel_Chart_Legend::xlLegendPositionCorner, - PHPExcel_Chart_Legend::xlLegendPositionCustom, - PHPExcel_Chart_Legend::xlLegendPositionLeft, - PHPExcel_Chart_Legend::xlLegendPositionRight, - PHPExcel_Chart_Legend::xlLegendPositionTop, - ); - - $testInstance = new PHPExcel_Chart_Legend; - - foreach($positionValues as $positionValue) { - $result = $testInstance->setPositionXL($positionValue); - $this->assertTrue($result); - } - } - - public function testSetInvalidXLPositionReturnsFalse() - { - $testInstance = new PHPExcel_Chart_Legend; - - $result = $testInstance->setPositionXL(999); - $this->assertFalse($result); - // Ensure that value is unchanged - $result = $testInstance->getPositionXL(); - $this->assertEquals(PHPExcel_Chart_Legend::xlLegendPositionRight,$result); - } - - public function testGetPositionXL() - { - $PositionValue = PHPExcel_Chart_Legend::xlLegendPositionCorner; - - $testInstance = new PHPExcel_Chart_Legend; - $setValue = $testInstance->setPositionXL($PositionValue); - - $result = $testInstance->getPositionXL(); - $this->assertEquals($PositionValue,$result); - } - - public function testSetOverlay() - { - $overlayValues = array( - TRUE, - FALSE, - ); - - $testInstance = new PHPExcel_Chart_Legend; - - foreach($overlayValues as $overlayValue) { - $result = $testInstance->setOverlay($overlayValue); - $this->assertTrue($result); - } - } - - public function testSetInvalidOverlayReturnsFalse() - { - $testInstance = new PHPExcel_Chart_Legend; - - $result = $testInstance->setOverlay('INVALID'); - $this->assertFalse($result); - - $result = $testInstance->getOverlay(); - $this->assertFalse($result); - } - - public function testGetOverlay() - { - $OverlayValue = TRUE; - - $testInstance = new PHPExcel_Chart_Legend; - $setValue = $testInstance->setOverlay($OverlayValue); - - $result = $testInstance->getOverlay(); - $this->assertEquals($OverlayValue,$result); - } + } + + public function testSetPosition() + { + $positionValues = array( + PHPExcel_Chart_Legend::POSITION_RIGHT, + PHPExcel_Chart_Legend::POSITION_LEFT, + PHPExcel_Chart_Legend::POSITION_TOP, + PHPExcel_Chart_Legend::POSITION_BOTTOM, + PHPExcel_Chart_Legend::POSITION_TOPRIGHT, + ); + + $testInstance = new PHPExcel_Chart_Legend; + + foreach ($positionValues as $positionValue) { + $result = $testInstance->setPosition($positionValue); + $this->assertTrue($result); + } + } + + public function testSetInvalidPositionReturnsFalse() + { + $testInstance = new PHPExcel_Chart_Legend; + + $result = $testInstance->setPosition('BottomLeft'); + $this->assertFalse($result); + // Ensure that value is unchanged + $result = $testInstance->getPosition(); + $this->assertEquals(PHPExcel_Chart_Legend::POSITION_RIGHT,$result); + } + + public function testGetPosition() + { + $PositionValue = PHPExcel_Chart_Legend::POSITION_BOTTOM; + + $testInstance = new PHPExcel_Chart_Legend; + $setValue = $testInstance->setPosition($PositionValue); + + $result = $testInstance->getPosition(); + $this->assertEquals($PositionValue,$result); + } + + public function testSetPositionXL() + { + $positionValues = array( + PHPExcel_Chart_Legend::xlLegendPositionBottom, + PHPExcel_Chart_Legend::xlLegendPositionCorner, + PHPExcel_Chart_Legend::xlLegendPositionCustom, + PHPExcel_Chart_Legend::xlLegendPositionLeft, + PHPExcel_Chart_Legend::xlLegendPositionRight, + PHPExcel_Chart_Legend::xlLegendPositionTop, + ); + + $testInstance = new PHPExcel_Chart_Legend; + + foreach ($positionValues as $positionValue) { + $result = $testInstance->setPositionXL($positionValue); + $this->assertTrue($result); + } + } + + public function testSetInvalidXLPositionReturnsFalse() + { + $testInstance = new PHPExcel_Chart_Legend; + + $result = $testInstance->setPositionXL(999); + $this->assertFalse($result); + // Ensure that value is unchanged + $result = $testInstance->getPositionXL(); + $this->assertEquals(PHPExcel_Chart_Legend::xlLegendPositionRight,$result); + } + + public function testGetPositionXL() + { + $PositionValue = PHPExcel_Chart_Legend::xlLegendPositionCorner; + + $testInstance = new PHPExcel_Chart_Legend; + $setValue = $testInstance->setPositionXL($PositionValue); + + $result = $testInstance->getPositionXL(); + $this->assertEquals($PositionValue,$result); + } + + public function testSetOverlay() + { + $overlayValues = array( + true, + false, + ); + + $testInstance = new PHPExcel_Chart_Legend; + + foreach ($overlayValues as $overlayValue) { + $result = $testInstance->setOverlay($overlayValue); + $this->assertTrue($result); + } + } + + public function testSetInvalidOverlayReturnsFalse() + { + $testInstance = new PHPExcel_Chart_Legend; + + $result = $testInstance->setOverlay('INVALID'); + $this->assertFalse($result); + + $result = $testInstance->getOverlay(); + $this->assertFalse($result); + } + + public function testGetOverlay() + { + $OverlayValue = true; + + $testInstance = new PHPExcel_Chart_Legend; + $setValue = $testInstance->setOverlay($OverlayValue); + + $result = $testInstance->getOverlay(); + $this->assertEquals($OverlayValue,$result); + } } diff --git a/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php b/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php index f635dbb87..47ad1f5dc 100644 --- a/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php +++ b/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php @@ -10,46 +10,46 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } /** * @dataProvider providerInvalidXML * @expectedException PHPExcel_Reader_Exception */ - public function testInvalidXML($filename) - { + public function testInvalidXML($filename) + { $reader = $this->getMockForAbstractClass('PHPExcel_Reader_Abstract'); $expectedResult = 'FAILURE: Should throw an Exception rather than return a value'; - $result = $reader->securityScanFile($filename); - $this->assertEquals($expectedResult, $result); - } + $result = $reader->securityScanFile($filename); + $this->assertEquals($expectedResult, $result); + } public function providerInvalidXML() { $tests = []; - foreach(glob('rawTestData/Reader/XEETestInvalid*.xml') as $file) { + foreach (glob('rawTestData/Reader/XEETestInvalid*.xml') as $file) { $tests[] = [realpath($file), true]; } return $tests; - } + } /** * @dataProvider providerValidXML */ - public function testValidXML($filename, $expectedResult) - { + public function testValidXML($filename, $expectedResult) + { $reader = $this->getMockForAbstractClass('PHPExcel_Reader_Abstract'); - $result = $reader->securityScanFile($filename); - $this->assertEquals($expectedResult, $result); - } + $result = $reader->securityScanFile($filename); + $this->assertEquals($expectedResult, $result); + } public function providerValidXML() { $tests = []; - foreach(glob('rawTestData/Reader/XEETestValid*.xml') as $file) { + foreach (glob('rawTestData/Reader/XEETestValid*.xml') as $file) { $tests[] = [realpath($file), file_get_contents($file)]; } return $tests; - } + } } diff --git a/unitTests/Classes/PHPExcel/ReferenceHelperTest.php b/unitTests/Classes/PHPExcel/ReferenceHelperTest.php index f37db692e..35c4a50c4 100644 --- a/unitTests/Classes/PHPExcel/ReferenceHelperTest.php +++ b/unitTests/Classes/PHPExcel/ReferenceHelperTest.php @@ -10,49 +10,49 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } - public function testColumnSort() - { - $columnBase = $columnExpectedResult = array( - 'A','B','Z', - 'AA','AB','AZ', - 'BA','BB','BZ', - 'ZA','ZB','ZZ', - 'AAA','AAB','AAZ', - 'ABA','ABB','ABZ', - 'AZA','AZB','AZZ', - 'BAA','BAB','BAZ', - 'BBA','BBB','BBZ', - 'BZA','BZB','BZZ' - ); - shuffle($columnBase); - usort($columnBase, array('PHPExcel_ReferenceHelper','columnSort')); - foreach($columnBase as $key => $value) { - $this->assertEquals($columnExpectedResult[$key], $value); - } - } + public function testColumnSort() + { + $columnBase = $columnExpectedResult = array( + 'A','B','Z', + 'AA','AB','AZ', + 'BA','BB','BZ', + 'ZA','ZB','ZZ', + 'AAA','AAB','AAZ', + 'ABA','ABB','ABZ', + 'AZA','AZB','AZZ', + 'BAA','BAB','BAZ', + 'BBA','BBB','BBZ', + 'BZA','BZB','BZZ' + ); + shuffle($columnBase); + usort($columnBase, array('PHPExcel_ReferenceHelper','columnSort')); + foreach ($columnBase as $key => $value) { + $this->assertEquals($columnExpectedResult[$key], $value); + } + } - public function testColumnReverseSort() - { - $columnBase = $columnExpectedResult = array( - 'A','B','Z', - 'AA','AB','AZ', - 'BA','BB','BZ', - 'ZA','ZB','ZZ', - 'AAA','AAB','AAZ', - 'ABA','ABB','ABZ', - 'AZA','AZB','AZZ', - 'BAA','BAB','BAZ', - 'BBA','BBB','BBZ', - 'BZA','BZB','BZZ' - ); - shuffle($columnBase); - $columnExpectedResult = array_reverse($columnExpectedResult); - usort($columnBase, array('PHPExcel_ReferenceHelper','columnReverseSort')); - foreach($columnBase as $key => $value) { - $this->assertEquals($columnExpectedResult[$key], $value); - } - } + public function testColumnReverseSort() + { + $columnBase = $columnExpectedResult = array( + 'A','B','Z', + 'AA','AB','AZ', + 'BA','BB','BZ', + 'ZA','ZB','ZZ', + 'AAA','AAB','AAZ', + 'ABA','ABB','ABZ', + 'AZA','AZB','AZZ', + 'BAA','BAB','BAZ', + 'BBA','BBB','BBZ', + 'BZA','BZB','BZZ' + ); + shuffle($columnBase); + $columnExpectedResult = array_reverse($columnExpectedResult); + usort($columnBase, array('PHPExcel_ReferenceHelper','columnReverseSort')); + foreach ($columnBase as $key => $value) { + $this->assertEquals($columnExpectedResult[$key], $value); + } + } } diff --git a/unitTests/Classes/PHPExcel/Shared/CodePageTest.php b/unitTests/Classes/PHPExcel/Shared/CodePageTest.php index ae4aeecc5..5463e858c 100644 --- a/unitTests/Classes/PHPExcel/Shared/CodePageTest.php +++ b/unitTests/Classes/PHPExcel/Shared/CodePageTest.php @@ -12,46 +12,46 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } /** * @dataProvider providerCodePage */ - public function testCodePageNumberToName() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_CodePage','NumberToName'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testCodePageNumberToName() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_CodePage','NumberToName'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerCodePage() { - return new testDataFileIterator('rawTestData/Shared/CodePage.data'); - } + return new testDataFileIterator('rawTestData/Shared/CodePage.data'); + } public function testNumberToNameWithInvalidCodePage() - { - $invalidCodePage = 12345; - try { - $result = call_user_func(array('PHPExcel_Shared_CodePage','NumberToName'),$invalidCodePage); - } catch (Exception $e) { - $this->assertEquals($e->getMessage(), 'Unknown codepage: 12345'); - return; - } - $this->fail('An expected exception has not been raised.'); - } + { + $invalidCodePage = 12345; + try { + $result = call_user_func(array('PHPExcel_Shared_CodePage','NumberToName'),$invalidCodePage); + } catch (Exception $e) { + $this->assertEquals($e->getMessage(), 'Unknown codepage: 12345'); + return; + } + $this->fail('An expected exception has not been raised.'); + } public function testNumberToNameWithUnsupportedCodePage() - { - $unsupportedCodePage = 720; - try { - $result = call_user_func(array('PHPExcel_Shared_CodePage','NumberToName'),$unsupportedCodePage); - } catch (Exception $e) { - $this->assertEquals($e->getMessage(), 'Code page 720 not supported.'); - return; - } - $this->fail('An expected exception has not been raised.'); - } + { + $unsupportedCodePage = 720; + try { + $result = call_user_func(array('PHPExcel_Shared_CodePage','NumberToName'),$unsupportedCodePage); + } catch (Exception $e) { + $this->assertEquals($e->getMessage(), 'Code page 720 not supported.'); + return; + } + $this->fail('An expected exception has not been raised.'); + } } diff --git a/unitTests/Classes/PHPExcel/Shared/DateTest.php b/unitTests/Classes/PHPExcel/Shared/DateTest.php index 80b77d3c6..ffac7095b 100644 --- a/unitTests/Classes/PHPExcel/Shared/DateTest.php +++ b/unitTests/Classes/PHPExcel/Shared/DateTest.php @@ -12,177 +12,177 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } - public function testSetExcelCalendar() - { - $calendarValues = array( - PHPExcel_Shared_Date::CALENDAR_MAC_1904, - PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900, - ); - - foreach($calendarValues as $calendarValue) { - $result = call_user_func(array('PHPExcel_Shared_Date','setExcelCalendar'),$calendarValue); - $this->assertTrue($result); - } - } + public function testSetExcelCalendar() + { + $calendarValues = array( + PHPExcel_Shared_Date::CALENDAR_MAC_1904, + PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900, + ); + + foreach ($calendarValues as $calendarValue) { + $result = call_user_func(array('PHPExcel_Shared_Date','setExcelCalendar'),$calendarValue); + $this->assertTrue($result); + } + } public function testSetExcelCalendarWithInvalidValue() - { - $unsupportedCalendar = '2012'; - $result = call_user_func(array('PHPExcel_Shared_Date','setExcelCalendar'),$unsupportedCalendar); - $this->assertFalse($result); - } + { + $unsupportedCalendar = '2012'; + $result = call_user_func(array('PHPExcel_Shared_Date','setExcelCalendar'),$unsupportedCalendar); + $this->assertFalse($result); + } /** * @dataProvider providerDateTimeExcelToPHP1900 */ - public function testDateTimeExcelToPHP1900() - { - $result = call_user_func( - array('PHPExcel_Shared_Date','setExcelCalendar'), - PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 - ); - - $args = func_get_args(); - $expectedResult = array_pop($args); - if ($args[0] < 1) { - $expectedResult += gmmktime(0,0,0); - } - $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testDateTimeExcelToPHP1900() + { + $result = call_user_func( + array('PHPExcel_Shared_Date','setExcelCalendar'), + PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 + ); + + $args = func_get_args(); + $expectedResult = array_pop($args); + if ($args[0] < 1) { + $expectedResult += gmmktime(0,0,0); + } + $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerDateTimeExcelToPHP1900() { - return new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1900.data'); - } + return new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1900.data'); + } /** * @dataProvider providerDateTimePHPToExcel1900 */ - public function testDateTimePHPToExcel1900() - { - $result = call_user_func( - array('PHPExcel_Shared_Date','setExcelCalendar'), - PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 - ); - - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-5); - } + public function testDateTimePHPToExcel1900() + { + $result = call_user_func( + array('PHPExcel_Shared_Date','setExcelCalendar'), + PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 + ); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-5); + } public function providerDateTimePHPToExcel1900() { - return new testDataFileIterator('rawTestData/Shared/DateTimePHPToExcel1900.data'); - } + return new testDataFileIterator('rawTestData/Shared/DateTimePHPToExcel1900.data'); + } /** * @dataProvider providerDateTimeFormattedPHPToExcel1900 */ - public function testDateTimeFormattedPHPToExcel1900() - { - $result = call_user_func( - array('PHPExcel_Shared_Date','setExcelCalendar'), - PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 - ); - - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Date','FormattedPHPToExcel'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-5); - } + public function testDateTimeFormattedPHPToExcel1900() + { + $result = call_user_func( + array('PHPExcel_Shared_Date','setExcelCalendar'), + PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 + ); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','FormattedPHPToExcel'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-5); + } public function providerDateTimeFormattedPHPToExcel1900() { - return new testDataFileIterator('rawTestData/Shared/DateTimeFormattedPHPToExcel1900.data'); - } + return new testDataFileIterator('rawTestData/Shared/DateTimeFormattedPHPToExcel1900.data'); + } /** * @dataProvider providerDateTimeExcelToPHP1904 */ - public function testDateTimeExcelToPHP1904() - { - $result = call_user_func( - array('PHPExcel_Shared_Date','setExcelCalendar'), - PHPExcel_Shared_Date::CALENDAR_MAC_1904 - ); - - $args = func_get_args(); - $expectedResult = array_pop($args); - if ($args[0] < 1) { - $expectedResult += gmmktime(0,0,0); - } - $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testDateTimeExcelToPHP1904() + { + $result = call_user_func( + array('PHPExcel_Shared_Date','setExcelCalendar'), + PHPExcel_Shared_Date::CALENDAR_MAC_1904 + ); + + $args = func_get_args(); + $expectedResult = array_pop($args); + if ($args[0] < 1) { + $expectedResult += gmmktime(0,0,0); + } + $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerDateTimeExcelToPHP1904() { - return new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1904.data'); - } + return new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1904.data'); + } /** * @dataProvider providerDateTimePHPToExcel1904 */ - public function testDateTimePHPToExcel1904() - { - $result = call_user_func( - array('PHPExcel_Shared_Date','setExcelCalendar'), - PHPExcel_Shared_Date::CALENDAR_MAC_1904 - ); - - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-5); - } + public function testDateTimePHPToExcel1904() + { + $result = call_user_func( + array('PHPExcel_Shared_Date','setExcelCalendar'), + PHPExcel_Shared_Date::CALENDAR_MAC_1904 + ); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'),$args); + $this->assertEquals($expectedResult, $result, null, 1E-5); + } public function providerDateTimePHPToExcel1904() { - return new testDataFileIterator('rawTestData/Shared/DateTimePHPToExcel1904.data'); - } + return new testDataFileIterator('rawTestData/Shared/DateTimePHPToExcel1904.data'); + } /** * @dataProvider providerIsDateTimeFormatCode */ - public function testIsDateTimeFormatCode() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Date','isDateTimeFormatCode'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testIsDateTimeFormatCode() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','isDateTimeFormatCode'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerIsDateTimeFormatCode() { - return new testDataFileIterator('rawTestData/Shared/DateTimeFormatCodes.data'); - } + return new testDataFileIterator('rawTestData/Shared/DateTimeFormatCodes.data'); + } /** * @dataProvider providerDateTimeExcelToPHP1900Timezone */ - public function testDateTimeExcelToPHP1900Timezone() - { - $result = call_user_func( - array('PHPExcel_Shared_Date','setExcelCalendar'), - PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 - ); - - $args = func_get_args(); - $expectedResult = array_pop($args); - if ($args[0] < 1) { - $expectedResult += gmmktime(0,0,0); - } - $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testDateTimeExcelToPHP1900Timezone() + { + $result = call_user_func( + array('PHPExcel_Shared_Date','setExcelCalendar'), + PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900 + ); + + $args = func_get_args(); + $expectedResult = array_pop($args); + if ($args[0] < 1) { + $expectedResult += gmmktime(0,0,0); + } + $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerDateTimeExcelToPHP1900Timezone() { - return new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1900Timezone.data'); - } + return new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1900Timezone.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Shared/FileTest.php b/unitTests/Classes/PHPExcel/Shared/FileTest.php index 9deb401d9..e7b288af3 100644 --- a/unitTests/Classes/PHPExcel/Shared/FileTest.php +++ b/unitTests/Classes/PHPExcel/Shared/FileTest.php @@ -12,28 +12,28 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } - - public function testGetUseUploadTempDirectory() - { - $expectedResult = FALSE; - - $result = call_user_func(array('PHPExcel_Shared_File','getUseUploadTempDirectory')); - $this->assertEquals($expectedResult, $result); - } - - public function testSetUseUploadTempDirectory() - { - $useUploadTempDirectoryValues = array( - TRUE, - FALSE, - ); - - foreach($useUploadTempDirectoryValues as $useUploadTempDirectoryValue) { - call_user_func(array('PHPExcel_Shared_File','setUseUploadTempDirectory'),$useUploadTempDirectoryValue); - - $result = call_user_func(array('PHPExcel_Shared_File','getUseUploadTempDirectory')); - $this->assertEquals($useUploadTempDirectoryValue, $result); - } - } + } + + public function testGetUseUploadTempDirectory() + { + $expectedResult = FALSE; + + $result = call_user_func(array('PHPExcel_Shared_File','getUseUploadTempDirectory')); + $this->assertEquals($expectedResult, $result); + } + + public function testSetUseUploadTempDirectory() + { + $useUploadTempDirectoryValues = array( + true, + false, + ); + + foreach ($useUploadTempDirectoryValues as $useUploadTempDirectoryValue) { + call_user_func(array('PHPExcel_Shared_File','setUseUploadTempDirectory'),$useUploadTempDirectoryValue); + + $result = call_user_func(array('PHPExcel_Shared_File','getUseUploadTempDirectory')); + $this->assertEquals($useUploadTempDirectoryValue, $result); + } + } } diff --git a/unitTests/Classes/PHPExcel/Shared/FontTest.php b/unitTests/Classes/PHPExcel/Shared/FontTest.php index 6ce5a0261..cf11fccab 100644 --- a/unitTests/Classes/PHPExcel/Shared/FontTest.php +++ b/unitTests/Classes/PHPExcel/Shared/FontTest.php @@ -12,83 +12,83 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } - public function testGetAutoSizeMethod() - { - $expectedResult = PHPExcel_Shared_Font::AUTOSIZE_METHOD_APPROX; - - $result = call_user_func(array('PHPExcel_Shared_Font','getAutoSizeMethod')); - $this->assertEquals($expectedResult, $result); - } + public function testGetAutoSizeMethod() + { + $expectedResult = PHPExcel_Shared_Font::AUTOSIZE_METHOD_APPROX; - public function testSetAutoSizeMethod() - { - $autosizeMethodValues = array( - PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT, - PHPExcel_Shared_Font::AUTOSIZE_METHOD_APPROX, - ); + $result = call_user_func(array('PHPExcel_Shared_Font','getAutoSizeMethod')); + $this->assertEquals($expectedResult, $result); + } - foreach($autosizeMethodValues as $autosizeMethodValue) { - $result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'),$autosizeMethodValue); - $this->assertTrue($result); - } - } + public function testSetAutoSizeMethod() + { + $autosizeMethodValues = array( + PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT, + PHPExcel_Shared_Font::AUTOSIZE_METHOD_APPROX, + ); + + foreach ($autosizeMethodValues as $autosizeMethodValue) { + $result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'),$autosizeMethodValue); + $this->assertTrue($result); + } + } public function testSetAutoSizeMethodWithInvalidValue() - { - $unsupportedAutosizeMethod = 'guess'; + { + $unsupportedAutosizeMethod = 'guess'; - $result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'),$unsupportedAutosizeMethod); - $this->assertFalse($result); - } + $result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'),$unsupportedAutosizeMethod); + $this->assertFalse($result); + } /** * @dataProvider providerFontSizeToPixels */ - public function testFontSizeToPixels() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Font','fontSizeToPixels'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testFontSizeToPixels() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Font','fontSizeToPixels'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerFontSizeToPixels() { - return new testDataFileIterator('rawTestData/Shared/FontSizeToPixels.data'); - } + return new testDataFileIterator('rawTestData/Shared/FontSizeToPixels.data'); + } /** * @dataProvider providerInchSizeToPixels */ - public function testInchSizeToPixels() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Font','inchSizeToPixels'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testInchSizeToPixels() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Font','inchSizeToPixels'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerInchSizeToPixels() { - return new testDataFileIterator('rawTestData/Shared/InchSizeToPixels.data'); - } + return new testDataFileIterator('rawTestData/Shared/InchSizeToPixels.data'); + } /** * @dataProvider providerCentimeterSizeToPixels */ - public function testCentimeterSizeToPixels() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Font','centimeterSizeToPixels'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testCentimeterSizeToPixels() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_Font','centimeterSizeToPixels'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerCentimeterSizeToPixels() { - return new testDataFileIterator('rawTestData/Shared/CentimeterSizeToPixels.data'); - } + return new testDataFileIterator('rawTestData/Shared/CentimeterSizeToPixels.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php b/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php index 24a26178a..20bf8b948 100644 --- a/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php +++ b/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php @@ -12,22 +12,22 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } /** * @dataProvider providerHashPassword */ - public function testHashPassword() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_PasswordHasher','hashPassword'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testHashPassword() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Shared_PasswordHasher','hashPassword'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerHashPassword() { - return new testDataFileIterator('rawTestData/Shared/PasswordHashes.data'); - } + return new testDataFileIterator('rawTestData/Shared/PasswordHashes.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Shared/StringTest.php b/unitTests/Classes/PHPExcel/Shared/StringTest.php index 9a34729d6..4de1a6287 100644 --- a/unitTests/Classes/PHPExcel/Shared/StringTest.php +++ b/unitTests/Classes/PHPExcel/Shared/StringTest.php @@ -12,72 +12,72 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } - - public function testGetIsMbStringEnabled() - { - $result = call_user_func(array('PHPExcel_Shared_String','getIsMbstringEnabled')); - $this->assertTrue($result); - } - - public function testGetIsIconvEnabled() - { - $result = call_user_func(array('PHPExcel_Shared_String','getIsIconvEnabled')); - $this->assertTrue($result); - } - - public function testGetDecimalSeparator() - { - $localeconv = localeconv(); - - $expectedResult = (!empty($localeconv['decimal_point'])) ? $localeconv['decimal_point'] : ','; - $result = call_user_func(array('PHPExcel_Shared_String','getDecimalSeparator')); - $this->assertEquals($expectedResult, $result); - } - - public function testSetDecimalSeparator() - { - $expectedResult = ','; - $result = call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),$expectedResult); - - $result = call_user_func(array('PHPExcel_Shared_String','getDecimalSeparator')); - $this->assertEquals($expectedResult, $result); - } - - public function testGetThousandsSeparator() - { - $localeconv = localeconv(); - - $expectedResult = (!empty($localeconv['thousands_sep'])) ? $localeconv['thousands_sep'] : ','; - $result = call_user_func(array('PHPExcel_Shared_String','getThousandsSeparator')); - $this->assertEquals($expectedResult, $result); - } - - public function testSetThousandsSeparator() - { - $expectedResult = ' '; - $result = call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),$expectedResult); - - $result = call_user_func(array('PHPExcel_Shared_String','getThousandsSeparator')); - $this->assertEquals($expectedResult, $result); - } - - public function testGetCurrencyCode() - { - $localeconv = localeconv(); - - $expectedResult = (!empty($localeconv['currency_symbol'])) ? $localeconv['currency_symbol'] : '$'; - $result = call_user_func(array('PHPExcel_Shared_String','getCurrencyCode')); - $this->assertEquals($expectedResult, $result); - } - - public function testSetCurrencyCode() - { - $expectedResult = '£'; - $result = call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),$expectedResult); - - $result = call_user_func(array('PHPExcel_Shared_String','getCurrencyCode')); - $this->assertEquals($expectedResult, $result); - } + } + + public function testGetIsMbStringEnabled() + { + $result = call_user_func(array('PHPExcel_Shared_String','getIsMbstringEnabled')); + $this->assertTrue($result); + } + + public function testGetIsIconvEnabled() + { + $result = call_user_func(array('PHPExcel_Shared_String','getIsIconvEnabled')); + $this->assertTrue($result); + } + + public function testGetDecimalSeparator() + { + $localeconv = localeconv(); + + $expectedResult = (!empty($localeconv['decimal_point'])) ? $localeconv['decimal_point'] : ','; + $result = call_user_func(array('PHPExcel_Shared_String','getDecimalSeparator')); + $this->assertEquals($expectedResult, $result); + } + + public function testSetDecimalSeparator() + { + $expectedResult = ','; + $result = call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),$expectedResult); + + $result = call_user_func(array('PHPExcel_Shared_String','getDecimalSeparator')); + $this->assertEquals($expectedResult, $result); + } + + public function testGetThousandsSeparator() + { + $localeconv = localeconv(); + + $expectedResult = (!empty($localeconv['thousands_sep'])) ? $localeconv['thousands_sep'] : ','; + $result = call_user_func(array('PHPExcel_Shared_String','getThousandsSeparator')); + $this->assertEquals($expectedResult, $result); + } + + public function testSetThousandsSeparator() + { + $expectedResult = ' '; + $result = call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),$expectedResult); + + $result = call_user_func(array('PHPExcel_Shared_String','getThousandsSeparator')); + $this->assertEquals($expectedResult, $result); + } + + public function testGetCurrencyCode() + { + $localeconv = localeconv(); + + $expectedResult = (!empty($localeconv['currency_symbol'])) ? $localeconv['currency_symbol'] : '$'; + $result = call_user_func(array('PHPExcel_Shared_String','getCurrencyCode')); + $this->assertEquals($expectedResult, $result); + } + + public function testSetCurrencyCode() + { + $expectedResult = '£'; + $result = call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),$expectedResult); + + $result = call_user_func(array('PHPExcel_Shared_String','getCurrencyCode')); + $this->assertEquals($expectedResult, $result); + } } diff --git a/unitTests/Classes/PHPExcel/Shared/TimeZoneTest.php b/unitTests/Classes/PHPExcel/Shared/TimeZoneTest.php index 0e44ceb62..79ac97162 100644 --- a/unitTests/Classes/PHPExcel/Shared/TimeZoneTest.php +++ b/unitTests/Classes/PHPExcel/Shared/TimeZoneTest.php @@ -10,30 +10,30 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } - public function testSetTimezone() - { - $timezoneValues = array( - 'Europe/Prague', - 'Asia/Tokyo', - 'America/Indiana/Indianapolis', - 'Pacific/Honolulu', - 'Atlantic/St_Helena', - ); - - foreach($timezoneValues as $timezoneValue) { - $result = call_user_func(array('PHPExcel_Shared_TimeZone','setTimezone'),$timezoneValue); - $this->assertTrue($result); - } + public function testSetTimezone() + { + $timezoneValues = array( + 'Europe/Prague', + 'Asia/Tokyo', + 'America/Indiana/Indianapolis', + 'Pacific/Honolulu', + 'Atlantic/St_Helena', + ); + + foreach ($timezoneValues as $timezoneValue) { + $result = call_user_func(array('PHPExcel_Shared_TimeZone','setTimezone'),$timezoneValue); + $this->assertTrue($result); + } - } + } public function testSetTimezoneWithInvalidValue() - { - $unsupportedTimezone = 'Etc/GMT+10'; - $result = call_user_func(array('PHPExcel_Shared_TimeZone','setTimezone'),$unsupportedTimezone); - $this->assertFalse($result); - } + { + $unsupportedTimezone = 'Etc/GMT+10'; + $result = call_user_func(array('PHPExcel_Shared_TimeZone','setTimezone'),$unsupportedTimezone); + $this->assertFalse($result); + } } diff --git a/unitTests/Classes/PHPExcel/Style/ColorTest.php b/unitTests/Classes/PHPExcel/Style/ColorTest.php index f157b1a34..8b0bd541d 100644 --- a/unitTests/Classes/PHPExcel/Style/ColorTest.php +++ b/unitTests/Classes/PHPExcel/Style/ColorTest.php @@ -12,70 +12,70 @@ public function setUp() define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + } /** * @dataProvider providerColorGetRed */ - public function testGetRed() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Style_Color','getRed'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testGetRed() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Style_Color','getRed'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerColorGetRed() { - return new testDataFileIterator('rawTestData/Style/ColorGetRed.data'); - } + return new testDataFileIterator('rawTestData/Style/ColorGetRed.data'); + } /** * @dataProvider providerColorGetGreen */ - public function testGetGreen() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Style_Color','getGreen'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testGetGreen() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Style_Color','getGreen'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerColorGetGreen() { - return new testDataFileIterator('rawTestData/Style/ColorGetGreen.data'); - } + return new testDataFileIterator('rawTestData/Style/ColorGetGreen.data'); + } /** * @dataProvider providerColorGetBlue */ - public function testGetBlue() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Style_Color','getBlue'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testGetBlue() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Style_Color','getBlue'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerColorGetBlue() { - return new testDataFileIterator('rawTestData/Style/ColorGetBlue.data'); - } + return new testDataFileIterator('rawTestData/Style/ColorGetBlue.data'); + } /** * @dataProvider providerColorChangeBrightness */ - public function testChangeBrightness() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Style_Color','changeBrightness'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testChangeBrightness() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Style_Color','changeBrightness'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerColorChangeBrightness() { - return new testDataFileIterator('rawTestData/Style/ColorChangeBrightness.data'); - } + return new testDataFileIterator('rawTestData/Style/ColorChangeBrightness.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php b/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php index 13fc3ede3..4d89d929c 100644 --- a/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php +++ b/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php @@ -13,24 +13,24 @@ public function setUp() } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - PHPExcel_Shared_String::setDecimalSeparator('.'); - PHPExcel_Shared_String::setThousandsSeparator(','); - } + PHPExcel_Shared_String::setDecimalSeparator('.'); + PHPExcel_Shared_String::setThousandsSeparator(','); + } /** * @dataProvider providerNumberFormat */ - public function testFormatValueWithMask() - { - $args = func_get_args(); - $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Style_NumberFormat','toFormattedString'),$args); - $this->assertEquals($expectedResult, $result); - } + public function testFormatValueWithMask() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Style_NumberFormat','toFormattedString'),$args); + $this->assertEquals($expectedResult, $result); + } public function providerNumberFormat() { - return new testDataFileIterator('rawTestData/Style/NumberFormat.data'); - } + return new testDataFileIterator('rawTestData/Style/NumberFormat.data'); + } } diff --git a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/Column/RuleTest.php b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/Column/RuleTest.php index 65d0a85c6..6a818f78c 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/Column/RuleTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/Column/RuleTest.php @@ -3,9 +3,9 @@ class RuleTest extends PHPUnit_Framework_TestCase { - private $_testAutoFilterRuleObject; + private $_testAutoFilterRuleObject; - private $_mockAutoFilterColumnObject; + private $_mockAutoFilterColumnObject; public function setUp() { @@ -15,95 +15,95 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); $this->_mockAutoFilterColumnObject = $this->getMockBuilder('PHPExcel_Worksheet_AutoFilter_Column') - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $this->_mockAutoFilterColumnObject->expects($this->any()) - ->method('testColumnInRange') - ->will($this->returnValue(3)); + ->method('testColumnInRange') + ->will($this->returnValue(3)); - $this->_testAutoFilterRuleObject = new PHPExcel_Worksheet_AutoFilter_Column_Rule( - $this->_mockAutoFilterColumnObject - ); + $this->_testAutoFilterRuleObject = new PHPExcel_Worksheet_AutoFilter_Column_Rule( + $this->_mockAutoFilterColumnObject + ); } - public function testGetRuleType() - { - $result = $this->_testAutoFilterRuleObject->getRuleType(); - $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER, $result); - } - - public function testSetRuleType() - { - $expectedResult = PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP; - - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterRuleObject->setRuleType($expectedResult); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); - - $result = $this->_testAutoFilterRuleObject->getRuleType(); - $this->assertEquals($expectedResult, $result); - } - - public function testSetValue() - { - $expectedResult = 100; - - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterRuleObject->setValue($expectedResult); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); - - $result = $this->_testAutoFilterRuleObject->getValue(); - $this->assertEquals($expectedResult, $result); - } - - public function testGetOperator() - { - $result = $this->_testAutoFilterRuleObject->getOperator(); - $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, $result); - } - - public function testSetOperator() - { - $expectedResult = PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN; - - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterRuleObject->setOperator($expectedResult); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); - - $result = $this->_testAutoFilterRuleObject->getOperator(); - $this->assertEquals($expectedResult, $result); - } - - public function testSetGrouping() - { - $expectedResult = PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH; - - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterRuleObject->setGrouping($expectedResult); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); - - $result = $this->_testAutoFilterRuleObject->getGrouping(); - $this->assertEquals($expectedResult, $result); - } - - public function testGetParent() - { - $result = $this->_testAutoFilterRuleObject->getParent(); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - } - - public function testSetParent() - { - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterRuleObject->setParent($this->_mockAutoFilterColumnObject); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); - } - - public function testClone() - { - $result = clone $this->_testAutoFilterRuleObject; - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); - } + public function testGetRuleType() + { + $result = $this->_testAutoFilterRuleObject->getRuleType(); + $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER, $result); + } + + public function testSetRuleType() + { + $expectedResult = PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterRuleObject->setRuleType($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); + + $result = $this->_testAutoFilterRuleObject->getRuleType(); + $this->assertEquals($expectedResult, $result); + } + + public function testSetValue() + { + $expectedResult = 100; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterRuleObject->setValue($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); + + $result = $this->_testAutoFilterRuleObject->getValue(); + $this->assertEquals($expectedResult, $result); + } + + public function testGetOperator() + { + $result = $this->_testAutoFilterRuleObject->getOperator(); + $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, $result); + } + + public function testSetOperator() + { + $expectedResult = PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterRuleObject->setOperator($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); + + $result = $this->_testAutoFilterRuleObject->getOperator(); + $this->assertEquals($expectedResult, $result); + } + + public function testSetGrouping() + { + $expectedResult = PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterRuleObject->setGrouping($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); + + $result = $this->_testAutoFilterRuleObject->getGrouping(); + $this->assertEquals($expectedResult, $result); + } + + public function testGetParent() + { + $result = $this->_testAutoFilterRuleObject->getParent(); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + } + + public function testSetParent() + { + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterRuleObject->setParent($this->_mockAutoFilterColumnObject); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); + } + + public function testClone() + { + $result = clone $this->_testAutoFilterRuleObject; + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); + } } diff --git a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php index 3c1821bad..9b49f8105 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php @@ -3,11 +3,11 @@ class AutofilterColumnTest extends PHPUnit_Framework_TestCase { - private $_testInitialColumn = 'H'; + private $_testInitialColumn = 'H'; - private $_testAutoFilterColumnObject; + private $_testAutoFilterColumnObject; - private $_mockAutoFilterObject; + private $_mockAutoFilterObject; public function setUp() { @@ -17,157 +17,157 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); $this->_mockAutoFilterObject = $this->getMockBuilder('PHPExcel_Worksheet_AutoFilter') - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $this->_mockAutoFilterObject->expects($this->any()) - ->method('testColumnInRange') - ->will($this->returnValue(3)); - - $this->_testAutoFilterColumnObject = new PHPExcel_Worksheet_AutoFilter_Column( - $this->_testInitialColumn, - $this->_mockAutoFilterObject - ); - } - - public function testGetColumnIndex() - { - $result = $this->_testAutoFilterColumnObject->getColumnIndex(); - $this->assertEquals($this->_testInitialColumn, $result); - } - - public function testSetColumnIndex() - { - $expectedResult = 'L'; - - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterColumnObject->setColumnIndex($expectedResult); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - - $result = $this->_testAutoFilterColumnObject->getColumnIndex(); - $this->assertEquals($expectedResult, $result); - } - - public function testGetParent() - { - $result = $this->_testAutoFilterColumnObject->getParent(); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); - } - - public function testSetParent() - { - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterColumnObject->setParent($this->_mockAutoFilterObject); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - } - - public function testGetFilterType() - { - $result = $this->_testAutoFilterColumnObject->getFilterType(); - $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER, $result); - } - - public function testSetFilterType() - { - $result = $this->_testAutoFilterColumnObject->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - - $result = $this->_testAutoFilterColumnObject->getFilterType(); - $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER, $result); - } + ->method('testColumnInRange') + ->will($this->returnValue(3)); + + $this->_testAutoFilterColumnObject = new PHPExcel_Worksheet_AutoFilter_Column( + $this->_testInitialColumn, + $this->_mockAutoFilterObject + ); + } + + public function testGetColumnIndex() + { + $result = $this->_testAutoFilterColumnObject->getColumnIndex(); + $this->assertEquals($this->_testInitialColumn, $result); + } + + public function testSetColumnIndex() + { + $expectedResult = 'L'; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterColumnObject->setColumnIndex($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + + $result = $this->_testAutoFilterColumnObject->getColumnIndex(); + $this->assertEquals($expectedResult, $result); + } + + public function testGetParent() + { + $result = $this->_testAutoFilterColumnObject->getParent(); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + } + + public function testSetParent() + { + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterColumnObject->setParent($this->_mockAutoFilterObject); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + } + + public function testGetFilterType() + { + $result = $this->_testAutoFilterColumnObject->getFilterType(); + $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER, $result); + } + + public function testSetFilterType() + { + $result = $this->_testAutoFilterColumnObject->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + + $result = $this->_testAutoFilterColumnObject->getFilterType(); + $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER, $result); + } /** * @expectedException PHPExcel_Exception */ - public function testSetInvalidFilterTypeThrowsException() - { - $expectedResult = 'Unfiltered'; + public function testSetInvalidFilterTypeThrowsException() + { + $expectedResult = 'Unfiltered'; - $result = $this->_testAutoFilterColumnObject->setFilterType($expectedResult); - } + $result = $this->_testAutoFilterColumnObject->setFilterType($expectedResult); + } - public function testGetJoin() - { - $result = $this->_testAutoFilterColumnObject->getJoin(); - $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR, $result); - } + public function testGetJoin() + { + $result = $this->_testAutoFilterColumnObject->getJoin(); + $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR, $result); + } - public function testSetJoin() - { - $result = $this->_testAutoFilterColumnObject->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + public function testSetJoin() + { + $result = $this->_testAutoFilterColumnObject->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - $result = $this->_testAutoFilterColumnObject->getJoin(); - $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND, $result); - } + $result = $this->_testAutoFilterColumnObject->getJoin(); + $this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND, $result); + } /** * @expectedException PHPExcel_Exception */ - public function testSetInvalidJoinThrowsException() - { - $expectedResult = 'Neither'; - - $result = $this->_testAutoFilterColumnObject->setJoin($expectedResult); - } - - public function testSetAttributes() - { - $attributeSet = array( 'val' => 100, - 'maxVal' => 200 - ); - - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterColumnObject->setAttributes($attributeSet); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - } - - public function testGetAttributes() - { - $attributeSet = array( 'val' => 100, - 'maxVal' => 200 - ); - - $this->_testAutoFilterColumnObject->setAttributes($attributeSet); - - $result = $this->_testAutoFilterColumnObject->getAttributes(); - $this->assertTrue(is_array($result)); - $this->assertEquals(count($attributeSet), count($result)); - } - - public function testSetAttribute() - { - $attributeSet = array( 'val' => 100, - 'maxVal' => 200 - ); - - foreach($attributeSet as $attributeName => $attributeValue) { - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterColumnObject->setAttribute($attributeName,$attributeValue); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - } - } - - public function testGetAttribute() - { - $attributeSet = array( 'val' => 100, - 'maxVal' => 200 - ); - - $this->_testAutoFilterColumnObject->setAttributes($attributeSet); - - foreach($attributeSet as $attributeName => $attributeValue) { - $result = $this->_testAutoFilterColumnObject->getAttribute($attributeName); - $this->assertEquals($attributeValue, $result); - } - $result = $this->_testAutoFilterColumnObject->getAttribute('nonExistentAttribute'); - $this->assertNull($result); - } - - public function testClone() - { - $result = clone $this->_testAutoFilterColumnObject; - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - } + public function testSetInvalidJoinThrowsException() + { + $expectedResult = 'Neither'; + + $result = $this->_testAutoFilterColumnObject->setJoin($expectedResult); + } + + public function testSetAttributes() + { + $attributeSet = array( 'val' => 100, + 'maxVal' => 200 + ); + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterColumnObject->setAttributes($attributeSet); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + } + + public function testGetAttributes() + { + $attributeSet = array( 'val' => 100, + 'maxVal' => 200 + ); + + $this->_testAutoFilterColumnObject->setAttributes($attributeSet); + + $result = $this->_testAutoFilterColumnObject->getAttributes(); + $this->assertTrue(is_array($result)); + $this->assertEquals(count($attributeSet), count($result)); + } + + public function testSetAttribute() + { + $attributeSet = array( 'val' => 100, + 'maxVal' => 200 + ); + + foreach ($attributeSet as $attributeName => $attributeValue) { + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterColumnObject->setAttribute($attributeName,$attributeValue); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + } + } + + public function testGetAttribute() + { + $attributeSet = array( 'val' => 100, + 'maxVal' => 200 + ); + + $this->_testAutoFilterColumnObject->setAttributes($attributeSet); + + foreach ($attributeSet as $attributeName => $attributeValue) { + $result = $this->_testAutoFilterColumnObject->getAttribute($attributeName); + $this->assertEquals($attributeValue, $result); + } + $result = $this->_testAutoFilterColumnObject->getAttribute('nonExistentAttribute'); + $this->assertNull($result); + } + + public function testClone() + { + $result = clone $this->_testAutoFilterColumnObject; + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + } } diff --git a/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php b/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php index 9907eabc5..2ea396c99 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php @@ -3,9 +3,9 @@ class AutoFilterTest extends PHPUnit_Framework_TestCase { - private $_testInitialRange = 'H2:O256'; + private $_testInitialRange = 'H2:O256'; - private $_testAutoFilterObject; + private $_testAutoFilterObject; public function setUp() @@ -16,325 +16,325 @@ public function setUp() require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); $this->_mockWorksheetObject = $this->getMockBuilder('PHPExcel_Worksheet') - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $this->_mockCacheController = $this->getMockBuilder('PHPExcel_CachedObjectStorage_Memory') - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $this->_mockWorksheetObject->expects($this->any()) ->method('getCellCacheController') ->will($this->returnValue($this->_mockCacheController)); - $this->_testAutoFilterObject = new PHPExcel_Worksheet_AutoFilter( - $this->_testInitialRange, - $this->_mockWorksheetObject - ); + $this->_testAutoFilterObject = new PHPExcel_Worksheet_AutoFilter( + $this->_testInitialRange, + $this->_mockWorksheetObject + ); } - public function testToString() - { - $expectedResult = $this->_testInitialRange; - - // magic __toString should return the active autofilter range - $result = $this->_testAutoFilterObject; - $this->assertEquals($expectedResult, $result); - } - - public function testGetParent() - { - $result = $this->_testAutoFilterObject->getParent(); - $this->assertInstanceOf('PHPExcel_Worksheet', $result); - } - - public function testSetParent() - { - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterObject->setParent($this->_mockWorksheetObject); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); - } - - public function testGetRange() - { - $expectedResult = $this->_testInitialRange; - - // Result should be the active autofilter range - $result = $this->_testAutoFilterObject->getRange(); - $this->assertEquals($expectedResult, $result); - } - - public function testSetRange() - { - $ranges = array('G1:J512' => 'Worksheet1!G1:J512', - 'K1:N20' => 'K1:N20' - ); - - foreach($ranges as $actualRange => $fullRange) { - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterObject->setRange($fullRange); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); - - // Result should be the new autofilter range - $result = $this->_testAutoFilterObject->getRange(); - $this->assertEquals($actualRange, $result); - } - } - - public function testClearRange() - { - $expectedResult = ''; - - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterObject->setRange(); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); - - // Result should be a clear range - $result = $this->_testAutoFilterObject->getRange(); - $this->assertEquals($expectedResult, $result); - } + public function testToString() + { + $expectedResult = $this->_testInitialRange; + + // magic __toString should return the active autofilter range + $result = $this->_testAutoFilterObject; + $this->assertEquals($expectedResult, $result); + } + + public function testGetParent() + { + $result = $this->_testAutoFilterObject->getParent(); + $this->assertInstanceOf('PHPExcel_Worksheet', $result); + } + + public function testSetParent() + { + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setParent($this->_mockWorksheetObject); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + } + + public function testGetRange() + { + $expectedResult = $this->_testInitialRange; + + // Result should be the active autofilter range + $result = $this->_testAutoFilterObject->getRange(); + $this->assertEquals($expectedResult, $result); + } + + public function testSetRange() + { + $ranges = array('G1:J512' => 'Worksheet1!G1:J512', + 'K1:N20' => 'K1:N20' + ); + + foreach ($ranges as $actualRange => $fullRange) { + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setRange($fullRange); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + // Result should be the new autofilter range + $result = $this->_testAutoFilterObject->getRange(); + $this->assertEquals($actualRange, $result); + } + } + + public function testClearRange() + { + $expectedResult = ''; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setRange(); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + // Result should be a clear range + $result = $this->_testAutoFilterObject->getRange(); + $this->assertEquals($expectedResult, $result); + } /** * @expectedException PHPExcel_Exception */ - public function testSetRangeInvalidRange() - { - $expectedResult = 'A1'; - - $result = $this->_testAutoFilterObject->setRange($expectedResult); - } - - public function testGetColumnsEmpty() - { - // There should be no columns yet defined - $result = $this->_testAutoFilterObject->getColumns(); - $this->assertInternalType('array', $result); - $this->assertEquals(0, count($result)); - } - - public function testGetColumnOffset() - { - $columnIndexes = array( 'H' => 0, - 'K' => 3, - 'M' => 5 - ); - - // If we request a specific column by its column ID, we should get an - // integer returned representing the column offset within the range - foreach($columnIndexes as $columnIndex => $columnOffset) { - $result = $this->_testAutoFilterObject->getColumnOffset($columnIndex); - $this->assertEquals($columnOffset, $result); - } - } + public function testSetRangeInvalidRange() + { + $expectedResult = 'A1'; + + $result = $this->_testAutoFilterObject->setRange($expectedResult); + } + + public function testGetColumnsEmpty() + { + // There should be no columns yet defined + $result = $this->_testAutoFilterObject->getColumns(); + $this->assertInternalType('array', $result); + $this->assertEquals(0, count($result)); + } + + public function testGetColumnOffset() + { + $columnIndexes = array( 'H' => 0, + 'K' => 3, + 'M' => 5 + ); + + // If we request a specific column by its column ID, we should get an + // integer returned representing the column offset within the range + foreach ($columnIndexes as $columnIndex => $columnOffset) { + $result = $this->_testAutoFilterObject->getColumnOffset($columnIndex); + $this->assertEquals($columnOffset, $result); + } + } /** * @expectedException PHPExcel_Exception */ public function testGetInvalidColumnOffset() - { - $invalidColumn = 'G'; - - $result = $this->_testAutoFilterObject->getColumnOffset($invalidColumn); - } - - public function testSetColumnWithString() - { - $expectedResult = 'L'; + { + $invalidColumn = 'G'; - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterObject->setColumn($expectedResult); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + $result = $this->_testAutoFilterObject->getColumnOffset($invalidColumn); + } - $result = $this->_testAutoFilterObject->getColumns(); - // Result should be an array of PHPExcel_Worksheet_AutoFilter_Column - // objects for each column we set indexed by the column ID - $this->assertInternalType('array', $result); - $this->assertEquals(1, count($result)); - $this->assertArrayHasKey($expectedResult,$result); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$expectedResult]); - } + public function testSetColumnWithString() + { + $expectedResult = 'L'; + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setColumn($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + $result = $this->_testAutoFilterObject->getColumns(); + // Result should be an array of PHPExcel_Worksheet_AutoFilter_Column + // objects for each column we set indexed by the column ID + $this->assertInternalType('array', $result); + $this->assertEquals(1, count($result)); + $this->assertArrayHasKey($expectedResult,$result); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$expectedResult]); + } /** * @expectedException PHPExcel_Exception */ public function testSetInvalidColumnWithString() - { - $invalidColumn = 'A'; - - $result = $this->_testAutoFilterObject->setColumn($invalidColumn); - } - - public function testSetColumnWithColumnObject() - { - $expectedResult = 'M'; - $columnObject = new PHPExcel_Worksheet_AutoFilter_Column($expectedResult); - - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterObject->setColumn($columnObject); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); - - $result = $this->_testAutoFilterObject->getColumns(); - // Result should be an array of PHPExcel_Worksheet_AutoFilter_Column - // objects for each column we set indexed by the column ID - $this->assertInternalType('array', $result); - $this->assertEquals(1, count($result)); - $this->assertArrayHasKey($expectedResult,$result); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$expectedResult]); - } + { + $invalidColumn = 'A'; + + $result = $this->_testAutoFilterObject->setColumn($invalidColumn); + } + + public function testSetColumnWithColumnObject() + { + $expectedResult = 'M'; + $columnObject = new PHPExcel_Worksheet_AutoFilter_Column($expectedResult); + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setColumn($columnObject); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + $result = $this->_testAutoFilterObject->getColumns(); + // Result should be an array of PHPExcel_Worksheet_AutoFilter_Column + // objects for each column we set indexed by the column ID + $this->assertInternalType('array', $result); + $this->assertEquals(1, count($result)); + $this->assertArrayHasKey($expectedResult,$result); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$expectedResult]); + } /** * @expectedException PHPExcel_Exception */ public function testSetInvalidColumnWithObject() - { - $invalidColumn = 'E'; - $columnObject = new PHPExcel_Worksheet_AutoFilter_Column($invalidColumn); + { + $invalidColumn = 'E'; + $columnObject = new PHPExcel_Worksheet_AutoFilter_Column($invalidColumn); - $result = $this->_testAutoFilterObject->setColumn($invalidColumn); - } + $result = $this->_testAutoFilterObject->setColumn($invalidColumn); + } /** * @expectedException PHPExcel_Exception */ public function testSetColumnWithInvalidDataType() - { - $invalidColumn = 123.456; - $columnObject = new PHPExcel_Worksheet_AutoFilter_Column($invalidColumn); - - $result = $this->_testAutoFilterObject->setColumn($invalidColumn); - } - - public function testGetColumns() - { - $columnIndexes = array('L','M'); - - foreach($columnIndexes as $columnIndex) { - $this->_testAutoFilterObject->setColumn($columnIndex); - } - - $result = $this->_testAutoFilterObject->getColumns(); - // Result should be an array of PHPExcel_Worksheet_AutoFilter_Column - // objects for each column we set indexed by the column ID - $this->assertInternalType('array', $result); - $this->assertEquals(count($columnIndexes), count($result)); - foreach($columnIndexes as $columnIndex) { - $this->assertArrayHasKey($columnIndex,$result); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$columnIndex]); - } - } - - public function testGetColumn() - { - $columnIndexes = array('L','M'); - - foreach($columnIndexes as $columnIndex) { - $this->_testAutoFilterObject->setColumn($columnIndex); - } - - // If we request a specific column by its column ID, we should - // get a PHPExcel_Worksheet_AutoFilter_Column object returned - foreach($columnIndexes as $columnIndex) { - $result = $this->_testAutoFilterObject->getColumn($columnIndex); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - } - } - - public function testGetColumnByOffset() - { - $columnIndexes = array( 0 => 'H', - 3 => 'K', - 5 => 'M' - ); - - // If we request a specific column by its offset, we should - // get a PHPExcel_Worksheet_AutoFilter_Column object returned - foreach($columnIndexes as $columnIndex => $columnID) { - $result = $this->_testAutoFilterObject->getColumnByOffset($columnIndex); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - $this->assertEquals($result->getColumnIndex(),$columnID); - } - } - - public function testGetColumnIfNotSet() - { - // If we request a specific column by its column ID, we should - // get a PHPExcel_Worksheet_AutoFilter_Column object returned - $result = $this->_testAutoFilterObject->getColumn('K'); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - } + { + $invalidColumn = 123.456; + $columnObject = new PHPExcel_Worksheet_AutoFilter_Column($invalidColumn); + + $result = $this->_testAutoFilterObject->setColumn($invalidColumn); + } + + public function testGetColumns() + { + $columnIndexes = array('L','M'); + + foreach ($columnIndexes as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + + $result = $this->_testAutoFilterObject->getColumns(); + // Result should be an array of PHPExcel_Worksheet_AutoFilter_Column + // objects for each column we set indexed by the column ID + $this->assertInternalType('array', $result); + $this->assertEquals(count($columnIndexes), count($result)); + foreach ($columnIndexes as $columnIndex) { + $this->assertArrayHasKey($columnIndex,$result); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$columnIndex]); + } + } + + public function testGetColumn() + { + $columnIndexes = array('L','M'); + + foreach ($columnIndexes as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + + // If we request a specific column by its column ID, we should + // get a PHPExcel_Worksheet_AutoFilter_Column object returned + foreach ($columnIndexes as $columnIndex) { + $result = $this->_testAutoFilterObject->getColumn($columnIndex); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + } + } + + public function testGetColumnByOffset() + { + $columnIndexes = array( 0 => 'H', + 3 => 'K', + 5 => 'M' + ); + + // If we request a specific column by its offset, we should + // get a PHPExcel_Worksheet_AutoFilter_Column object returned + foreach ($columnIndexes as $columnIndex => $columnID) { + $result = $this->_testAutoFilterObject->getColumnByOffset($columnIndex); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + $this->assertEquals($result->getColumnIndex(),$columnID); + } + } + + public function testGetColumnIfNotSet() + { + // If we request a specific column by its column ID, we should + // get a PHPExcel_Worksheet_AutoFilter_Column object returned + $result = $this->_testAutoFilterObject->getColumn('K'); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); + } /** * @expectedException PHPExcel_Exception */ - public function testGetColumnWithoutRangeSet() - { - // Clear the range - $result = $this->_testAutoFilterObject->setRange(); - - $result = $this->_testAutoFilterObject->getColumn('A'); - } - - public function testClearRangeWithExistingColumns() - { - $expectedResult = ''; - - $columnIndexes = array('L','M','N'); - foreach($columnIndexes as $columnIndex) { - $this->_testAutoFilterObject->setColumn($columnIndex); - } - - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterObject->setRange(); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); - - // Range should be cleared - $result = $this->_testAutoFilterObject->getRange(); - $this->assertEquals($expectedResult, $result); - - // Column array should be cleared - $result = $this->_testAutoFilterObject->getColumns(); - $this->assertInternalType('array', $result); - $this->assertEquals(0, count($result)); - } - - public function testSetRangeWithExistingColumns() - { - $expectedResult = 'G1:J512'; - - // These columns should be retained - $columnIndexes1 = array('I','J'); - foreach($columnIndexes1 as $columnIndex) { - $this->_testAutoFilterObject->setColumn($columnIndex); - } - // These columns should be discarded - $columnIndexes2 = array('K','L','M'); - foreach($columnIndexes2 as $columnIndex) { - $this->_testAutoFilterObject->setColumn($columnIndex); - } - - // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterObject->setRange($expectedResult); - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); - - // Range should be correctly set - $result = $this->_testAutoFilterObject->getRange(); - $this->assertEquals($expectedResult, $result); - - // Only columns that existed in the original range and that - // still fall within the new range should be retained - $result = $this->_testAutoFilterObject->getColumns(); - $this->assertInternalType('array', $result); - $this->assertEquals(count($columnIndexes1), count($result)); - } - - public function testClone() - { - $columnIndexes = array('L','M'); - - foreach($columnIndexes as $columnIndex) { - $this->_testAutoFilterObject->setColumn($columnIndex); - } - - $result = clone $this->_testAutoFilterObject; - $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); - } + public function testGetColumnWithoutRangeSet() + { + // Clear the range + $result = $this->_testAutoFilterObject->setRange(); + + $result = $this->_testAutoFilterObject->getColumn('A'); + } + + public function testClearRangeWithExistingColumns() + { + $expectedResult = ''; + + $columnIndexes = array('L','M','N'); + foreach ($columnIndexes as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setRange(); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + // Range should be cleared + $result = $this->_testAutoFilterObject->getRange(); + $this->assertEquals($expectedResult, $result); + + // Column array should be cleared + $result = $this->_testAutoFilterObject->getColumns(); + $this->assertInternalType('array', $result); + $this->assertEquals(0, count($result)); + } + + public function testSetRangeWithExistingColumns() + { + $expectedResult = 'G1:J512'; + + // These columns should be retained + $columnIndexes1 = array('I','J'); + foreach ($columnIndexes1 as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + // These columns should be discarded + $columnIndexes2 = array('K','L','M'); + foreach ($columnIndexes2 as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + + // Setters return the instance to implement the fluent interface + $result = $this->_testAutoFilterObject->setRange($expectedResult); + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + + // Range should be correctly set + $result = $this->_testAutoFilterObject->getRange(); + $this->assertEquals($expectedResult, $result); + + // Only columns that existed in the original range and that + // still fall within the new range should be retained + $result = $this->_testAutoFilterObject->getColumns(); + $this->assertInternalType('array', $result); + $this->assertEquals(count($columnIndexes1), count($result)); + } + + public function testClone() + { + $columnIndexes = array('L','M'); + + foreach ($columnIndexes as $columnIndex) { + $this->_testAutoFilterObject->setColumn($columnIndex); + } + + $result = clone $this->_testAutoFilterObject; + $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); + } } diff --git a/unitTests/Classes/PHPExcel/Worksheet/CellCollectionTest.php b/unitTests/Classes/PHPExcel/Worksheet/CellCollectionTest.php index c2c130d7a..c117ef8f4 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/CellCollectionTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/CellCollectionTest.php @@ -3,29 +3,29 @@ class CellCollectionTest extends PHPUnit_Framework_TestCase { - public function setUp() - { - if (!defined('PHPEXCEL_ROOT')) - { - define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); - } - require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); - } + public function setUp() + { + if (!defined('PHPEXCEL_ROOT')) + { + define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); + } + require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + } - public function testCacheLastCell() - { - $methods = PHPExcel_CachedObjectStorageFactory::getCacheStorageMethods(); - foreach ($methods as $method) { - PHPExcel_CachedObjectStorageFactory::initialize($method); - $workbook = new PHPExcel(); - $cells = array('A1', 'A2'); - $worksheet = $workbook->getActiveSheet(); - $worksheet->setCellValue('A1', 1); - $worksheet->setCellValue('A2', 2); - $this->assertEquals($cells, $worksheet->getCellCollection(), "Cache method \"$method\"."); - PHPExcel_CachedObjectStorageFactory::finalize(); - } - } + public function testCacheLastCell() + { + $methods = PHPExcel_CachedObjectStorageFactory::getCacheStorageMethods(); + foreach ($methods as $method) { + PHPExcel_CachedObjectStorageFactory::initialize($method); + $workbook = new PHPExcel(); + $cells = array('A1', 'A2'); + $worksheet = $workbook->getActiveSheet(); + $worksheet->setCellValue('A1', 1); + $worksheet->setCellValue('A2', 2); + $this->assertEquals($cells, $worksheet->getCellCollection(), "Cache method \"$method\"."); + PHPExcel_CachedObjectStorageFactory::finalize(); + } + } } diff --git a/unitTests/Classes/PHPExcel/Worksheet/ColumnCellIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/ColumnCellIteratorTest.php index bef500ca8..49abcb044 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/ColumnCellIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/ColumnCellIteratorTest.php @@ -5,12 +5,12 @@ class ColumnCellIteratorTest extends PHPUnit_Framework_TestCase public $mockWorksheet; public $mockColumnCell; - public function setUp() - { - if (!defined('PHPEXCEL_ROOT')) { - define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); - } - require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + public function setUp() + { + if (!defined('PHPEXCEL_ROOT')) { + define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); + } + require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); $this->mockCell = $this->getMockBuilder('PHPExcel_Cell') ->disableOriginalConstructor() @@ -29,32 +29,32 @@ public function setUp() } - public function testIteratorFullRange() - { + public function testIteratorFullRange() + { $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A'); $ColumnCellIndexResult = 1; $this->assertEquals($ColumnCellIndexResult, $iterator->key()); - foreach($iterator as $key => $ColumnCell) { + foreach ($iterator as $key => $ColumnCell) { $this->assertEquals($ColumnCellIndexResult++, $key); $this->assertInstanceOf('PHPExcel_Cell', $ColumnCell); } - } + } - public function testIteratorStartEndRange() - { + public function testIteratorStartEndRange() + { $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); $ColumnCellIndexResult = 2; $this->assertEquals($ColumnCellIndexResult, $iterator->key()); - foreach($iterator as $key => $ColumnCell) { + foreach ($iterator as $key => $ColumnCell) { $this->assertEquals($ColumnCellIndexResult++, $key); $this->assertInstanceOf('PHPExcel_Cell', $ColumnCell); } - } + } - public function testIteratorSeekAndPrev() - { + public function testIteratorSeekAndPrev() + { $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); $columnIndexResult = 4; $iterator->seek(4); @@ -64,7 +64,7 @@ public function testIteratorSeekAndPrev() $iterator->prev(); $this->assertEquals($columnIndexResult - $i, $iterator->key()); } - } + } /** * @expectedException PHPExcel_Exception diff --git a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php index 7d78b6179..83d3b111e 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php @@ -5,12 +5,12 @@ class ColumnIteratorTest extends PHPUnit_Framework_TestCase public $mockWorksheet; public $mockColumn; - public function setUp() - { - if (!defined('PHPEXCEL_ROOT')) { - define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); - } - require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + public function setUp() + { + if (!defined('PHPEXCEL_ROOT')) { + define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); + } + require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); $this->mockColumn = $this->getMockBuilder('PHPExcel_Worksheet_Column') ->disableOriginalConstructor() @@ -29,32 +29,32 @@ public function setUp() } - public function testIteratorFullRange() - { + public function testIteratorFullRange() + { $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet); $columnIndexResult = 'A'; $this->assertEquals($columnIndexResult, $iterator->key()); - foreach($iterator as $key => $column) { + foreach ($iterator as $key => $column) { $this->assertEquals($columnIndexResult++, $key); $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column); } - } + } - public function testIteratorStartEndRange() - { + public function testIteratorStartEndRange() + { $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D'); $columnIndexResult = 'B'; $this->assertEquals($columnIndexResult, $iterator->key()); - foreach($iterator as $key => $column) { + foreach ($iterator as $key => $column) { $this->assertEquals($columnIndexResult++, $key); $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column); } - } + } - public function testIteratorSeekAndPrev() - { + public function testIteratorSeekAndPrev() + { $ranges = range('A','E'); $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D'); $columnIndexResult = 'D'; @@ -66,7 +66,7 @@ public function testIteratorSeekAndPrev() $expectedResult = $ranges[array_search($columnIndexResult, $ranges) - $i]; $this->assertEquals($expectedResult, $iterator->key()); } - } + } /** * @expectedException PHPExcel_Exception diff --git a/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php index cdd3c84d4..7fd425fb8 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php @@ -5,12 +5,12 @@ class RowCellIteratorTest extends PHPUnit_Framework_TestCase public $mockWorksheet; public $mockRowCell; - public function setUp() - { - if (!defined('PHPEXCEL_ROOT')) { - define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); - } - require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + public function setUp() + { + if (!defined('PHPEXCEL_ROOT')) { + define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); + } + require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); $this->mockCell = $this->getMockBuilder('PHPExcel_Cell') ->disableOriginalConstructor() @@ -29,32 +29,32 @@ public function setUp() } - public function testIteratorFullRange() - { + public function testIteratorFullRange() + { $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet); $RowCellIndexResult = 'A'; $this->assertEquals($RowCellIndexResult, $iterator->key()); - foreach($iterator as $key => $RowCell) { + foreach ($iterator as $key => $RowCell) { $this->assertEquals($RowCellIndexResult++, $key); $this->assertInstanceOf('PHPExcel_Cell', $RowCell); } - } + } - public function testIteratorStartEndRange() - { + public function testIteratorStartEndRange() + { $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); $RowCellIndexResult = 'B'; $this->assertEquals($RowCellIndexResult, $iterator->key()); - foreach($iterator as $key => $RowCell) { + foreach ($iterator as $key => $RowCell) { $this->assertEquals($RowCellIndexResult++, $key); $this->assertInstanceOf('PHPExcel_Cell', $RowCell); } - } + } - public function testIteratorSeekAndPrev() - { + public function testIteratorSeekAndPrev() + { $ranges = range('A','E'); $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); $RowCellIndexResult = 'D'; @@ -66,7 +66,7 @@ public function testIteratorSeekAndPrev() $expectedResult = $ranges[array_search($RowCellIndexResult, $ranges) - $i]; $this->assertEquals($expectedResult, $iterator->key()); } - } + } /** * @expectedException PHPExcel_Exception diff --git a/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php index 48d8b6bb1..b6098936a 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php @@ -5,12 +5,12 @@ class RowIteratorTest extends PHPUnit_Framework_TestCase public $mockWorksheet; public $mockRow; - public function setUp() - { - if (!defined('PHPEXCEL_ROOT')) { - define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); - } - require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + public function setUp() + { + if (!defined('PHPEXCEL_ROOT')) { + define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); + } + require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); $this->mockRow = $this->getMockBuilder('PHPExcel_Worksheet_Row') ->disableOriginalConstructor() @@ -29,32 +29,32 @@ public function setUp() } - public function testIteratorFullRange() - { + public function testIteratorFullRange() + { $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet); $rowIndexResult = 1; $this->assertEquals($rowIndexResult, $iterator->key()); - foreach($iterator as $key => $row) { + foreach ($iterator as $key => $row) { $this->assertEquals($rowIndexResult++, $key); $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row); } - } + } - public function testIteratorStartEndRange() - { + public function testIteratorStartEndRange() + { $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); $rowIndexResult = 2; $this->assertEquals($rowIndexResult, $iterator->key()); - foreach($iterator as $key => $row) { + foreach ($iterator as $key => $row) { $this->assertEquals($rowIndexResult++, $key); $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row); } - } + } - public function testIteratorSeekAndPrev() - { + public function testIteratorSeekAndPrev() + { $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); $columnIndexResult = 4; $iterator->seek(4); @@ -64,7 +64,7 @@ public function testIteratorSeekAndPrev() $iterator->prev(); $this->assertEquals($columnIndexResult - $i, $iterator->key()); } - } + } /** * @expectedException PHPExcel_Exception diff --git a/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php b/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php index c70c38d36..9e880fb9f 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php @@ -5,12 +5,12 @@ class WorksheetColumnTest extends PHPUnit_Framework_TestCase public $mockWorksheet; public $mockColumn; - public function setUp() - { - if (!defined('PHPEXCEL_ROOT')) { - define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); - } - require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + public function setUp() + { + if (!defined('PHPEXCEL_ROOT')) { + define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); + } + require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') ->disableOriginalConstructor() @@ -21,26 +21,26 @@ public function setUp() } - public function testInstantiateColumnDefault() - { + public function testInstantiateColumnDefault() + { $column = new PHPExcel_Worksheet_Column($this->mockWorksheet); $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column); $columnIndex = $column->getColumnIndex(); $this->assertEquals('A', $columnIndex); - } + } - public function testInstantiateColumnSpecified() - { + public function testInstantiateColumnSpecified() + { $column = new PHPExcel_Worksheet_Column($this->mockWorksheet, 'E'); $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column); $columnIndex = $column->getColumnIndex(); $this->assertEquals('E', $columnIndex); - } + } - public function testGetCellIterator() - { + public function testGetCellIterator() + { $column = new PHPExcel_Worksheet_Column($this->mockWorksheet); $cellIterator = $column->getCellIterator(); $this->assertInstanceOf('PHPExcel_Worksheet_ColumnCellIterator', $cellIterator); - } + } } diff --git a/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php b/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php index 2761b52be..059d8b202 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php @@ -5,12 +5,12 @@ class WorksheetRowTest extends PHPUnit_Framework_TestCase public $mockWorksheet; public $mockRow; - public function setUp() - { - if (!defined('PHPEXCEL_ROOT')) { - define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); - } - require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + public function setUp() + { + if (!defined('PHPEXCEL_ROOT')) { + define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); + } + require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') ->disableOriginalConstructor() @@ -21,26 +21,26 @@ public function setUp() } - public function testInstantiateRowDefault() - { + public function testInstantiateRowDefault() + { $row = new PHPExcel_Worksheet_Row($this->mockWorksheet); $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row); $rowIndex = $row->getRowIndex(); $this->assertEquals(1, $rowIndex); - } + } - public function testInstantiateRowSpecified() - { + public function testInstantiateRowSpecified() + { $row = new PHPExcel_Worksheet_Row($this->mockWorksheet, 5); $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row); $rowIndex = $row->getRowIndex(); $this->assertEquals(5, $rowIndex); - } + } - public function testGetCellIterator() - { + public function testGetCellIterator() + { $row = new PHPExcel_Worksheet_Row($this->mockWorksheet); $cellIterator = $row->getCellIterator(); $this->assertInstanceOf('PHPExcel_Worksheet_RowCellIterator', $cellIterator); - } + } } diff --git a/unitTests/testDataFileIterator.php b/unitTests/testDataFileIterator.php index 9eabe09d1..c6f3e0b2e 100644 --- a/unitTests/testDataFileIterator.php +++ b/unitTests/testDataFileIterator.php @@ -54,11 +54,11 @@ private function _parseNextDataset() } while (($testDataRow > '') && ($testDataRow{0} === '#')); // Discard any comments at the end of the line - list($testData) = explode('//',$testDataRow); + list($testData) = explode('//', $testDataRow); // Split data into an array of individual values and a result $dataSet = $this->_getcsv($testData, ',', "'"); - foreach($dataSet as &$dataValue) { + foreach ($dataSet as &$dataValue) { $dataValue = $this->_parseDataValue($dataValue); } unset($dataValue); @@ -85,23 +85,24 @@ private function _getcsv($input, $delimiter, $enclosure) return $data; } - private function _parseDataValue($dataValue) { + private function _parseDataValue($dataValue) + { // discard any white space $dataValue = trim($dataValue); // test for the required datatype and convert accordingly if (!is_numeric($dataValue)) { if($dataValue == '') { - $dataValue = NULL; + $dataValue = null; } elseif($dataValue == '""') { $dataValue = ''; } elseif(($dataValue[0] == '"') && ($dataValue[strlen($dataValue)-1] == '"')) { $dataValue = substr($dataValue,1,-1); } elseif(($dataValue[0] == '{') && ($dataValue[strlen($dataValue)-1] == '}')) { $dataValue = explode(';',substr($dataValue,1,-1)); - foreach($dataValue as &$dataRow) { - if (strpos($dataRow,'|') !== FALSE) { + foreach ($dataValue as &$dataRow) { + if (strpos($dataRow,'|') !== false) { $dataRow = explode('|',$dataRow); - foreach($dataRow as &$dataCell) { + foreach ($dataRow as &$dataCell) { $dataCell = $this->_parseDataValue($dataCell); } unset($dataCell); @@ -112,20 +113,25 @@ private function _parseDataValue($dataValue) { unset($dataRow); } else { switch (strtoupper($dataValue)) { - case 'NULL' : $dataValue = NULL; break; - case 'TRUE' : $dataValue = TRUE; break; - case 'FALSE' : $dataValue = FALSE; break; + case 'NULL': + $dataValue = null; + break; + case 'TRUE': + $dataValue = true; + break; + case 'FALSE': + $dataValue = false; + break; } } } else { - if (strpos($dataValue,'.') !== FALSE) { + if (strpos($dataValue,'.') !== false) { $dataValue = (float) $dataValue; } else { $dataValue = (int) $dataValue; } } - return $dataValue; + return $dataValue; } - } From 576effef30f26c525cff4afb7c6ef51f37b1aaef Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sun, 17 May 2015 18:10:35 +0200 Subject: [PATCH 385/467] PSR2 Fixes --- Classes/PHPExcel/Reader/Excel5.php | 16108 +++++++++++----------- Classes/PHPExcel/Reader/OOCalc.php | 6 +- Classes/PHPExcel/Shared/JAMA/Matrix.php | 8 +- unitTests/bootstrap.php | 20 +- unitTests/custom/Complex.php | 229 +- unitTests/custom/complexAssert.php | 117 +- unitTests/testDataFileIterator.php | 273 +- 7 files changed, 8379 insertions(+), 8382 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 5fd36cce4..2f8a2f8ae 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -1,8054 +1,8054 @@ -<?php -/** - * PHPExcel - * - * Copyright (c) 2006 - 2015 PHPExcel - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * @category PHPExcel - * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL - * @version ##VERSION##, ##DATE## - */ - -// Original file header of ParseXL (used as the base for this class): -// -------------------------------------------------------------------------------- -// Adapted from Excel_Spreadsheet_Reader developed by users bizon153, -// trex005, and mmp11 (SourceForge.net) -// http://sourceforge.net/projects/phpexcelreader/ -// Primary changes made by canyoncasa (dvc) for ParseXL 1.00 ... -// Modelled moreso after Perl Excel Parse/Write modules -// Added Parse_Excel_Spreadsheet object -// Reads a whole worksheet or tab as row,column array or as -// associated hash of indexed rows and named column fields -// Added variables for worksheet (tab) indexes and names -// Added an object call for loading individual woorksheets -// Changed default indexing defaults to 0 based arrays -// Fixed date/time and percent formats -// Includes patches found at SourceForge... -// unicode patch by nobody -// unpack("d") machine depedency patch by matchy -// boundsheet utf16 patch by bjaenichen -// Renamed functions for shorter names -// General code cleanup and rigor, including <80 column width -// Included a testcase Excel file and PHP example calls -// Code works for PHP 5.x - -// Primary changes made by canyoncasa (dvc) for ParseXL 1.10 ... -// http://sourceforge.net/tracker/index.php?func=detail&aid=1466964&group_id=99160&atid=623334 -// Decoding of formula conditions, results, and tokens. -// Support for user-defined named cells added as an array "namedcells" -// Patch code for user-defined named cells supports single cells only. -// NOTE: this patch only works for BIFF8 as BIFF5-7 use a different -// external sheet reference structure - - -/** PHPExcel root directory */ -if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); -} - -/** - * PHPExcel_Reader_Excel5 - * - * This class uses {@link http://sourceforge.net/projects/phpexcelreader/parseXL} - * - * @category PHPExcel - * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ -class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader -{ - // ParseXL definitions - const XLS_BIFF8 = 0x0600; - const XLS_BIFF7 = 0x0500; - const XLS_WorkbookGlobals = 0x0005; - const XLS_Worksheet = 0x0010; - - // record identifiers - const XLS_Type_FORMULA = 0x0006; - const XLS_Type_EOF = 0x000a; - const XLS_Type_PROTECT = 0x0012; - const XLS_Type_OBJECTPROTECT = 0x0063; - const XLS_Type_SCENPROTECT = 0x00dd; - const XLS_Type_PASSWORD = 0x0013; - const XLS_Type_HEADER = 0x0014; - const XLS_Type_FOOTER = 0x0015; - const XLS_Type_EXTERNSHEET = 0x0017; - const XLS_Type_DEFINEDNAME = 0x0018; - const XLS_Type_VERTICALPAGEBREAKS = 0x001a; - const XLS_Type_HORIZONTALPAGEBREAKS = 0x001b; - const XLS_Type_NOTE = 0x001c; - const XLS_Type_SELECTION = 0x001d; - const XLS_Type_DATEMODE = 0x0022; - const XLS_Type_EXTERNNAME = 0x0023; - const XLS_Type_LEFTMARGIN = 0x0026; - const XLS_Type_RIGHTMARGIN = 0x0027; - const XLS_Type_TOPMARGIN = 0x0028; - const XLS_Type_BOTTOMMARGIN = 0x0029; - const XLS_Type_PRINTGRIDLINES = 0x002b; - const XLS_Type_FILEPASS = 0x002f; - const XLS_Type_FONT = 0x0031; - const XLS_Type_CONTINUE = 0x003c; - const XLS_Type_PANE = 0x0041; - const XLS_Type_CODEPAGE = 0x0042; - const XLS_Type_DEFCOLWIDTH = 0x0055; - const XLS_Type_OBJ = 0x005d; - const XLS_Type_COLINFO = 0x007d; - const XLS_Type_IMDATA = 0x007f; - const XLS_Type_SHEETPR = 0x0081; - const XLS_Type_HCENTER = 0x0083; - const XLS_Type_VCENTER = 0x0084; - const XLS_Type_SHEET = 0x0085; - const XLS_Type_PALETTE = 0x0092; - const XLS_Type_SCL = 0x00a0; - const XLS_Type_PAGESETUP = 0x00a1; - const XLS_Type_MULRK = 0x00bd; - const XLS_Type_MULBLANK = 0x00be; - const XLS_Type_DBCELL = 0x00d7; - const XLS_Type_XF = 0x00e0; - const XLS_Type_MERGEDCELLS = 0x00e5; - const XLS_Type_MSODRAWINGGROUP = 0x00eb; - const XLS_Type_MSODRAWING = 0x00ec; - const XLS_Type_SST = 0x00fc; - const XLS_Type_LABELSST = 0x00fd; - const XLS_Type_EXTSST = 0x00ff; - const XLS_Type_EXTERNALBOOK = 0x01ae; - const XLS_Type_DATAVALIDATIONS = 0x01b2; - const XLS_Type_TXO = 0x01b6; - const XLS_Type_HYPERLINK = 0x01b8; - const XLS_Type_DATAVALIDATION = 0x01be; - const XLS_Type_DIMENSION = 0x0200; - const XLS_Type_BLANK = 0x0201; - const XLS_Type_NUMBER = 0x0203; - const XLS_Type_LABEL = 0x0204; - const XLS_Type_BOOLERR = 0x0205; - const XLS_Type_STRING = 0x0207; - const XLS_Type_ROW = 0x0208; - const XLS_Type_INDEX = 0x020b; - const XLS_Type_ARRAY = 0x0221; - const XLS_Type_DEFAULTROWHEIGHT = 0x0225; - const XLS_Type_WINDOW2 = 0x023e; - const XLS_Type_RK = 0x027e; - const XLS_Type_STYLE = 0x0293; - const XLS_Type_FORMAT = 0x041e; - const XLS_Type_SHAREDFMLA = 0x04bc; - const XLS_Type_BOF = 0x0809; - const XLS_Type_SHEETPROTECTION = 0x0867; - const XLS_Type_RANGEPROTECTION = 0x0868; - const XLS_Type_SHEETLAYOUT = 0x0862; - const XLS_Type_XFEXT = 0x087d; - const XLS_Type_PAGELAYOUTVIEW = 0x088b; - const XLS_Type_UNKNOWN = 0xffff; - - // Encryption type - const MS_BIFF_CRYPTO_NONE = 0; - const MS_BIFF_CRYPTO_XOR = 1; - const MS_BIFF_CRYPTO_RC4 = 2; - - // Size of stream blocks when using RC4 encryption - const REKEY_BLOCK = 0x400; - - /** - * Summary Information stream data. - * - * @var string - */ - private $_summaryInformation; - - /** - * Extended Summary Information stream data. - * - * @var string - */ - private $_documentSummaryInformation; - - /** - * User-Defined Properties stream data. - * - * @var string - */ - private $_userDefinedProperties; - - /** - * Workbook stream data. (Includes workbook globals substream as well as sheet substreams) - * - * @var string - */ - private $_data; - - /** - * Size in bytes of $this->_data - * - * @var int - */ - private $_dataSize; - - /** - * Current position in stream - * - * @var integer - */ - private $_pos; - - /** - * Workbook to be returned by the reader. - * - * @var PHPExcel - */ - private $_phpExcel; - - /** - * Worksheet that is currently being built by the reader. - * - * @var PHPExcel_Worksheet - */ - private $_phpSheet; - - /** - * BIFF version - * - * @var int - */ - private $_version; - - /** - * Codepage set in the Excel file being read. Only important for BIFF5 (Excel 5.0 - Excel 95) - * For BIFF8 (Excel 97 - Excel 2003) this will always have the value 'UTF-16LE' - * - * @var string - */ - private $_codepage; - - /** - * Shared formats - * - * @var array - */ - private $_formats; - - /** - * Shared fonts - * - * @var array - */ - private $_objFonts; - - /** - * Color palette - * - * @var array - */ - private $_palette; - - /** - * Worksheets - * - * @var array - */ - private $_sheets; - - /** - * External books - * - * @var array - */ - private $_externalBooks; - - /** - * REF structures. Only applies to BIFF8. - * - * @var array - */ - private $_ref; - - /** - * External names - * - * @var array - */ - private $_externalNames; - - /** - * Defined names - * - * @var array - */ - private $_definedname; - - /** - * Shared strings. Only applies to BIFF8. - * - * @var array - */ - private $_sst; - - /** - * Panes are frozen? (in sheet currently being read). See WINDOW2 record. - * - * @var boolean - */ - private $_frozen; - - /** - * Fit printout to number of pages? (in sheet currently being read). See SHEETPR record. - * - * @var boolean - */ - private $_isFitToPages; - - /** - * Objects. One OBJ record contributes with one entry. - * - * @var array - */ - private $_objs; - - /** - * Text Objects. One TXO record corresponds with one entry. - * - * @var array - */ - private $_textObjects; - - /** - * Cell Annotations (BIFF8) - * - * @var array - */ - private $_cellNotes; - - /** - * The combined MSODRAWINGGROUP data - * - * @var string - */ - private $_drawingGroupData; - - /** - * The combined MSODRAWING data (per sheet) - * - * @var string - */ - private $_drawingData; - - /** - * Keep track of XF index - * - * @var int - */ - private $_xfIndex; - - /** - * Mapping of XF index (that is a cell XF) to final index in cellXf collection - * - * @var array - */ - private $_mapCellXfIndex; - - /** - * Mapping of XF index (that is a style XF) to final index in cellStyleXf collection - * - * @var array - */ - private $_mapCellStyleXfIndex; - - /** - * The shared formulas in a sheet. One SHAREDFMLA record contributes with one value. - * - * @var array - */ - private $_sharedFormulas; - - /** - * The shared formula parts in a sheet. One FORMULA record contributes with one value if it - * refers to a shared formula. - * - * @var array - */ - private $_sharedFormulaParts; - - /** - * The type of encryption in use - * - * @var int - */ - private $_encryption = 0; - - /** - * The position in the stream after which contents are encrypted - * - * @var int - */ - private $_encryptionStartPos = false; - - /** - * The current RC4 decryption object - * - * @var PHPExcel_Reader_Excel5_RC4 - */ - private $_rc4Key = null; - - /** - * The position in the stream that the RC4 decryption object was left at - * - * @var int - */ - private $_rc4Pos = 0; - - /** - * The current MD5 context state - * - * @var string - */ - private $_md5Ctxt = null; - - /** - * Create a new PHPExcel_Reader_Excel5 instance - */ - public function __construct() - { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - } - - /** - * Can the current PHPExcel_Reader_IReader read the file? - * - * @param string $pFilename - * @return boolean - * @throws PHPExcel_Reader_Exception - */ - public function canRead($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - try { - // Use ParseXL for the hard work. - $ole = new PHPExcel_Shared_OLERead(); - - // get excel data - $res = $ole->read($pFilename); - return true; - } catch (PHPExcel_Exception $e) { - return false; - } - } - - /** - * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetNames($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $worksheetNames = array(); - - // Read the OLE file - $this->_loadOLE($pFilename); - - // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); - - $this->_pos = 0; - $this->_sheets = array(); - - // Parse Workbook Global Substream - while ($this->_pos < $this->_dataSize) { - $code = self::_GetInt2d($this->_data, $this->_pos); - - switch ($code) { - case self::XLS_Type_BOF: - $this->_readBof(); - break; - case self::XLS_Type_SHEET: - $this->_readSheet(); - break; - case self::XLS_Type_EOF: - $this->_readDefault(); - break 2; - default: - $this->_readDefault(); - break; - } - } - - foreach ($this->_sheets as $sheet) { - if ($sheet['sheetType'] != 0x00) { - // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module - continue; - } - - $worksheetNames[] = $sheet['name']; - } - - return $worksheetNames; - } - - - /** - * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) - * - * @param string $pFilename - * @throws PHPExcel_Reader_Exception - */ - public function listWorksheetInfo($pFilename) - { - // Check if file exists - if (!file_exists($pFilename)) { - throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); - } - - $worksheetInfo = array(); - - // Read the OLE file - $this->_loadOLE($pFilename); - - // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); - - // initialize - $this->_pos = 0; - $this->_sheets = array(); - - // Parse Workbook Global Substream - while ($this->_pos < $this->_dataSize) { - $code = self::_GetInt2d($this->_data, $this->_pos); - - switch ($code) { - case self::XLS_Type_BOF: - $this->_readBof(); - break; - case self::XLS_Type_SHEET: - $this->_readSheet(); - break; - case self::XLS_Type_EOF: - $this->_readDefault(); - break 2; - default: - $this->_readDefault(); - break; - } - } - - // Parse the individual sheets - foreach ($this->_sheets as $sheet) { - if ($sheet['sheetType'] != 0x00) { - // 0x00: Worksheet - // 0x02: Chart - // 0x06: Visual Basic module - continue; - } - - $tmpInfo = array(); - $tmpInfo['worksheetName'] = $sheet['name']; - $tmpInfo['lastColumnLetter'] = 'A'; - $tmpInfo['lastColumnIndex'] = 0; - $tmpInfo['totalRows'] = 0; - $tmpInfo['totalColumns'] = 0; - - $this->_pos = $sheet['offset']; - - while ($this->_pos <= $this->_dataSize - 4) { - $code = self::_GetInt2d($this->_data, $this->_pos); - - switch ($code) { - case self::XLS_Type_RK: - case self::XLS_Type_LABELSST: - case self::XLS_Type_NUMBER: - case self::XLS_Type_FORMULA: - case self::XLS_Type_BOOLERR: - case self::XLS_Type_LABEL: - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - $rowIndex = self::_GetInt2d($recordData, 0) + 1; - $columnIndex = self::_GetInt2d($recordData, 2); - - $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); - $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); - break; - case self::XLS_Type_BOF: - $this->_readBof(); - break; - case self::XLS_Type_EOF: - $this->_readDefault(); - break 2; - default: - $this->_readDefault(); - break; - } - } - - $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); - $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; - - $worksheetInfo[] = $tmpInfo; - } - - return $worksheetInfo; - } - - - /** - * Loads PHPExcel from file - * - * @param string $pFilename - * @return PHPExcel - * @throws PHPExcel_Reader_Exception - */ - public function load($pFilename) - { - // Read the OLE file - $this->_loadOLE($pFilename); - - // Initialisations - $this->_phpExcel = new PHPExcel; - $this->_phpExcel->removeSheetByIndex(0); // remove 1st sheet - if (!$this->_readDataOnly) { - $this->_phpExcel->removeCellStyleXfByIndex(0); // remove the default style - $this->_phpExcel->removeCellXfByIndex(0); // remove the default style - } - - // Read the summary information stream (containing meta data) - $this->_readSummaryInformation(); - - // Read the Additional document summary information stream (containing application-specific meta data) - $this->_readDocumentSummaryInformation(); - - // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); - - // initialize - $this->_pos = 0; - $this->_codepage = 'CP1252'; - $this->_formats = array(); - $this->_objFonts = array(); - $this->_palette = array(); - $this->_sheets = array(); - $this->_externalBooks = array(); - $this->_ref = array(); - $this->_definedname = array(); - $this->_sst = array(); - $this->_drawingGroupData = ''; - $this->_xfIndex = ''; - $this->_mapCellXfIndex = array(); - $this->_mapCellStyleXfIndex = array(); - - // Parse Workbook Global Substream - while ($this->_pos < $this->_dataSize) { - $code = self::_GetInt2d($this->_data, $this->_pos); - - switch ($code) { - case self::XLS_Type_BOF: - $this->_readBof(); - break; - case self::XLS_Type_FILEPASS: - $this->_readFilepass(); - break; - case self::XLS_Type_CODEPAGE: - $this->_readCodepage(); - break; - case self::XLS_Type_DATEMODE: - $this->_readDateMode(); - break; - case self::XLS_Type_FONT: - $this->_readFont(); - break; - case self::XLS_Type_FORMAT: - $this->_readFormat(); - break; - case self::XLS_Type_XF: - $this->_readXf(); - break; - case self::XLS_Type_XFEXT: - $this->_readXfExt(); - break; - case self::XLS_Type_STYLE: - $this->_readStyle(); - break; - case self::XLS_Type_PALETTE: - $this->_readPalette(); - break; - case self::XLS_Type_SHEET: - $this->_readSheet(); - break; - case self::XLS_Type_EXTERNALBOOK: - $this->_readExternalBook(); - break; - case self::XLS_Type_EXTERNNAME: - $this->_readExternName(); - break; - case self::XLS_Type_EXTERNSHEET: - $this->_readExternSheet(); - break; - case self::XLS_Type_DEFINEDNAME: - $this->_readDefinedName(); - break; - case self::XLS_Type_MSODRAWINGGROUP: - $this->_readMsoDrawingGroup(); - break; - case self::XLS_Type_SST: - $this->_readSst(); - break; - case self::XLS_Type_EOF: - $this->_readDefault(); - break 2; - default: - $this->_readDefault(); - break; - } - } - - // Resolve indexed colors for font, fill, and border colors - // Cannot be resolved already in XF record, because PALETTE record comes afterwards - if (!$this->_readDataOnly) { - foreach ($this->_objFonts as $objFont) { - if (isset($objFont->colorIndex)) { - $color = self::_readColor($objFont->colorIndex, $this->_palette, $this->_version); - $objFont->getColor()->setRGB($color['rgb']); - } - } - - foreach ($this->_phpExcel->getCellXfCollection() as $objStyle) { - // fill start and end color - $fill = $objStyle->getFill(); - - if (isset($fill->startcolorIndex)) { - $startColor = self::_readColor($fill->startcolorIndex, $this->_palette, $this->_version); - $fill->getStartColor()->setRGB($startColor['rgb']); - } - if (isset($fill->endcolorIndex)) { - $endColor = self::_readColor($fill->endcolorIndex, $this->_palette, $this->_version); - $fill->getEndColor()->setRGB($endColor['rgb']); - } - - // border colors - $top = $objStyle->getBorders()->getTop(); - $right = $objStyle->getBorders()->getRight(); - $bottom = $objStyle->getBorders()->getBottom(); - $left = $objStyle->getBorders()->getLeft(); - $diagonal = $objStyle->getBorders()->getDiagonal(); - - if (isset($top->colorIndex)) { - $borderTopColor = self::_readColor($top->colorIndex, $this->_palette, $this->_version); - $top->getColor()->setRGB($borderTopColor['rgb']); - } - if (isset($right->colorIndex)) { - $borderRightColor = self::_readColor($right->colorIndex, $this->_palette, $this->_version); - $right->getColor()->setRGB($borderRightColor['rgb']); - } - if (isset($bottom->colorIndex)) { - $borderBottomColor = self::_readColor($bottom->colorIndex, $this->_palette, $this->_version); - $bottom->getColor()->setRGB($borderBottomColor['rgb']); - } - if (isset($left->colorIndex)) { - $borderLeftColor = self::_readColor($left->colorIndex, $this->_palette, $this->_version); - $left->getColor()->setRGB($borderLeftColor['rgb']); - } - if (isset($diagonal->colorIndex)) { - $borderDiagonalColor = self::_readColor($diagonal->colorIndex, $this->_palette, $this->_version); - $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']); - } - } - } - - // treat MSODRAWINGGROUP records, workbook-level Escher - if (!$this->_readDataOnly && $this->_drawingGroupData) { - $escherWorkbook = new PHPExcel_Shared_Escher(); - $reader = new PHPExcel_Reader_Excel5_Escher($escherWorkbook); - $escherWorkbook = $reader->load($this->_drawingGroupData); - - // debug Escher stream - //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); - //$debug->load($this->_drawingGroupData); - } - - // Parse the individual sheets - foreach ($this->_sheets as $sheet) { - if ($sheet['sheetType'] != 0x00) { - // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module - continue; - } - - // check if sheet should be skipped - if (isset($this->_loadSheetsOnly) && !in_array($sheet['name'], $this->_loadSheetsOnly)) { - continue; - } - - // add sheet to PHPExcel object - $this->_phpSheet = $this->_phpExcel->createSheet(); - // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula - // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet - // name in line with the formula, not the reverse - $this->_phpSheet->setTitle($sheet['name'], false); - $this->_phpSheet->setSheetState($sheet['sheetState']); - - $this->_pos = $sheet['offset']; - - // Initialize isFitToPages. May change after reading SHEETPR record. - $this->_isFitToPages = false; - - // Initialize drawingData - $this->_drawingData = ''; - - // Initialize objs - $this->_objs = array(); - - // Initialize shared formula parts - $this->_sharedFormulaParts = array(); - - // Initialize shared formulas - $this->_sharedFormulas = array(); - - // Initialize text objs - $this->_textObjects = array(); - - // Initialize cell annotations - $this->_cellNotes = array(); - $this->textObjRef = -1; - - while ($this->_pos <= $this->_dataSize - 4) { - $code = self::_GetInt2d($this->_data, $this->_pos); - - switch ($code) { - case self::XLS_Type_BOF: - $this->_readBof(); - break; - case self::XLS_Type_PRINTGRIDLINES: - $this->_readPrintGridlines(); - break; - case self::XLS_Type_DEFAULTROWHEIGHT: - $this->_readDefaultRowHeight(); - break; - case self::XLS_Type_SHEETPR: - $this->_readSheetPr(); - break; - case self::XLS_Type_HORIZONTALPAGEBREAKS: - $this->_readHorizontalPageBreaks(); - break; - case self::XLS_Type_VERTICALPAGEBREAKS: - $this->_readVerticalPageBreaks(); - break; - case self::XLS_Type_HEADER: - $this->_readHeader(); - break; - case self::XLS_Type_FOOTER: - $this->_readFooter(); - break; - case self::XLS_Type_HCENTER: - $this->_readHcenter(); - break; - case self::XLS_Type_VCENTER: - $this->_readVcenter(); - break; - case self::XLS_Type_LEFTMARGIN: - $this->_readLeftMargin(); - break; - case self::XLS_Type_RIGHTMARGIN: - $this->_readRightMargin(); - break; - case self::XLS_Type_TOPMARGIN: - $this->_readTopMargin(); - break; - case self::XLS_Type_BOTTOMMARGIN: - $this->_readBottomMargin(); - break; - case self::XLS_Type_PAGESETUP: - $this->_readPageSetup(); - break; - case self::XLS_Type_PROTECT: - $this->_readProtect(); - break; - case self::XLS_Type_SCENPROTECT: - $this->_readScenProtect(); - break; - case self::XLS_Type_OBJECTPROTECT: - $this->_readObjectProtect(); - break; - case self::XLS_Type_PASSWORD: - $this->_readPassword(); - break; - case self::XLS_Type_DEFCOLWIDTH: - $this->_readDefColWidth(); - break; - case self::XLS_Type_COLINFO: - $this->_readColInfo(); - break; - case self::XLS_Type_DIMENSION: - $this->_readDefault(); - break; - case self::XLS_Type_ROW: - $this->_readRow(); - break; - case self::XLS_Type_DBCELL: - $this->_readDefault(); - break; - case self::XLS_Type_RK: - $this->_readRk(); - break; - case self::XLS_Type_LABELSST: - $this->_readLabelSst(); - break; - case self::XLS_Type_MULRK: - $this->_readMulRk(); - break; - case self::XLS_Type_NUMBER: - $this->_readNumber(); - break; - case self::XLS_Type_FORMULA: - $this->_readFormula(); - break; - case self::XLS_Type_SHAREDFMLA: - $this->_readSharedFmla(); - break; - case self::XLS_Type_BOOLERR: - $this->_readBoolErr(); - break; - case self::XLS_Type_MULBLANK: - $this->_readMulBlank(); - break; - case self::XLS_Type_LABEL: - $this->_readLabel(); - break; - case self::XLS_Type_BLANK: - $this->_readBlank(); - break; - case self::XLS_Type_MSODRAWING: - $this->_readMsoDrawing(); - break; - case self::XLS_Type_OBJ: - $this->_readObj(); - break; - case self::XLS_Type_WINDOW2: - $this->_readWindow2(); - break; - case self::XLS_Type_PAGELAYOUTVIEW: - $this->_readPageLayoutView(); - break; - case self::XLS_Type_SCL: - $this->_readScl(); - break; - case self::XLS_Type_PANE: - $this->_readPane(); - break; - case self::XLS_Type_SELECTION: - $this->_readSelection(); - break; - case self::XLS_Type_MERGEDCELLS: - $this->_readMergedCells(); - break; - case self::XLS_Type_HYPERLINK: - $this->_readHyperLink(); - break; - case self::XLS_Type_DATAVALIDATIONS: - $this->_readDataValidations(); - break; - case self::XLS_Type_DATAVALIDATION: - $this->_readDataValidation(); - break; - case self::XLS_Type_SHEETLAYOUT: - $this->_readSheetLayout(); - break; - case self::XLS_Type_SHEETPROTECTION: - $this->_readSheetProtection(); - break; - case self::XLS_Type_RANGEPROTECTION: - $this->_readRangeProtection(); - break; - case self::XLS_Type_NOTE: - $this->_readNote(); - break; - //case self::XLS_Type_IMDATA: $this->_readImData(); break; - case self::XLS_Type_TXO: - $this->_readTextObject(); - break; - case self::XLS_Type_CONTINUE: - $this->_readContinue(); - break; - case self::XLS_Type_EOF: - $this->_readDefault(); - break 2; - default: - $this->_readDefault(); - break; - } - - } - - // treat MSODRAWING records, sheet-level Escher - if (!$this->_readDataOnly && $this->_drawingData) { - $escherWorksheet = new PHPExcel_Shared_Escher(); - $reader = new PHPExcel_Reader_Excel5_Escher($escherWorksheet); - $escherWorksheet = $reader->load($this->_drawingData); - - // debug Escher stream - //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); - //$debug->load($this->_drawingData); - - // get all spContainers in one long array, so they can be mapped to OBJ records - $allSpContainers = $escherWorksheet->getDgContainer()->getSpgrContainer()->getAllSpContainers(); - } - - // treat OBJ records - foreach ($this->_objs as $n => $obj) { -// echo '<hr /><b>Object</b> reference is ', $n,'<br />'; -// var_dump($obj); -// echo '<br />'; - - // the first shape container never has a corresponding OBJ record, hence $n + 1 - if (isset($allSpContainers[$n + 1]) && is_object($allSpContainers[$n + 1])) { - $spContainer = $allSpContainers[$n + 1]; - - // we skip all spContainers that are a part of a group shape since we cannot yet handle those - if ($spContainer->getNestingLevel() > 1) { - continue; - } - - // calculate the width and height of the shape - list($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($spContainer->getStartCoordinates()); - list($endColumn, $endRow) = PHPExcel_Cell::coordinateFromString($spContainer->getEndCoordinates()); - - $startOffsetX = $spContainer->getStartOffsetX(); - $startOffsetY = $spContainer->getStartOffsetY(); - $endOffsetX = $spContainer->getEndOffsetX(); - $endOffsetY = $spContainer->getEndOffsetY(); - - $width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX); - $height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY); - - // calculate offsetX and offsetY of the shape - $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024; - $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256; - - switch ($obj['otObjType']) { - case 0x19: - // Note -// echo 'Cell Annotation Object<br />'; -// echo 'Object ID is ', $obj['idObjID'],'<br />'; - if (isset($this->_cellNotes[$obj['idObjID']])) { - $cellNote = $this->_cellNotes[$obj['idObjID']]; - - if (isset($this->_textObjects[$obj['idObjID']])) { - $textObject = $this->_textObjects[$obj['idObjID']]; - $this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject; - } - } - break; - case 0x08: -// echo 'Picture Object<br />'; - // picture - // get index to BSE entry (1-based) - $BSEindex = $spContainer->getOPT(0x0104); - $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection(); - $BSE = $BSECollection[$BSEindex - 1]; - $blipType = $BSE->getBlipType(); - - // need check because some blip types are not supported by Escher reader such as EMF - if ($blip = $BSE->getBlip()) { - $ih = imagecreatefromstring($blip->getData()); - $drawing = new PHPExcel_Worksheet_MemoryDrawing(); - $drawing->setImageResource($ih); - - // width, height, offsetX, offsetY - $drawing->setResizeProportional(false); - $drawing->setWidth($width); - $drawing->setHeight($height); - $drawing->setOffsetX($offsetX); - $drawing->setOffsetY($offsetY); - - switch ($blipType) { - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: - $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); - $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG); - break; - case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: - $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG); - $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG); - break; - } - - $drawing->setWorksheet($this->_phpSheet); - $drawing->setCoordinates($spContainer->getStartCoordinates()); - } - break; - default: - // other object type - break; - } - } - } - - // treat SHAREDFMLA records - if ($this->_version == self::XLS_BIFF8) { - foreach ($this->_sharedFormulaParts as $cell => $baseCell) { - list($column, $row) = PHPExcel_Cell::coordinateFromString($cell); - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { - $formula = $this->_getFormulaFromStructure($this->_sharedFormulas[$baseCell], $cell); - $this->_phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); - } - } - } - - if (!empty($this->_cellNotes)) { - foreach ($this->_cellNotes as $note => $noteDetails) { - if (!isset($noteDetails['objTextData'])) { - if (isset($this->_textObjects[$note])) { - $textObject = $this->_textObjects[$note]; - $noteDetails['objTextData'] = $textObject; - } else { - $noteDetails['objTextData']['text'] = ''; - } - } -// echo '<b>Cell annotation ', $note,'</b><br />'; -// var_dump($noteDetails); -// echo '<br />'; - $cellAddress = str_replace('$', '', $noteDetails['cellRef']); - $this->_phpSheet->getComment($cellAddress)->setAuthor($noteDetails['author'])->setText($this->_parseRichText($noteDetails['objTextData']['text'])); - } - } - } - - // add the named ranges (defined names) - foreach ($this->_definedname as $definedName) { - if ($definedName['isBuiltInName']) { - switch ($definedName['name']) { - case pack('C', 0x06): - // print area - // in general, formula looks like this: Foo!$C$7:$J$66,Bar!$A$1:$IV$2 - $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? - - $extractedRanges = array(); - foreach ($ranges as $range) { - // $range should look like one of these - // Foo!$C$7:$J$66 - // Bar!$A$1:$IV$2 - $explodes = explode('!', $range); // FIXME: what if sheetname contains exclamation mark? - $sheetName = trim($explodes[0], "'"); - if (count($explodes) == 2) { - if (strpos($explodes[1], ':') === false) { - $explodes[1] = $explodes[1] . ':' . $explodes[1]; - } - $extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66 - } - } - if ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) { - $docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges)); // C7:J66,A1:IV2 - } - break; - case pack('C', 0x07): - // print titles (repeating rows) - // Assuming BIFF8, there are 3 cases - // 1. repeating rows - // formula looks like this: Sheet!$A$1:$IV$2 - // rows 1-2 repeat - // 2. repeating columns - // formula looks like this: Sheet!$A$1:$B$65536 - // columns A-B repeat - // 3. both repeating rows and repeating columns - // formula looks like this: Sheet!$A$1:$B$65536,Sheet!$A$1:$IV$2 - $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? - foreach ($ranges as $range) { - // $range should look like this one of these - // Sheet!$A$1:$B$65536 - // Sheet!$A$1:$IV$2 - $explodes = explode('!', $range); - if (count($explodes) == 2) { - if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) { - $extractedRange = $explodes[1]; - $extractedRange = str_replace('$', '', $extractedRange); - - $coordinateStrings = explode(':', $extractedRange); - if (count($coordinateStrings) == 2) { - list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[0]); - list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[1]); - - if ($firstColumn == 'A' and $lastColumn == 'IV') { - // then we have repeating rows - $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($firstRow, $lastRow)); - } elseif ($firstRow == 1 and $lastRow == 65536) { - // then we have repeating columns - $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($firstColumn, $lastColumn)); - } - } - } - } - } - break; - } - } else { - // Extract range - $explodes = explode('!', $definedName['formula']); - - if (count($explodes) == 2) { - if (($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) || - ($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0], "'")))) { - $extractedRange = $explodes[1]; - $extractedRange = str_replace('$', '', $extractedRange); - - $localOnly = ($definedName['scope'] == 0) ? false : true; - - $scope = ($definedName['scope'] == 0) ? null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']); - - $this->_phpExcel->addNamedRange(new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope)); - } - } else { - // Named Value - // TODO Provide support for named values - } - } - } - $this->_data = null; - - return $this->_phpExcel; - } - - /** - * Read record data from stream, decrypting as required - * - * @param string $data Data stream to read from - * @param int $pos Position to start reading from - * @param int $length Record data length - * - * @return string Record data - */ - private function _readRecordData($data, $pos, $len) - { - $data = substr($data, $pos, $len); - - // File not encrypted, or record before encryption start point - if ($this->_encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->_encryptionStartPos) { - return $data; - } - - $recordData = ''; - if ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) { - $oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK); - $block = floor($pos / self::REKEY_BLOCK); - $endBlock = floor(($pos + $len) / self::REKEY_BLOCK); - - // Spin an RC4 decryptor to the right spot. If we have a decryptor sitting - // at a point earlier in the current block, re-use it as we can save some time. - if ($block != $oldBlock || $pos < $this->_rc4Pos || !$this->_rc4Key) { - $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); - $step = $pos % self::REKEY_BLOCK; - } else { - $step = $pos - $this->_rc4Pos; - } - $this->_rc4Key->RC4(str_repeat("\0", $step)); - - // Decrypt record data (re-keying at the end of every block) - while ($block != $endBlock) { - $step = self::REKEY_BLOCK - ($pos % self::REKEY_BLOCK); - $recordData .= $this->_rc4Key->RC4(substr($data, 0, $step)); - $data = substr($data, $step); - $pos += $step; - $len -= $step; - $block++; - $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); - } - $recordData .= $this->_rc4Key->RC4(substr($data, 0, $len)); - - // Keep track of the position of this decryptor. - // We'll try and re-use it later if we can to speed things up - $this->_rc4Pos = $pos + $len; - } elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) { - throw new PHPExcel_Reader_Exception('XOr encryption not supported'); - } - return $recordData; - } - - /** - * Use OLE reader to extract the relevant data streams from the OLE file - * - * @param string $pFilename - */ - private function _loadOLE($pFilename) - { - // OLE reader - $ole = new PHPExcel_Shared_OLERead(); - // get excel data, - $res = $ole->read($pFilename); - // Get workbook data: workbook stream + sheet streams - $this->_data = $ole->getStream($ole->wrkbook); - // Get summary information data - $this->_summaryInformation = $ole->getStream($ole->summaryInformation); - // Get additional document summary information data - $this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation); - // Get user-defined property data -// $this->_userDefinedProperties = $ole->getUserDefinedProperties(); - } - - - /** - * Read summary information - */ - private function _readSummaryInformation() - { - if (!isset($this->_summaryInformation)) { - return; - } - - // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) - // offset: 2; size: 2; - // offset: 4; size: 2; OS version - // offset: 6; size: 2; OS indicator - // offset: 8; size: 16 - // offset: 24; size: 4; section count - $secCount = self::_GetInt4d($this->_summaryInformation, 24); - - // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 - // offset: 44; size: 4 - $secOffset = self::_GetInt4d($this->_summaryInformation, 44); - - // section header - // offset: $secOffset; size: 4; section length - $secLength = self::_GetInt4d($this->_summaryInformation, $secOffset); - - // offset: $secOffset+4; size: 4; property count - $countProperties = self::_GetInt4d($this->_summaryInformation, $secOffset+4); - - // initialize code page (used to resolve string values) - $codePage = 'CP1252'; - - // offset: ($secOffset+8); size: var - // loop through property decarations and properties - for ($i = 0; $i < $countProperties; ++$i) { - // offset: ($secOffset+8) + (8 * $i); size: 4; property ID - $id = self::_GetInt4d($this->_summaryInformation, ($secOffset+8) + (8 * $i)); - - // Use value of property id as appropriate - // offset: ($secOffset+12) + (8 * $i); size: 4; offset from beginning of section (48) - $offset = self::_GetInt4d($this->_summaryInformation, ($secOffset+12) + (8 * $i)); - - $type = self::_GetInt4d($this->_summaryInformation, $secOffset + $offset); - - // initialize property value - $value = null; - - // extract property value based on property type - switch ($type) { - case 0x02: // 2 byte signed integer - $value = self::_GetInt2d($this->_summaryInformation, $secOffset + 4 + $offset); - break; - case 0x03: // 4 byte signed integer - $value = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); - break; - case 0x13: // 4 byte unsigned integer - // not needed yet, fix later if necessary - break; - case 0x1E: // null-terminated string prepended by dword string length - $byteLength = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); - $value = substr($this->_summaryInformation, $secOffset + 8 + $offset, $byteLength); - $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); - $value = rtrim($value); - break; - case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) - // PHP-time - $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_summaryInformation, $secOffset + 4 + $offset, 8)); - break; - case 0x47: // Clipboard format - // not needed yet, fix later if necessary - break; - } - - switch ($id) { - case 0x01: // Code Page - $codePage = PHPExcel_Shared_CodePage::NumberToName($value); - break; - case 0x02: // Title - $this->_phpExcel->getProperties()->setTitle($value); - break; - case 0x03: // Subject - $this->_phpExcel->getProperties()->setSubject($value); - break; - case 0x04: // Author (Creator) - $this->_phpExcel->getProperties()->setCreator($value); - break; - case 0x05: // Keywords - $this->_phpExcel->getProperties()->setKeywords($value); - break; - case 0x06: // Comments (Description) - $this->_phpExcel->getProperties()->setDescription($value); - break; - case 0x07: // Template - // Not supported by PHPExcel - break; - case 0x08: // Last Saved By (LastModifiedBy) - $this->_phpExcel->getProperties()->setLastModifiedBy($value); - break; - case 0x09: // Revision - // Not supported by PHPExcel - break; - case 0x0A: // Total Editing Time - // Not supported by PHPExcel - break; - case 0x0B: // Last Printed - // Not supported by PHPExcel - break; - case 0x0C: // Created Date/Time - $this->_phpExcel->getProperties()->setCreated($value); - break; - case 0x0D: // Modified Date/Time - $this->_phpExcel->getProperties()->setModified($value); - break; - case 0x0E: // Number of Pages - // Not supported by PHPExcel - break; - case 0x0F: // Number of Words - // Not supported by PHPExcel - break; - case 0x10: // Number of Characters - // Not supported by PHPExcel - break; - case 0x11: // Thumbnail - // Not supported by PHPExcel - break; - case 0x12: // Name of creating application - // Not supported by PHPExcel - break; - case 0x13: // Security - // Not supported by PHPExcel - break; - } - } - } - - - /** - * Read additional document summary information - */ - private function _readDocumentSummaryInformation() - { - if (!isset($this->_documentSummaryInformation)) { - return; - } - - // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) - // offset: 2; size: 2; - // offset: 4; size: 2; OS version - // offset: 6; size: 2; OS indicator - // offset: 8; size: 16 - // offset: 24; size: 4; section count - $secCount = self::_GetInt4d($this->_documentSummaryInformation, 24); -// echo '$secCount = ', $secCount,'<br />'; - - // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae - // offset: 44; size: 4; first section offset - $secOffset = self::_GetInt4d($this->_documentSummaryInformation, 44); -// echo '$secOffset = ', $secOffset,'<br />'; - - // section header - // offset: $secOffset; size: 4; section length - $secLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset); -// echo '$secLength = ', $secLength,'<br />'; - - // offset: $secOffset+4; size: 4; property count - $countProperties = self::_GetInt4d($this->_documentSummaryInformation, $secOffset+4); -// echo '$countProperties = ', $countProperties,'<br />'; - - // initialize code page (used to resolve string values) - $codePage = 'CP1252'; - - // offset: ($secOffset+8); size: var - // loop through property decarations and properties - for ($i = 0; $i < $countProperties; ++$i) { -// echo 'Property ', $i,'<br />'; - // offset: ($secOffset+8) + (8 * $i); size: 4; property ID - $id = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+8) + (8 * $i)); -// echo 'ID is ', $id,'<br />'; - - // Use value of property id as appropriate - // offset: 60 + 8 * $i; size: 4; offset from beginning of section (48) - $offset = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+12) + (8 * $i)); - - $type = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + $offset); -// echo 'Type is ', $type,', '; - - // initialize property value - $value = null; - - // extract property value based on property type - switch ($type) { - case 0x02: // 2 byte signed integer - $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); - break; - case 0x03: // 4 byte signed integer - $value = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); - break; - case 0x0B: // Boolean - $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); - $value = ($value == 0 ? false : true); - break; - case 0x13: // 4 byte unsigned integer - // not needed yet, fix later if necessary - break; - case 0x1E: // null-terminated string prepended by dword string length - $byteLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); - $value = substr($this->_documentSummaryInformation, $secOffset + 8 + $offset, $byteLength); - $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); - $value = rtrim($value); - break; - case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) - // PHP-Time - $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_documentSummaryInformation, $secOffset + 4 + $offset, 8)); - break; - case 0x47: // Clipboard format - // not needed yet, fix later if necessary - break; - } - - switch ($id) { - case 0x01: // Code Page - $codePage = PHPExcel_Shared_CodePage::NumberToName($value); - break; - case 0x02: // Category - $this->_phpExcel->getProperties()->setCategory($value); - break; - case 0x03: // Presentation Target - // Not supported by PHPExcel - break; - case 0x04: // Bytes - // Not supported by PHPExcel - break; - case 0x05: // Lines - // Not supported by PHPExcel - break; - case 0x06: // Paragraphs - // Not supported by PHPExcel - break; - case 0x07: // Slides - // Not supported by PHPExcel - break; - case 0x08: // Notes - // Not supported by PHPExcel - break; - case 0x09: // Hidden Slides - // Not supported by PHPExcel - break; - case 0x0A: // MM Clips - // Not supported by PHPExcel - break; - case 0x0B: // Scale Crop - // Not supported by PHPExcel - break; - case 0x0C: // Heading Pairs - // Not supported by PHPExcel - break; - case 0x0D: // Titles of Parts - // Not supported by PHPExcel - break; - case 0x0E: // Manager - $this->_phpExcel->getProperties()->setManager($value); - break; - case 0x0F: // Company - $this->_phpExcel->getProperties()->setCompany($value); - break; - case 0x10: // Links up-to-date - // Not supported by PHPExcel - break; - } - } - } - - - /** - * Reads a general type of BIFF record. Does nothing except for moving stream pointer forward to next record. - */ - private function _readDefault() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); -// $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - } - - - /** - * The NOTE record specifies a comment associated with a particular cell. In Excel 95 (BIFF7) and earlier versions, - * this record stores a note (cell note). This feature was significantly enhanced in Excel 97. - */ - private function _readNote() - { -// echo '<b>Read Cell Annotation</b><br />'; - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - $cellAddress = $this->_readBIFF8CellAddress(substr($recordData, 0, 4)); - if ($this->_version == self::XLS_BIFF8) { - $noteObjID = self::_GetInt2d($recordData, 6); - $noteAuthor = self::_readUnicodeStringLong(substr($recordData, 8)); - $noteAuthor = $noteAuthor['value']; -// echo 'Note Address=', $cellAddress,'<br />'; -// echo 'Note Object ID=', $noteObjID,'<br />'; -// echo 'Note Author=', $noteAuthor,'<hr />'; -// - $this->_cellNotes[$noteObjID] = array( - 'cellRef' => $cellAddress, - 'objectID' => $noteObjID, - 'author' => $noteAuthor - ); - } else { - $extension = false; - if ($cellAddress == '$B$65536') { - // If the address row is -1 and the column is 0, (which translates as $B$65536) then this is a continuation - // note from the previous cell annotation. We're not yet handling this, so annotations longer than the - // max 2048 bytes will probably throw a wobbly. - $row = self::_GetInt2d($recordData, 0); - $extension = true; - $cellAddress = array_pop(array_keys($this->_phpSheet->getComments())); - } -// echo 'Note Address=', $cellAddress,'<br />'; - - $cellAddress = str_replace('$', '', $cellAddress); - $noteLength = self::_GetInt2d($recordData, 4); - $noteText = trim(substr($recordData, 6)); -// echo 'Note Length=', $noteLength,'<br />'; -// echo 'Note Text=', $noteText,'<br />'; - - if ($extension) { - // Concatenate this extension with the currently set comment for the cell - $comment = $this->_phpSheet->getComment($cellAddress); - $commentText = $comment->getText()->getPlainText(); - $comment->setText($this->_parseRichText($commentText.$noteText)); - } else { - // Set comment for the cell - $this->_phpSheet->getComment($cellAddress)->setText($this->_parseRichText($noteText)); -// ->setAuthor($author) - } - } - - } - - - /** - * The TEXT Object record contains the text associated with a cell annotation. - */ - private function _readTextObject() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - // recordData consists of an array of subrecords looking like this: - // grbit: 2 bytes; Option Flags - // rot: 2 bytes; rotation - // cchText: 2 bytes; length of the text (in the first continue record) - // cbRuns: 2 bytes; length of the formatting (in the second continue record) - // followed by the continuation records containing the actual text and formatting - $grbitOpts = self::_GetInt2d($recordData, 0); - $rot = self::_GetInt2d($recordData, 2); - $cchText = self::_GetInt2d($recordData, 10); - $cbRuns = self::_GetInt2d($recordData, 12); - $text = $this->_getSplicedRecordData(); - - $this->_textObjects[$this->textObjRef] = array( - 'text' => substr($text["recordData"], $text["spliceOffsets"][0]+1, $cchText), - 'format' => substr($text["recordData"], $text["spliceOffsets"][1], $cbRuns), - 'alignment' => $grbitOpts, - 'rotation' => $rot - ); - -// echo '<b>_readTextObject()</b><br />'; -// var_dump($this->_textObjects[$this->textObjRef]); -// echo '<br />'; - } - - - /** - * Read BOF - */ - private function _readBof() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 2; size: 2; type of the following data - $substreamType = self::_GetInt2d($recordData, 2); - - switch ($substreamType) { - case self::XLS_WorkbookGlobals: - $version = self::_GetInt2d($recordData, 0); - if (($version != self::XLS_BIFF8) && ($version != self::XLS_BIFF7)) { - throw new PHPExcel_Reader_Exception('Cannot read this Excel file. Version is too old.'); - } - $this->_version = $version; - break; - case self::XLS_Worksheet: - // do not use this version information for anything - // it is unreliable (OpenOffice doc, 5.8), use only version information from the global stream - break; - default: - // substream, e.g. chart - // just skip the entire substream - do { - $code = self::_GetInt2d($this->_data, $this->_pos); - $this->_readDefault(); - } while ($code != self::XLS_Type_EOF && $this->_pos < $this->_dataSize); - break; - } - } - - - /** - * FILEPASS - * - * This record is part of the File Protection Block. It - * contains information about the read/write password of the - * file. All record contents following this record will be - * encrypted. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - * - * The decryption functions and objects used from here on in - * are based on the source of Spreadsheet-ParseExcel: - * http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/ - */ - private function _readFilepass() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - - if ($length != 54) { - throw new PHPExcel_Reader_Exception('Unexpected file pass record length'); - } - - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_verifyPassword('VelvetSweatshop', substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->_md5Ctxt)) { - throw new PHPExcel_Reader_Exception('Decryption password incorrect'); - } - - $this->_encryption = self::MS_BIFF_CRYPTO_RC4; - - // Decryption required from the record after next onwards - $this->_encryptionStartPos = $this->_pos + self::_GetInt2d($this->_data, $this->_pos + 2); - } - - /** - * Make an RC4 decryptor for the given block - * - * @var int $block Block for which to create decrypto - * @var string $valContext MD5 context state - * - * @return PHPExcel_Reader_Excel5_RC4 - */ - private function _makeKey($block, $valContext) - { - $pwarray = str_repeat("\0", 64); - - for ($i = 0; $i < 5; $i++) { - $pwarray[$i] = $valContext[$i]; - } - - $pwarray[5] = chr($block & 0xff); - $pwarray[6] = chr(($block >> 8) & 0xff); - $pwarray[7] = chr(($block >> 16) & 0xff); - $pwarray[8] = chr(($block >> 24) & 0xff); - - $pwarray[9] = "\x80"; - $pwarray[56] = "\x48"; - - $md5 = new PHPExcel_Reader_Excel5_MD5(); - $md5->add($pwarray); - - $s = $md5->getContext(); - return new PHPExcel_Reader_Excel5_RC4($s); - } - - /** - * Verify RC4 file password - * - * @var string $password Password to check - * @var string $docid Document id - * @var string $salt_data Salt data - * @var string $hashedsalt_data Hashed salt data - * @var string &$valContext Set to the MD5 context of the value - * - * @return bool Success - */ - private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext) - { - $pwarray = str_repeat("\0", 64); - - for ($i = 0; $i < strlen($password); $i++) { - $o = ord(substr($password, $i, 1)); - $pwarray[2 * $i] = chr($o & 0xff); - $pwarray[2 * $i + 1] = chr(($o >> 8) & 0xff); - } - $pwarray[2 * $i] = chr(0x80); - $pwarray[56] = chr(($i << 4) & 0xff); - - $md5 = new PHPExcel_Reader_Excel5_MD5(); - $md5->add($pwarray); - - $mdContext1 = $md5->getContext(); - - $offset = 0; - $keyoffset = 0; - $tocopy = 5; - - $md5->reset(); - - while ($offset != 16) { - if ((64 - $offset) < 5) { - $tocopy = 64 - $offset; - } - for ($i = 0; $i <= $tocopy; $i++) { - $pwarray[$offset + $i] = $mdContext1[$keyoffset + $i]; - } - $offset += $tocopy; - - if ($offset == 64) { - $md5->add($pwarray); - $keyoffset = $tocopy; - $tocopy = 5 - $tocopy; - $offset = 0; - continue; - } - - $keyoffset = 0; - $tocopy = 5; - for ($i = 0; $i < 16; $i++) { - $pwarray[$offset + $i] = $docid[$i]; - } - $offset += 16; - } - - $pwarray[16] = "\x80"; - for ($i = 0; $i < 47; $i++) { - $pwarray[17 + $i] = "\0"; - } - $pwarray[56] = "\x80"; - $pwarray[57] = "\x0a"; - - $md5->add($pwarray); - $valContext = $md5->getContext(); - - $key = $this->_makeKey(0, $valContext); - - $salt = $key->RC4($salt_data); - $hashedsalt = $key->RC4($hashedsalt_data); - - $salt .= "\x80" . str_repeat("\0", 47); - $salt[56] = "\x80"; - - $md5->reset(); - $md5->add($salt); - $mdContext2 = $md5->getContext(); - - return $mdContext2 == $hashedsalt; - } - - /** - * CODEPAGE - * - * This record stores the text encoding used to write byte - * strings, stored as MS Windows code page identifier. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readCodepage() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; code page identifier - $codepage = self::_GetInt2d($recordData, 0); - - $this->_codepage = PHPExcel_Shared_CodePage::NumberToName($codepage); - } - - - /** - * DATEMODE - * - * This record specifies the base date for displaying date - * values. All dates are stored as count of days past this - * base date. In BIFF2-BIFF4 this record is part of the - * Calculation Settings Block. In BIFF5-BIFF8 it is - * stored in the Workbook Globals Substream. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readDateMode() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; 0 = base 1900, 1 = base 1904 - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); - if (ord($recordData{0}) == 1) { - PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); - } - } - - - /** - * Read a FONT record - */ - private function _readFont() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - $objFont = new PHPExcel_Style_Font(); - - // offset: 0; size: 2; height of the font (in twips = 1/20 of a point) - $size = self::_GetInt2d($recordData, 0); - $objFont->setSize($size / 20); - - // offset: 2; size: 2; option flags - // bit: 0; mask 0x0001; bold (redundant in BIFF5-BIFF8) - // bit: 1; mask 0x0002; italic - $isItalic = (0x0002 & self::_GetInt2d($recordData, 2)) >> 1; - if ($isItalic) { - $objFont->setItalic(true); - } - - // bit: 2; mask 0x0004; underlined (redundant in BIFF5-BIFF8) - // bit: 3; mask 0x0008; strike - $isStrike = (0x0008 & self::_GetInt2d($recordData, 2)) >> 3; - if ($isStrike) { - $objFont->setStrikethrough(true); - } - - // offset: 4; size: 2; colour index - $colorIndex = self::_GetInt2d($recordData, 4); - $objFont->colorIndex = $colorIndex; - - // offset: 6; size: 2; font weight - $weight = self::_GetInt2d($recordData, 6); - switch ($weight) { - case 0x02BC: - $objFont->setBold(true); - break; - } - - // offset: 8; size: 2; escapement type - $escapement = self::_GetInt2d($recordData, 8); - switch ($escapement) { - case 0x0001: - $objFont->setSuperScript(true); - break; - case 0x0002: - $objFont->setSubScript(true); - break; - } - - // offset: 10; size: 1; underline type - $underlineType = ord($recordData{10}); - switch ($underlineType) { - case 0x00: - break; // no underline - case 0x01: - $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); - break; - case 0x02: - $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); - break; - case 0x21: - $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING); - break; - case 0x22: - $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING); - break; - } - - // offset: 11; size: 1; font family - // offset: 12; size: 1; character set - // offset: 13; size: 1; not used - // offset: 14; size: var; font name - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringShort(substr($recordData, 14)); - } else { - $string = $this->_readByteStringShort(substr($recordData, 14)); - } - $objFont->setName($string['value']); - - $this->_objFonts[] = $objFont; - } - } - - - /** - * FORMAT - * - * This record contains information about a number format. - * All FORMAT records occur together in a sequential list. - * - * In BIFF2-BIFF4 other records referencing a FORMAT record - * contain a zero-based index into this list. From BIFF5 on - * the FORMAT record contains the index itself that will be - * used by other records. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readFormat() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - $indexCode = self::_GetInt2d($recordData, 0); - - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong(substr($recordData, 2)); - } else { - // BIFF7 - $string = $this->_readByteStringShort(substr($recordData, 2)); - } - - $formatString = $string['value']; - $this->_formats[$indexCode] = $formatString; - } - } - - - /** - * XF - Extended Format - * - * This record contains formatting information for cells, rows, columns or styles. - * According to http://support.microsoft.com/kb/147732 there are always at least 15 cell style XF - * and 1 cell XF. - * Inspection of Excel files generated by MS Office Excel shows that XF records 0-14 are cell style XF - * and XF record 15 is a cell XF - * We only read the first cell style XF and skip the remaining cell style XF records - * We read all cell XF records. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readXf() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - $objStyle = new PHPExcel_Style(); - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; Index to FONT record - if (self::_GetInt2d($recordData, 0) < 4) { - $fontIndex = self::_GetInt2d($recordData, 0); - } else { - // this has to do with that index 4 is omitted in all BIFF versions for some strange reason - // check the OpenOffice documentation of the FONT record - $fontIndex = self::_GetInt2d($recordData, 0) - 1; - } - $objStyle->setFont($this->_objFonts[$fontIndex]); - - // offset: 2; size: 2; Index to FORMAT record - $numberFormatIndex = self::_GetInt2d($recordData, 2); - if (isset($this->_formats[$numberFormatIndex])) { - // then we have user-defined format code - $numberformat = array('code' => $this->_formats[$numberFormatIndex]); - } elseif (($code = PHPExcel_Style_NumberFormat::builtInFormatCode($numberFormatIndex)) !== '') { - // then we have built-in format code - $numberformat = array('code' => $code); - } else { - // we set the general format code - $numberformat = array('code' => 'General'); - } - $objStyle->getNumberFormat()->setFormatCode($numberformat['code']); - - // offset: 4; size: 2; XF type, cell protection, and parent style XF - // bit 2-0; mask 0x0007; XF_TYPE_PROT - $xfTypeProt = self::_GetInt2d($recordData, 4); - // bit 0; mask 0x01; 1 = cell is locked - $isLocked = (0x01 & $xfTypeProt) >> 0; - $objStyle->getProtection()->setLocked($isLocked ? PHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); - - // bit 1; mask 0x02; 1 = Formula is hidden - $isHidden = (0x02 & $xfTypeProt) >> 1; - $objStyle->getProtection()->setHidden($isHidden ? PHPExcel_Style_Protection::PROTECTION_PROTECTED : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); - - // bit 2; mask 0x04; 0 = Cell XF, 1 = Cell Style XF - $isCellStyleXf = (0x04 & $xfTypeProt) >> 2; - - // offset: 6; size: 1; Alignment and text break - // bit 2-0, mask 0x07; horizontal alignment - $horAlign = (0x07 & ord($recordData{6})) >> 0; - switch ($horAlign) { - case 0: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_GENERAL); - break; - case 1: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT); - break; - case 2: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER); - break; - case 3: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); - break; - case 4: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_FILL); - break; - case 5: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY); - break; - case 6: - $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS); - break; - } - // bit 3, mask 0x08; wrap text - $wrapText = (0x08 & ord($recordData{6})) >> 3; - switch ($wrapText) { - case 0: - $objStyle->getAlignment()->setWrapText(false); - break; - case 1: - $objStyle->getAlignment()->setWrapText(true); - break; - } - // bit 6-4, mask 0x70; vertical alignment - $vertAlign = (0x70 & ord($recordData{6})) >> 4; - switch ($vertAlign) { - case 0: - $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP); - break; - case 1: - $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER); - break; - case 2: - $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_BOTTOM); - break; - case 3: - $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_JUSTIFY); - break; - } - - if ($this->_version == self::XLS_BIFF8) { - // offset: 7; size: 1; XF_ROTATION: Text rotation angle - $angle = ord($recordData{7}); - $rotation = 0; - if ($angle <= 90) { - $rotation = $angle; - } else if ($angle <= 180) { - $rotation = 90 - $angle; - } else if ($angle == 255) { - $rotation = -165; - } - $objStyle->getAlignment()->setTextRotation($rotation); - - // offset: 8; size: 1; Indentation, shrink to cell size, and text direction - // bit: 3-0; mask: 0x0F; indent level - $indent = (0x0F & ord($recordData{8})) >> 0; - $objStyle->getAlignment()->setIndent($indent); - - // bit: 4; mask: 0x10; 1 = shrink content to fit into cell - $shrinkToFit = (0x10 & ord($recordData{8})) >> 4; - switch ($shrinkToFit) { - case 0: - $objStyle->getAlignment()->setShrinkToFit(false); - break; - case 1: - $objStyle->getAlignment()->setShrinkToFit(true); - break; - } - - // offset: 9; size: 1; Flags used for attribute groups - - // offset: 10; size: 4; Cell border lines and background area - // bit: 3-0; mask: 0x0000000F; left style - if ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) { - $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle); - } - // bit: 7-4; mask: 0x000000F0; right style - if ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) { - $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle); - } - // bit: 11-8; mask: 0x00000F00; top style - if ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) { - $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle); - } - // bit: 15-12; mask: 0x0000F000; bottom style - if ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) { - $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle); - } - // bit: 22-16; mask: 0x007F0000; left color - $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16; - - // bit: 29-23; mask: 0x3F800000; right color - $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23; - - // bit: 30; mask: 0x40000000; 1 = diagonal line from top left to right bottom - $diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ? true : false; - - // bit: 31; mask: 0x80000000; 1 = diagonal line from bottom left to top right - $diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ? true : false; - - if ($diagonalUp == false && $diagonalDown == false) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); - } elseif ($diagonalUp == true && $diagonalDown == false) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); - } elseif ($diagonalUp == false && $diagonalDown == true) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); - } elseif ($diagonalUp == true && $diagonalDown == true) { - $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); - } - - // offset: 14; size: 4; - // bit: 6-0; mask: 0x0000007F; top color - $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0; - - // bit: 13-7; mask: 0x00003F80; bottom color - $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7; - - // bit: 20-14; mask: 0x001FC000; diagonal color - $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14; - - // bit: 24-21; mask: 0x01E00000; diagonal style - if ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) { - $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle); - } - - // bit: 31-26; mask: 0xFC000000 fill pattern - if ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) { - $objStyle->getFill()->setFillType($fillType); - } - // offset: 18; size: 2; pattern and background colour - // bit: 6-0; mask: 0x007F; color index for pattern color - $objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0; - - // bit: 13-7; mask: 0x3F80; color index for pattern background - $objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7; - } else { - // BIFF5 - - // offset: 7; size: 1; Text orientation and flags - $orientationAndFlags = ord($recordData{7}); - - // bit: 1-0; mask: 0x03; XF_ORIENTATION: Text orientation - $xfOrientation = (0x03 & $orientationAndFlags) >> 0; - switch ($xfOrientation) { - case 0: - $objStyle->getAlignment()->setTextRotation(0); - break; - case 1: - $objStyle->getAlignment()->setTextRotation(-165); - break; - case 2: - $objStyle->getAlignment()->setTextRotation(90); - break; - case 3: - $objStyle->getAlignment()->setTextRotation(-90); - break; - } - - // offset: 8; size: 4; cell border lines and background area - $borderAndBackground = self::_GetInt4d($recordData, 8); - - // bit: 6-0; mask: 0x0000007F; color index for pattern color - $objStyle->getFill()->startcolorIndex = (0x0000007F & $borderAndBackground) >> 0; - - // bit: 13-7; mask: 0x00003F80; color index for pattern background - $objStyle->getFill()->endcolorIndex = (0x00003F80 & $borderAndBackground) >> 7; - - // bit: 21-16; mask: 0x003F0000; fill pattern - $objStyle->getFill()->setFillType(self::_mapFillPattern((0x003F0000 & $borderAndBackground) >> 16)); - - // bit: 24-22; mask: 0x01C00000; bottom line style - $objStyle->getBorders()->getBottom()->setBorderStyle(self::_mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22)); - - // bit: 31-25; mask: 0xFE000000; bottom line color - $objStyle->getBorders()->getBottom()->colorIndex = (0xFE000000 & $borderAndBackground) >> 25; - - // offset: 12; size: 4; cell border lines - $borderLines = self::_GetInt4d($recordData, 12); - - // bit: 2-0; mask: 0x00000007; top line style - $objStyle->getBorders()->getTop()->setBorderStyle(self::_mapBorderStyle((0x00000007 & $borderLines) >> 0)); - - // bit: 5-3; mask: 0x00000038; left line style - $objStyle->getBorders()->getLeft()->setBorderStyle(self::_mapBorderStyle((0x00000038 & $borderLines) >> 3)); - - // bit: 8-6; mask: 0x000001C0; right line style - $objStyle->getBorders()->getRight()->setBorderStyle(self::_mapBorderStyle((0x000001C0 & $borderLines) >> 6)); - - // bit: 15-9; mask: 0x0000FE00; top line color index - $objStyle->getBorders()->getTop()->colorIndex = (0x0000FE00 & $borderLines) >> 9; - - // bit: 22-16; mask: 0x007F0000; left line color index - $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & $borderLines) >> 16; - - // bit: 29-23; mask: 0x3F800000; right line color index - $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & $borderLines) >> 23; - } - - // add cellStyleXf or cellXf and update mapping - if ($isCellStyleXf) { - // we only read one style XF record which is always the first - if ($this->_xfIndex == 0) { - $this->_phpExcel->addCellStyleXf($objStyle); - $this->_mapCellStyleXfIndex[$this->_xfIndex] = 0; - } - } else { - // we read all cell XF records - $this->_phpExcel->addCellXf($objStyle); - $this->_mapCellXfIndex[$this->_xfIndex] = count($this->_phpExcel->getCellXfCollection()) - 1; - } - - // update XF index for when we read next record - ++$this->_xfIndex; - } - } - - - /** - * - */ - private function _readXfExt() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; 0x087D = repeated header - - // offset: 2; size: 2 - - // offset: 4; size: 8; not used - - // offset: 12; size: 2; record version - - // offset: 14; size: 2; index to XF record which this record modifies - $ixfe = self::_GetInt2d($recordData, 14); - - // offset: 16; size: 2; not used - - // offset: 18; size: 2; number of extension properties that follow - $cexts = self::_GetInt2d($recordData, 18); - - // start reading the actual extension data - $offset = 20; - while ($offset < $length) { - // extension type - $extType = self::_GetInt2d($recordData, $offset); - - // extension length - $cb = self::_GetInt2d($recordData, $offset + 2); - - // extension data - $extData = substr($recordData, $offset + 4, $cb); - - switch ($extType) { - case 4: // fill start color - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); - $fill->getStartColor()->setRGB($rgb); - unset($fill->startcolorIndex); // normal color index does not apply, discard - } - } - break; - case 5: // fill end color - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); - $fill->getEndColor()->setRGB($rgb); - unset($fill->endcolorIndex); // normal color index does not apply, discard - } - } - break; - case 7: // border color top - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $top = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getTop(); - $top->getColor()->setRGB($rgb); - unset($top->colorIndex); // normal color index does not apply, discard - } - } - break; - case 8: // border color bottom - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $bottom = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getBottom(); - $bottom->getColor()->setRGB($rgb); - unset($bottom->colorIndex); // normal color index does not apply, discard - } - } - break; - case 9: // border color left - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $left = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getLeft(); - $left->getColor()->setRGB($rgb); - unset($left->colorIndex); // normal color index does not apply, discard - } - } - break; - case 10: // border color right - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $right = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getRight(); - $right->getColor()->setRGB($rgb); - unset($right->colorIndex); // normal color index does not apply, discard - } - } - break; - case 11: // border color diagonal - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $diagonal = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getDiagonal(); - $diagonal->getColor()->setRGB($rgb); - unset($diagonal->colorIndex); // normal color index does not apply, discard - } - } - break; - case 13: // font color - $xclfType = self::_GetInt2d($extData, 0); // color type - $xclrValue = substr($extData, 4, 4); // color value (value based on color type) - - if ($xclfType == 2) { - $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); - - // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $font = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFont(); - $font->getColor()->setRGB($rgb); - unset($font->colorIndex); // normal color index does not apply, discard - } - } - break; - } - - $offset += $cb; - } - } - - } - - - /** - * Read STYLE record - */ - private function _readStyle() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; index to XF record and flag for built-in style - $ixfe = self::_GetInt2d($recordData, 0); - - // bit: 11-0; mask 0x0FFF; index to XF record - $xfIndex = (0x0FFF & $ixfe) >> 0; - - // bit: 15; mask 0x8000; 0 = user-defined style, 1 = built-in style - $isBuiltIn = (bool) ((0x8000 & $ixfe) >> 15); - - if ($isBuiltIn) { - // offset: 2; size: 1; identifier for built-in style - $builtInId = ord($recordData{2}); - - switch ($builtInId) { - case 0x00: - // currently, we are not using this for anything - break; - default: - break; - } - } else { - // user-defined; not supported by PHPExcel - } - } - } - - - /** - * Read PALETTE record - */ - private function _readPalette() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; number of following colors - $nm = self::_GetInt2d($recordData, 0); - - // list of RGB colors - for ($i = 0; $i < $nm; ++$i) { - $rgb = substr($recordData, 2 + 4 * $i, 4); - $this->_palette[] = self::_readRGB($rgb); - } - } - } - - - /** - * SHEET - * - * This record is located in the Workbook Globals - * Substream and represents a sheet inside the workbook. - * One SHEET record is written for each sheet. It stores the - * sheet name and a stream offset to the BOF record of the - * respective Sheet Substream within the Workbook Stream. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readSheet() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // offset: 0; size: 4; absolute stream position of the BOF record of the sheet - // NOTE: not encrypted - $rec_offset = self::_GetInt4d($this->_data, $this->_pos + 4); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 4; size: 1; sheet state - switch (ord($recordData{4})) { - case 0x00: - $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; - break; - case 0x01: - $sheetState = PHPExcel_Worksheet::SHEETSTATE_HIDDEN; - break; - case 0x02: - $sheetState = PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN; - break; - default: - $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; - break; - } - - // offset: 5; size: 1; sheet type - $sheetType = ord($recordData{5}); - - // offset: 6; size: var; sheet name - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringShort(substr($recordData, 6)); - $rec_name = $string['value']; - } elseif ($this->_version == self::XLS_BIFF7) { - $string = $this->_readByteStringShort(substr($recordData, 6)); - $rec_name = $string['value']; - } - - $this->_sheets[] = array( - 'name' => $rec_name, - 'offset' => $rec_offset, - 'sheetState' => $sheetState, - 'sheetType' => $sheetType, - ); - } - - - /** - * Read EXTERNALBOOK record - */ - private function _readExternalBook() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset within record data - $offset = 0; - - // there are 4 types of records - if (strlen($recordData) > 4) { - // external reference - // offset: 0; size: 2; number of sheet names ($nm) - $nm = self::_GetInt2d($recordData, 0); - $offset += 2; - - // offset: 2; size: var; encoded URL without sheet name (Unicode string, 16-bit length) - $encodedUrlString = self::_readUnicodeStringLong(substr($recordData, 2)); - $offset += $encodedUrlString['size']; - - // offset: var; size: var; list of $nm sheet names (Unicode strings, 16-bit length) - $externalSheetNames = array(); - for ($i = 0; $i < $nm; ++$i) { - $externalSheetNameString = self::_readUnicodeStringLong(substr($recordData, $offset)); - $externalSheetNames[] = $externalSheetNameString['value']; - $offset += $externalSheetNameString['size']; - } - - // store the record data - $this->_externalBooks[] = array( - 'type' => 'external', - 'encodedUrl' => $encodedUrlString['value'], - 'externalSheetNames' => $externalSheetNames, - ); - } elseif (substr($recordData, 2, 2) == pack('CC', 0x01, 0x04)) { - // internal reference - // offset: 0; size: 2; number of sheet in this document - // offset: 2; size: 2; 0x01 0x04 - $this->_externalBooks[] = array( - 'type' => 'internal', - ); - } elseif (substr($recordData, 0, 4) == pack('vCC', 0x0001, 0x01, 0x3A)) { - // add-in function - // offset: 0; size: 2; 0x0001 - $this->_externalBooks[] = array( - 'type' => 'addInFunction', - ); - } elseif (substr($recordData, 0, 2) == pack('v', 0x0000)) { - // DDE links, OLE links - // offset: 0; size: 2; 0x0000 - // offset: 2; size: var; encoded source document name - $this->_externalBooks[] = array( - 'type' => 'DDEorOLE', - ); - } - } - - - /** - * Read EXTERNNAME record. - */ - private function _readExternName() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // external sheet references provided for named cells - if ($this->_version == self::XLS_BIFF8) { - // offset: 0; size: 2; options - $options = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; - - // offset: 4; size: 2; not used - - // offset: 6; size: var - $nameString = self::_readUnicodeStringShort(substr($recordData, 6)); - - // offset: var; size: var; formula data - $offset = 6 + $nameString['size']; - $formula = $this->_getFormulaFromStructure(substr($recordData, $offset)); - - $this->_externalNames[] = array( - 'name' => $nameString['value'], - 'formula' => $formula, - ); - } - } - - - /** - * Read EXTERNSHEET record - */ - private function _readExternSheet() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // external sheet references provided for named cells - if ($this->_version == self::XLS_BIFF8) { - // offset: 0; size: 2; number of following ref structures - $nm = self::_GetInt2d($recordData, 0); - for ($i = 0; $i < $nm; ++$i) { - $this->_ref[] = array( - // offset: 2 + 6 * $i; index to EXTERNALBOOK record - 'externalBookIndex' => self::_GetInt2d($recordData, 2 + 6 * $i), - // offset: 4 + 6 * $i; index to first sheet in EXTERNALBOOK record - 'firstSheetIndex' => self::_GetInt2d($recordData, 4 + 6 * $i), - // offset: 6 + 6 * $i; index to last sheet in EXTERNALBOOK record - 'lastSheetIndex' => self::_GetInt2d($recordData, 6 + 6 * $i), - ); - } - } - } - - - /** - * DEFINEDNAME - * - * This record is part of a Link Table. It contains the name - * and the token array of an internal defined name. Token - * arrays of defined names contain tokens with aberrant - * token classes. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readDefinedName() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8) { - // retrieves named cells - - // offset: 0; size: 2; option flags - $opts = self::_GetInt2d($recordData, 0); - - // bit: 5; mask: 0x0020; 0 = user-defined name, 1 = built-in-name - $isBuiltInName = (0x0020 & $opts) >> 5; - - // offset: 2; size: 1; keyboard shortcut - - // offset: 3; size: 1; length of the name (character count) - $nlen = ord($recordData{3}); - - // offset: 4; size: 2; size of the formula data (it can happen that this is zero) - // note: there can also be additional data, this is not included in $flen - $flen = self::_GetInt2d($recordData, 4); - - // offset: 8; size: 2; 0=Global name, otherwise index to sheet (1-based) - $scope = self::_GetInt2d($recordData, 8); - - // offset: 14; size: var; Name (Unicode string without length field) - $string = self::_readUnicodeString(substr($recordData, 14), $nlen); - - // offset: var; size: $flen; formula data - $offset = 14 + $string['size']; - $formulaStructure = pack('v', $flen) . substr($recordData, $offset); - - try { - $formula = $this->_getFormulaFromStructure($formulaStructure); - } catch (PHPExcel_Exception $e) { - $formula = ''; - } - - $this->_definedname[] = array( - 'isBuiltInName' => $isBuiltInName, - 'name' => $string['value'], - 'formula' => $formula, - 'scope' => $scope, - ); - } - } - - - /** - * Read MSODRAWINGGROUP record - */ - private function _readMsoDrawingGroup() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - - // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); - $recordData = $splicedRecordData['recordData']; - - $this->_drawingGroupData .= $recordData; - } - - - /** - * SST - Shared String Table - * - * This record contains a list of all strings used anywhere - * in the workbook. Each string occurs only once. The - * workbook uses indexes into the list to reference the - * strings. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - **/ - private function _readSst() - { - // offset within (spliced) record data - $pos = 0; - - // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); - - $recordData = $splicedRecordData['recordData']; - $spliceOffsets = $splicedRecordData['spliceOffsets']; - - // offset: 0; size: 4; total number of strings in the workbook - $pos += 4; - - // offset: 4; size: 4; number of following strings ($nm) - $nm = self::_GetInt4d($recordData, 4); - $pos += 4; - - // loop through the Unicode strings (16-bit length) - for ($i = 0; $i < $nm; ++$i) { - // number of characters in the Unicode string - $numChars = self::_GetInt2d($recordData, $pos); - $pos += 2; - - // option flags - $optionFlags = ord($recordData{$pos}); - ++$pos; - - // bit: 0; mask: 0x01; 0 = compressed; 1 = uncompressed - $isCompressed = (($optionFlags & 0x01) == 0) ; - - // bit: 2; mask: 0x02; 0 = ordinary; 1 = Asian phonetic - $hasAsian = (($optionFlags & 0x04) != 0); - - // bit: 3; mask: 0x03; 0 = ordinary; 1 = Rich-Text - $hasRichText = (($optionFlags & 0x08) != 0); - - if ($hasRichText) { - // number of Rich-Text formatting runs - $formattingRuns = self::_GetInt2d($recordData, $pos); - $pos += 2; - } - - if ($hasAsian) { - // size of Asian phonetic setting - $extendedRunLength = self::_GetInt4d($recordData, $pos); - $pos += 4; - } - - // expected byte length of character array if not split - $len = ($isCompressed) ? $numChars : $numChars * 2; - - // look up limit position - foreach ($spliceOffsets as $spliceOffset) { - // it can happen that the string is empty, therefore we need - // <= and not just < - if ($pos <= $spliceOffset) { - $limitpos = $spliceOffset; - break; - } - } - - if ($pos + $len <= $limitpos) { - // character array is not split between records - - $retstr = substr($recordData, $pos, $len); - $pos += $len; - } else { - // character array is split between records - - // first part of character array - $retstr = substr($recordData, $pos, $limitpos - $pos); - - $bytesRead = $limitpos - $pos; - - // remaining characters in Unicode string - $charsLeft = $numChars - (($isCompressed) ? $bytesRead : ($bytesRead / 2)); - - $pos = $limitpos; - - // keep reading the characters - while ($charsLeft > 0) { - // look up next limit position, in case the string span more than one continue record - foreach ($spliceOffsets as $spliceOffset) { - if ($pos < $spliceOffset) { - $limitpos = $spliceOffset; - break; - } - } - - // repeated option flags - // OpenOffice.org documentation 5.21 - $option = ord($recordData{$pos}); - ++$pos; - - if ($isCompressed && ($option == 0)) { - // 1st fragment compressed - // this fragment compressed - $len = min($charsLeft, $limitpos - $pos); - $retstr .= substr($recordData, $pos, $len); - $charsLeft -= $len; - $isCompressed = true; - } elseif (!$isCompressed && ($option != 0)) { - // 1st fragment uncompressed - // this fragment uncompressed - $len = min($charsLeft * 2, $limitpos - $pos); - $retstr .= substr($recordData, $pos, $len); - $charsLeft -= $len / 2; - $isCompressed = false; - } elseif (!$isCompressed && ($option == 0)) { - // 1st fragment uncompressed - // this fragment compressed - $len = min($charsLeft, $limitpos - $pos); - for ($j = 0; $j < $len; ++$j) { - $retstr .= $recordData{$pos + $j} . chr(0); - } - $charsLeft -= $len; - $isCompressed = false; - } else { - // 1st fragment compressed - // this fragment uncompressed - $newstr = ''; - for ($j = 0; $j < strlen($retstr); ++$j) { - $newstr .= $retstr[$j] . chr(0); - } - $retstr = $newstr; - $len = min($charsLeft * 2, $limitpos - $pos); - $retstr .= substr($recordData, $pos, $len); - $charsLeft -= $len / 2; - $isCompressed = false; - } - - $pos += $len; - } - } - - // convert to UTF-8 - $retstr = self::_encodeUTF16($retstr, $isCompressed); - - // read additional Rich-Text information, if any - $fmtRuns = array(); - if ($hasRichText) { - // list of formatting runs - for ($j = 0; $j < $formattingRuns; ++$j) { - // first formatted character; zero-based - $charPos = self::_GetInt2d($recordData, $pos + $j * 4); - - // index to font record - $fontIndex = self::_GetInt2d($recordData, $pos + 2 + $j * 4); - - $fmtRuns[] = array( - 'charPos' => $charPos, - 'fontIndex' => $fontIndex, - ); - } - $pos += 4 * $formattingRuns; - } - - // read additional Asian phonetics information, if any - if ($hasAsian) { - // For Asian phonetic settings, we skip the extended string data - $pos += $extendedRunLength; - } - - // store the shared sting - $this->_sst[] = array( - 'value' => $retstr, - 'fmtRuns' => $fmtRuns, - ); - } - - // _getSplicedRecordData() takes care of moving current position in data stream - } - - - /** - * Read PRINTGRIDLINES record - */ - private function _readPrintGridlines() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { - // offset: 0; size: 2; 0 = do not print sheet grid lines; 1 = print sheet gridlines - $printGridlines = (bool) self::_GetInt2d($recordData, 0); - $this->_phpSheet->setPrintGridlines($printGridlines); - } - } - - - /** - * Read DEFAULTROWHEIGHT record - */ - private function _readDefaultRowHeight() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; option flags - // offset: 2; size: 2; default height for unused rows, (twips 1/20 point) - $height = self::_GetInt2d($recordData, 2); - $this->_phpSheet->getDefaultRowDimension()->setRowHeight($height / 20); - } - - - /** - * Read SHEETPR record - */ - private function _readSheetPr() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2 - - // bit: 6; mask: 0x0040; 0 = outline buttons above outline group - $isSummaryBelow = (0x0040 & self::_GetInt2d($recordData, 0)) >> 6; - $this->_phpSheet->setShowSummaryBelow($isSummaryBelow); - - // bit: 7; mask: 0x0080; 0 = outline buttons left of outline group - $isSummaryRight = (0x0080 & self::_GetInt2d($recordData, 0)) >> 7; - $this->_phpSheet->setShowSummaryRight($isSummaryRight); - - // bit: 8; mask: 0x100; 0 = scale printout in percent, 1 = fit printout to number of pages - // this corresponds to radio button setting in page setup dialog in Excel - $this->_isFitToPages = (bool) ((0x0100 & self::_GetInt2d($recordData, 0)) >> 8); - } - - - /** - * Read HORIZONTALPAGEBREAKS record - */ - private function _readHorizontalPageBreaks() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { - // offset: 0; size: 2; number of the following row index structures - $nm = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 6 * $nm; list of $nm row index structures - for ($i = 0; $i < $nm; ++$i) { - $r = self::_GetInt2d($recordData, 2 + 6 * $i); - $cf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); - $cl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); - - // not sure why two column indexes are necessary? - $this->_phpSheet->setBreakByColumnAndRow($cf, $r, PHPExcel_Worksheet::BREAK_ROW); - } - } - } - - - /** - * Read VERTICALPAGEBREAKS record - */ - private function _readVerticalPageBreaks() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { - // offset: 0; size: 2; number of the following column index structures - $nm = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 6 * $nm; list of $nm row index structures - for ($i = 0; $i < $nm; ++$i) { - $c = self::_GetInt2d($recordData, 2 + 6 * $i); - $rf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); - $rl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); - - // not sure why two row indexes are necessary? - $this->_phpSheet->setBreakByColumnAndRow($c, $rf, PHPExcel_Worksheet::BREAK_COLUMN); - } - } - } - - - /** - * Read HEADER record - */ - private function _readHeader() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: var - // realized that $recordData can be empty even when record exists - if ($recordData) { - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong($recordData); - } else { - $string = $this->_readByteStringShort($recordData); - } - - $this->_phpSheet->getHeaderFooter()->setOddHeader($string['value']); - $this->_phpSheet->getHeaderFooter()->setEvenHeader($string['value']); - } - } - } - - - /** - * Read FOOTER record - */ - private function _readFooter() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: var - // realized that $recordData can be empty even when record exists - if ($recordData) { - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong($recordData); - } else { - $string = $this->_readByteStringShort($recordData); - } - $this->_phpSheet->getHeaderFooter()->setOddFooter($string['value']); - $this->_phpSheet->getHeaderFooter()->setEvenFooter($string['value']); - } - } - } - - - /** - * Read HCENTER record - */ - private function _readHcenter() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; 0 = print sheet left aligned, 1 = print sheet centered horizontally - $isHorizontalCentered = (bool) self::_GetInt2d($recordData, 0); - - $this->_phpSheet->getPageSetup()->setHorizontalCentered($isHorizontalCentered); - } - } - - - /** - * Read VCENTER record - */ - private function _readVcenter() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; 0 = print sheet aligned at top page border, 1 = print sheet vertically centered - $isVerticalCentered = (bool) self::_GetInt2d($recordData, 0); - - $this->_phpSheet->getPageSetup()->setVerticalCentered($isVerticalCentered); - } - } - - - /** - * Read LEFTMARGIN record - */ - private function _readLeftMargin() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setLeft(self::_extractNumber($recordData)); - } - } - - - /** - * Read RIGHTMARGIN record - */ - private function _readRightMargin() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setRight(self::_extractNumber($recordData)); - } - } - - - /** - * Read TOPMARGIN record - */ - private function _readTopMargin() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setTop(self::_extractNumber($recordData)); - } - } - - - /** - * Read BOTTOMMARGIN record - */ - private function _readBottomMargin() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setBottom(self::_extractNumber($recordData)); - } - } - - - /** - * Read PAGESETUP record - */ - private function _readPageSetup() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; paper size - $paperSize = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; scaling factor - $scale = self::_GetInt2d($recordData, 2); - - // offset: 6; size: 2; fit worksheet width to this number of pages, 0 = use as many as needed - $fitToWidth = self::_GetInt2d($recordData, 6); - - // offset: 8; size: 2; fit worksheet height to this number of pages, 0 = use as many as needed - $fitToHeight = self::_GetInt2d($recordData, 8); - - // offset: 10; size: 2; option flags - - // bit: 1; mask: 0x0002; 0=landscape, 1=portrait - $isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1; - - // bit: 2; mask: 0x0004; 1= paper size, scaling factor, paper orient. not init - // when this bit is set, do not use flags for those properties - $isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2; - - if (!$isNotInit) { - $this->_phpSheet->getPageSetup()->setPaperSize($paperSize); - switch ($isPortrait) { - case 0: - $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); - break; - case 1: - $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); - break; - } - - $this->_phpSheet->getPageSetup()->setScale($scale, false); - $this->_phpSheet->getPageSetup()->setFitToPage((bool) $this->_isFitToPages); - $this->_phpSheet->getPageSetup()->setFitToWidth($fitToWidth, false); - $this->_phpSheet->getPageSetup()->setFitToHeight($fitToHeight, false); - } - - // offset: 16; size: 8; header margin (IEEE 754 floating-point value) - $marginHeader = self::_extractNumber(substr($recordData, 16, 8)); - $this->_phpSheet->getPageMargins()->setHeader($marginHeader); - - // offset: 24; size: 8; footer margin (IEEE 754 floating-point value) - $marginFooter = self::_extractNumber(substr($recordData, 24, 8)); - $this->_phpSheet->getPageMargins()->setFooter($marginFooter); - } - } - - - /** - * PROTECT - Sheet protection (BIFF2 through BIFF8) - * if this record is omitted, then it also means no sheet protection - */ - private function _readProtect() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - // offset: 0; size: 2; - - // bit 0, mask 0x01; 1 = sheet is protected - $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; - $this->_phpSheet->getProtection()->setSheet((bool)$bool); - } - - - /** - * SCENPROTECT - */ - private function _readScenProtect() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - // offset: 0; size: 2; - - // bit: 0, mask 0x01; 1 = scenarios are protected - $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; - - $this->_phpSheet->getProtection()->setScenarios((bool)$bool); - } - - - /** - * OBJECTPROTECT - */ - private function _readObjectProtect() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - // offset: 0; size: 2; - - // bit: 0, mask 0x01; 1 = objects are protected - $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; - - $this->_phpSheet->getProtection()->setObjects((bool)$bool); - } - - - /** - * PASSWORD - Sheet protection (hashed) password (BIFF2 through BIFF8) - */ - private function _readPassword() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; 16-bit hash value of password - $password = strtoupper(dechex(self::_GetInt2d($recordData, 0))); // the hashed password - $this->_phpSheet->getProtection()->setPassword($password, true); - } - } - - - /** - * Read DEFCOLWIDTH record - */ - private function _readDefColWidth() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; default column width - $width = self::_GetInt2d($recordData, 0); - if ($width != 8) { - $this->_phpSheet->getDefaultColumnDimension()->setWidth($width); - } - } - - - /** - * Read COLINFO record - */ - private function _readColInfo() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; index to first column in range - $fc = self::_GetInt2d($recordData, 0); // first column index - - // offset: 2; size: 2; index to last column in range - $lc = self::_GetInt2d($recordData, 2); // first column index - - // offset: 4; size: 2; width of the column in 1/256 of the width of the zero character - $width = self::_GetInt2d($recordData, 4); - - // offset: 6; size: 2; index to XF record for default column formatting - $xfIndex = self::_GetInt2d($recordData, 6); - - // offset: 8; size: 2; option flags - // bit: 0; mask: 0x0001; 1= columns are hidden - $isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0; - - // bit: 10-8; mask: 0x0700; outline level of the columns (0 = no outline) - $level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8; - - // bit: 12; mask: 0x1000; 1 = collapsed - $isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12; - - // offset: 10; size: 2; not used - - for ($i = $fc; $i <= $lc; ++$i) { - if ($lc == 255 || $lc == 256) { - $this->_phpSheet->getDefaultColumnDimension()->setWidth($width / 256); - break; - } - $this->_phpSheet->getColumnDimensionByColumn($i)->setWidth($width / 256); - $this->_phpSheet->getColumnDimensionByColumn($i)->setVisible(!$isHidden); - $this->_phpSheet->getColumnDimensionByColumn($i)->setOutlineLevel($level); - $this->_phpSheet->getColumnDimensionByColumn($i)->setCollapsed($isCollapsed); - $this->_phpSheet->getColumnDimensionByColumn($i)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - - /** - * ROW - * - * This record contains the properties of a single row in a - * sheet. Rows and cells in a sheet are divided into blocks - * of 32 rows. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readRow() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; index of this row - $r = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to column of the first cell which is described by a cell record - - // offset: 4; size: 2; index to column of the last cell which is described by a cell record, increased by 1 - - // offset: 6; size: 2; - - // bit: 14-0; mask: 0x7FFF; height of the row, in twips = 1/20 of a point - $height = (0x7FFF & self::_GetInt2d($recordData, 6)) >> 0; - - // bit: 15: mask: 0x8000; 0 = row has custom height; 1= row has default height - $useDefaultHeight = (0x8000 & self::_GetInt2d($recordData, 6)) >> 15; - - if (!$useDefaultHeight) { - $this->_phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20); - } - - // offset: 8; size: 2; not used - - // offset: 10; size: 2; not used in BIFF5-BIFF8 - - // offset: 12; size: 4; option flags and default row formatting - - // bit: 2-0: mask: 0x00000007; outline level of the row - $level = (0x00000007 & self::_GetInt4d($recordData, 12)) >> 0; - $this->_phpSheet->getRowDimension($r + 1)->setOutlineLevel($level); - - // bit: 4; mask: 0x00000010; 1 = outline group start or ends here... and is collapsed - $isCollapsed = (0x00000010 & self::_GetInt4d($recordData, 12)) >> 4; - $this->_phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed); - - // bit: 5; mask: 0x00000020; 1 = row is hidden - $isHidden = (0x00000020 & self::_GetInt4d($recordData, 12)) >> 5; - $this->_phpSheet->getRowDimension($r + 1)->setVisible(!$isHidden); - - // bit: 7; mask: 0x00000080; 1 = row has explicit format - $hasExplicitFormat = (0x00000080 & self::_GetInt4d($recordData, 12)) >> 7; - - // bit: 27-16; mask: 0x0FFF0000; only applies when hasExplicitFormat = 1; index to XF record - $xfIndex = (0x0FFF0000 & self::_GetInt4d($recordData, 12)) >> 16; - - if ($hasExplicitFormat) { - $this->_phpSheet->getRowDimension($r + 1)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - - /** - * Read RK record - * This record represents a cell that contains an RK value - * (encoded integer or floating-point value). If a - * floating-point value cannot be encoded to an RK value, - * a NUMBER record will be written. This record replaces the - * record INTEGER written in BIFF2. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readRk() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to column - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { - // offset: 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); - - // offset: 6; size: 4; RK value - $rknum = self::_GetInt4d($recordData, 6); - $numValue = self::_GetIEEE754($rknum); - - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { - // add style information - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - - // add cell - $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); - } - } - - - /** - * Read LABELSST record - * This record represents a cell that contains a string. It - * replaces the LABEL record and RSTRING record used in - * BIFF2-BIFF5. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readLabelSst() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to column - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { - // offset: 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); - - // offset: 6; size: 4; index to SST record - $index = self::_GetInt4d($recordData, 6); - - // add cell - if (($fmtRuns = $this->_sst[$index]['fmtRuns']) && !$this->_readDataOnly) { - // then we should treat as rich text - $richText = new PHPExcel_RichText(); - $charPos = 0; - $sstCount = count($this->_sst[$index]['fmtRuns']); - for ($i = 0; $i <= $sstCount; ++$i) { - if (isset($fmtRuns[$i])) { - $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos); - $charPos = $fmtRuns[$i]['charPos']; - } else { - $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, PHPExcel_Shared_String::CountCharacters($this->_sst[$index]['value'])); - } - - if (PHPExcel_Shared_String::CountCharacters($text) > 0) { - if ($i == 0) { // first text run, no style - $richText->createText($text); - } else { - $textRun = $richText->createTextRun($text); - if (isset($fmtRuns[$i - 1])) { - if ($fmtRuns[$i - 1]['fontIndex'] < 4) { - $fontIndex = $fmtRuns[$i - 1]['fontIndex']; - } else { - // this has to do with that index 4 is omitted in all BIFF versions for some strange reason - // check the OpenOffice documentation of the FONT record - $fontIndex = $fmtRuns[$i - 1]['fontIndex'] - 1; - } - $textRun->setFont(clone $this->_objFonts[$fontIndex]); - } - } - } - } - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - $cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING); - } else { - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - $cell->setValueExplicit($this->_sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING); - } - - if (!$this->_readDataOnly) { - // add style information - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - - /** - * Read MULRK record - * This record represents a cell range containing RK value - * cells. All cells are located in the same row. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readMulRk() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to first column - $colFirst = self::_GetInt2d($recordData, 2); - - // offset: var; size: 2; index to last column - $colLast = self::_GetInt2d($recordData, $length - 2); - $columns = $colLast - $colFirst + 1; - - // offset within record data - $offset = 4; - - for ($i = 0; $i < $columns; ++$i) { - $columnString = PHPExcel_Cell::stringFromColumnIndex($colFirst + $i); - - // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { - // offset: var; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, $offset); - - // offset: var; size: 4; RK value - $numValue = self::_GetIEEE754(self::_GetInt4d($recordData, $offset + 2)); - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { - // add style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - - // add cell value - $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); - } - - $offset += 6; - } - } - - - /** - * Read NUMBER record - * This record represents a cell that contains a - * floating-point value. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readNumber() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size 2; index to column - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { - // offset 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); - - $numValue = self::_extractNumber(substr($recordData, 6, 8)); - - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { - // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - - // add cell value - $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); - } - } - - - /** - * Read FORMULA record + perhaps a following STRING record if formula result is a string - * This record contains the token array and the result of a - * formula cell. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readFormula() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; row index - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; col index - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // offset: 20: size: variable; formula structure - $formulaStructure = substr($recordData, 20); - - // offset: 14: size: 2; option flags, recalculate always, recalculate on open etc. - $options = self::_GetInt2d($recordData, 14); - - // bit: 0; mask: 0x0001; 1 = recalculate always - // bit: 1; mask: 0x0002; 1 = calculate on open - // bit: 2; mask: 0x0008; 1 = part of a shared formula - $isPartOfSharedFormula = (bool) (0x0008 & $options); - - // WARNING: - // We can apparently not rely on $isPartOfSharedFormula. Even when $isPartOfSharedFormula = true - // the formula data may be ordinary formula data, therefore we need to check - // explicitly for the tExp token (0x01) - $isPartOfSharedFormula = $isPartOfSharedFormula && ord($formulaStructure{2}) == 0x01; - - if ($isPartOfSharedFormula) { - // part of shared formula which means there will be a formula with a tExp token and nothing else - // get the base cell, grab tExp token - $baseRow = self::_GetInt2d($formulaStructure, 3); - $baseCol = self::_GetInt2d($formulaStructure, 5); - $this->_baseCell = PHPExcel_Cell::stringFromColumnIndex($baseCol). ($baseRow + 1); - } - - // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { - if ($isPartOfSharedFormula) { - // formula is added to this cell after the sheet has been read - $this->_sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell; - } - - // offset: 16: size: 4; not used - - // offset: 4; size: 2; XF index - $xfIndex = self::_GetInt2d($recordData, 4); - - // offset: 6; size: 8; result of the formula - if ((ord($recordData{6}) == 0) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { - // String formula. Result follows in appended STRING record - $dataType = PHPExcel_Cell_DataType::TYPE_STRING; - - // read possible SHAREDFMLA record - $code = self::_GetInt2d($this->_data, $this->_pos); - if ($code == self::XLS_Type_SHAREDFMLA) { - $this->_readSharedFmla(); - } - - // read STRING record - $value = $this->_readString(); - } elseif ((ord($recordData{6}) == 1) - && (ord($recordData{12}) == 255) - && (ord($recordData{13}) == 255)) { - // Boolean formula. Result is in +2; 0=false, 1=true - $dataType = PHPExcel_Cell_DataType::TYPE_BOOL; - $value = (bool) ord($recordData{8}); - } elseif ((ord($recordData{6}) == 2) - && (ord($recordData{12}) == 255) - && (ord($recordData{13}) == 255)) { - // Error formula. Error code is in +2 - $dataType = PHPExcel_Cell_DataType::TYPE_ERROR; - $value = self::_mapErrorCode(ord($recordData{8})); - } elseif ((ord($recordData{6}) == 3) - && (ord($recordData{12}) == 255) - && (ord($recordData{13}) == 255)) { - // Formula result is a null string - $dataType = PHPExcel_Cell_DataType::TYPE_NULL; - $value = ''; - } else { - // forumla result is a number, first 14 bytes like _NUMBER record - $dataType = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $value = self::_extractNumber(substr($recordData, 6, 8)); - } - - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { - // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - - // store the formula - if (!$isPartOfSharedFormula) { - // not part of shared formula - // add cell value. If we can read formula, populate with formula, otherwise just used cached value - try { - if ($this->_version != self::XLS_BIFF8) { - throw new PHPExcel_Reader_Exception('Not BIFF8. Can only read BIFF8 formulas'); - } - $formula = $this->_getFormulaFromStructure($formulaStructure); // get formula in human language - $cell->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); - - } catch (PHPExcel_Exception $e) { - $cell->setValueExplicit($value, $dataType); - } - } else { - if ($this->_version == self::XLS_BIFF8) { - // do nothing at this point, formula id added later in the code - } else { - $cell->setValueExplicit($value, $dataType); - } - } - - // store the cached calculated value - $cell->setCalculatedValue($value); - } - } - - - /** - * Read a SHAREDFMLA record. This function just stores the binary shared formula in the reader, - * which usually contains relative references. - * These will be used to construct the formula in each shared formula part after the sheet is read. - */ - private function _readSharedFmla() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0, size: 6; cell range address of the area used by the shared formula, not used for anything - $cellRange = substr($recordData, 0, 6); - $cellRange = $this->_readBIFF5CellRangeAddressFixed($cellRange); // note: even BIFF8 uses BIFF5 syntax - - // offset: 6, size: 1; not used - - // offset: 7, size: 1; number of existing FORMULA records for this shared formula - $no = ord($recordData{7}); - - // offset: 8, size: var; Binary token array of the shared formula - $formula = substr($recordData, 8); - - // at this point we only store the shared formula for later use - $this->_sharedFormulas[$this->_baseCell] = $formula; - } - - - /** - * Read a STRING record from current stream position and advance the stream pointer to next record - * This record is used for storing result from FORMULA record when it is a string, and - * it occurs directly after the FORMULA record - * - * @return string The string contents as UTF-8 - */ - private function _readString() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong($recordData); - $value = $string['value']; - } else { - $string = $this->_readByteStringLong($recordData); - $value = $string['value']; - } - - return $value; - } - - - /** - * Read BOOLERR record - * This record represents a Boolean value or error value - * cell. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readBoolErr() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; row index - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; column index - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { - // offset: 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); - - // offset: 6; size: 1; the boolean value or error value - $boolErr = ord($recordData{6}); - - // offset: 7; size: 1; 0=boolean; 1=error - $isError = ord($recordData{7}); - - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - switch ($isError) { - case 0: // boolean - $value = (bool) $boolErr; - - // add cell value - $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL); - break; - case 1: // error type - $value = self::_mapErrorCode($boolErr); - - // add cell value - $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_ERROR); - break; - } - - if (!$this->_readDataOnly) { - // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - - /** - * Read MULBLANK record - * This record represents a cell range of empty cells. All - * cells are located in the same row - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readMulBlank() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to first column - $fc = self::_GetInt2d($recordData, 2); - - // offset: 4; size: 2 x nc; list of indexes to XF records - // add style information - if (!$this->_readDataOnly) { - for ($i = 0; $i < $length / 2 - 3; ++$i) { - $columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i); - - // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { - $xfIndex = self::_GetInt2d($recordData, 4 + 2 * $i); - $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - // offset: 6; size 2; index to last column (not needed) - } - - - /** - * Read LABEL record - * This record represents a cell that contains a string. In - * BIFF8 it is usually replaced by the LABELSST record. - * Excel still uses this record, if it copies unformatted - * text cells to the clipboard. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readLabel() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to column - $column = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($column); - - // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { - // offset: 4; size: 2; XF index - $xfIndex = self::_GetInt2d($recordData, 4); - - // add cell value - // todo: what if string is very long? continue record - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong(substr($recordData, 6)); - $value = $string['value']; - } else { - $string = $this->_readByteStringLong(substr($recordData, 6)); - $value = $string['value']; - } - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); - - if (!$this->_readDataOnly) { - // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - } - - - /** - * Read BLANK record - */ - private function _readBlank() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; row index - $row = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; col index - $col = self::_GetInt2d($recordData, 2); - $columnString = PHPExcel_Cell::stringFromColumnIndex($col); - - // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { - // offset: 4; size: 2; XF index - $xfIndex = self::_GetInt2d($recordData, 4); - - // add style information - if (!$this->_readDataOnly) { - $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); - } - } - - } - - - /** - * Read MSODRAWING record - */ - private function _readMsoDrawing() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - - // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); - $recordData = $splicedRecordData['recordData']; - - $this->_drawingData .= $recordData; - } - - - /** - * Read OBJ record - */ - private function _readObj() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly || $this->_version != self::XLS_BIFF8) { - return; - } - - // recordData consists of an array of subrecords looking like this: - // ft: 2 bytes; ftCmo type (0x15) - // cb: 2 bytes; size in bytes of ftCmo data - // ot: 2 bytes; Object Type - // id: 2 bytes; Object id number - // grbit: 2 bytes; Option Flags - // data: var; subrecord data - - // for now, we are just interested in the second subrecord containing the object type - $ftCmoType = self::_GetInt2d($recordData, 0); - $cbCmoSize = self::_GetInt2d($recordData, 2); - $otObjType = self::_GetInt2d($recordData, 4); - $idObjID = self::_GetInt2d($recordData, 6); - $grbitOpts = self::_GetInt2d($recordData, 6); - - $this->_objs[] = array( - 'ftCmoType' => $ftCmoType, - 'cbCmoSize' => $cbCmoSize, - 'otObjType' => $otObjType, - 'idObjID' => $idObjID, - 'grbitOpts' => $grbitOpts - ); - $this->textObjRef = $idObjID; - -// echo '<b>_readObj()</b><br />'; -// var_dump(end($this->_objs)); -// echo '<br />'; - } - - - /** - * Read WINDOW2 record - */ - private function _readWindow2() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; option flags - $options = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; index to first visible row - $firstVisibleRow = self::_GetInt2d($recordData, 2); - - // offset: 4; size: 2; index to first visible colum - $firstVisibleColumn = self::_GetInt2d($recordData, 4); - if ($this->_version === self::XLS_BIFF8) { - // offset: 8; size: 2; not used - // offset: 10; size: 2; cached magnification factor in page break preview (in percent); 0 = Default (60%) - // offset: 12; size: 2; cached magnification factor in normal view (in percent); 0 = Default (100%) - // offset: 14; size: 4; not used - $zoomscaleInPageBreakPreview = self::_GetInt2d($recordData, 10); - if ($zoomscaleInPageBreakPreview === 0) { - $zoomscaleInPageBreakPreview = 60; - } - $zoomscaleInNormalView = self::_GetInt2d($recordData, 12); - if ($zoomscaleInNormalView === 0) { - $zoomscaleInNormalView = 100; - } - } - - // bit: 1; mask: 0x0002; 0 = do not show gridlines, 1 = show gridlines - $showGridlines = (bool) ((0x0002 & $options) >> 1); - $this->_phpSheet->setShowGridlines($showGridlines); - - // bit: 2; mask: 0x0004; 0 = do not show headers, 1 = show headers - $showRowColHeaders = (bool) ((0x0004 & $options) >> 2); - $this->_phpSheet->setShowRowColHeaders($showRowColHeaders); - - // bit: 3; mask: 0x0008; 0 = panes are not frozen, 1 = panes are frozen - $this->_frozen = (bool) ((0x0008 & $options) >> 3); - - // bit: 6; mask: 0x0040; 0 = columns from left to right, 1 = columns from right to left - $this->_phpSheet->setRightToLeft((bool)((0x0040 & $options) >> 6)); - - // bit: 10; mask: 0x0400; 0 = sheet not active, 1 = sheet active - $isActive = (bool) ((0x0400 & $options) >> 10); - if ($isActive) { - $this->_phpExcel->setActiveSheetIndex($this->_phpExcel->getIndex($this->_phpSheet)); - } - - // bit: 11; mask: 0x0800; 0 = normal view, 1 = page break view - $isPageBreakPreview = (bool) ((0x0800 & $options) >> 11); - - //FIXME: set $firstVisibleRow and $firstVisibleColumn - - if ($this->_phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { - //NOTE: this setting is inferior to page layout view(Excel2007-) - $view = $isPageBreakPreview ? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW : PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL; - $this->_phpSheet->getSheetView()->setView($view); - if ($this->_version === self::XLS_BIFF8) { - $zoomScale = $isPageBreakPreview ? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView; - $this->_phpSheet->getSheetView()->setZoomScale($zoomScale); - $this->_phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView); - } - } - } - - /** - * Read PLV Record(Created by Excel2007 or upper) - */ - private function _readPageLayoutView() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - //var_dump(unpack("vrt/vgrbitFrt/V2reserved/vwScalePLV/vgrbit", $recordData)); - - // offset: 0; size: 2; rt - //->ignore - $rt = self::_GetInt2d($recordData, 0); - // offset: 2; size: 2; grbitfr - //->ignore - $grbitFrt = self::_GetInt2d($recordData, 2); - // offset: 4; size: 8; reserved - //->ignore - - // offset: 12; size 2; zoom scale - $wScalePLV = self::_GetInt2d($recordData, 12); - // offset: 14; size 2; grbit - $grbit = self::_GetInt2d($recordData, 14); - - // decomprise grbit - $fPageLayoutView = $grbit & 0x01; - $fRulerVisible = ($grbit >> 1) & 0x01; //no support - $fWhitespaceHidden = ($grbit >> 3) & 0x01; //no support - - if ($fPageLayoutView === 1) { - $this->_phpSheet->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT); - $this->_phpSheet->getSheetView()->setZoomScale($wScalePLV); //set by Excel2007 only if SHEETVIEW_PAGE_LAYOUT - } - //otherwise, we cannot know whether SHEETVIEW_PAGE_LAYOUT or SHEETVIEW_PAGE_BREAK_PREVIEW. - } - - /** - * Read SCL record - */ - private function _readScl() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // offset: 0; size: 2; numerator of the view magnification - $numerator = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; numerator of the view magnification - $denumerator = self::_GetInt2d($recordData, 2); - - // set the zoom scale (in percent) - $this->_phpSheet->getSheetView()->setZoomScale($numerator * 100 / $denumerator); - } - - - /** - * Read PANE record - */ - private function _readPane() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; position of vertical split - $px = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; position of horizontal split - $py = self::_GetInt2d($recordData, 2); - - if ($this->_frozen) { - // frozen panes - $this->_phpSheet->freezePane(PHPExcel_Cell::stringFromColumnIndex($px) . ($py + 1)); - } else { - // unfrozen panes; split windows; not supported by PHPExcel core - } - } - } - - - /** - * Read SELECTION record. There is one such record for each pane in the sheet. - */ - private function _readSelection() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 1; pane identifier - $paneId = ord($recordData{0}); - - // offset: 1; size: 2; index to row of the active cell - $r = self::_GetInt2d($recordData, 1); - - // offset: 3; size: 2; index to column of the active cell - $c = self::_GetInt2d($recordData, 3); - - // offset: 5; size: 2; index into the following cell range list to the - // entry that contains the active cell - $index = self::_GetInt2d($recordData, 5); - - // offset: 7; size: var; cell range address list containing all selected cell ranges - $data = substr($recordData, 7); - $cellRangeAddressList = $this->_readBIFF5CellRangeAddressList($data); // note: also BIFF8 uses BIFF5 syntax - - $selectedCells = $cellRangeAddressList['cellRangeAddresses'][0]; - - // first row '1' + last row '16384' indicates that full column is selected (apparently also in BIFF8!) - if (preg_match('/^([A-Z]+1\:[A-Z]+)16384$/', $selectedCells)) { - $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)16384$/', '${1}1048576', $selectedCells); - } - - // first row '1' + last row '65536' indicates that full column is selected - if (preg_match('/^([A-Z]+1\:[A-Z]+)65536$/', $selectedCells)) { - $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)65536$/', '${1}1048576', $selectedCells); - } - - // first column 'A' + last column 'IV' indicates that full row is selected - if (preg_match('/^(A[0-9]+\:)IV([0-9]+)$/', $selectedCells)) { - $selectedCells = preg_replace('/^(A[0-9]+\:)IV([0-9]+)$/', '${1}XFD${2}', $selectedCells); - } - - $this->_phpSheet->setSelectedCells($selectedCells); - } - } - - - private function _includeCellRangeFiltered($cellRangeAddress) - { - $includeCellRange = true; - if ($this->getReadFilter() !== null) { - $includeCellRange = false; - $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($cellRangeAddress); - $rangeBoundaries[1][0]++; - for ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; $row++) { - for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; $column++) { - if ($this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { - $includeCellRange = true; - break 2; - } - } - } - } - return $includeCellRange; - } - - - /** - * MERGEDCELLS - * - * This record contains the addresses of merged cell ranges - * in the current sheet. - * - * -- "OpenOffice.org's Documentation of the Microsoft - * Excel File Format" - */ - private function _readMergedCells() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { - $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData); - foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) { - if ((strpos($cellRangeAddress, ':') !== false) && - ($this->_includeCellRangeFiltered($cellRangeAddress))) { - $this->_phpSheet->mergeCells($cellRangeAddress); - } - } - } - } - - - /** - * Read HYPERLINK record - */ - private function _readHyperLink() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer forward to next record - $this->_pos += 4 + $length; - - if (!$this->_readDataOnly) { - // offset: 0; size: 8; cell range address of all cells containing this hyperlink - try { - $cellRange = $this->_readBIFF8CellRangeAddressFixed($recordData, 0, 8); - } catch (PHPExcel_Exception $e) { - return; - } - - // offset: 8, size: 16; GUID of StdLink - - // offset: 24, size: 4; unknown value - - // offset: 28, size: 4; option flags - // bit: 0; mask: 0x00000001; 0 = no link or extant, 1 = file link or URL - $isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0; - - // bit: 1; mask: 0x00000002; 0 = relative path, 1 = absolute path or URL - $isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1; - - // bit: 2 (and 4); mask: 0x00000014; 0 = no description - $hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2; - - // bit: 3; mask: 0x00000008; 0 = no text, 1 = has text - $hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3; - - // bit: 7; mask: 0x00000080; 0 = no target frame, 1 = has target frame - $hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7; - - // bit: 8; mask: 0x00000100; 0 = file link or URL, 1 = UNC path (inc. server name) - $isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8; - - // offset within record data - $offset = 32; - - if ($hasDesc) { - // offset: 32; size: var; character count of description text - $dl = self::_GetInt4d($recordData, 32); - // offset: 36; size: var; character array of description text, no Unicode string header, always 16-bit characters, zero terminated - $desc = self::_encodeUTF16(substr($recordData, 36, 2 * ($dl - 1)), false); - $offset += 4 + 2 * $dl; - } - if ($hasFrame) { - $fl = self::_GetInt4d($recordData, $offset); - $offset += 4 + 2 * $fl; - } - - // detect type of hyperlink (there are 4 types) - $hyperlinkType = null; - - if ($isUNC) { - $hyperlinkType = 'UNC'; - } else if (!$isFileLinkOrUrl) { - $hyperlinkType = 'workbook'; - } else if (ord($recordData{$offset}) == 0x03) { - $hyperlinkType = 'local'; - } else if (ord($recordData{$offset}) == 0xE0) { - $hyperlinkType = 'URL'; - } - - switch ($hyperlinkType) { - case 'URL': - // section 5.58.2: Hyperlink containing a URL - // e.g. http://example.org/index.php - - // offset: var; size: 16; GUID of URL Moniker - $offset += 16; - // offset: var; size: 4; size (in bytes) of character array of the URL including trailing zero word - $us = self::_GetInt4d($recordData, $offset); - $offset += 4; - // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated - $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); - $nullOffset = strpos($url, 0x00); - if ($nullOffset) { - $url = substr($url, 0, $nullOffset); - } - $url .= $hasText ? '#' : ''; - $offset += $us; - break; - case 'local': - // section 5.58.3: Hyperlink to local file - // examples: - // mydoc.txt - // ../../somedoc.xls#Sheet!A1 - - // offset: var; size: 16; GUI of File Moniker - $offset += 16; - - // offset: var; size: 2; directory up-level count. - $upLevelCount = self::_GetInt2d($recordData, $offset); - $offset += 2; - - // offset: var; size: 4; character count of the shortened file path and name, including trailing zero word - $sl = self::_GetInt4d($recordData, $offset); - $offset += 4; - - // offset: var; size: sl; character array of the shortened file path and name in 8.3-DOS-format (compressed Unicode string) - $shortenedFilePath = substr($recordData, $offset, $sl); - $shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true); - $shortenedFilePath = substr($shortenedFilePath, 0, -1); // remove trailing zero - - $offset += $sl; - - // offset: var; size: 24; unknown sequence - $offset += 24; - - // extended file path - // offset: var; size: 4; size of the following file link field including string lenth mark - $sz = self::_GetInt4d($recordData, $offset); - $offset += 4; - - // only present if $sz > 0 - if ($sz > 0) { - // offset: var; size: 4; size of the character array of the extended file path and name - $xl = self::_GetInt4d($recordData, $offset); - $offset += 4; - - // offset: var; size 2; unknown - $offset += 2; - - // offset: var; size $xl; character array of the extended file path and name. - $extendedFilePath = substr($recordData, $offset, $xl); - $extendedFilePath = self::_encodeUTF16($extendedFilePath, false); - $offset += $xl; - } - - // construct the path - $url = str_repeat('..\\', $upLevelCount); - $url .= ($sz > 0) ? $extendedFilePath : $shortenedFilePath; // use extended path if available - $url .= $hasText ? '#' : ''; - - break; - case 'UNC': - // section 5.58.4: Hyperlink to a File with UNC (Universal Naming Convention) Path - // todo: implement - return; - case 'workbook': - // section 5.58.5: Hyperlink to the Current Workbook - // e.g. Sheet2!B1:C2, stored in text mark field - $url = 'sheet://'; - break; - default: - return; - } - - if ($hasText) { - // offset: var; size: 4; character count of text mark including trailing zero word - $tl = self::_GetInt4d($recordData, $offset); - $offset += 4; - // offset: var; size: var; character array of the text mark without the # sign, no Unicode header, always 16-bit characters, zero-terminated - $text = self::_encodeUTF16(substr($recordData, $offset, 2 * ($tl - 1)), false); - $url .= $text; - } - - // apply the hyperlink to all the relevant cells - foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cellRange) as $coordinate) { - $this->_phpSheet->getCell($coordinate)->getHyperLink()->setUrl($url); - } - } - } - - - /** - * Read DATAVALIDATIONS record - */ - private function _readDataValidations() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer forward to next record - $this->_pos += 4 + $length; - } - - - /** - * Read DATAVALIDATION record - */ - private function _readDataValidation() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer forward to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - // offset: 0; size: 4; Options - $options = self::_GetInt4d($recordData, 0); - - // bit: 0-3; mask: 0x0000000F; type - $type = (0x0000000F & $options) >> 0; - switch ($type) { - case 0x00: - $type = PHPExcel_Cell_DataValidation::TYPE_NONE; - break; - case 0x01: - $type = PHPExcel_Cell_DataValidation::TYPE_WHOLE; - break; - case 0x02: - $type = PHPExcel_Cell_DataValidation::TYPE_DECIMAL; - break; - case 0x03: - $type = PHPExcel_Cell_DataValidation::TYPE_LIST; - break; - case 0x04: - $type = PHPExcel_Cell_DataValidation::TYPE_DATE; - break; - case 0x05: - $type = PHPExcel_Cell_DataValidation::TYPE_TIME; - break; - case 0x06: - $type = PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH; - break; - case 0x07: - $type = PHPExcel_Cell_DataValidation::TYPE_CUSTOM; - break; - } - - // bit: 4-6; mask: 0x00000070; error type - $errorStyle = (0x00000070 & $options) >> 4; - switch ($errorStyle) { - case 0x00: - $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; - break; - case 0x01: - $errorStyle = PHPExcel_Cell_DataValidation::STYLE_WARNING; - break; - case 0x02: - $errorStyle = PHPExcel_Cell_DataValidation::STYLE_INFORMATION; - break; - } - - // bit: 7; mask: 0x00000080; 1= formula is explicit (only applies to list) - // I have only seen cases where this is 1 - $explicitFormula = (0x00000080 & $options) >> 7; - - // bit: 8; mask: 0x00000100; 1= empty cells allowed - $allowBlank = (0x00000100 & $options) >> 8; - - // bit: 9; mask: 0x00000200; 1= suppress drop down arrow in list type validity - $suppressDropDown = (0x00000200 & $options) >> 9; - - // bit: 18; mask: 0x00040000; 1= show prompt box if cell selected - $showInputMessage = (0x00040000 & $options) >> 18; - - // bit: 19; mask: 0x00080000; 1= show error box if invalid values entered - $showErrorMessage = (0x00080000 & $options) >> 19; - - // bit: 20-23; mask: 0x00F00000; condition operator - $operator = (0x00F00000 & $options) >> 20; - switch ($operator) { - case 0x00: - $operator = PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN; - break; - case 0x01: - $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN; - break; - case 0x02: - $operator = PHPExcel_Cell_DataValidation::OPERATOR_EQUAL; - break; - case 0x03: - $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL; - break; - case 0x04: - $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN; - break; - case 0x05: - $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN; - break; - case 0x06: - $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL; - break; - case 0x07: - $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL; - break; - } - - // offset: 4; size: var; title of the prompt box - $offset = 4; - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $promptTitle = $string['value'] !== chr(0) ? $string['value'] : ''; - $offset += $string['size']; - - // offset: var; size: var; title of the error box - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $errorTitle = $string['value'] !== chr(0) ? $string['value'] : ''; - $offset += $string['size']; - - // offset: var; size: var; text of the prompt box - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $prompt = $string['value'] !== chr(0) ? $string['value'] : ''; - $offset += $string['size']; - - // offset: var; size: var; text of the error box - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); - $error = $string['value'] !== chr(0) ? $string['value'] : ''; - $offset += $string['size']; - - // offset: var; size: 2; size of the formula data for the first condition - $sz1 = self::_GetInt2d($recordData, $offset); - $offset += 2; - - // offset: var; size: 2; not used - $offset += 2; - - // offset: var; size: $sz1; formula data for first condition (without size field) - $formula1 = substr($recordData, $offset, $sz1); - $formula1 = pack('v', $sz1) . $formula1; // prepend the length - try { - $formula1 = $this->_getFormulaFromStructure($formula1); - - // in list type validity, null characters are used as item separators - if ($type == PHPExcel_Cell_DataValidation::TYPE_LIST) { - $formula1 = str_replace(chr(0), ',', $formula1); - } - } catch (PHPExcel_Exception $e) { - return; - } - $offset += $sz1; - - // offset: var; size: 2; size of the formula data for the first condition - $sz2 = self::_GetInt2d($recordData, $offset); - $offset += 2; - - // offset: var; size: 2; not used - $offset += 2; - - // offset: var; size: $sz2; formula data for second condition (without size field) - $formula2 = substr($recordData, $offset, $sz2); - $formula2 = pack('v', $sz2) . $formula2; // prepend the length - try { - $formula2 = $this->_getFormulaFromStructure($formula2); - } catch (PHPExcel_Exception $e) { - return; - } - $offset += $sz2; - - // offset: var; size: var; cell range address list with - $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList(substr($recordData, $offset)); - $cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses']; - - foreach ($cellRangeAddresses as $cellRange) { - $stRange = $this->_phpSheet->shrinkRangeToFit($cellRange); - $stRange = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); - foreach ($stRange as $coordinate) { - $objValidation = $this->_phpSheet->getCell($coordinate)->getDataValidation(); - $objValidation->setType($type); - $objValidation->setErrorStyle($errorStyle); - $objValidation->setAllowBlank((bool)$allowBlank); - $objValidation->setShowInputMessage((bool)$showInputMessage); - $objValidation->setShowErrorMessage((bool)$showErrorMessage); - $objValidation->setShowDropDown(!$suppressDropDown); - $objValidation->setOperator($operator); - $objValidation->setErrorTitle($errorTitle); - $objValidation->setError($error); - $objValidation->setPromptTitle($promptTitle); - $objValidation->setPrompt($prompt); - $objValidation->setFormula1($formula1); - $objValidation->setFormula2($formula2); - } - } - } - - /** - * Read SHEETLAYOUT record. Stores sheet tab color information. - */ - private function _readSheetLayout() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // local pointer in record data - $offset = 0; - - if (!$this->_readDataOnly) { - // offset: 0; size: 2; repeated record identifier 0x0862 - - // offset: 2; size: 10; not used - - // offset: 12; size: 4; size of record data - // Excel 2003 uses size of 0x14 (documented), Excel 2007 uses size of 0x28 (not documented?) - $sz = self::_GetInt4d($recordData, 12); - - switch ($sz) { - case 0x14: - // offset: 16; size: 2; color index for sheet tab - $colorIndex = self::_GetInt2d($recordData, 16); - $color = self::_readColor($colorIndex, $this->_palette, $this->_version); - $this->_phpSheet->getTabColor()->setRGB($color['rgb']); - break; - case 0x28: - // TODO: Investigate structure for .xls SHEETLAYOUT record as saved by MS Office Excel 2007 - return; - break; - } - } - } - - - /** - * Read SHEETPROTECTION record (FEATHEADR) - */ - private function _readSheetProtection() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - if ($this->_readDataOnly) { - return; - } - - // offset: 0; size: 2; repeated record header - - // offset: 2; size: 2; FRT cell reference flag (=0 currently) - - // offset: 4; size: 8; Currently not used and set to 0 - - // offset: 12; size: 2; Shared feature type index (2=Enhanced Protetion, 4=SmartTag) - $isf = self::_GetInt2d($recordData, 12); - if ($isf != 2) { - return; - } - - // offset: 14; size: 1; =1 since this is a feat header - - // offset: 15; size: 4; size of rgbHdrSData - - // rgbHdrSData, assume "Enhanced Protection" - // offset: 19; size: 2; option flags - $options = self::_GetInt2d($recordData, 19); - - // bit: 0; mask 0x0001; 1 = user may edit objects, 0 = users must not edit objects - $bool = (0x0001 & $options) >> 0; - $this->_phpSheet->getProtection()->setObjects(!$bool); - - // bit: 1; mask 0x0002; edit scenarios - $bool = (0x0002 & $options) >> 1; - $this->_phpSheet->getProtection()->setScenarios(!$bool); - - // bit: 2; mask 0x0004; format cells - $bool = (0x0004 & $options) >> 2; - $this->_phpSheet->getProtection()->setFormatCells(!$bool); - - // bit: 3; mask 0x0008; format columns - $bool = (0x0008 & $options) >> 3; - $this->_phpSheet->getProtection()->setFormatColumns(!$bool); - - // bit: 4; mask 0x0010; format rows - $bool = (0x0010 & $options) >> 4; - $this->_phpSheet->getProtection()->setFormatRows(!$bool); - - // bit: 5; mask 0x0020; insert columns - $bool = (0x0020 & $options) >> 5; - $this->_phpSheet->getProtection()->setInsertColumns(!$bool); - - // bit: 6; mask 0x0040; insert rows - $bool = (0x0040 & $options) >> 6; - $this->_phpSheet->getProtection()->setInsertRows(!$bool); - - // bit: 7; mask 0x0080; insert hyperlinks - $bool = (0x0080 & $options) >> 7; - $this->_phpSheet->getProtection()->setInsertHyperlinks(!$bool); - - // bit: 8; mask 0x0100; delete columns - $bool = (0x0100 & $options) >> 8; - $this->_phpSheet->getProtection()->setDeleteColumns(!$bool); - - // bit: 9; mask 0x0200; delete rows - $bool = (0x0200 & $options) >> 9; - $this->_phpSheet->getProtection()->setDeleteRows(!$bool); - - // bit: 10; mask 0x0400; select locked cells - $bool = (0x0400 & $options) >> 10; - $this->_phpSheet->getProtection()->setSelectLockedCells(!$bool); - - // bit: 11; mask 0x0800; sort cell range - $bool = (0x0800 & $options) >> 11; - $this->_phpSheet->getProtection()->setSort(!$bool); - - // bit: 12; mask 0x1000; auto filter - $bool = (0x1000 & $options) >> 12; - $this->_phpSheet->getProtection()->setAutoFilter(!$bool); - - // bit: 13; mask 0x2000; pivot tables - $bool = (0x2000 & $options) >> 13; - $this->_phpSheet->getProtection()->setPivotTables(!$bool); - - // bit: 14; mask 0x4000; select unlocked cells - $bool = (0x4000 & $options) >> 14; - $this->_phpSheet->getProtection()->setSelectUnlockedCells(!$bool); - - // offset: 21; size: 2; not used - } - - - /** - * Read RANGEPROTECTION record - * Reading of this record is based on Microsoft Office Excel 97-2000 Binary File Format Specification, - * where it is referred to as FEAT record - */ - private function _readRangeProtection() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // move stream pointer to next record - $this->_pos += 4 + $length; - - // local pointer in record data - $offset = 0; - - if (!$this->_readDataOnly) { - $offset += 12; - - // offset: 12; size: 2; shared feature type, 2 = enhanced protection, 4 = smart tag - $isf = self::_GetInt2d($recordData, 12); - if ($isf != 2) { - // we only read FEAT records of type 2 - return; - } - $offset += 2; - - $offset += 5; - - // offset: 19; size: 2; count of ref ranges this feature is on - $cref = self::_GetInt2d($recordData, 19); - $offset += 2; - - $offset += 6; - - // offset: 27; size: 8 * $cref; list of cell ranges (like in hyperlink record) - $cellRanges = array(); - for ($i = 0; $i < $cref; ++$i) { - try { - $cellRange = $this->_readBIFF8CellRangeAddressFixed(substr($recordData, 27 + 8 * $i, 8)); - } catch (PHPExcel_Exception $e) { - return; - } - $cellRanges[] = $cellRange; - $offset += 8; - } - - // offset: var; size: var; variable length of feature specific data - $rgbFeat = substr($recordData, $offset); - $offset += 4; - - // offset: var; size: 4; the encrypted password (only 16-bit although field is 32-bit) - $wPassword = self::_GetInt4d($recordData, $offset); - $offset += 4; - - // Apply range protection to sheet - if ($cellRanges) { - $this->_phpSheet->protectCells(implode(' ', $cellRanges), strtoupper(dechex($wPassword)), true); - } - } - } - - - /** - * Read IMDATA record - */ - private function _readImData() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - - // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); - $recordData = $splicedRecordData['recordData']; - - // UNDER CONSTRUCTION - - // offset: 0; size: 2; image format - $cf = self::_GetInt2d($recordData, 0); - - // offset: 2; size: 2; environment from which the file was written - $env = self::_GetInt2d($recordData, 2); - - // offset: 4; size: 4; length of the image data - $lcb = self::_GetInt4d($recordData, 4); - - // offset: 8; size: var; image data - $iData = substr($recordData, 8); - - switch ($cf) { - case 0x09: // Windows bitmap format - // BITMAPCOREINFO - // 1. BITMAPCOREHEADER - // offset: 0; size: 4; bcSize, Specifies the number of bytes required by the structure - $bcSize = self::_GetInt4d($iData, 0); - // var_dump($bcSize); - - // offset: 4; size: 2; bcWidth, specifies the width of the bitmap, in pixels - $bcWidth = self::_GetInt2d($iData, 4); - // var_dump($bcWidth); - - // offset: 6; size: 2; bcHeight, specifies the height of the bitmap, in pixels. - $bcHeight = self::_GetInt2d($iData, 6); - // var_dump($bcHeight); - $ih = imagecreatetruecolor($bcWidth, $bcHeight); - - // offset: 8; size: 2; bcPlanes, specifies the number of planes for the target device. This value must be 1 - - // offset: 10; size: 2; bcBitCount specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24 - $bcBitCount = self::_GetInt2d($iData, 10); - // var_dump($bcBitCount); - - $rgbString = substr($iData, 12); - $rgbTriples = array(); - while (strlen($rgbString) > 0) { - $rgbTriples[] = unpack('Cb/Cg/Cr', $rgbString); - $rgbString = substr($rgbString, 3); - } - $x = 0; - $y = 0; - foreach ($rgbTriples as $i => $rgbTriple) { - $color = imagecolorallocate($ih, $rgbTriple['r'], $rgbTriple['g'], $rgbTriple['b']); - imagesetpixel($ih, $x, $bcHeight - 1 - $y, $color); - $x = ($x + 1) % $bcWidth; - $y = $y + floor(($x + 1) / $bcWidth); - } - //imagepng($ih, 'image.png'); - - $drawing = new PHPExcel_Worksheet_Drawing(); - $drawing->setPath($filename); - $drawing->setWorksheet($this->_phpSheet); - break; - case 0x02: // Windows metafile or Macintosh PICT format - case 0x0e: // native format - default; - break; - } - - // _getSplicedRecordData() takes care of moving current position in data stream - } - - - /** - * Read a free CONTINUE record. Free CONTINUE record may be a camouflaged MSODRAWING record - * When MSODRAWING data on a sheet exceeds 8224 bytes, CONTINUE records are used instead. Undocumented. - * In this case, we must treat the CONTINUE record as a MSODRAWING record - */ - private function _readContinue() - { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - // check if we are reading drawing data - // this is in case a free CONTINUE record occurs in other circumstances we are unaware of - if ($this->_drawingData == '') { - // move stream pointer to next record - $this->_pos += 4 + $length; - - return; - } - - // check if record data is at least 4 bytes long, otherwise there is no chance this is MSODRAWING data - if ($length < 4) { - // move stream pointer to next record - $this->_pos += 4 + $length; - - return; - } - - // dirty check to see if CONTINUE record could be a camouflaged MSODRAWING record - // look inside CONTINUE record to see if it looks like a part of an Escher stream - // we know that Escher stream may be split at least at - // 0xF003 MsofbtSpgrContainer - // 0xF004 MsofbtSpContainer - // 0xF00D MsofbtClientTextbox - $validSplitPoints = array(0xF003, 0xF004, 0xF00D); // add identifiers if we find more - - $splitPoint = self::_GetInt2d($recordData, 2); - if (in_array($splitPoint, $validSplitPoints)) { - // get spliced record data (and move pointer to next record) - $splicedRecordData = $this->_getSplicedRecordData(); - $this->_drawingData .= $splicedRecordData['recordData']; - - return; - } - - // move stream pointer to next record - $this->_pos += 4 + $length; - } - - - /** - * Reads a record from current position in data stream and continues reading data as long as CONTINUE - * records are found. Splices the record data pieces and returns the combined string as if record data - * is in one piece. - * Moves to next current position in data stream to start of next record different from a CONtINUE record - * - * @return array - */ - private function _getSplicedRecordData() - { - $data = ''; - $spliceOffsets = array(); - - $i = 0; - $spliceOffsets[0] = 0; - - do { - ++$i; - - // offset: 0; size: 2; identifier - $identifier = self::_GetInt2d($this->_data, $this->_pos); - // offset: 2; size: 2; length - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $data .= $this->_readRecordData($this->_data, $this->_pos + 4, $length); - - $spliceOffsets[$i] = $spliceOffsets[$i - 1] + $length; - - $this->_pos += 4 + $length; - $nextIdentifier = self::_GetInt2d($this->_data, $this->_pos); - } while ($nextIdentifier == self::XLS_Type_CONTINUE); - - $splicedData = array( - 'recordData' => $data, - 'spliceOffsets' => $spliceOffsets, - ); - - return $splicedData; - - } - - - /** - * Convert formula structure into human readable Excel formula like 'A3+A5*5' - * - * @param string $formulaStructure The complete binary data for the formula - * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas - * @return string Human readable formula - */ - private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') - { - // offset: 0; size: 2; size of the following formula data - $sz = self::_GetInt2d($formulaStructure, 0); - - // offset: 2; size: sz - $formulaData = substr($formulaStructure, 2, $sz); - - // for debug: dump the formula data - //echo '<xmp>'; - //echo 'size: ' . $sz . "\n"; - //echo 'the entire formula data: '; - //Debug::dump($formulaData); - //echo "\n----\n"; - - // offset: 2 + sz; size: variable (optional) - if (strlen($formulaStructure) > 2 + $sz) { - $additionalData = substr($formulaStructure, 2 + $sz); - - // for debug: dump the additional data - //echo 'the entire additional data: '; - //Debug::dump($additionalData); - //echo "\n----\n"; - } else { - $additionalData = ''; - } - - return $this->_getFormulaFromData($formulaData, $additionalData, $baseCell); - } - - - /** - * Take formula data and additional data for formula and return human readable formula - * - * @param string $formulaData The binary data for the formula itself - * @param string $additionalData Additional binary data going with the formula - * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas - * @return string Human readable formula - */ - private function _getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1') - { - // start parsing the formula data - $tokens = array(); - - while (strlen($formulaData) > 0 and $token = $this->_getNextToken($formulaData, $baseCell)) { - $tokens[] = $token; - $formulaData = substr($formulaData, $token['size']); - - // for debug: dump the token - //var_dump($token); - } - - $formulaString = $this->_createFormulaFromTokens($tokens, $additionalData); - - return $formulaString; - } - - - /** - * Take array of tokens together with additional data for formula and return human readable formula - * - * @param array $tokens - * @param array $additionalData Additional binary data going with the formula - * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas - * @return string Human readable formula - */ - private function _createFormulaFromTokens($tokens, $additionalData) - { - // empty formula? - if (empty($tokens)) { - return ''; - } - - $formulaStrings = array(); - foreach ($tokens as $token) { - // initialize spaces - $space0 = isset($space0) ? $space0 : ''; // spaces before next token, not tParen - $space1 = isset($space1) ? $space1 : ''; // carriage returns before next token, not tParen - $space2 = isset($space2) ? $space2 : ''; // spaces before opening parenthesis - $space3 = isset($space3) ? $space3 : ''; // carriage returns before opening parenthesis - $space4 = isset($space4) ? $space4 : ''; // spaces before closing parenthesis - $space5 = isset($space5) ? $space5 : ''; // carriage returns before closing parenthesis - - switch ($token['name']) { - case 'tAdd': // addition - case 'tConcat': // addition - case 'tDiv': // division - case 'tEQ': // equality - case 'tGE': // greater than or equal - case 'tGT': // greater than - case 'tIsect': // intersection - case 'tLE': // less than or equal - case 'tList': // less than or equal - case 'tLT': // less than - case 'tMul': // multiplication - case 'tNE': // multiplication - case 'tPower': // power - case 'tRange': // range - case 'tSub': // subtraction - $op2 = array_pop($formulaStrings); - $op1 = array_pop($formulaStrings); - $formulaStrings[] = "$op1$space1$space0{$token['data']}$op2"; - unset($space0, $space1); - break; - case 'tUplus': // unary plus - case 'tUminus': // unary minus - $op = array_pop($formulaStrings); - $formulaStrings[] = "$space1$space0{$token['data']}$op"; - unset($space0, $space1); - break; - case 'tPercent': // percent sign - $op = array_pop($formulaStrings); - $formulaStrings[] = "$op$space1$space0{$token['data']}"; - unset($space0, $space1); - break; - case 'tAttrVolatile': // indicates volatile function - case 'tAttrIf': - case 'tAttrSkip': - case 'tAttrChoose': - // token is only important for Excel formula evaluator - // do nothing - break; - case 'tAttrSpace': // space / carriage return - // space will be used when next token arrives, do not alter formulaString stack - switch ($token['data']['spacetype']) { - case 'type0': - $space0 = str_repeat(' ', $token['data']['spacecount']); - break; - case 'type1': - $space1 = str_repeat("\n", $token['data']['spacecount']); - break; - case 'type2': - $space2 = str_repeat(' ', $token['data']['spacecount']); - break; - case 'type3': - $space3 = str_repeat("\n", $token['data']['spacecount']); - break; - case 'type4': - $space4 = str_repeat(' ', $token['data']['spacecount']); - break; - case 'type5': - $space5 = str_repeat("\n", $token['data']['spacecount']); - break; - } - break; - case 'tAttrSum': // SUM function with one parameter - $op = array_pop($formulaStrings); - $formulaStrings[] = "{$space1}{$space0}SUM($op)"; - unset($space0, $space1); - break; - case 'tFunc': // function with fixed number of arguments - case 'tFuncV': // function with variable number of arguments - if ($token['data']['function'] != '') { - // normal function - $ops = array(); // array of operators - for ($i = 0; $i < $token['data']['args']; ++$i) { - $ops[] = array_pop($formulaStrings); - } - $ops = array_reverse($ops); - $formulaStrings[] = "$space1$space0{$token['data']['function']}(" . implode(',', $ops) . ")"; - unset($space0, $space1); - } else { - // add-in function - $ops = array(); // array of operators - for ($i = 0; $i < $token['data']['args'] - 1; ++$i) { - $ops[] = array_pop($formulaStrings); - } - $ops = array_reverse($ops); - $function = array_pop($formulaStrings); - $formulaStrings[] = "$space1$space0$function(" . implode(',', $ops) . ")"; - unset($space0, $space1); - } - break; - case 'tParen': // parenthesis - $expression = array_pop($formulaStrings); - $formulaStrings[] = "$space3$space2($expression$space5$space4)"; - unset($space2, $space3, $space4, $space5); - break; - case 'tArray': // array constant - $constantArray = self::_readBIFF8ConstantArray($additionalData); - $formulaStrings[] = $space1 . $space0 . $constantArray['value']; - $additionalData = substr($additionalData, $constantArray['size']); // bite of chunk of additional data - unset($space0, $space1); - break; - case 'tMemArea': - // bite off chunk of additional data - $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData); - $additionalData = substr($additionalData, $cellRangeAddressList['size']); - $formulaStrings[] = "$space1$space0{$token['data']}"; - unset($space0, $space1); - break; - case 'tArea': // cell range address - case 'tBool': // boolean - case 'tErr': // error code - case 'tInt': // integer - case 'tMemErr': - case 'tMemFunc': - case 'tMissArg': - case 'tName': - case 'tNameX': - case 'tNum': // number - case 'tRef': // single cell reference - case 'tRef3d': // 3d cell reference - case 'tArea3d': // 3d cell range reference - case 'tRefN': - case 'tAreaN': - case 'tStr': // string - $formulaStrings[] = "$space1$space0{$token['data']}"; - unset($space0, $space1); - break; - } - } - $formulaString = $formulaStrings[0]; - - // for debug: dump the human readable formula - //echo '----' . "\n"; - //echo 'Formula: ' . $formulaString; - - return $formulaString; - } - - - /** - * Fetch next token from binary formula data - * - * @param string Formula data - * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas - * @return array - * @throws PHPExcel_Reader_Exception - */ - private function _getNextToken($formulaData, $baseCell = 'A1') - { - // offset: 0; size: 1; token id - $id = ord($formulaData[0]); // token id - $name = false; // initialize token name - - switch ($id) { - case 0x03: - $name = 'tAdd'; - $size = 1; - $data = '+'; - break; - case 0x04: - $name = 'tSub'; - $size = 1; - $data = '-'; - break; - case 0x05: - $name = 'tMul'; - $size = 1; - $data = '*'; - break; - case 0x06: - $name = 'tDiv'; - $size = 1; - $data = '/'; - break; - case 0x07: - $name = 'tPower'; - $size = 1; - $data = '^'; - break; - case 0x08: - $name = 'tConcat'; - $size = 1; - $data = '&'; - break; - case 0x09: - $name = 'tLT'; - $size = 1; - $data = '<'; - break; - case 0x0A: - $name = 'tLE'; - $size = 1; - $data = '<='; - break; - case 0x0B: - $name = 'tEQ'; - $size = 1; - $data = '='; - break; - case 0x0C: - $name = 'tGE'; - $size = 1; - $data = '>='; - break; - case 0x0D: - $name = 'tGT'; - $size = 1; - $data = '>'; - break; - case 0x0E: - $name = 'tNE'; - $size = 1; - $data = '<>'; - break; - case 0x0F: - $name = 'tIsect'; - $size = 1; - $data = ' '; - break; - case 0x10: - $name = 'tList'; - $size = 1; - $data = ','; - break; - case 0x11: - $name = 'tRange'; - $size = 1; - $data = ':'; - break; - case 0x12: - $name = 'tUplus'; - $size = 1; - $data = '+'; - break; - case 0x13: - $name = 'tUminus'; - $size = 1; - $data = '-'; - break; - case 0x14: - $name = 'tPercent'; - $size = 1; - $data = '%'; - break; - case 0x15: // parenthesis - $name = 'tParen'; - $size = 1; - $data = null; - break; - case 0x16: // missing argument - $name = 'tMissArg'; - $size = 1; - $data = ''; - break; - case 0x17: // string - $name = 'tStr'; - // offset: 1; size: var; Unicode string, 8-bit string length - $string = self::_readUnicodeStringShort(substr($formulaData, 1)); - $size = 1 + $string['size']; - $data = self::_UTF8toExcelDoubleQuoted($string['value']); - break; - case 0x19: // Special attribute - // offset: 1; size: 1; attribute type flags: - switch (ord($formulaData[1])) { - case 0x01: - $name = 'tAttrVolatile'; - $size = 4; - $data = null; - break; - case 0x02: - $name = 'tAttrIf'; - $size = 4; - $data = null; - break; - case 0x04: - $name = 'tAttrChoose'; - // offset: 2; size: 2; number of choices in the CHOOSE function ($nc, number of parameters decreased by 1) - $nc = self::_GetInt2d($formulaData, 2); - // offset: 4; size: 2 * $nc - // offset: 4 + 2 * $nc; size: 2 - $size = 2 * $nc + 6; - $data = null; - break; - case 0x08: - $name = 'tAttrSkip'; - $size = 4; - $data = null; - break; - case 0x10: - $name = 'tAttrSum'; - $size = 4; - $data = null; - break; - case 0x40: - case 0x41: - $name = 'tAttrSpace'; - $size = 4; - // offset: 2; size: 2; space type and position - switch (ord($formulaData[2])) { - case 0x00: - $spacetype = 'type0'; - break; - case 0x01: - $spacetype = 'type1'; - break; - case 0x02: - $spacetype = 'type2'; - break; - case 0x03: - $spacetype = 'type3'; - break; - case 0x04: - $spacetype = 'type4'; - break; - case 0x05: - $spacetype = 'type5'; - break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized space type in tAttrSpace token'); - break; - } - // offset: 3; size: 1; number of inserted spaces/carriage returns - $spacecount = ord($formulaData[3]); - - $data = array('spacetype' => $spacetype, 'spacecount' => $spacecount); - break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized attribute flag in tAttr token'); - break; - } - break; - case 0x1C: // error code - // offset: 1; size: 1; error code - $name = 'tErr'; - $size = 2; - $data = self::_mapErrorCode(ord($formulaData[1])); - break; - case 0x1D: // boolean - // offset: 1; size: 1; 0 = false, 1 = true; - $name = 'tBool'; - $size = 2; - $data = ord($formulaData[1]) ? 'TRUE' : 'FALSE'; - break; - case 0x1E: // integer - // offset: 1; size: 2; unsigned 16-bit integer - $name = 'tInt'; - $size = 3; - $data = self::_GetInt2d($formulaData, 1); - break; - case 0x1F: // number - // offset: 1; size: 8; - $name = 'tNum'; - $size = 9; - $data = self::_extractNumber(substr($formulaData, 1)); - $data = str_replace(',', '.', (string)$data); // in case non-English locale - break; - case 0x20: // array constant - case 0x40: - case 0x60: - // offset: 1; size: 7; not used - $name = 'tArray'; - $size = 8; - $data = null; - break; - case 0x21: // function with fixed number of arguments - case 0x41: - case 0x61: - $name = 'tFunc'; - $size = 3; - // offset: 1; size: 2; index to built-in sheet function - switch (self::_GetInt2d($formulaData, 1)) { - case 2: - $function = 'ISNA'; - $args = 1; - break; - case 3: - $function = 'ISERROR'; - $args = 1; - break; - case 10: - $function = 'NA'; - $args = 0; - break; - case 15: - $function = 'SIN'; - $args = 1; - break; - case 16: - $function = 'COS'; - $args = 1; - break; - case 17: - $function = 'TAN'; - $args = 1; - break; - case 18: - $function = 'ATAN'; - $args = 1; - break; - case 19: - $function = 'PI'; - $args = 0; - break; - case 20: - $function = 'SQRT'; - $args = 1; - break; - case 21: - $function = 'EXP'; - $args = 1; - break; - case 22: - $function = 'LN'; - $args = 1; - break; - case 23: - $function = 'LOG10'; - $args = 1; - break; - case 24: - $function = 'ABS'; - $args = 1; - break; - case 25: - $function = 'INT'; - $args = 1; - break; - case 26: - $function = 'SIGN'; - $args = 1; - break; - case 27: - $function = 'ROUND'; - $args = 2; - break; - case 30: - $function = 'REPT'; - $args = 2; - break; - case 31: - $function = 'MID'; - $args = 3; - break; - case 32: - $function = 'LEN'; - $args = 1; - break; - case 33: - $function = 'VALUE'; - $args = 1; - break; - case 34: - $function = 'TRUE'; - $args = 0; - break; - case 35: - $function = 'FALSE'; - $args = 0; - break; - case 38: - $function = 'NOT'; - $args = 1; - break; - case 39: - $function = 'MOD'; - $args = 2; - break; - case 40: - $function = 'DCOUNT'; - $args = 3; - break; - case 41: - $function = 'DSUM'; - $args = 3; - break; - case 42: - $function = 'DAVERAGE'; - $args = 3; - break; - case 43: - $function = 'DMIN'; - $args = 3; - break; - case 44: - $function = 'DMAX'; - $args = 3; - break; - case 45: - $function = 'DSTDEV'; - $args = 3; - break; - case 48: - $function = 'TEXT'; - $args = 2; - break; - case 61: - $function = 'MIRR'; - $args = 3; - break; - case 63: - $function = 'RAND'; - $args = 0; - break; - case 65: - $function = 'DATE'; - $args = 3; - break; - case 66: - $function = 'TIME'; - $args = 3; - break; - case 67: - $function = 'DAY'; - $args = 1; - break; - case 68: - $function = 'MONTH'; - $args = 1; - break; - case 69: - $function = 'YEAR'; - $args = 1; - break; - case 71: - $function = 'HOUR'; - $args = 1; - break; - case 72: - $function = 'MINUTE'; - $args = 1; - break; - case 73: - $function = 'SECOND'; - $args = 1; - break; - case 74: - $function = 'NOW'; - $args = 0; - break; - case 75: - $function = 'AREAS'; - $args = 1; - break; - case 76: - $function = 'ROWS'; - $args = 1; - break; - case 77: - $function = 'COLUMNS'; - $args = 1; - break; - case 83: - $function = 'TRANSPOSE'; - $args = 1; - break; - case 86: - $function = 'TYPE'; - $args = 1; - break; - case 97: - $function = 'ATAN2'; - $args = 2; - break; - case 98: - $function = 'ASIN'; - $args = 1; - break; - case 99: - $function = 'ACOS'; - $args = 1; - break; - case 105: - $function = 'ISREF'; - $args = 1; - break; - case 111: - $function = 'CHAR'; - $args = 1; - break; - case 112: - $function = 'LOWER'; - $args = 1; - break; - case 113: - $function = 'UPPER'; - $args = 1; - break; - case 114: - $function = 'PROPER'; - $args = 1; - break; - case 117: - $function = 'EXACT'; - $args = 2; - break; - case 118: - $function = 'TRIM'; - $args = 1; - break; - case 119: - $function = 'REPLACE'; - $args = 4; - break; - case 121: - $function = 'CODE'; - $args = 1; - break; - case 126: - $function = 'ISERR'; - $args = 1; - break; - case 127: - $function = 'ISTEXT'; - $args = 1; - break; - case 128: - $function = 'ISNUMBER'; - $args = 1; - break; - case 129: - $function = 'ISBLANK'; - $args = 1; - break; - case 130: - $function = 'T'; - $args = 1; - break; - case 131: - $function = 'N'; - $args = 1; - break; - case 140: - $function = 'DATEVALUE'; - $args = 1; - break; - case 141: - $function = 'TIMEVALUE'; - $args = 1; - break; - case 142: - $function = 'SLN'; - $args = 3; - break; - case 143: - $function = 'SYD'; - $args = 4; - break; - case 162: - $function = 'CLEAN'; - $args = 1; - break; - case 163: - $function = 'MDETERM'; - $args = 1; - break; - case 164: - $function = 'MINVERSE'; - $args = 1; - break; - case 165: - $function = 'MMULT'; - $args = 2; - break; - case 184: - $function = 'FACT'; - $args = 1; - break; - case 189: - $function = 'DPRODUCT'; - $args = 3; - break; - case 190: - $function = 'ISNONTEXT'; - $args = 1; - break; - case 195: - $function = 'DSTDEVP'; - $args = 3; - break; - case 196: - $function = 'DVARP'; - $args = 3; - break; - case 198: - $function = 'ISLOGICAL'; - $args = 1; - break; - case 199: - $function = 'DCOUNTA'; - $args = 3; - break; - case 207: - $function = 'REPLACEB'; - $args = 4; - break; - case 210: - $function = 'MIDB'; - $args = 3; - break; - case 211: - $function = 'LENB'; - $args = 1; - break; - case 212: - $function = 'ROUNDUP'; - $args = 2; - break; - case 213: - $function = 'ROUNDDOWN'; - $args = 2; - break; - case 214: - $function = 'ASC'; - $args = 1; - break; - case 215: - $function = 'DBCS'; - $args = 1; - break; - case 221: - $function = 'TODAY'; - $args = 0; - break; - case 229: - $function = 'SINH'; - $args = 1; - break; - case 230: - $function = 'COSH'; - $args = 1; - break; - case 231: - $function = 'TANH'; - $args = 1; - break; - case 232: - $function = 'ASINH'; - $args = 1; - break; - case 233: - $function = 'ACOSH'; - $args = 1; - break; - case 234: - $function = 'ATANH'; - $args = 1; - break; - case 235: - $function = 'DGET'; - $args = 3; - break; - case 244: - $function = 'INFO'; - $args = 1; - break; - case 252: - $function = 'FREQUENCY'; - $args = 2; - break; - case 261: - $function = 'ERROR.TYPE'; - $args = 1; - break; - case 271: - $function = 'GAMMALN'; - $args = 1; - break; - case 273: - $function = 'BINOMDIST'; - $args = 4; - break; - case 274: - $function = 'CHIDIST'; - $args = 2; - break; - case 275: - $function = 'CHIINV'; - $args = 2; - break; - case 276: - $function = 'COMBIN'; - $args = 2; - break; - case 277: - $function = 'CONFIDENCE'; - $args = 3; - break; - case 278: - $function = 'CRITBINOM'; - $args = 3; - break; - case 279: - $function = 'EVEN'; - $args = 1; - break; - case 280: - $function = 'EXPONDIST'; - $args = 3; - break; - case 281: - $function = 'FDIST'; - $args = 3; - break; - case 282: - $function = 'FINV'; - $args = 3; - break; - case 283: - $function = 'FISHER'; - $args = 1; - break; - case 284: - $function = 'FISHERINV'; - $args = 1; - break; - case 285: - $function = 'FLOOR'; - $args = 2; - break; - case 286: - $function = 'GAMMADIST'; - $args = 4; - break; - case 287: - $function = 'GAMMAINV'; - $args = 3; - break; - case 288: - $function = 'CEILING'; - $args = 2; - break; - case 289: - $function = 'HYPGEOMDIST'; - $args = 4; - break; - case 290: - $function = 'LOGNORMDIST'; - $args = 3; - break; - case 291: - $function = 'LOGINV'; - $args = 3; - break; - case 292: - $function = 'NEGBINOMDIST'; - $args = 3; - break; - case 293: - $function = 'NORMDIST'; - $args = 4; - break; - case 294: - $function = 'NORMSDIST'; - $args = 1; - break; - case 295: - $function = 'NORMINV'; - $args = 3; - break; - case 296: - $function = 'NORMSINV'; - $args = 1; - break; - case 297: - $function = 'STANDARDIZE'; - $args = 3; - break; - case 298: - $function = 'ODD'; - $args = 1; - break; - case 299: - $function = 'PERMUT'; - $args = 2; - break; - case 300: - $function = 'POISSON'; - $args = 3; - break; - case 301: - $function = 'TDIST'; - $args = 3; - break; - case 302: - $function = 'WEIBULL'; - $args = 4; - break; - case 303: - $function = 'SUMXMY2'; - $args = 2; - break; - case 304: - $function = 'SUMX2MY2'; - $args = 2; - break; - case 305: - $function = 'SUMX2PY2'; - $args = 2; - break; - case 306: - $function = 'CHITEST'; - $args = 2; - break; - case 307: - $function = 'CORREL'; - $args = 2; - break; - case 308: - $function = 'COVAR'; - $args = 2; - break; - case 309: - $function = 'FORECAST'; - $args = 3; - break; - case 310: - $function = 'FTEST'; - $args = 2; - break; - case 311: - $function = 'INTERCEPT'; - $args = 2; - break; - case 312: - $function = 'PEARSON'; - $args = 2; - break; - case 313: - $function = 'RSQ'; - $args = 2; - break; - case 314: - $function = 'STEYX'; - $args = 2; - break; - case 315: - $function = 'SLOPE'; - $args = 2; - break; - case 316: - $function = 'TTEST'; - $args = 4; - break; - case 325: - $function = 'LARGE'; - $args = 2; - break; - case 326: - $function = 'SMALL'; - $args = 2; - break; - case 327: - $function = 'QUARTILE'; - $args = 2; - break; - case 328: - $function = 'PERCENTILE'; - $args = 2; - break; - case 331: - $function = 'TRIMMEAN'; - $args = 2; - break; - case 332: - $function = 'TINV'; - $args = 2; - break; - case 337: - $function = 'POWER'; - $args = 2; - break; - case 342: - $function = 'RADIANS'; - $args = 1; - break; - case 343: - $function = 'DEGREES'; - $args = 1; - break; - case 346: - $function = 'COUNTIF'; - $args = 2; - break; - case 347: - $function = 'COUNTBLANK'; - $args = 1; - break; - case 350: - $function = 'ISPMT'; - $args = 4; - break; - case 351: - $function = 'DATEDIF'; - $args = 3; - break; - case 352: - $function = 'DATESTRING'; - $args = 1; - break; - case 353: - $function = 'NUMBERSTRING'; - $args = 2; - break; - case 360: - $function = 'PHONETIC'; - $args = 1; - break; - case 368: - $function = 'BAHTTEXT'; - $args = 1; - break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); - break; - } - $data = array('function' => $function, 'args' => $args); - break; - case 0x22: // function with variable number of arguments - case 0x42: - case 0x62: - $name = 'tFuncV'; - $size = 4; - // offset: 1; size: 1; number of arguments - $args = ord($formulaData[1]); - // offset: 2: size: 2; index to built-in sheet function - $index = self::_GetInt2d($formulaData, 2); - switch ($index) { - case 0: - $function = 'COUNT'; - break; - case 1: - $function = 'IF'; - break; - case 4: - $function = 'SUM'; - break; - case 5: - $function = 'AVERAGE'; - break; - case 6: - $function = 'MIN'; - break; - case 7: - $function = 'MAX'; - break; - case 8: - $function = 'ROW'; - break; - case 9: - $function = 'COLUMN'; - break; - case 11: - $function = 'NPV'; - break; - case 12: - $function = 'STDEV'; - break; - case 13: - $function = 'DOLLAR'; - break; - case 14: - $function = 'FIXED'; - break; - case 28: - $function = 'LOOKUP'; - break; - case 29: - $function = 'INDEX'; - break; - case 36: - $function = 'AND'; - break; - case 37: - $function = 'OR'; - break; - case 46: - $function = 'VAR'; - break; - case 49: - $function = 'LINEST'; - break; - case 50: - $function = 'TREND'; - break; - case 51: - $function = 'LOGEST'; - break; - case 52: - $function = 'GROWTH'; - break; - case 56: - $function = 'PV'; - break; - case 57: - $function = 'FV'; - break; - case 58: - $function = 'NPER'; - break; - case 59: - $function = 'PMT'; - break; - case 60: - $function = 'RATE'; - break; - case 62: - $function = 'IRR'; - break; - case 64: - $function = 'MATCH'; - break; - case 70: - $function = 'WEEKDAY'; - break; - case 78: - $function = 'OFFSET'; - break; - case 82: - $function = 'SEARCH'; - break; - case 100: - $function = 'CHOOSE'; - break; - case 101: - $function = 'HLOOKUP'; - break; - case 102: - $function = 'VLOOKUP'; - break; - case 109: - $function = 'LOG'; - break; - case 115: - $function = 'LEFT'; - break; - case 116: - $function = 'RIGHT'; - break; - case 120: - $function = 'SUBSTITUTE'; - break; - case 124: - $function = 'FIND'; - break; - case 125: - $function = 'CELL'; - break; - case 144: - $function = 'DDB'; - break; - case 148: - $function = 'INDIRECT'; - break; - case 167: - $function = 'IPMT'; - break; - case 168: - $function = 'PPMT'; - break; - case 169: - $function = 'COUNTA'; - break; - case 183: - $function = 'PRODUCT'; - break; - case 193: - $function = 'STDEVP'; - break; - case 194: - $function = 'VARP'; - break; - case 197: - $function = 'TRUNC'; - break; - case 204: - $function = 'USDOLLAR'; - break; - case 205: - $function = 'FINDB'; - break; - case 206: - $function = 'SEARCHB'; - break; - case 208: - $function = 'LEFTB'; - break; - case 209: - $function = 'RIGHTB'; - break; - case 216: - $function = 'RANK'; - break; - case 219: - $function = 'ADDRESS'; - break; - case 220: - $function = 'DAYS360'; - break; - case 222: - $function = 'VDB'; - break; - case 227: - $function = 'MEDIAN'; - break; - case 228: - $function = 'SUMPRODUCT'; - break; - case 247: - $function = 'DB'; - break; - case 255: - $function = ''; - break; - case 269: - $function = 'AVEDEV'; - break; - case 270: - $function = 'BETADIST'; - break; - case 272: - $function = 'BETAINV'; - break; - case 317: - $function = 'PROB'; - break; - case 318: - $function = 'DEVSQ'; - break; - case 319: - $function = 'GEOMEAN'; - break; - case 320: - $function = 'HARMEAN'; - break; - case 321: - $function = 'SUMSQ'; - break; - case 322: - $function = 'KURT'; - break; - case 323: - $function = 'SKEW'; - break; - case 324: - $function = 'ZTEST'; - break; - case 329: - $function = 'PERCENTRANK'; - break; - case 330: - $function = 'MODE'; - break; - case 336: - $function = 'CONCATENATE'; - break; - case 344: - $function = 'SUBTOTAL'; - break; - case 345: - $function = 'SUMIF'; - break; - case 354: - $function = 'ROMAN'; - break; - case 358: - $function = 'GETPIVOTDATA'; - break; - case 359: - $function = 'HYPERLINK'; - break; - case 361: - $function = 'AVERAGEA'; - break; - case 362: - $function = 'MAXA'; - break; - case 363: - $function = 'MINA'; - break; - case 364: - $function = 'STDEVPA'; - break; - case 365: - $function = 'VARPA'; - break; - case 366: - $function = 'STDEVA'; - break; - case 367: - $function = 'VARA'; - break; - default: - throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); - break; - } - $data = array('function' => $function, 'args' => $args); - break; - case 0x23: // index to defined name - case 0x43: - case 0x63: - $name = 'tName'; - $size = 5; - // offset: 1; size: 2; one-based index to definedname record - $definedNameIndex = self::_GetInt2d($formulaData, 1) - 1; - // offset: 2; size: 2; not used - $data = $this->_definedname[$definedNameIndex]['name']; - break; - case 0x24: // single cell reference e.g. A5 - case 0x44: - case 0x64: - $name = 'tRef'; - $size = 5; - $data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4)); - break; - case 0x25: // cell range reference to cells in the same sheet (2d) - case 0x45: - case 0x65: - $name = 'tArea'; - $size = 9; - $data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8)); - break; - case 0x26: // Constant reference sub-expression - case 0x46: - case 0x66: - $name = 'tMemArea'; - // offset: 1; size: 4; not used - // offset: 5; size: 2; size of the following subexpression - $subSize = self::_GetInt2d($formulaData, 5); - $size = 7 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); - break; - case 0x27: // Deleted constant reference sub-expression - case 0x47: - case 0x67: - $name = 'tMemErr'; - // offset: 1; size: 4; not used - // offset: 5; size: 2; size of the following subexpression - $subSize = self::_GetInt2d($formulaData, 5); - $size = 7 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); - break; - case 0x29: // Variable reference sub-expression - case 0x49: - case 0x69: - $name = 'tMemFunc'; - // offset: 1; size: 2; size of the following sub-expression - $subSize = self::_GetInt2d($formulaData, 1); - $size = 3 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize)); - break; - case 0x2C: // Relative 2d cell reference reference, used in shared formulas and some other places - case 0x4C: - case 0x6C: - $name = 'tRefN'; - $size = 5; - $data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell); - break; - case 0x2D: // Relative 2d range reference - case 0x4D: - case 0x6D: - $name = 'tAreaN'; - $size = 9; - $data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell); - break; - case 0x39: // External name - case 0x59: - case 0x79: - $name = 'tNameX'; - $size = 7; - // offset: 1; size: 2; index to REF entry in EXTERNSHEET record - // offset: 3; size: 2; one-based index to DEFINEDNAME or EXTERNNAME record - $index = self::_GetInt2d($formulaData, 3); - // assume index is to EXTERNNAME record - $data = $this->_externalNames[$index - 1]['name']; - // offset: 5; size: 2; not used - break; - case 0x3A: // 3d reference to cell - case 0x5A: - case 0x7A: - $name = 'tRef3d'; - $size = 7; - - try { - // offset: 1; size: 2; index to REF entry - $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); - // offset: 3; size: 4; cell address - $cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4)); - - $data = "$sheetRange!$cellAddress"; - } catch (PHPExcel_Exception $e) { - // deleted sheet reference - $data = '#REF!'; - } - break; - case 0x3B: // 3d reference to cell range - case 0x5B: - case 0x7B: - $name = 'tArea3d'; - $size = 11; - - try { - // offset: 1; size: 2; index to REF entry - $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); - // offset: 3; size: 8; cell address - $cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8)); - - $data = "$sheetRange!$cellRangeAddress"; - } catch (PHPExcel_Exception $e) { - // deleted sheet reference - $data = '#REF!'; - } - break; - // Unknown cases // don't know how to deal with - default: - throw new PHPExcel_Reader_Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula'); - break; - } - - return array( - 'id' => $id, - 'name' => $name, - 'size' => $size, - 'data' => $data, - ); - } - - - /** - * Reads a cell address in BIFF8 e.g. 'A2' or '$A$2' - * section 3.3.4 - * - * @param string $cellAddressStructure - * @return string - */ - private function _readBIFF8CellAddress($cellAddressStructure) - { - // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) - $row = self::_GetInt2d($cellAddressStructure, 0) + 1; - - // offset: 2; size: 2; index to column or column offset + relative flags - // bit: 7-0; mask 0x00FF; column index - $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2)); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { - $column = '$' . $column; - } - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { - $row = '$' . $row; - } - - return $column . $row; - } - - - /** - * Reads a cell address in BIFF8 for shared formulas. Uses positive and negative values for row and column - * to indicate offsets from a base cell - * section 3.3.4 - * - * @param string $cellAddressStructure - * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas - * @return string - */ - private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') - { - list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); - $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; - - // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) - $rowIndex = self::_GetInt2d($cellAddressStructure, 0); - $row = self::_GetInt2d($cellAddressStructure, 0) + 1; - - // offset: 2; size: 2; index to column or column offset + relative flags - // bit: 7-0; mask 0x00FF; column index - $colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { - $column = PHPExcel_Cell::stringFromColumnIndex($colIndex); - $column = '$' . $column; - } else { - $colIndex = ($colIndex <= 127) ? $colIndex : $colIndex - 256; - $column = PHPExcel_Cell::stringFromColumnIndex($baseCol + $colIndex); - } - - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { - $row = '$' . $row; - } else { - $rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536; - $row = $baseRow + $rowIndex; - } - - return $column . $row; - } - - - /** - * Reads a cell range address in BIFF5 e.g. 'A2:B6' or 'A1' - * always fixed range - * section 2.5.14 - * - * @param string $subData - * @return string - * @throws PHPExcel_Reader_Exception - */ - private function _readBIFF5CellRangeAddressFixed($subData) - { - // offset: 0; size: 2; index to first row - $fr = self::_GetInt2d($subData, 0) + 1; - - // offset: 2; size: 2; index to last row - $lr = self::_GetInt2d($subData, 2) + 1; - - // offset: 4; size: 1; index to first column - $fc = ord($subData{4}); - - // offset: 5; size: 1; index to last column - $lc = ord($subData{5}); - - // check values - if ($fr > $lr || $fc > $lc) { - throw new PHPExcel_Reader_Exception('Not a cell range address'); - } - - // column index to letter - $fc = PHPExcel_Cell::stringFromColumnIndex($fc); - $lc = PHPExcel_Cell::stringFromColumnIndex($lc); - - if ($fr == $lr and $fc == $lc) { - return "$fc$fr"; - } - return "$fc$fr:$lc$lr"; - } - - - /** - * Reads a cell range address in BIFF8 e.g. 'A2:B6' or 'A1' - * always fixed range - * section 2.5.14 - * - * @param string $subData - * @return string - * @throws PHPExcel_Reader_Exception - */ - private function _readBIFF8CellRangeAddressFixed($subData) - { - // offset: 0; size: 2; index to first row - $fr = self::_GetInt2d($subData, 0) + 1; - - // offset: 2; size: 2; index to last row - $lr = self::_GetInt2d($subData, 2) + 1; - - // offset: 4; size: 2; index to first column - $fc = self::_GetInt2d($subData, 4); - - // offset: 6; size: 2; index to last column - $lc = self::_GetInt2d($subData, 6); - - // check values - if ($fr > $lr || $fc > $lc) { - throw new PHPExcel_Reader_Exception('Not a cell range address'); - } - - // column index to letter - $fc = PHPExcel_Cell::stringFromColumnIndex($fc); - $lc = PHPExcel_Cell::stringFromColumnIndex($lc); - - if ($fr == $lr and $fc == $lc) { - return "$fc$fr"; - } - return "$fc$fr:$lc$lr"; - } - - - /** - * Reads a cell range address in BIFF8 e.g. 'A2:B6' or '$A$2:$B$6' - * there are flags indicating whether column/row index is relative - * section 3.3.4 - * - * @param string $subData - * @return string - */ - private function _readBIFF8CellRangeAddress($subData) - { - // todo: if cell range is just a single cell, should this funciton - // not just return e.g. 'A1' and not 'A1:A1' ? - - // offset: 0; size: 2; index to first row (0... 65535) (or offset (-32768... 32767)) - $fr = self::_GetInt2d($subData, 0) + 1; - - // offset: 2; size: 2; index to last row (0... 65535) (or offset (-32768... 32767)) - $lr = self::_GetInt2d($subData, 2) + 1; - - // offset: 4; size: 2; index to first column or column offset + relative flags - - // bit: 7-0; mask 0x00FF; column index - $fc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 4)); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 4))) { - $fc = '$' . $fc; - } - - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 4))) { - $fr = '$' . $fr; - } - - // offset: 6; size: 2; index to last column or column offset + relative flags - - // bit: 7-0; mask 0x00FF; column index - $lc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 6)); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 6))) { - $lc = '$' . $lc; - } - - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 6))) { - $lr = '$' . $lr; - } - - return "$fc$fr:$lc$lr"; - } - - - /** - * Reads a cell range address in BIFF8 for shared formulas. Uses positive and negative values for row and column - * to indicate offsets from a base cell - * section 3.3.4 - * - * @param string $subData - * @param string $baseCell Base cell - * @return string Cell range address - */ - private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') - { - list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); - $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; - - // TODO: if cell range is just a single cell, should this funciton - // not just return e.g. 'A1' and not 'A1:A1' ? - - // offset: 0; size: 2; first row - $frIndex = self::_GetInt2d($subData, 0); // adjust below - - // offset: 2; size: 2; relative index to first row (0... 65535) should be treated as offset (-32768... 32767) - $lrIndex = self::_GetInt2d($subData, 2); // adjust below - - // offset: 4; size: 2; first column with relative/absolute flags - - // bit: 7-0; mask 0x00FF; column index - $fcIndex = 0x00FF & self::_GetInt2d($subData, 4); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 4))) { - // absolute column index - $fc = PHPExcel_Cell::stringFromColumnIndex($fcIndex); - $fc = '$' . $fc; - } else { - // column offset - $fcIndex = ($fcIndex <= 127) ? $fcIndex : $fcIndex - 256; - $fc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $fcIndex); - } - - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 4))) { - // absolute row index - $fr = $frIndex + 1; - $fr = '$' . $fr; - } else { - // row offset - $frIndex = ($frIndex <= 32767) ? $frIndex : $frIndex - 65536; - $fr = $baseRow + $frIndex; - } - - // offset: 6; size: 2; last column with relative/absolute flags - - // bit: 7-0; mask 0x00FF; column index - $lcIndex = 0x00FF & self::_GetInt2d($subData, 6); - $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; - $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); - - // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 6))) { - // absolute column index - $lc = PHPExcel_Cell::stringFromColumnIndex($lcIndex); - $lc = '$' . $lc; - } else { - // column offset - $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; - $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); - } - - // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 6))) { - // absolute row index - $lr = $lrIndex + 1; - $lr = '$' . $lr; - } else { - // row offset - $lrIndex = ($lrIndex <= 32767) ? $lrIndex : $lrIndex - 65536; - $lr = $baseRow + $lrIndex; - } - - return "$fc$fr:$lc$lr"; - } - - - /** - * Read BIFF8 cell range address list - * section 2.5.15 - * - * @param string $subData - * @return array - */ - private function _readBIFF8CellRangeAddressList($subData) - { - $cellRangeAddresses = array(); - - // offset: 0; size: 2; number of the following cell range addresses - $nm = self::_GetInt2d($subData, 0); - - $offset = 2; - // offset: 2; size: 8 * $nm; list of $nm (fixed) cell range addresses - for ($i = 0; $i < $nm; ++$i) { - $cellRangeAddresses[] = $this->_readBIFF8CellRangeAddressFixed(substr($subData, $offset, 8)); - $offset += 8; - } - - return array( - 'size' => 2 + 8 * $nm, - 'cellRangeAddresses' => $cellRangeAddresses, - ); - } - - - /** - * Read BIFF5 cell range address list - * section 2.5.15 - * - * @param string $subData - * @return array - */ - private function _readBIFF5CellRangeAddressList($subData) - { - $cellRangeAddresses = array(); - - // offset: 0; size: 2; number of the following cell range addresses - $nm = self::_GetInt2d($subData, 0); - - $offset = 2; - // offset: 2; size: 6 * $nm; list of $nm (fixed) cell range addresses - for ($i = 0; $i < $nm; ++$i) { - $cellRangeAddresses[] = $this->_readBIFF5CellRangeAddressFixed(substr($subData, $offset, 6)); - $offset += 6; - } - - return array( - 'size' => 2 + 6 * $nm, - 'cellRangeAddresses' => $cellRangeAddresses, - ); - } - - - /** - * Get a sheet range like Sheet1:Sheet3 from REF index - * Note: If there is only one sheet in the range, one gets e.g Sheet1 - * It can also happen that the REF structure uses the -1 (FFFF) code to indicate deleted sheets, - * in which case an PHPExcel_Reader_Exception is thrown - * - * @param int $index - * @return string|false - * @throws PHPExcel_Reader_Exception - */ - private function _readSheetRangeByRefIndex($index) - { - if (isset($this->_ref[$index])) { - $type = $this->_externalBooks[$this->_ref[$index]['externalBookIndex']]['type']; - - switch ($type) { - case 'internal': - // check if we have a deleted 3d reference - if ($this->_ref[$index]['firstSheetIndex'] == 0xFFFF or $this->_ref[$index]['lastSheetIndex'] == 0xFFFF) { - throw new PHPExcel_Reader_Exception('Deleted sheet reference'); - } - - // we have normal sheet range (collapsed or uncollapsed) - $firstSheetName = $this->_sheets[$this->_ref[$index]['firstSheetIndex']]['name']; - $lastSheetName = $this->_sheets[$this->_ref[$index]['lastSheetIndex']]['name']; - - if ($firstSheetName == $lastSheetName) { - // collapsed sheet range - $sheetRange = $firstSheetName; - } else { - $sheetRange = "$firstSheetName:$lastSheetName"; - } - - // escape the single-quotes - $sheetRange = str_replace("'", "''", $sheetRange); - - // if there are special characters, we need to enclose the range in single-quotes - // todo: check if we have identified the whole set of special characters - // it seems that the following characters are not accepted for sheet names - // and we may assume that they are not present: []*/:\? - if (preg_match("/[ !\"@#£$%&{()}<>=+'|^,;-]/", $sheetRange)) { - $sheetRange = "'$sheetRange'"; - } - - return $sheetRange; - break; - default: - // TODO: external sheet support - throw new PHPExcel_Reader_Exception('Excel5 reader only supports internal sheets in fomulas'); - break; - } - } - return false; - } - - - /** - * read BIFF8 constant value array from array data - * returns e.g. array('value' => '{1,2;3,4}', 'size' => 40} - * section 2.5.8 - * - * @param string $arrayData - * @return array - */ - private static function _readBIFF8ConstantArray($arrayData) - { - // offset: 0; size: 1; number of columns decreased by 1 - $nc = ord($arrayData[0]); - - // offset: 1; size: 2; number of rows decreased by 1 - $nr = self::_GetInt2d($arrayData, 1); - $size = 3; // initialize - $arrayData = substr($arrayData, 3); - - // offset: 3; size: var; list of ($nc + 1) * ($nr + 1) constant values - $matrixChunks = array(); - for ($r = 1; $r <= $nr + 1; ++$r) { - $items = array(); - for ($c = 1; $c <= $nc + 1; ++$c) { - $constant = self::_readBIFF8Constant($arrayData); - $items[] = $constant['value']; - $arrayData = substr($arrayData, $constant['size']); - $size += $constant['size']; - } - $matrixChunks[] = implode(',', $items); // looks like e.g. '1,"hello"' - } - $matrix = '{' . implode(';', $matrixChunks) . '}'; - - return array( - 'value' => $matrix, - 'size' => $size, - ); - } - - - /** - * read BIFF8 constant value which may be 'Empty Value', 'Number', 'String Value', 'Boolean Value', 'Error Value' - * section 2.5.7 - * returns e.g. array('value' => '5', 'size' => 9) - * - * @param string $valueData - * @return array - */ - private static function _readBIFF8Constant($valueData) - { - // offset: 0; size: 1; identifier for type of constant - $identifier = ord($valueData[0]); - - switch ($identifier) { - case 0x00: // empty constant (what is this?) - $value = ''; - $size = 9; - break; - case 0x01: // number - // offset: 1; size: 8; IEEE 754 floating-point value - $value = self::_extractNumber(substr($valueData, 1, 8)); - $size = 9; - break; - case 0x02: // string value - // offset: 1; size: var; Unicode string, 16-bit string length - $string = self::_readUnicodeStringLong(substr($valueData, 1)); - $value = '"' . $string['value'] . '"'; - $size = 1 + $string['size']; - break; - case 0x04: // boolean - // offset: 1; size: 1; 0 = FALSE, 1 = TRUE - if (ord($valueData[1])) { - $value = 'TRUE'; - } else { - $value = 'FALSE'; - } - $size = 9; - break; - case 0x10: // error code - // offset: 1; size: 1; error code - $value = self::_mapErrorCode(ord($valueData[1])); - $size = 9; - break; - } - return array( - 'value' => $value, - 'size' => $size, - ); - } - - - /** - * Extract RGB color - * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.4 - * - * @param string $rgb Encoded RGB value (4 bytes) - * @return array - */ - private static function _readRGB($rgb) - { - // offset: 0; size 1; Red component - $r = ord($rgb{0}); - - // offset: 1; size: 1; Green component - $g = ord($rgb{1}); - - // offset: 2; size: 1; Blue component - $b = ord($rgb{2}); - - // HEX notation, e.g. 'FF00FC' - $rgb = sprintf('%02X%02X%02X', $r, $g, $b); - - return array('rgb' => $rgb); - } - - - /** - * Read byte string (8-bit string length) - * OpenOffice documentation: 2.5.2 - * - * @param string $subData - * @return array - */ - private function _readByteStringShort($subData) - { - // offset: 0; size: 1; length of the string (character count) - $ln = ord($subData[0]); - - // offset: 1: size: var; character array (8-bit characters) - $value = $this->_decodeCodepage(substr($subData, 1, $ln)); - - return array( - 'value' => $value, - 'size' => 1 + $ln, // size in bytes of data structure - ); - } - - - /** - * Read byte string (16-bit string length) - * OpenOffice documentation: 2.5.2 - * - * @param string $subData - * @return array - */ - private function _readByteStringLong($subData) - { - // offset: 0; size: 2; length of the string (character count) - $ln = self::_GetInt2d($subData, 0); - - // offset: 2: size: var; character array (8-bit characters) - $value = $this->_decodeCodepage(substr($subData, 2)); - - //return $string; - return array( - 'value' => $value, - 'size' => 2 + $ln, // size in bytes of data structure - ); - } - - - /** - * Extracts an Excel Unicode short string (8-bit string length) - * OpenOffice documentation: 2.5.3 - * function will automatically find out where the Unicode string ends. - * - * @param string $subData - * @return array - */ - private static function _readUnicodeStringShort($subData) - { - $value = ''; - - // offset: 0: size: 1; length of the string (character count) - $characterCount = ord($subData[0]); - - $string = self::_readUnicodeString(substr($subData, 1), $characterCount); - - // add 1 for the string length - $string['size'] += 1; - - return $string; - } - - - /** - * Extracts an Excel Unicode long string (16-bit string length) - * OpenOffice documentation: 2.5.3 - * this function is under construction, needs to support rich text, and Asian phonetic settings - * - * @param string $subData - * @return array - */ - private static function _readUnicodeStringLong($subData) - { - $value = ''; - - // offset: 0: size: 2; length of the string (character count) - $characterCount = self::_GetInt2d($subData, 0); - - $string = self::_readUnicodeString(substr($subData, 2), $characterCount); - - // add 2 for the string length - $string['size'] += 2; - - return $string; - } - - - /** - * Read Unicode string with no string length field, but with known character count - * this function is under construction, needs to support rich text, and Asian phonetic settings - * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.3 - * - * @param string $subData - * @param int $characterCount - * @return array - */ - private static function _readUnicodeString($subData, $characterCount) - { - $value = ''; - - // offset: 0: size: 1; option flags - // bit: 0; mask: 0x01; character compression (0 = compressed 8-bit, 1 = uncompressed 16-bit) - $isCompressed = !((0x01 & ord($subData[0])) >> 0); - - // bit: 2; mask: 0x04; Asian phonetic settings - $hasAsian = (0x04) & ord($subData[0]) >> 2; - - // bit: 3; mask: 0x08; Rich-Text settings - $hasRichText = (0x08) & ord($subData[0]) >> 3; - - // offset: 1: size: var; character array - // this offset assumes richtext and Asian phonetic settings are off which is generally wrong - // needs to be fixed - $value = self::_encodeUTF16(substr($subData, 1, $isCompressed ? $characterCount : 2 * $characterCount), $isCompressed); - - return array( - 'value' => $value, - 'size' => $isCompressed ? 1 + $characterCount : 1 + 2 * $characterCount, // the size in bytes including the option flags - ); - } - - - /** - * Convert UTF-8 string to string surounded by double quotes. Used for explicit string tokens in formulas. - * Example: hello"world --> "hello""world" - * - * @param string $value UTF-8 encoded string - * @return string - */ - private static function _UTF8toExcelDoubleQuoted($value) - { - return '"' . str_replace('"', '""', $value) . '"'; - } - - - /** - * Reads first 8 bytes of a string and return IEEE 754 float - * - * @param string $data Binary string that is at least 8 bytes long - * @return float - */ - private static function _extractNumber($data) - { - $rknumhigh = self::_GetInt4d($data, 4); - $rknumlow = self::_GetInt4d($data, 0); - $sign = ($rknumhigh & 0x80000000) >> 31; - $exp = (($rknumhigh & 0x7ff00000) >> 20) - 1023; - $mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); - $mantissalow1 = ($rknumlow & 0x80000000) >> 31; - $mantissalow2 = ($rknumlow & 0x7fffffff); - $value = $mantissa / pow(2, (20 - $exp)); - - if ($mantissalow1 != 0) { - $value += 1 / pow (2, (21 - $exp)); - } - - $value += $mantissalow2 / pow (2, (52 - $exp)); - if ($sign) { - $value *= -1; - } - - return $value; - } - - - private static function _GetIEEE754($rknum) - { - if (($rknum & 0x02) != 0) { - $value = $rknum >> 2; - } else { - // changes by mmp, info on IEEE754 encoding from - // research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html - // The RK format calls for using only the most significant 30 bits - // of the 64 bit floating point value. The other 34 bits are assumed - // to be 0 so we use the upper 30 bits of $rknum as follows... - $sign = ($rknum & 0x80000000) >> 31; - $exp = ($rknum & 0x7ff00000) >> 20; - $mantissa = (0x100000 | ($rknum & 0x000ffffc)); - $value = $mantissa / pow(2, (20- ($exp - 1023))); - if ($sign) { - $value = -1 * $value; - } - //end of changes by mmp - } - if (($rknum & 0x01) != 0) { - $value /= 100; - } - return $value; - } - - - /** - * Get UTF-8 string from (compressed or uncompressed) UTF-16 string - * - * @param string $string - * @param bool $compressed - * @return string - */ - private static function _encodeUTF16($string, $compressed = '') - { - if ($compressed) { - $string = self::_uncompressByteString($string); - } - - return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE'); - } - - - /** - * Convert UTF-16 string in compressed notation to uncompressed form. Only used for BIFF8. - * - * @param string $string - * @return string - */ - private static function _uncompressByteString($string) - { - $uncompressedString = ''; - $strLen = strlen($string); - for ($i = 0; $i < $strLen; ++$i) { - $uncompressedString .= $string[$i] . "\0"; - } - - return $uncompressedString; - } - - - /** - * Convert string to UTF-8. Only used for BIFF5. - * - * @param string $string - * @return string - */ - private function _decodeCodepage($string) - { - return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->_codepage); - } - - - /** - * Read 16-bit unsigned integer - * - * @param string $data - * @param int $pos - * @return int - */ - public static function _GetInt2d($data, $pos) - { - return ord($data[$pos]) | (ord($data[$pos+1]) << 8); - } - - - /** - * Read 32-bit signed integer - * - * @param string $data - * @param int $pos - * @return int - */ - public static function _GetInt4d($data, $pos) - { - // FIX: represent numbers correctly on 64-bit system - // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 - // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems - $_or_24 = ord($data[$pos + 3]); - if ($_or_24 >= 128) { - // negative number - $_ord_24 = -abs((256 - $_or_24) << 24); - } else { - $_ord_24 = ($_or_24 & 127) << 24; - } - return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24; - } - - - /** - * Read color - * - * @param int $color Indexed color - * @param array $palette Color palette - * @return array RGB color value, example: array('rgb' => 'FF0000') - */ - private static function _readColor($color, $palette, $version) - { - if ($color <= 0x07 || $color >= 0x40) { - // special built-in color - return self::_mapBuiltInColor($color); - } elseif (isset($palette) && isset($palette[$color - 8])) { - // palette color, color index 0x08 maps to pallete index 0 - return $palette[$color - 8]; - } else { - // default color table - if ($version == self::XLS_BIFF8) { - return self::_mapColor($color); - } else { - // BIFF5 - return self::_mapColorBIFF5($color); - } - } - - return $color; - } - - - /** - * Map border style - * OpenOffice documentation: 2.5.11 - * - * @param int $index - * @return string - */ - private static function _mapBorderStyle($index) - { - switch ($index) { - case 0x00: - return PHPExcel_Style_Border::BORDER_NONE; - case 0x01: - return PHPExcel_Style_Border::BORDER_THIN; - case 0x02: - return PHPExcel_Style_Border::BORDER_MEDIUM; - case 0x03: - return PHPExcel_Style_Border::BORDER_DASHED; - case 0x04: - return PHPExcel_Style_Border::BORDER_DOTTED; - case 0x05: - return PHPExcel_Style_Border::BORDER_THICK; - case 0x06: - return PHPExcel_Style_Border::BORDER_DOUBLE; - case 0x07: - return PHPExcel_Style_Border::BORDER_HAIR; - case 0x08: - return PHPExcel_Style_Border::BORDER_MEDIUMDASHED; - case 0x09: - return PHPExcel_Style_Border::BORDER_DASHDOT; - case 0x0A: - return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; - case 0x0B: - return PHPExcel_Style_Border::BORDER_DASHDOTDOT; - case 0x0C: - return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; - case 0x0D: - return PHPExcel_Style_Border::BORDER_SLANTDASHDOT; - default: - return PHPExcel_Style_Border::BORDER_NONE; - } - } - - - /** - * Get fill pattern from index - * OpenOffice documentation: 2.5.12 - * - * @param int $index - * @return string - */ - private static function _mapFillPattern($index) - { - switch ($index) { - case 0x00: - return PHPExcel_Style_Fill::FILL_NONE; - case 0x01: - return PHPExcel_Style_Fill::FILL_SOLID; - case 0x02: - return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; - case 0x03: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; - case 0x04: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; - case 0x05: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; - case 0x06: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; - case 0x07: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; - case 0x08: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; - case 0x09: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; - case 0x0A: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; - case 0x0B: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; - case 0x0C: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; - case 0x0D: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; - case 0x0E: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; - case 0x0F: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; - case 0x10: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; - case 0x11: - return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; - case 0x12: - return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; - default: - return PHPExcel_Style_Fill::FILL_NONE; - } - } - - - /** - * Map error code, e.g. '#N/A' - * - * @param int $subData - * @return string - */ - private static function _mapErrorCode($subData) - { - switch ($subData) { - case 0x00: - return '#NULL!'; - break; - case 0x07: - return '#DIV/0!'; - break; - case 0x0F: - return '#VALUE!'; - break; - case 0x17: - return '#REF!'; - break; - case 0x1D: - return '#NAME?'; - break; - case 0x24: - return '#NUM!'; - break; - case 0x2A: - return '#N/A'; - break; - default: - return false; - } - } - - - /** - * Map built-in color to RGB value - * - * @param int $color Indexed color - * @return array - */ - private static function _mapBuiltInColor($color) - { - switch ($color) { - case 0x00: - return array('rgb' => '000000'); - case 0x01: - return array('rgb' => 'FFFFFF'); - case 0x02: - return array('rgb' => 'FF0000'); - case 0x03: - return array('rgb' => '00FF00'); - case 0x04: - return array('rgb' => '0000FF'); - case 0x05: - return array('rgb' => 'FFFF00'); - case 0x06: - return array('rgb' => 'FF00FF'); - case 0x07: - return array('rgb' => '00FFFF'); - case 0x40: - return array('rgb' => '000000'); // system window text color - case 0x41: - return array('rgb' => 'FFFFFF'); // system window background color - default: - return array('rgb' => '000000'); - } - } - - - /** - * Map color array from BIFF5 built-in color index - * - * @param int $subData - * @return array - */ - private static function _mapColorBIFF5($subData) - { - switch ($subData) { - case 0x08: - return array('rgb' => '000000'); - case 0x09: - return array('rgb' => 'FFFFFF'); - case 0x0A: - return array('rgb' => 'FF0000'); - case 0x0B: - return array('rgb' => '00FF00'); - case 0x0C: - return array('rgb' => '0000FF'); - case 0x0D: - return array('rgb' => 'FFFF00'); - case 0x0E: - return array('rgb' => 'FF00FF'); - case 0x0F: - return array('rgb' => '00FFFF'); - case 0x10: - return array('rgb' => '800000'); - case 0x11: - return array('rgb' => '008000'); - case 0x12: - return array('rgb' => '000080'); - case 0x13: - return array('rgb' => '808000'); - case 0x14: - return array('rgb' => '800080'); - case 0x15: - return array('rgb' => '008080'); - case 0x16: - return array('rgb' => 'C0C0C0'); - case 0x17: - return array('rgb' => '808080'); - case 0x18: - return array('rgb' => '8080FF'); - case 0x19: - return array('rgb' => '802060'); - case 0x1A: - return array('rgb' => 'FFFFC0'); - case 0x1B: - return array('rgb' => 'A0E0F0'); - case 0x1C: - return array('rgb' => '600080'); - case 0x1D: - return array('rgb' => 'FF8080'); - case 0x1E: - return array('rgb' => '0080C0'); - case 0x1F: - return array('rgb' => 'C0C0FF'); - case 0x20: - return array('rgb' => '000080'); - case 0x21: - return array('rgb' => 'FF00FF'); - case 0x22: - return array('rgb' => 'FFFF00'); - case 0x23: - return array('rgb' => '00FFFF'); - case 0x24: - return array('rgb' => '800080'); - case 0x25: - return array('rgb' => '800000'); - case 0x26: - return array('rgb' => '008080'); - case 0x27: - return array('rgb' => '0000FF'); - case 0x28: - return array('rgb' => '00CFFF'); - case 0x29: - return array('rgb' => '69FFFF'); - case 0x2A: - return array('rgb' => 'E0FFE0'); - case 0x2B: - return array('rgb' => 'FFFF80'); - case 0x2C: - return array('rgb' => 'A6CAF0'); - case 0x2D: - return array('rgb' => 'DD9CB3'); - case 0x2E: - return array('rgb' => 'B38FEE'); - case 0x2F: - return array('rgb' => 'E3E3E3'); - case 0x30: - return array('rgb' => '2A6FF9'); - case 0x31: - return array('rgb' => '3FB8CD'); - case 0x32: - return array('rgb' => '488436'); - case 0x33: - return array('rgb' => '958C41'); - case 0x34: - return array('rgb' => '8E5E42'); - case 0x35: - return array('rgb' => 'A0627A'); - case 0x36: - return array('rgb' => '624FAC'); - case 0x37: - return array('rgb' => '969696'); - case 0x38: - return array('rgb' => '1D2FBE'); - case 0x39: - return array('rgb' => '286676'); - case 0x3A: - return array('rgb' => '004500'); - case 0x3B: - return array('rgb' => '453E01'); - case 0x3C: - return array('rgb' => '6A2813'); - case 0x3D: - return array('rgb' => '85396A'); - case 0x3E: - return array('rgb' => '4A3285'); - case 0x3F: - return array('rgb' => '424242'); - default: - return array('rgb' => '000000'); - } - } - - - /** - * Map color array from BIFF8 built-in color index - * - * @param int $subData - * @return array - */ - private static function _mapColor($subData) - { - switch ($subData) { - case 0x08: - return array('rgb' => '000000'); - case 0x09: - return array('rgb' => 'FFFFFF'); - case 0x0A: - return array('rgb' => 'FF0000'); - case 0x0B: - return array('rgb' => '00FF00'); - case 0x0C: - return array('rgb' => '0000FF'); - case 0x0D: - return array('rgb' => 'FFFF00'); - case 0x0E: - return array('rgb' => 'FF00FF'); - case 0x0F: - return array('rgb' => '00FFFF'); - case 0x10: - return array('rgb' => '800000'); - case 0x11: - return array('rgb' => '008000'); - case 0x12: - return array('rgb' => '000080'); - case 0x13: - return array('rgb' => '808000'); - case 0x14: - return array('rgb' => '800080'); - case 0x15: - return array('rgb' => '008080'); - case 0x16: - return array('rgb' => 'C0C0C0'); - case 0x17: - return array('rgb' => '808080'); - case 0x18: - return array('rgb' => '9999FF'); - case 0x19: - return array('rgb' => '993366'); - case 0x1A: - return array('rgb' => 'FFFFCC'); - case 0x1B: - return array('rgb' => 'CCFFFF'); - case 0x1C: - return array('rgb' => '660066'); - case 0x1D: - return array('rgb' => 'FF8080'); - case 0x1E: - return array('rgb' => '0066CC'); - case 0x1F: - return array('rgb' => 'CCCCFF'); - case 0x20: - return array('rgb' => '000080'); - case 0x21: - return array('rgb' => 'FF00FF'); - case 0x22: - return array('rgb' => 'FFFF00'); - case 0x23: - return array('rgb' => '00FFFF'); - case 0x24: - return array('rgb' => '800080'); - case 0x25: - return array('rgb' => '800000'); - case 0x26: - return array('rgb' => '008080'); - case 0x27: - return array('rgb' => '0000FF'); - case 0x28: - return array('rgb' => '00CCFF'); - case 0x29: - return array('rgb' => 'CCFFFF'); - case 0x2A: - return array('rgb' => 'CCFFCC'); - case 0x2B: - return array('rgb' => 'FFFF99'); - case 0x2C: - return array('rgb' => '99CCFF'); - case 0x2D: - return array('rgb' => 'FF99CC'); - case 0x2E: - return array('rgb' => 'CC99FF'); - case 0x2F: - return array('rgb' => 'FFCC99'); - case 0x30: - return array('rgb' => '3366FF'); - case 0x31: - return array('rgb' => '33CCCC'); - case 0x32: - return array('rgb' => '99CC00'); - case 0x33: - return array('rgb' => 'FFCC00'); - case 0x34: - return array('rgb' => 'FF9900'); - case 0x35: - return array('rgb' => 'FF6600'); - case 0x36: - return array('rgb' => '666699'); - case 0x37: - return array('rgb' => '969696'); - case 0x38: - return array('rgb' => '003366'); - case 0x39: - return array('rgb' => '339966'); - case 0x3A: - return array('rgb' => '003300'); - case 0x3B: - return array('rgb' => '333300'); - case 0x3C: - return array('rgb' => '993300'); - case 0x3D: - return array('rgb' => '993366'); - case 0x3E: - return array('rgb' => '333399'); - case 0x3F: - return array('rgb' => '333333'); - default: - return array('rgb' => '000000'); - } - } - - private function _parseRichText($is = '') - { - $value = new PHPExcel_RichText(); - - $value->createText($is); - - return $value; - } -} +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2015 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## + */ + +// Original file header of ParseXL (used as the base for this class): +// -------------------------------------------------------------------------------- +// Adapted from Excel_Spreadsheet_Reader developed by users bizon153, +// trex005, and mmp11 (SourceForge.net) +// http://sourceforge.net/projects/phpexcelreader/ +// Primary changes made by canyoncasa (dvc) for ParseXL 1.00 ... +// Modelled moreso after Perl Excel Parse/Write modules +// Added Parse_Excel_Spreadsheet object +// Reads a whole worksheet or tab as row,column array or as +// associated hash of indexed rows and named column fields +// Added variables for worksheet (tab) indexes and names +// Added an object call for loading individual woorksheets +// Changed default indexing defaults to 0 based arrays +// Fixed date/time and percent formats +// Includes patches found at SourceForge... +// unicode patch by nobody +// unpack("d") machine depedency patch by matchy +// boundsheet utf16 patch by bjaenichen +// Renamed functions for shorter names +// General code cleanup and rigor, including <80 column width +// Included a testcase Excel file and PHP example calls +// Code works for PHP 5.x + +// Primary changes made by canyoncasa (dvc) for ParseXL 1.10 ... +// http://sourceforge.net/tracker/index.php?func=detail&aid=1466964&group_id=99160&atid=623334 +// Decoding of formula conditions, results, and tokens. +// Support for user-defined named cells added as an array "namedcells" +// Patch code for user-defined named cells supports single cells only. +// NOTE: this patch only works for BIFF8 as BIFF5-7 use a different +// external sheet reference structure + + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + +/** + * PHPExcel_Reader_Excel5 + * + * This class uses {@link http://sourceforge.net/projects/phpexcelreader/parseXL} + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader +{ + // ParseXL definitions + const XLS_BIFF8 = 0x0600; + const XLS_BIFF7 = 0x0500; + const XLS_WorkbookGlobals = 0x0005; + const XLS_Worksheet = 0x0010; + + // record identifiers + const XLS_Type_FORMULA = 0x0006; + const XLS_Type_EOF = 0x000a; + const XLS_Type_PROTECT = 0x0012; + const XLS_Type_OBJECTPROTECT = 0x0063; + const XLS_Type_SCENPROTECT = 0x00dd; + const XLS_Type_PASSWORD = 0x0013; + const XLS_Type_HEADER = 0x0014; + const XLS_Type_FOOTER = 0x0015; + const XLS_Type_EXTERNSHEET = 0x0017; + const XLS_Type_DEFINEDNAME = 0x0018; + const XLS_Type_VERTICALPAGEBREAKS = 0x001a; + const XLS_Type_HORIZONTALPAGEBREAKS = 0x001b; + const XLS_Type_NOTE = 0x001c; + const XLS_Type_SELECTION = 0x001d; + const XLS_Type_DATEMODE = 0x0022; + const XLS_Type_EXTERNNAME = 0x0023; + const XLS_Type_LEFTMARGIN = 0x0026; + const XLS_Type_RIGHTMARGIN = 0x0027; + const XLS_Type_TOPMARGIN = 0x0028; + const XLS_Type_BOTTOMMARGIN = 0x0029; + const XLS_Type_PRINTGRIDLINES = 0x002b; + const XLS_Type_FILEPASS = 0x002f; + const XLS_Type_FONT = 0x0031; + const XLS_Type_CONTINUE = 0x003c; + const XLS_Type_PANE = 0x0041; + const XLS_Type_CODEPAGE = 0x0042; + const XLS_Type_DEFCOLWIDTH = 0x0055; + const XLS_Type_OBJ = 0x005d; + const XLS_Type_COLINFO = 0x007d; + const XLS_Type_IMDATA = 0x007f; + const XLS_Type_SHEETPR = 0x0081; + const XLS_Type_HCENTER = 0x0083; + const XLS_Type_VCENTER = 0x0084; + const XLS_Type_SHEET = 0x0085; + const XLS_Type_PALETTE = 0x0092; + const XLS_Type_SCL = 0x00a0; + const XLS_Type_PAGESETUP = 0x00a1; + const XLS_Type_MULRK = 0x00bd; + const XLS_Type_MULBLANK = 0x00be; + const XLS_Type_DBCELL = 0x00d7; + const XLS_Type_XF = 0x00e0; + const XLS_Type_MERGEDCELLS = 0x00e5; + const XLS_Type_MSODRAWINGGROUP = 0x00eb; + const XLS_Type_MSODRAWING = 0x00ec; + const XLS_Type_SST = 0x00fc; + const XLS_Type_LABELSST = 0x00fd; + const XLS_Type_EXTSST = 0x00ff; + const XLS_Type_EXTERNALBOOK = 0x01ae; + const XLS_Type_DATAVALIDATIONS = 0x01b2; + const XLS_Type_TXO = 0x01b6; + const XLS_Type_HYPERLINK = 0x01b8; + const XLS_Type_DATAVALIDATION = 0x01be; + const XLS_Type_DIMENSION = 0x0200; + const XLS_Type_BLANK = 0x0201; + const XLS_Type_NUMBER = 0x0203; + const XLS_Type_LABEL = 0x0204; + const XLS_Type_BOOLERR = 0x0205; + const XLS_Type_STRING = 0x0207; + const XLS_Type_ROW = 0x0208; + const XLS_Type_INDEX = 0x020b; + const XLS_Type_ARRAY = 0x0221; + const XLS_Type_DEFAULTROWHEIGHT = 0x0225; + const XLS_Type_WINDOW2 = 0x023e; + const XLS_Type_RK = 0x027e; + const XLS_Type_STYLE = 0x0293; + const XLS_Type_FORMAT = 0x041e; + const XLS_Type_SHAREDFMLA = 0x04bc; + const XLS_Type_BOF = 0x0809; + const XLS_Type_SHEETPROTECTION = 0x0867; + const XLS_Type_RANGEPROTECTION = 0x0868; + const XLS_Type_SHEETLAYOUT = 0x0862; + const XLS_Type_XFEXT = 0x087d; + const XLS_Type_PAGELAYOUTVIEW = 0x088b; + const XLS_Type_UNKNOWN = 0xffff; + + // Encryption type + const MS_BIFF_CRYPTO_NONE = 0; + const MS_BIFF_CRYPTO_XOR = 1; + const MS_BIFF_CRYPTO_RC4 = 2; + + // Size of stream blocks when using RC4 encryption + const REKEY_BLOCK = 0x400; + + /** + * Summary Information stream data. + * + * @var string + */ + private $_summaryInformation; + + /** + * Extended Summary Information stream data. + * + * @var string + */ + private $_documentSummaryInformation; + + /** + * User-Defined Properties stream data. + * + * @var string + */ + private $_userDefinedProperties; + + /** + * Workbook stream data. (Includes workbook globals substream as well as sheet substreams) + * + * @var string + */ + private $_data; + + /** + * Size in bytes of $this->_data + * + * @var int + */ + private $_dataSize; + + /** + * Current position in stream + * + * @var integer + */ + private $_pos; + + /** + * Workbook to be returned by the reader. + * + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Worksheet that is currently being built by the reader. + * + * @var PHPExcel_Worksheet + */ + private $_phpSheet; + + /** + * BIFF version + * + * @var int + */ + private $_version; + + /** + * Codepage set in the Excel file being read. Only important for BIFF5 (Excel 5.0 - Excel 95) + * For BIFF8 (Excel 97 - Excel 2003) this will always have the value 'UTF-16LE' + * + * @var string + */ + private $_codepage; + + /** + * Shared formats + * + * @var array + */ + private $_formats; + + /** + * Shared fonts + * + * @var array + */ + private $_objFonts; + + /** + * Color palette + * + * @var array + */ + private $_palette; + + /** + * Worksheets + * + * @var array + */ + private $_sheets; + + /** + * External books + * + * @var array + */ + private $_externalBooks; + + /** + * REF structures. Only applies to BIFF8. + * + * @var array + */ + private $_ref; + + /** + * External names + * + * @var array + */ + private $_externalNames; + + /** + * Defined names + * + * @var array + */ + private $_definedname; + + /** + * Shared strings. Only applies to BIFF8. + * + * @var array + */ + private $_sst; + + /** + * Panes are frozen? (in sheet currently being read). See WINDOW2 record. + * + * @var boolean + */ + private $_frozen; + + /** + * Fit printout to number of pages? (in sheet currently being read). See SHEETPR record. + * + * @var boolean + */ + private $_isFitToPages; + + /** + * Objects. One OBJ record contributes with one entry. + * + * @var array + */ + private $_objs; + + /** + * Text Objects. One TXO record corresponds with one entry. + * + * @var array + */ + private $_textObjects; + + /** + * Cell Annotations (BIFF8) + * + * @var array + */ + private $_cellNotes; + + /** + * The combined MSODRAWINGGROUP data + * + * @var string + */ + private $_drawingGroupData; + + /** + * The combined MSODRAWING data (per sheet) + * + * @var string + */ + private $_drawingData; + + /** + * Keep track of XF index + * + * @var int + */ + private $_xfIndex; + + /** + * Mapping of XF index (that is a cell XF) to final index in cellXf collection + * + * @var array + */ + private $_mapCellXfIndex; + + /** + * Mapping of XF index (that is a style XF) to final index in cellStyleXf collection + * + * @var array + */ + private $_mapCellStyleXfIndex; + + /** + * The shared formulas in a sheet. One SHAREDFMLA record contributes with one value. + * + * @var array + */ + private $_sharedFormulas; + + /** + * The shared formula parts in a sheet. One FORMULA record contributes with one value if it + * refers to a shared formula. + * + * @var array + */ + private $_sharedFormulaParts; + + /** + * The type of encryption in use + * + * @var int + */ + private $_encryption = 0; + + /** + * The position in the stream after which contents are encrypted + * + * @var int + */ + private $_encryptionStartPos = false; + + /** + * The current RC4 decryption object + * + * @var PHPExcel_Reader_Excel5_RC4 + */ + private $_rc4Key = null; + + /** + * The position in the stream that the RC4 decryption object was left at + * + * @var int + */ + private $_rc4Pos = 0; + + /** + * The current MD5 context state + * + * @var string + */ + private $_md5Ctxt = null; + + /** + * Create a new PHPExcel_Reader_Excel5 instance + */ + public function __construct() + { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + try { + // Use ParseXL for the hard work. + $ole = new PHPExcel_Shared_OLERead(); + + // get excel data + $res = $ole->read($pFilename); + return true; + } catch (PHPExcel_Exception $e) { + return false; + } + } + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetNames = array(); + + // Read the OLE file + $this->_loadOLE($pFilename); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + $this->_pos = 0; + $this->_sheets = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: + $this->_readBof(); + break; + case self::XLS_Type_SHEET: + $this->_readSheet(); + break; + case self::XLS_Type_EOF: + $this->_readDefault(); + break 2; + default: + $this->_readDefault(); + break; + } + } + + foreach ($this->_sheets as $sheet) { + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module + continue; + } + + $worksheetNames[] = $sheet['name']; + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + // Read the OLE file + $this->_loadOLE($pFilename); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + // initialize + $this->_pos = 0; + $this->_sheets = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: + $this->_readBof(); + break; + case self::XLS_Type_SHEET: + $this->_readSheet(); + break; + case self::XLS_Type_EOF: + $this->_readDefault(); + break 2; + default: + $this->_readDefault(); + break; + } + } + + // Parse the individual sheets + foreach ($this->_sheets as $sheet) { + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet + // 0x02: Chart + // 0x06: Visual Basic module + continue; + } + + $tmpInfo = array(); + $tmpInfo['worksheetName'] = $sheet['name']; + $tmpInfo['lastColumnLetter'] = 'A'; + $tmpInfo['lastColumnIndex'] = 0; + $tmpInfo['totalRows'] = 0; + $tmpInfo['totalColumns'] = 0; + + $this->_pos = $sheet['offset']; + + while ($this->_pos <= $this->_dataSize - 4) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_RK: + case self::XLS_Type_LABELSST: + case self::XLS_Type_NUMBER: + case self::XLS_Type_FORMULA: + case self::XLS_Type_BOOLERR: + case self::XLS_Type_LABEL: + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + $rowIndex = self::_GetInt2d($recordData, 0) + 1; + $columnIndex = self::_GetInt2d($recordData, 2); + + $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); + $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); + break; + case self::XLS_Type_BOF: + $this->_readBof(); + break; + case self::XLS_Type_EOF: + $this->_readDefault(); + break 2; + default: + $this->_readDefault(); + break; + } + } + + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; + + $worksheetInfo[] = $tmpInfo; + } + + return $worksheetInfo; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Read the OLE file + $this->_loadOLE($pFilename); + + // Initialisations + $this->_phpExcel = new PHPExcel; + $this->_phpExcel->removeSheetByIndex(0); // remove 1st sheet + if (!$this->_readDataOnly) { + $this->_phpExcel->removeCellStyleXfByIndex(0); // remove the default style + $this->_phpExcel->removeCellXfByIndex(0); // remove the default style + } + + // Read the summary information stream (containing meta data) + $this->_readSummaryInformation(); + + // Read the Additional document summary information stream (containing application-specific meta data) + $this->_readDocumentSummaryInformation(); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + // initialize + $this->_pos = 0; + $this->_codepage = 'CP1252'; + $this->_formats = array(); + $this->_objFonts = array(); + $this->_palette = array(); + $this->_sheets = array(); + $this->_externalBooks = array(); + $this->_ref = array(); + $this->_definedname = array(); + $this->_sst = array(); + $this->_drawingGroupData = ''; + $this->_xfIndex = ''; + $this->_mapCellXfIndex = array(); + $this->_mapCellStyleXfIndex = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: + $this->_readBof(); + break; + case self::XLS_Type_FILEPASS: + $this->_readFilepass(); + break; + case self::XLS_Type_CODEPAGE: + $this->_readCodepage(); + break; + case self::XLS_Type_DATEMODE: + $this->_readDateMode(); + break; + case self::XLS_Type_FONT: + $this->_readFont(); + break; + case self::XLS_Type_FORMAT: + $this->_readFormat(); + break; + case self::XLS_Type_XF: + $this->_readXf(); + break; + case self::XLS_Type_XFEXT: + $this->_readXfExt(); + break; + case self::XLS_Type_STYLE: + $this->_readStyle(); + break; + case self::XLS_Type_PALETTE: + $this->_readPalette(); + break; + case self::XLS_Type_SHEET: + $this->_readSheet(); + break; + case self::XLS_Type_EXTERNALBOOK: + $this->_readExternalBook(); + break; + case self::XLS_Type_EXTERNNAME: + $this->_readExternName(); + break; + case self::XLS_Type_EXTERNSHEET: + $this->_readExternSheet(); + break; + case self::XLS_Type_DEFINEDNAME: + $this->_readDefinedName(); + break; + case self::XLS_Type_MSODRAWINGGROUP: + $this->_readMsoDrawingGroup(); + break; + case self::XLS_Type_SST: + $this->_readSst(); + break; + case self::XLS_Type_EOF: + $this->_readDefault(); + break 2; + default: + $this->_readDefault(); + break; + } + } + + // Resolve indexed colors for font, fill, and border colors + // Cannot be resolved already in XF record, because PALETTE record comes afterwards + if (!$this->_readDataOnly) { + foreach ($this->_objFonts as $objFont) { + if (isset($objFont->colorIndex)) { + $color = self::_readColor($objFont->colorIndex, $this->_palette, $this->_version); + $objFont->getColor()->setRGB($color['rgb']); + } + } + + foreach ($this->_phpExcel->getCellXfCollection() as $objStyle) { + // fill start and end color + $fill = $objStyle->getFill(); + + if (isset($fill->startcolorIndex)) { + $startColor = self::_readColor($fill->startcolorIndex, $this->_palette, $this->_version); + $fill->getStartColor()->setRGB($startColor['rgb']); + } + if (isset($fill->endcolorIndex)) { + $endColor = self::_readColor($fill->endcolorIndex, $this->_palette, $this->_version); + $fill->getEndColor()->setRGB($endColor['rgb']); + } + + // border colors + $top = $objStyle->getBorders()->getTop(); + $right = $objStyle->getBorders()->getRight(); + $bottom = $objStyle->getBorders()->getBottom(); + $left = $objStyle->getBorders()->getLeft(); + $diagonal = $objStyle->getBorders()->getDiagonal(); + + if (isset($top->colorIndex)) { + $borderTopColor = self::_readColor($top->colorIndex, $this->_palette, $this->_version); + $top->getColor()->setRGB($borderTopColor['rgb']); + } + if (isset($right->colorIndex)) { + $borderRightColor = self::_readColor($right->colorIndex, $this->_palette, $this->_version); + $right->getColor()->setRGB($borderRightColor['rgb']); + } + if (isset($bottom->colorIndex)) { + $borderBottomColor = self::_readColor($bottom->colorIndex, $this->_palette, $this->_version); + $bottom->getColor()->setRGB($borderBottomColor['rgb']); + } + if (isset($left->colorIndex)) { + $borderLeftColor = self::_readColor($left->colorIndex, $this->_palette, $this->_version); + $left->getColor()->setRGB($borderLeftColor['rgb']); + } + if (isset($diagonal->colorIndex)) { + $borderDiagonalColor = self::_readColor($diagonal->colorIndex, $this->_palette, $this->_version); + $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']); + } + } + } + + // treat MSODRAWINGGROUP records, workbook-level Escher + if (!$this->_readDataOnly && $this->_drawingGroupData) { + $escherWorkbook = new PHPExcel_Shared_Escher(); + $reader = new PHPExcel_Reader_Excel5_Escher($escherWorkbook); + $escherWorkbook = $reader->load($this->_drawingGroupData); + + // debug Escher stream + //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); + //$debug->load($this->_drawingGroupData); + } + + // Parse the individual sheets + foreach ($this->_sheets as $sheet) { + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module + continue; + } + + // check if sheet should be skipped + if (isset($this->_loadSheetsOnly) && !in_array($sheet['name'], $this->_loadSheetsOnly)) { + continue; + } + + // add sheet to PHPExcel object + $this->_phpSheet = $this->_phpExcel->createSheet(); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula + // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet + // name in line with the formula, not the reverse + $this->_phpSheet->setTitle($sheet['name'], false); + $this->_phpSheet->setSheetState($sheet['sheetState']); + + $this->_pos = $sheet['offset']; + + // Initialize isFitToPages. May change after reading SHEETPR record. + $this->_isFitToPages = false; + + // Initialize drawingData + $this->_drawingData = ''; + + // Initialize objs + $this->_objs = array(); + + // Initialize shared formula parts + $this->_sharedFormulaParts = array(); + + // Initialize shared formulas + $this->_sharedFormulas = array(); + + // Initialize text objs + $this->_textObjects = array(); + + // Initialize cell annotations + $this->_cellNotes = array(); + $this->textObjRef = -1; + + while ($this->_pos <= $this->_dataSize - 4) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: + $this->_readBof(); + break; + case self::XLS_Type_PRINTGRIDLINES: + $this->_readPrintGridlines(); + break; + case self::XLS_Type_DEFAULTROWHEIGHT: + $this->_readDefaultRowHeight(); + break; + case self::XLS_Type_SHEETPR: + $this->_readSheetPr(); + break; + case self::XLS_Type_HORIZONTALPAGEBREAKS: + $this->_readHorizontalPageBreaks(); + break; + case self::XLS_Type_VERTICALPAGEBREAKS: + $this->_readVerticalPageBreaks(); + break; + case self::XLS_Type_HEADER: + $this->_readHeader(); + break; + case self::XLS_Type_FOOTER: + $this->_readFooter(); + break; + case self::XLS_Type_HCENTER: + $this->_readHcenter(); + break; + case self::XLS_Type_VCENTER: + $this->_readVcenter(); + break; + case self::XLS_Type_LEFTMARGIN: + $this->_readLeftMargin(); + break; + case self::XLS_Type_RIGHTMARGIN: + $this->_readRightMargin(); + break; + case self::XLS_Type_TOPMARGIN: + $this->_readTopMargin(); + break; + case self::XLS_Type_BOTTOMMARGIN: + $this->_readBottomMargin(); + break; + case self::XLS_Type_PAGESETUP: + $this->_readPageSetup(); + break; + case self::XLS_Type_PROTECT: + $this->_readProtect(); + break; + case self::XLS_Type_SCENPROTECT: + $this->_readScenProtect(); + break; + case self::XLS_Type_OBJECTPROTECT: + $this->_readObjectProtect(); + break; + case self::XLS_Type_PASSWORD: + $this->_readPassword(); + break; + case self::XLS_Type_DEFCOLWIDTH: + $this->_readDefColWidth(); + break; + case self::XLS_Type_COLINFO: + $this->_readColInfo(); + break; + case self::XLS_Type_DIMENSION: + $this->_readDefault(); + break; + case self::XLS_Type_ROW: + $this->_readRow(); + break; + case self::XLS_Type_DBCELL: + $this->_readDefault(); + break; + case self::XLS_Type_RK: + $this->_readRk(); + break; + case self::XLS_Type_LABELSST: + $this->_readLabelSst(); + break; + case self::XLS_Type_MULRK: + $this->_readMulRk(); + break; + case self::XLS_Type_NUMBER: + $this->_readNumber(); + break; + case self::XLS_Type_FORMULA: + $this->_readFormula(); + break; + case self::XLS_Type_SHAREDFMLA: + $this->_readSharedFmla(); + break; + case self::XLS_Type_BOOLERR: + $this->_readBoolErr(); + break; + case self::XLS_Type_MULBLANK: + $this->_readMulBlank(); + break; + case self::XLS_Type_LABEL: + $this->_readLabel(); + break; + case self::XLS_Type_BLANK: + $this->_readBlank(); + break; + case self::XLS_Type_MSODRAWING: + $this->_readMsoDrawing(); + break; + case self::XLS_Type_OBJ: + $this->_readObj(); + break; + case self::XLS_Type_WINDOW2: + $this->_readWindow2(); + break; + case self::XLS_Type_PAGELAYOUTVIEW: + $this->_readPageLayoutView(); + break; + case self::XLS_Type_SCL: + $this->_readScl(); + break; + case self::XLS_Type_PANE: + $this->_readPane(); + break; + case self::XLS_Type_SELECTION: + $this->_readSelection(); + break; + case self::XLS_Type_MERGEDCELLS: + $this->_readMergedCells(); + break; + case self::XLS_Type_HYPERLINK: + $this->_readHyperLink(); + break; + case self::XLS_Type_DATAVALIDATIONS: + $this->_readDataValidations(); + break; + case self::XLS_Type_DATAVALIDATION: + $this->_readDataValidation(); + break; + case self::XLS_Type_SHEETLAYOUT: + $this->_readSheetLayout(); + break; + case self::XLS_Type_SHEETPROTECTION: + $this->_readSheetProtection(); + break; + case self::XLS_Type_RANGEPROTECTION: + $this->_readRangeProtection(); + break; + case self::XLS_Type_NOTE: + $this->_readNote(); + break; + //case self::XLS_Type_IMDATA: $this->_readImData(); break; + case self::XLS_Type_TXO: + $this->_readTextObject(); + break; + case self::XLS_Type_CONTINUE: + $this->_readContinue(); + break; + case self::XLS_Type_EOF: + $this->_readDefault(); + break 2; + default: + $this->_readDefault(); + break; + } + + } + + // treat MSODRAWING records, sheet-level Escher + if (!$this->_readDataOnly && $this->_drawingData) { + $escherWorksheet = new PHPExcel_Shared_Escher(); + $reader = new PHPExcel_Reader_Excel5_Escher($escherWorksheet); + $escherWorksheet = $reader->load($this->_drawingData); + + // debug Escher stream + //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); + //$debug->load($this->_drawingData); + + // get all spContainers in one long array, so they can be mapped to OBJ records + $allSpContainers = $escherWorksheet->getDgContainer()->getSpgrContainer()->getAllSpContainers(); + } + + // treat OBJ records + foreach ($this->_objs as $n => $obj) { +// echo '<hr /><b>Object</b> reference is ', $n,'<br />'; +// var_dump($obj); +// echo '<br />'; + + // the first shape container never has a corresponding OBJ record, hence $n + 1 + if (isset($allSpContainers[$n + 1]) && is_object($allSpContainers[$n + 1])) { + $spContainer = $allSpContainers[$n + 1]; + + // we skip all spContainers that are a part of a group shape since we cannot yet handle those + if ($spContainer->getNestingLevel() > 1) { + continue; + } + + // calculate the width and height of the shape + list($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($spContainer->getStartCoordinates()); + list($endColumn, $endRow) = PHPExcel_Cell::coordinateFromString($spContainer->getEndCoordinates()); + + $startOffsetX = $spContainer->getStartOffsetX(); + $startOffsetY = $spContainer->getStartOffsetY(); + $endOffsetX = $spContainer->getEndOffsetX(); + $endOffsetY = $spContainer->getEndOffsetY(); + + $width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX); + $height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY); + + // calculate offsetX and offsetY of the shape + $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024; + $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256; + + switch ($obj['otObjType']) { + case 0x19: + // Note +// echo 'Cell Annotation Object<br />'; +// echo 'Object ID is ', $obj['idObjID'],'<br />'; + if (isset($this->_cellNotes[$obj['idObjID']])) { + $cellNote = $this->_cellNotes[$obj['idObjID']]; + + if (isset($this->_textObjects[$obj['idObjID']])) { + $textObject = $this->_textObjects[$obj['idObjID']]; + $this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject; + } + } + break; + case 0x08: +// echo 'Picture Object<br />'; + // picture + // get index to BSE entry (1-based) + $BSEindex = $spContainer->getOPT(0x0104); + $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection(); + $BSE = $BSECollection[$BSEindex - 1]; + $blipType = $BSE->getBlipType(); + + // need check because some blip types are not supported by Escher reader such as EMF + if ($blip = $BSE->getBlip()) { + $ih = imagecreatefromstring($blip->getData()); + $drawing = new PHPExcel_Worksheet_MemoryDrawing(); + $drawing->setImageResource($ih); + + // width, height, offsetX, offsetY + $drawing->setResizeProportional(false); + $drawing->setWidth($width); + $drawing->setHeight($height); + $drawing->setOffsetX($offsetX); + $drawing->setOffsetY($offsetY); + + switch ($blipType) { + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: + $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); + $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG); + break; + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: + $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG); + $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG); + break; + } + + $drawing->setWorksheet($this->_phpSheet); + $drawing->setCoordinates($spContainer->getStartCoordinates()); + } + break; + default: + // other object type + break; + } + } + } + + // treat SHAREDFMLA records + if ($this->_version == self::XLS_BIFF8) { + foreach ($this->_sharedFormulaParts as $cell => $baseCell) { + list($column, $row) = PHPExcel_Cell::coordinateFromString($cell); + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { + $formula = $this->_getFormulaFromStructure($this->_sharedFormulas[$baseCell], $cell); + $this->_phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + } + } + } + + if (!empty($this->_cellNotes)) { + foreach ($this->_cellNotes as $note => $noteDetails) { + if (!isset($noteDetails['objTextData'])) { + if (isset($this->_textObjects[$note])) { + $textObject = $this->_textObjects[$note]; + $noteDetails['objTextData'] = $textObject; + } else { + $noteDetails['objTextData']['text'] = ''; + } + } +// echo '<b>Cell annotation ', $note,'</b><br />'; +// var_dump($noteDetails); +// echo '<br />'; + $cellAddress = str_replace('$', '', $noteDetails['cellRef']); + $this->_phpSheet->getComment($cellAddress)->setAuthor($noteDetails['author'])->setText($this->_parseRichText($noteDetails['objTextData']['text'])); + } + } + } + + // add the named ranges (defined names) + foreach ($this->_definedname as $definedName) { + if ($definedName['isBuiltInName']) { + switch ($definedName['name']) { + case pack('C', 0x06): + // print area + // in general, formula looks like this: Foo!$C$7:$J$66,Bar!$A$1:$IV$2 + $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? + + $extractedRanges = array(); + foreach ($ranges as $range) { + // $range should look like one of these + // Foo!$C$7:$J$66 + // Bar!$A$1:$IV$2 + $explodes = explode('!', $range); // FIXME: what if sheetname contains exclamation mark? + $sheetName = trim($explodes[0], "'"); + if (count($explodes) == 2) { + if (strpos($explodes[1], ':') === false) { + $explodes[1] = $explodes[1] . ':' . $explodes[1]; + } + $extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66 + } + } + if ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) { + $docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges)); // C7:J66,A1:IV2 + } + break; + case pack('C', 0x07): + // print titles (repeating rows) + // Assuming BIFF8, there are 3 cases + // 1. repeating rows + // formula looks like this: Sheet!$A$1:$IV$2 + // rows 1-2 repeat + // 2. repeating columns + // formula looks like this: Sheet!$A$1:$B$65536 + // columns A-B repeat + // 3. both repeating rows and repeating columns + // formula looks like this: Sheet!$A$1:$B$65536,Sheet!$A$1:$IV$2 + $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? + foreach ($ranges as $range) { + // $range should look like this one of these + // Sheet!$A$1:$B$65536 + // Sheet!$A$1:$IV$2 + $explodes = explode('!', $range); + if (count($explodes) == 2) { + if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) { + $extractedRange = $explodes[1]; + $extractedRange = str_replace('$', '', $extractedRange); + + $coordinateStrings = explode(':', $extractedRange); + if (count($coordinateStrings) == 2) { + list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[0]); + list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[1]); + + if ($firstColumn == 'A' and $lastColumn == 'IV') { + // then we have repeating rows + $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($firstRow, $lastRow)); + } elseif ($firstRow == 1 and $lastRow == 65536) { + // then we have repeating columns + $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($firstColumn, $lastColumn)); + } + } + } + } + } + break; + } + } else { + // Extract range + $explodes = explode('!', $definedName['formula']); + + if (count($explodes) == 2) { + if (($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) || + ($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0], "'")))) { + $extractedRange = $explodes[1]; + $extractedRange = str_replace('$', '', $extractedRange); + + $localOnly = ($definedName['scope'] == 0) ? false : true; + + $scope = ($definedName['scope'] == 0) ? null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']); + + $this->_phpExcel->addNamedRange(new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope)); + } + } else { + // Named Value + // TODO Provide support for named values + } + } + } + $this->_data = null; + + return $this->_phpExcel; + } + + /** + * Read record data from stream, decrypting as required + * + * @param string $data Data stream to read from + * @param int $pos Position to start reading from + * @param int $length Record data length + * + * @return string Record data + */ + private function _readRecordData($data, $pos, $len) + { + $data = substr($data, $pos, $len); + + // File not encrypted, or record before encryption start point + if ($this->_encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->_encryptionStartPos) { + return $data; + } + + $recordData = ''; + if ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) { + $oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK); + $block = floor($pos / self::REKEY_BLOCK); + $endBlock = floor(($pos + $len) / self::REKEY_BLOCK); + + // Spin an RC4 decryptor to the right spot. If we have a decryptor sitting + // at a point earlier in the current block, re-use it as we can save some time. + if ($block != $oldBlock || $pos < $this->_rc4Pos || !$this->_rc4Key) { + $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + $step = $pos % self::REKEY_BLOCK; + } else { + $step = $pos - $this->_rc4Pos; + } + $this->_rc4Key->RC4(str_repeat("\0", $step)); + + // Decrypt record data (re-keying at the end of every block) + while ($block != $endBlock) { + $step = self::REKEY_BLOCK - ($pos % self::REKEY_BLOCK); + $recordData .= $this->_rc4Key->RC4(substr($data, 0, $step)); + $data = substr($data, $step); + $pos += $step; + $len -= $step; + $block++; + $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + } + $recordData .= $this->_rc4Key->RC4(substr($data, 0, $len)); + + // Keep track of the position of this decryptor. + // We'll try and re-use it later if we can to speed things up + $this->_rc4Pos = $pos + $len; + } elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) { + throw new PHPExcel_Reader_Exception('XOr encryption not supported'); + } + return $recordData; + } + + /** + * Use OLE reader to extract the relevant data streams from the OLE file + * + * @param string $pFilename + */ + private function _loadOLE($pFilename) + { + // OLE reader + $ole = new PHPExcel_Shared_OLERead(); + // get excel data, + $res = $ole->read($pFilename); + // Get workbook data: workbook stream + sheet streams + $this->_data = $ole->getStream($ole->wrkbook); + // Get summary information data + $this->_summaryInformation = $ole->getStream($ole->summaryInformation); + // Get additional document summary information data + $this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation); + // Get user-defined property data +// $this->_userDefinedProperties = $ole->getUserDefinedProperties(); + } + + + /** + * Read summary information + */ + private function _readSummaryInformation() + { + if (!isset($this->_summaryInformation)) { + return; + } + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + // offset: 2; size: 2; + // offset: 4; size: 2; OS version + // offset: 6; size: 2; OS indicator + // offset: 8; size: 16 + // offset: 24; size: 4; section count + $secCount = self::_GetInt4d($this->_summaryInformation, 24); + + // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 + // offset: 44; size: 4 + $secOffset = self::_GetInt4d($this->_summaryInformation, 44); + + // section header + // offset: $secOffset; size: 4; section length + $secLength = self::_GetInt4d($this->_summaryInformation, $secOffset); + + // offset: $secOffset+4; size: 4; property count + $countProperties = self::_GetInt4d($this->_summaryInformation, $secOffset+4); + + // initialize code page (used to resolve string values) + $codePage = 'CP1252'; + + // offset: ($secOffset+8); size: var + // loop through property decarations and properties + for ($i = 0; $i < $countProperties; ++$i) { + // offset: ($secOffset+8) + (8 * $i); size: 4; property ID + $id = self::_GetInt4d($this->_summaryInformation, ($secOffset+8) + (8 * $i)); + + // Use value of property id as appropriate + // offset: ($secOffset+12) + (8 * $i); size: 4; offset from beginning of section (48) + $offset = self::_GetInt4d($this->_summaryInformation, ($secOffset+12) + (8 * $i)); + + $type = self::_GetInt4d($this->_summaryInformation, $secOffset + $offset); + + // initialize property value + $value = null; + + // extract property value based on property type + switch ($type) { + case 0x02: // 2 byte signed integer + $value = self::_GetInt2d($this->_summaryInformation, $secOffset + 4 + $offset); + break; + case 0x03: // 4 byte signed integer + $value = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); + break; + case 0x13: // 4 byte unsigned integer + // not needed yet, fix later if necessary + break; + case 0x1E: // null-terminated string prepended by dword string length + $byteLength = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); + $value = substr($this->_summaryInformation, $secOffset + 8 + $offset, $byteLength); + $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); + $value = rtrim($value); + break; + case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + // PHP-time + $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_summaryInformation, $secOffset + 4 + $offset, 8)); + break; + case 0x47: // Clipboard format + // not needed yet, fix later if necessary + break; + } + + switch ($id) { + case 0x01: // Code Page + $codePage = PHPExcel_Shared_CodePage::NumberToName($value); + break; + case 0x02: // Title + $this->_phpExcel->getProperties()->setTitle($value); + break; + case 0x03: // Subject + $this->_phpExcel->getProperties()->setSubject($value); + break; + case 0x04: // Author (Creator) + $this->_phpExcel->getProperties()->setCreator($value); + break; + case 0x05: // Keywords + $this->_phpExcel->getProperties()->setKeywords($value); + break; + case 0x06: // Comments (Description) + $this->_phpExcel->getProperties()->setDescription($value); + break; + case 0x07: // Template + // Not supported by PHPExcel + break; + case 0x08: // Last Saved By (LastModifiedBy) + $this->_phpExcel->getProperties()->setLastModifiedBy($value); + break; + case 0x09: // Revision + // Not supported by PHPExcel + break; + case 0x0A: // Total Editing Time + // Not supported by PHPExcel + break; + case 0x0B: // Last Printed + // Not supported by PHPExcel + break; + case 0x0C: // Created Date/Time + $this->_phpExcel->getProperties()->setCreated($value); + break; + case 0x0D: // Modified Date/Time + $this->_phpExcel->getProperties()->setModified($value); + break; + case 0x0E: // Number of Pages + // Not supported by PHPExcel + break; + case 0x0F: // Number of Words + // Not supported by PHPExcel + break; + case 0x10: // Number of Characters + // Not supported by PHPExcel + break; + case 0x11: // Thumbnail + // Not supported by PHPExcel + break; + case 0x12: // Name of creating application + // Not supported by PHPExcel + break; + case 0x13: // Security + // Not supported by PHPExcel + break; + } + } + } + + + /** + * Read additional document summary information + */ + private function _readDocumentSummaryInformation() + { + if (!isset($this->_documentSummaryInformation)) { + return; + } + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + // offset: 2; size: 2; + // offset: 4; size: 2; OS version + // offset: 6; size: 2; OS indicator + // offset: 8; size: 16 + // offset: 24; size: 4; section count + $secCount = self::_GetInt4d($this->_documentSummaryInformation, 24); +// echo '$secCount = ', $secCount,'<br />'; + + // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae + // offset: 44; size: 4; first section offset + $secOffset = self::_GetInt4d($this->_documentSummaryInformation, 44); +// echo '$secOffset = ', $secOffset,'<br />'; + + // section header + // offset: $secOffset; size: 4; section length + $secLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset); +// echo '$secLength = ', $secLength,'<br />'; + + // offset: $secOffset+4; size: 4; property count + $countProperties = self::_GetInt4d($this->_documentSummaryInformation, $secOffset+4); +// echo '$countProperties = ', $countProperties,'<br />'; + + // initialize code page (used to resolve string values) + $codePage = 'CP1252'; + + // offset: ($secOffset+8); size: var + // loop through property decarations and properties + for ($i = 0; $i < $countProperties; ++$i) { +// echo 'Property ', $i,'<br />'; + // offset: ($secOffset+8) + (8 * $i); size: 4; property ID + $id = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+8) + (8 * $i)); +// echo 'ID is ', $id,'<br />'; + + // Use value of property id as appropriate + // offset: 60 + 8 * $i; size: 4; offset from beginning of section (48) + $offset = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+12) + (8 * $i)); + + $type = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + $offset); +// echo 'Type is ', $type,', '; + + // initialize property value + $value = null; + + // extract property value based on property type + switch ($type) { + case 0x02: // 2 byte signed integer + $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + break; + case 0x03: // 4 byte signed integer + $value = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + break; + case 0x0B: // Boolean + $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = ($value == 0 ? false : true); + break; + case 0x13: // 4 byte unsigned integer + // not needed yet, fix later if necessary + break; + case 0x1E: // null-terminated string prepended by dword string length + $byteLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = substr($this->_documentSummaryInformation, $secOffset + 8 + $offset, $byteLength); + $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); + $value = rtrim($value); + break; + case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + // PHP-Time + $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_documentSummaryInformation, $secOffset + 4 + $offset, 8)); + break; + case 0x47: // Clipboard format + // not needed yet, fix later if necessary + break; + } + + switch ($id) { + case 0x01: // Code Page + $codePage = PHPExcel_Shared_CodePage::NumberToName($value); + break; + case 0x02: // Category + $this->_phpExcel->getProperties()->setCategory($value); + break; + case 0x03: // Presentation Target + // Not supported by PHPExcel + break; + case 0x04: // Bytes + // Not supported by PHPExcel + break; + case 0x05: // Lines + // Not supported by PHPExcel + break; + case 0x06: // Paragraphs + // Not supported by PHPExcel + break; + case 0x07: // Slides + // Not supported by PHPExcel + break; + case 0x08: // Notes + // Not supported by PHPExcel + break; + case 0x09: // Hidden Slides + // Not supported by PHPExcel + break; + case 0x0A: // MM Clips + // Not supported by PHPExcel + break; + case 0x0B: // Scale Crop + // Not supported by PHPExcel + break; + case 0x0C: // Heading Pairs + // Not supported by PHPExcel + break; + case 0x0D: // Titles of Parts + // Not supported by PHPExcel + break; + case 0x0E: // Manager + $this->_phpExcel->getProperties()->setManager($value); + break; + case 0x0F: // Company + $this->_phpExcel->getProperties()->setCompany($value); + break; + case 0x10: // Links up-to-date + // Not supported by PHPExcel + break; + } + } + } + + + /** + * Reads a general type of BIFF record. Does nothing except for moving stream pointer forward to next record. + */ + private function _readDefault() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); +// $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + } + + + /** + * The NOTE record specifies a comment associated with a particular cell. In Excel 95 (BIFF7) and earlier versions, + * this record stores a note (cell note). This feature was significantly enhanced in Excel 97. + */ + private function _readNote() + { +// echo '<b>Read Cell Annotation</b><br />'; + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + $cellAddress = $this->_readBIFF8CellAddress(substr($recordData, 0, 4)); + if ($this->_version == self::XLS_BIFF8) { + $noteObjID = self::_GetInt2d($recordData, 6); + $noteAuthor = self::_readUnicodeStringLong(substr($recordData, 8)); + $noteAuthor = $noteAuthor['value']; +// echo 'Note Address=', $cellAddress,'<br />'; +// echo 'Note Object ID=', $noteObjID,'<br />'; +// echo 'Note Author=', $noteAuthor,'<hr />'; +// + $this->_cellNotes[$noteObjID] = array( + 'cellRef' => $cellAddress, + 'objectID' => $noteObjID, + 'author' => $noteAuthor + ); + } else { + $extension = false; + if ($cellAddress == '$B$65536') { + // If the address row is -1 and the column is 0, (which translates as $B$65536) then this is a continuation + // note from the previous cell annotation. We're not yet handling this, so annotations longer than the + // max 2048 bytes will probably throw a wobbly. + $row = self::_GetInt2d($recordData, 0); + $extension = true; + $cellAddress = array_pop(array_keys($this->_phpSheet->getComments())); + } +// echo 'Note Address=', $cellAddress,'<br />'; + + $cellAddress = str_replace('$', '', $cellAddress); + $noteLength = self::_GetInt2d($recordData, 4); + $noteText = trim(substr($recordData, 6)); +// echo 'Note Length=', $noteLength,'<br />'; +// echo 'Note Text=', $noteText,'<br />'; + + if ($extension) { + // Concatenate this extension with the currently set comment for the cell + $comment = $this->_phpSheet->getComment($cellAddress); + $commentText = $comment->getText()->getPlainText(); + $comment->setText($this->_parseRichText($commentText.$noteText)); + } else { + // Set comment for the cell + $this->_phpSheet->getComment($cellAddress)->setText($this->_parseRichText($noteText)); +// ->setAuthor($author) + } + } + + } + + + /** + * The TEXT Object record contains the text associated with a cell annotation. + */ + private function _readTextObject() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // recordData consists of an array of subrecords looking like this: + // grbit: 2 bytes; Option Flags + // rot: 2 bytes; rotation + // cchText: 2 bytes; length of the text (in the first continue record) + // cbRuns: 2 bytes; length of the formatting (in the second continue record) + // followed by the continuation records containing the actual text and formatting + $grbitOpts = self::_GetInt2d($recordData, 0); + $rot = self::_GetInt2d($recordData, 2); + $cchText = self::_GetInt2d($recordData, 10); + $cbRuns = self::_GetInt2d($recordData, 12); + $text = $this->_getSplicedRecordData(); + + $this->_textObjects[$this->textObjRef] = array( + 'text' => substr($text["recordData"], $text["spliceOffsets"][0]+1, $cchText), + 'format' => substr($text["recordData"], $text["spliceOffsets"][1], $cbRuns), + 'alignment' => $grbitOpts, + 'rotation' => $rot + ); + +// echo '<b>_readTextObject()</b><br />'; +// var_dump($this->_textObjects[$this->textObjRef]); +// echo '<br />'; + } + + + /** + * Read BOF + */ + private function _readBof() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = substr($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 2; size: 2; type of the following data + $substreamType = self::_GetInt2d($recordData, 2); + + switch ($substreamType) { + case self::XLS_WorkbookGlobals: + $version = self::_GetInt2d($recordData, 0); + if (($version != self::XLS_BIFF8) && ($version != self::XLS_BIFF7)) { + throw new PHPExcel_Reader_Exception('Cannot read this Excel file. Version is too old.'); + } + $this->_version = $version; + break; + case self::XLS_Worksheet: + // do not use this version information for anything + // it is unreliable (OpenOffice doc, 5.8), use only version information from the global stream + break; + default: + // substream, e.g. chart + // just skip the entire substream + do { + $code = self::_GetInt2d($this->_data, $this->_pos); + $this->_readDefault(); + } while ($code != self::XLS_Type_EOF && $this->_pos < $this->_dataSize); + break; + } + } + + + /** + * FILEPASS + * + * This record is part of the File Protection Block. It + * contains information about the read/write password of the + * file. All record contents following this record will be + * encrypted. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + * + * The decryption functions and objects used from here on in + * are based on the source of Spreadsheet-ParseExcel: + * http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/ + */ + private function _readFilepass() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + if ($length != 54) { + throw new PHPExcel_Reader_Exception('Unexpected file pass record length'); + } + + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_verifyPassword('VelvetSweatshop', substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->_md5Ctxt)) { + throw new PHPExcel_Reader_Exception('Decryption password incorrect'); + } + + $this->_encryption = self::MS_BIFF_CRYPTO_RC4; + + // Decryption required from the record after next onwards + $this->_encryptionStartPos = $this->_pos + self::_GetInt2d($this->_data, $this->_pos + 2); + } + + /** + * Make an RC4 decryptor for the given block + * + * @var int $block Block for which to create decrypto + * @var string $valContext MD5 context state + * + * @return PHPExcel_Reader_Excel5_RC4 + */ + private function _makeKey($block, $valContext) + { + $pwarray = str_repeat("\0", 64); + + for ($i = 0; $i < 5; $i++) { + $pwarray[$i] = $valContext[$i]; + } + + $pwarray[5] = chr($block & 0xff); + $pwarray[6] = chr(($block >> 8) & 0xff); + $pwarray[7] = chr(($block >> 16) & 0xff); + $pwarray[8] = chr(($block >> 24) & 0xff); + + $pwarray[9] = "\x80"; + $pwarray[56] = "\x48"; + + $md5 = new PHPExcel_Reader_Excel5_MD5(); + $md5->add($pwarray); + + $s = $md5->getContext(); + return new PHPExcel_Reader_Excel5_RC4($s); + } + + /** + * Verify RC4 file password + * + * @var string $password Password to check + * @var string $docid Document id + * @var string $salt_data Salt data + * @var string $hashedsalt_data Hashed salt data + * @var string &$valContext Set to the MD5 context of the value + * + * @return bool Success + */ + private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext) + { + $pwarray = str_repeat("\0", 64); + + for ($i = 0; $i < strlen($password); $i++) { + $o = ord(substr($password, $i, 1)); + $pwarray[2 * $i] = chr($o & 0xff); + $pwarray[2 * $i + 1] = chr(($o >> 8) & 0xff); + } + $pwarray[2 * $i] = chr(0x80); + $pwarray[56] = chr(($i << 4) & 0xff); + + $md5 = new PHPExcel_Reader_Excel5_MD5(); + $md5->add($pwarray); + + $mdContext1 = $md5->getContext(); + + $offset = 0; + $keyoffset = 0; + $tocopy = 5; + + $md5->reset(); + + while ($offset != 16) { + if ((64 - $offset) < 5) { + $tocopy = 64 - $offset; + } + for ($i = 0; $i <= $tocopy; $i++) { + $pwarray[$offset + $i] = $mdContext1[$keyoffset + $i]; + } + $offset += $tocopy; + + if ($offset == 64) { + $md5->add($pwarray); + $keyoffset = $tocopy; + $tocopy = 5 - $tocopy; + $offset = 0; + continue; + } + + $keyoffset = 0; + $tocopy = 5; + for ($i = 0; $i < 16; $i++) { + $pwarray[$offset + $i] = $docid[$i]; + } + $offset += 16; + } + + $pwarray[16] = "\x80"; + for ($i = 0; $i < 47; $i++) { + $pwarray[17 + $i] = "\0"; + } + $pwarray[56] = "\x80"; + $pwarray[57] = "\x0a"; + + $md5->add($pwarray); + $valContext = $md5->getContext(); + + $key = $this->_makeKey(0, $valContext); + + $salt = $key->RC4($salt_data); + $hashedsalt = $key->RC4($hashedsalt_data); + + $salt .= "\x80" . str_repeat("\0", 47); + $salt[56] = "\x80"; + + $md5->reset(); + $md5->add($salt); + $mdContext2 = $md5->getContext(); + + return $mdContext2 == $hashedsalt; + } + + /** + * CODEPAGE + * + * This record stores the text encoding used to write byte + * strings, stored as MS Windows code page identifier. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readCodepage() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; code page identifier + $codepage = self::_GetInt2d($recordData, 0); + + $this->_codepage = PHPExcel_Shared_CodePage::NumberToName($codepage); + } + + + /** + * DATEMODE + * + * This record specifies the base date for displaying date + * values. All dates are stored as count of days past this + * base date. In BIFF2-BIFF4 this record is part of the + * Calculation Settings Block. In BIFF5-BIFF8 it is + * stored in the Workbook Globals Substream. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readDateMode() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; 0 = base 1900, 1 = base 1904 + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + if (ord($recordData{0}) == 1) { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + } + } + + + /** + * Read a FONT record + */ + private function _readFont() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + $objFont = new PHPExcel_Style_Font(); + + // offset: 0; size: 2; height of the font (in twips = 1/20 of a point) + $size = self::_GetInt2d($recordData, 0); + $objFont->setSize($size / 20); + + // offset: 2; size: 2; option flags + // bit: 0; mask 0x0001; bold (redundant in BIFF5-BIFF8) + // bit: 1; mask 0x0002; italic + $isItalic = (0x0002 & self::_GetInt2d($recordData, 2)) >> 1; + if ($isItalic) { + $objFont->setItalic(true); + } + + // bit: 2; mask 0x0004; underlined (redundant in BIFF5-BIFF8) + // bit: 3; mask 0x0008; strike + $isStrike = (0x0008 & self::_GetInt2d($recordData, 2)) >> 3; + if ($isStrike) { + $objFont->setStrikethrough(true); + } + + // offset: 4; size: 2; colour index + $colorIndex = self::_GetInt2d($recordData, 4); + $objFont->colorIndex = $colorIndex; + + // offset: 6; size: 2; font weight + $weight = self::_GetInt2d($recordData, 6); + switch ($weight) { + case 0x02BC: + $objFont->setBold(true); + break; + } + + // offset: 8; size: 2; escapement type + $escapement = self::_GetInt2d($recordData, 8); + switch ($escapement) { + case 0x0001: + $objFont->setSuperScript(true); + break; + case 0x0002: + $objFont->setSubScript(true); + break; + } + + // offset: 10; size: 1; underline type + $underlineType = ord($recordData{10}); + switch ($underlineType) { + case 0x00: + break; // no underline + case 0x01: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + break; + case 0x02: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); + break; + case 0x21: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING); + break; + case 0x22: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING); + break; + } + + // offset: 11; size: 1; font family + // offset: 12; size: 1; character set + // offset: 13; size: 1; not used + // offset: 14; size: var; font name + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringShort(substr($recordData, 14)); + } else { + $string = $this->_readByteStringShort(substr($recordData, 14)); + } + $objFont->setName($string['value']); + + $this->_objFonts[] = $objFont; + } + } + + + /** + * FORMAT + * + * This record contains information about a number format. + * All FORMAT records occur together in a sequential list. + * + * In BIFF2-BIFF4 other records referencing a FORMAT record + * contain a zero-based index into this list. From BIFF5 on + * the FORMAT record contains the index itself that will be + * used by other records. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readFormat() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + $indexCode = self::_GetInt2d($recordData, 0); + + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong(substr($recordData, 2)); + } else { + // BIFF7 + $string = $this->_readByteStringShort(substr($recordData, 2)); + } + + $formatString = $string['value']; + $this->_formats[$indexCode] = $formatString; + } + } + + + /** + * XF - Extended Format + * + * This record contains formatting information for cells, rows, columns or styles. + * According to http://support.microsoft.com/kb/147732 there are always at least 15 cell style XF + * and 1 cell XF. + * Inspection of Excel files generated by MS Office Excel shows that XF records 0-14 are cell style XF + * and XF record 15 is a cell XF + * We only read the first cell style XF and skip the remaining cell style XF records + * We read all cell XF records. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readXf() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + $objStyle = new PHPExcel_Style(); + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; Index to FONT record + if (self::_GetInt2d($recordData, 0) < 4) { + $fontIndex = self::_GetInt2d($recordData, 0); + } else { + // this has to do with that index 4 is omitted in all BIFF versions for some strange reason + // check the OpenOffice documentation of the FONT record + $fontIndex = self::_GetInt2d($recordData, 0) - 1; + } + $objStyle->setFont($this->_objFonts[$fontIndex]); + + // offset: 2; size: 2; Index to FORMAT record + $numberFormatIndex = self::_GetInt2d($recordData, 2); + if (isset($this->_formats[$numberFormatIndex])) { + // then we have user-defined format code + $numberformat = array('code' => $this->_formats[$numberFormatIndex]); + } elseif (($code = PHPExcel_Style_NumberFormat::builtInFormatCode($numberFormatIndex)) !== '') { + // then we have built-in format code + $numberformat = array('code' => $code); + } else { + // we set the general format code + $numberformat = array('code' => 'General'); + } + $objStyle->getNumberFormat()->setFormatCode($numberformat['code']); + + // offset: 4; size: 2; XF type, cell protection, and parent style XF + // bit 2-0; mask 0x0007; XF_TYPE_PROT + $xfTypeProt = self::_GetInt2d($recordData, 4); + // bit 0; mask 0x01; 1 = cell is locked + $isLocked = (0x01 & $xfTypeProt) >> 0; + $objStyle->getProtection()->setLocked($isLocked ? PHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + + // bit 1; mask 0x02; 1 = Formula is hidden + $isHidden = (0x02 & $xfTypeProt) >> 1; + $objStyle->getProtection()->setHidden($isHidden ? PHPExcel_Style_Protection::PROTECTION_PROTECTED : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + + // bit 2; mask 0x04; 0 = Cell XF, 1 = Cell Style XF + $isCellStyleXf = (0x04 & $xfTypeProt) >> 2; + + // offset: 6; size: 1; Alignment and text break + // bit 2-0, mask 0x07; horizontal alignment + $horAlign = (0x07 & ord($recordData{6})) >> 0; + switch ($horAlign) { + case 0: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_GENERAL); + break; + case 1: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT); + break; + case 2: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER); + break; + case 3: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); + break; + case 4: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_FILL); + break; + case 5: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY); + break; + case 6: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS); + break; + } + // bit 3, mask 0x08; wrap text + $wrapText = (0x08 & ord($recordData{6})) >> 3; + switch ($wrapText) { + case 0: + $objStyle->getAlignment()->setWrapText(false); + break; + case 1: + $objStyle->getAlignment()->setWrapText(true); + break; + } + // bit 6-4, mask 0x70; vertical alignment + $vertAlign = (0x70 & ord($recordData{6})) >> 4; + switch ($vertAlign) { + case 0: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP); + break; + case 1: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER); + break; + case 2: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_BOTTOM); + break; + case 3: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_JUSTIFY); + break; + } + + if ($this->_version == self::XLS_BIFF8) { + // offset: 7; size: 1; XF_ROTATION: Text rotation angle + $angle = ord($recordData{7}); + $rotation = 0; + if ($angle <= 90) { + $rotation = $angle; + } else if ($angle <= 180) { + $rotation = 90 - $angle; + } else if ($angle == 255) { + $rotation = -165; + } + $objStyle->getAlignment()->setTextRotation($rotation); + + // offset: 8; size: 1; Indentation, shrink to cell size, and text direction + // bit: 3-0; mask: 0x0F; indent level + $indent = (0x0F & ord($recordData{8})) >> 0; + $objStyle->getAlignment()->setIndent($indent); + + // bit: 4; mask: 0x10; 1 = shrink content to fit into cell + $shrinkToFit = (0x10 & ord($recordData{8})) >> 4; + switch ($shrinkToFit) { + case 0: + $objStyle->getAlignment()->setShrinkToFit(false); + break; + case 1: + $objStyle->getAlignment()->setShrinkToFit(true); + break; + } + + // offset: 9; size: 1; Flags used for attribute groups + + // offset: 10; size: 4; Cell border lines and background area + // bit: 3-0; mask: 0x0000000F; left style + if ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) { + $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle); + } + // bit: 7-4; mask: 0x000000F0; right style + if ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) { + $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle); + } + // bit: 11-8; mask: 0x00000F00; top style + if ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) { + $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle); + } + // bit: 15-12; mask: 0x0000F000; bottom style + if ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) { + $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle); + } + // bit: 22-16; mask: 0x007F0000; left color + $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16; + + // bit: 29-23; mask: 0x3F800000; right color + $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23; + + // bit: 30; mask: 0x40000000; 1 = diagonal line from top left to right bottom + $diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ? true : false; + + // bit: 31; mask: 0x80000000; 1 = diagonal line from bottom left to top right + $diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ? true : false; + + if ($diagonalUp == false && $diagonalDown == false) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); + } elseif ($diagonalUp == true && $diagonalDown == false) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); + } elseif ($diagonalUp == false && $diagonalDown == true) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); + } elseif ($diagonalUp == true && $diagonalDown == true) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); + } + + // offset: 14; size: 4; + // bit: 6-0; mask: 0x0000007F; top color + $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0; + + // bit: 13-7; mask: 0x00003F80; bottom color + $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7; + + // bit: 20-14; mask: 0x001FC000; diagonal color + $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14; + + // bit: 24-21; mask: 0x01E00000; diagonal style + if ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) { + $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle); + } + + // bit: 31-26; mask: 0xFC000000 fill pattern + if ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) { + $objStyle->getFill()->setFillType($fillType); + } + // offset: 18; size: 2; pattern and background colour + // bit: 6-0; mask: 0x007F; color index for pattern color + $objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0; + + // bit: 13-7; mask: 0x3F80; color index for pattern background + $objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7; + } else { + // BIFF5 + + // offset: 7; size: 1; Text orientation and flags + $orientationAndFlags = ord($recordData{7}); + + // bit: 1-0; mask: 0x03; XF_ORIENTATION: Text orientation + $xfOrientation = (0x03 & $orientationAndFlags) >> 0; + switch ($xfOrientation) { + case 0: + $objStyle->getAlignment()->setTextRotation(0); + break; + case 1: + $objStyle->getAlignment()->setTextRotation(-165); + break; + case 2: + $objStyle->getAlignment()->setTextRotation(90); + break; + case 3: + $objStyle->getAlignment()->setTextRotation(-90); + break; + } + + // offset: 8; size: 4; cell border lines and background area + $borderAndBackground = self::_GetInt4d($recordData, 8); + + // bit: 6-0; mask: 0x0000007F; color index for pattern color + $objStyle->getFill()->startcolorIndex = (0x0000007F & $borderAndBackground) >> 0; + + // bit: 13-7; mask: 0x00003F80; color index for pattern background + $objStyle->getFill()->endcolorIndex = (0x00003F80 & $borderAndBackground) >> 7; + + // bit: 21-16; mask: 0x003F0000; fill pattern + $objStyle->getFill()->setFillType(self::_mapFillPattern((0x003F0000 & $borderAndBackground) >> 16)); + + // bit: 24-22; mask: 0x01C00000; bottom line style + $objStyle->getBorders()->getBottom()->setBorderStyle(self::_mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22)); + + // bit: 31-25; mask: 0xFE000000; bottom line color + $objStyle->getBorders()->getBottom()->colorIndex = (0xFE000000 & $borderAndBackground) >> 25; + + // offset: 12; size: 4; cell border lines + $borderLines = self::_GetInt4d($recordData, 12); + + // bit: 2-0; mask: 0x00000007; top line style + $objStyle->getBorders()->getTop()->setBorderStyle(self::_mapBorderStyle((0x00000007 & $borderLines) >> 0)); + + // bit: 5-3; mask: 0x00000038; left line style + $objStyle->getBorders()->getLeft()->setBorderStyle(self::_mapBorderStyle((0x00000038 & $borderLines) >> 3)); + + // bit: 8-6; mask: 0x000001C0; right line style + $objStyle->getBorders()->getRight()->setBorderStyle(self::_mapBorderStyle((0x000001C0 & $borderLines) >> 6)); + + // bit: 15-9; mask: 0x0000FE00; top line color index + $objStyle->getBorders()->getTop()->colorIndex = (0x0000FE00 & $borderLines) >> 9; + + // bit: 22-16; mask: 0x007F0000; left line color index + $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & $borderLines) >> 16; + + // bit: 29-23; mask: 0x3F800000; right line color index + $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & $borderLines) >> 23; + } + + // add cellStyleXf or cellXf and update mapping + if ($isCellStyleXf) { + // we only read one style XF record which is always the first + if ($this->_xfIndex == 0) { + $this->_phpExcel->addCellStyleXf($objStyle); + $this->_mapCellStyleXfIndex[$this->_xfIndex] = 0; + } + } else { + // we read all cell XF records + $this->_phpExcel->addCellXf($objStyle); + $this->_mapCellXfIndex[$this->_xfIndex] = count($this->_phpExcel->getCellXfCollection()) - 1; + } + + // update XF index for when we read next record + ++$this->_xfIndex; + } + } + + + /** + * + */ + private function _readXfExt() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0x087D = repeated header + + // offset: 2; size: 2 + + // offset: 4; size: 8; not used + + // offset: 12; size: 2; record version + + // offset: 14; size: 2; index to XF record which this record modifies + $ixfe = self::_GetInt2d($recordData, 14); + + // offset: 16; size: 2; not used + + // offset: 18; size: 2; number of extension properties that follow + $cexts = self::_GetInt2d($recordData, 18); + + // start reading the actual extension data + $offset = 20; + while ($offset < $length) { + // extension type + $extType = self::_GetInt2d($recordData, $offset); + + // extension length + $cb = self::_GetInt2d($recordData, $offset + 2); + + // extension data + $extData = substr($recordData, $offset + 4, $cb); + + switch ($extType) { + case 4: // fill start color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if (isset($this->_mapCellXfIndex[$ixfe])) { + $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); + $fill->getStartColor()->setRGB($rgb); + unset($fill->startcolorIndex); // normal color index does not apply, discard + } + } + break; + case 5: // fill end color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if (isset($this->_mapCellXfIndex[$ixfe])) { + $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); + $fill->getEndColor()->setRGB($rgb); + unset($fill->endcolorIndex); // normal color index does not apply, discard + } + } + break; + case 7: // border color top + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if (isset($this->_mapCellXfIndex[$ixfe])) { + $top = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getTop(); + $top->getColor()->setRGB($rgb); + unset($top->colorIndex); // normal color index does not apply, discard + } + } + break; + case 8: // border color bottom + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if (isset($this->_mapCellXfIndex[$ixfe])) { + $bottom = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getBottom(); + $bottom->getColor()->setRGB($rgb); + unset($bottom->colorIndex); // normal color index does not apply, discard + } + } + break; + case 9: // border color left + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if (isset($this->_mapCellXfIndex[$ixfe])) { + $left = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getLeft(); + $left->getColor()->setRGB($rgb); + unset($left->colorIndex); // normal color index does not apply, discard + } + } + break; + case 10: // border color right + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if (isset($this->_mapCellXfIndex[$ixfe])) { + $right = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getRight(); + $right->getColor()->setRGB($rgb); + unset($right->colorIndex); // normal color index does not apply, discard + } + } + break; + case 11: // border color diagonal + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if (isset($this->_mapCellXfIndex[$ixfe])) { + $diagonal = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getDiagonal(); + $diagonal->getColor()->setRGB($rgb); + unset($diagonal->colorIndex); // normal color index does not apply, discard + } + } + break; + case 13: // font color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if (isset($this->_mapCellXfIndex[$ixfe])) { + $font = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFont(); + $font->getColor()->setRGB($rgb); + unset($font->colorIndex); // normal color index does not apply, discard + } + } + break; + } + + $offset += $cb; + } + } + + } + + + /** + * Read STYLE record + */ + private function _readStyle() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index to XF record and flag for built-in style + $ixfe = self::_GetInt2d($recordData, 0); + + // bit: 11-0; mask 0x0FFF; index to XF record + $xfIndex = (0x0FFF & $ixfe) >> 0; + + // bit: 15; mask 0x8000; 0 = user-defined style, 1 = built-in style + $isBuiltIn = (bool) ((0x8000 & $ixfe) >> 15); + + if ($isBuiltIn) { + // offset: 2; size: 1; identifier for built-in style + $builtInId = ord($recordData{2}); + + switch ($builtInId) { + case 0x00: + // currently, we are not using this for anything + break; + default: + break; + } + } else { + // user-defined; not supported by PHPExcel + } + } + } + + + /** + * Read PALETTE record + */ + private function _readPalette() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; number of following colors + $nm = self::_GetInt2d($recordData, 0); + + // list of RGB colors + for ($i = 0; $i < $nm; ++$i) { + $rgb = substr($recordData, 2 + 4 * $i, 4); + $this->_palette[] = self::_readRGB($rgb); + } + } + } + + + /** + * SHEET + * + * This record is located in the Workbook Globals + * Substream and represents a sheet inside the workbook. + * One SHEET record is written for each sheet. It stores the + * sheet name and a stream offset to the BOF record of the + * respective Sheet Substream within the Workbook Stream. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readSheet() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // offset: 0; size: 4; absolute stream position of the BOF record of the sheet + // NOTE: not encrypted + $rec_offset = self::_GetInt4d($this->_data, $this->_pos + 4); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 4; size: 1; sheet state + switch (ord($recordData{4})) { + case 0x00: + $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; + break; + case 0x01: + $sheetState = PHPExcel_Worksheet::SHEETSTATE_HIDDEN; + break; + case 0x02: + $sheetState = PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN; + break; + default: + $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; + break; + } + + // offset: 5; size: 1; sheet type + $sheetType = ord($recordData{5}); + + // offset: 6; size: var; sheet name + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringShort(substr($recordData, 6)); + $rec_name = $string['value']; + } elseif ($this->_version == self::XLS_BIFF7) { + $string = $this->_readByteStringShort(substr($recordData, 6)); + $rec_name = $string['value']; + } + + $this->_sheets[] = array( + 'name' => $rec_name, + 'offset' => $rec_offset, + 'sheetState' => $sheetState, + 'sheetType' => $sheetType, + ); + } + + + /** + * Read EXTERNALBOOK record + */ + private function _readExternalBook() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset within record data + $offset = 0; + + // there are 4 types of records + if (strlen($recordData) > 4) { + // external reference + // offset: 0; size: 2; number of sheet names ($nm) + $nm = self::_GetInt2d($recordData, 0); + $offset += 2; + + // offset: 2; size: var; encoded URL without sheet name (Unicode string, 16-bit length) + $encodedUrlString = self::_readUnicodeStringLong(substr($recordData, 2)); + $offset += $encodedUrlString['size']; + + // offset: var; size: var; list of $nm sheet names (Unicode strings, 16-bit length) + $externalSheetNames = array(); + for ($i = 0; $i < $nm; ++$i) { + $externalSheetNameString = self::_readUnicodeStringLong(substr($recordData, $offset)); + $externalSheetNames[] = $externalSheetNameString['value']; + $offset += $externalSheetNameString['size']; + } + + // store the record data + $this->_externalBooks[] = array( + 'type' => 'external', + 'encodedUrl' => $encodedUrlString['value'], + 'externalSheetNames' => $externalSheetNames, + ); + } elseif (substr($recordData, 2, 2) == pack('CC', 0x01, 0x04)) { + // internal reference + // offset: 0; size: 2; number of sheet in this document + // offset: 2; size: 2; 0x01 0x04 + $this->_externalBooks[] = array( + 'type' => 'internal', + ); + } elseif (substr($recordData, 0, 4) == pack('vCC', 0x0001, 0x01, 0x3A)) { + // add-in function + // offset: 0; size: 2; 0x0001 + $this->_externalBooks[] = array( + 'type' => 'addInFunction', + ); + } elseif (substr($recordData, 0, 2) == pack('v', 0x0000)) { + // DDE links, OLE links + // offset: 0; size: 2; 0x0000 + // offset: 2; size: var; encoded source document name + $this->_externalBooks[] = array( + 'type' => 'DDEorOLE', + ); + } + } + + + /** + * Read EXTERNNAME record. + */ + private function _readExternName() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // external sheet references provided for named cells + if ($this->_version == self::XLS_BIFF8) { + // offset: 0; size: 2; options + $options = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; + + // offset: 4; size: 2; not used + + // offset: 6; size: var + $nameString = self::_readUnicodeStringShort(substr($recordData, 6)); + + // offset: var; size: var; formula data + $offset = 6 + $nameString['size']; + $formula = $this->_getFormulaFromStructure(substr($recordData, $offset)); + + $this->_externalNames[] = array( + 'name' => $nameString['value'], + 'formula' => $formula, + ); + } + } + + + /** + * Read EXTERNSHEET record + */ + private function _readExternSheet() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // external sheet references provided for named cells + if ($this->_version == self::XLS_BIFF8) { + // offset: 0; size: 2; number of following ref structures + $nm = self::_GetInt2d($recordData, 0); + for ($i = 0; $i < $nm; ++$i) { + $this->_ref[] = array( + // offset: 2 + 6 * $i; index to EXTERNALBOOK record + 'externalBookIndex' => self::_GetInt2d($recordData, 2 + 6 * $i), + // offset: 4 + 6 * $i; index to first sheet in EXTERNALBOOK record + 'firstSheetIndex' => self::_GetInt2d($recordData, 4 + 6 * $i), + // offset: 6 + 6 * $i; index to last sheet in EXTERNALBOOK record + 'lastSheetIndex' => self::_GetInt2d($recordData, 6 + 6 * $i), + ); + } + } + } + + + /** + * DEFINEDNAME + * + * This record is part of a Link Table. It contains the name + * and the token array of an internal defined name. Token + * arrays of defined names contain tokens with aberrant + * token classes. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readDefinedName() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8) { + // retrieves named cells + + // offset: 0; size: 2; option flags + $opts = self::_GetInt2d($recordData, 0); + + // bit: 5; mask: 0x0020; 0 = user-defined name, 1 = built-in-name + $isBuiltInName = (0x0020 & $opts) >> 5; + + // offset: 2; size: 1; keyboard shortcut + + // offset: 3; size: 1; length of the name (character count) + $nlen = ord($recordData{3}); + + // offset: 4; size: 2; size of the formula data (it can happen that this is zero) + // note: there can also be additional data, this is not included in $flen + $flen = self::_GetInt2d($recordData, 4); + + // offset: 8; size: 2; 0=Global name, otherwise index to sheet (1-based) + $scope = self::_GetInt2d($recordData, 8); + + // offset: 14; size: var; Name (Unicode string without length field) + $string = self::_readUnicodeString(substr($recordData, 14), $nlen); + + // offset: var; size: $flen; formula data + $offset = 14 + $string['size']; + $formulaStructure = pack('v', $flen) . substr($recordData, $offset); + + try { + $formula = $this->_getFormulaFromStructure($formulaStructure); + } catch (PHPExcel_Exception $e) { + $formula = ''; + } + + $this->_definedname[] = array( + 'isBuiltInName' => $isBuiltInName, + 'name' => $string['value'], + 'formula' => $formula, + 'scope' => $scope, + ); + } + } + + + /** + * Read MSODRAWINGGROUP record + */ + private function _readMsoDrawingGroup() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + $this->_drawingGroupData .= $recordData; + } + + + /** + * SST - Shared String Table + * + * This record contains a list of all strings used anywhere + * in the workbook. Each string occurs only once. The + * workbook uses indexes into the list to reference the + * strings. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + **/ + private function _readSst() + { + // offset within (spliced) record data + $pos = 0; + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + + $recordData = $splicedRecordData['recordData']; + $spliceOffsets = $splicedRecordData['spliceOffsets']; + + // offset: 0; size: 4; total number of strings in the workbook + $pos += 4; + + // offset: 4; size: 4; number of following strings ($nm) + $nm = self::_GetInt4d($recordData, 4); + $pos += 4; + + // loop through the Unicode strings (16-bit length) + for ($i = 0; $i < $nm; ++$i) { + // number of characters in the Unicode string + $numChars = self::_GetInt2d($recordData, $pos); + $pos += 2; + + // option flags + $optionFlags = ord($recordData{$pos}); + ++$pos; + + // bit: 0; mask: 0x01; 0 = compressed; 1 = uncompressed + $isCompressed = (($optionFlags & 0x01) == 0) ; + + // bit: 2; mask: 0x02; 0 = ordinary; 1 = Asian phonetic + $hasAsian = (($optionFlags & 0x04) != 0); + + // bit: 3; mask: 0x03; 0 = ordinary; 1 = Rich-Text + $hasRichText = (($optionFlags & 0x08) != 0); + + if ($hasRichText) { + // number of Rich-Text formatting runs + $formattingRuns = self::_GetInt2d($recordData, $pos); + $pos += 2; + } + + if ($hasAsian) { + // size of Asian phonetic setting + $extendedRunLength = self::_GetInt4d($recordData, $pos); + $pos += 4; + } + + // expected byte length of character array if not split + $len = ($isCompressed) ? $numChars : $numChars * 2; + + // look up limit position + foreach ($spliceOffsets as $spliceOffset) { + // it can happen that the string is empty, therefore we need + // <= and not just < + if ($pos <= $spliceOffset) { + $limitpos = $spliceOffset; + break; + } + } + + if ($pos + $len <= $limitpos) { + // character array is not split between records + + $retstr = substr($recordData, $pos, $len); + $pos += $len; + } else { + // character array is split between records + + // first part of character array + $retstr = substr($recordData, $pos, $limitpos - $pos); + + $bytesRead = $limitpos - $pos; + + // remaining characters in Unicode string + $charsLeft = $numChars - (($isCompressed) ? $bytesRead : ($bytesRead / 2)); + + $pos = $limitpos; + + // keep reading the characters + while ($charsLeft > 0) { + // look up next limit position, in case the string span more than one continue record + foreach ($spliceOffsets as $spliceOffset) { + if ($pos < $spliceOffset) { + $limitpos = $spliceOffset; + break; + } + } + + // repeated option flags + // OpenOffice.org documentation 5.21 + $option = ord($recordData{$pos}); + ++$pos; + + if ($isCompressed && ($option == 0)) { + // 1st fragment compressed + // this fragment compressed + $len = min($charsLeft, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len; + $isCompressed = true; + } elseif (!$isCompressed && ($option != 0)) { + // 1st fragment uncompressed + // this fragment uncompressed + $len = min($charsLeft * 2, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len / 2; + $isCompressed = false; + } elseif (!$isCompressed && ($option == 0)) { + // 1st fragment uncompressed + // this fragment compressed + $len = min($charsLeft, $limitpos - $pos); + for ($j = 0; $j < $len; ++$j) { + $retstr .= $recordData{$pos + $j} . chr(0); + } + $charsLeft -= $len; + $isCompressed = false; + } else { + // 1st fragment compressed + // this fragment uncompressed + $newstr = ''; + for ($j = 0; $j < strlen($retstr); ++$j) { + $newstr .= $retstr[$j] . chr(0); + } + $retstr = $newstr; + $len = min($charsLeft * 2, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len / 2; + $isCompressed = false; + } + + $pos += $len; + } + } + + // convert to UTF-8 + $retstr = self::_encodeUTF16($retstr, $isCompressed); + + // read additional Rich-Text information, if any + $fmtRuns = array(); + if ($hasRichText) { + // list of formatting runs + for ($j = 0; $j < $formattingRuns; ++$j) { + // first formatted character; zero-based + $charPos = self::_GetInt2d($recordData, $pos + $j * 4); + + // index to font record + $fontIndex = self::_GetInt2d($recordData, $pos + 2 + $j * 4); + + $fmtRuns[] = array( + 'charPos' => $charPos, + 'fontIndex' => $fontIndex, + ); + } + $pos += 4 * $formattingRuns; + } + + // read additional Asian phonetics information, if any + if ($hasAsian) { + // For Asian phonetic settings, we skip the extended string data + $pos += $extendedRunLength; + } + + // store the shared sting + $this->_sst[] = array( + 'value' => $retstr, + 'fmtRuns' => $fmtRuns, + ); + } + + // _getSplicedRecordData() takes care of moving current position in data stream + } + + + /** + * Read PRINTGRIDLINES record + */ + private function _readPrintGridlines() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + // offset: 0; size: 2; 0 = do not print sheet grid lines; 1 = print sheet gridlines + $printGridlines = (bool) self::_GetInt2d($recordData, 0); + $this->_phpSheet->setPrintGridlines($printGridlines); + } + } + + + /** + * Read DEFAULTROWHEIGHT record + */ + private function _readDefaultRowHeight() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; option flags + // offset: 2; size: 2; default height for unused rows, (twips 1/20 point) + $height = self::_GetInt2d($recordData, 2); + $this->_phpSheet->getDefaultRowDimension()->setRowHeight($height / 20); + } + + + /** + * Read SHEETPR record + */ + private function _readSheetPr() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2 + + // bit: 6; mask: 0x0040; 0 = outline buttons above outline group + $isSummaryBelow = (0x0040 & self::_GetInt2d($recordData, 0)) >> 6; + $this->_phpSheet->setShowSummaryBelow($isSummaryBelow); + + // bit: 7; mask: 0x0080; 0 = outline buttons left of outline group + $isSummaryRight = (0x0080 & self::_GetInt2d($recordData, 0)) >> 7; + $this->_phpSheet->setShowSummaryRight($isSummaryRight); + + // bit: 8; mask: 0x100; 0 = scale printout in percent, 1 = fit printout to number of pages + // this corresponds to radio button setting in page setup dialog in Excel + $this->_isFitToPages = (bool) ((0x0100 & self::_GetInt2d($recordData, 0)) >> 8); + } + + + /** + * Read HORIZONTALPAGEBREAKS record + */ + private function _readHorizontalPageBreaks() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + // offset: 0; size: 2; number of the following row index structures + $nm = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 6 * $nm; list of $nm row index structures + for ($i = 0; $i < $nm; ++$i) { + $r = self::_GetInt2d($recordData, 2 + 6 * $i); + $cf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); + $cl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); + + // not sure why two column indexes are necessary? + $this->_phpSheet->setBreakByColumnAndRow($cf, $r, PHPExcel_Worksheet::BREAK_ROW); + } + } + } + + + /** + * Read VERTICALPAGEBREAKS record + */ + private function _readVerticalPageBreaks() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + // offset: 0; size: 2; number of the following column index structures + $nm = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 6 * $nm; list of $nm row index structures + for ($i = 0; $i < $nm; ++$i) { + $c = self::_GetInt2d($recordData, 2 + 6 * $i); + $rf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); + $rl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); + + // not sure why two row indexes are necessary? + $this->_phpSheet->setBreakByColumnAndRow($c, $rf, PHPExcel_Worksheet::BREAK_COLUMN); + } + } + } + + + /** + * Read HEADER record + */ + private function _readHeader() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: var + // realized that $recordData can be empty even when record exists + if ($recordData) { + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + } else { + $string = $this->_readByteStringShort($recordData); + } + + $this->_phpSheet->getHeaderFooter()->setOddHeader($string['value']); + $this->_phpSheet->getHeaderFooter()->setEvenHeader($string['value']); + } + } + } + + + /** + * Read FOOTER record + */ + private function _readFooter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: var + // realized that $recordData can be empty even when record exists + if ($recordData) { + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + } else { + $string = $this->_readByteStringShort($recordData); + } + $this->_phpSheet->getHeaderFooter()->setOddFooter($string['value']); + $this->_phpSheet->getHeaderFooter()->setEvenFooter($string['value']); + } + } + } + + + /** + * Read HCENTER record + */ + private function _readHcenter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0 = print sheet left aligned, 1 = print sheet centered horizontally + $isHorizontalCentered = (bool) self::_GetInt2d($recordData, 0); + + $this->_phpSheet->getPageSetup()->setHorizontalCentered($isHorizontalCentered); + } + } + + + /** + * Read VCENTER record + */ + private function _readVcenter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0 = print sheet aligned at top page border, 1 = print sheet vertically centered + $isVerticalCentered = (bool) self::_GetInt2d($recordData, 0); + + $this->_phpSheet->getPageSetup()->setVerticalCentered($isVerticalCentered); + } + } + + + /** + * Read LEFTMARGIN record + */ + private function _readLeftMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setLeft(self::_extractNumber($recordData)); + } + } + + + /** + * Read RIGHTMARGIN record + */ + private function _readRightMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setRight(self::_extractNumber($recordData)); + } + } + + + /** + * Read TOPMARGIN record + */ + private function _readTopMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setTop(self::_extractNumber($recordData)); + } + } + + + /** + * Read BOTTOMMARGIN record + */ + private function _readBottomMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setBottom(self::_extractNumber($recordData)); + } + } + + + /** + * Read PAGESETUP record + */ + private function _readPageSetup() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; paper size + $paperSize = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; scaling factor + $scale = self::_GetInt2d($recordData, 2); + + // offset: 6; size: 2; fit worksheet width to this number of pages, 0 = use as many as needed + $fitToWidth = self::_GetInt2d($recordData, 6); + + // offset: 8; size: 2; fit worksheet height to this number of pages, 0 = use as many as needed + $fitToHeight = self::_GetInt2d($recordData, 8); + + // offset: 10; size: 2; option flags + + // bit: 1; mask: 0x0002; 0=landscape, 1=portrait + $isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1; + + // bit: 2; mask: 0x0004; 1= paper size, scaling factor, paper orient. not init + // when this bit is set, do not use flags for those properties + $isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2; + + if (!$isNotInit) { + $this->_phpSheet->getPageSetup()->setPaperSize($paperSize); + switch ($isPortrait) { + case 0: + $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); + break; + case 1: + $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); + break; + } + + $this->_phpSheet->getPageSetup()->setScale($scale, false); + $this->_phpSheet->getPageSetup()->setFitToPage((bool) $this->_isFitToPages); + $this->_phpSheet->getPageSetup()->setFitToWidth($fitToWidth, false); + $this->_phpSheet->getPageSetup()->setFitToHeight($fitToHeight, false); + } + + // offset: 16; size: 8; header margin (IEEE 754 floating-point value) + $marginHeader = self::_extractNumber(substr($recordData, 16, 8)); + $this->_phpSheet->getPageMargins()->setHeader($marginHeader); + + // offset: 24; size: 8; footer margin (IEEE 754 floating-point value) + $marginFooter = self::_extractNumber(substr($recordData, 24, 8)); + $this->_phpSheet->getPageMargins()->setFooter($marginFooter); + } + } + + + /** + * PROTECT - Sheet protection (BIFF2 through BIFF8) + * if this record is omitted, then it also means no sheet protection + */ + private function _readProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; + + // bit 0, mask 0x01; 1 = sheet is protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + $this->_phpSheet->getProtection()->setSheet((bool)$bool); + } + + + /** + * SCENPROTECT + */ + private function _readScenProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; + + // bit: 0, mask 0x01; 1 = scenarios are protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + + $this->_phpSheet->getProtection()->setScenarios((bool)$bool); + } + + + /** + * OBJECTPROTECT + */ + private function _readObjectProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; + + // bit: 0, mask 0x01; 1 = objects are protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + + $this->_phpSheet->getProtection()->setObjects((bool)$bool); + } + + + /** + * PASSWORD - Sheet protection (hashed) password (BIFF2 through BIFF8) + */ + private function _readPassword() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 16-bit hash value of password + $password = strtoupper(dechex(self::_GetInt2d($recordData, 0))); // the hashed password + $this->_phpSheet->getProtection()->setPassword($password, true); + } + } + + + /** + * Read DEFCOLWIDTH record + */ + private function _readDefColWidth() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; default column width + $width = self::_GetInt2d($recordData, 0); + if ($width != 8) { + $this->_phpSheet->getDefaultColumnDimension()->setWidth($width); + } + } + + + /** + * Read COLINFO record + */ + private function _readColInfo() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index to first column in range + $fc = self::_GetInt2d($recordData, 0); // first column index + + // offset: 2; size: 2; index to last column in range + $lc = self::_GetInt2d($recordData, 2); // first column index + + // offset: 4; size: 2; width of the column in 1/256 of the width of the zero character + $width = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 2; index to XF record for default column formatting + $xfIndex = self::_GetInt2d($recordData, 6); + + // offset: 8; size: 2; option flags + // bit: 0; mask: 0x0001; 1= columns are hidden + $isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0; + + // bit: 10-8; mask: 0x0700; outline level of the columns (0 = no outline) + $level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8; + + // bit: 12; mask: 0x1000; 1 = collapsed + $isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12; + + // offset: 10; size: 2; not used + + for ($i = $fc; $i <= $lc; ++$i) { + if ($lc == 255 || $lc == 256) { + $this->_phpSheet->getDefaultColumnDimension()->setWidth($width / 256); + break; + } + $this->_phpSheet->getColumnDimensionByColumn($i)->setWidth($width / 256); + $this->_phpSheet->getColumnDimensionByColumn($i)->setVisible(!$isHidden); + $this->_phpSheet->getColumnDimensionByColumn($i)->setOutlineLevel($level); + $this->_phpSheet->getColumnDimensionByColumn($i)->setCollapsed($isCollapsed); + $this->_phpSheet->getColumnDimensionByColumn($i)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * ROW + * + * This record contains the properties of a single row in a + * sheet. Rows and cells in a sheet are divided into blocks + * of 32 rows. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readRow() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index of this row + $r = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column of the first cell which is described by a cell record + + // offset: 4; size: 2; index to column of the last cell which is described by a cell record, increased by 1 + + // offset: 6; size: 2; + + // bit: 14-0; mask: 0x7FFF; height of the row, in twips = 1/20 of a point + $height = (0x7FFF & self::_GetInt2d($recordData, 6)) >> 0; + + // bit: 15: mask: 0x8000; 0 = row has custom height; 1= row has default height + $useDefaultHeight = (0x8000 & self::_GetInt2d($recordData, 6)) >> 15; + + if (!$useDefaultHeight) { + $this->_phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20); + } + + // offset: 8; size: 2; not used + + // offset: 10; size: 2; not used in BIFF5-BIFF8 + + // offset: 12; size: 4; option flags and default row formatting + + // bit: 2-0: mask: 0x00000007; outline level of the row + $level = (0x00000007 & self::_GetInt4d($recordData, 12)) >> 0; + $this->_phpSheet->getRowDimension($r + 1)->setOutlineLevel($level); + + // bit: 4; mask: 0x00000010; 1 = outline group start or ends here... and is collapsed + $isCollapsed = (0x00000010 & self::_GetInt4d($recordData, 12)) >> 4; + $this->_phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed); + + // bit: 5; mask: 0x00000020; 1 = row is hidden + $isHidden = (0x00000020 & self::_GetInt4d($recordData, 12)) >> 5; + $this->_phpSheet->getRowDimension($r + 1)->setVisible(!$isHidden); + + // bit: 7; mask: 0x00000080; 1 = row has explicit format + $hasExplicitFormat = (0x00000080 & self::_GetInt4d($recordData, 12)) >> 7; + + // bit: 27-16; mask: 0x0FFF0000; only applies when hasExplicitFormat = 1; index to XF record + $xfIndex = (0x0FFF0000 & self::_GetInt4d($recordData, 12)) >> 16; + + if ($hasExplicitFormat) { + $this->_phpSheet->getRowDimension($r + 1)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read RK record + * This record represents a cell that contains an RK value + * (encoded integer or floating-point value). If a + * floating-point value cannot be encoded to an RK value, + * a NUMBER record will be written. This record replaces the + * record INTEGER written in BIFF2. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readRk() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 4; RK value + $rknum = self::_GetInt4d($recordData, 6); + $numValue = self::_GetIEEE754($rknum); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add style information + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + } + + + /** + * Read LABELSST record + * This record represents a cell that contains a string. It + * replaces the LABEL record and RSTRING record used in + * BIFF2-BIFF5. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readLabelSst() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 4; index to SST record + $index = self::_GetInt4d($recordData, 6); + + // add cell + if (($fmtRuns = $this->_sst[$index]['fmtRuns']) && !$this->_readDataOnly) { + // then we should treat as rich text + $richText = new PHPExcel_RichText(); + $charPos = 0; + $sstCount = count($this->_sst[$index]['fmtRuns']); + for ($i = 0; $i <= $sstCount; ++$i) { + if (isset($fmtRuns[$i])) { + $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos); + $charPos = $fmtRuns[$i]['charPos']; + } else { + $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, PHPExcel_Shared_String::CountCharacters($this->_sst[$index]['value'])); + } + + if (PHPExcel_Shared_String::CountCharacters($text) > 0) { + if ($i == 0) { // first text run, no style + $richText->createText($text); + } else { + $textRun = $richText->createTextRun($text); + if (isset($fmtRuns[$i - 1])) { + if ($fmtRuns[$i - 1]['fontIndex'] < 4) { + $fontIndex = $fmtRuns[$i - 1]['fontIndex']; + } else { + // this has to do with that index 4 is omitted in all BIFF versions for some strange reason + // check the OpenOffice documentation of the FONT record + $fontIndex = $fmtRuns[$i - 1]['fontIndex'] - 1; + } + $textRun->setFont(clone $this->_objFonts[$fontIndex]); + } + } + } + } + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING); + } else { + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($this->_sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING); + } + + if (!$this->_readDataOnly) { + // add style information + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read MULRK record + * This record represents a cell range containing RK value + * cells. All cells are located in the same row. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMulRk() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first column + $colFirst = self::_GetInt2d($recordData, 2); + + // offset: var; size: 2; index to last column + $colLast = self::_GetInt2d($recordData, $length - 2); + $columns = $colLast - $colFirst + 1; + + // offset within record data + $offset = 4; + + for ($i = 0; $i < $columns; ++$i) { + $columnString = PHPExcel_Cell::stringFromColumnIndex($colFirst + $i); + + // Read cell? + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + // offset: var; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, $offset); + + // offset: var; size: 4; RK value + $numValue = self::_GetIEEE754(self::_GetInt4d($recordData, $offset + 2)); + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell value + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + + $offset += 6; + } + } + + + /** + * Read NUMBER record + * This record represents a cell that contains a + * floating-point value. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readNumber() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + // offset 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + $numValue = self::_extractNumber(substr($recordData, 6, 8)); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell value + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + } + + + /** + * Read FORMULA record + perhaps a following STRING record if formula result is a string + * This record contains the token array and the result of a + * formula cell. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readFormula() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; col index + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // offset: 20: size: variable; formula structure + $formulaStructure = substr($recordData, 20); + + // offset: 14: size: 2; option flags, recalculate always, recalculate on open etc. + $options = self::_GetInt2d($recordData, 14); + + // bit: 0; mask: 0x0001; 1 = recalculate always + // bit: 1; mask: 0x0002; 1 = calculate on open + // bit: 2; mask: 0x0008; 1 = part of a shared formula + $isPartOfSharedFormula = (bool) (0x0008 & $options); + + // WARNING: + // We can apparently not rely on $isPartOfSharedFormula. Even when $isPartOfSharedFormula = true + // the formula data may be ordinary formula data, therefore we need to check + // explicitly for the tExp token (0x01) + $isPartOfSharedFormula = $isPartOfSharedFormula && ord($formulaStructure{2}) == 0x01; + + if ($isPartOfSharedFormula) { + // part of shared formula which means there will be a formula with a tExp token and nothing else + // get the base cell, grab tExp token + $baseRow = self::_GetInt2d($formulaStructure, 3); + $baseCol = self::_GetInt2d($formulaStructure, 5); + $this->_baseCell = PHPExcel_Cell::stringFromColumnIndex($baseCol). ($baseRow + 1); + } + + // Read cell? + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + if ($isPartOfSharedFormula) { + // formula is added to this cell after the sheet has been read + $this->_sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell; + } + + // offset: 16: size: 4; not used + + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 8; result of the formula + if ((ord($recordData{6}) == 0) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { + // String formula. Result follows in appended STRING record + $dataType = PHPExcel_Cell_DataType::TYPE_STRING; + + // read possible SHAREDFMLA record + $code = self::_GetInt2d($this->_data, $this->_pos); + if ($code == self::XLS_Type_SHAREDFMLA) { + $this->_readSharedFmla(); + } + + // read STRING record + $value = $this->_readString(); + } elseif ((ord($recordData{6}) == 1) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + // Boolean formula. Result is in +2; 0=false, 1=true + $dataType = PHPExcel_Cell_DataType::TYPE_BOOL; + $value = (bool) ord($recordData{8}); + } elseif ((ord($recordData{6}) == 2) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + // Error formula. Error code is in +2 + $dataType = PHPExcel_Cell_DataType::TYPE_ERROR; + $value = self::_mapErrorCode(ord($recordData{8})); + } elseif ((ord($recordData{6}) == 3) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + // Formula result is a null string + $dataType = PHPExcel_Cell_DataType::TYPE_NULL; + $value = ''; + } else { + // forumla result is a number, first 14 bytes like _NUMBER record + $dataType = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $value = self::_extractNumber(substr($recordData, 6, 8)); + } + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // store the formula + if (!$isPartOfSharedFormula) { + // not part of shared formula + // add cell value. If we can read formula, populate with formula, otherwise just used cached value + try { + if ($this->_version != self::XLS_BIFF8) { + throw new PHPExcel_Reader_Exception('Not BIFF8. Can only read BIFF8 formulas'); + } + $formula = $this->_getFormulaFromStructure($formulaStructure); // get formula in human language + $cell->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + + } catch (PHPExcel_Exception $e) { + $cell->setValueExplicit($value, $dataType); + } + } else { + if ($this->_version == self::XLS_BIFF8) { + // do nothing at this point, formula id added later in the code + } else { + $cell->setValueExplicit($value, $dataType); + } + } + + // store the cached calculated value + $cell->setCalculatedValue($value); + } + } + + + /** + * Read a SHAREDFMLA record. This function just stores the binary shared formula in the reader, + * which usually contains relative references. + * These will be used to construct the formula in each shared formula part after the sheet is read. + */ + private function _readSharedFmla() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0, size: 6; cell range address of the area used by the shared formula, not used for anything + $cellRange = substr($recordData, 0, 6); + $cellRange = $this->_readBIFF5CellRangeAddressFixed($cellRange); // note: even BIFF8 uses BIFF5 syntax + + // offset: 6, size: 1; not used + + // offset: 7, size: 1; number of existing FORMULA records for this shared formula + $no = ord($recordData{7}); + + // offset: 8, size: var; Binary token array of the shared formula + $formula = substr($recordData, 8); + + // at this point we only store the shared formula for later use + $this->_sharedFormulas[$this->_baseCell] = $formula; + } + + + /** + * Read a STRING record from current stream position and advance the stream pointer to next record + * This record is used for storing result from FORMULA record when it is a string, and + * it occurs directly after the FORMULA record + * + * @return string The string contents as UTF-8 + */ + private function _readString() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + $value = $string['value']; + } else { + $string = $this->_readByteStringLong($recordData); + $value = $string['value']; + } + + return $value; + } + + + /** + * Read BOOLERR record + * This record represents a Boolean value or error value + * cell. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readBoolErr() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; column index + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 1; the boolean value or error value + $boolErr = ord($recordData{6}); + + // offset: 7; size: 1; 0=boolean; 1=error + $isError = ord($recordData{7}); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + switch ($isError) { + case 0: // boolean + $value = (bool) $boolErr; + + // add cell value + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL); + break; + case 1: // error type + $value = self::_mapErrorCode($boolErr); + + // add cell value + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_ERROR); + break; + } + + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read MULBLANK record + * This record represents a cell range of empty cells. All + * cells are located in the same row + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMulBlank() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first column + $fc = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 2 x nc; list of indexes to XF records + // add style information + if (!$this->_readDataOnly) { + for ($i = 0; $i < $length / 2 - 3; ++$i) { + $columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i); + + // Read cell? + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + $xfIndex = self::_GetInt2d($recordData, 4 + 2 * $i); + $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + // offset: 6; size 2; index to last column (not needed) + } + + + /** + * Read LABEL record + * This record represents a cell that contains a string. In + * BIFF8 it is usually replaced by the LABELSST record. + * Excel still uses this record, if it copies unformatted + * text cells to the clipboard. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readLabel() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // add cell value + // todo: what if string is very long? continue record + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong(substr($recordData, 6)); + $value = $string['value']; + } else { + $string = $this->_readByteStringLong(substr($recordData, 6)); + $value = $string['value']; + } + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); + + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read BLANK record + */ + private function _readBlank() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; col index + $col = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($col); + + // Read cell? + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // add style information + if (!$this->_readDataOnly) { + $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + + } + + + /** + * Read MSODRAWING record + */ + private function _readMsoDrawing() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + $this->_drawingData .= $recordData; + } + + + /** + * Read OBJ record + */ + private function _readObj() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly || $this->_version != self::XLS_BIFF8) { + return; + } + + // recordData consists of an array of subrecords looking like this: + // ft: 2 bytes; ftCmo type (0x15) + // cb: 2 bytes; size in bytes of ftCmo data + // ot: 2 bytes; Object Type + // id: 2 bytes; Object id number + // grbit: 2 bytes; Option Flags + // data: var; subrecord data + + // for now, we are just interested in the second subrecord containing the object type + $ftCmoType = self::_GetInt2d($recordData, 0); + $cbCmoSize = self::_GetInt2d($recordData, 2); + $otObjType = self::_GetInt2d($recordData, 4); + $idObjID = self::_GetInt2d($recordData, 6); + $grbitOpts = self::_GetInt2d($recordData, 6); + + $this->_objs[] = array( + 'ftCmoType' => $ftCmoType, + 'cbCmoSize' => $cbCmoSize, + 'otObjType' => $otObjType, + 'idObjID' => $idObjID, + 'grbitOpts' => $grbitOpts + ); + $this->textObjRef = $idObjID; + +// echo '<b>_readObj()</b><br />'; +// var_dump(end($this->_objs)); +// echo '<br />'; + } + + + /** + * Read WINDOW2 record + */ + private function _readWindow2() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; option flags + $options = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first visible row + $firstVisibleRow = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 2; index to first visible colum + $firstVisibleColumn = self::_GetInt2d($recordData, 4); + if ($this->_version === self::XLS_BIFF8) { + // offset: 8; size: 2; not used + // offset: 10; size: 2; cached magnification factor in page break preview (in percent); 0 = Default (60%) + // offset: 12; size: 2; cached magnification factor in normal view (in percent); 0 = Default (100%) + // offset: 14; size: 4; not used + $zoomscaleInPageBreakPreview = self::_GetInt2d($recordData, 10); + if ($zoomscaleInPageBreakPreview === 0) { + $zoomscaleInPageBreakPreview = 60; + } + $zoomscaleInNormalView = self::_GetInt2d($recordData, 12); + if ($zoomscaleInNormalView === 0) { + $zoomscaleInNormalView = 100; + } + } + + // bit: 1; mask: 0x0002; 0 = do not show gridlines, 1 = show gridlines + $showGridlines = (bool) ((0x0002 & $options) >> 1); + $this->_phpSheet->setShowGridlines($showGridlines); + + // bit: 2; mask: 0x0004; 0 = do not show headers, 1 = show headers + $showRowColHeaders = (bool) ((0x0004 & $options) >> 2); + $this->_phpSheet->setShowRowColHeaders($showRowColHeaders); + + // bit: 3; mask: 0x0008; 0 = panes are not frozen, 1 = panes are frozen + $this->_frozen = (bool) ((0x0008 & $options) >> 3); + + // bit: 6; mask: 0x0040; 0 = columns from left to right, 1 = columns from right to left + $this->_phpSheet->setRightToLeft((bool)((0x0040 & $options) >> 6)); + + // bit: 10; mask: 0x0400; 0 = sheet not active, 1 = sheet active + $isActive = (bool) ((0x0400 & $options) >> 10); + if ($isActive) { + $this->_phpExcel->setActiveSheetIndex($this->_phpExcel->getIndex($this->_phpSheet)); + } + + // bit: 11; mask: 0x0800; 0 = normal view, 1 = page break view + $isPageBreakPreview = (bool) ((0x0800 & $options) >> 11); + + //FIXME: set $firstVisibleRow and $firstVisibleColumn + + if ($this->_phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { + //NOTE: this setting is inferior to page layout view(Excel2007-) + $view = $isPageBreakPreview ? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW : PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL; + $this->_phpSheet->getSheetView()->setView($view); + if ($this->_version === self::XLS_BIFF8) { + $zoomScale = $isPageBreakPreview ? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView; + $this->_phpSheet->getSheetView()->setZoomScale($zoomScale); + $this->_phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView); + } + } + } + + /** + * Read PLV Record(Created by Excel2007 or upper) + */ + private function _readPageLayoutView() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + //var_dump(unpack("vrt/vgrbitFrt/V2reserved/vwScalePLV/vgrbit", $recordData)); + + // offset: 0; size: 2; rt + //->ignore + $rt = self::_GetInt2d($recordData, 0); + // offset: 2; size: 2; grbitfr + //->ignore + $grbitFrt = self::_GetInt2d($recordData, 2); + // offset: 4; size: 8; reserved + //->ignore + + // offset: 12; size 2; zoom scale + $wScalePLV = self::_GetInt2d($recordData, 12); + // offset: 14; size 2; grbit + $grbit = self::_GetInt2d($recordData, 14); + + // decomprise grbit + $fPageLayoutView = $grbit & 0x01; + $fRulerVisible = ($grbit >> 1) & 0x01; //no support + $fWhitespaceHidden = ($grbit >> 3) & 0x01; //no support + + if ($fPageLayoutView === 1) { + $this->_phpSheet->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT); + $this->_phpSheet->getSheetView()->setZoomScale($wScalePLV); //set by Excel2007 only if SHEETVIEW_PAGE_LAYOUT + } + //otherwise, we cannot know whether SHEETVIEW_PAGE_LAYOUT or SHEETVIEW_PAGE_BREAK_PREVIEW. + } + + /** + * Read SCL record + */ + private function _readScl() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; numerator of the view magnification + $numerator = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; numerator of the view magnification + $denumerator = self::_GetInt2d($recordData, 2); + + // set the zoom scale (in percent) + $this->_phpSheet->getSheetView()->setZoomScale($numerator * 100 / $denumerator); + } + + + /** + * Read PANE record + */ + private function _readPane() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; position of vertical split + $px = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; position of horizontal split + $py = self::_GetInt2d($recordData, 2); + + if ($this->_frozen) { + // frozen panes + $this->_phpSheet->freezePane(PHPExcel_Cell::stringFromColumnIndex($px) . ($py + 1)); + } else { + // unfrozen panes; split windows; not supported by PHPExcel core + } + } + } + + + /** + * Read SELECTION record. There is one such record for each pane in the sheet. + */ + private function _readSelection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 1; pane identifier + $paneId = ord($recordData{0}); + + // offset: 1; size: 2; index to row of the active cell + $r = self::_GetInt2d($recordData, 1); + + // offset: 3; size: 2; index to column of the active cell + $c = self::_GetInt2d($recordData, 3); + + // offset: 5; size: 2; index into the following cell range list to the + // entry that contains the active cell + $index = self::_GetInt2d($recordData, 5); + + // offset: 7; size: var; cell range address list containing all selected cell ranges + $data = substr($recordData, 7); + $cellRangeAddressList = $this->_readBIFF5CellRangeAddressList($data); // note: also BIFF8 uses BIFF5 syntax + + $selectedCells = $cellRangeAddressList['cellRangeAddresses'][0]; + + // first row '1' + last row '16384' indicates that full column is selected (apparently also in BIFF8!) + if (preg_match('/^([A-Z]+1\:[A-Z]+)16384$/', $selectedCells)) { + $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)16384$/', '${1}1048576', $selectedCells); + } + + // first row '1' + last row '65536' indicates that full column is selected + if (preg_match('/^([A-Z]+1\:[A-Z]+)65536$/', $selectedCells)) { + $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)65536$/', '${1}1048576', $selectedCells); + } + + // first column 'A' + last column 'IV' indicates that full row is selected + if (preg_match('/^(A[0-9]+\:)IV([0-9]+)$/', $selectedCells)) { + $selectedCells = preg_replace('/^(A[0-9]+\:)IV([0-9]+)$/', '${1}XFD${2}', $selectedCells); + } + + $this->_phpSheet->setSelectedCells($selectedCells); + } + } + + + private function _includeCellRangeFiltered($cellRangeAddress) + { + $includeCellRange = true; + if ($this->getReadFilter() !== null) { + $includeCellRange = false; + $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($cellRangeAddress); + $rangeBoundaries[1][0]++; + for ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; $row++) { + for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; $column++) { + if ($this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { + $includeCellRange = true; + break 2; + } + } + } + } + return $includeCellRange; + } + + + /** + * MERGEDCELLS + * + * This record contains the addresses of merged cell ranges + * in the current sheet. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMergedCells() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData); + foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) { + if ((strpos($cellRangeAddress, ':') !== false) && + ($this->_includeCellRangeFiltered($cellRangeAddress))) { + $this->_phpSheet->mergeCells($cellRangeAddress); + } + } + } + } + + + /** + * Read HYPERLINK record + */ + private function _readHyperLink() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8; cell range address of all cells containing this hyperlink + try { + $cellRange = $this->_readBIFF8CellRangeAddressFixed($recordData, 0, 8); + } catch (PHPExcel_Exception $e) { + return; + } + + // offset: 8, size: 16; GUID of StdLink + + // offset: 24, size: 4; unknown value + + // offset: 28, size: 4; option flags + // bit: 0; mask: 0x00000001; 0 = no link or extant, 1 = file link or URL + $isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0; + + // bit: 1; mask: 0x00000002; 0 = relative path, 1 = absolute path or URL + $isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1; + + // bit: 2 (and 4); mask: 0x00000014; 0 = no description + $hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2; + + // bit: 3; mask: 0x00000008; 0 = no text, 1 = has text + $hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3; + + // bit: 7; mask: 0x00000080; 0 = no target frame, 1 = has target frame + $hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7; + + // bit: 8; mask: 0x00000100; 0 = file link or URL, 1 = UNC path (inc. server name) + $isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8; + + // offset within record data + $offset = 32; + + if ($hasDesc) { + // offset: 32; size: var; character count of description text + $dl = self::_GetInt4d($recordData, 32); + // offset: 36; size: var; character array of description text, no Unicode string header, always 16-bit characters, zero terminated + $desc = self::_encodeUTF16(substr($recordData, 36, 2 * ($dl - 1)), false); + $offset += 4 + 2 * $dl; + } + if ($hasFrame) { + $fl = self::_GetInt4d($recordData, $offset); + $offset += 4 + 2 * $fl; + } + + // detect type of hyperlink (there are 4 types) + $hyperlinkType = null; + + if ($isUNC) { + $hyperlinkType = 'UNC'; + } else if (!$isFileLinkOrUrl) { + $hyperlinkType = 'workbook'; + } else if (ord($recordData{$offset}) == 0x03) { + $hyperlinkType = 'local'; + } else if (ord($recordData{$offset}) == 0xE0) { + $hyperlinkType = 'URL'; + } + + switch ($hyperlinkType) { + case 'URL': + // section 5.58.2: Hyperlink containing a URL + // e.g. http://example.org/index.php + + // offset: var; size: 16; GUID of URL Moniker + $offset += 16; + // offset: var; size: 4; size (in bytes) of character array of the URL including trailing zero word + $us = self::_GetInt4d($recordData, $offset); + $offset += 4; + // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated + $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); + $nullOffset = strpos($url, 0x00); + if ($nullOffset) { + $url = substr($url, 0, $nullOffset); + } + $url .= $hasText ? '#' : ''; + $offset += $us; + break; + case 'local': + // section 5.58.3: Hyperlink to local file + // examples: + // mydoc.txt + // ../../somedoc.xls#Sheet!A1 + + // offset: var; size: 16; GUI of File Moniker + $offset += 16; + + // offset: var; size: 2; directory up-level count. + $upLevelCount = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 4; character count of the shortened file path and name, including trailing zero word + $sl = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // offset: var; size: sl; character array of the shortened file path and name in 8.3-DOS-format (compressed Unicode string) + $shortenedFilePath = substr($recordData, $offset, $sl); + $shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true); + $shortenedFilePath = substr($shortenedFilePath, 0, -1); // remove trailing zero + + $offset += $sl; + + // offset: var; size: 24; unknown sequence + $offset += 24; + + // extended file path + // offset: var; size: 4; size of the following file link field including string lenth mark + $sz = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // only present if $sz > 0 + if ($sz > 0) { + // offset: var; size: 4; size of the character array of the extended file path and name + $xl = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // offset: var; size 2; unknown + $offset += 2; + + // offset: var; size $xl; character array of the extended file path and name. + $extendedFilePath = substr($recordData, $offset, $xl); + $extendedFilePath = self::_encodeUTF16($extendedFilePath, false); + $offset += $xl; + } + + // construct the path + $url = str_repeat('..\\', $upLevelCount); + $url .= ($sz > 0) ? $extendedFilePath : $shortenedFilePath; // use extended path if available + $url .= $hasText ? '#' : ''; + + break; + case 'UNC': + // section 5.58.4: Hyperlink to a File with UNC (Universal Naming Convention) Path + // todo: implement + return; + case 'workbook': + // section 5.58.5: Hyperlink to the Current Workbook + // e.g. Sheet2!B1:C2, stored in text mark field + $url = 'sheet://'; + break; + default: + return; + } + + if ($hasText) { + // offset: var; size: 4; character count of text mark including trailing zero word + $tl = self::_GetInt4d($recordData, $offset); + $offset += 4; + // offset: var; size: var; character array of the text mark without the # sign, no Unicode header, always 16-bit characters, zero-terminated + $text = self::_encodeUTF16(substr($recordData, $offset, 2 * ($tl - 1)), false); + $url .= $text; + } + + // apply the hyperlink to all the relevant cells + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cellRange) as $coordinate) { + $this->_phpSheet->getCell($coordinate)->getHyperLink()->setUrl($url); + } + } + } + + + /** + * Read DATAVALIDATIONS record + */ + private function _readDataValidations() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + } + + + /** + * Read DATAVALIDATION record + */ + private function _readDataValidation() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 4; Options + $options = self::_GetInt4d($recordData, 0); + + // bit: 0-3; mask: 0x0000000F; type + $type = (0x0000000F & $options) >> 0; + switch ($type) { + case 0x00: + $type = PHPExcel_Cell_DataValidation::TYPE_NONE; + break; + case 0x01: + $type = PHPExcel_Cell_DataValidation::TYPE_WHOLE; + break; + case 0x02: + $type = PHPExcel_Cell_DataValidation::TYPE_DECIMAL; + break; + case 0x03: + $type = PHPExcel_Cell_DataValidation::TYPE_LIST; + break; + case 0x04: + $type = PHPExcel_Cell_DataValidation::TYPE_DATE; + break; + case 0x05: + $type = PHPExcel_Cell_DataValidation::TYPE_TIME; + break; + case 0x06: + $type = PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH; + break; + case 0x07: + $type = PHPExcel_Cell_DataValidation::TYPE_CUSTOM; + break; + } + + // bit: 4-6; mask: 0x00000070; error type + $errorStyle = (0x00000070 & $options) >> 4; + switch ($errorStyle) { + case 0x00: + $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; + break; + case 0x01: + $errorStyle = PHPExcel_Cell_DataValidation::STYLE_WARNING; + break; + case 0x02: + $errorStyle = PHPExcel_Cell_DataValidation::STYLE_INFORMATION; + break; + } + + // bit: 7; mask: 0x00000080; 1= formula is explicit (only applies to list) + // I have only seen cases where this is 1 + $explicitFormula = (0x00000080 & $options) >> 7; + + // bit: 8; mask: 0x00000100; 1= empty cells allowed + $allowBlank = (0x00000100 & $options) >> 8; + + // bit: 9; mask: 0x00000200; 1= suppress drop down arrow in list type validity + $suppressDropDown = (0x00000200 & $options) >> 9; + + // bit: 18; mask: 0x00040000; 1= show prompt box if cell selected + $showInputMessage = (0x00040000 & $options) >> 18; + + // bit: 19; mask: 0x00080000; 1= show error box if invalid values entered + $showErrorMessage = (0x00080000 & $options) >> 19; + + // bit: 20-23; mask: 0x00F00000; condition operator + $operator = (0x00F00000 & $options) >> 20; + switch ($operator) { + case 0x00: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN; + break; + case 0x01: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN; + break; + case 0x02: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_EQUAL; + break; + case 0x03: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL; + break; + case 0x04: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN; + break; + case 0x05: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN; + break; + case 0x06: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL; + break; + case 0x07: + $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL; + break; + } + + // offset: 4; size: var; title of the prompt box + $offset = 4; + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $promptTitle = $string['value'] !== chr(0) ? $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; title of the error box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $errorTitle = $string['value'] !== chr(0) ? $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; text of the prompt box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $prompt = $string['value'] !== chr(0) ? $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; text of the error box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $error = $string['value'] !== chr(0) ? $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: 2; size of the formula data for the first condition + $sz1 = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 2; not used + $offset += 2; + + // offset: var; size: $sz1; formula data for first condition (without size field) + $formula1 = substr($recordData, $offset, $sz1); + $formula1 = pack('v', $sz1) . $formula1; // prepend the length + try { + $formula1 = $this->_getFormulaFromStructure($formula1); + + // in list type validity, null characters are used as item separators + if ($type == PHPExcel_Cell_DataValidation::TYPE_LIST) { + $formula1 = str_replace(chr(0), ',', $formula1); + } + } catch (PHPExcel_Exception $e) { + return; + } + $offset += $sz1; + + // offset: var; size: 2; size of the formula data for the first condition + $sz2 = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 2; not used + $offset += 2; + + // offset: var; size: $sz2; formula data for second condition (without size field) + $formula2 = substr($recordData, $offset, $sz2); + $formula2 = pack('v', $sz2) . $formula2; // prepend the length + try { + $formula2 = $this->_getFormulaFromStructure($formula2); + } catch (PHPExcel_Exception $e) { + return; + } + $offset += $sz2; + + // offset: var; size: var; cell range address list with + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList(substr($recordData, $offset)); + $cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses']; + + foreach ($cellRangeAddresses as $cellRange) { + $stRange = $this->_phpSheet->shrinkRangeToFit($cellRange); + $stRange = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); + foreach ($stRange as $coordinate) { + $objValidation = $this->_phpSheet->getCell($coordinate)->getDataValidation(); + $objValidation->setType($type); + $objValidation->setErrorStyle($errorStyle); + $objValidation->setAllowBlank((bool)$allowBlank); + $objValidation->setShowInputMessage((bool)$showInputMessage); + $objValidation->setShowErrorMessage((bool)$showErrorMessage); + $objValidation->setShowDropDown(!$suppressDropDown); + $objValidation->setOperator($operator); + $objValidation->setErrorTitle($errorTitle); + $objValidation->setError($error); + $objValidation->setPromptTitle($promptTitle); + $objValidation->setPrompt($prompt); + $objValidation->setFormula1($formula1); + $objValidation->setFormula2($formula2); + } + } + } + + /** + * Read SHEETLAYOUT record. Stores sheet tab color information. + */ + private function _readSheetLayout() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // local pointer in record data + $offset = 0; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; repeated record identifier 0x0862 + + // offset: 2; size: 10; not used + + // offset: 12; size: 4; size of record data + // Excel 2003 uses size of 0x14 (documented), Excel 2007 uses size of 0x28 (not documented?) + $sz = self::_GetInt4d($recordData, 12); + + switch ($sz) { + case 0x14: + // offset: 16; size: 2; color index for sheet tab + $colorIndex = self::_GetInt2d($recordData, 16); + $color = self::_readColor($colorIndex, $this->_palette, $this->_version); + $this->_phpSheet->getTabColor()->setRGB($color['rgb']); + break; + case 0x28: + // TODO: Investigate structure for .xls SHEETLAYOUT record as saved by MS Office Excel 2007 + return; + break; + } + } + } + + + /** + * Read SHEETPROTECTION record (FEATHEADR) + */ + private function _readSheetProtection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; repeated record header + + // offset: 2; size: 2; FRT cell reference flag (=0 currently) + + // offset: 4; size: 8; Currently not used and set to 0 + + // offset: 12; size: 2; Shared feature type index (2=Enhanced Protetion, 4=SmartTag) + $isf = self::_GetInt2d($recordData, 12); + if ($isf != 2) { + return; + } + + // offset: 14; size: 1; =1 since this is a feat header + + // offset: 15; size: 4; size of rgbHdrSData + + // rgbHdrSData, assume "Enhanced Protection" + // offset: 19; size: 2; option flags + $options = self::_GetInt2d($recordData, 19); + + // bit: 0; mask 0x0001; 1 = user may edit objects, 0 = users must not edit objects + $bool = (0x0001 & $options) >> 0; + $this->_phpSheet->getProtection()->setObjects(!$bool); + + // bit: 1; mask 0x0002; edit scenarios + $bool = (0x0002 & $options) >> 1; + $this->_phpSheet->getProtection()->setScenarios(!$bool); + + // bit: 2; mask 0x0004; format cells + $bool = (0x0004 & $options) >> 2; + $this->_phpSheet->getProtection()->setFormatCells(!$bool); + + // bit: 3; mask 0x0008; format columns + $bool = (0x0008 & $options) >> 3; + $this->_phpSheet->getProtection()->setFormatColumns(!$bool); + + // bit: 4; mask 0x0010; format rows + $bool = (0x0010 & $options) >> 4; + $this->_phpSheet->getProtection()->setFormatRows(!$bool); + + // bit: 5; mask 0x0020; insert columns + $bool = (0x0020 & $options) >> 5; + $this->_phpSheet->getProtection()->setInsertColumns(!$bool); + + // bit: 6; mask 0x0040; insert rows + $bool = (0x0040 & $options) >> 6; + $this->_phpSheet->getProtection()->setInsertRows(!$bool); + + // bit: 7; mask 0x0080; insert hyperlinks + $bool = (0x0080 & $options) >> 7; + $this->_phpSheet->getProtection()->setInsertHyperlinks(!$bool); + + // bit: 8; mask 0x0100; delete columns + $bool = (0x0100 & $options) >> 8; + $this->_phpSheet->getProtection()->setDeleteColumns(!$bool); + + // bit: 9; mask 0x0200; delete rows + $bool = (0x0200 & $options) >> 9; + $this->_phpSheet->getProtection()->setDeleteRows(!$bool); + + // bit: 10; mask 0x0400; select locked cells + $bool = (0x0400 & $options) >> 10; + $this->_phpSheet->getProtection()->setSelectLockedCells(!$bool); + + // bit: 11; mask 0x0800; sort cell range + $bool = (0x0800 & $options) >> 11; + $this->_phpSheet->getProtection()->setSort(!$bool); + + // bit: 12; mask 0x1000; auto filter + $bool = (0x1000 & $options) >> 12; + $this->_phpSheet->getProtection()->setAutoFilter(!$bool); + + // bit: 13; mask 0x2000; pivot tables + $bool = (0x2000 & $options) >> 13; + $this->_phpSheet->getProtection()->setPivotTables(!$bool); + + // bit: 14; mask 0x4000; select unlocked cells + $bool = (0x4000 & $options) >> 14; + $this->_phpSheet->getProtection()->setSelectUnlockedCells(!$bool); + + // offset: 21; size: 2; not used + } + + + /** + * Read RANGEPROTECTION record + * Reading of this record is based on Microsoft Office Excel 97-2000 Binary File Format Specification, + * where it is referred to as FEAT record + */ + private function _readRangeProtection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // local pointer in record data + $offset = 0; + + if (!$this->_readDataOnly) { + $offset += 12; + + // offset: 12; size: 2; shared feature type, 2 = enhanced protection, 4 = smart tag + $isf = self::_GetInt2d($recordData, 12); + if ($isf != 2) { + // we only read FEAT records of type 2 + return; + } + $offset += 2; + + $offset += 5; + + // offset: 19; size: 2; count of ref ranges this feature is on + $cref = self::_GetInt2d($recordData, 19); + $offset += 2; + + $offset += 6; + + // offset: 27; size: 8 * $cref; list of cell ranges (like in hyperlink record) + $cellRanges = array(); + for ($i = 0; $i < $cref; ++$i) { + try { + $cellRange = $this->_readBIFF8CellRangeAddressFixed(substr($recordData, 27 + 8 * $i, 8)); + } catch (PHPExcel_Exception $e) { + return; + } + $cellRanges[] = $cellRange; + $offset += 8; + } + + // offset: var; size: var; variable length of feature specific data + $rgbFeat = substr($recordData, $offset); + $offset += 4; + + // offset: var; size: 4; the encrypted password (only 16-bit although field is 32-bit) + $wPassword = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // Apply range protection to sheet + if ($cellRanges) { + $this->_phpSheet->protectCells(implode(' ', $cellRanges), strtoupper(dechex($wPassword)), true); + } + } + } + + + /** + * Read IMDATA record + */ + private function _readImData() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + // UNDER CONSTRUCTION + + // offset: 0; size: 2; image format + $cf = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; environment from which the file was written + $env = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 4; length of the image data + $lcb = self::_GetInt4d($recordData, 4); + + // offset: 8; size: var; image data + $iData = substr($recordData, 8); + + switch ($cf) { + case 0x09: // Windows bitmap format + // BITMAPCOREINFO + // 1. BITMAPCOREHEADER + // offset: 0; size: 4; bcSize, Specifies the number of bytes required by the structure + $bcSize = self::_GetInt4d($iData, 0); + // var_dump($bcSize); + + // offset: 4; size: 2; bcWidth, specifies the width of the bitmap, in pixels + $bcWidth = self::_GetInt2d($iData, 4); + // var_dump($bcWidth); + + // offset: 6; size: 2; bcHeight, specifies the height of the bitmap, in pixels. + $bcHeight = self::_GetInt2d($iData, 6); + // var_dump($bcHeight); + $ih = imagecreatetruecolor($bcWidth, $bcHeight); + + // offset: 8; size: 2; bcPlanes, specifies the number of planes for the target device. This value must be 1 + + // offset: 10; size: 2; bcBitCount specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24 + $bcBitCount = self::_GetInt2d($iData, 10); + // var_dump($bcBitCount); + + $rgbString = substr($iData, 12); + $rgbTriples = array(); + while (strlen($rgbString) > 0) { + $rgbTriples[] = unpack('Cb/Cg/Cr', $rgbString); + $rgbString = substr($rgbString, 3); + } + $x = 0; + $y = 0; + foreach ($rgbTriples as $i => $rgbTriple) { + $color = imagecolorallocate($ih, $rgbTriple['r'], $rgbTriple['g'], $rgbTriple['b']); + imagesetpixel($ih, $x, $bcHeight - 1 - $y, $color); + $x = ($x + 1) % $bcWidth; + $y = $y + floor(($x + 1) / $bcWidth); + } + //imagepng($ih, 'image.png'); + + $drawing = new PHPExcel_Worksheet_Drawing(); + $drawing->setPath($filename); + $drawing->setWorksheet($this->_phpSheet); + break; + case 0x02: // Windows metafile or Macintosh PICT format + case 0x0e: // native format + default: + break; + } + + // _getSplicedRecordData() takes care of moving current position in data stream + } + + + /** + * Read a free CONTINUE record. Free CONTINUE record may be a camouflaged MSODRAWING record + * When MSODRAWING data on a sheet exceeds 8224 bytes, CONTINUE records are used instead. Undocumented. + * In this case, we must treat the CONTINUE record as a MSODRAWING record + */ + private function _readContinue() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // check if we are reading drawing data + // this is in case a free CONTINUE record occurs in other circumstances we are unaware of + if ($this->_drawingData == '') { + // move stream pointer to next record + $this->_pos += 4 + $length; + + return; + } + + // check if record data is at least 4 bytes long, otherwise there is no chance this is MSODRAWING data + if ($length < 4) { + // move stream pointer to next record + $this->_pos += 4 + $length; + + return; + } + + // dirty check to see if CONTINUE record could be a camouflaged MSODRAWING record + // look inside CONTINUE record to see if it looks like a part of an Escher stream + // we know that Escher stream may be split at least at + // 0xF003 MsofbtSpgrContainer + // 0xF004 MsofbtSpContainer + // 0xF00D MsofbtClientTextbox + $validSplitPoints = array(0xF003, 0xF004, 0xF00D); // add identifiers if we find more + + $splitPoint = self::_GetInt2d($recordData, 2); + if (in_array($splitPoint, $validSplitPoints)) { + // get spliced record data (and move pointer to next record) + $splicedRecordData = $this->_getSplicedRecordData(); + $this->_drawingData .= $splicedRecordData['recordData']; + + return; + } + + // move stream pointer to next record + $this->_pos += 4 + $length; + } + + + /** + * Reads a record from current position in data stream and continues reading data as long as CONTINUE + * records are found. Splices the record data pieces and returns the combined string as if record data + * is in one piece. + * Moves to next current position in data stream to start of next record different from a CONtINUE record + * + * @return array + */ + private function _getSplicedRecordData() + { + $data = ''; + $spliceOffsets = array(); + + $i = 0; + $spliceOffsets[0] = 0; + + do { + ++$i; + + // offset: 0; size: 2; identifier + $identifier = self::_GetInt2d($this->_data, $this->_pos); + // offset: 2; size: 2; length + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $data .= $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + $spliceOffsets[$i] = $spliceOffsets[$i - 1] + $length; + + $this->_pos += 4 + $length; + $nextIdentifier = self::_GetInt2d($this->_data, $this->_pos); + } while ($nextIdentifier == self::XLS_Type_CONTINUE); + + $splicedData = array( + 'recordData' => $data, + 'spliceOffsets' => $spliceOffsets, + ); + + return $splicedData; + + } + + + /** + * Convert formula structure into human readable Excel formula like 'A3+A5*5' + * + * @param string $formulaStructure The complete binary data for the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') + { + // offset: 0; size: 2; size of the following formula data + $sz = self::_GetInt2d($formulaStructure, 0); + + // offset: 2; size: sz + $formulaData = substr($formulaStructure, 2, $sz); + + // for debug: dump the formula data + //echo '<xmp>'; + //echo 'size: ' . $sz . "\n"; + //echo 'the entire formula data: '; + //Debug::dump($formulaData); + //echo "\n----\n"; + + // offset: 2 + sz; size: variable (optional) + if (strlen($formulaStructure) > 2 + $sz) { + $additionalData = substr($formulaStructure, 2 + $sz); + + // for debug: dump the additional data + //echo 'the entire additional data: '; + //Debug::dump($additionalData); + //echo "\n----\n"; + } else { + $additionalData = ''; + } + + return $this->_getFormulaFromData($formulaData, $additionalData, $baseCell); + } + + + /** + * Take formula data and additional data for formula and return human readable formula + * + * @param string $formulaData The binary data for the formula itself + * @param string $additionalData Additional binary data going with the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1') + { + // start parsing the formula data + $tokens = array(); + + while (strlen($formulaData) > 0 and $token = $this->_getNextToken($formulaData, $baseCell)) { + $tokens[] = $token; + $formulaData = substr($formulaData, $token['size']); + + // for debug: dump the token + //var_dump($token); + } + + $formulaString = $this->_createFormulaFromTokens($tokens, $additionalData); + + return $formulaString; + } + + + /** + * Take array of tokens together with additional data for formula and return human readable formula + * + * @param array $tokens + * @param array $additionalData Additional binary data going with the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _createFormulaFromTokens($tokens, $additionalData) + { + // empty formula? + if (empty($tokens)) { + return ''; + } + + $formulaStrings = array(); + foreach ($tokens as $token) { + // initialize spaces + $space0 = isset($space0) ? $space0 : ''; // spaces before next token, not tParen + $space1 = isset($space1) ? $space1 : ''; // carriage returns before next token, not tParen + $space2 = isset($space2) ? $space2 : ''; // spaces before opening parenthesis + $space3 = isset($space3) ? $space3 : ''; // carriage returns before opening parenthesis + $space4 = isset($space4) ? $space4 : ''; // spaces before closing parenthesis + $space5 = isset($space5) ? $space5 : ''; // carriage returns before closing parenthesis + + switch ($token['name']) { + case 'tAdd': // addition + case 'tConcat': // addition + case 'tDiv': // division + case 'tEQ': // equality + case 'tGE': // greater than or equal + case 'tGT': // greater than + case 'tIsect': // intersection + case 'tLE': // less than or equal + case 'tList': // less than or equal + case 'tLT': // less than + case 'tMul': // multiplication + case 'tNE': // multiplication + case 'tPower': // power + case 'tRange': // range + case 'tSub': // subtraction + $op2 = array_pop($formulaStrings); + $op1 = array_pop($formulaStrings); + $formulaStrings[] = "$op1$space1$space0{$token['data']}$op2"; + unset($space0, $space1); + break; + case 'tUplus': // unary plus + case 'tUminus': // unary minus + $op = array_pop($formulaStrings); + $formulaStrings[] = "$space1$space0{$token['data']}$op"; + unset($space0, $space1); + break; + case 'tPercent': // percent sign + $op = array_pop($formulaStrings); + $formulaStrings[] = "$op$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + case 'tAttrVolatile': // indicates volatile function + case 'tAttrIf': + case 'tAttrSkip': + case 'tAttrChoose': + // token is only important for Excel formula evaluator + // do nothing + break; + case 'tAttrSpace': // space / carriage return + // space will be used when next token arrives, do not alter formulaString stack + switch ($token['data']['spacetype']) { + case 'type0': + $space0 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type1': + $space1 = str_repeat("\n", $token['data']['spacecount']); + break; + case 'type2': + $space2 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type3': + $space3 = str_repeat("\n", $token['data']['spacecount']); + break; + case 'type4': + $space4 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type5': + $space5 = str_repeat("\n", $token['data']['spacecount']); + break; + } + break; + case 'tAttrSum': // SUM function with one parameter + $op = array_pop($formulaStrings); + $formulaStrings[] = "{$space1}{$space0}SUM($op)"; + unset($space0, $space1); + break; + case 'tFunc': // function with fixed number of arguments + case 'tFuncV': // function with variable number of arguments + if ($token['data']['function'] != '') { + // normal function + $ops = array(); // array of operators + for ($i = 0; $i < $token['data']['args']; ++$i) { + $ops[] = array_pop($formulaStrings); + } + $ops = array_reverse($ops); + $formulaStrings[] = "$space1$space0{$token['data']['function']}(" . implode(',', $ops) . ")"; + unset($space0, $space1); + } else { + // add-in function + $ops = array(); // array of operators + for ($i = 0; $i < $token['data']['args'] - 1; ++$i) { + $ops[] = array_pop($formulaStrings); + } + $ops = array_reverse($ops); + $function = array_pop($formulaStrings); + $formulaStrings[] = "$space1$space0$function(" . implode(',', $ops) . ")"; + unset($space0, $space1); + } + break; + case 'tParen': // parenthesis + $expression = array_pop($formulaStrings); + $formulaStrings[] = "$space3$space2($expression$space5$space4)"; + unset($space2, $space3, $space4, $space5); + break; + case 'tArray': // array constant + $constantArray = self::_readBIFF8ConstantArray($additionalData); + $formulaStrings[] = $space1 . $space0 . $constantArray['value']; + $additionalData = substr($additionalData, $constantArray['size']); // bite of chunk of additional data + unset($space0, $space1); + break; + case 'tMemArea': + // bite off chunk of additional data + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData); + $additionalData = substr($additionalData, $cellRangeAddressList['size']); + $formulaStrings[] = "$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + case 'tArea': // cell range address + case 'tBool': // boolean + case 'tErr': // error code + case 'tInt': // integer + case 'tMemErr': + case 'tMemFunc': + case 'tMissArg': + case 'tName': + case 'tNameX': + case 'tNum': // number + case 'tRef': // single cell reference + case 'tRef3d': // 3d cell reference + case 'tArea3d': // 3d cell range reference + case 'tRefN': + case 'tAreaN': + case 'tStr': // string + $formulaStrings[] = "$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + } + } + $formulaString = $formulaStrings[0]; + + // for debug: dump the human readable formula + //echo '----' . "\n"; + //echo 'Formula: ' . $formulaString; + + return $formulaString; + } + + + /** + * Fetch next token from binary formula data + * + * @param string Formula data + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return array + * @throws PHPExcel_Reader_Exception + */ + private function _getNextToken($formulaData, $baseCell = 'A1') + { + // offset: 0; size: 1; token id + $id = ord($formulaData[0]); // token id + $name = false; // initialize token name + + switch ($id) { + case 0x03: + $name = 'tAdd'; + $size = 1; + $data = '+'; + break; + case 0x04: + $name = 'tSub'; + $size = 1; + $data = '-'; + break; + case 0x05: + $name = 'tMul'; + $size = 1; + $data = '*'; + break; + case 0x06: + $name = 'tDiv'; + $size = 1; + $data = '/'; + break; + case 0x07: + $name = 'tPower'; + $size = 1; + $data = '^'; + break; + case 0x08: + $name = 'tConcat'; + $size = 1; + $data = '&'; + break; + case 0x09: + $name = 'tLT'; + $size = 1; + $data = '<'; + break; + case 0x0A: + $name = 'tLE'; + $size = 1; + $data = '<='; + break; + case 0x0B: + $name = 'tEQ'; + $size = 1; + $data = '='; + break; + case 0x0C: + $name = 'tGE'; + $size = 1; + $data = '>='; + break; + case 0x0D: + $name = 'tGT'; + $size = 1; + $data = '>'; + break; + case 0x0E: + $name = 'tNE'; + $size = 1; + $data = '<>'; + break; + case 0x0F: + $name = 'tIsect'; + $size = 1; + $data = ' '; + break; + case 0x10: + $name = 'tList'; + $size = 1; + $data = ','; + break; + case 0x11: + $name = 'tRange'; + $size = 1; + $data = ':'; + break; + case 0x12: + $name = 'tUplus'; + $size = 1; + $data = '+'; + break; + case 0x13: + $name = 'tUminus'; + $size = 1; + $data = '-'; + break; + case 0x14: + $name = 'tPercent'; + $size = 1; + $data = '%'; + break; + case 0x15: // parenthesis + $name = 'tParen'; + $size = 1; + $data = null; + break; + case 0x16: // missing argument + $name = 'tMissArg'; + $size = 1; + $data = ''; + break; + case 0x17: // string + $name = 'tStr'; + // offset: 1; size: var; Unicode string, 8-bit string length + $string = self::_readUnicodeStringShort(substr($formulaData, 1)); + $size = 1 + $string['size']; + $data = self::_UTF8toExcelDoubleQuoted($string['value']); + break; + case 0x19: // Special attribute + // offset: 1; size: 1; attribute type flags: + switch (ord($formulaData[1])) { + case 0x01: + $name = 'tAttrVolatile'; + $size = 4; + $data = null; + break; + case 0x02: + $name = 'tAttrIf'; + $size = 4; + $data = null; + break; + case 0x04: + $name = 'tAttrChoose'; + // offset: 2; size: 2; number of choices in the CHOOSE function ($nc, number of parameters decreased by 1) + $nc = self::_GetInt2d($formulaData, 2); + // offset: 4; size: 2 * $nc + // offset: 4 + 2 * $nc; size: 2 + $size = 2 * $nc + 6; + $data = null; + break; + case 0x08: + $name = 'tAttrSkip'; + $size = 4; + $data = null; + break; + case 0x10: + $name = 'tAttrSum'; + $size = 4; + $data = null; + break; + case 0x40: + case 0x41: + $name = 'tAttrSpace'; + $size = 4; + // offset: 2; size: 2; space type and position + switch (ord($formulaData[2])) { + case 0x00: + $spacetype = 'type0'; + break; + case 0x01: + $spacetype = 'type1'; + break; + case 0x02: + $spacetype = 'type2'; + break; + case 0x03: + $spacetype = 'type3'; + break; + case 0x04: + $spacetype = 'type4'; + break; + case 0x05: + $spacetype = 'type5'; + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized space type in tAttrSpace token'); + break; + } + // offset: 3; size: 1; number of inserted spaces/carriage returns + $spacecount = ord($formulaData[3]); + + $data = array('spacetype' => $spacetype, 'spacecount' => $spacecount); + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized attribute flag in tAttr token'); + break; + } + break; + case 0x1C: // error code + // offset: 1; size: 1; error code + $name = 'tErr'; + $size = 2; + $data = self::_mapErrorCode(ord($formulaData[1])); + break; + case 0x1D: // boolean + // offset: 1; size: 1; 0 = false, 1 = true; + $name = 'tBool'; + $size = 2; + $data = ord($formulaData[1]) ? 'TRUE' : 'FALSE'; + break; + case 0x1E: // integer + // offset: 1; size: 2; unsigned 16-bit integer + $name = 'tInt'; + $size = 3; + $data = self::_GetInt2d($formulaData, 1); + break; + case 0x1F: // number + // offset: 1; size: 8; + $name = 'tNum'; + $size = 9; + $data = self::_extractNumber(substr($formulaData, 1)); + $data = str_replace(',', '.', (string)$data); // in case non-English locale + break; + case 0x20: // array constant + case 0x40: + case 0x60: + // offset: 1; size: 7; not used + $name = 'tArray'; + $size = 8; + $data = null; + break; + case 0x21: // function with fixed number of arguments + case 0x41: + case 0x61: + $name = 'tFunc'; + $size = 3; + // offset: 1; size: 2; index to built-in sheet function + switch (self::_GetInt2d($formulaData, 1)) { + case 2: + $function = 'ISNA'; + $args = 1; + break; + case 3: + $function = 'ISERROR'; + $args = 1; + break; + case 10: + $function = 'NA'; + $args = 0; + break; + case 15: + $function = 'SIN'; + $args = 1; + break; + case 16: + $function = 'COS'; + $args = 1; + break; + case 17: + $function = 'TAN'; + $args = 1; + break; + case 18: + $function = 'ATAN'; + $args = 1; + break; + case 19: + $function = 'PI'; + $args = 0; + break; + case 20: + $function = 'SQRT'; + $args = 1; + break; + case 21: + $function = 'EXP'; + $args = 1; + break; + case 22: + $function = 'LN'; + $args = 1; + break; + case 23: + $function = 'LOG10'; + $args = 1; + break; + case 24: + $function = 'ABS'; + $args = 1; + break; + case 25: + $function = 'INT'; + $args = 1; + break; + case 26: + $function = 'SIGN'; + $args = 1; + break; + case 27: + $function = 'ROUND'; + $args = 2; + break; + case 30: + $function = 'REPT'; + $args = 2; + break; + case 31: + $function = 'MID'; + $args = 3; + break; + case 32: + $function = 'LEN'; + $args = 1; + break; + case 33: + $function = 'VALUE'; + $args = 1; + break; + case 34: + $function = 'TRUE'; + $args = 0; + break; + case 35: + $function = 'FALSE'; + $args = 0; + break; + case 38: + $function = 'NOT'; + $args = 1; + break; + case 39: + $function = 'MOD'; + $args = 2; + break; + case 40: + $function = 'DCOUNT'; + $args = 3; + break; + case 41: + $function = 'DSUM'; + $args = 3; + break; + case 42: + $function = 'DAVERAGE'; + $args = 3; + break; + case 43: + $function = 'DMIN'; + $args = 3; + break; + case 44: + $function = 'DMAX'; + $args = 3; + break; + case 45: + $function = 'DSTDEV'; + $args = 3; + break; + case 48: + $function = 'TEXT'; + $args = 2; + break; + case 61: + $function = 'MIRR'; + $args = 3; + break; + case 63: + $function = 'RAND'; + $args = 0; + break; + case 65: + $function = 'DATE'; + $args = 3; + break; + case 66: + $function = 'TIME'; + $args = 3; + break; + case 67: + $function = 'DAY'; + $args = 1; + break; + case 68: + $function = 'MONTH'; + $args = 1; + break; + case 69: + $function = 'YEAR'; + $args = 1; + break; + case 71: + $function = 'HOUR'; + $args = 1; + break; + case 72: + $function = 'MINUTE'; + $args = 1; + break; + case 73: + $function = 'SECOND'; + $args = 1; + break; + case 74: + $function = 'NOW'; + $args = 0; + break; + case 75: + $function = 'AREAS'; + $args = 1; + break; + case 76: + $function = 'ROWS'; + $args = 1; + break; + case 77: + $function = 'COLUMNS'; + $args = 1; + break; + case 83: + $function = 'TRANSPOSE'; + $args = 1; + break; + case 86: + $function = 'TYPE'; + $args = 1; + break; + case 97: + $function = 'ATAN2'; + $args = 2; + break; + case 98: + $function = 'ASIN'; + $args = 1; + break; + case 99: + $function = 'ACOS'; + $args = 1; + break; + case 105: + $function = 'ISREF'; + $args = 1; + break; + case 111: + $function = 'CHAR'; + $args = 1; + break; + case 112: + $function = 'LOWER'; + $args = 1; + break; + case 113: + $function = 'UPPER'; + $args = 1; + break; + case 114: + $function = 'PROPER'; + $args = 1; + break; + case 117: + $function = 'EXACT'; + $args = 2; + break; + case 118: + $function = 'TRIM'; + $args = 1; + break; + case 119: + $function = 'REPLACE'; + $args = 4; + break; + case 121: + $function = 'CODE'; + $args = 1; + break; + case 126: + $function = 'ISERR'; + $args = 1; + break; + case 127: + $function = 'ISTEXT'; + $args = 1; + break; + case 128: + $function = 'ISNUMBER'; + $args = 1; + break; + case 129: + $function = 'ISBLANK'; + $args = 1; + break; + case 130: + $function = 'T'; + $args = 1; + break; + case 131: + $function = 'N'; + $args = 1; + break; + case 140: + $function = 'DATEVALUE'; + $args = 1; + break; + case 141: + $function = 'TIMEVALUE'; + $args = 1; + break; + case 142: + $function = 'SLN'; + $args = 3; + break; + case 143: + $function = 'SYD'; + $args = 4; + break; + case 162: + $function = 'CLEAN'; + $args = 1; + break; + case 163: + $function = 'MDETERM'; + $args = 1; + break; + case 164: + $function = 'MINVERSE'; + $args = 1; + break; + case 165: + $function = 'MMULT'; + $args = 2; + break; + case 184: + $function = 'FACT'; + $args = 1; + break; + case 189: + $function = 'DPRODUCT'; + $args = 3; + break; + case 190: + $function = 'ISNONTEXT'; + $args = 1; + break; + case 195: + $function = 'DSTDEVP'; + $args = 3; + break; + case 196: + $function = 'DVARP'; + $args = 3; + break; + case 198: + $function = 'ISLOGICAL'; + $args = 1; + break; + case 199: + $function = 'DCOUNTA'; + $args = 3; + break; + case 207: + $function = 'REPLACEB'; + $args = 4; + break; + case 210: + $function = 'MIDB'; + $args = 3; + break; + case 211: + $function = 'LENB'; + $args = 1; + break; + case 212: + $function = 'ROUNDUP'; + $args = 2; + break; + case 213: + $function = 'ROUNDDOWN'; + $args = 2; + break; + case 214: + $function = 'ASC'; + $args = 1; + break; + case 215: + $function = 'DBCS'; + $args = 1; + break; + case 221: + $function = 'TODAY'; + $args = 0; + break; + case 229: + $function = 'SINH'; + $args = 1; + break; + case 230: + $function = 'COSH'; + $args = 1; + break; + case 231: + $function = 'TANH'; + $args = 1; + break; + case 232: + $function = 'ASINH'; + $args = 1; + break; + case 233: + $function = 'ACOSH'; + $args = 1; + break; + case 234: + $function = 'ATANH'; + $args = 1; + break; + case 235: + $function = 'DGET'; + $args = 3; + break; + case 244: + $function = 'INFO'; + $args = 1; + break; + case 252: + $function = 'FREQUENCY'; + $args = 2; + break; + case 261: + $function = 'ERROR.TYPE'; + $args = 1; + break; + case 271: + $function = 'GAMMALN'; + $args = 1; + break; + case 273: + $function = 'BINOMDIST'; + $args = 4; + break; + case 274: + $function = 'CHIDIST'; + $args = 2; + break; + case 275: + $function = 'CHIINV'; + $args = 2; + break; + case 276: + $function = 'COMBIN'; + $args = 2; + break; + case 277: + $function = 'CONFIDENCE'; + $args = 3; + break; + case 278: + $function = 'CRITBINOM'; + $args = 3; + break; + case 279: + $function = 'EVEN'; + $args = 1; + break; + case 280: + $function = 'EXPONDIST'; + $args = 3; + break; + case 281: + $function = 'FDIST'; + $args = 3; + break; + case 282: + $function = 'FINV'; + $args = 3; + break; + case 283: + $function = 'FISHER'; + $args = 1; + break; + case 284: + $function = 'FISHERINV'; + $args = 1; + break; + case 285: + $function = 'FLOOR'; + $args = 2; + break; + case 286: + $function = 'GAMMADIST'; + $args = 4; + break; + case 287: + $function = 'GAMMAINV'; + $args = 3; + break; + case 288: + $function = 'CEILING'; + $args = 2; + break; + case 289: + $function = 'HYPGEOMDIST'; + $args = 4; + break; + case 290: + $function = 'LOGNORMDIST'; + $args = 3; + break; + case 291: + $function = 'LOGINV'; + $args = 3; + break; + case 292: + $function = 'NEGBINOMDIST'; + $args = 3; + break; + case 293: + $function = 'NORMDIST'; + $args = 4; + break; + case 294: + $function = 'NORMSDIST'; + $args = 1; + break; + case 295: + $function = 'NORMINV'; + $args = 3; + break; + case 296: + $function = 'NORMSINV'; + $args = 1; + break; + case 297: + $function = 'STANDARDIZE'; + $args = 3; + break; + case 298: + $function = 'ODD'; + $args = 1; + break; + case 299: + $function = 'PERMUT'; + $args = 2; + break; + case 300: + $function = 'POISSON'; + $args = 3; + break; + case 301: + $function = 'TDIST'; + $args = 3; + break; + case 302: + $function = 'WEIBULL'; + $args = 4; + break; + case 303: + $function = 'SUMXMY2'; + $args = 2; + break; + case 304: + $function = 'SUMX2MY2'; + $args = 2; + break; + case 305: + $function = 'SUMX2PY2'; + $args = 2; + break; + case 306: + $function = 'CHITEST'; + $args = 2; + break; + case 307: + $function = 'CORREL'; + $args = 2; + break; + case 308: + $function = 'COVAR'; + $args = 2; + break; + case 309: + $function = 'FORECAST'; + $args = 3; + break; + case 310: + $function = 'FTEST'; + $args = 2; + break; + case 311: + $function = 'INTERCEPT'; + $args = 2; + break; + case 312: + $function = 'PEARSON'; + $args = 2; + break; + case 313: + $function = 'RSQ'; + $args = 2; + break; + case 314: + $function = 'STEYX'; + $args = 2; + break; + case 315: + $function = 'SLOPE'; + $args = 2; + break; + case 316: + $function = 'TTEST'; + $args = 4; + break; + case 325: + $function = 'LARGE'; + $args = 2; + break; + case 326: + $function = 'SMALL'; + $args = 2; + break; + case 327: + $function = 'QUARTILE'; + $args = 2; + break; + case 328: + $function = 'PERCENTILE'; + $args = 2; + break; + case 331: + $function = 'TRIMMEAN'; + $args = 2; + break; + case 332: + $function = 'TINV'; + $args = 2; + break; + case 337: + $function = 'POWER'; + $args = 2; + break; + case 342: + $function = 'RADIANS'; + $args = 1; + break; + case 343: + $function = 'DEGREES'; + $args = 1; + break; + case 346: + $function = 'COUNTIF'; + $args = 2; + break; + case 347: + $function = 'COUNTBLANK'; + $args = 1; + break; + case 350: + $function = 'ISPMT'; + $args = 4; + break; + case 351: + $function = 'DATEDIF'; + $args = 3; + break; + case 352: + $function = 'DATESTRING'; + $args = 1; + break; + case 353: + $function = 'NUMBERSTRING'; + $args = 2; + break; + case 360: + $function = 'PHONETIC'; + $args = 1; + break; + case 368: + $function = 'BAHTTEXT'; + $args = 1; + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + break; + } + $data = array('function' => $function, 'args' => $args); + break; + case 0x22: // function with variable number of arguments + case 0x42: + case 0x62: + $name = 'tFuncV'; + $size = 4; + // offset: 1; size: 1; number of arguments + $args = ord($formulaData[1]); + // offset: 2: size: 2; index to built-in sheet function + $index = self::_GetInt2d($formulaData, 2); + switch ($index) { + case 0: + $function = 'COUNT'; + break; + case 1: + $function = 'IF'; + break; + case 4: + $function = 'SUM'; + break; + case 5: + $function = 'AVERAGE'; + break; + case 6: + $function = 'MIN'; + break; + case 7: + $function = 'MAX'; + break; + case 8: + $function = 'ROW'; + break; + case 9: + $function = 'COLUMN'; + break; + case 11: + $function = 'NPV'; + break; + case 12: + $function = 'STDEV'; + break; + case 13: + $function = 'DOLLAR'; + break; + case 14: + $function = 'FIXED'; + break; + case 28: + $function = 'LOOKUP'; + break; + case 29: + $function = 'INDEX'; + break; + case 36: + $function = 'AND'; + break; + case 37: + $function = 'OR'; + break; + case 46: + $function = 'VAR'; + break; + case 49: + $function = 'LINEST'; + break; + case 50: + $function = 'TREND'; + break; + case 51: + $function = 'LOGEST'; + break; + case 52: + $function = 'GROWTH'; + break; + case 56: + $function = 'PV'; + break; + case 57: + $function = 'FV'; + break; + case 58: + $function = 'NPER'; + break; + case 59: + $function = 'PMT'; + break; + case 60: + $function = 'RATE'; + break; + case 62: + $function = 'IRR'; + break; + case 64: + $function = 'MATCH'; + break; + case 70: + $function = 'WEEKDAY'; + break; + case 78: + $function = 'OFFSET'; + break; + case 82: + $function = 'SEARCH'; + break; + case 100: + $function = 'CHOOSE'; + break; + case 101: + $function = 'HLOOKUP'; + break; + case 102: + $function = 'VLOOKUP'; + break; + case 109: + $function = 'LOG'; + break; + case 115: + $function = 'LEFT'; + break; + case 116: + $function = 'RIGHT'; + break; + case 120: + $function = 'SUBSTITUTE'; + break; + case 124: + $function = 'FIND'; + break; + case 125: + $function = 'CELL'; + break; + case 144: + $function = 'DDB'; + break; + case 148: + $function = 'INDIRECT'; + break; + case 167: + $function = 'IPMT'; + break; + case 168: + $function = 'PPMT'; + break; + case 169: + $function = 'COUNTA'; + break; + case 183: + $function = 'PRODUCT'; + break; + case 193: + $function = 'STDEVP'; + break; + case 194: + $function = 'VARP'; + break; + case 197: + $function = 'TRUNC'; + break; + case 204: + $function = 'USDOLLAR'; + break; + case 205: + $function = 'FINDB'; + break; + case 206: + $function = 'SEARCHB'; + break; + case 208: + $function = 'LEFTB'; + break; + case 209: + $function = 'RIGHTB'; + break; + case 216: + $function = 'RANK'; + break; + case 219: + $function = 'ADDRESS'; + break; + case 220: + $function = 'DAYS360'; + break; + case 222: + $function = 'VDB'; + break; + case 227: + $function = 'MEDIAN'; + break; + case 228: + $function = 'SUMPRODUCT'; + break; + case 247: + $function = 'DB'; + break; + case 255: + $function = ''; + break; + case 269: + $function = 'AVEDEV'; + break; + case 270: + $function = 'BETADIST'; + break; + case 272: + $function = 'BETAINV'; + break; + case 317: + $function = 'PROB'; + break; + case 318: + $function = 'DEVSQ'; + break; + case 319: + $function = 'GEOMEAN'; + break; + case 320: + $function = 'HARMEAN'; + break; + case 321: + $function = 'SUMSQ'; + break; + case 322: + $function = 'KURT'; + break; + case 323: + $function = 'SKEW'; + break; + case 324: + $function = 'ZTEST'; + break; + case 329: + $function = 'PERCENTRANK'; + break; + case 330: + $function = 'MODE'; + break; + case 336: + $function = 'CONCATENATE'; + break; + case 344: + $function = 'SUBTOTAL'; + break; + case 345: + $function = 'SUMIF'; + break; + case 354: + $function = 'ROMAN'; + break; + case 358: + $function = 'GETPIVOTDATA'; + break; + case 359: + $function = 'HYPERLINK'; + break; + case 361: + $function = 'AVERAGEA'; + break; + case 362: + $function = 'MAXA'; + break; + case 363: + $function = 'MINA'; + break; + case 364: + $function = 'STDEVPA'; + break; + case 365: + $function = 'VARPA'; + break; + case 366: + $function = 'STDEVA'; + break; + case 367: + $function = 'VARA'; + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + break; + } + $data = array('function' => $function, 'args' => $args); + break; + case 0x23: // index to defined name + case 0x43: + case 0x63: + $name = 'tName'; + $size = 5; + // offset: 1; size: 2; one-based index to definedname record + $definedNameIndex = self::_GetInt2d($formulaData, 1) - 1; + // offset: 2; size: 2; not used + $data = $this->_definedname[$definedNameIndex]['name']; + break; + case 0x24: // single cell reference e.g. A5 + case 0x44: + case 0x64: + $name = 'tRef'; + $size = 5; + $data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4)); + break; + case 0x25: // cell range reference to cells in the same sheet (2d) + case 0x45: + case 0x65: + $name = 'tArea'; + $size = 9; + $data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8)); + break; + case 0x26: // Constant reference sub-expression + case 0x46: + case 0x66: + $name = 'tMemArea'; + // offset: 1; size: 4; not used + // offset: 5; size: 2; size of the following subexpression + $subSize = self::_GetInt2d($formulaData, 5); + $size = 7 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + break; + case 0x27: // Deleted constant reference sub-expression + case 0x47: + case 0x67: + $name = 'tMemErr'; + // offset: 1; size: 4; not used + // offset: 5; size: 2; size of the following subexpression + $subSize = self::_GetInt2d($formulaData, 5); + $size = 7 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + break; + case 0x29: // Variable reference sub-expression + case 0x49: + case 0x69: + $name = 'tMemFunc'; + // offset: 1; size: 2; size of the following sub-expression + $subSize = self::_GetInt2d($formulaData, 1); + $size = 3 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize)); + break; + case 0x2C: // Relative 2d cell reference reference, used in shared formulas and some other places + case 0x4C: + case 0x6C: + $name = 'tRefN'; + $size = 5; + $data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell); + break; + case 0x2D: // Relative 2d range reference + case 0x4D: + case 0x6D: + $name = 'tAreaN'; + $size = 9; + $data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell); + break; + case 0x39: // External name + case 0x59: + case 0x79: + $name = 'tNameX'; + $size = 7; + // offset: 1; size: 2; index to REF entry in EXTERNSHEET record + // offset: 3; size: 2; one-based index to DEFINEDNAME or EXTERNNAME record + $index = self::_GetInt2d($formulaData, 3); + // assume index is to EXTERNNAME record + $data = $this->_externalNames[$index - 1]['name']; + // offset: 5; size: 2; not used + break; + case 0x3A: // 3d reference to cell + case 0x5A: + case 0x7A: + $name = 'tRef3d'; + $size = 7; + + try { + // offset: 1; size: 2; index to REF entry + $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + // offset: 3; size: 4; cell address + $cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4)); + + $data = "$sheetRange!$cellAddress"; + } catch (PHPExcel_Exception $e) { + // deleted sheet reference + $data = '#REF!'; + } + break; + case 0x3B: // 3d reference to cell range + case 0x5B: + case 0x7B: + $name = 'tArea3d'; + $size = 11; + + try { + // offset: 1; size: 2; index to REF entry + $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + // offset: 3; size: 8; cell address + $cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8)); + + $data = "$sheetRange!$cellRangeAddress"; + } catch (PHPExcel_Exception $e) { + // deleted sheet reference + $data = '#REF!'; + } + break; + // Unknown cases // don't know how to deal with + default: + throw new PHPExcel_Reader_Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula'); + break; + } + + return array( + 'id' => $id, + 'name' => $name, + 'size' => $size, + 'data' => $data, + ); + } + + + /** + * Reads a cell address in BIFF8 e.g. 'A2' or '$A$2' + * section 3.3.4 + * + * @param string $cellAddressStructure + * @return string + */ + private function _readBIFF8CellAddress($cellAddressStructure) + { + // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) + $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + + // offset: 2; size: 2; index to column or column offset + relative flags + // bit: 7-0; mask 0x00FF; column index + $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + $column = '$' . $column; + } + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + $row = '$' . $row; + } + + return $column . $row; + } + + + /** + * Reads a cell address in BIFF8 for shared formulas. Uses positive and negative values for row and column + * to indicate offsets from a base cell + * section 3.3.4 + * + * @param string $cellAddressStructure + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string + */ + private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') + { + list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); + $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; + + // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) + $rowIndex = self::_GetInt2d($cellAddressStructure, 0); + $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + + // offset: 2; size: 2; index to column or column offset + relative flags + // bit: 7-0; mask 0x00FF; column index + $colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + $column = PHPExcel_Cell::stringFromColumnIndex($colIndex); + $column = '$' . $column; + } else { + $colIndex = ($colIndex <= 127) ? $colIndex : $colIndex - 256; + $column = PHPExcel_Cell::stringFromColumnIndex($baseCol + $colIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + $row = '$' . $row; + } else { + $rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536; + $row = $baseRow + $rowIndex; + } + + return $column . $row; + } + + + /** + * Reads a cell range address in BIFF5 e.g. 'A2:B6' or 'A1' + * always fixed range + * section 2.5.14 + * + * @param string $subData + * @return string + * @throws PHPExcel_Reader_Exception + */ + private function _readBIFF5CellRangeAddressFixed($subData) + { + // offset: 0; size: 2; index to first row + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 1; index to first column + $fc = ord($subData{4}); + + // offset: 5; size: 1; index to last column + $lc = ord($subData{5}); + + // check values + if ($fr > $lr || $fc > $lc) { + throw new PHPExcel_Reader_Exception('Not a cell range address'); + } + + // column index to letter + $fc = PHPExcel_Cell::stringFromColumnIndex($fc); + $lc = PHPExcel_Cell::stringFromColumnIndex($lc); + + if ($fr == $lr and $fc == $lc) { + return "$fc$fr"; + } + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 e.g. 'A2:B6' or 'A1' + * always fixed range + * section 2.5.14 + * + * @param string $subData + * @return string + * @throws PHPExcel_Reader_Exception + */ + private function _readBIFF8CellRangeAddressFixed($subData) + { + // offset: 0; size: 2; index to first row + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 2; index to first column + $fc = self::_GetInt2d($subData, 4); + + // offset: 6; size: 2; index to last column + $lc = self::_GetInt2d($subData, 6); + + // check values + if ($fr > $lr || $fc > $lc) { + throw new PHPExcel_Reader_Exception('Not a cell range address'); + } + + // column index to letter + $fc = PHPExcel_Cell::stringFromColumnIndex($fc); + $lc = PHPExcel_Cell::stringFromColumnIndex($lc); + + if ($fr == $lr and $fc == $lc) { + return "$fc$fr"; + } + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 e.g. 'A2:B6' or '$A$2:$B$6' + * there are flags indicating whether column/row index is relative + * section 3.3.4 + * + * @param string $subData + * @return string + */ + private function _readBIFF8CellRangeAddress($subData) + { + // todo: if cell range is just a single cell, should this funciton + // not just return e.g. 'A1' and not 'A1:A1' ? + + // offset: 0; size: 2; index to first row (0... 65535) (or offset (-32768... 32767)) + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row (0... 65535) (or offset (-32768... 32767)) + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 2; index to first column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $fc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 4)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 4))) { + $fc = '$' . $fc; + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 4))) { + $fr = '$' . $fr; + } + + // offset: 6; size: 2; index to last column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $lc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 6)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 6))) { + $lc = '$' . $lc; + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 6))) { + $lr = '$' . $lr; + } + + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 for shared formulas. Uses positive and negative values for row and column + * to indicate offsets from a base cell + * section 3.3.4 + * + * @param string $subData + * @param string $baseCell Base cell + * @return string Cell range address + */ + private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') + { + list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); + $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; + + // TODO: if cell range is just a single cell, should this funciton + // not just return e.g. 'A1' and not 'A1:A1' ? + + // offset: 0; size: 2; first row + $frIndex = self::_GetInt2d($subData, 0); // adjust below + + // offset: 2; size: 2; relative index to first row (0... 65535) should be treated as offset (-32768... 32767) + $lrIndex = self::_GetInt2d($subData, 2); // adjust below + + // offset: 4; size: 2; first column with relative/absolute flags + + // bit: 7-0; mask 0x00FF; column index + $fcIndex = 0x00FF & self::_GetInt2d($subData, 4); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 4))) { + // absolute column index + $fc = PHPExcel_Cell::stringFromColumnIndex($fcIndex); + $fc = '$' . $fc; + } else { + // column offset + $fcIndex = ($fcIndex <= 127) ? $fcIndex : $fcIndex - 256; + $fc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $fcIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 4))) { + // absolute row index + $fr = $frIndex + 1; + $fr = '$' . $fr; + } else { + // row offset + $frIndex = ($frIndex <= 32767) ? $frIndex : $frIndex - 65536; + $fr = $baseRow + $frIndex; + } + + // offset: 6; size: 2; last column with relative/absolute flags + + // bit: 7-0; mask 0x00FF; column index + $lcIndex = 0x00FF & self::_GetInt2d($subData, 6); + $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; + $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 6))) { + // absolute column index + $lc = PHPExcel_Cell::stringFromColumnIndex($lcIndex); + $lc = '$' . $lc; + } else { + // column offset + $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; + $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 6))) { + // absolute row index + $lr = $lrIndex + 1; + $lr = '$' . $lr; + } else { + // row offset + $lrIndex = ($lrIndex <= 32767) ? $lrIndex : $lrIndex - 65536; + $lr = $baseRow + $lrIndex; + } + + return "$fc$fr:$lc$lr"; + } + + + /** + * Read BIFF8 cell range address list + * section 2.5.15 + * + * @param string $subData + * @return array + */ + private function _readBIFF8CellRangeAddressList($subData) + { + $cellRangeAddresses = array(); + + // offset: 0; size: 2; number of the following cell range addresses + $nm = self::_GetInt2d($subData, 0); + + $offset = 2; + // offset: 2; size: 8 * $nm; list of $nm (fixed) cell range addresses + for ($i = 0; $i < $nm; ++$i) { + $cellRangeAddresses[] = $this->_readBIFF8CellRangeAddressFixed(substr($subData, $offset, 8)); + $offset += 8; + } + + return array( + 'size' => 2 + 8 * $nm, + 'cellRangeAddresses' => $cellRangeAddresses, + ); + } + + + /** + * Read BIFF5 cell range address list + * section 2.5.15 + * + * @param string $subData + * @return array + */ + private function _readBIFF5CellRangeAddressList($subData) + { + $cellRangeAddresses = array(); + + // offset: 0; size: 2; number of the following cell range addresses + $nm = self::_GetInt2d($subData, 0); + + $offset = 2; + // offset: 2; size: 6 * $nm; list of $nm (fixed) cell range addresses + for ($i = 0; $i < $nm; ++$i) { + $cellRangeAddresses[] = $this->_readBIFF5CellRangeAddressFixed(substr($subData, $offset, 6)); + $offset += 6; + } + + return array( + 'size' => 2 + 6 * $nm, + 'cellRangeAddresses' => $cellRangeAddresses, + ); + } + + + /** + * Get a sheet range like Sheet1:Sheet3 from REF index + * Note: If there is only one sheet in the range, one gets e.g Sheet1 + * It can also happen that the REF structure uses the -1 (FFFF) code to indicate deleted sheets, + * in which case an PHPExcel_Reader_Exception is thrown + * + * @param int $index + * @return string|false + * @throws PHPExcel_Reader_Exception + */ + private function _readSheetRangeByRefIndex($index) + { + if (isset($this->_ref[$index])) { + $type = $this->_externalBooks[$this->_ref[$index]['externalBookIndex']]['type']; + + switch ($type) { + case 'internal': + // check if we have a deleted 3d reference + if ($this->_ref[$index]['firstSheetIndex'] == 0xFFFF or $this->_ref[$index]['lastSheetIndex'] == 0xFFFF) { + throw new PHPExcel_Reader_Exception('Deleted sheet reference'); + } + + // we have normal sheet range (collapsed or uncollapsed) + $firstSheetName = $this->_sheets[$this->_ref[$index]['firstSheetIndex']]['name']; + $lastSheetName = $this->_sheets[$this->_ref[$index]['lastSheetIndex']]['name']; + + if ($firstSheetName == $lastSheetName) { + // collapsed sheet range + $sheetRange = $firstSheetName; + } else { + $sheetRange = "$firstSheetName:$lastSheetName"; + } + + // escape the single-quotes + $sheetRange = str_replace("'", "''", $sheetRange); + + // if there are special characters, we need to enclose the range in single-quotes + // todo: check if we have identified the whole set of special characters + // it seems that the following characters are not accepted for sheet names + // and we may assume that they are not present: []*/:\? + if (preg_match("/[ !\"@#£$%&{()}<>=+'|^,;-]/", $sheetRange)) { + $sheetRange = "'$sheetRange'"; + } + + return $sheetRange; + break; + default: + // TODO: external sheet support + throw new PHPExcel_Reader_Exception('Excel5 reader only supports internal sheets in fomulas'); + break; + } + } + return false; + } + + + /** + * read BIFF8 constant value array from array data + * returns e.g. array('value' => '{1,2;3,4}', 'size' => 40} + * section 2.5.8 + * + * @param string $arrayData + * @return array + */ + private static function _readBIFF8ConstantArray($arrayData) + { + // offset: 0; size: 1; number of columns decreased by 1 + $nc = ord($arrayData[0]); + + // offset: 1; size: 2; number of rows decreased by 1 + $nr = self::_GetInt2d($arrayData, 1); + $size = 3; // initialize + $arrayData = substr($arrayData, 3); + + // offset: 3; size: var; list of ($nc + 1) * ($nr + 1) constant values + $matrixChunks = array(); + for ($r = 1; $r <= $nr + 1; ++$r) { + $items = array(); + for ($c = 1; $c <= $nc + 1; ++$c) { + $constant = self::_readBIFF8Constant($arrayData); + $items[] = $constant['value']; + $arrayData = substr($arrayData, $constant['size']); + $size += $constant['size']; + } + $matrixChunks[] = implode(',', $items); // looks like e.g. '1,"hello"' + } + $matrix = '{' . implode(';', $matrixChunks) . '}'; + + return array( + 'value' => $matrix, + 'size' => $size, + ); + } + + + /** + * read BIFF8 constant value which may be 'Empty Value', 'Number', 'String Value', 'Boolean Value', 'Error Value' + * section 2.5.7 + * returns e.g. array('value' => '5', 'size' => 9) + * + * @param string $valueData + * @return array + */ + private static function _readBIFF8Constant($valueData) + { + // offset: 0; size: 1; identifier for type of constant + $identifier = ord($valueData[0]); + + switch ($identifier) { + case 0x00: // empty constant (what is this?) + $value = ''; + $size = 9; + break; + case 0x01: // number + // offset: 1; size: 8; IEEE 754 floating-point value + $value = self::_extractNumber(substr($valueData, 1, 8)); + $size = 9; + break; + case 0x02: // string value + // offset: 1; size: var; Unicode string, 16-bit string length + $string = self::_readUnicodeStringLong(substr($valueData, 1)); + $value = '"' . $string['value'] . '"'; + $size = 1 + $string['size']; + break; + case 0x04: // boolean + // offset: 1; size: 1; 0 = FALSE, 1 = TRUE + if (ord($valueData[1])) { + $value = 'TRUE'; + } else { + $value = 'FALSE'; + } + $size = 9; + break; + case 0x10: // error code + // offset: 1; size: 1; error code + $value = self::_mapErrorCode(ord($valueData[1])); + $size = 9; + break; + } + return array( + 'value' => $value, + 'size' => $size, + ); + } + + + /** + * Extract RGB color + * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.4 + * + * @param string $rgb Encoded RGB value (4 bytes) + * @return array + */ + private static function _readRGB($rgb) + { + // offset: 0; size 1; Red component + $r = ord($rgb{0}); + + // offset: 1; size: 1; Green component + $g = ord($rgb{1}); + + // offset: 2; size: 1; Blue component + $b = ord($rgb{2}); + + // HEX notation, e.g. 'FF00FC' + $rgb = sprintf('%02X%02X%02X', $r, $g, $b); + + return array('rgb' => $rgb); + } + + + /** + * Read byte string (8-bit string length) + * OpenOffice documentation: 2.5.2 + * + * @param string $subData + * @return array + */ + private function _readByteStringShort($subData) + { + // offset: 0; size: 1; length of the string (character count) + $ln = ord($subData[0]); + + // offset: 1: size: var; character array (8-bit characters) + $value = $this->_decodeCodepage(substr($subData, 1, $ln)); + + return array( + 'value' => $value, + 'size' => 1 + $ln, // size in bytes of data structure + ); + } + + + /** + * Read byte string (16-bit string length) + * OpenOffice documentation: 2.5.2 + * + * @param string $subData + * @return array + */ + private function _readByteStringLong($subData) + { + // offset: 0; size: 2; length of the string (character count) + $ln = self::_GetInt2d($subData, 0); + + // offset: 2: size: var; character array (8-bit characters) + $value = $this->_decodeCodepage(substr($subData, 2)); + + //return $string; + return array( + 'value' => $value, + 'size' => 2 + $ln, // size in bytes of data structure + ); + } + + + /** + * Extracts an Excel Unicode short string (8-bit string length) + * OpenOffice documentation: 2.5.3 + * function will automatically find out where the Unicode string ends. + * + * @param string $subData + * @return array + */ + private static function _readUnicodeStringShort($subData) + { + $value = ''; + + // offset: 0: size: 1; length of the string (character count) + $characterCount = ord($subData[0]); + + $string = self::_readUnicodeString(substr($subData, 1), $characterCount); + + // add 1 for the string length + $string['size'] += 1; + + return $string; + } + + + /** + * Extracts an Excel Unicode long string (16-bit string length) + * OpenOffice documentation: 2.5.3 + * this function is under construction, needs to support rich text, and Asian phonetic settings + * + * @param string $subData + * @return array + */ + private static function _readUnicodeStringLong($subData) + { + $value = ''; + + // offset: 0: size: 2; length of the string (character count) + $characterCount = self::_GetInt2d($subData, 0); + + $string = self::_readUnicodeString(substr($subData, 2), $characterCount); + + // add 2 for the string length + $string['size'] += 2; + + return $string; + } + + + /** + * Read Unicode string with no string length field, but with known character count + * this function is under construction, needs to support rich text, and Asian phonetic settings + * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.3 + * + * @param string $subData + * @param int $characterCount + * @return array + */ + private static function _readUnicodeString($subData, $characterCount) + { + $value = ''; + + // offset: 0: size: 1; option flags + // bit: 0; mask: 0x01; character compression (0 = compressed 8-bit, 1 = uncompressed 16-bit) + $isCompressed = !((0x01 & ord($subData[0])) >> 0); + + // bit: 2; mask: 0x04; Asian phonetic settings + $hasAsian = (0x04) & ord($subData[0]) >> 2; + + // bit: 3; mask: 0x08; Rich-Text settings + $hasRichText = (0x08) & ord($subData[0]) >> 3; + + // offset: 1: size: var; character array + // this offset assumes richtext and Asian phonetic settings are off which is generally wrong + // needs to be fixed + $value = self::_encodeUTF16(substr($subData, 1, $isCompressed ? $characterCount : 2 * $characterCount), $isCompressed); + + return array( + 'value' => $value, + 'size' => $isCompressed ? 1 + $characterCount : 1 + 2 * $characterCount, // the size in bytes including the option flags + ); + } + + + /** + * Convert UTF-8 string to string surounded by double quotes. Used for explicit string tokens in formulas. + * Example: hello"world --> "hello""world" + * + * @param string $value UTF-8 encoded string + * @return string + */ + private static function _UTF8toExcelDoubleQuoted($value) + { + return '"' . str_replace('"', '""', $value) . '"'; + } + + + /** + * Reads first 8 bytes of a string and return IEEE 754 float + * + * @param string $data Binary string that is at least 8 bytes long + * @return float + */ + private static function _extractNumber($data) + { + $rknumhigh = self::_GetInt4d($data, 4); + $rknumlow = self::_GetInt4d($data, 0); + $sign = ($rknumhigh & 0x80000000) >> 31; + $exp = (($rknumhigh & 0x7ff00000) >> 20) - 1023; + $mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); + $mantissalow1 = ($rknumlow & 0x80000000) >> 31; + $mantissalow2 = ($rknumlow & 0x7fffffff); + $value = $mantissa / pow(2, (20 - $exp)); + + if ($mantissalow1 != 0) { + $value += 1 / pow(2, (21 - $exp)); + } + + $value += $mantissalow2 / pow(2, (52 - $exp)); + if ($sign) { + $value *= -1; + } + + return $value; + } + + + private static function _GetIEEE754($rknum) + { + if (($rknum & 0x02) != 0) { + $value = $rknum >> 2; + } else { + // changes by mmp, info on IEEE754 encoding from + // research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html + // The RK format calls for using only the most significant 30 bits + // of the 64 bit floating point value. The other 34 bits are assumed + // to be 0 so we use the upper 30 bits of $rknum as follows... + $sign = ($rknum & 0x80000000) >> 31; + $exp = ($rknum & 0x7ff00000) >> 20; + $mantissa = (0x100000 | ($rknum & 0x000ffffc)); + $value = $mantissa / pow(2, (20- ($exp - 1023))); + if ($sign) { + $value = -1 * $value; + } + //end of changes by mmp + } + if (($rknum & 0x01) != 0) { + $value /= 100; + } + return $value; + } + + + /** + * Get UTF-8 string from (compressed or uncompressed) UTF-16 string + * + * @param string $string + * @param bool $compressed + * @return string + */ + private static function _encodeUTF16($string, $compressed = '') + { + if ($compressed) { + $string = self::_uncompressByteString($string); + } + + return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE'); + } + + + /** + * Convert UTF-16 string in compressed notation to uncompressed form. Only used for BIFF8. + * + * @param string $string + * @return string + */ + private static function _uncompressByteString($string) + { + $uncompressedString = ''; + $strLen = strlen($string); + for ($i = 0; $i < $strLen; ++$i) { + $uncompressedString .= $string[$i] . "\0"; + } + + return $uncompressedString; + } + + + /** + * Convert string to UTF-8. Only used for BIFF5. + * + * @param string $string + * @return string + */ + private function _decodeCodepage($string) + { + return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->_codepage); + } + + + /** + * Read 16-bit unsigned integer + * + * @param string $data + * @param int $pos + * @return int + */ + public static function _GetInt2d($data, $pos) + { + return ord($data[$pos]) | (ord($data[$pos+1]) << 8); + } + + + /** + * Read 32-bit signed integer + * + * @param string $data + * @param int $pos + * @return int + */ + public static function _GetInt4d($data, $pos) + { + // FIX: represent numbers correctly on 64-bit system + // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 + // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems + $_or_24 = ord($data[$pos + 3]); + if ($_or_24 >= 128) { + // negative number + $_ord_24 = -abs((256 - $_or_24) << 24); + } else { + $_ord_24 = ($_or_24 & 127) << 24; + } + return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24; + } + + + /** + * Read color + * + * @param int $color Indexed color + * @param array $palette Color palette + * @return array RGB color value, example: array('rgb' => 'FF0000') + */ + private static function _readColor($color, $palette, $version) + { + if ($color <= 0x07 || $color >= 0x40) { + // special built-in color + return self::_mapBuiltInColor($color); + } elseif (isset($palette) && isset($palette[$color - 8])) { + // palette color, color index 0x08 maps to pallete index 0 + return $palette[$color - 8]; + } else { + // default color table + if ($version == self::XLS_BIFF8) { + return self::_mapColor($color); + } else { + // BIFF5 + return self::_mapColorBIFF5($color); + } + } + + return $color; + } + + + /** + * Map border style + * OpenOffice documentation: 2.5.11 + * + * @param int $index + * @return string + */ + private static function _mapBorderStyle($index) + { + switch ($index) { + case 0x00: + return PHPExcel_Style_Border::BORDER_NONE; + case 0x01: + return PHPExcel_Style_Border::BORDER_THIN; + case 0x02: + return PHPExcel_Style_Border::BORDER_MEDIUM; + case 0x03: + return PHPExcel_Style_Border::BORDER_DASHED; + case 0x04: + return PHPExcel_Style_Border::BORDER_DOTTED; + case 0x05: + return PHPExcel_Style_Border::BORDER_THICK; + case 0x06: + return PHPExcel_Style_Border::BORDER_DOUBLE; + case 0x07: + return PHPExcel_Style_Border::BORDER_HAIR; + case 0x08: + return PHPExcel_Style_Border::BORDER_MEDIUMDASHED; + case 0x09: + return PHPExcel_Style_Border::BORDER_DASHDOT; + case 0x0A: + return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; + case 0x0B: + return PHPExcel_Style_Border::BORDER_DASHDOTDOT; + case 0x0C: + return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + case 0x0D: + return PHPExcel_Style_Border::BORDER_SLANTDASHDOT; + default: + return PHPExcel_Style_Border::BORDER_NONE; + } + } + + + /** + * Get fill pattern from index + * OpenOffice documentation: 2.5.12 + * + * @param int $index + * @return string + */ + private static function _mapFillPattern($index) + { + switch ($index) { + case 0x00: + return PHPExcel_Style_Fill::FILL_NONE; + case 0x01: + return PHPExcel_Style_Fill::FILL_SOLID; + case 0x02: + return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; + case 0x03: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; + case 0x04: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; + case 0x05: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; + case 0x06: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; + case 0x07: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; + case 0x08: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; + case 0x09: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; + case 0x0A: + return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; + case 0x0B: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; + case 0x0C: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; + case 0x0D: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; + case 0x0E: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; + case 0x0F: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; + case 0x10: + return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; + case 0x11: + return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; + case 0x12: + return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; + default: + return PHPExcel_Style_Fill::FILL_NONE; + } + } + + + /** + * Map error code, e.g. '#N/A' + * + * @param int $subData + * @return string + */ + private static function _mapErrorCode($subData) + { + switch ($subData) { + case 0x00: + return '#NULL!'; + break; + case 0x07: + return '#DIV/0!'; + break; + case 0x0F: + return '#VALUE!'; + break; + case 0x17: + return '#REF!'; + break; + case 0x1D: + return '#NAME?'; + break; + case 0x24: + return '#NUM!'; + break; + case 0x2A: + return '#N/A'; + break; + default: + return false; + } + } + + + /** + * Map built-in color to RGB value + * + * @param int $color Indexed color + * @return array + */ + private static function _mapBuiltInColor($color) + { + switch ($color) { + case 0x00: + return array('rgb' => '000000'); + case 0x01: + return array('rgb' => 'FFFFFF'); + case 0x02: + return array('rgb' => 'FF0000'); + case 0x03: + return array('rgb' => '00FF00'); + case 0x04: + return array('rgb' => '0000FF'); + case 0x05: + return array('rgb' => 'FFFF00'); + case 0x06: + return array('rgb' => 'FF00FF'); + case 0x07: + return array('rgb' => '00FFFF'); + case 0x40: + return array('rgb' => '000000'); // system window text color + case 0x41: + return array('rgb' => 'FFFFFF'); // system window background color + default: + return array('rgb' => '000000'); + } + } + + + /** + * Map color array from BIFF5 built-in color index + * + * @param int $subData + * @return array + */ + private static function _mapColorBIFF5($subData) + { + switch ($subData) { + case 0x08: + return array('rgb' => '000000'); + case 0x09: + return array('rgb' => 'FFFFFF'); + case 0x0A: + return array('rgb' => 'FF0000'); + case 0x0B: + return array('rgb' => '00FF00'); + case 0x0C: + return array('rgb' => '0000FF'); + case 0x0D: + return array('rgb' => 'FFFF00'); + case 0x0E: + return array('rgb' => 'FF00FF'); + case 0x0F: + return array('rgb' => '00FFFF'); + case 0x10: + return array('rgb' => '800000'); + case 0x11: + return array('rgb' => '008000'); + case 0x12: + return array('rgb' => '000080'); + case 0x13: + return array('rgb' => '808000'); + case 0x14: + return array('rgb' => '800080'); + case 0x15: + return array('rgb' => '008080'); + case 0x16: + return array('rgb' => 'C0C0C0'); + case 0x17: + return array('rgb' => '808080'); + case 0x18: + return array('rgb' => '8080FF'); + case 0x19: + return array('rgb' => '802060'); + case 0x1A: + return array('rgb' => 'FFFFC0'); + case 0x1B: + return array('rgb' => 'A0E0F0'); + case 0x1C: + return array('rgb' => '600080'); + case 0x1D: + return array('rgb' => 'FF8080'); + case 0x1E: + return array('rgb' => '0080C0'); + case 0x1F: + return array('rgb' => 'C0C0FF'); + case 0x20: + return array('rgb' => '000080'); + case 0x21: + return array('rgb' => 'FF00FF'); + case 0x22: + return array('rgb' => 'FFFF00'); + case 0x23: + return array('rgb' => '00FFFF'); + case 0x24: + return array('rgb' => '800080'); + case 0x25: + return array('rgb' => '800000'); + case 0x26: + return array('rgb' => '008080'); + case 0x27: + return array('rgb' => '0000FF'); + case 0x28: + return array('rgb' => '00CFFF'); + case 0x29: + return array('rgb' => '69FFFF'); + case 0x2A: + return array('rgb' => 'E0FFE0'); + case 0x2B: + return array('rgb' => 'FFFF80'); + case 0x2C: + return array('rgb' => 'A6CAF0'); + case 0x2D: + return array('rgb' => 'DD9CB3'); + case 0x2E: + return array('rgb' => 'B38FEE'); + case 0x2F: + return array('rgb' => 'E3E3E3'); + case 0x30: + return array('rgb' => '2A6FF9'); + case 0x31: + return array('rgb' => '3FB8CD'); + case 0x32: + return array('rgb' => '488436'); + case 0x33: + return array('rgb' => '958C41'); + case 0x34: + return array('rgb' => '8E5E42'); + case 0x35: + return array('rgb' => 'A0627A'); + case 0x36: + return array('rgb' => '624FAC'); + case 0x37: + return array('rgb' => '969696'); + case 0x38: + return array('rgb' => '1D2FBE'); + case 0x39: + return array('rgb' => '286676'); + case 0x3A: + return array('rgb' => '004500'); + case 0x3B: + return array('rgb' => '453E01'); + case 0x3C: + return array('rgb' => '6A2813'); + case 0x3D: + return array('rgb' => '85396A'); + case 0x3E: + return array('rgb' => '4A3285'); + case 0x3F: + return array('rgb' => '424242'); + default: + return array('rgb' => '000000'); + } + } + + + /** + * Map color array from BIFF8 built-in color index + * + * @param int $subData + * @return array + */ + private static function _mapColor($subData) + { + switch ($subData) { + case 0x08: + return array('rgb' => '000000'); + case 0x09: + return array('rgb' => 'FFFFFF'); + case 0x0A: + return array('rgb' => 'FF0000'); + case 0x0B: + return array('rgb' => '00FF00'); + case 0x0C: + return array('rgb' => '0000FF'); + case 0x0D: + return array('rgb' => 'FFFF00'); + case 0x0E: + return array('rgb' => 'FF00FF'); + case 0x0F: + return array('rgb' => '00FFFF'); + case 0x10: + return array('rgb' => '800000'); + case 0x11: + return array('rgb' => '008000'); + case 0x12: + return array('rgb' => '000080'); + case 0x13: + return array('rgb' => '808000'); + case 0x14: + return array('rgb' => '800080'); + case 0x15: + return array('rgb' => '008080'); + case 0x16: + return array('rgb' => 'C0C0C0'); + case 0x17: + return array('rgb' => '808080'); + case 0x18: + return array('rgb' => '9999FF'); + case 0x19: + return array('rgb' => '993366'); + case 0x1A: + return array('rgb' => 'FFFFCC'); + case 0x1B: + return array('rgb' => 'CCFFFF'); + case 0x1C: + return array('rgb' => '660066'); + case 0x1D: + return array('rgb' => 'FF8080'); + case 0x1E: + return array('rgb' => '0066CC'); + case 0x1F: + return array('rgb' => 'CCCCFF'); + case 0x20: + return array('rgb' => '000080'); + case 0x21: + return array('rgb' => 'FF00FF'); + case 0x22: + return array('rgb' => 'FFFF00'); + case 0x23: + return array('rgb' => '00FFFF'); + case 0x24: + return array('rgb' => '800080'); + case 0x25: + return array('rgb' => '800000'); + case 0x26: + return array('rgb' => '008080'); + case 0x27: + return array('rgb' => '0000FF'); + case 0x28: + return array('rgb' => '00CCFF'); + case 0x29: + return array('rgb' => 'CCFFFF'); + case 0x2A: + return array('rgb' => 'CCFFCC'); + case 0x2B: + return array('rgb' => 'FFFF99'); + case 0x2C: + return array('rgb' => '99CCFF'); + case 0x2D: + return array('rgb' => 'FF99CC'); + case 0x2E: + return array('rgb' => 'CC99FF'); + case 0x2F: + return array('rgb' => 'FFCC99'); + case 0x30: + return array('rgb' => '3366FF'); + case 0x31: + return array('rgb' => '33CCCC'); + case 0x32: + return array('rgb' => '99CC00'); + case 0x33: + return array('rgb' => 'FFCC00'); + case 0x34: + return array('rgb' => 'FF9900'); + case 0x35: + return array('rgb' => 'FF6600'); + case 0x36: + return array('rgb' => '666699'); + case 0x37: + return array('rgb' => '969696'); + case 0x38: + return array('rgb' => '003366'); + case 0x39: + return array('rgb' => '339966'); + case 0x3A: + return array('rgb' => '003300'); + case 0x3B: + return array('rgb' => '333300'); + case 0x3C: + return array('rgb' => '993300'); + case 0x3D: + return array('rgb' => '993366'); + case 0x3E: + return array('rgb' => '333399'); + case 0x3F: + return array('rgb' => '333333'); + default: + return array('rgb' => '000000'); + } + } + + private function _parseRichText($is = '') + { + $value = new PHPExcel_RichText(); + + $value->createText($is); + + return $value; + } +} diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index cca5a23b6..ea6d08050 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -557,9 +557,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } break; case 'boolean': - $type = PHPExcel_Cell_DataType::TYPE_BOOL; - $dataValue = ($allCellDataText == 'TRUE') ? true : false; - break; + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $dataValue = ($allCellDataText == 'TRUE') ? true : false; + break; case 'percentage': $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; $dataValue = (float) $cellDataOfficeAttributes['value']; diff --git a/Classes/PHPExcel/Shared/JAMA/Matrix.php b/Classes/PHPExcel/Shared/JAMA/Matrix.php index dfb450fda..b39d414cd 100644 --- a/Classes/PHPExcel/Shared/JAMA/Matrix.php +++ b/Classes/PHPExcel/Shared/JAMA/Matrix.php @@ -198,10 +198,14 @@ public function getMatrix() case 'integer,integer,integer,integer': list($i0, $iF, $j0, $jF) = $args; if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { - $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + $m = $iF - $i0; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { - $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + $n = $jF - $j0; + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } $R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1); for ($i = $i0; $i <= $iF; ++$i) { diff --git a/unitTests/bootstrap.php b/unitTests/bootstrap.php index 8e8cdb39a..d212d58a1 100644 --- a/unitTests/bootstrap.php +++ b/unitTests/bootstrap.php @@ -17,21 +17,21 @@ // Define path to application directory defined('APPLICATION_PATH') - || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../Classes')); + || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../Classes')); // Define path to application tests directory defined('APPLICATION_TESTS_PATH') - || define('APPLICATION_TESTS_PATH', realpath(dirname(__FILE__) )); + || define('APPLICATION_TESTS_PATH', realpath(dirname(__FILE__))); // Define application environment defined('APPLICATION_ENV') || define('APPLICATION_ENV', 'ci'); // Ensure library/ is on include_path set_include_path(implode(PATH_SEPARATOR, array( - realpath(APPLICATION_PATH . '/../Classes'), - './', - dirname(__FILE__), - get_include_path(), + realpath(APPLICATION_PATH . '/../Classes'), + './', + dirname(__FILE__), + get_include_path(), ))); @@ -41,9 +41,9 @@ */ echo "PHPExcel tests beginning\n"; -if(extension_loaded('xdebug')) { - echo "Xdebug extension loaded and running\n"; - xdebug_enable(); +if (extension_loaded('xdebug')) { + echo "Xdebug extension loaded and running\n"; + xdebug_enable(); } else { - echo 'Xdebug not found, you should run the following at the command line: echo "zend_extension=/usr/lib64/php/modules/xdebug.so" > /etc/php.d/xdebug.ini' . "\n"; + echo 'Xdebug not found, you should run the following at the command line: echo "zend_extension=/usr/lib64/php/modules/xdebug.so" > /etc/php.d/xdebug.ini' . "\n"; } diff --git a/unitTests/custom/Complex.php b/unitTests/custom/Complex.php index c827baebd..182e1401a 100644 --- a/unitTests/custom/Complex.php +++ b/unitTests/custom/Complex.php @@ -1,114 +1,115 @@ -<?php - -class Complex { - - private $realPart = 0; - private $imaginaryPart = 0; - private $suffix = NULL; - - public static function _parseComplex($complexNumber) - { - // Test for real number, with no imaginary part - if (is_numeric($complexNumber)) - return array( $complexNumber, 0, NULL ); - - // Fix silly human errors - if (strpos($complexNumber,'+-') !== FALSE) - $complexNumber = str_replace('+-','-',$complexNumber); - if (strpos($complexNumber,'++') !== FALSE) - $complexNumber = str_replace('++','+',$complexNumber); - if (strpos($complexNumber,'--') !== FALSE) - $complexNumber = str_replace('--','-',$complexNumber); - - // Basic validation of string, to parse out real and imaginary parts, and any suffix - $validComplex = preg_match('/^([\-\+]?(\d+\.?\d*|\d*\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?)([\-\+]?(\d+\.?\d*|\d*\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?)?(([\-\+]?)([ij]?))$/ui',$complexNumber,$complexParts); - - if (!$validComplex) { - // Neither real nor imaginary part, so test to see if we actually have a suffix - $validComplex = preg_match('/^([\-\+]?)([ij])$/ui',$complexNumber,$complexParts); - if (!$validComplex) { - throw new Exception('COMPLEX: Invalid complex number'); - } - // We have a suffix, so set the real to 0, the imaginary to either 1 or -1 (as defined by the sign) - $imaginary = 1; - if ($complexParts[1] === '-') { - $imaginary = 0 - $imaginary; - } - return array(0, $imaginary, $complexParts[2]); - } - - // If we don't have an imaginary part, identify whether it should be +1 or -1... - if (($complexParts[4] === '') && ($complexParts[9] !== '')) { - if ($complexParts[7] !== $complexParts[9]) { - $complexParts[4] = 1; - if ($complexParts[8] === '-') { - $complexParts[4] = -1; - } - // ... or if we have only the real and no imaginary part (in which case our real should be the imaginary) - } else { - $complexParts[4] = $complexParts[1]; - $complexParts[1] = 0; - } - } - - // Return real and imaginary parts and suffix as an array, and set a default suffix if user input lazily - return array( $complexParts[1], - $complexParts[4], - !empty($complexParts[9]) ? $complexParts[9] : 'i' - ); - } // function _parseComplex() - - - public function __construct($realPart, $imaginaryPart = null, $suffix = 'i') - { - if ($imaginaryPart === null) { - if (is_array($realPart)) { - // We have an array of (potentially) real and imaginary parts, and any suffix - list ($realPart, $imaginaryPart, $suffix) = array_values($realPart) + array(0.0, 0.0, 'i'); - } elseif((is_string($realPart)) || (is_numeric($realPart))) { - // We've been given a string to parse to extract the real and imaginary parts, and any suffix - list ($realPart, $imaginaryPart, $suffix) = self::_parseComplex($realPart); - } - } - - // Set parsed values in our properties - $this->realPart = (float) $realPart; - $this->imaginaryPart = (float) $imaginaryPart; - $this->suffix = strtolower($suffix); - } - - public function getReal() - { - return $this->realPart; - } - - public function getImaginary() - { - return $this->imaginaryPart; - } - - public function getSuffix() - { - return $this->suffix; - } - - public function __toString() { - $str = ""; - if ($this->imaginaryPart != 0.0) { - if (abs($this->imaginaryPart) != 1.0) { - $str .= $this->imaginaryPart . $this->suffix; - } else { - $str .= (($this->imaginaryPart < 0.0) ? '-' : ''). $this->suffix; - } - } - if ($this->realPart != 0.0) { - if (($str) && ($this->imaginaryPart > 0.0)) - $str = "+" . $str; - $str = $this->realPart . $str; - } - if (!$str) - $str = "0.0"; - return $str; - } - -} +<?php + +class Complex +{ + private $realPart = 0; + private $imaginaryPart = 0; + private $suffix = null; + + public static function _parseComplex($complexNumber) + { + // Test for real number, with no imaginary part + if (is_numeric($complexNumber)) { + return array($complexNumber, 0, null); + } + + // Fix silly human errors + if (strpos($complexNumber, '+-') !== false) { + $complexNumber = str_replace('+-', '-', $complexNumber); + } + if (strpos($complexNumber, '++') !== false) { + $complexNumber = str_replace('++', '+', $complexNumber); + } + if (strpos($complexNumber, '--') !== false) { + $complexNumber = str_replace('--', '-', $complexNumber); + } + + // Basic validation of string, to parse out real and imaginary parts, and any suffix + $validComplex = preg_match('/^([\-\+]?(\d+\.?\d*|\d*\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?)([\-\+]?(\d+\.?\d*|\d*\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?)?(([\-\+]?)([ij]?))$/ui', $complexNumber, $complexParts); + + if (!$validComplex) { + // Neither real nor imaginary part, so test to see if we actually have a suffix + $validComplex = preg_match('/^([\-\+]?)([ij])$/ui', $complexNumber, $complexParts); + if (!$validComplex) { + throw new Exception('COMPLEX: Invalid complex number'); + } + // We have a suffix, so set the real to 0, the imaginary to either 1 or -1 (as defined by the sign) + $imaginary = 1; + if ($complexParts[1] === '-') { + $imaginary = 0 - $imaginary; + } + return array(0, $imaginary, $complexParts[2]); + } + + // If we don't have an imaginary part, identify whether it should be +1 or -1... + if (($complexParts[4] === '') && ($complexParts[9] !== '')) { + if ($complexParts[7] !== $complexParts[9]) { + $complexParts[4] = 1; + if ($complexParts[8] === '-') { + $complexParts[4] = -1; + } + // ... or if we have only the real and no imaginary part (in which case our real should be the imaginary) + } else { + $complexParts[4] = $complexParts[1]; + $complexParts[1] = 0; + } + } + + // Return real and imaginary parts and suffix as an array, and set a default suffix if user input lazily + return array($complexParts[1], $complexParts[4], !empty($complexParts[9]) ? $complexParts[9] : 'i'); + } // function _parseComplex() + + + public function __construct($realPart, $imaginaryPart = null, $suffix = 'i') + { + if ($imaginaryPart === null) { + if (is_array($realPart)) { + // We have an array of (potentially) real and imaginary parts, and any suffix + list ($realPart, $imaginaryPart, $suffix) = array_values($realPart) + array(0.0, 0.0, 'i'); + } elseif((is_string($realPart)) || (is_numeric($realPart))) { + // We've been given a string to parse to extract the real and imaginary parts, and any suffix + list ($realPart, $imaginaryPart, $suffix) = self::_parseComplex($realPart); + } + } + + // Set parsed values in our properties + $this->realPart = (float) $realPart; + $this->imaginaryPart = (float) $imaginaryPart; + $this->suffix = strtolower($suffix); + } + + public function getReal() + { + return $this->realPart; + } + + public function getImaginary() + { + return $this->imaginaryPart; + } + + public function getSuffix() + { + return $this->suffix; + } + + public function __toString() { + $str = ""; + if ($this->imaginaryPart != 0.0) { + if (abs($this->imaginaryPart) != 1.0) { + $str .= $this->imaginaryPart . $this->suffix; + } else { + $str .= (($this->imaginaryPart < 0.0) ? '-' : ''). $this->suffix; + } + } + if ($this->realPart != 0.0) { + if (($str) && ($this->imaginaryPart > 0.0)) + $str = "+" . $str; + $str = $this->realPart . $str; + } + if (!$str) + $str = "0.0"; + return $str; + } + +} diff --git a/unitTests/custom/complexAssert.php b/unitTests/custom/complexAssert.php index 5b813d257..f95ca28c0 100644 --- a/unitTests/custom/complexAssert.php +++ b/unitTests/custom/complexAssert.php @@ -1,62 +1,55 @@ -<?php - -include_once dirname(__FILE__).'/Complex.php'; - - -class complexAssert { - - private $_errorMessage = ''; - - public function assertComplexEquals($expected, $actual, $delta = 0) - { - if ($expected{0} === '#') { - // Expecting an error, so we do a straight string comparison - if ($expected === $actual) { - return TRUE; - } - $this->_errorMessage = 'Expected Error: ' . - $actual . ' !== ' . $expected; - return FALSE; - } - - $expectedComplex = new Complex($expected); - $actualComplex = new Complex($actual); - - if (!is_numeric($actualComplex->getReal()) || !is_numeric($expectedComplex->getReal())) { - if ($actualComplex->getReal() !== $expectedComplex->getReal()) { - $this->_errorMessage = 'Mismatched String: ' . - $actualComplex->getReal() . ' !== ' . $expectedComplex->getReal(); - return FALSE; - } - return TRUE; - } - - if ($actualComplex->getReal() < ($expectedComplex->getReal() - $delta) || - $actualComplex->getReal() > ($expectedComplex->getReal() + $delta)) { - $this->_errorMessage = 'Mismatched Real part: ' . - $actualComplex->getReal() . ' != ' . $expectedComplex->getReal(); - return FALSE; - } - - if ($actualComplex->getImaginary() < ($expectedComplex->getImaginary() - $delta) || - $actualComplex->getImaginary() > ($expectedComplex->getImaginary() + $delta)) { - $this->_errorMessage = 'Mismatched Imaginary part: ' . - $actualComplex->getImaginary() . ' != ' . $expectedComplex->getImaginary(); - return FALSE; - } - - if ($actualComplex->getSuffix() !== $actualComplex->getSuffix()) { - $this->_errorMessage = 'Mismatched Suffix: ' . - $actualComplex->getSuffix() . ' != ' . $expectedComplex->getSuffix(); - return FALSE; - } - - return TRUE; - } - - - public function getErrorMessage() { - return $this->_errorMessage; - } - -} +<?php + +include_once dirname(__FILE__).'/Complex.php'; + +class complexAssert +{ + private $_errorMessage = ''; + + public function assertComplexEquals($expected, $actual, $delta = 0) + { + if ($expected{0} === '#') { + // Expecting an error, so we do a straight string comparison + if ($expected === $actual) { + return true; + } + $this->_errorMessage = 'Expected Error: ' . $actual . ' !== ' . $expected; + return false; + } + + $expectedComplex = new Complex($expected); + $actualComplex = new Complex($actual); + + if (!is_numeric($actualComplex->getReal()) || !is_numeric($expectedComplex->getReal())) { + if ($actualComplex->getReal() !== $expectedComplex->getReal()) { + $this->_errorMessage = 'Mismatched String: ' . $actualComplex->getReal() . ' !== ' . $expectedComplex->getReal(); + return false; + } + return true; + } + + if ($actualComplex->getReal() < ($expectedComplex->getReal() - $delta) || + $actualComplex->getReal() > ($expectedComplex->getReal() + $delta)) { + $this->_errorMessage = 'Mismatched Real part: ' . $actualComplex->getReal() . ' != ' . $expectedComplex->getReal(); + return false; + } + + if ($actualComplex->getImaginary() < ($expectedComplex->getImaginary() - $delta) || + $actualComplex->getImaginary() > ($expectedComplex->getImaginary() + $delta)) { + $this->_errorMessage = 'Mismatched Imaginary part: ' . $actualComplex->getImaginary() . ' != ' . $expectedComplex->getImaginary(); + return false; + } + + if ($actualComplex->getSuffix() !== $actualComplex->getSuffix()) { + $this->_errorMessage = 'Mismatched Suffix: ' . $actualComplex->getSuffix() . ' != ' . $expectedComplex->getSuffix(); + return false; + } + + return true; + } + + public function getErrorMessage() + { + return $this->_errorMessage; + } +} diff --git a/unitTests/testDataFileIterator.php b/unitTests/testDataFileIterator.php index c6f3e0b2e..ee417e594 100644 --- a/unitTests/testDataFileIterator.php +++ b/unitTests/testDataFileIterator.php @@ -1,137 +1,136 @@ -<?php - -class testDataFileIterator implements Iterator -{ - - protected $file; - protected $key = 0; - protected $current; - - public function __construct($file) - { - $this->file = fopen($file, 'r'); - } - - public function __destruct() - { - fclose($this->file); - } - - public function rewind() - { - rewind($this->file); - $this->current = $this->_parseNextDataset(); - $this->key = 0; - } - - public function valid() - { - return !feof($this->file); - } - - public function key() - { - return $this->key; - } - - public function current() - { - return $this->current; - } - - public function next() - { - $this->current = $this->_parseNextDataset(); - $this->key++; - } - - private function _parseNextDataset() - { - // Read a line of test data from the file - do { - // Only take lines that contain test data and that aren't commented out - $testDataRow = trim(fgets($this->file)); - } while (($testDataRow > '') && ($testDataRow{0} === '#')); - - // Discard any comments at the end of the line - list($testData) = explode('//', $testDataRow); - - // Split data into an array of individual values and a result - $dataSet = $this->_getcsv($testData, ',', "'"); - foreach ($dataSet as &$dataValue) { - $dataValue = $this->_parseDataValue($dataValue); - } - unset($dataValue); - - return $dataSet; - } - - private function _getcsv($input, $delimiter, $enclosure) - { - if (function_exists('str_getcsv')) { - return str_getcsv($input, $delimiter, $enclosure); - } - - $temp = fopen('php://memory', 'rw'); - fwrite($temp, $input); - rewind($temp); - $data = fgetcsv($temp, strlen($input), $delimiter, $enclosure); - fclose($temp); - - if ($data === false) { - $data = array(null); - } - - return $data; - } - - private function _parseDataValue($dataValue) - { - // discard any white space - $dataValue = trim($dataValue); - // test for the required datatype and convert accordingly - if (!is_numeric($dataValue)) { - if($dataValue == '') { - $dataValue = null; - } elseif($dataValue == '""') { - $dataValue = ''; - } elseif(($dataValue[0] == '"') && ($dataValue[strlen($dataValue)-1] == '"')) { - $dataValue = substr($dataValue,1,-1); - } elseif(($dataValue[0] == '{') && ($dataValue[strlen($dataValue)-1] == '}')) { - $dataValue = explode(';',substr($dataValue,1,-1)); - foreach ($dataValue as &$dataRow) { - if (strpos($dataRow,'|') !== false) { - $dataRow = explode('|',$dataRow); - foreach ($dataRow as &$dataCell) { - $dataCell = $this->_parseDataValue($dataCell); - } - unset($dataCell); - } else { - $dataRow = $this->_parseDataValue($dataRow); - } - } - unset($dataRow); - } else { - switch (strtoupper($dataValue)) { - case 'NULL': - $dataValue = null; - break; - case 'TRUE': - $dataValue = true; - break; - case 'FALSE': - $dataValue = false; - break; - } - } - } else { - if (strpos($dataValue,'.') !== false) { - $dataValue = (float) $dataValue; - } else { - $dataValue = (int) $dataValue; - } - } - - return $dataValue; - } -} +<?php + +class testDataFileIterator implements Iterator +{ + protected $file; + protected $key = 0; + protected $current; + + public function __construct($file) + { + $this->file = fopen($file, 'r'); + } + + public function __destruct() + { + fclose($this->file); + } + + public function rewind() + { + rewind($this->file); + $this->current = $this->_parseNextDataset(); + $this->key = 0; + } + + public function valid() + { + return !feof($this->file); + } + + public function key() + { + return $this->key; + } + + public function current() + { + return $this->current; + } + + public function next() + { + $this->current = $this->_parseNextDataset(); + $this->key++; + } + + private function _parseNextDataset() + { + // Read a line of test data from the file + do { + // Only take lines that contain test data and that aren't commented out + $testDataRow = trim(fgets($this->file)); + } while (($testDataRow > '') && ($testDataRow{0} === '#')); + + // Discard any comments at the end of the line + list($testData) = explode('//', $testDataRow); + + // Split data into an array of individual values and a result + $dataSet = $this->_getcsv($testData, ',', "'"); + foreach ($dataSet as &$dataValue) { + $dataValue = $this->_parseDataValue($dataValue); + } + unset($dataValue); + + return $dataSet; + } + + private function _getcsv($input, $delimiter, $enclosure) + { + if (function_exists('str_getcsv')) { + return str_getcsv($input, $delimiter, $enclosure); + } + + $temp = fopen('php://memory', 'rw'); + fwrite($temp, $input); + rewind($temp); + $data = fgetcsv($temp, strlen($input), $delimiter, $enclosure); + fclose($temp); + + if ($data === false) { + $data = array(null); + } + + return $data; + } + + private function _parseDataValue($dataValue) + { + // discard any white space + $dataValue = trim($dataValue); + // test for the required datatype and convert accordingly + if (!is_numeric($dataValue)) { + if($dataValue == '') { + $dataValue = null; + } elseif($dataValue == '""') { + $dataValue = ''; + } elseif(($dataValue[0] == '"') && ($dataValue[strlen($dataValue)-1] == '"')) { + $dataValue = substr($dataValue,1,-1); + } elseif(($dataValue[0] == '{') && ($dataValue[strlen($dataValue)-1] == '}')) { + $dataValue = explode(';',substr($dataValue,1,-1)); + foreach ($dataValue as &$dataRow) { + if (strpos($dataRow,'|') !== false) { + $dataRow = explode('|',$dataRow); + foreach ($dataRow as &$dataCell) { + $dataCell = $this->_parseDataValue($dataCell); + } + unset($dataCell); + } else { + $dataRow = $this->_parseDataValue($dataRow); + } + } + unset($dataRow); + } else { + switch (strtoupper($dataValue)) { + case 'NULL': + $dataValue = null; + break; + case 'TRUE': + $dataValue = true; + break; + case 'FALSE': + $dataValue = false; + break; + } + } + } else { + if (strpos($dataValue,'.') !== false) { + $dataValue = (float) $dataValue; + } else { + $dataValue = (int) $dataValue; + } + } + + return $dataValue; + } +} From b6bc0db105236d9a5bf5fe15d1e112829ac27251 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sun, 17 May 2015 18:34:30 +0200 Subject: [PATCH 386/467] PSR2 Fixes --- Classes/PHPExcel/Worksheet.php | 2 +- unitTests/Classes/PHPExcel/AutoloaderTest.php | 6 +- .../PHPExcel/Calculation/DateTimeTest.php | 42 +++--- .../PHPExcel/Calculation/EngineeringTest.php | 121 ++++++++---------- .../PHPExcel/Calculation/FinancialTest.php | 66 +++++----- .../PHPExcel/Calculation/FunctionsTest.php | 30 ++--- .../PHPExcel/Calculation/LogicalTest.php | 14 +- .../PHPExcel/Calculation/LookupRefTest.php | 8 +- .../PHPExcel/Calculation/MathTrigTest.php | 62 +++++---- .../PHPExcel/Calculation/TextDataTest.php | 46 ++++--- .../Classes/PHPExcel/CalculationTest.php | 2 - .../PHPExcel/Cell/AdvancedValueBinderTest.php | 20 +-- .../Classes/PHPExcel/Cell/DataTypeTest.php | 4 +- .../PHPExcel/Cell/DefaultValueBinderTest.php | 3 +- .../Classes/PHPExcel/Cell/HyperlinkTest.php | 14 +- unitTests/Classes/PHPExcel/CellTest.php | 39 +++--- .../PHPExcel/Chart/DataSeriesValuesTest.php | 6 +- .../Classes/PHPExcel/Chart/LayoutTest.php | 6 +- .../Classes/PHPExcel/Chart/LegendTest.php | 13 +- .../PHPExcel/Reader/XEEValidatorTest.php | 1 - .../Classes/PHPExcel/ReferenceHelperTest.php | 1 - .../Classes/PHPExcel/Shared/CodePageTest.php | 7 +- .../Classes/PHPExcel/Shared/DateTest.php | 19 ++- .../Classes/PHPExcel/Shared/FileTest.php | 4 +- .../Classes/PHPExcel/Shared/FontTest.php | 11 +- .../PHPExcel/Shared/PasswordHasherTest.php | 3 +- .../Classes/PHPExcel/Shared/StringTest.php | 7 +- .../Classes/PHPExcel/Shared/TimeZoneTest.php | 5 +- .../Classes/PHPExcel/Style/ColorTest.php | 9 +- .../PHPExcel/Style/NumberFormatTest.php | 3 +- .../Worksheet/AutoFilter/Column/RuleTest.php | 1 - .../Worksheet/AutoFilter/ColumnTest.php | 3 +- .../PHPExcel/Worksheet/AutoFilterTest.php | 9 +- .../PHPExcel/Worksheet/CellCollectionTest.php | 4 +- .../PHPExcel/Worksheet/ColumnIteratorTest.php | 3 +- .../Worksheet/RowCellIteratorTest.php | 3 +- .../PHPExcel/Worksheet/RowIteratorTest.php | 3 +- unitTests/custom/Complex.php | 12 +- unitTests/testDataFileIterator.php | 18 +-- 39 files changed, 285 insertions(+), 345 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 5c6d3ed62..0946c7cb6 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -391,7 +391,7 @@ public function disconnectCells() * Code to execute when this worksheet is unset() * */ - function __destruct() + public function __destruct() { PHPExcel_Calculation::getInstance($this->_parent)->clearCalculationCacheForWorksheet($this->_title); diff --git a/unitTests/Classes/PHPExcel/AutoloaderTest.php b/unitTests/Classes/PHPExcel/AutoloaderTest.php index 286ef627c..f53015c6b 100644 --- a/unitTests/Classes/PHPExcel/AutoloaderTest.php +++ b/unitTests/Classes/PHPExcel/AutoloaderTest.php @@ -6,8 +6,7 @@ class AutoloaderTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -52,5 +51,4 @@ public function testAutoloadInstantiateSuccess() // ... of the correct type $this->assertTrue(is_a($result,'PHPExcel_Calculation_Function')); } - -} \ No newline at end of file +} diff --git a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php index 50cdec99c..8b28f2fac 100644 --- a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php @@ -8,8 +8,7 @@ class DateTimeTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -24,7 +23,7 @@ public function testDATE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -77,7 +76,7 @@ public function testDATEVALUE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEVALUE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEVALUE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -114,7 +113,7 @@ public function testYEAR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEAR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEAR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -130,7 +129,7 @@ public function testMONTH() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MONTHOFYEAR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MONTHOFYEAR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -146,7 +145,7 @@ public function testWEEKNUM() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WEEKOFYEAR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WEEKOFYEAR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -162,7 +161,7 @@ public function testWEEKDAY() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFWEEK'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFWEEK'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -178,7 +177,7 @@ public function testDAY() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFMONTH'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFMONTH'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -194,7 +193,7 @@ public function testTIME() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIME'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIME'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -231,7 +230,7 @@ public function testTIMEVALUE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIMEVALUE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIMEVALUE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -268,7 +267,7 @@ public function testHOUR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','HOUROFDAY'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','HOUROFDAY'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -284,7 +283,7 @@ public function testMINUTE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MINUTEOFHOUR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MINUTEOFHOUR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -300,7 +299,7 @@ public function testSECOND() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','SECONDOFMINUTE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','SECONDOFMINUTE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -316,7 +315,7 @@ public function testNETWORKDAYS() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','NETWORKDAYS'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','NETWORKDAYS'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -332,7 +331,7 @@ public function testWORKDAY() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WORKDAY'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WORKDAY'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -348,7 +347,7 @@ public function testEDATE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EDATE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EDATE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -385,7 +384,7 @@ public function testEOMONTH() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EOMONTH'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EOMONTH'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -422,7 +421,7 @@ public function testDATEDIF() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEDIF'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEDIF'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -438,7 +437,7 @@ public function testDAYS360() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYS360'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYS360'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -454,7 +453,7 @@ public function testYEARFRAC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEARFRAC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEARFRAC'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -462,5 +461,4 @@ public function providerYEARFRAC() { return new testDataFileIterator('rawTestData/Calculation/DateTime/YEARFRAC.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php b/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php index c5a829615..08448f558 100644 --- a/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php @@ -12,8 +12,7 @@ class EngineeringTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -28,7 +27,7 @@ public function testBESSELI() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELI'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELI'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -44,7 +43,7 @@ public function testBESSELJ() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELJ'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELJ'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -60,7 +59,7 @@ public function testBESSELK() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELK'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELK'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -76,7 +75,7 @@ public function testBESSELY() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELY'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELY'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -92,7 +91,7 @@ public function testCOMPLEX() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','COMPLEX'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','COMPLEX'), $args); $this->assertEquals($expectedResult, $result); } @@ -108,7 +107,7 @@ public function testIMAGINARY() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMAGINARY'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMAGINARY'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -124,7 +123,7 @@ public function testIMREAL() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMREAL'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMREAL'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -140,7 +139,7 @@ public function testIMABS() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMABS'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMABS'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -156,7 +155,7 @@ public function testIMARGUMENT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMARGUMENT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMARGUMENT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -172,10 +171,9 @@ public function testIMCONJUGATE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCONJUGATE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCONJUGATE'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMCONJUGATE() @@ -190,10 +188,9 @@ public function testIMCOS() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCOS'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCOS'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMCOS() @@ -208,10 +205,9 @@ public function testIMDIV() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMDIV'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMDIV'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMDIV() @@ -226,10 +222,9 @@ public function testIMEXP() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMEXP'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMEXP'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMEXP() @@ -244,10 +239,9 @@ public function testIMLN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLN'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMLN() @@ -262,10 +256,9 @@ public function testIMLOG2() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG2'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG2'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMLOG2() @@ -280,10 +273,9 @@ public function testIMLOG10() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG10'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG10'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMLOG10() @@ -298,10 +290,9 @@ public function testIMPOWER() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPOWER'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPOWER'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMPOWER() @@ -316,10 +307,9 @@ public function testIMPRODUCT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPRODUCT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPRODUCT'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMPRODUCT() @@ -334,10 +324,9 @@ public function testIMSIN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSIN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSIN'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMSIN() @@ -352,10 +341,9 @@ public function testIMSQRT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSQRT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSQRT'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMSQRT() @@ -370,10 +358,9 @@ public function testIMSUB() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUB'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUB'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMSUB() @@ -388,10 +375,9 @@ public function testIMSUM() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'), $args); $complexAssert = new complexAssert(); - $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), - $complexAssert->getErrorMessage()); + $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), $complexAssert->getErrorMessage()); } public function providerIMSUM() @@ -406,7 +392,7 @@ public function testERF() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERF'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERF'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -422,7 +408,7 @@ public function testERFC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERFC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERFC'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -438,7 +424,7 @@ public function testBIN2DEC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTODEC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTODEC'), $args); $this->assertEquals($expectedResult, $result); } @@ -454,7 +440,7 @@ public function testBIN2HEX() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOHEX'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOHEX'), $args); $this->assertEquals($expectedResult, $result); } @@ -470,7 +456,7 @@ public function testBIN2OCT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOOCT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOOCT'), $args); $this->assertEquals($expectedResult, $result); } @@ -486,7 +472,7 @@ public function testDEC2BIN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOBIN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOBIN'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -502,7 +488,7 @@ public function testDEC2HEX() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOHEX'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOHEX'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -518,7 +504,7 @@ public function testDEC2OCT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOOCT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOOCT'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -534,7 +520,7 @@ public function testHEX2BIN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOBIN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOBIN'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -550,7 +536,7 @@ public function testHEX2DEC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTODEC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTODEC'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -566,7 +552,7 @@ public function testHEX2OCT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOOCT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOOCT'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -582,7 +568,7 @@ public function testOCT2BIN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOBIN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOBIN'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -598,7 +584,7 @@ public function testOCT2DEC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTODEC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTODEC'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -614,7 +600,7 @@ public function testOCT2HEX() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOHEX'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOHEX'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -630,7 +616,7 @@ public function testDELTA() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DELTA'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DELTA'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -646,7 +632,7 @@ public function testGESTEP() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','GESTEP'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','GESTEP'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -686,7 +672,7 @@ public function testCONVERTUOM() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','CONVERTUOM'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','CONVERTUOM'), $args); $this->assertEquals($expectedResult, $result, null); } @@ -694,5 +680,4 @@ public function providerCONVERTUOM() { return new testDataFileIterator('rawTestData/Calculation/Engineering/CONVERTUOM.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php b/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php index efaa60e57..f6e39814c 100644 --- a/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php @@ -8,8 +8,7 @@ class FinancialTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -24,7 +23,7 @@ public function testACCRINT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -40,7 +39,7 @@ public function testACCRINTM() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINTM'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINTM'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -56,7 +55,7 @@ public function testAMORDEGRC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORDEGRC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORDEGRC'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -72,7 +71,7 @@ public function testAMORLINC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORLINC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORLINC'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -88,7 +87,7 @@ public function testCOUPDAYBS() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYBS'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYBS'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -104,7 +103,7 @@ public function testCOUPDAYS() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYS'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYS'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -120,7 +119,7 @@ public function testCOUPDAYSNC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYSNC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYSNC'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -136,7 +135,7 @@ public function testCOUPNCD() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNCD'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNCD'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -152,7 +151,7 @@ public function testCOUPNUM() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNUM'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNUM'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -168,7 +167,7 @@ public function testCOUPPCD() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPPCD'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPPCD'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -184,7 +183,7 @@ public function testCUMIPMT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMIPMT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMIPMT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -200,7 +199,7 @@ public function testCUMPRINC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMPRINC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMPRINC'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -216,7 +215,7 @@ public function testDB() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DB'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DB'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -232,7 +231,7 @@ public function testDDB() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DDB'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DDB'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -248,7 +247,7 @@ public function testDISC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DISC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DISC'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -264,7 +263,7 @@ public function testDOLLARDE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARDE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARDE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -280,7 +279,7 @@ public function testDOLLARFR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARFR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARFR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -296,7 +295,7 @@ public function testEFFECT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','EFFECT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','EFFECT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -312,7 +311,7 @@ public function testFV() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FV'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FV'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -328,7 +327,7 @@ public function testFVSCHEDULE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FVSCHEDULE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','FVSCHEDULE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -344,7 +343,7 @@ public function testINTRATE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','INTRATE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','INTRATE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -360,7 +359,7 @@ public function testIPMT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IPMT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IPMT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -376,7 +375,7 @@ public function testIRR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IRR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','IRR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -392,7 +391,7 @@ public function testISPMT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ISPMT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','ISPMT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -408,7 +407,7 @@ public function testMIRR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','MIRR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','MIRR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -424,7 +423,7 @@ public function testNOMINAL() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NOMINAL'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NOMINAL'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -440,7 +439,7 @@ public function testNPER() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPER'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPER'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -456,7 +455,7 @@ public function testNPV() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPV'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPV'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -472,7 +471,7 @@ public function testPRICE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','PRICE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','PRICE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -488,7 +487,7 @@ public function testRATE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','RATE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','RATE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -504,7 +503,7 @@ public function testXIRR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Financial','XIRR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Financial','XIRR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -512,5 +511,4 @@ public function providerXIRR() { return new testDataFileIterator('rawTestData/Calculation/Financial/XIRR.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php b/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php index 0e9fb50d7..61c48205a 100644 --- a/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php @@ -8,8 +8,7 @@ class FunctionsTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -72,7 +71,7 @@ public function testIS_BLANK() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_BLANK'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_BLANK'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -88,7 +87,7 @@ public function testIS_ERR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -104,7 +103,7 @@ public function testIS_ERROR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERROR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERROR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -120,7 +119,7 @@ public function testERROR_TYPE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','ERROR_TYPE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','ERROR_TYPE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -136,7 +135,7 @@ public function testIS_LOGICAL() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_LOGICAL'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_LOGICAL'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -152,7 +151,7 @@ public function testIS_NA() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NA'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NA'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -168,7 +167,7 @@ public function testIS_NUMBER() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NUMBER'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NUMBER'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -184,7 +183,7 @@ public function testIS_TEXT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_TEXT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_TEXT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -200,7 +199,7 @@ public function testIS_NONTEXT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NONTEXT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NONTEXT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -216,7 +215,7 @@ public function testIS_EVEN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_EVEN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_EVEN'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -232,7 +231,7 @@ public function testIS_ODD() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ODD'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ODD'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -248,7 +247,7 @@ public function testTYPE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','TYPE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','TYPE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -264,7 +263,7 @@ public function testN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Functions','N'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Functions','N'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -272,5 +271,4 @@ public function providerN() { return new testDataFileIterator('rawTestData/Calculation/Functions/N.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php b/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php index 21d497725..e475c30fb 100644 --- a/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php @@ -8,8 +8,7 @@ class LogicalTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -36,7 +35,7 @@ public function testAND() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_AND'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_AND'), $args); $this->assertEquals($expectedResult, $result); } @@ -52,7 +51,7 @@ public function testOR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_OR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_OR'), $args); $this->assertEquals($expectedResult, $result); } @@ -68,7 +67,7 @@ public function testNOT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','NOT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','NOT'), $args); $this->assertEquals($expectedResult, $result); } @@ -84,7 +83,7 @@ public function testIF() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','STATEMENT_IF'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','STATEMENT_IF'), $args); $this->assertEquals($expectedResult, $result); } @@ -100,7 +99,7 @@ public function testIFERROR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_Logical','IFERROR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_Logical','IFERROR'), $args); $this->assertEquals($expectedResult, $result); } @@ -108,5 +107,4 @@ public function providerIFERROR() { return new testDataFileIterator('rawTestData/Calculation/Logical/IFERROR.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php index ed4d6ee0d..1408b73b8 100644 --- a/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php @@ -8,8 +8,7 @@ class LookupRefTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -24,7 +23,7 @@ public function testHLOOKUP() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','HLOOKUP'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','HLOOKUP'), $args); $this->assertEquals($expectedResult, $result); } @@ -40,7 +39,7 @@ public function testVLOOKUP() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','VLOOKUP'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','VLOOKUP'), $args); $this->assertEquals($expectedResult, $result); } @@ -48,5 +47,4 @@ public function providerVLOOKUP() { return new testDataFileIterator('rawTestData/Calculation/LookupRef/VLOOKUP.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php index 9772a7e77..40d1c5050 100644 --- a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php @@ -8,8 +8,7 @@ class MathTrigTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -24,7 +23,7 @@ public function testATAN2() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ATAN2'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ATAN2'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -40,7 +39,7 @@ public function testCEILING() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','CEILING'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','CEILING'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -56,7 +55,7 @@ public function testCOMBIN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','COMBIN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','COMBIN'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -72,7 +71,7 @@ public function testEVEN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','EVEN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','EVEN'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -88,7 +87,7 @@ public function testODD() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ODD'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ODD'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -104,7 +103,7 @@ public function testFACT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -120,7 +119,7 @@ public function testFACTDOUBLE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACTDOUBLE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACTDOUBLE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -136,7 +135,7 @@ public function testFLOOR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FLOOR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FLOOR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -152,7 +151,7 @@ public function testGCD() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','GCD'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','GCD'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -168,7 +167,7 @@ public function testLCM() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LCM'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LCM'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -184,7 +183,7 @@ public function testINT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','INT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','INT'), $args); $this->assertEquals($expectedResult, $result); } @@ -200,7 +199,7 @@ public function testSIGN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SIGN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SIGN'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -216,7 +215,7 @@ public function testPOWER() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','POWER'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','POWER'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -232,7 +231,7 @@ public function testLOG() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LOG_BASE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LOG_BASE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -248,7 +247,7 @@ public function testMOD() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MOD'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MOD'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -264,7 +263,7 @@ public function testMDETERM() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MDETERM'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MDETERM'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -280,7 +279,7 @@ public function testMINVERSE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MINVERSE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MINVERSE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -296,7 +295,7 @@ public function testMMULT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MMULT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MMULT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -312,7 +311,7 @@ public function testMULTINOMIAL() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MULTINOMIAL'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MULTINOMIAL'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -329,7 +328,7 @@ public function testMROUND() $args = func_get_args(); $expectedResult = array_pop($args); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MROUND'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MROUND'), $args); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_ARRAY); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -346,7 +345,7 @@ public function testPRODUCT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','PRODUCT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','PRODUCT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -362,7 +361,7 @@ public function testQUOTIENT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','QUOTIENT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','QUOTIENT'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -378,7 +377,7 @@ public function testROUNDUP() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDUP'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDUP'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -394,7 +393,7 @@ public function testROUNDDOWN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDDOWN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDDOWN'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -410,7 +409,7 @@ public function testSERIESSUM() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SERIESSUM'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SERIESSUM'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -426,7 +425,7 @@ public function testSUMSQ() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SUMSQ'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SUMSQ'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -442,7 +441,7 @@ public function testTRUNC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','TRUNC'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','TRUNC'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -458,7 +457,7 @@ public function testROMAN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROMAN'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROMAN'), $args); $this->assertEquals($expectedResult, $result); } @@ -474,7 +473,7 @@ public function testSQRTPI() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SQRTPI'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SQRTPI'), $args); $this->assertEquals($expectedResult, $result, null, 1E-12); } @@ -556,5 +555,4 @@ public function providerSUMIF() ), ); } - } diff --git a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php index c7ed3b577..604c7a118 100644 --- a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php @@ -8,8 +8,7 @@ class TextDataTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -24,7 +23,7 @@ public function testCHAR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','CHARACTER'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','CHARACTER'), $args); $this->assertEquals($expectedResult, $result); } @@ -40,7 +39,7 @@ public function testCODE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','ASCIICODE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','ASCIICODE'), $args); $this->assertEquals($expectedResult, $result); } @@ -56,7 +55,7 @@ public function testCONCATENATE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','CONCATENATE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','CONCATENATE'), $args); $this->assertEquals($expectedResult, $result); } @@ -72,7 +71,7 @@ public function testLEFT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LEFT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LEFT'), $args); $this->assertEquals($expectedResult, $result); } @@ -88,7 +87,7 @@ public function testMID() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','MID'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','MID'), $args); $this->assertEquals($expectedResult, $result); } @@ -104,7 +103,7 @@ public function testRIGHT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RIGHT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RIGHT'), $args); $this->assertEquals($expectedResult, $result); } @@ -120,7 +119,7 @@ public function testLOWER() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LOWERCASE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','LOWERCASE'), $args); $this->assertEquals($expectedResult, $result); } @@ -136,7 +135,7 @@ public function testUPPER() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','UPPERCASE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','UPPERCASE'), $args); $this->assertEquals($expectedResult, $result); } @@ -152,7 +151,7 @@ public function testPROPER() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','PROPERCASE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','PROPERCASE'), $args); $this->assertEquals($expectedResult, $result); } @@ -168,7 +167,7 @@ public function testLEN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','STRINGLENGTH'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','STRINGLENGTH'), $args); $this->assertEquals($expectedResult, $result); } @@ -184,7 +183,7 @@ public function testSEARCH() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHINSENSITIVE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHINSENSITIVE'), $args); $this->assertEquals($expectedResult, $result); } @@ -200,7 +199,7 @@ public function testFIND() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHSENSITIVE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHSENSITIVE'), $args); $this->assertEquals($expectedResult, $result); } @@ -216,7 +215,7 @@ public function testREPLACE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','REPLACE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','REPLACE'), $args); $this->assertEquals($expectedResult, $result); } @@ -232,7 +231,7 @@ public function testSUBSTITUTE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SUBSTITUTE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','SUBSTITUTE'), $args); $this->assertEquals($expectedResult, $result); } @@ -248,7 +247,7 @@ public function testTRIM() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMSPACES'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMSPACES'), $args); $this->assertEquals($expectedResult, $result); } @@ -264,7 +263,7 @@ public function testCLEAN() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMNONPRINTABLE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMNONPRINTABLE'), $args); $this->assertEquals($expectedResult, $result); } @@ -280,7 +279,7 @@ public function testDOLLAR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','DOLLAR'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','DOLLAR'), $args); $this->assertEquals($expectedResult, $result); } @@ -296,7 +295,7 @@ public function testFIXED() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','FIXEDFORMAT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','FIXEDFORMAT'), $args); $this->assertEquals($expectedResult, $result); } @@ -312,7 +311,7 @@ public function testT() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RETURNSTRING'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','RETURNSTRING'), $args); $this->assertEquals($expectedResult, $result); } @@ -333,7 +332,7 @@ public function testTEXT() $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TEXTFORMAT'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TEXTFORMAT'), $args); $this->assertEquals($expectedResult, $result); } @@ -353,7 +352,7 @@ public function testVALUE() $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','VALUE'),$args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','VALUE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -361,5 +360,4 @@ public function providerVALUE() { return new testDataFileIterator('rawTestData/Calculation/TextData/VALUE.data'); } - } diff --git a/unitTests/Classes/PHPExcel/CalculationTest.php b/unitTests/Classes/PHPExcel/CalculationTest.php index 1de827ca8..bc221ce2a 100644 --- a/unitTests/Classes/PHPExcel/CalculationTest.php +++ b/unitTests/Classes/PHPExcel/CalculationTest.php @@ -4,7 +4,6 @@ class CalculationTest extends PHPUnit_Framework_TestCase { - public function setUp() { if (!defined('PHPEXCEL_ROOT')) { @@ -33,5 +32,4 @@ public function providerBinaryComparisonOperation() { return new testDataFileIterator('rawTestData/CalculationBinaryComparisonOperation.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php b/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php index b9b74d2ac..0a55ba730 100644 --- a/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php +++ b/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php @@ -13,20 +13,20 @@ public function setUp() public function provider() { if (!class_exists('PHPExcel_Style_NumberFormat')) { - $this->setUp(); + $this->setUp(); } $currencyUSD = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE; $currencyEURO = str_replace('$', '€', PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE); return array( - array('10%', 0.1, PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00, ',', '.', '$'), - array('$10.11', 10.11, $currencyUSD, ',', '.', '$'), - array('$1,010.12', 1010.12, $currencyUSD, ',', '.', '$'), - array('$20,20', 20.2, $currencyUSD, '.', ',', '$'), - array('$2.020,20', 2020.2, $currencyUSD, '.', ',', '$'), - array('€2.020,20', 2020.2, $currencyEURO, '.', ',', '€'), - array('€ 2.020,20', 2020.2, $currencyEURO, '.', ',', '€'), - array('€2,020.22', 2020.22, $currencyEURO, ',', '.', '€'), + array('10%', 0.1, PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00, ',', '.', '$'), + array('$10.11', 10.11, $currencyUSD, ',', '.', '$'), + array('$1,010.12', 1010.12, $currencyUSD, ',', '.', '$'), + array('$20,20', 20.2, $currencyUSD, '.', ',', '$'), + array('$2.020,20', 2020.2, $currencyUSD, '.', ',', '$'), + array('€2.020,20', 2020.2, $currencyEURO, '.', ',', '€'), + array('€ 2.020,20', 2020.2, $currencyEURO, '.', ',', '€'), + array('€2,020.22', 2020.22, $currencyEURO, ',', '.', '€'), ); } @@ -70,4 +70,4 @@ public function testCurrency($value, $valueBinded, $format, $thousandsSeparator, $binder->bindValue($cell, $value); $this->assertEquals($valueBinded, $cell->getValue()); } -} \ No newline at end of file +} diff --git a/unitTests/Classes/PHPExcel/Cell/DataTypeTest.php b/unitTests/Classes/PHPExcel/Cell/DataTypeTest.php index 00d965f13..1180c9d6f 100644 --- a/unitTests/Classes/PHPExcel/Cell/DataTypeTest.php +++ b/unitTests/Classes/PHPExcel/Cell/DataTypeTest.php @@ -6,8 +6,7 @@ class DataTypeTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -20,5 +19,4 @@ public function testGetErrorCodes() $this->assertGreaterThan(0, count($result)); $this->assertArrayHasKey('#NULL!', $result); } - } diff --git a/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php b/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php index a23261266..37287b1fe 100644 --- a/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php +++ b/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php @@ -8,8 +8,7 @@ class DefaultValueBinderTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); diff --git a/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php b/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php index 9fbbb5a3b..42dff6a56 100644 --- a/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php +++ b/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php @@ -6,8 +6,7 @@ class HyperlinkTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -20,7 +19,7 @@ public function testGetUrl() $testInstance = new PHPExcel_Cell_Hyperlink($urlValue); $result = $testInstance->getUrl(); - $this->assertEquals($urlValue,$result); + $this->assertEquals($urlValue, $result); } public function testSetUrl() @@ -33,7 +32,7 @@ public function testSetUrl() $this->assertTrue($result instanceof PHPExcel_Cell_Hyperlink); $result = $testInstance->getUrl(); - $this->assertEquals($newUrlValue,$result); + $this->assertEquals($newUrlValue, $result); } public function testGetTooltip() @@ -43,7 +42,7 @@ public function testGetTooltip() $testInstance = new PHPExcel_Cell_Hyperlink(null, $tooltipValue); $result = $testInstance->getTooltip(); - $this->assertEquals($tooltipValue,$result); + $this->assertEquals($tooltipValue, $result); } public function testSetTooltip() @@ -56,7 +55,7 @@ public function testSetTooltip() $this->assertTrue($result instanceof PHPExcel_Cell_Hyperlink); $result = $testInstance->getTooltip(); - $this->assertEquals($newTooltipValue,$result); + $this->assertEquals($newTooltipValue, $result); } public function testIsInternal() @@ -82,7 +81,6 @@ public function testGetHashCode() $testInstance = new PHPExcel_Cell_Hyperlink($urlValue, $tooltipValue); $result = $testInstance->getHashCode(); - $this->assertEquals($initialExpectedHash,$result); + $this->assertEquals($initialExpectedHash, $result); } - } diff --git a/unitTests/Classes/PHPExcel/CellTest.php b/unitTests/Classes/PHPExcel/CellTest.php index 2d8567e9c..9680294a5 100644 --- a/unitTests/Classes/PHPExcel/CellTest.php +++ b/unitTests/Classes/PHPExcel/CellTest.php @@ -21,7 +21,7 @@ public function testColumnIndexFromString() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','columnIndexFromString'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','columnIndexFromString'), $args); $this->assertEquals($expectedResult, $result); } @@ -34,7 +34,7 @@ public function testColumnIndexFromStringTooLong() { $cellAddress = 'ABCD'; try { - $result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'),$cellAddress); + $result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'), $cellAddress); } catch (PHPExcel_Exception $e) { $this->assertEquals($e->getMessage(), 'Column string index can not be longer than 3 characters'); return; @@ -46,7 +46,7 @@ public function testColumnIndexFromStringTooShort() { $cellAddress = ''; try { - $result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'),$cellAddress); + $result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'), $cellAddress); } catch (PHPExcel_Exception $e) { $this->assertEquals($e->getMessage(), 'Column string index can not be empty'); return; @@ -61,7 +61,7 @@ public function testStringFromColumnIndex() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','stringFromColumnIndex'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','stringFromColumnIndex'), $args); $this->assertEquals($expectedResult, $result); } @@ -77,7 +77,7 @@ public function testCoordinateFromString() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','coordinateFromString'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','coordinateFromString'), $args); $this->assertEquals($expectedResult, $result); } @@ -90,7 +90,7 @@ public function testCoordinateFromStringWithRangeAddress() { $cellAddress = 'A1:AI2012'; try { - $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); + $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'), $cellAddress); } catch (PHPExcel_Exception $e) { $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); return; @@ -102,7 +102,7 @@ public function testCoordinateFromStringWithEmptyAddress() { $cellAddress = ''; try { - $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); + $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'), $cellAddress); } catch (PHPExcel_Exception $e) { $this->assertEquals($e->getMessage(), 'Cell coordinate can not be zero-length string'); return; @@ -114,7 +114,7 @@ public function testCoordinateFromStringWithInvalidAddress() { $cellAddress = 'AI'; try { - $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress); + $result = call_user_func(array('PHPExcel_Cell','coordinateFromString'), $cellAddress); } catch (PHPExcel_Exception $e) { $this->assertEquals($e->getMessage(), 'Invalid cell coordinate '.$cellAddress); return; @@ -129,7 +129,7 @@ public function testAbsoluteCoordinateFromString() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','absoluteCoordinate'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','absoluteCoordinate'), $args); $this->assertEquals($expectedResult, $result); } @@ -142,7 +142,7 @@ public function testAbsoluteCoordinateFromStringWithRangeAddress() { $cellAddress = 'A1:AI2012'; try { - $result = call_user_func(array('PHPExcel_Cell','absoluteCoordinate'),$cellAddress); + $result = call_user_func(array('PHPExcel_Cell','absoluteCoordinate'), $cellAddress); } catch (PHPExcel_Exception $e) { $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); return; @@ -157,7 +157,7 @@ public function testAbsoluteReferenceFromString() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','absoluteReference'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','absoluteReference'), $args); $this->assertEquals($expectedResult, $result); } @@ -170,7 +170,7 @@ public function testAbsoluteReferenceFromStringWithRangeAddress() { $cellAddress = 'A1:AI2012'; try { - $result = call_user_func(array('PHPExcel_Cell','absoluteReference'),$cellAddress); + $result = call_user_func(array('PHPExcel_Cell','absoluteReference'), $cellAddress); } catch (PHPExcel_Exception $e) { $this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); return; @@ -185,7 +185,7 @@ public function testSplitRange() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','splitRange'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','splitRange'), $args); foreach ($result as $key => $split) { if (!is_array($expectedResult[$key])) { $this->assertEquals($expectedResult[$key], $split[0]); @@ -207,7 +207,7 @@ public function testBuildRange() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','buildRange'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','buildRange'), $args); $this->assertEquals($expectedResult, $result); } @@ -220,7 +220,7 @@ public function testBuildRangeInvalid() { $cellRange = ''; try { - $result = call_user_func(array('PHPExcel_Cell','buildRange'),$cellRange); + $result = call_user_func(array('PHPExcel_Cell','buildRange'), $cellRange); } catch (PHPExcel_Exception $e) { $this->assertEquals($e->getMessage(), 'Range does not contain any information'); return; @@ -235,7 +235,7 @@ public function testRangeBoundaries() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','rangeBoundaries'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','rangeBoundaries'), $args); $this->assertEquals($expectedResult, $result); } @@ -251,7 +251,7 @@ public function testRangeDimension() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','rangeDimension'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','rangeDimension'), $args); $this->assertEquals($expectedResult, $result); } @@ -267,7 +267,7 @@ public function testGetRangeBoundaries() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','getRangeBoundaries'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','getRangeBoundaries'), $args); $this->assertEquals($expectedResult, $result); } @@ -283,7 +283,7 @@ public function testExtractAllCellReferencesInRange() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Cell','extractAllCellReferencesInRange'),$args); + $result = call_user_func_array(array('PHPExcel_Cell','extractAllCellReferencesInRange'), $args); $this->assertEquals($expectedResult, $result); } @@ -291,5 +291,4 @@ public function providerExtractAllCellReferencesInRange() { return new testDataFileIterator('rawTestData/CellExtractAllCellReferencesInRange.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php b/unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php index 78ca67d71..5bb527cd5 100644 --- a/unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php +++ b/unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php @@ -6,8 +6,7 @@ class DataSeriesValuesTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -49,7 +48,6 @@ public function testGetDataType() $setValue = $testInstance->setDataType($dataTypeValue); $result = $testInstance->getDataType(); - $this->assertEquals($dataTypeValue,$result); + $this->assertEquals($dataTypeValue, $result); } - } diff --git a/unitTests/Classes/PHPExcel/Chart/LayoutTest.php b/unitTests/Classes/PHPExcel/Chart/LayoutTest.php index 457b8551c..a06b09b48 100644 --- a/unitTests/Classes/PHPExcel/Chart/LayoutTest.php +++ b/unitTests/Classes/PHPExcel/Chart/LayoutTest.php @@ -6,8 +6,7 @@ class LayoutTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -31,7 +30,6 @@ public function testGetLayoutTarget() $setValue = $testInstance->setLayoutTarget($LayoutTargetValue); $result = $testInstance->getLayoutTarget(); - $this->assertEquals($LayoutTargetValue,$result); + $this->assertEquals($LayoutTargetValue, $result); } - } diff --git a/unitTests/Classes/PHPExcel/Chart/LegendTest.php b/unitTests/Classes/PHPExcel/Chart/LegendTest.php index 47af687bd..462fbdc97 100644 --- a/unitTests/Classes/PHPExcel/Chart/LegendTest.php +++ b/unitTests/Classes/PHPExcel/Chart/LegendTest.php @@ -6,8 +6,7 @@ class LegendTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -39,7 +38,7 @@ public function testSetInvalidPositionReturnsFalse() $this->assertFalse($result); // Ensure that value is unchanged $result = $testInstance->getPosition(); - $this->assertEquals(PHPExcel_Chart_Legend::POSITION_RIGHT,$result); + $this->assertEquals(PHPExcel_Chart_Legend::POSITION_RIGHT, $result); } public function testGetPosition() @@ -50,7 +49,7 @@ public function testGetPosition() $setValue = $testInstance->setPosition($PositionValue); $result = $testInstance->getPosition(); - $this->assertEquals($PositionValue,$result); + $this->assertEquals($PositionValue, $result); } public function testSetPositionXL() @@ -80,7 +79,7 @@ public function testSetInvalidXLPositionReturnsFalse() $this->assertFalse($result); // Ensure that value is unchanged $result = $testInstance->getPositionXL(); - $this->assertEquals(PHPExcel_Chart_Legend::xlLegendPositionRight,$result); + $this->assertEquals(PHPExcel_Chart_Legend::xlLegendPositionRight, $result); } public function testGetPositionXL() @@ -91,7 +90,7 @@ public function testGetPositionXL() $setValue = $testInstance->setPositionXL($PositionValue); $result = $testInstance->getPositionXL(); - $this->assertEquals($PositionValue,$result); + $this->assertEquals($PositionValue, $result); } public function testSetOverlay() @@ -128,7 +127,7 @@ public function testGetOverlay() $setValue = $testInstance->setOverlay($OverlayValue); $result = $testInstance->getOverlay(); - $this->assertEquals($OverlayValue,$result); + $this->assertEquals($OverlayValue, $result); } } diff --git a/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php b/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php index 47ad1f5dc..e781f71ee 100644 --- a/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php +++ b/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php @@ -51,5 +51,4 @@ public function providerValidXML() } return $tests; } - } diff --git a/unitTests/Classes/PHPExcel/ReferenceHelperTest.php b/unitTests/Classes/PHPExcel/ReferenceHelperTest.php index 35c4a50c4..cf40f73aa 100644 --- a/unitTests/Classes/PHPExcel/ReferenceHelperTest.php +++ b/unitTests/Classes/PHPExcel/ReferenceHelperTest.php @@ -54,5 +54,4 @@ public function testColumnReverseSort() $this->assertEquals($columnExpectedResult[$key], $value); } } - } diff --git a/unitTests/Classes/PHPExcel/Shared/CodePageTest.php b/unitTests/Classes/PHPExcel/Shared/CodePageTest.php index 5463e858c..d434694e0 100644 --- a/unitTests/Classes/PHPExcel/Shared/CodePageTest.php +++ b/unitTests/Classes/PHPExcel/Shared/CodePageTest.php @@ -21,7 +21,7 @@ public function testCodePageNumberToName() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_CodePage','NumberToName'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_CodePage','NumberToName'), $args); $this->assertEquals($expectedResult, $result); } @@ -34,7 +34,7 @@ public function testNumberToNameWithInvalidCodePage() { $invalidCodePage = 12345; try { - $result = call_user_func(array('PHPExcel_Shared_CodePage','NumberToName'),$invalidCodePage); + $result = call_user_func(array('PHPExcel_Shared_CodePage','NumberToName'), $invalidCodePage); } catch (Exception $e) { $this->assertEquals($e->getMessage(), 'Unknown codepage: 12345'); return; @@ -46,12 +46,11 @@ public function testNumberToNameWithUnsupportedCodePage() { $unsupportedCodePage = 720; try { - $result = call_user_func(array('PHPExcel_Shared_CodePage','NumberToName'),$unsupportedCodePage); + $result = call_user_func(array('PHPExcel_Shared_CodePage','NumberToName'), $unsupportedCodePage); } catch (Exception $e) { $this->assertEquals($e->getMessage(), 'Code page 720 not supported.'); return; } $this->fail('An expected exception has not been raised.'); } - } diff --git a/unitTests/Classes/PHPExcel/Shared/DateTest.php b/unitTests/Classes/PHPExcel/Shared/DateTest.php index ffac7095b..50049f6e4 100644 --- a/unitTests/Classes/PHPExcel/Shared/DateTest.php +++ b/unitTests/Classes/PHPExcel/Shared/DateTest.php @@ -22,7 +22,7 @@ public function testSetExcelCalendar() ); foreach ($calendarValues as $calendarValue) { - $result = call_user_func(array('PHPExcel_Shared_Date','setExcelCalendar'),$calendarValue); + $result = call_user_func(array('PHPExcel_Shared_Date','setExcelCalendar'), $calendarValue); $this->assertTrue($result); } } @@ -30,7 +30,7 @@ public function testSetExcelCalendar() public function testSetExcelCalendarWithInvalidValue() { $unsupportedCalendar = '2012'; - $result = call_user_func(array('PHPExcel_Shared_Date','setExcelCalendar'),$unsupportedCalendar); + $result = call_user_func(array('PHPExcel_Shared_Date','setExcelCalendar'), $unsupportedCalendar); $this->assertFalse($result); } @@ -49,7 +49,7 @@ public function testDateTimeExcelToPHP1900() if ($args[0] < 1) { $expectedResult += gmmktime(0,0,0); } - $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'), $args); $this->assertEquals($expectedResult, $result); } @@ -70,7 +70,7 @@ public function testDateTimePHPToExcel1900() $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'), $args); $this->assertEquals($expectedResult, $result, null, 1E-5); } @@ -91,7 +91,7 @@ public function testDateTimeFormattedPHPToExcel1900() $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Date','FormattedPHPToExcel'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','FormattedPHPToExcel'), $args); $this->assertEquals($expectedResult, $result, null, 1E-5); } @@ -115,7 +115,7 @@ public function testDateTimeExcelToPHP1904() if ($args[0] < 1) { $expectedResult += gmmktime(0,0,0); } - $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'), $args); $this->assertEquals($expectedResult, $result); } @@ -136,7 +136,7 @@ public function testDateTimePHPToExcel1904() $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'), $args); $this->assertEquals($expectedResult, $result, null, 1E-5); } @@ -152,7 +152,7 @@ public function testIsDateTimeFormatCode() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Date','isDateTimeFormatCode'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','isDateTimeFormatCode'), $args); $this->assertEquals($expectedResult, $result); } @@ -176,7 +176,7 @@ public function testDateTimeExcelToPHP1900Timezone() if ($args[0] < 1) { $expectedResult += gmmktime(0,0,0); } - $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'), $args); $this->assertEquals($expectedResult, $result); } @@ -184,5 +184,4 @@ public function providerDateTimeExcelToPHP1900Timezone() { return new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1900Timezone.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Shared/FileTest.php b/unitTests/Classes/PHPExcel/Shared/FileTest.php index e7b288af3..6f6696c51 100644 --- a/unitTests/Classes/PHPExcel/Shared/FileTest.php +++ b/unitTests/Classes/PHPExcel/Shared/FileTest.php @@ -16,7 +16,7 @@ public function setUp() public function testGetUseUploadTempDirectory() { - $expectedResult = FALSE; + $expectedResult = false; $result = call_user_func(array('PHPExcel_Shared_File','getUseUploadTempDirectory')); $this->assertEquals($expectedResult, $result); @@ -30,7 +30,7 @@ public function testSetUseUploadTempDirectory() ); foreach ($useUploadTempDirectoryValues as $useUploadTempDirectoryValue) { - call_user_func(array('PHPExcel_Shared_File','setUseUploadTempDirectory'),$useUploadTempDirectoryValue); + call_user_func(array('PHPExcel_Shared_File','setUseUploadTempDirectory'), $useUploadTempDirectoryValue); $result = call_user_func(array('PHPExcel_Shared_File','getUseUploadTempDirectory')); $this->assertEquals($useUploadTempDirectoryValue, $result); diff --git a/unitTests/Classes/PHPExcel/Shared/FontTest.php b/unitTests/Classes/PHPExcel/Shared/FontTest.php index cf11fccab..eecd69de9 100644 --- a/unitTests/Classes/PHPExcel/Shared/FontTest.php +++ b/unitTests/Classes/PHPExcel/Shared/FontTest.php @@ -30,7 +30,7 @@ public function testSetAutoSizeMethod() ); foreach ($autosizeMethodValues as $autosizeMethodValue) { - $result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'),$autosizeMethodValue); + $result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'), $autosizeMethodValue); $this->assertTrue($result); } } @@ -39,7 +39,7 @@ public function testSetAutoSizeMethodWithInvalidValue() { $unsupportedAutosizeMethod = 'guess'; - $result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'),$unsupportedAutosizeMethod); + $result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'), $unsupportedAutosizeMethod); $this->assertFalse($result); } @@ -50,7 +50,7 @@ public function testFontSizeToPixels() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Font','fontSizeToPixels'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_Font','fontSizeToPixels'), $args); $this->assertEquals($expectedResult, $result); } @@ -66,7 +66,7 @@ public function testInchSizeToPixels() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Font','inchSizeToPixels'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_Font','inchSizeToPixels'), $args); $this->assertEquals($expectedResult, $result); } @@ -82,7 +82,7 @@ public function testCentimeterSizeToPixels() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_Font','centimeterSizeToPixels'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_Font','centimeterSizeToPixels'), $args); $this->assertEquals($expectedResult, $result); } @@ -90,5 +90,4 @@ public function providerCentimeterSizeToPixels() { return new testDataFileIterator('rawTestData/Shared/CentimeterSizeToPixels.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php b/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php index 20bf8b948..620acb983 100644 --- a/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php +++ b/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php @@ -21,7 +21,7 @@ public function testHashPassword() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Shared_PasswordHasher','hashPassword'),$args); + $result = call_user_func_array(array('PHPExcel_Shared_PasswordHasher','hashPassword'), $args); $this->assertEquals($expectedResult, $result); } @@ -29,5 +29,4 @@ public function providerHashPassword() { return new testDataFileIterator('rawTestData/Shared/PasswordHashes.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Shared/StringTest.php b/unitTests/Classes/PHPExcel/Shared/StringTest.php index 4de1a6287..9955d8165 100644 --- a/unitTests/Classes/PHPExcel/Shared/StringTest.php +++ b/unitTests/Classes/PHPExcel/Shared/StringTest.php @@ -38,7 +38,7 @@ public function testGetDecimalSeparator() public function testSetDecimalSeparator() { $expectedResult = ','; - $result = call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),$expectedResult); + $result = call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'), $expectedResult); $result = call_user_func(array('PHPExcel_Shared_String','getDecimalSeparator')); $this->assertEquals($expectedResult, $result); @@ -56,7 +56,7 @@ public function testGetThousandsSeparator() public function testSetThousandsSeparator() { $expectedResult = ' '; - $result = call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),$expectedResult); + $result = call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'), $expectedResult); $result = call_user_func(array('PHPExcel_Shared_String','getThousandsSeparator')); $this->assertEquals($expectedResult, $result); @@ -74,10 +74,9 @@ public function testGetCurrencyCode() public function testSetCurrencyCode() { $expectedResult = '£'; - $result = call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),$expectedResult); + $result = call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'), $expectedResult); $result = call_user_func(array('PHPExcel_Shared_String','getCurrencyCode')); $this->assertEquals($expectedResult, $result); } - } diff --git a/unitTests/Classes/PHPExcel/Shared/TimeZoneTest.php b/unitTests/Classes/PHPExcel/Shared/TimeZoneTest.php index 79ac97162..254842673 100644 --- a/unitTests/Classes/PHPExcel/Shared/TimeZoneTest.php +++ b/unitTests/Classes/PHPExcel/Shared/TimeZoneTest.php @@ -23,7 +23,7 @@ public function testSetTimezone() ); foreach ($timezoneValues as $timezoneValue) { - $result = call_user_func(array('PHPExcel_Shared_TimeZone','setTimezone'),$timezoneValue); + $result = call_user_func(array('PHPExcel_Shared_TimeZone','setTimezone'), $timezoneValue); $this->assertTrue($result); } @@ -32,8 +32,7 @@ public function testSetTimezone() public function testSetTimezoneWithInvalidValue() { $unsupportedTimezone = 'Etc/GMT+10'; - $result = call_user_func(array('PHPExcel_Shared_TimeZone','setTimezone'),$unsupportedTimezone); + $result = call_user_func(array('PHPExcel_Shared_TimeZone','setTimezone'), $unsupportedTimezone); $this->assertFalse($result); } - } diff --git a/unitTests/Classes/PHPExcel/Style/ColorTest.php b/unitTests/Classes/PHPExcel/Style/ColorTest.php index 8b0bd541d..2d9188ef3 100644 --- a/unitTests/Classes/PHPExcel/Style/ColorTest.php +++ b/unitTests/Classes/PHPExcel/Style/ColorTest.php @@ -21,7 +21,7 @@ public function testGetRed() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Style_Color','getRed'),$args); + $result = call_user_func_array(array('PHPExcel_Style_Color','getRed'), $args); $this->assertEquals($expectedResult, $result); } @@ -37,7 +37,7 @@ public function testGetGreen() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Style_Color','getGreen'),$args); + $result = call_user_func_array(array('PHPExcel_Style_Color','getGreen'), $args); $this->assertEquals($expectedResult, $result); } @@ -53,7 +53,7 @@ public function testGetBlue() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Style_Color','getBlue'),$args); + $result = call_user_func_array(array('PHPExcel_Style_Color','getBlue'), $args); $this->assertEquals($expectedResult, $result); } @@ -69,7 +69,7 @@ public function testChangeBrightness() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Style_Color','changeBrightness'),$args); + $result = call_user_func_array(array('PHPExcel_Style_Color','changeBrightness'), $args); $this->assertEquals($expectedResult, $result); } @@ -77,5 +77,4 @@ public function providerColorChangeBrightness() { return new testDataFileIterator('rawTestData/Style/ColorChangeBrightness.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php b/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php index 4d89d929c..08c2f0240 100644 --- a/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php +++ b/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php @@ -24,7 +24,7 @@ public function testFormatValueWithMask() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Style_NumberFormat','toFormattedString'),$args); + $result = call_user_func_array(array('PHPExcel_Style_NumberFormat','toFormattedString'), $args); $this->assertEquals($expectedResult, $result); } @@ -32,5 +32,4 @@ public function providerNumberFormat() { return new testDataFileIterator('rawTestData/Style/NumberFormat.data'); } - } diff --git a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/Column/RuleTest.php b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/Column/RuleTest.php index 6a818f78c..0c39c683a 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/Column/RuleTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/Column/RuleTest.php @@ -105,5 +105,4 @@ public function testClone() $result = clone $this->_testAutoFilterRuleObject; $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result); } - } diff --git a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php index 9b49f8105..da6eef53c 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php @@ -143,7 +143,7 @@ public function testSetAttribute() foreach ($attributeSet as $attributeName => $attributeValue) { // Setters return the instance to implement the fluent interface - $result = $this->_testAutoFilterColumnObject->setAttribute($attributeName,$attributeValue); + $result = $this->_testAutoFilterColumnObject->setAttribute($attributeName, $attributeValue); $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); } } @@ -169,5 +169,4 @@ public function testClone() $result = clone $this->_testAutoFilterColumnObject; $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); } - } diff --git a/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php b/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php index 2ea396c99..519810d3d 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php @@ -148,7 +148,7 @@ public function testSetColumnWithString() // objects for each column we set indexed by the column ID $this->assertInternalType('array', $result); $this->assertEquals(1, count($result)); - $this->assertArrayHasKey($expectedResult,$result); + $this->assertArrayHasKey($expectedResult, $result); $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$expectedResult]); } @@ -176,7 +176,7 @@ public function testSetColumnWithColumnObject() // objects for each column we set indexed by the column ID $this->assertInternalType('array', $result); $this->assertEquals(1, count($result)); - $this->assertArrayHasKey($expectedResult,$result); + $this->assertArrayHasKey($expectedResult, $result); $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$expectedResult]); } @@ -216,7 +216,7 @@ public function testGetColumns() $this->assertInternalType('array', $result); $this->assertEquals(count($columnIndexes), count($result)); foreach ($columnIndexes as $columnIndex) { - $this->assertArrayHasKey($columnIndex,$result); + $this->assertArrayHasKey($columnIndex, $result); $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$columnIndex]); } } @@ -249,7 +249,7 @@ public function testGetColumnByOffset() foreach ($columnIndexes as $columnIndex => $columnID) { $result = $this->_testAutoFilterObject->getColumnByOffset($columnIndex); $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result); - $this->assertEquals($result->getColumnIndex(),$columnID); + $this->assertEquals($result->getColumnIndex(), $columnID); } } @@ -336,5 +336,4 @@ public function testClone() $result = clone $this->_testAutoFilterObject; $this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result); } - } diff --git a/unitTests/Classes/PHPExcel/Worksheet/CellCollectionTest.php b/unitTests/Classes/PHPExcel/Worksheet/CellCollectionTest.php index c117ef8f4..95dd2cec4 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/CellCollectionTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/CellCollectionTest.php @@ -5,8 +5,7 @@ class CellCollectionTest extends PHPUnit_Framework_TestCase public function setUp() { - if (!defined('PHPEXCEL_ROOT')) - { + if (!defined('PHPEXCEL_ROOT')) { define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); } require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); @@ -27,5 +26,4 @@ public function testCacheLastCell() PHPExcel_CachedObjectStorageFactory::finalize(); } } - } diff --git a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php index 83d3b111e..f87a545f3 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php @@ -61,7 +61,7 @@ public function testIteratorSeekAndPrev() $iterator->seek('D'); $this->assertEquals($columnIndexResult, $iterator->key()); - for($i = 1; $i < array_search($columnIndexResult, $ranges); $i++) { + for ($i = 1; $i < array_search($columnIndexResult, $ranges); $i++) { $iterator->prev(); $expectedResult = $ranges[array_search($columnIndexResult, $ranges) - $i]; $this->assertEquals($expectedResult, $iterator->key()); @@ -85,5 +85,4 @@ public function testPrevOutOfRange() $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D'); $iterator->prev(); } - } diff --git a/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php index 7fd425fb8..d2d36499a 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php @@ -61,7 +61,7 @@ public function testIteratorSeekAndPrev() $iterator->seek('D'); $this->assertEquals($RowCellIndexResult, $iterator->key()); - for($i = 1; $i < array_search($RowCellIndexResult, $ranges); $i++) { + for ($i = 1; $i < array_search($RowCellIndexResult, $ranges); $i++) { $iterator->prev(); $expectedResult = $ranges[array_search($RowCellIndexResult, $ranges) - $i]; $this->assertEquals($expectedResult, $iterator->key()); @@ -85,5 +85,4 @@ public function testPrevOutOfRange() $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); $iterator->prev(); } - } diff --git a/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php index b6098936a..ec0b2796f 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php @@ -60,7 +60,7 @@ public function testIteratorSeekAndPrev() $iterator->seek(4); $this->assertEquals($columnIndexResult, $iterator->key()); - for($i = 1; $i < $columnIndexResult-1; $i++) { + for ($i = 1; $i < $columnIndexResult-1; $i++) { $iterator->prev(); $this->assertEquals($columnIndexResult - $i, $iterator->key()); } @@ -83,5 +83,4 @@ public function testPrevOutOfRange() $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); $iterator->prev(); } - } diff --git a/unitTests/custom/Complex.php b/unitTests/custom/Complex.php index 182e1401a..0b22ddfdd 100644 --- a/unitTests/custom/Complex.php +++ b/unitTests/custom/Complex.php @@ -66,7 +66,7 @@ public function __construct($realPart, $imaginaryPart = null, $suffix = 'i') if (is_array($realPart)) { // We have an array of (potentially) real and imaginary parts, and any suffix list ($realPart, $imaginaryPart, $suffix) = array_values($realPart) + array(0.0, 0.0, 'i'); - } elseif((is_string($realPart)) || (is_numeric($realPart))) { + } elseif ((is_string($realPart)) || (is_numeric($realPart))) { // We've been given a string to parse to extract the real and imaginary parts, and any suffix list ($realPart, $imaginaryPart, $suffix) = self::_parseComplex($realPart); } @@ -93,7 +93,8 @@ public function getSuffix() return $this->suffix; } - public function __toString() { + public function __toString() + { $str = ""; if ($this->imaginaryPart != 0.0) { if (abs($this->imaginaryPart) != 1.0) { @@ -103,13 +104,14 @@ public function __toString() { } } if ($this->realPart != 0.0) { - if (($str) && ($this->imaginaryPart > 0.0)) + if (($str) && ($this->imaginaryPart > 0.0)) { $str = "+" . $str; + } $str = $this->realPart . $str; } - if (!$str) + if (!$str) { $str = "0.0"; + } return $str; } - } diff --git a/unitTests/testDataFileIterator.php b/unitTests/testDataFileIterator.php index ee417e594..69ff6edcb 100644 --- a/unitTests/testDataFileIterator.php +++ b/unitTests/testDataFileIterator.php @@ -90,17 +90,17 @@ private function _parseDataValue($dataValue) $dataValue = trim($dataValue); // test for the required datatype and convert accordingly if (!is_numeric($dataValue)) { - if($dataValue == '') { + if ($dataValue == '') { $dataValue = null; - } elseif($dataValue == '""') { + } elseif ($dataValue == '""') { $dataValue = ''; - } elseif(($dataValue[0] == '"') && ($dataValue[strlen($dataValue)-1] == '"')) { - $dataValue = substr($dataValue,1,-1); - } elseif(($dataValue[0] == '{') && ($dataValue[strlen($dataValue)-1] == '}')) { - $dataValue = explode(';',substr($dataValue,1,-1)); + } elseif (($dataValue[0] == '"') && ($dataValue[strlen($dataValue)-1] == '"')) { + $dataValue = substr($dataValue, 1, -1); + } elseif (($dataValue[0] == '{') && ($dataValue[strlen($dataValue)-1] == '}')) { + $dataValue = explode(';',substr($dataValue, 1, -1)); foreach ($dataValue as &$dataRow) { - if (strpos($dataRow,'|') !== false) { - $dataRow = explode('|',$dataRow); + if (strpos($dataRow, '|') !== false) { + $dataRow = explode('|', $dataRow); foreach ($dataRow as &$dataCell) { $dataCell = $this->_parseDataValue($dataCell); } @@ -124,7 +124,7 @@ private function _parseDataValue($dataValue) } } } else { - if (strpos($dataValue,'.') !== false) { + if (strpos($dataValue, '.') !== false) { $dataValue = (float) $dataValue; } else { $dataValue = (int) $dataValue; From 004936e35abe6e0cfb8e325d58174f7703c49e78 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sun, 17 May 2015 19:26:34 +0200 Subject: [PATCH 387/467] PSR2 Fixes --- unitTests/Classes/PHPExcel/AutoloaderTest.php | 4 +- .../PHPExcel/Calculation/DateTimeTest.php | 78 +++++++++---------- .../PHPExcel/Calculation/TextDataTest.php | 16 ++-- .../Classes/PHPExcel/Chart/LegendTest.php | 1 - .../Classes/PHPExcel/Shared/DateTest.php | 8 +- .../Worksheet/ColumnCellIteratorTest.php | 3 +- .../PHPExcel/Worksheet/ColumnIteratorTest.php | 2 +- .../Worksheet/RowCellIteratorTest.php | 2 +- unitTests/testDataFileIterator.php | 2 +- 9 files changed, 57 insertions(+), 59 deletions(-) diff --git a/unitTests/Classes/PHPExcel/AutoloaderTest.php b/unitTests/Classes/PHPExcel/AutoloaderTest.php index f53015c6b..842d1797d 100644 --- a/unitTests/Classes/PHPExcel/AutoloaderTest.php +++ b/unitTests/Classes/PHPExcel/AutoloaderTest.php @@ -45,10 +45,10 @@ public function testAutoloadValidPHPExcelClass() public function testAutoloadInstantiateSuccess() { - $result = new PHPExcel_Calculation_Function(1,2,3); + $result = new PHPExcel_Calculation_Function(1, 2, 3); // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type - $this->assertTrue(is_a($result,'PHPExcel_Calculation_Function')); + $this->assertTrue(is_a($result, 'PHPExcel_Calculation_Function')); } } diff --git a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php index 8b28f2fac..fde43e56a 100644 --- a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php @@ -23,7 +23,7 @@ public function testDATE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATE'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'DATE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -35,7 +35,7 @@ public function providerDATE() public function testDATEtoPHP() { PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::DATE(2012,1,31); + $result = PHPExcel_Calculation_DateTime::DATE(2012, 1, 31); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); $this->assertEquals(1327968000, $result, null, 1E-8); } @@ -43,30 +43,30 @@ public function testDATEtoPHP() public function testDATEtoPHPObject() { PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::DATE(2012,1,31); + $result = PHPExcel_Calculation_DateTime::DATE(2012, 1, 31); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); + $this->assertTrue(is_a($result, 'DateTime')); // ... with the correct value - $this->assertEquals($result->format('d-M-Y'),'31-Jan-2012'); + $this->assertEquals($result->format('d-M-Y'), '31-Jan-2012'); } public function testDATEwith1904Calendar() { PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); - $result = PHPExcel_Calculation_DateTime::DATE(1918,11,11); + $result = PHPExcel_Calculation_DateTime::DATE(1918, 11, 11); PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); - $this->assertEquals($result,5428); + $this->assertEquals($result, 5428); } public function testDATEwith1904CalendarError() { PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); - $result = PHPExcel_Calculation_DateTime::DATE(1901,1,31); + $result = PHPExcel_Calculation_DateTime::DATE(1901, 1, 31); PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); - $this->assertEquals($result,'#NUM!'); + $this->assertEquals($result, '#NUM!'); } /** @@ -76,7 +76,7 @@ public function testDATEVALUE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEVALUE'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'DATEVALUE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -101,9 +101,9 @@ public function testDATEVALUEtoPHPObject() // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); + $this->assertTrue(is_a($result, 'DateTime')); // ... with the correct value - $this->assertEquals($result->format('d-M-Y'),'31-Jan-2012'); + $this->assertEquals($result->format('d-M-Y'), '31-Jan-2012'); } /** @@ -113,7 +113,7 @@ public function testYEAR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEAR'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'YEAR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -129,7 +129,7 @@ public function testMONTH() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MONTHOFYEAR'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'MONTHOFYEAR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -145,7 +145,7 @@ public function testWEEKNUM() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WEEKOFYEAR'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'WEEKOFYEAR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -161,7 +161,7 @@ public function testWEEKDAY() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFWEEK'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'DAYOFWEEK'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -177,7 +177,7 @@ public function testDAY() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFMONTH'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'DAYOFMONTH'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -193,7 +193,7 @@ public function testTIME() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIME'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'TIME'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -205,7 +205,7 @@ public function providerTIME() public function testTIMEtoPHP() { PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::TIME(7,30,20); + $result = PHPExcel_Calculation_DateTime::TIME(7, 30, 20); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); $this->assertEquals(27020, $result, null, 1E-8); } @@ -213,14 +213,14 @@ public function testTIMEtoPHP() public function testTIMEtoPHPObject() { PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::TIME(7,30,20); + $result = PHPExcel_Calculation_DateTime::TIME(7, 30, 20); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); + $this->assertTrue(is_a($result, 'DateTime')); // ... with the correct value - $this->assertEquals($result->format('H:i:s'),'07:30:20'); + $this->assertEquals($result->format('H:i:s'), '07:30:20'); } /** @@ -230,7 +230,7 @@ public function testTIMEVALUE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIMEVALUE'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'TIMEVALUE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -255,9 +255,9 @@ public function testTIMEVALUEtoPHPObject() // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); + $this->assertTrue(is_a($result, 'DateTime')); // ... with the correct value - $this->assertEquals($result->format('H:i:s'),'07:30:20'); + $this->assertEquals($result->format('H:i:s'), '07:30:20'); } /** @@ -267,7 +267,7 @@ public function testHOUR() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','HOUROFDAY'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'HOUROFDAY'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -283,7 +283,7 @@ public function testMINUTE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MINUTEOFHOUR'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'MINUTEOFHOUR'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -299,7 +299,7 @@ public function testSECOND() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','SECONDOFMINUTE'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'SECONDOFMINUTE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -315,7 +315,7 @@ public function testNETWORKDAYS() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','NETWORKDAYS'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'NETWORKDAYS'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -331,7 +331,7 @@ public function testWORKDAY() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WORKDAY'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'WORKDAY'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -347,7 +347,7 @@ public function testEDATE() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EDATE'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'EDATE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -372,9 +372,9 @@ public function testEDATEtoPHPObject() // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); + $this->assertTrue(is_a($result, 'DateTime')); // ... with the correct value - $this->assertEquals($result->format('d-M-Y'),'26-Dec-2011'); + $this->assertEquals($result->format('d-M-Y'), '26-Dec-2011'); } /** @@ -384,7 +384,7 @@ public function testEOMONTH() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EOMONTH'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'EOMONTH'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -409,9 +409,9 @@ public function testEOMONTHtoPHPObject() // Must return an object... $this->assertTrue(is_object($result)); // ... of the correct type - $this->assertTrue(is_a($result,'DateTime')); + $this->assertTrue(is_a($result, 'DateTime')); // ... with the correct value - $this->assertEquals($result->format('d-M-Y'),'31-Dec-2011'); + $this->assertEquals($result->format('d-M-Y'), '31-Dec-2011'); } /** @@ -421,7 +421,7 @@ public function testDATEDIF() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEDIF'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'DATEDIF'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -437,7 +437,7 @@ public function testDAYS360() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYS360'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'DAYS360'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } @@ -453,7 +453,7 @@ public function testYEARFRAC() { $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEARFRAC'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_DateTime', 'YEARFRAC'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } diff --git a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php index 604c7a118..135d4b092 100644 --- a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php @@ -326,13 +326,13 @@ public function providerT() public function testTEXT() { // Enforce decimal and thousands separator values to UK/US, and currency code to USD - call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.'); - call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),','); - call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$'); + call_user_func(array('PHPExcel_Shared_String', 'setDecimalSeparator'), '.'); + call_user_func(array('PHPExcel_Shared_String', 'setThousandsSeparator'), ','); + call_user_func(array('PHPExcel_Shared_String', 'setCurrencyCode'), '$'); $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','TEXTFORMAT'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData', 'TEXTFORMAT'), $args); $this->assertEquals($expectedResult, $result); } @@ -346,13 +346,13 @@ public function providerTEXT() */ public function testVALUE() { - call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.'); - call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),' '); - call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$'); + call_user_func(array('PHPExcel_Shared_String', 'setDecimalSeparator'), '.'); + call_user_func(array('PHPExcel_Shared_String', 'setThousandsSeparator'), ' '); + call_user_func(array('PHPExcel_Shared_String', 'setCurrencyCode'), '$'); $args = func_get_args(); $expectedResult = array_pop($args); - $result = call_user_func_array(array('PHPExcel_Calculation_TextData','VALUE'), $args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData', 'VALUE'), $args); $this->assertEquals($expectedResult, $result, null, 1E-8); } diff --git a/unitTests/Classes/PHPExcel/Chart/LegendTest.php b/unitTests/Classes/PHPExcel/Chart/LegendTest.php index 462fbdc97..b4df4119a 100644 --- a/unitTests/Classes/PHPExcel/Chart/LegendTest.php +++ b/unitTests/Classes/PHPExcel/Chart/LegendTest.php @@ -129,5 +129,4 @@ public function testGetOverlay() $result = $testInstance->getOverlay(); $this->assertEquals($OverlayValue, $result); } - } diff --git a/unitTests/Classes/PHPExcel/Shared/DateTest.php b/unitTests/Classes/PHPExcel/Shared/DateTest.php index 50049f6e4..f0bf91983 100644 --- a/unitTests/Classes/PHPExcel/Shared/DateTest.php +++ b/unitTests/Classes/PHPExcel/Shared/DateTest.php @@ -47,9 +47,9 @@ public function testDateTimeExcelToPHP1900() $args = func_get_args(); $expectedResult = array_pop($args); if ($args[0] < 1) { - $expectedResult += gmmktime(0,0,0); + $expectedResult += gmmktime(0, 0, 0); } - $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'), $args); + $result = call_user_func_array(array('PHPExcel_Shared_Date', 'ExcelToPHP'), $args); $this->assertEquals($expectedResult, $result); } @@ -113,7 +113,7 @@ public function testDateTimeExcelToPHP1904() $args = func_get_args(); $expectedResult = array_pop($args); if ($args[0] < 1) { - $expectedResult += gmmktime(0,0,0); + $expectedResult += gmmktime(0, 0, 0); } $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'), $args); $this->assertEquals($expectedResult, $result); @@ -174,7 +174,7 @@ public function testDateTimeExcelToPHP1900Timezone() $args = func_get_args(); $expectedResult = array_pop($args); if ($args[0] < 1) { - $expectedResult += gmmktime(0,0,0); + $expectedResult += gmmktime(0, 0, 0); } $result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'), $args); $this->assertEquals($expectedResult, $result); diff --git a/unitTests/Classes/PHPExcel/Worksheet/ColumnCellIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/ColumnCellIteratorTest.php index 49abcb044..869d086eb 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/ColumnCellIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/ColumnCellIteratorTest.php @@ -60,7 +60,7 @@ public function testIteratorSeekAndPrev() $iterator->seek(4); $this->assertEquals($columnIndexResult, $iterator->key()); - for($i = 1; $i < $columnIndexResult-1; $i++) { + for ($i = 1; $i < $columnIndexResult-1; $i++) { $iterator->prev(); $this->assertEquals($columnIndexResult - $i, $iterator->key()); } @@ -83,5 +83,4 @@ public function testPrevOutOfRange() $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); $iterator->prev(); } - } diff --git a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php index f87a545f3..e013210e1 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php @@ -55,7 +55,7 @@ public function testIteratorStartEndRange() public function testIteratorSeekAndPrev() { - $ranges = range('A','E'); + $ranges = range('A', 'E'); $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D'); $columnIndexResult = 'D'; $iterator->seek('D'); diff --git a/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php index d2d36499a..ec60e90bb 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php @@ -55,7 +55,7 @@ public function testIteratorStartEndRange() public function testIteratorSeekAndPrev() { - $ranges = range('A','E'); + $ranges = range('A', 'E'); $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); $RowCellIndexResult = 'D'; $iterator->seek('D'); diff --git a/unitTests/testDataFileIterator.php b/unitTests/testDataFileIterator.php index 69ff6edcb..33f64bdb6 100644 --- a/unitTests/testDataFileIterator.php +++ b/unitTests/testDataFileIterator.php @@ -97,7 +97,7 @@ private function _parseDataValue($dataValue) } elseif (($dataValue[0] == '"') && ($dataValue[strlen($dataValue)-1] == '"')) { $dataValue = substr($dataValue, 1, -1); } elseif (($dataValue[0] == '{') && ($dataValue[strlen($dataValue)-1] == '}')) { - $dataValue = explode(';',substr($dataValue, 1, -1)); + $dataValue = explode(';', substr($dataValue, 1, -1)); foreach ($dataValue as &$dataRow) { if (strpos($dataRow, '|') !== false) { $dataRow = explode('|', $dataRow); From 004d4117720262fa73d37c5773d636b48091c375 Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sun, 17 May 2015 19:33:14 +0200 Subject: [PATCH 388/467] PSR2 Fixes --- unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php index fde43e56a..d42ae44d8 100644 --- a/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php @@ -359,7 +359,7 @@ public function providerEDATE() public function testEDATEtoPHP() { PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1); + $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26', -1); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); $this->assertEquals(1324857600, $result, null, 1E-8); } @@ -367,7 +367,7 @@ public function testEDATEtoPHP() public function testEDATEtoPHPObject() { PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1); + $result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26', -1); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Must return an object... $this->assertTrue(is_object($result)); @@ -396,7 +396,7 @@ public function providerEOMONTH() public function testEOMONTHtoPHP() { PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); - $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1); + $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26', -1); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); $this->assertEquals(1325289600, $result, null, 1E-8); } @@ -404,7 +404,7 @@ public function testEOMONTHtoPHP() public function testEOMONTHtoPHPObject() { PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT); - $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1); + $result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26', -1); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Must return an object... $this->assertTrue(is_object($result)); From 066a85d3d253b645ff35c0639298d4c0bcb0474b Mon Sep 17 00:00:00 2001 From: Progi1984 <progi1984@gmail.com> Date: Sun, 17 May 2015 20:00:00 +0200 Subject: [PATCH 389/467] PSR2 Fixes --- Classes/PHPExcel/Cell.php | 2 +- Classes/PHPExcel/Reader/Excel5/RC4.php | 6 +- Classes/PHPExcel/Shared/ZipStreamWrapper.php | 2 +- .../Shared/trend/exponentialBestFitClass.php | 2 +- .../Shared/trend/linearBestFitClass.php | 2 +- .../Shared/trend/logarithmicBestFitClass.php | 2 +- .../Shared/trend/polynomialBestFitClass.php | 2 +- .../Shared/trend/powerBestFitClass.php | 2 +- Classes/PHPExcel/Shared/trend/trendClass.php | 2 +- Classes/PHPExcel/Worksheet/Protection.php | 70 +++++++++---------- 10 files changed, 46 insertions(+), 46 deletions(-) diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php index 8bc5dac93..c99a3c8b1 100644 --- a/Classes/PHPExcel/Cell.php +++ b/Classes/PHPExcel/Cell.php @@ -27,7 +27,6 @@ */ class PHPExcel_Cell { - /** * Default range variable constant * @@ -227,6 +226,7 @@ public function setValueExplicit($pValue = null, $pDataType = PHPExcel_Cell_Data break; case PHPExcel_Cell_DataType::TYPE_STRING2: $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + // no break case PHPExcel_Cell_DataType::TYPE_STRING: // Synonym for string case PHPExcel_Cell_DataType::TYPE_INLINE: diff --git a/Classes/PHPExcel/Reader/Excel5/RC4.php b/Classes/PHPExcel/Reader/Excel5/RC4.php index 394a00aa7..7a2eedc4f 100644 --- a/Classes/PHPExcel/Reader/Excel5/RC4.php +++ b/Classes/PHPExcel/Reader/Excel5/RC4.php @@ -35,9 +35,9 @@ class PHPExcel_Reader_Excel5_RC4 { // Context - var $s = array(); - var $i = 0; - var $j = 0; + protected $s = array(); + protected $i = 0; + protected $j = 0; /** * RC4 stream decryption/encryption constrcutor diff --git a/Classes/PHPExcel/Shared/ZipStreamWrapper.php b/Classes/PHPExcel/Shared/ZipStreamWrapper.php index c96cffe12..d1c87ac6e 100644 --- a/Classes/PHPExcel/Shared/ZipStreamWrapper.php +++ b/Classes/PHPExcel/Shared/ZipStreamWrapper.php @@ -131,7 +131,7 @@ public function stream_stat() * @param int $count maximum number of bytes to read * @return string */ - function stream_read($count) + public function stream_read($count) { $ret = substr($this->_data, $this->_position, $count); $this->_position += strlen($ret); diff --git a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php index 647bd2dc1..caa1759cd 100644 --- a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php @@ -138,7 +138,7 @@ private function _exponential_regression($yValues, $xValues, $const) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($yValues, $xValues = array(), $const = true) + public function __construct($yValues, $xValues = array(), $const = true) { if (parent::__construct($yValues, $xValues) !== false) { $this->_exponential_regression($yValues, $xValues, $const); diff --git a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php index 1689dd60c..c5ed3cf3b 100644 --- a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php @@ -100,7 +100,7 @@ private function _linear_regression($yValues, $xValues, $const) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($yValues, $xValues = array(), $const = true) + public function __construct($yValues, $xValues = array(), $const = true) { if (parent::__construct($yValues, $xValues) !== false) { $this->_linear_regression($yValues, $xValues, $const); diff --git a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php index fa1a3d268..7d561cda3 100644 --- a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php @@ -108,7 +108,7 @@ private function _logarithmic_regression($yValues, $xValues, $const) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($yValues, $xValues = array(), $const = true) + public function __construct($yValues, $xValues = array(), $const = true) { if (parent::__construct($yValues, $xValues) !== false) { $this->_logarithmic_regression($yValues, $xValues, $const); diff --git a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php index b571f206f..b1b69b0ac 100644 --- a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php @@ -213,7 +213,7 @@ private function _polynomial_regression($order, $yValues, $xValues, $const) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($order, $yValues, $xValues = array(), $const = true) + public function __construct($order, $yValues, $xValues = array(), $const = true) { if (parent::__construct($yValues, $xValues) !== false) { if ($order < $this->_valueCount) { diff --git a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php index b58d8f5d6..38870af8a 100644 --- a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php @@ -138,7 +138,7 @@ private function _power_regression($yValues, $xValues, $const) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - function __construct($yValues, $xValues = array(), $const = true) + public function __construct($yValues, $xValues = array(), $const = true) { if (parent::__construct($yValues, $xValues) !== false) { $this->_power_regression($yValues, $xValues, $const); diff --git a/Classes/PHPExcel/Shared/trend/trendClass.php b/Classes/PHPExcel/Shared/trend/trendClass.php index bb1cd1c54..a7b34ed9a 100644 --- a/Classes/PHPExcel/Shared/trend/trendClass.php +++ b/Classes/PHPExcel/Shared/trend/trendClass.php @@ -153,4 +153,4 @@ public static function calculate($trendType = self::TREND_BEST_FIT, $yValues, $x return false; } } // function calculate() -} // class trendClass +} diff --git a/Classes/PHPExcel/Worksheet/Protection.php b/Classes/PHPExcel/Worksheet/Protection.php index d6ab223a0..d84e6e9c8 100644 --- a/Classes/PHPExcel/Worksheet/Protection.php +++ b/Classes/PHPExcel/Worksheet/Protection.php @@ -166,7 +166,7 @@ public function __construct() * * @return boolean */ - function isProtectionEnabled() + public function isProtectionEnabled() { return $this->_sheet || $this->_objects || @@ -191,7 +191,7 @@ function isProtectionEnabled() * * @return boolean */ - function getSheet() + public function getSheet() { return $this->_sheet; } @@ -202,7 +202,7 @@ function getSheet() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setSheet($pValue = false) + public function setSheet($pValue = false) { $this->_sheet = $pValue; return $this; @@ -213,7 +213,7 @@ function setSheet($pValue = false) * * @return boolean */ - function getObjects() + public function getObjects() { return $this->_objects; } @@ -224,7 +224,7 @@ function getObjects() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setObjects($pValue = false) + public function setObjects($pValue = false) { $this->_objects = $pValue; return $this; @@ -235,7 +235,7 @@ function setObjects($pValue = false) * * @return boolean */ - function getScenarios() + public function getScenarios() { return $this->_scenarios; } @@ -246,7 +246,7 @@ function getScenarios() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setScenarios($pValue = false) + public function setScenarios($pValue = false) { $this->_scenarios = $pValue; return $this; @@ -257,7 +257,7 @@ function setScenarios($pValue = false) * * @return boolean */ - function getFormatCells() + public function getFormatCells() { return $this->_formatCells; } @@ -268,7 +268,7 @@ function getFormatCells() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setFormatCells($pValue = false) + public function setFormatCells($pValue = false) { $this->_formatCells = $pValue; return $this; @@ -279,7 +279,7 @@ function setFormatCells($pValue = false) * * @return boolean */ - function getFormatColumns() + public function getFormatColumns() { return $this->_formatColumns; } @@ -290,7 +290,7 @@ function getFormatColumns() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setFormatColumns($pValue = false) + public function setFormatColumns($pValue = false) { $this->_formatColumns = $pValue; return $this; @@ -301,7 +301,7 @@ function setFormatColumns($pValue = false) * * @return boolean */ - function getFormatRows() + public function getFormatRows() { return $this->_formatRows; } @@ -312,7 +312,7 @@ function getFormatRows() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setFormatRows($pValue = false) + public function setFormatRows($pValue = false) { $this->_formatRows = $pValue; return $this; @@ -323,7 +323,7 @@ function setFormatRows($pValue = false) * * @return boolean */ - function getInsertColumns() + public function getInsertColumns() { return $this->_insertColumns; } @@ -334,7 +334,7 @@ function getInsertColumns() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setInsertColumns($pValue = false) + public function setInsertColumns($pValue = false) { $this->_insertColumns = $pValue; return $this; @@ -345,7 +345,7 @@ function setInsertColumns($pValue = false) * * @return boolean */ - function getInsertRows() + public function getInsertRows() { return $this->_insertRows; } @@ -356,7 +356,7 @@ function getInsertRows() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setInsertRows($pValue = false) + public function setInsertRows($pValue = false) { $this->_insertRows = $pValue; return $this; @@ -367,7 +367,7 @@ function setInsertRows($pValue = false) * * @return boolean */ - function getInsertHyperlinks() + public function getInsertHyperlinks() { return $this->_insertHyperlinks; } @@ -378,7 +378,7 @@ function getInsertHyperlinks() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setInsertHyperlinks($pValue = false) + public function setInsertHyperlinks($pValue = false) { $this->_insertHyperlinks = $pValue; return $this; @@ -389,7 +389,7 @@ function setInsertHyperlinks($pValue = false) * * @return boolean */ - function getDeleteColumns() + public function getDeleteColumns() { return $this->_deleteColumns; } @@ -400,7 +400,7 @@ function getDeleteColumns() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setDeleteColumns($pValue = false) + public function setDeleteColumns($pValue = false) { $this->_deleteColumns = $pValue; return $this; @@ -411,7 +411,7 @@ function setDeleteColumns($pValue = false) * * @return boolean */ - function getDeleteRows() + public function getDeleteRows() { return $this->_deleteRows; } @@ -422,7 +422,7 @@ function getDeleteRows() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setDeleteRows($pValue = false) + public function setDeleteRows($pValue = false) { $this->_deleteRows = $pValue; return $this; @@ -433,7 +433,7 @@ function setDeleteRows($pValue = false) * * @return boolean */ - function getSelectLockedCells() + public function getSelectLockedCells() { return $this->_selectLockedCells; } @@ -444,7 +444,7 @@ function getSelectLockedCells() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setSelectLockedCells($pValue = false) + public function setSelectLockedCells($pValue = false) { $this->_selectLockedCells = $pValue; return $this; @@ -455,7 +455,7 @@ function setSelectLockedCells($pValue = false) * * @return boolean */ - function getSort() + public function getSort() { return $this->_sort; } @@ -466,7 +466,7 @@ function getSort() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setSort($pValue = false) + public function setSort($pValue = false) { $this->_sort = $pValue; return $this; @@ -477,7 +477,7 @@ function setSort($pValue = false) * * @return boolean */ - function getAutoFilter() + public function getAutoFilter() { return $this->_autoFilter; } @@ -488,7 +488,7 @@ function getAutoFilter() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setAutoFilter($pValue = false) + public function setAutoFilter($pValue = false) { $this->_autoFilter = $pValue; return $this; @@ -499,7 +499,7 @@ function setAutoFilter($pValue = false) * * @return boolean */ - function getPivotTables() + public function getPivotTables() { return $this->_pivotTables; } @@ -510,7 +510,7 @@ function getPivotTables() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setPivotTables($pValue = false) + public function setPivotTables($pValue = false) { $this->_pivotTables = $pValue; return $this; @@ -521,7 +521,7 @@ function setPivotTables($pValue = false) * * @return boolean */ - function getSelectUnlockedCells() + public function getSelectUnlockedCells() { return $this->_selectUnlockedCells; } @@ -532,7 +532,7 @@ function getSelectUnlockedCells() * @param boolean $pValue * @return PHPExcel_Worksheet_Protection */ - function setSelectUnlockedCells($pValue = false) + public function setSelectUnlockedCells($pValue = false) { $this->_selectUnlockedCells = $pValue; return $this; @@ -543,7 +543,7 @@ function setSelectUnlockedCells($pValue = false) * * @return string */ - function getPassword() + public function getPassword() { return $this->_password; } @@ -555,7 +555,7 @@ function getPassword() * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true * @return PHPExcel_Worksheet_Protection */ - function setPassword($pValue = '', $pAlreadyHashed = false) + public function setPassword($pValue = '', $pAlreadyHashed = false) { if (!$pAlreadyHashed) { $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); From 4648e386f5bef0c2c40cfded27482225da8f4b14 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 18 May 2015 16:39:04 +0100 Subject: [PATCH 390/467] Getting close to the end of all this psr-2 goodness now, and beginning to think about splitting to a 1.8 branch and a 1.9 branch, with the 1.9 branch having a minimum PHP version of 5.4, so we can begin improving the code, starting with namespacing and a simple bootstrap for those who don't use composer --- Classes/PHPExcel/Calculation.php | 34 +- Classes/PHPExcel/Calculation/Database.php | 2 +- Classes/PHPExcel/Calculation/Functions.php | 4 +- Classes/PHPExcel/Calculation/MathTrig.php | 2 +- Classes/PHPExcel/Calculation/Statistical.php | 8 +- Classes/PHPExcel/Chart.php | 6 +- Classes/PHPExcel/Chart/DataSeriesValues.php | 2 +- Classes/PHPExcel/IOFactory.php | 18 +- Classes/PHPExcel/NamedRange.php | 61 ++-- Classes/PHPExcel/Reader/CSV.php | 66 ++-- Classes/PHPExcel/Reader/Excel2003XML.php | 104 +++--- Classes/PHPExcel/Reader/Excel2007.php | 134 ++++---- Classes/PHPExcel/Reader/Excel2007/Chart.php | 184 +++++------ Classes/PHPExcel/Reader/Excel2007/Theme.php | 22 +- Classes/PHPExcel/Reader/Excel5.php | 10 +- Classes/PHPExcel/Reader/Excel5/Escher.php | 279 ++++++++-------- Classes/PHPExcel/Reader/Excel5/MD5.php | 12 +- Classes/PHPExcel/Reader/Excel5/RC4.php | 11 +- Classes/PHPExcel/Reader/Gnumeric.php | 44 +-- Classes/PHPExcel/Reader/OOCalc.php | 36 +- Classes/PHPExcel/Reader/SYLK.php | 30 +- Classes/PHPExcel/ReferenceHelper.php | 54 +-- Classes/PHPExcel/Shared/Escher.php | 23 +- .../PHPExcel/Shared/Escher/DgContainer.php | 29 +- .../Escher/DgContainer/SpgrContainer.php | 25 +- .../DgContainer/SpgrContainer/SpContainer.php | 87 +++-- .../PHPExcel/Shared/Escher/DggContainer.php | 49 ++- .../Escher/DggContainer/BstoreContainer.php | 17 +- .../DggContainer/BstoreContainer/BSE.php | 41 +-- .../DggContainer/BstoreContainer/BSE/Blip.php | 23 +- Classes/PHPExcel/Shared/Excel5.php | 15 +- Classes/PHPExcel/Shared/Font.php | 4 +- .../Shared/JAMA/EigenvalueDecomposition.php | 4 +- .../JAMA/SingularValueDecomposition.php | 2 +- Classes/PHPExcel/Shared/OLE/PPS/Root.php | 2 +- Classes/PHPExcel/Shared/OLERead.php | 2 +- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 74 ++--- Classes/PHPExcel/Shared/String.php | 2 +- Classes/PHPExcel/Style.php | 2 +- Classes/PHPExcel/Worksheet.php | 4 +- Classes/PHPExcel/Writer/CSV.php | 62 ++-- Classes/PHPExcel/Writer/Excel2007.php | 2 +- .../Writer/Excel2007/ContentTypes.php | 2 +- .../PHPExcel/Writer/Excel2007/StringTable.php | 8 +- Classes/PHPExcel/Writer/Excel2007/Style.php | 6 +- .../PHPExcel/Writer/Excel2007/Worksheet.php | 14 +- Classes/PHPExcel/Writer/Excel5.php | 118 +++---- Classes/PHPExcel/Writer/Excel5/Escher.php | 2 +- Classes/PHPExcel/Writer/Excel5/Font.php | 2 +- Classes/PHPExcel/Writer/Excel5/Workbook.php | 4 +- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 8 +- Classes/PHPExcel/Writer/Excel5/Xf.php | 309 +++++++++--------- Classes/PHPExcel/Writer/PDF/Core.php | 14 +- 53 files changed, 984 insertions(+), 1095 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index b94841c82..e13b93589 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2063,7 +2063,7 @@ class PHPExcel_Calculation private static $controlFunctions = array( 'MKMATRIX' => array( 'argumentCount' => '*', - 'functionCall' => 'self::_mkMatrix' + 'functionCall' => 'self::mkMatrix' ) ); @@ -2542,7 +2542,7 @@ public static function localeFunc($function) * @param mixed $value * @return mixed */ - public static function _wrapResult($value) + public static function wrapResult($value) { if (is_string($value)) { // Error values cannot be "wrapped" @@ -2567,7 +2567,7 @@ public static function _wrapResult($value) * @param mixed $value * @return mixed */ - public static function _unwrapResult($value) + public static function unwrapResult($value) { if (is_string($value)) { if ((isset($value{0})) && ($value{0} == '"') && (substr($value, -1) == '"')) { @@ -2634,7 +2634,7 @@ public function calculateCellValue(PHPExcel_Cell $pCell = null, $resetLog = true 'cell' => $pCell->getCoordinate(), ); try { - $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); + $result = self::unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); $cellAddress = array_pop($this->cellStack); $this->workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); } catch (PHPExcel_Exception $e) { @@ -2726,7 +2726,7 @@ public function calculateFormula($formula, $cellID = null, PHPExcel_Cell $pCell $this->calculationCacheEnabled = false; // Execute the calculation try { - $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); + $result = self::unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); } catch (PHPExcel_Exception $e) { throw new PHPExcel_Calculation_Exception($e->getMessage()); } @@ -2776,11 +2776,11 @@ public function _calculateFormulaValue($formula, $cellID = null, PHPExcel_Cell $ // We simply return the cell value if not $formula = trim($formula); if ($formula{0} != '=') { - return self::_wrapResult($formula); + return self::wrapResult($formula); } $formula = ltrim(substr($formula, 1)); if (!isset($formula{0})) { - return self::_wrapResult($formula); + return self::wrapResult($formula); } $pCellParent = ($pCell !== null) ? $pCell->getWorksheet() : null; @@ -2811,7 +2811,7 @@ public function _calculateFormulaValue($formula, $cellID = null, PHPExcel_Cell $ // Parse the formula onto the token stack and calculate the value $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(); // Save to calculation cache @@ -3108,7 +3108,7 @@ private function convertMatrixReferences($formula) } - private static function _mkMatrix() + private static function mkMatrix() { return func_get_args(); } @@ -3416,7 +3416,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) if ($opCharacter == '"') { // echo 'Element is a String<br />'; // UnEscape any quotes within the string - $val = self::_wrapResult(str_replace('""', '"', self::_unwrapResult($val))); + $val = self::wrapResult(str_replace('""', '"', self::unwrapResult($val))); } elseif (is_numeric($val)) { // echo 'Element is a Number<br />'; if ((strpos($val, '.') !== false) || (stripos($val, 'e') !== false) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { @@ -3519,7 +3519,7 @@ private static function _dataTestReference(&$operandData) } // evaluate postfix notation - private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCell = null) + private function processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCell = null) { if ($tokens == false) { return false; @@ -3659,7 +3659,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel $result = '#VALUE!'; } } else { - $result = '"'.str_replace('""', '"', self::_unwrapResult($operand1, '"').self::_unwrapResult($operand2, '"')).'"'; + $result = '"'.str_replace('""', '"', self::unwrapResult($operand1, '"').self::unwrapResult($operand2, '"')).'"'; } $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($result)); $stack->push('Value', $result); @@ -3832,7 +3832,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel } } } else { - $args[] = self::_unwrapResult($arg['value']); + $args[] = self::unwrapResult($arg['value']); if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->showValue($arg['value']); } @@ -3892,7 +3892,7 @@ private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCel if ($functionName != 'MKMATRIX') { $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->showTypeDetails($result)); } - $stack->push('Value', self::_wrapResult($result)); + $stack->push('Value', self::wrapResult($result)); } } else { @@ -3948,7 +3948,7 @@ private function validateBinaryOperand($cellID, &$operand, &$stack) // We only need special validations for the operand if it is a string // Start by stripping off the quotation marks we use to identify true excel string values internally if ($operand > '' && $operand{0} == '"') { - $operand = self::_unwrapResult($operand); + $operand = self::unwrapResult($operand); } // If the string is a numeric value, we treat it as a numeric, so no further testing if (!is_numeric($operand)) { @@ -4010,10 +4010,10 @@ private function executeBinaryComparisonOperation($cellID, $operand1, $operand2, // Simple validate the two operands if they are string values if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { - $operand1 = self::_unwrapResult($operand1); + $operand1 = self::unwrapResult($operand1); } if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { - $operand2 = self::_unwrapResult($operand2); + $operand2 = self::unwrapResult($operand2); } // Use case insensitive comparaison if not OpenOffice mode diff --git a/Classes/PHPExcel/Calculation/Database.php b/Classes/PHPExcel/Calculation/Database.php index af150fe03..b8d91cb6e 100644 --- a/Classes/PHPExcel/Calculation/Database.php +++ b/Classes/PHPExcel/Calculation/Database.php @@ -126,7 +126,7 @@ private static function filter($database, $criteria) $k = array_search($criteriaName, $fieldNames); if (isset($dataValues[$k])) { $dataValue = $dataValues[$k]; - $dataValue = (is_string($dataValue)) ? PHPExcel_Calculation::_wrapResult(strtoupper($dataValue)) : $dataValue; + $dataValue = (is_string($dataValue)) ? PHPExcel_Calculation::wrapResult(strtoupper($dataValue)) : $dataValue; $testConditionList = str_replace('[:' . $criteriaName . ']', $dataValue, $testConditionList); } } diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index 4d1771b9d..9e7a5db10 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -323,7 +323,7 @@ public static function ifCondition($condition) } if (!in_array($condition{0}, array('>', '<', '='))) { if (!is_numeric($condition)) { - $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); + $condition = PHPExcel_Calculation::wrapResult(strtoupper($condition)); } return '=' . $condition; } else { @@ -332,7 +332,7 @@ public static function ifCondition($condition) if (!is_numeric($operand)) { $operand = str_replace('"', '""', $operand); - $operand = PHPExcel_Calculation::_wrapResult(strtoupper($operand)); + $operand = PHPExcel_Calculation::wrapResult(strtoupper($operand)); } return $operator.$operand; diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index 9d5a439e6..dae2aa1ef 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -1206,7 +1206,7 @@ public static function SUMIF($aArgs, $condition, $sumArgs = array()) foreach ($aArgs as $key => $arg) { if (!is_numeric($arg)) { $arg = str_replace('"', '""', $arg); - $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + $arg = PHPExcel_Calculation::wrapResult(strtoupper($arg)); } $testCondition = '='.$arg.$condition; diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php index cd43dd6c7..500f95096 100644 --- a/Classes/PHPExcel/Calculation/Statistical.php +++ b/Classes/PHPExcel/Calculation/Statistical.php @@ -877,7 +877,7 @@ public static function AVERAGEIF($aArgs, $condition, $averageArgs = array()) $aCount = 0; foreach ($aArgs as $key => $arg) { if (!is_numeric($arg)) { - $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + $arg = PHPExcel_Calculation::wrapResult(strtoupper($arg)); } $testCondition = '='.$arg.$condition; if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { @@ -1298,7 +1298,7 @@ public static function COUNTIF($aArgs, $condition) // Loop through arguments foreach ($aArgs as $arg) { if (!is_numeric($arg)) { - $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + $arg = PHPExcel_Calculation::wrapResult(strtoupper($arg)); } $testCondition = '='.$arg.$condition; if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { @@ -2290,7 +2290,7 @@ public static function MAXIF($aArgs, $condition, $sumArgs = array()) // Loop through arguments foreach ($aArgs as $key => $arg) { if (!is_numeric($arg)) { - $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + $arg = PHPExcel_Calculation::wrapResult(strtoupper($arg)); } $testCondition = '='.$arg.$condition; if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { @@ -2449,7 +2449,7 @@ public static function MINIF($aArgs, $condition, $sumArgs = array()) // Loop through arguments foreach ($aArgs as $key => $arg) { if (!is_numeric($arg)) { - $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + $arg = PHPExcel_Calculation::wrapResult(strtoupper($arg)); } $testCondition = '='.$arg.$condition; if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { diff --git a/Classes/PHPExcel/Chart.php b/Classes/PHPExcel/Chart.php index 0cc22c145..d7799935b 100644 --- a/Classes/PHPExcel/Chart.php +++ b/Classes/PHPExcel/Chart.php @@ -32,7 +32,7 @@ class PHPExcel_Chart * * @var string */ - private $_name = ''; + private $name = ''; /** * Worksheet @@ -171,7 +171,7 @@ class PHPExcel_Chart */ public function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_Chart_Legend $legend = null, PHPExcel_Chart_PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = '0', PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, PHPExcel_Chart_Axis $xAxis = null, PHPExcel_Chart_Axis $yAxis = null, PHPExcel_Chart_GridLines $majorGridlines = null, PHPExcel_Chart_GridLines $minorGridlines = null) { - $this->_name = $name; + $this->name = $name; $this->title = $title; $this->legend = $legend; $this->xAxisLabel = $xAxisLabel; @@ -192,7 +192,7 @@ public function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_ */ public function getName() { - return $this->_name; + return $this->name; } /** diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php index 23d185deb..ea57e52a1 100644 --- a/Classes/PHPExcel/Chart/DataSeriesValues.php +++ b/Classes/PHPExcel/Chart/DataSeriesValues.php @@ -288,7 +288,7 @@ public function refresh(PHPExcel_Worksheet $worksheet, $flatten = true) { if ($this->dataSource !== null) { $calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent()); - $newDataValues = PHPExcel_Calculation::_unwrapResult( + $newDataValues = PHPExcel_Calculation::unwrapResult( $calcEngine->_calculateFormulaValue( '='.$this->dataSource, null, diff --git a/Classes/PHPExcel/IOFactory.php b/Classes/PHPExcel/IOFactory.php index bc1d99e3c..3ecda1777 100644 --- a/Classes/PHPExcel/IOFactory.php +++ b/Classes/PHPExcel/IOFactory.php @@ -43,7 +43,7 @@ class PHPExcel_IOFactory * @access private * @static */ - private static $_searchLocations = array( + private static $searchLocations = array( array( 'type' => 'IWriter', 'path' => 'PHPExcel/Writer/{0}.php', 'class' => 'PHPExcel_Writer_{0}' ), array( 'type' => 'IReader', 'path' => 'PHPExcel/Reader/{0}.php', 'class' => 'PHPExcel_Reader_{0}' ) ); @@ -55,7 +55,7 @@ class PHPExcel_IOFactory * @access private * @static */ - private static $_autoResolveClasses = array( + private static $autoResolveClasses = array( 'Excel2007', 'Excel5', 'Excel2003XML', @@ -82,7 +82,7 @@ private function __construct() */ public static function getSearchLocations() { - return self::$_searchLocations; + return self::$searchLocations; } /** @@ -96,7 +96,7 @@ public static function getSearchLocations() public static function setSearchLocations($value) { if (is_array($value)) { - self::$_searchLocations = $value; + self::$searchLocations = $value; } else { throw new PHPExcel_Reader_Exception('Invalid parameter passed.'); } @@ -113,7 +113,7 @@ public static function setSearchLocations($value) */ public static function addSearchLocation($type = '', $location = '', $classname = '') { - self::$_searchLocations[] = array( 'type' => $type, 'path' => $location, 'class' => $classname ); + self::$searchLocations[] = array( 'type' => $type, 'path' => $location, 'class' => $classname ); } /** @@ -132,7 +132,7 @@ public static function createWriter(PHPExcel $phpExcel, $writerType = '') $searchType = 'IWriter'; // Include class - foreach (self::$_searchLocations as $searchLocation) { + foreach (self::$searchLocations as $searchLocation) { if ($searchLocation['type'] == $searchType) { $className = str_replace('{0}', $writerType, $searchLocation['class']); @@ -162,7 +162,7 @@ public static function createReader($readerType = '') $searchType = 'IReader'; // Include class - foreach (self::$_searchLocations as $searchLocation) { + foreach (self::$searchLocations as $searchLocation) { if ($searchLocation['type'] == $searchType) { $className = str_replace('{0}', $readerType, $searchLocation['class']); @@ -273,8 +273,8 @@ public static function createReaderForFile($pFilename) } // If we reach here then "lucky guess" didn't give any result - // Try walking through all the options in self::$_autoResolveClasses - foreach (self::$_autoResolveClasses as $autoResolveClass) { + // Try walking through all the options in self::$autoResolveClasses + foreach (self::$autoResolveClasses as $autoResolveClass) { // Ignore our original guess, we know that won't work if ($autoResolveClass !== $extensionType) { $reader = self::createReader($autoResolveClass); diff --git a/Classes/PHPExcel/NamedRange.php b/Classes/PHPExcel/NamedRange.php index 318bcf3b5..2848db838 100644 --- a/Classes/PHPExcel/NamedRange.php +++ b/Classes/PHPExcel/NamedRange.php @@ -32,35 +32,35 @@ class PHPExcel_NamedRange * * @var string */ - private $_name; + private $name; /** * Worksheet on which the named range can be resolved * * @var PHPExcel_Worksheet */ - private $_worksheet; + private $worksheet; /** * Range of the referenced cells * * @var string */ - private $_range; + private $range; /** - * Is the named range local? (i.e. can only be used on $this->_worksheet) + * Is the named range local? (i.e. can only be used on $this->worksheet) * * @var bool */ - private $_localOnly; + private $localOnly; /** * Scope * * @var PHPExcel_Worksheet */ - private $_scope; + private $scope; /** * Create a new NamedRange @@ -80,12 +80,11 @@ public function __construct($pName = null, PHPExcel_Worksheet $pWorksheet, $pRan } // Set local members - $this->_name = $pName; - $this->_worksheet = $pWorksheet; - $this->_range = $pRange; - $this->_localOnly = $pLocalOnly; - $this->_scope = ($pLocalOnly == true) ? - (($pScope == null) ? $pWorksheet : $pScope) : null; + $this->name = $pName; + $this->worksheet = $pWorksheet; + $this->range = $pRange; + $this->localOnly = $pLocalOnly; + $this->scope = ($pLocalOnly == true) ? (($pScope == null) ? $pWorksheet : $pScope) : null; } /** @@ -95,7 +94,7 @@ public function __construct($pName = null, PHPExcel_Worksheet $pWorksheet, $pRan */ public function getName() { - return $this->_name; + return $this->name; } /** @@ -108,21 +107,21 @@ public function setName($value = null) { if ($value !== null) { // Old title - $oldTitle = $this->_name; + $oldTitle = $this->name; // Re-attach - if ($this->_worksheet !== null) { - $this->_worksheet->getParent()->removeNamedRange($this->_name, $this->_worksheet); + if ($this->worksheet !== null) { + $this->worksheet->getParent()->removeNamedRange($this->name, $this->worksheet); } - $this->_name = $value; + $this->name = $value; - if ($this->_worksheet !== null) { - $this->_worksheet->getParent()->addNamedRange($this); + if ($this->worksheet !== null) { + $this->worksheet->getParent()->addNamedRange($this); } // New title - $newTitle = $this->_name; - PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_worksheet->getParent(), $oldTitle, $newTitle); + $newTitle = $this->name; + PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->worksheet->getParent(), $oldTitle, $newTitle); } return $this; } @@ -134,7 +133,7 @@ public function setName($value = null) */ public function getWorksheet() { - return $this->_worksheet; + return $this->worksheet; } /** @@ -146,7 +145,7 @@ public function getWorksheet() public function setWorksheet(PHPExcel_Worksheet $value = null) { if ($value !== null) { - $this->_worksheet = $value; + $this->worksheet = $value; } return $this; } @@ -158,7 +157,7 @@ public function setWorksheet(PHPExcel_Worksheet $value = null) */ public function getRange() { - return $this->_range; + return $this->range; } /** @@ -170,7 +169,7 @@ public function getRange() public function setRange($value = null) { if ($value !== null) { - $this->_range = $value; + $this->range = $value; } return $this; } @@ -182,7 +181,7 @@ public function setRange($value = null) */ public function getLocalOnly() { - return $this->_localOnly; + return $this->localOnly; } /** @@ -193,8 +192,8 @@ public function getLocalOnly() */ public function setLocalOnly($value = false) { - $this->_localOnly = $value; - $this->_scope = $value ? $this->_worksheet : null; + $this->localOnly = $value; + $this->scope = $value ? $this->worksheet : null; return $this; } @@ -205,7 +204,7 @@ public function setLocalOnly($value = false) */ public function getScope() { - return $this->_scope; + return $this->scope; } /** @@ -216,8 +215,8 @@ public function getScope() */ public function setScope(PHPExcel_Worksheet $value = null) { - $this->_scope = $value; - $this->_localOnly = ($value == null) ? false : true; + $this->scope = $value; + $this->localOnly = ($value == null) ? false : true; return $this; } diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index c168310e4..65e2d3b64 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -50,7 +50,7 @@ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_R * @access private * @var string */ - private $_inputEncoding = 'UTF-8'; + private $inputEncoding = 'UTF-8'; /** * Delimiter @@ -58,7 +58,7 @@ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_R * @access private * @var string */ - private $_delimiter = ','; + private $delimiter = ','; /** * Enclosure @@ -66,7 +66,7 @@ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_R * @access private * @var string */ - private $_enclosure = '"'; + private $enclosure = '"'; /** * Sheet index to read @@ -74,7 +74,7 @@ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_R * @access private * @var int */ - private $_sheetIndex = 0; + private $sheetIndex = 0; /** * Load rows contiguously @@ -82,14 +82,14 @@ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_R * @access private * @var int */ - private $_contiguous = false; + private $contiguous = false; /** * Row counter for loading rows contiguously * * @var int */ - private $_contiguousRow = -1; + private $contiguousRow = -1; /** @@ -97,7 +97,7 @@ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_R */ public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); } /** @@ -117,7 +117,7 @@ protected function _isValidFormat() */ public function setInputEncoding($pValue = 'UTF-8') { - $this->_inputEncoding = $pValue; + $this->inputEncoding = $pValue; return $this; } @@ -128,7 +128,7 @@ public function setInputEncoding($pValue = 'UTF-8') */ public function getInputEncoding() { - return $this->_inputEncoding; + return $this->inputEncoding; } /** @@ -139,7 +139,7 @@ protected function _skipBOM() { rewind($this->_fileHandle); - switch ($this->_inputEncoding) { + switch ($this->inputEncoding) { case 'UTF-8': fgets($this->_fileHandle, 4) == "\xEF\xBB\xBF" ? fseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0); @@ -184,7 +184,7 @@ public function listWorksheetInfo($pFilename) // Skip BOM, if any $this->_skipBOM(); - $escapeEnclosures = array( "\\" . $this->_enclosure, $this->_enclosure . $this->_enclosure ); + $escapeEnclosures = array( "\\" . $this->enclosure, $this->enclosure . $this->enclosure ); $worksheetInfo = array(); $worksheetInfo[0]['worksheetName'] = 'Worksheet'; @@ -194,7 +194,7 @@ public function listWorksheetInfo($pFilename) $worksheetInfo[0]['totalColumns'] = 0; // Loop through each line of the file in turn - while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== false) { + while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) { $worksheetInfo[0]['totalRows']++; $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1); } @@ -249,32 +249,32 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $this->_skipBOM(); // Create new PHPExcel object - while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + while ($objPHPExcel->getSheetCount() <= $this->sheetIndex) { $objPHPExcel->createSheet(); } - $sheet = $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); + $sheet = $objPHPExcel->setActiveSheetIndex($this->sheetIndex); - $escapeEnclosures = array( "\\" . $this->_enclosure, - $this->_enclosure . $this->_enclosure + $escapeEnclosures = array( "\\" . $this->enclosure, + $this->enclosure . $this->enclosure ); // Set our starting row based on whether we're in contiguous mode or not $currentRow = 1; - if ($this->_contiguous) { - $currentRow = ($this->_contiguousRow == -1) ? $sheet->getHighestRow(): $this->_contiguousRow; + if ($this->contiguous) { + $currentRow = ($this->contiguousRow == -1) ? $sheet->getHighestRow(): $this->contiguousRow; } // Loop through each line of the file in turn - while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== false) { + while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) { $columnLetter = 'A'; foreach ($rowData as $rowDatum) { if ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) { // Unescape enclosures - $rowDatum = str_replace($escapeEnclosures, $this->_enclosure, $rowDatum); + $rowDatum = str_replace($escapeEnclosures, $this->enclosure, $rowDatum); // Convert encoding if necessary - if ($this->_inputEncoding !== 'UTF-8') { - $rowDatum = PHPExcel_Shared_String::ConvertEncoding($rowDatum, 'UTF-8', $this->_inputEncoding); + if ($this->inputEncoding !== 'UTF-8') { + $rowDatum = PHPExcel_Shared_String::ConvertEncoding($rowDatum, 'UTF-8', $this->inputEncoding); } // Set cell value @@ -288,8 +288,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Close file fclose($fileHandle); - if ($this->_contiguous) { - $this->_contiguousRow = $currentRow; + if ($this->contiguous) { + $this->contiguousRow = $currentRow; } ini_set('auto_detect_line_endings', $lineEnding); @@ -305,7 +305,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) */ public function getDelimiter() { - return $this->_delimiter; + return $this->delimiter; } /** @@ -316,7 +316,7 @@ public function getDelimiter() */ public function setDelimiter($pValue = ',') { - $this->_delimiter = $pValue; + $this->delimiter = $pValue; return $this; } @@ -327,7 +327,7 @@ public function setDelimiter($pValue = ',') */ public function getEnclosure() { - return $this->_enclosure; + return $this->enclosure; } /** @@ -341,7 +341,7 @@ public function setEnclosure($pValue = '"') if ($pValue == '') { $pValue = '"'; } - $this->_enclosure = $pValue; + $this->enclosure = $pValue; return $this; } @@ -352,7 +352,7 @@ public function setEnclosure($pValue = '"') */ public function getSheetIndex() { - return $this->_sheetIndex; + return $this->sheetIndex; } /** @@ -363,7 +363,7 @@ public function getSheetIndex() */ public function setSheetIndex($pValue = 0) { - $this->_sheetIndex = $pValue; + $this->sheetIndex = $pValue; return $this; } @@ -374,9 +374,9 @@ public function setSheetIndex($pValue = 0) */ public function setContiguous($contiguous = false) { - $this->_contiguous = (bool) $contiguous; + $this->contiguous = (bool) $contiguous; if (!$contiguous) { - $this->_contiguousRow = -1; + $this->contiguousRow = -1; } return $this; @@ -389,6 +389,6 @@ public function setContiguous($contiguous = false) */ public function getContiguous() { - return $this->_contiguous; + return $this->contiguous; } } diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index f27c8c8a1..feb0aaa02 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -1,6 +1,16 @@ <?php + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + /** - * PHPExcel + * PHPExcel_Reader_Excel2003XML * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,24 +34,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** PHPExcel root directory */ -if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); -} - -/** - * PHPExcel_Reader_Excel2003XML - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { /** @@ -49,21 +41,21 @@ class PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements P * * @var array */ - protected $_styles = array(); + protected $styles = array(); /** * Character set used in the file * * @var string */ - protected $_charSet = 'UTF-8'; + protected $charSet = 'UTF-8'; /** * Create a new PHPExcel_Reader_Excel2003XML */ public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); } @@ -111,9 +103,9 @@ public function canRead($pFilename) // Retrieve charset encoding if (preg_match('/<?xml.*encoding=[\'"](.*?)[\'"].*?>/um', $data, $matches)) { - $this->_charSet = strtoupper($matches[1]); + $this->charSet = strtoupper($matches[1]); } -// echo 'Character Set is ', $this->_charSet,'<br />'; +// echo 'Character Set is ', $this->charSet,'<br />'; return $valid; } @@ -143,7 +135,7 @@ public function listWorksheetNames($pFilename) $xml_ss = $xml->children($namespaces['ss']); foreach ($xml_ss->Worksheet as $worksheet) { $worksheet_ss = $worksheet->attributes($namespaces['ss']); - $worksheetNames[] = self::_convertStringEncoding((string) $worksheet_ss['Name'], $this->_charSet); + $worksheetNames[] = self::_convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet); } return $worksheetNames; @@ -337,39 +329,39 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($xml->DocumentProperties[0] as $propertyName => $propertyValue) { switch ($propertyName) { case 'Title': - $docProps->setTitle(self::_convertStringEncoding($propertyValue, $this->_charSet)); + $docProps->setTitle(self::_convertStringEncoding($propertyValue, $this->charSet)); break; case 'Subject': - $docProps->setSubject(self::_convertStringEncoding($propertyValue, $this->_charSet)); + $docProps->setSubject(self::_convertStringEncoding($propertyValue, $this->charSet)); break; case 'Author': - $docProps->setCreator(self::_convertStringEncoding($propertyValue, $this->_charSet)); + $docProps->setCreator(self::_convertStringEncoding($propertyValue, $this->charSet)); break; case 'Created': $creationDate = strtotime($propertyValue); $docProps->setCreated($creationDate); break; case 'LastAuthor': - $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue, $this->_charSet)); + $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue, $this->charSet)); break; case 'LastSaved': $lastSaveDate = strtotime($propertyValue); $docProps->setModified($lastSaveDate); break; case 'Company': - $docProps->setCompany(self::_convertStringEncoding($propertyValue, $this->_charSet)); + $docProps->setCompany(self::_convertStringEncoding($propertyValue, $this->charSet)); break; case 'Category': - $docProps->setCategory(self::_convertStringEncoding($propertyValue, $this->_charSet)); + $docProps->setCategory(self::_convertStringEncoding($propertyValue, $this->charSet)); break; case 'Manager': - $docProps->setManager(self::_convertStringEncoding($propertyValue, $this->_charSet)); + $docProps->setManager(self::_convertStringEncoding($propertyValue, $this->charSet)); break; case 'Keywords': - $docProps->setKeywords(self::_convertStringEncoding($propertyValue, $this->_charSet)); + $docProps->setKeywords(self::_convertStringEncoding($propertyValue, $this->charSet)); break; case 'Description': - $docProps->setDescription(self::_convertStringEncoding($propertyValue, $this->_charSet)); + $docProps->setDescription(self::_convertStringEncoding($propertyValue, $this->charSet)); break; } } @@ -410,9 +402,9 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $styleID = (string) $style_ss['ID']; // echo 'Style ID = '.$styleID.'<br />'; if ($styleID == 'Default') { - $this->_styles['Default'] = array(); + $this->styles['Default'] = array(); } else { - $this->_styles[$styleID] = $this->_styles['Default']; + $this->styles[$styleID] = $this->styles['Default']; } foreach ($style as $styleType => $styleData) { $styleAttributes = $styleData->attributes($namespaces['ss']); @@ -425,16 +417,16 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) switch ($styleAttributeKey) { case 'Vertical': if (self::identifyFixedStyleValue($verticalAlignmentStyles, $styleAttributeValue)) { - $this->_styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; + $this->styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; } break; case 'Horizontal': if (self::identifyFixedStyleValue($horizontalAlignmentStyles, $styleAttributeValue)) { - $this->_styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; + $this->styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; } break; case 'WrapText': - $this->_styles[$styleID]['alignment']['wrap'] = true; + $this->styles[$styleID]['alignment']['wrap'] = true; break; } } @@ -464,7 +456,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } if (!empty($thisBorder)) { if (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) { - $this->_styles[$styleID]['borders'][$borderPosition] = $thisBorder; + $this->styles[$styleID]['borders'][$borderPosition] = $thisBorder; } } } @@ -475,23 +467,23 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $styleAttributeValue = (string) $styleAttributeValue; switch ($styleAttributeKey) { case 'FontName': - $this->_styles[$styleID]['font']['name'] = $styleAttributeValue; + $this->styles[$styleID]['font']['name'] = $styleAttributeValue; break; case 'Size': - $this->_styles[$styleID]['font']['size'] = $styleAttributeValue; + $this->styles[$styleID]['font']['size'] = $styleAttributeValue; break; case 'Color': - $this->_styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue, 1); + $this->styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue, 1); break; case 'Bold': - $this->_styles[$styleID]['font']['bold'] = true; + $this->styles[$styleID]['font']['bold'] = true; break; case 'Italic': - $this->_styles[$styleID]['font']['italic'] = true; + $this->styles[$styleID]['font']['italic'] = true; break; case 'Underline': if (self::identifyFixedStyleValue($underlineStyles, $styleAttributeValue)) { - $this->_styles[$styleID]['font']['underline'] = $styleAttributeValue; + $this->styles[$styleID]['font']['underline'] = $styleAttributeValue; } break; } @@ -502,7 +494,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; switch ($styleAttributeKey) { case 'Color': - $this->_styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue, 1); + $this->styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue, 1); break; } } @@ -517,7 +509,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) break; } if ($styleAttributeValue > '') { - $this->_styles[$styleID]['numberformat']['code'] = $styleAttributeValue; + $this->styles[$styleID]['numberformat']['code'] = $styleAttributeValue; } } break; @@ -528,7 +520,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) break; } } -// print_r($this->_styles[$styleID]); +// print_r($this->styles[$styleID]); // echo '<hr />'; } // echo '<hr />'; @@ -550,7 +542,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $objPHPExcel->createSheet(); $objPHPExcel->setActiveSheetIndex($worksheetID); if (isset($worksheet_ss['Name'])) { - $worksheetName = self::_convertStringEncoding((string) $worksheet_ss['Name'], $this->_charSet); + $worksheetName = self::_convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet); // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in // formula cells... during the load, all formulae should be correct, and we're simply bringing // the worksheet name in line with the formula, not the reverse @@ -640,7 +632,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) const TYPE_ERROR = 'e'; */ case 'String': - $cellValue = self::_convertStringEncoding($cellValue, $this->_charSet); + $cellValue = self::_convertStringEncoding($cellValue, $this->charSet); $type = PHPExcel_Cell_DataType::TYPE_STRING; break; case 'Number': @@ -748,20 +740,20 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo $annotation,'<br />'; $annotation = strip_tags($node); // echo 'Annotation: ', $annotation,'<br />'; - $objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setAuthor(self::_convertStringEncoding($author, $this->_charSet))->setText($this->_parseRichText($annotation)); + $objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setAuthor(self::_convertStringEncoding($author, $this->charSet))->setText($this->_parseRichText($annotation)); } if (($cellIsSet) && (isset($cell_ss['StyleID']))) { $style = (string) $cell_ss['StyleID']; // echo 'Cell style for '.$columnID.$rowID.' is '.$style.'<br />'; - if ((isset($this->_styles[$style])) && (!empty($this->_styles[$style]))) { + if ((isset($this->styles[$style])) && (!empty($this->styles[$style]))) { // echo 'Cell '.$columnID.$rowID.'<br />'; -// print_r($this->_styles[$style]); +// print_r($this->styles[$style]); // echo '<br />'; if (!$objPHPExcel->getActiveSheet()->cellExists($columnID.$rowID)) { $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValue(null); } - $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->_styles[$style]); + $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->styles[$style]); } } ++$columnID; @@ -806,7 +798,7 @@ protected function _parseRichText($is = '') { $value = new PHPExcel_RichText(); - $value->createText(self::_convertStringEncoding($is, $this->_charSet)); + $value->createText(self::_convertStringEncoding($is, $this->charSet)); return $value; } diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index cc2616ae0..47a130e3c 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -1,6 +1,16 @@ <?php + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + /** - * PHPExcel + * PHPExcel_Reader_Excel2007 * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,24 +34,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** PHPExcel root directory */ -if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); -} - -/** - * PHPExcel_Reader_Excel2007 - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { /** @@ -49,14 +41,14 @@ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPE * * @var PHPExcel_ReferenceHelper */ - private $_referenceHelper = null; + private $referenceHelper = null; /** * PHPExcel_Reader_Excel2007_Theme instance * * @var PHPExcel_Reader_Excel2007_Theme */ - private static $_theme = null; + private static $theme = null; /** * Create a new PHPExcel_Reader_Excel2007 instance @@ -64,7 +56,7 @@ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPE public function __construct() { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $this->referenceHelper = PHPExcel_ReferenceHelper::getInstance(); } /** @@ -239,7 +231,7 @@ public function listWorksheetInfo($pFilename) return $worksheetInfo; } - private static function _castToBool($c) + private static function castToBoolean($c) { // echo 'Initial Cast to Boolean', PHP_EOL; $value = isset($c->v) ? (string) $c->v : null; @@ -251,21 +243,21 @@ private static function _castToBool($c) return (bool)$c->v; } return $value; - } // function _castToBool() + } - private static function _castToError($c) + private static function castToError($c) { // echo 'Initial Cast to Error', PHP_EOL; return isset($c->v) ? (string) $c->v : null; - } // function _castToError() + } - private static function _castToString($c) + private static function castToString($c) { // echo 'Initial Cast to String, PHP_EOL; return isset($c->v) ? (string) $c->v : null; - } // function _castToString() + } - private function _castToFormula($c, $r, &$cellDataType, &$value, &$calculatedValue, &$sharedFormulas, $castBaseType) + private function castToFormula($c, $r, &$cellDataType, &$value, &$calculatedValue, &$sharedFormulas, $castBaseType) { // echo 'Formula', PHP_EOL; // echo '$c->f is ', $c->f, PHP_EOL; @@ -300,7 +292,7 @@ private function _castToFormula($c, $r, &$cellDataType, &$value, &$calculatedVal $difference[0] = PHPExcel_Cell::columnIndexFromString($current[0]) - PHPExcel_Cell::columnIndexFromString($master[0]); $difference[1] = $current[1] - $master[1]; - $value = $this->_referenceHelper->updateFormulaReferences($sharedFormulas[$instance]['formula'], 'A1', $difference[0], $difference[1]); + $value = $this->referenceHelper->updateFormulaReferences($sharedFormulas[$instance]['formula'], 'A1', $difference[0], $difference[1]); // echo 'Adjusted Formula is ', $value, PHP_EOL; } } @@ -384,7 +376,7 @@ public function load($pFilename) $themeColours[$themePos] = $xmlColourData['val']; } } - self::$_theme = new PHPExcel_Reader_Excel2007_Theme($themeName, $colourSchemeName, $themeColours); + self::$theme = new PHPExcel_Reader_Excel2007_Theme($themeName, $colourSchemeName, $themeColours); } break; } @@ -445,7 +437,7 @@ public function load($pFilename) case "http://schemas.microsoft.com/office/2006/relationships/ui/extensibility": $customUI = $rel['Target']; if (!is_null($customUI)) { - $this->_readRibbon($excel, $customUI, $zip); + $this->readRibbon($excel, $customUI, $zip); } break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": @@ -461,7 +453,7 @@ public function load($pFilename) if (isset($val->t)) { $sharedStrings[] = PHPExcel_Shared_String::ControlCharacterOOXML2PHP((string) $val->t); } elseif (isset($val->r)) { - $sharedStrings[] = $this->_parseRichText($val); + $sharedStrings[] = $this->parseRichText($val); } } } @@ -540,7 +532,7 @@ public function load($pFilename) // add style to cellXf collection $objStyle = new PHPExcel_Style; - self::_readStyle($objStyle, $style); + self::readStyle($objStyle, $style); $excel->addCellXf($objStyle); } @@ -550,7 +542,7 @@ public function load($pFilename) $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); if (isset($tmpNumFmt["formatCode"])) { $numFmt = (string) $tmpNumFmt["formatCode"]; - } else if ((int)$xf["numFmtId"] < 165) { + } elseif ((int)$xf["numFmtId"] < 165) { $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); } } @@ -568,7 +560,7 @@ public function load($pFilename) // add style to cellStyleXf collection $objStyle = new PHPExcel_Style; - self::_readStyle($objStyle, $cellStyle); + self::readStyle($objStyle, $cellStyle); $excel->addCellStyleXf($objStyle); } } @@ -579,7 +571,7 @@ public function load($pFilename) if ($xmlStyles->dxfs) { foreach ($xmlStyles->dxfs->dxf as $dxf) { $style = new PHPExcel_Style(false, true); - self::_readStyle($style, $dxf); + self::readStyle($style, $dxf); $dxfs[] = $style; } } @@ -590,7 +582,7 @@ public function load($pFilename) if (isset($cellStyles[intval($cellStyle['xfId'])])) { // Set default style $style = new PHPExcel_Style; - self::_readStyle($style, $cellStyles[intval($cellStyle['xfId'])]); + self::readStyle($style, $cellStyles[intval($cellStyle['xfId'])]); // normal style, currently not using it for anything } @@ -843,10 +835,10 @@ public function load($pFilename) case "b": // echo 'Boolean', PHP_EOL; if (!isset($c->f)) { - $value = self::_castToBool($c); + $value = self::castToBoolean($c); } else { // Formula - $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, '_castToBool'); + $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToBoolean'); if (isset($c->f['t'])) { $att = array(); $att = $c->f; @@ -857,15 +849,15 @@ public function load($pFilename) break; case "inlineStr": // echo 'Inline String', PHP_EOL; - $value = $this->_parseRichText($c->is); + $value = $this->parseRichText($c->is); break; case "e": // echo 'Error', PHP_EOL; if (!isset($c->f)) { - $value = self::_castToError($c); + $value = self::castToError($c); } else { // Formula - $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, '_castToError'); + $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToError'); // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; } break; @@ -873,11 +865,11 @@ public function load($pFilename) // echo 'Default', PHP_EOL; if (!isset($c->f)) { // echo 'Not a Formula', PHP_EOL; - $value = self::_castToString($c); + $value = self::castToString($c); } else { // echo 'Treat as Formula', PHP_EOL; // Formula - $this->_castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, '_castToString'); + $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToString'); // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; } break; @@ -1280,7 +1272,7 @@ public function load($pFilename) if (!empty($comment['authorId'])) { $docSheet->getComment((string)$comment['ref'])->setAuthor($authors[(string)$comment['authorId']]); } - $docSheet->getComment((string)$comment['ref'])->setText($this->_parseRichText($comment->text)); + $docSheet->getComment((string)$comment['ref'])->setText($this->parseRichText($comment->text)); } } @@ -1654,7 +1646,7 @@ public function load($pFilename) } break; } - } else if (!isset($definedName['localSheetId'])) { + } elseif (!isset($definedName['localSheetId'])) { // "Global" definedNames $locatedSheet = null; $extractedSheetName = ''; @@ -1732,15 +1724,15 @@ public function load($pFilename) return $excel; } - private static function _readColor($color, $background = false) + private static function readColor($color, $background = false) { if (isset($color["rgb"])) { return (string)$color["rgb"]; - } else if (isset($color["indexed"])) { + } elseif (isset($color["indexed"])) { return PHPExcel_Style_Color::indexedColor($color["indexed"]-7, $background)->getARGB(); - } else if (isset($color["theme"])) { - if (self::$_theme !== null) { - $returnColour = self::$_theme->getColourByIndex((int)$color["theme"]); + } elseif (isset($color["theme"])) { + if (self::$theme !== null) { + $returnColour = self::$theme->getColourByIndex((int)$color["theme"]); if (isset($color["tint"])) { $tintAdjust = (float) $color["tint"]; $returnColour = PHPExcel_Style_Color::changeBrightness($returnColour, $tintAdjust); @@ -1755,7 +1747,7 @@ private static function _readColor($color, $background = false) return 'FF000000'; } - private static function _readStyle($docStyle, $style) + private static function readStyle($docStyle, $style) { // format code // if (isset($style->numFmt)) { @@ -1779,11 +1771,11 @@ private static function _readStyle($docStyle, $style) if (isset($style->font->strike)) { $docStyle->getFont()->setStrikethrough(!isset($style->font->strike["val"]) || self::boolean((string) $style->font->strike["val"])); } - $docStyle->getFont()->getColor()->setARGB(self::_readColor($style->font->color)); + $docStyle->getFont()->getColor()->setARGB(self::readColor($style->font->color)); if (isset($style->font->u) && !isset($style->font->u["val"])) { $docStyle->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); - } else if (isset($style->font->u) && isset($style->font->u["val"])) { + } elseif (isset($style->font->u) && isset($style->font->u["val"])) { $docStyle->getFont()->setUnderline((string)$style->font->u["val"]); } @@ -1807,18 +1799,18 @@ private static function _readStyle($docStyle, $style) } $docStyle->getFill()->setRotation(floatval($gradientFill["degree"])); $gradientFill->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - $docStyle->getFill()->getStartColor()->setARGB(self::_readColor(self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color)); - $docStyle->getFill()->getEndColor()->setARGB(self::_readColor(self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color)); + $docStyle->getFill()->getStartColor()->setARGB(self::readColor(self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color)); + $docStyle->getFill()->getEndColor()->setARGB(self::readColor(self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color)); } elseif ($style->fill->patternFill) { $patternType = (string)$style->fill->patternFill["patternType"] != '' ? (string)$style->fill->patternFill["patternType"] : 'solid'; $docStyle->getFill()->setFillType($patternType); if ($style->fill->patternFill->fgColor) { - $docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor, true)); + $docStyle->getFill()->getStartColor()->setARGB(self::readColor($style->fill->patternFill->fgColor, true)); } else { $docStyle->getFill()->getStartColor()->setARGB('FF000000'); } if ($style->fill->patternFill->bgColor) { - $docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor, true)); + $docStyle->getFill()->getEndColor()->setARGB(self::readColor($style->fill->patternFill->bgColor, true)); } } } @@ -1836,11 +1828,11 @@ private static function _readStyle($docStyle, $style) } else { $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); } - self::_readBorder($docStyle->getBorders()->getLeft(), $style->border->left); - self::_readBorder($docStyle->getBorders()->getRight(), $style->border->right); - self::_readBorder($docStyle->getBorders()->getTop(), $style->border->top); - self::_readBorder($docStyle->getBorders()->getBottom(), $style->border->bottom); - self::_readBorder($docStyle->getBorders()->getDiagonal(), $style->border->diagonal); + self::readBorder($docStyle->getBorders()->getLeft(), $style->border->left); + self::readBorder($docStyle->getBorders()->getRight(), $style->border->right); + self::readBorder($docStyle->getBorders()->getTop(), $style->border->top); + self::readBorder($docStyle->getBorders()->getBottom(), $style->border->bottom); + self::readBorder($docStyle->getBorders()->getDiagonal(), $style->border->diagonal); } // alignment @@ -1851,7 +1843,7 @@ private static function _readStyle($docStyle, $style) $textRotation = 0; if ((int)$style->alignment["textRotation"] <= 90) { $textRotation = (int)$style->alignment["textRotation"]; - } else if ((int)$style->alignment["textRotation"] > 90) { + } elseif ((int)$style->alignment["textRotation"] > 90) { $textRotation = 90 - (int)$style->alignment["textRotation"]; } @@ -1887,17 +1879,17 @@ private static function _readStyle($docStyle, $style) } } - private static function _readBorder($docBorder, $eleBorder) + private static function readBorder($docBorder, $eleBorder) { if (isset($eleBorder["style"])) { $docBorder->setBorderStyle((string) $eleBorder["style"]); } if (isset($eleBorder->color)) { - $docBorder->getColor()->setARGB(self::_readColor($eleBorder->color)); + $docBorder->getColor()->setARGB(self::readColor($eleBorder->color)); } } - private function _parseRichText($is = null) + private function parseRichText($is = null) { $value = new PHPExcel_RichText(); @@ -1919,7 +1911,7 @@ private function _parseRichText($is = null) $objText->getFont()->setSize((string) $run->rPr->sz["val"]); } if (isset($run->rPr->color)) { - $objText->getFont()->setColor(new PHPExcel_Style_Color(self::_readColor($run->rPr->color))); + $objText->getFont()->setColor(new PHPExcel_Style_Color(self::readColor($run->rPr->color))); } if ((isset($run->rPr->b["val"]) && self::boolean((string) $run->rPr->b["val"])) || (isset($run->rPr->b) && !isset($run->rPr->b["val"]))) { @@ -1940,7 +1932,7 @@ private function _parseRichText($is = null) } if (isset($run->rPr->u) && !isset($run->rPr->u["val"])) { $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); - } else if (isset($run->rPr->u) && isset($run->rPr->u["val"])) { + } elseif (isset($run->rPr->u) && isset($run->rPr->u["val"])) { $objText->getFont()->setUnderline((string)$run->rPr->u["val"]); } if ((isset($run->rPr->strike["val"]) && self::boolean((string) $run->rPr->strike["val"])) || @@ -1955,7 +1947,7 @@ private function _parseRichText($is = null) return $value; } - private function _readRibbon($excel, $customUITarget, $zip) + private function readRibbon($excel, $customUITarget, $zip) { $baseDir = dirname($customUITarget); $nameCustomUI = basename($customUITarget); diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index 4569f2679..88f336b38 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Chart.php +++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php @@ -34,7 +34,7 @@ */ class PHPExcel_Reader_Excel2007_Chart { - private static function _getAttribute($component, $name, $format) + private static function getAttribute($component, $name, $format) { $attributes = $component->attributes(); if (isset($attributes[$name])) { @@ -49,14 +49,14 @@ private static function _getAttribute($component, $name, $format) } } return null; - } // function _getAttribute() + } - private static function _readColor($color, $background = false) + private static function readColor($color, $background = false) { if (isset($color["rgb"])) { return (string)$color["rgb"]; - } else if (isset($color["indexed"])) { + } elseif (isset($color["indexed"])) { return PHPExcel_Style_Color::indexedColor($color["indexed"]-7, $background)->getARGB(); } } @@ -81,82 +81,82 @@ public static function readChart($chartElements, $chartName) foreach ($chartDetails as $chartDetailKey => $chartDetail) { switch ($chartDetailKey) { case "layout": - $plotAreaLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta, 'plotArea'); + $plotAreaLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta, 'plotArea'); break; case "catAx": if (isset($chartDetail->title)) { - $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); + $XaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); } break; case "dateAx": if (isset($chartDetail->title)) { - $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); + $XaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); } break; case "valAx": if (isset($chartDetail->title)) { - $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); + $YaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); } break; case "barChart": case "bar3DChart": - $barDirection = self::_getAttribute($chartDetail->barDir, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $barDirection = self::getAttribute($chartDetail->barDir, 'val', 'string'); + $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotDirection($barDirection); $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); + $plotAttributes = self::readChartAttributes($chartDetail); break; case "lineChart": case "line3DChart": - $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotAttributes = self::_readChartAttributes($chartDetail); + $plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotAttributes = self::readChartAttributes($chartDetail); break; case "areaChart": case "area3DChart": - $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotAttributes = self::_readChartAttributes($chartDetail); + $plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotAttributes = self::readChartAttributes($chartDetail); break; case "doughnutChart": case "pieChart": case "pie3DChart": $explosion = isset($chartDetail->ser->explosion); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotStyle($explosion); $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); + $plotAttributes = self::readChartAttributes($chartDetail); break; case "scatterChart": - $scatterStyle = self::_getAttribute($chartDetail->scatterStyle, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $scatterStyle = self::getAttribute($chartDetail->scatterStyle, 'val', 'string'); + $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotStyle($scatterStyle); $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); + $plotAttributes = self::readChartAttributes($chartDetail); break; case "bubbleChart": - $bubbleScale = self::_getAttribute($chartDetail->bubbleScale, 'val', 'integer'); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $bubbleScale = self::getAttribute($chartDetail->bubbleScale, 'val', 'integer'); + $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotStyle($bubbleScale); $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); + $plotAttributes = self::readChartAttributes($chartDetail); break; case "radarChart": - $radarStyle = self::_getAttribute($chartDetail->radarStyle, 'val', 'string'); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $radarStyle = self::getAttribute($chartDetail->radarStyle, 'val', 'string'); + $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotStyle($radarStyle); $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); + $plotAttributes = self::readChartAttributes($chartDetail); break; case "surfaceChart": case "surface3DChart": - $wireFrame = self::_getAttribute($chartDetail->wireframe, 'val', 'boolean'); - $plotSer = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $wireFrame = self::getAttribute($chartDetail->wireframe, 'val', 'boolean'); + $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); $plotSer->setPlotStyle($wireFrame); $plotSeries[] = $plotSer; - $plotAttributes = self::_readChartAttributes($chartDetail); + $plotAttributes = self::readChartAttributes($chartDetail); break; case "stockChart": - $plotSeries[] = self::_chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); - $plotAttributes = self::_readChartAttributes($plotAreaLayout); + $plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); + $plotAttributes = self::readChartAttributes($plotAreaLayout); break; } } @@ -164,16 +164,16 @@ public static function readChart($chartElements, $chartName) $plotAreaLayout = new PHPExcel_Chart_Layout(); } $plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout, $plotSeries); - self::_setChartAttributes($plotAreaLayout, $plotAttributes); + self::setChartAttributes($plotAreaLayout, $plotAttributes); break; case "plotVisOnly": - $plotVisOnly = self::_getAttribute($chartDetails, 'val', 'string'); + $plotVisOnly = self::getAttribute($chartDetails, 'val', 'string'); break; case "dispBlanksAs": - $dispBlanksAs = self::_getAttribute($chartDetails, 'val', 'string'); + $dispBlanksAs = self::getAttribute($chartDetails, 'val', 'string'); break; case "title": - $title = self::_chartTitle($chartDetails, $namespacesChartMeta, 'title'); + $title = self::chartTitle($chartDetails, $namespacesChartMeta, 'title'); break; case "legend": $legendPos = 'r'; @@ -182,13 +182,13 @@ public static function readChart($chartElements, $chartName) foreach ($chartDetails as $chartDetailKey => $chartDetail) { switch ($chartDetailKey) { case "legendPos": - $legendPos = self::_getAttribute($chartDetail, 'val', 'string'); + $legendPos = self::getAttribute($chartDetail, 'val', 'string'); break; case "overlay": - $legendOverlay = self::_getAttribute($chartDetail, 'val', 'boolean'); + $legendOverlay = self::getAttribute($chartDetail, 'val', 'boolean'); break; case "layout": - $legendLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta, 'legend'); + $legendLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta, 'legend'); break; } } @@ -201,9 +201,9 @@ public static function readChart($chartElements, $chartName) $chart = new PHPExcel_Chart($chartName, $title, $legend, $plotArea, $plotVisOnly, $dispBlanksAs, $XaxisLabel, $YaxisLabel); return $chart; - } // function readChart() + } - private static function _chartTitle($titleDetails, $namespacesChartMeta, $type) + private static function chartTitle($titleDetails, $namespacesChartMeta, $type) { $caption = array(); $titleLayout = null; @@ -215,20 +215,20 @@ private static function _chartTitle($titleDetails, $namespacesChartMeta, $type) switch ($titleKey) { case "p": $titleDetailPart = $titleDetail->children($namespacesChartMeta['a']); - $caption[] = self::_parseRichText($titleDetailPart); + $caption[] = self::parseRichText($titleDetailPart); } } break; case "layout": - $titleLayout = self::_chartLayoutDetails($chartDetail, $namespacesChartMeta); + $titleLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta); break; } } return new PHPExcel_Chart_Title($caption, $titleLayout); - } // function _chartTitle() + } - private static function _chartLayoutDetails($chartDetail, $namespacesChartMeta) + private static function chartLayoutDetails($chartDetail, $namespacesChartMeta) { if (!isset($chartDetail->manualLayout)) { return null; @@ -239,13 +239,13 @@ private static function _chartLayoutDetails($chartDetail, $namespacesChartMeta) } $layout = array(); foreach ($details as $detailKey => $detail) { -// echo $detailKey, ' => ',self::_getAttribute($detail, 'val', 'string'),PHP_EOL; - $layout[$detailKey] = self::_getAttribute($detail, 'val', 'string'); +// echo $detailKey, ' => ',self::getAttribute($detail, 'val', 'string'),PHP_EOL; + $layout[$detailKey] = self::getAttribute($detail, 'val', 'string'); } return new PHPExcel_Chart_Layout($layout); - } // function _chartLayoutDetails() + } - private static function _chartDataSeries($chartDetail, $namespacesChartMeta, $plotType) + private static function chartDataSeries($chartDetail, $namespacesChartMeta, $plotType) { $multiSeriesType = null; $smoothLine = false; @@ -255,76 +255,78 @@ private static function _chartDataSeries($chartDetail, $namespacesChartMeta, $pl foreach ($seriesDetailSet as $seriesDetailKey => $seriesDetails) { switch ($seriesDetailKey) { case "grouping": - $multiSeriesType = self::_getAttribute($chartDetail->grouping, 'val', 'string'); + $multiSeriesType = self::getAttribute($chartDetail->grouping, 'val', 'string'); break; case "ser": $marker = null; foreach ($seriesDetails as $seriesKey => $seriesDetail) { switch ($seriesKey) { case "idx": - $seriesIndex = self::_getAttribute($seriesDetail, 'val', 'integer'); + $seriesIndex = self::getAttribute($seriesDetail, 'val', 'integer'); break; case "order": - $seriesOrder = self::_getAttribute($seriesDetail, 'val', 'integer'); + $seriesOrder = self::getAttribute($seriesDetail, 'val', 'integer'); $plotOrder[$seriesIndex] = $seriesOrder; break; case "tx": - $seriesLabel[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta); + $seriesLabel[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta); break; case "marker": - $marker = self::_getAttribute($seriesDetail->symbol, 'val', 'string'); + $marker = self::getAttribute($seriesDetail->symbol, 'val', 'string'); break; case "smooth": - $smoothLine = self::_getAttribute($seriesDetail, 'val', 'boolean'); + $smoothLine = self::getAttribute($seriesDetail, 'val', 'boolean'); break; case "cat": - $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta); + $seriesCategory[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta); break; case "val": - $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); + $seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); break; case "xVal": - $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); + $seriesCategory[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); break; case "yVal": - $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); + $seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); break; } } } } return new PHPExcel_Chart_DataSeries($plotType, $multiSeriesType, $plotOrder, $seriesLabel, $seriesCategory, $seriesValues, $smoothLine); - } // function _chartDataSeries() + } - private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null, $smoothLine = false) + + private static function chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null, $smoothLine = false) { if (isset($seriesDetail->strRef)) { $seriesSource = (string) $seriesDetail->strRef->f; - $seriesData = self::_chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']), 's'); + $seriesData = self::chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']), 's'); return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } elseif (isset($seriesDetail->numRef)) { $seriesSource = (string) $seriesDetail->numRef->f; - $seriesData = self::_chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c'])); + $seriesData = self::chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c'])); return new PHPExcel_Chart_DataSeriesValues('Number', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } elseif (isset($seriesDetail->multiLvlStrRef)) { $seriesSource = (string) $seriesDetail->multiLvlStrRef->f; - $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']), 's'); + $seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']), 's'); $seriesData['pointCount'] = count($seriesData['dataValues']); return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } elseif (isset($seriesDetail->multiLvlNumRef)) { $seriesSource = (string) $seriesDetail->multiLvlNumRef->f; - $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']), 's'); + $seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']), 's'); $seriesData['pointCount'] = count($seriesData['dataValues']); return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); } return null; - } // function _chartDataSeriesValueSet() + } + - private static function _chartDataSeriesValues($seriesValueSet, $dataType = 'n') + private static function chartDataSeriesValues($seriesValueSet, $dataType = 'n') { $seriesVal = array(); $formatCode = ''; @@ -333,13 +335,13 @@ private static function _chartDataSeriesValues($seriesValueSet, $dataType = 'n') foreach ($seriesValueSet as $seriesValueIdx => $seriesValue) { switch ($seriesValueIdx) { case 'ptCount': - $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); + $pointCount = self::getAttribute($seriesValue, 'val', 'integer'); break; case 'formatCode': $formatCode = (string) $seriesValue; break; case 'pt': - $pointVal = self::_getAttribute($seriesValue, 'idx', 'integer'); + $pointVal = self::getAttribute($seriesValue, 'idx', 'integer'); if ($dataType == 's') { $seriesVal[$pointVal] = (string) $seriesValue->v; } else { @@ -358,9 +360,9 @@ private static function _chartDataSeriesValues($seriesValueSet, $dataType = 'n') 'pointCount' => $pointCount, 'dataValues' => $seriesVal ); - } // function _chartDataSeriesValues() + } - private static function _chartDataSeriesValuesMultiLevel($seriesValueSet, $dataType = 'n') + private static function chartDataSeriesValuesMultiLevel($seriesValueSet, $dataType = 'n') { $seriesVal = array(); $formatCode = ''; @@ -370,13 +372,13 @@ private static function _chartDataSeriesValuesMultiLevel($seriesValueSet, $dataT foreach ($seriesLevel as $seriesValueIdx => $seriesValue) { switch ($seriesValueIdx) { case 'ptCount': - $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); + $pointCount = self::getAttribute($seriesValue, 'val', 'integer'); break; case 'formatCode': $formatCode = (string) $seriesValue; break; case 'pt': - $pointVal = self::_getAttribute($seriesValue, 'idx', 'integer'); + $pointVal = self::getAttribute($seriesValue, 'idx', 'integer'); if ($dataType == 's') { $seriesVal[$pointVal][] = (string) $seriesValue->v; } else { @@ -392,9 +394,9 @@ private static function _chartDataSeriesValuesMultiLevel($seriesValueSet, $dataT 'pointCount' => $pointCount, 'dataValues' => $seriesVal ); - } // function _chartDataSeriesValuesMultiLevel() + } - private static function _parseRichText($titleDetailPart = null) + private static function parseRichText($titleDetailPart = null) { $value = new PHPExcel_RichText(); @@ -407,27 +409,27 @@ private static function _parseRichText($titleDetailPart = null) $objText->getFont()->setName((string) $titleDetailElement->rPr->rFont["val"]); } - $fontSize = (self::_getAttribute($titleDetailElement->rPr, 'sz', 'integer')); + $fontSize = (self::getAttribute($titleDetailElement->rPr, 'sz', 'integer')); if (!is_null($fontSize)) { $objText->getFont()->setSize(floor($fontSize / 100)); } - $fontColor = (self::_getAttribute($titleDetailElement->rPr, 'color', 'string')); + $fontColor = (self::getAttribute($titleDetailElement->rPr, 'color', 'string')); if (!is_null($fontColor)) { - $objText->getFont()->setColor(new PHPExcel_Style_Color(self::_readColor($fontColor))); + $objText->getFont()->setColor(new PHPExcel_Style_Color(self::readColor($fontColor))); } - $bold = self::_getAttribute($titleDetailElement->rPr, 'b', 'boolean'); + $bold = self::getAttribute($titleDetailElement->rPr, 'b', 'boolean'); if (!is_null($bold)) { $objText->getFont()->setBold($bold); } - $italic = self::_getAttribute($titleDetailElement->rPr, 'i', 'boolean'); + $italic = self::getAttribute($titleDetailElement->rPr, 'i', 'boolean'); if (!is_null($italic)) { $objText->getFont()->setItalic($italic); } - $baseline = self::_getAttribute($titleDetailElement->rPr, 'baseline', 'integer'); + $baseline = self::getAttribute($titleDetailElement->rPr, 'baseline', 'integer'); if (!is_null($baseline)) { if ($baseline > 0) { $objText->getFont()->setSuperScript(true); @@ -436,7 +438,7 @@ private static function _parseRichText($titleDetailPart = null) } } - $underscore = (self::_getAttribute($titleDetailElement->rPr, 'u', 'string')); + $underscore = (self::getAttribute($titleDetailElement->rPr, 'u', 'string')); if (!is_null($underscore)) { if ($underscore == 'sng') { $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); @@ -447,7 +449,7 @@ private static function _parseRichText($titleDetailPart = null) } } - $strikethrough = (self::_getAttribute($titleDetailElement->rPr, 's', 'string')); + $strikethrough = (self::getAttribute($titleDetailElement->rPr, 's', 'string')); if (!is_null($strikethrough)) { if ($strikethrough == 'noStrike') { $objText->getFont()->setStrikethrough(false); @@ -461,37 +463,37 @@ private static function _parseRichText($titleDetailPart = null) return $value; } - private static function _readChartAttributes($chartDetail) + private static function readChartAttributes($chartDetail) { $plotAttributes = array(); if (isset($chartDetail->dLbls)) { if (isset($chartDetail->dLbls->howLegendKey)) { - $plotAttributes['showLegendKey'] = self::_getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string'); + $plotAttributes['showLegendKey'] = self::getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string'); } if (isset($chartDetail->dLbls->showVal)) { - $plotAttributes['showVal'] = self::_getAttribute($chartDetail->dLbls->showVal, 'val', 'string'); + $plotAttributes['showVal'] = self::getAttribute($chartDetail->dLbls->showVal, 'val', 'string'); } if (isset($chartDetail->dLbls->showCatName)) { - $plotAttributes['showCatName'] = self::_getAttribute($chartDetail->dLbls->showCatName, 'val', 'string'); + $plotAttributes['showCatName'] = self::getAttribute($chartDetail->dLbls->showCatName, 'val', 'string'); } if (isset($chartDetail->dLbls->showSerName)) { - $plotAttributes['showSerName'] = self::_getAttribute($chartDetail->dLbls->showSerName, 'val', 'string'); + $plotAttributes['showSerName'] = self::getAttribute($chartDetail->dLbls->showSerName, 'val', 'string'); } if (isset($chartDetail->dLbls->showPercent)) { - $plotAttributes['showPercent'] = self::_getAttribute($chartDetail->dLbls->showPercent, 'val', 'string'); + $plotAttributes['showPercent'] = self::getAttribute($chartDetail->dLbls->showPercent, 'val', 'string'); } if (isset($chartDetail->dLbls->showBubbleSize)) { - $plotAttributes['showBubbleSize'] = self::_getAttribute($chartDetail->dLbls->showBubbleSize, 'val', 'string'); + $plotAttributes['showBubbleSize'] = self::getAttribute($chartDetail->dLbls->showBubbleSize, 'val', 'string'); } if (isset($chartDetail->dLbls->showLeaderLines)) { - $plotAttributes['showLeaderLines'] = self::_getAttribute($chartDetail->dLbls->showLeaderLines, 'val', 'string'); + $plotAttributes['showLeaderLines'] = self::getAttribute($chartDetail->dLbls->showLeaderLines, 'val', 'string'); } } return $plotAttributes; } - private static function _setChartAttributes($plotArea, $plotAttributes) + private static function setChartAttributes($plotArea, $plotAttributes) { foreach ($plotAttributes as $plotAttributeKey => $plotAttributeValue) { switch ($plotAttributeKey) { diff --git a/Classes/PHPExcel/Reader/Excel2007/Theme.php b/Classes/PHPExcel/Reader/Excel2007/Theme.php index d5879ad47..134f4b609 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Theme.php +++ b/Classes/PHPExcel/Reader/Excel2007/Theme.php @@ -40,21 +40,21 @@ class PHPExcel_Reader_Excel2007_Theme * * @var string */ - private $_themeName; + private $themeName; /** * Colour Scheme Name * * @var string */ - private $_colourSchemeName; + private $colourSchemeName; /** * Colour Map indexed by position * * @var array of string */ - private $_colourMapValues; + private $colourMapValues; /** @@ -62,7 +62,7 @@ class PHPExcel_Reader_Excel2007_Theme * * @var array of string */ - private $_colourMap; + private $colourMap; /** @@ -72,9 +72,9 @@ class PHPExcel_Reader_Excel2007_Theme public function __construct($themeName, $colourSchemeName, $colourMap) { // Initialise values - $this->_themeName = $themeName; - $this->_colourSchemeName = $colourSchemeName; - $this->_colourMap = $colourMap; + $this->themeName = $themeName; + $this->colourSchemeName = $colourSchemeName; + $this->colourMap = $colourMap; } /** @@ -84,7 +84,7 @@ public function __construct($themeName, $colourSchemeName, $colourMap) */ public function getThemeName() { - return $this->_themeName; + return $this->themeName; } /** @@ -94,7 +94,7 @@ public function getThemeName() */ public function getColourSchemeName() { - return $this->_colourSchemeName; + return $this->colourSchemeName; } /** @@ -104,8 +104,8 @@ public function getColourSchemeName() */ public function getColourByIndex($index = 0) { - if (isset($this->_colourMap[$index])) { - return $this->_colourMap[$index]; + if (isset($this->colourMap[$index])) { + return $this->colourMap[$index]; } return null; } diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 2f8a2f8ae..3728b6cc2 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -2192,9 +2192,9 @@ private function _readXf() $rotation = 0; if ($angle <= 90) { $rotation = $angle; - } else if ($angle <= 180) { + } elseif ($angle <= 180) { $rotation = 90 - $angle; - } else if ($angle == 255) { + } elseif ($angle == 255) { $rotation = -165; } $objStyle->getAlignment()->setTextRotation($rotation); @@ -4598,11 +4598,11 @@ private function _readHyperLink() if ($isUNC) { $hyperlinkType = 'UNC'; - } else if (!$isFileLinkOrUrl) { + } elseif (!$isFileLinkOrUrl) { $hyperlinkType = 'workbook'; - } else if (ord($recordData{$offset}) == 0x03) { + } elseif (ord($recordData{$offset}) == 0x03) { $hyperlinkType = 'local'; - } else if (ord($recordData{$offset}) == 0xE0) { + } elseif (ord($recordData{$offset}) == 0xE0) { $hyperlinkType = 'URL'; } diff --git a/Classes/PHPExcel/Reader/Excel5/Escher.php b/Classes/PHPExcel/Reader/Excel5/Escher.php index f7f45dcdd..b4575e6ae 100644 --- a/Classes/PHPExcel/Reader/Excel5/Escher.php +++ b/Classes/PHPExcel/Reader/Excel5/Escher.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Reader_Excel5_Escher * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Reader_Excel5_Escher - * - * @category PHPExcel - * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_Excel5_Escher { const DGGCONTAINER = 0xF000; @@ -58,28 +51,28 @@ class PHPExcel_Reader_Excel5_Escher * * @var string */ - private $_data; + private $data; /** * Size in bytes of the Escher stream data * * @var int */ - private $_dataSize; + private $dataSize; /** * Current position of stream pointer in Escher stream data * * @var int */ - private $_pos; + private $pos; /** * The object to be returned by the reader. Modified during load. * * @var mixed */ - private $_object; + private $object; /** * Create a new PHPExcel_Reader_Excel5_Escher instance @@ -88,7 +81,7 @@ class PHPExcel_Reader_Excel5_Escher */ public function __construct($object) { - $this->_object = $object; + $this->object = $object; } /** @@ -98,117 +91,117 @@ public function __construct($object) */ public function load($data) { - $this->_data = $data; + $this->data = $data; // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); + $this->dataSize = strlen($this->data); - $this->_pos = 0; + $this->pos = 0; // Parse Escher stream - while ($this->_pos < $this->_dataSize) { + while ($this->pos < $this->dataSize) { // offset: 2; size: 2: Record Type - $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); + $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos + 2); switch ($fbt) { case self::DGGCONTAINER: - $this->_readDggContainer(); + $this->readDggContainer(); break; case self::DGG: - $this->_readDgg(); + $this->readDgg(); break; case self::BSTORECONTAINER: - $this->_readBstoreContainer(); + $this->readBstoreContainer(); break; case self::BSE: - $this->_readBSE(); + $this->readBSE(); break; case self::BLIPJPEG: - $this->_readBlipJPEG(); + $this->readBlipJPEG(); break; case self::BLIPPNG: - $this->_readBlipPNG(); + $this->readBlipPNG(); break; case self::OPT: - $this->_readOPT(); + $this->readOPT(); break; case self::TERTIARYOPT: - $this->_readTertiaryOPT(); + $this->readTertiaryOPT(); break; case self::SPLITMENUCOLORS: - $this->_readSplitMenuColors(); + $this->readSplitMenuColors(); break; case self::DGCONTAINER: - $this->_readDgContainer(); + $this->readDgContainer(); break; case self::DG: - $this->_readDg(); + $this->readDg(); break; case self::SPGRCONTAINER: - $this->_readSpgrContainer(); + $this->readSpgrContainer(); break; case self::SPCONTAINER: - $this->_readSpContainer(); + $this->readSpContainer(); break; case self::SPGR: - $this->_readSpgr(); + $this->readSpgr(); break; case self::SP: - $this->_readSp(); + $this->readSp(); break; case self::CLIENTTEXTBOX: - $this->_readClientTextbox(); + $this->readClientTextbox(); break; case self::CLIENTANCHOR: - $this->_readClientAnchor(); + $this->readClientAnchor(); break; case self::CLIENTDATA: - $this->_readClientData(); + $this->readClientData(); break; default: - $this->_readDefault(); + $this->readDefault(); break; } } - return $this->_object; + return $this->object; } /** * Read a generic record */ - private function _readDefault() + private function readDefault() { // offset 0; size: 2; recVer and recInstance - $verInstance = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos); + $verInstance = PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos); // offset: 2; size: 2: Record Type - $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); + $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos + 2); // bit: 0-3; mask: 0x000F; recVer $recVer = (0x000F & $verInstance) >> 0; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; } /** * Read DggContainer record (Drawing Group Container) */ - private function _readDggContainer() + private function readDggContainer() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; // record is a container, read contents $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); - $this->_object->setDggContainer($dggContainer); + $this->object->setDggContainer($dggContainer); $reader = new PHPExcel_Reader_Excel5_Escher($dggContainer); $reader->load($recordData); } @@ -216,29 +209,29 @@ private function _readDggContainer() /** * Read Dgg record (Drawing Group) */ - private function _readDgg() + private function readDgg() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; } /** * Read BstoreContainer record (Blip Store Container) */ - private function _readBstoreContainer() + private function readBstoreContainer() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; // record is a container, read contents $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); - $this->_object->setBstoreContainer($bstoreContainer); + $this->object->setBstoreContainer($bstoreContainer); $reader = new PHPExcel_Reader_Excel5_Escher($bstoreContainer); $reader->load($recordData); } @@ -246,22 +239,22 @@ private function _readBstoreContainer() /** * Read BSE record */ - private function _readBSE() + private function readBSE() { // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; // add BSE to BstoreContainer $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); - $this->_object->addBSE($BSE); + $this->object->addBSE($BSE); $BSE->setBLIPType($recInstance); @@ -312,18 +305,18 @@ private function _readBSE() /** * Read BlipJPEG record. Holds raw JPEG image data */ - private function _readBlipJPEG() + private function readBlipJPEG() { // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; $pos = 0; @@ -347,24 +340,24 @@ private function _readBlipJPEG() $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); $blip->setData($data); - $this->_object->setBlip($blip); + $this->object->setBlip($blip); } /** * Read BlipPNG record. Holds raw PNG image data */ - private function _readBlipPNG() + private function readBlipPNG() { // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; $pos = 0; @@ -388,71 +381,71 @@ private function _readBlipPNG() $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); $blip->setData($data); - $this->_object->setBlip($blip); + $this->object->setBlip($blip); } /** * Read OPT record. This record may occur within DggContainer record or SpContainer */ - private function _readOPT() + private function readOPT() { // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; - $this->_readOfficeArtRGFOPTE($recordData, $recInstance); + $this->readOfficeArtRGFOPTE($recordData, $recInstance); } /** * Read TertiaryOPT record */ - private function _readTertiaryOPT() + private function readTertiaryOPT() { // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; } /** * Read SplitMenuColors record */ - private function _readSplitMenuColors() + private function readSplitMenuColors() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; } /** * Read DgContainer record (Drawing Container) */ - private function _readDgContainer() + private function readDgContainer() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; // record is a container, read contents $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); - $this->_object->setDgContainer($dgContainer); + $this->object->setDgContainer($dgContainer); $reader = new PHPExcel_Reader_Excel5_Escher($dgContainer); $escher = $reader->load($recordData); } @@ -460,37 +453,37 @@ private function _readDgContainer() /** * Read Dg record (Drawing) */ - private function _readDg() + private function readDg() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; } /** * Read SpgrContainer record (Shape Group Container) */ - private function _readSpgrContainer() + private function readSpgrContainer() { // context is either context DgContainer or SpgrContainer - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; // record is a container, read contents $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); - if ($this->_object instanceof PHPExcel_Shared_Escher_DgContainer) { + if ($this->object instanceof PHPExcel_Shared_Escher_DgContainer) { // DgContainer - $this->_object->setSpgrContainer($spgrContainer); + $this->object->setSpgrContainer($spgrContainer); } else { // SpgrContainer - $this->_object->addChild($spgrContainer); + $this->object->addChild($spgrContainer); } $reader = new PHPExcel_Reader_Excel5_Escher($spgrContainer); @@ -500,17 +493,17 @@ private function _readSpgrContainer() /** * Read SpContainer record (Shape Container) */ - private function _readSpContainer() + private function readSpContainer() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // add spContainer to spgrContainer $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); - $this->_object->addChild($spContainer); + $this->object->addChild($spContainer); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; // record is a container, read contents $reader = new PHPExcel_Reader_Excel5_Escher($spContainer); @@ -520,59 +513,59 @@ private function _readSpContainer() /** * Read Spgr record (Shape Group) */ - private function _readSpgr() + private function readSpgr() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; } /** * Read Sp record (Shape) */ - private function _readSp() + private function readSp() { // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; } /** * Read ClientTextbox record */ - private function _readClientTextbox() + private function readClientTextbox() { // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; } /** * Read ClientAnchor record. This record holds information about where the shape is anchored in worksheet */ - private function _readClientAnchor() + private function readClientAnchor() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; // offset: 2; size: 2; upper-left corner column index (0-based) $c1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 2); @@ -599,34 +592,34 @@ private function _readClientAnchor() $endOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 16); // set the start coordinates - $this->_object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1)); + $this->object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1)); // set the start offsetX - $this->_object->setStartOffsetX($startOffsetX); + $this->object->setStartOffsetX($startOffsetX); // set the start offsetY - $this->_object->setStartOffsetY($startOffsetY); + $this->object->setStartOffsetY($startOffsetY); // set the end coordinates - $this->_object->setEndCoordinates(PHPExcel_Cell::stringFromColumnIndex($c2) . ($r2 + 1)); + $this->object->setEndCoordinates(PHPExcel_Cell::stringFromColumnIndex($c2) . ($r2 + 1)); // set the end offsetX - $this->_object->setEndOffsetX($endOffsetX); + $this->object->setEndOffsetX($endOffsetX); // set the end offsetY - $this->_object->setEndOffsetY($endOffsetY); + $this->object->setEndOffsetY($endOffsetY); } /** * Read ClientData record */ - private function _readClientData() + private function readClientData() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); - $recordData = substr($this->_data, $this->_pos + 8, $length); + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record - $this->_pos += 8 + $length; + $this->pos += 8 + $length; } /** @@ -635,7 +628,7 @@ private function _readClientData() * @param string $data Binary data * @param int $n Number of properties */ - private function _readOfficeArtRGFOPTE($data, $n) + private function readOfficeArtRGFOPTE($data, $n) { $splicedComplexData = substr($data, 6 * $n); @@ -670,7 +663,7 @@ private function _readOfficeArtRGFOPTE($data, $n) $value = $op; } - $this->_object->setOPT($opidOpid, $value); + $this->object->setOPT($opidOpid, $value); } } } diff --git a/Classes/PHPExcel/Reader/Excel5/MD5.php b/Classes/PHPExcel/Reader/Excel5/MD5.php index 3570c52ee..1141d43a1 100644 --- a/Classes/PHPExcel/Reader/Excel5/MD5.php +++ b/Classes/PHPExcel/Reader/Excel5/MD5.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Reader_Excel5_MD5 * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Reader_Excel5_MD5 - * - * @category PHPExcel - * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_Excel5_MD5 { // Context diff --git a/Classes/PHPExcel/Reader/Excel5/RC4.php b/Classes/PHPExcel/Reader/Excel5/RC4.php index 7a2eedc4f..5640539cb 100644 --- a/Classes/PHPExcel/Reader/Excel5/RC4.php +++ b/Classes/PHPExcel/Reader/Excel5/RC4.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Reader_Excel5_RC4 * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Reader_Excel5_RC4 - * - * @category PHPExcel - * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_Excel5_RC4 { // Context diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index 2a187b3ba..e5bf84bbd 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -1,6 +1,16 @@ <?php + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + /** - * PHPExcel + * PHPExcel_Reader_Gnumeric * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,24 +34,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** PHPExcel root directory */ -if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); -} - -/** - * PHPExcel_Reader_Gnumeric - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { /** @@ -49,16 +41,16 @@ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPEx * * @var array */ - private $_styles = array(); + private $styles = array(); /** * Shared Expressions * * @var array */ - private $_expressions = array(); + private $expressions = array(); - private $_referenceHelper = null; + private $referenceHelper = null; /** * Create a new PHPExcel_Reader_Gnumeric @@ -66,7 +58,7 @@ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPEx public function __construct() { $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); - $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $this->referenceHelper = PHPExcel_ReferenceHelper::getInstance(); } /** @@ -425,16 +417,16 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $type = PHPExcel_Cell_DataType::TYPE_FORMULA; if ($ExprID > '') { if (((string) $cell) > '') { - $this->_expressions[$ExprID] = array( + $this->expressions[$ExprID] = array( 'column' => $cellAttributes->Col, 'row' => $cellAttributes->Row, 'formula' => (string) $cell ); // echo 'NEW EXPRESSION ', $ExprID,'<br />'; } else { - $expression = $this->_expressions[$ExprID]; + $expression = $this->expressions[$ExprID]; - $cell = $this->_referenceHelper->updateFormulaReferences($expression['formula'], 'A1', $cellAttributes->Col - $expression['column'], $cellAttributes->Row - $expression['row'], $worksheetName); + $cell = $this->referenceHelper->updateFormulaReferences($expression['formula'], 'A1', $cellAttributes->Col - $expression['column'], $cellAttributes->Row - $expression['row'], $worksheetName); // echo 'SHARED EXPRESSION ', $ExprID,'<br />'; // echo 'New Value is ', $cell,'<br />'; } diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index ea6d08050..66b7afe8d 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -1,6 +1,16 @@ <?php + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + /** - * PHPExcel + * PHPExcel_Reader_OOCalc * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,24 +34,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** PHPExcel root directory */ -if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); -} - -/** - * PHPExcel_Reader_OOCalc - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { /** @@ -49,7 +41,7 @@ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExce * * @var array */ - private $_styles = array(); + private $styles = array(); /** * Create a new PHPExcel_Reader_OOCalc @@ -520,7 +512,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } $text = implode("\n", $textArray); // echo $text, '<br />'; - $objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setText($this->_parseRichText($text)); + $objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setText($this->parseRichText($text)); // ->setAuthor( $author ) } @@ -693,7 +685,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) return $objPHPExcel; } - private function _parseRichText($is = '') + private function parseRichText($is = '') { $value = new PHPExcel_RichText(); diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index 2fc4967f8..a7f3f1729 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -49,28 +49,28 @@ class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_ * * @var string */ - private $_inputEncoding = 'ANSI'; + private $inputEncoding = 'ANSI'; /** * Sheet index to read * * @var int */ - private $_sheetIndex = 0; + private $sheetIndex = 0; /** * Formats * * @var array */ - private $_formats = array(); + private $formats = array(); /** * Format Count * * @var int */ - private $_format = 0; + private $format = 0; /** * Create a new PHPExcel_Reader_SYLK @@ -112,7 +112,7 @@ protected function _isValidFormat() */ public function setInputEncoding($pValue = 'ANSI') { - $this->_inputEncoding = $pValue; + $this->inputEncoding = $pValue; return $this; } @@ -123,7 +123,7 @@ public function setInputEncoding($pValue = 'ANSI') */ public function getInputEncoding() { - return $this->_inputEncoding; + return $this->inputEncoding; } /** @@ -231,10 +231,10 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) rewind($fileHandle); // Create new PHPExcel - while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + while ($objPHPExcel->getSheetCount() <= $this->sheetIndex) { $objPHPExcel->createSheet(); } - $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); + $objPHPExcel->setActiveSheetIndex($this->sheetIndex); $fromFormats = array('\-', '\ '); $toFormats = array('-', ' '); @@ -295,7 +295,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) break; } } - $this->_formats['P'.$this->_format++] = $formatArray; + $this->formats['P'.$this->format++] = $formatArray; // Read cell value data } elseif ($dataType == 'C') { $hasCalculatedValue = false; @@ -361,12 +361,12 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); - $cellData = PHPExcel_Calculation::_unwrapResult($cellData); + $cellData = PHPExcel_Calculation::unwrapResult($cellData); // Set cell value $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setValue(($hasCalculatedValue) ? $cellDataFormula : $cellData); if ($hasCalculatedValue) { - $cellData = PHPExcel_Calculation::_unwrapResult($cellData); + $cellData = PHPExcel_Calculation::unwrapResult($cellData); $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setCalculatedValue($cellData); } // Read cell formatting @@ -418,8 +418,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } if (($formatStyle > '') && ($column > '') && ($row > '')) { $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); - if (isset($this->_formats[$formatStyle])) { - $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($this->_formats[$formatStyle]); + if (isset($this->formats[$formatStyle])) { + $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($this->formats[$formatStyle]); } } if ((!empty($styleData)) && ($column > '') && ($row > '')) { @@ -469,7 +469,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) */ public function getSheetIndex() { - return $this->_sheetIndex; + return $this->sheetIndex; } /** @@ -480,7 +480,7 @@ public function getSheetIndex() */ public function setSheetIndex($pValue = 0) { - $this->_sheetIndex = $pValue; + $this->sheetIndex = $pValue; return $this; } } diff --git a/Classes/PHPExcel/ReferenceHelper.php b/Classes/PHPExcel/ReferenceHelper.php index 2964131a3..7d7de93be 100644 --- a/Classes/PHPExcel/ReferenceHelper.php +++ b/Classes/PHPExcel/ReferenceHelper.php @@ -39,7 +39,7 @@ class PHPExcel_ReferenceHelper * * @var PHPExcel_ReferenceHelper */ - private static $_instance; + private static $instance; /** * Get an instance of this class @@ -48,11 +48,11 @@ class PHPExcel_ReferenceHelper */ public static function getInstance() { - if (!isset(self::$_instance) || (self::$_instance === null)) { - self::$_instance = new PHPExcel_ReferenceHelper(); + if (!isset(self::$instance) || (self::$instance === null)) { + self::$instance = new PHPExcel_ReferenceHelper(); } - return self::$_instance; + return self::$instance; } /** @@ -163,7 +163,7 @@ private static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNum * @param integer $beforeRow Number of the row we're inserting/deleting before * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) */ - protected function _adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + protected function adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aBreaks = $pSheet->getBreaks(); ($pNumCols > 0 || $pNumRows > 0) ? @@ -197,7 +197,7 @@ protected function _adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $befo * @param integer $beforeRow Number of the row we're inserting/deleting before * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) */ - protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + protected function adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aComments = $pSheet->getComments(); $aNewComments = array(); // the new array of all comments @@ -224,7 +224,7 @@ protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumC * @param integer $beforeRow Number of the row we're inserting/deleting before * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) */ - protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + protected function adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); ($pNumCols > 0 || $pNumRows > 0) ? uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); @@ -248,7 +248,7 @@ protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNu * @param integer $beforeRow Number of the row we're inserting/deleting before * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) */ - protected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + protected function adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aDataValidationCollection = $pSheet->getDataValidationCollection(); ($pNumCols > 0 || $pNumRows > 0) ? uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); @@ -272,7 +272,7 @@ protected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, * @param integer $beforeRow Number of the row we're inserting/deleting before * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) */ - protected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + protected function adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aMergeCells = $pSheet->getMergeCells(); $aNewMergeCells = array(); // the new array of all merge cells @@ -293,7 +293,7 @@ protected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNu * @param integer $beforeRow Number of the row we're inserting/deleting before * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) */ - protected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + protected function adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aProtectedCells = $pSheet->getProtectedCells(); ($pNumCols > 0 || $pNumRows > 0) ? @@ -318,7 +318,7 @@ protected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, * @param integer $beforeRow Number of the row we're inserting/deleting before * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) */ - protected function _adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + protected function adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aColumnDimensions = array_reverse($pSheet->getColumnDimensions(), true); if (!empty($aColumnDimensions)) { @@ -343,7 +343,7 @@ protected function _adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex * @param integer $beforeRow Number of the row we're inserting/deleting before * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) */ - protected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + protected function adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) { $aRowDimensions = array_reverse($pSheet->getRowDimensions(), true); if (!empty($aRowDimensions)) { @@ -513,28 +513,28 @@ public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, P } // Update worksheet: column dimensions - $this->_adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + $this->adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: row dimensions - $this->_adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + $this->adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: page breaks - $this->_adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + $this->adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: comments - $this->_adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + $this->adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: hyperlinks - $this->_adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + $this->adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: data validations - $this->_adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + $this->adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: merge cells - $this->_adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + $this->adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: protected cells - $this->_adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + $this->adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); // Update worksheet: autofilter $autoFilter = $pSheet->getAutoFilter(); @@ -785,10 +785,10 @@ public function updateCellReference($pCellRange = 'A1', $pBefore = 'A1', $pNumCo // Is it a range or a single cell? } elseif (strpos($pCellRange, ':') === false && strpos($pCellRange, ',') === false) { // Single cell - return $this->_updateSingleCellReference($pCellRange, $pBefore, $pNumCols, $pNumRows); + return $this->updateSingleCellReference($pCellRange, $pBefore, $pNumCols, $pNumRows); } elseif (strpos($pCellRange, ':') !== false || strpos($pCellRange, ',') !== false) { // Range - return $this->_updateCellRange($pCellRange, $pBefore, $pNumCols, $pNumRows); + return $this->updateCellRange($pCellRange, $pBefore, $pNumCols, $pNumRows); } else { // Return original return $pCellRange; @@ -833,7 +833,7 @@ public function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName * @return string Updated cell range * @throws PHPExcel_Exception */ - private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) + private function updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { if (strpos($pCellRange, ':') !== false || strpos($pCellRange, ',') !== false) { // Update range @@ -843,13 +843,13 @@ private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumC $jc = count($range[$i]); for ($j = 0; $j < $jc; ++$j) { if (ctype_alpha($range[$i][$j])) { - $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference($range[$i][$j].'1', $pBefore, $pNumCols, $pNumRows)); + $r = PHPExcel_Cell::coordinateFromString($this->updateSingleCellReference($range[$i][$j].'1', $pBefore, $pNumCols, $pNumRows)); $range[$i][$j] = $r[0]; } elseif (ctype_digit($range[$i][$j])) { - $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference('A'.$range[$i][$j], $pBefore, $pNumCols, $pNumRows)); + $r = PHPExcel_Cell::coordinateFromString($this->updateSingleCellReference('A'.$range[$i][$j], $pBefore, $pNumCols, $pNumRows)); $range[$i][$j] = $r[1]; } else { - $range[$i][$j] = $this->_updateSingleCellReference($range[$i][$j], $pBefore, $pNumCols, $pNumRows); + $range[$i][$j] = $this->updateSingleCellReference($range[$i][$j], $pBefore, $pNumCols, $pNumRows); } } } @@ -871,7 +871,7 @@ private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumC * @return string Updated cell reference * @throws PHPExcel_Exception */ - private function _updateSingleCellReference($pCellReference = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) + private function updateSingleCellReference($pCellReference = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { if (strpos($pCellReference, ':') === false && strpos($pCellReference, ',') === false) { // Get coordinates of $pBefore diff --git a/Classes/PHPExcel/Shared/Escher.php b/Classes/PHPExcel/Shared/Escher.php index 948d409b6..1aedb9d2a 100644 --- a/Classes/PHPExcel/Shared/Escher.php +++ b/Classes/PHPExcel/Shared/Escher.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_Escher * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Shared_Escher - * - * @category PHPExcel - * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_Escher { /** @@ -39,14 +32,14 @@ class PHPExcel_Shared_Escher * * @var PHPExcel_Shared_Escher_DggContainer */ - private $_dggContainer; + private $dggContainer; /** * Drawing Container * * @var PHPExcel_Shared_Escher_DgContainer */ - private $_dgContainer; + private $dgContainer; /** * Get Drawing Group Container @@ -55,7 +48,7 @@ class PHPExcel_Shared_Escher */ public function getDggContainer() { - return $this->_dggContainer; + return $this->dggContainer; } /** @@ -65,7 +58,7 @@ public function getDggContainer() */ public function setDggContainer($dggContainer) { - return $this->_dggContainer = $dggContainer; + return $this->dggContainer = $dggContainer; } /** @@ -75,7 +68,7 @@ public function setDggContainer($dggContainer) */ public function getDgContainer() { - return $this->_dgContainer; + return $this->dgContainer; } /** @@ -85,6 +78,6 @@ public function getDgContainer() */ public function setDgContainer($dgContainer) { - return $this->_dgContainer = $dgContainer; + return $this->dgContainer = $dgContainer; } } diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer.php index e4d17bc1b..739cd9024 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_Escher_DgContainer * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Shared_Escher_DgContainer - * - * @category PHPExcel - * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_Escher_DgContainer { /** @@ -39,44 +32,44 @@ class PHPExcel_Shared_Escher_DgContainer * * @var int */ - private $_dgId; + private $dgId; /** * Last shape index in this drawing * * @var int */ - private $_lastSpId; + private $lastSpId; - private $_spgrContainer = null; + private $spgrContainer = null; public function getDgId() { - return $this->_dgId; + return $this->dgId; } public function setDgId($value) { - $this->_dgId = $value; + $this->dgId = $value; } public function getLastSpId() { - return $this->_lastSpId; + return $this->lastSpId; } public function setLastSpId($value) { - $this->_lastSpId = $value; + $this->lastSpId = $value; } public function getSpgrContainer() { - return $this->_spgrContainer; + return $this->spgrContainer; } public function setSpgrContainer($spgrContainer) { - return $this->_spgrContainer = $spgrContainer; + return $this->spgrContainer = $spgrContainer; } } diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php index efa1683f3..49e7d6856 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_Escher_DgContainer_SpgrContainer * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Shared_Escher_DgContainer_SpgrContainer - * - * @category PHPExcel - * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer { /** @@ -39,14 +32,14 @@ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer * * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer */ - private $_parent; + private $parent; /** * Shape Container collection * * @var array */ - private $_children = array(); + private $children = array(); /** * Set parent Shape Group Container @@ -55,7 +48,7 @@ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer */ public function setParent($parent) { - $this->_parent = $parent; + $this->parent = $parent; } /** @@ -65,7 +58,7 @@ public function setParent($parent) */ public function getParent() { - return $this->_parent; + return $this->parent; } /** @@ -75,7 +68,7 @@ public function getParent() */ public function addChild($child) { - $this->_children[] = $child; + $this->children[] = $child; $child->setParent($this); } @@ -84,7 +77,7 @@ public function addChild($child) */ public function getChildren() { - return $this->_children; + return $this->children; } /** @@ -96,7 +89,7 @@ public function getAllSpContainers() { $allSpContainers = array(); - foreach ($this->_children as $child) { + foreach ($this->children as $child) { if ($child instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) { $allSpContainers = array_merge($allSpContainers, $child->getAllSpContainers()); } else { diff --git a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php index 97136ee05..a1f1a4609 100644 --- a/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer - * - * @category PHPExcel - * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer { /** @@ -39,84 +32,84 @@ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer * * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer */ - private $_parent; + private $parent; /** * Is this a group shape? * * @var boolean */ - private $_spgr = false; + private $spgr = false; /** * Shape type * * @var int */ - private $_spType; + private $spType; /** * Shape flag * * @var int */ - private $_spFlag; + private $spFlag; /** * Shape index (usually group shape has index 0, and the rest: 1,2,3...) * * @var boolean */ - private $_spId; + private $spId; /** * Array of options * * @var array */ - private $_OPT; + private $OPT; /** * Cell coordinates of upper-left corner of shape, e.g. 'A1' * * @var string */ - private $_startCoordinates; + private $startCoordinates; /** * Horizontal offset of upper-left corner of shape measured in 1/1024 of column width * * @var int */ - private $_startOffsetX; + private $startOffsetX; /** * Vertical offset of upper-left corner of shape measured in 1/256 of row height * * @var int */ - private $_startOffsetY; + private $startOffsetY; /** * Cell coordinates of bottom-right corner of shape, e.g. 'B2' * * @var string */ - private $_endCoordinates; + private $endCoordinates; /** * Horizontal offset of bottom-right corner of shape measured in 1/1024 of column width * * @var int */ - private $_endOffsetX; + private $endOffsetX; /** * Vertical offset of bottom-right corner of shape measured in 1/256 of row height * * @var int */ - private $_endOffsetY; + private $endOffsetY; /** * Set parent Shape Group Container @@ -125,7 +118,7 @@ class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer */ public function setParent($parent) { - $this->_parent = $parent; + $this->parent = $parent; } /** @@ -135,7 +128,7 @@ public function setParent($parent) */ public function getParent() { - return $this->_parent; + return $this->parent; } /** @@ -145,7 +138,7 @@ public function getParent() */ public function setSpgr($value = false) { - $this->_spgr = $value; + $this->spgr = $value; } /** @@ -155,7 +148,7 @@ public function setSpgr($value = false) */ public function getSpgr() { - return $this->_spgr; + return $this->spgr; } /** @@ -165,7 +158,7 @@ public function getSpgr() */ public function setSpType($value) { - $this->_spType = $value; + $this->spType = $value; } /** @@ -175,7 +168,7 @@ public function setSpType($value) */ public function getSpType() { - return $this->_spType; + return $this->spType; } /** @@ -185,7 +178,7 @@ public function getSpType() */ public function setSpFlag($value) { - $this->_spFlag = $value; + $this->spFlag = $value; } /** @@ -195,7 +188,7 @@ public function setSpFlag($value) */ public function getSpFlag() { - return $this->_spFlag; + return $this->spFlag; } /** @@ -205,7 +198,7 @@ public function getSpFlag() */ public function setSpId($value) { - $this->_spId = $value; + $this->spId = $value; } /** @@ -215,7 +208,7 @@ public function setSpId($value) */ public function getSpId() { - return $this->_spId; + return $this->spId; } /** @@ -226,7 +219,7 @@ public function getSpId() */ public function setOPT($property, $value) { - $this->_OPT[$property] = $value; + $this->OPT[$property] = $value; } /** @@ -237,8 +230,8 @@ public function setOPT($property, $value) */ public function getOPT($property) { - if (isset($this->_OPT[$property])) { - return $this->_OPT[$property]; + if (isset($this->OPT[$property])) { + return $this->OPT[$property]; } return null; } @@ -250,7 +243,7 @@ public function getOPT($property) */ public function getOPTCollection() { - return $this->_OPT; + return $this->OPT; } /** @@ -260,7 +253,7 @@ public function getOPTCollection() */ public function setStartCoordinates($value = 'A1') { - $this->_startCoordinates = $value; + $this->startCoordinates = $value; } /** @@ -270,7 +263,7 @@ public function setStartCoordinates($value = 'A1') */ public function getStartCoordinates() { - return $this->_startCoordinates; + return $this->startCoordinates; } /** @@ -280,7 +273,7 @@ public function getStartCoordinates() */ public function setStartOffsetX($startOffsetX = 0) { - $this->_startOffsetX = $startOffsetX; + $this->startOffsetX = $startOffsetX; } /** @@ -290,7 +283,7 @@ public function setStartOffsetX($startOffsetX = 0) */ public function getStartOffsetX() { - return $this->_startOffsetX; + return $this->startOffsetX; } /** @@ -300,7 +293,7 @@ public function getStartOffsetX() */ public function setStartOffsetY($startOffsetY = 0) { - $this->_startOffsetY = $startOffsetY; + $this->startOffsetY = $startOffsetY; } /** @@ -310,7 +303,7 @@ public function setStartOffsetY($startOffsetY = 0) */ public function getStartOffsetY() { - return $this->_startOffsetY; + return $this->startOffsetY; } /** @@ -320,7 +313,7 @@ public function getStartOffsetY() */ public function setEndCoordinates($value = 'A1') { - $this->_endCoordinates = $value; + $this->endCoordinates = $value; } /** @@ -330,7 +323,7 @@ public function setEndCoordinates($value = 'A1') */ public function getEndCoordinates() { - return $this->_endCoordinates; + return $this->endCoordinates; } /** @@ -340,7 +333,7 @@ public function getEndCoordinates() */ public function setEndOffsetX($endOffsetX = 0) { - $this->_endOffsetX = $endOffsetX; + $this->endOffsetX = $endOffsetX; } /** @@ -350,7 +343,7 @@ public function setEndOffsetX($endOffsetX = 0) */ public function getEndOffsetX() { - return $this->_endOffsetX; + return $this->endOffsetX; } /** @@ -360,7 +353,7 @@ public function getEndOffsetX() */ public function setEndOffsetY($endOffsetY = 0) { - $this->_endOffsetY = $endOffsetY; + $this->endOffsetY = $endOffsetY; } /** @@ -370,7 +363,7 @@ public function setEndOffsetY($endOffsetY = 0) */ public function getEndOffsetY() { - return $this->_endOffsetY; + return $this->endOffsetY; } /** diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer.php index dae6a5a42..b116b1bd4 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_Escher_DggContainer * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Shared_Escher_DggContainer - * - * @category PHPExcel - * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_Escher_DggContainer { /** @@ -39,42 +32,42 @@ class PHPExcel_Shared_Escher_DggContainer * * @var int */ - private $_spIdMax; + private $spIdMax; /** * Total number of drawings saved * * @var int */ - private $_cDgSaved; + private $cDgSaved; /** * Total number of shapes saved (including group shapes) * * @var int */ - private $_cSpSaved; + private $cSpSaved; /** * BLIP Store Container * * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer */ - private $_bstoreContainer; + private $bstoreContainer; /** * Array of options for the drawing group * * @var array */ - private $_OPT = array(); + private $OPT = array(); /** * Array of identifier clusters containg information about the maximum shape identifiers * * @var array */ - private $_IDCLs = array(); + private $IDCLs = array(); /** * Get maximum shape index of all shapes in all drawings (plus one) @@ -83,7 +76,7 @@ class PHPExcel_Shared_Escher_DggContainer */ public function getSpIdMax() { - return $this->_spIdMax; + return $this->spIdMax; } /** @@ -93,7 +86,7 @@ public function getSpIdMax() */ public function setSpIdMax($value) { - $this->_spIdMax = $value; + $this->spIdMax = $value; } /** @@ -103,7 +96,7 @@ public function setSpIdMax($value) */ public function getCDgSaved() { - return $this->_cDgSaved; + return $this->cDgSaved; } /** @@ -113,7 +106,7 @@ public function getCDgSaved() */ public function setCDgSaved($value) { - $this->_cDgSaved = $value; + $this->cDgSaved = $value; } /** @@ -123,7 +116,7 @@ public function setCDgSaved($value) */ public function getCSpSaved() { - return $this->_cSpSaved; + return $this->cSpSaved; } /** @@ -133,7 +126,7 @@ public function getCSpSaved() */ public function setCSpSaved($value) { - $this->_cSpSaved = $value; + $this->cSpSaved = $value; } /** @@ -143,7 +136,7 @@ public function setCSpSaved($value) */ public function getBstoreContainer() { - return $this->_bstoreContainer; + return $this->bstoreContainer; } /** @@ -153,7 +146,7 @@ public function getBstoreContainer() */ public function setBstoreContainer($bstoreContainer) { - $this->_bstoreContainer = $bstoreContainer; + $this->bstoreContainer = $bstoreContainer; } /** @@ -164,7 +157,7 @@ public function setBstoreContainer($bstoreContainer) */ public function setOPT($property, $value) { - $this->_OPT[$property] = $value; + $this->OPT[$property] = $value; } /** @@ -175,8 +168,8 @@ public function setOPT($property, $value) */ public function getOPT($property) { - if (isset($this->_OPT[$property])) { - return $this->_OPT[$property]; + if (isset($this->OPT[$property])) { + return $this->OPT[$property]; } return null; } @@ -188,7 +181,7 @@ public function getOPT($property) */ public function getIDCLs() { - return $this->_IDCLs; + return $this->IDCLs; } /** @@ -198,6 +191,6 @@ public function getIDCLs() */ public function setIDCLs($pValue) { - $this->_IDCLs = $pValue; + $this->IDCLs = $pValue; } } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php index 3f8f81da6..1af2432bd 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Shared_Escher_DggContainer_BstoreContainer - * - * @category PHPExcel - * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer { /** @@ -39,7 +32,7 @@ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer * * @var array */ - private $_BSECollection = array(); + private $BSECollection = array(); /** * Add a BLIP Store Entry @@ -48,7 +41,7 @@ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer */ public function addBSE($BSE) { - $this->_BSECollection[] = $BSE; + $this->BSECollection[] = $BSE; $BSE->setParent($this); } @@ -59,6 +52,6 @@ public function addBSE($BSE) */ public function getBSECollection() { - return $this->_BSECollection; + return $this->BSECollection; } } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php index 1b0fbe2ca..9f8afa5d6 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,26 +25,18 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE - * - * @category PHPExcel - * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE { const BLIPTYPE_ERROR = 0x00; - const BLIPTYPE_UNKNOWN = 0x01; - const BLIPTYPE_EMF = 0x02; - const BLIPTYPE_WMF = 0x03; - const BLIPTYPE_PICT = 0x04; - const BLIPTYPE_JPEG = 0x05; - const BLIPTYPE_PNG = 0x06; - const BLIPTYPE_DIB = 0x07; - const BLIPTYPE_TIFF = 0x11; - const BLIPTYPE_CMYKJPEG = 0x12; + const BLIPTYPE_UNKNOWN = 0x01; + const BLIPTYPE_EMF = 0x02; + const BLIPTYPE_WMF = 0x03; + const BLIPTYPE_PICT = 0x04; + const BLIPTYPE_JPEG = 0x05; + const BLIPTYPE_PNG = 0x06; + const BLIPTYPE_DIB = 0x07; + const BLIPTYPE_TIFF = 0x11; + const BLIPTYPE_CMYKJPEG = 0x12; /** * The parent BLIP Store Entry Container @@ -57,14 +50,14 @@ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE * * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip */ - private $_blip; + private $blip; /** * The BLIP type * * @var int */ - private $_blipType; + private $blipType; /** * Set parent BLIP Store Entry Container @@ -83,7 +76,7 @@ public function setParent($parent) */ public function getBlip() { - return $this->_blip; + return $this->blip; } /** @@ -93,7 +86,7 @@ public function getBlip() */ public function setBlip($blip) { - $this->_blip = $blip; + $this->blip = $blip; $blip->setParent($this); } @@ -104,7 +97,7 @@ public function setBlip($blip) */ public function getBlipType() { - return $this->_blipType; + return $this->blipType; } /** @@ -114,6 +107,6 @@ public function getBlipType() */ public function setBlipType($blipType) { - $this->_blipType = $blipType; + $this->blipType = $blipType; } } diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php index 172c03e21..3bcbbbe28 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip - * - * @category PHPExcel - * @package PHPExcel_Shared_Escher - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip { /** @@ -39,14 +32,14 @@ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip * * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE */ - private $_parent; + private $parent; /** * Raw image data * * @var string */ - private $_data; + private $data; /** * Get the raw image data @@ -55,7 +48,7 @@ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip */ public function getData() { - return $this->_data; + return $this->data; } /** @@ -65,7 +58,7 @@ public function getData() */ public function setData($data) { - $this->_data = $data; + $this->data = $data; } /** @@ -75,7 +68,7 @@ public function setData($data) */ public function setParent($parent) { - $this->_parent = $parent; + $this->parent = $parent; } /** @@ -85,6 +78,6 @@ public function setParent($parent) */ public function getParent() { - return $this->_parent; + return $this->parent; } } diff --git a/Classes/PHPExcel/Shared/Excel5.php b/Classes/PHPExcel/Shared/Excel5.php index 819092dd0..c3ff209fa 100644 --- a/Classes/PHPExcel/Shared/Excel5.php +++ b/Classes/PHPExcel/Shared/Excel5.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_Excel5 * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Shared_Excel5 - * - * @category PHPExcel - * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_Excel5 { /** @@ -56,7 +49,7 @@ public static function sizeCol($sheet, $col = 'A') $columnDimension = $columnDimensions[$col]; $width = $columnDimension->getWidth(); $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); - } else if ($sheet->getDefaultColumnDimension()->getWidth() != -1) { + } elseif ($sheet->getDefaultColumnDimension()->getWidth() != -1) { // then we have default column dimension with explicit width $defaultColumnDimension = $sheet->getDefaultColumnDimension(); $width = $defaultColumnDimension->getWidth(); @@ -98,7 +91,7 @@ public static function sizeRow($sheet, $row = 1) $rowDimension = $rowDimensions[$row]; $rowHeight = $rowDimension->getRowHeight(); $pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10 - } else if ($sheet->getDefaultRowDimension()->getRowHeight() != -1) { + } elseif ($sheet->getDefaultRowDimension()->getRowHeight() != -1) { // then we have a default row dimension with explicit height $defaultRowDimension = $sheet->getDefaultRowDimension(); $rowHeight = $defaultRowDimension->getRowHeight(); diff --git a/Classes/PHPExcel/Shared/Font.php b/Classes/PHPExcel/Shared/Font.php index 23d087e7e..7efb3c96b 100644 --- a/Classes/PHPExcel/Shared/Font.php +++ b/Classes/PHPExcel/Shared/Font.php @@ -39,7 +39,7 @@ class PHPExcel_Shared_Font const AUTOSIZE_METHOD_APPROX = 'approx'; const AUTOSIZE_METHOD_EXACT = 'exact'; - private static $_autoSizeMethods = array( + private static $autoSizeMethods = array( self::AUTOSIZE_METHOD_APPROX, self::AUTOSIZE_METHOD_EXACT, ); @@ -196,7 +196,7 @@ class PHPExcel_Shared_Font */ public static function setAutoSizeMethod($pValue = self::AUTOSIZE_METHOD_APPROX) { - if (!in_array($pValue, self::$_autoSizeMethods)) { + if (!in_array($pValue, self::$autoSizeMethods)) { return false; } self::$autoSizeMethod = $pValue; diff --git a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php index b8e42d233..d4ae3979f 100644 --- a/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php @@ -444,7 +444,7 @@ private function hqr2() --$n; $iter = 0; // Two roots found - } else if ($l == $n-1) { + } elseif ($l == $n-1) { $w = $this->H[$n][$n-1] * $this->H[$n-1][$n]; $p = ($this->H[$n-1][$n-1] - $this->H[$n][$n]) / 2.0; $q = $p * $p + $w; @@ -687,7 +687,7 @@ private function hqr2() } } // Complex vector - } else if ($q < 0) { + } elseif ($q < 0) { $l = $n-1; // Last vector component imaginary so matrix is triangular if (abs($this->H[$n][$n-1]) > abs($this->H[$n-1][$n])) { diff --git a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php index 3d6aeb49b..f57d122ce 100644 --- a/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php @@ -273,7 +273,7 @@ public function __construct($Arg) } if ($ks == $k) { $kase = 3; - } else if ($ks == $p-1) { + } elseif ($ks == $p-1) { $kase = 1; } else { $kase = 2; diff --git a/Classes/PHPExcel/Shared/OLE/PPS/Root.php b/Classes/PHPExcel/Shared/OLE/PPS/Root.php index a36c4f970..c62399baa 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/Root.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/Root.php @@ -72,7 +72,7 @@ public function save($filename) if (is_resource($filename)) { $this->_FILEH_ = $filename; - } else if ($filename == '-' || $filename == '') { + } elseif ($filename == '-' || $filename == '') { if ($this->_tmp_dir === null) { $this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir(); } diff --git a/Classes/PHPExcel/Shared/OLERead.php b/Classes/PHPExcel/Shared/OLERead.php index 54b0fadd8..48b24eed8 100644 --- a/Classes/PHPExcel/Shared/OLERead.php +++ b/Classes/PHPExcel/Shared/OLERead.php @@ -273,7 +273,7 @@ private function _readPropertySets() // Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook) if (($upName === 'WORKBOOK') || ($upName === 'BOOK')) { $this->wrkbook = count($this->props) - 1; - } else if ($upName === 'ROOT ENTRY' || $upName === 'R') { + } elseif ($upName === 'ROOT ENTRY' || $upName === 'R') { // Root entry $this->rootentry = count($this->props) - 1; } diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index 78bed21f8..8fa3db831 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -319,7 +319,7 @@ function create($p_filelist) // ----- Look for the optional second argument if ($v_size == 2) { $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; - } else if ($v_size > 2) { + } elseif ($v_size > 2) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); return 0; } @@ -345,7 +345,7 @@ function create($p_filelist) // ----- The list is a list of string names $v_string_list = $p_filelist; } - } else if (is_string($p_filelist)) { + } elseif (is_string($p_filelist)) { // ----- Look if the $p_filelist is a string // ----- Create a list from the string $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); @@ -487,7 +487,7 @@ function add($p_filelist) // ----- Look for the optional second argument if ($v_size == 2) { $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; - } else if ($v_size > 2) { + } elseif ($v_size > 2) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); @@ -516,7 +516,7 @@ function add($p_filelist) // ----- The list is a list of string names $v_string_list = $p_filelist; } - } else if (is_string($p_filelist)) { + } elseif (is_string($p_filelist)) { // ----- Look if the $p_filelist is a string // ----- Create a list from the string $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); @@ -748,7 +748,7 @@ function extract() // ----- Look for the optional second argument if ($v_size == 2) { $v_remove_path = $v_arg_list[1]; - } else if ($v_size > 2) { + } elseif ($v_size > 2) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); @@ -903,7 +903,7 @@ function extractByIndex($p_index) // ----- Look for the optional second argument if ($v_size == 2) { $v_remove_path = $v_arg_list[1]; - } else if ($v_size > 2) { + } elseif ($v_size > 2) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); @@ -1122,7 +1122,7 @@ function duplicate($p_archive) if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) { // ----- Duplicate the archive $v_result = $this->privDuplicate($p_archive->zipname); - } else if (is_string($p_archive)) { + } elseif (is_string($p_archive)) { // ----- Look if the $p_archive is a string (so a filename) // ----- Check that $p_archive is a valid zip file // TBC : Should also check the archive format @@ -1176,7 +1176,7 @@ function merge($p_archive_to_add) if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) { // ----- Merge the archive $v_result = $this->privMerge($p_archive_to_add); - } else if (is_string($p_archive_to_add)) { + } elseif (is_string($p_archive_to_add)) { // ----- Look if the $p_archive_to_add is a string (so a filename) // ----- Create a temporary archive $v_object_archive = new PclZip($p_archive_to_add); @@ -1466,7 +1466,7 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request // ----- Get the value if (is_string($p_options_list[$i+1])) { $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; - } else if (is_array($p_options_list[$i+1])) { + } elseif (is_array($p_options_list[$i+1])) { $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; } else { // ----- Error log @@ -1548,9 +1548,9 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request // ----- Parse items $v_work_list = explode(",", $p_options_list[$i+1]); - } else if (is_integer($p_options_list[$i+1])) { + } elseif (is_integer($p_options_list[$i+1])) { $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; - } else if (is_array($p_options_list[$i+1])) { + } elseif (is_array($p_options_list[$i+1])) { $v_work_list = $p_options_list[$i+1]; } else { // ----- Error log @@ -1895,16 +1895,16 @@ function privFileDescrExpand(&$p_filedescr_list, &$p_options) if (file_exists($v_descr['filename'])) { if (@is_file($v_descr['filename'])) { $v_descr['type'] = 'file'; - } else if (@is_dir($v_descr['filename'])) { + } elseif (@is_dir($v_descr['filename'])) { $v_descr['type'] = 'folder'; - } else if (@is_link($v_descr['filename'])) { + } elseif (@is_link($v_descr['filename'])) { // skip continue; } else { // skip continue; } - } else if (isset($v_descr['content'])) { + } elseif (isset($v_descr['content'])) { // ----- Look for string added as file $v_descr['type'] = 'virtual_file'; } else { @@ -2412,12 +2412,12 @@ function privAddFile($p_filedescr, &$p_header, &$p_options) if ($p_filedescr['type']=='file') { $p_header['external'] = 0x00000000; $p_header['size'] = filesize($p_filename); - } else if ($p_filedescr['type']=='folder') { + } elseif ($p_filedescr['type']=='folder') { // ----- Look for regular folder $p_header['external'] = 0x00000010; $p_header['mtime'] = filemtime($p_filename); $p_header['size'] = filesize($p_filename); - } else if ($p_filedescr['type'] == 'virtual_file') { + } elseif ($p_filedescr['type'] == 'virtual_file') { // ----- Look for virtual file $p_header['external'] = 0x00000000; $p_header['size'] = strlen($p_filedescr['content']); @@ -2426,7 +2426,7 @@ function privAddFile($p_filedescr, &$p_header, &$p_options) // ----- Look for filetime if (isset($p_filedescr['mtime'])) { $p_header['mtime'] = $p_filedescr['mtime']; - } else if ($p_filedescr['type'] == 'virtual_file') { + } elseif ($p_filedescr['type'] == 'virtual_file') { $p_header['mtime'] = time(); } else { $p_header['mtime'] = filemtime($p_filename); @@ -2526,7 +2526,7 @@ function privAddFile($p_filedescr, &$p_header, &$p_options) // ----- Write the compressed (or not) content @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); } - } else if ($p_filedescr['type'] == 'virtual_file') { + } elseif ($p_filedescr['type'] == 'virtual_file') { // ----- Look for a virtual file (a file from string) $v_content = $p_filedescr['content']; @@ -2556,7 +2556,7 @@ function privAddFile($p_filedescr, &$p_header, &$p_options) // ----- Write the compressed (or not) content @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); - } else if ($p_filedescr['type'] == 'folder') { + } elseif ($p_filedescr['type'] == 'folder') { // ----- Look for a directory // ----- Look for directory last '/' if (@substr($p_header['stored_filename'], -1) != '/') { @@ -2761,7 +2761,7 @@ function privCalculateStoredFilename(&$p_filedescr, &$p_options) // ----- Look for all path to remove if ($p_remove_all_dir) { $v_stored_filename = basename($p_filename); - } else if ($p_remove_dir != "") { + } elseif ($p_remove_dir != "") { // ----- Look for partial path remove if (substr($p_remove_dir, -1) != '/') { $p_remove_dir .= "/"; @@ -3136,12 +3136,12 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all $v_extract = true; } } - } else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + } elseif ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { // ----- Look for extract by preg rule if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { $v_extract = true; } - } else if ((isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + } elseif ((isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { // ----- Look for extract by index rule // ----- Look if the index is in the list for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { @@ -3341,7 +3341,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, // ----- Get the basename of the path $p_entry['filename'] = basename($p_entry['filename']); - } else if ($p_remove_path != "") { + } elseif ($p_remove_path != "") { // ----- Look for path to remove if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) { // ----- Change the file status @@ -3418,7 +3418,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, "Filename '".$p_entry['filename']."' is already used by an existing directory"); return PclZip::errorCode(); } - } else if (!is_writeable($p_entry['filename'])) { + } elseif (!is_writeable($p_entry['filename'])) { // ----- Look if file is write protected // ----- Change the file status $p_entry['status'] = "write_protected"; @@ -3430,7 +3430,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Filename '".$p_entry['filename']."' exists and is write protected"); return PclZip::errorCode(); } - } else if (filemtime($p_entry['filename']) > $p_entry['mtime']) { + } elseif (filemtime($p_entry['filename']) > $p_entry['mtime']) { // ----- Look if the extracted file is older // ----- Change the file status if ((isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) && ($p_options[PCLZIP_OPT_REPLACE_NEWER] === true)) { @@ -3451,7 +3451,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, // ----- Check the directory availability and create it if necessary if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) { $v_dir_to_check = $p_entry['filename']; - } else if (!strstr($p_entry['filename'], "/")) { + } elseif (!strstr($p_entry['filename'], "/")) { $v_dir_to_check = ""; } else { $v_dir_to_check = dirname($p_entry['filename']); @@ -4334,12 +4334,12 @@ function privDeleteByRule(&$p_result_list, &$p_options) $v_found = true; } } - } else if ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + } elseif ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { // ----- Look for extract by preg rule if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { $v_found = true; } - } else if ((isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + } elseif ((isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { // ----- Look for extract by index rule // ----- Look if the index is in the list for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { @@ -4495,7 +4495,7 @@ function privDeleteByRule(&$p_result_list, &$p_options) // ----- Destroy the temporary archive unset($v_temp_zip); - } else if ($v_central_dir['entries'] != 0) { + } elseif ($v_central_dir['entries'] != 0) { // ----- Remove every files : reset the file $this->privCloseFd(); @@ -4915,9 +4915,9 @@ function PclZipUtilPathReduction($p_dir) if ($v_list[$i] == ".") { // ----- Ignore this directory // Should be the first $i=0, but no check is done - } else if ($v_list[$i] == "..") { + } elseif ($v_list[$i] == "..") { $v_skip++; - } else if ($v_list[$i] == "") { + } elseif ($v_list[$i] == "") { // ----- First '/' i.e. root slash if ($i == 0) { $v_result = "/".$v_result; @@ -4927,7 +4927,7 @@ function PclZipUtilPathReduction($p_dir) $v_result = $p_dir; $v_skip = 0; } - } else if ($i == (sizeof($v_list)-1)) { + } elseif ($i == (sizeof($v_list)-1)) { // ----- Last '/' i.e. indicates a directory $v_result = $v_list[$i]; } else { @@ -5029,7 +5029,7 @@ function PclZipUtilPathInclusion($p_dir, $p_path) if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { // ----- There are exactly the same $v_result = 2; - } else if ($i < $v_list_dir_size) { + } elseif ($i < $v_list_dir_size) { // ----- The path is shorter than the dir $v_result = 0; } @@ -5062,21 +5062,21 @@ function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode = 0) @fwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } - } else if ($p_mode==1) { + } elseif ($p_mode==1) { while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @gzread($p_src, $v_read_size); @fwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } - } else if ($p_mode==2) { + } elseif ($p_mode==2) { while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($p_src, $v_read_size); @gzwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } - } else if ($p_mode==3) { + } elseif ($p_mode==3) { while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @gzread($p_src, $v_read_size); @@ -5111,7 +5111,7 @@ function PclZipUtilRename($p_src, $p_dest) // ----- Try to copy & unlink the src if (!@copy($p_src, $p_dest)) { $v_result = 0; - } else if (!@unlink($p_src)) { + } elseif (!@unlink($p_src)) { $v_result = 0; } } diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index c32a3bb8a..df8cdf2f8 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -504,7 +504,7 @@ public static function ConvertEncoding($value, $to, $from) if ($from == 'UTF-16LE') { return self::utf16_decode($value, false); - } else if ($from == 'UTF-16BE') { + } elseif ($from == 'UTF-16BE') { return self::utf16_decode($value); } // else, no conversion diff --git a/Classes/PHPExcel/Style.php b/Classes/PHPExcel/Style.php index 20f7236e7..6b952ef94 100644 --- a/Classes/PHPExcel/Style.php +++ b/Classes/PHPExcel/Style.php @@ -358,7 +358,7 @@ public function applyFromArray($pStyles = null, $pAdvanced = true) // Selection type, inspect if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) { $selectionType = 'COLUMN'; - } else if (preg_match('/^A[0-9]+:XFD[0-9]+$/', $pRange)) { + } elseif (preg_match('/^A[0-9]+:XFD[0-9]+$/', $pRange)) { $selectionType = 'ROW'; } else { $selectionType = 'CELL'; diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 0946c7cb6..8004412d3 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -2265,9 +2265,9 @@ public function getComment($pCellCoordinate = 'A1') if (strpos($pCellCoordinate, ':') !== false || strpos($pCellCoordinate, ',') !== false) { throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells.'); - } else if (strpos($pCellCoordinate, '$') !== false) { + } elseif (strpos($pCellCoordinate, '$') !== false) { throw new PHPExcel_Exception('Cell coordinate string must not be absolute.'); - } else if ($pCellCoordinate == '') { + } elseif ($pCellCoordinate == '') { throw new PHPExcel_Exception('Cell coordinate can not be zero-length string.'); } else { // Check if we already have a comment for this cell. diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php index 1540a22b0..90c5cc08b 100644 --- a/Classes/PHPExcel/Writer/CSV.php +++ b/Classes/PHPExcel/Writer/CSV.php @@ -32,49 +32,49 @@ class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_W * * @var PHPExcel */ - private $_phpExcel; + private $phpExcel; /** * Delimiter * * @var string */ - private $_delimiter = ','; + private $delimiter = ','; /** * Enclosure * * @var string */ - private $_enclosure = '"'; + private $enclosure = '"'; /** * Line ending * * @var string */ - private $_lineEnding = PHP_EOL; + private $lineEnding = PHP_EOL; /** * Sheet index to write * * @var int */ - private $_sheetIndex = 0; + private $sheetIndex = 0; /** * Whether to write a BOM (for UTF8). * * @var boolean */ - private $_useBOM = false; + private $useBOM = false; /** * Whether to write a fully Excel compatible CSV file. * * @var boolean */ - private $_excelCompatibility = false; + private $excelCompatibility = false; /** * Create a new PHPExcel_Writer_CSV @@ -83,7 +83,7 @@ class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_W */ public function __construct(PHPExcel $phpExcel) { - $this->_phpExcel = $phpExcel; + $this->phpExcel = $phpExcel; } /** @@ -95,10 +95,10 @@ public function __construct(PHPExcel $phpExcel) public function save($pFilename = null) { // Fetch sheet - $sheet = $this->_phpExcel->getSheet($this->_sheetIndex); + $sheet = $this->phpExcel->getSheet($this->sheetIndex); - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(false); + $saveDebugLog = PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog(false); $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); @@ -108,13 +108,13 @@ public function save($pFilename = null) throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); } - if ($this->_excelCompatibility) { + if ($this->excelCompatibility) { fwrite($fileHandle, "\xEF\xBB\xBF"); // Enforce UTF-8 BOM Header $this->setEnclosure('"'); // Set enclosure to " $this->setDelimiter(";"); // Set delimiter to a semi-colon $this->setLineEnding("\r\n"); - fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->_lineEnding); - } elseif ($this->_useBOM) { + fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->lineEnding); + } elseif ($this->useBOM) { // Write the UTF-8 BOM code if required fwrite($fileHandle, "\xEF\xBB\xBF"); } @@ -135,7 +135,7 @@ public function save($pFilename = null) fclose($fileHandle); PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); } /** @@ -145,7 +145,7 @@ public function save($pFilename = null) */ public function getDelimiter() { - return $this->_delimiter; + return $this->delimiter; } /** @@ -156,7 +156,7 @@ public function getDelimiter() */ public function setDelimiter($pValue = ',') { - $this->_delimiter = $pValue; + $this->delimiter = $pValue; return $this; } @@ -167,7 +167,7 @@ public function setDelimiter($pValue = ',') */ public function getEnclosure() { - return $this->_enclosure; + return $this->enclosure; } /** @@ -181,7 +181,7 @@ public function setEnclosure($pValue = '"') if ($pValue == '') { $pValue = null; } - $this->_enclosure = $pValue; + $this->enclosure = $pValue; return $this; } @@ -192,7 +192,7 @@ public function setEnclosure($pValue = '"') */ public function getLineEnding() { - return $this->_lineEnding; + return $this->lineEnding; } /** @@ -203,7 +203,7 @@ public function getLineEnding() */ public function setLineEnding($pValue = PHP_EOL) { - $this->_lineEnding = $pValue; + $this->lineEnding = $pValue; return $this; } @@ -214,7 +214,7 @@ public function setLineEnding($pValue = PHP_EOL) */ public function getUseBOM() { - return $this->_useBOM; + return $this->useBOM; } /** @@ -225,7 +225,7 @@ public function getUseBOM() */ public function setUseBOM($pValue = false) { - $this->_useBOM = $pValue; + $this->useBOM = $pValue; return $this; } @@ -236,7 +236,7 @@ public function setUseBOM($pValue = false) */ public function getExcelCompatibility() { - return $this->_excelCompatibility; + return $this->excelCompatibility; } /** @@ -248,7 +248,7 @@ public function getExcelCompatibility() */ public function setExcelCompatibility($pValue = false) { - $this->_excelCompatibility = $pValue; + $this->excelCompatibility = $pValue; return $this; } @@ -259,7 +259,7 @@ public function setExcelCompatibility($pValue = false) */ public function getSheetIndex() { - return $this->_sheetIndex; + return $this->sheetIndex; } /** @@ -270,7 +270,7 @@ public function getSheetIndex() */ public function setSheetIndex($pValue = 0) { - $this->_sheetIndex = $pValue; + $this->sheetIndex = $pValue; return $this; } @@ -292,21 +292,21 @@ private function _writeLine($pFileHandle = null, $pValues = null) foreach ($pValues as $element) { // Escape enclosures - $element = str_replace($this->_enclosure, $this->_enclosure . $this->_enclosure, $element); + $element = str_replace($this->enclosure, $this->enclosure . $this->enclosure, $element); // Add delimiter if ($writeDelimiter) { - $line .= $this->_delimiter; + $line .= $this->delimiter; } else { $writeDelimiter = true; } // Add enclosed string - $line .= $this->_enclosure . $element . $this->_enclosure; + $line .= $this->enclosure . $element . $this->enclosure; } // Add line ending - $line .= $this->_lineEnding; + $line .= $this->lineEnding; // Write to file fwrite($pFileHandle, $line); diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index e7f26ff58..1b2410187 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -368,7 +368,7 @@ public function save($pFilename = null) } $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); - } else if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { + } elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { ob_start(); call_user_func( $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(), diff --git a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php index 4f0b1eba3..c441ef11b 100644 --- a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php +++ b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -145,7 +145,7 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); $mimeType = $this->_getImageMimeType($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath()); - } else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { + } elseif ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); $extension = explode('/', $extension); $extension = $extension[1]; diff --git a/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Classes/PHPExcel/Writer/Excel2007/StringTable.php index 4a28f13e9..7976f7bbe 100644 --- a/Classes/PHPExcel/Writer/Excel2007/StringTable.php +++ b/Classes/PHPExcel/Writer/Excel2007/StringTable.php @@ -123,7 +123,7 @@ public function writeStringTable($pStringTable = null) } $objWriter->writeRawData($textToWrite); $objWriter->endElement(); - } else if ($textElement instanceof PHPExcel_RichText) { + } elseif ($textElement instanceof PHPExcel_RichText) { $this->writeRichText($objWriter, $textElement); } @@ -184,7 +184,7 @@ public function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx $objWriter->startElement($prefix.'vertAlign'); if ($element->getFont()->getSuperScript()) { $objWriter->writeAttribute('val', 'superscript'); - } else if ($element->getFont()->getSubScript()) { + } elseif ($element->getFont()->getSubScript()) { $objWriter->writeAttribute('val', 'subscript'); } $objWriter->endElement(); @@ -280,7 +280,7 @@ public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = nu // $objWriter->startElement($prefix.'vertAlign'); // if ($element->getFont()->getSuperScript()) { // $objWriter->writeAttribute('val', 'superscript'); -// } else if ($element->getFont()->getSubScript()) { +// } elseif ($element->getFont()->getSubScript()) { // $objWriter->writeAttribute('val', 'subscript'); // } // $objWriter->endElement(); @@ -313,7 +313,7 @@ public function flipStringTable($stringTable = array()) foreach ($stringTable as $key => $value) { if (! $value instanceof PHPExcel_RichText) { $returnValue[$value] = $key; - } else if ($value instanceof PHPExcel_RichText) { + } elseif ($value instanceof PHPExcel_RichText) { $returnValue[$value->getHashCode()] = $key; } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Style.php b/Classes/PHPExcel/Writer/Excel2007/Style.php index d6cf85384..5ff56f33d 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Style.php +++ b/Classes/PHPExcel/Writer/Excel2007/Style.php @@ -317,7 +317,7 @@ private function _writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce $objWriter->startElement('vertAlign'); if ($pFont->getSuperScript() === true) { $objWriter->writeAttribute('val', 'superscript'); - } else if ($pFont->getSubScript() === true) { + } elseif ($pFont->getSubScript() === true) { $objWriter->writeAttribute('val', 'subscript'); } $objWriter->endElement(); @@ -428,7 +428,7 @@ private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, $textRotation = 0; if ($pStyle->getAlignment()->getTextRotation() >= 0) { $textRotation = $pStyle->getAlignment()->getTextRotation(); - } else if ($pStyle->getAlignment()->getTextRotation() < 0) { + } elseif ($pStyle->getAlignment()->getTextRotation() < 0) { $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); } $objWriter->writeAttribute('textRotation', $textRotation); @@ -493,7 +493,7 @@ private function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, $textRotation = 0; if ($pStyle->getAlignment()->getTextRotation() >= 0) { $textRotation = $pStyle->getAlignment()->getTextRotation(); - } else if ($pStyle->getAlignment()->getTextRotation() < 0) { + } elseif ($pStyle->getAlignment()->getTextRotation() < 0) { $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); } $objWriter->writeAttribute('textRotation', $textRotation); diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index cb153f8ae..492e04535 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -506,19 +506,19 @@ private function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWrite && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT && !is_null($conditional->getText())) { $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH && !is_null($conditional->getText())) { $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH && !is_null($conditional->getText())) { $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS && !is_null($conditional->getText())) { $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))'); - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS + } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { foreach ($conditional->getConditions() as $formula) { @@ -910,7 +910,7 @@ private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx foreach ($pSheet->getBreaks() as $cell => $breakType) { if ($breakType == PHPExcel_Worksheet::BREAK_ROW) { $aRowBreaks[] = $cell; - } else if ($breakType == PHPExcel_Worksheet::BREAK_COLUMN) { + } elseif ($breakType == PHPExcel_Worksheet::BREAK_COLUMN) { $aColumnBreaks[] = $cell; } } @@ -1095,7 +1095,7 @@ private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce case 'inlinestr': // Inline string if (! $cellValue instanceof PHPExcel_RichText) { $objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML(htmlspecialchars($cellValue))); - } else if ($cellValue instanceof PHPExcel_RichText) { + } elseif ($cellValue instanceof PHPExcel_RichText) { $objWriter->startElement('is'); $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue); $objWriter->endElement(); @@ -1107,7 +1107,7 @@ private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce if (isset($pFlippedStringTable[$cellValue])) { $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]); } - } else if ($cellValue instanceof PHPExcel_RichText) { + } elseif ($cellValue instanceof PHPExcel_RichText) { $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]); } diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index 024e7708a..b1f49e099 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -32,63 +32,63 @@ class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExce * * @var PHPExcel */ - private $_phpExcel; + private $phpExcel; /** * Total number of shared strings in workbook * * @var int */ - private $_str_total = 0; + private $strTotal = 0; /** * Number of unique shared strings in workbook * * @var int */ - private $_str_unique = 0; + private $strUnique = 0; /** * Array of unique shared strings in workbook * * @var array */ - private $_str_table = array(); + private $strTable = array(); /** * Color cache. Mapping between RGB value and color index. * * @var array */ - private $_colors; + private $colors; /** * Formula parser * * @var PHPExcel_Writer_Excel5_Parser */ - private $_parser; + private $parser; /** * Identifier clusters for drawings. Used in MSODRAWINGGROUP record. * * @var array */ - private $_IDCLs; + private $IDCLs; /** * Basic OLE object summary information * * @var array */ - private $_summaryInformation; + private $summaryInformation; /** * Extended OLE object document summary information * * @var array */ - private $_documentSummaryInformation; + private $documentSummaryInformation; /** * Create a new PHPExcel_Writer_Excel5 @@ -97,9 +97,9 @@ class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExce */ public function __construct(PHPExcel $phpExcel) { - $this->_phpExcel = $phpExcel; + $this->phpExcel = $phpExcel; - $this->_parser = new PHPExcel_Writer_Excel5_Parser(); + $this->parser = new PHPExcel_Writer_Excel5_Parser(); } /** @@ -112,38 +112,38 @@ public function save($pFilename = null) { // garbage collect - $this->_phpExcel->garbageCollect(); + $this->phpExcel->garbageCollect(); - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(false); + $saveDebugLog = PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog(false); $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // initialize colors array - $this->_colors = array(); + $this->colors = array(); // Initialise workbook writer - $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel, $this->_str_total, $this->_str_unique, $this->_str_table, $this->_colors, $this->_parser); + $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->phpExcel, $this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser); // Initialise worksheet writers - $countSheets = $this->_phpExcel->getSheetCount(); + $countSheets = $this->phpExcel->getSheetCount(); for ($i = 0; $i < $countSheets; ++$i) { - $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->_str_total, $this->_str_unique, $this->_str_table, $this->_colors, $this->_parser, $this->_preCalculateFormulas, $this->_phpExcel->getSheet($i)); + $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser, $this->_preCalculateFormulas, $this->phpExcel->getSheet($i)); } // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook. - $this->_buildWorksheetEschers(); - $this->_buildWorkbookEscher(); + $this->buildWorksheetEschers(); + $this->buildWorkbookEscher(); // add 15 identical cell style Xfs // for now, we use the first cellXf instead of cellStyleXf - $cellXfCollection = $this->_phpExcel->getCellXfCollection(); + $cellXfCollection = $this->phpExcel->getCellXfCollection(); for ($i = 0; $i < 15; ++$i) { $this->_writerWorkbook->addXfWriter($cellXfCollection[0], true); } // add all the cell Xfs - foreach ($this->_phpExcel->getCellXfCollection() as $style) { + foreach ($this->phpExcel->getCellXfCollection() as $style) { $this->_writerWorkbook->addXfWriter($style, false); } @@ -184,18 +184,18 @@ public function save($pFilename = null) $OLE->append($this->_writerWorksheets[$i]->getData()); } - $this->_documentSummaryInformation = $this->_writeDocumentSummaryInformation(); + $this->documentSummaryInformation = $this->writeDocumentSummaryInformation(); // initialize OLE Document Summary Information - if (isset($this->_documentSummaryInformation) && !empty($this->_documentSummaryInformation)) { + if (isset($this->documentSummaryInformation) && !empty($this->documentSummaryInformation)) { $OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation')); - $OLE_DocumentSummaryInformation->append($this->_documentSummaryInformation); + $OLE_DocumentSummaryInformation->append($this->documentSummaryInformation); } - $this->_summaryInformation = $this->_writeSummaryInformation(); + $this->summaryInformation = $this->writeSummaryInformation(); // initialize OLE Summary Information - if (isset($this->_summaryInformation) && !empty($this->_summaryInformation)) { + if (isset($this->summaryInformation) && !empty($this->summaryInformation)) { $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation')); - $OLE_SummaryInformation->append($this->_summaryInformation); + $OLE_SummaryInformation->append($this->summaryInformation); } // define OLE Parts @@ -214,7 +214,7 @@ public function save($pFilename = null) $res = $root->save($pFilename); PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); } /** @@ -234,14 +234,14 @@ public function setTempDir($pValue = '') * Build the Worksheet Escher objects * */ - private function _buildWorksheetEschers() + private function buildWorksheetEschers() { // 1-based index to BstoreContainer $blipIndex = 0; $lastReducedSpId = 0; $lastSpId = 0; - foreach ($this->_phpExcel->getAllsheets() as $sheet) { + foreach ($this->phpExcel->getAllsheets() as $sheet) { // sheet index $sheetIndex = $sheet->getParent()->getIndex($sheet); @@ -385,7 +385,7 @@ private function _buildWorksheetEschers() } // identifier clusters, used for workbook Escher object - $this->_IDCLs[$dgId] = $lastReducedSpId; + $this->IDCLs[$dgId] = $lastReducedSpId; // set last shape index $dgContainer->setLastSpId($lastSpId); @@ -398,13 +398,13 @@ private function _buildWorksheetEschers() /** * Build the Escher object corresponding to the MSODRAWINGGROUP record */ - private function _buildWorkbookEscher() + private function buildWorkbookEscher() { $escher = null; // any drawings in this workbook? $found = false; - foreach ($this->_phpExcel->getAllSheets() as $sheet) { + foreach ($this->phpExcel->getAllSheets() as $sheet) { if (count($sheet->getDrawingCollection()) > 0) { $found = true; break; @@ -424,14 +424,14 @@ private function _buildWorkbookEscher() $escher->setDggContainer($dggContainer); // set IDCLs (identifier clusters) - $dggContainer->setIDCLs($this->_IDCLs); + $dggContainer->setIDCLs($this->IDCLs); // this loop is for determining maximum shape identifier of all drawing $spIdMax = 0; $totalCountShapes = 0; $countDrawings = 0; - foreach ($this->_phpExcel->getAllsheets() as $sheet) { + foreach ($this->phpExcel->getAllsheets() as $sheet) { $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet if (count($sheet->getDrawingCollection()) > 0) { @@ -441,7 +441,7 @@ private function _buildWorkbookEscher() ++$sheetCountShapes; ++$totalCountShapes; - $spId = $sheetCountShapes | ($this->_phpExcel->getIndex($sheet) + 1) << 10; + $spId = $sheetCountShapes | ($this->phpExcel->getIndex($sheet) + 1) << 10; $spIdMax = max($spId, $spIdMax); } } @@ -456,7 +456,7 @@ private function _buildWorkbookEscher() $dggContainer->setBstoreContainer($bstoreContainer); // the BSE's (all the images) - foreach ($this->_phpExcel->getAllsheets() as $sheet) { + foreach ($this->phpExcel->getAllsheets() as $sheet) { foreach ($sheet->getDrawingCollection() as $drawing) { if ($drawing instanceof PHPExcel_Worksheet_Drawing) { $filename = $drawing->getPath(); @@ -498,7 +498,7 @@ private function _buildWorkbookEscher() $BSE->setBlip($blip); $bstoreContainer->addBSE($BSE); - } else if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { + } elseif ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { switch ($drawing->getRenderingFunction()) { case PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG: $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; @@ -537,7 +537,7 @@ private function _buildWorkbookEscher() * Build the OLE Part for DocumentSummary Information * @return string */ - private function _writeDocumentSummaryInformation() + private function writeDocumentSummaryInformation() { // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) $data = pack('v', 0xFFFE); @@ -571,8 +571,8 @@ private function _writeDocumentSummaryInformation() $dataSection_NumProps++; // GKPIDDSI_CATEGORY : Category - if ($this->_phpExcel->getProperties()->getCategory()) { - $dataProp = $this->_phpExcel->getProperties()->getCategory(); + if ($this->phpExcel->getProperties()->getCategory()) { + $dataProp = $this->phpExcel->getProperties()->getCategory(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), @@ -733,7 +733,7 @@ private function _writeDocumentSummaryInformation() * Build the OLE Part for Summary Information * @return string */ - private function _writeSummaryInformation() + private function writeSummaryInformation() { // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) $data = pack('v', 0xFFFE); @@ -767,8 +767,8 @@ private function _writeSummaryInformation() $dataSection_NumProps++; // Title - if ($this->_phpExcel->getProperties()->getTitle()) { - $dataProp = $this->_phpExcel->getProperties()->getTitle(); + if ($this->phpExcel->getProperties()->getTitle()) { + $dataProp = $this->phpExcel->getProperties()->getTitle(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length @@ -776,8 +776,8 @@ private function _writeSummaryInformation() $dataSection_NumProps++; } // Subject - if ($this->_phpExcel->getProperties()->getSubject()) { - $dataProp = $this->_phpExcel->getProperties()->getSubject(); + if ($this->phpExcel->getProperties()->getSubject()) { + $dataProp = $this->phpExcel->getProperties()->getSubject(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length @@ -785,8 +785,8 @@ private function _writeSummaryInformation() $dataSection_NumProps++; } // Author (Creator) - if ($this->_phpExcel->getProperties()->getCreator()) { - $dataProp = $this->_phpExcel->getProperties()->getCreator(); + if ($this->phpExcel->getProperties()->getCreator()) { + $dataProp = $this->phpExcel->getProperties()->getCreator(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length @@ -794,8 +794,8 @@ private function _writeSummaryInformation() $dataSection_NumProps++; } // Keywords - if ($this->_phpExcel->getProperties()->getKeywords()) { - $dataProp = $this->_phpExcel->getProperties()->getKeywords(); + if ($this->phpExcel->getProperties()->getKeywords()) { + $dataProp = $this->phpExcel->getProperties()->getKeywords(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length @@ -803,8 +803,8 @@ private function _writeSummaryInformation() $dataSection_NumProps++; } // Comments (Description) - if ($this->_phpExcel->getProperties()->getDescription()) { - $dataProp = $this->_phpExcel->getProperties()->getDescription(); + if ($this->phpExcel->getProperties()->getDescription()) { + $dataProp = $this->phpExcel->getProperties()->getDescription(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length @@ -812,8 +812,8 @@ private function _writeSummaryInformation() $dataSection_NumProps++; } // Last Saved By (LastModifiedBy) - if ($this->_phpExcel->getProperties()->getLastModifiedBy()) { - $dataProp = $this->_phpExcel->getProperties()->getLastModifiedBy(); + if ($this->phpExcel->getProperties()->getLastModifiedBy()) { + $dataProp = $this->phpExcel->getProperties()->getLastModifiedBy(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length @@ -821,8 +821,8 @@ private function _writeSummaryInformation() $dataSection_NumProps++; } // Created Date/Time - if ($this->_phpExcel->getProperties()->getCreated()) { - $dataProp = $this->_phpExcel->getProperties()->getCreated(); + if ($this->phpExcel->getProperties()->getCreated()) { + $dataProp = $this->phpExcel->getProperties()->getCreated(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) @@ -830,8 +830,8 @@ private function _writeSummaryInformation() $dataSection_NumProps++; } // Modified Date/Time - if ($this->_phpExcel->getProperties()->getModified()) { - $dataProp = $this->_phpExcel->getProperties()->getModified(); + if ($this->phpExcel->getProperties()->getModified()) { + $dataProp = $this->phpExcel->getProperties()->getModified(); $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), 'offset' => array('pack' => 'V'), 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) diff --git a/Classes/PHPExcel/Writer/Excel5/Escher.php b/Classes/PHPExcel/Writer/Excel5/Escher.php index fc0f10a75..e7e79a843 100644 --- a/Classes/PHPExcel/Writer/Excel5/Escher.php +++ b/Classes/PHPExcel/Writer/Excel5/Escher.php @@ -82,7 +82,7 @@ public function close() if ($dggContainer = $this->_object->getDggContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer); $this->_data = $writer->close(); - } else if ($dgContainer = $this->_object->getDgContainer()) { + } elseif ($dgContainer = $this->_object->getDgContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer); $this->_data = $writer->close(); $this->_spOffsets = $writer->getSpOffsets(); diff --git a/Classes/PHPExcel/Writer/Excel5/Font.php b/Classes/PHPExcel/Writer/Excel5/Font.php index a95e64555..e67562b8f 100644 --- a/Classes/PHPExcel/Writer/Excel5/Font.php +++ b/Classes/PHPExcel/Writer/Excel5/Font.php @@ -83,7 +83,7 @@ public function writeFont() $icv = $this->_colorIndex; // Index to color palette if ($this->_font->getSuperScript()) { $sss = 1; - } else if ($this->_font->getSubScript()) { + } elseif ($this->_font->getSubScript()) { $sss = 2; } else { $sss = 0; diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index cd6bbd737..c5f827d5e 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -610,7 +610,7 @@ private function _writeNames() ); // (exclusive) either repeatColumns or repeatRows - } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { + } elseif ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { // Columns to repeat if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); @@ -717,7 +717,7 @@ private function _writeAllDefinedNamesBiff8() $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); // (exclusive) either repeatColumns or repeatRows - } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { + } elseif ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { // Columns to repeat if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index 11e0e862a..6949c1727 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -504,7 +504,7 @@ public function close() // internal to current workbook $url = str_replace('sheet://', 'internal:', $url); - } else if (preg_match('/^(http:|https:|ftp:|mailto:)/', $url)) { + } elseif (preg_match('/^(http:|https:|ftp:|mailto:)/', $url)) { // URL // $url = $url; @@ -3048,7 +3048,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional) if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { $type = 0x02; $operatorType = 0x00; - } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS) { + } elseif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS) { $type = 0x01; switch ($conditional->getOperatorType()) { @@ -3089,7 +3089,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional) $szValue2 = 0x0000; $operand1 = pack('Cv', 0x1E, $arrConditions[0]); $operand2 = null; - } else if ($numConditions == 2 && ($conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BETWEEN)) { + } elseif ($numConditions == 2 && ($conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BETWEEN)) { $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); $szValue2 = ($arrConditions[1] <= 65535 ? 3 : 0x0000); $operand1 = pack('Cv', 0x1E, $arrConditions[0]); @@ -3226,7 +3226,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional) if ($conditional->getStyle()->getFont()->getSubScript() == true) { $dataBlockFont .= pack('v', 0x02); $fontEscapement = 0; - } else if ($conditional->getStyle()->getFont()->getSuperScript() == true) { + } elseif ($conditional->getStyle()->getFont()->getSuperScript() == true) { $dataBlockFont .= pack('v', 0x01); $fontEscapement = 0; } else { diff --git a/Classes/PHPExcel/Writer/Excel5/Xf.php b/Classes/PHPExcel/Writer/Excel5/Xf.php index dc185f00c..61a42eb26 100644 --- a/Classes/PHPExcel/Writer/Excel5/Xf.php +++ b/Classes/PHPExcel/Writer/Excel5/Xf.php @@ -75,61 +75,61 @@ class PHPExcel_Writer_Excel5_Xf * * @var boolean */ - private $_isStyleXf; + private $isStyleXf; /** * Index to the FONT record. Index 4 does not exist * @var integer */ - private $_fontIndex; + private $fontIndex; /** * An index (2 bytes) to a FORMAT record (number format). * @var integer */ - public $_numberFormatIndex; + private $numberFormatIndex; /** * 1 bit, apparently not used. * @var integer */ - public $_text_justlast; + private $textJustLast; /** * The cell's foreground color. * @var integer */ - public $_fg_color; + private $foregroundColor; /** * The cell's background color. * @var integer */ - public $_bg_color; + private $backgroundColor; /** * Color of the bottom border of the cell. * @var integer */ - public $_bottom_color; + private $bottomBorderColor; /** * Color of the top border of the cell. * @var integer */ - public $_top_color; + private $topBorderColor; /** * Color of the left border of the cell. * @var integer */ - public $_left_color; + private $leftBorderColor; /** * Color of the right border of the cell. * @var integer */ - public $_right_color; + private $rightBorderColor; /** * Constructor @@ -139,22 +139,22 @@ class PHPExcel_Writer_Excel5_Xf */ public function __construct(PHPExcel_Style $style = null) { - $this->_isStyleXf = false; - $this->_fontIndex = 0; + $this->isStyleXf = false; + $this->fontIndex = 0; - $this->_numberFormatIndex = 0; + $this->numberFormatIndex = 0; - $this->_text_justlast = 0; + $this->textJustLast = 0; - $this->_fg_color = 0x40; - $this->_bg_color = 0x41; + $this->foregroundColor = 0x40; + $this->backgroundColor = 0x41; $this->_diag = 0; - $this->_bottom_color = 0x40; - $this->_top_color = 0x40; - $this->_left_color = 0x40; - $this->_right_color = 0x40; + $this->bottomBorderColor = 0x40; + $this->topBorderColor = 0x40; + $this->leftBorderColor = 0x40; + $this->rightBorderColor = 0x40; $this->_diag_color = 0x40; $this->_style = $style; @@ -169,94 +169,94 @@ public function __construct(PHPExcel_Style $style = null) public function writeXf() { // Set the type of the XF record and some of the attributes. - if ($this->_isStyleXf) { + if ($this->isStyleXf) { $style = 0xFFF5; } else { - $style = self::_mapLocked($this->_style->getProtection()->getLocked()); - $style |= self::_mapHidden($this->_style->getProtection()->getHidden()) << 1; + $style = self::mapLocked($this->_style->getProtection()->getLocked()); + $style |= self::mapHidden($this->_style->getProtection()->getHidden()) << 1; } // Flags to indicate if attributes have been set. - $atr_num = ($this->_numberFormatIndex != 0)?1:0; - $atr_fnt = ($this->_fontIndex != 0)?1:0; + $atr_num = ($this->numberFormatIndex != 0)?1:0; + $atr_fnt = ($this->fontIndex != 0)?1:0; $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0; - $atr_bdr = (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) || - self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) || - self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) || - self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()))?1:0; - $atr_pat = (($this->_fg_color != 0x40) || - ($this->_bg_color != 0x41) || - self::_mapFillType($this->_style->getFill()->getFillType()))?1:0; - $atr_prot = self::_mapLocked($this->_style->getProtection()->getLocked()) - | self::_mapHidden($this->_style->getProtection()->getHidden()); + $atr_bdr = (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) || + self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) || + self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) || + self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()))?1:0; + $atr_pat = (($this->foregroundColor != 0x40) || + ($this->backgroundColor != 0x41) || + self::mapFillType($this->_style->getFill()->getFillType()))?1:0; + $atr_prot = self::mapLocked($this->_style->getProtection()->getLocked()) + | self::mapHidden($this->_style->getProtection()->getHidden()); // Zero the default border colour if the border has not been set. - if (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) { - $this->_bottom_color = 0; + if (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) { + $this->bottomBorderColor = 0; } - if (self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) { - $this->_top_color = 0; + if (self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) { + $this->topBorderColor = 0; } - if (self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) { - $this->_right_color = 0; + if (self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) { + $this->rightBorderColor = 0; } - if (self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) { - $this->_left_color = 0; + if (self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) { + $this->leftBorderColor = 0; } - if (self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) { + if (self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) { $this->_diag_color = 0; } - $record = 0x00E0; // Record identifier - $length = 0x0014; // Number of bytes to follow + $record = 0x00E0; // Record identifier + $length = 0x0014; // Number of bytes to follow - $ifnt = $this->_fontIndex; // Index to FONT record - $ifmt = $this->_numberFormatIndex; // Index to FORMAT record + $ifnt = $this->fontIndex; // Index to FONT record + $ifmt = $this->numberFormatIndex; // Index to FORMAT record - $align = $this->_mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment - $align |= (int) $this->_style->getAlignment()->getWrapText() << 3; - $align |= self::_mapVAlign($this->_style->getAlignment()->getVertical()) << 4; - $align |= $this->_text_justlast << 7; + $align = $this->mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment + $align |= (int) $this->_style->getAlignment()->getWrapText() << 3; + $align |= self::mapVAlign($this->_style->getAlignment()->getVertical()) << 4; + $align |= $this->textJustLast << 7; - $used_attrib = $atr_num << 2; - $used_attrib |= $atr_fnt << 3; - $used_attrib |= $atr_alc << 4; - $used_attrib |= $atr_bdr << 5; - $used_attrib |= $atr_pat << 6; - $used_attrib |= $atr_prot << 7; + $used_attrib = $atr_num << 2; + $used_attrib |= $atr_fnt << 3; + $used_attrib |= $atr_alc << 4; + $used_attrib |= $atr_bdr << 5; + $used_attrib |= $atr_pat << 6; + $used_attrib |= $atr_prot << 7; - $icv = $this->_fg_color; // fg and bg pattern colors - $icv |= $this->_bg_color << 7; + $icv = $this->foregroundColor; // fg and bg pattern colors + $icv |= $this->backgroundColor << 7; - $border1 = self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color - $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4; - $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8; - $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12; - $border1 |= $this->_left_color << 16; - $border1 |= $this->_right_color << 23; + $border1 = self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color + $border1 |= self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4; + $border1 |= self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8; + $border1 |= self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12; + $border1 |= $this->leftBorderColor << 16; + $border1 |= $this->rightBorderColor << 23; $diagonalDirection = $this->_style->getBorders()->getDiagonalDirection(); $diag_tl_to_rb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_DOWN; $diag_tr_to_lb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_UP; - $border1 |= $diag_tl_to_rb << 30; - $border1 |= $diag_tr_to_lb << 31; + $border1 |= $diag_tl_to_rb << 30; + $border1 |= $diag_tr_to_lb << 31; - $border2 = $this->_top_color; // Border color - $border2 |= $this->_bottom_color << 7; - $border2 |= $this->_diag_color << 14; - $border2 |= self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21; - $border2 |= self::_mapFillType($this->_style->getFill()->getFillType()) << 26; + $border2 = $this->topBorderColor; // Border color + $border2 |= $this->bottomBorderColor << 7; + $border2 |= $this->_diag_color << 14; + $border2 |= self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21; + $border2 |= self::mapFillType($this->_style->getFill()->getFillType()) << 26; - $header = pack("vv", $record, $length); + $header = pack("vv", $record, $length); //BIFF8 options: identation, shrinkToFit and text direction $biff8_options = $this->_style->getAlignment()->getIndent(); $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4; $data = pack("vvvC", $ifnt, $ifmt, $style, $align); - $data .= pack("CCC", self::_mapTextRotation($this->_style->getAlignment()->getTextRotation()), $biff8_options, $used_attrib); + $data .= pack("CCC", self::mapTextRotation($this->_style->getAlignment()->getTextRotation()), $biff8_options, $used_attrib); $data .= pack("VVv", $border1, $border2, $icv); return($header . $data); @@ -269,7 +269,7 @@ public function writeXf() */ public function setIsStyleXf($value) { - $this->_isStyleXf = $value; + $this->isStyleXf = $value; } /** @@ -280,7 +280,7 @@ public function setIsStyleXf($value) */ public function setBottomColor($colorIndex) { - $this->_bottom_color = $colorIndex; + $this->bottomBorderColor = $colorIndex; } /** @@ -291,7 +291,7 @@ public function setBottomColor($colorIndex) */ public function setTopColor($colorIndex) { - $this->_top_color = $colorIndex; + $this->topBorderColor = $colorIndex; } /** @@ -302,7 +302,7 @@ public function setTopColor($colorIndex) */ public function setLeftColor($colorIndex) { - $this->_left_color = $colorIndex; + $this->leftBorderColor = $colorIndex; } /** @@ -313,7 +313,7 @@ public function setLeftColor($colorIndex) */ public function setRightColor($colorIndex) { - $this->_right_color = $colorIndex; + $this->rightBorderColor = $colorIndex; } /** @@ -336,7 +336,7 @@ public function setDiagColor($colorIndex) */ public function setFgColor($colorIndex) { - $this->_fg_color = $colorIndex; + $this->foregroundColor = $colorIndex; } /** @@ -347,7 +347,7 @@ public function setFgColor($colorIndex) */ public function setBgColor($colorIndex) { - $this->_bg_color = $colorIndex; + $this->backgroundColor = $colorIndex; } /** @@ -359,7 +359,7 @@ public function setBgColor($colorIndex) */ public function setNumberFormatIndex($numberFormatIndex) { - $this->_numberFormatIndex = $numberFormatIndex; + $this->numberFormatIndex = $numberFormatIndex; } /** @@ -369,7 +369,7 @@ public function setNumberFormatIndex($numberFormatIndex) */ public function setFontIndex($value) { - $this->_fontIndex = $value; + $this->fontIndex = $value; } /** @@ -377,21 +377,22 @@ public function setFontIndex($value) * @static array of int * */ - private static $_mapBorderStyle = array ( PHPExcel_Style_Border::BORDER_NONE => 0x00, - PHPExcel_Style_Border::BORDER_THIN => 0x01, - PHPExcel_Style_Border::BORDER_MEDIUM => 0x02, - PHPExcel_Style_Border::BORDER_DASHED => 0x03, - PHPExcel_Style_Border::BORDER_DOTTED => 0x04, - PHPExcel_Style_Border::BORDER_THICK => 0x05, - PHPExcel_Style_Border::BORDER_DOUBLE => 0x06, - PHPExcel_Style_Border::BORDER_HAIR => 0x07, - PHPExcel_Style_Border::BORDER_MEDIUMDASHED => 0x08, - PHPExcel_Style_Border::BORDER_DASHDOT => 0x09, - PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT => 0x0A, - PHPExcel_Style_Border::BORDER_DASHDOTDOT => 0x0B, - PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT => 0x0C, - PHPExcel_Style_Border::BORDER_SLANTDASHDOT => 0x0D, - ); + private static $mapBorderStyles = array( + PHPExcel_Style_Border::BORDER_NONE => 0x00, + PHPExcel_Style_Border::BORDER_THIN => 0x01, + PHPExcel_Style_Border::BORDER_MEDIUM => 0x02, + PHPExcel_Style_Border::BORDER_DASHED => 0x03, + PHPExcel_Style_Border::BORDER_DOTTED => 0x04, + PHPExcel_Style_Border::BORDER_THICK => 0x05, + PHPExcel_Style_Border::BORDER_DOUBLE => 0x06, + PHPExcel_Style_Border::BORDER_HAIR => 0x07, + PHPExcel_Style_Border::BORDER_MEDIUMDASHED => 0x08, + PHPExcel_Style_Border::BORDER_DASHDOT => 0x09, + PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT => 0x0A, + PHPExcel_Style_Border::BORDER_DASHDOTDOT => 0x0B, + PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT => 0x0C, + PHPExcel_Style_Border::BORDER_SLANTDASHDOT => 0x0D, + ); /** * Map border style @@ -399,10 +400,10 @@ public function setFontIndex($value) * @param string $borderStyle * @return int */ - private static function _mapBorderStyle($borderStyle) + private static function mapBorderStyle($borderStyle) { - if (isset(self::$_mapBorderStyle[$borderStyle])) { - return self::$_mapBorderStyle[$borderStyle]; + if (isset(self::$mapBorderStyles[$borderStyle])) { + return self::$mapBorderStyles[$borderStyle]; } return 0x00; } @@ -412,38 +413,40 @@ private static function _mapBorderStyle($borderStyle) * @static array of int * */ - private static $_mapFillType = array( PHPExcel_Style_Fill::FILL_NONE => 0x00, - PHPExcel_Style_Fill::FILL_SOLID => 0x01, - PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY => 0x02, - PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY => 0x03, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY => 0x04, - PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL => 0x05, - PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL => 0x06, - PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN => 0x07, - PHPExcel_Style_Fill::FILL_PATTERN_DARKUP => 0x08, - PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID => 0x09, - PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS => 0x0A, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL => 0x0B, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL => 0x0C, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN => 0x0D, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP => 0x0E, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID => 0x0F, - PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS => 0x10, - PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 => 0x11, - PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 => 0x12, - PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR => 0x00, // does not exist in BIFF8 - PHPExcel_Style_Fill::FILL_GRADIENT_PATH => 0x00, // does not exist in BIFF8 - ); + private static $mapFillTypes = array( + PHPExcel_Style_Fill::FILL_NONE => 0x00, + PHPExcel_Style_Fill::FILL_SOLID => 0x01, + PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY => 0x02, + PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY => 0x03, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY => 0x04, + PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL => 0x05, + PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL => 0x06, + PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN => 0x07, + PHPExcel_Style_Fill::FILL_PATTERN_DARKUP => 0x08, + PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID => 0x09, + PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS => 0x0A, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL => 0x0B, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL => 0x0C, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN => 0x0D, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP => 0x0E, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID => 0x0F, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS => 0x10, + PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 => 0x11, + PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 => 0x12, + PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR => 0x00, // does not exist in BIFF8 + PHPExcel_Style_Fill::FILL_GRADIENT_PATH => 0x00, // does not exist in BIFF8 + ); + /** * Map fill type * * @param string $fillType * @return int */ - private static function _mapFillType($fillType) + private static function mapFillType($fillType) { - if (isset(self::$_mapFillType[$fillType])) { - return self::$_mapFillType[$fillType]; + if (isset(self::$mapFillTypes[$fillType])) { + return self::$mapFillTypes[$fillType]; } return 0x00; } @@ -453,24 +456,26 @@ private static function _mapFillType($fillType) * @static array of int * */ - private static $_mapHAlign = array( PHPExcel_Style_Alignment::HORIZONTAL_GENERAL => 0, - PHPExcel_Style_Alignment::HORIZONTAL_LEFT => 1, - PHPExcel_Style_Alignment::HORIZONTAL_CENTER => 2, - PHPExcel_Style_Alignment::HORIZONTAL_RIGHT => 3, - PHPExcel_Style_Alignment::HORIZONTAL_FILL => 4, - PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY => 5, - PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6, - ); + private static $mapHAlignments = array( + PHPExcel_Style_Alignment::HORIZONTAL_GENERAL => 0, + PHPExcel_Style_Alignment::HORIZONTAL_LEFT => 1, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER => 2, + PHPExcel_Style_Alignment::HORIZONTAL_RIGHT => 3, + PHPExcel_Style_Alignment::HORIZONTAL_FILL => 4, + PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY => 5, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6, + ); + /** * Map to BIFF2-BIFF8 codes for horizontal alignment * * @param string $hAlign * @return int */ - private function _mapHAlign($hAlign) + private function mapHAlign($hAlign) { - if (isset(self::$_mapHAlign[$hAlign])) { - return self::$_mapHAlign[$hAlign]; + if (isset(self::$mapHAlignments[$hAlign])) { + return self::$mapHAlignments[$hAlign]; } return 0; } @@ -480,21 +485,23 @@ private function _mapHAlign($hAlign) * @static array of int * */ - private static $_mapVAlign = array( PHPExcel_Style_Alignment::VERTICAL_TOP => 0, - PHPExcel_Style_Alignment::VERTICAL_CENTER => 1, - PHPExcel_Style_Alignment::VERTICAL_BOTTOM => 2, - PHPExcel_Style_Alignment::VERTICAL_JUSTIFY => 3, - ); + private static $mapVAlignments = array( + PHPExcel_Style_Alignment::VERTICAL_TOP => 0, + PHPExcel_Style_Alignment::VERTICAL_CENTER => 1, + PHPExcel_Style_Alignment::VERTICAL_BOTTOM => 2, + PHPExcel_Style_Alignment::VERTICAL_JUSTIFY => 3, + ); + /** * Map to BIFF2-BIFF8 codes for vertical alignment * * @param string $vAlign * @return int */ - private static function _mapVAlign($vAlign) + private static function mapVAlign($vAlign) { - if (isset(self::$_mapVAlign[$vAlign])) { - return self::$_mapVAlign[$vAlign]; + if (isset(self::$mapVAlignments[$vAlign])) { + return self::$mapVAlignments[$vAlign]; } return 2; } @@ -505,15 +512,13 @@ private static function _mapVAlign($vAlign) * @param int $textRotation * @return int */ - private static function _mapTextRotation($textRotation) + private static function mapTextRotation($textRotation) { if ($textRotation >= 0) { return $textRotation; - } - if ($textRotation == -165) { + } elseif ($textRotation == -165) { return 255; - } - if ($textRotation < 0) { + } elseif ($textRotation < 0) { return 90 - $textRotation; } } @@ -524,7 +529,7 @@ private static function _mapTextRotation($textRotation) * @param string * @return int */ - private static function _mapLocked($locked) + private static function mapLocked($locked) { switch ($locked) { case PHPExcel_Style_Protection::PROTECTION_INHERIT: @@ -544,7 +549,7 @@ private static function _mapLocked($locked) * @param string * @return int */ - private static function _mapHidden($hidden) + private static function mapHidden($hidden) { switch ($hidden) { case PHPExcel_Style_Protection::PROTECTION_INHERIT: diff --git a/Classes/PHPExcel/Writer/PDF/Core.php b/Classes/PHPExcel/Writer/PDF/Core.php index 8075c555b..ec3254b9a 100644 --- a/Classes/PHPExcel/Writer/PDF/Core.php +++ b/Classes/PHPExcel/Writer/PDF/Core.php @@ -32,14 +32,14 @@ abstract class PHPExcel_Writer_PDF_Core extends PHPExcel_Writer_HTML * * @var string */ - protected $_tempDir = ''; + protected $tempDir = ''; /** * Font * * @var string */ - protected $_font = 'freesans'; + protected $font = 'freesans'; /** * Orientation (Over-ride) @@ -212,7 +212,7 @@ public function __construct(PHPExcel $phpExcel) { parent::__construct($phpExcel); $this->setUseInlineCss(true); - $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + $this->tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); } /** @@ -222,7 +222,7 @@ public function __construct(PHPExcel $phpExcel) */ public function getFont() { - return $this->_font; + return $this->font; } /** @@ -236,7 +236,7 @@ public function getFont() */ public function setFont($fontName) { - $this->_font = $fontName; + $this->font = $fontName; return $this; } @@ -291,7 +291,7 @@ public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATI */ public function getTempDir() { - return $this->_tempDir; + return $this->tempDir; } /** @@ -304,7 +304,7 @@ public function getTempDir() public function setTempDir($pValue = '') { if (is_dir($pValue)) { - $this->_tempDir = $pValue; + $this->tempDir = $pValue; } else { throw new PHPExcel_Writer_Exception("Directory does not exist: $pValue"); } From 7cd731e4168c1c6b6ee64c7ec56a4570b4d59340 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 20 May 2015 00:20:20 +0100 Subject: [PATCH 391/467] Feels like all the psr-2 work is finally entering its final lap.... of course, that's only step #1 in the grand roadmap, but it's a start --- Classes/PHPExcel/Worksheet.php | 506 ++++++++++----------- Classes/PHPExcel/Worksheet/PageMargins.php | 36 +- Classes/PHPExcel/Worksheet/Protection.php | 134 +++--- Classes/PHPExcel/Worksheet/SheetView.php | 4 +- 4 files changed, 335 insertions(+), 345 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 8004412d3..71c0addca 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -42,287 +42,287 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable * * @var array */ - private static $_invalidCharacters = array('*', ':', '/', '\\', '?', '[', ']'); + private static $invalidCharacters = array('*', ':', '/', '\\', '?', '[', ']'); /** * Parent spreadsheet * * @var PHPExcel */ - private $_parent; + private $parent; /** * Cacheable collection of cells * * @var PHPExcel_CachedObjectStorage_xxx */ - private $_cellCollection = null; + private $cellCollection; /** * Collection of row dimensions * * @var PHPExcel_Worksheet_RowDimension[] */ - private $_rowDimensions = array(); + private $rowDimensions = array(); /** * Default row dimension * * @var PHPExcel_Worksheet_RowDimension */ - private $_defaultRowDimension = null; + private $defaultRowDimension; /** * Collection of column dimensions * * @var PHPExcel_Worksheet_ColumnDimension[] */ - private $_columnDimensions = array(); + private $columnDimensions = array(); /** * Default column dimension * * @var PHPExcel_Worksheet_ColumnDimension */ - private $_defaultColumnDimension = null; + private $defaultColumnDimension = null; /** * Collection of drawings * * @var PHPExcel_Worksheet_BaseDrawing[] */ - private $_drawingCollection = null; + private $drawingCollection = null; /** * Collection of Chart objects * * @var PHPExcel_Chart[] */ - private $_chartCollection = array(); + private $chartCollection = array(); /** * Worksheet title * * @var string */ - private $_title; + private $title; /** * Sheet state * * @var string */ - private $_sheetState; + private $sheetState; /** * Page setup * * @var PHPExcel_Worksheet_PageSetup */ - private $_pageSetup; + private $pageSetup; /** * Page margins * * @var PHPExcel_Worksheet_PageMargins */ - private $_pageMargins; + private $pageMargins; /** * Page header/footer * * @var PHPExcel_Worksheet_HeaderFooter */ - private $_headerFooter; + private $headerFooter; /** * Sheet view * * @var PHPExcel_Worksheet_SheetView */ - private $_sheetView; + private $sheetView; /** * Protection * * @var PHPExcel_Worksheet_Protection */ - private $_protection; + private $protection; /** * Collection of styles * * @var PHPExcel_Style[] */ - private $_styles = array(); + private $styles = array(); /** * Conditional styles. Indexed by cell coordinate, e.g. 'A1' * * @var array */ - private $_conditionalStylesCollection = array(); + private $conditionalStylesCollection = array(); /** * Is the current cell collection sorted already? * * @var boolean */ - private $_cellCollectionIsSorted = false; + private $cellCollectionIsSorted = false; /** * Collection of breaks * * @var array */ - private $_breaks = array(); + private $breaks = array(); /** * Collection of merged cell ranges * * @var array */ - private $_mergeCells = array(); + private $mergeCells = array(); /** * Collection of protected cell ranges * * @var array */ - private $_protectedCells = array(); + private $protectedCells = array(); /** * Autofilter Range and selection * * @var PHPExcel_Worksheet_AutoFilter */ - private $_autoFilter = null; + private $autoFilter; /** * Freeze pane * * @var string */ - private $_freezePane = ''; + private $freezePane = ''; /** * Show gridlines? * * @var boolean */ - private $_showGridlines = true; + private $showGridlines = true; /** * Print gridlines? * * @var boolean */ - private $_printGridlines = false; + private $printGridlines = false; /** * Show row and column headers? * * @var boolean */ - private $_showRowColHeaders = true; + private $showRowColHeaders = true; /** * Show summary below? (Row/Column outline) * * @var boolean */ - private $_showSummaryBelow = true; + private $showSummaryBelow = true; /** * Show summary right? (Row/Column outline) * * @var boolean */ - private $_showSummaryRight = true; + private $showSummaryRight = true; /** * Collection of comments * * @var PHPExcel_Comment[] */ - private $_comments = array(); + private $comments = array(); /** * Active cell. (Only one!) * * @var string */ - private $_activeCell = 'A1'; + private $activeCell = 'A1'; /** * Selected cells * * @var string */ - private $_selectedCells = 'A1'; + private $selectedCells = 'A1'; /** * Cached highest column * * @var string */ - private $_cachedHighestColumn = 'A'; + private $cachedHighestColumn = 'A'; /** * Cached highest row * * @var int */ - private $_cachedHighestRow = 1; + private $cachedHighestRow = 1; /** * Right-to-left? * * @var boolean */ - private $_rightToLeft = false; + private $rightToLeft = false; /** * Hyperlinks. Indexed by cell coordinate, e.g. 'A1' * * @var array */ - private $_hyperlinkCollection = array(); + private $hyperlinkCollection = array(); /** * Data validation objects. Indexed by cell coordinate, e.g. 'A1' * * @var array */ - private $_dataValidationCollection = array(); + private $dataValidationCollection = array(); /** * Tab color * * @var PHPExcel_Style_Color */ - private $_tabColor; + private $tabColor; /** * Dirty flag * * @var boolean */ - private $_dirty = true; + private $dirty = true; /** * Hash * * @var string */ - private $_hash = null; + private $hash; /** * CodeName * * @var string */ - private $_codeName = null; + private $codeName = null; /** * Create a new worksheet @@ -333,42 +333,32 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') { // Set parent and title - $this->_parent = $pParent; + $this->parent = $pParent; $this->setTitle($pTitle, false); // setTitle can change $pTitle $this->setCodeName($this->getTitle()); $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE); - $this->_cellCollection = PHPExcel_CachedObjectStorageFactory::getInstance($this); - + $this->cellCollection = PHPExcel_CachedObjectStorageFactory::getInstance($this); // Set page setup - $this->_pageSetup = new PHPExcel_Worksheet_PageSetup(); - + $this->pageSetup = new PHPExcel_Worksheet_PageSetup(); // Set page margins - $this->_pageMargins = new PHPExcel_Worksheet_PageMargins(); - + $this->pageMargins = new PHPExcel_Worksheet_PageMargins(); // Set page header/footer - $this->_headerFooter = new PHPExcel_Worksheet_HeaderFooter(); - + $this->headerFooter = new PHPExcel_Worksheet_HeaderFooter(); // Set sheet view - $this->_sheetView = new PHPExcel_Worksheet_SheetView(); - + $this->sheetView = new PHPExcel_Worksheet_SheetView(); // Drawing collection - $this->_drawingCollection = new ArrayObject(); - + $this->drawingCollection = new ArrayObject(); // Chart collection - $this->_chartCollection = new ArrayObject(); - + $this->chartCollection = new ArrayObject(); // Protection - $this->_protection = new PHPExcel_Worksheet_Protection(); - + $this->protection = new PHPExcel_Worksheet_Protection(); // Default row dimension - $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(null); - + $this->defaultRowDimension = new PHPExcel_Worksheet_RowDimension(null); // Default column dimension - $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(null); - - $this->_autoFilter = new PHPExcel_Worksheet_AutoFilter(null, $this); + $this->defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(null); + $this->autoFilter = new PHPExcel_Worksheet_AutoFilter(null, $this); } @@ -379,12 +369,12 @@ public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') */ public function disconnectCells() { - if ($this->_cellCollection !== null) { - $this->_cellCollection->unsetWorksheetCells(); - $this->_cellCollection = null; + if ($this->cellCollection !== null) { + $this->cellCollection->unsetWorksheetCells(); + $this->cellCollection = null; } // detach ourself from the workbook, so that it can then delete this worksheet successfully - $this->_parent = null; + $this->parent = null; } /** @@ -393,7 +383,7 @@ public function disconnectCells() */ public function __destruct() { - PHPExcel_Calculation::getInstance($this->_parent)->clearCalculationCacheForWorksheet($this->_title); + PHPExcel_Calculation::getInstance($this->parent)->clearCalculationCacheForWorksheet($this->title); $this->disconnectCells(); } @@ -405,7 +395,7 @@ public function __destruct() */ public function getCellCacheController() { - return $this->_cellCollection; + return $this->cellCollection; } // function getCellCacheController() @@ -416,7 +406,7 @@ public function getCellCacheController() */ public static function getInvalidCharacters() { - return self::$_invalidCharacters; + return self::$invalidCharacters; } /** @@ -433,7 +423,7 @@ private static function _checkSheetCodeName($pValue) throw new PHPExcel_Exception('Sheet code name cannot be empty.'); } // Some of the printable ASCII characters are invalid: * : / \ ? [ ] and first and last characters cannot be a "'" - if ((str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) || + if ((str_replace(self::$invalidCharacters, '', $pValue) !== $pValue) || (PHPExcel_Shared_String::Substring($pValue, -1, 1)=='\'') || (PHPExcel_Shared_String::Substring($pValue, 0, 1)=='\'')) { throw new PHPExcel_Exception('Invalid character found in sheet code name'); @@ -457,7 +447,7 @@ private static function _checkSheetCodeName($pValue) private static function _checkSheetTitle($pValue) { // Some of the printable ASCII characters are invalid: * : / \ ? [ ] - if (str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) { + if (str_replace(self::$invalidCharacters, '', $pValue) !== $pValue) { throw new PHPExcel_Exception('Invalid character found in sheet title'); } @@ -481,8 +471,8 @@ public function getCellCollection($pSorted = true) // Re-order cell collection return $this->sortCellCollection(); } - if ($this->_cellCollection !== null) { - return $this->_cellCollection->getCellList(); + if ($this->cellCollection !== null) { + return $this->cellCollection->getCellList(); } return array(); } @@ -494,8 +484,8 @@ public function getCellCollection($pSorted = true) */ public function sortCellCollection() { - if ($this->_cellCollection !== null) { - return $this->_cellCollection->getSortedCellList(); + if ($this->cellCollection !== null) { + return $this->cellCollection->getSortedCellList(); } return array(); } @@ -507,7 +497,7 @@ public function sortCellCollection() */ public function getRowDimensions() { - return $this->_rowDimensions; + return $this->rowDimensions; } /** @@ -517,7 +507,7 @@ public function getRowDimensions() */ public function getDefaultRowDimension() { - return $this->_defaultRowDimension; + return $this->defaultRowDimension; } /** @@ -527,7 +517,7 @@ public function getDefaultRowDimension() */ public function getColumnDimensions() { - return $this->_columnDimensions; + return $this->columnDimensions; } /** @@ -537,7 +527,7 @@ public function getColumnDimensions() */ public function getDefaultColumnDimension() { - return $this->_defaultColumnDimension; + return $this->defaultColumnDimension; } /** @@ -547,7 +537,7 @@ public function getDefaultColumnDimension() */ public function getDrawingCollection() { - return $this->_drawingCollection; + return $this->drawingCollection; } /** @@ -557,7 +547,7 @@ public function getDrawingCollection() */ public function getChartCollection() { - return $this->_chartCollection; + return $this->chartCollection; } /** @@ -571,10 +561,10 @@ public function addChart(PHPExcel_Chart $pChart = null, $iChartIndex = null) { $pChart->setWorksheet($this); if (is_null($iChartIndex)) { - $this->_chartCollection[] = $pChart; + $this->chartCollection[] = $pChart; } else { // Insert the chart at the requested index - array_splice($this->_chartCollection, $iChartIndex, 0, array($pChart)); + array_splice($this->chartCollection, $iChartIndex, 0, array($pChart)); } return $pChart; @@ -587,7 +577,7 @@ public function addChart(PHPExcel_Chart $pChart = null, $iChartIndex = null) */ public function getChartCount() { - return count($this->_chartCollection); + return count($this->chartCollection); } /** @@ -599,18 +589,18 @@ public function getChartCount() */ public function getChartByIndex($index = null) { - $chartCount = count($this->_chartCollection); + $chartCount = count($this->chartCollection); if ($chartCount == 0) { return false; } if (is_null($index)) { $index = --$chartCount; } - if (!isset($this->_chartCollection[$index])) { + if (!isset($this->chartCollection[$index])) { return false; } - return $this->_chartCollection[$index]; + return $this->chartCollection[$index]; } /** @@ -622,7 +612,7 @@ public function getChartByIndex($index = null) public function getChartNames() { $chartNames = array(); - foreach ($this->_chartCollection as $chart) { + foreach ($this->chartCollection as $chart) { $chartNames[] = $chart->getName(); } return $chartNames; @@ -637,13 +627,13 @@ public function getChartNames() */ public function getChartByName($chartName = '') { - $chartCount = count($this->_chartCollection); + $chartCount = count($this->chartCollection); if ($chartCount == 0) { return false; } - foreach ($this->_chartCollection as $index => $chart) { + foreach ($this->chartCollection as $index => $chart) { if ($chart->getName() == $chartName) { - return $this->_chartCollection[$index]; + return $this->chartCollection[$index]; } } return false; @@ -663,7 +653,7 @@ public function refreshColumnDimensions() $newColumnDimensions[$objColumnDimension->getColumnIndex()] = $objColumnDimension; } - $this->_columnDimensions = $newColumnDimensions; + $this->columnDimensions = $newColumnDimensions; return $this; } @@ -682,7 +672,7 @@ public function refreshRowDimensions() $newRowDimensions[$objRowDimension->getRowIndex()] = $objRowDimension; } - $this->_rowDimensions = $newRowDimensions; + $this->rowDimensions = $newRowDimensions; return $this; } @@ -738,9 +728,9 @@ public function calculateColumnWidths($calculateMergeCells = false) // loop through all cells in the worksheet foreach ($this->getCellCollection(false) as $cellID) { $cell = $this->getCell($cellID); - if (isset($autoSizes[$this->_cellCollection->getCurrentColumn()])) { + if (isset($autoSizes[$this->cellCollection->getCurrentColumn()])) { // Determine width if cell does not participate in a merge - if (!isset($isMergeCell[$this->_cellCollection->getCurrentAddress()])) { + if (!isset($isMergeCell[$this->cellCollection->getCurrentAddress()])) { // Calculated value // To formatted string $cellValue = PHPExcel_Style_NumberFormat::toFormattedString( @@ -748,8 +738,8 @@ public function calculateColumnWidths($calculateMergeCells = false) $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode() ); - $autoSizes[$this->_cellCollection->getCurrentColumn()] = max( - (float) $autoSizes[$this->_cellCollection->getCurrentColumn()], + $autoSizes[$this->cellCollection->getCurrentColumn()] = max( + (float) $autoSizes[$this->cellCollection->getCurrentColumn()], (float)PHPExcel_Shared_Font::calculateColumnWidth( $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(), $cellValue, @@ -780,7 +770,7 @@ public function calculateColumnWidths($calculateMergeCells = false) */ public function getParent() { - return $this->_parent; + return $this->parent; } /** @@ -791,17 +781,17 @@ public function getParent() */ public function rebindParent(PHPExcel $parent) { - if ($this->_parent !== null) { - $namedRanges = $this->_parent->getNamedRanges(); + if ($this->parent !== null) { + $namedRanges = $this->parent->getNamedRanges(); foreach ($namedRanges as $namedRange) { $parent->addNamedRange($namedRange); } - $this->_parent->removeSheetByIndex( - $this->_parent->getIndex($this) + $this->parent->removeSheetByIndex( + $this->parent->getIndex($this) ); } - $this->_parent = $parent; + $this->parent = $parent; return $this; } @@ -813,7 +803,7 @@ public function rebindParent(PHPExcel $parent) */ public function getTitle() { - return $this->_title; + return $this->title; } /** @@ -840,16 +830,16 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t // Old title $oldTitle = $this->getTitle(); - if ($this->_parent) { + if ($this->parent) { // Is there already such sheet name? - if ($this->_parent->sheetNameExists($pValue)) { + if ($this->parent->sheetNameExists($pValue)) { // Use name, but append with lowest possible integer if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 29); } $i = 1; - while ($this->_parent->sheetNameExists($pValue . ' ' . $i)) { + while ($this->parent->sheetNameExists($pValue . ' ' . $i)) { ++$i; if ($i == 10) { if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { @@ -868,16 +858,16 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t } // Set title - $this->_title = $pValue; - $this->_dirty = true; + $this->title = $pValue; + $this->dirty = true; - if ($this->_parent) { + if ($this->parent) { // New title $newTitle = $this->getTitle(); - PHPExcel_Calculation::getInstance($this->_parent) + PHPExcel_Calculation::getInstance($this->parent) ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); if ($updateFormulaCellReferences) { - PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_parent, $oldTitle, $newTitle); + PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->parent, $oldTitle, $newTitle); } } @@ -891,7 +881,7 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t */ public function getSheetState() { - return $this->_sheetState; + return $this->sheetState; } /** @@ -902,7 +892,7 @@ public function getSheetState() */ public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) { - $this->_sheetState = $value; + $this->sheetState = $value; return $this; } @@ -913,7 +903,7 @@ public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) */ public function getPageSetup() { - return $this->_pageSetup; + return $this->pageSetup; } /** @@ -924,7 +914,7 @@ public function getPageSetup() */ public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue) { - $this->_pageSetup = $pValue; + $this->pageSetup = $pValue; return $this; } @@ -935,7 +925,7 @@ public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue) */ public function getPageMargins() { - return $this->_pageMargins; + return $this->pageMargins; } /** @@ -946,7 +936,7 @@ public function getPageMargins() */ public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue) { - $this->_pageMargins = $pValue; + $this->pageMargins = $pValue; return $this; } @@ -957,7 +947,7 @@ public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue) */ public function getHeaderFooter() { - return $this->_headerFooter; + return $this->headerFooter; } /** @@ -968,7 +958,7 @@ public function getHeaderFooter() */ public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue) { - $this->_headerFooter = $pValue; + $this->headerFooter = $pValue; return $this; } @@ -979,7 +969,7 @@ public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue) */ public function getSheetView() { - return $this->_sheetView; + return $this->sheetView; } /** @@ -990,7 +980,7 @@ public function getSheetView() */ public function setSheetView(PHPExcel_Worksheet_SheetView $pValue) { - $this->_sheetView = $pValue; + $this->sheetView = $pValue; return $this; } @@ -1001,7 +991,7 @@ public function setSheetView(PHPExcel_Worksheet_SheetView $pValue) */ public function getProtection() { - return $this->_protection; + return $this->protection; } /** @@ -1012,8 +1002,8 @@ public function getProtection() */ public function setProtection(PHPExcel_Worksheet_Protection $pValue) { - $this->_protection = $pValue; - $this->_dirty = true; + $this->protection = $pValue; + $this->dirty = true; return $this; } @@ -1028,7 +1018,7 @@ public function setProtection(PHPExcel_Worksheet_Protection $pValue) public function getHighestColumn($row = null) { if ($row == null) { - return $this->_cachedHighestColumn; + return $this->cachedHighestColumn; } return $this->getHighestDataColumn($row); } @@ -1042,7 +1032,7 @@ public function getHighestColumn($row = null) */ public function getHighestDataColumn($row = null) { - return $this->_cellCollection->getHighestColumn($row); + return $this->cellCollection->getHighestColumn($row); } /** @@ -1055,7 +1045,7 @@ public function getHighestDataColumn($row = null) public function getHighestRow($column = null) { if ($column == null) { - return $this->_cachedHighestRow; + return $this->cachedHighestRow; } return $this->getHighestDataRow($column); } @@ -1069,7 +1059,7 @@ public function getHighestRow($column = null) */ public function getHighestDataRow($column = null) { - return $this->_cellCollection->getHighestRow($column); + return $this->cellCollection->getHighestRow($column); } /** @@ -1079,7 +1069,7 @@ public function getHighestDataRow($column = null) */ public function getHighestRowAndColumn() { - return $this->_cellCollection->getHighestRowAndColumn(); + return $this->cellCollection->getHighestRowAndColumn(); } /** @@ -1153,14 +1143,14 @@ public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pVa public function getCell($pCoordinate = 'A1') { // Check cell collection - if ($this->_cellCollection->isDataSet(strtoupper($pCoordinate))) { - return $this->_cellCollection->getCacheData($pCoordinate); + if ($this->cellCollection->isDataSet(strtoupper($pCoordinate))) { + return $this->cellCollection->getCacheData($pCoordinate); } // Worksheet reference? if (strpos($pCoordinate, '!') !== false) { $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); - return $this->_parent->getSheetByName($worksheetReference[0])->getCell(strtoupper($worksheetReference[1])); + return $this->parent->getSheetByName($worksheetReference[0])->getCell(strtoupper($worksheetReference[1])); } // Named range? @@ -1198,8 +1188,8 @@ public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn); $coordinate = $columnLetter . $pRow; - if ($this->_cellCollection->isDataSet($coordinate)) { - return $this->_cellCollection->getCacheData($coordinate); + if ($this->cellCollection->isDataSet($coordinate)) { + return $this->cellCollection->getCacheData($coordinate); } return $this->_createNewCell($coordinate); @@ -1213,18 +1203,18 @@ public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) */ private function _createNewCell($pCoordinate) { - $cell = $this->_cellCollection->addCacheData( + $cell = $this->cellCollection->addCacheData( $pCoordinate, new PHPExcel_Cell(null, PHPExcel_Cell_DataType::TYPE_NULL, $this) ); - $this->_cellCollectionIsSorted = false; + $this->cellCollectionIsSorted = false; // Coordinates $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); - if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) { - $this->_cachedHighestColumn = $aCoordinates[0]; + if (PHPExcel_Cell::columnIndexFromString($this->cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) { + $this->cachedHighestColumn = $aCoordinates[0]; } - $this->_cachedHighestRow = max($this->_cachedHighestRow, $aCoordinates[1]); + $this->cachedHighestRow = max($this->cachedHighestRow, $aCoordinates[1]); // Cell needs appropriate xfIndex from dimensions records // but don't create dimension records if they don't already exist @@ -1254,7 +1244,7 @@ public function cellExists($pCoordinate = 'A1') // Worksheet reference? if (strpos($pCoordinate, '!') !== false) { $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); - return $this->_parent->getSheetByName($worksheetReference[0])->cellExists(strtoupper($worksheetReference[1])); + return $this->parent->getSheetByName($worksheetReference[0])->cellExists(strtoupper($worksheetReference[1])); } // Named range? @@ -1287,7 +1277,7 @@ public function cellExists($pCoordinate = 'A1') $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); // Cell exists? - return $this->_cellCollection->isDataSet($pCoordinate); + return $this->cellCollection->isDataSet($pCoordinate); } } @@ -1315,15 +1305,15 @@ public function getRowDimension($pRow = 1, $create = true) $found = null; // Get row dimension - if (!isset($this->_rowDimensions[$pRow])) { + if (!isset($this->rowDimensions[$pRow])) { if (!$create) { return null; } - $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow); + $this->rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow); - $this->_cachedHighestRow = max($this->_cachedHighestRow, $pRow); + $this->cachedHighestRow = max($this->cachedHighestRow, $pRow); } - return $this->_rowDimensions[$pRow]; + return $this->rowDimensions[$pRow]; } /** @@ -1338,17 +1328,17 @@ public function getColumnDimension($pColumn = 'A', $create = true) $pColumn = strtoupper($pColumn); // Fetch dimensions - if (!isset($this->_columnDimensions[$pColumn])) { + if (!isset($this->columnDimensions[$pColumn])) { if (!$create) { return null; } - $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn); + $this->columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn); - if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) { - $this->_cachedHighestColumn = $pColumn; + if (PHPExcel_Cell::columnIndexFromString($this->cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) { + $this->cachedHighestColumn = $pColumn; } } - return $this->_columnDimensions[$pColumn]; + return $this->columnDimensions[$pColumn]; } /** @@ -1369,7 +1359,7 @@ public function getColumnDimensionByColumn($pColumn = 0) */ public function getStyles() { - return $this->_styles; + return $this->styles; } /** @@ -1381,7 +1371,7 @@ public function getStyles() */ public function getDefaultStyle() { - return $this->_parent->getDefaultStyle(); + return $this->parent->getDefaultStyle(); } /** @@ -1394,7 +1384,7 @@ public function getDefaultStyle() */ public function setDefaultStyle(PHPExcel_Style $pValue) { - $this->_parent->getDefaultStyle()->applyFromArray(array( + $this->parent->getDefaultStyle()->applyFromArray(array( 'font' => array( 'name' => $pValue->getFont()->getName(), 'size' => $pValue->getFont()->getSize(), @@ -1413,12 +1403,12 @@ public function setDefaultStyle(PHPExcel_Style $pValue) public function getStyle($pCellCoordinate = 'A1') { // set this sheet as active - $this->_parent->setActiveSheetIndex($this->_parent->getIndex($this)); + $this->parent->setActiveSheetIndex($this->parent->getIndex($this)); // set cell coordinate as active $this->setSelectedCells(strtoupper($pCellCoordinate)); - return $this->_parent->getCellXfSupervisor(); + return $this->parent->getCellXfSupervisor(); } /** @@ -1430,10 +1420,10 @@ public function getStyle($pCellCoordinate = 'A1') public function getConditionalStyles($pCoordinate = 'A1') { $pCoordinate = strtoupper($pCoordinate); - if (!isset($this->_conditionalStylesCollection[$pCoordinate])) { - $this->_conditionalStylesCollection[$pCoordinate] = array(); + if (!isset($this->conditionalStylesCollection[$pCoordinate])) { + $this->conditionalStylesCollection[$pCoordinate] = array(); } - return $this->_conditionalStylesCollection[$pCoordinate]; + return $this->conditionalStylesCollection[$pCoordinate]; } /** @@ -1444,7 +1434,7 @@ public function getConditionalStyles($pCoordinate = 'A1') */ public function conditionalStylesExists($pCoordinate = 'A1') { - if (isset($this->_conditionalStylesCollection[strtoupper($pCoordinate)])) { + if (isset($this->conditionalStylesCollection[strtoupper($pCoordinate)])) { return true; } return false; @@ -1458,7 +1448,7 @@ public function conditionalStylesExists($pCoordinate = 'A1') */ public function removeConditionalStyles($pCoordinate = 'A1') { - unset($this->_conditionalStylesCollection[strtoupper($pCoordinate)]); + unset($this->conditionalStylesCollection[strtoupper($pCoordinate)]); return $this; } @@ -1469,7 +1459,7 @@ public function removeConditionalStyles($pCoordinate = 'A1') */ public function getConditionalStylesCollection() { - return $this->_conditionalStylesCollection; + return $this->conditionalStylesCollection; } /** @@ -1481,7 +1471,7 @@ public function getConditionalStylesCollection() */ public function setConditionalStyles($pCoordinate = 'A1', $pValue) { - $this->_conditionalStylesCollection[strtoupper($pCoordinate)] = $pValue; + $this->conditionalStylesCollection[strtoupper($pCoordinate)] = $pValue; return $this; } @@ -1537,8 +1527,8 @@ public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') $style = $pCellStyle->getIsSupervisor() ? $pCellStyle->getSharedComponent() : $pCellStyle; // Add the style to the workbook if necessary - $workbook = $this->_parent; - if ($existingStyle = $this->_parent->getCellXfByHashCode($pCellStyle->getHashCode())) { + $workbook = $this->parent; + if ($existingStyle = $this->parent->getCellXfByHashCode($pCellStyle->getHashCode())) { // there is already such cell Xf in our collection $xfIndex = $existingStyle->getIndex(); } else { @@ -1640,11 +1630,11 @@ public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE if ($pCell != '') { if ($pBreak == PHPExcel_Worksheet::BREAK_NONE) { - if (isset($this->_breaks[$pCell])) { - unset($this->_breaks[$pCell]); + if (isset($this->breaks[$pCell])) { + unset($this->breaks[$pCell]); } } else { - $this->_breaks[$pCell] = $pBreak; + $this->breaks[$pCell] = $pBreak; } } else { throw new PHPExcel_Exception('No cell coordinate specified.'); @@ -1673,7 +1663,7 @@ public function setBreakByColumnAndRow($pColumn = 0, $pRow = 1, $pBreak = PHPExc */ public function getBreaks() { - return $this->_breaks; + return $this->breaks; } /** @@ -1689,7 +1679,7 @@ public function mergeCells($pRange = 'A1:A1') $pRange = strtoupper($pRange); if (strpos($pRange, ':') !== false) { - $this->_mergeCells[$pRange] = $pRange; + $this->mergeCells[$pRange] = $pRange; // make sure cells are created @@ -1743,8 +1733,8 @@ public function unmergeCells($pRange = 'A1:A1') $pRange = strtoupper($pRange); if (strpos($pRange, ':') !== false) { - if (isset($this->_mergeCells[$pRange])) { - unset($this->_mergeCells[$pRange]); + if (isset($this->mergeCells[$pRange])) { + unset($this->mergeCells[$pRange]); } else { throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as merged.'); } @@ -1778,7 +1768,7 @@ public function unmergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 */ public function getMergeCells() { - return $this->_mergeCells; + return $this->mergeCells; } /** @@ -1789,7 +1779,7 @@ public function getMergeCells() */ public function setMergeCells($pValue = array()) { - $this->_mergeCells = $pValue; + $this->mergeCells = $pValue; return $this; } @@ -1810,7 +1800,7 @@ public function protectCells($pRange = 'A1', $pPassword = '', $pAlreadyHashed = if (!$pAlreadyHashed) { $pPassword = PHPExcel_Shared_PasswordHasher::hashPassword($pPassword); } - $this->_protectedCells[$pRange] = $pPassword; + $this->protectedCells[$pRange] = $pPassword; return $this; } @@ -1845,8 +1835,8 @@ public function unprotectCells($pRange = 'A1') // Uppercase coordinate $pRange = strtoupper($pRange); - if (isset($this->_protectedCells[$pRange])) { - unset($this->_protectedCells[$pRange]); + if (isset($this->protectedCells[$pRange])) { + unset($this->protectedCells[$pRange]); } else { throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as protected.'); } @@ -1878,7 +1868,7 @@ public function unprotectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn */ public function getProtectedCells() { - return $this->_protectedCells; + return $this->protectedCells; } /** @@ -1888,7 +1878,7 @@ public function getProtectedCells() */ public function getAutoFilter() { - return $this->_autoFilter; + return $this->autoFilter; } /** @@ -1903,9 +1893,9 @@ public function setAutoFilter($pValue) { $pRange = strtoupper($pValue); if (is_string($pValue)) { - $this->_autoFilter->setRange($pValue); + $this->autoFilter->setRange($pValue); } elseif (is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) { - $this->_autoFilter = $pValue; + $this->autoFilter = $pValue; } return $this; } @@ -1936,7 +1926,7 @@ public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 */ public function removeAutoFilter() { - $this->_autoFilter->setRange(null); + $this->autoFilter->setRange(null); return $this; } @@ -1947,7 +1937,7 @@ public function removeAutoFilter() */ public function getFreezePane() { - return $this->_freezePane; + return $this->freezePane; } /** @@ -1967,7 +1957,7 @@ public function freezePane($pCell = '') // Uppercase coordinate $pCell = strtoupper($pCell); if (strpos($pCell, ':') === false && strpos($pCell, ',') === false) { - $this->_freezePane = $pCell; + $this->freezePane = $pCell; } else { throw new PHPExcel_Exception('Freeze pane can not be set on a range of cells.'); } @@ -2125,7 +2115,7 @@ public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) */ public function getShowGridlines() { - return $this->_showGridlines; + return $this->showGridlines; } /** @@ -2136,7 +2126,7 @@ public function getShowGridlines() */ public function setShowGridlines($pValue = false) { - $this->_showGridlines = $pValue; + $this->showGridlines = $pValue; return $this; } @@ -2147,7 +2137,7 @@ public function setShowGridlines($pValue = false) */ public function getPrintGridlines() { - return $this->_printGridlines; + return $this->printGridlines; } /** @@ -2158,7 +2148,7 @@ public function getPrintGridlines() */ public function setPrintGridlines($pValue = false) { - $this->_printGridlines = $pValue; + $this->printGridlines = $pValue; return $this; } @@ -2169,7 +2159,7 @@ public function setPrintGridlines($pValue = false) */ public function getShowRowColHeaders() { - return $this->_showRowColHeaders; + return $this->showRowColHeaders; } /** @@ -2180,7 +2170,7 @@ public function getShowRowColHeaders() */ public function setShowRowColHeaders($pValue = false) { - $this->_showRowColHeaders = $pValue; + $this->showRowColHeaders = $pValue; return $this; } @@ -2191,7 +2181,7 @@ public function setShowRowColHeaders($pValue = false) */ public function getShowSummaryBelow() { - return $this->_showSummaryBelow; + return $this->showSummaryBelow; } /** @@ -2202,7 +2192,7 @@ public function getShowSummaryBelow() */ public function setShowSummaryBelow($pValue = true) { - $this->_showSummaryBelow = $pValue; + $this->showSummaryBelow = $pValue; return $this; } @@ -2213,7 +2203,7 @@ public function setShowSummaryBelow($pValue = true) */ public function getShowSummaryRight() { - return $this->_showSummaryRight; + return $this->showSummaryRight; } /** @@ -2224,7 +2214,7 @@ public function getShowSummaryRight() */ public function setShowSummaryRight($pValue = true) { - $this->_showSummaryRight = $pValue; + $this->showSummaryRight = $pValue; return $this; } @@ -2235,7 +2225,7 @@ public function setShowSummaryRight($pValue = true) */ public function getComments() { - return $this->_comments; + return $this->comments; } /** @@ -2246,7 +2236,7 @@ public function getComments() */ public function setComments($pValue = array()) { - $this->_comments = $pValue; + $this->comments = $pValue; return $this; } @@ -2272,11 +2262,11 @@ public function getComment($pCellCoordinate = 'A1') } else { // Check if we already have a comment for this cell. // If not, create a new comment. - if (isset($this->_comments[$pCellCoordinate])) { - return $this->_comments[$pCellCoordinate]; + if (isset($this->comments[$pCellCoordinate])) { + return $this->comments[$pCellCoordinate]; } else { $newComment = new PHPExcel_Comment(); - $this->_comments[$pCellCoordinate] = $newComment; + $this->comments[$pCellCoordinate] = $newComment; return $newComment; } } @@ -2312,7 +2302,7 @@ public function getSelectedCell() */ public function getActiveCell() { - return $this->_activeCell; + return $this->activeCell; } /** @@ -2322,7 +2312,7 @@ public function getActiveCell() */ public function getSelectedCells() { - return $this->_selectedCells; + return $this->selectedCells; } /** @@ -2362,11 +2352,11 @@ public function setSelectedCells($pCoordinate = 'A1') if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) { list($first, ) = PHPExcel_Cell::splitRange($pCoordinate); - $this->_activeCell = $first[0]; + $this->activeCell = $first[0]; } else { - $this->_activeCell = $pCoordinate; + $this->activeCell = $pCoordinate; } - $this->_selectedCells = $pCoordinate; + $this->selectedCells = $pCoordinate; return $this; } @@ -2390,7 +2380,7 @@ public function setSelectedCellByColumnAndRow($pColumn = 0, $pRow = 1) */ public function getRightToLeft() { - return $this->_rightToLeft; + return $this->rightToLeft; } /** @@ -2401,7 +2391,7 @@ public function getRightToLeft() */ public function setRightToLeft($value = false) { - $this->_rightToLeft = $value; + $this->rightToLeft = $value; return $this; } @@ -2483,10 +2473,10 @@ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormul for ($col = $minCol; $col != $maxCol; ++$col) { $cRef = ($returnCellRef) ? $col : ++$c; // Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen - // so we test and retrieve directly against _cellCollection - if ($this->_cellCollection->isDataSet($col.$row)) { + // so we test and retrieve directly against cellCollection + if ($this->cellCollection->isDataSet($col.$row)) { // Cell exists - $cell = $this->_cellCollection->getCacheData($col.$row); + $cell = $this->cellCollection->getCacheData($col.$row); if ($cell->getValue() !== null) { if ($cell->getValue() instanceof PHPExcel_RichText) { $returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText(); @@ -2499,7 +2489,7 @@ public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormul } if ($formatData) { - $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); + $style = $this->parent->getCellXfByIndex($cell->getXfIndex()); $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString( $returnValue[$rRef][$cRef], ($style && $style->getNumberFormat()) ? $style->getNumberFormat()->getFormatCode() : PHPExcel_Style_NumberFormat::FORMAT_GENERAL @@ -2603,7 +2593,7 @@ public function getColumnIterator($startColumn = 'A', $endColumn = null) public function garbageCollect() { // Flush cache - $this->_cellCollection->getCacheData('A1'); + $this->cellCollection->getCacheData('A1'); // Build a reference table from images // $imageCoordinates = array(); // $iterator = $this->getDrawingCollection()->getIterator(); @@ -2614,27 +2604,27 @@ public function garbageCollect() // } // // Lookup highest column and highest row if cells are cleaned - $colRow = $this->_cellCollection->getHighestRowAndColumn(); + $colRow = $this->cellCollection->getHighestRowAndColumn(); $highestRow = $colRow['row']; $highestColumn = PHPExcel_Cell::columnIndexFromString($colRow['column']); // Loop through column dimensions - foreach ($this->_columnDimensions as $dimension) { + foreach ($this->columnDimensions as $dimension) { $highestColumn = max($highestColumn, PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex())); } // Loop through row dimensions - foreach ($this->_rowDimensions as $dimension) { + foreach ($this->rowDimensions as $dimension) { $highestRow = max($highestRow, $dimension->getRowIndex()); } // Cache values if ($highestColumn < 0) { - $this->_cachedHighestColumn = 'A'; + $this->cachedHighestColumn = 'A'; } else { - $this->_cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn); + $this->cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn); } - $this->_cachedHighestRow = $highestRow; + $this->cachedHighestRow = $highestRow; // Return return $this; @@ -2647,11 +2637,11 @@ public function garbageCollect() */ public function getHashCode() { - if ($this->_dirty) { - $this->_hash = md5($this->_title . $this->_autoFilter . ($this->_protection->isProtectionEnabled() ? 't' : 'f') . __CLASS__); - $this->_dirty = false; + if ($this->dirty) { + $this->hash = md5($this->title . $this->autoFilter . ($this->protection->isProtectionEnabled() ? 't' : 'f') . __CLASS__); + $this->dirty = false; } - return $this->_hash; + return $this->hash; } /** @@ -2686,13 +2676,13 @@ public static function extractSheetTitle($pRange, $returnRange = false) public function getHyperlink($pCellCoordinate = 'A1') { // return hyperlink if we already have one - if (isset($this->_hyperlinkCollection[$pCellCoordinate])) { - return $this->_hyperlinkCollection[$pCellCoordinate]; + if (isset($this->hyperlinkCollection[$pCellCoordinate])) { + return $this->hyperlinkCollection[$pCellCoordinate]; } // else create hyperlink - $this->_hyperlinkCollection[$pCellCoordinate] = new PHPExcel_Cell_Hyperlink(); - return $this->_hyperlinkCollection[$pCellCoordinate]; + $this->hyperlinkCollection[$pCellCoordinate] = new PHPExcel_Cell_Hyperlink(); + return $this->hyperlinkCollection[$pCellCoordinate]; } /** @@ -2705,9 +2695,9 @@ public function getHyperlink($pCellCoordinate = 'A1') public function setHyperlink($pCellCoordinate = 'A1', PHPExcel_Cell_Hyperlink $pHyperlink = null) { if ($pHyperlink === null) { - unset($this->_hyperlinkCollection[$pCellCoordinate]); + unset($this->hyperlinkCollection[$pCellCoordinate]); } else { - $this->_hyperlinkCollection[$pCellCoordinate] = $pHyperlink; + $this->hyperlinkCollection[$pCellCoordinate] = $pHyperlink; } return $this; } @@ -2720,7 +2710,7 @@ public function setHyperlink($pCellCoordinate = 'A1', PHPExcel_Cell_Hyperlink $p */ public function hyperlinkExists($pCoordinate = 'A1') { - return isset($this->_hyperlinkCollection[$pCoordinate]); + return isset($this->hyperlinkCollection[$pCoordinate]); } /** @@ -2730,7 +2720,7 @@ public function hyperlinkExists($pCoordinate = 'A1') */ public function getHyperlinkCollection() { - return $this->_hyperlinkCollection; + return $this->hyperlinkCollection; } /** @@ -2741,13 +2731,13 @@ public function getHyperlinkCollection() public function getDataValidation($pCellCoordinate = 'A1') { // return data validation if we already have one - if (isset($this->_dataValidationCollection[$pCellCoordinate])) { - return $this->_dataValidationCollection[$pCellCoordinate]; + if (isset($this->dataValidationCollection[$pCellCoordinate])) { + return $this->dataValidationCollection[$pCellCoordinate]; } // else create data validation - $this->_dataValidationCollection[$pCellCoordinate] = new PHPExcel_Cell_DataValidation(); - return $this->_dataValidationCollection[$pCellCoordinate]; + $this->dataValidationCollection[$pCellCoordinate] = new PHPExcel_Cell_DataValidation(); + return $this->dataValidationCollection[$pCellCoordinate]; } /** @@ -2760,9 +2750,9 @@ public function getDataValidation($pCellCoordinate = 'A1') public function setDataValidation($pCellCoordinate = 'A1', PHPExcel_Cell_DataValidation $pDataValidation = null) { if ($pDataValidation === null) { - unset($this->_dataValidationCollection[$pCellCoordinate]); + unset($this->dataValidationCollection[$pCellCoordinate]); } else { - $this->_dataValidationCollection[$pCellCoordinate] = $pDataValidation; + $this->dataValidationCollection[$pCellCoordinate] = $pDataValidation; } return $this; } @@ -2775,7 +2765,7 @@ public function setDataValidation($pCellCoordinate = 'A1', PHPExcel_Cell_DataVal */ public function dataValidationExists($pCoordinate = 'A1') { - return isset($this->_dataValidationCollection[$pCoordinate]); + return isset($this->dataValidationCollection[$pCoordinate]); } /** @@ -2785,7 +2775,7 @@ public function dataValidationExists($pCoordinate = 'A1') */ public function getDataValidationCollection() { - return $this->_dataValidationCollection; + return $this->dataValidationCollection; } /** @@ -2831,10 +2821,10 @@ public function shrinkRangeToFit($range) */ public function getTabColor() { - if ($this->_tabColor === null) { - $this->_tabColor = new PHPExcel_Style_Color(); + if ($this->tabColor === null) { + $this->tabColor = new PHPExcel_Style_Color(); } - return $this->_tabColor; + return $this->tabColor; } /** @@ -2844,8 +2834,8 @@ public function getTabColor() */ public function resetTabColor() { - $this->_tabColor = null; - unset($this->_tabColor); + $this->tabColor = null; + unset($this->tabColor); return $this; } @@ -2857,7 +2847,7 @@ public function resetTabColor() */ public function isTabColorSet() { - return ($this->_tabColor !== null); + return ($this->tabColor !== null); } /** @@ -2878,22 +2868,22 @@ public function copy() public function __clone() { foreach ($this as $key => $val) { - if ($key == '_parent') { + if ($key == 'parent') { continue; } if (is_object($val) || (is_array($val))) { - if ($key == '_cellCollection') { - $newCollection = clone $this->_cellCollection; + if ($key == 'cellCollection') { + $newCollection = clone $this->cellCollection; $newCollection->copyCellCollection($this); - $this->_cellCollection = $newCollection; - } elseif ($key == '_drawingCollection') { - $newCollection = clone $this->_drawingCollection; - $this->_drawingCollection = $newCollection; - } elseif (($key == '_autoFilter') && ($this->_autoFilter instanceof PHPExcel_Worksheet_AutoFilter)) { - $newAutoFilter = clone $this->_autoFilter; - $this->_autoFilter = $newAutoFilter; - $this->_autoFilter->setParent($this); + $this->cellCollection = $newCollection; + } elseif ($key == 'drawingCollection') { + $newCollection = clone $this->drawingCollection; + $this->drawingCollection = $newCollection; + } elseif (($key == 'autoFilter') && ($this->autoFilter instanceof PHPExcel_Worksheet_AutoFilter)) { + $newAutoFilter = clone $this->autoFilter; + $this->autoFilter = $newAutoFilter; + $this->autoFilter->setParent($this); } else { $this->{$key} = unserialize(serialize($val)); } @@ -2948,7 +2938,7 @@ public function setCodeName($pValue = null) } } - $this->_codeName=$pValue; + $this->codeName=$pValue; return $this; } /** @@ -2958,7 +2948,7 @@ public function setCodeName($pValue = null) */ public function getCodeName() { - return $this->_codeName; + return $this->codeName; } /** * Sheet has a code name ? @@ -2966,6 +2956,6 @@ public function getCodeName() */ public function hasCodeName() { - return !(is_null($this->_codeName)); + return !(is_null($this->codeName)); } } diff --git a/Classes/PHPExcel/Worksheet/PageMargins.php b/Classes/PHPExcel/Worksheet/PageMargins.php index afc269fd7..70f5ee0f5 100644 --- a/Classes/PHPExcel/Worksheet/PageMargins.php +++ b/Classes/PHPExcel/Worksheet/PageMargins.php @@ -40,42 +40,42 @@ class PHPExcel_Worksheet_PageMargins * * @var double */ - private $_left = 0.7; + private $left = 0.7; /** * Right * * @var double */ - private $_right = 0.7; + private $right = 0.7; /** * Top * * @var double */ - private $_top = 0.75; + private $top = 0.75; /** * Bottom * * @var double */ - private $_bottom = 0.75; + private $bottom = 0.75; /** * Header * * @var double */ - private $_header = 0.3; + private $header = 0.3; /** * Footer * * @var double */ - private $_footer = 0.3; + private $footer = 0.3; /** * Create a new PHPExcel_Worksheet_PageMargins @@ -91,7 +91,7 @@ public function __construct() */ public function getLeft() { - return $this->_left; + return $this->left; } /** @@ -102,7 +102,7 @@ public function getLeft() */ public function setLeft($pValue) { - $this->_left = $pValue; + $this->left = $pValue; return $this; } @@ -113,7 +113,7 @@ public function setLeft($pValue) */ public function getRight() { - return $this->_right; + return $this->right; } /** @@ -124,7 +124,7 @@ public function getRight() */ public function setRight($pValue) { - $this->_right = $pValue; + $this->right = $pValue; return $this; } @@ -135,7 +135,7 @@ public function setRight($pValue) */ public function getTop() { - return $this->_top; + return $this->top; } /** @@ -146,7 +146,7 @@ public function getTop() */ public function setTop($pValue) { - $this->_top = $pValue; + $this->top = $pValue; return $this; } @@ -157,7 +157,7 @@ public function setTop($pValue) */ public function getBottom() { - return $this->_bottom; + return $this->bottom; } /** @@ -168,7 +168,7 @@ public function getBottom() */ public function setBottom($pValue) { - $this->_bottom = $pValue; + $this->bottom = $pValue; return $this; } @@ -179,7 +179,7 @@ public function setBottom($pValue) */ public function getHeader() { - return $this->_header; + return $this->header; } /** @@ -190,7 +190,7 @@ public function getHeader() */ public function setHeader($pValue) { - $this->_header = $pValue; + $this->header = $pValue; return $this; } @@ -201,7 +201,7 @@ public function setHeader($pValue) */ public function getFooter() { - return $this->_footer; + return $this->footer; } /** @@ -212,7 +212,7 @@ public function getFooter() */ public function setFooter($pValue) { - $this->_footer = $pValue; + $this->footer = $pValue; return $this; } diff --git a/Classes/PHPExcel/Worksheet/Protection.php b/Classes/PHPExcel/Worksheet/Protection.php index d84e6e9c8..00633eeb7 100644 --- a/Classes/PHPExcel/Worksheet/Protection.php +++ b/Classes/PHPExcel/Worksheet/Protection.php @@ -40,119 +40,119 @@ class PHPExcel_Worksheet_Protection * * @var boolean */ - private $_sheet = false; + private $sheet = false; /** * Objects * * @var boolean */ - private $_objects = false; + private $objects = false; /** * Scenarios * * @var boolean */ - private $_scenarios = false; + private $scenarios = false; /** * Format cells * * @var boolean */ - private $_formatCells = false; + private $formatCells = false; /** * Format columns * * @var boolean */ - private $_formatColumns = false; + private $formatColumns = false; /** * Format rows * * @var boolean */ - private $_formatRows = false; + private $formatRows = false; /** * Insert columns * * @var boolean */ - private $_insertColumns = false; + private $insertColumns = false; /** * Insert rows * * @var boolean */ - private $_insertRows = false; + private $insertRows = false; /** * Insert hyperlinks * * @var boolean */ - private $_insertHyperlinks = false; + private $insertHyperlinks = false; /** * Delete columns * * @var boolean */ - private $_deleteColumns = false; + private $deleteColumns = false; /** * Delete rows * * @var boolean */ - private $_deleteRows = false; + private $deleteRows = false; /** * Select locked cells * * @var boolean */ - private $_selectLockedCells = false; + private $selectLockedCells = false; /** * Sort * * @var boolean */ - private $_sort = false; + private $sort = false; /** * AutoFilter * * @var boolean */ - private $_autoFilter = false; + private $autoFilter = false; /** * Pivot tables * * @var boolean */ - private $_pivotTables = false; + private $pivotTables = false; /** * Select unlocked cells * * @var boolean */ - private $_selectUnlockedCells = false; + private $selectUnlockedCells = false; /** * Password * * @var string */ - private $_password = ''; + private $password = ''; /** * Create a new PHPExcel_Worksheet_Protection @@ -168,22 +168,22 @@ public function __construct() */ public function isProtectionEnabled() { - return $this->_sheet || - $this->_objects || - $this->_scenarios || - $this->_formatCells || - $this->_formatColumns || - $this->_formatRows || - $this->_insertColumns || - $this->_insertRows || - $this->_insertHyperlinks || - $this->_deleteColumns || - $this->_deleteRows || - $this->_selectLockedCells || - $this->_sort || - $this->_autoFilter || - $this->_pivotTables || - $this->_selectUnlockedCells; + return $this->sheet || + $this->objects || + $this->scenarios || + $this->formatCells || + $this->formatColumns || + $this->formatRows || + $this->insertColumns || + $this->insertRows || + $this->insertHyperlinks || + $this->deleteColumns || + $this->deleteRows || + $this->selectLockedCells || + $this->sort || + $this->autoFilter || + $this->pivotTables || + $this->selectUnlockedCells; } /** @@ -193,7 +193,7 @@ public function isProtectionEnabled() */ public function getSheet() { - return $this->_sheet; + return $this->sheet; } /** @@ -204,7 +204,7 @@ public function getSheet() */ public function setSheet($pValue = false) { - $this->_sheet = $pValue; + $this->sheet = $pValue; return $this; } @@ -215,7 +215,7 @@ public function setSheet($pValue = false) */ public function getObjects() { - return $this->_objects; + return $this->objects; } /** @@ -226,7 +226,7 @@ public function getObjects() */ public function setObjects($pValue = false) { - $this->_objects = $pValue; + $this->objects = $pValue; return $this; } @@ -237,7 +237,7 @@ public function setObjects($pValue = false) */ public function getScenarios() { - return $this->_scenarios; + return $this->scenarios; } /** @@ -248,7 +248,7 @@ public function getScenarios() */ public function setScenarios($pValue = false) { - $this->_scenarios = $pValue; + $this->scenarios = $pValue; return $this; } @@ -259,7 +259,7 @@ public function setScenarios($pValue = false) */ public function getFormatCells() { - return $this->_formatCells; + return $this->formatCells; } /** @@ -270,7 +270,7 @@ public function getFormatCells() */ public function setFormatCells($pValue = false) { - $this->_formatCells = $pValue; + $this->formatCells = $pValue; return $this; } @@ -281,7 +281,7 @@ public function setFormatCells($pValue = false) */ public function getFormatColumns() { - return $this->_formatColumns; + return $this->formatColumns; } /** @@ -292,7 +292,7 @@ public function getFormatColumns() */ public function setFormatColumns($pValue = false) { - $this->_formatColumns = $pValue; + $this->formatColumns = $pValue; return $this; } @@ -303,7 +303,7 @@ public function setFormatColumns($pValue = false) */ public function getFormatRows() { - return $this->_formatRows; + return $this->formatRows; } /** @@ -314,7 +314,7 @@ public function getFormatRows() */ public function setFormatRows($pValue = false) { - $this->_formatRows = $pValue; + $this->formatRows = $pValue; return $this; } @@ -325,7 +325,7 @@ public function setFormatRows($pValue = false) */ public function getInsertColumns() { - return $this->_insertColumns; + return $this->insertColumns; } /** @@ -336,7 +336,7 @@ public function getInsertColumns() */ public function setInsertColumns($pValue = false) { - $this->_insertColumns = $pValue; + $this->insertColumns = $pValue; return $this; } @@ -347,7 +347,7 @@ public function setInsertColumns($pValue = false) */ public function getInsertRows() { - return $this->_insertRows; + return $this->insertRows; } /** @@ -358,7 +358,7 @@ public function getInsertRows() */ public function setInsertRows($pValue = false) { - $this->_insertRows = $pValue; + $this->insertRows = $pValue; return $this; } @@ -369,7 +369,7 @@ public function setInsertRows($pValue = false) */ public function getInsertHyperlinks() { - return $this->_insertHyperlinks; + return $this->insertHyperlinks; } /** @@ -380,7 +380,7 @@ public function getInsertHyperlinks() */ public function setInsertHyperlinks($pValue = false) { - $this->_insertHyperlinks = $pValue; + $this->insertHyperlinks = $pValue; return $this; } @@ -391,7 +391,7 @@ public function setInsertHyperlinks($pValue = false) */ public function getDeleteColumns() { - return $this->_deleteColumns; + return $this->deleteColumns; } /** @@ -402,7 +402,7 @@ public function getDeleteColumns() */ public function setDeleteColumns($pValue = false) { - $this->_deleteColumns = $pValue; + $this->deleteColumns = $pValue; return $this; } @@ -413,7 +413,7 @@ public function setDeleteColumns($pValue = false) */ public function getDeleteRows() { - return $this->_deleteRows; + return $this->deleteRows; } /** @@ -424,7 +424,7 @@ public function getDeleteRows() */ public function setDeleteRows($pValue = false) { - $this->_deleteRows = $pValue; + $this->deleteRows = $pValue; return $this; } @@ -435,7 +435,7 @@ public function setDeleteRows($pValue = false) */ public function getSelectLockedCells() { - return $this->_selectLockedCells; + return $this->selectLockedCells; } /** @@ -446,7 +446,7 @@ public function getSelectLockedCells() */ public function setSelectLockedCells($pValue = false) { - $this->_selectLockedCells = $pValue; + $this->selectLockedCells = $pValue; return $this; } @@ -457,7 +457,7 @@ public function setSelectLockedCells($pValue = false) */ public function getSort() { - return $this->_sort; + return $this->sort; } /** @@ -468,7 +468,7 @@ public function getSort() */ public function setSort($pValue = false) { - $this->_sort = $pValue; + $this->sort = $pValue; return $this; } @@ -479,7 +479,7 @@ public function setSort($pValue = false) */ public function getAutoFilter() { - return $this->_autoFilter; + return $this->autoFilter; } /** @@ -490,7 +490,7 @@ public function getAutoFilter() */ public function setAutoFilter($pValue = false) { - $this->_autoFilter = $pValue; + $this->autoFilter = $pValue; return $this; } @@ -501,7 +501,7 @@ public function setAutoFilter($pValue = false) */ public function getPivotTables() { - return $this->_pivotTables; + return $this->pivotTables; } /** @@ -512,7 +512,7 @@ public function getPivotTables() */ public function setPivotTables($pValue = false) { - $this->_pivotTables = $pValue; + $this->pivotTables = $pValue; return $this; } @@ -523,7 +523,7 @@ public function setPivotTables($pValue = false) */ public function getSelectUnlockedCells() { - return $this->_selectUnlockedCells; + return $this->selectUnlockedCells; } /** @@ -534,7 +534,7 @@ public function getSelectUnlockedCells() */ public function setSelectUnlockedCells($pValue = false) { - $this->_selectUnlockedCells = $pValue; + $this->selectUnlockedCells = $pValue; return $this; } @@ -545,7 +545,7 @@ public function setSelectUnlockedCells($pValue = false) */ public function getPassword() { - return $this->_password; + return $this->password; } /** @@ -560,7 +560,7 @@ public function setPassword($pValue = '', $pAlreadyHashed = false) if (!$pAlreadyHashed) { $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); } - $this->_password = $pValue; + $this->password = $pValue; return $this; } diff --git a/Classes/PHPExcel/Worksheet/SheetView.php b/Classes/PHPExcel/Worksheet/SheetView.php index c7a7d5bf1..5aaef3ba3 100644 --- a/Classes/PHPExcel/Worksheet/SheetView.php +++ b/Classes/PHPExcel/Worksheet/SheetView.php @@ -33,7 +33,7 @@ class PHPExcel_Worksheet_SheetView const SHEETVIEW_PAGE_LAYOUT = 'pageLayout'; const SHEETVIEW_PAGE_BREAK_PREVIEW = 'pageBreakPreview'; - private static $_sheetViewTypes = array( + private static $sheetViewTypes = array( self::SHEETVIEW_NORMAL, self::SHEETVIEW_PAGE_LAYOUT, self::SHEETVIEW_PAGE_BREAK_PREVIEW, @@ -161,7 +161,7 @@ public function setView($pValue = null) if ($pValue === null) { $pValue = self::SHEETVIEW_NORMAL; } - if (in_array($pValue, self::$_sheetViewTypes)) { + if (in_array($pValue, self::$sheetViewTypes)) { $this->sheetviewType = $pValue; } else { throw new PHPExcel_Exception("Invalid sheetview layout type."); From 0c177b5ea2ac2b87d6161d9a9acbdb95e222c879 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 20 May 2015 19:17:17 +0100 Subject: [PATCH 392/467] We modified another block of files to psr-2, and their jaws dropped when they saw what happened next --- Classes/PHPExcel/Reader/Abstract.php | 52 +- Classes/PHPExcel/Reader/CSV.php | 80 +- Classes/PHPExcel/Reader/DefaultReadFilter.php | 36 +- Classes/PHPExcel/Reader/Excel2003XML.php | 50 +- Classes/PHPExcel/Reader/Excel2007.php | 238 +- Classes/PHPExcel/Reader/Excel5.php | 2403 ++++++++--------- Classes/PHPExcel/Reader/Excel5/Escher.php | 86 +- Classes/PHPExcel/Reader/Exception.php | 12 +- Classes/PHPExcel/Reader/Gnumeric.php | 74 +- Classes/PHPExcel/Reader/HTML.php | 147 +- Classes/PHPExcel/Reader/IReadFilter.php | 6 +- Classes/PHPExcel/Reader/IReader.php | 12 +- Classes/PHPExcel/Reader/OOCalc.php | 8 +- Classes/PHPExcel/Reader/SYLK.php | 52 +- Classes/PHPExcel/Shared/CodePage.php | 149 +- Classes/PHPExcel/Shared/OLERead.php | 34 +- Classes/PHPExcel/Worksheet/AutoFilter.php | 134 +- .../PHPExcel/Worksheet/AutoFilter/Column.php | 104 +- .../Worksheet/AutoFilter/Column/Rule.php | 206 +- Classes/PHPExcel/Worksheet/BaseDrawing.php | 36 +- Classes/PHPExcel/Worksheet/Drawing.php | 32 +- Classes/PHPExcel/Worksheet/Drawing/Shadow.php | 100 +- Classes/PHPExcel/Worksheet/HeaderFooter.php | 120 +- .../Worksheet/HeaderFooterDrawing.php | 120 +- Classes/PHPExcel/Worksheet/MemoryDrawing.php | 80 +- Classes/PHPExcel/Worksheet/PageSetup.php | 124 +- Classes/PHPExcel/Writer/Abstract.php | 6 +- Classes/PHPExcel/Writer/Excel2007.php | 14 +- Classes/PHPExcel/Writer/HTML.php | 334 +-- Classes/PHPExcel/Writer/PDF/Core.php | 4 +- Classes/PHPExcel/Writer/PDF/DomPDF.php | 12 +- Classes/PHPExcel/Writer/PDF/mPDF.php | 22 +- Classes/PHPExcel/Writer/PDF/tcPDF.php | 22 +- .../Calculation/MathTrig/QUOTIENT.data | 2 +- 34 files changed, 2383 insertions(+), 2528 deletions(-) diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php index 08f8dbd13..5902574b9 100644 --- a/Classes/PHPExcel/Reader/Abstract.php +++ b/Classes/PHPExcel/Reader/Abstract.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Reader_Abstract * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Reader_Abstract - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { /** @@ -42,7 +34,7 @@ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader * * @var boolean */ - protected $_readDataOnly = false; + protected $readDataOnly = false; /** * Read charts that are defined in the workbook? @@ -50,7 +42,7 @@ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader * * @var boolean */ - protected $_includeCharts = false; + protected $includeCharts = false; /** * Restrict which sheets should be loaded? @@ -58,16 +50,16 @@ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader * * @var array of string */ - protected $_loadSheetsOnly = null; + protected $loadSheetsOnly; /** * PHPExcel_Reader_IReadFilter instance * * @var PHPExcel_Reader_IReadFilter */ - protected $_readFilter = null; + protected $readFilter; - protected $_fileHandle = null; + protected $fileHandle = null; /** @@ -79,7 +71,7 @@ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader */ public function getReadDataOnly() { - return $this->_readDataOnly; + return $this->readDataOnly; } /** @@ -93,7 +85,7 @@ public function getReadDataOnly() */ public function setReadDataOnly($pValue = false) { - $this->_readDataOnly = $pValue; + $this->readDataOnly = $pValue; return $this; } @@ -107,7 +99,7 @@ public function setReadDataOnly($pValue = false) */ public function getIncludeCharts() { - return $this->_includeCharts; + return $this->includeCharts; } /** @@ -122,7 +114,7 @@ public function getIncludeCharts() */ public function setIncludeCharts($pValue = false) { - $this->_includeCharts = (boolean) $pValue; + $this->includeCharts = (boolean) $pValue; return $this; } @@ -135,7 +127,7 @@ public function setIncludeCharts($pValue = false) */ public function getLoadSheetsOnly() { - return $this->_loadSheetsOnly; + return $this->loadSheetsOnly; } /** @@ -153,7 +145,7 @@ public function setLoadSheetsOnly($value = null) return $this->setLoadAllSheets(); } - $this->_loadSheetsOnly = is_array($value) ? $value : array($value); + $this->loadSheetsOnly = is_array($value) ? $value : array($value); return $this; } @@ -165,7 +157,7 @@ public function setLoadSheetsOnly($value = null) */ public function setLoadAllSheets() { - $this->_loadSheetsOnly = null; + $this->loadSheetsOnly = null; return $this; } @@ -176,7 +168,7 @@ public function setLoadAllSheets() */ public function getReadFilter() { - return $this->_readFilter; + return $this->readFilter; } /** @@ -187,7 +179,7 @@ public function getReadFilter() */ public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) { - $this->_readFilter = $pValue; + $this->readFilter = $pValue; return $this; } @@ -198,7 +190,7 @@ public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) * @throws PHPExcel_Reader_Exception * @return resource */ - protected function _openFile($pFilename) + protected function openFile($pFilename) { // Check if file exists if (!file_exists($pFilename) || !is_readable($pFilename)) { @@ -206,8 +198,8 @@ protected function _openFile($pFilename) } // Open file - $this->_fileHandle = fopen($pFilename, 'r'); - if ($this->_fileHandle === false) { + $this->fileHandle = fopen($pFilename, 'r'); + if ($this->fileHandle === false) { throw new PHPExcel_Reader_Exception("Could not open file " . $pFilename . " for reading."); } } @@ -223,13 +215,13 @@ public function canRead($pFilename) { // Check if file exists try { - $this->_openFile($pFilename); + $this->openFile($pFilename); } catch (Exception $e) { return false; } - $readable = $this->_isValidFormat(); - fclose($this->_fileHandle); + $readable = $this->isValidFormat(); + fclose($this->fileHandle); return $readable; } diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index 65e2d3b64..db96b6084 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -1,6 +1,16 @@ <?php + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + /** - * PHPExcel + * PHPExcel_Reader_CSV * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,24 +34,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** PHPExcel root directory */ -if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); -} - -/** - * PHPExcel_Reader_CSV - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { /** @@ -97,7 +89,7 @@ class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_R */ public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); } /** @@ -105,7 +97,7 @@ public function __construct() * * @return boolean */ - protected function _isValidFormat() + protected function isValidFormat() { return true; } @@ -135,30 +127,30 @@ public function getInputEncoding() * Move filepointer past any BOM marker * */ - protected function _skipBOM() + protected function skipBOM() { - rewind($this->_fileHandle); + rewind($this->fileHandle); switch ($this->inputEncoding) { case 'UTF-8': - fgets($this->_fileHandle, 4) == "\xEF\xBB\xBF" ? - fseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0); + fgets($this->fileHandle, 4) == "\xEF\xBB\xBF" ? + fseek($this->fileHandle, 3) : fseek($this->fileHandle, 0); break; case 'UTF-16LE': - fgets($this->_fileHandle, 3) == "\xFF\xFE" ? - fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); + fgets($this->fileHandle, 3) == "\xFF\xFE" ? + fseek($this->fileHandle, 2) : fseek($this->fileHandle, 0); break; case 'UTF-16BE': - fgets($this->_fileHandle, 3) == "\xFE\xFF" ? - fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); + fgets($this->fileHandle, 3) == "\xFE\xFF" ? + fseek($this->fileHandle, 2) : fseek($this->fileHandle, 0); break; case 'UTF-32LE': - fgets($this->_fileHandle, 5) == "\xFF\xFE\x00\x00" ? - fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); + fgets($this->fileHandle, 5) == "\xFF\xFE\x00\x00" ? + fseek($this->fileHandle, 4) : fseek($this->fileHandle, 0); break; case 'UTF-32BE': - fgets($this->_fileHandle, 5) == "\x00\x00\xFE\xFF" ? - fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); + fgets($this->fileHandle, 5) == "\x00\x00\xFE\xFF" ? + fseek($this->fileHandle, 4) : fseek($this->fileHandle, 0); break; default: break; @@ -174,15 +166,15 @@ protected function _skipBOM() public function listWorksheetInfo($pFilename) { // Open file - $this->_openFile($pFilename); - if (!$this->_isValidFormat()) { - fclose($this->_fileHandle); + $this->openFile($pFilename); + if (!$this->isValidFormat()) { + fclose($this->fileHandle); throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } - $fileHandle = $this->_fileHandle; + $fileHandle = $this->fileHandle; // Skip BOM, if any - $this->_skipBOM(); + $this->skipBOM(); $escapeEnclosures = array( "\\" . $this->enclosure, $this->enclosure . $this->enclosure ); @@ -238,15 +230,15 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) ini_set('auto_detect_line_endings', true); // Open file - $this->_openFile($pFilename); - if (!$this->_isValidFormat()) { - fclose($this->_fileHandle); + $this->openFile($pFilename); + if (!$this->isValidFormat()) { + fclose($this->fileHandle); throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } - $fileHandle = $this->_fileHandle; + $fileHandle = $this->fileHandle; // Skip BOM, if any - $this->_skipBOM(); + $this->skipBOM(); // Create new PHPExcel object while ($objPHPExcel->getSheetCount() <= $this->sheetIndex) { @@ -268,7 +260,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) { $columnLetter = 'A'; foreach ($rowData as $rowDatum) { - if ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) { + if ($rowDatum != '' && $this->readFilter->readCell($columnLetter, $currentRow)) { // Unescape enclosures $rowDatum = str_replace($escapeEnclosures, $this->enclosure, $rowDatum); diff --git a/Classes/PHPExcel/Reader/DefaultReadFilter.php b/Classes/PHPExcel/Reader/DefaultReadFilter.php index 2e06dcbd4..ea25f63c5 100644 --- a/Classes/PHPExcel/Reader/DefaultReadFilter.php +++ b/Classes/PHPExcel/Reader/DefaultReadFilter.php @@ -1,6 +1,16 @@ <?php + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + /** - * PHPExcel + * PHPExcel_Reader_DefaultReadFilter * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,33 +34,15 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** PHPExcel root directory */ -if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); -} - -/** - * PHPExcel_Reader_DefaultReadFilter - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_DefaultReadFilter implements PHPExcel_Reader_IReadFilter { /** * Should this cell be read? * - * @param $column String column index - * @param $row Row index + * @param $column Column address (as a string value like "A", or "IV") + * @param $row Row number * @param $worksheetName Optional worksheet name - * @return boolean + * @return boolean */ public function readCell($column, $row, $worksheetName = '') { diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index feb0aaa02..fb1ebc01b 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -55,7 +55,7 @@ class PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements P */ public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); } @@ -85,8 +85,8 @@ public function canRead($pFilename) ); // Open file - $this->_openFile($pFilename); - $fileHandle = $this->_fileHandle; + $this->openFile($pFilename); + $fileHandle = $this->fileHandle; // Read sample data (first 2 KB will do) $data = fread($fileHandle, 2048); @@ -135,7 +135,7 @@ public function listWorksheetNames($pFilename) $xml_ss = $xml->children($namespaces['ss']); foreach ($xml_ss->Worksheet as $worksheet) { $worksheet_ss = $worksheet->attributes($namespaces['ss']); - $worksheetNames[] = self::_convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet); + $worksheetNames[] = self::convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet); } return $worksheetNames; @@ -247,7 +247,7 @@ protected static function identifyFixedStyleValue($styleList, &$styleAttributeVa * @param pxs * @return */ - protected static function _pixel2WidthUnits($pxs) + protected static function pixel2WidthUnits($pxs) { $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); @@ -261,7 +261,7 @@ protected static function _pixel2WidthUnits($pxs) * @param widthUnits * @return */ - protected static function _widthUnits2Pixel($widthUnits) + protected static function widthUnits2Pixel($widthUnits) { $pixels = ($widthUnits / 256) * 7; $offsetWidthUnits = $widthUnits % 256; @@ -269,7 +269,7 @@ protected static function _widthUnits2Pixel($widthUnits) return $pixels; } - protected static function _hex2str($hex) + protected static function hex2str($hex) { return chr(hexdec($hex[1])); } @@ -329,39 +329,39 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($xml->DocumentProperties[0] as $propertyName => $propertyValue) { switch ($propertyName) { case 'Title': - $docProps->setTitle(self::_convertStringEncoding($propertyValue, $this->charSet)); + $docProps->setTitle(self::convertStringEncoding($propertyValue, $this->charSet)); break; case 'Subject': - $docProps->setSubject(self::_convertStringEncoding($propertyValue, $this->charSet)); + $docProps->setSubject(self::convertStringEncoding($propertyValue, $this->charSet)); break; case 'Author': - $docProps->setCreator(self::_convertStringEncoding($propertyValue, $this->charSet)); + $docProps->setCreator(self::convertStringEncoding($propertyValue, $this->charSet)); break; case 'Created': $creationDate = strtotime($propertyValue); $docProps->setCreated($creationDate); break; case 'LastAuthor': - $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue, $this->charSet)); + $docProps->setLastModifiedBy(self::convertStringEncoding($propertyValue, $this->charSet)); break; case 'LastSaved': $lastSaveDate = strtotime($propertyValue); $docProps->setModified($lastSaveDate); break; case 'Company': - $docProps->setCompany(self::_convertStringEncoding($propertyValue, $this->charSet)); + $docProps->setCompany(self::convertStringEncoding($propertyValue, $this->charSet)); break; case 'Category': - $docProps->setCategory(self::_convertStringEncoding($propertyValue, $this->charSet)); + $docProps->setCategory(self::convertStringEncoding($propertyValue, $this->charSet)); break; case 'Manager': - $docProps->setManager(self::_convertStringEncoding($propertyValue, $this->charSet)); + $docProps->setManager(self::convertStringEncoding($propertyValue, $this->charSet)); break; case 'Keywords': - $docProps->setKeywords(self::_convertStringEncoding($propertyValue, $this->charSet)); + $docProps->setKeywords(self::convertStringEncoding($propertyValue, $this->charSet)); break; case 'Description': - $docProps->setDescription(self::_convertStringEncoding($propertyValue, $this->charSet)); + $docProps->setDescription(self::convertStringEncoding($propertyValue, $this->charSet)); break; } } @@ -369,7 +369,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if (isset($xml->CustomDocumentProperties)) { foreach ($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { $propertyAttributes = $propertyValue->attributes($namespaces['dt']); - $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/', 'PHPExcel_Reader_Excel2003XML::_hex2str', $propertyName); + $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/', 'PHPExcel_Reader_Excel2003XML::hex2str', $propertyName); $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN; switch ((string) $propertyAttributes) { case 'string': @@ -531,8 +531,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($xml_ss->Worksheet as $worksheet) { $worksheet_ss = $worksheet->attributes($namespaces['ss']); - if ((isset($this->_loadSheetsOnly)) && (isset($worksheet_ss['Name'])) && - (!in_array($worksheet_ss['Name'], $this->_loadSheetsOnly))) { + if ((isset($this->loadSheetsOnly)) && (isset($worksheet_ss['Name'])) && + (!in_array($worksheet_ss['Name'], $this->loadSheetsOnly))) { continue; } @@ -542,7 +542,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $objPHPExcel->createSheet(); $objPHPExcel->setActiveSheetIndex($worksheetID); if (isset($worksheet_ss['Name'])) { - $worksheetName = self::_convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet); + $worksheetName = self::convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet); // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in // formula cells... during the load, all formulae should be correct, and we're simply bringing // the worksheet name in line with the formula, not the reverse @@ -632,7 +632,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) const TYPE_ERROR = 'e'; */ case 'String': - $cellValue = self::_convertStringEncoding($cellValue, $this->charSet); + $cellValue = self::convertStringEncoding($cellValue, $this->charSet); $type = PHPExcel_Cell_DataType::TYPE_STRING; break; case 'Number': @@ -740,7 +740,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // echo $annotation,'<br />'; $annotation = strip_tags($node); // echo 'Annotation: ', $annotation,'<br />'; - $objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setAuthor(self::_convertStringEncoding($author, $this->charSet))->setText($this->_parseRichText($annotation)); + $objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setAuthor(self::convertStringEncoding($author, $this->charSet))->setText($this->parseRichText($annotation)); } if (($cellIsSet) && (isset($cell_ss['StyleID']))) { @@ -785,7 +785,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } - protected static function _convertStringEncoding($string, $charset) + protected static function convertStringEncoding($string, $charset) { if ($charset != 'UTF-8') { return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $charset); @@ -794,11 +794,11 @@ protected static function _convertStringEncoding($string, $charset) } - protected function _parseRichText($is = '') + protected function parseRichText($is = '') { $value = new PHPExcel_RichText(); - $value->createText(self::_convertStringEncoding($is, $this->charSet)); + $value->createText(self::convertStringEncoding($is, $this->charSet)); return $value; } diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 47a130e3c..2903313e2 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -55,7 +55,7 @@ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPE */ public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); $this->referenceHelper = PHPExcel_ReferenceHelper::getInstance(); } @@ -85,7 +85,7 @@ public function canRead($pFilename) $zip = new $zipClass; if ($zip->open($pFilename) === true) { // check if it is an OOXML archive - $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $rels = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if ($rels !== false) { foreach ($rels->Relationship as $rel) { switch ($rel["Type"]) { @@ -127,13 +127,13 @@ public function listWorksheetNames($pFilename) // The files we're looking at here are small enough that simpleXML is more efficient than XMLReader $rels = simplexml_load_string( - $this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) + $this->securityScan($this->getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($rels->Relationship as $rel) { switch ($rel["Type"]) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": $xmlWorkbook = simplexml_load_string( - $this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) + $this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) ); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); if ($xmlWorkbook->sheets) { @@ -171,11 +171,11 @@ public function listWorksheetInfo($pFilename) $zip = new $zipClass; $zip->open($pFilename); - $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $rels = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($rels->Relationship as $rel) { if ($rel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument") { $dir = dirname($rel["Target"]); - $relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); $worksheets = array(); @@ -185,7 +185,7 @@ public function listWorksheetInfo($pFilename) } } - $xmlWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlWorkbook = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); if ($xmlWorkbook->sheets) { $dir = dirname($rel["Target"]); foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { @@ -197,7 +197,7 @@ public function listWorksheetInfo($pFilename) 'totalColumns' => 0, ); - $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + $fileWorksheet = $worksheets[(string) self::getArrayItem($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; $xml = new XMLReader(); $res = $xml->xml($this->securityScanFile('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet"), null, PHPExcel_Settings::getLibXmlLoaderOptions()); @@ -299,7 +299,7 @@ private function castToFormula($c, $r, &$cellDataType, &$value, &$calculatedValu } - public function _getFromZipArchive($archive, $fileName = '') + private function getFromZipArchive($archive, $fileName = '') { // Root-relative paths if (strpos($fileName, '//') !== false) { @@ -334,7 +334,7 @@ public function load($pFilename) // Initialisations $excel = new PHPExcel; $excel->removeSheetByIndex(0); - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { $excel->removeCellStyleXfByIndex(0); // remove the default style $excel->removeCellXfByIndex(0); // remove the default style } @@ -345,14 +345,14 @@ public function load($pFilename) $zip->open($pFilename); // Read the theme first, because we need the colour scheme when reading the styles - $wbRels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $wbRels = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "xl/_rels/workbook.xml.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($wbRels->Relationship as $rel) { switch ($rel["Type"]) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme": $themeOrderArray = array('lt1', 'dk1', 'lt2', 'dk2'); $themeOrderAdditional = count($themeOrderArray); - $xmlTheme = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "xl/{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xmlTheme = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "xl/{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlTheme)) { $xmlThemeName = $xmlTheme->attributes(); $xmlTheme = $xmlTheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); @@ -382,29 +382,29 @@ public function load($pFilename) } } - $rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $rels = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "_rels/.rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($rels->Relationship as $rel) { switch ($rel["Type"]) { case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties": - $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xmlCore = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { $xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/"); $xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/"); $xmlCore->registerXPathNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"); $docProps = $excel->getProperties(); - $docProps->setCreator((string) self::array_item($xmlCore->xpath("dc:creator"))); - $docProps->setLastModifiedBy((string) self::array_item($xmlCore->xpath("cp:lastModifiedBy"))); - $docProps->setCreated(strtotime(self::array_item($xmlCore->xpath("dcterms:created")))); //! respect xsi:type - $docProps->setModified(strtotime(self::array_item($xmlCore->xpath("dcterms:modified")))); //! respect xsi:type - $docProps->setTitle((string) self::array_item($xmlCore->xpath("dc:title"))); - $docProps->setDescription((string) self::array_item($xmlCore->xpath("dc:description"))); - $docProps->setSubject((string) self::array_item($xmlCore->xpath("dc:subject"))); - $docProps->setKeywords((string) self::array_item($xmlCore->xpath("cp:keywords"))); - $docProps->setCategory((string) self::array_item($xmlCore->xpath("cp:category"))); + $docProps->setCreator((string) self::getArrayItem($xmlCore->xpath("dc:creator"))); + $docProps->setLastModifiedBy((string) self::getArrayItem($xmlCore->xpath("cp:lastModifiedBy"))); + $docProps->setCreated(strtotime(self::getArrayItem($xmlCore->xpath("dcterms:created")))); //! respect xsi:type + $docProps->setModified(strtotime(self::getArrayItem($xmlCore->xpath("dcterms:modified")))); //! respect xsi:type + $docProps->setTitle((string) self::getArrayItem($xmlCore->xpath("dc:title"))); + $docProps->setDescription((string) self::getArrayItem($xmlCore->xpath("dc:description"))); + $docProps->setSubject((string) self::getArrayItem($xmlCore->xpath("dc:subject"))); + $docProps->setKeywords((string) self::getArrayItem($xmlCore->xpath("cp:keywords"))); + $docProps->setCategory((string) self::getArrayItem($xmlCore->xpath("cp:category"))); } break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties": - $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xmlCore = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { $docProps = $excel->getProperties(); if (isset($xmlCore->Company)) { @@ -416,7 +416,7 @@ public function load($pFilename) } break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties": - $xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $xmlCore = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); if (is_object($xmlCore)) { $docProps = $excel->getProperties(); foreach ($xmlCore as $xmlProperty) { @@ -442,12 +442,12 @@ public function load($pFilename) break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": $dir = dirname($rel["Target"]); - $relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); $sharedStrings = array(); - $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']")); - $xmlStrings = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xpath = self::getArrayItem($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']")); + $xmlStrings = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); if (isset($xmlStrings) && isset($xmlStrings->si)) { foreach ($xmlStrings->si as $val) { if (isset($val->t)) { @@ -473,12 +473,12 @@ public function load($pFilename) } if (!is_null($macros)) { - $macrosCode = $this->_getFromZipArchive($zip, 'xl/vbaProject.bin');//vbaProject.bin always in 'xl' dir and always named vbaProject.bin + $macrosCode = $this->getFromZipArchive($zip, 'xl/vbaProject.bin');//vbaProject.bin always in 'xl' dir and always named vbaProject.bin if ($macrosCode !== false) { $excel->setMacrosCode($macrosCode); $excel->setHasMacros(true); //short-circuit : not reading vbaProject.bin.rel to get Signature =>allways vbaProjectSignature.bin in 'xl' dir - $Certificate = $this->_getFromZipArchive($zip, 'xl/vbaProjectSignature.bin'); + $Certificate = $this->getFromZipArchive($zip, 'xl/vbaProjectSignature.bin'); if ($Certificate !== false) { $excel->setMacrosCertificate($Certificate); } @@ -486,8 +486,8 @@ public function load($pFilename) } $styles = array(); $cellStyles = array(); - $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); - $xmlStyles = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xpath = self::getArrayItem($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); + $xmlStyles = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); $numFmts = null; if ($xmlStyles && $xmlStyles->numFmts[0]) { $numFmts = $xmlStyles->numFmts[0]; @@ -495,13 +495,13 @@ public function load($pFilename) if (isset($numFmts) && ($numFmts !== null)) { $numFmts->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); } - if (!$this->_readDataOnly && $xmlStyles) { + if (!$this->readDataOnly && $xmlStyles) { foreach ($xmlStyles->cellXfs->xf as $xf) { $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; if ($xf["numFmtId"]) { if (isset($numFmts)) { - $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); + $tmpNumFmt = self::getArrayItem($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); if (isset($tmpNumFmt["formatCode"])) { $numFmt = (string) $tmpNumFmt["formatCode"]; @@ -539,7 +539,7 @@ public function load($pFilename) foreach ($xmlStyles->cellStyleXfs->xf as $xf) { $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; if ($numFmts && $xf["numFmtId"]) { - $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); + $tmpNumFmt = self::getArrayItem($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); if (isset($tmpNumFmt["formatCode"])) { $numFmt = (string) $tmpNumFmt["formatCode"]; } elseif ((int)$xf["numFmtId"] < 165) { @@ -566,7 +566,7 @@ public function load($pFilename) } $dxfs = array(); - if (!$this->_readDataOnly && $xmlStyles) { + if (!$this->readDataOnly && $xmlStyles) { // Conditional Styles if ($xmlStyles->dxfs) { foreach ($xmlStyles->dxfs->dxf as $dxf) { @@ -591,7 +591,7 @@ public function load($pFilename) } } - $xmlWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlWorkbook = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); // Set base date if ($xmlWorkbook->workbookPr) { @@ -615,7 +615,7 @@ public function load($pFilename) ++$oldSheetId; // Check if sheet should be skipped - if (isset($this->_loadSheetsOnly) && !in_array((string) $eleSheet["name"], $this->_loadSheetsOnly)) { + if (isset($this->loadSheetsOnly) && !in_array((string) $eleSheet["name"], $this->loadSheetsOnly)) { ++$countSkippedSheets; $mapSheetId[$oldSheetId] = null; continue; @@ -632,8 +632,8 @@ public function load($pFilename) // and we're simply bringing the worksheet name in line with the formula, not the // reverse $docSheet->setTitle((string) $eleSheet["name"], false); - $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; - $xmlSheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "$dir/$fileWorksheet")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $fileWorksheet = $worksheets[(string) self::getArrayItem($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + $xmlSheet = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "$dir/$fileWorksheet")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); $sharedFormulas = array(); @@ -737,10 +737,10 @@ public function load($pFilename) } } - if (isset($xmlSheet->cols) && !$this->_readDataOnly) { + if (isset($xmlSheet->cols) && !$this->readDataOnly) { foreach ($xmlSheet->cols->col as $col) { for ($i = intval($col["min"]) - 1; $i < intval($col["max"]); ++$i) { - if ($col["style"] && !$this->_readDataOnly) { + if ($col["style"] && !$this->readDataOnly) { $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setXfIndex(intval($col["style"])); } if (self::boolean($col["bestFit"])) { @@ -765,7 +765,7 @@ public function load($pFilename) } } - if (isset($xmlSheet->printOptions) && !$this->_readDataOnly) { + if (isset($xmlSheet->printOptions) && !$this->readDataOnly) { if (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) { $docSheet->setShowGridlines(true); } @@ -782,10 +782,10 @@ public function load($pFilename) if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) { foreach ($xmlSheet->sheetData->row as $row) { - if ($row["ht"] && !$this->_readDataOnly) { + if ($row["ht"] && !$this->readDataOnly) { $docSheet->getRowDimension(intval($row["r"]))->setRowHeight(floatval($row["ht"])); } - if (self::boolean($row["hidden"]) && !$this->_readDataOnly) { + if (self::boolean($row["hidden"]) && !$this->readDataOnly) { $docSheet->getRowDimension(intval($row["r"]))->setVisible(false); } if (self::boolean($row["collapsed"])) { @@ -794,7 +794,7 @@ public function load($pFilename) if ($row["outlineLevel"] > 0) { $docSheet->getRowDimension(intval($row["r"]))->setOutlineLevel(intval($row["outlineLevel"])); } - if ($row["s"] && !$this->_readDataOnly) { + if ($row["s"] && !$this->readDataOnly) { $docSheet->getRowDimension(intval($row["r"]))->setXfIndex(intval($row["s"])); } @@ -888,7 +888,7 @@ public function load($pFilename) } // Rich text? - if ($value instanceof PHPExcel_RichText && $this->_readDataOnly) { + if ($value instanceof PHPExcel_RichText && $this->readDataOnly) { $value = $value->getPlainText(); } @@ -904,7 +904,7 @@ public function load($pFilename) } // Style information? - if ($c["s"] && !$this->_readDataOnly) { + if ($c["s"] && !$this->readDataOnly) { // no style index means 0, it seems $cell->setXfIndex(isset($styles[intval($c["s"])]) ? intval($c["s"]) : 0); @@ -914,7 +914,7 @@ public function load($pFilename) } $conditionals = array(); - if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) { + if (!$this->readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) { foreach ($xmlSheet->conditionalFormatting as $conditional) { foreach ($conditional->cfRule as $cfRule) { if (((string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_NONE || (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CELLIS || (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT || (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) && isset($dxfs[intval($cfRule["dxfId"])])) { @@ -955,14 +955,14 @@ public function load($pFilename) } $aKeys = array("sheet", "objects", "scenarios", "formatCells", "formatColumns", "formatRows", "insertColumns", "insertRows", "insertHyperlinks", "deleteColumns", "deleteRows", "selectLockedCells", "sort", "autoFilter", "pivotTables", "selectUnlockedCells"); - if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { + if (!$this->readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { foreach ($aKeys as $key) { $method = "set" . ucfirst($key); $docSheet->getProtection()->$method(self::boolean((string) $xmlSheet->sheetProtection[$key])); } } - if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { + if (!$this->readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { $docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection["password"], true); if ($xmlSheet->protectedRanges->protectedRange) { foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) { @@ -971,7 +971,7 @@ public function load($pFilename) } } - if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { + if ($xmlSheet && $xmlSheet->autoFilter && !$this->readDataOnly) { $autoFilterRange = (string) $xmlSheet->autoFilter["ref"]; if (strpos($autoFilterRange, ':') !== false) { $autoFilter = $docSheet->getAutoFilter(); @@ -1071,7 +1071,7 @@ public function load($pFilename) } } - if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) { + if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->readDataOnly) { foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) { $mergeRef = (string) $mergeCell["ref"]; if (strpos($mergeRef, ':') !== false) { @@ -1080,7 +1080,7 @@ public function load($pFilename) } } - if ($xmlSheet && $xmlSheet->pageMargins && !$this->_readDataOnly) { + if ($xmlSheet && $xmlSheet->pageMargins && !$this->readDataOnly) { $docPageMargins = $docSheet->getPageMargins(); $docPageMargins->setLeft(floatval($xmlSheet->pageMargins["left"])); $docPageMargins->setRight(floatval($xmlSheet->pageMargins["right"])); @@ -1090,7 +1090,7 @@ public function load($pFilename) $docPageMargins->setFooter(floatval($xmlSheet->pageMargins["footer"])); } - if ($xmlSheet && $xmlSheet->pageSetup && !$this->_readDataOnly) { + if ($xmlSheet && $xmlSheet->pageSetup && !$this->readDataOnly) { $docPageSetup = $docSheet->getPageSetup(); if (isset($xmlSheet->pageSetup["orientation"])) { @@ -1114,7 +1114,7 @@ public function load($pFilename) } } - if ($xmlSheet && $xmlSheet->headerFooter && !$this->_readDataOnly) { + if ($xmlSheet && $xmlSheet->headerFooter && !$this->readDataOnly) { $docHeaderFooter = $docSheet->getHeaderFooter(); if (isset($xmlSheet->headerFooter["differentOddEven"]) && @@ -1150,14 +1150,14 @@ public function load($pFilename) $docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter); } - if ($xmlSheet && $xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk && !$this->_readDataOnly) { + if ($xmlSheet && $xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk && !$this->readDataOnly) { foreach ($xmlSheet->rowBreaks->brk as $brk) { if ($brk["man"]) { $docSheet->setBreak("A$brk[id]", PHPExcel_Worksheet::BREAK_ROW); } } } - if ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->_readDataOnly) { + if ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->readDataOnly) { foreach ($xmlSheet->colBreaks->brk as $brk) { if ($brk["man"]) { $docSheet->setBreak(PHPExcel_Cell::stringFromColumnIndex((string) $brk["id"]) . "1", PHPExcel_Worksheet::BREAK_COLUMN); @@ -1165,7 +1165,7 @@ public function load($pFilename) } } - if ($xmlSheet && $xmlSheet->dataValidations && !$this->_readDataOnly) { + if ($xmlSheet && $xmlSheet->dataValidations && !$this->readDataOnly) { foreach ($xmlSheet->dataValidations->dataValidation as $dataValidation) { // Uppercase coordinate $range = strtoupper($dataValidation["sqref"]); @@ -1198,10 +1198,10 @@ public function load($pFilename) // Add hyperlinks $hyperlinks = array(); - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // Locate hyperlink relations if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") { $hyperlinks[(string)$ele["Id"]] = (string)$ele["Target"]; @@ -1239,10 +1239,10 @@ public function load($pFilename) // Add comments $comments = array(); $vmlComments = array(); - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // Locate comment relations if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") { $comments[(string)$ele["Id"]] = (string)$ele["Target"]; @@ -1257,7 +1257,7 @@ public function load($pFilename) foreach ($comments as $relName => $relPath) { // Load comments file $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); - $commentsFile = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $commentsFile = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); // Utility variables $authors = array(); @@ -1280,7 +1280,7 @@ public function load($pFilename) foreach ($vmlComments as $relName => $relPath) { // Load VML comments file $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); - $vmlCommentsFile = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $vmlCommentsFile = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); $shapes = $vmlCommentsFile->xpath('//v:shape'); @@ -1342,29 +1342,29 @@ public function load($pFilename) } // Header/footer images - if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) { + if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->readDataOnly) { if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $vmlRelationship = ''; foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") { - $vmlRelationship = self::dir_add("$dir/$fileWorksheet", $ele["Target"]); + $vmlRelationship = self::dirAdd("$dir/$fileWorksheet", $ele["Target"]); } } if ($vmlRelationship != '') { // Fetch linked images - $relsVML = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsVML = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $drawings = array(); foreach ($relsVML->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { - $drawings[(string) $ele["Id"]] = self::dir_add($vmlRelationship, $ele["Target"]); + $drawings[(string) $ele["Id"]] = self::dirAdd($vmlRelationship, $ele["Target"]); } } // Fetch VML document - $vmlDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $vmlRelationship)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $vmlDrawing = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, $vmlRelationship)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); $hfImages = array(); @@ -1403,26 +1403,26 @@ public function load($pFilename) // TODO: Autoshapes from twoCellAnchors! if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { - $relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorksheet = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $drawings = array(); foreach ($relsWorksheet->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing") { - $drawings[(string) $ele["Id"]] = self::dir_add("$dir/$fileWorksheet", $ele["Target"]); + $drawings[(string) $ele["Id"]] = self::dirAdd("$dir/$fileWorksheet", $ele["Target"]); } } - if ($xmlSheet->drawing && !$this->_readDataOnly) { + if ($xmlSheet->drawing && !$this->readDataOnly) { foreach ($xmlSheet->drawing as $drawing) { - $fileDrawing = $drawings[(string) self::array_item($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; - $relsDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $fileDrawing = $drawings[(string) self::getArrayItem($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + $relsDrawing = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); $images = array(); if ($relsDrawing && $relsDrawing->Relationship) { foreach ($relsDrawing->Relationship as $ele) { if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { - $images[(string) $ele["Id"]] = self::dir_add($fileDrawing, $ele["Target"]); + $images[(string) $ele["Id"]] = self::dirAdd($fileDrawing, $ele["Target"]); } elseif ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart") { - if ($this->_includeCharts) { - $charts[self::dir_add($fileDrawing, $ele["Target"])] = array( + if ($this->includeCharts) { + $charts[self::dirAdd($fileDrawing, $ele["Target"])] = array( 'id' => (string) $ele["Id"], 'sheet' => $docSheet->getTitle() ); @@ -1430,7 +1430,7 @@ public function load($pFilename) } } } - $xmlDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $fileDrawing)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"); + $xmlDrawing = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, $fileDrawing)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"); if ($xmlDrawing->oneCellAnchor) { foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) { @@ -1439,27 +1439,27 @@ public function load($pFilename) $xfrm = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm; $outerShdw = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw; $objDrawing = new PHPExcel_Worksheet_Drawing; - $objDrawing->setName((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); - $objDrawing->setDescription((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); - $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); + $objDrawing->setName((string) self::getArrayItem($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); + $objDrawing->setDescription((string) self::getArrayItem($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); + $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::getArrayItem($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1)); $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff)); $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff)); $objDrawing->setResizeProportional(false); - $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx"))); - $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy"))); + $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), "cx"))); + $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), "cy"))); if ($xfrm) { - $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); + $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::getArrayItem($xfrm->attributes(), "rot"))); } if ($outerShdw) { $shadow = $objDrawing->getShadow(); $shadow->setVisible(true); - $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad"))); - $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist"))); - $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir"))); - $shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn")); - $shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val")); - $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); + $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::getArrayItem($outerShdw->attributes(), "blurRad"))); + $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::getArrayItem($outerShdw->attributes(), "dist"))); + $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::getArrayItem($outerShdw->attributes(), "dir"))); + $shadow->setAlignment((string) self::getArrayItem($outerShdw->attributes(), "algn")); + $shadow->getColor()->setRGB(self::getArrayItem($outerShdw->srgbClr->attributes(), "val")); + $shadow->setAlpha(self::getArrayItem($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); } $objDrawing->setWorksheet($docSheet); } else { @@ -1467,8 +1467,8 @@ public function load($pFilename) $coordinates = PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1); $offsetX = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff); $offsetY = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff); - $width = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx")); - $height = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy")); + $width = PHPExcel_Shared_Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), "cx")); + $height = PHPExcel_Shared_Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), "cy")); } } } @@ -1479,31 +1479,31 @@ public function load($pFilename) $xfrm = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm; $outerShdw = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw; $objDrawing = new PHPExcel_Worksheet_Drawing; - $objDrawing->setName((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); - $objDrawing->setDescription((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); - $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); + $objDrawing->setName((string) self::getArrayItem($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); + $objDrawing->setDescription((string) self::getArrayItem($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); + $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::getArrayItem($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1)); $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff)); $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff)); $objDrawing->setResizeProportional(false); if ($xfrm) { - $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cx"))); - $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cy"))); - $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); + $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::getArrayItem($xfrm->ext->attributes(), "cx"))); + $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::getArrayItem($xfrm->ext->attributes(), "cy"))); + $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::getArrayItem($xfrm->attributes(), "rot"))); } if ($outerShdw) { $shadow = $objDrawing->getShadow(); $shadow->setVisible(true); - $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad"))); - $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist"))); - $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir"))); - $shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn")); - $shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val")); - $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); + $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::getArrayItem($outerShdw->attributes(), "blurRad"))); + $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::getArrayItem($outerShdw->attributes(), "dist"))); + $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::getArrayItem($outerShdw->attributes(), "dir"))); + $shadow->setAlignment((string) self::getArrayItem($outerShdw->attributes(), "algn")); + $shadow->getColor()->setRGB(self::getArrayItem($outerShdw->srgbClr->attributes(), "val")); + $shadow->setAlpha(self::getArrayItem($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); } $objDrawing->setWorksheet($docSheet); - } elseif (($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { + } elseif (($this->includeCharts) && ($twoCellAnchor->graphicFrame)) { $fromCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1); $fromOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff); $fromOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff); @@ -1671,7 +1671,7 @@ public function load($pFilename) } } - if ((!$this->_readDataOnly) || (!empty($this->_loadSheetsOnly))) { + if ((!$this->readDataOnly) || (!empty($this->loadSheetsOnly))) { // active sheet index $activeTab = intval($xmlWorkbook->bookViews->workbookView["activeTab"]); // refers to old sheet index @@ -1689,14 +1689,14 @@ public function load($pFilename) } } - if (!$this->_readDataOnly) { - $contentTypes = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, "[Content_Types].xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (!$this->readDataOnly) { + $contentTypes = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "[Content_Types].xml")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); foreach ($contentTypes->Override as $contentType) { switch ($contentType["ContentType"]) { case "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": - if ($this->_includeCharts) { + if ($this->includeCharts) { $chartEntryRef = ltrim($contentType['PartName'], '/'); - $chartElements = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $chartEntryRef)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $chartElements = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, $chartEntryRef)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements, basename($chartEntryRef, '.xml')); // echo 'Chart ', $chartEntryRef, '<br />'; @@ -1799,8 +1799,8 @@ private static function readStyle($docStyle, $style) } $docStyle->getFill()->setRotation(floatval($gradientFill["degree"])); $gradientFill->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - $docStyle->getFill()->getStartColor()->setARGB(self::readColor(self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color)); - $docStyle->getFill()->getEndColor()->setARGB(self::readColor(self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color)); + $docStyle->getFill()->getStartColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath("sml:stop[@position=0]"))->color)); + $docStyle->getFill()->getEndColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath("sml:stop[@position=1]"))->color)); } elseif ($style->fill->patternFill) { $patternType = (string)$style->fill->patternFill["patternType"] != '' ? (string)$style->fill->patternFill["patternType"] : 'solid'; $docStyle->getFill()->setFillType($patternType); @@ -1952,12 +1952,12 @@ private function readRibbon($excel, $customUITarget, $zip) $baseDir = dirname($customUITarget); $nameCustomUI = basename($customUITarget); // get the xml file (ribbon) - $localRibbon = $this->_getFromZipArchive($zip, $customUITarget); + $localRibbon = $this->getFromZipArchive($zip, $customUITarget); $customUIImagesNames = array(); $customUIImagesBinaries = array(); // something like customUI/_rels/customUI.xml.rels $pathRels = $baseDir . '/_rels/' . $nameCustomUI . '.rels'; - $dataRels = $this->_getFromZipArchive($zip, $pathRels); + $dataRels = $this->getFromZipArchive($zip, $pathRels); if ($dataRels) { // exists and not empty if the ribbon have some pictures (other than internal MSO) $UIRels = simplexml_load_string($this->securityScan($dataRels), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); @@ -1967,7 +1967,7 @@ private function readRibbon($excel, $customUITarget, $zip) if ($ele["Type"] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') { // an image ? $customUIImagesNames[(string) $ele['Id']] = (string)$ele['Target']; - $customUIImagesBinaries[(string)$ele['Target']] = $this->_getFromZipArchive($zip, $baseDir . '/' . (string) $ele['Target']); + $customUIImagesBinaries[(string)$ele['Target']] = $this->getFromZipArchive($zip, $baseDir . '/' . (string) $ele['Target']); } } } @@ -1985,12 +1985,12 @@ private function readRibbon($excel, $customUITarget, $zip) } } - private static function array_item($array, $key = 0) + private static function getArrayItem($array, $key = 0) { return (isset($array[$key]) ? $array[$key] : null); } - private static function dir_add($base, $add) + private static function dirAdd($base, $add) { return preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add"); } diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 3728b6cc2..50cc87e39 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -1,6 +1,16 @@ <?php + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + /** - * PHPExcel + * PHPExcel_Reader_Excel5 * * Copyright (c) 2006 - 2015 PHPExcel * @@ -55,26 +65,6 @@ // Patch code for user-defined named cells supports single cells only. // NOTE: this patch only works for BIFF8 as BIFF5-7 use a different // external sheet reference structure - - -/** PHPExcel root directory */ -if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); -} - -/** - * PHPExcel_Reader_Excel5 - * - * This class uses {@link http://sourceforge.net/projects/phpexcelreader/parseXL} - * - * @category PHPExcel - * @package PHPExcel_Reader_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { // ParseXL definitions @@ -172,63 +162,63 @@ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExce * * @var string */ - private $_summaryInformation; + private $summaryInformation; /** * Extended Summary Information stream data. * * @var string */ - private $_documentSummaryInformation; + private $documentSummaryInformation; /** * User-Defined Properties stream data. * * @var string */ - private $_userDefinedProperties; + private $userDefinedProperties; /** * Workbook stream data. (Includes workbook globals substream as well as sheet substreams) * * @var string */ - private $_data; + private $data; /** - * Size in bytes of $this->_data + * Size in bytes of $this->data * * @var int */ - private $_dataSize; + private $dataSize; /** * Current position in stream * * @var integer */ - private $_pos; + private $pos; /** * Workbook to be returned by the reader. * * @var PHPExcel */ - private $_phpExcel; + private $phpExcel; /** * Worksheet that is currently being built by the reader. * * @var PHPExcel_Worksheet */ - private $_phpSheet; + private $phpSheet; /** * BIFF version * * @var int */ - private $_version; + private $version; /** * Codepage set in the Excel file being read. Only important for BIFF5 (Excel 5.0 - Excel 95) @@ -236,147 +226,147 @@ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExce * * @var string */ - private $_codepage; + private $codepage; /** * Shared formats * * @var array */ - private $_formats; + private $formats; /** * Shared fonts * * @var array */ - private $_objFonts; + private $objFonts; /** * Color palette * * @var array */ - private $_palette; + private $palette; /** * Worksheets * * @var array */ - private $_sheets; + private $sheets; /** * External books * * @var array */ - private $_externalBooks; + private $externalBooks; /** * REF structures. Only applies to BIFF8. * * @var array */ - private $_ref; + private $ref; /** * External names * * @var array */ - private $_externalNames; + private $externalNames; /** * Defined names * * @var array */ - private $_definedname; + private $definedname; /** * Shared strings. Only applies to BIFF8. * * @var array */ - private $_sst; + private $sst; /** * Panes are frozen? (in sheet currently being read). See WINDOW2 record. * * @var boolean */ - private $_frozen; + private $frozen; /** * Fit printout to number of pages? (in sheet currently being read). See SHEETPR record. * * @var boolean */ - private $_isFitToPages; + private $isFitToPages; /** * Objects. One OBJ record contributes with one entry. * * @var array */ - private $_objs; + private $objs; /** * Text Objects. One TXO record corresponds with one entry. * * @var array */ - private $_textObjects; + private $textObjects; /** * Cell Annotations (BIFF8) * * @var array */ - private $_cellNotes; + private $cellNotes; /** * The combined MSODRAWINGGROUP data * * @var string */ - private $_drawingGroupData; + private $drawingGroupData; /** * The combined MSODRAWING data (per sheet) * * @var string */ - private $_drawingData; + private $drawingData; /** * Keep track of XF index * * @var int */ - private $_xfIndex; + private $xfIndex; /** * Mapping of XF index (that is a cell XF) to final index in cellXf collection * * @var array */ - private $_mapCellXfIndex; + private $mapCellXfIndex; /** * Mapping of XF index (that is a style XF) to final index in cellStyleXf collection * * @var array */ - private $_mapCellStyleXfIndex; + private $mapCellStyleXfIndex; /** * The shared formulas in a sheet. One SHAREDFMLA record contributes with one value. * * @var array */ - private $_sharedFormulas; + private $sharedFormulas; /** * The shared formula parts in a sheet. One FORMULA record contributes with one value if it @@ -384,49 +374,49 @@ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExce * * @var array */ - private $_sharedFormulaParts; + private $sharedFormulaParts; /** * The type of encryption in use * * @var int */ - private $_encryption = 0; + private $encryption = 0; /** * The position in the stream after which contents are encrypted * * @var int */ - private $_encryptionStartPos = false; + private $encryptionStartPos = false; /** * The current RC4 decryption object * * @var PHPExcel_Reader_Excel5_RC4 */ - private $_rc4Key = null; + private $rc4Key = null; /** * The position in the stream that the RC4 decryption object was left at * * @var int */ - private $_rc4Pos = 0; + private $rc4Pos = 0; /** * The current MD5 context state * * @var string */ - private $_md5Ctxt = null; + private $md5Ctxt = null; /** * Create a new PHPExcel_Reader_Excel5 instance */ public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); } /** @@ -471,35 +461,35 @@ public function listWorksheetNames($pFilename) $worksheetNames = array(); // Read the OLE file - $this->_loadOLE($pFilename); + $this->loadOLE($pFilename); // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); + $this->dataSize = strlen($this->data); - $this->_pos = 0; - $this->_sheets = array(); + $this->pos = 0; + $this->sheets = array(); // Parse Workbook Global Substream - while ($this->_pos < $this->_dataSize) { - $code = self::_GetInt2d($this->_data, $this->_pos); + while ($this->pos < $this->dataSize) { + $code = self::getInt2d($this->data, $this->pos); switch ($code) { case self::XLS_Type_BOF: - $this->_readBof(); + $this->readBof(); break; case self::XLS_Type_SHEET: - $this->_readSheet(); + $this->readSheet(); break; case self::XLS_Type_EOF: - $this->_readDefault(); + $this->readDefault(); break 2; default: - $this->_readDefault(); + $this->readDefault(); break; } } - foreach ($this->_sheets as $sheet) { + foreach ($this->sheets as $sheet) { if ($sheet['sheetType'] != 0x00) { // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module continue; @@ -528,37 +518,37 @@ public function listWorksheetInfo($pFilename) $worksheetInfo = array(); // Read the OLE file - $this->_loadOLE($pFilename); + $this->loadOLE($pFilename); // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); + $this->dataSize = strlen($this->data); // initialize - $this->_pos = 0; - $this->_sheets = array(); + $this->pos = 0; + $this->sheets = array(); // Parse Workbook Global Substream - while ($this->_pos < $this->_dataSize) { - $code = self::_GetInt2d($this->_data, $this->_pos); + while ($this->pos < $this->dataSize) { + $code = self::getInt2d($this->data, $this->pos); switch ($code) { case self::XLS_Type_BOF: - $this->_readBof(); + $this->readBof(); break; case self::XLS_Type_SHEET: - $this->_readSheet(); + $this->readSheet(); break; case self::XLS_Type_EOF: - $this->_readDefault(); + $this->readDefault(); break 2; default: - $this->_readDefault(); + $this->readDefault(); break; } } // Parse the individual sheets - foreach ($this->_sheets as $sheet) { + foreach ($this->sheets as $sheet) { if ($sheet['sheetType'] != 0x00) { // 0x00: Worksheet // 0x02: Chart @@ -573,10 +563,10 @@ public function listWorksheetInfo($pFilename) $tmpInfo['totalRows'] = 0; $tmpInfo['totalColumns'] = 0; - $this->_pos = $sheet['offset']; + $this->pos = $sheet['offset']; - while ($this->_pos <= $this->_dataSize - 4) { - $code = self::_GetInt2d($this->_data, $this->_pos); + while ($this->pos <= $this->dataSize - 4) { + $code = self::getInt2d($this->data, $this->pos); switch ($code) { case self::XLS_Type_RK: @@ -585,26 +575,26 @@ public function listWorksheetInfo($pFilename) case self::XLS_Type_FORMULA: case self::XLS_Type_BOOLERR: case self::XLS_Type_LABEL: - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - $rowIndex = self::_GetInt2d($recordData, 0) + 1; - $columnIndex = self::_GetInt2d($recordData, 2); + $rowIndex = self::getInt2d($recordData, 0) + 1; + $columnIndex = self::getInt2d($recordData, 2); $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); break; case self::XLS_Type_BOF: - $this->_readBof(); + $this->readBof(); break; case self::XLS_Type_EOF: - $this->_readDefault(); + $this->readDefault(); break 2; default: - $this->_readDefault(); + $this->readDefault(); break; } } @@ -629,126 +619,126 @@ public function listWorksheetInfo($pFilename) public function load($pFilename) { // Read the OLE file - $this->_loadOLE($pFilename); + $this->loadOLE($pFilename); // Initialisations - $this->_phpExcel = new PHPExcel; - $this->_phpExcel->removeSheetByIndex(0); // remove 1st sheet - if (!$this->_readDataOnly) { - $this->_phpExcel->removeCellStyleXfByIndex(0); // remove the default style - $this->_phpExcel->removeCellXfByIndex(0); // remove the default style + $this->phpExcel = new PHPExcel; + $this->phpExcel->removeSheetByIndex(0); // remove 1st sheet + if (!$this->readDataOnly) { + $this->phpExcel->removeCellStyleXfByIndex(0); // remove the default style + $this->phpExcel->removeCellXfByIndex(0); // remove the default style } // Read the summary information stream (containing meta data) - $this->_readSummaryInformation(); + $this->readSummaryInformation(); // Read the Additional document summary information stream (containing application-specific meta data) - $this->_readDocumentSummaryInformation(); + $this->readDocumentSummaryInformation(); // total byte size of Excel data (workbook global substream + sheet substreams) - $this->_dataSize = strlen($this->_data); + $this->dataSize = strlen($this->data); // initialize - $this->_pos = 0; - $this->_codepage = 'CP1252'; - $this->_formats = array(); - $this->_objFonts = array(); - $this->_palette = array(); - $this->_sheets = array(); - $this->_externalBooks = array(); - $this->_ref = array(); - $this->_definedname = array(); - $this->_sst = array(); - $this->_drawingGroupData = ''; - $this->_xfIndex = ''; - $this->_mapCellXfIndex = array(); - $this->_mapCellStyleXfIndex = array(); + $this->pos = 0; + $this->codepage = 'CP1252'; + $this->formats = array(); + $this->objFonts = array(); + $this->palette = array(); + $this->sheets = array(); + $this->externalBooks = array(); + $this->ref = array(); + $this->definedname = array(); + $this->sst = array(); + $this->drawingGroupData = ''; + $this->xfIndex = ''; + $this->mapCellXfIndex = array(); + $this->mapCellStyleXfIndex = array(); // Parse Workbook Global Substream - while ($this->_pos < $this->_dataSize) { - $code = self::_GetInt2d($this->_data, $this->_pos); + while ($this->pos < $this->dataSize) { + $code = self::getInt2d($this->data, $this->pos); switch ($code) { case self::XLS_Type_BOF: - $this->_readBof(); + $this->readBof(); break; case self::XLS_Type_FILEPASS: - $this->_readFilepass(); + $this->readFilepass(); break; case self::XLS_Type_CODEPAGE: - $this->_readCodepage(); + $this->readCodepage(); break; case self::XLS_Type_DATEMODE: - $this->_readDateMode(); + $this->readDateMode(); break; case self::XLS_Type_FONT: - $this->_readFont(); + $this->readFont(); break; case self::XLS_Type_FORMAT: - $this->_readFormat(); + $this->readFormat(); break; case self::XLS_Type_XF: - $this->_readXf(); + $this->readXf(); break; case self::XLS_Type_XFEXT: - $this->_readXfExt(); + $this->readXfExt(); break; case self::XLS_Type_STYLE: - $this->_readStyle(); + $this->readStyle(); break; case self::XLS_Type_PALETTE: - $this->_readPalette(); + $this->readPalette(); break; case self::XLS_Type_SHEET: - $this->_readSheet(); + $this->readSheet(); break; case self::XLS_Type_EXTERNALBOOK: - $this->_readExternalBook(); + $this->readExternalBook(); break; case self::XLS_Type_EXTERNNAME: - $this->_readExternName(); + $this->readExternName(); break; case self::XLS_Type_EXTERNSHEET: - $this->_readExternSheet(); + $this->readExternSheet(); break; case self::XLS_Type_DEFINEDNAME: - $this->_readDefinedName(); + $this->readDefinedName(); break; case self::XLS_Type_MSODRAWINGGROUP: - $this->_readMsoDrawingGroup(); + $this->readMsoDrawingGroup(); break; case self::XLS_Type_SST: - $this->_readSst(); + $this->readSst(); break; case self::XLS_Type_EOF: - $this->_readDefault(); + $this->readDefault(); break 2; default: - $this->_readDefault(); + $this->readDefault(); break; } } // Resolve indexed colors for font, fill, and border colors // Cannot be resolved already in XF record, because PALETTE record comes afterwards - if (!$this->_readDataOnly) { - foreach ($this->_objFonts as $objFont) { + if (!$this->readDataOnly) { + foreach ($this->objFonts as $objFont) { if (isset($objFont->colorIndex)) { - $color = self::_readColor($objFont->colorIndex, $this->_palette, $this->_version); + $color = self::readColor($objFont->colorIndex, $this->palette, $this->version); $objFont->getColor()->setRGB($color['rgb']); } } - foreach ($this->_phpExcel->getCellXfCollection() as $objStyle) { + foreach ($this->phpExcel->getCellXfCollection() as $objStyle) { // fill start and end color $fill = $objStyle->getFill(); if (isset($fill->startcolorIndex)) { - $startColor = self::_readColor($fill->startcolorIndex, $this->_palette, $this->_version); + $startColor = self::readColor($fill->startcolorIndex, $this->palette, $this->version); $fill->getStartColor()->setRGB($startColor['rgb']); } if (isset($fill->endcolorIndex)) { - $endColor = self::_readColor($fill->endcolorIndex, $this->_palette, $this->_version); + $endColor = self::readColor($fill->endcolorIndex, $this->palette, $this->version); $fill->getEndColor()->setRGB($endColor['rgb']); } @@ -760,267 +750,267 @@ public function load($pFilename) $diagonal = $objStyle->getBorders()->getDiagonal(); if (isset($top->colorIndex)) { - $borderTopColor = self::_readColor($top->colorIndex, $this->_palette, $this->_version); + $borderTopColor = self::readColor($top->colorIndex, $this->palette, $this->version); $top->getColor()->setRGB($borderTopColor['rgb']); } if (isset($right->colorIndex)) { - $borderRightColor = self::_readColor($right->colorIndex, $this->_palette, $this->_version); + $borderRightColor = self::readColor($right->colorIndex, $this->palette, $this->version); $right->getColor()->setRGB($borderRightColor['rgb']); } if (isset($bottom->colorIndex)) { - $borderBottomColor = self::_readColor($bottom->colorIndex, $this->_palette, $this->_version); + $borderBottomColor = self::readColor($bottom->colorIndex, $this->palette, $this->version); $bottom->getColor()->setRGB($borderBottomColor['rgb']); } if (isset($left->colorIndex)) { - $borderLeftColor = self::_readColor($left->colorIndex, $this->_palette, $this->_version); + $borderLeftColor = self::readColor($left->colorIndex, $this->palette, $this->version); $left->getColor()->setRGB($borderLeftColor['rgb']); } if (isset($diagonal->colorIndex)) { - $borderDiagonalColor = self::_readColor($diagonal->colorIndex, $this->_palette, $this->_version); + $borderDiagonalColor = self::readColor($diagonal->colorIndex, $this->palette, $this->version); $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']); } } } // treat MSODRAWINGGROUP records, workbook-level Escher - if (!$this->_readDataOnly && $this->_drawingGroupData) { + if (!$this->readDataOnly && $this->drawingGroupData) { $escherWorkbook = new PHPExcel_Shared_Escher(); $reader = new PHPExcel_Reader_Excel5_Escher($escherWorkbook); - $escherWorkbook = $reader->load($this->_drawingGroupData); + $escherWorkbook = $reader->load($this->drawingGroupData); // debug Escher stream //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); - //$debug->load($this->_drawingGroupData); + //$debug->load($this->drawingGroupData); } // Parse the individual sheets - foreach ($this->_sheets as $sheet) { + foreach ($this->sheets as $sheet) { if ($sheet['sheetType'] != 0x00) { // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module continue; } // check if sheet should be skipped - if (isset($this->_loadSheetsOnly) && !in_array($sheet['name'], $this->_loadSheetsOnly)) { + if (isset($this->loadSheetsOnly) && !in_array($sheet['name'], $this->loadSheetsOnly)) { continue; } // add sheet to PHPExcel object - $this->_phpSheet = $this->_phpExcel->createSheet(); + $this->phpSheet = $this->phpExcel->createSheet(); // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet // name in line with the formula, not the reverse - $this->_phpSheet->setTitle($sheet['name'], false); - $this->_phpSheet->setSheetState($sheet['sheetState']); + $this->phpSheet->setTitle($sheet['name'], false); + $this->phpSheet->setSheetState($sheet['sheetState']); - $this->_pos = $sheet['offset']; + $this->pos = $sheet['offset']; // Initialize isFitToPages. May change after reading SHEETPR record. - $this->_isFitToPages = false; + $this->isFitToPages = false; // Initialize drawingData - $this->_drawingData = ''; + $this->drawingData = ''; // Initialize objs - $this->_objs = array(); + $this->objs = array(); // Initialize shared formula parts - $this->_sharedFormulaParts = array(); + $this->sharedFormulaParts = array(); // Initialize shared formulas - $this->_sharedFormulas = array(); + $this->sharedFormulas = array(); // Initialize text objs - $this->_textObjects = array(); + $this->textObjects = array(); // Initialize cell annotations - $this->_cellNotes = array(); + $this->cellNotes = array(); $this->textObjRef = -1; - while ($this->_pos <= $this->_dataSize - 4) { - $code = self::_GetInt2d($this->_data, $this->_pos); + while ($this->pos <= $this->dataSize - 4) { + $code = self::getInt2d($this->data, $this->pos); switch ($code) { case self::XLS_Type_BOF: - $this->_readBof(); + $this->readBof(); break; case self::XLS_Type_PRINTGRIDLINES: - $this->_readPrintGridlines(); + $this->readPrintGridlines(); break; case self::XLS_Type_DEFAULTROWHEIGHT: - $this->_readDefaultRowHeight(); + $this->readDefaultRowHeight(); break; case self::XLS_Type_SHEETPR: - $this->_readSheetPr(); + $this->readSheetPr(); break; case self::XLS_Type_HORIZONTALPAGEBREAKS: - $this->_readHorizontalPageBreaks(); + $this->readHorizontalPageBreaks(); break; case self::XLS_Type_VERTICALPAGEBREAKS: - $this->_readVerticalPageBreaks(); + $this->readVerticalPageBreaks(); break; case self::XLS_Type_HEADER: - $this->_readHeader(); + $this->readHeader(); break; case self::XLS_Type_FOOTER: - $this->_readFooter(); + $this->readFooter(); break; case self::XLS_Type_HCENTER: - $this->_readHcenter(); + $this->readHcenter(); break; case self::XLS_Type_VCENTER: - $this->_readVcenter(); + $this->readVcenter(); break; case self::XLS_Type_LEFTMARGIN: - $this->_readLeftMargin(); + $this->readLeftMargin(); break; case self::XLS_Type_RIGHTMARGIN: - $this->_readRightMargin(); + $this->readRightMargin(); break; case self::XLS_Type_TOPMARGIN: - $this->_readTopMargin(); + $this->readTopMargin(); break; case self::XLS_Type_BOTTOMMARGIN: - $this->_readBottomMargin(); + $this->readBottomMargin(); break; case self::XLS_Type_PAGESETUP: - $this->_readPageSetup(); + $this->readPageSetup(); break; case self::XLS_Type_PROTECT: - $this->_readProtect(); + $this->readProtect(); break; case self::XLS_Type_SCENPROTECT: - $this->_readScenProtect(); + $this->readScenProtect(); break; case self::XLS_Type_OBJECTPROTECT: - $this->_readObjectProtect(); + $this->readObjectProtect(); break; case self::XLS_Type_PASSWORD: - $this->_readPassword(); + $this->readPassword(); break; case self::XLS_Type_DEFCOLWIDTH: - $this->_readDefColWidth(); + $this->readDefColWidth(); break; case self::XLS_Type_COLINFO: - $this->_readColInfo(); + $this->readColInfo(); break; case self::XLS_Type_DIMENSION: - $this->_readDefault(); + $this->readDefault(); break; case self::XLS_Type_ROW: - $this->_readRow(); + $this->readRow(); break; case self::XLS_Type_DBCELL: - $this->_readDefault(); + $this->readDefault(); break; case self::XLS_Type_RK: - $this->_readRk(); + $this->readRk(); break; case self::XLS_Type_LABELSST: - $this->_readLabelSst(); + $this->readLabelSst(); break; case self::XLS_Type_MULRK: - $this->_readMulRk(); + $this->readMulRk(); break; case self::XLS_Type_NUMBER: - $this->_readNumber(); + $this->readNumber(); break; case self::XLS_Type_FORMULA: - $this->_readFormula(); + $this->readFormula(); break; case self::XLS_Type_SHAREDFMLA: - $this->_readSharedFmla(); + $this->readSharedFmla(); break; case self::XLS_Type_BOOLERR: - $this->_readBoolErr(); + $this->readBoolErr(); break; case self::XLS_Type_MULBLANK: - $this->_readMulBlank(); + $this->readMulBlank(); break; case self::XLS_Type_LABEL: - $this->_readLabel(); + $this->readLabel(); break; case self::XLS_Type_BLANK: - $this->_readBlank(); + $this->readBlank(); break; case self::XLS_Type_MSODRAWING: - $this->_readMsoDrawing(); + $this->readMsoDrawing(); break; case self::XLS_Type_OBJ: - $this->_readObj(); + $this->readObj(); break; case self::XLS_Type_WINDOW2: - $this->_readWindow2(); + $this->readWindow2(); break; case self::XLS_Type_PAGELAYOUTVIEW: - $this->_readPageLayoutView(); + $this->readPageLayoutView(); break; case self::XLS_Type_SCL: - $this->_readScl(); + $this->readScl(); break; case self::XLS_Type_PANE: - $this->_readPane(); + $this->readPane(); break; case self::XLS_Type_SELECTION: - $this->_readSelection(); + $this->readSelection(); break; case self::XLS_Type_MERGEDCELLS: - $this->_readMergedCells(); + $this->readMergedCells(); break; case self::XLS_Type_HYPERLINK: - $this->_readHyperLink(); + $this->readHyperLink(); break; case self::XLS_Type_DATAVALIDATIONS: - $this->_readDataValidations(); + $this->readDataValidations(); break; case self::XLS_Type_DATAVALIDATION: - $this->_readDataValidation(); + $this->readDataValidation(); break; case self::XLS_Type_SHEETLAYOUT: - $this->_readSheetLayout(); + $this->readSheetLayout(); break; case self::XLS_Type_SHEETPROTECTION: - $this->_readSheetProtection(); + $this->readSheetProtection(); break; case self::XLS_Type_RANGEPROTECTION: - $this->_readRangeProtection(); + $this->readRangeProtection(); break; case self::XLS_Type_NOTE: - $this->_readNote(); + $this->readNote(); break; - //case self::XLS_Type_IMDATA: $this->_readImData(); break; + //case self::XLS_Type_IMDATA: $this->readImData(); break; case self::XLS_Type_TXO: - $this->_readTextObject(); + $this->readTextObject(); break; case self::XLS_Type_CONTINUE: - $this->_readContinue(); + $this->readContinue(); break; case self::XLS_Type_EOF: - $this->_readDefault(); + $this->readDefault(); break 2; default: - $this->_readDefault(); + $this->readDefault(); break; } } // treat MSODRAWING records, sheet-level Escher - if (!$this->_readDataOnly && $this->_drawingData) { + if (!$this->readDataOnly && $this->drawingData) { $escherWorksheet = new PHPExcel_Shared_Escher(); $reader = new PHPExcel_Reader_Excel5_Escher($escherWorksheet); - $escherWorksheet = $reader->load($this->_drawingData); + $escherWorksheet = $reader->load($this->drawingData); // debug Escher stream //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); - //$debug->load($this->_drawingData); + //$debug->load($this->drawingData); // get all spContainers in one long array, so they can be mapped to OBJ records $allSpContainers = $escherWorksheet->getDgContainer()->getSpgrContainer()->getAllSpContainers(); } // treat OBJ records - foreach ($this->_objs as $n => $obj) { + foreach ($this->objs as $n => $obj) { // echo '<hr /><b>Object</b> reference is ', $n,'<br />'; // var_dump($obj); // echo '<br />'; @@ -1043,24 +1033,24 @@ public function load($pFilename) $endOffsetX = $spContainer->getEndOffsetX(); $endOffsetY = $spContainer->getEndOffsetY(); - $width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX); - $height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY); + $width = PHPExcel_Shared_Excel5::getDistanceX($this->phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX); + $height = PHPExcel_Shared_Excel5::getDistanceY($this->phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY); // calculate offsetX and offsetY of the shape - $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024; - $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256; + $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, $startColumn) / 1024; + $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $startRow) / 256; switch ($obj['otObjType']) { case 0x19: // Note // echo 'Cell Annotation Object<br />'; // echo 'Object ID is ', $obj['idObjID'],'<br />'; - if (isset($this->_cellNotes[$obj['idObjID']])) { - $cellNote = $this->_cellNotes[$obj['idObjID']]; + if (isset($this->cellNotes[$obj['idObjID']])) { + $cellNote = $this->cellNotes[$obj['idObjID']]; - if (isset($this->_textObjects[$obj['idObjID']])) { - $textObject = $this->_textObjects[$obj['idObjID']]; - $this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject; + if (isset($this->textObjects[$obj['idObjID']])) { + $textObject = $this->textObjects[$obj['idObjID']]; + $this->cellNotes[$obj['idObjID']]['objTextData'] = $textObject; } } break; @@ -1097,7 +1087,7 @@ public function load($pFilename) break; } - $drawing->setWorksheet($this->_phpSheet); + $drawing->setWorksheet($this->phpSheet); $drawing->setCoordinates($spContainer->getStartCoordinates()); } break; @@ -1109,21 +1099,21 @@ public function load($pFilename) } // treat SHAREDFMLA records - if ($this->_version == self::XLS_BIFF8) { - foreach ($this->_sharedFormulaParts as $cell => $baseCell) { + if ($this->version == self::XLS_BIFF8) { + foreach ($this->sharedFormulaParts as $cell => $baseCell) { list($column, $row) = PHPExcel_Cell::coordinateFromString($cell); - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { - $formula = $this->_getFormulaFromStructure($this->_sharedFormulas[$baseCell], $cell); - $this->_phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($column, $row, $this->phpSheet->getTitle())) { + $formula = $this->getFormulaFromStructure($this->sharedFormulas[$baseCell], $cell); + $this->phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); } } } - if (!empty($this->_cellNotes)) { - foreach ($this->_cellNotes as $note => $noteDetails) { + if (!empty($this->cellNotes)) { + foreach ($this->cellNotes as $note => $noteDetails) { if (!isset($noteDetails['objTextData'])) { - if (isset($this->_textObjects[$note])) { - $textObject = $this->_textObjects[$note]; + if (isset($this->textObjects[$note])) { + $textObject = $this->textObjects[$note]; $noteDetails['objTextData'] = $textObject; } else { $noteDetails['objTextData']['text'] = ''; @@ -1133,13 +1123,13 @@ public function load($pFilename) // var_dump($noteDetails); // echo '<br />'; $cellAddress = str_replace('$', '', $noteDetails['cellRef']); - $this->_phpSheet->getComment($cellAddress)->setAuthor($noteDetails['author'])->setText($this->_parseRichText($noteDetails['objTextData']['text'])); + $this->phpSheet->getComment($cellAddress)->setAuthor($noteDetails['author'])->setText($this->parseRichText($noteDetails['objTextData']['text'])); } } } // add the named ranges (defined names) - foreach ($this->_definedname as $definedName) { + foreach ($this->definedname as $definedName) { if ($definedName['isBuiltInName']) { switch ($definedName['name']) { case pack('C', 0x06): @@ -1161,7 +1151,7 @@ public function load($pFilename) $extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66 } } - if ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) { + if ($docSheet = $this->phpExcel->getSheetByName($sheetName)) { $docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges)); // C7:J66,A1:IV2 } break; @@ -1183,7 +1173,7 @@ public function load($pFilename) // Sheet!$A$1:$IV$2 $explodes = explode('!', $range); if (count($explodes) == 2) { - if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) { + if ($docSheet = $this->phpExcel->getSheetByName($explodes[0])) { $extractedRange = $explodes[1]; $extractedRange = str_replace('$', '', $extractedRange); @@ -1210,16 +1200,16 @@ public function load($pFilename) $explodes = explode('!', $definedName['formula']); if (count($explodes) == 2) { - if (($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) || - ($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0], "'")))) { + if (($docSheet = $this->phpExcel->getSheetByName($explodes[0])) || + ($docSheet = $this->phpExcel->getSheetByName(trim($explodes[0], "'")))) { $extractedRange = $explodes[1]; $extractedRange = str_replace('$', '', $extractedRange); $localOnly = ($definedName['scope'] == 0) ? false : true; - $scope = ($definedName['scope'] == 0) ? null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']); + $scope = ($definedName['scope'] == 0) ? null : $this->phpExcel->getSheetByName($this->sheets[$definedName['scope'] - 1]['name']); - $this->_phpExcel->addNamedRange(new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope)); + $this->phpExcel->addNamedRange(new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope)); } } else { // Named Value @@ -1227,9 +1217,9 @@ public function load($pFilename) } } } - $this->_data = null; + $this->data = null; - return $this->_phpExcel; + return $this->phpExcel; } /** @@ -1241,47 +1231,47 @@ public function load($pFilename) * * @return string Record data */ - private function _readRecordData($data, $pos, $len) + private function readRecordData($data, $pos, $len) { $data = substr($data, $pos, $len); // File not encrypted, or record before encryption start point - if ($this->_encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->_encryptionStartPos) { + if ($this->encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->encryptionStartPos) { return $data; } $recordData = ''; - if ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) { - $oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK); + if ($this->encryption == self::MS_BIFF_CRYPTO_RC4) { + $oldBlock = floor($this->rc4Pos / self::REKEY_BLOCK); $block = floor($pos / self::REKEY_BLOCK); $endBlock = floor(($pos + $len) / self::REKEY_BLOCK); // Spin an RC4 decryptor to the right spot. If we have a decryptor sitting // at a point earlier in the current block, re-use it as we can save some time. - if ($block != $oldBlock || $pos < $this->_rc4Pos || !$this->_rc4Key) { - $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + if ($block != $oldBlock || $pos < $this->rc4Pos || !$this->rc4Key) { + $this->rc4Key = $this->makeKey($block, $this->md5Ctxt); $step = $pos % self::REKEY_BLOCK; } else { - $step = $pos - $this->_rc4Pos; + $step = $pos - $this->rc4Pos; } - $this->_rc4Key->RC4(str_repeat("\0", $step)); + $this->rc4Key->RC4(str_repeat("\0", $step)); // Decrypt record data (re-keying at the end of every block) while ($block != $endBlock) { $step = self::REKEY_BLOCK - ($pos % self::REKEY_BLOCK); - $recordData .= $this->_rc4Key->RC4(substr($data, 0, $step)); + $recordData .= $this->rc4Key->RC4(substr($data, 0, $step)); $data = substr($data, $step); $pos += $step; $len -= $step; $block++; - $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + $this->rc4Key = $this->makeKey($block, $this->md5Ctxt); } - $recordData .= $this->_rc4Key->RC4(substr($data, 0, $len)); + $recordData .= $this->rc4Key->RC4(substr($data, 0, $len)); // Keep track of the position of this decryptor. // We'll try and re-use it later if we can to speed things up - $this->_rc4Pos = $pos + $len; - } elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) { + $this->rc4Pos = $pos + $len; + } elseif ($this->encryption == self::MS_BIFF_CRYPTO_XOR) { throw new PHPExcel_Reader_Exception('XOr encryption not supported'); } return $recordData; @@ -1292,29 +1282,29 @@ private function _readRecordData($data, $pos, $len) * * @param string $pFilename */ - private function _loadOLE($pFilename) + private function loadOLE($pFilename) { // OLE reader $ole = new PHPExcel_Shared_OLERead(); // get excel data, $res = $ole->read($pFilename); // Get workbook data: workbook stream + sheet streams - $this->_data = $ole->getStream($ole->wrkbook); + $this->data = $ole->getStream($ole->wrkbook); // Get summary information data - $this->_summaryInformation = $ole->getStream($ole->summaryInformation); + $this->summaryInformation = $ole->getStream($ole->summaryInformation); // Get additional document summary information data - $this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation); + $this->documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation); // Get user-defined property data -// $this->_userDefinedProperties = $ole->getUserDefinedProperties(); +// $this->userDefinedProperties = $ole->getUserDefinedProperties(); } /** * Read summary information */ - private function _readSummaryInformation() + private function readSummaryInformation() { - if (!isset($this->_summaryInformation)) { + if (!isset($this->summaryInformation)) { return; } @@ -1324,18 +1314,18 @@ private function _readSummaryInformation() // offset: 6; size: 2; OS indicator // offset: 8; size: 16 // offset: 24; size: 4; section count - $secCount = self::_GetInt4d($this->_summaryInformation, 24); + $secCount = self::getInt4d($this->summaryInformation, 24); // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 // offset: 44; size: 4 - $secOffset = self::_GetInt4d($this->_summaryInformation, 44); + $secOffset = self::getInt4d($this->summaryInformation, 44); // section header // offset: $secOffset; size: 4; section length - $secLength = self::_GetInt4d($this->_summaryInformation, $secOffset); + $secLength = self::getInt4d($this->summaryInformation, $secOffset); // offset: $secOffset+4; size: 4; property count - $countProperties = self::_GetInt4d($this->_summaryInformation, $secOffset+4); + $countProperties = self::getInt4d($this->summaryInformation, $secOffset+4); // initialize code page (used to resolve string values) $codePage = 'CP1252'; @@ -1344,13 +1334,13 @@ private function _readSummaryInformation() // loop through property decarations and properties for ($i = 0; $i < $countProperties; ++$i) { // offset: ($secOffset+8) + (8 * $i); size: 4; property ID - $id = self::_GetInt4d($this->_summaryInformation, ($secOffset+8) + (8 * $i)); + $id = self::getInt4d($this->summaryInformation, ($secOffset+8) + (8 * $i)); // Use value of property id as appropriate // offset: ($secOffset+12) + (8 * $i); size: 4; offset from beginning of section (48) - $offset = self::_GetInt4d($this->_summaryInformation, ($secOffset+12) + (8 * $i)); + $offset = self::getInt4d($this->summaryInformation, ($secOffset+12) + (8 * $i)); - $type = self::_GetInt4d($this->_summaryInformation, $secOffset + $offset); + $type = self::getInt4d($this->summaryInformation, $secOffset + $offset); // initialize property value $value = null; @@ -1358,23 +1348,23 @@ private function _readSummaryInformation() // extract property value based on property type switch ($type) { case 0x02: // 2 byte signed integer - $value = self::_GetInt2d($this->_summaryInformation, $secOffset + 4 + $offset); + $value = self::getInt2d($this->summaryInformation, $secOffset + 4 + $offset); break; case 0x03: // 4 byte signed integer - $value = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); + $value = self::getInt4d($this->summaryInformation, $secOffset + 4 + $offset); break; case 0x13: // 4 byte unsigned integer // not needed yet, fix later if necessary break; case 0x1E: // null-terminated string prepended by dword string length - $byteLength = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); - $value = substr($this->_summaryInformation, $secOffset + 8 + $offset, $byteLength); + $byteLength = self::getInt4d($this->summaryInformation, $secOffset + 4 + $offset); + $value = substr($this->summaryInformation, $secOffset + 8 + $offset, $byteLength); $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); $value = rtrim($value); break; case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) // PHP-time - $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_summaryInformation, $secOffset + 4 + $offset, 8)); + $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->summaryInformation, $secOffset + 4 + $offset, 8)); break; case 0x47: // Clipboard format // not needed yet, fix later if necessary @@ -1386,25 +1376,25 @@ private function _readSummaryInformation() $codePage = PHPExcel_Shared_CodePage::NumberToName($value); break; case 0x02: // Title - $this->_phpExcel->getProperties()->setTitle($value); + $this->phpExcel->getProperties()->setTitle($value); break; case 0x03: // Subject - $this->_phpExcel->getProperties()->setSubject($value); + $this->phpExcel->getProperties()->setSubject($value); break; case 0x04: // Author (Creator) - $this->_phpExcel->getProperties()->setCreator($value); + $this->phpExcel->getProperties()->setCreator($value); break; case 0x05: // Keywords - $this->_phpExcel->getProperties()->setKeywords($value); + $this->phpExcel->getProperties()->setKeywords($value); break; case 0x06: // Comments (Description) - $this->_phpExcel->getProperties()->setDescription($value); + $this->phpExcel->getProperties()->setDescription($value); break; case 0x07: // Template // Not supported by PHPExcel break; case 0x08: // Last Saved By (LastModifiedBy) - $this->_phpExcel->getProperties()->setLastModifiedBy($value); + $this->phpExcel->getProperties()->setLastModifiedBy($value); break; case 0x09: // Revision // Not supported by PHPExcel @@ -1416,10 +1406,10 @@ private function _readSummaryInformation() // Not supported by PHPExcel break; case 0x0C: // Created Date/Time - $this->_phpExcel->getProperties()->setCreated($value); + $this->phpExcel->getProperties()->setCreated($value); break; case 0x0D: // Modified Date/Time - $this->_phpExcel->getProperties()->setModified($value); + $this->phpExcel->getProperties()->setModified($value); break; case 0x0E: // Number of Pages // Not supported by PHPExcel @@ -1447,9 +1437,9 @@ private function _readSummaryInformation() /** * Read additional document summary information */ - private function _readDocumentSummaryInformation() + private function readDocumentSummaryInformation() { - if (!isset($this->_documentSummaryInformation)) { + if (!isset($this->documentSummaryInformation)) { return; } @@ -1459,21 +1449,21 @@ private function _readDocumentSummaryInformation() // offset: 6; size: 2; OS indicator // offset: 8; size: 16 // offset: 24; size: 4; section count - $secCount = self::_GetInt4d($this->_documentSummaryInformation, 24); + $secCount = self::getInt4d($this->documentSummaryInformation, 24); // echo '$secCount = ', $secCount,'<br />'; // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae // offset: 44; size: 4; first section offset - $secOffset = self::_GetInt4d($this->_documentSummaryInformation, 44); + $secOffset = self::getInt4d($this->documentSummaryInformation, 44); // echo '$secOffset = ', $secOffset,'<br />'; // section header // offset: $secOffset; size: 4; section length - $secLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset); + $secLength = self::getInt4d($this->documentSummaryInformation, $secOffset); // echo '$secLength = ', $secLength,'<br />'; // offset: $secOffset+4; size: 4; property count - $countProperties = self::_GetInt4d($this->_documentSummaryInformation, $secOffset+4); + $countProperties = self::getInt4d($this->documentSummaryInformation, $secOffset+4); // echo '$countProperties = ', $countProperties,'<br />'; // initialize code page (used to resolve string values) @@ -1484,14 +1474,14 @@ private function _readDocumentSummaryInformation() for ($i = 0; $i < $countProperties; ++$i) { // echo 'Property ', $i,'<br />'; // offset: ($secOffset+8) + (8 * $i); size: 4; property ID - $id = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+8) + (8 * $i)); + $id = self::getInt4d($this->documentSummaryInformation, ($secOffset+8) + (8 * $i)); // echo 'ID is ', $id,'<br />'; // Use value of property id as appropriate // offset: 60 + 8 * $i; size: 4; offset from beginning of section (48) - $offset = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+12) + (8 * $i)); + $offset = self::getInt4d($this->documentSummaryInformation, ($secOffset+12) + (8 * $i)); - $type = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + $offset); + $type = self::getInt4d($this->documentSummaryInformation, $secOffset + $offset); // echo 'Type is ', $type,', '; // initialize property value @@ -1500,27 +1490,27 @@ private function _readDocumentSummaryInformation() // extract property value based on property type switch ($type) { case 0x02: // 2 byte signed integer - $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = self::getInt2d($this->documentSummaryInformation, $secOffset + 4 + $offset); break; case 0x03: // 4 byte signed integer - $value = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = self::getInt4d($this->documentSummaryInformation, $secOffset + 4 + $offset); break; case 0x0B: // Boolean - $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = self::getInt2d($this->documentSummaryInformation, $secOffset + 4 + $offset); $value = ($value == 0 ? false : true); break; case 0x13: // 4 byte unsigned integer // not needed yet, fix later if necessary break; case 0x1E: // null-terminated string prepended by dword string length - $byteLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); - $value = substr($this->_documentSummaryInformation, $secOffset + 8 + $offset, $byteLength); + $byteLength = self::getInt4d($this->documentSummaryInformation, $secOffset + 4 + $offset); + $value = substr($this->documentSummaryInformation, $secOffset + 8 + $offset, $byteLength); $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); $value = rtrim($value); break; case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) // PHP-Time - $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_documentSummaryInformation, $secOffset + 4 + $offset, 8)); + $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->documentSummaryInformation, $secOffset + 4 + $offset, 8)); break; case 0x47: // Clipboard format // not needed yet, fix later if necessary @@ -1532,7 +1522,7 @@ private function _readDocumentSummaryInformation() $codePage = PHPExcel_Shared_CodePage::NumberToName($value); break; case 0x02: // Category - $this->_phpExcel->getProperties()->setCategory($value); + $this->phpExcel->getProperties()->setCategory($value); break; case 0x03: // Presentation Target // Not supported by PHPExcel @@ -1568,10 +1558,10 @@ private function _readDocumentSummaryInformation() // Not supported by PHPExcel break; case 0x0E: // Manager - $this->_phpExcel->getProperties()->setManager($value); + $this->phpExcel->getProperties()->setManager($value); break; case 0x0F: // Company - $this->_phpExcel->getProperties()->setCompany($value); + $this->phpExcel->getProperties()->setCompany($value); break; case 0x10: // Links up-to-date // Not supported by PHPExcel @@ -1584,13 +1574,13 @@ private function _readDocumentSummaryInformation() /** * Reads a general type of BIFF record. Does nothing except for moving stream pointer forward to next record. */ - private function _readDefault() + private function readDefault() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); -// $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); +// $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; } @@ -1598,29 +1588,29 @@ private function _readDefault() * The NOTE record specifies a comment associated with a particular cell. In Excel 95 (BIFF7) and earlier versions, * this record stores a note (cell note). This feature was significantly enhanced in Excel 97. */ - private function _readNote() + private function readNote() { // echo '<b>Read Cell Annotation</b><br />'; - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_readDataOnly) { + if ($this->readDataOnly) { return; } - $cellAddress = $this->_readBIFF8CellAddress(substr($recordData, 0, 4)); - if ($this->_version == self::XLS_BIFF8) { - $noteObjID = self::_GetInt2d($recordData, 6); - $noteAuthor = self::_readUnicodeStringLong(substr($recordData, 8)); + $cellAddress = $this->readBIFF8CellAddress(substr($recordData, 0, 4)); + if ($this->version == self::XLS_BIFF8) { + $noteObjID = self::getInt2d($recordData, 6); + $noteAuthor = self::readUnicodeStringLong(substr($recordData, 8)); $noteAuthor = $noteAuthor['value']; // echo 'Note Address=', $cellAddress,'<br />'; // echo 'Note Object ID=', $noteObjID,'<br />'; // echo 'Note Author=', $noteAuthor,'<hr />'; // - $this->_cellNotes[$noteObjID] = array( + $this->cellNotes[$noteObjID] = array( 'cellRef' => $cellAddress, 'objectID' => $noteObjID, 'author' => $noteAuthor @@ -1631,26 +1621,26 @@ private function _readNote() // If the address row is -1 and the column is 0, (which translates as $B$65536) then this is a continuation // note from the previous cell annotation. We're not yet handling this, so annotations longer than the // max 2048 bytes will probably throw a wobbly. - $row = self::_GetInt2d($recordData, 0); + $row = self::getInt2d($recordData, 0); $extension = true; - $cellAddress = array_pop(array_keys($this->_phpSheet->getComments())); + $cellAddress = array_pop(array_keys($this->phpSheet->getComments())); } // echo 'Note Address=', $cellAddress,'<br />'; $cellAddress = str_replace('$', '', $cellAddress); - $noteLength = self::_GetInt2d($recordData, 4); + $noteLength = self::getInt2d($recordData, 4); $noteText = trim(substr($recordData, 6)); // echo 'Note Length=', $noteLength,'<br />'; // echo 'Note Text=', $noteText,'<br />'; if ($extension) { // Concatenate this extension with the currently set comment for the cell - $comment = $this->_phpSheet->getComment($cellAddress); + $comment = $this->phpSheet->getComment($cellAddress); $commentText = $comment->getText()->getPlainText(); - $comment->setText($this->_parseRichText($commentText.$noteText)); + $comment->setText($this->parseRichText($commentText.$noteText)); } else { // Set comment for the cell - $this->_phpSheet->getComment($cellAddress)->setText($this->_parseRichText($noteText)); + $this->phpSheet->getComment($cellAddress)->setText($this->parseRichText($noteText)); // ->setAuthor($author) } } @@ -1661,15 +1651,15 @@ private function _readNote() /** * The TEXT Object record contains the text associated with a cell annotation. */ - private function _readTextObject() + private function readTextObject() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_readDataOnly) { + if ($this->readDataOnly) { return; } @@ -1679,13 +1669,13 @@ private function _readTextObject() // cchText: 2 bytes; length of the text (in the first continue record) // cbRuns: 2 bytes; length of the formatting (in the second continue record) // followed by the continuation records containing the actual text and formatting - $grbitOpts = self::_GetInt2d($recordData, 0); - $rot = self::_GetInt2d($recordData, 2); - $cchText = self::_GetInt2d($recordData, 10); - $cbRuns = self::_GetInt2d($recordData, 12); - $text = $this->_getSplicedRecordData(); + $grbitOpts = self::getInt2d($recordData, 0); + $rot = self::getInt2d($recordData, 2); + $cchText = self::getInt2d($recordData, 10); + $cbRuns = self::getInt2d($recordData, 12); + $text = $this->getSplicedRecordData(); - $this->_textObjects[$this->textObjRef] = array( + $this->textObjects[$this->textObjRef] = array( 'text' => substr($text["recordData"], $text["spliceOffsets"][0]+1, $cchText), 'format' => substr($text["recordData"], $text["spliceOffsets"][1], $cbRuns), 'alignment' => $grbitOpts, @@ -1693,7 +1683,7 @@ private function _readTextObject() ); // echo '<b>_readTextObject()</b><br />'; -// var_dump($this->_textObjects[$this->textObjRef]); +// var_dump($this->textObjects[$this->textObjRef]); // echo '<br />'; } @@ -1701,24 +1691,24 @@ private function _readTextObject() /** * Read BOF */ - private function _readBof() + private function readBof() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = substr($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = substr($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 2; size: 2; type of the following data - $substreamType = self::_GetInt2d($recordData, 2); + $substreamType = self::getInt2d($recordData, 2); switch ($substreamType) { case self::XLS_WorkbookGlobals: - $version = self::_GetInt2d($recordData, 0); + $version = self::getInt2d($recordData, 0); if (($version != self::XLS_BIFF8) && ($version != self::XLS_BIFF7)) { throw new PHPExcel_Reader_Exception('Cannot read this Excel file. Version is too old.'); } - $this->_version = $version; + $this->version = $version; break; case self::XLS_Worksheet: // do not use this version information for anything @@ -1728,9 +1718,9 @@ private function _readBof() // substream, e.g. chart // just skip the entire substream do { - $code = self::_GetInt2d($this->_data, $this->_pos); - $this->_readDefault(); - } while ($code != self::XLS_Type_EOF && $this->_pos < $this->_dataSize); + $code = self::getInt2d($this->data, $this->pos); + $this->readDefault(); + } while ($code != self::XLS_Type_EOF && $this->pos < $this->dataSize); break; } } @@ -1751,27 +1741,27 @@ private function _readBof() * are based on the source of Spreadsheet-ParseExcel: * http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/ */ - private function _readFilepass() + private function readFilepass() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $length = self::getInt2d($this->data, $this->pos + 2); if ($length != 54) { throw new PHPExcel_Reader_Exception('Unexpected file pass record length'); } - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_verifyPassword('VelvetSweatshop', substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->_md5Ctxt)) { + if (!$this->verifyPassword('VelvetSweatshop', substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->md5Ctxt)) { throw new PHPExcel_Reader_Exception('Decryption password incorrect'); } - $this->_encryption = self::MS_BIFF_CRYPTO_RC4; + $this->encryption = self::MS_BIFF_CRYPTO_RC4; // Decryption required from the record after next onwards - $this->_encryptionStartPos = $this->_pos + self::_GetInt2d($this->_data, $this->_pos + 2); + $this->encryptionStartPos = $this->pos + self::getInt2d($this->data, $this->pos + 2); } /** @@ -1782,7 +1772,7 @@ private function _readFilepass() * * @return PHPExcel_Reader_Excel5_RC4 */ - private function _makeKey($block, $valContext) + private function makeKey($block, $valContext) { $pwarray = str_repeat("\0", 64); @@ -1816,7 +1806,7 @@ private function _makeKey($block, $valContext) * * @return bool Success */ - private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext) + private function verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext) { $pwarray = str_repeat("\0", 64); @@ -1874,7 +1864,7 @@ private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data $md5->add($pwarray); $valContext = $md5->getContext(); - $key = $this->_makeKey(0, $valContext); + $key = $this->makeKey(0, $valContext); $salt = $key->RC4($salt_data); $hashedsalt = $key->RC4($hashedsalt_data); @@ -1898,18 +1888,18 @@ private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readCodepage() + private function readCodepage() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; code page identifier - $codepage = self::_GetInt2d($recordData, 0); + $codepage = self::getInt2d($recordData, 0); - $this->_codepage = PHPExcel_Shared_CodePage::NumberToName($codepage); + $this->codepage = PHPExcel_Shared_CodePage::NumberToName($codepage); } @@ -1925,13 +1915,13 @@ private function _readCodepage() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readDateMode() + private function readDateMode() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; 0 = base 1900, 1 = base 1904 PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); @@ -1944,42 +1934,42 @@ private function _readDateMode() /** * Read a FONT record */ - private function _readFont() + private function readFont() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { $objFont = new PHPExcel_Style_Font(); // offset: 0; size: 2; height of the font (in twips = 1/20 of a point) - $size = self::_GetInt2d($recordData, 0); + $size = self::getInt2d($recordData, 0); $objFont->setSize($size / 20); // offset: 2; size: 2; option flags // bit: 0; mask 0x0001; bold (redundant in BIFF5-BIFF8) // bit: 1; mask 0x0002; italic - $isItalic = (0x0002 & self::_GetInt2d($recordData, 2)) >> 1; + $isItalic = (0x0002 & self::getInt2d($recordData, 2)) >> 1; if ($isItalic) { $objFont->setItalic(true); } // bit: 2; mask 0x0004; underlined (redundant in BIFF5-BIFF8) // bit: 3; mask 0x0008; strike - $isStrike = (0x0008 & self::_GetInt2d($recordData, 2)) >> 3; + $isStrike = (0x0008 & self::getInt2d($recordData, 2)) >> 3; if ($isStrike) { $objFont->setStrikethrough(true); } // offset: 4; size: 2; colour index - $colorIndex = self::_GetInt2d($recordData, 4); + $colorIndex = self::getInt2d($recordData, 4); $objFont->colorIndex = $colorIndex; // offset: 6; size: 2; font weight - $weight = self::_GetInt2d($recordData, 6); + $weight = self::getInt2d($recordData, 6); switch ($weight) { case 0x02BC: $objFont->setBold(true); @@ -1987,7 +1977,7 @@ private function _readFont() } // offset: 8; size: 2; escapement type - $escapement = self::_GetInt2d($recordData, 8); + $escapement = self::getInt2d($recordData, 8); switch ($escapement) { case 0x0001: $objFont->setSuperScript(true); @@ -2020,14 +2010,14 @@ private function _readFont() // offset: 12; size: 1; character set // offset: 13; size: 1; not used // offset: 14; size: var; font name - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringShort(substr($recordData, 14)); + if ($this->version == self::XLS_BIFF8) { + $string = self::readUnicodeStringShort(substr($recordData, 14)); } else { - $string = $this->_readByteStringShort(substr($recordData, 14)); + $string = $this->readByteStringShort(substr($recordData, 14)); } $objFont->setName($string['value']); - $this->_objFonts[] = $objFont; + $this->objFonts[] = $objFont; } } @@ -2046,26 +2036,26 @@ private function _readFont() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readFormat() + private function readFormat() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { - $indexCode = self::_GetInt2d($recordData, 0); + if (!$this->readDataOnly) { + $indexCode = self::getInt2d($recordData, 0); - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong(substr($recordData, 2)); + if ($this->version == self::XLS_BIFF8) { + $string = self::readUnicodeStringLong(substr($recordData, 2)); } else { // BIFF7 - $string = $this->_readByteStringShort(substr($recordData, 2)); + $string = $this->readByteStringShort(substr($recordData, 2)); } $formatString = $string['value']; - $this->_formats[$indexCode] = $formatString; + $this->formats[$indexCode] = $formatString; } } @@ -2084,32 +2074,32 @@ private function _readFormat() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readXf() + private function readXf() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; $objStyle = new PHPExcel_Style(); - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; Index to FONT record - if (self::_GetInt2d($recordData, 0) < 4) { - $fontIndex = self::_GetInt2d($recordData, 0); + if (self::getInt2d($recordData, 0) < 4) { + $fontIndex = self::getInt2d($recordData, 0); } else { // this has to do with that index 4 is omitted in all BIFF versions for some strange reason // check the OpenOffice documentation of the FONT record - $fontIndex = self::_GetInt2d($recordData, 0) - 1; + $fontIndex = self::getInt2d($recordData, 0) - 1; } - $objStyle->setFont($this->_objFonts[$fontIndex]); + $objStyle->setFont($this->objFonts[$fontIndex]); // offset: 2; size: 2; Index to FORMAT record - $numberFormatIndex = self::_GetInt2d($recordData, 2); - if (isset($this->_formats[$numberFormatIndex])) { + $numberFormatIndex = self::getInt2d($recordData, 2); + if (isset($this->formats[$numberFormatIndex])) { // then we have user-defined format code - $numberformat = array('code' => $this->_formats[$numberFormatIndex]); + $numberformat = array('code' => $this->formats[$numberFormatIndex]); } elseif (($code = PHPExcel_Style_NumberFormat::builtInFormatCode($numberFormatIndex)) !== '') { // then we have built-in format code $numberformat = array('code' => $code); @@ -2121,7 +2111,7 @@ private function _readXf() // offset: 4; size: 2; XF type, cell protection, and parent style XF // bit 2-0; mask 0x0007; XF_TYPE_PROT - $xfTypeProt = self::_GetInt2d($recordData, 4); + $xfTypeProt = self::getInt2d($recordData, 4); // bit 0; mask 0x01; 1 = cell is locked $isLocked = (0x01 & $xfTypeProt) >> 0; $objStyle->getProtection()->setLocked($isLocked ? PHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); @@ -2186,7 +2176,7 @@ private function _readXf() break; } - if ($this->_version == self::XLS_BIFF8) { + if ($this->version == self::XLS_BIFF8) { // offset: 7; size: 1; XF_ROTATION: Text rotation angle $angle = ord($recordData{7}); $rotation = 0; @@ -2219,32 +2209,32 @@ private function _readXf() // offset: 10; size: 4; Cell border lines and background area // bit: 3-0; mask: 0x0000000F; left style - if ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) { + if ($bordersLeftStyle = self::mapBorderStyle((0x0000000F & self::getInt4d($recordData, 10)) >> 0)) { $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle); } // bit: 7-4; mask: 0x000000F0; right style - if ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) { + if ($bordersRightStyle = self::mapBorderStyle((0x000000F0 & self::getInt4d($recordData, 10)) >> 4)) { $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle); } // bit: 11-8; mask: 0x00000F00; top style - if ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) { + if ($bordersTopStyle = self::mapBorderStyle((0x00000F00 & self::getInt4d($recordData, 10)) >> 8)) { $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle); } // bit: 15-12; mask: 0x0000F000; bottom style - if ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) { + if ($bordersBottomStyle = self::mapBorderStyle((0x0000F000 & self::getInt4d($recordData, 10)) >> 12)) { $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle); } // bit: 22-16; mask: 0x007F0000; left color - $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16; + $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::getInt4d($recordData, 10)) >> 16; // bit: 29-23; mask: 0x3F800000; right color - $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23; + $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::getInt4d($recordData, 10)) >> 23; // bit: 30; mask: 0x40000000; 1 = diagonal line from top left to right bottom - $diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ? true : false; + $diagonalDown = (0x40000000 & self::getInt4d($recordData, 10)) >> 30 ? true : false; // bit: 31; mask: 0x80000000; 1 = diagonal line from bottom left to top right - $diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ? true : false; + $diagonalUp = (0x80000000 & self::getInt4d($recordData, 10)) >> 31 ? true : false; if ($diagonalUp == false && $diagonalDown == false) { $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); @@ -2258,29 +2248,29 @@ private function _readXf() // offset: 14; size: 4; // bit: 6-0; mask: 0x0000007F; top color - $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0; + $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::getInt4d($recordData, 14)) >> 0; // bit: 13-7; mask: 0x00003F80; bottom color - $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7; + $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::getInt4d($recordData, 14)) >> 7; // bit: 20-14; mask: 0x001FC000; diagonal color - $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14; + $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::getInt4d($recordData, 14)) >> 14; // bit: 24-21; mask: 0x01E00000; diagonal style - if ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) { + if ($bordersDiagonalStyle = self::mapBorderStyle((0x01E00000 & self::getInt4d($recordData, 14)) >> 21)) { $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle); } // bit: 31-26; mask: 0xFC000000 fill pattern - if ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) { + if ($fillType = self::mapFillPattern((0xFC000000 & self::getInt4d($recordData, 14)) >> 26)) { $objStyle->getFill()->setFillType($fillType); } // offset: 18; size: 2; pattern and background colour // bit: 6-0; mask: 0x007F; color index for pattern color - $objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0; + $objStyle->getFill()->startcolorIndex = (0x007F & self::getInt2d($recordData, 18)) >> 0; // bit: 13-7; mask: 0x3F80; color index for pattern background - $objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7; + $objStyle->getFill()->endcolorIndex = (0x3F80 & self::getInt2d($recordData, 18)) >> 7; } else { // BIFF5 @@ -2305,7 +2295,7 @@ private function _readXf() } // offset: 8; size: 4; cell border lines and background area - $borderAndBackground = self::_GetInt4d($recordData, 8); + $borderAndBackground = self::getInt4d($recordData, 8); // bit: 6-0; mask: 0x0000007F; color index for pattern color $objStyle->getFill()->startcolorIndex = (0x0000007F & $borderAndBackground) >> 0; @@ -2314,25 +2304,25 @@ private function _readXf() $objStyle->getFill()->endcolorIndex = (0x00003F80 & $borderAndBackground) >> 7; // bit: 21-16; mask: 0x003F0000; fill pattern - $objStyle->getFill()->setFillType(self::_mapFillPattern((0x003F0000 & $borderAndBackground) >> 16)); + $objStyle->getFill()->setFillType(self::mapFillPattern((0x003F0000 & $borderAndBackground) >> 16)); // bit: 24-22; mask: 0x01C00000; bottom line style - $objStyle->getBorders()->getBottom()->setBorderStyle(self::_mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22)); + $objStyle->getBorders()->getBottom()->setBorderStyle(self::mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22)); // bit: 31-25; mask: 0xFE000000; bottom line color $objStyle->getBorders()->getBottom()->colorIndex = (0xFE000000 & $borderAndBackground) >> 25; // offset: 12; size: 4; cell border lines - $borderLines = self::_GetInt4d($recordData, 12); + $borderLines = self::getInt4d($recordData, 12); // bit: 2-0; mask: 0x00000007; top line style - $objStyle->getBorders()->getTop()->setBorderStyle(self::_mapBorderStyle((0x00000007 & $borderLines) >> 0)); + $objStyle->getBorders()->getTop()->setBorderStyle(self::mapBorderStyle((0x00000007 & $borderLines) >> 0)); // bit: 5-3; mask: 0x00000038; left line style - $objStyle->getBorders()->getLeft()->setBorderStyle(self::_mapBorderStyle((0x00000038 & $borderLines) >> 3)); + $objStyle->getBorders()->getLeft()->setBorderStyle(self::mapBorderStyle((0x00000038 & $borderLines) >> 3)); // bit: 8-6; mask: 0x000001C0; right line style - $objStyle->getBorders()->getRight()->setBorderStyle(self::_mapBorderStyle((0x000001C0 & $borderLines) >> 6)); + $objStyle->getBorders()->getRight()->setBorderStyle(self::mapBorderStyle((0x000001C0 & $borderLines) >> 6)); // bit: 15-9; mask: 0x0000FE00; top line color index $objStyle->getBorders()->getTop()->colorIndex = (0x0000FE00 & $borderLines) >> 9; @@ -2347,18 +2337,18 @@ private function _readXf() // add cellStyleXf or cellXf and update mapping if ($isCellStyleXf) { // we only read one style XF record which is always the first - if ($this->_xfIndex == 0) { - $this->_phpExcel->addCellStyleXf($objStyle); - $this->_mapCellStyleXfIndex[$this->_xfIndex] = 0; + if ($this->xfIndex == 0) { + $this->phpExcel->addCellStyleXf($objStyle); + $this->mapCellStyleXfIndex[$this->xfIndex] = 0; } } else { // we read all cell XF records - $this->_phpExcel->addCellXf($objStyle); - $this->_mapCellXfIndex[$this->_xfIndex] = count($this->_phpExcel->getCellXfCollection()) - 1; + $this->phpExcel->addCellXf($objStyle); + $this->mapCellXfIndex[$this->xfIndex] = count($this->phpExcel->getCellXfCollection()) - 1; } // update XF index for when we read next record - ++$this->_xfIndex; + ++$this->xfIndex; } } @@ -2366,15 +2356,15 @@ private function _readXf() /** * */ - private function _readXfExt() + private function readXfExt() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; 0x087D = repeated header // offset: 2; size: 2 @@ -2384,141 +2374,141 @@ private function _readXfExt() // offset: 12; size: 2; record version // offset: 14; size: 2; index to XF record which this record modifies - $ixfe = self::_GetInt2d($recordData, 14); + $ixfe = self::getInt2d($recordData, 14); // offset: 16; size: 2; not used // offset: 18; size: 2; number of extension properties that follow - $cexts = self::_GetInt2d($recordData, 18); + $cexts = self::getInt2d($recordData, 18); // start reading the actual extension data $offset = 20; while ($offset < $length) { // extension type - $extType = self::_GetInt2d($recordData, $offset); + $extType = self::getInt2d($recordData, $offset); // extension length - $cb = self::_GetInt2d($recordData, $offset + 2); + $cb = self::getInt2d($recordData, $offset + 2); // extension data $extData = substr($recordData, $offset + 4, $cb); switch ($extType) { case 4: // fill start color - $xclfType = self::_GetInt2d($extData, 0); // color type + $xclfType = self::getInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) if ($xclfType == 2) { $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); + if (isset($this->mapCellXfIndex[$ixfe])) { + $fill = $this->phpExcel->getCellXfByIndex($this->mapCellXfIndex[$ixfe])->getFill(); $fill->getStartColor()->setRGB($rgb); unset($fill->startcolorIndex); // normal color index does not apply, discard } } break; case 5: // fill end color - $xclfType = self::_GetInt2d($extData, 0); // color type + $xclfType = self::getInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) if ($xclfType == 2) { $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); + if (isset($this->mapCellXfIndex[$ixfe])) { + $fill = $this->phpExcel->getCellXfByIndex($this->mapCellXfIndex[$ixfe])->getFill(); $fill->getEndColor()->setRGB($rgb); unset($fill->endcolorIndex); // normal color index does not apply, discard } } break; case 7: // border color top - $xclfType = self::_GetInt2d($extData, 0); // color type + $xclfType = self::getInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) if ($xclfType == 2) { $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $top = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getTop(); + if (isset($this->mapCellXfIndex[$ixfe])) { + $top = $this->phpExcel->getCellXfByIndex($this->mapCellXfIndex[$ixfe])->getBorders()->getTop(); $top->getColor()->setRGB($rgb); unset($top->colorIndex); // normal color index does not apply, discard } } break; case 8: // border color bottom - $xclfType = self::_GetInt2d($extData, 0); // color type + $xclfType = self::getInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) if ($xclfType == 2) { $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $bottom = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getBottom(); + if (isset($this->mapCellXfIndex[$ixfe])) { + $bottom = $this->phpExcel->getCellXfByIndex($this->mapCellXfIndex[$ixfe])->getBorders()->getBottom(); $bottom->getColor()->setRGB($rgb); unset($bottom->colorIndex); // normal color index does not apply, discard } } break; case 9: // border color left - $xclfType = self::_GetInt2d($extData, 0); // color type + $xclfType = self::getInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) if ($xclfType == 2) { $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $left = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getLeft(); + if (isset($this->mapCellXfIndex[$ixfe])) { + $left = $this->phpExcel->getCellXfByIndex($this->mapCellXfIndex[$ixfe])->getBorders()->getLeft(); $left->getColor()->setRGB($rgb); unset($left->colorIndex); // normal color index does not apply, discard } } break; case 10: // border color right - $xclfType = self::_GetInt2d($extData, 0); // color type + $xclfType = self::getInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) if ($xclfType == 2) { $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $right = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getRight(); + if (isset($this->mapCellXfIndex[$ixfe])) { + $right = $this->phpExcel->getCellXfByIndex($this->mapCellXfIndex[$ixfe])->getBorders()->getRight(); $right->getColor()->setRGB($rgb); unset($right->colorIndex); // normal color index does not apply, discard } } break; case 11: // border color diagonal - $xclfType = self::_GetInt2d($extData, 0); // color type + $xclfType = self::getInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) if ($xclfType == 2) { $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $diagonal = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getDiagonal(); + if (isset($this->mapCellXfIndex[$ixfe])) { + $diagonal = $this->phpExcel->getCellXfByIndex($this->mapCellXfIndex[$ixfe])->getBorders()->getDiagonal(); $diagonal->getColor()->setRGB($rgb); unset($diagonal->colorIndex); // normal color index does not apply, discard } } break; case 13: // font color - $xclfType = self::_GetInt2d($extData, 0); // color type + $xclfType = self::getInt2d($extData, 0); // color type $xclrValue = substr($extData, 4, 4); // color value (value based on color type) if ($xclfType == 2) { $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); // modify the relevant style property - if (isset($this->_mapCellXfIndex[$ixfe])) { - $font = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFont(); + if (isset($this->mapCellXfIndex[$ixfe])) { + $font = $this->phpExcel->getCellXfByIndex($this->mapCellXfIndex[$ixfe])->getFont(); $font->getColor()->setRGB($rgb); unset($font->colorIndex); // normal color index does not apply, discard } @@ -2536,17 +2526,17 @@ private function _readXfExt() /** * Read STYLE record */ - private function _readStyle() + private function readStyle() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; index to XF record and flag for built-in style - $ixfe = self::_GetInt2d($recordData, 0); + $ixfe = self::getInt2d($recordData, 0); // bit: 11-0; mask 0x0FFF; index to XF record $xfIndex = (0x0FFF & $ixfe) >> 0; @@ -2575,22 +2565,22 @@ private function _readStyle() /** * Read PALETTE record */ - private function _readPalette() + private function readPalette() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; number of following colors - $nm = self::_GetInt2d($recordData, 0); + $nm = self::getInt2d($recordData, 0); // list of RGB colors for ($i = 0; $i < $nm; ++$i) { $rgb = substr($recordData, 2 + 4 * $i, 4); - $this->_palette[] = self::_readRGB($rgb); + $this->palette[] = self::readRGB($rgb); } } } @@ -2608,17 +2598,17 @@ private function _readPalette() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readSheet() + private function readSheet() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // offset: 0; size: 4; absolute stream position of the BOF record of the sheet // NOTE: not encrypted - $rec_offset = self::_GetInt4d($this->_data, $this->_pos + 4); + $rec_offset = self::getInt4d($this->data, $this->pos + 4); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 4; size: 1; sheet state switch (ord($recordData{4})) { @@ -2640,15 +2630,15 @@ private function _readSheet() $sheetType = ord($recordData{5}); // offset: 6; size: var; sheet name - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringShort(substr($recordData, 6)); + if ($this->version == self::XLS_BIFF8) { + $string = self::readUnicodeStringShort(substr($recordData, 6)); $rec_name = $string['value']; - } elseif ($this->_version == self::XLS_BIFF7) { - $string = $this->_readByteStringShort(substr($recordData, 6)); + } elseif ($this->version == self::XLS_BIFF7) { + $string = $this->readByteStringShort(substr($recordData, 6)); $rec_name = $string['value']; } - $this->_sheets[] = array( + $this->sheets[] = array( 'name' => $rec_name, 'offset' => $rec_offset, 'sheetState' => $sheetState, @@ -2660,13 +2650,13 @@ private function _readSheet() /** * Read EXTERNALBOOK record */ - private function _readExternalBook() + private function readExternalBook() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset within record data $offset = 0; @@ -2675,23 +2665,23 @@ private function _readExternalBook() if (strlen($recordData) > 4) { // external reference // offset: 0; size: 2; number of sheet names ($nm) - $nm = self::_GetInt2d($recordData, 0); + $nm = self::getInt2d($recordData, 0); $offset += 2; // offset: 2; size: var; encoded URL without sheet name (Unicode string, 16-bit length) - $encodedUrlString = self::_readUnicodeStringLong(substr($recordData, 2)); + $encodedUrlString = self::readUnicodeStringLong(substr($recordData, 2)); $offset += $encodedUrlString['size']; // offset: var; size: var; list of $nm sheet names (Unicode strings, 16-bit length) $externalSheetNames = array(); for ($i = 0; $i < $nm; ++$i) { - $externalSheetNameString = self::_readUnicodeStringLong(substr($recordData, $offset)); + $externalSheetNameString = self::readUnicodeStringLong(substr($recordData, $offset)); $externalSheetNames[] = $externalSheetNameString['value']; $offset += $externalSheetNameString['size']; } // store the record data - $this->_externalBooks[] = array( + $this->externalBooks[] = array( 'type' => 'external', 'encodedUrl' => $encodedUrlString['value'], 'externalSheetNames' => $externalSheetNames, @@ -2700,20 +2690,20 @@ private function _readExternalBook() // internal reference // offset: 0; size: 2; number of sheet in this document // offset: 2; size: 2; 0x01 0x04 - $this->_externalBooks[] = array( + $this->externalBooks[] = array( 'type' => 'internal', ); } elseif (substr($recordData, 0, 4) == pack('vCC', 0x0001, 0x01, 0x3A)) { // add-in function // offset: 0; size: 2; 0x0001 - $this->_externalBooks[] = array( + $this->externalBooks[] = array( 'type' => 'addInFunction', ); } elseif (substr($recordData, 0, 2) == pack('v', 0x0000)) { // DDE links, OLE links // offset: 0; size: 2; 0x0000 // offset: 2; size: var; encoded source document name - $this->_externalBooks[] = array( + $this->externalBooks[] = array( 'type' => 'DDEorOLE', ); } @@ -2723,31 +2713,31 @@ private function _readExternalBook() /** * Read EXTERNNAME record. */ - private function _readExternName() + private function readExternName() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // external sheet references provided for named cells - if ($this->_version == self::XLS_BIFF8) { + if ($this->version == self::XLS_BIFF8) { // offset: 0; size: 2; options - $options = self::_GetInt2d($recordData, 0); + $options = self::getInt2d($recordData, 0); // offset: 2; size: 2; // offset: 4; size: 2; not used // offset: 6; size: var - $nameString = self::_readUnicodeStringShort(substr($recordData, 6)); + $nameString = self::readUnicodeStringShort(substr($recordData, 6)); // offset: var; size: var; formula data $offset = 6 + $nameString['size']; - $formula = $this->_getFormulaFromStructure(substr($recordData, $offset)); + $formula = $this->getFormulaFromStructure(substr($recordData, $offset)); - $this->_externalNames[] = array( + $this->externalNames[] = array( 'name' => $nameString['value'], 'formula' => $formula, ); @@ -2758,26 +2748,26 @@ private function _readExternName() /** * Read EXTERNSHEET record */ - private function _readExternSheet() + private function readExternSheet() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // external sheet references provided for named cells - if ($this->_version == self::XLS_BIFF8) { + if ($this->version == self::XLS_BIFF8) { // offset: 0; size: 2; number of following ref structures - $nm = self::_GetInt2d($recordData, 0); + $nm = self::getInt2d($recordData, 0); for ($i = 0; $i < $nm; ++$i) { - $this->_ref[] = array( + $this->ref[] = array( // offset: 2 + 6 * $i; index to EXTERNALBOOK record - 'externalBookIndex' => self::_GetInt2d($recordData, 2 + 6 * $i), + 'externalBookIndex' => self::getInt2d($recordData, 2 + 6 * $i), // offset: 4 + 6 * $i; index to first sheet in EXTERNALBOOK record - 'firstSheetIndex' => self::_GetInt2d($recordData, 4 + 6 * $i), + 'firstSheetIndex' => self::getInt2d($recordData, 4 + 6 * $i), // offset: 6 + 6 * $i; index to last sheet in EXTERNALBOOK record - 'lastSheetIndex' => self::_GetInt2d($recordData, 6 + 6 * $i), + 'lastSheetIndex' => self::getInt2d($recordData, 6 + 6 * $i), ); } } @@ -2795,19 +2785,19 @@ private function _readExternSheet() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readDefinedName() + private function readDefinedName() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_version == self::XLS_BIFF8) { + if ($this->version == self::XLS_BIFF8) { // retrieves named cells // offset: 0; size: 2; option flags - $opts = self::_GetInt2d($recordData, 0); + $opts = self::getInt2d($recordData, 0); // bit: 5; mask: 0x0020; 0 = user-defined name, 1 = built-in-name $isBuiltInName = (0x0020 & $opts) >> 5; @@ -2819,25 +2809,25 @@ private function _readDefinedName() // offset: 4; size: 2; size of the formula data (it can happen that this is zero) // note: there can also be additional data, this is not included in $flen - $flen = self::_GetInt2d($recordData, 4); + $flen = self::getInt2d($recordData, 4); // offset: 8; size: 2; 0=Global name, otherwise index to sheet (1-based) - $scope = self::_GetInt2d($recordData, 8); + $scope = self::getInt2d($recordData, 8); // offset: 14; size: var; Name (Unicode string without length field) - $string = self::_readUnicodeString(substr($recordData, 14), $nlen); + $string = self::readUnicodeString(substr($recordData, 14), $nlen); // offset: var; size: $flen; formula data $offset = 14 + $string['size']; $formulaStructure = pack('v', $flen) . substr($recordData, $offset); try { - $formula = $this->_getFormulaFromStructure($formulaStructure); + $formula = $this->getFormulaFromStructure($formulaStructure); } catch (PHPExcel_Exception $e) { $formula = ''; } - $this->_definedname[] = array( + $this->definedname[] = array( 'isBuiltInName' => $isBuiltInName, 'name' => $string['value'], 'formula' => $formula, @@ -2850,15 +2840,15 @@ private function _readDefinedName() /** * Read MSODRAWINGGROUP record */ - private function _readMsoDrawingGroup() + private function readMsoDrawingGroup() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $length = self::getInt2d($this->data, $this->pos + 2); // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); + $splicedRecordData = $this->getSplicedRecordData(); $recordData = $splicedRecordData['recordData']; - $this->_drawingGroupData .= $recordData; + $this->drawingGroupData .= $recordData; } @@ -2873,13 +2863,13 @@ private function _readMsoDrawingGroup() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" **/ - private function _readSst() + private function readSst() { // offset within (spliced) record data $pos = 0; // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); + $splicedRecordData = $this->getSplicedRecordData(); $recordData = $splicedRecordData['recordData']; $spliceOffsets = $splicedRecordData['spliceOffsets']; @@ -2888,13 +2878,13 @@ private function _readSst() $pos += 4; // offset: 4; size: 4; number of following strings ($nm) - $nm = self::_GetInt4d($recordData, 4); + $nm = self::getInt4d($recordData, 4); $pos += 4; // loop through the Unicode strings (16-bit length) for ($i = 0; $i < $nm; ++$i) { // number of characters in the Unicode string - $numChars = self::_GetInt2d($recordData, $pos); + $numChars = self::getInt2d($recordData, $pos); $pos += 2; // option flags @@ -2912,13 +2902,13 @@ private function _readSst() if ($hasRichText) { // number of Rich-Text formatting runs - $formattingRuns = self::_GetInt2d($recordData, $pos); + $formattingRuns = self::getInt2d($recordData, $pos); $pos += 2; } if ($hasAsian) { // size of Asian phonetic setting - $extendedRunLength = self::_GetInt4d($recordData, $pos); + $extendedRunLength = self::getInt4d($recordData, $pos); $pos += 4; } @@ -3010,7 +3000,7 @@ private function _readSst() } // convert to UTF-8 - $retstr = self::_encodeUTF16($retstr, $isCompressed); + $retstr = self::encodeUTF16($retstr, $isCompressed); // read additional Rich-Text information, if any $fmtRuns = array(); @@ -3018,10 +3008,10 @@ private function _readSst() // list of formatting runs for ($j = 0; $j < $formattingRuns; ++$j) { // first formatted character; zero-based - $charPos = self::_GetInt2d($recordData, $pos + $j * 4); + $charPos = self::getInt2d($recordData, $pos + $j * 4); // index to font record - $fontIndex = self::_GetInt2d($recordData, $pos + 2 + $j * 4); + $fontIndex = self::getInt2d($recordData, $pos + 2 + $j * 4); $fmtRuns[] = array( 'charPos' => $charPos, @@ -3038,31 +3028,31 @@ private function _readSst() } // store the shared sting - $this->_sst[] = array( + $this->sst[] = array( 'value' => $retstr, 'fmtRuns' => $fmtRuns, ); } - // _getSplicedRecordData() takes care of moving current position in data stream + // getSplicedRecordData() takes care of moving current position in data stream } /** * Read PRINTGRIDLINES record */ - private function _readPrintGridlines() + private function readPrintGridlines() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + if ($this->version == self::XLS_BIFF8 && !$this->readDataOnly) { // offset: 0; size: 2; 0 = do not print sheet grid lines; 1 = print sheet gridlines - $printGridlines = (bool) self::_GetInt2d($recordData, 0); - $this->_phpSheet->setPrintGridlines($printGridlines); + $printGridlines = (bool) self::getInt2d($recordData, 0); + $this->phpSheet->setPrintGridlines($printGridlines); } } @@ -3070,71 +3060,71 @@ private function _readPrintGridlines() /** * Read DEFAULTROWHEIGHT record */ - private function _readDefaultRowHeight() + private function readDefaultRowHeight() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; option flags // offset: 2; size: 2; default height for unused rows, (twips 1/20 point) - $height = self::_GetInt2d($recordData, 2); - $this->_phpSheet->getDefaultRowDimension()->setRowHeight($height / 20); + $height = self::getInt2d($recordData, 2); + $this->phpSheet->getDefaultRowDimension()->setRowHeight($height / 20); } /** * Read SHEETPR record */ - private function _readSheetPr() + private function readSheetPr() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2 // bit: 6; mask: 0x0040; 0 = outline buttons above outline group - $isSummaryBelow = (0x0040 & self::_GetInt2d($recordData, 0)) >> 6; - $this->_phpSheet->setShowSummaryBelow($isSummaryBelow); + $isSummaryBelow = (0x0040 & self::getInt2d($recordData, 0)) >> 6; + $this->phpSheet->setShowSummaryBelow($isSummaryBelow); // bit: 7; mask: 0x0080; 0 = outline buttons left of outline group - $isSummaryRight = (0x0080 & self::_GetInt2d($recordData, 0)) >> 7; - $this->_phpSheet->setShowSummaryRight($isSummaryRight); + $isSummaryRight = (0x0080 & self::getInt2d($recordData, 0)) >> 7; + $this->phpSheet->setShowSummaryRight($isSummaryRight); // bit: 8; mask: 0x100; 0 = scale printout in percent, 1 = fit printout to number of pages // this corresponds to radio button setting in page setup dialog in Excel - $this->_isFitToPages = (bool) ((0x0100 & self::_GetInt2d($recordData, 0)) >> 8); + $this->isFitToPages = (bool) ((0x0100 & self::getInt2d($recordData, 0)) >> 8); } /** * Read HORIZONTALPAGEBREAKS record */ - private function _readHorizontalPageBreaks() + private function readHorizontalPageBreaks() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + if ($this->version == self::XLS_BIFF8 && !$this->readDataOnly) { // offset: 0; size: 2; number of the following row index structures - $nm = self::_GetInt2d($recordData, 0); + $nm = self::getInt2d($recordData, 0); // offset: 2; size: 6 * $nm; list of $nm row index structures for ($i = 0; $i < $nm; ++$i) { - $r = self::_GetInt2d($recordData, 2 + 6 * $i); - $cf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); - $cl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); + $r = self::getInt2d($recordData, 2 + 6 * $i); + $cf = self::getInt2d($recordData, 2 + 6 * $i + 2); + $cl = self::getInt2d($recordData, 2 + 6 * $i + 4); // not sure why two column indexes are necessary? - $this->_phpSheet->setBreakByColumnAndRow($cf, $r, PHPExcel_Worksheet::BREAK_ROW); + $this->phpSheet->setBreakByColumnAndRow($cf, $r, PHPExcel_Worksheet::BREAK_ROW); } } } @@ -3143,26 +3133,26 @@ private function _readHorizontalPageBreaks() /** * Read VERTICALPAGEBREAKS record */ - private function _readVerticalPageBreaks() + private function readVerticalPageBreaks() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + if ($this->version == self::XLS_BIFF8 && !$this->readDataOnly) { // offset: 0; size: 2; number of the following column index structures - $nm = self::_GetInt2d($recordData, 0); + $nm = self::getInt2d($recordData, 0); // offset: 2; size: 6 * $nm; list of $nm row index structures for ($i = 0; $i < $nm; ++$i) { - $c = self::_GetInt2d($recordData, 2 + 6 * $i); - $rf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); - $rl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); + $c = self::getInt2d($recordData, 2 + 6 * $i); + $rf = self::getInt2d($recordData, 2 + 6 * $i + 2); + $rl = self::getInt2d($recordData, 2 + 6 * $i + 4); // not sure why two row indexes are necessary? - $this->_phpSheet->setBreakByColumnAndRow($c, $rf, PHPExcel_Worksheet::BREAK_COLUMN); + $this->phpSheet->setBreakByColumnAndRow($c, $rf, PHPExcel_Worksheet::BREAK_COLUMN); } } } @@ -3171,26 +3161,26 @@ private function _readVerticalPageBreaks() /** * Read HEADER record */ - private function _readHeader() + private function readHeader() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: var // realized that $recordData can be empty even when record exists if ($recordData) { - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong($recordData); + if ($this->version == self::XLS_BIFF8) { + $string = self::readUnicodeStringLong($recordData); } else { - $string = $this->_readByteStringShort($recordData); + $string = $this->readByteStringShort($recordData); } - $this->_phpSheet->getHeaderFooter()->setOddHeader($string['value']); - $this->_phpSheet->getHeaderFooter()->setEvenHeader($string['value']); + $this->phpSheet->getHeaderFooter()->setOddHeader($string['value']); + $this->phpSheet->getHeaderFooter()->setEvenHeader($string['value']); } } } @@ -3199,25 +3189,25 @@ private function _readHeader() /** * Read FOOTER record */ - private function _readFooter() + private function readFooter() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: var // realized that $recordData can be empty even when record exists if ($recordData) { - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong($recordData); + if ($this->version == self::XLS_BIFF8) { + $string = self::readUnicodeStringLong($recordData); } else { - $string = $this->_readByteStringShort($recordData); + $string = $this->readByteStringShort($recordData); } - $this->_phpSheet->getHeaderFooter()->setOddFooter($string['value']); - $this->_phpSheet->getHeaderFooter()->setEvenFooter($string['value']); + $this->phpSheet->getHeaderFooter()->setOddFooter($string['value']); + $this->phpSheet->getHeaderFooter()->setEvenFooter($string['value']); } } } @@ -3226,19 +3216,19 @@ private function _readFooter() /** * Read HCENTER record */ - private function _readHcenter() + private function readHcenter() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; 0 = print sheet left aligned, 1 = print sheet centered horizontally - $isHorizontalCentered = (bool) self::_GetInt2d($recordData, 0); + $isHorizontalCentered = (bool) self::getInt2d($recordData, 0); - $this->_phpSheet->getPageSetup()->setHorizontalCentered($isHorizontalCentered); + $this->phpSheet->getPageSetup()->setHorizontalCentered($isHorizontalCentered); } } @@ -3246,19 +3236,19 @@ private function _readHcenter() /** * Read VCENTER record */ - private function _readVcenter() + private function readVcenter() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; 0 = print sheet aligned at top page border, 1 = print sheet vertically centered - $isVerticalCentered = (bool) self::_GetInt2d($recordData, 0); + $isVerticalCentered = (bool) self::getInt2d($recordData, 0); - $this->_phpSheet->getPageSetup()->setVerticalCentered($isVerticalCentered); + $this->phpSheet->getPageSetup()->setVerticalCentered($isVerticalCentered); } } @@ -3266,17 +3256,17 @@ private function _readVcenter() /** * Read LEFTMARGIN record */ - private function _readLeftMargin() + private function readLeftMargin() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setLeft(self::_extractNumber($recordData)); + $this->phpSheet->getPageMargins()->setLeft(self::extractNumber($recordData)); } } @@ -3284,17 +3274,17 @@ private function _readLeftMargin() /** * Read RIGHTMARGIN record */ - private function _readRightMargin() + private function readRightMargin() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setRight(self::_extractNumber($recordData)); + $this->phpSheet->getPageMargins()->setRight(self::extractNumber($recordData)); } } @@ -3302,17 +3292,17 @@ private function _readRightMargin() /** * Read TOPMARGIN record */ - private function _readTopMargin() + private function readTopMargin() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setTop(self::_extractNumber($recordData)); + $this->phpSheet->getPageMargins()->setTop(self::extractNumber($recordData)); } } @@ -3320,17 +3310,17 @@ private function _readTopMargin() /** * Read BOTTOMMARGIN record */ - private function _readBottomMargin() + private function readBottomMargin() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 8 - $this->_phpSheet->getPageMargins()->setBottom(self::_extractNumber($recordData)); + $this->phpSheet->getPageMargins()->setBottom(self::extractNumber($recordData)); } } @@ -3338,60 +3328,60 @@ private function _readBottomMargin() /** * Read PAGESETUP record */ - private function _readPageSetup() + private function readPageSetup() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; paper size - $paperSize = self::_GetInt2d($recordData, 0); + $paperSize = self::getInt2d($recordData, 0); // offset: 2; size: 2; scaling factor - $scale = self::_GetInt2d($recordData, 2); + $scale = self::getInt2d($recordData, 2); // offset: 6; size: 2; fit worksheet width to this number of pages, 0 = use as many as needed - $fitToWidth = self::_GetInt2d($recordData, 6); + $fitToWidth = self::getInt2d($recordData, 6); // offset: 8; size: 2; fit worksheet height to this number of pages, 0 = use as many as needed - $fitToHeight = self::_GetInt2d($recordData, 8); + $fitToHeight = self::getInt2d($recordData, 8); // offset: 10; size: 2; option flags // bit: 1; mask: 0x0002; 0=landscape, 1=portrait - $isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1; + $isPortrait = (0x0002 & self::getInt2d($recordData, 10)) >> 1; // bit: 2; mask: 0x0004; 1= paper size, scaling factor, paper orient. not init // when this bit is set, do not use flags for those properties - $isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2; + $isNotInit = (0x0004 & self::getInt2d($recordData, 10)) >> 2; if (!$isNotInit) { - $this->_phpSheet->getPageSetup()->setPaperSize($paperSize); + $this->phpSheet->getPageSetup()->setPaperSize($paperSize); switch ($isPortrait) { case 0: - $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); + $this->phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); break; case 1: - $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); + $this->phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); break; } - $this->_phpSheet->getPageSetup()->setScale($scale, false); - $this->_phpSheet->getPageSetup()->setFitToPage((bool) $this->_isFitToPages); - $this->_phpSheet->getPageSetup()->setFitToWidth($fitToWidth, false); - $this->_phpSheet->getPageSetup()->setFitToHeight($fitToHeight, false); + $this->phpSheet->getPageSetup()->setScale($scale, false); + $this->phpSheet->getPageSetup()->setFitToPage((bool) $this->isFitToPages); + $this->phpSheet->getPageSetup()->setFitToWidth($fitToWidth, false); + $this->phpSheet->getPageSetup()->setFitToHeight($fitToHeight, false); } // offset: 16; size: 8; header margin (IEEE 754 floating-point value) - $marginHeader = self::_extractNumber(substr($recordData, 16, 8)); - $this->_phpSheet->getPageMargins()->setHeader($marginHeader); + $marginHeader = self::extractNumber(substr($recordData, 16, 8)); + $this->phpSheet->getPageMargins()->setHeader($marginHeader); // offset: 24; size: 8; footer margin (IEEE 754 floating-point value) - $marginFooter = self::_extractNumber(substr($recordData, 24, 8)); - $this->_phpSheet->getPageMargins()->setFooter($marginFooter); + $marginFooter = self::extractNumber(substr($recordData, 24, 8)); + $this->phpSheet->getPageMargins()->setFooter($marginFooter); } } @@ -3400,89 +3390,89 @@ private function _readPageSetup() * PROTECT - Sheet protection (BIFF2 through BIFF8) * if this record is omitted, then it also means no sheet protection */ - private function _readProtect() + private function readProtect() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_readDataOnly) { + if ($this->readDataOnly) { return; } // offset: 0; size: 2; // bit 0, mask 0x01; 1 = sheet is protected - $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; - $this->_phpSheet->getProtection()->setSheet((bool)$bool); + $bool = (0x01 & self::getInt2d($recordData, 0)) >> 0; + $this->phpSheet->getProtection()->setSheet((bool)$bool); } /** * SCENPROTECT */ - private function _readScenProtect() + private function readScenProtect() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_readDataOnly) { + if ($this->readDataOnly) { return; } // offset: 0; size: 2; // bit: 0, mask 0x01; 1 = scenarios are protected - $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + $bool = (0x01 & self::getInt2d($recordData, 0)) >> 0; - $this->_phpSheet->getProtection()->setScenarios((bool)$bool); + $this->phpSheet->getProtection()->setScenarios((bool)$bool); } /** * OBJECTPROTECT */ - private function _readObjectProtect() + private function readObjectProtect() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_readDataOnly) { + if ($this->readDataOnly) { return; } // offset: 0; size: 2; // bit: 0, mask 0x01; 1 = objects are protected - $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + $bool = (0x01 & self::getInt2d($recordData, 0)) >> 0; - $this->_phpSheet->getProtection()->setObjects((bool)$bool); + $this->phpSheet->getProtection()->setObjects((bool)$bool); } /** * PASSWORD - Sheet protection (hashed) password (BIFF2 through BIFF8) */ - private function _readPassword() + private function readPassword() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; 16-bit hash value of password - $password = strtoupper(dechex(self::_GetInt2d($recordData, 0))); // the hashed password - $this->_phpSheet->getProtection()->setPassword($password, true); + $password = strtoupper(dechex(self::getInt2d($recordData, 0))); // the hashed password + $this->phpSheet->getProtection()->setPassword($password, true); } } @@ -3490,18 +3480,18 @@ private function _readPassword() /** * Read DEFCOLWIDTH record */ - private function _readDefColWidth() + private function readDefColWidth() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; default column width - $width = self::_GetInt2d($recordData, 0); + $width = self::getInt2d($recordData, 0); if ($width != 8) { - $this->_phpSheet->getDefaultColumnDimension()->setWidth($width); + $this->phpSheet->getDefaultColumnDimension()->setWidth($width); } } @@ -3509,49 +3499,49 @@ private function _readDefColWidth() /** * Read COLINFO record */ - private function _readColInfo() + private function readColInfo() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; index to first column in range - $fc = self::_GetInt2d($recordData, 0); // first column index + $fc = self::getInt2d($recordData, 0); // first column index // offset: 2; size: 2; index to last column in range - $lc = self::_GetInt2d($recordData, 2); // first column index + $lc = self::getInt2d($recordData, 2); // first column index // offset: 4; size: 2; width of the column in 1/256 of the width of the zero character - $width = self::_GetInt2d($recordData, 4); + $width = self::getInt2d($recordData, 4); // offset: 6; size: 2; index to XF record for default column formatting - $xfIndex = self::_GetInt2d($recordData, 6); + $xfIndex = self::getInt2d($recordData, 6); // offset: 8; size: 2; option flags // bit: 0; mask: 0x0001; 1= columns are hidden - $isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0; + $isHidden = (0x0001 & self::getInt2d($recordData, 8)) >> 0; // bit: 10-8; mask: 0x0700; outline level of the columns (0 = no outline) - $level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8; + $level = (0x0700 & self::getInt2d($recordData, 8)) >> 8; // bit: 12; mask: 0x1000; 1 = collapsed - $isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12; + $isCollapsed = (0x1000 & self::getInt2d($recordData, 8)) >> 12; // offset: 10; size: 2; not used for ($i = $fc; $i <= $lc; ++$i) { if ($lc == 255 || $lc == 256) { - $this->_phpSheet->getDefaultColumnDimension()->setWidth($width / 256); + $this->phpSheet->getDefaultColumnDimension()->setWidth($width / 256); break; } - $this->_phpSheet->getColumnDimensionByColumn($i)->setWidth($width / 256); - $this->_phpSheet->getColumnDimensionByColumn($i)->setVisible(!$isHidden); - $this->_phpSheet->getColumnDimensionByColumn($i)->setOutlineLevel($level); - $this->_phpSheet->getColumnDimensionByColumn($i)->setCollapsed($isCollapsed); - $this->_phpSheet->getColumnDimensionByColumn($i)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + $this->phpSheet->getColumnDimensionByColumn($i)->setWidth($width / 256); + $this->phpSheet->getColumnDimensionByColumn($i)->setVisible(!$isHidden); + $this->phpSheet->getColumnDimensionByColumn($i)->setOutlineLevel($level); + $this->phpSheet->getColumnDimensionByColumn($i)->setCollapsed($isCollapsed); + $this->phpSheet->getColumnDimensionByColumn($i)->setXfIndex($this->mapCellXfIndex[$xfIndex]); } } } @@ -3567,17 +3557,17 @@ private function _readColInfo() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readRow() + private function readRow() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; index of this row - $r = self::_GetInt2d($recordData, 0); + $r = self::getInt2d($recordData, 0); // offset: 2; size: 2; index to column of the first cell which is described by a cell record @@ -3586,13 +3576,13 @@ private function _readRow() // offset: 6; size: 2; // bit: 14-0; mask: 0x7FFF; height of the row, in twips = 1/20 of a point - $height = (0x7FFF & self::_GetInt2d($recordData, 6)) >> 0; + $height = (0x7FFF & self::getInt2d($recordData, 6)) >> 0; // bit: 15: mask: 0x8000; 0 = row has custom height; 1= row has default height - $useDefaultHeight = (0x8000 & self::_GetInt2d($recordData, 6)) >> 15; + $useDefaultHeight = (0x8000 & self::getInt2d($recordData, 6)) >> 15; if (!$useDefaultHeight) { - $this->_phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20); + $this->phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20); } // offset: 8; size: 2; not used @@ -3602,25 +3592,25 @@ private function _readRow() // offset: 12; size: 4; option flags and default row formatting // bit: 2-0: mask: 0x00000007; outline level of the row - $level = (0x00000007 & self::_GetInt4d($recordData, 12)) >> 0; - $this->_phpSheet->getRowDimension($r + 1)->setOutlineLevel($level); + $level = (0x00000007 & self::getInt4d($recordData, 12)) >> 0; + $this->phpSheet->getRowDimension($r + 1)->setOutlineLevel($level); // bit: 4; mask: 0x00000010; 1 = outline group start or ends here... and is collapsed - $isCollapsed = (0x00000010 & self::_GetInt4d($recordData, 12)) >> 4; - $this->_phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed); + $isCollapsed = (0x00000010 & self::getInt4d($recordData, 12)) >> 4; + $this->phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed); // bit: 5; mask: 0x00000020; 1 = row is hidden - $isHidden = (0x00000020 & self::_GetInt4d($recordData, 12)) >> 5; - $this->_phpSheet->getRowDimension($r + 1)->setVisible(!$isHidden); + $isHidden = (0x00000020 & self::getInt4d($recordData, 12)) >> 5; + $this->phpSheet->getRowDimension($r + 1)->setVisible(!$isHidden); // bit: 7; mask: 0x00000080; 1 = row has explicit format - $hasExplicitFormat = (0x00000080 & self::_GetInt4d($recordData, 12)) >> 7; + $hasExplicitFormat = (0x00000080 & self::getInt4d($recordData, 12)) >> 7; // bit: 27-16; mask: 0x0FFF0000; only applies when hasExplicitFormat = 1; index to XF record - $xfIndex = (0x0FFF0000 & self::_GetInt4d($recordData, 12)) >> 16; + $xfIndex = (0x0FFF0000 & self::getInt4d($recordData, 12)) >> 16; if ($hasExplicitFormat) { - $this->_phpSheet->getRowDimension($r + 1)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + $this->phpSheet->getRowDimension($r + 1)->setXfIndex($this->mapCellXfIndex[$xfIndex]); } } } @@ -3637,34 +3627,34 @@ private function _readRow() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readRk() + private function readRk() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); + $row = self::getInt2d($recordData, 0); // offset: 2; size: 2; index to column - $column = self::_GetInt2d($recordData, 2); + $column = self::getInt2d($recordData, 2); $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) { // offset: 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); + $xfIndex = self::getInt2d($recordData, 4); // offset: 6; size: 4; RK value - $rknum = self::_GetInt4d($recordData, 6); - $numValue = self::_GetIEEE754($rknum); + $rknum = self::getInt4d($recordData, 6); + $numValue = self::getIEEE754($rknum); - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); + if (!$this->readDataOnly) { // add style information - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]); } // add cell @@ -3682,41 +3672,41 @@ private function _readRk() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readLabelSst() + private function readLabelSst() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); + $row = self::getInt2d($recordData, 0); // offset: 2; size: 2; index to column - $column = self::_GetInt2d($recordData, 2); + $column = self::getInt2d($recordData, 2); $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) { // offset: 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); + $xfIndex = self::getInt2d($recordData, 4); // offset: 6; size: 4; index to SST record - $index = self::_GetInt4d($recordData, 6); + $index = self::getInt4d($recordData, 6); // add cell - if (($fmtRuns = $this->_sst[$index]['fmtRuns']) && !$this->_readDataOnly) { + if (($fmtRuns = $this->sst[$index]['fmtRuns']) && !$this->readDataOnly) { // then we should treat as rich text $richText = new PHPExcel_RichText(); $charPos = 0; - $sstCount = count($this->_sst[$index]['fmtRuns']); + $sstCount = count($this->sst[$index]['fmtRuns']); for ($i = 0; $i <= $sstCount; ++$i) { if (isset($fmtRuns[$i])) { - $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos); + $text = PHPExcel_Shared_String::Substring($this->sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos); $charPos = $fmtRuns[$i]['charPos']; } else { - $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, PHPExcel_Shared_String::CountCharacters($this->_sst[$index]['value'])); + $text = PHPExcel_Shared_String::Substring($this->sst[$index]['value'], $charPos, PHPExcel_Shared_String::CountCharacters($this->sst[$index]['value'])); } if (PHPExcel_Shared_String::CountCharacters($text) > 0) { @@ -3732,21 +3722,21 @@ private function _readLabelSst() // check the OpenOffice documentation of the FONT record $fontIndex = $fmtRuns[$i - 1]['fontIndex'] - 1; } - $textRun->setFont(clone $this->_objFonts[$fontIndex]); + $textRun->setFont(clone $this->objFonts[$fontIndex]); } } } } - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); $cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING); } else { - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - $cell->setValueExplicit($this->_sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING); + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($this->sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING); } - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // add style information - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]); } } } @@ -3760,22 +3750,22 @@ private function _readLabelSst() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readMulRk() + private function readMulRk() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); + $row = self::getInt2d($recordData, 0); // offset: 2; size: 2; index to first column - $colFirst = self::_GetInt2d($recordData, 2); + $colFirst = self::getInt2d($recordData, 2); // offset: var; size: 2; index to last column - $colLast = self::_GetInt2d($recordData, $length - 2); + $colLast = self::getInt2d($recordData, $length - 2); $columns = $colLast - $colFirst + 1; // offset within record data @@ -3785,16 +3775,16 @@ private function _readMulRk() $columnString = PHPExcel_Cell::stringFromColumnIndex($colFirst + $i); // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) { // offset: var; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, $offset); + $xfIndex = self::getInt2d($recordData, $offset); // offset: var; size: 4; RK value - $numValue = self::_GetIEEE754(self::_GetInt4d($recordData, $offset + 2)); - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { + $numValue = self::getIEEE754(self::getInt4d($recordData, $offset + 2)); + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); + if (!$this->readDataOnly) { // add style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]); } // add cell value @@ -3814,32 +3804,32 @@ private function _readMulRk() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readNumber() + private function readNumber() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); + $row = self::getInt2d($recordData, 0); // offset: 2; size 2; index to column - $column = self::_GetInt2d($recordData, 2); + $column = self::getInt2d($recordData, 2); $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) { // offset 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); + $xfIndex = self::getInt2d($recordData, 4); - $numValue = self::_extractNumber(substr($recordData, 6, 8)); + $numValue = self::extractNumber(substr($recordData, 6, 8)); - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); + if (!$this->readDataOnly) { // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]); } // add cell value @@ -3856,26 +3846,26 @@ private function _readNumber() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readFormula() + private function readFormula() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; row index - $row = self::_GetInt2d($recordData, 0); + $row = self::getInt2d($recordData, 0); // offset: 2; size: 2; col index - $column = self::_GetInt2d($recordData, 2); + $column = self::getInt2d($recordData, 2); $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // offset: 20: size: variable; formula structure $formulaStructure = substr($recordData, 20); // offset: 14: size: 2; option flags, recalculate always, recalculate on open etc. - $options = self::_GetInt2d($recordData, 14); + $options = self::getInt2d($recordData, 14); // bit: 0; mask: 0x0001; 1 = recalculate always // bit: 1; mask: 0x0002; 1 = calculate on open @@ -3891,22 +3881,22 @@ private function _readFormula() if ($isPartOfSharedFormula) { // part of shared formula which means there will be a formula with a tExp token and nothing else // get the base cell, grab tExp token - $baseRow = self::_GetInt2d($formulaStructure, 3); - $baseCol = self::_GetInt2d($formulaStructure, 5); + $baseRow = self::getInt2d($formulaStructure, 3); + $baseCol = self::getInt2d($formulaStructure, 5); $this->_baseCell = PHPExcel_Cell::stringFromColumnIndex($baseCol). ($baseRow + 1); } // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) { if ($isPartOfSharedFormula) { // formula is added to this cell after the sheet has been read - $this->_sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell; + $this->sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell; } // offset: 16: size: 4; not used // offset: 4; size: 2; XF index - $xfIndex = self::_GetInt2d($recordData, 4); + $xfIndex = self::getInt2d($recordData, 4); // offset: 6; size: 8; result of the formula if ((ord($recordData{6}) == 0) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { @@ -3914,13 +3904,13 @@ private function _readFormula() $dataType = PHPExcel_Cell_DataType::TYPE_STRING; // read possible SHAREDFMLA record - $code = self::_GetInt2d($this->_data, $this->_pos); + $code = self::getInt2d($this->data, $this->pos); if ($code == self::XLS_Type_SHAREDFMLA) { - $this->_readSharedFmla(); + $this->readSharedFmla(); } // read STRING record - $value = $this->_readString(); + $value = $this->readString(); } elseif ((ord($recordData{6}) == 1) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { @@ -3932,7 +3922,7 @@ private function _readFormula() && (ord($recordData{13}) == 255)) { // Error formula. Error code is in +2 $dataType = PHPExcel_Cell_DataType::TYPE_ERROR; - $value = self::_mapErrorCode(ord($recordData{8})); + $value = self::mapErrorCode(ord($recordData{8})); } elseif ((ord($recordData{6}) == 3) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { @@ -3942,13 +3932,13 @@ private function _readFormula() } else { // forumla result is a number, first 14 bytes like _NUMBER record $dataType = PHPExcel_Cell_DataType::TYPE_NUMERIC; - $value = self::_extractNumber(substr($recordData, 6, 8)); + $value = self::extractNumber(substr($recordData, 6, 8)); } - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); - if (!$this->_readDataOnly) { + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); + if (!$this->readDataOnly) { // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]); } // store the formula @@ -3956,17 +3946,17 @@ private function _readFormula() // not part of shared formula // add cell value. If we can read formula, populate with formula, otherwise just used cached value try { - if ($this->_version != self::XLS_BIFF8) { + if ($this->version != self::XLS_BIFF8) { throw new PHPExcel_Reader_Exception('Not BIFF8. Can only read BIFF8 formulas'); } - $formula = $this->_getFormulaFromStructure($formulaStructure); // get formula in human language + $formula = $this->getFormulaFromStructure($formulaStructure); // get formula in human language $cell->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); } catch (PHPExcel_Exception $e) { $cell->setValueExplicit($value, $dataType); } } else { - if ($this->_version == self::XLS_BIFF8) { + if ($this->version == self::XLS_BIFF8) { // do nothing at this point, formula id added later in the code } else { $cell->setValueExplicit($value, $dataType); @@ -3984,17 +3974,17 @@ private function _readFormula() * which usually contains relative references. * These will be used to construct the formula in each shared formula part after the sheet is read. */ - private function _readSharedFmla() + private function readSharedFmla() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0, size: 6; cell range address of the area used by the shared formula, not used for anything $cellRange = substr($recordData, 0, 6); - $cellRange = $this->_readBIFF5CellRangeAddressFixed($cellRange); // note: even BIFF8 uses BIFF5 syntax + $cellRange = $this->readBIFF5CellRangeAddressFixed($cellRange); // note: even BIFF8 uses BIFF5 syntax // offset: 6, size: 1; not used @@ -4005,7 +3995,7 @@ private function _readSharedFmla() $formula = substr($recordData, 8); // at this point we only store the shared formula for later use - $this->_sharedFormulas[$this->_baseCell] = $formula; + $this->sharedFormulas[$this->_baseCell] = $formula; } @@ -4016,19 +4006,19 @@ private function _readSharedFmla() * * @return string The string contents as UTF-8 */ - private function _readString() + private function readString() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong($recordData); + if ($this->version == self::XLS_BIFF8) { + $string = self::readUnicodeStringLong($recordData); $value = $string['value']; } else { - $string = $this->_readByteStringLong($recordData); + $string = $this->readByteStringLong($recordData); $value = $string['value']; } @@ -4044,25 +4034,25 @@ private function _readString() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readBoolErr() + private function readBoolErr() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; row index - $row = self::_GetInt2d($recordData, 0); + $row = self::getInt2d($recordData, 0); // offset: 2; size: 2; column index - $column = self::_GetInt2d($recordData, 2); + $column = self::getInt2d($recordData, 2); $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) { // offset: 4; size: 2; index to XF record - $xfIndex = self::_GetInt2d($recordData, 4); + $xfIndex = self::getInt2d($recordData, 4); // offset: 6; size: 1; the boolean value or error value $boolErr = ord($recordData{6}); @@ -4070,7 +4060,7 @@ private function _readBoolErr() // offset: 7; size: 1; 0=boolean; 1=error $isError = ord($recordData{7}); - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); switch ($isError) { case 0: // boolean $value = (bool) $boolErr; @@ -4079,16 +4069,16 @@ private function _readBoolErr() $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL); break; case 1: // error type - $value = self::_mapErrorCode($boolErr); + $value = self::mapErrorCode($boolErr); // add cell value $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_ERROR); break; } - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]); } } } @@ -4102,30 +4092,30 @@ private function _readBoolErr() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readMulBlank() + private function readMulBlank() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); + $row = self::getInt2d($recordData, 0); // offset: 2; size: 2; index to first column - $fc = self::_GetInt2d($recordData, 2); + $fc = self::getInt2d($recordData, 2); // offset: 4; size: 2 x nc; list of indexes to XF records // add style information - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { for ($i = 0; $i < $length / 2 - 3; ++$i) { $columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i); // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { - $xfIndex = self::_GetInt2d($recordData, 4 + 2 * $i); - $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) { + $xfIndex = self::getInt2d($recordData, 4 + 2 * $i); + $this->phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->mapCellXfIndex[$xfIndex]); } } } @@ -4144,41 +4134,41 @@ private function _readMulBlank() * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readLabel() + private function readLabel() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; index to row - $row = self::_GetInt2d($recordData, 0); + $row = self::getInt2d($recordData, 0); // offset: 2; size: 2; index to column - $column = self::_GetInt2d($recordData, 2); + $column = self::getInt2d($recordData, 2); $columnString = PHPExcel_Cell::stringFromColumnIndex($column); // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) { // offset: 4; size: 2; XF index - $xfIndex = self::_GetInt2d($recordData, 4); + $xfIndex = self::getInt2d($recordData, 4); // add cell value // todo: what if string is very long? continue record - if ($this->_version == self::XLS_BIFF8) { - $string = self::_readUnicodeStringLong(substr($recordData, 6)); + if ($this->version == self::XLS_BIFF8) { + $string = self::readUnicodeStringLong(substr($recordData, 6)); $value = $string['value']; } else { - $string = $this->_readByteStringLong(substr($recordData, 6)); + $string = $this->readByteStringLong(substr($recordData, 6)); $value = $string['value']; } - $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // add cell style - $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]); } } } @@ -4187,29 +4177,29 @@ private function _readLabel() /** * Read BLANK record */ - private function _readBlank() + private function readBlank() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; row index - $row = self::_GetInt2d($recordData, 0); + $row = self::getInt2d($recordData, 0); // offset: 2; size: 2; col index - $col = self::_GetInt2d($recordData, 2); + $col = self::getInt2d($recordData, 2); $columnString = PHPExcel_Cell::stringFromColumnIndex($col); // Read cell? - if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle())) { + if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) { // offset: 4; size: 2; XF index - $xfIndex = self::_GetInt2d($recordData, 4); + $xfIndex = self::getInt2d($recordData, 4); // add style information - if (!$this->_readDataOnly) { - $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + if (!$this->readDataOnly) { + $this->phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->mapCellXfIndex[$xfIndex]); } } @@ -4219,30 +4209,30 @@ private function _readBlank() /** * Read MSODRAWING record */ - private function _readMsoDrawing() + private function readMsoDrawing() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $length = self::getInt2d($this->data, $this->pos + 2); // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); + $splicedRecordData = $this->getSplicedRecordData(); $recordData = $splicedRecordData['recordData']; - $this->_drawingData .= $recordData; + $this->drawingData .= $recordData; } /** * Read OBJ record */ - private function _readObj() + private function readObj() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_readDataOnly || $this->_version != self::XLS_BIFF8) { + if ($this->readDataOnly || $this->version != self::XLS_BIFF8) { return; } @@ -4255,13 +4245,13 @@ private function _readObj() // data: var; subrecord data // for now, we are just interested in the second subrecord containing the object type - $ftCmoType = self::_GetInt2d($recordData, 0); - $cbCmoSize = self::_GetInt2d($recordData, 2); - $otObjType = self::_GetInt2d($recordData, 4); - $idObjID = self::_GetInt2d($recordData, 6); - $grbitOpts = self::_GetInt2d($recordData, 6); + $ftCmoType = self::getInt2d($recordData, 0); + $cbCmoSize = self::getInt2d($recordData, 2); + $otObjType = self::getInt2d($recordData, 4); + $idObjID = self::getInt2d($recordData, 6); + $grbitOpts = self::getInt2d($recordData, 6); - $this->_objs[] = array( + $this->objs[] = array( 'ftCmoType' => $ftCmoType, 'cbCmoSize' => $cbCmoSize, 'otObjType' => $otObjType, @@ -4271,7 +4261,7 @@ private function _readObj() $this->textObjRef = $idObjID; // echo '<b>_readObj()</b><br />'; -// var_dump(end($this->_objs)); +// var_dump(end($this->objs)); // echo '<br />'; } @@ -4279,32 +4269,32 @@ private function _readObj() /** * Read WINDOW2 record */ - private function _readWindow2() + private function readWindow2() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; option flags - $options = self::_GetInt2d($recordData, 0); + $options = self::getInt2d($recordData, 0); // offset: 2; size: 2; index to first visible row - $firstVisibleRow = self::_GetInt2d($recordData, 2); + $firstVisibleRow = self::getInt2d($recordData, 2); // offset: 4; size: 2; index to first visible colum - $firstVisibleColumn = self::_GetInt2d($recordData, 4); - if ($this->_version === self::XLS_BIFF8) { + $firstVisibleColumn = self::getInt2d($recordData, 4); + if ($this->version === self::XLS_BIFF8) { // offset: 8; size: 2; not used // offset: 10; size: 2; cached magnification factor in page break preview (in percent); 0 = Default (60%) // offset: 12; size: 2; cached magnification factor in normal view (in percent); 0 = Default (100%) // offset: 14; size: 4; not used - $zoomscaleInPageBreakPreview = self::_GetInt2d($recordData, 10); + $zoomscaleInPageBreakPreview = self::getInt2d($recordData, 10); if ($zoomscaleInPageBreakPreview === 0) { $zoomscaleInPageBreakPreview = 60; } - $zoomscaleInNormalView = self::_GetInt2d($recordData, 12); + $zoomscaleInNormalView = self::getInt2d($recordData, 12); if ($zoomscaleInNormalView === 0) { $zoomscaleInNormalView = 100; } @@ -4312,22 +4302,22 @@ private function _readWindow2() // bit: 1; mask: 0x0002; 0 = do not show gridlines, 1 = show gridlines $showGridlines = (bool) ((0x0002 & $options) >> 1); - $this->_phpSheet->setShowGridlines($showGridlines); + $this->phpSheet->setShowGridlines($showGridlines); // bit: 2; mask: 0x0004; 0 = do not show headers, 1 = show headers $showRowColHeaders = (bool) ((0x0004 & $options) >> 2); - $this->_phpSheet->setShowRowColHeaders($showRowColHeaders); + $this->phpSheet->setShowRowColHeaders($showRowColHeaders); // bit: 3; mask: 0x0008; 0 = panes are not frozen, 1 = panes are frozen - $this->_frozen = (bool) ((0x0008 & $options) >> 3); + $this->frozen = (bool) ((0x0008 & $options) >> 3); // bit: 6; mask: 0x0040; 0 = columns from left to right, 1 = columns from right to left - $this->_phpSheet->setRightToLeft((bool)((0x0040 & $options) >> 6)); + $this->phpSheet->setRightToLeft((bool)((0x0040 & $options) >> 6)); // bit: 10; mask: 0x0400; 0 = sheet not active, 1 = sheet active $isActive = (bool) ((0x0400 & $options) >> 10); if ($isActive) { - $this->_phpExcel->setActiveSheetIndex($this->_phpExcel->getIndex($this->_phpSheet)); + $this->phpExcel->setActiveSheetIndex($this->phpExcel->getIndex($this->phpSheet)); } // bit: 11; mask: 0x0800; 0 = normal view, 1 = page break view @@ -4335,14 +4325,14 @@ private function _readWindow2() //FIXME: set $firstVisibleRow and $firstVisibleColumn - if ($this->_phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { + if ($this->phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { //NOTE: this setting is inferior to page layout view(Excel2007-) $view = $isPageBreakPreview ? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW : PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL; - $this->_phpSheet->getSheetView()->setView($view); - if ($this->_version === self::XLS_BIFF8) { + $this->phpSheet->getSheetView()->setView($view); + if ($this->version === self::XLS_BIFF8) { $zoomScale = $isPageBreakPreview ? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView; - $this->_phpSheet->getSheetView()->setZoomScale($zoomScale); - $this->_phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView); + $this->phpSheet->getSheetView()->setZoomScale($zoomScale); + $this->phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView); } } } @@ -4350,29 +4340,29 @@ private function _readWindow2() /** * Read PLV Record(Created by Excel2007 or upper) */ - private function _readPageLayoutView() + private function readPageLayoutView() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; //var_dump(unpack("vrt/vgrbitFrt/V2reserved/vwScalePLV/vgrbit", $recordData)); // offset: 0; size: 2; rt //->ignore - $rt = self::_GetInt2d($recordData, 0); + $rt = self::getInt2d($recordData, 0); // offset: 2; size: 2; grbitfr //->ignore - $grbitFrt = self::_GetInt2d($recordData, 2); + $grbitFrt = self::getInt2d($recordData, 2); // offset: 4; size: 8; reserved //->ignore // offset: 12; size 2; zoom scale - $wScalePLV = self::_GetInt2d($recordData, 12); + $wScalePLV = self::getInt2d($recordData, 12); // offset: 14; size 2; grbit - $grbit = self::_GetInt2d($recordData, 14); + $grbit = self::getInt2d($recordData, 14); // decomprise grbit $fPageLayoutView = $grbit & 0x01; @@ -4380,8 +4370,8 @@ private function _readPageLayoutView() $fWhitespaceHidden = ($grbit >> 3) & 0x01; //no support if ($fPageLayoutView === 1) { - $this->_phpSheet->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT); - $this->_phpSheet->getSheetView()->setZoomScale($wScalePLV); //set by Excel2007 only if SHEETVIEW_PAGE_LAYOUT + $this->phpSheet->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT); + $this->phpSheet->getSheetView()->setZoomScale($wScalePLV); //set by Excel2007 only if SHEETVIEW_PAGE_LAYOUT } //otherwise, we cannot know whether SHEETVIEW_PAGE_LAYOUT or SHEETVIEW_PAGE_BREAK_PREVIEW. } @@ -4389,46 +4379,46 @@ private function _readPageLayoutView() /** * Read SCL record */ - private function _readScl() + private function readScl() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // offset: 0; size: 2; numerator of the view magnification - $numerator = self::_GetInt2d($recordData, 0); + $numerator = self::getInt2d($recordData, 0); // offset: 2; size: 2; numerator of the view magnification - $denumerator = self::_GetInt2d($recordData, 2); + $denumerator = self::getInt2d($recordData, 2); // set the zoom scale (in percent) - $this->_phpSheet->getSheetView()->setZoomScale($numerator * 100 / $denumerator); + $this->phpSheet->getSheetView()->setZoomScale($numerator * 100 / $denumerator); } /** * Read PANE record */ - private function _readPane() + private function readPane() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; position of vertical split - $px = self::_GetInt2d($recordData, 0); + $px = self::getInt2d($recordData, 0); // offset: 2; size: 2; position of horizontal split - $py = self::_GetInt2d($recordData, 2); + $py = self::getInt2d($recordData, 2); - if ($this->_frozen) { + if ($this->frozen) { // frozen panes - $this->_phpSheet->freezePane(PHPExcel_Cell::stringFromColumnIndex($px) . ($py + 1)); + $this->phpSheet->freezePane(PHPExcel_Cell::stringFromColumnIndex($px) . ($py + 1)); } else { // unfrozen panes; split windows; not supported by PHPExcel core } @@ -4439,31 +4429,31 @@ private function _readPane() /** * Read SELECTION record. There is one such record for each pane in the sheet. */ - private function _readSelection() + private function readSelection() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 1; pane identifier $paneId = ord($recordData{0}); // offset: 1; size: 2; index to row of the active cell - $r = self::_GetInt2d($recordData, 1); + $r = self::getInt2d($recordData, 1); // offset: 3; size: 2; index to column of the active cell - $c = self::_GetInt2d($recordData, 3); + $c = self::getInt2d($recordData, 3); // offset: 5; size: 2; index into the following cell range list to the // entry that contains the active cell - $index = self::_GetInt2d($recordData, 5); + $index = self::getInt2d($recordData, 5); // offset: 7; size: var; cell range address list containing all selected cell ranges $data = substr($recordData, 7); - $cellRangeAddressList = $this->_readBIFF5CellRangeAddressList($data); // note: also BIFF8 uses BIFF5 syntax + $cellRangeAddressList = $this->readBIFF5CellRangeAddressList($data); // note: also BIFF8 uses BIFF5 syntax $selectedCells = $cellRangeAddressList['cellRangeAddresses'][0]; @@ -4482,12 +4472,12 @@ private function _readSelection() $selectedCells = preg_replace('/^(A[0-9]+\:)IV([0-9]+)$/', '${1}XFD${2}', $selectedCells); } - $this->_phpSheet->setSelectedCells($selectedCells); + $this->phpSheet->setSelectedCells($selectedCells); } } - private function _includeCellRangeFiltered($cellRangeAddress) + private function includeCellRangeFiltered($cellRangeAddress) { $includeCellRange = true; if ($this->getReadFilter() !== null) { @@ -4496,7 +4486,7 @@ private function _includeCellRangeFiltered($cellRangeAddress) $rangeBoundaries[1][0]++; for ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; $row++) { for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; $column++) { - if ($this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { + if ($this->getReadFilter()->readCell($column, $row, $this->phpSheet->getTitle())) { $includeCellRange = true; break 2; } @@ -4516,20 +4506,20 @@ private function _includeCellRangeFiltered($cellRangeAddress) * -- "OpenOffice.org's Documentation of the Microsoft * Excel File Format" */ - private function _readMergedCells() + private function readMergedCells() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { - $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData); + if ($this->version == self::XLS_BIFF8 && !$this->readDataOnly) { + $cellRangeAddressList = $this->readBIFF8CellRangeAddressList($recordData); foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) { if ((strpos($cellRangeAddress, ':') !== false) && - ($this->_includeCellRangeFiltered($cellRangeAddress))) { - $this->_phpSheet->mergeCells($cellRangeAddress); + ($this->includeCellRangeFiltered($cellRangeAddress))) { + $this->phpSheet->mergeCells($cellRangeAddress); } } } @@ -4539,18 +4529,18 @@ private function _readMergedCells() /** * Read HYPERLINK record */ - private function _readHyperLink() + private function readHyperLink() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer forward to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 8; cell range address of all cells containing this hyperlink try { - $cellRange = $this->_readBIFF8CellRangeAddressFixed($recordData, 0, 8); + $cellRange = $this->readBIFF8CellRangeAddressFixed($recordData, 0, 8); } catch (PHPExcel_Exception $e) { return; } @@ -4561,35 +4551,35 @@ private function _readHyperLink() // offset: 28, size: 4; option flags // bit: 0; mask: 0x00000001; 0 = no link or extant, 1 = file link or URL - $isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0; + $isFileLinkOrUrl = (0x00000001 & self::getInt2d($recordData, 28)) >> 0; // bit: 1; mask: 0x00000002; 0 = relative path, 1 = absolute path or URL - $isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1; + $isAbsPathOrUrl = (0x00000001 & self::getInt2d($recordData, 28)) >> 1; // bit: 2 (and 4); mask: 0x00000014; 0 = no description - $hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2; + $hasDesc = (0x00000014 & self::getInt2d($recordData, 28)) >> 2; // bit: 3; mask: 0x00000008; 0 = no text, 1 = has text - $hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3; + $hasText = (0x00000008 & self::getInt2d($recordData, 28)) >> 3; // bit: 7; mask: 0x00000080; 0 = no target frame, 1 = has target frame - $hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7; + $hasFrame = (0x00000080 & self::getInt2d($recordData, 28)) >> 7; // bit: 8; mask: 0x00000100; 0 = file link or URL, 1 = UNC path (inc. server name) - $isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8; + $isUNC = (0x00000100 & self::getInt2d($recordData, 28)) >> 8; // offset within record data $offset = 32; if ($hasDesc) { // offset: 32; size: var; character count of description text - $dl = self::_GetInt4d($recordData, 32); + $dl = self::getInt4d($recordData, 32); // offset: 36; size: var; character array of description text, no Unicode string header, always 16-bit characters, zero terminated - $desc = self::_encodeUTF16(substr($recordData, 36, 2 * ($dl - 1)), false); + $desc = self::encodeUTF16(substr($recordData, 36, 2 * ($dl - 1)), false); $offset += 4 + 2 * $dl; } if ($hasFrame) { - $fl = self::_GetInt4d($recordData, $offset); + $fl = self::getInt4d($recordData, $offset); $offset += 4 + 2 * $fl; } @@ -4614,10 +4604,10 @@ private function _readHyperLink() // offset: var; size: 16; GUID of URL Moniker $offset += 16; // offset: var; size: 4; size (in bytes) of character array of the URL including trailing zero word - $us = self::_GetInt4d($recordData, $offset); + $us = self::getInt4d($recordData, $offset); $offset += 4; // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated - $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); + $url = self::encodeUTF16(substr($recordData, $offset, $us - 2), false); $nullOffset = strpos($url, 0x00); if ($nullOffset) { $url = substr($url, 0, $nullOffset); @@ -4635,16 +4625,16 @@ private function _readHyperLink() $offset += 16; // offset: var; size: 2; directory up-level count. - $upLevelCount = self::_GetInt2d($recordData, $offset); + $upLevelCount = self::getInt2d($recordData, $offset); $offset += 2; // offset: var; size: 4; character count of the shortened file path and name, including trailing zero word - $sl = self::_GetInt4d($recordData, $offset); + $sl = self::getInt4d($recordData, $offset); $offset += 4; // offset: var; size: sl; character array of the shortened file path and name in 8.3-DOS-format (compressed Unicode string) $shortenedFilePath = substr($recordData, $offset, $sl); - $shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true); + $shortenedFilePath = self::encodeUTF16($shortenedFilePath, true); $shortenedFilePath = substr($shortenedFilePath, 0, -1); // remove trailing zero $offset += $sl; @@ -4654,13 +4644,13 @@ private function _readHyperLink() // extended file path // offset: var; size: 4; size of the following file link field including string lenth mark - $sz = self::_GetInt4d($recordData, $offset); + $sz = self::getInt4d($recordData, $offset); $offset += 4; // only present if $sz > 0 if ($sz > 0) { // offset: var; size: 4; size of the character array of the extended file path and name - $xl = self::_GetInt4d($recordData, $offset); + $xl = self::getInt4d($recordData, $offset); $offset += 4; // offset: var; size 2; unknown @@ -4668,7 +4658,7 @@ private function _readHyperLink() // offset: var; size $xl; character array of the extended file path and name. $extendedFilePath = substr($recordData, $offset, $xl); - $extendedFilePath = self::_encodeUTF16($extendedFilePath, false); + $extendedFilePath = self::encodeUTF16($extendedFilePath, false); $offset += $xl; } @@ -4693,16 +4683,16 @@ private function _readHyperLink() if ($hasText) { // offset: var; size: 4; character count of text mark including trailing zero word - $tl = self::_GetInt4d($recordData, $offset); + $tl = self::getInt4d($recordData, $offset); $offset += 4; // offset: var; size: var; character array of the text mark without the # sign, no Unicode header, always 16-bit characters, zero-terminated - $text = self::_encodeUTF16(substr($recordData, $offset, 2 * ($tl - 1)), false); + $text = self::encodeUTF16(substr($recordData, $offset, 2 * ($tl - 1)), false); $url .= $text; } // apply the hyperlink to all the relevant cells foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cellRange) as $coordinate) { - $this->_phpSheet->getCell($coordinate)->getHyperLink()->setUrl($url); + $this->phpSheet->getCell($coordinate)->getHyperLink()->setUrl($url); } } } @@ -4711,33 +4701,33 @@ private function _readHyperLink() /** * Read DATAVALIDATIONS record */ - private function _readDataValidations() + private function readDataValidations() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer forward to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; } /** * Read DATAVALIDATION record */ - private function _readDataValidation() + private function readDataValidation() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer forward to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_readDataOnly) { + if ($this->readDataOnly) { return; } // offset: 0; size: 4; Options - $options = self::_GetInt4d($recordData, 0); + $options = self::getInt4d($recordData, 0); // bit: 0-3; mask: 0x0000000F; type $type = (0x0000000F & $options) >> 0; @@ -4829,27 +4819,27 @@ private function _readDataValidation() // offset: 4; size: var; title of the prompt box $offset = 4; - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $string = self::readUnicodeStringLong(substr($recordData, $offset)); $promptTitle = $string['value'] !== chr(0) ? $string['value'] : ''; $offset += $string['size']; // offset: var; size: var; title of the error box - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $string = self::readUnicodeStringLong(substr($recordData, $offset)); $errorTitle = $string['value'] !== chr(0) ? $string['value'] : ''; $offset += $string['size']; // offset: var; size: var; text of the prompt box - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $string = self::readUnicodeStringLong(substr($recordData, $offset)); $prompt = $string['value'] !== chr(0) ? $string['value'] : ''; $offset += $string['size']; // offset: var; size: var; text of the error box - $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $string = self::readUnicodeStringLong(substr($recordData, $offset)); $error = $string['value'] !== chr(0) ? $string['value'] : ''; $offset += $string['size']; // offset: var; size: 2; size of the formula data for the first condition - $sz1 = self::_GetInt2d($recordData, $offset); + $sz1 = self::getInt2d($recordData, $offset); $offset += 2; // offset: var; size: 2; not used @@ -4859,7 +4849,7 @@ private function _readDataValidation() $formula1 = substr($recordData, $offset, $sz1); $formula1 = pack('v', $sz1) . $formula1; // prepend the length try { - $formula1 = $this->_getFormulaFromStructure($formula1); + $formula1 = $this->getFormulaFromStructure($formula1); // in list type validity, null characters are used as item separators if ($type == PHPExcel_Cell_DataValidation::TYPE_LIST) { @@ -4871,7 +4861,7 @@ private function _readDataValidation() $offset += $sz1; // offset: var; size: 2; size of the formula data for the first condition - $sz2 = self::_GetInt2d($recordData, $offset); + $sz2 = self::getInt2d($recordData, $offset); $offset += 2; // offset: var; size: 2; not used @@ -4881,21 +4871,21 @@ private function _readDataValidation() $formula2 = substr($recordData, $offset, $sz2); $formula2 = pack('v', $sz2) . $formula2; // prepend the length try { - $formula2 = $this->_getFormulaFromStructure($formula2); + $formula2 = $this->getFormulaFromStructure($formula2); } catch (PHPExcel_Exception $e) { return; } $offset += $sz2; // offset: var; size: var; cell range address list with - $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList(substr($recordData, $offset)); + $cellRangeAddressList = $this->readBIFF8CellRangeAddressList(substr($recordData, $offset)); $cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses']; foreach ($cellRangeAddresses as $cellRange) { - $stRange = $this->_phpSheet->shrinkRangeToFit($cellRange); + $stRange = $this->phpSheet->shrinkRangeToFit($cellRange); $stRange = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); foreach ($stRange as $coordinate) { - $objValidation = $this->_phpSheet->getCell($coordinate)->getDataValidation(); + $objValidation = $this->phpSheet->getCell($coordinate)->getDataValidation(); $objValidation->setType($type); $objValidation->setErrorStyle($errorStyle); $objValidation->setAllowBlank((bool)$allowBlank); @@ -4916,32 +4906,32 @@ private function _readDataValidation() /** * Read SHEETLAYOUT record. Stores sheet tab color information. */ - private function _readSheetLayout() + private function readSheetLayout() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // local pointer in record data $offset = 0; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { // offset: 0; size: 2; repeated record identifier 0x0862 // offset: 2; size: 10; not used // offset: 12; size: 4; size of record data // Excel 2003 uses size of 0x14 (documented), Excel 2007 uses size of 0x28 (not documented?) - $sz = self::_GetInt4d($recordData, 12); + $sz = self::getInt4d($recordData, 12); switch ($sz) { case 0x14: // offset: 16; size: 2; color index for sheet tab - $colorIndex = self::_GetInt2d($recordData, 16); - $color = self::_readColor($colorIndex, $this->_palette, $this->_version); - $this->_phpSheet->getTabColor()->setRGB($color['rgb']); + $colorIndex = self::getInt2d($recordData, 16); + $color = self::readColor($colorIndex, $this->palette, $this->version); + $this->phpSheet->getTabColor()->setRGB($color['rgb']); break; case 0x28: // TODO: Investigate structure for .xls SHEETLAYOUT record as saved by MS Office Excel 2007 @@ -4955,15 +4945,15 @@ private function _readSheetLayout() /** * Read SHEETPROTECTION record (FEATHEADR) */ - private function _readSheetProtection() + private function readSheetProtection() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; - if ($this->_readDataOnly) { + if ($this->readDataOnly) { return; } @@ -4974,7 +4964,7 @@ private function _readSheetProtection() // offset: 4; size: 8; Currently not used and set to 0 // offset: 12; size: 2; Shared feature type index (2=Enhanced Protetion, 4=SmartTag) - $isf = self::_GetInt2d($recordData, 12); + $isf = self::getInt2d($recordData, 12); if ($isf != 2) { return; } @@ -4985,67 +4975,67 @@ private function _readSheetProtection() // rgbHdrSData, assume "Enhanced Protection" // offset: 19; size: 2; option flags - $options = self::_GetInt2d($recordData, 19); + $options = self::getInt2d($recordData, 19); // bit: 0; mask 0x0001; 1 = user may edit objects, 0 = users must not edit objects $bool = (0x0001 & $options) >> 0; - $this->_phpSheet->getProtection()->setObjects(!$bool); + $this->phpSheet->getProtection()->setObjects(!$bool); // bit: 1; mask 0x0002; edit scenarios $bool = (0x0002 & $options) >> 1; - $this->_phpSheet->getProtection()->setScenarios(!$bool); + $this->phpSheet->getProtection()->setScenarios(!$bool); // bit: 2; mask 0x0004; format cells $bool = (0x0004 & $options) >> 2; - $this->_phpSheet->getProtection()->setFormatCells(!$bool); + $this->phpSheet->getProtection()->setFormatCells(!$bool); // bit: 3; mask 0x0008; format columns $bool = (0x0008 & $options) >> 3; - $this->_phpSheet->getProtection()->setFormatColumns(!$bool); + $this->phpSheet->getProtection()->setFormatColumns(!$bool); // bit: 4; mask 0x0010; format rows $bool = (0x0010 & $options) >> 4; - $this->_phpSheet->getProtection()->setFormatRows(!$bool); + $this->phpSheet->getProtection()->setFormatRows(!$bool); // bit: 5; mask 0x0020; insert columns $bool = (0x0020 & $options) >> 5; - $this->_phpSheet->getProtection()->setInsertColumns(!$bool); + $this->phpSheet->getProtection()->setInsertColumns(!$bool); // bit: 6; mask 0x0040; insert rows $bool = (0x0040 & $options) >> 6; - $this->_phpSheet->getProtection()->setInsertRows(!$bool); + $this->phpSheet->getProtection()->setInsertRows(!$bool); // bit: 7; mask 0x0080; insert hyperlinks $bool = (0x0080 & $options) >> 7; - $this->_phpSheet->getProtection()->setInsertHyperlinks(!$bool); + $this->phpSheet->getProtection()->setInsertHyperlinks(!$bool); // bit: 8; mask 0x0100; delete columns $bool = (0x0100 & $options) >> 8; - $this->_phpSheet->getProtection()->setDeleteColumns(!$bool); + $this->phpSheet->getProtection()->setDeleteColumns(!$bool); // bit: 9; mask 0x0200; delete rows $bool = (0x0200 & $options) >> 9; - $this->_phpSheet->getProtection()->setDeleteRows(!$bool); + $this->phpSheet->getProtection()->setDeleteRows(!$bool); // bit: 10; mask 0x0400; select locked cells $bool = (0x0400 & $options) >> 10; - $this->_phpSheet->getProtection()->setSelectLockedCells(!$bool); + $this->phpSheet->getProtection()->setSelectLockedCells(!$bool); // bit: 11; mask 0x0800; sort cell range $bool = (0x0800 & $options) >> 11; - $this->_phpSheet->getProtection()->setSort(!$bool); + $this->phpSheet->getProtection()->setSort(!$bool); // bit: 12; mask 0x1000; auto filter $bool = (0x1000 & $options) >> 12; - $this->_phpSheet->getProtection()->setAutoFilter(!$bool); + $this->phpSheet->getProtection()->setAutoFilter(!$bool); // bit: 13; mask 0x2000; pivot tables $bool = (0x2000 & $options) >> 13; - $this->_phpSheet->getProtection()->setPivotTables(!$bool); + $this->phpSheet->getProtection()->setPivotTables(!$bool); // bit: 14; mask 0x4000; select unlocked cells $bool = (0x4000 & $options) >> 14; - $this->_phpSheet->getProtection()->setSelectUnlockedCells(!$bool); + $this->phpSheet->getProtection()->setSelectUnlockedCells(!$bool); // offset: 21; size: 2; not used } @@ -5056,22 +5046,22 @@ private function _readSheetProtection() * Reading of this record is based on Microsoft Office Excel 97-2000 Binary File Format Specification, * where it is referred to as FEAT record */ - private function _readRangeProtection() + private function readRangeProtection() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; // local pointer in record data $offset = 0; - if (!$this->_readDataOnly) { + if (!$this->readDataOnly) { $offset += 12; // offset: 12; size: 2; shared feature type, 2 = enhanced protection, 4 = smart tag - $isf = self::_GetInt2d($recordData, 12); + $isf = self::getInt2d($recordData, 12); if ($isf != 2) { // we only read FEAT records of type 2 return; @@ -5081,7 +5071,7 @@ private function _readRangeProtection() $offset += 5; // offset: 19; size: 2; count of ref ranges this feature is on - $cref = self::_GetInt2d($recordData, 19); + $cref = self::getInt2d($recordData, 19); $offset += 2; $offset += 6; @@ -5090,7 +5080,7 @@ private function _readRangeProtection() $cellRanges = array(); for ($i = 0; $i < $cref; ++$i) { try { - $cellRange = $this->_readBIFF8CellRangeAddressFixed(substr($recordData, 27 + 8 * $i, 8)); + $cellRange = $this->readBIFF8CellRangeAddressFixed(substr($recordData, 27 + 8 * $i, 8)); } catch (PHPExcel_Exception $e) { return; } @@ -5103,12 +5093,12 @@ private function _readRangeProtection() $offset += 4; // offset: var; size: 4; the encrypted password (only 16-bit although field is 32-bit) - $wPassword = self::_GetInt4d($recordData, $offset); + $wPassword = self::getInt4d($recordData, $offset); $offset += 4; // Apply range protection to sheet if ($cellRanges) { - $this->_phpSheet->protectCells(implode(' ', $cellRanges), strtoupper(dechex($wPassword)), true); + $this->phpSheet->protectCells(implode(' ', $cellRanges), strtoupper(dechex($wPassword)), true); } } } @@ -5117,24 +5107,24 @@ private function _readRangeProtection() /** * Read IMDATA record */ - private function _readImData() + private function readImData() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $length = self::getInt2d($this->data, $this->pos + 2); // get spliced record data - $splicedRecordData = $this->_getSplicedRecordData(); + $splicedRecordData = $this->getSplicedRecordData(); $recordData = $splicedRecordData['recordData']; // UNDER CONSTRUCTION // offset: 0; size: 2; image format - $cf = self::_GetInt2d($recordData, 0); + $cf = self::getInt2d($recordData, 0); // offset: 2; size: 2; environment from which the file was written - $env = self::_GetInt2d($recordData, 2); + $env = self::getInt2d($recordData, 2); // offset: 4; size: 4; length of the image data - $lcb = self::_GetInt4d($recordData, 4); + $lcb = self::getInt4d($recordData, 4); // offset: 8; size: var; image data $iData = substr($recordData, 8); @@ -5144,22 +5134,22 @@ private function _readImData() // BITMAPCOREINFO // 1. BITMAPCOREHEADER // offset: 0; size: 4; bcSize, Specifies the number of bytes required by the structure - $bcSize = self::_GetInt4d($iData, 0); + $bcSize = self::getInt4d($iData, 0); // var_dump($bcSize); // offset: 4; size: 2; bcWidth, specifies the width of the bitmap, in pixels - $bcWidth = self::_GetInt2d($iData, 4); + $bcWidth = self::getInt2d($iData, 4); // var_dump($bcWidth); // offset: 6; size: 2; bcHeight, specifies the height of the bitmap, in pixels. - $bcHeight = self::_GetInt2d($iData, 6); + $bcHeight = self::getInt2d($iData, 6); // var_dump($bcHeight); $ih = imagecreatetruecolor($bcWidth, $bcHeight); // offset: 8; size: 2; bcPlanes, specifies the number of planes for the target device. This value must be 1 // offset: 10; size: 2; bcBitCount specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24 - $bcBitCount = self::_GetInt2d($iData, 10); + $bcBitCount = self::getInt2d($iData, 10); // var_dump($bcBitCount); $rgbString = substr($iData, 12); @@ -5180,7 +5170,7 @@ private function _readImData() $drawing = new PHPExcel_Worksheet_Drawing(); $drawing->setPath($filename); - $drawing->setWorksheet($this->_phpSheet); + $drawing->setWorksheet($this->phpSheet); break; case 0x02: // Windows metafile or Macintosh PICT format case 0x0e: // native format @@ -5188,7 +5178,7 @@ private function _readImData() break; } - // _getSplicedRecordData() takes care of moving current position in data stream + // getSplicedRecordData() takes care of moving current position in data stream } @@ -5197,16 +5187,16 @@ private function _readImData() * When MSODRAWING data on a sheet exceeds 8224 bytes, CONTINUE records are used instead. Undocumented. * In this case, we must treat the CONTINUE record as a MSODRAWING record */ - private function _readContinue() + private function readContinue() { - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); // check if we are reading drawing data // this is in case a free CONTINUE record occurs in other circumstances we are unaware of - if ($this->_drawingData == '') { + if ($this->drawingData == '') { // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; return; } @@ -5214,7 +5204,7 @@ private function _readContinue() // check if record data is at least 4 bytes long, otherwise there is no chance this is MSODRAWING data if ($length < 4) { // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; return; } @@ -5227,17 +5217,17 @@ private function _readContinue() // 0xF00D MsofbtClientTextbox $validSplitPoints = array(0xF003, 0xF004, 0xF00D); // add identifiers if we find more - $splitPoint = self::_GetInt2d($recordData, 2); + $splitPoint = self::getInt2d($recordData, 2); if (in_array($splitPoint, $validSplitPoints)) { // get spliced record data (and move pointer to next record) - $splicedRecordData = $this->_getSplicedRecordData(); - $this->_drawingData .= $splicedRecordData['recordData']; + $splicedRecordData = $this->getSplicedRecordData(); + $this->drawingData .= $splicedRecordData['recordData']; return; } // move stream pointer to next record - $this->_pos += 4 + $length; + $this->pos += 4 + $length; } @@ -5249,7 +5239,7 @@ private function _readContinue() * * @return array */ - private function _getSplicedRecordData() + private function getSplicedRecordData() { $data = ''; $spliceOffsets = array(); @@ -5261,15 +5251,15 @@ private function _getSplicedRecordData() ++$i; // offset: 0; size: 2; identifier - $identifier = self::_GetInt2d($this->_data, $this->_pos); + $identifier = self::getInt2d($this->data, $this->pos); // offset: 2; size: 2; length - $length = self::_GetInt2d($this->_data, $this->_pos + 2); - $data .= $this->_readRecordData($this->_data, $this->_pos + 4, $length); + $length = self::getInt2d($this->data, $this->pos + 2); + $data .= $this->readRecordData($this->data, $this->pos + 4, $length); $spliceOffsets[$i] = $spliceOffsets[$i - 1] + $length; - $this->_pos += 4 + $length; - $nextIdentifier = self::_GetInt2d($this->_data, $this->_pos); + $this->pos += 4 + $length; + $nextIdentifier = self::getInt2d($this->data, $this->pos); } while ($nextIdentifier == self::XLS_Type_CONTINUE); $splicedData = array( @@ -5289,10 +5279,10 @@ private function _getSplicedRecordData() * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas * @return string Human readable formula */ - private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') + private function getFormulaFromStructure($formulaStructure, $baseCell = 'A1') { // offset: 0; size: 2; size of the following formula data - $sz = self::_GetInt2d($formulaStructure, 0); + $sz = self::getInt2d($formulaStructure, 0); // offset: 2; size: sz $formulaData = substr($formulaStructure, 2, $sz); @@ -5316,7 +5306,7 @@ private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') $additionalData = ''; } - return $this->_getFormulaFromData($formulaData, $additionalData, $baseCell); + return $this->getFormulaFromData($formulaData, $additionalData, $baseCell); } @@ -5328,12 +5318,12 @@ private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas * @return string Human readable formula */ - private function _getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1') + private function getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1') { // start parsing the formula data $tokens = array(); - while (strlen($formulaData) > 0 and $token = $this->_getNextToken($formulaData, $baseCell)) { + while (strlen($formulaData) > 0 and $token = $this->getNextToken($formulaData, $baseCell)) { $tokens[] = $token; $formulaData = substr($formulaData, $token['size']); @@ -5341,7 +5331,7 @@ private function _getFormulaFromData($formulaData, $additionalData = '', $baseCe //var_dump($token); } - $formulaString = $this->_createFormulaFromTokens($tokens, $additionalData); + $formulaString = $this->createFormulaFromTokens($tokens, $additionalData); return $formulaString; } @@ -5355,7 +5345,7 @@ private function _getFormulaFromData($formulaData, $additionalData = '', $baseCe * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas * @return string Human readable formula */ - private function _createFormulaFromTokens($tokens, $additionalData) + private function createFormulaFromTokens($tokens, $additionalData) { // empty formula? if (empty($tokens)) { @@ -5475,7 +5465,7 @@ private function _createFormulaFromTokens($tokens, $additionalData) break; case 'tMemArea': // bite off chunk of additional data - $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData); + $cellRangeAddressList = $this->readBIFF8CellRangeAddressList($additionalData); $additionalData = substr($additionalData, $cellRangeAddressList['size']); $formulaStrings[] = "$space1$space0{$token['data']}"; unset($space0, $space1); @@ -5519,7 +5509,7 @@ private function _createFormulaFromTokens($tokens, $additionalData) * @return array * @throws PHPExcel_Reader_Exception */ - private function _getNextToken($formulaData, $baseCell = 'A1') + private function getNextToken($formulaData, $baseCell = 'A1') { // offset: 0; size: 1; token id $id = ord($formulaData[0]); // token id @@ -5629,9 +5619,9 @@ private function _getNextToken($formulaData, $baseCell = 'A1') case 0x17: // string $name = 'tStr'; // offset: 1; size: var; Unicode string, 8-bit string length - $string = self::_readUnicodeStringShort(substr($formulaData, 1)); + $string = self::readUnicodeStringShort(substr($formulaData, 1)); $size = 1 + $string['size']; - $data = self::_UTF8toExcelDoubleQuoted($string['value']); + $data = self::UTF8toExcelDoubleQuoted($string['value']); break; case 0x19: // Special attribute // offset: 1; size: 1; attribute type flags: @@ -5649,7 +5639,7 @@ private function _getNextToken($formulaData, $baseCell = 'A1') case 0x04: $name = 'tAttrChoose'; // offset: 2; size: 2; number of choices in the CHOOSE function ($nc, number of parameters decreased by 1) - $nc = self::_GetInt2d($formulaData, 2); + $nc = self::getInt2d($formulaData, 2); // offset: 4; size: 2 * $nc // offset: 4 + 2 * $nc; size: 2 $size = 2 * $nc + 6; @@ -5707,7 +5697,7 @@ private function _getNextToken($formulaData, $baseCell = 'A1') // offset: 1; size: 1; error code $name = 'tErr'; $size = 2; - $data = self::_mapErrorCode(ord($formulaData[1])); + $data = self::mapErrorCode(ord($formulaData[1])); break; case 0x1D: // boolean // offset: 1; size: 1; 0 = false, 1 = true; @@ -5719,13 +5709,13 @@ private function _getNextToken($formulaData, $baseCell = 'A1') // offset: 1; size: 2; unsigned 16-bit integer $name = 'tInt'; $size = 3; - $data = self::_GetInt2d($formulaData, 1); + $data = self::getInt2d($formulaData, 1); break; case 0x1F: // number // offset: 1; size: 8; $name = 'tNum'; $size = 9; - $data = self::_extractNumber(substr($formulaData, 1)); + $data = self::extractNumber(substr($formulaData, 1)); $data = str_replace(',', '.', (string)$data); // in case non-English locale break; case 0x20: // array constant @@ -5742,7 +5732,7 @@ private function _getNextToken($formulaData, $baseCell = 'A1') $name = 'tFunc'; $size = 3; // offset: 1; size: 2; index to built-in sheet function - switch (self::_GetInt2d($formulaData, 1)) { + switch (self::getInt2d($formulaData, 1)) { case 2: $function = 'ISNA'; $args = 1; @@ -6397,7 +6387,7 @@ private function _getNextToken($formulaData, $baseCell = 'A1') // offset: 1; size: 1; number of arguments $args = ord($formulaData[1]); // offset: 2: size: 2; index to built-in sheet function - $index = self::_GetInt2d($formulaData, 2); + $index = self::getInt2d($formulaData, 2); switch ($index) { case 0: $function = 'COUNT'; @@ -6675,23 +6665,23 @@ private function _getNextToken($formulaData, $baseCell = 'A1') $name = 'tName'; $size = 5; // offset: 1; size: 2; one-based index to definedname record - $definedNameIndex = self::_GetInt2d($formulaData, 1) - 1; + $definedNameIndex = self::getInt2d($formulaData, 1) - 1; // offset: 2; size: 2; not used - $data = $this->_definedname[$definedNameIndex]['name']; + $data = $this->definedname[$definedNameIndex]['name']; break; case 0x24: // single cell reference e.g. A5 case 0x44: case 0x64: $name = 'tRef'; $size = 5; - $data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4)); + $data = $this->readBIFF8CellAddress(substr($formulaData, 1, 4)); break; case 0x25: // cell range reference to cells in the same sheet (2d) case 0x45: case 0x65: $name = 'tArea'; $size = 9; - $data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8)); + $data = $this->readBIFF8CellRangeAddress(substr($formulaData, 1, 8)); break; case 0x26: // Constant reference sub-expression case 0x46: @@ -6699,9 +6689,9 @@ private function _getNextToken($formulaData, $baseCell = 'A1') $name = 'tMemArea'; // offset: 1; size: 4; not used // offset: 5; size: 2; size of the following subexpression - $subSize = self::_GetInt2d($formulaData, 5); + $subSize = self::getInt2d($formulaData, 5); $size = 7 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + $data = $this->getFormulaFromData(substr($formulaData, 7, $subSize)); break; case 0x27: // Deleted constant reference sub-expression case 0x47: @@ -6709,32 +6699,32 @@ private function _getNextToken($formulaData, $baseCell = 'A1') $name = 'tMemErr'; // offset: 1; size: 4; not used // offset: 5; size: 2; size of the following subexpression - $subSize = self::_GetInt2d($formulaData, 5); + $subSize = self::getInt2d($formulaData, 5); $size = 7 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + $data = $this->getFormulaFromData(substr($formulaData, 7, $subSize)); break; case 0x29: // Variable reference sub-expression case 0x49: case 0x69: $name = 'tMemFunc'; // offset: 1; size: 2; size of the following sub-expression - $subSize = self::_GetInt2d($formulaData, 1); + $subSize = self::getInt2d($formulaData, 1); $size = 3 + $subSize; - $data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize)); + $data = $this->getFormulaFromData(substr($formulaData, 3, $subSize)); break; case 0x2C: // Relative 2d cell reference reference, used in shared formulas and some other places case 0x4C: case 0x6C: $name = 'tRefN'; $size = 5; - $data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell); + $data = $this->readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell); break; case 0x2D: // Relative 2d range reference case 0x4D: case 0x6D: $name = 'tAreaN'; $size = 9; - $data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell); + $data = $this->readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell); break; case 0x39: // External name case 0x59: @@ -6743,9 +6733,9 @@ private function _getNextToken($formulaData, $baseCell = 'A1') $size = 7; // offset: 1; size: 2; index to REF entry in EXTERNSHEET record // offset: 3; size: 2; one-based index to DEFINEDNAME or EXTERNNAME record - $index = self::_GetInt2d($formulaData, 3); + $index = self::getInt2d($formulaData, 3); // assume index is to EXTERNNAME record - $data = $this->_externalNames[$index - 1]['name']; + $data = $this->externalNames[$index - 1]['name']; // offset: 5; size: 2; not used break; case 0x3A: // 3d reference to cell @@ -6756,9 +6746,9 @@ private function _getNextToken($formulaData, $baseCell = 'A1') try { // offset: 1; size: 2; index to REF entry - $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + $sheetRange = $this->readSheetRangeByRefIndex(self::getInt2d($formulaData, 1)); // offset: 3; size: 4; cell address - $cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4)); + $cellAddress = $this->readBIFF8CellAddress(substr($formulaData, 3, 4)); $data = "$sheetRange!$cellAddress"; } catch (PHPExcel_Exception $e) { @@ -6774,9 +6764,9 @@ private function _getNextToken($formulaData, $baseCell = 'A1') try { // offset: 1; size: 2; index to REF entry - $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + $sheetRange = $this->readSheetRangeByRefIndex(self::getInt2d($formulaData, 1)); // offset: 3; size: 8; cell address - $cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8)); + $cellRangeAddress = $this->readBIFF8CellRangeAddress(substr($formulaData, 3, 8)); $data = "$sheetRange!$cellRangeAddress"; } catch (PHPExcel_Exception $e) { @@ -6806,21 +6796,21 @@ private function _getNextToken($formulaData, $baseCell = 'A1') * @param string $cellAddressStructure * @return string */ - private function _readBIFF8CellAddress($cellAddressStructure) + private function readBIFF8CellAddress($cellAddressStructure) { // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) - $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + $row = self::getInt2d($cellAddressStructure, 0) + 1; // offset: 2; size: 2; index to column or column offset + relative flags // bit: 7-0; mask 0x00FF; column index - $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2)); + $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::getInt2d($cellAddressStructure, 2)); // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + if (!(0x4000 & self::getInt2d($cellAddressStructure, 2))) { $column = '$' . $column; } // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + if (!(0x8000 & self::getInt2d($cellAddressStructure, 2))) { $row = '$' . $row; } @@ -6837,21 +6827,21 @@ private function _readBIFF8CellAddress($cellAddressStructure) * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas * @return string */ - private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') + private function readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') { list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) - $rowIndex = self::_GetInt2d($cellAddressStructure, 0); - $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + $rowIndex = self::getInt2d($cellAddressStructure, 0); + $row = self::getInt2d($cellAddressStructure, 0) + 1; // offset: 2; size: 2; index to column or column offset + relative flags // bit: 7-0; mask 0x00FF; column index - $colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2); + $colIndex = 0x00FF & self::getInt2d($cellAddressStructure, 2); // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + if (!(0x4000 & self::getInt2d($cellAddressStructure, 2))) { $column = PHPExcel_Cell::stringFromColumnIndex($colIndex); $column = '$' . $column; } else { @@ -6860,7 +6850,7 @@ private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') } // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + if (!(0x8000 & self::getInt2d($cellAddressStructure, 2))) { $row = '$' . $row; } else { $rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536; @@ -6880,13 +6870,13 @@ private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') * @return string * @throws PHPExcel_Reader_Exception */ - private function _readBIFF5CellRangeAddressFixed($subData) + private function readBIFF5CellRangeAddressFixed($subData) { // offset: 0; size: 2; index to first row - $fr = self::_GetInt2d($subData, 0) + 1; + $fr = self::getInt2d($subData, 0) + 1; // offset: 2; size: 2; index to last row - $lr = self::_GetInt2d($subData, 2) + 1; + $lr = self::getInt2d($subData, 2) + 1; // offset: 4; size: 1; index to first column $fc = ord($subData{4}); @@ -6919,19 +6909,19 @@ private function _readBIFF5CellRangeAddressFixed($subData) * @return string * @throws PHPExcel_Reader_Exception */ - private function _readBIFF8CellRangeAddressFixed($subData) + private function readBIFF8CellRangeAddressFixed($subData) { // offset: 0; size: 2; index to first row - $fr = self::_GetInt2d($subData, 0) + 1; + $fr = self::getInt2d($subData, 0) + 1; // offset: 2; size: 2; index to last row - $lr = self::_GetInt2d($subData, 2) + 1; + $lr = self::getInt2d($subData, 2) + 1; // offset: 4; size: 2; index to first column - $fc = self::_GetInt2d($subData, 4); + $fc = self::getInt2d($subData, 4); // offset: 6; size: 2; index to last column - $lc = self::_GetInt2d($subData, 6); + $lc = self::getInt2d($subData, 6); // check values if ($fr > $lr || $fc > $lc) { @@ -6957,44 +6947,44 @@ private function _readBIFF8CellRangeAddressFixed($subData) * @param string $subData * @return string */ - private function _readBIFF8CellRangeAddress($subData) + private function readBIFF8CellRangeAddress($subData) { // todo: if cell range is just a single cell, should this funciton // not just return e.g. 'A1' and not 'A1:A1' ? // offset: 0; size: 2; index to first row (0... 65535) (or offset (-32768... 32767)) - $fr = self::_GetInt2d($subData, 0) + 1; + $fr = self::getInt2d($subData, 0) + 1; // offset: 2; size: 2; index to last row (0... 65535) (or offset (-32768... 32767)) - $lr = self::_GetInt2d($subData, 2) + 1; + $lr = self::getInt2d($subData, 2) + 1; // offset: 4; size: 2; index to first column or column offset + relative flags // bit: 7-0; mask 0x00FF; column index - $fc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 4)); + $fc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::getInt2d($subData, 4)); // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 4))) { + if (!(0x4000 & self::getInt2d($subData, 4))) { $fc = '$' . $fc; } // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 4))) { + if (!(0x8000 & self::getInt2d($subData, 4))) { $fr = '$' . $fr; } // offset: 6; size: 2; index to last column or column offset + relative flags // bit: 7-0; mask 0x00FF; column index - $lc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 6)); + $lc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::getInt2d($subData, 6)); // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 6))) { + if (!(0x4000 & self::getInt2d($subData, 6))) { $lc = '$' . $lc; } // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 6))) { + if (!(0x8000 & self::getInt2d($subData, 6))) { $lr = '$' . $lr; } @@ -7011,7 +7001,7 @@ private function _readBIFF8CellRangeAddress($subData) * @param string $baseCell Base cell * @return string Cell range address */ - private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') + private function readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') { list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; @@ -7020,18 +7010,18 @@ private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') // not just return e.g. 'A1' and not 'A1:A1' ? // offset: 0; size: 2; first row - $frIndex = self::_GetInt2d($subData, 0); // adjust below + $frIndex = self::getInt2d($subData, 0); // adjust below // offset: 2; size: 2; relative index to first row (0... 65535) should be treated as offset (-32768... 32767) - $lrIndex = self::_GetInt2d($subData, 2); // adjust below + $lrIndex = self::getInt2d($subData, 2); // adjust below // offset: 4; size: 2; first column with relative/absolute flags // bit: 7-0; mask 0x00FF; column index - $fcIndex = 0x00FF & self::_GetInt2d($subData, 4); + $fcIndex = 0x00FF & self::getInt2d($subData, 4); // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 4))) { + if (!(0x4000 & self::getInt2d($subData, 4))) { // absolute column index $fc = PHPExcel_Cell::stringFromColumnIndex($fcIndex); $fc = '$' . $fc; @@ -7042,7 +7032,7 @@ private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') } // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 4))) { + if (!(0x8000 & self::getInt2d($subData, 4))) { // absolute row index $fr = $frIndex + 1; $fr = '$' . $fr; @@ -7055,12 +7045,12 @@ private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') // offset: 6; size: 2; last column with relative/absolute flags // bit: 7-0; mask 0x00FF; column index - $lcIndex = 0x00FF & self::_GetInt2d($subData, 6); + $lcIndex = 0x00FF & self::getInt2d($subData, 6); $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) - if (!(0x4000 & self::_GetInt2d($subData, 6))) { + if (!(0x4000 & self::getInt2d($subData, 6))) { // absolute column index $lc = PHPExcel_Cell::stringFromColumnIndex($lcIndex); $lc = '$' . $lc; @@ -7071,7 +7061,7 @@ private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') } // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) - if (!(0x8000 & self::_GetInt2d($subData, 6))) { + if (!(0x8000 & self::getInt2d($subData, 6))) { // absolute row index $lr = $lrIndex + 1; $lr = '$' . $lr; @@ -7092,17 +7082,17 @@ private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') * @param string $subData * @return array */ - private function _readBIFF8CellRangeAddressList($subData) + private function readBIFF8CellRangeAddressList($subData) { $cellRangeAddresses = array(); // offset: 0; size: 2; number of the following cell range addresses - $nm = self::_GetInt2d($subData, 0); + $nm = self::getInt2d($subData, 0); $offset = 2; // offset: 2; size: 8 * $nm; list of $nm (fixed) cell range addresses for ($i = 0; $i < $nm; ++$i) { - $cellRangeAddresses[] = $this->_readBIFF8CellRangeAddressFixed(substr($subData, $offset, 8)); + $cellRangeAddresses[] = $this->readBIFF8CellRangeAddressFixed(substr($subData, $offset, 8)); $offset += 8; } @@ -7120,17 +7110,17 @@ private function _readBIFF8CellRangeAddressList($subData) * @param string $subData * @return array */ - private function _readBIFF5CellRangeAddressList($subData) + private function readBIFF5CellRangeAddressList($subData) { $cellRangeAddresses = array(); // offset: 0; size: 2; number of the following cell range addresses - $nm = self::_GetInt2d($subData, 0); + $nm = self::getInt2d($subData, 0); $offset = 2; // offset: 2; size: 6 * $nm; list of $nm (fixed) cell range addresses for ($i = 0; $i < $nm; ++$i) { - $cellRangeAddresses[] = $this->_readBIFF5CellRangeAddressFixed(substr($subData, $offset, 6)); + $cellRangeAddresses[] = $this->readBIFF5CellRangeAddressFixed(substr($subData, $offset, 6)); $offset += 6; } @@ -7151,21 +7141,21 @@ private function _readBIFF5CellRangeAddressList($subData) * @return string|false * @throws PHPExcel_Reader_Exception */ - private function _readSheetRangeByRefIndex($index) + private function readSheetRangeByRefIndex($index) { - if (isset($this->_ref[$index])) { - $type = $this->_externalBooks[$this->_ref[$index]['externalBookIndex']]['type']; + if (isset($this->ref[$index])) { + $type = $this->externalBooks[$this->ref[$index]['externalBookIndex']]['type']; switch ($type) { case 'internal': // check if we have a deleted 3d reference - if ($this->_ref[$index]['firstSheetIndex'] == 0xFFFF or $this->_ref[$index]['lastSheetIndex'] == 0xFFFF) { + if ($this->ref[$index]['firstSheetIndex'] == 0xFFFF or $this->ref[$index]['lastSheetIndex'] == 0xFFFF) { throw new PHPExcel_Reader_Exception('Deleted sheet reference'); } // we have normal sheet range (collapsed or uncollapsed) - $firstSheetName = $this->_sheets[$this->_ref[$index]['firstSheetIndex']]['name']; - $lastSheetName = $this->_sheets[$this->_ref[$index]['lastSheetIndex']]['name']; + $firstSheetName = $this->sheets[$this->ref[$index]['firstSheetIndex']]['name']; + $lastSheetName = $this->sheets[$this->ref[$index]['lastSheetIndex']]['name']; if ($firstSheetName == $lastSheetName) { // collapsed sheet range @@ -7205,13 +7195,13 @@ private function _readSheetRangeByRefIndex($index) * @param string $arrayData * @return array */ - private static function _readBIFF8ConstantArray($arrayData) + private static function readBIFF8ConstantArray($arrayData) { // offset: 0; size: 1; number of columns decreased by 1 $nc = ord($arrayData[0]); // offset: 1; size: 2; number of rows decreased by 1 - $nr = self::_GetInt2d($arrayData, 1); + $nr = self::getInt2d($arrayData, 1); $size = 3; // initialize $arrayData = substr($arrayData, 3); @@ -7244,7 +7234,7 @@ private static function _readBIFF8ConstantArray($arrayData) * @param string $valueData * @return array */ - private static function _readBIFF8Constant($valueData) + private static function readBIFF8Constant($valueData) { // offset: 0; size: 1; identifier for type of constant $identifier = ord($valueData[0]); @@ -7256,12 +7246,12 @@ private static function _readBIFF8Constant($valueData) break; case 0x01: // number // offset: 1; size: 8; IEEE 754 floating-point value - $value = self::_extractNumber(substr($valueData, 1, 8)); + $value = self::extractNumber(substr($valueData, 1, 8)); $size = 9; break; case 0x02: // string value // offset: 1; size: var; Unicode string, 16-bit string length - $string = self::_readUnicodeStringLong(substr($valueData, 1)); + $string = self::readUnicodeStringLong(substr($valueData, 1)); $value = '"' . $string['value'] . '"'; $size = 1 + $string['size']; break; @@ -7276,7 +7266,7 @@ private static function _readBIFF8Constant($valueData) break; case 0x10: // error code // offset: 1; size: 1; error code - $value = self::_mapErrorCode(ord($valueData[1])); + $value = self::mapErrorCode(ord($valueData[1])); $size = 9; break; } @@ -7294,7 +7284,7 @@ private static function _readBIFF8Constant($valueData) * @param string $rgb Encoded RGB value (4 bytes) * @return array */ - private static function _readRGB($rgb) + private static function readRGB($rgb) { // offset: 0; size 1; Red component $r = ord($rgb{0}); @@ -7319,13 +7309,13 @@ private static function _readRGB($rgb) * @param string $subData * @return array */ - private function _readByteStringShort($subData) + private function readByteStringShort($subData) { // offset: 0; size: 1; length of the string (character count) $ln = ord($subData[0]); // offset: 1: size: var; character array (8-bit characters) - $value = $this->_decodeCodepage(substr($subData, 1, $ln)); + $value = $this->decodeCodepage(substr($subData, 1, $ln)); return array( 'value' => $value, @@ -7341,13 +7331,13 @@ private function _readByteStringShort($subData) * @param string $subData * @return array */ - private function _readByteStringLong($subData) + private function readByteStringLong($subData) { // offset: 0; size: 2; length of the string (character count) - $ln = self::_GetInt2d($subData, 0); + $ln = self::getInt2d($subData, 0); // offset: 2: size: var; character array (8-bit characters) - $value = $this->_decodeCodepage(substr($subData, 2)); + $value = $this->decodeCodepage(substr($subData, 2)); //return $string; return array( @@ -7365,14 +7355,14 @@ private function _readByteStringLong($subData) * @param string $subData * @return array */ - private static function _readUnicodeStringShort($subData) + private static function readUnicodeStringShort($subData) { $value = ''; // offset: 0: size: 1; length of the string (character count) $characterCount = ord($subData[0]); - $string = self::_readUnicodeString(substr($subData, 1), $characterCount); + $string = self::readUnicodeString(substr($subData, 1), $characterCount); // add 1 for the string length $string['size'] += 1; @@ -7389,14 +7379,14 @@ private static function _readUnicodeStringShort($subData) * @param string $subData * @return array */ - private static function _readUnicodeStringLong($subData) + private static function readUnicodeStringLong($subData) { $value = ''; // offset: 0: size: 2; length of the string (character count) - $characterCount = self::_GetInt2d($subData, 0); + $characterCount = self::getInt2d($subData, 0); - $string = self::_readUnicodeString(substr($subData, 2), $characterCount); + $string = self::readUnicodeString(substr($subData, 2), $characterCount); // add 2 for the string length $string['size'] += 2; @@ -7414,7 +7404,7 @@ private static function _readUnicodeStringLong($subData) * @param int $characterCount * @return array */ - private static function _readUnicodeString($subData, $characterCount) + private static function readUnicodeString($subData, $characterCount) { $value = ''; @@ -7431,7 +7421,7 @@ private static function _readUnicodeString($subData, $characterCount) // offset: 1: size: var; character array // this offset assumes richtext and Asian phonetic settings are off which is generally wrong // needs to be fixed - $value = self::_encodeUTF16(substr($subData, 1, $isCompressed ? $characterCount : 2 * $characterCount), $isCompressed); + $value = self::encodeUTF16(substr($subData, 1, $isCompressed ? $characterCount : 2 * $characterCount), $isCompressed); return array( 'value' => $value, @@ -7447,7 +7437,7 @@ private static function _readUnicodeString($subData, $characterCount) * @param string $value UTF-8 encoded string * @return string */ - private static function _UTF8toExcelDoubleQuoted($value) + private static function UTF8toExcelDoubleQuoted($value) { return '"' . str_replace('"', '""', $value) . '"'; } @@ -7459,10 +7449,10 @@ private static function _UTF8toExcelDoubleQuoted($value) * @param string $data Binary string that is at least 8 bytes long * @return float */ - private static function _extractNumber($data) + private static function extractNumber($data) { - $rknumhigh = self::_GetInt4d($data, 4); - $rknumlow = self::_GetInt4d($data, 0); + $rknumhigh = self::getInt4d($data, 4); + $rknumlow = self::getInt4d($data, 0); $sign = ($rknumhigh & 0x80000000) >> 31; $exp = (($rknumhigh & 0x7ff00000) >> 20) - 1023; $mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); @@ -7483,7 +7473,7 @@ private static function _extractNumber($data) } - private static function _GetIEEE754($rknum) + private static function getIEEE754($rknum) { if (($rknum & 0x02) != 0) { $value = $rknum >> 2; @@ -7516,10 +7506,10 @@ private static function _GetIEEE754($rknum) * @param bool $compressed * @return string */ - private static function _encodeUTF16($string, $compressed = '') + private static function encodeUTF16($string, $compressed = '') { if ($compressed) { - $string = self::_uncompressByteString($string); + $string = self::uncompressByteString($string); } return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE'); @@ -7532,7 +7522,7 @@ private static function _encodeUTF16($string, $compressed = '') * @param string $string * @return string */ - private static function _uncompressByteString($string) + private static function uncompressByteString($string) { $uncompressedString = ''; $strLen = strlen($string); @@ -7550,9 +7540,9 @@ private static function _uncompressByteString($string) * @param string $string * @return string */ - private function _decodeCodepage($string) + private function decodeCodepage($string) { - return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->_codepage); + return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->codepage); } @@ -7563,7 +7553,7 @@ private function _decodeCodepage($string) * @param int $pos * @return int */ - public static function _GetInt2d($data, $pos) + public static function getInt2d($data, $pos) { return ord($data[$pos]) | (ord($data[$pos+1]) << 8); } @@ -7576,7 +7566,7 @@ public static function _GetInt2d($data, $pos) * @param int $pos * @return int */ - public static function _GetInt4d($data, $pos) + public static function getInt4d($data, $pos) { // FIX: represent numbers correctly on 64-bit system // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 @@ -7599,21 +7589,21 @@ public static function _GetInt4d($data, $pos) * @param array $palette Color palette * @return array RGB color value, example: array('rgb' => 'FF0000') */ - private static function _readColor($color, $palette, $version) + private static function readColor($color, $palette, $version) { if ($color <= 0x07 || $color >= 0x40) { // special built-in color - return self::_mapBuiltInColor($color); + return self::mapBuiltInColor($color); } elseif (isset($palette) && isset($palette[$color - 8])) { // palette color, color index 0x08 maps to pallete index 0 return $palette[$color - 8]; } else { // default color table if ($version == self::XLS_BIFF8) { - return self::_mapColor($color); + return self::mapColor($color); } else { // BIFF5 - return self::_mapColorBIFF5($color); + return self::mapColorBIFF5($color); } } @@ -7628,7 +7618,7 @@ private static function _readColor($color, $palette, $version) * @param int $index * @return string */ - private static function _mapBorderStyle($index) + private static function mapBorderStyle($index) { switch ($index) { case 0x00: @@ -7672,7 +7662,7 @@ private static function _mapBorderStyle($index) * @param int $index * @return string */ - private static function _mapFillPattern($index) + private static function mapFillPattern($index) { switch ($index) { case 0x00: @@ -7725,7 +7715,7 @@ private static function _mapFillPattern($index) * @param int $subData * @return string */ - private static function _mapErrorCode($subData) + private static function mapErrorCode($subData) { switch ($subData) { case 0x00: @@ -7761,7 +7751,7 @@ private static function _mapErrorCode($subData) * @param int $color Indexed color * @return array */ - private static function _mapBuiltInColor($color) + private static function mapBuiltInColor($color) { switch ($color) { case 0x00: @@ -7796,7 +7786,7 @@ private static function _mapBuiltInColor($color) * @param int $subData * @return array */ - private static function _mapColorBIFF5($subData) + private static function mapColorBIFF5($subData) { switch ($subData) { case 0x08: @@ -7923,7 +7913,7 @@ private static function _mapColorBIFF5($subData) * @param int $subData * @return array */ - private static function _mapColor($subData) + private static function mapColor($subData) { switch ($subData) { case 0x08: @@ -8043,10 +8033,9 @@ private static function _mapColor($subData) } } - private function _parseRichText($is = '') + private function parseRichText($is = '') { $value = new PHPExcel_RichText(); - $value->createText($is); return $value; diff --git a/Classes/PHPExcel/Reader/Excel5/Escher.php b/Classes/PHPExcel/Reader/Excel5/Escher.php index b4575e6ae..2b99e2223 100644 --- a/Classes/PHPExcel/Reader/Excel5/Escher.php +++ b/Classes/PHPExcel/Reader/Excel5/Escher.php @@ -101,7 +101,7 @@ public function load($data) // Parse Escher stream while ($this->pos < $this->dataSize) { // offset: 2; size: 2: Record Type - $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos + 2); + $fbt = PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos + 2); switch ($fbt) { case self::DGGCONTAINER: @@ -173,15 +173,15 @@ public function load($data) private function readDefault() { // offset 0; size: 2; recVer and recInstance - $verInstance = PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos); + $verInstance = PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos); // offset: 2; size: 2: Record Type - $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos + 2); + $fbt = PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos + 2); // bit: 0-3; mask: 0x000F; recVer $recVer = (0x000F & $verInstance) >> 0; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -193,7 +193,7 @@ private function readDefault() */ private function readDggContainer() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -211,7 +211,7 @@ private function readDggContainer() */ private function readDgg() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -223,7 +223,7 @@ private function readDgg() */ private function readBstoreContainer() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -244,9 +244,9 @@ private function readBSE() // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -268,16 +268,16 @@ private function readBSE() $rgbUid = substr($recordData, 2, 16); // offset: 18; size: 2; tag - $tag = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 18); + $tag = PHPExcel_Reader_Excel5::getInt2d($recordData, 18); // offset: 20; size: 4; size of BLIP in bytes - $size = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 20); + $size = PHPExcel_Reader_Excel5::getInt4d($recordData, 20); // offset: 24; size: 4; number of references to this BLIP - $cRef = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 24); + $cRef = PHPExcel_Reader_Excel5::getInt4d($recordData, 24); // offset: 28; size: 4; MSOFO file offset - $foDelay = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 28); + $foDelay = PHPExcel_Reader_Excel5::getInt4d($recordData, 28); // offset: 32; size: 1; unused1 $unused1 = ord($recordData{32}); @@ -310,9 +310,9 @@ private function readBlipJPEG() // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -351,9 +351,9 @@ private function readBlipPNG() // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -392,9 +392,9 @@ private function readOPT() // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -411,9 +411,9 @@ private function readTertiaryOPT() // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -425,7 +425,7 @@ private function readTertiaryOPT() */ private function readSplitMenuColors() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -437,7 +437,7 @@ private function readSplitMenuColors() */ private function readDgContainer() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -455,7 +455,7 @@ private function readDgContainer() */ private function readDg() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -469,7 +469,7 @@ private function readSpgrContainer() { // context is either context DgContainer or SpgrContainer - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -495,7 +495,7 @@ private function readSpgrContainer() */ private function readSpContainer() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // add spContainer to spgrContainer @@ -515,7 +515,7 @@ private function readSpContainer() */ private function readSpgr() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -530,9 +530,9 @@ private function readSp() // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -547,9 +547,9 @@ private function readClientTextbox() // offset: 0; size: 2; recVer and recInstance // bit: 4-15; mask: 0xFFF0; recInstance - $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->data, $this->pos)) >> 4; + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -561,35 +561,35 @@ private function readClientTextbox() */ private function readClientAnchor() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record $this->pos += 8 + $length; // offset: 2; size: 2; upper-left corner column index (0-based) - $c1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 2); + $c1 = PHPExcel_Reader_Excel5::getInt2d($recordData, 2); // offset: 4; size: 2; upper-left corner horizontal offset in 1/1024 of column width - $startOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 4); + $startOffsetX = PHPExcel_Reader_Excel5::getInt2d($recordData, 4); // offset: 6; size: 2; upper-left corner row index (0-based) - $r1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 6); + $r1 = PHPExcel_Reader_Excel5::getInt2d($recordData, 6); // offset: 8; size: 2; upper-left corner vertical offset in 1/256 of row height - $startOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 8); + $startOffsetY = PHPExcel_Reader_Excel5::getInt2d($recordData, 8); // offset: 10; size: 2; bottom-right corner column index (0-based) - $c2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 10); + $c2 = PHPExcel_Reader_Excel5::getInt2d($recordData, 10); // offset: 12; size: 2; bottom-right corner horizontal offset in 1/1024 of column width - $endOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 12); + $endOffsetX = PHPExcel_Reader_Excel5::getInt2d($recordData, 12); // offset: 14; size: 2; bottom-right corner row index (0-based) - $r2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 14); + $r2 = PHPExcel_Reader_Excel5::getInt2d($recordData, 14); // offset: 16; size: 2; bottom-right corner vertical offset in 1/256 of row height - $endOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 16); + $endOffsetY = PHPExcel_Reader_Excel5::getInt2d($recordData, 16); // set the start coordinates $this->object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1)); @@ -615,7 +615,7 @@ private function readClientAnchor() */ private function readClientData() { - $length = PHPExcel_Reader_Excel5::_GetInt4d($this->data, $this->pos + 4); + $length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); $recordData = substr($this->data, $this->pos + 8, $length); // move stream pointer to next record @@ -638,7 +638,7 @@ private function readOfficeArtRGFOPTE($data, $n) $fopte = substr($data, 6 * $i, 6); // offset: 0; size: 2; opid - $opid = PHPExcel_Reader_Excel5::_GetInt2d($fopte, 0); + $opid = PHPExcel_Reader_Excel5::getInt2d($fopte, 0); // bit: 0-13; mask: 0x3FFF; opid.opid $opidOpid = (0x3FFF & $opid) >> 0; @@ -650,7 +650,7 @@ private function readOfficeArtRGFOPTE($data, $n) $opidFComplex = (0x8000 & $opid) >> 15; // offset: 2; size: 4; the value for this property - $op = PHPExcel_Reader_Excel5::_GetInt4d($fopte, 2); + $op = PHPExcel_Reader_Excel5::getInt4d($fopte, 2); if ($opidFComplex) { $complexData = substr($splicedComplexData, 0, $op); diff --git a/Classes/PHPExcel/Reader/Exception.php b/Classes/PHPExcel/Reader/Exception.php index 158b20756..48b3f8253 100644 --- a/Classes/PHPExcel/Reader/Exception.php +++ b/Classes/PHPExcel/Reader/Exception.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Reader_Exception * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Reader_Exception - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_Exception extends PHPExcel_Exception { /** diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index e5bf84bbd..e4a30b00c 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -57,7 +57,7 @@ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPEx */ public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); $this->referenceHelper = PHPExcel_ReferenceHelper::getInstance(); } @@ -173,7 +173,7 @@ public function listWorksheetInfo($pFilename) return $worksheetInfo; } - private function _gzfileGetContents($filename) + private function gzfileGetContents($filename) { $file = @gzopen($filename, 'rb'); if ($file !== false) { @@ -220,7 +220,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $timezoneObj = new DateTimeZone('Europe/London'); $GMT = new DateTimeZone('UTC'); - $gFileData = $this->_gzfileGetContents($pFilename); + $gFileData = $this->gzfileGetContents($pFilename); // echo '<pre>'; // echo htmlentities($gFileData,ENT_QUOTES,'UTF-8'); @@ -340,7 +340,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) foreach ($gnmXML->Sheets->Sheet as $sheet) { $worksheetName = (string) $sheet->Name; // echo '<b>Worksheet: ', $worksheetName,'</b><br />'; - if ((isset($this->_loadSheetsOnly)) && (!in_array($worksheetName, $this->_loadSheetsOnly))) { + if ((isset($this->loadSheetsOnly)) && (!in_array($worksheetName, $this->loadSheetsOnly))) { continue; } @@ -354,7 +354,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // name in line with the formula, not the reverse $objPHPExcel->getActiveSheet()->setTitle($worksheetName, false); - if ((!$this->_readDataOnly) && (isset($sheet->PrintInformation))) { + if ((!$this->readDataOnly) && (isset($sheet->PrintInformation))) { if (isset($sheet->PrintInformation->Margins)) { foreach ($sheet->PrintInformation->Margins->children('gnm', true) as $key => $margin) { $marginAttributes = $margin->attributes(); @@ -441,6 +441,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $cell = ($cell == 'TRUE') ? true: false; break; case '30': // Integer + // Excel 2007+ doesn't differentiate between integer and float, so set the value and dropthru to the next (numeric) case $cell = intval($cell); case '40': // Float $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; @@ -458,12 +459,12 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $objPHPExcel->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell, $type); } - if ((!$this->_readDataOnly) && (isset($sheet->Objects))) { + if ((!$this->readDataOnly) && (isset($sheet->Objects))) { foreach ($sheet->Objects->children('gnm', true) as $key => $comment) { $commentAttributes = $comment->attributes(); // Only comment objects are handled at the moment if ($commentAttributes->Text) { - $objPHPExcel->getActiveSheet()->getComment((string)$commentAttributes->ObjectBound)->setAuthor((string)$commentAttributes->Author)->setText($this->_parseRichText((string)$commentAttributes->Text)); + $objPHPExcel->getActiveSheet()->getComment((string)$commentAttributes->ObjectBound)->setAuthor((string)$commentAttributes->Author)->setText($this->parseRichText((string)$commentAttributes->Text)); } } } @@ -487,13 +488,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // var_dump($styleAttributes); // echo '<br />'; - // We still set the number format mask for date/time values, even if _readDataOnly is true - if ((!$this->_readDataOnly) || + // We still set the number format mask for date/time values, even if readDataOnly is true + if ((!$this->readDataOnly) || (PHPExcel_Shared_Date::isDateTimeFormatCode((string) $styleAttributes['Format']))) { $styleArray = array(); $styleArray['numberformat']['code'] = (string) $styleAttributes['Format']; - // If _readDataOnly is false, we set all formatting information - if (!$this->_readDataOnly) { + // If readDataOnly is false, we set all formatting information + if (!$this->readDataOnly) { switch ($styleAttributes['HAlign']) { case '1': $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; @@ -535,13 +536,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $styleArray['alignment']['shrinkToFit'] = ($styleAttributes['ShrinkToFit'] == '1') ? true : false; $styleArray['alignment']['indent'] = (intval($styleAttributes["Indent"]) > 0) ? $styleAttributes["indent"] : 0; - $RGB = self::_parseGnumericColour($styleAttributes["Fore"]); + $RGB = self::parseGnumericColour($styleAttributes["Fore"]); $styleArray['font']['color']['rgb'] = $RGB; - $RGB = self::_parseGnumericColour($styleAttributes["Back"]); + $RGB = self::parseGnumericColour($styleAttributes["Back"]); $shade = $styleAttributes["Shade"]; if (($RGB != '000000') || ($shade != '0')) { $styleArray['fill']['color']['rgb'] = $styleArray['fill']['startcolor']['rgb'] = $RGB; - $RGB2 = self::_parseGnumericColour($styleAttributes["PatternColor"]); + $RGB2 = self::parseGnumericColour($styleAttributes["PatternColor"]); $styleArray['fill']['endcolor']['rgb'] = $RGB2; switch ($shade) { case '1': @@ -643,25 +644,25 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) if (isset($styleRegion->Style->StyleBorder)) { if (isset($styleRegion->Style->StyleBorder->Top)) { - $styleArray['borders']['top'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Top->attributes()); + $styleArray['borders']['top'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Top->attributes()); } if (isset($styleRegion->Style->StyleBorder->Bottom)) { - $styleArray['borders']['bottom'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Bottom->attributes()); + $styleArray['borders']['bottom'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Bottom->attributes()); } if (isset($styleRegion->Style->StyleBorder->Left)) { - $styleArray['borders']['left'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Left->attributes()); + $styleArray['borders']['left'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Left->attributes()); } if (isset($styleRegion->Style->StyleBorder->Right)) { - $styleArray['borders']['right'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Right->attributes()); + $styleArray['borders']['right'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Right->attributes()); } if ((isset($styleRegion->Style->StyleBorder->Diagonal)) && (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}))) { - $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); + $styleArray['borders']['diagonal'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_BOTH; } elseif (isset($styleRegion->Style->StyleBorder->Diagonal)) { - $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); + $styleArray['borders']['diagonal'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_UP; } elseif (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'})) { - $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}->attributes()); + $styleArray['borders']['diagonal'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}->attributes()); $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_DOWN; } } @@ -677,7 +678,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } - if ((!$this->_readDataOnly) && (isset($sheet->Cols))) { + if ((!$this->readDataOnly) && (isset($sheet->Cols))) { // Column Widths $columnAttributes = $sheet->Cols->attributes(); $defaultWidth = $columnAttributes['DefaultSizePts'] / 5.4; @@ -706,7 +707,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } } - if ((!$this->_readDataOnly) && (isset($sheet->Rows))) { + if ((!$this->readDataOnly) && (isset($sheet->Rows))) { // Row Heights $rowAttributes = $sheet->Rows->attributes(); $defaultHeight = $rowAttributes['DefaultSizePts']; @@ -770,13 +771,11 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) return $objPHPExcel; } - private static function _parseBorderAttributes($borderAttributes) + private static function parseBorderAttributes($borderAttributes) { $styleArray = array(); - if (isset($borderAttributes["Color"])) { - $RGB = self::_parseGnumericColour($borderAttributes["Color"]); - $styleArray['color']['rgb'] = $RGB; + $styleArray['color']['rgb'] = self::parseGnumericColour($borderAttributes["Color"]); } switch ($borderAttributes["Style"]) { @@ -789,6 +788,9 @@ private static function _parseBorderAttributes($borderAttributes) case '2': $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; break; + case '3': + $styleArray['style'] = PHPExcel_Style_Border::BORDER_SLANTDASHDOT; + break; case '4': $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHED; break; @@ -801,6 +803,9 @@ private static function _parseBorderAttributes($borderAttributes) case '7': $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOTTED; break; + case '8': + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHED; + break; case '9': $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOT; break; @@ -816,33 +821,24 @@ private static function _parseBorderAttributes($borderAttributes) case '13': $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; break; - case '3': - $styleArray['style'] = PHPExcel_Style_Border::BORDER_SLANTDASHDOT; - break; - case '8': - $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHED; - break; } return $styleArray; } - private function _parseRichText($is = '') + private function parseRichText($is = '') { $value = new PHPExcel_RichText(); - $value->createText($is); return $value; } - private static function _parseGnumericColour($gnmColour) + private static function parseGnumericColour($gnmColour) { list($gnmR, $gnmG, $gnmB) = explode(':', $gnmColour); $gnmR = substr(str_pad($gnmR, 4, '0', STR_PAD_RIGHT), 0, 2); $gnmG = substr(str_pad($gnmG, 4, '0', STR_PAD_RIGHT), 0, 2); $gnmB = substr(str_pad($gnmB, 4, '0', STR_PAD_RIGHT), 0, 2); - $RGB = $gnmR.$gnmG.$gnmB; -// echo 'Excel Colour: ', $RGB,'<br />'; - return $RGB; + return $gnmR . $gnmG . $gnmB; } } diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index a7272e470..dedc1daa4 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -42,52 +42,71 @@ class PHPExcel_Reader_HTML extends PHPExcel_Reader_Abstract implements PHPExcel_ * * @var string */ - protected $_inputEncoding = 'ANSI'; + protected $inputEncoding = 'ANSI'; /** * Sheet index to read * * @var int */ - protected $_sheetIndex = 0; + protected $sheetIndex = 0; /** * Formats * * @var array */ - protected $_formats = array( - 'h1' => array('font' => array('bold' => true, + protected $formats = array( + 'h1' => array( + 'font' => array( + 'bold' => true, 'size' => 24, ), ), // Bold, 24pt - 'h2' => array('font' => array('bold' => true, + 'h2' => array( + 'font' => array( + 'bold' => true, 'size' => 18, ), ), // Bold, 18pt - 'h3' => array('font' => array('bold' => true, + 'h3' => array( + 'font' => array( + 'bold' => true, 'size' => 13.5, ), ), // Bold, 13.5pt - 'h4' => array('font' => array('bold' => true, + 'h4' => array( + 'font' => array( + 'bold' => true, 'size' => 12, ), ), // Bold, 12pt - 'h5' => array('font' => array('bold' => true, + 'h5' => array( + 'font' => array( + 'bold' => true, 'size' => 10, ), ), // Bold, 10pt - 'h6' => array('font' => array('bold' => true, + 'h6' => array( + 'font' => array( + 'bold' => true, 'size' => 7.5, ), ), // Bold, 7.5pt - 'a' => array('font' => array('underline' => true, - 'color' => array('argb' => PHPExcel_Style_Color::COLOR_BLUE, + 'a' => array( + 'font' => array( + 'underline' => true, + 'color' => array( + 'argb' => PHPExcel_Style_Color::COLOR_BLUE, ), ), ), // Blue underlined - 'hr' => array('borders' => array('bottom' => array('style' => PHPExcel_Style_Border::BORDER_THIN, - 'color' => array(\PHPExcel_Style_Color::COLOR_BLACK, + 'hr' => array( + 'borders' => array( + 'bottom' => array( + 'style' => PHPExcel_Style_Border::BORDER_THIN, + 'color' => array( + PHPExcel_Style_Color::COLOR_BLACK, ), ), ), @@ -101,7 +120,7 @@ class PHPExcel_Reader_HTML extends PHPExcel_Reader_Abstract implements PHPExcel_ */ public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); } /** @@ -109,10 +128,10 @@ public function __construct() * * @return boolean */ - protected function _isValidFormat() + protected function isValidFormat() { // Reading 2048 bytes should be enough to validate that the format is HTML - $data = fread($this->_fileHandle, 2048); + $data = fread($this->fileHandle, 2048); if ((strpos($data, '<') !== false) && (strlen($data) !== strlen(strip_tags($data)))) { return true; @@ -144,7 +163,7 @@ public function load($pFilename) */ public function setInputEncoding($pValue = 'ANSI') { - $this->_inputEncoding = $pValue; + $this->inputEncoding = $pValue; return $this; } @@ -156,7 +175,7 @@ public function setInputEncoding($pValue = 'ANSI') */ public function getInputEncoding() { - return $this->_inputEncoding; + return $this->inputEncoding; } // Data Array used for testing only, should write to PHPExcel object on completion of tests @@ -164,7 +183,7 @@ public function getInputEncoding() protected $_tableLevel = 0; protected $_nestedColumn = array('A'); - protected function _setTableStartColumn($column) + protected function setTableStartColumn($column) { if ($this->_tableLevel == 0) { $column = 'A'; @@ -175,19 +194,19 @@ protected function _setTableStartColumn($column) return $this->_nestedColumn[$this->_tableLevel]; } - protected function _getTableStartColumn() + protected function getTableStartColumn() { return $this->_nestedColumn[$this->_tableLevel]; } - protected function _releaseTableStartColumn() + protected function releaseTableStartColumn() { --$this->_tableLevel; return array_pop($this->_nestedColumn); } - protected function _flushCell($sheet, $column, $row, &$cellContent) + protected function flushCell($sheet, $column, $row, &$cellContent) { if (is_string($cellContent)) { // Simple String content @@ -207,7 +226,7 @@ protected function _flushCell($sheet, $column, $row, &$cellContent) $cellContent = (string) ''; } - protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, &$cellContent, $format = null) + protected function processDomElement(DOMNode $element, $sheet, &$row, &$column, &$cellContent, $format = null) { foreach ($element->childNodes as $child) { if ($child instanceof DOMText) { @@ -238,10 +257,10 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, break; } } - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); break; case 'title': - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); $sheet->setTitle($cellContent); $cellContent = ''; break; @@ -256,20 +275,20 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, if ($cellContent > '') { $cellContent .= ' '; } - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); if ($cellContent > '') { $cellContent .= ' '; } // echo 'END OF STYLING, SPAN OR DIV<br />'; break; case 'hr': - $this->_flushCell($sheet, $column, $row, $cellContent); + $this->flushCell($sheet, $column, $row, $cellContent); ++$row; - if (isset($this->_formats[$child->nodeName])) { - $sheet->getStyle($column . $row)->applyFromArray($this->_formats[$child->nodeName]); + if (isset($this->formats[$child->nodeName])) { + $sheet->getStyle($column . $row)->applyFromArray($this->formats[$child->nodeName]); } else { $cellContent = '----------'; - $this->_flushCell($sheet, $column, $row, $cellContent); + $this->flushCell($sheet, $column, $row, $cellContent); } ++$row; case 'br': @@ -278,7 +297,7 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, $cellContent .= "\n"; } else { // Otherwise flush our existing content and move the row cursor on - $this->_flushCell($sheet, $column, $row, $cellContent); + $this->flushCell($sheet, $column, $row, $cellContent); ++$row; } // echo 'HARD LINE BREAK: ' , '<br />'; @@ -290,14 +309,14 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, case 'href': // echo 'Link to ' , $attributeValue , '<br />'; $sheet->getCell($column . $row)->getHyperlink()->setUrl($attributeValue); - if (isset($this->_formats[$child->nodeName])) { - $sheet->getStyle($column . $row)->applyFromArray($this->_formats[$child->nodeName]); + if (isset($this->formats[$child->nodeName])) { + $sheet->getStyle($column . $row)->applyFromArray($this->formats[$child->nodeName]); } break; } } $cellContent .= ' '; - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF HYPERLINK:' , '<br />'; break; case 'h1': @@ -313,20 +332,20 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, // If we're inside a table, replace with a \n $cellContent .= "\n"; // echo 'LIST ENTRY: ' , '<br />'; - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF LIST ENTRY:' , '<br />'; } else { if ($cellContent > '') { - $this->_flushCell($sheet, $column, $row, $cellContent); + $this->flushCell($sheet, $column, $row, $cellContent); $row++; } // echo 'START OF PARAGRAPH: ' , '<br />'; - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF PARAGRAPH:' , '<br />'; - $this->_flushCell($sheet, $column, $row, $cellContent); + $this->flushCell($sheet, $column, $row, $cellContent); - if (isset($this->_formats[$child->nodeName])) { - $sheet->getStyle($column . $row)->applyFromArray($this->_formats[$child->nodeName]); + if (isset($this->formats[$child->nodeName])) { + $sheet->getStyle($column . $row)->applyFromArray($this->formats[$child->nodeName]); } $row++; @@ -338,30 +357,30 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, // If we're inside a table, replace with a \n $cellContent .= "\n"; // echo 'LIST ENTRY: ' , '<br />'; - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF LIST ENTRY:' , '<br />'; } else { if ($cellContent > '') { - $this->_flushCell($sheet, $column, $row, $cellContent); + $this->flushCell($sheet, $column, $row, $cellContent); } ++$row; // echo 'LIST ENTRY: ' , '<br />'; - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF LIST ENTRY:' , '<br />'; - $this->_flushCell($sheet, $column, $row, $cellContent); + $this->flushCell($sheet, $column, $row, $cellContent); $column = 'A'; } break; case 'table': - $this->_flushCell($sheet, $column, $row, $cellContent); - $column = $this->_setTableStartColumn($column); + $this->flushCell($sheet, $column, $row, $cellContent); + $column = $this->setTableStartColumn($column); // echo 'START OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; if ($this->_tableLevel > 1) { --$row; } - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; - $column = $this->_releaseTableStartColumn(); + $column = $this->releaseTableStartColumn(); if ($this->_tableLevel > 1) { ++$column; } else { @@ -370,27 +389,27 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, break; case 'thead': case 'tbody': - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); break; case 'tr': - $column = $this->_getTableStartColumn(); + $column = $this->getTableStartColumn(); $cellContent = ''; // echo 'START OF TABLE ' , $this->_tableLevel , ' ROW<br />'; - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); ++$row; // echo 'END OF TABLE ' , $this->_tableLevel , ' ROW<br />'; break; case 'th': case 'td': // echo 'START OF TABLE ' , $this->_tableLevel , ' CELL<br />'; - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); // echo 'END OF TABLE ' , $this->_tableLevel , ' CELL<br />'; while (isset($this->rowspan[$column . $row])) { ++$column; } - $this->_flushCell($sheet, $column, $row, $cellContent); + $this->flushCell($sheet, $column, $row, $cellContent); // if (isset($attributeArray['style']) && !empty($attributeArray['style'])) { // $styleAry = $this->getPhpExcelStyleArray($attributeArray['style']); @@ -435,10 +454,10 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, $column = 'A'; $content = ''; $this->_tableLevel = 0; - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); break; default: - $this->_processDomElement($child, $sheet, $row, $column, $cellContent); + $this->processDomElement($child, $sheet, $row, $column, $cellContent); } } } @@ -455,19 +474,19 @@ protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) { // Open file to validate - $this->_openFile($pFilename); - if (!$this->_isValidFormat()) { - fclose($this->_fileHandle); + $this->openFile($pFilename); + if (!$this->isValidFormat()) { + fclose($this->fileHandle); throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid HTML file."); } // Close after validating - fclose($this->_fileHandle); + fclose($this->fileHandle); // Create new PHPExcel - while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + while ($objPHPExcel->getSheetCount() <= $this->sheetIndex) { $objPHPExcel->createSheet(); } - $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); + $objPHPExcel->setActiveSheetIndex($this->sheetIndex); // Create a new DOM object $dom = new domDocument; @@ -483,7 +502,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $row = 0; $column = 'A'; $content = ''; - $this->_processDomElement($dom, $objPHPExcel->getActiveSheet(), $row, $column, $content); + $this->processDomElement($dom, $objPHPExcel->getActiveSheet(), $row, $column, $content); // Return return $objPHPExcel; @@ -496,7 +515,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) */ public function getSheetIndex() { - return $this->_sheetIndex; + return $this->sheetIndex; } /** @@ -507,7 +526,7 @@ public function getSheetIndex() */ public function setSheetIndex($pValue = 0) { - $this->_sheetIndex = $pValue; + $this->sheetIndex = $pValue; return $this; } diff --git a/Classes/PHPExcel/Reader/IReadFilter.php b/Classes/PHPExcel/Reader/IReadFilter.php index 0006cf3dc..f7c852d9d 100644 --- a/Classes/PHPExcel/Reader/IReadFilter.php +++ b/Classes/PHPExcel/Reader/IReadFilter.php @@ -30,10 +30,10 @@ interface PHPExcel_Reader_IReadFilter /** * Should this cell be read? * - * @param $column String column index - * @param $row Row index + * @param $column Column address (as a string value like "A", or "IV") + * @param $row Row number * @param $worksheetName Optional worksheet name - * @return boolean + * @return boolean */ public function readCell($column, $row, $worksheetName = ''); } diff --git a/Classes/PHPExcel/Reader/IReader.php b/Classes/PHPExcel/Reader/IReader.php index 79d098f8d..903454641 100644 --- a/Classes/PHPExcel/Reader/IReader.php +++ b/Classes/PHPExcel/Reader/IReader.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Reader_IReader * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Reader_IReader - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ interface PHPExcel_Reader_IReader { /** diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 66b7afe8d..22def5d5a 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -48,7 +48,7 @@ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExce */ public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); } /** @@ -438,8 +438,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']); // print_r($worksheetDataAttributes); // echo '<br />'; - if ((isset($this->_loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) && - (!in_array($worksheetDataAttributes['name'], $this->_loadSheetsOnly))) { + if ((isset($this->loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) && + (!in_array($worksheetDataAttributes['name'], $this->loadSheetsOnly))) { continue; } @@ -657,7 +657,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Merged cells if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) { - if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) { + if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->readDataOnly)) { $columnTo = $columnID; if (isset($cellDataTableAttributes['number-columns-spanned'])) { $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2); diff --git a/Classes/PHPExcel/Reader/SYLK.php b/Classes/PHPExcel/Reader/SYLK.php index a7f3f1729..eb7ef1afb 100644 --- a/Classes/PHPExcel/Reader/SYLK.php +++ b/Classes/PHPExcel/Reader/SYLK.php @@ -1,6 +1,16 @@ <?php + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + /** - * PHPExcel + * PHPExcel_Reader_SYLK * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,24 +34,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** PHPExcel root directory */ -if (!defined('PHPEXCEL_ROOT')) { - /** - * @ignore - */ - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); -} - -/** - * PHPExcel_Reader_SYLK - * - * @category PHPExcel - * @package PHPExcel_Reader - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader { /** @@ -77,7 +69,7 @@ class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_ */ public function __construct() { - $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); } /** @@ -85,10 +77,10 @@ public function __construct() * * @return boolean */ - protected function _isValidFormat() + protected function isValidFormat() { // Read sample data (first 2 KB will do) - $data = fread($this->_fileHandle, 2048); + $data = fread($this->fileHandle, 2048); // Count delimiters in file $delimiterCount = substr_count($data, ';'); @@ -135,12 +127,12 @@ public function getInputEncoding() public function listWorksheetInfo($pFilename) { // Open file - $this->_openFile($pFilename); - if (!$this->_isValidFormat()) { - fclose($this->_fileHandle); + $this->openFile($pFilename); + if (!$this->isValidFormat()) { + fclose($this->fileHandle); throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } - $fileHandle = $this->_fileHandle; + $fileHandle = $this->fileHandle; rewind($fileHandle); $worksheetInfo = array(); @@ -222,12 +214,12 @@ public function load($pFilename) public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) { // Open file - $this->_openFile($pFilename); - if (!$this->_isValidFormat()) { - fclose($this->_fileHandle); + $this->openFile($pFilename); + if (!$this->isValidFormat()) { + fclose($this->fileHandle); throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); } - $fileHandle = $this->_fileHandle; + $fileHandle = $this->fileHandle; rewind($fileHandle); // Create new PHPExcel diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index 13c166a3a..b9df3b4d7 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -39,154 +39,105 @@ public static function NumberToName($codePage = 1252) { switch ($codePage) { case 367: - return 'ASCII'; - break; // ASCII + return 'ASCII'; // ASCII case 437: - return 'CP437'; - break; // OEM US + return 'CP437'; // OEM US case 720: - throw new PHPExcel_Exception('Code page 720 not supported.'); - break; // OEM Arabic + throw new PHPExcel_Exception('Code page 720 not supported.'); // OEM Arabic case 737: - return 'CP737'; - break; // OEM Greek + return 'CP737'; // OEM Greek case 775: - return 'CP775'; - break; // OEM Baltic + return 'CP775'; // OEM Baltic case 850: - return 'CP850'; - break; // OEM Latin I + return 'CP850'; // OEM Latin I case 852: - return 'CP852'; - break; // OEM Latin II (Central European) + return 'CP852'; // OEM Latin II (Central European) case 855: - return 'CP855'; - break; // OEM Cyrillic + return 'CP855'; // OEM Cyrillic case 857: - return 'CP857'; - break; // OEM Turkish + return 'CP857'; // OEM Turkish case 858: - return 'CP858'; - break; // OEM Multilingual Latin I with Euro + return 'CP858'; // OEM Multilingual Latin I with Euro case 860: - return 'CP860'; - break; // OEM Portugese + return 'CP860'; // OEM Portugese case 861: - return 'CP861'; - break; // OEM Icelandic + return 'CP861'; // OEM Icelandic case 862: - return 'CP862'; - break; // OEM Hebrew + return 'CP862'; // OEM Hebrew case 863: - return 'CP863'; - break; // OEM Canadian (French) + return 'CP863'; // OEM Canadian (French) case 864: - return 'CP864'; - break; // OEM Arabic + return 'CP864'; // OEM Arabic case 865: - return 'CP865'; - break; // OEM Nordic + return 'CP865'; // OEM Nordic case 866: - return 'CP866'; - break; // OEM Cyrillic (Russian) + return 'CP866'; // OEM Cyrillic (Russian) case 869: - return 'CP869'; - break; // OEM Greek (Modern) + return 'CP869'; // OEM Greek (Modern) case 874: - return 'CP874'; - break; // ANSI Thai + return 'CP874'; // ANSI Thai case 932: - return 'CP932'; - break; // ANSI Japanese Shift-JIS + return 'CP932'; // ANSI Japanese Shift-JIS case 936: - return 'CP936'; - break; // ANSI Chinese Simplified GBK + return 'CP936'; // ANSI Chinese Simplified GBK case 949: - return 'CP949'; - break; // ANSI Korean (Wansung) + return 'CP949'; // ANSI Korean (Wansung) case 950: - return 'CP950'; - break; // ANSI Chinese Traditional BIG5 + return 'CP950'; // ANSI Chinese Traditional BIG5 case 1200: - return 'UTF-16LE'; - break; // UTF-16 (BIFF8) + return 'UTF-16LE'; // UTF-16 (BIFF8) case 1250: - return 'CP1250'; - break; // ANSI Latin II (Central European) + return 'CP1250'; // ANSI Latin II (Central European) case 1251: - return 'CP1251'; - break; // ANSI Cyrillic + return 'CP1251'; // ANSI Cyrillic case 0: - // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program + // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program case 1252: - return 'CP1252'; - break; // ANSI Latin I (BIFF4-BIFF7) + return 'CP1252'; // ANSI Latin I (BIFF4-BIFF7) case 1253: - return 'CP1253'; - break; // ANSI Greek + return 'CP1253'; // ANSI Greek case 1254: - return 'CP1254'; - break; // ANSI Turkish + return 'CP1254'; // ANSI Turkish case 1255: - return 'CP1255'; - break; // ANSI Hebrew + return 'CP1255'; // ANSI Hebrew case 1256: - return 'CP1256'; - break; // ANSI Arabic + return 'CP1256'; // ANSI Arabic case 1257: - return 'CP1257'; - break; // ANSI Baltic + return 'CP1257'; // ANSI Baltic case 1258: - return 'CP1258'; - break; // ANSI Vietnamese + return 'CP1258'; // ANSI Vietnamese case 1361: - return 'CP1361'; - break; // ANSI Korean (Johab) + return 'CP1361'; // ANSI Korean (Johab) case 10000: - return 'MAC'; - break; // Apple Roman + return 'MAC'; // Apple Roman case 10001: - return 'CP932'; - break; // Macintosh Japanese + return 'CP932'; // Macintosh Japanese case 10002: - return 'CP950'; - break; // Macintosh Chinese Traditional + return 'CP950'; // Macintosh Chinese Traditional case 10003: - return 'CP1361'; - break; // Macintosh Korean + return 'CP1361'; // Macintosh Korean case 10006: - return 'MACGREEK'; - break; // Macintosh Greek + return 'MACGREEK'; // Macintosh Greek case 10007: - return 'MACCYRILLIC'; - break; // Macintosh Cyrillic + return 'MACCYRILLIC'; // Macintosh Cyrillic case 10008: - return 'CP936'; - break; // Macintosh - Simplified Chinese (GB 2312) + return 'CP936'; // Macintosh - Simplified Chinese (GB 2312) case 10029: - return 'MACCENTRALEUROPE'; - break; // Macintosh Central Europe + return 'MACCENTRALEUROPE'; // Macintosh Central Europe case 10079: - return 'MACICELAND'; - break; // Macintosh Icelandic + return 'MACICELAND'; // Macintosh Icelandic case 10081: - return 'MACTURKISH'; - break; // Macintosh Turkish + return 'MACTURKISH'; // Macintosh Turkish case 21010: - return 'UTF-16LE'; - break; // UTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE + return 'UTF-16LE'; // UTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE case 32768: - return 'MAC'; - break; // Apple Roman + return 'MAC'; // Apple Roman case 32769: - throw new PHPExcel_Exception('Code page 32769 not supported.'); - break; // ANSI Latin I (BIFF2-BIFF3) + throw new PHPExcel_Exception('Code page 32769 not supported.'); // ANSI Latin I (BIFF2-BIFF3) case 65000: - return 'UTF-7'; - break; // Unicode (UTF-7) + return 'UTF-7'; // Unicode (UTF-7) case 65001: - return 'UTF-8'; - break; // Unicode (UTF-8) + return 'UTF-8'; // Unicode (UTF-8) } throw new PHPExcel_Exception('Unknown codepage: ' . $codePage); } diff --git a/Classes/PHPExcel/Shared/OLERead.php b/Classes/PHPExcel/Shared/OLERead.php index 48b24eed8..6b15d9700 100644 --- a/Classes/PHPExcel/Shared/OLERead.php +++ b/Classes/PHPExcel/Shared/OLERead.php @@ -94,19 +94,19 @@ public function read($sFileName) $this->data = file_get_contents($sFileName); // Total number of sectors used for the SAT - $this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); + $this->numBigBlockDepotBlocks = self::getInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); // SecID of the first sector of the directory stream - $this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS); + $this->rootStartBlock = self::getInt4d($this->data, self::ROOT_START_BLOCK_POS); // SecID of the first sector of the SSAT (or -2 if not extant) - $this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS); + $this->sbdStartBlock = self::getInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS); // SecID of the first sector of the MSAT (or -2 if no additional sectors are used) - $this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS); + $this->extensionBlock = self::getInt4d($this->data, self::EXTENSION_BLOCK_POS); // Total number of sectors used by MSAT - $this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS); + $this->numExtensionBlocks = self::getInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS); $bigBlockDepotBlocks = array(); $pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS; @@ -118,7 +118,7 @@ public function read($sFileName) } for ($i = 0; $i < $bbdBlocks; ++$i) { - $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos); + $bigBlockDepotBlocks[$i] = self::getInt4d($this->data, $pos); $pos += 4; } @@ -127,13 +127,13 @@ public function read($sFileName) $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1); for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) { - $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos); + $bigBlockDepotBlocks[$i] = self::getInt4d($this->data, $pos); $pos += 4; } $bbdBlocks += $blocksToRead; if ($bbdBlocks < $this->numBigBlockDepotBlocks) { - $this->extensionBlock = self::_GetInt4d($this->data, $pos); + $this->extensionBlock = self::getInt4d($this->data, $pos); } } @@ -156,14 +156,14 @@ public function read($sFileName) $this->smallBlockChain .= substr($this->data, $pos, 4*$bbs); $pos += 4*$bbs; - $sbdBlock = self::_GetInt4d($this->bigBlockChain, $sbdBlock*4); + $sbdBlock = self::getInt4d($this->bigBlockChain, $sbdBlock*4); } // read the directory stream $block = $this->rootStartBlock; $this->entry = $this->_readData($block); - $this->_readPropertySets(); + $this->readPropertySets(); } /** @@ -188,7 +188,7 @@ public function getStream($stream) $pos = $block * self::SMALL_BLOCK_SIZE; $streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE); - $block = self::_GetInt4d($this->smallBlockChain, $block*4); + $block = self::getInt4d($this->smallBlockChain, $block*4); } return $streamData; @@ -207,7 +207,7 @@ public function getStream($stream) while ($block != -2) { $pos = ($block + 1) * self::BIG_BLOCK_SIZE; $streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); - $block = self::_GetInt4d($this->bigBlockChain, $block*4); + $block = self::getInt4d($this->bigBlockChain, $block*4); } return $streamData; @@ -228,7 +228,7 @@ private function _readData($bl) while ($block != -2) { $pos = ($block + 1) * self::BIG_BLOCK_SIZE; $data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); - $block = self::_GetInt4d($this->bigBlockChain, $block*4); + $block = self::getInt4d($this->bigBlockChain, $block*4); } return $data; } @@ -236,7 +236,7 @@ private function _readData($bl) /** * Read entries in the directory stream. */ - private function _readPropertySets() + private function readPropertySets() { $offset = 0; @@ -254,9 +254,9 @@ private function _readPropertySets() // sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook) // sectorID of first sector of the short-stream container stream, if this entry is root entry - $startBlock = self::_GetInt4d($d, self::START_BLOCK_POS); + $startBlock = self::getInt4d($d, self::START_BLOCK_POS); - $size = self::_GetInt4d($d, self::SIZE_POS); + $size = self::getInt4d($d, self::SIZE_POS); $name = str_replace("\x00", "", substr($d, 0, $nameSize)); @@ -301,7 +301,7 @@ private function _readPropertySets() * @param int $pos * @return int */ - private static function _GetInt4d($data, $pos) + private static function getInt4d($data, $pos) { // FIX: represent numbers correctly on 64-bit system // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 diff --git a/Classes/PHPExcel/Worksheet/AutoFilter.php b/Classes/PHPExcel/Worksheet/AutoFilter.php index e86f97830..6ec8a4466 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Worksheet_AutoFilter * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Worksheet_AutoFilter - * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Worksheet_AutoFilter { /** @@ -40,7 +32,7 @@ class PHPExcel_Worksheet_AutoFilter * * @var PHPExcel_Worksheet */ - private $_workSheet = null; + private $workSheet; /** @@ -48,7 +40,7 @@ class PHPExcel_Worksheet_AutoFilter * * @var string */ - private $_range = ''; + private $range = ''; /** @@ -56,7 +48,7 @@ class PHPExcel_Worksheet_AutoFilter * * @var array of PHPExcel_Worksheet_AutoFilter_Column */ - private $_columns = array(); + private $columns = array(); /** @@ -67,8 +59,8 @@ class PHPExcel_Worksheet_AutoFilter */ public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = null) { - $this->_range = $pRange; - $this->_workSheet = $pSheet; + $this->range = $pRange; + $this->workSheet = $pSheet; } /** @@ -78,7 +70,7 @@ public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = null) */ public function getParent() { - return $this->_workSheet; + return $this->workSheet; } /** @@ -89,7 +81,7 @@ public function getParent() */ public function setParent(PHPExcel_Worksheet $pSheet = null) { - $this->_workSheet = $pSheet; + $this->workSheet = $pSheet; return $this; } @@ -101,7 +93,7 @@ public function setParent(PHPExcel_Worksheet $pSheet = null) */ public function getRange() { - return $this->_range; + return $this->range; } /** @@ -120,23 +112,23 @@ public function setRange($pRange = '') } if (strpos($pRange, ':') !== false) { - $this->_range = $pRange; + $this->range = $pRange; } elseif (empty($pRange)) { - $this->_range = ''; + $this->range = ''; } else { throw new PHPExcel_Exception('Autofilter must be set on a range of cells.'); } if (empty($pRange)) { // Discard all column rules - $this->_columns = array(); + $this->columns = array(); } else { // Discard any column rules that are no longer valid within this range - list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); - foreach ($this->_columns as $key => $value) { + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->range); + foreach ($this->columns as $key => $value) { $colIndex = PHPExcel_Cell::columnIndexFromString($key); if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) { - unset($this->_columns[$key]); + unset($this->columns[$key]); } } } @@ -152,7 +144,7 @@ public function setRange($pRange = '') */ public function getColumns() { - return $this->_columns; + return $this->columns; } /** @@ -164,12 +156,12 @@ public function getColumns() */ public function testColumnInRange($column) { - if (empty($this->_range)) { + if (empty($this->range)) { throw new PHPExcel_Exception("No autofilter range is defined."); } $columnIndex = PHPExcel_Cell::columnIndexFromString($column); - list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->range); if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) { throw new PHPExcel_Exception("Column is outside of current autofilter range."); } @@ -200,11 +192,11 @@ public function getColumn($pColumn) { $this->testColumnInRange($pColumn); - if (!isset($this->_columns[$pColumn])) { - $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + if (!isset($this->columns[$pColumn])) { + $this->columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); } - return $this->_columns[$pColumn]; + return $this->columns[$pColumn]; } /** @@ -216,7 +208,7 @@ public function getColumn($pColumn) */ public function getColumnByOffset($pColumnOffset = 0) { - list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->range); $pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1); return $this->getColumn($pColumn); @@ -242,12 +234,12 @@ public function setColumn($pColumn) $this->testColumnInRange($column); if (is_string($pColumn)) { - $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + $this->columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); } elseif (is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { $pColumn->setParent($this); - $this->_columns[$column] = $pColumn; + $this->columns[$column] = $pColumn; } - ksort($this->_columns); + ksort($this->columns); return $this; } @@ -263,8 +255,8 @@ public function clearColumn($pColumn) { $this->testColumnInRange($pColumn); - if (isset($this->_columns[$pColumn])) { - unset($this->_columns[$pColumn]); + if (isset($this->columns[$pColumn])) { + unset($this->columns[$pColumn]); } return $this; @@ -286,14 +278,14 @@ public function shiftColumn($fromColumn = null, $toColumn = null) $fromColumn = strtoupper($fromColumn); $toColumn = strtoupper($toColumn); - if (($fromColumn !== null) && (isset($this->_columns[$fromColumn])) && ($toColumn !== null)) { - $this->_columns[$fromColumn]->setParent(); - $this->_columns[$fromColumn]->setColumnIndex($toColumn); - $this->_columns[$toColumn] = $this->_columns[$fromColumn]; - $this->_columns[$toColumn]->setParent($this); - unset($this->_columns[$fromColumn]); + if (($fromColumn !== null) && (isset($this->columns[$fromColumn])) && ($toColumn !== null)) { + $this->columns[$fromColumn]->setParent(); + $this->columns[$fromColumn]->setColumnIndex($toColumn); + $this->columns[$toColumn] = $this->columns[$fromColumn]; + $this->columns[$toColumn]->setParent($this); + unset($this->columns[$fromColumn]); - ksort($this->_columns); + ksort($this->columns); } return $this; @@ -307,7 +299,7 @@ public function shiftColumn($fromColumn = null, $toColumn = null) * @param mixed[] $dataSet * @return boolean */ - private static function _filterTestInSimpleDataSet($cellValue, $dataSet) + private static function filterTestInSimpleDataSet($cellValue, $dataSet) { $dataSetValues = $dataSet['filterValues']; $blanks = $dataSet['blanks']; @@ -324,7 +316,7 @@ private static function _filterTestInSimpleDataSet($cellValue, $dataSet) * @param mixed[] $dataSet * @return boolean */ - private static function _filterTestInDateGroupSet($cellValue, $dataSet) + private static function filterTestInDateGroupSet($cellValue, $dataSet) { $dateSet = $dataSet['filterValues']; $blanks = $dataSet['blanks']; @@ -364,7 +356,7 @@ private static function _filterTestInDateGroupSet($cellValue, $dataSet) * @param mixed[] $ruleSet * @return boolean */ - private static function _filterTestInCustomDataSet($cellValue, $ruleSet) + private static function filterTestInCustomDataSet($cellValue, $ruleSet) { $dataSet = $ruleSet['filterRules']; $join = $ruleSet['join']; @@ -442,7 +434,7 @@ private static function _filterTestInCustomDataSet($cellValue, $ruleSet) * @param mixed[] $monthSet * @return boolean */ - private static function _filterTestInPeriodDateSet($cellValue, $monthSet) + private static function filterTestInPeriodDateSet($cellValue, $monthSet) { // Blank cells are always ignored, so return a FALSE if (($cellValue == '') || ($cellValue === null)) { @@ -464,8 +456,8 @@ private static function _filterTestInPeriodDateSet($cellValue, $monthSet) * * @var array */ - private static $_fromReplace = array('\*', '\?', '~~', '~.*', '~.?'); - private static $_toReplace = array('.*', '.', '~', '\*', '\?'); + private static $fromReplace = array('\*', '\?', '~~', '~.*', '~.?'); + private static $toReplace = array('.*', '.', '~', '\*', '\?'); /** @@ -475,7 +467,7 @@ private static function _filterTestInPeriodDateSet($cellValue, $monthSet) * @param PHPExcel_Worksheet_AutoFilter_Column &$filterColumn * @return mixed[] */ - private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) + private function dynamicFilterDateRange($dynamicRuleType, &$filterColumn) { $rDateType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); @@ -574,13 +566,13 @@ private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) $ruleValues[] = array('operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, 'value' => $maxVal); PHPExcel_Calculation_Functions::setReturnDateType($rDateType); - return array('method' => '_filterTestInCustomDataSet', 'arguments' => array('filterRules' => $ruleValues, 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND)); + return array('method' => 'filterTestInCustomDataSet', 'arguments' => array('filterRules' => $ruleValues, 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND)); } - private function _calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, $ruleValue) + private function calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, $ruleValue) { $range = $columnID.$startRow.':'.$columnID.$endRow; - $dataValues = PHPExcel_Calculation_Functions::flattenArray($this->_workSheet->rangeToArray($range, null, true, false)); + $dataValues = PHPExcel_Calculation_Functions::flattenArray($this->workSheet->rangeToArray($range, null, true, false)); $dataValues = array_filter($dataValues); if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) { @@ -600,14 +592,14 @@ private function _calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, */ public function showHideRows() { - list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->range); // The heading row should always be visible // echo 'AutoFilter Heading Row ', $rangeStart[1],' is always SHOWN',PHP_EOL; - $this->_workSheet->getRowDimension($rangeStart[1])->setVisible(true); + $this->workSheet->getRowDimension($rangeStart[1])->setVisible(true); $columnFilterTests = array(); - foreach ($this->_columns as $columnID => $filterColumn) { + foreach ($this->columns as $columnID => $filterColumn) { $rules = $filterColumn->getRules(); switch ($filterColumn->getFilterType()) { case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER: @@ -626,7 +618,7 @@ public function showHideRows() if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) { // Filter on absolute values $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInSimpleDataSet', + 'method' => 'filterTestInSimpleDataSet', 'arguments' => array('filterValues' => $ruleDataSet, 'blanks' => $blanks) ); } else { @@ -672,7 +664,7 @@ public function showHideRows() $arguments['time'] = array_filter($arguments['time']); $arguments['dateTime'] = array_filter($arguments['dateTime']); $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInDateGroupSet', + 'method' => 'filterTestInDateGroupSet', 'arguments' => array('filterValues' => $arguments, 'blanks' => $blanks) ); } @@ -687,7 +679,7 @@ public function showHideRows() if (!is_numeric($ruleValue)) { // Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards $ruleValue = preg_quote($ruleValue); - $ruleValue = str_replace(self::$_fromReplace, self::$_toReplace, $ruleValue); + $ruleValue = str_replace(self::$fromReplace, self::$toReplace, $ruleValue); if (trim($ruleValue) == '') { $customRuleForBlanks = true; $ruleValue = trim($ruleValue); @@ -697,7 +689,7 @@ public function showHideRows() } $join = $filterColumn->getJoin(); $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInCustomDataSet', + 'method' => 'filterTestInCustomDataSet', 'arguments' => array('filterRules' => $ruleValues, 'join' => $join, 'customRuleForBlanks' => $customRuleForBlanks) ); break; @@ -711,7 +703,7 @@ public function showHideRows() // Number (Average) based // Calculate the average $averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')'; - $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula, null, $this->_workSheet->getCell('A1')); + $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula, null, $this->workSheet->getCell('A1')); // Set above/below rule based on greaterThan or LessTan $operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN @@ -720,7 +712,7 @@ public function showHideRows() 'value' => $average ); $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInCustomDataSet', + 'method' => 'filterTestInCustomDataSet', 'arguments' => array('filterRules' => $ruleValues, 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR) ); } else { @@ -737,13 +729,13 @@ public function showHideRows() $ruleValues = range($periodStart, $periodEnd); } $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInPeriodDateSet', + 'method' => 'filterTestInPeriodDateSet', 'arguments' => $ruleValues ); $filterColumn->setAttributes(array()); } else { // Date Range - $columnFilterTests[$columnID] = $this->_dynamicFilterDateRange($dynamicRuleType, $filterColumn); + $columnFilterTests[$columnID] = $this->dynamicFilterDateRange($dynamicRuleType, $filterColumn); break; } } @@ -768,14 +760,14 @@ public function showHideRows() $ruleValue = 500; } - $maxVal = $this->_calculateTopTenValue($columnID, $rangeStart[1]+1, $rangeEnd[1], $toptenRuleType, $ruleValue); + $maxVal = $this->calculateTopTenValue($columnID, $rangeStart[1]+1, $rangeEnd[1], $toptenRuleType, $ruleValue); $operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL; $ruleValues[] = array('operator' => $operator, 'value' => $maxVal); $columnFilterTests[$columnID] = array( - 'method' => '_filterTestInCustomDataSet', + 'method' => 'filterTestInCustomDataSet', 'arguments' => array('filterRules' => $ruleValues, 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR) ); $filterColumn->setAttributes(array('maxVal' => $maxVal)); @@ -792,7 +784,7 @@ public function showHideRows() $result = true; foreach ($columnFilterTests as $columnID => $columnFilterTest) { // echo 'Testing cell ', $columnID.$row,PHP_EOL; - $cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue(); + $cellValue = $this->workSheet->getCell($columnID.$row)->getCalculatedValue(); // echo 'Value is ', $cellValue,PHP_EOL; // Execute the filter test $result = $result && @@ -808,7 +800,7 @@ public function showHideRows() } // Set show/hide for the row based on the result of the autoFilter result // echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL; - $this->_workSheet->getRowDimension($row)->setVisible($result); + $this->workSheet->getRowDimension($row)->setVisible($result); } return $this; @@ -823,13 +815,13 @@ public function __clone() $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { - if ($key == '_workSheet') { + if ($key == 'workSheet') { // Detach from worksheet $this->{$key} = null; } else { $this->{$key} = clone $value; } - } elseif ((is_array($value)) && ($key == '_columns')) { + } elseif ((is_array($value)) && ($key == 'columns')) { // The columns array of PHPExcel_Worksheet_AutoFilter objects $this->{$key} = array(); foreach ($value as $k => $v) { @@ -849,6 +841,6 @@ public function __clone() */ public function __toString() { - return (string) $this->_range; + return (string) $this->range; } } diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php index e30cb3cdf..d64fd8165 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Worksheet_AutoFilter_Column * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,32 +25,23 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Worksheet_AutoFilter_Column - * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Worksheet_AutoFilter_Column { - const AUTOFILTER_FILTERTYPE_FILTER = 'filters'; - const AUTOFILTER_FILTERTYPE_CUSTOMFILTER = 'customFilters'; + const AUTOFILTER_FILTERTYPE_FILTER = 'filters'; + const AUTOFILTER_FILTERTYPE_CUSTOMFILTER = 'customFilters'; // Supports no more than 2 rules, with an And/Or join criteria // if more than 1 rule is defined - const AUTOFILTER_FILTERTYPE_DYNAMICFILTER = 'dynamicFilter'; + const AUTOFILTER_FILTERTYPE_DYNAMICFILTER = 'dynamicFilter'; // Even though the filter rule is constant, the filtered data can vary // e.g. filtered by date = TODAY - const AUTOFILTER_FILTERTYPE_TOPTENFILTER = 'top10'; + const AUTOFILTER_FILTERTYPE_TOPTENFILTER = 'top10'; /** * Types of autofilter rules * * @var string[] */ - private static $_filterTypes = array( + private static $filterTypes = array( // Currently we're not handling // colorFilter // extLst @@ -61,15 +53,15 @@ class PHPExcel_Worksheet_AutoFilter_Column ); /* Multiple Rule Connections */ - const AUTOFILTER_COLUMN_JOIN_AND = 'and'; - const AUTOFILTER_COLUMN_JOIN_OR = 'or'; + const AUTOFILTER_COLUMN_JOIN_AND = 'and'; + const AUTOFILTER_COLUMN_JOIN_OR = 'or'; /** * Join options for autofilter rules * * @var string[] */ - private static $_ruleJoins = array( + private static $ruleJoins = array( self::AUTOFILTER_COLUMN_JOIN_AND, self::AUTOFILTER_COLUMN_JOIN_OR, ); @@ -79,7 +71,7 @@ class PHPExcel_Worksheet_AutoFilter_Column * * @var PHPExcel_Worksheet_AutoFilter */ - private $_parent = null; + private $parent; /** @@ -87,7 +79,7 @@ class PHPExcel_Worksheet_AutoFilter_Column * * @var string */ - private $_columnIndex = ''; + private $columnIndex = ''; /** @@ -95,7 +87,7 @@ class PHPExcel_Worksheet_AutoFilter_Column * * @var string */ - private $_filterType = self::AUTOFILTER_FILTERTYPE_FILTER; + private $filterType = self::AUTOFILTER_FILTERTYPE_FILTER; /** @@ -103,7 +95,7 @@ class PHPExcel_Worksheet_AutoFilter_Column * * @var string */ - private $_join = self::AUTOFILTER_COLUMN_JOIN_OR; + private $join = self::AUTOFILTER_COLUMN_JOIN_OR; /** @@ -111,7 +103,7 @@ class PHPExcel_Worksheet_AutoFilter_Column * * @var array of PHPExcel_Worksheet_AutoFilter_Column_Rule */ - private $_ruleset = array(); + private $ruleset = array(); /** @@ -119,7 +111,7 @@ class PHPExcel_Worksheet_AutoFilter_Column * * @var array of mixed */ - private $_attributes = array(); + private $attributes = array(); /** @@ -130,8 +122,8 @@ class PHPExcel_Worksheet_AutoFilter_Column */ public function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = null) { - $this->_columnIndex = $pColumn; - $this->_parent = $pParent; + $this->columnIndex = $pColumn; + $this->parent = $pParent; } /** @@ -141,7 +133,7 @@ public function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = n */ public function getColumnIndex() { - return $this->_columnIndex; + return $this->columnIndex; } /** @@ -155,11 +147,11 @@ public function setColumnIndex($pColumn) { // Uppercase coordinate $pColumn = strtoupper($pColumn); - if ($this->_parent !== null) { - $this->_parent->testColumnInRange($pColumn); + if ($this->parent !== null) { + $this->parent->testColumnInRange($pColumn); } - $this->_columnIndex = $pColumn; + $this->columnIndex = $pColumn; return $this; } @@ -171,7 +163,7 @@ public function setColumnIndex($pColumn) */ public function getParent() { - return $this->_parent; + return $this->parent; } /** @@ -182,7 +174,7 @@ public function getParent() */ public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = null) { - $this->_parent = $pParent; + $this->parent = $pParent; return $this; } @@ -194,7 +186,7 @@ public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = null) */ public function getFilterType() { - return $this->_filterType; + return $this->filterType; } /** @@ -206,11 +198,11 @@ public function getFilterType() */ public function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER) { - if (!in_array($pFilterType, self::$_filterTypes)) { + if (!in_array($pFilterType, self::$filterTypes)) { throw new PHPExcel_Exception('Invalid filter type for column AutoFilter.'); } - $this->_filterType = $pFilterType; + $this->filterType = $pFilterType; return $this; } @@ -222,7 +214,7 @@ public function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER) */ public function getJoin() { - return $this->_join; + return $this->join; } /** @@ -236,11 +228,11 @@ public function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR) { // Lowercase And/Or $pJoin = strtolower($pJoin); - if (!in_array($pJoin, self::$_ruleJoins)) { + if (!in_array($pJoin, self::$ruleJoins)) { throw new PHPExcel_Exception('Invalid rule connection for column AutoFilter.'); } - $this->_join = $pJoin; + $this->join = $pJoin; return $this; } @@ -254,7 +246,7 @@ public function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR) */ public function setAttributes($pAttributes = array()) { - $this->_attributes = $pAttributes; + $this->attributes = $pAttributes; return $this; } @@ -269,7 +261,7 @@ public function setAttributes($pAttributes = array()) */ public function setAttribute($pName, $pValue) { - $this->_attributes[$pName] = $pValue; + $this->attributes[$pName] = $pValue; return $this; } @@ -281,7 +273,7 @@ public function setAttribute($pName, $pValue) */ public function getAttributes() { - return $this->_attributes; + return $this->attributes; } /** @@ -292,8 +284,8 @@ public function getAttributes() */ public function getAttribute($pName) { - if (isset($this->_attributes[$pName])) { - return $this->_attributes[$pName]; + if (isset($this->attributes[$pName])) { + return $this->attributes[$pName]; } return null; } @@ -306,7 +298,7 @@ public function getAttribute($pName) */ public function getRules() { - return $this->_ruleset; + return $this->ruleset; } /** @@ -317,10 +309,10 @@ public function getRules() */ public function getRule($pIndex) { - if (!isset($this->_ruleset[$pIndex])) { - $this->_ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); + if (!isset($this->ruleset[$pIndex])) { + $this->ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); } - return $this->_ruleset[$pIndex]; + return $this->ruleset[$pIndex]; } /** @@ -330,9 +322,9 @@ public function getRule($pIndex) */ public function createRule() { - $this->_ruleset[] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); + $this->ruleset[] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); - return end($this->_ruleset); + return end($this->ruleset); } /** @@ -345,7 +337,7 @@ public function createRule() public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $returnRule = true) { $pRule->setParent($this); - $this->_ruleset[] = $pRule; + $this->ruleset[] = $pRule; return ($returnRule) ? $pRule : $this; } @@ -359,10 +351,10 @@ public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $retur */ public function deleteRule($pIndex) { - if (isset($this->_ruleset[$pIndex])) { - unset($this->_ruleset[$pIndex]); + if (isset($this->ruleset[$pIndex])) { + unset($this->ruleset[$pIndex]); // If we've just deleted down to a single rule, then reset And/Or joining to Or - if (count($this->_ruleset) <= 1) { + if (count($this->ruleset) <= 1) { $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); } } @@ -377,7 +369,7 @@ public function deleteRule($pIndex) */ public function clearRules() { - $this->_ruleset = array(); + $this->ruleset = array(); $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); return $this; @@ -391,13 +383,13 @@ public function __clone() $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { - if ($key == '_parent') { + if ($key == 'parent') { // Detach from autofilter parent $this->$key = null; } else { $this->$key = clone $value; } - } elseif ((is_array($value)) && ($key == '_ruleset')) { + } elseif ((is_array($value)) && ($key == 'ruleset')) { // The columns array of PHPExcel_Worksheet_AutoFilter objects $this->$key = array(); foreach ($value as $k => $v) { diff --git a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php index 2250bcde8..39ad18bf3 100644 --- a/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php +++ b/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Worksheet_AutoFilter_Column_Rule * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,24 +25,15 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Worksheet_AutoFilter_Column_Rule - * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Worksheet_AutoFilter_Column_Rule { const AUTOFILTER_RULETYPE_FILTER = 'filter'; - const AUTOFILTER_RULETYPE_DATEGROUP = 'dateGroupItem'; - const AUTOFILTER_RULETYPE_CUSTOMFILTER = 'customFilter'; - const AUTOFILTER_RULETYPE_DYNAMICFILTER = 'dynamicFilter'; - const AUTOFILTER_RULETYPE_TOPTENFILTER = 'top10Filter'; + const AUTOFILTER_RULETYPE_DATEGROUP = 'dateGroupItem'; + const AUTOFILTER_RULETYPE_CUSTOMFILTER = 'customFilter'; + const AUTOFILTER_RULETYPE_DYNAMICFILTER = 'dynamicFilter'; + const AUTOFILTER_RULETYPE_TOPTENFILTER = 'top10Filter'; - private static $_ruleTypes = array( + private static $ruleTypes = array( // Currently we're not handling // colorFilter // extLst @@ -53,14 +45,14 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule self::AUTOFILTER_RULETYPE_TOPTENFILTER, ); - const AUTOFILTER_RULETYPE_DATEGROUP_YEAR = 'year'; - const AUTOFILTER_RULETYPE_DATEGROUP_MONTH = 'month'; - const AUTOFILTER_RULETYPE_DATEGROUP_DAY = 'day'; - const AUTOFILTER_RULETYPE_DATEGROUP_HOUR = 'hour'; - const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE = 'minute'; - const AUTOFILTER_RULETYPE_DATEGROUP_SECOND = 'second'; + const AUTOFILTER_RULETYPE_DATEGROUP_YEAR = 'year'; + const AUTOFILTER_RULETYPE_DATEGROUP_MONTH = 'month'; + const AUTOFILTER_RULETYPE_DATEGROUP_DAY = 'day'; + const AUTOFILTER_RULETYPE_DATEGROUP_HOUR = 'hour'; + const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE = 'minute'; + const AUTOFILTER_RULETYPE_DATEGROUP_SECOND = 'second'; - private static $_dateTimeGroups = array( + private static $dateTimeGroups = array( self::AUTOFILTER_RULETYPE_DATEGROUP_YEAR, self::AUTOFILTER_RULETYPE_DATEGROUP_MONTH, self::AUTOFILTER_RULETYPE_DATEGROUP_DAY, @@ -69,54 +61,54 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule self::AUTOFILTER_RULETYPE_DATEGROUP_SECOND, ); - const AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY = 'yesterday'; - const AUTOFILTER_RULETYPE_DYNAMIC_TODAY = 'today'; - const AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW = 'tomorrow'; - const AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE = 'yearToDate'; - const AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR = 'thisYear'; - const AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER = 'thisQuarter'; - const AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH = 'thisMonth'; - const AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK = 'thisWeek'; - const AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR = 'lastYear'; - const AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER = 'lastQuarter'; - const AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH = 'lastMonth'; - const AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK = 'lastWeek'; - const AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR = 'nextYear'; - const AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER = 'nextQuarter'; - const AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH = 'nextMonth'; - const AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK = 'nextWeek'; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1 = 'M1'; - const AUTOFILTER_RULETYPE_DYNAMIC_JANUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2 = 'M2'; - const AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3 = 'M3'; - const AUTOFILTER_RULETYPE_DYNAMIC_MARCH = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4 = 'M4'; - const AUTOFILTER_RULETYPE_DYNAMIC_APRIL = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5 = 'M5'; - const AUTOFILTER_RULETYPE_DYNAMIC_MAY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6 = 'M6'; - const AUTOFILTER_RULETYPE_DYNAMIC_JUNE = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7 = 'M7'; - const AUTOFILTER_RULETYPE_DYNAMIC_JULY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8 = 'M8'; - const AUTOFILTER_RULETYPE_DYNAMIC_AUGUST = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9 = 'M9'; - const AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10 = 'M10'; - const AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11 = 'M11'; - const AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11; - const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12 = 'M12'; - const AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12; - const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1 = 'Q1'; - const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2 = 'Q2'; - const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3 = 'Q3'; - const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4 = 'Q4'; - const AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE = 'aboveAverage'; - const AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE = 'belowAverage'; - - private static $_dynamicTypes = array( + const AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY = 'yesterday'; + const AUTOFILTER_RULETYPE_DYNAMIC_TODAY = 'today'; + const AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW = 'tomorrow'; + const AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE = 'yearToDate'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR = 'thisYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER = 'thisQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH = 'thisMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK = 'thisWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR = 'lastYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER = 'lastQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH = 'lastMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK = 'lastWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR = 'nextYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER = 'nextQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH = 'nextMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK = 'nextWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1 = 'M1'; + const AUTOFILTER_RULETYPE_DYNAMIC_JANUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2 = 'M2'; + const AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3 = 'M3'; + const AUTOFILTER_RULETYPE_DYNAMIC_MARCH = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4 = 'M4'; + const AUTOFILTER_RULETYPE_DYNAMIC_APRIL = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5 = 'M5'; + const AUTOFILTER_RULETYPE_DYNAMIC_MAY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6 = 'M6'; + const AUTOFILTER_RULETYPE_DYNAMIC_JUNE = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7 = 'M7'; + const AUTOFILTER_RULETYPE_DYNAMIC_JULY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8 = 'M8'; + const AUTOFILTER_RULETYPE_DYNAMIC_AUGUST = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9 = 'M9'; + const AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10 = 'M10'; + const AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11 = 'M11'; + const AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12 = 'M12'; + const AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1 = 'Q1'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2 = 'Q2'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3 = 'Q3'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4 = 'Q4'; + const AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE = 'aboveAverage'; + const AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE = 'belowAverage'; + + private static $dynamicTypes = array( self::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY, self::AUTOFILTER_RULETYPE_DYNAMIC_TODAY, self::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW, @@ -162,14 +154,14 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule * <xsd:enumeration value="greaterThanOrEqual"/> * <xsd:enumeration value="greaterThan"/> */ - const AUTOFILTER_COLUMN_RULE_EQUAL = 'equal'; - const AUTOFILTER_COLUMN_RULE_NOTEQUAL = 'notEqual'; + const AUTOFILTER_COLUMN_RULE_EQUAL = 'equal'; + const AUTOFILTER_COLUMN_RULE_NOTEQUAL = 'notEqual'; const AUTOFILTER_COLUMN_RULE_GREATERTHAN = 'greaterThan'; - const AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL = 'greaterThanOrEqual'; - const AUTOFILTER_COLUMN_RULE_LESSTHAN = 'lessThan'; + const AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL = 'greaterThanOrEqual'; + const AUTOFILTER_COLUMN_RULE_LESSTHAN = 'lessThan'; const AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL = 'lessThanOrEqual'; - private static $_operators = array( + private static $operators = array( self::AUTOFILTER_COLUMN_RULE_EQUAL, self::AUTOFILTER_COLUMN_RULE_NOTEQUAL, self::AUTOFILTER_COLUMN_RULE_GREATERTHAN, @@ -178,18 +170,18 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule self::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL, ); - const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE = 'byValue'; - const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT = 'byPercent'; + const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE = 'byValue'; + const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT = 'byPercent'; - private static $_topTenValue = array( + private static $topTenValue = array( self::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, self::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, ); - const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP = 'top'; - const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM = 'bottom'; + const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP = 'top'; + const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM = 'bottom'; - private static $_topTenType = array( + private static $topTenType = array( self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, self::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM, ); @@ -234,7 +226,7 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule * * @var PHPExcel_Worksheet_AutoFilter_Column */ - private $_parent = null; + private $parent = null; /** @@ -242,7 +234,7 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule * * @var string */ - private $_ruleType = self::AUTOFILTER_RULETYPE_FILTER; + private $ruleType = self::AUTOFILTER_RULETYPE_FILTER; /** @@ -250,21 +242,21 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule * * @var string */ - private $_value = ''; + private $value = ''; /** * Autofilter Rule Operator * * @var string */ - private $_operator = self::AUTOFILTER_COLUMN_RULE_EQUAL; + private $operator = self::AUTOFILTER_COLUMN_RULE_EQUAL; /** * DateTimeGrouping Group Value * * @var string */ - private $_grouping = ''; + private $grouping = ''; /** @@ -274,7 +266,7 @@ class PHPExcel_Worksheet_AutoFilter_Column_Rule */ public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = null) { - $this->_parent = $pParent; + $this->parent = $pParent; } /** @@ -284,7 +276,7 @@ public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = null */ public function getRuleType() { - return $this->_ruleType; + return $this->ruleType; } /** @@ -296,11 +288,11 @@ public function getRuleType() */ public function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) { - if (!in_array($pRuleType, self::$_ruleTypes)) { + if (!in_array($pRuleType, self::$ruleTypes)) { throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); } - $this->_ruleType = $pRuleType; + $this->ruleType = $pRuleType; return $this; } @@ -312,7 +304,7 @@ public function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) */ public function getValue() { - return $this->_value; + return $this->value; } /** @@ -328,21 +320,21 @@ public function setValue($pValue = '') $grouping = -1; foreach ($pValue as $key => $value) { // Validate array entries - if (!in_array($key, self::$_dateTimeGroups)) { + if (!in_array($key, self::$dateTimeGroups)) { // Remove any invalid entries from the value array unset($pValue[$key]); } else { // Work out what the dateTime grouping will be - $grouping = max($grouping, array_search($key, self::$_dateTimeGroups)); + $grouping = max($grouping, array_search($key, self::$dateTimeGroups)); } } if (count($pValue) == 0) { throw new PHPExcel_Exception('Invalid rule value for column AutoFilter Rule.'); } // Set the dateTime grouping that we've anticipated - $this->setGrouping(self::$_dateTimeGroups[$grouping]); + $this->setGrouping(self::$dateTimeGroups[$grouping]); } - $this->_value = $pValue; + $this->value = $pValue; return $this; } @@ -354,7 +346,7 @@ public function setValue($pValue = '') */ public function getOperator() { - return $this->_operator; + return $this->operator; } /** @@ -369,11 +361,11 @@ public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) if (empty($pOperator)) { $pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL; } - if ((!in_array($pOperator, self::$_operators)) && - (!in_array($pOperator, self::$_topTenValue))) { + if ((!in_array($pOperator, self::$operators)) && + (!in_array($pOperator, self::$topTenValue))) { throw new PHPExcel_Exception('Invalid operator for column AutoFilter Rule.'); } - $this->_operator = $pOperator; + $this->operator = $pOperator; return $this; } @@ -385,7 +377,7 @@ public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) */ public function getGrouping() { - return $this->_grouping; + return $this->grouping; } /** @@ -398,12 +390,12 @@ public function getGrouping() public function setGrouping($pGrouping = null) { if (($pGrouping !== null) && - (!in_array($pGrouping, self::$_dateTimeGroups)) && - (!in_array($pGrouping, self::$_dynamicTypes)) && - (!in_array($pGrouping, self::$_topTenType))) { + (!in_array($pGrouping, self::$dateTimeGroups)) && + (!in_array($pGrouping, self::$dynamicTypes)) && + (!in_array($pGrouping, self::$topTenType))) { throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); } - $this->_grouping = $pGrouping; + $this->grouping = $pGrouping; return $this; } @@ -438,7 +430,7 @@ public function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue */ public function getParent() { - return $this->_parent; + return $this->parent; } /** @@ -449,7 +441,7 @@ public function getParent() */ public function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = null) { - $this->_parent = $pParent; + $this->parent = $pParent; return $this; } @@ -462,7 +454,7 @@ public function __clone() $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { - if ($key == '_parent') { + if ($key == 'parent') { // Detach from autofilter column parent $this->$key = null; } else { diff --git a/Classes/PHPExcel/Worksheet/BaseDrawing.php b/Classes/PHPExcel/Worksheet/BaseDrawing.php index 9ae35adc2..d63c28213 100644 --- a/Classes/PHPExcel/Worksheet/BaseDrawing.php +++ b/Classes/PHPExcel/Worksheet/BaseDrawing.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Worksheet_BaseDrawing * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Worksheet_BaseDrawing - * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { /** @@ -40,14 +32,14 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * * @var int */ - private static $_imageCounter = 0; + private static $imageCounter = 0; /** * Image index * * @var int */ - private $_imageIndex = 0; + private $imageIndex = 0; /** * Name @@ -145,8 +137,8 @@ public function __construct() $this->_shadow = new PHPExcel_Worksheet_Drawing_Shadow(); // Set image index - self::$_imageCounter++; - $this->_imageIndex = self::$_imageCounter; + self::$imageCounter++; + $this->imageIndex = self::$imageCounter; } /** @@ -156,7 +148,7 @@ public function __construct() */ public function getImageIndex() { - return $this->_imageIndex; + return $this->imageIndex; } /** @@ -483,7 +475,19 @@ public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) */ public function getHashCode() { - return md5($this->_name.$this->_description.$this->_worksheet->getHashCode().$this->_coordinates.$this->_offsetX.$this->_offsetY.$this->_width.$this->_height.$this->_rotation.$this->_shadow->getHashCode().__CLASS__); + return md5( + $this->_name . + $this->_description . + $this->_worksheet->getHashCode() . + $this->_coordinates . + $this->_offsetX . + $this->_offsetY . + $this->_width . + $this->_height . + $this->_rotation . + $this->_shadow->getHashCode() . + __CLASS__ + ); } /** diff --git a/Classes/PHPExcel/Worksheet/Drawing.php b/Classes/PHPExcel/Worksheet/Drawing.php index 983bda48e..e259c3c31 100644 --- a/Classes/PHPExcel/Worksheet/Drawing.php +++ b/Classes/PHPExcel/Worksheet/Drawing.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Worksheet_Drawing * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Worksheet_Drawing - * - * @category PHPExcel - * @package PHPExcel_Worksheet_Drawing - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { /** @@ -40,7 +32,7 @@ class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implemen * * @var string */ - private $_path; + private $path; /** * Create a new PHPExcel_Worksheet_Drawing @@ -48,7 +40,7 @@ class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implemen public function __construct() { // Initialise values - $this->_path = ''; + $this->path = ''; // Initialize parent parent::__construct(); @@ -61,7 +53,7 @@ public function __construct() */ public function getFilename() { - return basename($this->_path); + return basename($this->path); } /** @@ -83,7 +75,7 @@ public function getIndexedFilename() */ public function getExtension() { - $exploded = explode(".", basename($this->_path)); + $exploded = explode(".", basename($this->path)); return $exploded[count($exploded) - 1]; } @@ -94,7 +86,7 @@ public function getExtension() */ public function getPath() { - return $this->_path; + return $this->path; } /** @@ -109,7 +101,7 @@ public function setPath($pValue = '', $pVerifyFile = true) { if ($pVerifyFile) { if (file_exists($pValue)) { - $this->_path = $pValue; + $this->path = $pValue; if ($this->_width == 0 && $this->_height == 0) { // Get width/height @@ -119,7 +111,7 @@ public function setPath($pValue = '', $pVerifyFile = true) throw new PHPExcel_Exception("File $pValue not found!"); } } else { - $this->_path = $pValue; + $this->path = $pValue; } return $this; } @@ -132,9 +124,9 @@ public function setPath($pValue = '', $pVerifyFile = true) public function getHashCode() { return md5( - $this->_path - . parent::getHashCode() - . __CLASS__ + $this->path . + parent::getHashCode() . + __CLASS__ ); } diff --git a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php index 9806bb903..84db91d57 100644 --- a/Classes/PHPExcel/Worksheet/Drawing/Shadow.php +++ b/Classes/PHPExcel/Worksheet/Drawing/Shadow.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Worksheet_Drawing_Shadow * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,33 +25,24 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Worksheet_Drawing_Shadow - * - * @category PHPExcel - * @package PHPExcel_Worksheet_Drawing - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable { /* Shadow alignment */ - const SHADOW_BOTTOM = 'b'; - const SHADOW_BOTTOM_LEFT = 'bl'; - const SHADOW_BOTTOM_RIGHT = 'br'; - const SHADOW_CENTER = 'ctr'; - const SHADOW_LEFT = 'l'; - const SHADOW_TOP = 't'; - const SHADOW_TOP_LEFT = 'tl'; - const SHADOW_TOP_RIGHT = 'tr'; + const SHADOW_BOTTOM = 'b'; + const SHADOW_BOTTOM_LEFT = 'bl'; + const SHADOW_BOTTOM_RIGHT = 'br'; + const SHADOW_CENTER = 'ctr'; + const SHADOW_LEFT = 'l'; + const SHADOW_TOP = 't'; + const SHADOW_TOP_LEFT = 'tl'; + const SHADOW_TOP_RIGHT = 'tr'; /** * Visible * * @var boolean */ - private $_visible; + private $visible; /** * Blur radius @@ -59,7 +51,7 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * * @var int */ - private $_blurRadius; + private $blurRadius; /** * Shadow distance @@ -68,35 +60,35 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable * * @var int */ - private $_distance; + private $distance; /** * Shadow direction (in degrees) * * @var int */ - private $_direction; + private $direction; /** * Shadow alignment * * @var int */ - private $_alignment; + private $alignment; /** * Color * * @var PHPExcel_Style_Color */ - private $_color; + private $color; /** * Alpha * * @var int */ - private $_alpha; + private $alpha; /** * Create a new PHPExcel_Worksheet_Drawing_Shadow @@ -104,13 +96,13 @@ class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable public function __construct() { // Initialise values - $this->_visible = false; - $this->_blurRadius = 6; - $this->_distance = 2; - $this->_direction = 0; - $this->_alignment = PHPExcel_Worksheet_Drawing_Shadow::SHADOW_BOTTOM_RIGHT; - $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK); - $this->_alpha = 50; + $this->visible = false; + $this->blurRadius = 6; + $this->distance = 2; + $this->direction = 0; + $this->alignment = PHPExcel_Worksheet_Drawing_Shadow::SHADOW_BOTTOM_RIGHT; + $this->color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK); + $this->alpha = 50; } /** @@ -120,7 +112,7 @@ public function __construct() */ public function getVisible() { - return $this->_visible; + return $this->visible; } /** @@ -131,7 +123,7 @@ public function getVisible() */ public function setVisible($pValue = false) { - $this->_visible = $pValue; + $this->visible = $pValue; return $this; } @@ -142,7 +134,7 @@ public function setVisible($pValue = false) */ public function getBlurRadius() { - return $this->_blurRadius; + return $this->blurRadius; } /** @@ -153,7 +145,7 @@ public function getBlurRadius() */ public function setBlurRadius($pValue = 6) { - $this->_blurRadius = $pValue; + $this->blurRadius = $pValue; return $this; } @@ -164,7 +156,7 @@ public function setBlurRadius($pValue = 6) */ public function getDistance() { - return $this->_distance; + return $this->distance; } /** @@ -175,7 +167,7 @@ public function getDistance() */ public function setDistance($pValue = 2) { - $this->_distance = $pValue; + $this->distance = $pValue; return $this; } @@ -186,7 +178,7 @@ public function setDistance($pValue = 2) */ public function getDirection() { - return $this->_direction; + return $this->direction; } /** @@ -197,7 +189,7 @@ public function getDirection() */ public function setDirection($pValue = 0) { - $this->_direction = $pValue; + $this->direction = $pValue; return $this; } @@ -208,7 +200,7 @@ public function setDirection($pValue = 0) */ public function getAlignment() { - return $this->_alignment; + return $this->alignment; } /** @@ -219,7 +211,7 @@ public function getAlignment() */ public function setAlignment($pValue = 0) { - $this->_alignment = $pValue; + $this->alignment = $pValue; return $this; } @@ -230,7 +222,7 @@ public function setAlignment($pValue = 0) */ public function getColor() { - return $this->_color; + return $this->color; } /** @@ -242,7 +234,7 @@ public function getColor() */ public function setColor(PHPExcel_Style_Color $pValue = null) { - $this->_color = $pValue; + $this->color = $pValue; return $this; } @@ -253,7 +245,7 @@ public function setColor(PHPExcel_Style_Color $pValue = null) */ public function getAlpha() { - return $this->_alpha; + return $this->alpha; } /** @@ -264,7 +256,7 @@ public function getAlpha() */ public function setAlpha($pValue = 0) { - $this->_alpha = $pValue; + $this->alpha = $pValue; return $this; } @@ -276,14 +268,14 @@ public function setAlpha($pValue = 0) public function getHashCode() { return md5( - ($this->_visible ? 't' : 'f') - . $this->_blurRadius - . $this->_distance - . $this->_direction - . $this->_alignment - . $this->_color->getHashCode() - . $this->_alpha - . __CLASS__ + ($this->visible ? 't' : 'f') . + $this->blurRadius . + $this->distance . + $this->direction . + $this->alignment . + $this->color->getHashCode() . + $this->alpha . + __CLASS__ ); } diff --git a/Classes/PHPExcel/Worksheet/HeaderFooter.php b/Classes/PHPExcel/Worksheet/HeaderFooter.php index 394baf7c2..3a88923fc 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooter.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooter.php @@ -1,6 +1,6 @@ <?php /** - * PHPExcel + * PHPExcel_Worksheet_HeaderFooter * * Copyright (c) 2006 - 2015 PHPExcel * @@ -23,11 +23,6 @@ * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## - */ - - -/** - * PHPExcel_Worksheet_HeaderFooter * * <code> * Header/Footer Formatting Syntax taken from Office Open XML Part 4 - Markup Language Reference, page 1970: @@ -89,96 +84,93 @@ * &H - code for "shadow style" * </code> * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) */ class PHPExcel_Worksheet_HeaderFooter { /* Header/footer image location */ - const IMAGE_HEADER_LEFT = 'LH'; - const IMAGE_HEADER_CENTER = 'CH'; - const IMAGE_HEADER_RIGHT = 'RH'; - const IMAGE_FOOTER_LEFT = 'LF'; - const IMAGE_FOOTER_CENTER = 'CF'; - const IMAGE_FOOTER_RIGHT = 'RF'; + const IMAGE_HEADER_LEFT = 'LH'; + const IMAGE_HEADER_CENTER = 'CH'; + const IMAGE_HEADER_RIGHT = 'RH'; + const IMAGE_FOOTER_LEFT = 'LF'; + const IMAGE_FOOTER_CENTER = 'CF'; + const IMAGE_FOOTER_RIGHT = 'RF'; /** * OddHeader * * @var string */ - private $_oddHeader = ''; + private $oddHeader = ''; /** * OddFooter * * @var string */ - private $_oddFooter = ''; + private $oddFooter = ''; /** * EvenHeader * * @var string */ - private $_evenHeader = ''; + private $evenHeader = ''; /** * EvenFooter * * @var string */ - private $_evenFooter = ''; + private $evenFooter = ''; /** * FirstHeader * * @var string */ - private $_firstHeader = ''; + private $firstHeader = ''; /** * FirstFooter * * @var string */ - private $_firstFooter = ''; + private $firstFooter = ''; /** * Different header for Odd/Even, defaults to false * * @var boolean */ - private $_differentOddEven = false; + private $differentOddEven = false; /** * Different header for first page, defaults to false * * @var boolean */ - private $_differentFirst = false; + private $differentFirst = false; /** * Scale with document, defaults to true * * @var boolean */ - private $_scaleWithDocument = true; + private $scaleWithDocument = true; /** * Align with margins, defaults to true * * @var boolean */ - private $_alignWithMargins = true; + private $alignWithMargins = true; /** * Header/footer images * * @var PHPExcel_Worksheet_HeaderFooterDrawing[] */ - private $_headerFooterImages = array(); + private $headerFooterImages = array(); /** * Create a new PHPExcel_Worksheet_HeaderFooter @@ -194,7 +186,7 @@ public function __construct() */ public function getOddHeader() { - return $this->_oddHeader; + return $this->oddHeader; } /** @@ -205,7 +197,7 @@ public function getOddHeader() */ public function setOddHeader($pValue) { - $this->_oddHeader = $pValue; + $this->oddHeader = $pValue; return $this; } @@ -216,7 +208,7 @@ public function setOddHeader($pValue) */ public function getOddFooter() { - return $this->_oddFooter; + return $this->oddFooter; } /** @@ -227,7 +219,7 @@ public function getOddFooter() */ public function setOddFooter($pValue) { - $this->_oddFooter = $pValue; + $this->oddFooter = $pValue; return $this; } @@ -238,7 +230,7 @@ public function setOddFooter($pValue) */ public function getEvenHeader() { - return $this->_evenHeader; + return $this->evenHeader; } /** @@ -249,7 +241,7 @@ public function getEvenHeader() */ public function setEvenHeader($pValue) { - $this->_evenHeader = $pValue; + $this->evenHeader = $pValue; return $this; } @@ -260,7 +252,7 @@ public function setEvenHeader($pValue) */ public function getEvenFooter() { - return $this->_evenFooter; + return $this->evenFooter; } /** @@ -271,7 +263,7 @@ public function getEvenFooter() */ public function setEvenFooter($pValue) { - $this->_evenFooter = $pValue; + $this->evenFooter = $pValue; return $this; } @@ -282,7 +274,7 @@ public function setEvenFooter($pValue) */ public function getFirstHeader() { - return $this->_firstHeader; + return $this->firstHeader; } /** @@ -293,7 +285,7 @@ public function getFirstHeader() */ public function setFirstHeader($pValue) { - $this->_firstHeader = $pValue; + $this->firstHeader = $pValue; return $this; } @@ -304,7 +296,7 @@ public function setFirstHeader($pValue) */ public function getFirstFooter() { - return $this->_firstFooter; + return $this->firstFooter; } /** @@ -315,7 +307,7 @@ public function getFirstFooter() */ public function setFirstFooter($pValue) { - $this->_firstFooter = $pValue; + $this->firstFooter = $pValue; return $this; } @@ -326,7 +318,7 @@ public function setFirstFooter($pValue) */ public function getDifferentOddEven() { - return $this->_differentOddEven; + return $this->differentOddEven; } /** @@ -337,7 +329,7 @@ public function getDifferentOddEven() */ public function setDifferentOddEven($pValue = false) { - $this->_differentOddEven = $pValue; + $this->differentOddEven = $pValue; return $this; } @@ -348,7 +340,7 @@ public function setDifferentOddEven($pValue = false) */ public function getDifferentFirst() { - return $this->_differentFirst; + return $this->differentFirst; } /** @@ -359,7 +351,7 @@ public function getDifferentFirst() */ public function setDifferentFirst($pValue = false) { - $this->_differentFirst = $pValue; + $this->differentFirst = $pValue; return $this; } @@ -370,7 +362,7 @@ public function setDifferentFirst($pValue = false) */ public function getScaleWithDocument() { - return $this->_scaleWithDocument; + return $this->scaleWithDocument; } /** @@ -381,7 +373,7 @@ public function getScaleWithDocument() */ public function setScaleWithDocument($pValue = true) { - $this->_scaleWithDocument = $pValue; + $this->scaleWithDocument = $pValue; return $this; } @@ -392,7 +384,7 @@ public function setScaleWithDocument($pValue = true) */ public function getAlignWithMargins() { - return $this->_alignWithMargins; + return $this->alignWithMargins; } /** @@ -403,7 +395,7 @@ public function getAlignWithMargins() */ public function setAlignWithMargins($pValue = true) { - $this->_alignWithMargins = $pValue; + $this->alignWithMargins = $pValue; return $this; } @@ -417,7 +409,7 @@ public function setAlignWithMargins($pValue = true) */ public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $location = self::IMAGE_HEADER_LEFT) { - $this->_headerFooterImages[$location] = $image; + $this->headerFooterImages[$location] = $image; return $this; } @@ -430,8 +422,8 @@ public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $ */ public function removeImage($location = self::IMAGE_HEADER_LEFT) { - if (isset($this->_headerFooterImages[$location])) { - unset($this->_headerFooterImages[$location]); + if (isset($this->headerFooterImages[$location])) { + unset($this->headerFooterImages[$location]); } return $this; } @@ -449,7 +441,7 @@ public function setImages($images) throw new PHPExcel_Exception('Invalid parameter!'); } - $this->_headerFooterImages = $images; + $this->headerFooterImages = $images; return $this; } @@ -462,27 +454,27 @@ public function getImages() { // Sort array $images = array(); - if (isset($this->_headerFooterImages[self::IMAGE_HEADER_LEFT])) { - $images[self::IMAGE_HEADER_LEFT] = $this->_headerFooterImages[self::IMAGE_HEADER_LEFT]; + if (isset($this->headerFooterImages[self::IMAGE_HEADER_LEFT])) { + $images[self::IMAGE_HEADER_LEFT] = $this->headerFooterImages[self::IMAGE_HEADER_LEFT]; } - if (isset($this->_headerFooterImages[self::IMAGE_HEADER_CENTER])) { - $images[self::IMAGE_HEADER_CENTER] = $this->_headerFooterImages[self::IMAGE_HEADER_CENTER]; + if (isset($this->headerFooterImages[self::IMAGE_HEADER_CENTER])) { + $images[self::IMAGE_HEADER_CENTER] = $this->headerFooterImages[self::IMAGE_HEADER_CENTER]; } - if (isset($this->_headerFooterImages[self::IMAGE_HEADER_RIGHT])) { - $images[self::IMAGE_HEADER_RIGHT] = $this->_headerFooterImages[self::IMAGE_HEADER_RIGHT]; + if (isset($this->headerFooterImages[self::IMAGE_HEADER_RIGHT])) { + $images[self::IMAGE_HEADER_RIGHT] = $this->headerFooterImages[self::IMAGE_HEADER_RIGHT]; } - if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_LEFT])) { - $images[self::IMAGE_FOOTER_LEFT] = $this->_headerFooterImages[self::IMAGE_FOOTER_LEFT]; + if (isset($this->headerFooterImages[self::IMAGE_FOOTER_LEFT])) { + $images[self::IMAGE_FOOTER_LEFT] = $this->headerFooterImages[self::IMAGE_FOOTER_LEFT]; } - if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_CENTER])) { - $images[self::IMAGE_FOOTER_CENTER] = $this->_headerFooterImages[self::IMAGE_FOOTER_CENTER]; + if (isset($this->headerFooterImages[self::IMAGE_FOOTER_CENTER])) { + $images[self::IMAGE_FOOTER_CENTER] = $this->headerFooterImages[self::IMAGE_FOOTER_CENTER]; } - if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT])) { - $images[self::IMAGE_FOOTER_RIGHT] = $this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT]; + if (isset($this->headerFooterImages[self::IMAGE_FOOTER_RIGHT])) { + $images[self::IMAGE_FOOTER_RIGHT] = $this->headerFooterImages[self::IMAGE_FOOTER_RIGHT]; } - $this->_headerFooterImages = $images; + $this->headerFooterImages = $images; - return $this->_headerFooterImages; + return $this->headerFooterImages; } /** diff --git a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php index 6c1fa1f22..a491f4ba6 100644 --- a/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php +++ b/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Worksheet_HeaderFooterDrawing * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Worksheet_HeaderFooterDrawing - * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing implements PHPExcel_IComparable { /** @@ -40,49 +32,49 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing * * @var string */ - private $_path; + private $path; /** * Name * * @var string */ - protected $_name; + protected $name; /** * Offset X * * @var int */ - protected $_offsetX; + protected $offsetX; /** * Offset Y * * @var int */ - protected $_offsetY; + protected $offsetY; /** * Width * * @var int */ - protected $_width; + protected $width; /** * Height * * @var int */ - protected $_height; + protected $height; /** * Proportional resize * * @var boolean */ - protected $_resizeProportional; + protected $resizeProportional; /** * Create a new PHPExcel_Worksheet_HeaderFooterDrawing @@ -90,13 +82,13 @@ class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing public function __construct() { // Initialise values - $this->_path = ''; - $this->_name = ''; - $this->_offsetX = 0; - $this->_offsetY = 0; - $this->_width = 0; - $this->_height = 0; - $this->_resizeProportional = true; + $this->path = ''; + $this->name = ''; + $this->offsetX = 0; + $this->offsetY = 0; + $this->width = 0; + $this->height = 0; + $this->resizeProportional = true; } /** @@ -106,7 +98,7 @@ public function __construct() */ public function getName() { - return $this->_name; + return $this->name; } /** @@ -117,7 +109,7 @@ public function getName() */ public function setName($pValue = '') { - $this->_name = $pValue; + $this->name = $pValue; return $this; } @@ -128,7 +120,7 @@ public function setName($pValue = '') */ public function getOffsetX() { - return $this->_offsetX; + return $this->offsetX; } /** @@ -139,7 +131,7 @@ public function getOffsetX() */ public function setOffsetX($pValue = 0) { - $this->_offsetX = $pValue; + $this->offsetX = $pValue; return $this; } @@ -150,7 +142,7 @@ public function setOffsetX($pValue = 0) */ public function getOffsetY() { - return $this->_offsetY; + return $this->offsetY; } /** @@ -161,7 +153,7 @@ public function getOffsetY() */ public function setOffsetY($pValue = 0) { - $this->_offsetY = $pValue; + $this->offsetY = $pValue; return $this; } @@ -172,7 +164,7 @@ public function setOffsetY($pValue = 0) */ public function getWidth() { - return $this->_width; + return $this->width; } /** @@ -184,13 +176,13 @@ public function getWidth() public function setWidth($pValue = 0) { // Resize proportional? - if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_width / $this->_height; - $this->_height = round($ratio * $pValue); + if ($this->resizeProportional && $pValue != 0) { + $ratio = $this->width / $this->height; + $this->height = round($ratio * $pValue); } // Set width - $this->_width = $pValue; + $this->width = $pValue; return $this; } @@ -202,7 +194,7 @@ public function setWidth($pValue = 0) */ public function getHeight() { - return $this->_height; + return $this->height; } /** @@ -214,13 +206,13 @@ public function getHeight() public function setHeight($pValue = 0) { // Resize proportional? - if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_width / $this->_height; - $this->_width = round($ratio * $pValue); + if ($this->resizeProportional && $pValue != 0) { + $ratio = $this->width / $this->height; + $this->width = round($ratio * $pValue); } // Set height - $this->_height = $pValue; + $this->height = $pValue; return $this; } @@ -240,15 +232,15 @@ public function setHeight($pValue = 0) */ public function setWidthAndHeight($width = 0, $height = 0) { - $xratio = $width / $this->_width; - $yratio = $height / $this->_height; - if ($this->_resizeProportional && !($width == 0 || $height == 0)) { - if (($xratio * $this->_height) < $height) { - $this->_height = ceil($xratio * $this->_height); - $this->_width = $width; + $xratio = $width / $this->width; + $yratio = $height / $this->height; + if ($this->resizeProportional && !($width == 0 || $height == 0)) { + if (($xratio * $this->height) < $height) { + $this->height = ceil($xratio * $this->height); + $this->width = $width; } else { - $this->_width = ceil($yratio * $this->_width); - $this->_height = $height; + $this->width = ceil($yratio * $this->width); + $this->height = $height; } } return $this; @@ -261,7 +253,7 @@ public function setWidthAndHeight($width = 0, $height = 0) */ public function getResizeProportional() { - return $this->_resizeProportional; + return $this->resizeProportional; } /** @@ -272,7 +264,7 @@ public function getResizeProportional() */ public function setResizeProportional($pValue = true) { - $this->_resizeProportional = $pValue; + $this->resizeProportional = $pValue; return $this; } @@ -283,7 +275,7 @@ public function setResizeProportional($pValue = true) */ public function getFilename() { - return basename($this->_path); + return basename($this->path); } /** @@ -293,7 +285,7 @@ public function getFilename() */ public function getExtension() { - $parts = explode(".", basename($this->_path)); + $parts = explode(".", basename($this->path)); return end($parts); } @@ -304,7 +296,7 @@ public function getExtension() */ public function getPath() { - return $this->_path; + return $this->path; } /** @@ -319,17 +311,17 @@ public function setPath($pValue = '', $pVerifyFile = true) { if ($pVerifyFile) { if (file_exists($pValue)) { - $this->_path = $pValue; + $this->path = $pValue; - if ($this->_width == 0 && $this->_height == 0) { + if ($this->width == 0 && $this->height == 0) { // Get width/height - list($this->_width, $this->_height) = getimagesize($pValue); + list($this->width, $this->height) = getimagesize($pValue); } } else { throw new PHPExcel_Exception("File $pValue not found!"); } } else { - $this->_path = $pValue; + $this->path = $pValue; } return $this; } @@ -342,13 +334,13 @@ public function setPath($pValue = '', $pVerifyFile = true) public function getHashCode() { return md5( - $this->_path - . $this->_name - . $this->_offsetX - . $this->_offsetY - . $this->_width - . $this->_height - . __CLASS__ + $this->path . + $this->name . + $this->offsetX . + $this->offsetY . + $this->width . + $this->height . + __CLASS__ ); } diff --git a/Classes/PHPExcel/Worksheet/MemoryDrawing.php b/Classes/PHPExcel/Worksheet/MemoryDrawing.php index 04f8d1102..119a75208 100644 --- a/Classes/PHPExcel/Worksheet/MemoryDrawing.php +++ b/Classes/PHPExcel/Worksheet/MemoryDrawing.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Worksheet_MemoryDrawing * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,56 +25,47 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Worksheet_MemoryDrawing - * - * @category PHPExcel - * @package PHPExcel_Worksheet - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable { /* Rendering functions */ - const RENDERING_DEFAULT = 'imagepng'; - const RENDERING_PNG = 'imagepng'; - const RENDERING_GIF = 'imagegif'; - const RENDERING_JPEG = 'imagejpeg'; + const RENDERING_DEFAULT = 'imagepng'; + const RENDERING_PNG = 'imagepng'; + const RENDERING_GIF = 'imagegif'; + const RENDERING_JPEG = 'imagejpeg'; /* MIME types */ - const MIMETYPE_DEFAULT = 'image/png'; - const MIMETYPE_PNG = 'image/png'; - const MIMETYPE_GIF = 'image/gif'; - const MIMETYPE_JPEG = 'image/jpeg'; + const MIMETYPE_DEFAULT = 'image/png'; + const MIMETYPE_PNG = 'image/png'; + const MIMETYPE_GIF = 'image/gif'; + const MIMETYPE_JPEG = 'image/jpeg'; /** * Image resource * * @var resource */ - private $_imageResource; + private $imageResource; /** * Rendering function * * @var string */ - private $_renderingFunction; + private $renderingFunction; /** * Mime type * * @var string */ - private $_mimeType; + private $mimeType; /** * Unique name * * @var string */ - private $_uniqueName; + private $uniqueName; /** * Create a new PHPExcel_Worksheet_MemoryDrawing @@ -81,10 +73,10 @@ class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing im public function __construct() { // Initialise values - $this->_imageResource = null; - $this->_renderingFunction = self::RENDERING_DEFAULT; - $this->_mimeType = self::MIMETYPE_DEFAULT; - $this->_uniqueName = md5(rand(0, 9999). time() . rand(0, 9999)); + $this->imageResource = null; + $this->renderingFunction = self::RENDERING_DEFAULT; + $this->mimeType = self::MIMETYPE_DEFAULT; + $this->uniqueName = md5(rand(0, 9999). time() . rand(0, 9999)); // Initialize parent parent::__construct(); @@ -97,7 +89,7 @@ public function __construct() */ public function getImageResource() { - return $this->_imageResource; + return $this->imageResource; } /** @@ -108,12 +100,12 @@ public function getImageResource() */ public function setImageResource($value = null) { - $this->_imageResource = $value; + $this->imageResource = $value; - if (!is_null($this->_imageResource)) { + if (!is_null($this->imageResource)) { // Get width/height - $this->_width = imagesx($this->_imageResource); - $this->_height = imagesy($this->_imageResource); + $this->_width = imagesx($this->imageResource); + $this->_height = imagesy($this->imageResource); } return $this; } @@ -125,7 +117,7 @@ public function setImageResource($value = null) */ public function getRenderingFunction() { - return $this->_renderingFunction; + return $this->renderingFunction; } /** @@ -136,7 +128,7 @@ public function getRenderingFunction() */ public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT) { - $this->_renderingFunction = $value; + $this->renderingFunction = $value; return $this; } @@ -147,7 +139,7 @@ public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing:: */ public function getMimeType() { - return $this->_mimeType; + return $this->mimeType; } /** @@ -158,7 +150,7 @@ public function getMimeType() */ public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT) { - $this->_mimeType = $value; + $this->mimeType = $value; return $this; } @@ -169,11 +161,11 @@ public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_ */ public function getIndexedFilename() { - $extension = strtolower($this->getMimeType()); - $extension = explode('/', $extension); - $extension = $extension[1]; + $extension = strtolower($this->getMimeType()); + $extension = explode('/', $extension); + $extension = $extension[1]; - return $this->_uniqueName . $this->getImageIndex() . '.' . $extension; + return $this->uniqueName . $this->getImageIndex() . '.' . $extension; } /** @@ -184,11 +176,11 @@ public function getIndexedFilename() public function getHashCode() { return md5( - $this->_renderingFunction - . $this->_mimeType - . $this->_uniqueName - . parent::getHashCode() - . __CLASS__ + $this->renderingFunction . + $this->mimeType . + $this->uniqueName . + parent::getHashCode() . + __CLASS__ ); } diff --git a/Classes/PHPExcel/Worksheet/PageSetup.php b/Classes/PHPExcel/Worksheet/PageSetup.php index 1e9df19ef..c67053e6b 100644 --- a/Classes/PHPExcel/Worksheet/PageSetup.php +++ b/Classes/PHPExcel/Worksheet/PageSetup.php @@ -189,14 +189,14 @@ class PHPExcel_Worksheet_PageSetup * * @var int */ - private $_paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER; + private $paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER; /** * Orientation * * @var string */ - private $_orientation = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT; + private $orientation = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT; /** * Scale (Print Scale) @@ -206,7 +206,7 @@ class PHPExcel_Worksheet_PageSetup * * @var int? */ - private $_scale = 100; + private $scale = 100; /** * Fit To Page @@ -214,7 +214,7 @@ class PHPExcel_Worksheet_PageSetup * * @var boolean */ - private $_fitToPage = false; + private $fitToPage = false; /** * Fit To Height @@ -222,7 +222,7 @@ class PHPExcel_Worksheet_PageSetup * * @var int? */ - private $_fitToHeight = 1; + private $fitToHeight = 1; /** * Fit To Width @@ -230,49 +230,49 @@ class PHPExcel_Worksheet_PageSetup * * @var int? */ - private $_fitToWidth = 1; + private $fitToWidth = 1; /** * Columns to repeat at left * * @var array Containing start column and end column, empty array if option unset */ - private $_columnsToRepeatAtLeft = array('', ''); + private $columnsToRepeatAtLeft = array('', ''); /** * Rows to repeat at top * * @var array Containing start row number and end row number, empty array if option unset */ - private $_rowsToRepeatAtTop = array(0, 0); + private $rowsToRepeatAtTop = array(0, 0); /** * Center page horizontally * * @var boolean */ - private $_horizontalCentered = false; + private $horizontalCentered = false; /** * Center page vertically * * @var boolean */ - private $_verticalCentered = false; + private $verticalCentered = false; /** * Print area * * @var string */ - private $_printArea = null; + private $printArea = null; /** * First page number * * @var int */ - private $_firstPageNumber = null; + private $firstPageNumber = null; /** * Create a new PHPExcel_Worksheet_PageSetup @@ -288,7 +288,7 @@ public function __construct() */ public function getPaperSize() { - return $this->_paperSize; + return $this->paperSize; } /** @@ -299,7 +299,7 @@ public function getPaperSize() */ public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) { - $this->_paperSize = $pValue; + $this->paperSize = $pValue; return $this; } @@ -310,7 +310,7 @@ public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_L */ public function getOrientation() { - return $this->_orientation; + return $this->orientation; } /** @@ -321,7 +321,7 @@ public function getOrientation() */ public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) { - $this->_orientation = $pValue; + $this->orientation = $pValue; return $this; } @@ -332,7 +332,7 @@ public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATI */ public function getScale() { - return $this->_scale; + return $this->scale; } /** @@ -351,9 +351,9 @@ public function setScale($pValue = 100, $pUpdate = true) // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, // but it is apparently still able to handle any scale >= 0, where 0 results in 100 if (($pValue >= 0) || is_null($pValue)) { - $this->_scale = $pValue; + $this->scale = $pValue; if ($pUpdate) { - $this->_fitToPage = false; + $this->fitToPage = false; } } else { throw new PHPExcel_Exception("Scale must not be negative"); @@ -368,7 +368,7 @@ public function setScale($pValue = 100, $pUpdate = true) */ public function getFitToPage() { - return $this->_fitToPage; + return $this->fitToPage; } /** @@ -379,7 +379,7 @@ public function getFitToPage() */ public function setFitToPage($pValue = true) { - $this->_fitToPage = $pValue; + $this->fitToPage = $pValue; return $this; } @@ -390,7 +390,7 @@ public function setFitToPage($pValue = true) */ public function getFitToHeight() { - return $this->_fitToHeight; + return $this->fitToHeight; } /** @@ -402,9 +402,9 @@ public function getFitToHeight() */ public function setFitToHeight($pValue = 1, $pUpdate = true) { - $this->_fitToHeight = $pValue; + $this->fitToHeight = $pValue; if ($pUpdate) { - $this->_fitToPage = true; + $this->fitToPage = true; } return $this; } @@ -416,7 +416,7 @@ public function setFitToHeight($pValue = 1, $pUpdate = true) */ public function getFitToWidth() { - return $this->_fitToWidth; + return $this->fitToWidth; } /** @@ -428,9 +428,9 @@ public function getFitToWidth() */ public function setFitToWidth($pValue = 1, $pUpdate = true) { - $this->_fitToWidth = $pValue; + $this->fitToWidth = $pValue; if ($pUpdate) { - $this->_fitToPage = true; + $this->fitToPage = true; } return $this; } @@ -442,8 +442,8 @@ public function setFitToWidth($pValue = 1, $pUpdate = true) */ public function isColumnsToRepeatAtLeftSet() { - if (is_array($this->_columnsToRepeatAtLeft)) { - if ($this->_columnsToRepeatAtLeft[0] != '' && $this->_columnsToRepeatAtLeft[1] != '') { + if (is_array($this->columnsToRepeatAtLeft)) { + if ($this->columnsToRepeatAtLeft[0] != '' && $this->columnsToRepeatAtLeft[1] != '') { return true; } } @@ -458,7 +458,7 @@ public function isColumnsToRepeatAtLeftSet() */ public function getColumnsToRepeatAtLeft() { - return $this->_columnsToRepeatAtLeft; + return $this->columnsToRepeatAtLeft; } /** @@ -470,7 +470,7 @@ public function getColumnsToRepeatAtLeft() public function setColumnsToRepeatAtLeft($pValue = null) { if (is_array($pValue)) { - $this->_columnsToRepeatAtLeft = $pValue; + $this->columnsToRepeatAtLeft = $pValue; } return $this; } @@ -484,7 +484,7 @@ public function setColumnsToRepeatAtLeft($pValue = null) */ public function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A') { - $this->_columnsToRepeatAtLeft = array($pStart, $pEnd); + $this->columnsToRepeatAtLeft = array($pStart, $pEnd); return $this; } @@ -495,8 +495,8 @@ public function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A' */ public function isRowsToRepeatAtTopSet() { - if (is_array($this->_rowsToRepeatAtTop)) { - if ($this->_rowsToRepeatAtTop[0] != 0 && $this->_rowsToRepeatAtTop[1] != 0) { + if (is_array($this->rowsToRepeatAtTop)) { + if ($this->rowsToRepeatAtTop[0] != 0 && $this->rowsToRepeatAtTop[1] != 0) { return true; } } @@ -511,7 +511,7 @@ public function isRowsToRepeatAtTopSet() */ public function getRowsToRepeatAtTop() { - return $this->_rowsToRepeatAtTop; + return $this->rowsToRepeatAtTop; } /** @@ -523,7 +523,7 @@ public function getRowsToRepeatAtTop() public function setRowsToRepeatAtTop($pValue = null) { if (is_array($pValue)) { - $this->_rowsToRepeatAtTop = $pValue; + $this->rowsToRepeatAtTop = $pValue; } return $this; } @@ -537,7 +537,7 @@ public function setRowsToRepeatAtTop($pValue = null) */ public function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1) { - $this->_rowsToRepeatAtTop = array($pStart, $pEnd); + $this->rowsToRepeatAtTop = array($pStart, $pEnd); return $this; } @@ -548,7 +548,7 @@ public function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1) */ public function getHorizontalCentered() { - return $this->_horizontalCentered; + return $this->horizontalCentered; } /** @@ -559,7 +559,7 @@ public function getHorizontalCentered() */ public function setHorizontalCentered($value = false) { - $this->_horizontalCentered = $value; + $this->horizontalCentered = $value; return $this; } @@ -570,7 +570,7 @@ public function setHorizontalCentered($value = false) */ public function getVerticalCentered() { - return $this->_verticalCentered; + return $this->verticalCentered; } /** @@ -581,7 +581,7 @@ public function getVerticalCentered() */ public function setVerticalCentered($value = false) { - $this->_verticalCentered = $value; + $this->verticalCentered = $value; return $this; } @@ -598,9 +598,9 @@ public function setVerticalCentered($value = false) public function getPrintArea($index = 0) { if ($index == 0) { - return $this->_printArea; + return $this->printArea; } - $printAreas = explode(',', $this->_printArea); + $printAreas = explode(',', $this->printArea); if (isset($printAreas[$index-1])) { return $printAreas[$index-1]; } @@ -619,9 +619,9 @@ public function getPrintArea($index = 0) public function isPrintAreaSet($index = 0) { if ($index == 0) { - return !is_null($this->_printArea); + return !is_null($this->printArea); } - $printAreas = explode(',', $this->_printArea); + $printAreas = explode(',', $this->printArea); return isset($printAreas[$index-1]); } @@ -637,12 +637,12 @@ public function isPrintAreaSet($index = 0) public function clearPrintArea($index = 0) { if ($index == 0) { - $this->_printArea = null; + $this->printArea = null; } else { - $printAreas = explode(',', $this->_printArea); + $printAreas = explode(',', $this->printArea); if (isset($printAreas[$index-1])) { unset($printAreas[$index-1]); - $this->_printArea = implode(',', $printAreas); + $this->printArea = implode(',', $printAreas); } } @@ -682,9 +682,9 @@ public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_O if ($method == self::SETPRINTRANGE_OVERWRITE) { if ($index == 0) { - $this->_printArea = $value; + $this->printArea = $value; } else { - $printAreas = explode(',', $this->_printArea); + $printAreas = explode(',', $this->printArea); if ($index < 0) { $index = count($printAreas) - abs($index) + 1; } @@ -692,13 +692,13 @@ public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_O throw new PHPExcel_Exception('Invalid index for setting print range.'); } $printAreas[$index-1] = $value; - $this->_printArea = implode(',', $printAreas); + $this->printArea = implode(',', $printAreas); } } elseif ($method == self::SETPRINTRANGE_INSERT) { if ($index == 0) { - $this->_printArea .= ($this->_printArea == '') ? $value : ','.$value; + $this->printArea .= ($this->printArea == '') ? $value : ','.$value; } else { - $printAreas = explode(',', $this->_printArea); + $printAreas = explode(',', $this->printArea); if ($index < 0) { $index = abs($index) - 1; } @@ -706,7 +706,7 @@ public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_O throw new PHPExcel_Exception('Invalid index for setting print range.'); } $printAreas = array_merge(array_slice($printAreas, 0, $index), array($value), array_slice($printAreas, $index)); - $this->_printArea = implode(',', $printAreas); + $this->printArea = implode(',', $printAreas); } } else { throw new PHPExcel_Exception('Invalid method for setting print range.'); @@ -758,7 +758,11 @@ public function addPrintArea($value, $index = -1) */ public function setPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) { - return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, $method); + return $this->setPrintArea( + PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, + $index, + $method + ); } /** @@ -779,7 +783,11 @@ public function setPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $in */ public function addPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = -1) { - return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, self::SETPRINTRANGE_INSERT); + return $this->setPrintArea( + PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, + $index, + self::SETPRINTRANGE_INSERT + ); } /** @@ -789,7 +797,7 @@ public function addPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $in */ public function getFirstPageNumber() { - return $this->_firstPageNumber; + return $this->firstPageNumber; } /** @@ -800,7 +808,7 @@ public function getFirstPageNumber() */ public function setFirstPageNumber($value = null) { - $this->_firstPageNumber = $value; + $this->firstPageNumber = $value; return $this; } diff --git a/Classes/PHPExcel/Writer/Abstract.php b/Classes/PHPExcel/Writer/Abstract.php index a0f141002..e6e130de0 100644 --- a/Classes/PHPExcel/Writer/Abstract.php +++ b/Classes/PHPExcel/Writer/Abstract.php @@ -33,7 +33,7 @@ abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter * * @var boolean */ - protected $_includeCharts = false; + protected $includeCharts = false; /** * Pre-calculate formulas @@ -67,7 +67,7 @@ abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter */ public function getIncludeCharts() { - return $this->_includeCharts; + return $this->includeCharts; } /** @@ -80,7 +80,7 @@ public function getIncludeCharts() */ public function setIncludeCharts($pValue = false) { - $this->_includeCharts = (boolean) $pValue; + $this->includeCharts = (boolean) $pValue; return $this; } diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index 1b2410187..5b812cc1e 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -236,7 +236,7 @@ public function save($pFilename = null) } // Add [Content_Types].xml to ZIP file - $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->_includeCharts)); + $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->includeCharts)); //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) if ($this->_spreadSheet->hasMacros()) { @@ -292,8 +292,8 @@ public function save($pFilename = null) $chartCount = 0; // Add worksheets for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { - $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->_spreadSheet->getSheet($i), $this->_stringTable, $this->_includeCharts)); - if ($this->_includeCharts) { + $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->_spreadSheet->getSheet($i), $this->_stringTable, $this->includeCharts)); + if ($this->includeCharts) { $charts = $this->_spreadSheet->getSheet($i)->getChartCollection(); if (count($charts) > 0) { foreach ($charts as $chart) { @@ -308,21 +308,21 @@ public function save($pFilename = null) // Add worksheet relationships (drawings, ...) for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { // Add relationships - $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->_spreadSheet->getSheet($i), ($i + 1), $this->_includeCharts)); + $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->_spreadSheet->getSheet($i), ($i + 1), $this->includeCharts)); $drawings = $this->_spreadSheet->getSheet($i)->getDrawingCollection(); $drawingCount = count($drawings); - if ($this->_includeCharts) { + if ($this->includeCharts) { $chartCount = $this->_spreadSheet->getSheet($i)->getChartCount(); } // Add drawing and image relationship parts if (($drawingCount > 0) || ($chartCount > 0)) { // Drawing relationships - $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->_spreadSheet->getSheet($i), $chartRef1, $this->_includeCharts)); + $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->_spreadSheet->getSheet($i), $chartRef1, $this->includeCharts)); // Drawings - $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->_spreadSheet->getSheet($i), $chartRef2, $this->_includeCharts)); + $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->_spreadSheet->getSheet($i), $chartRef2, $this->includeCharts)); } // Add comment relationship parts diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index eecc6ec69..746ec55db 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -32,98 +32,98 @@ class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_ * * @var PHPExcel */ - protected $_phpExcel; + protected $phpExcel; /** * Sheet index to write * * @var int */ - private $_sheetIndex = 0; + private $sheetIndex = 0; /** * Images root * * @var string */ - private $_imagesRoot = '.'; + private $imagesRoot = '.'; /** * embed images, or link to images * * @var boolean */ - private $_embedImages = false; + private $embedImages = false; /** * Use inline CSS? * * @var boolean */ - private $_useInlineCss = false; + private $useInlineCss = false; /** * Array of CSS styles * * @var array */ - private $_cssStyles = null; + private $cssStyles; /** * Array of column widths in points * * @var array */ - private $_columnWidths = null; + private $columnWidths; /** * Default font * * @var PHPExcel_Style_Font */ - private $_defaultFont; + private $defaultFont; /** * Flag whether spans have been calculated * * @var boolean */ - private $_spansAreCalculated = false; + private $spansAreCalculated = false; /** * Excel cells that should not be written as HTML cells * * @var array */ - private $_isSpannedCell = array(); + private $isSpannedCell = array(); /** * Excel cells that are upper-left corner in a cell merge * * @var array */ - private $_isBaseCell = array(); + private $isBaseCell = array(); /** * Excel rows that should not be written as HTML rows * * @var array */ - private $_isSpannedRow = array(); + private $isSpannedRow = array(); /** * Is the current writer creating PDF? * * @var boolean */ - protected $_isPdf = false; + protected $isPdf = false; /** * Generate the Navigation block * * @var boolean */ - private $_generateSheetNavigationBlock = true; + private $generateSheetNavigationBlock = true; /** * Create a new PHPExcel_Writer_HTML @@ -132,8 +132,8 @@ class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_ */ public function __construct(PHPExcel $phpExcel) { - $this->_phpExcel = $phpExcel; - $this->_defaultFont = $this->_phpExcel->getDefaultStyle()->getFont(); + $this->phpExcel = $phpExcel; + $this->defaultFont = $this->phpExcel->getDefaultStyle()->getFont(); } /** @@ -145,15 +145,15 @@ public function __construct(PHPExcel $phpExcel) public function save($pFilename = null) { // garbage collect - $this->_phpExcel->garbageCollect(); + $this->phpExcel->garbageCollect(); - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(false); + $saveDebugLog = PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog(false); $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); // Build CSS - $this->buildCSS(!$this->_useInlineCss); + $this->buildCSS(!$this->useInlineCss); // Open file $fileHandle = fopen($pFilename, 'wb+'); @@ -162,10 +162,10 @@ public function save($pFilename = null) } // Write headers - fwrite($fileHandle, $this->generateHTMLHeader(!$this->_useInlineCss)); + fwrite($fileHandle, $this->generateHTMLHeader(!$this->useInlineCss)); // Write navigation (tabs) - if ((!$this->_isPdf) && ($this->_generateSheetNavigationBlock)) { + if ((!$this->isPdf) && ($this->generateSheetNavigationBlock)) { fwrite($fileHandle, $this->generateNavigation()); } @@ -179,7 +179,7 @@ public function save($pFilename = null) fclose($fileHandle); PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); - PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); } /** @@ -188,7 +188,7 @@ public function save($pFilename = null) * @param string $vAlign Vertical alignment * @return string */ - private function _mapVAlign($vAlign) + private function mapVAlign($vAlign) { switch ($vAlign) { case PHPExcel_Style_Alignment::VERTICAL_BOTTOM: @@ -209,7 +209,7 @@ private function _mapVAlign($vAlign) * @param string $hAlign Horizontal alignment * @return string|false */ - private function _mapHAlign($hAlign) + private function mapHAlign($hAlign) { switch ($hAlign) { case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL: @@ -234,7 +234,7 @@ private function _mapHAlign($hAlign) * @param int $borderStyle Sheet index * @return string */ - private function _mapBorderStyle($borderStyle) + private function mapBorderStyle($borderStyle) { switch ($borderStyle) { case PHPExcel_Style_Border::BORDER_NONE: @@ -278,7 +278,7 @@ private function _mapBorderStyle($borderStyle) */ public function getSheetIndex() { - return $this->_sheetIndex; + return $this->sheetIndex; } /** @@ -289,7 +289,7 @@ public function getSheetIndex() */ public function setSheetIndex($pValue = 0) { - $this->_sheetIndex = $pValue; + $this->sheetIndex = $pValue; return $this; } @@ -300,7 +300,7 @@ public function setSheetIndex($pValue = 0) */ public function getGenerateSheetNavigationBlock() { - return $this->_generateSheetNavigationBlock; + return $this->generateSheetNavigationBlock; } /** @@ -311,7 +311,7 @@ public function getGenerateSheetNavigationBlock() */ public function setGenerateSheetNavigationBlock($pValue = true) { - $this->_generateSheetNavigationBlock = (bool) $pValue; + $this->generateSheetNavigationBlock = (bool) $pValue; return $this; } @@ -320,7 +320,7 @@ public function setGenerateSheetNavigationBlock($pValue = true) */ public function writeAllSheets() { - $this->_sheetIndex = null; + $this->sheetIndex = null; return $this; } @@ -334,12 +334,12 @@ public function writeAllSheets() public function generateHTMLHeader($pIncludeStyles = false) { // PHPExcel object known? - if (is_null($this->_phpExcel)) { + if (is_null($this->phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); } // Construct HTML - $properties = $this->_phpExcel->getProperties(); + $properties = $this->phpExcel->getProperties(); $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' . PHP_EOL; $html .= '<!-- Generated by PHPExcel - http://www.phpexcel.net -->' . PHP_EOL; $html .= '<html>' . PHP_EOL; @@ -393,21 +393,21 @@ public function generateHTMLHeader($pIncludeStyles = false) public function generateSheetData() { // PHPExcel object known? - if (is_null($this->_phpExcel)) { + if (is_null($this->phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); } // Ensure that Spans have been calculated? - if (!$this->_spansAreCalculated) { - $this->_calculateSpans(); + if (!$this->spansAreCalculated) { + $this->calculateSpans(); } // Fetch sheets $sheets = array(); - if (is_null($this->_sheetIndex)) { - $sheets = $this->_phpExcel->getAllSheets(); + if (is_null($this->sheetIndex)) { + $sheets = $this->phpExcel->getAllSheets(); } else { - $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + $sheets[] = $this->phpExcel->getSheet($this->sheetIndex); } // Construct HTML @@ -417,7 +417,7 @@ public function generateSheetData() $sheetId = 0; foreach ($sheets as $sheet) { // Write table header - $html .= $this->_generateTableHeader($sheet); + $html .= $this->generateTableHeader($sheet); // Get worksheet dimension $dimension = explode(':', $sheet->calculateWorksheetDimension()); @@ -460,7 +460,7 @@ public function generateSheetData() } // Write row if there are HTML table cells in it - if (!isset($this->_isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row])) { + if (!isset($this->isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row])) { // Start a new rowData $rowData = array(); // Loop through columns @@ -473,7 +473,7 @@ public function generateSheetData() $rowData[$column] = ''; } } - $html .= $this->_generateRow($sheet, $rowData, $row - 1, $cellType); + $html .= $this->generateRow($sheet, $rowData, $row - 1, $cellType); } // </thead> ? @@ -481,17 +481,17 @@ public function generateSheetData() $html .= ' </thead>' . PHP_EOL; } } - $html .= $this->_extendRowsForChartsAndImages($sheet, $row); + $html .= $this->extendRowsForChartsAndImages($sheet, $row); // Close table body. $html .= ' </tbody>' . PHP_EOL; // Write table footer - $html .= $this->_generateTableFooter(); + $html .= $this->generateTableFooter(); // Writing PDF? - if ($this->_isPdf) { - if (is_null($this->_sheetIndex) && $sheetId + 1 < $this->_phpExcel->getSheetCount()) { + if ($this->isPdf) { + if (is_null($this->sheetIndex) && $sheetId + 1 < $this->phpExcel->getSheetCount()) { $html .= '<div style="page-break-before:always" />'; } } @@ -512,16 +512,16 @@ public function generateSheetData() public function generateNavigation() { // PHPExcel object known? - if (is_null($this->_phpExcel)) { + if (is_null($this->phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); } // Fetch sheets $sheets = array(); - if (is_null($this->_sheetIndex)) { - $sheets = $this->_phpExcel->getAllSheets(); + if (is_null($this->sheetIndex)) { + $sheets = $this->phpExcel->getAllSheets(); } else { - $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + $sheets[] = $this->phpExcel->getSheet($this->sheetIndex); } // Construct HTML @@ -545,11 +545,11 @@ public function generateNavigation() return $html; } - private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) + private function extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) { $rowMax = $row; $colMax = 'A'; - if ($this->_includeCharts) { + if ($this->includeCharts) { foreach ($pSheet->getChartCollection() as $chart) { if ($chart instanceof PHPExcel_Chart) { $chartCoordinates = $chart->getTopLeftPosition(); @@ -583,9 +583,9 @@ private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) $html .= '<tr>'; for ($col = 'A'; $col != $colMax; ++$col) { $html .= '<td>'; - $html .= $this->_writeImageInCell($pSheet, $col.$row); - if ($this->_includeCharts) { - $html .= $this->_writeChartInCell($pSheet, $col.$row); + $html .= $this->writeImageInCell($pSheet, $col.$row); + if ($this->includeCharts) { + $html .= $this->writeChartInCell($pSheet, $col.$row); } $html .= '</td>'; } @@ -604,7 +604,7 @@ private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) * @return string * @throws PHPExcel_Writer_Exception */ - private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) + private function writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { // Construct HTML $html = ''; @@ -632,7 +632,7 @@ private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) $filename = htmlspecialchars($filename); $html .= PHP_EOL; - if ((!$this->_embedImages) || ($this->_isPdf)) { + if ((!$this->embedImages) || ($this->isPdf)) { $imageData = $filename; } else { $imageDetails = getimagesize($filename); @@ -669,7 +669,7 @@ private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) * @return string * @throws PHPExcel_Writer_Exception */ - private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) + private function writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) { // Construct HTML $html = ''; @@ -718,7 +718,7 @@ private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) public function generateStyles($generateSurroundingHTML = true) { // PHPExcel object known? - if (is_null($this->_phpExcel)) { + if (is_null($this->phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); } @@ -731,13 +731,13 @@ public function generateStyles($generateSurroundingHTML = true) // Start styles if ($generateSurroundingHTML) { $html .= ' <style type="text/css">' . PHP_EOL; - $html .= ' html { ' . $this->_assembleCSS($css['html']) . ' }' . PHP_EOL; + $html .= ' html { ' . $this->assembleCSS($css['html']) . ' }' . PHP_EOL; } // Write all other styles foreach ($css as $styleName => $styleDefinition) { if ($styleName != 'html') { - $html .= ' ' . $styleName . ' { ' . $this->_assembleCSS($styleDefinition) . ' }' . PHP_EOL; + $html .= ' ' . $styleName . ' { ' . $this->assembleCSS($styleDefinition) . ' }' . PHP_EOL; } } @@ -760,18 +760,18 @@ public function generateStyles($generateSurroundingHTML = true) public function buildCSS($generateSurroundingHTML = true) { // PHPExcel object known? - if (is_null($this->_phpExcel)) { + if (is_null($this->phpExcel)) { throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); } // Cached? - if (!is_null($this->_cssStyles)) { - return $this->_cssStyles; + if (!is_null($this->cssStyles)) { + return $this->cssStyles; } // Ensure that spans have been calculated - if (!$this->_spansAreCalculated) { - $this->_calculateSpans(); + if (!$this->spansAreCalculated) { + $this->calculateSpans(); } // Construct CSS @@ -788,7 +788,7 @@ public function buildCSS($generateSurroundingHTML = true) // table { } $css['table']['border-collapse'] = 'collapse'; - if (!$this->_isPdf) { + if (!$this->isPdf) { $css['table']['page-break-after'] = 'always'; } @@ -815,17 +815,17 @@ public function buildCSS($generateSurroundingHTML = true) $css['.s']['text-align'] = 'left'; // STRING // Calculate cell style hashes - foreach ($this->_phpExcel->getCellXfCollection() as $index => $style) { - $css['td.style' . $index] = $this->_createCSSStyle($style); - $css['th.style' . $index] = $this->_createCSSStyle($style); + foreach ($this->phpExcel->getCellXfCollection() as $index => $style) { + $css['td.style' . $index] = $this->createCSSStyle($style); + $css['th.style' . $index] = $this->createCSSStyle($style); } // Fetch sheets $sheets = array(); - if (is_null($this->_sheetIndex)) { - $sheets = $this->_phpExcel->getAllSheets(); + if (is_null($this->sheetIndex)) { + $sheets = $this->phpExcel->getAllSheets(); } else { - $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + $sheets[] = $this->phpExcel->getSheet($this->sheetIndex); } // Build styles per sheet @@ -841,16 +841,16 @@ public function buildCSS($generateSurroundingHTML = true) $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()) - 1; $column = -1; while ($column++ < $highestColumnIndex) { - $this->_columnWidths[$sheetIndex][$column] = 42; // approximation + $this->columnWidths[$sheetIndex][$column] = 42; // approximation $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = '42pt'; } // col elements, loop through columnDimensions and set width foreach ($sheet->getColumnDimensions() as $columnDimension) { - if (($width = PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth(), $this->_defaultFont)) >= 0) { + if (($width = PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth(), $this->defaultFont)) >= 0) { $width = PHPExcel_Shared_Drawing::pixelsToPoints($width); $column = PHPExcel_Cell::columnIndexFromString($columnDimension->getColumnIndex()) - 1; - $this->_columnWidths[$sheetIndex][$column] = $width; + $this->columnWidths[$sheetIndex][$column] = $width; $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = $width . 'pt'; if ($columnDimension->getVisible() === false) { @@ -867,7 +867,7 @@ public function buildCSS($generateSurroundingHTML = true) $css['table.sheet' . $sheetIndex . ' tr'] = array(); if ($rowDimension->getRowHeight() == -1) { - $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont()); + $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->phpExcel->getDefaultStyle()->getFont()); } else { $pt_height = $rowDimension->getRowHeight(); } @@ -885,7 +885,7 @@ public function buildCSS($generateSurroundingHTML = true) $css['table.sheet' . $sheetIndex . ' tr.row' . $row] = array(); if ($rowDimension->getRowHeight() == -1) { - $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont()); + $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->phpExcel->getDefaultStyle()->getFont()); } else { $pt_height = $rowDimension->getRowHeight(); } @@ -898,8 +898,8 @@ public function buildCSS($generateSurroundingHTML = true) } // Cache - if (is_null($this->_cssStyles)) { - $this->_cssStyles = $css; + if (is_null($this->cssStyles)) { + $this->cssStyles = $css; } // Return @@ -912,17 +912,17 @@ public function buildCSS($generateSurroundingHTML = true) * @param PHPExcel_Style $pStyle PHPExcel_Style * @return array */ - private function _createCSSStyle(PHPExcel_Style $pStyle) + private function createCSSStyle(PHPExcel_Style $pStyle) { // Construct CSS $css = ''; // Create CSS $css = array_merge( - $this->_createCSSStyleAlignment($pStyle->getAlignment()), - $this->_createCSSStyleBorders($pStyle->getBorders()), - $this->_createCSSStyleFont($pStyle->getFont()), - $this->_createCSSStyleFill($pStyle->getFill()) + $this->createCSSStyleAlignment($pStyle->getAlignment()), + $this->createCSSStyleBorders($pStyle->getBorders()), + $this->createCSSStyleFont($pStyle->getFont()), + $this->createCSSStyleFill($pStyle->getFill()) ); // Return @@ -935,14 +935,14 @@ private function _createCSSStyle(PHPExcel_Style $pStyle) * @param PHPExcel_Style_Alignment $pStyle PHPExcel_Style_Alignment * @return array */ - private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) + private function createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) { // Construct CSS $css = array(); // Create CSS - $css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical()); - if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) { + $css['vertical-align'] = $this->mapVAlign($pStyle->getVertical()); + if ($textAlign = $this->mapHAlign($pStyle->getHorizontal())) { $css['text-align'] = $textAlign; if (in_array($textAlign, array('left', 'right'))) { $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px'; @@ -958,7 +958,7 @@ private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) * @param PHPExcel_Style_Font $pStyle PHPExcel_Style_Font * @return array */ - private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) + private function createCSSStyleFont(PHPExcel_Style_Font $pStyle) { // Construct CSS $css = array(); @@ -991,16 +991,16 @@ private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) * @param PHPExcel_Style_Borders $pStyle PHPExcel_Style_Borders * @return array */ - private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) + private function createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) { // Construct CSS $css = array(); // Create CSS - $css['border-bottom'] = $this->_createCSSStyleBorder($pStyle->getBottom()); - $css['border-top'] = $this->_createCSSStyleBorder($pStyle->getTop()); - $css['border-left'] = $this->_createCSSStyleBorder($pStyle->getLeft()); - $css['border-right'] = $this->_createCSSStyleBorder($pStyle->getRight()); + $css['border-bottom'] = $this->createCSSStyleBorder($pStyle->getBottom()); + $css['border-top'] = $this->createCSSStyleBorder($pStyle->getTop()); + $css['border-left'] = $this->createCSSStyleBorder($pStyle->getLeft()); + $css['border-right'] = $this->createCSSStyleBorder($pStyle->getRight()); return $css; } @@ -1011,12 +1011,12 @@ private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) * @param PHPExcel_Style_Border $pStyle PHPExcel_Style_Border * @return string */ - private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) + private function createCSSStyleBorder(PHPExcel_Style_Border $pStyle) { // Create CSS -// $css = $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); +// $css = $this->mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); // Create CSS - add !important to non-none border styles for merged cells - $borderStyle = $this->_mapBorderStyle($pStyle->getBorderStyle()); + $borderStyle = $this->mapBorderStyle($pStyle->getBorderStyle()); $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); return $css; @@ -1028,7 +1028,7 @@ private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) * @param PHPExcel_Style_Fill $pStyle PHPExcel_Style_Fill * @return array */ - private function _createCSSStyleFill(PHPExcel_Style_Fill $pStyle) + private function createCSSStyleFill(PHPExcel_Style_Fill $pStyle) { // Construct HTML $css = array(); @@ -1061,22 +1061,22 @@ public function generateHTMLFooter() * @return string * @throws PHPExcel_Writer_Exception */ - private function _generateTableHeader($pSheet) + private function generateTableHeader($pSheet) { $sheetIndex = $pSheet->getParent()->getIndex($pSheet); // Construct HTML $html = ''; - $html .= $this->_setMargins($pSheet); + $html .= $this->setMargins($pSheet); - if (!$this->_useInlineCss) { + if (!$this->useInlineCss) { $gridlines = $pSheet->getShowGridlines() ? ' gridlines' : ''; $html .= ' <table border="0" cellpadding="0" cellspacing="0" id="sheet' . $sheetIndex . '" class="sheet' . $sheetIndex . $gridlines . '">' . PHP_EOL; } else { - $style = isset($this->_cssStyles['table']) ? - $this->_assembleCSS($this->_cssStyles['table']) : ''; + $style = isset($this->cssStyles['table']) ? + $this->assembleCSS($this->cssStyles['table']) : ''; - if ($this->_isPdf && $pSheet->getShowGridlines()) { + if ($this->isPdf && $pSheet->getShowGridlines()) { $html .= ' <table border="1" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="1" style="' . $style . '">' . PHP_EOL; } else { $html .= ' <table border="0" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="0" style="' . $style . '">' . PHP_EOL; @@ -1087,12 +1087,12 @@ private function _generateTableHeader($pSheet) $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()) - 1; $i = -1; while ($i++ < $highestColumnIndex) { - if (!$this->_isPdf) { - if (!$this->_useInlineCss) { + if (!$this->isPdf) { + if (!$this->useInlineCss) { $html .= ' <col class="col' . $i . '">' . PHP_EOL; } else { - $style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) ? - $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) : ''; + $style = isset($this->cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) ? + $this->assembleCSS($this->cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) : ''; $html .= ' <col style="' . $style . '">' . PHP_EOL; } } @@ -1106,7 +1106,7 @@ private function _generateTableHeader($pSheet) * * @throws PHPExcel_Writer_Exception */ - private function _generateTableFooter() + private function generateTableFooter() { $html = ' </table>' . PHP_EOL; @@ -1122,7 +1122,7 @@ private function _generateTableFooter() * @return string * @throws PHPExcel_Writer_Exception */ - private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td') + private function generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td') { if (is_array($pValues)) { // Construct HTML @@ -1132,28 +1132,28 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow $sheetIndex = $pSheet->getParent()->getIndex($pSheet); // DomPDF and breaks - if ($this->_isPdf && count($pSheet->getBreaks()) > 0) { + if ($this->isPdf && count($pSheet->getBreaks()) > 0) { $breaks = $pSheet->getBreaks(); // check if a break is needed before this row if (isset($breaks['A' . $pRow])) { // close table: </table> - $html .= $this->_generateTableFooter(); + $html .= $this->generateTableFooter(); // insert page break $html .= '<div style="page-break-before:always" />'; // open table again: <table> + <col> etc. - $html .= $this->_generateTableHeader($pSheet); + $html .= $this->generateTableHeader($pSheet); } } // Write row start - if (!$this->_useInlineCss) { + if (!$this->useInlineCss) { $html .= ' <tr class="row' . $pRow . '">' . PHP_EOL; } else { - $style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) - ? $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : ''; + $style = isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) + ? $this->assembleCSS($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : ''; $html .= ' <tr style="' . $style . '">' . PHP_EOL; } @@ -1163,18 +1163,18 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow foreach ($pValues as $cellAddress) { $cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : ''; $coordinate = PHPExcel_Cell::stringFromColumnIndex($colNum) . ($pRow + 1); - if (!$this->_useInlineCss) { + if (!$this->useInlineCss) { $cssClass = ''; $cssClass = 'column' . $colNum; } else { $cssClass = array(); if ($cellType == 'th') { - if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum])) { - $this->_cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum]; + if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum])) { + $this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum]; } } else { - if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) { - $this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum]; + if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) { + $this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum]; } } } @@ -1197,7 +1197,7 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow foreach ($elements as $element) { // Rich text start? if ($element instanceof PHPExcel_RichText_Run) { - $cellData .= '<span style="' . $this->_assembleCSS($this->_createCSSStyleFont($element->getFont())) . '">'; + $cellData .= '<span style="' . $this->assembleCSS($this->createCSSStyleFont($element->getFont())) . '">'; if ($element->getFont()->getSuperScript()) { $cellData .= '<sup>'; @@ -1250,25 +1250,25 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow $cellData = nl2br($cellData); // Extend CSS class? - if (!$this->_useInlineCss) { + if (!$this->useInlineCss) { $cssClass .= ' style' . $cell->getXfIndex(); $cssClass .= ' ' . $cell->getDataType(); } else { if ($cellType == 'th') { - if (isset($this->_cssStyles['th.style' . $cell->getXfIndex()])) { - $cssClass = array_merge($cssClass, $this->_cssStyles['th.style' . $cell->getXfIndex()]); + if (isset($this->cssStyles['th.style' . $cell->getXfIndex()])) { + $cssClass = array_merge($cssClass, $this->cssStyles['th.style' . $cell->getXfIndex()]); } } else { - if (isset($this->_cssStyles['td.style' . $cell->getXfIndex()])) { - $cssClass = array_merge($cssClass, $this->_cssStyles['td.style' . $cell->getXfIndex()]); + if (isset($this->cssStyles['td.style' . $cell->getXfIndex()])) { + $cssClass = array_merge($cssClass, $this->cssStyles['td.style' . $cell->getXfIndex()]); } } // General horizontal alignment: Actual horizontal alignment depends on dataType $sharedStyle = $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex()); if ($sharedStyle->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL - && isset($this->_cssStyles['.' . $cell->getDataType()]['text-align'])) { - $cssClass['text-align'] = $this->_cssStyles['.' . $cell->getDataType()]['text-align']; + && isset($this->cssStyles['.' . $cell->getDataType()]['text-align'])) { + $cssClass['text-align'] = $this->cssStyles['.' . $cell->getDataType()]['text-align']; } } } @@ -1279,21 +1279,21 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow } // Should the cell be written or is it swallowed by a rowspan or colspan? - $writeCell = !(isset($this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]) - && $this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]); + $writeCell = !(isset($this->isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]) + && $this->isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]); // Colspan and Rowspan $colspan = 1; $rowspan = 1; - if (isset($this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) { - $spans = $this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]; + if (isset($this->isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) { + $spans = $this->isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]; $rowSpan = $spans['rowspan']; $colSpan = $spans['colspan']; // Also apply style from last cell in merge to fix borders - - // relies on !important for non-none border declarations in _createCSSStyleBorder + // relies on !important for non-none border declarations in createCSSStyleBorder $endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan); - if (!$this->_useInlineCss) { + if (!$this->useInlineCss) { $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex(); } } @@ -1302,7 +1302,7 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow if ($writeCell) { // Column start $html .= ' <' . $cellType; - if (!$this->_useInlineCss) { + if (!$this->useInlineCss) { $html .= ' class="' . $cssClass . '"'; } else { //** Necessary redundant code for the sake of PHPExcel_Writer_PDF ** @@ -1312,21 +1312,21 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow $i = $colNum - 1; $e = $colNum + $colSpan - 1; while ($i++ < $e) { - if (isset($this->_columnWidths[$sheetIndex][$i])) { - $width += $this->_columnWidths[$sheetIndex][$i]; + if (isset($this->columnWidths[$sheetIndex][$i])) { + $width += $this->columnWidths[$sheetIndex][$i]; } } $cssClass['width'] = $width . 'pt'; // We must also explicitly write the height of the <td> element because TCPDF // does not recognize e.g. <tr style="height:50pt"> - if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) { - $height = $this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height']; + if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) { + $height = $this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height']; $cssClass['height'] = $height; } //** end of redundant code ** - $html .= ' style="' . $this->_assembleCSS($cssClass) . '"'; + $html .= ' style="' . $this->assembleCSS($cssClass) . '"'; } if ($colSpan > 1) { $html .= ' colspan="' . $colSpan . '"'; @@ -1337,11 +1337,11 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow $html .= '>'; // Image? - $html .= $this->_writeImageInCell($pSheet, $coordinate); + $html .= $this->writeImageInCell($pSheet, $coordinate); // Chart? - if ($this->_includeCharts) { - $html .= $this->_writeChartInCell($pSheet, $coordinate); + if ($this->includeCharts) { + $html .= $this->writeChartInCell($pSheet, $coordinate); } // Cell data @@ -1371,7 +1371,7 @@ private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow * @param array * @return string */ - private function _assembleCSS($pValue = array()) + private function assembleCSS($pValue = array()) { $pairs = array(); foreach ($pValue as $property => $value) { @@ -1389,7 +1389,7 @@ private function _assembleCSS($pValue = array()) */ public function getImagesRoot() { - return $this->_imagesRoot; + return $this->imagesRoot; } /** @@ -1400,7 +1400,7 @@ public function getImagesRoot() */ public function setImagesRoot($pValue = '.') { - $this->_imagesRoot = $pValue; + $this->imagesRoot = $pValue; return $this; } @@ -1411,7 +1411,7 @@ public function setImagesRoot($pValue = '.') */ public function getEmbedImages() { - return $this->_embedImages; + return $this->embedImages; } /** @@ -1422,7 +1422,7 @@ public function getEmbedImages() */ public function setEmbedImages($pValue = '.') { - $this->_embedImages = $pValue; + $this->embedImages = $pValue; return $this; } @@ -1433,7 +1433,7 @@ public function setEmbedImages($pValue = '.') */ public function getUseInlineCss() { - return $this->_useInlineCss; + return $this->useInlineCss; } /** @@ -1444,7 +1444,7 @@ public function getUseInlineCss() */ public function setUseInlineCss($pValue = false) { - $this->_useInlineCss = $pValue; + $this->useInlineCss = $pValue; return $this; } @@ -1482,22 +1482,22 @@ public function formatColor($pValue, $pFormat) /** * Calculate information about HTML colspan and rowspan which is not always the same as Excel's */ - private function _calculateSpans() + private function calculateSpans() { // Identify all cells that should be omitted in HTML due to cell merge. // In HTML only the upper-left cell should be written and it should have // appropriate rowspan / colspan attribute - $sheetIndexes = $this->_sheetIndex !== null ? - array($this->_sheetIndex) : range(0, $this->_phpExcel->getSheetCount() - 1); + $sheetIndexes = $this->sheetIndex !== null ? + array($this->sheetIndex) : range(0, $this->phpExcel->getSheetCount() - 1); foreach ($sheetIndexes as $sheetIndex) { - $sheet = $this->_phpExcel->getSheet($sheetIndex); + $sheet = $this->phpExcel->getSheet($sheetIndex); $candidateSpannedRow = array(); // loop through all Excel merged cells foreach ($sheet->getMergeCells() as $cells) { - list($cells, ) = PHPExcel_Cell::splitRange($cells); + list($cells,) = PHPExcel_Cell::splitRange($cells); $first = $cells[0]; $last = $cells[1]; @@ -1517,12 +1517,12 @@ private function _calculateSpans() while ($c++ < $lc) { if (!($c == $fc && $r == $fr)) { // not the upper-left cell (should not be written in HTML) - $this->_isSpannedCell[$sheetIndex][$r][$c] = array( + $this->isSpannedCell[$sheetIndex][$r][$c] = array( 'baseCell' => array($fr, $fc), ); } else { // upper-left is the base cell that should hold the colspan/rowspan attribute - $this->_isBaseCell[$sheetIndex][$r][$c] = array( + $this->isBaseCell[$sheetIndex][$r][$c] = array( 'xlrowspan' => $lr - $fr + 1, // Excel rowspan 'rowspan' => $lr - $fr + 1, // HTML rowspan, value may change 'xlcolspan' => $lc - $fc + 1, // Excel colspan @@ -1537,25 +1537,25 @@ private function _calculateSpans() // participate in a merge and the where base cells are somewhere above. $countColumns = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()); foreach ($candidateSpannedRow as $rowIndex) { - if (isset($this->_isSpannedCell[$sheetIndex][$rowIndex])) { - if (count($this->_isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) { - $this->_isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex; + if (isset($this->isSpannedCell[$sheetIndex][$rowIndex])) { + if (count($this->isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) { + $this->isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex; }; } } // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1 - if (isset($this->_isSpannedRow[$sheetIndex])) { - foreach ($this->_isSpannedRow[$sheetIndex] as $rowIndex) { + if (isset($this->isSpannedRow[$sheetIndex])) { + foreach ($this->isSpannedRow[$sheetIndex] as $rowIndex) { $adjustedBaseCells = array(); $c = -1; $e = $countColumns - 1; while ($c++ < $e) { - $baseCell = $this->_isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell']; + $baseCell = $this->isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell']; if (!in_array($baseCell, $adjustedBaseCells)) { // subtract rowspan by 1 - --$this->_isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan']; + --$this->isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan']; $adjustedBaseCells[] = $baseCell; } } @@ -1566,10 +1566,10 @@ private function _calculateSpans() } // We have calculated the spans - $this->_spansAreCalculated = true; + $this->spansAreCalculated = true; } - private function _setMargins(PHPExcel_Worksheet $pSheet) + private function setMargins(PHPExcel_Worksheet $pSheet) { $htmlPage = '@page { '; $htmlBody = 'body { '; diff --git a/Classes/PHPExcel/Writer/PDF/Core.php b/Classes/PHPExcel/Writer/PDF/Core.php index ec3254b9a..4fed84a71 100644 --- a/Classes/PHPExcel/Writer/PDF/Core.php +++ b/Classes/PHPExcel/Writer/PDF/Core.php @@ -320,7 +320,7 @@ public function setTempDir($pValue = '') protected function prepareForSave($pFilename = null) { // garbage collect - $this->_phpExcel->garbageCollect(); + $this->phpExcel->garbageCollect(); $this->saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); @@ -332,7 +332,7 @@ protected function prepareForSave($pFilename = null) } // Set PDF - $this->_isPdf = true; + $this->isPdf = true; // Build CSS $this->buildCSS(true); diff --git a/Classes/PHPExcel/Writer/PDF/DomPDF.php b/Classes/PHPExcel/Writer/PDF/DomPDF.php index 45247ed79..83761acb3 100644 --- a/Classes/PHPExcel/Writer/PDF/DomPDF.php +++ b/Classes/PHPExcel/Writer/PDF/DomPDF.php @@ -60,15 +60,15 @@ public function save($pFilename = null) // Check for paper size and page orientation if (is_null($this->getSheetIndex())) { - $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() + $orientation = ($this->phpExcel->getSheet(0)->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; - $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); - $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); + $printPaperSize = $this->phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); + $printMargins = $this->phpExcel->getSheet(0)->getPageMargins(); } else { - $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() + $orientation = ($this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; - $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); - $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); + $printPaperSize = $this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); + $printMargins = $this->phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); } $orientation = ($orientation == 'L') ? 'landscape' : 'portrait'; diff --git a/Classes/PHPExcel/Writer/PDF/mPDF.php b/Classes/PHPExcel/Writer/PDF/mPDF.php index d13b982d6..e4e6057d7 100644 --- a/Classes/PHPExcel/Writer/PDF/mPDF.php +++ b/Classes/PHPExcel/Writer/PDF/mPDF.php @@ -60,15 +60,15 @@ public function save($pFilename = null) // Check for paper size and page orientation if (is_null($this->getSheetIndex())) { - $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() + $orientation = ($this->phpExcel->getSheet(0)->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; - $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); - $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); + $printPaperSize = $this->phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); + $printMargins = $this->phpExcel->getSheet(0)->getPageMargins(); } else { - $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() + $orientation = ($this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; - $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); - $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); + $printPaperSize = $this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); + $printMargins = $this->phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); } $this->setOrientation($orientation); @@ -98,11 +98,11 @@ public function save($pFilename = null) $pdf->AddPage($orientation); // Document info - $pdf->SetTitle($this->_phpExcel->getProperties()->getTitle()); - $pdf->SetAuthor($this->_phpExcel->getProperties()->getCreator()); - $pdf->SetSubject($this->_phpExcel->getProperties()->getSubject()); - $pdf->SetKeywords($this->_phpExcel->getProperties()->getKeywords()); - $pdf->SetCreator($this->_phpExcel->getProperties()->getCreator()); + $pdf->SetTitle($this->phpExcel->getProperties()->getTitle()); + $pdf->SetAuthor($this->phpExcel->getProperties()->getCreator()); + $pdf->SetSubject($this->phpExcel->getProperties()->getSubject()); + $pdf->SetKeywords($this->phpExcel->getProperties()->getKeywords()); + $pdf->SetCreator($this->phpExcel->getProperties()->getCreator()); $pdf->WriteHTML( $this->generateHTMLHeader(false) . diff --git a/Classes/PHPExcel/Writer/PDF/tcPDF.php b/Classes/PHPExcel/Writer/PDF/tcPDF.php index 8b6c0bca3..dea33a352 100644 --- a/Classes/PHPExcel/Writer/PDF/tcPDF.php +++ b/Classes/PHPExcel/Writer/PDF/tcPDF.php @@ -61,15 +61,15 @@ public function save($pFilename = null) // Check for paper size and page orientation if (is_null($this->getSheetIndex())) { - $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() + $orientation = ($this->phpExcel->getSheet(0)->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; - $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); - $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); + $printPaperSize = $this->phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); + $printMargins = $this->phpExcel->getSheet(0)->getPageMargins(); } else { - $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() + $orientation = ($this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; - $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); - $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); + $printPaperSize = $this->phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); + $printMargins = $this->phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); } // Override Page Orientation @@ -109,11 +109,11 @@ public function save($pFilename = null) ); // Document info - $pdf->SetTitle($this->_phpExcel->getProperties()->getTitle()); - $pdf->SetAuthor($this->_phpExcel->getProperties()->getCreator()); - $pdf->SetSubject($this->_phpExcel->getProperties()->getSubject()); - $pdf->SetKeywords($this->_phpExcel->getProperties()->getKeywords()); - $pdf->SetCreator($this->_phpExcel->getProperties()->getCreator()); + $pdf->SetTitle($this->phpExcel->getProperties()->getTitle()); + $pdf->SetAuthor($this->phpExcel->getProperties()->getCreator()); + $pdf->SetSubject($this->phpExcel->getProperties()->getSubject()); + $pdf->SetKeywords($this->phpExcel->getProperties()->getKeywords()); + $pdf->SetCreator($this->phpExcel->getProperties()->getCreator()); // Write to file fwrite($fileHandle, $pdf->output($pFilename, 'S')); diff --git a/unitTests/rawTestData/Calculation/MathTrig/QUOTIENT.data b/unitTests/rawTestData/Calculation/MathTrig/QUOTIENT.data index 5992a4cf1..61c6b7b36 100644 --- a/unitTests/rawTestData/Calculation/MathTrig/QUOTIENT.data +++ b/unitTests/rawTestData/Calculation/MathTrig/QUOTIENT.data @@ -3,4 +3,4 @@ -10, 3, -3 10, 2.2, 4 5.5, 2.667, 2 --7, 2, -4 +-7, 2, -3 From c4ff34dde4ce9bf18393582d4271b0de943a793b Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 20 May 2015 23:19:33 +0100 Subject: [PATCH 393/467] Yet more chunks of psr-2 goodness --- Classes/PHPExcel/Calculation.php | 18 +-- Classes/PHPExcel/Reader/Gnumeric.php | 10 +- Classes/PHPExcel/Reader/HTML.php | 49 ++++---- Classes/PHPExcel/Reader/OOCalc.php | 2 +- Classes/PHPExcel/Shared/File.php | 24 ++-- Classes/PHPExcel/Shared/JAMA/Matrix.php | 58 ++++----- Classes/PHPExcel/Shared/OLE/PPS/Root.php | 14 +-- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 112 +++++++++--------- Classes/PHPExcel/Worksheet.php | 14 +-- 9 files changed, 150 insertions(+), 151 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index e13b93589..3413ac894 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2407,7 +2407,7 @@ public function setLocale($locale = 'en_us') - public static function _translateSeparator($fromSeparator, $toSeparator, $formula, &$inBraces) + public static function translateSeparator($fromSeparator, $toSeparator, $formula, &$inBraces) { $strlen = mb_strlen($formula); for ($i = 0; $i < $strlen; ++$i) { @@ -2428,7 +2428,7 @@ public static function _translateSeparator($fromSeparator, $toSeparator, $formul return $formula; } - private static function _translateFormula($from, $to, $formula, $fromSeparator, $toSeparator) + private static function translateFormula($from, $to, $formula, $fromSeparator, $toSeparator) { // Convert any Excel function names to the required language if (self::$localeLanguage !== 'en_us') { @@ -2443,7 +2443,7 @@ private static function _translateFormula($from, $to, $formula, $fromSeparator, // Only count/replace in alternating array entries if ($i = !$i) { $value = preg_replace($from, $to, $value); - $value = self::_translateSeparator($fromSeparator, $toSeparator, $value, $inBraces); + $value = self::translateSeparator($fromSeparator, $toSeparator, $value, $inBraces); } } unset($value); @@ -2452,7 +2452,7 @@ private static function _translateFormula($from, $to, $formula, $fromSeparator, } else { // If there's no quoted strings, then we do a simple count/replace $formula = preg_replace($from, $to, $formula); - $formula = self::_translateSeparator($fromSeparator, $toSeparator, $formula, $inBraces); + $formula = self::translateSeparator($fromSeparator, $toSeparator, $formula, $inBraces); } } @@ -2485,7 +2485,7 @@ public function _translateFormulaToLocale($formula) } } - return self::_translateFormula(self::$functionReplaceFromExcel, self::$functionReplaceToLocale, $formula, ',', self::$localeArgumentSeparator); + return self::translateFormula(self::$functionReplaceFromExcel, self::$functionReplaceToLocale, $formula, ',', self::$localeArgumentSeparator); } @@ -2514,7 +2514,7 @@ public function _translateFormulaToEnglish($formula) } } - return self::_translateFormula(self::$functionReplaceFromLocale, self::$functionReplaceToExcel, $formula, self::$localeArgumentSeparator, ','); + return self::translateFormula(self::$functionReplaceFromLocale, self::$functionReplaceToExcel, $formula, self::$localeArgumentSeparator, ','); } @@ -3503,7 +3503,7 @@ private function _parseFormula($formula, PHPExcel_Cell $pCell = null) } - private static function _dataTestReference(&$operandData) + private static function dataTestReference(&$operandData) { $operand = $operandData['value']; if (($operandData['reference'] === null) && (is_array($operand))) { @@ -3548,8 +3548,8 @@ private function processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCell return $this->raiseFormulaError('Internal error - Operand value missing from stack'); } - $operand1 = self::_dataTestReference($operand1Data); - $operand2 = self::_dataTestReference($operand2Data); + $operand1 = self::dataTestReference($operand1Data); + $operand2 = self::dataTestReference($operand2Data); // Log what we're doing if ($token == ':') { diff --git a/Classes/PHPExcel/Reader/Gnumeric.php b/Classes/PHPExcel/Reader/Gnumeric.php index e4a30b00c..913e52bc8 100644 --- a/Classes/PHPExcel/Reader/Gnumeric.php +++ b/Classes/PHPExcel/Reader/Gnumeric.php @@ -426,7 +426,13 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) } else { $expression = $this->expressions[$ExprID]; - $cell = $this->referenceHelper->updateFormulaReferences($expression['formula'], 'A1', $cellAttributes->Col - $expression['column'], $cellAttributes->Row - $expression['row'], $worksheetName); + $cell = $this->referenceHelper->updateFormulaReferences( + $expression['formula'], + 'A1', + $cellAttributes->Col - $expression['column'], + $cellAttributes->Row - $expression['row'], + $worksheetName + ); // echo 'SHARED EXPRESSION ', $ExprID,'<br />'; // echo 'New Value is ', $cell,'<br />'; } @@ -441,8 +447,8 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $cell = ($cell == 'TRUE') ? true: false; break; case '30': // Integer - // Excel 2007+ doesn't differentiate between integer and float, so set the value and dropthru to the next (numeric) case $cell = intval($cell); + // Excel 2007+ doesn't differentiate between integer and float, so set the value and dropthru to the next (numeric) case case '40': // Float $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; break; diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index dedc1daa4..a19eaec9d 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -179,31 +179,31 @@ public function getInputEncoding() } // Data Array used for testing only, should write to PHPExcel object on completion of tests - protected $_dataArray = array(); - protected $_tableLevel = 0; - protected $_nestedColumn = array('A'); + protected $dataArray = array(); + protected $tableLevel = 0; + protected $nestedColumn = array('A'); protected function setTableStartColumn($column) { - if ($this->_tableLevel == 0) { + if ($this->tableLevel == 0) { $column = 'A'; } - ++$this->_tableLevel; - $this->_nestedColumn[$this->_tableLevel] = $column; + ++$this->tableLevel; + $this->nestedColumn[$this->tableLevel] = $column; - return $this->_nestedColumn[$this->_tableLevel]; + return $this->nestedColumn[$this->tableLevel]; } protected function getTableStartColumn() { - return $this->_nestedColumn[$this->_tableLevel]; + return $this->nestedColumn[$this->tableLevel]; } protected function releaseTableStartColumn() { - --$this->_tableLevel; + --$this->tableLevel; - return array_pop($this->_nestedColumn); + return array_pop($this->nestedColumn); } protected function flushCell($sheet, $column, $row, &$cellContent) @@ -216,12 +216,12 @@ protected function flushCell($sheet, $column, $row, &$cellContent) // Write to worksheet to be done here... // ... we return the cell so we can mess about with styles more easily $sheet->setCellValue($column . $row, $cellContent, true); - $this->_dataArray[$row][$column] = $cellContent; + $this->dataArray[$row][$column] = $cellContent; } } else { // We have a Rich Text run // TODO - $this->_dataArray[$row][$column] = 'RICH TEXT: ' . $cellContent; + $this->dataArray[$row][$column] = 'RICH TEXT: ' . $cellContent; } $cellContent = (string) ''; } @@ -291,8 +291,9 @@ protected function processDomElement(DOMNode $element, $sheet, &$row, &$column, $this->flushCell($sheet, $column, $row, $cellContent); } ++$row; + // Add a break after a horizontal rule, simply by allowing the code to dropthru case 'br': - if ($this->_tableLevel > 0) { + if ($this->tableLevel > 0) { // If we're inside a table, replace with a \n $cellContent .= "\n"; } else { @@ -328,7 +329,7 @@ protected function processDomElement(DOMNode $element, $sheet, &$row, &$column, case 'ol': case 'ul': case 'p': - if ($this->_tableLevel > 0) { + if ($this->tableLevel > 0) { // If we're inside a table, replace with a \n $cellContent .= "\n"; // echo 'LIST ENTRY: ' , '<br />'; @@ -353,7 +354,7 @@ protected function processDomElement(DOMNode $element, $sheet, &$row, &$column, } break; case 'li': - if ($this->_tableLevel > 0) { + if ($this->tableLevel > 0) { // If we're inside a table, replace with a \n $cellContent .= "\n"; // echo 'LIST ENTRY: ' , '<br />'; @@ -374,14 +375,14 @@ protected function processDomElement(DOMNode $element, $sheet, &$row, &$column, case 'table': $this->flushCell($sheet, $column, $row, $cellContent); $column = $this->setTableStartColumn($column); -// echo 'START OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; - if ($this->_tableLevel > 1) { +// echo 'START OF TABLE LEVEL ' , $this->tableLevel , '<br />'; + if ($this->tableLevel > 1) { --$row; } $this->processDomElement($child, $sheet, $row, $column, $cellContent); -// echo 'END OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; +// echo 'END OF TABLE LEVEL ' , $this->tableLevel , '<br />'; $column = $this->releaseTableStartColumn(); - if ($this->_tableLevel > 1) { + if ($this->tableLevel > 1) { ++$column; } else { ++$row; @@ -394,16 +395,16 @@ protected function processDomElement(DOMNode $element, $sheet, &$row, &$column, case 'tr': $column = $this->getTableStartColumn(); $cellContent = ''; -// echo 'START OF TABLE ' , $this->_tableLevel , ' ROW<br />'; +// echo 'START OF TABLE ' , $this->tableLevel , ' ROW<br />'; $this->processDomElement($child, $sheet, $row, $column, $cellContent); ++$row; -// echo 'END OF TABLE ' , $this->_tableLevel , ' ROW<br />'; +// echo 'END OF TABLE ' , $this->tableLevel , ' ROW<br />'; break; case 'th': case 'td': -// echo 'START OF TABLE ' , $this->_tableLevel , ' CELL<br />'; +// echo 'START OF TABLE ' , $this->tableLevel , ' CELL<br />'; $this->processDomElement($child, $sheet, $row, $column, $cellContent); -// echo 'END OF TABLE ' , $this->_tableLevel , ' CELL<br />'; +// echo 'END OF TABLE ' , $this->tableLevel , ' CELL<br />'; while (isset($this->rowspan[$column . $row])) { ++$column; @@ -453,7 +454,7 @@ protected function processDomElement(DOMNode $element, $sheet, &$row, &$column, $row = 1; $column = 'A'; $content = ''; - $this->_tableLevel = 0; + $this->tableLevel = 0; $this->processDomElement($child, $sheet, $row, $column, $cellContent); break; default: diff --git a/Classes/PHPExcel/Reader/OOCalc.php b/Classes/PHPExcel/Reader/OOCalc.php index 22def5d5a..a889d9570 100644 --- a/Classes/PHPExcel/Reader/OOCalc.php +++ b/Classes/PHPExcel/Reader/OOCalc.php @@ -619,7 +619,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/Ui', '$1!$2', $value); // Cell reference in another sheet $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/Ui', '$1:$2', $value); // Cell range reference $value = preg_replace('/\[\.([^\.]+)\]/Ui', '$1', $value); // Simple cell reference - $value = PHPExcel_Calculation::_translateSeparator(';', ',', $value, $inBraces); + $value = PHPExcel_Calculation::translateSeparator(';', ',', $value, $inBraces); } } unset($value); diff --git a/Classes/PHPExcel/Shared/File.php b/Classes/PHPExcel/Shared/File.php index 6e04857af..a62df759f 100644 --- a/Classes/PHPExcel/Shared/File.php +++ b/Classes/PHPExcel/Shared/File.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_File * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Shared_File - * - * @category PHPExcel - * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_File { /* @@ -41,7 +33,7 @@ class PHPExcel_Shared_File * @protected * @var boolean */ - protected static $_useUploadTempDirectory = false; + protected static $useUploadTempDirectory = false; /** @@ -51,7 +43,7 @@ class PHPExcel_Shared_File */ public static function setUseUploadTempDirectory($useUploadTempDir = false) { - self::$_useUploadTempDirectory = (boolean) $useUploadTempDir; + self::$useUploadTempDirectory = (boolean) $useUploadTempDir; } @@ -62,7 +54,7 @@ public static function setUseUploadTempDirectory($useUploadTempDir = false) */ public static function getUseUploadTempDirectory() { - return self::$_useUploadTempDirectory; + return self::$useUploadTempDirectory; } @@ -79,8 +71,8 @@ public static function file_exists($pFilename) // doing the original file_exists on ZIP archives... if (strtolower(substr($pFilename, 0, 3)) == 'zip') { // Open ZIP file and verify if the file exists - $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); - $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1); + $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); + $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1); $zip = new ZipArchive(); if ($zip->open($zipFile) === true) { @@ -138,7 +130,7 @@ public static function realpath($pFilename) */ public static function sys_get_temp_dir() { - if (self::$_useUploadTempDirectory) { + if (self::$useUploadTempDirectory) { // use upload-directory when defined to allow running on environments having very restricted // open_basedir configs if (ini_get('upload_tmp_dir') !== false) { diff --git a/Classes/PHPExcel/Shared/JAMA/Matrix.php b/Classes/PHPExcel/Shared/JAMA/Matrix.php index b39d414cd..83668b0f4 100644 --- a/Classes/PHPExcel/Shared/JAMA/Matrix.php +++ b/Classes/PHPExcel/Shared/JAMA/Matrix.php @@ -111,7 +111,7 @@ public function __construct() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function __construct() + } /** * getArray @@ -121,7 +121,7 @@ public function __construct() public function getArray() { return $this->A; - } // function getArray() + } /** * getRowDimension @@ -131,7 +131,7 @@ public function getArray() public function getRowDimension() { return $this->m; - } // function getRowDimension() + } /** * getColumnDimension @@ -141,7 +141,7 @@ public function getRowDimension() public function getColumnDimension() { return $this->n; - } // function getColumnDimension() + } /** * get @@ -154,7 +154,7 @@ public function getColumnDimension() public function get($i = null, $j = null) { return $this->A[$i][$j]; - } // function get() + } /** * getMatrix @@ -306,7 +306,7 @@ public function getMatrix() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function getMatrix() + } /** * checkMatrixDimensions @@ -354,7 +354,7 @@ public function set($i = null, $j = null, $c = null) public function identity($m = null, $n = null) { return $this->diagonal($m, $n, 1); - } // function identity() + } /** * diagonal @@ -372,7 +372,7 @@ public function diagonal($m = null, $n = null, $c = 1) $R->set($i, $i, $c); } return $R; - } // function diagonal() + } /** * getMatrixByRow @@ -393,7 +393,7 @@ public function getMatrixByRow($i0 = null, $iF = null) } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - } // function getMatrixByRow() + } /** * getMatrixByCol @@ -414,7 +414,7 @@ public function getMatrixByCol($j0 = null, $jF = null) } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } - } // function getMatrixByCol() + } /** * transpose @@ -447,7 +447,7 @@ public function trace() $s += $this->A[$i][$i]; } return $s; - } // function trace() + } /** * uminus @@ -457,7 +457,7 @@ public function trace() */ public function uminus() { - } // function uminus() + } /** * plus @@ -497,7 +497,7 @@ public function plus() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function plus() + } /** * plusEquals @@ -551,7 +551,7 @@ public function plusEquals() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function plusEquals() + } /** * minus @@ -591,7 +591,7 @@ public function minus() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function minus() + } /** * minusEquals @@ -645,7 +645,7 @@ public function minusEquals() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function minusEquals() + } /** * arrayTimes @@ -686,7 +686,7 @@ public function arrayTimes() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function arrayTimes() + } /** * arrayTimesEquals @@ -741,7 +741,7 @@ public function arrayTimesEquals() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function arrayTimesEquals() + } /** * arrayRightDivide @@ -801,7 +801,7 @@ public function arrayRightDivide() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function arrayRightDivide() + } /** @@ -843,7 +843,7 @@ public function arrayRightDivideEquals() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function arrayRightDivideEquals() + } /** @@ -885,7 +885,7 @@ public function arrayLeftDivide() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function arrayLeftDivide() + } /** @@ -927,7 +927,7 @@ public function arrayLeftDivideEquals() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function arrayLeftDivideEquals() + } /** @@ -1023,7 +1023,7 @@ public function times() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function times() + } /** * power @@ -1077,7 +1077,7 @@ public function power() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function power() + } /** * concat @@ -1116,7 +1116,7 @@ public function concat() } else { throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); } - } // function concat() + } /** * Solve A*X = B. @@ -1133,7 +1133,7 @@ public function solve($B) $QR = new PHPExcel_Shared_JAMA_QRDecomposition($this); return $QR->solve($B); } - } // function solve() + } /** * Matrix inverse or pseudoinverse. @@ -1143,7 +1143,7 @@ public function solve($B) public function inverse() { return $this->solve($this->identity($this->m, $this->m)); - } // function inverse() + } /** * det @@ -1155,5 +1155,5 @@ public function det() { $L = new PHPExcel_Shared_JAMA_LUDecomposition($this); return $L->det(); - } // function det() -} // class PHPExcel_Shared_JAMA_Matrix + } +} diff --git a/Classes/PHPExcel/Shared/OLE/PPS/Root.php b/Classes/PHPExcel/Shared/OLE/PPS/Root.php index c62399baa..5d4052f06 100644 --- a/Classes/PHPExcel/Shared/OLE/PPS/Root.php +++ b/Classes/PHPExcel/Shared/OLE/PPS/Root.php @@ -34,7 +34,7 @@ class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS * Directory for temporary files * @var string */ - protected $_tmp_dir = null; + protected $tempDirectory = null; /** * @param integer $time_1st A timestamp @@ -63,20 +63,20 @@ public function save($filename) // Initial Setting for saving $this->_BIG_BLOCK_SIZE = pow( 2, - (isset($this->_BIG_BLOCK_SIZE))? self::_adjust2($this->_BIG_BLOCK_SIZE) : 9 + (isset($this->_BIG_BLOCK_SIZE))? self::adjust2($this->_BIG_BLOCK_SIZE) : 9 ); $this->_SMALL_BLOCK_SIZE= pow( 2, - (isset($this->_SMALL_BLOCK_SIZE))? self::_adjust2($this->_SMALL_BLOCK_SIZE) : 6 + (isset($this->_SMALL_BLOCK_SIZE))? self::adjust2($this->_SMALL_BLOCK_SIZE) : 6 ); if (is_resource($filename)) { $this->_FILEH_ = $filename; } elseif ($filename == '-' || $filename == '') { - if ($this->_tmp_dir === null) { - $this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir(); + if ($this->tempDirectory === null) { + $this->tempDirectory = PHPExcel_Shared_File::sys_get_temp_dir(); } - $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root"); + $this->_tmp_filename = tempnam($this->tempDirectory, "OLE_PPS_Root"); $this->_FILEH_ = fopen($this->_tmp_filename, "w+b"); if ($this->_FILEH_ == false) { throw new PHPExcel_Writer_Exception("Can't create temporary file."); @@ -158,7 +158,7 @@ public function _calcSize(&$raList) * @see save() * @return integer */ - private static function _adjust2($i2) + private static function adjust2($i2) { $iWk = log($i2)/log(2); return ($iWk > floor($iWk))? floor($iWk)+1:$iWk; diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index 8fa3db831..263137d1b 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -190,19 +190,19 @@ class PclZip { // ----- Filename of the zip file - var $zipname = ''; + public $zipname = ''; // ----- File descriptor of the zip file - var $zip_fd = 0; + public $zip_fd = 0; // ----- Internal error handling - var $error_code = 1; - var $error_string = ''; + public $error_code = 1; + public $error_string = ''; // ----- Current status of the magic_quotes_runtime // This value store the php configuration for magic_quotes // The class can then disable the magic_quotes and reset it after - var $magic_quotes_status; + public $magic_quotes_status; // -------------------------------------------------------------------------------- // Function : PclZip() @@ -212,7 +212,7 @@ class PclZip // Note that no real action is taken, if the archive does not exist it is not // created. Use create() for that. // -------------------------------------------------------------------------------- - function PclZip($p_zipname) + public function PclZip($p_zipname) { // ----- Tests the zlib @@ -267,7 +267,7 @@ function PclZip($p_zipname) // The list of the added files, with a status of the add action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- - function create($p_filelist) + public function create($p_filelist) { $v_result=1; @@ -433,7 +433,7 @@ function create($p_filelist) // The list of the added files, with a status of the add action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- - function add($p_filelist) + public function add($p_filelist) { $v_result=1; @@ -607,7 +607,7 @@ function add($p_filelist) // 0 on an unrecoverable failure, // The list of the files in the archive. // -------------------------------------------------------------------------------- - function listContent() + public function listContent() { $v_result=1; @@ -663,7 +663,7 @@ function listContent() // The list of the extracted files, with a status of the action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- - function extract() + public function extract() { $v_result=1; @@ -814,7 +814,7 @@ function extract() // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- //function extractByIndex($p_index, options...) - function extractByIndex($p_index) + public function extractByIndex($p_index) { $v_result=1; @@ -957,7 +957,7 @@ function extractByIndex($p_index) // The list of the files which are still present in the archive. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- - function delete() + public function delete() { $v_result=1; @@ -1017,7 +1017,7 @@ function delete() // ***** Deprecated ***** // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. // -------------------------------------------------------------------------------- - function deleteByIndex($p_index) + public function deleteByIndex($p_index) { $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); @@ -1041,7 +1041,7 @@ function deleteByIndex($p_index) // 0 on failure, // An array with the archive properties. // -------------------------------------------------------------------------------- - function properties() + public function properties() { // ----- Reset the error handler @@ -1111,7 +1111,7 @@ function properties() // 1 on success. // 0 or a negative value on error (error code). // -------------------------------------------------------------------------------- - function duplicate($p_archive) + public function duplicate($p_archive) { $v_result = 1; @@ -1160,7 +1160,7 @@ function duplicate($p_archive) // 1 on success, // 0 or negative values on error (see below). // -------------------------------------------------------------------------------- - function merge($p_archive_to_add) + public function merge($p_archive_to_add) { $v_result = 1; @@ -1202,7 +1202,7 @@ function merge($p_archive_to_add) // Description : // Parameters : // -------------------------------------------------------------------------------- - function errorCode() + public function errorCode() { if (PCLZIP_ERROR_EXTERNAL == 1) { return(PclErrorCode()); @@ -1217,7 +1217,7 @@ function errorCode() // Description : // Parameters : // -------------------------------------------------------------------------------- - function errorName($p_with_code = false) + public function errorName($p_with_code = false) { $v_name = array( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', @@ -1262,7 +1262,7 @@ function errorName($p_with_code = false) // Description : // Parameters : // -------------------------------------------------------------------------------- - function errorInfo($p_full = false) + public function errorInfo($p_full = false) { if (PCLZIP_ERROR_EXTERNAL == 1) { return(PclErrorString()); @@ -1299,7 +1299,7 @@ function errorInfo($p_full = false) // true on success, // false on error, the error code is set. // -------------------------------------------------------------------------------- - function privCheckFormat($p_level = 0) + public function privCheckFormat($p_level = 0) { $v_result = true; @@ -1352,7 +1352,7 @@ function privCheckFormat($p_level = 0) // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- - function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options = false) + public function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options = false) { $v_result=1; @@ -1714,7 +1714,7 @@ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_request // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privOptionDefaultThreshold(&$p_options) + public function privOptionDefaultThreshold(&$p_options) { $v_result=1; @@ -1759,7 +1759,7 @@ function privOptionDefaultThreshold(&$p_options) // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- - function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options = false) + public function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options = false) { $v_result=1; @@ -1875,7 +1875,7 @@ function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requ // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- - function privFileDescrExpand(&$p_filedescr_list, &$p_options) + public function privFileDescrExpand(&$p_filedescr_list, &$p_options) { $v_result=1; @@ -1986,7 +1986,7 @@ function privFileDescrExpand(&$p_filedescr_list, &$p_options) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privCreate($p_filedescr_list, &$p_result_list, &$p_options) + public function privCreate($p_filedescr_list, &$p_result_list, &$p_options) { $v_result=1; $v_list_detail = array(); @@ -2020,7 +2020,7 @@ function privCreate($p_filedescr_list, &$p_result_list, &$p_options) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privAdd($p_filedescr_list, &$p_result_list, &$p_options) + public function privAdd($p_filedescr_list, &$p_result_list, &$p_options) { $v_result=1; $v_list_detail = array(); @@ -2189,7 +2189,7 @@ function privAdd($p_filedescr_list, &$p_result_list, &$p_options) // Description : // Parameters : // -------------------------------------------------------------------------------- - function privOpenFd($p_mode) + public function privOpenFd($p_mode) { $v_result=1; @@ -2221,7 +2221,7 @@ function privOpenFd($p_mode) // Description : // Parameters : // -------------------------------------------------------------------------------- - function privCloseFd() + public function privCloseFd() { $v_result=1; @@ -2248,8 +2248,8 @@ function privCloseFd() // $p_remove_dir : Path to remove in the filename path archived // Return Values : // -------------------------------------------------------------------------------- - // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) - function privAddList($p_filedescr_list, &$p_result_list, &$p_options) + // public function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) + public function privAddList($p_filedescr_list, &$p_result_list, &$p_options) { $v_result=1; @@ -2310,7 +2310,7 @@ function privAddList($p_filedescr_list, &$p_result_list, &$p_options) // $p_result_list : list of added files with their properties (specially the status field) // Return Values : // -------------------------------------------------------------------------------- - function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) + public function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) { $v_result=1; $v_header = array(); @@ -2362,7 +2362,7 @@ function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privAddFile($p_filedescr, &$p_header, &$p_options) + public function privAddFile($p_filedescr, &$p_header, &$p_options) { $v_result=1; @@ -2606,7 +2606,7 @@ function privAddFile($p_filedescr, &$p_header, &$p_options) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) + public function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) { $v_result=PCLZIP_ERR_NO_ERROR; @@ -2716,7 +2716,7 @@ function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privCalculateStoredFilename(&$p_filedescr, &$p_options) + public function privCalculateStoredFilename(&$p_filedescr, &$p_options) { $v_result=1; @@ -2814,7 +2814,7 @@ function privCalculateStoredFilename(&$p_filedescr, &$p_options) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privWriteFileHeader(&$p_header) + public function privWriteFileHeader(&$p_header) { $v_result=1; @@ -2851,7 +2851,7 @@ function privWriteFileHeader(&$p_header) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privWriteCentralFileHeader(&$p_header) + public function privWriteCentralFileHeader(&$p_header) { $v_result=1; @@ -2893,7 +2893,7 @@ function privWriteCentralFileHeader(&$p_header) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) + public function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) { $v_result = 1; @@ -2919,7 +2919,7 @@ function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privList(&$p_list) + public function privList(&$p_list) { $v_result = 1; @@ -3001,7 +3001,7 @@ function privList(&$p_list) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privConvertHeader2FileInfo($p_header, &$p_info) + public function privConvertHeader2FileInfo($p_header, &$p_info) { $v_result=1; @@ -3040,7 +3040,7 @@ function privConvertHeader2FileInfo($p_header, &$p_info) // Return Values : // 1 on success,0 or less on error (see error code list) // -------------------------------------------------------------------------------- - function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + public function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) { $v_result=1; @@ -3314,7 +3314,7 @@ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all // 1 : ... ? // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback // -------------------------------------------------------------------------------- - function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + public function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) { $v_result=1; @@ -3591,7 +3591,7 @@ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privExtractFileUsingTempFile(&$p_entry, &$p_options) + public function privExtractFileUsingTempFile(&$p_entry, &$p_options) { $v_result=1; @@ -3664,7 +3664,7 @@ function privExtractFileUsingTempFile(&$p_entry, &$p_options) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privExtractFileInOutput(&$p_entry, &$p_options) + public function privExtractFileInOutput(&$p_entry, &$p_options) { $v_result=1; @@ -3768,7 +3768,7 @@ function privExtractFileInOutput(&$p_entry, &$p_options) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) + public function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) { $v_result=1; @@ -3877,7 +3877,7 @@ function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privReadFileHeader(&$p_header) + public function privReadFileHeader(&$p_header) { $v_result=1; @@ -3973,7 +3973,7 @@ function privReadFileHeader(&$p_header) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privReadCentralFileHeader(&$p_header) + public function privReadCentralFileHeader(&$p_header) { $v_result = 1; @@ -4078,7 +4078,7 @@ function privReadCentralFileHeader(&$p_header) // 1 on success, // 0 on error; // -------------------------------------------------------------------------------- - function privCheckFileHeaders(&$p_local_header, &$p_central_header) + public function privCheckFileHeaders(&$p_local_header, &$p_central_header) { $v_result=1; @@ -4115,7 +4115,7 @@ function privCheckFileHeaders(&$p_local_header, &$p_central_header) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privReadEndCentralDir(&$p_central_dir) + public function privReadEndCentralDir(&$p_central_dir) { $v_result=1; @@ -4261,7 +4261,7 @@ function privReadEndCentralDir(&$p_central_dir) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privDeleteByRule(&$p_result_list, &$p_options) + public function privDeleteByRule(&$p_result_list, &$p_options) { $v_result=1; $v_list_detail = array(); @@ -4526,7 +4526,7 @@ function privDeleteByRule(&$p_result_list, &$p_options) // 1 : OK // -1 : Unable to create directory // -------------------------------------------------------------------------------- - function privDirCheck($p_dir, $p_is_dir = false) + public function privDirCheck($p_dir, $p_is_dir = false) { $v_result = 1; @@ -4574,7 +4574,7 @@ function privDirCheck($p_dir, $p_is_dir = false) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privMerge(&$p_archive_to_add) + public function privMerge(&$p_archive_to_add) { $v_result=1; @@ -4745,7 +4745,7 @@ function privMerge(&$p_archive_to_add) // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privDuplicate($p_archive_filename) + public function privDuplicate($p_archive_filename) { $v_result=1; @@ -4800,7 +4800,7 @@ function privDuplicate($p_archive_filename) // Description : // Parameters : // -------------------------------------------------------------------------------- - function privErrorLog($p_error_code = 0, $p_error_string = '') + public function privErrorLog($p_error_code = 0, $p_error_string = '') { if (PCLZIP_ERROR_EXTERNAL == 1) { PclError($p_error_code, $p_error_string); @@ -4816,7 +4816,7 @@ function privErrorLog($p_error_code = 0, $p_error_string = '') // Description : // Parameters : // -------------------------------------------------------------------------------- - function privErrorReset() + public function privErrorReset() { if (PCLZIP_ERROR_EXTERNAL == 1) { PclErrorReset(); @@ -4833,7 +4833,7 @@ function privErrorReset() // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privDisableMagicQuotes() + public function privDisableMagicQuotes() { $v_result=1; @@ -4866,7 +4866,7 @@ function privDisableMagicQuotes() // Parameters : // Return Values : // -------------------------------------------------------------------------------- - function privSwapBackMagicQuotes() + public function privSwapBackMagicQuotes() { $v_result=1; diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 71c0addca..0f44c7744 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -416,7 +416,7 @@ public static function getInvalidCharacters() * @return string The valid string * @throws Exception */ - private static function _checkSheetCodeName($pValue) + private static function checkSheetCodeName($pValue) { $CharCount = PHPExcel_Shared_String::CountCharacters($pValue); if ($CharCount == 0) { @@ -444,7 +444,7 @@ private static function _checkSheetCodeName($pValue) * @return string The valid string * @throws PHPExcel_Exception */ - private static function _checkSheetTitle($pValue) + private static function checkSheetTitle($pValue) { // Some of the printable ASCII characters are invalid: * : / \ ? [ ] if (str_replace(self::$invalidCharacters, '', $pValue) !== $pValue) { @@ -825,7 +825,7 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t } // Syntax check - self::_checkSheetTitle($pValue); + self::checkSheetTitle($pValue); // Old title $oldTitle = $this->getTitle(); @@ -1173,7 +1173,7 @@ public function getCell($pCoordinate = 'A1') } // Create new cell object - return $this->_createNewCell($pCoordinate); + return $this->createNewCell($pCoordinate); } /** @@ -1192,7 +1192,7 @@ public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) return $this->cellCollection->getCacheData($coordinate); } - return $this->_createNewCell($coordinate); + return $this->createNewCell($coordinate); } /** @@ -1201,7 +1201,7 @@ public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) * @param string $pCoordinate Coordinate of the cell * @return PHPExcel_Cell Cell that was created */ - private function _createNewCell($pCoordinate) + private function createNewCell($pCoordinate) { $cell = $this->cellCollection->addCacheData( $pCoordinate, @@ -2906,7 +2906,7 @@ public function setCodeName($pValue = null) $pValue = str_replace(' ', '_', $pValue);//Excel does this automatically without flinching, we are doing the same // Syntax check // throw an exception if not valid - self::_checkSheetCodeName($pValue); + self::checkSheetCodeName($pValue); // We use the same code that setTitle to find a valid codeName else not using a space (Excel don't like) but a '_' From 85692956a79329320b692a9faf5fed8fbde47217 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 20 May 2015 23:55:01 +0100 Subject: [PATCH 394/467] Close to the end of the psr-2 work, just trends to go --- Classes/PHPExcel/Shared/String.php | 106 ++++++------- Classes/PHPExcel/Shared/TimeZone.php | 16 +- Classes/PHPExcel/Shared/XMLWriter.php | 45 +++--- Classes/PHPExcel/Shared/ZipArchive.php | 25 ++- Classes/PHPExcel/Shared/ZipStreamWrapper.php | 42 ++--- Classes/PHPExcel/Worksheet/BaseDrawing.php | 152 +++++++++---------- Classes/PHPExcel/Worksheet/Drawing.php | 4 +- Classes/PHPExcel/Worksheet/MemoryDrawing.php | 4 +- 8 files changed, 189 insertions(+), 205 deletions(-) diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index df8cdf2f8..fa1a64e05 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Shared_String * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Shared_String - * - * @category PHPExcel - * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_String { /** Constants */ @@ -46,60 +38,60 @@ class PHPExcel_Shared_String * * @var string[] */ - private static $_controlCharacters = array(); + private static $controlCharacters = array(); /** * SYLK Characters array * * $var array */ - private static $_SYLKCharacters = array(); + private static $SYLKCharacters = array(); /** * Decimal separator * * @var string */ - private static $_decimalSeparator; + private static $decimalSeparator; /** * Thousands separator * * @var string */ - private static $_thousandsSeparator; + private static $thousandsSeparator; /** * Currency code * * @var string */ - private static $_currencyCode; + private static $currencyCode; /** * Is mbstring extension avalable? * * @var boolean */ - private static $_isMbstringEnabled; + private static $isMbstringEnabled; /** * Is iconv extension avalable? * * @var boolean */ - private static $_isIconvEnabled; + private static $isIconvEnabled; /** * Build control characters array */ - private static function _buildControlCharacters() + private static function buildControlCharacters() { for ($i = 0; $i <= 31; ++$i) { if ($i != 9 && $i != 10 && $i != 13) { $find = '_x' . sprintf('%04s', strtoupper(dechex($i))) . '_'; $replace = chr($i); - self::$_controlCharacters[$find] = $replace; + self::$controlCharacters[$find] = $replace; } } } @@ -107,9 +99,9 @@ private static function _buildControlCharacters() /** * Build SYLK characters array */ - private static function _buildSYLKCharacters() + private static function buildSYLKCharacters() { - self::$_SYLKCharacters = array( + self::$SYLKCharacters = array( "\x1B 0" => chr(0), "\x1B 1" => chr(1), "\x1B 2" => chr(2), @@ -276,14 +268,14 @@ private static function _buildSYLKCharacters() */ public static function getIsMbstringEnabled() { - if (isset(self::$_isMbstringEnabled)) { - return self::$_isMbstringEnabled; + if (isset(self::$isMbstringEnabled)) { + return self::$isMbstringEnabled; } - self::$_isMbstringEnabled = function_exists('mb_convert_encoding') ? + self::$isMbstringEnabled = function_exists('mb_convert_encoding') ? true : false; - return self::$_isMbstringEnabled; + return self::$isMbstringEnabled; } /** @@ -293,47 +285,47 @@ public static function getIsMbstringEnabled() */ public static function getIsIconvEnabled() { - if (isset(self::$_isIconvEnabled)) { - return self::$_isIconvEnabled; + if (isset(self::$isIconvEnabled)) { + return self::$isIconvEnabled; } // Fail if iconv doesn't exist if (!function_exists('iconv')) { - self::$_isIconvEnabled = false; + self::$isIconvEnabled = false; return false; } // Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false, if (!@iconv('UTF-8', 'UTF-16LE', 'x')) { - self::$_isIconvEnabled = false; + self::$isIconvEnabled = false; return false; } // Sometimes iconv_substr('A', 0, 1, 'UTF-8') just returns false in PHP 5.2.0 // we cannot use iconv in that case either (http://bugs.php.net/bug.php?id=37773) if (!@iconv_substr('A', 0, 1, 'UTF-8')) { - self::$_isIconvEnabled = false; + self::$isIconvEnabled = false; return false; } // CUSTOM: IBM AIX iconv() does not work if (defined('PHP_OS') && @stristr(PHP_OS, 'AIX') && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)) { - self::$_isIconvEnabled = false; + self::$isIconvEnabled = false; return false; } // If we reach here no problems were detected with iconv - self::$_isIconvEnabled = true; + self::$isIconvEnabled = true; return true; } public static function buildCharacterSets() { - if (empty(self::$_controlCharacters)) { - self::_buildControlCharacters(); + if (empty(self::$controlCharacters)) { + self::buildControlCharacters(); } - if (empty(self::$_SYLKCharacters)) { - self::_buildSYLKCharacters(); + if (empty(self::$SYLKCharacters)) { + self::buildSYLKCharacters(); } } @@ -353,7 +345,7 @@ public static function buildCharacterSets() */ public static function ControlCharacterOOXML2PHP($value = '') { - return str_replace(array_keys(self::$_controlCharacters), array_values(self::$_controlCharacters), $value); + return str_replace(array_keys(self::$controlCharacters), array_values(self::$controlCharacters), $value); } /** @@ -372,7 +364,7 @@ public static function ControlCharacterOOXML2PHP($value = '') */ public static function ControlCharacterPHP2OOXML($value = '') { - return str_replace(array_values(self::$_controlCharacters), array_keys(self::$_controlCharacters), $value); + return str_replace(array_values(self::$controlCharacters), array_keys(self::$controlCharacters), $value); } /** @@ -701,17 +693,17 @@ public static function convertToNumberIfFraction(&$operand) */ public static function getDecimalSeparator() { - if (!isset(self::$_decimalSeparator)) { + if (!isset(self::$decimalSeparator)) { $localeconv = localeconv(); - self::$_decimalSeparator = ($localeconv['decimal_point'] != '') + self::$decimalSeparator = ($localeconv['decimal_point'] != '') ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point']; - if (self::$_decimalSeparator == '') { + if (self::$decimalSeparator == '') { // Default to . - self::$_decimalSeparator = '.'; + self::$decimalSeparator = '.'; } } - return self::$_decimalSeparator; + return self::$decimalSeparator; } /** @@ -722,7 +714,7 @@ public static function getDecimalSeparator() */ public static function setDecimalSeparator($pValue = '.') { - self::$_decimalSeparator = $pValue; + self::$decimalSeparator = $pValue; } /** @@ -733,17 +725,17 @@ public static function setDecimalSeparator($pValue = '.') */ public static function getThousandsSeparator() { - if (!isset(self::$_thousandsSeparator)) { + if (!isset(self::$thousandsSeparator)) { $localeconv = localeconv(); - self::$_thousandsSeparator = ($localeconv['thousands_sep'] != '') + self::$thousandsSeparator = ($localeconv['thousands_sep'] != '') ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep']; - if (self::$_thousandsSeparator == '') { + if (self::$thousandsSeparator == '') { // Default to . - self::$_thousandsSeparator = ','; + self::$thousandsSeparator = ','; } } - return self::$_thousandsSeparator; + return self::$thousandsSeparator; } /** @@ -754,7 +746,7 @@ public static function getThousandsSeparator() */ public static function setThousandsSeparator($pValue = ',') { - self::$_thousandsSeparator = $pValue; + self::$thousandsSeparator = $pValue; } /** @@ -765,17 +757,17 @@ public static function setThousandsSeparator($pValue = ',') */ public static function getCurrencyCode() { - if (!isset(self::$_currencyCode)) { + if (!isset(self::$currencyCode)) { $localeconv = localeconv(); - self::$_currencyCode = ($localeconv['currency_symbol'] != '') + self::$currencyCode = ($localeconv['currency_symbol'] != '') ? $localeconv['currency_symbol'] : $localeconv['int_curr_symbol']; - if (self::$_currencyCode == '') { + if (self::$currencyCode == '') { // Default to $ - self::$_currencyCode = '$'; + self::$currencyCode = '$'; } } - return self::$_currencyCode; + return self::$currencyCode; } /** @@ -786,7 +778,7 @@ public static function getCurrencyCode() */ public static function setCurrencyCode($pValue = '$') { - self::$_currencyCode = $pValue; + self::$currencyCode = $pValue; } /** @@ -802,7 +794,7 @@ public static function SYLKtoUTF8($pValue = '') return $pValue; } - foreach (self::$_SYLKCharacters as $k => $v) { + foreach (self::$SYLKCharacters as $k => $v) { $pValue = str_replace($k, $v, $pValue); } diff --git a/Classes/PHPExcel/Shared/TimeZone.php b/Classes/PHPExcel/Shared/TimeZone.php index c303eb936..73373e042 100644 --- a/Classes/PHPExcel/Shared/TimeZone.php +++ b/Classes/PHPExcel/Shared/TimeZone.php @@ -42,7 +42,7 @@ class PHPExcel_Shared_TimeZone * @private * @var string */ - protected static $_timezone = 'UTC'; + protected static $timezone = 'UTC'; /** * Validate a Timezone name @@ -67,11 +67,11 @@ public static function _validateTimeZone($timezone) public static function setTimeZone($timezone) { if (self::_validateTimezone($timezone)) { - self::$_timezone = $timezone; + self::$timezone = $timezone; return true; } return false; - } // function setTimezone() + } /** @@ -81,8 +81,8 @@ public static function setTimeZone($timezone) */ public static function getTimeZone() { - return self::$_timezone; - } // function getTimezone() + return self::$timezone; + } /** @@ -92,7 +92,7 @@ public static function getTimeZone() * @param integer $timestamp PHP date/time value for finding the current transition * @return array The current transition details */ - private static function _getTimezoneTransitions($objTimezone, $timestamp) + private static function getTimezoneTransitions($objTimezone, $timestamp) { $allTransitions = $objTimezone->getTransitions(); $transitions = array(); @@ -125,7 +125,7 @@ public static function getTimeZoneAdjustment($timezone, $timestamp) throw new PHPExcel_Exception("Invalid timezone " . $timezone); } } else { - $timezone = self::$_timezone; + $timezone = self::$timezone; } if ($timezone == 'UST') { @@ -136,7 +136,7 @@ public static function getTimeZoneAdjustment($timezone, $timestamp) if (version_compare(PHP_VERSION, '5.3.0') >= 0) { $transitions = $objTimezone->getTransitions($timestamp, $timestamp); } else { - $transitions = self::_getTimezoneTransitions($objTimezone, $timestamp); + $transitions = self::getTimezoneTransitions($objTimezone, $timestamp); } return (count($transitions) > 0) ? $transitions[0]['offset'] : 0; diff --git a/Classes/PHPExcel/Shared/XMLWriter.php b/Classes/PHPExcel/Shared/XMLWriter.php index 7b3b5a162..1dc119b50 100644 --- a/Classes/PHPExcel/Shared/XMLWriter.php +++ b/Classes/PHPExcel/Shared/XMLWriter.php @@ -1,6 +1,15 @@ <?php + +if (!defined('DATE_W3C')) { + define('DATE_W3C', 'Y-m-d\TH:i:sP'); +} + +if (!defined('DEBUGMODE_ENABLED')) { + define('DEBUGMODE_ENABLED', false); +} + /** - * PHPExcel + * PHPExcel_Shared_XMLWriter * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,22 +33,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -if (!defined('DATE_W3C')) { - define('DATE_W3C', 'Y-m-d\TH:i:sP'); -} - -if (!defined('DEBUGMODE_ENABLED')) { - define('DEBUGMODE_ENABLED', false); -} - -/** - * PHPExcel_Shared_XMLWriter - * - * @category PHPExcel - * @package PHPExcel_Shared - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Shared_XMLWriter extends XMLWriter { /** Temporary storage method */ @@ -51,13 +44,13 @@ class PHPExcel_Shared_XMLWriter extends XMLWriter * * @var string */ - private $_tempFileName = ''; + private $tempFileName = ''; /** * Create a new PHPExcel_Shared_XMLWriter instance * - * @param int $pTemporaryStorage Temporary storage location - * @param string $pTemporaryStorageFolder Temporary storage folder + * @param int $pTemporaryStorage Temporary storage location + * @param string $pTemporaryStorageFolder Temporary storage folder */ public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = null) { @@ -69,10 +62,10 @@ public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTempora if ($pTemporaryStorageFolder === null) { $pTemporaryStorageFolder = PHPExcel_Shared_File::sys_get_temp_dir(); } - $this->_tempFileName = @tempnam($pTemporaryStorageFolder, 'xml'); + $this->tempFileName = @tempnam($pTemporaryStorageFolder, 'xml'); // Open storage - if ($this->openUri($this->_tempFileName) === false) { + if ($this->openUri($this->tempFileName) === false) { // Fallback to memory... $this->openMemory(); } @@ -90,8 +83,8 @@ public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTempora public function __destruct() { // Unlink temporary files - if ($this->_tempFileName != '') { - @unlink($this->_tempFileName); + if ($this->tempFileName != '') { + @unlink($this->tempFileName); } } @@ -102,11 +95,11 @@ public function __destruct() */ public function getData() { - if ($this->_tempFileName == '') { + if ($this->tempFileName == '') { return $this->outputMemory(true); } else { $this->flush(); - return file_get_contents($this->_tempFileName); + return file_get_contents($this->tempFileName); } } diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index f795350a1..806a2febd 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -43,14 +43,14 @@ class PHPExcel_Shared_ZipArchive * * @var string */ - private $_tempDir; + private $tempDir; /** * Zip Archive Stream Handle * * @var string */ - private $_zip; + private $zip; /** @@ -61,9 +61,8 @@ class PHPExcel_Shared_ZipArchive */ public function open($fileName) { - $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); - - $this->_zip = new PclZip($fileName); + $this->tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + $this->zip = new PclZip($fileName); return true; } @@ -88,16 +87,16 @@ public function addFromString($localname, $contents) { $filenameParts = pathinfo($localname); - $handle = fopen($this->_tempDir.'/'.$filenameParts["basename"], "wb"); + $handle = fopen($this->tempDir.'/'.$filenameParts["basename"], "wb"); fwrite($handle, $contents); fclose($handle); - $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"]); + $res = $this->zip->add($this->tempDir.'/'.$filenameParts["basename"], PCLZIP_OPT_REMOVE_PATH, $this->tempDir, PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"]); if ($res == 0) { - throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->_zip->errorInfo(true)); + throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->zip->errorInfo(true)); } - unlink($this->_tempDir.'/'.$filenameParts["basename"]); + unlink($this->tempDir.'/'.$filenameParts["basename"]); } /** @@ -108,7 +107,7 @@ public function addFromString($localname, $contents) */ public function locateName($fileName) { - $list = $this->_zip->listContent(); + $list = $this->zip->listContent(); $listCount = count($list); $list_index = -1; for ($i = 0; $i < $listCount; ++$i) { @@ -129,7 +128,7 @@ public function locateName($fileName) */ public function getFromName($fileName) { - $list = $this->_zip->listContent(); + $list = $this->zip->listContent(); $listCount = count($list); $list_index = -1; for ($i = 0; $i < $listCount; ++$i) { @@ -142,7 +141,7 @@ public function getFromName($fileName) $extracted = ""; if ($list_index != -1) { - $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); + $extracted = $this->zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); } else { $filename = substr($fileName, 1); $list_index = -1; @@ -153,7 +152,7 @@ public function getFromName($fileName) break; } } - $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); + $extracted = $this->zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); } if ((is_array($extracted)) && ($extracted != 0)) { $contents = $extracted[0]["content"]; diff --git a/Classes/PHPExcel/Shared/ZipStreamWrapper.php b/Classes/PHPExcel/Shared/ZipStreamWrapper.php index d1c87ac6e..2e0324ce7 100644 --- a/Classes/PHPExcel/Shared/ZipStreamWrapper.php +++ b/Classes/PHPExcel/Shared/ZipStreamWrapper.php @@ -32,28 +32,28 @@ class PHPExcel_Shared_ZipStreamWrapper * * @var ZipArchive */ - private $_archive; + private $archive; /** * Filename in ZipAcrhive * * @var string */ - private $_fileNameInArchive = ''; + private $fileNameInArchive = ''; /** * Position in file * * @var int */ - private $_position = 0; + private $position = 0; /** * Data * * @var mixed */ - private $_data = ''; + private $data = ''; /** * Register wrapper @@ -85,12 +85,12 @@ public function stream_open($path, $mode, $options, &$opened_path) $url['fragment'] = substr($path, $pos + 1); // Open archive - $this->_archive = new ZipArchive(); - $this->_archive->open($url['host']); + $this->archive = new ZipArchive(); + $this->archive->open($url['host']); - $this->_fileNameInArchive = $url['fragment']; - $this->_position = 0; - $this->_data = $this->_archive->getFromName($this->_fileNameInArchive); + $this->fileNameInArchive = $url['fragment']; + $this->position = 0; + $this->data = $this->archive->getFromName($this->fileNameInArchive); return true; } @@ -102,7 +102,7 @@ public function stream_open($path, $mode, $options, &$opened_path) */ public function statName() { - return $this->_fileNameInArchive; + return $this->fileNameInArchive; } /** @@ -112,7 +112,7 @@ public function statName() */ public function url_stat() { - return $this->statName($this->_fileNameInArchive); + return $this->statName($this->fileNameInArchive); } /** @@ -122,7 +122,7 @@ public function url_stat() */ public function stream_stat() { - return $this->_archive->statName($this->_fileNameInArchive); + return $this->archive->statName($this->fileNameInArchive); } /** @@ -133,8 +133,8 @@ public function stream_stat() */ public function stream_read($count) { - $ret = substr($this->_data, $this->_position, $count); - $this->_position += strlen($ret); + $ret = substr($this->data, $this->position, $count); + $this->position += strlen($ret); return $ret; } @@ -146,7 +146,7 @@ public function stream_read($count) */ public function stream_tell() { - return $this->_position; + return $this->position; } /** @@ -156,7 +156,7 @@ public function stream_tell() */ public function stream_eof() { - return $this->_position >= strlen($this->_data); + return $this->position >= strlen($this->data); } /** @@ -170,8 +170,8 @@ public function stream_seek($offset, $whence) { switch ($whence) { case SEEK_SET: - if ($offset < strlen($this->_data) && $offset >= 0) { - $this->_position = $offset; + if ($offset < strlen($this->data) && $offset >= 0) { + $this->position = $offset; return true; } else { return false; @@ -179,15 +179,15 @@ public function stream_seek($offset, $whence) break; case SEEK_CUR: if ($offset >= 0) { - $this->_position += $offset; + $this->position += $offset; return true; } else { return false; } break; case SEEK_END: - if (strlen($this->_data) + $offset >= 0) { - $this->_position = strlen($this->_data) + $offset; + if (strlen($this->data) + $offset >= 0) { + $this->position = strlen($this->data) + $offset; return true; } else { return false; diff --git a/Classes/PHPExcel/Worksheet/BaseDrawing.php b/Classes/PHPExcel/Worksheet/BaseDrawing.php index d63c28213..9ad15c70f 100644 --- a/Classes/PHPExcel/Worksheet/BaseDrawing.php +++ b/Classes/PHPExcel/Worksheet/BaseDrawing.php @@ -46,77 +46,77 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable * * @var string */ - protected $_name; + protected $name; /** * Description * * @var string */ - protected $_description; + protected $description; /** * Worksheet * * @var PHPExcel_Worksheet */ - protected $_worksheet; + protected $worksheet; /** * Coordinates * * @var string */ - protected $_coordinates; + protected $coordinates; /** * Offset X * * @var int */ - protected $_offsetX; + protected $offsetX; /** * Offset Y * * @var int */ - protected $_offsetY; + protected $offsetY; /** * Width * * @var int */ - protected $_width; + protected $width; /** * Height * * @var int */ - protected $_height; + protected $height; /** * Proportional resize * * @var boolean */ - protected $_resizeProportional; + protected $resizeProportional; /** * Rotation * * @var int */ - protected $_rotation; + protected $rotation; /** * Shadow * * @var PHPExcel_Worksheet_Drawing_Shadow */ - protected $_shadow; + protected $shadow; /** * Create a new PHPExcel_Worksheet_BaseDrawing @@ -124,17 +124,17 @@ class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable public function __construct() { // Initialise values - $this->_name = ''; - $this->_description = ''; - $this->_worksheet = null; - $this->_coordinates = 'A1'; - $this->_offsetX = 0; - $this->_offsetY = 0; - $this->_width = 0; - $this->_height = 0; - $this->_resizeProportional = true; - $this->_rotation = 0; - $this->_shadow = new PHPExcel_Worksheet_Drawing_Shadow(); + $this->name = ''; + $this->description = ''; + $this->worksheet = null; + $this->coordinates = 'A1'; + $this->offsetX = 0; + $this->offsetY = 0; + $this->width = 0; + $this->height = 0; + $this->resizeProportional = true; + $this->rotation = 0; + $this->shadow = new PHPExcel_Worksheet_Drawing_Shadow(); // Set image index self::$imageCounter++; @@ -158,7 +158,7 @@ public function getImageIndex() */ public function getName() { - return $this->_name; + return $this->name; } /** @@ -169,7 +169,7 @@ public function getName() */ public function setName($pValue = '') { - $this->_name = $pValue; + $this->name = $pValue; return $this; } @@ -180,7 +180,7 @@ public function setName($pValue = '') */ public function getDescription() { - return $this->_description; + return $this->description; } /** @@ -191,7 +191,7 @@ public function getDescription() */ public function setDescription($pValue = '') { - $this->_description = $pValue; + $this->description = $pValue; return $this; } @@ -202,7 +202,7 @@ public function setDescription($pValue = '') */ public function getWorksheet() { - return $this->_worksheet; + return $this->worksheet; } /** @@ -215,20 +215,20 @@ public function getWorksheet() */ public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = false) { - if (is_null($this->_worksheet)) { + if (is_null($this->worksheet)) { // Add drawing to PHPExcel_Worksheet - $this->_worksheet = $pValue; - $this->_worksheet->getCell($this->_coordinates); - $this->_worksheet->getDrawingCollection()->append($this); + $this->worksheet = $pValue; + $this->worksheet->getCell($this->coordinates); + $this->worksheet->getDrawingCollection()->append($this); } else { if ($pOverrideOld) { // Remove drawing from old PHPExcel_Worksheet - $iterator = $this->_worksheet->getDrawingCollection()->getIterator(); + $iterator = $this->worksheet->getDrawingCollection()->getIterator(); while ($iterator->valid()) { if ($iterator->current()->getHashCode() == $this->getHashCode()) { - $this->_worksheet->getDrawingCollection()->offsetUnset($iterator->key()); - $this->_worksheet = null; + $this->worksheet->getDrawingCollection()->offsetUnset($iterator->key()); + $this->worksheet = null; break; } } @@ -249,7 +249,7 @@ public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = */ public function getCoordinates() { - return $this->_coordinates; + return $this->coordinates; } /** @@ -260,7 +260,7 @@ public function getCoordinates() */ public function setCoordinates($pValue = 'A1') { - $this->_coordinates = $pValue; + $this->coordinates = $pValue; return $this; } @@ -271,7 +271,7 @@ public function setCoordinates($pValue = 'A1') */ public function getOffsetX() { - return $this->_offsetX; + return $this->offsetX; } /** @@ -282,7 +282,7 @@ public function getOffsetX() */ public function setOffsetX($pValue = 0) { - $this->_offsetX = $pValue; + $this->offsetX = $pValue; return $this; } @@ -293,7 +293,7 @@ public function setOffsetX($pValue = 0) */ public function getOffsetY() { - return $this->_offsetY; + return $this->offsetY; } /** @@ -304,7 +304,7 @@ public function getOffsetY() */ public function setOffsetY($pValue = 0) { - $this->_offsetY = $pValue; + $this->offsetY = $pValue; return $this; } @@ -315,7 +315,7 @@ public function setOffsetY($pValue = 0) */ public function getWidth() { - return $this->_width; + return $this->width; } /** @@ -327,13 +327,13 @@ public function getWidth() public function setWidth($pValue = 0) { // Resize proportional? - if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_height / ($this->_width != 0 ? $this->_width : 1); - $this->_height = round($ratio * $pValue); + if ($this->resizeProportional && $pValue != 0) { + $ratio = $this->height / ($this->width != 0 ? $this->width : 1); + $this->height = round($ratio * $pValue); } // Set width - $this->_width = $pValue; + $this->width = $pValue; return $this; } @@ -345,7 +345,7 @@ public function setWidth($pValue = 0) */ public function getHeight() { - return $this->_height; + return $this->height; } /** @@ -357,13 +357,13 @@ public function getHeight() public function setHeight($pValue = 0) { // Resize proportional? - if ($this->_resizeProportional && $pValue != 0) { - $ratio = $this->_width / ($this->_height != 0 ? $this->_height : 1); - $this->_width = round($ratio * $pValue); + if ($this->resizeProportional && $pValue != 0) { + $ratio = $this->width / ($this->height != 0 ? $this->height : 1); + $this->width = round($ratio * $pValue); } // Set height - $this->_height = $pValue; + $this->height = $pValue; return $this; } @@ -383,19 +383,19 @@ public function setHeight($pValue = 0) */ public function setWidthAndHeight($width = 0, $height = 0) { - $xratio = $width / ($this->_width != 0 ? $this->_width : 1); - $yratio = $height / ($this->_height != 0 ? $this->_height : 1); - if ($this->_resizeProportional && !($width == 0 || $height == 0)) { - if (($xratio * $this->_height) < $height) { - $this->_height = ceil($xratio * $this->_height); - $this->_width = $width; + $xratio = $width / ($this->width != 0 ? $this->width : 1); + $yratio = $height / ($this->height != 0 ? $this->height : 1); + if ($this->resizeProportional && !($width == 0 || $height == 0)) { + if (($xratio * $this->height) < $height) { + $this->height = ceil($xratio * $this->height); + $this->width = $width; } else { - $this->_width = ceil($yratio * $this->_width); - $this->_height = $height; + $this->width = ceil($yratio * $this->width); + $this->height = $height; } } else { - $this->_width = $width; - $this->_height = $height; + $this->width = $width; + $this->height = $height; } return $this; @@ -408,7 +408,7 @@ public function setWidthAndHeight($width = 0, $height = 0) */ public function getResizeProportional() { - return $this->_resizeProportional; + return $this->resizeProportional; } /** @@ -419,7 +419,7 @@ public function getResizeProportional() */ public function setResizeProportional($pValue = true) { - $this->_resizeProportional = $pValue; + $this->resizeProportional = $pValue; return $this; } @@ -430,7 +430,7 @@ public function setResizeProportional($pValue = true) */ public function getRotation() { - return $this->_rotation; + return $this->rotation; } /** @@ -441,7 +441,7 @@ public function getRotation() */ public function setRotation($pValue = 0) { - $this->_rotation = $pValue; + $this->rotation = $pValue; return $this; } @@ -452,7 +452,7 @@ public function setRotation($pValue = 0) */ public function getShadow() { - return $this->_shadow; + return $this->shadow; } /** @@ -464,7 +464,7 @@ public function getShadow() */ public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) { - $this->_shadow = $pValue; + $this->shadow = $pValue; return $this; } @@ -476,16 +476,16 @@ public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) public function getHashCode() { return md5( - $this->_name . - $this->_description . - $this->_worksheet->getHashCode() . - $this->_coordinates . - $this->_offsetX . - $this->_offsetY . - $this->_width . - $this->_height . - $this->_rotation . - $this->_shadow->getHashCode() . + $this->name . + $this->description . + $this->worksheet->getHashCode() . + $this->coordinates . + $this->offsetX . + $this->offsetY . + $this->width . + $this->height . + $this->rotation . + $this->shadow->getHashCode() . __CLASS__ ); } diff --git a/Classes/PHPExcel/Worksheet/Drawing.php b/Classes/PHPExcel/Worksheet/Drawing.php index e259c3c31..e39d3eb91 100644 --- a/Classes/PHPExcel/Worksheet/Drawing.php +++ b/Classes/PHPExcel/Worksheet/Drawing.php @@ -103,9 +103,9 @@ public function setPath($pValue = '', $pVerifyFile = true) if (file_exists($pValue)) { $this->path = $pValue; - if ($this->_width == 0 && $this->_height == 0) { + if ($this->width == 0 && $this->height == 0) { // Get width/height - list($this->_width, $this->_height) = getimagesize($pValue); + list($this->width, $this->height) = getimagesize($pValue); } } else { throw new PHPExcel_Exception("File $pValue not found!"); diff --git a/Classes/PHPExcel/Worksheet/MemoryDrawing.php b/Classes/PHPExcel/Worksheet/MemoryDrawing.php index 119a75208..438ed2c58 100644 --- a/Classes/PHPExcel/Worksheet/MemoryDrawing.php +++ b/Classes/PHPExcel/Worksheet/MemoryDrawing.php @@ -104,8 +104,8 @@ public function setImageResource($value = null) if (!is_null($this->imageResource)) { // Get width/height - $this->_width = imagesx($this->imageResource); - $this->_height = imagesy($this->imageResource); + $this->width = imagesx($this->imageResource); + $this->height = imagesy($this->imageResource); } return $this; } From 3dcdba0c6703959877715c75754f47db2d582218 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Fri, 22 May 2015 08:03:34 +0100 Subject: [PATCH 395/467] Another big blast of psr-2 changes. Getting close to the finishing line now --- Classes/PHPExcel/Calculation.php | 10 +- Classes/PHPExcel/Writer/Abstract.php | 6 +- Classes/PHPExcel/Writer/CSV.php | 6 +- Classes/PHPExcel/Writer/Excel2007.php | 168 +++++++-------- Classes/PHPExcel/Writer/Excel2007/Chart.php | 79 ++++--- .../PHPExcel/Writer/Excel2007/Comments.php | 12 +- .../Writer/Excel2007/ContentTypes.php | 62 +++--- .../PHPExcel/Writer/Excel2007/DocProps.php | 13 +- Classes/PHPExcel/Writer/Excel2007/Drawing.php | 12 +- Classes/PHPExcel/Writer/Excel2007/Rels.php | 53 ++--- .../PHPExcel/Writer/Excel2007/RelsRibbon.php | 17 +- Classes/PHPExcel/Writer/Excel2007/RelsVBA.php | 17 +- .../PHPExcel/Writer/Excel2007/StringTable.php | 15 +- Classes/PHPExcel/Writer/Excel2007/Style.php | 64 +++--- Classes/PHPExcel/Writer/Excel2007/Theme.php | 18 +- .../PHPExcel/Writer/Excel2007/Workbook.php | 64 +++--- .../PHPExcel/Writer/Excel2007/Worksheet.php | 88 ++++---- .../PHPExcel/Writer/Excel2007/WriterPart.php | 22 +- Classes/PHPExcel/Writer/Excel5.php | 2 +- Classes/PHPExcel/Writer/Excel5/BIFFwriter.php | 8 +- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 196 +++++++++--------- Classes/PHPExcel/Writer/HTML.php | 2 +- 22 files changed, 410 insertions(+), 524 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 3413ac894..307db191b 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2841,17 +2841,17 @@ private static function checkMatrixOperands(&$operand1, &$operand2, $resize = 1) // Examine each of the two operands, and turn them into an array if they aren't one already // Note that this function should only be called if one or both of the operand is already an array if (!is_array($operand1)) { - list($matrixRows, $matrixColumns) = self::_getMatrixDimensions($operand2); + list($matrixRows, $matrixColumns) = self::getMatrixDimensions($operand2); $operand1 = array_fill(0, $matrixRows, array_fill(0, $matrixColumns, $operand1)); $resize = 0; } elseif (!is_array($operand2)) { - list($matrixRows, $matrixColumns) = self::_getMatrixDimensions($operand1); + list($matrixRows, $matrixColumns) = self::getMatrixDimensions($operand1); $operand2 = array_fill(0, $matrixRows, array_fill(0, $matrixColumns, $operand2)); $resize = 0; } - list($matrix1Rows, $matrix1Columns) = self::_getMatrixDimensions($operand1); - list($matrix2Rows, $matrix2Columns) = self::_getMatrixDimensions($operand2); + list($matrix1Rows, $matrix1Columns) = self::getMatrixDimensions($operand1); + list($matrix2Rows, $matrix2Columns) = self::getMatrixDimensions($operand2); if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { $resize = 1; } @@ -2873,7 +2873,7 @@ private static function checkMatrixOperands(&$operand1, &$operand2, $resize = 1) * @param mixed &$matrix matrix operand * @return array An array comprising the number of rows, and number of columns */ - public static function _getMatrixDimensions(&$matrix) + private static function getMatrixDimensions(&$matrix) { $matrixRows = count($matrix); $matrixColumns = 0; diff --git a/Classes/PHPExcel/Writer/Abstract.php b/Classes/PHPExcel/Writer/Abstract.php index e6e130de0..2a797a948 100644 --- a/Classes/PHPExcel/Writer/Abstract.php +++ b/Classes/PHPExcel/Writer/Abstract.php @@ -42,7 +42,7 @@ abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter * * @var boolean */ - protected $_preCalculateFormulas = true; + protected $preCalculateFormulas = true; /** * Use disk caching where possible? @@ -96,7 +96,7 @@ public function setIncludeCharts($pValue = false) */ public function getPreCalculateFormulas() { - return $this->_preCalculateFormulas; + return $this->preCalculateFormulas; } /** @@ -109,7 +109,7 @@ public function getPreCalculateFormulas() */ public function setPreCalculateFormulas($pValue = true) { - $this->_preCalculateFormulas = (boolean) $pValue; + $this->preCalculateFormulas = (boolean) $pValue; return $this; } diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php index 90c5cc08b..31ca874b6 100644 --- a/Classes/PHPExcel/Writer/CSV.php +++ b/Classes/PHPExcel/Writer/CSV.php @@ -126,9 +126,9 @@ public function save($pFilename = null) // Write rows to file for ($row = 1; $row <= $maxRow; ++$row) { // Convert the row to an array... - $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row, '', $this->_preCalculateFormulas); + $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row, '', $this->preCalculateFormulas); // ... and write to the file - $this->_writeLine($fileHandle, $cellsArray[0]); + $this->writeLine($fileHandle, $cellsArray[0]); } // Close file @@ -281,7 +281,7 @@ public function setSheetIndex($pValue = 0) * @param array $pValues Array containing values in a row * @throws PHPExcel_Writer_Exception */ - private function _writeLine($pFileHandle = null, $pValues = null) + private function writeLine($pFileHandle = null, $pValues = null) { if (is_array($pValues)) { // No leading delimiter diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index 5b812cc1e..8f2eaa000 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -36,84 +36,84 @@ class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPE * * @var boolean */ - protected $_preCalculateFormulas = false; + protected $preCalculateFormulas = false; /** * Office2003 compatibility * * @var boolean */ - private $_office2003compatibility = false; + private $office2003compatibility = false; /** * Private writer parts * * @var PHPExcel_Writer_Excel2007_WriterPart[] */ - private $_writerParts = array(); + private $writerParts = array(); /** * Private PHPExcel * * @var PHPExcel */ - private $_spreadSheet; + private $spreadSheet; /** * Private string table * * @var string[] */ - private $_stringTable = array(); + private $stringTable = array(); /** * Private unique PHPExcel_Style_Conditional HashTable * * @var PHPExcel_HashTable */ - private $_stylesConditionalHashTable; + private $stylesConditionalHashTable; /** * Private unique PHPExcel_Style HashTable * * @var PHPExcel_HashTable */ - private $_styleHashTable; + private $styleHashTable; /** * Private unique PHPExcel_Style_Fill HashTable * * @var PHPExcel_HashTable */ - private $_fillHashTable; + private $fillHashTable; /** * Private unique PHPExcel_Style_Font HashTable * * @var PHPExcel_HashTable */ - private $_fontHashTable; + private $fontHashTable; /** * Private unique PHPExcel_Style_Borders HashTable * * @var PHPExcel_HashTable */ - private $_bordersHashTable ; + private $bordersHashTable ; /** * Private unique PHPExcel_Style_NumberFormat HashTable * * @var PHPExcel_HashTable */ - private $_numFmtHashTable; + private $numFmtHashTable; /** * Private unique PHPExcel_Worksheet_BaseDrawing HashTable * * @var PHPExcel_HashTable */ - private $_drawingHashTable; + private $drawingHashTable; /** * Create a new PHPExcel_Writer_Excel2007 @@ -143,12 +143,12 @@ public function __construct(PHPExcel $pPHPExcel = null) // Initialise writer parts // and Assign their parent IWriters foreach ($writerPartsArray as $writer => $class) { - $this->_writerParts[$writer] = new $class($this); + $this->writerParts[$writer] = new $class($this); } - $hashTablesArray = array( '_stylesConditionalHashTable', '_fillHashTable', '_fontHashTable', - '_bordersHashTable', '_numFmtHashTable', '_drawingHashTable', - '_styleHashTable' + $hashTablesArray = array( 'stylesConditionalHashTable', 'fillHashTable', 'fontHashTable', + 'bordersHashTable', 'numFmtHashTable', 'drawingHashTable', + 'styleHashTable' ); // Set HashTable variables @@ -165,8 +165,8 @@ public function __construct(PHPExcel $pPHPExcel = null) */ public function getWriterPart($pPartName = '') { - if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) { - return $this->_writerParts[strtolower($pPartName)]; + if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) { + return $this->writerParts[strtolower($pPartName)]; } else { return null; } @@ -180,9 +180,9 @@ public function getWriterPart($pPartName = '') */ public function save($pFilename = null) { - if ($this->_spreadSheet !== null) { + if ($this->spreadSheet !== null) { // garbage collect - $this->_spreadSheet->garbageCollect(); + $this->spreadSheet->garbageCollect(); // If $pFilename is php://output or php://stdout, make it a temporary file... $originalFilename = $pFilename; @@ -193,27 +193,27 @@ public function save($pFilename = null) } } - $saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->getWriteDebugLog(); - PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(false); + $saveDebugLog = PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog(false); $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); // Create string lookup table - $this->_stringTable = array(); - for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { - $this->_stringTable = $this->getWriterPart('StringTable')->createStringTable($this->_spreadSheet->getSheet($i), $this->_stringTable); + $this->stringTable = array(); + for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { + $this->stringTable = $this->getWriterPart('StringTable')->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable); } // Create styles dictionaries - $this->_styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->_spreadSheet)); - $this->_stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->_spreadSheet)); - $this->_fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->_spreadSheet)); - $this->_fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->_spreadSheet)); - $this->_bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->_spreadSheet)); - $this->_numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->_spreadSheet)); + $this->styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->spreadSheet)); + $this->stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->spreadSheet)); + $this->fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->spreadSheet)); + $this->fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->spreadSheet)); + $this->bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->spreadSheet)); + $this->numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->spreadSheet)); // Create drawing dictionary - $this->_drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->_spreadSheet)); + $this->drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->spreadSheet)); // Create new ZIP file and open it for writing $zipClass = PHPExcel_Settings::getZipClass(); @@ -236,65 +236,65 @@ public function save($pFilename = null) } // Add [Content_Types].xml to ZIP file - $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->includeCharts)); + $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->spreadSheet, $this->includeCharts)); //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) - if ($this->_spreadSheet->hasMacros()) { - $macrosCode=$this->_spreadSheet->getMacrosCode(); + if ($this->spreadSheet->hasMacros()) { + $macrosCode=$this->spreadSheet->getMacrosCode(); if (!is_null($macrosCode)) {// we have the code ? $objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin - if ($this->_spreadSheet->hasMacrosCertificate()) {//signed macros ? + if ($this->spreadSheet->hasMacrosCertificate()) {//signed macros ? // Yes : add the certificate file and the related rels file - $objZip->addFromString('xl/vbaProjectSignature.bin', $this->_spreadSheet->getMacrosCertificate()); - $objZip->addFromString('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->_spreadSheet)); + $objZip->addFromString('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate()); + $objZip->addFromString('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->spreadSheet)); } } } //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) - if ($this->_spreadSheet->hasRibbon()) { - $tmpRibbonTarget=$this->_spreadSheet->getRibbonXMLData('target'); - $objZip->addFromString($tmpRibbonTarget, $this->_spreadSheet->getRibbonXMLData('data')); - if ($this->_spreadSheet->hasRibbonBinObjects()) { + if ($this->spreadSheet->hasRibbon()) { + $tmpRibbonTarget=$this->spreadSheet->getRibbonXMLData('target'); + $objZip->addFromString($tmpRibbonTarget, $this->spreadSheet->getRibbonXMLData('data')); + if ($this->spreadSheet->hasRibbonBinObjects()) { $tmpRootPath=dirname($tmpRibbonTarget).'/'; - $ribbonBinObjects=$this->_spreadSheet->getRibbonBinObjects('data');//the files to write + $ribbonBinObjects=$this->spreadSheet->getRibbonBinObjects('data');//the files to write foreach ($ribbonBinObjects as $aPath => $aContent) { $objZip->addFromString($tmpRootPath.$aPath, $aContent); } //the rels for files - $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->_spreadSheet)); + $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet)); } } // Add relationships to ZIP file - $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->_spreadSheet)); - $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->_spreadSheet)); + $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet)); + $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet)); // Add document properties to ZIP file - $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->_spreadSheet)); - $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->_spreadSheet)); - $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->_spreadSheet); + $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet)); + $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet)); + $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet); if ($customPropertiesPart !== null) { $objZip->addFromString('docProps/custom.xml', $customPropertiesPart); } // Add theme to ZIP file - $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->_spreadSheet)); + $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet)); // Add string table to ZIP file - $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->_stringTable)); + $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable)); // Add styles to ZIP file - $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->_spreadSheet)); + $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet)); // Add workbook to ZIP file - $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->_spreadSheet, $this->_preCalculateFormulas)); + $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas)); $chartCount = 0; // Add worksheets - for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { - $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->_spreadSheet->getSheet($i), $this->_stringTable, $this->includeCharts)); + for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { + $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts)); if ($this->includeCharts) { - $charts = $this->_spreadSheet->getSheet($i)->getChartCollection(); + $charts = $this->spreadSheet->getSheet($i)->getChartCollection(); if (count($charts) > 0) { foreach ($charts as $chart) { $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart)); @@ -306,44 +306,44 @@ public function save($pFilename = null) $chartRef1 = $chartRef2 = 0; // Add worksheet relationships (drawings, ...) - for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { + for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { // Add relationships - $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->_spreadSheet->getSheet($i), ($i + 1), $this->includeCharts)); + $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts)); - $drawings = $this->_spreadSheet->getSheet($i)->getDrawingCollection(); + $drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection(); $drawingCount = count($drawings); if ($this->includeCharts) { - $chartCount = $this->_spreadSheet->getSheet($i)->getChartCount(); + $chartCount = $this->spreadSheet->getSheet($i)->getChartCount(); } // Add drawing and image relationship parts if (($drawingCount > 0) || ($chartCount > 0)) { // Drawing relationships - $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->_spreadSheet->getSheet($i), $chartRef1, $this->includeCharts)); + $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts)); // Drawings - $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->_spreadSheet->getSheet($i), $chartRef2, $this->includeCharts)); + $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $chartRef2, $this->includeCharts)); } // Add comment relationship parts - if (count($this->_spreadSheet->getSheet($i)->getComments()) > 0) { + if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) { // VML Comments - $objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->_spreadSheet->getSheet($i))); + $objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i))); // Comments - $objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->_spreadSheet->getSheet($i))); + $objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i))); } // Add header/footer relationship parts - if (count($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { + if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { // VML Drawings - $objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->_spreadSheet->getSheet($i))); + $objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i))); // VML Drawing relationships - $objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->_spreadSheet->getSheet($i))); + $objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i))); // Media - foreach ($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) { + foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) { $objZip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath())); } } @@ -382,7 +382,7 @@ public function save($pFilename = null) } PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); - PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); + PHPExcel_Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); // Close file if ($objZip->close() === false) { @@ -409,10 +409,10 @@ public function save($pFilename = null) */ public function getPHPExcel() { - if ($this->_spreadSheet !== null) { - return $this->_spreadSheet; + if ($this->spreadSheet !== null) { + return $this->spreadSheet; } else { - throw new PHPExcel_Writer_Exception("No PHPExcel assigned."); + throw new PHPExcel_Writer_Exception("No PHPExcel object assigned."); } } @@ -425,7 +425,7 @@ public function getPHPExcel() */ public function setPHPExcel(PHPExcel $pPHPExcel = null) { - $this->_spreadSheet = $pPHPExcel; + $this->spreadSheet = $pPHPExcel; return $this; } @@ -436,7 +436,7 @@ public function setPHPExcel(PHPExcel $pPHPExcel = null) */ public function getStringTable() { - return $this->_stringTable; + return $this->stringTable; } /** @@ -446,7 +446,7 @@ public function getStringTable() */ public function getStyleHashTable() { - return $this->_styleHashTable; + return $this->styleHashTable; } /** @@ -456,7 +456,7 @@ public function getStyleHashTable() */ public function getStylesConditionalHashTable() { - return $this->_stylesConditionalHashTable; + return $this->stylesConditionalHashTable; } /** @@ -466,7 +466,7 @@ public function getStylesConditionalHashTable() */ public function getFillHashTable() { - return $this->_fillHashTable; + return $this->fillHashTable; } /** @@ -476,7 +476,7 @@ public function getFillHashTable() */ public function getFontHashTable() { - return $this->_fontHashTable; + return $this->fontHashTable; } /** @@ -486,7 +486,7 @@ public function getFontHashTable() */ public function getBordersHashTable() { - return $this->_bordersHashTable; + return $this->bordersHashTable; } /** @@ -496,7 +496,7 @@ public function getBordersHashTable() */ public function getNumFmtHashTable() { - return $this->_numFmtHashTable; + return $this->numFmtHashTable; } /** @@ -506,7 +506,7 @@ public function getNumFmtHashTable() */ public function getDrawingHashTable() { - return $this->_drawingHashTable; + return $this->drawingHashTable; } /** @@ -516,7 +516,7 @@ public function getDrawingHashTable() */ public function getOffice2003Compatibility() { - return $this->_office2003compatibility; + return $this->office2003compatibility; } /** @@ -527,7 +527,7 @@ public function getOffice2003Compatibility() */ public function setOffice2003Compatibility($pValue = false) { - $this->_office2003compatibility = $pValue; + $this->office2003compatibility = $pValue; return $this; } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index 8afa52f2e..ebe0018f2 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_Chart * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Writer_Excel2007_Chart - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPart { /** @@ -73,19 +66,19 @@ public function writeChart(PHPExcel_Chart $pChart = null) $objWriter->writeAttribute('val', 0); $objWriter->endElement(); - $this->_writeAlternateContent($objWriter); + $this->writeAlternateContent($objWriter); $objWriter->startElement('c:chart'); - $this->_writeTitle($pChart->getTitle(), $objWriter); + $this->writeTitle($pChart->getTitle(), $objWriter); $objWriter->startElement('c:autoTitleDeleted'); $objWriter->writeAttribute('val', 0); $objWriter->endElement(); - $this->_writePlotArea($pChart->getPlotArea(), $pChart->getXAxisLabel(), $pChart->getYAxisLabel(), $objWriter, $pChart->getWorksheet(), $pChart->getChartAxisX(), $pChart->getChartAxisY(), $pChart->getMajorGridlines(), $pChart->getMinorGridlines()); + $this->writePlotArea($pChart->getPlotArea(), $pChart->getXAxisLabel(), $pChart->getYAxisLabel(), $objWriter, $pChart->getWorksheet(), $pChart->getChartAxisX(), $pChart->getChartAxisY(), $pChart->getMajorGridlines(), $pChart->getMinorGridlines()); - $this->_writeLegend($pChart->getLegend(), $objWriter); + $this->writeLegend($pChart->getLegend(), $objWriter); $objWriter->startElement('c:plotVisOnly'); $objWriter->writeAttribute('val', 1); @@ -101,7 +94,7 @@ public function writeChart(PHPExcel_Chart $pChart = null) $objWriter->endElement(); - $this->_writePrintSettings($objWriter); + $this->writePrintSettings($objWriter); $objWriter->endElement(); @@ -117,7 +110,7 @@ public function writeChart(PHPExcel_Chart $pChart = null) * * @throws PHPExcel_Writer_Exception */ - private function _writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) + private function writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) { if (is_null($title)) { return; @@ -145,7 +138,7 @@ private function _writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) $objWriter->endElement(); $objWriter->endElement(); - $this->_writeLayout($title->getLayout(), $objWriter); + $this->writeLayout($title->getLayout(), $objWriter); $objWriter->startElement('c:overlay'); $objWriter->writeAttribute('val', 0); @@ -162,7 +155,7 @@ private function _writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) * * @throws PHPExcel_Writer_Exception */ - private function _writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) + private function writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) { if (is_null($legend)) { return; @@ -174,7 +167,7 @@ private function _writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) $objWriter->writeAttribute('val', $legend->getPosition()); $objWriter->endElement(); - $this->_writeLayout($legend->getLayout(), $objWriter); + $this->writeLayout($legend->getLayout(), $objWriter); $objWriter->startElement('c:overlay'); $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0'); @@ -217,7 +210,7 @@ private function _writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) * * @throws PHPExcel_Writer_Exception */ - private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, $objWriter, PHPExcel_Worksheet $pSheet, PHPExcel_Chart_Axis $xAxis, PHPExcel_Chart_Axis $yAxis, PHPExcel_Chart_GridLines $majorGridlines, PHPExcel_Chart_GridLines $minorGridlines) + private function writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, $objWriter, PHPExcel_Worksheet $pSheet, PHPExcel_Chart_Axis $xAxis, PHPExcel_Chart_Axis $yAxis, PHPExcel_Chart_GridLines $majorGridlines, PHPExcel_Chart_GridLines $minorGridlines) { if (is_null($plotArea)) { return; @@ -229,9 +222,9 @@ private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Char $layout = $plotArea->getLayout(); - $this->_writeLayout($layout, $objWriter); + $this->writeLayout($layout, $objWriter); - $chartTypes = self::_getChartType($plotArea); + $chartTypes = self::getChartType($plotArea); $catIsMultiLevelSeries = $valIsMultiLevelSeries = false; $plotGroupingType = ''; foreach ($chartTypes as $chartType) { @@ -253,11 +246,11 @@ private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Char $objWriter->endElement(); } - $this->_writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet); + $this->writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet); } } - $this->_writeDataLbls($objWriter, $layout); + $this->writeDataLabels($objWriter, $layout); if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) { // Line only, Line3D can't be smoothed @@ -334,12 +327,12 @@ private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Char if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { if ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $this->_writeValAx($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); + $this->writeValueAxis($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); } else { - $this->_writeCatAx($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis); + $this->writeCategoryAxis($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis); } - $this->_writeValAx($objWriter, $plotArea, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); + $this->writeValueAxis($objWriter, $plotArea, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines); } $objWriter->endElement(); @@ -353,7 +346,7 @@ private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, PHPExcel_Char * * @throws PHPExcel_Writer_Exception */ - private function _writeDataLbls($objWriter, $chartLayout) + private function writeDataLabels($objWriter, $chartLayout) { $objWriter->startElement('c:dLbls'); @@ -408,7 +401,7 @@ private function _writeDataLbls($objWriter, $chartLayout) * * @throws PHPExcel_Writer_Exception */ - private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis) + private function writeCategoryAxis($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis) { $objWriter->startElement('c:catAx'); @@ -461,7 +454,7 @@ private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAx $objWriter->endElement(); $layout = $xAxisLabel->getLayout(); - $this->_writeLayout($layout, $objWriter); + $this->writeLayout($layout, $objWriter); $objWriter->startElement('c:overlay'); $objWriter->writeAttribute('val', 0); @@ -530,7 +523,7 @@ private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAx * * @throws PHPExcel_Writer_Exception */ - private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines) + private function writeValueAxis($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines) { $objWriter->startElement('c:valAx'); @@ -811,7 +804,7 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { $layout = $yAxisLabel->getLayout(); - $this->_writeLayout($layout, $objWriter); + $this->writeLayout($layout, $objWriter); } $objWriter->startElement('c:overlay'); @@ -1011,7 +1004,7 @@ private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAx * @return string|array * @throws PHPExcel_Writer_Exception */ - private static function _getChartType($plotArea) + private static function getChartType($plotArea) { $groupCount = $plotArea->getPlotGroupCount(); @@ -1044,7 +1037,7 @@ private static function _getChartType($plotArea) * * @throws PHPExcel_Writer_Exception */ - private function _writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType, PHPExcel_Worksheet $pSheet) + private function writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType, PHPExcel_Worksheet $pSheet) { if (is_null($plotGroup)) { return; @@ -1117,7 +1110,7 @@ private function _writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMult if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) { $objWriter->startElement('c:tx'); $objWriter->startElement('c:strRef'); - $this->_writePlotSeriesLabel($plotSeriesLabel, $objWriter); + $this->writePlotSeriesLabel($plotSeriesLabel, $objWriter); $objWriter->endElement(); $objWriter->endElement(); } @@ -1182,7 +1175,7 @@ private function _writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMult $objWriter->startElement('c:cat'); } - $this->_writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet); + $this->writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet); $objWriter->endElement(); } @@ -1196,12 +1189,12 @@ private function _writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMult $objWriter->startElement('c:val'); } - $this->_writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet); + $this->writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet); $objWriter->endElement(); } if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { - $this->_writeBubbles($plotSeriesValues, $objWriter, $pSheet); + $this->writeBubbles($plotSeriesValues, $objWriter, $pSheet); } $objWriter->endElement(); @@ -1218,7 +1211,7 @@ private function _writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMult * * @throws PHPExcel_Writer_Exception */ - private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) + private function writePlotSeriesLabel($plotSeriesLabel, $objWriter) { if (is_null($plotSeriesLabel)) { return; @@ -1256,7 +1249,7 @@ private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) * * @throws PHPExcel_Writer_Exception */ - private function _writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, $dataType = 'str', PHPExcel_Worksheet $pSheet) + private function writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, $dataType = 'str', PHPExcel_Worksheet $pSheet) { if (is_null($plotSeriesValues)) { return; @@ -1348,7 +1341,7 @@ private function _writePlotSeriesValues($plotSeriesValues, $objWriter, $groupTyp * * @throws PHPExcel_Writer_Exception */ - private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) + private function writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) { if (is_null($plotSeriesValues)) { return; @@ -1395,7 +1388,7 @@ private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet * * @throws PHPExcel_Writer_Exception */ - private function _writeLayout(PHPExcel_Chart_Layout $layout = null, $objWriter) + private function writeLayout(PHPExcel_Chart_Layout $layout = null, $objWriter) { $objWriter->startElement('c:layout'); @@ -1464,7 +1457,7 @@ private function _writeLayout(PHPExcel_Chart_Layout $layout = null, $objWriter) * * @throws PHPExcel_Writer_Exception */ - private function _writeAlternateContent($objWriter) + private function writeAlternateContent($objWriter) { $objWriter->startElement('mc:AlternateContent'); $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); @@ -1494,7 +1487,7 @@ private function _writeAlternateContent($objWriter) * * @throws PHPExcel_Writer_Exception */ - private function _writePrintSettings($objWriter) + private function writePrintSettings($objWriter) { $objWriter->startElement('c:printSettings'); diff --git a/Classes/PHPExcel/Writer/Excel2007/Comments.php b/Classes/PHPExcel/Writer/Excel2007/Comments.php index 95336e863..ee18e7941 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Comments.php +++ b/Classes/PHPExcel/Writer/Excel2007/Comments.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_Comments * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_Comments - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_Comments extends PHPExcel_Writer_Excel2007_WriterPart { /** diff --git a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php index c441ef11b..0d9118990 100644 --- a/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php +++ b/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_ContentTypes * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_ContentTypes - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_ContentTypes extends PHPExcel_Writer_Excel2007_WriterPart { /** @@ -61,52 +53,52 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types'); // Theme - $this->_writeOverrideContentType($objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml'); + $this->writeOverrideContentType($objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml'); // Styles - $this->_writeOverrideContentType($objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'); + $this->writeOverrideContentType($objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'); // Rels - $this->_writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml'); + $this->writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml'); // XML - $this->_writeDefaultContentType($objWriter, 'xml', 'application/xml'); + $this->writeDefaultContentType($objWriter, 'xml', 'application/xml'); // VML - $this->_writeDefaultContentType($objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'); + $this->writeDefaultContentType($objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'); // Workbook if ($pPHPExcel->hasMacros()) { //Macros in workbook ? // Yes : not standard content but "macroEnabled" - $this->_writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml'); + $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml'); //... and define a new type for the VBA project - $this->_writeDefaultContentType($objWriter, 'bin', 'application/vnd.ms-office.vbaProject'); + $this->writeDefaultContentType($objWriter, 'bin', 'application/vnd.ms-office.vbaProject'); if ($pPHPExcel->hasMacrosCertificate()) {// signed macros ? // Yes : add needed information - $this->_writeOverrideContentType($objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature'); + $this->writeOverrideContentType($objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature'); } } else {// no macros in workbook, so standard type - $this->_writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'); + $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'); } // DocProps - $this->_writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml'); + $this->writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml'); - $this->_writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml'); + $this->writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml'); $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); if (!empty($customPropertyList)) { - $this->_writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml'); + $this->writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml'); } // Worksheets $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { - $this->_writeOverrideContentType($objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'); + $this->writeOverrideContentType($objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'); } // Shared strings - $this->_writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'); + $this->writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'); // Add worksheet relationship content types $chart = 1; @@ -117,13 +109,13 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f // We need a drawing relationship for the worksheet if we have either drawings or charts if (($drawingCount > 0) || ($chartCount > 0)) { - $this->_writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml'); + $this->writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml'); } // If we have charts, then we need a chart relationship for every individual chart if ($chartCount > 0) { for ($c = 0; $c < $chartCount; ++$c) { - $this->_writeOverrideContentType($objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); + $this->writeOverrideContentType($objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); } } } @@ -131,7 +123,7 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f // Comments for ($i = 0; $i < $sheetCount; ++$i) { if (count($pPHPExcel->getSheet($i)->getComments()) > 0) { - $this->_writeOverrideContentType($objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'); + $this->writeOverrideContentType($objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'); } } @@ -144,7 +136,7 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); - $mimeType = $this->_getImageMimeType($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath()); + $mimeType = $this->getImageMimeType($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath()); } elseif ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); $extension = explode('/', $extension); @@ -156,7 +148,7 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f if (!isset( $aMediaContentTypes[$extension])) { $aMediaContentTypes[$extension] = $mimeType; - $this->_writeDefaultContentType($objWriter, $extension, $mimeType); + $this->writeDefaultContentType($objWriter, $extension, $mimeType); } } if ($pPHPExcel->hasRibbonBinObjects()) { @@ -165,7 +157,7 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); foreach ($tabRibbonTypes as $aRibbonType) { $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor - $this->_writeDefaultContentType($objWriter, $aRibbonType, $mimeType); + $this->writeDefaultContentType($objWriter, $aRibbonType, $mimeType); } } $sheetCount = $pPHPExcel->getSheetCount(); @@ -173,9 +165,9 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) { foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) { if (!isset( $aMediaContentTypes[strtolower($image->getExtension())])) { - $aMediaContentTypes[strtolower($image->getExtension())] = $this->_getImageMimeType($image->getPath()); + $aMediaContentTypes[strtolower($image->getExtension())] = $this->getImageMimeType($image->getPath()); - $this->_writeDefaultContentType($objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())]); + $this->writeDefaultContentType($objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())]); } } } @@ -194,7 +186,7 @@ public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = f * @return string Mime Type * @throws PHPExcel_Writer_Exception */ - private function _getImageMimeType($pFile = '') + private function getImageMimeType($pFile = '') { if (PHPExcel_Shared_File::file_exists($pFile)) { $image = getimagesize($pFile); @@ -212,7 +204,7 @@ private function _getImageMimeType($pFile = '') * @param string $pContentType Content type * @throws PHPExcel_Writer_Exception */ - private function _writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') + private function writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') { if ($pPartname != '' && $pContentType != '') { // Write content type @@ -233,7 +225,7 @@ private function _writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = * @param string $pContentType Content type * @throws PHPExcel_Writer_Exception */ - private function _writeOverrideContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') + private function writeOverrideContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') { if ($pPartname != '' && $pContentType != '') { // Write content type diff --git a/Classes/PHPExcel/Writer/Excel2007/DocProps.php b/Classes/PHPExcel/Writer/Excel2007/DocProps.php index 6ef50d3bf..fef3d9371 100644 --- a/Classes/PHPExcel/Writer/Excel2007/DocProps.php +++ b/Classes/PHPExcel/Writer/Excel2007/DocProps.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_DocProps * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_DocProps - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_DocProps extends PHPExcel_Writer_Excel2007_WriterPart { /** @@ -265,7 +257,6 @@ public function writeDocPropsCustom(PHPExcel $pPHPExcel = null) $objWriter->endElement(); - // Return return $objWriter->getData(); } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Drawing.php b/Classes/PHPExcel/Writer/Excel2007/Drawing.php index 794d6a4bb..9b2779f7a 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Drawing.php +++ b/Classes/PHPExcel/Writer/Excel2007/Drawing.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_Drawing * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_Drawing - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_Drawing extends PHPExcel_Writer_Excel2007_WriterPart { /** diff --git a/Classes/PHPExcel/Writer/Excel2007/Rels.php b/Classes/PHPExcel/Writer/Excel2007/Rels.php index 5e8abe696..dd1faf9b1 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Rels.php +++ b/Classes/PHPExcel/Writer/Excel2007/Rels.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_Rels * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_Rels - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_Rels extends PHPExcel_Writer_Excel2007_WriterPart { /** @@ -62,7 +54,7 @@ public function writeRelationships(PHPExcel $pPHPExcel = null) $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); if (!empty($customPropertyList)) { // Relationship docProps/app.xml - $this->_writeRelationship( + $this->writeRelationship( $objWriter, 4, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties', @@ -72,7 +64,7 @@ public function writeRelationships(PHPExcel $pPHPExcel = null) } // Relationship docProps/app.xml - $this->_writeRelationship( + $this->writeRelationship( $objWriter, 3, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties', @@ -80,7 +72,7 @@ public function writeRelationships(PHPExcel $pPHPExcel = null) ); // Relationship docProps/core.xml - $this->_writeRelationship( + $this->writeRelationship( $objWriter, 2, 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', @@ -88,7 +80,7 @@ public function writeRelationships(PHPExcel $pPHPExcel = null) ); // Relationship xl/workbook.xml - $this->_writeRelationship( + $this->writeRelationship( $objWriter, 1, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', @@ -106,7 +98,6 @@ public function writeRelationships(PHPExcel $pPHPExcel = null) $objWriter->endElement(); - // Return return $objWriter->getData(); } @@ -135,7 +126,7 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); // Relationship styles.xml - $this->_writeRelationship( + $this->writeRelationship( $objWriter, 1, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles', @@ -143,7 +134,7 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) ); // Relationship theme/theme1.xml - $this->_writeRelationship( + $this->writeRelationship( $objWriter, 2, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', @@ -151,7 +142,7 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) ); // Relationship sharedStrings.xml - $this->_writeRelationship( + $this->writeRelationship( $objWriter, 3, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', @@ -161,7 +152,7 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) // Relationships with sheets $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { - $this->_writeRelationship( + $this->writeRelationship( $objWriter, ($i + 1 + 3), 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', @@ -182,7 +173,6 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) $objWriter->endElement(); - // Return return $objWriter->getData(); } @@ -225,7 +215,7 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul } if (($pWorksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0)) { - $this->_writeRelationship( + $this->writeRelationship( $objWriter, ++$d, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', @@ -239,7 +229,7 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul // echo 'Chart Rels: ' , count($charts) , '<br />'; // if (count($charts) > 0) { // foreach ($charts as $chart) { -// $this->_writeRelationship( +// $this->writeRelationship( // $objWriter, // ++$d, // 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', @@ -252,7 +242,7 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul $i = 1; foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) { if (!$hyperlink->isInternal()) { - $this->_writeRelationship( + $this->writeRelationship( $objWriter, '_hyperlink_' . $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', @@ -267,14 +257,14 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul // Write comments relationship? $i = 1; if (count($pWorksheet->getComments()) > 0) { - $this->_writeRelationship( + $this->writeRelationship( $objWriter, '_comments_vml' . $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', '../drawings/vmlDrawing' . $pWorksheetId . '.vml' ); - $this->_writeRelationship( + $this->writeRelationship( $objWriter, '_comments' . $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', @@ -285,7 +275,7 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul // Write header/footer relationship? $i = 1; if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) { - $this->_writeRelationship( + $this->writeRelationship( $objWriter, '_headerfooter_vml' . $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', @@ -295,7 +285,6 @@ public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = nul $objWriter->endElement(); - // Return return $objWriter->getData(); } @@ -332,7 +321,7 @@ public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, if ($iterator->current() instanceof PHPExcel_Worksheet_Drawing || $iterator->current() instanceof PHPExcel_Worksheet_MemoryDrawing) { // Write relationship for image drawing - $this->_writeRelationship( + $this->writeRelationship( $objWriter, $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', @@ -349,7 +338,7 @@ public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, $chartCount = $pWorksheet->getChartCount(); if ($chartCount > 0) { for ($c = 0; $c < $chartCount; ++$c) { - $this->_writeRelationship( + $this->writeRelationship( $objWriter, $i++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', @@ -361,7 +350,6 @@ public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, $objWriter->endElement(); - // Return return $objWriter->getData(); } @@ -392,7 +380,7 @@ public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorks // Loop through images and write relationships foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) { // Write relationship for image drawing - $this->_writeRelationship( + $this->writeRelationship( $objWriter, $key, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', @@ -402,7 +390,6 @@ public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorks $objWriter->endElement(); - // Return return $objWriter->getData(); } @@ -416,7 +403,7 @@ public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorks * @param string $pTargetMode Relationship target mode * @throws PHPExcel_Writer_Exception */ - private function _writeRelationship(PHPExcel_Shared_XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '') + private function writeRelationship(PHPExcel_Shared_XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '') { if ($pType != '' && $pTarget != '') { // Write relationship diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php index 0ab653574..5a4a9fc09 100644 --- a/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php +++ b/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_RelsRibbon * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_RelsRibbon - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_RelsRibbon extends PHPExcel_Writer_Excel2007_WriterPart { /** @@ -65,12 +57,11 @@ public function writeRibbonRelationships(PHPExcel $pPHPExcel = null) $objWriter->writeAttribute('Id', $aId); $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); $objWriter->writeAttribute('Target', $aTarget); - $objWriter->endElement();//Relationship + $objWriter->endElement(); } } - $objWriter->endElement();//Relationships + $objWriter->endElement(); - // Return return $objWriter->getData(); } } diff --git a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php index b8e3ed4f6..bee0e6436 100644 --- a/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php +++ b/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_RelsVBA * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_RelsVBA - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_RelsVBA extends PHPExcel_Writer_Excel2007_WriterPart { /** @@ -62,10 +54,9 @@ public function writeVBARelationships(PHPExcel $pPHPExcel = null) $objWriter->writeAttribute('Id', 'rId1'); $objWriter->writeAttribute('Type', 'http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature'); $objWriter->writeAttribute('Target', 'vbaProjectSignature.bin'); - $objWriter->endElement();//Relationship - $objWriter->endElement();//Relationships + $objWriter->endElement(); + $objWriter->endElement(); - // Return return $objWriter->getData(); } diff --git a/Classes/PHPExcel/Writer/Excel2007/StringTable.php b/Classes/PHPExcel/Writer/Excel2007/StringTable.php index 7976f7bbe..fccec669f 100644 --- a/Classes/PHPExcel/Writer/Excel2007/StringTable.php +++ b/Classes/PHPExcel/Writer/Excel2007/StringTable.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_StringTable * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_StringTable - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_StringTable extends PHPExcel_Writer_Excel2007_WriterPart { /** @@ -78,7 +70,6 @@ public function createStringTable($pSheet = null, $pExistingTable = null) } } - // Return return $aStringTable; } else { throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); @@ -132,7 +123,6 @@ public function writeStringTable($pStringTable = null) $objWriter->endElement(); - // Return return $objWriter->getData(); } else { throw new PHPExcel_Writer_Exception("Invalid string table array passed."); @@ -318,7 +308,6 @@ public function flipStringTable($stringTable = array()) } } - // Return return $returnValue; } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Style.php b/Classes/PHPExcel/Writer/Excel2007/Style.php index 5ff56f33d..d3f0af7b2 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Style.php +++ b/Classes/PHPExcel/Writer/Excel2007/Style.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_Style * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_Style - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_Style extends PHPExcel_Writer_Excel2007_WriterPart { /** @@ -66,7 +58,7 @@ public function writeStyles(PHPExcel $pPHPExcel = null) // numFmt for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) { - $this->_writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i); + $this->writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i); } $objWriter->endElement(); @@ -77,7 +69,7 @@ public function writeStyles(PHPExcel $pPHPExcel = null) // font for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) { - $this->_writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i)); + $this->writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i)); } $objWriter->endElement(); @@ -88,7 +80,7 @@ public function writeStyles(PHPExcel $pPHPExcel = null) // fill for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) { - $this->_writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i)); + $this->writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i)); } $objWriter->endElement(); @@ -99,7 +91,7 @@ public function writeStyles(PHPExcel $pPHPExcel = null) // border for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) { - $this->_writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i)); + $this->writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i)); } $objWriter->endElement(); @@ -124,7 +116,7 @@ public function writeStyles(PHPExcel $pPHPExcel = null) // xf foreach ($pPHPExcel->getCellXfCollection() as $cellXf) { - $this->_writeCellStyleXf($objWriter, $cellXf, $pPHPExcel); + $this->writeCellStyleXf($objWriter, $cellXf, $pPHPExcel); } $objWriter->endElement(); @@ -148,7 +140,7 @@ public function writeStyles(PHPExcel $pPHPExcel = null) // dxf for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) { - $this->_writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle()); + $this->writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle()); } $objWriter->endElement(); @@ -172,16 +164,16 @@ public function writeStyles(PHPExcel $pPHPExcel = null) * @param PHPExcel_Style_Fill $pFill Fill style * @throws PHPExcel_Writer_Exception */ - private function _writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + private function writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) { // Check if this is a pattern type or gradient type if ($pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR || $pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_PATH) { // Gradient fill - $this->_writeGradientFill($objWriter, $pFill); + $this->writeGradientFill($objWriter, $pFill); } elseif ($pFill->getFillType() !== null) { // Pattern fill - $this->_writePatternFill($objWriter, $pFill); + $this->writePatternFill($objWriter, $pFill); } } @@ -192,7 +184,7 @@ private function _writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce * @param PHPExcel_Style_Fill $pFill Fill style * @throws PHPExcel_Writer_Exception */ - private function _writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + private function writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) { // fill $objWriter->startElement('fill'); @@ -236,7 +228,7 @@ private function _writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, * @param PHPExcel_Style_Fill $pFill Fill style * @throws PHPExcel_Writer_Exception */ - private function _writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + private function writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) { // fill $objWriter->startElement('fill'); @@ -274,7 +266,7 @@ private function _writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, * @param PHPExcel_Style_Font $pFont Font style * @throws PHPExcel_Writer_Exception */ - private function _writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Font $pFont = null) + private function writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Font $pFont = null) { // font $objWriter->startElement('font'); @@ -354,7 +346,7 @@ private function _writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce * @param PHPExcel_Style_Borders $pBorders Borders style * @throws PHPExcel_Writer_Exception */ - private function _writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Borders $pBorders = null) + private function writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Borders $pBorders = null) { // Write border $objWriter->startElement('border'); @@ -375,11 +367,11 @@ private function _writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx } // BorderPr - $this->_writeBorderPr($objWriter, 'left', $pBorders->getLeft()); - $this->_writeBorderPr($objWriter, 'right', $pBorders->getRight()); - $this->_writeBorderPr($objWriter, 'top', $pBorders->getTop()); - $this->_writeBorderPr($objWriter, 'bottom', $pBorders->getBottom()); - $this->_writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal()); + $this->writeBorderPr($objWriter, 'left', $pBorders->getLeft()); + $this->writeBorderPr($objWriter, 'right', $pBorders->getRight()); + $this->writeBorderPr($objWriter, 'top', $pBorders->getTop()); + $this->writeBorderPr($objWriter, 'bottom', $pBorders->getBottom()); + $this->writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal()); $objWriter->endElement(); } @@ -391,7 +383,7 @@ private function _writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx * @param PHPExcel $pPHPExcel Workbook * @throws PHPExcel_Writer_Exception */ - private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null, PHPExcel $pPHPExcel = null) + private function writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null, PHPExcel $pPHPExcel = null) { // xf $objWriter->startElement('xf'); @@ -466,19 +458,19 @@ private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, * @param PHPExcel_Style $pStyle Style * @throws PHPExcel_Writer_Exception */ - private function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null) + private function writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null) { // dxf $objWriter->startElement('dxf'); // font - $this->_writeFont($objWriter, $pStyle->getFont()); + $this->writeFont($objWriter, $pStyle->getFont()); // numFmt - $this->_writeNumFmt($objWriter, $pStyle->getNumberFormat()); + $this->writeNumFmt($objWriter, $pStyle->getNumberFormat()); // fill - $this->_writeFill($objWriter, $pStyle->getFill()); + $this->writeFill($objWriter, $pStyle->getFill()); // alignment $objWriter->startElement('alignment'); @@ -501,7 +493,7 @@ private function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, $objWriter->endElement(); // border - $this->_writeBorder($objWriter, $pStyle->getBorders()); + $this->writeBorder($objWriter, $pStyle->getBorders()); // protection if (($pStyle->getProtection()->getLocked() !== null) || ($pStyle->getProtection()->getHidden() !== null)) { @@ -531,7 +523,7 @@ private function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, * @param PHPExcel_Style_Border $pBorder Border style * @throws PHPExcel_Writer_Exception */ - private function _writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pName = 'left', PHPExcel_Style_Border $pBorder = null) + private function writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pName = 'left', PHPExcel_Style_Border $pBorder = null) { // Write BorderPr if ($pBorder->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) { @@ -555,7 +547,7 @@ private function _writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pN * @param int $pId Number Format identifier * @throws PHPExcel_Writer_Exception */ - private function _writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_NumberFormat $pNumberFormat = null, $pId = 0) + private function writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_NumberFormat $pNumberFormat = null, $pId = 0) { // Translate formatcode $formatCode = $pNumberFormat->getFormatCode(); diff --git a/Classes/PHPExcel/Writer/Excel2007/Theme.php b/Classes/PHPExcel/Writer/Excel2007/Theme.php index 7253afe48..223e40241 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Theme.php +++ b/Classes/PHPExcel/Writer/Excel2007/Theme.php @@ -40,7 +40,7 @@ class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPa * @static array of string * */ - private static $_majorFonts = array( + private static $majorFonts = array( 'Jpan' => 'MS Pゴシック', 'Hang' => '맑은 고딕', 'Hans' => '宋体', @@ -78,7 +78,7 @@ class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPa * @static array of string * */ - private static $_minorFonts = array( + private static $minorFonts = array( 'Jpan' => 'MS Pゴシック', 'Hang' => '맑은 고딕', 'Hans' => '宋体', @@ -116,7 +116,7 @@ class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPa * @static array of string * */ - private static $_colourScheme = array( + private static $colourScheme = array( 'dk2' => '1F497D', 'lt2' => 'EEECE1', 'accent1' => '4F81BD', @@ -184,7 +184,7 @@ public function writeTheme(PHPExcel $pPHPExcel = null) $objWriter->endElement(); // a:dk2 - $this->_writeColourScheme($objWriter); + $this->writeColourScheme($objWriter); $objWriter->endElement(); @@ -194,12 +194,12 @@ public function writeTheme(PHPExcel $pPHPExcel = null) // a:majorFont $objWriter->startElement('a:majorFont'); - $this->_writeFonts($objWriter, 'Cambria', self::$_majorFonts); + $this->writeFonts($objWriter, 'Cambria', self::$majorFonts); $objWriter->endElement(); // a:minorFont $objWriter->startElement('a:minorFont'); - $this->_writeFonts($objWriter, 'Calibri', self::$_minorFonts); + $this->writeFonts($objWriter, 'Calibri', self::$minorFonts); $objWriter->endElement(); $objWriter->endElement(); @@ -822,7 +822,7 @@ public function writeTheme(PHPExcel $pPHPExcel = null) * @return string XML Output * @throws PHPExcel_Writer_Exception */ - private function _writeFonts($objWriter, $latinFont, $fontSet) + private function writeFonts($objWriter, $latinFont, $fontSet) { // a:latin $objWriter->startElement('a:latin'); @@ -854,9 +854,9 @@ private function _writeFonts($objWriter, $latinFont, $fontSet) * @return string XML Output * @throws PHPExcel_Writer_Exception */ - private function _writeColourScheme($objWriter) + private function writeColourScheme($objWriter) { - foreach (self::$_colourScheme as $colourName => $colourValue) { + foreach (self::$colourScheme as $colourName => $colourValue) { $objWriter->startElement('a:'.$colourName); $objWriter->startElement('a:srgbClr'); diff --git a/Classes/PHPExcel/Writer/Excel2007/Workbook.php b/Classes/PHPExcel/Writer/Excel2007/Workbook.php index 40c1cf4f7..87c877ea9 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel2007/Workbook.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_Workbook * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_Workbook - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_WriterPart { /** @@ -63,27 +55,27 @@ public function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = fals $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); // fileVersion - $this->_writeFileVersion($objWriter); + $this->writeFileVersion($objWriter); // workbookPr - $this->_writeWorkbookPr($objWriter); + $this->writeWorkbookPr($objWriter); // workbookProtection - $this->_writeWorkbookProtection($objWriter, $pPHPExcel); + $this->writeWorkbookProtection($objWriter, $pPHPExcel); // bookViews if ($this->getParentWriter()->getOffice2003Compatibility() === false) { - $this->_writeBookViews($objWriter, $pPHPExcel); + $this->writeBookViews($objWriter, $pPHPExcel); } // sheets - $this->_writeSheets($objWriter, $pPHPExcel); + $this->writeSheets($objWriter, $pPHPExcel); // definedNames - $this->_writeDefinedNames($objWriter, $pPHPExcel); + $this->writeDefinedNames($objWriter, $pPHPExcel); // calcPr - $this->_writeCalcPr($objWriter, $recalcRequired); + $this->writeCalcPr($objWriter, $recalcRequired); $objWriter->endElement(); @@ -97,7 +89,7 @@ public function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = fals * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @throws PHPExcel_Writer_Exception */ - private function _writeFileVersion(PHPExcel_Shared_XMLWriter $objWriter = null) + private function writeFileVersion(PHPExcel_Shared_XMLWriter $objWriter = null) { $objWriter->startElement('fileVersion'); $objWriter->writeAttribute('appName', 'xl'); @@ -113,7 +105,7 @@ private function _writeFileVersion(PHPExcel_Shared_XMLWriter $objWriter = null) * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer * @throws PHPExcel_Writer_Exception */ - private function _writeWorkbookPr(PHPExcel_Shared_XMLWriter $objWriter = null) + private function writeWorkbookPr(PHPExcel_Shared_XMLWriter $objWriter = null) { $objWriter->startElement('workbookPr'); @@ -133,7 +125,7 @@ private function _writeWorkbookPr(PHPExcel_Shared_XMLWriter $objWriter = null) * @param PHPExcel $pPHPExcel * @throws PHPExcel_Writer_Exception */ - private function _writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + private function writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) { // bookViews $objWriter->startElement('bookViews'); @@ -163,7 +155,7 @@ private function _writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PH * @param PHPExcel $pPHPExcel * @throws PHPExcel_Writer_Exception */ - private function _writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + private function writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) { if ($pPHPExcel->getSecurity()->isSecurityEnabled()) { $objWriter->startElement('workbookProtection'); @@ -190,7 +182,7 @@ private function _writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing * @throws PHPExcel_Writer_Exception */ - private function _writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = true) + private function writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = true) { $objWriter->startElement('calcPr'); @@ -213,14 +205,14 @@ private function _writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $reca * @param PHPExcel $pPHPExcel * @throws PHPExcel_Writer_Exception */ - private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + private function writeSheets(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) { // Write sheets $objWriter->startElement('sheets'); $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { // sheet - $this->_writeSheet( + $this->writeSheet( $objWriter, $pPHPExcel->getSheet($i)->getTitle(), ($i + 1), @@ -242,7 +234,7 @@ private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx * @param string $sheetState Sheet state (visible, hidden, veryHidden) * @throws PHPExcel_Writer_Exception */ - private function _writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pSheetname = '', $pSheetId = 1, $pRelId = 1, $sheetState = 'visible') + private function writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pSheetname = '', $pSheetId = 1, $pRelId = 1, $sheetState = 'visible') { if ($pSheetname != '') { // Write sheet @@ -266,7 +258,7 @@ private function _writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pShee * @param PHPExcel $pPHPExcel * @throws PHPExcel_Writer_Exception */ - private function _writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + private function writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) { // Write defined names $objWriter->startElement('definedNames'); @@ -274,20 +266,20 @@ private function _writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, // Named ranges if (count($pPHPExcel->getNamedRanges()) > 0) { // Named ranges - $this->_writeNamedRanges($objWriter, $pPHPExcel); + $this->writeNamedRanges($objWriter, $pPHPExcel); } // Other defined names $sheetCount = $pPHPExcel->getSheetCount(); for ($i = 0; $i < $sheetCount; ++$i) { // definedName for autoFilter - $this->_writeDefinedNameForAutofilter($objWriter, $pPHPExcel->getSheet($i), $i); + $this->writeDefinedNameForAutofilter($objWriter, $pPHPExcel->getSheet($i), $i); // definedName for Print_Titles - $this->_writeDefinedNameForPrintTitles($objWriter, $pPHPExcel->getSheet($i), $i); + $this->writeDefinedNameForPrintTitles($objWriter, $pPHPExcel->getSheet($i), $i); // definedName for Print_Area - $this->_writeDefinedNameForPrintArea($objWriter, $pPHPExcel->getSheet($i), $i); + $this->writeDefinedNameForPrintArea($objWriter, $pPHPExcel->getSheet($i), $i); } $objWriter->endElement(); @@ -300,12 +292,12 @@ private function _writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, * @param PHPExcel $pPHPExcel * @throws PHPExcel_Writer_Exception */ - private function _writeNamedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel) + private function writeNamedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel) { // Loop named ranges $namedRanges = $pPHPExcel->getNamedRanges(); foreach ($namedRanges as $namedRange) { - $this->_writeDefinedNameForNamedRange($objWriter, $namedRange); + $this->writeDefinedNameForNamedRange($objWriter, $namedRange); } } @@ -316,7 +308,7 @@ private function _writeNamedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, * @param PHPExcel_NamedRange $pNamedRange * @throws PHPExcel_Writer_Exception */ - private function _writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_NamedRange $pNamedRange) + private function writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_NamedRange $pNamedRange) { // definedName for named range $objWriter->startElement('definedName'); @@ -348,7 +340,7 @@ private function _writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWr * @param int $pSheetId * @throws PHPExcel_Writer_Exception */ - private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + private function writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) { // definedName for autoFilter $autoFilterRange = $pSheet->getAutoFilter()->getRange(); @@ -384,7 +376,7 @@ private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWr * @param int $pSheetId * @throws PHPExcel_Writer_Exception */ - private function _writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + private function writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) { // definedName for PrintTitles if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { @@ -427,7 +419,7 @@ private function _writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objW * @param int $pSheetId * @throws PHPExcel_Writer_Exception */ - private function _writeDefinedNameForPrintArea(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + private function writeDefinedNameForPrintArea(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) { // definedName for PrintArea if ($pSheet->getPageSetup()->isPrintAreaSet()) { diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index 492e04535..290bbe771 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -65,67 +65,67 @@ public function writeWorksheet($pSheet = null, $pStringTable = null, $includeCha $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); // sheetPr - $this->_writeSheetPr($objWriter, $pSheet); + $this->writeSheetPr($objWriter, $pSheet); // Dimension - $this->_writeDimension($objWriter, $pSheet); + $this->writeDimension($objWriter, $pSheet); // sheetViews - $this->_writeSheetViews($objWriter, $pSheet); + $this->writeSheetViews($objWriter, $pSheet); // sheetFormatPr - $this->_writeSheetFormatPr($objWriter, $pSheet); + $this->writeSheetFormatPr($objWriter, $pSheet); // cols - $this->_writeCols($objWriter, $pSheet); + $this->writeCols($objWriter, $pSheet); // sheetData - $this->_writeSheetData($objWriter, $pSheet, $pStringTable); + $this->writeSheetData($objWriter, $pSheet, $pStringTable); // sheetProtection - $this->_writeSheetProtection($objWriter, $pSheet); + $this->writeSheetProtection($objWriter, $pSheet); // protectedRanges - $this->_writeProtectedRanges($objWriter, $pSheet); + $this->writeProtectedRanges($objWriter, $pSheet); // autoFilter - $this->_writeAutoFilter($objWriter, $pSheet); + $this->writeAutoFilter($objWriter, $pSheet); // mergeCells - $this->_writeMergeCells($objWriter, $pSheet); + $this->writeMergeCells($objWriter, $pSheet); // conditionalFormatting - $this->_writeConditionalFormatting($objWriter, $pSheet); + $this->writeConditionalFormatting($objWriter, $pSheet); // dataValidations - $this->_writeDataValidations($objWriter, $pSheet); + $this->writeDataValidations($objWriter, $pSheet); // hyperlinks - $this->_writeHyperlinks($objWriter, $pSheet); + $this->writeHyperlinks($objWriter, $pSheet); // Print options - $this->_writePrintOptions($objWriter, $pSheet); + $this->writePrintOptions($objWriter, $pSheet); // Page margins - $this->_writePageMargins($objWriter, $pSheet); + $this->writePageMargins($objWriter, $pSheet); // Page setup - $this->_writePageSetup($objWriter, $pSheet); + $this->writePageSetup($objWriter, $pSheet); // Header / footer - $this->_writeHeaderFooter($objWriter, $pSheet); + $this->writeHeaderFooter($objWriter, $pSheet); // Breaks - $this->_writeBreaks($objWriter, $pSheet); + $this->writeBreaks($objWriter, $pSheet); // Drawings and/or Charts - $this->_writeDrawings($objWriter, $pSheet, $includeCharts); + $this->writeDrawings($objWriter, $pSheet, $includeCharts); // LegacyDrawing - $this->_writeLegacyDrawing($objWriter, $pSheet); + $this->writeLegacyDrawing($objWriter, $pSheet); // LegacyDrawingHF - $this->_writeLegacyDrawingHF($objWriter, $pSheet); + $this->writeLegacyDrawingHF($objWriter, $pSheet); $objWriter->endElement(); @@ -143,7 +143,7 @@ public function writeWorksheet($pSheet = null, $pStringTable = null, $includeCha * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // sheetPr $objWriter->startElement('sheetPr'); @@ -190,7 +190,7 @@ private function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPE * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // dimension $objWriter->startElement('dimension'); @@ -205,7 +205,7 @@ private function _writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PH * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // sheetViews $objWriter->startElement('sheetViews'); @@ -317,7 +317,7 @@ private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, P * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // sheetFormatPr $objWriter->startElement('sheetFormatPr'); @@ -369,7 +369,7 @@ private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // cols if (count($pSheet->getColumnDimensions()) > 0) { @@ -434,7 +434,7 @@ private function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // sheetProtection $objWriter->startElement('sheetProtection'); @@ -469,7 +469,7 @@ private function _writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = nu * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // Conditional id $id = 1; @@ -542,7 +542,7 @@ private function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWrite * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // Datavalidation collection $dataValidationCollection = $pSheet->getDataValidationCollection(); @@ -608,7 +608,7 @@ private function _writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = nu * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // Hyperlink collection $hyperlinkCollection = $pSheet->getHyperlinkCollection(); @@ -649,7 +649,7 @@ private function _writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, P * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { if (count($pSheet->getProtectedCells()) > 0) { // protectedRanges @@ -678,7 +678,7 @@ private function _writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = nu * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { if (count($pSheet->getMergeCells()) > 0) { // mergeCells @@ -703,7 +703,7 @@ private function _writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, P * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // printOptions $objWriter->startElement('printOptions'); @@ -729,7 +729,7 @@ private function _writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // pageMargins $objWriter->startElement('pageMargins'); @@ -749,7 +749,7 @@ private function _writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { $autoFilterRange = $pSheet->getAutoFilter()->getRange(); if (!empty($autoFilterRange)) { @@ -842,7 +842,7 @@ private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, P * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // pageSetup $objWriter->startElement('pageSetup'); @@ -877,7 +877,7 @@ private function _writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PH * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // headerFooter $objWriter->startElement('headerFooter'); @@ -902,7 +902,7 @@ private function _writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // Get row and column breaks $aRowBreaks = array(); @@ -960,7 +960,7 @@ private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPEx * @param string[] $pStringTable String table * @throws PHPExcel_Writer_Exception */ - private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pStringTable = null) + private function writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pStringTable = null) { if (is_array($pStringTable)) { // Flipped stringtable, for faster index searching @@ -1027,7 +1027,7 @@ private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PH if (isset($cellsByRow[$currentRow])) { foreach ($cellsByRow[$currentRow] as $cellAddress) { // Write cell - $this->_writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable); + $this->writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable); } } @@ -1052,7 +1052,7 @@ private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PH * @param string[] $pFlippedStringTable String table (flipped), for faster index searching * @throws PHPExcel_Writer_Exception */ - private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pCellAddress = null, $pStringTable = null, $pFlippedStringTable = null) + private function writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pCellAddress = null, $pStringTable = null, $pFlippedStringTable = null) { if (is_array($pStringTable) && is_array($pFlippedStringTable)) { // Cell @@ -1171,7 +1171,7 @@ private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce * @param boolean $includeCharts Flag indicating if we should include drawing details for charts * @throws PHPExcel_Writer_Exception */ - private function _writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = false) + private function writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = false) { $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0; // If sheet contains drawings, add the relationships @@ -1190,7 +1190,7 @@ private function _writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHP * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // If sheet contains comments, add the relationships if (count($pSheet->getComments()) > 0) { @@ -1207,7 +1207,7 @@ private function _writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null * @param PHPExcel_Worksheet $pSheet Worksheet * @throws PHPExcel_Writer_Exception */ - private function _writeLegacyDrawingHF(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + private function writeLegacyDrawingHF(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) { // If sheet contains images, add the relationships if (count($pSheet->getHeaderFooter()->getImages()) > 0) { diff --git a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php index b32f1ad41..806ebe510 100644 --- a/Classes/PHPExcel/Writer/Excel2007/WriterPart.php +++ b/Classes/PHPExcel/Writer/Excel2007/WriterPart.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel2007_WriterPart * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel2007_WriterPart - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel2007 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ abstract class PHPExcel_Writer_Excel2007_WriterPart { /** @@ -40,7 +32,7 @@ abstract class PHPExcel_Writer_Excel2007_WriterPart * * @var PHPExcel_Writer_IWriter */ - private $_parentWriter; + private $parentWriter; /** * Set parent IWriter object @@ -50,7 +42,7 @@ abstract class PHPExcel_Writer_Excel2007_WriterPart */ public function setParentWriter(PHPExcel_Writer_IWriter $pWriter = null) { - $this->_parentWriter = $pWriter; + $this->parentWriter = $pWriter; } /** @@ -61,8 +53,8 @@ public function setParentWriter(PHPExcel_Writer_IWriter $pWriter = null) */ public function getParentWriter() { - if (!is_null($this->_parentWriter)) { - return $this->_parentWriter; + if (!is_null($this->parentWriter)) { + return $this->parentWriter; } else { throw new PHPExcel_Writer_Exception("No parent PHPExcel_Writer_IWriter assigned."); } @@ -77,7 +69,7 @@ public function getParentWriter() public function __construct(PHPExcel_Writer_IWriter $pWriter = null) { if (!is_null($pWriter)) { - $this->_parentWriter = $pWriter; + $this->parentWriter = $pWriter; } } } diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index b1f49e099..14d86124d 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -128,7 +128,7 @@ public function save($pFilename = null) // Initialise worksheet writers $countSheets = $this->phpExcel->getSheetCount(); for ($i = 0; $i < $countSheets; ++$i) { - $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser, $this->_preCalculateFormulas, $this->phpExcel->getSheet($i)); + $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser, $this->preCalculateFormulas, $this->phpExcel->getSheet($i)); } // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook. diff --git a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php index 62ab5839a..e6d87a4ae 100644 --- a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php +++ b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php @@ -73,7 +73,7 @@ class PHPExcel_Writer_Excel5_BIFFwriter * The byte order of this architecture. 0 => little endian, 1 => big endian * @var integer */ - private static $_byte_order; + private static $byteOrder; /** * The string containing the data of the BIFF stream @@ -112,7 +112,7 @@ public function __construct() */ public static function getByteOrder() { - if (!isset(self::$_byte_order)) { + if (!isset(self::$byteOrder)) { // Check if "pack" gives the required IEEE 64bit float $teststr = pack("d", 1.2345); $number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F); @@ -124,10 +124,10 @@ public static function getByteOrder() // Give up. I'll fix this in a later version. throw new PHPExcel_Writer_Exception("Required floating point format not supported on this platform."); } - self::$_byte_order = $byte_order; + self::$byteOrder = $byte_order; } - return self::$_byte_order; + return self::$byteOrder; } /** diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index 6949c1727..5a4d2a7e1 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel5_Worksheet * * Copyright (c) 2006 - 2015 PHPExcel * @@ -59,15 +60,6 @@ // * License along with this library; if not, write to the Free Software // * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // */ - - -/** - * PHPExcel_Writer_Excel5_Worksheet - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter { /** @@ -75,7 +67,7 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter * * @var PHPExcel_Writer_Excel5_Parser */ - private $_parser; + private $parser; /** * Maximum number of characters for a string (LABEL record in BIFF5) @@ -146,31 +138,31 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter /** * Color cache */ - private $_colors; + private $colors; /** * Index of first used row (at least 0) * @var int */ - private $_firstRowIndex; + private $firstRowIndex; /** * Index of last used row. (no used rows means -1) * @var int */ - private $_lastRowIndex; + private $lastRowIndex; /** * Index of first used column (at least 0) * @var int */ - private $_firstColumnIndex; + private $firstColumnIndex; /** * Index of last used column (no used columns means -1) * @var int */ - private $_lastColumnIndex; + private $lastColumnIndex; /** * Sheet object @@ -183,14 +175,14 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter * * @var int */ - private $_countCellStyleXfs; + private $countCellStyleXfs; /** * Escher object corresponding to MSODRAWING * * @var PHPExcel_Shared_Escher */ - private $_escher; + private $escher; /** * Array of font hashes associated to FONT records index @@ -224,8 +216,8 @@ public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, $p $this->_str_total = &$str_total; $this->_str_unique = &$str_unique; $this->_str_table = &$str_table; - $this->_colors = &$colors; - $this->_parser = $parser; + $this->colors = &$colors; + $this->parser = $parser; $this->_phpSheet = $phpSheet; @@ -253,18 +245,18 @@ public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, $p $maxC = $this->_phpSheet->getHighestColumn(); // Determine lowest and highest column and row -// $this->_firstRowIndex = ($minR > 65535) ? 65535 : $minR; - $this->_lastRowIndex = ($maxR > 65535) ? 65535 : $maxR ; +// $this->firstRowIndex = ($minR > 65535) ? 65535 : $minR; + $this->lastRowIndex = ($maxR > 65535) ? 65535 : $maxR ; - $this->_firstColumnIndex = PHPExcel_Cell::columnIndexFromString($minC); - $this->_lastColumnIndex = PHPExcel_Cell::columnIndexFromString($maxC); + $this->firstColumnIndex = PHPExcel_Cell::columnIndexFromString($minC); + $this->lastColumnIndex = PHPExcel_Cell::columnIndexFromString($maxC); -// if ($this->_firstColumnIndex > 255) $this->_firstColumnIndex = 255; - if ($this->_lastColumnIndex > 255) { - $this->_lastColumnIndex = 255; +// if ($this->firstColumnIndex > 255) $this->firstColumnIndex = 255; + if ($this->lastColumnIndex > 255) { + $this->lastColumnIndex = 255; } - $this->_countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection()); + $this->countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection()); } /** @@ -301,7 +293,7 @@ public function close() } $columnDimensions = $_phpSheet->getColumnDimensions(); - $maxCol = $this->_lastColumnIndex -1; + $maxCol = $this->lastColumnIndex -1; for ($i = 0; $i <= $maxCol; ++$i) { $hidden = 0; $level = 0; @@ -334,7 +326,7 @@ public function close() $this->_writeGuts(); // Write DEFAULTROWHEIGHT - $this->_writeDefaultRowHeight(); + $this->writeDefaultRowHeight(); // Write WSBOOL $this->_writeWsbool(); @@ -398,12 +390,12 @@ public function close() } // Write sheet dimensions - $this->_writeDimensions(); + $this->writeDimensions(); // Row dimensions foreach ($_phpSheet->getRowDimensions() as $rowDimension) { $xfIndex = $rowDimension->getXfIndex() + 15; // there are 15 cellXfs - $this->_writeRow($rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel()); + $this->writeRow($rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel()); } // Write Cells @@ -423,7 +415,7 @@ public function close() $cVal = $cell->getValue(); if ($cVal instanceof PHPExcel_RichText) { - // $this->_writeString($row, $column, $cVal->getPlainText(), $xfIndex); + // $this->writeString($row, $column, $cVal->getPlainText(), $xfIndex); $arrcRun = array(); $str_len = PHPExcel_Shared_String::CountCharacters($cVal->getPlainText(), 'UTF-8'); $str_pos = 0; @@ -439,7 +431,7 @@ public function close() // Position FROM $str_pos += PHPExcel_Shared_String::CountCharacters($element->getText(), 'UTF-8'); } - $this->_writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun); + $this->writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun); } else { switch ($cell->getDatatype()) { case PHPExcel_Cell_DataType::TYPE_STRING: @@ -447,26 +439,26 @@ public function close() if ($cVal === '' || $cVal === null) { $this->_writeBlank($row, $column, $xfIndex); } else { - $this->_writeString($row, $column, $cVal, $xfIndex); + $this->writeString($row, $column, $cVal, $xfIndex); } break; case PHPExcel_Cell_DataType::TYPE_NUMERIC: - $this->_writeNumber($row, $column, $cVal, $xfIndex); + $this->writeNumber($row, $column, $cVal, $xfIndex); break; case PHPExcel_Cell_DataType::TYPE_FORMULA: $calculatedValue = $this->_preCalculateFormulas ? $cell->getCalculatedValue() : null; - $this->_writeFormula($row, $column, $cVal, $xfIndex, $calculatedValue); + $this->writeFormula($row, $column, $cVal, $xfIndex, $calculatedValue); break; case PHPExcel_Cell_DataType::TYPE_BOOL: - $this->_writeBoolErr($row, $column, $cVal, 0, $xfIndex); + $this->writeBoolErr($row, $column, $cVal, 0, $xfIndex); break; case PHPExcel_Cell_DataType::TYPE_ERROR: - $this->_writeBoolErr($row, $column, self::_mapErrorCode($cVal), 1, $xfIndex); + $this->writeBoolErr($row, $column, self::_mapErrorCode($cVal), 1, $xfIndex); break; } @@ -477,7 +469,7 @@ public function close() $this->_writeMsoDrawing(); // Write WINDOW2 record - $this->_writeWindow2(); + $this->writeWindow2(); // Write PLV record $this->_writePageLayoutView(); @@ -513,7 +505,7 @@ public function close() $url = 'external:' . $url; } - $this->_writeUrl($row - 1, PHPExcel_Cell::columnIndexFromString($column) - 1, $url); + $this->writeUrl($row - 1, PHPExcel_Cell::columnIndexFromString($column) - 1, $url); } $this->_writeDataValidity(); @@ -528,7 +520,7 @@ public function close() $arrConditional = array(); // @todo CFRule & CFHeader // Write CFHEADER record - $this->_writeCFHeader(); + $this->writeCFHeader(); // Write ConditionalFormattingTable records foreach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) { foreach ($conditionalStyles as $conditional) { @@ -537,7 +529,7 @@ public function close() if (!in_array($conditional->getHashCode(), $arrConditional)) { $arrConditional[] = $conditional->getHashCode(); // Write CFRULE record - $this->_writeCFRule($conditional); + $this->writeCFRule($conditional); } } } @@ -555,7 +547,7 @@ public function close() * @param string $range E.g. 'A1' or 'A1:B6' * @return string Binary data */ - private function _writeBIFF8CellRangeAddressFixed($range = 'A1') + private function writeBIFF8CellRangeAddressFixed($range = 'A1') { $explodes = explode(':', $range); @@ -642,7 +634,7 @@ public function setOutline($visible = true, $symbols_below = true, $symbols_righ * @param mixed $xfIndex The optional XF format * @return integer */ - private function _writeNumber($row, $col, $num, $xfIndex) + private function writeNumber($row, $col, $num, $xfIndex) { $record = 0x0203; // Record identifier $length = 0x000E; // Number of bytes to follow @@ -666,21 +658,21 @@ private function _writeNumber($row, $col, $num, $xfIndex) * @param string $str The string * @param int $xfIndex Index to XF record */ - private function _writeString($row, $col, $str, $xfIndex) + private function writeString($row, $col, $str, $xfIndex) { - $this->_writeLabelSst($row, $col, $str, $xfIndex); + $this->writeLabelSst($row, $col, $str, $xfIndex); } /** * Write a LABELSST record or a LABEL record. Which one depends on BIFF version - * It differs from _writeString by the writing of rich text strings. + * It differs from writeString by the writing of rich text strings. * @param int $row Row index (0-based) * @param int $col Column index (0-based) * @param string $str The string * @param mixed $xfIndex The XF format index for the cell * @param array $arrcRun Index to Font record and characters beginning */ - private function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun) + private function writeRichTextString($row, $col, $str, $xfIndex, $arrcRun) { $record = 0x00FD; // Record identifier $length = 0x000A; // Bytes to follow @@ -712,7 +704,7 @@ private function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun) * @param mixed $xfIndex The XF format index for the cell * @return integer */ - private function _writeLabel($row, $col, $str, $xfIndex) + private function writeLabel($row, $col, $str, $xfIndex) { $strlen = strlen($str); $record = 0x0204; // Record identifier @@ -748,7 +740,7 @@ private function _writeLabel($row, $col, $str, $xfIndex) * @param mixed $xfIndex The XF format index for the cell * @return integer */ - private function _writeLabelSst($row, $col, $str, $xfIndex) + private function writeLabelSst($row, $col, $str, $xfIndex) { $record = 0x00FD; // Record identifier $length = 0x000A; // Bytes to follow @@ -774,7 +766,7 @@ private function _writeLabelSst($row, $col, $str, $xfIndex) * @param integer $col Zero indexed column * @param string $note The note to write */ - private function _writeNote($row, $col, $note) + private function writeNote($row, $col, $note) { $note_length = strlen($note); $record = 0x001C; // Record identifier @@ -832,7 +824,7 @@ public function _writeBlank($row, $col, $xfIndex) * @param boolean $isError Error or Boolean? * @param int $xfIndex */ - private function _writeBoolErr($row, $col, $value, $isError, $xfIndex) + private function writeBoolErr($row, $col, $value, $isError, $xfIndex) { $record = 0x0205; $length = 8; @@ -859,7 +851,7 @@ private function _writeBoolErr($row, $col, $value, $isError, $xfIndex) * @param mixed $calculatedValue Calculated value * @return integer */ - private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) + private function writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) { $record = 0x0006; // Record identifier @@ -904,14 +896,14 @@ private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) $formula = substr($formula, 1); } else { // Error handling - $this->_writeString($row, $col, 'Unrecognised character for formula'); + $this->writeString($row, $col, 'Unrecognised character for formula'); return -1; } // Parse the formula using the parser in Parser.php try { - $error = $this->_parser->parse($formula); - $formula = $this->_parser->toReversePolish(); + $error = $this->parser->parse($formula); + $formula = $this->parser->toReversePolish(); $formlen = strlen($formula); // Length of the binary string $length = 0x16 + $formlen; // Length of the record data @@ -925,7 +917,7 @@ private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) // Append also a STRING record if necessary if ($stringValue !== null) { - $this->_writeStringRecord($stringValue); + $this->writeStringRecord($stringValue); } return 0; @@ -941,7 +933,7 @@ private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) * * @param string $stringValue */ - private function _writeStringRecord($stringValue) + private function writeStringRecord($stringValue) { $record = 0x0207; // Record identifier $data = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($stringValue); @@ -957,7 +949,7 @@ private function _writeStringRecord($stringValue) * This is comprised of two elements: the visible label and * the invisible link. The visible label is the same as the link unless an * alternative string is specified. The label is written using the - * _writeString() method. Therefore the 255 characters string limit applies. + * writeString() method. Therefore the 255 characters string limit applies. * $string and $format are optional. * * The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external @@ -972,20 +964,20 @@ private function _writeStringRecord($stringValue) * @param string $url URL string * @return integer */ - private function _writeUrl($row, $col, $url) + private function writeUrl($row, $col, $url) { // Add start row and col to arg list - return($this->_writeUrlRange($row, $col, $row, $col, $url)); + return($this->writeUrlRange($row, $col, $row, $col, $url)); } /** - * This is the more general form of _writeUrl(). It allows a hyperlink to be + * This is the more general form of writeUrl(). It allows a hyperlink to be * written to a range of cells. This function also decides the type of hyperlink * to be written. These are either, Web (http, ftp, mailto), Internal * (Sheet1!A1) or external ('c:\temp\foo.xls#Sheet1!A1'). * * @access private - * @see _writeUrl() + * @see writeUrl() * @param integer $row1 Start row * @param integer $col1 Start column * @param integer $row2 End row @@ -993,16 +985,16 @@ private function _writeUrl($row, $col, $url) * @param string $url URL string * @return integer */ - public function _writeUrlRange($row1, $col1, $row2, $col2, $url) + public function writeUrlRange($row1, $col1, $row2, $col2, $url) { // Check for internal/external sheet links or default to web link if (preg_match('[^internal:]', $url)) { - return($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url)); + return($this->writeUrlInternal($row1, $col1, $row2, $col2, $url)); } if (preg_match('[^external:]', $url)) { - return($this->_writeUrlExternal($row1, $col1, $row2, $col2, $url)); + return($this->writeUrlExternal($row1, $col1, $row2, $col2, $url)); } - return($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url)); + return($this->writeUrlWeb($row1, $col1, $row2, $col2, $url)); } /** @@ -1011,7 +1003,7 @@ public function _writeUrlRange($row1, $col1, $row2, $col2, $url) * sheet. However it is differentiated by the $unknown2 data stream. * * @access private - * @see _writeUrl() + * @see writeUrl() * @param integer $row1 Start row * @param integer $col1 Start column * @param integer $row2 End row @@ -1019,7 +1011,7 @@ public function _writeUrlRange($row1, $col1, $row2, $col2, $url) * @param string $url URL string * @return integer */ - public function _writeUrlWeb($row1, $col1, $row2, $col2, $url) + public function writeUrlWeb($row1, $col1, $row2, $col2, $url) { $record = 0x01B8; // Record identifier $length = 0x00000; // Bytes to follow @@ -1056,7 +1048,7 @@ public function _writeUrlWeb($row1, $col1, $row2, $col2, $url) * Used to write internal reference hyperlinks such as "Sheet1!A1". * * @access private - * @see _writeUrl() + * @see writeUrl() * @param integer $row1 Start row * @param integer $col1 Start column * @param integer $row2 End row @@ -1064,7 +1056,7 @@ public function _writeUrlWeb($row1, $col1, $row2, $col2, $url) * @param string $url URL string * @return integer */ - public function _writeUrlInternal($row1, $col1, $row2, $col2, $url) + public function writeUrlInternal($row1, $col1, $row2, $col2, $url) { $record = 0x01B8; // Record identifier $length = 0x00000; // Bytes to follow @@ -1109,7 +1101,7 @@ public function _writeUrlInternal($row1, $col1, $row2, $col2, $url) * these cases for the sake of simpler code. * * @access private - * @see _writeUrl() + * @see writeUrl() * @param integer $row1 Start row * @param integer $col1 Start column * @param integer $row2 End row @@ -1117,12 +1109,12 @@ public function _writeUrlInternal($row1, $col1, $row2, $col2, $url) * @param string $url URL string * @return integer */ - public function _writeUrlExternal($row1, $col1, $row2, $col2, $url) + public function writeUrlExternal($row1, $col1, $row2, $col2, $url) { // Network drives are different. We will handle them separately // MS/Novell network drives and shares start with \\ if (preg_match('[^external:\\\\]', $url)) { - return; //($this->_writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format)); + return; //($this->writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format)); } $record = 0x01B8; // Record identifier @@ -1212,7 +1204,7 @@ public function _writeUrlExternal($row1, $col1, $row2, $col2, $url) * @param bool $hidden The optional hidden attribute * @param integer $level The optional outline level for row, in range [0,7] */ - private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) + private function writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) { $record = 0x0208; // Record identifier $length = 0x0010; // Number of bytes to follow @@ -1228,7 +1220,7 @@ private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) $height = null; } - // Use _writeRow($row, null, $XF) to set XF format without setting height + // Use writeRow($row, null, $XF) to set XF format without setting height if ($height != null) { $miyRw = $height * 20; // row height } else { @@ -1261,12 +1253,12 @@ private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) /** * Writes Excel DIMENSIONS to define the area in which there is data. */ - private function _writeDimensions() + private function writeDimensions() { $record = 0x0200; // Record identifier $length = 0x000E; - $data = pack('VVvvv', $this->_firstRowIndex, $this->_lastRowIndex + 1, $this->_firstColumnIndex, $this->_lastColumnIndex + 1, 0x0000); // reserved + $data = pack('VVvvv', $this->firstRowIndex, $this->lastRowIndex + 1, $this->firstColumnIndex, $this->lastColumnIndex + 1, 0x0000); // reserved $header = pack("vv", $record, $length); $this->_append($header.$data); @@ -1275,7 +1267,7 @@ private function _writeDimensions() /** * Write BIFF record Window2. */ - private function _writeWindow2() + private function writeWindow2() { $record = 0x023E; // Record identifier $length = 0x0012; @@ -1329,7 +1321,7 @@ private function _writeWindow2() /** * Write BIFF record DEFAULTROWHEIGHT. */ - private function _writeDefaultRowHeight() + private function writeDefaultRowHeight() { $defaultRowHeight = $this->_phpSheet->getDefaultRowDimension()->getRowHeight(); @@ -1552,7 +1544,7 @@ private function _writeSheetLayout() 0x00000000, // unused 0x00000000, // unused 0x00000014, // size of record data - $this->_colors[$this->_phpSheet->getTabColor()->getRGB()], // color index + $this->colors[$this->_phpSheet->getTabColor()->getRGB()], // color index 0x0000 // unused ); @@ -1635,7 +1627,7 @@ private function _writeRangeProtection() ); foreach ($cellRanges as $cellRange) { - $recordData .= $this->_writeBIFF8CellRangeAddressFixed($cellRange); + $recordData .= $this->writeBIFF8CellRangeAddressFixed($cellRange); } // the rgbFeat structure @@ -2096,7 +2088,7 @@ private function _writeGuts() $col_level = 0; // Calculate the maximum column outline level. The equivalent calculation - // for the row outline level is carried out in _writeRow(). + // for the row outline level is carried out in writeRow(). $colcount = count($this->_colinfo); for ($i = 0; $i < $colcount; ++$i) { $col_level = max($this->_colinfo[$i][5], $col_level); @@ -2687,7 +2679,7 @@ private function _writeZoom() */ public function getEscher() { - return $this->_escher; + return $this->escher; } /** @@ -2697,7 +2689,7 @@ public function getEscher() */ public function setEscher(PHPExcel_Shared_Escher $pValue = null) { - $this->_escher = $pValue; + $this->escher = $pValue; } /** @@ -2706,8 +2698,8 @@ public function setEscher(PHPExcel_Shared_Escher $pValue = null) private function _writeMsoDrawing() { // write the Escher stream if necessary - if (isset($this->_escher)) { - $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); + if (isset($this->escher)) { + $writer = new PHPExcel_Writer_Excel5_Escher($this->escher); $data = $writer->close(); $spOffsets = $writer->getSpOffsets(); $spTypes = $writer->getSpTypes(); @@ -2938,8 +2930,8 @@ private function _writeDataValidity() if ($type == 0x03) { // list type $formula1 = str_replace(',', chr(0), $formula1); } - $this->_parser->parse($formula1); - $formula1 = $this->_parser->toReversePolish(); + $this->parser->parse($formula1); + $formula1 = $this->parser->toReversePolish(); $sz1 = strlen($formula1); } catch (PHPExcel_Exception $e) { $sz1 = 0; @@ -2954,8 +2946,8 @@ private function _writeDataValidity() if ($formula2 === '') { throw new PHPExcel_Writer_Exception('No formula2'); } - $this->_parser->parse($formula2); - $formula2 = $this->_parser->toReversePolish(); + $this->parser->parse($formula2); + $formula2 = $this->parser->toReversePolish(); $sz2 = strlen($formula2); } catch (PHPExcel_Exception $e) { $sz2 = 0; @@ -2966,7 +2958,7 @@ private function _writeDataValidity() // cell range address list $data .= pack('v', 0x0001); - $data .= $this->_writeBIFF8CellRangeAddressFixed($cellCoordinate); + $data .= $this->writeBIFF8CellRangeAddressFixed($cellCoordinate); $length = strlen($data); $header = pack("vv", $record, $length); @@ -3039,7 +3031,7 @@ private function _writePageLayoutView() * Write CFRule Record * @param PHPExcel_Style_Conditional $conditional */ - private function _writeCFRule(PHPExcel_Style_Conditional $conditional) + private function writeCFRule(PHPExcel_Style_Conditional $conditional) { $record = 0x01B1; // Record identifier @@ -3699,14 +3691,14 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional) $blockLineStyle |= 0x0D << 12; break; } - //@todo _writeCFRule() => $blockLineStyle => Index Color for left line - //@todo _writeCFRule() => $blockLineStyle => Index Color for right line - //@todo _writeCFRule() => $blockLineStyle => Top-left to bottom-right on/off - //@todo _writeCFRule() => $blockLineStyle => Bottom-left to top-right on/off + //@todo writeCFRule() => $blockLineStyle => Index Color for left line + //@todo writeCFRule() => $blockLineStyle => Index Color for right line + //@todo writeCFRule() => $blockLineStyle => Top-left to bottom-right on/off + //@todo writeCFRule() => $blockLineStyle => Bottom-left to top-right on/off $blockColor = 0; - //@todo _writeCFRule() => $blockColor => Index Color for top line - //@todo _writeCFRule() => $blockColor => Index Color for bottom line - //@todo _writeCFRule() => $blockColor => Index Color for diagonal line + //@todo writeCFRule() => $blockColor => Index Color for top line + //@todo writeCFRule() => $blockColor => Index Color for bottom line + //@todo writeCFRule() => $blockColor => Index Color for diagonal line switch ($conditional->getStyle()->getBorders()->getDiagonal()->getBorderStyle()) { case PHPExcel_Style_Border::BORDER_NONE: $blockColor |= 0x00 << 21; @@ -4214,7 +4206,7 @@ private function _writeCFRule(PHPExcel_Style_Conditional $conditional) /** * Write CFHeader record */ - private function _writeCFHeader() + private function writeCFHeader() { $record = 0x01B0; // Record identifier $length = 0x0016; // Bytes to follow diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 746ec55db..fddf7b27f 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -1221,7 +1221,7 @@ private function generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow } } } else { - if ($this->_preCalculateFormulas) { + if ($this->preCalculateFormulas) { $cellData = PHPExcel_Style_NumberFormat::toFormattedString( $cell->getCalculatedValue(), $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(), From e0cefe336073cd3b67766a02d5ea8997a4169dc7 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Fri, 22 May 2015 23:31:23 +0100 Subject: [PATCH 396/467] Another big chunk of psr-2 --- .../DggContainer/BstoreContainer/BSE.php | 4 +- .../PHPExcel/Writer/Excel2007/Comments.php | 8 +- Classes/PHPExcel/Writer/Excel2007/Drawing.php | 12 +- Classes/PHPExcel/Writer/Excel5.php | 26 +- Classes/PHPExcel/Writer/Excel5/BIFFwriter.php | 48 +- Classes/PHPExcel/Writer/Excel5/Escher.php | 134 +-- Classes/PHPExcel/Writer/Excel5/Font.php | 69 +- Classes/PHPExcel/Writer/Excel5/Parser.php | 996 +++++++++--------- Classes/PHPExcel/Writer/Excel5/Workbook.php | 637 ++++++----- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 154 +-- Classes/PHPExcel/Writer/Excel5/Xf.php | 12 +- 11 files changed, 1031 insertions(+), 1069 deletions(-) diff --git a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php index 9f8afa5d6..d17e91e16 100644 --- a/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php +++ b/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php @@ -43,7 +43,7 @@ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE * * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer */ - private $_parent; + private $parent; /** * The BLIP (Big Large Image or Picture) @@ -66,7 +66,7 @@ class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE */ public function setParent($parent) { - $this->_parent = $parent; + $this->parent = $parent; } /** diff --git a/Classes/PHPExcel/Writer/Excel2007/Comments.php b/Classes/PHPExcel/Writer/Excel2007/Comments.php index ee18e7941..7139f6c49 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Comments.php +++ b/Classes/PHPExcel/Writer/Excel2007/Comments.php @@ -73,7 +73,7 @@ public function writeComments(PHPExcel_Worksheet $pWorksheet = null) // Loop through comments $objWriter->startElement('commentList'); foreach ($comments as $key => $value) { - $this->_writeComment($objWriter, $key, $value, $authors); + $this->writeComment($objWriter, $key, $value, $authors); } $objWriter->endElement(); @@ -92,7 +92,7 @@ public function writeComments(PHPExcel_Worksheet $pWorksheet = null) * @param array $pAuthors Array of authors * @throws PHPExcel_Writer_Exception */ - public function _writeComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null, $pAuthors = null) + private function writeComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null, $pAuthors = null) { // comment $objWriter->startElement('comment'); @@ -170,7 +170,7 @@ public function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null) // Loop through comments foreach ($comments as $key => $value) { - $this->_writeVMLComment($objWriter, $key, $value); + $this->writeVMLComment($objWriter, $key, $value); } $objWriter->endElement(); @@ -187,7 +187,7 @@ public function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null) * @param PHPExcel_Comment $pComment Comment * @throws PHPExcel_Writer_Exception */ - public function _writeVMLComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null) + private function writeVMLComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null) { // Metadata list($column, $row) = PHPExcel_Cell::coordinateFromString($pCellReference); diff --git a/Classes/PHPExcel/Writer/Excel2007/Drawing.php b/Classes/PHPExcel/Writer/Excel2007/Drawing.php index 9b2779f7a..281438889 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Drawing.php +++ b/Classes/PHPExcel/Writer/Excel2007/Drawing.php @@ -58,7 +58,7 @@ public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $i = 1; $iterator = $pWorksheet->getDrawingCollection()->getIterator(); while ($iterator->valid()) { - $this->_writeDrawing($objWriter, $iterator->current(), $i); + $this->writeDrawing($objWriter, $iterator->current(), $i); $iterator->next(); ++$i; @@ -69,7 +69,7 @@ public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, // Loop through charts and write the chart position if ($chartCount > 0) { for ($c = 0; $c < $chartCount; ++$c) { - $this->_writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i); + $this->writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i); } } } @@ -88,7 +88,7 @@ public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, * @param int $pRelationId * @throws PHPExcel_Writer_Exception */ - public function _writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Chart $pChart = null, $pRelationId = -1) + public function writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Chart $pChart = null, $pRelationId = -1) { $tl = $pChart->getTopLeftPosition(); $tl['colRow'] = PHPExcel_Cell::coordinateFromString($tl['cell']); @@ -160,7 +160,7 @@ public function _writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExce * @param int $pRelationId * @throws PHPExcel_Writer_Exception */ - public function _writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet_BaseDrawing $pDrawing = null, $pRelationId = -1) + public function writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet_BaseDrawing $pDrawing = null, $pRelationId = -1) { if ($pRelationId >= 0) { // xdr:oneCellAnchor @@ -508,7 +508,7 @@ public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null // Loop through images foreach ($images as $key => $value) { - $this->_writeVMLHeaderFooterImage($objWriter, $key, $value); + $this->writeVMLHeaderFooterImage($objWriter, $key, $value); } $objWriter->endElement(); @@ -525,7 +525,7 @@ public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null * @param PHPExcel_Worksheet_HeaderFooterDrawing $pImage Image * @throws PHPExcel_Writer_Exception */ - public function _writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter = null, $pReference = '', PHPExcel_Worksheet_HeaderFooterDrawing $pImage = null) + private function writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter = null, $pReference = '', PHPExcel_Worksheet_HeaderFooterDrawing $pImage = null) { // Calculate object id preg_match('{(\d+)}', md5($pReference), $m); diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index 14d86124d..fed37fa22 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -123,12 +123,12 @@ public function save($pFilename = null) $this->colors = array(); // Initialise workbook writer - $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->phpExcel, $this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser); + $this->writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->phpExcel, $this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser); // Initialise worksheet writers $countSheets = $this->phpExcel->getSheetCount(); for ($i = 0; $i < $countSheets; ++$i) { - $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser, $this->preCalculateFormulas, $this->phpExcel->getSheet($i)); + $this->writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser, $this->preCalculateFormulas, $this->phpExcel->getSheet($i)); } // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook. @@ -139,25 +139,25 @@ public function save($pFilename = null) // for now, we use the first cellXf instead of cellStyleXf $cellXfCollection = $this->phpExcel->getCellXfCollection(); for ($i = 0; $i < 15; ++$i) { - $this->_writerWorkbook->addXfWriter($cellXfCollection[0], true); + $this->writerWorkbook->addXfWriter($cellXfCollection[0], true); } // add all the cell Xfs foreach ($this->phpExcel->getCellXfCollection() as $style) { - $this->_writerWorkbook->addXfWriter($style, false); + $this->writerWorkbook->addXfWriter($style, false); } // add fonts from rich text eleemnts for ($i = 0; $i < $countSheets; ++$i) { - foreach ($this->_writerWorksheets[$i]->_phpSheet->getCellCollection() as $cellID) { - $cell = $this->_writerWorksheets[$i]->_phpSheet->getCell($cellID); + foreach ($this->writerWorksheets[$i]->_phpSheet->getCellCollection() as $cellID) { + $cell = $this->writerWorksheets[$i]->_phpSheet->getCell($cellID); $cVal = $cell->getValue(); if ($cVal instanceof PHPExcel_RichText) { $elements = $cVal->getRichTextElements(); foreach ($elements as $element) { if ($element instanceof PHPExcel_RichText_Run) { $font = $element->getFont(); - $this->_writerWorksheets[$i]->_fntHashIndex[$font->getHashCode()] = $this->_writerWorkbook->_addFont($font); + $this->writerWorksheets[$i]->_fntHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font); } } } @@ -172,16 +172,16 @@ public function save($pFilename = null) // because the byte sizes of these are needed in the global workbook stream $worksheetSizes = array(); for ($i = 0; $i < $countSheets; ++$i) { - $this->_writerWorksheets[$i]->close(); - $worksheetSizes[] = $this->_writerWorksheets[$i]->_datasize; + $this->writerWorksheets[$i]->close(); + $worksheetSizes[] = $this->writerWorksheets[$i]->_datasize; } // add binary data for global workbook stream - $OLE->append($this->_writerWorkbook->writeWorkbook($worksheetSizes)); + $OLE->append($this->writerWorkbook->writeWorkbook($worksheetSizes)); // add binary data for sheet streams for ($i = 0; $i < $countSheets; ++$i) { - $OLE->append($this->_writerWorksheets[$i]->getData()); + $OLE->append($this->writerWorksheets[$i]->getData()); } $this->documentSummaryInformation = $this->writeDocumentSummaryInformation(); @@ -391,7 +391,7 @@ private function buildWorksheetEschers() $dgContainer->setLastSpId($lastSpId); // set the Escher object - $this->_writerWorksheets[$sheetIndex]->setEscher($escher); + $this->writerWorksheets[$sheetIndex]->setEscher($escher); } } @@ -530,7 +530,7 @@ private function buildWorkbookEscher() } // Set the Escher object - $this->_writerWorkbook->setEscher($escher); + $this->writerWorkbook->setEscher($escher); } /** diff --git a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php index e6d87a4ae..a79575239 100644 --- a/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php +++ b/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel5_BIFFwriter * * Copyright (c) 2006 - 2015 PHPExcel * @@ -58,15 +59,6 @@ // * License along with this library; if not, write to the Free Software // * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // */ - - -/** - * PHPExcel_Writer_Excel5_BIFFwriter - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel5_BIFFwriter { /** @@ -88,11 +80,11 @@ class PHPExcel_Writer_Excel5_BIFFwriter public $_datasize; /** - * The maximum length for a BIFF record (excluding record header and length field). See _addContinue() + * The maximum length for a BIFF record (excluding record header and length field). See addContinue() * @var integer - * @see _addContinue() + * @see addContinue() */ - public $_limit = 8224; + private $limit = 8224; /** * Constructor @@ -101,7 +93,7 @@ public function __construct() { $this->_data = ''; $this->_datasize = 0; -// $this->_limit = 8224; +// $this->limit = 8224; } /** @@ -136,25 +128,25 @@ public static function getByteOrder() * @param string $data binary data to append * @access private */ - public function _append($data) + protected function append($data) { - if (strlen($data) - 4 > $this->_limit) { - $data = $this->_addContinue($data); + if (strlen($data) - 4 > $this->limit) { + $data = $this->addContinue($data); } - $this->_data .= $data; - $this->_datasize += strlen($data); + $this->_data .= $data; + $this->_datasize += strlen($data); } /** - * General storage function like _append, but returns string instead of modifying $this->_data + * General storage function like append, but returns string instead of modifying $this->_data * * @param string $data binary data to write * @return string */ public function writeData($data) { - if (strlen($data) - 4 > $this->_limit) { - $data = $this->_addContinue($data); + if (strlen($data) - 4 > $this->limit) { + $data = $this->addContinue($data); } $this->_datasize += strlen($data); @@ -169,7 +161,7 @@ public function writeData($data) * 0x0010 Worksheet. * @access private */ - public function _storeBof($type) + protected function storeBof($type) { $record = 0x0809; // Record identifier (BIFF5-BIFF8) $length = 0x0010; @@ -184,7 +176,7 @@ public function _storeBof($type) $header = pack("vv", $record, $length); $data = pack("vvvv", $version, $type, $build, $year); - $this->_append($header . $data . $unknown); + $this->append($header . $data . $unknown); } /** @@ -192,13 +184,13 @@ public function _storeBof($type) * * @access private */ - public function _storeEof() + protected function storeEof() { $record = 0x000A; // Record identifier $length = 0x0000; // Number of bytes to follow $header = pack("vv", $record, $length); - $this->_append($header); + $this->append($header); } /** @@ -226,9 +218,9 @@ public function writeEof() * @return string A very convenient string of continue blocks * @access private */ - public function _addContinue($data) + private function addContinue($data) { - $limit = $this->_limit; + $limit = $this->limit; $record = 0x003C; // Record identifier // The first 2080/8224 bytes remain intact. However, we have to change diff --git a/Classes/PHPExcel/Writer/Excel5/Escher.php b/Classes/PHPExcel/Writer/Excel5/Escher.php index e7e79a843..c37fda9b6 100644 --- a/Classes/PHPExcel/Writer/Excel5/Escher.php +++ b/Classes/PHPExcel/Writer/Excel5/Escher.php @@ -38,26 +38,26 @@ class PHPExcel_Writer_Excel5_Escher /** * The object we are writing */ - private $_object; + private $object; /** * The written binary data */ - private $_data; + private $data; /** * Shape offsets. Positions in binary stream where a new shape record begins * * @var array */ - private $_spOffsets; + private $spOffsets; /** * Shape types. * * @var array */ - private $_spTypes; + private $spTypes; /** * Constructor @@ -66,7 +66,7 @@ class PHPExcel_Writer_Excel5_Escher */ public function __construct($object) { - $this->_object = $object; + $this->object = $object; } /** @@ -75,18 +75,18 @@ public function __construct($object) public function close() { // initialize - $this->_data = ''; + $this->data = ''; - switch (get_class($this->_object)) { + switch (get_class($this->object)) { case 'PHPExcel_Shared_Escher': - if ($dggContainer = $this->_object->getDggContainer()) { + if ($dggContainer = $this->object->getDggContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer); - $this->_data = $writer->close(); - } elseif ($dgContainer = $this->_object->getDgContainer()) { + $this->data = $writer->close(); + } elseif ($dgContainer = $this->object->getDgContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer); - $this->_data = $writer->close(); - $this->_spOffsets = $writer->getSpOffsets(); - $this->_spTypes = $writer->getSpTypes(); + $this->data = $writer->close(); + $this->spOffsets = $writer->getSpOffsets(); + $this->spTypes = $writer->getSpTypes(); } break; case 'PHPExcel_Shared_Escher_DggContainer': @@ -107,14 +107,14 @@ public function close() $dggData = pack( 'VVVV', - $this->_object->getSpIdMax(), // maximum shape identifier increased by one - $this->_object->getCDgSaved() + 1, // number of file identifier clusters increased by one - $this->_object->getCSpSaved(), - $this->_object->getCDgSaved() // count total number of drawings saved + $this->object->getSpIdMax(), // maximum shape identifier increased by one + $this->object->getCDgSaved() + 1, // number of file identifier clusters increased by one + $this->object->getCSpSaved(), + $this->object->getCDgSaved() // count total number of drawings saved ); // add file identifier clusters (one per drawing) - $IDCLs = $this->_object->getIDCLs(); + $IDCLs = $this->object->getIDCLs(); foreach ($IDCLs as $dgId => $maxReducedSpId) { $dggData .= pack('VV', $dgId, $maxReducedSpId + 1); @@ -124,7 +124,7 @@ public function close() $innerData .= $header . $dggData; // write the bstoreContainer - if ($bstoreContainer = $this->_object->getBstoreContainer()) { + if ($bstoreContainer = $this->object->getBstoreContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer); $innerData .= $writer->close(); } @@ -140,7 +140,7 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header . $innerData; + $this->data = $header . $innerData; break; case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer': // this is a container record @@ -149,7 +149,7 @@ public function close() $innerData = ''; // treat the inner data - if ($BSECollection = $this->_object->getBSECollection()) { + if ($BSECollection = $this->object->getBSECollection()) { foreach ($BSECollection as $BSE) { $writer = new PHPExcel_Writer_Excel5_Escher($BSE); $innerData .= $writer->close(); @@ -158,7 +158,7 @@ public function close() // write the record $recVer = 0xF; - $recInstance = count($this->_object->getBSECollection()); + $recInstance = count($this->object->getBSECollection()); $recType = 0xF001; $length = strlen($innerData); @@ -167,7 +167,7 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header . $innerData; + $this->data = $header . $innerData; break; case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE': // this is a semi-container record @@ -176,7 +176,7 @@ public function close() $innerData = ''; // here we treat the inner data - if ($blip = $this->_object->getBlip()) { + if ($blip = $this->object->getBlip()) { $writer = new PHPExcel_Writer_Excel5_Escher($blip); $innerData .= $writer->close(); } @@ -184,8 +184,8 @@ public function close() // initialize $data = ''; - $btWin32 = $this->_object->getBlipType(); - $btMacOS = $this->_object->getBlipType(); + $btWin32 = $this->object->getBlipType(); + $btMacOS = $this->object->getBlipType(); $data .= pack('CC', $btWin32, $btMacOS); $rgbUid = pack('VVVV', 0, 0, 0, 0); // todo @@ -205,7 +205,7 @@ public function close() // write the record $recVer = 0x2; - $recInstance = $this->_object->getBlipType(); + $recInstance = $this->object->getBlipType(); $recType = 0xF007; $length = strlen($data); @@ -214,15 +214,15 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header; + $this->data = $header; - $this->_data .= $data; + $this->data .= $data; break; case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip': // this is an atom record // write the record - switch ($this->_object->getParent()->getBlipType()) { + switch ($this->object->getParent()->getBlipType()) { case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: // initialize $innerData = ''; @@ -233,7 +233,7 @@ public function close() $tag = 0xFF; // todo $innerData .= pack('C', $tag); - $innerData .= $this->_object->getData(); + $innerData .= $this->object->getData(); $recVer = 0x0; $recInstance = 0x46A; @@ -245,9 +245,9 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header; + $this->data = $header; - $this->_data .= $innerData; + $this->data .= $innerData; break; case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: @@ -260,7 +260,7 @@ public function close() $tag = 0xFF; // todo $innerData .= pack('C', $tag); - $innerData .= $this->_object->getData(); + $innerData .= $this->object->getData(); $recVer = 0x0; $recInstance = 0x6E0; @@ -272,9 +272,9 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header; + $this->data = $header; - $this->_data .= $innerData; + $this->data .= $innerData; break; } break; @@ -286,7 +286,7 @@ public function close() // write the dg $recVer = 0x0; - $recInstance = $this->_object->getDgId(); + $recInstance = $this->object->getDgId(); $recType = 0xF008; $length = 8; @@ -296,12 +296,12 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); // number of shapes in this drawing (including group shape) - $countShapes = count($this->_object->getSpgrContainer()->getChildren()); - $innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId()); + $countShapes = count($this->object->getSpgrContainer()->getChildren()); + $innerData .= $header . pack('VV', $countShapes, $this->object->getLastSpId()); //$innerData .= $header . pack('VV', 0, 0); // write the spgrContainer - if ($spgrContainer = $this->_object->getSpgrContainer()) { + if ($spgrContainer = $this->object->getSpgrContainer()) { $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer); $innerData .= $writer->close(); @@ -314,8 +314,8 @@ public function close() $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes) } - $this->_spOffsets = $spOffsets; - $this->_spTypes = $spTypes; + $this->spOffsets = $spOffsets; + $this->spTypes = $spTypes; } // write the record @@ -329,7 +329,7 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header . $innerData; + $this->data = $header . $innerData; break; case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer': // this is a container record @@ -343,7 +343,7 @@ public function close() $spTypes = array(); // treat the inner data - foreach ($this->_object->getChildren() as $spContainer) { + foreach ($this->object->getChildren() as $spContainer) { $writer = new PHPExcel_Writer_Excel5_Escher($spContainer); $spData = $writer->close(); $innerData .= $spData; @@ -366,9 +366,9 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header . $innerData; - $this->_spOffsets = $spOffsets; - $this->_spTypes = $spTypes; + $this->data = $header . $innerData; + $this->spOffsets = $spOffsets; + $this->spTypes = $spTypes; break; case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer': // initialize @@ -377,7 +377,7 @@ public function close() // build the data // write group shape record, if necessary? - if ($this->_object->getSpgr()) { + if ($this->object->getSpgr()) { $recVer = 0x1; $recInstance = 0x0000; $recType = 0xF009; @@ -390,11 +390,11 @@ public function close() $data .= $header . pack('VVVV', 0, 0, 0, 0); } - $this->_spTypes[] = ($this->_object->getSpType()); + $this->spTypes[] = ($this->object->getSpType()); // write the shape record $recVer = 0x2; - $recInstance = $this->_object->getSpType(); // shape type + $recInstance = $this->object->getSpType(); // shape type $recType = 0xF00A; $length = 0x00000008; @@ -403,17 +403,17 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); - $data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x0005 : 0x0A00); + $data .= $header . pack('VV', $this->object->getSpId(), $this->object->getSpgr() ? 0x0005 : 0x0A00); // the options - if ($this->_object->getOPTCollection()) { + if ($this->object->getOPTCollection()) { $optData = ''; $recVer = 0x3; - $recInstance = count($this->_object->getOPTCollection()); + $recInstance = count($this->object->getOPTCollection()); $recType = 0xF00B; - foreach ($this->_object->getOPTCollection() as $property => $value) { + foreach ($this->object->getOPTCollection() as $property => $value) { $optData .= pack('vV', $property, $value); } $length = strlen($optData); @@ -426,7 +426,7 @@ public function close() } // the client anchor - if ($this->_object->getStartCoordinates()) { + if ($this->object->getStartCoordinates()) { $clientAnchorData = ''; $recVer = 0x0; @@ -434,28 +434,28 @@ public function close() $recType = 0xF010; // start coordinates - list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates()); + list($column, $row) = PHPExcel_Cell::coordinateFromString($this->object->getStartCoordinates()); $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1; $r1 = $row - 1; // start offsetX - $startOffsetX = $this->_object->getStartOffsetX(); + $startOffsetX = $this->object->getStartOffsetX(); // start offsetY - $startOffsetY = $this->_object->getStartOffsetY(); + $startOffsetY = $this->object->getStartOffsetY(); // end coordinates - list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates()); + list($column, $row) = PHPExcel_Cell::coordinateFromString($this->object->getEndCoordinates()); $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1; $r2 = $row - 1; // end offsetX - $endOffsetX = $this->_object->getEndOffsetX(); + $endOffsetX = $this->object->getEndOffsetX(); // end offsetY - $endOffsetY = $this->_object->getEndOffsetY(); + $endOffsetY = $this->object->getEndOffsetY(); - $clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(), $c1, $startOffsetX, $r1, $startOffsetY, $c2, $endOffsetX, $r2, $endOffsetY); + $clientAnchorData = pack('vvvvvvvvv', $this->object->getSpFlag(), $c1, $startOffsetX, $r1, $startOffsetY, $c2, $endOffsetX, $r2, $endOffsetY); $length = strlen($clientAnchorData); @@ -467,7 +467,7 @@ public function close() } // the client data, just empty for now - if (!$this->_object->getSpgr()) { + if (!$this->object->getSpgr()) { $clientDataData = ''; $recVer = 0x0; @@ -494,11 +494,11 @@ public function close() $header = pack('vvV', $recVerInstance, $recType, $length); - $this->_data = $header . $data; + $this->data = $header . $data; break; } - return $this->_data; + return $this->data; } /** @@ -508,7 +508,7 @@ public function close() */ public function getSpOffsets() { - return $this->_spOffsets; + return $this->spOffsets; } /** @@ -518,6 +518,6 @@ public function getSpOffsets() */ public function getSpTypes() { - return $this->_spTypes; + return $this->spTypes; } } diff --git a/Classes/PHPExcel/Writer/Excel5/Font.php b/Classes/PHPExcel/Writer/Excel5/Font.php index e67562b8f..ed85ff457 100644 --- a/Classes/PHPExcel/Writer/Excel5/Font.php +++ b/Classes/PHPExcel/Writer/Excel5/Font.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel5_Font * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,15 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -/** - * PHPExcel_Writer_Excel5_Font - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel5_Font { /** @@ -40,14 +32,14 @@ class PHPExcel_Writer_Excel5_Font * * @var int */ - private $_colorIndex; + private $colorIndex; /** * Font * * @var PHPExcel_Style_Font */ - private $_font; + private $font; /** * Constructor @@ -56,8 +48,8 @@ class PHPExcel_Writer_Excel5_Font */ public function __construct(PHPExcel_Style_Font $font = null) { - $this->_colorIndex = 0x7FFF; - $this->_font = $font; + $this->colorIndex = 0x7FFF; + $this->font = $font; } /** @@ -67,7 +59,7 @@ public function __construct(PHPExcel_Style_Font $font = null) */ public function setColorIndex($colorIndex) { - $this->_colorIndex = $colorIndex; + $this->colorIndex = $colorIndex; } /** @@ -80,24 +72,24 @@ public function writeFont() $font_outline = 0; $font_shadow = 0; - $icv = $this->_colorIndex; // Index to color palette - if ($this->_font->getSuperScript()) { + $icv = $this->colorIndex; // Index to color palette + if ($this->font->getSuperScript()) { $sss = 1; - } elseif ($this->_font->getSubScript()) { + } elseif ($this->font->getSubScript()) { $sss = 2; } else { $sss = 0; } $bFamily = 0; // Font family - $bCharSet = PHPExcel_Shared_Font::getCharsetFromFontName($this->_font->getName()); // Character set + $bCharSet = PHPExcel_Shared_Font::getCharsetFromFontName($this->font->getName()); // Character set $record = 0x31; // Record identifier $reserved = 0x00; // Reserved $grbit = 0x00; // Font attributes - if ($this->_font->getItalic()) { + if ($this->font->getItalic()) { $grbit |= 0x02; } - if ($this->_font->getStrikethrough()) { + if ($this->font->getStrikethrough()) { $grbit |= 0x08; } if ($font_outline) { @@ -110,20 +102,20 @@ public function writeFont() $data = pack( "vvvvvCCCC", // Fontsize (in twips) - $this->_font->getSize() * 20, + $this->font->getSize() * 20, $grbit, // Colour $icv, // Font weight - self::_mapBold($this->_font->getBold()), + self::mapBold($this->font->getBold()), // Superscript/Subscript $sss, - self::_mapUnderline($this->_font->getUnderline()), + self::mapUnderline($this->font->getUnderline()), $bFamily, $bCharSet, $reserved ); - $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($this->_font->getName()); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($this->font->getName()); $length = strlen($data); $header = pack("vv", $record, $length); @@ -137,12 +129,12 @@ public function writeFont() * @param boolean $bold * @return int */ - private static function _mapBold($bold) + private static function mapBold($bold) { if ($bold) { - return 0x2BC; // 700 = Bold font weight + return 0x2BC; // 700 = Bold font weight } - return 0x190; // 400 = Normal font weight + return 0x190; // 400 = Normal font weight } /** @@ -150,23 +142,24 @@ private static function _mapBold($bold) * @static array of int * */ - private static $_mapUnderline = array( - PHPExcel_Style_Font::UNDERLINE_NONE => 0x00, - PHPExcel_Style_Font::UNDERLINE_SINGLE => 0x01, - PHPExcel_Style_Font::UNDERLINE_DOUBLE => 0x02, - PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING => 0x21, - PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING => 0x22, - ); + private static $mapUnderline = array( + PHPExcel_Style_Font::UNDERLINE_NONE => 0x00, + PHPExcel_Style_Font::UNDERLINE_SINGLE => 0x01, + PHPExcel_Style_Font::UNDERLINE_DOUBLE => 0x02, + PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING => 0x21, + PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING => 0x22, + ); + /** * Map underline * * @param string * @return int */ - private static function _mapUnderline($underline) + private static function mapUnderline($underline) { - if (isset(self::$_mapUnderline[$underline])) { - return self::$_mapUnderline[$underline]; + if (isset(self::$mapUnderline[$underline])) { + return self::$mapUnderline[$underline]; } return 0x00; } diff --git a/Classes/PHPExcel/Writer/Excel5/Parser.php b/Classes/PHPExcel/Writer/Excel5/Parser.php index 05ea60ef7..0cf1c1d65 100644 --- a/Classes/PHPExcel/Writer/Excel5/Parser.php +++ b/Classes/PHPExcel/Writer/Excel5/Parser.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel5_Parser * * Copyright (c) 2006 - 2015 PHPExcel * @@ -48,15 +49,6 @@ // * License along with this library; if not, write to the Free Software // * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // */ - - -/** - * PHPExcel_Writer_Excel5_Parser - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel5_Parser { /** Constants */ @@ -77,43 +69,43 @@ class PHPExcel_Writer_Excel5_Parser * The index of the character we are currently looking at * @var integer */ - public $_current_char; + public $currentCharacter; /** * The token we are working on. * @var string */ - public $_current_token; + public $currentToken; /** * The formula to parse * @var string */ - public $_formula; + private $formula; /** * The character ahead of the current char * @var string */ - public $_lookahead; + public $lookAhead; /** * The parse tree to be generated * @var string */ - public $_parse_tree; + private $parseTree; /** * Array of external sheets * @var array */ - public $_ext_sheets; + private $externalSheets; /** * Array of sheet references in the form of REF structures * @var array */ - public $_references; + public $references; /** * The class constructor @@ -121,14 +113,14 @@ class PHPExcel_Writer_Excel5_Parser */ public function __construct() { - $this->_current_char = 0; - $this->_current_token = ''; // The token we are working on. - $this->_formula = ''; // The formula to parse. - $this->_lookahead = ''; // The character ahead of the current char. - $this->_parse_tree = ''; // The parse tree to be generated. - $this->_initializeHashes(); // Initialize the hashes: ptg's and function's ptg's - $this->_ext_sheets = array(); - $this->_references = array(); + $this->currentCharacter = 0; + $this->currentToken = ''; // The token we are working on. + $this->formula = ''; // The formula to parse. + $this->lookAhead = ''; // The character ahead of the current char. + $this->parseTree = ''; // The parse tree to be generated. + $this->initializeHashes(); // Initialize the hashes: ptg's and function's ptg's + $this->externalSheets = array(); + $this->references = array(); } /** @@ -136,7 +128,7 @@ public function __construct() * * @access private */ - private function _initializeHashes() + private function initializeHashes() { // The Excel ptg indices $this->ptg = array( @@ -235,7 +227,7 @@ private function _initializeHashes() 'ptgArea3dA' => 0x7B, 'ptgRefErr3dA' => 0x7C, 'ptgAreaErr3d' => 0x7D - ); + ); // Thanks to Michael Meeks and Gnumeric for the initial arg values. // @@ -250,259 +242,259 @@ private function _initializeHashes() // class: The reference, value or array class of the function args. // vol: The function is volatile. // - $this->_functions = array( - // function ptg args class vol - 'COUNT' => array( 0, -1, 0, 0 ), - 'IF' => array( 1, -1, 1, 0 ), - 'ISNA' => array( 2, 1, 1, 0 ), - 'ISERROR' => array( 3, 1, 1, 0 ), - 'SUM' => array( 4, -1, 0, 0 ), - 'AVERAGE' => array( 5, -1, 0, 0 ), - 'MIN' => array( 6, -1, 0, 0 ), - 'MAX' => array( 7, -1, 0, 0 ), - 'ROW' => array( 8, -1, 0, 0 ), - 'COLUMN' => array( 9, -1, 0, 0 ), - 'NA' => array( 10, 0, 0, 0 ), - 'NPV' => array( 11, -1, 1, 0 ), - 'STDEV' => array( 12, -1, 0, 0 ), - 'DOLLAR' => array( 13, -1, 1, 0 ), - 'FIXED' => array( 14, -1, 1, 0 ), - 'SIN' => array( 15, 1, 1, 0 ), - 'COS' => array( 16, 1, 1, 0 ), - 'TAN' => array( 17, 1, 1, 0 ), - 'ATAN' => array( 18, 1, 1, 0 ), - 'PI' => array( 19, 0, 1, 0 ), - 'SQRT' => array( 20, 1, 1, 0 ), - 'EXP' => array( 21, 1, 1, 0 ), - 'LN' => array( 22, 1, 1, 0 ), - 'LOG10' => array( 23, 1, 1, 0 ), - 'ABS' => array( 24, 1, 1, 0 ), - 'INT' => array( 25, 1, 1, 0 ), - 'SIGN' => array( 26, 1, 1, 0 ), - 'ROUND' => array( 27, 2, 1, 0 ), - 'LOOKUP' => array( 28, -1, 0, 0 ), - 'INDEX' => array( 29, -1, 0, 1 ), - 'REPT' => array( 30, 2, 1, 0 ), - 'MID' => array( 31, 3, 1, 0 ), - 'LEN' => array( 32, 1, 1, 0 ), - 'VALUE' => array( 33, 1, 1, 0 ), - 'TRUE' => array( 34, 0, 1, 0 ), - 'FALSE' => array( 35, 0, 1, 0 ), - 'AND' => array( 36, -1, 0, 0 ), - 'OR' => array( 37, -1, 0, 0 ), - 'NOT' => array( 38, 1, 1, 0 ), - 'MOD' => array( 39, 2, 1, 0 ), - 'DCOUNT' => array( 40, 3, 0, 0 ), - 'DSUM' => array( 41, 3, 0, 0 ), - 'DAVERAGE' => array( 42, 3, 0, 0 ), - 'DMIN' => array( 43, 3, 0, 0 ), - 'DMAX' => array( 44, 3, 0, 0 ), - 'DSTDEV' => array( 45, 3, 0, 0 ), - 'VAR' => array( 46, -1, 0, 0 ), - 'DVAR' => array( 47, 3, 0, 0 ), - 'TEXT' => array( 48, 2, 1, 0 ), - 'LINEST' => array( 49, -1, 0, 0 ), - 'TREND' => array( 50, -1, 0, 0 ), - 'LOGEST' => array( 51, -1, 0, 0 ), - 'GROWTH' => array( 52, -1, 0, 0 ), - 'PV' => array( 56, -1, 1, 0 ), - 'FV' => array( 57, -1, 1, 0 ), - 'NPER' => array( 58, -1, 1, 0 ), - 'PMT' => array( 59, -1, 1, 0 ), - 'RATE' => array( 60, -1, 1, 0 ), - 'MIRR' => array( 61, 3, 0, 0 ), - 'IRR' => array( 62, -1, 0, 0 ), - 'RAND' => array( 63, 0, 1, 1 ), - 'MATCH' => array( 64, -1, 0, 0 ), - 'DATE' => array( 65, 3, 1, 0 ), - 'TIME' => array( 66, 3, 1, 0 ), - 'DAY' => array( 67, 1, 1, 0 ), - 'MONTH' => array( 68, 1, 1, 0 ), - 'YEAR' => array( 69, 1, 1, 0 ), - 'WEEKDAY' => array( 70, -1, 1, 0 ), - 'HOUR' => array( 71, 1, 1, 0 ), - 'MINUTE' => array( 72, 1, 1, 0 ), - 'SECOND' => array( 73, 1, 1, 0 ), - 'NOW' => array( 74, 0, 1, 1 ), - 'AREAS' => array( 75, 1, 0, 1 ), - 'ROWS' => array( 76, 1, 0, 1 ), - 'COLUMNS' => array( 77, 1, 0, 1 ), - 'OFFSET' => array( 78, -1, 0, 1 ), - 'SEARCH' => array( 82, -1, 1, 0 ), - 'TRANSPOSE' => array( 83, 1, 1, 0 ), - 'TYPE' => array( 86, 1, 1, 0 ), - 'ATAN2' => array( 97, 2, 1, 0 ), - 'ASIN' => array( 98, 1, 1, 0 ), - 'ACOS' => array( 99, 1, 1, 0 ), - 'CHOOSE' => array( 100, -1, 1, 0 ), - 'HLOOKUP' => array( 101, -1, 0, 0 ), - 'VLOOKUP' => array( 102, -1, 0, 0 ), - 'ISREF' => array( 105, 1, 0, 0 ), - 'LOG' => array( 109, -1, 1, 0 ), - 'CHAR' => array( 111, 1, 1, 0 ), - 'LOWER' => array( 112, 1, 1, 0 ), - 'UPPER' => array( 113, 1, 1, 0 ), - 'PROPER' => array( 114, 1, 1, 0 ), - 'LEFT' => array( 115, -1, 1, 0 ), - 'RIGHT' => array( 116, -1, 1, 0 ), - 'EXACT' => array( 117, 2, 1, 0 ), - 'TRIM' => array( 118, 1, 1, 0 ), - 'REPLACE' => array( 119, 4, 1, 0 ), - 'SUBSTITUTE' => array( 120, -1, 1, 0 ), - 'CODE' => array( 121, 1, 1, 0 ), - 'FIND' => array( 124, -1, 1, 0 ), - 'CELL' => array( 125, -1, 0, 1 ), - 'ISERR' => array( 126, 1, 1, 0 ), - 'ISTEXT' => array( 127, 1, 1, 0 ), - 'ISNUMBER' => array( 128, 1, 1, 0 ), - 'ISBLANK' => array( 129, 1, 1, 0 ), - 'T' => array( 130, 1, 0, 0 ), - 'N' => array( 131, 1, 0, 0 ), - 'DATEVALUE' => array( 140, 1, 1, 0 ), - 'TIMEVALUE' => array( 141, 1, 1, 0 ), - 'SLN' => array( 142, 3, 1, 0 ), - 'SYD' => array( 143, 4, 1, 0 ), - 'DDB' => array( 144, -1, 1, 0 ), - 'INDIRECT' => array( 148, -1, 1, 1 ), - 'CALL' => array( 150, -1, 1, 0 ), - 'CLEAN' => array( 162, 1, 1, 0 ), - 'MDETERM' => array( 163, 1, 2, 0 ), - 'MINVERSE' => array( 164, 1, 2, 0 ), - 'MMULT' => array( 165, 2, 2, 0 ), - 'IPMT' => array( 167, -1, 1, 0 ), - 'PPMT' => array( 168, -1, 1, 0 ), - 'COUNTA' => array( 169, -1, 0, 0 ), - 'PRODUCT' => array( 183, -1, 0, 0 ), - 'FACT' => array( 184, 1, 1, 0 ), - 'DPRODUCT' => array( 189, 3, 0, 0 ), - 'ISNONTEXT' => array( 190, 1, 1, 0 ), - 'STDEVP' => array( 193, -1, 0, 0 ), - 'VARP' => array( 194, -1, 0, 0 ), - 'DSTDEVP' => array( 195, 3, 0, 0 ), - 'DVARP' => array( 196, 3, 0, 0 ), - 'TRUNC' => array( 197, -1, 1, 0 ), - 'ISLOGICAL' => array( 198, 1, 1, 0 ), - 'DCOUNTA' => array( 199, 3, 0, 0 ), - 'USDOLLAR' => array( 204, -1, 1, 0 ), - 'FINDB' => array( 205, -1, 1, 0 ), - 'SEARCHB' => array( 206, -1, 1, 0 ), - 'REPLACEB' => array( 207, 4, 1, 0 ), - 'LEFTB' => array( 208, -1, 1, 0 ), - 'RIGHTB' => array( 209, -1, 1, 0 ), - 'MIDB' => array( 210, 3, 1, 0 ), - 'LENB' => array( 211, 1, 1, 0 ), - 'ROUNDUP' => array( 212, 2, 1, 0 ), - 'ROUNDDOWN' => array( 213, 2, 1, 0 ), - 'ASC' => array( 214, 1, 1, 0 ), - 'DBCS' => array( 215, 1, 1, 0 ), - 'RANK' => array( 216, -1, 0, 0 ), - 'ADDRESS' => array( 219, -1, 1, 0 ), - 'DAYS360' => array( 220, -1, 1, 0 ), - 'TODAY' => array( 221, 0, 1, 1 ), - 'VDB' => array( 222, -1, 1, 0 ), - 'MEDIAN' => array( 227, -1, 0, 0 ), - 'SUMPRODUCT' => array( 228, -1, 2, 0 ), - 'SINH' => array( 229, 1, 1, 0 ), - 'COSH' => array( 230, 1, 1, 0 ), - 'TANH' => array( 231, 1, 1, 0 ), - 'ASINH' => array( 232, 1, 1, 0 ), - 'ACOSH' => array( 233, 1, 1, 0 ), - 'ATANH' => array( 234, 1, 1, 0 ), - 'DGET' => array( 235, 3, 0, 0 ), - 'INFO' => array( 244, 1, 1, 1 ), - 'DB' => array( 247, -1, 1, 0 ), - 'FREQUENCY' => array( 252, 2, 0, 0 ), - 'ERROR.TYPE' => array( 261, 1, 1, 0 ), - 'REGISTER.ID' => array( 267, -1, 1, 0 ), - 'AVEDEV' => array( 269, -1, 0, 0 ), - 'BETADIST' => array( 270, -1, 1, 0 ), - 'GAMMALN' => array( 271, 1, 1, 0 ), - 'BETAINV' => array( 272, -1, 1, 0 ), - 'BINOMDIST' => array( 273, 4, 1, 0 ), - 'CHIDIST' => array( 274, 2, 1, 0 ), - 'CHIINV' => array( 275, 2, 1, 0 ), - 'COMBIN' => array( 276, 2, 1, 0 ), - 'CONFIDENCE' => array( 277, 3, 1, 0 ), - 'CRITBINOM' => array( 278, 3, 1, 0 ), - 'EVEN' => array( 279, 1, 1, 0 ), - 'EXPONDIST' => array( 280, 3, 1, 0 ), - 'FDIST' => array( 281, 3, 1, 0 ), - 'FINV' => array( 282, 3, 1, 0 ), - 'FISHER' => array( 283, 1, 1, 0 ), - 'FISHERINV' => array( 284, 1, 1, 0 ), - 'FLOOR' => array( 285, 2, 1, 0 ), - 'GAMMADIST' => array( 286, 4, 1, 0 ), - 'GAMMAINV' => array( 287, 3, 1, 0 ), - 'CEILING' => array( 288, 2, 1, 0 ), - 'HYPGEOMDIST' => array( 289, 4, 1, 0 ), - 'LOGNORMDIST' => array( 290, 3, 1, 0 ), - 'LOGINV' => array( 291, 3, 1, 0 ), - 'NEGBINOMDIST' => array( 292, 3, 1, 0 ), - 'NORMDIST' => array( 293, 4, 1, 0 ), - 'NORMSDIST' => array( 294, 1, 1, 0 ), - 'NORMINV' => array( 295, 3, 1, 0 ), - 'NORMSINV' => array( 296, 1, 1, 0 ), - 'STANDARDIZE' => array( 297, 3, 1, 0 ), - 'ODD' => array( 298, 1, 1, 0 ), - 'PERMUT' => array( 299, 2, 1, 0 ), - 'POISSON' => array( 300, 3, 1, 0 ), - 'TDIST' => array( 301, 3, 1, 0 ), - 'WEIBULL' => array( 302, 4, 1, 0 ), - 'SUMXMY2' => array( 303, 2, 2, 0 ), - 'SUMX2MY2' => array( 304, 2, 2, 0 ), - 'SUMX2PY2' => array( 305, 2, 2, 0 ), - 'CHITEST' => array( 306, 2, 2, 0 ), - 'CORREL' => array( 307, 2, 2, 0 ), - 'COVAR' => array( 308, 2, 2, 0 ), - 'FORECAST' => array( 309, 3, 2, 0 ), - 'FTEST' => array( 310, 2, 2, 0 ), - 'INTERCEPT' => array( 311, 2, 2, 0 ), - 'PEARSON' => array( 312, 2, 2, 0 ), - 'RSQ' => array( 313, 2, 2, 0 ), - 'STEYX' => array( 314, 2, 2, 0 ), - 'SLOPE' => array( 315, 2, 2, 0 ), - 'TTEST' => array( 316, 4, 2, 0 ), - 'PROB' => array( 317, -1, 2, 0 ), - 'DEVSQ' => array( 318, -1, 0, 0 ), - 'GEOMEAN' => array( 319, -1, 0, 0 ), - 'HARMEAN' => array( 320, -1, 0, 0 ), - 'SUMSQ' => array( 321, -1, 0, 0 ), - 'KURT' => array( 322, -1, 0, 0 ), - 'SKEW' => array( 323, -1, 0, 0 ), - 'ZTEST' => array( 324, -1, 0, 0 ), - 'LARGE' => array( 325, 2, 0, 0 ), - 'SMALL' => array( 326, 2, 0, 0 ), - 'QUARTILE' => array( 327, 2, 0, 0 ), - 'PERCENTILE' => array( 328, 2, 0, 0 ), - 'PERCENTRANK' => array( 329, -1, 0, 0 ), - 'MODE' => array( 330, -1, 2, 0 ), - 'TRIMMEAN' => array( 331, 2, 0, 0 ), - 'TINV' => array( 332, 2, 1, 0 ), - 'CONCATENATE' => array( 336, -1, 1, 0 ), - 'POWER' => array( 337, 2, 1, 0 ), - 'RADIANS' => array( 342, 1, 1, 0 ), - 'DEGREES' => array( 343, 1, 1, 0 ), - 'SUBTOTAL' => array( 344, -1, 0, 0 ), - 'SUMIF' => array( 345, -1, 0, 0 ), - 'COUNTIF' => array( 346, 2, 0, 0 ), - 'COUNTBLANK' => array( 347, 1, 0, 0 ), - 'ISPMT' => array( 350, 4, 1, 0 ), - 'DATEDIF' => array( 351, 3, 1, 0 ), - 'DATESTRING' => array( 352, 1, 1, 0 ), - 'NUMBERSTRING' => array( 353, 2, 1, 0 ), - 'ROMAN' => array( 354, -1, 1, 0 ), - 'GETPIVOTDATA' => array( 358, -1, 0, 0 ), - 'HYPERLINK' => array( 359, -1, 1, 0 ), - 'PHONETIC' => array( 360, 1, 0, 0 ), - 'AVERAGEA' => array( 361, -1, 0, 0 ), - 'MAXA' => array( 362, -1, 0, 0 ), - 'MINA' => array( 363, -1, 0, 0 ), - 'STDEVPA' => array( 364, -1, 0, 0 ), - 'VARPA' => array( 365, -1, 0, 0 ), - 'STDEVA' => array( 366, -1, 0, 0 ), - 'VARA' => array( 367, -1, 0, 0 ), - 'BAHTTEXT' => array( 368, 1, 0, 0 ), - ); + $this->functions = array( + // function ptg args class vol + 'COUNT' => array( 0, -1, 0, 0 ), + 'IF' => array( 1, -1, 1, 0 ), + 'ISNA' => array( 2, 1, 1, 0 ), + 'ISERROR' => array( 3, 1, 1, 0 ), + 'SUM' => array( 4, -1, 0, 0 ), + 'AVERAGE' => array( 5, -1, 0, 0 ), + 'MIN' => array( 6, -1, 0, 0 ), + 'MAX' => array( 7, -1, 0, 0 ), + 'ROW' => array( 8, -1, 0, 0 ), + 'COLUMN' => array( 9, -1, 0, 0 ), + 'NA' => array( 10, 0, 0, 0 ), + 'NPV' => array( 11, -1, 1, 0 ), + 'STDEV' => array( 12, -1, 0, 0 ), + 'DOLLAR' => array( 13, -1, 1, 0 ), + 'FIXED' => array( 14, -1, 1, 0 ), + 'SIN' => array( 15, 1, 1, 0 ), + 'COS' => array( 16, 1, 1, 0 ), + 'TAN' => array( 17, 1, 1, 0 ), + 'ATAN' => array( 18, 1, 1, 0 ), + 'PI' => array( 19, 0, 1, 0 ), + 'SQRT' => array( 20, 1, 1, 0 ), + 'EXP' => array( 21, 1, 1, 0 ), + 'LN' => array( 22, 1, 1, 0 ), + 'LOG10' => array( 23, 1, 1, 0 ), + 'ABS' => array( 24, 1, 1, 0 ), + 'INT' => array( 25, 1, 1, 0 ), + 'SIGN' => array( 26, 1, 1, 0 ), + 'ROUND' => array( 27, 2, 1, 0 ), + 'LOOKUP' => array( 28, -1, 0, 0 ), + 'INDEX' => array( 29, -1, 0, 1 ), + 'REPT' => array( 30, 2, 1, 0 ), + 'MID' => array( 31, 3, 1, 0 ), + 'LEN' => array( 32, 1, 1, 0 ), + 'VALUE' => array( 33, 1, 1, 0 ), + 'TRUE' => array( 34, 0, 1, 0 ), + 'FALSE' => array( 35, 0, 1, 0 ), + 'AND' => array( 36, -1, 0, 0 ), + 'OR' => array( 37, -1, 0, 0 ), + 'NOT' => array( 38, 1, 1, 0 ), + 'MOD' => array( 39, 2, 1, 0 ), + 'DCOUNT' => array( 40, 3, 0, 0 ), + 'DSUM' => array( 41, 3, 0, 0 ), + 'DAVERAGE' => array( 42, 3, 0, 0 ), + 'DMIN' => array( 43, 3, 0, 0 ), + 'DMAX' => array( 44, 3, 0, 0 ), + 'DSTDEV' => array( 45, 3, 0, 0 ), + 'VAR' => array( 46, -1, 0, 0 ), + 'DVAR' => array( 47, 3, 0, 0 ), + 'TEXT' => array( 48, 2, 1, 0 ), + 'LINEST' => array( 49, -1, 0, 0 ), + 'TREND' => array( 50, -1, 0, 0 ), + 'LOGEST' => array( 51, -1, 0, 0 ), + 'GROWTH' => array( 52, -1, 0, 0 ), + 'PV' => array( 56, -1, 1, 0 ), + 'FV' => array( 57, -1, 1, 0 ), + 'NPER' => array( 58, -1, 1, 0 ), + 'PMT' => array( 59, -1, 1, 0 ), + 'RATE' => array( 60, -1, 1, 0 ), + 'MIRR' => array( 61, 3, 0, 0 ), + 'IRR' => array( 62, -1, 0, 0 ), + 'RAND' => array( 63, 0, 1, 1 ), + 'MATCH' => array( 64, -1, 0, 0 ), + 'DATE' => array( 65, 3, 1, 0 ), + 'TIME' => array( 66, 3, 1, 0 ), + 'DAY' => array( 67, 1, 1, 0 ), + 'MONTH' => array( 68, 1, 1, 0 ), + 'YEAR' => array( 69, 1, 1, 0 ), + 'WEEKDAY' => array( 70, -1, 1, 0 ), + 'HOUR' => array( 71, 1, 1, 0 ), + 'MINUTE' => array( 72, 1, 1, 0 ), + 'SECOND' => array( 73, 1, 1, 0 ), + 'NOW' => array( 74, 0, 1, 1 ), + 'AREAS' => array( 75, 1, 0, 1 ), + 'ROWS' => array( 76, 1, 0, 1 ), + 'COLUMNS' => array( 77, 1, 0, 1 ), + 'OFFSET' => array( 78, -1, 0, 1 ), + 'SEARCH' => array( 82, -1, 1, 0 ), + 'TRANSPOSE' => array( 83, 1, 1, 0 ), + 'TYPE' => array( 86, 1, 1, 0 ), + 'ATAN2' => array( 97, 2, 1, 0 ), + 'ASIN' => array( 98, 1, 1, 0 ), + 'ACOS' => array( 99, 1, 1, 0 ), + 'CHOOSE' => array( 100, -1, 1, 0 ), + 'HLOOKUP' => array( 101, -1, 0, 0 ), + 'VLOOKUP' => array( 102, -1, 0, 0 ), + 'ISREF' => array( 105, 1, 0, 0 ), + 'LOG' => array( 109, -1, 1, 0 ), + 'CHAR' => array( 111, 1, 1, 0 ), + 'LOWER' => array( 112, 1, 1, 0 ), + 'UPPER' => array( 113, 1, 1, 0 ), + 'PROPER' => array( 114, 1, 1, 0 ), + 'LEFT' => array( 115, -1, 1, 0 ), + 'RIGHT' => array( 116, -1, 1, 0 ), + 'EXACT' => array( 117, 2, 1, 0 ), + 'TRIM' => array( 118, 1, 1, 0 ), + 'REPLACE' => array( 119, 4, 1, 0 ), + 'SUBSTITUTE' => array( 120, -1, 1, 0 ), + 'CODE' => array( 121, 1, 1, 0 ), + 'FIND' => array( 124, -1, 1, 0 ), + 'CELL' => array( 125, -1, 0, 1 ), + 'ISERR' => array( 126, 1, 1, 0 ), + 'ISTEXT' => array( 127, 1, 1, 0 ), + 'ISNUMBER' => array( 128, 1, 1, 0 ), + 'ISBLANK' => array( 129, 1, 1, 0 ), + 'T' => array( 130, 1, 0, 0 ), + 'N' => array( 131, 1, 0, 0 ), + 'DATEVALUE' => array( 140, 1, 1, 0 ), + 'TIMEVALUE' => array( 141, 1, 1, 0 ), + 'SLN' => array( 142, 3, 1, 0 ), + 'SYD' => array( 143, 4, 1, 0 ), + 'DDB' => array( 144, -1, 1, 0 ), + 'INDIRECT' => array( 148, -1, 1, 1 ), + 'CALL' => array( 150, -1, 1, 0 ), + 'CLEAN' => array( 162, 1, 1, 0 ), + 'MDETERM' => array( 163, 1, 2, 0 ), + 'MINVERSE' => array( 164, 1, 2, 0 ), + 'MMULT' => array( 165, 2, 2, 0 ), + 'IPMT' => array( 167, -1, 1, 0 ), + 'PPMT' => array( 168, -1, 1, 0 ), + 'COUNTA' => array( 169, -1, 0, 0 ), + 'PRODUCT' => array( 183, -1, 0, 0 ), + 'FACT' => array( 184, 1, 1, 0 ), + 'DPRODUCT' => array( 189, 3, 0, 0 ), + 'ISNONTEXT' => array( 190, 1, 1, 0 ), + 'STDEVP' => array( 193, -1, 0, 0 ), + 'VARP' => array( 194, -1, 0, 0 ), + 'DSTDEVP' => array( 195, 3, 0, 0 ), + 'DVARP' => array( 196, 3, 0, 0 ), + 'TRUNC' => array( 197, -1, 1, 0 ), + 'ISLOGICAL' => array( 198, 1, 1, 0 ), + 'DCOUNTA' => array( 199, 3, 0, 0 ), + 'USDOLLAR' => array( 204, -1, 1, 0 ), + 'FINDB' => array( 205, -1, 1, 0 ), + 'SEARCHB' => array( 206, -1, 1, 0 ), + 'REPLACEB' => array( 207, 4, 1, 0 ), + 'LEFTB' => array( 208, -1, 1, 0 ), + 'RIGHTB' => array( 209, -1, 1, 0 ), + 'MIDB' => array( 210, 3, 1, 0 ), + 'LENB' => array( 211, 1, 1, 0 ), + 'ROUNDUP' => array( 212, 2, 1, 0 ), + 'ROUNDDOWN' => array( 213, 2, 1, 0 ), + 'ASC' => array( 214, 1, 1, 0 ), + 'DBCS' => array( 215, 1, 1, 0 ), + 'RANK' => array( 216, -1, 0, 0 ), + 'ADDRESS' => array( 219, -1, 1, 0 ), + 'DAYS360' => array( 220, -1, 1, 0 ), + 'TODAY' => array( 221, 0, 1, 1 ), + 'VDB' => array( 222, -1, 1, 0 ), + 'MEDIAN' => array( 227, -1, 0, 0 ), + 'SUMPRODUCT' => array( 228, -1, 2, 0 ), + 'SINH' => array( 229, 1, 1, 0 ), + 'COSH' => array( 230, 1, 1, 0 ), + 'TANH' => array( 231, 1, 1, 0 ), + 'ASINH' => array( 232, 1, 1, 0 ), + 'ACOSH' => array( 233, 1, 1, 0 ), + 'ATANH' => array( 234, 1, 1, 0 ), + 'DGET' => array( 235, 3, 0, 0 ), + 'INFO' => array( 244, 1, 1, 1 ), + 'DB' => array( 247, -1, 1, 0 ), + 'FREQUENCY' => array( 252, 2, 0, 0 ), + 'ERROR.TYPE' => array( 261, 1, 1, 0 ), + 'REGISTER.ID' => array( 267, -1, 1, 0 ), + 'AVEDEV' => array( 269, -1, 0, 0 ), + 'BETADIST' => array( 270, -1, 1, 0 ), + 'GAMMALN' => array( 271, 1, 1, 0 ), + 'BETAINV' => array( 272, -1, 1, 0 ), + 'BINOMDIST' => array( 273, 4, 1, 0 ), + 'CHIDIST' => array( 274, 2, 1, 0 ), + 'CHIINV' => array( 275, 2, 1, 0 ), + 'COMBIN' => array( 276, 2, 1, 0 ), + 'CONFIDENCE' => array( 277, 3, 1, 0 ), + 'CRITBINOM' => array( 278, 3, 1, 0 ), + 'EVEN' => array( 279, 1, 1, 0 ), + 'EXPONDIST' => array( 280, 3, 1, 0 ), + 'FDIST' => array( 281, 3, 1, 0 ), + 'FINV' => array( 282, 3, 1, 0 ), + 'FISHER' => array( 283, 1, 1, 0 ), + 'FISHERINV' => array( 284, 1, 1, 0 ), + 'FLOOR' => array( 285, 2, 1, 0 ), + 'GAMMADIST' => array( 286, 4, 1, 0 ), + 'GAMMAINV' => array( 287, 3, 1, 0 ), + 'CEILING' => array( 288, 2, 1, 0 ), + 'HYPGEOMDIST' => array( 289, 4, 1, 0 ), + 'LOGNORMDIST' => array( 290, 3, 1, 0 ), + 'LOGINV' => array( 291, 3, 1, 0 ), + 'NEGBINOMDIST' => array( 292, 3, 1, 0 ), + 'NORMDIST' => array( 293, 4, 1, 0 ), + 'NORMSDIST' => array( 294, 1, 1, 0 ), + 'NORMINV' => array( 295, 3, 1, 0 ), + 'NORMSINV' => array( 296, 1, 1, 0 ), + 'STANDARDIZE' => array( 297, 3, 1, 0 ), + 'ODD' => array( 298, 1, 1, 0 ), + 'PERMUT' => array( 299, 2, 1, 0 ), + 'POISSON' => array( 300, 3, 1, 0 ), + 'TDIST' => array( 301, 3, 1, 0 ), + 'WEIBULL' => array( 302, 4, 1, 0 ), + 'SUMXMY2' => array( 303, 2, 2, 0 ), + 'SUMX2MY2' => array( 304, 2, 2, 0 ), + 'SUMX2PY2' => array( 305, 2, 2, 0 ), + 'CHITEST' => array( 306, 2, 2, 0 ), + 'CORREL' => array( 307, 2, 2, 0 ), + 'COVAR' => array( 308, 2, 2, 0 ), + 'FORECAST' => array( 309, 3, 2, 0 ), + 'FTEST' => array( 310, 2, 2, 0 ), + 'INTERCEPT' => array( 311, 2, 2, 0 ), + 'PEARSON' => array( 312, 2, 2, 0 ), + 'RSQ' => array( 313, 2, 2, 0 ), + 'STEYX' => array( 314, 2, 2, 0 ), + 'SLOPE' => array( 315, 2, 2, 0 ), + 'TTEST' => array( 316, 4, 2, 0 ), + 'PROB' => array( 317, -1, 2, 0 ), + 'DEVSQ' => array( 318, -1, 0, 0 ), + 'GEOMEAN' => array( 319, -1, 0, 0 ), + 'HARMEAN' => array( 320, -1, 0, 0 ), + 'SUMSQ' => array( 321, -1, 0, 0 ), + 'KURT' => array( 322, -1, 0, 0 ), + 'SKEW' => array( 323, -1, 0, 0 ), + 'ZTEST' => array( 324, -1, 0, 0 ), + 'LARGE' => array( 325, 2, 0, 0 ), + 'SMALL' => array( 326, 2, 0, 0 ), + 'QUARTILE' => array( 327, 2, 0, 0 ), + 'PERCENTILE' => array( 328, 2, 0, 0 ), + 'PERCENTRANK' => array( 329, -1, 0, 0 ), + 'MODE' => array( 330, -1, 2, 0 ), + 'TRIMMEAN' => array( 331, 2, 0, 0 ), + 'TINV' => array( 332, 2, 1, 0 ), + 'CONCATENATE' => array( 336, -1, 1, 0 ), + 'POWER' => array( 337, 2, 1, 0 ), + 'RADIANS' => array( 342, 1, 1, 0 ), + 'DEGREES' => array( 343, 1, 1, 0 ), + 'SUBTOTAL' => array( 344, -1, 0, 0 ), + 'SUMIF' => array( 345, -1, 0, 0 ), + 'COUNTIF' => array( 346, 2, 0, 0 ), + 'COUNTBLANK' => array( 347, 1, 0, 0 ), + 'ISPMT' => array( 350, 4, 1, 0 ), + 'DATEDIF' => array( 351, 3, 1, 0 ), + 'DATESTRING' => array( 352, 1, 1, 0 ), + 'NUMBERSTRING' => array( 353, 2, 1, 0 ), + 'ROMAN' => array( 354, -1, 1, 0 ), + 'GETPIVOTDATA' => array( 358, -1, 0, 0 ), + 'HYPERLINK' => array( 359, -1, 1, 0 ), + 'PHONETIC' => array( 360, 1, 0, 0 ), + 'AVERAGEA' => array( 361, -1, 0, 0 ), + 'MAXA' => array( 362, -1, 0, 0 ), + 'MINA' => array( 363, -1, 0, 0 ), + 'STDEVPA' => array( 364, -1, 0, 0 ), + 'VARPA' => array( 365, -1, 0, 0 ), + 'STDEVA' => array( 366, -1, 0, 0 ), + 'VARA' => array( 367, -1, 0, 0 ), + 'BAHTTEXT' => array( 368, 1, 0, 0 ), + ); } /** @@ -512,37 +504,37 @@ private function _initializeHashes() * @param mixed $token The token to convert. * @return mixed the converted token on success */ - private function _convert($token) + private function convert($token) { if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token)) { - return $this->_convertString($token); + return $this->convertString($token); } elseif (is_numeric($token)) { - return $this->_convertNumber($token); + return $this->convertNumber($token); // match references like A1 or $A$1 } elseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/', $token)) { - return $this->_convertRef2d($token); + return $this->convertRef2d($token); // match external references like Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1 } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u", $token)) { - return $this->_convertRef3d($token); + return $this->convertRef3d($token); // match external references like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1 } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u", $token)) { - return $this->_convertRef3d($token); + return $this->convertRef3d($token); // match ranges like A1:B2 or $A$1:$B$2 } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\:(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/', $token)) { - return $this->_convertRange2d($token); + return $this->convertRange2d($token); // match external ranges like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u", $token)) { - return $this->_convertRange3d($token); + return $this->convertRange3d($token); // match external ranges like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u", $token)) { - return $this->_convertRange3d($token); + return $this->convertRange3d($token); // operators (including parentheses) } elseif (isset($this->ptg[$token])) { @@ -550,12 +542,12 @@ private function _convert($token) // match error codes } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { - return $this->_convertError($token); + return $this->convertError($token); // commented so argument number can be processed correctly. See toReversePolish(). /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/", $token)) { - return($this->_convertFunction($token, $this->_func_args)); + return($this->convertFunction($token, $this->_func_args)); }*/ // if it's an argument, ignore the token (the argument remains) @@ -573,7 +565,7 @@ private function _convert($token) * @access private * @param mixed $num an integer or double for conversion to its ptg value */ - private function _convertNumber($num) + private function convertNumber($num) { // Integer in the range 0..2**16-1 if ((preg_match("/^\d+$/", $num)) and ($num <= 65535)) { @@ -593,7 +585,7 @@ private function _convertNumber($num) * @param string $string A string for conversion to its ptg value. * @return mixed the converted token on success */ - private function _convertString($string) + private function convertString($string) { // chop away beggining and ending quotes $string = substr($string, 1, strlen($string) - 2); @@ -613,18 +605,18 @@ private function _convertString($string) * @param integer $num_args The number of arguments the function receives. * @return string The packed ptg for the function */ - private function _convertFunction($token, $num_args) + private function convertFunction($token, $num_args) { - $args = $this->_functions[$token][1]; -// $volatile = $this->_functions[$token][3]; + $args = $this->functions[$token][1]; +// $volatile = $this->functions[$token][3]; // Fixed number of args eg. TIME($i, $j, $k). if ($args >= 0) { - return pack("Cv", $this->ptg['ptgFuncV'], $this->_functions[$token][0]); + return pack("Cv", $this->ptg['ptgFuncV'], $this->functions[$token][0]); } // Variable number of args eg. SUM($i, $j, $k, ..). if ($args == -1) { - return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0]); + return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->functions[$token][0]); } } @@ -635,7 +627,7 @@ private function _convertFunction($token, $num_args) * @param string $range An Excel range in the A1:A2 * @param int $class */ - private function _convertRange2d($range, $class = 0) + private function convertRange2d($range, $class = 0) { // TODO: possible class value 0,1,2 check Formula.pm @@ -648,8 +640,8 @@ private function _convertRange2d($range, $class = 0) } // Convert the cell references - list($row1, $col1) = $this->_cellToPackedRowcol($cell1); - list($row2, $col2) = $this->_cellToPackedRowcol($cell2); + list($row1, $col1) = $this->cellToPackedRowcol($cell1); + list($row2, $col2) = $this->cellToPackedRowcol($cell2); // The ptg value depends on the class of the ptg. if ($class == 0) { @@ -673,7 +665,7 @@ private function _convertRange2d($range, $class = 0) * @param string $token An Excel range in the Sheet1!A1:A2 format. * @return mixed The packed ptgArea3d token on success. */ - private function _convertRange3d($token) + private function convertRange3d($token) { // $class = 0; // formulas like Sheet1!$A$1:$A$2 in list type data validation need this class (0x3B) @@ -681,17 +673,17 @@ private function _convertRange3d($token) list($ext_ref, $range) = explode('!', $token); // Convert the external reference part (different for BIFF8) - $ext_ref = $this->_getRefIndex($ext_ref); + $ext_ref = $this->getRefIndex($ext_ref); // Split the range into 2 cell refs list($cell1, $cell2) = explode(':', $range); // Convert the cell references if (preg_match("/^(\\$)?[A-Ia-i]?[A-Za-z](\\$)?(\d+)$/", $cell1)) { - list($row1, $col1) = $this->_cellToPackedRowcol($cell1); - list($row2, $col2) = $this->_cellToPackedRowcol($cell2); + list($row1, $col1) = $this->cellToPackedRowcol($cell1); + list($row2, $col2) = $this->cellToPackedRowcol($cell2); } else { // It's a rows range (like 26:27) - list($row1, $col1, $row2, $col2) = $this->_rangeToPackedRange($cell1.':'.$cell2); + list($row1, $col1, $row2, $col2) = $this->rangeToPackedRange($cell1.':'.$cell2); } // The ptg value depends on the class of the ptg. @@ -715,12 +707,12 @@ private function _convertRange3d($token) * @param string $cell An Excel cell reference * @return string The cell in packed() format with the corresponding ptg */ - private function _convertRef2d($cell) + private function convertRef2d($cell) { // $class = 2; // as far as I know, this is magick. // Convert the cell reference - $cell_array = $this->_cellToPackedRowcol($cell); + $cell_array = $this->cellToPackedRowcol($cell); list($row, $col) = $cell_array; // The ptg value depends on the class of the ptg. @@ -745,7 +737,7 @@ private function _convertRef2d($cell) * @param string $cell An Excel cell reference * @return mixed The packed ptgRef3d token on success. */ - private function _convertRef3d($cell) + private function convertRef3d($cell) { // $class = 2; // as far as I know, this is magick. @@ -753,10 +745,10 @@ private function _convertRef3d($cell) list($ext_ref, $cell) = explode('!', $cell); // Convert the external reference part (different for BIFF8) - $ext_ref = $this->_getRefIndex($ext_ref); + $ext_ref = $this->getRefIndex($ext_ref); // Convert the cell reference part - list($row, $col) = $this->_cellToPackedRowcol($cell); + list($row, $col) = $this->cellToPackedRowcol($cell); // The ptg value depends on the class of the ptg. // if ($class == 0) { @@ -779,7 +771,7 @@ private function _convertRef3d($cell) * @param string $errorCode The error code for conversion to its ptg value * @return string The error code ptgErr */ - private function _convertError($errorCode) + private function convertError($errorCode) { switch ($errorCode) { case '#NULL!': @@ -808,7 +800,7 @@ private function _convertError($errorCode) * @param string $ext_ref The name of the external reference * @return string The reference index in packed() format */ - private function _packExtRef($ext_ref) + private function packExtRef($ext_ref) { $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. @@ -817,11 +809,11 @@ private function _packExtRef($ext_ref) if (preg_match("/:/", $ext_ref)) { list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); - $sheet1 = $this->_getSheetIndex($sheet_name1); + $sheet1 = $this->getSheetIndex($sheet_name1); if ($sheet1 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); } - $sheet2 = $this->_getSheetIndex($sheet_name2); + $sheet2 = $this->getSheetIndex($sheet_name2); if ($sheet2 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); } @@ -831,7 +823,7 @@ private function _packExtRef($ext_ref) list($sheet1, $sheet2) = array($sheet2, $sheet1); } } else { // Single sheet name only. - $sheet1 = $this->_getSheetIndex($ext_ref); + $sheet1 = $this->getSheetIndex($ext_ref); if ($sheet1 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); } @@ -853,7 +845,7 @@ private function _packExtRef($ext_ref) * @param string $ext_ref The name of the external reference * @return mixed The reference index in packed() format on success */ - private function _getRefIndex($ext_ref) + private function getRefIndex($ext_ref) { $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. @@ -863,11 +855,11 @@ private function _getRefIndex($ext_ref) if (preg_match("/:/", $ext_ref)) { list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); - $sheet1 = $this->_getSheetIndex($sheet_name1); + $sheet1 = $this->getSheetIndex($sheet_name1); if ($sheet1 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); } - $sheet2 = $this->_getSheetIndex($sheet_name2); + $sheet2 = $this->getSheetIndex($sheet_name2); if ($sheet2 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); } @@ -877,7 +869,7 @@ private function _getRefIndex($ext_ref) list($sheet1, $sheet2) = array($sheet2, $sheet1); } } else { // Single sheet name only. - $sheet1 = $this->_getSheetIndex($ext_ref); + $sheet1 = $this->getSheetIndex($ext_ref); if ($sheet1 == -1) { throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); } @@ -887,18 +879,18 @@ private function _getRefIndex($ext_ref) // assume all references belong to this document $supbook_index = 0x00; $ref = pack('vvv', $supbook_index, $sheet1, $sheet2); - $total_references = count($this->_references); + $totalreferences = count($this->references); $index = -1; - for ($i = 0; $i < $total_references; ++$i) { - if ($ref == $this->_references[$i]) { + for ($i = 0; $i < $totalreferences; ++$i) { + if ($ref == $this->references[$i]) { $index = $i; break; } } // if REF was not found add it to references array if ($index == -1) { - $this->_references[$total_references] = $ref; - $index = $total_references; + $this->references[$totalreferences] = $ref; + $index = $totalreferences; } return pack('v', $index); @@ -913,12 +905,12 @@ private function _getRefIndex($ext_ref) * @param string $sheet_name Sheet name * @return integer The sheet index, -1 if the sheet was not found */ - private function _getSheetIndex($sheet_name) + private function getSheetIndex($sheet_name) { - if (!isset($this->_ext_sheets[$sheet_name])) { + if (!isset($this->externalSheets[$sheet_name])) { return -1; } else { - return $this->_ext_sheets[$sheet_name]; + return $this->externalSheets[$sheet_name]; } } @@ -934,7 +926,7 @@ private function _getSheetIndex($sheet_name) */ public function setExtSheet($name, $index) { - $this->_ext_sheets[$name] = $index; + $this->externalSheets[$name] = $index; } /** @@ -944,10 +936,10 @@ public function setExtSheet($name, $index) * @param string $cell The Excel cell reference to be packed * @return array Array containing the row and column in packed() format */ - private function _cellToPackedRowcol($cell) + private function cellToPackedRowcol($cell) { $cell = strtoupper($cell); - list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell); + list($row, $col, $row_rel, $col_rel) = $this->cellToRowcol($cell); if ($col >= 256) { throw new PHPExcel_Writer_Exception("Column in: $cell greater than 255"); } @@ -973,7 +965,7 @@ private function _cellToPackedRowcol($cell) * @param string $range The Excel range to be packed * @return array Array containing (row1,col1,row2,col2) in packed() format */ - private function _rangeToPackedRange($range) + private function rangeToPackedRange($range) { preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match); // return absolute rows if there is a $ in the ref @@ -1014,7 +1006,7 @@ private function _rangeToPackedRange($range) * @param string $cell The Excel cell reference in A1 format. * @return array */ - private function _cellToRowcol($cell) + private function cellToRowcol($cell) { preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/', $cell, $match); // return absolute column if there is a $ in the ref @@ -1024,8 +1016,8 @@ private function _cellToRowcol($cell) $row = $match[4]; // Convert base26 column string to a number. - $expn = strlen($col_ref) - 1; - $col = 0; + $expn = strlen($col_ref) - 1; + $col = 0; $col_ref_length = strlen($col_ref); for ($i = 0; $i < $col_ref_length; ++$i) { $col += (ord($col_ref{$i}) - 64) * pow(26, $expn); @@ -1044,48 +1036,48 @@ private function _cellToRowcol($cell) * * @access private */ - private function _advance() + private function advance() { - $i = $this->_current_char; - $formula_length = strlen($this->_formula); + $i = $this->currentCharacter; + $formula_length = strlen($this->formula); // eat up white spaces if ($i < $formula_length) { - while ($this->_formula{$i} == " ") { + while ($this->formula{$i} == " ") { ++$i; } if ($i < ($formula_length - 1)) { - $this->_lookahead = $this->_formula{$i+1}; + $this->lookAhead = $this->formula{$i+1}; } $token = ''; } while ($i < $formula_length) { - $token .= $this->_formula{$i}; + $token .= $this->formula{$i}; if ($i < ($formula_length - 1)) { - $this->_lookahead = $this->_formula{$i+1}; + $this->lookAhead = $this->formula{$i+1}; } else { - $this->_lookahead = ''; + $this->lookAhead = ''; } - if ($this->_match($token) != '') { - //if ($i < strlen($this->_formula) - 1) { - // $this->_lookahead = $this->_formula{$i+1}; + if ($this->match($token) != '') { + //if ($i < strlen($this->formula) - 1) { + // $this->lookAhead = $this->formula{$i+1}; //} - $this->_current_char = $i + 1; - $this->_current_token = $token; + $this->currentCharacter = $i + 1; + $this->currentToken = $token; return 1; } if ($i < ($formula_length - 2)) { - $this->_lookahead = $this->_formula{$i+2}; - } else { // if we run out of characters _lookahead becomes empty - $this->_lookahead = ''; + $this->lookAhead = $this->formula{$i+2}; + } else { // if we run out of characters lookAhead becomes empty + $this->lookAhead = ''; } ++$i; } - //die("Lexical error ".$this->_current_char); + //die("Lexical error ".$this->currentCharacter); } /** @@ -1095,7 +1087,7 @@ private function _advance() * @param mixed $token The token to check. * @return mixed The checked token or false on failure */ - private function _match($token) + private function match($token) { switch ($token) { case "+": @@ -1116,47 +1108,47 @@ private function _match($token) return $token; break; case ">": - if ($this->_lookahead == '=') { // it's a GE token + if ($this->lookAhead == '=') { // it's a GE token break; } return $token; break; case "<": // it's a LE or a NE token - if (($this->_lookahead == '=') or ($this->_lookahead == '>')) { + if (($this->lookAhead == '=') or ($this->lookAhead == '>')) { break; } return $token; break; default: // if it's a reference A1 or $A$1 or $A1 or A$1 - if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $token) and !preg_match("/[0-9]/", $this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.') and ($this->_lookahead != '!')) { + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $token) and !preg_match("/[0-9]/", $this->lookAhead) and ($this->lookAhead != ':') and ($this->lookAhead != '.') and ($this->lookAhead != '!')) { return $token; - } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.')) { + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->lookAhead) and ($this->lookAhead != ':') and ($this->lookAhead != '.')) { // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) return $token; - } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead) and ($this->_lookahead != ':') and ($this->_lookahead != '.')) { + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->lookAhead) and ($this->lookAhead != ':') and ($this->lookAhead != '.')) { // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) return $token; - } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) && !preg_match("/[0-9]/", $this->_lookahead)) { + } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) && !preg_match("/[0-9]/", $this->lookAhead)) { // if it's a range A1:A2 or $A$1:$A$2 return $token; - } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead)) { + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->lookAhead)) { // If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 return $token; - } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->_lookahead)) { + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $token) and !preg_match("/[0-9]/", $this->lookAhead)) { // If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 return $token; - } elseif (is_numeric($token) and (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and ($this->_lookahead != '!') and ($this->_lookahead != ':')) { + } elseif (is_numeric($token) and (!is_numeric($token.$this->lookAhead) or ($this->lookAhead == '')) and ($this->lookAhead != '!') and ($this->lookAhead != ':')) { // If it's a number (check that it's not a sheet name or range) return $token; - } elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token) and $this->_lookahead != '"' and (substr_count($token, '"')%2 == 0)) { + } elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token) and $this->lookAhead != '"' and (substr_count($token, '"')%2 == 0)) { // If it's a string (of maximum 255 characters) return $token; } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { // If it's an error code return $token; - } elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $token) and ($this->_lookahead == "(")) { + } elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $token) and ($this->lookAhead == "(")) { // if it's a function call return $token; } elseif (substr($token, -1) == ')') { @@ -1178,11 +1170,11 @@ private function _match($token) */ public function parse($formula) { - $this->_current_char = 0; - $this->_formula = $formula; - $this->_lookahead = isset($formula{1}) ? $formula{1} : ''; - $this->_advance(); - $this->_parse_tree = $this->_condition(); + $this->currentCharacter = 0; + $this->formula = $formula; + $this->lookAhead = isset($formula{1}) ? $formula{1} : ''; + $this->advance(); + $this->parseTree = $this->condition(); return true; } @@ -1193,37 +1185,37 @@ public function parse($formula) * @access private * @return mixed The parsed ptg'd tree on success */ - private function _condition() + private function condition() { - $result = $this->_expression(); - if ($this->_current_token == "<") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgLT', $result, $result2); - } elseif ($this->_current_token == ">") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgGT', $result, $result2); - } elseif ($this->_current_token == "<=") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgLE', $result, $result2); - } elseif ($this->_current_token == ">=") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgGE', $result, $result2); - } elseif ($this->_current_token == "=") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgEQ', $result, $result2); - } elseif ($this->_current_token == "<>") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgNE', $result, $result2); - } elseif ($this->_current_token == "&") { - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgConcat', $result, $result2); + $result = $this->expression(); + if ($this->currentToken == "<") { + $this->advance(); + $result2 = $this->expression(); + $result = $this->createTree('ptgLT', $result, $result2); + } elseif ($this->currentToken == ">") { + $this->advance(); + $result2 = $this->expression(); + $result = $this->createTree('ptgGT', $result, $result2); + } elseif ($this->currentToken == "<=") { + $this->advance(); + $result2 = $this->expression(); + $result = $this->createTree('ptgLE', $result, $result2); + } elseif ($this->currentToken == ">=") { + $this->advance(); + $result2 = $this->expression(); + $result = $this->createTree('ptgGE', $result, $result2); + } elseif ($this->currentToken == "=") { + $this->advance(); + $result2 = $this->expression(); + $result = $this->createTree('ptgEQ', $result, $result2); + } elseif ($this->currentToken == "<>") { + $this->advance(); + $result2 = $this->expression(); + $result = $this->createTree('ptgNE', $result, $result2); + } elseif ($this->currentToken == "&") { + $this->advance(); + $result2 = $this->expression(); + $result = $this->createTree('ptgConcat', $result, $result2); } return $result; } @@ -1239,55 +1231,55 @@ private function _condition() * @access private * @return mixed The parsed ptg'd tree on success */ - private function _expression() + private function expression() { // If it's a string return a string node - if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $this->_current_token)) { - $tmp = str_replace('""', '"', $this->_current_token); + if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $this->currentToken)) { + $tmp = str_replace('""', '"', $this->currentToken); if (($tmp == '"') || ($tmp == '')) { // Trap for "" that has been used for an empty string $tmp = '""'; } - $result = $this->_createTree($tmp, '', ''); - $this->_advance(); + $result = $this->createTree($tmp, '', ''); + $this->advance(); return $result; // If it's an error code - } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $this->_current_token) or $this->_current_token == '#N/A') { - $result = $this->_createTree($this->_current_token, 'ptgErr', ''); - $this->_advance(); + } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $this->currentToken) or $this->currentToken == '#N/A') { + $result = $this->createTree($this->currentToken, 'ptgErr', ''); + $this->advance(); return $result; // If it's a negative value - } elseif ($this->_current_token == "-") { + } elseif ($this->currentToken == "-") { // catch "-" Term - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgUminus', $result2, ''); + $this->advance(); + $result2 = $this->expression(); + $result = $this->createTree('ptgUminus', $result2, ''); return $result; // If it's a positive value - } elseif ($this->_current_token == "+") { + } elseif ($this->currentToken == "+") { // catch "+" Term - $this->_advance(); - $result2 = $this->_expression(); - $result = $this->_createTree('ptgUplus', $result2, ''); + $this->advance(); + $result2 = $this->expression(); + $result = $this->createTree('ptgUplus', $result2, ''); return $result; } - $result = $this->_term(); - while (($this->_current_token == "+") or - ($this->_current_token == "-") or - ($this->_current_token == "^")) { + $result = $this->term(); + while (($this->currentToken == "+") or + ($this->currentToken == "-") or + ($this->currentToken == "^")) { /**/ - if ($this->_current_token == "+") { - $this->_advance(); - $result2 = $this->_term(); - $result = $this->_createTree('ptgAdd', $result, $result2); - } elseif ($this->_current_token == "-") { - $this->_advance(); - $result2 = $this->_term(); - $result = $this->_createTree('ptgSub', $result, $result2); + if ($this->currentToken == "+") { + $this->advance(); + $result2 = $this->term(); + $result = $this->createTree('ptgAdd', $result, $result2); + } elseif ($this->currentToken == "-") { + $this->advance(); + $result2 = $this->term(); + $result = $this->createTree('ptgSub', $result, $result2); } else { - $this->_advance(); - $result2 = $this->_term(); - $result = $this->_createTree('ptgPower', $result, $result2); + $this->advance(); + $result2 = $this->term(); + $result = $this->createTree('ptgPower', $result, $result2); } } return $result; @@ -1298,12 +1290,12 @@ private function _expression() * doesn't get confused when working with a parenthesized formula afterwards. * * @access private - * @see _fact() + * @see fact() * @return array The parsed ptg'd tree */ - private function _parenthesizedExpression() + private function parenthesizedExpression() { - $result = $this->_createTree('ptgParen', $this->_expression(), ''); + $result = $this->createTree('ptgParen', $this->expression(), ''); return $result; } @@ -1314,20 +1306,20 @@ private function _parenthesizedExpression() * @access private * @return mixed The parsed ptg'd tree on success */ - private function _term() + private function term() { - $result = $this->_fact(); - while (($this->_current_token == "*") or - ($this->_current_token == "/")) { + $result = $this->fact(); + while (($this->currentToken == "*") or + ($this->currentToken == "/")) { /**/ - if ($this->_current_token == "*") { - $this->_advance(); - $result2 = $this->_fact(); - $result = $this->_createTree('ptgMul', $result, $result2); + if ($this->currentToken == "*") { + $this->advance(); + $result2 = $this->fact(); + $result = $this->createTree('ptgMul', $result, $result2); } else { - $this->_advance(); - $result2 = $this->_fact(); - $result = $this->_createTree('ptgDiv', $result, $result2); + $this->advance(); + $result2 = $this->fact(); + $result = $this->createTree('ptgDiv', $result, $result2); } } return $result; @@ -1344,69 +1336,69 @@ private function _term() * @access private * @return mixed The parsed ptg'd tree on success */ - private function _fact() + private function fact() { - if ($this->_current_token == "(") { - $this->_advance(); // eat the "(" - $result = $this->_parenthesizedExpression(); - if ($this->_current_token != ")") { + if ($this->currentToken == "(") { + $this->advance(); // eat the "(" + $result = $this->parenthesizedExpression(); + if ($this->currentToken != ")") { throw new PHPExcel_Writer_Exception("')' token expected."); } - $this->_advance(); // eat the ")" + $this->advance(); // eat the ")" return $result; } // if it's a reference - if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $this->_current_token)) { - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/', $this->currentToken)) { + $result = $this->createTree($this->currentToken, '', ''); + $this->advance(); return $result; - } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) { + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->currentToken)) { // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); + $result = $this->createTree($this->currentToken, '', ''); + $this->advance(); return $result; - } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->_current_token)) { + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u", $this->currentToken)) { // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); + $result = $this->createTree($this->currentToken, '', ''); + $this->advance(); return $result; - } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->_current_token) or - preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->_current_token)) { + } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->currentToken) or + preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $this->currentToken)) { // if it's a range A1:B2 or $A$1:$B$2 // must be an error? - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); + $result = $this->createTree($this->currentToken, '', ''); + $this->advance(); return $result; - } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) { + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->currentToken)) { // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2) // must be an error? - //$result = $this->_current_token; - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); + //$result = $this->currentToken; + $result = $this->createTree($this->currentToken, '', ''); + $this->advance(); return $result; - } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->_current_token)) { + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u", $this->currentToken)) { // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2) // must be an error? - //$result = $this->_current_token; - $result = $this->_createTree($this->_current_token, '', ''); - $this->_advance(); + //$result = $this->currentToken; + $result = $this->createTree($this->currentToken, '', ''); + $this->advance(); return $result; - } elseif (is_numeric($this->_current_token)) { + } elseif (is_numeric($this->currentToken)) { // If it's a number or a percent - if ($this->_lookahead == '%') { - $result = $this->_createTree('ptgPercent', $this->_current_token, ''); - $this->_advance(); // Skip the percentage operator once we've pre-built that tree + if ($this->lookAhead == '%') { + $result = $this->createTree('ptgPercent', $this->currentToken, ''); + $this->advance(); // Skip the percentage operator once we've pre-built that tree } else { - $result = $this->_createTree($this->_current_token, '', ''); + $result = $this->createTree($this->currentToken, '', ''); } - $this->_advance(); + $this->advance(); return $result; - } elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $this->_current_token)) { + } elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i", $this->currentToken)) { // if it's a function call - $result = $this->_func(); + $result = $this->func(); return $result; } - throw new PHPExcel_Writer_Exception("Syntax error: ".$this->_current_token.", lookahead: ".$this->_lookahead.", current char: ".$this->_current_char); + throw new PHPExcel_Writer_Exception("Syntax error: ".$this->currentToken.", lookahead: ".$this->lookAhead.", current char: ".$this->currentCharacter); } /** @@ -1416,40 +1408,40 @@ private function _fact() * @access private * @return mixed The parsed ptg'd tree on success */ - private function _func() + private function func() { $num_args = 0; // number of arguments received - $function = strtoupper($this->_current_token); + $function = strtoupper($this->currentToken); $result = ''; // initialize result - $this->_advance(); - $this->_advance(); // eat the "(" - while ($this->_current_token != ')') { + $this->advance(); + $this->advance(); // eat the "(" + while ($this->currentToken != ')') { /**/ if ($num_args > 0) { - if ($this->_current_token == "," || $this->_current_token == ";") { - $this->_advance(); // eat the "," or ";" + if ($this->currentToken == "," || $this->currentToken == ";") { + $this->advance(); // eat the "," or ";" } else { throw new PHPExcel_Writer_Exception("Syntax error: comma expected in function $function, arg #{$num_args}"); } - $result2 = $this->_condition(); - $result = $this->_createTree('arg', $result, $result2); + $result2 = $this->condition(); + $result = $this->createTree('arg', $result, $result2); } else { // first argument - $result2 = $this->_condition(); - $result = $this->_createTree('arg', '', $result2); + $result2 = $this->condition(); + $result = $this->createTree('arg', '', $result2); } ++$num_args; } - if (!isset($this->_functions[$function])) { + if (!isset($this->functions[$function])) { throw new PHPExcel_Writer_Exception("Function $function() doesn't exist"); } - $args = $this->_functions[$function][1]; + $args = $this->functions[$function][1]; // If fixed number of args eg. TIME($i, $j, $k). Check that the number of args is valid. if (($args >= 0) and ($args != $num_args)) { throw new PHPExcel_Writer_Exception("Incorrect number of arguments in function $function() "); } - $result = $this->_createTree($function, $result, $num_args); - $this->_advance(); // eat the ")" + $result = $this->createTree($function, $result, $num_args); + $this->advance(); // eat the ")" return $result; } @@ -1463,7 +1455,7 @@ private function _func() * @param mixed $right The right array (sub-tree) or a final node. * @return array A tree */ - private function _createTree($value, $left, $right) + private function createTree($value, $left, $right) { return array('value' => $value, 'left' => $left, 'right' => $right); } @@ -1498,22 +1490,22 @@ private function _createTree($value, $left, $right) public function toReversePolish($tree = array()) { $polish = ""; // the string we are going to return - if (empty($tree)) { // If it's the first call use _parse_tree - $tree = $this->_parse_tree; + if (empty($tree)) { // If it's the first call use parseTree + $tree = $this->parseTree; } if (is_array($tree['left'])) { $converted_tree = $this->toReversePolish($tree['left']); $polish .= $converted_tree; } elseif ($tree['left'] != '') { // It's a final node - $converted_tree = $this->_convert($tree['left']); + $converted_tree = $this->convert($tree['left']); $polish .= $converted_tree; } if (is_array($tree['right'])) { $converted_tree = $this->toReversePolish($tree['right']); $polish .= $converted_tree; } elseif ($tree['right'] != '') { // It's a final node - $converted_tree = $this->_convert($tree['right']); + $converted_tree = $this->convert($tree['right']); $polish .= $converted_tree; } // if it's a function convert it here (so we can set it's arguments) @@ -1529,9 +1521,9 @@ public function toReversePolish($tree = array()) $left_tree = ''; } // add it's left subtree and return. - return $left_tree.$this->_convertFunction($tree['value'], $tree['right']); + return $left_tree.$this->convertFunction($tree['value'], $tree['right']); } else { - $converted_tree = $this->_convert($tree['value']); + $converted_tree = $this->convert($tree['value']); } $polish .= $converted_tree; return $polish; diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index c5f827d5e..ad201c87a 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel5_Workbook * * Copyright (c) 2006 - 2015 PHPExcel * @@ -59,15 +60,6 @@ // * License along with this library; if not, write to the Free Software // * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // */ - - -/** - * PHPExcel_Writer_Excel5_Workbook - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter { /** @@ -75,119 +67,119 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter * * @var PHPExcel_Writer_Excel5_Parser */ - private $_parser; + private $parser; /** * The BIFF file size for the workbook. * @var integer - * @see _calcSheetOffsets() + * @see calcSheetOffsets() */ - public $_biffsize; + private $biffSize; /** * XF Writers * @var PHPExcel_Writer_Excel5_Xf[] */ - private $_xfWriters = array(); + private $xfWriters = array(); /** * Array containing the colour palette * @var array */ - public $_palette; + private $palette; /** * The codepage indicates the text encoding used for strings * @var integer */ - public $_codepage; + private $codepage; /** * The country code used for localization * @var integer */ - public $_country_code; + private $countryCode; /** * Workbook * @var PHPExcel */ - private $_phpExcel; + private $phpExcel; /** * Fonts writers * * @var PHPExcel_Writer_Excel5_Font[] */ - private $_fontWriters = array(); + private $fontWriters = array(); /** * Added fonts. Maps from font's hash => index in workbook * * @var array */ - private $_addedFonts = array(); + private $addedFonts = array(); /** * Shared number formats * * @var array */ - private $_numberFormats = array(); + private $numberFormats = array(); /** * Added number formats. Maps from numberFormat's hash => index in workbook * * @var array */ - private $_addedNumberFormats = array(); + private $addedNumberFormats = array(); /** * Sizes of the binary worksheet streams * * @var array */ - private $_worksheetSizes = array(); + private $worksheetSizes = array(); /** * Offsets of the binary worksheet streams relative to the start of the global workbook stream * * @var array */ - private $_worksheetOffsets = array(); + private $worksheetOffsets = array(); /** * Total number of shared strings in workbook * * @var int */ - private $_str_total; + private $strTotal; /** * Number of unique shared strings in workbook * * @var int */ - private $_str_unique; + private $strUnique; /** * Array of unique shared strings in workbook * * @var array */ - private $_str_table; + private $strTable; /** * Color cache */ - private $_colors; + private $colors; /** * Escher object corresponding to MSODRAWINGGROUP * * @var PHPExcel_Shared_Escher */ - private $_escher; + private $escher; /** @@ -205,37 +197,37 @@ public function __construct(PHPExcel $phpExcel = null, &$str_total, &$str_unique // It needs to call its parent's constructor explicitly parent::__construct(); - $this->_parser = $parser; - $this->_biffsize = 0; - $this->_palette = array(); - $this->_country_code = -1; + $this->parser = $parser; + $this->biffSize = 0; + $this->palette = array(); + $this->countryCode = -1; - $this->_str_total = &$str_total; - $this->_str_unique = &$str_unique; - $this->_str_table = &$str_table; - $this->_colors = &$colors; - $this->_setPaletteXl97(); + $this->strTotal = &$str_total; + $this->strUnique = &$str_unique; + $this->strTable = &$str_table; + $this->colors = &$colors; + $this->setPaletteXl97(); - $this->_phpExcel = $phpExcel; + $this->phpExcel = $phpExcel; // set BIFFwriter limit for CONTINUE records // $this->_limit = 8224; - $this->_codepage = 0x04B0; + $this->codepage = 0x04B0; // Add empty sheets and Build color cache $countSheets = $phpExcel->getSheetCount(); for ($i = 0; $i < $countSheets; ++$i) { $phpSheet = $phpExcel->getSheet($i); - $this->_parser->setExtSheet($phpSheet->getTitle(), $i); // Register worksheet name with parser + $this->parser->setExtSheet($phpSheet->getTitle(), $i); // Register worksheet name with parser $supbook_index = 0x00; $ref = pack('vvv', $supbook_index, $i, $i); - $this->_parser->_references[] = $ref; // Register reference with parser + $this->parser->references[] = $ref; // Register reference with parser // Sheet tab colors? if ($phpSheet->isTabColorSet()) { - $this->_addColor($phpSheet->getTabColor()->getRGB()); + $this->addColor($phpSheet->getTabColor()->getRGB()); } } @@ -254,30 +246,30 @@ public function addXfWriter($style, $isStyleXf = false) $xfWriter->setIsStyleXf($isStyleXf); // Add the font if not already added - $fontIndex = $this->_addFont($style->getFont()); + $fontIndex = $this->addFont($style->getFont()); // Assign the font index to the xf record $xfWriter->setFontIndex($fontIndex); // Background colors, best to treat these after the font so black will come after white in custom palette - $xfWriter->setFgColor($this->_addColor($style->getFill()->getStartColor()->getRGB())); - $xfWriter->setBgColor($this->_addColor($style->getFill()->getEndColor()->getRGB())); - $xfWriter->setBottomColor($this->_addColor($style->getBorders()->getBottom()->getColor()->getRGB())); - $xfWriter->setTopColor($this->_addColor($style->getBorders()->getTop()->getColor()->getRGB())); - $xfWriter->setRightColor($this->_addColor($style->getBorders()->getRight()->getColor()->getRGB())); - $xfWriter->setLeftColor($this->_addColor($style->getBorders()->getLeft()->getColor()->getRGB())); - $xfWriter->setDiagColor($this->_addColor($style->getBorders()->getDiagonal()->getColor()->getRGB())); + $xfWriter->setFgColor($this->addColor($style->getFill()->getStartColor()->getRGB())); + $xfWriter->setBgColor($this->addColor($style->getFill()->getEndColor()->getRGB())); + $xfWriter->setBottomColor($this->addColor($style->getBorders()->getBottom()->getColor()->getRGB())); + $xfWriter->setTopColor($this->addColor($style->getBorders()->getTop()->getColor()->getRGB())); + $xfWriter->setRightColor($this->addColor($style->getBorders()->getRight()->getColor()->getRGB())); + $xfWriter->setLeftColor($this->addColor($style->getBorders()->getLeft()->getColor()->getRGB())); + $xfWriter->setDiagColor($this->addColor($style->getBorders()->getDiagonal()->getColor()->getRGB())); // Add the number format if it is not a built-in one and not already added if ($style->getNumberFormat()->getBuiltInFormatCode() === false) { $numberFormatHashCode = $style->getNumberFormat()->getHashCode(); - if (isset($this->_addedNumberFormats[$numberFormatHashCode])) { - $numberFormatIndex = $this->_addedNumberFormats[$numberFormatHashCode]; + if (isset($this->addedNumberFormats[$numberFormatHashCode])) { + $numberFormatIndex = $this->addedNumberFormats[$numberFormatHashCode]; } else { - $numberFormatIndex = 164 + count($this->_numberFormats); - $this->_numberFormats[$numberFormatIndex] = $style->getNumberFormat(); - $this->_addedNumberFormats[$numberFormatHashCode] = $numberFormatIndex; + $numberFormatIndex = 164 + count($this->numberFormats); + $this->numberFormats[$numberFormatIndex] = $style->getNumberFormat(); + $this->addedNumberFormats[$numberFormatHashCode] = $numberFormatIndex; } } else { $numberFormatIndex = (int) $style->getNumberFormat()->getBuiltInFormatCode(); @@ -286,9 +278,9 @@ public function addXfWriter($style, $isStyleXf = false) // Assign the number format index to xf record $xfWriter->setNumberFormatIndex($numberFormatIndex); - $this->_xfWriters[] = $xfWriter; + $this->xfWriters[] = $xfWriter; - $xfIndex = count($this->_xfWriters) - 1; + $xfIndex = count($this->xfWriters) - 1; return $xfIndex; } @@ -298,20 +290,20 @@ public function addXfWriter($style, $isStyleXf = false) * @param PHPExcel_Style_Font $font * @return int Index to FONT record */ - public function _addFont(PHPExcel_Style_Font $font) + public function addFont(PHPExcel_Style_Font $font) { $fontHashCode = $font->getHashCode(); - if (isset($this->_addedFonts[$fontHashCode])) { - $fontIndex = $this->_addedFonts[$fontHashCode]; + if (isset($this->addedFonts[$fontHashCode])) { + $fontIndex = $this->addedFonts[$fontHashCode]; } else { - $countFonts = count($this->_fontWriters); + $countFonts = count($this->fontWriters); $fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1; $fontWriter = new PHPExcel_Writer_Excel5_Font($font); - $fontWriter->setColorIndex($this->_addColor($font->getColor()->getRGB())); - $this->_fontWriters[] = $fontWriter; + $fontWriter->setColorIndex($this->addColor($font->getColor()->getRGB())); + $this->fontWriters[] = $fontWriter; - $this->_addedFonts[$fontHashCode] = $fontIndex; + $this->addedFonts[$fontHashCode] = $fontIndex; } return $fontIndex; } @@ -322,27 +314,27 @@ public function _addFont(PHPExcel_Style_Font $font) * @param string $rgb E.g. 'FF00AA' * @return int Color index */ - private function _addColor($rgb) + private function addColor($rgb) { - if (!isset($this->_colors[$rgb])) { - if (count($this->_colors) < 57) { + if (!isset($this->colors[$rgb])) { + if (count($this->colors) < 57) { // then we add a custom color altering the palette - $colorIndex = 8 + count($this->_colors); - $this->_palette[$colorIndex] = + $colorIndex = 8 + count($this->colors); + $this->palette[$colorIndex] = array( hexdec(substr($rgb, 0, 2)), hexdec(substr($rgb, 2, 2)), hexdec(substr($rgb, 4)), 0 ); - $this->_colors[$rgb] = $colorIndex; + $this->colors[$rgb] = $colorIndex; } else { // no room for more custom colors, just map to black $colorIndex = 0; } } else { // fetch already added custom color - $colorIndex = $this->_colors[$rgb]; + $colorIndex = $this->colors[$rgb]; } return $colorIndex; @@ -353,9 +345,9 @@ private function _addColor($rgb) * * @access private */ - private function _setPaletteXl97() + private function setPaletteXl97() { - $this->_palette = array( + $this->palette = array( 0x08 => array(0x00, 0x00, 0x00, 0x00), 0x09 => array(0xff, 0xff, 0xff, 0x00), 0x0A => array(0xff, 0x00, 0x00, 0x00), @@ -424,45 +416,45 @@ private function _setPaletteXl97() */ public function writeWorkbook($pWorksheetSizes = null) { - $this->_worksheetSizes = $pWorksheetSizes; + $this->worksheetSizes = $pWorksheetSizes; // Calculate the number of selected worksheet tabs and call the finalization // methods for each worksheet - $total_worksheets = $this->_phpExcel->getSheetCount(); + $total_worksheets = $this->phpExcel->getSheetCount(); // Add part 1 of the Workbook globals, what goes before the SHEET records - $this->_storeBof(0x0005); - $this->_writeCodepage(); - $this->_writeWindow1(); + $this->storeBof(0x0005); + $this->writeCodepage(); + $this->writeWindow1(); - $this->_writeDatemode(); - $this->_writeAllFonts(); - $this->_writeAllNumFormats(); - $this->_writeAllXfs(); - $this->_writeAllStyles(); - $this->_writePalette(); + $this->writeDateMode(); + $this->writeAllFonts(); + $this->writeAllNumberFormats(); + $this->writeAllXfs(); + $this->writeAllStyles(); + $this->writePalette(); // Prepare part 3 of the workbook global stream, what goes after the SHEET records $part3 = ''; - if ($this->_country_code != -1) { - $part3 .= $this->_writeCountry(); + if ($this->countryCode != -1) { + $part3 .= $this->writeCountry(); } - $part3 .= $this->_writeRecalcId(); + $part3 .= $this->writeRecalcId(); - $part3 .= $this->_writeSupbookInternal(); + $part3 .= $this->writeSupbookInternal(); /* TODO: store external SUPBOOK records and XCT and CRN records in case of external references for BIFF8 */ - $part3 .= $this->_writeExternsheetBiff8(); - $part3 .= $this->_writeAllDefinedNamesBiff8(); - $part3 .= $this->_writeMsoDrawingGroup(); - $part3 .= $this->_writeSharedStringsTable(); + $part3 .= $this->writeExternalsheetBiff8(); + $part3 .= $this->writeAllDefinedNamesBiff8(); + $part3 .= $this->writeMsoDrawingGroup(); + $part3 .= $this->writeSharedStringsTable(); $part3 .= $this->writeEof(); // Add part 2 of the Workbook globals, the SHEET records - $this->_calcSheetOffsets(); + $this->calcSheetOffsets(); for ($i = 0; $i < $total_worksheets; ++$i) { - $this->_writeBoundsheet($this->_phpExcel->getSheet($i), $this->_worksheetOffsets[$i]); + $this->writeBoundSheet($this->phpExcel->getSheet($i), $this->worksheetOffsets[$i]); } // Add part 3 of the Workbook globals @@ -476,7 +468,7 @@ public function writeWorkbook($pWorksheetSizes = null) * * @access private */ - private function _calcSheetOffsets() + private function calcSheetOffsets() { $boundsheet_length = 10; // fixed length for a BOUNDSHEET record @@ -484,84 +476,84 @@ private function _calcSheetOffsets() $offset = $this->_datasize; // add size of Workbook globals part 2, the length of the SHEET records - $total_worksheets = count($this->_phpExcel->getAllSheets()); - foreach ($this->_phpExcel->getWorksheetIterator() as $sheet) { + $total_worksheets = count($this->phpExcel->getAllSheets()); + foreach ($this->phpExcel->getWorksheetIterator() as $sheet) { $offset += $boundsheet_length + strlen(PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheet->getTitle())); } // add the sizes of each of the Sheet substreams, respectively for ($i = 0; $i < $total_worksheets; ++$i) { - $this->_worksheetOffsets[$i] = $offset; - $offset += $this->_worksheetSizes[$i]; + $this->worksheetOffsets[$i] = $offset; + $offset += $this->worksheetSizes[$i]; } - $this->_biffsize = $offset; + $this->biffSize = $offset; } /** * Store the Excel FONT records. */ - private function _writeAllFonts() + private function writeAllFonts() { - foreach ($this->_fontWriters as $fontWriter) { - $this->_append($fontWriter->writeFont()); + foreach ($this->fontWriters as $fontWriter) { + $this->append($fontWriter->writeFont()); } } /** * Store user defined numerical formats i.e. FORMAT records */ - private function _writeAllNumFormats() + private function writeAllNumberFormats() { - foreach ($this->_numberFormats as $numberFormatIndex => $numberFormat) { - $this->_writeNumFormat($numberFormat->getFormatCode(), $numberFormatIndex); + foreach ($this->numberFormats as $numberFormatIndex => $numberFormat) { + $this->writeNumberFormat($numberFormat->getFormatCode(), $numberFormatIndex); } } /** * Write all XF records. */ - private function _writeAllXfs() + private function writeAllXfs() { - foreach ($this->_xfWriters as $xfWriter) { - $this->_append($xfWriter->writeXf()); + foreach ($this->xfWriters as $xfWriter) { + $this->append($xfWriter->writeXf()); } } /** * Write all STYLE records. */ - private function _writeAllStyles() + private function writeAllStyles() { - $this->_writeStyle(); + $this->writeStyle(); } /** * Write the EXTERNCOUNT and EXTERNSHEET records. These are used as indexes for * the NAME records. */ - private function _writeExterns() + private function writeExternals() { - $countSheets = $this->_phpExcel->getSheetCount(); + $countSheets = $this->phpExcel->getSheetCount(); // Create EXTERNCOUNT with number of worksheets - $this->_writeExterncount($countSheets); + $this->writeExternalCount($countSheets); // Create EXTERNSHEET for each worksheet for ($i = 0; $i < $countSheets; ++$i) { - $this->_writeExternsheet($this->_phpExcel->getSheet($i)->getTitle()); + $this->writeExternalSheet($this->phpExcel->getSheet($i)->getTitle()); } } /** * Write the NAME record to define the print area and the repeat rows and cols. */ - private function _writeNames() + private function writeNames() { // total number of sheets - $total_worksheets = $this->_phpExcel->getSheetCount(); + $total_worksheets = $this->phpExcel->getSheetCount(); // Create the print area NAME records for ($i = 0; $i < $total_worksheets; ++$i) { - $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + $sheetSetup = $this->phpExcel->getSheet($i)->getPageSetup(); // Write a Name record if the print area has been defined if ($sheetSetup->isPrintAreaSet()) { // Print area @@ -575,7 +567,7 @@ private function _writeNames() $print_colmin = PHPExcel_Cell::columnIndexFromString($printArea[0][0]) - 1; $print_colmax = PHPExcel_Cell::columnIndexFromString($printArea[1][0]) - 1; - $this->_writeNameShort( + $this->writeNameShort( $i, // sheet index 0x06, // NAME type $print_rowmin, @@ -588,7 +580,7 @@ private function _writeNames() // Create the print title NAME records for ($i = 0; $i < $total_worksheets; ++$i) { - $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + $sheetSetup = $this->phpExcel->getSheet($i)->getPageSetup(); // simultaneous repeatColumns repeatRows if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { @@ -600,7 +592,7 @@ private function _writeNames() $rowmin = $repeat[0] - 1; $rowmax = $repeat[1] - 1; - $this->_writeNameLong( + $this->writeNameLong( $i, // sheet index 0x07, // NAME type $rowmin, @@ -631,7 +623,7 @@ private function _writeNames() $rowmax = 65535; } - $this->_writeNameShort( + $this->writeNameShort( $i, // sheet index 0x07, // NAME type $rowmin, @@ -647,14 +639,14 @@ private function _writeNames() * Writes all the DEFINEDNAME records (BIFF8). * So far this is only used for repeating rows/columns (print titles) and print areas */ - private function _writeAllDefinedNamesBiff8() + private function writeAllDefinedNamesBiff8() { $chunk = ''; // Named ranges - if (count($this->_phpExcel->getNamedRanges()) > 0) { + if (count($this->phpExcel->getNamedRanges()) > 0) { // Loop named ranges - $namedRanges = $this->_phpExcel->getNamedRanges(); + $namedRanges = $this->phpExcel->getNamedRanges(); foreach ($namedRanges as $namedRange) { // Create absolute coordinate $range = PHPExcel_Cell::splitRange($namedRange->getRange()); @@ -668,8 +660,8 @@ private function _writeAllDefinedNamesBiff8() // parse formula try { - $error = $this->_parser->parse($range); - $formulaData = $this->_parser->toReversePolish(); + $error = $this->parser->parse($range); + $formulaData = $this->parser->toReversePolish(); // make sure tRef3d is of type tRef3dR (0x3A) if (isset($formulaData{0}) and ($formulaData{0} == "\x7A" or $formulaData{0} == "\x5A")) { @@ -678,12 +670,12 @@ private function _writeAllDefinedNamesBiff8() if ($namedRange->getLocalOnly()) { // local scope - $scope = $this->_phpExcel->getIndex($namedRange->getScope()) + 1; + $scope = $this->phpExcel->getIndex($namedRange->getScope()) + 1; } else { // global scope $scope = 0; } - $chunk .= $this->writeData($this->_writeDefinedNameBiff8($namedRange->getName(), $formulaData, $scope, false)); + $chunk .= $this->writeData($this->writeDefinedNameBiff8($namedRange->getName(), $formulaData, $scope, false)); } catch (PHPExcel_Exception $e) { // do nothing @@ -692,11 +684,11 @@ private function _writeAllDefinedNamesBiff8() } // total number of sheets - $total_worksheets = $this->_phpExcel->getSheetCount(); + $total_worksheets = $this->phpExcel->getSheetCount(); // write the print titles (repeating rows, columns), if any for ($i = 0; $i < $total_worksheets; ++$i) { - $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + $sheetSetup = $this->phpExcel->getSheet($i)->getPageSetup(); // simultaneous repeatColumns repeatRows if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); @@ -714,7 +706,7 @@ private function _writeAllDefinedNamesBiff8() $formulaData .= pack('C', 0x10); // tList // store the DEFINEDNAME record - $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); + $chunk .= $this->writeData($this->writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); // (exclusive) either repeatColumns or repeatRows } elseif ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { @@ -741,13 +733,13 @@ private function _writeAllDefinedNamesBiff8() $formulaData = pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, $colmin, $colmax); // store the DEFINEDNAME record - $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); + $chunk .= $this->writeData($this->writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); } } // write the print areas, if any for ($i = 0; $i < $total_worksheets; ++$i) { - $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + $sheetSetup = $this->phpExcel->getSheet($i)->getPageSetup(); if ($sheetSetup->isPrintAreaSet()) { // Print area, e.g. A3:J6,H1:X20 $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); @@ -773,13 +765,13 @@ private function _writeAllDefinedNamesBiff8() } // store the DEFINEDNAME record - $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true)); + $chunk .= $this->writeData($this->writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true)); } } // write autofilters, if any for ($i = 0; $i < $total_worksheets; ++$i) { - $sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter(); + $sheetAutoFilter = $this->phpExcel->getSheet($i)->getAutoFilter(); $autoFilterRange = $sheetAutoFilter->getRange(); if (!empty($autoFilterRange)) { $rangeBounds = PHPExcel_Cell::rangeBoundaries($autoFilterRange); @@ -787,7 +779,7 @@ private function _writeAllDefinedNamesBiff8() //Autofilter built in name $name = pack('C', 0x0D); - $chunk .= $this->writeData($this->_writeShortNameBiff8($name, $i + 1, $rangeBounds, true)); + $chunk .= $this->writeData($this->writeShortNameBiff8($name, $i + 1, $rangeBounds, true)); } } @@ -803,7 +795,7 @@ private function _writeAllDefinedNamesBiff8() * @param boolean $isBuiltIn Built-in name? * @return string Complete binary record data */ - private function _writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $isBuiltIn = false) + private function writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $isBuiltIn = false) { $record = 0x0018; @@ -838,7 +830,7 @@ private function _writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $i * @param boolean $isHidden * @return string Complete binary record data * */ - private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false) + private function writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false) { $record = 0x0018; @@ -871,45 +863,45 @@ private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isH /** * Stores the CODEPAGE biff record. */ - private function _writeCodepage() + private function writeCodepage() { - $record = 0x0042; // Record identifier - $length = 0x0002; // Number of bytes to follow - $cv = $this->_codepage; // The code page + $record = 0x0042; // Record identifier + $length = 0x0002; // Number of bytes to follow + $cv = $this->codepage; // The code page - $header = pack('vv', $record, $length); - $data = pack('v', $cv); + $header = pack('vv', $record, $length); + $data = pack('v', $cv); - $this->_append($header . $data); + $this->append($header . $data); } /** * Write Excel BIFF WINDOW1 record. */ - private function _writeWindow1() + private function writeWindow1() { - $record = 0x003D; // Record identifier - $length = 0x0012; // Number of bytes to follow + $record = 0x003D; // Record identifier + $length = 0x0012; // Number of bytes to follow - $xWn = 0x0000; // Horizontal position of window - $yWn = 0x0000; // Vertical position of window - $dxWn = 0x25BC; // Width of window - $dyWn = 0x1572; // Height of window + $xWn = 0x0000; // Horizontal position of window + $yWn = 0x0000; // Vertical position of window + $dxWn = 0x25BC; // Width of window + $dyWn = 0x1572; // Height of window - $grbit = 0x0038; // Option flags + $grbit = 0x0038; // Option flags // not supported by PHPExcel, so there is only one selected sheet, the active - $ctabsel = 1; // Number of workbook tabs selected + $ctabsel = 1; // Number of workbook tabs selected - $wTabRatio = 0x0258; // Tab to scrollbar ratio + $wTabRatio = 0x0258; // Tab to scrollbar ratio // not supported by PHPExcel, set to 0 $itabFirst = 0; // 1st displayed worksheet - $itabCur = $this->_phpExcel->getActiveSheetIndex(); // Active worksheet + $itabCur = $this->phpExcel->getActiveSheetIndex(); // Active worksheet - $header = pack("vv", $record, $length); - $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, $grbit, $itabCur, $itabFirst, $ctabsel, $wTabRatio); - $this->_append($header . $data); + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, $grbit, $itabCur, $itabFirst, $ctabsel, $wTabRatio); + $this->append($header . $data); } /** @@ -918,7 +910,7 @@ private function _writeWindow1() * @param PHPExcel_Worksheet $sheet Worksheet name * @param integer $offset Location of worksheet BOF */ - private function _writeBoundsheet($sheet, $offset) + private function writeBoundSheet($sheet, $offset) { $sheetname = $sheet->getTitle(); $record = 0x0085; // Record identifier @@ -942,26 +934,26 @@ private function _writeBoundsheet($sheet, $offset) // sheet type $st = 0x00; - $grbit = 0x0000; // Visibility and sheet type + $grbit = 0x0000; // Visibility and sheet type - $data = pack("VCC", $offset, $ss, $st); + $data = pack("VCC", $offset, $ss, $st); $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheetname); $length = strlen($data); $header = pack("vv", $record, $length); - $this->_append($header . $data); + $this->append($header . $data); } /** * Write Internal SUPBOOK record */ - private function _writeSupbookInternal() + private function writeSupbookInternal() { $record = 0x01AE; // Record identifier $length = 0x0004; // Bytes to follow $header = pack("vv", $record, $length); - $data = pack("vv", $this->_phpExcel->getSheetCount(), 0x0401); + $data = pack("vv", $this->phpExcel->getSheetCount(), 0x0401); return $this->writeData($header . $data); } @@ -970,17 +962,17 @@ private function _writeSupbookInternal() * formulas. * */ - private function _writeExternsheetBiff8() + private function writeExternalsheetBiff8() { - $total_references = count($this->_parser->_references); - $record = 0x0017; // Record identifier - $length = 2 + 6 * $total_references; // Number of bytes to follow + $totalReferences = count($this->parser->references); + $record = 0x0017; // Record identifier + $length = 2 + 6 * $totalReferences; // Number of bytes to follow $supbook_index = 0; // FIXME: only using internal SUPBOOK record - $header = pack("vv", $record, $length); - $data = pack('v', $total_references); - for ($i = 0; $i < $total_references; ++$i) { - $data .= $this->_parser->_references[$i]; + $header = pack("vv", $record, $length); + $data = pack('v', $totalReferences); + for ($i = 0; $i < $totalReferences; ++$i) { + $data .= $this->parser->references[$i]; } return $this->writeData($header . $data); } @@ -988,18 +980,18 @@ private function _writeExternsheetBiff8() /** * Write Excel BIFF STYLE records. */ - private function _writeStyle() + private function writeStyle() { - $record = 0x0293; // Record identifier - $length = 0x0004; // Bytes to follow + $record = 0x0293; // Record identifier + $length = 0x0004; // Bytes to follow - $ixfe = 0x8000; // Index to cell style XF - $BuiltIn = 0x00; // Built-in style - $iLevel = 0xff; // Outline style level + $ixfe = 0x8000; // Index to cell style XF + $BuiltIn = 0x00; // Built-in style + $iLevel = 0xff; // Outline style level - $header = pack("vv", $record, $length); - $data = pack("vCC", $ixfe, $BuiltIn, $iLevel); - $this->_append($header . $data); + $header = pack("vv", $record, $length); + $data = pack("vCC", $ixfe, $BuiltIn, $iLevel); + $this->append($header . $data); } /** @@ -1008,33 +1000,34 @@ private function _writeStyle() * @param string $format Custom format string * @param integer $ifmt Format index code */ - private function _writeNumFormat($format, $ifmt) + private function writeNumberFormat($format, $ifmt) { - $record = 0x041E; // Record identifier + $record = 0x041E; // Record identifier $numberFormatString = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($format); - $length = 2 + strlen($numberFormatString); // Number of bytes to follow + $length = 2 + strlen($numberFormatString); // Number of bytes to follow - $header = pack("vv", $record, $length); - $data = pack("v", $ifmt) . $numberFormatString; - $this->_append($header . $data); + $header = pack("vv", $record, $length); + $data = pack("v", $ifmt) . $numberFormatString; + $this->append($header . $data); } /** * Write DATEMODE record to indicate the date system in use (1904 or 1900). */ - private function _writeDatemode() + private function writeDateMode() { - $record = 0x0022; // Record identifier - $length = 0x0002; // Bytes to follow + $record = 0x0022; // Record identifier + $length = 0x0002; // Bytes to follow - $f1904 = (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) ? - 1 : 0; // Flag for 1904 date system + $f1904 = (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) + ? 1 + : 0; // Flag for 1904 date system - $header = pack("vv", $record, $length); - $data = pack("v", $f1904); - $this->_append($header . $data); + $header = pack("vv", $record, $length); + $data = pack("v", $f1904); + $this->append($header . $data); } /** @@ -1049,14 +1042,14 @@ private function _writeDatemode() * * @param integer $cxals Number of external references */ - private function _writeExterncount($cxals) + private function writeExternalCount($cxals) { - $record = 0x0016; // Record identifier - $length = 0x0002; // Number of bytes to follow + $record = 0x0016; // Record identifier + $length = 0x0002; // Number of bytes to follow - $header = pack("vv", $record, $length); - $data = pack("v", $cxals); - $this->_append($header . $data); + $header = pack("vv", $record, $length); + $data = pack("v", $cxals); + $this->append($header . $data); } /** @@ -1068,17 +1061,17 @@ private function _writeExterncount($cxals) * * @param string $sheetname Worksheet name */ - private function _writeExternsheet($sheetname) + private function writeExternalSheet($sheetname) { - $record = 0x0017; // Record identifier - $length = 0x02 + strlen($sheetname); // Number of bytes to follow + $record = 0x0017; // Record identifier + $length = 0x02 + strlen($sheetname); // Number of bytes to follow - $cch = strlen($sheetname); // Length of sheet name - $rgch = 0x03; // Filename encoding + $cch = strlen($sheetname); // Length of sheet name + $rgch = 0x03; // Filename encoding - $header = pack("vv", $record, $length); - $data = pack("CC", $cch, $rgch); - $this->_append($header . $data . $sheetname); + $header = pack("vv", $record, $length); + $data = pack("CC", $cch, $rgch); + $this->append($header . $data . $sheetname); } /** @@ -1092,61 +1085,61 @@ private function _writeExternsheet($sheetname) * @param integer $colmin Start colum * @param integer $colmax End column */ - private function _writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax) + private function writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax) { - $record = 0x0018; // Record identifier - $length = 0x0024; // Number of bytes to follow + $record = 0x0018; // Record identifier + $length = 0x0024; // Number of bytes to follow + + $grbit = 0x0020; // Option flags + $chKey = 0x00; // Keyboard shortcut + $cch = 0x01; // Length of text name + $cce = 0x0015; // Length of text definition + $ixals = $index + 1; // Sheet index + $itab = $ixals; // Equal to ixals + $cchCustMenu = 0x00; // Length of cust menu text + $cchDescription = 0x00; // Length of description text + $cchHelptopic = 0x00; // Length of help topic text + $cchStatustext = 0x00; // Length of status bar text + $rgch = $type; // Built-in name type + + $unknown03 = 0x3b; + $unknown04 = 0xffff - $index; + $unknown05 = 0x0000; + $unknown06 = 0x0000; + $unknown07 = 0x1087; + $unknown08 = 0x8005; - $grbit = 0x0020; // Option flags - $chKey = 0x00; // Keyboard shortcut - $cch = 0x01; // Length of text name - $cce = 0x0015; // Length of text definition - $ixals = $index + 1; // Sheet index - $itab = $ixals; // Equal to ixals - $cchCustMenu = 0x00; // Length of cust menu text - $cchDescription = 0x00; // Length of description text - $cchHelptopic = 0x00; // Length of help topic text - $cchStatustext = 0x00; // Length of status bar text - $rgch = $type; // Built-in name type - - $unknown03 = 0x3b; - $unknown04 = 0xffff-$index; - $unknown05 = 0x0000; - $unknown06 = 0x0000; - $unknown07 = 0x1087; - $unknown08 = 0x8005; - - $header = pack("vv", $record, $length); - $data = pack("v", $grbit); - $data .= pack("C", $chKey); - $data .= pack("C", $cch); - $data .= pack("v", $cce); - $data .= pack("v", $ixals); - $data .= pack("v", $itab); - $data .= pack("C", $cchCustMenu); - $data .= pack("C", $cchDescription); - $data .= pack("C", $cchHelptopic); - $data .= pack("C", $cchStatustext); - $data .= pack("C", $rgch); - $data .= pack("C", $unknown03); - $data .= pack("v", $unknown04); - $data .= pack("v", $unknown05); - $data .= pack("v", $unknown06); - $data .= pack("v", $unknown07); - $data .= pack("v", $unknown08); - $data .= pack("v", $index); - $data .= pack("v", $index); - $data .= pack("v", $rowmin); - $data .= pack("v", $rowmax); - $data .= pack("C", $colmin); - $data .= pack("C", $colmax); - $this->_append($header . $data); + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $data .= pack("C", $chKey); + $data .= pack("C", $cch); + $data .= pack("v", $cce); + $data .= pack("v", $ixals); + $data .= pack("v", $itab); + $data .= pack("C", $cchCustMenu); + $data .= pack("C", $cchDescription); + $data .= pack("C", $cchHelptopic); + $data .= pack("C", $cchStatustext); + $data .= pack("C", $rgch); + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", $rowmin); + $data .= pack("v", $rowmax); + $data .= pack("C", $colmin); + $data .= pack("C", $colmax); + $this->append($header . $data); } /** * Store the NAME record in the long format that is used for storing the repeat * rows and columns when both are specified. This shares a lot of code with - * _writeNameShort() but we use a separate method to keep the code clean. + * writeNameShort() but we use a separate method to keep the code clean. * Code abstraction for reuse can be carried too far, and I should know. ;-) * * @param integer $index Sheet index @@ -1156,7 +1149,7 @@ private function _writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colm * @param integer $colmin Start colum * @param integer $colmax End column */ - private function _writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colmax) + private function writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colmax) { $record = 0x0018; // Record identifier $length = 0x003d; // Number of bytes to follow @@ -1181,49 +1174,49 @@ private function _writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colma $unknown07 = 0x1087; $unknown08 = 0x8008; - $header = pack("vv", $record, $length); - $data = pack("v", $grbit); - $data .= pack("C", $chKey); - $data .= pack("C", $cch); - $data .= pack("v", $cce); - $data .= pack("v", $ixals); - $data .= pack("v", $itab); - $data .= pack("C", $cchCustMenu); - $data .= pack("C", $cchDescription); - $data .= pack("C", $cchHelptopic); - $data .= pack("C", $cchStatustext); - $data .= pack("C", $rgch); - $data .= pack("C", $unknown01); - $data .= pack("v", $unknown02); + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $data .= pack("C", $chKey); + $data .= pack("C", $cch); + $data .= pack("v", $cce); + $data .= pack("v", $ixals); + $data .= pack("v", $itab); + $data .= pack("C", $cchCustMenu); + $data .= pack("C", $cchDescription); + $data .= pack("C", $cchHelptopic); + $data .= pack("C", $cchStatustext); + $data .= pack("C", $rgch); + $data .= pack("C", $unknown01); + $data .= pack("v", $unknown02); // Column definition - $data .= pack("C", $unknown03); - $data .= pack("v", $unknown04); - $data .= pack("v", $unknown05); - $data .= pack("v", $unknown06); - $data .= pack("v", $unknown07); - $data .= pack("v", $unknown08); - $data .= pack("v", $index); - $data .= pack("v", $index); - $data .= pack("v", 0x0000); - $data .= pack("v", 0x3fff); - $data .= pack("C", $colmin); - $data .= pack("C", $colmax); + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", 0x0000); + $data .= pack("v", 0x3fff); + $data .= pack("C", $colmin); + $data .= pack("C", $colmax); // Row definition - $data .= pack("C", $unknown03); - $data .= pack("v", $unknown04); - $data .= pack("v", $unknown05); - $data .= pack("v", $unknown06); - $data .= pack("v", $unknown07); - $data .= pack("v", $unknown08); - $data .= pack("v", $index); - $data .= pack("v", $index); - $data .= pack("v", $rowmin); - $data .= pack("v", $rowmax); - $data .= pack("C", 0x00); - $data .= pack("C", 0xff); + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", $rowmin); + $data .= pack("v", $rowmax); + $data .= pack("C", 0x00); + $data .= pack("C", 0xff); // End of data - $data .= pack("C", 0x10); - $this->_append($header . $data); + $data .= pack("C", 0x10); + $this->append($header . $data); } /** @@ -1231,15 +1224,15 @@ private function _writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colma * * @return string */ - private function _writeCountry() + private function writeCountry() { - $record = 0x008C; // Record identifier - $length = 4; // Number of bytes to follow + $record = 0x008C; // Record identifier + $length = 4; // Number of bytes to follow $header = pack('vv', $record, $length); /* using the same country code always for simplicity */ - $data = pack('vv', $this->_country_code, $this->_country_code); - //$this->_append($header . $data); + $data = pack('vv', $this->countryCode, $this->countryCode); + //$this->append($header . $data); return $this->writeData($header . $data); } @@ -1248,7 +1241,7 @@ private function _writeCountry() * * @return string */ - private function _writeRecalcId() + private function writeRecalcId() { $record = 0x01C1; // Record identifier $length = 8; // Number of bytes to follow @@ -1264,14 +1257,14 @@ private function _writeRecalcId() /** * Stores the PALETTE biff record. */ - private function _writePalette() + private function writePalette() { - $aref = $this->_palette; + $aref = $this->palette; - $record = 0x0092; // Record identifier - $length = 2 + 4 * count($aref); // Number of bytes to follow - $ccv = count($aref); // Number of RGB values to follow - $data = ''; // The RGB data + $record = 0x0092; // Record identifier + $length = 2 + 4 * count($aref); // Number of bytes to follow + $ccv = count($aref); // Number of RGB values to follow + $data = ''; // The RGB data // Pack the RGB data foreach ($aref as $color) { @@ -1281,7 +1274,7 @@ private function _writePalette() } $header = pack("vvv", $record, $length, $ccv); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -1298,7 +1291,7 @@ private function _writePalette() * * @return string Binary data */ - private function _writeSharedStringsTable() + private function writeSharedStringsTable() { // maximum size of record data (excluding record header) $continue_limit = 8224; @@ -1307,10 +1300,10 @@ private function _writeSharedStringsTable() $recordDatas = array(); // start SST record data block with total number of strings, total number of unique strings - $recordData = pack("VV", $this->_str_total, $this->_str_unique); + $recordData = pack("VV", $this->strTotal, $this->strUnique); // loop through all (unique) strings in shared strings table - foreach (array_keys($this->_str_table) as $string) { + foreach (array_keys($this->strTable) as $string) { // here $string is a BIFF8 encoded string // length = character count @@ -1412,11 +1405,11 @@ private function _writeSharedStringsTable() /** * Writes the MSODRAWINGGROUP record if needed. Possibly split using CONTINUE records. */ - private function _writeMsoDrawingGroup() + private function writeMsoDrawingGroup() { // write the Escher stream if necessary - if (isset($this->_escher)) { - $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); + if (isset($this->escher)) { + $writer = new PHPExcel_Writer_Excel5_Escher($this->escher); $data = $writer->close(); $record = 0x00EB; @@ -1436,7 +1429,7 @@ private function _writeMsoDrawingGroup() */ public function getEscher() { - return $this->_escher; + return $this->escher; } /** @@ -1446,6 +1439,6 @@ public function getEscher() */ public function setEscher(PHPExcel_Shared_Escher $pValue = null) { - $this->_escher = $pValue; + $this->escher = $pValue; } } diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index 5a4d2a7e1..059486a2d 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -273,7 +273,7 @@ public function close() $num_sheets = $_phpSheet->getParent()->getSheetCount(); // Write BOF record - $this->_storeBof(0x0010); + $this->storeBof(0x0010); // Write PRINTHEADERS $this->_writePrintHeaders(); @@ -347,16 +347,16 @@ public function close() $this->_writeVcenter(); // Write left margin - $this->_writeMarginLeft(); + $this->writeMarginLeft(); // Write right margin - $this->_writeMarginRight(); + $this->writeMarginRight(); // Write top margin - $this->_writeMarginTop(); + $this->writeMarginTop(); // Write bottom margin - $this->_writeMarginBottom(); + $this->writeMarginBottom(); // Write page setup $this->_writeSetup(); @@ -458,7 +458,7 @@ public function close() break; case PHPExcel_Cell_DataType::TYPE_ERROR: - $this->writeBoolErr($row, $column, self::_mapErrorCode($cVal), 1, $xfIndex); + $this->writeBoolErr($row, $column, self::mapErrorCode($cVal), 1, $xfIndex); break; } @@ -466,13 +466,13 @@ public function close() } // Append - $this->_writeMsoDrawing(); + $this->writeMsoDrawing(); // Write WINDOW2 record $this->writeWindow2(); // Write PLV record - $this->_writePageLayoutView(); + $this->writePageLayoutView(); // Write ZOOM record $this->_writeZoom(); @@ -508,7 +508,7 @@ public function close() $this->writeUrl($row - 1, PHPExcel_Cell::columnIndexFromString($column) - 1, $url); } - $this->_writeDataValidity(); + $this->writeDataValidity(); $this->_writeSheetLayout(); // Write SHEETPROTECTION record @@ -536,7 +536,7 @@ public function close() } } - $this->_storeEof(); + $this->storeEof(); } /** @@ -646,7 +646,7 @@ private function writeNumber($row, $col, $num, $xfIndex) $xl_double = strrev($xl_double); } - $this->_append($header.$data.$xl_double); + $this->append($header.$data.$xl_double); return(0); } @@ -686,7 +686,7 @@ private function writeRichTextString($row, $col, $str, $xfIndex, $arrcRun) $header = pack('vv', $record, $length); $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); - $this->_append($header.$data); + $this->append($header.$data); } /** @@ -721,7 +721,7 @@ private function writeLabel($row, $col, $str, $xfIndex) $header = pack("vv", $record, $length); $data = pack("vvvv", $row, $col, $xfIndex, $strlen); - $this->_append($header . $data . $str); + $this->append($header . $data . $str); return($str_error); } @@ -755,7 +755,7 @@ private function writeLabelSst($row, $col, $str, $xfIndex) $header = pack('vv', $record, $length); $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); - $this->_append($header.$data); + $this->append($header.$data); } /** @@ -776,14 +776,14 @@ private function writeNote($row, $col, $note) $length = 0x0006 + min($note_length, 2048); $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $note_length); - $this->_append($header . $data . substr($note, 0, 2048)); + $this->append($header . $data . substr($note, 0, 2048)); for ($i = $max_length; $i < $note_length; $i += $max_length) { $chunk = substr($note, $i, $max_length); $length = 0x0006 + strlen($chunk); $header = pack("vv", $record, $length); $data = pack("vvv", -1, 0, strlen($chunk)); - $this->_append($header.$data.$chunk); + $this->append($header.$data.$chunk); } return(0); } @@ -811,7 +811,7 @@ public function _writeBlank($row, $col, $xfIndex) $header = pack("vv", $record, $length); $data = pack("vvv", $row, $col, $xfIndex); - $this->_append($header . $data); + $this->append($header . $data); return 0; } @@ -831,7 +831,7 @@ private function writeBoolErr($row, $col, $value, $isError, $xfIndex) $header = pack("vv", $record, $length); $data = pack("vvvCC", $row, $col, $xfIndex, $value, $isError); - $this->_append($header . $data); + $this->append($header . $data); return 0; } @@ -871,7 +871,7 @@ private function writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) } elseif (is_string($calculatedValue)) { if (array_key_exists($calculatedValue, PHPExcel_Cell_DataType::getErrorCodes())) { // Error value - $num = pack('CCCvCv', 0x02, 0x00, self::_mapErrorCode($calculatedValue), 0x00, 0x00, 0xFFFF); + $num = pack('CCCvCv', 0x02, 0x00, self::mapErrorCode($calculatedValue), 0x00, 0x00, 0xFFFF); } elseif ($calculatedValue === '') { // Empty string (and BIFF8) $num = pack('CCCvCv', 0x03, 0x00, 0x00, 0x00, 0x00, 0xFFFF); @@ -913,7 +913,7 @@ private function writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) $data = pack("vvv", $row, $col, $xfIndex) . $num . pack("vVv", $grbit, $unknown, $formlen); - $this->_append($header . $data . $formula); + $this->append($header . $data . $formula); // Append also a STRING record if necessary if ($stringValue !== null) { @@ -941,7 +941,7 @@ private function writeStringRecord($stringValue) $length = strlen($data); $header = pack('vv', $record, $length); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -1038,7 +1038,7 @@ public function writeUrlWeb($row1, $col1, $row2, $col2, $url) $data = pack("vvvv", $row1, $row2, $col1, $col2); // Write the packed data - $this->_append($header . $data . + $this->append($header . $data . $unknown1 . $options . $unknown2 . $url_len . $url); return 0; @@ -1087,7 +1087,7 @@ public function writeUrlInternal($row1, $col1, $row2, $col2, $url) $data = pack("vvvv", $row1, $row2, $col1, $col2); // Write the packed data - $this->_append($header . $data . + $this->append($header . $data . $unknown1 . $options . $url_len . $url); return 0; @@ -1190,7 +1190,7 @@ public function writeUrlExternal($row1, $col1, $row2, $col2, $url) $header = pack("vv", $record, $length); // Write the packed data - $this->_append($header. $data); + $this->append($header. $data); return 0; } @@ -1247,7 +1247,7 @@ private function writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) $header = pack("vv", $record, $length); $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, $irwMac, $reserved, $grbit, $ixfe); - $this->_append($header.$data); + $this->append($header.$data); } /** @@ -1261,7 +1261,7 @@ private function writeDimensions() $data = pack('VVvvv', $this->firstRowIndex, $this->lastRowIndex + 1, $this->firstColumnIndex, $this->lastColumnIndex + 1, 0x0000); // reserved $header = pack("vv", $record, $length); - $this->_append($header.$data); + $this->append($header.$data); } /** @@ -1315,7 +1315,7 @@ private function writeWindow2() $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000); - $this->_append($header.$data); + $this->append($header.$data); } /** @@ -1337,7 +1337,7 @@ private function writeDefaultRowHeight() $header = pack("vv", $record, $length); $data = pack("vv", 1, $defaultRowHeight); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -1352,7 +1352,7 @@ private function _writeDefcol() $header = pack("vv", $record, $length); $data = pack("v", $defaultColWidth); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -1410,7 +1410,7 @@ private function _writeColinfo($col_array) $header = pack("vv", $record, $length); $data = pack("vvvvvv", $colFirst, $colLast, $coldx, $ixfe, $grbit, $reserved); - $this->_append($header.$data); + $this->append($header.$data); } /** @@ -1471,7 +1471,7 @@ private function _writeSelection() $header = pack("vv", $record, $length); $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct, $irefAct, $cref, $rwFirst, $rwLast, $colFirst, $colLast); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -1519,7 +1519,7 @@ private function _writeMergedCells() $recordData = pack('v', $j) . $recordData; $length = strlen($recordData); $header = pack('vv', $record, $length); - $this->_append($header . $recordData); + $this->append($header . $recordData); // initialize for next record, if any $recordData = ''; @@ -1552,7 +1552,7 @@ private function _writeSheetLayout() $record = 0x0862; // Record identifier $header = pack('vv', $record, $length); - $this->_append($header . $recordData); + $this->append($header . $recordData); } /** @@ -1596,7 +1596,7 @@ private function _writeSheetProtection() $length = strlen($recordData); $header = pack('vv', $record, $length); - $this->_append($header . $recordData); + $this->append($header . $recordData); } /** @@ -1643,7 +1643,7 @@ private function _writeRangeProtection() $record = 0x0868; // Record identifier $header = pack("vv", $record, $length); - $this->_append($header . $recordData); + $this->append($header . $recordData); } } @@ -1666,7 +1666,7 @@ private function _writeExterncount($count) $header = pack("vv", $record, $length); $data = pack("v", $count); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -1697,7 +1697,7 @@ private function _writeExternsheet($sheetname) $header = pack("vv", $record, $length); $data = pack("CC", $cch, $rgch); - $this->_append($header . $data . $sheetname); + $this->append($header . $data . $sheetname); } /** @@ -1780,7 +1780,7 @@ private function _writePanes() $header = pack("vv", $record, $length); $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -1841,7 +1841,7 @@ private function _writeSetup() $data1 = pack("vvvvvvvv", $iPaperSize, $iScale, $iPageStart, $iFitWidth, $iFitHeight, $grbit, $iRes, $iVRes); $data2 = $numHdr.$numFtr; $data3 = pack("v", $iCopies); - $this->_append($header . $data1 . $data2 . $data3); + $this->append($header . $data1 . $data2 . $data3); } /** @@ -1865,7 +1865,7 @@ private function _writeHeader() $header = pack("vv", $record, $length); - $this->_append($header . $recordData); + $this->append($header . $recordData); } /** @@ -1889,7 +1889,7 @@ private function _writeFooter() $header = pack("vv", $record, $length); - $this->_append($header . $recordData); + $this->append($header . $recordData); } /** @@ -1907,7 +1907,7 @@ private function _writeHcenter() $header = pack("vv", $record, $length); $data = pack("v", $fHCenter); - $this->_append($header.$data); + $this->append($header.$data); } /** @@ -1922,13 +1922,13 @@ private function _writeVcenter() $header = pack("vv", $record, $length); $data = pack("v", $fVCenter); - $this->_append($header . $data); + $this->append($header . $data); } /** * Store the LEFTMARGIN BIFF record. */ - private function _writeMarginLeft() + private function writeMarginLeft() { $record = 0x0026; // Record identifier $length = 0x0008; // Bytes to follow @@ -1941,13 +1941,13 @@ private function _writeMarginLeft() $data = strrev($data); } - $this->_append($header . $data); + $this->append($header . $data); } /** * Store the RIGHTMARGIN BIFF record. */ - private function _writeMarginRight() + private function writeMarginRight() { $record = 0x0027; // Record identifier $length = 0x0008; // Bytes to follow @@ -1960,13 +1960,13 @@ private function _writeMarginRight() $data = strrev($data); } - $this->_append($header . $data); + $this->append($header . $data); } /** * Store the TOPMARGIN BIFF record. */ - private function _writeMarginTop() + private function writeMarginTop() { $record = 0x0028; // Record identifier $length = 0x0008; // Bytes to follow @@ -1979,13 +1979,13 @@ private function _writeMarginTop() $data = strrev($data); } - $this->_append($header . $data); + $this->append($header . $data); } /** * Store the BOTTOMMARGIN BIFF record. */ - private function _writeMarginBottom() + private function writeMarginBottom() { $record = 0x0029; // Record identifier $length = 0x0008; // Bytes to follow @@ -1998,7 +1998,7 @@ private function _writeMarginBottom() $data = strrev($data); } - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2013,7 +2013,7 @@ private function _writePrintHeaders() $header = pack("vv", $record, $length); $data = pack("v", $fPrintRwCol); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2029,7 +2029,7 @@ private function _writePrintGridlines() $header = pack("vv", $record, $length); $data = pack("v", $fPrintGrid); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2045,7 +2045,7 @@ private function _writeGridset() $header = pack("vv", $record, $length); $data = pack("v", $fGridSet); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2061,7 +2061,7 @@ private function _writeAutoFilterInfo() $header = pack("vv", $record, $length); $data = pack("v", $iNumFilters); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2108,7 +2108,7 @@ private function _writeGuts() $header = pack("vv", $record, $length); $data = pack("vvvv", $dxRwGut, $dxColGut, $maxRowOutlineLevel, $col_level); - $this->_append($header.$data); + $this->append($header.$data); } /** @@ -2144,7 +2144,7 @@ private function _writeWsbool() $header = pack("vv", $record, $length); $data = pack("v", $grbit); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2197,7 +2197,7 @@ private function _writeBreaks() $data .= pack("vvv", $hbreak, 0x0000, 0x00ff); } - $this->_append($header . $data); + $this->append($header . $data); } // vertical page breaks @@ -2224,7 +2224,7 @@ private function _writeBreaks() $data .= pack("vvv", $vbreak, 0x0000, 0xffff); } - $this->_append($header . $data); + $this->append($header . $data); } } @@ -2246,7 +2246,7 @@ private function _writeProtect() $header = pack("vv", $record, $length); $data = pack("v", $fLock); - $this->_append($header.$data); + $this->append($header.$data); } /** @@ -2270,7 +2270,7 @@ private function _writeScenProtect() $header = pack('vv', $record, $length); $data = pack('v', 1); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2294,7 +2294,7 @@ private function _writeObjectProtect() $header = pack('vv', $record, $length); $data = pack('v', 1); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2315,7 +2315,7 @@ private function _writePassword() $header = pack("vv", $record, $length); $data = pack("v", $wPassword); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2350,7 +2350,7 @@ public function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $lcb = $size; $header = pack("vvvvV", $record, $length, $cf, $env, $lcb); - $this->_append($header.$data); + $this->append($header.$data); } /** @@ -2534,7 +2534,7 @@ private function _writeObjPicture($colL, $dxL, $rwT, $dyT, $colR, $dxR, $rwB, $d $data .= pack("v", $grbit2); $data .= pack("V", $Reserved5); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2669,7 +2669,7 @@ private function _writeZoom() $header = pack("vv", $record, $length); $data = pack("vv", $this->_phpSheet->getSheetView()->getZoomScale(), 100); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -2695,7 +2695,7 @@ public function setEscher(PHPExcel_Shared_Escher $pValue = null) /** * Write MSODRAWING record */ - private function _writeMsoDrawing() + private function writeMsoDrawing() { // write the Escher stream if necessary if (isset($this->escher)) { @@ -2718,7 +2718,7 @@ private function _writeMsoDrawing() $length = strlen($dataChunk); $header = pack("vv", $record, $length); - $this->_append($header . $dataChunk); + $this->append($header . $dataChunk); // OBJ record $record = 0x005D; // record identifier @@ -2772,7 +2772,7 @@ private function _writeMsoDrawing() $length = strlen($objData); $header = pack('vv', $record, $length); - $this->_append($header . $objData); + $this->append($header . $objData); } } } @@ -2780,7 +2780,7 @@ private function _writeMsoDrawing() /** * Store the DATAVALIDATIONS and DATAVALIDATION records. */ - private function _writeDataValidity() + private function writeDataValidity() { // Datavalidation collection $dataValidationCollection = $this->_phpSheet->getDataValidationCollection(); @@ -2798,7 +2798,7 @@ private function _writeDataValidity() $header = pack('vv', $record, $length); $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId, count($dataValidationCollection)); - $this->_append($header.$data); + $this->append($header.$data); // DATAVALIDATION records $record = 0x01BE; // Record identifier @@ -2963,7 +2963,7 @@ private function _writeDataValidity() $length = strlen($data); $header = pack("vv", $record, $length); - $this->_append($header . $data); + $this->append($header . $data); } } } @@ -2974,7 +2974,7 @@ private function _writeDataValidity() * @param string $errorCode * @return int */ - private static function _mapErrorCode($errorCode) + private static function mapErrorCode($errorCode) { switch ($errorCode) { case '#NULL!': @@ -2999,7 +2999,7 @@ private static function _mapErrorCode($errorCode) /** * Write PLV Record */ - private function _writePageLayoutView() + private function writePageLayoutView() { $record = 0x088B; // Record identifier $length = 0x0010; // Bytes to follow @@ -3024,7 +3024,7 @@ private function _writePageLayoutView() $header = pack("vv", $record, $length); $data = pack("vvVVvv", $rt, $grbitFrt, 0x00000000, 0x00000000, $wScalvePLV, $grbit); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -4200,7 +4200,7 @@ private function writeCFRule(PHPExcel_Style_Conditional $conditional) $data .= $operand2; } $header = pack('vv', $record, strlen($data)); - $this->_append($header . $data); + $this->append($header . $data); } /** @@ -4251,6 +4251,6 @@ private function writeCFHeader() $data .= $cellRange; $data .= pack('v', 0x0001); $data .= $cellRange; - $this->_append($header . $data); + $this->append($header . $data); } } diff --git a/Classes/PHPExcel/Writer/Excel5/Xf.php b/Classes/PHPExcel/Writer/Excel5/Xf.php index 61a42eb26..e41589a84 100644 --- a/Classes/PHPExcel/Writer/Excel5/Xf.php +++ b/Classes/PHPExcel/Writer/Excel5/Xf.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Writer_Excel5_Xf * * Copyright (c) 2006 - 2015 PHPExcel * @@ -59,15 +60,6 @@ // * License along with this library; if not, write to the Free Software // * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // */ - - -/** - * PHPExcel_Writer_Excel5_Xf - * - * @category PHPExcel - * @package PHPExcel_Writer_Excel5 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Writer_Excel5_Xf { /** From 44f049a0a5dc7c23e45b0d0a3fe55637b38c42c4 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Fri, 22 May 2015 23:57:51 +0100 Subject: [PATCH 397/467] Fix to short array reference in tests for PHP < 5.4 --- unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php b/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php index e781f71ee..49e4aa980 100644 --- a/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php +++ b/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php @@ -45,7 +45,7 @@ public function testValidXML($filename, $expectedResult) public function providerValidXML() { - $tests = []; + $tests = array(); foreach (glob('rawTestData/Reader/XEETestValid*.xml') as $file) { $tests[] = [realpath($file), file_get_contents($file)]; } From 98a087afb4c18f5b424352fafcacdc891dafe96b Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sat, 23 May 2015 18:37:11 +0100 Subject: [PATCH 398/467] This should be the last of the writer changes for psr-2, leaving just trendlines before we've done as much as we can without breaking backward compatibility --- Classes/PHPExcel/Writer/Excel5.php | 6 +- Classes/PHPExcel/Writer/Excel5/Workbook.php | 16 +- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 466 +++++++++---------- 3 files changed, 236 insertions(+), 252 deletions(-) diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index fed37fa22..2dede819a 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -149,15 +149,15 @@ public function save($pFilename = null) // add fonts from rich text eleemnts for ($i = 0; $i < $countSheets; ++$i) { - foreach ($this->writerWorksheets[$i]->_phpSheet->getCellCollection() as $cellID) { - $cell = $this->writerWorksheets[$i]->_phpSheet->getCell($cellID); + foreach ($this->writerWorksheets[$i]->phpSheet->getCellCollection() as $cellID) { + $cell = $this->writerWorksheets[$i]->phpSheet->getCell($cellID); $cVal = $cell->getValue(); if ($cVal instanceof PHPExcel_RichText) { $elements = $cVal->getRichTextElements(); foreach ($elements as $element) { if ($element instanceof PHPExcel_RichText_Run) { $font = $element->getFont(); - $this->writerWorksheets[$i]->_fntHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font); + $this->writerWorksheets[$i]->fontHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font); } } } diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index ad201c87a..8b0684375 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -153,21 +153,21 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter * * @var int */ - private $strTotal; + private $stringTotal; /** * Number of unique shared strings in workbook * * @var int */ - private $strUnique; + private $stringUnique; /** * Array of unique shared strings in workbook * * @var array */ - private $strTable; + private $stringTable; /** * Color cache @@ -202,9 +202,9 @@ public function __construct(PHPExcel $phpExcel = null, &$str_total, &$str_unique $this->palette = array(); $this->countryCode = -1; - $this->strTotal = &$str_total; - $this->strUnique = &$str_unique; - $this->strTable = &$str_table; + $this->stringTotal = &$str_total; + $this->stringUnique = &$str_unique; + $this->stringTable = &$str_table; $this->colors = &$colors; $this->setPaletteXl97(); @@ -1300,10 +1300,10 @@ private function writeSharedStringsTable() $recordDatas = array(); // start SST record data block with total number of strings, total number of unique strings - $recordData = pack("VV", $this->strTotal, $this->strUnique); + $recordData = pack("VV", $this->stringTotal, $this->stringUnique); // loop through all (unique) strings in shared strings table - foreach (array_keys($this->strTable) as $string) { + foreach (array_keys($this->stringTable) as $string) { // here $string is a BIFF8 encoded string // length = character count diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index 059486a2d..be965e23d 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -73,67 +73,67 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter * Maximum number of characters for a string (LABEL record in BIFF5) * @var integer */ - public $_xls_strmax; + private $xlsStringMaxLength; /** * Array containing format information for columns * @var array */ - public $_colinfo; + private $columnInfo; /** * Array containing the selected area for the worksheet * @var array */ - public $_selection; + private $selection; /** * The active pane for the worksheet * @var integer */ - public $_active_pane; + private $activePane; /** * Whether to use outline. * @var integer */ - public $_outline_on; + private $outlineOn; /** * Auto outline styles. * @var bool */ - public $_outline_style; + private $outlineStyle; /** * Whether to have outline summary below. * @var bool */ - public $_outline_below; + private $outlineBelow; /** * Whether to have outline summary at the right. * @var bool */ - public $_outline_right; + private $outlineRight; /** * Reference to the total number of strings in the workbook * @var integer */ - public $_str_total; + private $stringTotal; /** * Reference to the number of unique strings in the workbook * @var integer */ - public $_str_unique; + private $stringUnique; /** * Reference to the array containing all the unique strings in the workbook * @var array */ - public $_str_table; + private $stringTable; /** * Color cache @@ -168,7 +168,7 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter * Sheet object * @var PHPExcel_Worksheet */ - public $_phpSheet; + public $phpSheet; /** * Count cell style Xfs @@ -189,7 +189,7 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter * * @var array */ - public $_fntHashIndex; + public $fontHashIndex; /** * Constructor @@ -213,43 +213,43 @@ public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, $p $this->_preCalculateFormulas = $preCalculateFormulas; - $this->_str_total = &$str_total; - $this->_str_unique = &$str_unique; - $this->_str_table = &$str_table; + $this->stringTotal = &$str_total; + $this->stringUnique = &$str_unique; + $this->stringTable = &$str_table; $this->colors = &$colors; $this->parser = $parser; - $this->_phpSheet = $phpSheet; + $this->phpSheet = $phpSheet; //$this->ext_sheets = array(); //$this->offset = 0; - $this->_xls_strmax = 255; - $this->_colinfo = array(); - $this->_selection = array(0,0,0,0); - $this->_active_pane = 3; + $this->xlsStringMaxLength = 255; + $this->columnInfo = array(); + $this->selection = array(0,0,0,0); + $this->activePane = 3; - $this->_print_headers = 0; + $this->_print_headers = 0; - $this->_outline_style = 0; - $this->_outline_below = 1; - $this->_outline_right = 1; - $this->_outline_on = 1; + $this->outlineStyle = 0; + $this->outlineBelow = 1; + $this->outlineRight = 1; + $this->outlineOn = 1; - $this->_fntHashIndex = array(); + $this->fontHashIndex = array(); // calculate values for DIMENSIONS record $minR = 1; $minC = 'A'; - $maxR = $this->_phpSheet->getHighestRow(); - $maxC = $this->_phpSheet->getHighestColumn(); + $maxR = $this->phpSheet->getHighestRow(); + $maxC = $this->phpSheet->getHighestColumn(); // Determine lowest and highest column and row // $this->firstRowIndex = ($minR > 65535) ? 65535 : $minR; $this->lastRowIndex = ($maxR > 65535) ? 65535 : $maxR ; - $this->firstColumnIndex = PHPExcel_Cell::columnIndexFromString($minC); - $this->lastColumnIndex = PHPExcel_Cell::columnIndexFromString($maxC); + $this->firstColumnIndex = PHPExcel_Cell::columnIndexFromString($minC); + $this->lastColumnIndex = PHPExcel_Cell::columnIndexFromString($maxC); // if ($this->firstColumnIndex > 255) $this->firstColumnIndex = 255; if ($this->lastColumnIndex > 255) { @@ -268,31 +268,31 @@ public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, $p */ public function close() { - $_phpSheet = $this->_phpSheet; + $phpSheet = $this->phpSheet; - $num_sheets = $_phpSheet->getParent()->getSheetCount(); + $num_sheets = $phpSheet->getParent()->getSheetCount(); // Write BOF record $this->storeBof(0x0010); // Write PRINTHEADERS - $this->_writePrintHeaders(); + $this->writePrintHeaders(); // Write PRINTGRIDLINES - $this->_writePrintGridlines(); + $this->writePrintGridlines(); // Write GRIDSET - $this->_writeGridset(); + $this->writeGridset(); // Calculate column widths - $_phpSheet->calculateColumnWidths(); + $phpSheet->calculateColumnWidths(); // Column dimensions - if (($defaultWidth = $_phpSheet->getDefaultColumnDimension()->getWidth()) < 0) { - $defaultWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($_phpSheet->getParent()->getDefaultStyle()->getFont()); + if (($defaultWidth = $phpSheet->getDefaultColumnDimension()->getWidth()) < 0) { + $defaultWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($phpSheet->getParent()->getDefaultStyle()->getFont()); } - $columnDimensions = $_phpSheet->getColumnDimensions(); + $columnDimensions = $phpSheet->getColumnDimensions(); $maxCol = $this->lastColumnIndex -1; for ($i = 0; $i <= $maxCol; ++$i) { $hidden = 0; @@ -312,95 +312,79 @@ public function close() $xfIndex = $columnDimension->getXfIndex() + 15; // there are 15 cell style Xfs } - // Components of _colinfo: + // Components of columnInfo: // $firstcol first column on the range // $lastcol last column on the range // $width width to set // $xfIndex The optional cell style Xf index to apply to the columns // $hidden The optional hidden atribute // $level The optional outline level - $this->_colinfo[] = array($i, $i, $width, $xfIndex, $hidden, $level); + $this->columnInfo[] = array($i, $i, $width, $xfIndex, $hidden, $level); } // Write GUTS - $this->_writeGuts(); + $this->writeGuts(); // Write DEFAULTROWHEIGHT $this->writeDefaultRowHeight(); - // Write WSBOOL - $this->_writeWsbool(); - + $this->writeWsbool(); // Write horizontal and vertical page breaks - $this->_writeBreaks(); - + $this->writeBreaks(); // Write page header - $this->_writeHeader(); - + $this->writeHeader(); // Write page footer - $this->_writeFooter(); - + $this->writeFooter(); // Write page horizontal centering - $this->_writeHcenter(); - + $this->writeHcenter(); // Write page vertical centering - $this->_writeVcenter(); - + $this->writeVcenter(); // Write left margin $this->writeMarginLeft(); - // Write right margin $this->writeMarginRight(); - // Write top margin $this->writeMarginTop(); - // Write bottom margin $this->writeMarginBottom(); - // Write page setup - $this->_writeSetup(); - + $this->writeSetup(); // Write sheet protection - $this->_writeProtect(); - + $this->writeProtect(); // Write SCENPROTECT - $this->_writeScenProtect(); - + $this->writeScenProtect(); // Write OBJECTPROTECT - $this->_writeObjectProtect(); - + $this->writeObjectProtect(); // Write sheet password - $this->_writePassword(); - + $this->writePassword(); // Write DEFCOLWIDTH record - $this->_writeDefcol(); + $this->writeDefcol(); // Write the COLINFO records if they exist - if (!empty($this->_colinfo)) { - $colcount = count($this->_colinfo); + if (!empty($this->columnInfo)) { + $colcount = count($this->columnInfo); for ($i = 0; $i < $colcount; ++$i) { - $this->_writeColinfo($this->_colinfo[$i]); + $this->writeColinfo($this->columnInfo[$i]); } } - $autoFilterRange = $_phpSheet->getAutoFilter()->getRange(); + $autoFilterRange = $phpSheet->getAutoFilter()->getRange(); if (!empty($autoFilterRange)) { // Write AUTOFILTERINFO - $this->_writeAutoFilterInfo(); + $this->writeAutoFilterInfo(); } // Write sheet dimensions $this->writeDimensions(); // Row dimensions - foreach ($_phpSheet->getRowDimensions() as $rowDimension) { + foreach ($phpSheet->getRowDimensions() as $rowDimension) { $xfIndex = $rowDimension->getXfIndex() + 15; // there are 15 cellXfs $this->writeRow($rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel()); } // Write Cells - foreach ($_phpSheet->getCellCollection() as $cellID) { - $cell = $_phpSheet->getCell($cellID); + foreach ($phpSheet->getCellCollection() as $cellID) { + $cell = $phpSheet->getCell($cellID); $row = $cell->getRow() - 1; $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1; @@ -423,7 +407,7 @@ public function close() foreach ($elements as $element) { // FONT Index if ($element instanceof PHPExcel_RichText_Run) { - $str_fontidx = $this->_fntHashIndex[$element->getFont()->getHashCode()]; + $str_fontidx = $this->fontHashIndex[$element->getFont()->getHashCode()]; } else { $str_fontidx = 0; } @@ -437,7 +421,7 @@ public function close() case PHPExcel_Cell_DataType::TYPE_STRING: case PHPExcel_Cell_DataType::TYPE_NULL: if ($cVal === '' || $cVal === null) { - $this->_writeBlank($row, $column, $xfIndex); + $this->writeBlank($row, $column, $xfIndex); } else { $this->writeString($row, $column, $cVal, $xfIndex); } @@ -475,19 +459,19 @@ public function close() $this->writePageLayoutView(); // Write ZOOM record - $this->_writeZoom(); - if ($_phpSheet->getFreezePane()) { - $this->_writePanes(); + $this->writeZoom(); + if ($phpSheet->getFreezePane()) { + $this->writePanes(); } // Write SELECTION record - $this->_writeSelection(); + $this->writeSelection(); // Write MergedCellsTable Record - $this->_writeMergedCells(); + $this->writeMergedCells(); // Hyperlinks - foreach ($_phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) { + foreach ($phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) { list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinate); $url = $hyperlink->getUrl(); @@ -509,13 +493,13 @@ public function close() } $this->writeDataValidity(); - $this->_writeSheetLayout(); + $this->writeSheetLayout(); // Write SHEETPROTECTION record - $this->_writeSheetProtection(); - $this->_writeRangeProtection(); + $this->writeSheetProtection(); + $this->writeRangeProtection(); - $arrConditionalStyles = $_phpSheet->getConditionalStylesCollection(); + $arrConditionalStyles = $phpSheet->getConditionalStylesCollection(); if (!empty($arrConditionalStyles)) { $arrConditional = array(); // @todo CFRule & CFHeader @@ -609,14 +593,14 @@ public function printRowColHeaders($print = 1) */ public function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false) { - $this->_outline_on = $visible; - $this->_outline_below = $symbols_below; - $this->_outline_right = $symbols_right; - $this->_outline_style = $auto_style; + $this->outlineOn = $visible; + $this->outlineBelow = $symbols_below; + $this->outlineRight = $symbols_right; + $this->outlineStyle = $auto_style; // Ensure this is a boolean vale for Window2 - if ($this->_outline_on) { - $this->_outline_on = 1; + if ($this->outlineOn) { + $this->outlineOn = 1; } } @@ -679,13 +663,13 @@ private function writeRichTextString($row, $col, $str, $xfIndex, $arrcRun) $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($str, $arrcRun); /* check if string is already present */ - if (!isset($this->_str_table[$str])) { - $this->_str_table[$str] = $this->_str_unique++; + if (!isset($this->stringTable[$str])) { + $this->stringTable[$str] = $this->stringUnique++; } - $this->_str_total++; + $this->stringTotal++; $header = pack('vv', $record, $length); - $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); + $data = pack('vvvV', $row, $col, $xfIndex, $this->stringTable[$str]); $this->append($header.$data); } @@ -712,10 +696,10 @@ private function writeLabel($row, $col, $str, $xfIndex) $str_error = 0; - if ($strlen > $this->_xls_strmax) { // LABEL must be < 255 chars - $str = substr($str, 0, $this->_xls_strmax); - $length = 0x0008 + $this->_xls_strmax; - $strlen = $this->_xls_strmax; + if ($strlen > $this->xlsStringMaxLength) { // LABEL must be < 255 chars + $str = substr($str, 0, $this->xlsStringMaxLength); + $length = 0x0008 + $this->xlsStringMaxLength; + $strlen = $this->xlsStringMaxLength; $str_error = -3; } @@ -748,13 +732,13 @@ private function writeLabelSst($row, $col, $str, $xfIndex) $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($str); /* check if string is already present */ - if (!isset($this->_str_table[$str])) { - $this->_str_table[$str] = $this->_str_unique++; + if (!isset($this->stringTable[$str])) { + $this->stringTable[$str] = $this->stringUnique++; } - $this->_str_total++; + $this->stringTotal++; $header = pack('vv', $record, $length); - $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); + $data = pack('vvvV', $row, $col, $xfIndex, $this->stringTable[$str]); $this->append($header.$data); } @@ -804,7 +788,7 @@ private function writeNote($row, $col, $note) * @param integer $col Zero indexed column * @param mixed $xfIndex The XF format index */ - public function _writeBlank($row, $col, $xfIndex) + public function writeBlank($row, $col, $xfIndex) { $record = 0x0201; // Record identifier $length = 0x0006; // Number of bytes to follow @@ -1279,18 +1263,18 @@ private function writeWindow2() // The options flags that comprise $grbit $fDspFmla = 0; // 0 - bit - $fDspGrid = $this->_phpSheet->getShowGridlines() ? 1 : 0; // 1 - $fDspRwCol = $this->_phpSheet->getShowRowColHeaders() ? 1 : 0; // 2 - $fFrozen = $this->_phpSheet->getFreezePane() ? 1 : 0; // 3 + $fDspGrid = $this->phpSheet->getShowGridlines() ? 1 : 0; // 1 + $fDspRwCol = $this->phpSheet->getShowRowColHeaders() ? 1 : 0; // 2 + $fFrozen = $this->phpSheet->getFreezePane() ? 1 : 0; // 3 $fDspZeros = 1; // 4 $fDefaultHdr = 1; // 5 - $fArabic = $this->_phpSheet->getRightToLeft() ? 1 : 0; // 6 - $fDspGuts = $this->_outline_on; // 7 + $fArabic = $this->phpSheet->getRightToLeft() ? 1 : 0; // 6 + $fDspGuts = $this->outlineOn; // 7 $fFrozenNoSplit = 0; // 0 - bit // no support in PHPExcel for selected sheet, therefore sheet is only selected if it is the active sheet - $fSelected = ($this->_phpSheet === $this->_phpSheet->getParent()->getActiveSheet()) ? 1 : 0; + $fSelected = ($this->phpSheet === $this->phpSheet->getParent()->getActiveSheet()) ? 1 : 0; $fPaged = 1; // 2 - $fPageBreakPreview = $this->_phpSheet->getSheetView()->getView() === PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW; + $fPageBreakPreview = $this->phpSheet->getSheetView()->getView() === PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW; $grbit = $fDspFmla; $grbit |= $fDspGrid << 1; @@ -1310,8 +1294,8 @@ private function writeWindow2() // FIXME !!! $rgbHdr = 0x0040; // Row/column heading and gridline color index - $zoom_factor_page_break = ($fPageBreakPreview ? $this->_phpSheet->getSheetView()->getZoomScale() : 0x0000); - $zoom_factor_normal = $this->_phpSheet->getSheetView()->getZoomScaleNormal(); + $zoom_factor_page_break = ($fPageBreakPreview ? $this->phpSheet->getSheetView()->getZoomScale() : 0x0000); + $zoom_factor_normal = $this->phpSheet->getSheetView()->getZoomScaleNormal(); $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000); @@ -1323,7 +1307,7 @@ private function writeWindow2() */ private function writeDefaultRowHeight() { - $defaultRowHeight = $this->_phpSheet->getDefaultRowDimension()->getRowHeight(); + $defaultRowHeight = $this->phpSheet->getDefaultRowDimension()->getRowHeight(); if ($defaultRowHeight < 0) { return; @@ -1343,7 +1327,7 @@ private function writeDefaultRowHeight() /** * Write BIFF record DEFCOLWIDTH if COLINFO records are in use. */ - private function _writeDefcol() + private function writeDefcol() { $defaultColWidth = 8; @@ -1369,7 +1353,7 @@ private function _writeDefcol() * 4 => Option flags. * 5 => Optional outline level */ - private function _writeColinfo($col_array) + private function writeColinfo($col_array) { if (isset($col_array[0])) { $colFirst = $col_array[0]; @@ -1416,11 +1400,11 @@ private function _writeColinfo($col_array) /** * Write BIFF record SELECTION. */ - private function _writeSelection() + private function writeSelection() { // look up the selected cell range - $selectedCells = $this->_phpSheet->getSelectedCells(); - $selectedCells = PHPExcel_Cell::splitRange($this->_phpSheet->getSelectedCells()); + $selectedCells = $this->phpSheet->getSelectedCells(); + $selectedCells = PHPExcel_Cell::splitRange($this->phpSheet->getSelectedCells()); $selectedCells = $selectedCells[0]; if (count($selectedCells) == 2) { list($first, $last) = $selectedCells; @@ -1447,7 +1431,7 @@ private function _writeSelection() $record = 0x001D; // Record identifier $length = 0x000F; // Number of bytes to follow - $pnn = $this->_active_pane; // Pane position + $pnn = $this->activePane; // Pane position $rwAct = $rwFirst; // Active row $colAct = $colFirst; // Active column $irefAct = 0; // Active cell ref @@ -1477,9 +1461,9 @@ private function _writeSelection() /** * Store the MERGEDCELLS records for all ranges of merged cells */ - private function _writeMergedCells() + private function writeMergedCells() { - $mergeCells = $this->_phpSheet->getMergeCells(); + $mergeCells = $this->phpSheet->getMergeCells(); $countMergeCells = count($mergeCells); if ($countMergeCells == 0) { @@ -1531,9 +1515,9 @@ private function _writeMergedCells() /** * Write SHEETLAYOUT record */ - private function _writeSheetLayout() + private function writeSheetLayout() { - if (!$this->_phpSheet->isTabColorSet()) { + if (!$this->phpSheet->isTabColorSet()) { return; } @@ -1544,7 +1528,7 @@ private function _writeSheetLayout() 0x00000000, // unused 0x00000000, // unused 0x00000014, // size of record data - $this->colors[$this->_phpSheet->getTabColor()->getRGB()], // color index + $this->colors[$this->phpSheet->getTabColor()->getRGB()], // color index 0x0000 // unused ); @@ -1558,27 +1542,27 @@ private function _writeSheetLayout() /** * Write SHEETPROTECTION */ - private function _writeSheetProtection() + private function writeSheetProtection() { // record identifier $record = 0x0867; // prepare options - $options = (int) !$this->_phpSheet->getProtection()->getObjects() - | (int) !$this->_phpSheet->getProtection()->getScenarios() << 1 - | (int) !$this->_phpSheet->getProtection()->getFormatCells() << 2 - | (int) !$this->_phpSheet->getProtection()->getFormatColumns() << 3 - | (int) !$this->_phpSheet->getProtection()->getFormatRows() << 4 - | (int) !$this->_phpSheet->getProtection()->getInsertColumns() << 5 - | (int) !$this->_phpSheet->getProtection()->getInsertRows() << 6 - | (int) !$this->_phpSheet->getProtection()->getInsertHyperlinks() << 7 - | (int) !$this->_phpSheet->getProtection()->getDeleteColumns() << 8 - | (int) !$this->_phpSheet->getProtection()->getDeleteRows() << 9 - | (int) !$this->_phpSheet->getProtection()->getSelectLockedCells() << 10 - | (int) !$this->_phpSheet->getProtection()->getSort() << 11 - | (int) !$this->_phpSheet->getProtection()->getAutoFilter() << 12 - | (int) !$this->_phpSheet->getProtection()->getPivotTables() << 13 - | (int) !$this->_phpSheet->getProtection()->getSelectUnlockedCells() << 14 ; + $options = (int) !$this->phpSheet->getProtection()->getObjects() + | (int) !$this->phpSheet->getProtection()->getScenarios() << 1 + | (int) !$this->phpSheet->getProtection()->getFormatCells() << 2 + | (int) !$this->phpSheet->getProtection()->getFormatColumns() << 3 + | (int) !$this->phpSheet->getProtection()->getFormatRows() << 4 + | (int) !$this->phpSheet->getProtection()->getInsertColumns() << 5 + | (int) !$this->phpSheet->getProtection()->getInsertRows() << 6 + | (int) !$this->phpSheet->getProtection()->getInsertHyperlinks() << 7 + | (int) !$this->phpSheet->getProtection()->getDeleteColumns() << 8 + | (int) !$this->phpSheet->getProtection()->getDeleteRows() << 9 + | (int) !$this->phpSheet->getProtection()->getSelectLockedCells() << 10 + | (int) !$this->phpSheet->getProtection()->getSort() << 11 + | (int) !$this->phpSheet->getProtection()->getAutoFilter() << 12 + | (int) !$this->phpSheet->getProtection()->getPivotTables() << 13 + | (int) !$this->phpSheet->getProtection()->getSelectUnlockedCells() << 14 ; // record data $recordData = pack( @@ -1605,9 +1589,9 @@ private function _writeSheetProtection() * Openoffice.org's Documentaion of the Microsoft Excel File Format uses term RANGEPROTECTION for these records * Microsoft Office Excel 97-2007 Binary File Format Specification uses term FEAT for these records */ - private function _writeRangeProtection() + private function writeRangeProtection() { - foreach ($this->_phpSheet->getProtectedCells() as $range => $password) { + foreach ($this->phpSheet->getProtectedCells() as $range => $password) { // number of ranges, e.g. 'A1:B3 C20:D25' $cellRanges = explode(' ', $range); $cref = count($cellRanges); @@ -1659,7 +1643,7 @@ private function _writeRangeProtection() * * @param integer $count The number of external sheet references in this worksheet */ - private function _writeExterncount($count) + private function writeExterncount($count) { $record = 0x0016; // Record identifier $length = 0x0002; // Number of bytes to follow @@ -1677,14 +1661,14 @@ private function _writeExterncount($count) * * @param string $sheetname The name of a external worksheet */ - private function _writeExternsheet($sheetname) + private function writeExternsheet($sheetname) { $record = 0x0017; // Record identifier // References to the current sheet are encoded differently to references to // external sheets. // - if ($this->_phpSheet->getTitle() == $sheetname) { + if ($this->phpSheet->getTitle() == $sheetname) { $sheetname = ''; $length = 0x02; // The following 2 bytes $cch = 1; // The following byte @@ -1706,10 +1690,10 @@ private function _writeExternsheet($sheetname) * Frozen panes are specified in terms of an integer number of rows and columns. * Thawed panes are specified in terms of Excel's units for rows and columns. */ - private function _writePanes() + private function writePanes() { $panes = array(); - if ($freezePane = $this->_phpSheet->getFreezePane()) { + if ($freezePane = $this->phpSheet->getFreezePane()) { list($column, $row) = PHPExcel_Cell::coordinateFromString($freezePane); $panes[0] = $row - 1; $panes[1] = PHPExcel_Cell::columnIndexFromString($column) - 1; @@ -1731,7 +1715,7 @@ private function _writePanes() $length = 0x000A; // Number of bytes to follow // Code specific to frozen or thawed panes. - if ($this->_phpSheet->getFreezePane()) { + if ($this->phpSheet->getFreezePane()) { // Set default values for $rwTop and $colLeft if (!isset($rwTop)) { $rwTop = $y; @@ -1776,7 +1760,7 @@ private function _writePanes() } } - $this->_active_pane = $pnnAct; // Used in _writeSelection + $this->activePane = $pnnAct; // Used in writeSelection $header = pack("vv", $record, $length); $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); @@ -1786,32 +1770,32 @@ private function _writePanes() /** * Store the page setup SETUP BIFF record. */ - private function _writeSetup() + private function writeSetup() { $record = 0x00A1; // Record identifier $length = 0x0022; // Number of bytes to follow - $iPaperSize = $this->_phpSheet->getPageSetup()->getPaperSize(); // Paper size + $iPaperSize = $this->phpSheet->getPageSetup()->getPaperSize(); // Paper size - $iScale = $this->_phpSheet->getPageSetup()->getScale() ? - $this->_phpSheet->getPageSetup()->getScale() : 100; // Print scaling factor + $iScale = $this->phpSheet->getPageSetup()->getScale() ? + $this->phpSheet->getPageSetup()->getScale() : 100; // Print scaling factor $iPageStart = 0x01; // Starting page number - $iFitWidth = (int) $this->_phpSheet->getPageSetup()->getFitToWidth(); // Fit to number of pages wide - $iFitHeight = (int) $this->_phpSheet->getPageSetup()->getFitToHeight(); // Fit to number of pages high + $iFitWidth = (int) $this->phpSheet->getPageSetup()->getFitToWidth(); // Fit to number of pages wide + $iFitHeight = (int) $this->phpSheet->getPageSetup()->getFitToHeight(); // Fit to number of pages high $grbit = 0x00; // Option flags $iRes = 0x0258; // Print resolution $iVRes = 0x0258; // Vertical print resolution - $numHdr = $this->_phpSheet->getPageMargins()->getHeader(); // Header Margin + $numHdr = $this->phpSheet->getPageMargins()->getHeader(); // Header Margin - $numFtr = $this->_phpSheet->getPageMargins()->getFooter(); // Footer Margin + $numFtr = $this->phpSheet->getPageMargins()->getFooter(); // Footer Margin $iCopies = 0x01; // Number of copies $fLeftToRight = 0x0; // Print over then down // Page orientation - $fLandscape = ($this->_phpSheet->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? + $fLandscape = ($this->phpSheet->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? 0x0 : 0x1; $fNoPls = 0x0; // Setup not read from printer @@ -1847,20 +1831,20 @@ private function _writeSetup() /** * Store the header caption BIFF record. */ - private function _writeHeader() + private function writeHeader() { $record = 0x0014; // Record identifier /* removing for now // need to fix character count (multibyte!) - if (strlen($this->_phpSheet->getHeaderFooter()->getOddHeader()) <= 255) { - $str = $this->_phpSheet->getHeaderFooter()->getOddHeader(); // header string + if (strlen($this->phpSheet->getHeaderFooter()->getOddHeader()) <= 255) { + $str = $this->phpSheet->getHeaderFooter()->getOddHeader(); // header string } else { $str = ''; } */ - $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddHeader()); + $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->phpSheet->getHeaderFooter()->getOddHeader()); $length = strlen($recordData); $header = pack("vv", $record, $length); @@ -1871,20 +1855,20 @@ private function _writeHeader() /** * Store the footer caption BIFF record. */ - private function _writeFooter() + private function writeFooter() { $record = 0x0015; // Record identifier /* removing for now // need to fix character count (multibyte!) - if (strlen($this->_phpSheet->getHeaderFooter()->getOddFooter()) <= 255) { - $str = $this->_phpSheet->getHeaderFooter()->getOddFooter(); + if (strlen($this->phpSheet->getHeaderFooter()->getOddFooter()) <= 255) { + $str = $this->phpSheet->getHeaderFooter()->getOddFooter(); } else { $str = ''; } */ - $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddFooter()); + $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->phpSheet->getHeaderFooter()->getOddFooter()); $length = strlen($recordData); $header = pack("vv", $record, $length); @@ -1897,12 +1881,12 @@ private function _writeFooter() * * @access private */ - private function _writeHcenter() + private function writeHcenter() { $record = 0x0083; // Record identifier $length = 0x0002; // Bytes to follow - $fHCenter = $this->_phpSheet->getPageSetup()->getHorizontalCentered() ? 1 : 0; // Horizontal centering + $fHCenter = $this->phpSheet->getPageSetup()->getHorizontalCentered() ? 1 : 0; // Horizontal centering $header = pack("vv", $record, $length); $data = pack("v", $fHCenter); @@ -1913,12 +1897,12 @@ private function _writeHcenter() /** * Store the vertical centering VCENTER BIFF record. */ - private function _writeVcenter() + private function writeVcenter() { $record = 0x0084; // Record identifier $length = 0x0002; // Bytes to follow - $fVCenter = $this->_phpSheet->getPageSetup()->getVerticalCentered() ? 1 : 0; // Horizontal centering + $fVCenter = $this->phpSheet->getPageSetup()->getVerticalCentered() ? 1 : 0; // Horizontal centering $header = pack("vv", $record, $length); $data = pack("v", $fVCenter); @@ -1933,7 +1917,7 @@ private function writeMarginLeft() $record = 0x0026; // Record identifier $length = 0x0008; // Bytes to follow - $margin = $this->_phpSheet->getPageMargins()->getLeft(); // Margin in inches + $margin = $this->phpSheet->getPageMargins()->getLeft(); // Margin in inches $header = pack("vv", $record, $length); $data = pack("d", $margin); @@ -1952,7 +1936,7 @@ private function writeMarginRight() $record = 0x0027; // Record identifier $length = 0x0008; // Bytes to follow - $margin = $this->_phpSheet->getPageMargins()->getRight(); // Margin in inches + $margin = $this->phpSheet->getPageMargins()->getRight(); // Margin in inches $header = pack("vv", $record, $length); $data = pack("d", $margin); @@ -1971,7 +1955,7 @@ private function writeMarginTop() $record = 0x0028; // Record identifier $length = 0x0008; // Bytes to follow - $margin = $this->_phpSheet->getPageMargins()->getTop(); // Margin in inches + $margin = $this->phpSheet->getPageMargins()->getTop(); // Margin in inches $header = pack("vv", $record, $length); $data = pack("d", $margin); @@ -1990,7 +1974,7 @@ private function writeMarginBottom() $record = 0x0029; // Record identifier $length = 0x0008; // Bytes to follow - $margin = $this->_phpSheet->getPageMargins()->getBottom(); // Margin in inches + $margin = $this->phpSheet->getPageMargins()->getBottom(); // Margin in inches $header = pack("vv", $record, $length); $data = pack("d", $margin); @@ -2004,7 +1988,7 @@ private function writeMarginBottom() /** * Write the PRINTHEADERS BIFF record. */ - private function _writePrintHeaders() + private function writePrintHeaders() { $record = 0x002a; // Record identifier $length = 0x0002; // Bytes to follow @@ -2020,12 +2004,12 @@ private function _writePrintHeaders() * Write the PRINTGRIDLINES BIFF record. Must be used in conjunction with the * GRIDSET record. */ - private function _writePrintGridlines() + private function writePrintGridlines() { $record = 0x002b; // Record identifier $length = 0x0002; // Bytes to follow - $fPrintGrid = $this->_phpSheet->getPrintGridlines() ? 1 : 0; // Boolean flag + $fPrintGrid = $this->phpSheet->getPrintGridlines() ? 1 : 0; // Boolean flag $header = pack("vv", $record, $length); $data = pack("v", $fPrintGrid); @@ -2036,12 +2020,12 @@ private function _writePrintGridlines() * Write the GRIDSET BIFF record. Must be used in conjunction with the * PRINTGRIDLINES record. */ - private function _writeGridset() + private function writeGridset() { $record = 0x0082; // Record identifier $length = 0x0002; // Bytes to follow - $fGridSet = !$this->_phpSheet->getPrintGridlines(); // Boolean flag + $fGridSet = !$this->phpSheet->getPrintGridlines(); // Boolean flag $header = pack("vv", $record, $length); $data = pack("v", $fGridSet); @@ -2051,12 +2035,12 @@ private function _writeGridset() /** * Write the AUTOFILTERINFO BIFF record. This is used to configure the number of autofilter select used in the sheet. */ - private function _writeAutoFilterInfo() + private function writeAutoFilterInfo() { $record = 0x009D; // Record identifier $length = 0x0002; // Bytes to follow - $rangeBounds = PHPExcel_Cell::rangeBoundaries($this->_phpSheet->getAutoFilter()->getRange()); + $rangeBounds = PHPExcel_Cell::rangeBoundaries($this->phpSheet->getAutoFilter()->getRange()); $iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0]; $header = pack("vv", $record, $length); @@ -2069,9 +2053,9 @@ private function _writeAutoFilterInfo() * where Excel outline symbols are displayed. The visibility of the gutters is * controlled by a flag in WSBOOL. * - * @see _writeWsbool() + * @see writeWsbool() */ - private function _writeGuts() + private function writeGuts() { $record = 0x0080; // Record identifier $length = 0x0008; // Bytes to follow @@ -2081,7 +2065,7 @@ private function _writeGuts() // determine maximum row outline level $maxRowOutlineLevel = 0; - foreach ($this->_phpSheet->getRowDimensions() as $rowDimension) { + foreach ($this->phpSheet->getRowDimensions() as $rowDimension) { $maxRowOutlineLevel = max($maxRowOutlineLevel, $rowDimension->getOutlineLevel()); } @@ -2089,9 +2073,9 @@ private function _writeGuts() // Calculate the maximum column outline level. The equivalent calculation // for the row outline level is carried out in writeRow(). - $colcount = count($this->_colinfo); + $colcount = count($this->columnInfo); for ($i = 0; $i < $colcount; ++$i) { - $col_level = max($this->_colinfo[$i][5], $col_level); + $col_level = max($this->columnInfo[$i][5], $col_level); } // Set the limits for the outline levels (0 <= x <= 7). @@ -2115,7 +2099,7 @@ private function _writeGuts() * Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction * with the SETUP record. */ - private function _writeWsbool() + private function writeWsbool() { $record = 0x0081; // Record identifier $length = 0x0002; // Bytes to follow @@ -2126,19 +2110,19 @@ private function _writeWsbool() // // Set the option flags $grbit |= 0x0001; // Auto page breaks visible - if ($this->_outline_style) { + if ($this->outlineStyle) { $grbit |= 0x0020; // Auto outline styles } - if ($this->_phpSheet->getShowSummaryBelow()) { + if ($this->phpSheet->getShowSummaryBelow()) { $grbit |= 0x0040; // Outline summary below } - if ($this->_phpSheet->getShowSummaryRight()) { + if ($this->phpSheet->getShowSummaryRight()) { $grbit |= 0x0080; // Outline summary right } - if ($this->_phpSheet->getPageSetup()->getFitToPage()) { + if ($this->phpSheet->getPageSetup()->getFitToPage()) { $grbit |= 0x0100; // Page setup fit to page } - if ($this->_outline_on) { + if ($this->outlineOn) { $grbit |= 0x0400; // Outline symbols displayed } @@ -2150,13 +2134,13 @@ private function _writeWsbool() /** * Write the HORIZONTALPAGEBREAKS and VERTICALPAGEBREAKS BIFF records. */ - private function _writeBreaks() + private function writeBreaks() { // initialize $vbreaks = array(); $hbreaks = array(); - foreach ($this->_phpSheet->getBreaks() as $cell => $breakType) { + foreach ($this->phpSheet->getBreaks() as $cell => $breakType) { // Fetch coordinates $coordinates = PHPExcel_Cell::coordinateFromString($cell); @@ -2231,10 +2215,10 @@ private function _writeBreaks() /** * Set the Biff PROTECT record to indicate that the worksheet is protected. */ - private function _writeProtect() + private function writeProtect() { // Exit unless sheet protection has been specified - if (!$this->_phpSheet->getProtection()->getSheet()) { + if (!$this->phpSheet->getProtection()->getSheet()) { return; } @@ -2252,15 +2236,15 @@ private function _writeProtect() /** * Write SCENPROTECT */ - private function _writeScenProtect() + private function writeScenProtect() { // Exit if sheet protection is not active - if (!$this->_phpSheet->getProtection()->getSheet()) { + if (!$this->phpSheet->getProtection()->getSheet()) { return; } // Exit if scenarios are not protected - if (!$this->_phpSheet->getProtection()->getScenarios()) { + if (!$this->phpSheet->getProtection()->getScenarios()) { return; } @@ -2276,15 +2260,15 @@ private function _writeScenProtect() /** * Write OBJECTPROTECT */ - private function _writeObjectProtect() + private function writeObjectProtect() { // Exit if sheet protection is not active - if (!$this->_phpSheet->getProtection()->getSheet()) { + if (!$this->phpSheet->getProtection()->getSheet()) { return; } // Exit if objects are not protected - if (!$this->_phpSheet->getProtection()->getObjects()) { + if (!$this->phpSheet->getProtection()->getObjects()) { return; } @@ -2300,17 +2284,17 @@ private function _writeObjectProtect() /** * Write the worksheet PASSWORD record. */ - private function _writePassword() + private function writePassword() { // Exit unless sheet protection and password have been specified - if (!$this->_phpSheet->getProtection()->getSheet() || !$this->_phpSheet->getProtection()->getPassword()) { + if (!$this->phpSheet->getProtection()->getSheet() || !$this->phpSheet->getProtection()->getPassword()) { return; } $record = 0x0013; // Record identifier $length = 0x0002; // Bytes to follow - $wPassword = hexdec($this->_phpSheet->getProtection()->getPassword()); // Encoded password + $wPassword = hexdec($this->phpSheet->getProtection()->getPassword()); // Encoded password $header = pack("vv", $record, $length); $data = pack("v", $wPassword); @@ -2332,15 +2316,15 @@ private function _writePassword() */ public function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) { - $bitmap_array = (is_resource($bitmap) ? $this->_processBitmapGd($bitmap) : $this->_processBitmap($bitmap)); - list($width, $height, $size, $data) = $bitmap_array; //$this->_processBitmap($bitmap); + $bitmap_array = (is_resource($bitmap) ? $this->processBitmapGd($bitmap) : $this->processBitmap($bitmap)); + list($width, $height, $size, $data) = $bitmap_array; //$this->processBitmap($bitmap); // Scale the frame of the image. $width *= $scale_x; $height *= $scale_y; // Calculate the vertices of the image and write the OBJ record - $this->_positionImage($col, $row, $x, $y, $width, $height); + $this->positionImage($col, $row, $x, $y, $width, $height); // Write the IMDATA record to store the bitmap data $record = 0x007f; @@ -2404,17 +2388,17 @@ public function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, * @param integer $width Width of image frame * @param integer $height Height of image frame */ - public function _positionImage($col_start, $row_start, $x1, $y1, $width, $height) + public function positionImage($col_start, $row_start, $x1, $y1, $width, $height) { // Initialise end cell to the same as the start cell $col_end = $col_start; // Col containing lower right corner of object $row_end = $row_start; // Row containing bottom right corner of object // Zero the specified offset if greater than the cell dimensions - if ($x1 >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { + if ($x1 >= PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { $x1 = 0; } - if ($y1 >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1)) { + if ($y1 >= PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_start + 1)) { $y1 = 0; } @@ -2422,40 +2406,40 @@ public function _positionImage($col_start, $row_start, $x1, $y1, $width, $height $height = $height + $y1 -1; // Subtract the underlying cell widths to find the end cell of the image - while ($width >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { - $width -= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); + while ($width >= PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { + $width -= PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); ++$col_end; } // Subtract the underlying cell heights to find the end cell of the image - while ($height >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1)) { - $height -= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1); + while ($height >= PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_end + 1)) { + $height -= PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_end + 1); ++$row_end; } // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell // with zero eight or width. // - if (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { + if (PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { return; } - if (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { + if (PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { return; } - if (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) == 0) { + if (PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_start + 1) == 0) { return; } - if (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) == 0) { + if (PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_end + 1) == 0) { return; } // Convert the pixel values to the percentage value expected by Excel - $x1 = $x1 / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; - $y1 = $y1 / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) * 256; - $x2 = $width / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object - $y2 = $height / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) * 256; // Distance to bottom of object + $x1 = $x1 / PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; + $y1 = $y1 / PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_start + 1) * 256; + $x2 = $width / PHPExcel_Shared_Excel5::sizeCol($this->phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object + $y2 = $height / PHPExcel_Shared_Excel5::sizeRow($this->phpSheet, $row_end + 1) * 256; // Distance to bottom of object - $this->_writeObjPicture($col_start, $x1, $row_start, $y1, $col_end, $x2, $row_end, $y2); + $this->writeObjPicture($col_start, $x1, $row_start, $y1, $col_end, $x2, $row_end, $y2); } /** @@ -2471,7 +2455,7 @@ public function _positionImage($col_start, $row_start, $x1, $y1, $width, $height * @param integer $rwB Row containing bottom right corner of object * @param integer $dyB Distance from bottom of cell */ - private function _writeObjPicture($colL, $dxL, $rwT, $dyT, $colR, $dxR, $rwB, $dyB) + private function writeObjPicture($colL, $dxL, $rwT, $dyT, $colR, $dxR, $rwB, $dyB) { $record = 0x005d; // Record identifier $length = 0x003c; // Bytes to follow @@ -2544,7 +2528,7 @@ private function _writeObjPicture($colL, $dxL, $rwT, $dyT, $colR, $dxR, $rwB, $d * @param resource $image The image to process * @return array Array with data and properties of the bitmap */ - public function _processBitmapGd($image) + public function processBitmapGd($image) { $width = imagesx($image); $height = imagesy($image); @@ -2575,7 +2559,7 @@ public function _processBitmapGd($image) * @param string $bitmap The bitmap to process * @return array Array with data and properties of the bitmap */ - public function _processBitmap($bitmap) + public function processBitmap($bitmap) { // Open file. $bmp_fd = @fopen($bitmap, "rb"); @@ -2657,10 +2641,10 @@ public function _processBitmap($bitmap) * Store the window zoom factor. This should be a reduced fraction but for * simplicity we will store all fractions with a numerator of 100. */ - private function _writeZoom() + private function writeZoom() { // If scale is 100 we don't need to write a record - if ($this->_phpSheet->getSheetView()->getZoomScale() == 100) { + if ($this->phpSheet->getSheetView()->getZoomScale() == 100) { return; } @@ -2668,7 +2652,7 @@ private function _writeZoom() $length = 0x0004; // Bytes to follow $header = pack("vv", $record, $length); - $data = pack("vv", $this->_phpSheet->getSheetView()->getZoomScale(), 100); + $data = pack("vv", $this->phpSheet->getSheetView()->getZoomScale(), 100); $this->append($header . $data); } @@ -2783,7 +2767,7 @@ private function writeMsoDrawing() private function writeDataValidity() { // Datavalidation collection - $dataValidationCollection = $this->_phpSheet->getDataValidationCollection(); + $dataValidationCollection = $this->phpSheet->getDataValidationCollection(); // Write data validations? if (!empty($dataValidationCollection)) { @@ -3007,10 +2991,10 @@ private function writePageLayoutView() $rt = 0x088B; // 2 $grbitFrt = 0x0000; // 2 $reserved = 0x0000000000000000; // 8 - $wScalvePLV = $this->_phpSheet->getSheetView()->getZoomScale(); // 2 + $wScalvePLV = $this->phpSheet->getSheetView()->getZoomScale(); // 2 // The options flags that comprise $grbit - if ($this->_phpSheet->getSheetView()->getView() == PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { + if ($this->phpSheet->getSheetView()->getView() == PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { $fPageLayoutView = 1; } else { $fPageLayoutView = 0; @@ -4216,7 +4200,7 @@ private function writeCFHeader() $numRowMin = null; $numRowMax = null; $arrConditional = array(); - foreach ($this->_phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { + foreach ($this->phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { foreach ($conditionalStyles as $conditional) { if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS) { From 003c25980193e14b08ecdfc3bf6d1b43ba877900 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sat, 23 May 2015 23:41:38 +0100 Subject: [PATCH 399/467] Modifying a few constants to psr-2 standards --- Classes/PHPExcel/Reader/Excel5.php | 324 +++++++++--------- Classes/PHPExcel/Reader/Excel5/MD5.php | 16 +- .../Shared/JAMA/CholeskyDecomposition.php | 6 +- .../PHPExcel/Shared/JAMA/LUDecomposition.php | 14 +- Classes/PHPExcel/Shared/JAMA/Matrix.php | 130 +++---- .../PHPExcel/Shared/JAMA/QRDecomposition.php | 10 +- Classes/PHPExcel/Shared/JAMA/utils/Error.php | 82 ++--- Classes/PHPExcel/Shared/JAMA/utils/Maths.php | 2 +- 8 files changed, 292 insertions(+), 292 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 50cc87e39..498e98521 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -74,80 +74,80 @@ class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExce const XLS_Worksheet = 0x0010; // record identifiers - const XLS_Type_FORMULA = 0x0006; - const XLS_Type_EOF = 0x000a; - const XLS_Type_PROTECT = 0x0012; - const XLS_Type_OBJECTPROTECT = 0x0063; - const XLS_Type_SCENPROTECT = 0x00dd; - const XLS_Type_PASSWORD = 0x0013; - const XLS_Type_HEADER = 0x0014; - const XLS_Type_FOOTER = 0x0015; - const XLS_Type_EXTERNSHEET = 0x0017; - const XLS_Type_DEFINEDNAME = 0x0018; - const XLS_Type_VERTICALPAGEBREAKS = 0x001a; - const XLS_Type_HORIZONTALPAGEBREAKS = 0x001b; - const XLS_Type_NOTE = 0x001c; - const XLS_Type_SELECTION = 0x001d; - const XLS_Type_DATEMODE = 0x0022; - const XLS_Type_EXTERNNAME = 0x0023; - const XLS_Type_LEFTMARGIN = 0x0026; - const XLS_Type_RIGHTMARGIN = 0x0027; - const XLS_Type_TOPMARGIN = 0x0028; - const XLS_Type_BOTTOMMARGIN = 0x0029; - const XLS_Type_PRINTGRIDLINES = 0x002b; - const XLS_Type_FILEPASS = 0x002f; - const XLS_Type_FONT = 0x0031; - const XLS_Type_CONTINUE = 0x003c; - const XLS_Type_PANE = 0x0041; - const XLS_Type_CODEPAGE = 0x0042; - const XLS_Type_DEFCOLWIDTH = 0x0055; - const XLS_Type_OBJ = 0x005d; - const XLS_Type_COLINFO = 0x007d; - const XLS_Type_IMDATA = 0x007f; - const XLS_Type_SHEETPR = 0x0081; - const XLS_Type_HCENTER = 0x0083; - const XLS_Type_VCENTER = 0x0084; - const XLS_Type_SHEET = 0x0085; - const XLS_Type_PALETTE = 0x0092; - const XLS_Type_SCL = 0x00a0; - const XLS_Type_PAGESETUP = 0x00a1; - const XLS_Type_MULRK = 0x00bd; - const XLS_Type_MULBLANK = 0x00be; - const XLS_Type_DBCELL = 0x00d7; - const XLS_Type_XF = 0x00e0; - const XLS_Type_MERGEDCELLS = 0x00e5; - const XLS_Type_MSODRAWINGGROUP = 0x00eb; - const XLS_Type_MSODRAWING = 0x00ec; - const XLS_Type_SST = 0x00fc; - const XLS_Type_LABELSST = 0x00fd; - const XLS_Type_EXTSST = 0x00ff; - const XLS_Type_EXTERNALBOOK = 0x01ae; - const XLS_Type_DATAVALIDATIONS = 0x01b2; - const XLS_Type_TXO = 0x01b6; - const XLS_Type_HYPERLINK = 0x01b8; - const XLS_Type_DATAVALIDATION = 0x01be; - const XLS_Type_DIMENSION = 0x0200; - const XLS_Type_BLANK = 0x0201; - const XLS_Type_NUMBER = 0x0203; - const XLS_Type_LABEL = 0x0204; - const XLS_Type_BOOLERR = 0x0205; - const XLS_Type_STRING = 0x0207; - const XLS_Type_ROW = 0x0208; - const XLS_Type_INDEX = 0x020b; - const XLS_Type_ARRAY = 0x0221; - const XLS_Type_DEFAULTROWHEIGHT = 0x0225; - const XLS_Type_WINDOW2 = 0x023e; - const XLS_Type_RK = 0x027e; - const XLS_Type_STYLE = 0x0293; - const XLS_Type_FORMAT = 0x041e; - const XLS_Type_SHAREDFMLA = 0x04bc; - const XLS_Type_BOF = 0x0809; - const XLS_Type_SHEETPROTECTION = 0x0867; - const XLS_Type_RANGEPROTECTION = 0x0868; - const XLS_Type_SHEETLAYOUT = 0x0862; - const XLS_Type_XFEXT = 0x087d; - const XLS_Type_PAGELAYOUTVIEW = 0x088b; - const XLS_Type_UNKNOWN = 0xffff; + const XLS_TYPE_FORMULA = 0x0006; + const XLS_TYPE_EOF = 0x000a; + const XLS_TYPE_PROTECT = 0x0012; + const XLS_TYPE_OBJECTPROTECT = 0x0063; + const XLS_TYPE_SCENPROTECT = 0x00dd; + const XLS_TYPE_PASSWORD = 0x0013; + const XLS_TYPE_HEADER = 0x0014; + const XLS_TYPE_FOOTER = 0x0015; + const XLS_TYPE_EXTERNSHEET = 0x0017; + const XLS_TYPE_DEFINEDNAME = 0x0018; + const XLS_TYPE_VERTICALPAGEBREAKS = 0x001a; + const XLS_TYPE_HORIZONTALPAGEBREAKS = 0x001b; + const XLS_TYPE_NOTE = 0x001c; + const XLS_TYPE_SELECTION = 0x001d; + const XLS_TYPE_DATEMODE = 0x0022; + const XLS_TYPE_EXTERNNAME = 0x0023; + const XLS_TYPE_LEFTMARGIN = 0x0026; + const XLS_TYPE_RIGHTMARGIN = 0x0027; + const XLS_TYPE_TOPMARGIN = 0x0028; + const XLS_TYPE_BOTTOMMARGIN = 0x0029; + const XLS_TYPE_PRINTGRIDLINES = 0x002b; + const XLS_TYPE_FILEPASS = 0x002f; + const XLS_TYPE_FONT = 0x0031; + const XLS_TYPE_CONTINUE = 0x003c; + const XLS_TYPE_PANE = 0x0041; + const XLS_TYPE_CODEPAGE = 0x0042; + const XLS_TYPE_DEFCOLWIDTH = 0x0055; + const XLS_TYPE_OBJ = 0x005d; + const XLS_TYPE_COLINFO = 0x007d; + const XLS_TYPE_IMDATA = 0x007f; + const XLS_TYPE_SHEETPR = 0x0081; + const XLS_TYPE_HCENTER = 0x0083; + const XLS_TYPE_VCENTER = 0x0084; + const XLS_TYPE_SHEET = 0x0085; + const XLS_TYPE_PALETTE = 0x0092; + const XLS_TYPE_SCL = 0x00a0; + const XLS_TYPE_PAGESETUP = 0x00a1; + const XLS_TYPE_MULRK = 0x00bd; + const XLS_TYPE_MULBLANK = 0x00be; + const XLS_TYPE_DBCELL = 0x00d7; + const XLS_TYPE_XF = 0x00e0; + const XLS_TYPE_MERGEDCELLS = 0x00e5; + const XLS_TYPE_MSODRAWINGGROUP = 0x00eb; + const XLS_TYPE_MSODRAWING = 0x00ec; + const XLS_TYPE_SST = 0x00fc; + const XLS_TYPE_LABELSST = 0x00fd; + const XLS_TYPE_EXTSST = 0x00ff; + const XLS_TYPE_EXTERNALBOOK = 0x01ae; + const XLS_TYPE_DATAVALIDATIONS = 0x01b2; + const XLS_TYPE_TXO = 0x01b6; + const XLS_TYPE_HYPERLINK = 0x01b8; + const XLS_TYPE_DATAVALIDATION = 0x01be; + const XLS_TYPE_DIMENSION = 0x0200; + const XLS_TYPE_BLANK = 0x0201; + const XLS_TYPE_NUMBER = 0x0203; + const XLS_TYPE_LABEL = 0x0204; + const XLS_TYPE_BOOLERR = 0x0205; + const XLS_TYPE_STRING = 0x0207; + const XLS_TYPE_ROW = 0x0208; + const XLS_TYPE_INDEX = 0x020b; + const XLS_TYPE_ARRAY = 0x0221; + const XLS_TYPE_DEFAULTROWHEIGHT = 0x0225; + const XLS_TYPE_WINDOW2 = 0x023e; + const XLS_TYPE_RK = 0x027e; + const XLS_TYPE_STYLE = 0x0293; + const XLS_TYPE_FORMAT = 0x041e; + const XLS_TYPE_SHAREDFMLA = 0x04bc; + const XLS_TYPE_BOF = 0x0809; + const XLS_TYPE_SHEETPROTECTION = 0x0867; + const XLS_TYPE_RANGEPROTECTION = 0x0868; + const XLS_TYPE_SHEETLAYOUT = 0x0862; + const XLS_TYPE_XFEXT = 0x087d; + const XLS_TYPE_PAGELAYOUTVIEW = 0x088b; + const XLS_TYPE_UNKNOWN = 0xffff; // Encryption type const MS_BIFF_CRYPTO_NONE = 0; @@ -474,13 +474,13 @@ public function listWorksheetNames($pFilename) $code = self::getInt2d($this->data, $this->pos); switch ($code) { - case self::XLS_Type_BOF: + case self::XLS_TYPE_BOF: $this->readBof(); break; - case self::XLS_Type_SHEET: + case self::XLS_TYPE_SHEET: $this->readSheet(); break; - case self::XLS_Type_EOF: + case self::XLS_TYPE_EOF: $this->readDefault(); break 2; default: @@ -532,13 +532,13 @@ public function listWorksheetInfo($pFilename) $code = self::getInt2d($this->data, $this->pos); switch ($code) { - case self::XLS_Type_BOF: + case self::XLS_TYPE_BOF: $this->readBof(); break; - case self::XLS_Type_SHEET: + case self::XLS_TYPE_SHEET: $this->readSheet(); break; - case self::XLS_Type_EOF: + case self::XLS_TYPE_EOF: $this->readDefault(); break 2; default: @@ -569,12 +569,12 @@ public function listWorksheetInfo($pFilename) $code = self::getInt2d($this->data, $this->pos); switch ($code) { - case self::XLS_Type_RK: - case self::XLS_Type_LABELSST: - case self::XLS_Type_NUMBER: - case self::XLS_Type_FORMULA: - case self::XLS_Type_BOOLERR: - case self::XLS_Type_LABEL: + case self::XLS_TYPE_RK: + case self::XLS_TYPE_LABELSST: + case self::XLS_TYPE_NUMBER: + case self::XLS_TYPE_FORMULA: + case self::XLS_TYPE_BOOLERR: + case self::XLS_TYPE_LABEL: $length = self::getInt2d($this->data, $this->pos + 2); $recordData = $this->readRecordData($this->data, $this->pos + 4, $length); @@ -587,10 +587,10 @@ public function listWorksheetInfo($pFilename) $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); break; - case self::XLS_Type_BOF: + case self::XLS_TYPE_BOF: $this->readBof(); break; - case self::XLS_Type_EOF: + case self::XLS_TYPE_EOF: $this->readDefault(); break 2; default: @@ -659,58 +659,58 @@ public function load($pFilename) $code = self::getInt2d($this->data, $this->pos); switch ($code) { - case self::XLS_Type_BOF: + case self::XLS_TYPE_BOF: $this->readBof(); break; - case self::XLS_Type_FILEPASS: + case self::XLS_TYPE_FILEPASS: $this->readFilepass(); break; - case self::XLS_Type_CODEPAGE: + case self::XLS_TYPE_CODEPAGE: $this->readCodepage(); break; - case self::XLS_Type_DATEMODE: + case self::XLS_TYPE_DATEMODE: $this->readDateMode(); break; - case self::XLS_Type_FONT: + case self::XLS_TYPE_FONT: $this->readFont(); break; - case self::XLS_Type_FORMAT: + case self::XLS_TYPE_FORMAT: $this->readFormat(); break; - case self::XLS_Type_XF: + case self::XLS_TYPE_XF: $this->readXf(); break; - case self::XLS_Type_XFEXT: + case self::XLS_TYPE_XFEXT: $this->readXfExt(); break; - case self::XLS_Type_STYLE: + case self::XLS_TYPE_STYLE: $this->readStyle(); break; - case self::XLS_Type_PALETTE: + case self::XLS_TYPE_PALETTE: $this->readPalette(); break; - case self::XLS_Type_SHEET: + case self::XLS_TYPE_SHEET: $this->readSheet(); break; - case self::XLS_Type_EXTERNALBOOK: + case self::XLS_TYPE_EXTERNALBOOK: $this->readExternalBook(); break; - case self::XLS_Type_EXTERNNAME: + case self::XLS_TYPE_EXTERNNAME: $this->readExternName(); break; - case self::XLS_Type_EXTERNSHEET: + case self::XLS_TYPE_EXTERNSHEET: $this->readExternSheet(); break; - case self::XLS_Type_DEFINEDNAME: + case self::XLS_TYPE_DEFINEDNAME: $this->readDefinedName(); break; - case self::XLS_Type_MSODRAWINGGROUP: + case self::XLS_TYPE_MSODRAWINGGROUP: $this->readMsoDrawingGroup(); break; - case self::XLS_Type_SST: + case self::XLS_TYPE_SST: $this->readSst(); break; - case self::XLS_Type_EOF: + case self::XLS_TYPE_EOF: $this->readDefault(); break 2; default: @@ -831,161 +831,161 @@ public function load($pFilename) $code = self::getInt2d($this->data, $this->pos); switch ($code) { - case self::XLS_Type_BOF: + case self::XLS_TYPE_BOF: $this->readBof(); break; - case self::XLS_Type_PRINTGRIDLINES: + case self::XLS_TYPE_PRINTGRIDLINES: $this->readPrintGridlines(); break; - case self::XLS_Type_DEFAULTROWHEIGHT: + case self::XLS_TYPE_DEFAULTROWHEIGHT: $this->readDefaultRowHeight(); break; - case self::XLS_Type_SHEETPR: + case self::XLS_TYPE_SHEETPR: $this->readSheetPr(); break; - case self::XLS_Type_HORIZONTALPAGEBREAKS: + case self::XLS_TYPE_HORIZONTALPAGEBREAKS: $this->readHorizontalPageBreaks(); break; - case self::XLS_Type_VERTICALPAGEBREAKS: + case self::XLS_TYPE_VERTICALPAGEBREAKS: $this->readVerticalPageBreaks(); break; - case self::XLS_Type_HEADER: + case self::XLS_TYPE_HEADER: $this->readHeader(); break; - case self::XLS_Type_FOOTER: + case self::XLS_TYPE_FOOTER: $this->readFooter(); break; - case self::XLS_Type_HCENTER: + case self::XLS_TYPE_HCENTER: $this->readHcenter(); break; - case self::XLS_Type_VCENTER: + case self::XLS_TYPE_VCENTER: $this->readVcenter(); break; - case self::XLS_Type_LEFTMARGIN: + case self::XLS_TYPE_LEFTMARGIN: $this->readLeftMargin(); break; - case self::XLS_Type_RIGHTMARGIN: + case self::XLS_TYPE_RIGHTMARGIN: $this->readRightMargin(); break; - case self::XLS_Type_TOPMARGIN: + case self::XLS_TYPE_TOPMARGIN: $this->readTopMargin(); break; - case self::XLS_Type_BOTTOMMARGIN: + case self::XLS_TYPE_BOTTOMMARGIN: $this->readBottomMargin(); break; - case self::XLS_Type_PAGESETUP: + case self::XLS_TYPE_PAGESETUP: $this->readPageSetup(); break; - case self::XLS_Type_PROTECT: + case self::XLS_TYPE_PROTECT: $this->readProtect(); break; - case self::XLS_Type_SCENPROTECT: + case self::XLS_TYPE_SCENPROTECT: $this->readScenProtect(); break; - case self::XLS_Type_OBJECTPROTECT: + case self::XLS_TYPE_OBJECTPROTECT: $this->readObjectProtect(); break; - case self::XLS_Type_PASSWORD: + case self::XLS_TYPE_PASSWORD: $this->readPassword(); break; - case self::XLS_Type_DEFCOLWIDTH: + case self::XLS_TYPE_DEFCOLWIDTH: $this->readDefColWidth(); break; - case self::XLS_Type_COLINFO: + case self::XLS_TYPE_COLINFO: $this->readColInfo(); break; - case self::XLS_Type_DIMENSION: + case self::XLS_TYPE_DIMENSION: $this->readDefault(); break; - case self::XLS_Type_ROW: + case self::XLS_TYPE_ROW: $this->readRow(); break; - case self::XLS_Type_DBCELL: + case self::XLS_TYPE_DBCELL: $this->readDefault(); break; - case self::XLS_Type_RK: + case self::XLS_TYPE_RK: $this->readRk(); break; - case self::XLS_Type_LABELSST: + case self::XLS_TYPE_LABELSST: $this->readLabelSst(); break; - case self::XLS_Type_MULRK: + case self::XLS_TYPE_MULRK: $this->readMulRk(); break; - case self::XLS_Type_NUMBER: + case self::XLS_TYPE_NUMBER: $this->readNumber(); break; - case self::XLS_Type_FORMULA: + case self::XLS_TYPE_FORMULA: $this->readFormula(); break; - case self::XLS_Type_SHAREDFMLA: + case self::XLS_TYPE_SHAREDFMLA: $this->readSharedFmla(); break; - case self::XLS_Type_BOOLERR: + case self::XLS_TYPE_BOOLERR: $this->readBoolErr(); break; - case self::XLS_Type_MULBLANK: + case self::XLS_TYPE_MULBLANK: $this->readMulBlank(); break; - case self::XLS_Type_LABEL: + case self::XLS_TYPE_LABEL: $this->readLabel(); break; - case self::XLS_Type_BLANK: + case self::XLS_TYPE_BLANK: $this->readBlank(); break; - case self::XLS_Type_MSODRAWING: + case self::XLS_TYPE_MSODRAWING: $this->readMsoDrawing(); break; - case self::XLS_Type_OBJ: + case self::XLS_TYPE_OBJ: $this->readObj(); break; - case self::XLS_Type_WINDOW2: + case self::XLS_TYPE_WINDOW2: $this->readWindow2(); break; - case self::XLS_Type_PAGELAYOUTVIEW: + case self::XLS_TYPE_PAGELAYOUTVIEW: $this->readPageLayoutView(); break; - case self::XLS_Type_SCL: + case self::XLS_TYPE_SCL: $this->readScl(); break; - case self::XLS_Type_PANE: + case self::XLS_TYPE_PANE: $this->readPane(); break; - case self::XLS_Type_SELECTION: + case self::XLS_TYPE_SELECTION: $this->readSelection(); break; - case self::XLS_Type_MERGEDCELLS: + case self::XLS_TYPE_MERGEDCELLS: $this->readMergedCells(); break; - case self::XLS_Type_HYPERLINK: + case self::XLS_TYPE_HYPERLINK: $this->readHyperLink(); break; - case self::XLS_Type_DATAVALIDATIONS: + case self::XLS_TYPE_DATAVALIDATIONS: $this->readDataValidations(); break; - case self::XLS_Type_DATAVALIDATION: + case self::XLS_TYPE_DATAVALIDATION: $this->readDataValidation(); break; - case self::XLS_Type_SHEETLAYOUT: + case self::XLS_TYPE_SHEETLAYOUT: $this->readSheetLayout(); break; - case self::XLS_Type_SHEETPROTECTION: + case self::XLS_TYPE_SHEETPROTECTION: $this->readSheetProtection(); break; - case self::XLS_Type_RANGEPROTECTION: + case self::XLS_TYPE_RANGEPROTECTION: $this->readRangeProtection(); break; - case self::XLS_Type_NOTE: + case self::XLS_TYPE_NOTE: $this->readNote(); break; - //case self::XLS_Type_IMDATA: $this->readImData(); break; - case self::XLS_Type_TXO: + //case self::XLS_TYPE_IMDATA: $this->readImData(); break; + case self::XLS_TYPE_TXO: $this->readTextObject(); break; - case self::XLS_Type_CONTINUE: + case self::XLS_TYPE_CONTINUE: $this->readContinue(); break; - case self::XLS_Type_EOF: + case self::XLS_TYPE_EOF: $this->readDefault(); break 2; default: @@ -1720,7 +1720,7 @@ private function readBof() do { $code = self::getInt2d($this->data, $this->pos); $this->readDefault(); - } while ($code != self::XLS_Type_EOF && $this->pos < $this->dataSize); + } while ($code != self::XLS_TYPE_EOF && $this->pos < $this->dataSize); break; } } @@ -3905,7 +3905,7 @@ private function readFormula() // read possible SHAREDFMLA record $code = self::getInt2d($this->data, $this->pos); - if ($code == self::XLS_Type_SHAREDFMLA) { + if ($code == self::XLS_TYPE_SHAREDFMLA) { $this->readSharedFmla(); } @@ -5260,7 +5260,7 @@ private function getSplicedRecordData() $this->pos += 4 + $length; $nextIdentifier = self::getInt2d($this->data, $this->pos); - } while ($nextIdentifier == self::XLS_Type_CONTINUE); + } while ($nextIdentifier == self::XLS_TYPE_CONTINUE); $splicedData = array( 'recordData' => $data, diff --git a/Classes/PHPExcel/Reader/Excel5/MD5.php b/Classes/PHPExcel/Reader/Excel5/MD5.php index 1141d43a1..f14ea9469 100644 --- a/Classes/PHPExcel/Reader/Excel5/MD5.php +++ b/Classes/PHPExcel/Reader/Excel5/MD5.php @@ -85,10 +85,10 @@ public function add($data) $C = $this->c; $D = $this->d; - $F = array('PHPExcel_Reader_Excel5_MD5','F'); - $G = array('PHPExcel_Reader_Excel5_MD5','G'); - $H = array('PHPExcel_Reader_Excel5_MD5','H'); - $I = array('PHPExcel_Reader_Excel5_MD5','I'); + $F = array('PHPExcel_Reader_Excel5_MD5','f'); + $G = array('PHPExcel_Reader_Excel5_MD5','g'); + $H = array('PHPExcel_Reader_Excel5_MD5','h'); + $I = array('PHPExcel_Reader_Excel5_MD5','i'); /* ROUND 1 */ self::step($F, $A, $B, $C, $D, $words[0], 7, 0xd76aa478); @@ -168,22 +168,22 @@ public function add($data) $this->d = ($this->d + $D) & 0xffffffff; } - private static function F($X, $Y, $Z) + private static function f($X, $Y, $Z) { return (($X & $Y) | ((~ $X) & $Z)); // X AND Y OR NOT X AND Z } - private static function G($X, $Y, $Z) + private static function g($X, $Y, $Z) { return (($X & $Z) | ($Y & (~ $Z))); // X AND Z OR Y AND NOT Z } - private static function H($X, $Y, $Z) + private static function h($X, $Y, $Z) { return ($X ^ $Y ^ $Z); // X XOR Y XOR Z } - private static function I($X, $Y, $Z) + private static function i($X, $Y, $Z) { return ($Y ^ ($X | (~ $Z))) ; // Y XOR (X OR NOT Z) } diff --git a/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php b/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php index 4b73e077a..d68109b31 100644 --- a/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php @@ -73,7 +73,7 @@ public function __construct($A = null) } } } else { - throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + throw new PHPExcel_Calculation_Exception(JAMAError(ARGUMENT_TYPE_EXCEPTION)); } } // function __construct() @@ -139,10 +139,10 @@ public function solve($B = null) throw new PHPExcel_Calculation_Exception(JAMAError(MatrixSPDException)); } } else { - throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionException)); + throw new PHPExcel_Calculation_Exception(JAMAError(MATRIX_DIMENSION_EXCEPTION)); } } else { - throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + throw new PHPExcel_Calculation_Exception(JAMAError(ARGUMENT_TYPE_EXCEPTION)); } } // function solve() } diff --git a/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php b/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php index 64290fe7e..2505d9226 100644 --- a/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php @@ -20,8 +20,8 @@ */ class PHPExcel_Shared_JAMA_LUDecomposition { - const MatrixSingularException = "Can only perform operation on singular matrix."; - const MatrixSquareException = "Mismatched Row dimension"; + const MATRIX_SINGULAR_EXCEPTION = "Can only perform operation on singular matrix."; + const MATRIX_SQUARE_EXCEPTION = "Mismatched Row dimension"; /** * Decomposition storage @@ -115,7 +115,7 @@ public function __construct($A) } } } else { - throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ARGUMENT_TYPE_EXCEPTION); } } // function __construct() @@ -208,7 +208,7 @@ public function det() } return $d; } else { - throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MATRIX_DIMENSION_EXCEPTION); } } // function det() @@ -248,10 +248,10 @@ public function solve($B) } return $X; } else { - throw new PHPExcel_Calculation_Exception(self::MatrixSingularException); + throw new PHPExcel_Calculation_Exception(self::MATRIX_SINGULAR_EXCEPTION); } } else { - throw new PHPExcel_Calculation_Exception(self::MatrixSquareException); + throw new PHPExcel_Calculation_Exception(self::MATRIX_SQUARE_EXCEPTION); } - } // function solve() + } } diff --git a/Classes/PHPExcel/Shared/JAMA/Matrix.php b/Classes/PHPExcel/Shared/JAMA/Matrix.php index 83668b0f4..82fb0fb20 100644 --- a/Classes/PHPExcel/Shared/JAMA/Matrix.php +++ b/Classes/PHPExcel/Shared/JAMA/Matrix.php @@ -26,11 +26,11 @@ */ class PHPExcel_Shared_JAMA_Matrix { - const PolymorphicArgumentException = "Invalid argument pattern for polymorphic function."; - const ArgumentTypeException = "Invalid argument type."; - const ArgumentBoundsException = "Invalid argument range."; - const MatrixDimensionException = "Matrix dimensions are not equal."; - const ArrayLengthException = "Array length must be a multiple of m."; + const POLYMORPHIC_ARGUMENT_EXCEPTION = "Invalid argument pattern for polymorphic function."; + const ARGUMENT_TYPE_EXCEPTION = "Invalid argument type."; + const ARGUMENT_BOUNDS_EXCEPTION = "Invalid argument range."; + const MATRIX_DIMENSION_EXCEPTION = "Matrix dimensions are not equal."; + const ARRAY_LENGTH_EXCEPTION = "Array length must be a multiple of m."; /** * Matrix storage @@ -101,15 +101,15 @@ public function __construct() } } } else { - throw new PHPExcel_Calculation_Exception(self::ArrayLengthException); + throw new PHPExcel_Calculation_Exception(self::ARRAY_LENGTH_EXCEPTION); } break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -179,12 +179,12 @@ public function getMatrix() if ($i0 >= 0) { $m = $this->m - $i0; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } if ($j0 >= 0) { $n = $this->n - $j0; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); for ($i = $i0; $i < $this->m; ++$i) { @@ -200,12 +200,12 @@ public function getMatrix() if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } $R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1); for ($i = $i0; $i <= $iF; ++$i) { @@ -221,12 +221,12 @@ public function getMatrix() if (count($RL) > 0) { $m = count($RL); } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } if (count($CL) > 0) { $n = count($CL); } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); for ($i = 0; $i < $m; ++$i) { @@ -242,12 +242,12 @@ public function getMatrix() if (count($RL) > 0) { $m = count($RL); } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } if (count($CL) > 0) { $n = count($CL); } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); for ($i = 0; $i < $m; ++$i) { @@ -263,12 +263,12 @@ public function getMatrix() if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } if (count($CL) > 0) { $n = count($CL); } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); for ($i = $i0; $i < $iF; ++$i) { @@ -284,12 +284,12 @@ public function getMatrix() if (count($RL) > 0) { $m = count($RL); } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_BOUNDS_EXCEPTION); } $R = new PHPExcel_Shared_JAMA_Matrix($m, $n+1); for ($i = 0; $i < $m; ++$i) { @@ -300,11 +300,11 @@ public function getMatrix() return $R; break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -321,10 +321,10 @@ public function checkMatrixDimensions($B = null) if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) { return true; } else { - throw new PHPExcel_Calculation_Exception(self::MatrixDimensionException); + throw new PHPExcel_Calculation_Exception(self::MATRIX_DIMENSION_EXCEPTION); } } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } } // function checkMatrixDimensions() @@ -391,7 +391,7 @@ public function getMatrixByRow($i0 = null, $iF = null) return $this->getMatrix($i0, 0, $i0 + 1, $this->n); } } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } } @@ -412,7 +412,7 @@ public function getMatrixByCol($j0 = null, $jF = null) return $this->getMatrix(0, $j0, $this->m, $j0 + 1); } } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } } @@ -477,14 +477,14 @@ public function plus() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -495,7 +495,7 @@ public function plus() } return $M; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -517,14 +517,14 @@ public function plusEquals() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -549,7 +549,7 @@ public function plusEquals() } return $this; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -571,14 +571,14 @@ public function minus() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -589,7 +589,7 @@ public function minus() } return $M; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -611,14 +611,14 @@ public function minusEquals() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -643,7 +643,7 @@ public function minusEquals() } return $this; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -666,14 +666,14 @@ public function arrayTimes() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -684,7 +684,7 @@ public function arrayTimes() } return $M; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -707,14 +707,14 @@ public function arrayTimesEquals() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -739,7 +739,7 @@ public function arrayTimesEquals() } return $this; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -762,14 +762,14 @@ public function arrayRightDivide() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -799,7 +799,7 @@ public function arrayRightDivide() } return $M; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -823,14 +823,14 @@ public function arrayRightDivideEquals() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -841,7 +841,7 @@ public function arrayRightDivideEquals() } return $M; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -865,14 +865,14 @@ public function arrayLeftDivide() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -883,7 +883,7 @@ public function arrayLeftDivide() } return $M; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -907,14 +907,14 @@ public function arrayLeftDivideEquals() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -925,7 +925,7 @@ public function arrayLeftDivideEquals() } return $M; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -948,7 +948,7 @@ public function times() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $B = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } if ($this->n == $B->m) { $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); @@ -1017,11 +1017,11 @@ public function times() return $C; break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -1043,14 +1043,14 @@ public function power() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } break; case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -1075,7 +1075,7 @@ public function power() } return $this; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } @@ -1097,13 +1097,13 @@ public function concat() if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { - throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(self::ARGUMENT_TYPE_EXCEPTION); } case 'array': $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); break; default: - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); break; } $this->checkMatrixDimensions($M); @@ -1114,7 +1114,7 @@ public function concat() } return $this; } else { - throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + throw new PHPExcel_Calculation_Exception(self::POLYMORPHIC_ARGUMENT_EXCEPTION); } } diff --git a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php index b20e5a073..1e43c7c43 100644 --- a/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php +++ b/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php @@ -18,7 +18,7 @@ */ class PHPExcel_Shared_JAMA_QRDecomposition { - const MatrixRankException = "Can only perform operation on full-rank matrix."; + const MATRIX_RANK_EXCEPTION = "Can only perform operation on full-rank matrix."; /** * Array for internal storage of decomposition. @@ -89,7 +89,7 @@ public function __construct($A) $this->Rdiag[$k] = -$nrm; } } else { - throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException); + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ARGUMENT_TYPE_EXCEPTION); } } // function __construct() @@ -226,10 +226,10 @@ public function solve($B) $X = new PHPExcel_Shared_JAMA_Matrix($X); return ($X->getMatrix(0, $this->n-1, 0, $nx)); } else { - throw new PHPExcel_Calculation_Exception(self::MatrixRankException); + throw new PHPExcel_Calculation_Exception(self::MATRIX_RANK_EXCEPTION); } } else { - throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MATRIX_DIMENSION_EXCEPTION); } - } // function solve() + } } diff --git a/Classes/PHPExcel/Shared/JAMA/utils/Error.php b/Classes/PHPExcel/Shared/JAMA/utils/Error.php index 155bcba04..71b8c994a 100644 --- a/Classes/PHPExcel/Shared/JAMA/utils/Error.php +++ b/Classes/PHPExcel/Shared/JAMA/utils/Error.php @@ -21,47 +21,47 @@ Feel free to correct anything that looks amiss to you. */ -define('PolymorphicArgumentException', -1); -$error['EN'][PolymorphicArgumentException] = "Invalid argument pattern for polymorphic function."; -$error['FR'][PolymorphicArgumentException] = "Modèle inadmissible d'argument pour la fonction polymorphe.". -$error['DE'][PolymorphicArgumentException] = "Unzulässiges Argumentmuster für polymorphe Funktion."; - -define('ArgumentTypeException', -2); -$error['EN'][ArgumentTypeException] = "Invalid argument type."; -$error['FR'][ArgumentTypeException] = "Type inadmissible d'argument."; -$error['DE'][ArgumentTypeException] = "Unzulässige Argumentart."; - -define('ArgumentBoundsException', -3); -$error['EN'][ArgumentBoundsException] = "Invalid argument range."; -$error['FR'][ArgumentBoundsException] = "Gamme inadmissible d'argument."; -$error['DE'][ArgumentBoundsException] = "Unzulässige Argumentstrecke."; - -define('MatrixDimensionException', -4); -$error['EN'][MatrixDimensionException] = "Matrix dimensions are not equal."; -$error['FR'][MatrixDimensionException] = "Les dimensions de Matrix ne sont pas égales."; -$error['DE'][MatrixDimensionException] = "Matrixmaße sind nicht gleich."; - -define('PrecisionLossException', -5); -$error['EN'][PrecisionLossException] = "Significant precision loss detected."; -$error['FR'][PrecisionLossException] = "Perte significative de précision détectée."; -$error['DE'][PrecisionLossException] = "Bedeutender Präzision Verlust ermittelte."; - -define('MatrixSPDException', -6); -$error['EN'][MatrixSPDException] = "Can only perform operation on symmetric positive definite matrix."; -$error['FR'][MatrixSPDException] = "Perte significative de précision détectée."; -$error['DE'][MatrixSPDException] = "Bedeutender Präzision Verlust ermittelte."; - -define('MatrixSingularException', -7); -$error['EN'][MatrixSingularException] = "Can only perform operation on singular matrix."; - -define('MatrixRankException', -8); -$error['EN'][MatrixRankException] = "Can only perform operation on full-rank matrix."; - -define('ArrayLengthException', -9); -$error['EN'][ArrayLengthException] = "Array length must be a multiple of m."; - -define('RowLengthException', -10); -$error['EN'][RowLengthException] = "All rows must have the same length."; +define('POLYMORPHIC_ARGUMENT_EXCEPTION', -1); +$error['EN'][POLYMORPHIC_ARGUMENT_EXCEPTION] = "Invalid argument pattern for polymorphic function."; +$error['FR'][POLYMORPHIC_ARGUMENT_EXCEPTION] = "Modèle inadmissible d'argument pour la fonction polymorphe.". +$error['DE'][POLYMORPHIC_ARGUMENT_EXCEPTION] = "Unzulässiges Argumentmuster für polymorphe Funktion."; + +define('ARGUMENT_TYPE_EXCEPTION', -2); +$error['EN'][ARGUMENT_TYPE_EXCEPTION] = "Invalid argument type."; +$error['FR'][ARGUMENT_TYPE_EXCEPTION] = "Type inadmissible d'argument."; +$error['DE'][ARGUMENT_TYPE_EXCEPTION] = "Unzulässige Argumentart."; + +define('ARGUMENT_BOUNDS_EXCEPTION', -3); +$error['EN'][ARGUMENT_BOUNDS_EXCEPTION] = "Invalid argument range."; +$error['FR'][ARGUMENT_BOUNDS_EXCEPTION] = "Gamme inadmissible d'argument."; +$error['DE'][ARGUMENT_BOUNDS_EXCEPTION] = "Unzulässige Argumentstrecke."; + +define('MATRIX_DIMENSION_EXCEPTION', -4); +$error['EN'][MATRIX_DIMENSION_EXCEPTION] = "Matrix dimensions are not equal."; +$error['FR'][MATRIX_DIMENSION_EXCEPTION] = "Les dimensions de Matrix ne sont pas égales."; +$error['DE'][MATRIX_DIMENSION_EXCEPTION] = "Matrixmaße sind nicht gleich."; + +define('PRECISION_LOSS_EXCEPTION', -5); +$error['EN'][PRECISION_LOSS_EXCEPTION] = "Significant precision loss detected."; +$error['FR'][PRECISION_LOSS_EXCEPTION] = "Perte significative de précision détectée."; +$error['DE'][PRECISION_LOSS_EXCEPTION] = "Bedeutender Präzision Verlust ermittelte."; + +define('MATRIX_SPD_EXCEPTION', -6); +$error['EN'][MATRIX_SPD_EXCEPTION] = "Can only perform operation on symmetric positive definite matrix."; +$error['FR'][MATRIX_SPD_EXCEPTION] = "Perte significative de précision détectée."; +$error['DE'][MATRIX_SPD_EXCEPTION] = "Bedeutender Präzision Verlust ermittelte."; + +define('MATRIX_SINGULAR_EXCEPTION', -7); +$error['EN'][MATRIX_SINGULAR_EXCEPTION] = "Can only perform operation on singular matrix."; + +define('MATRIX_RANK_EXCEPTION', -8); +$error['EN'][MATRIX_RANK_EXCEPTION] = "Can only perform operation on full-rank matrix."; + +define('ARRAY_LENGTH_EXCEPTION', -9); +$error['EN'][ARRAY_LENGTH_EXCEPTION] = "Array length must be a multiple of m."; + +define('ROW_LENGTH_EXCEPTION', -10); +$error['EN'][ROW_LENGTH_EXCEPTION] = "All rows must have the same length."; /** * Custom error handler diff --git a/Classes/PHPExcel/Shared/JAMA/utils/Maths.php b/Classes/PHPExcel/Shared/JAMA/utils/Maths.php index 6d4db65a1..386c1e673 100644 --- a/Classes/PHPExcel/Shared/JAMA/utils/Maths.php +++ b/Classes/PHPExcel/Shared/JAMA/utils/Maths.php @@ -36,7 +36,7 @@ function hypot() { if (is_numeric($d)) { $s += pow($d, 2); } else { - throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + throw new PHPExcel_Calculation_Exception(JAMAError(ARGUMENT_TYPE_EXCEPTION)); } } return sqrt($s); From 99b375613d81d270817579464625cc0fe9cd5c8d Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 24 May 2015 01:17:43 +0100 Subject: [PATCH 400/467] PSR-2 coding standards for trendclass.... this really does want factoring out into a separate repo --- .../PHPExcel/Shared/trend/bestFitClass.php | 243 +++++++++--------- .../Shared/trend/exponentialBestFitClass.php | 49 ++-- .../Shared/trend/linearBestFitClass.php | 35 +-- .../Shared/trend/logarithmicBestFitClass.php | 35 +-- .../Shared/trend/polynomialBestFitClass.php | 71 +++-- .../Shared/trend/powerBestFitClass.php | 45 ++-- Classes/PHPExcel/Shared/trend/trendClass.php | 95 ++++--- 7 files changed, 258 insertions(+), 315 deletions(-) diff --git a/Classes/PHPExcel/Shared/trend/bestFitClass.php b/Classes/PHPExcel/Shared/trend/bestFitClass.php index 1e547b2fb..2de029f96 100644 --- a/Classes/PHPExcel/Shared/trend/bestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/bestFitClass.php @@ -1,6 +1,7 @@ <?php + /** - * PHPExcel + * PHPExcel_Best_Fit * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,14 +25,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -/** - * PHPExcel_Best_Fit - * - * @category PHPExcel - * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Best_Fit { /** @@ -39,89 +32,89 @@ class PHPExcel_Best_Fit * * @var boolean **/ - protected $_error = false; + protected $error = false; /** * Algorithm type to use for best-fit * * @var string **/ - protected $_bestFitType = 'undetermined'; + protected $bestFitType = 'undetermined'; /** * Number of entries in the sets of x- and y-value arrays * * @var int **/ - protected $_valueCount = 0; + protected $valueCount = 0; /** * X-value dataseries of values * * @var float[] **/ - protected $_xValues = array(); + protected $xValues = array(); /** * Y-value dataseries of values * * @var float[] **/ - protected $_yValues = array(); + protected $yValues = array(); /** * Flag indicating whether values should be adjusted to Y=0 * * @var boolean **/ - protected $_adjustToZero = false; + protected $adjustToZero = false; /** * Y-value series of best-fit values * * @var float[] **/ - protected $_yBestFitValues = array(); + protected $yBestFitValues = array(); - protected $_goodnessOfFit = 1; + protected $goodnessOfFit = 1; - protected $_stdevOfResiduals = 0; + protected $stdevOfResiduals = 0; - protected $_covariance = 0; + protected $covariance = 0; - protected $_correlation = 0; + protected $correlation = 0; - protected $_SSRegression = 0; + protected $SSRegression = 0; - protected $_SSResiduals = 0; + protected $SSResiduals = 0; - protected $_DFResiduals = 0; + protected $DFResiduals = 0; - protected $_F = 0; + protected $f = 0; - protected $_slope = 0; + protected $slope = 0; - protected $_slopeSE = 0; + protected $slopeSE = 0; - protected $_intersect = 0; + protected $intersect = 0; - protected $_intersectSE = 0; + protected $intersectSE = 0; - protected $_Xoffset = 0; + protected $xOffset = 0; - protected $_Yoffset = 0; + protected $yOffset = 0; public function getError() { - return $this->_error; - } // function getBestFitType() + return $this->error; + } public function getBestFitType() { - return $this->_bestFitType; - } // function getBestFitType() + return $this->bestFitType; + } /** * Return the Y-Value for a specified value of X @@ -132,7 +125,7 @@ public function getBestFitType() public function getValueOfYForX($xValue) { return false; - } // function getValueOfYForX() + } /** * Return the X-Value for a specified value of Y @@ -143,7 +136,7 @@ public function getValueOfYForX($xValue) public function getValueOfXForY($yValue) { return false; - } // function getValueOfXForY() + } /** * Return the original set of X-Values @@ -152,8 +145,8 @@ public function getValueOfXForY($yValue) */ public function getXValues() { - return $this->_xValues; - } // function getValueOfXForY() + return $this->xValues; + } /** * Return the Equation of the best-fit line @@ -164,7 +157,7 @@ public function getXValues() public function getEquation($dp = 0) { return false; - } // function getEquation() + } /** * Return the Slope of the line @@ -175,10 +168,10 @@ public function getEquation($dp = 0) public function getSlope($dp = 0) { if ($dp != 0) { - return round($this->_slope, $dp); + return round($this->slope, $dp); } - return $this->_slope; - } // function getSlope() + return $this->slope; + } /** * Return the standard error of the Slope @@ -189,10 +182,10 @@ public function getSlope($dp = 0) public function getSlopeSE($dp = 0) { if ($dp != 0) { - return round($this->_slopeSE, $dp); + return round($this->slopeSE, $dp); } - return $this->_slopeSE; - } // function getSlopeSE() + return $this->slopeSE; + } /** * Return the Value of X where it intersects Y = 0 @@ -203,10 +196,10 @@ public function getSlopeSE($dp = 0) public function getIntersect($dp = 0) { if ($dp != 0) { - return round($this->_intersect, $dp); + return round($this->intersect, $dp); } - return $this->_intersect; - } // function getIntersect() + return $this->intersect; + } /** * Return the standard error of the Intersect @@ -217,10 +210,10 @@ public function getIntersect($dp = 0) public function getIntersectSE($dp = 0) { if ($dp != 0) { - return round($this->_intersectSE, $dp); + return round($this->intersectSE, $dp); } - return $this->_intersectSE; - } // function getIntersectSE() + return $this->intersectSE; + } /** * Return the goodness of fit for this regression @@ -231,18 +224,18 @@ public function getIntersectSE($dp = 0) public function getGoodnessOfFit($dp = 0) { if ($dp != 0) { - return round($this->_goodnessOfFit, $dp); + return round($this->goodnessOfFit, $dp); } - return $this->_goodnessOfFit; - } // function getGoodnessOfFit() + return $this->goodnessOfFit; + } public function getGoodnessOfFitPercent($dp = 0) { if ($dp != 0) { - return round($this->_goodnessOfFit * 100, $dp); + return round($this->goodnessOfFit * 100, $dp); } - return $this->_goodnessOfFit * 100; - } // function getGoodnessOfFitPercent() + return $this->goodnessOfFit * 100; + } /** * Return the standard deviation of the residuals for this regression @@ -253,127 +246,127 @@ public function getGoodnessOfFitPercent($dp = 0) public function getStdevOfResiduals($dp = 0) { if ($dp != 0) { - return round($this->_stdevOfResiduals, $dp); + return round($this->stdevOfResiduals, $dp); } - return $this->_stdevOfResiduals; - } // function getStdevOfResiduals() + return $this->stdevOfResiduals; + } public function getSSRegression($dp = 0) { if ($dp != 0) { - return round($this->_SSRegression, $dp); + return round($this->SSRegression, $dp); } - return $this->_SSRegression; - } // function getSSRegression() + return $this->SSRegression; + } public function getSSResiduals($dp = 0) { if ($dp != 0) { - return round($this->_SSResiduals, $dp); + return round($this->SSResiduals, $dp); } - return $this->_SSResiduals; - } // function getSSResiduals() + return $this->SSResiduals; + } public function getDFResiduals($dp = 0) { if ($dp != 0) { - return round($this->_DFResiduals, $dp); + return round($this->DFResiduals, $dp); } - return $this->_DFResiduals; - } // function getDFResiduals() + return $this->DFResiduals; + } public function getF($dp = 0) { if ($dp != 0) { - return round($this->_F, $dp); + return round($this->f, $dp); } - return $this->_F; - } // function getF() + return $this->f; + } public function getCovariance($dp = 0) { if ($dp != 0) { - return round($this->_covariance, $dp); + return round($this->covariance, $dp); } - return $this->_covariance; - } // function getCovariance() + return $this->covariance; + } public function getCorrelation($dp = 0) { if ($dp != 0) { - return round($this->_correlation, $dp); + return round($this->correlation, $dp); } - return $this->_correlation; - } // function getCorrelation() + return $this->correlation; + } public function getYBestFitValues() { - return $this->_yBestFitValues; - } // function getYBestFitValues() + return $this->yBestFitValues; + } - protected function _calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const) + protected function calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const) { $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0; - foreach ($this->_xValues as $xKey => $xValue) { - $bestFitY = $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); + foreach ($this->xValues as $xKey => $xValue) { + $bestFitY = $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); - $SSres += ($this->_yValues[$xKey] - $bestFitY) * ($this->_yValues[$xKey] - $bestFitY); + $SSres += ($this->yValues[$xKey] - $bestFitY) * ($this->yValues[$xKey] - $bestFitY); if ($const) { - $SStot += ($this->_yValues[$xKey] - $meanY) * ($this->_yValues[$xKey] - $meanY); + $SStot += ($this->yValues[$xKey] - $meanY) * ($this->yValues[$xKey] - $meanY); } else { - $SStot += $this->_yValues[$xKey] * $this->_yValues[$xKey]; + $SStot += $this->yValues[$xKey] * $this->yValues[$xKey]; } - $SScov += ($this->_xValues[$xKey] - $meanX) * ($this->_yValues[$xKey] - $meanY); + $SScov += ($this->xValues[$xKey] - $meanX) * ($this->yValues[$xKey] - $meanY); if ($const) { - $SSsex += ($this->_xValues[$xKey] - $meanX) * ($this->_xValues[$xKey] - $meanX); + $SSsex += ($this->xValues[$xKey] - $meanX) * ($this->xValues[$xKey] - $meanX); } else { - $SSsex += $this->_xValues[$xKey] * $this->_xValues[$xKey]; + $SSsex += $this->xValues[$xKey] * $this->xValues[$xKey]; } } - $this->_SSResiduals = $SSres; - $this->_DFResiduals = $this->_valueCount - 1 - $const; + $this->SSResiduals = $SSres; + $this->DFResiduals = $this->valueCount - 1 - $const; - if ($this->_DFResiduals == 0.0) { - $this->_stdevOfResiduals = 0.0; + if ($this->DFResiduals == 0.0) { + $this->stdevOfResiduals = 0.0; } else { - $this->_stdevOfResiduals = sqrt($SSres / $this->_DFResiduals); + $this->stdevOfResiduals = sqrt($SSres / $this->DFResiduals); } if (($SStot == 0.0) || ($SSres == $SStot)) { - $this->_goodnessOfFit = 1; + $this->goodnessOfFit = 1; } else { - $this->_goodnessOfFit = 1 - ($SSres / $SStot); + $this->goodnessOfFit = 1 - ($SSres / $SStot); } - $this->_SSRegression = $this->_goodnessOfFit * $SStot; - $this->_covariance = $SScov / $this->_valueCount; - $this->_correlation = ($this->_valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->_valueCount * $sumX2 - pow($sumX, 2)) * ($this->_valueCount * $sumY2 - pow($sumY, 2))); - $this->_slopeSE = $this->_stdevOfResiduals / sqrt($SSsex); - $this->_intersectSE = $this->_stdevOfResiduals * sqrt(1 / ($this->_valueCount - ($sumX * $sumX) / $sumX2)); - if ($this->_SSResiduals != 0.0) { - if ($this->_DFResiduals == 0.0) { - $this->_F = 0.0; + $this->SSRegression = $this->goodnessOfFit * $SStot; + $this->covariance = $SScov / $this->valueCount; + $this->correlation = ($this->valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->valueCount * $sumX2 - pow($sumX, 2)) * ($this->valueCount * $sumY2 - pow($sumY, 2))); + $this->slopeSE = $this->stdevOfResiduals / sqrt($SSsex); + $this->intersectSE = $this->stdevOfResiduals * sqrt(1 / ($this->valueCount - ($sumX * $sumX) / $sumX2)); + if ($this->SSResiduals != 0.0) { + if ($this->DFResiduals == 0.0) { + $this->f = 0.0; } else { - $this->_F = $this->_SSRegression / ($this->_SSResiduals / $this->_DFResiduals); + $this->f = $this->SSRegression / ($this->SSResiduals / $this->DFResiduals); } } else { - if ($this->_DFResiduals == 0.0) { - $this->_F = 0.0; + if ($this->DFResiduals == 0.0) { + $this->f = 0.0; } else { - $this->_F = $this->_SSRegression / $this->_DFResiduals; + $this->f = $this->SSRegression / $this->DFResiduals; } } - } // function _calculateGoodnessOfFit() + } - protected function _leastSquareFit($yValues, $xValues, $const) + protected function leastSquareFit($yValues, $xValues, $const) { // calculate sums $x_sum = array_sum($xValues); $y_sum = array_sum($yValues); - $meanX = $x_sum / $this->_valueCount; - $meanY = $y_sum / $this->_valueCount; + $meanX = $x_sum / $this->valueCount; + $meanY = $y_sum / $this->valueCount; $mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0; - for ($i = 0; $i < $this->_valueCount; ++$i) { + for ($i = 0; $i < $this->valueCount; ++$i) { $xy_sum += $xValues[$i] * $yValues[$i]; $xx_sum += $xValues[$i] * $xValues[$i]; $yy_sum += $yValues[$i] * $yValues[$i]; @@ -388,19 +381,19 @@ protected function _leastSquareFit($yValues, $xValues, $const) } // calculate slope -// $this->_slope = (($this->_valueCount * $xy_sum) - ($x_sum * $y_sum)) / (($this->_valueCount * $xx_sum) - ($x_sum * $x_sum)); - $this->_slope = $mBase / $mDivisor; +// $this->slope = (($this->valueCount * $xy_sum) - ($x_sum * $y_sum)) / (($this->valueCount * $xx_sum) - ($x_sum * $x_sum)); + $this->slope = $mBase / $mDivisor; // calculate intersect -// $this->_intersect = ($y_sum - ($this->_slope * $x_sum)) / $this->_valueCount; +// $this->intersect = ($y_sum - ($this->slope * $x_sum)) / $this->valueCount; if ($const) { - $this->_intersect = $meanY - ($this->_slope * $meanX); + $this->intersect = $meanY - ($this->slope * $meanX); } else { - $this->_intersect = 0; + $this->intersect = 0; } - $this->_calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, $meanX, $meanY, $const); - } // function _leastSquareFit() + $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, $meanX, $meanY, $const); + } /** * Define the regression @@ -421,12 +414,12 @@ public function __construct($yValues, $xValues = array(), $const = true) $nX = $nY; } elseif ($nY != $nX) { // Ensure both arrays of points are the same size - $this->_error = true; + $this->error = true; return false; } - $this->_valueCount = $nY; - $this->_xValues = $xValues; - $this->_yValues = $yValues; - } // function __construct() + $this->valueCount = $nY; + $this->xValues = $xValues; + $this->yValues = $yValues; + } } diff --git a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php index caa1759cd..444873525 100644 --- a/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php @@ -1,6 +1,9 @@ <?php + +require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); + /** - * PHPExcel + * PHPExcel_Exponential_Best_Fit * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,18 +27,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); - - -/** - * PHPExcel_Exponential_Best_Fit - * - * @category PHPExcel - * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit { /** @@ -44,7 +35,7 @@ class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit * * @var string **/ - protected $_bestFitType = 'exponential'; + protected $bestFitType = 'exponential'; /** * Return the Y-Value for a specified value of X @@ -54,8 +45,8 @@ class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit **/ public function getValueOfYForX($xValue) { - return $this->getIntersect() * pow($this->getSlope(), ($xValue - $this->_Xoffset)); - } // function getValueOfYForX() + return $this->getIntersect() * pow($this->getSlope(), ($xValue - $this->xOffset)); + } /** * Return the X-Value for a specified value of Y @@ -65,8 +56,8 @@ public function getValueOfYForX($xValue) **/ public function getValueOfXForY($yValue) { - return log(($yValue + $this->_Yoffset) / $this->getIntersect()) / log($this->getSlope()); - } // function getValueOfXForY() + return log(($yValue + $this->yOffset) / $this->getIntersect()) / log($this->getSlope()); + } /** * Return the Equation of the best-fit line @@ -79,8 +70,8 @@ public function getEquation($dp = 0) $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); - return 'Y = '.$intersect.' * '.$slope.'^X'; - } // function getEquation() + return 'Y = ' . $intersect . ' * ' . $slope . '^X'; + } /** * Return the Slope of the line @@ -94,7 +85,7 @@ public function getSlope($dp = 0) return round(exp($this->_slope), $dp); } return exp($this->_slope); - } // function getSlope() + } /** * Return the Value of X where it intersects Y = 0 @@ -105,10 +96,10 @@ public function getSlope($dp = 0) public function getIntersect($dp = 0) { if ($dp != 0) { - return round(exp($this->_intersect), $dp); + return round(exp($this->intersect), $dp); } - return exp($this->_intersect); - } // function getIntersect() + return exp($this->intersect); + } /** * Execute the regression and calculate the goodness of fit for a set of X and Y data values @@ -117,7 +108,7 @@ public function getIntersect($dp = 0) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - private function _exponential_regression($yValues, $xValues, $const) + private function exponentialRegression($yValues, $xValues, $const) { foreach ($yValues as &$value) { if ($value < 0.0) { @@ -128,8 +119,8 @@ private function _exponential_regression($yValues, $xValues, $const) } unset($value); - $this->_leastSquareFit($yValues, $xValues, $const); - } // function _exponential_regression() + $this->leastSquareFit($yValues, $xValues, $const); + } /** * Define the regression and calculate the goodness of fit for a set of X and Y data values @@ -141,7 +132,7 @@ private function _exponential_regression($yValues, $xValues, $const) public function __construct($yValues, $xValues = array(), $const = true) { if (parent::__construct($yValues, $xValues) !== false) { - $this->_exponential_regression($yValues, $xValues, $const); + $this->exponentialRegression($yValues, $xValues, $const); } - } // function __construct() + } } diff --git a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php index c5ed3cf3b..76b55b3e7 100644 --- a/Classes/PHPExcel/Shared/trend/linearBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/linearBestFitClass.php @@ -1,6 +1,9 @@ <?php + +require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); + /** - * PHPExcel + * PHPExcel_Linear_Best_Fit * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,16 +27,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); - -/** - * PHPExcel_Linear_Best_Fit - * - * @category PHPExcel - * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit { /** @@ -42,7 +35,7 @@ class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit * * @var string **/ - protected $_bestFitType = 'linear'; + protected $bestFitType = 'linear'; /** * Return the Y-Value for a specified value of X @@ -53,7 +46,7 @@ class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit public function getValueOfYForX($xValue) { return $this->getIntersect() + $this->getSlope() * $xValue; - } // function getValueOfYForX() + } /** * Return the X-Value for a specified value of Y @@ -64,7 +57,7 @@ public function getValueOfYForX($xValue) public function getValueOfXForY($yValue) { return ($yValue - $this->getIntersect()) / $this->getSlope(); - } // function getValueOfXForY() + } /** @@ -78,8 +71,8 @@ public function getEquation($dp = 0) $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); - return 'Y = '.$intersect.' + '.$slope.' * X'; - } // function getEquation() + return 'Y = ' . $intersect . ' + ' . $slope . ' * X'; + } /** * Execute the regression and calculate the goodness of fit for a set of X and Y data values @@ -88,10 +81,10 @@ public function getEquation($dp = 0) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - private function _linear_regression($yValues, $xValues, $const) + private function linearRegression($yValues, $xValues, $const) { - $this->_leastSquareFit($yValues, $xValues, $const); - } // function _linear_regression() + $this->leastSquareFit($yValues, $xValues, $const); + } /** * Define the regression and calculate the goodness of fit for a set of X and Y data values @@ -103,7 +96,7 @@ private function _linear_regression($yValues, $xValues, $const) public function __construct($yValues, $xValues = array(), $const = true) { if (parent::__construct($yValues, $xValues) !== false) { - $this->_linear_regression($yValues, $xValues, $const); + $this->linearRegression($yValues, $xValues, $const); } - } // function __construct() + } } diff --git a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php index 7d561cda3..221c53869 100644 --- a/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php @@ -1,6 +1,9 @@ <?php + +require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); + /** - * PHPExcel + * PHPExcel_Logarithmic_Best_Fit * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,16 +27,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - -require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); - -/** - * PHPExcel_Logarithmic_Best_Fit - * - * @category PHPExcel - * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit { /** @@ -42,7 +35,7 @@ class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit * * @var string **/ - protected $_bestFitType = 'logarithmic'; + protected $bestFitType = 'logarithmic'; /** * Return the Y-Value for a specified value of X @@ -52,8 +45,8 @@ class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit **/ public function getValueOfYForX($xValue) { - return $this->getIntersect() + $this->getSlope() * log($xValue - $this->_Xoffset); - } // function getValueOfYForX() + return $this->getIntersect() + $this->getSlope() * log($xValue - $this->xOffset); + } /** * Return the X-Value for a specified value of Y @@ -64,7 +57,7 @@ public function getValueOfYForX($xValue) public function getValueOfXForY($yValue) { return exp(($yValue - $this->getIntersect()) / $this->getSlope()); - } // function getValueOfXForY() + } /** * Return the Equation of the best-fit line @@ -78,7 +71,7 @@ public function getEquation($dp = 0) $intersect = $this->getIntersect($dp); return 'Y = '.$intersect.' + '.$slope.' * log(X)'; - } // function getEquation() + } /** * Execute the regression and calculate the goodness of fit for a set of X and Y data values @@ -87,7 +80,7 @@ public function getEquation($dp = 0) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - private function _logarithmic_regression($yValues, $xValues, $const) + private function logarithmicRegression($yValues, $xValues, $const) { foreach ($xValues as &$value) { if ($value < 0.0) { @@ -98,8 +91,8 @@ private function _logarithmic_regression($yValues, $xValues, $const) } unset($value); - $this->_leastSquareFit($yValues, $xValues, $const); - } // function _logarithmic_regression() + $this->leastSquareFit($yValues, $xValues, $const); + } /** * Define the regression and calculate the goodness of fit for a set of X and Y data values @@ -111,7 +104,7 @@ private function _logarithmic_regression($yValues, $xValues, $const) public function __construct($yValues, $xValues = array(), $const = true) { if (parent::__construct($yValues, $xValues) !== false) { - $this->_logarithmic_regression($yValues, $xValues, $const); + $this->logarithmicRegression($yValues, $xValues, $const); } - } // function __construct() + } } diff --git a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php index b1b69b0ac..8a882b743 100644 --- a/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php @@ -1,6 +1,10 @@ <?php + +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/Matrix.php'; + /** - * PHPExcel + * PHPExcel_Polynomial_Best_Fit * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,19 +28,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'; -require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/Matrix.php'; - - -/** - * PHPExcel_Polynomial_Best_Fit - * - * @category PHPExcel - * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit { /** @@ -45,7 +36,7 @@ class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit * * @var string **/ - protected $_bestFitType = 'polynomial'; + protected $bestFitType = 'polynomial'; /** * Polynomial order @@ -53,7 +44,7 @@ class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit * @protected * @var int **/ - protected $_order = 0; + protected $order = 0; /** @@ -63,8 +54,8 @@ class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit **/ public function getOrder() { - return $this->_order; - } // function getOrder() + return $this->order; + } /** @@ -83,7 +74,7 @@ public function getValueOfYForX($xValue) } } return $retVal; - } // function getValueOfYForX() + } /** @@ -95,7 +86,7 @@ public function getValueOfYForX($xValue) public function getValueOfXForY($yValue) { return ($yValue - $this->getIntersect()) / $this->getSlope(); - } // function getValueOfXForY() + } /** @@ -109,17 +100,17 @@ public function getEquation($dp = 0) $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); - $equation = 'Y = '.$intersect; + $equation = 'Y = ' . $intersect; foreach ($slope as $key => $value) { if ($value != 0.0) { - $equation .= ' + '.$value.' * X'; + $equation .= ' + ' . $value . ' * X'; if ($key > 0) { - $equation .= '^'.($key + 1); + $equation .= '^' . ($key + 1); } } } return $equation; - } // function getEquation() + } /** @@ -138,13 +129,13 @@ public function getSlope($dp = 0) return $coefficients; } return $this->_slope; - } // function getSlope() + } public function getCoefficients($dp = 0) { return array_merge(array($this->getIntersect($dp)), $this->getSlope($dp)); - } // function getCoefficients() + } /** @@ -155,13 +146,13 @@ public function getCoefficients($dp = 0) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - private function _polynomial_regression($order, $yValues, $xValues, $const) + private function polynomialRegression($order, $yValues, $xValues, $const) { // calculate sums $x_sum = array_sum($xValues); $y_sum = array_sum($yValues); $xx_sum = $xy_sum = 0; - for ($i = 0; $i < $this->_valueCount; ++$i) { + for ($i = 0; $i < $this->valueCount; ++$i) { $xy_sum += $xValues[$i] * $yValues[$i]; $xx_sum += $xValues[$i] * $xValues[$i]; $yy_sum += $yValues[$i] * $yValues[$i]; @@ -174,12 +165,12 @@ private function _polynomial_regression($order, $yValues, $xValues, $const) * a series of x-y data points using least squares. * */ - for ($i = 0; $i < $this->_valueCount; ++$i) { + for ($i = 0; $i < $this->valueCount; ++$i) { for ($j = 0; $j <= $order; ++$j) { $A[$i][$j] = pow($xValues[$i], $j); } } - for ($i=0; $i < $this->_valueCount; ++$i) { + for ($i=0; $i < $this->valueCount; ++$i) { $B[$i] = array($yValues[$i]); } $matrixA = new Matrix($A); @@ -195,14 +186,14 @@ private function _polynomial_regression($order, $yValues, $xValues, $const) $coefficients[] = $r; } - $this->_intersect = array_shift($coefficients); + $this->intersect = array_shift($coefficients); $this->_slope = $coefficients; - $this->_calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum); - foreach ($this->_xValues as $xKey => $xValue) { - $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); + $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum); + foreach ($this->xValues as $xKey => $xValue) { + $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); } - } // function _polynomial_regression() + } /** @@ -216,10 +207,10 @@ private function _polynomial_regression($order, $yValues, $xValues, $const) public function __construct($order, $yValues, $xValues = array(), $const = true) { if (parent::__construct($yValues, $xValues) !== false) { - if ($order < $this->_valueCount) { - $this->_bestFitType .= '_'.$order; - $this->_order = $order; - $this->_polynomial_regression($order, $yValues, $xValues, $const); + if ($order < $this->valueCount) { + $this->bestFitType .= '_'.$order; + $this->order = $order; + $this->polynomialRegression($order, $yValues, $xValues, $const); if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) { $this->_error = true; } @@ -227,5 +218,5 @@ public function __construct($order, $yValues, $xValues = array(), $const = true) $this->_error = true; } } - } // function __construct() + } } diff --git a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php index 38870af8a..77c473429 100644 --- a/Classes/PHPExcel/Shared/trend/powerBestFitClass.php +++ b/Classes/PHPExcel/Shared/trend/powerBestFitClass.php @@ -1,6 +1,9 @@ <?php + +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'; + /** - * PHPExcel + * PHPExcel_Power_Best_Fit * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,18 +27,6 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'; - - -/** - * PHPExcel_Power_Best_Fit - * - * @category PHPExcel - * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit { /** @@ -44,7 +35,7 @@ class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit * * @var string **/ - protected $_bestFitType = 'power'; + protected $bestFitType = 'power'; /** @@ -55,8 +46,8 @@ class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit **/ public function getValueOfYForX($xValue) { - return $this->getIntersect() * pow(($xValue - $this->_Xoffset), $this->getSlope()); - } // function getValueOfYForX() + return $this->getIntersect() * pow(($xValue - $this->xOffset), $this->getSlope()); + } /** @@ -67,8 +58,8 @@ public function getValueOfYForX($xValue) **/ public function getValueOfXForY($yValue) { - return pow((($yValue + $this->_Yoffset) / $this->getIntersect()), (1 / $this->getSlope())); - } // function getValueOfXForY() + return pow((($yValue + $this->yOffset) / $this->getIntersect()), (1 / $this->getSlope())); + } /** @@ -82,8 +73,8 @@ public function getEquation($dp = 0) $slope = $this->getSlope($dp); $intersect = $this->getIntersect($dp); - return 'Y = '.$intersect.' * X^'.$slope; - } // function getEquation() + return 'Y = ' . $intersect . ' * X^' . $slope; + } /** @@ -95,10 +86,10 @@ public function getEquation($dp = 0) public function getIntersect($dp = 0) { if ($dp != 0) { - return round(exp($this->_intersect), $dp); + return round(exp($this->intersect), $dp); } - return exp($this->_intersect); - } // function getIntersect() + return exp($this->intersect); + } /** @@ -108,7 +99,7 @@ public function getIntersect($dp = 0) * @param float[] $xValues The set of X-values for this regression * @param boolean $const */ - private function _power_regression($yValues, $xValues, $const) + private function powerRegression($yValues, $xValues, $const) { foreach ($xValues as &$value) { if ($value < 0.0) { @@ -127,8 +118,8 @@ private function _power_regression($yValues, $xValues, $const) } unset($value); - $this->_leastSquareFit($yValues, $xValues, $const); - } // function _power_regression() + $this->leastSquareFit($yValues, $xValues, $const); + } /** @@ -141,7 +132,7 @@ private function _power_regression($yValues, $xValues, $const) public function __construct($yValues, $xValues = array(), $const = true) { if (parent::__construct($yValues, $xValues) !== false) { - $this->_power_regression($yValues, $xValues, $const); + $this->powerRegression($yValues, $xValues, $const); } } } diff --git a/Classes/PHPExcel/Shared/trend/trendClass.php b/Classes/PHPExcel/Shared/trend/trendClass.php index a7b34ed9a..715cd4124 100644 --- a/Classes/PHPExcel/Shared/trend/trendClass.php +++ b/Classes/PHPExcel/Shared/trend/trendClass.php @@ -1,6 +1,13 @@ <?php + +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/linearBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/logarithmicBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/exponentialBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/powerBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/polynomialBestFitClass.php'; + /** - * PHPExcel + * PHPExcel_trendClass * * Copyright (c) 2006 - 2015 PHPExcel * @@ -24,64 +31,51 @@ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ - - -require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/linearBestFitClass.php'; -require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/logarithmicBestFitClass.php'; -require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/exponentialBestFitClass.php'; -require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/powerBestFitClass.php'; -require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/polynomialBestFitClass.php'; - - -/** - * PHPExcel_trendClass - * - * @category PHPExcel - * @package PHPExcel_Shared_Trend - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) - */ class trendClass { - const TREND_LINEAR = 'Linear'; - const TREND_LOGARITHMIC = 'Logarithmic'; - const TREND_EXPONENTIAL = 'Exponential'; - const TREND_POWER = 'Power'; - const TREND_POLYNOMIAL_2 = 'Polynomial_2'; - const TREND_POLYNOMIAL_3 = 'Polynomial_3'; - const TREND_POLYNOMIAL_4 = 'Polynomial_4'; - const TREND_POLYNOMIAL_5 = 'Polynomial_5'; - const TREND_POLYNOMIAL_6 = 'Polynomial_6'; - const TREND_BEST_FIT = 'Bestfit'; - const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials'; + const TREND_LINEAR = 'Linear'; + const TREND_LOGARITHMIC = 'Logarithmic'; + const TREND_EXPONENTIAL = 'Exponential'; + const TREND_POWER = 'Power'; + const TREND_POLYNOMIAL_2 = 'Polynomial_2'; + const TREND_POLYNOMIAL_3 = 'Polynomial_3'; + const TREND_POLYNOMIAL_4 = 'Polynomial_4'; + const TREND_POLYNOMIAL_5 = 'Polynomial_5'; + const TREND_POLYNOMIAL_6 = 'Polynomial_6'; + const TREND_BEST_FIT = 'Bestfit'; + const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials'; /** * Names of the best-fit trend analysis methods * * @var string[] **/ - private static $_trendTypes = array( self::TREND_LINEAR, - self::TREND_LOGARITHMIC, - self::TREND_EXPONENTIAL, - self::TREND_POWER - ); + private static $trendTypes = array( + self::TREND_LINEAR, + self::TREND_LOGARITHMIC, + self::TREND_EXPONENTIAL, + self::TREND_POWER + ); + /** * Names of the best-fit trend polynomial orders * * @var string[] **/ - private static $_trendTypePolyOrders = array( self::TREND_POLYNOMIAL_2, - self::TREND_POLYNOMIAL_3, - self::TREND_POLYNOMIAL_4, - self::TREND_POLYNOMIAL_5, - self::TREND_POLYNOMIAL_6 - ); + private static $trendTypePolynomialOrders = array( + self::TREND_POLYNOMIAL_2, + self::TREND_POLYNOMIAL_3, + self::TREND_POLYNOMIAL_4, + self::TREND_POLYNOMIAL_5, + self::TREND_POLYNOMIAL_6 + ); /** * Cached results for each method when trying to identify which provides the best fit * * @var PHPExcel_Best_Fit[] **/ - private static $_trendCache = array(); + private static $trendCache = array(); public static function calculate($trendType = self::TREND_BEST_FIT, $yValues, $xValues = array(), $const = true) @@ -107,34 +101,32 @@ public static function calculate($trendType = self::TREND_BEST_FIT, $yValues, $x case self::TREND_LOGARITHMIC: case self::TREND_EXPONENTIAL: case self::TREND_POWER: - if (!isset(self::$_trendCache[$key])) { + if (!isset(self::$trendCache[$key])) { $className = 'PHPExcel_'.$trendType.'_Best_Fit'; - self::$_trendCache[$key] = new $className($yValues, $xValues, $const); + self::$trendCache[$key] = new $className($yValues, $xValues, $const); } - return self::$_trendCache[$key]; - break; + return self::$trendCache[$key]; case self::TREND_POLYNOMIAL_2: case self::TREND_POLYNOMIAL_3: case self::TREND_POLYNOMIAL_4: case self::TREND_POLYNOMIAL_5: case self::TREND_POLYNOMIAL_6: - if (!isset(self::$_trendCache[$key])) { + if (!isset(self::$trendCache[$key])) { $order = substr($trendType, -1); - self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order, $yValues, $xValues, $const); + self::$trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order, $yValues, $xValues, $const); } - return self::$_trendCache[$key]; - break; + return self::$trendCache[$key]; case self::TREND_BEST_FIT: case self::TREND_BEST_FIT_NO_POLY: // If the request is to determine the best fit regression, then we test each trend line in turn // Start by generating an instance of each available trend method - foreach (self::$_trendTypes as $trendMethod) { + foreach (self::$trendTypes as $trendMethod) { $className = 'PHPExcel_'.$trendMethod.'BestFit'; $bestFit[$trendMethod] = new $className($yValues, $xValues, $const); $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); } if ($trendType != self::TREND_BEST_FIT_NO_POLY) { - foreach (self::$_trendTypePolyOrders as $trendMethod) { + foreach (self::$trendTypePolynomialOrders as $trendMethod) { $order = substr($trendMethod, -1); $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order, $yValues, $xValues, $const); if ($bestFit[$trendMethod]->getError()) { @@ -148,9 +140,8 @@ public static function calculate($trendType = self::TREND_BEST_FIT, $yValues, $x arsort($bestFitValue); $bestFitType = key($bestFitValue); return $bestFit[$bestFitType]; - break; default: return false; } - } // function calculate() + } } From 1ba2ae0cec68de85f6fd80ddf785db0b423b92cd Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 24 May 2015 12:27:36 +0100 Subject: [PATCH 401/467] Bugfix: (ncrypthic) Work Item GH-570 - Ignore inlineStr type if formula element exists --- Classes/PHPExcel/Calculation/LookupRef.php | 2 +- Classes/PHPExcel/Reader/Excel2007.php | 10 +++++++--- changelog.txt | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index 640f0c2eb..af38ea36d 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -694,7 +694,7 @@ public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not { $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); $index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); - $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); + $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); // index_number must be greater than or equal to 1 if ($index_number < 1) { diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 2903313e2..82b002136 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -848,8 +848,12 @@ public function load($pFilename) } break; case "inlineStr": - // echo 'Inline String', PHP_EOL; - $value = $this->parseRichText($c->is); +// echo 'Inline String', PHP_EOL; + if (isset($c->f)) { + $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToError'); + } else { + $value = $this->parseRichText($c->is); + } break; case "e": // echo 'Error', PHP_EOL; @@ -862,7 +866,7 @@ public function load($pFilename) } break; default: - // echo 'Default', PHP_EOL; +// echo 'Default', PHP_EOL; if (!isset($c->f)) { // echo 'Not a Formula', PHP_EOL; $value = self::castToString($c); diff --git a/changelog.txt b/changelog.txt index d12660c22..d4afc0c0f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -25,6 +25,7 @@ Planned for 1.8.2 - Bugfix: (MBaker) - Fix to getCell() method when cell reference includes a worksheet reference +- Bugfix: (ncrypthic) Work Item GH-570 - Ignore inlineStr type if formula element exists 2015-04-30 (v1.8.1): From e4d29824a65472298de40c9ab6c82ceb945e471e Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 24 May 2015 12:32:24 +0100 Subject: [PATCH 402/467] General: (umpirsky) Work Item GH-548 - Optimize vlookup() sort --- Classes/PHPExcel/Calculation/LookupRef.php | 4 ++-- changelog.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index af38ea36d..d86055121 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -674,10 +674,10 @@ private static function vlookupSort($a, $b) { reset($a); $firstColumn = key($a); - if (strtolower($a[$firstColumn]) == strtolower($b[$firstColumn])) { + if (($aLower = strtolower($a[$firstColumn])) == ($bLower = strtolower($b[$firstColumn]))) { return 0; } - return (strtolower($a[$firstColumn]) < strtolower($b[$firstColumn])) ? -1 : 1; + return ($aLower < $bLower) ? -1 : 1; } diff --git a/changelog.txt b/changelog.txt index d4afc0c0f..2f455c2de 100644 --- a/changelog.txt +++ b/changelog.txt @@ -26,6 +26,7 @@ Planned for 1.8.2 - Bugfix: (MBaker) - Fix to getCell() method when cell reference includes a worksheet reference - Bugfix: (ncrypthic) Work Item GH-570 - Ignore inlineStr type if formula element exists +- General: (umpirsky) Work Item GH-548 - Optimize vlookup() sort 2015-04-30 (v1.8.1): From 5f73ef34d355680280f1f8219b8e883ab94c92f7 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 24 May 2015 12:43:08 +0100 Subject: [PATCH 403/467] Docblock fixes from long to integer --- Classes/PHPExcel/Shared/Date.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index f860b8a46..00aefab3d 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -106,11 +106,11 @@ public static function getExcelCalendar() /** * Convert a date from Excel to PHP * - * @param long $dateValue Excel date/time value + * @param integer $dateValue Excel date/time value * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as * a UST timestamp, or adjusted to UST * @param string $timezone The timezone for finding the adjustment from UST - * @return long PHP serialized date/time + * @return integer PHP serialized date/time */ public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = false, $timezone = null) { @@ -197,13 +197,13 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $ti /** * FormattedPHPToExcel * - * @param long $year - * @param long $month - * @param long $day - * @param long $hours - * @param long $minutes - * @param long $seconds - * @return long Excel date/time value + * @param integer $year + * @param integer $month + * @param integer $day + * @param integer $hours + * @param integer $minutes + * @param integer $seconds + * @return integer Excel date/time value */ public static function FormattedPHPToExcel($year, $month, $day, $hours = 0, $minutes = 0, $seconds = 0) { From 3092adbb18185f624f24ec4919d48411d08e07c4 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 24 May 2015 14:15:39 +0100 Subject: [PATCH 404/467] Minor fixes and docblock changes --- Classes/PHPExcel/Shared/Date.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index 00aefab3d..a0a4e3953 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -78,8 +78,8 @@ class PHPExcel_Shared_Date /** * Set the Excel calendar (Windows 1900 or Mac 1904) * - * @param integer $baseDate Excel base date (1900 or 1904) - * @return boolean Success or failure + * @param integer $baseDate Excel base date (1900 or 1904) + * @return boolean Success or failure */ public static function setExcelCalendar($baseDate) { @@ -374,6 +374,12 @@ public static function stringToExcel($dateValue = '') return $dateValueNew; } + /** + * Converts a month name (either a long or a short name) to a month number + * + * @param string $month Month name or abbreviation + * @return integer|string Month number (1 - 12), or the original string argument if it isn't a valid month name + */ public static function monthStringToNumber($month) { $monthIndex = 1; @@ -386,11 +392,17 @@ public static function monthStringToNumber($month) return $month; } + /** + * Strips an ordinal froma numeric value + * + * @param string $day Day number with an ordinal + * @return integer|string The integer value with any ordinal stripped, or the original string argument if it isn't a valid numeric + */ public static function dayStringToNumber($day) { $strippedDayValue = (str_replace(self::$numberSuffixes, '', $day)); if (is_numeric($strippedDayValue)) { - return $strippedDayValue; + return (integer) $strippedDayValue; } return $day; } From 891478f6ab1e053154834c66362444a9f499c06e Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 24 May 2015 14:53:48 +0100 Subject: [PATCH 405/467] Updated Readme --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 220a6681a..3d831059a 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,12 @@ Develop: [![Build Status](https://travis-ci.org/PHPOffice/PHPExcel.png?branch=de ## Want to contribute? If you would like to contribute, here are some notes and guidlines: - - All development happens on the develop branch, so it is always the most up-to-date + - All new development happens on the 1.8 branch, so it is always the most up-to-date - The master branch only contains tagged releases - - If you are going to be submitting a pull request, please branch from develop, and submit your pull request back to the develop branch - - [Helpful article about forking](https://help.github.com/articles/fork-a-repo/ "") - - [Helpful article about pull requests](https://help.github.com/articles/using-pull-requests/ "") + - If you are going to be submitting a pull request, please fork from 1.8, and submit your pull request back to that 1.8 branch + - Wherever possible, code changes should conform as closely as possible to PSR-2 standards + - [Helpful article about forking](https://help.github.com/articles/fork-a-repo/ "Forking a Github repository") + - [Helpful article about pull requests](https://help.github.com/articles/using-pull-requests/ "Pull Requests") ## License From 77cc77209bf2b56b844629a57ac33b038fe4f8c9 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Tue, 26 May 2015 15:50:44 +0100 Subject: [PATCH 406/467] Minor performance tweak to OfficeOpenXML and BIFF Readers --- Classes/PHPExcel/Reader/Excel2007.php | 6 ++---- Classes/PHPExcel/Reader/Excel5.php | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 82b002136..c439bfc93 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -951,8 +951,7 @@ public function load($pFilename) } // Extract all cell references in $ref - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($ref); - foreach ($aReferences as $reference) { + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($ref) as $reference) { $docSheet->getStyle($reference)->setConditionalStyles($conditionalStyles); } } @@ -1178,8 +1177,7 @@ public function load($pFilename) $stRange = $docSheet->shrinkRangeToFit($range); // Extract all cell references in $range - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); - foreach ($aReferences as $reference) { + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($stRange) as $reference) { // Create validation $docValidation = $docSheet->getCell($reference)->getDataValidation(); $docValidation->setType((string) $dataValidation["type"]); diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 498e98521..ec22fe5cf 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -4883,8 +4883,7 @@ private function readDataValidation() foreach ($cellRangeAddresses as $cellRange) { $stRange = $this->phpSheet->shrinkRangeToFit($cellRange); - $stRange = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); - foreach ($stRange as $coordinate) { + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($stRange) as $coordinate) { $objValidation = $this->phpSheet->getCell($coordinate)->getDataValidation(); $objValidation->setType($type); $objValidation->setErrorStyle($errorStyle); From 7ced78b0be53cf11ba29b40f1176f8ba6e7b7db9 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Tue, 26 May 2015 21:35:53 +0100 Subject: [PATCH 407/467] gitter link --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 3d831059a..b0dd57aff 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ Master: [![Build Status](https://travis-ci.org/PHPOffice/PHPExcel.png?branch=mas Develop: [![Build Status](https://travis-ci.org/PHPOffice/PHPExcel.png?branch=develop)](http://travis-ci.org/PHPOffice/PHPExcel) +[![Join the chat at https://gitter.im/PHPOffice/PHPExcel](https://img.shields.io/badge/GITTER-join%20chat-green.svg)](https://gitter.im/PHPOffice/PHPExcel) + ## File Formats supported ### Reading From 879f86c235846350b96a5337a2f1323d87140614 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 12 Jul 2015 23:16:41 +0100 Subject: [PATCH 408/467] GH-554 - Whitespace after toRichTextObject() --- Classes/PHPExcel/Helper/HTML.php | 126 +++++++++++++++---------------- Examples/42richText.php | 27 ++++--- changelog.txt | 1 + 3 files changed, 76 insertions(+), 78 deletions(-) diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index 28bf6b107..5b6ecfe02 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -3,7 +3,7 @@ class PHPExcel_Helper_HTML { protected static $colourMap = array( - 'aliceblue' => 'f0f8ff', + 'aliceblue' => 'f0f8ff', 'antiquewhite' => 'faebd7', 'antiquewhite1' => 'ffefdb', 'antiquewhite2' => 'eedfcc', @@ -526,12 +526,12 @@ class PHPExcel_Helper_HTML protected $size; protected $color; - protected $bold = false; - protected $italic = false; - protected $underline = false; - protected $superscript = false; - protected $subscript = false; - protected $strikethrough = false; + protected $bold = false; + protected $italic = false; + protected $underline = false; + protected $superscript = false; + protected $subscript = false; + protected $strikethrough = false; protected $startTagCallbacks = array( 'font' => 'startFontTag', @@ -573,8 +573,7 @@ class PHPExcel_Helper_HTML protected $richTextObject; - protected function initialise() - { + protected function initialise() { $this->face = $this->size = $this->color = null; $this->bold = $this->italic = $this->underline = $this->superscript = $this->subscript = $this->strikethrough = false; @@ -583,30 +582,44 @@ protected function initialise() $this->stringData = ''; } - public function toRichTextObject($html) - { + public function toRichTextObject($html) { $this->initialise(); - // Create a new DOM object + // Create a new DOM object $dom = new domDocument; - // Load the HTML file into the DOM object + // Load the HTML file into the DOM object // Note the use of error suppression, because typically this will be an html fragment, so not fully valid markup $loaded = @$dom->loadHTML($html); - // Discard excess white space + // Discard excess white space $dom->preserveWhiteSpace = false; - $this->richTextObject = new PHPExcel_RichText(); + $this->richTextObject = new PHPExcel_RichText();; $this->parseElements($dom); + + // Clean any further spurious whitespace + $this->cleanWhitespace(); + return $this->richTextObject; } - protected function buildTextRun() - { + protected function cleanWhitespace() { + foreach($this->richTextObject->getRichTextElements() as $key => $element) { + $text = $element->getText(); + // Trim any leading spaces on the first run + if ($key == 0) { + $text = ltrim($text); + } + // Trim any spaces immediately after a line break + $text = preg_replace('/\n */mu', "\n", $text); + $element->setText($text); + } + } + + protected function buildTextRun() { $text = $this->stringData; - if (trim($text) === '') { + if (trim($text) === '') return; - } $richtextRun = $this->richTextObject->createTextRun($this->stringData); if ($this->face) { @@ -616,7 +629,7 @@ protected function buildTextRun() $richtextRun->getFont()->setSize($this->size); } if ($this->color) { - $richtextRun->getFont()->setColor(new PHPExcel_Style_Color('ff' . $this->color)); + $richtextRun->getFont()->setColor( new PHPExcel_Style_Color( 'ff' . $this->color ) ); } if ($this->bold) { $richtextRun->getFont()->setBold(true); @@ -639,22 +652,19 @@ protected function buildTextRun() $this->stringData = ''; } - protected function rgbToColour($rgb) - { + protected function rgbToColour($rgb) { preg_match_all('/\d+/', $rgb, $values); - foreach ($values[0] as &$value) { + foreach($values[0] as &$value) { $value = str_pad(dechex($value), 2, '0', STR_PAD_LEFT); } return implode($values[0]); } - protected function colourNameLookup($rgb) - { + protected function colourNameLookup($rgb) { return self::$colourMap[$rgb]; } - protected function startFontTag($tag) - { + protected function startFontTag($tag) { foreach ($tag->attributes as $attribute) { $attributeName = strtolower($attribute->name); $attributeValue = $attribute->value; @@ -662,7 +672,7 @@ protected function startFontTag($tag) if ($attributeName == 'color') { if (preg_match('/rgb\s*\(/', $attributeValue)) { $this->$attributeName = $this->rgbToColour($attributeValue); - } elseif (strpos(trim($attributeValue), '#') === 0) { + } elseif(strpos(trim($attributeValue), '#') === 0) { $this->$attributeName = ltrim($attributeValue, '#'); } else { $this->$attributeName = $this->colourNameLookup($attributeValue); @@ -673,85 +683,69 @@ protected function startFontTag($tag) } } - protected function endFontTag() - { + protected function endFontTag() { $this->face = $this->size = $this->color = null; } - protected function startBoldTag() - { + protected function startBoldTag() { $this->bold = true; } - protected function endBoldTag() - { + protected function endBoldTag() { $this->bold = false; } - protected function startItalicTag() - { + protected function startItalicTag() { $this->italic = true; } - protected function endItalicTag() - { + protected function endItalicTag() { $this->italic = false; } - protected function startUnderlineTag() - { + protected function startUnderlineTag() { $this->underline = true; } - protected function endUnderlineTag() - { + protected function endUnderlineTag() { $this->underline = false; } - protected function startSubscriptTag() - { + protected function startSubscriptTag() { $this->subscript = true; } - protected function endSubscriptTag() - { + protected function endSubscriptTag() { $this->subscript = false; } - protected function startSuperscriptTag() - { + protected function startSuperscriptTag() { $this->superscript = true; } - protected function endSuperscriptTag() - { + protected function endSuperscriptTag() { $this->superscript = false; } - protected function startStrikethruTag() - { + protected function startStrikethruTag() { $this->strikethrough = true; } - protected function endStrikethruTag() - { + protected function endStrikethruTag() { $this->strikethrough = false; } - protected function breakTag() - { - $this->stringData .= PHP_EOL; + protected function breakTag() { + $this->stringData .= "\n"; } - protected function parseTextNode(DOMText $textNode) - { - $domText = preg_replace('/\s+/u', ' ', ltrim($textNode->nodeValue)); + protected function parseTextNode(DOMText $textNode) { + $domText = preg_replace('/\s+/u', ' ', str_replace(["\r", "\n"], ' ', $textNode->nodeValue)); $this->stringData .= $domText; $this->buildTextRun(); } - protected function handleCallback($element, $callbackTag, $callbacks) - { + protected function handleCallback($element, $callbackTag, $callbacks) { if (isset($callbacks[$callbackTag])) { $elementHandler = $callbacks[$callbackTag]; if (method_exists($this, $elementHandler)) { @@ -760,22 +754,20 @@ protected function handleCallback($element, $callbackTag, $callbacks) } } - protected function parseElementNode(DOMElement $element) - { + protected function parseElementNode(DOMElement $element) { $callbackTag = strtolower($element->nodeName); $this->stack[] = $callbackTag; $this->handleCallback($element, $callbackTag, $this->startTagCallbacks); $this->parseElements($element); - $this->stringData .= ' '; +// $this->stringData .= ' '; array_pop($this->stack); $this->handleCallback($element, $callbackTag, $this->endTagCallbacks); } - protected function parseElements(DOMNode $element) - { + protected function parseElements(DOMNode $element) { foreach ($element->childNodes as $child) { if ($child instanceof DOMText) { $this->parseTextNode($child); diff --git a/Examples/42richText.php b/Examples/42richText.php index b8f994e6c..32bc401fd 100644 --- a/Examples/42richText.php +++ b/Examples/42richText.php @@ -2,7 +2,7 @@ /** * PHPExcel * - * Copyright (c) 2006 - 2015 PHPExcel + * Copyright (C) 2006 - 2014 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,7 @@ * * @category PHPExcel * @package PHPExcel - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL * @version ##VERSION##, ##DATE## */ @@ -55,7 +55,7 @@ // Add some data echo date('H:i:s') , " Add some data" , EOL; -$html1='<font color="#0000ff"> +$html1 = '<font color="#0000ff"> <h1 align="center">My very first example of rich text<br />generated from html markup</h1> <p> <font size="14" COLOR="rgb(0,255,128)"> @@ -64,11 +64,11 @@ </font> </p> <p align="right"><font size="9" color="red"> -I want to eat <ins><del>healthy food</del><strong>pizza</strong></ins>. +I want to eat <ins><del>healthy food</del> <strong>pizza</strong></ins>. </font> '; -$html2='<p> +$html2 = '<p> <font color="#ff0000"> 100&deg;C is a hot temperature </font> @@ -78,9 +78,11 @@ </font> </p>'; -$html3='2<sup>3</sup> equals 8'; +$html3 = '2<sup>3</sup> equals 8'; -$html4='H<sub>2</sub>SO<sub>4</sub> is the chemical formula for Sulphuric acid'; +$html4 = 'H<sub>2</sub>SO<sub>4</sub> is the chemical formula for Sulphuric acid'; + +$html5 = '<strong>bold</strong>, <em>italic</em>, <strong><em>bold+italic</em></strong>'; $wizard = new PHPExcel_Helper_HTML; @@ -97,7 +99,7 @@ $richText = $wizard->toRichTextObject($html2); -$objPHPExcel->setActiveSheetIndex(0) +$objPHPExcel->getActiveSheet() ->setCellValue('A2', $richText); $objPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(-1); @@ -105,12 +107,15 @@ ->getAlignment() ->setWrapText(true); -$objPHPExcel->setActiveSheetIndex(0) - ->setCellValue('A3', $wizard->toRichTextObject($html3)); +$objPHPExcel->getActiveSheet() + ->setCellValue('A3', $wizard->toRichTextObject($html3)); -$objPHPExcel->setActiveSheetIndex(0) +$objPHPExcel->getActiveSheet() ->setCellValue('A4', $wizard->toRichTextObject($html4)); +$objPHPExcel->getActiveSheet() + ->setCellValue('A5', $wizard->toRichTextObject($html5)); + // Rename worksheet echo date('H:i:s') , " Rename worksheet" , EOL; diff --git a/changelog.txt b/changelog.txt index 2f455c2de..eaefe2aae 100644 --- a/changelog.txt +++ b/changelog.txt @@ -27,6 +27,7 @@ Planned for 1.8.2 - Bugfix: (MBaker) - Fix to getCell() method when cell reference includes a worksheet reference - Bugfix: (ncrypthic) Work Item GH-570 - Ignore inlineStr type if formula element exists - General: (umpirsky) Work Item GH-548 - Optimize vlookup() sort +- Bugfix: (MBaker) Work Item GH-554 - Whitespace after toRichTextObject() 2015-04-30 (v1.8.1): From 78378f1c88a128a2e8e6c220f52a3b4b190a1174 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 12 Jul 2015 23:25:34 +0100 Subject: [PATCH 409/467] GH-554 - Whitespace after toRichTextObject() - abide by coding standards --- Classes/PHPExcel/Helper/HTML.php | 115 +++++++++++++++++++------------ 1 file changed, 72 insertions(+), 43 deletions(-) diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index 5b6ecfe02..661e26c11 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -3,7 +3,7 @@ class PHPExcel_Helper_HTML { protected static $colourMap = array( - 'aliceblue' => 'f0f8ff', + 'aliceblue' => 'f0f8ff', 'antiquewhite' => 'faebd7', 'antiquewhite1' => 'ffefdb', 'antiquewhite2' => 'eedfcc', @@ -526,12 +526,12 @@ class PHPExcel_Helper_HTML protected $size; protected $color; - protected $bold = false; - protected $italic = false; - protected $underline = false; - protected $superscript = false; - protected $subscript = false; - protected $strikethrough = false; + protected $bold = false; + protected $italic = false; + protected $underline = false; + protected $superscript = false; + protected $subscript = false; + protected $strikethrough = false; protected $startTagCallbacks = array( 'font' => 'startFontTag', @@ -573,7 +573,8 @@ class PHPExcel_Helper_HTML protected $richTextObject; - protected function initialise() { + protected function initialise() + { $this->face = $this->size = $this->color = null; $this->bold = $this->italic = $this->underline = $this->superscript = $this->subscript = $this->strikethrough = false; @@ -582,16 +583,17 @@ protected function initialise() { $this->stringData = ''; } - public function toRichTextObject($html) { + public function toRichTextObject($html) + { $this->initialise(); - // Create a new DOM object + // Create a new DOM object $dom = new domDocument; - // Load the HTML file into the DOM object + // Load the HTML file into the DOM object // Note the use of error suppression, because typically this will be an html fragment, so not fully valid markup $loaded = @$dom->loadHTML($html); - // Discard excess white space + // Discard excess white space $dom->preserveWhiteSpace = false; $this->richTextObject = new PHPExcel_RichText();; @@ -603,8 +605,9 @@ public function toRichTextObject($html) { return $this->richTextObject; } - protected function cleanWhitespace() { - foreach($this->richTextObject->getRichTextElements() as $key => $element) { + protected function cleanWhitespace() + { + foreach ($this->richTextObject->getRichTextElements() as $key => $element) { $text = $element->getText(); // Trim any leading spaces on the first run if ($key == 0) { @@ -615,11 +618,13 @@ protected function cleanWhitespace() { $element->setText($text); } } - - protected function buildTextRun() { + + protected function buildTextRun() + { $text = $this->stringData; - if (trim($text) === '') + if (trim($text) === '') { return; + } $richtextRun = $this->richTextObject->createTextRun($this->stringData); if ($this->face) { @@ -629,7 +634,7 @@ protected function buildTextRun() { $richtextRun->getFont()->setSize($this->size); } if ($this->color) { - $richtextRun->getFont()->setColor( new PHPExcel_Style_Color( 'ff' . $this->color ) ); + $richtextRun->getFont()->setColor(new PHPExcel_Style_Color('ff' . $this->color)); } if ($this->bold) { $richtextRun->getFont()->setBold(true); @@ -652,19 +657,22 @@ protected function buildTextRun() { $this->stringData = ''; } - protected function rgbToColour($rgb) { + protected function rgbToColour($rgb) + { preg_match_all('/\d+/', $rgb, $values); - foreach($values[0] as &$value) { + foreach ($values[0] as &$value) { $value = str_pad(dechex($value), 2, '0', STR_PAD_LEFT); } return implode($values[0]); } - protected function colourNameLookup($rgb) { + protected function colourNameLookup($rgb) + { return self::$colourMap[$rgb]; } - protected function startFontTag($tag) { + protected function startFontTag($tag) + { foreach ($tag->attributes as $attribute) { $attributeName = strtolower($attribute->name); $attributeValue = $attribute->value; @@ -672,7 +680,7 @@ protected function startFontTag($tag) { if ($attributeName == 'color') { if (preg_match('/rgb\s*\(/', $attributeValue)) { $this->$attributeName = $this->rgbToColour($attributeValue); - } elseif(strpos(trim($attributeValue), '#') === 0) { + } elseif (strpos(trim($attributeValue), '#') === 0) { $this->$attributeName = ltrim($attributeValue, '#'); } else { $this->$attributeName = $this->colourNameLookup($attributeValue); @@ -683,69 +691,89 @@ protected function startFontTag($tag) { } } - protected function endFontTag() { + protected function endFontTag() + { $this->face = $this->size = $this->color = null; } - protected function startBoldTag() { + protected function startBoldTag() + { $this->bold = true; } - protected function endBoldTag() { + protected function endBoldTag() + { $this->bold = false; } - protected function startItalicTag() { + protected function startItalicTag() + { $this->italic = true; } - protected function endItalicTag() { + protected function endItalicTag() + { $this->italic = false; } - protected function startUnderlineTag() { + protected function startUnderlineTag() + { $this->underline = true; } - protected function endUnderlineTag() { + protected function endUnderlineTag() + { $this->underline = false; } - protected function startSubscriptTag() { + protected function startSubscriptTag() + { $this->subscript = true; } - protected function endSubscriptTag() { + protected function endSubscriptTag() + { $this->subscript = false; } - protected function startSuperscriptTag() { + protected function startSuperscriptTag() + { $this->superscript = true; } - protected function endSuperscriptTag() { + protected function endSuperscriptTag() + { $this->superscript = false; } - protected function startStrikethruTag() { + protected function startStrikethruTag() + { $this->strikethrough = true; } - protected function endStrikethruTag() { + protected function endStrikethruTag() + { $this->strikethrough = false; } - protected function breakTag() { + protected function breakTag() + { $this->stringData .= "\n"; } - protected function parseTextNode(DOMText $textNode) { - $domText = preg_replace('/\s+/u', ' ', str_replace(["\r", "\n"], ' ', $textNode->nodeValue)); + protected function parseTextNode(DOMText $textNode) + { + $domText = preg_replace( + '/\s+/u', + ' ', + str_replace(["\r", "\n"], ' ', $textNode->nodeValue) + ); $this->stringData .= $domText; $this->buildTextRun(); } - protected function handleCallback($element, $callbackTag, $callbacks) { + protected function handleCallback($element, $callbackTag, $callbacks) + { if (isset($callbacks[$callbackTag])) { $elementHandler = $callbacks[$callbackTag]; if (method_exists($this, $elementHandler)) { @@ -754,20 +782,21 @@ protected function handleCallback($element, $callbackTag, $callbacks) { } } - protected function parseElementNode(DOMElement $element) { + protected function parseElementNode(DOMElement $element) + { $callbackTag = strtolower($element->nodeName); $this->stack[] = $callbackTag; $this->handleCallback($element, $callbackTag, $this->startTagCallbacks); $this->parseElements($element); -// $this->stringData .= ' '; array_pop($this->stack); $this->handleCallback($element, $callbackTag, $this->endTagCallbacks); } - protected function parseElements(DOMNode $element) { + protected function parseElements(DOMNode $element) + { foreach ($element->childNodes as $child) { if ($child instanceof DOMText) { $this->parseTextNode($child); From 1e4988e12cb48ac27a8c11489d17d356f387d7bf Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 15 Jul 2015 23:22:11 +0100 Subject: [PATCH 410/467] Case-sensitivity --- Classes/PHPExcel/Helper/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index 661e26c11..1e41e065e 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -588,7 +588,7 @@ public function toRichTextObject($html) $this->initialise(); // Create a new DOM object - $dom = new domDocument; + $dom = new \DOMDocument; // Load the HTML file into the DOM object // Note the use of error suppression, because typically this will be an html fragment, so not fully valid markup $loaded = @$dom->loadHTML($html); From 36eef2f16345a73b2e5c68b58bf10077b9e21d37 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 16 Jul 2015 22:29:15 +0100 Subject: [PATCH 411/467] New example to demonstrate merging two spreadsheet files into a single file --- Examples/43mergeWorkbooks.php | 91 +++++++++++++++++++++++++++ Examples/runall.php | 1 + Examples/templates/43mergeBook1.xlsx | Bin 0 -> 9629 bytes Examples/templates/43mergeBook2.xlsx | Bin 0 -> 9618 bytes 4 files changed, 92 insertions(+) create mode 100644 Examples/43mergeWorkbooks.php create mode 100644 Examples/templates/43mergeBook1.xlsx create mode 100644 Examples/templates/43mergeBook2.xlsx diff --git a/Examples/43mergeWorkbooks.php b/Examples/43mergeWorkbooks.php new file mode 100644 index 000000000..465b60a36 --- /dev/null +++ b/Examples/43mergeWorkbooks.php @@ -0,0 +1,91 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2015 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## + */ + +error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />'); + +date_default_timezone_set('Europe/London'); + +/** Include PHPExcel_IOFactory */ +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; + + +echo date('H:i:s') , " Load MergeBook1 from Excel2007 file" , EOL; +$callStartTime = microtime(true); + +$objPHPExcel1 = PHPExcel_IOFactory::load(dirname(__FILE__) . "/templates/43mergeBook1.xlsx"); + +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; +echo 'Call time to read Mergebook1 was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +echo date('H:i:s') , " Load MergeBook2 from Excel2007 file" , EOL; +$callStartTime = microtime(true); + +$objPHPExcel2 = PHPExcel_IOFactory::load(dirname(__FILE__) . "/templates/43mergeBook2.xlsx"); + +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; +echo 'Call time to read Mergebook2 was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +foreach($objPHPExcel2->getSheetNames() as $sheetName) { + $sheet = $objPHPExcel2->getSheetByName($sheetName); + $sheet->setTitle($sheet->getTitle() . ' copied'); + $objPHPExcel1->addExternalSheet($sheet); +} + + +echo date('H:i:s') , " Write to Excel2007 format" , EOL; +$callStartTime = microtime(true); + +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel1, 'Excel2007'); +$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); + +$callEndTime = microtime(true); +$callTime = $callEndTime - $callStartTime; + +echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL; +// Echo memory usage +echo date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , " MB" , EOL; + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , EOL; +echo 'File has been created in ' , getcwd() , EOL; diff --git a/Examples/runall.php b/Examples/runall.php index 3d94e4a5e..cad5b39af 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -102,6 +102,7 @@ , '40duplicateStyle.php' , '41password.php' , '42richText.php' + , '43mergeWorkbooks.php' , 'OOCalcReader.php' , 'OOCalcReaderPCLZip.php' , 'SylkReader.php' diff --git a/Examples/templates/43mergeBook1.xlsx b/Examples/templates/43mergeBook1.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6efc05a5db1c904f332e6ddf17c938adef9f4722 GIT binary patch literal 9629 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 literal 0 HcmV?d00001 diff --git a/Examples/templates/43mergeBook2.xlsx b/Examples/templates/43mergeBook2.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..1eb6035d491cc701da55926da1315bc127863bbe GIT binary patch literal 9618 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 literal 0 HcmV?d00001 From 87ba4290200bd83e2bde5203d2d813a2b59fcb0a Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sat, 1 Aug 2015 00:37:05 +0100 Subject: [PATCH 412/467] Improved masking for number format handling, particularly for datetime masks --- Classes/PHPExcel/Style/NumberFormat.php | 59 +++++++++++++------ .../PHPExcel/Style/NumberFormatDateTest.php | 35 +++++++++++ .../rawTestData/Style/NumberFormatDates.data | 6 ++ 3 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/Style/NumberFormatDateTest.php create mode 100644 unitTests/rawTestData/Style/NumberFormatDates.data diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index 8b7f300dc..20c4f4cbe 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -423,26 +423,43 @@ public function getHashCode() 'h' => 'g' ); + private static function setLowercaseCallback($matches) { + return mb_strtolower($matches[0]); + } + + private static function escapeQuotesCallback($matches) { + return '\\' . implode('\\', str_split($matches[1])); + } + private static function formatAsDate(&$value, &$format) { - // dvc: convert Excel formats to PHP date formats - // strip off first part containing e.g. [$-F800] or [$USD-409] // general syntax: [$<Currency string>-<language info>] // language info is in hexadecimal $format = preg_replace('/^(\[\$[A-Z]*-[0-9A-F]*\])/i', '', $format); - // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case - $format = strtolower($format); - - $format = strtr($format, self::$dateFormatReplacements); - if (!strpos($format, 'A')) { - // 24-hour time format - $format = strtr($format, self::$dateFormatReplacements24); - } else { - // 12-hour time format - $format = strtr($format, self::$dateFormatReplacements12); + // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case; + // but we don't want to change any quoted strings + $format = preg_replace_callback('/(?:^|")([^"]*)(?:$|")/', array('self', 'setLowercaseCallback'), $format); + + // Only process the non-quoted blocks for date format characters + $blocks = explode('"', $format); + foreach($blocks as $key => &$block) { + if ($key % 2 == 0) { + $block = strtr($block, self::$dateFormatReplacements); + if (!strpos($block, 'A')) { + // 24-hour time format + $block = strtr($block, self::$dateFormatReplacements24); + } else { + // 12-hour time format + $block = strtr($block, self::$dateFormatReplacements12); + } + } } + $format = implode('"', $blocks); + + // escape any quoted characters so that DateTime format() will render them correctly + $format = preg_replace_callback('/"(.*)"/U', array('self', 'escapeQuotesCallback'), $format); $dateObj = PHPExcel_Shared_Date::ExcelToPHPObject($value); $value = $dateObj->format($format); @@ -551,10 +568,12 @@ public static function toFormattedString($value = '0', $format = PHPExcel_Style_ return $value; } - // Get the sections, there can be up to four sections - $sections = explode(';', $format); + // Convert any escaped characters to quoted strings, e.g. (\T to "T") + $format = preg_replace('/(\\\(.))(?=(?:[^"]|"[^"]*")*$)/u', '"${2}"', $format); + // Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal) + $sections = preg_split('/(;)(?=(?:[^"]|"[^"]*")*$)/u', $format); - // Fetch the relevant section depending on whether number is positive, negative, or zero? + // Extract the relevant section depending on whether number is positive, negative, or zero? // Text not supported yet. // Here is how the sections apply to various values in Excel: // 1 section: [POSITIVE/NEGATIVE/ZERO/TEXT] @@ -595,9 +614,13 @@ public static function toFormattedString($value = '0', $format = PHPExcel_Style_ $format = preg_replace($color_regex, '', $format); // Let's begin inspecting the format and converting the value to a formatted string - if (preg_match('/^(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy]/i', $format)) { // datetime format + + // Check for date/time characters (not inside quotes) + if (preg_match('/(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy](?=(?:[^"]|"[^"]*")*$)/miu', $format, $matches)) { + // datetime format self::formatAsDate($value, $format); - } elseif (preg_match('/%$/', $format)) { // % number format + } elseif (preg_match('/%$/', $format)) { + // % number format self::formatAsPercentage($value, $format); } else { if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) { @@ -685,7 +708,7 @@ public static function toFormattedString($value = '0', $format = PHPExcel_Style_ } } if (preg_match('/\[\$(.*)\]/u', $format, $m)) { - // Currency or Accounting + // Currency or Accounting $currencyFormat = $m[0]; $currencyCode = $m[1]; list($currencyCode) = explode('-', $currencyCode); diff --git a/unitTests/Classes/PHPExcel/Style/NumberFormatDateTest.php b/unitTests/Classes/PHPExcel/Style/NumberFormatDateTest.php new file mode 100644 index 000000000..8ba828f73 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Style/NumberFormatDateTest.php @@ -0,0 +1,35 @@ +<?php + + +require_once 'testDataFileIterator.php'; + +class NumberFormatDateTest extends PHPUnit_Framework_TestCase +{ + + public function setUp() + { + if (!defined('PHPEXCEL_ROOT')) { + define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); + } + require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + + PHPExcel_Shared_String::setDecimalSeparator('.'); + PHPExcel_Shared_String::setThousandsSeparator(','); + } + + /** + * @dataProvider providerNumberFormat + */ + public function testFormatValueWithMask() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Style_NumberFormat','toFormattedString'), $args); + $this->assertEquals($expectedResult, $result); + } + + public function providerNumberFormat() + { + return new testDataFileIterator('rawTestData/Style/NumberFormatDates.data'); + } +} diff --git a/unitTests/rawTestData/Style/NumberFormatDates.data b/unitTests/rawTestData/Style/NumberFormatDates.data new file mode 100644 index 000000000..7c7754cd3 --- /dev/null +++ b/unitTests/rawTestData/Style/NumberFormatDates.data @@ -0,0 +1,6 @@ +22269.0625, 'dd-mm-yyyy hh:mm:ss', "19-12-1960 01:30:00" +22269.0625, 'MM/DD/YYYY HH:MM:SS', "12/19/1960 01:30:00" // Oasis uses upper-case +22269.0625, 'yyyy-mm-dd\Thh:mm:ss', "1960-12-19T01:30:00" // Date with plaintext escaped with a \ +22269.0625, 'yyyy-mm-dd"T"hh:mm:ss \Z', "1960-12-19T01:30:00 Z" // Date with plaintext in quotes +22269.0625, '"y-m-d" yyyy-mm-dd "h:m:s" hh:mm:ss', "y-m-d 1960-12-19 h:m:s 01:30:00" // Date with quoted formatting characters +22269.0625, '"y-m-d "yyyy-mm-dd" h:m:s "hh:mm:ss', "y-m-d 1960-12-19 h:m:s 01:30:00" // Date with quoted formatting characters From 941ab7d7392e6c2f07972ff46f0940623cba6b59 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 2 Aug 2015 00:40:16 +0100 Subject: [PATCH 413/467] Handle some discrepancies between the ECMA standard and actual internal number formats used by MS Excel --- Classes/PHPExcel/Style/NumberFormat.php | 36 ++++++++++++++++++++----- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index 20c4f4cbe..92869bf9c 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -243,6 +243,28 @@ public function setBuiltInFormatCode($pValue = 0) */ private static function fillBuiltInFormatCodes() { + // [MS-OI29500: Microsoft Office Implementation Information for ISO/IEC-29500 Standard Compliance] + // 18.8.30. numFmt (Number Format) + // + // The ECMA standard defines built-in format IDs + // 14: "mm-dd-yy" + // 22: "m/d/yy h:mm" + // 37: "#,##0 ;(#,##0)" + // 38: "#,##0 ;[Red](#,##0)" + // 39: "#,##0.00;(#,##0.00)" + // 40: "#,##0.00;[Red](#,##0.00)" + // 47: "mmss.0" + // KOR fmt 55: "yyyy-mm-dd" + // Excel defines built-in format IDs + // 14: "m/d/yyyy" + // 22: "m/d/yyyy h:mm" + // 37: "#,##0_);(#,##0)" + // 38: "#,##0_);[Red](#,##0)" + // 39: "#,##0.00_);(#,##0.00)" + // 40: "#,##0.00_);[Red](#,##0.00)" + // 47: "mm:ss.0" + // KOR fmt 55: "yyyy/mm/dd" + // Built-in format codes if (is_null(self::$builtInFormats)) { self::$builtInFormats = array(); @@ -259,7 +281,7 @@ private static function fillBuiltInFormatCodes() self::$builtInFormats[11] = '0.00E+00'; self::$builtInFormats[12] = '# ?/?'; self::$builtInFormats[13] = '# ??/??'; - self::$builtInFormats[14] = 'mm-dd-yy'; + self::$builtInFormats[14] = 'm/d/yyyy'; // Despite ECMA 'mm-dd-yy'; self::$builtInFormats[15] = 'd-mmm-yy'; self::$builtInFormats[16] = 'd-mmm'; self::$builtInFormats[17] = 'mmm-yy'; @@ -267,17 +289,17 @@ private static function fillBuiltInFormatCodes() self::$builtInFormats[19] = 'h:mm:ss AM/PM'; self::$builtInFormats[20] = 'h:mm'; self::$builtInFormats[21] = 'h:mm:ss'; - self::$builtInFormats[22] = 'm/d/yy h:mm'; + self::$builtInFormats[22] = 'm/d/yyyy h:mm'; // Despite ECMA 'm/d/yy h:mm'; - self::$builtInFormats[37] = '#,##0 ;(#,##0)'; - self::$builtInFormats[38] = '#,##0 ;[Red](#,##0)'; - self::$builtInFormats[39] = '#,##0.00;(#,##0.00)'; - self::$builtInFormats[40] = '#,##0.00;[Red](#,##0.00)'; + self::$builtInFormats[37] = '#,##0_);(#,##0)'; // Despite ECMA '#,##0 ;(#,##0)'; + self::$builtInFormats[38] = '#,##0_);[Red](#,##0)'; // Despite ECMA '#,##0 ;[Red](#,##0)'; + self::$builtInFormats[39] = '#,##0.00_);(#,##0.00)'; // Despite ECMA '#,##0.00;(#,##0.00)'; + self::$builtInFormats[40] = '#,##0.00_);[Red](#,##0.00)'; // Despite ECMA '#,##0.00;[Red](#,##0.00)'; self::$builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)'; self::$builtInFormats[45] = 'mm:ss'; self::$builtInFormats[46] = '[h]:mm:ss'; - self::$builtInFormats[47] = 'mmss.0'; + self::$builtInFormats[47] = 'mm:ss.0'; // Despite ECMA 'mmss.0'; self::$builtInFormats[48] = '##0.0E+0'; self::$builtInFormats[49] = '@'; From 8f7c2fd4645ffebdb7d194742534c755579f4c10 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 3 Aug 2015 00:33:29 +0100 Subject: [PATCH 414/467] Additional work on number format masks --- Classes/PHPExcel/Style/NumberFormat.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index 92869bf9c..f517df3b2 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -590,8 +590,9 @@ public static function toFormattedString($value = '0', $format = PHPExcel_Style_ return $value; } - // Convert any escaped characters to quoted strings, e.g. (\T to "T") + // Convert any other escaped characters to quoted strings, e.g. (\T to "T") $format = preg_replace('/(\\\(.))(?=(?:[^"]|"[^"]*")*$)/u', '"${2}"', $format); + // Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal) $sections = preg_split('/(;)(?=(?:[^"]|"[^"]*")*$)/u', $format); @@ -628,6 +629,10 @@ public static function toFormattedString($value = '0', $format = PHPExcel_Style_ break; } + // In Excel formats, "_" is used to add spacing, + // The following character indicates the size of the spacing, which we can't do in HTML, so we just use a standard space + $format = preg_replace('/_./', ' ', $format); + // Save format with color information for later use below $formatColor = $format; @@ -648,15 +653,6 @@ public static function toFormattedString($value = '0', $format = PHPExcel_Style_ if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) { $value = 'EUR ' . sprintf('%1.2f', $value); } else { - // In Excel formats, "_" is used to add spacing, which we can't do in HTML - $format = preg_replace('/_./', '', $format); - - // Some non-number characters are escaped with \, which we don't need - $format = preg_replace("/\\\\/", '', $format); -// Handle escaped characters, such as \" to display a literal " or \\ to display a literal \ -// $format = preg_replace('/(?<!\\\\)\"/', '', $format); -// $format = str_replace(array('\\"', '*'), array('"', ''), $format); - // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols $format = str_replace(array('"', '*'), '', $format); @@ -742,6 +738,9 @@ public static function toFormattedString($value = '0', $format = PHPExcel_Style_ } } + // Escape any escaped slashes to a single slash + $format = preg_replace("/\\\\/u", '\\', $format); + // Additional formatting provided by callback function if ($callBack !== null) { list($writerInstance, $function) = $callBack; From 663d9422056de325f388f9775cf609bcd9764dd7 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 3 Aug 2015 19:40:16 +0100 Subject: [PATCH 415/467] Fix to HTML generation with charts that fall outside of the main data area, and fix to show trailing `/` in folders for the jpgraph in examples --- Classes/PHPExcel/Writer/HTML.php | 3 ++- Examples/36chartreadwriteHTML.php | 2 +- Examples/36chartreadwritePDF.php | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index fddf7b27f..5c39ddc28 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -577,9 +577,10 @@ private function extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) } } } + $html = ''; $colMax++; - while ($row < $rowMax) { + while ($row <= $rowMax) { $html .= '<tr>'; for ($col = 'A'; $col != $colMax; ++$col) { $html .= '<td>'; diff --git a/Examples/36chartreadwriteHTML.php b/Examples/36chartreadwriteHTML.php index 3ee8242de..7fc26fdee 100644 --- a/Examples/36chartreadwriteHTML.php +++ b/Examples/36chartreadwriteHTML.php @@ -46,7 +46,7 @@ // Change these values to select the Rendering library that you wish to use // and its directory location on your server $rendererName = PHPExcel_Settings::CHART_RENDERER_JPGRAPH; -$rendererLibrary = 'jpgraph3.5.0b1/src'; +$rendererLibrary = 'jpgraph3.5.0b1/src/'; $rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary; diff --git a/Examples/36chartreadwritePDF.php b/Examples/36chartreadwritePDF.php index 0a428a2b6..24d1c857b 100644 --- a/Examples/36chartreadwritePDF.php +++ b/Examples/36chartreadwritePDF.php @@ -69,7 +69,7 @@ // Change these values to select the Rendering library that you wish to use // for Chart images, and its directory location on your server $rendererName = PHPExcel_Settings::CHART_RENDERER_JPGRAPH; -$rendererLibrary = 'jpgraph3.5.0b1/src'; +$rendererLibrary = 'jpgraph3.5.0b1/src/'; $rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary; From 6eae1393015beed089c59b3d571039359868e077 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Fri, 14 Aug 2015 19:50:24 +0100 Subject: [PATCH 416/467] We shouldn't override any of the built-in MS Excel values (values below id 164) But there's a lot of naughty homebrew xlsx writers that do use "reserved" id values that aren't actually used So we make allowance for them rather than lose formatting masks --- Classes/PHPExcel/Reader/Excel2007.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index c439bfc93..0303a0bd4 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -487,7 +487,9 @@ public function load($pFilename) $styles = array(); $cellStyles = array(); $xpath = self::getArrayItem($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); - $xmlStyles = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $xmlStyles = simplexml_load_string($this->securityScan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $numFmts = null; if ($xmlStyles && $xmlStyles->numFmts[0]) { $numFmts = $xmlStyles->numFmts[0]; @@ -508,7 +510,10 @@ public function load($pFilename) } } - if ((int)$xf["numFmtId"] < 164) { + // We shouldn't override any of the built-in MS Excel values (values below id 164) + // But there's a lot of naughty homebrew xlsx writers that do use "reserved" id values that aren't actually used + // So we make allowance for them rather than lose formatting masks + if ((int)$xf["numFmtId"] < 164 && PHPExcel_Style_NumberFormat::builtInFormatCodeIndex((int)$xf["numFmtId"]) !== false) { $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); } } @@ -516,8 +521,6 @@ public function load($pFilename) if (isset($xf["quotePrefix"])) { $quotePrefix = (boolean) $xf["quotePrefix"]; } - //$numFmt = str_replace('mm', 'i', $numFmt); - //$numFmt = str_replace('h', 'H', $numFmt); $style = (object) array( "numFmt" => $numFmt, From 18c6b498f875442fe552d99187c4dbedb95ed846 Mon Sep 17 00:00:00 2001 From: stchr <proverbs3V5-6> Date: Thu, 3 Sep 2015 15:41:46 +0200 Subject: [PATCH 417/467] Exclude /Examples and /unitTests from export. Not needed for production --- .gitattributes | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 1bc28be4b..da774df62 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,5 @@ /Build export-ignore /Documentation export-ignore -/Tests export-ignore +/Examples export-ignore +/unitTests export-ignore README.md export-ignore From 889b0a4b3ecc515aca27f66b86ebdacd84632b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Cantar=C3=ADn?= <omega_canta@yahoo.com> Date: Tue, 8 Sep 2015 14:47:25 -0300 Subject: [PATCH 418/467] Fix for #633 A typo in css syntax had nasty effects in exports. --- Classes/PHPExcel/Writer/HTML.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 5c39ddc28..7a41bb53f 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -1576,17 +1576,17 @@ private function setMargins(PHPExcel_Worksheet $pSheet) $htmlBody = 'body { '; $left = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()) . 'in; '; - $htmlPage .= 'left-margin: ' . $left; - $htmlBody .= 'left-margin: ' . $left; + $htmlPage .= 'margin-left: ' . $left; + $htmlBody .= 'margin-left: ' . $left; $right = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()) . 'in; '; - $htmlPage .= 'right-margin: ' . $right; - $htmlBody .= 'right-margin: ' . $right; + $htmlPage .= 'margin-right: ' . $right; + $htmlBody .= 'margin-right: ' . $right; $top = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()) . 'in; '; - $htmlPage .= 'top-margin: ' . $top; - $htmlBody .= 'top-margin: ' . $top; + $htmlPage .= 'margin-top: ' . $top; + $htmlBody .= 'margin-top: ' . $top; $bottom = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()) . 'in; '; - $htmlPage .= 'bottom-margin: ' . $bottom; - $htmlBody .= 'bottom-margin: ' . $bottom; + $htmlPage .= 'margin-bottom: ' . $bottom; + $htmlBody .= 'margin-bottom: ' . $bottom; $htmlPage .= "}\n"; $htmlBody .= "}\n"; From bc29a1c38ae866061cc419d253653db99e8da705 Mon Sep 17 00:00:00 2001 From: Darren Benney <cutenfuzzy@gmail.com> Date: Wed, 9 Sep 2015 15:30:00 +0100 Subject: [PATCH 419/467] Fix typo. Docs referenced IReader class incorrectly. --- Documentation/markdown/Overview/02-Architecture.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/markdown/Overview/02-Architecture.md b/Documentation/markdown/Overview/02-Architecture.md index d5af2ce6f..b59c18892 100644 --- a/Documentation/markdown/Overview/02-Architecture.md +++ b/Documentation/markdown/Overview/02-Architecture.md @@ -40,7 +40,7 @@ Just like desktop spreadsheet software, PHPExcel represents a spreadsheet contai On its own, PHPExcel does not provide the functionality to read from or write to a persisted spreadsheet (on disk or in a database). To provide that functionality, readers and writers can be used. -By default, the PHPExcel package provides some readers and writers, including one for the Open XML spreadsheet format (a.k.a. Excel 2007 file format). You are not limited to the default readers and writers, as you are free to implement the PHPExcel_Writer_IReader and PHPExcel_Writer_IWriter interface in a custom class. +By default, the PHPExcel package provides some readers and writers, including one for the Open XML spreadsheet format (a.k.a. Excel 2007 file format). You are not limited to the default readers and writers, as you are free to implement the PHPExcel_Reader_IReader and PHPExcel_Writer_IWriter interface in a custom class. ![02-readers-writers.png](./images/02-readers-writers.png "") From 78df8592e586ef312d61fb0c9b4993e7c383fdda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pat=20M=C3=A4chler?= <u@valio.ch> Date: Mon, 14 Sep 2015 15:57:45 +0200 Subject: [PATCH 420/467] Clarification on the license for details refer to https://github.com/PHPOffice/PHPExcel/pull/672 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a280b88e3..c3b3f0b44 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "keywords": ["PHP","Excel","OpenXML","xlsx","xls","spreadsheet"], "homepage": "http://phpexcel.codeplex.com/", "type": "library", - "license": "LGPL", + "license": "LGPL-2.1", "authors": [ { "name": "Maarten Balliauw", From 54738ea3db9a85aef85e9b4c8e4bb482ae35d5f6 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 14 Sep 2015 22:55:58 +0100 Subject: [PATCH 421/467] mbstring in composer --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index a280b88e3..c95c13398 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ ], "require": { "php": ">=5.2.0", + "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*" }, From 49d123e910b12ecdab66b23700aed513124371f3 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 17 Sep 2015 23:56:41 +0100 Subject: [PATCH 422/467] Fix to allow calculate formula against a workbook, without passing in a cell --- Classes/PHPExcel/Calculation.php | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 307db191b..809c57157 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2720,10 +2720,16 @@ public function calculateFormula($formula, $cellID = null, PHPExcel_Cell $pCell $this->_debugLog->clearLog(); $this->cyclicReferenceStack->clear(); - // Disable calculation cacheing because it only applies to cell calculations, not straight formulae - // But don't actually flush any cache - $resetCache = $this->getCalculationCacheEnabled(); - $this->calculationCacheEnabled = false; + if ($this->workbook !== null && $cellID === null && $pCell === null) { + $cellID = 'A1'; + $pCell = $this->workbook->getActiveSheet()->getCell($cellID); + } else { + // Disable calculation cacheing because it only applies to cell calculations, not straight formulae + // But don't actually flush any cache + $resetCache = $this->getCalculationCacheEnabled(); + $this->calculationCacheEnabled = false; + } + // Execute the calculation try { $result = self::unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); @@ -2731,8 +2737,10 @@ public function calculateFormula($formula, $cellID = null, PHPExcel_Cell $pCell throw new PHPExcel_Calculation_Exception($e->getMessage()); } - // Reset calculation cacheing to its previous state - $this->calculationCacheEnabled = $resetCache; + if ($this->workbook === null) { + // Reset calculation cacheing to its previous state + $this->calculationCacheEnabled = $resetCache; + } return $result; } From cd151ae2e4342f94f11f6b9e727c7cf1f149d15c Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 14 Oct 2015 23:23:19 +0100 Subject: [PATCH 423/467] Fix for problem with xlsx files overriding the reserved number format codes below 164 with custom codes --- Classes/PHPExcel/Reader/Excel2007.php | 3 +-- Classes/PHPExcel/Style/NumberFormat.php | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 0303a0bd4..5ab5a42b7 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -500,7 +500,6 @@ public function load($pFilename) if (!$this->readDataOnly && $xmlStyles) { foreach ($xmlStyles->cellXfs->xf as $xf) { $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; - if ($xf["numFmtId"]) { if (isset($numFmts)) { $tmpNumFmt = self::getArrayItem($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); @@ -513,7 +512,7 @@ public function load($pFilename) // We shouldn't override any of the built-in MS Excel values (values below id 164) // But there's a lot of naughty homebrew xlsx writers that do use "reserved" id values that aren't actually used // So we make allowance for them rather than lose formatting masks - if ((int)$xf["numFmtId"] < 164 && PHPExcel_Style_NumberFormat::builtInFormatCodeIndex((int)$xf["numFmtId"]) !== false) { + if ((int)$xf["numFmtId"] < 164 && PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]) !== '') { $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); } } diff --git a/Classes/PHPExcel/Style/NumberFormat.php b/Classes/PHPExcel/Style/NumberFormat.php index f517df3b2..1b72cda92 100644 --- a/Classes/PHPExcel/Style/NumberFormat.php +++ b/Classes/PHPExcel/Style/NumberFormat.php @@ -338,7 +338,6 @@ public static function builtInFormatCode($pIndex) // Ensure built-in format codes are available self::fillBuiltInFormatCodes(); - // Lookup format code if (isset(self::$builtInFormats[$pIndex])) { return self::$builtInFormats[$pIndex]; From ba04463cc954264546d94c109e6cb903b01abe41 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 15 Oct 2015 23:07:22 +0100 Subject: [PATCH 424/467] Remove savedPrecision from Calculation Engine --- Classes/PHPExcel/Calculation.php | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index 809c57157..d6fdd9ef5 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -208,12 +208,12 @@ class PHPExcel_Calculation public $cyclicFormulaCount = 1; /** - * Precision used for calculations + * Epsilon Precision used for comparisons in calculations * * @var integer * */ - private $savedPrecision = 14; + private $delta = 0.0000000000001; /** @@ -2070,12 +2070,7 @@ class PHPExcel_Calculation private function __construct(PHPExcel $workbook = null) { - $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; - $this->savedPrecision = ini_get('precision'); - if ($this->savedPrecision < $setPrecision) { - ini_set('precision', $setPrecision); - } - $this->delta = 1 * pow(10, -$setPrecision); + $this->delta = 1 * pow(10, 0 - ini_get('precision')); if ($workbook !== null) { self::$workbookSets[$workbook->getID()] = $this; @@ -2087,13 +2082,6 @@ private function __construct(PHPExcel $workbook = null) } - public function __destruct() - { - if ($this->savedPrecision != ini_get('precision')) { - ini_set('precision', $this->savedPrecision); - } - } - private static function loadLocales() { $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/'; From 6a8fca703ca1b1de44d4acf1c1695ea1c0196085 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 28 Oct 2015 00:47:01 +0000 Subject: [PATCH 425/467] Fix to MEDIAN() function --- Classes/PHPExcel/Calculation/Statistical.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Calculation/Statistical.php b/Classes/PHPExcel/Calculation/Statistical.php index 500f95096..1a33610fc 100644 --- a/Classes/PHPExcel/Calculation/Statistical.php +++ b/Classes/PHPExcel/Calculation/Statistical.php @@ -2337,7 +2337,7 @@ public static function MEDIAN() if ($mValueCount == floor($mValueCount)) { $returnValue = ($mArgs[$mValueCount--] + $mArgs[$mValueCount]) / 2; } else { - $mValueCount == floor($mValueCount); + $mValueCount = floor($mValueCount); $returnValue = $mArgs[$mValueCount]; } } From ecdb406d4da9741d8efe31e23cc9f641b644effb Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 15 Nov 2015 18:04:45 +0000 Subject: [PATCH 426/467] A mass of small changes including * Implementation of the Excel SUMIFS function * Fixes for Readers to handle various malformed spreadsheet file formats * Better error handling in Iterators * Suppression of Chart formula evaluation on save if formula evaluation is disabled * Changes for PHP7 * Hopefully fixed a memory issue with unsetting PHPExcel object failing to unset the calculation engine --- Classes/PHPExcel.php | 4 +- Classes/PHPExcel/Calculation.php | 28 +++------ Classes/PHPExcel/Calculation/Financial.php | 6 +- Classes/PHPExcel/Calculation/Functions.php | 2 - Classes/PHPExcel/Calculation/MathTrig.php | 60 +++++++++++++++++++ Classes/PHPExcel/Reader/Excel2003XML.php | 6 +- Classes/PHPExcel/Reader/Excel2007.php | 11 +++- Classes/PHPExcel/Reader/Excel2007/Chart.php | 4 -- Classes/PHPExcel/Reader/Excel5.php | 2 +- Classes/PHPExcel/Shared/CodePage.php | 12 ++++ Classes/PHPExcel/Shared/ZipArchive.php | 54 ++++++++--------- Classes/PHPExcel/Worksheet.php | 4 +- Classes/PHPExcel/Worksheet/ColumnIterator.php | 8 +++ Classes/PHPExcel/Worksheet/RowIterator.php | 10 +++- Classes/PHPExcel/Writer/Excel2007.php | 2 +- Classes/PHPExcel/Writer/Excel2007/Chart.php | 10 +++- Classes/PHPExcel/Writer/Excel2007/Rels.php | 4 +- Examples/.gitignore | 6 +- Examples/01simple.php | 8 +++ Examples/28iterator.php | 26 ++++++-- changelog.txt | 6 +- composer.json | 2 +- .../PHPExcel/Calculation/MathTrigTest.php | 16 +++++ .../PHPExcel/Worksheet/ColumnIteratorTest.php | 8 +++ .../PHPExcel/Worksheet/RowIteratorTest.php | 18 ++++-- .../Calculation/MathTrig/SUMIFS.data | 6 ++ 26 files changed, 234 insertions(+), 89 deletions(-) create mode 100644 unitTests/rawTestData/Calculation/MathTrig/SUMIFS.data diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index c3ec05197..dcba06770 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -364,7 +364,7 @@ public function getSheetByCodeName($pName = '') public function __construct() { $this->uniqueID = uniqid(); - $this->calculationEngine = PHPExcel_Calculation::getInstance($this); + $this->calculationEngine = new PHPExcel_Calculation($this); // Initialise worksheet collection and add one worksheet $this->workSheetCollection = array(); @@ -395,7 +395,7 @@ public function __construct() */ public function __destruct() { - PHPExcel_Calculation::unsetInstance($this); + $this->calculationEngine = null; $this->disconnectWorksheets(); } diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index d6fdd9ef5..a2d9ab8eb 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -1497,7 +1497,7 @@ class PHPExcel_Calculation 'OFFSET' => array( 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', - 'argumentCount' => '3,5', + 'argumentCount' => '3-5', 'passCellReference' => true, 'passByReference' => array(true) ), @@ -1814,8 +1814,8 @@ class PHPExcel_Calculation ), 'SUMIFS' => array( 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', - 'argumentCount' => '?' + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIFS', + 'argumentCount' => '3+' ), 'SUMPRODUCT' => array( 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, @@ -2068,14 +2068,10 @@ class PHPExcel_Calculation ); - private function __construct(PHPExcel $workbook = null) + public function __construct(PHPExcel $workbook = null) { $this->delta = 1 * pow(10, 0 - ini_get('precision')); - if ($workbook !== null) { - self::$workbookSets[$workbook->getID()] = $this; - } - $this->workbook = $workbook; $this->cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->cyclicReferenceStack); @@ -2104,16 +2100,15 @@ private static function loadLocales() public static function getInstance(PHPExcel $workbook = null) { if ($workbook !== null) { - if (isset(self::$workbookSets[$workbook->getID()])) { - return self::$workbookSets[$workbook->getID()]; + $instance = $workbook->getCalculationEngine(); + if (isset($instance)) { + return $instance; } - return new PHPExcel_Calculation($workbook); } if (!isset(self::$instance) || (self::$instance === null)) { self::$instance = new PHPExcel_Calculation(); } - return self::$instance; } @@ -2121,15 +2116,10 @@ public static function getInstance(PHPExcel $workbook = null) * Unset an instance of this class * * @access public - * @param PHPExcel $workbook Injected workbook identifying the instance to unset */ - public static function unsetInstance(PHPExcel $workbook = null) + public function __destruct() { - if ($workbook !== null) { - if (isset(self::$workbookSets[$workbook->getID()])) { - unset(self::$workbookSets[$workbook->getID()]); - } - } + $this->workbook = null; } /** diff --git a/Classes/PHPExcel/Calculation/Financial.php b/Classes/PHPExcel/Calculation/Financial.php index 8865e56f3..fdf489400 100644 --- a/Classes/PHPExcel/Calculation/Financial.php +++ b/Classes/PHPExcel/Calculation/Financial.php @@ -2146,9 +2146,9 @@ public static function XIRR($values, $dates, $guess = 0.1) if ((!is_array($values)) && (!is_array($dates))) { return PHPExcel_Calculation_Functions::VALUE(); } - $values = PHPExcel_Calculation_Functions::flattenArray($values); - $dates = PHPExcel_Calculation_Functions::flattenArray($dates); - $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $dates = PHPExcel_Calculation_Functions::flattenArray($dates); + $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); if (count($values) != count($dates)) { return PHPExcel_Calculation_Functions::NaN(); } diff --git a/Classes/PHPExcel/Calculation/Functions.php b/Classes/PHPExcel/Calculation/Functions.php index 9e7a5db10..5a1e5ee5a 100644 --- a/Classes/PHPExcel/Calculation/Functions.php +++ b/Classes/PHPExcel/Calculation/Functions.php @@ -555,10 +555,8 @@ public static function N($value = null) case 'float': case 'integer': return $value; - break; case 'boolean': return (integer) $value; - break; case 'string': // Errors if ((strlen($value) > 0) && ($value{0} == '#')) { diff --git a/Classes/PHPExcel/Calculation/MathTrig.php b/Classes/PHPExcel/Calculation/MathTrig.php index dae2aa1ef..894ba9cf0 100644 --- a/Classes/PHPExcel/Calculation/MathTrig.php +++ b/Classes/PHPExcel/Calculation/MathTrig.php @@ -1220,6 +1220,66 @@ public static function SUMIF($aArgs, $condition, $sumArgs = array()) } + /** + * SUMIFS + * + * Counts the number of cells that contain numbers within the list of arguments + * + * Excel Function: + * SUMIFS(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be summed. + * @return float + */ + public static function SUMIFS() { + $arrayList = func_get_args(); + + $sumArgs = PHPExcel_Calculation_Functions::flattenArray(array_shift($arrayList)); + + while (count($arrayList) > 0) { + $aArgsArray[] = PHPExcel_Calculation_Functions::flattenArray(array_shift($arrayList)); + $conditions[] = PHPExcel_Calculation_Functions::ifCondition(array_shift($arrayList)); + } + + // Loop through each set of arguments and conditions + foreach ($conditions as $index => $condition) { + $aArgs = $aArgsArray[$index]; + $wildcard = false; + if ((strpos($condition, '*') !== false) || (strpos($condition, '?') !== false)) { + // * and ? are wildcard characters. + // Use ~* and ~? for literal star and question mark + // Code logic doesn't yet handle escaping + $condition = trim(ltrim($condition, '=<>'), '"'); + $wildcard = true; + } + // Loop through arguments + foreach ($aArgs as $key => $arg) { + if ($wildcard) { + if (!fnmatch($condition, $arg, FNM_CASEFOLD)) { + // Is it a value within our criteria + $sumArgs[$key] = 0.0; + } + } else { + if (!is_numeric($arg)) { + $arg = PHPExcel_Calculation::wrapResult(strtoupper($arg)); + } + $testCondition = '='.$arg.$condition; + if (!PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + // Is it a value within our criteria + $sumArgs[$key] = 0.0; + } + } + } + } + + // Return + return array_sum($sumArgs); + } + + /** * SUMPRODUCT * diff --git a/Classes/PHPExcel/Reader/Excel2003XML.php b/Classes/PHPExcel/Reader/Excel2003XML.php index fb1ebc01b..c007f9bbc 100644 --- a/Classes/PHPExcel/Reader/Excel2003XML.php +++ b/Classes/PHPExcel/Reader/Excel2003XML.php @@ -401,11 +401,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) $style_ss = $style->attributes($namespaces['ss']); $styleID = (string) $style_ss['ID']; // echo 'Style ID = '.$styleID.'<br />'; - if ($styleID == 'Default') { - $this->styles['Default'] = array(); - } else { - $this->styles[$styleID] = $this->styles['Default']; - } + $this->styles[$styleID] = (isset($this->styles['Default'])) ? $this->styles['Default'] : array(); foreach ($style as $styleType => $styleData) { $styleAttributes = $styleData->attributes($namespaces['ss']); // echo $styleType.'<br />'; diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index 5ab5a42b7..bf387a098 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -307,10 +307,17 @@ private function getFromZipArchive($archive, $fileName = '') } $fileName = PHPExcel_Shared_File::realpath($fileName); + // Sadly, some 3rd party xlsx generators don't use consistent case for filenaming + // so we need to load case-insensitively from the zip file + // Apache POI fixes - $contents = $archive->getFromName($fileName); + $contents = $archive->getFromIndex( + $archive->locateName($fileName, ZIPARCHIVE::FL_NOCASE) + ); if ($contents === false) { - $contents = $archive->getFromName(substr($fileName, 1)); + $contents = $archive->getFromIndex( + $archive->locateName(substr($fileName, 1), ZIPARCHIVE::FL_NOCASE) + ); } return $contents; diff --git a/Classes/PHPExcel/Reader/Excel2007/Chart.php b/Classes/PHPExcel/Reader/Excel2007/Chart.php index 88f336b38..590bf2d8f 100644 --- a/Classes/PHPExcel/Reader/Excel2007/Chart.php +++ b/Classes/PHPExcel/Reader/Excel2007/Chart.php @@ -351,10 +351,6 @@ private static function chartDataSeriesValues($seriesValueSet, $dataType = 'n') } } - if (empty($seriesVal)) { - $seriesVal = null; - } - return array( 'formatCode' => $formatCode, 'pointCount' => $pointCount, diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index ec22fe5cf..770d43569 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -1753,7 +1753,7 @@ private function readFilepass() // move stream pointer to next record $this->pos += 4 + $length; - + if (!$this->verifyPassword('VelvetSweatshop', substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->md5Ctxt)) { throw new PHPExcel_Reader_Exception('Decryption password incorrect'); } diff --git a/Classes/PHPExcel/Shared/CodePage.php b/Classes/PHPExcel/Shared/CodePage.php index b9df3b4d7..b3e440e29 100644 --- a/Classes/PHPExcel/Shared/CodePage.php +++ b/Classes/PHPExcel/Shared/CodePage.php @@ -116,18 +116,30 @@ public static function NumberToName($codePage = 1252) return 'CP950'; // Macintosh Chinese Traditional case 10003: return 'CP1361'; // Macintosh Korean + case 10004: + return 'MACARABIC'; // Apple Arabic + case 10005: + return 'MACHEBREW'; // Apple Hebrew case 10006: return 'MACGREEK'; // Macintosh Greek case 10007: return 'MACCYRILLIC'; // Macintosh Cyrillic case 10008: return 'CP936'; // Macintosh - Simplified Chinese (GB 2312) + case 10010: + return 'MACROMANIA'; // Macintosh Romania + case 10017: + return 'MACUKRAINE'; // Macintosh Ukraine + case 10021: + return 'MACTHAI'; // Macintosh Thai case 10029: return 'MACCENTRALEUROPE'; // Macintosh Central Europe case 10079: return 'MACICELAND'; // Macintosh Icelandic case 10081: return 'MACTURKISH'; // Macintosh Turkish + case 10082: + return 'MACCROATIAN'; // Macintosh Croatian case 21010: return 'UTF-16LE'; // UTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE case 32768: diff --git a/Classes/PHPExcel/Shared/ZipArchive.php b/Classes/PHPExcel/Shared/ZipArchive.php index 806a2febd..9eac8cae0 100644 --- a/Classes/PHPExcel/Shared/ZipArchive.php +++ b/Classes/PHPExcel/Shared/ZipArchive.php @@ -107,17 +107,19 @@ public function addFromString($localname, $contents) */ public function locateName($fileName) { + $fileName = strtolower($fileName); + $list = $this->zip->listContent(); $listCount = count($list); - $list_index = -1; + $index = -1; for ($i = 0; $i < $listCount; ++$i) { - if (strtolower($list[$i]["filename"]) == strtolower($fileName) || - strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { - $list_index = $i; + if (strtolower($list[$i]["filename"]) == $fileName || + strtolower($list[$i]["stored_filename"]) == $fileName) { + $index = $i; break; } } - return ($list_index > -1); + return ($index > -1) ? $index : false; } /** @@ -128,32 +130,30 @@ public function locateName($fileName) */ public function getFromName($fileName) { - $list = $this->zip->listContent(); - $listCount = count($list); - $list_index = -1; - for ($i = 0; $i < $listCount; ++$i) { - if (strtolower($list[$i]["filename"]) == strtolower($fileName) || - strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { - $list_index = $i; - break; - } - } + $index = $this->locateName($fileName); - $extracted = ""; - if ($list_index != -1) { - $extracted = $this->zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); + if ($index !== false) { + $extracted = $this->getFromIndex($index); } else { - $filename = substr($fileName, 1); - $list_index = -1; - for ($i = 0; $i < $listCount; ++$i) { - if (strtolower($list[$i]["filename"]) == strtolower($fileName) || - strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { - $list_index = $i; - break; - } + $fileName = substr($fileName, 1); + $index = $this->locateName($fileName); + if ($index === false) { + return false; } - $extracted = $this->zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); + $extracted = $this->zip->getFromIndex($index); } + + $contents = $extracted; + if ((is_array($extracted)) && ($extracted != 0)) { + $contents = $extracted[0]["content"]; + } + + return $contents; + } + + public function getFromIndex($index) { + $extracted = $this->zip->extractByIndex($index, PCLZIP_OPT_EXTRACT_AS_STRING); + $contents = ''; if ((is_array($extracted)) && ($extracted != 0)) { $contents = $extracted[0]["content"]; } diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 0f44c7744..51470c3e8 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -861,10 +861,10 @@ public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = t $this->title = $pValue; $this->dirty = true; - if ($this->parent) { + if ($this->parent && $this->parent->getCalculationEngine()) { // New title $newTitle = $this->getTitle(); - PHPExcel_Calculation::getInstance($this->parent) + $this->parent->getCalculationEngine() ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); if ($updateFormulaCellReferences) { PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->parent, $oldTitle, $newTitle); diff --git a/Classes/PHPExcel/Worksheet/ColumnIterator.php b/Classes/PHPExcel/Worksheet/ColumnIterator.php index 270bca65e..0db3e5347 100644 --- a/Classes/PHPExcel/Worksheet/ColumnIterator.php +++ b/Classes/PHPExcel/Worksheet/ColumnIterator.php @@ -85,11 +85,19 @@ public function __destruct() * * @param integer $startColumn The column address at which to start iterating * @return PHPExcel_Worksheet_ColumnIterator + * @throws PHPExcel_Exception */ public function resetStart($startColumn = 'A') { $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; + if ($startColumnIndex > PHPExcel_Cell::columnIndexFromString($this->subject->getHighestColumn()) - 1) { + throw new PHPExcel_Exception("Start column ({$startColumn}) is beyond highest column ({$this->subject->getHighestColumn()})"); + } + $this->startColumn = $startColumnIndex; + if ($this->endColumn < $this->startColumn) { + $this->endColumn = $this->startColumn; + } $this->seek($startColumn); return $this; diff --git a/Classes/PHPExcel/Worksheet/RowIterator.php b/Classes/PHPExcel/Worksheet/RowIterator.php index 6c88d50c7..9ddb3e030 100644 --- a/Classes/PHPExcel/Worksheet/RowIterator.php +++ b/Classes/PHPExcel/Worksheet/RowIterator.php @@ -64,7 +64,7 @@ class PHPExcel_Worksheet_RowIterator implements Iterator * @param integer $startRow The row number at which to start iterating * @param integer $endRow Optionally, the row number at which to stop iterating */ - public function __construct(PHPExcel_Worksheet $subject = null, $startRow = 1, $endRow = null) + public function __construct(PHPExcel_Worksheet $subject, $startRow = 1, $endRow = null) { // Set subject $this->subject = $subject; @@ -85,10 +85,18 @@ public function __destruct() * * @param integer $startRow The row number at which to start iterating * @return PHPExcel_Worksheet_RowIterator + * @throws PHPExcel_Exception */ public function resetStart($startRow = 1) { + if ($startRow > $this->subject->getHighestRow()) { + throw new PHPExcel_Exception("Start row ({$startRow}) is beyond highest row ({$this->subject->getHighestRow()})"); + } + $this->startRow = $startRow; + if ($this->endRow < $this->startRow) { + $this->endRow = $this->startRow; + } $this->seek($startRow); return $this; diff --git a/Classes/PHPExcel/Writer/Excel2007.php b/Classes/PHPExcel/Writer/Excel2007.php index 8f2eaa000..11d354b4a 100644 --- a/Classes/PHPExcel/Writer/Excel2007.php +++ b/Classes/PHPExcel/Writer/Excel2007.php @@ -297,7 +297,7 @@ public function save($pFilename = null) $charts = $this->spreadSheet->getSheet($i)->getChartCollection(); if (count($charts) > 0) { foreach ($charts as $chart) { - $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart)); + $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas)); $chartCount++; } } diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index ebe0018f2..c0f86bf20 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -27,6 +27,8 @@ */ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPart { + protected $calculateCellValues; + /** * Write charts to XML format * @@ -35,8 +37,10 @@ class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPa * @return string XML Output * @throws PHPExcel_Writer_Exception */ - public function writeChart(PHPExcel_Chart $pChart = null) + public function writeChart(PHPExcel_Chart $pChart = null, $calculateCellValues = true) { + $this->calculateCellValues = $calculateCellValues; + // Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { @@ -45,7 +49,9 @@ public function writeChart(PHPExcel_Chart $pChart = null) $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); } // Ensure that data series values are up-to-date before we save - $pChart->refresh(); + if ($this->calculateCellValues) { + $pChart->refresh(); + } // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); diff --git a/Classes/PHPExcel/Writer/Excel2007/Rels.php b/Classes/PHPExcel/Writer/Excel2007/Rels.php index dd1faf9b1..14ff33710 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Rels.php +++ b/Classes/PHPExcel/Writer/Excel2007/Rels.php @@ -88,7 +88,7 @@ public function writeRelationships(PHPExcel $pPHPExcel = null) ); // a custom UI in workbook ? if ($pPHPExcel->hasRibbon()) { - $this->_writeRelationShip( + $this->writeRelationShip( $objWriter, 5, 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', @@ -162,7 +162,7 @@ public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) // Relationships for vbaProject if needed // id : just after the last sheet if ($pPHPExcel->hasMacros()) { - $this->_writeRelationShip( + $this->writeRelationShip( $objWriter, ($i + 1 + 3), 'http://schemas.microsoft.com/office/2006/relationships/vbaProject', diff --git a/Examples/.gitignore b/Examples/.gitignore index 1888a98fa..d53fd7fab 100644 --- a/Examples/.gitignore +++ b/Examples/.gitignore @@ -1,3 +1,5 @@ - *.xls -*.xlsx \ No newline at end of file +*.xlsx +*.csv +*.jpg +*.pdf diff --git a/Examples/01simple.php b/Examples/01simple.php index 5e1912b80..e9671be1e 100644 --- a/Examples/01simple.php +++ b/Examples/01simple.php @@ -71,6 +71,14 @@ $objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true); +$value = "-ValueA\n-Value B\n-Value C"; +$objPHPExcel->getActiveSheet()->setCellValue('A10', $value); +$objPHPExcel->getActiveSheet()->getRowDimension(10)->setRowHeight(-1); +$objPHPExcel->getActiveSheet()->getStyle('A10')->getAlignment()->setWrapText(true); +$objPHPExcel->getActiveSheet()->getStyle('A10')->setQuotePrefix(true); + + + // Rename worksheet echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Simple'); diff --git a/Examples/28iterator.php b/Examples/28iterator.php index 92c4192a5..1ba9cbee0 100644 --- a/Examples/28iterator.php +++ b/Examples/28iterator.php @@ -38,15 +38,11 @@ require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; -if (!file_exists("05featuredemo.xlsx")) { - exit("Please run 05featuredemo.php first." . EOL); -} - echo date('H:i:s') , " Load from Excel2007 file" , EOL; $objReader = PHPExcel_IOFactory::createReader('Excel2007'); -$objPHPExcel = $objReader->load("05featuredemo.xlsx"); +$objPHPExcel = $objReader->load("./templates/28iterators.xlsx"); -echo date('H:i:s') , " Iterate worksheets" , EOL; +echo date('H:i:s') , " Iterate worksheets by Row" , EOL; foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) { echo 'Worksheet - ' , $worksheet->getTitle() , EOL; @@ -64,5 +60,23 @@ } +echo date('H:i:s') , " Iterate worksheets by Column" , EOL; +foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) { + echo 'Worksheet - ' , $worksheet->getTitle() , EOL; + + foreach ($worksheet->getColumnIterator() as $column) { + echo ' Column index - ' , $column->getColumnIndex() , EOL; + + $cellIterator = $column->getCellIterator(); + $cellIterator->setIterateOnlyExistingCells(true); // Loop all cells, even if it is not set + foreach ($cellIterator as $cell) { + if (!is_null($cell)) { + echo ' Cell - ' , $cell->getCoordinate() , ' - ' , $cell->getCalculatedValue() , EOL; + } + } + } +} + + // Echo memory peak usage echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; diff --git a/changelog.txt b/changelog.txt index eaefe2aae..4d1605b4e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -26,8 +26,11 @@ Planned for 1.8.2 - Bugfix: (MBaker) - Fix to getCell() method when cell reference includes a worksheet reference - Bugfix: (ncrypthic) Work Item GH-570 - Ignore inlineStr type if formula element exists +- Bugfix: (hernst42) Work Item GH-709 - Fixed missing renames of writeRelationShip (from _writeRelationShip) - General: (umpirsky) Work Item GH-548 - Optimize vlookup() sort - Bugfix: (MBaker) Work Item GH-554 - Whitespace after toRichTextObject() +- Feature: (MBaker) - Initial implementation of SUMIFS() function +- Feature: (MBaker) - Additional codepages 2015-04-30 (v1.8.1): @@ -68,8 +71,7 @@ Planned for 1.8.2 (see http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion for an explanation of XEE injection) attacks Reference CVE-2015-3542 - Identification of problem courtesy of Dawid Golunski (Pentest Ltd.) - - 2014-03-02 (v1.8.0): +2014-03-02 (v1.8.0): - Bugfix: (MBaker) Work item CP19830 - Undefined variable: fileHandle in CSV Reader - Bugfix: (MBaker) Work item CP19968 - Out of memory in style/supervisor.php - Bugfix: (MBaker) - Style error with merged cells in PDF Writer diff --git a/composer.json b/composer.json index 188f3af2c..81e83e792 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": ">=5.2.0", + "php": "^5.2|^7.0", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*" diff --git a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php index 40d1c5050..2f2bc2b54 100644 --- a/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php @@ -418,6 +418,22 @@ public function providerSERIESSUM() return new testDataFileIterator('rawTestData/Calculation/MathTrig/SERIESSUM.data'); } + /** + * @dataProvider providerSUMIFS + */ + public function testSUMIFS() + { + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SUMIFS'), $args); + $this->assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSUMIFS() + { + return new testDataFileIterator('rawTestData/Calculation/MathTrig/SUMIFS.data'); + } + /** * @dataProvider providerSUMSQ */ diff --git a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php index e013210e1..20108e850 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php @@ -68,6 +68,14 @@ public function testIteratorSeekAndPrev() } } + /** + * @expectedException PHPExcel_Exception + */ + public function testStartOutOfRange() + { + $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'IA', 'IV'); + } + /** * @expectedException PHPExcel_Exception */ diff --git a/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php index ec0b2796f..346941c37 100644 --- a/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php +++ b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php @@ -56,16 +56,24 @@ public function testIteratorStartEndRange() public function testIteratorSeekAndPrev() { $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); - $columnIndexResult = 4; - $iterator->seek(4); - $this->assertEquals($columnIndexResult, $iterator->key()); + $rowIndexResult = 4; + $iterator->seek($rowIndexResult); + $this->assertEquals($rowIndexResult, $iterator->key()); - for ($i = 1; $i < $columnIndexResult-1; $i++) { + for ($i = 1; $i < $rowIndexResult-1; $i++) { $iterator->prev(); - $this->assertEquals($columnIndexResult - $i, $iterator->key()); + $this->assertEquals($rowIndexResult - $i, $iterator->key()); } } + /** + * @expectedException PHPExcel_Exception + */ + public function testStartOutOfRange() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 256, 512); + } + /** * @expectedException PHPExcel_Exception */ diff --git a/unitTests/rawTestData/Calculation/MathTrig/SUMIFS.data b/unitTests/rawTestData/Calculation/MathTrig/SUMIFS.data new file mode 100644 index 000000000..8d85945dc --- /dev/null +++ b/unitTests/rawTestData/Calculation/MathTrig/SUMIFS.data @@ -0,0 +1,6 @@ +{12.25;10.5;5.1;8.35;13.45;7.95;6;4.55}, {2013;2012;2012;2013;2013;2011;2013;2009}, "=2013", 40.05 +{12.25;10.5;5.1;8.35;13.45;7.95;6;4.55}, {"Oranges";"Bananas";"Apples";"Bananas";"Oranges";"Apples";"Pears";"Oranges"}, "=Oranges", 30.25 +{12.25;10.5;5.1;8.35;13.45;7.95;6;4.55}, {2013;2012;2012;2013;2013;2011;2013;2009}, "=2013", {"Oranges";"Bananas";"Apples";"Bananas";"Oranges";"Apples";"Pears";"Oranges"}, "=Oranges", 25.7 +{12.25;10.5;5.1;8.35;13.45;7.95;6;4.55}, {2013;2012;2012;2013;2013;2011;2013;2009}, ">=2009", {"Oranges";"Bananas";"Apples";"Bananas";"Oranges";"Apples";"Pears";"Oranges"}, "=Oranges", {2013;2012;2012;2013;2013;2011;2013;2009}, "<=2012", 4.55 +{12.25;10.5;5.1;8.35;13.45;7.95;6;4.55}, {2013;2012;2012;2013;2013;2011;2013;2009}, ">=2009", {"Oranges";"Bananas";"Apples";"Bananas";"Oranges";"Apples";"Pears";"Oranges"}, "=B*", 18.85 +{12.25;10.5;5.1;8.35;13.45;7.95;6;4.55}, {2013;2012;2012;2013;2013;2011;2013;2009}, ">=2009", {"Oranges";"Bananas";"Apples";"Bananas";"Oranges";"Apples";"Pears";"Oranges"}, "=B?nanas", 18.85 From 65310d164c4cf1eca6c2344f866f195371cdb5d2 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Fri, 27 Nov 2015 01:02:37 +0000 Subject: [PATCH 427/467] Change PCLZip constructor name to __construct ready for PHP7 --- Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php index 263137d1b..a5a9b0a8b 100644 --- a/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php +++ b/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -212,7 +212,7 @@ class PclZip // Note that no real action is taken, if the archive does not exist it is not // created. Use create() for that. // -------------------------------------------------------------------------------- - public function PclZip($p_zipname) + public function __construct($p_zipname) { // ----- Tests the zlib From 6f43f0429b67c772381e64409496a7d1c77d8b66 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 6 Dec 2015 16:04:32 +0000 Subject: [PATCH 428/467] Minor tweaks --- Classes/PHPExcel.php | 17 +++++++++-------- Classes/PHPExcel/Calculation.php | 4 ++-- Classes/PHPExcel/Reader/HTML.php | 2 +- Classes/PHPExcel/Writer/Excel2007/Worksheet.php | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Classes/PHPExcel.php b/Classes/PHPExcel.php index dcba06770..b8dbe0efd 100644 --- a/Classes/PHPExcel.php +++ b/Classes/PHPExcel.php @@ -141,7 +141,7 @@ class PHPExcel /** * The workbook has macros ? * - * @return true if workbook has macros, false if not + * @return boolean true if workbook has macros, false if not */ public function hasMacros() { @@ -312,7 +312,7 @@ public function getRibbonBinObjects($What = 'all') /** * This workbook have a custom UI ? * - * @return true|false + * @return boolean true|false */ public function hasRibbon() { @@ -322,7 +322,7 @@ public function hasRibbon() /** * This workbook have additionnal object for the ribbon ? * - * @return true|false + * @return boolean true|false */ public function hasRibbonBinObjects() { @@ -621,7 +621,7 @@ public function getSheetByName($pName = '') * Get index for sheet * * @param PHPExcel_Worksheet $pSheet - * @return Sheet index + * @return int Sheet index * @throws PHPExcel_Exception */ public function getIndex(PHPExcel_Worksheet $pSheet) @@ -640,7 +640,7 @@ public function getIndex(PHPExcel_Worksheet $pSheet) * * @param string $sheetName Sheet name to modify index for * @param int $newIndex New index for the sheet - * @return New sheet index + * @return int New sheet index * @throws PHPExcel_Exception */ public function setIndexByName($sheetName, $newIndex) @@ -782,7 +782,7 @@ public function getNamedRanges() * Add named range * * @param PHPExcel_NamedRange $namedRange - * @return PHPExcel + * @return boolean */ public function addNamedRange(PHPExcel_NamedRange $namedRange) { @@ -908,7 +908,7 @@ public function getCellXfByIndex($pIndex = 0) * Get cellXf by hash code * * @param string $pValue - * @return PHPExcel_Style|false + * @return PHPExcel_Style|boolean False if no match found */ public function getCellXfByHashCode($pValue = '') { @@ -1022,7 +1022,7 @@ public function getCellStyleXfByIndex($pIndex = 0) * Get cellStyleXf by hash code * * @param string $pValue - * @return PHPExcel_Style|false + * @return PHPExcel_Style|boolean False if no match found */ public function getCellStyleXfByHashCode($pValue = '') { @@ -1095,6 +1095,7 @@ public function garbageCollect() // remove cellXfs without references and create mapping so we can update xfIndex // for all cells and columns $countNeededCellXfs = 0; + $map = array(); foreach ($this->cellXfCollection as $index => $cellXf) { if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf ++$countNeededCellXfs; diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index a2d9ab8eb..20b1ec3f5 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -210,10 +210,10 @@ class PHPExcel_Calculation /** * Epsilon Precision used for comparisons in calculations * - * @var integer + * @var float * */ - private $delta = 0.0000000000001; + private $delta = 0.1e-12; /** diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index a19eaec9d..2500f16c1 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -492,7 +492,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Create a new DOM object $dom = new domDocument; // Reload the HTML file into the DOM object - $loaded = $dom->loadHTML($this->securityScanFile($pFilename)); + $loaded = $dom->loadHTML(mb_convert_encoding($this->securityScanFile($pFilename), 'HTML-ENTITIES', 'UTF-8')); if ($loaded === false) { throw new PHPExcel_Reader_Exception('Failed to load ', $pFilename, ' as a DOM Document'); } diff --git a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php index 290bbe771..c211403e3 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel2007/Worksheet.php @@ -259,7 +259,7 @@ private function writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = null, PH $pane = ''; $topLeftCell = $pSheet->getFreezePane(); if (($topLeftCell != '') && ($topLeftCell != 'A1')) { - $activeCell = $topLeftCell; + $activeCell = empty($activeCell) ? $topLeftCell : $activeCell; // Calculate freeze coordinates $xSplit = $ySplit = 0; From 7eb10adb3b78292d3d3f098151f13daf1c0afbcf Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 28 Dec 2015 23:26:15 +0000 Subject: [PATCH 429/467] Modify getCell() methods to allow creating a new cell if the selected cell doesn't exist as an option --- Classes/PHPExcel/Worksheet.php | 37 ++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 51470c3e8..483aa0021 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -396,7 +396,7 @@ public function __destruct() public function getCellCacheController() { return $this->cellCollection; - } // function getCellCacheController() + } /** @@ -727,8 +727,8 @@ public function calculateColumnWidths($calculateMergeCells = false) // loop through all cells in the worksheet foreach ($this->getCellCollection(false) as $cellID) { - $cell = $this->getCell($cellID); - if (isset($autoSizes[$this->cellCollection->getCurrentColumn()])) { + $cell = $this->getCell($cellID, false); + if ($cell !== null && isset($autoSizes[$this->cellCollection->getCurrentColumn()])) { // Determine width if cell does not participate in a merge if (!isset($isMergeCell[$this->cellCollection->getCurrentAddress()])) { // Calculated value @@ -1137,10 +1137,12 @@ public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pVa * Get cell at a specific coordinate * * @param string $pCoordinate Coordinate of the cell + * @param boolean $createIfNotExists Flag indicating whether a new cell should be created if it doesn't + * already exist, or a null should be returned instead * @throws PHPExcel_Exception - * @return PHPExcel_Cell Cell that was found + * @return null|PHPExcel_Cell Cell that was found/created or null */ - public function getCell($pCoordinate = 'A1') + public function getCell($pCoordinate = 'A1', $createIfNotExists = true) { // Check cell collection if ($this->cellCollection->isDataSet(strtoupper($pCoordinate))) { @@ -1150,7 +1152,7 @@ public function getCell($pCoordinate = 'A1') // Worksheet reference? if (strpos($pCoordinate, '!') !== false) { $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); - return $this->parent->getSheetByName($worksheetReference[0])->getCell(strtoupper($worksheetReference[1])); + return $this->parent->getSheetByName($worksheetReference[0])->getCell(strtoupper($worksheetReference[1]), $createIfNotExists); } // Named range? @@ -1159,7 +1161,7 @@ public function getCell($pCoordinate = 'A1') $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); if ($namedRange !== null) { $pCoordinate = $namedRange->getRange(); - return $namedRange->getWorksheet()->getCell($pCoordinate); + return $namedRange->getWorksheet()->getCell($pCoordinate, $createIfNotExists); } } @@ -1172,18 +1174,20 @@ public function getCell($pCoordinate = 'A1') throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); } - // Create new cell object - return $this->createNewCell($pCoordinate); + // Create new cell object, if required + return $createIfNotExists ? $this->createNewCell($pCoordinate) : null; } /** * Get cell at a specific coordinate by using numeric cell coordinates * - * @param string $pColumn Numeric column coordinate of the cell + * @param string $pColumn Numeric column coordinate of the cell (starting from 0) * @param string $pRow Numeric row coordinate of the cell - * @return PHPExcel_Cell Cell that was found + * @param boolean $createIfNotExists Flag indicating whether a new cell should be created if it doesn't + * already exist, or a null should be returned instead + * @return null|PHPExcel_Cell Cell that was found/created or null */ - public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) + public function getCellByColumnAndRow($pColumn = 0, $pRow = 1, $createIfNotExists = true) { $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn); $coordinate = $columnLetter . $pRow; @@ -1192,7 +1196,8 @@ public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) return $this->cellCollection->getCacheData($coordinate); } - return $this->createNewCell($coordinate); + // Create new cell object, if required + return $createIfNotExists ? $this->createNewCell($coordinate) : null; } /** @@ -1692,10 +1697,12 @@ public function mergeCells($pRange = 'A1:A1') $this->getCell($upperLeft)->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); } - // create or blank out the rest of the cells in the range + // Blank out the rest of the cells in the range (if they exist) $count = count($aReferences); for ($i = 1; $i < $count; $i++) { - $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); + if ($this->cellExists($aReferences[$i])) { + $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); + } } } else { throw new PHPExcel_Exception('Merge must be set on a range of cells.'); From 2058c8468a8fa9e7c5f5e2e2e98c09aaff9fc6ac Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 30 Dec 2015 00:24:36 +0000 Subject: [PATCH 430/467] Start work on implementing an option to ignore "empty" cells when reading a file --- Classes/PHPExcel/Reader/Abstract.php | 36 ++++++++++++++++++++++++++++ Classes/PHPExcel/Reader/Excel5.php | 34 ++++++++++++++++---------- 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php index 5902574b9..189c70a1b 100644 --- a/Classes/PHPExcel/Reader/Abstract.php +++ b/Classes/PHPExcel/Reader/Abstract.php @@ -36,6 +36,15 @@ abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader */ protected $readDataOnly = false; + /** + * Read empty cells? + * Identifies whether the Reader should read data values for cells all cells, or should ignore cells containing + * null value or empty string + * + * @var boolean + */ + protected $readEmptyCells = true; + /** * Read charts that are defined in the workbook? * Identifies whether the Reader should read the definitions for any charts that exist in the workbook; @@ -89,6 +98,33 @@ public function setReadDataOnly($pValue = false) return $this; } + /** + * Read empty cells? + * If this is true (the default), then the Reader will read data values for all cells, irrespective of value. + * If false it will not read data for cells containing a null value or an empty string. + * + * @return boolean + */ + public function getReadEmptyCells() + { + return $this->readEmptyCells; + } + + /** + * Set read empty cells + * Set to true (the default) to advise the Reader read data values for all cells, irrespective of value. + * Set to false to advise the Reader to ignore cells containing a null value or an empty string. + * + * @param boolean $pValue + * + * @return PHPExcel_Reader_IReader + */ + public function setReadEmptyCells($pValue = true) + { + $this->readEmptyCells = $pValue; + return $this; + } + /** * Read charts in workbook? * If this is true, then the Reader will include any charts that exist in the workbook. diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 770d43569..8dd15af9e 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -3687,6 +3687,7 @@ private function readLabelSst() $column = self::getInt2d($recordData, 2); $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + $emptyCell = true; // Read cell? if (($this->getReadFilter() !== null) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) { // offset: 4; size: 2; index to XF record @@ -3727,14 +3728,20 @@ private function readLabelSst() } } } - $cell = $this->phpSheet->getCell($columnString . ($row + 1)); - $cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING); + if ($this->readEmptyCells || trim($richText->getPlainText()) !== '') { + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING); + $emptyCell = false; + } } else { - $cell = $this->phpSheet->getCell($columnString . ($row + 1)); - $cell->setValueExplicit($this->sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING); + if ($this->readEmptyCells || trim($this->sst[$index]['value']) !== '') { + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($this->sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING); + $emptyCell = false; + } } - if (!$this->readDataOnly) { + if (!$this->readDataOnly && !$emptyCell) { // add style information $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]); } @@ -4108,7 +4115,7 @@ private function readMulBlank() // offset: 4; size: 2 x nc; list of indexes to XF records // add style information - if (!$this->readDataOnly) { + if (!$this->readDataOnly && $this->readEmptyCells) { for ($i = 0; $i < $length / 2 - 3; ++$i) { $columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i); @@ -4163,12 +4170,14 @@ private function readLabel() $string = $this->readByteStringLong(substr($recordData, 6)); $value = $string['value']; } - $cell = $this->phpSheet->getCell($columnString . ($row + 1)); - $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); + if ($this->readEmptyCells || trim($value) !== '') { + $cell = $this->phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); - if (!$this->readDataOnly) { - // add cell style - $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]); + if (!$this->readDataOnly) { + // add cell style + $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]); + } } } } @@ -4198,11 +4207,10 @@ private function readBlank() $xfIndex = self::getInt2d($recordData, 4); // add style information - if (!$this->readDataOnly) { + if (!$this->readDataOnly && $this->readEmptyCells) { $this->phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->mapCellXfIndex[$xfIndex]); } } - } From 6d3a440aae68c1450dc93cd9a3535221ce13682f Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 30 Dec 2015 02:17:40 +0000 Subject: [PATCH 431/467] Refactor colour mapping for Excel5 Reader --- Classes/PHPExcel/Reader/Excel5.php | 270 +----------------- .../PHPExcel/Reader/Excel5/Color/BIFF5.php | 63 ++++ .../PHPExcel/Reader/Excel5/Color/BIFF8.php | 63 ++++ .../PHPExcel/Reader/Excel5/Color/BuiltIn.php | 17 ++ 4 files changed, 156 insertions(+), 257 deletions(-) create mode 100644 Classes/PHPExcel/Reader/Excel5/Color/BIFF5.php create mode 100644 Classes/PHPExcel/Reader/Excel5/Color/BIFF8.php create mode 100644 Classes/PHPExcel/Reader/Excel5/Color/BuiltIn.php diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 8dd15af9e..969b8dc7e 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -7760,284 +7760,40 @@ private static function mapErrorCode($subData) */ private static function mapBuiltInColor($color) { - switch ($color) { - case 0x00: - return array('rgb' => '000000'); - case 0x01: - return array('rgb' => 'FFFFFF'); - case 0x02: - return array('rgb' => 'FF0000'); - case 0x03: - return array('rgb' => '00FF00'); - case 0x04: - return array('rgb' => '0000FF'); - case 0x05: - return array('rgb' => 'FFFF00'); - case 0x06: - return array('rgb' => 'FF00FF'); - case 0x07: - return array('rgb' => '00FFFF'); - case 0x40: - return array('rgb' => '000000'); // system window text color - case 0x41: - return array('rgb' => 'FFFFFF'); // system window background color - default: - return array('rgb' => '000000'); + if (isset(PHPExcel_Reader_Excel5_Color_BuiltIn::$map[$color])) { + return array('rgb' => PHPExcel_Reader_Excel5_Color_BuiltIn::$map[$color]); } + return array('rgb' => '000000'); } /** * Map color array from BIFF5 built-in color index * - * @param int $subData + * @param int $color * @return array */ - private static function mapColorBIFF5($subData) + private static function mapColorBIFF5($color) { - switch ($subData) { - case 0x08: - return array('rgb' => '000000'); - case 0x09: - return array('rgb' => 'FFFFFF'); - case 0x0A: - return array('rgb' => 'FF0000'); - case 0x0B: - return array('rgb' => '00FF00'); - case 0x0C: - return array('rgb' => '0000FF'); - case 0x0D: - return array('rgb' => 'FFFF00'); - case 0x0E: - return array('rgb' => 'FF00FF'); - case 0x0F: - return array('rgb' => '00FFFF'); - case 0x10: - return array('rgb' => '800000'); - case 0x11: - return array('rgb' => '008000'); - case 0x12: - return array('rgb' => '000080'); - case 0x13: - return array('rgb' => '808000'); - case 0x14: - return array('rgb' => '800080'); - case 0x15: - return array('rgb' => '008080'); - case 0x16: - return array('rgb' => 'C0C0C0'); - case 0x17: - return array('rgb' => '808080'); - case 0x18: - return array('rgb' => '8080FF'); - case 0x19: - return array('rgb' => '802060'); - case 0x1A: - return array('rgb' => 'FFFFC0'); - case 0x1B: - return array('rgb' => 'A0E0F0'); - case 0x1C: - return array('rgb' => '600080'); - case 0x1D: - return array('rgb' => 'FF8080'); - case 0x1E: - return array('rgb' => '0080C0'); - case 0x1F: - return array('rgb' => 'C0C0FF'); - case 0x20: - return array('rgb' => '000080'); - case 0x21: - return array('rgb' => 'FF00FF'); - case 0x22: - return array('rgb' => 'FFFF00'); - case 0x23: - return array('rgb' => '00FFFF'); - case 0x24: - return array('rgb' => '800080'); - case 0x25: - return array('rgb' => '800000'); - case 0x26: - return array('rgb' => '008080'); - case 0x27: - return array('rgb' => '0000FF'); - case 0x28: - return array('rgb' => '00CFFF'); - case 0x29: - return array('rgb' => '69FFFF'); - case 0x2A: - return array('rgb' => 'E0FFE0'); - case 0x2B: - return array('rgb' => 'FFFF80'); - case 0x2C: - return array('rgb' => 'A6CAF0'); - case 0x2D: - return array('rgb' => 'DD9CB3'); - case 0x2E: - return array('rgb' => 'B38FEE'); - case 0x2F: - return array('rgb' => 'E3E3E3'); - case 0x30: - return array('rgb' => '2A6FF9'); - case 0x31: - return array('rgb' => '3FB8CD'); - case 0x32: - return array('rgb' => '488436'); - case 0x33: - return array('rgb' => '958C41'); - case 0x34: - return array('rgb' => '8E5E42'); - case 0x35: - return array('rgb' => 'A0627A'); - case 0x36: - return array('rgb' => '624FAC'); - case 0x37: - return array('rgb' => '969696'); - case 0x38: - return array('rgb' => '1D2FBE'); - case 0x39: - return array('rgb' => '286676'); - case 0x3A: - return array('rgb' => '004500'); - case 0x3B: - return array('rgb' => '453E01'); - case 0x3C: - return array('rgb' => '6A2813'); - case 0x3D: - return array('rgb' => '85396A'); - case 0x3E: - return array('rgb' => '4A3285'); - case 0x3F: - return array('rgb' => '424242'); - default: - return array('rgb' => '000000'); + if (isset(PHPExcel_Reader_Excel5_Color_BIFF5::$map[$color])) { + return array('rgb' => PHPExcel_Reader_Excel5_Color_BIFF5::$map[$color]); } + return array('rgb' => '000000'); } /** * Map color array from BIFF8 built-in color index * - * @param int $subData + * @param int $color * @return array */ - private static function mapColor($subData) + private static function mapColor($color) { - switch ($subData) { - case 0x08: - return array('rgb' => '000000'); - case 0x09: - return array('rgb' => 'FFFFFF'); - case 0x0A: - return array('rgb' => 'FF0000'); - case 0x0B: - return array('rgb' => '00FF00'); - case 0x0C: - return array('rgb' => '0000FF'); - case 0x0D: - return array('rgb' => 'FFFF00'); - case 0x0E: - return array('rgb' => 'FF00FF'); - case 0x0F: - return array('rgb' => '00FFFF'); - case 0x10: - return array('rgb' => '800000'); - case 0x11: - return array('rgb' => '008000'); - case 0x12: - return array('rgb' => '000080'); - case 0x13: - return array('rgb' => '808000'); - case 0x14: - return array('rgb' => '800080'); - case 0x15: - return array('rgb' => '008080'); - case 0x16: - return array('rgb' => 'C0C0C0'); - case 0x17: - return array('rgb' => '808080'); - case 0x18: - return array('rgb' => '9999FF'); - case 0x19: - return array('rgb' => '993366'); - case 0x1A: - return array('rgb' => 'FFFFCC'); - case 0x1B: - return array('rgb' => 'CCFFFF'); - case 0x1C: - return array('rgb' => '660066'); - case 0x1D: - return array('rgb' => 'FF8080'); - case 0x1E: - return array('rgb' => '0066CC'); - case 0x1F: - return array('rgb' => 'CCCCFF'); - case 0x20: - return array('rgb' => '000080'); - case 0x21: - return array('rgb' => 'FF00FF'); - case 0x22: - return array('rgb' => 'FFFF00'); - case 0x23: - return array('rgb' => '00FFFF'); - case 0x24: - return array('rgb' => '800080'); - case 0x25: - return array('rgb' => '800000'); - case 0x26: - return array('rgb' => '008080'); - case 0x27: - return array('rgb' => '0000FF'); - case 0x28: - return array('rgb' => '00CCFF'); - case 0x29: - return array('rgb' => 'CCFFFF'); - case 0x2A: - return array('rgb' => 'CCFFCC'); - case 0x2B: - return array('rgb' => 'FFFF99'); - case 0x2C: - return array('rgb' => '99CCFF'); - case 0x2D: - return array('rgb' => 'FF99CC'); - case 0x2E: - return array('rgb' => 'CC99FF'); - case 0x2F: - return array('rgb' => 'FFCC99'); - case 0x30: - return array('rgb' => '3366FF'); - case 0x31: - return array('rgb' => '33CCCC'); - case 0x32: - return array('rgb' => '99CC00'); - case 0x33: - return array('rgb' => 'FFCC00'); - case 0x34: - return array('rgb' => 'FF9900'); - case 0x35: - return array('rgb' => 'FF6600'); - case 0x36: - return array('rgb' => '666699'); - case 0x37: - return array('rgb' => '969696'); - case 0x38: - return array('rgb' => '003366'); - case 0x39: - return array('rgb' => '339966'); - case 0x3A: - return array('rgb' => '003300'); - case 0x3B: - return array('rgb' => '333300'); - case 0x3C: - return array('rgb' => '993300'); - case 0x3D: - return array('rgb' => '993366'); - case 0x3E: - return array('rgb' => '333399'); - case 0x3F: - return array('rgb' => '333333'); - default: - return array('rgb' => '000000'); + if (isset(PHPExcel_Reader_Excel5_Color_BIFF8::$map[$color])) { + return array('rgb' => PHPExcel_Reader_Excel5_Color_BIFF8::$map[$color]); } + return array('rgb' => '000000'); } private function parseRichText($is = '') diff --git a/Classes/PHPExcel/Reader/Excel5/Color/BIFF5.php b/Classes/PHPExcel/Reader/Excel5/Color/BIFF5.php new file mode 100644 index 000000000..7c15d5d4f --- /dev/null +++ b/Classes/PHPExcel/Reader/Excel5/Color/BIFF5.php @@ -0,0 +1,63 @@ +<?php + +class PHPExcel_Reader_Excel5_Color_BIFF5 +{ + public static $map = array( + 0x08 => '000000', + 0x09 => 'FFFFFF', + 0x0A => 'FF0000', + 0x0B => '00FF00', + 0x0C => '0000FF', + 0x0D => 'FFFF00', + 0x0E => 'FF00FF', + 0x0F => '00FFFF', + 0x10 => '800000', + 0x11 => '008000', + 0x12 => '000080', + 0x13 => '808000', + 0x14 => '800080', + 0x15 => '008080', + 0x16 => 'C0C0C0', + 0x17 => '808080', + 0x18 => '8080FF', + 0x19 => '802060', + 0x1A => 'FFFFC0', + 0x1B => 'A0E0F0', + 0x1C => '600080', + 0x1D => 'FF8080', + 0x1E => '0080C0', + 0x1F => 'C0C0FF', + 0x20 => '000080', + 0x21 => 'FF00FF', + 0x22 => 'FFFF00', + 0x23 => '00FFFF', + 0x24 => '800080', + 0x25 => '800000', + 0x26 => '008080', + 0x27 => '0000FF', + 0x28 => '00CFFF', + 0x29 => '69FFFF', + 0x2A => 'E0FFE0', + 0x2B => 'FFFF80', + 0x2C => 'A6CAF0', + 0x2D => 'DD9CB3', + 0x2E => 'B38FEE', + 0x2F => 'E3E3E3', + 0x30 => '2A6FF9', + 0x31 => '3FB8CD', + 0x32 => '488436', + 0x33 => '958C41', + 0x34 => '8E5E42', + 0x35 => 'A0627A', + 0x36 => '624FAC', + 0x37 => '969696', + 0x38 => '1D2FBE', + 0x39 => '286676', + 0x3A => '004500', + 0x3B => '453E01', + 0x3C => '6A2813', + 0x3D => '85396A', + 0x3E => '4A3285', + 0x3F => '424242', + ); +} \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5/Color/BIFF8.php b/Classes/PHPExcel/Reader/Excel5/Color/BIFF8.php new file mode 100644 index 000000000..d0c8afbb8 --- /dev/null +++ b/Classes/PHPExcel/Reader/Excel5/Color/BIFF8.php @@ -0,0 +1,63 @@ +<?php + +class PHPExcel_Reader_Excel5_Color_BIFF8 +{ + public static $map = array( + 0x08 => '000000', + 0x09 => 'FFFFFF', + 0x0A => 'FF0000', + 0x0B => '00FF00', + 0x0C => '0000FF', + 0x0D => 'FFFF00', + 0x0E => 'FF00FF', + 0x0F => '00FFFF', + 0x10 => '800000', + 0x11 => '008000', + 0x12 => '000080', + 0x13 => '808000', + 0x14 => '800080', + 0x15 => '008080', + 0x16 => 'C0C0C0', + 0x17 => '808080', + 0x18 => '9999FF', + 0x19 => '993366', + 0x1A => 'FFFFCC', + 0x1B => 'CCFFFF', + 0x1C => '660066', + 0x1D => 'FF8080', + 0x1E => '0066CC', + 0x1F => 'CCCCFF', + 0x20 => '000080', + 0x21 => 'FF00FF', + 0x22 => 'FFFF00', + 0x23 => '00FFFF', + 0x24 => '800080', + 0x25 => '800000', + 0x26 => '008080', + 0x27 => '0000FF', + 0x28 => '00CCFF', + 0x29 => 'CCFFFF', + 0x2A => 'CCFFCC', + 0x2B => 'FFFF99', + 0x2C => '99CCFF', + 0x2D => 'FF99CC', + 0x2E => 'CC99FF', + 0x2F => 'FFCC99', + 0x30 => '3366FF', + 0x31 => '33CCCC', + 0x32 => '99CC00', + 0x33 => 'FFCC00', + 0x34 => 'FF9900', + 0x35 => 'FF6600', + 0x36 => '666699', + 0x37 => '969696', + 0x38 => '003366', + 0x39 => '339966', + 0x3A => '003300', + 0x3B => '333300', + 0x3C => '993300', + 0x3D => '993366', + 0x3E => '333399', + 0x3F => '333333', + ); +} \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5/Color/BuiltIn.php b/Classes/PHPExcel/Reader/Excel5/Color/BuiltIn.php new file mode 100644 index 000000000..f3458955f --- /dev/null +++ b/Classes/PHPExcel/Reader/Excel5/Color/BuiltIn.php @@ -0,0 +1,17 @@ +<?php + +class PHPExcel_Reader_Excel5_Color_BuiltIn +{ + public static $map = array( + 0x00 => '000000', + 0x01 => 'FFFFFF', + 0x02 => 'FF0000', + 0x03 => '00FF00', + 0x04 => '0000FF', + 0x05 => 'FFFF00', + 0x06 => 'FF00FF', + 0x07 => '00FFFF', + 0x40 => '000000', // system window text color + 0x41 => 'FFFFFF', // system window background color + ); +} \ No newline at end of file From 2743dc4acfe75d96a9ab15eb0a4b165b962009e7 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 30 Dec 2015 11:05:36 +0000 Subject: [PATCH 432/467] Short array syntax in XEE Validator tests --- unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php b/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php index 49e4aa980..c2c411fe5 100644 --- a/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php +++ b/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php @@ -26,7 +26,7 @@ public function testInvalidXML($filename) public function providerInvalidXML() { - $tests = []; + $tests = array(); foreach (glob('rawTestData/Reader/XEETestInvalid*.xml') as $file) { $tests[] = [realpath($file), true]; } From e11a76759f92b9a145c0bcedc95d35620d97b72d Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 30 Dec 2015 11:15:21 +0000 Subject: [PATCH 433/467] Update Travis configuration --- .travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 284b516be..99e9e8da6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,10 @@ language: php php: - - 5.2 - - 5.3 - - 5.3.3 - 5.4 - 5.5 - 5.6 + - 7.0 - hhvm matrix: @@ -17,8 +15,6 @@ before_script: ## Packages - sudo apt-get -qq update > /dev/null ## Composer - ##@todo Remove when support of 5.2 will be dropped - - phpenv global 5.3 - composer self-update - composer install --prefer-source --dev - phpenv global "$TRAVIS_PHP_VERSION" From dbb819003cb3b81bc9c7b62d9bf9a36b6eb31ab0 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 30 Dec 2015 20:01:29 +0000 Subject: [PATCH 434/467] More refactoring of Excel5 Reader mappings --- Classes/PHPExcel/Reader/Excel5.php | 107 ++---------------- Classes/PHPExcel/Reader/Excel5/ErrorCode.php | 14 +++ .../PHPExcel/Reader/Excel5/Style/Border.php | 21 ++++ .../Reader/Excel5/Style/FillPattern.php | 26 +++++ 4 files changed, 71 insertions(+), 97 deletions(-) create mode 100644 Classes/PHPExcel/Reader/Excel5/ErrorCode.php create mode 100644 Classes/PHPExcel/Reader/Excel5/Style/Border.php create mode 100644 Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 969b8dc7e..243dcba9b 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -7627,38 +7627,10 @@ private static function readColor($color, $palette, $version) */ private static function mapBorderStyle($index) { - switch ($index) { - case 0x00: - return PHPExcel_Style_Border::BORDER_NONE; - case 0x01: - return PHPExcel_Style_Border::BORDER_THIN; - case 0x02: - return PHPExcel_Style_Border::BORDER_MEDIUM; - case 0x03: - return PHPExcel_Style_Border::BORDER_DASHED; - case 0x04: - return PHPExcel_Style_Border::BORDER_DOTTED; - case 0x05: - return PHPExcel_Style_Border::BORDER_THICK; - case 0x06: - return PHPExcel_Style_Border::BORDER_DOUBLE; - case 0x07: - return PHPExcel_Style_Border::BORDER_HAIR; - case 0x08: - return PHPExcel_Style_Border::BORDER_MEDIUMDASHED; - case 0x09: - return PHPExcel_Style_Border::BORDER_DASHDOT; - case 0x0A: - return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; - case 0x0B: - return PHPExcel_Style_Border::BORDER_DASHDOTDOT; - case 0x0C: - return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; - case 0x0D: - return PHPExcel_Style_Border::BORDER_SLANTDASHDOT; - default: - return PHPExcel_Style_Border::BORDER_NONE; + if (isset(PHPExcel_Reader_Excel5_Style_Border::$map[$index])) { + return PHPExcel_Reader_Excel5_Style_Border::$map[$index]; } + return PHPExcel_Style_Border::BORDER_NONE; } @@ -7671,48 +7643,10 @@ private static function mapBorderStyle($index) */ private static function mapFillPattern($index) { - switch ($index) { - case 0x00: - return PHPExcel_Style_Fill::FILL_NONE; - case 0x01: - return PHPExcel_Style_Fill::FILL_SOLID; - case 0x02: - return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; - case 0x03: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; - case 0x04: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; - case 0x05: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; - case 0x06: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; - case 0x07: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; - case 0x08: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; - case 0x09: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; - case 0x0A: - return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; - case 0x0B: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; - case 0x0C: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; - case 0x0D: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; - case 0x0E: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; - case 0x0F: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; - case 0x10: - return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; - case 0x11: - return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; - case 0x12: - return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; - default: - return PHPExcel_Style_Fill::FILL_NONE; + if (isset(PHPExcel_Reader_Excel5_Style_FillPattern::$map[$index])) { + return PHPExcel_Reader_Excel5_Style_FillPattern::$map[$index]; } + return PHPExcel_Style_Fill::FILL_NONE; } @@ -7722,33 +7656,12 @@ private static function mapFillPattern($index) * @param int $subData * @return string */ - private static function mapErrorCode($subData) + private static function mapErrorCode($code) { - switch ($subData) { - case 0x00: - return '#NULL!'; - break; - case 0x07: - return '#DIV/0!'; - break; - case 0x0F: - return '#VALUE!'; - break; - case 0x17: - return '#REF!'; - break; - case 0x1D: - return '#NAME?'; - break; - case 0x24: - return '#NUM!'; - break; - case 0x2A: - return '#N/A'; - break; - default: - return false; + if (isset(PHPExcel_Reader_Excel5_ErrorCode::$map[$code])) { + return PHPExcel_Reader_Excel5_ErrorCode::$map[$code]; } + return false; } diff --git a/Classes/PHPExcel/Reader/Excel5/ErrorCode.php b/Classes/PHPExcel/Reader/Excel5/ErrorCode.php new file mode 100644 index 000000000..df3eadce1 --- /dev/null +++ b/Classes/PHPExcel/Reader/Excel5/ErrorCode.php @@ -0,0 +1,14 @@ +<?php + +class PHPExcel_Reader_Excel5_ErrorCode +{ + public static $map = array( + 0x00 => '#NULL!', + 0x07 => '#DIV/0!', + 0x0F => '#VALUE!', + 0x17 => '#REF!', + 0x1D => '#NAME?', + 0x24 => '#NUM!', + 0x2A => '#N/A', + ); +} \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5/Style/Border.php b/Classes/PHPExcel/Reader/Excel5/Style/Border.php new file mode 100644 index 000000000..5695376a4 --- /dev/null +++ b/Classes/PHPExcel/Reader/Excel5/Style/Border.php @@ -0,0 +1,21 @@ +<?php + +class PHPExcel_Reader_Excel5_Style_Border +{ + public static $map = array( + 0x00 => PHPExcel_Style_Border::BORDER_NONE, + 0x01 => PHPExcel_Style_Border::BORDER_THIN, + 0x02 => PHPExcel_Style_Border::BORDER_MEDIUM, + 0x03 => PHPExcel_Style_Border::BORDER_DASHED, + 0x04 => PHPExcel_Style_Border::BORDER_DOTTED, + 0x05 => PHPExcel_Style_Border::BORDER_THICK, + 0x06 => PHPExcel_Style_Border::BORDER_DOUBLE, + 0x07 => PHPExcel_Style_Border::BORDER_HAIR, + 0x08 => PHPExcel_Style_Border::BORDER_MEDIUMDASHED, + 0x09 => PHPExcel_Style_Border::BORDER_DASHDOT, + 0x0A => PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT, + 0x0B => PHPExcel_Style_Border::BORDER_DASHDOTDOT, + 0x0C => PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT, + 0x0D => PHPExcel_Style_Border::BORDER_SLANTDASHDOT, + ); +} \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php b/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php new file mode 100644 index 000000000..a780639ec --- /dev/null +++ b/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php @@ -0,0 +1,26 @@ +<?php + +class PHPExcel_Reader_Excel5_Style_FillPattern +{ + public static $map = array( + 0x00 => PHPExcel_Style_Fill::FILL_NONE, + 0x01 => PHPExcel_Style_Fill::FILL_SOLID, + 0x02 => PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY, + 0x03 => PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY, + 0x04 => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY, + 0x05 => PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL, + 0x06 => PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL, + 0x07 => PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN, + 0x08 => PHPExcel_Style_Fill::FILL_PATTERN_DARKUP, + 0x09 => PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID, + 0x0A => PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS, + 0x0B => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL, + 0x0C => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL, + 0x0D => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN, + 0x0E => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP, + 0x0F => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID, + 0x10 => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS, + 0x11 => PHPExcel_Style_Fill::FILL_PATTERN_GRAY125, + 0x12 => PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625, + ); +} \ No newline at end of file From a27e053354adf9f7fc327f6c8b79041ff129eb83 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 31 Dec 2015 00:16:34 +0000 Subject: [PATCH 435/467] Refactor mappers out from Excel5 Reader completely --- Classes/PHPExcel/Reader/Excel5.php | 173 +++--------------- Classes/PHPExcel/Reader/Excel5/Color.php | 32 ++++ .../PHPExcel/Reader/Excel5/Color/BIFF5.php | 16 +- .../PHPExcel/Reader/Excel5/Color/BIFF8.php | 16 +- .../PHPExcel/Reader/Excel5/Color/BuiltIn.php | 16 +- Classes/PHPExcel/Reader/Excel5/ErrorCode.php | 16 +- .../PHPExcel/Reader/Excel5/Style/Border.php | 17 +- .../Reader/Excel5/Style/FillPattern.php | 17 +- 8 files changed, 148 insertions(+), 155 deletions(-) create mode 100644 Classes/PHPExcel/Reader/Excel5/Color.php diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 243dcba9b..9b122e4ff 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -724,7 +724,7 @@ public function load($pFilename) if (!$this->readDataOnly) { foreach ($this->objFonts as $objFont) { if (isset($objFont->colorIndex)) { - $color = self::readColor($objFont->colorIndex, $this->palette, $this->version); + $color = PHPExcel_Reader_Excel5_Color::map($objFont->colorIndex, $this->palette, $this->version); $objFont->getColor()->setRGB($color['rgb']); } } @@ -734,11 +734,11 @@ public function load($pFilename) $fill = $objStyle->getFill(); if (isset($fill->startcolorIndex)) { - $startColor = self::readColor($fill->startcolorIndex, $this->palette, $this->version); + $startColor = PHPExcel_Reader_Excel5_Color::map($fill->startcolorIndex, $this->palette, $this->version); $fill->getStartColor()->setRGB($startColor['rgb']); } if (isset($fill->endcolorIndex)) { - $endColor = self::readColor($fill->endcolorIndex, $this->palette, $this->version); + $endColor = PHPExcel_Reader_Excel5_Color::map($fill->endcolorIndex, $this->palette, $this->version); $fill->getEndColor()->setRGB($endColor['rgb']); } @@ -750,23 +750,23 @@ public function load($pFilename) $diagonal = $objStyle->getBorders()->getDiagonal(); if (isset($top->colorIndex)) { - $borderTopColor = self::readColor($top->colorIndex, $this->palette, $this->version); + $borderTopColor = PHPExcel_Reader_Excel5_Color::map($top->colorIndex, $this->palette, $this->version); $top->getColor()->setRGB($borderTopColor['rgb']); } if (isset($right->colorIndex)) { - $borderRightColor = self::readColor($right->colorIndex, $this->palette, $this->version); + $borderRightColor = PHPExcel_Reader_Excel5_Color::map($right->colorIndex, $this->palette, $this->version); $right->getColor()->setRGB($borderRightColor['rgb']); } if (isset($bottom->colorIndex)) { - $borderBottomColor = self::readColor($bottom->colorIndex, $this->palette, $this->version); + $borderBottomColor = PHPExcel_Reader_Excel5_Color::map($bottom->colorIndex, $this->palette, $this->version); $bottom->getColor()->setRGB($borderBottomColor['rgb']); } if (isset($left->colorIndex)) { - $borderLeftColor = self::readColor($left->colorIndex, $this->palette, $this->version); + $borderLeftColor = PHPExcel_Reader_Excel5_Color::map($left->colorIndex, $this->palette, $this->version); $left->getColor()->setRGB($borderLeftColor['rgb']); } if (isset($diagonal->colorIndex)) { - $borderDiagonalColor = self::readColor($diagonal->colorIndex, $this->palette, $this->version); + $borderDiagonalColor = PHPExcel_Reader_Excel5_Color::map($diagonal->colorIndex, $this->palette, $this->version); $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']); } } @@ -2209,19 +2209,19 @@ private function readXf() // offset: 10; size: 4; Cell border lines and background area // bit: 3-0; mask: 0x0000000F; left style - if ($bordersLeftStyle = self::mapBorderStyle((0x0000000F & self::getInt4d($recordData, 10)) >> 0)) { + if ($bordersLeftStyle = PHPExcel_Reader_Excel5_Style_Border::lookup((0x0000000F & self::getInt4d($recordData, 10)) >> 0)) { $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle); } // bit: 7-4; mask: 0x000000F0; right style - if ($bordersRightStyle = self::mapBorderStyle((0x000000F0 & self::getInt4d($recordData, 10)) >> 4)) { + if ($bordersRightStyle = PHPExcel_Reader_Excel5_Style_Border::lookup((0x000000F0 & self::getInt4d($recordData, 10)) >> 4)) { $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle); } // bit: 11-8; mask: 0x00000F00; top style - if ($bordersTopStyle = self::mapBorderStyle((0x00000F00 & self::getInt4d($recordData, 10)) >> 8)) { + if ($bordersTopStyle = PHPExcel_Reader_Excel5_Style_Border::lookup((0x00000F00 & self::getInt4d($recordData, 10)) >> 8)) { $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle); } // bit: 15-12; mask: 0x0000F000; bottom style - if ($bordersBottomStyle = self::mapBorderStyle((0x0000F000 & self::getInt4d($recordData, 10)) >> 12)) { + if ($bordersBottomStyle = PHPExcel_Reader_Excel5_Style_Border::lookup((0x0000F000 & self::getInt4d($recordData, 10)) >> 12)) { $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle); } // bit: 22-16; mask: 0x007F0000; left color @@ -2257,12 +2257,12 @@ private function readXf() $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::getInt4d($recordData, 14)) >> 14; // bit: 24-21; mask: 0x01E00000; diagonal style - if ($bordersDiagonalStyle = self::mapBorderStyle((0x01E00000 & self::getInt4d($recordData, 14)) >> 21)) { + if ($bordersDiagonalStyle = PHPExcel_Reader_Excel5_Style_Border::lookup((0x01E00000 & self::getInt4d($recordData, 14)) >> 21)) { $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle); } // bit: 31-26; mask: 0xFC000000 fill pattern - if ($fillType = self::mapFillPattern((0xFC000000 & self::getInt4d($recordData, 14)) >> 26)) { + if ($fillType = PHPExcel_Reader_Excel5_Style_FillPattern::lookup((0xFC000000 & self::getInt4d($recordData, 14)) >> 26)) { $objStyle->getFill()->setFillType($fillType); } // offset: 18; size: 2; pattern and background colour @@ -2304,10 +2304,10 @@ private function readXf() $objStyle->getFill()->endcolorIndex = (0x00003F80 & $borderAndBackground) >> 7; // bit: 21-16; mask: 0x003F0000; fill pattern - $objStyle->getFill()->setFillType(self::mapFillPattern((0x003F0000 & $borderAndBackground) >> 16)); + $objStyle->getFill()->setFillType(PHPExcel_Reader_Excel5_Style_FillPattern::lookup((0x003F0000 & $borderAndBackground) >> 16)); // bit: 24-22; mask: 0x01C00000; bottom line style - $objStyle->getBorders()->getBottom()->setBorderStyle(self::mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22)); + $objStyle->getBorders()->getBottom()->setBorderStyle(PHPExcel_Reader_Excel5_Style_Border::lookup((0x01C00000 & $borderAndBackground) >> 22)); // bit: 31-25; mask: 0xFE000000; bottom line color $objStyle->getBorders()->getBottom()->colorIndex = (0xFE000000 & $borderAndBackground) >> 25; @@ -2316,13 +2316,13 @@ private function readXf() $borderLines = self::getInt4d($recordData, 12); // bit: 2-0; mask: 0x00000007; top line style - $objStyle->getBorders()->getTop()->setBorderStyle(self::mapBorderStyle((0x00000007 & $borderLines) >> 0)); + $objStyle->getBorders()->getTop()->setBorderStyle(PHPExcel_Reader_Excel5_Style_Border::lookup((0x00000007 & $borderLines) >> 0)); // bit: 5-3; mask: 0x00000038; left line style - $objStyle->getBorders()->getLeft()->setBorderStyle(self::mapBorderStyle((0x00000038 & $borderLines) >> 3)); + $objStyle->getBorders()->getLeft()->setBorderStyle(PHPExcel_Reader_Excel5_Style_Border::lookup((0x00000038 & $borderLines) >> 3)); // bit: 8-6; mask: 0x000001C0; right line style - $objStyle->getBorders()->getRight()->setBorderStyle(self::mapBorderStyle((0x000001C0 & $borderLines) >> 6)); + $objStyle->getBorders()->getRight()->setBorderStyle(PHPExcel_Reader_Excel5_Style_Border::lookup((0x000001C0 & $borderLines) >> 6)); // bit: 15-9; mask: 0x0000FE00; top line color index $objStyle->getBorders()->getTop()->colorIndex = (0x0000FE00 & $borderLines) >> 9; @@ -3929,7 +3929,7 @@ private function readFormula() && (ord($recordData{13}) == 255)) { // Error formula. Error code is in +2 $dataType = PHPExcel_Cell_DataType::TYPE_ERROR; - $value = self::mapErrorCode(ord($recordData{8})); + $value = PHPExcel_Reader_Excel5_ErrorCode::lookup(ord($recordData{8})); } elseif ((ord($recordData{6}) == 3) && (ord($recordData{12}) == 255) && (ord($recordData{13}) == 255)) { @@ -4076,7 +4076,7 @@ private function readBoolErr() $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL); break; case 1: // error type - $value = self::mapErrorCode($boolErr); + $value = PHPExcel_Reader_Excel5_ErrorCode::lookup($boolErr); // add cell value $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_ERROR); @@ -4937,7 +4937,7 @@ private function readSheetLayout() case 0x14: // offset: 16; size: 2; color index for sheet tab $colorIndex = self::getInt2d($recordData, 16); - $color = self::readColor($colorIndex, $this->palette, $this->version); + $color = PHPExcel_Reader_Excel5_Color::map($colorIndex, $this->palette, $this->version); $this->phpSheet->getTabColor()->setRGB($color['rgb']); break; case 0x28: @@ -5704,7 +5704,7 @@ private function getNextToken($formulaData, $baseCell = 'A1') // offset: 1; size: 1; error code $name = 'tErr'; $size = 2; - $data = self::mapErrorCode(ord($formulaData[1])); + $data = PHPExcel_Reader_Excel5_ErrorCode::lookup(ord($formulaData[1])); break; case 0x1D: // boolean // offset: 1; size: 1; 0 = false, 1 = true; @@ -7273,7 +7273,7 @@ private static function readBIFF8Constant($valueData) break; case 0x10: // error code // offset: 1; size: 1; error code - $value = self::mapErrorCode(ord($valueData[1])); + $value = PHPExcel_Reader_Excel5_ErrorCode::lookup(ord($valueData[1])); $size = 9; break; } @@ -7522,7 +7522,6 @@ private static function encodeUTF16($string, $compressed = '') return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE'); } - /** * Convert UTF-16 string in compressed notation to uncompressed form. Only used for BIFF8. * @@ -7540,7 +7539,6 @@ private static function uncompressByteString($string) return $uncompressedString; } - /** * Convert string to UTF-8. Only used for BIFF5. * @@ -7552,7 +7550,6 @@ private function decodeCodepage($string) return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->codepage); } - /** * Read 16-bit unsigned integer * @@ -7565,7 +7562,6 @@ public static function getInt2d($data, $pos) return ord($data[$pos]) | (ord($data[$pos+1]) << 8); } - /** * Read 32-bit signed integer * @@ -7588,127 +7584,6 @@ public static function getInt4d($data, $pos) return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24; } - - /** - * Read color - * - * @param int $color Indexed color - * @param array $palette Color palette - * @return array RGB color value, example: array('rgb' => 'FF0000') - */ - private static function readColor($color, $palette, $version) - { - if ($color <= 0x07 || $color >= 0x40) { - // special built-in color - return self::mapBuiltInColor($color); - } elseif (isset($palette) && isset($palette[$color - 8])) { - // palette color, color index 0x08 maps to pallete index 0 - return $palette[$color - 8]; - } else { - // default color table - if ($version == self::XLS_BIFF8) { - return self::mapColor($color); - } else { - // BIFF5 - return self::mapColorBIFF5($color); - } - } - - return $color; - } - - - /** - * Map border style - * OpenOffice documentation: 2.5.11 - * - * @param int $index - * @return string - */ - private static function mapBorderStyle($index) - { - if (isset(PHPExcel_Reader_Excel5_Style_Border::$map[$index])) { - return PHPExcel_Reader_Excel5_Style_Border::$map[$index]; - } - return PHPExcel_Style_Border::BORDER_NONE; - } - - - /** - * Get fill pattern from index - * OpenOffice documentation: 2.5.12 - * - * @param int $index - * @return string - */ - private static function mapFillPattern($index) - { - if (isset(PHPExcel_Reader_Excel5_Style_FillPattern::$map[$index])) { - return PHPExcel_Reader_Excel5_Style_FillPattern::$map[$index]; - } - return PHPExcel_Style_Fill::FILL_NONE; - } - - - /** - * Map error code, e.g. '#N/A' - * - * @param int $subData - * @return string - */ - private static function mapErrorCode($code) - { - if (isset(PHPExcel_Reader_Excel5_ErrorCode::$map[$code])) { - return PHPExcel_Reader_Excel5_ErrorCode::$map[$code]; - } - return false; - } - - - /** - * Map built-in color to RGB value - * - * @param int $color Indexed color - * @return array - */ - private static function mapBuiltInColor($color) - { - if (isset(PHPExcel_Reader_Excel5_Color_BuiltIn::$map[$color])) { - return array('rgb' => PHPExcel_Reader_Excel5_Color_BuiltIn::$map[$color]); - } - return array('rgb' => '000000'); - } - - - /** - * Map color array from BIFF5 built-in color index - * - * @param int $color - * @return array - */ - private static function mapColorBIFF5($color) - { - if (isset(PHPExcel_Reader_Excel5_Color_BIFF5::$map[$color])) { - return array('rgb' => PHPExcel_Reader_Excel5_Color_BIFF5::$map[$color]); - } - return array('rgb' => '000000'); - } - - - /** - * Map color array from BIFF8 built-in color index - * - * @param int $color - * @return array - */ - private static function mapColor($color) - { - if (isset(PHPExcel_Reader_Excel5_Color_BIFF8::$map[$color])) { - return array('rgb' => PHPExcel_Reader_Excel5_Color_BIFF8::$map[$color]); - } - return array('rgb' => '000000'); - } - private function parseRichText($is = '') { $value = new PHPExcel_RichText(); diff --git a/Classes/PHPExcel/Reader/Excel5/Color.php b/Classes/PHPExcel/Reader/Excel5/Color.php new file mode 100644 index 000000000..1801df5e5 --- /dev/null +++ b/Classes/PHPExcel/Reader/Excel5/Color.php @@ -0,0 +1,32 @@ +<?php + +class PHPExcel_Reader_Excel5_Color +{ + /** + * Read color + * + * @param int $color Indexed color + * @param array $palette Color palette + * @return array RGB color value, example: array('rgb' => 'FF0000') + */ + public static function map($color, $palette, $version) + { + if ($color <= 0x07 || $color >= 0x40) { + // special built-in color + return PHPExcel_Reader_Excel5_Color_BuiltIn::lookup($color); + } elseif (isset($palette) && isset($palette[$color - 8])) { + // palette color, color index 0x08 maps to pallete index 0 + return $palette[$color - 8]; + } else { + // default color table + if ($version == PHPExcel_Reader_Excel5::XLS_BIFF8) { + return PHPExcel_Reader_Excel5_Color_BIFF8::lookup($color); + } else { + // BIFF5 + return PHPExcel_Reader_Excel5_Color_BIFF5::lookup($color); + } + } + + return $color; + } +} \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5/Color/BIFF5.php b/Classes/PHPExcel/Reader/Excel5/Color/BIFF5.php index 7c15d5d4f..159c27fc7 100644 --- a/Classes/PHPExcel/Reader/Excel5/Color/BIFF5.php +++ b/Classes/PHPExcel/Reader/Excel5/Color/BIFF5.php @@ -2,7 +2,7 @@ class PHPExcel_Reader_Excel5_Color_BIFF5 { - public static $map = array( + protected static $map = array( 0x08 => '000000', 0x09 => 'FFFFFF', 0x0A => 'FF0000', @@ -60,4 +60,18 @@ class PHPExcel_Reader_Excel5_Color_BIFF5 0x3E => '4A3285', 0x3F => '424242', ); + + /** + * Map color array from BIFF5 built-in color index + * + * @param int $color + * @return array + */ + public static function lookup($color) + { + if (isset(self::$map[$color])) { + return array('rgb' => self::$map[$color]); + } + return array('rgb' => '000000'); + } } \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5/Color/BIFF8.php b/Classes/PHPExcel/Reader/Excel5/Color/BIFF8.php index d0c8afbb8..4d3f2d0a3 100644 --- a/Classes/PHPExcel/Reader/Excel5/Color/BIFF8.php +++ b/Classes/PHPExcel/Reader/Excel5/Color/BIFF8.php @@ -2,7 +2,7 @@ class PHPExcel_Reader_Excel5_Color_BIFF8 { - public static $map = array( + protected static $map = array( 0x08 => '000000', 0x09 => 'FFFFFF', 0x0A => 'FF0000', @@ -60,4 +60,18 @@ class PHPExcel_Reader_Excel5_Color_BIFF8 0x3E => '333399', 0x3F => '333333', ); + + /** + * Map color array from BIFF8 built-in color index + * + * @param int $color + * @return array + */ + public static function lookup($color) + { + if (isset(self::$map[$color])) { + return array('rgb' => self::$map[$color]); + } + return array('rgb' => '000000'); + } } \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5/Color/BuiltIn.php b/Classes/PHPExcel/Reader/Excel5/Color/BuiltIn.php index f3458955f..a5b7e59b8 100644 --- a/Classes/PHPExcel/Reader/Excel5/Color/BuiltIn.php +++ b/Classes/PHPExcel/Reader/Excel5/Color/BuiltIn.php @@ -2,7 +2,7 @@ class PHPExcel_Reader_Excel5_Color_BuiltIn { - public static $map = array( + protected static $map = array( 0x00 => '000000', 0x01 => 'FFFFFF', 0x02 => 'FF0000', @@ -14,4 +14,18 @@ class PHPExcel_Reader_Excel5_Color_BuiltIn 0x40 => '000000', // system window text color 0x41 => 'FFFFFF', // system window background color ); + + /** + * Map built-in color to RGB value + * + * @param int $color Indexed color + * @return array + */ + public static function lookup($color) + { + if (isset(self::$map[$color])) { + return array('rgb' => self::$map[$color]); + } + return array('rgb' => '000000'); + } } \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5/ErrorCode.php b/Classes/PHPExcel/Reader/Excel5/ErrorCode.php index df3eadce1..f1d1cb6d8 100644 --- a/Classes/PHPExcel/Reader/Excel5/ErrorCode.php +++ b/Classes/PHPExcel/Reader/Excel5/ErrorCode.php @@ -2,7 +2,7 @@ class PHPExcel_Reader_Excel5_ErrorCode { - public static $map = array( + protected static $map = array( 0x00 => '#NULL!', 0x07 => '#DIV/0!', 0x0F => '#VALUE!', @@ -11,4 +11,18 @@ class PHPExcel_Reader_Excel5_ErrorCode 0x24 => '#NUM!', 0x2A => '#N/A', ); + + /** + * Map error code, e.g. '#N/A' + * + * @param int $code + * @return string + */ + public static function lookup($code) + { + if (isset(self::$map[$code])) { + return self::$map[$code]; + } + return false; + } } \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5/Style/Border.php b/Classes/PHPExcel/Reader/Excel5/Style/Border.php index 5695376a4..fb45b9d5b 100644 --- a/Classes/PHPExcel/Reader/Excel5/Style/Border.php +++ b/Classes/PHPExcel/Reader/Excel5/Style/Border.php @@ -2,7 +2,7 @@ class PHPExcel_Reader_Excel5_Style_Border { - public static $map = array( + protected static $map = array( 0x00 => PHPExcel_Style_Border::BORDER_NONE, 0x01 => PHPExcel_Style_Border::BORDER_THIN, 0x02 => PHPExcel_Style_Border::BORDER_MEDIUM, @@ -18,4 +18,19 @@ class PHPExcel_Reader_Excel5_Style_Border 0x0C => PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT, 0x0D => PHPExcel_Style_Border::BORDER_SLANTDASHDOT, ); + + /** + * Map border style + * OpenOffice documentation: 2.5.11 + * + * @param int $index + * @return string + */ + public static function lookup($index) + { + if (isset(self::$map[$index])) { + return self::$map[$index]; + } + return PHPExcel_Style_Border::BORDER_NONE; + } } \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php b/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php index a780639ec..5d6b3898c 100644 --- a/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php +++ b/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php @@ -2,7 +2,7 @@ class PHPExcel_Reader_Excel5_Style_FillPattern { - public static $map = array( + protected static $map = array( 0x00 => PHPExcel_Style_Fill::FILL_NONE, 0x01 => PHPExcel_Style_Fill::FILL_SOLID, 0x02 => PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY, @@ -23,4 +23,19 @@ class PHPExcel_Reader_Excel5_Style_FillPattern 0x11 => PHPExcel_Style_Fill::FILL_PATTERN_GRAY125, 0x12 => PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625, ); + + /** + * Get fill pattern from index + * OpenOffice documentation: 2.5.12 + * + * @param int $index + * @return string + */ + public static function lookup($index) + { + if (isset(self::$map[$index])) { + return self::$map[$index]; + } + return self::FILL_NONE; + } } \ No newline at end of file From 2221c5ed12f3b9dbd6e7e710cc2159453da2d958 Mon Sep 17 00:00:00 2001 From: dedulay <dedulay@unerblet.ru> Date: Thu, 31 Dec 2015 10:52:57 +0300 Subject: [PATCH 436/467] Refactor code PHPExcel/Helper/HTML.php:769:Parse error - syntax error, unexpected '[', expecting ')' --- Classes/PHPExcel/Helper/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Helper/HTML.php b/Classes/PHPExcel/Helper/HTML.php index 1e41e065e..a78f11c1f 100644 --- a/Classes/PHPExcel/Helper/HTML.php +++ b/Classes/PHPExcel/Helper/HTML.php @@ -766,7 +766,7 @@ protected function parseTextNode(DOMText $textNode) $domText = preg_replace( '/\s+/u', ' ', - str_replace(["\r", "\n"], ' ', $textNode->nodeValue) + str_replace(array("\r", "\n"), ' ', $textNode->nodeValue) ); $this->stringData .= $domText; $this->buildTextRun(); From e6ded71172c6277ad44736435e6c00b61641e5ae Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Fri, 1 Jan 2016 16:41:35 +0000 Subject: [PATCH 437/467] Fix default style for Fill Pattern --- Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php b/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php index 5d6b3898c..c92d19a69 100644 --- a/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php +++ b/Classes/PHPExcel/Reader/Excel5/Style/FillPattern.php @@ -36,6 +36,6 @@ public static function lookup($index) if (isset(self::$map[$index])) { return self::$map[$index]; } - return self::FILL_NONE; + return PHPExcel_Style_Fill::FILL_NONE; } } \ No newline at end of file From 6ae1056fb2145f599434c831b645adff35ebfc1a Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Wed, 13 Jan 2016 22:38:20 +0000 Subject: [PATCH 438/467] Minor bugfixes and documentation changes --- .../Chart/Renderer/PHP Charting Libraries.txt | 3 +++ Classes/PHPExcel/Reader/Excel5.php | 4 +-- Classes/PHPExcel/Reader/HTML.php | 2 +- .../PHPExcel developer documentation.doc | Bin 865792 -> 885248 bytes Documentation/markdown/Overview/08-Recipes.md | 24 ++++++++++-------- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Classes/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt b/Classes/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt index 20a825885..a088989e9 100644 --- a/Classes/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt +++ b/Classes/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt @@ -15,3 +15,6 @@ pChart TeeChart http://www.steema.com/products/teechart/overview.html + +PHPGraphLib + http://www.ebrueggeman.com/phpgraphlib \ No newline at end of file diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index 9b122e4ff..62e971d2e 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -5465,7 +5465,7 @@ private function createFormulaFromTokens($tokens, $additionalData) unset($space2, $space3, $space4, $space5); break; case 'tArray': // array constant - $constantArray = self::_readBIFF8ConstantArray($additionalData); + $constantArray = self::readBIFF8ConstantArray($additionalData); $formulaStrings[] = $space1 . $space0 . $constantArray['value']; $additionalData = substr($additionalData, $constantArray['size']); // bite of chunk of additional data unset($space0, $space1); @@ -7217,7 +7217,7 @@ private static function readBIFF8ConstantArray($arrayData) for ($r = 1; $r <= $nr + 1; ++$r) { $items = array(); for ($c = 1; $c <= $nc + 1; ++$c) { - $constant = self::_readBIFF8Constant($arrayData); + $constant = self::readBIFF8Constant($arrayData); $items[] = $constant['value']; $arrayData = substr($arrayData, $constant['size']); $size += $constant['size']; diff --git a/Classes/PHPExcel/Reader/HTML.php b/Classes/PHPExcel/Reader/HTML.php index 2500f16c1..ac762a4f2 100644 --- a/Classes/PHPExcel/Reader/HTML.php +++ b/Classes/PHPExcel/Reader/HTML.php @@ -494,7 +494,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Reload the HTML file into the DOM object $loaded = $dom->loadHTML(mb_convert_encoding($this->securityScanFile($pFilename), 'HTML-ENTITIES', 'UTF-8')); if ($loaded === false) { - throw new PHPExcel_Reader_Exception('Failed to load ', $pFilename, ' as a DOM Document'); + throw new PHPExcel_Reader_Exception('Failed to load ' . $pFilename . ' as a DOM Document'); } // Discard white space diff --git a/Documentation/PHPExcel developer documentation.doc b/Documentation/PHPExcel developer documentation.doc index 2c7c81a6e493f56d67a559654ec0d7380c2056e8..52cc9647d2ecedfd1c3cb603d8ce6b57c99bc707 100644 GIT binary patch delta 32627 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 J;WW<f{{YFp*-`)i delta 14844 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 diff --git a/Documentation/markdown/Overview/08-Recipes.md b/Documentation/markdown/Overview/08-Recipes.md index 6ee9c693c..5e202db1c 100644 --- a/Documentation/markdown/Overview/08-Recipes.md +++ b/Documentation/markdown/Overview/08-Recipes.md @@ -103,13 +103,13 @@ This is regardless of which language version of Microsoft Office Excel may have When the final workbook is opened by the user, Microsoft Office Excel will take care of displaying the formula according the applications language. Translation is taken care of by the application! -The following line of code writes the formula '=IF(C4>500,"profit","loss")'� into the cell B8. Note that the formula must start with "=" to make PHPExcel recognise this as a formula. +The following line of code writes the formula '=IF(C4>500,"profit","loss")' into the cell B8. Note that the formula must start with "=" to make PHPExcel recognise this as a formula. ```php $objPHPExcel->getActiveSheet()->setCellValue('B8','=IF(C4>500,"profit","loss")'); ``` -If you want to write a string beginning with an "="� character to a cell, then you should use the setCellValueExplicit() method. +If you want to write a string beginning with an "=" character to a cell, then you should use the setCellValueExplicit() method. ```php $objPHPExcel->getActiveSheet() @@ -167,22 +167,22 @@ At present, the following locale settings are supported: Language | | Locale Code ---------------------|----------------------|------------- - Czech | Ce�tina | cs + Czech | Ceština | cs Danish | Dansk | da German | Deutsch | de - Spanish | Espa�ol | es + Spanish | Español | es Finnish | Suomi | fi - French | Fran�ais | fr + French | Français | fr Hungarian | Magyar | hu Italian | Italiano | it Dutch | Nederlands | nl Norwegian | Norsk | no Polish | Jezyk polski | pl - Portuguese | Portugu�s | pt - Brazilian Portuguese | Portugu�s Brasileiro | pt_br + Portuguese | Português | pt + Brazilian Portuguese | Português Brasileiro | pt_br Russian | ??????? ???? | ru Swedish | Svenska | sv - Turkish | T�rk�e | tr + Turkish | Türkçe | tr ### Write a newline character "\n" in a cell (ALT+"Enter") @@ -843,7 +843,7 @@ You can instruct PHPExcel to add a summary to the right (default), or to the lef $objPHPExcel->getActiveSheet()->setShowSummaryRight(false); ``` -### Setting a row''s height +### Setting a row's height A row's height can be set using the following code: @@ -851,6 +851,8 @@ A row's height can be set using the following code: $objPHPExcel->getActiveSheet()->getRowDimension('10')->setRowHeight(100); ``` +Excel measures row height in points, where 1 pt is 1/72 of an inch (or about 0.35mm). The default value is 12.75 pts; and the permitted range of values is between 0 and 409 pts, where 0 pts is a hidden row. + ### Show/hide a row To set a worksheet''s row visibility, you can use the following code. The following example hides row number 10. @@ -1059,7 +1061,7 @@ Sometimes, one really wants to output a file to a client''s browser, especially 2. Output HTTP headers for the type of document you wish to output 3. Use the PHPExcel_Writer_* of your choice, and save to "php://output" -�PHPExcel_Writer_Excel2007 uses temporary storage when writing to php://output. By default, temporary files are stored in the script's working directory. When there is no access, it falls back to the operating system's temporary files location. +PHPExcel_Writer_Excel2007 uses temporary storage when writing to php://output. By default, temporary files are stored in the script's working directory. When there is no access, it falls back to the operating system's temporary files location. __This may not be safe for unauthorized viewing!__ Depending on the configuration of your operating system, temporary storage can be read by anyone using the same temporary storage folder. When confidentiality of your document is needed, it is recommended not to use php://output. @@ -1146,7 +1148,7 @@ To set a worksheet's zoom level, the following code can be used: $objPHPExcel->getActiveSheet()->getSheetView()->setZoomScale(75); ``` -Note that zoom level should be in range 10 – 400. +Note that zoom level should be in range 10 – 400. ### Sheet tab color From 144f57e44a7b6a5cb10fb781a718e2cd49591408 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Fri, 15 Jan 2016 01:19:58 +0000 Subject: [PATCH 439/467] modify export ignores --- .gitattributes | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index da774df62..58182f254 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,3 @@ /Build export-ignore -/Documentation export-ignore -/Examples export-ignore /unitTests export-ignore README.md export-ignore From 36d2ba12e38b6be60429e31f217c09afe781d620 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 25 Jan 2016 19:04:40 +0000 Subject: [PATCH 440/467] Added worksheet info example --- Examples/44worksheetInfo.php | 58 ++++++++++++++++++++++++++++++++++++ Examples/runall.php | 1 + 2 files changed, 59 insertions(+) create mode 100644 Examples/44worksheetInfo.php diff --git a/Examples/44worksheetInfo.php b/Examples/44worksheetInfo.php new file mode 100644 index 000000000..5aeefcbd8 --- /dev/null +++ b/Examples/44worksheetInfo.php @@ -0,0 +1,58 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2015 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version ##VERSION##, ##DATE## + */ + +error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />'); + +date_default_timezone_set('Europe/London'); + +/** Include PHPExcel_IOFactory */ +require_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php'; + + +if (!file_exists("05featuredemo.xlsx")) { + exit("Please run 05featuredemo.php first." . EOL); +} + +$inputFileName = "05featuredemo.xlsx"; +$inputFileType = PHPExcel_IOFactory::identify($inputFileName); +$objReader = PHPExcel_IOFactory::createReader($inputFileType); +$sheetList = $objReader->listWorksheetNames($inputFileName); +$sheetInfo = $objReader->listWorksheetInfo($inputFileName); + +echo 'File Type:', PHP_EOL; +var_dump($inputFileType); + +echo 'Worksheet Names:', PHP_EOL; +var_dump($sheetList); + +echo 'Worksheet Names:', PHP_EOL; +var_dump($sheetInfo); + diff --git a/Examples/runall.php b/Examples/runall.php index cad5b39af..153cb7657 100644 --- a/Examples/runall.php +++ b/Examples/runall.php @@ -103,6 +103,7 @@ , '41password.php' , '42richText.php' , '43mergeWorkbooks.php' + , '44worksheetInfo.php' , 'OOCalcReader.php' , 'OOCalcReaderPCLZip.php' , 'SylkReader.php' From 19d7849bd18ef901f5514b3b3c205d4af0993db3 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Tue, 9 Feb 2016 15:27:30 +0000 Subject: [PATCH 441/467] Fix reference for gd in composer --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 81e83e792..d512dd0d5 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ }, "recommend": { "ext-zip": "*", - "ext-gd2": "*" + "ext-gd": "*" }, "autoload": { "psr-0": { From 6a3dd85f6fb434542e92cbc3b07a8dc917db92d4 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 29 Feb 2016 09:32:34 +0000 Subject: [PATCH 442/467] Docblock fix --- Classes/PHPExcel/Worksheet/Column.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Worksheet/Column.php b/Classes/PHPExcel/Worksheet/Column.php index 8c561fa8c..6d3f36d17 100644 --- a/Classes/PHPExcel/Worksheet/Column.php +++ b/Classes/PHPExcel/Worksheet/Column.php @@ -65,7 +65,7 @@ public function __destruct() /** * Get column index * - * @return int + * @return string */ public function getColumnIndex() { From 352e6ea5cc297ddfcfe3cd1af6c3e170691ed4b3 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Tue, 1 Mar 2016 12:34:05 +0000 Subject: [PATCH 443/467] Allow HYPERLINK() function to set the tooltip, and add extra examples of setting hyperlinks either through PHPExcel methods or using the HYPERLINK() function --- Classes/PHPExcel/Calculation/LookupRef.php | 1 + Examples/02types.php | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/Classes/PHPExcel/Calculation/LookupRef.php b/Classes/PHPExcel/Calculation/LookupRef.php index d86055121..1fe77902f 100644 --- a/Classes/PHPExcel/Calculation/LookupRef.php +++ b/Classes/PHPExcel/Calculation/LookupRef.php @@ -281,6 +281,7 @@ public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Ce } $pCell->getHyperlink()->setUrl($linkURL); + $pCell->getHyperlink()->setTooltip($displayName); return $displayName; } diff --git a/Examples/02types.php b/Examples/02types.php index 6ac11c7b0..394a73dd4 100644 --- a/Examples/02types.php +++ b/Examples/02types.php @@ -136,6 +136,27 @@ $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true); +$objRichText3 = new PHPExcel_RichText(); +$objRichText3->createText("Hello "); + +$objUnderlined = $objRichText3->createTextRun("underlined"); +$objUnderlined->getFont()->setUnderline(true); +$objRichText3->createText(' World.'); + +$objPHPExcel->getActiveSheet() + ->getCell("C15") + ->setValue($objRichText3); + + +$objPHPExcel->getActiveSheet()->setCellValue('A17', 'Hyperlink'); + +$objPHPExcel->getActiveSheet()->setCellValue('C17', 'www.phpexcel.net'); +$objPHPExcel->getActiveSheet()->getCell('C17')->getHyperlink()->setUrl('http://www.phpexcel.net/'); +$objPHPExcel->getActiveSheet()->getCell('C17')->getHyperlink()->setTooltip('Navigate to website'); + +$objPHPExcel->getActiveSheet()->setCellValue('C18', '=HYPERLINK("mailto:abc@def.com","abc@def.com")'); + + // Rename worksheet echo date('H:i:s') , " Rename worksheet" , EOL; $objPHPExcel->getActiveSheet()->setTitle('Datatypes'); From 39d8b8f57ad369f48c2471ba43f967a6a86816fd Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Tue, 1 Mar 2016 23:15:49 +0000 Subject: [PATCH 444/467] Feature: (Tomino2112) Work Item GH-808 - MemoryDrawing not working in HTML writer Manual merge of Pull Request --- Classes/PHPExcel/Writer/HTML.php | 16 ++++++++++++++++ Examples/25inmemoryimage.php | 8 +++++++- changelog.txt | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 7a41bb53f..5dcb9983f 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -656,6 +656,22 @@ private function writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) $imageData . '" border="0" />'; $html .= '</div>'; } + } elseif ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { + if ($drawing->getCoordinates() != $coordinates) { + continue; + } + ob_start(); // Let's start output buffering. + imagepng($drawing->getImageResource()); // This will normally output the image, but because of ob_start(), it won't. + $contents = ob_get_contents(); // Instead, output above is saved to $contents + ob_end_clean(); // End the output buffer. + + $dataUri = "data:image/jpeg;base64," . base64_encode($contents); + + // Because of the nature of tables, width is more important than height. + // max-width: 100% ensures that image doesnt overflow containing cell + // width: X sets width of supplied image. + // As a result, images bigger than cell will be contained and images smaller will not get stretched + $html .= '<img src="'.$dataUri.'" style="max-width:100%;width:'.$drawing->getWidth().'px;" />'; } } diff --git a/Examples/25inmemoryimage.php b/Examples/25inmemoryimage.php index 167a861a7..6c3b0b845 100644 --- a/Examples/25inmemoryimage.php +++ b/Examples/25inmemoryimage.php @@ -75,9 +75,15 @@ echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; +echo date('H:i:s') , " Write to HTML format" , EOL; +$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML'); +$objWriter->save(str_replace('.php', '.html', __FILE__)); +echo date('H:i:s') , " File written to " , str_replace('.php', '.html', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL; + + // Echo memory peak usage echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; // Echo done echo date('H:i:s') , " Done writing file" , EOL; -echo 'File has been created in ' , getcwd() , EOL; +echo 'Files have been created in ' , getcwd() , EOL; diff --git a/changelog.txt b/changelog.txt index 4d1605b4e..2b7c4a712 100644 --- a/changelog.txt +++ b/changelog.txt @@ -31,6 +31,7 @@ Planned for 1.8.2 - Bugfix: (MBaker) Work Item GH-554 - Whitespace after toRichTextObject() - Feature: (MBaker) - Initial implementation of SUMIFS() function - Feature: (MBaker) - Additional codepages +- Feature: (Tomino2112) Work Item GH-808 - MemoryDrawing not working in HTML writer 2015-04-30 (v1.8.1): From da91993df07649f5f1fb52ae1de456093a205544 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 6 Mar 2016 23:23:39 +0000 Subject: [PATCH 445/467] Minor fixes to documentation --- .../markdown/Overview/01-Getting-Started.md | 16 ++++++++-------- .../markdown/Overview/02-Architecture.md | 11 +++++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Documentation/markdown/Overview/01-Getting-Started.md b/Documentation/markdown/Overview/01-Getting-Started.md index d3fb06b5a..a6eb77d15 100644 --- a/Documentation/markdown/Overview/01-Getting-Started.md +++ b/Documentation/markdown/Overview/01-Getting-Started.md @@ -21,10 +21,10 @@ Installation is quite easy: copy the contents of the Classes folder to any locat If your web root folder is /var/www/ you may want to create a subfolder called /var/www/Classes/ and copy the files into that folder so you end up with files: -/var/www/Classes/PHPExcel.php -/var/www/Classes/PHPExcel/Calculation.php -/var/www/Classes/PHPExcel/Cell.php -... + /var/www/Classes/PHPExcel.php + /var/www/Classes/PHPExcel/Calculation.php + /var/www/Classes/PHPExcel/Cell.php + ... ### Getting started @@ -32,9 +32,9 @@ If your web root folder is /var/www/ you may want to create a subfolder called / A good way to get started is to run some of the tests included in the download. Copy the "Examples" folder next to your "Classes" folder from above so you end up with: -/var/www/Examples/01simple.php -/var/www/Examples/02types.php -... + /var/www/Examples/01simple.php + /var/www/Examples/02types.php + ... Start running the tests by pointing your browser to the test scripts: @@ -89,7 +89,7 @@ At present, this only allows you to write Excel2007 files without the need for Z ##### Excel 2007 cannot open the file generated by PHPExcel_Writer_2007 on Windows -*"Excel found unreadable content in '*.xlsx'. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes."�* +"Excel found unreadable content in '*.xlsx'. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes." Some older versions of the 5.2.x php_zip extension on Windows contain an error when creating ZIP files. The version that can be found on [http://snaps.php.net/win32/php5.2-win32-latest.zip][8] should work at all times. diff --git a/Documentation/markdown/Overview/02-Architecture.md b/Documentation/markdown/Overview/02-Architecture.md index b59c18892..8ddb43e2c 100644 --- a/Documentation/markdown/Overview/02-Architecture.md +++ b/Documentation/markdown/Overview/02-Architecture.md @@ -5,12 +5,12 @@ ### Schematical -![01-schematic.png](./images/01-schematic.png "") +![01-schematic.png](./images/01-schematic.png "Basic Architecture Schematic") ### Lazy Loader -PHPExcel implements an autoloader or "lazy loader"�, which means that it is not necessary to include every file within PHPExcel. It is only necessary to include the initial PHPExcel class file, then the autoloader will include other class files as and when required, so only those files that are actually required by your script will be loaded into PHP memory. The main benefit of this is that it reduces the memory footprint of PHPExcel itself, so that it uses less PHP memory. +PHPExcel implements an autoloader or "lazy loader", which means that it is not necessary to include every file within PHPExcel. It is only necessary to include the initial PHPExcel class file, then the autoloader will include other class files as and when required, so only those files that are actually required by your script will be loaded into PHP memory. The main benefit of this is that it reduces the memory footprint of PHPExcel itself, so that it uses less PHP memory. If your own scripts already define an autoload function, then this may be overwritten by the PHPExcel autoload function. For example, if you have: ```php @@ -42,11 +42,12 @@ On its own, PHPExcel does not provide the functionality to read from or write to By default, the PHPExcel package provides some readers and writers, including one for the Open XML spreadsheet format (a.k.a. Excel 2007 file format). You are not limited to the default readers and writers, as you are free to implement the PHPExcel_Reader_IReader and PHPExcel_Writer_IWriter interface in a custom class. -![02-readers-writers.png](./images/02-readers-writers.png "") +![02-readers-writers.png](./images/02-readers-writers.png "Readers/Writers") ### Fluent interfaces -PHPExcel supports fluent interfaces in most locations. This means that you can easily "chain"" calls to specific methods without requiring a new PHP statement. For example, take the following code: +PHPExcel supports fluent interfaces in most locations. This means that you can easily "chain" calls to specific methods without requiring a new PHP statement. For example, take the following code: + ```php $objPHPExcel->getProperties()->setCreator("Maarten Balliauw"); $objPHPExcel->getProperties()->setLastModifiedBy("Maarten Balliauw"); @@ -56,7 +57,9 @@ $objPHPExcel->getProperties()->setDescription("Test document for Office 2007 XLS $objPHPExcel->getProperties()->setKeywords("office 2007 openxml php"); $objPHPExcel->getProperties()->setCategory("Test result file"); ``` + This can be rewritten as: + ```php $objPHPExcel->getProperties() ->setCreator("Maarten Balliauw") From 802a94fc5da3573cec3774579b1538496a59c52a Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 6 Mar 2016 23:25:13 +0000 Subject: [PATCH 446/467] Allow formatted strings as argument in PHPToExcel date conversion --- Classes/PHPExcel/Shared/Date.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index a0a4e3953..025a6ecea 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -187,7 +187,8 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $ti $retValue = self::FormattedPHPToExcel($dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s')); } elseif (is_numeric($dateValue)) { $retValue = self::FormattedPHPToExcel(date('Y', $dateValue), date('m', $dateValue), date('d', $dateValue), date('H', $dateValue), date('i', $dateValue), date('s', $dateValue)); - } + } elseif (is_string($dateValue)) { + $retValue = self::stringToExcel($dateValue) date_default_timezone_set($saveTimeZone); return $retValue; From bf2b74b57eb0fc72423ed7edfd8bd14743100f1a Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 7 Mar 2016 07:59:19 +0000 Subject: [PATCH 447/467] Fix missing ; in last commit --- Classes/PHPExcel/Shared/Date.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index 025a6ecea..c772bd4fb 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -188,7 +188,8 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $ti } elseif (is_numeric($dateValue)) { $retValue = self::FormattedPHPToExcel(date('Y', $dateValue), date('m', $dateValue), date('d', $dateValue), date('H', $dateValue), date('i', $dateValue), date('s', $dateValue)); } elseif (is_string($dateValue)) { - $retValue = self::stringToExcel($dateValue) + $retValue = self::stringToExcel($dateValue); + } date_default_timezone_set($saveTimeZone); return $retValue; From d3fd1508a110c6d8767da13ef4c51d2ad62f8d5a Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 7 Mar 2016 10:03:52 +0000 Subject: [PATCH 448/467] Testing pre-commit hook for lint check of PHP syntax --- Classes/PHPExcel/Shared/Date.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index c772bd4fb..a99f0706c 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -188,7 +188,7 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $ti } elseif (is_numeric($dateValue)) { $retValue = self::FormattedPHPToExcel(date('Y', $dateValue), date('m', $dateValue), date('d', $dateValue), date('H', $dateValue), date('i', $dateValue), date('s', $dateValue)); } elseif (is_string($dateValue)) { - $retValue = self::stringToExcel($dateValue); + $retValue = self::stringToExcel($dateValue) } date_default_timezone_set($saveTimeZone); From 6fe91ac86a486d548ed019efcb345f8840a6835d Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 7 Mar 2016 11:36:29 +0000 Subject: [PATCH 449/467] git hooks syntax error test --- Classes/PHPExcel/Shared/Date.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index a99f0706c..278f6ba1b 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -188,8 +188,8 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $ti } elseif (is_numeric($dateValue)) { $retValue = self::FormattedPHPToExcel(date('Y', $dateValue), date('m', $dateValue), date('d', $dateValue), date('H', $dateValue), date('i', $dateValue), date('s', $dateValue)); } elseif (is_string($dateValue)) { - $retValue = self::stringToExcel($dateValue) - } + $retValue = self::stringToExcel($dateValue); + date_default_timezone_set($saveTimeZone); return $retValue; From 1b6ed6b9c623e16044a132ace32b7611f6ce73b3 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 7 Mar 2016 11:37:40 +0000 Subject: [PATCH 450/467] Testing pre-commit syntax check --- Classes/PHPExcel/Shared/Date.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index 278f6ba1b..a99f0706c 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -188,8 +188,8 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $ti } elseif (is_numeric($dateValue)) { $retValue = self::FormattedPHPToExcel(date('Y', $dateValue), date('m', $dateValue), date('d', $dateValue), date('H', $dateValue), date('i', $dateValue), date('s', $dateValue)); } elseif (is_string($dateValue)) { - $retValue = self::stringToExcel($dateValue); - + $retValue = self::stringToExcel($dateValue) + } date_default_timezone_set($saveTimeZone); return $retValue; From 5e89b26e9d969b880606f190fdfd4c829a0ecc2d Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Mon, 7 Mar 2016 11:50:12 +0000 Subject: [PATCH 451/467] Testing pre-commit hook for lint checking --- Classes/PHPExcel/Shared/Date.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index a99f0706c..c772bd4fb 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -188,7 +188,7 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $ti } elseif (is_numeric($dateValue)) { $retValue = self::FormattedPHPToExcel(date('Y', $dateValue), date('m', $dateValue), date('d', $dateValue), date('H', $dateValue), date('i', $dateValue), date('s', $dateValue)); } elseif (is_string($dateValue)) { - $retValue = self::stringToExcel($dateValue) + $retValue = self::stringToExcel($dateValue); } date_default_timezone_set($saveTimeZone); From 7d1c140974a4988f8a9739d167335d24fb59955e Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Tue, 15 Mar 2016 11:48:49 +0000 Subject: [PATCH 452/467] Data validation example limiting the length of text that can be entered in a cell --- Documentation/markdown/Overview/08-Recipes.md | 16 ++++++ Examples/15datavalidation-xls.php | 49 ++++++++++++------- Examples/15datavalidation.php | 49 ++++++++++++------- 3 files changed, 78 insertions(+), 36 deletions(-) diff --git a/Documentation/markdown/Overview/08-Recipes.md b/Documentation/markdown/Overview/08-Recipes.md index 5e202db1c..b8930a44c 100644 --- a/Documentation/markdown/Overview/08-Recipes.md +++ b/Documentation/markdown/Overview/08-Recipes.md @@ -765,6 +765,22 @@ $objValidation->setFormula1(10); $objValidation->setFormula2(20); ``` +This validation will limit the length of text that can be entered in a cell to 6 characters. + +``` +$objValidation = $objPHPExcel->getActiveSheet()->getCell('B9')->getDataValidation(); +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH ); +$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP ); +$objValidation->setAllowBlank(true); +$objValidation->setShowInputMessage(true); +$objValidation->setShowErrorMessage(true); +$objValidation->setErrorTitle('Input error'); +$objValidation->setError('Text exceeds maximum length'); +$objValidation->setPromptTitle('Allowed input'); +$objValidation->setPrompt('Maximum text length is 6 characters.'); +$objValidation->setFormula1(6); +``` + The following piece of code only allows an item picked from a list of data to be entered in cell B3: ```php diff --git a/Examples/15datavalidation-xls.php b/Examples/15datavalidation-xls.php index 22ed62654..3f0afde53 100644 --- a/Examples/15datavalidation-xls.php +++ b/Examples/15datavalidation-xls.php @@ -47,30 +47,31 @@ // Set document properties echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") - ->setLastModifiedBy("Maarten Balliauw") - ->setTitle("Office 2007 XLSX Test Document") - ->setSubject("Office 2007 XLSX Test Document") - ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") - ->setKeywords("office 2007 openxml php") - ->setCategory("Test result file"); + ->setLastModifiedBy("Maarten Balliauw") + ->setTitle("Office 2007 XLSX Test Document") + ->setSubject("Office 2007 XLSX Test Document") + ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") + ->setKeywords("office 2007 openxml php") + ->setCategory("Test result file"); // Create a first sheet echo date('H:i:s') , " Add data" , EOL; $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getActiveSheet()->setCellValue('A1', "Cell B3 and B5 contain data validation...") - ->setCellValue('A3', "Number:") - ->setCellValue('B3', "10") - ->setCellValue('A5', "List:") - ->setCellValue('B5', "Item A") - ->setCellValue('A7', "List #2:") - ->setCellValue('B7', "Item #2") - ->setCellValue('D2', "Item #1") - ->setCellValue('D3', "Item #2") - ->setCellValue('D4', "Item #3") - ->setCellValue('D5', "Item #4") - ->setCellValue('D6', "Item #5") - ; + ->setCellValue('A3', "Number:") + ->setCellValue('B3', "10") + ->setCellValue('A5', "List:") + ->setCellValue('B5', "Item A") + ->setCellValue('A7', "List #2:") + ->setCellValue('B7', "Item #2") + ->setCellValue('D2', "Item #1") + ->setCellValue('D3', "Item #2") + ->setCellValue('D4', "Item #3") + ->setCellValue('D5', "Item #4") + ->setCellValue('D6', "Item #5") + ->setCellValue('A9', 'Text:') + ; // Set data validation @@ -114,6 +115,18 @@ $objValidation->setPrompt('Please pick a value from the drop-down list.'); $objValidation->setFormula1('$D$2:$D$6'); // Make sure NOT to put a range of cells or a formula between " and " !!! +$objValidation = $objPHPExcel->getActiveSheet()->getCell('B9')->getDataValidation(); +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH ); +$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP ); +$objValidation->setAllowBlank(true); +$objValidation->setShowInputMessage(true); +$objValidation->setShowErrorMessage(true); +$objValidation->setErrorTitle('Input error'); +$objValidation->setError('Text exceeds maximum length'); +$objValidation->setPromptTitle('Allowed input'); +$objValidation->setPrompt('Maximum text length is 6 characters.'); +$objValidation->setFormula1(6); + // Set active sheet index to the first sheet, so Excel opens this as the first sheet $objPHPExcel->setActiveSheetIndex(0); diff --git a/Examples/15datavalidation.php b/Examples/15datavalidation.php index e6688c5f2..132063d8e 100644 --- a/Examples/15datavalidation.php +++ b/Examples/15datavalidation.php @@ -47,30 +47,31 @@ // Set document properties echo date('H:i:s') , " Set document properties" , EOL; $objPHPExcel->getProperties()->setCreator("Maarten Balliauw") - ->setLastModifiedBy("Maarten Balliauw") - ->setTitle("Office 2007 XLSX Test Document") - ->setSubject("Office 2007 XLSX Test Document") - ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") - ->setKeywords("office 2007 openxml php") - ->setCategory("Test result file"); + ->setLastModifiedBy("Maarten Balliauw") + ->setTitle("Office 2007 XLSX Test Document") + ->setSubject("Office 2007 XLSX Test Document") + ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") + ->setKeywords("office 2007 openxml php") + ->setCategory("Test result file"); // Create a first sheet echo date('H:i:s') , " Add data" , EOL; $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getActiveSheet()->setCellValue('A1', "Cell B3 and B5 contain data validation...") - ->setCellValue('A3', "Number:") - ->setCellValue('B3', "10") - ->setCellValue('A5', "List:") - ->setCellValue('B5', "Item A") - ->setCellValue('A7', "List #2:") - ->setCellValue('B7', "Item #2") - ->setCellValue('D2', "Item #1") - ->setCellValue('D3', "Item #2") - ->setCellValue('D4', "Item #3") - ->setCellValue('D5', "Item #4") - ->setCellValue('D6', "Item #5") - ; + ->setCellValue('A3', "Number:") + ->setCellValue('B3', "10") + ->setCellValue('A5', "List:") + ->setCellValue('B5', "Item A") + ->setCellValue('A7', "List #2:") + ->setCellValue('B7', "Item #2") + ->setCellValue('D2', "Item #1") + ->setCellValue('D3', "Item #2") + ->setCellValue('D4', "Item #3") + ->setCellValue('D5', "Item #4") + ->setCellValue('D6', "Item #5") + ->setCellValue('A9', 'Text:') + ; // Set data validation @@ -115,6 +116,18 @@ $objValidation->setPrompt('Please pick a value from the drop-down list.'); $objValidation->setFormula1('$D$2:$D$6'); // Make sure NOT to put a range of cells or a formula between " and " !!! +$objValidation = $objPHPExcel->getActiveSheet()->getCell('B9')->getDataValidation(); +$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH ); +$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP ); +$objValidation->setAllowBlank(true); +$objValidation->setShowInputMessage(true); +$objValidation->setShowErrorMessage(true); +$objValidation->setErrorTitle('Input error'); +$objValidation->setError('Text exceeds maximum length'); +$objValidation->setPromptTitle('Allowed input'); +$objValidation->setPrompt('Maximum text length is 6 characters.'); +$objValidation->setFormula1(6); + // Set active sheet index to the first sheet, so Excel opens this as the first sheet $objPHPExcel->setActiveSheetIndex(0); From a806b79aba15b1ee6f8c520fb9a55731a78d7904 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 17 Mar 2016 22:39:58 +0000 Subject: [PATCH 453/467] Allow inclusion of a sep=; line when creating csv files --- Classes/PHPExcel/Writer/CSV.php | 45 +++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/Classes/PHPExcel/Writer/CSV.php b/Classes/PHPExcel/Writer/CSV.php index 31ca874b6..e59c30130 100644 --- a/Classes/PHPExcel/Writer/CSV.php +++ b/Classes/PHPExcel/Writer/CSV.php @@ -69,6 +69,14 @@ class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_W */ private $useBOM = false; + /** + * Whether to write a Separator line as the first line of the file + * sep=x + * + * @var boolean + */ + private $includeSeparatorLine = false; + /** * Whether to write a fully Excel compatible CSV file. * @@ -109,15 +117,20 @@ public function save($pFilename = null) } if ($this->excelCompatibility) { - fwrite($fileHandle, "\xEF\xBB\xBF"); // Enforce UTF-8 BOM Header - $this->setEnclosure('"'); // Set enclosure to " - $this->setDelimiter(";"); // Set delimiter to a semi-colon + $this->setUseBOM(true); // Enforce UTF-8 BOM Header + $this->setIncludeSeparatorLine(true); // Set separator line + $this->setEnclosure('"'); // Set enclosure to " + $this->setDelimiter(";"); // Set delimiter to a semi-colon $this->setLineEnding("\r\n"); - fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->lineEnding); - } elseif ($this->useBOM) { + } + if ($this->useBOM) { // Write the UTF-8 BOM code if required fwrite($fileHandle, "\xEF\xBB\xBF"); } + if ($this->includeSeparatorLine) { + // Write the separator line if required + fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->lineEnding); + } // Identify the range that we need to extract from the worksheet $maxCol = $sheet->getHighestDataColumn(); @@ -229,6 +242,28 @@ public function setUseBOM($pValue = false) return $this; } + /** + * Get whether a separator line should be included + * + * @return boolean + */ + public function getIncludeSeparatorLine() + { + return $this->includeSeparatorLine; + } + + /** + * Set whether a separator line should be included as the first line of the file + * + * @param boolean $pValue Use separator line? Defaults to false + * @return PHPExcel_Writer_CSV + */ + public function setIncludeSeparatorLine($pValue = false) + { + $this->includeSeparatorLine = $pValue; + return $this; + } + /** * Get whether the file should be saved with full Excel Compatibility * From 79f95213e0bb73111d777966316fef4056a1fdb7 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 17 Mar 2016 22:52:07 +0000 Subject: [PATCH 454/467] Detect the presence of a sep=; line in CSV imports, and set the delimiter accordingly --- Classes/PHPExcel/Reader/CSV.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index db96b6084..194240ffd 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -157,6 +157,23 @@ protected function skipBOM() } } + /** + * Identify any separator that is explicitly set in the file + * + */ + protected function checkSeparator() + { + $line = fgets($this->fileHandle); + if ($line === false) { + return; + } + + if ((strlen(trim($line)) == 5) && (strpos($line, 'sep=') !== 0)) { + return $this->skipBOM(); + } + $this->delimiter = substr($line, 4, 1); + } + /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) * @@ -175,6 +192,7 @@ public function listWorksheetInfo($pFilename) // Skip BOM, if any $this->skipBOM(); + $this->checkSeparator(); $escapeEnclosures = array( "\\" . $this->enclosure, $this->enclosure . $this->enclosure ); @@ -239,6 +257,7 @@ public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) // Skip BOM, if any $this->skipBOM(); + $this->checkSeparator(); // Create new PHPExcel object while ($objPHPExcel->getSheetCount() <= $this->sheetIndex) { From 7fa160905bec24ae5fdf7c98db7a4e1925a4acfa Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Tue, 22 Mar 2016 13:35:28 +0000 Subject: [PATCH 455/467] General: (rentalhost) Work Item GH-575 - Excel 2007 Reader freezes because of conditional formatting --- Classes/PHPExcel/Reader/Excel2007.php | 5 +++-- changelog.txt | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Reader/Excel2007.php b/Classes/PHPExcel/Reader/Excel2007.php index bf387a098..1932df4b6 100644 --- a/Classes/PHPExcel/Reader/Excel2007.php +++ b/Classes/PHPExcel/Reader/Excel2007.php @@ -960,8 +960,9 @@ public function load($pFilename) } // Extract all cell references in $ref - foreach (PHPExcel_Cell::extractAllCellReferencesInRange($ref) as $reference) { - $docSheet->getStyle($reference)->setConditionalStyles($conditionalStyles); + $cellBlocks = explode(' ', str_replace('$', '', strtoupper($ref))); + foreach ($cellBlocks as $cellBlock) { + $docSheet->getStyle($cellBlock)->setConditionalStyles($conditionalStyles); } } } diff --git a/changelog.txt b/changelog.txt index 2b7c4a712..ab75211e9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -32,6 +32,7 @@ Planned for 1.8.2 - Feature: (MBaker) - Initial implementation of SUMIFS() function - Feature: (MBaker) - Additional codepages - Feature: (Tomino2112) Work Item GH-808 - MemoryDrawing not working in HTML writer +- General: (rentalhost) Work Item GH-575 - Excel 2007 Reader freezes because of conditional formatting 2015-04-30 (v1.8.1): From 44918984a1b938c311699cd79918a01c1d4fa392 Mon Sep 17 00:00:00 2001 From: Vitaly Repin <vitaly.repin@gmail.com> Date: Thu, 24 Mar 2016 00:45:27 +0200 Subject: [PATCH 456/467] Bug fix: c:max and c:min elements must not be inside c:orientation elements. They shall be inside c:scaling elements. Otherwise they are ignored by Excel and Libreoffice --- Classes/PHPExcel/Writer/Excel2007/Chart.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Classes/PHPExcel/Writer/Excel2007/Chart.php b/Classes/PHPExcel/Writer/Excel2007/Chart.php index c0f86bf20..92fa21506 100644 --- a/Classes/PHPExcel/Writer/Excel2007/Chart.php +++ b/Classes/PHPExcel/Writer/Excel2007/Chart.php @@ -540,8 +540,6 @@ private function writeValueAxis($objWriter, PHPExcel_Chart_PlotArea $plotArea, $ } $objWriter->startElement('c:scaling'); - $objWriter->startElement('c:orientation'); - $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation')); if (!is_null($xAxis->getAxisOptionsProperty('maximum'))) { $objWriter->startElement('c:max'); @@ -555,6 +553,10 @@ private function writeValueAxis($objWriter, PHPExcel_Chart_PlotArea $plotArea, $ $objWriter->endElement(); } + $objWriter->startElement('c:orientation'); + $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation')); + + $objWriter->endElement(); $objWriter->endElement(); From a1dee8f6c3bc58a63d04b2b54f85bc1874ba0105 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 31 Mar 2016 23:25:30 +0100 Subject: [PATCH 457/467] Bugfix: (vitalyrepin) Pull Request 869 - c:max and c:min elements shall NOT be inside c:orientation elements --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index ab75211e9..3a5456f06 100644 --- a/changelog.txt +++ b/changelog.txt @@ -33,6 +33,7 @@ Planned for 1.8.2 - Feature: (MBaker) - Additional codepages - Feature: (Tomino2112) Work Item GH-808 - MemoryDrawing not working in HTML writer - General: (rentalhost) Work Item GH-575 - Excel 2007 Reader freezes because of conditional formatting +- Bugfix: (vitalyrepin) Pull Request 869 - c:max and c:min elements shall NOT be inside c:orientation elements 2015-04-30 (v1.8.1): From c4782b660619be139a64d96a545f6a422ca74c20 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 31 Mar 2016 23:50:44 +0100 Subject: [PATCH 458/467] General: (sim642) Pull Request 489 - Implement actual timezone adjustment into PHPExcel_Shared_Date::PHPToExcel --- Classes/PHPExcel/Shared/Date.php | 7 +++++++ changelog.txt | 1 + 2 files changed, 8 insertions(+) diff --git a/Classes/PHPExcel/Shared/Date.php b/Classes/PHPExcel/Shared/Date.php index c772bd4fb..b00a39a3d 100644 --- a/Classes/PHPExcel/Shared/Date.php +++ b/Classes/PHPExcel/Shared/Date.php @@ -182,10 +182,17 @@ public static function PHPToExcel($dateValue = 0, $adjustToTimezone = false, $ti { $saveTimeZone = date_default_timezone_get(); date_default_timezone_set('UTC'); + + $timezoneAdjustment = ($adjustToTimezone) ? + PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone ? $timezone : $saveTimeZone, $dateValue) : + 0; + $retValue = false; if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { + $dateValue->add(new DateInterval('PT' . $timezoneAdjustment . 'S')); $retValue = self::FormattedPHPToExcel($dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s')); } elseif (is_numeric($dateValue)) { + $dateValue += $timezoneAdjustment; $retValue = self::FormattedPHPToExcel(date('Y', $dateValue), date('m', $dateValue), date('d', $dateValue), date('H', $dateValue), date('i', $dateValue), date('s', $dateValue)); } elseif (is_string($dateValue)) { $retValue = self::stringToExcel($dateValue); diff --git a/changelog.txt b/changelog.txt index 3a5456f06..1d5c9fee0 100644 --- a/changelog.txt +++ b/changelog.txt @@ -34,6 +34,7 @@ Planned for 1.8.2 - Feature: (Tomino2112) Work Item GH-808 - MemoryDrawing not working in HTML writer - General: (rentalhost) Work Item GH-575 - Excel 2007 Reader freezes because of conditional formatting - Bugfix: (vitalyrepin) Pull Request 869 - c:max and c:min elements shall NOT be inside c:orientation elements +- General: (sim642) Pull Request 489 - Implement actual timezone adjustment into PHPExcel_Shared_Date::PHPToExcel 2015-04-30 (v1.8.1): From 8af620f97b8b1c8a677d90b3d7203fa562050db1 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 14 Apr 2016 23:19:40 +0100 Subject: [PATCH 459/467] GH-879 Bug in file PHPExcel/Reader/CSV.php Code logic identifying a defined separator when no separator is explicitly defined Case-insensitive check when separator is explicitly defined --- Classes/PHPExcel/Reader/CSV.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Classes/PHPExcel/Reader/CSV.php b/Classes/PHPExcel/Reader/CSV.php index 194240ffd..21329dad6 100644 --- a/Classes/PHPExcel/Reader/CSV.php +++ b/Classes/PHPExcel/Reader/CSV.php @@ -168,10 +168,11 @@ protected function checkSeparator() return; } - if ((strlen(trim($line)) == 5) && (strpos($line, 'sep=') !== 0)) { - return $this->skipBOM(); + if ((strlen(trim($line, "\r\n")) == 5) && (stripos($line, 'sep=') === 0)) { + $this->delimiter = substr($line, 4, 1); + return; } - $this->delimiter = substr($line, 4, 1); + return $this->skipBOM(); } /** From 772e66f74a2162574d6fa128b26381a6299d084e Mon Sep 17 00:00:00 2001 From: psirus0588 <psirus0588@gmail.com> Date: Wed, 11 May 2016 12:44:28 +0300 Subject: [PATCH 460/467] Update 01-Getting-Started.md delete fake url --- Documentation/markdown/Overview/01-Getting-Started.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Documentation/markdown/Overview/01-Getting-Started.md b/Documentation/markdown/Overview/01-Getting-Started.md index a6eb77d15..262f1eaf8 100644 --- a/Documentation/markdown/Overview/01-Getting-Started.md +++ b/Documentation/markdown/Overview/01-Getting-Started.md @@ -149,8 +149,6 @@ Thanks to peterrlynch for the following advice on resolving issues between the [ [http://openxmldeveloper.org][18] - __French PHPExcel tutorial__ [http://g-ernaelsten.developpez.com/tutoriels/excel2007/][19] - - __Russian PHPExcel Blog Postings__ - [http://www.web-junior.net/sozdanie-excel-fajjlov-s-pomoshhyu-phpexcel/][20] - __A Japanese-language introduction to PHPExcel__ [http://journal.mycom.co.jp/articles/2009/03/06/phpexcel/index.html][21] From b2029564e5fe1f7e8a154defe20604666c7192a3 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 5 Jun 2016 16:45:50 +0100 Subject: [PATCH 461/467] Fix for XML settings, together with unit tests --- Classes/PHPExcel/Settings.php | 16 ++++++----- Examples/01simple.php | 6 ++++ unitTests/Classes/PHPExcel/SettingsTest.php | 32 +++++++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/SettingsTest.php diff --git a/Classes/PHPExcel/Settings.php b/Classes/PHPExcel/Settings.php index eff33f0f9..dcbc89fc0 100644 --- a/Classes/PHPExcel/Settings.php +++ b/Classes/PHPExcel/Settings.php @@ -353,34 +353,36 @@ public static function getPdfRendererPath() } /** - * Set default options for libxml loader + * Set options for libxml loader * - * @param int $options Default options for libxml loader + * @param int $options Options for libxml loader */ public static function setLibXmlLoaderOptions($options = null) { - if (is_null($options) && defined(LIBXML_DTDLOAD)) { + if (is_null($options) && defined('LIBXML_DTDLOAD')) { $options = LIBXML_DTDLOAD | LIBXML_DTDATTR; } if (version_compare(PHP_VERSION, '5.2.11') >= 0) { - @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + @libxml_disable_entity_loader((bool) $options); } self::$libXmlLoaderOptions = $options; } /** - * Get default options for libxml loader. + * Get defined options for libxml loader. * Defaults to LIBXML_DTDLOAD | LIBXML_DTDATTR when not set explicitly. * * @return int Default options for libxml loader */ public static function getLibXmlLoaderOptions() { - if (is_null(self::$libXmlLoaderOptions) && defined(LIBXML_DTDLOAD)) { + if (is_null(self::$libXmlLoaderOptions) && defined('LIBXML_DTDLOAD')) { self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR); + } elseif (is_null(self::$libXmlLoaderOptions)) { + self::$libXmlLoaderOptions = true; } if (version_compare(PHP_VERSION, '5.2.11') >= 0) { - @libxml_disable_entity_loader(self::$libXmlLoaderOptions == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + @libxml_disable_entity_loader((bool) self::$libXmlLoaderOptions); } return self::$libXmlLoaderOptions; } diff --git a/Examples/01simple.php b/Examples/01simple.php index e9671be1e..4644a46c6 100644 --- a/Examples/01simple.php +++ b/Examples/01simple.php @@ -37,6 +37,12 @@ require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; + +$count = 39; +$columnLetter = PHPExcel_Cell::stringFromColumnIndex($count); + +var_dump($columnLetter); +die(); // Create new PHPExcel object echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); diff --git a/unitTests/Classes/PHPExcel/SettingsTest.php b/unitTests/Classes/PHPExcel/SettingsTest.php new file mode 100644 index 000000000..0618c7822 --- /dev/null +++ b/unitTests/Classes/PHPExcel/SettingsTest.php @@ -0,0 +1,32 @@ +<?php + + +class SettingsTest extends PHPUnit_Framework_TestCase +{ + + public function setUp() + { + if (!defined('PHPEXCEL_ROOT')) { + define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); + } + require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); + } + + /** + */ + public function testGetXMLSettings() + { + $result = call_user_func(array('PHPExcel_Settings','getLibXmlLoaderOptions')); + $this->assertTrue((bool) ((LIBXML_DTDLOAD | LIBXML_DTDATTR) & $result)); + } + + /** + */ + public function testSetXMLSettings() + { + call_user_func_array(array('PHPExcel_Settings','setLibXmlLoaderOptions'), [LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_DTDVALID]); + $result = call_user_func(array('PHPExcel_Settings','getLibXmlLoaderOptions')); + $this->assertTrue((bool) ((LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_DTDVALID) & $result)); + } + +} From fcc5c6585574054bd2dce530d5fb3f5da745bc49 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sun, 5 Jun 2016 16:48:23 +0100 Subject: [PATCH 462/467] Fix to 01simple.php example after mis-commit --- Examples/01simple.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Examples/01simple.php b/Examples/01simple.php index 4644a46c6..13f802759 100644 --- a/Examples/01simple.php +++ b/Examples/01simple.php @@ -36,13 +36,6 @@ /** Include PHPExcel */ require_once dirname(__FILE__) . '/../Classes/PHPExcel.php'; - - -$count = 39; -$columnLetter = PHPExcel_Cell::stringFromColumnIndex($count); - -var_dump($columnLetter); -die(); // Create new PHPExcel object echo date('H:i:s') , " Create new PHPExcel object" , EOL; $objPHPExcel = new PHPExcel(); From e487f5c11a4b62376015d1e7da27420be0932275 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 14 Jul 2016 23:05:28 +0100 Subject: [PATCH 463/467] Fix for multiple worksheets, all with merge cells, in HTML Writer --- Classes/PHPExcel/Writer/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 5dcb9983f..8fd625592 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -398,7 +398,7 @@ public function generateSheetData() } // Ensure that Spans have been calculated? - if (!$this->spansAreCalculated) { + if ($this->_sheetIndex !== null || !$this->spansAreCalculated) { $this->calculateSpans(); } From 900325d0c809bc9cc4263fe67881d7627bb0b7f3 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 4 Aug 2016 23:55:21 +0100 Subject: [PATCH 464/467] Minor updates to composer --- composer.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index d512dd0d5..8aa448025 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "phpoffice/phpexcel", "description": "PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", "keywords": ["PHP","Excel","OpenXML","xlsx","xls","spreadsheet"], - "homepage": "http://phpexcel.codeplex.com/", + "homepage": "https://github.com/PHPOffice/PHPExcel", "type": "library", "license": "LGPL-2.1", "authors": [ @@ -11,7 +11,8 @@ "homepage": "http://blog.maartenballiauw.be/" }, { - "name": "Mark Baker" + "name": "Mark Baker", + "homepage": "http://markbakeruk.net/" }, { "name": "Franck Lefevre", From 1c8c2379ccf5ab9dd7cb46be965821d22173bcf4 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Sat, 13 Aug 2016 12:16:51 +0100 Subject: [PATCH 465/467] Fix to Radar and Scatter chart examples --- Examples/33chartcreate-radar.php | 17 +++++++++-------- Examples/33chartcreate-scatter.php | 1 + 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Examples/33chartcreate-radar.php b/Examples/33chartcreate-radar.php index 0c28addf0..7d1047a42 100644 --- a/Examples/33chartcreate-radar.php +++ b/Examples/33chartcreate-radar.php @@ -97,14 +97,15 @@ // Build the dataseries $series = new PHPExcel_Chart_DataSeries( - PHPExcel_Chart_DataSeries::TYPE_RADARCHART, // plotType - NULL, // plotGrouping (Radar charts don't have any grouping) - range(0, count($dataSeriesValues)-1), // plotOrder - $dataSeriesLabels, // plotLabel - $xAxisTickValues, // plotCategory - $dataSeriesValues, // plotValues - NULL, // smooth line - PHPExcel_Chart_DataSeries::STYLE_MARKER // plotStyle + PHPExcel_Chart_DataSeries::TYPE_RADARCHART, // plotType + NULL, // plotGrouping (Radar charts don't have any grouping) + range(0, count($dataSeriesValues)-1), // plotOrder + $dataSeriesLabels, // plotLabel + $xAxisTickValues, // plotCategory + $dataSeriesValues, // plotValues + NULL, // plotDirection + NULL, // smooth line + PHPExcel_Chart_DataSeries::STYLE_MARKER // plotStyle ); // Set up a layout object for the Pie chart diff --git a/Examples/33chartcreate-scatter.php b/Examples/33chartcreate-scatter.php index 7fc5b5ad4..a5fab8272 100644 --- a/Examples/33chartcreate-scatter.php +++ b/Examples/33chartcreate-scatter.php @@ -89,6 +89,7 @@ $dataSeriesLabels, // plotLabel $xAxisTickValues, // plotCategory $dataSeriesValues, // plotValues + NULL, // plotDirection NULL, // smooth line PHPExcel_Chart_DataSeries::STYLE_LINEMARKER // plotStyle ); From d3373c97e1bd4fceb0687d2e289998bccda514f1 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 29 Sep 2016 21:13:14 +0100 Subject: [PATCH 466/467] Fix old reference to _sheetIndex in HTML Writer --- Classes/PHPExcel/Writer/HTML.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Writer/HTML.php b/Classes/PHPExcel/Writer/HTML.php index 8fd625592..31d7c63ac 100644 --- a/Classes/PHPExcel/Writer/HTML.php +++ b/Classes/PHPExcel/Writer/HTML.php @@ -398,7 +398,7 @@ public function generateSheetData() } // Ensure that Spans have been calculated? - if ($this->_sheetIndex !== null || !$this->spansAreCalculated) { + if ($this->sheetIndex !== null || !$this->spansAreCalculated) { $this->calculateSpans(); } From 2b601574975acfb9d4378a788ed5f2b747958095 Mon Sep 17 00:00:00 2001 From: MarkBaker <mark@lange.demon.co.uk> Date: Thu, 22 Nov 2018 23:50:50 +0100 Subject: [PATCH 467/467] Fix and improve XXE security scanning for XML-based Readers --- Classes/PHPExcel/Reader/Abstract.php | 12 ++++++++++++ changelog.txt | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Classes/PHPExcel/Reader/Abstract.php b/Classes/PHPExcel/Reader/Abstract.php index 189c70a1b..deeb75a21 100644 --- a/Classes/PHPExcel/Reader/Abstract.php +++ b/Classes/PHPExcel/Reader/Abstract.php @@ -269,6 +269,18 @@ public function canRead($pFilename) */ public function securityScan($xml) { + $pattern = '/encoding="(.*?)"/'; + $result = preg_match($pattern, $xml, $matches); + if ($result) { + $charset = $matches[1]; + } else { + $charset = 'UTF-8'; + } + + if ($charset !== 'UTF-8') { + $xml = mb_convert_encoding($xml, 'UTF-8', $charset); + } + $pattern = '/\\0?' . implode('\\0?', str_split('<!DOCTYPE')) . '\\0?/'; if (preg_match($pattern, $xml)) { throw new PHPExcel_Reader_Exception('Detected use of ENTITY in XML, spreadsheet file load() aborted to prevent XXE/XEE attacks'); diff --git a/changelog.txt b/changelog.txt index 1d5c9fee0..d92923215 100644 --- a/changelog.txt +++ b/changelog.txt @@ -23,7 +23,8 @@ ************************************************************************************** -Planned for 1.8.2 +2018-11-22 (v1.8.2): +- Security (MBaker) - Fix and improve XXE security scanning for XML-based Readers - Bugfix: (MBaker) - Fix to getCell() method when cell reference includes a worksheet reference - Bugfix: (ncrypthic) Work Item GH-570 - Ignore inlineStr type if formula element exists - Bugfix: (hernst42) Work Item GH-709 - Fixed missing renames of writeRelationShip (from _writeRelationShip)